isle/LEGO1/mxregion.cpp
Christian Semmler 494a556f8e
(Proposal) Adjustments to "decomp" language (#308)
* Adjustments to "decomp" language

* Fix a comment

* Fix accidental clang-formatting

* Fix order

* Fix order

* Remove junk

* Fix OFFSET

* Adjustments based on new suggestions

* Annotate globals

* Globals in ISLE

* More globals

* Merge from parser2 branch

* Allow prepending space for exact marker match

* To eliminate noise, require the 0x prefix on offset for marker match

* fix test from previous

* Count tab stops for indented functions to reduce MISSED_END_OF_FUNCTION noise

* FUNCTION to SYNTHETIC where needed

* Missed marker conversion on SetAtomId

* pylint cleanup, remove unused code

* Fix unexpected function end, add more unit tests

* Be more strict about synthetic name syntax

* Revert "Missed marker conversion on SetAtomId"

This reverts commit d87d665127.

* Revert "FUNCTION to SYNTHETIC where needed"

This reverts commit 8c815418d2.

* Implicit lookup by name for functions

* Fix VTABLE SYNTHETIC and other decomp markers

* Get vtable class name

* Vtable marker should identify struct

* No colon for SIZE comment

* Update README.md

* Update README.md

* Update CONTRIBUTING.md

* Update README.md

* Update README.md

* Update CONTRIBUTING.md

* Update README.md

* Update CONTRIBUTING.md

* Fix destructor/annotation

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

---------

Co-authored-by: disinvite <disinvite@users.noreply.github.com>
2023-12-06 13:10:45 +01:00

198 lines
4.8 KiB
C++

#include "mxregion.h"
#include <limits.h>
DECOMP_SIZE_ASSERT(MxRegion, 0x1c);
DECOMP_SIZE_ASSERT(MxRegionTopBottom, 0x0c);
DECOMP_SIZE_ASSERT(MxRegionLeftRight, 0x08);
// FUNCTION: LEGO1 0x100c31c0
MxRegion::MxRegion()
{
m_list = new MxRegionList;
m_rect.SetPoint(MxPoint32(INT_MAX, INT_MAX));
m_rect.SetSize(MxSize32(-1, -1));
}
// FUNCTION: LEGO1 0x100c3660
MxBool MxRegion::vtable20()
{
return m_list->GetCount() == 0;
}
// FUNCTION: LEGO1 0x100c3690
MxRegion::~MxRegion()
{
if (m_list)
delete m_list;
}
// FUNCTION: LEGO1 0x100c3700
void MxRegion::Reset()
{
m_list->DeleteAll();
m_rect.SetPoint(MxPoint32(INT_MAX, INT_MAX));
m_rect.SetSize(MxSize32(-1, -1));
}
// FUNCTION: LEGO1 0x100c3750
void MxRegion::vtable18(MxRect32& p_rect)
{
MxRect32 rect(p_rect.GetPoint(), MxSize32(p_rect.GetRight(), p_rect.GetBottom()));
MxRegionListCursor cursor(m_list);
MxRegionTopBottom* topBottom;
while (rect.IsValid() && cursor.Next(topBottom)) {
if (topBottom->GetTop() >= rect.GetBottom()) {
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect);
cursor.Prepend(newTopBottom);
rect.SetTop(rect.GetBottom());
}
else if (rect.GetTop() < topBottom->GetBottom()) {
if (rect.GetTop() < topBottom->GetTop()) {
MxRect32 newRect(rect);
newRect.SetBottom(topBottom->GetTop());
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(newRect);
cursor.Prepend(newTopBottom);
rect.SetTop(topBottom->GetTop());
}
else if (topBottom->GetTop() < rect.GetTop()) {
MxRegionTopBottom* newTopBottom = topBottom->Clone();
newTopBottom->SetBottom(rect.GetTop());
topBottom->SetTop(rect.GetTop());
cursor.Prepend(newTopBottom);
}
if (rect.GetBottom() < topBottom->GetBottom()) {
MxRegionTopBottom* newTopBottom = topBottom->Clone();
newTopBottom->SetBottom(rect.GetBottom());
topBottom->SetTop(rect.GetBottom());
newTopBottom->FUN_100c5280(rect.GetLeft(), rect.GetRight());
cursor.Prepend(newTopBottom);
rect.SetTop(rect.GetBottom());
}
else {
topBottom->FUN_100c5280(rect.GetLeft(), rect.GetRight());
rect.SetTop(topBottom->GetBottom());
}
}
}
if (rect.IsValid()) {
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect);
m_list->Append(newTopBottom);
}
m_rect.UpdateBounds(p_rect);
}
// FUNCTION: LEGO1 0x100c3e20
MxBool MxRegion::vtable1c(MxRect32& p_rect)
{
if (!m_rect.IntersectsWith(p_rect))
return FALSE;
MxRegionListCursor cursor(m_list);
MxRegionTopBottom* topBottom;
while (cursor.Next(topBottom)) {
if (topBottom->GetTop() >= p_rect.GetBottom())
return FALSE;
if (topBottom->GetBottom() > p_rect.GetTop() && topBottom->FUN_100c57b0(p_rect))
return TRUE;
}
return FALSE;
}
// FUNCTION: LEGO1 0x100c4c90
MxRegionTopBottom::MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom)
{
m_top = p_top;
m_bottom = p_bottom;
m_leftRightList = new MxRegionLeftRightList;
}
// FUNCTION: LEGO1 0x100c50e0
MxRegionTopBottom::MxRegionTopBottom(MxRect32& p_rect)
{
m_top = p_rect.GetTop();
m_bottom = p_rect.GetBottom();
m_leftRightList = new MxRegionLeftRightList;
MxRegionLeftRight* leftRight = new MxRegionLeftRight(p_rect.GetLeft(), p_rect.GetRight());
m_leftRightList->Append(leftRight);
}
// FUNCTION: LEGO1 0x100c5280
void MxRegionTopBottom::FUN_100c5280(MxS32 p_left, MxS32 p_right)
{
MxRegionLeftRightListCursor a(m_leftRightList);
MxRegionLeftRightListCursor b(m_leftRightList);
MxRegionLeftRight* leftRight;
while (a.Next(leftRight) && leftRight->GetRight() < p_left)
;
if (!a.HasMatch()) {
MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right);
m_leftRightList->Append(copy);
}
else {
if (p_left > leftRight->GetLeft())
p_left = leftRight->GetLeft();
while (leftRight->GetLeft() < p_right) {
if (p_right < leftRight->GetRight())
p_right = leftRight->GetRight();
b = a;
b.Advance();
a.Destroy();
if (!b.Current(leftRight))
break;
a = b;
}
if (a.HasMatch()) {
MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right);
a.Prepend(copy);
}
else {
MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right);
m_leftRightList->Append(copy);
}
}
}
// FUNCTION: LEGO1 0x100c55d0
MxRegionTopBottom* MxRegionTopBottom::Clone()
{
MxRegionTopBottom* clone = new MxRegionTopBottom(m_top, m_bottom);
MxRegionLeftRightListCursor cursor(m_leftRightList);
MxRegionLeftRight* leftRight;
while (cursor.Next(leftRight))
clone->m_leftRightList->Append(leftRight->Clone());
return clone;
}
// FUNCTION: LEGO1 0x100c57b0
MxBool MxRegionTopBottom::FUN_100c57b0(MxRect32& p_rect)
{
MxRegionLeftRightListCursor cursor(m_leftRightList);
MxRegionLeftRight* leftRight;
while (cursor.Next(leftRight)) {
if (p_rect.GetRight() <= leftRight->GetLeft())
return FALSE;
if (leftRight->GetRight() > p_rect.GetLeft())
return TRUE;
}
return FALSE;
}