Skip to content

Commit

Permalink
More use of SDL (#47)
Browse files Browse the repository at this point in the history
* Use SDL_GetPerformance(Counter|Frequency) in MxStopWatch

* Fix flic.h for gcc Linux compiler

* cmake: remove left-over message

* Replace some more stricmp with SDL_strcasecmp

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

* clang-format

* Use SDL_Timer for unknown input dragging events

* Fix naming

---------

Co-authored-by: Christian Semmler <[email protected]>
  • Loading branch information
madebr and foxtacles authored Dec 27, 2024
1 parent d3cdec8 commit 65adfe7
Show file tree
Hide file tree
Showing 20 changed files with 148 additions and 74 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,6 @@ endif()
set(lego1_objects)
set(lego1_link_libraries dxguid d3drm_guid)
foreach(lego1_library IN LISTS lego1_targets)
message("lego1_library:${lego1_library}")
target_compile_definitions(${lego1_library}-objects PRIVATE LEGO1_DLL)
list(APPEND lego1_objects $<TARGET_OBJECTS:${lego1_library}-objects>)
list(APPEND lego1_link_libraries ${lego1_library}-interface)
Expand Down
23 changes: 15 additions & 8 deletions ISLE/isleapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,18 +178,15 @@ 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) {
Expand Down Expand Up @@ -392,12 +389,22 @@ 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.m_windowsMessage) {
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;
case WM_TIMER:
if (InputManager()) {
InputManager()->QueueEvent(c_notificationTimer, (MxU8) (uintptr_t) event->user.data1, 0, 0, 0);
}
break;
default:
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unknown SDL Windows message: 0x%" SDL_PRIx32, event->user.code);
break;
}
}

Expand Down
3 changes: 2 additions & 1 deletion LEGO1/lego/legoomni/include/legoinputmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <SDL3/SDL_joystick.h>
#include <SDL3/SDL_keyboard.h>
#include <SDL3/SDL_timer.h>
#include <windows.h>

class LegoCameraController;
Expand Down Expand Up @@ -145,7 +146,7 @@ class LegoInputManager : public MxPresenter {
MxS32 m_x; // 0x6c
MxS32 m_y; // 0x70
MxS32 m_unk0x74; // 0x74
UINT m_autoDragTimerID; // 0x78
SDL_TimerID m_autoDragTimerID; // 0x78
UINT m_autoDragTime; // 0x7c
MxBool m_unk0x80; // 0x80
MxBool m_unk0x81; // 0x81
Expand Down
13 changes: 12 additions & 1 deletion LEGO1/lego/legoomni/include/legomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@

#include "compat.h"
#include "lego1_export.h"
#include "legoutils.h"
#include "mxdsaction.h"
#include "mxomni.h"

#include <SDL3/SDL_events.h>

class Isle;
class LegoAnimationManager;
class LegoBuildingManager;
Expand Down Expand Up @@ -185,7 +188,15 @@ 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.m_windowsMessage;
event.user.code = WM_CLOSE;
event.user.data1 = NULL;
event.user.data2 = NULL;
SDL_PushEvent(&event);
}

// SYNTHETIC: LEGO1 0x10058b30
// LegoOmni::`scalar deleting destructor'
Expand Down
9 changes: 9 additions & 0 deletions LEGO1/lego/legoomni/include/legoutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@
#include "actionsfwd.h"
#include "decomp.h"
#include "extra.h"
#include "lego1_export.h"
#include "mxtypes.h"

#include <SDL3/SDL_stdinc.h>
#include <windows.h>

#define WM_ISLE_SETCURSOR 0x5400

// name verified by BETA10 0x100d4054
#define DS_NOT_A_STREAM -1

struct LegoSdlEvents {
Uint32 m_windowsMessage;
};

LEGO1_EXPORT extern LegoSdlEvents g_legoSdlEvents;

enum Cursor {
e_cursorArrow = 0,
e_cursorBusy,
Expand Down Expand Up @@ -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);
Expand Down
12 changes: 6 additions & 6 deletions LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ inline void LegoCarBuildAnimPresenter::Beta10Inline0x100733d0()
if (roi) {
const LegoChar* name = roi->GetName();

if (name && stricmp(wiredName, name) == 0) {
if (name && SDL_strcasecmp(wiredName, name) == 0) {
if (bvar5) {
roi->SetVisibility(TRUE);
}
Expand Down Expand Up @@ -310,7 +310,7 @@ void LegoCarBuildAnimPresenter::SwapNodesByName(LegoChar* p_name1, LegoChar* p_n
{
char buffer[40];

if (stricmp(p_name1, p_name2) != 0) {
if (SDL_strcasecmp(p_name1, p_name2) != 0) {
LegoAnimNodeData* node1 = FindNodeDataByName(m_anim->GetRoot(), p_name1);
LegoAnimNodeData* node2 = FindNodeDataByName(m_anim->GetRoot(), p_name2);

Expand Down Expand Up @@ -468,7 +468,7 @@ LegoAnimNodeData* LegoCarBuildAnimPresenter::FindNodeDataByName(LegoTreeNode* p_
if (p_treeNode) {
data = (LegoAnimNodeData*) p_treeNode->GetData();

if (stricmp(data->GetName(), p_name) == 0) {
if (SDL_strcasecmp(data->GetName(), p_name) == 0) {
return data;
}

Expand All @@ -494,7 +494,7 @@ LegoTreeNode* LegoCarBuildAnimPresenter::FindNodeByName(LegoTreeNode* p_treeNode
if (p_treeNode) {
data = (LegoAnimNodeData*) p_treeNode->GetData();

if (stricmp(data->GetName(), p_name) == 0) {
if (SDL_strcasecmp(data->GetName(), p_name) == 0) {
return p_treeNode;
}

Expand All @@ -519,7 +519,7 @@ void LegoCarBuildAnimPresenter::FUN_10079790(const LegoChar* p_name)

if (SDL_strcasecmp(m_parts[m_placedPartCount].m_name, p_name) != 0) {
for (i = m_placedPartCount + 1; i < m_numberOfParts; i++) {
if (stricmp(m_parts[i].m_name, p_name) == 0) {
if (SDL_strcasecmp(m_parts[i].m_name, p_name) == 0) {
break;
}
}
Expand Down Expand Up @@ -595,7 +595,7 @@ void LegoCarBuildAnimPresenter::FUN_10079a90()
// FUNCTION: BETA10 0x100724fa
MxBool LegoCarBuildAnimPresenter::StringEqualsPlatform(const LegoChar* p_string)
{
return stricmp(p_string, "PLATFORM") == 0;
return SDL_strcasecmp(p_string, "PLATFORM") == 0;
}

// FUNCTION: LEGO1 0x10079b40
Expand Down
2 changes: 1 addition & 1 deletion LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ void LegoAnimationManager::FUN_10060480(const LegoChar* p_characterNames[], MxU3
{
for (MxS32 i = 0; i < p_numCharacterNames; i++) {
for (MxS32 j = 0; j < sizeOfArray(g_characters); j++) {
if (!stricmp(g_characters[j].m_name, p_characterNames[i])) {
if (!SDL_strcasecmp(g_characters[j].m_name, p_characterNames[i])) {
g_characters[j].m_unk0x08 = TRUE;
}
}
Expand Down
17 changes: 14 additions & 3 deletions LEGO1/lego/legoomni/src/common/legoutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#include <string.h>
#include <vec.h>

LegoSdlEvents g_legoSdlEvents;

// FUNCTION: LEGO1 0x1003dd70
// FUNCTION: BETA10 0x100d3410
LegoROI* PickROI(MxLong p_x, MxLong p_y)
Expand Down Expand Up @@ -565,13 +567,22 @@ void EnableAnimations(MxBool p_enable)
AnimationManager()->FUN_100604d0(p_enable);
}

void InitSdlEvents()
{
static bool g_initialized = false;

if (!g_initialized) {
g_initialized = true;
Uint32 event = SDL_RegisterEvents(1);
g_legoSdlEvents.m_windowsMessage = 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.m_windowsMessage;
event.user.code = WM_ISLE_SETCURSOR;
event.user.data1 = (void*) p_cursor;
SDL_PushEvent(&event);
Expand Down
3 changes: 2 additions & 1 deletion LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "mxmisc.h"
#include "mxvariabletable.h"

#include <SDL3/SDL_stdinc.h>
#include <vec.h>

DECOMP_SIZE_ASSERT(LegoJetskiRaceActor, 0x1a8)
Expand Down Expand Up @@ -123,7 +124,7 @@ void LegoJetskiRaceActor::Animate(float p_time)
{
if (m_unk0x0c == 0) {
const LegoChar* raceState = VariableTable()->GetVariable(g_raceState);
if (!stricmp(raceState, g_racing)) {
if (!SDL_strcasecmp(raceState, g_racing)) {
m_unk0x0c = 1;
m_lastTime = p_time - 1.0f;
m_unk0x1c = p_time;
Expand Down
16 changes: 14 additions & 2 deletions LEGO1/lego/legoomni/src/input/legoinputmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,19 +514,31 @@ MxBool LegoInputManager::FUN_1005cdf0(LegoEventNotificationParam& p_param)
return result;
}

static Uint32 SDLCALL LegoInputManagerTimerCallback(void* userdata, SDL_TimerID timerID, Uint32 interval)
{
LegoInputManager* inputManager = (LegoInputManager*) userdata;
SDL_Event event;
event.type = g_legoSdlEvents.m_windowsMessage;
event.user.code = WM_TIMER;
event.user.data1 = (void*) (uintptr_t) timerID;
event.user.data2 = NULL;
return interval;
}

// FUNCTION: LEGO1 0x1005cfb0
// FUNCTION: BETA10 0x10089fc5
void LegoInputManager::StartAutoDragTimer()
{
m_autoDragTimerID = ::SetTimer(LegoOmni::GetInstance()->GetWindowHandle(), 1, m_autoDragTime, NULL);
m_autoDragTimerID = SDL_AddTimer(m_autoDragTime, LegoInputManagerTimerCallback, this);
}

// FUNCTION: LEGO1 0x1005cfd0
// FUNCTION: BETA10 0x1008a005
void LegoInputManager::StopAutoDragTimer()
{
if (m_autoDragTimerID) {
::KillTimer(LegoOmni::GetInstance()->GetWindowHandle(), m_autoDragTimerID);
SDL_RemoveTimer(m_autoDragTimerID);
m_autoDragTimerID = 0;
}
}

Expand Down
11 changes: 10 additions & 1 deletion LEGO1/lego/legoomni/src/main/legomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -191,7 +192,13 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
goto done;
}

if (!(m_inputManager = new LegoInputManager()) || m_inputManager->Create(p_param.GetWindowHandle()) != SUCCESS) {
// [library:dinput]
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;
Expand Down Expand Up @@ -260,6 +267,8 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
SetAppCursor(e_cursorBusy);
m_gameState->SetCurrentAct(LegoGameState::e_act1);

InitSdlEvents();

result = SUCCESS;

done:
Expand Down
13 changes: 11 additions & 2 deletions LEGO1/lego/legoomni/src/video/legovideomanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ 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();
// [library:ddraw] [library:d3d]
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()) {
Expand Down Expand Up @@ -176,7 +181,11 @@ 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();
Expand Down
Loading

0 comments on commit 65adfe7

Please sign in to comment.