From 4bf9174c159de20e2186fb27625c6193779eb31a Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 1 Jun 2024 10:54:17 -0400 Subject: [PATCH] Add SDL cursors (#16) * Add SDL cursors * Fix naming --- ISLE/isleapp.cpp | 53 ++++++++++------ ISLE/isleapp.h | 64 ++++++++++---------- LEGO1/lego/legoomni/src/common/legoutils.cpp | 9 ++- 3 files changed, 77 insertions(+), 49 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 1651307c..f722da70 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -9,6 +9,7 @@ #include "legomain.h" #include "legomodelpresenter.h" #include "legopartpresenter.h" +#include "legoutils.h" #include "legovideomanager.h" #include "legoworldpresenter.h" #include "misc.h" @@ -318,8 +319,6 @@ int SDL_AppEvent(void* appstate, const SDL_Event* event) // Remaining functionality to be implemented: // Full screen - crashes when minimizing/maximizing // WM_TIMER - use SDL_Timer functionality instead - // WM_SETCURSOR - update cursor - // 0x5400 - custom LEGO Island SetupCursor event switch (event->type) { case SDL_EVENT_WINDOW_FOCUS_GAINED: @@ -391,6 +390,14 @@ int SDL_AppEvent(void* appstate, const SDL_Event* event) break; } + if (event->type >= SDL_EVENT_USER && event->type <= SDL_EVENT_LAST - 1) { + switch (event->user.code) { + case WM_ISLE_SETCURSOR: + g_isle->SetupCursor((Cursor) (MxS32) event->user.data1); + break; + } + } + return SDL_APP_CONTINUE; } @@ -440,6 +447,12 @@ MxResult IsleApp::SetupWindow() srand(time(NULL)); + // [library:window] Use original game cursors in the resources instead? + m_cursorCurrent = m_cursorArrow = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + m_cursorBusy = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT); + m_cursorNo = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); + SDL_SetCursor(m_cursorCurrent); + if (m_fullScreen) { m_windowHandle = SDL_CreateWindow(WINDOW_TITLE, g_targetWidth, g_targetHeight, SDL_WINDOW_FULLSCREEN); } @@ -635,30 +648,36 @@ inline void IsleApp::Tick() } // FUNCTION: ISLE 0x402e80 -void IsleApp::SetupCursor(WPARAM wParam) +void IsleApp::SetupCursor(Cursor p_cursor) { - switch (wParam) { - case 0: + switch (p_cursor) { + case e_cursorArrow: m_cursorCurrent = m_cursorArrow; break; - case 1: + case e_cursorBusy: m_cursorCurrent = m_cursorBusy; break; - case 2: + case e_cursorNo: m_cursorCurrent = m_cursorNo; break; - case 0xB: + case e_cursorNone: m_cursorCurrent = NULL; - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 0xA: + case e_cursorUnused3: + case e_cursorUnused4: + case e_cursorUnused5: + case e_cursorUnused6: + case e_cursorUnused7: + case e_cursorUnused8: + case e_cursorUnused9: + case e_cursorUnused10: break; } - SetCursor(m_cursorCurrent); + if (m_cursorCurrent != NULL) { + SDL_SetCursor(m_cursorCurrent); + SDL_ShowCursor(); + } + else { + SDL_HideCursor(); + } } diff --git a/ISLE/isleapp.h b/ISLE/isleapp.h index c6f84d1b..73fa918c 100644 --- a/ISLE/isleapp.h +++ b/ISLE/isleapp.h @@ -8,6 +8,8 @@ #include #include +enum Cursor; + // SIZE 0x8c class IsleApp { public: @@ -32,48 +34,48 @@ class IsleApp { void LoadConfig(); void Tick(); - void SetupCursor(WPARAM wParam); + void SetupCursor(Cursor p_cursor); static MxU8 MapMouseButtonFlagsToModifier(SDL_MouseButtonFlags p_flags); inline SDL_Window* GetWindowHandle() { return m_windowHandle; } inline MxLong GetFrameDelta() { return m_frameDelta; } inline MxS32 GetFullScreen() { return m_fullScreen; } - inline HCURSOR GetCursorCurrent() { return m_cursorCurrent; } - inline HCURSOR GetCursorBusy() { return m_cursorBusy; } - inline HCURSOR GetCursorNo() { return m_cursorNo; } + inline SDL_Cursor* GetCursorCurrent() { return m_cursorCurrent; } + inline SDL_Cursor* GetCursorBusy() { return m_cursorBusy; } + inline SDL_Cursor* GetCursorNo() { return m_cursorNo; } inline MxS32 GetDrawCursor() { return m_drawCursor; } inline void SetWindowActive(MxS32 p_windowActive) { m_windowActive = p_windowActive; } private: - char* m_hdPath; // 0x00 - char* m_cdPath; // 0x04 - char* m_deviceId; // 0x08 - char* m_savePath; // 0x0c - MxS32 m_fullScreen; // 0x10 - MxS32 m_flipSurfaces; // 0x14 - MxS32 m_backBuffersInVram; // 0x18 - MxS32 m_using8bit; // 0x1c - MxS32 m_using16bit; // 0x20 - MxS32 m_unk0x24; // 0x24 - MxS32 m_use3dSound; // 0x28 - MxS32 m_useMusic; // 0x2c - MxS32 m_useJoystick; // 0x30 - MxS32 m_joystickIndex; // 0x34 - MxS32 m_wideViewAngle; // 0x38 - MxS32 m_islandQuality; // 0x3c - MxS32 m_islandTexture; // 0x40 - MxS32 m_gameStarted; // 0x44 - MxLong m_frameDelta; // 0x48 - MxVideoParam m_videoParam; // 0x4c - MxS32 m_windowActive; // 0x70 - SDL_Window* m_windowHandle; // 0x74 - MxS32 m_drawCursor; // 0x78 - HCURSOR m_cursorArrow; // 0x7c - HCURSOR m_cursorBusy; // 0x80 - HCURSOR m_cursorNo; // 0x84 - HCURSOR m_cursorCurrent; // 0x88 + char* m_hdPath; // 0x00 + char* m_cdPath; // 0x04 + char* m_deviceId; // 0x08 + char* m_savePath; // 0x0c + MxS32 m_fullScreen; // 0x10 + MxS32 m_flipSurfaces; // 0x14 + MxS32 m_backBuffersInVram; // 0x18 + MxS32 m_using8bit; // 0x1c + MxS32 m_using16bit; // 0x20 + MxS32 m_unk0x24; // 0x24 + MxS32 m_use3dSound; // 0x28 + MxS32 m_useMusic; // 0x2c + MxS32 m_useJoystick; // 0x30 + MxS32 m_joystickIndex; // 0x34 + MxS32 m_wideViewAngle; // 0x38 + MxS32 m_islandQuality; // 0x3c + MxS32 m_islandTexture; // 0x40 + MxS32 m_gameStarted; // 0x44 + MxLong m_frameDelta; // 0x48 + MxVideoParam m_videoParam; // 0x4c + MxS32 m_windowActive; // 0x70 + SDL_Window* m_windowHandle; // 0x74 + MxS32 m_drawCursor; // 0x78 + SDL_Cursor* m_cursorArrow; // 0x7c + SDL_Cursor* m_cursorBusy; // 0x80 + SDL_Cursor* m_cursorNo; // 0x84 + SDL_Cursor* m_cursorCurrent; // 0x88 }; #endif // ISLEAPP_H diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index 62783224..9a755c43 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -27,6 +27,7 @@ #include "realtime/realtime.h" #include "scripts.h" +#include #include #include #include @@ -451,7 +452,13 @@ void FUN_1003ef00(MxBool p_enable) // FUNCTION: LEGO1 0x1003ef40 void SetAppCursor(Cursor p_cursor) { - PostMessageA(MxOmni::GetInstance()->GetWindowHandle(), WM_ISLE_SETCURSOR, p_cursor, 0); + static Uint32 g_userEvent = SDL_RegisterEvents(1); + + SDL_Event event; + event.user.type = g_userEvent; + event.user.code = WM_ISLE_SETCURSOR; + event.user.data1 = (void*) p_cursor; + SDL_PushEvent(&event); } // FUNCTION: LEGO1 0x1003ef60