From 93012b62f491c322891976ccf60c4a5500cc32b5 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:12:35 -0500 Subject: [PATCH] Implement MxDisplaySurface::CreateCursorSurface (#471) * Update mxdisplaysurface.cpp * Fixes * Update legovideomanager.cpp * Match to 100% --------- Co-authored-by: Christian Semmler --- .../lego/legoomni/include/legovideomanager.h | 4 +- .../legoomni/src/video/legovideomanager.cpp | 19 ++--- LEGO1/omni/include/mxdisplaysurface.h | 2 +- LEGO1/omni/src/video/mxdisplaysurface.cpp | 74 ++++++++++++++++++- 4 files changed, 85 insertions(+), 14 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legovideomanager.h b/LEGO1/lego/legoomni/include/legovideomanager.h index a9532e87..67a7805c 100644 --- a/LEGO1/lego/legoomni/include/legovideomanager.h +++ b/LEGO1/lego/legoomni/include/legovideomanager.h @@ -72,8 +72,8 @@ private: MxS32 m_cursorYCopy; // 0x508 MxS32 m_cursorX; // 0x50c MxS32 m_cursorY; // 0x510 - LPDIRECTDRAWSURFACE m_unk0x514; // 0x514 - RECT m_unk0x518; // 0x518 + LPDIRECTDRAWSURFACE m_cursorSurface; // 0x514 + RECT m_cursorRect; // 0x518 undefined4 m_unk0x528; // 0x528 MxBool m_drawFPS; // 0x52c RECT m_fpsRect; // 0x530 diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index 2a5d1643..f31879b3 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -30,7 +30,7 @@ LegoVideoManager::LegoVideoManager() m_cursorX = m_cursorY; m_cursorYCopy = m_cursorY; m_cursorXCopy = m_cursorY; - m_unk0x514 = NULL; + m_cursorSurface = NULL; m_fullScreenMovie = FALSE; m_drawFPS = FALSE; m_unk0x528 = 0; @@ -309,18 +309,19 @@ inline void LegoVideoManager::DrawCursor() 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_cursorSurface) { + m_cursorRect.top = 0; + m_cursorRect.left = 0; + m_cursorRect.bottom = 16; + m_cursorRect.right = 16; + m_cursorSurface = MxDisplaySurface::CreateCursorSurface(); - if (!m_unk0x514) + if (!m_cursorSurface) m_drawCursor = FALSE; } - ddSurface2->BltFast(m_cursorXCopy, m_cursorYCopy, m_unk0x514, &m_unk0x518, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY); + ddSurface2 + ->BltFast(m_cursorXCopy, m_cursorYCopy, m_cursorSurface, &m_cursorRect, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY); } // STUB: LEGO1 0x1007bbc0 diff --git a/LEGO1/omni/include/mxdisplaysurface.h b/LEGO1/omni/include/mxdisplaysurface.h index dde3d086..1d26264c 100644 --- a/LEGO1/omni/include/mxdisplaysurface.h +++ b/LEGO1/omni/include/mxdisplaysurface.h @@ -91,7 +91,7 @@ public: ); // vtable+0x44 void ClearScreen(); - static LPDIRECTDRAWSURFACE FUN_100bc070(); + static LPDIRECTDRAWSURFACE CreateCursorSurface(); inline LPDIRECTDRAWSURFACE GetDirectDrawSurface1() { return this->m_ddSurface1; } inline LPDIRECTDRAWSURFACE GetDirectDrawSurface2() { return this->m_ddSurface2; } diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index fe67aebb..a9dc2608 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -679,9 +679,79 @@ done: return surface; } -// STUB: LEGO1 0x100bc070 -LPDIRECTDRAWSURFACE MxDisplaySurface::FUN_100bc070() +// FUNCTION: LEGO1 0x100bc070 +LPDIRECTDRAWSURFACE MxDisplaySurface::CreateCursorSurface() { + LPDIRECTDRAWSURFACE newSurface = NULL; + IDirectDraw* draw = MVideoManager()->GetDirectDraw(); + MVideoManager(); + + DDSURFACEDESC ddsd; + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + if (draw->GetDisplayMode(&ddsd) != S_OK) { + return NULL; + } + + if (ddsd.ddpfPixelFormat.dwRGBBitCount != 16) { + return NULL; + } + + ddsd.dwWidth = 16; + ddsd.dwHeight = 16; + ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN; + + if (draw->CreateSurface(&ddsd, &newSurface, NULL) != S_OK) { + ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; + ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + + if (draw->CreateSurface(&ddsd, &newSurface, NULL) != S_OK) + goto done; + } + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + if (newSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != S_OK) + goto done; + else { + MxU16* surface = (MxU16*) ddsd.lpSurface; + MxLong pitch = ddsd.lPitch; + + // draw a simple cursor to the surface + for (MxS32 x = 0; x < 16; x++) { + MxU16* surface2 = surface; + for (MxS32 y = 0; y < 16; y++) { + if ((y > 10 || x) && (x > 10 || y) && x + y != 10) { + if (x + y > 10) + *surface2 = 31775; + else + *surface2 = -1; + } + else { + *surface2 = 0; + } + surface2++; + } + surface = (MxU16*) ((MxU8*) surface + pitch); + } + + newSurface->Unlock(ddsd.lpSurface); + DDCOLORKEY colorkey; + colorkey.dwColorSpaceHighValue = 31775; + colorkey.dwColorSpaceLowValue = 31775; + newSurface->SetColorKey(DDCKEY_SRCBLT, &colorkey); + + return newSurface; + } + +done: + if (newSurface) { + newSurface->Release(); + } + return NULL; }