2023-10-14 15:33:11 -04:00
|
|
|
#include "mxregion.h"
|
|
|
|
|
2023-10-31 11:30:13 -04:00
|
|
|
#include <limits.h>
|
|
|
|
|
2023-10-14 15:33:11 -04:00
|
|
|
DECOMP_SIZE_ASSERT(MxRegion, 0x1c);
|
2023-10-31 11:30:13 -04:00
|
|
|
DECOMP_SIZE_ASSERT(MxRegionTopBottom, 0x0c);
|
|
|
|
DECOMP_SIZE_ASSERT(MxRegionLeftRight, 0x08);
|
2023-10-14 15:33:11 -04:00
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c31c0
|
2023-10-14 15:33:11 -04:00
|
|
|
MxRegion::MxRegion()
|
|
|
|
{
|
2023-10-31 11:30:13 -04:00
|
|
|
m_list = new MxRegionList;
|
|
|
|
m_rect.SetPoint(MxPoint32(INT_MAX, INT_MAX));
|
|
|
|
m_rect.SetSize(MxSize32(-1, -1));
|
|
|
|
}
|
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c3660
|
2023-10-31 11:30:13 -04:00
|
|
|
MxBool MxRegion::vtable20()
|
|
|
|
{
|
|
|
|
return m_list->GetCount() == 0;
|
2023-10-14 15:33:11 -04:00
|
|
|
}
|
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c3690
|
2023-10-14 15:33:11 -04:00
|
|
|
MxRegion::~MxRegion()
|
|
|
|
{
|
2023-10-31 11:30:13 -04:00
|
|
|
if (m_list)
|
|
|
|
delete m_list;
|
2023-10-14 15:33:11 -04:00
|
|
|
}
|
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c3700
|
2023-10-14 15:33:11 -04:00
|
|
|
void MxRegion::Reset()
|
|
|
|
{
|
2023-10-31 11:30:13 -04:00
|
|
|
m_list->DeleteAll();
|
|
|
|
m_rect.SetPoint(MxPoint32(INT_MAX, INT_MAX));
|
|
|
|
m_rect.SetSize(MxSize32(-1, -1));
|
2023-10-14 15:33:11 -04:00
|
|
|
}
|
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c3750
|
2023-10-24 19:38:27 -04:00
|
|
|
void MxRegion::vtable18(MxRect32& p_rect)
|
2023-10-14 15:33:11 -04:00
|
|
|
{
|
2023-11-06 18:12:09 -05:00
|
|
|
MxRect32 rect(p_rect.GetPoint(), MxSize32(p_rect.GetRight(), p_rect.GetBottom()));
|
2023-10-31 11:30:13 -04:00
|
|
|
MxRegionListCursor cursor(m_list);
|
2023-11-06 18:12:09 -05:00
|
|
|
MxRegionTopBottom* topBottom;
|
2023-10-31 11:30:13 -04:00
|
|
|
|
2023-11-06 18:12:09 -05:00
|
|
|
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());
|
2023-10-31 11:30:13 -04:00
|
|
|
}
|
2023-11-06 18:12:09 -05:00
|
|
|
else if (topBottom->GetTop() < rect.GetTop()) {
|
|
|
|
MxRegionTopBottom* newTopBottom = topBottom->Clone();
|
|
|
|
newTopBottom->SetBottom(rect.GetTop());
|
|
|
|
topBottom->SetTop(rect.GetTop());
|
|
|
|
cursor.Prepend(newTopBottom);
|
2023-10-31 11:30:13 -04:00
|
|
|
}
|
|
|
|
|
2023-11-06 18:12:09 -05:00
|
|
|
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());
|
|
|
|
}
|
2023-10-31 11:30:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-06 18:12:09 -05:00
|
|
|
if (rect.IsValid()) {
|
|
|
|
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect);
|
2023-11-06 08:04:51 -05:00
|
|
|
m_list->Append(newTopBottom);
|
2023-10-31 11:30:13 -04:00
|
|
|
}
|
|
|
|
|
2023-11-06 18:12:09 -05:00
|
|
|
m_rect.UpdateBounds(p_rect);
|
2023-10-31 11:30:13 -04:00
|
|
|
}
|
|
|
|
|
2023-12-07 14:14:49 -05:00
|
|
|
// SYNTHETIC: LEGO1 0x100c3be0
|
|
|
|
// MxRegionListCursor::`scalar deleting destructor'
|
|
|
|
|
|
|
|
// TEMPLATE: LEGO1 0x100c3c50
|
|
|
|
// MxPtrListCursor<MxRegionTopBottom>::~MxPtrListCursor<MxRegionTopBottom>
|
|
|
|
|
|
|
|
// SYNTHETIC: LEGO1 0x100c3ca0
|
|
|
|
// MxListCursor<MxRegionTopBottom *>::`scalar deleting destructor'
|
|
|
|
|
|
|
|
// SYNTHETIC: LEGO1 0x100c3d10
|
|
|
|
// MxPtrListCursor<MxRegionTopBottom>::`scalar deleting destructor'
|
|
|
|
|
|
|
|
// TEMPLATE: LEGO1 0x100c3d80
|
|
|
|
// MxListCursor<MxRegionTopBottom *>::~MxListCursor<MxRegionTopBottom *>
|
|
|
|
|
|
|
|
// FUNCTION: LEGO1 0x100c3dd0
|
|
|
|
// MxRegionListCursor::~MxRegionListCursor
|
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c3e20
|
2023-10-31 11:30:13 -04:00
|
|
|
MxBool MxRegion::vtable1c(MxRect32& p_rect)
|
|
|
|
{
|
2023-11-06 18:12:09 -05:00
|
|
|
if (!m_rect.IntersectsWith(p_rect))
|
2023-10-31 11:30:13 -04:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
MxRegionListCursor cursor(m_list);
|
|
|
|
MxRegionTopBottom* topBottom;
|
|
|
|
|
|
|
|
while (cursor.Next(topBottom)) {
|
2023-11-06 18:12:09 -05:00
|
|
|
if (topBottom->GetTop() >= p_rect.GetBottom())
|
2023-10-31 11:30:13 -04:00
|
|
|
return FALSE;
|
2023-11-06 18:12:09 -05:00
|
|
|
if (topBottom->GetBottom() > p_rect.GetTop() && topBottom->FUN_100c57b0(p_rect))
|
2023-10-31 11:30:13 -04:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
2023-10-14 15:33:11 -04:00
|
|
|
}
|
|
|
|
|
2023-12-07 14:14:49 -05:00
|
|
|
// SYNTHETIC: LEGO1 0x100c4790
|
|
|
|
// MxRegionLeftRightListCursor::`scalar deleting destructor'
|
|
|
|
|
|
|
|
// TEMPLATE: LEGO1 0x100c4800
|
|
|
|
// MxPtrListCursor<MxRegionLeftRight>::~MxPtrListCursor<MxRegionLeftRight>
|
|
|
|
|
|
|
|
// SYNTHETIC: LEGO1 0x100c4850
|
|
|
|
// MxListCursor<MxRegionLeftRight *>::`scalar deleting destructor'
|
|
|
|
|
|
|
|
// SYNTHETIC: LEGO1 0x100c48c0
|
|
|
|
// MxPtrListCursor<MxRegionLeftRight>::`scalar deleting destructor'
|
|
|
|
|
|
|
|
// TEMPLATE: LEGO1 0x100c4930
|
|
|
|
// MxListCursor<MxRegionLeftRight *>::~MxListCursor<MxRegionLeftRight *>
|
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c4c90
|
2023-10-31 11:30:13 -04:00
|
|
|
MxRegionTopBottom::MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom)
|
2023-10-14 15:33:11 -04:00
|
|
|
{
|
2023-10-31 11:30:13 -04:00
|
|
|
m_top = p_top;
|
|
|
|
m_bottom = p_bottom;
|
|
|
|
m_leftRightList = new MxRegionLeftRightList;
|
2023-10-14 15:33:11 -04:00
|
|
|
}
|
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c50e0
|
2023-10-31 11:30:13 -04:00
|
|
|
MxRegionTopBottom::MxRegionTopBottom(MxRect32& p_rect)
|
2023-10-14 15:33:11 -04:00
|
|
|
{
|
2023-11-06 18:12:09 -05:00
|
|
|
m_top = p_rect.GetTop();
|
|
|
|
m_bottom = p_rect.GetBottom();
|
2023-10-31 11:30:13 -04:00
|
|
|
m_leftRightList = new MxRegionLeftRightList;
|
|
|
|
|
2023-11-06 18:12:09 -05:00
|
|
|
MxRegionLeftRight* leftRight = new MxRegionLeftRight(p_rect.GetLeft(), p_rect.GetRight());
|
2023-10-31 11:30:13 -04:00
|
|
|
m_leftRightList->Append(leftRight);
|
|
|
|
}
|
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c5280
|
2023-10-31 11:30:13 -04:00
|
|
|
void MxRegionTopBottom::FUN_100c5280(MxS32 p_left, MxS32 p_right)
|
|
|
|
{
|
|
|
|
MxRegionLeftRightListCursor a(m_leftRightList);
|
|
|
|
MxRegionLeftRightListCursor b(m_leftRightList);
|
|
|
|
|
|
|
|
MxRegionLeftRight* leftRight;
|
2023-11-06 18:12:09 -05:00
|
|
|
while (a.Next(leftRight) && leftRight->GetRight() < p_left)
|
2023-10-31 11:30:13 -04:00
|
|
|
;
|
|
|
|
|
|
|
|
if (!a.HasMatch()) {
|
|
|
|
MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right);
|
2023-11-06 08:04:51 -05:00
|
|
|
m_leftRightList->Append(copy);
|
2023-10-31 11:30:13 -04:00
|
|
|
}
|
|
|
|
else {
|
2023-11-06 18:12:09 -05:00
|
|
|
if (p_left > leftRight->GetLeft())
|
|
|
|
p_left = leftRight->GetLeft();
|
2023-10-31 11:30:13 -04:00
|
|
|
|
2023-11-06 18:12:09 -05:00
|
|
|
while (leftRight->GetLeft() < p_right) {
|
|
|
|
if (p_right < leftRight->GetRight())
|
|
|
|
p_right = leftRight->GetRight();
|
2023-10-31 11:30:13 -04:00
|
|
|
|
|
|
|
b = a;
|
|
|
|
b.Advance();
|
2023-11-06 08:04:51 -05:00
|
|
|
a.Destroy();
|
2023-10-31 11:30:13 -04:00
|
|
|
|
|
|
|
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);
|
2023-11-06 08:04:51 -05:00
|
|
|
m_leftRightList->Append(copy);
|
2023-10-31 11:30:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-07 14:14:49 -05:00
|
|
|
// TEMPLATE: LEGO1 0x100c54f0
|
|
|
|
// MxListCursor<MxRegionLeftRight *>::MxListCursor<MxRegionLeftRight *>
|
|
|
|
|
|
|
|
// FUNCTION: LEGO1 0x100c5560
|
|
|
|
// MxRegionLeftRightListCursor::~MxRegionLeftRightListCursor
|
|
|
|
|
|
|
|
// TEMPLATE: LEGO1 0x100c55b0
|
|
|
|
// MxListCursor<MxRegionLeftRight *>::operator=
|
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c55d0
|
2023-10-31 11:30:13 -04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-12-06 07:10:45 -05:00
|
|
|
// FUNCTION: LEGO1 0x100c57b0
|
2023-10-31 11:30:13 -04:00
|
|
|
MxBool MxRegionTopBottom::FUN_100c57b0(MxRect32& p_rect)
|
|
|
|
{
|
|
|
|
MxRegionLeftRightListCursor cursor(m_leftRightList);
|
|
|
|
MxRegionLeftRight* leftRight;
|
|
|
|
|
|
|
|
while (cursor.Next(leftRight)) {
|
2023-11-06 18:12:09 -05:00
|
|
|
if (p_rect.GetRight() <= leftRight->GetLeft())
|
2023-10-31 11:30:13 -04:00
|
|
|
return FALSE;
|
2023-11-06 18:12:09 -05:00
|
|
|
if (leftRight->GetRight() > p_rect.GetLeft())
|
2023-10-31 11:30:13 -04:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2023-10-24 19:38:27 -04:00
|
|
|
return FALSE;
|
2023-10-25 14:51:59 -04:00
|
|
|
}
|