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 @@ class Lego3DManager { 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..b940f879 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" @@ -33,7 +34,7 @@ LegoVideoManager::LegoVideoManager() m_unk0x528 = 0; m_arialFont = NULL; m_unk0xe5 = FALSE; - m_unk0x554 = 0; + m_unk0x554 = FALSE; m_initialized = FALSE; } @@ -223,11 +224,109 @@ void LegoVideoManager::MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY) m_cursorY = 463; } -// STUB: LEGO1 0x1007b770 +// 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(), m_videoParam.GetRect().GetHeight()); + 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.Retreat(); + + while (cursor.Next(presenter)) + presenter->PutData(); + + if (m_cursorMoved) { + 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_cursorMoved = FALSE; + } + + ddSurface2->BltFast( + m_cursorXCopy, + m_cursorYCopy, + m_unk0x514, + &m_unk0x518, + DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY + ); + } + + if (m_drawFPS) + FUN_1007bbc0(); + } + else if (m_unk0x500) { + MxPresenter* presenter2; + MxPresenterListCursor cursor2(m_presenters); + + if (cursor2.Last(presenter2)) + presenter2->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::FUN_1007bbc0() { // TODO - return MxVideoManager::Tickle(); } // STUB: LEGO1 0x1007c080 diff --git a/LEGO1/legovideomanager.h b/LEGO1/legovideomanager.h index 24b35507..eb2156ed 100644 --- a/LEGO1/legovideomanager.h +++ b/LEGO1/legovideomanager.h @@ -43,6 +43,7 @@ class LegoVideoManager : public MxVideoManager { private: MxResult CreateDirect3D(); MxResult ConfigureD3DRM(); + void FUN_1007bbc0(); Tgl::Renderer* m_renderer; Lego3DManager* m_3dManager; // 0x68 @@ -59,22 +60,22 @@ class LegoVideoManager : public MxVideoManager { MxBool m_isFullscreenMovie; // 0x4ec MxPalette* m_palette; // 0x4f0 MxStopWatch* m_stopWatch; // 0x4f4 - undefined m_padding0x4f4[8]; + double m_elapsedSeconds; // 0x4f8 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]; + LPDIRECTDRAWSURFACE m_unk0x514; + RECT m_unk0x518; 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_unk0x554; MxBool m_initialized; // 0x555 undefined m_pad0x556[0x39]; }; 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 @@ class MxDirectDraw { 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 @@ class MxDirectDraw { 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 @@ class MxDisplaySurface : public MxCore { 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..f0e3c216 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -97,6 +97,7 @@ class MxListCursor : public MxCore { MxBool First(T& p_obj); MxBool Last(T& p_obj); MxBool Advance(); + MxBool Retreat(); MxBool HasMatch() { return m_match != NULL; } void SetValue(T p_obj); MxBool Head() @@ -290,6 +291,17 @@ inline MxBool MxListCursor::Advance() return m_match != NULL; } +template +inline MxBool MxListCursor::Retreat() +{ + if (!m_match) + m_match = m_list->m_last; + else + m_match = m_match->GetPrev(); + + return m_match != NULL; +} + template inline void MxListCursor::SetValue(T p_obj) { 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 @@ class MxTransitionManager : public MxCore { 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 @@ class MxTransitionManager : public MxCore { 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