Pass SDL_Window* to LEGO1.DLL, and pass window events through SDL event handler

This commit is contained in:
Anonymous Maarten 2024-12-26 23:45:23 +01:00
parent a2a6e52feb
commit f58d4e45e9
13 changed files with 74 additions and 28 deletions

View File

@ -178,18 +178,14 @@ MxS32 IsleApp::SetupLegoOmni()
char mediaPath[256]; char mediaPath[256];
GetProfileStringA("LEGO Island", "MediaPath", "", mediaPath, sizeof(mediaPath)); 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 #ifdef COMPAT_MODE
MxS32 failure; MxS32 failure;
{ {
MxOmniCreateParam param(mediaPath, hwnd, m_videoParam, MxOmniCreateFlags()); MxOmniCreateParam param(mediaPath, m_windowHandle, m_videoParam, MxOmniCreateFlags());
failure = Lego()->Create(param) == FAILURE; failure = Lego()->Create(param) == FAILURE;
} }
#else #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 #endif
if (!failure) { if (!failure) {
@ -392,12 +388,17 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
break; break;
} }
// FIXME: use g_userEvent instead of SDL_EVENT_USER if (event->user.type == g_LegoSdlEvents.windows_message) {
if (event->type >= SDL_EVENT_USER && event->type <= SDL_EVENT_LAST - 1) {
switch (event->user.code) { switch (event->user.code) {
case WM_ISLE_SETCURSOR: case WM_ISLE_SETCURSOR:
g_isle->SetupCursor((Cursor) (uintptr_t) event->user.data1); g_isle->SetupCursor((Cursor) (uintptr_t) event->user.data1);
break; 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;
} }
} }

View File

@ -1,8 +1,10 @@
#ifndef LEGOMAIN_H #ifndef LEGOMAIN_H
#define LEGOMAIN_H #define LEGOMAIN_H
#include <SDL3/SDL_events.h>
#include "compat.h" #include "compat.h"
#include "lego1_export.h" #include "lego1_export.h"
#include "legoutils.h"
#include "mxdsaction.h" #include "mxdsaction.h"
#include "mxomni.h" #include "mxomni.h"
@ -185,7 +187,14 @@ class LegoOmni : public MxOmni {
MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) { return m_unk0x13c ? Start(&p_dsAction) : SUCCESS; } MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) { return m_unk0x13c ? Start(&p_dsAction) : SUCCESS; }
void SetUnknown13c(MxBool p_unk0x13c) { m_unk0x13c = p_unk0x13c; } 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 // SYNTHETIC: LEGO1 0x10058b30
// LegoOmni::`scalar deleting destructor' // LegoOmni::`scalar deleting destructor'

View File

@ -4,8 +4,10 @@
#include "actionsfwd.h" #include "actionsfwd.h"
#include "decomp.h" #include "decomp.h"
#include "extra.h" #include "extra.h"
#include "lego1_export.h"
#include "mxtypes.h" #include "mxtypes.h"
#include <SDL3/SDL_stdinc.h>
#include <windows.h> #include <windows.h>
#define WM_ISLE_SETCURSOR 0x5400 #define WM_ISLE_SETCURSOR 0x5400
@ -13,6 +15,12 @@
// name verified by BETA10 0x100d4054 // name verified by BETA10 0x100d4054
#define DS_NOT_A_STREAM -1 #define DS_NOT_A_STREAM -1
struct LegoSdlEvents {
Uint32 windows_message;
};
LEGO1_EXPORT extern LegoSdlEvents g_LegoSdlEvents;
enum Cursor { enum Cursor {
e_cursorArrow = 0, e_cursorArrow = 0,
e_cursorBusy, e_cursorBusy,
@ -58,6 +66,7 @@ void PlayCamAnim(LegoPathActor* p_actor, MxBool p_unused, MxU32 p_location, MxBo
void FUN_1003eda0(); void FUN_1003eda0();
MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id); MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id);
void EnableAnimations(MxBool p_enable); void EnableAnimations(MxBool p_enable);
void InitSdlEvents();
void SetAppCursor(Cursor p_cursor); void SetAppCursor(Cursor p_cursor);
MxBool FUN_1003ef60(); MxBool FUN_1003ef60();
MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_worldAtom, MxS32 p_worldEntityId); MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_worldAtom, MxS32 p_worldEntityId);

View File

@ -37,6 +37,8 @@
#include <string.h> #include <string.h>
#include <vec.h> #include <vec.h>
LegoSdlEvents g_LegoSdlEvents;
// FUNCTION: LEGO1 0x1003dd70 // FUNCTION: LEGO1 0x1003dd70
// FUNCTION: BETA10 0x100d3410 // FUNCTION: BETA10 0x100d3410
LegoROI* PickROI(MxLong p_x, MxLong p_y) LegoROI* PickROI(MxLong p_x, MxLong p_y)
@ -565,13 +567,20 @@ void EnableAnimations(MxBool p_enable)
AnimationManager()->FUN_100604d0(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 // FUNCTION: LEGO1 0x1003ef40
void SetAppCursor(Cursor p_cursor) void SetAppCursor(Cursor p_cursor)
{ {
static Uint32 g_userEvent = SDL_RegisterEvents(1);
SDL_Event event; SDL_Event event;
event.user.type = g_userEvent; event.user.type = g_LegoSdlEvents.windows_message;
event.user.code = WM_ISLE_SETCURSOR; event.user.code = WM_ISLE_SETCURSOR;
event.user.data1 = (void*) p_cursor; event.user.data1 = (void*) p_cursor;
SDL_PushEvent(&event); SDL_PushEvent(&event);

View File

@ -518,7 +518,8 @@ MxBool LegoInputManager::FUN_1005cdf0(LegoEventNotificationParam& p_param)
// FUNCTION: BETA10 0x10089fc5 // FUNCTION: BETA10 0x10089fc5
void LegoInputManager::StartAutoDragTimer() 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 // FUNCTION: LEGO1 0x1005cfd0
@ -526,7 +527,8 @@ void LegoInputManager::StartAutoDragTimer()
void LegoInputManager::StopAutoDragTimer() void LegoInputManager::StopAutoDragTimer()
{ {
if (m_autoDragTimerID) { 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);
} }
} }

View File

@ -160,6 +160,7 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
{ {
MxResult result = FAILURE; MxResult result = FAILURE;
AUTOLOCK(m_criticalSection); AUTOLOCK(m_criticalSection);
HWND hWnd = NULL;
p_param.CreateFlags().CreateObjectFactory(FALSE); p_param.CreateFlags().CreateObjectFactory(FALSE);
p_param.CreateFlags().CreateVideoManager(FALSE); p_param.CreateFlags().CreateVideoManager(FALSE);
@ -191,7 +192,8 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
goto done; 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; delete m_inputManager;
m_inputManager = NULL; m_inputManager = NULL;
goto done; goto done;
@ -260,6 +262,8 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
SetAppCursor(e_cursorBusy); SetAppCursor(e_cursorBusy);
m_gameState->SetCurrentAct(LegoGameState::e_act1); m_gameState->SetCurrentAct(LegoGameState::e_act1);
InitSdlEvents();
result = SUCCESS; result = SUCCESS;
done: done:

View File

@ -85,7 +85,7 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM
Mx3DPointFloat dirVec(0.0, 0.0, 1.0); Mx3DPointFloat dirVec(0.0, 0.0, 1.0);
Mx3DPointFloat upVec(0.0, 1.0, 0.0); Mx3DPointFloat upVec(0.0, 1.0, 0.0);
MxMatrix outMatrix; 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; MxS32 bits = p_videoParam.Flags().Get16Bit() ? 16 : 8;
if (!p_videoParam.GetPalette()) { if (!p_videoParam.GetPalette()) {
@ -176,7 +176,7 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM
Lego3DManager::CreateStruct createStruct; Lego3DManager::CreateStruct createStruct;
memset(&createStruct, 0, sizeof(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_pDirectDraw = m_pDirectDraw;
createStruct.m_pFrontBuffer = m_displaySurface->GetDirectDrawSurface1(); createStruct.m_pFrontBuffer = m_displaySurface->GetDirectDrawSurface1();
createStruct.m_pBackBuffer = m_displaySurface->GetDirectDrawSurface2(); createStruct.m_pBackBuffer = m_displaySurface->GetDirectDrawSurface2();

View File

@ -6,6 +6,7 @@
#include "mxcriticalsection.h" #include "mxcriticalsection.h"
#include "mxstring.h" #include "mxstring.h"
#include <SDL3/SDL_video.h>
#include <windows.h> #include <windows.h>
class MxAtomSet; class MxAtomSet;
@ -61,7 +62,9 @@ class MxOmni : public MxCore {
static void SetInstance(MxOmni* p_instance); static void SetInstance(MxOmni* p_instance);
static MxBool ActionSourceEquals(MxDSAction* p_action, const char* p_name); 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 // FUNCTION: BETA10 0x10125100
MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; } MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; }
@ -102,7 +105,7 @@ class MxOmni : public MxCore {
static MxOmni* g_instance; static MxOmni* g_instance;
MxString m_mediaPath; // 0x08 MxString m_mediaPath; // 0x08
HWND m_windowHandle; // 0x18 SDL_Window* m_windowHandle; // 0x18
MxObjectFactory* m_objectFactory; // 0x1c MxObjectFactory* m_objectFactory; // 0x1c
MxVariableTable* m_variableTable; // 0x20 MxVariableTable* m_variableTable; // 0x20
MxTickleManager* m_tickleManager; // 0x24 MxTickleManager* m_tickleManager; // 0x24

View File

@ -7,7 +7,7 @@
#include "mxstring.h" #include "mxstring.h"
#include "mxvideoparam.h" #include "mxvideoparam.h"
#include <windows.h> #include <SDL3/SDL_video.h>
// VTABLE: LEGO1 0x100dc218 // VTABLE: LEGO1 0x100dc218
// VTABLE: BETA10 0x101c1ca8 // VTABLE: BETA10 0x101c1ca8
@ -15,7 +15,7 @@ class MxOmniCreateParam : public MxParam {
public: public:
LEGO1_EXPORT MxOmniCreateParam( LEGO1_EXPORT MxOmniCreateParam(
const char* p_mediaPath, const char* p_mediaPath,
HWND p_windowHandle, SDL_Window* p_windowHandle,
MxVideoParam& p_vparam, MxVideoParam& p_vparam,
MxOmniCreateFlags p_flags MxOmniCreateFlags p_flags
); );
@ -24,7 +24,7 @@ class MxOmniCreateParam : public MxParam {
MxOmniCreateFlags& CreateFlags() { return this->m_createFlags; } MxOmniCreateFlags& CreateFlags() { return this->m_createFlags; }
const MxString& GetMediaPath() const { return m_mediaPath; } 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; } MxVideoParam& GetVideoParam() { return m_videoParam; }
const MxVideoParam& GetVideoParam() const { return m_videoParam; } const MxVideoParam& GetVideoParam() const { return m_videoParam; }
@ -34,7 +34,7 @@ class MxOmniCreateParam : public MxParam {
private: private:
MxString m_mediaPath; // 0x04 MxString m_mediaPath; // 0x04
HWND m_windowHandle; // 0x14 SDL_Window* m_windowHandle; // 0x14
MxVideoParam m_videoParam; // 0x18 MxVideoParam m_videoParam; // 0x18
MxOmniCreateFlags m_createFlags; // 0x3c MxOmniCreateFlags m_createFlags; // 0x3c
}; };

View File

@ -8,7 +8,7 @@ DECOMP_SIZE_ASSERT(MxOmniCreateParam, 0x40)
// FUNCTION: BETA10 0x10130b6b // FUNCTION: BETA10 0x10130b6b
MxOmniCreateParam::MxOmniCreateParam( MxOmniCreateParam::MxOmniCreateParam(
const char* p_mediaPath, const char* p_mediaPath,
HWND p_windowHandle, SDL_Window* p_windowHandle,
MxVideoParam& p_vparam, MxVideoParam& p_vparam,
MxOmniCreateFlags p_flags MxOmniCreateFlags p_flags
) )

View File

@ -139,7 +139,13 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam)
DDSURFACEDESC ddsd; DDSURFACEDESC ddsd;
MxResult result = FAILURE; MxResult result = FAILURE;
LPDIRECTDRAW lpDirectDraw = MVideoManager()->GetDirectDraw(); 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_initialized = TRUE;
m_videoParam = p_videoParam; m_videoParam = p_videoParam;
@ -842,7 +848,8 @@ void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p
} }
else { else {
MxPoint32 point(0, 0); 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_left2 += m_videoParam.GetRect().GetLeft() + point.GetX();
p_top2 += m_videoParam.GetRect().GetTop() + point.GetY(); p_top2 += m_videoParam.GetRect().GetTop() + point.GetY();

View File

@ -216,6 +216,7 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS,
{ {
MxBool locked = FALSE; MxBool locked = FALSE;
MxResult status = FAILURE; MxResult status = FAILURE;
HWND hWnd = NULL;
m_unk0x60 = TRUE; m_unk0x60 = TRUE;
@ -237,7 +238,8 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS,
goto done; 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; goto done;
} }

View File

@ -3,7 +3,7 @@
// Various macros to enable compiling with other/newer compilers. // 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 #define COMPAT_MODE
#endif #endif