Adapt MxRegion.h (#1393)

* Adapt MxRegion.h

* Use specific GH action version

* Disable clang32 for now

* Fix regression

* Add space

* Add BETA annotations
This commit is contained in:
Christian Semmler
2025-02-26 19:30:11 -07:00
committed by GitHub
parent ea5a722311
commit 67b25b0bcc
15 changed files with 947 additions and 911 deletions

View File

@@ -2,108 +2,104 @@
#include <limits.h>
DECOMP_SIZE_ASSERT(MxRegion, 0x1c);
DECOMP_SIZE_ASSERT(MxRegionTopBottom, 0x0c);
DECOMP_SIZE_ASSERT(MxRegionLeftRight, 0x08);
DECOMP_SIZE_ASSERT(MxRegion, 0x1c)
DECOMP_SIZE_ASSERT(MxSpan, 0x0c)
DECOMP_SIZE_ASSERT(MxSegment, 0x08)
DECOMP_SIZE_ASSERT(MxRegionCursor, 0x18)
// FUNCTION: LEGO1 0x100c31c0
// FUNCTION: BETA10 0x10148f00
MxRegion::MxRegion()
{
m_list = new MxRegionTopBottomList;
m_rect = MxRect32(INT_MAX, INT_MAX, -1, -1);
}
// FUNCTION: LEGO1 0x100c3660
MxBool MxRegion::VTable0x20()
{
return m_list->GetCount() == 0;
m_spanList = new MxSpanList;
m_boundingRect = MxRect32(INT_MAX, INT_MAX, -1, -1);
}
// FUNCTION: LEGO1 0x100c3690
// FUNCTION: BETA10 0x10148fe8
MxRegion::~MxRegion()
{
if (m_list) {
delete m_list;
}
delete m_spanList;
}
// FUNCTION: LEGO1 0x100c3700
// FUNCTION: BETA10 0x1014907a
void MxRegion::Reset()
{
m_list->DeleteAll();
m_rect = MxRect32(INT_MAX, INT_MAX, -1, -1);
m_spanList->DeleteAll();
m_boundingRect = MxRect32(INT_MAX, INT_MAX, -1, -1);
}
// FUNCTION: LEGO1 0x100c3750
// FUNCTION: BETA10 0x101490bd
void MxRegion::VTable0x18(MxRect32& p_rect)
void MxRegion::AddRect(MxRect32& p_rect)
{
MxRect32 rect(p_rect);
MxRect32 newRect;
MxRegionTopBottomListCursor cursor(m_list);
MxRegionTopBottom* topBottom;
MxSpanListCursor cursor(m_spanList);
MxSpan* span;
while (rect.IsValid() && cursor.Next(topBottom)) {
if (topBottom->GetTop() >= rect.GetBottom()) {
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect);
cursor.Prepend(newTopBottom);
while (rect.IsValid() && cursor.Next(span)) {
if (span->GetMin() >= rect.GetBottom()) {
MxSpan* newSpan = new MxSpan(rect);
cursor.Prepend(newSpan);
rect.SetTop(rect.GetBottom());
}
else if (rect.GetTop() < topBottom->GetBottom()) {
if (rect.GetTop() < topBottom->GetTop()) {
else if (rect.GetTop() < span->GetMax()) {
if (rect.GetTop() < span->GetMin()) {
newRect = rect;
newRect.SetBottom(topBottom->GetTop());
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(newRect);
cursor.Prepend(newTopBottom);
rect.SetTop(topBottom->GetTop());
newRect.SetBottom(span->GetMin());
MxSpan* newSpan = new MxSpan(newRect);
cursor.Prepend(newSpan);
rect.SetTop(span->GetMin());
}
else if (topBottom->GetTop() < rect.GetTop()) {
MxRegionTopBottom* newTopBottom = topBottom->Clone();
newTopBottom->SetBottom(rect.GetTop());
topBottom->SetTop(rect.GetTop());
cursor.Prepend(newTopBottom);
else if (span->GetMin() < rect.GetTop()) {
MxSpan* newSpan = span->Clone();
newSpan->SetMax(rect.GetTop());
span->SetMin(rect.GetTop());
cursor.Prepend(newSpan);
}
if (rect.GetBottom() < topBottom->GetBottom()) {
MxRegionTopBottom* newTopBottom = topBottom->Clone();
newTopBottom->SetBottom(rect.GetBottom());
topBottom->SetTop(rect.GetBottom());
newTopBottom->MergeOrExpandRegions(rect.GetLeft(), rect.GetRight());
cursor.Prepend(newTopBottom);
if (rect.GetBottom() < span->GetMax()) {
MxSpan* newSpan = span->Clone();
newSpan->SetMax(rect.GetBottom());
span->SetMin(rect.GetBottom());
newSpan->AddSegment(rect.GetLeft(), rect.GetRight());
cursor.Prepend(newSpan);
rect.SetTop(rect.GetBottom());
}
else {
topBottom->MergeOrExpandRegions(rect.GetLeft(), rect.GetRight());
rect.SetTop(topBottom->GetBottom());
span->AddSegment(rect.GetLeft(), rect.GetRight());
rect.SetTop(span->GetMax());
}
}
}
if (rect.IsValid()) {
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect);
m_list->Append(newTopBottom);
MxSpan* newSpan = new MxSpan(rect);
m_spanList->Append(newSpan);
}
m_rect.UpdateBounds(p_rect);
m_boundingRect.UpdateBounds(p_rect);
}
// FUNCTION: LEGO1 0x100c3e20
MxBool MxRegion::VTable0x1c(MxRect32& p_rect)
// FUNCTION: BETA10 0x10149535
MxBool MxRegion::Intersects(MxRect32& p_rect)
{
if (!m_rect.IntersectsWith(p_rect)) {
if (!m_boundingRect.IntersectsWith(p_rect)) {
return FALSE;
}
MxRegionTopBottomListCursor cursor(m_list);
MxRegionTopBottom* topBottom;
MxSpanListCursor cursor(m_spanList);
MxSpan* span;
while (cursor.Next(topBottom)) {
if (topBottom->GetTop() >= p_rect.GetBottom()) {
while (cursor.Next(span)) {
if (span->GetMin() >= p_rect.GetBottom()) {
return FALSE;
}
if (topBottom->GetBottom() > p_rect.GetTop() && topBottom->CheckHorizontalOverlap(p_rect)) {
if (span->GetMax() > p_rect.GetTop() && span->IntersectsH(p_rect)) {
return TRUE;
}
}
@@ -111,57 +107,338 @@ MxBool MxRegion::VTable0x1c(MxRect32& p_rect)
return FALSE;
}
// FUNCTION: LEGO1 0x100c4c90
MxRegionTopBottom::MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom)
// FUNCTION: LEGO1 0x100c3f70
// FUNCTION: BETA10 0x10149663
MxRegionCursor::MxRegionCursor(MxRegion* p_region)
{
m_top = p_top;
m_bottom = p_bottom;
m_leftRightList = new MxRegionLeftRightList;
m_region = p_region;
m_rect = NULL;
m_spanListCursor = new MxSpanListCursor(m_region->m_spanList);
m_segListCursor = NULL;
}
// FUNCTION: LEGO1 0x100c40b0
MxRegionCursor::~MxRegionCursor()
{
if (m_rect) {
delete m_rect;
}
if (m_spanListCursor) {
delete m_spanListCursor;
}
if (m_segListCursor) {
delete m_segListCursor;
}
}
// FUNCTION: LEGO1 0x100c4140
MxRect32* MxRegionCursor::Head()
{
m_spanListCursor->Head();
MxSpan* span;
if (m_spanListCursor->Current(span)) {
CreateSegmentListCursor(span->m_segList);
MxSegment* segment;
m_segListCursor->First(segment);
SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
}
else {
Reset();
}
return m_rect;
}
// FUNCTION: LEGO1 0x100c41d0
MxRect32* MxRegionCursor::Tail()
{
m_spanListCursor->Tail();
MxSpan* span;
if (m_spanListCursor->Current(span)) {
CreateSegmentListCursor(span->m_segList);
MxSegment* segment;
m_segListCursor->Last(segment);
SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
}
else {
Reset();
}
return m_rect;
}
// FUNCTION: LEGO1 0x100c4260
MxRect32* MxRegionCursor::Next()
{
MxSegment* segment;
MxSpan* span;
if (m_segListCursor && m_segListCursor->Next(segment)) {
m_spanListCursor->Current(span);
SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
return m_rect;
}
if (m_spanListCursor->Next(span)) {
CreateSegmentListCursor(span->m_segList);
m_segListCursor->First(segment);
SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
return m_rect;
}
Reset();
return m_rect;
}
// FUNCTION: LEGO1 0x100c4360
MxRect32* MxRegionCursor::Prev()
{
MxSegment* segment;
MxSpan* span;
if (m_segListCursor && m_segListCursor->Prev(segment)) {
m_spanListCursor->Current(span);
SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
return m_rect;
}
if (m_spanListCursor->Prev(span)) {
CreateSegmentListCursor(span->m_segList);
m_segListCursor->Last(segment);
SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
return m_rect;
}
Reset();
return m_rect;
}
// FUNCTION: LEGO1 0x100c4460
MxRect32* MxRegionCursor::Head(MxRect32& p_rect)
{
m_spanListCursor->Reset();
NextSpan(p_rect);
return m_rect;
}
// FUNCTION: LEGO1 0x100c4480
MxRect32* MxRegionCursor::Tail(MxRect32& p_rect)
{
m_spanListCursor->Reset();
PrevSpan(p_rect);
return m_rect;
}
// FUNCTION: LEGO1 0x100c44a0
MxRect32* MxRegionCursor::Next(MxRect32& p_rect)
{
MxSegment* segment;
if (m_segListCursor && m_segListCursor->Next(segment)) {
MxSpan* span;
m_spanListCursor->Current(span);
if (span->IntersectsV(p_rect) && segment->IntersectsH(p_rect)) {
SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
m_rect->Intersect(p_rect);
}
else {
NextSpan(p_rect);
}
}
else {
NextSpan(p_rect);
}
return m_rect;
}
// FUNCTION: LEGO1 0x100c4590
MxRect32* MxRegionCursor::Prev(MxRect32& p_rect)
{
MxSegment* segment;
if (m_segListCursor && m_segListCursor->Prev(segment)) {
MxSpan* span;
m_spanListCursor->Current(span);
if (span->IntersectsV(p_rect) && segment->IntersectsH(p_rect)) {
SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
m_rect->Intersect(p_rect);
}
else {
PrevSpan(p_rect);
}
}
else {
PrevSpan(p_rect);
}
return m_rect;
}
// FUNCTION: LEGO1 0x100c4680
void MxRegionCursor::Reset()
{
if (m_rect) {
delete m_rect;
m_rect = NULL;
}
m_spanListCursor->Reset();
if (m_segListCursor) {
delete m_segListCursor;
m_segListCursor = NULL;
}
}
// FUNCTION: LEGO1 0x100c46c0
void MxRegionCursor::CreateSegmentListCursor(MxSegmentList* p_segList)
{
if (m_segListCursor) {
delete m_segListCursor;
}
m_segListCursor = new MxSegmentListCursor(p_segList);
}
// FUNCTION: LEGO1 0x100c4980
void MxRegionCursor::SetRect(MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom)
{
if (!m_rect) {
m_rect = new MxRect32;
}
m_rect->SetLeft(p_left);
m_rect->SetTop(p_top);
m_rect->SetRight(p_right);
m_rect->SetBottom(p_bottom);
}
// FUNCTION: LEGO1 0x100c4a20
void MxRegionCursor::NextSpan(MxRect32& p_rect)
{
MxSpan* span;
while (m_spanListCursor->Next(span)) {
if (p_rect.GetBottom() <= span->GetMin()) {
Reset();
return;
}
if (p_rect.GetTop() < span->GetMax()) {
CreateSegmentListCursor(span->m_segList);
MxSegment* segment;
while (m_segListCursor->Next(segment)) {
if (p_rect.GetRight() <= segment->GetMin()) {
break;
}
if (p_rect.GetLeft() < segment->GetMax()) {
SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
m_rect->Intersect(p_rect);
return;
}
}
}
}
Reset();
}
// FUNCTION: LEGO1 0x100c4b50
void MxRegionCursor::PrevSpan(MxRect32& p_rect)
{
MxSpan* span;
while (m_spanListCursor->Prev(span)) {
if (span->GetMax() <= p_rect.GetTop()) {
Reset();
return;
}
if (span->GetMin() < p_rect.GetBottom()) {
CreateSegmentListCursor(span->m_segList);
MxSegment* segment;
while (m_segListCursor->Prev(segment)) {
if (segment->GetMax() <= p_rect.GetLeft()) {
break;
}
if (segment->GetMin() < p_rect.GetRight()) {
SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
m_rect->Intersect(p_rect);
return;
}
}
}
}
Reset();
}
// FUNCTION: LEGO1 0x100c4c90
MxSpan::MxSpan(MxS32 p_min, MxS32 p_max)
{
m_min = p_min;
m_max = p_max;
m_segList = new MxSegmentList;
}
// FUNCTION: LEGO1 0x100c50e0
// FUNCTION: BETA10 0x1014a2d6
MxRegionTopBottom::MxRegionTopBottom(MxRect32& p_rect)
MxSpan::MxSpan(MxRect32& p_rect)
{
m_top = p_rect.GetTop();
m_bottom = p_rect.GetBottom();
m_leftRightList = new MxRegionLeftRightList;
m_min = p_rect.GetTop();
m_max = p_rect.GetBottom();
m_segList = new MxSegmentList;
MxRegionLeftRight* leftRight = new MxRegionLeftRight(p_rect.GetLeft(), p_rect.GetRight());
m_leftRightList->Append(leftRight);
MxSegment* segment = new MxSegment(p_rect.GetLeft(), p_rect.GetRight());
m_segList->Append(segment);
}
// FUNCTION: LEGO1 0x100c5280
// FUNCTION: BETA10 0x1014a3fc
void MxRegionTopBottom::MergeOrExpandRegions(MxS32 p_left, MxS32 p_right)
void MxSpan::AddSegment(MxS32 p_min, MxS32 p_max)
{
MxRegionLeftRightListCursor a(m_leftRightList);
MxRegionLeftRightListCursor b(m_leftRightList);
MxSegmentListCursor a(m_segList);
MxSegmentListCursor b(m_segList);
MxRegionLeftRight* leftRight;
while (a.Next(leftRight) && leftRight->GetRight() < p_left) {
MxSegment* segment;
while (a.Next(segment) && segment->GetMax() < p_min) {
;
}
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();
if (a.HasMatch()) {
if (p_min > segment->GetMin()) {
p_min = segment->GetMin();
}
while (leftRight->GetLeft() < p_right) {
if (p_right < leftRight->GetRight()) {
p_right = leftRight->GetRight();
while (segment->GetMin() < p_max) {
if (p_max < segment->GetMax()) {
p_max = segment->GetMax();
}
b = a;
b.Next();
a.Destroy();
if (!b.Current(leftRight)) {
if (!b.Current(segment)) {
break;
}
@@ -169,42 +446,48 @@ void MxRegionTopBottom::MergeOrExpandRegions(MxS32 p_left, MxS32 p_right)
}
if (a.HasMatch()) {
MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right);
MxSegment* copy = new MxSegment(p_min, p_max);
a.Prepend(copy);
}
else {
MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right);
m_leftRightList->Append(copy);
MxSegment* copy = new MxSegment(p_min, p_max);
m_segList->Append(copy);
}
}
else {
MxSegment* copy = new MxSegment(p_min, p_max);
m_segList->Append(copy);
}
}
// FUNCTION: LEGO1 0x100c55d0
MxRegionTopBottom* MxRegionTopBottom::Clone()
MxSpan* MxSpan::Clone()
{
MxRegionTopBottom* clone = new MxRegionTopBottom(m_top, m_bottom);
MxSpan* clone = new MxSpan(m_min, m_max);
MxRegionLeftRightListCursor cursor(m_leftRightList);
MxRegionLeftRight* leftRight;
MxSegmentListCursor cursor(m_segList);
MxSegment* segment;
while (cursor.Next(leftRight)) {
clone->m_leftRightList->Append(leftRight->Clone());
while (cursor.Next(segment)) {
clone->m_segList->Append(segment->Clone());
}
return clone;
}
// FUNCTION: LEGO1 0x100c57b0
MxBool MxRegionTopBottom::CheckHorizontalOverlap(MxRect32& p_rect)
// FUNCTION: BETA10 0x1014aa46
MxBool MxSpan::IntersectsH(MxRect32& p_rect)
{
MxRegionLeftRightListCursor cursor(m_leftRightList);
MxRegionLeftRight* leftRight;
MxSegmentListCursor cursor(m_segList);
MxSegment* segment;
while (cursor.Next(leftRight)) {
if (p_rect.GetRight() <= leftRight->GetLeft()) {
while (cursor.Next(segment)) {
if (p_rect.GetRight() <= segment->GetMin()) {
return FALSE;
}
if (leftRight->GetRight() > p_rect.GetLeft()) {
if (segment->GetMax() > p_rect.GetLeft()) {
return TRUE;
}
}

View File

@@ -1,298 +0,0 @@
#include "mxregioncursor.h"
DECOMP_SIZE_ASSERT(MxRegionCursor, 0x18);
// FUNCTION: LEGO1 0x100c3f70
// FUNCTION: BETA10 0x10149663
MxRegionCursor::MxRegionCursor(MxRegion* p_region)
{
m_region = p_region;
m_rect = NULL;
m_topBottomCursor = new MxRegionTopBottomListCursor(m_region->m_list);
m_leftRightCursor = NULL;
}
// FUNCTION: LEGO1 0x100c40b0
MxRegionCursor::~MxRegionCursor()
{
if (m_rect) {
delete m_rect;
}
if (m_topBottomCursor) {
delete m_topBottomCursor;
}
if (m_leftRightCursor) {
delete m_leftRightCursor;
}
}
// FUNCTION: LEGO1 0x100c4140
MxRect32* MxRegionCursor::VTable0x18()
{
m_topBottomCursor->Head();
MxRegionTopBottom* topBottom;
if (m_topBottomCursor->Current(topBottom)) {
ResetAndInitializeCursor(*topBottom->m_leftRightList);
MxRegionLeftRight* leftRight;
m_leftRightCursor->First(leftRight);
UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom());
}
else {
Reset();
}
return m_rect;
}
// FUNCTION: LEGO1 0x100c41d0
MxRect32* MxRegionCursor::VTable0x20()
{
m_topBottomCursor->Tail();
MxRegionTopBottom* topBottom;
if (m_topBottomCursor->Current(topBottom)) {
ResetAndInitializeCursor(*topBottom->m_leftRightList);
MxRegionLeftRight* leftRight;
m_leftRightCursor->Last(leftRight);
UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom());
}
else {
Reset();
}
return m_rect;
}
// FUNCTION: LEGO1 0x100c4260
MxRect32* MxRegionCursor::VTable0x28()
{
MxRegionLeftRight* leftRight;
MxRegionTopBottom* topBottom;
if (m_leftRightCursor && m_leftRightCursor->Next(leftRight)) {
m_topBottomCursor->Current(topBottom);
UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom());
return m_rect;
}
if (m_topBottomCursor->Next(topBottom)) {
ResetAndInitializeCursor(*topBottom->m_leftRightList);
m_leftRightCursor->First(leftRight);
UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom());
return m_rect;
}
Reset();
return m_rect;
}
// FUNCTION: LEGO1 0x100c4360
MxRect32* MxRegionCursor::VTable0x30()
{
MxRegionLeftRight* leftRight;
MxRegionTopBottom* topBottom;
if (m_leftRightCursor && m_leftRightCursor->Prev(leftRight)) {
m_topBottomCursor->Current(topBottom);
UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom());
return m_rect;
}
if (m_topBottomCursor->Prev(topBottom)) {
ResetAndInitializeCursor(*topBottom->m_leftRightList);
m_leftRightCursor->Last(leftRight);
UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom());
return m_rect;
}
Reset();
return m_rect;
}
// FUNCTION: LEGO1 0x100c4460
MxRect32* MxRegionCursor::VTable0x14(MxRect32& p_rect)
{
m_topBottomCursor->Reset();
ProcessRectOverlapAscending(p_rect);
return m_rect;
}
// FUNCTION: LEGO1 0x100c4480
MxRect32* MxRegionCursor::VTable0x1c(MxRect32& p_rect)
{
m_topBottomCursor->Reset();
ProcessOverlapWithRect(p_rect);
return m_rect;
}
// FUNCTION: LEGO1 0x100c44a0
MxRect32* MxRegionCursor::VTable0x24(MxRect32& p_rect)
{
MxRegionLeftRight* leftRight;
if (m_leftRightCursor && m_leftRightCursor->Next(leftRight)) {
MxRegionTopBottom* topBottom;
m_topBottomCursor->Current(topBottom);
if (topBottom->IntersectsWith(p_rect) && leftRight->IntersectsWith(p_rect)) {
UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom());
m_rect->Intersect(p_rect);
}
else {
ProcessRectOverlapAscending(p_rect);
}
}
else {
ProcessRectOverlapAscending(p_rect);
}
return m_rect;
}
// FUNCTION: LEGO1 0x100c4590
MxRect32* MxRegionCursor::VTable0x2c(MxRect32& p_rect)
{
MxRegionLeftRight* leftRight;
if (m_leftRightCursor && m_leftRightCursor->Prev(leftRight)) {
MxRegionTopBottom* topBottom;
m_topBottomCursor->Current(topBottom);
if (topBottom->IntersectsWith(p_rect) && leftRight->IntersectsWith(p_rect)) {
UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom());
m_rect->Intersect(p_rect);
}
else {
ProcessOverlapWithRect(p_rect);
}
}
else {
ProcessOverlapWithRect(p_rect);
}
return m_rect;
}
// FUNCTION: LEGO1 0x100c4680
void MxRegionCursor::Reset()
{
if (m_rect) {
delete m_rect;
m_rect = NULL;
}
m_topBottomCursor->Reset();
if (m_leftRightCursor) {
delete m_leftRightCursor;
m_leftRightCursor = NULL;
}
}
// FUNCTION: LEGO1 0x100c46c0
void MxRegionCursor::ResetAndInitializeCursor(MxRegionLeftRightList& p_leftRightList)
{
if (m_leftRightCursor) {
delete m_leftRightCursor;
}
m_leftRightCursor = new MxRegionLeftRightListCursor(&p_leftRightList);
}
// FUNCTION: LEGO1 0x100c4980
void MxRegionCursor::UpdateRect(MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom)
{
if (!m_rect) {
m_rect = new MxRect32;
}
m_rect->SetLeft(p_left);
m_rect->SetTop(p_top);
m_rect->SetRight(p_right);
m_rect->SetBottom(p_bottom);
}
// FUNCTION: LEGO1 0x100c4a20
void MxRegionCursor::ProcessRectOverlapAscending(MxRect32& p_rect)
{
MxRegionTopBottom* topBottom;
while (m_topBottomCursor->Next(topBottom)) {
if (p_rect.GetBottom() <= topBottom->GetTop()) {
Reset();
return;
}
if (p_rect.GetTop() < topBottom->GetBottom()) {
ResetAndInitializeCursor(*topBottom->m_leftRightList);
MxRegionLeftRight* leftRight;
while (m_leftRightCursor->Next(leftRight)) {
if (p_rect.GetRight() <= leftRight->GetLeft()) {
break;
}
if (p_rect.GetLeft() < leftRight->GetRight()) {
UpdateRect(
leftRight->GetLeft(),
topBottom->GetTop(),
leftRight->GetRight(),
topBottom->GetBottom()
);
m_rect->Intersect(p_rect);
return;
}
}
}
}
Reset();
}
// FUNCTION: LEGO1 0x100c4b50
void MxRegionCursor::ProcessOverlapWithRect(MxRect32& p_rect)
{
MxRegionTopBottom* topBottom;
while (m_topBottomCursor->Prev(topBottom)) {
if (topBottom->GetBottom() <= p_rect.GetTop()) {
Reset();
return;
}
if (topBottom->GetTop() < p_rect.GetBottom()) {
ResetAndInitializeCursor(*topBottom->m_leftRightList);
MxRegionLeftRight* leftRight;
while (m_leftRightCursor->Prev(leftRight)) {
if (leftRight->GetRight() <= p_rect.GetLeft()) {
break;
}
if (leftRight->GetLeft() < p_rect.GetRight()) {
UpdateRect(
leftRight->GetLeft(),
topBottom->GetTop(),
leftRight->GetRight(),
topBottom->GetBottom()
);
m_rect->Intersect(p_rect);
return;
}
}
}
}
Reset();
}

View File

@@ -32,12 +32,12 @@ MxVideoManager::~MxVideoManager()
// FUNCTION: LEGO1 0x100be320
MxResult MxVideoManager::Init()
{
this->m_pDirectDraw = NULL;
this->m_pDirect3D = NULL;
this->m_displaySurface = NULL;
this->m_region = NULL;
this->m_videoParam.SetPalette(NULL);
this->m_unk0x60 = FALSE;
m_pDirectDraw = NULL;
m_pDirect3D = NULL;
m_displaySurface = NULL;
m_region = NULL;
m_videoParam.SetPalette(NULL);
m_unk0x60 = FALSE;
return SUCCESS;
}
@@ -86,8 +86,8 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor)
// FUNCTION: LEGO1 0x100be3e0
void MxVideoManager::UpdateRegion()
{
if (m_region->VTable0x20() == FALSE) {
MxRect32 rect(m_region->GetRect());
if (m_region->IsEmpty() == FALSE) {
MxRect32 rect(m_region->GetBoundingRect());
rect.Intersect(m_videoParam.GetRect());
m_displaySurface
@@ -99,13 +99,13 @@ void MxVideoManager::UpdateRegion()
// FUNCTION: BETA10 0x1012ce5e
void MxVideoManager::SortPresenterList()
{
if (this->m_presenters->GetCount() <= 1) {
if (m_presenters->GetNumElements() <= 1) {
return;
}
MxPresenterListCursor a(this->m_presenters);
MxPresenterListCursor b(this->m_presenters);
MxU32 count = this->m_presenters->GetCount() - 1;
MxPresenterListCursor a(m_presenters);
MxPresenterListCursor b(m_presenters);
MxU32 count = m_presenters->GetNumElements() - 1;
MxBool finished;
if (count != 0) {
@@ -302,7 +302,7 @@ void MxVideoManager::InvalidateRect(MxRect32& p_rect)
m_criticalSection.Enter();
if (m_region) {
m_region->VTable0x18(p_rect);
m_region->AddRect(p_rect);
}
m_criticalSection.Leave();
@@ -316,7 +316,7 @@ MxResult MxVideoManager::Tickle()
SortPresenterList();
MxPresenter* presenter;
MxPresenterListCursor cursor(this->m_presenters);
MxPresenterListCursor cursor(m_presenters);
while (cursor.Next(presenter)) {
presenter->Tickle();
@@ -339,14 +339,14 @@ MxResult MxVideoManager::RealizePalette(MxPalette* p_palette)
{
PALETTEENTRY paletteEntries[256];
this->m_criticalSection.Enter();
m_criticalSection.Enter();
if (p_palette && this->m_videoParam.GetPalette()) {
if (p_palette && m_videoParam.GetPalette()) {
p_palette->GetEntries(paletteEntries);
this->m_videoParam.GetPalette()->SetEntries(paletteEntries);
this->m_displaySurface->SetPalette(this->m_videoParam.GetPalette());
m_videoParam.GetPalette()->SetEntries(paletteEntries);
m_displaySurface->SetPalette(m_videoParam.GetPalette());
}
this->m_criticalSection.Leave();
m_criticalSection.Leave();
return SUCCESS;
}

View File

@@ -5,7 +5,7 @@
#include "mxdsmediaaction.h"
#include "mxdssubscriber.h"
#include "mxmisc.h"
#include "mxregioncursor.h"
#include "mxregion.h"
#include "mxvideomanager.h"
DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64);
@@ -342,7 +342,7 @@ void MxVideoPresenter::PutFrame()
MxRegionCursor cursor(region);
MxRect32* regionRect;
while ((regionRect = cursor.VTable0x24(rect))) {
while ((regionRect = cursor.Next(rect))) {
if (regionRect->GetWidth() >= 1 && regionRect->GetHeight() >= 1) {
RECT src, dest;