From eec27f8536e2f6a9c63c961630806eed6b7cba9f Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 27 Jun 2023 12:35:54 +0200 Subject: [PATCH] rearrange functions to get close to the original --- ISLE/isle.cpp | 565 +++++++++++++++++++++++++++++++++++++++++++++++--- ISLE/isle.h | 217 +------------------ ISLE/main.cpp | 303 --------------------------- isle.mak | 90 ++++---- isle.mdp | Bin 50176 -> 50176 bytes 5 files changed, 596 insertions(+), 579 deletions(-) delete mode 100644 ISLE/main.cpp diff --git a/ISLE/isle.cpp b/ISLE/isle.cpp index 051572ef..25d653d8 100644 --- a/ISLE/isle.cpp +++ b/ISLE/isle.cpp @@ -1,4 +1,18 @@ #include "isle.h" +#include "define.h" + +#include + +#include "legoomni.h" +#include "legoanimationmanager.h" +#include "legobuildingmanager.h" +#include "legomodelpresenter.h" +#include "legopartpresenter.h" +#include "legoworldpresenter.h" +#include "mxdirectdraw.h" +#include "mxdsaction.h" + +#include "res/resource.h" // OFFSET: ISLE 0x401000 Isle::Isle() @@ -97,6 +111,460 @@ void Isle::Close() } } +// OFFSET: ISLE 0x4013b0 +BOOL Isle::SetupLegoOmni() +{ + BOOL result = FALSE; + char mediaPath[256]; + GetProfileStringA("LEGO Island", "MediaPath", "", mediaPath, sizeof(mediaPath)); + + BOOL failure = Lego()->Create(MxOmniCreateParam(mediaPath, (struct HWND__ *) m_windowHandle, m_videoParam, MxOmniCreateFlags())) == FAILURE; + if (!failure) { + VariableTable()->SetVariable("ACTOR_01", ""); + TickleManager()->vtable1c(VideoManager(), 10); + result = TRUE; + } + + return result; +} + +// OFFSET: ISLE 0x401560 +void Isle::SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, + BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7, + BOOL wideViewAngle, char *deviceId) +{ + m_videoParam.flags().SetFullScreen(fullScreen); + m_videoParam.flags().SetFlipSurfaces(flipSurfaces); + m_videoParam.flags().SetBackBuffers(!backBuffers); + m_videoParam.flags().Set_f2bit0(!param_6); + m_videoParam.flags().Set_f1bit7(param_7); + m_videoParam.flags().SetWideViewAngle(wideViewAngle); + m_videoParam.flags().Set_f2bit1(1); + m_videoParam.SetDeviceName(deviceId); + if (using8bit) { + m_videoParam.flags().Set16Bit(0); + } + if (using16bit) { + m_videoParam.flags().Set16Bit(1); + } +} + +BOOL FindExistingInstance(void); +BOOL StartDirectSound(void); + +// OFFSET: ISLE 0x401610 +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) +{ + // Look for another instance, if we find one, bring it to the foreground instead + if (!FindExistingInstance()) { + return 0; + } + + // 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 0; + } + + // Create global app instance + g_isle = new Isle(); + + // Create window + if (g_isle->SetupWindow(hInstance, lpCmdLine) != SUCCESS) { + MessageBoxA(NULL, "\"LEGO\xAE Island\" failed to start. Please quit all other applications and try again.", "LEGO\xAE Island Error", MB_OK); + return 0; + } + + // Get reference to window + HWND window; + if (g_isle->m_windowHandle) { + window = g_isle->m_windowHandle; + } + + // Load accelerators (this call actually achieves nothing - there is no "AppAccel" resource in the original - but we'll keep this for authenticity) + // This line may actually be here because it's in DFVIEW, an example project that ships with + // MSVC420, and was such a clean example of a Win32 app, that it was later adapted + // into an "ExeSkeleton" sample for MSVC600. It's quite possible Mindscape derived + // this app from that example since they no longer had the luxury of the + // MFC AppWizard which we know they used for the frontend used during development (ISLEMFC.EXE, MAIN.EXE, et al.) + LoadAcceleratorsA(hInstance, "AppAccel"); + + MSG msg; + + while (!g_closed) { + while (!PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE)) { + 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->m_windowHandle + || msg.message != WM_MOUSEMOVE + || !PeekMessageA(&nextMsg, NULL, 0, 0, PM_NOREMOVE) + || nextMsg.message != WM_MOUSEMOVE) { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + + if (g_reqEnableRMDevice) { + g_reqEnableRMDevice = 0; + VideoManager()->EnableRMDevice(); + g_rmDisabled = 0; + Lego()->vtable3c(); + } + + if (g_closed) { + break; + } + + if (g_mousedown == 0) { +LAB_00401bc7: + if (g_mousemoved) { + g_mousemoved = FALSE; + } + } else if (g_mousemoved) { + if (g_isle) { + g_isle->Tick(0); + } + goto LAB_00401bc7; + } + } + } + + DestroyWindow(window); + + return msg.wParam; +} + +// OFFSET: ISLE 0x401ca0 +BOOL FindExistingInstance(void) +{ + HWND hWnd = FindWindowA(WNDCLASS_NAME, WINDOW_TITLE); + if (hWnd) { + if (SetForegroundWindow(hWnd)) { + ShowWindow(hWnd, SW_RESTORE); + } + return 0; + } + return 1; +} + +// OFFSET: ISLE 0x401ce0 +BOOL StartDirectSound(void) +{ + LPDIRECTSOUND lpDS = NULL; + HRESULT ret = DirectSoundCreate(NULL, &lpDS, NULL); + if (ret == DS_OK && lpDS != NULL) { + lpDS->Release(); + return TRUE; + } + + return FALSE; +} + +// OFFSET: 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->m_fullScreen)) { + 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->m_windowActive = 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 == 0) { + if (g_isle) { + if (g_rmDisabled) { + ShowWindow(g_isle->m_windowHandle, SW_RESTORE); + } + PostMessageA(g_isle->m_windowHandle, WM_CLOSE, 0, 0); + return 0; + } + } else if (g_isle && g_isle->m_fullScreen && (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->m_fullScreen) { + GetWindowRect(hWnd, (LPRECT) lParam); + return 0; + } + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + case WM_NCPAINT: + if (g_isle && g_isle->m_fullScreen) { + return 0; + } + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + case WM_DISPLAYCHANGE: + if (g_isle && VideoManager() && g_isle->m_fullScreen && VideoManager()->m_unk74 && VideoManager()->m_unk74[0x220]) { + int targetWidth = LOWORD(lParam); + int targetHeight = HIWORD(lParam); + int targetDepth = wParam; + + if (g_waitingForTargetDepth) { + g_waitingForTargetDepth = 0; + g_targetDepth = targetDepth; + } + else { + BOOL valid = FALSE; + if (targetWidth == g_targetWidth && targetHeight == g_targetHeight && g_targetDepth == targetDepth) { + valid = TRUE; + } + + if (g_rmDisabled) { + if (valid) { + g_reqEnableRMDevice = 1; + } + } + else if (!valid) { + g_rmDisabled = 1; + Lego()->vtable38(); + VideoManager()->DisableRMDevice(); + } + } + } + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + case WM_SETCURSOR: + if (g_isle) { + HCURSOR hCursor = g_isle->m_cursorCurrent; + if (hCursor == g_isle->m_cursorBusy || hCursor == g_isle->m_cursorNo || !hCursor) { + SetCursor(hCursor); + return 0; + } + } + break; + 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); + } + keyCode = wParam; + type = KEYDOWN; + break; + case WM_MOUSEMOVE: + g_mousemoved = 1; + type = MOUSEMOVE; + break; + case WM_TIMER: + type = TIMER; + break; + case WM_LBUTTONDOWN: + g_mousedown = 1; + type = MOUSEDOWN; + break; + case WM_LBUTTONUP: + g_mousedown = 0; + type = MOUSEUP; + break; + case 0x5400: + if (g_isle) { + g_isle->SetupCursor(wParam); + 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->m_drawCursor && type == MOUSEMOVE) { + int x = LOWORD(lParam); + int y = HIWORD(lParam); + if (x >= 640) { + x = 639; + } + if (y >= 480) { + y = 479; + } + VideoManager()->MoveCursor(x,y); + } + } + + return 0; +} + + +// OFFSET: ISLE 0x4023e0 +inline MxResult Isle::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine) +{ + WNDCLASSA wndclass; + ZeroMemory(&wndclass, sizeof(WNDCLASSA)); + + LoadConfig(); + + SetupVideoFlags(m_fullScreen, m_flipSurfaces, m_backBuffersInVram, m_using8bit, + m_using16bit, m_unk24, FALSE, m_wideViewAngle, m_deviceId); + + MxOmni::SetSound3D(m_use3dSound); + + srand(timeGetTime() / 1000); + 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) { + AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW); + + 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 { + AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW); + + 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) { + 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()) { + return FAILURE; + } + + GameState()->SetSavePath(m_savePath); + GameState()->SerializePlayersInfo(1); + GameState()->SerializeScoreHistory(1); + + int iVar10; + switch (m_islandQuality) { + case 0: + iVar10 = 1; + break; + case 1: + iVar10 = 2; + break; + default: + iVar10 = 100; + } + + int uVar1 = (m_islandTexture == 0); + LegoModelPresenter::configureLegoModelPresenter(uVar1); + LegoPartPresenter::configureLegoPartPresenter(uVar1,iVar10); + LegoWorldPresenter::configureLegoWorldPresenter(m_islandQuality); + LegoBuildingManager::configureLegoBuildingManager(m_islandQuality); + LegoROI::configureLegoROI(iVar10); + LegoAnimationManager::configureLegoAnimationManager(m_islandQuality); + if (LegoOmni::GetInstance()) { + if (LegoOmni::GetInstance()->GetInputManager()) { + LegoOmni::GetInstance()->GetInputManager()->m_useJoystick = m_useJoystick; + LegoOmni::GetInstance()->GetInputManager()->m_joystickIndex = 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; +} + // OFFSET: ISLE 0x402740 BOOL Isle::ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize) { @@ -216,43 +684,76 @@ void Isle::LoadConfig() } } -// OFFSET: ISLE 0x401560 -void Isle::SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, - BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7, - BOOL wideViewAngle, char *deviceId) + + +// OFFSET: ISLE 0x402c20 +inline void Isle::Tick(BOOL sleepIfNotNextFrame) { - m_videoParam.flags().SetFullScreen(fullScreen); - m_videoParam.flags().SetFlipSurfaces(flipSurfaces); - m_videoParam.flags().SetBackBuffers(!backBuffers); - m_videoParam.flags().Set_f2bit0(!param_6); - m_videoParam.flags().Set_f1bit7(param_7); - m_videoParam.flags().SetWideViewAngle(wideViewAngle); - m_videoParam.flags().Set_f2bit1(1); - m_videoParam.SetDeviceName(deviceId); - if (using8bit) { - m_videoParam.flags().Set16Bit(0); + if (!this->m_windowActive) { + Sleep(0); + return; } - if (using16bit) { - m_videoParam.flags().Set16Bit(1); + + if (!Lego()) return; + if (!TickleManager()) return; + if (!Timer()) return; + + long currentTime = Timer()->GetRealTime(); + if (currentTime < g_lastFrameTime) { + g_lastFrameTime = -this->m_frameDelta; } + + if (this->m_frameDelta + g_lastFrameTime < currentTime) { + if (!Lego()->vtable40()) { + TickleManager()->Tickle(); + } + g_lastFrameTime = currentTime; + + if (g_startupDelay == 0) { + return; + } + + g_startupDelay--; + if (g_startupDelay != 0) { + return; + } + + LegoOmni::GetInstance()->CreateBackgroundAudio(); + BackgroundAudioManager()->Enable(this->m_useMusic); + + MxStreamController *stream = Streamer()->Open("\\lego\\scripts\\isle\\isle", 0); + MxDSAction ds; + + if (!stream) { + stream = Streamer()->Open("\\lego\\scripts\\nocd", 0); + if (!stream) { + return; + } + + ds.SetAtomId(stream->atom); + ds.SetUnknown24(-1); + ds.SetUnknown1c(0); + VideoManager()->EnableFullScreenMovie(TRUE, TRUE); + + if (Start(&ds) != SUCCESS) { + return; + } + } else { + ds.SetAtomId(stream->atom); + ds.SetUnknown24(-1); + ds.SetUnknown1c(0); + if (Start(&ds) != SUCCESS) { + return; + } + this->m_gameStarted = 1; + } + return; + } + + if (sleepIfNotNextFrame != 0) + Sleep(0); } -// OFFSET: ISLE 0x4013b0 -BOOL Isle::SetupLegoOmni() -{ - BOOL result = FALSE; - char mediaPath[256]; - GetProfileStringA("LEGO Island", "MediaPath", "", mediaPath, sizeof(mediaPath)); - - BOOL failure = Lego()->Create(MxOmniCreateParam(mediaPath, (struct HWND__ *) m_windowHandle, m_videoParam, MxOmniCreateFlags())) == FAILURE; - if (!failure) { - VariableTable()->SetVariable("ACTOR_01", ""); - TickleManager()->vtable1c(VideoManager(), 10); - result = TRUE; - } - - return result; -} // OFFSET: ISLE 0x402e80 void Isle::SetupCursor(WPARAM wParam) diff --git a/ISLE/isle.h b/ISLE/isle.h index d899d037..d45d33a3 100644 --- a/ISLE/isle.h +++ b/ISLE/isle.h @@ -2,20 +2,9 @@ #define ISLE_H #include "legoinc.h" -#include "define.h" -#include "legoomni.h" -#include "legoanimationmanager.h" -#include "legobuildingmanager.h" -#include "legomodelpresenter.h" -#include "legopartpresenter.h" -#include "legoworldpresenter.h" #include "mxresult.h" #include "mxvideoparam.h" -#include "mxdirectdraw.h" -#include "mxdsaction.h" -#include "mxomni.h" -#include "res/resource.h" class Isle { @@ -25,24 +14,21 @@ class Isle void Close(); + BOOL SetupLegoOmni(); + void SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, + BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7, + BOOL wideViewAngle, char *deviceId); + MxResult SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine); + BOOL ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize); int ReadRegBool(LPCSTR name, BOOL *out); int ReadRegInt(LPCSTR name, int *out); - MxResult SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine); - - void Tick(BOOL sleepIfNotNextFrame); - - BOOL SetupLegoOmni(); void LoadConfig(); - void SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, - BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7, - BOOL wideViewAngle, char *deviceId); - + void Tick(BOOL sleepIfNotNextFrame); void SetupCursor(WPARAM wParam); -// private: - + // private: // 0 LPSTR m_hdPath; LPSTR m_cdPath; @@ -85,193 +71,6 @@ class Isle HCURSOR m_cursorBusy; HCURSOR m_cursorNo; HCURSOR m_cursorCurrent; - }; -extern LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - -// OFFSET: ISLE 0x4023e0 -inline MxResult Isle::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine) -{ - WNDCLASSA wndclass; - ZeroMemory(&wndclass, sizeof(WNDCLASSA)); - - LoadConfig(); - - SetupVideoFlags(m_fullScreen, m_flipSurfaces, m_backBuffersInVram, m_using8bit, - m_using16bit, m_unk24, FALSE, m_wideViewAngle, m_deviceId); - - MxOmni::SetSound3D(m_use3dSound); - - srand(timeGetTime() / 1000); - 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) { - AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW); - - 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 { - AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW); - - 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) { - 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()) { - return FAILURE; - } - - GameState()->SetSavePath(m_savePath); - GameState()->SerializePlayersInfo(1); - GameState()->SerializeScoreHistory(1); - - int iVar10; - switch (m_islandQuality) { - case 0: - iVar10 = 1; - break; - case 1: - iVar10 = 2; - break; - default: - iVar10 = 100; - } - - int uVar1 = (m_islandTexture == 0); - LegoModelPresenter::configureLegoModelPresenter(uVar1); - LegoPartPresenter::configureLegoPartPresenter(uVar1,iVar10); - LegoWorldPresenter::configureLegoWorldPresenter(m_islandQuality); - LegoBuildingManager::configureLegoBuildingManager(m_islandQuality); - LegoROI::configureLegoROI(iVar10); - LegoAnimationManager::configureLegoAnimationManager(m_islandQuality); - if (LegoOmni::GetInstance()) { - if (LegoOmni::GetInstance()->GetInputManager()) { - LegoOmni::GetInstance()->GetInputManager()->m_useJoystick = m_useJoystick; - LegoOmni::GetInstance()->GetInputManager()->m_joystickIndex = 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; -} - -// OFFSET: ISLE 0x402c20 -inline void Isle::Tick(BOOL sleepIfNotNextFrame) -{ - if (!this->m_windowActive) { - Sleep(0); - return; - } - - if (!Lego()) return; - if (!TickleManager()) return; - if (!Timer()) return; - - long currentTime = Timer()->GetRealTime(); - if (currentTime < g_lastFrameTime) { - g_lastFrameTime = -this->m_frameDelta; - } - - if (this->m_frameDelta + g_lastFrameTime < currentTime) { - if (!Lego()->vtable40()) { - TickleManager()->Tickle(); - } - g_lastFrameTime = currentTime; - - if (g_startupDelay == 0) { - return; - } - - g_startupDelay--; - if (g_startupDelay != 0) { - return; - } - - LegoOmni::GetInstance()->CreateBackgroundAudio(); - BackgroundAudioManager()->Enable(this->m_useMusic); - - MxStreamController *stream = Streamer()->Open("\\lego\\scripts\\isle\\isle", 0); - MxDSAction ds; - - if (!stream) { - stream = Streamer()->Open("\\lego\\scripts\\nocd", 0); - if (!stream) { - return; - } - - ds.SetAtomId(stream->atom); - ds.SetUnknown24(-1); - ds.SetUnknown1c(0); - VideoManager()->EnableFullScreenMovie(TRUE, TRUE); - - if (Start(&ds) != SUCCESS) { - return; - } - } else { - ds.SetAtomId(stream->atom); - ds.SetUnknown24(-1); - ds.SetUnknown1c(0); - if (Start(&ds) != SUCCESS) { - return; - } - this->m_gameStarted = 1; - } - return; - } - - if (sleepIfNotNextFrame != 0) - Sleep(0); -} - #endif // ISLE_H diff --git a/ISLE/main.cpp b/ISLE/main.cpp deleted file mode 100644 index 2ba477f7..00000000 --- a/ISLE/main.cpp +++ /dev/null @@ -1,303 +0,0 @@ -#include - -#include "legoinc.h" -#include "define.h" - -#include "legoomni.h" -#include "isle.h" - -// OFFSET: ISLE 0x401ca0 -BOOL FindExistingInstance(void) -{ - HWND hWnd = FindWindowA(WNDCLASS_NAME, WINDOW_TITLE); - if (hWnd) { - if (SetForegroundWindow(hWnd)) { - ShowWindow(hWnd, SW_RESTORE); - } - return 0; - } - return 1; -} - -// OFFSET: ISLE 0x401ce0 -BOOL StartDirectSound(void) -{ - LPDIRECTSOUND lpDS = NULL; - HRESULT ret = DirectSoundCreate(NULL, &lpDS, NULL); - if (ret == DS_OK && lpDS != NULL) { - lpDS->Release(); - return TRUE; - } - - return FALSE; -} - -// OFFSET: ISLE 0x401610 -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) -{ - // Look for another instance, if we find one, bring it to the foreground instead - if (!FindExistingInstance()) { - return 0; - } - - // 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 0; - } - - // Create global app instance - g_isle = new Isle(); - - // Create window - if (g_isle->SetupWindow(hInstance, lpCmdLine) != SUCCESS) { - MessageBoxA(NULL, "\"LEGO\xAE Island\" failed to start. Please quit all other applications and try again.", "LEGO\xAE Island Error", MB_OK); - return 0; - } - - // Get reference to window - HWND window; - if (g_isle->m_windowHandle) { - window = g_isle->m_windowHandle; - } - - // Load accelerators (this call actually achieves nothing - there is no "AppAccel" resource in the original - but we'll keep this for authenticity) - // This line may actually be here because it's in DFVIEW, an example project that ships with - // MSVC420, and was such a clean example of a Win32 app, that it was later adapted - // into an "ExeSkeleton" sample for MSVC600. It's quite possible Mindscape derived - // this app from that example since they no longer had the luxury of the - // MFC AppWizard which we know they used for the frontend used during development (ISLEMFC.EXE, MAIN.EXE, et al.) - LoadAcceleratorsA(hInstance, "AppAccel"); - - MSG msg; - - while (!g_closed) { - while (!PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE)) { - 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->m_windowHandle - || msg.message != WM_MOUSEMOVE - || !PeekMessageA(&nextMsg, NULL, 0, 0, PM_NOREMOVE) - || nextMsg.message != WM_MOUSEMOVE) { - TranslateMessage(&msg); - DispatchMessageA(&msg); - } - - if (g_reqEnableRMDevice) { - g_reqEnableRMDevice = 0; - VideoManager()->EnableRMDevice(); - g_rmDisabled = 0; - Lego()->vtable3c(); - } - - if (g_closed) { - break; - } - - if (g_mousedown == 0) { -LAB_00401bc7: - if (g_mousemoved) { - g_mousemoved = FALSE; - } - } else if (g_mousemoved) { - if (g_isle) { - g_isle->Tick(0); - } - goto LAB_00401bc7; - } - } - } - - DestroyWindow(window); - - return msg.wParam; -} - -// OFFSET: 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->m_fullScreen)) { - 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->m_windowActive = 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 == 0) { - if (g_isle) { - if (g_rmDisabled) { - ShowWindow(g_isle->m_windowHandle, SW_RESTORE); - } - PostMessageA(g_isle->m_windowHandle, WM_CLOSE, 0, 0); - return 0; - } - } else if (g_isle && g_isle->m_fullScreen && (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->m_fullScreen) { - GetWindowRect(hWnd, (LPRECT) lParam); - return 0; - } - return DefWindowProcA(hWnd, uMsg, wParam, lParam); - case WM_NCPAINT: - if (g_isle && g_isle->m_fullScreen) { - return 0; - } - return DefWindowProcA(hWnd, uMsg, wParam, lParam); - case WM_DISPLAYCHANGE: - if (g_isle && VideoManager() && g_isle->m_fullScreen && VideoManager()->m_unk74 && VideoManager()->m_unk74[0x220]) { - int targetWidth = LOWORD(lParam); - int targetHeight = HIWORD(lParam); - int targetDepth = wParam; - - if (g_waitingForTargetDepth) { - g_waitingForTargetDepth = 0; - g_targetDepth = targetDepth; - } - else { - BOOL valid = FALSE; - if (targetWidth == g_targetWidth && targetHeight == g_targetHeight && g_targetDepth == targetDepth) { - valid = TRUE; - } - - if (g_rmDisabled) { - if (valid) { - g_reqEnableRMDevice = 1; - } - } - else if (!valid) { - g_rmDisabled = 1; - Lego()->vtable38(); - VideoManager()->DisableRMDevice(); - } - } - } - return DefWindowProcA(hWnd, uMsg, wParam, lParam); - case WM_SETCURSOR: - if (g_isle) { - HCURSOR hCursor = g_isle->m_cursorCurrent; - if (hCursor == g_isle->m_cursorBusy || hCursor == g_isle->m_cursorNo || !hCursor) { - SetCursor(hCursor); - return 0; - } - } - break; - 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); - } - keyCode = wParam; - type = KEYDOWN; - break; - case WM_MOUSEMOVE: - g_mousemoved = 1; - type = MOUSEMOVE; - break; - case WM_TIMER: - type = TIMER; - break; - case WM_LBUTTONDOWN: - g_mousedown = 1; - type = MOUSEDOWN; - break; - case WM_LBUTTONUP: - g_mousedown = 0; - type = MOUSEUP; - break; - case 0x5400: - if (g_isle) { - g_isle->SetupCursor(wParam); - 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->m_drawCursor && type == MOUSEMOVE) { - int x = LOWORD(lParam); - int y = HIWORD(lParam); - if (x >= 640) { - x = 639; - } - if (y >= 480) { - y = 479; - } - VideoManager()->MoveCursor(x,y); - } - } - - return 0; -} \ No newline at end of file diff --git a/isle.mak b/isle.mak index 59570097..5e3fdd3e 100644 --- a/isle.mak +++ b/isle.mak @@ -299,7 +299,6 @@ CLEAN : -@erase "$(INTDIR)\define.obj" -@erase "$(INTDIR)\isle.obj" -@erase "$(INTDIR)\isle.res" - -@erase "$(INTDIR)\main.obj" -@erase "$(INTDIR)\vc40.pdb" -@erase ".\Release\ISLE.EXE" -@erase ".\Release\ISLE.PDB" @@ -360,7 +359,6 @@ LINK32_OBJS= \ "$(INTDIR)\define.obj" \ "$(INTDIR)\isle.obj" \ "$(INTDIR)\isle.res" \ - "$(INTDIR)\main.obj" \ ".\Release\LEGO1.LIB" ".\Release\ISLE.EXE" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) @@ -389,7 +387,6 @@ CLEAN : -@erase "$(INTDIR)\define.obj" -@erase "$(INTDIR)\isle.obj" -@erase "$(INTDIR)\isle.res" - -@erase "$(INTDIR)\main.obj" -@erase "$(INTDIR)\vc40.idb" -@erase "$(INTDIR)\vc40.pdb" -@erase ".\Debug\ISLE.EXE" @@ -452,7 +449,6 @@ LINK32_OBJS= \ "$(INTDIR)\define.obj" \ "$(INTDIR)\isle.obj" \ "$(INTDIR)\isle.res" \ - "$(INTDIR)\main.obj" \ ".\LEGO1\Debug\LEGO1.lib" ".\Debug\ISLE.EXE" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) @@ -902,20 +898,10 @@ DEP_CPP_MXPAL=\ ################################################################################ # Begin Source File -SOURCE=.\ISLE\define.cpp -DEP_CPP_DEFIN=\ - ".\ISLE\define.h"\ - - -"$(INTDIR)\define.obj" : $(SOURCE) $(DEP_CPP_DEFIN) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -# End Source File -################################################################################ -# Begin Source File - SOURCE=.\ISLE\isle.cpp + +!IF "$(CFG)" == "ISLE - Win32 Release" + DEP_CPP_ISLE_=\ ".\ISLE\define.h"\ ".\ISLE\isle.h"\ @@ -974,29 +960,33 @@ DEP_CPP_ISLE_=\ $(CPP) $(CPP_PROJ) $(SOURCE) -# End Source File -################################################################################ -# Begin Source File +!ELSEIF "$(CFG)" == "ISLE - Win32 Debug" -SOURCE=.\ISLE\main.cpp -DEP_CPP_MAIN_=\ +DEP_CPP_ISLE_=\ ".\ISLE\define.h"\ ".\ISLE\isle.h"\ + ".\ISLE\res\resource.h"\ ".\LEGO1\lego3dmanager.h"\ ".\LEGO1\lego3dview.h"\ + ".\LEGO1\legoanimationmanager.h"\ + ".\LEGO1\legobuildingmanager.h"\ ".\LEGO1\legoentity.h"\ ".\LEGO1\legogamestate.h"\ ".\LEGO1\legoinc.h"\ ".\LEGO1\legoinputmanager.h"\ + ".\LEGO1\legomodelpresenter.h"\ ".\LEGO1\legonavcontroller.h"\ ".\LEGO1\legoomni.h"\ + ".\LEGO1\legopartpresenter.h"\ ".\LEGO1\legoroi.h"\ ".\LEGO1\legovideomanager.h"\ + ".\LEGO1\legoworldpresenter.h"\ ".\LEGO1\mxatomid.h"\ ".\LEGO1\mxbackgroundaudiomanager.h"\ ".\LEGO1\mxbool.h"\ ".\LEGO1\mxcore.h"\ ".\LEGO1\mxcriticalsection.h"\ + ".\LEGO1\mxdirectdraw.h"\ ".\LEGO1\mxdsaction.h"\ ".\LEGO1\mxdsfile.h"\ ".\LEGO1\mxdsobject.h"\ @@ -1026,10 +1016,12 @@ DEP_CPP_MAIN_=\ ".\LEGO1\viewmanager.h"\ -"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)" +"$(INTDIR)\isle.obj" : $(SOURCE) $(DEP_CPP_ISLE_) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) +!ENDIF + # End Source File ################################################################################ # Begin Source File @@ -1179,18 +1171,6 @@ SOURCE=.\LEGO1\legoworldpresenter.h ################################################################################ # Begin Source File -SOURCE=.\LEGO1\mxatomid.h - -!IF "$(CFG)" == "ISLE - Win32 Release" - -!ELSEIF "$(CFG)" == "ISLE - Win32 Debug" - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - SOURCE=.\LEGO1\mxbackgroundaudiomanager.h !IF "$(CFG)" == "ISLE - Win32 Release" @@ -1470,6 +1450,46 @@ SOURCE=.\LEGO1\mxvideoparamflags.h !ENDIF # End Project Dependency +################################################################################ +# Begin Source File + +SOURCE=.\LEGO1\mxatomid.h + +!IF "$(CFG)" == "ISLE - Win32 Release" + +!ELSEIF "$(CFG)" == "ISLE - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ISLE\define.cpp + +!IF "$(CFG)" == "ISLE - Win32 Release" + +DEP_CPP_DEFIN=\ + ".\ISLE\define.h"\ + + +"$(INTDIR)\define.obj" : $(SOURCE) $(DEP_CPP_DEFIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "ISLE - Win32 Debug" + +DEP_CPP_DEFIN=\ + ".\ISLE\define.h"\ + + +"$(INTDIR)\define.obj" : $(SOURCE) $(DEP_CPP_DEFIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File # End Target # End Project ################################################################################ diff --git a/isle.mdp b/isle.mdp index 390064aa600f2bb5cc48156405e1040876938d6d..0d438f5eb8b8cd4902f94a7963a3263402b17a62 100644 GIT binary patch delta 808 zcmdT@&ui0g6#ph|VyzY1(QQ~aI@e@1tEM}6*hPfWlOA;LpafSOZo%ptWf^O0+OBLG z3T|o2M;Rzm*wKT!ens%0Y~o48KVcJvF&%>*TtV2u^dR=&z^jM%c%S!y&wIQd#gd~~ za=dT_yh)ba5@e37k`ZFXzVIu)EvDAxYWq7eupbfMkGLYSOca$sFN(?$x~AwX6SHAI zeKd0437Uvt=hy*Mt_n8KdB(=oV$V2;hxg`aeWt;|U6AQ!PGIO@Veb#(IhQ|v z?lL-!ZYYL8myKP9zAgQ5ps^sLwh%`(!y%Cl;;}B`OkTo8y$@Yh2tUgq%-Ffj+)1c; z86Qm%pVDCjGpDed?ni2gLv>cd=Xt@_7{ax?k!BA#Ystu`hwvbO0`-i7Og4=7wpFtt zs&_)z&c1|q&O~`$#Ht=aAQ#5A9))Vxd6gT$#NsGYWe(G36b)0d<0x)h5(W#>|JL*G z;V+eXaKXNjZ(1)-8$s-7o%o=&AF@|Vc$a^8IChCHKG8gt9>4bnOKyhycw$X_<(p?t eeeSxW_RQ7hOLmai)(4ov^HG^jC0;Yj@7P}kR5^wK delta 1161 zcmZqZU~cGO-oPOxBFoGm*L<3Z;Q+%thKk=;nG#qS7$#4Q*P7g)&B2yjP@u%6G&wL) zpD#BtFEKr}NDnFmQt>ubm>DDuV*gEnumcmVV7dx(3}MW`L=$!-ox+JF`MH@XP!VUV zn9$sPjra^FP@>tKpV`gA&LHgL>h5nixi(E|vq(}i3sp_uoS4VR zIyrQ%mwe#*32yZjsLX8&3h#>x3DdXwF!Xm0i^zl;!JW91NW@d}^3 zpsaiH@mAT%%5&u>2b8i;e$uMK!>@otvcDDf_3uVa-Yc?W+zTIsArv=Fii<4rZqXLM`iMbKGwe0