1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-24 00:03:11 +01:00

Refactor paint structs to use ImageId and extend size of image list (#16258)

* Move to image ID for paint struct

* Move image list to be past the end of legacy limit

* Extend image list size

* Introduce constants for image list size

* Use std::array to store internal paint struct
This commit is contained in:
Ted John
2021-12-18 07:40:10 +00:00
committed by GitHub
parent 186d3efb59
commit e165de7482
9 changed files with 57 additions and 50 deletions

View File

@@ -18,6 +18,7 @@
#include <mutex> #include <mutex>
#include <openrct2/common.h> #include <openrct2/common.h>
#include <openrct2/drawing/Drawing.h> #include <openrct2/drawing/Drawing.h>
#include <openrct2/sprites.h>
#ifndef __MACOSX__ #ifndef __MACOSX__
# include <shared_mutex> # include <shared_mutex>
#endif #endif
@@ -202,7 +203,7 @@ private:
std::vector<Atlas> _atlases; std::vector<Atlas> _atlases;
std::unordered_map<GlyphId, AtlasTextureInfo, GlyphId::Hash, GlyphId::Equal> _glyphTextureMap; std::unordered_map<GlyphId, AtlasTextureInfo, GlyphId::Hash, GlyphId::Equal> _glyphTextureMap;
std::vector<AtlasTextureInfo> _textureCache; std::vector<AtlasTextureInfo> _textureCache;
std::array<uint32_t, 0x7FFFF> _indexMap; std::array<uint32_t, SPR_IMAGE_LIST_END> _indexMap;
GLuint _paletteTexture = 0; GLuint _paletteTexture = 0;

View File

@@ -42,14 +42,14 @@ static void fixup_pointers(std::vector<RecordedPaintSession>& s)
auto& quadrants = s[i].Session.Quadrants; auto& quadrants = s[i].Session.Quadrants;
for (size_t j = 0; j < entries.size(); j++) for (size_t j = 0; j < entries.size(); j++)
{ {
if (entries[j].basic.next_quadrant_ps == reinterpret_cast<paint_struct*>(-1)) if (entries[j].AsBasic()->next_quadrant_ps == reinterpret_cast<paint_struct*>(-1))
{ {
entries[j].basic.next_quadrant_ps = nullptr; entries[j].AsBasic()->next_quadrant_ps = nullptr;
} }
else else
{ {
auto nextQuadrantPs = reinterpret_cast<size_t>(entries[j].basic.next_quadrant_ps) / sizeof(paint_entry); auto nextQuadrantPs = reinterpret_cast<size_t>(entries[j].AsBasic()->next_quadrant_ps) / sizeof(paint_entry);
entries[j].basic.next_quadrant_ps = &s[i].Entries[nextQuadrantPs].basic; entries[j].AsBasic()->next_quadrant_ps = s[i].Entries[nextQuadrantPs].AsBasic();
} }
} }
for (size_t j = 0; j < std::size(quadrants); j++) for (size_t j = 0; j < std::size(quadrants); j++)
@@ -61,7 +61,7 @@ static void fixup_pointers(std::vector<RecordedPaintSession>& s)
else else
{ {
auto ps = reinterpret_cast<size_t>(quadrants[j]) / sizeof(paint_entry); auto ps = reinterpret_cast<size_t>(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<RecordedPaintSession> sessions(1); std::vector<RecordedPaintSession> sessions(1);
for (auto& ps : sessions[0].Entries) for (auto& ps : sessions[0].Entries)
{ {
ps.basic.next_quadrant_ps = reinterpret_cast<paint_struct*>(-1); ps.AsBasic()->next_quadrant_ps = reinterpret_cast<paint_struct*>(-1);
} }
for (auto& quad : sessions[0].Session.Quadrants) for (auto& quad : sessions[0].Session.Quadrants)
{ {

View File

@@ -857,7 +857,7 @@ static void record_session(
auto& src = chain->PaintStructs[i]; auto& src = chain->PaintStructs[i];
auto& dst = recordedSession.Entries[paintIndex++]; auto& dst = recordedSession.Entries[paintIndex++];
dst = src; dst = src;
entryRemap[&src.basic] = reinterpret_cast<paint_struct*>(i * sizeof(paint_entry)); entryRemap[src.AsBasic()] = reinterpret_cast<paint_struct*>(i * sizeof(paint_entry));
} }
chain = chain->Next; chain = chain->Next;
} }
@@ -866,7 +866,7 @@ static void record_session(
// Remap all entries // Remap all entries
for (auto& ps : recordedSession.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); auto it = entryRemap.find(ptr);
if (it == entryRemap.end()) if (it == entryRemap.end())
{ {
@@ -1662,8 +1662,7 @@ InteractionInfo set_interaction_info_from_paint_session(paint_session* session,
while (next_ps != nullptr) while (next_ps != nullptr)
{ {
ps = next_ps; ps = next_ps;
auto imageId = ImageId::FromUInt32(ps->image_id, ps->tertiary_colour); if (is_sprite_interacted_with(dpi, ps->image_id, { ps->x, ps->y }))
if (is_sprite_interacted_with(dpi, imageId, { ps->x, ps->y }))
{ {
if (PSSpriteTypeIsInFilter(ps, filter)) 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) 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, attached_ps->image_id, { (attached_ps->x + ps->x), (attached_ps->y + ps->y) }))
if (is_sprite_interacted_with(dpi, imageId, { (attached_ps->x + ps->x), (attached_ps->y + ps->y) }))
{ {
if (PSSpriteTypeIsInFilter(ps, filter)) if (PSSpriteTypeIsInFilter(ps, filter))
{ {

View File

@@ -25,7 +25,7 @@ struct rct_window;
struct EntityBase; struct EntityBase;
struct Guest; struct Guest;
struct Staff; struct Staff;
union paint_entry; struct paint_entry;
enum enum
{ {

View File

@@ -176,8 +176,7 @@ static paint_struct* CreateNormalPaintStruct(
return nullptr; return nullptr;
} }
ps->image_id = image_id.ToUInt32(); ps->image_id = image_id;
ps->tertiary_colour = image_id.GetTertiary();
ps->x = imagePos.x; ps->x = imagePos.x;
ps->y = imagePos.y; ps->y = imagePos.y;
ps->bounds.x_end = rotBoundBoxSize.x + rotBoundBoxOffset.x + session->SpritePosition.x; 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( auto imageId = PaintPSColourifyImage(ps->image_id, ps->sprite_type, session->ViewFlags);
ImageId::FromUInt32(ps->image_id, ps->tertiary_colour), ps->sprite_type, session->ViewFlags);
if (gPaintBoundingBoxes && dpi->zoom_level == ZoomLevel{ 0 }) if (gPaintBoundingBoxes && dpi->zoom_level == ZoomLevel{ 0 })
{ {
PaintPSImageWithBoundingBoxes(dpi, ps, imageId, x, y); 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 screenCoords = ScreenCoordsXY{ attached_ps->x + ps->x, attached_ps->y + ps->y };
auto imageId = PaintPSColourifyImage( auto imageId = PaintPSColourifyImage(attached_ps->image_id, ps->sprite_type, viewFlags);
ImageId::FromUInt32(attached_ps->image_id, ps->tertiary_colour), ps->sprite_type, viewFlags);
if (attached_ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) 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 else
{ {
@@ -654,7 +651,7 @@ static void PaintPSImage(rct_drawpixelinfo* dpi, paint_struct* ps, ImageId image
{ {
if (ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) 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 }); gfx_draw_sprite(dpi, imageId, { x, y });
@@ -882,8 +879,7 @@ bool PaintAttachToPreviousAttach(paint_session* session, ImageId imageId, int32_
return false; return false;
} }
ps->image_id = imageId.ToUInt32(); ps->image_id = imageId;
ps->tertiary_colour = imageId.GetTertiary();
ps->x = x; ps->x = x;
ps->y = y; ps->y = y;
ps->flags = 0; ps->flags = 0;
@@ -921,8 +917,7 @@ bool PaintAttachToPreviousPS(paint_session* session, ImageId image_id, int32_t x
return false; return false;
} }
ps->image_id = image_id.ToUInt32(); ps->image_id = image_id;
ps->tertiary_colour = image_id.GetTertiary();
ps->x = x; ps->x = x;
ps->y = y; ps->y = y;
ps->flags = 0; ps->flags = 0;

View File

@@ -26,13 +26,8 @@ enum class ViewportInteractionItem : uint8_t;
struct attached_paint_struct struct attached_paint_struct
{ {
attached_paint_struct* next; attached_paint_struct* next;
uint32_t image_id; ImageId image_id;
union ImageId colour_image_id;
{
uint32_t tertiary_colour;
// If masked image_id is masked_id
uint32_t colour_image_id;
};
int32_t x; int32_t x;
int32_t y; int32_t y;
uint8_t flags; uint8_t flags;
@@ -55,13 +50,8 @@ struct paint_struct
paint_struct* children; paint_struct* children;
paint_struct* next_quadrant_ps; paint_struct* next_quadrant_ps;
TileElement* tileElement; TileElement* tileElement;
uint32_t image_id; ImageId image_id;
union ImageId colour_image_id;
{
uint32_t tertiary_colour;
// If masked image_id is masked_id
uint32_t colour_image_id;
};
int32_t x; int32_t x;
int32_t y; int32_t y;
int32_t map_x; int32_t map_x;
@@ -82,12 +72,34 @@ struct paint_string_struct
uint8_t* y_offsets; uint8_t* y_offsets;
}; };
union paint_entry struct paint_entry
{ {
paint_struct basic; private:
attached_paint_struct attached; std::array<uint8_t, std::max({ sizeof(paint_struct), sizeof(attached_paint_struct), sizeof(paint_string_struct) })> data;
paint_string_struct string;
public:
paint_struct* AsBasic()
{
auto* res = reinterpret_cast<paint_struct*>(data.data());
::new (res) paint_struct();
return res;
}
attached_paint_struct* AsAttached()
{
auto* res = reinterpret_cast<attached_paint_struct*>(data.data());
::new (res) attached_paint_struct();
return res;
}
paint_string_struct* AsString()
{
auto* res = reinterpret_cast<paint_string_struct*>(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 struct sprite_bb
{ {
@@ -214,7 +226,7 @@ struct paint_session : public PaintSessionCore
auto* entry = PaintEntryChain.Allocate(); auto* entry = PaintEntryChain.Allocate();
if (entry != nullptr) if (entry != nullptr)
{ {
LastPS = &entry->basic; LastPS = entry->AsBasic();
return LastPS; return LastPS;
} }
return nullptr; return nullptr;
@@ -225,7 +237,7 @@ struct paint_session : public PaintSessionCore
auto* entry = PaintEntryChain.Allocate(); auto* entry = PaintEntryChain.Allocate();
if (entry != nullptr) if (entry != nullptr)
{ {
LastAttachedPS = &entry->attached; LastAttachedPS = entry->AsAttached();
return LastAttachedPS; return LastAttachedPS;
} }
return nullptr; return nullptr;
@@ -236,7 +248,7 @@ struct paint_session : public PaintSessionCore
auto* entry = PaintEntryChain.Allocate(); auto* entry = PaintEntryChain.Allocate();
if (entry != nullptr) if (entry != nullptr)
{ {
auto* string = &entry->string; auto* string = entry->AsString();
if (LastPSString == nullptr) if (LastPSString == nullptr)
{ {
PSStringHead = string; PSStringHead = string;

View File

@@ -529,7 +529,7 @@ static void viewport_surface_smoothen_edge(
{ {
attached_paint_struct* out = session->LastAttachedPS; attached_paint_struct* out = session->LastAttachedPS;
// set content and enable masking // 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; out->flags |= PAINT_STRUCT_FLAG_IS_MASKED;
} }
} }

View File

@@ -336,7 +336,7 @@ static void sub_68B3FB(paint_session* session, int32_t x, int32_t y)
if (ps != nullptr) if (ps != nullptr)
{ {
ps->flags &= PAINT_STRUCT_FLAG_IS_MASKED; ps->flags &= PAINT_STRUCT_FLAG_IS_MASKED;
ps->colour_image_id = COLOUR_BORDEAUX_RED; ps->image_id = ps->image_id.WithTertiary(COLOUR_BORDEAUX_RED);
} }
} }
} }

View File

@@ -1118,6 +1118,7 @@ enum
SPR_SCROLLING_TEXT_START = SPR_CSG_END, SPR_SCROLLING_TEXT_START = SPR_CSG_END,
SPR_SCROLLING_TEXT_END = SPR_SCROLLING_TEXT_START + OpenRCT2::MaxScrollingTextEntries, 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_BEGIN = SPR_SCROLLING_TEXT_END,
SPR_IMAGE_LIST_END = 0x7FFFE SPR_IMAGE_LIST_END = SPR_IMAGE_LIST_BEGIN + SPR_IMAGE_LIST_LENGTH,
}; };