1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-20 21:43:06 +01:00

Fix #19991: Crash when using cut-away view (#19968)

* Fix #19991: Crash using cut-away view

* Update changelog.txt

* Document the use of temporary paint head
This commit is contained in:
Matthias Moninger
2023-04-20 18:00:22 +03:00
committed by GitHub
parent f7bd96fbbf
commit e614584f65
5 changed files with 18 additions and 14 deletions

View File

@@ -27,6 +27,7 @@
- Fix: [#19924] Destructible cheat does not allow partial ride modification.
- Fix: [#19950] Mine train block brake supports drawn incorrectly.
- Fix: [#19987] [Plugin] SetCheatAction has wrong ID in plugin API.
- Fix: [#19991] Crash using cut-away view.
0.4.4 (2023-03-28)
------------------------------------------------------------------------

View File

@@ -1834,10 +1834,10 @@ InteractionInfo SetInteractionInfoFromPaintSession(PaintSession* session, uint32
{
PROFILED_FUNCTION();
PaintStruct* ps = &session->PaintHead;
InteractionInfo info{};
while ((ps = ps->NextQuadrantEntry) != nullptr)
PaintStruct* ps = session->PaintHead;
while (ps != nullptr)
{
PaintStruct* old_ps = ps;
PaintStruct* next_ps = ps;
@@ -1868,7 +1868,7 @@ InteractionInfo SetInteractionInfoFromPaintSession(PaintSession* session, uint32
}
#pragma GCC diagnostic pop
ps = old_ps;
ps = old_ps->NextQuadrantEntry;
}
return info;
}

View File

@@ -447,9 +447,9 @@ static PaintStruct* PaintArrangeStructsHelperRotation(PaintStruct* psQuadrantEnt
// Iterates over all the quadrant lists and links them together as a
// singly linked list.
// The paint session has a head member which is the first entry.
static void PaintStructsLinkQuadrants(PaintSessionCore& session)
static void PaintStructsLinkQuadrants(PaintSessionCore& session, PaintStruct& psHead)
{
PaintStruct* ps = &session.PaintHead;
PaintStruct* ps = &psHead;
ps->NextQuadrantEntry = nullptr;
uint32_t quadrantIndex = session.QuadrantBackIndex;
@@ -477,15 +477,21 @@ template<int TRotation> static void PaintSessionArrangeImpl(PaintSessionCore& se
return;
}
PaintStructsLinkQuadrants(session);
// psHead is an intermediate node that is used to link all the quadrant lists together,
// this was previously stored in PaintSession but only the NextQuadrantEntry is relevant here.
// The head node is not part of the linked list and just serves as an entry point.
PaintStruct psHead{};
PaintStructsLinkQuadrants(session, psHead);
PaintStruct* psNextQuadrant = PaintArrangeStructsHelperRotation<TRotation>(
&session.PaintHead, session.QuadrantBackIndex, PaintSortFlags::Neighbour);
&psHead, session.QuadrantBackIndex, PaintSortFlags::Neighbour);
while (++quadrantIndex < session.QuadrantFrontIndex)
{
psNextQuadrant = PaintArrangeStructsHelperRotation<TRotation>(psNextQuadrant, quadrantIndex, PaintSortFlags::None);
}
session.PaintHead = psHead.NextQuadrantEntry;
}
using PaintArrangeWithRotation = void (*)(PaintSessionCore& session);
@@ -552,13 +558,9 @@ void PaintDrawStructs(PaintSession& session)
{
PROFILED_FUNCTION();
PaintStruct* ps = &session.PaintHead;
for (ps = ps->NextQuadrantEntry; ps != nullptr;)
for (PaintStruct* ps = session.PaintHead; ps != nullptr; ps = ps->NextQuadrantEntry)
{
PaintDrawStruct(session, ps);
ps = ps->NextQuadrantEntry;
}
}
@@ -691,7 +693,7 @@ PaintSession* PaintSessionAlloc(DrawPixelInfo& dpi, uint32_t viewFlags)
return GetContext()->GetPainter()->CreateSession(dpi, viewFlags);
}
void PaintSessionFree([[maybe_unused]] PaintSession* session)
void PaintSessionFree(PaintSession* session)
{
GetContext()->GetPainter()->ReleaseSession(session);
}

View File

@@ -179,7 +179,7 @@ public:
struct PaintSessionCore
{
PaintStruct PaintHead;
PaintStruct* PaintHead;
PaintStruct* Quadrants[MaxPaintQuadrants];
PaintStruct* LastPS;
PaintStringStruct* PSStringHead;

View File

@@ -160,6 +160,7 @@ PaintSession* Painter::CreateSession(DrawPixelInfo& dpi, uint32_t viewFlags)
session->Flags = 0;
std::fill(std::begin(session->Quadrants), std::end(session->Quadrants), nullptr);
session->PaintHead = nullptr;
session->LastPS = nullptr;
session->LastAttachedPS = nullptr;
session->PSStringHead = nullptr;