1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-23 15:52:55 +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 <openrct2/common.h>
#include <openrct2/drawing/Drawing.h>
#include <openrct2/sprites.h>
#ifndef __MACOSX__
# include <shared_mutex>
#endif
@@ -202,7 +203,7 @@ private:
std::vector<Atlas> _atlases;
std::unordered_map<GlyphId, AtlasTextureInfo, GlyphId::Hash, GlyphId::Equal> _glyphTextureMap;
std::vector<AtlasTextureInfo> _textureCache;
std::array<uint32_t, 0x7FFFF> _indexMap;
std::array<uint32_t, SPR_IMAGE_LIST_END> _indexMap;
GLuint _paletteTexture = 0;

View File

@@ -42,14 +42,14 @@ static void fixup_pointers(std::vector<RecordedPaintSession>& 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<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
{
auto nextQuadrantPs = reinterpret_cast<size_t>(entries[j].basic.next_quadrant_ps) / sizeof(paint_entry);
entries[j].basic.next_quadrant_ps = &s[i].Entries[nextQuadrantPs].basic;
auto nextQuadrantPs = reinterpret_cast<size_t>(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<RecordedPaintSession>& s)
else
{
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);
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)
{

View File

@@ -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<paint_struct*>(i * sizeof(paint_entry));
entryRemap[src.AsBasic()] = reinterpret_cast<paint_struct*>(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))
{

View File

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

View File

@@ -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;

View File

@@ -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<uint8_t, std::max({ sizeof(paint_struct), sizeof(attached_paint_struct), sizeof(paint_string_struct) })> data;
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
{
@@ -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;

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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,
};