From 78e924e4ee0e34dea8734b8ff6378de5f601ce23 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Fri, 21 Feb 2025 21:26:10 +0100 Subject: [PATCH 01/16] Match `Infocenter::ReadyWorld` (#1389) --------- Co-authored-by: jonschz --- LEGO1/lego/legoomni/include/infocenter.h | 7 ++- LEGO1/lego/legoomni/src/common/legostate.cpp | 1 + LEGO1/lego/legoomni/src/worlds/infocenter.cpp | 52 ++++++++----------- 3 files changed, 29 insertions(+), 31 deletions(-) diff --git a/LEGO1/lego/legoomni/include/infocenter.h b/LEGO1/lego/legoomni/include/infocenter.h index 19d70d7b..03c55254 100644 --- a/LEGO1/lego/legoomni/include/infocenter.h +++ b/LEGO1/lego/legoomni/include/infocenter.h @@ -51,10 +51,15 @@ class InfocenterState : public LegoState { return (InfomainScript::Script) m_leaveDialogue[GameState()->GetCurrentAct()].Next(); } + // FUNCTION: BETA10 0x10031ac0 + InfomainScript::Script GetNextReturnDialogue() + { + return (InfomainScript::Script) m_returnDialogue[GameState()->GetCurrentAct()].Next(); + } + // TODO: These probably don't exist according to BETA Playlist& GetExitDialogueAct1() { return m_exitDialogueAct1; } Playlist& GetExitDialogueAct23() { return m_exitDialogueAct23; } - Playlist& GetReturnDialogue(LegoGameState::Act p_act) { return m_returnDialogue[p_act]; } Playlist& GetBricksterDialogue() { return m_bricksterDialogue; } // SYNTHETIC: LEGO1 0x10071900 diff --git a/LEGO1/lego/legoomni/src/common/legostate.cpp b/LEGO1/lego/legoomni/src/common/legostate.cpp index a8c2cc6b..6d48f5d0 100644 --- a/LEGO1/lego/legoomni/src/common/legostate.cpp +++ b/LEGO1/lego/legoomni/src/common/legostate.cpp @@ -6,6 +6,7 @@ DECOMP_SIZE_ASSERT(LegoState, 0x08) DECOMP_SIZE_ASSERT(LegoState::Playlist, 0x0c) // FUNCTION: LEGO1 0x10014d00 +// FUNCTION: BETA10 0x10022580 MxU32 LegoState::Playlist::Next() { MxU32 objectId; diff --git a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp index 671fbf7c..657536b0 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp @@ -456,7 +456,7 @@ void Infocenter::ReadyWorld() case 3: PlayCutscene(e_legoMovie, TRUE); m_infocenterState->m_unk0x74 = 0; - break; + return; case 4: m_infocenterState->m_unk0x74 = 2; if (!m_infocenterState->HasRegistered()) { @@ -466,13 +466,12 @@ void Infocenter::ReadyWorld() PlayAction(InfomainScript::c_iicx18in_RunAnim); PlayMusic(JukeboxScript::c_InformationCenter_Music); FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); - break; + return; case 5: default: { PlayMusic(JukeboxScript::c_InformationCenter_Music); - InfomainScript::Script script = - (InfomainScript::Script) m_infocenterState->GetReturnDialogue(GameState()->GetCurrentAct()).Next(); + InfomainScript::Script script = m_infocenterState->GetNextReturnDialogue(); PlayAction(script); if (script == InfomainScript::c_iicx26in_RunAnim) { @@ -485,15 +484,13 @@ void Infocenter::ReadyWorld() m_bookAnimationTimer = 1; } - m_infocenterState->m_unk0x74 = 11; - FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); break; } case 8: PlayMusic(JukeboxScript::c_InformationCenter_Music); PlayAction(InfomainScript::c_iic043in_RunAnim); FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); - break; + return; case 0xf: m_infocenterState->m_unk0x74 = 2; if (!m_infocenterState->HasRegistered()) { @@ -503,9 +500,9 @@ void Infocenter::ReadyWorld() PlayAction(InfomainScript::c_iicx17in_RunAnim); PlayMusic(JukeboxScript::c_InformationCenter_Music); FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); - break; + return; } - return; + break; case LegoGameState::e_act2: { if (m_infocenterState->m_unk0x74 == 8) { PlayMusic(JukeboxScript::c_InformationCenter_Music); @@ -537,8 +534,7 @@ void Infocenter::ReadyWorld() m_infocenterState->m_unk0x74 = 5; m_destLocation = LegoGameState::e_act2main; - InfomainScript::Script script = - (InfomainScript::Script) m_infocenterState->GetReturnDialogue(GameState()->GetCurrentAct()).Next(); + InfomainScript::Script script = m_infocenterState->GetNextReturnDialogue(); PlayAction(script); InputManager()->DisableInputProcessing(); @@ -547,8 +543,7 @@ void Infocenter::ReadyWorld() } PlayMusic(JukeboxScript::c_InformationCenter_Music); - InfomainScript::Script script = - (InfomainScript::Script) m_infocenterState->GetReturnDialogue(GameState()->GetCurrentAct()).Next(); + InfomainScript::Script script = m_infocenterState->GetNextReturnDialogue(); PlayAction(script); bgRed->Enable(TRUE); break; @@ -565,20 +560,18 @@ void Infocenter::ReadyWorld() Act3State* state = (Act3State*) GameState()->GetState("Act3State"); GameState()->FindLoadedAct(); - if (state) { - if (state->GetUnknown0x08() == 3) { - bg->Enable(TRUE); - PlayCutscene(e_badEndMovie, TRUE); - m_infocenterState->m_unk0x74 = 0; - return; - } + if (state && state->GetUnknown0x08() == 3) { + bg->Enable(TRUE); + PlayCutscene(e_badEndMovie, TRUE); + m_infocenterState->m_unk0x74 = 0; + return; + } - if (state && state->GetUnknown0x08() == 2) { - bg->Enable(TRUE); - PlayCutscene(e_goodEndMovie, TRUE); - m_infocenterState->m_unk0x74 = 0; - return; - } + if (state && state->GetUnknown0x08() == 2) { + bg->Enable(TRUE); + PlayCutscene(e_goodEndMovie, TRUE); + m_infocenterState->m_unk0x74 = 0; + return; } if (m_infocenterState->m_unk0x74 == 4) { @@ -593,8 +586,7 @@ void Infocenter::ReadyWorld() m_infocenterState->m_unk0x74 = 5; m_destLocation = LegoGameState::e_act3script; - InfomainScript::Script script = - (InfomainScript::Script) m_infocenterState->GetReturnDialogue(GameState()->GetCurrentAct()).Next(); + InfomainScript::Script script = m_infocenterState->GetNextReturnDialogue(); PlayAction(script); InputManager()->DisableInputProcessing(); @@ -603,8 +595,7 @@ void Infocenter::ReadyWorld() } PlayMusic(JukeboxScript::c_InformationCenter_Music); - InfomainScript::Script script = - (InfomainScript::Script) m_infocenterState->GetReturnDialogue(GameState()->GetCurrentAct()).Next(); + InfomainScript::Script script = m_infocenterState->GetNextReturnDialogue(); PlayAction(script); bgRed->Enable(TRUE); break; @@ -1228,6 +1219,7 @@ MxLong Infocenter::HandleNotification0(MxNotificationParam& p_param) } // FUNCTION: LEGO1 0x10070aa0 +// FUNCTION: BETA10 0x10030508 void Infocenter::Enable(MxBool p_enable) { LegoWorld::Enable(p_enable); From 5e5b048b3436d6fc7a2ea9239c5dbdec1199c752 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 21 Feb 2025 15:50:38 -0700 Subject: [PATCH 02/16] Match `Act3::DebugCopter` (#1392) * Match `Act3::DebugCopter` * Rename param --- LEGO1/lego/legoomni/include/act3.h | 2 +- LEGO1/lego/legoomni/src/worlds/act3.cpp | 14 ++++++-------- LEGO1/mxgeometry/mxquaternion.h | 8 ++++++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act3.h b/LEGO1/lego/legoomni/include/act3.h index 8b31ea73..dc81160c 100644 --- a/LEGO1/lego/legoomni/include/act3.h +++ b/LEGO1/lego/legoomni/include/act3.h @@ -155,7 +155,7 @@ class Act3 : public LegoWorld { const Matrix4& p_destination, const Matrix4& p_startPosition, const Matrix4& p_endPosition, - const MxQuaternionTransformer& p_unk0x1f4 + const MxQuaternionTransformer& p_quatTransform ); Act3State* m_state; // 0xf8 diff --git a/LEGO1/lego/legoomni/src/worlds/act3.cpp b/LEGO1/lego/legoomni/src/worlds/act3.cpp index af9619ac..daee3b2d 100644 --- a/LEGO1/lego/legoomni/src/worlds/act3.cpp +++ b/LEGO1/lego/legoomni/src/worlds/act3.cpp @@ -793,7 +793,7 @@ void Act3::DebugCopter( const Matrix4& p_destination, const Matrix4& p_startPosition, const Matrix4& p_endPosition, - const MxQuaternionTransformer& p_unk0x1f4 + const MxQuaternionTransformer& p_quatTransform ) { DebugPrintf("Copter matrix...\n\n"); @@ -823,19 +823,17 @@ void Act3::DebugCopter( DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_endPosition[2])); DebugPrintf("\t%g, %g, %g, %g\n\n", EXPAND4(p_endPosition[3])); - Mx4DPointFloat unk0x00, unk0x18; + Mx4DPointFloat startQuat, endQuat; - if (p_unk0x1f4.GetFlags() != 0) { - // TODO: Match - unk0x00 = p_unk0x1f4.GetStartQuat(); - unk0x18 = p_unk0x1f4.GetEndQuat(); + if (p_quatTransform.GetFlags() != 0) { + p_quatTransform.GetQuat(startQuat, endQuat); DebugPrintf("Source quaternion..."); // STRING: LEGO1 0x100f7864 - DebugPrintf("\t%g, %g, %g, %g\n", EXPAND4(unk0x00)); + DebugPrintf("\t%g, %g, %g, %g\n", EXPAND4(startQuat)); DebugPrintf("Destination quaternion..."); - DebugPrintf("\t%g, %g, %g, %g\n", EXPAND4(unk0x18)); + DebugPrintf("\t%g, %g, %g, %g\n", EXPAND4(endQuat)); } } diff --git a/LEGO1/mxgeometry/mxquaternion.h b/LEGO1/mxgeometry/mxquaternion.h index a5fb006b..44218a6d 100644 --- a/LEGO1/mxgeometry/mxquaternion.h +++ b/LEGO1/mxgeometry/mxquaternion.h @@ -21,8 +21,12 @@ class MxQuaternionTransformer { inline void SetEnd(Vector4& p_v); inline int InterpolateToMatrix(Matrix4& p_matrix, float p_f); - const Vector4& GetStartQuat() const { return m_startQuat; } - const Vector4& GetEndQuat() const { return m_endQuat; } + void GetQuat(Vector4& p_startQuat, Vector4& p_endQuat) const + { + p_startQuat = m_startQuat; + p_endQuat = m_endQuat; + } + undefined4 GetFlags() const { return m_flags; } private: From ea5a72231127b82c6368701992f7a33da6ff6a93 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 22 Feb 2025 06:48:11 -0700 Subject: [PATCH 03/16] Fix Matrix4::operator[] annotation (#1390) --- LEGO1/lego/legoomni/include/legoanimpresenter.h | 6 +++--- LEGO1/lego/legoomni/include/legocarbuildpresenter.h | 2 +- LEGO1/lego/legoomni/include/legopathactor.h | 4 ++-- LEGO1/lego/legoomni/src/paths/legopathactor.cpp | 2 +- LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp | 8 +++++--- LEGO1/lego/sources/misc/legounknown.cpp | 2 +- LEGO1/lego/sources/misc/legounknown.h | 4 ++-- LEGO1/lego/sources/roi/legoroi.cpp | 3 ++- LEGO1/mxgeometry/mxmatrix.h | 1 - LEGO1/realtime/matrix.h | 1 + LEGO1/realtime/matrix4d.inl.h | 2 +- LEGO1/realtime/orientableroi.cpp | 1 + 12 files changed, 20 insertions(+), 16 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index f31423c5..fce22592 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -93,7 +93,7 @@ class LegoAnimPresenter : public MxVideoPresenter { void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; } void SetUnknown0x0cTo1() { m_unk0x9c = 1; } - void SetUnknown0xa0(MxMatrix* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; } + void SetUnknown0xa0(Matrix4* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; } LegoAnim* GetAnimation() { return m_anim; } @@ -123,7 +123,7 @@ class LegoAnimPresenter : public MxVideoPresenter { MxU32 m_roiMapSize; // 0x6c LegoROIList* m_unk0x70; // 0x70 LegoROIList* m_unk0x74; // 0x74 - MxMatrix* m_unk0x78; // 0x78 + Matrix4* m_unk0x78; // 0x78 MxU32 m_flags; // 0x7c LegoWorld* m_currentWorld; // 0x80 MxAtomId m_worldAtom; // 0x84 @@ -136,7 +136,7 @@ class LegoAnimPresenter : public MxVideoPresenter { undefined m_unk0x97; // 0x97 LegoAnimSubstMap* m_substMap; // 0x98 MxS16 m_unk0x9c; // 0x9c - MxMatrix* m_unk0xa0; // 0xa0 + Matrix4* m_unk0xa0; // 0xa0 public: float m_unk0xa4; // 0xa4 diff --git a/LEGO1/lego/legoomni/include/legocarbuildpresenter.h b/LEGO1/lego/legoomni/include/legocarbuildpresenter.h index 821c3a60..f09515bf 100644 --- a/LEGO1/lego/legoomni/include/legocarbuildpresenter.h +++ b/LEGO1/lego/legoomni/include/legocarbuildpresenter.h @@ -90,7 +90,7 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { void SetUnknown0xbc(undefined2 p_unk0xbc) { m_unk0xbc = p_unk0xbc; } // FUNCTION: BETA10 0x100703b0 - MxMatrix& GetUnknown0xe0() { return m_unk0xe0; } + Matrix4& GetUnknown0xe0() { return m_unk0xe0; } MxBool StringEndsOnW(LegoChar* p_param); MxBool StringEndsOnYOrN(const LegoChar* p_string); diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 169cdd22..f4a4117e 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -77,8 +77,8 @@ class LegoPathActor : public LegoActor { float p_srcScale, LegoUnknown100db7f4& p_destEdge, float p_destScale - ); // vtable+0x88 - virtual MxS32 VTable0x8c(float p_time, MxMatrix& p_transform); // vtable+0x8c + ); // vtable+0x88 + virtual MxS32 VTable0x8c(float p_time, Matrix4& p_transform); // vtable+0x8c // FUNCTION: LEGO1 0x10002d40 virtual MxU32 VTable0x90(float, Matrix4&) { return FALSE; } // vtable+0x90 diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index 69a624ee..5daf64c2 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -234,7 +234,7 @@ MxResult LegoPathActor::VTable0x84( // FUNCTION: LEGO1 0x1002e100 // FUNCTION: BETA10 0x100b0520 -MxS32 LegoPathActor::VTable0x8c(float p_time, MxMatrix& p_transform) +MxS32 LegoPathActor::VTable0x8c(float p_time, Matrix4& p_transform) { if (m_userNavFlag && m_actorState == c_initial) { m_lastTime = p_time; diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index 6c698bcf..4c0b13f2 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -704,7 +704,9 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi) return FAILURE; } - MxMatrix* mn = new MxMatrix(); + Matrix4* mn = new MxMatrix(); + assert(mn); + MxMatrix local58; const Matrix4& local2world = p_roi->GetLocal2World(); MxMatrix* local5c; @@ -725,7 +727,7 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi) } { - ((Matrix4*) mn)->Product(local58, local2world); + mn->Product(local58, local2world); SetUnknown0xa0(mn); delete[] local5c; SetUnknown0x0cTo1(); @@ -734,7 +736,7 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi) MxMatrix localf8; localf8.Product(local140, *m_unk0xa0); - ((Matrix4&) *m_unk0x78) = localf8; + *m_unk0x78 = localf8; return SUCCESS; } diff --git a/LEGO1/lego/sources/misc/legounknown.cpp b/LEGO1/lego/sources/misc/legounknown.cpp index db3f056c..afc22e8f 100644 --- a/LEGO1/lego/sources/misc/legounknown.cpp +++ b/LEGO1/lego/sources/misc/legounknown.cpp @@ -37,7 +37,7 @@ void LegoUnknown::FUN_1009a140( // FUNCTION: LEGO1 0x1009a1e0 // FUNCTION: BETA10 0x10182d61 -LegoResult LegoUnknown::FUN_1009a1e0(float p_f1, MxMatrix& p_mat, Vector3& p_v, LegoU32 p_und) +LegoResult LegoUnknown::FUN_1009a1e0(float p_f1, Matrix4& p_mat, Vector3& p_v, LegoU32 p_und) { Vector3 v1(p_mat[3]); Vector3 v2(p_mat[0]); diff --git a/LEGO1/lego/sources/misc/legounknown.h b/LEGO1/lego/sources/misc/legounknown.h index e129952c..c29bbd28 100644 --- a/LEGO1/lego/sources/misc/legounknown.h +++ b/LEGO1/lego/sources/misc/legounknown.h @@ -4,7 +4,7 @@ #include "legotypes.h" #include "mxgeometry/mxgeometry3d.h" -class MxMatrix; +class Matrix4; // SIZE 0x50 class LegoUnknown { @@ -18,7 +18,7 @@ class LegoUnknown { const Vector3& p_point3, const Vector3& p_point4 ); - LegoResult FUN_1009a1e0(float p_f1, MxMatrix& p_mat, Vector3& p_v, LegoU32 p_und); + LegoResult FUN_1009a1e0(float p_f1, Matrix4& p_mat, Vector3& p_v, LegoU32 p_und); private: Mx3DPointFloat m_unk0x00[4]; // 0x00 diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index 2c0bc7de..25d6fb36 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -736,6 +736,7 @@ TimeROI::TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, LegoTime p_t } // FUNCTION: LEGO1 0x100a9b40 +// FUNCTION: BETA10 0x1018bbf0 void TimeROI::FUN_100a9b40(Matrix4& p_matrix, LegoTime p_time) { LegoTime time = p_time - m_time; @@ -747,7 +748,7 @@ void TimeROI::FUN_100a9b40(Matrix4& p_matrix, LegoTime p_time) Vector3 vec(m_local2world[3]); targetPosition -= vec; - targetPosition /= time * 0.001; + targetPosition /= time / 1000.0; FUN_100a5a30(targetPosition); } diff --git a/LEGO1/mxgeometry/mxmatrix.h b/LEGO1/mxgeometry/mxmatrix.h index a31a5d4e..7fc5c605 100644 --- a/LEGO1/mxgeometry/mxmatrix.h +++ b/LEGO1/mxgeometry/mxmatrix.h @@ -22,7 +22,6 @@ class MxMatrix : public Matrix4 { // FUNCTION: BETA10 0x10010860 float* operator[](int idx) { return m_data[idx]; } - // FUNCTION: BETA10 0x1001c670 const float* operator[](int idx) const { return m_data[idx]; } // FUNCTION: LEGO1 0x10002850 diff --git a/LEGO1/realtime/matrix.h b/LEGO1/realtime/matrix.h index eccc4f04..bbadcdf2 100644 --- a/LEGO1/realtime/matrix.h +++ b/LEGO1/realtime/matrix.h @@ -48,6 +48,7 @@ class Matrix4 { inline int BETA_1005a590(Matrix4& p_mat); inline void Swap(int p_d1, int p_d2); + // FUNCTION: BETA10 0x1001c670 float* operator[](int idx) { return m_data[idx]; } // FUNCTION: BETA10 0x10017780 diff --git a/LEGO1/realtime/matrix4d.inl.h b/LEGO1/realtime/matrix4d.inl.h index 2bf22a85..b8bba5a3 100644 --- a/LEGO1/realtime/matrix4d.inl.h +++ b/LEGO1/realtime/matrix4d.inl.h @@ -292,8 +292,8 @@ int Matrix4::BETA_1005a590(Matrix4& p_mat) { float local5c[4][4]; Matrix4 localc(local5c); + localc = *this; - ((Matrix4&) localc) = *this; p_mat.SetIdentity(); for (int i = 0; i < 4; i++) { diff --git a/LEGO1/realtime/orientableroi.cpp b/LEGO1/realtime/orientableroi.cpp index 9946e78e..95261810 100644 --- a/LEGO1/realtime/orientableroi.cpp +++ b/LEGO1/realtime/orientableroi.cpp @@ -68,6 +68,7 @@ void OrientableROI::WrappedVTable0x24(const Matrix4& p_transform) } // FUNCTION: LEGO1 0x100a50a0 +// FUNCTION: BETA10 0x1016601f void OrientableROI::GetLocalTransform(Matrix4& p_transform) { MxMatrix mat; From 67b25b0bcc9c6ffb8dbaaa27202390788d93028f Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 26 Feb 2025 19:30:11 -0700 Subject: [PATCH 04/16] Adapt `MxRegion.h` (#1393) * Adapt MxRegion.h * Use specific GH action version * Disable clang32 for now * Fix regression * Add space * Add BETA annotations --- .github/workflows/build.yml | 2 +- CMakeLists.txt | 1 - .../src/common/mxcontrolpresenter.cpp | 2 +- .../src/control/legocontrolmanager.cpp | 2 +- .../src/video/legolocomotionanimpresenter.cpp | 2 +- .../legoomni/src/video/legopartpresenter.cpp | 2 +- LEGO1/omni/include/mxlist.h | 2 +- LEGO1/omni/include/mxregion.h | 555 +++++++++++++++++- LEGO1/omni/include/mxregioncursor.h | 45 -- LEGO1/omni/include/mxregionlist.h | 427 -------------- LEGO1/omni/include/mxvideomanager.h | 7 +- LEGO1/omni/src/video/mxregion.cpp | 471 ++++++++++++--- LEGO1/omni/src/video/mxregioncursor.cpp | 298 ---------- LEGO1/omni/src/video/mxvideomanager.cpp | 38 +- LEGO1/omni/src/video/mxvideopresenter.cpp | 4 +- 15 files changed, 947 insertions(+), 911 deletions(-) delete mode 100644 LEGO1/omni/include/mxregioncursor.h delete mode 100644 LEGO1/omni/include/mxregionlist.h delete mode 100644 LEGO1/omni/src/video/mxregioncursor.cpp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4a33e2b9..eabeb295 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,7 @@ jobs: toolchain: - { name: 'MSVC', shell: 'sh', setup-cmake: true, setup-ninja: true, setup-msvc: true } - { name: 'msys2 mingw32', shell: 'msys2 {0}', msystem: mingw32, msys-env: mingw-w64-i686, clang-tidy: true, werror: true } - - { name: 'msys2 clang32', shell: 'msys2 {0}', msystem: clang32, msys-env: mingw-w64-clang-i686, clang-tidy: true, werror: true, no-dx5-libs: true } + # - { name: 'msys2 clang32', shell: 'msys2 {0}', msystem: clang32, msys-env: mingw-w64-clang-i686, clang-tidy: true, werror: true, no-dx5-libs: true } steps: - name: Set up MSYS2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 76bdb406..5b337e0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,7 +264,6 @@ function(add_lego_libraries NAME) LEGO1/omni/src/audio/mxloopingmidipresenter.cpp LEGO1/omni/src/event/mxeventpresenter.cpp LEGO1/omni/src/stream/mxstreamchunk.cpp - LEGO1/omni/src/video/mxregioncursor.cpp LEGO1/omni/src/video/mxregion.cpp LEGO1/omni/src/video/mxsmk.cpp LEGO1/omni/src/stream/mxramstreamcontroller.cpp diff --git a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp index 6b24bc80..3449423e 100644 --- a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp @@ -192,7 +192,7 @@ MxBool MxControlPresenter::FUN_10044480(LegoControlManagerNotificationParam* p_p void MxControlPresenter::VTable0x6c(MxS16 p_unk0x4e) { if (p_unk0x4e == -1) { - if ((MxS16) ((MxDSMultiAction*) m_action)->GetActionList()->GetCount() - m_unk0x4e == 1) { + if ((MxS16) ((MxDSMultiAction*) m_action)->GetActionList()->GetNumElements() - m_unk0x4e == 1) { m_unk0x4e = 0; } else { diff --git a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp index 691ddb40..3a47f2da 100644 --- a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp +++ b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp @@ -58,7 +58,7 @@ void LegoControlManager::Unregister(MxCore* p_listener) // FUNCTION: LEGO1 0x10029210 MxBool LegoControlManager::FUN_10029210(LegoEventNotificationParam& p_param, MxPresenter* p_presenter) { - if (m_presenterList != NULL && m_presenterList->GetCount() != 0) { + if (m_presenterList != NULL && m_presenterList->GetNumElements() != 0) { m_unk0x14 = p_presenter; if (p_param.GetNotification() == c_notificationButtonUp || diff --git a/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp index 90b6533e..0272e50d 100644 --- a/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp @@ -114,7 +114,7 @@ void LegoLocomotionAnimPresenter::StartingTickle() m_subscriber->FreeDataChunk(chunk); } - if (m_roiMapList->GetCount() != 0) { + if (m_roiMapList->GetNumElements() != 0) { ProgressTickleState(e_streaming); } } diff --git a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp index 60f33d89..fba9373f 100644 --- a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp @@ -250,7 +250,7 @@ void LegoPartPresenter::Store() ViewLODList* lodList = GetViewLODListManager()->Lookup(part->GetName()->GetData()); if (lodList == NULL) { - lodList = GetViewLODListManager()->Create(part->GetName()->GetData(), part->GetList()->GetCount()); + lodList = GetViewLODListManager()->Create(part->GetName()->GetData(), part->GetList()->GetNumElements()); LegoLODListCursor lodCursor(part->GetList()); LegoLOD* lod; diff --git a/LEGO1/omni/include/mxlist.h b/LEGO1/omni/include/mxlist.h index 6ab165e2..f6954168 100644 --- a/LEGO1/omni/include/mxlist.h +++ b/LEGO1/omni/include/mxlist.h @@ -52,7 +52,7 @@ class MxList : protected MxCollection { void Prepend(T p_obj) { InsertEntry(p_obj, NULL, this->m_first); } void DeleteAll(); void Empty(); - MxU32 GetCount() { return this->m_count; } + MxU32 GetNumElements() { return this->m_count; } friend class MxListCursor; using MxCollection::SetDestroy; diff --git a/LEGO1/omni/include/mxregion.h b/LEGO1/omni/include/mxregion.h index d6f5f720..c5f8e31e 100644 --- a/LEGO1/omni/include/mxregion.h +++ b/LEGO1/omni/include/mxregion.h @@ -1,34 +1,559 @@ -#ifndef MXREGION_H -#define MXREGION_H +#ifndef __MXREGION_H +#define __MXREGION_H #include "decomp.h" #include "mxcore.h" -#include "mxrect32.h" -#include "mxregionlist.h" +#include "mxlist.h" +#include "mxrect32.h" // should be mxgeometry.h + +// SIZE 0x08 +class MxSegment { +protected: + MxS32 m_min; // 0x00 + MxS32 m_max; // 0x04 + +public: + // FUNCTION: BETA10 0x1014c360 + MxSegment(MxS32 p_min, MxS32 p_max) + { + m_min = p_min; + m_max = p_max; + } + + // FUNCTION: BETA10 0x1014b910 + MxS32 GetMin() { return m_min; } + + // FUNCTION: BETA10 0x1014b930 + MxS32 GetMax() { return m_max; } + + MxSegment* Clone() { return new MxSegment(m_min, m_max); } + MxBool Combine(MxSegment& p_seg); + MxBool Adjacent(MxSegment& p_seg) { return m_max == p_seg.m_min || m_min == p_seg.m_max; } + MxBool IntersectsH(MxRect32& p_rect) { return p_rect.GetRight() > m_min && p_rect.GetTop() < m_max; } + MxBool operator==(MxSegment& p_seg) { return m_min == p_seg.m_min && m_max == p_seg.m_max; } + MxBool operator!=(MxSegment& p_seg) { return !operator==(p_seg); } +}; + +// VTABLE: LEGO1 0x100dcc40 +// VTABLE: BETA10 0x101c2628 +// class MxCollection + +// VTABLE: LEGO1 0x100dcc58 +// VTABLE: BETA10 0x101c2610 +// class MxList + +// VTABLE: LEGO1 0x100dcc70 +// VTABLE: BETA10 0x101c25f8 +// class MxPtrList + +// VTABLE: LEGO1 0x100dcc88 +// VTABLE: BETA10 0x101c25e0 +// SIZE 0x18 +class MxSegmentList : public MxPtrList { +public: + // FUNCTION: BETA10 0x1014bdd0 + MxSegmentList() : MxPtrList(TRUE) {} + + // SYNTHETIC: LEGO1 0x100c4e90 + // SYNTHETIC: BETA10 0x1014c1a0 + // MxSegmentList::`scalar deleting destructor' +}; + +// VTABLE: LEGO1 0x100dcbf8 +// VTABLE: BETA10 0x101c25b0 +// class MxPtrListCursor + +// VTABLE: LEGO1 0x100dcc28 +// VTABLE: BETA10 0x101c25c8 +// class MxListCursor + +// VTABLE: LEGO1 0x100dcc10 +// VTABLE: BETA10 0x101c2598 +class MxSegmentListCursor : public MxPtrListCursor { +public: + // FUNCTION: BETA10 0x1014ba10 + MxSegmentListCursor(MxSegmentList* p_list) : MxPtrListCursor(p_list) {} +}; + +// SIZE 0x0c +class MxSpan { +protected: + MxS32 m_min; // 0x00 + MxS32 m_max; // 0x04 + MxSegmentList* m_segList; // 0x08 + +public: + MxSpan(MxS32 p_min, MxS32 p_max); + MxSpan(MxRect32& p_rect); + + // FUNCTION: BETA10 0x1014b0f0 + ~MxSpan() { delete m_segList; } + + // FUNCTION: BETA10 0x1014b3b0 + MxS32 GetMin() { return m_min; } + + void SetMin(MxS32 p_min) { m_min = p_min; } + + // FUNCTION: BETA10 0x1014b3f0 + MxS32 GetMax() { return m_max; } + + void SetMax(MxS32 p_max) { m_max = p_max; } + MxSpan* Clone(); + void Compact(); + MxBool Combine(MxSpan& p_span); + MxBool Adjacent(MxSpan& p_span) { return m_max == p_span.m_min || m_min == p_span.m_max; } + MxBool HasSameSegments(MxSpan& p_span); + MxBool IntersectsV(MxRect32& p_rect) { return p_rect.GetBottom() > m_min && p_rect.GetTop() < m_max; } + MxBool IntersectsH(MxRect32& p_rect); + void AddSegment(MxS32 p_min, MxS32 p_max); + MxBool operator==(MxSpan& p_span) + { + return m_min == p_span.m_min && m_max == p_span.m_max && HasSameSegments(p_span); + } + MxBool operator!=(MxSpan& p_span) { return !operator==(p_span); } + friend class MxRegionCursor; + + // SYNTHETIC: BETA10 0x1014b0b0 + // MxSpan::`scalar deleting destructor' +}; + +// VTABLE: LEGO1 0x100dcb10 +// VTABLE: BETA10 0x101c24f8 +// class MxCollection + +// VTABLE: LEGO1 0x100dcb28 +// VTABLE: BETA10 0x101c24e0 +// class MxList + +// VTABLE: LEGO1 0x100dcb40 +// VTABLE: BETA10 0x101c24c8 +// class MxPtrList + +// VTABLE: LEGO1 0x100dcb58 +// VTABLE: BETA10 0x101c24b0 +// SIZE 0x18 +class MxSpanList : public MxPtrList { +public: + // FUNCTION: BETA10 0x1014abb0 + MxSpanList() : MxPtrList(TRUE) {} + + // SYNTHETIC: LEGO1 0x100c3410 + // SYNTHETIC: BETA10 0x1014af90 + // MxSpanList::`scalar deleting destructor' +}; + +// VTABLE: LEGO1 0x100dcb70 +// VTABLE: BETA10 0x101c2528 +// class MxPtrListCursor + +// VTABLE: LEGO1 0x100dcba0 +// VTABLE: BETA10 0x101c2540 +// class MxListCursor + +// TODO: The initialize list param type should be MxSpanList, but doing that +// drastically reduced the match percentage for MxRegion::AddRect. +// (developer provided MxRegion.h file also uses MxSpanList*.) +// It also works with MxPtrList, so we'll do that until we figure this out. + +// VTABLE: LEGO1 0x100dcb88 +// VTABLE: BETA10 0x101c2510 +class MxSpanListCursor : public MxPtrListCursor { +public: + // FUNCTION: BETA10 0x1014b470 + MxSpanListCursor(MxPtrList* p_list) : MxPtrListCursor(p_list) {} +}; // VTABLE: LEGO1 0x100dcae8 // SIZE 0x1c class MxRegion : public MxCore { +protected: + MxSpanList* m_spanList; // 0x08 + MxRect32 m_boundingRect; // 0x0c + public: MxRegion(); ~MxRegion() override; - + MxRect32& GetBoundingRect() { return m_boundingRect; } virtual void Reset(); // vtable+0x14 - virtual void VTable0x18(MxRect32& p_rect); // vtable+0x18 - virtual MxBool VTable0x1c(MxRect32& p_rect); // vtable+0x1c - virtual MxBool VTable0x20(); // vtable+0x20 + virtual void AddRect(MxRect32& p_rect); // vtable+0x18 + virtual MxBool Intersects(MxRect32& p_rect); // vtable+0x1c - MxRegionTopBottomList* GetTopBottomList() const { return m_list; } - const MxRect32& GetRect() const { return m_rect; } + // FUNCTION: LEGO1 0x100c3660 + // FUNCTION: BETA10 0x1014b1d0 + virtual MxBool IsEmpty() { return m_spanList->GetNumElements() == 0; } // vtable+0x20 + void Compact(); friend class MxRegionCursor; // SYNTHETIC: LEGO1 0x100c3670 + // SYNTHETIC: BETA10 0x1014b230 // MxRegion::`scalar deleting destructor' - -private: - MxRegionTopBottomList* m_list; // 0x08 - MxRect32 m_rect; // 0x0c }; -#endif // MXREGION_H +// VTABLE: LEGO1 0x100dcbb8 +// SIZE 0x18 +class MxRegionCursor : public MxCore { +protected: + MxRegion* m_region; // 0x08 + MxRect32* m_rect; // 0x0c + MxSpanListCursor* m_spanListCursor; // 0x10 + MxSegmentListCursor* m_segListCursor; // 0x14 + void CreateSegmentListCursor(MxSegmentList* p_segList); + void SetRect(MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom); + void NextSpan(MxRect32& p_rect); + void PrevSpan(MxRect32& p_rect); + +public: + MxRegionCursor(MxRegion* p_region); + ~MxRegionCursor() override; + virtual MxRect32* Head(); // vtable+0x18 + virtual MxRect32* Tail(); // vtable+0x20 + virtual MxRect32* Next(); // vtable+0x28 + virtual MxRect32* Prev(); // vtable+0x30 + virtual MxRect32* Head(MxRect32& p_rect); // vtable+0x14 + virtual MxRect32* Tail(MxRect32& p_rect); // vtable+0x1c + virtual MxRect32* Next(MxRect32& p_rect); // vtable+0x24 + virtual MxRect32* Prev(MxRect32& p_rect); // vtable+0x2c + + // FUNCTION: LEGO1 0x100c4070 + virtual MxRect32* GetRect() { return m_rect; } // vtable+0x34 + + // FUNCTION: LEGO1 0x100c4080 + virtual MxBool Valid() { return m_rect != NULL; } // vtable+0x38 + + virtual void Reset(); // vtable+0x3c + + // SYNTHETIC: LEGO1 0x100c4090 + // MxRegionCursor::`scalar deleting destructor' +}; + +#ifdef REGION_SANITY_CHECK + +class MxRectIntersection { +protected: + MxRect32 m_rect; + MxS32 m_numRects; + +public: + MxRect32& GetRect() { return m_rect; } + void SetRect(MxRect32& p_rect) { m_rect = p_rect; } + MxS32 GetNumRects() { return m_numRects; } + void SetNumRects(MxS32 p_numRects) { m_numRects = p_numRects; } +}; + +class MxRectIntersectionList : public MxPtrList { +public: + MxRectIntersectionList() : MxPtrList(TRUE) {} +}; + +class MxRectIntersectionListCursor : public MxPtrListCursor { +public: + MxRectIntersectionListCursor(MxRectIntersectionList* p_list) : MxPtrListCursor(p_list) {} +}; + +class MxRegionSanityCheck { +protected: + MxRectIntersectionList* m_rectIntersectionList; + +public: + MxRegionSanityCheck(); + ~MxRegionSanityCheck(); + void Reset() { m_rectIntersectionList->Delete(); } + void AddRect(MxRect32& p_rect); + MxS32 CalculateArea(); +}; + +#endif + +// TEMPLATE: LEGO1 0x100c32e0 +// TEMPLATE: BETA10 0x1014ac30 +// MxCollection::Compare + +// TEMPLATE: LEGO1 0x100c32f0 +// TEMPLATE: BETA10 0x1014adf0 +// MxCollection::~MxCollection + +// TEMPLATE: LEGO1 0x100c3340 +// TEMPLATE: BETA10 0x1014ae90 +// MxCollection::Destroy + +// TEMPLATE: LEGO1 0x100c3350 +// TEMPLATE: BETA10 0x1014aea0 +// MxList::~MxList + +// TEMPLATE: LEGO1 0x100c33e0 +// TEMPLATE: BETA10 0x1014af50 +// MxPtrList::Destroy + +// TEMPLATE: LEGO1 0x100c3480 +// TEMPLATE: BETA10 0x1014afd0 +// MxPtrList::~MxPtrList + +// SYNTHETIC: LEGO1 0x100c34d0 +// SYNTHETIC: BETA10 0x1014b030 +// MxCollection::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x100c3540 +// SYNTHETIC: BETA10 0x1014b070 +// MxList::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x100c35f0 +// SYNTHETIC: BETA10 0x1014b130 +// MxPtrList::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x100c3be0 +// SYNTHETIC: BETA10 0x1014b600 +// MxSpanListCursor::`scalar deleting destructor' + +// TEMPLATE: LEGO1 0x100c3c50 +// TEMPLATE: BETA10 0x1014b640 +// MxPtrListCursor::~MxPtrListCursor + +// SYNTHETIC: LEGO1 0x100c3ca0 +// SYNTHETIC: BETA10 0x1014b6a0 +// MxListCursor::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x100c3d10 +// SYNTHETIC: BETA10 0x1014b6e0 +// MxPtrListCursor::`scalar deleting destructor' + +// TEMPLATE: LEGO1 0x100c3d80 +// TEMPLATE: BETA10 0x1014b720 +// MxListCursor::~MxListCursor + +// FUNCTION: LEGO1 0x100c3dd0 +// FUNCTION: BETA10 0x1014b780 +// MxSpanListCursor::~MxSpanListCursor + +// SYNTHETIC: LEGO1 0x100c4790 +// SYNTHETIC: BETA10 0x1014bba0 +// MxSegmentListCursor::`scalar deleting destructor' + +// TEMPLATE: LEGO1 0x100c4800 +// TEMPLATE: BETA10 0x1014bbe0 +// MxPtrListCursor::~MxPtrListCursor + +// SYNTHETIC: LEGO1 0x100c4850 +// SYNTHETIC: BETA10 0x1014bc40 +// MxListCursor::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x100c48c0 +// SYNTHETIC: BETA10 0x1014bc80 +// MxPtrListCursor::`scalar deleting destructor' + +// TEMPLATE: LEGO1 0x100c4930 +// TEMPLATE: BETA10 0x1014bcc0 +// MxListCursor::~MxListCursor + +// TEMPLATE: LEGO1 0x100c4d80 +// TEMPLATE: BETA10 0x1014be50 +// MxCollection::Compare + +// TEMPLATE: LEGO1 0x100c4d90 +// TEMPLATE: BETA10 0x1014c010 +// MxCollection::~MxCollection + +// TEMPLATE: LEGO1 0x100c4de0 +// TEMPLATE: BETA10 0x1014c0b0 +// MxCollection::Destroy + +// TEMPLATE: LEGO1 0x100c4df0 +// TEMPLATE: BETA10 0x1014c0c0 +// MxList::~MxList + +// TEMPLATE: LEGO1 0x100c4f00 +// TEMPLATE: BETA10 0x1014c1e0 +// MxPtrList::~MxPtrList + +// SYNTHETIC: LEGO1 0x100c4f50 +// SYNTHETIC: BETA10 0x1014c240 +// MxCollection::`scalar deleting destructor' + +// TEMPLATE: LEGO1 0x100c4e80 +// TEMPLATE: BETA10 0x1014c170 +// MxPtrList::Destroy + +// SYNTHETIC: LEGO1 0x100c4fc0 +// SYNTHETIC: BETA10 0x1014c280 +// MxList::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x100c5070 +// SYNTHETIC: BETA10 0x1014c2c0 +// MxPtrList::`scalar deleting destructor' + +// TEMPLATE: LEGO1 0x100c54f0 +// MxListCursor::MxListCursor + +// FUNCTION: LEGO1 0x100c5560 +// MxSegmentListCursor::~MxSegmentListCursor + +// TEMPLATE: LEGO1 0x100c55b0 +// MxListCursor::operator= + +// TEMPLATE: LEGO1 0x100c58c0 +// TEMPLATE: BETA10 0x1014c650 +// MxList::InsertEntry + +// TEMPLATE: LEGO1 0x100c5970 +// TEMPLATE: BETA10 0x1014cb20 +// MxList::InsertEntry + +// TEMPLATE: LEGO1 0x100c5a20 +// TEMPLATE: BETA10 0x1014d050 +// MxListEntry::MxListEntry + +// TEMPLATE: LEGO1 0x100c5a40 +// TEMPLATE: BETA10 0x1014d150 +// MxList::DeleteEntry + +// TEMPLATE: BETA10 0x1014ac50 +// MxPtrList::MxPtrList + +// TEMPLATE: BETA10 0x1014acd0 +// MxList::MxList + +// TEMPLATE: BETA10 0x1014ad60 +// MxCollection::MxCollection + +// TEMPLATE: BETA10 0x1014ae60 +// MxCollection::SetDestroy + +// TEMPLATE: BETA10 0x1014af10 +// MxPtrList::SetOwnership + +// FUNCTION: BETA10 0x1014b170 +// MxSpanList::~MxSpanList + +// TEMPLATE: BETA10 0x1014b440 +// MxList::Append + +// TEMPLATE: BETA10 0x1014b4f0 +// MxPtrListCursor::MxPtrListCursor + +// TEMPLATE: BETA10 0x1014b570 +// MxListCursor::MxListCursor + +// TEMPLATE: BETA10 0x1014ba90 +// MxPtrListCursor::MxPtrListCursor + +// TEMPLATE: BETA10 0x1014bb10 +// MxListCursor::MxListCursor + +// FUNCTION: BETA10 0x1014bd20 +// MxSegmentListCursor::~MxSegmentListCursor + +// TEMPLATE: BETA10 0x1014be70 +// MxPtrList::MxPtrList + +// TEMPLATE: BETA10 0x1014bef0 +// MxList::MxList + +// TEMPLATE: BETA10 0x1014bf80 +// MxCollection::MxCollection + +// TEMPLATE: BETA10 0x1014c080 +// MxCollection::SetDestroy + +// TEMPLATE: BETA10 0x1014c130 +// MxPtrList::SetOwnership + +// FUNCTION: BETA10 0x1014c300 +// MxSegmentList::~MxSegmentList + +// TEMPLATE: BETA10 0x1014c390 +// MxList::Append + +// SYNTHETIC: BETA10 0x1014c3c0 +// MxSegmentListCursor::operator= + +// SYNTHETIC: BETA10 0x1014c3f0 +// MxPtrListCursor::operator= + +// SYNTHETIC: BETA10 0x1014c420 +// MxListCursor::operator= + +// TEMPLATE: BETA10 0x1014c740 +// MxList::DeleteAll + +// TEMPLATE: BETA10 0x1014c7d0 +// MxListCursor::First + +// TEMPLATE: BETA10 0x1014c830 +// MxListCursor::Last + +// TEMPLATE: BETA10 0x1014c890 +// MxListCursor::Next + +// TEMPLATE: BETA10 0x1014c970 +// MxListCursor::Prev + +// TEMPLATE: BETA10 0x1014c9f0 +// MxListCursor::Current + +// TEMPLATE: BETA10 0x1014ca40 +// MxListCursor::Prepend + +// TEMPLATE: BETA10 0x1014ca90 +// MxListCursor::Destroy + +// TEMPLATE: BETA10 0x1014caf0 +// MxListCursor::HasMatch + +// TEMPLATE: BETA10 0x1014cc10 +// MxList::DeleteAll + +// TEMPLATE: BETA10 0x1014cd20 +// MxListCursor::Next + +// TEMPLATE: BETA10 0x1014cda0 +// MxListCursor::Prev + +// TEMPLATE: BETA10 0x1014ce70 +// MxListCursor::Prepend + +// TEMPLATE: BETA10 0x1014cec0 +// MxListCursor::Destroy + +// TEMPLATE: BETA10 0x1014cf50 +// MxListEntry::MxListEntry + +// TEMPLATE: BETA10 0x1014cf90 +// MxListEntry::GetPrev + +// TEMPLATE: BETA10 0x1014cfb0 +// MxListEntry::SetPrev + +// TEMPLATE: BETA10 0x1014cfe0 +// MxListEntry::GetNext + +// TEMPLATE: BETA10 0x1014d000 +// MxListEntry::SetNext + +// TEMPLATE: BETA10 0x1014d030 +// MxListEntry::GetValue + +// TEMPLATE: BETA10 0x1014d090 +// MxListEntry::GetPrev + +// TEMPLATE: BETA10 0x1014d0b0 +// MxListEntry::SetPrev + +// TEMPLATE: BETA10 0x1014d0e0 +// MxListEntry::GetNext + +// TEMPLATE: BETA10 0x1014d100 +// MxListEntry::SetNext + +// TEMPLATE: BETA10 0x1014d130 +// MxListEntry::GetValue + +// TEMPLATE: BETA10 0x1014d200 +// MxList::DeleteEntry + +// TEMPLATE: BETA10 0x1014b210 +// MxList::GetNumElements + +// TEMPLATE: BETA10 0x1014c910 +// ?Next@?$MxListCursor@PAVMxSegment@@@@QAEEXZ + +#endif // __MXREGION_H diff --git a/LEGO1/omni/include/mxregioncursor.h b/LEGO1/omni/include/mxregioncursor.h deleted file mode 100644 index 692ccce9..00000000 --- a/LEGO1/omni/include/mxregioncursor.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef MXREGIONCURSOR_H -#define MXREGIONCURSOR_H - -#include "mxregion.h" - -// VTABLE: LEGO1 0x100dcbb8 -// SIZE 0x18 -class MxRegionCursor : public MxCore { -public: - MxRegionCursor(MxRegion* p_region); - ~MxRegionCursor() override; - - virtual MxRect32* VTable0x14(MxRect32& p_rect); // vtable+0x14 - virtual MxRect32* VTable0x18(); // vtable+0x18 - virtual MxRect32* VTable0x1c(MxRect32& p_rect); // vtable+0x1c - virtual MxRect32* VTable0x20(); // vtable+0x20 - virtual MxRect32* VTable0x24(MxRect32& p_rect); // vtable+0x24 - virtual MxRect32* VTable0x28(); // vtable+0x28 - virtual MxRect32* VTable0x2c(MxRect32& p_rect); // vtable+0x2c - virtual MxRect32* VTable0x30(); // vtable+0x30 - - // FUNCTION: LEGO1 0x100c4070 - virtual MxRect32* GetRect() { return m_rect; } // vtable+0x34 - - // FUNCTION: LEGO1 0x100c4080 - virtual MxBool HasRect() { return m_rect != NULL; } // vtable+0x38 - - virtual void Reset(); // vtable+0x3c - -private: - void ResetAndInitializeCursor(MxRegionLeftRightList& p_leftRightList); - void UpdateRect(MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom); - void ProcessRectOverlapAscending(MxRect32& p_rect); - void ProcessOverlapWithRect(MxRect32& p_rect); - - MxRegion* m_region; // 0x08 - MxRect32* m_rect; // 0x0c - MxRegionTopBottomListCursor* m_topBottomCursor; // 0x10 - MxRegionLeftRightListCursor* m_leftRightCursor; // 0x14 -}; - -// SYNTHETIC: LEGO1 0x100c4090 -// MxRegionCursor::`scalar deleting destructor' - -#endif // MXREGIONCURSOR_H diff --git a/LEGO1/omni/include/mxregionlist.h b/LEGO1/omni/include/mxregionlist.h deleted file mode 100644 index 3fc220ff..00000000 --- a/LEGO1/omni/include/mxregionlist.h +++ /dev/null @@ -1,427 +0,0 @@ -#ifndef MXREGIONLIST_H -#define MXREGIONLIST_H - -#include "mxlist.h" - -// SIZE 0x08 -struct MxRegionLeftRight { - MxRegionLeftRight(MxS32 p_left, MxS32 p_right) - { - m_left = p_left; - m_right = p_right; - } - - MxRegionLeftRight* Clone() { return new MxRegionLeftRight(m_left, m_right); } - - MxS32 GetLeft() { return m_left; } - MxS32 GetRight() { return m_right; } - - void SetLeft(MxS32 p_left) { m_left = p_left; } - void SetRight(MxS32 p_right) { m_right = p_right; } - - MxBool IntersectsWith(MxRect32& p_rect) { return m_left < p_rect.GetRight() && p_rect.GetTop() < m_right; } - -private: - MxS32 m_left; // 0x00 - MxS32 m_right; // 0x04 -}; - -// VTABLE: LEGO1 0x100dcc40 -// VTABLE: BETA10 0x101c2628 -// class MxCollection - -// VTABLE: LEGO1 0x100dcc58 -// VTABLE: BETA10 0x101c2610 -// class MxList - -// VTABLE: LEGO1 0x100dcc70 -// VTABLE: BETA10 0x101c25f8 -// class MxPtrList - -// VTABLE: LEGO1 0x100dcc88 -// VTABLE: BETA10 0x101c25e0 -// SIZE 0x18 -class MxRegionLeftRightList : public MxPtrList { -public: - // FUNCTION: BETA10 0x1014bdd0 - MxRegionLeftRightList() : MxPtrList(TRUE) {} - - // SYNTHETIC: LEGO1 0x100c4e90 - // SYNTHETIC: BETA10 0x1014c1a0 - // MxRegionLeftRightList::`scalar deleting destructor' -}; - -// VTABLE: LEGO1 0x100dcbf8 -// VTABLE: BETA10 0x101c25b0 -// class MxPtrListCursor - -// VTABLE: LEGO1 0x100dcc28 -// VTABLE: BETA10 0x101c25c8 -// class MxListCursor - -// VTABLE: LEGO1 0x100dcc10 -// VTABLE: BETA10 0x101c2598 -class MxRegionLeftRightListCursor : public MxPtrListCursor { -public: - // FUNCTION: BETA10 0x1014ba10 - MxRegionLeftRightListCursor(MxRegionLeftRightList* p_list) : MxPtrListCursor(p_list) {} -}; - -// SIZE 0x0c -struct MxRegionTopBottom { - MxRegionTopBottom(MxRect32& p_rect); - MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom); - ~MxRegionTopBottom() { delete m_leftRightList; } - - MxRegionTopBottom* Clone(); - void MergeOrExpandRegions(MxS32 p_left, MxS32 p_right); - MxBool CheckHorizontalOverlap(MxRect32& p_rect); - - MxS32 GetTop() { return m_top; } - MxS32 GetBottom() { return m_bottom; } - - void SetTop(MxS32 p_top) { m_top = p_top; } - void SetBottom(MxS32 p_bottom) { m_bottom = p_bottom; } - - MxBool IntersectsWith(MxRect32& p_rect) { return m_top < p_rect.GetBottom() && p_rect.GetTop() < m_bottom; } - - friend class MxRegionTopBottomList; - friend class MxRegionCursor; - -private: - MxS32 m_top; // 0x00 - MxS32 m_bottom; // 0x04 - MxRegionLeftRightList* m_leftRightList; // 0x08 -}; - -// VTABLE: LEGO1 0x100dcb10 -// VTABLE: BETA10 0x101c24f8 -// class MxCollection - -// VTABLE: LEGO1 0x100dcb28 -// VTABLE: BETA10 0x101c24e0 -// class MxList - -// VTABLE: LEGO1 0x100dcb40 -// VTABLE: BETA10 0x101c24c8 -// class MxPtrList - -// VTABLE: LEGO1 0x100dcb58 -// VTABLE: BETA10 0x101c24b0 -// SIZE 0x18 -class MxRegionTopBottomList : public MxPtrList { -public: - // FUNCTION: BETA10 0x1014abb0 - MxRegionTopBottomList() : MxPtrList(TRUE) {} - - // SYNTHETIC: LEGO1 0x100c3410 - // SYNTHETIC: BETA10 0x1014af90 - // MxRegionTopBottomList::`scalar deleting destructor' -}; - -// VTABLE: LEGO1 0x100dcb70 -// VTABLE: BETA10 0x101c2528 -// class MxPtrListCursor - -// VTABLE: LEGO1 0x100dcba0 -// VTABLE: BETA10 0x101c2540 -// class MxListCursor - -// TODO: The initialize list param type should be MxRegionTopBottomList, but doing that -// drastically reduced the match percentage for MxRegion::VTable0x18. -// It also works with MxPtrList, so we'll do that until we figure this out. - -// VTABLE: LEGO1 0x100dcb88 -// VTABLE: BETA10 0x101c2510 -class MxRegionTopBottomListCursor : public MxPtrListCursor { -public: - // FUNCTION: BETA10 0x1014b470 - MxRegionTopBottomListCursor(MxPtrList* p_list) : MxPtrListCursor(p_list) {} -}; - -// TEMPLATE: LEGO1 0x100c32e0 -// TEMPLATE: BETA10 0x1014ac30 -// MxCollection::Compare - -// TEMPLATE: LEGO1 0x100c32f0 -// TEMPLATE: BETA10 0x1014adf0 -// MxCollection::~MxCollection - -// TEMPLATE: LEGO1 0x100c3340 -// TEMPLATE: BETA10 0x1014ae90 -// MxCollection::Destroy - -// TEMPLATE: LEGO1 0x100c3350 -// TEMPLATE: BETA10 0x1014aea0 -// MxList::~MxList - -// TEMPLATE: LEGO1 0x100c33e0 -// TEMPLATE: BETA10 0x1014af50 -// MxPtrList::Destroy - -// TEMPLATE: LEGO1 0x100c3480 -// TEMPLATE: BETA10 0x1014afd0 -// MxPtrList::~MxPtrList - -// SYNTHETIC: LEGO1 0x100c34d0 -// SYNTHETIC: BETA10 0x1014b030 -// MxCollection::`scalar deleting destructor' - -// SYNTHETIC: LEGO1 0x100c3540 -// SYNTHETIC: BETA10 0x1014b070 -// MxList::`scalar deleting destructor' - -// SYNTHETIC: LEGO1 0x100c35f0 -// SYNTHETIC: BETA10 0x1014b130 -// MxPtrList::`scalar deleting destructor' - -// SYNTHETIC: LEGO1 0x100c3be0 -// SYNTHETIC: BETA10 0x1014b600 -// MxRegionTopBottomListCursor::`scalar deleting destructor' - -// TEMPLATE: LEGO1 0x100c3c50 -// TEMPLATE: BETA10 0x1014b640 -// MxPtrListCursor::~MxPtrListCursor - -// SYNTHETIC: LEGO1 0x100c3ca0 -// SYNTHETIC: BETA10 0x1014b6a0 -// MxListCursor::`scalar deleting destructor' - -// SYNTHETIC: LEGO1 0x100c3d10 -// SYNTHETIC: BETA10 0x1014b6e0 -// MxPtrListCursor::`scalar deleting destructor' - -// TEMPLATE: LEGO1 0x100c3d80 -// TEMPLATE: BETA10 0x1014b720 -// MxListCursor::~MxListCursor - -// FUNCTION: LEGO1 0x100c3dd0 -// FUNCTION: BETA10 0x1014b780 -// MxRegionTopBottomListCursor::~MxRegionTopBottomListCursor - -// SYNTHETIC: LEGO1 0x100c4790 -// SYNTHETIC: BETA10 0x1014bba0 -// MxRegionLeftRightListCursor::`scalar deleting destructor' - -// TEMPLATE: LEGO1 0x100c4800 -// TEMPLATE: BETA10 0x1014bbe0 -// MxPtrListCursor::~MxPtrListCursor - -// SYNTHETIC: LEGO1 0x100c4850 -// SYNTHETIC: BETA10 0x1014bc40 -// MxListCursor::`scalar deleting destructor' - -// SYNTHETIC: LEGO1 0x100c48c0 -// SYNTHETIC: BETA10 0x1014bc80 -// MxPtrListCursor::`scalar deleting destructor' - -// TEMPLATE: LEGO1 0x100c4930 -// TEMPLATE: BETA10 0x1014bcc0 -// MxListCursor::~MxListCursor - -// TEMPLATE: LEGO1 0x100c4d80 -// TEMPLATE: BETA10 0x1014be50 -// MxCollection::Compare - -// TEMPLATE: LEGO1 0x100c4d90 -// TEMPLATE: BETA10 0x1014c010 -// MxCollection::~MxCollection - -// TEMPLATE: LEGO1 0x100c4de0 -// TEMPLATE: BETA10 0x1014c0b0 -// MxCollection::Destroy - -// TEMPLATE: LEGO1 0x100c4df0 -// TEMPLATE: BETA10 0x1014c0c0 -// MxList::~MxList - -// TEMPLATE: LEGO1 0x100c4f00 -// TEMPLATE: BETA10 0x1014c1e0 -// MxPtrList::~MxPtrList - -// SYNTHETIC: LEGO1 0x100c4f50 -// SYNTHETIC: BETA10 0x1014c240 -// MxCollection::`scalar deleting destructor' - -// TEMPLATE: LEGO1 0x100c4e80 -// TEMPLATE: BETA10 0x1014c170 -// MxPtrList::Destroy - -// SYNTHETIC: LEGO1 0x100c4fc0 -// SYNTHETIC: BETA10 0x1014c280 -// MxList::`scalar deleting destructor' - -// SYNTHETIC: LEGO1 0x100c5070 -// SYNTHETIC: BETA10 0x1014c2c0 -// MxPtrList::`scalar deleting destructor' - -// TEMPLATE: LEGO1 0x100c54f0 -// MxListCursor::MxListCursor - -// FUNCTION: LEGO1 0x100c5560 -// MxRegionLeftRightListCursor::~MxRegionLeftRightListCursor - -// TEMPLATE: LEGO1 0x100c55b0 -// MxListCursor::operator= - -// TEMPLATE: LEGO1 0x100c58c0 -// TEMPLATE: BETA10 0x1014c650 -// MxList::InsertEntry - -// TEMPLATE: LEGO1 0x100c5970 -// TEMPLATE: BETA10 0x1014cb20 -// MxList::InsertEntry - -// TEMPLATE: LEGO1 0x100c5a20 -// TEMPLATE: BETA10 0x1014d050 -// MxListEntry::MxListEntry - -// TEMPLATE: LEGO1 0x100c5a40 -// TEMPLATE: BETA10 0x1014d150 -// MxList::DeleteEntry - -// TEMPLATE: BETA10 0x1014ac50 -// MxPtrList::MxPtrList - -// TEMPLATE: BETA10 0x1014acd0 -// MxList::MxList - -// TEMPLATE: BETA10 0x1014ad60 -// MxCollection::MxCollection - -// TEMPLATE: BETA10 0x1014ae60 -// MxCollection::SetDestroy - -// TEMPLATE: BETA10 0x1014af10 -// MxPtrList::SetOwnership - -// FUNCTION: BETA10 0x1014b170 -// MxRegionTopBottomList::~MxRegionTopBottomList - -// TEMPLATE: BETA10 0x1014b440 -// MxList::Append - -// TEMPLATE: BETA10 0x1014b4f0 -// MxPtrListCursor::MxPtrListCursor - -// TEMPLATE: BETA10 0x1014b570 -// MxListCursor::MxListCursor - -// TEMPLATE: BETA10 0x1014ba90 -// MxPtrListCursor::MxPtrListCursor - -// TEMPLATE: BETA10 0x1014bb10 -// MxListCursor::MxListCursor - -// FUNCTION: BETA10 0x1014bd20 -// MxRegionLeftRightListCursor::~MxRegionLeftRightListCursor - -// TEMPLATE: BETA10 0x1014be70 -// MxPtrList::MxPtrList - -// TEMPLATE: BETA10 0x1014bef0 -// MxList::MxList - -// TEMPLATE: BETA10 0x1014bf80 -// MxCollection::MxCollection - -// TEMPLATE: BETA10 0x1014c080 -// MxCollection::SetDestroy - -// TEMPLATE: BETA10 0x1014c130 -// MxPtrList::SetOwnership - -// FUNCTION: BETA10 0x1014c300 -// MxRegionLeftRightList::~MxRegionLeftRightList - -// TEMPLATE: BETA10 0x1014c390 -// MxList::Append - -// SYNTHETIC: BETA10 0x1014c3c0 -// MxRegionLeftRightListCursor::operator= - -// SYNTHETIC: BETA10 0x1014c3f0 -// MxPtrListCursor::operator= - -// SYNTHETIC: BETA10 0x1014c420 -// MxListCursor::operator= - -// TEMPLATE: BETA10 0x1014c740 -// MxList::DeleteAll - -// TEMPLATE: BETA10 0x1014c7d0 -// MxListCursor::First - -// TEMPLATE: BETA10 0x1014c830 -// MxListCursor::Last - -// TEMPLATE: BETA10 0x1014c890 -// MxListCursor::Next - -// TEMPLATE: BETA10 0x1014c970 -// MxListCursor::Prev - -// TEMPLATE: BETA10 0x1014c9f0 -// MxListCursor::Current - -// TEMPLATE: BETA10 0x1014ca40 -// MxListCursor::Prepend - -// TEMPLATE: BETA10 0x1014ca90 -// MxListCursor::Destroy - -// TEMPLATE: BETA10 0x1014caf0 -// MxListCursor::HasMatch - -// TEMPLATE: BETA10 0x1014cc10 -// MxList::DeleteAll - -// TEMPLATE: BETA10 0x1014cd20 -// MxListCursor::Next - -// TEMPLATE: BETA10 0x1014cda0 -// MxListCursor::Prev - -// TEMPLATE: BETA10 0x1014ce70 -// MxListCursor::Prepend - -// TEMPLATE: BETA10 0x1014cec0 -// MxListCursor::Destroy - -// TEMPLATE: BETA10 0x1014cf50 -// MxListEntry::MxListEntry - -// TEMPLATE: BETA10 0x1014cf90 -// MxListEntry::GetPrev - -// TEMPLATE: BETA10 0x1014cfb0 -// MxListEntry::SetPrev - -// TEMPLATE: BETA10 0x1014cfe0 -// MxListEntry::GetNext - -// TEMPLATE: BETA10 0x1014d000 -// MxListEntry::SetNext - -// TEMPLATE: BETA10 0x1014d030 -// MxListEntry::GetValue - -// TEMPLATE: BETA10 0x1014d090 -// MxListEntry::GetPrev - -// TEMPLATE: BETA10 0x1014d0b0 -// MxListEntry::SetPrev - -// TEMPLATE: BETA10 0x1014d0e0 -// MxListEntry::GetNext - -// TEMPLATE: BETA10 0x1014d100 -// MxListEntry::SetNext - -// TEMPLATE: BETA10 0x1014d130 -// MxListEntry::GetValue - -// TEMPLATE: BETA10 0x1014d200 -// MxList::DeleteEntry - -#endif // MXREGIONLIST_H diff --git a/LEGO1/omni/include/mxvideomanager.h b/LEGO1/omni/include/mxvideomanager.h index 163f18b0..78411dcb 100644 --- a/LEGO1/omni/include/mxvideomanager.h +++ b/LEGO1/omni/include/mxvideomanager.h @@ -30,13 +30,12 @@ class MxVideoManager : public MxMediaManager { MxBool p_createThread ); // vtable+0x28 virtual MxResult Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, MxBool p_createThread); // vtable+0x2c - - void InvalidateRect(MxRect32&); - virtual MxResult RealizePalette(MxPalette*); // vtable+0x30 - virtual void UpdateView(MxU32 p_x, MxU32 p_y, MxU32 p_width, MxU32 p_height); // vtable+0x34 + virtual MxResult RealizePalette(MxPalette* p_palette); // vtable+0x30 + virtual void UpdateView(MxU32 p_x, MxU32 p_y, MxU32 p_width, MxU32 p_height); // vtable+0x34 MxResult Init(); void Destroy(MxBool p_fromDestructor); + void InvalidateRect(MxRect32& p_rect); void SortPresenterList(); void UpdateRegion(); diff --git a/LEGO1/omni/src/video/mxregion.cpp b/LEGO1/omni/src/video/mxregion.cpp index f294d3a5..e2841f23 100644 --- a/LEGO1/omni/src/video/mxregion.cpp +++ b/LEGO1/omni/src/video/mxregion.cpp @@ -2,108 +2,104 @@ #include -DECOMP_SIZE_ASSERT(MxRegion, 0x1c); -DECOMP_SIZE_ASSERT(MxRegionTopBottom, 0x0c); -DECOMP_SIZE_ASSERT(MxRegionLeftRight, 0x08); +DECOMP_SIZE_ASSERT(MxRegion, 0x1c) +DECOMP_SIZE_ASSERT(MxSpan, 0x0c) +DECOMP_SIZE_ASSERT(MxSegment, 0x08) +DECOMP_SIZE_ASSERT(MxRegionCursor, 0x18) // FUNCTION: LEGO1 0x100c31c0 // FUNCTION: BETA10 0x10148f00 MxRegion::MxRegion() { - m_list = new MxRegionTopBottomList; - m_rect = MxRect32(INT_MAX, INT_MAX, -1, -1); -} - -// FUNCTION: LEGO1 0x100c3660 -MxBool MxRegion::VTable0x20() -{ - return m_list->GetCount() == 0; + m_spanList = new MxSpanList; + m_boundingRect = MxRect32(INT_MAX, INT_MAX, -1, -1); } // FUNCTION: LEGO1 0x100c3690 +// FUNCTION: BETA10 0x10148fe8 MxRegion::~MxRegion() { - if (m_list) { - delete m_list; - } + delete m_spanList; } // FUNCTION: LEGO1 0x100c3700 // FUNCTION: BETA10 0x1014907a void MxRegion::Reset() { - m_list->DeleteAll(); - m_rect = MxRect32(INT_MAX, INT_MAX, -1, -1); + m_spanList->DeleteAll(); + m_boundingRect = MxRect32(INT_MAX, INT_MAX, -1, -1); } // FUNCTION: LEGO1 0x100c3750 // FUNCTION: BETA10 0x101490bd -void MxRegion::VTable0x18(MxRect32& p_rect) +void MxRegion::AddRect(MxRect32& p_rect) { MxRect32 rect(p_rect); MxRect32 newRect; - MxRegionTopBottomListCursor cursor(m_list); - MxRegionTopBottom* topBottom; + MxSpanListCursor cursor(m_spanList); + MxSpan* span; - while (rect.IsValid() && cursor.Next(topBottom)) { - if (topBottom->GetTop() >= rect.GetBottom()) { - MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect); - cursor.Prepend(newTopBottom); + while (rect.IsValid() && cursor.Next(span)) { + if (span->GetMin() >= rect.GetBottom()) { + MxSpan* newSpan = new MxSpan(rect); + cursor.Prepend(newSpan); rect.SetTop(rect.GetBottom()); } - else if (rect.GetTop() < topBottom->GetBottom()) { - if (rect.GetTop() < topBottom->GetTop()) { + else if (rect.GetTop() < span->GetMax()) { + if (rect.GetTop() < span->GetMin()) { newRect = rect; - newRect.SetBottom(topBottom->GetTop()); - MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(newRect); - cursor.Prepend(newTopBottom); - rect.SetTop(topBottom->GetTop()); + newRect.SetBottom(span->GetMin()); + MxSpan* newSpan = new MxSpan(newRect); + cursor.Prepend(newSpan); + rect.SetTop(span->GetMin()); } - else if (topBottom->GetTop() < rect.GetTop()) { - MxRegionTopBottom* newTopBottom = topBottom->Clone(); - newTopBottom->SetBottom(rect.GetTop()); - topBottom->SetTop(rect.GetTop()); - cursor.Prepend(newTopBottom); + else if (span->GetMin() < rect.GetTop()) { + MxSpan* newSpan = span->Clone(); + newSpan->SetMax(rect.GetTop()); + span->SetMin(rect.GetTop()); + cursor.Prepend(newSpan); } - if (rect.GetBottom() < topBottom->GetBottom()) { - MxRegionTopBottom* newTopBottom = topBottom->Clone(); - newTopBottom->SetBottom(rect.GetBottom()); - topBottom->SetTop(rect.GetBottom()); - newTopBottom->MergeOrExpandRegions(rect.GetLeft(), rect.GetRight()); - cursor.Prepend(newTopBottom); + if (rect.GetBottom() < span->GetMax()) { + MxSpan* newSpan = span->Clone(); + newSpan->SetMax(rect.GetBottom()); + span->SetMin(rect.GetBottom()); + newSpan->AddSegment(rect.GetLeft(), rect.GetRight()); + cursor.Prepend(newSpan); rect.SetTop(rect.GetBottom()); } else { - topBottom->MergeOrExpandRegions(rect.GetLeft(), rect.GetRight()); - rect.SetTop(topBottom->GetBottom()); + span->AddSegment(rect.GetLeft(), rect.GetRight()); + rect.SetTop(span->GetMax()); } } } if (rect.IsValid()) { - MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect); - m_list->Append(newTopBottom); + MxSpan* newSpan = new MxSpan(rect); + m_spanList->Append(newSpan); } - m_rect.UpdateBounds(p_rect); + m_boundingRect.UpdateBounds(p_rect); } // FUNCTION: LEGO1 0x100c3e20 -MxBool MxRegion::VTable0x1c(MxRect32& p_rect) +// FUNCTION: BETA10 0x10149535 +MxBool MxRegion::Intersects(MxRect32& p_rect) { - if (!m_rect.IntersectsWith(p_rect)) { + if (!m_boundingRect.IntersectsWith(p_rect)) { return FALSE; } - MxRegionTopBottomListCursor cursor(m_list); - MxRegionTopBottom* topBottom; + MxSpanListCursor cursor(m_spanList); + MxSpan* span; - while (cursor.Next(topBottom)) { - if (topBottom->GetTop() >= p_rect.GetBottom()) { + while (cursor.Next(span)) { + if (span->GetMin() >= p_rect.GetBottom()) { return FALSE; } - if (topBottom->GetBottom() > p_rect.GetTop() && topBottom->CheckHorizontalOverlap(p_rect)) { + + if (span->GetMax() > p_rect.GetTop() && span->IntersectsH(p_rect)) { return TRUE; } } @@ -111,57 +107,338 @@ MxBool MxRegion::VTable0x1c(MxRect32& p_rect) return FALSE; } -// FUNCTION: LEGO1 0x100c4c90 -MxRegionTopBottom::MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom) +// FUNCTION: LEGO1 0x100c3f70 +// FUNCTION: BETA10 0x10149663 +MxRegionCursor::MxRegionCursor(MxRegion* p_region) { - m_top = p_top; - m_bottom = p_bottom; - m_leftRightList = new MxRegionLeftRightList; + m_region = p_region; + m_rect = NULL; + m_spanListCursor = new MxSpanListCursor(m_region->m_spanList); + m_segListCursor = NULL; +} + +// FUNCTION: LEGO1 0x100c40b0 +MxRegionCursor::~MxRegionCursor() +{ + if (m_rect) { + delete m_rect; + } + + if (m_spanListCursor) { + delete m_spanListCursor; + } + + if (m_segListCursor) { + delete m_segListCursor; + } +} + +// FUNCTION: LEGO1 0x100c4140 +MxRect32* MxRegionCursor::Head() +{ + m_spanListCursor->Head(); + + MxSpan* span; + if (m_spanListCursor->Current(span)) { + CreateSegmentListCursor(span->m_segList); + + MxSegment* segment; + m_segListCursor->First(segment); + + SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); + } + else { + Reset(); + } + + return m_rect; +} + +// FUNCTION: LEGO1 0x100c41d0 +MxRect32* MxRegionCursor::Tail() +{ + m_spanListCursor->Tail(); + + MxSpan* span; + if (m_spanListCursor->Current(span)) { + CreateSegmentListCursor(span->m_segList); + + MxSegment* segment; + m_segListCursor->Last(segment); + + SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); + } + else { + Reset(); + } + + return m_rect; +} + +// FUNCTION: LEGO1 0x100c4260 +MxRect32* MxRegionCursor::Next() +{ + MxSegment* segment; + MxSpan* span; + + if (m_segListCursor && m_segListCursor->Next(segment)) { + m_spanListCursor->Current(span); + + SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); + return m_rect; + } + + if (m_spanListCursor->Next(span)) { + CreateSegmentListCursor(span->m_segList); + m_segListCursor->First(segment); + + SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); + return m_rect; + } + + Reset(); + return m_rect; +} + +// FUNCTION: LEGO1 0x100c4360 +MxRect32* MxRegionCursor::Prev() +{ + MxSegment* segment; + MxSpan* span; + + if (m_segListCursor && m_segListCursor->Prev(segment)) { + m_spanListCursor->Current(span); + + SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); + return m_rect; + } + + if (m_spanListCursor->Prev(span)) { + CreateSegmentListCursor(span->m_segList); + m_segListCursor->Last(segment); + + SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); + return m_rect; + } + + Reset(); + return m_rect; +} + +// FUNCTION: LEGO1 0x100c4460 +MxRect32* MxRegionCursor::Head(MxRect32& p_rect) +{ + m_spanListCursor->Reset(); + NextSpan(p_rect); + return m_rect; +} + +// FUNCTION: LEGO1 0x100c4480 +MxRect32* MxRegionCursor::Tail(MxRect32& p_rect) +{ + m_spanListCursor->Reset(); + PrevSpan(p_rect); + return m_rect; +} + +// FUNCTION: LEGO1 0x100c44a0 +MxRect32* MxRegionCursor::Next(MxRect32& p_rect) +{ + MxSegment* segment; + + if (m_segListCursor && m_segListCursor->Next(segment)) { + MxSpan* span; + + m_spanListCursor->Current(span); + + if (span->IntersectsV(p_rect) && segment->IntersectsH(p_rect)) { + SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); + m_rect->Intersect(p_rect); + } + else { + NextSpan(p_rect); + } + } + else { + NextSpan(p_rect); + } + + return m_rect; +} + +// FUNCTION: LEGO1 0x100c4590 +MxRect32* MxRegionCursor::Prev(MxRect32& p_rect) +{ + MxSegment* segment; + + if (m_segListCursor && m_segListCursor->Prev(segment)) { + MxSpan* span; + + m_spanListCursor->Current(span); + + if (span->IntersectsV(p_rect) && segment->IntersectsH(p_rect)) { + SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); + m_rect->Intersect(p_rect); + } + else { + PrevSpan(p_rect); + } + } + else { + PrevSpan(p_rect); + } + + return m_rect; +} + +// FUNCTION: LEGO1 0x100c4680 +void MxRegionCursor::Reset() +{ + if (m_rect) { + delete m_rect; + m_rect = NULL; + } + + m_spanListCursor->Reset(); + + if (m_segListCursor) { + delete m_segListCursor; + m_segListCursor = NULL; + } +} + +// FUNCTION: LEGO1 0x100c46c0 +void MxRegionCursor::CreateSegmentListCursor(MxSegmentList* p_segList) +{ + if (m_segListCursor) { + delete m_segListCursor; + } + + m_segListCursor = new MxSegmentListCursor(p_segList); +} + +// FUNCTION: LEGO1 0x100c4980 +void MxRegionCursor::SetRect(MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom) +{ + if (!m_rect) { + m_rect = new MxRect32; + } + + m_rect->SetLeft(p_left); + m_rect->SetTop(p_top); + m_rect->SetRight(p_right); + m_rect->SetBottom(p_bottom); +} + +// FUNCTION: LEGO1 0x100c4a20 +void MxRegionCursor::NextSpan(MxRect32& p_rect) +{ + MxSpan* span; + while (m_spanListCursor->Next(span)) { + if (p_rect.GetBottom() <= span->GetMin()) { + Reset(); + return; + } + + if (p_rect.GetTop() < span->GetMax()) { + CreateSegmentListCursor(span->m_segList); + + MxSegment* segment; + while (m_segListCursor->Next(segment)) { + if (p_rect.GetRight() <= segment->GetMin()) { + break; + } + + if (p_rect.GetLeft() < segment->GetMax()) { + SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); + m_rect->Intersect(p_rect); + return; + } + } + } + } + + Reset(); +} + +// FUNCTION: LEGO1 0x100c4b50 +void MxRegionCursor::PrevSpan(MxRect32& p_rect) +{ + MxSpan* span; + while (m_spanListCursor->Prev(span)) { + if (span->GetMax() <= p_rect.GetTop()) { + Reset(); + return; + } + + if (span->GetMin() < p_rect.GetBottom()) { + CreateSegmentListCursor(span->m_segList); + + MxSegment* segment; + while (m_segListCursor->Prev(segment)) { + if (segment->GetMax() <= p_rect.GetLeft()) { + break; + } + + if (segment->GetMin() < p_rect.GetRight()) { + SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); + m_rect->Intersect(p_rect); + return; + } + } + } + } + + Reset(); +} + +// FUNCTION: LEGO1 0x100c4c90 +MxSpan::MxSpan(MxS32 p_min, MxS32 p_max) +{ + m_min = p_min; + m_max = p_max; + m_segList = new MxSegmentList; } // FUNCTION: LEGO1 0x100c50e0 // FUNCTION: BETA10 0x1014a2d6 -MxRegionTopBottom::MxRegionTopBottom(MxRect32& p_rect) +MxSpan::MxSpan(MxRect32& p_rect) { - m_top = p_rect.GetTop(); - m_bottom = p_rect.GetBottom(); - m_leftRightList = new MxRegionLeftRightList; + m_min = p_rect.GetTop(); + m_max = p_rect.GetBottom(); + m_segList = new MxSegmentList; - MxRegionLeftRight* leftRight = new MxRegionLeftRight(p_rect.GetLeft(), p_rect.GetRight()); - m_leftRightList->Append(leftRight); + MxSegment* segment = new MxSegment(p_rect.GetLeft(), p_rect.GetRight()); + m_segList->Append(segment); } // FUNCTION: LEGO1 0x100c5280 // FUNCTION: BETA10 0x1014a3fc -void MxRegionTopBottom::MergeOrExpandRegions(MxS32 p_left, MxS32 p_right) +void MxSpan::AddSegment(MxS32 p_min, MxS32 p_max) { - MxRegionLeftRightListCursor a(m_leftRightList); - MxRegionLeftRightListCursor b(m_leftRightList); + MxSegmentListCursor a(m_segList); + MxSegmentListCursor b(m_segList); - MxRegionLeftRight* leftRight; - while (a.Next(leftRight) && leftRight->GetRight() < p_left) { + MxSegment* segment; + while (a.Next(segment) && segment->GetMax() < p_min) { ; } - if (!a.HasMatch()) { - MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right); - m_leftRightList->Append(copy); - } - else { - if (p_left > leftRight->GetLeft()) { - p_left = leftRight->GetLeft(); + if (a.HasMatch()) { + if (p_min > segment->GetMin()) { + p_min = segment->GetMin(); } - while (leftRight->GetLeft() < p_right) { - if (p_right < leftRight->GetRight()) { - p_right = leftRight->GetRight(); + while (segment->GetMin() < p_max) { + if (p_max < segment->GetMax()) { + p_max = segment->GetMax(); } b = a; b.Next(); a.Destroy(); - if (!b.Current(leftRight)) { + if (!b.Current(segment)) { break; } @@ -169,42 +446,48 @@ void MxRegionTopBottom::MergeOrExpandRegions(MxS32 p_left, MxS32 p_right) } if (a.HasMatch()) { - MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right); + MxSegment* copy = new MxSegment(p_min, p_max); a.Prepend(copy); } else { - MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right); - m_leftRightList->Append(copy); + MxSegment* copy = new MxSegment(p_min, p_max); + m_segList->Append(copy); } } + else { + MxSegment* copy = new MxSegment(p_min, p_max); + m_segList->Append(copy); + } } // FUNCTION: LEGO1 0x100c55d0 -MxRegionTopBottom* MxRegionTopBottom::Clone() +MxSpan* MxSpan::Clone() { - MxRegionTopBottom* clone = new MxRegionTopBottom(m_top, m_bottom); + MxSpan* clone = new MxSpan(m_min, m_max); - MxRegionLeftRightListCursor cursor(m_leftRightList); - MxRegionLeftRight* leftRight; + MxSegmentListCursor cursor(m_segList); + MxSegment* segment; - while (cursor.Next(leftRight)) { - clone->m_leftRightList->Append(leftRight->Clone()); + while (cursor.Next(segment)) { + clone->m_segList->Append(segment->Clone()); } return clone; } // FUNCTION: LEGO1 0x100c57b0 -MxBool MxRegionTopBottom::CheckHorizontalOverlap(MxRect32& p_rect) +// FUNCTION: BETA10 0x1014aa46 +MxBool MxSpan::IntersectsH(MxRect32& p_rect) { - MxRegionLeftRightListCursor cursor(m_leftRightList); - MxRegionLeftRight* leftRight; + MxSegmentListCursor cursor(m_segList); + MxSegment* segment; - while (cursor.Next(leftRight)) { - if (p_rect.GetRight() <= leftRight->GetLeft()) { + while (cursor.Next(segment)) { + if (p_rect.GetRight() <= segment->GetMin()) { return FALSE; } - if (leftRight->GetRight() > p_rect.GetLeft()) { + + if (segment->GetMax() > p_rect.GetLeft()) { return TRUE; } } diff --git a/LEGO1/omni/src/video/mxregioncursor.cpp b/LEGO1/omni/src/video/mxregioncursor.cpp deleted file mode 100644 index 827c1947..00000000 --- a/LEGO1/omni/src/video/mxregioncursor.cpp +++ /dev/null @@ -1,298 +0,0 @@ -#include "mxregioncursor.h" - -DECOMP_SIZE_ASSERT(MxRegionCursor, 0x18); - -// FUNCTION: LEGO1 0x100c3f70 -// FUNCTION: BETA10 0x10149663 -MxRegionCursor::MxRegionCursor(MxRegion* p_region) -{ - m_region = p_region; - m_rect = NULL; - m_topBottomCursor = new MxRegionTopBottomListCursor(m_region->m_list); - m_leftRightCursor = NULL; -} - -// FUNCTION: LEGO1 0x100c40b0 -MxRegionCursor::~MxRegionCursor() -{ - if (m_rect) { - delete m_rect; - } - - if (m_topBottomCursor) { - delete m_topBottomCursor; - } - - if (m_leftRightCursor) { - delete m_leftRightCursor; - } -} - -// FUNCTION: LEGO1 0x100c4140 -MxRect32* MxRegionCursor::VTable0x18() -{ - m_topBottomCursor->Head(); - - MxRegionTopBottom* topBottom; - if (m_topBottomCursor->Current(topBottom)) { - ResetAndInitializeCursor(*topBottom->m_leftRightList); - - MxRegionLeftRight* leftRight; - m_leftRightCursor->First(leftRight); - - UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom()); - } - else { - Reset(); - } - - return m_rect; -} - -// FUNCTION: LEGO1 0x100c41d0 -MxRect32* MxRegionCursor::VTable0x20() -{ - m_topBottomCursor->Tail(); - - MxRegionTopBottom* topBottom; - if (m_topBottomCursor->Current(topBottom)) { - ResetAndInitializeCursor(*topBottom->m_leftRightList); - - MxRegionLeftRight* leftRight; - m_leftRightCursor->Last(leftRight); - - UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom()); - } - else { - Reset(); - } - - return m_rect; -} - -// FUNCTION: LEGO1 0x100c4260 -MxRect32* MxRegionCursor::VTable0x28() -{ - MxRegionLeftRight* leftRight; - MxRegionTopBottom* topBottom; - - if (m_leftRightCursor && m_leftRightCursor->Next(leftRight)) { - m_topBottomCursor->Current(topBottom); - - UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom()); - return m_rect; - } - - if (m_topBottomCursor->Next(topBottom)) { - ResetAndInitializeCursor(*topBottom->m_leftRightList); - m_leftRightCursor->First(leftRight); - - UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom()); - return m_rect; - } - - Reset(); - return m_rect; -} - -// FUNCTION: LEGO1 0x100c4360 -MxRect32* MxRegionCursor::VTable0x30() -{ - MxRegionLeftRight* leftRight; - MxRegionTopBottom* topBottom; - - if (m_leftRightCursor && m_leftRightCursor->Prev(leftRight)) { - m_topBottomCursor->Current(topBottom); - - UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom()); - return m_rect; - } - - if (m_topBottomCursor->Prev(topBottom)) { - ResetAndInitializeCursor(*topBottom->m_leftRightList); - m_leftRightCursor->Last(leftRight); - - UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom()); - return m_rect; - } - - Reset(); - return m_rect; -} - -// FUNCTION: LEGO1 0x100c4460 -MxRect32* MxRegionCursor::VTable0x14(MxRect32& p_rect) -{ - m_topBottomCursor->Reset(); - ProcessRectOverlapAscending(p_rect); - return m_rect; -} - -// FUNCTION: LEGO1 0x100c4480 -MxRect32* MxRegionCursor::VTable0x1c(MxRect32& p_rect) -{ - m_topBottomCursor->Reset(); - ProcessOverlapWithRect(p_rect); - return m_rect; -} - -// FUNCTION: LEGO1 0x100c44a0 -MxRect32* MxRegionCursor::VTable0x24(MxRect32& p_rect) -{ - MxRegionLeftRight* leftRight; - - if (m_leftRightCursor && m_leftRightCursor->Next(leftRight)) { - MxRegionTopBottom* topBottom; - - m_topBottomCursor->Current(topBottom); - - if (topBottom->IntersectsWith(p_rect) && leftRight->IntersectsWith(p_rect)) { - UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom()); - m_rect->Intersect(p_rect); - } - else { - ProcessRectOverlapAscending(p_rect); - } - } - else { - ProcessRectOverlapAscending(p_rect); - } - - return m_rect; -} - -// FUNCTION: LEGO1 0x100c4590 -MxRect32* MxRegionCursor::VTable0x2c(MxRect32& p_rect) -{ - MxRegionLeftRight* leftRight; - - if (m_leftRightCursor && m_leftRightCursor->Prev(leftRight)) { - MxRegionTopBottom* topBottom; - - m_topBottomCursor->Current(topBottom); - - if (topBottom->IntersectsWith(p_rect) && leftRight->IntersectsWith(p_rect)) { - UpdateRect(leftRight->GetLeft(), topBottom->GetTop(), leftRight->GetRight(), topBottom->GetBottom()); - m_rect->Intersect(p_rect); - } - else { - ProcessOverlapWithRect(p_rect); - } - } - else { - ProcessOverlapWithRect(p_rect); - } - - return m_rect; -} - -// FUNCTION: LEGO1 0x100c4680 -void MxRegionCursor::Reset() -{ - if (m_rect) { - delete m_rect; - m_rect = NULL; - } - - m_topBottomCursor->Reset(); - - if (m_leftRightCursor) { - delete m_leftRightCursor; - m_leftRightCursor = NULL; - } -} - -// FUNCTION: LEGO1 0x100c46c0 -void MxRegionCursor::ResetAndInitializeCursor(MxRegionLeftRightList& p_leftRightList) -{ - if (m_leftRightCursor) { - delete m_leftRightCursor; - } - - m_leftRightCursor = new MxRegionLeftRightListCursor(&p_leftRightList); -} - -// FUNCTION: LEGO1 0x100c4980 -void MxRegionCursor::UpdateRect(MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom) -{ - if (!m_rect) { - m_rect = new MxRect32; - } - - m_rect->SetLeft(p_left); - m_rect->SetTop(p_top); - m_rect->SetRight(p_right); - m_rect->SetBottom(p_bottom); -} - -// FUNCTION: LEGO1 0x100c4a20 -void MxRegionCursor::ProcessRectOverlapAscending(MxRect32& p_rect) -{ - MxRegionTopBottom* topBottom; - while (m_topBottomCursor->Next(topBottom)) { - if (p_rect.GetBottom() <= topBottom->GetTop()) { - Reset(); - return; - } - - if (p_rect.GetTop() < topBottom->GetBottom()) { - ResetAndInitializeCursor(*topBottom->m_leftRightList); - - MxRegionLeftRight* leftRight; - while (m_leftRightCursor->Next(leftRight)) { - if (p_rect.GetRight() <= leftRight->GetLeft()) { - break; - } - - if (p_rect.GetLeft() < leftRight->GetRight()) { - UpdateRect( - leftRight->GetLeft(), - topBottom->GetTop(), - leftRight->GetRight(), - topBottom->GetBottom() - ); - m_rect->Intersect(p_rect); - return; - } - } - } - } - - Reset(); -} - -// FUNCTION: LEGO1 0x100c4b50 -void MxRegionCursor::ProcessOverlapWithRect(MxRect32& p_rect) -{ - MxRegionTopBottom* topBottom; - while (m_topBottomCursor->Prev(topBottom)) { - if (topBottom->GetBottom() <= p_rect.GetTop()) { - Reset(); - return; - } - - if (topBottom->GetTop() < p_rect.GetBottom()) { - ResetAndInitializeCursor(*topBottom->m_leftRightList); - - MxRegionLeftRight* leftRight; - while (m_leftRightCursor->Prev(leftRight)) { - if (leftRight->GetRight() <= p_rect.GetLeft()) { - break; - } - - if (leftRight->GetLeft() < p_rect.GetRight()) { - UpdateRect( - leftRight->GetLeft(), - topBottom->GetTop(), - leftRight->GetRight(), - topBottom->GetBottom() - ); - m_rect->Intersect(p_rect); - return; - } - } - } - } - - Reset(); -} diff --git a/LEGO1/omni/src/video/mxvideomanager.cpp b/LEGO1/omni/src/video/mxvideomanager.cpp index f6040ce8..4a6072a0 100644 --- a/LEGO1/omni/src/video/mxvideomanager.cpp +++ b/LEGO1/omni/src/video/mxvideomanager.cpp @@ -32,12 +32,12 @@ MxVideoManager::~MxVideoManager() // FUNCTION: LEGO1 0x100be320 MxResult MxVideoManager::Init() { - this->m_pDirectDraw = NULL; - this->m_pDirect3D = NULL; - this->m_displaySurface = NULL; - this->m_region = NULL; - this->m_videoParam.SetPalette(NULL); - this->m_unk0x60 = FALSE; + m_pDirectDraw = NULL; + m_pDirect3D = NULL; + m_displaySurface = NULL; + m_region = NULL; + m_videoParam.SetPalette(NULL); + m_unk0x60 = FALSE; return SUCCESS; } @@ -86,8 +86,8 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor) // FUNCTION: LEGO1 0x100be3e0 void MxVideoManager::UpdateRegion() { - if (m_region->VTable0x20() == FALSE) { - MxRect32 rect(m_region->GetRect()); + if (m_region->IsEmpty() == FALSE) { + MxRect32 rect(m_region->GetBoundingRect()); rect.Intersect(m_videoParam.GetRect()); m_displaySurface @@ -99,13 +99,13 @@ void MxVideoManager::UpdateRegion() // FUNCTION: BETA10 0x1012ce5e void MxVideoManager::SortPresenterList() { - if (this->m_presenters->GetCount() <= 1) { + if (m_presenters->GetNumElements() <= 1) { return; } - MxPresenterListCursor a(this->m_presenters); - MxPresenterListCursor b(this->m_presenters); - MxU32 count = this->m_presenters->GetCount() - 1; + MxPresenterListCursor a(m_presenters); + MxPresenterListCursor b(m_presenters); + MxU32 count = m_presenters->GetNumElements() - 1; MxBool finished; if (count != 0) { @@ -302,7 +302,7 @@ void MxVideoManager::InvalidateRect(MxRect32& p_rect) m_criticalSection.Enter(); if (m_region) { - m_region->VTable0x18(p_rect); + m_region->AddRect(p_rect); } m_criticalSection.Leave(); @@ -316,7 +316,7 @@ MxResult MxVideoManager::Tickle() SortPresenterList(); MxPresenter* presenter; - MxPresenterListCursor cursor(this->m_presenters); + MxPresenterListCursor cursor(m_presenters); while (cursor.Next(presenter)) { presenter->Tickle(); @@ -339,14 +339,14 @@ MxResult MxVideoManager::RealizePalette(MxPalette* p_palette) { PALETTEENTRY paletteEntries[256]; - this->m_criticalSection.Enter(); + m_criticalSection.Enter(); - if (p_palette && this->m_videoParam.GetPalette()) { + if (p_palette && m_videoParam.GetPalette()) { p_palette->GetEntries(paletteEntries); - this->m_videoParam.GetPalette()->SetEntries(paletteEntries); - this->m_displaySurface->SetPalette(this->m_videoParam.GetPalette()); + m_videoParam.GetPalette()->SetEntries(paletteEntries); + m_displaySurface->SetPalette(m_videoParam.GetPalette()); } - this->m_criticalSection.Leave(); + m_criticalSection.Leave(); return SUCCESS; } diff --git a/LEGO1/omni/src/video/mxvideopresenter.cpp b/LEGO1/omni/src/video/mxvideopresenter.cpp index c92e5dc4..a045ae95 100644 --- a/LEGO1/omni/src/video/mxvideopresenter.cpp +++ b/LEGO1/omni/src/video/mxvideopresenter.cpp @@ -5,7 +5,7 @@ #include "mxdsmediaaction.h" #include "mxdssubscriber.h" #include "mxmisc.h" -#include "mxregioncursor.h" +#include "mxregion.h" #include "mxvideomanager.h" DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64); @@ -342,7 +342,7 @@ void MxVideoPresenter::PutFrame() MxRegionCursor cursor(region); MxRect32* regionRect; - while ((regionRect = cursor.VTable0x24(rect))) { + while ((regionRect = cursor.Next(rect))) { if (regionRect->GetWidth() >= 1 && regionRect->GetHeight() >= 1) { RECT src, dest; From 92f20e7f7bdf6f663b55120ed2584446f24644d2 Mon Sep 17 00:00:00 2001 From: MS Date: Thu, 27 Feb 2025 21:32:27 -0500 Subject: [PATCH 05/16] Fix enum in Ambulance::HandlePathStruct (#1395) --- LEGO1/lego/legoomni/src/actors/ambulance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/lego/legoomni/src/actors/ambulance.cpp b/LEGO1/lego/legoomni/src/actors/ambulance.cpp index 129b3863..eb1b7c8c 100644 --- a/LEGO1/lego/legoomni/src/actors/ambulance.cpp +++ b/LEGO1/lego/legoomni/src/actors/ambulance.cpp @@ -302,7 +302,7 @@ MxLong Ambulance::HandlePathStruct(LegoPathStructNotificationParam& p_param) InvokeAction(Extra::e_stop, *g_isleScript, m_lastAction, NULL); } - PlayAction(IsleScript::c_Avo915In_PlayWav); + PlayAction(IsleScript::c_Avo916In_PlayWav); return 0; } } From 8b7182f9dba176ad5f2700083e1dd4afc3adc290 Mon Sep 17 00:00:00 2001 From: MS Date: Thu, 27 Feb 2025 22:02:17 -0500 Subject: [PATCH 06/16] MxDirect3D::SetDevice to 100% (#1396) --- LEGO1/mxdirectx/mxdirect3d.cpp | 77 ++++++++++++++++------------------ 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/LEGO1/mxdirectx/mxdirect3d.cpp b/LEGO1/mxdirectx/mxdirect3d.cpp index 80626a30..fbdb14e4 100644 --- a/LEGO1/mxdirectx/mxdirect3d.cpp +++ b/LEGO1/mxdirectx/mxdirect3d.cpp @@ -1,5 +1,7 @@ #include "mxdirect3d.h" +#include + DECOMP_SIZE_ASSERT(MxDirect3D, 0x894) #if !defined(MXDIRECTX_FOR_CONFIG) @@ -234,81 +236,72 @@ BOOL MxDirect3D::SetDevice(MxDeviceEnumerate& p_deviceEnumerate, MxDriver* p_dri m_pCurrentDeviceModesList = NULL; } - MxAssignedDevice* assignedDevice = new MxAssignedDevice; + MxAssignedDevice* d = new MxAssignedDevice; + assert(d); int i = 0; - for (list::iterator it = p_deviceEnumerate.m_list.begin(); it != p_deviceEnumerate.m_list.end(); it++) { + for (list::iterator it = p_deviceEnumerate.m_list.begin(); it != p_deviceEnumerate.m_list.end(); + it++, i++) { MxDriver& driver = *it; if (&driver == p_driver) { - assignedDevice->m_deviceInfo = new DeviceModesInfo; + d->m_deviceInfo = new DeviceModesInfo; if (driver.m_guid) { - assignedDevice->m_deviceInfo->m_guid = new GUID; - memcpy(assignedDevice->m_deviceInfo->m_guid, driver.m_guid, sizeof(GUID)); + d->m_deviceInfo->m_guid = new GUID; + *d->m_deviceInfo->m_guid = *driver.m_guid; } - assignedDevice->m_deviceInfo->m_count = driver.m_displayModes.size(); - - if (assignedDevice->m_deviceInfo->m_count > 0) { - assignedDevice->m_deviceInfo->m_modeArray = - new DeviceModesInfo::Mode[assignedDevice->m_deviceInfo->m_count]; + d->m_deviceInfo->m_count = driver.m_displayModes.size(); + if (d->m_deviceInfo->m_count > 0) { int j = 0; + d->m_deviceInfo->m_modeArray = new DeviceModesInfo::Mode[d->m_deviceInfo->m_count]; + for (list::iterator it2 = driver.m_displayModes.begin(); it2 != driver.m_displayModes.end(); - it2++) { - assignedDevice->m_deviceInfo->m_modeArray[j].width = (*it2).m_width; - assignedDevice->m_deviceInfo->m_modeArray[j].height = (*it2).m_height; - assignedDevice->m_deviceInfo->m_modeArray[j].bitsPerPixel = (*it2).m_bitsPerPixel; - j++; + it2++, j++) { + d->m_deviceInfo->m_modeArray[j].width = (*it2).m_width; + d->m_deviceInfo->m_modeArray[j].height = (*it2).m_height; + d->m_deviceInfo->m_modeArray[j].bitsPerPixel = (*it2).m_bitsPerPixel; } } - memcpy( - &assignedDevice->m_deviceInfo->m_ddcaps, - &driver.m_ddCaps, - sizeof(assignedDevice->m_deviceInfo->m_ddcaps) - ); + d->m_deviceInfo->m_ddcaps = driver.m_ddCaps; if (i == 0) { - assignedDevice->m_flags |= MxAssignedDevice::c_primaryDevice; + d->m_flags |= MxAssignedDevice::c_primaryDevice; } for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) { Direct3DDeviceInfo& device = *it2; - if (&device != p_device) { - continue; - } + if (&device == p_device) { + memcpy(&d->m_guid, device.m_guid, sizeof(d->m_guid)); - memcpy(&assignedDevice->m_guid, device.m_guid, sizeof(assignedDevice->m_guid)); + if (device.m_HWDesc.dcmColorModel) { + d->m_flags |= MxAssignedDevice::c_hardwareMode; + d->m_desc = device.m_HWDesc; + } + else { + d->m_desc = device.m_HELDesc; + } - D3DDEVICEDESC* desc; - if (device.m_HWDesc.dcmColorModel) { - assignedDevice->m_flags |= MxAssignedDevice::c_hardwareMode; - desc = &device.m_HWDesc; + m_assignedDevice = d; + m_pCurrentDeviceModesList = d->m_deviceInfo; + break; } - else { - desc = &device.m_HELDesc; - } - - memcpy(&assignedDevice->m_desc, desc, sizeof(assignedDevice->m_desc)); - m_assignedDevice = assignedDevice; - m_pCurrentDeviceModesList = assignedDevice->m_deviceInfo; - break; } } - - i++; } if (!m_assignedDevice) { - delete assignedDevice; + delete d; return FALSE; } - - return TRUE; + else { + return TRUE; + } } #endif From 87d13aa2772c2d9e349ae3b366b77a035b70d698 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Sun, 2 Mar 2025 19:59:03 +0100 Subject: [PATCH 07/16] Add various BETA10 references and fixes (#1398) Co-authored-by: jonschz --- LEGO1/lego/legoomni/include/legoanimactor.h | 3 +++ LEGO1/lego/legoomni/include/legosoundmanager.h | 2 ++ LEGO1/lego/legoomni/src/actors/act2actor.cpp | 7 +++++++ LEGO1/lego/legoomni/src/audio/lego3dsound.cpp | 1 + LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp | 3 +++ LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp | 6 ++++++ LEGO1/library_msvc.h | 7 +++++++ LEGO1/omni/include/mxsoundmanager.h | 1 + LEGO1/omni/include/mxticklemanager.h | 8 ++++++++ LEGO1/omni/src/audio/mxsoundmanager.cpp | 1 + LEGO1/omni/src/common/mxticklemanager.cpp | 7 +++++++ reccmp-project.yml | 1 + 12 files changed, 47 insertions(+) diff --git a/LEGO1/lego/legoomni/include/legoanimactor.h b/LEGO1/lego/legoomni/include/legoanimactor.h index 112f215c..5b752586 100644 --- a/LEGO1/lego/legoomni/include/legoanimactor.h +++ b/LEGO1/lego/legoomni/include/legoanimactor.h @@ -105,6 +105,9 @@ class LegoAnimActor : public virtual LegoPathActor { // TEMPLATE: LEGO1 0x1001c7e0 // vector >::_Destroy +// TEMPLATE: BETA10 0x1000fbc0 +// vector >::begin + // TEMPLATE: LEGO1 0x1001c9e0 // uninitialized_fill_n diff --git a/LEGO1/lego/legoomni/include/legosoundmanager.h b/LEGO1/lego/legoomni/include/legosoundmanager.h index 696eaf1c..d0320320 100644 --- a/LEGO1/lego/legoomni/include/legosoundmanager.h +++ b/LEGO1/lego/legoomni/include/legosoundmanager.h @@ -6,6 +6,7 @@ class LegoCacheSoundManager; // VTABLE: LEGO1 0x100d6b10 +// VTABLE: BETA10 0x101bec30 // SIZE 0x44 class LegoSoundManager : public MxSoundManager { public: @@ -17,6 +18,7 @@ class LegoSoundManager : public MxSoundManager { MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread) override; // vtable+0x30 // SYNTHETIC: LEGO1 0x10029920 + // SYNTHETIC: BETA10 0x100d0660 // LegoSoundManager::`scalar deleting destructor' void UpdateListener(const float* p_position, const float* p_direction, const float* p_up, const float* p_velocity); diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index 014f03a0..d810c975 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -153,8 +153,15 @@ void Act2Actor::FUN_10018980() assert(m_shootAnim); m_unk0x38 = SoundManager()->GetCacheSoundManager()->FindSoundByKey("xarrow"); +#ifdef BETA10 + // actually 0x2c and 0x30 + m_unk0x38 = SoundManager()->GetCacheSoundManager()->FindSoundByKey("bcrash"); + m_unk0x38->SetDistance(35, 60); + m_unk0x38->SetDistance(35, 60); +#else m_unk0x38->SetDistance(45, 55); m_roi->SetVisibility(TRUE); +#endif } // FUNCTION: LEGO1 0x100189f0 diff --git a/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp b/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp index 508cd395..81112ea8 100644 --- a/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp +++ b/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp @@ -296,6 +296,7 @@ void Lego3DSound::Reset() } // FUNCTION: LEGO1 0x10011cf0 +// FUNCTION: BETA10 0x10039fe0 MxS32 Lego3DSound::SetDistance(MxS32 p_min, MxS32 p_max) { if (MxOmni::IsSound3D()) { diff --git a/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp index 289e4ea3..34be4519 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp @@ -61,8 +61,11 @@ MxResult LegoCacheSoundManager::Tickle() } // FUNCTION: LEGO1 0x1003d170 +// FUNCTION: BETA10 0x1006539d LegoCacheSound* LegoCacheSoundManager::FindSoundByKey(const char* p_key) { + // This function has changed completely since BETA10, but its calls suggest the match is correct + char* key = new char[strlen(p_key) + 1]; strcpy(key, p_key); diff --git a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp index 2832d825..c92f2bea 100644 --- a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp @@ -4,6 +4,8 @@ #include "mxautolock.h" #include "mxomni.h" +#include + DECOMP_SIZE_ASSERT(LegoSoundManager, 0x44) // FUNCTION: LEGO1 0x100298a0 @@ -37,6 +39,7 @@ void LegoSoundManager::Destroy(MxBool p_fromDestructor) } // FUNCTION: LEGO1 0x100299f0 +// FUNCTION: BETA10 0x100d0129 MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) { MxBool locked = FALSE; @@ -67,6 +70,7 @@ MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) } m_cacheSoundManager = new LegoCacheSoundManager; + assert(m_cacheSoundManager); result = SUCCESS; } @@ -83,12 +87,14 @@ MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) } // FUNCTION: LEGO1 0x1002a390 +// FUNCTION: BETA10 0x100d02ed void LegoSoundManager::Destroy() { Destroy(FALSE); } // FUNCTION: LEGO1 0x1002a3a0 +// FUNCTION: BETA10 0x100d030d MxResult LegoSoundManager::Tickle() { MxSoundManager::Tickle(); diff --git a/LEGO1/library_msvc.h b/LEGO1/library_msvc.h index 2ae816e7..51d0cba1 100644 --- a/LEGO1/library_msvc.h +++ b/LEGO1/library_msvc.h @@ -783,4 +783,11 @@ // GLOBAL: BETA10 0x101faf78 // __app_type +// GLOBAL: LEGO1 0x100db6e0 +// GUID_SysKeyboard + +// Cannot be handled right now due to anonymous pointer in struct +// // GLOBAL: LEGO1 0x10098f80 +// c_dfDIKeyboard + #endif diff --git a/LEGO1/omni/include/mxsoundmanager.h b/LEGO1/omni/include/mxsoundmanager.h index 3d7c35c7..36568ef3 100644 --- a/LEGO1/omni/include/mxsoundmanager.h +++ b/LEGO1/omni/include/mxsoundmanager.h @@ -8,6 +8,7 @@ #include // VTABLE: LEGO1 0x100dc128 +// VTABLE: BETA10 0x101c1ce8 // SIZE 0x3c class MxSoundManager : public MxAudioManager { public: diff --git a/LEGO1/omni/include/mxticklemanager.h b/LEGO1/omni/include/mxticklemanager.h index 17837479..1fae7a43 100644 --- a/LEGO1/omni/include/mxticklemanager.h +++ b/LEGO1/omni/include/mxticklemanager.h @@ -34,10 +34,13 @@ class MxTickleClient { typedef list MxTickleClientPtrList; // VTABLE: LEGO1 0x100d86d8 +// VTABLE: BETA10 0x101bc9d0 // SIZE 0x14 class MxTickleManager : public MxCore { public: + // FUNCTION: BETA10 0x100937c0 MxTickleManager() {} + ~MxTickleManager() override; MxResult Tickle() override; // vtable+0x08 @@ -47,6 +50,7 @@ class MxTickleManager : public MxCore { virtual MxTime GetClientTickleInterval(MxCore* p_client); // vtable+0x20 // SYNTHETIC: LEGO1 0x1005a510 + // SYNTHETIC: BETA10 0x100962f0 // MxTickleManager::`scalar deleting destructor' private: @@ -58,7 +62,11 @@ class MxTickleManager : public MxCore { // TEMPLATE: LEGO1 0x1005a4a0 // list >::~list > +// TEMPLATE: BETA10 0x10093870 +// List::List + // TEMPLATE: LEGO1 0x1005a530 +// TEMPLATE: BETA10 0x10096340 // List::~List #endif // MXTICKLEMANAGER_H diff --git a/LEGO1/omni/src/audio/mxsoundmanager.cpp b/LEGO1/omni/src/audio/mxsoundmanager.cpp index e97f7f29..ccfe2dc2 100644 --- a/LEGO1/omni/src/audio/mxsoundmanager.cpp +++ b/LEGO1/omni/src/audio/mxsoundmanager.cpp @@ -67,6 +67,7 @@ void MxSoundManager::Destroy(MxBool p_fromDestructor) } // FUNCTION: LEGO1 0x100ae8b0 +// FUNCTION: BETA10 0x10132e94 MxResult MxSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) { MxResult status = FAILURE; diff --git a/LEGO1/omni/src/common/mxticklemanager.cpp b/LEGO1/omni/src/common/mxticklemanager.cpp index 59fae3f3..64933fb7 100644 --- a/LEGO1/omni/src/common/mxticklemanager.cpp +++ b/LEGO1/omni/src/common/mxticklemanager.cpp @@ -5,6 +5,8 @@ #include "mxtimer.h" #include "mxtypes.h" +#include + #define TICKLE_MANAGER_FLAG_DESTROY 0x01 DECOMP_SIZE_ASSERT(MxTickleClient, 0x10); @@ -30,6 +32,7 @@ MxTickleManager::~MxTickleManager() } // FUNCTION: LEGO1 0x100bdde0 +// FUNCTION: BETA10 0x1013eb1f MxResult MxTickleManager::Tickle() { MxTime time = Timer()->GetTime(); @@ -60,6 +63,7 @@ MxResult MxTickleManager::Tickle() } // FUNCTION: LEGO1 0x100bde80 +// FUNCTION: BETA10 0x1013ec5f void MxTickleManager::RegisterClient(MxCore* p_client, MxTime p_interval) { MxTime interval = GetClientTickleInterval(p_client); @@ -72,6 +76,7 @@ void MxTickleManager::RegisterClient(MxCore* p_client, MxTime p_interval) } // FUNCTION: LEGO1 0x100bdf60 +// FUNCTION: BETA10 0x1013edd0 void MxTickleManager::UnregisterClient(MxCore* p_client) { MxTickleClientPtrList::iterator it = m_clients.begin(); @@ -87,6 +92,7 @@ void MxTickleManager::UnregisterClient(MxCore* p_client) } // FUNCTION: LEGO1 0x100bdfa0 +// FUNCTION: BETA10 0x1013ee6d void MxTickleManager::SetClientTickleInterval(MxCore* p_client, MxTime p_interval) { for (MxTickleClientPtrList::iterator it = m_clients.begin(); it != m_clients.end(); it++) { @@ -99,6 +105,7 @@ void MxTickleManager::SetClientTickleInterval(MxCore* p_client, MxTime p_interva } // FUNCTION: LEGO1 0x100be000 +// FUNCTION: BETA10 0x1013ef2d MxTime MxTickleManager::GetClientTickleInterval(MxCore* p_client) { MxTickleClientPtrList::iterator it = m_clients.begin(); diff --git a/reccmp-project.yml b/reccmp-project.yml index 009c737f..b433ce46 100644 --- a/reccmp-project.yml +++ b/reccmp-project.yml @@ -35,5 +35,6 @@ targets: - 0x100f8ad0 - 0x100fa200 - 0x100f9780 + - 0x100fb080 # memset etc. - 0x100f9570 From 06d23a4e996758725d4434a621f78e1a661d999c Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Sun, 2 Mar 2025 19:59:16 +0100 Subject: [PATCH 08/16] Add BETA10 reference to `_aexit_rtn` (#1397) Co-authored-by: jonschz --- LEGO1/library_msvc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/LEGO1/library_msvc.h b/LEGO1/library_msvc.h index 51d0cba1..7622ae1a 100644 --- a/LEGO1/library_msvc.h +++ b/LEGO1/library_msvc.h @@ -774,6 +774,9 @@ // LIBRARY: BETA10 0x100fbdb0 // _exit +// GLOBAL: BETA10 0x101faf70 +// _aexit_rtn + // LIBRARY: BETA10 0x10100bf0 // _CrtDbgReport From ca1c8b2be67e62e8f459d5d854bbc255f03ae7bd Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 5 Mar 2025 15:25:39 -0700 Subject: [PATCH 09/16] Add `build-with-entropy` pipeline (#1384) * Try entropy build * Fix * Updates * Remove file * Fix * Add seed parameter to entropy.sh * echo SEED used * Try build pipeline changes * Add python setup * Fix pipeline * Increase number of samples, add entropy to isle and config * Try 32 samples * Empty commit for another CI run * Try 50 samples * Empty commit for another CI run * Empty commit for another CI run * Empty commit for another CI run * Empty commit for another CI run * Empty commit for another CI run * Empty commit for another CI run * Empty commit for another CI run * Empty commit for another CI run * Trigger CI with 100 entropy samples * Trigger CI with 100 entropy samples * Trigger CI with 100 entropy samples * Trigger CI with 100 entropy samples * Trigger CI with 100 entropy samples * Trigger CI with 100 entropy samples * Trigger CI with 100 entropy samples * Trigger CI with 100 entropy samples * Trigger CI with 100 entropy samples * Trigger CI with 100 entropy samples * Update * Echo seed * Update text * Fix requirements.txt * Cancel previous CI workflows * Try only build,yml * Empty commit - should stop earlier build * Fix upload --- .github/workflows/build.yml | 144 +++++++++++++++++++++++++++++++++--- CMakeLists.txt | 13 ++++ tools/entropy.py | 45 +++++++++++ 3 files changed, 193 insertions(+), 9 deletions(-) create mode 100644 tools/entropy.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eabeb295..7dfca4af 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,6 +2,10 @@ name: Build on: [push, pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: fetch-deps: name: Download original binaries @@ -100,9 +104,104 @@ jobs: build/LEGO1.DLL build/LEGO1.PDB + build-with-entropy: + name: 'MSVC 4.20 with entropy' + needs: [fetch-deps] + runs-on: windows-latest + strategy: + matrix: + instance: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - uses: actions/checkout@v4 + with: + repository: itsmattkc/msvc420 + path: msvc420 + + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v2 + with: + # Use minimum supported version + cmake-version: '3.15.x' + + - name: Patch MSVC 4.2 + run: | + tools/patch_c2.py msvc420/bin/C2.EXE + + - name: Generate Entropy + shell: bash + run: | + # Get the first 8 characters of the SHA (enough for a decent seed) + SHA_PREFIX=$(echo "${{ github.sha }}" | cut -c 1-8) + ENTROPY_SEED=$((16#$SHA_PREFIX + ${{ matrix.instance }})) + + echo "Using seed: $ENTROPY_SEED" + python3 tools/entropy.py $ENTROPY_SEED > entropy.h + + - name: Build + shell: cmd + run: | + call .\msvc420\bin\VCVARS32.BAT x86 + cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DISLE_INCLUDE_ENTROPY=ON -G "NMake Makefiles" + cmake --build build + + - name: Restore cached original binaries + id: cache-original-binaries + uses: actions/cache/restore@v4 + with: + enableCrossOsArchive: true + path: legobin + key: legobin + + - name: Install python packages + shell: bash + run: | + pip install -r tools/requirements.txt + + - name: Detect binaries + run: | + reccmp-project detect --what original --search-path legobin + reccmp-project detect --what recompiled --search-path build + + - name: Summarize Accuracy + shell: bash + run: | + reccmp-reccmp --target CONFIG --json CONFIGPROGRESS.json + reccmp-reccmp --target ISLE --json ISLEPROGRESS.json + reccmp-reccmp --target LEGO1 --json LEGO1PROGRESS.json + + - name: Upload Artifact + uses: actions/upload-artifact@main + with: + name: Win32-Entropy-${{ matrix.instance }} + path: | + CONFIGPROGRESS.json + ISLEPROGRESS.json + LEGO1PROGRESS.json + + merge-entropy-artifacts: + name: 'Merge entropy artifacts' + runs-on: ubuntu-latest + needs: build-with-entropy + steps: + - name: Merge Artifacts + uses: actions/upload-artifact/merge@v4 + with: + name: Win32-Entropy + pattern: Win32-Entropy-* + separate-directories: true + compare: name: Compare with master - needs: [build, fetch-deps] + needs: [build, merge-entropy-artifacts, fetch-deps] runs-on: windows-latest steps: - uses: actions/checkout@main @@ -113,8 +212,13 @@ jobs: - uses: actions/download-artifact@main with: - name: Win32 - path: build + name: Win32 + path: build + + - uses: actions/download-artifact@main + with: + name: Win32-Entropy + path: build-entropy - name: Restore cached original binaries id: cache-original-binaries @@ -156,6 +260,28 @@ jobs: reccmp-reccmp --target ISLE --diff ISLEPROGRESS-old.json || echo "Current master not found" reccmp-reccmp --target LEGO1 --diff LEGO1PROGRESS-old.json || echo "Current master not found" + - name: Aggregate Accuracy + shell: bash + run: | + reccmp-aggregate --samples $(find build-entropy -type f -name "CONFIGPROGRESS.json") --output CONFIGPROGRESS-agg.json + reccmp-aggregate --samples $(find build-entropy -type f -name "ISLEPROGRESS.json") --output ISLEPROGRESS-agg.json + reccmp-aggregate --samples $(find build-entropy -type f -name "LEGO1PROGRESS.json") --output LEGO1PROGRESS-agg.json + + - name: Compare Aggregate Accuracy With Current Master + shell: bash + env: + RELEASE_URL: https://github.com/isledecomp/isle/releases/download/continuous + run: | + # Download the current master state + curl -fLSs -o CONFIGPROGRESS-agg-old.json $RELEASE_URL/CONFIGPROGRESS-agg.json || echo "" >CONFIGPROGRESS-agg-old.json + curl -fLSs -o ISLEPROGRESS-agg-old.json $RELEASE_URL/ISLEPROGRESS-agg.json || echo "" >ISLEPROGRESS-agg-old.json + curl -fLSs -o LEGO1PROGRESS-agg-old.json $RELEASE_URL/LEGO1PROGRESS-agg.json || echo "" >LEGO1PROGRESS-agg-old.json + + # Compare with current master + reccmp-aggregate --diff CONFIGPROGRESS-agg-old.json CONFIGPROGRESS-agg.json || echo "Current master not found" + reccmp-aggregate --diff ISLEPROGRESS-agg-old.json ISLEPROGRESS-agg.json || echo "Current master not found" + reccmp-aggregate --diff LEGO1PROGRESS-agg-old.json LEGO1PROGRESS-agg.json || echo "Current master not found" + - name: Test Exports shell: bash run: | @@ -180,9 +306,9 @@ jobs: with: name: Accuracy Report path: | - CONFIGPROGRESS.* - ISLEPROGRESS.* - LEGO1PROGRESS.* + CONFIGPROGRESS* + ISLEPROGRESS* + LEGO1PROGRESS* upload: name: Upload artifacts @@ -212,9 +338,9 @@ jobs: build/CONFIG.EXE \ build/ISLE.EXE \ build/LEGO1.DLL \ - CONFIGPROGRESS.* \ - ISLEPROGRESS.* \ - LEGO1PROGRESS.* + CONFIGPROGRESS* \ + ISLEPROGRESS* \ + LEGO1PROGRESS* curl -X POST -F key=$UPLOAD_KEY -F 'file=@CONFIGPROGRESS.SVG' https://legoisland.org/progress/ curl -X POST -F key=$UPLOAD_KEY -F 'file=@ISLEPROGRESS.SVG' https://legoisland.org/progress/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b337e0a..d66a1706 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,7 @@ option(ISLE_DECOMP_ASSERT "Assert struct size" ${MSVC_FOR_DECOMP}) cmake_dependent_option(ISLE_USE_DX5_LIBS "Build with internal DirectX 5 SDK Libraries" ON ISLE_USE_DX5 OFF) option(ISLE_BUILD_LEGO1 "Build LEGO1.DLL library" ON) option(ISLE_BUILD_BETA10 "Build BETA10.DLL library" OFF) +option(ISLE_INCLUDE_ENTROPY "Build with entropy.h" OFF) if(NOT (ISLE_BUILD_LEGO1 OR ISLE_BUILD_BETA10)) message(FATAL_ERROR "ISLE_BUILD_LEGO1 AND ISLE_BUILD_BETA10 cannot be both disabled") @@ -584,6 +585,18 @@ if (MSVC_FOR_DECOMP) set_property(TARGET isle ${lego1_targets} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") endif() + if (ISLE_INCLUDE_ENTROPY) + foreach(tgt IN LISTS lego1_targets beta10_targets) + target_compile_options(${tgt} PRIVATE /FI${PROJECT_SOURCE_DIR}/entropy.h) + endforeach() + if (TARGET isle) + target_compile_options(isle PRIVATE /FI${PROJECT_SOURCE_DIR}/entropy.h) + endif() + if (TARGET config) + target_compile_options(config PRIVATE /FI${PROJECT_SOURCE_DIR}/entropy.h) + endif() + endif() + if(TARGET lego1) target_link_options(lego1 PRIVATE "/OPT:REF") # Equivalent to target_compile_options(... PRIVATE "/MT$<$:d>") diff --git a/tools/entropy.py b/tools/entropy.py new file mode 100644 index 00000000..a98a98b8 --- /dev/null +++ b/tools/entropy.py @@ -0,0 +1,45 @@ +import random +import string +import sys + +# Parameters for tweaking: +MAX_CLASSES = 10 +MAX_FUNC_PER_CLASS = 10 + +# Only the unique suffix, not counting "Class" or "Function" +CLASS_NAME_LEN = 6 +FUNC_NAME_LEN = 8 + + +def random_camel_case(length: int) -> str: + """Return a random string with first letter capitalized.""" + return "".join( + [ + random.choice(string.ascii_uppercase), + *random.choices(string.ascii_lowercase, k=length - 1), + ] + ) + + +# If the first parameter is an integer, use it as the seed. +try: + seed = int(sys.argv[1]) +except (IndexError, ValueError): + seed = random.randint(0, 10000) + +random.seed(seed) + +print(f"// Seed: {seed}\n") + +num_classes = random.randint(1, MAX_CLASSES) +for i in range(num_classes): + class_name = "Class" + random_camel_case(CLASS_NAME_LEN) + print(f"class {class_name} {{") + num_functions = random.randint(1, MAX_FUNC_PER_CLASS) + for j in range(num_functions): + function_name = "Function" + random_camel_case(FUNC_NAME_LEN) + print(f"\tinline void {function_name}() {{}}") + + print(f"}};\n") + +print() From f879cac9bae88cab0fb421f212fadd50bc83b04b Mon Sep 17 00:00:00 2001 From: MS Date: Sun, 9 Mar 2025 15:30:39 -0400 Subject: [PATCH 10/16] Write entropy report to HTML (#1404) --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7dfca4af..245009a6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -263,9 +263,9 @@ jobs: - name: Aggregate Accuracy shell: bash run: | - reccmp-aggregate --samples $(find build-entropy -type f -name "CONFIGPROGRESS.json") --output CONFIGPROGRESS-agg.json - reccmp-aggregate --samples $(find build-entropy -type f -name "ISLEPROGRESS.json") --output ISLEPROGRESS-agg.json - reccmp-aggregate --samples $(find build-entropy -type f -name "LEGO1PROGRESS.json") --output LEGO1PROGRESS-agg.json + reccmp-aggregate --samples $(find build-entropy -type f -name "CONFIGPROGRESS.json") --output CONFIGPROGRESS-agg.json --html CONFIGPROGRESS-agg.html + reccmp-aggregate --samples $(find build-entropy -type f -name "ISLEPROGRESS.json") --output ISLEPROGRESS-agg.json --html ISLEPROGRESS-agg.html + reccmp-aggregate --samples $(find build-entropy -type f -name "LEGO1PROGRESS.json") --output LEGO1PROGRESS-agg.json --html LEGO1PROGRESS-agg.html - name: Compare Aggregate Accuracy With Current Master shell: bash From fbf71990c9ca8ee89f3c09b67cd684d1f7fe179e Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sun, 9 Mar 2025 17:17:07 -0700 Subject: [PATCH 11/16] Use separate workflows for regular build and entropy builds (#1405) * Experiment with separate workflows * Fix * Fix * Fix * Fix * Fix * Add compare to verify * Add space * Update * Test compare workflow * Test * Cancel naming * Cancel * Remove space * Fixes * fix typo --- .github/workflows/build.yml | 144 ++------------------------ .github/workflows/compare.yml | 190 ++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+), 135 deletions(-) create mode 100644 .github/workflows/compare.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 245009a6..982d9468 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,10 +2,6 @@ name: Build on: [push, pull_request] -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - jobs: fetch-deps: name: Download original binaries @@ -104,104 +100,9 @@ jobs: build/LEGO1.DLL build/LEGO1.PDB - build-with-entropy: - name: 'MSVC 4.20 with entropy' - needs: [fetch-deps] - runs-on: windows-latest - strategy: - matrix: - instance: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] - - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - uses: actions/checkout@v4 - with: - repository: itsmattkc/msvc420 - path: msvc420 - - - name: Setup cmake - uses: jwlawson/actions-setup-cmake@v2 - with: - # Use minimum supported version - cmake-version: '3.15.x' - - - name: Patch MSVC 4.2 - run: | - tools/patch_c2.py msvc420/bin/C2.EXE - - - name: Generate Entropy - shell: bash - run: | - # Get the first 8 characters of the SHA (enough for a decent seed) - SHA_PREFIX=$(echo "${{ github.sha }}" | cut -c 1-8) - ENTROPY_SEED=$((16#$SHA_PREFIX + ${{ matrix.instance }})) - - echo "Using seed: $ENTROPY_SEED" - python3 tools/entropy.py $ENTROPY_SEED > entropy.h - - - name: Build - shell: cmd - run: | - call .\msvc420\bin\VCVARS32.BAT x86 - cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DISLE_INCLUDE_ENTROPY=ON -G "NMake Makefiles" - cmake --build build - - - name: Restore cached original binaries - id: cache-original-binaries - uses: actions/cache/restore@v4 - with: - enableCrossOsArchive: true - path: legobin - key: legobin - - - name: Install python packages - shell: bash - run: | - pip install -r tools/requirements.txt - - - name: Detect binaries - run: | - reccmp-project detect --what original --search-path legobin - reccmp-project detect --what recompiled --search-path build - - - name: Summarize Accuracy - shell: bash - run: | - reccmp-reccmp --target CONFIG --json CONFIGPROGRESS.json - reccmp-reccmp --target ISLE --json ISLEPROGRESS.json - reccmp-reccmp --target LEGO1 --json LEGO1PROGRESS.json - - - name: Upload Artifact - uses: actions/upload-artifact@main - with: - name: Win32-Entropy-${{ matrix.instance }} - path: | - CONFIGPROGRESS.json - ISLEPROGRESS.json - LEGO1PROGRESS.json - - merge-entropy-artifacts: - name: 'Merge entropy artifacts' - runs-on: ubuntu-latest - needs: build-with-entropy - steps: - - name: Merge Artifacts - uses: actions/upload-artifact/merge@v4 - with: - name: Win32-Entropy - pattern: Win32-Entropy-* - separate-directories: true - - compare: - name: Compare with master - needs: [build, merge-entropy-artifacts, fetch-deps] + verify: + name: Verify decomp + needs: [build, fetch-deps] runs-on: windows-latest steps: - uses: actions/checkout@main @@ -212,13 +113,8 @@ jobs: - uses: actions/download-artifact@main with: - name: Win32 - path: build - - - uses: actions/download-artifact@main - with: - name: Win32-Entropy - path: build-entropy + name: Win32 + path: build - name: Restore cached original binaries id: cache-original-binaries @@ -260,28 +156,6 @@ jobs: reccmp-reccmp --target ISLE --diff ISLEPROGRESS-old.json || echo "Current master not found" reccmp-reccmp --target LEGO1 --diff LEGO1PROGRESS-old.json || echo "Current master not found" - - name: Aggregate Accuracy - shell: bash - run: | - reccmp-aggregate --samples $(find build-entropy -type f -name "CONFIGPROGRESS.json") --output CONFIGPROGRESS-agg.json --html CONFIGPROGRESS-agg.html - reccmp-aggregate --samples $(find build-entropy -type f -name "ISLEPROGRESS.json") --output ISLEPROGRESS-agg.json --html ISLEPROGRESS-agg.html - reccmp-aggregate --samples $(find build-entropy -type f -name "LEGO1PROGRESS.json") --output LEGO1PROGRESS-agg.json --html LEGO1PROGRESS-agg.html - - - name: Compare Aggregate Accuracy With Current Master - shell: bash - env: - RELEASE_URL: https://github.com/isledecomp/isle/releases/download/continuous - run: | - # Download the current master state - curl -fLSs -o CONFIGPROGRESS-agg-old.json $RELEASE_URL/CONFIGPROGRESS-agg.json || echo "" >CONFIGPROGRESS-agg-old.json - curl -fLSs -o ISLEPROGRESS-agg-old.json $RELEASE_URL/ISLEPROGRESS-agg.json || echo "" >ISLEPROGRESS-agg-old.json - curl -fLSs -o LEGO1PROGRESS-agg-old.json $RELEASE_URL/LEGO1PROGRESS-agg.json || echo "" >LEGO1PROGRESS-agg-old.json - - # Compare with current master - reccmp-aggregate --diff CONFIGPROGRESS-agg-old.json CONFIGPROGRESS-agg.json || echo "Current master not found" - reccmp-aggregate --diff ISLEPROGRESS-agg-old.json ISLEPROGRESS-agg.json || echo "Current master not found" - reccmp-aggregate --diff LEGO1PROGRESS-agg-old.json LEGO1PROGRESS-agg.json || echo "Current master not found" - - name: Test Exports shell: bash run: | @@ -297,9 +171,9 @@ jobs: - name: Check Variables shell: bash run: | - reccmp-datacmp --target CONFIG - reccmp-datacmp --target ISLE - reccmp-datacmp --target LEGO1 + reccmp-datacmp --target CONFIG + reccmp-datacmp --target ISLE + reccmp-datacmp --target LEGO1 - name: Upload Artifact uses: actions/upload-artifact@main @@ -312,7 +186,7 @@ jobs: upload: name: Upload artifacts - needs: [build, compare] + needs: [verify] runs-on: ubuntu-latest if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'isledecomp/isle' }} steps: diff --git a/.github/workflows/compare.yml b/.github/workflows/compare.yml new file mode 100644 index 00000000..615fd9fe --- /dev/null +++ b/.github/workflows/compare.yml @@ -0,0 +1,190 @@ +name: Compare + +on: + push: + branches: + - master + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + fetch-deps: + name: Download original binaries + uses: ./.github/workflows/legobin.yml + + build: + name: 'MSVC 4.20' + needs: [fetch-deps] + runs-on: windows-latest + strategy: + matrix: + high: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + low: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - uses: actions/checkout@v4 + with: + repository: itsmattkc/msvc420 + path: msvc420 + + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v2 + with: + # Use minimum supported version + cmake-version: '3.15.x' + + - name: Patch MSVC 4.2 + run: | + tools/patch_c2.py msvc420/bin/C2.EXE + + - name: Generate Entropy + shell: bash + run: | + # Calculate instance number based on matrix inputs + INSTANCE=$((${{ matrix.high }} << 4 | ${{ matrix.low }})) + + # Get the first 8 characters of the SHA (enough for a decent seed) + SHA_PREFIX=$(echo "${{ github.sha }}" | cut -c 1-8) + ENTROPY_SEED=$((16#$SHA_PREFIX + $INSTANCE)) + + echo "Using seed: $ENTROPY_SEED (instance $INSTANCE)" + python3 tools/entropy.py $ENTROPY_SEED > entropy.h + + - name: Build + shell: cmd + run: | + call .\msvc420\bin\VCVARS32.BAT x86 + cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DISLE_INCLUDE_ENTROPY=ON -G "NMake Makefiles" + cmake --build build + + - name: Restore cached original binaries + id: cache-original-binaries + uses: actions/cache/restore@v4 + with: + enableCrossOsArchive: true + path: legobin + key: legobin + + - name: Install python packages + shell: bash + run: | + pip install -r tools/requirements.txt + + - name: Detect binaries + run: | + reccmp-project detect --what original --search-path legobin + reccmp-project detect --what recompiled --search-path build + + - name: Summarize Accuracy + shell: bash + run: | + reccmp-reccmp --target CONFIG --json CONFIGPROGRESS.json + reccmp-reccmp --target ISLE --json ISLEPROGRESS.json + reccmp-reccmp --target LEGO1 --json LEGO1PROGRESS.json + + - name: Upload Artifact + uses: actions/upload-artifact@main + with: + name: Win32-Entropy-${{ matrix.high }}-${{ matrix.low }} + path: | + CONFIGPROGRESS.json + ISLEPROGRESS.json + LEGO1PROGRESS.json + + merge-artifacts: + name: 'Merge entropy artifacts' + runs-on: ubuntu-latest + needs: build + steps: + - name: Merge Artifacts + uses: actions/upload-artifact/merge@v4 + with: + name: Win32-Entropy + pattern: Win32-Entropy-* + separate-directories: true + + compare: + name: Compare with master + needs: [merge-artifacts] + runs-on: windows-latest + steps: + - uses: actions/checkout@main + + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - uses: actions/download-artifact@main + with: + name: Win32-Entropy + path: build-entropy + + - name: Install python packages + shell: bash + run: | + pip install -r tools/requirements.txt + + - name: Aggregate Accuracy + shell: bash + run: | + reccmp-aggregate --samples $(find build-entropy -type f -name "CONFIGPROGRESS.json") --output CONFIGPROGRESS-agg.json --html CONFIGPROGRESS-agg.html + reccmp-aggregate --samples $(find build-entropy -type f -name "ISLEPROGRESS.json") --output ISLEPROGRESS-agg.json --html ISLEPROGRESS-agg.html + reccmp-aggregate --samples $(find build-entropy -type f -name "LEGO1PROGRESS.json") --output LEGO1PROGRESS-agg.json --html LEGO1PROGRESS-agg.html + + - name: Compare Aggregate Accuracy With Current Master + shell: bash + env: + RELEASE_URL: https://github.com/isledecomp/isle/releases/download/continuous-accuracy + run: | + # Download the current master state + curl -fLSs -o CONFIGPROGRESS-agg-old.json $RELEASE_URL/CONFIGPROGRESS-agg.json || echo "" >CONFIGPROGRESS-agg-old.json + curl -fLSs -o ISLEPROGRESS-agg-old.json $RELEASE_URL/ISLEPROGRESS-agg.json || echo "" >ISLEPROGRESS-agg-old.json + curl -fLSs -o LEGO1PROGRESS-agg-old.json $RELEASE_URL/LEGO1PROGRESS-agg.json || echo "" >LEGO1PROGRESS-agg-old.json + + # Compare with current master + reccmp-aggregate --diff CONFIGPROGRESS-agg-old.json CONFIGPROGRESS-agg.json || echo "Current master not found" + reccmp-aggregate --diff ISLEPROGRESS-agg-old.json ISLEPROGRESS-agg.json || echo "Current master not found" + reccmp-aggregate --diff LEGO1PROGRESS-agg-old.json LEGO1PROGRESS-agg.json || echo "Current master not found" + + - name: Upload Artifact + uses: actions/upload-artifact@main + with: + name: Accuracy Report + path: | + CONFIGPROGRESS* + ISLEPROGRESS* + LEGO1PROGRESS* + + upload: + name: Upload artifacts + needs: [compare] + runs-on: ubuntu-latest + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'isledecomp/isle' }} + steps: + - uses: actions/checkout@v4 + with: + repository: probonopd/uploadtool + + - uses: actions/download-artifact@main + with: + name: Accuracy Report + + - name: Upload Continuous Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + UPLOAD_KEY: ${{ secrets.UPLOAD_KEY }} + run: | + export UPLOADTOOL_SUFFIX=accuracy + ./upload.sh \ + CONFIGPROGRESS* \ + ISLEPROGRESS* \ + LEGO1PROGRESS* From d663e26321ed98927292a2855571c439e4bafe7e Mon Sep 17 00:00:00 2001 From: MS Date: Tue, 11 Mar 2025 21:13:13 -0400 Subject: [PATCH 12/16] Use MxGeometry header (#1399) * Use MxGeometry header * Fix comment --------- Co-authored-by: Christian Semmler --- LEGO1/lego/legoomni/include/infocenter.h | 4 +- .../legoomni/include/legocameracontroller.h | 2 +- .../legoomni/include/legometerpresenter.h | 20 +- .../include/legopointofviewcontroller.h | 2 +- LEGO1/lego/legoomni/include/legorace.h | 2 +- LEGO1/lego/legoomni/src/worlds/infocenter.cpp | 35 +- LEGO1/lego/sources/misc/legoutil.h | 5 + LEGO1/omni/include/mxgeometry.h | 604 ++++++++++++++++++ LEGO1/omni/include/mxpoint32.h | 36 -- LEGO1/omni/include/mxpresenter.h | 2 +- LEGO1/omni/include/mxrect16.h | 47 -- LEGO1/omni/include/mxrect32.h | 127 ---- LEGO1/omni/include/mxrectlist.h | 161 ----- LEGO1/omni/include/mxregion.h | 2 +- LEGO1/omni/include/mxsize32.h | 25 - LEGO1/omni/include/mxsmk.h | 4 +- LEGO1/omni/include/mxutilities.h | 6 + LEGO1/omni/include/mxvideoparam.h | 2 +- LEGO1/omni/include/mxvideopresenter.h | 2 +- LEGO1/omni/src/common/mxutilities.cpp | 19 +- LEGO1/omni/src/video/mxflcpresenter.cpp | 2 +- LEGO1/omni/src/video/mxregion.cpp | 16 +- LEGO1/omni/src/video/mxsmk.cpp | 2 +- LEGO1/omni/src/video/mxsmkpresenter.cpp | 6 +- LEGO1/omni/src/video/mxstillpresenter.cpp | 15 +- LEGO1/omni/src/video/mxvideomanager.cpp | 3 +- LEGO1/omni/src/video/mxvideopresenter.cpp | 2 +- 27 files changed, 674 insertions(+), 479 deletions(-) create mode 100644 LEGO1/omni/include/mxgeometry.h delete mode 100644 LEGO1/omni/include/mxpoint32.h delete mode 100644 LEGO1/omni/include/mxrect16.h delete mode 100644 LEGO1/omni/include/mxrect32.h delete mode 100644 LEGO1/omni/include/mxrectlist.h delete mode 100644 LEGO1/omni/include/mxsize32.h diff --git a/LEGO1/lego/legoomni/include/infocenter.h b/LEGO1/lego/legoomni/include/infocenter.h index 03c55254..24d14aa8 100644 --- a/LEGO1/lego/legoomni/include/infocenter.h +++ b/LEGO1/lego/legoomni/include/infocenter.h @@ -6,7 +6,7 @@ #include "legostate.h" #include "legoworld.h" #include "misc.h" -#include "mxrect32.h" +#include "mxgeometry.h" #include "radio.h" class MxNotificationParam; @@ -82,7 +82,7 @@ struct InfocenterMapEntry { MxStillPresenter* m_destCtl; // 0x00 undefined4 m_unk0x04; // 0x04 - MxRect32 m_area; // 0x08 + MxRect m_area; // 0x08 }; // VTABLE: LEGO1 0x100d9338 diff --git a/LEGO1/lego/legoomni/include/legocameracontroller.h b/LEGO1/lego/legoomni/include/legocameracontroller.h index 96934e4f..4dcb6c39 100644 --- a/LEGO1/lego/legoomni/include/legocameracontroller.h +++ b/LEGO1/lego/legoomni/include/legocameracontroller.h @@ -2,9 +2,9 @@ #define LEGOCAMERACONTROLLER_H #include "legopointofviewcontroller.h" +#include "mxgeometry.h" #include "mxgeometry/mxgeometry3d.h" #include "mxgeometry/mxmatrix.h" -#include "mxpoint32.h" // VTABLE: LEGO1 0x100d57b0 // VTABLE: BETA10 0x101bb748 diff --git a/LEGO1/lego/legoomni/include/legometerpresenter.h b/LEGO1/lego/legoomni/include/legometerpresenter.h index 9a8b7acd..efcf5db9 100644 --- a/LEGO1/lego/legoomni/include/legometerpresenter.h +++ b/LEGO1/lego/legoomni/include/legometerpresenter.h @@ -1,16 +1,10 @@ #ifndef LEGOMETERPRESENTER_H #define LEGOMETERPRESENTER_H -#include "mxrect16.h" +#include "mxgeometry.h" #include "mxstillpresenter.h" #include "mxstring.h" -// SIZE 0x08 -struct MeterRect : public MxRect16 { - // FUNCTION: BETA10 0x10097eb0 - MeterRect() {} -}; - // VTABLE: LEGO1 0x100d7ac8 // VTABLE: BETA10 0x101bca68 // SIZE 0x94 @@ -35,12 +29,12 @@ class LegoMeterPresenter : public MxStillPresenter { void DrawMeter(); - MxU8* m_meterPixels; // 0x6c - MxU16 m_fillColor; // 0x70 - MxString m_variable; // 0x74 - MxFloat m_curPercent; // 0x84 - MeterRect m_meterRect; // 0x88 - MxS16 m_layout; // 0x90 + MxU8* m_meterPixels; // 0x6c + MxU16 m_fillColor; // 0x70 + MxString m_variable; // 0x74 + MxFloat m_curPercent; // 0x84 + MxRect16 m_meterRect; // 0x88 + MxS16 m_layout; // 0x90 }; // SYNTHETIC: LEGO1 0x10043760 diff --git a/LEGO1/lego/legoomni/include/legopointofviewcontroller.h b/LEGO1/lego/legoomni/include/legopointofviewcontroller.h index ee6ac32c..9d1253aa 100644 --- a/LEGO1/lego/legoomni/include/legopointofviewcontroller.h +++ b/LEGO1/lego/legoomni/include/legopointofviewcontroller.h @@ -3,7 +3,7 @@ #include "decomp.h" #include "mxcore.h" -#include "mxpoint32.h" +#include "mxgeometry.h" #include diff --git a/LEGO1/lego/legoomni/include/legorace.h b/LEGO1/lego/legoomni/include/legorace.h index 344136f3..55d43785 100644 --- a/LEGO1/lego/legoomni/include/legorace.h +++ b/LEGO1/lego/legoomni/include/legorace.h @@ -7,7 +7,7 @@ #include "legoracemap.h" #include "legostate.h" #include "legoworld.h" -#include "mxrect32.h" +#include "mxgeometry.h" #include "mxtypes.h" class Act1State; diff --git a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp index 657536b0..5cc9138c 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp @@ -630,58 +630,37 @@ void Infocenter::InitializeBitmaps() m_glowInfo[0].m_destCtl = (MxStillPresenter*) Find("MxStillPresenter", "Info_A_Bitmap"); assert(m_glowInfo[0].m_destCtl); - m_glowInfo[0].m_area.SetLeft(391); - m_glowInfo[0].m_area.SetTop(182); - m_glowInfo[0].m_area.SetRight(427); - m_glowInfo[0].m_area.SetBottom(230); + m_glowInfo[0].m_area = MxRect(391, 182, 427, 230); m_glowInfo[0].m_unk0x04 = 3; m_glowInfo[1].m_destCtl = (MxStillPresenter*) Find("MxStillPresenter", "Boat_A_Bitmap"); assert(m_glowInfo[1].m_destCtl); - m_glowInfo[1].m_area.SetLeft(304); - m_glowInfo[1].m_area.SetTop(225); - m_glowInfo[1].m_area.SetRight(350); - m_glowInfo[1].m_area.SetBottom(268); + m_glowInfo[1].m_area = MxRect(304, 225, 350, 268); m_glowInfo[1].m_unk0x04 = 10; m_glowInfo[2].m_destCtl = (MxStillPresenter*) Find("MxStillPresenter", "Race_A_Bitmap"); assert(m_glowInfo[1].m_destCtl); // DECOMP: intentional typo - m_glowInfo[2].m_area.SetLeft(301); - m_glowInfo[2].m_area.SetTop(133); - m_glowInfo[2].m_area.SetRight(347); - m_glowInfo[2].m_area.SetBottom(181); + m_glowInfo[2].m_area = MxRect(301, 133, 347, 181); m_glowInfo[2].m_unk0x04 = 11; m_glowInfo[3].m_destCtl = (MxStillPresenter*) Find("MxStillPresenter", "Pizza_A_Bitmap"); assert(m_glowInfo[3].m_destCtl); - m_glowInfo[3].m_area.SetLeft(289); - m_glowInfo[3].m_area.SetTop(182); - m_glowInfo[3].m_area.SetRight(335); - m_glowInfo[3].m_area.SetBottom(225); + m_glowInfo[3].m_area = MxRect(289, 182, 335, 225); m_glowInfo[3].m_unk0x04 = 12; m_glowInfo[4].m_destCtl = (MxStillPresenter*) Find("MxStillPresenter", "Gas_A_Bitmap"); assert(m_glowInfo[4].m_destCtl); - m_glowInfo[4].m_area.SetLeft(350); - m_glowInfo[4].m_area.SetTop(161); - m_glowInfo[4].m_area.SetRight(391); - m_glowInfo[4].m_area.SetBottom(209); + m_glowInfo[4].m_area = MxRect(350, 161, 391, 209); m_glowInfo[4].m_unk0x04 = 13; m_glowInfo[5].m_destCtl = (MxStillPresenter*) Find("MxStillPresenter", "Med_A_Bitmap"); assert(m_glowInfo[5].m_destCtl); - m_glowInfo[5].m_area.SetLeft(392); - m_glowInfo[5].m_area.SetTop(130); - m_glowInfo[5].m_area.SetRight(438); - m_glowInfo[5].m_area.SetBottom(176); + m_glowInfo[5].m_area = MxRect(392, 130, 438, 176); m_glowInfo[5].m_unk0x04 = 14; m_glowInfo[6].m_destCtl = (MxStillPresenter*) Find("MxStillPresenter", "Cop_A_Bitmap"); assert(m_glowInfo[6].m_destCtl); - m_glowInfo[6].m_area.SetLeft(396); - m_glowInfo[6].m_area.SetTop(229); - m_glowInfo[6].m_area.SetRight(442); - m_glowInfo[6].m_area.SetBottom(272); + m_glowInfo[6].m_area = MxRect(396, 229, 442, 272); m_glowInfo[6].m_unk0x04 = 15; m_frame = (MxStillPresenter*) Find("MxStillPresenter", "FrameHot_Bitmap"); diff --git a/LEGO1/lego/sources/misc/legoutil.h b/LEGO1/lego/sources/misc/legoutil.h index fc42d462..871a9b72 100644 --- a/LEGO1/lego/sources/misc/legoutil.h +++ b/LEGO1/lego/sources/misc/legoutil.h @@ -1,6 +1,9 @@ #ifndef __LEGOUTIL_H #define __LEGOUTIL_H +// Exclude from modern compilers due to clash with mxutilities.h +#ifndef COMPAT_MODE + template inline T Min(T p_t1, T p_t2) { @@ -31,6 +34,8 @@ inline T Abs(T p_t) return p_t < 0 ? -p_t : p_t; } +#endif + template inline void Swap(T& p_t1, T& p_t2) { diff --git a/LEGO1/omni/include/mxgeometry.h b/LEGO1/omni/include/mxgeometry.h new file mode 100644 index 00000000..073b5471 --- /dev/null +++ b/LEGO1/omni/include/mxgeometry.h @@ -0,0 +1,604 @@ +#ifndef MXGEOMETRY_H +#define MXGEOMETRY_H + +#include "mxlist.h" +#include "mxutilities.h" + +template +class MxPoint { +protected: + T m_x; + T m_y; + +public: + MxPoint() {} + MxPoint(const MxPoint& p_p) + { + m_x = p_p.m_x; + m_y = p_p.m_y; + } + MxPoint(T p_x, T p_y) + { + m_x = p_x; + m_y = p_y; + } + T GetX() const { return m_x; } + T GetY() const { return m_y; } + void SetX(T p_x) { m_x = p_x; } + void SetY(T p_y) { m_y = p_y; } + void operator+=(const MxPoint& p_p) + { + m_x += p_p.m_x; + m_y += p_p.m_y; + } + void operator-=(const MxPoint& p_p) + { + m_x -= p_p.m_x; + m_y -= p_p.m_y; + } + MxPoint operator+(const MxPoint& p_p) const { return MxPoint(m_x + p_p.m_x, m_y + p_p.m_y); } + MxPoint operator-(const MxPoint& p_p) const { return MxPoint(m_x - p_p.m_x, m_y - p_p.m_y); } +}; + +template +class MxSize { +protected: + T m_width; + T m_height; + +public: + MxSize() {} + MxSize(const MxSize& p_s) + { + m_width = p_s.m_width; + m_height = p_s.m_height; + } + MxSize(T p_width, T p_height) + { + m_width = p_width; + m_height = p_height; + } + T GetWidth() const { return m_width; } + T GetHeight() const { return m_height; } + void SetWidth(T p_width) { m_width = p_width; } + void SetHeight(T p_height) { m_height = p_height; } +}; + +template +class MxRect { +protected: + T m_left; + T m_top; + T m_right; + T m_bottom; + +public: + MxRect() {} + MxRect(const MxRect& p_r) + { + m_left = p_r.m_left; + m_top = p_r.m_top; + m_right = p_r.m_right; + m_bottom = p_r.m_bottom; + } + MxRect(T p_l, T p_t, T p_r, T p_b) + { + m_left = p_l; + m_top = p_t; + m_right = p_r; + m_bottom = p_b; + } + MxRect(const MxPoint& p_p, const MxSize& p_s) + { + m_left = p_p.GetX(); + m_top = p_p.GetY(); + m_right = p_p.GetX() + p_s.GetWidth() - 1; + m_bottom = p_p.GetY() + p_s.GetHeight() - 1; + } + T GetLeft() const { return m_left; } + void SetLeft(T p_left) { m_left = p_left; } + T GetTop() const { return m_top; } + void SetTop(T p_top) { m_top = p_top; } + T GetRight() const { return m_right; } + void SetRight(T p_right) { m_right = p_right; } + T GetBottom() const { return m_bottom; } + void SetBottom(T p_bottom) { m_bottom = p_bottom; } + T GetWidth() const { return (m_right - m_left + 1); } + T GetHeight() const { return (m_bottom - m_top + 1); } + MxPoint GetLT() const { return MxPoint(m_left, m_top); } + MxPoint GetRB() const { return MxPoint(m_right, m_bottom); } + MxBool Empty() const { return m_left >= m_right || m_top >= m_bottom; } + MxBool Contains(const MxPoint& p_p) const + { + return p_p.GetX() >= m_left && p_p.GetX() <= m_right && p_p.GetY() >= m_top && p_p.GetY() <= m_bottom; + } + MxBool Intersects(const MxRect& p_r) const + { + return p_r.m_right > m_left && p_r.m_left < m_right && p_r.m_bottom > m_top && p_r.m_top < m_bottom; + } + void operator=(const MxRect& p_r) + { + m_left = p_r.m_left; + m_top = p_r.m_top; + m_right = p_r.m_right; + m_bottom = p_r.m_bottom; + } + MxBool operator==(const MxRect& p_r) const + { + return m_left == p_r.m_left && m_top == p_r.m_top && m_right == p_r.m_right && m_bottom == p_r.m_bottom; + } + MxBool operator!=(const MxRect& p_r) const { return !operator==(p_r); } + void operator+=(const MxPoint& p_p) + { + m_left += p_p.GetX(); + m_top += p_p.GetY(); + m_right += p_p.GetX(); + m_bottom += p_p.GetY(); + } + void operator-=(const MxPoint& p_p) + { + m_left -= p_p.GetX(); + m_top -= p_p.GetY(); + m_right -= p_p.GetX(); + m_bottom -= p_p.GetY(); + } + void operator&=(const MxRect& p_r) + { + m_left = Max(p_r.m_left, m_left); + m_top = Max(p_r.m_top, m_top); + m_right = Min(p_r.m_right, m_right); + m_bottom = Min(p_r.m_bottom, m_bottom); + } + void operator|=(const MxRect& p_r) + { + m_left = Min(p_r.m_left, m_left); + m_top = Min(p_r.m_top, m_top); + m_right = Max(p_r.m_right, m_right); + m_bottom = Max(p_r.m_bottom, m_bottom); + } + MxRect operator+(const MxPoint& p_p) const + { + return MxRect(m_left + p_p.GetX(), m_top + p_p.GetY(), m_left + p_p.GetX(), m_bottom + p_p.GetY()); + } + MxRect operator-(const MxPoint& p_p) const + { + return MxRect(m_left - p_p.GetX(), m_top - p_p.GetY(), m_left - p_p.GetX(), m_bottom - p_p.GetY()); + } + MxRect operator&(const MxRect& p_r) const + { + return MxRect( + Max(p_r.m_left, m_left), + Max(p_r.m_top, m_top), + Min(p_r.m_right, m_right), + Min(p_r.m_bottom, m_bottom) + ); + } + MxRect operator|(const MxRect& p_r) const + { + return MxRect( + Min(p_r.m_left, m_left), + Min(p_r.m_top, m_top), + Max(p_r.m_right, m_right), + Max(p_r.m_bottom, m_bottom) + ); + } +}; + +/******************************* MxPoint16 **********************************/ + +// SIZE 0x04 +class MxPoint16 : public MxPoint { +public: + MxPoint16() {} + MxPoint16(const MxPoint16& p_p) : MxPoint(p_p) {} + MxPoint16(MxS16 p_x, MxS16 p_y) : MxPoint(p_x, p_y) {} +}; + +class MxPoint16List : public MxPtrList { +public: + MxPoint16List(MxBool p_ownership) : MxPtrList(p_ownership) {} +}; + +class MxPoint16ListCursor : public MxPtrListCursor { +public: + MxPoint16ListCursor(MxPoint16List* p_list) : MxPtrListCursor(p_list) {} +}; + +/******************************* MxPoint32 **********************************/ + +// SIZE 0x08 +class MxPoint32 : public MxPoint { +public: + // FUNCTION: BETA10 0x10054d10 + MxPoint32() {} + + // FUNCTION: BETA10 0x10031a50 + MxPoint32(const MxPoint32& p_p) : MxPoint(p_p) {} + + // FUNCTION: LEGO1 0x10012170 + // FUNCTION: BETA10 0x1006aa70 + MxPoint32(MxS32 p_x, MxS32 p_y) : MxPoint(p_x, p_y) {} +}; + +class MxPoint32List : public MxPtrList { +public: + MxPoint32List(MxBool p_ownership) : MxPtrList(p_ownership) {} +}; + +class MxPoint32ListCursor : public MxPtrListCursor { +public: + MxPoint32ListCursor(MxPoint32List* p_list) : MxPtrListCursor(p_list) {} +}; + +// TEMPLATE: BETA10 0x10031a80 +// ??0?$MxPoint@H@@QAE@ABV0@@Z + +// TEMPLATE: BETA10 0x100318f0 +// MxPoint::GetX + +// TEMPLATE: BETA10 0x10031920 +// MxPoint::GetY + +// TEMPLATE: BETA10 0x10031cf0 +// ??0?$MxPoint@H@@QAE@HH@Z + +// TEMPLATE: BETA10 0x10054d40 +// ??0?$MxPoint@H@@QAE@XZ + +// TEMPLATE: BETA10 0x10142c90 +// MxPoint::SetX + +// TEMPLATE: BETA10 0x10142cb0 +// MxPoint::SetY + +/******************************** MxSize16 **********************************/ + +// SIZE 0x04 +class MxSize16 : public MxSize { +public: + MxSize16() {} + MxSize16(const MxSize16& p_s) : MxSize(p_s) {} + MxSize16(MxS16 p_width, MxS16 p_height) : MxSize(p_width, p_height) {} +}; + +class MxSize16List : public MxPtrList { +public: + MxSize16List(MxBool p_ownership) : MxPtrList(p_ownership) {} +}; + +class MxSize16ListCursor : public MxPtrListCursor { +public: + MxSize16ListCursor(MxSize16List* p_list) : MxPtrListCursor(p_list) {} +}; + +/******************************** MxSize32 **********************************/ + +// SIZE 0x08 +class MxSize32 : public MxSize { +public: + MxSize32() {} + MxSize32(const MxSize32& p_s) : MxSize(p_s) {} + + // FUNCTION: BETA10 0x10137030 + MxSize32(MxS32 p_width, MxS32 p_height) : MxSize(p_width, p_height) {} +}; + +class MxSize32List : public MxPtrList { +public: + MxSize32List(MxBool p_ownership) : MxPtrList(p_ownership) {} +}; + +class MxSize32ListCursor : public MxPtrListCursor { +public: + MxSize32ListCursor(MxSize32List* p_list) : MxPtrListCursor(p_list) {} +}; + +// TEMPLATE: BETA10 0x10031820 +// ??0?$MxSize@H@@QAE@HH@Z + +// TEMPLATE: BETA10 0x10031950 +// MxSize::GetWidth + +// TEMPLATE: BETA10 0x10031980 +// MxSize::GetHeight + +/******************************** MxRect16 **********************************/ + +// SIZE 0x08 +class MxRect16 : public MxRect { +public: + // FUNCTION: BETA10 0x10097eb0 + MxRect16() {} + MxRect16(const MxRect16& p_r) : MxRect(p_r) {} + MxRect16(MxS16 p_l, MxS16 p_t, MxS16 p_r, MxS16 p_b) : MxRect(p_l, p_t, p_r, p_b) {} + MxRect16(MxPoint16& p_p, MxSize16& p_s) : MxRect(p_p, p_s) {} +}; + +class MxRect16List : public MxPtrList { +public: + MxRect16List(MxBool p_ownership) : MxPtrList(p_ownership) {} +}; + +class MxRect16ListCursor : public MxPtrListCursor { +public: + MxRect16ListCursor(MxRect16List* p_list) : MxPtrListCursor(p_list) {} +}; + +// TEMPLATE: BETA10 0x10097ee0 +// ??0?$MxRect@F@@QAE@XZ + +// TEMPLATE: BETA10 0x100981f0 +// MxRect::SetLeft + +// TEMPLATE: BETA10 0x10098220 +// MxRect::SetTop + +// TEMPLATE: BETA10 0x10098250 +// MxRect::SetRight + +// TEMPLATE: BETA10 0x10098280 +// MxRect::SetBottom + +// TEMPLATE: BETA10 0x10098300 +// MxRect::GetLeft + +// TEMPLATE: BETA10 0x10098330 +// MxRect::GetTop + +// TEMPLATE: BETA10 0x10098360 +// MxRect::GetBottom + +// TEMPLATE: BETA10 0x10098390 +// MxRect::GetWidth + +// TEMPLATE: BETA10 0x100983c0 +// MxRect::GetHeight + +/******************************** MxRect32 **********************************/ + +// SIZE 0x10 +class MxRect32 : public MxRect { +public: + // FUNCTION: BETA10 0x1012df70 + MxRect32() {} + + // FUNCTION: BETA10 0x1012de40 + MxRect32(const MxRect32& p_r) : MxRect(p_r) {} + + // FUNCTION: BETA10 0x100d8e90 + MxRect32(MxS32 p_l, MxS32 p_t, MxS32 p_r, MxS32 p_b) : MxRect(p_l, p_t, p_r, p_b) {} + +#ifndef COMPAT_MODE + // FUNCTION: LEGO1 0x100b6fc0 + // FUNCTION: BETA10 0x10137060 + MxRect32(MxPoint32& p_p, MxSize32& p_s) : MxRect(p_p, p_s) {} +#else + MxRect32(const MxPoint32& p_p, const MxSize32& p_s) : MxRect(p_p, p_s) {} +#endif +}; + +// VTABLE: LEGO1 0x100dc3f0 +// VTABLE: BETA10 0x101c1fb8 +// SIZE 0x18 +class MxRect32List : public MxPtrList { +public: + // FUNCTION: BETA10 0x1013b980 + MxRect32List(MxBool p_ownership) : MxPtrList(p_ownership) {} +}; + +// VTABLE: LEGO1 0x100dc438 +// VTABLE: BETA10 0x101c2048 +// class MxListCursor + +// VTABLE: LEGO1 0x100dc408 +// VTABLE: BETA10 0x101c2030 +// class MxPtrListCursor + +// VTABLE: LEGO1 0x100dc420 +// VTABLE: BETA10 0x101c2018 +// SIZE 0x10 +class MxRect32ListCursor : public MxPtrListCursor { +public: + // FUNCTION: BETA10 0x1013bf10 + MxRect32ListCursor(MxRect32List* p_list) : MxPtrListCursor(p_list) {} +}; + +// TEMPLATE: BETA10 0x10031800 +// ??0?$MxRect@H@@QAE@XZ + +// TEMPLATE: BETA10 0x10031860 +// ??0?$MxRect@H@@QAE@ABV?$MxPoint@H@@ABV?$MxSize@H@@@Z + +// TEMPLATE: BETA10 0x100319b0 +// MxRect::operator= + +// TEMPLATE: BETA10 0x100d8090 +// MxRect::GetWidth + +// TEMPLATE: BETA10 0x100d80c0 +// MxRect::GetHeight + +// TEMPLATE: BETA10 0x100d8ed0 +// ??0?$MxRect@H@@QAE@HHHH@Z + +// TEMPLATE: BETA10 0x100ec100 +// MxRect::GetLeft + +// TEMPLATE: BETA10 0x100ec130 +// MxRect::GetTop + +// TEMPLATE: BETA10 0x100ec160 +// MxRect::GetRight + +// TEMPLATE: BETA10 0x100ec190 +// MxRect::GetBottom + +// TEMPLATE: BETA10 0x100ec1c0 +// MxRect::operator+= + +// TEMPLATE: BETA10 0x1012de70 +// ??0?$MxRect@H@@QAE@ABV0@@Z + +// TEMPLATE: BETA10 0x1012dec0 +// MxRect::operator&= + +// SYNTHETIC: BETA10 0x1012dfa0 +// MxRect32::operator= + +// TEMPLATE: BETA10 0x10031d30 +// MxRect::Contains + +// TEMPLATE: BETA10 0x10137090 +// MxRect::Intersects + +// TEMPLATE: BETA10 0x10137100 +// MxRect::operator-= + +// TEMPLATE: BETA10 0x1014b320 +// MxRect::operator|= + +// TEMPLATE: BETA10 0x1014b2d0 +// MxRect::Empty + +// TEMPLATE: BETA10 0x1014bd80 +// MxRect::SetLeft + +// TEMPLATE: BETA10 0x1014b270 +// MxRect::SetTop + +// TEMPLATE: BETA10 0x1014bda0 +// MxRect::SetRight + +// TEMPLATE: BETA10 0x1014b2a0 +// MxRect::SetBottom + +// VTABLE: LEGO1 0x100dc3d8 +// VTABLE: BETA10 0x101c1fd0 +// class MxPtrList + +// VTABLE: LEGO1 0x100dc450 +// VTABLE: BETA10 0x101c1fe8 +// class MxList + +// VTABLE: LEGO1 0x100dc468 +// VTABLE: BETA10 0x101c2000 +// class MxCollection + +// TEMPLATE: LEGO1 0x100b3c00 +// TEMPLATE: BETA10 0x1013ba00 +// MxCollection::Compare + +// TEMPLATE: LEGO1 0x100b3c10 +// TEMPLATE: BETA10 0x1013bb30 +// MxCollection::MxCollection + +// TEMPLATE: LEGO1 0x100b3c80 +// TEMPLATE: BETA10 0x1013bbc0 +// MxCollection::~MxCollection + +// TEMPLATE: LEGO1 0x100b3cd0 +// TEMPLATE: BETA10 0x1013bc60 +// MxCollection::Destroy + +// TEMPLATE: LEGO1 0x100b3ce0 +// TEMPLATE: BETA10 0x1013bc70 +// MxList::~MxList + +// TEMPLATE: LEGO1 0x100b3d70 +// TEMPLATE: BETA10 0x1013bd20 +// MxPtrList::Destroy + +// SYNTHETIC: LEGO1 0x100b3d80 +// SYNTHETIC: BETA10 0x1013bd50 +// MxRect32List::`scalar deleting destructor' + +// TEMPLATE: LEGO1 0x100b3df0 +// TEMPLATE: BETA10 0x1013bd90 +// MxPtrList::~MxPtrList + +// SYNTHETIC: LEGO1 0x100b3e40 +// SYNTHETIC: BETA10 0x1013bdf0 +// MxCollection::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x100b3eb0 +// SYNTHETIC: BETA10 0x1013be30 +// MxList::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x100b3f60 +// SYNTHETIC: BETA10 0x1013be70 +// MxPtrList::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x100b3fd0 +// SYNTHETIC: BETA10 0x1013beb0 +// MxRect32List::~MxRect32List + +// SYNTHETIC: LEGO1 0x100b4020 +// SYNTHETIC: BETA10 0x1013c0a0 +// MxRect32ListCursor::`scalar deleting destructor' + +// TEMPLATE: LEGO1 0x100b4090 +// TEMPLATE: BETA10 0x1013c0e0 +// MxPtrListCursor::~MxPtrListCursor + +// SYNTHETIC: LEGO1 0x100b40e0 +// SYNTHETIC: BETA10 0x1013c140 +// MxListCursor::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x100b4150 +// SYNTHETIC: BETA10 0x1013c180 +// MxPtrListCursor::`scalar deleting destructor' + +// TEMPLATE: LEGO1 0x100b41c0 +// TEMPLATE: BETA10 0x1013c1c0 +// MxListCursor::~MxListCursor + +// SYNTHETIC: LEGO1 0x100b4210 +// SYNTHETIC: BETA10 0x1013c220 +// MxRect32ListCursor::~MxRect32ListCursor + +// TEMPLATE: BETA10 0x1013ba20 +// MxPtrList::MxPtrList + +// TEMPLATE: BETA10 0x1013baa0 +// MxList::MxList + +// TEMPLATE: BETA10 0x1013bc30 +// MxCollection::SetDestroy + +// TEMPLATE: BETA10 0x1013bce0 +// MxPtrList::SetOwnership + +// TEMPLATE: BETA10 0x1013bf90 +// MxPtrListCursor::MxPtrListCursor + +// TEMPLATE: BETA10 0x1013c010 +// MxListCursor::MxListCursor + +// TEMPLATE: BETA10 0x1013c3c0 +// MxList::DeleteAll + +// TEMPLATE: BETA10 0x1013c450 +// MxListCursor::Next + +// TEMPLATE: BETA10 0x1013c610 +// MxListEntry::GetNext + +// TEMPLATE: BETA10 0x1013c630 +// MxListEntry::GetValue + +// TEMPLATE: BETA10 0x10152860 +// MxList::Append + +// TEMPLATE: BETA10 0x10152890 +// MxList::InsertEntry + +// TEMPLATE: BETA10 0x10152980 +// MxListEntry::MxListEntry + +// TEMPLATE: BETA10 0x101529c0 +// MxListEntry::SetPrev + +// TEMPLATE: BETA10 0x101529f0 +// MxListEntry::SetNext + +#endif // MXGEOMETRY_H diff --git a/LEGO1/omni/include/mxpoint32.h b/LEGO1/omni/include/mxpoint32.h deleted file mode 100644 index b3ee2267..00000000 --- a/LEGO1/omni/include/mxpoint32.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef MXPOINT32_H -#define MXPOINT32_H - -#include "mxtypes.h" - -class MxPoint32 { -public: - MxPoint32() {} - - // FUNCTION: LEGO1 0x10012170 - MxPoint32(MxS32 p_x, MxS32 p_y) { CopyFrom(p_x, p_y); } - - MxPoint32(const MxPoint32& p_point) - { - this->m_x = p_point.m_x; - this->m_y = p_point.m_y; - } - - MxS32 GetX() const { return m_x; } - MxS32 GetY() const { return m_y; } - - void SetX(MxS32 p_x) { m_x = p_x; } - void SetY(MxS32 p_y) { m_y = p_y; } - -private: - void CopyFrom(MxS32 p_x, MxS32 p_y) - { - this->m_x = p_x; - this->m_y = p_y; - } - - MxS32 m_x; // 0x00 - MxS32 m_y; // 0x04 -}; - -#endif // MXPOINT32_H diff --git a/LEGO1/omni/include/mxpresenter.h b/LEGO1/omni/include/mxpresenter.h index 3151704e..e257f3c4 100644 --- a/LEGO1/omni/include/mxpresenter.h +++ b/LEGO1/omni/include/mxpresenter.h @@ -4,7 +4,7 @@ #include "decomp.h" #include "mxcore.h" #include "mxcriticalsection.h" -#include "mxpoint32.h" +#include "mxgeometry.h" class MxCompositePresenter; class MxDSAction; diff --git a/LEGO1/omni/include/mxrect16.h b/LEGO1/omni/include/mxrect16.h deleted file mode 100644 index 43e46548..00000000 --- a/LEGO1/omni/include/mxrect16.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef MXRECT16_H -#define MXRECT16_H - -#include "mxtypes.h" - -// SIZE 0x08 -struct MxRect16 { - // FUNCTION: BETA10 0x10097ee0 - MxRect16() {} - - // FUNCTION: BETA10 0x100981f0 - void SetLeft(MxS16 p_left) { m_left = p_left; } - - // FUNCTION: BETA10 0x10098220 - void SetTop(MxS16 p_top) { m_top = p_top; } - - // FUNCTION: BETA10 0x10098250 - void SetRight(MxS16 p_right) { m_right = p_right; } - - // FUNCTION: BETA10 0x10098280 - void SetBottom(MxS16 p_bottom) { m_bottom = p_bottom; } - - // FUNCTION: BETA10 0x10098300 - MxS16 GetLeft() const { return m_left; } - - // FUNCTION: BETA10 0x10098330 - MxS16 GetTop() const { return m_top; } - - // There is no GetRight() - - // FUNCTION: BETA10 0x10098360 - MxS16 GetBottom() const { return m_bottom; } - - // FUNCTION: BETA10 0x10098390 - MxS16 GetWidth() const { return m_right - m_left + 1; } - - // FUNCTION: BETA10 0x100983c0 - MxS16 GetHeight() const { return m_bottom - m_top + 1; } - -private: - MxS16 m_left; // 0x00 - MxS16 m_top; // 0x02 - MxS16 m_right; // 0x04 - MxS16 m_bottom; // 0x06 -}; - -#endif // MXRECT16_H diff --git a/LEGO1/omni/include/mxrect32.h b/LEGO1/omni/include/mxrect32.h deleted file mode 100644 index 1461cbb9..00000000 --- a/LEGO1/omni/include/mxrect32.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef MXRECT32_H -#define MXRECT32_H - -#include "mxpoint32.h" -#include "mxsize32.h" - -// SIZE 0x10 -class MxRect32 { -public: - MxRect32() {} - MxRect32(MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom) { CopyFrom(p_left, p_top, p_right, p_bottom); } - MxRect32(const MxPoint32& p_point, const MxSize32& p_size) { CopyFrom(p_point, p_size); } - MxRect32(const MxRect32& p_a, const MxRect32& p_b) - { - m_left = Max(p_a.m_left, p_b.m_left); - m_top = Max(p_a.m_top, p_b.m_top); - m_right = Min(p_a.m_right, p_b.m_right); - m_bottom = Min(p_a.m_bottom, p_b.m_bottom); - } - - MxRect32(const MxRect32& p_rect) { CopyFrom(p_rect); } - - MxRect32& operator=(const MxRect32& p_rect) - { - CopyFrom(p_rect); - return *this; - } - - void Intersect(const MxRect32& p_rect) - { - m_left = Max(p_rect.m_left, m_left); - m_top = Max(p_rect.m_top, m_top); - m_right = Min(p_rect.m_right, m_right); - m_bottom = Min(p_rect.m_bottom, m_bottom); - } - - void SetPoint(const MxPoint32& p_point) - { - this->m_left = p_point.GetX(); - this->m_top = p_point.GetY(); - } - - void AddPoint(const MxPoint32& p_point) - { - this->m_left += p_point.GetX(); - this->m_top += p_point.GetY(); - this->m_right += p_point.GetX(); - this->m_bottom += p_point.GetY(); - } - - void SubtractPoint(const MxPoint32& p_point) - { - this->m_left -= p_point.GetX(); - this->m_top -= p_point.GetY(); - this->m_right -= p_point.GetX(); - this->m_bottom -= p_point.GetY(); - } - - void UpdateBounds(const MxRect32& p_rect) - { - m_left = Min(m_left, p_rect.m_left); - m_top = Min(m_top, p_rect.m_top); - m_right = Max(m_right, p_rect.m_right); - m_bottom = Max(m_bottom, p_rect.m_bottom); - } - - MxBool IsValid() const { return m_left < m_right && m_top < m_bottom; } - - MxBool IntersectsWith(const MxRect32& p_rect) const - { - return m_left < p_rect.m_right && p_rect.m_left < m_right && m_top < p_rect.m_bottom && p_rect.m_top < m_bottom; - } - - MxS32 GetWidth() const { return (m_right - m_left) + 1; } - MxS32 GetHeight() const { return (m_bottom - m_top) + 1; } - - MxPoint32 GetPoint() const { return MxPoint32(this->m_left, this->m_top); } - MxSize32 GetSize() const { return MxSize32(this->m_right, this->m_bottom); } - - MxS32 GetLeft() const { return m_left; } - MxS32 GetTop() const { return m_top; } - MxS32 GetRight() const { return m_right; } - MxS32 GetBottom() const { return m_bottom; } - - void SetLeft(MxS32 p_left) { m_left = p_left; } - void SetTop(MxS32 p_top) { m_top = p_top; } - void SetRight(MxS32 p_right) { m_right = p_right; } - void SetBottom(MxS32 p_bottom) { m_bottom = p_bottom; } - -private: - void CopyFrom(MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom) - { - this->m_left = p_left; - this->m_top = p_top; - this->m_right = p_right; - this->m_bottom = p_bottom; - } - - void CopyFrom(const MxRect32& p_rect) - { - this->m_left = p_rect.m_left; - this->m_top = p_rect.m_top; - this->m_right = p_rect.m_right; - this->m_bottom = p_rect.m_bottom; - } - - // The address might also be the constructor that calls CopyFrom - // FUNCTION: LEGO1 0x100b6fc0 - MxRect32* CopyFrom(const MxPoint32& p_point, const MxSize32& p_size) - { - this->m_left = p_point.GetX(); - this->m_top = p_point.GetY(); - this->m_right = p_size.GetWidth() + p_point.GetX() - 1; - this->m_bottom = p_size.GetHeight() + p_point.GetY() - 1; - return this; - } - - static MxS32 Min(MxS32 p_a, MxS32 p_b) { return p_a <= p_b ? p_a : p_b; } - static MxS32 Max(MxS32 p_a, MxS32 p_b) { return p_a <= p_b ? p_b : p_a; } - - MxS32 m_left; // 0x00 - MxS32 m_top; // 0x04 - MxS32 m_right; // 0x08 - MxS32 m_bottom; // 0x0c -}; - -#endif // MXRECT32_H diff --git a/LEGO1/omni/include/mxrectlist.h b/LEGO1/omni/include/mxrectlist.h deleted file mode 100644 index c4be8dcd..00000000 --- a/LEGO1/omni/include/mxrectlist.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef MXRECTLIST_H -#define MXRECTLIST_H - -#include "mxlist.h" -#include "mxrect32.h" - -// VTABLE: LEGO1 0x100dc3f0 -// VTABLE: BETA10 0x101c1fb8 -// SIZE 0x18 -class MxRectList : public MxPtrList { -public: - // FUNCTION: BETA10 0x1013b980 - MxRectList(MxBool p_ownership = FALSE) : MxPtrList(p_ownership) {} -}; - -// VTABLE: LEGO1 0x100dc438 -// VTABLE: BETA10 0x101c2048 -// class MxListCursor - -// VTABLE: LEGO1 0x100dc408 -// VTABLE: BETA10 0x101c2030 -// class MxPtrListCursor - -// VTABLE: LEGO1 0x100dc420 -// VTABLE: BETA10 0x101c2018 -class MxRectListCursor : public MxPtrListCursor { -public: - // FUNCTION: BETA10 0x1013bf10 - MxRectListCursor(MxRectList* p_list) : MxPtrListCursor(p_list) {} -}; - -// VTABLE: LEGO1 0x100dc3d8 -// VTABLE: BETA10 0x101c1fd0 -// class MxPtrList - -// VTABLE: LEGO1 0x100dc450 -// VTABLE: BETA10 0x101c1fe8 -// class MxList - -// VTABLE: LEGO1 0x100dc468 -// VTABLE: BETA10 0x101c2000 -// class MxCollection - -// TEMPLATE: LEGO1 0x100b3c00 -// TEMPLATE: BETA10 0x1013ba00 -// MxCollection::Compare - -// TEMPLATE: LEGO1 0x100b3c10 -// TEMPLATE: BETA10 0x1013bb30 -// MxCollection::MxCollection - -// TEMPLATE: LEGO1 0x100b3c80 -// TEMPLATE: BETA10 0x1013bbc0 -// MxCollection::~MxCollection - -// TEMPLATE: LEGO1 0x100b3cd0 -// TEMPLATE: BETA10 0x1013bc60 -// MxCollection::Destroy - -// TEMPLATE: LEGO1 0x100b3ce0 -// TEMPLATE: BETA10 0x1013bc70 -// MxList::~MxList - -// TEMPLATE: LEGO1 0x100b3d70 -// TEMPLATE: BETA10 0x1013bd20 -// MxPtrList::Destroy - -// SYNTHETIC: LEGO1 0x100b3d80 -// SYNTHETIC: BETA10 0x1013bd50 -// MxRectList::`scalar deleting destructor' - -// TEMPLATE: LEGO1 0x100b3df0 -// TEMPLATE: BETA10 0x1013bd90 -// MxPtrList::~MxPtrList - -// SYNTHETIC: LEGO1 0x100b3e40 -// SYNTHETIC: BETA10 0x1013bdf0 -// MxCollection::`scalar deleting destructor' - -// SYNTHETIC: LEGO1 0x100b3eb0 -// SYNTHETIC: BETA10 0x1013be30 -// MxList::`scalar deleting destructor' - -// SYNTHETIC: LEGO1 0x100b3f60 -// SYNTHETIC: BETA10 0x1013be70 -// MxPtrList::`scalar deleting destructor' - -// SYNTHETIC: LEGO1 0x100b3fd0 -// SYNTHETIC: BETA10 0x1013beb0 -// MxRectList::~MxRectList - -// SYNTHETIC: LEGO1 0x100b4020 -// SYNTHETIC: BETA10 0x1013c0a0 -// MxRectListCursor::`scalar deleting destructor' - -// TEMPLATE: LEGO1 0x100b4090 -// TEMPLATE: BETA10 0x1013c0e0 -// MxPtrListCursor::~MxPtrListCursor - -// SYNTHETIC: LEGO1 0x100b40e0 -// SYNTHETIC: BETA10 0x1013c140 -// MxListCursor::`scalar deleting destructor' - -// SYNTHETIC: LEGO1 0x100b4150 -// SYNTHETIC: BETA10 0x1013c180 -// MxPtrListCursor::`scalar deleting destructor' - -// TEMPLATE: LEGO1 0x100b41c0 -// TEMPLATE: BETA10 0x1013c1c0 -// MxListCursor::~MxListCursor - -// SYNTHETIC: LEGO1 0x100b4210 -// SYNTHETIC: BETA10 0x1013c220 -// MxRectListCursor::~MxRectListCursor - -// TEMPLATE: BETA10 0x1013ba20 -// MxPtrList::MxPtrList - -// TEMPLATE: BETA10 0x1013baa0 -// MxList::MxList - -// TEMPLATE: BETA10 0x1013bc30 -// MxCollection::SetDestroy - -// TEMPLATE: BETA10 0x1013bce0 -// MxPtrList::SetOwnership - -// TEMPLATE: BETA10 0x1013bf90 -// MxPtrListCursor::MxPtrListCursor - -// TEMPLATE: BETA10 0x1013c010 -// MxListCursor::MxListCursor - -// TEMPLATE: BETA10 0x1013c3c0 -// MxList::DeleteAll - -// TEMPLATE: BETA10 0x1013c450 -// MxListCursor::Next - -// TEMPLATE: BETA10 0x1013c610 -// MxListEntry::GetNext - -// TEMPLATE: BETA10 0x1013c630 -// MxListEntry::GetValue - -// TEMPLATE: BETA10 0x10152860 -// MxList::Append - -// TEMPLATE: BETA10 0x10152890 -// MxList::InsertEntry - -// TEMPLATE: BETA10 0x10152980 -// MxListEntry::MxListEntry - -// TEMPLATE: BETA10 0x101529c0 -// MxListEntry::SetPrev - -// TEMPLATE: BETA10 0x101529f0 -// MxListEntry::SetNext - -#endif // MXRECTLIST_H diff --git a/LEGO1/omni/include/mxregion.h b/LEGO1/omni/include/mxregion.h index c5f8e31e..997b658e 100644 --- a/LEGO1/omni/include/mxregion.h +++ b/LEGO1/omni/include/mxregion.h @@ -3,8 +3,8 @@ #include "decomp.h" #include "mxcore.h" +#include "mxgeometry.h" #include "mxlist.h" -#include "mxrect32.h" // should be mxgeometry.h // SIZE 0x08 class MxSegment { diff --git a/LEGO1/omni/include/mxsize32.h b/LEGO1/omni/include/mxsize32.h deleted file mode 100644 index 28ac7fcc..00000000 --- a/LEGO1/omni/include/mxsize32.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef MXSIZE32_H -#define MXSIZE32_H - -#include "mxtypes.h" - -class MxSize32 { -public: - MxSize32() {} - MxSize32(MxS32 p_width, MxS32 p_height) { CopyFrom(p_width, p_height); } - - MxS32 GetWidth() const { return m_width; } - MxS32 GetHeight() const { return m_height; } - -private: - void CopyFrom(MxS32 p_width, MxS32 p_height) - { - this->m_width = p_width; - this->m_height = p_height; - } - - MxS32 m_width; - MxS32 m_height; -}; - -#endif // MXSIZE32_H diff --git a/LEGO1/omni/include/mxsmk.h b/LEGO1/omni/include/mxsmk.h index ec611f97..d587149f 100644 --- a/LEGO1/omni/include/mxsmk.h +++ b/LEGO1/omni/include/mxsmk.h @@ -2,7 +2,7 @@ #define MXSMK_H #include "decomp.h" -#include "mxrectlist.h" +#include "mxgeometry.h" #include "mxtypes.h" #include @@ -46,7 +46,7 @@ struct MxSmk { MxSmk* p_mxSmk, MxU8* p_chunkData, MxBool p_paletteChanged, - MxRectList* p_list + MxRect32List* p_list ); static MxBool GetRect(MxU8* p_unk0x6b4, MxU16* p_und, u32* p_smackRect, MxRect32* p_rect); }; diff --git a/LEGO1/omni/include/mxutilities.h b/LEGO1/omni/include/mxutilities.h index c7a2bcfb..51b897b7 100644 --- a/LEGO1/omni/include/mxutilities.h +++ b/LEGO1/omni/include/mxutilities.h @@ -78,4 +78,10 @@ MxBool ContainsPresenter(MxCompositePresenterList& p_presenterList, MxPresenter* void FUN_100b7220(MxDSAction* p_action, MxU32 p_newFlags, MxBool p_setFlags); MxBool KeyValueStringParse(char*, const char*, const char*); +// TEMPLATE: BETA10 0x1012dfd0 +// ?Max@@YAHHH@Z + +// TEMPLATE: BETA10 0x1012dff0 +// ?Min@@YAHHH@Z + #endif // MXUTILITIES_H diff --git a/LEGO1/omni/include/mxvideoparam.h b/LEGO1/omni/include/mxvideoparam.h index e85ead69..c597eaf8 100644 --- a/LEGO1/omni/include/mxvideoparam.h +++ b/LEGO1/omni/include/mxvideoparam.h @@ -2,7 +2,7 @@ #define MXVIDEOPARAM_H #include "compat.h" -#include "mxrect32.h" +#include "mxgeometry.h" #include "mxtypes.h" #include "mxvideoparamflags.h" diff --git a/LEGO1/omni/include/mxvideopresenter.h b/LEGO1/omni/include/mxvideopresenter.h index a1794aec..c95445b9 100644 --- a/LEGO1/omni/include/mxvideopresenter.h +++ b/LEGO1/omni/include/mxvideopresenter.h @@ -3,8 +3,8 @@ #include "decomp.h" #include "mxbitmap.h" +#include "mxgeometry.h" #include "mxmediapresenter.h" -#include "mxrect32.h" #include diff --git a/LEGO1/omni/src/common/mxutilities.cpp b/LEGO1/omni/src/common/mxutilities.cpp index c1a102f5..7845d88f 100644 --- a/LEGO1/omni/src/common/mxutilities.cpp +++ b/LEGO1/omni/src/common/mxutilities.cpp @@ -6,8 +6,8 @@ #include "mxdsfile.h" #include "mxdsmultiaction.h" #include "mxdsobject.h" +#include "mxgeometry.h" #include "mxpresenterlist.h" -#include "mxrect32.h" #include @@ -15,6 +15,7 @@ void (*g_omniUserMessage)(const char*, MxS32) = NULL; // FUNCTION: LEGO1 0x100b6e10 +// FUNCTION: BETA10 0x10136970 MxBool GetRectIntersection( MxS32 p_rect1Width, MxS32 p_rect1Height, @@ -35,22 +36,22 @@ MxBool GetRectIntersection( MxRect32 rect2(MxPoint32(0, 0), MxSize32(p_rect2Width, p_rect2Height)); MxRect32 rect(0, 0, *p_width, *p_height); - rect.AddPoint(rect1Origin); + rect += rect1Origin; - if (!rect.IntersectsWith(rect1)) { + if (!rect.Intersects(rect1)) { return FALSE; } - rect.Intersect(rect1); - rect.SubtractPoint(rect1Origin); - rect.AddPoint(rect2Origin); + rect &= rect1; + rect -= rect1Origin; + rect += rect2Origin; - if (!rect.IntersectsWith(rect2)) { + if (!rect.Intersects(rect2)) { return FALSE; } - rect.Intersect(rect2); - rect.SubtractPoint(rect2Origin); + rect &= rect2; + rect -= rect2Origin; *p_rect1Left += rect.GetLeft(); *p_rect1Top += rect.GetTop(); diff --git a/LEGO1/omni/src/video/mxflcpresenter.cpp b/LEGO1/omni/src/video/mxflcpresenter.cpp index e618ea9e..57b734c1 100644 --- a/LEGO1/omni/src/video/mxflcpresenter.cpp +++ b/LEGO1/omni/src/video/mxflcpresenter.cpp @@ -70,7 +70,7 @@ void MxFlcPresenter::LoadFrame(MxStreamChunk* p_chunk) for (MxS32 i = 0; i < rectCount; i++) { MxRect32 rect(rects[i]); - rect.AddPoint(m_location); + rect += m_location; MVideoManager()->InvalidateRect(rect); } } diff --git a/LEGO1/omni/src/video/mxregion.cpp b/LEGO1/omni/src/video/mxregion.cpp index e2841f23..9b63ff7c 100644 --- a/LEGO1/omni/src/video/mxregion.cpp +++ b/LEGO1/omni/src/video/mxregion.cpp @@ -39,7 +39,7 @@ void MxRegion::AddRect(MxRect32& p_rect) MxSpanListCursor cursor(m_spanList); MxSpan* span; - while (rect.IsValid() && cursor.Next(span)) { + while (!rect.Empty() && cursor.Next(span)) { if (span->GetMin() >= rect.GetBottom()) { MxSpan* newSpan = new MxSpan(rect); cursor.Prepend(newSpan); @@ -75,19 +75,19 @@ void MxRegion::AddRect(MxRect32& p_rect) } } - if (rect.IsValid()) { + if (!rect.Empty()) { MxSpan* newSpan = new MxSpan(rect); m_spanList->Append(newSpan); } - m_boundingRect.UpdateBounds(p_rect); + m_boundingRect |= p_rect; } // FUNCTION: LEGO1 0x100c3e20 // FUNCTION: BETA10 0x10149535 MxBool MxRegion::Intersects(MxRect32& p_rect) { - if (!m_boundingRect.IntersectsWith(p_rect)) { + if (!m_boundingRect.Intersects(p_rect)) { return FALSE; } @@ -253,7 +253,7 @@ MxRect32* MxRegionCursor::Next(MxRect32& p_rect) if (span->IntersectsV(p_rect) && segment->IntersectsH(p_rect)) { SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); - m_rect->Intersect(p_rect); + *m_rect &= p_rect; } else { NextSpan(p_rect); @@ -278,7 +278,7 @@ MxRect32* MxRegionCursor::Prev(MxRect32& p_rect) if (span->IntersectsV(p_rect) && segment->IntersectsH(p_rect)) { SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); - m_rect->Intersect(p_rect); + *m_rect &= p_rect; } else { PrevSpan(p_rect); @@ -351,7 +351,7 @@ void MxRegionCursor::NextSpan(MxRect32& p_rect) if (p_rect.GetLeft() < segment->GetMax()) { SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); - m_rect->Intersect(p_rect); + *m_rect &= p_rect; return; } } @@ -382,7 +382,7 @@ void MxRegionCursor::PrevSpan(MxRect32& p_rect) if (segment->GetMin() < p_rect.GetRight()) { SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax()); - m_rect->Intersect(p_rect); + *m_rect &= p_rect; return; } } diff --git a/LEGO1/omni/src/video/mxsmk.cpp b/LEGO1/omni/src/video/mxsmk.cpp index 0f2bdd77..b0affc4b 100644 --- a/LEGO1/omni/src/video/mxsmk.cpp +++ b/LEGO1/omni/src/video/mxsmk.cpp @@ -165,7 +165,7 @@ MxResult MxSmk::LoadFrame( MxSmk* p_mxSmk, MxU8* p_chunkData, MxBool p_paletteChanged, - MxRectList* p_list + MxRect32List* p_list ) { p_bitmapInfo->m_bmiHeader.biHeight = -MxBitmap::HeightAbs(p_bitmapInfo->m_bmiHeader.biHeight); diff --git a/LEGO1/omni/src/video/mxsmkpresenter.cpp b/LEGO1/omni/src/video/mxsmkpresenter.cpp index 5bbddbe9..aa21f6ee 100644 --- a/LEGO1/omni/src/video/mxsmkpresenter.cpp +++ b/LEGO1/omni/src/video/mxsmkpresenter.cpp @@ -72,7 +72,7 @@ void MxSmkPresenter::LoadFrame(MxStreamChunk* p_chunk) m_currentFrame++; VTable0x88(); - MxRectList rects(TRUE); + MxRect32List rects(TRUE); MxSmk::LoadFrame(bitmapInfo, bitmapData, &m_mxSmk, chunkData, paletteChanged, &rects); if (((MxDSMediaAction*) m_action)->GetPaletteManagement() && paletteChanged) { @@ -80,12 +80,12 @@ void MxSmkPresenter::LoadFrame(MxStreamChunk* p_chunk) } MxRect32 invalidateRect; - MxRectListCursor cursor(&rects); + MxRect32ListCursor cursor(&rects); MxRect32* rect; while (cursor.Next(rect)) { invalidateRect = *rect; - invalidateRect.AddPoint(GetLocation()); + invalidateRect += GetLocation(); MVideoManager()->InvalidateRect(invalidateRect); } } diff --git a/LEGO1/omni/src/video/mxstillpresenter.cpp b/LEGO1/omni/src/video/mxstillpresenter.cpp index 7074ae26..03ffcb31 100644 --- a/LEGO1/omni/src/video/mxstillpresenter.cpp +++ b/LEGO1/omni/src/video/mxstillpresenter.cpp @@ -148,20 +148,21 @@ void MxStillPresenter::RepeatingTickle() } // FUNCTION: LEGO1 0x100ba040 +// FUNCTION: BETA10 0x10142724 void MxStillPresenter::SetPosition(MxS32 p_x, MxS32 p_y) { - MxS32 x = m_location.GetX(); - MxS32 y = m_location.GetY(); + MxPoint32 oldLocation(m_location); m_location.SetX(p_x); m_location.SetY(p_y); if (IsEnabled()) { - // Most likely needs to work with MxSize32 and MxPoint32 - MxS32 height = GetHeight() - 1; - MxS32 width = GetWidth() - 1; + MxRect32 area(0, 0, GetWidth() - 1, GetHeight() - 1); - MxRect32 rectA(x, y, width + x, height + y); - MxRect32 rectB(m_location.GetX(), m_location.GetY(), width + m_location.GetX(), height + m_location.GetY()); + MxRect32 rectA(area); + rectA += oldLocation; + + MxRect32 rectB(area); + rectB += m_location; MVideoManager()->InvalidateRect(rectA); MVideoManager()->UpdateView(rectA.GetLeft(), rectA.GetTop(), rectA.GetWidth(), rectA.GetHeight()); diff --git a/LEGO1/omni/src/video/mxvideomanager.cpp b/LEGO1/omni/src/video/mxvideomanager.cpp index 4a6072a0..cde2e1ca 100644 --- a/LEGO1/omni/src/video/mxvideomanager.cpp +++ b/LEGO1/omni/src/video/mxvideomanager.cpp @@ -84,11 +84,12 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor) } // FUNCTION: LEGO1 0x100be3e0 +// FUNCTION: BETA10 0x1012cdaa void MxVideoManager::UpdateRegion() { if (m_region->IsEmpty() == FALSE) { MxRect32 rect(m_region->GetBoundingRect()); - rect.Intersect(m_videoParam.GetRect()); + rect &= m_videoParam.GetRect(); m_displaySurface ->Display(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight()); diff --git a/LEGO1/omni/src/video/mxvideopresenter.cpp b/LEGO1/omni/src/video/mxvideopresenter.cpp index a045ae95..7e7c9822 100644 --- a/LEGO1/omni/src/video/mxvideopresenter.cpp +++ b/LEGO1/omni/src/video/mxvideopresenter.cpp @@ -301,7 +301,7 @@ void MxVideoPresenter::PutFrame() MxDisplaySurface* displaySurface = MVideoManager()->GetDisplaySurface(); MxRegion* region = MVideoManager()->GetRegion(); MxRect32 rect(MxPoint32(0, 0), MxSize32(GetWidth(), GetHeight())); - rect.AddPoint(GetLocation()); + rect += GetLocation(); LPDIRECTDRAWSURFACE ddSurface = displaySurface->GetDirectDrawSurface2(); if (m_action->GetFlags() & MxDSAction::c_bit5) { From 3d9c7a8956973198cf0b9b0ccf71467050d85f4e Mon Sep 17 00:00:00 2001 From: MS Date: Fri, 14 Mar 2025 15:05:55 -0400 Subject: [PATCH 13/16] Improve performance of entropy build action (#1407) * Use multiple threads for entropy builds * Verify builds parameter * Revert "Verify builds parameter" This reverts commit 460d3d3b55ead59b1100452e460f6a7bae0e8457. * Use options instead * Seed fix * 256 samples on push --- .github/workflows/compare.yml | 130 ++++++++++++++++++++++------------ CMakeLists.txt | 8 ++- tools/multi-analyze.ps1 | 62 ++++++++++++++++ tools/multi-build.ps1 | 56 +++++++++++++++ tools/multi-prepare.ps1 | 81 +++++++++++++++++++++ 5 files changed, 287 insertions(+), 50 deletions(-) create mode 100644 tools/multi-analyze.ps1 create mode 100644 tools/multi-build.ps1 create mode 100644 tools/multi-prepare.ps1 diff --git a/.github/workflows/compare.yml b/.github/workflows/compare.yml index 615fd9fe..b4819b72 100644 --- a/.github/workflows/compare.yml +++ b/.github/workflows/compare.yml @@ -5,6 +5,13 @@ on: branches: - master workflow_dispatch: + inputs: + builds_per_job: + description: 'How many builds to run in parallel on each job.' + default: 4 + required: true + type: choice + options: [1, 2, 4, 8, 16, 32, 64] concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -15,14 +22,40 @@ jobs: name: Download original binaries uses: ./.github/workflows/legobin.yml + reccmp: + name: Setup python environment + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + + # The typical cache key would include a hash on requirements.txt. + # We currently run reccmp from latest so we would have to manually purge it. + # The goal is simply to restore the cache across entropy build jobs. + - name: Cache venv + uses: actions/cache@v4 + with: + key: venv-entropy-${{ github.run_id }} + path: .venv + + - name: Install python packages + run: | + python -m venv .venv + .venv\Scripts\Activate + pip install -r tools/requirements.txt + build: name: 'MSVC 4.20' - needs: [fetch-deps] + needs: [fetch-deps, reccmp] runs-on: windows-latest strategy: matrix: - high: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] - low: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + job: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + builds: + - ${{ inputs.builds_per_job && inputs.builds_per_job || 16 }} steps: - uses: actions/checkout@v4 @@ -46,26 +79,6 @@ jobs: run: | tools/patch_c2.py msvc420/bin/C2.EXE - - name: Generate Entropy - shell: bash - run: | - # Calculate instance number based on matrix inputs - INSTANCE=$((${{ matrix.high }} << 4 | ${{ matrix.low }})) - - # Get the first 8 characters of the SHA (enough for a decent seed) - SHA_PREFIX=$(echo "${{ github.sha }}" | cut -c 1-8) - ENTROPY_SEED=$((16#$SHA_PREFIX + $INSTANCE)) - - echo "Using seed: $ENTROPY_SEED (instance $INSTANCE)" - python3 tools/entropy.py $ENTROPY_SEED > entropy.h - - - name: Build - shell: cmd - run: | - call .\msvc420\bin\VCVARS32.BAT x86 - cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DISLE_INCLUDE_ENTROPY=ON -G "NMake Makefiles" - cmake --build build - - name: Restore cached original binaries id: cache-original-binaries uses: actions/cache/restore@v4 @@ -73,32 +86,47 @@ jobs: enableCrossOsArchive: true path: legobin key: legobin - - - name: Install python packages - shell: bash - run: | - pip install -r tools/requirements.txt - - - name: Detect binaries - run: | - reccmp-project detect --what original --search-path legobin - reccmp-project detect --what recompiled --search-path build - - name: Summarize Accuracy - shell: bash + - name: Install python packages run: | - reccmp-reccmp --target CONFIG --json CONFIGPROGRESS.json - reccmp-reccmp --target ISLE --json ISLEPROGRESS.json - reccmp-reccmp --target LEGO1 --json LEGO1PROGRESS.json + python -m venv .venv + .venv\Scripts\Activate + echo ($env:VIRTUAL_ENV + "\Scripts") >> $env:GITHUB_PATH + echo ("VIRTUAL_ENV=" + $env:VIRTUAL_ENV) >> $env:GITHUB_ENV + + - name: Restore cached virtualenv + uses: actions/cache@v4 + with: + key: venv-entropy-${{ github.run_id }} + path: .venv + + - name: Prepare builds + shell: pwsh + run: | + cmd /c "call `".\msvc420\bin\VCVARS32.BAT`" x86 && set > %temp%\vcvars32.txt" + Get-Content "$env:temp\vcvars32.txt" | Foreach-Object { if ($_ -match "^(.*?)=(.*)$") { Set-Content "env:\$($matches[1])" $matches[2] } } + .\tools\multi-prepare.ps1 ${{ matrix.job }} ${{ matrix.builds }} + + - name: Run builds + shell: pwsh + run: | + cmd /c "call `".\msvc420\bin\VCVARS32.BAT`" x86 && set > %temp%\vcvars32.txt" + Get-Content "$env:temp\vcvars32.txt" | Foreach-Object { if ($_ -match "^(.*?)=(.*)$") { Set-Content "env:\$($matches[1])" $matches[2] } } + .\tools\multi-build.ps1 ${{ matrix.builds }} + + - name: Analyze builds + shell: pwsh + run: | + .\tools\multi-analyze.ps1 ${{ matrix.builds }} - name: Upload Artifact uses: actions/upload-artifact@main with: - name: Win32-Entropy-${{ matrix.high }}-${{ matrix.low }} + name: Win32-Entropy-${{ matrix.job }} path: | - CONFIGPROGRESS.json - ISLEPROGRESS.json - LEGO1PROGRESS.json + CONFIGPROGRESS* + ISLEPROGRESS* + LEGO1PROGRESS* merge-artifacts: name: 'Merge entropy artifacts' @@ -129,16 +157,24 @@ jobs: path: build-entropy - name: Install python packages - shell: bash run: | - pip install -r tools/requirements.txt + python -m venv .venv + .venv\Scripts\Activate + echo ($env:VIRTUAL_ENV + "\Scripts") >> $env:GITHUB_PATH + echo ("VIRTUAL_ENV=" + $env:VIRTUAL_ENV) >> $env:GITHUB_ENV + + - name: Restore cached virtualenv + uses: actions/cache@v4 + with: + key: venv-entropy-${{ github.run_id }} + path: .venv - name: Aggregate Accuracy shell: bash run: | - reccmp-aggregate --samples $(find build-entropy -type f -name "CONFIGPROGRESS.json") --output CONFIGPROGRESS-agg.json --html CONFIGPROGRESS-agg.html - reccmp-aggregate --samples $(find build-entropy -type f -name "ISLEPROGRESS.json") --output ISLEPROGRESS-agg.json --html ISLEPROGRESS-agg.html - reccmp-aggregate --samples $(find build-entropy -type f -name "LEGO1PROGRESS.json") --output LEGO1PROGRESS-agg.json --html LEGO1PROGRESS-agg.html + reccmp-aggregate --samples $(find build-entropy -type f -name "CONFIGPROGRESS*.json") --output CONFIGPROGRESS-agg.json --html CONFIGPROGRESS-agg.html + reccmp-aggregate --samples $(find build-entropy -type f -name "ISLEPROGRESS*.json") --output ISLEPROGRESS-agg.json --html ISLEPROGRESS-agg.html + reccmp-aggregate --samples $(find build-entropy -type f -name "LEGO1PROGRESS*.json") --output LEGO1PROGRESS-agg.json --html LEGO1PROGRESS-agg.html - name: Compare Aggregate Accuracy With Current Master shell: bash diff --git a/CMakeLists.txt b/CMakeLists.txt index d66a1706..63ce08c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ cmake_dependent_option(ISLE_USE_DX5_LIBS "Build with internal DirectX 5 SDK Libr option(ISLE_BUILD_LEGO1 "Build LEGO1.DLL library" ON) option(ISLE_BUILD_BETA10 "Build BETA10.DLL library" OFF) option(ISLE_INCLUDE_ENTROPY "Build with entropy.h" OFF) +option(ISLE_ENTROPY_FILENAME "Entropy header filename" "entropy.h") if(NOT (ISLE_BUILD_LEGO1 OR ISLE_BUILD_BETA10)) message(FATAL_ERROR "ISLE_BUILD_LEGO1 AND ISLE_BUILD_BETA10 cannot be both disabled") @@ -586,14 +587,15 @@ if (MSVC_FOR_DECOMP) endif() if (ISLE_INCLUDE_ENTROPY) + message(STATUS "Using entropy file: ${ISLE_ENTROPY_FILENAME}") foreach(tgt IN LISTS lego1_targets beta10_targets) - target_compile_options(${tgt} PRIVATE /FI${PROJECT_SOURCE_DIR}/entropy.h) + target_compile_options(${tgt} PRIVATE /FI${PROJECT_SOURCE_DIR}/${ISLE_ENTROPY_FILENAME}) endforeach() if (TARGET isle) - target_compile_options(isle PRIVATE /FI${PROJECT_SOURCE_DIR}/entropy.h) + target_compile_options(isle PRIVATE /FI${PROJECT_SOURCE_DIR}/${ISLE_ENTROPY_FILENAME}) endif() if (TARGET config) - target_compile_options(config PRIVATE /FI${PROJECT_SOURCE_DIR}/entropy.h) + target_compile_options(config PRIVATE /FI${PROJECT_SOURCE_DIR}/${ISLE_ENTROPY_FILENAME}) endif() endif() diff --git a/tools/multi-analyze.ps1 b/tools/multi-analyze.ps1 new file mode 100644 index 00000000..36caf284 --- /dev/null +++ b/tools/multi-analyze.ps1 @@ -0,0 +1,62 @@ +if ($args.count -lt 1) { + Write-Error "Requires 1 arg: number of builds for this job." + exit 1 +} + +$BuildCount = [int]$args[0] +$build_ids = 0..($BuildCount-1) + +$build_dirs = foreach($i in $build_ids) { "build$i" } +$stdout_files = foreach($i in $build_ids) { "stdout$i.txt" } +$stderr_files = foreach($i in $build_ids) { "stderr$i.txt" } + +$artifacts = @( + @{prog = "CONFIGPROGRESS"; binfile = "CONFIG.EXE"; pdbfile = "CONFIG.PDB"; codedir = "."} + @{prog = "ISLEPROGRESS"; binfile = "ISLE.EXE"; pdbfile = "ISLE.PDB"; codedir = "."} + @{prog = "LEGO1PROGRESS"; binfile = "LEGO1.DLL"; pdbfile = "LEGO1.PDB"; codedir = "LEGO1"} +) + +foreach($a in $artifacts) { + $procs = New-Object System.Collections.Generic.List[System.Diagnostics.Process] + + foreach($i in $build_ids) { + $params = @{ + FilePath = "reccmp-reccmp" + PassThru = $null + ArgumentList = @( + "--paths", + $("legobin/" + $a["binfile"]), + $($build_dirs[$i] + "/" + $a["binfile"]), + $($build_dirs[$i] + "/" + $a["pdbfile"]), + $a["codedir"], + "--json", + $($a["prog"] + "$i.json"), + "--silent" + ) + } + + # For the first job, display stdout and stderr. + # Else dump to file so we don't see 50 at once. + if ($i -eq 0) { + $params.Add("NoNewWindow", $null) + } else { + $params.Add("RedirectStandardOutput", $stdout_files[$i]) + $params.Add("RedirectStandardError", $stderr_files[$i]) + } + + $procs.Add($(Start-Process @params)) + } + + $failed = $false + try { Wait-Process -InputObject $procs } catch { $failed = $true } + + foreach($i in $build_ids) { + if ($procs[$i].ExitCode -ne 0) { + Get-Content $stdout_files[$i] -Tail 20 + Get-Content $stderr_files[$i] -Tail 20 + $failed = $true + } + } + + if ($failed) { exit 1 } +} diff --git a/tools/multi-build.ps1 b/tools/multi-build.ps1 new file mode 100644 index 00000000..5be28c09 --- /dev/null +++ b/tools/multi-build.ps1 @@ -0,0 +1,56 @@ +if ($args.count -lt 1) { + Write-Error "Requires 1 arg: number of builds for this job." + exit 1 +} + +$BuildCount = [int]$args[0] + +$build_ids = 0..($BuildCount - 1) +$build_dirs = foreach($i in $build_ids) { "build$i" } +$stdout_files = foreach($i in $build_ids) { "stdout$i.txt" } +$stderr_files = foreach($i in $build_ids) { "stderr$i.txt" } + +# Create unique temp dir for each build thread +$temp_dirs = foreach($dir in $build_dirs) { "$env:temp\$dir" } +New-Item -ItemType Directory -Force -Path $temp_dirs + +$procs = New-Object System.Collections.Generic.List[System.Diagnostics.Process] + +foreach($i in $build_ids) { + $params = @{ + FilePath = "cmake" + PassThru = $null + ArgumentList = @("--build", $build_dirs[$i]) + Environment = @{ TEMP = $temp_dirs[$i]; TMP = $temp_dirs[$i] } + } + + # For the first job, display stdout and stderr. + # Else dump to file so we don't see 50 at once. + if ($i -eq 0) { + $params.Add("NoNewWindow", $null) + } else { + $params.Add("RedirectStandardOutput", $stdout_files[$i]) + $params.Add("RedirectStandardError", $stderr_files[$i]) + } + + $procs.Add($(Start-Process @params)) +} + + +$failed = $false + +# Wait for all builds to finish +try { Wait-Process -InputObject $procs } catch { $failed = $true } + +# Check for failure +foreach($i in $build_ids) { + if ($procs[$i].ExitCode -ne 0) { + if ($i -ne 0) { + Get-Content $stdout_files[$i] -Tail 10 + Get-Content $stderr_files[$i] -Tail 10 + } + $failed = $true + } +} + +if ($failed) { exit 1 } diff --git a/tools/multi-prepare.ps1 b/tools/multi-prepare.ps1 new file mode 100644 index 00000000..3ba89ed8 --- /dev/null +++ b/tools/multi-prepare.ps1 @@ -0,0 +1,81 @@ +if ($args.count -lt 2) { + Write-Error "Requires 2 args: job matrix number and number of builds for this job." + exit 1 +} + +function Get-BaseSeed { + Param ( + [int]$Matrix + ) + + # GITHUB_SHA is the commit hash. This means the entropy files will be consistent + # unless you push a new commit. + $sha = [System.Convert]::ToUInt32($env:GITHUB_SHA.Substring(0, 8), 16) + + # Mask off the last 16 bits + $base_seed = ($sha -band 0xffff0000) + + # Add the matrix number * 256. We can run 256 unique builds on this job. + return $base_seed + ($Matrix -shl 8) +} + +$MatrixNo = [int]$args[0] +$BuildCount = [int]$args[1] +$base_seed = $(Get-BaseSeed -Matrix $MatrixNo) + +$build_ids = 0..($BuildCount - 1) + +$build_dirs = foreach($i in $build_ids) { "build$i" } +$stdout_files = foreach($i in $build_ids) { "stdout$i.txt" } +$stderr_files = foreach($i in $build_ids) { "stderr$i.txt" } + +$procs = New-Object System.Collections.Generic.List[System.Diagnostics.Process] + +foreach($i in $build_ids) { + # Create the entropy file + $entropy_file = "entropy$i.h" + $seed = $base_seed + $i + + Write-Output "Using seed: $seed (instance $i)" + python3 tools/entropy.py $seed > $entropy_file + + # Prepare to build + $params = @{ + FilePath = "cmake" + PassThru = $null + ArgumentList = @( + "-B", $build_dirs[$i], + "-DCMAKE_BUILD_TYPE=RelWithDebInfo", + "-DISLE_INCLUDE_ENTROPY=ON", + "-DISLE_ENTROPY_FILENAME=$entropy_file", + "-G", "`"NMake Makefiles`"" + ) + } + + # For the first job, display stdout and stderr. + # Else dump to file so we don't see 50 at once. + if ($i -eq 0) { + $params.Add("NoNewWindow", $null) + } else { + $params.Add("RedirectStandardOutput", $stdout_files[$i]) + $params.Add("RedirectStandardError", $stderr_files[$i]) + } + + $procs.Add($(Start-Process @params)) +} + +$failed = $false +try { Wait-Process -InputObject $procs } catch { $failed = $true } + +# Check for failure +foreach($i in $build_ids) { + if ($procs[$i].ExitCode -ne 0) { + if ($i -ne 0) { + Get-Content $stdout_files[$i] -Tail 10 + Get-Content $stderr_files[$i] -Tail 10 + } + $failed = $true + } +} + +if ($failed) { exit 1 } From 77435427b33d221943a99c26b4ad1f35a439340f Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 14 Mar 2025 13:24:11 -0700 Subject: [PATCH 14/16] Match `Radio::HandleControl` (#1408) --- LEGO1/lego/legoomni/src/actors/radio.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/LEGO1/lego/legoomni/src/actors/radio.cpp b/LEGO1/lego/legoomni/src/actors/radio.cpp index 310a08b0..db5017f2 100644 --- a/LEGO1/lego/legoomni/src/actors/radio.cpp +++ b/LEGO1/lego/legoomni/src/actors/radio.cpp @@ -141,12 +141,13 @@ void Radio::Stop() } // FUNCTION: LEGO1 0x1002cbc0 +// FUNCTION: BETA10 0x100f1ce1 MxLong Radio::HandleControl(LegoControlManagerNotificationParam& p_param) { MxDSAction action; // Unused - MxS32 objectId = p_param.m_clickedObjectId; - if (objectId == IsleScript::c_Radio_Ctl) { + switch (p_param.m_clickedObjectId) { + case IsleScript::c_Radio_Ctl: if (m_state->IsActive()) { Stop(); } From 421a31705093c73387fe728c8802203ccfdb8965 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 14 Mar 2025 13:24:50 -0700 Subject: [PATCH 15/16] Match `Isle::HandleEndAction` (#1409) --- LEGO1/lego/legoomni/src/worlds/isle.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 7829d6e8..865607d9 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -205,13 +205,8 @@ MxLong Isle::HandleEndAction(MxEndActionNotificationParam& p_param) result = m_radio.Notify(p_param); if (result == 0) { - MxDSAction* action = p_param.GetAction(); - - // TODO: Should be signed, but worsens match - MxU32 script; - - if (action->GetAtomId() == *g_jukeboxScript) { - script = action->GetObjectId(); + if (p_param.GetAction()->GetAtomId() == *g_jukeboxScript) { + MxS32 script = p_param.GetAction()->GetObjectId(); if (script >= JukeboxScript::c_JBMusic1 && script <= JukeboxScript::c_JBMusic6) { m_jukebox->StopAction((JukeboxScript::Script) script); @@ -219,14 +214,14 @@ MxLong Isle::HandleEndAction(MxEndActionNotificationParam& p_param) } } else if (m_act1state->m_planeActive) { - script = action->GetObjectId(); + MxS32 script = p_param.GetAction()->GetObjectId(); if (script >= IsleScript::c_nic002pr_RunAnim && script <= IsleScript::c_nic004pr_RunAnim) { m_act1state->m_planeActive = FALSE; } } else { - script = action->GetObjectId(); + MxS32 script = p_param.GetAction()->GetObjectId(); if (script == IsleScript::c_Avo917In_PlayWav || (script >= IsleScript::c_Avo900Ps_PlayWav && script <= IsleScript::c_Avo907Ps_PlayWav)) { From b0b68052d4185063251d22f8698afdf3717e140f Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 14 Mar 2025 13:45:53 -0700 Subject: [PATCH 16/16] Improve `Isle::Enable` match (#1410) --- LEGO1/lego/legoomni/src/worlds/isle.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 865607d9..5fb87505 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -543,11 +543,12 @@ void Isle::Enable(MxBool p_enable) m_act1state->PlaceActors(); if (UserActor() != NULL && UserActor()->GetActorId() != LegoActor::c_none) { - // TODO: Match, most likely an inline function - MxS32 targetEntityId = (UserActor()->GetActorId() == 1) + 250; + IsleScript::Script noPizzaSign = UserActor()->GetActorId() == LegoActor::c_pepper + ? IsleScript::c_NoPizaz_Texture + : IsleScript::c_NoPizza_Texture; - if (targetEntityId != -1) { - InvokeAction(Extra::e_start, *g_isleScript, targetEntityId, NULL); + if (noPizzaSign != IsleScript::c_noneIsle) { + InvokeAction(Extra::e_start, *g_isleScript, noPizzaSign, NULL); } }