Implement MxTransitionManager SetWaitIndicator and SetupCopyRect (#165)

* Implement MxTransitionManager SetWaitIndicator and SetupCopyRect

* More accurate SetupCopyRect

* Add MxDSAction::Flag_Bit5

* SetupCopyRect PR Amends

* Correct braces formatting

* Stub MxVideoPresenter::Destroy
This commit is contained in:
Regan Green 2023-10-05 06:31:20 -04:00 committed by GitHub
parent 2d45914ddf
commit c46bc985c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 208 additions and 21 deletions

View file

@ -174,7 +174,7 @@ void MxDisplaySurface::SetPalette(MxPalette *p_palette)
} }
// OFFSET: LEGO1 0x100bc200 STUB // OFFSET: LEGO1 0x100bc200 STUB
void MxDisplaySurface::vtable24(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4) void MxDisplaySurface::vtable24(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4)
{ {
} }
@ -186,7 +186,7 @@ MxBool MxDisplaySurface::vtable28(undefined4, undefined4, undefined4, undefined4
} }
// OFFSET: LEGO1 0x100bc630 STUB // OFFSET: LEGO1 0x100bc630 STUB
MxBool MxDisplaySurface::vtable2c(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool) MxBool MxDisplaySurface::vtable2c(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool)
{ {
return 0; return 0;
} }

View file

@ -23,9 +23,9 @@ class MxDisplaySurface : public MxCore
virtual MxResult Create(MxVideoParam &p_videoParam); virtual MxResult Create(MxVideoParam &p_videoParam);
virtual void Clear(); virtual void Clear();
virtual void SetPalette(MxPalette *p_palette); virtual void SetPalette(MxPalette *p_palette);
virtual void vtable24(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual void vtable24(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4);
virtual MxBool vtable28(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual MxBool vtable28(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4);
virtual MxBool vtable2c(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); virtual MxBool vtable2c(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool);
virtual MxBool vtable30(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); virtual MxBool vtable30(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool);
virtual undefined4 vtable34(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual undefined4 vtable34(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4);
virtual void Display(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual void Display(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4);

View file

@ -16,6 +16,7 @@ class MxDSAction : public MxDSObject
{ {
Flag_Looping = 0x01, Flag_Looping = 0x01,
Flag_Bit3 = 0x04, Flag_Bit3 = 0x04,
Flag_Bit5 = 0x10,
Flag_Enabled = 0x20, Flag_Enabled = 0x20,
Flag_Parsed = 0x80, Flag_Parsed = 0x80,
Flag_Bit9 = 0x200, Flag_Bit9 = 0x200,

View file

@ -17,3 +17,9 @@ void MxMediaPresenter::Init()
this->m_unk48 = NULL; this->m_unk48 = NULL;
this->m_unk4c = NULL; this->m_unk4c = NULL;
} }
// OFFSET: LEGO1 0x100b5f10 STUB
void MxMediaPresenter::VTable0x58()
{
// TODO
}

View file

@ -29,6 +29,8 @@ class MxMediaPresenter : public MxPresenter
return !strcmp(name, MxMediaPresenter::ClassName()) || MxPresenter::IsA(name); return !strcmp(name, MxMediaPresenter::ClassName()) || MxPresenter::IsA(name);
} }
virtual void VTable0x58(); // vtable+0x58
undefined4 m_unk40; undefined4 m_unk40;
undefined4 m_unk44; undefined4 m_unk44;
undefined4 m_unk48; undefined4 m_unk48;

View file

@ -68,6 +68,8 @@ class MxPresenter : public MxCore
MxBool IsEnabled(); MxBool IsEnabled();
inline MxS32 GetCurrentTickleState() { return this->m_currentTickleState; }
inline MxPoint32 GetLocation() { return this->m_location; }
inline MxS32 GetDisplayZ() { return this->m_displayZ; } inline MxS32 GetDisplayZ() { return this->m_displayZ; }
inline MxDSAction *GetAction() { return this->m_action; } inline MxDSAction *GetAction() { return this->m_action; }

View file

@ -104,7 +104,7 @@ void MxTransitionManager::Transition_Dissolve()
} }
if (res == DD_OK) { if (res == DD_OK) {
SubmitCopyRect(ddsd); SubmitCopyRect(&ddsd);
for (MxS32 i = 0; i < 640; i++) { for (MxS32 i = 0; i < 640; i++) {
// Select 16 columns on each tick // Select 16 columns on each tick
@ -129,7 +129,7 @@ void MxTransitionManager::Transition_Dissolve()
} }
} }
SetupCopyRect(ddsd); SetupCopyRect(&ddsd);
m_ddSurface->Unlock(ddsd.lpSurface); m_ddSurface->Unlock(ddsd.lpSurface);
if (VideoManager()->GetVideoParam().flags().GetFlipSurfaces()) { if (VideoManager()->GetVideoParam().flags().GetFlipSurfaces()) {
@ -213,7 +213,7 @@ void MxTransitionManager::Transition_Wipe()
} }
if (res == DD_OK) { if (res == DD_OK) {
SubmitCopyRect(ddsd); SubmitCopyRect(&ddsd);
// For each of the 240 animation ticks, blank out two scanlines // For each of the 240 animation ticks, blank out two scanlines
// starting at the top of the screen. // starting at the top of the screen.
@ -224,21 +224,42 @@ void MxTransitionManager::Transition_Wipe()
line += ddsd.lPitch; line += ddsd.lPitch;
memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8); memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8);
SetupCopyRect(ddsd); SetupCopyRect(&ddsd);
m_ddSurface->Unlock(ddsd.lpSurface); m_ddSurface->Unlock(ddsd.lpSurface);
m_animationTimer++; m_animationTimer++;
} }
} }
// OFFSET: LEGO1 0x1004c470 STUB // OFFSET: LEGO1 0x1004c470
void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *p_waitIndicator)
{ {
// TODO // End current wait indicator
if (m_waitIndicator != NULL) {
m_waitIndicator->GetAction()->SetFlags(m_waitIndicator->GetAction()->GetFlags() & ~MxDSAction::Flag_Parsed);
m_waitIndicator->EndAction();
m_waitIndicator = NULL;
}
// Check if we were given a new wait indicator
if (p_waitIndicator != NULL) {
// Setup the new wait indicator
m_waitIndicator = p_waitIndicator;
LegoVideoManager *videoManager = VideoManager();
videoManager->RemovePresenter(*m_waitIndicator);
if (m_waitIndicator->GetCurrentTickleState() < MxPresenter::TickleState_Streaming) {
m_waitIndicator->Tickle();
}
} else {
// Disable copy rect
m_copyFlags.bit0 = FALSE;
}
} }
// OFFSET: LEGO1 0x1004c4d0 // OFFSET: LEGO1 0x1004c4d0
void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) void MxTransitionManager::SubmitCopyRect(LPDDSURFACEDESC ddsc)
{ {
// Check if the copy rect is setup // Check if the copy rect is setup
if (m_copyFlags.bit0 == FALSE || m_waitIndicator == NULL || m_copyBuffer == NULL) { if (m_copyFlags.bit0 == FALSE || m_waitIndicator == NULL || m_copyBuffer == NULL) {
@ -248,7 +269,7 @@ void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc)
// Copy the copy rect onto the surface // Copy the copy rect onto the surface
char *dst; char *dst;
DWORD bytesPerPixel = ddsc.ddpfPixelFormat.dwRGBBitCount / 8; DWORD bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8;
const char *src = (const char *)m_copyBuffer; const char *src = (const char *)m_copyBuffer;
@ -256,12 +277,12 @@ void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc)
copyPitch = ((m_copyRect.right - m_copyRect.left) + 1) * bytesPerPixel; copyPitch = ((m_copyRect.right - m_copyRect.left) + 1) * bytesPerPixel;
LONG y; LONG y;
dst = (char *)ddsc.lpSurface + (ddsc.lPitch * m_copyRect.top) + (bytesPerPixel * m_copyRect.left); dst = (char *)ddsc->lpSurface + (ddsc->lPitch * m_copyRect.top) + (bytesPerPixel * m_copyRect.left);
for (y = 0; y < m_copyRect.bottom - m_copyRect.top + 1; ++y) { for (y = 0; y < m_copyRect.bottom - m_copyRect.top + 1; ++y) {
memcpy(dst, src, copyPitch); memcpy(dst, src, copyPitch);
src += copyPitch; src += copyPitch;
dst += ddsc.lPitch; dst += ddsc->lPitch;
} }
// Free the copy buffer // Free the copy buffer
@ -269,8 +290,60 @@ void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc)
m_copyBuffer = NULL; m_copyBuffer = NULL;
} }
// OFFSET: LEGO1 0x1004c580 STUB // OFFSET: LEGO1 0x1004c580
void MxTransitionManager::SetupCopyRect(DDSURFACEDESC &ddsc) void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc)
{ {
// TODO // Check if the copy rect is setup
if (m_copyFlags.bit0 == FALSE || m_waitIndicator == NULL) {
return;
}
// Tickle wait indicator
m_waitIndicator->Tickle();
// Check if wait indicator has started
if (m_waitIndicator->GetCurrentTickleState() >= MxPresenter::TickleState_Streaming) {
// Setup the copy rect
DWORD copyPitch = (ddsc->ddpfPixelFormat.dwRGBBitCount / 8) * (m_copyRect.right - m_copyRect.left + 1); // This uses m_copyRect, seemingly erroneously
DWORD bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8;
m_copyRect.left = m_waitIndicator->GetLocation().m_x;
m_copyRect.top = m_waitIndicator->GetLocation().m_y;
MxS32 height = m_waitIndicator->GetHeight();
MxS32 width = m_waitIndicator->GetWidth();
m_copyRect.right = m_copyRect.left + width - 1;
m_copyRect.bottom = m_copyRect.top + height - 1;
// Allocate the copy buffer
const char *src = (const char*)ddsc->lpSurface + m_copyRect.top * ddsc->lPitch + bytesPerPixel * m_copyRect.left;
m_copyBuffer = malloc(bytesPerPixel * width * height);
if (!m_copyBuffer)
return;
// Copy into the copy buffer
char *dst = (char*)m_copyBuffer;
for (MxS32 i = 0; i < (m_copyRect.bottom - m_copyRect.top + 1); i++)
{
memcpy(dst, src, copyPitch);
src += ddsc->lPitch;
dst += copyPitch;
}
}
// Setup display surface
if ((m_waitIndicator->GetAction()->GetFlags() & MxDSAction::Flag_Bit5) != 0)
{
MxDisplaySurface *displaySurface = VideoManager()->GetDisplaySurface();
MxBool unkbool = FALSE;
displaySurface->vtable2c(ddsc, m_waitIndicator->m_unk50, 0, 0, m_waitIndicator->GetLocation().m_x, m_waitIndicator->GetLocation().m_y, m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight(), unkbool);
}
else
{
MxDisplaySurface *displaySurface = VideoManager()->GetDisplaySurface();
displaySurface->vtable24(ddsc, m_waitIndicator->m_unk50, 0, 0, m_waitIndicator->GetLocation().m_x, m_waitIndicator->GetLocation().m_y, m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight());
}
} }

View file

@ -12,7 +12,7 @@ class MxTransitionManager : public MxCore
MxTransitionManager(); MxTransitionManager();
virtual ~MxTransitionManager() override; // vtable+0x0 virtual ~MxTransitionManager() override; // vtable+0x0
__declspec(dllexport) void SetWaitIndicator(MxVideoPresenter *videoPresenter); __declspec(dllexport) void SetWaitIndicator(MxVideoPresenter *p_waitIndicator);
virtual MxResult Tickle(); // vtable+0x8 virtual MxResult Tickle(); // vtable+0x8
@ -46,8 +46,8 @@ class MxTransitionManager : public MxCore
void EndTransition(MxBool p_notifyWorld); void EndTransition(MxBool p_notifyWorld);
void Transition_Dissolve(); void Transition_Dissolve();
void Transition_Wipe(); void Transition_Wipe();
void SubmitCopyRect(DDSURFACEDESC &); void SubmitCopyRect(LPDDSURFACEDESC ddsc);
void SetupCopyRect(DDSURFACEDESC &); void SetupCopyRect(LPDDSURFACEDESC ddsc);
MxVideoPresenter *m_waitIndicator; MxVideoPresenter *m_waitIndicator;
RECT m_copyRect; RECT m_copyRect;

View file

@ -2,8 +2,94 @@
DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64); DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64);
// OFFSET: LEGO1 0x1000c700 STUB
void MxVideoPresenter::VTable0x5c()
{
// TODO
}
// OFFSET: LEGO1 0x1000c710 STUB
void MxVideoPresenter::VTable0x60()
{
// TODO
}
// OFFSET: LEGO1 0x1000c720 STUB
void MxVideoPresenter::VTable0x68()
{
// TODO
}
// OFFSET: LEGO1 0x1000c730 STUB
void MxVideoPresenter::VTable0x70()
{
// TODO
}
// OFFSET: LEGO1 0x1000c740
MxVideoPresenter::~MxVideoPresenter()
{
Destroy(TRUE);
}
// OFFSET: LEGO1 0x1000c7a0 STUB
void MxVideoPresenter::InitVirtual()
{
// TODO
}
// OFFSET: LEGO1 0x1000c7b0 STUB
void MxVideoPresenter::VTable0x78()
{
// TODO
}
// OFFSET: LEGO1 0x1000c7c0 STUB
void MxVideoPresenter::VTable0x7c()
{
// TODO
}
// OFFSET: LEGO1 0x1000c7e0 STUB
MxS32 MxVideoPresenter::GetWidth()
{
// TODO
return 0;
}
// OFFSET: LEGO1 0x1000c800 STUB
MxS32 MxVideoPresenter::GetHeight()
{
// TODO
return 0;
}
// OFFSET: LEGO1 0x100b2760 STUB // OFFSET: LEGO1 0x100b2760 STUB
void MxVideoPresenter::Init() void MxVideoPresenter::Init()
{ {
// TODO // TODO
} }
// OFFSET: LEGO1 0x100b27b0 STUB
void MxVideoPresenter::Destroy(MxBool)
{
// TODO
}
// OFFSET: LEGO1 0x100b28b0 STUB
void MxVideoPresenter::VTable0x64()
{
// TODO
}
// OFFSET: LEGO1 0x100b2a70 STUB
void MxVideoPresenter::VTable0x6c()
{
// TODO
}
// OFFSET: LEGO1 0x100b3300 STUB
void MxVideoPresenter::VTable0x74()
{
// TODO
}

View file

@ -13,6 +13,8 @@ class MxVideoPresenter : public MxMediaPresenter
Init(); Init();
} }
virtual ~MxVideoPresenter() override; // vtable+0x0
// OFFSET: LEGO1 0x1000c820 // OFFSET: LEGO1 0x1000c820
inline virtual const char *ClassName() const override // vtable+0x0c inline virtual const char *ClassName() const override // vtable+0x0c
{ {
@ -27,6 +29,21 @@ class MxVideoPresenter : public MxMediaPresenter
} }
void Init(); void Init();
void Destroy(MxBool);
virtual void InitVirtual() override; // vtable+0x38
virtual void VTable0x5c(); // vtable+0x5c
virtual void VTable0x60(); // vtable+0x60
virtual void VTable0x64(); // vtable+0x64
virtual void VTable0x68(); // vtable+0x68
virtual void VTable0x6c(); // vtable+0x6c
virtual void VTable0x70(); // vtable+0x70
virtual void VTable0x74(); // vtable+0x74
virtual void VTable0x78(); // vtable+0x78
virtual void VTable0x7c(); // vtable+0x7c
virtual MxS32 GetWidth(); // vtable+0x80
virtual MxS32 GetHeight(); // vtable+0x84
undefined4 m_unk50; undefined4 m_unk50;
undefined4 m_unk54; undefined4 m_unk54;