mirror of
https://github.com/isledecomp/isle-portable.git
synced 2025-02-16 19:50:52 -05:00
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:
parent
d5cf23bada
commit
23f4fda304
7 changed files with 123 additions and 107 deletions
|
@ -82,8 +82,8 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam)
|
|||
}
|
||||
|
||||
if (this->m_videoParam.flags().GetFullScreen()) {
|
||||
MxS32 width = this->m_videoParam.GetRect().m_right - this->m_videoParam.GetRect().m_left + 1;
|
||||
MxS32 height = this->m_videoParam.GetRect().m_bottom - this->m_videoParam.GetRect().m_top + 1;
|
||||
MxS32 width = this->m_videoParam.GetRect().GetWidth();
|
||||
MxS32 height = this->m_videoParam.GetRect().GetHeight();
|
||||
|
||||
if (lpDirectDraw->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN))
|
||||
goto done;
|
||||
|
@ -129,8 +129,8 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam)
|
|||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS;
|
||||
ddsd.dwWidth = this->m_videoParam.GetRect().m_right - this->m_videoParam.GetRect().m_left + 1;
|
||||
ddsd.dwHeight = this->m_videoParam.GetRect().m_bottom - this->m_videoParam.GetRect().m_top + 1;
|
||||
ddsd.dwWidth = this->m_videoParam.GetRect().GetWidth();
|
||||
ddsd.dwHeight = this->m_videoParam.GetRect().GetHeight();
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN;
|
||||
|
||||
if (!this->m_videoParam.flags().GetBackBuffers())
|
||||
|
|
|
@ -23,6 +23,14 @@ public:
|
|||
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)
|
||||
{
|
||||
this->m_left = p_point.m_x;
|
||||
|
@ -35,10 +43,39 @@ public:
|
|||
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 GetHeight() { return (m_bottom - m_top) + 1; }
|
||||
|
||||
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_top;
|
||||
|
|
|
@ -38,78 +38,67 @@ void MxRegion::Reset()
|
|||
// OFFSET: LEGO1 0x100c3750
|
||||
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);
|
||||
MxRegionTopBottom* topBottom;
|
||||
|
||||
if (rectCopy.m_left < rectCopy.m_right) {
|
||||
while (rectCopy.m_top < rectCopy.m_bottom) {
|
||||
MxRegionTopBottom* topBottom;
|
||||
if (!cursor.Next(topBottom))
|
||||
break;
|
||||
|
||||
if (topBottom->m_top >= rectCopy.m_bottom) {
|
||||
cursor.Prepend(new MxRegionTopBottom(rectCopy));
|
||||
rectCopy.m_top = rectCopy.m_bottom;
|
||||
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());
|
||||
}
|
||||
else if (rectCopy.m_top < topBottom->m_bottom) {
|
||||
if (rectCopy.m_top < topBottom->m_top) {
|
||||
MxRect32 topBottomRect(rectCopy.GetPoint(), MxSize32(rectCopy.m_right, topBottom->m_top));
|
||||
|
||||
cursor.Prepend(new MxRegionTopBottom(topBottomRect));
|
||||
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;
|
||||
}
|
||||
else if (topBottom->GetTop() < rect.GetTop()) {
|
||||
MxRegionTopBottom* newTopBottom = topBottom->Clone();
|
||||
newTopBottom->SetBottom(rect.GetTop());
|
||||
topBottom->SetTop(rect.GetTop());
|
||||
cursor.Prepend(newTopBottom);
|
||||
}
|
||||
|
||||
if (rectCopy.m_right <= rectCopy.m_left)
|
||||
break;
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rectCopy.m_left < rectCopy.m_right && rectCopy.m_top < rectCopy.m_bottom) {
|
||||
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rectCopy);
|
||||
if (rect.IsValid()) {
|
||||
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect);
|
||||
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.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;
|
||||
m_rect.UpdateBounds(p_rect);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c3e20
|
||||
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 ||
|
||||
p_rect.m_top >= m_rect.m_bottom)
|
||||
if (!m_rect.IntersectsWith(p_rect))
|
||||
return FALSE;
|
||||
|
||||
MxRegionListCursor cursor(m_list);
|
||||
MxRegionTopBottom* topBottom;
|
||||
|
||||
while (cursor.Next(topBottom)) {
|
||||
if (topBottom->m_top >= p_rect.m_bottom)
|
||||
if (topBottom->GetTop() >= p_rect.GetBottom())
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -127,11 +116,11 @@ MxRegionTopBottom::MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom)
|
|||
// OFFSET: LEGO1 0x100c50e0
|
||||
MxRegionTopBottom::MxRegionTopBottom(MxRect32& p_rect)
|
||||
{
|
||||
m_top = p_rect.m_top;
|
||||
m_bottom = p_rect.m_bottom;
|
||||
m_top = p_rect.GetTop();
|
||||
m_bottom = p_rect.GetBottom();
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -142,7 +131,7 @@ void MxRegionTopBottom::FUN_100c5280(MxS32 p_left, MxS32 p_right)
|
|||
MxRegionLeftRightListCursor b(m_leftRightList);
|
||||
|
||||
MxRegionLeftRight* leftRight;
|
||||
while (a.Next(leftRight) && leftRight->m_right < p_left)
|
||||
while (a.Next(leftRight) && leftRight->GetRight() < p_left)
|
||||
;
|
||||
|
||||
if (!a.HasMatch()) {
|
||||
|
@ -150,12 +139,12 @@ void MxRegionTopBottom::FUN_100c5280(MxS32 p_left, MxS32 p_right)
|
|||
m_leftRightList->Append(copy);
|
||||
}
|
||||
else {
|
||||
if (p_left > leftRight->m_left)
|
||||
p_left = leftRight->m_left;
|
||||
if (p_left > leftRight->GetLeft())
|
||||
p_left = leftRight->GetLeft();
|
||||
|
||||
while (leftRight->m_left < p_right) {
|
||||
if (p_right < leftRight->m_right)
|
||||
p_right = leftRight->m_right;
|
||||
while (leftRight->GetLeft() < p_right) {
|
||||
if (p_right < leftRight->GetRight())
|
||||
p_right = leftRight->GetRight();
|
||||
|
||||
b = a;
|
||||
b.Advance();
|
||||
|
@ -199,9 +188,9 @@ MxBool MxRegionTopBottom::FUN_100c57b0(MxRect32& p_rect)
|
|||
MxRegionLeftRight* leftRight;
|
||||
|
||||
while (cursor.Next(leftRight)) {
|
||||
if (p_rect.m_right <= leftRight->m_left)
|
||||
if (p_rect.GetRight() <= leftRight->GetLeft())
|
||||
return FALSE;
|
||||
if (leftRight->m_right > p_rect.m_left)
|
||||
if (leftRight->GetRight() > p_rect.GetLeft())
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,15 @@ struct MxRegionTopBottom {
|
|||
void FUN_100c5280(MxS32 p_left, MxS32 p_right);
|
||||
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_bottom;
|
||||
MxRegionLeftRightList* m_leftRightList;
|
||||
|
@ -30,6 +39,13 @@ struct MxRegionLeftRight {
|
|||
|
||||
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_right;
|
||||
};
|
||||
|
|
|
@ -75,26 +75,9 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor)
|
|||
void MxVideoManager::UpdateRegion()
|
||||
{
|
||||
if (m_region->vtable20() == FALSE) {
|
||||
MxS32 left, top, right, bottom;
|
||||
MxRect32& regionRect = m_region->GetRect();
|
||||
|
||||
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);
|
||||
MxRect32 rect(m_region->GetRect(), m_videoParam.GetRect());
|
||||
m_displaySurface
|
||||
->Display(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
// OFFSET: LEGO1 0x100bec70
|
||||
MxVideoParam::MxVideoParam()
|
||||
{
|
||||
this->m_rect.m_right = 640;
|
||||
this->m_rect.m_bottom = 480;
|
||||
this->m_rect.m_left = 0;
|
||||
this->m_rect.m_top = 0;
|
||||
this->m_palette = 0;
|
||||
this->m_rect.SetRight(640);
|
||||
this->m_rect.SetBottom(480);
|
||||
this->m_rect.SetLeft(0);
|
||||
this->m_rect.SetTop(0);
|
||||
this->m_palette = NULL;
|
||||
this->m_backBuffers = 0;
|
||||
this->m_unk1c = 0;
|
||||
this->m_deviceId = 0;
|
||||
this->m_deviceId = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100beca0
|
||||
|
@ -24,10 +24,7 @@ MxVideoParam::MxVideoParam(
|
|||
COMPAT_CONST MxVideoParamFlags& p_flags
|
||||
)
|
||||
{
|
||||
this->m_rect.m_left = p_rect.m_left;
|
||||
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_rect = p_rect;
|
||||
this->m_palette = p_pal;
|
||||
this->m_backBuffers = p_backBuffers;
|
||||
this->m_flags = p_flags;
|
||||
|
@ -38,10 +35,7 @@ MxVideoParam::MxVideoParam(
|
|||
// OFFSET: LEGO1 0x100becf0
|
||||
MxVideoParam::MxVideoParam(MxVideoParam& p_videoParam)
|
||||
{
|
||||
this->m_rect.m_left = p_videoParam.m_rect.m_left;
|
||||
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_rect = p_videoParam.m_rect;
|
||||
this->m_palette = p_videoParam.m_palette;
|
||||
this->m_backBuffers = p_videoParam.m_backBuffers;
|
||||
this->m_flags = p_videoParam.m_flags;
|
||||
|
@ -53,10 +47,7 @@ MxVideoParam::MxVideoParam(MxVideoParam& p_videoParam)
|
|||
// OFFSET: LEGO1 0x100bede0
|
||||
MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam)
|
||||
{
|
||||
this->m_rect.m_left = p_videoParam.m_rect.m_left;
|
||||
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_rect = p_videoParam.m_rect;
|
||||
this->m_palette = p_videoParam.m_palette;
|
||||
this->m_backBuffers = p_videoParam.m_backBuffers;
|
||||
this->m_flags = p_videoParam.m_flags;
|
||||
|
@ -69,24 +60,24 @@ MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam)
|
|||
// OFFSET: LEGO1 0x100bed70
|
||||
void MxVideoParam::SetDeviceName(char* id)
|
||||
{
|
||||
if (this->m_deviceId != 0)
|
||||
if (this->m_deviceId != NULL)
|
||||
delete[] this->m_deviceId;
|
||||
|
||||
if (id != 0) {
|
||||
this->m_deviceId = new char[strlen(id) + 1];
|
||||
|
||||
if (this->m_deviceId != 0) {
|
||||
if (this->m_deviceId != NULL) {
|
||||
strcpy(this->m_deviceId, id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this->m_deviceId = 0;
|
||||
this->m_deviceId = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bed50
|
||||
MxVideoParam::~MxVideoParam()
|
||||
{
|
||||
if (this->m_deviceId != 0)
|
||||
if (this->m_deviceId != NULL)
|
||||
delete[] this->m_deviceId;
|
||||
}
|
||||
|
|
|
@ -220,7 +220,7 @@ void MxVideoPresenter::Destroy(MxBool p_fromDestructor)
|
|||
MxRect32 rect(x, y, x + width, y + height);
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue