diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 2eab4970..17380db7 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -17,6 +17,7 @@ jobs: --style=file \ ISLE/*.cpp ISLE/*.h \ LEGO1/*.cpp LEGO1/*.h \ + LEGO1/mxstl/*.h \ LEGO1/realtime/*.cpp LEGO1/realtime/*.h \ LEGO1/tgl/*.h \ LEGO1/tgl/d3drm/*.cpp LEGO1/tgl/d3drm/*.h \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a60e3d4..ed3c29cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,6 +230,8 @@ if (MINGW) endif() # Additional include directories + +target_include_directories(lego1 PRIVATE "${CMAKE_SOURCE_DIR}/util") target_include_directories(lego1 PUBLIC "${CMAKE_SOURCE_DIR}/3rdparty/vec") target_include_directories(lego1 PRIVATE "${CMAKE_SOURCE_DIR}/3rdparty/flic") target_include_directories(lego1 PRIVATE "${CMAKE_SOURCE_DIR}/3rdparty/smk") @@ -264,6 +266,8 @@ if (ISLE_BUILD_APP) ISLE/define.cpp ) + target_include_directories(isle PRIVATE "${CMAKE_SOURCE_DIR}/util") + # Include LEGO1 headers in ISLE target_include_directories(isle PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1") diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1a698a7d..0c65bc1c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,6 +27,7 @@ This repository currently has only one goal: accuracy to the original executable * [`ISLE`](/ISLE): Decompilation of `ISLE.EXE`. It depends on some code in `LEGO1`. * [`LEGO1`](/LEGO1): Decompilation of `LEGO1.DLL`. This folder contains code from Mindscape's custom in-house engine called **Omni** (file pattern: `mx*`), the LEGO Island-specific extensions for Omni and the game's code (file pattern: `lego*`) as well as several utility libraries developed by Mindscape. * [`tools`](/tools): A set of tools aiding in the decompilation effort. +* [`util`](/util): Utility headers aiding in the decompilation effort. ## Tooling diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 1d4d4641..8d1fe268 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -24,6 +24,10 @@ #include +// Might be static functions of IsleApp +BOOL FindExistingInstance(void); +BOOL StartDirectSound(void); + // FUNCTION: ISLE 0x401000 IsleApp::IsleApp() { @@ -169,9 +173,6 @@ void IsleApp::SetupVideoFlags( } } -BOOL FindExistingInstance(void); -BOOL StartDirectSound(void); - // FUNCTION: ISLE 0x401610 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { @@ -389,52 +390,46 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } return DefWindowProcA(hWnd, uMsg, wParam, lParam); case WM_DISPLAYCHANGE: - if (g_isle && VideoManager() && g_isle->m_fullScreen && VideoManager()->GetDirect3D() && - VideoManager()->GetDirect3D()->GetDeviceModeFinder()) { - int targetWidth = LOWORD(lParam); - int targetHeight = HIWORD(lParam); - int targetDepth = wParam; + if (g_isle && VideoManager() && g_isle->m_fullScreen && VideoManager()->GetDirect3D()) { + if (VideoManager()->GetDirect3D()->GetDeviceModeFinder()) { + int targetDepth = wParam; + int targetWidth = LOWORD(lParam); + int targetHeight = HIWORD(lParam); - 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_waitingForTargetDepth) { + g_waitingForTargetDepth = 0; + g_targetDepth = targetDepth; } + else { + BOOL valid = FALSE; - if (g_rmDisabled) { - if (valid) { - g_reqEnableRMDevice = 1; + if (g_targetWidth == targetWidth && g_targetHeight == targetHeight && + g_targetDepth == targetDepth) { + valid = TRUE; + } + + if (g_rmDisabled) { + if (valid) { + g_reqEnableRMDevice = 1; + } + } + else if (!valid) { + g_rmDisabled = 1; + Lego()->StartTimer(); + VideoManager()->DisableRMDevice(); } - } - else if (!valid) { - g_rmDisabled = 1; - Lego()->StartTimer(); - 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 = c_notificationKeyPress; + keyCode = wParam; break; case WM_MOUSEMOVE: g_mousemoved = 1; @@ -457,6 +452,13 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return 0; } break; + case WM_SETCURSOR: + if (g_isle && (g_isle->m_cursorCurrent == g_isle->m_cursorBusy || + g_isle->m_cursorCurrent == g_isle->m_cursorNo || !g_isle->m_cursorCurrent)) { + SetCursor(g_isle->m_cursorCurrent); + return 0; + } + break; default: return DefWindowProcA(hWnd, uMsg, wParam, lParam); } @@ -812,10 +814,8 @@ inline void IsleApp::Tick(BOOL sleepIfNotNextFrame) } this->m_gameStarted = 1; } - return; } - - if (sleepIfNotNextFrame != 0) + else if (sleepIfNotNextFrame != 0) Sleep(0); } diff --git a/LEGO1/mxatomidcounter.h b/LEGO1/mxatomidcounter.h index c75c2b5c..8fb5ae97 100644 --- a/LEGO1/mxatomidcounter.h +++ b/LEGO1/mxatomidcounter.h @@ -1,7 +1,7 @@ #ifndef MXATOMIDCOUNTER_H #define MXATOMIDCOUNTER_H -#include "compat.h" // STL +#include "mxstl/stlcompat.h" #include "mxstring.h" // Counts the number of existing MxAtomId objects based diff --git a/LEGO1/mxcompositepresenter.h b/LEGO1/mxcompositepresenter.h index 7479a8b7..a506505e 100644 --- a/LEGO1/mxcompositepresenter.h +++ b/LEGO1/mxcompositepresenter.h @@ -1,9 +1,9 @@ #ifndef MXCOMPOSITEPRESENTER_H #define MXCOMPOSITEPRESENTER_H -#include "compat.h" // STL #include "mxactionnotificationparam.h" #include "mxpresenter.h" +#include "mxstl/stlcompat.h" class MxCompositePresenterList : public list {}; diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index bed571f4..2de006d1 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -1,9 +1,9 @@ #ifndef MXDISKSTREAMCONTROLLER_H #define MXDISKSTREAMCONTROLLER_H -#include "compat.h" // STL #include "decomp.h" #include "mxdsbuffer.h" +#include "mxstl/stlcompat.h" #include "mxstreamcontroller.h" #include "mxtypes.h" diff --git a/LEGO1/mxnotificationmanager.h b/LEGO1/mxnotificationmanager.h index a26f3748..9ab9c733 100644 --- a/LEGO1/mxnotificationmanager.h +++ b/LEGO1/mxnotificationmanager.h @@ -1,10 +1,10 @@ #ifndef MXNOTIFICATIONMANAGER_H #define MXNOTIFICATIONMANAGER_H -#include "compat.h" #include "mxcore.h" #include "mxcriticalsection.h" #include "mxnotificationparam.h" +#include "mxstl/stlcompat.h" #include "mxtypes.h" class MxNotification { diff --git a/LEGO1/mxramstreamcontroller.cpp b/LEGO1/mxramstreamcontroller.cpp index e16e6190..f97486c2 100644 --- a/LEGO1/mxramstreamcontroller.cpp +++ b/LEGO1/mxramstreamcontroller.cpp @@ -42,11 +42,19 @@ MxResult MxRAMStreamController::vtable0x20(MxDSAction* p_action) return FAILURE; } -// STUB: LEGO1 0x100c6320 -MxResult MxRAMStreamController::vtable0x24(undefined4 p_unknown) +// FUNCTION: LEGO1 0x100c6320 +MxResult MxRAMStreamController::vtable0x24(MxDSAction* p_action) { - // TODO STUB - return FAILURE; + MxDSAction action; + do { + if (m_action0x60 != NULL) { + delete m_action0x60; + m_action0x60 = NULL; + } + action = *p_action; + MxStreamController::vtable0x24(&action); + } while (m_action0x60 != NULL); + return SUCCESS; } // STUB: LEGO1 0x100d0d80 diff --git a/LEGO1/mxramstreamcontroller.h b/LEGO1/mxramstreamcontroller.h index 26e9a4e1..fad2a80c 100644 --- a/LEGO1/mxramstreamcontroller.h +++ b/LEGO1/mxramstreamcontroller.h @@ -26,7 +26,7 @@ class MxRAMStreamController : public MxStreamController { virtual MxResult Open(const char* p_filename) override; virtual MxResult vtable0x20(MxDSAction* p_action) override; - virtual MxResult vtable0x24(undefined4 p_unknown) override; + virtual MxResult vtable0x24(MxDSAction* p_action) override; private: MxDSBuffer m_buffer; diff --git a/LEGO1/mxstl.h b/LEGO1/mxstl/mxstl.h similarity index 100% rename from LEGO1/mxstl.h rename to LEGO1/mxstl/mxstl.h diff --git a/LEGO1/mxstl/stlcompat.h b/LEGO1/mxstl/stlcompat.h new file mode 100644 index 00000000..bc0076bf --- /dev/null +++ b/LEGO1/mxstl/stlcompat.h @@ -0,0 +1,18 @@ +#ifndef STLCOMPAT_H +#define STLCOMPAT_H + +#include "compat.h" + +#if defined(_MSC_VER) && _MSC_VER <= MSVC420_VERSION +// Disable "nonstandard extension used : 'bool'" warning spam +#pragma warning(disable : 4237) +#include "mxstl.h" +#else +#include +#include +#include +using std::list; +using std::set; +#endif + +#endif // STLCOMPAT_H diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index cdc8eff3..6fafb2c7 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -117,11 +117,20 @@ MxResult MxStreamController::vtable0x20(MxDSAction* p_action) return result; } -// STUB: LEGO1 0x100c1740 -MxResult MxStreamController::vtable0x24(undefined4 p_unknown) +// FUNCTION: LEGO1 0x100c1740 +MxResult MxStreamController::vtable0x24(MxDSAction* p_action) { - // TODO STUB - return FAILURE; + MxAutoLocker locker(&m_criticalSection); + vtable0x30(p_action); + m_action0x60 = m_unkList0x54.Find(p_action, TRUE); + if (m_action0x60 == NULL) { + return FAILURE; + } + else { + p_action->SetUnknown24(m_action0x60->GetUnknown24()); + p_action->SetObjectId(m_action0x60->GetObjectId()); + return FUN_100c1f00(m_action0x60); + } } // FUNCTION: LEGO1 0x100c1800 @@ -153,9 +162,25 @@ MxResult MxStreamController::vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval) return FUN_100c1800(p_action, (p_bufferval / m_provider->GetFileSize()) * m_provider->GetFileSize()); } -// STUB: LEGO1 0x100c1ce0 -MxResult MxStreamController::vtable0x30(undefined4 p_unknown) +// FUNCTION: LEGO1 0x100c1ce0 +MxResult MxStreamController::vtable0x30(MxDSAction* p_unknown) { + MxAutoLocker locker(&m_criticalSection); + MxResult result = FAILURE; + MxDSAction* action = m_unkList0x3c.Find(p_unknown, TRUE); + if (action != NULL) { + MxNextActionDataStart* data = m_nextActionList.Find(action->GetObjectId(), action->GetUnknown24()); + delete action; + delete data; + result = SUCCESS; + } + return result; +} + +// STUB: LEGO1 0x100c1f00 +MxResult MxStreamController::FUN_100c1f00(MxDSAction* p_action) +{ + // TODO return FAILURE; } diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index 80ff9e35..9a763ba1 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -1,13 +1,13 @@ #ifndef MXSTREAMCONTROLLER_H #define MXSTREAMCONTROLLER_H -#include "compat.h" // STL #include "decomp.h" #include "mxatomid.h" #include "mxcore.h" #include "mxcriticalsection.h" #include "mxdsaction.h" #include "mxdsobject.h" +#include "mxstl/stlcompat.h" #include "mxstreamlist.h" #include "mxstreamprovider.h" @@ -36,14 +36,15 @@ class MxStreamController : public MxCore { virtual MxResult vtable0x18(undefined4 p_unknown, undefined4 p_unknown2); // vtable+0x18 virtual MxResult vtable0x1C(undefined4 p_unknown, undefined4 p_unknown2); // vtable+0x1c virtual MxResult vtable0x20(MxDSAction* p_action); // vtable+0x20 - virtual MxResult vtable0x24(undefined4 p_unknown); // vtable+0x24 + virtual MxResult vtable0x24(MxDSAction* p_unknown); // vtable+0x24 MxResult FUN_100c1800(MxDSAction* p_action, MxU32 p_val); virtual MxResult vtable0x28(); // vtable+0x28 virtual MxResult vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval); // vtable+0x2c - virtual MxResult vtable0x30(undefined4 p_unknown); // vtable+0x30 + virtual MxResult vtable0x30(MxDSAction* p_unknown); // vtable+0x30 MxBool FUN_100c20d0(MxDSObject& p_obj); MxResult FUN_100c1a00(MxDSAction* p_action, MxU32 p_bufferval); + MxResult FUN_100c1f00(MxDSAction* p_action); inline MxAtomId& GetAtom() { return atom; }; diff --git a/LEGO1/mxstreamlist.h b/LEGO1/mxstreamlist.h index 46024be5..2a9e7351 100644 --- a/LEGO1/mxstreamlist.h +++ b/LEGO1/mxstreamlist.h @@ -1,10 +1,10 @@ #ifndef MXSTREAMLIST_H #define MXSTREAMLIST_H -#include "compat.h" // STL #include "mxdsaction.h" #include "mxdssubscriber.h" #include "mxnextactiondatastart.h" +#include "mxstl/stlcompat.h" template class MxStreamList : public list {}; diff --git a/LEGO1/mxticklemanager.h b/LEGO1/mxticklemanager.h index b7d90763..85994ef5 100644 --- a/LEGO1/mxticklemanager.h +++ b/LEGO1/mxticklemanager.h @@ -1,8 +1,8 @@ #ifndef MXTICKLEMANAGER_H #define MXTICKLEMANAGER_H -#include "compat.h" #include "mxcore.h" +#include "mxstl/stlcompat.h" #include "mxtypes.h" class MxTickleClient { diff --git a/LEGO1/realtime/matrix.cpp b/LEGO1/realtime/matrix.cpp index 7b2a94b3..3ba63ca5 100644 --- a/LEGO1/realtime/matrix.cpp +++ b/LEGO1/realtime/matrix.cpp @@ -1,7 +1,7 @@ #include "matrix.h" -#include "../decomp.h" +#include "decomp.h" #include "math.h" #include diff --git a/LEGO1/realtime/orientableroi.cpp b/LEGO1/realtime/orientableroi.cpp index 651a1ac7..e03b78cb 100644 --- a/LEGO1/realtime/orientableroi.cpp +++ b/LEGO1/realtime/orientableroi.cpp @@ -1,6 +1,6 @@ #include "orientableroi.h" -#include "../decomp.h" +#include "decomp.h" DECOMP_SIZE_ASSERT(OrientableROI, 0xdc) diff --git a/LEGO1/realtime/roi.h b/LEGO1/realtime/roi.h index 66c17a84..40cff140 100644 --- a/LEGO1/realtime/roi.h +++ b/LEGO1/realtime/roi.h @@ -3,9 +3,9 @@ // ROI stands for Real-time Object Instance. -#include "../compat.h" -#include "../mxstl.h" +#include "../mxstl/stlcompat.h" #include "../realtime/realtime.h" +#include "compat.h" #include "lodlist.h" #include "vector.h" diff --git a/LEGO1/realtime/vector.cpp b/LEGO1/realtime/vector.cpp index 1d41470c..54df74e4 100644 --- a/LEGO1/realtime/vector.cpp +++ b/LEGO1/realtime/vector.cpp @@ -1,7 +1,7 @@ #include "vector.h" -#include "../decomp.h" +#include "decomp.h" #include #include diff --git a/LEGO1/tgl/d3drm/impl.h b/LEGO1/tgl/d3drm/impl.h index bbc7baa0..89894c2d 100644 --- a/LEGO1/tgl/d3drm/impl.h +++ b/LEGO1/tgl/d3drm/impl.h @@ -1,6 +1,6 @@ -#include "../../decomp.h" #include "../tgl.h" +#include "decomp.h" #include diff --git a/LEGO1/viewmanager/viewlodlist.h b/LEGO1/viewmanager/viewlodlist.h index 12817ff9..d695624f 100644 --- a/LEGO1/viewmanager/viewlodlist.h +++ b/LEGO1/viewmanager/viewlodlist.h @@ -1,9 +1,9 @@ #ifndef VIEWLODLIST_H #define VIEWLODLIST_H -#include "../compat.h" #include "../realtime/lodlist.h" #include "assert.h" +#include "compat.h" #pragma warning(disable : 4786) diff --git a/LEGO1/viewmanager/viewroi.cpp b/LEGO1/viewmanager/viewroi.cpp index 47cb71e8..47f340ac 100644 --- a/LEGO1/viewmanager/viewroi.cpp +++ b/LEGO1/viewmanager/viewroi.cpp @@ -1,6 +1,6 @@ #include "viewroi.h" -#include "../decomp.h" +#include "decomp.h" DECOMP_SIZE_ASSERT(ViewROI, 0xe0) diff --git a/LEGO1/compat.h b/util/compat.h similarity index 71% rename from LEGO1/compat.h rename to util/compat.h index 9616b254..c1175cd2 100644 --- a/LEGO1/compat.h +++ b/util/compat.h @@ -1,5 +1,5 @@ -#ifndef ISLECOMPAT_H -#define ISLECOMPAT_H +#ifndef COMPAT_H +#define COMPAT_H // Various macros to enable compiling with other/newer compilers. @@ -11,9 +11,6 @@ #define COMPAT_CONST #endif -// DIsable "nonstandard extension used : 'bool'" warning spam -#pragma warning(disable : 4237) - // Disable "identifier was truncated to '255' characters" warning. // Impossible to avoid this if using STL map or set. // This removes most (but not all) occurrences of the warning. @@ -21,17 +18,6 @@ #define MSVC420_VERSION 1020 -// STL compatibility. -#if defined(_MSC_VER) && _MSC_VER <= MSVC420_VERSION -#include "mxstl.h" -#else -#include -#include -#include -using std::list; -using std::set; -#endif - // We use `override` so newer compilers can tell us our vtables are valid, // however this keyword was added in C++11, so we define it as empty for // compatibility with older compilers. @@ -39,4 +25,4 @@ using std::set; #define override #endif -#endif // ISLECOMPAT_H +#endif // COMPAT_H diff --git a/LEGO1/decomp.h b/util/decomp.h similarity index 100% rename from LEGO1/decomp.h rename to util/decomp.h