diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 634e420c..71173643 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -88,7 +88,11 @@ public: MxBool Find(T p_obj); void Detach(); + void Destroy(); MxBool Next(T& p_obj); + MxBool Current(T& p_obj); + void Advance(); + MxListEntry *GetMatch() { return m_match; } void SetValue(T p_obj); void Head() { m_match = m_list->m_first; } void Reset() { m_match = NULL; } @@ -209,6 +213,12 @@ inline void MxListCursor::Detach() m_match = NULL; } +template +inline void MxListCursor::Destroy() +{ + m_list->m_customDestructor(m_match->GetValue()); +} + template inline MxBool MxListCursor::Next(T& p_obj) { @@ -223,6 +233,24 @@ inline MxBool MxListCursor::Next(T& p_obj) return m_match != NULL; } +template +inline MxBool MxListCursor::Current(T& p_obj) +{ + if (m_match) + p_obj = m_match->GetValue(); + + return m_match != NULL; +} + +template +inline void MxListCursor::Advance() +{ + if (!m_match) + m_match = m_list->m_first; + else + m_match = m_match->m_next; +} + template inline void MxListCursor::SetValue(T p_obj) { diff --git a/LEGO1/mxregion.cpp b/LEGO1/mxregion.cpp index 07cdf70b..e858f60b 100644 --- a/LEGO1/mxregion.cpp +++ b/LEGO1/mxregion.cpp @@ -66,6 +66,7 @@ void MxRegion::vtable18(MxRect32 &p_rect) MxRegionTopBottom *newTopBottom = topBottom->Clone(); newTopBottom->m_bottom = rectCopy.m_top; topBottom->m_top = rectCopy.m_top; + // TODO: _InsertEntry currently inlined, shouldn't be cursor.Prepend(newTopBottom); } @@ -124,10 +125,53 @@ MxRegionTopBottom::MxRegionTopBottom(MxRect32 &p_rect) m_leftRightList->Append(leftRight); } -// OFFSET: LEGO1 0x100c5280 STUB +// OFFSET: 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->m_right < p_left); + + if (!a.GetMatch()) { + MxRegionLeftRight *copy = new MxRegionLeftRight(p_left, p_right); + m_leftRightList->OtherAppend(copy); + } + else { + if (p_left > leftRight->m_left) + p_left = leftRight->m_left; + + if (leftRight->m_left < p_right) { + do { + if (p_right < leftRight->m_right) + p_right = leftRight->m_right; + + // TODO: Currently inlined, shouldn't be + b = a; + b.Advance(); + + if (a.GetMatch()) { + a.Destroy(); + a.Detach(); + } + + if (!b.Current(leftRight)) + break; + + a = b; + } while (leftRight->m_left < p_right); + } + + if (a.GetMatch()) { + MxRegionLeftRight *copy = new MxRegionLeftRight(p_left, p_right); + a.Prepend(copy); + } + else { + MxRegionLeftRight *copy = new MxRegionLeftRight(p_left, p_right); + m_leftRightList->OtherAppend(copy); + } + } } // OFFSET: LEGO1 0x100c55d0