diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 10a06a6a..e7c2dda1 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -178,18 +178,14 @@ MxS32 IsleApp::SetupLegoOmni() char mediaPath[256]; GetProfileStringA("LEGO Island", "MediaPath", "", mediaPath, sizeof(mediaPath)); - // [library:window] For now, get the underlying Windows HWND to pass into Omni - HWND hwnd = (HWND - ) SDL_GetPointerProperty(SDL_GetWindowProperties(m_windowHandle), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); - #ifdef COMPAT_MODE MxS32 failure; { - MxOmniCreateParam param(mediaPath, hwnd, m_videoParam, MxOmniCreateFlags()); + MxOmniCreateParam param(mediaPath, m_windowHandle, m_videoParam, MxOmniCreateFlags()); failure = Lego()->Create(param) == FAILURE; } #else - MxS32 failure = Lego()->Create(MxOmniCreateParam(mediaPath, hwnd, m_videoParam, MxOmniCreateFlags())) == FAILURE; + MxS32 failure = Lego()->Create(MxOmniCreateParam(mediaPath, m_windowHandle, m_videoParam, MxOmniCreateFlags())) == FAILURE; #endif if (!failure) { @@ -392,12 +388,17 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) break; } - // FIXME: use g_userEvent instead of SDL_EVENT_USER - if (event->type >= SDL_EVENT_USER && event->type <= SDL_EVENT_LAST - 1) { + if (event->user.type == g_LegoSdlEvents.windows_message) { switch (event->user.code) { case WM_ISLE_SETCURSOR: g_isle->SetupCursor((Cursor) (uintptr_t) event->user.data1); break; + case WM_QUIT: + return SDL_APP_SUCCESS; + break; + default: + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unknown SDL Windows message: 0x%" SDL_PRIx32, event->user.code); + break; } } diff --git a/LEGO1/lego/legoomni/include/legomain.h b/LEGO1/lego/legoomni/include/legomain.h index c7126f85..a323cdf3 100644 --- a/LEGO1/lego/legoomni/include/legomain.h +++ b/LEGO1/lego/legoomni/include/legomain.h @@ -1,8 +1,10 @@ #ifndef LEGOMAIN_H #define LEGOMAIN_H +#include #include "compat.h" #include "lego1_export.h" +#include "legoutils.h" #include "mxdsaction.h" #include "mxomni.h" @@ -185,7 +187,14 @@ class LegoOmni : public MxOmni { MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) { return m_unk0x13c ? Start(&p_dsAction) : SUCCESS; } void SetUnknown13c(MxBool p_unk0x13c) { m_unk0x13c = p_unk0x13c; } - void CloseMainWindow() { PostMessageA(m_windowHandle, WM_CLOSE, 0, 0); } + void CloseMainWindow() { + SDL_Event event; + event.user.type = g_LegoSdlEvents.windows_message; + event.user.code = WM_CLOSE; + event.user.data1 = NULL; + event.user.data2 = NULL; + SDL_PushEvent(&event); + } // SYNTHETIC: LEGO1 0x10058b30 // LegoOmni::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoutils.h b/LEGO1/lego/legoomni/include/legoutils.h index ef816382..49a87543 100644 --- a/LEGO1/lego/legoomni/include/legoutils.h +++ b/LEGO1/lego/legoomni/include/legoutils.h @@ -4,8 +4,10 @@ #include "actionsfwd.h" #include "decomp.h" #include "extra.h" +#include "lego1_export.h" #include "mxtypes.h" +#include #include #define WM_ISLE_SETCURSOR 0x5400 @@ -13,6 +15,12 @@ // name verified by BETA10 0x100d4054 #define DS_NOT_A_STREAM -1 +struct LegoSdlEvents { + Uint32 windows_message; +}; + +LEGO1_EXPORT extern LegoSdlEvents g_LegoSdlEvents; + enum Cursor { e_cursorArrow = 0, e_cursorBusy, @@ -58,6 +66,7 @@ void PlayCamAnim(LegoPathActor* p_actor, MxBool p_unused, MxU32 p_location, MxBo void FUN_1003eda0(); MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id); void EnableAnimations(MxBool p_enable); +void InitSdlEvents(); void SetAppCursor(Cursor p_cursor); MxBool FUN_1003ef60(); MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_worldAtom, MxS32 p_worldEntityId); diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index 8230f4e2..978aa703 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -37,6 +37,8 @@ #include #include +LegoSdlEvents g_LegoSdlEvents; + // FUNCTION: LEGO1 0x1003dd70 // FUNCTION: BETA10 0x100d3410 LegoROI* PickROI(MxLong p_x, MxLong p_y) @@ -565,13 +567,20 @@ void EnableAnimations(MxBool p_enable) AnimationManager()->FUN_100604d0(p_enable); } +void InitSdlEvents() { + static bool initialized = false; + if (!initialized) { + initialized = true; + Uint32 event = SDL_RegisterEvents(1); + g_LegoSdlEvents.windows_message = event + 0; + } +} + // FUNCTION: LEGO1 0x1003ef40 void SetAppCursor(Cursor p_cursor) { - static Uint32 g_userEvent = SDL_RegisterEvents(1); - SDL_Event event; - event.user.type = g_userEvent; + event.user.type = g_LegoSdlEvents.windows_message; event.user.code = WM_ISLE_SETCURSOR; event.user.data1 = (void*) p_cursor; SDL_PushEvent(&event); diff --git a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp index c18367f5..e90be07d 100644 --- a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp +++ b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp @@ -518,7 +518,8 @@ MxBool LegoInputManager::FUN_1005cdf0(LegoEventNotificationParam& p_param) // FUNCTION: BETA10 0x10089fc5 void LegoInputManager::StartAutoDragTimer() { - m_autoDragTimerID = ::SetTimer(LegoOmni::GetInstance()->GetWindowHandle(), 1, m_autoDragTime, NULL); + HWND hWnd = (HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); + m_autoDragTimerID = ::SetTimer(hWnd, 1, m_autoDragTime, NULL); } // FUNCTION: LEGO1 0x1005cfd0 @@ -526,7 +527,8 @@ void LegoInputManager::StartAutoDragTimer() void LegoInputManager::StopAutoDragTimer() { if (m_autoDragTimerID) { - ::KillTimer(LegoOmni::GetInstance()->GetWindowHandle(), m_autoDragTimerID); + HWND hWnd = (HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); + ::KillTimer(hWnd, m_autoDragTimerID); } } diff --git a/LEGO1/lego/legoomni/src/main/legomain.cpp b/LEGO1/lego/legoomni/src/main/legomain.cpp index fe7fc015..a83a0989 100644 --- a/LEGO1/lego/legoomni/src/main/legomain.cpp +++ b/LEGO1/lego/legoomni/src/main/legomain.cpp @@ -160,6 +160,7 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param) { MxResult result = FAILURE; AUTOLOCK(m_criticalSection); + HWND hWnd = NULL; p_param.CreateFlags().CreateObjectFactory(FALSE); p_param.CreateFlags().CreateVideoManager(FALSE); @@ -191,7 +192,8 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param) goto done; } - if (!(m_inputManager = new LegoInputManager()) || m_inputManager->Create(p_param.GetWindowHandle()) != SUCCESS) { + hWnd = (HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); + if (!(m_inputManager = new LegoInputManager()) || m_inputManager->Create(hWnd) != SUCCESS) { delete m_inputManager; m_inputManager = NULL; goto done; @@ -260,6 +262,8 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param) SetAppCursor(e_cursorBusy); m_gameState->SetCurrentAct(LegoGameState::e_act1); + InitSdlEvents(); + result = SUCCESS; done: diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index fb7bd950..d9aa657a 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -85,7 +85,7 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM Mx3DPointFloat dirVec(0.0, 0.0, 1.0); Mx3DPointFloat upVec(0.0, 1.0, 0.0); MxMatrix outMatrix; - HWND hwnd = MxOmni::GetInstance()->GetWindowHandle(); + HWND hwnd = (HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); MxS32 bits = p_videoParam.Flags().Get16Bit() ? 16 : 8; if (!p_videoParam.GetPalette()) { @@ -176,7 +176,7 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM Lego3DManager::CreateStruct createStruct; memset(&createStruct, 0, sizeof(createStruct)); - createStruct.m_hWnd = LegoOmni::GetInstance()->GetWindowHandle(); + createStruct.m_hWnd = (HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); createStruct.m_pDirectDraw = m_pDirectDraw; createStruct.m_pFrontBuffer = m_displaySurface->GetDirectDrawSurface1(); createStruct.m_pBackBuffer = m_displaySurface->GetDirectDrawSurface2(); diff --git a/LEGO1/omni/include/mxomni.h b/LEGO1/omni/include/mxomni.h index 55fb4e21..ebc7b5d3 100644 --- a/LEGO1/omni/include/mxomni.h +++ b/LEGO1/omni/include/mxomni.h @@ -6,6 +6,7 @@ #include "mxcriticalsection.h" #include "mxstring.h" +#include #include class MxAtomSet; @@ -61,7 +62,9 @@ class MxOmni : public MxCore { static void SetInstance(MxOmni* p_instance); static MxBool ActionSourceEquals(MxDSAction* p_action, const char* p_name); - HWND GetWindowHandle() const { return this->m_windowHandle; } + SDL_Window* GetWindowHandle() const { + return m_windowHandle; + } // FUNCTION: BETA10 0x10125100 MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; } @@ -102,7 +105,7 @@ class MxOmni : public MxCore { static MxOmni* g_instance; MxString m_mediaPath; // 0x08 - HWND m_windowHandle; // 0x18 + SDL_Window* m_windowHandle; // 0x18 MxObjectFactory* m_objectFactory; // 0x1c MxVariableTable* m_variableTable; // 0x20 MxTickleManager* m_tickleManager; // 0x24 diff --git a/LEGO1/omni/include/mxomnicreateparam.h b/LEGO1/omni/include/mxomnicreateparam.h index 65a19fd6..7e83e419 100644 --- a/LEGO1/omni/include/mxomnicreateparam.h +++ b/LEGO1/omni/include/mxomnicreateparam.h @@ -7,7 +7,7 @@ #include "mxstring.h" #include "mxvideoparam.h" -#include +#include // VTABLE: LEGO1 0x100dc218 // VTABLE: BETA10 0x101c1ca8 @@ -15,7 +15,7 @@ class MxOmniCreateParam : public MxParam { public: LEGO1_EXPORT MxOmniCreateParam( const char* p_mediaPath, - HWND p_windowHandle, + SDL_Window* p_windowHandle, MxVideoParam& p_vparam, MxOmniCreateFlags p_flags ); @@ -24,7 +24,7 @@ class MxOmniCreateParam : public MxParam { MxOmniCreateFlags& CreateFlags() { return this->m_createFlags; } const MxString& GetMediaPath() const { return m_mediaPath; } - const HWND GetWindowHandle() const { return m_windowHandle; } + SDL_Window* GetWindowHandle() const { return m_windowHandle; } MxVideoParam& GetVideoParam() { return m_videoParam; } const MxVideoParam& GetVideoParam() const { return m_videoParam; } @@ -34,7 +34,7 @@ class MxOmniCreateParam : public MxParam { private: MxString m_mediaPath; // 0x04 - HWND m_windowHandle; // 0x14 + SDL_Window* m_windowHandle; // 0x14 MxVideoParam m_videoParam; // 0x18 MxOmniCreateFlags m_createFlags; // 0x3c }; diff --git a/LEGO1/omni/src/main/mxomnicreateparam.cpp b/LEGO1/omni/src/main/mxomnicreateparam.cpp index 88235330..37133217 100644 --- a/LEGO1/omni/src/main/mxomnicreateparam.cpp +++ b/LEGO1/omni/src/main/mxomnicreateparam.cpp @@ -8,7 +8,7 @@ DECOMP_SIZE_ASSERT(MxOmniCreateParam, 0x40) // FUNCTION: BETA10 0x10130b6b MxOmniCreateParam::MxOmniCreateParam( const char* p_mediaPath, - HWND p_windowHandle, + SDL_Window* p_windowHandle, MxVideoParam& p_vparam, MxOmniCreateFlags p_flags ) diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index 6a2baddf..cb9c09b6 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -139,7 +139,13 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam) DDSURFACEDESC ddsd; MxResult result = FAILURE; LPDIRECTDRAW lpDirectDraw = MVideoManager()->GetDirectDraw(); - HWND hWnd = MxOmni::GetInstance()->GetWindowHandle(); + SDL_Window* window = MxOmni::GetInstance()->GetWindowHandle(); + HWND hWnd = (HWND + ) SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); + + if (!hWnd) { + goto done; + } m_initialized = TRUE; m_videoParam = p_videoParam; @@ -842,7 +848,8 @@ void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p } else { MxPoint32 point(0, 0); - ClientToScreen(MxOmni::GetInstance()->GetWindowHandle(), (LPPOINT) &point); + HWND hWnd = (HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); + ClientToScreen(hWnd, (LPPOINT) &point); p_left2 += m_videoParam.GetRect().GetLeft() + point.GetX(); p_top2 += m_videoParam.GetRect().GetTop() + point.GetY(); diff --git a/LEGO1/omni/src/video/mxvideomanager.cpp b/LEGO1/omni/src/video/mxvideomanager.cpp index 9c99f944..3a17821e 100644 --- a/LEGO1/omni/src/video/mxvideomanager.cpp +++ b/LEGO1/omni/src/video/mxvideomanager.cpp @@ -216,6 +216,7 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, { MxBool locked = FALSE; MxResult status = FAILURE; + HWND hWnd = NULL; m_unk0x60 = TRUE; @@ -237,7 +238,8 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, goto done; } - if (m_pDirectDraw->SetCooperativeLevel(MxOmni::GetInstance()->GetWindowHandle(), DDSCL_NORMAL) != DD_OK) { + hWnd = (HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); + if (m_pDirectDraw->SetCooperativeLevel(hWnd, DDSCL_NORMAL) != DD_OK) { goto done; } diff --git a/util/compat.h b/util/compat.h index ea2a6507..db768dda 100644 --- a/util/compat.h +++ b/util/compat.h @@ -3,7 +3,7 @@ // Various macros to enable compiling with other/newer compilers. -#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER >= 1100) +#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER >= 1100) || !defined(_WIN32) #define COMPAT_MODE #endif