Improve match of MxRegion::vtable18 (#266)

* Match MxRegionTopBottom::FUN_100c5280

* Resolve OtherAppend/Append

* Remove old code

* MxRegion::vtable18 up to 80%, refactor MxRect
This commit is contained in:
Christian Semmler
2023-11-06 18:12:09 -05:00
committed by GitHub
parent d5cf23bada
commit 23f4fda304
7 changed files with 123 additions and 107 deletions

View File

@@ -82,8 +82,8 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam)
} }
if (this->m_videoParam.flags().GetFullScreen()) { if (this->m_videoParam.flags().GetFullScreen()) {
MxS32 width = this->m_videoParam.GetRect().m_right - this->m_videoParam.GetRect().m_left + 1; MxS32 width = this->m_videoParam.GetRect().GetWidth();
MxS32 height = this->m_videoParam.GetRect().m_bottom - this->m_videoParam.GetRect().m_top + 1; MxS32 height = this->m_videoParam.GetRect().GetHeight();
if (lpDirectDraw->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN)) if (lpDirectDraw->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN))
goto done; goto done;
@@ -129,8 +129,8 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam)
memset(&ddsd, 0, sizeof(ddsd)); memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd); ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS; ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS;
ddsd.dwWidth = this->m_videoParam.GetRect().m_right - this->m_videoParam.GetRect().m_left + 1; ddsd.dwWidth = this->m_videoParam.GetRect().GetWidth();
ddsd.dwHeight = this->m_videoParam.GetRect().m_bottom - this->m_videoParam.GetRect().m_top + 1; ddsd.dwHeight = this->m_videoParam.GetRect().GetHeight();
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN; ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN;
if (!this->m_videoParam.flags().GetBackBuffers()) if (!this->m_videoParam.flags().GetBackBuffers())

View File

@@ -23,6 +23,14 @@ public:
this->m_bottom = p_size.m_height; this->m_bottom = p_size.m_height;
} }
MxRect32(const MxRect32& p_a, const MxRect32& p_b)
{
m_left = Max(p_a.m_left, p_b.m_left);
m_top = Max(p_a.m_top, p_b.m_top);
m_right = Min(p_a.m_right, p_b.m_right);
m_bottom = Min(p_a.m_bottom, p_b.m_bottom);
}
inline void SetPoint(const MxPoint32& p_point) inline void SetPoint(const MxPoint32& p_point)
{ {
this->m_left = p_point.m_x; this->m_left = p_point.m_x;
@@ -35,10 +43,39 @@ public:
this->m_bottom = p_size.m_height; this->m_bottom = p_size.m_height;
} }
inline MxBool IsValid() { return m_left < m_right && m_top < m_bottom; }
inline MxBool IntersectsWith(const MxRect32& p_rect)
{
return m_left < p_rect.m_right && p_rect.m_left < m_right && m_top < p_rect.m_bottom && p_rect.m_top < m_bottom;
}
inline void UpdateBounds(const MxRect32& p_rect)
{
m_left = Min(m_left, p_rect.m_left);
m_top = Min(m_top, p_rect.m_top);
m_right = Max(m_right, p_rect.m_right);
m_bottom = Max(m_bottom, p_rect.m_bottom);
}
inline MxS32 GetWidth() { return (m_right - m_left) + 1; } inline MxS32 GetWidth() { return (m_right - m_left) + 1; }
inline MxS32 GetHeight() { return (m_bottom - m_top) + 1; } inline MxS32 GetHeight() { return (m_bottom - m_top) + 1; }
inline MxPoint32 GetPoint() { return MxPoint32(this->m_left, this->m_top); } inline MxPoint32 GetPoint() { return MxPoint32(this->m_left, this->m_top); }
inline MxSize32 GetSize() { return MxSize32(this->m_right, this->m_bottom); }
inline MxS32 GetLeft() { return m_left; }
inline MxS32 GetTop() { return m_top; }
inline MxS32 GetRight() { return m_right; }
inline MxS32 GetBottom() { return m_bottom; }
inline void SetLeft(MxS32 p_left) { m_left = p_left; }
inline void SetTop(MxS32 p_top) { m_top = p_top; }
inline void SetRight(MxS32 p_right) { m_right = p_right; }
inline void SetBottom(MxS32 p_bottom) { m_bottom = p_bottom; }
private:
static inline MxS32 Min(MxS32 a, MxS32 b) { return a <= b ? a : b; };
static inline MxS32 Max(MxS32 a, MxS32 b) { return a <= b ? b : a; };
MxS32 m_left; MxS32 m_left;
MxS32 m_top; MxS32 m_top;

View File

@@ -38,78 +38,67 @@ void MxRegion::Reset()
// OFFSET: LEGO1 0x100c3750 // OFFSET: LEGO1 0x100c3750
void MxRegion::vtable18(MxRect32& p_rect) void MxRegion::vtable18(MxRect32& p_rect)
{ {
MxRect32 rectCopy(p_rect.GetPoint(), MxSize32(p_rect.m_right, p_rect.m_bottom)); MxRect32 rect(p_rect.GetPoint(), MxSize32(p_rect.GetRight(), p_rect.GetBottom()));
MxRegionListCursor cursor(m_list); MxRegionListCursor cursor(m_list);
MxRegionTopBottom* topBottom;
if (rectCopy.m_left < rectCopy.m_right) { while (rect.IsValid() && cursor.Next(topBottom)) {
while (rectCopy.m_top < rectCopy.m_bottom) { if (topBottom->GetTop() >= rect.GetBottom()) {
MxRegionTopBottom* topBottom; MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect);
if (!cursor.Next(topBottom)) cursor.Prepend(newTopBottom);
break; rect.SetTop(rect.GetBottom());
}
if (topBottom->m_top >= rectCopy.m_bottom) { else if (rect.GetTop() < topBottom->GetBottom()) {
cursor.Prepend(new MxRegionTopBottom(rectCopy)); if (rect.GetTop() < topBottom->GetTop()) {
rectCopy.m_top = rectCopy.m_bottom; MxRect32 newRect(rect);
newRect.SetBottom(topBottom->GetTop());
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(newRect);
cursor.Prepend(newTopBottom);
rect.SetTop(topBottom->GetTop());
} }
else if (rectCopy.m_top < topBottom->m_bottom) { else if (topBottom->GetTop() < rect.GetTop()) {
if (rectCopy.m_top < topBottom->m_top) { MxRegionTopBottom* newTopBottom = topBottom->Clone();
MxRect32 topBottomRect(rectCopy.GetPoint(), MxSize32(rectCopy.m_right, topBottom->m_top)); newTopBottom->SetBottom(rect.GetTop());
topBottom->SetTop(rect.GetTop());
cursor.Prepend(new MxRegionTopBottom(topBottomRect)); cursor.Prepend(newTopBottom);
rectCopy.m_top = topBottom->m_top;
}
else if (topBottom->m_top < rectCopy.m_top) {
MxRegionTopBottom* newTopBottom = topBottom->Clone();
newTopBottom->m_bottom = rectCopy.m_top;
topBottom->m_top = rectCopy.m_top;
cursor.Prepend(newTopBottom);
}
if (rectCopy.m_bottom < topBottom->m_bottom) {
MxRegionTopBottom* newTopBottom = topBottom->Clone();
newTopBottom->m_bottom = rectCopy.m_bottom;
topBottom->m_top = rectCopy.m_bottom;
newTopBottom->FUN_100c5280(rectCopy.m_left, rectCopy.m_right);
// TODO: _InsertEntry currently inlined, shouldn't be
cursor.Prepend(newTopBottom);
rectCopy.m_top = rectCopy.m_bottom;
}
else {
topBottom->FUN_100c5280(rectCopy.m_left, rectCopy.m_right);
rectCopy.m_top = topBottom->m_bottom;
}
} }
if (rectCopy.m_right <= rectCopy.m_left) if (rect.GetBottom() < topBottom->GetBottom()) {
break; 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 (rectCopy.m_left < rectCopy.m_right && rectCopy.m_top < rectCopy.m_bottom) { if (rect.IsValid()) {
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rectCopy); MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect);
m_list->Append(newTopBottom); m_list->Append(newTopBottom);
} }
m_rect.m_left = m_rect.m_left <= p_rect.m_left ? m_rect.m_left : p_rect.m_left; m_rect.UpdateBounds(p_rect);
m_rect.m_top = m_rect.m_top <= p_rect.m_top ? m_rect.m_top : p_rect.m_top;
m_rect.m_right = m_rect.m_right <= p_rect.m_right ? p_rect.m_right : m_rect.m_right;
m_rect.m_bottom = m_rect.m_bottom <= p_rect.m_bottom ? p_rect.m_bottom : m_rect.m_bottom;
} }
// OFFSET: LEGO1 0x100c3e20 // OFFSET: LEGO1 0x100c3e20
MxBool MxRegion::vtable1c(MxRect32& p_rect) MxBool MxRegion::vtable1c(MxRect32& p_rect)
{ {
if (m_rect.m_left >= p_rect.m_right || p_rect.m_left >= m_rect.m_right || m_rect.m_top >= p_rect.m_bottom || if (!m_rect.IntersectsWith(p_rect))
p_rect.m_top >= m_rect.m_bottom)
return FALSE; return FALSE;
MxRegionListCursor cursor(m_list); MxRegionListCursor cursor(m_list);
MxRegionTopBottom* topBottom; MxRegionTopBottom* topBottom;
while (cursor.Next(topBottom)) { while (cursor.Next(topBottom)) {
if (topBottom->m_top >= p_rect.m_bottom) if (topBottom->GetTop() >= p_rect.GetBottom())
return FALSE; return FALSE;
if (topBottom->m_bottom > p_rect.m_top && topBottom->FUN_100c57b0(p_rect)) if (topBottom->GetBottom() > p_rect.GetTop() && topBottom->FUN_100c57b0(p_rect))
return TRUE; return TRUE;
} }
@@ -127,11 +116,11 @@ MxRegionTopBottom::MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom)
// OFFSET: LEGO1 0x100c50e0 // OFFSET: LEGO1 0x100c50e0
MxRegionTopBottom::MxRegionTopBottom(MxRect32& p_rect) MxRegionTopBottom::MxRegionTopBottom(MxRect32& p_rect)
{ {
m_top = p_rect.m_top; m_top = p_rect.GetTop();
m_bottom = p_rect.m_bottom; m_bottom = p_rect.GetBottom();
m_leftRightList = new MxRegionLeftRightList; m_leftRightList = new MxRegionLeftRightList;
MxRegionLeftRight* leftRight = new MxRegionLeftRight(p_rect.m_left, p_rect.m_right); MxRegionLeftRight* leftRight = new MxRegionLeftRight(p_rect.GetLeft(), p_rect.GetRight());
m_leftRightList->Append(leftRight); m_leftRightList->Append(leftRight);
} }
@@ -142,7 +131,7 @@ void MxRegionTopBottom::FUN_100c5280(MxS32 p_left, MxS32 p_right)
MxRegionLeftRightListCursor b(m_leftRightList); MxRegionLeftRightListCursor b(m_leftRightList);
MxRegionLeftRight* leftRight; MxRegionLeftRight* leftRight;
while (a.Next(leftRight) && leftRight->m_right < p_left) while (a.Next(leftRight) && leftRight->GetRight() < p_left)
; ;
if (!a.HasMatch()) { if (!a.HasMatch()) {
@@ -150,12 +139,12 @@ void MxRegionTopBottom::FUN_100c5280(MxS32 p_left, MxS32 p_right)
m_leftRightList->Append(copy); m_leftRightList->Append(copy);
} }
else { else {
if (p_left > leftRight->m_left) if (p_left > leftRight->GetLeft())
p_left = leftRight->m_left; p_left = leftRight->GetLeft();
while (leftRight->m_left < p_right) { while (leftRight->GetLeft() < p_right) {
if (p_right < leftRight->m_right) if (p_right < leftRight->GetRight())
p_right = leftRight->m_right; p_right = leftRight->GetRight();
b = a; b = a;
b.Advance(); b.Advance();
@@ -199,9 +188,9 @@ MxBool MxRegionTopBottom::FUN_100c57b0(MxRect32& p_rect)
MxRegionLeftRight* leftRight; MxRegionLeftRight* leftRight;
while (cursor.Next(leftRight)) { while (cursor.Next(leftRight)) {
if (p_rect.m_right <= leftRight->m_left) if (p_rect.GetRight() <= leftRight->GetLeft())
return FALSE; return FALSE;
if (leftRight->m_right > p_rect.m_left) if (leftRight->GetRight() > p_rect.GetLeft())
return TRUE; return TRUE;
} }

View File

@@ -15,6 +15,15 @@ struct MxRegionTopBottom {
void FUN_100c5280(MxS32 p_left, MxS32 p_right); void FUN_100c5280(MxS32 p_left, MxS32 p_right);
MxBool FUN_100c57b0(MxRect32& p_rect); MxBool FUN_100c57b0(MxRect32& p_rect);
inline MxS32 GetTop() { return m_top; }
inline MxS32 GetBottom() { return m_bottom; }
inline void SetTop(MxS32 p_top) { m_top = p_top; }
inline void SetBottom(MxS32 p_bottom) { m_bottom = p_bottom; }
friend class MxRegionListParent;
private:
MxS32 m_top; MxS32 m_top;
MxS32 m_bottom; MxS32 m_bottom;
MxRegionLeftRightList* m_leftRightList; MxRegionLeftRightList* m_leftRightList;
@@ -30,6 +39,13 @@ struct MxRegionLeftRight {
MxRegionLeftRight* Clone() { return new MxRegionLeftRight(m_left, m_right); } MxRegionLeftRight* Clone() { return new MxRegionLeftRight(m_left, m_right); }
inline MxS32 GetLeft() { return m_left; }
inline MxS32 GetRight() { return m_right; }
inline void SetLeft(MxS32 p_left) { m_left = p_left; }
inline void SetRight(MxS32 p_right) { m_right = p_right; }
private:
MxS32 m_left; MxS32 m_left;
MxS32 m_right; MxS32 m_right;
}; };

View File

@@ -75,26 +75,9 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor)
void MxVideoManager::UpdateRegion() void MxVideoManager::UpdateRegion()
{ {
if (m_region->vtable20() == FALSE) { if (m_region->vtable20() == FALSE) {
MxS32 left, top, right, bottom; MxRect32 rect(m_region->GetRect(), m_videoParam.GetRect());
MxRect32& regionRect = m_region->GetRect(); m_displaySurface
->Display(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight());
left = m_videoParam.GetRect().m_left;
if (left <= regionRect.m_left)
left = regionRect.m_left;
top = regionRect.m_top;
if (top <= m_videoParam.GetRect().m_top)
top = m_videoParam.GetRect().m_top;
right = regionRect.m_right;
if (right >= m_videoParam.GetRect().m_right)
right = m_videoParam.GetRect().m_right;
bottom = m_videoParam.GetRect().m_bottom;
if (bottom >= regionRect.m_bottom)
bottom = regionRect.m_bottom;
m_displaySurface->Display(left, top, left, top, right - left + 1, bottom - top + 1);
} }
} }

View File

@@ -6,14 +6,14 @@
// OFFSET: LEGO1 0x100bec70 // OFFSET: LEGO1 0x100bec70
MxVideoParam::MxVideoParam() MxVideoParam::MxVideoParam()
{ {
this->m_rect.m_right = 640; this->m_rect.SetRight(640);
this->m_rect.m_bottom = 480; this->m_rect.SetBottom(480);
this->m_rect.m_left = 0; this->m_rect.SetLeft(0);
this->m_rect.m_top = 0; this->m_rect.SetTop(0);
this->m_palette = 0; this->m_palette = NULL;
this->m_backBuffers = 0; this->m_backBuffers = 0;
this->m_unk1c = 0; this->m_unk1c = 0;
this->m_deviceId = 0; this->m_deviceId = NULL;
} }
// OFFSET: LEGO1 0x100beca0 // OFFSET: LEGO1 0x100beca0
@@ -24,10 +24,7 @@ MxVideoParam::MxVideoParam(
COMPAT_CONST MxVideoParamFlags& p_flags COMPAT_CONST MxVideoParamFlags& p_flags
) )
{ {
this->m_rect.m_left = p_rect.m_left; this->m_rect = p_rect;
this->m_rect.m_top = p_rect.m_top;
this->m_rect.m_right = p_rect.m_right;
this->m_rect.m_bottom = p_rect.m_bottom;
this->m_palette = p_pal; this->m_palette = p_pal;
this->m_backBuffers = p_backBuffers; this->m_backBuffers = p_backBuffers;
this->m_flags = p_flags; this->m_flags = p_flags;
@@ -38,10 +35,7 @@ MxVideoParam::MxVideoParam(
// OFFSET: LEGO1 0x100becf0 // OFFSET: LEGO1 0x100becf0
MxVideoParam::MxVideoParam(MxVideoParam& p_videoParam) MxVideoParam::MxVideoParam(MxVideoParam& p_videoParam)
{ {
this->m_rect.m_left = p_videoParam.m_rect.m_left; this->m_rect = p_videoParam.m_rect;
this->m_rect.m_top = p_videoParam.m_rect.m_top;
this->m_rect.m_right = p_videoParam.m_rect.m_right;
this->m_rect.m_bottom = p_videoParam.m_rect.m_bottom;
this->m_palette = p_videoParam.m_palette; this->m_palette = p_videoParam.m_palette;
this->m_backBuffers = p_videoParam.m_backBuffers; this->m_backBuffers = p_videoParam.m_backBuffers;
this->m_flags = p_videoParam.m_flags; this->m_flags = p_videoParam.m_flags;
@@ -53,10 +47,7 @@ MxVideoParam::MxVideoParam(MxVideoParam& p_videoParam)
// OFFSET: LEGO1 0x100bede0 // OFFSET: LEGO1 0x100bede0
MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam) MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam)
{ {
this->m_rect.m_left = p_videoParam.m_rect.m_left; this->m_rect = p_videoParam.m_rect;
this->m_rect.m_top = p_videoParam.m_rect.m_top;
this->m_rect.m_right = p_videoParam.m_rect.m_right;
this->m_rect.m_bottom = p_videoParam.m_rect.m_bottom;
this->m_palette = p_videoParam.m_palette; this->m_palette = p_videoParam.m_palette;
this->m_backBuffers = p_videoParam.m_backBuffers; this->m_backBuffers = p_videoParam.m_backBuffers;
this->m_flags = p_videoParam.m_flags; this->m_flags = p_videoParam.m_flags;
@@ -69,24 +60,24 @@ MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam)
// OFFSET: LEGO1 0x100bed70 // OFFSET: LEGO1 0x100bed70
void MxVideoParam::SetDeviceName(char* id) void MxVideoParam::SetDeviceName(char* id)
{ {
if (this->m_deviceId != 0) if (this->m_deviceId != NULL)
delete[] this->m_deviceId; delete[] this->m_deviceId;
if (id != 0) { if (id != 0) {
this->m_deviceId = new char[strlen(id) + 1]; this->m_deviceId = new char[strlen(id) + 1];
if (this->m_deviceId != 0) { if (this->m_deviceId != NULL) {
strcpy(this->m_deviceId, id); strcpy(this->m_deviceId, id);
} }
} }
else { else {
this->m_deviceId = 0; this->m_deviceId = NULL;
} }
} }
// OFFSET: LEGO1 0x100bed50 // OFFSET: LEGO1 0x100bed50
MxVideoParam::~MxVideoParam() MxVideoParam::~MxVideoParam()
{ {
if (this->m_deviceId != 0) if (this->m_deviceId != NULL)
delete[] this->m_deviceId; delete[] this->m_deviceId;
} }

View File

@@ -220,7 +220,7 @@ void MxVideoPresenter::Destroy(MxBool p_fromDestructor)
MxRect32 rect(x, y, x + width, y + height); MxRect32 rect(x, y, x + width, y + height);
MVideoManager()->InvalidateRect(rect); MVideoManager()->InvalidateRect(rect);
MVideoManager()->vtable0x34(rect.m_left, rect.m_top, rect.GetWidth(), rect.GetHeight()); MVideoManager()->vtable0x34(rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight());
} }
delete m_bitmap; delete m_bitmap;