1
0
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:
ζeh Matt
2021-08-17 01:32:58 -07:00
committed by GitHub
parent 15ba3d3229
commit 4bc5f70581
2 changed files with 61 additions and 42 deletions

View File

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

View File

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