1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-10 09:32:29 +01:00

Merge pull request #4659 from IntelOrca/refactor/painting

Refactor some of the paint and draw functions to pass parameters instead of using globals as the first steps towards nicer paint code and multi-threaded paint code.
This commit is contained in:
Ted John
2016-10-22 14:30:45 +01:00
committed by GitHub
8 changed files with 309 additions and 358 deletions

View File

@@ -187,12 +187,14 @@ void update_palette_effects()
// animate the water/lava/chain movement palette
int q = 0;
extern const sint32 WeatherColours[4];
int weather_colour = WeatherColours[gClimateCurrentWeatherGloom];
if (weather_colour != -1 && gConfigGeneral.render_weather_gloom) {
q = 1;
if (weather_colour != 0x2000031) {
q = 2;
if (gConfigGeneral.render_weather_gloom) {
uint8 gloom = gClimateCurrentWeatherGloom;
if (gloom != 0) {
uint32 weatherColour = ClimateWeatherGloomColours[gloom];
q = 1;
if (weatherColour != 0x2000031) {
q = 2;
}
}
}
uint32 j = gPaletteEffectFrame;

View File

@@ -52,7 +52,6 @@ uint8 gSavedViewZoom;
uint8 gSavedViewRotation;
#ifdef NO_RCT2
paint_entry *unk_EE7884;
paint_entry *gNextFreePaintStruct;
uint8 gCurrentRotation;
uint32 gCurrentViewportFlags = 0;
@@ -69,7 +68,8 @@ static sint16 _unk9AC14E;
static uint16 _unk9AC154;
static sint16 _unk9ABDAE;
static void viewport_paint_column(rct_drawpixelinfo * dpi);
static void viewport_paint_column(rct_drawpixelinfo * dpi, uint32 viewFlags);
static void viewport_paint_weather_gloom(rct_drawpixelinfo * dpi);
/**
* This is not a viewport function. It is used to setup many variables for
@@ -671,14 +671,6 @@ void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, i
#endif
}
/** rct2: 0x0098195C */
const sint32 WeatherColours[] = {
-1,
0x2000000 | 49,
0x2000000 | 50,
0x2000000 | 47,
};
/**
*
* rct2: 0x00685CBF
@@ -691,8 +683,7 @@ const sint32 WeatherColours[] = {
*/
void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, sint16 left, sint16 top, sint16 right, sint16 bottom)
{
gCurrentViewportFlags = viewport->flags;
uint32 viewFlags = viewport->flags;
uint16 width = right - left;
uint16 height = bottom - top;
uint16 bitmask = 0xFFFF & (0xFFFF << viewport->zoom);
@@ -740,44 +731,52 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, sint16 left,
}
dpi2.width = paintRight - dpi2.x;
viewport_paint_column(&dpi2);
viewport_paint_column(&dpi2, viewFlags);
}
}
static void viewport_paint_column(rct_drawpixelinfo * dpi)
static void viewport_paint_column(rct_drawpixelinfo * dpi, uint32 viewFlags)
{
if (gCurrentViewportFlags & (VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE)){
uint8 colour = 0x0A;
if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES){
gCurrentViewportFlags = viewFlags;
if (viewFlags & (VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE)) {
uint8 colour = 10;
if (viewFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES) {
colour = 0;
}
gfx_clear(dpi, colour);
}
gEndOfPaintStructArray = &gPaintStructs[4000 - 1];
unk_140E9A8 = dpi;
painter_setup();
viewport_paint_setup();
sub_688217();
paint_quadrant_ps();
paint_init(dpi);
paint_generate_structs(dpi);
paint_struct ps = paint_arrange_structs();
paint_draw_structs(dpi, &ps, viewFlags);
int weather_colour = WeatherColours[gClimateCurrentWeatherGloom];
if (
(weather_colour != -1)
&& (!(gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES))
&& (!gTrackDesignSaveMode)
&& (gConfigGeneral.render_weather_gloom)
if (gConfigGeneral.render_weather_gloom &&
!gTrackDesignSaveMode &&
!(viewFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES)
) {
viewport_paint_weather_gloom(dpi);
}
if (gPaintPSStringHead != NULL) {
paint_draw_money_structs(dpi, gPaintPSStringHead);
}
}
static void viewport_paint_weather_gloom(rct_drawpixelinfo * dpi)
{
uint8 gloom = gClimateCurrentWeatherGloom;
if (gloom != 0) {
uint32 colour = ClimateWeatherGloomColours[gloom];
gfx_fill_rect(
dpi,
dpi->x,
dpi->y,
dpi->width + dpi->x - 1,
dpi->height + dpi->y - 1,
weather_colour
colour
);
}
viewport_draw_money_effects();
}
/**
@@ -1323,15 +1322,11 @@ static bool sub_679023(rct_drawpixelinfo *dpi, int imageId, int x, int y)
*
* rct2: 0x0068862C
*/
static void sub_68862C()
static void sub_68862C(rct_drawpixelinfo * dpi, paint_struct * ps)
{
rct_drawpixelinfo *dpi = unk_140E9A8;
paint_struct *ps = &unk_EE7884->basic, *old_ps, *next_ps;
while ((ps = ps->next_quadrant_ps) != NULL) {
old_ps = ps;
next_ps = ps;
paint_struct * old_ps = ps;
paint_struct * next_ps = ps;
while (next_ps != NULL) {
ps = next_ps;
if (sub_679023(dpi, ps->image_id, ps->x, ps->y))
@@ -1394,12 +1389,10 @@ void get_map_coordinates_from_pos(int screenX, int screenY, int flags, sint16 *x
dpi->zoom_level = _viewportDpi1.zoom_level;
dpi->x = _viewportDpi1.x;
dpi->width = 1;
gEndOfPaintStructArray = &gPaintStructs[4000 - 1];
unk_140E9A8 = dpi;
painter_setup();
viewport_paint_setup();
sub_688217();
sub_68862C();
paint_init(dpi);
paint_generate_structs(dpi);
paint_struct ps = paint_arrange_structs();
sub_68862C(dpi, &ps);
}
if (viewport != NULL) *viewport = myviewport;
}

View File

@@ -105,12 +105,10 @@ extern uint8 gSavedViewZoom;
extern uint8 gSavedViewRotation;
#ifdef NO_RCT2
extern paint_entry *unk_EE7884;
extern paint_entry *gNextFreePaintStruct;
extern uint8 gCurrentRotation;
extern uint32 gCurrentViewportFlags;
#else
#define unk_EE7884 RCT2_GLOBAL(0x00EE7884, paint_entry*)
#define gNextFreePaintStruct RCT2_GLOBAL(0x00EE7888, paint_entry*)
#define gCurrentRotation RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8)
#define gCurrentViewportFlags RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_VIEWPORT_FLAGS, uint32)
@@ -152,9 +150,6 @@ void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rc
void viewport_interaction_remove_park_entrance(rct_map_element *mapElement, int x, int y);
void sub_68B2B7(int x, int y);
void painter_setup();
void paint_quadrant_ps();
void sub_688217();
void viewport_invalidate(rct_viewport *viewport, int left, int top, int right, int bottom);

View File

@@ -29,14 +29,15 @@ const uint32 construction_markers[] = {
paint_struct * g_ps_F1AD28;
attached_paint_struct * g_aps_F1AD2C;
paint_string_struct *pss1;
paint_string_struct *pss2;
paint_string_struct * gPaintPSStringHead;
static paint_string_struct * _paintLastPSString;
#ifdef NO_RCT2
paint_entry gPaintStructs[4000];
uint32 _F1AD0C;
uint32 _F1AD10;
static paint_struct *_paint_struct_quadrants[512];
static uint32 _paintQuadrantBackIndex;
static uint32 _paintQuadrantFrontIndex;
static paint_struct *_paintQuadrants[512];
void *g_currently_drawn_item;
paint_entry * gEndOfPaintStructArray;
sint16 gUnk9DE568;
@@ -47,9 +48,9 @@ support_height gSupportSegments[9] = { 0 };
support_height gSupport;
#else
#define _paint_struct_quadrants (RCT2_ADDRESS(0x00F1A50C, paint_struct*))
#define _F1AD0C RCT2_GLOBAL(0xF1AD0C, uint32)
#define _F1AD10 RCT2_GLOBAL(0xF1AD10, uint32)
#define _paintQuadrants (RCT2_ADDRESS(0x00F1A50C, paint_struct*))
#define _paintQuadrantBackIndex RCT2_GLOBAL(0xF1AD0C, uint32)
#define _paintQuadrantFrontIndex RCT2_GLOBAL(0xF1AD10, uint32)
#endif
static const uint8 BoundBoxDebugColours[] = {
@@ -70,21 +71,41 @@ static const uint8 BoundBoxDebugColours[] = {
bool gPaintBoundingBoxes;
static void paint_attached_ps(rct_drawpixelinfo * dpi, paint_struct * ps, uint32 viewFlags);
static void paint_ps_image_with_bounding_boxes(rct_drawpixelinfo * dpi, paint_struct * ps, uint32 imageId, sint16 x, sint16 y);
static void paint_ps_image(rct_drawpixelinfo * dpi, paint_struct * ps, uint32 imageId, sint16 x, sint16 y);
static uint32 paint_ps_colourify_image(uint32 imageId, uint8 spriteType, uint32 viewFlags);
/**
*
* rct2: 0x0068615B
*/
void painter_setup() {
void paint_init(rct_drawpixelinfo * dpi)
{
unk_140E9A8 = dpi;
gEndOfPaintStructArray = &gPaintStructs[4000 - 1];
gNextFreePaintStruct = gPaintStructs;
g_ps_F1AD28 = NULL;
g_aps_F1AD2C = NULL;
for (int i = 0; i < 512; i++) {
_paint_struct_quadrants[i] = NULL;
_paintQuadrants[i] = NULL;
}
_F1AD0C = -1;
_F1AD10 = 0;
pss1 = NULL;
pss2 = NULL;
_paintQuadrantBackIndex = -1;
_paintQuadrantFrontIndex = 0;
gPaintPSStringHead = NULL;
_paintLastPSString = NULL;
}
static void paint_add_ps_to_quadrant(paint_struct * ps, sint32 positionHash)
{
uint32 paintQuadrantIndex = clamp(0, positionHash / 32, countof(_paintQuadrants) - 1);
ps->var_18 = paintQuadrantIndex;
ps->next_quadrant_ps = _paintQuadrants[paintQuadrantIndex];
_paintQuadrants[paintQuadrantIndex] = ps;
_paintQuadrantBackIndex = min(_paintQuadrantBackIndex, paintQuadrantIndex);
_paintQuadrantFrontIndex = max(_paintQuadrantFrontIndex, paintQuadrantIndex);
}
/**
@@ -295,45 +316,22 @@ paint_struct * sub_98196C(
g_ps_F1AD28 = ps;
sint32 edi = 0;
sint32 positionHash = 0;
switch (rotation) {
case 0:
edi = coord_3d.y + coord_3d.x;
break;
case 1:
edi = coord_3d.y - coord_3d.x + 0x2000;
break;
case 2:
edi = -(coord_3d.y + coord_3d.x) + 0x4000;
break;
case 3:
edi = coord_3d.x - coord_3d.y + 0x2000;
break;
}
if (edi < 0) {
edi = 0;
}
edi /= 32;
edi = min(edi, 0x1FF); // 511
ps->var_18 = edi;
paint_struct *old_ps = _paint_struct_quadrants[edi];
_paint_struct_quadrants[edi] = ps;
ps->next_quadrant_ps = old_ps;
if ((uint16)edi < _F1AD0C) {
_F1AD0C = edi;
}
if ((uint16)edi > _F1AD10) {
_F1AD10 = edi;
case 0:
positionHash = coord_3d.y + coord_3d.x;
break;
case 1:
positionHash = coord_3d.y - coord_3d.x + 0x2000;
break;
case 2:
positionHash = -(coord_3d.y + coord_3d.x) + 0x4000;
break;
case 3:
positionHash = coord_3d.x - coord_3d.y + 0x2000;
break;
}
paint_add_ps_to_quadrant(ps, positionHash);
gNextFreePaintStruct++;
@@ -397,27 +395,8 @@ paint_struct * sub_98197C(
break;
}
sint16 di = attach.x + attach.y;
if (di < 0)
di = 0;
di /= 32;
if (di > 511)
di = 511;
ps->var_18 = di;
paint_struct* old_ps = _paint_struct_quadrants[di];
_paint_struct_quadrants[di] = ps;
ps->next_quadrant_ps = old_ps;
if ((uint16)di < _F1AD0C) {
_F1AD0C = di;
}
if ((uint16)di > _F1AD10) {
_F1AD10 = di;
}
sint32 positionHash = attach.x + attach.y;
paint_add_ps_to_quadrant(ps, positionHash);
gNextFreePaintStruct++;
return ps;
@@ -534,29 +513,29 @@ paint_struct * sub_98199C(
*/
bool paint_attach_to_previous_attach(uint32 image_id, uint16 x, uint16 y)
{
if (g_aps_F1AD2C == NULL) {
return paint_attach_to_previous_ps(image_id, x, y);
}
if (g_aps_F1AD2C == NULL) {
return paint_attach_to_previous_ps(image_id, x, y);
}
if (gNextFreePaintStruct >= gEndOfPaintStructArray) {
return false;
}
return false;
}
attached_paint_struct * ps = &gNextFreePaintStruct->attached;
ps->image_id = image_id;
ps->x = x;
ps->y = y;
ps->flags = 0;
ps->image_id = image_id;
ps->x = x;
ps->y = y;
ps->flags = 0;
attached_paint_struct * ebx = g_aps_F1AD2C;
attached_paint_struct * ebx = g_aps_F1AD2C;
ps->next = NULL;
ebx->next = ps;
ps->next = NULL;
ebx->next = ps;
g_aps_F1AD2C = ps;
gNextFreePaintStruct++;
return true;
return true;
}
/**
@@ -570,30 +549,30 @@ bool paint_attach_to_previous_attach(uint32 image_id, uint16 x, uint16 y)
bool paint_attach_to_previous_ps(uint32 image_id, uint16 x, uint16 y)
{
if (gNextFreePaintStruct >= gEndOfPaintStructArray) {
return false;
}
return false;
}
attached_paint_struct * ps = &gNextFreePaintStruct->attached;
ps->image_id = image_id;
ps->x = x;
ps->y = y;
ps->flags = 0;
ps->image_id = image_id;
ps->x = x;
ps->y = y;
ps->flags = 0;
paint_struct * masterPs = g_ps_F1AD28;
if (masterPs == NULL) {
return false;
}
if (masterPs == NULL) {
return false;
}
gNextFreePaintStruct++;
attached_paint_struct * oldFirstAttached = masterPs->attached_ps;
attached_paint_struct * oldFirstAttached = masterPs->attached_ps;
masterPs->attached_ps = ps;
ps->next = oldFirstAttached;
ps->next = oldFirstAttached;
g_aps_F1AD2C = ps;
return true;
return true;
}
/**
@@ -609,8 +588,8 @@ bool paint_attach_to_previous_ps(uint32 image_id, uint16 x, uint16 y)
void sub_685EBC(money32 amount, rct_string_id string_id, sint16 y, sint16 z, sint8 y_offsets[], sint16 offset_x, uint32 rotation)
{
if (gNextFreePaintStruct >= gEndOfPaintStructArray) {
return;
}
return;
}
paint_string_struct * ps = &gNextFreePaintStruct->string;
ps->string_id = string_id;
@@ -629,25 +608,20 @@ void sub_685EBC(money32 amount, rct_string_id string_id, sint16 y, sint16 z, sin
gNextFreePaintStruct++;
paint_string_struct * oldPs = pss2;
pss2 = ps;
if (oldPs == 0) { // 0 or NULL?
pss1 = ps;
if (_paintLastPSString == NULL) {
gPaintPSStringHead = ps;
} else {
oldPs->next = ps;
_paintLastPSString->next = ps;
}
_paintLastPSString = ps;
}
/**
*
* rct2: 0x0068B6C2
*/
void viewport_paint_setup()
void paint_generate_structs(rct_drawpixelinfo * dpi)
{
rct_drawpixelinfo* dpi = unk_140E9A8;
rct_xy16 mapTile = {
.x = dpi->x & 0xFFE0,
.y = (dpi->y - 16) & 0xFFE0
@@ -751,11 +725,10 @@ void viewport_paint_setup()
}
}
static void sub_688217_helper(uint16 ax, uint8 flag)
static void paint_arrange_structs_helper(paint_struct * ps_next, uint16 ax, uint8 flag)
{
paint_struct *ps, *ps_temp;
paint_struct *ps_next = &unk_EE7884->basic;
paint_struct * ps;
paint_struct * ps_temp;
do {
ps = ps_next;
ps_next = ps_next->next_quadrant_ps;
@@ -763,7 +736,6 @@ static void sub_688217_helper(uint16 ax, uint8 flag)
} while (ax > ps_next->var_18);
ps_temp = ps;
do {
ps = ps->next_quadrant_ps;
if (ps == NULL) break;
@@ -778,7 +750,6 @@ static void sub_688217_helper(uint16 ax, uint8 flag)
ps->var_1B = flag | (1 << 0);
}
} while (ps->var_18 <= ax + 1);
ps = ps_temp;
uint8 rotation = get_current_rotation();
@@ -861,36 +832,70 @@ static void sub_688217_helper(uint16 ax, uint8 flag)
*
* rct2: 0x00688217
*/
void sub_688217()
paint_struct paint_arrange_structs()
{
paint_struct *ps_next;
unk_EE7884 = gNextFreePaintStruct++;
paint_struct *ps = &unk_EE7884->basic;
paint_struct psHead = { 0 };
paint_struct * ps = &psHead;
ps->next_quadrant_ps = NULL;
uint32 edi = _F1AD0C;
if (edi == -1)
return;
uint32 quadrantIndex = _paintQuadrantBackIndex;
if (quadrantIndex != UINT32_MAX) {
do {
paint_struct * ps_next = _paintQuadrants[quadrantIndex];
if (ps_next != NULL) {
ps->next_quadrant_ps = ps_next;
do {
ps = ps_next;
ps_next = ps_next->next_quadrant_ps;
} while (ps_next != NULL);
}
} while (++quadrantIndex <= _paintQuadrantFrontIndex);
do {
ps_next = _paint_struct_quadrants[edi];
if (ps_next != NULL) {
ps->next_quadrant_ps = ps_next;
do {
ps = ps_next;
ps_next = ps_next->next_quadrant_ps;
} while (ps_next != NULL);
paint_arrange_structs_helper(&psHead, _paintQuadrantBackIndex & 0xFFFF, 1 << 1);
quadrantIndex = _paintQuadrantBackIndex;
while (++quadrantIndex < _paintQuadrantFrontIndex) {
paint_arrange_structs_helper(&psHead, quadrantIndex & 0xFFFF, 0);
}
} while (++edi <= _F1AD10);
}
return psHead;
}
uint32 eax = _F1AD0C;
/**
*
* rct2: 0x00688485
*/
void paint_draw_structs(rct_drawpixelinfo * dpi, paint_struct * ps, uint32 viewFlags)
{
paint_struct* previous_ps = ps->next_quadrant_ps;
for (ps = ps->next_quadrant_ps; ps;) {
sint16 x = ps->x;
sint16 y = ps->y;
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_SPRITE) {
if (dpi->zoom_level >= 1) {
x = floor2(x, 2);
y = floor2(y, 2);
if (dpi->zoom_level >= 2) {
x = floor2(x, 4);
y = floor2(y, 4);
}
}
}
sub_688217_helper(eax & 0xFFFF, 1 << 1);
uint32 imageId = paint_ps_colourify_image(ps->image_id, ps->sprite_type, viewFlags);
if (gPaintBoundingBoxes && dpi->zoom_level == 0) {
paint_ps_image_with_bounding_boxes(dpi, ps, imageId, x, y);
} else {
paint_ps_image(dpi, ps, imageId, x, y);
}
eax = _F1AD0C;
while (++eax < _F1AD10)
sub_688217_helper(eax & 0xFFFF, 0);
if (ps->var_20 != 0) {
ps = ps->var_20;
} else {
paint_attached_ps(dpi, ps, viewFlags);
ps = previous_ps->next_quadrant_ps;
previous_ps = ps;
}
}
}
/**
@@ -898,174 +903,123 @@ void sub_688217()
* rct2: 0x00688596
* Part of 0x688485
*/
static void paint_attached_ps(paint_struct* ps, attached_paint_struct* attached_ps, rct_drawpixelinfo* dpi) {
static void paint_attached_ps(rct_drawpixelinfo * dpi, paint_struct * ps, uint32 viewFlags)
{
attached_paint_struct * attached_ps = ps->attached_ps;
for (; attached_ps; attached_ps = attached_ps->next) {
sint16 x = attached_ps->x + ps->x;
sint16 y = attached_ps->y + ps->y;
int image_id = attached_ps->image_id;
if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_RIDES) {
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_RIDE) {
if (image_id & 0x40000000) {
image_id &= 0x7FFFF;
image_id |= 0x41880000;
}
}
}
if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) {
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_SCENERY) {
if (image_id & 0x40000000) {
image_id &= 0x7FFFF;
image_id |= 0x41880000;
}
}
}
if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_PATHS) {
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_FOOTPATH) {
if (!(image_id & 0x40000000)) {
image_id &= 0x7FFFF;
image_id |= 0x41880000;
}
}
}
uint32 imageId = paint_ps_colourify_image(attached_ps->image_id, ps->sprite_type, viewFlags);
if (attached_ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) {
gfx_draw_sprite_raw_masked(dpi, x, y, image_id, attached_ps->colour_image_id);
}
else {
gfx_draw_sprite(dpi, image_id, x, y, ps->tertiary_colour);
gfx_draw_sprite_raw_masked(dpi, x, y, imageId, attached_ps->colour_image_id);
} else {
gfx_draw_sprite(dpi, imageId, x, y, ps->tertiary_colour);
}
}
}
/* rct2: 0x00688485 */
void paint_quadrant_ps() {
rct_drawpixelinfo* dpi = unk_140E9A8;
paint_struct* ps = &unk_EE7884->basic;
paint_struct* previous_ps = ps->next_quadrant_ps;
static void paint_ps_image_with_bounding_boxes(rct_drawpixelinfo * dpi, paint_struct * ps, uint32 imageId, sint16 x, sint16 y)
{
uint8 colour = BoundBoxDebugColours[ps->sprite_type];
for (ps = ps->next_quadrant_ps; ps;) {
sint16 x = ps->x;
sint16 y = ps->y;
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_SPRITE) {
if (dpi->zoom_level >= 1) {
x &= 0xFFFE;
y &= 0xFFFE;
if (dpi->zoom_level >= 2) {
x &= 0xFFFC;
y &= 0xFFFC;
}
}
}
int image_id = ps->image_id;
if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_RIDES) {
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_RIDE) {
if (!(image_id & 0x40000000)) {
image_id &= 0x7FFFF;
image_id |= 0x41880000;
}
}
}
if (gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) {
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_WALL) {
if (!(image_id & 0x40000000)) {
image_id &= 0x7FFFF;
image_id |= 0x41880000;
}
}
}
if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_PATHS) {
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_FOOTPATH ||
ps->sprite_type == VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM ||
ps->sprite_type == VIEWPORT_INTERACTION_ITEM_BANNER) {
if (!(image_id & 0x40000000)) {
image_id &= 0x7FFFF;
image_id |= 0x41880000;
}
}
}
if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) {
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY ||
ps->sprite_type == VIEWPORT_INTERACTION_ITEM_WALL ||
ps->sprite_type == VIEWPORT_INTERACTION_ITEM_SCENERY) {
if (!(image_id & 0x40000000)) {
image_id &= 0x7FFFF;
image_id |= 0x41880000;
}
}
}
rct_xyz16 frontTop = {.x = ps->bound_box_x_end, .y = ps->bound_box_y_end, .z = ps->bound_box_z_end};
rct_xy16 screenCoordFrontTop = coordinate_3d_to_2d(&frontTop, get_current_rotation());
rct_xyz16 frontBottom = {.x = ps->bound_box_x_end, .y = ps->bound_box_y_end, .z = ps->bound_box_z};
rct_xy16 screenCoordFrontBottom = coordinate_3d_to_2d(&frontBottom, get_current_rotation());
if (gPaintBoundingBoxes && dpi->zoom_level == 0) {
uint8 colour = BoundBoxDebugColours[ps->sprite_type];
rct_xyz16 leftTop = {.x = ps->bound_box_x, .y = ps->bound_box_y_end, .z = ps->bound_box_z_end};
rct_xy16 screenCoordLeftTop = coordinate_3d_to_2d(&leftTop, get_current_rotation());
rct_xyz16 leftBottom = {.x = ps->bound_box_x, .y = ps->bound_box_y_end, .z = ps->bound_box_z};
rct_xy16 screenCoordLeftBottom = coordinate_3d_to_2d(&leftBottom, get_current_rotation());
rct_xyz16 frontTop = {.x = ps->bound_box_x_end, .y = ps->bound_box_y_end, .z = ps->bound_box_z_end};
rct_xy16 screenCoordFrontTop = coordinate_3d_to_2d(&frontTop, get_current_rotation());
rct_xyz16 frontBottom = {.x = ps->bound_box_x_end, .y = ps->bound_box_y_end, .z = ps->bound_box_z};
rct_xy16 screenCoordFrontBottom = coordinate_3d_to_2d(&frontBottom, get_current_rotation());
rct_xyz16 rightTop = {.x = ps->bound_box_x_end, .y = ps->bound_box_y, .z = ps->bound_box_z_end};
rct_xy16 screenCoordRightTop = coordinate_3d_to_2d(&rightTop, get_current_rotation());
rct_xyz16 rightBottom = {.x = ps->bound_box_x_end, .y = ps->bound_box_y, .z = ps->bound_box_z};
rct_xy16 screenCoordRightBottom = coordinate_3d_to_2d(&rightBottom, get_current_rotation());
rct_xyz16 leftTop = {.x = ps->bound_box_x, .y = ps->bound_box_y_end, .z = ps->bound_box_z_end};
rct_xy16 screenCoordLeftTop = coordinate_3d_to_2d(&leftTop, get_current_rotation());
rct_xyz16 leftBottom = {.x = ps->bound_box_x, .y = ps->bound_box_y_end, .z = ps->bound_box_z};
rct_xy16 screenCoordLeftBottom = coordinate_3d_to_2d(&leftBottom, get_current_rotation());
rct_xyz16 backTop = {.x = ps->bound_box_x, .y = ps->bound_box_y, .z = ps->bound_box_z_end};
rct_xy16 screenCoordBackTop = coordinate_3d_to_2d(&backTop, get_current_rotation());
rct_xyz16 backBottom = {.x = ps->bound_box_x, .y = ps->bound_box_y, .z = ps->bound_box_z};
rct_xy16 screenCoordBackBottom = coordinate_3d_to_2d(&backBottom, get_current_rotation());
rct_xyz16 rightTop = {.x = ps->bound_box_x_end, .y = ps->bound_box_y, .z = ps->bound_box_z_end};
rct_xy16 screenCoordRightTop = coordinate_3d_to_2d(&rightTop, get_current_rotation());
rct_xyz16 rightBottom = {.x = ps->bound_box_x_end, .y = ps->bound_box_y, .z = ps->bound_box_z};
rct_xy16 screenCoordRightBottom = coordinate_3d_to_2d(&rightBottom, get_current_rotation());
// bottom square
gfx_draw_line(dpi, screenCoordFrontBottom.x, screenCoordFrontBottom.y, screenCoordLeftBottom.x, screenCoordLeftBottom.y, colour);
gfx_draw_line(dpi, screenCoordBackBottom.x, screenCoordBackBottom.y, screenCoordLeftBottom.x, screenCoordLeftBottom.y, colour);
gfx_draw_line(dpi, screenCoordBackBottom.x, screenCoordBackBottom.y, screenCoordRightBottom.x, screenCoordRightBottom.y, colour);
gfx_draw_line(dpi, screenCoordFrontBottom.x, screenCoordFrontBottom.y, screenCoordRightBottom.x, screenCoordRightBottom.y, colour);
rct_xyz16 backTop = {.x = ps->bound_box_x, .y = ps->bound_box_y, .z = ps->bound_box_z_end};
rct_xy16 screenCoordBackTop = coordinate_3d_to_2d(&backTop, get_current_rotation());
rct_xyz16 backBottom = {.x = ps->bound_box_x, .y = ps->bound_box_y, .z = ps->bound_box_z};
rct_xy16 screenCoordBackBottom = coordinate_3d_to_2d(&backBottom, get_current_rotation());
//vertical back + sides
gfx_draw_line(dpi, screenCoordBackTop.x, screenCoordBackTop.y, screenCoordBackBottom.x, screenCoordBackBottom.y, colour);
gfx_draw_line(dpi, screenCoordLeftTop.x, screenCoordLeftTop.y, screenCoordLeftBottom.x, screenCoordLeftBottom.y, colour);
gfx_draw_line(dpi, screenCoordRightTop.x, screenCoordRightTop.y, screenCoordRightBottom.x, screenCoordRightBottom.y, colour);
// bottom square
gfx_draw_line(dpi, screenCoordFrontBottom.x, screenCoordFrontBottom.y, screenCoordLeftBottom.x, screenCoordLeftBottom.y, colour);
gfx_draw_line(dpi, screenCoordBackBottom.x, screenCoordBackBottom.y, screenCoordLeftBottom.x, screenCoordLeftBottom.y, colour);
gfx_draw_line(dpi, screenCoordBackBottom.x, screenCoordBackBottom.y, screenCoordRightBottom.x, screenCoordRightBottom.y, colour);
gfx_draw_line(dpi, screenCoordFrontBottom.x, screenCoordFrontBottom.y, screenCoordRightBottom.x, screenCoordRightBottom.y, colour);
// top square back
gfx_draw_line(dpi, screenCoordBackTop.x, screenCoordBackTop.y, screenCoordLeftTop.x, screenCoordLeftTop.y, colour);
gfx_draw_line(dpi, screenCoordBackTop.x, screenCoordBackTop.y, screenCoordRightTop.x, screenCoordRightTop.y, colour);
//vertical back + sides
gfx_draw_line(dpi, screenCoordBackTop.x, screenCoordBackTop.y, screenCoordBackBottom.x, screenCoordBackBottom.y, colour);
gfx_draw_line(dpi, screenCoordLeftTop.x, screenCoordLeftTop.y, screenCoordLeftBottom.x, screenCoordLeftBottom.y, colour);
gfx_draw_line(dpi, screenCoordRightTop.x, screenCoordRightTop.y, screenCoordRightBottom.x, screenCoordRightBottom.y, colour);
paint_ps_image(dpi, ps, imageId, x, y);
// top square back
gfx_draw_line(dpi, screenCoordBackTop.x, screenCoordBackTop.y, screenCoordLeftTop.x, screenCoordLeftTop.y, colour);
gfx_draw_line(dpi, screenCoordBackTop.x, screenCoordBackTop.y, screenCoordRightTop.x, screenCoordRightTop.y, colour);
// vertical front
gfx_draw_line(dpi, screenCoordFrontTop.x, screenCoordFrontTop.y, screenCoordFrontBottom.x, screenCoordFrontBottom.y, colour);
if (ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) {
gfx_draw_sprite_raw_masked(dpi, x, y, image_id, ps->colour_image_id);
} else {
gfx_draw_sprite(dpi, image_id, x, y, ps->tertiary_colour);
}
// top square
gfx_draw_line(dpi, screenCoordFrontTop.x, screenCoordFrontTop.y, screenCoordLeftTop.x, screenCoordLeftTop.y, colour);
gfx_draw_line(dpi, screenCoordFrontTop.x, screenCoordFrontTop.y, screenCoordRightTop.x, screenCoordRightTop.y, colour);
}
// vertical front
gfx_draw_line(dpi, screenCoordFrontTop.x, screenCoordFrontTop.y, screenCoordFrontBottom.x, screenCoordFrontBottom.y, colour);
// top square
gfx_draw_line(dpi, screenCoordFrontTop.x, screenCoordFrontTop.y, screenCoordLeftTop.x, screenCoordLeftTop.y, colour);
gfx_draw_line(dpi, screenCoordFrontTop.x, screenCoordFrontTop.y, screenCoordRightTop.x, screenCoordRightTop.y, colour);
} else {
if (ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) {
gfx_draw_sprite_raw_masked(dpi, x, y, image_id, ps->colour_image_id);
} else {
gfx_draw_sprite(dpi, image_id, x, y, ps->tertiary_colour);
}
}
if (ps->var_20 != 0) {
ps = ps->var_20;
continue;
}
paint_attached_ps(ps, ps->attached_ps, dpi);
ps = previous_ps->next_quadrant_ps;
previous_ps = ps;
static void paint_ps_image(rct_drawpixelinfo * dpi, paint_struct * ps, uint32 imageId, sint16 x, sint16 y)
{
if (ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) {
gfx_draw_sprite_raw_masked(dpi, x, y, imageId, ps->colour_image_id);
} else {
gfx_draw_sprite(dpi, imageId, x, y, ps->tertiary_colour);
}
}
static uint32 paint_ps_colourify_image(uint32 imageId, uint8 spriteType, uint32 viewFlags)
{
if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_RIDES) {
if (spriteType == VIEWPORT_INTERACTION_ITEM_RIDE) {
if (!(imageId & 0x40000000)) {
imageId &= 0x7FFFF;
imageId |= 0x41880000;
}
}
}
if (viewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) {
if (spriteType == VIEWPORT_INTERACTION_ITEM_WALL) {
if (!(imageId & 0x40000000)) {
imageId &= 0x7FFFF;
imageId |= 0x41880000;
}
}
}
if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_PATHS) {
switch (spriteType) {
case VIEWPORT_INTERACTION_ITEM_FOOTPATH:
case VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM:
case VIEWPORT_INTERACTION_ITEM_BANNER:
if (!(imageId & 0x40000000)) {
imageId &= 0x7FFFF;
imageId |= 0x41880000;
}
break;
}
}
if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) {
switch (spriteType) {
case VIEWPORT_INTERACTION_ITEM_SCENERY:
case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY:
case VIEWPORT_INTERACTION_ITEM_WALL:
if (!(imageId & 0x40000000)) {
imageId &= 0x7FFFF;
imageId |= 0x41880000;
}
break;
}
}
return imageId;
}
static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo *dpi)
@@ -1082,27 +1036,23 @@ static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo *dpi)
*
* rct2: 0x006860C3
*/
void viewport_draw_money_effects()
void paint_draw_money_structs(rct_drawpixelinfo * dpi, paint_string_struct * ps)
{
utf8 buffer[256];
paint_string_struct *ps = pss1;
if (ps == NULL)
return;
rct_drawpixelinfo dpi = *(unk_140E9A8);
draw_pixel_info_crop_by_zoom(&dpi);
rct_drawpixelinfo dpi2 = *dpi;
draw_pixel_info_crop_by_zoom(&dpi2);
do {
utf8 buffer[256];
format_string(buffer, 256, ps->string_id, &ps->args);
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
// Use sprite font unless the currency contains characters unsupported by the sprite font
bool forceSpriteFont = false;
const currency_descriptor *currencyDesc = &CurrencyDescriptors[gConfigGeneral.currency_format];
if (gUseTrueTypeFont && font_supports_string_sprite(currencyDesc->symbol_unicode)) {
forceSpriteFont = true;
}
gfx_draw_string_with_y_offsets(&dpi, buffer, 0, ps->x, ps->y, (sint8 *)ps->y_offsets, forceSpriteFont);
gfx_draw_string_with_y_offsets(&dpi2, buffer, 0, ps->x, ps->y, (sint8 *)ps->y_offsets, forceSpriteFont);
} while ((ps = ps->next) != NULL);
}

View File

@@ -147,12 +147,12 @@ extern support_height gSupportSegments[9];
extern support_height gSupport;
#endif
extern paint_string_struct * gPaintPSStringHead;
/** rct2: 0x00993CC4 */
extern const uint32 construction_markers[];
extern bool gPaintBoundingBoxes;
void painter_setup();
paint_struct * sub_98196C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, sint16 z_offset, uint32 rotation);
paint_struct * sub_98197C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, sint16 z_offset, sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, uint32 rotation);
paint_struct * sub_98198C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, sint16 z_offset, sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, uint32 rotation);
@@ -168,8 +168,11 @@ bool paint_attach_to_previous_attach(uint32 image_id, uint16 x, uint16 y);
bool paint_attach_to_previous_ps(uint32 image_id, uint16 x, uint16 y);
void sub_685EBC(money32 amount, rct_string_id string_id, sint16 y, sint16 z, sint8 y_offsets[], sint16 offset_x, uint32 rotation);
void viewport_draw_money_effects();
void viewport_paint_setup();
void paint_init(rct_drawpixelinfo * dpi);
void paint_generate_structs(rct_drawpixelinfo * dpi);
paint_struct paint_arrange_structs();
void paint_draw_structs(rct_drawpixelinfo * dpi, paint_struct * ps, uint32 viewFlags);
void paint_draw_money_structs(rct_drawpixelinfo * dpi, paint_string_struct * ps);
// TESTING
#ifdef __TESTPAINT__

View File

@@ -2310,8 +2310,7 @@ static void sub_6CBCE2(
gCurrentViewportFlags = 0;
trackDirection &= 3;
gEndOfPaintStructArray = &gPaintStructs[4000 - 1];
painter_setup();
paint_init(unk_140E9A8);
ride = get_ride(rideIndex);
@@ -2413,8 +2412,8 @@ static void sub_6CBCE2(
gMapSize = preserveMapSize;
gMapSizeMaxXY = preserveMapSizeMaxXY;
sub_688217();
paint_quadrant_ps();
paint_struct ps = paint_arrange_structs();
paint_draw_structs(unk_140E9A8, &ps, gCurrentViewportFlags);
gCurrentViewportFlags = preserve_current_viewport_flags;
}

View File

@@ -345,6 +345,14 @@ static int climate_play_thunder(int instanceIndex, int soundId, int volume, int
#pragma region Climate / Weather data tables
/** rct2: 0x0098195C */
const uint32 ClimateWeatherGloomColours[4] = {
0xFFFFFFFF,
0x2000000 | 49,
0x2000000 | 50,
0x2000000 | 47,
};
// rct2: 0x00993C94
// There is actually a sprite at 0x5A9C for snow but only these weather types seem to be fully implemented
const rct_weather climate_weather_data[6] = {

View File

@@ -62,6 +62,7 @@ extern uint16 gClimateUpdateTimer;
extern uint16 gClimateLightningFlash;
extern const rct_weather climate_weather_data[6];
extern const uint32 ClimateWeatherGloomColours[4];
int climate_celsius_to_fahrenheit(int celsius);
void climate_reset(int climate);