diff --git a/ISLE/define.cpp b/ISLE/define.cpp index b5501b08..0a77efd9 100644 --- a/ISLE/define.cpp +++ b/ISLE/define.cpp @@ -28,7 +28,7 @@ int g_targetWidth = 640; int g_targetHeight = 480; // 0x410060 -unsigned int g_targetDepth = 16; +int g_targetDepth = 16; // 0x410064 int g_reqEnableRMDevice = 0; diff --git a/ISLE/define.h b/ISLE/define.h index 27a347b7..41f7de27 100644 --- a/ISLE/define.h +++ b/ISLE/define.h @@ -18,7 +18,7 @@ extern int g_rmDisabled; extern int g_waitingForTargetDepth; extern int g_targetWidth; extern int g_targetHeight; -extern unsigned int g_targetDepth; +extern int g_targetDepth; extern int g_reqEnableRMDevice; extern int g_startupDelay; extern long g_lastFrameTime; diff --git a/ISLE/isle.cpp b/ISLE/isle.cpp index 051572ef..efaa2564 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,459 @@ 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 +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,42 +683,72 @@ 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 (using16bit) { - m_videoParam.flags().Set16Bit(1); - } -} - -// 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; + if (!this->m_windowActive) { + Sleep(0); + return; } - return result; + 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 0x402e80 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 @@ public: 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 @@ public: 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 f45e9529..00000000 --- a/ISLE/main.cpp +++ /dev/null @@ -1,311 +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) -{ - if (!g_isle) { - return DefWindowProcA(hWnd, uMsg, wParam, lParam); - } - - switch (uMsg) { - case WM_PAINT: - return DefWindowProcA(hWnd, WM_PAINT, wParam, lParam); - case WM_ACTIVATE: - return DefWindowProcA(hWnd, WM_ACTIVATE, 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,WM_ACTIVATEAPP,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,WM_CLOSE,wParam,lParam); - case WM_GETMINMAXINFO: - { - MINMAXINFO *mmi = (MINMAXINFO *) lParam; - - mmi->ptMaxTrackSize.x = (g_windowRect.right - g_windowRect.left) + 1; - mmi->ptMaxTrackSize.y = (g_windowRect.bottom - g_windowRect.top) + 1; - mmi->ptMinTrackSize.x = (g_windowRect.right - g_windowRect.left) + 1; - mmi->ptMinTrackSize.y = (g_windowRect.bottom - g_windowRect.top) + 1; - - return 0; - } - case WM_ENTERMENULOOP: - return DefWindowProcA(hWnd,WM_ENTERMENULOOP,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,WM_SYSCOMMAND,wParam,lParam); - case WM_EXITMENULOOP: - return DefWindowProcA(hWnd, WM_EXITMENULOOP, wParam, lParam); - case WM_MOVING: - if (g_isle && g_isle->m_fullScreen) { - GetWindowRect(hWnd, (LPRECT) lParam); - return 0; - } - return DefWindowProcA(hWnd, WM_MOVING, wParam, lParam); - case WM_NCPAINT: - if (g_isle && g_isle->m_fullScreen) { - return 0; - } - return DefWindowProcA(hWnd, WM_NCPAINT, wParam, lParam); - case WM_DISPLAYCHANGE: - if (g_isle && VideoManager() && g_isle->m_fullScreen && VideoManager()->m_unk74 && VideoManager()->m_unk74[0x220]) { - if (!g_waitingForTargetDepth) { - unsigned char valid = FALSE; - if (LOWORD(lParam) == g_targetWidth && HIWORD(lParam) == g_targetHeight && g_targetDepth == wParam) { - valid = TRUE; - } - if (!g_rmDisabled) { - if (!valid) { - g_rmDisabled = 1; - Lego()->vtable38(); - VideoManager()->DisableRMDevice(); - } - } else if (valid) { - g_reqEnableRMDevice = 1; - } - } else { - g_waitingForTargetDepth = 0; - g_targetDepth = wParam; - } - } - return DefWindowProcA(hWnd, WM_DISPLAYCHANGE, wParam, lParam); - case WM_SETCURSOR: - case WM_KEYDOWN: - case WM_MOUSEMOVE: - case WM_TIMER: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case 0x5400: - { - - NotificationId type = NONE; - unsigned char keyCode = 0; - - switch (uMsg) { - 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, WM_KEYDOWN, wParam, lParam); - } - keyCode = wParam; - type = KEYDOWN; - break; - case WM_MOUSEMOVE: - g_mousemoved = 1; - type = MOUSEMOVE; - break; - case WM_TIMER: - type = TIMER; - break; - 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_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; - } - } - - if (g_isle) { - if (InputManager()) { - InputManager()->QueueEvent(type, wParam, LOWORD(lParam), HIWORD(lParam), keyCode); - } - if (g_isle && g_isle->m_drawCursor && type == MOUSEMOVE) { - unsigned short x = LOWORD(lParam); - unsigned short y = HIWORD(lParam); - if (639 < x) { - x = 639; - } - if (479 < y) { - y = 479; - } - VideoManager()->MoveCursor(x,y); - } - } - return 0; - } - } - - return DefWindowProcA(hWnd,uMsg,wParam,lParam); -} \ No newline at end of file diff --git a/LEGO1/mxpalette.cpp b/LEGO1/mxpalette.cpp old mode 100755 new mode 100644 diff --git a/LEGO1/mxunknown100dc6b0.cpp b/LEGO1/mxunknown100dc6b0.cpp old mode 100755 new mode 100644 diff --git a/LEGO1/mxunknown100dc6b0.h b/LEGO1/mxunknown100dc6b0.h old mode 100755 new mode 100644 diff --git a/LEGO1/mxvideomanager.cpp b/LEGO1/mxvideomanager.cpp old mode 100755 new mode 100644 diff --git a/isle.mak b/isle.mak index 7eaf3d48..23583c29 100644 --- a/isle.mak +++ b/isle.mak @@ -311,7 +311,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" @@ -372,7 +371,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) @@ -401,7 +399,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" @@ -464,7 +461,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) @@ -917,6 +913,7 @@ DEP_CPP_MXPAL=\ SOURCE=.\LEGO1\mxioinfo.cpp DEP_CPP_MXIOI=\ + ".\LEGO1\legoinc.h"\ ".\LEGO1\mxioinfo.h"\ @@ -930,6 +927,7 @@ DEP_CPP_MXIOI=\ SOURCE=.\LEGO1\mxdsfile.cpp DEP_CPP_MXDSF=\ + ".\LEGO1\legoinc.h"\ ".\LEGO1\mxbool.h"\ ".\LEGO1\mxcore.h"\ ".\LEGO1\mxdsfile.h"\ @@ -974,19 +972,6 @@ DEP_CPP_MXDSS=\ ################################################################################ # 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 DEP_CPP_ISLE_=\ ".\ISLE\define.h"\ @@ -1048,71 +1033,6 @@ DEP_CPP_ISLE_=\ $(CPP) $(CPP_PROJ) $(SOURCE) -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ISLE\main.cpp -DEP_CPP_MAIN_=\ - ".\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"\ - ".\LEGO1\mxdssource.h"\ - ".\LEGO1\mxeventmanager.h"\ - ".\LEGO1\mxioinfo.h"\ - ".\LEGO1\mxmusicmanager.h"\ - ".\LEGO1\mxnotificationmanager.h"\ - ".\LEGO1\mxobjectfactory.h"\ - ".\LEGO1\mxomni.h"\ - ".\LEGO1\mxomnicreateflags.h"\ - ".\LEGO1\mxomnicreateparam.h"\ - ".\LEGO1\mxomnicreateparambase.h"\ - ".\LEGO1\mxpalette.h"\ - ".\LEGO1\mxrect32.h"\ - ".\LEGO1\mxresult.h"\ - ".\LEGO1\mxsoundmanager.h"\ - ".\LEGO1\mxstreamcontroller.h"\ - ".\LEGO1\mxstreamer.h"\ - ".\LEGO1\mxstring.h"\ - ".\LEGO1\mxticklemanager.h"\ - ".\LEGO1\mxtimer.h"\ - ".\LEGO1\mxtransitionmanager.h"\ - ".\LEGO1\mxunknown100dc6b0.h"\ - ".\LEGO1\mxvariabletable.h"\ - ".\LEGO1\mxvideomanager.h"\ - ".\LEGO1\mxvideoparam.h"\ - ".\LEGO1\mxvideoparamflags.h"\ - ".\LEGO1\viewmanager.h"\ - - -"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - # End Source File ################################################################################ # Begin Source File @@ -1262,18 +1182,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" @@ -1553,6 +1461,32 @@ 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 +DEP_CPP_DEFIN=\ + ".\ISLE\define.h"\ + ".\LEGO1\legoinc.h"\ + + +"$(INTDIR)\define.obj" : $(SOURCE) $(DEP_CPP_DEFIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File # End Target # End Project ################################################################################ diff --git a/isle.mdp b/isle.mdp index 9449bd89..d9512305 100644 Binary files a/isle.mdp and b/isle.mdp differ