From 1fa2fd9737b16b7f12f5ad96d8417c503e8176bd Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Sun, 10 Sep 2023 08:01:39 -0400 Subject: [PATCH 01/87] The IslePathActor's (#113) * pizza: fix type m_unk90 * Initial implementation of a lot of IslePathActor's All IslePathActor's seem to have (for the most part), the same few variables in common, probably some ID. SkateBoard, Pizza and TowTrack seem to be a bit more complicated with additional fields surrounding it. * Add missing ClassName(s) and IsA(s) * Add decomp size asserts * Fix size assertions * Make legopathactor fields protected for now, fix a type in Pizza * Fix TowTrack structure --------- Co-authored-by: Christian Semmler --- LEGO1/ambulance.cpp | 18 ++++++++++++++++-- LEGO1/ambulance.h | 15 ++++++++++++++- LEGO1/bike.cpp | 8 ++++++-- LEGO1/bike.h | 5 ++++- LEGO1/dunebuggy.cpp | 9 +++++++-- LEGO1/dunebuggy.h | 7 ++++++- LEGO1/jetski.cpp | 8 ++++++-- LEGO1/jetski.h | 5 ++++- LEGO1/legopathactor.h | 12 ++++++++---- LEGO1/racecar.cpp | 6 ++++-- LEGO1/racecar.h | 17 +++++++++++++++++ LEGO1/skateboard.cpp | 14 ++++++++++++-- LEGO1/skateboard.h | 17 +++++++++++++++++ LEGO1/towtrack.cpp | 14 ++++++++++++-- LEGO1/towtrack.h | 26 ++++++++++++++++++++++++++ 15 files changed, 159 insertions(+), 22 deletions(-) diff --git a/LEGO1/ambulance.cpp b/LEGO1/ambulance.cpp index 6b5e76ad..707f7a8d 100644 --- a/LEGO1/ambulance.cpp +++ b/LEGO1/ambulance.cpp @@ -1,7 +1,21 @@ #include "ambulance.h" -// OFFSET: LEGO1 0x10035ee0 STUB +#include "decomp.h" + +DECOMP_SIZE_ASSERT(Ambulance, 0x184); + +// OFFSET: LEGO1 0x10035ee0 Ambulance::Ambulance() { - // TODO + this->m_unk168 = 0; + this->m_unk16a = -1; + this->m_unk164 = 0; + this->m_unk16c = 0; + this->m_unk174 = -1; + this->m_unk16e = 0; + this->m_unk178 = -1; + this->m_unk170 = 0; + this->m_unk172 = 0; + this->m_unk13c = 40.0; + this->m_unk17c = 1.0; } \ No newline at end of file diff --git a/LEGO1/ambulance.h b/LEGO1/ambulance.h index dd89af3c..3371830f 100644 --- a/LEGO1/ambulance.h +++ b/LEGO1/ambulance.h @@ -22,7 +22,20 @@ class Ambulance : public IslePathActor { return !strcmp(name, Ambulance::ClassName()) || IslePathActor::IsA(name); } - +private: + // TODO: Ambulance fields + undefined m_unk160[4]; + MxS32 m_unk164; + MxS16 m_unk168; + MxS16 m_unk16a; + MxS16 m_unk16c; + MxS16 m_unk16e; + MxS16 m_unk170; + MxS16 m_unk172; + MxS32 m_unk174; + MxS32 m_unk178; + MxFloat m_unk17c; + undefined m_unk180[4]; }; #endif // AMBULANCE_H diff --git a/LEGO1/bike.cpp b/LEGO1/bike.cpp index ac741a44..217e8c64 100644 --- a/LEGO1/bike.cpp +++ b/LEGO1/bike.cpp @@ -1,8 +1,12 @@ #include "bike.h" -// OFFSET: LEGO1 0x10076670 STUB +DECOMP_SIZE_ASSERT(Bike, 0x164); + +// OFFSET: LEGO1 0x10076670 Bike::Bike() { - // TODO + this->m_unk13c = 20.0; + this->m_unk150 = 3.0; + this->m_unk148 = 1; } diff --git a/LEGO1/bike.h b/LEGO1/bike.h index 8d2de0f1..af8711a5 100644 --- a/LEGO1/bike.h +++ b/LEGO1/bike.h @@ -1,6 +1,7 @@ #ifndef BIKE_H #define BIKE_H +#include "decomp.h" #include "islepathactor.h" // VTABLE 0x100d9808 @@ -22,7 +23,9 @@ class Bike : public IslePathActor { return !strcmp(name, Bike::ClassName()) || IslePathActor::IsA(name); } - +private: + // TODO: Bike fields + undefined m_unk160[4]; }; diff --git a/LEGO1/dunebuggy.cpp b/LEGO1/dunebuggy.cpp index babf21cb..42fd4c37 100644 --- a/LEGO1/dunebuggy.cpp +++ b/LEGO1/dunebuggy.cpp @@ -1,7 +1,12 @@ #include "dunebuggy.h" -// OFFSET: LEGO1 0x10067bb0 STUB +#include "decomp.h" + +DECOMP_SIZE_ASSERT(DuneBuggy, 0x16c); + +// OFFSET: LEGO1 0x10067bb0 DuneBuggy::DuneBuggy() { - // TODO + this->m_unk13c = 25.0; + this->m_unk164 = 1.0; } \ No newline at end of file diff --git a/LEGO1/dunebuggy.h b/LEGO1/dunebuggy.h index 1f89784e..1a083207 100644 --- a/LEGO1/dunebuggy.h +++ b/LEGO1/dunebuggy.h @@ -1,6 +1,7 @@ #ifndef DUNEBUGGY_H #define DUNEBUGGY_H +#include "decomp.h" #include "islepathactor.h" // VTABLE 0x100d8f98 @@ -22,7 +23,11 @@ class DuneBuggy : public IslePathActor { return !strcmp(name, DuneBuggy::ClassName()) || IslePathActor::IsA(name); } - +private: + // TODO: Double check DuneBuggy field types + undefined4 m_unk160; + MxFloat m_unk164; + undefined4 m_unk168; }; #endif // DUNEBUGGY_H diff --git a/LEGO1/jetski.cpp b/LEGO1/jetski.cpp index 50676253..20993cf3 100644 --- a/LEGO1/jetski.cpp +++ b/LEGO1/jetski.cpp @@ -1,7 +1,11 @@ #include "jetski.h" -// OFFSET: LEGO1 0x1007e3b0 STUB +DECOMP_SIZE_ASSERT(Jetski, 0x164); + +// OFFSET: LEGO1 0x1007e3b0 Jetski::Jetski() { - // TODO + this->m_unk13c = 25.0; + this->m_unk150 = 2.0; + this->m_unk148 = 1; } \ No newline at end of file diff --git a/LEGO1/jetski.h b/LEGO1/jetski.h index 7cabea4d..d5de5a76 100644 --- a/LEGO1/jetski.h +++ b/LEGO1/jetski.h @@ -1,6 +1,7 @@ #ifndef JETSKI_H #define JETSKI_H +#include "decomp.h" #include "islepathactor.h" // VTABLE 0x100d9ec8 @@ -22,7 +23,9 @@ class Jetski : public IslePathActor { return !strcmp(name, Jetski::ClassName()) || IslePathActor::IsA(name); } - +private: + // TODO: Jetski fields + undefined m_unk160[4]; }; diff --git a/LEGO1/legopathactor.h b/LEGO1/legopathactor.h index 7e524b08..41c6d843 100644 --- a/LEGO1/legopathactor.h +++ b/LEGO1/legopathactor.h @@ -25,11 +25,15 @@ class LegoPathActor : public LegoActor { return !strcmp(name, LegoPathActor::ClassName()) || LegoActor::IsA(name); } - - // TODO: the types. Pizza needs this as public: +protected: + // TODO: the types undefined unk78[0xc4]; - MxS32 m_unk13c; - undefined unk140[0x14]; + MxFloat m_unk13c; + MxS32 m_unk140; + MxS32 m_unk144; + undefined m_unk148; + MxS32 m_unk14c; + MxFloat m_unk150; }; #endif // LEGOPATHACTOR_H diff --git a/LEGO1/racecar.cpp b/LEGO1/racecar.cpp index 59bb5146..4e4a4a21 100644 --- a/LEGO1/racecar.cpp +++ b/LEGO1/racecar.cpp @@ -1,9 +1,11 @@ #include "racecar.h" -// OFFSET: LEGO1 0x10028200 STUB +DECOMP_SIZE_ASSERT(RaceCar, 0x164); + +// OFFSET: LEGO1 0x10028200 RaceCar::RaceCar() { - // TODO + this->m_unk13c = 40.0; } // OFFSET: LEGO1 0x10028420 STUB diff --git a/LEGO1/racecar.h b/LEGO1/racecar.h index f8bd6ccf..f10d9b62 100644 --- a/LEGO1/racecar.h +++ b/LEGO1/racecar.h @@ -1,6 +1,7 @@ #ifndef RACECAR_H #define RACECAR_H +#include "decomp.h" #include "islepathactor.h" // VTABLE 0x100d6918 @@ -10,6 +11,22 @@ class RaceCar : public IslePathActor public: RaceCar(); virtual ~RaceCar() override; // vtable+0x0 + + // OFFSET: LEGO1 0x10028270 + inline virtual const char *ClassName() const override // vtable+0x0c + { + // 0x100f03e0 + return "RaceCar"; + } + + // OFFSET: LEGO1 0x10028280 + inline virtual MxBool IsA(const char *name) const override // vtable+0x10 + { + return !strcmp(name, RaceCar::ClassName()) || IslePathActor::IsA(name); + } +private: + // TODO: RaceCar fields + undefined m_unk160[4]; }; #endif // RACECAR_H diff --git a/LEGO1/skateboard.cpp b/LEGO1/skateboard.cpp index 42466206..5c5cbf38 100644 --- a/LEGO1/skateboard.cpp +++ b/LEGO1/skateboard.cpp @@ -1,7 +1,17 @@ #include "skateboard.h" +#include "mxomni.h" -// OFFSET: LEGO1 0x1000fd40 STUB +#include "decomp.h" + +DECOMP_SIZE_ASSERT(SkateBoard, 0x168); + +// OFFSET: LEGO1 0x1000fd40 SkateBoard::SkateBoard() { - // TODO + this->m_unk160 = 0; + this->m_unk13c = 15.0; + this->m_unk150 = 3.5; + this->m_unk148 = 1; + + NotificationManager()->Register(this); } diff --git a/LEGO1/skateboard.h b/LEGO1/skateboard.h index f290dc7b..e7fb1fc8 100644 --- a/LEGO1/skateboard.h +++ b/LEGO1/skateboard.h @@ -1,6 +1,7 @@ #ifndef SKATEBOARD_H #define SKATEBOARD_H +#include "decomp.h" #include "islepathactor.h" // VTABLE 0x100d55f0 @@ -10,6 +11,22 @@ class SkateBoard : public IslePathActor public: SkateBoard(); + // OFFSET: LEGO1 0x1000fdd0 + inline virtual const char *ClassName() const override // vtable+0x0c + { + // 0x100f041c + return "SkateBoard"; + } + + // OFFSET: LEGO1 0x1000fde0 + inline virtual MxBool IsA(const char *name) const override // vtable+0x10 + { + return !strcmp(name, SkateBoard::ClassName()) || IslePathActor::IsA(name); + } +private: + // TODO: SkateBoard types + undefined m_unk160; + undefined m_unk161[0x7]; }; #endif // SKATEBOARD_H diff --git a/LEGO1/towtrack.cpp b/LEGO1/towtrack.cpp index 90d3d018..3b7a9264 100644 --- a/LEGO1/towtrack.cpp +++ b/LEGO1/towtrack.cpp @@ -1,7 +1,17 @@ #include "towtrack.h" -// OFFSET: LEGO1 0x1004c720 STUB +DECOMP_SIZE_ASSERT(TowTrack, 0x180); + +// OFFSET: LEGO1 0x1004c720 TowTrack::TowTrack() { - // TODO + this->m_unk168 = 0; + this->m_unk16a = -1; + this->m_unk164 = 0; + this->m_unk16c = 0; + this->m_unk170 = -1; + this->m_unk16e = 0; + this->m_unk174 = -1; + this->m_unk13c = 40.0; + this->m_unk178 = 1.0; } diff --git a/LEGO1/towtrack.h b/LEGO1/towtrack.h index 95e6885a..7263ab3a 100644 --- a/LEGO1/towtrack.h +++ b/LEGO1/towtrack.h @@ -1,6 +1,7 @@ #ifndef TOWTRACK_H #define TOWTRACK_H +#include "decomp.h" #include "islepathactor.h" // VTABLE 0x100d7ee0 @@ -10,6 +11,31 @@ class TowTrack : public IslePathActor public: TowTrack(); + // OFFSET: LEGO1 0x1004c7c0 + inline virtual const char *ClassName() const override // vtable+0x0c + { + // 0x100f03b8 + return "TowTrack"; + } + + // OFFSET: LEGO1 0x1004c7d0 + inline virtual MxBool IsA(const char *name) const override // vtable+0x10 + { + return !strcmp(name, TowTrack::ClassName()) || IslePathActor::IsA(name); + } + +private: + // TODO: TowTrack field types + undefined m_unk154[4]; + MxS32 m_unk164; + MxS16 m_unk168; + MxS16 m_unk16a; + MxS16 m_unk16c; + MxS16 m_unk16e; + MxS32 m_unk170; + MxS32 m_unk174; + MxFloat m_unk178; + undefined4 m_unk17c; }; From dc18b5d9c11386cfca27799bed52826959f3c73c Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Sun, 10 Sep 2023 08:56:16 -0400 Subject: [PATCH 02/87] MxDirect3D (#114) * MxDirect3D Constructor * Implement MxDirect3D::Clear (not yet matching) * Match MxDirect3D::Clear * Building out MxDirect3D, link dxguid, add size asserts * Move a few things around on the Enumerate context obj * remove dupe mxdirect3d * Match BuildErrorString and _DoEnumerate * Fix style --------- Co-authored-by: Christian Semmler Co-authored-by: disinvite --- CMakeLists.txt | 7 +- LEGO1/mxdirect3d.cpp | 191 +++++++++++++++++++++++++++++++++++++++++ LEGO1/mxdirect3d.h | 59 ++++++++++++- LEGO1/mxdirectdraw.cpp | 8 +- LEGO1/mxdirectdraw.h | 7 +- 5 files changed, 262 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1eb41a6d..f72f83e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,9 +46,9 @@ add_library(lego1 SHARED LEGO1/jukeboxentity.cpp LEGO1/jukeboxstate.cpp LEGO1/legoact2state.cpp - LEGO1/legoactor.cpp LEGO1/legoactioncontrolpresenter.cpp LEGO1/legoactor.cpp + LEGO1/legoactor.cpp LEGO1/legoanimactor.cpp LEGO1/legoanimationmanager.cpp LEGO1/legoanimmmpresenter.cpp @@ -102,6 +102,7 @@ add_library(lego1 SHARED LEGO1/mxcontrolpresenter.cpp LEGO1/mxcore.cpp LEGO1/mxcriticalsection.cpp + LEGO1/mxdirect3d.cpp LEGO1/mxdirectdraw.cpp LEGO1/mxdiskstreamcontroller.cpp LEGO1/mxdiskstreamprovider.cpp @@ -118,10 +119,10 @@ add_library(lego1 SHARED LEGO1/mxdsparallelaction.cpp LEGO1/mxdsselectaction.cpp LEGO1/mxdsserialaction.cpp - LEGO1/mxdsstreamingaction.cpp LEGO1/mxdssound.cpp LEGO1/mxdssource.cpp LEGO1/mxdsstill.cpp + LEGO1/mxdsstreamingaction.cpp LEGO1/mxdssubscriber.cpp LEGO1/mxentity.cpp LEGO1/mxeventmanager.cpp @@ -205,7 +206,7 @@ if (ISLE_USE_DX5) endif() # Link libraries -target_link_libraries(lego1 PRIVATE ddraw dsound winmm) +target_link_libraries(lego1 PRIVATE ddraw dsound dxguid winmm) # Make sure filenames are ALL CAPS set_property(TARGET lego1 PROPERTY OUTPUT_NAME LEGO1) diff --git a/LEGO1/mxdirect3d.cpp b/LEGO1/mxdirect3d.cpp index e69de29b..6d6a43e3 100644 --- a/LEGO1/mxdirect3d.cpp +++ b/LEGO1/mxdirect3d.cpp @@ -0,0 +1,191 @@ +#include "mxdirect3d.h" +#include // for vsprintf + +DECOMP_SIZE_ASSERT(MxDirect3D, 0x894); +DECOMP_SIZE_ASSERT(MxDeviceModeFinder, 0xe4); +DECOMP_SIZE_ASSERT(MxDeviceEnumerate, 0x198); + +// OFFSET: LEGO1 0x1009b0a0 +MxDirect3D::MxDirect3D() +{ + this->m_pDirect3d = NULL; + this->m_pDirect3dDevice = NULL; + this->m_unk88c = NULL; + this->m_pDeviceModeFinder = NULL; +} + +// OFFSET: LEGO1 0x1009b140 +MxDirect3D::~MxDirect3D() +{ + Destroy(); +} + +// OFFSET: LEGO1 0x1009b1a0 +BOOL MxDirect3D::Create( + HWND hWnd, + BOOL fullscreen_1, + BOOL surface_fullscreen, + BOOL onlySystemMemory, + int width, + int height, + int bpp, + const PALETTEENTRY* pPaletteEntries, + int paletteEntryCount) +{ + BOOL success = FALSE; + + BOOL ret = MxDirectDraw::Create(hWnd, fullscreen_1, surface_fullscreen, + onlySystemMemory, width, height, bpp, + pPaletteEntries, paletteEntryCount); + + if (ret && CreateIDirect3D() && D3DSetMode()) + success = TRUE; + + if (!success) + FUN_1009D920(); + + return success; +} + +// OFFSET: LEGO1 0x1009b210 +void MxDirect3D::Destroy() +{ + if (this->m_pDirect3dDevice) { + this->m_pDirect3dDevice->Release(); + this->m_pDirect3dDevice = NULL; + } + + if (this->m_pDirect3d) { + this->m_pDirect3d->Release(); + this->m_pDirect3d = NULL; + } + + if (this->m_pDeviceModeFinder) { + delete m_pDeviceModeFinder; + this->m_pDeviceModeFinder = NULL; + } + + // This should get deleted by MxDirectDraw::Destroy + if (m_pCurrentDeviceModesList) { + // delete m_pCurrentDeviceModesList; // missing? + m_pCurrentDeviceModesList = NULL; + } + + MxDirectDraw::Destroy(); +} + +// OFFSET: LEGO1 0x1009b290 +void MxDirect3D::Clear() +{ + if(this->m_pDirect3dDevice) { + this->m_pDirect3dDevice->Release(); + this->m_pDirect3dDevice = NULL; + } + if(this->m_pDirect3d) { + this->m_pDirect3d->Release(); + this->m_pDirect3d = NULL; + } + MxDirectDraw::DestroyButNotDirectDraw(); +} + +// OFFSET: LEGO1 0x1009b2d0 +BOOL MxDirect3D::CreateIDirect3D() +{ + MxResult ret = IDirect3D_QueryInterface(m_pDirectDraw, + IID_IDirect3D2, + (LPVOID*)&m_pDirect3d); + + if (ret) { + Error("Creation of IDirect3D failed", ret); + return FALSE; + } + + return TRUE; +} + +// OFFSET: LEGO1 0x1009b310 STUB +BOOL MxDirect3D::D3DSetMode() +{ + // TODO + //if (m_pDeviceModeFinder) + Error("This device cannot support the current display mode", 0); + OutputDebugString("MxDirect3D::D3DSetMode() front lock failed\n"); + OutputDebugString("MxDirect3D::D3DSetMode() back lock failed\n"); + return TRUE; +} + +// OFFSET: LEGO1 0x1009b8b0 +MxDeviceModeFinder::MxDeviceModeFinder() +{ + memset(this, 0, sizeof(*this)); +} + +// OFFSET: LEGO1 0x1009b8d0 +MxDeviceModeFinder::~MxDeviceModeFinder() +{ + if (m_deviceInfo) { + delete m_deviceInfo; + m_deviceInfo = NULL; + } +} + +// OFFSET: LEGO1 0x1009c070 STUB +BOOL MxDeviceEnumerate::FUN_1009c070() +{ + // TODO + // HRESULT ret = DirectDrawCreate(); + HRESULT ret = 0; + if (ret) { + MxDirect3D::BuildErrorString("GetCaps failed: %s\n", + EnumerateErrorToString(ret)); + } + //IDirect3D2_EnumDevices + return TRUE; +} + +// OFFSET: LEGO1 0x1009c4c0 +void MxDirect3D::BuildErrorString(const char *p_format, ...) +{ + va_list args; + char buf[512]; + + va_start(args, p_format); + vsprintf(buf, p_format, args); + va_end(args); + + OutputDebugString(buf); +} + +// OFFSET: LEGO1 0x1009c6c0 +MxResult MxDeviceEnumerate::_DoEnumerate() +{ + // TODO: what does ECX refer to in this context? + if (m_unk010_flag) + return FAILURE; + + HRESULT ret = DirectDrawEnumerate(EnumerateCallback, this); + if (ret) { + MxDirect3D::BuildErrorString("DirectDrawEnumerate returned error %s\n", + EnumerateErrorToString(ret)); + return FAILURE; + } + + m_unk010_flag = TRUE; + return SUCCESS; +} + +// OFFSET: LEGO1 0x1009c710 STUB +BOOL FAR PASCAL EnumerateCallback(GUID FAR *, LPSTR, LPSTR, LPVOID) +{ + // TODO + return FALSE; +} + +// OFFSET: LEGO1 0x1009c730 STUB +char *MxDeviceEnumerate::EnumerateErrorToString(HRESULT p_error) +{ + // TODO: This is a list of error messages, similar to the function in + // MxDirectDraw, except that this one now contains the Direct3D errors. + // Probably just copied from a sample file in the dx5 sdk. + return ""; +} diff --git a/LEGO1/mxdirect3d.h b/LEGO1/mxdirect3d.h index ecc1f0aa..03e9f1ac 100644 --- a/LEGO1/mxdirect3d.h +++ b/LEGO1/mxdirect3d.h @@ -2,24 +2,77 @@ #define MXDIRECT3D_H #include "mxdirectdraw.h" +#include "mxtypes.h" #include "decomp.h" #include -class MxDeviceModeFinder; +// SIZE 0xe4 +class MxDeviceModeFinder +{ +public: + MxDeviceModeFinder(); + ~MxDeviceModeFinder(); + undefined4 m_unknown[56]; + MxDirectDraw::DeviceModesInfo *m_deviceInfo; // +0xe0 +}; + +// VTABLE 0x100db814 (or 0x100d9cc8?) +// SIZE 0x198 +class MxDeviceEnumerate +{ +public: + MxDeviceEnumerate(); + virtual MxResult _DoEnumerate(); + BOOL FUN_1009c070(); + + char *EnumerateErrorToString(HRESULT p_error); + + undefined4 m_unk004; + undefined4 m_unk008; + undefined4 m_unk00c; + MxBool m_unk010_flag; // +0x10 + + undefined4 m_unknown[97]; +}; + +// VTABLE 0x100db800 // SIZE 0x894 class MxDirect3D : public MxDirectDraw { public: + MxDirect3D(); + + void Clear(); inline MxDeviceModeFinder *GetDeviceModeFinder() { return this->m_pDeviceModeFinder; }; + virtual ~MxDirect3D(); + virtual BOOL Create( + HWND hWnd, + BOOL fullscreen_1, + BOOL surface_fullscreen, + BOOL onlySystemMemory, + int width, + int height, + int bpp, + const PALETTEENTRY* pPaletteEntries, + int paletteEntryCount); + virtual void Destroy(); + + BOOL CreateIDirect3D(); + BOOL D3DSetMode(); + + static void BuildErrorString(const char *, ...); + private: - MxDeviceModeFinder *m_pDeviceModeFinder; - IDirect3D *m_pDirect3d; + MxDeviceModeFinder *m_pDeviceModeFinder; // +0x880 + IDirect3D *m_pDirect3d; // +0x884 IDirect3DDevice *m_pDirect3dDevice; undefined4 m_unk88c; undefined4 m_unk890; }; +BOOL FAR PASCAL EnumerateCallback(GUID FAR *, LPSTR, LPSTR, LPVOID); + #endif // MXDIRECT3D_H \ No newline at end of file diff --git a/LEGO1/mxdirectdraw.cpp b/LEGO1/mxdirectdraw.cpp index 625a6fae..099e9bc6 100644 --- a/LEGO1/mxdirectdraw.cpp +++ b/LEGO1/mxdirectdraw.cpp @@ -1,8 +1,8 @@ - #include "mxdirectdraw.h" #include "decomp.h" DECOMP_SIZE_ASSERT(MxDirectDraw, 0x880); +DECOMP_SIZE_ASSERT(MxDirectDraw::DeviceModesInfo, 0x17c); #ifndef DDSCAPS_3DDEVICE #define DDSCAPS_3DDEVICE 0x00002000l @@ -30,6 +30,12 @@ void EnableResizing(HWND hwnd, BOOL flag) } } +// OFFSET: LEGO1 0x1009efb0 +MxDirectDraw::DeviceModesInfo::DeviceModesInfo() +{ + memset(this, 0, sizeof(*this)); +} + // OFFSET: LEGO1 0x1009EFD0 MxDirectDraw::DeviceModesInfo::~DeviceModesInfo() { diff --git a/LEGO1/mxdirectdraw.h b/LEGO1/mxdirectdraw.h index 3e2c710a..8cee9477 100644 --- a/LEGO1/mxdirectdraw.h +++ b/LEGO1/mxdirectdraw.h @@ -1,4 +1,3 @@ - #ifndef MXDIRECTDRAW_H #define MXDIRECTDRAW_H @@ -7,6 +6,7 @@ extern BOOL g_is_PALETTEINDEXED8; +// VTABLE 0x100db818 // SIZE 0x880 class MxDirectDraw { @@ -37,11 +37,12 @@ class MxDirectDraw DDCAPS m_ddcaps; void* a_178; + DeviceModesInfo(); ~DeviceModesInfo(); }; -private: +protected: BOOL m_bOnlySoftRender; BOOL m_bFlipSurfaces; IDirectDraw* m_pDirectDraw; @@ -94,7 +95,7 @@ class MxDirectDraw virtual void DestroyButNotDirectDraw(); virtual const char* ErrorToString(HRESULT error); -private: +protected: BOOL CacheOriginalPaletteEntries(); HRESULT CreateDDSurface( LPDDSURFACEDESC a2, From 3e7cb6a7a8140064455c27574c7f5d43642a27b1 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Mon, 11 Sep 2023 13:43:55 -0400 Subject: [PATCH 03/87] Init functions in MxMediaPresenter and LegoPalettePresenter (#121) * Match MxMediaPresenter::Init * LegoPalettePresenter::Init() * LegoPalettePresenter: for now, use undefined4 type --- LEGO1/legopalettepresenter.cpp | 6 ++++-- LEGO1/legopalettepresenter.h | 2 ++ LEGO1/mxmediapresenter.cpp | 7 +++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/LEGO1/legopalettepresenter.cpp b/LEGO1/legopalettepresenter.cpp index 07b9cb99..575ada4a 100644 --- a/LEGO1/legopalettepresenter.cpp +++ b/LEGO1/legopalettepresenter.cpp @@ -1,5 +1,7 @@ #include "legopalettepresenter.h" +DECOMP_SIZE_ASSERT(LegoPalettePresenter, 0x68) + // OFFSET: LEGO1 0x10079e50 LegoPalettePresenter::LegoPalettePresenter() { @@ -12,8 +14,8 @@ LegoPalettePresenter::~LegoPalettePresenter() // TODO } -// OFFSET: LEGO1 0x1007a0d0 STUB +// OFFSET: LEGO1 0x1007a0d0 void LegoPalettePresenter::Init() { - // TODO + this->m_unk64 = 0; } diff --git a/LEGO1/legopalettepresenter.h b/LEGO1/legopalettepresenter.h index d5fbefba..4cdda5ab 100644 --- a/LEGO1/legopalettepresenter.h +++ b/LEGO1/legopalettepresenter.h @@ -1,6 +1,7 @@ #ifndef LEGOPALETTEPRESENTER_H #define LEGOPALETTEPRESENTER_H +#include "decomp.h" #include "mxvideopresenter.h" // VTABLE 0x100d9aa0 @@ -27,6 +28,7 @@ class LegoPalettePresenter : public MxVideoPresenter private: void Init(); + undefined4 m_unk64; }; diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index 58c068ac..31e68abc 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -9,8 +9,11 @@ MxLong MxMediaPresenter::Tickle() return 0; } -// OFFSET: LEGO1 0x100b54e0 STUB +// OFFSET: LEGO1 0x100b54e0 void MxMediaPresenter::Init() { - // TODO + this->m_unk40 = NULL; + this->m_unk44 = NULL; + this->m_unk48 = NULL; + this->m_unk4c = NULL; } From 89f66e4e0eda81b1c212cca74416f2ada7e01430 Mon Sep 17 00:00:00 2001 From: MS Date: Wed, 13 Sep 2023 03:44:03 -0400 Subject: [PATCH 04/87] MxPresenter::ParseExtra (#123) * MxPresenter::ParseExtra and surrounding functions * Named extra data is MxDSAction, added Parsed flag to enum --- LEGO1/legoomni.cpp | 36 +++++++++++++++++++++++++++ LEGO1/legoomni.h | 1 + LEGO1/mxdsaction.cpp | 52 +++++++++++++++++++-------------------- LEGO1/mxdsaction.h | 10 +++++--- LEGO1/mxomni.cpp | 49 +++++++++++++++++++++++++++++++++++++ LEGO1/mxomni.h | 8 ++++++ LEGO1/mxpresenter.cpp | 57 ++++++++++++++++++++++++++++++++++++++++--- LEGO1/mxpresenter.h | 4 ++- 8 files changed, 184 insertions(+), 33 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index b5cbca8e..e5574058 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -43,6 +43,42 @@ void MakeSourceName(char *, const char *) // TODO } +// OFFSET: LEGO1 0x100b7050 +MxBool KeyValueStringParse(char *p_outputValue, char *p_key, char *p_source) +{ + MxBool didMatch = FALSE; + + MxS16 len = strlen(p_source); + char *temp = new char[len + 1]; + strcpy(temp, p_source); + + char *token = strtok(temp, ", \t\r\n:"); + while (token) { + len -= (strlen(token) + 1); + + if (strcmpi(token, p_key) == 0) { + if (p_outputValue && len > 0) { + char *cur = &token[strlen(p_key)]; + cur++; + while (*cur != ',') { + if (*cur == ' ' || *cur == '\0' || *cur == '\t' || *cur == '\n' || *cur == '\r') + break; + *p_outputValue++ = *cur++; + } + *p_outputValue = '\0'; + } + + didMatch = TRUE; + break; + } + + token = strtok(NULL, ", \t\r\n:"); + } + + delete[] temp; + return didMatch; +} + // OFFSET: LEGO1 0x100b7210 void SetOmniUserMessage(void (*p_userMsg)(const char *,int)) { diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 0ba27cf2..485da46c 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -113,5 +113,6 @@ __declspec(dllexport) MxLong Start(MxDSAction *a); LegoBuildingManager* BuildingManager(); Isle* GetIsle(); LegoPlantManager* PlantManager(); +MxBool KeyValueStringParse(char *, char *, char *); #endif // LEGOOMNI_H diff --git a/LEGO1/mxdsaction.cpp b/LEGO1/mxdsaction.cpp index e9b65037..cccea39c 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -13,8 +13,8 @@ MxDSAction::MxDSAction() { this->m_flags = 32; this->m_startTime = INT_MIN; - this->m_unkData = NULL; - this->m_unkLength = 0; + this->m_extraData = NULL; + this->m_extraLength = 0; this->m_duration = INT_MIN; this->m_loopCount = -1; @@ -44,7 +44,7 @@ MxDSAction::MxDSAction() // OFFSET: LEGO1 0x100ada80 MxDSAction::~MxDSAction() { - delete[] this->m_unkData; + delete[] this->m_extraData; } // OFFSET: LEGO1 0x100adaf0 @@ -60,7 +60,7 @@ void MxDSAction::CopyFrom(MxDSAction &p_dsAction) this->m_direction.CopyFrom(p_dsAction.m_direction); this->m_up.CopyFrom(p_dsAction.m_up); - AppendData(p_dsAction.m_unkLength, p_dsAction.m_unkData); + AppendData(p_dsAction.m_extraLength, p_dsAction.m_extraData); this->m_unk84 = p_dsAction.m_unk84; this->m_unk88 = p_dsAction.m_unk88; this->m_omni = p_dsAction.m_omni; @@ -83,7 +83,7 @@ MxU32 MxDSAction::GetSizeOnDisk() { MxU32 totalSizeOnDisk; - totalSizeOnDisk = MxDSObject::GetSizeOnDisk() + 90 + this->m_unkLength; + totalSizeOnDisk = MxDSObject::GetSizeOnDisk() + 90 + this->m_extraLength; this->m_sizeOnDisk = totalSizeOnDisk - MxDSObject::GetSizeOnDisk(); return totalSizeOnDisk; @@ -186,13 +186,13 @@ void MxDSAction::MergeFrom(MxDSAction &p_dsAction) this->m_up[2] = p_dsAction.m_up[2]; // TODO - MxU16 unkLength = p_dsAction.m_unkLength; - char *unkData = p_dsAction.m_unkData; - if (unkLength && unkData) { - if (!this->m_unkData || !strncmp("XXX", this->m_unkData, 3)) { - delete[] this->m_unkData; - this->m_unkLength = 0; - AppendData(unkLength, unkData); + MxU16 extraLength = p_dsAction.m_extraLength; + char *extraData = p_dsAction.m_extraData; + if (extraLength && extraData) { + if (!this->m_extraData || !strncmp("XXX", this->m_extraData, 3)) { + delete[] this->m_extraData; + this->m_extraLength = 0; + AppendData(extraLength, extraData); } } } @@ -222,29 +222,29 @@ MxLong MxDSAction::GetCurrentTime() } // OFFSET: LEGO1 0x100ade60 -void MxDSAction::AppendData(MxU16 p_unkLength, const char *p_unkData) +void MxDSAction::AppendData(MxU16 p_extraLength, const char *p_extraData) { - if (this->m_unkData == p_unkData || !p_unkData) + if (this->m_extraData == p_extraData || !p_extraData) return; - if (this->m_unkLength) { - char *concat = new char[p_unkLength + this->m_unkLength + sizeof(g_unkSep)]; - memcpy(concat, this->m_unkData, this->m_unkLength); + if (this->m_extraLength) { + char *concat = new char[p_extraLength + this->m_extraLength + sizeof(g_unkSep)]; + memcpy(concat, this->m_extraData, this->m_extraLength); - *(MxU16*) &concat[this->m_unkLength] = g_unkSep; - memcpy(&concat[this->m_unkLength + sizeof(g_unkSep)], p_unkData, p_unkLength); + *(MxU16*) &concat[this->m_extraLength] = g_unkSep; + memcpy(&concat[this->m_extraLength + sizeof(g_unkSep)], p_extraData, p_extraLength); - this->m_unkLength += p_unkLength + sizeof(g_unkSep); - delete[] this->m_unkData; - this->m_unkData = concat; + this->m_extraLength += p_extraLength + sizeof(g_unkSep); + delete[] this->m_extraData; + this->m_extraData = concat; } else { - char *copy = new char[p_unkLength]; - this->m_unkData = copy; + char *copy = new char[p_extraLength]; + this->m_extraData = copy; if (copy) { - this->m_unkLength = p_unkLength; - memcpy(copy, p_unkData, p_unkLength); + this->m_extraLength = p_extraLength; + memcpy(copy, p_extraData, p_extraLength); } } } diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index a85e6494..11388c0f 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -13,6 +13,7 @@ class MxDSAction : public MxDSObject enum { Flag_Enabled = 0x20, + Flag_Parsed = 0x80, }; __declspec(dllexport) MxDSAction(); @@ -45,10 +46,13 @@ class MxDSAction : public MxDSObject virtual MxLong GetSomeTimingField(); // vtable+3c; virtual MxLong GetCurrentTime(); // vtable+40; - void AppendData(MxU16 p_unkLength, const char *p_unkData); + void AppendData(MxU16 p_extraLength, const char *p_extraData); inline MxU32 GetFlags() { return this->m_flags; } inline void SetFlags(MxU32 m_flags) { this->m_flags = m_flags; } + inline char *GetExtraData() { return m_extraData; } + inline MxU16 GetExtraLength() const { return m_extraLength; } + inline void SetOmni(MxOmni *p_omni) { m_omni = p_omni; } private: MxU32 m_sizeOnDisk; @@ -63,8 +67,8 @@ class MxDSAction : public MxDSObject MxVector3Data m_location; MxVector3Data m_direction; MxVector3Data m_up; - char *m_unkData; - MxU16 m_unkLength; + char *m_extraData; + MxU16 m_extraLength; undefined4 m_unk84; undefined4 m_unk88; MxOmni *m_omni; // 0x8c diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 4048a0b5..446ac4f9 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -42,6 +42,55 @@ void MxOmni::Init() m_unk64 = NULL; } +// OFFSET: LEGO1 0x100b0090 STUB +void MxOmni::vtable0x20() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b00c0 STUB +void MxOmni::DeleteObject() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b09a0 STUB +void MxOmni::DoesEntityExist() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b00e0 STUB +void MxOmni::vtable0x2c() +{ + // TODO +} + +// OFFSET: LEGO1 0x100aefb0 STUB +int MxOmni::vtable0x30(char*, int, MxCore*) +{ + // TODO + return 0; +} + +// OFFSET: LEGO1 0x100aefc0 STUB +void MxOmni::NotifyCurrentEntity() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b09d0 STUB +void MxOmni::StartTimer() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b0a00 STUB +void MxOmni::vtable0x3c() +{ + // TODO +} + // OFFSET: LEGO1 0x100b0690 void MxOmni::DestroyInstance() { diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index bbaf4cb0..8cacc5fc 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -37,6 +37,14 @@ class MxOmni : public MxCore virtual void Init(); // vtable+14 virtual MxResult Create(MxOmniCreateParam &p); // vtable+18 virtual void Destroy(); // vtable+1c + virtual void vtable0x20(); // vtable+20 + virtual void DeleteObject(); // vtable+24 + virtual void DoesEntityExist(); // vtable+28 + virtual void vtable0x2c(); // vtable+2c + virtual int vtable0x30(char*, int, MxCore*); // vtable+30 + virtual void NotifyCurrentEntity(); // vtable+34 + virtual void StartTimer(); // vtable+38 + virtual void vtable0x3c(); // vtable+3c static void SetInstance(MxOmni* instance); HWND GetWindowHandle() const { return this->m_windowHandle; } MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; } diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 5fbdb8e4..56688233 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -1,26 +1,77 @@ #include "mxpresenter.h" #include "mxautolocker.h" +#include "mxparam.h" +#include "legoomni.h" +#include #include "decomp.h" DECOMP_SIZE_ASSERT(MxPresenter, 0x40); +// 0x10101eac +char *g_parseExtraTokens = ":;"; + +// 0x10101edc +char *g_strWORLD = "WORLD"; + // OFFSET: LEGO1 0x100b4d50 void MxPresenter::Init() { m_currentTickleState = TickleState_Idle; m_action = NULL; m_unk0x18 = 0; - m_unk0x3c = 0; + m_unkPresenter = NULL; m_previousTickleStates = 0; m_unk0x10 = 0; m_unk0x14 = 0; } -// OFFSET: LEGO1 0x100b4fc0 STUB +// OFFSET: LEGO1 0x100b4fc0 void MxPresenter::ParseExtra() { - // TODO + + MxAutoLocker lock(&m_criticalSection); + MxU32 len = m_action->GetExtraLength(); + char *extraData = m_action->GetExtraData(); + + if (len) { + len &= MAXWORD; + char extraCopy[512]; + memcpy(extraCopy, extraData, len); + extraCopy[len] = '\0'; + + char t_worldValue[512]; + if (KeyValueStringParse(t_worldValue, g_strWORLD, extraCopy)) { + char *token = strtok(t_worldValue, g_parseExtraTokens); + char t_token[256]; + strcpy(t_token, token); + + token = strtok(NULL, g_parseExtraTokens); + int val = token ? atoi(token) : 0; + + int result = MxOmni::GetInstance()->vtable0x30(t_token, val, this); + + m_action->SetFlags(m_action->GetFlags() | MxDSAction::Flag_Parsed); + + if (result) + SendTo_unkPresenter(MxOmni::GetInstance()); + + } + } +} + +// OFFSET: LEGO1 0x100b5120 +void MxPresenter::SendTo_unkPresenter(MxOmni *p_omni) +{ + if (m_unkPresenter) { + MxAutoLocker lock(&m_criticalSection); + + // TOOD: magic number used for notification type. replace with enum + NotificationManager()->Send(m_unkPresenter, &MxParam(5, this)); + + m_action->SetOmni(p_omni ? p_omni : MxOmni::GetInstance()); + m_unkPresenter = NULL; + } } // OFFSET: LEGO1 0x1000bf00 diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 6f50984e..4b8659ec 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -4,6 +4,7 @@ #include "mxcore.h" #include "mxdsaction.h" #include "mxcriticalsection.h" +#include "mxomni.h" #include "decomp.h" @@ -68,6 +69,7 @@ class MxPresenter : public MxCore protected: __declspec(dllexport) void Init(); + void SendTo_unkPresenter(MxOmni *); private: MxS32 m_currentTickleState; // 0x8 @@ -77,7 +79,7 @@ class MxPresenter : public MxCore undefined4 m_unk0x18; MxDSAction* m_action; // 0 MxCriticalSection m_criticalSection; - undefined4 m_unk0x3c; + MxPresenter *m_unkPresenter; // 0x3c }; #endif // MXPRESENTER_H From b1a2aeaed6ccbebfd94f137433cf6480feaf276b Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 13 Sep 2023 10:39:35 -0400 Subject: [PATCH 05/87] Print recompiled address when using --verbose --- tools/reccmp/reccmp.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/reccmp/reccmp.py b/tools/reccmp/reccmp.py index 1beec5dd..113dea2c 100755 --- a/tools/reccmp/reccmp.py +++ b/tools/reccmp/reccmp.py @@ -463,11 +463,12 @@ def can_resolve_register_differences(original_asm, new_asm): else: percenttext += colorama.Fore.RED + "*" + colorama.Style.RESET_ALL + if args.print_rec_addr: + addrs = '%s / %s' % (hex(addr), hex(recinfo.addr)) + else: + addrs = hex(addr) + if not verbose: - if args.print_rec_addr: - addrs = '%s / %s' % (hex(addr), hex(recinfo.addr)) - else: - addrs = hex(addr) print(' %s (%s) is %s similar to the original' % (recinfo.name, addrs, percenttext)) function_count += 1 @@ -477,16 +478,16 @@ def can_resolve_register_differences(original_asm, new_asm): if recinfo.size: udiff = difflib.unified_diff(origasm, recompasm, n=10) - # If verbose, print the diff for that funciton to the output + # If verbose, print the diff for that function to the output if verbose: if effective_ratio == 1.0: ok_text = "OK!" if plain else (colorama.Fore.GREEN + "✨ OK! ✨" + colorama.Style.RESET_ALL) if ratio == 1.0: print("%s: %s 100%% match.\n\n%s\n\n" % - (hex(addr), recinfo.name, ok_text)) + (addrs, recinfo.name, ok_text)) else: print("%s: %s Effective 100%% match. (Differs in register allocation only)\n\n%s (still differs in register allocation)\n\n" % - (hex(addr), recinfo.name, ok_text)) + (addrs, recinfo.name, ok_text)) else: for line in udiff: if line.startswith("++") or line.startswith("@@") or line.startswith("--"): From 253538feed3f7a94caf401c86ec2f13d3727b7e0 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sun, 17 Sep 2023 00:18:56 -0400 Subject: [PATCH 06/87] Add MxList, MxPresenterList, add to MxMediaManager (#122) * Add MxList, MxPresenterList, add to MxMediaManager * Match ~MxList --- CMakeLists.txt | 1 + LEGO1/mxlist.h | 83 +++++++++++++++++++++++++++++++++++++++ LEGO1/mxmediamanager.cpp | 38 ++++++++++++++---- LEGO1/mxmediamanager.h | 12 +++++- LEGO1/mxpresenterlist.cpp | 14 +++++++ LEGO1/mxpresenterlist.h | 27 +++++++++++++ 6 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 LEGO1/mxlist.h create mode 100644 LEGO1/mxpresenterlist.cpp create mode 100644 LEGO1/mxpresenterlist.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f72f83e2..202e2b7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,6 +146,7 @@ add_library(lego1 SHARED LEGO1/mxpalette.cpp LEGO1/mxparam.cpp LEGO1/mxpresenter.cpp + LEGO1/mxpresenterlist.cpp LEGO1/mxscheduler.cpp LEGO1/mxsemaphore.cpp LEGO1/mxsmkpresenter.cpp diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h new file mode 100644 index 00000000..9ace7bf7 --- /dev/null +++ b/LEGO1/mxlist.h @@ -0,0 +1,83 @@ +#ifndef MXLIST_H +#define MXLIST_H + +#include "mxtypes.h" +#include "mxcore.h" + +template +class MxListEntry +{ +public: + MxListEntry() {} + MxListEntry(T *p_obj) { + m_obj = p_obj; + m_prev = NULL; + m_next = NULL; + } + + T *m_obj; + MxListEntry *m_prev; + MxListEntry *m_next; +}; + +// VTABLE 0x100d6350 +// SIZE 0x10 +template +class MxListParent : public MxCore +{ +public: + MxListParent() { + m_count = 0; + m_customDestructor = Destroy; + } + // OFFSET: LEGO1 0x1001cdd0 + virtual ~MxListParent() {} + + // OFFSET: LEGO1 0x1001cd30 + static void Destroy(T *) {}; + + // OFFSET: LEGO1 0x1001cd20 + virtual MxS8 Compare(T *, T *) = 0; + +protected: + MxU32 m_count; // +0x8 + void (*m_customDestructor)(T *); // +0xc +}; + +// VTABLE 0x100d6368 +// SIZE 0x18 +template +class MxList : protected MxListParent +{ +public: + MxList() { + m_last = NULL; + m_first = NULL; + } + + virtual ~MxList(); +protected: + MxListEntry *m_first; // +0x10 + MxListEntry *m_last; // +0x14 +}; + +template +// OFFSET: LEGO1 0x1001ce20 +MxList::~MxList() +{ + for (MxListEntry *t = m_first;;) { + if (!t) + break; + + MxListEntry *next = t->m_next; + m_customDestructor(t->m_obj); + delete t; + t = next; + } + + m_count = 0; + m_last = NULL; + m_first = NULL; +} + +#endif // MXLIST_H \ No newline at end of file diff --git a/LEGO1/mxmediamanager.cpp b/LEGO1/mxmediamanager.cpp index a6c8a9c0..95012e19 100644 --- a/LEGO1/mxmediamanager.cpp +++ b/LEGO1/mxmediamanager.cpp @@ -1,4 +1,5 @@ #include "mxmediamanager.h" +#include "mxautolocker.h" #include "decomp.h" DECOMP_SIZE_ASSERT(MxMediaManager, 0x2c); @@ -12,22 +13,45 @@ MxMediaManager::MxMediaManager() // OFFSET: LEGO1 0x100b8560 MxMediaManager::~MxMediaManager() { - Teardown(); + Destroy(); } // OFFSET: LEGO1 0x100b85d0 MxResult MxMediaManager::Init() { - this->m_unk08 = NULL; + this->m_presenters = NULL; this->m_thread = NULL; return SUCCESS; } // OFFSET: LEGO1 0x100b8710 -void MxMediaManager::Teardown() +void MxMediaManager::Destroy() { - if(this->m_unk08) { - delete this->m_unk08; - } + MxAutoLocker lock(&this->m_criticalSection); + + if (this->m_presenters) + delete this->m_presenters; + Init(); -} \ No newline at end of file +} + +// OFFSET: LEGO1 0x100b8790 STUB +MxResult MxMediaManager::Tickle() +{ + return SUCCESS; +} + +// OFFSET: LEGO1 0x100b85e0 +MxResult MxMediaManager::InitPresenters() +{ + MxAutoLocker lock(&this->m_criticalSection); + + this->m_presenters = new MxPresenterList; + + if (!this->m_presenters) { + this->Destroy(); + return FAILURE; + } + + return SUCCESS; +} diff --git a/LEGO1/mxmediamanager.h b/LEGO1/mxmediamanager.h index 76af63fb..b5435957 100644 --- a/LEGO1/mxmediamanager.h +++ b/LEGO1/mxmediamanager.h @@ -4,19 +4,27 @@ #include "mxcore.h" #include "mxcriticalsection.h" #include "mxthread.h" +#include "mxpresenterlist.h" #include "mxtypes.h" // VTABLE 0x100dc6b0 +// SIZE 0x2c class MxMediaManager : public MxCore { public: MxMediaManager(); virtual ~MxMediaManager() override; + virtual MxResult Tickle(); // vtable+08 + virtual MxResult InitPresenters(); // vtable+14 + virtual void Destroy(); // vtable+18 + // vtable+1c + // vtable+20 + // vtable+24 + MxResult Init(); - void Teardown(); private: - void* m_unk08; + MxPresenterList *m_presenters; MxThread* m_thread; // 0xc protected: diff --git a/LEGO1/mxpresenterlist.cpp b/LEGO1/mxpresenterlist.cpp new file mode 100644 index 00000000..ca3f15a8 --- /dev/null +++ b/LEGO1/mxpresenterlist.cpp @@ -0,0 +1,14 @@ +#include "mxpresenterlist.h" +#include "mxpresenter.h" + +DECOMP_SIZE_ASSERT(MxPresenterList, 0x18); + +// OFFSET: LEGO1 0x1001cd00 +MxS8 MxPresenterList::Compare(MxPresenter *p_var0, MxPresenter *p_var1) +{ + if (p_var1 == p_var0) + return 0; + if (p_var1 <= p_var0) + return 1; + return -1; +} diff --git a/LEGO1/mxpresenterlist.h b/LEGO1/mxpresenterlist.h new file mode 100644 index 00000000..9373040d --- /dev/null +++ b/LEGO1/mxpresenterlist.h @@ -0,0 +1,27 @@ +#ifndef MXPRESENTERLIST_H +#define MXPRESENTERLIST_H + +#include "mxlist.h" + +class MxPresenter; + +// Unclear what the purpose of this class is +// VTABLE 0x100d62f0 +// SIZE 0x18 +class MxPresenterListParent : public MxList +{ +public: + MxPresenterListParent() { + m_customDestructor = Destroy; + } +}; + +// VTABLE 0x100d6308 +// SIZE 0x18 +class MxPresenterList : public MxPresenterListParent +{ +public: + virtual MxS8 Compare(MxPresenter *, MxPresenter *); // +0x14 +}; + +#endif // MXPRESENTERLIST_H From b819657bd8f6618e45ca34e335db96ac9fe38c2d Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sun, 17 Sep 2023 06:38:50 -0400 Subject: [PATCH 07/87] Implement AddPresenter, RemovePresenter, StopPresenters (#124) * Add MxList, MxPresenterList, add to MxMediaManager * Match ~MxList * Implement AddPresenter, RemovePresenter, StopPresenters * Initial implementation of RemovePresenter/Find/Detach * Implement/match MxMediaManager::StopPresenters * Move definitions out of class body * Match RemovePresenter/Detach * Fix style * Fix merge error * Fix merge error * Fix merge error * Remove space --- LEGO1/mxhashtable.h | 2 +- LEGO1/mxlist.h | 118 ++++++++++++++++++++++++++++++++++++++- LEGO1/mxmediamanager.cpp | 54 ++++++++++++++---- LEGO1/mxmediamanager.h | 9 +-- LEGO1/mxpresenter.h | 2 +- 5 files changed, 165 insertions(+), 20 deletions(-) diff --git a/LEGO1/mxhashtable.h b/LEGO1/mxhashtable.h index f9505bb5..3d91717b 100644 --- a/LEGO1/mxhashtable.h +++ b/LEGO1/mxhashtable.h @@ -67,7 +67,7 @@ class MxHashTable : protected HashTableParent virtual ~MxHashTable(); void Resize(); - void MxHashTable::Add(T* ); + void Add(T* ); virtual MxS8 Compare(T*, T*) = 0; diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 9ace7bf7..6f26cad8 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -5,13 +5,14 @@ #include "mxcore.h" template +// SIZE 0xc class MxListEntry { public: - MxListEntry() {} - MxListEntry(T *p_obj) { + MxListEntry() {} + MxListEntry(T *p_obj, MxListEntry *p_prev) { m_obj = p_obj; - m_prev = NULL; + m_prev = p_prev; m_next = NULL; } @@ -56,9 +57,54 @@ class MxList : protected MxListParent } virtual ~MxList(); + + void Append(T*); + + friend class MxListCursor; + protected: MxListEntry *m_first; // +0x10 MxListEntry *m_last; // +0x14 + +private: + void _DeleteEntry(MxListEntry *match); +}; + +// VTABLE 0x100d6488 +template +class MxListCursor : public MxCore +{ +public: + MxListCursor(MxList *p_list) { + m_list = p_list; + m_match = NULL; + } + + MxBool Find(T *p_obj); + void Detach(); + MxBool Next(T*& p_obj); + +private: + MxList *m_list; + MxListEntry *m_match; +}; + +// Unclear purpose +// VTABLE 0x100d6530 +template +class MxListCursorChild : public MxListCursor +{ +public: + MxListCursorChild(MxList *p_list) : MxListCursor(p_list) {} +}; + +// Unclear purpose +// VTABLE 0x100d6470 +template +class MxListCursorChildChild : public MxListCursorChild +{ +public: + MxListCursorChildChild(MxList *p_list) : MxListCursorChild(p_list) {} }; template @@ -80,4 +126,70 @@ MxList::~MxList() m_first = NULL; } +template +inline void MxList::Append(T *p_newobj) +{ + MxListEntry *currentLast = this->m_last; + MxListEntry *newEntry = new MxListEntry(p_newobj, currentLast); + + if (currentLast) + currentLast->m_next = newEntry; + else + this->m_first = newEntry; + + this->m_last = newEntry; + this->m_count++; +} + +template +inline void MxList::_DeleteEntry(MxListEntry *match) +{ + MxListEntry **pPrev = &match->m_prev; + MxListEntry **pNext = &match->m_next; + + if (match->m_prev) + match->m_prev->m_next = *pNext; + else + m_first = *pNext; + + if (*pNext) + (*pNext)->m_prev = *pPrev; + else + m_last = *pPrev; + + delete match; + m_count--; +} + +template +inline MxBool MxListCursor::Find(T *p_obj) +{ + for (m_match = m_list->m_first; + m_match && m_list->Compare(m_match->m_obj, p_obj); + m_match = m_match->m_next); + + return m_match != NULL; +} + +template +inline void MxListCursor::Detach() +{ + m_list->_DeleteEntry(m_match); + m_match = NULL; +} + +template +inline MxBool MxListCursor::Next(T*& p_obj) +{ + if (!m_match) + m_match = m_list->m_first; + else + m_match = m_match->m_next; + + if (m_match) + p_obj = m_match->m_obj; + + return m_match != NULL; +} + #endif // MXLIST_H \ No newline at end of file diff --git a/LEGO1/mxmediamanager.cpp b/LEGO1/mxmediamanager.cpp index 95012e19..d1823c03 100644 --- a/LEGO1/mxmediamanager.cpp +++ b/LEGO1/mxmediamanager.cpp @@ -1,9 +1,12 @@ #include "mxmediamanager.h" #include "mxautolocker.h" +#include "mxpresenter.h" #include "decomp.h" DECOMP_SIZE_ASSERT(MxMediaManager, 0x2c); +typedef MxListCursorChildChild MxPresenterListCursor; + // OFFSET: LEGO1 0x100b84c0 MxMediaManager::MxMediaManager() { @@ -24,17 +27,6 @@ MxResult MxMediaManager::Init() return SUCCESS; } -// OFFSET: LEGO1 0x100b8710 -void MxMediaManager::Destroy() -{ - MxAutoLocker lock(&this->m_criticalSection); - - if (this->m_presenters) - delete this->m_presenters; - - Init(); -} - // OFFSET: LEGO1 0x100b8790 STUB MxResult MxMediaManager::Tickle() { @@ -55,3 +47,43 @@ MxResult MxMediaManager::InitPresenters() return SUCCESS; } + +// OFFSET: LEGO1 0x100b8710 +void MxMediaManager::Destroy() +{ + MxAutoLocker lock(&this->m_criticalSection); + + if (this->m_presenters) + delete this->m_presenters; + + Init(); +} + +// OFFSET: LEGO1 0x100b88c0 +void MxMediaManager::AddPresenter(MxPresenter &p_presenter) +{ + MxAutoLocker lock(&this->m_criticalSection); + + this->m_presenters->Append(&p_presenter); +} + +// OFFSET: LEGO1 0x100b8980 +void MxMediaManager::RemovePresenter(MxPresenter &p_presenter) +{ + MxAutoLocker lock(&this->m_criticalSection); + MxPresenterListCursor cursor(this->m_presenters); + + if (cursor.Find(&p_presenter)) + cursor.Detach(); +} + +// OFFSET: LEGO1 0x100b8ac0 +void MxMediaManager::StopPresenters() +{ + MxAutoLocker lock(&this->m_criticalSection); + MxPresenter *presenter; + MxPresenterListCursor cursor(this->m_presenters); + + while (cursor.Next(presenter)) + presenter->EndAction(); +} diff --git a/LEGO1/mxmediamanager.h b/LEGO1/mxmediamanager.h index b5435957..9df073bc 100644 --- a/LEGO1/mxmediamanager.h +++ b/LEGO1/mxmediamanager.h @@ -18,14 +18,15 @@ class MxMediaManager : public MxCore virtual MxResult Tickle(); // vtable+08 virtual MxResult InitPresenters(); // vtable+14 virtual void Destroy(); // vtable+18 - // vtable+1c - // vtable+20 - // vtable+24 + virtual void AddPresenter(MxPresenter &p_presenter); // vtable+1c + virtual void RemovePresenter(MxPresenter &p_presenter); // vtable+20 + virtual void StopPresenters(); // vtable+24 MxResult Init(); + private: MxPresenterList *m_presenters; - MxThread* m_thread; // 0xc + MxThread *m_thread; // 0xc protected: MxCriticalSection m_criticalSection; // 0x10 diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 4b8659ec..87ef9645 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -77,7 +77,7 @@ class MxPresenter : public MxCore undefined4 m_unk0x10; undefined4 m_unk0x14; undefined4 m_unk0x18; - MxDSAction* m_action; // 0 + MxDSAction *m_action; // 0 MxCriticalSection m_criticalSection; MxPresenter *m_unkPresenter; // 0x3c }; From c67e537508fb49143a567c3bc3e356aa83190750 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sun, 17 Sep 2023 17:10:38 -0400 Subject: [PATCH 08/87] Implement/match MxMediaManager::Tickle (#127) * Implement/match MxMediaManager::Tickle * Remove space --- LEGO1/mxlist.h | 1 + LEGO1/mxmediamanager.cpp | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 6f26cad8..da2c3e4e 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -83,6 +83,7 @@ class MxListCursor : public MxCore MxBool Find(T *p_obj); void Detach(); MxBool Next(T*& p_obj); + void Reset() { m_match = NULL; } private: MxList *m_list; diff --git a/LEGO1/mxmediamanager.cpp b/LEGO1/mxmediamanager.cpp index d1823c03..b890eec4 100644 --- a/LEGO1/mxmediamanager.cpp +++ b/LEGO1/mxmediamanager.cpp @@ -27,9 +27,21 @@ MxResult MxMediaManager::Init() return SUCCESS; } -// OFFSET: LEGO1 0x100b8790 STUB +// OFFSET: LEGO1 0x100b8790 MxResult MxMediaManager::Tickle() { + MxAutoLocker lock(&this->m_criticalSection); + MxPresenter *presenter; + MxPresenterListCursor cursor(this->m_presenters); + + while (cursor.Next(presenter)) + presenter->Tickle(); + + cursor.Reset(); + + while (cursor.Next(presenter)) + presenter->VTable0x4c(); + return SUCCESS; } From 5617e0e0445b6a52ab887c9105811befae554a0b Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Tue, 19 Sep 2023 10:42:39 -0400 Subject: [PATCH 09/87] MxAudioManager: Destructor, LockedReinitialize, Reinitialize (#125) * MxAudioManager: Destructor, LockedReinitialize * MxAudioManager::Reinitialize, fix LockedReinitialize logic * MxAudioManager cleanup - fix param in LockedReinitialize, mark that function as private/give it a better param name * Match LockedReinitialize, fix function declarations, add/match InitPresenters --------- Co-authored-by: Christian Semmler --- CMakeLists.txt | 2 +- LEGO1/mxaudiomanager.cpp | 64 +++++++++++++++++++++++++++++++++++++ LEGO1/mxaudiomanager.h | 28 ++++++++++++++++ LEGO1/mxsoundmanager.h | 6 ++-- LEGO1/mxunknown100dc6e0.cpp | 19 ----------- LEGO1/mxunknown100dc6e0.h | 19 ----------- 6 files changed, 96 insertions(+), 42 deletions(-) create mode 100644 LEGO1/mxaudiomanager.cpp create mode 100644 LEGO1/mxaudiomanager.h delete mode 100644 LEGO1/mxunknown100dc6e0.cpp delete mode 100644 LEGO1/mxunknown100dc6e0.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 202e2b7d..3a47fc78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,7 @@ add_library(lego1 SHARED LEGO1/motorcycle.cpp LEGO1/mxatomid.cpp LEGO1/mxatomidcounter.cpp + LEGO1/mxaudiomanager.cpp LEGO1/mxaudiopresenter.cpp LEGO1/mxautolocker.cpp LEGO1/mxbackgroundaudiomanager.cpp @@ -159,7 +160,6 @@ add_library(lego1 SHARED LEGO1/mxticklemanager.cpp LEGO1/mxtimer.cpp LEGO1/mxtransitionmanager.cpp - LEGO1/mxunknown100dc6e0.cpp LEGO1/mxvariable.cpp LEGO1/mxvariabletable.cpp LEGO1/mxvector.cpp diff --git a/LEGO1/mxaudiomanager.cpp b/LEGO1/mxaudiomanager.cpp new file mode 100644 index 00000000..c7ecdc12 --- /dev/null +++ b/LEGO1/mxaudiomanager.cpp @@ -0,0 +1,64 @@ +#include "mxaudiomanager.h" + +DECOMP_SIZE_ASSERT(MxAudioManager, 0x30); + +// GLOBAL: LEGO1 0x10102108 +MxS32 MxAudioManager::g_unkCount = 0; + +// OFFSET: LEGO1 0x100b8d00 +MxAudioManager::MxAudioManager() +{ + Init(); +} + +// OFFSET: LEGO1 0x100b8d90 +MxAudioManager::~MxAudioManager() +{ + LockedReinitialize(TRUE); +} + +// OFFSET: LEGO1 0x100b8df0 +void MxAudioManager::Init() +{ + this->m_unk2c = 100; +} + +// OFFSET: LEGO1 0x100b8e00 +void MxAudioManager::LockedReinitialize(MxBool p_skipDestroy) +{ + this->m_criticalSection.Enter(); + g_unkCount--; + Init(); + this->m_criticalSection.Leave(); + + if (!p_skipDestroy) + MxMediaManager::Destroy(); +} + +// OFFSET: LEGO1 0x100b8e40 +MxResult MxAudioManager::InitPresenters() +{ + MxResult result = FAILURE; + MxBool success = FALSE; + + if (MxMediaManager::InitPresenters() == SUCCESS) { + this->m_criticalSection.Enter(); + success = TRUE; + result = SUCCESS; + g_unkCount++; + } + + if (result) + Destroy(); + + if (success) + this->m_criticalSection.Leave(); + + return result; +} + +// OFFSET: LEGO1 0x100b8e90 +void MxAudioManager::Destroy() +{ + LockedReinitialize(FALSE); +} \ No newline at end of file diff --git a/LEGO1/mxaudiomanager.h b/LEGO1/mxaudiomanager.h new file mode 100644 index 00000000..1403f36d --- /dev/null +++ b/LEGO1/mxaudiomanager.h @@ -0,0 +1,28 @@ +#ifndef MXAUDIOMANAGER_H +#define MXAUDIOMANAGER_H + +#include "decomp.h" +#include "mxmediamanager.h" + +// VTABLE 0x100dc6e0 +class MxAudioManager : public MxMediaManager +{ +public: + MxAudioManager(); + virtual ~MxAudioManager() override; + + virtual MxResult InitPresenters(); // vtable+14 + virtual void Destroy(); // vtable+18 + +private: + void LockedReinitialize(MxBool); + + static MxS32 g_unkCount; + +protected: + void Init(); + + undefined4 m_unk2c; +}; + +#endif // MXAUDIOMANAGER_H diff --git a/LEGO1/mxsoundmanager.h b/LEGO1/mxsoundmanager.h index 4d74fa95..06dc9d5f 100644 --- a/LEGO1/mxsoundmanager.h +++ b/LEGO1/mxsoundmanager.h @@ -1,12 +1,12 @@ #ifndef MXSOUNDMANAGER_H #define MXSOUNDMANAGER_H -#include "mxunknown100dc6e0.h" +#include "mxaudiomanager.h" // VTABLE 0x100dc128 // SIZE 0x3c -// Base vtables are: MxCore -> 0x100dc6b0 -> 0x100dc6e0 -> MxSoundManager -class MxSoundManager : public MxUnknown100dc6e0 +// Base vtables are: MxCore -> 0x100dc6b0 -> MxAudioManager -> MxSoundManager +class MxSoundManager : public MxAudioManager { public: MxSoundManager(); diff --git a/LEGO1/mxunknown100dc6e0.cpp b/LEGO1/mxunknown100dc6e0.cpp deleted file mode 100644 index b896e89b..00000000 --- a/LEGO1/mxunknown100dc6e0.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "mxunknown100dc6e0.h" - -// OFFSET: LEGO1 0x100b8d00 -MxUnknown100dc6e0::MxUnknown100dc6e0() -{ - Init(); -} - -// OFFSET: LEGO1 0x100b8d90 STUB -MxUnknown100dc6e0::~MxUnknown100dc6e0() -{ - // TODO -} - -// OFFSET: LEGO1 0x100b8df0 -void MxUnknown100dc6e0::Init() -{ - this->m_unk2c = 100; -} diff --git a/LEGO1/mxunknown100dc6e0.h b/LEGO1/mxunknown100dc6e0.h deleted file mode 100644 index 056e1fcd..00000000 --- a/LEGO1/mxunknown100dc6e0.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef MXUNKNOWN100DC6E0_H -#define MXUNKNOWN100DC6E0_H - -#include "mxmediamanager.h" - -// VTABLE 0x100dc6e0 -class MxUnknown100dc6e0 : public MxMediaManager -{ -public: - MxUnknown100dc6e0(); - virtual ~MxUnknown100dc6e0() override; - -protected: - void Init(); - - int m_unk2c; -}; - -#endif // MXUNKNOWN100DC6E0_H From 4bd67e4ae14b9ad3a188e643bcf48fe71d2cf4b9 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 19 Sep 2023 17:45:16 -0400 Subject: [PATCH 10/87] Implement/match MxPresenter::StartAction (#126) * Implement/match MxPresenter::StartAction * Update mxpoint32.h --- LEGO1/mxdsaction.h | 1 + LEGO1/mxpoint32.h | 20 ++++++++++++++++++++ LEGO1/mxpresenter.cpp | 25 +++++++++++++++++-------- LEGO1/mxpresenter.h | 6 +++--- 4 files changed, 41 insertions(+), 11 deletions(-) create mode 100755 LEGO1/mxpoint32.h diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 11388c0f..3028a43d 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -52,6 +52,7 @@ class MxDSAction : public MxDSObject inline void SetFlags(MxU32 m_flags) { this->m_flags = m_flags; } inline char *GetExtraData() { return m_extraData; } inline MxU16 GetExtraLength() const { return m_extraLength; } + inline const MxVector3Data &GetLocation() const { return m_location; } inline void SetOmni(MxOmni *p_omni) { m_omni = p_omni; } private: diff --git a/LEGO1/mxpoint32.h b/LEGO1/mxpoint32.h new file mode 100755 index 00000000..cc0f6327 --- /dev/null +++ b/LEGO1/mxpoint32.h @@ -0,0 +1,20 @@ +#ifndef MXPOINT32_H +#define MXPOINT32_H + +#include "mxtypes.h" + +class MxPoint32 +{ +public: + MxPoint32() { } + MxPoint32(MxS32 p_x, MxS32 p_y) + { + this->m_x = p_x; + this->m_y = p_y; + } + + MxS32 m_x; + MxS32 m_y; +}; + +#endif // MXPOINT32_H diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 56688233..cf934fe7 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -19,11 +19,10 @@ void MxPresenter::Init() { m_currentTickleState = TickleState_Idle; m_action = NULL; - m_unk0x18 = 0; + m_location = MxPoint32(0, 0); + m_locationZ = 0; m_unkPresenter = NULL; m_previousTickleStates = 0; - m_unk0x10 = 0; - m_unk0x14 = 0; } // OFFSET: LEGO1 0x100b4fc0 @@ -116,15 +115,25 @@ MxLong MxPresenter::Tickle() break; } - return 0; + return SUCCESS; } -// OFFSET: LEGO1 0x100b4d80 STUB -MxLong MxPresenter::StartAction(MxStreamController *, MxDSAction *) +// OFFSET: LEGO1 0x100b4d80 +MxLong MxPresenter::StartAction(MxStreamController *, MxDSAction *p_action) { - // TODO + MxAutoLocker lock(&this->m_criticalSection); - return 0; + this->m_action = p_action; + + const MxVector3Data& location = this->m_action->GetLocation(); + MxS32 previousTickleState = this->m_currentTickleState; + + this->m_location = MxPoint32(location[0], location[1]); + this->m_locationZ = location[2]; + this->m_previousTickleStates |= 1 << (unsigned char)previousTickleState; + this->m_currentTickleState = TickleState_Ready; + + return SUCCESS; } // OFFSET: LEGO1 0x100b4e40 STUB diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 87ef9645..f20ac647 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -2,6 +2,7 @@ #define MXPRESENTER_H #include "mxcore.h" +#include "mxpoint32.h" #include "mxdsaction.h" #include "mxcriticalsection.h" #include "mxomni.h" @@ -74,9 +75,8 @@ class MxPresenter : public MxCore private: MxS32 m_currentTickleState; // 0x8 MxU32 m_previousTickleStates; - undefined4 m_unk0x10; - undefined4 m_unk0x14; - undefined4 m_unk0x18; + MxPoint32 m_location; + MxS32 m_locationZ; MxDSAction *m_action; // 0 MxCriticalSection m_criticalSection; MxPresenter *m_unkPresenter; // 0x3c From d145f914c464a3b1892e6c4a70ceb12dadd3c91a Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 19 Sep 2023 23:00:34 -0400 Subject: [PATCH 11/87] Implement/match MxVideoManager::Tickle (#128) * Implement/match MxPresenter::StartAction * Update mxpoint32.h * Implement/match MxVideoManager::Tickle * Update mxlist.h * Update mxpresenter.cpp --- LEGO1/mxlist.h | 12 +++++- LEGO1/mxmediamanager.cpp | 4 +- LEGO1/mxmediamanager.h | 6 +-- LEGO1/mxpresenter.cpp | 10 ++--- LEGO1/mxpresenter.h | 8 ++-- LEGO1/mxpresenterlist.h | 2 + LEGO1/mxregion.h | 26 +++++++++++ LEGO1/mxvideomanager.cpp | 93 ++++++++++++++++++++++++++++++++-------- LEGO1/mxvideomanager.h | 9 ++-- 9 files changed, 133 insertions(+), 37 deletions(-) create mode 100644 LEGO1/mxregion.h diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index da2c3e4e..013ef852 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -59,6 +59,7 @@ class MxList : protected MxListParent virtual ~MxList(); void Append(T*); + MxU32 GetCount() { return m_count; } friend class MxListCursor; @@ -83,6 +84,8 @@ class MxListCursor : public MxCore MxBool Find(T *p_obj); void Detach(); MxBool Next(T*& p_obj); + void SetValue(T *p_obj); + void Head() { m_match = m_list->m_first; } void Reset() { m_match = NULL; } private: @@ -193,4 +196,11 @@ inline MxBool MxListCursor::Next(T*& p_obj) return m_match != NULL; } -#endif // MXLIST_H \ No newline at end of file +template +inline void MxListCursor::SetValue(T *p_obj) +{ + if (m_match) + m_match->m_obj = p_obj; +} + +#endif // MXLIST_H diff --git a/LEGO1/mxmediamanager.cpp b/LEGO1/mxmediamanager.cpp index b890eec4..3fb28d37 100644 --- a/LEGO1/mxmediamanager.cpp +++ b/LEGO1/mxmediamanager.cpp @@ -5,8 +5,6 @@ DECOMP_SIZE_ASSERT(MxMediaManager, 0x2c); -typedef MxListCursorChildChild MxPresenterListCursor; - // OFFSET: LEGO1 0x100b84c0 MxMediaManager::MxMediaManager() { @@ -40,7 +38,7 @@ MxResult MxMediaManager::Tickle() cursor.Reset(); while (cursor.Next(presenter)) - presenter->VTable0x4c(); + presenter->PutData(); return SUCCESS; } diff --git a/LEGO1/mxmediamanager.h b/LEGO1/mxmediamanager.h index 9df073bc..ccc3ec42 100644 --- a/LEGO1/mxmediamanager.h +++ b/LEGO1/mxmediamanager.h @@ -23,12 +23,10 @@ class MxMediaManager : public MxCore virtual void StopPresenters(); // vtable+24 MxResult Init(); - -private: - MxPresenterList *m_presenters; - MxThread *m_thread; // 0xc protected: + MxPresenterList *m_presenters; + MxThread *m_thread; // 0xc MxCriticalSection m_criticalSection; // 0x10 }; diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index cf934fe7..e82aa3a4 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -20,7 +20,7 @@ void MxPresenter::Init() m_currentTickleState = TickleState_Idle; m_action = NULL; m_location = MxPoint32(0, 0); - m_locationZ = 0; + m_displayZ = 0; m_unkPresenter = NULL; m_previousTickleStates = 0; } @@ -129,7 +129,7 @@ MxLong MxPresenter::StartAction(MxStreamController *, MxDSAction *p_action) MxS32 previousTickleState = this->m_currentTickleState; this->m_location = MxPoint32(location[0], location[1]); - this->m_locationZ = location[2]; + this->m_displayZ = location[2]; this->m_previousTickleStates |= 1 << (unsigned char)previousTickleState; this->m_currentTickleState = TickleState_Ready; @@ -236,13 +236,13 @@ MxBool MxPresenter::HasTickleStatePassed(TickleState p_tickleState) } // OFFSET: LEGO1 0x1000bfc0 -undefined4 MxPresenter::VTable0x4c() +undefined4 MxPresenter::PutData() { return 0; } // OFFSET: LEGO1 0x1000bfd0 -undefined MxPresenter::VTable0x50(undefined4, undefined4) +MxBool MxPresenter::IsHit(MxS32 p_x, MxS32 p_y) { - return 0; + return FALSE; } diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index f20ac647..b7e99edf 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -62,12 +62,14 @@ class MxPresenter : public MxCore __declspec(dllexport) virtual void EndAction(); // vtable+0x40 virtual void SetTickleState(TickleState p_tickleState); // vtable+0x44 virtual MxBool HasTickleStatePassed(TickleState p_tickleState); // vtable+0x48 - virtual undefined4 VTable0x4c(); // vtable+0x4c - virtual undefined VTable0x50(undefined4, undefined4); // vtable+0x50 + virtual undefined4 PutData(); // vtable+0x4c + virtual MxBool IsHit(MxS32 p_x, MxS32 p_y); // vtable+0x50 __declspec(dllexport) virtual void Enable(MxBool p_enable); // vtable+0x54 MxBool IsEnabled(); + inline MxS32 GetDisplayZ() { return this->m_displayZ; } + protected: __declspec(dllexport) void Init(); void SendTo_unkPresenter(MxOmni *); @@ -76,7 +78,7 @@ class MxPresenter : public MxCore MxS32 m_currentTickleState; // 0x8 MxU32 m_previousTickleStates; MxPoint32 m_location; - MxS32 m_locationZ; + MxS32 m_displayZ; MxDSAction *m_action; // 0 MxCriticalSection m_criticalSection; MxPresenter *m_unkPresenter; // 0x3c diff --git a/LEGO1/mxpresenterlist.h b/LEGO1/mxpresenterlist.h index 9373040d..5b36e2d8 100644 --- a/LEGO1/mxpresenterlist.h +++ b/LEGO1/mxpresenterlist.h @@ -24,4 +24,6 @@ class MxPresenterList : public MxPresenterListParent virtual MxS8 Compare(MxPresenter *, MxPresenter *); // +0x14 }; +typedef MxListCursorChildChild MxPresenterListCursor; + #endif // MXPRESENTERLIST_H diff --git a/LEGO1/mxregion.h b/LEGO1/mxregion.h new file mode 100644 index 00000000..717be924 --- /dev/null +++ b/LEGO1/mxregion.h @@ -0,0 +1,26 @@ +#ifndef MXREGION_H +#define MXREGION_H + +#include "mxcore.h" + +// VTABLE 0x100dcae8 +// SIZE 0x1c +class MxRegion : public MxCore +{ +public: + MxRegion(); + virtual ~MxRegion() override; + + virtual void Reset(); + virtual void vtable18(); + virtual void vtable1c(); + virtual void vtable20(); + +private: + // A container (probably MxList) holding MxRect32 + // MxList *m_rects; + // 4 coordinates (could be MxRect32) + // MxS32 left, top, right, bottom; +}; + +#endif // MXREGION_H diff --git a/LEGO1/mxvideomanager.cpp b/LEGO1/mxvideomanager.cpp index 7663743d..81d431a9 100644 --- a/LEGO1/mxvideomanager.cpp +++ b/LEGO1/mxvideomanager.cpp @@ -1,18 +1,6 @@ #include "mxvideomanager.h" - -// OFFSET: LEGO1 0x100be2a0 STUB -MxVideoManager::~MxVideoManager() -{ - // TODO -} - -// OFFSET: LEGO1 0x100bea90 STUB -MxLong MxVideoManager::Tickle() -{ - // TODO - - return 0; -} +#include "mxautolocker.h" +#include "mxpresenter.h" // OFFSET: LEGO1 0x100be1f0 MxVideoManager::MxVideoManager() @@ -20,16 +8,85 @@ MxVideoManager::MxVideoManager() Init(); } +// OFFSET: LEGO1 0x100be2a0 STUB +MxVideoManager::~MxVideoManager() +{ + // TODO +} + +// OFFSET: LEGO1 0x100bea90 +MxLong MxVideoManager::Tickle() +{ + MxAutoLocker lock(&this->m_criticalSection); + + SortPresenterList(); + + MxPresenter *presenter; + MxPresenterListCursor cursor(this->m_presenters); + + while (cursor.Next(presenter)) + presenter->Tickle(); + + cursor.Reset(); + + while (cursor.Next(presenter)) + presenter->PutData(); + + UpdateRegion(); + m_region->Reset(); + + return SUCCESS; +} + // OFFSET: LEGO1 0x100be320 -int MxVideoManager::Init() +MxResult MxVideoManager::Init() { this->m_pDirectDraw = NULL; - this->m_unk54 = NULL; + this->m_pDDSurface = NULL; this->m_displaySurface = NULL; - this->m_unk5c = 0; + this->m_region = NULL; this->m_videoParam.SetPalette(NULL); this->m_unk60 = FALSE; - return 0; + return SUCCESS; +} + +// OFFSET: LEGO1 0x100be440 +void MxVideoManager::SortPresenterList() +{ + if (this->m_presenters->GetCount() <= 1) + return; + + MxPresenterListCursor a(this->m_presenters); + MxPresenterListCursor b(this->m_presenters); + MxU32 count = this->m_presenters->GetCount() - 1; + MxBool finished; + + if (count != 0) { + do { + a.Reset(); + b.Head(); + + finished = TRUE; + for (MxU32 i = count; i != 0; i--) { + MxPresenter *p_a, *p_b; + + a.Next(p_a); + b.Next(p_b); + + if (p_a->GetDisplayZ() < p_b->GetDisplayZ()) { + a.SetValue(p_b); + b.SetValue(p_a); + finished = FALSE; + } + } + } while (!finished && --count != 0); + } +} + +// OFFSET: LEGO1 0x100be3e0 STUB +void MxVideoManager::UpdateRegion() +{ + // TODO } // OFFSET: LEGO1 0x100bea60 STUB diff --git a/LEGO1/mxvideomanager.h b/LEGO1/mxvideomanager.h index 03eac8aa..a7cde92f 100644 --- a/LEGO1/mxvideomanager.h +++ b/LEGO1/mxvideomanager.h @@ -2,6 +2,7 @@ #define MXVIDEOMANAGER_H #include "mxdisplaysurface.h" +#include "mxregion.h" #include "mxmediamanager.h" #include "mxvideoparam.h" @@ -19,16 +20,18 @@ class MxVideoManager : public MxMediaManager MxVideoManager(); - int Init(); + MxResult Init(); + void SortPresenterList(); + void UpdateRegion(); inline MxVideoParam& GetVideoParam() { return this->m_videoParam; } inline LPDIRECTDRAW GetDirectDraw() { return this->m_pDirectDraw; } private: MxVideoParam m_videoParam; LPDIRECTDRAW m_pDirectDraw; - LPDIRECTDRAWSURFACE m_unk54; + LPDIRECTDRAWSURFACE m_pDDSurface; MxDisplaySurface *m_displaySurface; - int m_unk5c; + MxRegion *m_region; MxBool m_unk60; }; From 1d3c1bdbd147ef1ec68ed1e096645c98f90745fe Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Wed, 20 Sep 2023 07:48:46 -0400 Subject: [PATCH 12/87] MxFlcPresenter ctor/dtor (#132) * MxFlcPresenter ctor/dtor * Match constructor --------- Co-authored-by: Christian Semmler --- LEGO1/mxflcpresenter.cpp | 12 ++++++++---- LEGO1/mxflcpresenter.h | 2 +- LEGO1/mxvideopresenter.h | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/LEGO1/mxflcpresenter.cpp b/LEGO1/mxflcpresenter.cpp index 8bd23d22..79c1ae49 100644 --- a/LEGO1/mxflcpresenter.cpp +++ b/LEGO1/mxflcpresenter.cpp @@ -4,14 +4,18 @@ DECOMP_SIZE_ASSERT(MxFlcPresenter, 0x68); -// OFFSET: LEGO1 0x100b3310 STUB +// OFFSET: LEGO1 0x100b3310 MxFlcPresenter::MxFlcPresenter() { - // TODO + this->m_unk64 = 0; + this->m_flags &= 0xfd; + this->m_flags &= 0xfb; } -// OFFSET: LEGO1 0x100b3420 STUB +// OFFSET: LEGO1 0x100b3420 MxFlcPresenter::~MxFlcPresenter() { - // TODO + if (this->m_unk64) { + delete this->m_unk64; + } } diff --git a/LEGO1/mxflcpresenter.h b/LEGO1/mxflcpresenter.h index bc34ff12..19535bcd 100644 --- a/LEGO1/mxflcpresenter.h +++ b/LEGO1/mxflcpresenter.h @@ -26,7 +26,7 @@ class MxFlcPresenter : public MxVideoPresenter return !strcmp(name, MxFlcPresenter::ClassName()) || MxVideoPresenter::IsA(name); } - undefined4 m_unk64; + undefined4 *m_unk64; }; #endif // MXFLCPRESENTER_H diff --git a/LEGO1/mxvideopresenter.h b/LEGO1/mxvideopresenter.h index 19c211c3..bc5fac5c 100644 --- a/LEGO1/mxvideopresenter.h +++ b/LEGO1/mxvideopresenter.h @@ -32,7 +32,7 @@ class MxVideoPresenter : public MxMediaPresenter undefined4 m_unk54; undefined4 m_unk58; undefined2 m_unk5c; - unsigned char m_flags; + unsigned char m_flags; // 0x5e undefined4 m_unk60; }; From b743f99d2080792468c35f8854e294269cc9b050 Mon Sep 17 00:00:00 2001 From: MS Date: Wed, 20 Sep 2023 16:22:57 -0400 Subject: [PATCH 13/87] LegoOmni::CreateStreamObject and related (#129) * LegoOmni::CreateStreamObject and related * Revert change to MxDSSource/MxDSFile Read export --- LEGO1/legoomni.cpp | 36 +++++++++++++++++-- LEGO1/mxdsfile.cpp | 16 ++++----- LEGO1/mxdsfile.h | 3 +- LEGO1/mxdsmultiaction.cpp | 2 ++ LEGO1/mxdsmultiaction.h | 4 +++ LEGO1/mxdsobject.cpp | 70 ++++++++++++++++++++++++++++++++++++ LEGO1/mxdsobject.h | 2 ++ LEGO1/mxdsparallelaction.cpp | 2 ++ LEGO1/mxdsselectaction.cpp | 2 ++ LEGO1/mxdsselectaction.h | 7 ++++ LEGO1/mxdsserialaction.cpp | 2 ++ LEGO1/mxdsserialaction.h | 5 +++ LEGO1/mxdssource.cpp | 6 ++++ LEGO1/mxdssource.h | 3 +- 14 files changed, 147 insertions(+), 13 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index e5574058..cda6d9ff 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -1,5 +1,7 @@ #include "legoomni.h" +#include "mxdsobject.h" + // 0x100f4588 char *g_nocdSourceName = NULL; @@ -147,10 +149,38 @@ MxBackgroundAudioManager *BackgroundAudioManager() return LegoOmni::GetInstance()->GetBackgroundAudioManager(); } -// OFFSET: LEGO1 0x100c0280 STUB -MxDSObject *CreateStreamObject(MxDSFile *,MxS16) +// OFFSET: LEGO1 0x100c0280 +MxDSObject *CreateStreamObject(MxDSFile *p_file, MxS16 p_ofs) { - // TODO + char *buf; + _MMCKINFO tmp_chunk; + + if (p_file->Seek(((MxLong*)p_file->GetBuffer())[p_ofs], 0)) { + return NULL; + } + + if (p_file->Read((MxU8*)&tmp_chunk.ckid, 8) == 0 && tmp_chunk.ckid == FOURCC('M', 'x', 'S', 't')) { + if (p_file->Read((MxU8*)&tmp_chunk.ckid, 8) == 0 && tmp_chunk.ckid == FOURCC('M', 'x', 'O', 'b')) { + + buf = new char[tmp_chunk.cksize]; + if (!buf) { + return NULL; + } + + if (p_file->Read((MxU8*)buf, tmp_chunk.cksize) != 0) { + return NULL; + } + + // Save a copy so we can clean up properly, because + // this function will alter the pointer value. + char *copy = buf; + MxDSObject *obj = DeserializeDSObjectDispatch(&buf, -1); + delete[] copy; + return obj; + } + return NULL; + } + return NULL; } diff --git a/LEGO1/mxdsfile.cpp b/LEGO1/mxdsfile.cpp index 8bccf914..ca6e96fb 100644 --- a/LEGO1/mxdsfile.cpp +++ b/LEGO1/mxdsfile.cpp @@ -47,13 +47,13 @@ MxLong MxDSFile::Open(MxULong uStyle) } // OFFSET: LEGO1 0x100cc780 -MxLong MxDSFile::Read(unsigned char *pch, MxULong cch) +MxResult MxDSFile::Read(unsigned char *p_buf, MxULong p_nbytes) { - if (m_io.Read((char*)pch, cch) != cch) - return -1; + if (m_io.Read(p_buf, p_nbytes) != p_nbytes) + return FAILURE; - m_position += cch; - return 0; + m_position += p_nbytes; + return SUCCESS; } // OFFSET: LEGO1 0x100cc620 @@ -72,7 +72,7 @@ MxLong MxDSFile::ReadChunks() return -1; } - m_io.Read((char*)&m_header, 0xc); + m_io.Read(&m_header, 0xc); if ((m_header.majorVersion == SI_MAJOR_VERSION) && (m_header.minorVersion == SI_MINOR_VERSION)) { childChunk.ckid = FOURCC('M', 'x', 'O', 'f'); @@ -80,9 +80,9 @@ MxLong MxDSFile::ReadChunks() return -1; } MxULong* pLengthInDWords = &m_lengthInDWords; - m_io.Read((char *)pLengthInDWords, 4); + m_io.Read(pLengthInDWords, 4); m_pBuffer = malloc(*pLengthInDWords * 4); - m_io.Read((char*)m_pBuffer, *pLengthInDWords * 4); + m_io.Read(m_pBuffer, *pLengthInDWords * 4); return 0; } else diff --git a/LEGO1/mxdsfile.h b/LEGO1/mxdsfile.h index ac812df7..d46a6153 100644 --- a/LEGO1/mxdsfile.h +++ b/LEGO1/mxdsfile.h @@ -4,6 +4,7 @@ #include "mxdssource.h" #include "mxioinfo.h" #include "mxstring.h" +#include "mxtypes.h" // VTABLE 0x100dc890 class MxDSFile : public MxDSSource @@ -27,7 +28,7 @@ class MxDSFile : public MxDSSource __declspec(dllexport) virtual MxLong Open(MxULong); // vtable+0x14 __declspec(dllexport) virtual MxLong Close(); // vtable+0x18 - __declspec(dllexport) virtual MxLong Read(unsigned char *,MxULong); // vtable+0x20 + __declspec(dllexport) virtual MxResult Read(unsigned char *,MxULong); // vtable+0x20 __declspec(dllexport) virtual MxLong Seek(MxLong,int); // vtable+0x24 __declspec(dllexport) virtual MxULong GetBufferSize(); // vtable+0x28 __declspec(dllexport) virtual MxULong GetStreamBuffersNum(); // vtable+0x2c diff --git a/LEGO1/mxdsmultiaction.cpp b/LEGO1/mxdsmultiaction.cpp index 4188fb66..0328a5fd 100644 --- a/LEGO1/mxdsmultiaction.cpp +++ b/LEGO1/mxdsmultiaction.cpp @@ -1,5 +1,7 @@ #include "mxdsmultiaction.h" +DECOMP_SIZE_ASSERT(MxDSMultiAction, 0x9c) + // OFFSET: LEGO1 0x100c9b90 MxDSMultiAction::MxDSMultiAction() { diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index af3d69df..6e049965 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -2,6 +2,7 @@ #define MXDSMULTIACTION_H #include "mxdsaction.h" +#include "decomp.h" // VTABLE 0x100dcef0 // SIZE 0x9c @@ -23,6 +24,9 @@ class MxDSMultiAction : public MxDSAction { return !strcmp(name, MxDSMultiAction::ClassName()) || MxDSAction::IsA(name); } + + undefined4 m_unk0x94; + undefined4 m_unk0x98; }; #endif // MXDSMULTIACTION_H diff --git a/LEGO1/mxdsobject.cpp b/LEGO1/mxdsobject.cpp index 57663cee..2b7d8437 100644 --- a/LEGO1/mxdsobject.cpp +++ b/LEGO1/mxdsobject.cpp @@ -3,6 +3,19 @@ #include #include +#include "mxdstypes.h" +#include "mxdsaction.h" +#include "mxdsmediaaction.h" +#include "mxdsanim.h" +#include "mxdssound.h" +#include "mxdsmultiaction.h" +#include "mxdsserialaction.h" +#include "mxdsparallelaction.h" +#include "mxdsevent.h" +#include "mxdsselectaction.h" +#include "mxdsstill.h" +#include "mxdsobjectaction.h" + DECOMP_SIZE_ASSERT(MxDSObject, 0x2c); // OFFSET: LEGO1 0x100bf6a0 @@ -127,3 +140,60 @@ void MxDSObject::Deserialize(char **p_source, MxS16 p_unk24) this->m_unk24 = p_unk24; } + + +// OFFSET: LEGO1 0x100bfb30 +MxDSObject *DeserializeDSObjectDispatch(char **p_source, MxS16 p_flags) +{ + MxU16 type = *(MxU16*) *p_source; + *p_source += 2; + + MxDSObject *obj = NULL; + + switch (type) { + default: + return NULL; + case MxDSType_Object: + obj = new MxDSObject(); + break; + case MxDSType_Action: + obj = new MxDSAction(); + break; + case MxDSType_MediaAction: + obj = new MxDSMediaAction(); + break; + case MxDSType_Anim: + obj = new MxDSAnim(); + break; + case MxDSType_Sound: + obj = new MxDSSound(); + break; + case MxDSType_MultiAction: + obj = new MxDSMultiAction(); + break; + case MxDSType_SerialAction: + obj = new MxDSSerialAction(); + break; + case MxDSType_ParallelAction: + obj = new MxDSParallelAction(); + break; + case MxDSType_Event: + obj = new MxDSEvent(); + break; + case MxDSType_SelectAction: + obj = new MxDSSelectAction(); + break; + case MxDSType_Still: + obj = new MxDSStill(); + break; + case MxDSType_ObjectAction: + obj = new MxDSObjectAction(); + break; + } + + if (obj) { + obj->Deserialize(p_source, p_flags); + } + + return obj; +} \ No newline at end of file diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index c46ee609..0b247a6a 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -56,4 +56,6 @@ class MxDSObject : public MxCore undefined4 m_unk28; }; +MxDSObject *DeserializeDSObjectDispatch(char **, MxS16); + #endif // MXDSOBJECT_H diff --git a/LEGO1/mxdsparallelaction.cpp b/LEGO1/mxdsparallelaction.cpp index 97a8a9d3..2e0d66da 100644 --- a/LEGO1/mxdsparallelaction.cpp +++ b/LEGO1/mxdsparallelaction.cpp @@ -1,5 +1,7 @@ #include "mxdsparallelaction.h" +DECOMP_SIZE_ASSERT(MxDSParallelAction, 0x9c) + // OFFSET: LEGO1 0x100cae80 MxDSParallelAction::MxDSParallelAction() { diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 5cae82fb..1c21b466 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -1,5 +1,7 @@ #include "mxdsselectaction.h" +DECOMP_SIZE_ASSERT(MxDSSelectAction, 0xb0) + // OFFSET: LEGO1 0x100cb2b0 MxDSSelectAction::MxDSSelectAction() { diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index cb5374e1..df956fbc 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -2,6 +2,7 @@ #define MXDSSELECTACTION_H #include "mxdsparallelaction.h" +#include "decomp.h" // VTABLE 0x100dcfc8 // SIZE 0xb0 @@ -24,6 +25,12 @@ class MxDSSelectAction : public MxDSParallelAction return !strcmp(name, MxDSSelectAction::ClassName()) || MxDSParallelAction::IsA(name); } + undefined4 m_unk0x9c; + undefined4 m_unk0xa0; + undefined4 m_unk0xa4; + undefined4 m_unk0xa8; + undefined4 m_unk0xac; + }; #endif // MXDSSELECTACTION_H diff --git a/LEGO1/mxdsserialaction.cpp b/LEGO1/mxdsserialaction.cpp index 46964208..c6aa541f 100644 --- a/LEGO1/mxdsserialaction.cpp +++ b/LEGO1/mxdsserialaction.cpp @@ -1,5 +1,7 @@ #include "mxdsserialaction.h" +DECOMP_SIZE_ASSERT(MxDSSerialAction, 0xa8) + // OFFSET: LEGO1 0x100ca9d0 MxDSSerialAction::MxDSSerialAction() { diff --git a/LEGO1/mxdsserialaction.h b/LEGO1/mxdsserialaction.h index 2b260556..6bf30c0f 100644 --- a/LEGO1/mxdsserialaction.h +++ b/LEGO1/mxdsserialaction.h @@ -2,6 +2,7 @@ #define MXDSSERIALACTION_H #include "mxdsmultiaction.h" +#include "decomp.h" // VTABLE 0x100dcf38 // SIZE 0xa8 @@ -23,6 +24,10 @@ class MxDSSerialAction : public MxDSMultiAction { return !strcmp(name, MxDSSerialAction::ClassName()) || MxDSMultiAction::IsA(name); } + + undefined4 m_unk0x9c; + undefined4 m_unk0xa0; + undefined4 m_unk0xa4; }; #endif // MXDSSERIALACTION_H diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp index 9a94f110..4dfb5386 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -11,4 +11,10 @@ void MxDSSource::SomethingWhichCallsRead(void* pUnknownObject) MxLong MxDSSource::GetLengthInDWords() { return m_lengthInDWords; +} + +// OFFSET: LEGO1 0x100c0000 +void *MxDSSource::GetBuffer() +{ + return m_pBuffer; } \ No newline at end of file diff --git a/LEGO1/mxdssource.h b/LEGO1/mxdssource.h index 5ff4c33c..67cbc6c7 100644 --- a/LEGO1/mxdssource.h +++ b/LEGO1/mxdssource.h @@ -29,11 +29,12 @@ class MxDSSource : public MxCore virtual MxLong Open(MxULong) = 0; virtual MxLong Close() = 0; virtual void SomethingWhichCallsRead(void* pUnknownObject); - virtual MxLong Read(unsigned char *, MxULong) = 0; + virtual MxResult Read(unsigned char *, MxULong) = 0; virtual MxLong Seek(MxLong, int) = 0; virtual MxULong GetBufferSize() = 0; virtual MxULong GetStreamBuffersNum() = 0; virtual MxLong GetLengthInDWords(); + virtual void* GetBuffer(); // 0x34 protected: MxULong m_lengthInDWords; From 99c27a6a50fa62773d8249ca51a79afeadfcbd39 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 20 Sep 2023 16:36:15 -0400 Subject: [PATCH 14/87] Bootstrap MxDSMultiAction (#133) * Bootstrap MxDSMultiAction * Move destroy function to list class * Fix unk14 call --- CMakeLists.txt | 1 + LEGO1/mxdsactionlist.cpp | 21 +++++++++++++++++++++ LEGO1/mxdsactionlist.h | 28 ++++++++++++++++++++++++++++ LEGO1/mxdsmultiaction.cpp | 36 +++++++++++++++++++++++++++++++++--- LEGO1/mxdsmultiaction.h | 10 +++++++--- LEGO1/mxlist.h | 1 + 6 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 LEGO1/mxdsactionlist.cpp create mode 100644 LEGO1/mxdsactionlist.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a47fc78..d96b0c61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,7 @@ add_library(lego1 SHARED LEGO1/mxdiskstreamprovider.cpp LEGO1/mxdisplaysurface.cpp LEGO1/mxdsaction.cpp + LEGO1/mxdsactionlist.cpp LEGO1/mxdsanim.cpp LEGO1/mxdschunk.cpp LEGO1/mxdsevent.cpp diff --git a/LEGO1/mxdsactionlist.cpp b/LEGO1/mxdsactionlist.cpp new file mode 100644 index 00000000..86c75365 --- /dev/null +++ b/LEGO1/mxdsactionlist.cpp @@ -0,0 +1,21 @@ +#include "mxdsactionlist.h" +#include "mxdsaction.h" + +DECOMP_SIZE_ASSERT(MxDSActionList, 0x1c); + +// OFFSET: LEGO1 0x100c9c90 +MxS8 MxDSActionList::Compare(MxDSAction *p_var0, MxDSAction *p_var1) +{ + if (p_var1 == p_var0) + return 0; + if (p_var1 <= p_var0) + return 1; + return -1; +} + +// OFFSET: LEGO1 0x100c9cb0 +void MxDSActionList::Destroy(MxDSAction *p_action) +{ + if (p_action) + delete p_action; +} \ No newline at end of file diff --git a/LEGO1/mxdsactionlist.h b/LEGO1/mxdsactionlist.h new file mode 100644 index 00000000..4ae6e2a6 --- /dev/null +++ b/LEGO1/mxdsactionlist.h @@ -0,0 +1,28 @@ +#ifndef MXDSACTIONLIST_H +#define MXDSACTIONLIST_H + +#include "decomp.h" +#include "mxlist.h" + +class MxDSAction; + +// VTABLE 0x100dced8 +// SIZE 0x1c +class MxDSActionList : public MxList +{ +public: + MxDSActionList() { + this->m_unk18 = 0; + } + + virtual MxS8 Compare(MxDSAction *, MxDSAction *); // +0x14 + + static void Destroy(MxDSAction *p_action); + +private: + undefined m_unk18; +}; + +typedef MxListCursorChild MxDSActionListCursor; + +#endif // MXDSACTIONLIST_H diff --git a/LEGO1/mxdsmultiaction.cpp b/LEGO1/mxdsmultiaction.cpp index 0328a5fd..6cbccc39 100644 --- a/LEGO1/mxdsmultiaction.cpp +++ b/LEGO1/mxdsmultiaction.cpp @@ -5,12 +5,42 @@ DECOMP_SIZE_ASSERT(MxDSMultiAction, 0x9c) // OFFSET: LEGO1 0x100c9b90 MxDSMultiAction::MxDSMultiAction() { - // TODO this->SetType(MxDSType_MultiAction); + this->m_actions = new MxDSActionList; + this->m_actions->SetDestroy(MxDSActionList::Destroy); } -// OFFSET: LEGO1 0x100ca060 STUB +// OFFSET: LEGO1 0x100ca060 MxDSMultiAction::~MxDSMultiAction() { - // TODO + if (this->m_actions) + delete this->m_actions; } + +// OFFSET: LEGO1 0x100ca5e0 +undefined4 MxDSMultiAction::unk14() +{ + undefined4 result = MxDSAction::unk14(); + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) + result += action->unk14(); + + return result; +} + +// OFFSET: LEGO1 0x100ca6c0 +MxU32 MxDSMultiAction::GetSizeOnDisk() +{ + MxU32 totalSizeOnDisk = MxDSAction::GetSizeOnDisk() + 16; + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) + totalSizeOnDisk += action->GetSizeOnDisk(); + + this->m_sizeOnDisk = totalSizeOnDisk - MxDSAction::GetSizeOnDisk(); + + return totalSizeOnDisk; +} \ No newline at end of file diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 6e049965..7d4312f4 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -2,7 +2,7 @@ #define MXDSMULTIACTION_H #include "mxdsaction.h" -#include "decomp.h" +#include "mxdsactionlist.h" // VTABLE 0x100dcef0 // SIZE 0x9c @@ -25,8 +25,12 @@ class MxDSMultiAction : public MxDSAction return !strcmp(name, MxDSMultiAction::ClassName()) || MxDSAction::IsA(name); } - undefined4 m_unk0x94; - undefined4 m_unk0x98; + virtual undefined4 unk14(); // vtable+14; + virtual MxU32 GetSizeOnDisk(); // vtable+18; + +private: + MxU32 m_sizeOnDisk; + MxDSActionList *m_actions; }; #endif // MXDSMULTIACTION_H diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 013ef852..a4231c92 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -60,6 +60,7 @@ class MxList : protected MxListParent void Append(T*); MxU32 GetCount() { return m_count; } + void SetDestroy(void (*p_customDestructor)(T *)) { this->m_customDestructor = p_customDestructor; } friend class MxListCursor; From 611afb779984306116788b04cdb061e2af0f9b70 Mon Sep 17 00:00:00 2001 From: MS Date: Thu, 21 Sep 2023 05:27:27 -0400 Subject: [PATCH 15/87] Quick patch for EqualsDataProduct (#134) --- LEGO1/mxmatrix.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/LEGO1/mxmatrix.cpp b/LEGO1/mxmatrix.cpp index 534db6a9..1cc3c550 100644 --- a/LEGO1/mxmatrix.cpp +++ b/LEGO1/mxmatrix.cpp @@ -111,21 +111,20 @@ void MxMatrix::EqualsMxProduct(const MxMatrix *p_a, const MxMatrix *p_b) EqualsDataProduct(p_a->m_data, p_b->m_data); } -// Just a placeholder matrix multiply implementation. I think the decomp will -// look roughly like this but it's not close to matching and won't be until -// an exact match is found given it's all loop and float crunching. -// OFFSET: LEGO1 0x100024d0 STUB +// OFFSET: LEGO1 0x100024d0 void MxMatrix::EqualsDataProduct(const float *p_a, const float *p_b) { + float *cur = m_data; for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { - m_data[row * 4 + col] = 0.0f; + *cur = 0.0f; for (int k = 0; k < 4; ++k) { - m_data[row * 4 + col] += p_a[row * 4 + k] * p_b[k * 4 + col]; + *cur += p_a[row * 4 + k] * p_b[k * 4 + col]; } + cur++; } } } From b4258da0f5ff9a08ff9211b1169e431d94471f74 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Thu, 21 Sep 2023 14:51:24 -0400 Subject: [PATCH 16/87] MxLong Tickle() -> MxResult Tickle() (#135) * MxLong Tickle() -> MxResult Tickle() * Remove garbage * Fix implementations --- LEGO1/act2brick.cpp | 2 +- LEGO1/act2brick.h | 2 +- LEGO1/gasstation.cpp | 2 +- LEGO1/gasstation.h | 2 +- LEGO1/infocenter.cpp | 2 +- LEGO1/infocenter.h | 2 +- LEGO1/legoanimationmanager.cpp | 2 +- LEGO1/legoanimationmanager.h | 2 +- LEGO1/legocarbuild.cpp | 2 +- LEGO1/legocarbuild.h | 2 +- LEGO1/legocontrolmanager.cpp | 2 +- LEGO1/legocontrolmanager.h | 2 +- LEGO1/legoinputmanager.cpp | 2 +- LEGO1/legoinputmanager.h | 2 +- LEGO1/legopathcontroller.cpp | 2 +- LEGO1/legopathcontroller.h | 2 +- LEGO1/legoplantmanager.cpp | 2 +- LEGO1/legoplantmanager.h | 2 +- LEGO1/legosoundmanager.cpp | 2 +- LEGO1/legosoundmanager.h | 2 +- LEGO1/mxcore.cpp | 2 +- LEGO1/mxdiskstreamcontroller.cpp | 2 +- LEGO1/mxdiskstreamcontroller.h | 2 +- LEGO1/mxmediapresenter.cpp | 2 +- LEGO1/mxmediapresenter.h | 2 +- LEGO1/mxpresenter.cpp | 2 +- LEGO1/mxpresenter.h | 2 +- LEGO1/mxtransitionmanager.cpp | 2 +- LEGO1/mxtransitionmanager.h | 2 +- LEGO1/mxvideomanager.cpp | 2 +- LEGO1/mxvideomanager.h | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) diff --git a/LEGO1/act2brick.cpp b/LEGO1/act2brick.cpp index 84c8bbb3..dde79d0b 100644 --- a/LEGO1/act2brick.cpp +++ b/LEGO1/act2brick.cpp @@ -21,7 +21,7 @@ MxLong Act2Brick::Notify(MxParam &p) } // OFFSET: LEGO1 0x1007a7f0 STUB -MxLong Act2Brick::Tickle() +MxResult Act2Brick::Tickle() { // TODO diff --git a/LEGO1/act2brick.h b/LEGO1/act2brick.h index bf909198..65aba252 100644 --- a/LEGO1/act2brick.h +++ b/LEGO1/act2brick.h @@ -12,7 +12,7 @@ class Act2Brick : public LegoPathActor virtual ~Act2Brick() override; // vtable+0x0 virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxLong Tickle() override; // vtable+0x08 + virtual MxResult Tickle() override; // vtable+0x08 // OFFSET: LEGO1 0x1007a360 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/gasstation.cpp b/LEGO1/gasstation.cpp index 33590dc9..eb178ef0 100644 --- a/LEGO1/gasstation.cpp +++ b/LEGO1/gasstation.cpp @@ -21,7 +21,7 @@ MxLong GasStation::Notify(MxParam &p) } // OFFSET: LEGO1 0x10005c90 STUB -MxLong GasStation::Tickle() +MxResult GasStation::Tickle() { // TODO diff --git a/LEGO1/gasstation.h b/LEGO1/gasstation.h index 7f2263d0..e88c028a 100644 --- a/LEGO1/gasstation.h +++ b/LEGO1/gasstation.h @@ -13,7 +13,7 @@ class GasStation : public LegoWorld virtual ~GasStation() override; // vtable+0x0 virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x10004780 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/infocenter.cpp b/LEGO1/infocenter.cpp index b9ea67c6..eb7e65fc 100644 --- a/LEGO1/infocenter.cpp +++ b/LEGO1/infocenter.cpp @@ -21,7 +21,7 @@ MxLong Infocenter::Notify(MxParam &p) } // OFFSET: LEGO1 0x10070af0 STUB -MxLong Infocenter::Tickle() +MxResult Infocenter::Tickle() { // TODO diff --git a/LEGO1/infocenter.h b/LEGO1/infocenter.h index a6e06f0f..1d385993 100644 --- a/LEGO1/infocenter.h +++ b/LEGO1/infocenter.h @@ -12,7 +12,7 @@ class Infocenter : public LegoWorld virtual ~Infocenter() override; virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x1006eb40 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/legoanimationmanager.cpp b/LEGO1/legoanimationmanager.cpp index d396d431..20e0a0e3 100644 --- a/LEGO1/legoanimationmanager.cpp +++ b/LEGO1/legoanimationmanager.cpp @@ -23,7 +23,7 @@ MxLong LegoAnimationManager::Notify(MxParam &p) } // OFFSET: LEGO1 0x10061cc0 STUB -MxLong LegoAnimationManager::Tickle() +MxResult LegoAnimationManager::Tickle() { // TODO diff --git a/LEGO1/legoanimationmanager.h b/LEGO1/legoanimationmanager.h index 49b95f94..ec07603d 100644 --- a/LEGO1/legoanimationmanager.h +++ b/LEGO1/legoanimationmanager.h @@ -12,7 +12,7 @@ class LegoAnimationManager : public MxCore virtual ~LegoAnimationManager() override; // vtable+0x0 virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x1005ec80 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/legocarbuild.cpp b/LEGO1/legocarbuild.cpp index c9254c37..e204529b 100644 --- a/LEGO1/legocarbuild.cpp +++ b/LEGO1/legocarbuild.cpp @@ -21,7 +21,7 @@ MxLong LegoCarBuild::Notify(MxParam &p) } // OFFSET: LEGO1 0x100238b0 STUB -MxLong LegoCarBuild::Tickle() +MxResult LegoCarBuild::Tickle() { // TODO diff --git a/LEGO1/legocarbuild.h b/LEGO1/legocarbuild.h index d320cd6e..1d68b0c1 100644 --- a/LEGO1/legocarbuild.h +++ b/LEGO1/legocarbuild.h @@ -12,7 +12,7 @@ class LegoCarBuild : public LegoWorld virtual ~LegoCarBuild() override; virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x10022940 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/legocontrolmanager.cpp b/LEGO1/legocontrolmanager.cpp index 16733e13..91ff8c39 100644 --- a/LEGO1/legocontrolmanager.cpp +++ b/LEGO1/legocontrolmanager.cpp @@ -13,7 +13,7 @@ LegoControlManager::~LegoControlManager() } // OFFSET: LEGO1 0x10029600 STUB -MxLong LegoControlManager::Tickle() +MxResult LegoControlManager::Tickle() { // TODO diff --git a/LEGO1/legocontrolmanager.h b/LEGO1/legocontrolmanager.h index c4563776..0088ac0f 100644 --- a/LEGO1/legocontrolmanager.h +++ b/LEGO1/legocontrolmanager.h @@ -10,7 +10,7 @@ class LegoControlManager : public MxCore LegoControlManager(); virtual ~LegoControlManager() override; // vtable+0x0 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x10028cb0 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index 90be0c2c..7c6489ee 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -35,7 +35,7 @@ void LegoInputManager::UnRegister(MxCore *) } // OFFSET: LEGO1 0x1005b8b0 STUB -MxLong LegoInputManager::Tickle() +MxResult LegoInputManager::Tickle() { // TODO diff --git a/LEGO1/legoinputmanager.h b/LEGO1/legoinputmanager.h index 7ae2dd62..3a35d4b1 100644 --- a/LEGO1/legoinputmanager.h +++ b/LEGO1/legoinputmanager.h @@ -26,7 +26,7 @@ class LegoInputManager : public MxPresenter __declspec(dllexport) void Register(MxCore *); __declspec(dllexport) void UnRegister(MxCore *); - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 undefined m_pad40[0x15c]; int m_joystickIndex; diff --git a/LEGO1/legopathcontroller.cpp b/LEGO1/legopathcontroller.cpp index 0cebbc0f..f8b64109 100644 --- a/LEGO1/legopathcontroller.cpp +++ b/LEGO1/legopathcontroller.cpp @@ -13,7 +13,7 @@ LegoPathController::~LegoPathController() } // OFFSET: LEGO1 0x10045c10 STUB -MxLong LegoPathController::Tickle() +MxResult LegoPathController::Tickle() { // TODO return 0; diff --git a/LEGO1/legopathcontroller.h b/LEGO1/legopathcontroller.h index ba415076..61dbdcfe 100644 --- a/LEGO1/legopathcontroller.h +++ b/LEGO1/legopathcontroller.h @@ -11,7 +11,7 @@ class LegoPathController : public MxCore LegoPathController(); virtual ~LegoPathController() override; - virtual MxLong Tickle() override; // vtable+08 + virtual MxResult Tickle() override; // vtable+08 // OFFSET: LEGO1 0x10045110 inline const char *ClassName() const override // vtable+0xc diff --git a/LEGO1/legoplantmanager.cpp b/LEGO1/legoplantmanager.cpp index eee83726..515d330d 100644 --- a/LEGO1/legoplantmanager.cpp +++ b/LEGO1/legoplantmanager.cpp @@ -13,7 +13,7 @@ LegoPlantManager::~LegoPlantManager() } // OFFSET: LEGO1 0x10026e00 STUB -MxLong LegoPlantManager::Tickle() +MxResult LegoPlantManager::Tickle() { // TODO diff --git a/LEGO1/legoplantmanager.h b/LEGO1/legoplantmanager.h index 3e8bfefe..b8e8dd9d 100644 --- a/LEGO1/legoplantmanager.h +++ b/LEGO1/legoplantmanager.h @@ -11,7 +11,7 @@ class LegoPlantManager : public MxCore LegoPlantManager(); virtual ~LegoPlantManager() override; // vtable+0x0 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x10026290 inline const char *ClassName() const override // vtable+0xc diff --git a/LEGO1/legosoundmanager.cpp b/LEGO1/legosoundmanager.cpp index e56747f6..01f8fee5 100644 --- a/LEGO1/legosoundmanager.cpp +++ b/LEGO1/legosoundmanager.cpp @@ -13,7 +13,7 @@ LegoSoundManager::~LegoSoundManager() } // OFFSET: LEGO1 0x1002a3a0 STUB -MxLong LegoSoundManager::Tickle() +MxResult LegoSoundManager::Tickle() { // TODO return 0; diff --git a/LEGO1/legosoundmanager.h b/LEGO1/legosoundmanager.h index 1d191e03..90e23fba 100644 --- a/LEGO1/legosoundmanager.h +++ b/LEGO1/legosoundmanager.h @@ -10,7 +10,7 @@ class LegoSoundManager : public MxSoundManager public: LegoSoundManager(); virtual ~LegoSoundManager() override; - virtual MxLong Tickle() override; // vtable+08 + virtual MxResult Tickle() override; // vtable+08 private: void Init(); diff --git a/LEGO1/mxcore.cpp b/LEGO1/mxcore.cpp index 78441d8d..ab73e242 100644 --- a/LEGO1/mxcore.cpp +++ b/LEGO1/mxcore.cpp @@ -22,7 +22,7 @@ MxLong MxCore::Notify(MxParam &p) } // OFFSET: LEGO1 0x10001f70 -MxLong MxCore::Tickle() +MxResult MxCore::Tickle() { return 0; } \ No newline at end of file diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp index 61243410..9e37edc4 100644 --- a/LEGO1/mxdiskstreamcontroller.cpp +++ b/LEGO1/mxdiskstreamcontroller.cpp @@ -13,7 +13,7 @@ MxDiskStreamController::~MxDiskStreamController() } // OFFSET: LEGO1 0x100c8640 STUB -MxLong MxDiskStreamController::Tickle() +MxResult MxDiskStreamController::Tickle() { // TODO diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index c0142663..1f66984c 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -14,7 +14,7 @@ class MxDiskStreamController : public MxStreamController MxDiskStreamController(); virtual ~MxDiskStreamController() override; - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x100c7360 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index 31e68abc..6a59a0ec 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -3,7 +3,7 @@ DECOMP_SIZE_ASSERT(MxMediaPresenter, 0x50); // OFFSET: LEGO1 0x100b5d10 STUB -MxLong MxMediaPresenter::Tickle() +MxResult MxMediaPresenter::Tickle() { // TODO return 0; diff --git a/LEGO1/mxmediapresenter.h b/LEGO1/mxmediapresenter.h index 64de0614..741ab49f 100644 --- a/LEGO1/mxmediapresenter.h +++ b/LEGO1/mxmediapresenter.h @@ -14,7 +14,7 @@ class MxMediaPresenter : public MxPresenter Init(); } - virtual MxLong Tickle() override; // vtable+0x8, override MxCore + virtual MxResult Tickle() override; // vtable+0x8, override MxCore // OFFSET: LEGO1 0x1000c5c0 inline virtual const char *ClassName() const override // vtable+0xc diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index e82aa3a4..838b0af3 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -79,7 +79,7 @@ MxPresenter::~MxPresenter() } // OFFSET: LEGO1 0x100b5200 -MxLong MxPresenter::Tickle() +MxResult MxPresenter::Tickle() { MxAutoLocker lock(&this->m_criticalSection); diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index b7e99edf..86b078a6 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -29,7 +29,7 @@ class MxPresenter : public MxCore MxPresenter() { Init(); } __declspec(dllexport) virtual ~MxPresenter(); // vtable+0x0 - __declspec(dllexport) virtual MxLong Tickle() override; // vtable+0x8 + __declspec(dllexport) virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x1000bfe0 inline virtual const char *ClassName() const override// vtable+0xc diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 8af3f497..fdae06ea 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -13,7 +13,7 @@ MxTransitionManager::~MxTransitionManager() } // OFFSET: LEGO1 0x1004bac0 STUB -MxLong MxTransitionManager::Tickle() +MxResult MxTransitionManager::Tickle() { // TODO diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index c6cc28aa..215cd2d7 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -14,7 +14,7 @@ class MxTransitionManager : public MxCore __declspec(dllexport) void SetWaitIndicator(MxVideoPresenter *videoPresenter); - virtual MxLong Tickle(); // vtable+0x8 + virtual MxResult Tickle(); // vtable+0x8 }; #endif // MXTRANSITIONMANAGER_H diff --git a/LEGO1/mxvideomanager.cpp b/LEGO1/mxvideomanager.cpp index 81d431a9..8f64dbd4 100644 --- a/LEGO1/mxvideomanager.cpp +++ b/LEGO1/mxvideomanager.cpp @@ -15,7 +15,7 @@ MxVideoManager::~MxVideoManager() } // OFFSET: LEGO1 0x100bea90 -MxLong MxVideoManager::Tickle() +MxResult MxVideoManager::Tickle() { MxAutoLocker lock(&this->m_criticalSection); diff --git a/LEGO1/mxvideomanager.h b/LEGO1/mxvideomanager.h index a7cde92f..4068b793 100644 --- a/LEGO1/mxvideomanager.h +++ b/LEGO1/mxvideomanager.h @@ -13,7 +13,7 @@ class MxVideoManager : public MxMediaManager public: virtual ~MxVideoManager(); - virtual MxLong Tickle(); // vtable+0x8 + virtual MxResult Tickle(); // vtable+0x8 __declspec(dllexport) void InvalidateRect(MxRect32 &); __declspec(dllexport) virtual MxLong RealizePalette(MxPalette *); // vtable+0x30 From 6dd94d36263c1aed0e56e6be4ad5612e1a92f935 Mon Sep 17 00:00:00 2001 From: MS Date: Fri, 22 Sep 2023 17:42:23 -0400 Subject: [PATCH 17/87] PresenterNameDispatch (#137) * PresenterNameDispatch * Use reference for PresenterNameDispatch param - fix or add const markers so we can use a const reference --- LEGO1/mxdsaction.h | 3 +++ LEGO1/mxdsmediaaction.h | 2 ++ LEGO1/mxdsobject.h | 5 ++-- LEGO1/mxpresenter.cpp | 59 +++++++++++++++++++++++++++++++++++++++++ LEGO1/mxpresenter.h | 2 ++ 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 3028a43d..265f0a6f 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -12,6 +12,7 @@ class MxDSAction : public MxDSObject public: enum { + Flag_Looping = 0x01, Flag_Enabled = 0x20, Flag_Parsed = 0x80, }; @@ -55,6 +56,8 @@ class MxDSAction : public MxDSObject inline const MxVector3Data &GetLocation() const { return m_location; } inline void SetOmni(MxOmni *p_omni) { m_omni = p_omni; } + inline MxBool IsLooping() const { return this->m_flags & Flag_Looping; } + private: MxU32 m_sizeOnDisk; MxU32 m_flags; diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index 1ebbfdd2..f3c03839 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -32,6 +32,8 @@ class MxDSMediaAction : public MxDSAction virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; void CopyMediaSrcPath(const char *p_mediaSrcPath); + + inline MxS32 GetMediaFormat() const { return this->m_mediaFormat; } private: MxU32 m_sizeOnDisk; char *m_mediaSrcPath; diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index 0b247a6a..1ca3d98a 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -40,9 +40,10 @@ class MxDSObject : public MxCore inline void SetObjectId(MxU32 p_objectId) { this->m_objectId = p_objectId; } inline void SetUnknown24(MxS16 p_unk24) { this->m_unk24 = p_unk24; } -protected: + inline char *GetSourceName() const { return this->m_sourceName; } + inline void SetType(MxDSType p_type) { this->m_type = p_type; } - inline MxDSType GetType() { return (MxDSType) this->m_type; } + inline MxDSType GetType() const { return (MxDSType) this->m_type; } private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 838b0af3..940248a0 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -2,6 +2,8 @@ #include "mxautolocker.h" #include "mxparam.h" #include "legoomni.h" +#include "mxdsanim.h" +#include "mxdssound.h" #include #include "decomp.h" @@ -155,6 +157,63 @@ void MxPresenter::Enable(MxBool p_enable) } } +// OFFSET: LEGO1 0x100b5310 +char *PresenterNameDispatch(const MxDSAction &p_action) +{ + char *name = p_action.GetSourceName(); + MxS32 format; + + if (!name || strlen(name) == 0) { + switch (p_action.GetType()) { + case MxDSType_Anim: + format = ((MxDSAnim&)p_action).GetMediaFormat(); + switch (format) { + case FOURCC(' ', 'F', 'L', 'C'): + name = !p_action.IsLooping() ? + "MxFlcPresenter" : + "MxLoopingFlcPresenter"; + break; + case FOURCC(' ', 'S', 'M', 'K'): + name = !p_action.IsLooping() ? + "MxSmkPresenter" : + "MxLoopingSmkPresenter"; + break; + } + break; + + case MxDSType_Sound: + format = ((MxDSSound&)p_action).GetMediaFormat(); + switch(format) { + case FOURCC(' ', 'M', 'I', 'D'): + name = !p_action.IsLooping() ? + "MxMIDIPresenter" : + "MxLoopingMIDIPresenter"; + break; + case FOURCC(' ', 'W', 'A', 'V'): + name = "MxWavePresenter"; + break; + } + break; + + case MxDSType_SerialAction: + case MxDSType_ParallelAction: + case MxDSType_SelectAction: + name = "MxCompositePresenter"; + break; + + case MxDSType_Event: + name = "MxEventPresenter"; + break; + + case MxDSType_Still: + name = "MxStillPresenter"; + break; + } + } + + return name; +} + // OFFSET: LEGO1 0x100b54c0 MxBool MxPresenter::IsEnabled() { diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 86b078a6..1537d2d3 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -84,4 +84,6 @@ class MxPresenter : public MxCore MxPresenter *m_unkPresenter; // 0x3c }; +char *PresenterNameDispatch(const MxDSAction &); + #endif // MXPRESENTER_H From 548f337cad9bd99636430eb8dc8e5272aeb387a9 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 25 Sep 2023 13:08:19 -0400 Subject: [PATCH 18/87] Implement/match remaining MxDSMultiAction functions (#136) * Implement/match MxDSMultiAction::Deserialize * Implement remaining functions of MxDSMultiAction * Remove space --- LEGO1/mxdsaction.h | 2 + LEGO1/mxdsmultiaction.cpp | 108 ++++++++++++++++++++++++++++++++++++++ LEGO1/mxdsmultiaction.h | 9 ++++ LEGO1/mxlist.h | 7 +++ 4 files changed, 126 insertions(+) diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 265f0a6f..ce54cfc4 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -76,6 +76,8 @@ class MxDSAction : public MxDSObject undefined4 m_unk84; undefined4 m_unk88; MxOmni *m_omni; // 0x8c + +protected: MxLong m_someTimingField; // 0x90 }; diff --git a/LEGO1/mxdsmultiaction.cpp b/LEGO1/mxdsmultiaction.cpp index 6cbccc39..2580b813 100644 --- a/LEGO1/mxdsmultiaction.cpp +++ b/LEGO1/mxdsmultiaction.cpp @@ -17,6 +17,77 @@ MxDSMultiAction::~MxDSMultiAction() delete this->m_actions; } +// OFFSET: LEGO1 0x100ca0d0 +void MxDSMultiAction::CopyFrom(MxDSMultiAction &p_dsMultiAction) +{ + this->m_actions->DeleteAll(); + + MxDSActionListCursor cursor(p_dsMultiAction.m_actions); + MxDSAction *action; + while (cursor.Next(action)) + this->m_actions->Append(action->Clone()); +} + +// OFFSET: LEGO1 0x100ca260 +MxDSMultiAction &MxDSMultiAction::operator=(MxDSMultiAction &p_dsMultiAction) +{ + if (this == &p_dsMultiAction) + return *this; + + MxDSAction::operator=(p_dsMultiAction); + this->CopyFrom(p_dsMultiAction); + return *this; +} + +// OFFSET: LEGO1 0x100ca290 +void MxDSMultiAction::SetSomeTimingField(MxLong p_someTimingField) +{ + this->m_someTimingField = p_someTimingField; + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) + action->SetSomeTimingField(p_someTimingField); +} + +// OFFSET: LEGO1 0x100ca370 +void MxDSMultiAction::MergeFrom(MxDSAction &p_dsMultiAction) +{ + MxDSAction::MergeFrom(p_dsMultiAction); + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) + action->MergeFrom(p_dsMultiAction); +} + +// OFFSET: LEGO1 0x100ca450 +MxBool MxDSMultiAction::HasId(MxU32 p_objectId) +{ + if (this->GetObjectId() == p_objectId) + return TRUE; + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) { + if (action->HasId(p_objectId)) + return TRUE; + } + + return FALSE; +} + +// OFFSET: LEGO1 0x100ca550 +MxDSAction *MxDSMultiAction::Clone() +{ + MxDSMultiAction *clone = new MxDSMultiAction(); + + if (clone) + *clone = *this; + + return clone; +} + // OFFSET: LEGO1 0x100ca5e0 undefined4 MxDSMultiAction::unk14() { @@ -43,4 +114,41 @@ MxU32 MxDSMultiAction::GetSizeOnDisk() this->m_sizeOnDisk = totalSizeOnDisk - MxDSAction::GetSizeOnDisk(); return totalSizeOnDisk; +} + +// OFFSET: LEGO1 0x100ca7b0 +void MxDSMultiAction::Deserialize(char **p_source, MxS16 p_unk24) +{ + MxDSAction::Deserialize(p_source, p_unk24); + + MxU32 extraFlag = *(MxU32*)(*p_source + 4) & 1; + *p_source += 12; + + MxU32 count = *(MxU32*) *p_source; + *p_source += sizeof(count); + + if (count) { + while (count--) { + MxU32 extraFlag = *(MxU32*)(*p_source + 4) & 1; + *p_source += 8; + + MxDSAction *action = (MxDSAction*) DeserializeDSObjectDispatch(p_source, p_unk24); + *p_source += extraFlag; + + this->m_actions->Append(action); + } + } + + *p_source += extraFlag; +} + +// OFFSET: LEGO1 0x100ca8c0 +void MxDSMultiAction::SetAtomId(MxAtomId p_atomId) +{ + MxDSAction::SetAtomId(p_atomId); + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) + action->SetAtomId(p_atomId); } \ No newline at end of file diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 7d4312f4..21b1dc03 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -12,6 +12,9 @@ class MxDSMultiAction : public MxDSAction MxDSMultiAction(); virtual ~MxDSMultiAction() override; + void CopyFrom(MxDSMultiAction &p_dsMultiAction); + MxDSMultiAction &operator=(MxDSMultiAction &p_dsMultiAction); + // OFFSET: LEGO1 0x100c9f50 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -27,6 +30,12 @@ class MxDSMultiAction : public MxDSAction virtual undefined4 unk14(); // vtable+14; virtual MxU32 GetSizeOnDisk(); // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; + virtual void SetAtomId(MxAtomId p_atomId); // vtable+20; + virtual MxDSAction *Clone(); // vtable+2c; + virtual void MergeFrom(MxDSAction &p_dsAction); // vtable+30; + virtual MxBool HasId(MxU32 p_objectId); // vtable+34; + virtual void SetSomeTimingField(MxLong p_someTimingField); // vtable+38; private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index a4231c92..0de71903 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -59,6 +59,7 @@ class MxList : protected MxListParent virtual ~MxList(); void Append(T*); + void DeleteAll(); MxU32 GetCount() { return m_count; } void SetDestroy(void (*p_customDestructor)(T *)) { this->m_customDestructor = p_customDestructor; } @@ -115,6 +116,12 @@ class MxListCursorChildChild : public MxListCursorChild template // OFFSET: LEGO1 0x1001ce20 MxList::~MxList() +{ + DeleteAll(); +} + +template +inline void MxList::DeleteAll() { for (MxListEntry *t = m_first;;) { if (!t) From b2ec18f943fc91fdc2869026f394e8e94c627678 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 25 Sep 2023 14:58:15 -0400 Subject: [PATCH 19/87] Implement/match MxDSParallelAction (#138) * Implement/match MxDSParallelAction * Fix type * Remove space * Add neccessary MxDSMultiAction functions --- LEGO1/mxdsaction.cpp | 4 +- LEGO1/mxdsaction.h | 5 ++- LEGO1/mxdsmediaaction.h | 1 + LEGO1/mxdsmultiaction.h | 2 + LEGO1/mxdsparallelaction.cpp | 72 ++++++++++++++++++++++++++++++++++++ LEGO1/mxdsparallelaction.h | 5 +++ 6 files changed, 86 insertions(+), 3 deletions(-) diff --git a/LEGO1/mxdsaction.cpp b/LEGO1/mxdsaction.cpp index cccea39c..536fbd8a 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -96,8 +96,8 @@ void MxDSAction::Deserialize(char **p_source, MxS16 p_unk24) this->m_flags = *(MxU32*) *p_source; *p_source += sizeof(MxU32); - this->m_startTime = *(DWORD*) *p_source; - *p_source += sizeof(DWORD); + this->m_startTime = *(MxLong*) *p_source; + *p_source += sizeof(MxLong); this->m_duration = *(MxLong*) *p_source; *p_source += sizeof(MxLong); this->m_loopCount = *(MxS32*) *p_source; diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index ce54cfc4..7d9d2f0c 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -13,6 +13,7 @@ class MxDSAction : public MxDSObject enum { Flag_Looping = 0x01, + Flag_Bit3 = 0x04, Flag_Enabled = 0x20, Flag_Parsed = 0x80, }; @@ -53,15 +54,17 @@ class MxDSAction : public MxDSObject inline void SetFlags(MxU32 m_flags) { this->m_flags = m_flags; } inline char *GetExtraData() { return m_extraData; } inline MxU16 GetExtraLength() const { return m_extraLength; } + inline MxLong GetStartTime() const { return m_startTime; } inline const MxVector3Data &GetLocation() const { return m_location; } inline void SetOmni(MxOmni *p_omni) { m_omni = p_omni; } inline MxBool IsLooping() const { return this->m_flags & Flag_Looping; } + inline MxBool IsBit3() const { return this->m_flags & Flag_Bit3; } private: MxU32 m_sizeOnDisk; MxU32 m_flags; - DWORD m_startTime; + MxLong m_startTime; protected: MxLong m_duration; diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index f3c03839..cc710425 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -34,6 +34,7 @@ class MxDSMediaAction : public MxDSAction void CopyMediaSrcPath(const char *p_mediaSrcPath); inline MxS32 GetMediaFormat() const { return this->m_mediaFormat; } + inline MxLong GetSustainTime() const { return this->m_sustainTime; } private: MxU32 m_sizeOnDisk; char *m_mediaSrcPath; diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 21b1dc03..4063343c 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -39,6 +39,8 @@ class MxDSMultiAction : public MxDSAction private: MxU32 m_sizeOnDisk; + +protected: MxDSActionList *m_actions; }; diff --git a/LEGO1/mxdsparallelaction.cpp b/LEGO1/mxdsparallelaction.cpp index 2e0d66da..564e39c6 100644 --- a/LEGO1/mxdsparallelaction.cpp +++ b/LEGO1/mxdsparallelaction.cpp @@ -1,4 +1,5 @@ #include "mxdsparallelaction.h" +#include "mxdsmediaaction.h" DECOMP_SIZE_ASSERT(MxDSParallelAction, 0x9c) @@ -12,3 +13,74 @@ MxDSParallelAction::MxDSParallelAction() MxDSParallelAction::~MxDSParallelAction() { } + +// OFFSET: LEGO1 0x100cb090 +void MxDSParallelAction::CopyFrom(MxDSParallelAction &p_dsParallelAction) +{ +} + +// OFFSET: LEGO1 0x100cb0a0 +MxDSParallelAction &MxDSParallelAction::operator=(MxDSParallelAction &p_dsParallelAction) +{ + if (this == &p_dsParallelAction) + return *this; + + MxDSMultiAction::operator=(p_dsParallelAction); + this->CopyFrom(p_dsParallelAction); + return *this; +} + +// OFFSET: LEGO1 0x100cb0d0 +MxDSAction *MxDSParallelAction::Clone() +{ + MxDSParallelAction *clone = new MxDSParallelAction(); + + if (clone) + *clone = *this; + + return clone; +} + +// OFFSET: LEGO1 0x100cb160 +MxLong MxDSParallelAction::GetDuration() +{ + if (this->m_duration) + return this->m_duration; + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + + while (cursor.Next(action)) { + if (!action) + continue; + + MxLong duration = action->GetDuration(); + if (duration == -1) { + this->m_duration = -1; + break; + } + + duration += action->GetStartTime(); + if (action->IsA("MxDSMediaAction")) { + MxLong sustainTime = ((MxDSMediaAction*) action)->GetSustainTime(); + + if (sustainTime == -1) + duration = -1; + else if (sustainTime) + duration += sustainTime; + } + + if (duration == -1) { + this->m_duration = -1; + break; + } + + if (this->m_duration < duration) + this->m_duration = duration; + } + + if (this->IsBit3()) + this->m_duration *= this->m_loopCount; + + return this->m_duration; +} \ No newline at end of file diff --git a/LEGO1/mxdsparallelaction.h b/LEGO1/mxdsparallelaction.h index 067dc82c..962ba34b 100644 --- a/LEGO1/mxdsparallelaction.h +++ b/LEGO1/mxdsparallelaction.h @@ -11,6 +11,9 @@ class MxDSParallelAction : public MxDSMultiAction MxDSParallelAction(); virtual ~MxDSParallelAction() override; + void CopyFrom(MxDSParallelAction &p_dsParallelAction); + MxDSParallelAction &operator=(MxDSParallelAction &p_dsParallelAction); + // OFFSET: LEGO1 0x100caf00 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -24,6 +27,8 @@ class MxDSParallelAction : public MxDSMultiAction return !strcmp(name, MxDSParallelAction::ClassName()) || MxDSMultiAction::IsA(name); } + virtual MxLong GetDuration(); // vtable+24; + virtual MxDSAction *Clone(); // vtable+2c; }; #endif // MXDSPARALLELACTION_H From e1e2abc5107c1754d7b6a52dba9a2a84b3b3de08 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 25 Sep 2023 15:53:57 -0400 Subject: [PATCH 20/87] Implement/match MxDSSerialAction (#139) * Implement/match MxDSSerialAction * Add neccessary MxDSMultiAction functions --- LEGO1/mxdsactionlist.cpp | 1 + LEGO1/mxdsserialaction.cpp | 70 ++++++++++++++++++++++++++++++++++++-- LEGO1/mxdsserialaction.h | 10 +++++- LEGO1/mxpresenterlist.cpp | 1 + 4 files changed, 78 insertions(+), 4 deletions(-) diff --git a/LEGO1/mxdsactionlist.cpp b/LEGO1/mxdsactionlist.cpp index 86c75365..46eb4e36 100644 --- a/LEGO1/mxdsactionlist.cpp +++ b/LEGO1/mxdsactionlist.cpp @@ -2,6 +2,7 @@ #include "mxdsaction.h" DECOMP_SIZE_ASSERT(MxDSActionList, 0x1c); +DECOMP_SIZE_ASSERT(MxDSActionListCursor, 0x10); // OFFSET: LEGO1 0x100c9c90 MxS8 MxDSActionList::Compare(MxDSAction *p_var0, MxDSAction *p_var1) diff --git a/LEGO1/mxdsserialaction.cpp b/LEGO1/mxdsserialaction.cpp index c6aa541f..7196b1b7 100644 --- a/LEGO1/mxdsserialaction.cpp +++ b/LEGO1/mxdsserialaction.cpp @@ -1,16 +1,80 @@ #include "mxdsserialaction.h" +#include "mxdsmediaaction.h" DECOMP_SIZE_ASSERT(MxDSSerialAction, 0xa8) // OFFSET: LEGO1 0x100ca9d0 MxDSSerialAction::MxDSSerialAction() { - // TODO this->SetType(MxDSType_SerialAction); + this->m_cursor = new MxDSActionListCursor(this->m_actions); + this->m_unk0xa0 = 0; } -// OFFSET: LEGO1 0x100cac10 STUB +// OFFSET: LEGO1 0x100caac0 +void MxDSSerialAction::SetDuration(MxLong p_duration) +{ + this->m_duration = p_duration; +} + +// OFFSET: LEGO1 0x100cac10 MxDSSerialAction::~MxDSSerialAction() { - // TODO + if (this->m_cursor) + delete this->m_cursor; + + this->m_cursor = NULL; } + +// OFFSET: LEGO1 0x100cac90 +void MxDSSerialAction::CopyFrom(MxDSSerialAction &p_dsSerialAction) +{ +} + +// OFFSET: LEGO1 0x100caca0 +MxDSSerialAction &MxDSSerialAction::operator=(MxDSSerialAction &p_dsSerialAction) +{ + if (this == &p_dsSerialAction) + return *this; + + MxDSMultiAction::operator=(p_dsSerialAction); + this->CopyFrom(p_dsSerialAction); + return *this; +} + +// OFFSET: LEGO1 0x100cacd0 +MxDSAction *MxDSSerialAction::Clone() +{ + MxDSSerialAction *clone = new MxDSSerialAction(); + + if (clone) + *clone = *this; + + return clone; +} + +// OFFSET: LEGO1 0x100cad60 +MxLong MxDSSerialAction::GetDuration() +{ + if (this->m_duration) + return this->m_duration; + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + + while (cursor.Next(action)) { + if (!action) + continue; + + this->m_duration += action->GetDuration() + action->GetStartTime(); + + if (action->IsA("MxDSMediaAction")) { + MxLong sustainTime = ((MxDSMediaAction*) action)->GetSustainTime(); + + if (sustainTime && sustainTime != -1) + this->m_duration += sustainTime; + } + } + + return this->m_duration; +} \ No newline at end of file diff --git a/LEGO1/mxdsserialaction.h b/LEGO1/mxdsserialaction.h index 6bf30c0f..e2f6cd72 100644 --- a/LEGO1/mxdsserialaction.h +++ b/LEGO1/mxdsserialaction.h @@ -12,6 +12,9 @@ class MxDSSerialAction : public MxDSMultiAction MxDSSerialAction(); virtual ~MxDSSerialAction() override; + void CopyFrom(MxDSSerialAction &p_dsSerialAction); + MxDSSerialAction &operator=(MxDSSerialAction &p_dsSerialAction); + // OFFSET: LEGO1 0x100caad0 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -25,7 +28,12 @@ class MxDSSerialAction : public MxDSMultiAction return !strcmp(name, MxDSSerialAction::ClassName()) || MxDSMultiAction::IsA(name); } - undefined4 m_unk0x9c; + virtual MxLong GetDuration(); // vtable+24; + virtual void SetDuration(MxLong p_duration); // vtable+28; + virtual MxDSAction *Clone(); // vtable+2c; + +private: + MxDSActionListCursor *m_cursor; undefined4 m_unk0xa0; undefined4 m_unk0xa4; }; diff --git a/LEGO1/mxpresenterlist.cpp b/LEGO1/mxpresenterlist.cpp index ca3f15a8..1edb6e12 100644 --- a/LEGO1/mxpresenterlist.cpp +++ b/LEGO1/mxpresenterlist.cpp @@ -2,6 +2,7 @@ #include "mxpresenter.h" DECOMP_SIZE_ASSERT(MxPresenterList, 0x18); +DECOMP_SIZE_ASSERT(MxPresenterListCursor, 0x10); // OFFSET: LEGO1 0x1001cd00 MxS8 MxPresenterList::Compare(MxPresenter *p_var0, MxPresenter *p_var1) From 3f6e3af8cad2d6880db7ec2814f44e3648727d5d Mon Sep 17 00:00:00 2001 From: MattKC <34096995+itsmattkc@users.noreply.github.com> Date: Mon, 25 Sep 2023 13:28:25 -0700 Subject: [PATCH 21/87] Fix LegoOmni vtable (#140) --- ISLE/isleapp.cpp | 10 +++--- LEGO1/legoomni.cpp | 51 +++++++++++++++--------------- LEGO1/legoomni.h | 30 +++++++++--------- LEGO1/mxbackgroundaudiomanager.cpp | 2 ++ LEGO1/mxdsaction.cpp | 5 +++ LEGO1/mxdsaction.h | 6 ++-- LEGO1/mxomni.cpp | 5 +-- LEGO1/mxomni.h | 9 +++--- 8 files changed, 65 insertions(+), 53 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 198389a3..c20f1652 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -91,9 +91,9 @@ void IsleApp::Close() VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveAll(NULL); Lego()->RemoveWorld(ds.GetAtomId(), ds.GetObjectId()); - Lego()->vtable24(ds); + Lego()->DeleteObject(ds); TransitionManager()->SetWaitIndicator(NULL); - Lego()->vtable3c(); + Lego()->vtable0x3c(); MxLong lVar8; do { @@ -101,7 +101,7 @@ void IsleApp::Close() } while (lVar8 == 0); while (Lego()) { - if (Lego()->vtable28(ds) != FALSE) { + if (Lego()->DoesEntityExist(ds)) { break; } @@ -232,7 +232,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine g_reqEnableRMDevice = 0; VideoManager()->EnableRMDevice(); g_rmDisabled = 0; - Lego()->vtable3c(); + Lego()->vtable0x3c(); } if (g_closed) { @@ -379,7 +379,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } else if (!valid) { g_rmDisabled = 1; - Lego()->vtable38(); + Lego()->StartTimer(); VideoManager()->DisableRMDevice(); } } diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index cda6d9ff..1dd7a561 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -253,48 +253,49 @@ void LegoOmni::Destroy() // FIXME: Stub } -void LegoOmni::vtable20() +void LegoOmni::vtable0x20() { // FIXME: Stub } -void LegoOmni::vtable24(MxDSAction &ds) +void LegoOmni::DeleteObject(MxDSAction &ds) { // FIXME: Stub } -MxBool LegoOmni::vtable28(MxDSAction &ds) +MxBool LegoOmni::DoesEntityExist(MxDSAction &ds) { // FIXME: Stub return TRUE; } -void LegoOmni::vtable2c() +void LegoOmni::vtable0x2c() { // FIXME: Stub } -void LegoOmni::vtable30() -{ - // FIXME: Stub -} - -void LegoOmni::vtable34() -{ - // FIXME: Stub -} - -void LegoOmni::vtable38() -{ - // FIXME: Stub -} - -void LegoOmni::vtable3c() -{ - // FIXME: Stub -} - -unsigned char LegoOmni::vtable40() +int LegoOmni::vtable0x30(char*, int, MxCore*) +{ + // FIXME: Stub + return 0; +} + +void LegoOmni::NotifyCurrentEntity() +{ + // FIXME: Stub +} + +void LegoOmni::StartTimer() +{ + // FIXME: Stub +} + +void LegoOmni::vtable0x3c() +{ + // FIXME: Stub +} + +MxBool LegoOmni::vtable40() { // FIXME: Stub return 0; diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 485da46c..be289769 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -36,33 +36,33 @@ class LegoOmni : public MxOmni LegoOmni(); virtual ~LegoOmni(); // vtable+00 - virtual MxLong Notify(MxParam &p); // vtable+04 + virtual MxLong Notify(MxParam &p) override; // vtable+04 // OFFSET: LEGO1 0x10058aa0 - inline virtual const char *ClassName() const // vtable+0c + inline virtual const char *ClassName() const override // vtable+0c { // 0x100f671c return "LegoOmni"; } // OFFSET: LEGO1 0x10058ab0 - inline virtual MxBool IsA(const char *name) const // vtable+10 + inline virtual MxBool IsA(const char *name) const override // vtable+10 { return !strcmp(name, LegoOmni::ClassName()) || MxOmni::IsA(name); } - virtual void Init(); // vtable+14 - virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p); // vtable+18 - virtual void Destroy(); // vtable+1c - virtual void vtable20(); - virtual void vtable24(MxDSAction &ds); - virtual MxBool vtable28(MxDSAction &ds); - virtual void vtable2c(); - virtual void vtable30(); - virtual void vtable34(); - virtual void vtable38(); - virtual void vtable3c(); - virtual unsigned char vtable40(); + virtual void Init() override; // vtable+14 + virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p) override; // vtable+18 + virtual void Destroy() override; // vtable+1c + virtual void vtable0x20() override; + virtual void DeleteObject(MxDSAction &ds) override; + virtual MxBool DoesEntityExist(MxDSAction &ds) override; + virtual void vtable0x2c() override; + virtual int vtable0x30(char*, int, MxCore*) override; + virtual void NotifyCurrentEntity() override; + virtual void StartTimer() override; + virtual void vtable0x3c() override; + virtual MxBool vtable40(); LegoVideoManager *GetVideoManager() { return (LegoVideoManager *) m_videoManager; } LegoSoundManager *GetSoundManager() { return (LegoSoundManager *)m_soundManager;} diff --git a/LEGO1/mxbackgroundaudiomanager.cpp b/LEGO1/mxbackgroundaudiomanager.cpp index a24286ad..40891bef 100644 --- a/LEGO1/mxbackgroundaudiomanager.cpp +++ b/LEGO1/mxbackgroundaudiomanager.cpp @@ -1,5 +1,7 @@ #include "mxbackgroundaudiomanager.h" +#include "mxomni.h" + DECOMP_SIZE_ASSERT(MxBackgroundAudioManager, 0x150) // OFFSET: LEGO1 0x1007ea90 diff --git a/LEGO1/mxdsaction.cpp b/LEGO1/mxdsaction.cpp index 536fbd8a..3411a460 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -3,6 +3,8 @@ #include #include +#include "mxomni.h" + DECOMP_SIZE_ASSERT(MxDSAction, 0x94) // GLOBAL OFFSET: LEGO1 0x10101410 @@ -215,6 +217,9 @@ MxLong MxDSAction::GetSomeTimingField() return this->m_someTimingField; } +// Win32 defines GetCurrentTime to GetTickCount +#undef GetCurrentTime + // OFFSET: LEGO1 0x100adcd0 MxLong MxDSAction::GetCurrentTime() { diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 7d9d2f0c..01dfcf2c 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -2,8 +2,10 @@ #define MXDSACTION_H #include "mxdsobject.h" +#include "mxtypes.h" #include "mxvector.h" -#include "mxomni.h" + +class MxOmni; // VTABLE 0x100dc098 // SIZE 0x94 @@ -40,7 +42,7 @@ class MxDSAction : public MxDSObject virtual MxU32 GetSizeOnDisk(); // vtable+18; virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; virtual MxLong GetDuration(); // vtable+24; - virtual void SetDuration(LONG p_duration); // vtable+28; + virtual void SetDuration(MxLong p_duration); // vtable+28; virtual MxDSAction *Clone(); // vtable+2c; virtual void MergeFrom(MxDSAction &p_dsAction); // vtable+30; virtual MxBool HasId(MxU32 p_objectId); // vtable+34; diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 446ac4f9..22cc2a70 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -49,15 +49,16 @@ void MxOmni::vtable0x20() } // OFFSET: LEGO1 0x100b00c0 STUB -void MxOmni::DeleteObject() +void MxOmni::DeleteObject(MxDSAction &ds) { // TODO } // OFFSET: LEGO1 0x100b09a0 STUB -void MxOmni::DoesEntityExist() +MxBool MxOmni::DoesEntityExist(MxDSAction &ds) { // TODO + return FALSE; } // OFFSET: LEGO1 0x100b00e0 STUB diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 8cacc5fc..a8fa9db8 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -2,6 +2,7 @@ #define MXOMNI_H #include "mxcriticalsection.h" +#include "mxdsaction.h" #include "mxeventmanager.h" #include "mxmusicmanager.h" #include "mxnotificationmanager.h" @@ -33,13 +34,13 @@ class MxOmni : public MxCore MxOmni(); virtual ~MxOmni() override; - virtual MxLong Notify(MxParam &p); // vtable+04 + virtual MxLong Notify(MxParam &p) override; // vtable+04 virtual void Init(); // vtable+14 - virtual MxResult Create(MxOmniCreateParam &p); // vtable+18 + virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p); // vtable+18 virtual void Destroy(); // vtable+1c virtual void vtable0x20(); // vtable+20 - virtual void DeleteObject(); // vtable+24 - virtual void DoesEntityExist(); // vtable+28 + virtual void DeleteObject(MxDSAction &ds); // vtable+24 + virtual MxBool DoesEntityExist(MxDSAction &ds); // vtable+28 virtual void vtable0x2c(); // vtable+2c virtual int vtable0x30(char*, int, MxCore*); // vtable+30 virtual void NotifyCurrentEntity(); // vtable+34 From 574a9dc6f15cdaf65b2ab1b0f28b97c1c764617f Mon Sep 17 00:00:00 2001 From: MattKC <34096995+itsmattkc@users.noreply.github.com> Date: Mon, 25 Sep 2023 19:30:56 -0700 Subject: [PATCH 22/87] Implement some MxStreamer functions (#130) * Implement some MxStreamer stuff * Implement/match MxVideoManager::Tickle (#128) * Implement/match MxPresenter::StartAction * Update mxpoint32.h * Implement/match MxVideoManager::Tickle * Update mxlist.h * Update mxpresenter.cpp * MxFlcPresenter ctor/dtor (#132) * MxFlcPresenter ctor/dtor * Match constructor --------- Co-authored-by: Christian Semmler * LegoOmni::CreateStreamObject and related (#129) * LegoOmni::CreateStreamObject and related * Revert change to MxDSSource/MxDSFile Read export * Bootstrap MxDSMultiAction (#133) * Bootstrap MxDSMultiAction * Move destroy function to list class * Fix unk14 call * Quick patch for EqualsDataProduct (#134) * MxLong Tickle() -> MxResult Tickle() (#135) * MxLong Tickle() -> MxResult Tickle() * Remove garbage * Fix implementations * PresenterNameDispatch (#137) * PresenterNameDispatch * Use reference for PresenterNameDispatch param - fix or add const markers so we can use a const reference * Implement/match remaining MxDSMultiAction functions (#136) * Implement/match MxDSMultiAction::Deserialize * Implement remaining functions of MxDSMultiAction * Remove space * Implement/match MxDSParallelAction (#138) * Implement/match MxDSParallelAction * Fix type * Remove space * Add neccessary MxDSMultiAction functions * Implement/match MxDSSerialAction (#139) * Implement/match MxDSSerialAction * Add neccessary MxDSMultiAction functions * Fix LegoOmni vtable (#140) * matched GetOpenStream * matched MakeSourceName * add MxDSBuffer stub * add MxRAMStreamController stub * add stubbed functions for MxStreamController used by MxStreamer * implement AddStreamControllerToOpenList * implement most of MxStreamer::Open * add note for MxStreamerSubclass1 * fix compiler issue * implement MxStreamer::Notify --------- Co-authored-by: Christian Semmler Co-authored-by: Joshua Peisach Co-authored-by: MS --- CMakeLists.txt | 3 + LEGO1/legoomni.cpp | 18 +++- LEGO1/mxatomid.h | 3 + LEGO1/mxdsbuffer.cpp | 13 +++ LEGO1/mxdsbuffer.h | 20 ++++ LEGO1/mxparam.h | 5 +- LEGO1/mxramstreamcontroller.cpp | 3 + LEGO1/mxramstreamcontroller.h | 7 ++ LEGO1/mxstreamcontroller.cpp | 32 +++++++ LEGO1/mxstreamcontroller.h | 21 +++-- LEGO1/mxstreamer.cpp | 161 ++++++++++++++++++++++++++++---- LEGO1/mxstreamer.h | 93 +++++++++++++++++- 12 files changed, 347 insertions(+), 32 deletions(-) create mode 100644 LEGO1/mxdsbuffer.cpp create mode 100644 LEGO1/mxdsbuffer.h create mode 100644 LEGO1/mxramstreamcontroller.cpp create mode 100644 LEGO1/mxstreamcontroller.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d96b0c61..d62c2b2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,6 +111,7 @@ add_library(lego1 SHARED LEGO1/mxdsaction.cpp LEGO1/mxdsactionlist.cpp LEGO1/mxdsanim.cpp + LEGO1/mxdsbuffer.cpp LEGO1/mxdschunk.cpp LEGO1/mxdsevent.cpp LEGO1/mxdsfile.cpp @@ -149,12 +150,14 @@ add_library(lego1 SHARED LEGO1/mxparam.cpp LEGO1/mxpresenter.cpp LEGO1/mxpresenterlist.cpp + LEGO1/mxramstreamcontroller.cpp LEGO1/mxscheduler.cpp LEGO1/mxsemaphore.cpp LEGO1/mxsmkpresenter.cpp LEGO1/mxsoundmanager.cpp LEGO1/mxsoundpresenter.cpp LEGO1/mxstillpresenter.cpp + LEGO1/mxstreamcontroller.cpp LEGO1/mxstreamer.cpp LEGO1/mxstring.cpp LEGO1/mxthread.cpp diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index 1dd7a561..0c84395e 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -39,10 +39,22 @@ int LegoOmni::GetCurrPathInfo(LegoPathBoundary **,int &) return 0; } -// OFFSET: LEGO1 0x100b6ff0 STUB -void MakeSourceName(char *, const char *) +// OFFSET: LEGO1 0x100b6ff0 +void MakeSourceName(char *p_output, const char *p_input) { - // TODO + const char *cln = strchr(p_input, ':'); + if (cln) { + p_input = cln + 1; + } + + strcpy(p_output, p_input); + + strlwr(p_output); + + char *extLoc = strstr(p_output, ".si"); + if (extLoc) { + *extLoc = 0; + } } // OFFSET: LEGO1 0x100b7050 diff --git a/LEGO1/mxatomid.h b/LEGO1/mxatomid.h index 8efef679..7c89f35f 100644 --- a/LEGO1/mxatomid.h +++ b/LEGO1/mxatomid.h @@ -28,8 +28,11 @@ class MxAtomId { return this->m_internal == other.m_internal; } + void Clear(); + const char *GetInternal() const { return m_internal; } + private: MxAtomIdCounter* GetCounter(const char *, LookupMode); void Destroy(); diff --git a/LEGO1/mxdsbuffer.cpp b/LEGO1/mxdsbuffer.cpp new file mode 100644 index 00000000..686627a4 --- /dev/null +++ b/LEGO1/mxdsbuffer.cpp @@ -0,0 +1,13 @@ +#include "mxdsbuffer.h" + +// OFFSET: LEGO1 0x100c6470 +MxDSBuffer::MxDSBuffer() +{ + // TODO +} + +// OFFSET: LEGO1 0x100c6530 +MxDSBuffer::~MxDSBuffer() +{ + // TODO +} diff --git a/LEGO1/mxdsbuffer.h b/LEGO1/mxdsbuffer.h new file mode 100644 index 00000000..cb962cea --- /dev/null +++ b/LEGO1/mxdsbuffer.h @@ -0,0 +1,20 @@ +#ifndef MXDSBUFFER_H +#define MXDSBUFFER_H + +#include "decomp.h" +#include "mxcore.h" + +// VTABLE 0x100dcca0 +// SIZE 0x34 +class MxDSBuffer : public MxCore +{ +public: + MxDSBuffer(); + virtual ~MxDSBuffer() override; + +private: + undefined m_unk08[0x2C]; + +}; + +#endif // MXDSBUFFER_H diff --git a/LEGO1/mxparam.h b/LEGO1/mxparam.h index c4150ff7..ffbf1530 100644 --- a/LEGO1/mxparam.h +++ b/LEGO1/mxparam.h @@ -1,6 +1,7 @@ #ifndef MXPARAM_H #define MXPARAM_H +#include "compat.h" #include "mxomnicreateparambase.h" #include "mxtypes.h" @@ -12,7 +13,7 @@ class MxParam : public MxOmniCreateParamBase public: inline MxParam(MxS32 p_type, MxCore *p_sender) : MxOmniCreateParamBase(), m_type(p_type), m_sender(p_sender){} - virtual ~MxParam(){}; // vtable+0x0 (scalar deleting destructor) + virtual ~MxParam() override {} // vtable+0x0 (scalar deleting destructor) virtual MxParam *Clone(); // vtable+0x4 inline MxS32 GetType() const @@ -25,7 +26,7 @@ class MxParam : public MxOmniCreateParamBase return m_sender; } -private: +protected: MxS32 m_type; // 0x4 MxCore *m_sender; // 0x8 }; diff --git a/LEGO1/mxramstreamcontroller.cpp b/LEGO1/mxramstreamcontroller.cpp new file mode 100644 index 00000000..a96046a0 --- /dev/null +++ b/LEGO1/mxramstreamcontroller.cpp @@ -0,0 +1,3 @@ +#include "mxramstreamcontroller.h" + +DECOMP_SIZE_ASSERT(MxRAMStreamController, 0x98); diff --git a/LEGO1/mxramstreamcontroller.h b/LEGO1/mxramstreamcontroller.h index 09915cbf..563d9cb6 100644 --- a/LEGO1/mxramstreamcontroller.h +++ b/LEGO1/mxramstreamcontroller.h @@ -1,11 +1,18 @@ #ifndef MXRAMSTREAMCONTROLLER_H #define MXRAMSTREAMCONTROLLER_H +#include "mxdsbuffer.h" #include "mxstreamcontroller.h" // VTABLE 0x100dc728 +// SIZE 0x98 class MxRAMStreamController : public MxStreamController { +public: + inline MxRAMStreamController() {} + +private: + MxDSBuffer m_buffer; }; diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp new file mode 100644 index 00000000..09f2d95c --- /dev/null +++ b/LEGO1/mxstreamcontroller.cpp @@ -0,0 +1,32 @@ +#include "mxstreamcontroller.h" + +#include "mxautolocker.h" + +// OFFSET: LEGO1 0x100c0b90 STUB +MxStreamController::MxStreamController() +{ + // TODO +} + +// OFFSET: LEGO1 0x100c1290 STUB +MxStreamController::~MxStreamController() +{ + // TODO +} + +// OFFSET: LEGO1 0x100c20d0 STUB +MxBool MxStreamController::FUN_100c20d0(MxDSObject &p_obj) +{ + // TODO + return TRUE; +} + +// OFFSET: LEGO1 0x100c1520 +MxResult MxStreamController::Open(const char *p_filename) +{ + MxAutoLocker locker(&m_criticalSection); + + // TODO + + return SUCCESS; +} diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index 4ec95e9e..c7e4309e 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -1,13 +1,21 @@ #ifndef MXSTREAMCONTROLLER_H #define MXSTREAMCONTROLLER_H +#include "decomp.h" #include "mxatomid.h" +#include "mxcriticalsection.h" #include "mxcore.h" +#include "mxdsobject.h" // VTABLE 0x100dc968 +// SIZE 0x64 class MxStreamController : public MxCore { public: + MxStreamController(); + + virtual ~MxStreamController() override; // vtable+0x0 + // OFFSET: LEGO1 0x100c0f10 inline virtual const char *ClassName() const override // vtable+0xc { @@ -21,16 +29,15 @@ class MxStreamController : public MxCore return !strcmp(name, MxStreamController::ClassName()) || MxCore::IsA(name); } - int m_unk08; - int m_unk0c; - int m_unk10; - int m_unk14; - int m_unk18; - int m_unk1c; - int m_unk20; + virtual MxResult Open(const char *p_filename); // vtable+0x14 + + MxBool FUN_100c20d0(MxDSObject &p_obj); + + MxCriticalSection m_criticalSection; MxAtomId atom; int m_unk28; int m_unk2c; + undefined m_unk30[0x34]; }; #endif // MXSTREAMCONTROLLER_H diff --git a/LEGO1/mxstreamer.cpp b/LEGO1/mxstreamer.cpp index 12f51f99..2121773e 100644 --- a/LEGO1/mxstreamer.cpp +++ b/LEGO1/mxstreamer.cpp @@ -1,37 +1,166 @@ #include "mxstreamer.h" -// OFFSET: LEGO1 0x100b91d0 STUB -MxStreamer::~MxStreamer() +#include + +#include "legoomni.h" +#include "mxdiskstreamcontroller.h" +#include "mxramstreamcontroller.h" + +DECOMP_SIZE_ASSERT(MxStreamer, 0x2c); + +#define MXSTREAMER_DELETE_NOTIFY 6 + +// OFFSET: LEGO1 0x100b8f00 +MxStreamer::MxStreamer() { - // TODO + NotificationManager()->Register(this); } -// OFFSET: LEGO1 0x100b92c0 STUB -MxStreamController *MxStreamer::Open(const char *name, MxU16 p) +// OFFSET: LEGO1 0x100b9190 +MxResult MxStreamer::Init() +{ + undefined *b = new undefined[m_subclass1.GetSize() * 0x5800]; + m_subclass1.SetBuffer(b); + if (b) { + b = new undefined[m_subclass2.GetSize() * 0x800]; + m_subclass2.SetBuffer(b); + if (b) { + return SUCCESS; + } + } + + return FAILURE; +} + +// OFFSET: LEGO1 0x100b91d0 +MxStreamer::~MxStreamer() +{ + while (!m_openStreams.empty()) { + MxStreamController *c = m_openStreams.front(); + m_openStreams.pop_front(); + delete c; + } + + NotificationManager()->Unregister(this); +} + +// OFFSET: LEGO1 0x100b92c0 +MxStreamController *MxStreamer::Open(const char *p_name, MxU16 p_lookupType) { // TODO + MxStreamController *stream = NULL; + + if (!GetOpenStream(p_name)) { + switch (p_lookupType) { + case e_DiskStream: + stream = new MxDiskStreamController(); + break; + case e_RAMStream: + stream = new MxRAMStreamController(); + break; + } + + if (!stream + || stream->Open(p_name) != SUCCESS + || AddStreamControllerToOpenList(stream) != SUCCESS) { + delete stream; + stream = NULL; + } + } + + return stream; +} + +// OFFSET: LEGO1 0x100b9570 +MxLong MxStreamer::Close(const char *p) +{ + MxDSAction ds; + + ds.SetUnknown24(-2); + + for (list::iterator it = m_openStreams.begin(); it != m_openStreams.end(); it++) { + MxStreamController *c = *it; + + if (!p || !strcmp(p, c->atom.GetInternal())) { + m_openStreams.erase(it); + + if (!c->FUN_100c20d0(ds)) { + MxStreamerNotification notif(MXSTREAMER_DELETE_NOTIFY, NULL, c); + + NotificationManager()->Send(this, ¬if); + } else { + delete c; + } + + return SUCCESS; + } + } + + return FAILURE; +} + +// OFFSET: LEGO1 0x100b9700 +MxParam *MxStreamerNotification::Clone() +{ + return new MxStreamerNotification(m_type, m_sender, m_controller); +} + +// OFFSET: LEGO1 0x100b9870 +MxStreamController *MxStreamer::GetOpenStream(const char *p_name) +{ + for (list::iterator it = m_openStreams.begin(); it != m_openStreams.end(); it++) { + MxStreamController *c = *it; + MxAtomId &atom = c->atom; + if (p_name) { + if (!strcmp(atom.GetInternal(), p_name)) { + return *it; + } + } + } + return NULL; } -// OFFSET: LEGO1 0x100b9570 STUB -MxLong MxStreamer::Close(const char *p) + +// OFFSET: LEGO1 0x100b9930 +MxResult MxStreamer::AddStreamControllerToOpenList(MxStreamController *stream) { - // TODO - return 0; + if (find(m_openStreams.begin(), m_openStreams.end(), stream) == m_openStreams.end()) { + m_openStreams.push_back(stream); + return SUCCESS; + } + + return FAILURE; } -// OFFSET: LEGO1 0x100b9b60 STUB +// OFFSET: LEGO1 0x100b9b60 MxLong MxStreamer::Notify(MxParam &p) { - // TODO + if (p.GetType() == MXSTREAMER_DELETE_NOTIFY) { + MxDSAction ds; + + ds.SetUnknown24(-2); + + MxStreamController *c = static_cast(p).GetController(); + + if (!c->FUN_100c20d0(ds)) { + MxStreamerNotification notif(MXSTREAMER_DELETE_NOTIFY, NULL, c); + NotificationManager()->Send(this, ¬if); + } else { + delete c; + } + } return 0; } -// OFFSET: LEGO1 0x100b9190 STUB -MxResult MxStreamer::VTable0x14() +// No offset, function is always inlined +MxStreamerSubClass1::MxStreamerSubClass1(undefined4 size) { - // TODO - - return MxResult(); + m_buffer = NULL; + m_size = size; + undefined4 *ptr = &m_unk08; + for (int i = 0; i >= 0; i--) { + ptr[i] = 0; + } } diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index f14ac66d..5ab02cbb 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -1,21 +1,106 @@ #ifndef MXSTREAMER_H #define MXSTREAMER_H +#include + +#include "decomp.h" #include "mxcore.h" +#include "mxparam.h" #include "mxstreamcontroller.h" #include "mxtypes.h" +// NOTE: This feels like some kind of templated class, maybe something from the +// STL. But I haven't figured out what yet (it's definitely not a vector). +class MxStreamerSubClass1 +{ +public: + inline MxStreamerSubClass1(undefined4 size); + + ~MxStreamerSubClass1() { delete [] m_buffer; } + + undefined4 GetSize() { return m_size; } + + void SetBuffer(undefined *p_buf) { m_buffer = p_buf; } + +private: + undefined *m_buffer; + undefined4 m_size; + undefined4 m_unk08; +}; + +class MxStreamerSubClass2 : public MxStreamerSubClass1 +{ +public: + inline MxStreamerSubClass2() : MxStreamerSubClass1(0x40) {} +}; + +class MxStreamerSubClass3 : public MxStreamerSubClass1 +{ +public: + inline MxStreamerSubClass3() : MxStreamerSubClass1(0x80) {} +}; + +class MxStreamerNotification : public MxParam +{ +public: + inline MxStreamerNotification(MxS32 p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxParam(p_type, p_sender) + { + m_controller = p_ctrlr; + } + + virtual ~MxStreamerNotification() override {} + + virtual MxParam *Clone() override; + + MxStreamController *GetController() { return m_controller; } + +private: + MxStreamController *m_controller; +}; + // VTABLE 0x100dc710 +// SIZE 0x2c class MxStreamer : public MxCore { public: - virtual ~MxStreamer() override; + enum OpenMode + { + e_DiskStream, + e_RAMStream + }; - __declspec(dllexport) MxStreamController *Open(const char *name, MxU16 p); - __declspec(dllexport) MxLong Close(const char *p); + MxStreamer(); + virtual ~MxStreamer() override; // vtable+0x0 + + __declspec(dllexport) MxStreamController *Open(const char *p_name, MxU16 p_openMode); + __declspec(dllexport) MxLong Close(const char *p_name); virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxResult VTable0x14(); // vtable+0x14 + + // OFFSET: LEGO1 0x100b9000 + inline virtual const char *ClassName() const override // vtable+0x0c + { + // 0x1010210c + return "MxStreamer"; + } + + // OFFSET: LEGO1 0x100b9010 + inline virtual MxBool IsA(const char *p_name) const override // vtable+0x10 + { + return !strcmp(p_name, MxStreamer::ClassName()) || MxCore::IsA(p_name); + } + + virtual MxResult Init(); // vtable+0x14 + + MxStreamController *GetOpenStream(const char *p_name); + + MxResult AddStreamControllerToOpenList(MxStreamController *p_stream); + +private: + list m_openStreams; // 0x8 + MxStreamerSubClass2 m_subclass1; // 0x14 + MxStreamerSubClass3 m_subclass2; // 0x20 + }; #endif // MXSTREAMER_H From 915390602bbee7030d124683b45803e7eddf7c85 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 26 Sep 2023 07:24:28 -0400 Subject: [PATCH 23/87] Add size assert for MxString --- LEGO1/mxstring.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/LEGO1/mxstring.cpp b/LEGO1/mxstring.cpp index e2f24cab..e82d431a 100644 --- a/LEGO1/mxstring.cpp +++ b/LEGO1/mxstring.cpp @@ -1,7 +1,11 @@ #include "mxstring.h" +#include "decomp.h" + #include #include +DECOMP_SIZE_ASSERT(MxString, 0x10) + // OFFSET: LEGO1 0x100ae200 MxString::MxString() { From e341afd411f1f958b23d0049f95d0fa457046d94 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 26 Sep 2023 07:25:23 -0400 Subject: [PATCH 24/87] Match ~MxDSStreamingAction --- LEGO1/mxdsstreamingaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/mxdsstreamingaction.cpp b/LEGO1/mxdsstreamingaction.cpp index ab04c19e..665f079e 100644 --- a/LEGO1/mxdsstreamingaction.cpp +++ b/LEGO1/mxdsstreamingaction.cpp @@ -1,4 +1,5 @@ #include "mxdsstreamingaction.h" +#include "mxdsbuffer.h" DECOMP_SIZE_ASSERT(MxDSStreamingAction, 0xb4) @@ -22,7 +23,6 @@ MxDSStreamingAction::MxDSStreamingAction(MxDSStreamingAction &p_dsStreamingActio // OFFSET: LEGO1 0x100cd150 MxDSStreamingAction::~MxDSStreamingAction() { - // TODO: Implement MxDSBuffer if (this->m_unka0) delete this->m_unka0; if (this->m_unka4) From 749c553325149575ceaaab09e1ff3f11eead6ece Mon Sep 17 00:00:00 2001 From: MS Date: Wed, 27 Sep 2023 15:16:46 -0400 Subject: [PATCH 25/87] LegoEntity parsing extra Action strings (#141) * LegoEntity parse action string * Reduced size assert for MxEntity * remove override keyword for LegoEntity function * Move global strings to new define.cpp file --- CMakeLists.txt | 1 + LEGO1/define.cpp | 10 ++++++++++ LEGO1/define.h | 8 ++++++++ LEGO1/extra.h | 21 +++++++++++++++++++++ LEGO1/legoentity.cpp | 33 +++++++++++++++++++++++++++++++++ LEGO1/legoentity.h | 12 +++++++++++- LEGO1/legoomni.cpp | 2 +- LEGO1/legoomni.h | 2 +- LEGO1/legoutil.cpp | 30 ++++++++++++++++++++++++++++++ LEGO1/legoutil.h | 3 +++ LEGO1/mxentity.cpp | 4 +++- LEGO1/mxentity.h | 2 +- LEGO1/mxpresenter.cpp | 7 +------ 13 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 LEGO1/define.cpp create mode 100644 LEGO1/define.h create mode 100644 LEGO1/extra.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d62c2b2b..6c408d65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(lego1 SHARED LEGO1/buildingentity.cpp LEGO1/bumpbouy.cpp LEGO1/carrace.cpp + LEGO1/define.cpp LEGO1/dllmain.cpp LEGO1/dunebuggy.cpp LEGO1/elevatorbottom.cpp diff --git a/LEGO1/define.cpp b/LEGO1/define.cpp new file mode 100644 index 00000000..84073b9d --- /dev/null +++ b/LEGO1/define.cpp @@ -0,0 +1,10 @@ +#include "define.h" + +// 0x10101eac +const char *g_parseExtraTokens = ":;"; + +// 0x10101edc +const char *g_strWORLD = "WORLD"; + +// 0x10102040 +const char *g_strACTION = "ACTION"; diff --git a/LEGO1/define.h b/LEGO1/define.h new file mode 100644 index 00000000..ec41943e --- /dev/null +++ b/LEGO1/define.h @@ -0,0 +1,8 @@ +#ifndef DEFINE_H +#define DEFINE_H + +extern const char *g_parseExtraTokens; +extern const char *g_strWORLD; +extern const char *g_strACTION; + +#endif // DEFINE_H \ No newline at end of file diff --git a/LEGO1/extra.h b/LEGO1/extra.h new file mode 100644 index 00000000..05ed5f07 --- /dev/null +++ b/LEGO1/extra.h @@ -0,0 +1,21 @@ +#ifndef EXTRA_H +#define EXTRA_H + +// Items related to the Extra string of key-value pairs found in MxOb + +enum ExtraActionType +{ + ExtraActionType_opendisk = 1, + ExtraActionType_openram = 2, + ExtraActionType_close = 3, + ExtraActionType_start = 4, + ExtraActionType_stop = 5, + ExtraActionType_run = 6, + ExtraActionType_exit = 7, + ExtraActionType_enable = 8, + ExtraActionType_disable = 9, + ExtraActionType_notify = 10, + ExtraActionType_unknown = 11, +}; + +#endif // EXTRA_H diff --git a/LEGO1/legoentity.cpp b/LEGO1/legoentity.cpp index b8ed69f9..d2062946 100644 --- a/LEGO1/legoentity.cpp +++ b/LEGO1/legoentity.cpp @@ -1,5 +1,9 @@ #include "legoentity.h" +#include "legoomni.h" +#include "legoutil.h" +#include "define.h" + DECOMP_SIZE_ASSERT(LegoEntity, 0x68) // OFFSET: LEGO1 0x1000c290 @@ -16,8 +20,37 @@ MxLong LegoEntity::Notify(MxParam &p) return 0; } +// OFFSET: LEGO1 0x100107e0 STUB +void LegoEntity::vtable18() +{ + +} + // OFFSET: LEGO1 0x10010810 STUB void LegoEntity::Destroy() { // TODO } + +// OFFSET: LEGO1 0x10010e10 +void LegoEntity::ParseAction(char *p_extra) +{ + char copy[1024]; + char actionValue[1024]; + strcpy(copy, p_extra); + + if (KeyValueStringParse(actionValue, g_strACTION, copy)) { + m_actionType = MatchActionString(strtok(actionValue, g_parseExtraTokens)); + + if (m_actionType != ExtraActionType_exit) { + char *token = strtok(NULL, g_parseExtraTokens); + + m_actionArgString = new char[strlen(token) + 1]; + strcpy(m_actionArgString, token); + + if (m_actionType != ExtraActionType_run) { + m_actionArgNumber = atoi(strtok(NULL, g_parseExtraTokens)); + } + } + } +} diff --git a/LEGO1/legoentity.h b/LEGO1/legoentity.h index fdfe997f..9fbbb5bb 100644 --- a/LEGO1/legoentity.h +++ b/LEGO1/legoentity.h @@ -2,6 +2,7 @@ #define LEGOENTITY_H #include "mxentity.h" +#include "extra.h" // VTABLE 0x100d4858 // SIZE 0x68 (probably) @@ -31,7 +32,16 @@ class LegoEntity : public MxEntity return !strcmp(name, LegoEntity::ClassName()) || MxEntity::IsA(name); } - virtual void Destroy() override; // vtable+0x1c + virtual void vtable18(); // vtable+0x18 + virtual void Destroy(); // vtable+0x1c + virtual void ParseAction(char *); // vtable+0x20 + +protected: + // For tokens from the extra string that look like this: + // "Action:openram;\lego\scripts\Race\CarRaceR;0" + ExtraActionType m_actionType; // 0x5c + char *m_actionArgString; // 0x60 + MxS32 m_actionArgNumber; // 0x64 }; diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index 0c84395e..bbc8258b 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -58,7 +58,7 @@ void MakeSourceName(char *p_output, const char *p_input) } // OFFSET: LEGO1 0x100b7050 -MxBool KeyValueStringParse(char *p_outputValue, char *p_key, char *p_source) +MxBool KeyValueStringParse(char *p_outputValue, const char *p_key, const char *p_source) { MxBool didMatch = FALSE; diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index be289769..a9cce9cf 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -113,6 +113,6 @@ __declspec(dllexport) MxLong Start(MxDSAction *a); LegoBuildingManager* BuildingManager(); Isle* GetIsle(); LegoPlantManager* PlantManager(); -MxBool KeyValueStringParse(char *, char *, char *); +MxBool KeyValueStringParse(char *, const char *, const char *); #endif // LEGOOMNI_H diff --git a/LEGO1/legoutil.cpp b/LEGO1/legoutil.cpp index bac8f284..9827b376 100644 --- a/LEGO1/legoutil.cpp +++ b/LEGO1/legoutil.cpp @@ -2,6 +2,36 @@ #include "mxtypes.h" +#include + +// OFFSET: LEGO1 0x1003e300 +ExtraActionType MatchActionString(const char *p_str) { + ExtraActionType result = ExtraActionType_unknown; + + if (!strcmpi("openram", p_str)) + result = ExtraActionType_openram; + else if (!strcmpi("opendisk", p_str)) + result = ExtraActionType_opendisk; + else if (!strcmpi("close", p_str)) + result = ExtraActionType_close; + else if (!strcmpi("start", p_str)) + result = ExtraActionType_start; + else if (!strcmpi("stop", p_str)) + result = ExtraActionType_stop; + else if (!strcmpi("run", p_str)) + result = ExtraActionType_run; + else if (!strcmpi("exit", p_str)) + result = ExtraActionType_exit; + else if (!strcmpi("enable", p_str)) + result = ExtraActionType_enable; + else if (!strcmpi("disable", p_str)) + result = ExtraActionType_disable; + else if (!strcmpi("notify", p_str)) + result = ExtraActionType_notify; + + return result; +} + // OFFSET: LEGO1 0x1003eae0 void ConvertHSVToRGB(float h, float s, float v, float *r_out, float *b_out, float *g_out) { diff --git a/LEGO1/legoutil.h b/LEGO1/legoutil.h index 6a0113e8..b736cd29 100644 --- a/LEGO1/legoutil.h +++ b/LEGO1/legoutil.h @@ -1,6 +1,8 @@ #ifndef LEGOUTIL_H #define LEGOUTIL_H +#include "extra.h" + template inline T Abs(T p_t) { @@ -19,6 +21,7 @@ inline T Max(T p_t1, T p_t2) return p_t1 > p_t2 ? p_t1 : p_t2; } +ExtraActionType MatchActionString(const char *); void ConvertHSVToRGB(float r, float g, float b, float* out_r, float* out_g, float* out_b); #endif // LEGOUTIL_H diff --git a/LEGO1/mxentity.cpp b/LEGO1/mxentity.cpp index 65adad67..54e854ab 100644 --- a/LEGO1/mxentity.cpp +++ b/LEGO1/mxentity.cpp @@ -1,6 +1,8 @@ #include "mxentity.h" -DECOMP_SIZE_ASSERT(MxEntity, 0x68) +// Size subject to change. It's not clear yet which members belong to +// MxEntity and which belong only the subclasses. +DECOMP_SIZE_ASSERT(MxEntity, 0x5c) // OFFSET: LEGO1 0x1001d190 MxEntity::MxEntity() diff --git a/LEGO1/mxentity.h b/LEGO1/mxentity.h index 25e74d1b..3d73292e 100644 --- a/LEGO1/mxentity.h +++ b/LEGO1/mxentity.h @@ -31,7 +31,7 @@ class MxEntity : public MxCore private: MxS32 m_mxEntityId; // 0x8 MxAtomId m_atom; // 0xc - undefined m_unk10[0x58]; + undefined m_unk10[76]; }; #endif // MXENTITY_H diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 940248a0..b57af821 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -7,15 +7,10 @@ #include #include "decomp.h" +#include "define.h" DECOMP_SIZE_ASSERT(MxPresenter, 0x40); -// 0x10101eac -char *g_parseExtraTokens = ":;"; - -// 0x10101edc -char *g_strWORLD = "WORLD"; - // OFFSET: LEGO1 0x100b4d50 void MxPresenter::Init() { From 27945255644881393003273d1a754596e64675bc Mon Sep 17 00:00:00 2001 From: Ramen2X <64166386+Ramen2X@users.noreply.github.com> Date: Thu, 28 Sep 2023 13:11:30 -0400 Subject: [PATCH 26/87] make note of enum style in CONTRIBUTING.md [skip ci] --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c9d3364a..005f599c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ This repository currently has only one goal: accuracy to the original executable In general, we're not exhaustively strict about coding style, but there are some preferable guidelines to follow that have been adopted from what we know about the original codebase: - Indent: 2 spaces -- `PascalCase` for classes and function names. +- `PascalCase` for classes, function names, and enumerations. - `m_camelCase` for member variables. - `g_camelCase` for global variables. - `p_camelCase` for function parameters. From 44c3ae478b29078d8d36bb13dbc05b66ee9cec18 Mon Sep 17 00:00:00 2001 From: Ramen2X <64166386+Ramen2X@users.noreply.github.com> Date: Fri, 29 Sep 2023 12:09:46 -0400 Subject: [PATCH 27/87] implement some of MxTransitionManager (#143) * implement some of MxTransitionManager start working on MxTransitionManager::StartTransition add TransitionType enum implement/match MxTransitionManager::GetDDrawSurfaceFromVideoManager implement/match global function SetAppCursor * remove offset comment from mxomni.h * remove misc offset comments from mxtransitionmanager.h * address feedback * merge m_unk20-24 into pad --- LEGO1/legoinputmanager.h | 16 +++++++++-- LEGO1/legoomni.h | 1 + LEGO1/legovideomanager.h | 3 ++ LEGO1/mxbackgroundaudiomanager.h | 3 +- LEGO1/mxdisplaysurface.h | 2 ++ LEGO1/mxomni.cpp | 6 ++++ LEGO1/mxomni.h | 2 ++ LEGO1/mxtransitionmanager.cpp | 47 ++++++++++++++++++++++++++++++++ LEGO1/mxtransitionmanager.h | 41 ++++++++++++++++++++++++++-- LEGO1/mxvideomanager.h | 1 + 10 files changed, 117 insertions(+), 5 deletions(-) diff --git a/LEGO1/legoinputmanager.h b/LEGO1/legoinputmanager.h index 3a35d4b1..56b77445 100644 --- a/LEGO1/legoinputmanager.h +++ b/LEGO1/legoinputmanager.h @@ -28,10 +28,22 @@ class LegoInputManager : public MxPresenter virtual MxResult Tickle() override; // vtable+0x8 - undefined m_pad40[0x15c]; + undefined m_pad40[0x48]; + + MxBool m_unk88; + undefined m_unk89[0x113]; + + // 0x19C int m_joystickIndex; - undefined m_pad200[0x194]; + + undefined m_pad1a0[0x194]; + + // 0x334 MxBool m_useJoystick; + + undefined m_unk335; + MxBool m_unk336; + undefined m_unk337; }; #endif // LEGOINPUTMANAGER_H diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index a9cce9cf..4e772cae 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -21,6 +21,7 @@ #include "legoplantmanager.h" class LegoSoundManager; +class MxTransitionManager; // VTABLE 0x100d8638 // SIZE: 0x140 diff --git a/LEGO1/legovideomanager.h b/LEGO1/legovideomanager.h index 60f670fb..d71c39a1 100644 --- a/LEGO1/legovideomanager.h +++ b/LEGO1/legovideomanager.h @@ -23,6 +23,7 @@ class LegoVideoManager : public MxVideoManager inline MxDirect3D *GetDirect3D() { return this->m_direct3d; } void SetSkyColor(float r, float g, float b); + inline void SetUnkE4(MxBool p_value) { this->m_unke4 = p_value; } private: undefined4 m_unk64; @@ -30,6 +31,8 @@ class LegoVideoManager : public MxVideoManager undefined4 m_unk6c; undefined4 m_unk70; MxDirect3D *m_direct3d; + undefined m_pad78[0x6c]; + MxBool m_unke4; }; #endif // LEGOVIDEOMANAGER_H diff --git a/LEGO1/mxbackgroundaudiomanager.h b/LEGO1/mxbackgroundaudiomanager.h index c6f2f1e7..a2c4cae3 100644 --- a/LEGO1/mxbackgroundaudiomanager.h +++ b/LEGO1/mxbackgroundaudiomanager.h @@ -28,8 +28,9 @@ class MxBackgroundAudioManager : public MxCore } __declspec(dllexport) void Enable(unsigned char p); -private: + void Stop(); +private: void Init(); MxBool m_musicEnabled; // 0x8 diff --git a/LEGO1/mxdisplaysurface.h b/LEGO1/mxdisplaysurface.h index c76266d7..4c2c3866 100644 --- a/LEGO1/mxdisplaysurface.h +++ b/LEGO1/mxdisplaysurface.h @@ -33,6 +33,8 @@ class MxDisplaySurface : public MxCore virtual void ReleaseDC(HDC p_hdc); virtual undefined4 vtable44(undefined4, undefined4*, undefined4, undefined4); + inline LPDIRECTDRAWSURFACE GetDirectDrawSurface2() { return this->m_ddSurface2; } + private: MxVideoParam m_videoParam; LPDIRECTDRAWSURFACE m_ddSurface1; diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 22cc2a70..17de7d73 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -289,3 +289,9 @@ MxEventManager* EventManager() { return MxOmni::GetInstance()->GetEventManager(); } + +// OFFSET: LEGO1 0x1003ef40 +void SetAppCursor(WPARAM p_wparam) +{ + PostMessageA(MxOmni::GetInstance()->GetWindowHandle(), 0x5400, p_wparam, 0); +} diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index a8fa9db8..28e47124 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -92,4 +92,6 @@ __declspec(dllexport) MxNotificationManager * NotificationManager(); MxVideoManager * MVideoManager(); MxAtomIdCounterSet* AtomIdCounterSet(); +void SetAppCursor(WPARAM p_wparam); + #endif // MXOMNI_H diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index fdae06ea..ea295dda 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -1,4 +1,7 @@ #include "mxtransitionmanager.h" +#include "legovideomanager.h" + +DECOMP_SIZE_ASSERT(MxTransitionManager, 0x900); // OFFSET: LEGO1 0x1004b8d0 STUB MxTransitionManager::MxTransitionManager() @@ -25,3 +28,47 @@ void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) { // TODO } + +// OFFSET: LEGO1 0x1004baa0 +MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 +{ + LegoVideoManager *videoManager = VideoManager(); + this->m_ddSurface = videoManager->GetDisplaySurface()->GetDirectDrawSurface2(); + return SUCCESS; +} + +// OFFSET: LEGO1 0x1004bb70 +MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, MxS32 p_speed, + undefined p_unk, MxBool p_playMusicInAnim) +{ + // TODO: Incomplete and far from matching + + if (this->m_transitionType == NOT_TRANSITIONING) { + if (!p_playMusicInAnim) { + MxBackgroundAudioManager *backgroundAudioManager = BackgroundAudioManager(); + backgroundAudioManager->Stop(); + } + this->m_transitionType = p_animationType; + + // TODO: This part of the function is mangled and I can't make out what it's doing right now + + MxU32 time = timeGetTime(); + this->m_systemTime = time; + + this->m_animationSpeed = p_speed; + + MxTickleManager *tickleManager = TickleManager(); + tickleManager->RegisterClient(this, p_speed); + + LegoInputManager *inputManager = InputManager(); + inputManager->m_unk88 = TRUE; + inputManager->m_unk336 = FALSE; + + LegoVideoManager *videoManager = VideoManager(); + videoManager->SetUnkE4(FALSE); + + SetAppCursor(1); + return SUCCESS; + } + return FAILURE; +} \ No newline at end of file diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 215cd2d7..2276219d 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -2,10 +2,11 @@ #define MXTRANSITIONMANAGER_H #include "mxcore.h" +#include "mxvideopresenter.h" +#include "legoomni.h" -class MxVideoPresenter; -// 0x100d7ea0 +// VTABLE 0x100d7ea0 class MxTransitionManager : public MxCore { public: @@ -15,6 +16,42 @@ class MxTransitionManager : public MxCore __declspec(dllexport) void SetWaitIndicator(MxVideoPresenter *videoPresenter); virtual MxResult Tickle(); // vtable+0x8 + + // OFFSET: LEGO1 0x1004b950 + inline virtual const char *ClassName() const override // vtable+0x0c + { + return "MxTransitionManager"; + } + + // OFFSET: LEGO1 0x1004b960 + inline virtual MxBool IsA(const char *name) const override // vtable+0x10 + { + return !strcmp(name, MxTransitionManager::ClassName()) || MxCore::IsA(name); + } + + virtual MxResult GetDDrawSurfaceFromVideoManager(); // vtable+0x14 + + enum TransitionType { + NOT_TRANSITIONING, + NO_ANIMATION, + DISSOLVE, + PIXELATION, + SCREEN_WIPE, + WINDOWS, + BROKEN // Unknown what this is supposed to be, it locks the game up + }; + + MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, undefined p_unk, MxBool p_playMusicInAnim); + +private: + undefined m_pad00[0x20]; + undefined m_pad20[0x04]; + TransitionType m_transitionType; + LPDIRECTDRAWSURFACE m_ddSurface; + MxU16 m_animationTimer; + undefined m_pad36[0x8c2]; + MxULong m_systemTime; + MxS32 m_animationSpeed; }; #endif // MXTRANSITIONMANAGER_H diff --git a/LEGO1/mxvideomanager.h b/LEGO1/mxvideomanager.h index 4068b793..7888f7e7 100644 --- a/LEGO1/mxvideomanager.h +++ b/LEGO1/mxvideomanager.h @@ -26,6 +26,7 @@ class MxVideoManager : public MxMediaManager inline MxVideoParam& GetVideoParam() { return this->m_videoParam; } inline LPDIRECTDRAW GetDirectDraw() { return this->m_pDirectDraw; } + inline MxDisplaySurface *GetDisplaySurface() { return this->m_displaySurface; } private: MxVideoParam m_videoParam; LPDIRECTDRAW m_pDirectDraw; From dc869c441cccac8683362916d2f4378e07d3704e Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 29 Sep 2023 12:42:15 -0400 Subject: [PATCH 28/87] Relocate SetAppCursor to legoutil (#144) --- LEGO1/legoutil.cpp | 7 +++++++ LEGO1/legoutil.h | 3 +++ LEGO1/mxomni.cpp | 8 +------- LEGO1/mxomni.h | 2 -- LEGO1/mxtransitionmanager.cpp | 1 + LEGO1/mxtransitionmanager.h | 1 - 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/LEGO1/legoutil.cpp b/LEGO1/legoutil.cpp index 9827b376..cd46c902 100644 --- a/LEGO1/legoutil.cpp +++ b/LEGO1/legoutil.cpp @@ -1,5 +1,6 @@ #include "legoutil.h" +#include "mxomni.h" #include "mxtypes.h" #include @@ -101,3 +102,9 @@ void ConvertHSVToRGB(float h, float s, float v, float *r_out, float *b_out, floa return; } } + +// OFFSET: LEGO1 0x1003ef40 +void SetAppCursor(WPARAM p_wparam) +{ + PostMessageA(MxOmni::GetInstance()->GetWindowHandle(), 0x5400, p_wparam, 0); +} diff --git a/LEGO1/legoutil.h b/LEGO1/legoutil.h index b736cd29..e912991d 100644 --- a/LEGO1/legoutil.h +++ b/LEGO1/legoutil.h @@ -1,6 +1,8 @@ #ifndef LEGOUTIL_H #define LEGOUTIL_H +#include + #include "extra.h" template @@ -23,5 +25,6 @@ inline T Max(T p_t1, T p_t2) ExtraActionType MatchActionString(const char *); void ConvertHSVToRGB(float r, float g, float b, float* out_r, float* out_g, float* out_b); +void SetAppCursor(WPARAM p_wparam); #endif // LEGOUTIL_H diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 17de7d73..200e5bdf 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -288,10 +288,4 @@ MxMusicManager* MusicManager() MxEventManager* EventManager() { return MxOmni::GetInstance()->GetEventManager(); -} - -// OFFSET: LEGO1 0x1003ef40 -void SetAppCursor(WPARAM p_wparam) -{ - PostMessageA(MxOmni::GetInstance()->GetWindowHandle(), 0x5400, p_wparam, 0); -} +} \ No newline at end of file diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 28e47124..a8fa9db8 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -92,6 +92,4 @@ __declspec(dllexport) MxNotificationManager * NotificationManager(); MxVideoManager * MVideoManager(); MxAtomIdCounterSet* AtomIdCounterSet(); -void SetAppCursor(WPARAM p_wparam); - #endif // MXOMNI_H diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index ea295dda..12bd0931 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -1,4 +1,5 @@ #include "mxtransitionmanager.h" +#include "legoutil.h" #include "legovideomanager.h" DECOMP_SIZE_ASSERT(MxTransitionManager, 0x900); diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 2276219d..1b662e98 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -5,7 +5,6 @@ #include "mxvideopresenter.h" #include "legoomni.h" - // VTABLE 0x100d7ea0 class MxTransitionManager : public MxCore { From 5b7954a97bb6c20cb03f1cd5b114c2001da8113c Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Fri, 29 Sep 2023 12:51:05 -0400 Subject: [PATCH 29/87] MxMusicPresenter: ClassName, IsA, ctor, Init (#145) --- LEGO1/mxmusicpresenter.cpp | 9 +++++++-- LEGO1/mxmusicpresenter.h | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/LEGO1/mxmusicpresenter.cpp b/LEGO1/mxmusicpresenter.cpp index 562f047c..d33627ad 100644 --- a/LEGO1/mxmusicpresenter.cpp +++ b/LEGO1/mxmusicpresenter.cpp @@ -1,7 +1,12 @@ #include "mxmusicpresenter.h" -// OFFSET: LEGO1 0x100c22c0 STUB +// OFFSET: LEGO1 0x100c22c0 MxMusicPresenter::MxMusicPresenter() { - // TODO + Init(); +} + +// OFFSET: LEGO1 0x100c2540 +void MxMusicPresenter::Init() +{ } \ No newline at end of file diff --git a/LEGO1/mxmusicpresenter.h b/LEGO1/mxmusicpresenter.h index e244b036..c8e88604 100644 --- a/LEGO1/mxmusicpresenter.h +++ b/LEGO1/mxmusicpresenter.h @@ -7,7 +7,23 @@ class MxMusicPresenter : public MxAudioPresenter { public: + // OFFSET: LEGO1 0x100c23a0 + inline virtual const char *ClassName() const override // vtable+0xc + { + // 0x10101e48 + return "MxMusicPresenter"; + } + + // OFFSET: LEGO1 0x100c23b0 + inline virtual MxBool IsA(const char *name) const override // vtable+0x10 + { + return !strcmp(name, MxMusicPresenter::ClassName()) || MxAudioPresenter::IsA(name); + } + MxMusicPresenter(); + +private: + void Init(); }; #endif // MXMUSICPRESENTER_H From f7743c51fb43cb310e1bc16a0cf2675e25c8eb3e Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Fri, 29 Sep 2023 13:18:22 -0400 Subject: [PATCH 30/87] MxMIDIPresenter: ClassName, IsA (#146) --- LEGO1/mxmidipresenter.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/LEGO1/mxmidipresenter.h b/LEGO1/mxmidipresenter.h index 1cd65c4a..07fc55a2 100644 --- a/LEGO1/mxmidipresenter.h +++ b/LEGO1/mxmidipresenter.h @@ -8,6 +8,20 @@ class MxMIDIPresenter : public MxMusicPresenter { public: MxMIDIPresenter(); + + // OFFSET: LEGO1 0x100c2650 + inline virtual const char *ClassName() const override // vtable+0xc + { + // 0x10101df8 + return "MxMIDIPresenter"; + } + + // OFFSET: LEGO1 0x100c2660 + inline virtual MxBool IsA(const char *name) const override // vtable+0x10 + { + return !strcmp(name, MxMIDIPresenter::ClassName()) || MxMusicPresenter::IsA(name); + } + private: void Init(); undefined4 m_unk54; From b77cd067d3f9dc5d25aa5143ebeea23b8d9c89a6 Mon Sep 17 00:00:00 2001 From: pewpew Date: Fri, 29 Sep 2023 13:40:46 -0500 Subject: [PATCH 31/87] reccmp: template compare annotations (#88) * reccmp: Add ability to compare template instantiations * Add example of template instantiation comparison. * merge * Add template compare annotations for MxList instances --------- Co-authored-by: Christian Semmler --- LEGO1/mxdsactionlist.h | 9 ++++++ LEGO1/mxlist.h | 9 ++---- LEGO1/mxnotificationmanager.cpp | 2 +- LEGO1/mxpresenterlist.h | 9 ++++++ tools/reccmp/reccmp.py | 51 +++++++++++++++++++++++---------- 5 files changed, 57 insertions(+), 23 deletions(-) diff --git a/LEGO1/mxdsactionlist.h b/LEGO1/mxdsactionlist.h index 4ae6e2a6..127dd142 100644 --- a/LEGO1/mxdsactionlist.h +++ b/LEGO1/mxdsactionlist.h @@ -25,4 +25,13 @@ class MxDSActionList : public MxList typedef MxListCursorChild MxDSActionListCursor; +// OFFSET: LEGO1 0x100c9d20 TEMPLATE +// MxListParent::Destroy + +// OFFSET: LEGO1 0x100c9cd0 TEMPLATE +// MxListParent::~MxListParent + +// OFFSET: LEGO1 0x100c9d30 TEMPLATE +// MxList::~MxList + #endif // MXDSACTIONLIST_H diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 0de71903..ed4c2802 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -31,15 +31,11 @@ class MxListParent : public MxCore m_count = 0; m_customDestructor = Destroy; } - // OFFSET: LEGO1 0x1001cdd0 + virtual ~MxListParent() {} - - // OFFSET: LEGO1 0x1001cd30 - static void Destroy(T *) {}; - - // OFFSET: LEGO1 0x1001cd20 virtual MxS8 Compare(T *, T *) = 0; + static void Destroy(T *) {}; protected: MxU32 m_count; // +0x8 void (*m_customDestructor)(T *); // +0xc @@ -114,7 +110,6 @@ class MxListCursorChildChild : public MxListCursorChild }; template -// OFFSET: LEGO1 0x1001ce20 MxList::~MxList() { DeleteAll(); diff --git a/LEGO1/mxnotificationmanager.cpp b/LEGO1/mxnotificationmanager.cpp index fe48c7c2..1b097067 100644 --- a/LEGO1/mxnotificationmanager.cpp +++ b/LEGO1/mxnotificationmanager.cpp @@ -182,4 +182,4 @@ MxResult MxNotificationManager::Send(MxCore *p_listener, MxParam *p_param) } return FAILURE; -} +} \ No newline at end of file diff --git a/LEGO1/mxpresenterlist.h b/LEGO1/mxpresenterlist.h index 5b36e2d8..71a7f9aa 100644 --- a/LEGO1/mxpresenterlist.h +++ b/LEGO1/mxpresenterlist.h @@ -26,4 +26,13 @@ class MxPresenterList : public MxPresenterListParent typedef MxListCursorChildChild MxPresenterListCursor; +// OFFSET: LEGO1 0x1001cd30 TEMPLATE +// MxListParent::Destroy + +// OFFSET: LEGO1 0x1001cdd0 TEMPLATE +// MxListParent::~MxListParent + +// OFFSET: LEGO1 0x1001ce20 TEMPLATE +// MxList::~MxList + #endif // MXPRESENTERLIST_H diff --git a/tools/reccmp/reccmp.py b/tools/reccmp/reccmp.py index 113dea2c..e0962534 100755 --- a/tools/reccmp/reccmp.py +++ b/tools/reccmp/reccmp.py @@ -10,6 +10,7 @@ import os import sys import colorama +import html import re parser = argparse.ArgumentParser(allow_abbrev=False, @@ -43,7 +44,7 @@ verbose = int(args.verbose, 16) except ValueError: parser.error('invalid verbose argument') -html = args.html +html_path = args.html plain = args.no_color @@ -140,6 +141,7 @@ def get_file_in_script_dir(fn): class SymInfo: funcs = {} lines = {} + names = {} def __init__(self, pdb, file, wine_path_converter): call = [get_file_in_script_dir('cvdump.exe'), '-l', '-s'] @@ -183,6 +185,7 @@ def __init__(self, pdb, file, wine_path_converter): info.name = line[77:] + self.names[info.name] = info self.funcs[addr] = info elif current_section == 'LINES' and line.startswith(' ') and not line.startswith(' '): sourcepath = line.split()[0] @@ -238,6 +241,14 @@ def get_recompiled_address(self, filename, line): else: logger.error('Failed to find function symbol with filename and line: %s:%d', filename, line) + def get_recompiled_address_from_name(self, name): + logger.debug('Looking for %s', name) + + if name in self.names: + return self.names[name] + else: + logger.error('Failed to find function symbol with name: %s', name) + wine_path_converter = None if os.name != 'nt': wine_path_converter = WinePathConverter(source) @@ -419,14 +430,24 @@ def can_resolve_register_differences(original_asm, new_asm): else: continue - find_open_bracket = line - while '{' not in find_open_bracket: - find_open_bracket = srcfile.readline() - line_no += 1 + if line.endswith("TEMPLATE"): + line = srcfile.readline() + line_no += 1 + # Name comes after // comment + name = line[2:].strip() - recinfo = syminfo.get_recompiled_address(srcfilename, line_no) - if not recinfo: - continue + recinfo = syminfo.get_recompiled_address_from_name(name) + if not recinfo: + continue + else: + find_open_bracket = line + while '{' not in find_open_bracket: + find_open_bracket = srcfile.readline() + line_no += 1 + + recinfo = syminfo.get_recompiled_address(srcfilename, line_no) + if not recinfo: + continue # The effective_ratio is the ratio when ignoring differing register # allocation vs the ratio is the true ratio. @@ -511,14 +532,14 @@ def can_resolve_register_differences(original_asm, new_asm): print("\n%s is only %s similar to the original, diff above" % (recinfo.name, percenttext)) # If html, record the diffs to an HTML file - if html: + if html_path: escaped = '\\n'.join(udiff).replace('"', '\\"').replace('\n', '\\n').replace('<', '<').replace('>', '>') - htmlinsert.append('{address: "%s", name: "%s", matching: %s, diff: "%s"}' % (hex(addr), recinfo.name, str(effective_ratio), escaped)) + htmlinsert.append('{address: "%s", name: "%s", matching: %s, diff: "%s"}' % (hex(addr), html.escape(recinfo.name), str(effective_ratio), escaped)) except UnicodeDecodeError: break -def gen_html(html, data): +def gen_html(html_path, data): templatefile = open(get_file_in_script_dir('template.html'), 'r') if not templatefile: print('Failed to find HTML template file, can\'t generate HTML summary') @@ -529,9 +550,9 @@ def gen_html(html, data): templatedata = templatedata.replace('/* INSERT DATA HERE */', ','.join(data), 1) - htmlfile = open(html, 'w') + htmlfile = open(html_path, 'w') if not htmlfile: - print('Failed to write to HTML file %s' % html) + print('Failed to write to HTML file %s' % html_path) return htmlfile.write(templatedata) @@ -580,8 +601,8 @@ def gen_svg(svg, name, icon, implemented_funcs, total_funcs, raw_accuracy): svgfile.write(templatedata) svgfile.close() -if html: - gen_html(html, htmlinsert) +if html_path: + gen_html(html_path, htmlinsert) if verbose: if not found_verbose_target: From 0dc8dd641ab17cb6efaa840f21067d4e2cfaf734 Mon Sep 17 00:00:00 2001 From: MS Date: Fri, 29 Sep 2023 16:38:08 -0400 Subject: [PATCH 32/87] MxVariable subclass for fsmovie setting (#147) * LegoFullScreenMovie variable and related * Changes after review - Reduce scope on global strings - Size assert for LegoGameState (based on the constructor references only) - 1 -> TRUE for EnableFullScreenMovie --- CMakeLists.txt | 1 + LEGO1/legobackgroundcolor.cpp | 3 +++ LEGO1/legobackgroundcolor.h | 4 +++- LEGO1/legofullscreenmovie.cpp | 41 +++++++++++++++++++++++++++++++++++ LEGO1/legofullscreenmovie.h | 15 +++++++++++++ LEGO1/legogamestate.cpp | 16 ++++++++++++++ LEGO1/legogamestate.h | 11 +++++++++- LEGO1/legovideomanager.cpp | 8 ++++++- LEGO1/legovideomanager.h | 3 ++- LEGO1/mxvariable.cpp | 3 +++ LEGO1/mxvariable.h | 3 ++- 11 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 LEGO1/legofullscreenmovie.cpp create mode 100644 LEGO1/legofullscreenmovie.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c408d65..bcdadc2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,7 @@ add_library(lego1 SHARED LEGO1/legoentity.cpp LEGO1/legoentitypresenter.cpp LEGO1/legoflctexturepresenter.cpp + LEGO1/legofullscreenmovie.cpp LEGO1/legogamestate.cpp LEGO1/legohideanimpresenter.cpp LEGO1/legoinputmanager.cpp diff --git a/LEGO1/legobackgroundcolor.cpp b/LEGO1/legobackgroundcolor.cpp index e1d6beca..cc1483b3 100644 --- a/LEGO1/legobackgroundcolor.cpp +++ b/LEGO1/legobackgroundcolor.cpp @@ -3,6 +3,9 @@ #include "legoomni.h" #include "legoutil.h" #include "legovideomanager.h" +#include "decomp.h" + +DECOMP_SIZE_ASSERT(LegoBackgroundColor, 0x30) const char *g_delimiter = "\t"; const char *g_set = "set"; diff --git a/LEGO1/legobackgroundcolor.h b/LEGO1/legobackgroundcolor.h index aff62fe8..884a477b 100644 --- a/LEGO1/legobackgroundcolor.h +++ b/LEGO1/legobackgroundcolor.h @@ -3,11 +3,13 @@ #include "mxvariable.h" +// VTABLE 0x100d74a8 +// SIZE 0x30 class LegoBackgroundColor : public MxVariable { public: __declspec(dllexport) LegoBackgroundColor(const char *p_key, const char *p_value); - void SetValue(const char *p_colorString); + virtual void SetValue(const char *p_colorString) override; private: float h; diff --git a/LEGO1/legofullscreenmovie.cpp b/LEGO1/legofullscreenmovie.cpp new file mode 100644 index 00000000..f2a287f3 --- /dev/null +++ b/LEGO1/legofullscreenmovie.cpp @@ -0,0 +1,41 @@ +#include "legofullscreenmovie.h" +#include "mxtypes.h" +#include "legoomni.h" +#include "decomp.h" + +DECOMP_SIZE_ASSERT(LegoFullScreenMovie, 0x24) + +// 0x100f3be8 +const char *g_str_enable = "enable"; + +// 0x100f3bf4 +const char *g_str_disable = "disable"; + +// OFFSET: LEGO1 0x1003c500 +LegoFullScreenMovie::LegoFullScreenMovie(const char *p_key, const char *p_value) +{ + m_key = p_key; + m_key.ToUpperCase(); + SetValue(p_value); +} + +// OFFSET: LEGO1 0x1003c5c0 +void LegoFullScreenMovie::SetValue(const char *p_option) +{ + m_value = p_option; + m_value.ToLowerCase(); + + LegoVideoManager *videomanager = VideoManager(); + if (videomanager) { + + if (!strcmp(m_value.GetData(), g_str_enable)) { + videomanager->EnableFullScreenMovie(TRUE); + return; + } + + if (!strcmp(m_value.GetData(), g_str_disable)) { + videomanager->EnableFullScreenMovie(FALSE); + return; + } + } +} diff --git a/LEGO1/legofullscreenmovie.h b/LEGO1/legofullscreenmovie.h new file mode 100644 index 00000000..ffe350f5 --- /dev/null +++ b/LEGO1/legofullscreenmovie.h @@ -0,0 +1,15 @@ +#ifndef LEGOFULLSCREENMOVIE_H +#define LEGOFULLSCREENMOVIE_H + +#include "mxvariable.h" + +// VTABLE 0x100d74b8 +// SIZE 0x24 +class LegoFullScreenMovie : public MxVariable +{ +public: + LegoFullScreenMovie(const char *p_key, const char *p_value); + virtual void SetValue(const char *p_option) override; +}; + +#endif // LEGOFULLSCREENMOVIE_H diff --git a/LEGO1/legogamestate.cpp b/LEGO1/legogamestate.cpp index 344cf1ca..0f444f95 100644 --- a/LEGO1/legogamestate.cpp +++ b/LEGO1/legogamestate.cpp @@ -1,10 +1,26 @@ #include "legogamestate.h" #include "legoomni.h" +#include "decomp.h" + +// Based on the highest dword offset (0x42c) referenced in the constructor. +// There may be other members that come after. +DECOMP_SIZE_ASSERT(LegoGameState, 0x430) // OFFSET: LEGO1 0x10039550 LegoGameState::LegoGameState() { // TODO + m_backgroundColor = new LegoBackgroundColor("backgroundcolor", "set 56 54 68"); + VariableTable()->SetVariable(m_backgroundColor); + + m_tempBackgroundColor = new LegoBackgroundColor("tempBackgroundcolor", "set 56 54 68"); + VariableTable()->SetVariable(m_tempBackgroundColor); + + m_fullScreenMovie = new LegoFullScreenMovie("fsmovie", "disable"); + VariableTable()->SetVariable(m_fullScreenMovie); + + VariableTable()->SetVariable("lightposition", "2"); + SerializeScoreHistory(1); } // OFFSET: LEGO1 0x10039720 diff --git a/LEGO1/legogamestate.h b/LEGO1/legogamestate.h index ef2eeb1e..b1cd8b60 100644 --- a/LEGO1/legogamestate.h +++ b/LEGO1/legogamestate.h @@ -1,8 +1,12 @@ #ifndef LEGOGAMESTATE_H #define LEGOGAMESTATE_H +#include "decomp.h" #include "mxtypes.h" +#include "legobackgroundcolor.h" +#include "legofullscreenmovie.h" +// SIZE 0x430 (at least) class LegoGameState { public: @@ -15,7 +19,12 @@ class LegoGameState __declspec(dllexport) void SetSavePath(char *p); private: - char *m_savePath; + char *m_savePath; // 0x0 + undefined m_unk04[20]; + LegoBackgroundColor *m_backgroundColor; // 0x18 + LegoBackgroundColor *m_tempBackgroundColor; // 0x1c + LegoFullScreenMovie *m_fullScreenMovie; // 0x20 + undefined m_unk24[1036]; }; #endif // LEGOGAMESTATE_H diff --git a/LEGO1/legovideomanager.cpp b/LEGO1/legovideomanager.cpp index 9c1044e2..4105ef2a 100644 --- a/LEGO1/legovideomanager.cpp +++ b/LEGO1/legovideomanager.cpp @@ -27,8 +27,14 @@ int LegoVideoManager::DisableRMDevice() return 0; } +// OFFSET: LEGO1 0x1007c300 +void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable) +{ + EnableFullScreenMovie(p_enable, TRUE); +} + // OFFSET: LEGO1 0x1007c310 STUB -void LegoVideoManager::EnableFullScreenMovie(unsigned char a, unsigned char b) +void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable, MxBool p_scale) { // TODO } diff --git a/LEGO1/legovideomanager.h b/LEGO1/legovideomanager.h index d71c39a1..4ff8491b 100644 --- a/LEGO1/legovideomanager.h +++ b/LEGO1/legovideomanager.h @@ -16,7 +16,8 @@ class LegoVideoManager : public MxVideoManager __declspec(dllexport) int EnableRMDevice(); __declspec(dllexport) int DisableRMDevice(); - __declspec(dllexport) void EnableFullScreenMovie(unsigned char a, unsigned char b); + void EnableFullScreenMovie(MxBool p_enable); + __declspec(dllexport) void EnableFullScreenMovie(MxBool p_enable, MxBool p_scale); __declspec(dllexport) void MoveCursor(int x, int y); inline Lego3DManager *Get3DManager() { return this->m_3dManager; } diff --git a/LEGO1/mxvariable.cpp b/LEGO1/mxvariable.cpp index f18e6a94..0c9bf95a 100644 --- a/LEGO1/mxvariable.cpp +++ b/LEGO1/mxvariable.cpp @@ -1,5 +1,8 @@ #include "mxvariable.h" #include "mxstring.h" +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxVariable, 0x24) // OFFSET: LEGO1 0x1003bea0 MxString *MxVariable::GetValue() diff --git a/LEGO1/mxvariable.h b/LEGO1/mxvariable.h index 6899dfac..83c83020 100644 --- a/LEGO1/mxvariable.h +++ b/LEGO1/mxvariable.h @@ -4,7 +4,8 @@ #include "mxstring.h" #include "mxcore.h" -//VTABLE: 0x100d74a8 +// VTABLE 0x100d7498 +// SIZE 0x24 class MxVariable { public: From 06c7ba2c3787c764892f90c39c5f9cf47b71aef9 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Fri, 29 Sep 2023 17:53:02 -0400 Subject: [PATCH 33/87] MxDiskStreamProvider constructor (#131) * MxDiskStreamProvider constructor * Add work-in-progress list struct to MxDiskStreamProvider --------- Co-authored-by: Christian Semmler --- LEGO1/mxdiskstreamprovider.cpp | 8 +++++-- LEGO1/mxdiskstreamprovider.h | 41 +++++++++++++++++++++++++++------- LEGO1/mxstreamprovider.h | 7 +++++- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp index 38d5cddc..4dcb02cf 100644 --- a/LEGO1/mxdiskstreamprovider.cpp +++ b/LEGO1/mxdiskstreamprovider.cpp @@ -2,6 +2,8 @@ #include "mxthread.h" +DECOMP_SIZE_ASSERT(MxDiskStreamProvider, 0x60); + // OFFSET: LEGO1 0x100d0f30 MxResult MxDiskStreamProviderThread::Run() { @@ -15,7 +17,9 @@ MxResult MxDiskStreamProviderThread::Run() // OFFSET: LEGO1 0x100d0f70 MxDiskStreamProvider::MxDiskStreamProvider() { - // TODO + this->m_pFile = NULL; + this->m_remainingWork = 0; + this->m_unk35 = 0; } // OFFSET: LEGO1 0x100d1240 @@ -31,7 +35,7 @@ MxResult MxDiskStreamProvider::WaitForWorkToComplete() while (m_remainingWork != 0) { m_busySemaphore.Wait(INFINITE); - if (m_unk1 != 0) + if (m_unk35 != 0) PerformWork(); } return SUCCESS; diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index 58679055..b6ff8c18 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -1,6 +1,7 @@ #ifndef MXDISKSTREAMPROVIDER_H #define MXDISKSTREAMPROVIDER_H +#include "decomp.h" #include "mxstreamprovider.h" #include "mxthread.h" #include "mxcriticalsection.h" @@ -22,6 +23,32 @@ class MxDiskStreamProviderThread : public MxThread MxDiskStreamProvider *m_target; }; +// TODO +struct MxDiskStreamListNode { + MxDiskStreamListNode *m_unk00; + MxDiskStreamListNode *m_unk04; + undefined4 m_unk08; +}; + +// TODO +struct MxDiskStreamList { + inline MxDiskStreamList() { + undefined unk; + this->m_unk00 = unk; + + MxDiskStreamListNode *node = new MxDiskStreamListNode(); + node->m_unk00 = node; + node->m_unk04 = node; + + this->m_head = node; + this->m_count = 0; + } + + undefined m_unk00; + MxDiskStreamListNode *m_head; + MxU32 m_count; +}; + // VTABLE 0x100dd138 class MxDiskStreamProvider : public MxStreamProvider { @@ -48,14 +75,12 @@ class MxDiskStreamProvider : public MxStreamProvider void PerformWork(); private: - MxDiskStreamProviderThread m_thread; - MxSemaphore m_busySemaphore; - byte m_remainingWork; - byte m_unk1; - MxCriticalSection m_criticalSection; - byte unk2[4]; - void* unk3; - void *unk4; + MxDiskStreamProviderThread m_thread; // 0x10 + MxSemaphore m_busySemaphore; // 0x2c + undefined m_remainingWork; // 0x34 + undefined m_unk35; // 0x35 + MxCriticalSection m_criticalSection; // 0x38 + MxDiskStreamList m_list; }; #endif // MXDISKSTREAMPROVIDER_H diff --git a/LEGO1/mxstreamprovider.h b/LEGO1/mxstreamprovider.h index b70b6446..2daf75ab 100644 --- a/LEGO1/mxstreamprovider.h +++ b/LEGO1/mxstreamprovider.h @@ -8,6 +8,11 @@ class MxStreamProvider : public MxCore { public: + inline MxStreamProvider() { + this->m_pLookup = NULL; + this->m_pFile = NULL; + } + // OFFSET: LEGO1 0x100d07e0 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -20,7 +25,7 @@ class MxStreamProvider : public MxCore return !strcmp(name, MxStreamProvider::ClassName()) || MxCore::IsA(name); } -private: +protected: void *m_pLookup; MxDSFile* m_pFile; }; From b20aa9b8fb03f07481a0dffc31cb07a5a05a59d0 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Sat, 30 Sep 2023 18:57:10 -0400 Subject: [PATCH 34/87] Police, PoliceEntity ClassName and IsA (#150) --- LEGO1/police.h | 14 +++++++++++++- LEGO1/policeentity.h | 12 ++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/LEGO1/police.h b/LEGO1/police.h index 8ff6dff9..a11264da 100644 --- a/LEGO1/police.h +++ b/LEGO1/police.h @@ -13,7 +13,19 @@ class Police : public LegoWorld virtual ~Police() override; // vtable+0x0 virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - + + // OFFSET: LEGO1 0x1005e1e0 + inline virtual const char *ClassName() const override // vtable+0xc + { + // 0x100f0450 + return "Police"; + } + + // OFFSET: LEGO1 0x1005e1f0 + inline virtual MxBool IsA(const char *name) const override // vtable+0x10 + { + return !strcmp(name, Police::ClassName()) || LegoWorld::IsA(name); + } }; #endif // POLICE_H diff --git a/LEGO1/policeentity.h b/LEGO1/policeentity.h index a23cced4..3a301016 100644 --- a/LEGO1/policeentity.h +++ b/LEGO1/policeentity.h @@ -7,7 +7,19 @@ // SIZE 0x68 class PoliceEntity : public BuildingEntity { +public: + // OFFSET: LEGO1 0x1000ed60 + inline virtual const char *ClassName() const override // vtable+0xc + { + // 0x100f0328 + return "PoliceEntity"; + } + // OFFSET: LEGO1 0x1000ed70 + inline virtual MxBool IsA(const char *name) const override // vtable+0x10 + { + return !strcmp(name, PoliceEntity::ClassName()) || BuildingEntity::IsA(name); + } }; #endif // POLICEENTITY_H From 7f423439b7516423c434c79a98ba8f98546e7dcf Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Sat, 30 Sep 2023 19:25:33 -0400 Subject: [PATCH 35/87] Fix pizza constructor (#149) * Pizza: fix type of m_unk98 * Fix pizza constructor * Match Pizza::Pizza * Use undefined type --------- Co-authored-by: Christian Semmler --- LEGO1/legoactor.cpp | 5 +++++ LEGO1/legoactor.h | 2 ++ LEGO1/pizza.cpp | 4 +--- LEGO1/pizza.h | 21 ++++++++++++--------- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/LEGO1/legoactor.cpp b/LEGO1/legoactor.cpp index c26cc1fc..7faa3b0d 100644 --- a/LEGO1/legoactor.cpp +++ b/LEGO1/legoactor.cpp @@ -1,3 +1,8 @@ #include "legoactor.h" DECOMP_SIZE_ASSERT(LegoActor, 0x78) + +// OFFSET: LEGO1 0x1002d110 STUB +LegoActor::LegoActor() +{ +} \ No newline at end of file diff --git a/LEGO1/legoactor.h b/LEGO1/legoactor.h index cc8778db..fe5e43a0 100644 --- a/LEGO1/legoactor.h +++ b/LEGO1/legoactor.h @@ -9,6 +9,8 @@ class LegoActor : public LegoEntity { public: + LegoActor(); + // OFFSET: LEGO1 0x1002d210 inline virtual const char *ClassName() const override // vtable+0x0c { diff --git a/LEGO1/pizza.cpp b/LEGO1/pizza.cpp index 7e153b26..047e34bb 100644 --- a/LEGO1/pizza.cpp +++ b/LEGO1/pizza.cpp @@ -1,13 +1,11 @@ #include "pizza.h" -#include "decomp.h" - DECOMP_SIZE_ASSERT(Pizza, 0x9c); // OFFSET: LEGO1 0x10037ef0 Pizza::Pizza() { - // FIXME: This inherits from LegoActor, probably why this isn't matching + this->m_unk7c = 0; this->m_unk80 = 0; this->m_unk84 = 0; this->m_unk88 = 0; diff --git a/LEGO1/pizza.h b/LEGO1/pizza.h index 34d781c9..d6909810 100644 --- a/LEGO1/pizza.h +++ b/LEGO1/pizza.h @@ -1,6 +1,8 @@ #ifndef PIZZA_H #define PIZZA_H +#include "decomp.h" + #include "isleactor.h" #include "mxcore.h" #include "mxomni.h" @@ -29,16 +31,17 @@ class Pizza : public IsleActor { return !strcmp(name, Pizza::ClassName()) || IsleActor::IsA(name); } + private: - MxS32 m_unk78; - MxS32 m_unk7c; - MxS32 m_unk80; - MxS32 m_unk84; - MxS32 m_unk88; - MxS32 m_unk8c; - MxU32 m_unk90; - MxS32 m_unk94; - MxS32 m_unk98; + undefined4 m_unk78; + undefined4 m_unk7c; + undefined4 m_unk80; + undefined4 m_unk84; + undefined4 m_unk88; + undefined4 m_unk8c; + undefined4 m_unk90; + undefined4 m_unk94; + undefined m_unk98; }; #endif // PIZZA_H From 87259860858a1e773e5261ba57defb3e9d4cf630 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Sun, 1 Oct 2023 08:49:55 -0400 Subject: [PATCH 36/87] MxControlPresenter ctor/structure (#151) * MxControlPresenter ctor/structure * Use undefined types where possible, remove implicit pads --------- Co-authored-by: Christian Semmler --- LEGO1/mxcontrolpresenter.cpp | 11 +++++++++-- LEGO1/mxcontrolpresenter.h | 10 +++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/LEGO1/mxcontrolpresenter.cpp b/LEGO1/mxcontrolpresenter.cpp index e9e10ef8..7210952c 100644 --- a/LEGO1/mxcontrolpresenter.cpp +++ b/LEGO1/mxcontrolpresenter.cpp @@ -1,7 +1,14 @@ #include "mxcontrolpresenter.h" -// OFFSET: LEGO1 0x10043f50 STUB +DECOMP_SIZE_ASSERT(MxControlPresenter, 0x5c) + +// OFFSET: LEGO1 0x10043f50 MxControlPresenter::MxControlPresenter() { - // TODO + this->m_unk4c = 0; + this->m_unk4e = -1; + this->m_unk50 = 0; + this->m_unk52 = 0; + this->m_unk58 = 0; + this->m_unk54 = 0; } \ No newline at end of file diff --git a/LEGO1/mxcontrolpresenter.h b/LEGO1/mxcontrolpresenter.h index 909a3502..18af66a3 100644 --- a/LEGO1/mxcontrolpresenter.h +++ b/LEGO1/mxcontrolpresenter.h @@ -1,6 +1,8 @@ #ifndef MXCONTROLPRESENTER_H #define MXCONTROLPRESENTER_H +#include "decomp.h" + #include "mxcompositepresenter.h" // VTABLE 0x100d7b88 @@ -22,7 +24,13 @@ class MxControlPresenter : public MxCompositePresenter { return !strcmp(name, MxControlPresenter::ClassName()) || MxCompositePresenter::IsA(name); } - +private: + undefined2 m_unk4c; + MxS16 m_unk4e; + undefined m_unk50; + undefined2 m_unk52; + undefined2 m_unk54; + undefined4 m_unk58; }; From 592ede1c7bfea6b73ab87f5728b58a58b0f4dec7 Mon Sep 17 00:00:00 2001 From: MS Date: Sun, 1 Oct 2023 09:06:29 -0400 Subject: [PATCH 37/87] LegoEntity::Reset (#152) --- LEGO1/legoentity.cpp | 31 ++++++++++++++++++++++++++++--- LEGO1/legoentity.h | 15 ++++++++++++++- LEGO1/mxentity.cpp | 4 +--- LEGO1/mxentity.h | 3 +-- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/LEGO1/legoentity.cpp b/LEGO1/legoentity.cpp index d2062946..105b4b5f 100644 --- a/LEGO1/legoentity.cpp +++ b/LEGO1/legoentity.cpp @@ -9,7 +9,7 @@ DECOMP_SIZE_ASSERT(LegoEntity, 0x68) // OFFSET: LEGO1 0x1000c290 LegoEntity::~LegoEntity() { - Destroy(); + Destroy(TRUE); } // OFFSET: LEGO1 0x100114f0 STUB @@ -20,6 +20,26 @@ MxLong LegoEntity::Notify(MxParam &p) return 0; } +// OFFSET: LEGO1 0x100105f0 +void LegoEntity::Reset() +{ + float value = 0.0f; + m_vec1.EqualsScalar(&value); + + value = 0.0f; + m_vec2.EqualsScalar(&value); + + m_unk50 = 0; + m_unk54 = 0; + m_unk58 = 0; + m_actionArgString = NULL; + m_unk10 = 0; + m_unk11 = 0; + m_actionType = ExtraActionType_unknown; + m_actionArgNumber = -1; + m_unk59 = 4; +} + // OFFSET: LEGO1 0x100107e0 STUB void LegoEntity::vtable18() { @@ -27,9 +47,14 @@ void LegoEntity::vtable18() } // OFFSET: LEGO1 0x10010810 STUB -void LegoEntity::Destroy() +void LegoEntity::Destroy(MxBool) { - // TODO + if (m_unk54) { + // TODO + } + + delete[] m_actionArgString; + Reset(); } // OFFSET: LEGO1 0x10010e10 diff --git a/LEGO1/legoentity.h b/LEGO1/legoentity.h index 9fbbb5bb..79acca27 100644 --- a/LEGO1/legoentity.h +++ b/LEGO1/legoentity.h @@ -2,7 +2,9 @@ #define LEGOENTITY_H #include "mxentity.h" +#include "mxvector.h" #include "extra.h" +#include "decomp.h" // VTABLE 0x100d4858 // SIZE 0x68 (probably) @@ -33,10 +35,21 @@ class LegoEntity : public MxEntity } virtual void vtable18(); // vtable+0x18 - virtual void Destroy(); // vtable+0x1c + virtual void Destroy(MxBool); // vtable+0x1c virtual void ParseAction(char *); // vtable+0x20 protected: + void Reset(); + + undefined m_unk10; + undefined m_unk11; + MxVector3Data m_vec1; // 0x14 + MxVector3Data m_vec2; // 0x28 + MxVector3Data m_vec3; // 0x3c + undefined4 m_unk50; + undefined4 m_unk54; + undefined m_unk58; + undefined m_unk59; // For tokens from the extra string that look like this: // "Action:openram;\lego\scripts\Race\CarRaceR;0" ExtraActionType m_actionType; // 0x5c diff --git a/LEGO1/mxentity.cpp b/LEGO1/mxentity.cpp index 54e854ab..585150f1 100644 --- a/LEGO1/mxentity.cpp +++ b/LEGO1/mxentity.cpp @@ -1,8 +1,6 @@ #include "mxentity.h" -// Size subject to change. It's not clear yet which members belong to -// MxEntity and which belong only the subclasses. -DECOMP_SIZE_ASSERT(MxEntity, 0x5c) +DECOMP_SIZE_ASSERT(MxEntity, 0x10) // OFFSET: LEGO1 0x1001d190 MxEntity::MxEntity() diff --git a/LEGO1/mxentity.h b/LEGO1/mxentity.h index 3d73292e..44afd9c4 100644 --- a/LEGO1/mxentity.h +++ b/LEGO1/mxentity.h @@ -7,7 +7,7 @@ #include "mxtypes.h" // VTABLE 0x100d5390 -// SIZE 0x68 or less +// SIZE 0x10 class MxEntity : public MxCore { public: @@ -31,7 +31,6 @@ class MxEntity : public MxCore private: MxS32 m_mxEntityId; // 0x8 MxAtomId m_atom; // 0xc - undefined m_unk10[76]; }; #endif // MXENTITY_H From 56f3d120964c6dea5e994132e0db4c1743575bb1 Mon Sep 17 00:00:00 2001 From: MattKC <34096995+itsmattkc@users.noreply.github.com> Date: Sun, 1 Oct 2023 17:18:16 -0700 Subject: [PATCH 38/87] Implement MxTransitionManager ctor/dtor/rest of StartTransition (#153) --- LEGO1/mxtransitionmanager.cpp | 65 +++++++++++++++++++++++------------ LEGO1/mxtransitionmanager.h | 60 ++++++++++++++++++++++++++++++-- LEGO1/mxtypes.h | 15 ++++++++ LEGO1/mxvideoparamflags.h | 15 +------- 4 files changed, 116 insertions(+), 39 deletions(-) diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 12bd0931..c5a0cb27 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -4,16 +4,30 @@ DECOMP_SIZE_ASSERT(MxTransitionManager, 0x900); -// OFFSET: LEGO1 0x1004b8d0 STUB +// OFFSET: LEGO1 0x1004b8d0 MxTransitionManager::MxTransitionManager() { - // TODO + m_animationTimer = 0; + m_transitionType = NOT_TRANSITIONING; + m_ddSurface = NULL; + m_unk08 = 0; + m_unk1c = 0; + m_unk20.bit0 = FALSE; + m_unk28.bit0 = FALSE; + m_unk24 = 0; } -// OFFSET: LEGO1 0x1004ba00 STUB +// OFFSET: LEGO1 0x1004ba00 MxTransitionManager::~MxTransitionManager() { - // TODO + free(m_unk1c); + + if (m_unk08 != NULL) { + delete m_unk08->m_unk1c; + delete m_unk08; + } + + TickleManager()->UnregisterClient(this); } // OFFSET: LEGO1 0x1004bac0 STUB @@ -40,36 +54,43 @@ MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 // OFFSET: LEGO1 0x1004bb70 MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, MxS32 p_speed, - undefined p_unk, MxBool p_playMusicInAnim) + MxBool p_unk, MxBool p_playMusicInAnim) { - // TODO: Incomplete and far from matching - if (this->m_transitionType == NOT_TRANSITIONING) { if (!p_playMusicInAnim) { MxBackgroundAudioManager *backgroundAudioManager = BackgroundAudioManager(); backgroundAudioManager->Stop(); } - this->m_transitionType = p_animationType; - // TODO: This part of the function is mangled and I can't make out what it's doing right now + this->m_transitionType = p_animationType; - MxU32 time = timeGetTime(); - this->m_systemTime = time; + m_unk20.bit0 = p_unk; - this->m_animationSpeed = p_speed; + if (m_unk20.bit0 && m_unk08 != NULL) { + m_unk08->vtable54(1); - MxTickleManager *tickleManager = TickleManager(); - tickleManager->RegisterClient(this, p_speed); + MxTransitionManagerUnknownSubclass2 *iVar2 = m_unk08->m_unk1c; + iVar2->m_unk3c = 10000; + iVar2->m_unk30 |= 0x200; + } - LegoInputManager *inputManager = InputManager(); - inputManager->m_unk88 = TRUE; - inputManager->m_unk336 = FALSE; + MxU32 time = timeGetTime(); + this->m_systemTime = time; - LegoVideoManager *videoManager = VideoManager(); - videoManager->SetUnkE4(FALSE); + this->m_animationSpeed = p_speed; - SetAppCursor(1); - return SUCCESS; + MxTickleManager *tickleManager = TickleManager(); + tickleManager->RegisterClient(this, p_speed); + + LegoInputManager *inputManager = InputManager(); + inputManager->m_unk88 = TRUE; + inputManager->m_unk336 = FALSE; + + LegoVideoManager *videoManager = VideoManager(); + videoManager->SetUnkE4(FALSE); + + SetAppCursor(1); + return SUCCESS; } return FAILURE; -} \ No newline at end of file +} diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 1b662e98..723366c1 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -5,6 +5,52 @@ #include "mxvideopresenter.h" #include "legoomni.h" +class MxTransitionManagerUnknownSubclass2 +{ +public: + virtual ~MxTransitionManagerUnknownSubclass2(){} + + undefined m_unk04[0x2c]; + undefined4 m_unk30; + undefined4 m_unk34; + undefined4 m_unk38; + undefined4 m_unk3c; + +}; + +// TODO: Don't know what this is yet +class MxTransitionManagerUnknownSubclass1 +{ +public: + virtual ~MxTransitionManagerUnknownSubclass1(){} + + virtual void vtable04(); + virtual void vtable08(); + virtual void vtable0c(); + virtual void vtable10(); + virtual void vtable14(); + virtual void vtable18(); + virtual void vtable1c(); + virtual void vtable20(); + virtual void vtable24(); + virtual void vtable28(); + virtual void vtable2c(); + virtual void vtable30(); + virtual void vtable34(); + virtual void vtable38(); + virtual void vtable3c(); + virtual void vtable40(); + virtual void vtable44(); + virtual void vtable48(); + virtual void vtable4c(); + virtual void vtable50(); + virtual void vtable54(undefined4 p_unk1); + + undefined m_unk04[0x18]; + MxTransitionManagerUnknownSubclass2 *m_unk1c; + +}; + // VTABLE 0x100d7ea0 class MxTransitionManager : public MxCore { @@ -40,11 +86,19 @@ class MxTransitionManager : public MxCore BROKEN // Unknown what this is supposed to be, it locks the game up }; - MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, undefined p_unk, MxBool p_playMusicInAnim); + MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_unk, MxBool p_playMusicInAnim); private: - undefined m_pad00[0x20]; - undefined m_pad20[0x04]; + MxTransitionManagerUnknownSubclass1 *m_unk08; + undefined4 m_unk0c; + undefined4 m_unk10; + undefined4 m_unk14; + undefined4 m_unk18; + void *m_unk1c; + flag_bitfield m_unk20; + undefined4 m_unk24; + flag_bitfield m_unk28; + TransitionType m_transitionType; LPDIRECTDRAWSURFACE m_ddSurface; MxU16 m_animationTimer; diff --git a/LEGO1/mxtypes.h b/LEGO1/mxtypes.h index fc8d47b5..75f19d4a 100644 --- a/LEGO1/mxtypes.h +++ b/LEGO1/mxtypes.h @@ -44,4 +44,19 @@ typedef MxU8 MxBool; #define TWOCC(a, b) (((a) << 0) | ((b) << 8)) #define FOURCC(a, b, c, d) (((a) << 0) | ((b) << 8) | ((c) << 16) | ((d) << 24)) +// Must be union with struct for match. +typedef union { + struct { + MxU8 bit0: 1; + MxU8 bit1: 1; + MxU8 bit2: 1; + MxU8 bit3: 1; + MxU8 bit4: 1; + MxU8 bit5: 1; + MxU8 bit6: 1; + MxU8 bit7: 1; + }; + // BYTE all; // ? +} flag_bitfield; + #endif // MXTYPE_H diff --git a/LEGO1/mxvideoparamflags.h b/LEGO1/mxvideoparamflags.h index f25ab4bd..8d1714ed 100644 --- a/LEGO1/mxvideoparamflags.h +++ b/LEGO1/mxvideoparamflags.h @@ -3,20 +3,7 @@ #include -// Must be union with struct for match. -typedef union { - struct { - BYTE bit0: 1; - BYTE bit1: 1; - BYTE bit2: 1; - BYTE bit3: 1; - BYTE bit4: 1; - BYTE bit5: 1; - BYTE bit6: 1; - BYTE bit7: 1; - }; - // BYTE all; // ? -} flag_bitfield; +#include "mxtypes.h" class MxVideoParamFlags { From b7efd64ac1ce93f2d15f646c68d5c5917be0a17b Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 2 Oct 2023 09:51:43 -0400 Subject: [PATCH 39/87] Bootstrap MxDSSelectAction, generalize MxList (#142) * reccmp: Add ability to compare template instantiations * Add example of template instantiation comparison. * merge * Add template compare annotations for MxList instances * Bootstrap MxDSSelectAction, generalize MxList * Fix template annotations * Fix merge error * Fix merge error --------- Co-authored-by: Brendan Dougherty --- LEGO1/mxdsactionlist.h | 14 +++++++------- LEGO1/mxdsselectaction.cpp | 7 ++++--- LEGO1/mxdsselectaction.h | 10 ++++------ LEGO1/mxlist.h | 38 +++++++++++++++++++++----------------- LEGO1/mxpresenterlist.h | 14 +++++++------- LEGO1/mxstringlist.h | 23 +++++++++++++++++++++++ 6 files changed, 66 insertions(+), 40 deletions(-) create mode 100644 LEGO1/mxstringlist.h diff --git a/LEGO1/mxdsactionlist.h b/LEGO1/mxdsactionlist.h index 127dd142..fe0e162c 100644 --- a/LEGO1/mxdsactionlist.h +++ b/LEGO1/mxdsactionlist.h @@ -8,7 +8,7 @@ class MxDSAction; // VTABLE 0x100dced8 // SIZE 0x1c -class MxDSActionList : public MxList +class MxDSActionList : public MxList { public: MxDSActionList() { @@ -23,15 +23,15 @@ class MxDSActionList : public MxList undefined m_unk18; }; -typedef MxListCursorChild MxDSActionListCursor; +typedef MxListCursorChild MxDSActionListCursor; + +// OFFSET: LEGO1 0x100c9cc0 TEMPLATE +// MxListParent::Compare // OFFSET: LEGO1 0x100c9d20 TEMPLATE -// MxListParent::Destroy - -// OFFSET: LEGO1 0x100c9cd0 TEMPLATE -// MxListParent::~MxListParent +// MxListParent::Destroy // OFFSET: LEGO1 0x100c9d30 TEMPLATE -// MxList::~MxList +// MxList::~MxList #endif // MXDSACTIONLIST_H diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 1c21b466..29f69022 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -5,12 +5,13 @@ DECOMP_SIZE_ASSERT(MxDSSelectAction, 0xb0) // OFFSET: LEGO1 0x100cb2b0 MxDSSelectAction::MxDSSelectAction() { - // TODO this->SetType(MxDSType_SelectAction); + this->m_unk0xac = new MxStringList; } -// OFFSET: LEGO1 0x100cb8d0 STUB +// OFFSET: LEGO1 0x100cb8d0 MxDSSelectAction::~MxDSSelectAction() { - // TODO + if (this->m_unk0xac) + delete this->m_unk0xac; } diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index df956fbc..d513efd0 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -2,6 +2,7 @@ #define MXDSSELECTACTION_H #include "mxdsparallelaction.h" +#include "mxstringlist.h" #include "decomp.h" // VTABLE 0x100dcfc8 @@ -25,12 +26,9 @@ class MxDSSelectAction : public MxDSParallelAction return !strcmp(name, MxDSSelectAction::ClassName()) || MxDSParallelAction::IsA(name); } - undefined4 m_unk0x9c; - undefined4 m_unk0xa0; - undefined4 m_unk0xa4; - undefined4 m_unk0xa8; - undefined4 m_unk0xac; - +private: + MxString m_unk0x9c; + MxStringList *m_unk0xac; }; #endif // MXDSSELECTACTION_H diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index ed4c2802..12695f82 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -4,19 +4,24 @@ #include "mxtypes.h" #include "mxcore.h" -template // SIZE 0xc +template class MxListEntry { public: MxListEntry() {} - MxListEntry(T *p_obj, MxListEntry *p_prev) { + MxListEntry(T p_obj, MxListEntry *p_prev) { m_obj = p_obj; m_prev = p_prev; m_next = NULL; } - T *m_obj; + T GetValue() { return this->m_obj; } + + friend class MxList; + friend class MxListCursor; +private: + T m_obj; MxListEntry *m_prev; MxListEntry *m_next; }; @@ -33,12 +38,12 @@ class MxListParent : public MxCore } virtual ~MxListParent() {} - virtual MxS8 Compare(T *, T *) = 0; + virtual MxS8 Compare(T, T) { return 0; }; - static void Destroy(T *) {}; + static void Destroy(T) {}; protected: MxU32 m_count; // +0x8 - void (*m_customDestructor)(T *); // +0xc + void (*m_customDestructor)(T); // +0xc }; // VTABLE 0x100d6368 @@ -54,13 +59,12 @@ class MxList : protected MxListParent virtual ~MxList(); - void Append(T*); + void Append(T); void DeleteAll(); MxU32 GetCount() { return m_count; } - void SetDestroy(void (*p_customDestructor)(T *)) { this->m_customDestructor = p_customDestructor; } + void SetDestroy(void (*p_customDestructor)(T)) { this->m_customDestructor = p_customDestructor; } friend class MxListCursor; - protected: MxListEntry *m_first; // +0x10 MxListEntry *m_last; // +0x14 @@ -79,10 +83,10 @@ class MxListCursor : public MxCore m_match = NULL; } - MxBool Find(T *p_obj); + MxBool Find(T p_obj); void Detach(); - MxBool Next(T*& p_obj); - void SetValue(T *p_obj); + MxBool Next(T& p_obj); + void SetValue(T p_obj); void Head() { m_match = m_list->m_first; } void Reset() { m_match = NULL; } @@ -123,7 +127,7 @@ inline void MxList::DeleteAll() break; MxListEntry *next = t->m_next; - m_customDestructor(t->m_obj); + m_customDestructor(t->GetValue()); delete t; t = next; } @@ -134,7 +138,7 @@ inline void MxList::DeleteAll() } template -inline void MxList::Append(T *p_newobj) +inline void MxList::Append(T p_newobj) { MxListEntry *currentLast = this->m_last; MxListEntry *newEntry = new MxListEntry(p_newobj, currentLast); @@ -169,7 +173,7 @@ inline void MxList::_DeleteEntry(MxListEntry *match) } template -inline MxBool MxListCursor::Find(T *p_obj) +inline MxBool MxListCursor::Find(T p_obj) { for (m_match = m_list->m_first; m_match && m_list->Compare(m_match->m_obj, p_obj); @@ -186,7 +190,7 @@ inline void MxListCursor::Detach() } template -inline MxBool MxListCursor::Next(T*& p_obj) +inline MxBool MxListCursor::Next(T& p_obj) { if (!m_match) m_match = m_list->m_first; @@ -200,7 +204,7 @@ inline MxBool MxListCursor::Next(T*& p_obj) } template -inline void MxListCursor::SetValue(T *p_obj) +inline void MxListCursor::SetValue(T p_obj) { if (m_match) m_match->m_obj = p_obj; diff --git a/LEGO1/mxpresenterlist.h b/LEGO1/mxpresenterlist.h index 71a7f9aa..0ee54a85 100644 --- a/LEGO1/mxpresenterlist.h +++ b/LEGO1/mxpresenterlist.h @@ -8,7 +8,7 @@ class MxPresenter; // Unclear what the purpose of this class is // VTABLE 0x100d62f0 // SIZE 0x18 -class MxPresenterListParent : public MxList +class MxPresenterListParent : public MxList { public: MxPresenterListParent() { @@ -24,15 +24,15 @@ class MxPresenterList : public MxPresenterListParent virtual MxS8 Compare(MxPresenter *, MxPresenter *); // +0x14 }; -typedef MxListCursorChildChild MxPresenterListCursor; +typedef MxListCursorChildChild MxPresenterListCursor; + +// OFFSET: LEGO1 0x1001cd20 TEMPLATE +// MxListParent::Compare // OFFSET: LEGO1 0x1001cd30 TEMPLATE -// MxListParent::Destroy - -// OFFSET: LEGO1 0x1001cdd0 TEMPLATE -// MxListParent::~MxListParent +// MxListParent::Destroy // OFFSET: LEGO1 0x1001ce20 TEMPLATE -// MxList::~MxList +// MxList::~MxList #endif // MXPRESENTERLIST_H diff --git a/LEGO1/mxstringlist.h b/LEGO1/mxstringlist.h new file mode 100644 index 00000000..dbf063f6 --- /dev/null +++ b/LEGO1/mxstringlist.h @@ -0,0 +1,23 @@ +#ifndef MXSTRINGLIST_H +#define MXSTRINGLIST_H + +#include "mxlist.h" +#include "mxstring.h" + +// VTABLE 0x100dd040 +// SIZE 0x18 +class MxStringList : public MxList {}; + +// OFFSET: LEGO1 0x100cb3c0 TEMPLATE +// MxListParent::Compare + +// OFFSET: LEGO1 0x100cb470 TEMPLATE +// MxListParent::Destroy + +// OFFSET: LEGO1 0x100cb4c0 TEMPLATE +// MxList::~MxList + +// OFFSET: LEGO1 0x100cc450 TEMPLATE +// MxListEntry::GetValue + +#endif // MXSTRINGLIST_H From 6480fd90e73aceac0ca47b415f873c71d087acff Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Tue, 3 Oct 2023 04:02:08 -0400 Subject: [PATCH 40/87] Motorcycle initial class structure and ctor (#156) --- LEGO1/motorcycle.cpp | 9 +++++++-- LEGO1/motorcycle.h | 6 +++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/LEGO1/motorcycle.cpp b/LEGO1/motorcycle.cpp index 9b0e0e40..59188fc4 100644 --- a/LEGO1/motorcycle.cpp +++ b/LEGO1/motorcycle.cpp @@ -1,7 +1,12 @@ #include "motorcycle.h" -// OFFSET: LEGO1 0x100357b0 STUB +DECOMP_SIZE_ASSERT(Motorcycle, 0x16c); + +// OFFSET: LEGO1 0x100357b0 Motorcycle::Motorcycle() { - // TODO + this->m_unk13c = 40.0; + this->m_unk150 = 1.75; + this->m_unk148 = 1; + this->m_unk164 = 1.0; } diff --git a/LEGO1/motorcycle.h b/LEGO1/motorcycle.h index 5ba746a8..ee39fe24 100644 --- a/LEGO1/motorcycle.h +++ b/LEGO1/motorcycle.h @@ -1,6 +1,7 @@ #ifndef MOTORCYCLE_H #define MOTORCYCLE_H +#include "decomp.h" #include "islepathactor.h" // VTABLE 0x100d7090 @@ -22,7 +23,10 @@ class Motorcycle : public IslePathActor { return !strcmp(name, Motorcycle::ClassName()) || IslePathActor::IsA(name); } - +private: + undefined m_unk160[4]; + MxFloat m_unk164; + undefined m_unk168[4]; }; #endif // MOTORCYCLE_H From a6f3acf5b7bd34468cdeb6906e6c27cae12c5f9e Mon Sep 17 00:00:00 2001 From: ecumber Date: Tue, 3 Oct 2023 10:53:22 -0700 Subject: [PATCH 41/87] LegoInputManager: some members and functions (#81) * Squashed commit of the following: commit 1fe03a4a787693616c56f59622bcaae8fd53b30b Author: ecumber Date: Thu Jul 6 21:04:15 2023 -0700 data types commit 7c8432f88236c42c17998d51e820b5e219f3c326 Author: ecumber Date: Thu Jul 6 12:39:13 2023 -0700 Destroy commit f60eb3923b24bc87bb31ba783676c6a50d48e9b8 Author: ecumber Date: Thu Jul 6 12:15:33 2023 -0700 compile fix commit e2f78d557f223c2552a046470578d154c29e473b Author: ecumber Date: Tue Jul 4 13:37:33 2023 -0700 Timer functions commit 447e234e6324a5b0958e9e94c5cda53703abada2 Author: ecumber Date: Thu Jul 6 02:40:10 2023 -0700 fix commit 4670fd790b16a15b5797d50bc3cd1f6e2c9e890d Author: ecumber Date: Thu Jul 6 02:39:04 2023 -0700 improvements commit 7f70bce1eefe550fe6bef193e7ee54948af354b6 Author: ecumber Date: Tue Jul 4 03:42:47 2023 -0700 Update legoinputmanager.cpp commit 0d3433a75d2b20a3fff1da8147ce502b279b1e9c Author: ecumber Date: Tue Jul 4 03:38:32 2023 -0700 Add ReleaseDX commit 72d27fd402efb37da1ce8c41a3350df66c99db1d Author: ecumber Date: Tue Jul 4 02:27:12 2023 -0700 Update CMakeLists.txt commit 09626a62f9d2c56a523ca582be95a4dfb29ee188 Author: ecumber Date: Mon Jul 3 13:48:46 2023 -0700 Move to new branch * Squashed commit of the following: commit d9148242a322ec54750c89357a0db2154310907d Author: ecumber Date: Sun Jul 16 23:56:54 2023 -0700 Update legoinputmanager.cpp commit 983d08650eb3df0b9103761b4023a6d3395686b2 Author: ecumber Date: Thu Jul 6 21:04:15 2023 -0700 data types commit 4e8aac36ece6f3d7cfff39432ebc4e731876fb75 Author: ecumber Date: Thu Jul 6 12:39:13 2023 -0700 Destroy commit 907801567a8c93ebd242b25b4aa2b00d38eaedc8 Author: ecumber Date: Thu Jul 6 12:15:33 2023 -0700 compile fix commit 91a5f75e938d796f153cc872e46acef2c342818c Author: ecumber Date: Tue Jul 4 13:37:33 2023 -0700 Timer functions commit e77f08f5358b6cc4ee41583f70281c40b95bea29 Author: ecumber Date: Thu Jul 6 02:40:10 2023 -0700 fix commit 30d204b7734a56b4140a3bf53c9825126a1f80c7 Author: ecumber Date: Thu Jul 6 02:39:04 2023 -0700 improvements commit dd4ff493355796c41a6fb328fda1892c0f1fec0a Author: ecumber Date: Tue Jul 4 03:42:47 2023 -0700 Update legoinputmanager.cpp commit 852658cdbc0e6f792a6a79dfc77df3539ea4a15a Author: ecumber Date: Tue Jul 4 03:38:32 2023 -0700 Add ReleaseDX commit 430d4e100811bc00dc983a9fe78aa1482fb92f7f Author: ecumber Date: Tue Jul 4 02:27:12 2023 -0700 Update CMakeLists.txt commit 6fb94f007613e920b1d64775b7b76cb721482884 Author: ecumber Date: Mon Jul 3 13:48:46 2023 -0700 Move to new branch * Fixes * Remove obsolete stuff * Fixes --------- Co-authored-by: Christian Semmler --- CMakeLists.txt | 4 +- LEGO1/legoinputmanager.cpp | 190 +++++++++++++++++++++++++++++++--- LEGO1/legoinputmanager.h | 53 +++++++--- LEGO1/mxtransitionmanager.cpp | 4 +- 4 files changed, 220 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bcdadc2e..0da82a25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,7 +213,7 @@ if (ISLE_USE_DX5) endif() # Link libraries -target_link_libraries(lego1 PRIVATE ddraw dsound dxguid winmm) +target_link_libraries(lego1 PRIVATE ddraw dsound dxguid dinput winmm) # Make sure filenames are ALL CAPS set_property(TARGET lego1 PROPERTY OUTPUT_NAME LEGO1) @@ -272,4 +272,4 @@ if (MSVC) set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "/incremental:no") set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "/incremental:no /debug") set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "/incremental:no") -endif() +endif() \ No newline at end of file diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index 7c6489ee..149af67b 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -1,25 +1,175 @@ #include "legoinputmanager.h" +#include "legocontrolmanager.h" +#include "legoomni.h" -#include "decomp.h" +#include "mxautolocker.h" -DECOMP_SIZE_ASSERT(LegoInputManager, 0x338); // 0x10059085 +DECOMP_SIZE_ASSERT(LegoInputManager, 0x338); -// OFFSET: LEGO1 0x1005b790 STUB +// OFFSET: LEGO1 0x1005b790 LegoInputManager::LegoInputManager() { - // TODO + m_unk0x5c = NULL; + m_unk0x64 = 0; + m_unk0x60 = 0; + m_unk0x68 = NULL; + m_unk0x80 = 0; + m_timer = 0; + m_unk0x6c = 0; + m_unk0x70 = 0; + m_controlManager = NULL; + m_unk0x81 = 0; + m_unk0x88 = FALSE; + m_directInput = NULL; + m_directInputDevice = NULL; + m_unk0x94 = 0; + m_unk0x195 = 0; + m_joyid = (UINT) -1; + m_joystickIndex = -1; + m_useJoystick = FALSE; + m_unk0x335 = 0; + m_unk0x336 = 0; + m_unk0x74 = 0x19; + m_timeout = 1000; } -// OFFSET: LEGO1 0x1005b8f0 STUB +// OFFSET: LEGO1 0x1005b8b0 STUB +MxResult LegoInputManager::Tickle() +{ + // TODO + return SUCCESS; +} + +// OFFSET: LEGO1 0x1005b8f0 LegoInputManager::~LegoInputManager() { - // TODO + Destroy(); } -// OFFSET: LEGO1 0x1005c740 STUB -void LegoInputManager::QueueEvent(NotificationId id, unsigned char p2, MxLong p3, MxLong p4, unsigned char p5) +// OFFSET: LEGO1 0x1005bfe0 +void LegoInputManager::Destroy() { - // TODO + ReleaseDX(); + + if (m_unk0x5c) + delete m_unk0x5c; + m_unk0x5c = NULL; + + if (m_unk0x68) + delete m_unk0x68; + m_unk0x68 = NULL; + + if (m_controlManager) + delete m_controlManager; +} + +// OFFSET: LEGO1 0x1005c030 +void LegoInputManager::CreateAndAcquireKeyboard(HWND hwnd) +{ + HINSTANCE hinstance = (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE); + HRESULT hresult = DirectInputCreate(hinstance, 0x500, &m_directInput, NULL); // 0x500 for DX5 + + if (hresult == DI_OK) { + HRESULT createdeviceresult = m_directInput->CreateDevice(GUID_SysKeyboard, &m_directInputDevice, NULL); + if (createdeviceresult == DI_OK) { + m_directInputDevice->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); + m_directInputDevice->SetDataFormat(&c_dfDIKeyboard); + m_directInputDevice->Acquire(); + } + } +} + +// OFFSET: LEGO1 0x1005c0a0 +void LegoInputManager::ReleaseDX() +{ + if (m_directInputDevice != NULL) { + m_directInputDevice->Unacquire(); + m_directInputDevice->Release(); + m_directInputDevice = NULL; + } + + if (m_directInput != NULL) { + m_directInput->Release(); + m_directInput = NULL; + } +} + +// OFFSET: LEGO1 0x1005c240 +MxResult LegoInputManager::GetJoystickId() +{ + JOYINFOEX joyinfoex; + + if (m_useJoystick != FALSE) { + MxS32 joyid = m_joystickIndex; + if (joyid >= 0) { + joyinfoex.dwSize = 0x34; + joyinfoex.dwFlags = 0xFF; + + if (joyGetPosEx(joyid, &joyinfoex) == JOYERR_NOERROR && joyGetDevCaps(joyid, &m_joyCaps, 0x194) == JOYERR_NOERROR) { + m_joyid = joyid; + return SUCCESS; + } + } + + for (joyid = JOYSTICKID1; joyid < 16; joyid++) { + joyinfoex.dwSize = 0x34; + joyinfoex.dwFlags = 0xFF; + if (joyGetPosEx(joyid, &joyinfoex) == JOYERR_NOERROR && joyGetDevCaps(joyid, &m_joyCaps, 0x194) == JOYERR_NOERROR) { + m_joyid = joyid; + return SUCCESS; + } + } + } + + return FAILURE; +} + +// OFFSET: LEGO1 0x1005c320 +MxResult LegoInputManager::GetJoystickState(MxU32 *joystick_x, MxU32 *joystick_y, DWORD *buttons_state, MxU32 *pov_position) +{ + if (m_useJoystick != FALSE) { + if (m_joyid < 0 && GetJoystickId() == -1) { + m_useJoystick = FALSE; + return FAILURE; + } + + JOYINFOEX joyinfoex; + joyinfoex.dwSize = 0x34; + joyinfoex.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNBUTTONS; + MxU32 capabilities = m_joyCaps.wCaps; + + if ((capabilities & JOYCAPS_HASPOV) != 0) { + joyinfoex.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNPOV | JOY_RETURNBUTTONS; + + if ((capabilities & JOYCAPS_POVCTS) != 0) + joyinfoex.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNPOV | JOY_RETURNBUTTONS | JOY_RETURNPOVCTS; + } + + MMRESULT mmresult = joyGetPosEx(m_joyid, &joyinfoex); + + if (mmresult == MMSYSERR_NOERROR) { + *buttons_state = joyinfoex.dwButtons; + MxU32 xmin = m_joyCaps.wXmin; + MxU32 ymax = m_joyCaps.wYmax; + MxU32 ymin = m_joyCaps.wYmin; + MxS32 ydiff = ymax - ymin; + *joystick_x = ((joyinfoex.dwXpos - xmin) * 100) / (m_joyCaps.wXmax - xmin); + *joystick_y = ((joyinfoex.dwYpos - m_joyCaps.wYmin) * 100) / ydiff; + if ((m_joyCaps.wCaps & (JOYCAPS_POV4DIR | JOYCAPS_POVCTS)) != 0) { + if (joyinfoex.dwPOV == JOY_POVCENTERED) { + *pov_position = (MxU32) -1; + return SUCCESS; + } + *pov_position = joyinfoex.dwPOV / 100; + return SUCCESS; + } + else { + *pov_position = (MxU32) -1; + return SUCCESS; + } + } + } + return FAILURE; } // OFFSET: LEGO1 0x1005c470 STUB @@ -34,11 +184,25 @@ void LegoInputManager::UnRegister(MxCore *) // TODO } -// OFFSET: LEGO1 0x1005b8b0 STUB -MxResult LegoInputManager::Tickle() +// OFFSET: LEGO1 0x1005c740 STUB +void LegoInputManager::QueueEvent(NotificationId id, unsigned char p2, MxLong p3, MxLong p4, unsigned char p5) { // TODO - - return 0; } +// OFFSET: LEGO1 0x1005cfb0 +void LegoInputManager::SetTimer() +{ + LegoOmni* omni = LegoOmni::GetInstance(); + UINT timer = ::SetTimer(omni->GetWindowHandle(), 1, m_timeout, NULL); + m_timer = timer; +} + +// OFFSET: LEGO1 0x1005cfd0 +void LegoInputManager::KillTimer() +{ + if (m_timer != 0) { + LegoOmni* omni = LegoOmni::GetInstance(); + ::KillTimer(omni->GetWindowHandle(), m_timer); + } +} diff --git a/LEGO1/legoinputmanager.h b/LEGO1/legoinputmanager.h index 56b77445..a44aef32 100644 --- a/LEGO1/legoinputmanager.h +++ b/LEGO1/legoinputmanager.h @@ -3,6 +3,9 @@ #include "decomp.h" #include "mxpresenter.h" +#include "mxlist.h" + +#include enum NotificationId { @@ -14,6 +17,8 @@ enum NotificationId TIMER = 15 }; +class LegoControlManager; + // VTABLE 0x100d8760 // SIZE 0x338 class LegoInputManager : public MxPresenter @@ -28,22 +33,42 @@ class LegoInputManager : public MxPresenter virtual MxResult Tickle() override; // vtable+0x8 - undefined m_pad40[0x48]; + void Destroy(); + void CreateAndAcquireKeyboard(HWND hwnd); + void ReleaseDX(); + MxResult GetJoystickId(); + MxResult GetJoystickState(MxU32 *joystick_x, MxU32 *joystick_y, DWORD *buttons_state, MxU32 *pov_position); + void SetTimer(); + void KillTimer(); - MxBool m_unk88; - undefined m_unk89[0x113]; - - // 0x19C - int m_joystickIndex; - - undefined m_pad1a0[0x194]; - - // 0x334 +//private: + MxCriticalSection m_criticalSection; + MxList *m_unk0x5c; // list or hash table + undefined4 m_unk0x60; + undefined4 m_unk0x64; + MxList *m_unk0x68; // list or hash table + undefined4 m_unk0x6c; + undefined4 m_unk0x70; + undefined4 m_unk0x74; + UINT m_timer; + UINT m_timeout; + undefined m_unk0x80; + undefined m_unk0x81; + LegoControlManager* m_controlManager; + MxBool m_unk0x88; + IDirectInput *m_directInput; + IDirectInputDevice *m_directInputDevice; + undefined m_unk0x94; + undefined4 m_unk0x98; + undefined m_unk0x9c[0xF8]; + undefined m_unk0x194; + MxBool m_unk0x195; + MxS32 m_joyid; + MxS32 m_joystickIndex; + JOYCAPS m_joyCaps; MxBool m_useJoystick; - - undefined m_unk335; - MxBool m_unk336; - undefined m_unk337; + MxBool m_unk0x335; + MxBool m_unk0x336; }; #endif // LEGOINPUTMANAGER_H diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index c5a0cb27..c3dfb035 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -83,8 +83,8 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx tickleManager->RegisterClient(this, p_speed); LegoInputManager *inputManager = InputManager(); - inputManager->m_unk88 = TRUE; - inputManager->m_unk336 = FALSE; + inputManager->m_unk0x88 = TRUE; + inputManager->m_unk0x336 = FALSE; LegoVideoManager *videoManager = VideoManager(); videoManager->SetUnkE4(FALSE); From 6c86503d3596c4f591415ba7eddcd75228af2797 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 3 Oct 2023 14:02:50 -0400 Subject: [PATCH 42/87] Remove UINT cast --- LEGO1/legoinputmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index 149af67b..750c4700 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -24,7 +24,7 @@ LegoInputManager::LegoInputManager() m_directInputDevice = NULL; m_unk0x94 = 0; m_unk0x195 = 0; - m_joyid = (UINT) -1; + m_joyid = -1; m_joystickIndex = -1; m_useJoystick = FALSE; m_unk0x335 = 0; From f9cd17e3dc5bc901b51f3172c19f97ac330fba96 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 3 Oct 2023 14:50:14 -0400 Subject: [PATCH 43/87] Initialize bool members with FALSE --- LEGO1/legoinputmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index 750c4700..3aaaec76 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -27,8 +27,8 @@ LegoInputManager::LegoInputManager() m_joyid = -1; m_joystickIndex = -1; m_useJoystick = FALSE; - m_unk0x335 = 0; - m_unk0x336 = 0; + m_unk0x335 = FALSE; + m_unk0x336 = FALSE; m_unk0x74 = 0x19; m_timeout = 1000; } From 62d953c6c3b03fd233732e8fe4cbf664757a4220 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Tue, 3 Oct 2023 17:38:03 -0400 Subject: [PATCH 44/87] MxLoopingFlcPresenter ctor/half of Init (#158) * MxLoopingFlcPresenter ctor/half of Init * MxLoopingFlcPresenter - finish Init, stub Destroy function, match dtor * Update mxloopingflcpresenter.cpp --------- Co-authored-by: Christian Semmler --- LEGO1/mxloopingflcpresenter.cpp | 18 +++++++++++++----- LEGO1/mxloopingflcpresenter.h | 2 ++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/LEGO1/mxloopingflcpresenter.cpp b/LEGO1/mxloopingflcpresenter.cpp index 041ae6a5..54002246 100644 --- a/LEGO1/mxloopingflcpresenter.cpp +++ b/LEGO1/mxloopingflcpresenter.cpp @@ -4,20 +4,28 @@ DECOMP_SIZE_ASSERT(MxLoopingFlcPresenter, 0x6c); -// OFFSET: LEGO1 0x100b4310 STUB +// OFFSET: LEGO1 0x100b4310 MxLoopingFlcPresenter::MxLoopingFlcPresenter() { - // TODO + Init(); } // OFFSET: LEGO1 0x100b43b0 STUB MxLoopingFlcPresenter::~MxLoopingFlcPresenter() { - // TODO + Destroy(TRUE); } -// OFFSET: LEGO1 0x100b4410 STUB +// OFFSET: LEGO1 0x100b4410 void MxLoopingFlcPresenter::Init() { - // TODO + this->m_unk68 = 0; + this->m_flags &= 0xfd; + this->m_flags &= 0xfb; +} + +// OFFSET: LEGO1 0x100b4432 STUB +void MxLoopingFlcPresenter::Destroy(MxBool p_param) +{ + // TODO } diff --git a/LEGO1/mxloopingflcpresenter.h b/LEGO1/mxloopingflcpresenter.h index 1973c28e..209e2a53 100644 --- a/LEGO1/mxloopingflcpresenter.h +++ b/LEGO1/mxloopingflcpresenter.h @@ -22,6 +22,8 @@ class MxLoopingFlcPresenter : public MxFlcPresenter private: void Init(); + void Destroy(MxBool); + undefined4 m_unk68; }; From 129e8d6373ff8167b4549a855132e1411dc449c1 Mon Sep 17 00:00:00 2001 From: MS Date: Tue, 3 Oct 2023 18:03:10 -0400 Subject: [PATCH 45/87] MxTransitionManager::Dissolve (#155) * MxTransitionManager::Dissolve * Some comments and better names * use refs instead of pointers * slightly improved name for rect * Use MxS32 instead of int --- LEGO1/mxdisplaysurface.h | 1 + LEGO1/mxtransitionmanager.cpp | 101 ++++++++++++++++++++++++++++++++++ LEGO1/mxtransitionmanager.h | 8 ++- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/LEGO1/mxdisplaysurface.h b/LEGO1/mxdisplaysurface.h index 4c2c3866..9bbc44bc 100644 --- a/LEGO1/mxdisplaysurface.h +++ b/LEGO1/mxdisplaysurface.h @@ -33,6 +33,7 @@ class MxDisplaySurface : public MxCore virtual void ReleaseDC(HDC p_hdc); virtual undefined4 vtable44(undefined4, undefined4*, undefined4, undefined4); + inline LPDIRECTDRAWSURFACE GetDirectDrawSurface1() { return this->m_ddSurface1; } inline LPDIRECTDRAWSURFACE GetDirectDrawSurface2() { return this->m_ddSurface2; } private: diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index c3dfb035..61283718 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -4,6 +4,9 @@ DECOMP_SIZE_ASSERT(MxTransitionManager, 0x900); +// 0x100f4378 +RECT g_fullScreenRect = {0, 0, 640, 480}; + // OFFSET: LEGO1 0x1004b8d0 MxTransitionManager::MxTransitionManager() { @@ -38,12 +41,110 @@ MxResult MxTransitionManager::Tickle() return 0; } +// OFFSET: LEGO1 0x1004bc30 STUB +void MxTransitionManager::EndTransition(MxBool) +{ + // TODO +} + +// OFFSET: LEGO1 0x1004bd10 +void MxTransitionManager::Transition_Dissolve() +{ + // If the animation is finished + if (m_animationTimer == 40) { + m_animationTimer = 0; + EndTransition(TRUE); + return; + } + + // If we are starting the animation + if (m_animationTimer == 0) { + // Generate the list of columns in order... + for (MxS32 i = 0; i < 640; i++) { + m_columnOrder[i] = i; + } + + // ...then shuffle the list (to ensure that we hit each column once) + for (i = 0; i < 640; i++) { + MxS32 swap = rand() % 640; + MxU16 t = m_columnOrder[i]; + m_columnOrder[i] = m_columnOrder[swap]; + m_columnOrder[swap] = t; + } + + // For each scanline, pick a random X offset + for (i = 0; i < 480; i++) { + m_randomShift[i] = rand() % 640; + } + } + + // Run one tick of the animation + DDSURFACEDESC ddsd; + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + HRESULT res = m_ddSurface->Lock(NULL, &ddsd, 1, NULL); + if (res == DDERR_SURFACELOST) { + m_ddSurface->Restore(); + res = m_ddSurface->Lock(NULL, &ddsd, 1, NULL); + } + + if (res == DD_OK) { + FUN_1004c4d0(ddsd); + + for (MxS32 i = 0; i < 640; i++) { + // Select 16 columns on each tick + if (m_animationTimer * 16 > m_columnOrder[i]) + continue; + + if (m_animationTimer * 16 + 15 < m_columnOrder[i]) + continue; + + for (MxS32 j = 0; j < 480; j++) { + // Shift the chosen column a different amount at each scanline. + // We use the same shift for that scanline each time. + // By the end, every pixel gets hit. + MxS32 ofs = (m_randomShift[j] + i) % 640; + + // Set the chosen pixel to black + if (ddsd.ddpfPixelFormat.dwRGBBitCount == 8) { + ((MxU8*)ddsd.lpSurface)[j * ddsd.lPitch + ofs] = 0; + } else { + ((MxU16*)ddsd.lpSurface)[j * ddsd.lPitch + ofs] = 0; + } + } + } + + FUN_1004c580(ddsd); + m_ddSurface->Unlock(ddsd.lpSurface); + + if (VideoManager()->GetVideoParam().flags().GetFlipSurfaces()) { + LPDIRECTDRAWSURFACE surf = VideoManager()->GetDisplaySurface()->GetDirectDrawSurface1(); + surf->BltFast(NULL, NULL, m_ddSurface, &g_fullScreenRect, 0x10); + } + + m_animationTimer++; + } +} + // OFFSET: LEGO1 0x1004c470 STUB void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) { // TODO } +// OFFSET: LEGO1 0x1004c4d0 STUB +void MxTransitionManager::FUN_1004c4d0(DDSURFACEDESC &ddsc) +{ + // TODO +} + +// OFFSET: LEGO1 0x1004c580 STUB +void MxTransitionManager::FUN_1004c580(DDSURFACEDESC &ddsc) +{ + // TODO +} + // OFFSET: LEGO1 0x1004baa0 MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 { diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 723366c1..09d3e622 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -89,6 +89,11 @@ class MxTransitionManager : public MxCore MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_unk, MxBool p_playMusicInAnim); private: + void EndTransition(MxBool); + void Transition_Dissolve(); + void FUN_1004c4d0(DDSURFACEDESC &); + void FUN_1004c580(DDSURFACEDESC &); + MxTransitionManagerUnknownSubclass1 *m_unk08; undefined4 m_unk0c; undefined4 m_unk10; @@ -102,7 +107,8 @@ class MxTransitionManager : public MxCore TransitionType m_transitionType; LPDIRECTDRAWSURFACE m_ddSurface; MxU16 m_animationTimer; - undefined m_pad36[0x8c2]; + MxU16 m_columnOrder[640]; // 0x36 + MxU16 m_randomShift[480]; // 0x536 MxULong m_systemTime; MxS32 m_animationSpeed; }; From 6da912e932643b28a0f97d12e7c81692bd60d699 Mon Sep 17 00:00:00 2001 From: MattKC <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:56:16 -0700 Subject: [PATCH 46/87] Implement MxTransitionManager::EndTransition and GetCurrentWorld (#159) * Implement MxTransitionManager::EndTransition and GetCurrentWorld * Match EndTransition --------- Co-authored-by: Christian Semmler --- LEGO1/legoomni.cpp | 6 ++++++ LEGO1/legoomni.h | 7 ++++++- LEGO1/mxtransitionmanager.cpp | 20 +++++++++++++++++--- LEGO1/mxtransitionmanager.h | 6 +++--- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index bbc8258b..929ba556 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -312,3 +312,9 @@ MxBool LegoOmni::vtable40() // FIXME: Stub return 0; } + +// OFFSET: LEGO1 0x100157a0 +LegoWorld *GetCurrentWorld() +{ + return LegoOmni::GetInstance()->GetCurrentWorld(); +} diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 4e772cae..4a5fe6e4 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -75,12 +75,16 @@ class LegoOmni : public MxOmni LegoGameState *GetGameState() { return m_gameState; } LegoNavController *GetNavController() { return m_navController; } MxTransitionManager *GetTransitionManager() { return m_transitionManager; } + LegoWorld *GetCurrentWorld() { return m_currentWorld; } private: int m_unk68; int m_unk6c; LegoInputManager *m_inputMgr; // 0x70 - char m_unk74[0x10]; + undefined4 m_unk74; + undefined4 m_unk78; + LegoWorld *m_currentWorld; + undefined4 m_unk80; LegoNavController *m_navController; // 0x84 Isle* m_isle; // 0x88 char m_unk8c[0x4]; @@ -115,5 +119,6 @@ LegoBuildingManager* BuildingManager(); Isle* GetIsle(); LegoPlantManager* PlantManager(); MxBool KeyValueStringParse(char *, const char *, const char *); +LegoWorld *GetCurrentWorld(); #endif // LEGOOMNI_H diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 61283718..4581abe9 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -41,10 +41,24 @@ MxResult MxTransitionManager::Tickle() return 0; } -// OFFSET: LEGO1 0x1004bc30 STUB -void MxTransitionManager::EndTransition(MxBool) +// OFFSET: LEGO1 0x1004bc30 +void MxTransitionManager::EndTransition(MxBool p_notifyWorld) { - // TODO + if (m_transitionType != NOT_TRANSITIONING) { + m_transitionType = NOT_TRANSITIONING; + + m_unk20.bit0 = FALSE; + + TickleManager()->UnregisterClient(this); + + if (p_notifyWorld) { + LegoWorld *world = GetCurrentWorld(); + + if (world) { + world->Notify(MxParam(0x18, this)); + } + } + } } // OFFSET: LEGO1 0x1004bd10 diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 09d3e622..c66e7380 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -89,7 +89,7 @@ class MxTransitionManager : public MxCore MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_unk, MxBool p_playMusicInAnim); private: - void EndTransition(MxBool); + void EndTransition(MxBool p_notifyWorld); void Transition_Dissolve(); void FUN_1004c4d0(DDSURFACEDESC &); void FUN_1004c580(DDSURFACEDESC &); @@ -109,8 +109,8 @@ class MxTransitionManager : public MxCore MxU16 m_animationTimer; MxU16 m_columnOrder[640]; // 0x36 MxU16 m_randomShift[480]; // 0x536 - MxULong m_systemTime; - MxS32 m_animationSpeed; + MxULong m_systemTime; // 0x8f8 + MxS32 m_animationSpeed; // 0x8fc }; #endif // MXTRANSITIONMANAGER_H From 7c7311ea5e3ccc2f725f677b0f6646c3cc9e07c3 Mon Sep 17 00:00:00 2001 From: Regan Green Date: Wed, 4 Oct 2023 09:43:34 -0400 Subject: [PATCH 47/87] Implement MxTransitionManager::SubmitCopyRect (#160) * Implement MxTransitionManager::SubmitCopyRect * MxTransitionManager::SubmitCopyRect Amendments * Fix MxTransitionManager::EndTransition * Fix MxDSAction::SetLoopCount --- LEGO1/mxdsaction.h | 11 ++-- LEGO1/mxpresenter.h | 1 + LEGO1/mxtransitionmanager.cpp | 96 ++++++++++++++++++++++------------- LEGO1/mxtransitionmanager.h | 64 +++-------------------- 4 files changed, 77 insertions(+), 95 deletions(-) diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 01dfcf2c..eb7afb99 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -18,6 +18,7 @@ class MxDSAction : public MxDSObject Flag_Bit3 = 0x04, Flag_Enabled = 0x20, Flag_Parsed = 0x80, + Flag_Bit9 = 0x200, }; __declspec(dllexport) MxDSAction(); @@ -52,16 +53,18 @@ class MxDSAction : public MxDSObject void AppendData(MxU16 p_extraLength, const char *p_extraData); - inline MxU32 GetFlags() { return this->m_flags; } - inline void SetFlags(MxU32 m_flags) { this->m_flags = m_flags; } + inline MxU32 GetFlags() { return m_flags; } + inline void SetFlags(MxU32 p_flags) { m_flags = p_flags; } inline char *GetExtraData() { return m_extraData; } inline MxU16 GetExtraLength() const { return m_extraLength; } inline MxLong GetStartTime() const { return m_startTime; } + inline MxS32 GetLoopCount() { return m_loopCount; } + inline void SetLoopCount(MxS32 p_loopCount) { m_loopCount = p_loopCount; } inline const MxVector3Data &GetLocation() const { return m_location; } inline void SetOmni(MxOmni *p_omni) { m_omni = p_omni; } - inline MxBool IsLooping() const { return this->m_flags & Flag_Looping; } - inline MxBool IsBit3() const { return this->m_flags & Flag_Bit3; } + inline MxBool IsLooping() const { return m_flags & Flag_Looping; } + inline MxBool IsBit3() const { return m_flags & Flag_Bit3; } private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 1537d2d3..c0757665 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -69,6 +69,7 @@ class MxPresenter : public MxCore MxBool IsEnabled(); inline MxS32 GetDisplayZ() { return this->m_displayZ; } + inline MxDSAction *GetAction() { return this->m_action; } protected: __declspec(dllexport) void Init(); diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 4581abe9..c3de0ff8 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -13,9 +13,9 @@ MxTransitionManager::MxTransitionManager() m_animationTimer = 0; m_transitionType = NOT_TRANSITIONING; m_ddSurface = NULL; - m_unk08 = 0; - m_unk1c = 0; - m_unk20.bit0 = FALSE; + m_waitIndicator = NULL; + m_copyBuffer = NULL; + m_copyFlags.bit0 = FALSE; m_unk28.bit0 = FALSE; m_unk24 = 0; } @@ -23,11 +23,11 @@ MxTransitionManager::MxTransitionManager() // OFFSET: LEGO1 0x1004ba00 MxTransitionManager::~MxTransitionManager() { - free(m_unk1c); + free(m_copyBuffer); - if (m_unk08 != NULL) { - delete m_unk08->m_unk1c; - delete m_unk08; + if (m_waitIndicator != NULL) { + delete m_waitIndicator->GetAction(); + delete m_waitIndicator; } TickleManager()->UnregisterClient(this); @@ -47,7 +47,7 @@ void MxTransitionManager::EndTransition(MxBool p_notifyWorld) if (m_transitionType != NOT_TRANSITIONING) { m_transitionType = NOT_TRANSITIONING; - m_unk20.bit0 = FALSE; + m_copyFlags.bit0 = FALSE; TickleManager()->UnregisterClient(this); @@ -104,7 +104,7 @@ void MxTransitionManager::Transition_Dissolve() } if (res == DD_OK) { - FUN_1004c4d0(ddsd); + SubmitCopyRect(ddsd); for (MxS32 i = 0; i < 640; i++) { // Select 16 columns on each tick @@ -129,7 +129,7 @@ void MxTransitionManager::Transition_Dissolve() } } - FUN_1004c580(ddsd); + SetupCopyRect(ddsd); m_ddSurface->Unlock(ddsd.lpSurface); if (VideoManager()->GetVideoParam().flags().GetFlipSurfaces()) { @@ -141,24 +141,6 @@ void MxTransitionManager::Transition_Dissolve() } } -// OFFSET: LEGO1 0x1004c470 STUB -void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) -{ - // TODO -} - -// OFFSET: LEGO1 0x1004c4d0 STUB -void MxTransitionManager::FUN_1004c4d0(DDSURFACEDESC &ddsc) -{ - // TODO -} - -// OFFSET: LEGO1 0x1004c580 STUB -void MxTransitionManager::FUN_1004c580(DDSURFACEDESC &ddsc) -{ - // TODO -} - // OFFSET: LEGO1 0x1004baa0 MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 { @@ -169,7 +151,7 @@ MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 // OFFSET: LEGO1 0x1004bb70 MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, MxS32 p_speed, - MxBool p_unk, MxBool p_playMusicInAnim) + MxBool p_doCopy, MxBool p_playMusicInAnim) { if (this->m_transitionType == NOT_TRANSITIONING) { if (!p_playMusicInAnim) { @@ -179,14 +161,14 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx this->m_transitionType = p_animationType; - m_unk20.bit0 = p_unk; + m_copyFlags.bit0 = p_doCopy; - if (m_unk20.bit0 && m_unk08 != NULL) { - m_unk08->vtable54(1); + if (m_copyFlags.bit0 && m_waitIndicator != NULL) { + m_waitIndicator->Enable(TRUE); - MxTransitionManagerUnknownSubclass2 *iVar2 = m_unk08->m_unk1c; - iVar2->m_unk3c = 10000; - iVar2->m_unk30 |= 0x200; + MxDSAction *action = m_waitIndicator->GetAction(); + action->SetLoopCount(10000); + action->SetFlags(action->GetFlags() | MxDSAction::Flag_Bit9); } MxU32 time = timeGetTime(); @@ -209,3 +191,47 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx } return FAILURE; } + +// OFFSET: LEGO1 0x1004c470 STUB +void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) +{ + // TODO +} + +// OFFSET: LEGO1 0x1004c4d0 +void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) +{ + // Check if the copy rect is setup + if (m_copyFlags.bit0 == FALSE || m_waitIndicator == NULL || m_copyBuffer == NULL) { + return; + } + + // Copy the copy rect onto the surface + char *dst; + + DWORD bytesPerPixel = ddsc.ddpfPixelFormat.dwRGBBitCount / 8; + + const char *src = (const char *)m_copyBuffer; + + LONG copyPitch; + copyPitch = ((m_copyRect.right - m_copyRect.left) + 1) * bytesPerPixel; + + LONG y; + dst = (char *)ddsc.lpSurface + (ddsc.lPitch * m_copyRect.top) + (bytesPerPixel * m_copyRect.left); + + for (y = 0; y < m_copyRect.bottom - m_copyRect.top + 1; ++y) { + memcpy(dst, src, copyPitch); + src += copyPitch; + dst += ddsc.lPitch; + } + + // Free the copy buffer + free(m_copyBuffer); + m_copyBuffer = NULL; +} + +// OFFSET: LEGO1 0x1004c580 STUB +void MxTransitionManager::SetupCopyRect(DDSURFACEDESC &ddsc) +{ + // TODO +} diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index c66e7380..6cbc608b 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -5,52 +5,6 @@ #include "mxvideopresenter.h" #include "legoomni.h" -class MxTransitionManagerUnknownSubclass2 -{ -public: - virtual ~MxTransitionManagerUnknownSubclass2(){} - - undefined m_unk04[0x2c]; - undefined4 m_unk30; - undefined4 m_unk34; - undefined4 m_unk38; - undefined4 m_unk3c; - -}; - -// TODO: Don't know what this is yet -class MxTransitionManagerUnknownSubclass1 -{ -public: - virtual ~MxTransitionManagerUnknownSubclass1(){} - - virtual void vtable04(); - virtual void vtable08(); - virtual void vtable0c(); - virtual void vtable10(); - virtual void vtable14(); - virtual void vtable18(); - virtual void vtable1c(); - virtual void vtable20(); - virtual void vtable24(); - virtual void vtable28(); - virtual void vtable2c(); - virtual void vtable30(); - virtual void vtable34(); - virtual void vtable38(); - virtual void vtable3c(); - virtual void vtable40(); - virtual void vtable44(); - virtual void vtable48(); - virtual void vtable4c(); - virtual void vtable50(); - virtual void vtable54(undefined4 p_unk1); - - undefined m_unk04[0x18]; - MxTransitionManagerUnknownSubclass2 *m_unk1c; - -}; - // VTABLE 0x100d7ea0 class MxTransitionManager : public MxCore { @@ -86,21 +40,19 @@ class MxTransitionManager : public MxCore BROKEN // Unknown what this is supposed to be, it locks the game up }; - MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_unk, MxBool p_playMusicInAnim); + MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim); private: void EndTransition(MxBool p_notifyWorld); void Transition_Dissolve(); - void FUN_1004c4d0(DDSURFACEDESC &); - void FUN_1004c580(DDSURFACEDESC &); + void SubmitCopyRect(DDSURFACEDESC &); + void SetupCopyRect(DDSURFACEDESC &); - MxTransitionManagerUnknownSubclass1 *m_unk08; - undefined4 m_unk0c; - undefined4 m_unk10; - undefined4 m_unk14; - undefined4 m_unk18; - void *m_unk1c; - flag_bitfield m_unk20; + MxVideoPresenter *m_waitIndicator; + RECT m_copyRect; + void *m_copyBuffer; + + flag_bitfield m_copyFlags; undefined4 m_unk24; flag_bitfield m_unk28; From 5125314755fd4d558a337446228e025869196b9b Mon Sep 17 00:00:00 2001 From: MS Date: Wed, 4 Oct 2023 11:48:25 -0400 Subject: [PATCH 48/87] Wipe transition (#161) --- LEGO1/mxtransitionmanager.cpp | 39 +++++++++++++++++++++++++++++++++++ LEGO1/mxtransitionmanager.h | 1 + 2 files changed, 40 insertions(+) diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index c3de0ff8..f66f4bae 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -192,6 +192,45 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx return FAILURE; } +// OFFSET: LEGO1 0x1004c170 +void MxTransitionManager::Transition_Wipe() +{ + // If the animation is finished + if (m_animationTimer == 240) { + m_animationTimer = 0; + EndTransition(TRUE); + return; + } + + DDSURFACEDESC ddsd; + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + HRESULT res = m_ddSurface->Lock(NULL, &ddsd, 1, NULL); + if (res == DDERR_SURFACELOST) { + m_ddSurface->Restore(); + res = m_ddSurface->Lock(NULL, &ddsd, 1, NULL); + } + + if (res == DD_OK) { + SubmitCopyRect(ddsd); + + // For each of the 240 animation ticks, blank out two scanlines + // starting at the top of the screen. + // (dwRGBBitCount / 8) will tell how many bytes are used per pixel. + MxU8 *line = (MxU8*)ddsd.lpSurface + 2*ddsd.lPitch*m_animationTimer; + memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8); + + line += ddsd.lPitch; + memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8); + + SetupCopyRect(ddsd); + m_ddSurface->Unlock(ddsd.lpSurface); + + m_animationTimer++; + } +} + // OFFSET: LEGO1 0x1004c470 STUB void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) { diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 6cbc608b..cc5bd678 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -45,6 +45,7 @@ class MxTransitionManager : public MxCore private: void EndTransition(MxBool p_notifyWorld); void Transition_Dissolve(); + void Transition_Wipe(); void SubmitCopyRect(DDSURFACEDESC &); void SetupCopyRect(DDSURFACEDESC &); From 6916aa49e3298153d5442851910191bc2c9a7cba Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Wed, 4 Oct 2023 13:30:37 -0400 Subject: [PATCH 49/87] MxLoopingSmkPresenter - dtor, Init, stub Destroy (#162) --- LEGO1/mxloopingsmkpresenter.cpp | 16 ++++++++++++---- LEGO1/mxloopingsmkpresenter.h | 2 ++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/LEGO1/mxloopingsmkpresenter.cpp b/LEGO1/mxloopingsmkpresenter.cpp index da9223df..f51e2750 100644 --- a/LEGO1/mxloopingsmkpresenter.cpp +++ b/LEGO1/mxloopingsmkpresenter.cpp @@ -10,14 +10,22 @@ MxLoopingSmkPresenter::MxLoopingSmkPresenter() Init(); } -// OFFSET: LEGO1 0x100b4950 STUB +// OFFSET: LEGO1 0x100b4950 MxLoopingSmkPresenter::~MxLoopingSmkPresenter() { - // TODO + Destroy(TRUE); } -// OFFSET: LEGO1 0x100b49b0 STUB +// OFFSET: LEGO1 0x100b49b0 void MxLoopingSmkPresenter::Init() { - // TODO + this->m_unk720 = 0; + this->m_flags &= 0xfd; + this->m_flags &= 0xfb; +} + +// OFFSET: LEGO1 0x100b49d0 STUB +void MxLoopingSmkPresenter::Destroy(MxBool p_bool) +{ + // TODO - theres a chain of destroy and free function calls here (FUN_100b4300 -> FUN_100b3900 -> FUN_100c5d40 -> function at 0x100b27b0) } diff --git a/LEGO1/mxloopingsmkpresenter.h b/LEGO1/mxloopingsmkpresenter.h index 8ca18d20..ae9cfa05 100644 --- a/LEGO1/mxloopingsmkpresenter.h +++ b/LEGO1/mxloopingsmkpresenter.h @@ -22,6 +22,8 @@ class MxLoopingSmkPresenter : public MxSmkPresenter private: void Init(); + void Destroy(MxBool); + undefined4 m_unk720; }; From 2d45914ddf43843febc110c37c40f03143f7c569 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Thu, 5 Oct 2023 03:47:37 -0400 Subject: [PATCH 50/87] MxSoundManager: dtor, destroy, update types (#164) * MxSoundManager: dtor, destroy, update types Also make MxThread's destructor public * Minor adjustments --------- Co-authored-by: Christian Semmler --- LEGO1/mxsoundmanager.cpp | 34 +++++++++++++++++++++++++++++++--- LEGO1/mxsoundmanager.h | 11 ++++++++--- LEGO1/mxthread.h | 2 ++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/LEGO1/mxsoundmanager.cpp b/LEGO1/mxsoundmanager.cpp index 275d0514..16d504ce 100644 --- a/LEGO1/mxsoundmanager.cpp +++ b/LEGO1/mxsoundmanager.cpp @@ -1,21 +1,49 @@ #include "mxsoundmanager.h" +#include "mxomni.h" + +DECOMP_SIZE_ASSERT(MxSoundManager, 0x3c); + // OFFSET: LEGO1 0x100ae740 MxSoundManager::MxSoundManager() { Init(); } -// OFFSET: LEGO1 0x100ae7d0 STUB +// OFFSET: LEGO1 0x100ae7d0 MxSoundManager::~MxSoundManager() { - // TODO + Destroy(TRUE); } // OFFSET: LEGO1 0x100ae830 void MxSoundManager::Init() { m_unk30 = 0; - m_unk34 = 0; + m_dsBuffer = NULL; } +// OFFSET: LEGO1 0x100ae840 +void MxSoundManager::Destroy(MxBool p_param) +{ + if (this->m_thread) { + this->m_thread->Terminate(); + delete this->m_thread; + } + else { + TickleManager()->UnregisterClient(this); + } + + this->m_criticalSection.Enter(); + + if (this->m_dsBuffer) { + this->m_dsBuffer->Release(); + } + + Init(); + this->m_criticalSection.Leave(); + + if (!p_param) { + MxAudioManager::Destroy(); + } +} \ No newline at end of file diff --git a/LEGO1/mxsoundmanager.h b/LEGO1/mxsoundmanager.h index 06dc9d5f..d41c6fdb 100644 --- a/LEGO1/mxsoundmanager.h +++ b/LEGO1/mxsoundmanager.h @@ -1,11 +1,13 @@ #ifndef MXSOUNDMANAGER_H #define MXSOUNDMANAGER_H +#include "decomp.h" #include "mxaudiomanager.h" +#include + // VTABLE 0x100dc128 // SIZE 0x3c -// Base vtables are: MxCore -> 0x100dc6b0 -> MxAudioManager -> MxSoundManager class MxSoundManager : public MxAudioManager { public: @@ -14,8 +16,11 @@ class MxSoundManager : public MxAudioManager private: void Init(); - int m_unk30; - int m_unk34; + void Destroy(MxBool); + + undefined4 m_unk30; + LPDIRECTSOUNDBUFFER m_dsBuffer; // 0x34 + undefined m_unk35[4]; }; #endif // MXSOUNDMANAGER_H diff --git a/LEGO1/mxthread.h b/LEGO1/mxthread.h index 4537dc14..758205d7 100644 --- a/LEGO1/mxthread.h +++ b/LEGO1/mxthread.h @@ -24,6 +24,8 @@ class MxThread protected: MxThread(); + +public: virtual ~MxThread(); private: From c46bc985c272ceeff9d6fee2ff88a3f24ef0154b Mon Sep 17 00:00:00 2001 From: Regan Green Date: Thu, 5 Oct 2023 06:31:20 -0400 Subject: [PATCH 51/87] Implement MxTransitionManager SetWaitIndicator and SetupCopyRect (#165) * Implement MxTransitionManager SetWaitIndicator and SetupCopyRect * More accurate SetupCopyRect * Add MxDSAction::Flag_Bit5 * SetupCopyRect PR Amends * Correct braces formatting * Stub MxVideoPresenter::Destroy --- LEGO1/mxdisplaysurface.cpp | 4 +- LEGO1/mxdisplaysurface.h | 4 +- LEGO1/mxdsaction.h | 1 + LEGO1/mxmediapresenter.cpp | 6 ++ LEGO1/mxmediapresenter.h | 2 + LEGO1/mxpresenter.h | 2 + LEGO1/mxtransitionmanager.cpp | 101 +++++++++++++++++++++++++++++----- LEGO1/mxtransitionmanager.h | 6 +- LEGO1/mxvideopresenter.cpp | 86 +++++++++++++++++++++++++++++ LEGO1/mxvideopresenter.h | 17 ++++++ 10 files changed, 208 insertions(+), 21 deletions(-) diff --git a/LEGO1/mxdisplaysurface.cpp b/LEGO1/mxdisplaysurface.cpp index 4f02aeb6..619f5eef 100644 --- a/LEGO1/mxdisplaysurface.cpp +++ b/LEGO1/mxdisplaysurface.cpp @@ -174,7 +174,7 @@ void MxDisplaySurface::SetPalette(MxPalette *p_palette) } // OFFSET: LEGO1 0x100bc200 STUB -void MxDisplaySurface::vtable24(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4) +void MxDisplaySurface::vtable24(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4) { } @@ -186,7 +186,7 @@ MxBool MxDisplaySurface::vtable28(undefined4, undefined4, undefined4, undefined4 } // OFFSET: LEGO1 0x100bc630 STUB -MxBool MxDisplaySurface::vtable2c(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool) +MxBool MxDisplaySurface::vtable2c(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool) { return 0; } diff --git a/LEGO1/mxdisplaysurface.h b/LEGO1/mxdisplaysurface.h index 9bbc44bc..af484716 100644 --- a/LEGO1/mxdisplaysurface.h +++ b/LEGO1/mxdisplaysurface.h @@ -23,9 +23,9 @@ class MxDisplaySurface : public MxCore virtual MxResult Create(MxVideoParam &p_videoParam); virtual void Clear(); virtual void SetPalette(MxPalette *p_palette); - virtual void vtable24(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); + virtual void vtable24(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual MxBool vtable28(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); - virtual MxBool vtable2c(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); + virtual MxBool vtable2c(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); virtual MxBool vtable30(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); virtual undefined4 vtable34(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual void Display(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index eb7afb99..9881f3e2 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -16,6 +16,7 @@ class MxDSAction : public MxDSObject { Flag_Looping = 0x01, Flag_Bit3 = 0x04, + Flag_Bit5 = 0x10, Flag_Enabled = 0x20, Flag_Parsed = 0x80, Flag_Bit9 = 0x200, diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index 6a59a0ec..f36ecbdc 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -17,3 +17,9 @@ void MxMediaPresenter::Init() this->m_unk48 = NULL; this->m_unk4c = NULL; } + +// OFFSET: LEGO1 0x100b5f10 STUB +void MxMediaPresenter::VTable0x58() +{ + // TODO +} diff --git a/LEGO1/mxmediapresenter.h b/LEGO1/mxmediapresenter.h index 741ab49f..824dd399 100644 --- a/LEGO1/mxmediapresenter.h +++ b/LEGO1/mxmediapresenter.h @@ -29,6 +29,8 @@ class MxMediaPresenter : public MxPresenter return !strcmp(name, MxMediaPresenter::ClassName()) || MxPresenter::IsA(name); } + virtual void VTable0x58(); // vtable+0x58 + undefined4 m_unk40; undefined4 m_unk44; undefined4 m_unk48; diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index c0757665..81ea14ad 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -68,6 +68,8 @@ class MxPresenter : public MxCore MxBool IsEnabled(); + inline MxS32 GetCurrentTickleState() { return this->m_currentTickleState; } + inline MxPoint32 GetLocation() { return this->m_location; } inline MxS32 GetDisplayZ() { return this->m_displayZ; } inline MxDSAction *GetAction() { return this->m_action; } diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index f66f4bae..efb90604 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -104,7 +104,7 @@ void MxTransitionManager::Transition_Dissolve() } if (res == DD_OK) { - SubmitCopyRect(ddsd); + SubmitCopyRect(&ddsd); for (MxS32 i = 0; i < 640; i++) { // Select 16 columns on each tick @@ -129,7 +129,7 @@ void MxTransitionManager::Transition_Dissolve() } } - SetupCopyRect(ddsd); + SetupCopyRect(&ddsd); m_ddSurface->Unlock(ddsd.lpSurface); if (VideoManager()->GetVideoParam().flags().GetFlipSurfaces()) { @@ -213,7 +213,7 @@ void MxTransitionManager::Transition_Wipe() } if (res == DD_OK) { - SubmitCopyRect(ddsd); + SubmitCopyRect(&ddsd); // For each of the 240 animation ticks, blank out two scanlines // starting at the top of the screen. @@ -224,21 +224,42 @@ void MxTransitionManager::Transition_Wipe() line += ddsd.lPitch; memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8); - SetupCopyRect(ddsd); + SetupCopyRect(&ddsd); m_ddSurface->Unlock(ddsd.lpSurface); m_animationTimer++; } } -// OFFSET: LEGO1 0x1004c470 STUB -void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) +// OFFSET: LEGO1 0x1004c470 +void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *p_waitIndicator) { - // TODO + // End current wait indicator + if (m_waitIndicator != NULL) { + m_waitIndicator->GetAction()->SetFlags(m_waitIndicator->GetAction()->GetFlags() & ~MxDSAction::Flag_Parsed); + m_waitIndicator->EndAction(); + m_waitIndicator = NULL; + } + + // Check if we were given a new wait indicator + if (p_waitIndicator != NULL) { + // Setup the new wait indicator + m_waitIndicator = p_waitIndicator; + + LegoVideoManager *videoManager = VideoManager(); + videoManager->RemovePresenter(*m_waitIndicator); + + if (m_waitIndicator->GetCurrentTickleState() < MxPresenter::TickleState_Streaming) { + m_waitIndicator->Tickle(); + } + } else { + // Disable copy rect + m_copyFlags.bit0 = FALSE; + } } // OFFSET: LEGO1 0x1004c4d0 -void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) +void MxTransitionManager::SubmitCopyRect(LPDDSURFACEDESC ddsc) { // Check if the copy rect is setup if (m_copyFlags.bit0 == FALSE || m_waitIndicator == NULL || m_copyBuffer == NULL) { @@ -248,7 +269,7 @@ void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) // Copy the copy rect onto the surface char *dst; - DWORD bytesPerPixel = ddsc.ddpfPixelFormat.dwRGBBitCount / 8; + DWORD bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; const char *src = (const char *)m_copyBuffer; @@ -256,12 +277,12 @@ void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) copyPitch = ((m_copyRect.right - m_copyRect.left) + 1) * bytesPerPixel; LONG y; - dst = (char *)ddsc.lpSurface + (ddsc.lPitch * m_copyRect.top) + (bytesPerPixel * m_copyRect.left); + dst = (char *)ddsc->lpSurface + (ddsc->lPitch * m_copyRect.top) + (bytesPerPixel * m_copyRect.left); for (y = 0; y < m_copyRect.bottom - m_copyRect.top + 1; ++y) { memcpy(dst, src, copyPitch); src += copyPitch; - dst += ddsc.lPitch; + dst += ddsc->lPitch; } // Free the copy buffer @@ -269,8 +290,60 @@ void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) m_copyBuffer = NULL; } -// OFFSET: LEGO1 0x1004c580 STUB -void MxTransitionManager::SetupCopyRect(DDSURFACEDESC &ddsc) +// OFFSET: LEGO1 0x1004c580 +void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc) { - // TODO + // Check if the copy rect is setup + if (m_copyFlags.bit0 == FALSE || m_waitIndicator == NULL) { + return; + } + + // Tickle wait indicator + m_waitIndicator->Tickle(); + + // Check if wait indicator has started + if (m_waitIndicator->GetCurrentTickleState() >= MxPresenter::TickleState_Streaming) { + // Setup the copy rect + DWORD copyPitch = (ddsc->ddpfPixelFormat.dwRGBBitCount / 8) * (m_copyRect.right - m_copyRect.left + 1); // This uses m_copyRect, seemingly erroneously + DWORD bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; + + m_copyRect.left = m_waitIndicator->GetLocation().m_x; + m_copyRect.top = m_waitIndicator->GetLocation().m_y; + + MxS32 height = m_waitIndicator->GetHeight(); + MxS32 width = m_waitIndicator->GetWidth(); + + m_copyRect.right = m_copyRect.left + width - 1; + m_copyRect.bottom = m_copyRect.top + height - 1; + + // Allocate the copy buffer + const char *src = (const char*)ddsc->lpSurface + m_copyRect.top * ddsc->lPitch + bytesPerPixel * m_copyRect.left; + + m_copyBuffer = malloc(bytesPerPixel * width * height); + if (!m_copyBuffer) + return; + + // Copy into the copy buffer + char *dst = (char*)m_copyBuffer; + + for (MxS32 i = 0; i < (m_copyRect.bottom - m_copyRect.top + 1); i++) + { + memcpy(dst, src, copyPitch); + src += ddsc->lPitch; + dst += copyPitch; + } + } + + // Setup display surface + if ((m_waitIndicator->GetAction()->GetFlags() & MxDSAction::Flag_Bit5) != 0) + { + MxDisplaySurface *displaySurface = VideoManager()->GetDisplaySurface(); + MxBool unkbool = FALSE; + displaySurface->vtable2c(ddsc, m_waitIndicator->m_unk50, 0, 0, m_waitIndicator->GetLocation().m_x, m_waitIndicator->GetLocation().m_y, m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight(), unkbool); + } + else + { + MxDisplaySurface *displaySurface = VideoManager()->GetDisplaySurface(); + displaySurface->vtable24(ddsc, m_waitIndicator->m_unk50, 0, 0, m_waitIndicator->GetLocation().m_x, m_waitIndicator->GetLocation().m_y, m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight()); + } } diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index cc5bd678..4ed82229 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -12,7 +12,7 @@ class MxTransitionManager : public MxCore MxTransitionManager(); virtual ~MxTransitionManager() override; // vtable+0x0 - __declspec(dllexport) void SetWaitIndicator(MxVideoPresenter *videoPresenter); + __declspec(dllexport) void SetWaitIndicator(MxVideoPresenter *p_waitIndicator); virtual MxResult Tickle(); // vtable+0x8 @@ -46,8 +46,8 @@ class MxTransitionManager : public MxCore void EndTransition(MxBool p_notifyWorld); void Transition_Dissolve(); void Transition_Wipe(); - void SubmitCopyRect(DDSURFACEDESC &); - void SetupCopyRect(DDSURFACEDESC &); + void SubmitCopyRect(LPDDSURFACEDESC ddsc); + void SetupCopyRect(LPDDSURFACEDESC ddsc); MxVideoPresenter *m_waitIndicator; RECT m_copyRect; diff --git a/LEGO1/mxvideopresenter.cpp b/LEGO1/mxvideopresenter.cpp index 4e47e4a4..fe83a2dc 100644 --- a/LEGO1/mxvideopresenter.cpp +++ b/LEGO1/mxvideopresenter.cpp @@ -2,8 +2,94 @@ DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64); +// OFFSET: LEGO1 0x1000c700 STUB +void MxVideoPresenter::VTable0x5c() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c710 STUB +void MxVideoPresenter::VTable0x60() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c720 STUB +void MxVideoPresenter::VTable0x68() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c730 STUB +void MxVideoPresenter::VTable0x70() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c740 +MxVideoPresenter::~MxVideoPresenter() +{ + Destroy(TRUE); +} + +// OFFSET: LEGO1 0x1000c7a0 STUB +void MxVideoPresenter::InitVirtual() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c7b0 STUB +void MxVideoPresenter::VTable0x78() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c7c0 STUB +void MxVideoPresenter::VTable0x7c() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c7e0 STUB +MxS32 MxVideoPresenter::GetWidth() +{ + // TODO + return 0; +} + +// OFFSET: LEGO1 0x1000c800 STUB +MxS32 MxVideoPresenter::GetHeight() +{ + // TODO + return 0; +} + // OFFSET: LEGO1 0x100b2760 STUB void MxVideoPresenter::Init() { // TODO } + +// OFFSET: LEGO1 0x100b27b0 STUB +void MxVideoPresenter::Destroy(MxBool) +{ + // TODO +} + +// OFFSET: LEGO1 0x100b28b0 STUB +void MxVideoPresenter::VTable0x64() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b2a70 STUB +void MxVideoPresenter::VTable0x6c() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b3300 STUB +void MxVideoPresenter::VTable0x74() +{ + // TODO +} diff --git a/LEGO1/mxvideopresenter.h b/LEGO1/mxvideopresenter.h index bc5fac5c..84822f71 100644 --- a/LEGO1/mxvideopresenter.h +++ b/LEGO1/mxvideopresenter.h @@ -13,6 +13,8 @@ class MxVideoPresenter : public MxMediaPresenter Init(); } + virtual ~MxVideoPresenter() override; // vtable+0x0 + // OFFSET: LEGO1 0x1000c820 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -27,6 +29,21 @@ class MxVideoPresenter : public MxMediaPresenter } void Init(); + void Destroy(MxBool); + + virtual void InitVirtual() override; // vtable+0x38 + + virtual void VTable0x5c(); // vtable+0x5c + virtual void VTable0x60(); // vtable+0x60 + virtual void VTable0x64(); // vtable+0x64 + virtual void VTable0x68(); // vtable+0x68 + virtual void VTable0x6c(); // vtable+0x6c + virtual void VTable0x70(); // vtable+0x70 + virtual void VTable0x74(); // vtable+0x74 + virtual void VTable0x78(); // vtable+0x78 + virtual void VTable0x7c(); // vtable+0x7c + virtual MxS32 GetWidth(); // vtable+0x80 + virtual MxS32 GetHeight(); // vtable+0x84 undefined4 m_unk50; undefined4 m_unk54; From e767d6524e73d5f24863ebf70923b1248c0d51b9 Mon Sep 17 00:00:00 2001 From: vMidz <147055059+vMidz@users.noreply.github.com> Date: Thu, 5 Oct 2023 23:06:11 +0300 Subject: [PATCH 52/87] implement MxMIDIManager (#167) * added MxMIDIManager * implement MxMIDIManager implement MxMIDIManager implement MxAudioManager::GetVolume implement MxAudioManager::SetVolume * added override + small changes --- CMakeLists.txt | 3 +- LEGO1/mxaudiomanager.cpp | 16 +++- LEGO1/mxaudiomanager.h | 10 ++- LEGO1/mxmidimanager.cpp | 161 +++++++++++++++++++++++++++++++++++++++ LEGO1/mxmidimanager.h | 42 ++++++++++ 5 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 LEGO1/mxmidimanager.cpp create mode 100644 LEGO1/mxmidimanager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0da82a25..818d3773 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,7 @@ add_library(lego1 SHARED LEGO1/mxmatrix.cpp LEGO1/mxmediamanager.cpp LEGO1/mxmediapresenter.cpp + LEGO1/mxmidimanager.cpp LEGO1/mxmidipresenter.cpp LEGO1/mxmusicpresenter.cpp LEGO1/mxnotificationmanager.cpp @@ -272,4 +273,4 @@ if (MSVC) set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "/incremental:no") set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "/incremental:no /debug") set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "/incremental:no") -endif() \ No newline at end of file +endif() diff --git a/LEGO1/mxaudiomanager.cpp b/LEGO1/mxaudiomanager.cpp index c7ecdc12..bb358e47 100644 --- a/LEGO1/mxaudiomanager.cpp +++ b/LEGO1/mxaudiomanager.cpp @@ -20,7 +20,21 @@ MxAudioManager::~MxAudioManager() // OFFSET: LEGO1 0x100b8df0 void MxAudioManager::Init() { - this->m_unk2c = 100; + this->m_volume = 100; +} + +// OFFSET: LEGO1 0x10029910 +MxS32 MxAudioManager::GetVolume() +{ + return this->m_volume; +} + +// OFFSET: LEGO1 0x100b8ea0 +void MxAudioManager::SetVolume(MxS32 p_volume) +{ + this->m_criticalSection.Enter(); + this->m_volume = p_volume; + this->m_criticalSection.Leave(); } // OFFSET: LEGO1 0x100b8e00 diff --git a/LEGO1/mxaudiomanager.h b/LEGO1/mxaudiomanager.h index 1403f36d..1ba5b6fd 100644 --- a/LEGO1/mxaudiomanager.h +++ b/LEGO1/mxaudiomanager.h @@ -11,18 +11,20 @@ class MxAudioManager : public MxMediaManager MxAudioManager(); virtual ~MxAudioManager() override; - virtual MxResult InitPresenters(); // vtable+14 - virtual void Destroy(); // vtable+18 + virtual MxResult InitPresenters() override; // vtable+14 + virtual void Destroy() override; // vtable+18 + virtual MxS32 GetVolume(); // vtable+28 + virtual void SetVolume(MxS32 p_volume); // vtable+2c private: - void LockedReinitialize(MxBool); + void LockedReinitialize(MxBool p_skipDestroy); static MxS32 g_unkCount; protected: void Init(); - undefined4 m_unk2c; + MxS32 m_volume; // 0x2c }; #endif // MXAUDIOMANAGER_H diff --git a/LEGO1/mxmidimanager.cpp b/LEGO1/mxmidimanager.cpp new file mode 100644 index 00000000..62bcb6d2 --- /dev/null +++ b/LEGO1/mxmidimanager.cpp @@ -0,0 +1,161 @@ +#include "mxmidimanager.h" +#include "mxomni.h" +#include + +DECOMP_SIZE_ASSERT(MxMIDIManager, 0x58); + +// OFFSET: LEGO1 0x100c05a0 +MxMIDIManager::MxMIDIManager() +{ + Init(); +} + +// OFFSET: LEGO1 0x100c0630 +MxMIDIManager::~MxMIDIManager() +{ + LockedReinitialize(TRUE); +} + +// OFFSET: LEGO1 0x100c0b20 +void MxMIDIManager::DeinitializeMIDI() +{ + m_criticalSection.Enter(); + + if (this->m_MIDIInitialized) + { + this->m_MIDIInitialized = FALSE; + midiStreamStop(this->m_MIDIStreamH); + midiOutUnprepareHeader(this->m_MIDIStreamH, this->m_MIDIHdrP, sizeof(MIDIHDR)); + midiOutSetVolume(this->m_MIDIStreamH, this->m_MIDIVolume); + midiStreamClose(this->m_MIDIStreamH); + delete this->m_MIDIHdrP; + this->InitData(); + } + + this->m_criticalSection.Leave(); +} + +// OFFSET: LEGO1 0x100c0690 +void MxMIDIManager::Init() +{ + this->m_multiplier = 100; + InitData(); +} + +// OFFSET: LEGO1 0x100c06a0 +void MxMIDIManager::InitData() +{ + this->m_MIDIStreamH = 0; + this->m_MIDIInitialized = FALSE; + this->m_unk38 = 0; + this->m_unk3c = 0; + this->m_unk40 = 0; + this->m_unk44 = 0; + this->m_unk48 = 0; + this->m_MIDIHdrP = NULL; +} + +// OFFSET: LEGO1 0x100c06c0 +void MxMIDIManager::LockedReinitialize(MxBool p_skipDestroy) +{ + if (this->m_thread) + { + this->m_thread->Terminate(); + if (this->m_thread) + { + delete m_thread; + } + } + else + { + TickleManager()->UnregisterClient(this); + } + + this->m_criticalSection.Enter(); + DeinitializeMIDI(); + Init(); + this->m_criticalSection.Leave(); + + if (!p_skipDestroy) + { + MxAudioManager::Destroy(); + } +} + +// OFFSET: LEGO1 0x100c0930 +void MxMIDIManager::Destroy() +{ + LockedReinitialize(FALSE); +} + +// OFFSET: LEGO1 0x100c09a0 +MxS32 MxMIDIManager::CalculateVolume(MxS32 p_volume) +{ + MxS32 result = (p_volume * 0xffff) / 100; + return (result << 0x10) | result; +} + +// OFFSET: LEGO1 0x100c07f0 +void MxMIDIManager::SetMIDIVolume() +{ + MxS32 result = (this->m_volume * this->m_multiplier) / 0x64; + HMIDISTRM streamHandle = this->m_MIDIStreamH; + + if (streamHandle) + { + MxS32 volume = CalculateVolume(result); + midiOutSetVolume(streamHandle, volume); + } +} + +// OFFSET: LEGO1 0x100c0940 +void MxMIDIManager::SetVolume(MxS32 p_volume) +{ + MxAudioManager::SetVolume(p_volume); + this->m_criticalSection.Enter(); + SetMIDIVolume(); + this->m_criticalSection.Leave(); +} + +// OFFSET: LEGO1 0x100c0840 +MxResult MxMIDIManager::StartMIDIThread(MxU32 p_frequencyMS, MxBool p_noRegister) +{ + MxResult status = FAILURE; + MxBool locked = FALSE; + + MxResult result = MxAudioManager::InitPresenters(); + if (result == SUCCESS) + { + if (p_noRegister) + { + this->m_criticalSection.Enter(); + locked = TRUE; + this->m_thread = new MxTickleThread(this, p_frequencyMS); + + if (this->m_thread) + { + if (this->m_thread->Start(0, 0) == SUCCESS) + { + status = SUCCESS; + } + } + } + else + { + TickleManager()->RegisterClient(this, p_frequencyMS); + status = SUCCESS; + } + } + + if (status != SUCCESS) + { + Destroy(); + } + + if (locked) + { + this->m_criticalSection.Leave(); + } + + return status; +} \ No newline at end of file diff --git a/LEGO1/mxmidimanager.h b/LEGO1/mxmidimanager.h new file mode 100644 index 00000000..f944d67d --- /dev/null +++ b/LEGO1/mxmidimanager.h @@ -0,0 +1,42 @@ +#ifndef MXMIDIMANAGER_H +#define MXMIDIMANAGER_H + +#include "decomp.h" +#include "mxaudiomanager.h" + +// VTABLE 0x100dc930 +// SIZE 0x58 +class MxMIDIManager : public MxAudioManager +{ +public: + MxMIDIManager(); + virtual ~MxMIDIManager() override; + + virtual void Destroy() override; // vtable+18 + virtual void SetVolume(MxS32 p_volume) override; // vtable+2c + virtual MxResult StartMIDIThread(MxU32 p_frequencyMS, MxU8 p_noRegister); // vtable+30 + +private: + void LockedReinitialize(MxBool p_skipDestroy); + void DeinitializeMIDI(); + + MxS32 CalculateVolume(MxS32 p_volume); + void SetMIDIVolume(); + + HMIDISTRM m_MIDIStreamH; // 0x30 + MxBool m_MIDIInitialized; // 0x34 + undefined4 m_unk38; // 0x38 + undefined4 m_unk3c; // 0x3c + undefined4 m_unk40; // 0x40 + undefined4 m_unk44; // 0x44 + undefined4 m_unk48; // 0x48 + MIDIHDR *m_MIDIHdrP; // 0x4c + MxS32 m_multiplier; // 0x50 + DWORD m_MIDIVolume; // 0x54 + +protected: + void Init(); + void InitData(); +}; + +#endif // MXMIDIMANAGER_H \ No newline at end of file From 8e87b5b4c8ab3b483cba80c31f8707726d0647ec Mon Sep 17 00:00:00 2001 From: Ramen2X <64166386+Ramen2X@users.noreply.github.com> Date: Thu, 5 Oct 2023 18:51:34 -0400 Subject: [PATCH 53/87] MxTransitionManager::Tickle() & FUN_1004bcf0 (#168) * implement MxTransitionManager::Tickle() * improved accuracy of MxTransitionManager::Tickle * implement MxTransitionManager::FUN_1004bcf0 * improved accuracy of FUN_1004bcf0 * move/rename stubbed transition methods --------- Co-authored-by: MattKC <34096995+itsmattkc@users.noreply.github.com> --- LEGO1/mxdisplaysurface.cpp | 6 ++++ LEGO1/mxdisplaysurface.h | 2 ++ LEGO1/mxtransitionmanager.cpp | 57 +++++++++++++++++++++++++++++++++-- LEGO1/mxtransitionmanager.h | 7 +++++ 4 files changed, 69 insertions(+), 3 deletions(-) diff --git a/LEGO1/mxdisplaysurface.cpp b/LEGO1/mxdisplaysurface.cpp index 619f5eef..e22244c5 100644 --- a/LEGO1/mxdisplaysurface.cpp +++ b/LEGO1/mxdisplaysurface.cpp @@ -230,3 +230,9 @@ undefined4 MxDisplaySurface::vtable44(undefined4, undefined4*, undefined4, undef { return 0; } + +// OFFSET: LEGO1 0x100ba640 STUB +void MxDisplaySurface::FUN_100ba640() +{ + // TODO +} diff --git a/LEGO1/mxdisplaysurface.h b/LEGO1/mxdisplaysurface.h index af484716..8e79f6e8 100644 --- a/LEGO1/mxdisplaysurface.h +++ b/LEGO1/mxdisplaysurface.h @@ -19,6 +19,8 @@ class MxDisplaySurface : public MxCore void Reset(); + void FUN_100ba640(); + virtual MxResult Init(MxVideoParam &p_videoParam, LPDIRECTDRAWSURFACE p_ddSurface1, LPDIRECTDRAWSURFACE p_ddSurface2, LPDIRECTDRAWCLIPPER p_ddClipper); virtual MxResult Create(MxVideoParam &p_videoParam); virtual void Clear(); diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index efb90604..b844095e 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -33,12 +33,36 @@ MxTransitionManager::~MxTransitionManager() TickleManager()->UnregisterClient(this); } -// OFFSET: LEGO1 0x1004bac0 STUB +// OFFSET: LEGO1 0x1004bac0 MxResult MxTransitionManager::Tickle() { - // TODO + if (this->m_animationSpeed + this->m_systemTime > timeGetTime()) { + return SUCCESS; + } - return 0; + this->m_systemTime = timeGetTime(); + + switch (this->m_transitionType) { + case NO_ANIMATION: + FUN_1004bcf0(); + break; + case DISSOLVE: + Transition_Dissolve(); + break; + case PIXELATION: + Transition_Pixelation(); + break; + case SCREEN_WIPE: + Transition_Wipe(); + break; + case WINDOWS: + Transition_Windows(); + break; + case BROKEN: + Transition_Broken(); + break; + } + return SUCCESS; } // OFFSET: LEGO1 0x1004bc30 @@ -192,6 +216,33 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx return FAILURE; } +// OFFSET: LEGO1 0x1004bcf0 +void MxTransitionManager::FUN_1004bcf0() +{ + LegoVideoManager *videoManager = VideoManager(); + videoManager->GetDisplaySurface()->FUN_100ba640(); + EndTransition(TRUE); +} + +// OFFSET: LEGO1 0x1004bed0 STUB +void MxTransitionManager::Transition_Pixelation() +{ + // TODO +} + + +// OFFSET: LEGO1 0x1004c270 STUB +void MxTransitionManager::Transition_Windows() +{ + // TODO +} + +// OFFSET: LEGO1 0x1004c3e0 STUB +void MxTransitionManager::Transition_Broken() +{ + // TODO +} + // OFFSET: LEGO1 0x1004c170 void MxTransitionManager::Transition_Wipe() { diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 4ed82229..d3c344ce 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -42,10 +42,17 @@ class MxTransitionManager : public MxCore MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim); + private: void EndTransition(MxBool p_notifyWorld); void Transition_Dissolve(); + void Transition_Pixelation(); void Transition_Wipe(); + void Transition_Windows(); + void Transition_Broken(); + + void FUN_1004bcf0(); + void SubmitCopyRect(LPDDSURFACEDESC ddsc); void SetupCopyRect(LPDDSURFACEDESC ddsc); From 666c65fa4fb4a68cad2e35f835b9f7c08cdd8010 Mon Sep 17 00:00:00 2001 From: Ramen2X <64166386+Ramen2X@users.noreply.github.com> Date: Thu, 5 Oct 2023 18:55:35 -0400 Subject: [PATCH 54/87] rename FUN_1004bcf0 to Transition_None --- LEGO1/mxtransitionmanager.cpp | 4 ++-- LEGO1/mxtransitionmanager.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index b844095e..d34df54f 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -44,7 +44,7 @@ MxResult MxTransitionManager::Tickle() switch (this->m_transitionType) { case NO_ANIMATION: - FUN_1004bcf0(); + Transition_None(); break; case DISSOLVE: Transition_Dissolve(); @@ -217,7 +217,7 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx } // OFFSET: LEGO1 0x1004bcf0 -void MxTransitionManager::FUN_1004bcf0() +void MxTransitionManager::Transition_None() { LegoVideoManager *videoManager = VideoManager(); videoManager->GetDisplaySurface()->FUN_100ba640(); diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index d3c344ce..7f1d4ead 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -45,14 +45,13 @@ class MxTransitionManager : public MxCore private: void EndTransition(MxBool p_notifyWorld); + void Transition_None(); void Transition_Dissolve(); void Transition_Pixelation(); void Transition_Wipe(); void Transition_Windows(); void Transition_Broken(); - void FUN_1004bcf0(); - void SubmitCopyRect(LPDDSURFACEDESC ddsc); void SetupCopyRect(LPDDSURFACEDESC ddsc); From 5ac6cf55a9920265e96efd5074763578354c352b Mon Sep 17 00:00:00 2001 From: Angel <67720650+AngelTomkins@users.noreply.github.com> Date: Fri, 6 Oct 2023 01:26:48 -0400 Subject: [PATCH 55/87] Corrected typo in reccmp.py (#169) --- tools/reccmp/reccmp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/reccmp/reccmp.py b/tools/reccmp/reccmp.py index e0962534..f26ab764 100755 --- a/tools/reccmp/reccmp.py +++ b/tools/reccmp/reccmp.py @@ -114,7 +114,7 @@ def __init__(self, unix_cwd): def get_wine_path(self, unix_fn: str) -> str: if unix_fn.startswith('./'): - return self.win_cmd + '\\' + unix_fn[2:].replace('/', '\\') + return self.win_cwd + '\\' + unix_fn[2:].replace('/', '\\') if unix_fn.startswith(self.unix_cwd): return self.win_cwd + '\\' + unix_fn.removeprefix(self.unix_cwd).replace('/', '\\').lstrip('\\') return self._call_winepath_unix2win(unix_fn) From 1da1d291a8c14a8f594d26b1f2ae37c745819ced Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 6 Oct 2023 09:00:00 -0400 Subject: [PATCH 56/87] Fix line endings --- LEGO1/mxmidimanager.cpp | 320 ++++++++++++++++++++-------------------- LEGO1/mxmidimanager.h | 82 +++++----- 2 files changed, 201 insertions(+), 201 deletions(-) diff --git a/LEGO1/mxmidimanager.cpp b/LEGO1/mxmidimanager.cpp index 62bcb6d2..26b977df 100644 --- a/LEGO1/mxmidimanager.cpp +++ b/LEGO1/mxmidimanager.cpp @@ -1,161 +1,161 @@ -#include "mxmidimanager.h" -#include "mxomni.h" -#include - -DECOMP_SIZE_ASSERT(MxMIDIManager, 0x58); - -// OFFSET: LEGO1 0x100c05a0 -MxMIDIManager::MxMIDIManager() -{ - Init(); -} - -// OFFSET: LEGO1 0x100c0630 -MxMIDIManager::~MxMIDIManager() -{ - LockedReinitialize(TRUE); -} - -// OFFSET: LEGO1 0x100c0b20 -void MxMIDIManager::DeinitializeMIDI() -{ - m_criticalSection.Enter(); - - if (this->m_MIDIInitialized) - { - this->m_MIDIInitialized = FALSE; - midiStreamStop(this->m_MIDIStreamH); - midiOutUnprepareHeader(this->m_MIDIStreamH, this->m_MIDIHdrP, sizeof(MIDIHDR)); - midiOutSetVolume(this->m_MIDIStreamH, this->m_MIDIVolume); - midiStreamClose(this->m_MIDIStreamH); - delete this->m_MIDIHdrP; - this->InitData(); - } - - this->m_criticalSection.Leave(); -} - -// OFFSET: LEGO1 0x100c0690 -void MxMIDIManager::Init() -{ - this->m_multiplier = 100; - InitData(); -} - -// OFFSET: LEGO1 0x100c06a0 -void MxMIDIManager::InitData() -{ - this->m_MIDIStreamH = 0; - this->m_MIDIInitialized = FALSE; - this->m_unk38 = 0; - this->m_unk3c = 0; - this->m_unk40 = 0; - this->m_unk44 = 0; - this->m_unk48 = 0; - this->m_MIDIHdrP = NULL; -} - -// OFFSET: LEGO1 0x100c06c0 -void MxMIDIManager::LockedReinitialize(MxBool p_skipDestroy) -{ - if (this->m_thread) - { - this->m_thread->Terminate(); - if (this->m_thread) - { - delete m_thread; - } - } - else - { - TickleManager()->UnregisterClient(this); - } - - this->m_criticalSection.Enter(); - DeinitializeMIDI(); - Init(); - this->m_criticalSection.Leave(); - - if (!p_skipDestroy) - { - MxAudioManager::Destroy(); - } -} - -// OFFSET: LEGO1 0x100c0930 -void MxMIDIManager::Destroy() -{ - LockedReinitialize(FALSE); -} - -// OFFSET: LEGO1 0x100c09a0 -MxS32 MxMIDIManager::CalculateVolume(MxS32 p_volume) -{ - MxS32 result = (p_volume * 0xffff) / 100; - return (result << 0x10) | result; -} - -// OFFSET: LEGO1 0x100c07f0 -void MxMIDIManager::SetMIDIVolume() -{ - MxS32 result = (this->m_volume * this->m_multiplier) / 0x64; - HMIDISTRM streamHandle = this->m_MIDIStreamH; - - if (streamHandle) - { - MxS32 volume = CalculateVolume(result); - midiOutSetVolume(streamHandle, volume); - } -} - -// OFFSET: LEGO1 0x100c0940 -void MxMIDIManager::SetVolume(MxS32 p_volume) -{ - MxAudioManager::SetVolume(p_volume); - this->m_criticalSection.Enter(); - SetMIDIVolume(); - this->m_criticalSection.Leave(); -} - -// OFFSET: LEGO1 0x100c0840 -MxResult MxMIDIManager::StartMIDIThread(MxU32 p_frequencyMS, MxBool p_noRegister) -{ - MxResult status = FAILURE; - MxBool locked = FALSE; - - MxResult result = MxAudioManager::InitPresenters(); - if (result == SUCCESS) - { - if (p_noRegister) - { - this->m_criticalSection.Enter(); - locked = TRUE; - this->m_thread = new MxTickleThread(this, p_frequencyMS); - - if (this->m_thread) - { - if (this->m_thread->Start(0, 0) == SUCCESS) - { - status = SUCCESS; - } - } - } - else - { - TickleManager()->RegisterClient(this, p_frequencyMS); - status = SUCCESS; - } - } - - if (status != SUCCESS) - { - Destroy(); - } - - if (locked) - { - this->m_criticalSection.Leave(); - } - - return status; +#include "mxmidimanager.h" +#include "mxomni.h" +#include + +DECOMP_SIZE_ASSERT(MxMIDIManager, 0x58); + +// OFFSET: LEGO1 0x100c05a0 +MxMIDIManager::MxMIDIManager() +{ + Init(); +} + +// OFFSET: LEGO1 0x100c0630 +MxMIDIManager::~MxMIDIManager() +{ + LockedReinitialize(TRUE); +} + +// OFFSET: LEGO1 0x100c0b20 +void MxMIDIManager::DeinitializeMIDI() +{ + m_criticalSection.Enter(); + + if (this->m_MIDIInitialized) + { + this->m_MIDIInitialized = FALSE; + midiStreamStop(this->m_MIDIStreamH); + midiOutUnprepareHeader(this->m_MIDIStreamH, this->m_MIDIHdrP, sizeof(MIDIHDR)); + midiOutSetVolume(this->m_MIDIStreamH, this->m_MIDIVolume); + midiStreamClose(this->m_MIDIStreamH); + delete this->m_MIDIHdrP; + this->InitData(); + } + + this->m_criticalSection.Leave(); +} + +// OFFSET: LEGO1 0x100c0690 +void MxMIDIManager::Init() +{ + this->m_multiplier = 100; + InitData(); +} + +// OFFSET: LEGO1 0x100c06a0 +void MxMIDIManager::InitData() +{ + this->m_MIDIStreamH = 0; + this->m_MIDIInitialized = FALSE; + this->m_unk38 = 0; + this->m_unk3c = 0; + this->m_unk40 = 0; + this->m_unk44 = 0; + this->m_unk48 = 0; + this->m_MIDIHdrP = NULL; +} + +// OFFSET: LEGO1 0x100c06c0 +void MxMIDIManager::LockedReinitialize(MxBool p_skipDestroy) +{ + if (this->m_thread) + { + this->m_thread->Terminate(); + if (this->m_thread) + { + delete m_thread; + } + } + else + { + TickleManager()->UnregisterClient(this); + } + + this->m_criticalSection.Enter(); + DeinitializeMIDI(); + Init(); + this->m_criticalSection.Leave(); + + if (!p_skipDestroy) + { + MxAudioManager::Destroy(); + } +} + +// OFFSET: LEGO1 0x100c0930 +void MxMIDIManager::Destroy() +{ + LockedReinitialize(FALSE); +} + +// OFFSET: LEGO1 0x100c09a0 +MxS32 MxMIDIManager::CalculateVolume(MxS32 p_volume) +{ + MxS32 result = (p_volume * 0xffff) / 100; + return (result << 0x10) | result; +} + +// OFFSET: LEGO1 0x100c07f0 +void MxMIDIManager::SetMIDIVolume() +{ + MxS32 result = (this->m_volume * this->m_multiplier) / 0x64; + HMIDISTRM streamHandle = this->m_MIDIStreamH; + + if (streamHandle) + { + MxS32 volume = CalculateVolume(result); + midiOutSetVolume(streamHandle, volume); + } +} + +// OFFSET: LEGO1 0x100c0940 +void MxMIDIManager::SetVolume(MxS32 p_volume) +{ + MxAudioManager::SetVolume(p_volume); + this->m_criticalSection.Enter(); + SetMIDIVolume(); + this->m_criticalSection.Leave(); +} + +// OFFSET: LEGO1 0x100c0840 +MxResult MxMIDIManager::StartMIDIThread(MxU32 p_frequencyMS, MxBool p_noRegister) +{ + MxResult status = FAILURE; + MxBool locked = FALSE; + + MxResult result = MxAudioManager::InitPresenters(); + if (result == SUCCESS) + { + if (p_noRegister) + { + this->m_criticalSection.Enter(); + locked = TRUE; + this->m_thread = new MxTickleThread(this, p_frequencyMS); + + if (this->m_thread) + { + if (this->m_thread->Start(0, 0) == SUCCESS) + { + status = SUCCESS; + } + } + } + else + { + TickleManager()->RegisterClient(this, p_frequencyMS); + status = SUCCESS; + } + } + + if (status != SUCCESS) + { + Destroy(); + } + + if (locked) + { + this->m_criticalSection.Leave(); + } + + return status; } \ No newline at end of file diff --git a/LEGO1/mxmidimanager.h b/LEGO1/mxmidimanager.h index f944d67d..dd362594 100644 --- a/LEGO1/mxmidimanager.h +++ b/LEGO1/mxmidimanager.h @@ -1,42 +1,42 @@ -#ifndef MXMIDIMANAGER_H -#define MXMIDIMANAGER_H - -#include "decomp.h" -#include "mxaudiomanager.h" - -// VTABLE 0x100dc930 -// SIZE 0x58 -class MxMIDIManager : public MxAudioManager -{ -public: - MxMIDIManager(); - virtual ~MxMIDIManager() override; - - virtual void Destroy() override; // vtable+18 - virtual void SetVolume(MxS32 p_volume) override; // vtable+2c - virtual MxResult StartMIDIThread(MxU32 p_frequencyMS, MxU8 p_noRegister); // vtable+30 - -private: - void LockedReinitialize(MxBool p_skipDestroy); - void DeinitializeMIDI(); - - MxS32 CalculateVolume(MxS32 p_volume); - void SetMIDIVolume(); - - HMIDISTRM m_MIDIStreamH; // 0x30 - MxBool m_MIDIInitialized; // 0x34 - undefined4 m_unk38; // 0x38 - undefined4 m_unk3c; // 0x3c - undefined4 m_unk40; // 0x40 - undefined4 m_unk44; // 0x44 - undefined4 m_unk48; // 0x48 - MIDIHDR *m_MIDIHdrP; // 0x4c - MxS32 m_multiplier; // 0x50 - DWORD m_MIDIVolume; // 0x54 - -protected: - void Init(); - void InitData(); -}; - +#ifndef MXMIDIMANAGER_H +#define MXMIDIMANAGER_H + +#include "decomp.h" +#include "mxaudiomanager.h" + +// VTABLE 0x100dc930 +// SIZE 0x58 +class MxMIDIManager : public MxAudioManager +{ +public: + MxMIDIManager(); + virtual ~MxMIDIManager() override; + + virtual void Destroy() override; // vtable+18 + virtual void SetVolume(MxS32 p_volume) override; // vtable+2c + virtual MxResult StartMIDIThread(MxU32 p_frequencyMS, MxU8 p_noRegister); // vtable+30 + +private: + void LockedReinitialize(MxBool p_skipDestroy); + void DeinitializeMIDI(); + + MxS32 CalculateVolume(MxS32 p_volume); + void SetMIDIVolume(); + + HMIDISTRM m_MIDIStreamH; // 0x30 + MxBool m_MIDIInitialized; // 0x34 + undefined4 m_unk38; // 0x38 + undefined4 m_unk3c; // 0x3c + undefined4 m_unk40; // 0x40 + undefined4 m_unk44; // 0x44 + undefined4 m_unk48; // 0x48 + MIDIHDR *m_MIDIHdrP; // 0x4c + MxS32 m_multiplier; // 0x50 + DWORD m_MIDIVolume; // 0x54 + +protected: + void Init(); + void InitData(); +}; + #endif // MXMIDIMANAGER_H \ No newline at end of file From 7f5198220c6aef7eda3f675f0b4a774b5d03037e Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Fri, 6 Oct 2023 12:54:58 -0400 Subject: [PATCH 57/87] Unstub MxLoopingFlcPresenter destructor (#173) sorry guys --- LEGO1/mxloopingflcpresenter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/mxloopingflcpresenter.cpp b/LEGO1/mxloopingflcpresenter.cpp index 54002246..58b066f6 100644 --- a/LEGO1/mxloopingflcpresenter.cpp +++ b/LEGO1/mxloopingflcpresenter.cpp @@ -10,7 +10,7 @@ MxLoopingFlcPresenter::MxLoopingFlcPresenter() Init(); } -// OFFSET: LEGO1 0x100b43b0 STUB +// OFFSET: LEGO1 0x100b43b0 MxLoopingFlcPresenter::~MxLoopingFlcPresenter() { Destroy(TRUE); From 1217e4aa58996df88b29a0239761d7dda35b90f7 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Fri, 6 Oct 2023 13:00:49 -0400 Subject: [PATCH 58/87] MxMusicPresenter dtor, stub destroy (#174) * MxMusicPresenter dtor, stub destroy * Fix destructor declaration --------- Co-authored-by: Christian Semmler --- LEGO1/mxmusicpresenter.cpp | 12 ++++++++++++ LEGO1/mxmusicpresenter.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/LEGO1/mxmusicpresenter.cpp b/LEGO1/mxmusicpresenter.cpp index d33627ad..72ae273a 100644 --- a/LEGO1/mxmusicpresenter.cpp +++ b/LEGO1/mxmusicpresenter.cpp @@ -6,7 +6,19 @@ MxMusicPresenter::MxMusicPresenter() Init(); } +// OFFSET: LEGO1 0x100c24e0 +MxMusicPresenter::~MxMusicPresenter() +{ + Destroy(TRUE); +} + // OFFSET: LEGO1 0x100c2540 void MxMusicPresenter::Init() { +} + +// OFFSET: LEGO1 0x100c2550 STUB +void MxMusicPresenter::Destroy(MxBool) +{ + // TODO } \ No newline at end of file diff --git a/LEGO1/mxmusicpresenter.h b/LEGO1/mxmusicpresenter.h index c8e88604..a000c2b9 100644 --- a/LEGO1/mxmusicpresenter.h +++ b/LEGO1/mxmusicpresenter.h @@ -21,9 +21,11 @@ class MxMusicPresenter : public MxAudioPresenter } MxMusicPresenter(); + virtual ~MxMusicPresenter() override; private: void Init(); + void Destroy(MxBool); }; #endif // MXMUSICPRESENTER_H From 85fe4ad07aa7fb13c928673e078e4da82d174cdf Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Fri, 6 Oct 2023 18:17:49 -0400 Subject: [PATCH 59/87] MxAudioPresenter - vtable functions (#175) * MxAudioPresenter - vtable functions * Rename parameter --------- Co-authored-by: Christian Semmler --- LEGO1/mxaudiopresenter.cpp | 12 ++++++++++++ LEGO1/mxaudiopresenter.h | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/LEGO1/mxaudiopresenter.cpp b/LEGO1/mxaudiopresenter.cpp index ac634362..48a02377 100644 --- a/LEGO1/mxaudiopresenter.cpp +++ b/LEGO1/mxaudiopresenter.cpp @@ -3,3 +3,15 @@ #include "decomp.h" DECOMP_SIZE_ASSERT(MxAudioPresenter, 0x54); + +// OFFSET: LEGO1 0x1000d260 +undefined4 MxAudioPresenter::vtable5c() +{ + return this->m_unk50; +} + +// OFFSET: LEGO1 0x1000d270 +void MxAudioPresenter::vtable60(undefined4 p_unk50) +{ + this->m_unk50 = p_unk50; +} diff --git a/LEGO1/mxaudiopresenter.h b/LEGO1/mxaudiopresenter.h index c1001a13..fb2e75a8 100644 --- a/LEGO1/mxaudiopresenter.h +++ b/LEGO1/mxaudiopresenter.h @@ -1,6 +1,7 @@ #ifndef MXAUDIOPRESENTER_H #define MXAUDIOPRESENTER_H +#include "decomp.h" #include "mxmediapresenter.h" // VTABLE 0x100d4c70 @@ -24,7 +25,10 @@ class MxAudioPresenter : public MxMediaPresenter return !strcmp(name, MxAudioPresenter::ClassName()) || MxMediaPresenter::IsA(name); } - int m_unk50; + virtual undefined4 vtable5c(); + virtual void vtable60(undefined4); + + undefined4 m_unk50; }; #endif // MXAUDIOPRESENTER_H From 50b9a6dea5631042b956cf5996008fe226fa688e Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sat, 7 Oct 2023 09:05:44 -0400 Subject: [PATCH 60/87] Implement Start() (#176) * Implement Start() * Undo isleapp changes * Implement LegoOmni::Start * fix vtable0x20 * Address review * fix build --- LEGO1/legoomni.cpp | 20 ++++++++++++++------ LEGO1/legoomni.h | 5 ++--- LEGO1/mxdsobject.h | 1 + LEGO1/mxomni.cpp | 16 +++++++++++----- LEGO1/mxomni.h | 2 +- LEGO1/mxstreamcontroller.cpp | 19 +++++++++++++++++++ LEGO1/mxstreamcontroller.h | 4 ++++ LEGO1/mxstreamer.cpp | 16 ++++++++++++++++ LEGO1/mxstreamer.h | 2 ++ 9 files changed, 70 insertions(+), 15 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index 929ba556..58eed5c1 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -99,11 +99,10 @@ void SetOmniUserMessage(void (*p_userMsg)(const char *,int)) g_omniUserMessage = p_userMsg; } -// OFFSET: LEGO1 0x100acf50 STUB -MxLong Start(MxDSAction *) +// OFFSET: LEGO1 0x100acf50 +MxResult Start(MxDSAction* p_dsAction) { - // TODO - return 0; + return MxOmni::GetInstance()->Start(p_dsAction); } // OFFSET: LEGO1 0x1005ad10 @@ -257,6 +256,10 @@ void LegoOmni::Init() MxResult LegoOmni::Create(COMPAT_CONST MxOmniCreateParam &p) { // FIXME: Stub + MxOmni::Create(p); + m_gameState = new LegoGameState(); + m_bkgAudioManager = new MxBackgroundAudioManager(); + return SUCCESS; } @@ -265,9 +268,14 @@ void LegoOmni::Destroy() // FIXME: Stub } -void LegoOmni::vtable0x20() +// OFFSET: LEGO1 0x1005b580 +MxResult LegoOmni::Start(MxDSAction* action) { - // FIXME: Stub + MxResult result = MxOmni::Start(action); + this->m_action.SetAtomId(action->GetAtomId()); + this->m_action.SetObjectId(action->GetObjectId()); + this->m_action.SetUnknown24(action->GetUnknown24()); + return result; } void LegoOmni::DeleteObject(MxDSAction &ds) diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 4a5fe6e4..044275b4 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -55,7 +55,7 @@ class LegoOmni : public MxOmni virtual void Init() override; // vtable+14 virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p) override; // vtable+18 virtual void Destroy() override; // vtable+1c - virtual void vtable0x20() override; + virtual MxResult Start(MxDSAction* action) override; virtual void DeleteObject(MxDSAction &ds) override; virtual MxBool DoesEntityExist(MxDSAction &ds) override; virtual void vtable0x2c() override; @@ -110,10 +110,9 @@ __declspec(dllexport) LegoEntity * PickEntity(MxLong,MxLong); __declspec(dllexport) LegoROI * PickROI(MxLong,MxLong); __declspec(dllexport) void SetOmniUserMessage(void (*)(const char *,int)); __declspec(dllexport) LegoSoundManager * SoundManager(); -__declspec(dllexport) MxLong Start(MxDSAction *); +__declspec(dllexport) MxResult Start(MxDSAction*); __declspec(dllexport) MxTransitionManager * TransitionManager(); __declspec(dllexport) LegoVideoManager * VideoManager(); -__declspec(dllexport) MxLong Start(MxDSAction *a); LegoBuildingManager* BuildingManager(); Isle* GetIsle(); diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index 1ca3d98a..e340789a 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -36,6 +36,7 @@ class MxDSObject : public MxCore inline const MxAtomId& GetAtomId() { return this->m_atomId; } inline MxU32 GetObjectId() { return this->m_objectId; } + inline MxS16 GetUnknown24() { return this->m_unk24; } inline void SetObjectId(MxU32 p_objectId) { this->m_objectId = p_objectId; } inline void SetUnknown24(MxS16 p_unk24) { this->m_unk24 = p_unk24; } diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 200e5bdf..ed870b34 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -42,10 +42,16 @@ void MxOmni::Init() m_unk64 = NULL; } -// OFFSET: LEGO1 0x100b0090 STUB -void MxOmni::vtable0x20() +// OFFSET: LEGO1 0x100b0090 +MxResult MxOmni::Start(MxDSAction* p_dsAction) { - // TODO + MxResult result = FAILURE; + if(p_dsAction->GetAtomId().GetInternal() != NULL && p_dsAction->GetObjectId() != -1 && m_streamer != NULL) + { + result = m_streamer->Unknown100b99b0(p_dsAction); + } + + return result; } // OFFSET: LEGO1 0x100b00c0 STUB @@ -258,7 +264,7 @@ MxAtomIdCounterSet *AtomIdCounterSet() MxStreamer* Streamer() { return MxOmni::GetInstance()->GetStreamer(); -} +} // OFFSET: LEGO1 0x100acf00 MxSoundManager* MSoundManager() @@ -288,4 +294,4 @@ MxMusicManager* MusicManager() MxEventManager* EventManager() { return MxOmni::GetInstance()->GetEventManager(); -} \ No newline at end of file +} diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index a8fa9db8..9c7d6b0a 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -38,7 +38,7 @@ class MxOmni : public MxCore virtual void Init(); // vtable+14 virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p); // vtable+18 virtual void Destroy(); // vtable+1c - virtual void vtable0x20(); // vtable+20 + virtual MxResult Start(MxDSAction* p_dsAction); // vtable+20 virtual void DeleteObject(MxDSAction &ds); // vtable+24 virtual MxBool DoesEntityExist(MxDSAction &ds); // vtable+28 virtual void vtable0x2c(); // vtable+2c diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index 09f2d95c..e219f357 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -30,3 +30,22 @@ MxResult MxStreamController::Open(const char *p_filename) return SUCCESS; } + +// OFFSET: LEGO1 0x100b9400 +MxResult MxStreamController::vtable0x18(undefined4 p_unknown, undefined4 p_unknown2) +{ + return FAILURE; +} + +// OFFSET: LEGO1 0x100b9410 +MxResult MxStreamController::vtable0x1C(undefined4 p_unknown, undefined4 p_unknown2) +{ + return FAILURE; +} + +// OFFSET: LEGO1 0x100c1690 STUB +MxResult MxStreamController::vtable0x20(MxDSAction* action) +{ + // TODO STUB + return FAILURE; +} diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index c7e4309e..0f459ed0 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -6,6 +6,7 @@ #include "mxcriticalsection.h" #include "mxcore.h" #include "mxdsobject.h" +#include "mxdsaction.h" // VTABLE 0x100dc968 // SIZE 0x64 @@ -30,6 +31,9 @@ class MxStreamController : public MxCore } virtual MxResult Open(const char *p_filename); // vtable+0x14 + 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* action); //vtable+0x20 MxBool FUN_100c20d0(MxDSObject &p_obj); diff --git a/LEGO1/mxstreamer.cpp b/LEGO1/mxstreamer.cpp index 2121773e..53d7303f 100644 --- a/LEGO1/mxstreamer.cpp +++ b/LEGO1/mxstreamer.cpp @@ -133,6 +133,22 @@ MxResult MxStreamer::AddStreamControllerToOpenList(MxStreamController *stream) return FAILURE; } +// OFFSET: LEGO1 0x100b99b0 +MxResult MxStreamer::Unknown100b99b0(MxDSAction* p_action) +{ + MxStreamController* controller; + if (p_action != NULL && p_action->GetAtomId().GetInternal() != NULL && p_action->GetObjectId() != -1) + { + controller = GetOpenStream(p_action->GetAtomId().GetInternal()); + if (controller == NULL) + { + return FAILURE; + } + return controller->vtable0x20(p_action); + } + return FAILURE; +} + // OFFSET: LEGO1 0x100b9b60 MxLong MxStreamer::Notify(MxParam &p) { diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index 5ab02cbb..c900feb9 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -96,6 +96,8 @@ class MxStreamer : public MxCore MxResult AddStreamControllerToOpenList(MxStreamController *p_stream); + MxResult MxStreamer::Unknown100b99b0(MxDSAction* p_action); + private: list m_openStreams; // 0x8 MxStreamerSubClass2 m_subclass1; // 0x14 From 775ee9f05fee0c02e2f66cb672670d83f23f23d7 Mon Sep 17 00:00:00 2001 From: DmitriLeon2000 Date: Sun, 8 Oct 2023 00:02:12 +0900 Subject: [PATCH 61/87] Move MxMIDIManager to MxMusicManager (#178) --- CMakeLists.txt | 2 +- LEGO1/mxmidimanager.h | 42 ------------------- .../{mxmidimanager.cpp => mxmusicmanager.cpp} | 26 ++++++------ LEGO1/mxmusicmanager.h | 37 ++++++++++++++-- 4 files changed, 48 insertions(+), 59 deletions(-) delete mode 100644 LEGO1/mxmidimanager.h rename LEGO1/{mxmidimanager.cpp => mxmusicmanager.cpp} (82%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 818d3773..0e2135c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,8 +140,8 @@ add_library(lego1 SHARED LEGO1/mxmatrix.cpp LEGO1/mxmediamanager.cpp LEGO1/mxmediapresenter.cpp - LEGO1/mxmidimanager.cpp LEGO1/mxmidipresenter.cpp + LEGO1/mxmusicmanager.cpp LEGO1/mxmusicpresenter.cpp LEGO1/mxnotificationmanager.cpp LEGO1/mxobjectfactory.cpp diff --git a/LEGO1/mxmidimanager.h b/LEGO1/mxmidimanager.h deleted file mode 100644 index dd362594..00000000 --- a/LEGO1/mxmidimanager.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef MXMIDIMANAGER_H -#define MXMIDIMANAGER_H - -#include "decomp.h" -#include "mxaudiomanager.h" - -// VTABLE 0x100dc930 -// SIZE 0x58 -class MxMIDIManager : public MxAudioManager -{ -public: - MxMIDIManager(); - virtual ~MxMIDIManager() override; - - virtual void Destroy() override; // vtable+18 - virtual void SetVolume(MxS32 p_volume) override; // vtable+2c - virtual MxResult StartMIDIThread(MxU32 p_frequencyMS, MxU8 p_noRegister); // vtable+30 - -private: - void LockedReinitialize(MxBool p_skipDestroy); - void DeinitializeMIDI(); - - MxS32 CalculateVolume(MxS32 p_volume); - void SetMIDIVolume(); - - HMIDISTRM m_MIDIStreamH; // 0x30 - MxBool m_MIDIInitialized; // 0x34 - undefined4 m_unk38; // 0x38 - undefined4 m_unk3c; // 0x3c - undefined4 m_unk40; // 0x40 - undefined4 m_unk44; // 0x44 - undefined4 m_unk48; // 0x48 - MIDIHDR *m_MIDIHdrP; // 0x4c - MxS32 m_multiplier; // 0x50 - DWORD m_MIDIVolume; // 0x54 - -protected: - void Init(); - void InitData(); -}; - -#endif // MXMIDIMANAGER_H \ No newline at end of file diff --git a/LEGO1/mxmidimanager.cpp b/LEGO1/mxmusicmanager.cpp similarity index 82% rename from LEGO1/mxmidimanager.cpp rename to LEGO1/mxmusicmanager.cpp index 26b977df..247b6596 100644 --- a/LEGO1/mxmidimanager.cpp +++ b/LEGO1/mxmusicmanager.cpp @@ -1,23 +1,23 @@ -#include "mxmidimanager.h" +#include "mxmusicmanager.h" #include "mxomni.h" #include -DECOMP_SIZE_ASSERT(MxMIDIManager, 0x58); +DECOMP_SIZE_ASSERT(MxMusicManager, 0x58); // OFFSET: LEGO1 0x100c05a0 -MxMIDIManager::MxMIDIManager() +MxMusicManager::MxMusicManager() { Init(); } // OFFSET: LEGO1 0x100c0630 -MxMIDIManager::~MxMIDIManager() +MxMusicManager::~MxMusicManager() { LockedReinitialize(TRUE); } // OFFSET: LEGO1 0x100c0b20 -void MxMIDIManager::DeinitializeMIDI() +void MxMusicManager::DeinitializeMIDI() { m_criticalSection.Enter(); @@ -36,14 +36,14 @@ void MxMIDIManager::DeinitializeMIDI() } // OFFSET: LEGO1 0x100c0690 -void MxMIDIManager::Init() +void MxMusicManager::Init() { this->m_multiplier = 100; InitData(); } // OFFSET: LEGO1 0x100c06a0 -void MxMIDIManager::InitData() +void MxMusicManager::InitData() { this->m_MIDIStreamH = 0; this->m_MIDIInitialized = FALSE; @@ -56,7 +56,7 @@ void MxMIDIManager::InitData() } // OFFSET: LEGO1 0x100c06c0 -void MxMIDIManager::LockedReinitialize(MxBool p_skipDestroy) +void MxMusicManager::LockedReinitialize(MxBool p_skipDestroy) { if (this->m_thread) { @@ -83,20 +83,20 @@ void MxMIDIManager::LockedReinitialize(MxBool p_skipDestroy) } // OFFSET: LEGO1 0x100c0930 -void MxMIDIManager::Destroy() +void MxMusicManager::Destroy() { LockedReinitialize(FALSE); } // OFFSET: LEGO1 0x100c09a0 -MxS32 MxMIDIManager::CalculateVolume(MxS32 p_volume) +MxS32 MxMusicManager::CalculateVolume(MxS32 p_volume) { MxS32 result = (p_volume * 0xffff) / 100; return (result << 0x10) | result; } // OFFSET: LEGO1 0x100c07f0 -void MxMIDIManager::SetMIDIVolume() +void MxMusicManager::SetMIDIVolume() { MxS32 result = (this->m_volume * this->m_multiplier) / 0x64; HMIDISTRM streamHandle = this->m_MIDIStreamH; @@ -109,7 +109,7 @@ void MxMIDIManager::SetMIDIVolume() } // OFFSET: LEGO1 0x100c0940 -void MxMIDIManager::SetVolume(MxS32 p_volume) +void MxMusicManager::SetVolume(MxS32 p_volume) { MxAudioManager::SetVolume(p_volume); this->m_criticalSection.Enter(); @@ -118,7 +118,7 @@ void MxMIDIManager::SetVolume(MxS32 p_volume) } // OFFSET: LEGO1 0x100c0840 -MxResult MxMIDIManager::StartMIDIThread(MxU32 p_frequencyMS, MxBool p_noRegister) +MxResult MxMusicManager::StartMIDIThread(MxU32 p_frequencyMS, MxBool p_noRegister) { MxResult status = FAILURE; MxBool locked = FALSE; diff --git a/LEGO1/mxmusicmanager.h b/LEGO1/mxmusicmanager.h index 4288ed1e..1a828c84 100644 --- a/LEGO1/mxmusicmanager.h +++ b/LEGO1/mxmusicmanager.h @@ -1,11 +1,42 @@ #ifndef MXMUSICMANAGER_H #define MXMUSICMANAGER_H -#include "mxcore.h" +#include "decomp.h" +#include "mxaudiomanager.h" // VTABLE 0x100dc930 -class MxMusicManager : public MxCore +// SIZE 0x58 +class MxMusicManager : public MxAudioManager { +public: + MxMusicManager(); + virtual ~MxMusicManager() override; + + virtual void Destroy() override; // vtable+18 + virtual void SetVolume(MxS32 p_volume) override; // vtable+2c + virtual MxResult StartMIDIThread(MxU32 p_frequencyMS, MxU8 p_noRegister); // vtable+30 + +private: + void LockedReinitialize(MxBool p_skipDestroy); + void DeinitializeMIDI(); + + MxS32 CalculateVolume(MxS32 p_volume); + void SetMIDIVolume(); + + HMIDISTRM m_MIDIStreamH; // 0x30 + MxBool m_MIDIInitialized; // 0x34 + undefined4 m_unk38; // 0x38 + undefined4 m_unk3c; // 0x3c + undefined4 m_unk40; // 0x40 + undefined4 m_unk44; // 0x44 + undefined4 m_unk48; // 0x48 + MIDIHDR *m_MIDIHdrP; // 0x4c + MxS32 m_multiplier; // 0x50 + DWORD m_MIDIVolume; // 0x54 + +protected: + void Init(); + void InitData(); }; -#endif // MXMUSICMANAGER_H +#endif // MXMUSICMANAGER_H \ No newline at end of file From 5164ef1a546d4bbb4e997380d6e53d6c91e836a8 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 7 Oct 2023 11:30:04 -0400 Subject: [PATCH 62/87] Refactor MxOmni/LegoOmni headers to use forward declarations (#148) * Refactor MxOmni/LegoOmni headers to use forward declarations * Fixes * Fix build * Fix deps --- ISLE/isleapp.cpp | 13 ++++++++++++- LEGO1/legofullscreenmovie.cpp | 4 +++- LEGO1/legogamestate.cpp | 2 ++ LEGO1/legonavcontroller.cpp | 1 + LEGO1/legoomni.cpp | 4 +++- LEGO1/legoomni.h | 31 +++++++++++++++---------------- LEGO1/mxdisplaysurface.cpp | 2 ++ LEGO1/mxdsaction.cpp | 5 +++-- LEGO1/mxmusicmanager.cpp | 2 ++ LEGO1/mxnotificationmanager.cpp | 5 +++-- LEGO1/mxomni.cpp | 12 ++++++++++++ LEGO1/mxomni.h | 30 ++++++++++++++++-------------- LEGO1/mxpalette.cpp | 2 ++ LEGO1/mxpresenter.cpp | 7 +++++-- LEGO1/mxsoundmanager.cpp | 2 +- LEGO1/mxstreamer.cpp | 5 +++-- LEGO1/mxthread.cpp | 5 +++-- LEGO1/mxtransitionmanager.cpp | 8 +++++++- LEGO1/mxtransitionmanager.h | 2 ++ LEGO1/skateboard.cpp | 2 ++ 20 files changed, 99 insertions(+), 45 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index c20f1652..87f3ebe2 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -3,14 +3,25 @@ #include -#include "legoomni.h" #include "legoanimationmanager.h" #include "legobuildingmanager.h" +#include "legogamestate.h" +#include "legoinputmanager.h" #include "legomodelpresenter.h" +#include "legoomni.h" #include "legopartpresenter.h" +#include "legoroi.h" +#include "legovideomanager.h" #include "legoworldpresenter.h" +#include "mxbackgroundaudiomanager.h" #include "mxdirectdraw.h" #include "mxdsaction.h" +#include "mxomnicreateflags.h" +#include "mxomnicreateparam.h" +#include "mxstreamer.h" +#include "mxticklemanager.h" +#include "mxtimer.h" +#include "mxtransitionmanager.h" #include "res/resource.h" diff --git a/LEGO1/legofullscreenmovie.cpp b/LEGO1/legofullscreenmovie.cpp index f2a287f3..cb803133 100644 --- a/LEGO1/legofullscreenmovie.cpp +++ b/LEGO1/legofullscreenmovie.cpp @@ -1,6 +1,8 @@ #include "legofullscreenmovie.h" -#include "mxtypes.h" + #include "legoomni.h" +#include "legovideomanager.h" +#include "mxtypes.h" #include "decomp.h" DECOMP_SIZE_ASSERT(LegoFullScreenMovie, 0x24) diff --git a/LEGO1/legogamestate.cpp b/LEGO1/legogamestate.cpp index 0f444f95..a08ce8e2 100644 --- a/LEGO1/legogamestate.cpp +++ b/LEGO1/legogamestate.cpp @@ -1,5 +1,7 @@ #include "legogamestate.h" + #include "legoomni.h" +#include "mxvariabletable.h" #include "decomp.h" // Based on the highest dword offset (0x42c) referenced in the constructor. diff --git a/LEGO1/legonavcontroller.cpp b/LEGO1/legonavcontroller.cpp index 90c0a485..1f056f59 100644 --- a/LEGO1/legonavcontroller.cpp +++ b/LEGO1/legonavcontroller.cpp @@ -1,6 +1,7 @@ #include "legonavcontroller.h" #include "legoomni.h" +#include "legovideomanager.h" #include "legoutil.h" // 0x100f4c28 diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index 58eed5c1..2bff73af 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -1,6 +1,8 @@ #include "legoomni.h" -#include "mxdsobject.h" +#include "mxbackgroundaudiomanager.h" +#include "mxdsfile.h" +#include "legogamestate.h" // 0x100f4588 char *g_nocdSourceName = NULL; diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 044275b4..122c77de 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -2,25 +2,24 @@ #define LEGOOMNI_H #include "compat.h" -#include "legoentity.h" -#include "legoinputmanager.h" -#include "legogamestate.h" -#include "legonavcontroller.h" -#include "legopathboundary.h" -#include "legoroi.h" -#include "legovideomanager.h" -#include "mxatomid.h" -#include "mxbackgroundaudiomanager.h" -#include "mxdsaction.h" -#include "mxdsfile.h" -#include "mxdsobject.h" #include "mxomni.h" -#include "mxtransitionmanager.h" -#include "isle.h" -#include "legobuildingmanager.h" -#include "legoplantmanager.h" +#include "mxdsaction.h" +class Isle; +class LegoBuildingManager; +class LegoEntity; +class LegoGameState; +class LegoInputManager; +class LegoNavController; +class LegoPathBoundary; +class LegoPlantManager; +class LegoROI; class LegoSoundManager; +class LegoVideoManager; +class LegoWorld; +class MxAtomId; +class MxBackgroundAudioManager; +class MxDSFile; class MxTransitionManager; // VTABLE 0x100d8638 diff --git a/LEGO1/mxdisplaysurface.cpp b/LEGO1/mxdisplaysurface.cpp index e22244c5..05a50475 100644 --- a/LEGO1/mxdisplaysurface.cpp +++ b/LEGO1/mxdisplaysurface.cpp @@ -1,5 +1,7 @@ #include "mxdisplaysurface.h" + #include "mxomni.h" +#include "mxvideomanager.h" DECOMP_SIZE_ASSERT(MxDisplaySurface, 0xac); diff --git a/LEGO1/mxdsaction.cpp b/LEGO1/mxdsaction.cpp index 3411a460..0ac01543 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -1,10 +1,11 @@ #include "mxdsaction.h" +#include "mxomni.h" +#include "mxtimer.h" + #include #include -#include "mxomni.h" - DECOMP_SIZE_ASSERT(MxDSAction, 0x94) // GLOBAL OFFSET: LEGO1 0x10101410 diff --git a/LEGO1/mxmusicmanager.cpp b/LEGO1/mxmusicmanager.cpp index 247b6596..6f49adcc 100644 --- a/LEGO1/mxmusicmanager.cpp +++ b/LEGO1/mxmusicmanager.cpp @@ -1,5 +1,7 @@ #include "mxmusicmanager.h" +#include "mxticklemanager.h" #include "mxomni.h" + #include DECOMP_SIZE_ASSERT(MxMusicManager, 0x58); diff --git a/LEGO1/mxnotificationmanager.cpp b/LEGO1/mxnotificationmanager.cpp index 1b097067..cb653ba4 100644 --- a/LEGO1/mxnotificationmanager.cpp +++ b/LEGO1/mxnotificationmanager.cpp @@ -1,7 +1,8 @@ +#include "mxnotificationmanager.h" + #include "legoomni.h" #include "mxautolocker.h" -#include "mxcore.h" -#include "mxnotificationmanager.h" +#include "mxticklemanager.h" #include "mxparam.h" #include "mxtypes.h" diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index ed870b34..c4d6d471 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -1,5 +1,17 @@ #include "mxomni.h" +#include "mxatomidcounter.h" +#include "mxeventmanager.h" +#include "mxmusicmanager.h" +#include "mxnotificationmanager.h" +#include "mxobjectfactory.h" +#include "mxomnicreateparam.h" +#include "mxsoundmanager.h" +#include "mxstreamer.h" +#include "mxticklemanager.h" +#include "mxtimer.h" +#include "mxvideomanager.h" + // 0x101015b8 char g_hdPath[1024]; diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 9c7d6b0a..585068ce 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -1,21 +1,23 @@ #ifndef MXOMNI_H #define MXOMNI_H +#include "mxcore.h" +#include "mxstring.h" #include "mxcriticalsection.h" -#include "mxdsaction.h" -#include "mxeventmanager.h" -#include "mxmusicmanager.h" -#include "mxnotificationmanager.h" -#include "mxobjectfactory.h" -#include "mxomnicreateflags.h" -#include "mxomnicreateparam.h" -#include "mxsoundmanager.h" -#include "mxstreamer.h" -#include "mxticklemanager.h" -#include "mxtimer.h" -#include "mxvariabletable.h" -#include "mxvideomanager.h" -#include "mxatomidcounter.h" + +class MxAtomIdCounterSet; +class MxDSAction; +class MxEventManager; +class MxMusicManager; +class MxNotificationManager; +class MxObjectFactory; +class MxOmniCreateParam; +class MxSoundManager; +class MxStreamer; +class MxTickleManager; +class MxTimer; +class MxVariableTable; +class MxVideoManager; // VTABLE 0x100dc168 // SIZE 0x68 diff --git a/LEGO1/mxpalette.cpp b/LEGO1/mxpalette.cpp index 7fb02f4f..cdd1597f 100644 --- a/LEGO1/mxpalette.cpp +++ b/LEGO1/mxpalette.cpp @@ -1,5 +1,7 @@ #include "mxpalette.h" + #include "mxomni.h" +#include "mxvideomanager.h" // GLOBAL: LEGO1 0x10102188 0x400 PALETTEENTRY g_defaultPaletteEntries[256] = diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index b57af821..5afafc79 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -1,14 +1,17 @@ #include "mxpresenter.h" + +#include "legoomni.h" #include "mxautolocker.h" #include "mxparam.h" -#include "legoomni.h" #include "mxdsanim.h" #include "mxdssound.h" -#include +#include "mxnotificationmanager.h" #include "decomp.h" #include "define.h" +#include + DECOMP_SIZE_ASSERT(MxPresenter, 0x40); // OFFSET: LEGO1 0x100b4d50 diff --git a/LEGO1/mxsoundmanager.cpp b/LEGO1/mxsoundmanager.cpp index 16d504ce..466843e3 100644 --- a/LEGO1/mxsoundmanager.cpp +++ b/LEGO1/mxsoundmanager.cpp @@ -1,5 +1,5 @@ #include "mxsoundmanager.h" - +#include "mxticklemanager.h" #include "mxomni.h" DECOMP_SIZE_ASSERT(MxSoundManager, 0x3c); diff --git a/LEGO1/mxstreamer.cpp b/LEGO1/mxstreamer.cpp index 53d7303f..eef989bc 100644 --- a/LEGO1/mxstreamer.cpp +++ b/LEGO1/mxstreamer.cpp @@ -1,10 +1,11 @@ #include "mxstreamer.h" -#include - #include "legoomni.h" #include "mxdiskstreamcontroller.h" #include "mxramstreamcontroller.h" +#include "mxnotificationmanager.h" + +#include DECOMP_SIZE_ASSERT(MxStreamer, 0x2c); diff --git a/LEGO1/mxthread.cpp b/LEGO1/mxthread.cpp index b63019ed..fed82eca 100644 --- a/LEGO1/mxthread.cpp +++ b/LEGO1/mxthread.cpp @@ -1,9 +1,10 @@ #include "mxthread.h" -#include - #include "mxomni.h" +#include "mxtimer.h" + +#include // OFFSET: LEGO1 0x100bf690 MxResult MxThread::Run() diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index d34df54f..8d52266c 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -1,6 +1,12 @@ #include "mxtransitionmanager.h" -#include "legoutil.h" + #include "legovideomanager.h" +#include "legoinputmanager.h" +#include "legoutil.h" +#include "legoworld.h" +#include "mxbackgroundaudiomanager.h" +#include "mxparam.h" +#include "mxticklemanager.h" DECOMP_SIZE_ASSERT(MxTransitionManager, 0x900); diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 7f1d4ead..b4a9ba30 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -5,6 +5,8 @@ #include "mxvideopresenter.h" #include "legoomni.h" +#include + // VTABLE 0x100d7ea0 class MxTransitionManager : public MxCore { diff --git a/LEGO1/skateboard.cpp b/LEGO1/skateboard.cpp index 5c5cbf38..b67e127e 100644 --- a/LEGO1/skateboard.cpp +++ b/LEGO1/skateboard.cpp @@ -1,5 +1,7 @@ #include "skateboard.h" + #include "mxomni.h" +#include "mxnotificationmanager.h" #include "decomp.h" From 907c85616b1a551379c13d67be641a4da69815b4 Mon Sep 17 00:00:00 2001 From: MS Date: Sat, 7 Oct 2023 12:48:36 -0400 Subject: [PATCH 63/87] Supporting items for SetupCopyRect() (#177) * Minor improvements all related to SetupCopyRect * Rename inline getters. malloc/free -> new/delete * MxTypes in TransitionManager. Remove stub marker (oops) --- LEGO1/mxbitmap.h | 4 ++++ LEGO1/mxdisplaysurface.cpp | 4 ++-- LEGO1/mxdisplaysurface.h | 5 +++-- LEGO1/mxpresenter.h | 12 +++++++----- LEGO1/mxsmkpresenter.cpp | 11 +++++++++++ LEGO1/mxsmkpresenter.h | 7 ++++++- LEGO1/mxtransitionmanager.cpp | 34 +++++++++++++++++----------------- LEGO1/mxtransitionmanager.h | 2 +- LEGO1/mxvideopresenter.cpp | 22 +++++++++++----------- LEGO1/mxvideopresenter.h | 16 +++++++++++++--- 10 files changed, 75 insertions(+), 42 deletions(-) diff --git a/LEGO1/mxbitmap.h b/LEGO1/mxbitmap.h index ba90b7da..791581c6 100644 --- a/LEGO1/mxbitmap.h +++ b/LEGO1/mxbitmap.h @@ -25,6 +25,8 @@ struct MxBITMAPINFO { #define LOWCOLOR 0 // 256 color #define HIGHCOLOR 1 // High Color (16-bit) +// SIZE 0x20 +// VTABLE 0x100dc7b0 class MxBitmap : public MxCore { public: @@ -44,6 +46,8 @@ class MxBitmap : public MxCore virtual MxResult SetBitDepth(MxBool); // vtable+3c virtual MxResult StretchBits(HDC p_hdc, int p_xSrc, int p_ySrc, int p_xDest, int p_yDest, int p_destWidth, int p_destHeight); // vtable+40 + inline BITMAPINFOHEADER *GetBmiHeader() const { return m_bmiHeader; } + private: MxResult ImportColorsToPalette(RGBQUAD*, MxPalette*); diff --git a/LEGO1/mxdisplaysurface.cpp b/LEGO1/mxdisplaysurface.cpp index 05a50475..af7e57db 100644 --- a/LEGO1/mxdisplaysurface.cpp +++ b/LEGO1/mxdisplaysurface.cpp @@ -176,7 +176,7 @@ void MxDisplaySurface::SetPalette(MxPalette *p_palette) } // OFFSET: LEGO1 0x100bc200 STUB -void MxDisplaySurface::vtable24(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4) +void MxDisplaySurface::vtable24(LPDDSURFACEDESC, MxBitmap*, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4) { } @@ -188,7 +188,7 @@ MxBool MxDisplaySurface::vtable28(undefined4, undefined4, undefined4, undefined4 } // OFFSET: LEGO1 0x100bc630 STUB -MxBool MxDisplaySurface::vtable2c(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool) +MxBool MxDisplaySurface::vtable2c(LPDDSURFACEDESC, MxBitmap*, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool) { return 0; } diff --git a/LEGO1/mxdisplaysurface.h b/LEGO1/mxdisplaysurface.h index 8e79f6e8..8a80a0f4 100644 --- a/LEGO1/mxdisplaysurface.h +++ b/LEGO1/mxdisplaysurface.h @@ -3,6 +3,7 @@ #include +#include "mxbitmap.h" #include "mxcore.h" #include "mxpalette.h" #include "mxvideoparam.h" @@ -25,9 +26,9 @@ class MxDisplaySurface : public MxCore virtual MxResult Create(MxVideoParam &p_videoParam); virtual void Clear(); virtual void SetPalette(MxPalette *p_palette); - virtual void vtable24(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); + virtual void vtable24(LPDDSURFACEDESC, MxBitmap*, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual MxBool vtable28(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); - virtual MxBool vtable2c(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); + virtual MxBool vtable2c(LPDDSURFACEDESC, MxBitmap*, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); virtual MxBool vtable30(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); virtual undefined4 vtable34(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual void Display(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 81ea14ad..156065f4 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -68,17 +68,19 @@ class MxPresenter : public MxCore MxBool IsEnabled(); - inline MxS32 GetCurrentTickleState() { return this->m_currentTickleState; } - inline MxPoint32 GetLocation() { return this->m_location; } - inline MxS32 GetDisplayZ() { return this->m_displayZ; } - inline MxDSAction *GetAction() { return this->m_action; } + inline MxS32 GetCurrentTickleState() const { return this->m_currentTickleState; } + inline MxPoint32 GetLocation() const { return this->m_location; } + inline MxS32 GetLocationX() const { return this->m_location.m_x; } + inline MxS32 GetLocationY() const { return this->m_location.m_y; } + inline MxS32 GetDisplayZ() const { return this->m_displayZ; } + inline MxDSAction *GetAction() const { return this->m_action; } protected: __declspec(dllexport) void Init(); void SendTo_unkPresenter(MxOmni *); private: - MxS32 m_currentTickleState; // 0x8 + TickleState m_currentTickleState; // 0x8 MxU32 m_previousTickleStates; MxPoint32 m_location; MxS32 m_displayZ; diff --git a/LEGO1/mxsmkpresenter.cpp b/LEGO1/mxsmkpresenter.cpp index cc7efec1..99faae22 100644 --- a/LEGO1/mxsmkpresenter.cpp +++ b/LEGO1/mxsmkpresenter.cpp @@ -15,3 +15,14 @@ void MxSmkPresenter::Init() { // TODO } + +// OFFSET: LEGO1 0x100b3960 +void MxSmkPresenter::VTable0x60() +{ + if (m_bitmap) { + delete m_bitmap; + } + + m_bitmap = new MxBitmap(); + m_bitmap->SetSize(m_smkWidth, m_smkHeight, NULL, NULL); +} diff --git a/LEGO1/mxsmkpresenter.h b/LEGO1/mxsmkpresenter.h index 325091bb..34a78dab 100644 --- a/LEGO1/mxsmkpresenter.h +++ b/LEGO1/mxsmkpresenter.h @@ -12,7 +12,12 @@ class MxSmkPresenter : public MxVideoPresenter public: MxSmkPresenter(); - undefined4 m_unk64[430]; + virtual void VTable0x60() override; + + undefined4 m_unk64; + MxS32 m_smkWidth; // 0x68 + MxS32 m_smkHeight; // 0x6c + undefined4 m_unk70[427]; undefined4 m_unk71c; private: void Init(); diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 8d52266c..d7d16544 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -29,7 +29,7 @@ MxTransitionManager::MxTransitionManager() // OFFSET: LEGO1 0x1004ba00 MxTransitionManager::~MxTransitionManager() { - free(m_copyBuffer); + delete[] m_copyBuffer; if (m_waitIndicator != NULL) { delete m_waitIndicator->GetAction(); @@ -324,17 +324,17 @@ void MxTransitionManager::SubmitCopyRect(LPDDSURFACEDESC ddsc) } // Copy the copy rect onto the surface - char *dst; + MxU8 *dst; - DWORD bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; + MxU32 bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; - const char *src = (const char *)m_copyBuffer; + const MxU8 *src = (const MxU8 *)m_copyBuffer; - LONG copyPitch; + MxS32 copyPitch; copyPitch = ((m_copyRect.right - m_copyRect.left) + 1) * bytesPerPixel; - LONG y; - dst = (char *)ddsc->lpSurface + (ddsc->lPitch * m_copyRect.top) + (bytesPerPixel * m_copyRect.left); + MxS32 y; + dst = (MxU8 *)ddsc->lpSurface + (ddsc->lPitch * m_copyRect.top) + (bytesPerPixel * m_copyRect.left); for (y = 0; y < m_copyRect.bottom - m_copyRect.top + 1; ++y) { memcpy(dst, src, copyPitch); @@ -343,7 +343,7 @@ void MxTransitionManager::SubmitCopyRect(LPDDSURFACEDESC ddsc) } // Free the copy buffer - free(m_copyBuffer); + delete[] m_copyBuffer; m_copyBuffer = NULL; } @@ -361,11 +361,11 @@ void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc) // Check if wait indicator has started if (m_waitIndicator->GetCurrentTickleState() >= MxPresenter::TickleState_Streaming) { // Setup the copy rect - DWORD copyPitch = (ddsc->ddpfPixelFormat.dwRGBBitCount / 8) * (m_copyRect.right - m_copyRect.left + 1); // This uses m_copyRect, seemingly erroneously - DWORD bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; + MxU32 copyPitch = (ddsc->ddpfPixelFormat.dwRGBBitCount / 8) * (m_copyRect.right - m_copyRect.left + 1); // This uses m_copyRect, seemingly erroneously + MxU32 bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; - m_copyRect.left = m_waitIndicator->GetLocation().m_x; - m_copyRect.top = m_waitIndicator->GetLocation().m_y; + m_copyRect.left = m_waitIndicator->GetLocationX(); + m_copyRect.top = m_waitIndicator->GetLocationY(); MxS32 height = m_waitIndicator->GetHeight(); MxS32 width = m_waitIndicator->GetWidth(); @@ -374,14 +374,14 @@ void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc) m_copyRect.bottom = m_copyRect.top + height - 1; // Allocate the copy buffer - const char *src = (const char*)ddsc->lpSurface + m_copyRect.top * ddsc->lPitch + bytesPerPixel * m_copyRect.left; + const MxU8 *src = (const MxU8*)ddsc->lpSurface + m_copyRect.top * ddsc->lPitch + bytesPerPixel * m_copyRect.left; - m_copyBuffer = malloc(bytesPerPixel * width * height); + m_copyBuffer = new MxU8[bytesPerPixel * width * height]; if (!m_copyBuffer) return; // Copy into the copy buffer - char *dst = (char*)m_copyBuffer; + MxU8 *dst = m_copyBuffer; for (MxS32 i = 0; i < (m_copyRect.bottom - m_copyRect.top + 1); i++) { @@ -396,11 +396,11 @@ void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc) { MxDisplaySurface *displaySurface = VideoManager()->GetDisplaySurface(); MxBool unkbool = FALSE; - displaySurface->vtable2c(ddsc, m_waitIndicator->m_unk50, 0, 0, m_waitIndicator->GetLocation().m_x, m_waitIndicator->GetLocation().m_y, m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight(), unkbool); + displaySurface->vtable2c(ddsc, m_waitIndicator->m_bitmap, 0, 0, m_waitIndicator->GetLocationX(), m_waitIndicator->GetLocationY(), m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight(), unkbool); } else { MxDisplaySurface *displaySurface = VideoManager()->GetDisplaySurface(); - displaySurface->vtable24(ddsc, m_waitIndicator->m_unk50, 0, 0, m_waitIndicator->GetLocation().m_x, m_waitIndicator->GetLocation().m_y, m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight()); + displaySurface->vtable24(ddsc, m_waitIndicator->m_bitmap, 0, 0, m_waitIndicator->GetLocationX(), m_waitIndicator->GetLocationY(), m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight()); } } diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index b4a9ba30..58a8079e 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -59,7 +59,7 @@ class MxTransitionManager : public MxCore MxVideoPresenter *m_waitIndicator; RECT m_copyRect; - void *m_copyBuffer; + MxU8 *m_copyBuffer; flag_bitfield m_copyFlags; undefined4 m_unk24; diff --git a/LEGO1/mxvideopresenter.cpp b/LEGO1/mxvideopresenter.cpp index fe83a2dc..42dc34f3 100644 --- a/LEGO1/mxvideopresenter.cpp +++ b/LEGO1/mxvideopresenter.cpp @@ -8,10 +8,10 @@ void MxVideoPresenter::VTable0x5c() // TODO } -// OFFSET: LEGO1 0x1000c710 STUB +// OFFSET: LEGO1 0x1000c710 void MxVideoPresenter::VTable0x60() { - // TODO + // Empty } // OFFSET: LEGO1 0x1000c720 STUB @@ -44,24 +44,24 @@ void MxVideoPresenter::VTable0x78() // TODO } -// OFFSET: LEGO1 0x1000c7c0 STUB -void MxVideoPresenter::VTable0x7c() +// OFFSET: LEGO1 0x1000c7c0 +MxBool MxVideoPresenter::VTable0x7c() { - // TODO + return (m_bitmap != NULL) || (m_unk54 != NULL); } -// OFFSET: LEGO1 0x1000c7e0 STUB +// OFFSET: LEGO1 0x1000c7e0 MxS32 MxVideoPresenter::GetWidth() { - // TODO - return 0; + return m_unk54 ? m_unk54->width + : m_bitmap->GetBmiHeader()->biWidth; } -// OFFSET: LEGO1 0x1000c800 STUB +// OFFSET: LEGO1 0x1000c800 MxS32 MxVideoPresenter::GetHeight() { - // TODO - return 0; + return m_unk54 ? m_unk54->height + : m_bitmap->GetBmiHeader()->biHeight; } // OFFSET: LEGO1 0x100b2760 STUB diff --git a/LEGO1/mxvideopresenter.h b/LEGO1/mxvideopresenter.h index 84822f71..9c9a21a3 100644 --- a/LEGO1/mxvideopresenter.h +++ b/LEGO1/mxvideopresenter.h @@ -2,9 +2,11 @@ #define MXVIDEOPRESENTER_H #include "mxmediapresenter.h" +#include "mxbitmap.h" #include "decomp.h" +// VTABLE 0x100d4be8 class MxVideoPresenter : public MxMediaPresenter { public: @@ -41,12 +43,20 @@ class MxVideoPresenter : public MxMediaPresenter virtual void VTable0x70(); // vtable+0x70 virtual void VTable0x74(); // vtable+0x74 virtual void VTable0x78(); // vtable+0x78 - virtual void VTable0x7c(); // vtable+0x7c + virtual MxBool VTable0x7c(); // vtable+0x7c virtual MxS32 GetWidth(); // vtable+0x80 virtual MxS32 GetHeight(); // vtable+0x84 - undefined4 m_unk50; - undefined4 m_unk54; + // TODO: Not sure what this is. Seems to have size of 12 bytes + // based on 0x100b9e9a. Values are copied from the bitmap header. + typedef struct { + undefined unk0[8]; + MxU16 width; + MxU16 height; + } unknown_meta_struct; + + MxBitmap *m_bitmap; + unknown_meta_struct *m_unk54; undefined4 m_unk58; undefined2 m_unk5c; unsigned char m_flags; // 0x5e From 8281e195f708d6e3d36176d9ec471929619c6c5a Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sat, 7 Oct 2023 13:12:59 -0400 Subject: [PATCH 64/87] Implement MxOmni Start/stop timer (#181) * Implement start/stop timer * Mark StartDirectSound as stub * remove accidently committed files --- ISLE/isleapp.cpp | 4 ++-- LEGO1/legoomni.cpp | 11 ++++++++--- LEGO1/legoomni.h | 2 +- LEGO1/mxomni.cpp | 24 +++++++++++++++++------- LEGO1/mxomni.h | 4 ++-- LEGO1/mxsoundmanager.cpp | 21 ++++++++++++++++++++- LEGO1/mxsoundmanager.h | 4 ++++ 7 files changed, 54 insertions(+), 16 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 87f3ebe2..9aefae60 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -104,7 +104,7 @@ void IsleApp::Close() Lego()->RemoveWorld(ds.GetAtomId(), ds.GetObjectId()); Lego()->DeleteObject(ds); TransitionManager()->SetWaitIndicator(NULL); - Lego()->vtable0x3c(); + Lego()->StopTimer(); MxLong lVar8; do { @@ -243,7 +243,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine g_reqEnableRMDevice = 0; VideoManager()->EnableRMDevice(); g_rmDisabled = 0; - Lego()->vtable0x3c(); + Lego()->StopTimer(); } if (g_closed) { diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index 2bff73af..f4480bb8 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -3,6 +3,7 @@ #include "mxbackgroundaudiomanager.h" #include "mxdsfile.h" #include "legogamestate.h" +#include "legoutil.h" // 0x100f4588 char *g_nocdSourceName = NULL; @@ -307,14 +308,18 @@ void LegoOmni::NotifyCurrentEntity() // FIXME: Stub } +// OFFSET: LEGO1 0x1005b640 void LegoOmni::StartTimer() { - // FIXME: Stub + MxOmni::StartTimer(); + SetAppCursor(2); } -void LegoOmni::vtable0x3c() +// OFFSET: LEGO1 0x1005b650 +void LegoOmni::StopTimer() { - // FIXME: Stub + MxOmni::StopTimer(); + SetAppCursor(0); } MxBool LegoOmni::vtable40() diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 122c77de..4de0d1b5 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -61,7 +61,7 @@ class LegoOmni : public MxOmni virtual int vtable0x30(char*, int, MxCore*) override; virtual void NotifyCurrentEntity() override; virtual void StartTimer() override; - virtual void vtable0x3c() override; + virtual void StopTimer() override; virtual MxBool vtable40(); LegoVideoManager *GetVideoManager() { return (LegoVideoManager *) m_videoManager; } diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index c4d6d471..d1db1398 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -2,7 +2,7 @@ #include "mxatomidcounter.h" #include "mxeventmanager.h" -#include "mxmusicmanager.h" +#include "mxmusicmanager.h" #include "mxnotificationmanager.h" #include "mxobjectfactory.h" #include "mxomnicreateparam.h" @@ -51,7 +51,7 @@ void MxOmni::Init() m_timer = NULL; m_streamer = NULL; m_atomIdCounterSet = NULL; - m_unk64 = NULL; + m_timerRunning = NULL; } // OFFSET: LEGO1 0x100b0090 @@ -98,16 +98,26 @@ void MxOmni::NotifyCurrentEntity() // TODO } -// OFFSET: LEGO1 0x100b09d0 STUB +// OFFSET: LEGO1 0x100b09d0 void MxOmni::StartTimer() { - // TODO + if (m_timerRunning == FALSE && m_timer != NULL && m_soundManager != NULL) + { + m_timer->Start(); + m_soundManager->vtable0x34(); + m_timerRunning = TRUE; + } } -// OFFSET: LEGO1 0x100b0a00 STUB -void MxOmni::vtable0x3c() +// OFFSET: LEGO1 0x100b0a00 +void MxOmni::StopTimer() { - // TODO + if (m_timerRunning != FALSE && m_timer != NULL && m_soundManager != NULL) + { + m_timer->Stop(); + m_soundManager->vtable0x38(); + m_timerRunning = FALSE; + } } // OFFSET: LEGO1 0x100b0690 diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 585068ce..66682842 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -47,7 +47,7 @@ class MxOmni : public MxCore virtual int vtable0x30(char*, int, MxCore*); // vtable+30 virtual void NotifyCurrentEntity(); // vtable+34 virtual void StartTimer(); // vtable+38 - virtual void vtable0x3c(); // vtable+3c + virtual void StopTimer(); // vtable+3c static void SetInstance(MxOmni* instance); HWND GetWindowHandle() const { return this->m_windowHandle; } MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; } @@ -81,7 +81,7 @@ class MxOmni : public MxCore MxCriticalSection m_criticalsection; // 0x48 - unsigned char m_unk64; // 0x64 + MxBool m_timerRunning; // 0x64 }; __declspec(dllexport) MxTickleManager * TickleManager(); __declspec(dllexport) MxTimer * Timer(); diff --git a/LEGO1/mxsoundmanager.cpp b/LEGO1/mxsoundmanager.cpp index 466843e3..e34534f9 100644 --- a/LEGO1/mxsoundmanager.cpp +++ b/LEGO1/mxsoundmanager.cpp @@ -46,4 +46,23 @@ void MxSoundManager::Destroy(MxBool p_param) if (!p_param) { MxAudioManager::Destroy(); } -} \ No newline at end of file +} + +// OFFSET: LEGO1 0x100ae8b0 STUB +MxResult MxSoundManager::StartDirectSound(undefined4 p_unknown1, MxBool p_unknown2) +{ + // TODO STUB + return FAILURE; +} + +// OFFSET: LEGO1 0x100aed10 STUB +void MxSoundManager::vtable0x34() +{ + // TODO STUB +} + +// OFFSET: LEGO1 0x100aee10 STUB +void MxSoundManager::vtable0x38() +{ + // TODO STUB +} diff --git a/LEGO1/mxsoundmanager.h b/LEGO1/mxsoundmanager.h index d41c6fdb..46eef2e7 100644 --- a/LEGO1/mxsoundmanager.h +++ b/LEGO1/mxsoundmanager.h @@ -14,6 +14,10 @@ class MxSoundManager : public MxAudioManager MxSoundManager(); virtual ~MxSoundManager() override; // vtable+0x0 + virtual MxResult StartDirectSound(undefined4 p_unknown1, MxBool p_unknown2); //vtable+0x30 + virtual void vtable0x34(); // vtable+0x34 + virtual void vtable0x38(); // vtable+0x38 + private: void Init(); void Destroy(MxBool); From 201125d2099d244e556cec4d1d02e837dbdd9a23 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 7 Oct 2023 13:28:52 -0400 Subject: [PATCH 65/87] Silence all C4786 warnings (#180) --- LEGO1/compat.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/LEGO1/compat.h b/LEGO1/compat.h index 33b97d5a..ba0b9d34 100644 --- a/LEGO1/compat.h +++ b/LEGO1/compat.h @@ -18,6 +18,9 @@ // Impossible to avoid this if using STL map or set. // This removes most (but not all) occurrences of the warning. #pragma warning( disable : 4786 ) +// To really remove *all* of the warnings, we have to employ the following, +// obscure workaround from https://www.earthli.com/news/view_article.php?id=376 +static class msVC6_4786WorkAround { public: msVC6_4786WorkAround() {} } msVC6_4786WorkAround; #define MSVC420_VERSION 1020 From e6507b874a477e64e5796bbfb6d147be5a08da5e Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 7 Oct 2023 14:00:20 -0400 Subject: [PATCH 66/87] Refactor vector EqualsScalar (#171) * Refactor vector EqualsScalar * Fix param name --- LEGO1/legoentity.cpp | 8 ++------ LEGO1/mxdsaction.cpp | 19 +++---------------- LEGO1/mxvector.h | 2 ++ 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/LEGO1/legoentity.cpp b/LEGO1/legoentity.cpp index 105b4b5f..e7601cc2 100644 --- a/LEGO1/legoentity.cpp +++ b/LEGO1/legoentity.cpp @@ -23,12 +23,8 @@ MxLong LegoEntity::Notify(MxParam &p) // OFFSET: LEGO1 0x100105f0 void LegoEntity::Reset() { - float value = 0.0f; - m_vec1.EqualsScalar(&value); - - value = 0.0f; - m_vec2.EqualsScalar(&value); - + m_vec1.Fill(0); + m_vec2.Fill(0); m_unk50 = 0; m_unk54 = 0; m_unk58 = 0; diff --git a/LEGO1/mxdsaction.cpp b/LEGO1/mxdsaction.cpp index 0ac01543..1f26c7c9 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -22,22 +22,9 @@ MxDSAction::MxDSAction() this->m_loopCount = -1; this->SetType(MxDSType_Action); - - { - float value = FLT_MAX; - this->m_location.EqualsScalar(&value); - } - - { - float value = FLT_MAX; - this->m_direction.EqualsScalar(&value); - } - - { - float value = FLT_MAX; - this->m_up.EqualsScalar(&value); - } - + this->m_location.Fill(FLT_MAX); + this->m_direction.Fill(FLT_MAX); + this->m_up.Fill(FLT_MAX); this->m_unk84 = 0; this->m_unk88 = 0; this->m_omni = NULL; diff --git a/LEGO1/mxvector.h b/LEGO1/mxvector.h index ae58abd9..eef1d927 100644 --- a/LEGO1/mxvector.h +++ b/LEGO1/mxvector.h @@ -95,6 +95,8 @@ class MxVector3 : public MxVector2 virtual void EqualsCross(MxVector3 *p_a, float *p_b); virtual void EqualsCross(MxVector3 *p_a, MxVector3 *p_b); virtual void EqualsScalar(float *p_value); + + inline void Fill(float p_value) { EqualsScalar(&p_value); } }; // VTABLE 0x100d45a0 From 4a674d823b18817dd35182fcaefef27209429266 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 7 Oct 2023 14:03:15 -0400 Subject: [PATCH 67/87] Implement MxDSSelectAction Clone/operator=/CopyFrom (#154) --- CMakeLists.txt | 1 + LEGO1/mxdsaction.h | 4 ++-- LEGO1/mxdsanim.h | 2 +- LEGO1/mxdschunk.h | 1 - LEGO1/mxdsevent.h | 2 +- LEGO1/mxdsmediaaction.h | 4 ++-- LEGO1/mxdsmultiaction.h | 16 ++++++++-------- LEGO1/mxdsobjectaction.h | 2 +- LEGO1/mxdsparallelaction.h | 4 ++-- LEGO1/mxdsselectaction.cpp | 34 ++++++++++++++++++++++++++++++++++ LEGO1/mxdsselectaction.h | 8 ++++++++ LEGO1/mxdsserialaction.h | 6 +++--- LEGO1/mxdssound.h | 6 +++--- LEGO1/mxdsstill.h | 2 +- LEGO1/mxdsstreamingaction.h | 2 +- LEGO1/mxlist.h | 33 ++++++++++++++++++++++++++------- LEGO1/mxstring.cpp | 8 ++++---- LEGO1/mxstring.h | 2 +- LEGO1/mxstringlist.cpp | 5 +++++ LEGO1/mxstringlist.h | 12 ++++++++++++ 20 files changed, 116 insertions(+), 38 deletions(-) create mode 100644 LEGO1/mxstringlist.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e2135c9..a3573874 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,6 +163,7 @@ add_library(lego1 SHARED LEGO1/mxstreamcontroller.cpp LEGO1/mxstreamer.cpp LEGO1/mxstring.cpp + LEGO1/mxstringlist.cpp LEGO1/mxthread.cpp LEGO1/mxticklemanager.cpp LEGO1/mxtimer.cpp diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 9881f3e2..57d1f200 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -41,8 +41,8 @@ class MxDSAction : public MxDSObject return !strcmp(name, MxDSAction::ClassName()) || MxDSObject::IsA(name); } - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; virtual MxLong GetDuration(); // vtable+24; virtual void SetDuration(MxLong p_duration); // vtable+28; virtual MxDSAction *Clone(); // vtable+2c; diff --git a/LEGO1/mxdsanim.h b/LEGO1/mxdsanim.h index 92890e8e..1bc77558 100644 --- a/LEGO1/mxdsanim.h +++ b/LEGO1/mxdsanim.h @@ -27,7 +27,7 @@ class MxDSAnim : public MxDSMediaAction return !strcmp(name, MxDSAnim::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSANIM_H diff --git a/LEGO1/mxdschunk.h b/LEGO1/mxdschunk.h index f9b1d9d0..367dcb4d 100644 --- a/LEGO1/mxdschunk.h +++ b/LEGO1/mxdschunk.h @@ -1,7 +1,6 @@ #ifndef MXDSCHUNK_H #define MXDSCHUNK_H - #include "mxcore.h" #include "mxtypes.h" diff --git a/LEGO1/mxdsevent.h b/LEGO1/mxdsevent.h index b8fedace..576c8b14 100644 --- a/LEGO1/mxdsevent.h +++ b/LEGO1/mxdsevent.h @@ -25,7 +25,7 @@ class MxDSEvent : public MxDSMediaAction return !strcmp(name, MxDSEvent::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSEVENT_H diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index cc710425..34b6695e 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -28,8 +28,8 @@ class MxDSMediaAction : public MxDSAction return !strcmp(name, MxDSMediaAction::ClassName()) || MxDSAction::IsA(name); } - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; void CopyMediaSrcPath(const char *p_mediaSrcPath); diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 4063343c..1689cc2d 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -28,14 +28,14 @@ class MxDSMultiAction : public MxDSAction return !strcmp(name, MxDSMultiAction::ClassName()) || MxDSAction::IsA(name); } - virtual undefined4 unk14(); // vtable+14; - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; - virtual void SetAtomId(MxAtomId p_atomId); // vtable+20; - virtual MxDSAction *Clone(); // vtable+2c; - virtual void MergeFrom(MxDSAction &p_dsAction); // vtable+30; - virtual MxBool HasId(MxU32 p_objectId); // vtable+34; - virtual void SetSomeTimingField(MxLong p_someTimingField); // vtable+38; + virtual undefined4 unk14() override; // vtable+14; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; + virtual void SetAtomId(MxAtomId p_atomId) override; // vtable+20; + virtual MxDSAction *Clone() override; // vtable+2c; + virtual void MergeFrom(MxDSAction &p_dsAction) override; // vtable+30; + virtual MxBool HasId(MxU32 p_objectId) override; // vtable+34; + virtual void SetSomeTimingField(MxLong p_someTimingField) override; // vtable+38; private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxdsobjectaction.h b/LEGO1/mxdsobjectaction.h index 4a1b68bb..07f35758 100644 --- a/LEGO1/mxdsobjectaction.h +++ b/LEGO1/mxdsobjectaction.h @@ -26,7 +26,7 @@ class MxDSObjectAction : public MxDSMediaAction return !strcmp(name, MxDSObjectAction::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; virtual void CopyFrom(MxDSObjectAction &p_dsObjectAction); // vtable+44; }; diff --git a/LEGO1/mxdsparallelaction.h b/LEGO1/mxdsparallelaction.h index 962ba34b..e28bfe58 100644 --- a/LEGO1/mxdsparallelaction.h +++ b/LEGO1/mxdsparallelaction.h @@ -27,8 +27,8 @@ class MxDSParallelAction : public MxDSMultiAction return !strcmp(name, MxDSParallelAction::ClassName()) || MxDSMultiAction::IsA(name); } - virtual MxLong GetDuration(); // vtable+24; - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxLong GetDuration() override; // vtable+24; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSPARALLELACTION_H diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 29f69022..58af9543 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -15,3 +15,37 @@ MxDSSelectAction::~MxDSSelectAction() if (this->m_unk0xac) delete this->m_unk0xac; } + +// OFFSET: LEGO1 0x100cb950 +void MxDSSelectAction::CopyFrom(MxDSSelectAction &p_dsSelectAction) +{ + this->m_unk0x9c = p_dsSelectAction.m_unk0x9c; + + this->m_unk0xac->DeleteAll(); + + MxStringListCursor cursor(p_dsSelectAction.m_unk0xac); + MxString string; + while (cursor.Next(string)) + this->m_unk0xac->OtherAppend(string); +} + +// OFFSET: LEGO1 0x100cbd50 +MxDSSelectAction &MxDSSelectAction::operator=(MxDSSelectAction &p_dsSelectAction) +{ + if (this != &p_dsSelectAction) { + MxDSParallelAction::operator=(p_dsSelectAction); + this->CopyFrom(p_dsSelectAction); + } + return *this; +} + +// OFFSET: LEGO1 0x100cbd80 +MxDSAction *MxDSSelectAction::Clone() +{ + MxDSSelectAction *clone = new MxDSSelectAction(); + + if (clone) + *clone = *this; + + return clone; +} \ No newline at end of file diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index d513efd0..746afc87 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -13,6 +13,9 @@ class MxDSSelectAction : public MxDSParallelAction MxDSSelectAction(); virtual ~MxDSSelectAction() override; + void CopyFrom(MxDSSelectAction &p_dsSelectAction); + MxDSSelectAction &operator=(MxDSSelectAction &p_dsSelectAction); + // OFFSET: LEGO1 0x100cb6f0 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -26,6 +29,11 @@ class MxDSSelectAction : public MxDSParallelAction return !strcmp(name, MxDSSelectAction::ClassName()) || MxDSParallelAction::IsA(name); } + //virtual MxU32 GetSizeOnDisk() override; // vtable+18; + //virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; + //virtual MxLong GetDuration() override; // vtable+24; + virtual MxDSAction *Clone() override; // vtable+2c; + private: MxString m_unk0x9c; MxStringList *m_unk0xac; diff --git a/LEGO1/mxdsserialaction.h b/LEGO1/mxdsserialaction.h index e2f6cd72..4e383681 100644 --- a/LEGO1/mxdsserialaction.h +++ b/LEGO1/mxdsserialaction.h @@ -28,9 +28,9 @@ class MxDSSerialAction : public MxDSMultiAction return !strcmp(name, MxDSSerialAction::ClassName()) || MxDSMultiAction::IsA(name); } - virtual MxLong GetDuration(); // vtable+24; - virtual void SetDuration(MxLong p_duration); // vtable+28; - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxLong GetDuration() override; // vtable+24; + virtual void SetDuration(MxLong p_duration) override; // vtable+28; + virtual MxDSAction *Clone() override; // vtable+2c; private: MxDSActionListCursor *m_cursor; diff --git a/LEGO1/mxdssound.h b/LEGO1/mxdssound.h index de345e51..514ef1ec 100644 --- a/LEGO1/mxdssound.h +++ b/LEGO1/mxdssound.h @@ -27,9 +27,9 @@ class MxDSSound : public MxDSMediaAction return !strcmp(name, MxDSSound::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; + virtual MxDSAction *Clone() override; // vtable+2c; private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxdsstill.h b/LEGO1/mxdsstill.h index 084fe931..3b29c287 100644 --- a/LEGO1/mxdsstill.h +++ b/LEGO1/mxdsstill.h @@ -27,7 +27,7 @@ class MxDSStill : public MxDSMediaAction return !strcmp(name, MxDSStill::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSSTILL_H diff --git a/LEGO1/mxdsstreamingaction.h b/LEGO1/mxdsstreamingaction.h index d50dbed8..f95621eb 100644 --- a/LEGO1/mxdsstreamingaction.h +++ b/LEGO1/mxdsstreamingaction.h @@ -24,7 +24,7 @@ class MxDSStreamingAction : public MxDSAction return *this; } - virtual MxBool HasId(MxU32 p_objectId); // vtable+34; + virtual MxBool HasId(MxU32 p_objectId) override; // vtable+34; MxResult Init(); void SetInternalAction(MxDSAction *p_dsAction); diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 12695f82..94798b33 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -4,7 +4,6 @@ #include "mxtypes.h" #include "mxcore.h" -// SIZE 0xc template class MxListEntry { @@ -15,6 +14,11 @@ class MxListEntry m_prev = p_prev; m_next = NULL; } + MxListEntry(T p_obj, MxListEntry *p_prev, MxListEntry *p_next) { + m_obj = p_obj; + m_prev = p_prev; + m_next = p_next; + } T GetValue() { return this->m_obj; } @@ -26,7 +30,6 @@ class MxListEntry MxListEntry *m_next; }; -// VTABLE 0x100d6350 // SIZE 0x10 template class MxListParent : public MxCore @@ -46,7 +49,6 @@ class MxListParent : public MxCore void (*m_customDestructor)(T); // +0xc }; -// VTABLE 0x100d6368 // SIZE 0x18 template class MxList : protected MxListParent @@ -60,6 +62,7 @@ class MxList : protected MxListParent virtual ~MxList(); void Append(T); + void OtherAppend(T p_obj) { _InsertEntry(p_obj, this->m_last, NULL); }; void DeleteAll(); MxU32 GetCount() { return m_count; } void SetDestroy(void (*p_customDestructor)(T)) { this->m_customDestructor = p_customDestructor; } @@ -71,9 +74,9 @@ class MxList : protected MxListParent private: void _DeleteEntry(MxListEntry *match); + void _InsertEntry(T, MxListEntry *, MxListEntry *); }; -// VTABLE 0x100d6488 template class MxListCursor : public MxCore { @@ -96,7 +99,6 @@ class MxListCursor : public MxCore }; // Unclear purpose -// VTABLE 0x100d6530 template class MxListCursorChild : public MxListCursor { @@ -105,7 +107,6 @@ class MxListCursorChild : public MxListCursor }; // Unclear purpose -// VTABLE 0x100d6470 template class MxListCursorChildChild : public MxListCursorChild { @@ -152,6 +153,24 @@ inline void MxList::Append(T p_newobj) this->m_count++; } +template +inline void MxList::_InsertEntry(T p_newobj, MxListEntry *p_prev, MxListEntry *p_next) +{ + MxListEntry *newEntry = new MxListEntry(p_newobj, p_prev, p_next); + + if (p_prev) + p_prev->m_next = newEntry; + else + this->m_first = newEntry; + + if (p_next) + p_next->m_prev = newEntry; + else + this->m_last = newEntry; + + this->m_count++; +} + template inline void MxList::_DeleteEntry(MxListEntry *match) { @@ -198,7 +217,7 @@ inline MxBool MxListCursor::Next(T& p_obj) m_match = m_match->m_next; if (m_match) - p_obj = m_match->m_obj; + p_obj = m_match->GetValue(); return m_match != NULL; } diff --git a/LEGO1/mxstring.cpp b/LEGO1/mxstring.cpp index e82d431a..fe221f94 100644 --- a/LEGO1/mxstring.cpp +++ b/LEGO1/mxstring.cpp @@ -56,14 +56,14 @@ void MxString::ToLowerCase() } // OFFSET: LEGO1 0x100ae4b0 -MxString &MxString::operator=(MxString *param) +MxString &MxString::operator=(MxString ¶m) { - if (this->m_data != param->m_data) + if (this->m_data != param.m_data) { delete[] this->m_data; - this->m_length = param->m_length; + this->m_length = param.m_length; this->m_data = new char[this->m_length + 1]; - strcpy(this->m_data, param->m_data); + strcpy(this->m_data, param.m_data); } return *this; diff --git a/LEGO1/mxstring.h b/LEGO1/mxstring.h index a24a0df1..ec20f879 100644 --- a/LEGO1/mxstring.h +++ b/LEGO1/mxstring.h @@ -15,7 +15,7 @@ class MxString : public MxCore MxString(const char *); void ToUpperCase(); void ToLowerCase(); - MxString& operator=(MxString *); + MxString& operator=(MxString &); MxString operator+(const char *); MxString& operator+=(const char *); diff --git a/LEGO1/mxstringlist.cpp b/LEGO1/mxstringlist.cpp new file mode 100644 index 00000000..8a0a2ddc --- /dev/null +++ b/LEGO1/mxstringlist.cpp @@ -0,0 +1,5 @@ +#include "mxstringlist.h" + +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxListEntry, 0x18) diff --git a/LEGO1/mxstringlist.h b/LEGO1/mxstringlist.h index dbf063f6..f92d2b7d 100644 --- a/LEGO1/mxstringlist.h +++ b/LEGO1/mxstringlist.h @@ -8,6 +8,9 @@ // SIZE 0x18 class MxStringList : public MxList {}; +// VTABLE 0x100dd058 +typedef MxListCursorChild MxStringListCursor; + // OFFSET: LEGO1 0x100cb3c0 TEMPLATE // MxListParent::Compare @@ -17,6 +20,15 @@ class MxStringList : public MxList {}; // OFFSET: LEGO1 0x100cb4c0 TEMPLATE // MxList::~MxList +// OFFSET: LEGO1 0x100cbb40 TEMPLATE +// MxList::OtherAppend + +// OFFSET: LEGO1 0x100cc2d0 TEMPLATE +// MxList::_InsertEntry + +// OFFSET: LEGO1 0x100cc3c0 TEMPLATE +// MxListEntry::MxListEntry + // OFFSET: LEGO1 0x100cc450 TEMPLATE // MxListEntry::GetValue From 62b97b8f1f4078da83eabad6a4aa4f0dc8cae139 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sat, 7 Oct 2023 14:05:45 -0400 Subject: [PATCH 68/87] Implement MxOmni::Create (#182) * implement mxomni::create, and match MxStreamController::Open * Use enum for mxparam type * Fix return type * Match MxOmni::Notify * Remove unused variable * Added override keywords --------- Co-authored-by: Christian Semmler --- LEGO1/mxeventmanager.cpp | 9 ++- LEGO1/mxeventmanager.h | 3 +- LEGO1/mxmediamanager.h | 2 +- LEGO1/mxomni.cpp | 115 ++++++++++++++++++++++++++++++++-- LEGO1/mxomni.h | 1 + LEGO1/mxomnicreateparam.h | 3 + LEGO1/mxparam.h | 14 ++++- LEGO1/mxpresenter.cpp | 7 +-- LEGO1/mxstreamcontroller.cpp | 6 +- LEGO1/mxstreamer.cpp | 2 - LEGO1/mxstreamer.h | 2 +- LEGO1/mxtransitionmanager.cpp | 2 +- LEGO1/mxvideomanager.cpp | 18 +++++- LEGO1/mxvideomanager.h | 4 +- 14 files changed, 164 insertions(+), 24 deletions(-) diff --git a/LEGO1/mxeventmanager.cpp b/LEGO1/mxeventmanager.cpp index 5383c25a..54cc2905 100644 --- a/LEGO1/mxeventmanager.cpp +++ b/LEGO1/mxeventmanager.cpp @@ -15,4 +15,11 @@ MxEventManager::~MxEventManager() // OFFSET: LEGO1 0x100c0450 void MxEventManager::Init() { -} \ No newline at end of file +} + +// OFFSET: LEGO1 0x100c04a0 STUB +MxResult MxEventManager::vtable0x28(undefined4 p_unknown1, undefined p_unknown2) +{ + //TODO + return FAILURE; +} diff --git a/LEGO1/mxeventmanager.h b/LEGO1/mxeventmanager.h index cb89f637..59a1c8ea 100644 --- a/LEGO1/mxeventmanager.h +++ b/LEGO1/mxeventmanager.h @@ -2,6 +2,7 @@ #define MXEVENTMANAGER_H #include "mxmediamanager.h" +#include "decomp.h" // VTABLE 0x100dc900 // SIZE 0x2c @@ -10,7 +11,7 @@ class MxEventManager : public MxMediaManager public: MxEventManager(); virtual ~MxEventManager() override; - + virtual MxResult vtable0x28(undefined4 p_unknown1, MxU8 p_unknown2); // vtable+28 private: void Init(); }; diff --git a/LEGO1/mxmediamanager.h b/LEGO1/mxmediamanager.h index ccc3ec42..db8d9056 100644 --- a/LEGO1/mxmediamanager.h +++ b/LEGO1/mxmediamanager.h @@ -15,7 +15,7 @@ class MxMediaManager : public MxCore MxMediaManager(); virtual ~MxMediaManager() override; - virtual MxResult Tickle(); // vtable+08 + virtual MxResult Tickle() override; // vtable+08 virtual MxResult InitPresenters(); // vtable+14 virtual void Destroy(); // vtable+18 virtual void AddPresenter(MxPresenter &p_presenter); // vtable+1c diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index d1db1398..b5c0dcb3 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -11,6 +11,7 @@ #include "mxticklemanager.h" #include "mxtimer.h" #include "mxvideomanager.h" +#include "mxautolocker.h" // 0x101015b8 char g_hdPath[1024]; @@ -182,7 +183,22 @@ void MxOmni::SetInstance(MxOmni *instance) // OFFSET: LEGO1 0x100af0c0 MxResult MxOmni::Create(MxOmniCreateParam &p) { + MxResult result = FAILURE; m_atomIdCounterSet = new MxAtomIdCounterSet(); + if (m_atomIdCounterSet == NULL) + { + goto failure; + } + m_mediaPath = p.GetMediaPath(); + m_windowHandle = p.GetWindowHandle(); + if (p.CreateFlags().CreateObjectFactory()) + { + MxObjectFactory *objectFactory = new MxObjectFactory(); + this->m_objectFactory = objectFactory; + + if (objectFactory == NULL) + goto failure; + } if (p.CreateFlags().CreateVariableTable()) { @@ -190,7 +206,7 @@ MxResult MxOmni::Create(MxOmniCreateParam &p) this->m_variableTable = variableTable; if (variableTable == NULL) - return FAILURE; + goto failure; } if (p.CreateFlags().CreateTimer()) @@ -202,7 +218,87 @@ MxResult MxOmni::Create(MxOmniCreateParam &p) return FAILURE; } - return SUCCESS; + if (p.CreateFlags().CreateTickleManager()) + { + this->m_tickleManager = new MxTickleManager(); + + if (m_tickleManager == NULL) + goto failure; + } + + if (p.CreateFlags().CreateNotificationManager()) + { + MxNotificationManager *notificationManager = new MxNotificationManager(); + this->m_notificationManager = notificationManager; + + if (notificationManager == NULL || notificationManager->Create(100, 0) != SUCCESS) + goto failure; + } + + if (p.CreateFlags().CreateStreamer()) + { + MxStreamer *streamer = new MxStreamer(); + this->m_streamer = streamer; + + if (streamer == NULL || streamer->Init() != SUCCESS) + goto failure; + } + + if (p.CreateFlags().CreateVideoManager()) + { + MxVideoManager *videoManager = new MxVideoManager(); + this->m_videoManager = videoManager; + + if (videoManager != NULL && videoManager->vtable0x2c(p.GetVideoParam(), 100, 0) != SUCCESS) + { + delete m_videoManager; + m_videoManager = NULL; + } + } + + if (p.CreateFlags().CreateSoundManager()) + { + MxSoundManager *soundManager = new MxSoundManager(); + this->m_soundManager = soundManager; + + //TODO + if (soundManager != NULL && soundManager->StartDirectSound(10, 0) != SUCCESS) + { + delete m_soundManager; + m_soundManager = NULL; + } + } + + if (p.CreateFlags().CreateMusicManager()) + { + MxMusicManager *musicManager = new MxMusicManager(); + this->m_musicManager = musicManager; + if (musicManager != NULL && musicManager->StartMIDIThread(50, 0) != SUCCESS) + { + delete m_musicManager; + m_musicManager = NULL; + } + } + + if (p.CreateFlags().CreateEventManager()) + { + MxEventManager *eventManager = new MxEventManager(); + this->m_eventManager = eventManager; + if (m_eventManager != NULL && m_eventManager->vtable0x28(50, 0) != SUCCESS) + { + delete m_eventManager; + m_eventManager = NULL; + } + } + + result = SUCCESS; + failure: + if (result != SUCCESS) + { + Destroy(); + } + + return result; } // OFFSET: LEGO1 0x100afe90 @@ -248,8 +344,19 @@ void MxOmni::Destroy() // OFFSET: LEGO1 0x100b07f0 MxLong MxOmni::Notify(MxParam &p) { - // FIXME: Stub - return 0; + MxAutoLocker lock(&this->m_criticalsection); + + if (p.GetType() != MXSTREAMER_UNKNOWN) + return 0; + + return HandleNotificationType2(p); +} + +// OFFSET: LEGO1 0x100b0880 STUB +MxResult MxOmni::HandleNotificationType2(MxParam& p_param) +{ + // TODO STUB + return FAILURE; } // OFFSET: LEGO1 0x100acea0 diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 66682842..5290c6ed 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -61,6 +61,7 @@ class MxOmni : public MxCore MxMusicManager* GetMusicManager() const { return this->m_musicManager; } MxEventManager* GetEventManager() const { return this->m_eventManager; } MxAtomIdCounterSet* GetAtomIdCounterSet() const { return this->m_atomIdCounterSet; } + MxResult HandleNotificationType2(MxParam& p_param); protected: static MxOmni* g_instance; diff --git a/LEGO1/mxomnicreateparam.h b/LEGO1/mxomnicreateparam.h index 31dcd447..3c1059dd 100644 --- a/LEGO1/mxomnicreateparam.h +++ b/LEGO1/mxomnicreateparam.h @@ -14,6 +14,9 @@ class MxOmniCreateParam : public MxOmniCreateParamBase __declspec(dllexport) MxOmniCreateParam(const char *mediaPath, struct HWND__ *windowHandle, MxVideoParam &vparam, MxOmniCreateFlags flags); const MxOmniCreateFlags& CreateFlags() const { return this->m_createFlags; } + const MxString GetMediaPath() const { return m_mediaPath; } + const HWND GetWindowHandle() const { return m_windowHandle; } + MxVideoParam& GetVideoParam() { return m_videoParam; } private: MxString m_mediaPath; diff --git a/LEGO1/mxparam.h b/LEGO1/mxparam.h index ffbf1530..d76ecdb0 100644 --- a/LEGO1/mxparam.h +++ b/LEGO1/mxparam.h @@ -7,16 +7,24 @@ class MxCore; +enum MxParamType +{ + MXSTREAMER_UNKNOWN = 2, + MXPRESENTER_NOTIFICATION = 5, + MXSTREAMER_DELETE_NOTIFY = 6, + MXTRANSITIONMANAGER_TRANSITIONENDED = 24 +}; + // VTABLE 0x100d56e0 class MxParam : public MxOmniCreateParamBase { public: - inline MxParam(MxS32 p_type, MxCore *p_sender) : MxOmniCreateParamBase(), m_type(p_type), m_sender(p_sender){} + inline MxParam(MxParamType p_type, MxCore *p_sender) : MxOmniCreateParamBase(), m_type(p_type), m_sender(p_sender){} virtual ~MxParam() override {} // vtable+0x0 (scalar deleting destructor) virtual MxParam *Clone(); // vtable+0x4 - inline MxS32 GetType() const + inline MxParamType GetType() const { return m_type; } @@ -27,7 +35,7 @@ class MxParam : public MxOmniCreateParamBase } protected: - MxS32 m_type; // 0x4 + MxParamType m_type; // 0x4 MxCore *m_sender; // 0x8 }; diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 5afafc79..f8f60386 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -49,9 +49,9 @@ void MxPresenter::ParseExtra() int val = token ? atoi(token) : 0; int result = MxOmni::GetInstance()->vtable0x30(t_token, val, this); - + m_action->SetFlags(m_action->GetFlags() | MxDSAction::Flag_Parsed); - + if (result) SendTo_unkPresenter(MxOmni::GetInstance()); @@ -65,8 +65,7 @@ void MxPresenter::SendTo_unkPresenter(MxOmni *p_omni) if (m_unkPresenter) { MxAutoLocker lock(&m_criticalSection); - // TOOD: magic number used for notification type. replace with enum - NotificationManager()->Send(m_unkPresenter, &MxParam(5, this)); + NotificationManager()->Send(m_unkPresenter, &MxParam(MXPRESENTER_NOTIFICATION, this)); m_action->SetOmni(p_omni ? p_omni : MxOmni::GetInstance()); m_unkPresenter = NULL; diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index e219f357..83917cd4 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -1,6 +1,7 @@ #include "mxstreamcontroller.h" #include "mxautolocker.h" +#include "legoomni.h" // OFFSET: LEGO1 0x100c0b90 STUB MxStreamController::MxStreamController() @@ -24,10 +25,11 @@ MxBool MxStreamController::FUN_100c20d0(MxDSObject &p_obj) // OFFSET: LEGO1 0x100c1520 MxResult MxStreamController::Open(const char *p_filename) { + char sourceName [256]; MxAutoLocker locker(&m_criticalSection); - // TODO - + MakeSourceName(sourceName, p_filename); + this->atom = MxAtomId(sourceName, LookupMode_LowerCase2); return SUCCESS; } diff --git a/LEGO1/mxstreamer.cpp b/LEGO1/mxstreamer.cpp index eef989bc..c6ef85bd 100644 --- a/LEGO1/mxstreamer.cpp +++ b/LEGO1/mxstreamer.cpp @@ -9,8 +9,6 @@ DECOMP_SIZE_ASSERT(MxStreamer, 0x2c); -#define MXSTREAMER_DELETE_NOTIFY 6 - // OFFSET: LEGO1 0x100b8f00 MxStreamer::MxStreamer() { diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index c900feb9..515be51b 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -43,7 +43,7 @@ class MxStreamerSubClass3 : public MxStreamerSubClass1 class MxStreamerNotification : public MxParam { public: - inline MxStreamerNotification(MxS32 p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxParam(p_type, p_sender) + inline MxStreamerNotification(MxParamType p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxParam(p_type, p_sender) { m_controller = p_ctrlr; } diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index d7d16544..66c99532 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -85,7 +85,7 @@ void MxTransitionManager::EndTransition(MxBool p_notifyWorld) LegoWorld *world = GetCurrentWorld(); if (world) { - world->Notify(MxParam(0x18, this)); + world->Notify(MxParam(MXTRANSITIONMANAGER_TRANSITIONENDED, this)); } } } diff --git a/LEGO1/mxvideomanager.cpp b/LEGO1/mxvideomanager.cpp index 8f64dbd4..bab495fd 100644 --- a/LEGO1/mxvideomanager.cpp +++ b/LEGO1/mxvideomanager.cpp @@ -34,7 +34,7 @@ MxResult MxVideoManager::Tickle() UpdateRegion(); m_region->Reset(); - + return SUCCESS; } @@ -54,13 +54,13 @@ MxResult MxVideoManager::Init() void MxVideoManager::SortPresenterList() { if (this->m_presenters->GetCount() <= 1) - return; + return; MxPresenterListCursor a(this->m_presenters); MxPresenterListCursor b(this->m_presenters); MxU32 count = this->m_presenters->GetCount() - 1; MxBool finished; - + if (count != 0) { do { a.Reset(); @@ -111,3 +111,15 @@ MxLong MxVideoManager::RealizePalette(MxPalette *p_palette) this->m_criticalSection.Leave(); return 0; } + +// OFFSET: LEGO1 0x100be600 STUB +void MxVideoManager::vtable0x28() +{ + +} + +// OFFSET: LEGO1 0x100bebe0 STUB +MxResult MxVideoManager::vtable0x2c(MxVideoParam& p_videoParam, undefined4 p_unknown1, MxU8 p_unknown2) +{ + return FAILURE; +} diff --git a/LEGO1/mxvideomanager.h b/LEGO1/mxvideomanager.h index 7888f7e7..d72c1d10 100644 --- a/LEGO1/mxvideomanager.h +++ b/LEGO1/mxvideomanager.h @@ -13,7 +13,9 @@ class MxVideoManager : public MxMediaManager public: virtual ~MxVideoManager(); - virtual MxResult Tickle(); // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 + virtual void vtable0x28(); // vtable+0x28 (TODO ARGUMENTS) + virtual MxResult vtable0x2c(MxVideoParam& p_videoParam, undefined4 p_unknown1, MxU8 p_unknown2); // vtable+0x2c __declspec(dllexport) void InvalidateRect(MxRect32 &); __declspec(dllexport) virtual MxLong RealizePalette(MxPalette *); // vtable+0x30 From a9fa734844d1fb9ea58832439c38564d5d2c2dcb Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 7 Oct 2023 14:07:26 -0400 Subject: [PATCH 69/87] Refactor deserialization of objects (#170) * Use template helpers for deserialization * Remove space * Fix naming --- LEGO1/legoutil.h | 29 +++++++++++++++++++++++ LEGO1/mxdsaction.cpp | 49 ++++++++++++++------------------------- LEGO1/mxdsmediaaction.cpp | 24 +++++++------------ LEGO1/mxdsobject.cpp | 15 ++++-------- LEGO1/mxdssound.cpp | 4 ++-- 5 files changed, 63 insertions(+), 58 deletions(-) diff --git a/LEGO1/legoutil.h b/LEGO1/legoutil.h index e912991d..cc54da74 100644 --- a/LEGO1/legoutil.h +++ b/LEGO1/legoutil.h @@ -23,6 +23,35 @@ inline T Max(T p_t1, T p_t2) return p_t1 > p_t2 ? p_t1 : p_t2; } +template +inline void GetScalar(char **p_source, T& p_dest) +{ + p_dest = *(T*) *p_source; + *p_source += sizeof(T); +} + +template +inline T GetScalar(T **p_source) +{ + T val = **p_source; + *p_source += 1; + return val; +} + +template +inline void GetDouble(char **p_source, T& p_dest) +{ + p_dest = *(double*) *p_source; + *p_source += sizeof(double); +} + +template +inline void GetString(char **p_source, const char *&p_dest, T *p_obj, void (T::*p_setter)(const char*)) +{ + (p_obj->*p_setter)(*p_source); + *p_source += strlen(p_dest) + 1; +} + ExtraActionType MatchActionString(const char *); void ConvertHSVToRGB(float r, float g, float b, float* out_r, float* out_g, float* out_b); void SetAppCursor(WPARAM p_wparam); diff --git a/LEGO1/mxdsaction.cpp b/LEGO1/mxdsaction.cpp index 1f26c7c9..153a6498 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -2,6 +2,7 @@ #include "mxomni.h" #include "mxtimer.h" +#include "legoutil.h" #include #include @@ -84,38 +85,24 @@ void MxDSAction::Deserialize(char **p_source, MxS16 p_unk24) { MxDSObject::Deserialize(p_source, p_unk24); - this->m_flags = *(MxU32*) *p_source; - *p_source += sizeof(MxU32); - this->m_startTime = *(MxLong*) *p_source; - *p_source += sizeof(MxLong); - this->m_duration = *(MxLong*) *p_source; - *p_source += sizeof(MxLong); - this->m_loopCount = *(MxS32*) *p_source; - *p_source += sizeof(MxS32); - this->m_location[0] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_location[1] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_location[2] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_direction[0] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_direction[1] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_direction[2] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_up[0] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_up[1] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_up[2] = *(double*) *p_source; - *p_source += sizeof(double); + GetScalar(p_source, this->m_flags); + GetScalar(p_source, this->m_startTime); + GetScalar(p_source, this->m_duration); + GetScalar(p_source, this->m_loopCount); + GetDouble(p_source, this->m_location[0]); + GetDouble(p_source, this->m_location[1]); + GetDouble(p_source, this->m_location[2]); + GetDouble(p_source, this->m_direction[0]); + GetDouble(p_source, this->m_direction[1]); + GetDouble(p_source, this->m_direction[2]); + GetDouble(p_source, this->m_up[0]); + GetDouble(p_source, this->m_up[1]); + GetDouble(p_source, this->m_up[2]); - MxU16 unkLength = *(MxU16*) *p_source; - *p_source += sizeof(MxU16); - if (unkLength) { - AppendData(unkLength, *p_source); - *p_source += unkLength; + MxU16 extraLength = GetScalar((MxU16**) p_source); + if (extraLength) { + AppendData(extraLength, *p_source); + *p_source += extraLength; } } diff --git a/LEGO1/mxdsmediaaction.cpp b/LEGO1/mxdsmediaaction.cpp index d368aa3d..19f3bde2 100644 --- a/LEGO1/mxdsmediaaction.cpp +++ b/LEGO1/mxdsmediaaction.cpp @@ -1,5 +1,7 @@ #include "mxdsmediaaction.h" +#include "legoutil.h" + DECOMP_SIZE_ASSERT(MxDSMediaAction, 0xb8) // OFFSET: LEGO1 0x100c8b40 @@ -68,21 +70,13 @@ void MxDSMediaAction::Deserialize(char **p_source, MxS16 p_unk24) { MxDSAction::Deserialize(p_source, p_unk24); - CopyMediaSrcPath(*p_source); - *p_source += strlen(this->m_mediaSrcPath) + 1; - - this->m_unk9c = *(undefined4*) *p_source; - *p_source += sizeof(undefined4); - this->m_unka0 = *(undefined4*) *p_source; - *p_source += sizeof(undefined4); - this->m_framesPerSecond = *(MxS32*) *p_source; - *p_source += sizeof(MxS32); - this->m_mediaFormat = *(MxS32*) *p_source; - *p_source += sizeof(MxS32); - this->m_paletteManagement = *(MxS32*) *p_source; - *p_source += sizeof(MxS32); - this->m_sustainTime = *(MxLong*) *p_source; - *p_source += sizeof(MxLong); + GetString(p_source, this->m_mediaSrcPath, this, &MxDSMediaAction::CopyMediaSrcPath); + GetScalar(p_source, this->m_unk9c); + GetScalar(p_source, this->m_unka0); + GetScalar(p_source, this->m_framesPerSecond); + GetScalar(p_source, this->m_mediaFormat); + GetScalar(p_source, this->m_paletteManagement); + GetScalar(p_source, this->m_sustainTime); } // OFFSET: LEGO1 0x100c8e80 diff --git a/LEGO1/mxdsobject.cpp b/LEGO1/mxdsobject.cpp index 2b7d8437..f508c53b 100644 --- a/LEGO1/mxdsobject.cpp +++ b/LEGO1/mxdsobject.cpp @@ -15,6 +15,7 @@ #include "mxdsselectaction.h" #include "mxdsstill.h" #include "mxdsobjectaction.h" +#include "legoutil.h" DECOMP_SIZE_ASSERT(MxDSObject, 0x2c); @@ -128,20 +129,14 @@ MxU32 MxDSObject::GetSizeOnDisk() // OFFSET: LEGO1 0x100bfa20 void MxDSObject::Deserialize(char **p_source, MxS16 p_unk24) { - this->SetSourceName(*p_source); - *p_source += strlen(this->m_sourceName) + 1; - this->m_unk14 = *(undefined4*) *p_source; - *p_source += sizeof(undefined4); - - this->SetObjectName(*p_source); - *p_source += strlen(this->m_objectName) + 1; - this->m_objectId = *(MxU32*) *p_source; - *p_source += sizeof(MxU32); + GetString(p_source, this->m_sourceName, this, &MxDSObject::SetSourceName); + GetScalar(p_source, this->m_unk14); + GetString(p_source, this->m_objectName, this, &MxDSObject::SetObjectName); + GetScalar(p_source, this->m_objectId); this->m_unk24 = p_unk24; } - // OFFSET: LEGO1 0x100bfb30 MxDSObject *DeserializeDSObjectDispatch(char **p_source, MxS16 p_flags) { diff --git a/LEGO1/mxdssound.cpp b/LEGO1/mxdssound.cpp index cbb1c057..ca69ef34 100644 --- a/LEGO1/mxdssound.cpp +++ b/LEGO1/mxdssound.cpp @@ -1,4 +1,5 @@ #include "mxdssound.h" +#include "legoutil.h" DECOMP_SIZE_ASSERT(MxDSSound, 0xc0) @@ -46,8 +47,7 @@ void MxDSSound::Deserialize(char **p_source, MxS16 p_unk24) { MxDSMediaAction::Deserialize(p_source, p_unk24); - this->m_volume = *(MxS32*) *p_source; - *p_source += sizeof(MxS32); + GetScalar(p_source, this->m_volume); } // OFFSET: LEGO1 0x100c9510 From 472a82f22016cb32488b1a0f2fd8f0855e15f5bb Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Sat, 7 Oct 2023 16:36:05 -0400 Subject: [PATCH 70/87] MxMusicPresenter vtable (#184) * MxMusicPresenter vtable vtable+0x34 adds the current presenter to the music manager vtable+0x38 calls destroy with the param as "FALSE" * Update mxmusicpresenter.cpp * Update mxmusicpresenter.cpp --------- Co-authored-by: Christian Semmler --- LEGO1/mxmusicpresenter.cpp | 26 +++++++++++++++++++++++++- LEGO1/mxmusicpresenter.h | 4 ++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/LEGO1/mxmusicpresenter.cpp b/LEGO1/mxmusicpresenter.cpp index 72ae273a..45a56679 100644 --- a/LEGO1/mxmusicpresenter.cpp +++ b/LEGO1/mxmusicpresenter.cpp @@ -1,5 +1,11 @@ #include "mxmusicpresenter.h" +#include "decomp.h" +#include "mxmusicmanager.h" +#include "mxomni.h" + +DECOMP_SIZE_ASSERT(MxMusicPresenter, 0x54); + // OFFSET: LEGO1 0x100c22c0 MxMusicPresenter::MxMusicPresenter() { @@ -21,4 +27,22 @@ void MxMusicPresenter::Init() void MxMusicPresenter::Destroy(MxBool) { // TODO -} \ No newline at end of file +} + +// OFFSET: LEGO1 0x100c25a0 +MxResult MxMusicPresenter::AddToMusicManager() +{ + MxResult result = FAILURE; + if (MusicManager()) { + result = SUCCESS; + MusicManager()->AddPresenter(*this); + } + return result; +} + +// OFFSET: LEGO1 0x100c25d0 +void MxMusicPresenter::vtable38() +{ + // TODO: Name this function when we know what the argument to Destroy does + Destroy(FALSE); +} diff --git a/LEGO1/mxmusicpresenter.h b/LEGO1/mxmusicpresenter.h index a000c2b9..2e55aa6c 100644 --- a/LEGO1/mxmusicpresenter.h +++ b/LEGO1/mxmusicpresenter.h @@ -4,6 +4,7 @@ #include "mxaudiopresenter.h" // VTABLE 0x100dc9b8 +// SIZE 0x54 class MxMusicPresenter : public MxAudioPresenter { public: @@ -23,6 +24,9 @@ class MxMusicPresenter : public MxAudioPresenter MxMusicPresenter(); virtual ~MxMusicPresenter() override; + virtual MxResult AddToMusicManager(); // vtable+0x34 + virtual void vtable38(); // vtable+0x38 + private: void Init(); void Destroy(MxBool); From 5f8bde9e48797bb9bd29416e8857bb66abdfe390 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sat, 7 Oct 2023 17:30:05 -0400 Subject: [PATCH 71/87] Finish MxMediaManager and MxEventManager (#185) * Finish MxMediaManager and MxEventManager * Update mxomni.cpp * fixes --- LEGO1/mxeventmanager.cpp | 51 ++++++++++++++++++++++++++++++++++++---- LEGO1/mxeventmanager.h | 2 +- LEGO1/mxmediamanager.cpp | 23 +++++++++++++++++- LEGO1/mxmediamanager.h | 1 + LEGO1/mxomni.cpp | 4 ++-- 5 files changed, 72 insertions(+), 9 deletions(-) diff --git a/LEGO1/mxeventmanager.cpp b/LEGO1/mxeventmanager.cpp index 54cc2905..0861af77 100644 --- a/LEGO1/mxeventmanager.cpp +++ b/LEGO1/mxeventmanager.cpp @@ -1,4 +1,8 @@ #include "mxeventmanager.h" +#include "mxcriticalsection.h" +#include "mxthread.h" +#include "mxticklemanager.h" +#include "mxomni.h" // OFFSET: LEGO1 0x100c0360 MxEventManager::MxEventManager() @@ -9,17 +13,54 @@ MxEventManager::MxEventManager() // OFFSET: LEGO1 0x100c03f0 MxEventManager::~MxEventManager() { - // TODO: MxMediaManager::TerminateThread call + TerminateThread(TRUE); } // OFFSET: LEGO1 0x100c0450 void MxEventManager::Init() { + // This is intentionally left blank } -// OFFSET: LEGO1 0x100c04a0 STUB -MxResult MxEventManager::vtable0x28(undefined4 p_unknown1, undefined p_unknown2) +// OFFSET: LEGO1 0x100c04a0 +MxResult MxEventManager::CreateEventThread(MxU32 p_frequencyMS, MxBool p_noRegister) { - //TODO - return FAILURE; + MxResult status = FAILURE; + MxBool locked = FALSE; + + MxResult result = MxMediaManager::InitPresenters(); + if (result == SUCCESS) + { + if (p_noRegister) + { + this->m_criticalSection.Enter(); + locked = TRUE; + this->m_thread = new MxTickleThread(this, p_frequencyMS); + + if (this->m_thread) + { + if (this->m_thread->Start(0, 0) == SUCCESS) + { + status = SUCCESS; + } + } + } + else + { + TickleManager()->RegisterClient(this, p_frequencyMS); + status = SUCCESS; + } + } + + if (status != SUCCESS) + { + Destroy(); + } + + if (locked) + { + this->m_criticalSection.Leave(); + } + + return status; } diff --git a/LEGO1/mxeventmanager.h b/LEGO1/mxeventmanager.h index 59a1c8ea..1ef43748 100644 --- a/LEGO1/mxeventmanager.h +++ b/LEGO1/mxeventmanager.h @@ -11,7 +11,7 @@ class MxEventManager : public MxMediaManager public: MxEventManager(); virtual ~MxEventManager() override; - virtual MxResult vtable0x28(undefined4 p_unknown1, MxU8 p_unknown2); // vtable+28 + virtual MxResult CreateEventThread(MxU32 p_frequencyMS, MxBool p_noRegister); // vtable+28 private: void Init(); }; diff --git a/LEGO1/mxmediamanager.cpp b/LEGO1/mxmediamanager.cpp index 3fb28d37..c992cd42 100644 --- a/LEGO1/mxmediamanager.cpp +++ b/LEGO1/mxmediamanager.cpp @@ -2,6 +2,8 @@ #include "mxautolocker.h" #include "mxpresenter.h" #include "decomp.h" +#include "mxticklemanager.h" +#include "mxomni.h" DECOMP_SIZE_ASSERT(MxMediaManager, 0x2c); @@ -65,7 +67,7 @@ void MxMediaManager::Destroy() if (this->m_presenters) delete this->m_presenters; - + Init(); } @@ -97,3 +99,22 @@ void MxMediaManager::StopPresenters() while (cursor.Next(presenter)) presenter->EndAction(); } + +// OFFSET: LEGO1 0x100c0460 +void MxMediaManager::TerminateThread(MxBool p_reinit) +{ + if(m_thread != NULL) + { + m_thread->Terminate(); + delete m_thread; + } + else + { + TickleManager()->UnregisterClient(this); + } + + if(!p_reinit) + { + MxMediaManager::Destroy(); + } +} diff --git a/LEGO1/mxmediamanager.h b/LEGO1/mxmediamanager.h index db8d9056..c17ab300 100644 --- a/LEGO1/mxmediamanager.h +++ b/LEGO1/mxmediamanager.h @@ -23,6 +23,7 @@ class MxMediaManager : public MxCore virtual void StopPresenters(); // vtable+24 MxResult Init(); + void TerminateThread(MxBool p_reinit); protected: MxPresenterList *m_presenters; diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index b5c0dcb3..fb3251da 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -284,7 +284,7 @@ MxResult MxOmni::Create(MxOmniCreateParam &p) { MxEventManager *eventManager = new MxEventManager(); this->m_eventManager = eventManager; - if (m_eventManager != NULL && m_eventManager->vtable0x28(50, 0) != SUCCESS) + if (m_eventManager != NULL && m_eventManager->CreateEventThread(50, 0) != SUCCESS) { delete m_eventManager; m_eventManager = NULL; @@ -345,7 +345,7 @@ void MxOmni::Destroy() MxLong MxOmni::Notify(MxParam &p) { MxAutoLocker lock(&this->m_criticalsection); - + if (p.GetType() != MXSTREAMER_UNKNOWN) return 0; From 3afbf808d186fee463385ce0067fc8774b2871c4 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sun, 8 Oct 2023 09:46:09 -0400 Subject: [PATCH 72/87] MxMediaPresenter vtable (#189) * Add vtables for MxMediaPresenter * remove comments and fix override --- LEGO1/mxmediapresenter.cpp | 56 ++++++++++++++++++++++++++++++++++++++ LEGO1/mxmediapresenter.h | 13 +++++++-- LEGO1/mxpresenter.h | 4 +-- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index f36ecbdc..00a2b851 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -2,6 +2,12 @@ DECOMP_SIZE_ASSERT(MxMediaPresenter, 0x50); +// OFFSET: LEGO1 0x1000c550 +MxMediaPresenter::~MxMediaPresenter() +{ + Destroy(TRUE); +} + // OFFSET: LEGO1 0x100b5d10 STUB MxResult MxMediaPresenter::Tickle() { @@ -18,6 +24,56 @@ void MxMediaPresenter::Init() this->m_unk4c = NULL; } +// OFFSET: LEGO1 0x100b54f0 STUB +void MxMediaPresenter::Destroy(MxBool p_destroy) +{ + // TODO +} + +// OFFSET: LEGO1 0x100b5d90 STUB +void MxMediaPresenter::StreamingTickle() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b5e10 STUB +void MxMediaPresenter::RepeatingTickle() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b5ef0 +void MxMediaPresenter::DoneTickle() +{ + m_previousTickleStates |= 1 << m_currentTickleState; + m_currentTickleState = TickleState_Idle; + EndAction(); +} + +// OFFSET: LEGO1 0x100b6030 STUB +void MxMediaPresenter::Enable(MxBool p_enable) +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c5b0 +void MxMediaPresenter::InitVirtual() +{ + Destroy(FALSE); +} + +// OFFSET: LEGO1 0x100b5700 STUB +MxLong MxMediaPresenter::StartAction(MxStreamController * p_controller, MxDSAction * p_action) +{ + return 0; +} + +// OFFSET: LEGO1 0x100b5bc0 STUB +void MxMediaPresenter::EndAction() +{ + // TODO +} + // OFFSET: LEGO1 0x100b5f10 STUB void MxMediaPresenter::VTable0x58() { diff --git a/LEGO1/mxmediapresenter.h b/LEGO1/mxmediapresenter.h index 824dd399..167b10c1 100644 --- a/LEGO1/mxmediapresenter.h +++ b/LEGO1/mxmediapresenter.h @@ -13,8 +13,9 @@ class MxMediaPresenter : public MxPresenter { Init(); } + virtual ~MxMediaPresenter() override; - virtual MxResult Tickle() override; // vtable+0x8, override MxCore + virtual MxResult Tickle() override; // OFFSET: LEGO1 0x1000c5c0 inline virtual const char *ClassName() const override // vtable+0xc @@ -29,7 +30,14 @@ class MxMediaPresenter : public MxPresenter return !strcmp(name, MxMediaPresenter::ClassName()) || MxPresenter::IsA(name); } - virtual void VTable0x58(); // vtable+0x58 + virtual void StreamingTickle() override; + virtual void RepeatingTickle() override; + virtual void DoneTickle() override; + virtual void InitVirtual() override; + virtual MxLong StartAction(MxStreamController *, MxDSAction *) override; + virtual void EndAction() override; + virtual void Enable(MxBool p_enable) override; + virtual void VTable0x58(); undefined4 m_unk40; undefined4 m_unk44; @@ -37,6 +45,7 @@ class MxMediaPresenter : public MxPresenter undefined4 m_unk4c; private: void Init(); + void Destroy(MxBool); }; diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 156065f4..959533c5 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -15,7 +15,7 @@ class MxStreamController; class MxPresenter : public MxCore { public: - enum TickleState + enum TickleState { TickleState_Idle = 0, TickleState_Ready, @@ -78,8 +78,6 @@ class MxPresenter : public MxCore protected: __declspec(dllexport) void Init(); void SendTo_unkPresenter(MxOmni *); - -private: TickleState m_currentTickleState; // 0x8 MxU32 m_previousTickleStates; MxPoint32 m_location; From aa516af4349e3f48eaa8ca1af09a0129b583a165 Mon Sep 17 00:00:00 2001 From: ChrisMiuchiz Date: Sun, 8 Oct 2023 10:10:16 -0400 Subject: [PATCH 73/87] Remove goto from isleapp.cpp (#188) * Remove goto from isleapp.cpp * Simplify if statement and make indent consistent --- ISLE/isleapp.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 9aefae60..503a7128 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -250,16 +250,12 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine 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; + if (g_mousedown && g_mousemoved && g_isle) { + g_isle->Tick(0); + } + + if (g_mousemoved) { + g_mousemoved = FALSE; } } } From 7c674cbb4734c687f86c72a89bc0e096a9a7c002 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Sun, 8 Oct 2023 11:25:38 -0400 Subject: [PATCH 74/87] Start MxCompositePresenter ctor/dtor (#186) * Start MxCompositePresenter ctor/dtor * Add MxUnkList --------- Co-authored-by: Christian Semmler --- LEGO1/mxcompositepresenter.cpp | 9 +++++---- LEGO1/mxcompositepresenter.h | 5 ++--- LEGO1/mxdiskstreamprovider.h | 29 ++------------------------ LEGO1/mxunklist.h | 37 ++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 34 deletions(-) create mode 100644 LEGO1/mxunklist.h diff --git a/LEGO1/mxcompositepresenter.cpp b/LEGO1/mxcompositepresenter.cpp index 342f3d96..06477c94 100644 --- a/LEGO1/mxcompositepresenter.cpp +++ b/LEGO1/mxcompositepresenter.cpp @@ -1,17 +1,18 @@ #include "mxcompositepresenter.h" #include "decomp.h" +#include "mxnotificationmanager.h" DECOMP_SIZE_ASSERT(MxCompositePresenter, 0x4c); -// OFFSET: LEGO1 0x100b60b0 STUB +// OFFSET: LEGO1 0x100b60b0 MxCompositePresenter::MxCompositePresenter() { - // TODO + NotificationManager()->Register(this); } -// OFFSET: LEGO1 0x100b6390 STUB +// OFFSET: LEGO1 0x100b6390 MxCompositePresenter::~MxCompositePresenter() { - // TODO + NotificationManager()->Unregister(this); } diff --git a/LEGO1/mxcompositepresenter.h b/LEGO1/mxcompositepresenter.h index 9f517652..0be080f0 100644 --- a/LEGO1/mxcompositepresenter.h +++ b/LEGO1/mxcompositepresenter.h @@ -2,6 +2,7 @@ #define MXCOMPOSITEPRESENTER_H #include "mxpresenter.h" +#include "mxunklist.h" // VTABLE 0x100dc618 // SIZE 0x4c @@ -24,9 +25,7 @@ class MxCompositePresenter : public MxPresenter return !strcmp(name, MxCompositePresenter::ClassName()) || MxPresenter::IsA(name); } - undefined m_unk40; - undefined4 *m_unk44; - undefined4 m_unk48; + MxUnkList m_list; }; #endif // MXCOMPOSITEPRESENTER_H diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index b6ff8c18..c797a0de 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -5,6 +5,7 @@ #include "mxstreamprovider.h" #include "mxthread.h" #include "mxcriticalsection.h" +#include "mxunklist.h" class MxDiskStreamProvider; @@ -23,32 +24,6 @@ class MxDiskStreamProviderThread : public MxThread MxDiskStreamProvider *m_target; }; -// TODO -struct MxDiskStreamListNode { - MxDiskStreamListNode *m_unk00; - MxDiskStreamListNode *m_unk04; - undefined4 m_unk08; -}; - -// TODO -struct MxDiskStreamList { - inline MxDiskStreamList() { - undefined unk; - this->m_unk00 = unk; - - MxDiskStreamListNode *node = new MxDiskStreamListNode(); - node->m_unk00 = node; - node->m_unk04 = node; - - this->m_head = node; - this->m_count = 0; - } - - undefined m_unk00; - MxDiskStreamListNode *m_head; - MxU32 m_count; -}; - // VTABLE 0x100dd138 class MxDiskStreamProvider : public MxStreamProvider { @@ -80,7 +55,7 @@ class MxDiskStreamProvider : public MxStreamProvider undefined m_remainingWork; // 0x34 undefined m_unk35; // 0x35 MxCriticalSection m_criticalSection; // 0x38 - MxDiskStreamList m_list; + MxUnkList m_list; }; #endif // MXDISKSTREAMPROVIDER_H diff --git a/LEGO1/mxunklist.h b/LEGO1/mxunklist.h new file mode 100644 index 00000000..af59f47b --- /dev/null +++ b/LEGO1/mxunklist.h @@ -0,0 +1,37 @@ +#ifndef MXUNKLIST_H +#define MXUNKLIST_H + +#include "decomp.h" +#include "mxtypes.h" + +/* +* This is an as-of-yet unknown list-like data structure. +* The class hierarchy/structure isn't quite correct yet. +*/ + +struct MxUnkListNode { + MxUnkListNode *m_unk00; + MxUnkListNode *m_unk04; + undefined4 m_unk08; +}; + +class MxUnkList { +public: + inline MxUnkList() { + undefined unk; + this->m_unk00 = unk; + + MxUnkListNode *node = new MxUnkListNode(); + node->m_unk00 = node; + node->m_unk04 = node; + + this->m_head = node; + this->m_count = 0; + } + + undefined m_unk00; + MxUnkListNode *m_head; + MxU32 m_count; +}; + +#endif // MXUNKLIST_H \ No newline at end of file From 3ac0c5d86c9c87e52119522451c44e3b0ff9cd28 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sun, 8 Oct 2023 16:00:59 -0400 Subject: [PATCH 75/87] Implement LegoVideoManager::MoveCursor and improve SetSkyColor (#190) * improved SetSkyColor match * LegoVideoManager::MoveCursor * rename parameters * Minor improvements --------- Co-authored-by: Christian Semmler --- LEGO1/legovideomanager.cpp | 33 +++++++++++++++++++++++---------- LEGO1/legovideomanager.h | 17 ++++++++++++++--- LEGO1/mxpalette.h | 1 + LEGO1/mxvideomanager.h | 2 +- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/LEGO1/legovideomanager.cpp b/LEGO1/legovideomanager.cpp index 4105ef2a..ca7926b9 100644 --- a/LEGO1/legovideomanager.cpp +++ b/LEGO1/legovideomanager.cpp @@ -1,5 +1,6 @@ #include "legovideomanager.h" -#include + +DECOMP_SIZE_ASSERT(LegoVideoManager, 0x590); // OFFSET: LEGO1 0x1007aa20 STUB LegoVideoManager::LegoVideoManager() @@ -39,20 +40,32 @@ void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable, MxBool p_scale) // TODO } -// OFFSET: LEGO1 0x1007b6a0 STUB -void LegoVideoManager::MoveCursor(int x, int y) +// OFFSET: LEGO1 0x1007b6a0 +void LegoVideoManager::MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY) { - // TODO + m_cursorX = p_cursorX; + m_cursorY = p_cursorY; + m_cursorMoved = TRUE; + + if (623 < p_cursorX) + m_cursorX = 623; + + if (463 < p_cursorY) + m_cursorY = 463; } // OFFSET: LEGO1 0x1007c440 -void LegoVideoManager::SetSkyColor(float red, float green, float blue) +void LegoVideoManager::SetSkyColor(float p_red, float p_green, float p_blue) { - PALETTEENTRY colorStrucure; // [esp+0h] [ebp-4h] BYREF + PALETTEENTRY colorStrucure; - colorStrucure.peRed = (red* 255.0); - colorStrucure.peGreen = (green * 255.0); - colorStrucure.peBlue = (blue * 255.0); + colorStrucure.peRed = (p_red * 255.0f); + colorStrucure.peGreen = (p_green * 255.0f); + colorStrucure.peBlue = (p_blue * 255.0f); colorStrucure.peFlags = -124; - // TODO + m_videoParam.GetPalette()->SetSkyColor(&colorStrucure); + m_videoParam.GetPalette()->SetOverrideSkyColor(TRUE); + + // TODO 3d manager + //m_3dManager->m_pViewport->vtable1c(red, green, blue) } diff --git a/LEGO1/legovideomanager.h b/LEGO1/legovideomanager.h index 4ff8491b..cc051f16 100644 --- a/LEGO1/legovideomanager.h +++ b/LEGO1/legovideomanager.h @@ -6,6 +6,8 @@ #include "lego3dmanager.h" #include "decomp.h" +#include + // VTABLE 0x100d9c88 // SIZE 0x590 class LegoVideoManager : public MxVideoManager @@ -24,7 +26,10 @@ class LegoVideoManager : public MxVideoManager inline MxDirect3D *GetDirect3D() { return this->m_direct3d; } void SetSkyColor(float r, float g, float b); - inline void SetUnkE4(MxBool p_value) { this->m_unke4 = p_value; } + inline void SetUnkE4(MxBool p_unk0xe4) { this->m_unk0xe4 = p_unk0xe4; } + + // OFFSET: LEGO1 0x1007c4c0 + void OverrideSkyColor(MxBool p_shouldOverride) { this->m_videoParam.GetPalette()->SetOverrideSkyColor(p_shouldOverride);} private: undefined4 m_unk64; @@ -32,8 +37,14 @@ class LegoVideoManager : public MxVideoManager undefined4 m_unk6c; undefined4 m_unk70; MxDirect3D *m_direct3d; - undefined m_pad78[0x6c]; - MxBool m_unke4; + undefined m_pad0x78[0x6c]; + MxBool m_unk0xe4; + undefined m_pad0xe8[0x41c]; + MxBool m_cursorMoved; // 0x501 + undefined m_pad0x502[0x8]; + MxS32 m_cursorX; // 0x50c + MxS32 m_cursorY; // 0x510 + undefined m_pad0x514[0x7c]; }; #endif // LEGOVIDEOMANAGER_H diff --git a/LEGO1/mxpalette.h b/LEGO1/mxpalette.h index b024330a..7c9568b1 100644 --- a/LEGO1/mxpalette.h +++ b/LEGO1/mxpalette.h @@ -26,6 +26,7 @@ class MxPalette : public MxCore MxResult SetSkyColor(LPPALETTEENTRY p_sky_color); void Reset(MxBool p_ignoreSkyColor); LPDIRECTDRAWPALETTE CreateNativePalette(); + inline void SetOverrideSkyColor(MxBool p_value) { this->m_overrideSkyColor = p_value; } private: LPDIRECTDRAWPALETTE m_palette; PALETTEENTRY m_entries[256]; // 0xc diff --git a/LEGO1/mxvideomanager.h b/LEGO1/mxvideomanager.h index d72c1d10..f6e1a726 100644 --- a/LEGO1/mxvideomanager.h +++ b/LEGO1/mxvideomanager.h @@ -29,7 +29,7 @@ class MxVideoManager : public MxMediaManager inline MxVideoParam& GetVideoParam() { return this->m_videoParam; } inline LPDIRECTDRAW GetDirectDraw() { return this->m_pDirectDraw; } inline MxDisplaySurface *GetDisplaySurface() { return this->m_displaySurface; } -private: +protected: MxVideoParam m_videoParam; LPDIRECTDRAW m_pDirectDraw; LPDIRECTDRAWSURFACE m_pDDSurface; From d82649c6f06817f01098ef0c93a9adbbca519149 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sun, 8 Oct 2023 16:41:34 -0400 Subject: [PATCH 76/87] MxStream provider and controller vtables (#191) * MxStreamProvider and MxRamStreamProvider vtable * Update mxramstreamprovider.h * Match IsA * Fixes, improvements --------- Co-authored-by: Christian Semmler --- CMakeLists.txt | 2 ++ ISLE/isleapp.cpp | 4 +-- LEGO1/mxramstreamcontroller.cpp | 22 ++++++++++++ LEGO1/mxramstreamcontroller.h | 17 ++++++++++ LEGO1/mxramstreamprovider.cpp | 59 +++++++++++++++++++++++++++++++++ LEGO1/mxramstreamprovider.h | 15 +++++++++ LEGO1/mxstreamcontroller.cpp | 27 ++++++++++++++- LEGO1/mxstreamcontroller.h | 12 +++++-- LEGO1/mxstreamer.cpp | 4 +-- LEGO1/mxstreamprovider.cpp | 17 ++++++++++ LEGO1/mxstreamprovider.h | 14 +++++--- 11 files changed, 181 insertions(+), 12 deletions(-) create mode 100644 LEGO1/mxramstreamprovider.cpp create mode 100644 LEGO1/mxstreamprovider.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a3573874..2e0fed5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,6 +154,7 @@ add_library(lego1 SHARED LEGO1/mxpresenter.cpp LEGO1/mxpresenterlist.cpp LEGO1/mxramstreamcontroller.cpp + LEGO1/mxramstreamprovider.cpp LEGO1/mxscheduler.cpp LEGO1/mxsemaphore.cpp LEGO1/mxsmkpresenter.cpp @@ -162,6 +163,7 @@ add_library(lego1 SHARED LEGO1/mxstillpresenter.cpp LEGO1/mxstreamcontroller.cpp LEGO1/mxstreamer.cpp + LEGO1/mxstreamprovider.cpp LEGO1/mxstring.cpp LEGO1/mxstringlist.cpp LEGO1/mxthread.cpp diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 503a7128..803ef45e 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -734,7 +734,7 @@ inline void IsleApp::Tick(BOOL sleepIfNotNextFrame) return; } - ds.SetAtomId(stream->atom); + ds.SetAtomId(stream->GetAtom()); ds.SetUnknown24(-1); ds.SetObjectId(0); VideoManager()->EnableFullScreenMovie(TRUE, TRUE); @@ -743,7 +743,7 @@ inline void IsleApp::Tick(BOOL sleepIfNotNextFrame) return; } } else { - ds.SetAtomId(stream->atom); + ds.SetAtomId(stream->GetAtom()); ds.SetUnknown24(-1); ds.SetObjectId(0); if (Start(&ds) != SUCCESS) { diff --git a/LEGO1/mxramstreamcontroller.cpp b/LEGO1/mxramstreamcontroller.cpp index a96046a0..9796b05a 100644 --- a/LEGO1/mxramstreamcontroller.cpp +++ b/LEGO1/mxramstreamcontroller.cpp @@ -1,3 +1,25 @@ #include "mxramstreamcontroller.h" +#include "mxramstreamprovider.h" DECOMP_SIZE_ASSERT(MxRAMStreamController, 0x98); + +// OFFSET: LEGO1 0x100c6110 STUB +MxResult MxRAMStreamController::Open(const char *p_filename) +{ + // TODO STUB + return FAILURE; +} + +// OFFSET: LEGO1 0x100c6210 STUB +MxResult MxRAMStreamController::vtable0x20(MxDSAction* p_action) +{ + // TODO STUB + return FAILURE; +} + +// OFFSET: LEGO1 0x100c6320 STUB +MxResult MxRAMStreamController::vtable0x24(undefined4 p_unknown) +{ + // TODO STUB + return FAILURE; +} diff --git a/LEGO1/mxramstreamcontroller.h b/LEGO1/mxramstreamcontroller.h index 563d9cb6..62587bca 100644 --- a/LEGO1/mxramstreamcontroller.h +++ b/LEGO1/mxramstreamcontroller.h @@ -11,6 +11,23 @@ class MxRAMStreamController : public MxStreamController public: inline MxRAMStreamController() {} + // OFFSET: LEGO1 0x100b9430 + inline virtual const char *ClassName() const override // vtable+0xc + { + // 0x10102130 + return "MxRAMStreamController"; + } + + // OFFSET: LEGO1 0x100b9440 + inline virtual MxBool IsA(const char *name) const override // vtable+0x10 + { + return !strcmp(name, MxRAMStreamController::ClassName()) || !strcmp(name, MxStreamController::ClassName()) || MxCore::IsA(name); + } + + virtual MxResult Open(const char *p_filename) override; + virtual MxResult vtable0x20(MxDSAction* p_action) override; + virtual MxResult vtable0x24(undefined4 p_unknown) override; + private: MxDSBuffer m_buffer; diff --git a/LEGO1/mxramstreamprovider.cpp b/LEGO1/mxramstreamprovider.cpp new file mode 100644 index 00000000..9b052699 --- /dev/null +++ b/LEGO1/mxramstreamprovider.cpp @@ -0,0 +1,59 @@ +#include "mxramstreamprovider.h" +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxRAMStreamProvider, 0x24); + +// OFFSET: LEGO1 0x100d0730 +MxRAMStreamProvider::MxRAMStreamProvider() +{ + m_bufferSize = 0; + m_fileSize = 0; + m_pBufferOfFileSize = NULL; + m_lengthInDWords = 0; + m_bufferForDWords = NULL; +} + +// OFFSET: LEGO1 0x100d0a50 +MxRAMStreamProvider::~MxRAMStreamProvider() +{ + m_bufferSize = 0; + m_fileSize = 0; + + free(m_pBufferOfFileSize); + m_pBufferOfFileSize = NULL; + + m_lengthInDWords = 0; + + free(m_bufferForDWords); + m_bufferForDWords = NULL; +} + +// OFFSET: LEGO1 0x100d0ae0 STUB +MxResult MxRAMStreamProvider::SetResourceToGet(void* p_resource) +{ + return FAILURE; +} + +// OFFSET: LEGO1 0x100d0930 +MxU32 MxRAMStreamProvider::GetFileSize() +{ + return m_fileSize; +} + +// OFFSET: LEGO1 0x100d0940 +MxU32 MxRAMStreamProvider::vtable0x1C() +{ + return 1; +} + +// OFFSET: LEGO1 0x100d0950 +MxU32 MxRAMStreamProvider::GetLengthInDWords() +{ + return m_lengthInDWords; +} + +// OFFSET: LEGO1 0x100d0960 +void* MxRAMStreamProvider::GetBufferForDWords() +{ + return m_bufferForDWords; +} diff --git a/LEGO1/mxramstreamprovider.h b/LEGO1/mxramstreamprovider.h index 5422d3b3..4a22b013 100644 --- a/LEGO1/mxramstreamprovider.h +++ b/LEGO1/mxramstreamprovider.h @@ -6,7 +6,22 @@ // VTABLE 0x100dd0d0 class MxRAMStreamProvider : public MxStreamProvider { +public: + MxRAMStreamProvider(); + virtual ~MxRAMStreamProvider() override; + + virtual MxResult SetResourceToGet(void* p_resource) override; //vtable+0x14 + virtual MxU32 GetFileSize() override; //vtable+0x18 + virtual MxU32 vtable0x1C() override; //vtable+0x1c + virtual MxU32 GetLengthInDWords() override; //vtable+0x24 + virtual void* GetBufferForDWords() override; //vtable+0x28 +protected: + MxU32 m_bufferSize; + MxU32 m_fileSize; + void* m_pBufferOfFileSize; + MxU32 m_lengthInDWords; + void* m_bufferForDWords; }; #endif // MXRAMSTREAMPROVIDER_H diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index 83917cd4..36b85ebc 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -46,8 +46,33 @@ MxResult MxStreamController::vtable0x1C(undefined4 p_unknown, undefined4 p_unkno } // OFFSET: LEGO1 0x100c1690 STUB -MxResult MxStreamController::vtable0x20(MxDSAction* action) +MxResult MxStreamController::vtable0x20(MxDSAction* p_action) { // TODO STUB return FAILURE; } + +// OFFSET: LEGO1 0x100c1740 STUB +MxResult MxStreamController::vtable0x24(undefined4 p_unknown) +{ + // TODO STUB + return FAILURE; +} + +// OFFSET: LEGO1 0x100b9420 +MxResult MxStreamController::vtable0x28() +{ + return SUCCESS; +} + +// OFFSET: LEGO1 0x100c1c10 STUB +MxResult MxStreamController::vtable0x2c(undefined4 p_unknown1, undefined4 p_unknow2) +{ + return FAILURE; +} + +// OFFSET: LEGO1 0x100c1ce0 STUB +MxResult MxStreamController::vtable0x30(undefined4 p_unknown) +{ + return FAILURE; +} diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index 0f459ed0..59490d2c 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -33,14 +33,20 @@ class MxStreamController : public MxCore virtual MxResult Open(const char *p_filename); // vtable+0x14 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* action); //vtable+0x20 + virtual MxResult vtable0x20(MxDSAction* p_action); //vtable+0x20 + virtual MxResult vtable0x24(undefined4 p_unknown); //vtable+0x24 + virtual MxResult vtable0x28(); //vtable+0x28 + virtual MxResult vtable0x2c(undefined4 p_unknown1, undefined4 p_unknow2); //vtable+0x2c + virtual MxResult vtable0x30(undefined4 p_unknown); //vtable+0x30 MxBool FUN_100c20d0(MxDSObject &p_obj); + inline MxAtomId &GetAtom() { return atom; }; +protected: MxCriticalSection m_criticalSection; MxAtomId atom; - int m_unk28; - int m_unk2c; + undefined4 m_unk28; // MxStreamProvider* + undefined4 m_unk2c; undefined m_unk30[0x34]; }; diff --git a/LEGO1/mxstreamer.cpp b/LEGO1/mxstreamer.cpp index c6ef85bd..8e7cc231 100644 --- a/LEGO1/mxstreamer.cpp +++ b/LEGO1/mxstreamer.cpp @@ -80,7 +80,7 @@ MxLong MxStreamer::Close(const char *p) for (list::iterator it = m_openStreams.begin(); it != m_openStreams.end(); it++) { MxStreamController *c = *it; - if (!p || !strcmp(p, c->atom.GetInternal())) { + if (!p || !strcmp(p, c->GetAtom().GetInternal())) { m_openStreams.erase(it); if (!c->FUN_100c20d0(ds)) { @@ -109,7 +109,7 @@ MxStreamController *MxStreamer::GetOpenStream(const char *p_name) { for (list::iterator it = m_openStreams.begin(); it != m_openStreams.end(); it++) { MxStreamController *c = *it; - MxAtomId &atom = c->atom; + MxAtomId &atom = c->GetAtom(); if (p_name) { if (!strcmp(atom.GetInternal(), p_name)) { return *it; diff --git a/LEGO1/mxstreamprovider.cpp b/LEGO1/mxstreamprovider.cpp new file mode 100644 index 00000000..c9dab949 --- /dev/null +++ b/LEGO1/mxstreamprovider.cpp @@ -0,0 +1,17 @@ +#include "decomp.h" +#include "mxstreamprovider.h" + +DECOMP_SIZE_ASSERT(MxStreamProvider, 0x10); + +// OFFSET: LEGO1 0x100d07c0 +MxResult MxStreamProvider::SetResourceToGet(void* p_resource) +{ + m_pLookup = p_resource; + return SUCCESS; +} + +// OFFSET: LEGO1 0x100d07d0 +void MxStreamProvider::vtable0x20(undefined4 p_unknown1) +{ + +} diff --git a/LEGO1/mxstreamprovider.h b/LEGO1/mxstreamprovider.h index 2daf75ab..3cb11144 100644 --- a/LEGO1/mxstreamprovider.h +++ b/LEGO1/mxstreamprovider.h @@ -1,17 +1,16 @@ #ifndef MXSTREAMPROVIDER_H #define MXSTREAMPROVIDER_H +#include "decomp.h" #include "mxcore.h" #include "mxdsfile.h" // VTABLE 0x100dd100 +// SIZE 0x10 class MxStreamProvider : public MxCore { public: - inline MxStreamProvider() { - this->m_pLookup = NULL; - this->m_pFile = NULL; - } + inline MxStreamProvider() : m_pLookup(NULL), m_pFile(NULL) {} // OFFSET: LEGO1 0x100d07e0 inline virtual const char *ClassName() const override // vtable+0x0c @@ -25,6 +24,13 @@ class MxStreamProvider : public MxCore return !strcmp(name, MxStreamProvider::ClassName()) || MxCore::IsA(name); } + virtual MxResult SetResourceToGet(void* p_resource); //vtable+0x14 + virtual MxU32 GetFileSize() = 0; //vtable+0x18 + virtual MxU32 vtable0x1C() = 0; //vtable+0x1c + virtual void vtable0x20(undefined4 p_unknown1); //vtable+0x20 + virtual MxU32 GetLengthInDWords() = 0; //vtable+0x24 + virtual void* GetBufferForDWords() = 0; //vtable+0x28 + protected: void *m_pLookup; MxDSFile* m_pFile; From 0db96ce2d6b9410a22cf667bcc3ec1cccf48f948 Mon Sep 17 00:00:00 2001 From: Angel <67720650+AngelTomkins@users.noreply.github.com> Date: Mon, 9 Oct 2023 05:04:35 -0400 Subject: [PATCH 77/87] Implemented MxVector4::UnknownQuaternionOp (#192) * Corrected typo in reccmp.py * Implemented MxVector4::UnknownQuaternionOp 65% similar to the original * Brought MxVector4::DotImpl to 100% match --- LEGO1/mxvector.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/LEGO1/mxvector.cpp b/LEGO1/mxvector.cpp index a4053105..9c7c2a07 100644 --- a/LEGO1/mxvector.cpp +++ b/LEGO1/mxvector.cpp @@ -371,7 +371,7 @@ float MxVector4::DotImpl(float *p_a, float *p_b) const { return p_a[0] * p_b[0] + p_a[2] * p_b[2] + - p_a[1] * p_b[1] + p_a[3] * p_b[3]; + (p_a[1] * p_b[1] + p_a[3] * p_b[3]); } // OFFSET: LEGO1 0x10002a20 @@ -453,8 +453,19 @@ MxResult MxVector4::NormalizeQuaternion() return FAILURE; } -// OFFSET: LEGO1 0x10002bf0 STUB +// OFFSET: LEGO1 0x10002bf0 void MxVector4::UnknownQuaternionOp(MxVector4 *p_a, MxVector4 *p_b) { + MxFloat *bDat = p_b->m_data; + MxFloat *aDat = p_a->m_data; -} \ No newline at end of file + this->m_data[3] = aDat[3] * bDat[3] - (bDat[0] * aDat[0] + aDat[2] *bDat[2] + aDat[1] * aDat[1]); + this->m_data[0] = bDat[2] * aDat[1] - bDat[1] * aDat[2]; + this->m_data[1] = aDat[2] * bDat[0] - bDat[2] * aDat[0]; + this->m_data[2] = bDat[1] * aDat[0] - aDat[1] * bDat[0]; + + + m_data[0] = p_b->m_data[3] * p_a->m_data[0] + p_a->m_data[3] * p_b->m_data[0] + m_data[0]; + m_data[1] = p_b->m_data[1] * p_a->m_data[3] + p_a->m_data[1] * p_b->m_data[3] + m_data[1]; + m_data[2] = p_b->m_data[2] * p_a->m_data[3] + p_a->m_data[2] * p_b->m_data[3] + m_data[2]; +} From 625ee52fe080a36fa442875f959a6701d6050f33 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Mon, 9 Oct 2023 06:31:36 -0400 Subject: [PATCH 78/87] implement a few mxomni/legoomni functions (#193) --- ISLE/isleapp.cpp | 2 +- LEGO1/legoomni.cpp | 29 ++++++++++++++++++++--------- LEGO1/legoomni.h | 11 +++++------ LEGO1/mxomni.cpp | 6 ++++++ LEGO1/mxomni.h | 1 + 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 803ef45e..a4a73035 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -708,7 +708,7 @@ inline void IsleApp::Tick(BOOL sleepIfNotNextFrame) } if (this->m_frameDelta + g_lastFrameTime < currentTime) { - if (!Lego()->vtable40()) { + if (!Lego()->IsTimerRunning()) { TickleManager()->Tickle(); } g_lastFrameTime = currentTime; diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index f4480bb8..33f88a58 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -6,7 +6,7 @@ #include "legoutil.h" // 0x100f4588 -char *g_nocdSourceName = NULL; +MxAtomId *g_nocdSourceName = NULL; // 0x101020e8 void (*g_omniUserMessage)(const char *,int); @@ -225,7 +225,7 @@ MxTransitionManager *TransitionManager() // OFFSET: LEGO1 0x10053430 const char *GetNoCD_SourceName() { - return g_nocdSourceName; + return g_nocdSourceName->GetInternal(); } // OFFSET: LEGO1 0x1005b5f0 @@ -252,7 +252,23 @@ LegoEntity *PickEntity(MxLong,MxLong) // OFFSET: LEGO1 0x10058bd0 void LegoOmni::Init() { - // FIXME: Stub + MxOmni::Init(); + m_unk68 = 0; + m_inputMgr = NULL; + m_unk6c = 0; + m_unk74 = 0; + m_unk78 = 0; + m_currentWorld = NULL; + m_unk80 = FALSE; + m_isle = NULL; + m_unk8c = 0; + m_plantManager = NULL; + m_gameState = NULL; + m_animationManager = NULL; + m_buildingManager = NULL; + m_bkgAudioManager = NULL; + m_unk13c = TRUE; + m_transitionManager = NULL; } // OFFSET: LEGO1 0x10058e70 @@ -266,6 +282,7 @@ MxResult LegoOmni::Create(COMPAT_CONST MxOmniCreateParam &p) return SUCCESS; } +// OFFSET: LEGO1 0x10058c30 STUB void LegoOmni::Destroy() { // FIXME: Stub @@ -322,12 +339,6 @@ void LegoOmni::StopTimer() SetAppCursor(0); } -MxBool LegoOmni::vtable40() -{ - // FIXME: Stub - return 0; -} - // OFFSET: LEGO1 0x100157a0 LegoWorld *GetCurrentWorld() { diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 4de0d1b5..d1c1b9be 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -4,6 +4,7 @@ #include "compat.h" #include "mxomni.h" #include "mxdsaction.h" +#include "legoanimationmanager.h" class Isle; class LegoBuildingManager; @@ -62,7 +63,6 @@ class LegoOmni : public MxOmni virtual void NotifyCurrentEntity() override; virtual void StartTimer() override; virtual void StopTimer() override; - virtual MxBool vtable40(); LegoVideoManager *GetVideoManager() { return (LegoVideoManager *) m_videoManager; } LegoSoundManager *GetSoundManager() { return (LegoSoundManager *)m_soundManager;} @@ -83,19 +83,18 @@ class LegoOmni : public MxOmni undefined4 m_unk74; undefined4 m_unk78; LegoWorld *m_currentWorld; - undefined4 m_unk80; + MxBool m_unk80; LegoNavController *m_navController; // 0x84 Isle* m_isle; // 0x88 - char m_unk8c[0x4]; + undefined4 m_unk8c; LegoPlantManager* m_plantManager; // 0x90 - char m_unk94[0x4]; + LegoAnimationManager* m_animationManager; LegoBuildingManager* m_buildingManager; // 0x98 LegoGameState *m_gameState; // 0x9c MxDSAction m_action; MxBackgroundAudioManager *m_bkgAudioManager; // 0x134 MxTransitionManager *m_transitionManager; // 0x138 - int m_unk13c; - + MxBool m_unk13c; }; __declspec(dllexport) MxBackgroundAudioManager * BackgroundAudioManager(); diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index fb3251da..69473b0d 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -121,6 +121,12 @@ void MxOmni::StopTimer() } } +// OFFSET: LEGO1 0x10058a90 +MxBool MxOmni::IsTimerRunning() +{ + return m_timerRunning; +} + // OFFSET: LEGO1 0x100b0690 void MxOmni::DestroyInstance() { diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 5290c6ed..9b2c6581 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -48,6 +48,7 @@ class MxOmni : public MxCore virtual void NotifyCurrentEntity(); // vtable+34 virtual void StartTimer(); // vtable+38 virtual void StopTimer(); // vtable+3c + virtual MxBool IsTimerRunning(); //vtable+40 static void SetInstance(MxOmni* instance); HWND GetWindowHandle() const { return this->m_windowHandle; } MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; } From 28206402f9c235770a01e332ff890609ee660484 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 9 Oct 2023 06:33:06 -0400 Subject: [PATCH 79/87] Use forward declaration for LegoAnimationManager in LegoOmni --- LEGO1/legoomni.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index d1c1b9be..e4074463 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -4,9 +4,9 @@ #include "compat.h" #include "mxomni.h" #include "mxdsaction.h" -#include "legoanimationmanager.h" class Isle; +class LegoAnimationManager; class LegoBuildingManager; class LegoEntity; class LegoGameState; From 49efa02eaa127d0f5e4e25657423398cd120f227 Mon Sep 17 00:00:00 2001 From: MS Date: Mon, 9 Oct 2023 18:20:38 -0400 Subject: [PATCH 80/87] MxBitmap code clarity (#195) * MxBitmap code clarity * Use mxtypes. TWOCC for BM string. SetSize arg to FALSE --- LEGO1/mxbitmap.cpp | 135 ++++++++++++++++++++------------------- LEGO1/mxbitmap.h | 12 ++-- LEGO1/mxsmkpresenter.cpp | 2 +- 3 files changed, 76 insertions(+), 73 deletions(-) diff --git a/LEGO1/mxbitmap.cpp b/LEGO1/mxbitmap.cpp index 5987f31f..8f33fc22 100644 --- a/LEGO1/mxbitmap.cpp +++ b/LEGO1/mxbitmap.cpp @@ -1,12 +1,13 @@ #include "mxbitmap.h" #include "decomp.h" -DECOMP_SIZE_ASSERT(MxBITMAPINFO, 1064); +DECOMP_SIZE_ASSERT(MxBitmap, 0x20); +DECOMP_SIZE_ASSERT(MxBITMAPINFO, 0x428); -// The way that the BITMAPFILEHEADER structure ensures the file type is by ensuring it is "BM", which is literally just 0x424d. +// Bitmap header magic string "BM" (42 4d) // Sources: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapfileheader, DirectX Complete (1998) // GLOBAL: LEGO1 0x10102184 -undefined2 g_bitmapSignature = 0x424d; +MxU16 g_bitmapSignature = TWOCC('B', 'M'); // OFFSET: LEGO1 0x100bc980 MxBitmap::MxBitmap() @@ -15,7 +16,7 @@ MxBitmap::MxBitmap() this->m_bmiHeader = NULL; this->m_paletteData = NULL; this->m_data = NULL; - this->m_bitDepth = LOWCOLOR; + this->m_isHighColor = FALSE; this->m_palette = NULL; } @@ -30,43 +31,54 @@ MxBitmap::~MxBitmap() delete m_palette; } +// Bit mask trick to round up to the nearest multiple of four. +// Pixel data may be stored with padding. +// https://learn.microsoft.com/en-us/windows/win32/medfound/image-stride +inline MxLong AlignToFourByte(MxLong p_value) +{ + return (p_value + 3) & -4; +} + +// Same as the one from legoutil.h, but flipped the other way +// TODO: While it's not outside the realm of possibility that they +// reimplemented Abs for only this file, that seems odd, right? +inline MxLong _Abs(MxLong p_value) +{ + return p_value > 0 ? p_value : -p_value; +} + // OFFSET: LEGO1 0x100bcc40 MxResult MxBitmap::ImportBitmap(MxBitmap *p_bitmap) { - MxLong height; MxResult result = FAILURE; this->m_info = new MxBITMAPINFO; if(this->m_info) { - height = p_bitmap->m_bmiHeader->biHeight; - if (height <= 0L) { - height = -height; - } - this->m_data = (LPVOID*) new MxU8[(p_bitmap->m_bmiHeader->biWidth + 3U & -4) * height]; + MxLong height = _Abs(p_bitmap->m_bmiHeader->biHeight); + this->m_data = new MxU8[AlignToFourByte(p_bitmap->m_bmiHeader->biWidth) * height]; if(this->m_data) { - memcpy(this->m_info, p_bitmap->m_info, sizeof(MxBITMAPINFO)); - - height = p_bitmap->m_bmiHeader->biHeight; - if (height <= 0L) { - height = -height; - } - memcpy(this->m_data, p_bitmap->m_data, (p_bitmap->m_bmiHeader->biWidth + 3U & -4) * height); + memcpy(this->m_info, p_bitmap->m_info, sizeof(*this->m_info)); + height = _Abs(p_bitmap->m_bmiHeader->biHeight); + memcpy(this->m_data, p_bitmap->m_data, AlignToFourByte(p_bitmap->m_bmiHeader->biWidth) * height); result = SUCCESS; this->m_bmiHeader = &this->m_info->bmiHeader; this->m_paletteData = this->m_info->bmiColors; } } + if (result != SUCCESS) { if (this->m_info) { delete this->m_info; this->m_info = NULL; } + if (this->m_data) { delete this->m_data; this->m_data = NULL; } } + return result; } @@ -76,29 +88,31 @@ MxResult MxBitmap::ImportBitmapInfo(MxBITMAPINFO *p_info) MxResult result = FAILURE; MxLong width = p_info->bmiHeader.biWidth; MxLong height = p_info->bmiHeader.biHeight; - // ((width + 3) & -4) clamps width to nearest 4-byte boundary - MxLong size = ((width + 3) & -4) * height; + MxLong size = AlignToFourByte(width) * height; this->m_info = new MxBITMAPINFO; if (this->m_info) { - this->m_data = (LPVOID*) new MxU8[size]; + this->m_data = new MxU8[size]; if(this->m_data) { - memcpy(this->m_info, p_info, sizeof(MxBITMAPINFO)); + memcpy(this->m_info, p_info, sizeof(*this->m_info)); this->m_bmiHeader = &this->m_info->bmiHeader; this->m_paletteData = this->m_info->bmiColors; result = SUCCESS; } } + if (result != SUCCESS) { if (this->m_info) { delete this->m_info; this->m_info = NULL; } + if (this->m_data) { delete this->m_data; this->m_data = NULL; } } + return result; } @@ -118,7 +132,7 @@ MxResult MxBitmap::ImportColorsToPalette(RGBQUAD* p_rgbquad, MxPalette* p_palett return ret; } - for (int i = 0; i < 256; i++) { + for (MxS32 i = 0; i < 256; i++) { p_rgbquad[i].rgbRed = entries[i].peRed; p_rgbquad[i].rgbGreen = entries[i].peGreen; p_rgbquad[i].rgbBlue = entries[i].peBlue; @@ -130,14 +144,14 @@ MxResult MxBitmap::ImportColorsToPalette(RGBQUAD* p_rgbquad, MxPalette* p_palett } // OFFSET: LEGO1 0x100bcaa0 -MxResult MxBitmap::SetSize(int p_width, int p_height, MxPalette *p_palette, int p_bitDepth) +MxResult MxBitmap::SetSize(MxS32 p_width, MxS32 p_height, MxPalette *p_palette, MxBool p_isHighColor) { MxResult ret = FAILURE; - MxLong size = ((p_width + 3) & -4) * p_height; + MxLong size = AlignToFourByte(p_width) * p_height; m_info = new MxBITMAPINFO; if (m_info) { - m_data = (LPVOID*) new MxU8[size]; + m_data = new MxU8[size]; if (m_data) { m_bmiHeader = &m_info->bmiHeader; m_paletteData = m_info->bmiColors; @@ -152,7 +166,7 @@ MxResult MxBitmap::SetSize(int p_width, int p_height, MxPalette *p_palette, int m_bmiHeader->biSizeImage = size; if (!ImportColorsToPalette(m_paletteData, p_palette)) { - if (!SetBitDepth(p_bitDepth)) { + if (!SetBitDepth(p_isHighColor)) { ret = SUCCESS; } } @@ -177,34 +191,26 @@ MxResult MxBitmap::SetSize(int p_width, int p_height, MxPalette *p_palette, int // OFFSET: LEGO1 0x100bcd60 MxResult MxBitmap::LoadFile(HANDLE p_handle) { - BOOL ret; - LPVOID* lpBuffer; - MxLong height; MxResult result = FAILURE; DWORD bytesRead; BITMAPFILEHEADER hdr; - MxLong size; - ret = ReadFile(p_handle, &hdr, sizeof(hdr), &bytesRead, NULL); + BOOL ret = ReadFile(p_handle, &hdr, sizeof(hdr), &bytesRead, NULL); if (ret && (hdr.bfType == g_bitmapSignature)) { this->m_info = new MxBITMAPINFO; - if(this->m_info) { - ret = ReadFile(p_handle, this->m_info, sizeof(MxBITMAPINFO), &bytesRead, NULL); - if (ret && ((this->m_info->bmiHeader).biBitCount == 8)) { - size = hdr.bfSize - (sizeof(MxBITMAPINFO) + sizeof(BITMAPFILEHEADER)); - lpBuffer = (LPVOID*) new MxU8[size]; - this->m_data = lpBuffer; - if (lpBuffer) { - ret = ReadFile(p_handle, lpBuffer, size, &bytesRead, NULL); - if(ret) { + if (this->m_info) { + ret = ReadFile(p_handle, this->m_info, sizeof(*this->m_info), &bytesRead, NULL); + if (ret && (this->m_info->bmiHeader.biBitCount == 8)) { + MxLong size = hdr.bfSize - (sizeof(MxBITMAPINFO) + sizeof(BITMAPFILEHEADER)); + this->m_data = new MxU8[size]; + if (this->m_data) { + ret = ReadFile(p_handle, this->m_data, size, &bytesRead, NULL); + if (ret) { this->m_bmiHeader = &this->m_info->bmiHeader; this->m_paletteData = this->m_info->bmiColors; - if((this->m_info->bmiHeader).biSizeImage == 0) { - height = (this->m_info->bmiHeader).biHeight; - if (height <= 0L) { - height = -height; - } - (this->m_info->bmiHeader).biSizeImage = ((this->m_info->bmiHeader).biWidth + 3U & -4) * height; + if (this->m_info->bmiHeader.biSizeImage == 0) { + MxLong height = _Abs(this->m_info->bmiHeader.biHeight); + this->m_info->bmiHeader.biSizeImage = AlignToFourByte(this->m_info->bmiHeader.biWidth) * height; } result = SUCCESS; } @@ -212,16 +218,19 @@ MxResult MxBitmap::LoadFile(HANDLE p_handle) } } } + if (result != SUCCESS) { if (this->m_info) { delete this->m_info; this->m_info = NULL; } + if (this->m_data) { delete this->m_data; this->m_data = NULL; } } + return result; } @@ -270,14 +279,14 @@ MxPalette *MxBitmap::CreatePalette() MxBool success = FALSE; MxPalette *palette = NULL; - switch (this->m_bitDepth) { - case LOWCOLOR: + switch (this->m_isHighColor) { + case FALSE: palette = new MxPalette(this->m_paletteData); if (palette) success = TRUE; break; - case HIGHCOLOR: + case TRUE: palette = this->m_palette->Clone(); if (palette) success = TRUE; @@ -295,14 +304,13 @@ MxPalette *MxBitmap::CreatePalette() // OFFSET: LEGO1 0x100bd280 void MxBitmap::ImportPalette(MxPalette* p_palette) { - // This is weird but it matches. Maybe m_bmiColorsProvided had more - // potential values than just true/false at some point? - switch (this->m_bitDepth) { - case LOWCOLOR: + // Odd to use a switch on a boolean, but it matches. + switch (this->m_isHighColor) { + case FALSE: ImportColorsToPalette(this->m_paletteData, p_palette); break; - case HIGHCOLOR: + case TRUE: if (this->m_palette) { delete this->m_palette; } @@ -312,18 +320,17 @@ void MxBitmap::ImportPalette(MxPalette* p_palette) } // OFFSET: LEGO1 0x100bd2d0 -MxResult MxBitmap::SetBitDepth(MxBool p_bitDepth) +MxResult MxBitmap::SetBitDepth(MxBool p_isHighColor) { MxResult ret = FAILURE; MxPalette *pal = NULL; - if (m_bitDepth == p_bitDepth) { + if (m_isHighColor == p_isHighColor) { // no change: do nothing. ret = SUCCESS; } else { - // TODO: Another switch used for this boolean value? Is it not a bool? - switch (p_bitDepth) { - case 0: + switch (p_isHighColor) { + case FALSE: ImportColorsToPalette(m_paletteData, m_palette); if (m_palette) delete m_palette; @@ -331,7 +338,7 @@ MxResult MxBitmap::SetBitDepth(MxBool p_bitDepth) m_palette = NULL; break; - case 1: + case TRUE: pal = NULL; pal = new MxPalette(m_paletteData); if (pal) { @@ -343,7 +350,7 @@ MxResult MxBitmap::SetBitDepth(MxBool p_bitDepth) buf[i] = i; } - m_bitDepth = p_bitDepth; + m_isHighColor = p_isHighColor; ret = SUCCESS; } break; @@ -359,12 +366,12 @@ MxResult MxBitmap::SetBitDepth(MxBool p_bitDepth) } // OFFSET: LEGO1 0x100bd3e0 -MxResult MxBitmap::StretchBits(HDC p_hdc, int p_xSrc, int p_ySrc, int p_xDest, int p_yDest, int p_destWidth, int p_destHeight) +MxResult MxBitmap::StretchBits(HDC p_hdc, MxS32 p_xSrc, MxS32 p_ySrc, MxS32 p_xDest, MxS32 p_yDest, MxS32 p_destWidth, MxS32 p_destHeight) { // Compression fix? if ((this->m_bmiHeader->biCompression != 16) && (0 < this->m_bmiHeader->biHeight)) { p_ySrc = (this->m_bmiHeader->biHeight - p_destHeight) - p_ySrc; } - return StretchDIBits(p_hdc, p_xDest, p_yDest, p_destWidth, p_destHeight, p_xSrc, p_ySrc, p_destWidth, p_destHeight, this->m_data, (BITMAPINFO*)this->m_info, this->m_bitDepth, SRCCOPY); -} \ No newline at end of file + return StretchDIBits(p_hdc, p_xDest, p_yDest, p_destWidth, p_destHeight, p_xSrc, p_ySrc, p_destWidth, p_destHeight, this->m_data, (BITMAPINFO*)this->m_info, this->m_isHighColor, SRCCOPY); +} diff --git a/LEGO1/mxbitmap.h b/LEGO1/mxbitmap.h index 791581c6..53b01e16 100644 --- a/LEGO1/mxbitmap.h +++ b/LEGO1/mxbitmap.h @@ -21,10 +21,6 @@ struct MxBITMAPINFO { RGBQUAD bmiColors[256]; }; -// These values are the bit depth, set in the registry -#define LOWCOLOR 0 // 256 color -#define HIGHCOLOR 1 // High Color (16-bit) - // SIZE 0x20 // VTABLE 0x100dc7b0 class MxBitmap : public MxCore @@ -35,7 +31,7 @@ class MxBitmap : public MxCore virtual MxResult ImportBitmap(MxBitmap *p_bitmap); // vtable+14 virtual MxResult ImportBitmapInfo(MxBITMAPINFO *p_info); // vtable+18 - virtual MxResult SetSize(int p_width, int p_height, MxPalette *p_palette, int); // vtable+1c + virtual MxResult SetSize(MxS32 p_width, MxS32 p_height, MxPalette *p_palette, MxBool); // vtable+1c virtual MxResult LoadFile(HANDLE p_handle); // vtable+20 __declspec(dllexport) virtual MxLong Read(const char *p_filename); // vtable+24 virtual int vtable28(int); @@ -44,7 +40,7 @@ class MxBitmap : public MxCore __declspec(dllexport) virtual MxPalette *CreatePalette(); // vtable+34 virtual void ImportPalette(MxPalette* p_palette); // vtable+38 virtual MxResult SetBitDepth(MxBool); // vtable+3c - virtual MxResult StretchBits(HDC p_hdc, int p_xSrc, int p_ySrc, int p_xDest, int p_yDest, int p_destWidth, int p_destHeight); // vtable+40 + virtual MxResult StretchBits(HDC p_hdc, MxS32 p_xSrc, MxS32 p_ySrc, MxS32 p_xDest, MxS32 p_yDest, MxS32 p_destWidth, MxS32 p_destHeight); // vtable+40 inline BITMAPINFOHEADER *GetBmiHeader() const { return m_bmiHeader; } @@ -54,8 +50,8 @@ class MxBitmap : public MxCore MxBITMAPINFO *m_info; // 0x8 BITMAPINFOHEADER *m_bmiHeader; // 0xc RGBQUAD *m_paletteData; // 0x10 - LPVOID *m_data; // 0x14 - MxBool m_bitDepth; // 0x18 + MxU8 *m_data; // 0x14 + MxBool m_isHighColor; // 0x18 MxPalette *m_palette; // 0x1c }; diff --git a/LEGO1/mxsmkpresenter.cpp b/LEGO1/mxsmkpresenter.cpp index 99faae22..d8699862 100644 --- a/LEGO1/mxsmkpresenter.cpp +++ b/LEGO1/mxsmkpresenter.cpp @@ -24,5 +24,5 @@ void MxSmkPresenter::VTable0x60() } m_bitmap = new MxBitmap(); - m_bitmap->SetSize(m_smkWidth, m_smkHeight, NULL, NULL); + m_bitmap->SetSize(m_smkWidth, m_smkHeight, NULL, FALSE); } From 114a959741a7ef5355cfe6092315bd67a9687f93 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Tue, 10 Oct 2023 04:27:00 -0400 Subject: [PATCH 81/87] MxDiskStreamController vtable (#197) * mxdiskstreamcontroller vtable + MxStreamController::vtable0x20 * stub MxDiskStreamController::Open * MxDiskStreamProvider * MxNextActionDataStart * Revert "MxNextActionDataStart" This reverts commit 41e8cfa2f11ea4f9b39df0bdf0c3657fdbd9efe9. * Match MxStreamController::vtable0x20 --------- Co-authored-by: Christian Semmler --- LEGO1/mxdiskstreamcontroller.cpp | 48 +++++++++++++++++++++++++++++++- LEGO1/mxdiskstreamcontroller.h | 7 +++++ LEGO1/mxdiskstreamprovider.cpp | 39 +++++++++++++++++++++++++- LEGO1/mxdiskstreamprovider.h | 7 +++++ LEGO1/mxdsfile.cpp | 4 +-- LEGO1/mxdssource.cpp | 2 +- LEGO1/mxdssource.h | 4 +-- LEGO1/mxramstreamprovider.cpp | 4 +-- LEGO1/mxramstreamprovider.h | 8 +++--- LEGO1/mxstreamcontroller.cpp | 23 ++++++++++++--- LEGO1/mxstreamcontroller.h | 5 ++-- LEGO1/mxstreamprovider.h | 4 +-- 12 files changed, 134 insertions(+), 21 deletions(-) diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp index 9e37edc4..0c74c3a7 100644 --- a/LEGO1/mxdiskstreamcontroller.cpp +++ b/LEGO1/mxdiskstreamcontroller.cpp @@ -16,6 +16,52 @@ MxDiskStreamController::~MxDiskStreamController() MxResult MxDiskStreamController::Tickle() { // TODO - return 0; } + +// OFFSET: LEGO1 0x100c7790 STUB +MxResult MxDiskStreamController::Open(const char *p_filename) +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100c7880 +MxResult MxDiskStreamController::vtable0x18(undefined4 p_unknown, undefined4 p_unknown2) +{ + return SUCCESS; +} + +// OFFSET: LEGO1 0x100c7ff0 STUB +MxResult MxDiskStreamController::vtable0x20(MxDSAction* p_action) +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100c8160 STUB +MxResult MxDiskStreamController::vtable0x24(undefined4 p_unknown) +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100c7ac0 STUB +MxResult MxDiskStreamController::vtable0x28() +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100c7c00 STUB +MxResult MxDiskStreamController::vtable0x30(undefined4 p_unknown) +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100c7960 +MxResult MxDiskStreamController::vtable0x34(undefined4 p_unknown) +{ + return FAILURE; +} diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index 1f66984c..5457a9b5 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -15,6 +15,13 @@ class MxDiskStreamController : public MxStreamController virtual ~MxDiskStreamController() override; virtual MxResult Tickle() override; // vtable+0x8 + virtual MxResult Open(const char *p_filename) override; // vtable+0x14 + virtual MxResult vtable0x18(undefined4 p_unknown, undefined4 p_unknown2) override; //vtable+0x18 + virtual MxResult vtable0x20(MxDSAction* p_action) override; //vtable+0x20 + virtual MxResult vtable0x24(undefined4 p_unknown) override; //vtable+0x24 + virtual MxResult vtable0x28() override; //vtable+0x28 + virtual MxResult vtable0x30(undefined4 p_unknown) override; //vtable+0x30 + virtual MxResult vtable0x34(undefined4 p_unknown); //vtable+0x34 // OFFSET: LEGO1 0x100c7360 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp index 4dcb02cf..9555a8cf 100644 --- a/LEGO1/mxdiskstreamprovider.cpp +++ b/LEGO1/mxdiskstreamprovider.cpp @@ -45,4 +45,41 @@ MxResult MxDiskStreamProvider::WaitForWorkToComplete() void MxDiskStreamProvider::PerformWork() { // TODO -} \ No newline at end of file +} + +// OFFSET: LEGO1 0x100d13d0 STUB +MxResult MxDiskStreamProvider::SetResourceToGet(void* p_resource) +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100d1e90 +MxU32 MxDiskStreamProvider::GetFileSize() +{ + return m_pFile->GetBufferSize(); +} + +// OFFSET: LEGO1 0x100d1ea0 +MxU32 MxDiskStreamProvider::GetStreamBuffersNum() +{ + return m_pFile->GetStreamBuffersNum(); +} + +// OFFSET: LEGO1 0x100d15e0 STUB +void MxDiskStreamProvider::vtable0x20(undefined4 p_unknown1) +{ + // TODO +} + +// OFFSET: LEGO1 0x100d1eb0 +MxU32 MxDiskStreamProvider::GetLengthInDWords() +{ + return m_pFile->GetLengthInDWords(); +} + +// OFFSET: LEGO1 0x100d1ec0 +MxU32* MxDiskStreamProvider::GetBufferForDWords() +{ + return m_pFile->GetBuffer(); +} diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index c797a0de..c35826b8 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -49,6 +49,13 @@ class MxDiskStreamProvider : public MxStreamProvider void PerformWork(); + virtual MxResult SetResourceToGet(void* p_resource) override; //vtable+0x14 + virtual MxU32 GetFileSize() override; //vtable+0x18 + virtual MxU32 GetStreamBuffersNum() override; //vtable+0x1c + virtual void vtable0x20(undefined4 p_unknown1) override; //vtable+0x20 + virtual MxU32 GetLengthInDWords() override; //vtable+0x24 + virtual MxU32* GetBufferForDWords()override; //vtable+0x28 + private: MxDiskStreamProviderThread m_thread; // 0x10 MxSemaphore m_busySemaphore; // 0x2c diff --git a/LEGO1/mxdsfile.cpp b/LEGO1/mxdsfile.cpp index ca6e96fb..d1c87032 100644 --- a/LEGO1/mxdsfile.cpp +++ b/LEGO1/mxdsfile.cpp @@ -81,7 +81,7 @@ MxLong MxDSFile::ReadChunks() } MxULong* pLengthInDWords = &m_lengthInDWords; m_io.Read(pLengthInDWords, 4); - m_pBuffer = malloc(*pLengthInDWords * 4); + m_pBuffer = new MxU32[*pLengthInDWords]; m_io.Read(m_pBuffer, *pLengthInDWords * 4); return 0; } @@ -120,7 +120,7 @@ MxLong MxDSFile::Close() if (m_lengthInDWords != 0) { m_lengthInDWords = 0; - free(m_pBuffer); + delete[] m_pBuffer; m_pBuffer = NULL; } return 0; diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp index 4dfb5386..86c4f9fb 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -14,7 +14,7 @@ MxLong MxDSSource::GetLengthInDWords() } // OFFSET: LEGO1 0x100c0000 -void *MxDSSource::GetBuffer() +MxU32 *MxDSSource::GetBuffer() { return m_pBuffer; } \ No newline at end of file diff --git a/LEGO1/mxdssource.h b/LEGO1/mxdssource.h index 67cbc6c7..626eaf37 100644 --- a/LEGO1/mxdssource.h +++ b/LEGO1/mxdssource.h @@ -34,11 +34,11 @@ class MxDSSource : public MxCore virtual MxULong GetBufferSize() = 0; virtual MxULong GetStreamBuffersNum() = 0; virtual MxLong GetLengthInDWords(); - virtual void* GetBuffer(); // 0x34 + virtual MxU32* GetBuffer(); // 0x34 protected: MxULong m_lengthInDWords; - void* m_pBuffer; + MxU32* m_pBuffer; MxLong m_position; }; diff --git a/LEGO1/mxramstreamprovider.cpp b/LEGO1/mxramstreamprovider.cpp index 9b052699..1b44d84f 100644 --- a/LEGO1/mxramstreamprovider.cpp +++ b/LEGO1/mxramstreamprovider.cpp @@ -41,7 +41,7 @@ MxU32 MxRAMStreamProvider::GetFileSize() } // OFFSET: LEGO1 0x100d0940 -MxU32 MxRAMStreamProvider::vtable0x1C() +MxU32 MxRAMStreamProvider::GetStreamBuffersNum() { return 1; } @@ -53,7 +53,7 @@ MxU32 MxRAMStreamProvider::GetLengthInDWords() } // OFFSET: LEGO1 0x100d0960 -void* MxRAMStreamProvider::GetBufferForDWords() +MxU32* MxRAMStreamProvider::GetBufferForDWords() { return m_bufferForDWords; } diff --git a/LEGO1/mxramstreamprovider.h b/LEGO1/mxramstreamprovider.h index 4a22b013..48e0dcae 100644 --- a/LEGO1/mxramstreamprovider.h +++ b/LEGO1/mxramstreamprovider.h @@ -9,19 +9,19 @@ class MxRAMStreamProvider : public MxStreamProvider public: MxRAMStreamProvider(); virtual ~MxRAMStreamProvider() override; - + virtual MxResult SetResourceToGet(void* p_resource) override; //vtable+0x14 virtual MxU32 GetFileSize() override; //vtable+0x18 - virtual MxU32 vtable0x1C() override; //vtable+0x1c + virtual MxU32 GetStreamBuffersNum() override; //vtable+0x1c virtual MxU32 GetLengthInDWords() override; //vtable+0x24 - virtual void* GetBufferForDWords() override; //vtable+0x28 + virtual MxU32* GetBufferForDWords() override; //vtable+0x28 protected: MxU32 m_bufferSize; MxU32 m_fileSize; void* m_pBufferOfFileSize; MxU32 m_lengthInDWords; - void* m_bufferForDWords; + MxU32* m_bufferForDWords; }; #endif // MXRAMSTREAMPROVIDER_H diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index 36b85ebc..89b2fa51 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -45,11 +45,26 @@ MxResult MxStreamController::vtable0x1C(undefined4 p_unknown, undefined4 p_unkno return FAILURE; } -// OFFSET: LEGO1 0x100c1690 STUB +// OFFSET: LEGO1 0x100c1690 MxResult MxStreamController::vtable0x20(MxDSAction* p_action) { - // TODO STUB - return FAILURE; + MxAutoLocker locker(&m_criticalSection); + + MxResult result; + MxU32 offset = 0; + + MxS32 objectId = p_action->GetObjectId(); + MxStreamProvider *provider = m_provider; + + if ((MxS32) provider->GetLengthInDWords() > objectId) + offset = provider->GetBufferForDWords()[objectId]; + + if (offset) + result = vtable0x2c(p_action, offset); + else + result = FAILURE; + + return result; } // OFFSET: LEGO1 0x100c1740 STUB @@ -66,7 +81,7 @@ MxResult MxStreamController::vtable0x28() } // OFFSET: LEGO1 0x100c1c10 STUB -MxResult MxStreamController::vtable0x2c(undefined4 p_unknown1, undefined4 p_unknow2) +MxResult MxStreamController::vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval) { return FAILURE; } diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index 59490d2c..539af0bd 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -7,6 +7,7 @@ #include "mxcore.h" #include "mxdsobject.h" #include "mxdsaction.h" +#include "mxstreamprovider.h" // VTABLE 0x100dc968 // SIZE 0x64 @@ -36,7 +37,7 @@ class MxStreamController : public MxCore virtual MxResult vtable0x20(MxDSAction* p_action); //vtable+0x20 virtual MxResult vtable0x24(undefined4 p_unknown); //vtable+0x24 virtual MxResult vtable0x28(); //vtable+0x28 - virtual MxResult vtable0x2c(undefined4 p_unknown1, undefined4 p_unknow2); //vtable+0x2c + virtual MxResult vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval); //vtable+0x2c virtual MxResult vtable0x30(undefined4 p_unknown); //vtable+0x30 MxBool FUN_100c20d0(MxDSObject &p_obj); @@ -45,7 +46,7 @@ class MxStreamController : public MxCore protected: MxCriticalSection m_criticalSection; MxAtomId atom; - undefined4 m_unk28; // MxStreamProvider* + MxStreamProvider* m_provider; // MxStreamProvider* undefined4 m_unk2c; undefined m_unk30[0x34]; }; diff --git a/LEGO1/mxstreamprovider.h b/LEGO1/mxstreamprovider.h index 3cb11144..fb210f80 100644 --- a/LEGO1/mxstreamprovider.h +++ b/LEGO1/mxstreamprovider.h @@ -26,10 +26,10 @@ class MxStreamProvider : public MxCore virtual MxResult SetResourceToGet(void* p_resource); //vtable+0x14 virtual MxU32 GetFileSize() = 0; //vtable+0x18 - virtual MxU32 vtable0x1C() = 0; //vtable+0x1c + virtual MxU32 GetStreamBuffersNum() = 0; //vtable+0x1c virtual void vtable0x20(undefined4 p_unknown1); //vtable+0x20 virtual MxU32 GetLengthInDWords() = 0; //vtable+0x24 - virtual void* GetBufferForDWords() = 0; //vtable+0x28 + virtual MxU32* GetBufferForDWords() = 0; //vtable+0x28 protected: void *m_pLookup; From d65c87f04d110ac489e1cb1bae535b7aa30eebea Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 10 Oct 2023 05:30:56 -0400 Subject: [PATCH 82/87] Add missing space --- LEGO1/mxdiskstreamprovider.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index c35826b8..de807e3d 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -54,7 +54,7 @@ class MxDiskStreamProvider : public MxStreamProvider virtual MxU32 GetStreamBuffersNum() override; //vtable+0x1c virtual void vtable0x20(undefined4 p_unknown1) override; //vtable+0x20 virtual MxU32 GetLengthInDWords() override; //vtable+0x24 - virtual MxU32* GetBufferForDWords()override; //vtable+0x28 + virtual MxU32* GetBufferForDWords() override; //vtable+0x28 private: MxDiskStreamProviderThread m_thread; // 0x10 From 23b9d47e8a2099b7d19865ca30b20c5e57ea1ed9 Mon Sep 17 00:00:00 2001 From: vMidz <147055059+vMidz@users.noreply.github.com> Date: Tue, 10 Oct 2023 20:05:04 +0300 Subject: [PATCH 83/87] implement EndAction (#196) * implement EndAction implement EndAction +offsets commenets * Refactor MxParam/MxNotificationParam * Add correct address for destructor * Make MxNoticiationParam more concise --------- Co-authored-by: Christian Semmler --- CMakeLists.txt | 3 +- LEGO1/mxactionnotificationparam.cpp | 16 ++++++++ LEGO1/mxactionnotificationparam.h | 59 +++++++++++++++++++++++++++++ LEGO1/mxdsobject.h | 18 ++++----- LEGO1/mxnotificationmanager.cpp | 4 +- LEGO1/mxnotificationmanager.h | 18 +++------ LEGO1/mxnotificationparam.cpp | 11 ++++++ LEGO1/mxnotificationparam.h | 35 +++++++++++++++++ LEGO1/mxomni.cpp | 7 ++-- LEGO1/mxomni.h | 2 +- LEGO1/mxomnicreateparam.h | 4 +- LEGO1/mxomnicreateparambase.cpp | 1 - LEGO1/mxomnicreateparambase.h | 12 ------ LEGO1/mxparam.cpp | 10 ----- LEGO1/mxparam.h | 36 +----------------- LEGO1/mxpresenter.cpp | 20 ++++++++-- LEGO1/mxpresenter.h | 10 ++--- LEGO1/mxstreamer.cpp | 7 ++-- LEGO1/mxstreamer.h | 9 ++--- LEGO1/mxtransitionmanager.cpp | 2 +- 20 files changed, 177 insertions(+), 107 deletions(-) create mode 100644 LEGO1/mxactionnotificationparam.cpp create mode 100644 LEGO1/mxactionnotificationparam.h create mode 100644 LEGO1/mxnotificationparam.cpp create mode 100644 LEGO1/mxnotificationparam.h delete mode 100644 LEGO1/mxomnicreateparambase.cpp delete mode 100644 LEGO1/mxomnicreateparambase.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e0fed5a..2cedd429 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,7 @@ add_library(lego1 SHARED LEGO1/legoworld.cpp LEGO1/legoworldpresenter.cpp LEGO1/motorcycle.cpp + LEGO1/mxactionnotificationparam.cpp LEGO1/mxatomid.cpp LEGO1/mxatomidcounter.cpp LEGO1/mxaudiomanager.cpp @@ -144,11 +145,11 @@ add_library(lego1 SHARED LEGO1/mxmusicmanager.cpp LEGO1/mxmusicpresenter.cpp LEGO1/mxnotificationmanager.cpp + LEGO1/mxnotificationparam.cpp LEGO1/mxobjectfactory.cpp LEGO1/mxomni.cpp LEGO1/mxomnicreateflags.cpp LEGO1/mxomnicreateparam.cpp - LEGO1/mxomnicreateparambase.cpp LEGO1/mxpalette.cpp LEGO1/mxparam.cpp LEGO1/mxpresenter.cpp diff --git a/LEGO1/mxactionnotificationparam.cpp b/LEGO1/mxactionnotificationparam.cpp new file mode 100644 index 00000000..33395c4d --- /dev/null +++ b/LEGO1/mxactionnotificationparam.cpp @@ -0,0 +1,16 @@ +#include "mxactionnotificationparam.h" + +DECOMP_SIZE_ASSERT(MxActionNotificationParam, 0x14) +DECOMP_SIZE_ASSERT(MxEndActionNotificationParam, 0x14) + +// OFFSET: LEGO1 0x100510c0 +MxNotificationParam *MxActionNotificationParam::Clone() +{ + return new MxActionNotificationParam(this->m_type, this->m_sender, this->m_action, this->m_realloc); +} + +// OFFSET: LEGO1 0x10051270 +MxNotificationParam *MxEndActionNotificationParam::Clone() +{ + return new MxEndActionNotificationParam(MXSTREAMER_UNKNOWN, this->m_sender, this->m_action, this->m_realloc); +} diff --git a/LEGO1/mxactionnotificationparam.h b/LEGO1/mxactionnotificationparam.h new file mode 100644 index 00000000..4229e252 --- /dev/null +++ b/LEGO1/mxactionnotificationparam.h @@ -0,0 +1,59 @@ +#ifndef MXACTIONNOTIFICATIONPARAM_H +#define MXACTIONNOTIFICATIONPARAM_H + +#include "mxnotificationparam.h" +#include "mxdsaction.h" + +// VTABLE 0x100d8350 +// SIZE 0x14 +class MxActionNotificationParam : public MxNotificationParam +{ +public: + inline MxActionNotificationParam(MxParamType p_type, MxCore *p_sender, MxDSAction *p_action, MxBool p_reallocAction) : MxNotificationParam(p_type, p_sender) + { + MxDSAction *oldAction = p_action; + this->m_realloc = p_reallocAction; + + if (p_reallocAction) + this->m_action = new MxDSAction(); + else { + this->m_action = oldAction; + return; + } + + this->m_action->SetAtomId(oldAction->GetAtomId()); + this->m_action->SetObjectId(oldAction->GetObjectId()); + this->m_action->SetUnknown24(oldAction->GetUnknown24()); + } + + // OFFSET: LEGO1 0x10051050 + inline virtual MxActionNotificationParam::~MxActionNotificationParam() override + { + if (!this->m_realloc) + return; + + if (this->m_action) + delete this->m_action; + } + + virtual MxNotificationParam *Clone() override; // vtable+0x4 + +protected: + MxDSAction *m_action; // 0xc + MxBool m_realloc; // 0x10 +}; + +// VTABLE 0x100d8358 +// SIZE 0x14 +class MxEndActionNotificationParam : public MxActionNotificationParam +{ +public: + inline MxEndActionNotificationParam(MxParamType p_type, MxCore *p_sender, MxDSAction *p_action, MxBool p_reallocAction) + : MxActionNotificationParam(p_type, p_sender, p_action, p_reallocAction) {} + + inline virtual ~MxEndActionNotificationParam() override {}; // 0x100513a0 + + virtual MxNotificationParam *Clone() override; // vtable+0x4 +}; + +#endif \ No newline at end of file diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index e340789a..cfb5d6a1 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -47,15 +47,15 @@ class MxDSObject : public MxCore inline MxDSType GetType() const { return (MxDSType) this->m_type; } private: - MxU32 m_sizeOnDisk; - MxU16 m_type; - char* m_sourceName; - undefined4 m_unk14; - char *m_objectName; - MxU32 m_objectId; - MxAtomId m_atomId; - MxS16 m_unk24; - undefined4 m_unk28; + MxU32 m_sizeOnDisk; // 0x8 + MxU16 m_type; // 0xc + char* m_sourceName; // 0x10 + undefined4 m_unk14; // 0x14 + char *m_objectName; // 0x18 + MxU32 m_objectId; // 0x1c + MxAtomId m_atomId; // 0x20 + MxS16 m_unk24; // 0x24 + undefined4 m_unk28; // 0x28 }; MxDSObject *DeserializeDSObjectDispatch(char **, MxS16); diff --git a/LEGO1/mxnotificationmanager.cpp b/LEGO1/mxnotificationmanager.cpp index cb653ba4..017df73d 100644 --- a/LEGO1/mxnotificationmanager.cpp +++ b/LEGO1/mxnotificationmanager.cpp @@ -13,7 +13,7 @@ DECOMP_SIZE_ASSERT(MxNotification, 0x8); DECOMP_SIZE_ASSERT(MxNotificationManager, 0x40); // OFFSET: LEGO1 0x100ac220 -MxNotification::MxNotification(MxCore *p_target, MxParam *p_param) +MxNotification::MxNotification(MxCore *p_target, MxNotificationParam *p_param) { m_target = p_target; m_param = p_param->Clone(); @@ -161,7 +161,7 @@ void MxNotificationManager::FlushPending(MxCore *p_listener) } // OFFSET: LEGO1 0x100ac6c0 -MxResult MxNotificationManager::Send(MxCore *p_listener, MxParam *p_param) +MxResult MxNotificationManager::Send(MxCore *p_listener, MxNotificationParam *p_param) { MxAutoLocker lock(&m_lock); diff --git a/LEGO1/mxnotificationmanager.h b/LEGO1/mxnotificationmanager.h index 1c2aee7c..89908871 100644 --- a/LEGO1/mxnotificationmanager.h +++ b/LEGO1/mxnotificationmanager.h @@ -3,6 +3,7 @@ #include "mxcore.h" #include "mxcriticalsection.h" +#include "mxnotificationparam.h" #include "mxtypes.h" #include "compat.h" @@ -10,22 +11,15 @@ class MxNotification { public: - MxNotification(MxCore *p_target, MxParam *p_param); + MxNotification(MxCore *p_target, MxNotificationParam *p_param); ~MxNotification(); - inline MxCore *GetTarget() - { - return m_target; - } - - inline MxParam *GetParam() - { - return m_param; - } + inline MxCore *GetTarget() { return m_target; } + inline MxNotificationParam *GetParam() { return m_param; } private: MxCore *m_target; // 0x0 - MxParam *m_param; // 0x4 + MxNotificationParam *m_param; // 0x4 }; class MxIdList : public list @@ -54,7 +48,7 @@ class MxNotificationManager : public MxCore virtual MxResult Create(MxS32 p_unk1, MxS32 p_unk2); // vtable+0x14 void Register(MxCore *p_listener); void Unregister(MxCore *p_listener); - MxResult Send(MxCore *p_listener, MxParam *p_param); + MxResult Send(MxCore *p_listener, MxNotificationParam *p_param); private: void FlushPending(MxCore *p_listener); diff --git a/LEGO1/mxnotificationparam.cpp b/LEGO1/mxnotificationparam.cpp new file mode 100644 index 00000000..16a0b41f --- /dev/null +++ b/LEGO1/mxnotificationparam.cpp @@ -0,0 +1,11 @@ +#include "mxnotificationparam.h" + +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxNotificationParam, 0xc); + +// OFFSET: LEGO1 0x10010390 +MxNotificationParam* MxNotificationParam::Clone() +{ + return new MxNotificationParam(m_type, m_sender); +} diff --git a/LEGO1/mxnotificationparam.h b/LEGO1/mxnotificationparam.h new file mode 100644 index 00000000..a02f33d8 --- /dev/null +++ b/LEGO1/mxnotificationparam.h @@ -0,0 +1,35 @@ +#ifndef MXNOTIFICATIONPARAM_H +#define MXNOTIFICATIONPARAM_H + +#include "compat.h" +#include "mxparam.h" +#include "mxtypes.h" + +class MxCore; + +enum MxParamType +{ + MXSTREAMER_UNKNOWN = 2, + MXPRESENTER_NOTIFICATION = 5, + MXSTREAMER_DELETE_NOTIFY = 6, + MXTRANSITIONMANAGER_TRANSITIONENDED = 24 +}; + +// VTABLE 0x100d56e0 +class MxNotificationParam : public MxParam +{ +public: + inline MxNotificationParam(MxParamType p_type, MxCore *p_sender) : MxParam(), m_type(p_type), m_sender(p_sender){} + + virtual ~MxNotificationParam() override {} // vtable+0x0 (scalar deleting destructor) + virtual MxNotificationParam *Clone(); // vtable+0x4 + + inline MxParamType GetType() const { return m_type; } + inline MxCore *GetSender() const { return m_sender; } + +protected: + MxParamType m_type; // 0x4 + MxCore *m_sender; // 0x8 +}; + +#endif // MXNOTIFICATIONPARAM_H diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 69473b0d..43b9578a 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -93,10 +93,9 @@ int MxOmni::vtable0x30(char*, int, MxCore*) return 0; } -// OFFSET: LEGO1 0x100aefc0 STUB -void MxOmni::NotifyCurrentEntity() +// OFFSET: LEGO1 0x100aefc0 +void MxOmni::NotifyCurrentEntity(MxParam *p_param) { - // TODO } // OFFSET: LEGO1 0x100b09d0 @@ -352,7 +351,7 @@ MxLong MxOmni::Notify(MxParam &p) { MxAutoLocker lock(&this->m_criticalsection); - if (p.GetType() != MXSTREAMER_UNKNOWN) + if (((MxNotificationParam&) p).GetType() != MXSTREAMER_UNKNOWN) return 0; return HandleNotificationType2(p); diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 9b2c6581..265db29b 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -45,7 +45,7 @@ class MxOmni : public MxCore virtual MxBool DoesEntityExist(MxDSAction &ds); // vtable+28 virtual void vtable0x2c(); // vtable+2c virtual int vtable0x30(char*, int, MxCore*); // vtable+30 - virtual void NotifyCurrentEntity(); // vtable+34 + virtual void NotifyCurrentEntity(MxParam *p_param); // vtable+34 virtual void StartTimer(); // vtable+38 virtual void StopTimer(); // vtable+3c virtual MxBool IsTimerRunning(); //vtable+40 diff --git a/LEGO1/mxomnicreateparam.h b/LEGO1/mxomnicreateparam.h index 3c1059dd..d4984b24 100644 --- a/LEGO1/mxomnicreateparam.h +++ b/LEGO1/mxomnicreateparam.h @@ -4,11 +4,11 @@ #include #include "mxomnicreateflags.h" -#include "mxomnicreateparambase.h" +#include "mxparam.h" #include "mxstring.h" #include "mxvideoparam.h" -class MxOmniCreateParam : public MxOmniCreateParamBase +class MxOmniCreateParam : public MxParam { public: __declspec(dllexport) MxOmniCreateParam(const char *mediaPath, struct HWND__ *windowHandle, MxVideoParam &vparam, MxOmniCreateFlags flags); diff --git a/LEGO1/mxomnicreateparambase.cpp b/LEGO1/mxomnicreateparambase.cpp deleted file mode 100644 index 0091785d..00000000 --- a/LEGO1/mxomnicreateparambase.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "mxomnicreateparam.h" diff --git a/LEGO1/mxomnicreateparambase.h b/LEGO1/mxomnicreateparambase.h deleted file mode 100644 index 605f4d30..00000000 --- a/LEGO1/mxomnicreateparambase.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef MXOMNICREATEPARAMBASE_H -#define MXOMNICREATEPARAMBASE_H - -// FIXME: Clearly not its real name -class MxOmniCreateParamBase -{ -public: - virtual ~MxOmniCreateParamBase(){} - -}; - -#endif // MXOMNICREATEPARAMBASE_H diff --git a/LEGO1/mxparam.cpp b/LEGO1/mxparam.cpp index d7bb36b2..4faa1625 100644 --- a/LEGO1/mxparam.cpp +++ b/LEGO1/mxparam.cpp @@ -1,11 +1 @@ #include "mxparam.h" - -#include "decomp.h" - -DECOMP_SIZE_ASSERT(MxParam, 0xc); - -// OFFSET: LEGO1 0x10010390 -MxParam* MxParam::Clone() -{ - return new MxParam(m_type, m_sender); -} diff --git a/LEGO1/mxparam.h b/LEGO1/mxparam.h index d76ecdb0..8f89e2d0 100644 --- a/LEGO1/mxparam.h +++ b/LEGO1/mxparam.h @@ -1,42 +1,10 @@ #ifndef MXPARAM_H #define MXPARAM_H -#include "compat.h" -#include "mxomnicreateparambase.h" -#include "mxtypes.h" - -class MxCore; - -enum MxParamType -{ - MXSTREAMER_UNKNOWN = 2, - MXPRESENTER_NOTIFICATION = 5, - MXSTREAMER_DELETE_NOTIFY = 6, - MXTRANSITIONMANAGER_TRANSITIONENDED = 24 -}; - -// VTABLE 0x100d56e0 -class MxParam : public MxOmniCreateParamBase +class MxParam { public: - inline MxParam(MxParamType p_type, MxCore *p_sender) : MxOmniCreateParamBase(), m_type(p_type), m_sender(p_sender){} - - virtual ~MxParam() override {} // vtable+0x0 (scalar deleting destructor) - virtual MxParam *Clone(); // vtable+0x4 - - inline MxParamType GetType() const - { - return m_type; - } - - inline MxCore *GetSender() const - { - return m_sender; - } - -protected: - MxParamType m_type; // 0x4 - MxCore *m_sender; // 0x8 + virtual ~MxParam() {} }; #endif // MXPARAM_H diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index f8f60386..86e4ae26 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -6,7 +6,8 @@ #include "mxdsanim.h" #include "mxdssound.h" #include "mxnotificationmanager.h" - +#include "mxactionnotificationparam.h" +#include "mxstreamer.h" #include "decomp.h" #include "define.h" @@ -65,7 +66,7 @@ void MxPresenter::SendTo_unkPresenter(MxOmni *p_omni) if (m_unkPresenter) { MxAutoLocker lock(&m_criticalSection); - NotificationManager()->Send(m_unkPresenter, &MxParam(MXPRESENTER_NOTIFICATION, this)); + NotificationManager()->Send(m_unkPresenter, &MxNotificationParam(MXPRESENTER_NOTIFICATION, this)); m_action->SetOmni(p_omni ? p_omni : MxOmni::GetInstance()); m_unkPresenter = NULL; @@ -135,10 +136,21 @@ MxLong MxPresenter::StartAction(MxStreamController *, MxDSAction *p_action) return SUCCESS; } -// OFFSET: LEGO1 0x100b4e40 STUB +// OFFSET: LEGO1 0x100b4e40 void MxPresenter::EndAction() { - // TODO + if (this->m_action == FALSE) + return; + MxAutoLocker lock(&this->m_criticalSection); + if (!this->m_unkPresenter) + { + MxOmni::GetInstance()->NotifyCurrentEntity(&MxEndActionNotificationParam(MXSTREAMER_UNKNOWN, NULL, this->m_action, TRUE)); + } + + this->m_action = FALSE; + MxS32 previousTickleState = 1 << m_currentTickleState; + this->m_previousTickleStates |= previousTickleState; + this->m_currentTickleState = TickleState_Idle; } // OFFSET: LEGO1 0x100b52d0 diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 959533c5..bcdc5aac 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -79,11 +79,11 @@ class MxPresenter : public MxCore __declspec(dllexport) void Init(); void SendTo_unkPresenter(MxOmni *); TickleState m_currentTickleState; // 0x8 - MxU32 m_previousTickleStates; - MxPoint32 m_location; - MxS32 m_displayZ; - MxDSAction *m_action; // 0 - MxCriticalSection m_criticalSection; + MxU32 m_previousTickleStates; // 0x0c + MxPoint32 m_location; // 0x10 + MxS32 m_displayZ; // 0x18 + MxDSAction *m_action; // 0x1c + MxCriticalSection m_criticalSection; // 0x20 MxPresenter *m_unkPresenter; // 0x3c }; diff --git a/LEGO1/mxstreamer.cpp b/LEGO1/mxstreamer.cpp index 8e7cc231..e95e4558 100644 --- a/LEGO1/mxstreamer.cpp +++ b/LEGO1/mxstreamer.cpp @@ -99,7 +99,7 @@ MxLong MxStreamer::Close(const char *p) } // OFFSET: LEGO1 0x100b9700 -MxParam *MxStreamerNotification::Clone() +MxNotificationParam *MxStreamerNotification::Clone() { return new MxStreamerNotification(m_type, m_sender, m_controller); } @@ -120,7 +120,6 @@ MxStreamController *MxStreamer::GetOpenStream(const char *p_name) return NULL; } - // OFFSET: LEGO1 0x100b9930 MxResult MxStreamer::AddStreamControllerToOpenList(MxStreamController *stream) { @@ -151,7 +150,7 @@ MxResult MxStreamer::Unknown100b99b0(MxDSAction* p_action) // OFFSET: LEGO1 0x100b9b60 MxLong MxStreamer::Notify(MxParam &p) { - if (p.GetType() == MXSTREAMER_DELETE_NOTIFY) { + if (((MxNotificationParam&) p).GetType() == MXSTREAMER_DELETE_NOTIFY) { MxDSAction ds; ds.SetUnknown24(-2); @@ -178,4 +177,4 @@ MxStreamerSubClass1::MxStreamerSubClass1(undefined4 size) for (int i = 0; i >= 0; i--) { ptr[i] = 0; } -} +} \ No newline at end of file diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index 515be51b..529a564a 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -5,7 +5,7 @@ #include "decomp.h" #include "mxcore.h" -#include "mxparam.h" +#include "mxnotificationparam.h" #include "mxstreamcontroller.h" #include "mxtypes.h" @@ -40,17 +40,17 @@ class MxStreamerSubClass3 : public MxStreamerSubClass1 inline MxStreamerSubClass3() : MxStreamerSubClass1(0x80) {} }; -class MxStreamerNotification : public MxParam +class MxStreamerNotification : public MxNotificationParam { public: - inline MxStreamerNotification(MxParamType p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxParam(p_type, p_sender) + inline MxStreamerNotification(MxParamType p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxNotificationParam(p_type, p_sender) { m_controller = p_ctrlr; } virtual ~MxStreamerNotification() override {} - virtual MxParam *Clone() override; + virtual MxNotificationParam *Clone() override; MxStreamController *GetController() { return m_controller; } @@ -102,7 +102,6 @@ class MxStreamer : public MxCore list m_openStreams; // 0x8 MxStreamerSubClass2 m_subclass1; // 0x14 MxStreamerSubClass3 m_subclass2; // 0x20 - }; #endif // MXSTREAMER_H diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 66c99532..12d989c8 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -85,7 +85,7 @@ void MxTransitionManager::EndTransition(MxBool p_notifyWorld) LegoWorld *world = GetCurrentWorld(); if (world) { - world->Notify(MxParam(MXTRANSITIONMANAGER_TRANSITIONENDED, this)); + world->Notify(MxNotificationParam(MXTRANSITIONMANAGER_TRANSITIONENDED, this)); } } } From 93ce1ccfe83e2af29ab658f4e54bedac6c973a33 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 10 Oct 2023 13:22:00 -0400 Subject: [PATCH 84/87] Implement remaining MxDSSelectAction functions (#183) * Implement remaining MxDSSelectAction functions * Fix match --- LEGO1/mxdsmultiaction.h | 4 +- LEGO1/mxdsselectaction.cpp | 80 ++++++++++++++++++++++++++++++++++++++ LEGO1/mxdsselectaction.h | 5 +-- 3 files changed, 83 insertions(+), 6 deletions(-) diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 1689cc2d..4e516333 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -37,10 +37,8 @@ class MxDSMultiAction : public MxDSAction virtual MxBool HasId(MxU32 p_objectId) override; // vtable+34; virtual void SetSomeTimingField(MxLong p_someTimingField) override; // vtable+38; -private: - MxU32 m_sizeOnDisk; - protected: + MxU32 m_sizeOnDisk; MxDSActionList *m_actions; }; diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 58af9543..e49f587a 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -1,4 +1,7 @@ #include "mxdsselectaction.h" +#include "mxvariabletable.h" +#include "mxtimer.h" +#include "mxomni.h" DECOMP_SIZE_ASSERT(MxDSSelectAction, 0xb0) @@ -48,4 +51,81 @@ MxDSAction *MxDSSelectAction::Clone() *clone = *this; return clone; +} + +// OFFSET: LEGO1 0x100cbe10 +MxU32 MxDSSelectAction::GetSizeOnDisk() +{ + MxU32 totalSizeOnDisk = MxDSParallelAction::GetSizeOnDisk(); + + totalSizeOnDisk += strlen(this->m_unk0x9c.GetData()) + 1; + + MxStringListCursor cursor(this->m_unk0xac); + MxString string; + while (cursor.Next(string)) + totalSizeOnDisk += strlen(string.GetData()) + 1; + + // Note: unlike the other classes, MxDSSelectAction does not have its own + // sizeOnDisk member. Instead, it overrides the one from MxDSMultiAction. + this->m_sizeOnDisk = totalSizeOnDisk; + + return totalSizeOnDisk; +} + +// OFFSET: LEGO1 0x100cbf60 +void MxDSSelectAction::Deserialize(char **p_source, MxS16 p_unk24) +{ + MxString string; + MxDSAction::Deserialize(p_source, p_unk24); + + MxU32 extraFlag = *(MxU32*)(*p_source + 4) & 1; + *p_source += 12; + + this->m_unk0x9c = *p_source; + + if (!strnicmp(this->m_unk0x9c.GetData(), "RANDOM_", strlen("RANDOM_"))) { + char buffer[10]; + MxS16 value = atoi(&this->m_unk0x9c.GetData()[strlen("RANDOM_")]); + + srand(Timer()->GetTime()); + MxS32 random = rand() % value; + string = itoa((MxS16) random, buffer, 10); + } + else + string = VariableTable()->GetVariable(*p_source); + + *p_source += strlen(*p_source) + 1; + + MxU32 count = *(MxU32*) *p_source; + *p_source += sizeof(MxU32); + + if (count) { + MxS32 index = -1; + this->m_unk0xac->DeleteAll(); + + MxU32 i; + for (i = 0; i < count; i++) { + if (!strcmp(string.GetData(), *p_source)) + index = i; + + this->m_unk0xac->OtherAppend(*p_source); + *p_source += strlen(*p_source) + 1; + } + + for (i = 0; i < count; i++) { + MxU32 extraFlag = *(MxU32*)(*p_source + 4) & 1; + *p_source += 8; + + MxDSAction *action = (MxDSAction*) DeserializeDSObjectDispatch(p_source, p_unk24); + + if (index == i) + this->m_actions->Append(action); + else + delete action; + + *p_source += extraFlag; + } + } + + *p_source += extraFlag; } \ No newline at end of file diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index 746afc87..7b668a15 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -29,9 +29,8 @@ class MxDSSelectAction : public MxDSParallelAction return !strcmp(name, MxDSSelectAction::ClassName()) || MxDSParallelAction::IsA(name); } - //virtual MxU32 GetSizeOnDisk() override; // vtable+18; - //virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; - //virtual MxLong GetDuration() override; // vtable+24; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; virtual MxDSAction *Clone() override; // vtable+2c; private: From 11dafaf816b0a4364a5290a5950e1d937999d7bb Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 11 Oct 2023 03:50:14 -0400 Subject: [PATCH 85/87] Fix MxDSMediaAction structure/matches (#194) --- LEGO1/mxdsmediaaction.cpp | 11 ++++------- LEGO1/mxdsmediaaction.h | 7 +++++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/LEGO1/mxdsmediaaction.cpp b/LEGO1/mxdsmediaaction.cpp index 19f3bde2..125156d7 100644 --- a/LEGO1/mxdsmediaaction.cpp +++ b/LEGO1/mxdsmediaaction.cpp @@ -8,8 +8,8 @@ DECOMP_SIZE_ASSERT(MxDSMediaAction, 0xb8) MxDSMediaAction::MxDSMediaAction() { this->m_mediaSrcPath = NULL; - this->m_unk9c = 0; - this->m_unka0 = 0; + this->m_unk9c.m_unk00 = 0; + this->m_unk9c.m_unk04 = 0; this->m_framesPerSecond = 0; this->m_mediaFormat = 0; this->m_paletteManagement = 1; @@ -29,10 +29,7 @@ void MxDSMediaAction::CopyFrom(MxDSMediaAction &p_dsMediaAction) { CopyMediaSrcPath(p_dsMediaAction.m_mediaSrcPath); - // TODO this->m_unk9c = p_dsMediaAction.m_unk9c; - this->m_unka0 = p_dsMediaAction.m_unka0; - this->m_framesPerSecond = p_dsMediaAction.m_framesPerSecond; this->m_mediaFormat = p_dsMediaAction.m_mediaFormat; this->m_paletteManagement = p_dsMediaAction.m_paletteManagement; @@ -71,8 +68,8 @@ void MxDSMediaAction::Deserialize(char **p_source, MxS16 p_unk24) MxDSAction::Deserialize(p_source, p_unk24); GetString(p_source, this->m_mediaSrcPath, this, &MxDSMediaAction::CopyMediaSrcPath); - GetScalar(p_source, this->m_unk9c); - GetScalar(p_source, this->m_unka0); + GetScalar(p_source, this->m_unk9c.m_unk00); + GetScalar(p_source, this->m_unk9c.m_unk04); GetScalar(p_source, this->m_framesPerSecond); GetScalar(p_source, this->m_mediaFormat); GetScalar(p_source, this->m_paletteManagement); diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index 34b6695e..a6303227 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -3,6 +3,7 @@ #include "decomp.h" #include "mxdsaction.h" +#include "mxpoint32.h" // VTABLE 0x100dcd40 // SIZE 0xb8 @@ -38,8 +39,10 @@ class MxDSMediaAction : public MxDSAction private: MxU32 m_sizeOnDisk; char *m_mediaSrcPath; - undefined4 m_unk9c; - undefined4 m_unka0; + struct { + undefined4 m_unk00; + undefined4 m_unk04; + } m_unk9c; MxS32 m_framesPerSecond; MxS32 m_mediaFormat; MxS32 m_paletteManagement; From 02d003673dce7e0b7f438ae8090967f91289a4a5 Mon Sep 17 00:00:00 2001 From: DmitriLeon2000 Date: Wed, 11 Oct 2023 19:18:26 +0900 Subject: [PATCH 86/87] Implement MxMusicPresenter's Destroy method and move MxMediaPresenter's Destroy method to "protected" (#199) * MxMusicPresenter destroy * Implement MxMusicPresenter's Destroy method and move MxMediaPresenter's Destroy method to "protected" * MxMediaPresenter Destroy to "protected", for real * MxMusicPresenter Destroy --- LEGO1/mxmediapresenter.h | 3 ++- LEGO1/mxmusicpresenter.cpp | 14 +++++++++++--- LEGO1/mxmusicpresenter.h | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/LEGO1/mxmediapresenter.h b/LEGO1/mxmediapresenter.h index 167b10c1..6b8fd552 100644 --- a/LEGO1/mxmediapresenter.h +++ b/LEGO1/mxmediapresenter.h @@ -43,9 +43,10 @@ class MxMediaPresenter : public MxPresenter undefined4 m_unk44; undefined4 m_unk48; undefined4 m_unk4c; +protected: + void Destroy(MxBool); private: void Init(); - void Destroy(MxBool); }; diff --git a/LEGO1/mxmusicpresenter.cpp b/LEGO1/mxmusicpresenter.cpp index 45a56679..f376c64f 100644 --- a/LEGO1/mxmusicpresenter.cpp +++ b/LEGO1/mxmusicpresenter.cpp @@ -23,10 +23,18 @@ void MxMusicPresenter::Init() { } -// OFFSET: LEGO1 0x100c2550 STUB -void MxMusicPresenter::Destroy(MxBool) +// OFFSET: LEGO1 0x100c2550 +void MxMusicPresenter::Destroy(MxBool p_reinit) { - // TODO + if (MusicManager()) { + MusicManager()->RemovePresenter(*this); + } + m_criticalSection.Enter(); + Init(); + m_criticalSection.Leave(); + if (!p_reinit) { + MxMediaPresenter::Destroy(FALSE); + } } // OFFSET: LEGO1 0x100c25a0 diff --git a/LEGO1/mxmusicpresenter.h b/LEGO1/mxmusicpresenter.h index 2e55aa6c..ff765786 100644 --- a/LEGO1/mxmusicpresenter.h +++ b/LEGO1/mxmusicpresenter.h @@ -29,7 +29,7 @@ class MxMusicPresenter : public MxAudioPresenter private: void Init(); - void Destroy(MxBool); + void Destroy(MxBool p_reinit); }; #endif // MXMUSICPRESENTER_H From 19ee8cdc3041ebf81cf0dee5707e957d19203108 Mon Sep 17 00:00:00 2001 From: Angel <67720650+AngelTomkins@users.noreply.github.com> Date: Wed, 11 Oct 2023 06:18:48 -0400 Subject: [PATCH 87/87] Implemented MxVector4::SetMatrixProductWrapper (#198) * Implemented the function wrapper for SetMatrixProduct labeled as SetMatrixProductWrapper with 100% match. * Rename for consistency --------- Co-authored-by: Christian Semmler --- LEGO1/mxvector.cpp | 7 ++++--- LEGO1/mxvector.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/LEGO1/mxvector.cpp b/LEGO1/mxvector.cpp index 9c7c2a07..ad4060e0 100644 --- a/LEGO1/mxvector.cpp +++ b/LEGO1/mxvector.cpp @@ -410,13 +410,14 @@ void MxVector4::EqualsScalar(float *p_value) m_data[3] = *p_value; } -// OFFSET: LEGO1 0x10002ae0 STUB -void MxVector4::unk1(MxVector4 *p_a, float *p_b) +// OFFSET: LEGO1 0x10002ae0 +void MxVector4::SetMatrixProduct(MxVector4 *p_a, float *p_b) { + SetMatrixProductImpl(p_a->m_data, p_b); } // OFFSET: LEGO1 0x10002a40 -void MxVector4::SetMatrixProduct(float *p_vec, float *p_mat) +void MxVector4::SetMatrixProductImpl(float *p_vec, float *p_mat) { m_data[0] = p_vec[0] * p_mat[0] + p_vec[1] * p_mat[4] + diff --git a/LEGO1/mxvector.h b/LEGO1/mxvector.h index eef1d927..b2d0bf54 100644 --- a/LEGO1/mxvector.h +++ b/LEGO1/mxvector.h @@ -125,8 +125,8 @@ class MxVector4 : public MxVector3 void EqualsScalar(float *p_value); // vtable + 0x84 - virtual void unk1(MxVector4 *p_a, float *p_b); - virtual void SetMatrixProduct(float *p_vec, float *p_mat); + virtual void SetMatrixProduct(MxVector4 *p_a, float *p_b); + virtual void SetMatrixProductImpl(float *p_vec, float *p_mat); virtual MxResult NormalizeQuaternion(); virtual void UnknownQuaternionOp(MxVector4 *p_a, MxVector4 *p_b); };