mirror of
https://github.com/isledecomp/isle-portable.git
synced 2025-09-27 14:42:51 -04:00
Use SDL window instead of Win32 window (#12)
* Use SDL window * Fixes * Update README * Remove unused decl * Consistent use * Add comment about fullscreen
This commit is contained in:
parent
3190a6c23a
commit
65036e1a36
478
ISLE/isleapp.cpp
478
ISLE/isleapp.cpp
@ -22,6 +22,7 @@
|
|||||||
#include "mxticklemanager.h"
|
#include "mxticklemanager.h"
|
||||||
#include "mxtimer.h"
|
#include "mxtimer.h"
|
||||||
#include "mxtransitionmanager.h"
|
#include "mxtransitionmanager.h"
|
||||||
|
#include "mxutilities.h"
|
||||||
#include "mxvariabletable.h"
|
#include "mxvariabletable.h"
|
||||||
#include "res/resource.h"
|
#include "res/resource.h"
|
||||||
#include "roi/legoroi.h"
|
#include "roi/legoroi.h"
|
||||||
@ -31,8 +32,10 @@
|
|||||||
#include <SDL3/SDL_filesystem.h>
|
#include <SDL3/SDL_filesystem.h>
|
||||||
#include <SDL3/SDL_init.h>
|
#include <SDL3/SDL_init.h>
|
||||||
#include <SDL3/SDL_main.h>
|
#include <SDL3/SDL_main.h>
|
||||||
|
#include <SDL3/SDL_messagebox.h>
|
||||||
#include <dsound.h>
|
#include <dsound.h>
|
||||||
#include <iniparser.h>
|
#include <iniparser.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(IsleApp, 0x8c)
|
DECOMP_SIZE_ASSERT(IsleApp, 0x8c)
|
||||||
|
|
||||||
@ -40,10 +43,10 @@ DECOMP_SIZE_ASSERT(IsleApp, 0x8c)
|
|||||||
IsleApp* g_isle = NULL;
|
IsleApp* g_isle = NULL;
|
||||||
|
|
||||||
// GLOBAL: ISLE 0x410034
|
// GLOBAL: ISLE 0x410034
|
||||||
unsigned char g_mousedown = 0;
|
unsigned char g_mousedown = FALSE;
|
||||||
|
|
||||||
// GLOBAL: ISLE 0x410038
|
// GLOBAL: ISLE 0x410038
|
||||||
unsigned char g_mousemoved = 0;
|
unsigned char g_mousemoved = FALSE;
|
||||||
|
|
||||||
// GLOBAL: ISLE 0x41003c
|
// GLOBAL: ISLE 0x41003c
|
||||||
BOOL g_closed = FALSE;
|
BOOL g_closed = FALSE;
|
||||||
@ -69,15 +72,8 @@ int g_targetDepth = 16;
|
|||||||
// GLOBAL: ISLE 0x410064
|
// GLOBAL: ISLE 0x410064
|
||||||
BOOL g_reqEnableRMDevice = FALSE;
|
BOOL g_reqEnableRMDevice = FALSE;
|
||||||
|
|
||||||
// STRING: ISLE 0x4101c4
|
|
||||||
#define WNDCLASS_NAME "Lego Island MainNoM App"
|
|
||||||
|
|
||||||
// STRING: ISLE 0x4101dc
|
// STRING: ISLE 0x4101dc
|
||||||
#define WINDOW_TITLE "LEGO\xAE"
|
#define WINDOW_TITLE "LEGO®"
|
||||||
|
|
||||||
// Might be static functions of IsleApp
|
|
||||||
BOOL FindExistingInstance();
|
|
||||||
BOOL StartDirectSound();
|
|
||||||
|
|
||||||
// FUNCTION: ISLE 0x401000
|
// FUNCTION: ISLE 0x401000
|
||||||
IsleApp::IsleApp()
|
IsleApp::IsleApp()
|
||||||
@ -191,16 +187,19 @@ BOOL 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_GetProperty(SDL_GetWindowProperties(m_windowHandle), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
|
||||||
|
|
||||||
#ifdef COMPAT_MODE
|
#ifdef COMPAT_MODE
|
||||||
BOOL failure;
|
BOOL failure;
|
||||||
{
|
{
|
||||||
MxOmniCreateParam param(mediaPath, (struct HWND__*) m_windowHandle, m_videoParam, MxOmniCreateFlags());
|
MxOmniCreateParam param(mediaPath, (struct HWND__*) hwnd, m_videoParam, MxOmniCreateFlags());
|
||||||
failure = Lego()->Create(param) == FAILURE;
|
failure = Lego()->Create(param) == FAILURE;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
BOOL failure =
|
BOOL failure = Lego()->Create(MxOmniCreateParam(mediaPath, (struct HWND__*) hwnd, m_videoParam, MxOmniCreateFlags())
|
||||||
Lego()->Create(MxOmniCreateParam(mediaPath, (struct HWND__*) m_windowHandle, m_videoParam, MxOmniCreateFlags())
|
) == FAILURE;
|
||||||
) == FAILURE;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!failure) {
|
if (!failure) {
|
||||||
@ -244,45 +243,29 @@ void IsleApp::SetupVideoFlags(
|
|||||||
int SDL_AppInit(void** appstate, int argc, char** argv)
|
int SDL_AppInit(void** appstate, int argc, char** argv)
|
||||||
{
|
{
|
||||||
// Add subsystems as necessary later
|
// Add subsystems as necessary later
|
||||||
SDL_Init(SDL_INIT_TIMER);
|
if (SDL_Init(SDL_INIT_VIDEO) != 0 || SDL_Init(SDL_INIT_TIMER) != 0) {
|
||||||
|
SDL_ShowSimpleMessageBox(
|
||||||
// Look for another instance, if we find one, bring it to the foreground instead
|
SDL_MESSAGEBOX_ERROR,
|
||||||
if (!FindExistingInstance()) {
|
"LEGO® Island Error",
|
||||||
return 1;
|
"\"LEGO® Island\" failed to start. Please quit all other applications and try again.",
|
||||||
}
|
NULL
|
||||||
|
|
||||||
// Attempt to create DirectSound instance
|
|
||||||
BOOL soundReady = FALSE;
|
|
||||||
for (int i = 0; i < 20; i++) {
|
|
||||||
if (StartDirectSound()) {
|
|
||||||
soundReady = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Sleep(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Throw error if sound unavailable
|
|
||||||
if (!soundReady) {
|
|
||||||
MessageBoxA(
|
|
||||||
NULL,
|
|
||||||
"\"LEGO\xAE Island\" is not detecting a DirectSound compatible sound card. Please quit all other "
|
|
||||||
"applications and try again.",
|
|
||||||
"Lego Island Error",
|
|
||||||
MB_OK
|
|
||||||
);
|
);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [library:window]
|
||||||
|
// Original game checks for an existing instance here.
|
||||||
|
// We don't really need that.
|
||||||
|
|
||||||
// Create global app instance
|
// Create global app instance
|
||||||
g_isle = new IsleApp();
|
g_isle = new IsleApp();
|
||||||
|
|
||||||
// Create window
|
// Create window
|
||||||
if (g_isle->SetupWindow(GetModuleHandle(NULL), NULL) != SUCCESS) {
|
if (g_isle->SetupWindow() != SUCCESS) {
|
||||||
MessageBoxA(
|
SDL_ShowSimpleMessageBox(
|
||||||
NULL,
|
SDL_MESSAGEBOX_ERROR,
|
||||||
"\"LEGO\xAE Island\" failed to start. Please quit all other applications and try again.",
|
"LEGO® Island Error",
|
||||||
"LEGO\xAE Island Error",
|
"\"LEGO® Island\" failed to start. Please quit all other applications and try again.",
|
||||||
MB_OK
|
NULL
|
||||||
);
|
);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -294,34 +277,13 @@ int SDL_AppInit(void** appstate, int argc, char** argv)
|
|||||||
|
|
||||||
int SDL_AppIterate(void* appstate)
|
int SDL_AppIterate(void* appstate)
|
||||||
{
|
{
|
||||||
MSG msg;
|
|
||||||
|
|
||||||
if (g_closed) {
|
if (g_closed) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE)) {
|
g_isle->Tick(0);
|
||||||
if (g_isle) {
|
|
||||||
g_isle->Tick(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_isle) {
|
|
||||||
g_isle->Tick(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!g_closed) {
|
|
||||||
if (!PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSG nextMsg;
|
|
||||||
if (!g_isle || !g_isle->GetWindowHandle() || msg.message != WM_MOUSEMOVE ||
|
|
||||||
!PeekMessageA(&nextMsg, NULL, 0, 0, PM_NOREMOVE) || nextMsg.message != WM_MOUSEMOVE) {
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessageA(&msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!g_closed) {
|
||||||
if (g_reqEnableRMDevice) {
|
if (g_reqEnableRMDevice) {
|
||||||
g_reqEnableRMDevice = FALSE;
|
g_reqEnableRMDevice = FALSE;
|
||||||
VideoManager()->EnableRMDevice();
|
VideoManager()->EnableRMDevice();
|
||||||
@ -347,222 +309,119 @@ int SDL_AppIterate(void* appstate)
|
|||||||
|
|
||||||
int SDL_AppEvent(void* appstate, const SDL_Event* event)
|
int SDL_AppEvent(void* appstate, const SDL_Event* event)
|
||||||
{
|
{
|
||||||
// Process events here once we use SDL window
|
if (!g_isle) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [library:window] 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:
|
||||||
|
g_isle->SetWindowActive(TRUE);
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||||
|
g_isle->SetWindowActive(FALSE);
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
|
||||||
|
if (!g_closed) {
|
||||||
|
delete g_isle;
|
||||||
|
g_isle = NULL;
|
||||||
|
g_closed = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_KEY_DOWN: {
|
||||||
|
if (event->key.repeat) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Keycode keyCode = event->key.keysym.sym;
|
||||||
|
if (InputManager()) {
|
||||||
|
InputManager()->QueueEvent(c_notificationKeyPress, keyCode, 0, 0, keyCode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_MOUSE_MOTION:
|
||||||
|
g_mousemoved = TRUE;
|
||||||
|
|
||||||
|
if (InputManager()) {
|
||||||
|
InputManager()->QueueEvent(
|
||||||
|
c_notificationMouseMove,
|
||||||
|
IsleApp::MapMouseButtonFlagsToModifier(event->motion.state),
|
||||||
|
event->motion.x,
|
||||||
|
event->motion.y,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_isle->GetDrawCursor()) {
|
||||||
|
VideoManager()->MoveCursor(Min((int) event->motion.x, 639), Min((int) event->motion.y, 479));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
|
g_mousedown = TRUE;
|
||||||
|
|
||||||
|
if (InputManager()) {
|
||||||
|
InputManager()->QueueEvent(
|
||||||
|
c_notificationButtonDown,
|
||||||
|
IsleApp::MapMouseButtonFlagsToModifier(SDL_GetMouseState(NULL, NULL)),
|
||||||
|
event->button.x,
|
||||||
|
event->button.y,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||||
|
g_mousedown = FALSE;
|
||||||
|
|
||||||
|
if (InputManager()) {
|
||||||
|
InputManager()->QueueEvent(
|
||||||
|
c_notificationButtonUp,
|
||||||
|
IsleApp::MapMouseButtonFlagsToModifier(SDL_GetMouseState(NULL, NULL)),
|
||||||
|
event->button.x,
|
||||||
|
event->button.y,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_AppQuit(void* appstate)
|
void SDL_AppQuit(void* appstate)
|
||||||
{
|
{
|
||||||
DestroyWindow((HWND) appstate);
|
if (appstate != NULL) {
|
||||||
|
SDL_DestroyWindow((SDL_Window*) appstate);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: ISLE 0x401ca0
|
MxU8 IsleApp::MapMouseButtonFlagsToModifier(SDL_MouseButtonFlags p_flags)
|
||||||
BOOL FindExistingInstance()
|
|
||||||
{
|
{
|
||||||
HWND hWnd = FindWindowA(WNDCLASS_NAME, WINDOW_TITLE);
|
// [library:window]
|
||||||
if (hWnd) {
|
// Map button states to Windows button states (LegoEventNotificationParam)
|
||||||
if (SetForegroundWindow(hWnd)) {
|
// Not mapping mod keys SHIFT and CTRL since they are not used by the game.
|
||||||
ShowWindow(hWnd, SW_RESTORE);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FUNCTION: ISLE 0x401ce0
|
MxU8 modifier = 0;
|
||||||
BOOL StartDirectSound()
|
if (p_flags & SDL_BUTTON_LMASK) {
|
||||||
{
|
modifier |= LegoEventNotificationParam::c_lButtonState;
|
||||||
LPDIRECTSOUND lpDS = NULL;
|
}
|
||||||
HRESULT ret = DirectSoundCreate(NULL, &lpDS, NULL);
|
if (p_flags & SDL_BUTTON_RMASK) {
|
||||||
if (ret == DS_OK && lpDS != NULL) {
|
modifier |= LegoEventNotificationParam::c_rButtonState;
|
||||||
lpDS->Release();
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return modifier;
|
||||||
}
|
|
||||||
|
|
||||||
// FUNCTION: ISLE 0x401d20
|
|
||||||
LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
NotificationId type;
|
|
||||||
unsigned char keyCode = 0;
|
|
||||||
|
|
||||||
if (!g_isle) {
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (uMsg) {
|
|
||||||
case WM_PAINT:
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
case WM_ACTIVATE:
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
case WM_ACTIVATEAPP:
|
|
||||||
if (g_isle) {
|
|
||||||
if ((wParam != 0) && (g_isle->GetFullScreen())) {
|
|
||||||
MoveWindow(
|
|
||||||
hWnd,
|
|
||||||
g_windowRect.left,
|
|
||||||
g_windowRect.top,
|
|
||||||
(g_windowRect.right - g_windowRect.left) + 1,
|
|
||||||
(g_windowRect.bottom - g_windowRect.top) + 1,
|
|
||||||
TRUE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
g_isle->SetWindowActive(wParam);
|
|
||||||
}
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
case WM_CLOSE:
|
|
||||||
if (!g_closed && g_isle) {
|
|
||||||
if (g_isle) {
|
|
||||||
delete g_isle;
|
|
||||||
}
|
|
||||||
g_isle = NULL;
|
|
||||||
g_closed = TRUE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
case WM_GETMINMAXINFO:
|
|
||||||
((MINMAXINFO*) lParam)->ptMaxTrackSize.x = (g_windowRect.right - g_windowRect.left) + 1;
|
|
||||||
((MINMAXINFO*) lParam)->ptMaxTrackSize.y = (g_windowRect.bottom - g_windowRect.top) + 1;
|
|
||||||
((MINMAXINFO*) lParam)->ptMinTrackSize.x = (g_windowRect.right - g_windowRect.left) + 1;
|
|
||||||
((MINMAXINFO*) lParam)->ptMinTrackSize.y = (g_windowRect.bottom - g_windowRect.top) + 1;
|
|
||||||
return 0;
|
|
||||||
case WM_ENTERMENULOOP:
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
case WM_SYSCOMMAND:
|
|
||||||
if (wParam == SC_SCREENSAVE) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (wParam == SC_CLOSE && g_closed == FALSE) {
|
|
||||||
if (g_isle) {
|
|
||||||
if (g_rmDisabled) {
|
|
||||||
ShowWindow(g_isle->GetWindowHandle(), SW_RESTORE);
|
|
||||||
}
|
|
||||||
PostMessageA(g_isle->GetWindowHandle(), WM_CLOSE, 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (g_isle && g_isle->GetFullScreen() && (wParam == SC_MOVE || wParam == SC_KEYMENU)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
case WM_EXITMENULOOP:
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
case WM_MOVING:
|
|
||||||
if (g_isle && g_isle->GetFullScreen()) {
|
|
||||||
GetWindowRect(hWnd, (LPRECT) lParam);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
case WM_NCPAINT:
|
|
||||||
if (g_isle && g_isle->GetFullScreen()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
case WM_DISPLAYCHANGE:
|
|
||||||
if (g_isle && VideoManager() && g_isle->GetFullScreen() && VideoManager()->GetDirect3D()) {
|
|
||||||
if (VideoManager()->GetDirect3D()->AssignedDevice()) {
|
|
||||||
int targetDepth = wParam;
|
|
||||||
int targetWidth = LOWORD(lParam);
|
|
||||||
int targetHeight = HIWORD(lParam);
|
|
||||||
|
|
||||||
if (g_waitingForTargetDepth) {
|
|
||||||
g_waitingForTargetDepth = FALSE;
|
|
||||||
g_targetDepth = targetDepth;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BOOL valid = FALSE;
|
|
||||||
|
|
||||||
if (g_targetWidth == targetWidth && g_targetHeight == targetHeight &&
|
|
||||||
g_targetDepth == targetDepth) {
|
|
||||||
valid = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_rmDisabled) {
|
|
||||||
if (valid) {
|
|
||||||
g_reqEnableRMDevice = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!valid) {
|
|
||||||
g_rmDisabled = TRUE;
|
|
||||||
Lego()->StartTimer();
|
|
||||||
VideoManager()->DisableRMDevice();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
case WM_KEYDOWN:
|
|
||||||
// While this probably should be (HIWORD(lParam) & KF_REPEAT), this seems
|
|
||||||
// to be what the assembly is actually doing
|
|
||||||
if (lParam & (KF_REPEAT << 16)) {
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
}
|
|
||||||
type = c_notificationKeyPress;
|
|
||||||
keyCode = wParam;
|
|
||||||
break;
|
|
||||||
case WM_MOUSEMOVE:
|
|
||||||
g_mousemoved = 1;
|
|
||||||
type = c_notificationMouseMove;
|
|
||||||
break;
|
|
||||||
case WM_TIMER:
|
|
||||||
type = c_notificationTimer;
|
|
||||||
break;
|
|
||||||
case WM_LBUTTONDOWN:
|
|
||||||
g_mousedown = 1;
|
|
||||||
type = c_notificationButtonDown;
|
|
||||||
break;
|
|
||||||
case WM_LBUTTONUP:
|
|
||||||
g_mousedown = 0;
|
|
||||||
type = c_notificationButtonUp;
|
|
||||||
break;
|
|
||||||
case 0x5400:
|
|
||||||
if (g_isle) {
|
|
||||||
g_isle->SetupCursor(wParam);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_SETCURSOR:
|
|
||||||
if (g_isle && (g_isle->GetCursorCurrent() == g_isle->GetCursorBusy() ||
|
|
||||||
g_isle->GetCursorCurrent() == g_isle->GetCursorNo() || !g_isle->GetCursorCurrent())) {
|
|
||||||
SetCursor(g_isle->GetCursorCurrent());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_isle) {
|
|
||||||
if (InputManager()) {
|
|
||||||
InputManager()->QueueEvent(type, wParam, LOWORD(lParam), HIWORD(lParam), keyCode);
|
|
||||||
}
|
|
||||||
if (g_isle && g_isle->GetDrawCursor() && type == c_notificationMouseMove) {
|
|
||||||
int x = LOWORD(lParam);
|
|
||||||
int y = HIWORD(lParam);
|
|
||||||
if (x >= 640) {
|
|
||||||
x = 639;
|
|
||||||
}
|
|
||||||
if (y >= 480) {
|
|
||||||
y = 479;
|
|
||||||
}
|
|
||||||
VideoManager()->MoveCursor(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: ISLE 0x4023e0
|
// FUNCTION: ISLE 0x4023e0
|
||||||
MxResult IsleApp::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine)
|
MxResult IsleApp::SetupWindow()
|
||||||
{
|
{
|
||||||
WNDCLASSA wndclass;
|
|
||||||
ZeroMemory(&wndclass, sizeof(WNDCLASSA));
|
|
||||||
|
|
||||||
LoadConfig();
|
LoadConfig();
|
||||||
|
|
||||||
SetupVideoFlags(
|
SetupVideoFlags(
|
||||||
m_fullScreen,
|
m_fullScreen,
|
||||||
m_flipSurfaces,
|
m_flipSurfaces,
|
||||||
@ -577,81 +436,19 @@ MxResult IsleApp::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine)
|
|||||||
|
|
||||||
MxOmni::SetSound3D(m_use3dSound);
|
MxOmni::SetSound3D(m_use3dSound);
|
||||||
|
|
||||||
srand(timeGetTime() / 1000);
|
srand(time(NULL));
|
||||||
SystemParametersInfoA(SPI_SETMOUSETRAILS, 0, NULL, 0);
|
|
||||||
|
|
||||||
ZeroMemory(&wndclass, sizeof(WNDCLASSA));
|
|
||||||
|
|
||||||
wndclass.cbClsExtra = 0;
|
|
||||||
wndclass.style = CS_HREDRAW | CS_VREDRAW;
|
|
||||||
wndclass.lpfnWndProc = WndProc;
|
|
||||||
wndclass.cbWndExtra = 0;
|
|
||||||
wndclass.hIcon = LoadIconA(hInstance, MAKEINTRESOURCEA(APP_ICON));
|
|
||||||
wndclass.hCursor = m_cursorArrow = m_cursorCurrent = LoadCursorA(hInstance, MAKEINTRESOURCEA(ISLE_ARROW));
|
|
||||||
m_cursorBusy = LoadCursorA(hInstance, MAKEINTRESOURCEA(ISLE_BUSY));
|
|
||||||
m_cursorNo = LoadCursorA(hInstance, MAKEINTRESOURCEA(ISLE_NO));
|
|
||||||
wndclass.hInstance = hInstance;
|
|
||||||
wndclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
|
|
||||||
wndclass.lpszClassName = WNDCLASS_NAME;
|
|
||||||
|
|
||||||
if (!RegisterClassA(&wndclass)) {
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_fullScreen) {
|
if (m_fullScreen) {
|
||||||
AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW);
|
m_windowHandle = SDL_CreateWindow(WINDOW_TITLE, g_windowRect.right, g_windowRect.bottom, SDL_WINDOW_FULLSCREEN);
|
||||||
|
|
||||||
m_windowHandle = CreateWindowExA(
|
|
||||||
WS_EX_APPWINDOW,
|
|
||||||
WNDCLASS_NAME,
|
|
||||||
WINDOW_TITLE,
|
|
||||||
WS_CAPTION | WS_SYSMENU,
|
|
||||||
g_windowRect.left,
|
|
||||||
g_windowRect.top,
|
|
||||||
g_windowRect.right - g_windowRect.left + 1,
|
|
||||||
g_windowRect.bottom - g_windowRect.top + 1,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
hInstance,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW);
|
m_windowHandle = SDL_CreateWindow(WINDOW_TITLE, g_windowRect.right, g_windowRect.bottom, 0);
|
||||||
|
|
||||||
m_windowHandle = CreateWindowExA(
|
|
||||||
WS_EX_APPWINDOW,
|
|
||||||
WNDCLASS_NAME,
|
|
||||||
WINDOW_TITLE,
|
|
||||||
WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX,
|
|
||||||
CW_USEDEFAULT,
|
|
||||||
CW_USEDEFAULT,
|
|
||||||
g_windowRect.right - g_windowRect.left + 1,
|
|
||||||
g_windowRect.bottom - g_windowRect.top + 1,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
hInstance,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_windowHandle) {
|
if (!m_windowHandle) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_fullScreen) {
|
|
||||||
MoveWindow(
|
|
||||||
m_windowHandle,
|
|
||||||
g_windowRect.left,
|
|
||||||
g_windowRect.top,
|
|
||||||
(g_windowRect.right - g_windowRect.left) + 1,
|
|
||||||
(g_windowRect.bottom - g_windowRect.top) + 1,
|
|
||||||
TRUE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowWindow(m_windowHandle, SW_SHOWNORMAL);
|
|
||||||
UpdateWindow(m_windowHandle);
|
|
||||||
if (!SetupLegoOmni()) {
|
if (!SetupLegoOmni()) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
@ -685,18 +482,6 @@ MxResult IsleApp::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine)
|
|||||||
LegoOmni::GetInstance()->GetInputManager()->SetJoystickIndex(m_joystickIndex);
|
LegoOmni::GetInstance()->GetInputManager()->SetJoystickIndex(m_joystickIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_fullScreen) {
|
|
||||||
MoveWindow(
|
|
||||||
m_windowHandle,
|
|
||||||
g_windowRect.left,
|
|
||||||
g_windowRect.top,
|
|
||||||
(g_windowRect.right - g_windowRect.left) + 1,
|
|
||||||
(g_windowRect.bottom - g_windowRect.top) + 1,
|
|
||||||
TRUE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ShowWindow(m_windowHandle, SW_SHOWNORMAL);
|
|
||||||
UpdateWindow(m_windowHandle);
|
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@ -754,7 +539,8 @@ void IsleApp::LoadConfig()
|
|||||||
strcpy(m_deviceId, deviceId);
|
strcpy(m_deviceId, deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [library:config] The original game does not save any data if no savepath is given.
|
// [library:config]
|
||||||
|
// The original game does not save any data if no savepath is given.
|
||||||
// Instead, we use SDLs prefPath as a default fallback and always save data.
|
// Instead, we use SDLs prefPath as a default fallback and always save data.
|
||||||
const char* savePath = iniparser_getstring(dict, "isle:savepath", prefPath);
|
const char* savePath = iniparser_getstring(dict, "isle:savepath", prefPath);
|
||||||
m_savePath = new char[strlen(savePath) + 1];
|
m_savePath = new char[strlen(savePath) + 1];
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include "mxtypes.h"
|
#include "mxtypes.h"
|
||||||
#include "mxvideoparam.h"
|
#include "mxvideoparam.h"
|
||||||
|
|
||||||
|
#include <SDL3/SDL_mouse.h>
|
||||||
|
#include <SDL3/SDL_video.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
// SIZE 0x8c
|
// SIZE 0x8c
|
||||||
@ -26,13 +28,15 @@ public:
|
|||||||
BOOL wideViewAngle,
|
BOOL wideViewAngle,
|
||||||
char* deviceId
|
char* deviceId
|
||||||
);
|
);
|
||||||
MxResult SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine);
|
MxResult SetupWindow();
|
||||||
|
|
||||||
void LoadConfig();
|
void LoadConfig();
|
||||||
void Tick(BOOL sleepIfNotNextFrame);
|
void Tick(BOOL sleepIfNotNextFrame);
|
||||||
void SetupCursor(WPARAM wParam);
|
void SetupCursor(WPARAM wParam);
|
||||||
|
|
||||||
inline HWND GetWindowHandle() { return m_windowHandle; }
|
static MxU8 MapMouseButtonFlagsToModifier(SDL_MouseButtonFlags p_flags);
|
||||||
|
|
||||||
|
inline SDL_Window* GetWindowHandle() { return m_windowHandle; }
|
||||||
inline MxLong GetFrameDelta() { return m_frameDelta; }
|
inline MxLong GetFrameDelta() { return m_frameDelta; }
|
||||||
inline BOOL GetFullScreen() { return m_fullScreen; }
|
inline BOOL GetFullScreen() { return m_fullScreen; }
|
||||||
inline HCURSOR GetCursorCurrent() { return m_cursorCurrent; }
|
inline HCURSOR GetCursorCurrent() { return m_cursorCurrent; }
|
||||||
@ -43,33 +47,33 @@ public:
|
|||||||
inline void SetWindowActive(BOOL p_windowActive) { m_windowActive = p_windowActive; }
|
inline void SetWindowActive(BOOL p_windowActive) { m_windowActive = p_windowActive; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* m_hdPath; // 0x00
|
char* m_hdPath; // 0x00
|
||||||
char* m_cdPath; // 0x04
|
char* m_cdPath; // 0x04
|
||||||
char* m_deviceId; // 0x08
|
char* m_deviceId; // 0x08
|
||||||
char* m_savePath; // 0x0c
|
char* m_savePath; // 0x0c
|
||||||
BOOL m_fullScreen; // 0x10
|
BOOL m_fullScreen; // 0x10
|
||||||
BOOL m_flipSurfaces; // 0x14
|
BOOL m_flipSurfaces; // 0x14
|
||||||
BOOL m_backBuffersInVram; // 0x18
|
BOOL m_backBuffersInVram; // 0x18
|
||||||
BOOL m_using8bit; // 0x1c
|
BOOL m_using8bit; // 0x1c
|
||||||
BOOL m_using16bit; // 0x20
|
BOOL m_using16bit; // 0x20
|
||||||
int m_unk0x24; // 0x24
|
int m_unk0x24; // 0x24
|
||||||
BOOL m_use3dSound; // 0x28
|
BOOL m_use3dSound; // 0x28
|
||||||
BOOL m_useMusic; // 0x2c
|
BOOL m_useMusic; // 0x2c
|
||||||
BOOL m_useJoystick; // 0x30
|
BOOL m_useJoystick; // 0x30
|
||||||
int m_joystickIndex; // 0x34
|
int m_joystickIndex; // 0x34
|
||||||
BOOL m_wideViewAngle; // 0x38
|
BOOL m_wideViewAngle; // 0x38
|
||||||
int m_islandQuality; // 0x3c
|
int m_islandQuality; // 0x3c
|
||||||
int m_islandTexture; // 0x40
|
int m_islandTexture; // 0x40
|
||||||
BOOL m_gameStarted; // 0x44
|
BOOL m_gameStarted; // 0x44
|
||||||
MxLong m_frameDelta; // 0x48
|
MxLong m_frameDelta; // 0x48
|
||||||
MxVideoParam m_videoParam; // 0x4c
|
MxVideoParam m_videoParam; // 0x4c
|
||||||
BOOL m_windowActive; // 0x70
|
BOOL m_windowActive; // 0x70
|
||||||
HWND m_windowHandle; // 0x74
|
SDL_Window* m_windowHandle; // 0x74
|
||||||
BOOL m_drawCursor; // 0x78
|
BOOL m_drawCursor; // 0x78
|
||||||
HCURSOR m_cursorArrow; // 0x7c
|
HCURSOR m_cursorArrow; // 0x7c
|
||||||
HCURSOR m_cursorBusy; // 0x80
|
HCURSOR m_cursorBusy; // 0x80
|
||||||
HCURSOR m_cursorNo; // 0x84
|
HCURSOR m_cursorNo; // 0x84
|
||||||
HCURSOR m_cursorCurrent; // 0x88
|
HCURSOR m_cursorCurrent; // 0x88
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ISLEAPP_H
|
#endif // ISLEAPP_H
|
||||||
|
@ -26,7 +26,7 @@ To achieve our goal of platform independence, we need to replace any Windows-onl
|
|||||||
| Windows Registry (Configuration) | [libiniparser](https://github.com/ndevilla/iniparser) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Aconfig%5D%22&type=code) |
|
| Windows Registry (Configuration) | [libiniparser](https://github.com/ndevilla/iniparser) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Aconfig%5D%22&type=code) |
|
||||||
| Filesystem | [SDL3](https://www.libsdl.org/) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Afilesystem%5D%22&type=code) |
|
| Filesystem | [SDL3](https://www.libsdl.org/) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Afilesystem%5D%22&type=code) |
|
||||||
| Threads, Mutexes (Synchronization) | [SDL3](https://www.libsdl.org/) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Asynchronization%5D%22&type=code) |
|
| Threads, Mutexes (Synchronization) | [SDL3](https://www.libsdl.org/) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Asynchronization%5D%22&type=code) |
|
||||||
| Keyboard/Mouse, Joystick, DirectInput (Input) | [SDL3](https://www.libsdl.org/) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Ainput%5D%22&type=code) |
|
| Keyboard/Mouse, Joystick, DirectInput (Input) | [SDL3](https://www.libsdl.org/) | WIP | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Ainput%5D%22&type=code) |
|
||||||
| WinMM, DirectSound (Audio) | [SDL_mixer](https://github.com/libsdl-org/SDL_mixer) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Aaudio%5D%22&type=code) |
|
| WinMM, DirectSound (Audio) | [SDL_mixer](https://github.com/libsdl-org/SDL_mixer) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Aaudio%5D%22&type=code) |
|
||||||
| DirectDraw (2D video) | [SDL3](https://www.libsdl.org/) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3A2d%5D%22&type=code) |
|
| DirectDraw (2D video) | [SDL3](https://www.libsdl.org/) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3A2d%5D%22&type=code) |
|
||||||
| [Smacker](https://github.com/isledecomp/isle/tree/master/3rdparty/smacker) | [libsmacker](https://github.com/foxtacles/libsmacker) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable%20%22%2F%2F%20%5Blibrary%3Alibsmacker%5D%22&type=code) |
|
| [Smacker](https://github.com/isledecomp/isle/tree/master/3rdparty/smacker) | [libsmacker](https://github.com/foxtacles/libsmacker) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable%20%22%2F%2F%20%5Blibrary%3Alibsmacker%5D%22&type=code) |
|
||||||
|
Loading…
x
Reference in New Issue
Block a user