From dac2a517c3d9953d00f634cf060f648f8ae84577 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 6 Jan 2024 12:06:50 -0500 Subject: [PATCH] Implement/match LegoVideoManager::Tickle (#409) * Implement LegoVideoManager::Tickle * Match * Remove duplicate annotations * Add missing annotations * Rename list functions * Fix * Rename some symbols --- LEGO1/lego3dmanager.cpp | 7 +++ LEGO1/lego3dmanager.h | 1 + LEGO1/legovideomanager.cpp | 107 ++++++++++++++++++++++++++++++-- LEGO1/legovideomanager.h | 62 +++++++++--------- LEGO1/legoworld.h | 3 + LEGO1/mxdirectdraw.h | 100 +++++++++++++++-------------- LEGO1/mxdirectx/mxstopwatch.h | 4 +- LEGO1/mxdisplaysurface.cpp | 6 ++ LEGO1/mxdisplaysurface.h | 1 + LEGO1/mxlist.h | 36 +++++++---- LEGO1/mxloopingsmkpresenter.cpp | 2 +- LEGO1/mxregion.cpp | 2 +- LEGO1/mxtransitionmanager.h | 30 ++++----- 13 files changed, 247 insertions(+), 114 deletions(-) diff --git a/LEGO1/lego3dmanager.cpp b/LEGO1/lego3dmanager.cpp index 13b5711c..ebc488ff 100644 --- a/LEGO1/lego3dmanager.cpp +++ b/LEGO1/lego3dmanager.cpp @@ -63,3 +63,10 @@ void Lego3DManager::Destroy() delete m_viewLODListManager; m_viewLODListManager = NULL; } + +// STUB: LEGO1 0xx100ab4b0 +double Lego3DManager::FUN_100ab4b0(double p_und) +{ + // TODO + return 0.0; +} diff --git a/LEGO1/lego3dmanager.h b/LEGO1/lego3dmanager.h index 37b7c1ff..732bf978 100644 --- a/LEGO1/lego3dmanager.h +++ b/LEGO1/lego3dmanager.h @@ -27,6 +27,7 @@ public: virtual ~Lego3DManager(); BOOL Create(CreateStruct& p_createStruct); + double FUN_100ab4b0(double p_und); inline Lego3DView* GetLego3DView() { return this->m_3dView; } inline ViewLODListManager* GetViewLODListManager() { return this->m_viewLODListManager; } diff --git a/LEGO1/legovideomanager.cpp b/LEGO1/legovideomanager.cpp index 8ab9fc35..218406e6 100644 --- a/LEGO1/legovideomanager.cpp +++ b/LEGO1/legovideomanager.cpp @@ -3,6 +3,7 @@ #include "legoomni.h" #include "legoroi.h" #include "mxtimer.h" +#include "mxtransitionmanager.h" #include "realtime/matrix.h" #include "viewmanager/viewroi.h" @@ -23,7 +24,7 @@ LegoVideoManager::LegoVideoManager() m_isFullscreenMovie = FALSE; m_palette = NULL; m_stopWatch = NULL; - m_cursorMoved = FALSE; + m_drawCursor = FALSE; m_cursorX = m_cursorY; m_cursorYCopy = m_cursorY; m_cursorXCopy = m_cursorY; @@ -33,7 +34,7 @@ LegoVideoManager::LegoVideoManager() m_unk0x528 = 0; m_arialFont = NULL; m_unk0xe5 = FALSE; - m_unk0x554 = 0; + m_unk0x554 = FALSE; m_initialized = FALSE; } @@ -214,7 +215,7 @@ void LegoVideoManager::MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY) { m_cursorX = p_cursorX; m_cursorY = p_cursorY; - m_cursorMoved = TRUE; + m_drawCursor = TRUE; if (623 < p_cursorX) m_cursorX = 623; @@ -223,11 +224,107 @@ void LegoVideoManager::MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY) m_cursorY = 463; } -// STUB: LEGO1 0x1007b770 +inline void LegoVideoManager::DrawCursor() +{ + if (m_cursorX != m_cursorXCopy || m_cursorY != m_cursorYCopy) { + if (m_cursorX >= 0 && m_cursorY >= 0) { + m_cursorXCopy = m_cursorX; + m_cursorYCopy = m_cursorY; + } + } + + LPDIRECTDRAWSURFACE ddSurface2 = m_displaySurface->GetDirectDrawSurface2(); + + if (!m_unk0x514) { + m_unk0x518.top = 0; + m_unk0x518.left = 0; + m_unk0x518.bottom = 16; + m_unk0x518.right = 16; + m_unk0x514 = MxDisplaySurface::FUN_100bc070(); + + if (!m_unk0x514) + m_drawCursor = FALSE; + } + + ddSurface2->BltFast(m_cursorXCopy, m_cursorYCopy, m_unk0x514, &m_unk0x518, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY); +} + +// FUNCTION: LEGO1 0x1007b770 MxResult LegoVideoManager::Tickle() +{ + if (m_unk0x554 && !m_videoParam.Flags().GetFlipSurfaces() && + TransitionManager()->GetTransitionType() == MxTransitionManager::NOT_TRANSITIONING) + Sleep(30); + + m_stopWatch->Stop(); + m_elapsedSeconds = m_stopWatch->ElapsedSeconds(); + m_stopWatch->Reset(); + m_stopWatch->Start(); + + m_direct3d->RestoreSurfaces(); + + SortPresenterList(); + + MxPresenter* presenter; + MxPresenterListCursor cursor(m_presenters); + + while (cursor.Next(presenter)) + presenter->Tickle(); + + if (m_unk0xe4 && !m_initialized) + m_3dManager->GetLego3DView()->GetView()->Clear(); + + MxRect32 rect(0, 0, m_videoParam.GetRect().GetWidth() - 1, m_videoParam.GetRect().GetHeight() - 1); + InvalidateRect(rect); + + if (!m_initialized && (m_unk0xe4 || m_unk0xe5)) { + cursor.Reset(); + + while (cursor.Next(presenter) && presenter->GetDisplayZ() >= 0) + presenter->PutData(); + + if (!m_unk0xe5) { + m_3dManager->FUN_100ab4b0(0.0); + m_3dManager->GetLego3DView()->GetDevice()->Update(); + } + + cursor.Prev(); + + while (cursor.Next(presenter)) + presenter->PutData(); + + if (m_drawCursor) + DrawCursor(); + + if (m_drawFPS) + DrawFPS(); + } + else if (m_unk0x500) { + MxPresenter* presenter; + MxPresenterListCursor cursor(m_presenters); + + if (cursor.Last(presenter)) + presenter->PutData(); + } + + if (!m_initialized) { + if (m_unk0xe4 && m_videoParam.Flags().GetFlipSurfaces()) { + m_3dManager->GetLego3DView() + ->GetView() + ->ForceUpdate(0, 0, m_videoParam.GetRect().GetWidth(), m_videoParam.GetRect().GetHeight()); + } + + UpdateRegion(); + } + + m_region->Reset(); + return SUCCESS; +} + +// STUB: LEGO1 0x1007bbc0 +void LegoVideoManager::DrawFPS() { // TODO - return MxVideoManager::Tickle(); } // STUB: LEGO1 0x1007c080 diff --git a/LEGO1/legovideomanager.h b/LEGO1/legovideomanager.h index 24b35507..e4ef28ea 100644 --- a/LEGO1/legovideomanager.h +++ b/LEGO1/legovideomanager.h @@ -43,40 +43,46 @@ public: private: MxResult CreateDirect3D(); MxResult ConfigureD3DRM(); + void DrawFPS(); - Tgl::Renderer* m_renderer; - Lego3DManager* m_3dManager; // 0x68 - LegoROI* m_viewROI; // 0x6c - undefined4 m_unk0x70; - MxDirect3D* m_direct3d; // 0x74 - undefined4 m_unk0x78[27]; - MxBool m_unk0xe4; - MxBool m_unk0xe5; - MxBool m_unk0xe6; + inline void DrawCursor(); + + Tgl::Renderer* m_renderer; // 0x64 + Lego3DManager* m_3dManager; // 0x68 + LegoROI* m_viewROI; // 0x6c + undefined4 m_unk0x70; // 0x70 + MxDirect3D* m_direct3d; // 0x74 + undefined4 m_unk0x78[27]; // 0x78 + MxBool m_unk0xe4; // 0xe4 + MxBool m_unk0xe5; // 0xe5 + MxBool m_unk0xe6; // 0xe6 PALETTEENTRY m_paletteEntries[256]; // 0xe7 - undefined m_padding0x4e7; + undefined m_padding0x4e7; // 0x4e7 MxUnknown100d9d00* m_unk0x100d9d00; // 0x4e8 MxBool m_isFullscreenMovie; // 0x4ec MxPalette* m_palette; // 0x4f0 MxStopWatch* m_stopWatch; // 0x4f4 - undefined m_padding0x4f4[8]; - MxBool m_unk0x500; - MxBool m_cursorMoved; // 0x501 - MxS32 m_cursorXCopy; // 0x504 - MxS32 m_cursorYCopy; // 0x508 - MxS32 m_cursorX; // 0x50c - MxS32 m_cursorY; // 0x510 - undefined4 m_unk0x514; - undefined m_pad0x518[0x10]; - undefined4 m_unk0x528; - MxBool m_drawFPS; // 0x52c - RECT m_fpsRect; // 0x530 - HFONT m_arialFont; // 0x540 - SIZE m_fpsSize; // 0x544 - undefined m_pad0x54c[8]; - undefined m_unk0x554; - MxBool m_initialized; // 0x555 - undefined m_pad0x556[0x39]; + double m_elapsedSeconds; // 0x4f8 + MxBool m_unk0x500; // 0x500 + MxBool m_drawCursor; // 0x501 + MxS32 m_cursorXCopy; // 0x504 + MxS32 m_cursorYCopy; // 0x508 + MxS32 m_cursorX; // 0x50c + MxS32 m_cursorY; // 0x510 + LPDIRECTDRAWSURFACE m_unk0x514; // 0x514 + RECT m_unk0x518; // 0x518 + undefined4 m_unk0x528; // 0x528 + MxBool m_drawFPS; // 0x52c + RECT m_fpsRect; // 0x530 + HFONT m_arialFont; // 0x540 + SIZE m_fpsSize; // 0x544 + undefined m_pad0x54c[8]; // 0x54c + MxBool m_unk0x554; // 0x554 + MxBool m_initialized; // 0x555 + undefined m_pad0x556[0x39]; // 0x556 }; +// SYNTHETIC: LEGO1 0x1007ab20 +// LegoVideoManager::`scalar deleting destructor' + #endif // LEGOVIDEOMANAGER_H diff --git a/LEGO1/legoworld.h b/LEGO1/legoworld.h index d855b530..c4f53913 100644 --- a/LEGO1/legoworld.h +++ b/LEGO1/legoworld.h @@ -84,4 +84,7 @@ protected: // FUNCTION: LEGO1 0x1001f0c0 // MxPresenterListCursor::~MxPresenterListCursor +// TEMPLATE: LEGO1 0x10020760 +// MxListCursor::MxListCursor + #endif // LEGOWORLD_H diff --git a/LEGO1/mxdirectdraw.h b/LEGO1/mxdirectdraw.h index 248537cd..90be31c5 100644 --- a/LEGO1/mxdirectdraw.h +++ b/LEGO1/mxdirectdraw.h @@ -39,6 +39,55 @@ public: void* m_unk0x178; // 0x178 }; + __declspec(dllexport) int FlipToGDISurface(); + __declspec(dllexport) static int GetPrimaryBitDepth(); + __declspec(dllexport) int Pause(int); + + MxDirectDraw(); + virtual ~MxDirectDraw(); + + virtual BOOL Create( + HWND hWnd, + BOOL fullscreen_1, + BOOL surface_fullscreen, + BOOL onlySystemMemory, + int width, + int height, + int bpp, + const PALETTEENTRY* pPaletteEntries, + int paletteEntryCount + ); // vtable+0x04 + virtual void Destroy(); // vtable+0x08 + virtual void DestroyButNotDirectDraw(); // vtable+0x0c + virtual const char* ErrorToString(HRESULT p_error); // vtable+0x10 + + BOOL CacheOriginalPaletteEntries(); + HRESULT CreateDDSurface(LPDDSURFACEDESC a2, LPDIRECTDRAWSURFACE* a3, IUnknown* a4); + BOOL CreateTextSurfaces(); + BOOL CreateZBuffer(DWORD memorytype, DWORD depth); + BOOL DDCreateSurfaces(); + BOOL DDInit(BOOL fullscreen); + BOOL DDSetMode(int width, int height, int bpp); + void Error(const char* p_message, MxS32 p_error); + + BOOL GetDDSurfaceDesc(LPDDSURFACEDESC lpDDSurfDesc, LPDIRECTDRAWSURFACE lpDDSurf); + BOOL IsSupportedMode(int width, int height, int bpp); + BOOL RecreateDirectDraw(GUID** a2); + BOOL RestoreOriginalPaletteEntries(); + BOOL RestorePaletteEntries(); + BOOL RestoreSurfaces(); + BOOL SetPaletteEntries(const PALETTEENTRY* pPaletteEntries, int paletteEntryCount, BOOL fullscreen); + BOOL TextToTextSurface(const char* text, IDirectDrawSurface* pSurface, SIZE& textSizeOnSurface); + BOOL TextToTextSurface1(const char* text); + BOOL TextToTextSurface2(const char* lpString); + void FUN_1009e020(); + void FUN_1009d920(); + + inline IDirectDraw* GetDirectDraw() { return m_pDirectDraw; } + inline IDirectDrawSurface* GetFrontBuffer() { return m_pFrontBuffer; } + inline IDirectDrawSurface* GetBackBuffer() { return m_pBackBuffer; } + inline IDirectDrawClipper* GetClipper() { return m_pClipper; } + protected: BOOL m_bOnlySoftRender; // 0x04 BOOL m_bFlipSurfaces; // 0x08 @@ -69,57 +118,6 @@ protected: int m_pauseCount; // 0x86c DeviceModesInfo* m_pCurrentDeviceModesList; // 0x870 Mode m_currentMode; // 0x874 - -public: - __declspec(dllexport) int FlipToGDISurface(); - __declspec(dllexport) static int GetPrimaryBitDepth(); - __declspec(dllexport) int Pause(int); - - MxDirectDraw(); - virtual ~MxDirectDraw(); - - virtual BOOL Create( - HWND hWnd, - BOOL fullscreen_1, - BOOL surface_fullscreen, - BOOL onlySystemMemory, - int width, - int height, - int bpp, - const PALETTEENTRY* pPaletteEntries, - int paletteEntryCount - ); // vtable+0x04 - virtual void Destroy(); // vtable+0x08 - virtual void DestroyButNotDirectDraw(); // vtable+0x0c - virtual const char* ErrorToString(HRESULT p_error); // vtable+0x10 - - inline IDirectDraw* GetDirectDraw() { return m_pDirectDraw; } - inline IDirectDrawSurface* GetFrontBuffer() { return m_pFrontBuffer; } - inline IDirectDrawSurface* GetBackBuffer() { return m_pBackBuffer; } - inline IDirectDrawClipper* GetClipper() { return m_pClipper; } - -protected: - BOOL CacheOriginalPaletteEntries(); - HRESULT CreateDDSurface(LPDDSURFACEDESC a2, LPDIRECTDRAWSURFACE* a3, IUnknown* a4); - BOOL CreateTextSurfaces(); - BOOL CreateZBuffer(DWORD memorytype, DWORD depth); - BOOL DDCreateSurfaces(); - BOOL DDInit(BOOL fullscreen); - BOOL DDSetMode(int width, int height, int bpp); - void Error(const char* p_message, MxS32 p_error); - - BOOL GetDDSurfaceDesc(LPDDSURFACEDESC lpDDSurfDesc, LPDIRECTDRAWSURFACE lpDDSurf); - BOOL IsSupportedMode(int width, int height, int bpp); - BOOL RecreateDirectDraw(GUID** a2); - BOOL RestoreOriginalPaletteEntries(); - BOOL RestorePaletteEntries(); - BOOL RestoreSurfaces(); - BOOL SetPaletteEntries(const PALETTEENTRY* pPaletteEntries, int paletteEntryCount, BOOL fullscreen); - BOOL TextToTextSurface(const char* text, IDirectDrawSurface* pSurface, SIZE& textSizeOnSurface); - BOOL TextToTextSurface1(const char* text); - BOOL TextToTextSurface2(const char* lpString); - void FUN_1009e020(); - void FUN_1009d920(); }; #endif // MXDIRECTDRAW_H diff --git a/LEGO1/mxdirectx/mxstopwatch.h b/LEGO1/mxdirectx/mxstopwatch.h index bb37e484..1ce3275f 100644 --- a/LEGO1/mxdirectx/mxstopwatch.h +++ b/LEGO1/mxdirectx/mxstopwatch.h @@ -11,6 +11,8 @@ // NOTE: MxStopWatch measures elapsed (wall clock) time. // +#define HUGE_VAL_IMMEDIATE 1.7976931348623157e+308 + class MxStopWatch { public: MxStopWatch(); @@ -54,7 +56,7 @@ inline void MxStopWatch::Stop() if (endTick.HighPart != m_startTick.HighPart) { // LARGE_INTEGER arithmetic not yet provided - m_elapsedSeconds = HUGE_VAL; + m_elapsedSeconds = HUGE_VAL_IMMEDIATE; } else { m_elapsedSeconds += ((endTick.LowPart - m_startTick.LowPart) / (double) m_ticksPerSeconds); diff --git a/LEGO1/mxdisplaysurface.cpp b/LEGO1/mxdisplaysurface.cpp index 46789886..69d28822 100644 --- a/LEGO1/mxdisplaysurface.cpp +++ b/LEGO1/mxdisplaysurface.cpp @@ -569,6 +569,12 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::VTable0x44(MxBitmap*, undefined4*, undefin return NULL; } +// STUB: LEGO1 0x100bc070 +LPDIRECTDRAWSURFACE MxDisplaySurface::FUN_100bc070() +{ + return NULL; +} + // STUB: LEGO1 0x100bc200 void MxDisplaySurface::VTable0x24( LPDDSURFACEDESC, diff --git a/LEGO1/mxdisplaysurface.h b/LEGO1/mxdisplaysurface.h index 7b578c68..25fe95aa 100644 --- a/LEGO1/mxdisplaysurface.h +++ b/LEGO1/mxdisplaysurface.h @@ -86,6 +86,7 @@ public: virtual LPDIRECTDRAWSURFACE VTable0x44(MxBitmap*, undefined4*, undefined4, undefined4); // vtable+0x44 void FUN_100ba640(); + static LPDIRECTDRAWSURFACE FUN_100bc070(); inline LPDIRECTDRAWSURFACE GetDirectDrawSurface1() { return this->m_ddSurface1; } inline LPDIRECTDRAWSURFACE GetDirectDrawSurface2() { return this->m_ddSurface2; } diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 80fa0e00..33fbbcd0 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -91,12 +91,13 @@ public: MxBool Find(T p_obj); void Detach(); void Destroy(); + MxBool Next(); MxBool Next(T& p_obj); + MxBool Prev(); MxBool Prev(T& p_obj); MxBool Current(T& p_obj); MxBool First(T& p_obj); MxBool Last(T& p_obj); - MxBool Advance(); MxBool HasMatch() { return m_match != NULL; } void SetValue(T p_obj); MxBool Head() @@ -222,6 +223,17 @@ inline void MxListCursor::Destroy() } } +template +inline MxBool MxListCursor::Next() +{ + if (!m_match) + m_match = m_list->m_first; + else + m_match = m_match->GetNext(); + + return m_match != NULL; +} + template inline MxBool MxListCursor::Next(T& p_obj) { @@ -236,6 +248,17 @@ inline MxBool MxListCursor::Next(T& p_obj) return m_match != NULL; } +template +inline MxBool MxListCursor::Prev() +{ + if (!m_match) + m_match = m_list->m_last; + else + m_match = m_match->GetPrev(); + + return m_match != NULL; +} + template inline MxBool MxListCursor::Prev(T& p_obj) { @@ -279,17 +302,6 @@ inline MxBool MxListCursor::Last(T& p_obj) return m_match != NULL; } -template -inline MxBool MxListCursor::Advance() -{ - if (!m_match) - m_match = m_list->m_first; - else - m_match = m_match->GetNext(); - - return m_match != NULL; -} - template inline void MxListCursor::SetValue(T p_obj) { diff --git a/LEGO1/mxloopingsmkpresenter.cpp b/LEGO1/mxloopingsmkpresenter.cpp index 11ab8388..8d0f4d00 100644 --- a/LEGO1/mxloopingsmkpresenter.cpp +++ b/LEGO1/mxloopingsmkpresenter.cpp @@ -99,7 +99,7 @@ void MxLoopingSmkPresenter::RepeatingTickle() while (cursor.Next(chunk)) chunk->SetTime(chunk->GetTime() + time); - m_cursor->Advance(); + m_cursor->Next(); } MxStreamChunk* chunk; diff --git a/LEGO1/mxregion.cpp b/LEGO1/mxregion.cpp index d21b9fdb..ea7fab55 100644 --- a/LEGO1/mxregion.cpp +++ b/LEGO1/mxregion.cpp @@ -146,7 +146,7 @@ void MxRegionTopBottom::FUN_100c5280(MxS32 p_left, MxS32 p_right) p_right = leftRight->GetRight(); b = a; - b.Advance(); + b.Next(); a.Destroy(); if (!b.Current(leftRight)) diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index e55e4804..ac87ffcc 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -43,6 +43,8 @@ public: MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim); + inline TransitionType GetTransitionType() { return m_transitionType; } + private: void EndTransition(MxBool p_notifyWorld); void TransitionNone(); @@ -55,21 +57,19 @@ private: void SubmitCopyRect(LPDDSURFACEDESC p_ddsc); void SetupCopyRect(LPDDSURFACEDESC p_ddsc); - MxVideoPresenter* m_waitIndicator; - RECT m_copyRect; - MxU8* m_copyBuffer; - - FlagBitfield m_copyFlags; - undefined4 m_unk0x24; - FlagBitfield m_unk0x28; - - TransitionType m_transitionType; - LPDIRECTDRAWSURFACE m_ddSurface; - MxU16 m_animationTimer; - MxU16 m_columnOrder[640]; // 0x36 - MxU16 m_randomShift[480]; // 0x536 - MxULong m_systemTime; // 0x8f8 - MxS32 m_animationSpeed; // 0x8fc + MxVideoPresenter* m_waitIndicator; // 0x08 + RECT m_copyRect; // 0x0c + MxU8* m_copyBuffer; // 0x1c + FlagBitfield m_copyFlags; // 0x20 + undefined4 m_unk0x24; // 0x24 + FlagBitfield m_unk0x28; // 0x28 + TransitionType m_transitionType; // 0x2c + LPDIRECTDRAWSURFACE m_ddSurface; // 0x30 + MxU16 m_animationTimer; // 0x34 + MxU16 m_columnOrder[640]; // 0x36 + MxU16 m_randomShift[480]; // 0x536 + MxULong m_systemTime; // 0x8f8 + MxS32 m_animationSpeed; // 0x8fc }; #endif // MXTRANSITIONMANAGER_H