From 915390602bbee7030d124683b45803e7eddf7c85 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 26 Sep 2023 07:24:28 -0400 Subject: [PATCH 1/9] 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 2/9] 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 3/9] 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 4/9] 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 5/9] 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 6/9] 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 7/9] 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 8/9] 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 9/9] 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: