From a7acf8c607d7b62e76a42f9850bb9ca6353a9cb5 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Thu, 1 Feb 2024 18:08:56 -0500 Subject: [PATCH] Implement/match InfocenterState::InfocenterState (#515) * Implement LegoState::Shuffle * Remove unused params * Move ctor * Asm generate hotfix --------- Co-authored-by: MS --- LEGO1/lego/legoomni/include/infocenter.h | 9 ++ LEGO1/lego/legoomni/include/infocenterstate.h | 16 +-- LEGO1/lego/legoomni/include/legostate.h | 40 +++++-- .../legoomni/include/legovehiclebuildstate.h | 2 +- LEGO1/lego/legoomni/include/radiostate.h | 6 +- LEGO1/lego/legoomni/src/common/legostate.cpp | 6 +- .../src/infocenter/infocenterstate.cpp | 101 +++++++++++++++++- LEGO1/lego/legoomni/src/isle/radiostate.cpp | 30 ++---- .../isledecomp/compare/asm/parse.py | 7 +- 9 files changed, 167 insertions(+), 50 deletions(-) diff --git a/LEGO1/lego/legoomni/include/infocenter.h b/LEGO1/lego/legoomni/include/infocenter.h index 3c0d04d6..cd033c03 100644 --- a/LEGO1/lego/legoomni/include/infocenter.h +++ b/LEGO1/lego/legoomni/include/infocenter.h @@ -146,6 +146,15 @@ class Infocenter : public LegoWorld { c_leaveInfoCenterDialogue3 = 564, c_leaveInfoCenterDialogue4 = 565, + c_unk566 = 566, + c_unk567 = 567, + c_unk568 = 568, + + c_unk569 = 569, + c_unk570 = 570, + c_unk571 = 571, + c_unk572 = 572, + c_registerToContinueDialogue = 573, c_bricksterDialogue = 574, diff --git a/LEGO1/lego/legoomni/include/infocenterstate.h b/LEGO1/lego/legoomni/include/infocenterstate.h index 7e651740..977ea3d1 100644 --- a/LEGO1/lego/legoomni/include/infocenterstate.h +++ b/LEGO1/lego/legoomni/include/infocenterstate.h @@ -30,9 +30,9 @@ class InfocenterState : public LegoState { inline MxS16 GetInfocenterBufferSize() { return sizeof(m_buffer) / sizeof(m_buffer[0]); } inline MxStillPresenter* GetInfocenterBufferElement(MxS32 p_index) { return m_buffer[p_index]; } - inline StateStruct& GetUnknown0x08() { return m_unk0x08; } - inline StateStruct& GetUnknown0x14() { return m_unk0x14; } - inline StateStruct& GetUnknown0x68() { return m_unk0x68; } + inline Shuffle& GetUnknown0x08() { return m_unk0x08; } + inline Shuffle& GetUnknown0x14() { return m_unk0x14; } + inline Shuffle& GetUnknown0x68() { return m_unk0x68; } inline MxU32 GetUnknown0x74() { return m_unk0x74; } inline void SetUnknown0x74(MxU32 p_unk0x74) { m_unk0x74 = p_unk0x74; } @@ -41,11 +41,11 @@ class InfocenterState : public LegoState { // InfocenterState::`scalar deleting destructor' private: - StateStruct m_unk0x08; // 0x08 - StateStruct m_unk0x14; // 0x14 - StateStruct m_unk0x20[3]; // 0x20 - StateStruct m_unk0x44[3]; // 0x44 - StateStruct m_unk0x68; // 0x68 + Shuffle m_unk0x08; // 0x08 + Shuffle m_unk0x14; // 0x14 + Shuffle m_unk0x20[3]; // 0x20 + Shuffle m_unk0x44[3]; // 0x44 + Shuffle m_unk0x68; // 0x68 MxU32 m_unk0x74; // 0x74 MxStillPresenter* m_buffer[7]; // 0x78 }; diff --git a/LEGO1/lego/legoomni/include/legostate.h b/LEGO1/lego/legoomni/include/legostate.h index 8aa55226..42fd0fe9 100644 --- a/LEGO1/lego/legoomni/include/legostate.h +++ b/LEGO1/lego/legoomni/include/legostate.h @@ -45,23 +45,45 @@ class LegoState : public MxCore { // LegoState::`scalar deleting destructor' // SIZE 0x0c - struct StateStruct { - void* m_unk0x00; // 0x00 - undefined2 m_unk0x04; // 0x04 - undefined2 m_unk0x06; // 0x06 - MxU16 m_unk0x08; // 0x08 - + class Shuffle { + public: // FUNCTION: LEGO1 0x10017c00 - StateStruct() + Shuffle() { - m_unk0x04 = 0; - m_unk0x00 = NULL; + m_objectIds = NULL; + m_length = 0; m_unk0x06 = 0; m_unk0x08 = 0; } + Shuffle(MxU32* p_objectIds, MxU16 p_length) + { + m_objectIds = p_objectIds; + m_length = p_length; + m_unk0x06 = 0; + m_unk0x08 = 0; + } + + // FUNCTION: LEGO1 0x10071800 + Shuffle& operator=(const Shuffle& p_shuffle) + { + m_objectIds = p_shuffle.m_objectIds; + m_length = p_shuffle.m_length; + m_unk0x08 = p_shuffle.m_unk0x08; + m_unk0x06 = p_shuffle.m_unk0x06; + return *this; + } + MxU32 FUN_10014d00(); MxBool FUN_10014de0(MxU32 p_objectId); + + inline void SetUnknown0x08(MxU16 p_unk0x08) { m_unk0x08 = p_unk0x08; } + + private: + MxU32* m_objectIds; // 0x00 + MxU16 m_length; // 0x04 + undefined2 m_unk0x06; // 0x06 + MxU16 m_unk0x08; // 0x08 }; }; diff --git a/LEGO1/lego/legoomni/include/legovehiclebuildstate.h b/LEGO1/lego/legoomni/include/legovehiclebuildstate.h index 83032325..03e72ae9 100644 --- a/LEGO1/lego/legoomni/include/legovehiclebuildstate.h +++ b/LEGO1/lego/legoomni/include/legovehiclebuildstate.h @@ -29,7 +29,7 @@ class LegoVehicleBuildState : public LegoState { // LegoVehicleBuildState::`scalar deleting destructor' private: - StateStruct m_unk0x08[4]; // 0x08 + Shuffle m_unk0x08[4]; // 0x08 // This can be one of the following: // * LegoRaceCarBuildState diff --git a/LEGO1/lego/legoomni/include/radiostate.h b/LEGO1/lego/legoomni/include/radiostate.h index cffef003..5ffd0176 100644 --- a/LEGO1/lego/legoomni/include/radiostate.h +++ b/LEGO1/lego/legoomni/include/radiostate.h @@ -36,9 +36,9 @@ class RadioState : public LegoState { MxBool FUN_1002d0c0(const MxAtomId& p_atom, MxU32 p_objectId); private: - StateStruct m_unk0x08[3]; // 0x08 - MxS16 m_unk0x2c; // 0x2c - MxBool m_active; // 0x2e + Shuffle m_unk0x08[3]; // 0x08 + MxS16 m_unk0x2c; // 0x2c + MxBool m_active; // 0x2e }; #endif // RADIOSTATE_H diff --git a/LEGO1/lego/legoomni/src/common/legostate.cpp b/LEGO1/lego/legoomni/src/common/legostate.cpp index 96a08dbe..4cc7622f 100644 --- a/LEGO1/lego/legoomni/src/common/legostate.cpp +++ b/LEGO1/lego/legoomni/src/common/legostate.cpp @@ -1,17 +1,17 @@ #include "legostate.h" DECOMP_SIZE_ASSERT(LegoState, 0x08) -DECOMP_SIZE_ASSERT(LegoState::StateStruct, 0x0c) +DECOMP_SIZE_ASSERT(LegoState::Shuffle, 0x0c) // STUB: LEGO1 0x10014d00 -MxU32 LegoState::StateStruct::FUN_10014d00() +MxU32 LegoState::Shuffle::FUN_10014d00() { // TODO return 0; } // STUB: LEGO1 0x10014de0 -MxBool LegoState::StateStruct::FUN_10014de0(MxU32 p_objectId) +MxBool LegoState::Shuffle::FUN_10014de0(MxU32 p_objectId) { // TODO return FALSE; diff --git a/LEGO1/lego/legoomni/src/infocenter/infocenterstate.cpp b/LEGO1/lego/legoomni/src/infocenter/infocenterstate.cpp index 76ffd3ea..a6de4a6f 100644 --- a/LEGO1/lego/legoomni/src/infocenter/infocenterstate.cpp +++ b/LEGO1/lego/legoomni/src/infocenter/infocenterstate.cpp @@ -1,11 +1,110 @@ #include "infocenterstate.h" +#include "infocenter.h" + DECOMP_SIZE_ASSERT(InfocenterState, 0x94); +// GLOBAL: LEGO1 0x100f76a8 +Infocenter::InfomainScript g_unk0x100f76a8[14] = { + Infocenter::c_clickOnObjectsGuidanceDialogue, + Infocenter::c_arrowNavigationGuidanceDialogue, + Infocenter::c_elevatorGuidanceDialogue, + Infocenter::c_radioGuidanceDialogue, + Infocenter::c_exitGuidanceDialogue1, + Infocenter::c_goOutsideGuidanceDialogue, + Infocenter::c_experimentGuidanceDialogue, + Infocenter::c_returnBackGuidanceDialogue1, + Infocenter::c_bricksterWarningDialogue, + Infocenter::c_infomanHiccup, + Infocenter::c_infomanSneeze, + Infocenter::c_infomanLaughs, + Infocenter::c_newGameGuidanceDialogue, + Infocenter::c_returnBackGuidanceDialogue3 +}; + +// GLOBAL: LEGO1 0x100f76e0 +Infocenter::InfomainScript g_unk0x100f76e0[6] = { + Infocenter::c_bricksterWarningDialogue, + Infocenter::c_newGameGuidanceDialogue, + Infocenter::c_bricksterEscapedDialogue1, + Infocenter::c_bricksterEscapedDialogue5, + Infocenter::c_exitGuidanceDialogue2 + // Zero-terminated +}; + +// GLOBAL: LEGO1 0x100f76f8 +Infocenter::InfomainScript g_unk0x100f76f8[6] = { + Infocenter::c_returnBackGuidanceDialogue2, + Infocenter::c_reenterInfoCenterDialogue1, + Infocenter::c_reenterInfoCenterDialogue2, + Infocenter::c_reenterInfoCenterDialogue3, + Infocenter::c_reenterInfoCenterDialogue4 + // Zero-terminated +}; + +// GLOBAL: LEGO1 0x100f7710 +Infocenter::InfomainScript g_unk0x100f7710[4] = { + Infocenter::c_bricksterEscapedDialogue1, + Infocenter::c_bricksterEscapedDialogue2, + Infocenter::c_bricksterEscapedDialogue3, + // Zero-terminated +}; + +// GLOBAL: LEGO1 0x100f7720 +Infocenter::InfomainScript g_unk0x100f7720[4] = { + Infocenter::c_bricksterEscapedDialogue4, + Infocenter::c_bricksterEscapedDialogue5, + Infocenter::c_bricksterEscapedDialogue6, + Infocenter::c_bricksterEscapedDialogue7 +}; + +// GLOBAL: LEGO1 0x100f7730 +Infocenter::InfomainScript g_unk0x100f7730[4] = { + Infocenter::c_leaveInfoCenterDialogue1, + Infocenter::c_leaveInfoCenterDialogue2, + Infocenter::c_leaveInfoCenterDialogue3, + Infocenter::c_leaveInfoCenterDialogue4 +}; + +// GLOBAL: LEGO1 0x100f7740 +Infocenter::InfomainScript g_unk0x100f7740[4] = + {Infocenter::c_unk569, Infocenter::c_unk570, Infocenter::c_unk571, Infocenter::c_unk572}; + +// GLOBAL: LEGO1 0x100f7750 +Infocenter::InfomainScript g_unk0x100f7750[4] = { + Infocenter::c_unk566, + Infocenter::c_unk567, + Infocenter::c_unk568, + // Zero-terminated +}; + +// GLOBAL: LEGO1 0x100f7760 +Infocenter::InfomainScript g_unk0x100f7760[2] = {Infocenter::c_bricksterDialogue, Infocenter::c_bricksterLaughs}; + // FUNCTION: LEGO1 0x10071600 InfocenterState::InfocenterState() { - // TODO + m_unk0x08 = LegoState::Shuffle((MxU32*) g_unk0x100f76a8, sizeof(g_unk0x100f76a8) / sizeof(g_unk0x100f76a8[0])); + + m_unk0x14 = LegoState::Shuffle((MxU32*) g_unk0x100f76e0, sizeof(g_unk0x100f76e0) / sizeof(g_unk0x100f76e0[0]) - 1); + + m_unk0x20[0] = + LegoState::Shuffle((MxU32*) g_unk0x100f76f8, sizeof(g_unk0x100f76f8) / sizeof(g_unk0x100f76f8[0]) - 1); + + m_unk0x20[1] = + LegoState::Shuffle((MxU32*) g_unk0x100f7710, sizeof(g_unk0x100f7710) / sizeof(g_unk0x100f7710[0]) - 1); + + m_unk0x20[2] = LegoState::Shuffle((MxU32*) g_unk0x100f7720, sizeof(g_unk0x100f7720) / sizeof(g_unk0x100f7720[0])); + + m_unk0x44[0] = LegoState::Shuffle((MxU32*) g_unk0x100f7730, sizeof(g_unk0x100f7730) / sizeof(g_unk0x100f7730[0])); + + m_unk0x44[1] = LegoState::Shuffle((MxU32*) g_unk0x100f7740, sizeof(g_unk0x100f7740) / sizeof(g_unk0x100f7740[0])); + + m_unk0x44[2] = + LegoState::Shuffle((MxU32*) g_unk0x100f7750, sizeof(g_unk0x100f7750) / sizeof(g_unk0x100f7750[0]) - 1); + + m_unk0x68 = LegoState::Shuffle((MxU32*) g_unk0x100f7760, sizeof(g_unk0x100f7760) / sizeof(g_unk0x100f7760[0])); + memset(m_buffer, 0, sizeof(m_buffer)); } diff --git a/LEGO1/lego/legoomni/src/isle/radiostate.cpp b/LEGO1/lego/legoomni/src/isle/radiostate.cpp index 74094c2c..676bd753 100644 --- a/LEGO1/lego/legoomni/src/isle/radiostate.cpp +++ b/LEGO1/lego/legoomni/src/isle/radiostate.cpp @@ -53,32 +53,14 @@ RadioState::RadioState() MxS32 random = rand(); m_unk0x2c = random % 3; - // TODO: Most likely inline function + m_unk0x08[0] = LegoState::Shuffle((MxU32*) g_unk0x100f3218, sizeof(g_unk0x100f3218) / sizeof(g_unk0x100f3218[0])); + m_unk0x08[0].SetUnknown0x08(rand() % (sizeof(g_unk0x100f3218) / sizeof(g_unk0x100f3218[0]))); - m_unk0x08[0].m_unk0x04 = sizeof(g_unk0x100f3218) / sizeof(g_unk0x100f3218[0]); - m_unk0x08[0].m_unk0x00 = g_unk0x100f3218; - m_unk0x08[0].m_unk0x08 = 0; - m_unk0x08[0].m_unk0x06 = 0; + m_unk0x08[1] = LegoState::Shuffle((MxU32*) g_unk0x100f3230, sizeof(g_unk0x100f3230) / sizeof(g_unk0x100f3230[0])); + m_unk0x08[1].SetUnknown0x08(rand() % (sizeof(g_unk0x100f3230) / sizeof(g_unk0x100f3230[0]))); - random = rand(); - - m_unk0x08[1].m_unk0x08 = 0; - m_unk0x08[1].m_unk0x06 = 0; - m_unk0x08[1].m_unk0x04 = sizeof(g_unk0x100f3230) / sizeof(g_unk0x100f3230[0]); - m_unk0x08[1].m_unk0x00 = g_unk0x100f3230; - - m_unk0x08[0].m_unk0x08 = (MxU32) random % (sizeof(g_unk0x100f3218) / sizeof(g_unk0x100f3218[0])); - random = rand(); - - m_unk0x08[2].m_unk0x08 = 0; - m_unk0x08[2].m_unk0x06 = 0; - m_unk0x08[2].m_unk0x04 = sizeof(g_unk0x100f3268) / sizeof(g_unk0x100f3268[0]); - m_unk0x08[2].m_unk0x00 = g_unk0x100f3268; - - m_unk0x08[1].m_unk0x08 = (MxU32) random % (sizeof(g_unk0x100f3230) / sizeof(g_unk0x100f3230[0])); - random = rand(); - - m_unk0x08[2].m_unk0x08 = (MxU32) random % (sizeof(g_unk0x100f3268) / sizeof(g_unk0x100f3268[0])); + m_unk0x08[2] = LegoState::Shuffle((MxU32*) g_unk0x100f3268, sizeof(g_unk0x100f3268) / sizeof(g_unk0x100f3268[0])); + m_unk0x08[2].SetUnknown0x08(rand() % (sizeof(g_unk0x100f3268) / sizeof(g_unk0x100f3268[0]))); m_active = FALSE; } diff --git a/tools/isledecomp/isledecomp/compare/asm/parse.py b/tools/isledecomp/isledecomp/compare/asm/parse.py index ef1ad2c2..f8323165 100644 --- a/tools/isledecomp/isledecomp/compare/asm/parse.py +++ b/tools/isledecomp/isledecomp/compare/asm/parse.py @@ -9,6 +9,7 @@ import re from typing import Callable, List, Optional, Tuple from collections import namedtuple +from isledecomp.bin import InvalidVirtualAddressError from capstone import Cs, CS_ARCH_X86, CS_MODE_32 disassembler = Cs(CS_ARCH_X86, CS_MODE_32) @@ -55,7 +56,11 @@ def is_relocated(self, addr: int) -> bool: def float_replace(self, addr: int, data_size: int) -> Optional[str]: if callable(self.float_lookup): - float_str = self.float_lookup(addr, data_size) + try: + float_str = self.float_lookup(addr, data_size) + except InvalidVirtualAddressError: + # probably caused by reading an invalid instruction + return None if float_str is not None: return f"{float_str} (FLOAT)"