mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-16 11:33:03 +01:00
Minor refactor work around the painting (#15226)
* Remove unused variables and drop packing of paint structs * Move PAINT_QUADRANT_FLAGS out of the header * Rename enum and variable to SortFlags * Rename variable and document the sorting * Apply review
This commit is contained in:
@@ -178,7 +178,6 @@ static paint_struct* CreateNormalPaintStruct(
|
||||
ps->attached_ps = nullptr;
|
||||
ps->children = nullptr;
|
||||
ps->sprite_type = session->InteractionType;
|
||||
ps->var_29 = 0;
|
||||
ps->map_x = session->MapPosition.x;
|
||||
ps->map_y = session->MapPosition.y;
|
||||
ps->tileElement = reinterpret_cast<TileElement*>(const_cast<void*>(session->CurrentlyDrawnItem));
|
||||
@@ -298,11 +297,21 @@ template<> bool CheckBoundingBox<3>(const paint_struct_bound_box& initialBBox, c
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace PaintSortFlags
|
||||
{
|
||||
static constexpr uint8_t None = 0;
|
||||
static constexpr uint8_t PendingVisit = (1U << 0);
|
||||
static constexpr uint8_t Neighbour = (1U << 1);
|
||||
static constexpr uint8_t OutsideQuadrant = (1U << 7);
|
||||
} // namespace PaintSortFlags
|
||||
|
||||
template<uint8_t _TRotation>
|
||||
static paint_struct* PaintArrangeStructsHelperRotation(paint_struct* ps_next, uint16_t quadrantIndex, uint8_t flag)
|
||||
{
|
||||
paint_struct* ps;
|
||||
paint_struct* ps_temp;
|
||||
|
||||
// Get the first node in the specified quadrant.
|
||||
do
|
||||
{
|
||||
ps = ps_next;
|
||||
@@ -311,9 +320,12 @@ static paint_struct* PaintArrangeStructsHelperRotation(paint_struct* ps_next, ui
|
||||
return ps;
|
||||
} while (quadrantIndex > ps_next->quadrant_index);
|
||||
|
||||
// Cache the last visited node so we don't have to walk the whole list again
|
||||
paint_struct* ps_cache = ps;
|
||||
// We keep track of the first node in the quadrant so the next call with a higher quadrant index
|
||||
// can use this node to skip some iterations.
|
||||
paint_struct* psQuadrantEntry = ps;
|
||||
|
||||
// Visit all nodes in the linked quadrant list and determine their current
|
||||
// sorting relevancy.
|
||||
ps_temp = ps;
|
||||
do
|
||||
{
|
||||
@@ -323,47 +335,63 @@ static paint_struct* PaintArrangeStructsHelperRotation(paint_struct* ps_next, ui
|
||||
|
||||
if (ps->quadrant_index > quadrantIndex + 1)
|
||||
{
|
||||
ps->quadrant_flags = PAINT_QUADRANT_FLAG_BIGGER;
|
||||
// Outside of the range.
|
||||
ps->SortFlags = PaintSortFlags::OutsideQuadrant;
|
||||
}
|
||||
else if (ps->quadrant_index == quadrantIndex + 1)
|
||||
{
|
||||
ps->quadrant_flags = PAINT_QUADRANT_FLAG_NEXT | PAINT_QUADRANT_FLAG_IDENTICAL;
|
||||
// Is neighbour and requires a visit.
|
||||
ps->SortFlags = PaintSortFlags::Neighbour | PaintSortFlags::PendingVisit;
|
||||
}
|
||||
else if (ps->quadrant_index == quadrantIndex)
|
||||
{
|
||||
ps->quadrant_flags = flag | PAINT_QUADRANT_FLAG_IDENTICAL;
|
||||
// In specified quadrant, requires visit.
|
||||
ps->SortFlags = flag | PaintSortFlags::PendingVisit;
|
||||
}
|
||||
} while (ps->quadrant_index <= quadrantIndex + 1);
|
||||
ps = ps_temp;
|
||||
|
||||
// Iterate all nodes in the current list and re-order them based on
|
||||
// the current rotation and their bounding box.
|
||||
while (true)
|
||||
{
|
||||
// Get the first pending node in the quadrant list
|
||||
while (true)
|
||||
{
|
||||
ps_next = ps->next_quadrant_ps;
|
||||
if (ps_next == nullptr)
|
||||
return ps_cache;
|
||||
if (ps_next->quadrant_flags & PAINT_QUADRANT_FLAG_BIGGER)
|
||||
return ps_cache;
|
||||
if (ps_next->quadrant_flags & PAINT_QUADRANT_FLAG_IDENTICAL)
|
||||
{
|
||||
// End of the current list.
|
||||
return psQuadrantEntry;
|
||||
}
|
||||
if (ps_next->SortFlags & PaintSortFlags::OutsideQuadrant)
|
||||
{
|
||||
// Reached point outside of specified quadrant.
|
||||
return psQuadrantEntry;
|
||||
}
|
||||
if (ps_next->SortFlags & PaintSortFlags::PendingVisit)
|
||||
{
|
||||
// Found node to check on.
|
||||
break;
|
||||
}
|
||||
ps = ps_next;
|
||||
}
|
||||
|
||||
ps_next->quadrant_flags &= ~PAINT_QUADRANT_FLAG_IDENTICAL;
|
||||
// Mark visited.
|
||||
ps_next->SortFlags &= ~PaintSortFlags::PendingVisit;
|
||||
ps_temp = ps;
|
||||
|
||||
// Compare current node against the remaining children.
|
||||
const paint_struct_bound_box& initialBBox = ps_next->bounds;
|
||||
|
||||
while (true)
|
||||
{
|
||||
ps = ps_next;
|
||||
ps_next = ps_next->next_quadrant_ps;
|
||||
if (ps_next == nullptr)
|
||||
break;
|
||||
if (ps_next->quadrant_flags & PAINT_QUADRANT_FLAG_BIGGER)
|
||||
if (ps_next->SortFlags & PaintSortFlags::OutsideQuadrant)
|
||||
break;
|
||||
if (!(ps_next->quadrant_flags & PAINT_QUADRANT_FLAG_NEXT))
|
||||
if (!(ps_next->SortFlags & PaintSortFlags::Neighbour))
|
||||
continue;
|
||||
|
||||
const paint_struct_bound_box& currentBBox = ps_next->bounds;
|
||||
@@ -372,6 +400,7 @@ static paint_struct* PaintArrangeStructsHelperRotation(paint_struct* ps_next, ui
|
||||
|
||||
if (compareResult)
|
||||
{
|
||||
// Child node intersects with current node, move behind.
|
||||
ps->next_quadrant_ps = ps_next->next_quadrant_ps;
|
||||
paint_struct* ps_temp2 = ps_temp->next_quadrant_ps;
|
||||
ps_temp->next_quadrant_ps = ps_next;
|
||||
@@ -410,12 +439,12 @@ template<int TRotation> static void PaintSessionArrange(PaintSessionCore* sessio
|
||||
} while (++quadrantIndex <= session->QuadrantFrontIndex);
|
||||
|
||||
paint_struct* ps_cache = PaintArrangeStructsHelperRotation<TRotation>(
|
||||
psHead, session->QuadrantBackIndex & 0xFFFF, PAINT_QUADRANT_FLAG_NEXT);
|
||||
psHead, session->QuadrantBackIndex & 0xFFFF, PaintSortFlags::Neighbour);
|
||||
|
||||
quadrantIndex = session->QuadrantBackIndex;
|
||||
while (++quadrantIndex < session->QuadrantFrontIndex)
|
||||
{
|
||||
ps_cache = PaintArrangeStructsHelperRotation<TRotation>(ps_cache, quadrantIndex & 0xFFFF, 0);
|
||||
ps_cache = PaintArrangeStructsHelperRotation<TRotation>(ps_cache, quadrantIndex & 0xFFFF, PaintSortFlags::None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ enum class ViewportInteractionItem : uint8_t;
|
||||
|
||||
struct attached_paint_struct
|
||||
{
|
||||
attached_paint_struct* next;
|
||||
uint32_t image_id;
|
||||
union
|
||||
{
|
||||
@@ -33,15 +34,6 @@ struct attached_paint_struct
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
uint8_t flags;
|
||||
uint8_t pad_0D;
|
||||
attached_paint_struct* next;
|
||||
};
|
||||
|
||||
enum PAINT_QUADRANT_FLAGS
|
||||
{
|
||||
PAINT_QUADRANT_FLAG_IDENTICAL = (1 << 0),
|
||||
PAINT_QUADRANT_FLAG_BIGGER = (1 << 7),
|
||||
PAINT_QUADRANT_FLAG_NEXT = (1 << 1),
|
||||
};
|
||||
|
||||
struct paint_struct_bound_box
|
||||
@@ -56,6 +48,11 @@ struct paint_struct_bound_box
|
||||
|
||||
struct paint_struct
|
||||
{
|
||||
paint_struct_bound_box bounds;
|
||||
attached_paint_struct* attached_ps;
|
||||
paint_struct* children;
|
||||
paint_struct* next_quadrant_ps;
|
||||
TileElement* tileElement;
|
||||
uint32_t image_id;
|
||||
union
|
||||
{
|
||||
@@ -63,31 +60,24 @@ struct paint_struct
|
||||
// If masked image_id is masked_id
|
||||
uint32_t colour_image_id;
|
||||
};
|
||||
paint_struct_bound_box bounds;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
uint16_t quadrant_index;
|
||||
uint8_t flags;
|
||||
uint8_t quadrant_flags;
|
||||
attached_paint_struct* attached_ps;
|
||||
paint_struct* children;
|
||||
paint_struct* next_quadrant_ps;
|
||||
ViewportInteractionItem sprite_type;
|
||||
uint8_t var_29;
|
||||
uint16_t pad_2A;
|
||||
int32_t map_x;
|
||||
int32_t map_y;
|
||||
TileElement* tileElement;
|
||||
uint16_t quadrant_index;
|
||||
uint8_t flags;
|
||||
uint8_t SortFlags;
|
||||
ViewportInteractionItem sprite_type;
|
||||
};
|
||||
|
||||
struct paint_string_struct
|
||||
{
|
||||
rct_string_id string_id; // 0x00
|
||||
paint_string_struct* next; // 0x02
|
||||
int32_t x; // 0x06
|
||||
int32_t y; // 0x08
|
||||
uint32_t args[4]; // 0x0A
|
||||
uint8_t* y_offsets; // 0x1A
|
||||
rct_string_id string_id;
|
||||
paint_string_struct* next;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
uint32_t args[4];
|
||||
uint8_t* y_offsets;
|
||||
};
|
||||
|
||||
union paint_entry
|
||||
|
||||
Reference in New Issue
Block a user