mirror of
https://github.com/isledecomp/isle.git
synced 2025-10-23 08:24:16 +00:00
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:

committed by
GitHub

parent
ea5a722311
commit
67b25b0bcc
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user