diff --git a/src/game.c b/src/game.c index 5a56eefcfd..05c54ac1ed 100644 --- a/src/game.c +++ b/src/game.c @@ -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; diff --git a/src/interface/viewport.c b/src/interface/viewport.c index bb58b0b12f..76387c823f 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -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; } diff --git a/src/interface/viewport.h b/src/interface/viewport.h index 59fb9d94a1..fdf6596185 100644 --- a/src/interface/viewport.h +++ b/src/interface/viewport.h @@ -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); diff --git a/src/paint/paint.c b/src/paint/paint.c index c44f6efa27..a1a6770dfe 100644 --- a/src/paint/paint.c +++ b/src/paint/paint.c @@ -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); } diff --git a/src/paint/paint.h b/src/paint/paint.h index d72d07b526..4b2f916fad 100644 --- a/src/paint/paint.h +++ b/src/paint/paint.h @@ -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__ diff --git a/src/windows/ride_construction.c b/src/windows/ride_construction.c index 54688d4aa4..27133606bc 100644 --- a/src/windows/ride_construction.c +++ b/src/windows/ride_construction.c @@ -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; } diff --git a/src/world/climate.c b/src/world/climate.c index a61782c8c9..3f2bee2394 100644 --- a/src/world/climate.c +++ b/src/world/climate.c @@ -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] = { diff --git a/src/world/climate.h b/src/world/climate.h index 349c6a6df0..a76a489bfc 100644 --- a/src/world/climate.h +++ b/src/world/climate.h @@ -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);