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:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user