diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h index adb0da2a0e..6b7f508af2 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h @@ -18,6 +18,7 @@ #include #include #include +#include #ifndef __MACOSX__ # include #endif @@ -202,7 +203,7 @@ private: std::vector _atlases; std::unordered_map _glyphTextureMap; std::vector _textureCache; - std::array _indexMap; + std::array _indexMap; GLuint _paletteTexture = 0; diff --git a/src/openrct2/cmdline/BenchSpriteSort.cpp b/src/openrct2/cmdline/BenchSpriteSort.cpp index 1f605150a5..ab8625eb35 100644 --- a/src/openrct2/cmdline/BenchSpriteSort.cpp +++ b/src/openrct2/cmdline/BenchSpriteSort.cpp @@ -42,14 +42,14 @@ static void fixup_pointers(std::vector& s) auto& quadrants = s[i].Session.Quadrants; for (size_t j = 0; j < entries.size(); j++) { - if (entries[j].basic.next_quadrant_ps == reinterpret_cast(-1)) + if (entries[j].AsBasic()->next_quadrant_ps == reinterpret_cast(-1)) { - entries[j].basic.next_quadrant_ps = nullptr; + entries[j].AsBasic()->next_quadrant_ps = nullptr; } else { - auto nextQuadrantPs = reinterpret_cast(entries[j].basic.next_quadrant_ps) / sizeof(paint_entry); - entries[j].basic.next_quadrant_ps = &s[i].Entries[nextQuadrantPs].basic; + auto nextQuadrantPs = reinterpret_cast(entries[j].AsBasic()->next_quadrant_ps) / sizeof(paint_entry); + entries[j].AsBasic()->next_quadrant_ps = s[i].Entries[nextQuadrantPs].AsBasic(); } } for (size_t j = 0; j < std::size(quadrants); j++) @@ -61,7 +61,7 @@ static void fixup_pointers(std::vector& s) else { auto ps = reinterpret_cast(quadrants[j]) / sizeof(paint_entry); - quadrants[j] = &entries[ps].basic; + quadrants[j] = entries[ps].AsBasic(); } } } @@ -164,7 +164,7 @@ static int cmdline_for_bench_sprite_sort(int argc, const char** argv) std::vector sessions(1); for (auto& ps : sessions[0].Entries) { - ps.basic.next_quadrant_ps = reinterpret_cast(-1); + ps.AsBasic()->next_quadrant_ps = reinterpret_cast(-1); } for (auto& quad : sessions[0].Session.Quadrants) { diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 1dcfe3f418..4d6989f62a 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -857,7 +857,7 @@ static void record_session( auto& src = chain->PaintStructs[i]; auto& dst = recordedSession.Entries[paintIndex++]; dst = src; - entryRemap[&src.basic] = reinterpret_cast(i * sizeof(paint_entry)); + entryRemap[src.AsBasic()] = reinterpret_cast(i * sizeof(paint_entry)); } chain = chain->Next; } @@ -866,7 +866,7 @@ static void record_session( // Remap all entries for (auto& ps : recordedSession.Entries) { - auto& ptr = ps.basic.next_quadrant_ps; + auto& ptr = ps.AsBasic()->next_quadrant_ps; auto it = entryRemap.find(ptr); if (it == entryRemap.end()) { @@ -1662,8 +1662,7 @@ InteractionInfo set_interaction_info_from_paint_session(paint_session* session, while (next_ps != nullptr) { ps = next_ps; - auto imageId = ImageId::FromUInt32(ps->image_id, ps->tertiary_colour); - if (is_sprite_interacted_with(dpi, imageId, { ps->x, ps->y })) + if (is_sprite_interacted_with(dpi, ps->image_id, { ps->x, ps->y })) { if (PSSpriteTypeIsInFilter(ps, filter)) { @@ -1675,8 +1674,7 @@ InteractionInfo set_interaction_info_from_paint_session(paint_session* session, for (attached_paint_struct* attached_ps = ps->attached_ps; attached_ps != nullptr; attached_ps = attached_ps->next) { - auto imageId = ImageId::FromUInt32(attached_ps->image_id, attached_ps->tertiary_colour); - if (is_sprite_interacted_with(dpi, imageId, { (attached_ps->x + ps->x), (attached_ps->y + ps->y) })) + if (is_sprite_interacted_with(dpi, attached_ps->image_id, { (attached_ps->x + ps->x), (attached_ps->y + ps->y) })) { if (PSSpriteTypeIsInFilter(ps, filter)) { diff --git a/src/openrct2/interface/Viewport.h b/src/openrct2/interface/Viewport.h index ac1e394014..b2c655c195 100644 --- a/src/openrct2/interface/Viewport.h +++ b/src/openrct2/interface/Viewport.h @@ -25,7 +25,7 @@ struct rct_window; struct EntityBase; struct Guest; struct Staff; -union paint_entry; +struct paint_entry; enum { diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index 77222465e6..8040d542b1 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -176,8 +176,7 @@ static paint_struct* CreateNormalPaintStruct( return nullptr; } - ps->image_id = image_id.ToUInt32(); - ps->tertiary_colour = image_id.GetTertiary(); + ps->image_id = image_id; ps->x = imagePos.x; ps->y = imagePos.y; ps->bounds.x_end = rotBoundBoxSize.x + rotBoundBoxOffset.x + session->SpritePosition.x; @@ -502,8 +501,7 @@ static void PaintDrawStruct(paint_session* session, paint_struct* ps) } } - auto imageId = PaintPSColourifyImage( - ImageId::FromUInt32(ps->image_id, ps->tertiary_colour), ps->sprite_type, session->ViewFlags); + auto imageId = PaintPSColourifyImage(ps->image_id, ps->sprite_type, session->ViewFlags); if (gPaintBoundingBoxes && dpi->zoom_level == ZoomLevel{ 0 }) { PaintPSImageWithBoundingBoxes(dpi, ps, imageId, x, y); @@ -551,11 +549,10 @@ static void PaintAttachedPS(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t v { auto screenCoords = ScreenCoordsXY{ attached_ps->x + ps->x, attached_ps->y + ps->y }; - auto imageId = PaintPSColourifyImage( - ImageId::FromUInt32(attached_ps->image_id, ps->tertiary_colour), ps->sprite_type, viewFlags); + auto imageId = PaintPSColourifyImage(attached_ps->image_id, ps->sprite_type, viewFlags); if (attached_ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) { - gfx_draw_sprite_raw_masked(dpi, screenCoords, imageId, ImageId::FromUInt32(attached_ps->colour_image_id)); + gfx_draw_sprite_raw_masked(dpi, screenCoords, imageId, attached_ps->colour_image_id); } else { @@ -654,7 +651,7 @@ static void PaintPSImage(rct_drawpixelinfo* dpi, paint_struct* ps, ImageId image { if (ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) { - return gfx_draw_sprite_raw_masked(dpi, { x, y }, imageId, ImageId::FromUInt32(ps->colour_image_id)); + return gfx_draw_sprite_raw_masked(dpi, { x, y }, imageId, ps->colour_image_id); } gfx_draw_sprite(dpi, imageId, { x, y }); @@ -882,8 +879,7 @@ bool PaintAttachToPreviousAttach(paint_session* session, ImageId imageId, int32_ return false; } - ps->image_id = imageId.ToUInt32(); - ps->tertiary_colour = imageId.GetTertiary(); + ps->image_id = imageId; ps->x = x; ps->y = y; ps->flags = 0; @@ -921,8 +917,7 @@ bool PaintAttachToPreviousPS(paint_session* session, ImageId image_id, int32_t x return false; } - ps->image_id = image_id.ToUInt32(); - ps->tertiary_colour = image_id.GetTertiary(); + ps->image_id = image_id; ps->x = x; ps->y = y; ps->flags = 0; diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index cb7ee44154..f57f461927 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -26,13 +26,8 @@ enum class ViewportInteractionItem : uint8_t; struct attached_paint_struct { attached_paint_struct* next; - uint32_t image_id; - union - { - uint32_t tertiary_colour; - // If masked image_id is masked_id - uint32_t colour_image_id; - }; + ImageId image_id; + ImageId colour_image_id; int32_t x; int32_t y; uint8_t flags; @@ -55,13 +50,8 @@ struct paint_struct paint_struct* children; paint_struct* next_quadrant_ps; TileElement* tileElement; - uint32_t image_id; - union - { - uint32_t tertiary_colour; - // If masked image_id is masked_id - uint32_t colour_image_id; - }; + ImageId image_id; + ImageId colour_image_id; int32_t x; int32_t y; int32_t map_x; @@ -82,12 +72,34 @@ struct paint_string_struct uint8_t* y_offsets; }; -union paint_entry +struct paint_entry { - paint_struct basic; - attached_paint_struct attached; - paint_string_struct string; +private: + std::array data; + +public: + paint_struct* AsBasic() + { + auto* res = reinterpret_cast(data.data()); + ::new (res) paint_struct(); + return res; + } + attached_paint_struct* AsAttached() + { + auto* res = reinterpret_cast(data.data()); + ::new (res) attached_paint_struct(); + return res; + } + paint_string_struct* AsString() + { + auto* res = reinterpret_cast(data.data()); + ::new (res) paint_string_struct(); + return res; + } }; +static_assert(sizeof(paint_entry) >= sizeof(paint_struct)); +static_assert(sizeof(paint_entry) >= sizeof(attached_paint_struct)); +static_assert(sizeof(paint_entry) >= sizeof(paint_string_struct)); struct sprite_bb { @@ -214,7 +226,7 @@ struct paint_session : public PaintSessionCore auto* entry = PaintEntryChain.Allocate(); if (entry != nullptr) { - LastPS = &entry->basic; + LastPS = entry->AsBasic(); return LastPS; } return nullptr; @@ -225,7 +237,7 @@ struct paint_session : public PaintSessionCore auto* entry = PaintEntryChain.Allocate(); if (entry != nullptr) { - LastAttachedPS = &entry->attached; + LastAttachedPS = entry->AsAttached(); return LastAttachedPS; } return nullptr; @@ -236,7 +248,7 @@ struct paint_session : public PaintSessionCore auto* entry = PaintEntryChain.Allocate(); if (entry != nullptr) { - auto* string = &entry->string; + auto* string = entry->AsString(); if (LastPSString == nullptr) { PSStringHead = string; diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index 3d65495636..86927735a8 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -529,7 +529,7 @@ static void viewport_surface_smoothen_edge( { attached_paint_struct* out = session->LastAttachedPS; // set content and enable masking - out->colour_image_id = get_surface_pattern(neighbour.terrain, cl).ToUInt32(); + out->colour_image_id = get_surface_pattern(neighbour.terrain, cl); out->flags |= PAINT_STRUCT_FLAG_IS_MASKED; } } diff --git a/src/openrct2/paint/tile_element/Paint.TileElement.cpp b/src/openrct2/paint/tile_element/Paint.TileElement.cpp index 818f2b159b..348859c972 100644 --- a/src/openrct2/paint/tile_element/Paint.TileElement.cpp +++ b/src/openrct2/paint/tile_element/Paint.TileElement.cpp @@ -336,7 +336,7 @@ static void sub_68B3FB(paint_session* session, int32_t x, int32_t y) if (ps != nullptr) { ps->flags &= PAINT_STRUCT_FLAG_IS_MASKED; - ps->colour_image_id = COLOUR_BORDEAUX_RED; + ps->image_id = ps->image_id.WithTertiary(COLOUR_BORDEAUX_RED); } } } diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 6b5b4cf742..3e5e07dc22 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1118,6 +1118,7 @@ enum SPR_SCROLLING_TEXT_START = SPR_CSG_END, SPR_SCROLLING_TEXT_END = SPR_SCROLLING_TEXT_START + OpenRCT2::MaxScrollingTextEntries, + SPR_IMAGE_LIST_LENGTH = 1000000, SPR_IMAGE_LIST_BEGIN = SPR_SCROLLING_TEXT_END, - SPR_IMAGE_LIST_END = 0x7FFFE + SPR_IMAGE_LIST_END = SPR_IMAGE_LIST_BEGIN + SPR_IMAGE_LIST_LENGTH, };