diff --git a/LEGO1/lego/legoomni/include/act2actor.h b/LEGO1/lego/legoomni/include/act2actor.h index 68b8f59d..324cf4b3 100644 --- a/LEGO1/lego/legoomni/include/act2actor.h +++ b/LEGO1/lego/legoomni/include/act2actor.h @@ -19,13 +19,23 @@ public: Act2Actor(); - void SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) override; // vtable+0x24 - void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 - MxS32 VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) override; // vtable+0x68 - void Animate(float p_time) override; // vtable+0x70 - MxResult HitActor(LegoPathActor*, MxBool) override; // vtable+0x94 - MxResult VTable0x9c() override; // vtable+0x9c - MxS32 VTable0xa0() override; // vtable+0xa0 + void SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) override; // vtable+0x24 + void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 + + // FUNCTION: LEGO1 0x1001a180 + MxS32 VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) override + { + if (m_unk0x1f) { + return 0; + } + + return LegoAnimActor::VTable0x68(p_v1, p_v2, p_v3); + } // vtable+0x68 + + void Animate(float p_time) override; // vtable+0x70 + MxResult HitActor(LegoPathActor*, MxBool) override; // vtable+0x94 + MxResult VTable0x9c() override; // vtable+0x9c + MxS32 VTable0xa0() override; // vtable+0xa0 void FUN_10018980(); void FUN_10019250(MxFloat p_speed, MxFloat p_param2); diff --git a/LEGO1/lego/legoomni/include/act3.h b/LEGO1/lego/legoomni/include/act3.h index 57012215..174d74a7 100644 --- a/LEGO1/lego/legoomni/include/act3.h +++ b/LEGO1/lego/legoomni/include/act3.h @@ -10,6 +10,7 @@ class Act3Brickster; class Act3Cop; class Act3Shark; class Helicopter; +class MxQuaternionTransformer; // Macros confirmed by BETA10 #define MAX_PIZZAS 20 @@ -53,6 +54,9 @@ class Act3State : public LegoState { public: Act3State() { m_unk0x08 = 0; } + // FUNCTION: LEGO1 0x1000e2f0 + MxBool IsSerializable() override { return FALSE; } + // FUNCTION: LEGO1 0x1000e300 // FUNCTION: BETA10 0x10017e10 const char* ClassName() const override // vtable+0x0c @@ -67,9 +71,6 @@ public: return !strcmp(p_name, Act3State::ClassName()) || LegoState::IsA(p_name); } - // FUNCTION: LEGO1 0x1000e2f0 - MxBool IsSerializable() override { return FALSE; } - // SYNTHETIC: LEGO1 0x1000e3c0 // Act3State::`scalar deleting destructor' @@ -152,7 +153,7 @@ protected: const Matrix4& p_destination, const Matrix4& p_startPosition, const Matrix4& p_endPosition, - const UnknownMx4DPointFloat& p_unk0x1f4 + const MxQuaternionTransformer& p_unk0x1f4 ); Act3State* m_state; // 0xf8 diff --git a/LEGO1/lego/legoomni/include/buildings.h b/LEGO1/lego/legoomni/include/buildings.h index 71201a48..165bc87e 100644 --- a/LEGO1/lego/legoomni/include/buildings.h +++ b/LEGO1/lego/legoomni/include/buildings.h @@ -5,80 +5,6 @@ class LegoEventNotificationParam; -// VTABLE: LEGO1 0x100d48a8 -// VTABLE: BETA10 0x101bd818 -// SIZE 0x68 -class RaceStandsEntity : public BuildingEntity { - // FUNCTION: LEGO1 0x1000efa0 - // FUNCTION: BETA10 0x100a9820 - const char* ClassName() const override // vtable+0x0c - { - // at LEGO1 0x100f0300, needs no annotation - return "RaceStandsEntity"; - } - - // FUNCTION: LEGO1 0x1000efb0 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, RaceStandsEntity::ClassName()) || BuildingEntity::IsA(p_name); - } - - MxLong HandleClick(LegoEventNotificationParam& p_param) override; - - // SYNTHETIC: LEGO1 0x1000f9e0 - // RaceStandsEntity::`scalar deleting destructor' -}; - -// VTABLE: LEGO1 0x100d4a18 -// VTABLE: BETA10 0x101bd7b0 -// SIZE 0x68 -class BeachHouseEntity : public BuildingEntity { -public: - // FUNCTION: LEGO1 0x1000ee80 - // FUNCTION: BETA10 0x100a96f0 - const char* ClassName() const override // vtable+0x0c - { - // STRING: LEGO1 0x100f0314 - return "BeachHouseEntity"; - } - - // FUNCTION: LEGO1 0x1000ee90 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, BeachHouseEntity::ClassName()) || BuildingEntity::IsA(p_name); - } - - MxLong HandleClick(LegoEventNotificationParam& p_param) override; - - // SYNTHETIC: LEGO1 0x1000f970 - // BeachHouseEntity::`scalar deleting destructor' -}; - -// VTABLE: LEGO1 0x100d4ab0 -// VTABLE: BETA10 0x101bd748 -// SIZE 0x68 -class PoliceEntity : public BuildingEntity { -public: - // FUNCTION: LEGO1 0x1000ed60 - // FUNCTION: BETA10 0x100a95c0 - const char* ClassName() const override // vtable+0x0c - { - // STRING: LEGO1 0x100f0328 - return "PoliceEntity"; - } - - // FUNCTION: LEGO1 0x1000ed70 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, PoliceEntity::ClassName()) || BuildingEntity::IsA(p_name); - } - - MxLong HandleClick(LegoEventNotificationParam& p_param) override; // vtable+0x50 - - // SYNTHETIC: LEGO1 0x1000f900 - // PoliceEntity::`scalar deleting destructor' -}; - // VTABLE: LEGO1 0x100d4b90 // VTABLE: BETA10 0x101bd610 // SIZE 0x68 @@ -104,79 +30,6 @@ public: // InfoCenterEntity::`scalar deleting destructor' }; -// VTABLE: LEGO1 0x100d5068 -// VTABLE: BETA10 0x101bd678 -// SIZE 0x68 -class HospitalEntity : public BuildingEntity { -public: - // FUNCTION: LEGO1 0x1000ec40 - // FUNCTION: BETA10 0x100a9360 - const char* ClassName() const override // vtable+0x0c - { - // STRING: LEGO1 0x100f0338 - return "HospitalEntity"; - } - - // FUNCTION: LEGO1 0x1000ec50 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, HospitalEntity::ClassName()) || BuildingEntity::IsA(p_name); - } - - MxLong HandleClick(LegoEventNotificationParam& p_param) override; // vtable+0x50 - - // SYNTHETIC: LEGO1 0x1000f820 - // HospitalEntity::`scalar deleting destructor' -}; - -// VTABLE: LEGO1 0x100d50c0 -// VTABLE: BETA10 0x101bd880 -// SIZE 0x68 -class CaveEntity : public BuildingEntity { - // FUNCTION: LEGO1 0x1000f1e0 - // FUNCTION: BETA10 0x100a9950 - const char* ClassName() const override // vtable+0x0c - { - // at LEGO1 0x100f0300, needs no annotation - return "RaceStandsEntity"; - } - - // FUNCTION: LEGO1 0x1000f1f0 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, CaveEntity::ClassName()) || BuildingEntity::IsA(p_name); - } - - MxLong HandleClick(LegoEventNotificationParam& p_param) override; - - // SYNTHETIC: LEGO1 0x1000fa50 - // CaveEntity::`scalar deleting destructor' -}; - -// VTABLE: LEGO1 0x100d5200 -// VTABLE: BETA10 0x101bd8e8 -// SIZE 0x68 -class JailEntity : public BuildingEntity { - // FUNCTION: LEGO1 0x1000f0c0 - // FUNCTION: BETA10 0x100a9a80 - const char* ClassName() const override // vtable+0x0c - { - // at LEGO1 0x100f0300, needs no annotation - return "RaceStandsEntity"; - } - - // FUNCTION: LEGO1 0x1000f0d0 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, JailEntity::ClassName()) || BuildingEntity::IsA(p_name); - } - - MxLong HandleClick(LegoEventNotificationParam& p_param) override; - - // SYNTHETIC: LEGO1 0x1000fac0 - // JailEntity::`scalar deleting destructor' -}; - // VTABLE: LEGO1 0x100d5258 // VTABLE: BETA10 0x101bd6e0 // SIZE 0x68 @@ -202,4 +55,151 @@ public: // GasStationEntity::`scalar deleting destructor' }; +// VTABLE: LEGO1 0x100d5068 +// VTABLE: BETA10 0x101bd678 +// SIZE 0x68 +class HospitalEntity : public BuildingEntity { +public: + // FUNCTION: LEGO1 0x1000ec40 + // FUNCTION: BETA10 0x100a9360 + const char* ClassName() const override // vtable+0x0c + { + // STRING: LEGO1 0x100f0338 + return "HospitalEntity"; + } + + // FUNCTION: LEGO1 0x1000ec50 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, HospitalEntity::ClassName()) || BuildingEntity::IsA(p_name); + } + + MxLong HandleClick(LegoEventNotificationParam& p_param) override; // vtable+0x50 + + // SYNTHETIC: LEGO1 0x1000f820 + // HospitalEntity::`scalar deleting destructor' +}; + +// VTABLE: LEGO1 0x100d4ab0 +// VTABLE: BETA10 0x101bd748 +// SIZE 0x68 +class PoliceEntity : public BuildingEntity { +public: + // FUNCTION: LEGO1 0x1000ed60 + // FUNCTION: BETA10 0x100a95c0 + const char* ClassName() const override // vtable+0x0c + { + // STRING: LEGO1 0x100f0328 + return "PoliceEntity"; + } + + // FUNCTION: LEGO1 0x1000ed70 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, PoliceEntity::ClassName()) || BuildingEntity::IsA(p_name); + } + + MxLong HandleClick(LegoEventNotificationParam& p_param) override; // vtable+0x50 + + // SYNTHETIC: LEGO1 0x1000f900 + // PoliceEntity::`scalar deleting destructor' +}; + +// VTABLE: LEGO1 0x100d4a18 +// VTABLE: BETA10 0x101bd7b0 +// SIZE 0x68 +class BeachHouseEntity : public BuildingEntity { +public: + // FUNCTION: LEGO1 0x1000ee80 + // FUNCTION: BETA10 0x100a96f0 + const char* ClassName() const override // vtable+0x0c + { + // STRING: LEGO1 0x100f0314 + return "BeachHouseEntity"; + } + + // FUNCTION: LEGO1 0x1000ee90 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, BeachHouseEntity::ClassName()) || BuildingEntity::IsA(p_name); + } + + MxLong HandleClick(LegoEventNotificationParam& p_param) override; + + // SYNTHETIC: LEGO1 0x1000f970 + // BeachHouseEntity::`scalar deleting destructor' +}; + +// VTABLE: LEGO1 0x100d48a8 +// VTABLE: BETA10 0x101bd818 +// SIZE 0x68 +class RaceStandsEntity : public BuildingEntity { + // FUNCTION: LEGO1 0x1000efa0 + // FUNCTION: BETA10 0x100a9820 + const char* ClassName() const override // vtable+0x0c + { + // at LEGO1 0x100f0300, needs no annotation + return "RaceStandsEntity"; + } + + // FUNCTION: LEGO1 0x1000efb0 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, RaceStandsEntity::ClassName()) || BuildingEntity::IsA(p_name); + } + + MxLong HandleClick(LegoEventNotificationParam& p_param) override; + + // SYNTHETIC: LEGO1 0x1000f9e0 + // RaceStandsEntity::`scalar deleting destructor' +}; + +// VTABLE: LEGO1 0x100d5200 +// VTABLE: BETA10 0x101bd8e8 +// SIZE 0x68 +class JailEntity : public BuildingEntity { + // FUNCTION: LEGO1 0x1000f0c0 + // FUNCTION: BETA10 0x100a9a80 + const char* ClassName() const override // vtable+0x0c + { + // at LEGO1 0x100f0300, needs no annotation + return "RaceStandsEntity"; + } + + // FUNCTION: LEGO1 0x1000f0d0 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, JailEntity::ClassName()) || BuildingEntity::IsA(p_name); + } + + MxLong HandleClick(LegoEventNotificationParam& p_param) override; + + // SYNTHETIC: LEGO1 0x1000fac0 + // JailEntity::`scalar deleting destructor' +}; + +// VTABLE: LEGO1 0x100d50c0 +// VTABLE: BETA10 0x101bd880 +// SIZE 0x68 +class CaveEntity : public BuildingEntity { + // FUNCTION: LEGO1 0x1000f1e0 + // FUNCTION: BETA10 0x100a9950 + const char* ClassName() const override // vtable+0x0c + { + // at LEGO1 0x100f0300, needs no annotation + return "RaceStandsEntity"; + } + + // FUNCTION: LEGO1 0x1000f1f0 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, CaveEntity::ClassName()) || BuildingEntity::IsA(p_name); + } + + MxLong HandleClick(LegoEventNotificationParam& p_param) override; + + // SYNTHETIC: LEGO1 0x1000fa50 + // CaveEntity::`scalar deleting destructor' +}; + #endif // BUILDINGS_H diff --git a/LEGO1/lego/legoomni/include/elevatorbottom.h b/LEGO1/lego/legoomni/include/elevatorbottom.h index 899a830a..ad1fe29f 100644 --- a/LEGO1/lego/legoomni/include/elevatorbottom.h +++ b/LEGO1/lego/legoomni/include/elevatorbottom.h @@ -17,6 +17,9 @@ public: MxLong Notify(MxParam& p_param) override; // vtable+0x04 + // FUNCTION: LEGO1 0x10017f10 + MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c + // FUNCTION: LEGO1 0x10017f20 // FUNCTION: BETA10 0x10028130 const char* ClassName() const override // vtable+0x0c @@ -33,12 +36,8 @@ public: MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 void ReadyWorld() override; // vtable+0x50 - - // FUNCTION: LEGO1 0x10017f10 - MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c - - MxBool Escape() override; // vtable+0x64 - void Enable(MxBool p_enable) override; // vtable+0x68 + MxBool Escape() override; // vtable+0x64 + void Enable(MxBool p_enable) override; // vtable+0x68 // SYNTHETIC: LEGO1 0x10018040 // ElevatorBottom::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/gasstation.h b/LEGO1/lego/legoomni/include/gasstation.h index e89ac51c..bb7bb3ad 100644 --- a/LEGO1/lego/legoomni/include/gasstation.h +++ b/LEGO1/lego/legoomni/include/gasstation.h @@ -16,11 +16,6 @@ class MxStillPresenter; // SIZE 0x24 class GasStationState : public LegoState { public: - // SIZE 0x04 - struct Unknown0x14 { - undefined4 m_unk0x00; // 0x00 - }; - GasStationState(); // FUNCTION: LEGO1 0x100061d0 @@ -49,7 +44,7 @@ public: // TODO: Most likely getters/setters are not used according to BETA. GarageScript::Script m_actions[3]; // 0x08 - Unknown0x14 m_unk0x14; // 0x14 + undefined4 m_unk0x14; // 0x14 MxS16 m_pepperAction; // 0x18 MxS16 m_mamaAction; // 0x1a MxS16 m_papaAction; // 0x1c @@ -68,6 +63,9 @@ public: MxLong Notify(MxParam& p_param) override; // vtable+0x04 MxResult Tickle() override; // vtable+0x08 + // FUNCTION: LEGO1 0x10004770 + MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c + // FUNCTION: LEGO1 0x10004780 // FUNCTION: BETA10 0x10029d40 const char* ClassName() const override // vtable+0x0c @@ -84,7 +82,6 @@ public: MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 void ReadyWorld() override; // vtable+0x50 - MxBool VTable0x5c() override; // vtable+0x5c MxBool Escape() override; // vtable+0x64 void Enable(MxBool p_enable) override; // vtable+0x68 virtual MxLong HandleControl(LegoControlManagerNotificationParam& p_param); // vtable+0x6c diff --git a/LEGO1/lego/legoomni/include/helicopter.h b/LEGO1/lego/legoomni/include/helicopter.h index 8d887d73..8496faf9 100644 --- a/LEGO1/lego/legoomni/include/helicopter.h +++ b/LEGO1/lego/legoomni/include/helicopter.h @@ -3,7 +3,7 @@ #include "islepathactor.h" #include "legostate.h" -#include "realtime/matrix.h" +#include "mxgeometry/mxquaternion.h" class Act3; @@ -14,6 +14,16 @@ class HelicopterState : public LegoState { public: HelicopterState() : m_unk0x08(0) {} + // FUNCTION: LEGO1 0x1000e0b0 + MxBool IsSerializable() override { return FALSE; } // vtable+0x14 + + // FUNCTION: LEGO1 0x1000e0c0 + MxBool Reset() override + { + m_unk0x08 = 0; + return TRUE; + } // vtable+0x18 + // FUNCTION: LEGO1 0x1000e0d0 // FUNCTION: BETA10 0x100a7cc0 const char* ClassName() const override // vtable+0x0c @@ -28,16 +38,6 @@ public: return !strcmp(p_name, HelicopterState::ClassName()) || LegoState::IsA(p_name); } - // FUNCTION: LEGO1 0x1000e0b0 - MxBool IsSerializable() override { return FALSE; } // vtable+0x14 - - // FUNCTION: LEGO1 0x1000e0c0 - MxBool Reset() override - { - m_unk0x08 = 0; - return TRUE; - } // vtable+0x18 - // SYNTHETIC: LEGO1 0x1000e190 // HelicopterState::`scalar deleting destructor' @@ -88,12 +88,12 @@ public: protected: void FUN_100042a0(const Matrix4& p_matrix); - MxMatrix m_unk0x160; // 0x160 - MxMatrix m_unk0x1a8; // 0x1a8 - float m_unk0x1f0; // 0x1f0 - UnknownMx4DPointFloat m_unk0x1f4; // 0x1f4 - HelicopterState* m_state; // 0x228 - MxAtomId m_script; // 0x22c + MxMatrix m_unk0x160; // 0x160 + MxMatrix m_unk0x1a8; // 0x1a8 + float m_unk0x1f0; // 0x1f0 + MxQuaternionTransformer m_unk0x1f4; // 0x1f4 + HelicopterState* m_state; // 0x228 + MxAtomId m_script; // 0x22c }; #endif // HELICOPTER_H diff --git a/LEGO1/lego/legoomni/include/isleactor.h b/LEGO1/lego/legoomni/include/isleactor.h index 56df85f4..15896e79 100644 --- a/LEGO1/lego/legoomni/include/isleactor.h +++ b/LEGO1/lego/legoomni/include/isleactor.h @@ -14,22 +14,7 @@ class MxNotificationParam; // SIZE 0x7c class IsleActor : public LegoActor { public: - MxLong Notify(MxParam& p_param) override; // vtable+0x04 - - // FUNCTION: LEGO1 0x1000e660 - // FUNCTION: BETA10 0x100a8300 - const char* ClassName() const override // vtable+0x0c - { - // STRING: LEGO1 0x100f07dc - return "IsleActor"; - } - - // FUNCTION: LEGO1 0x1000e670 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, IsleActor::ClassName()) || LegoActor::IsA(p_name); - } - + MxLong Notify(MxParam& p_param) override; // vtable+0x04 MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 // FUNCTION: LEGO1 0x1000e5f0 @@ -53,6 +38,20 @@ public: // FUNCTION: LEGO1 0x1000e650 virtual MxLong HandlePathStruct(LegoPathStructNotificationParam&) { return 0; } // vtable+0x80 + // FUNCTION: LEGO1 0x1000e660 + // FUNCTION: BETA10 0x100a8300 + const char* ClassName() const override // vtable+0x0c + { + // STRING: LEGO1 0x100f07dc + return "IsleActor"; + } + + // FUNCTION: LEGO1 0x1000e670 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, IsleActor::ClassName()) || LegoActor::IsA(p_name); + } + protected: LegoWorld* m_world; // 0x78 }; diff --git a/LEGO1/lego/legoomni/include/islepathactor.h b/LEGO1/lego/legoomni/include/islepathactor.h index 1aa5616a..70a58702 100644 --- a/LEGO1/lego/legoomni/include/islepathactor.h +++ b/LEGO1/lego/legoomni/include/islepathactor.h @@ -86,6 +86,26 @@ public: IslePathActor(); + // FUNCTION: LEGO1 0x10002e70 + virtual MxLong HandleClick() { return 0; } // vtable+0xcc + + // FUNCTION: LEGO1 0x10002df0 + virtual MxLong HandleNotification0() { return 0; } // vtable+0xd0 + + // FUNCTION: LEGO1 0x10002e80 + virtual MxLong HandleControl(LegoControlManagerNotificationParam&) { return 0; } // vtable+0xd4 + + // FUNCTION: LEGO1 0x10002e90 + virtual MxLong HandleEndAnim(LegoEndAnimNotificationParam&) { return 0; } // vtable+0xd8 + + // FUNCTION: LEGO1 0x10002e00 + virtual MxLong HandlePathStruct(LegoPathStructNotificationParam&) { return 0; } // vtable+0xdc + + virtual void Enter(); // vtable+0xe0 + virtual void Exit(); // vtable+0xe4 + virtual void SpawnPlayer(LegoGameState::Area p_area, MxBool p_enter, MxU8 p_flags); // vtable+0xe8 + virtual void VTable0xec(MxMatrix p_transform, LegoPathBoundary* p_boundary, MxBool p_reset); // vtable+0xec + // FUNCTION: LEGO1 0x10002e10 ~IslePathActor() override { IslePathActor::Destroy(TRUE); } @@ -108,29 +128,6 @@ public: MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 void Destroy(MxBool p_fromDestructor) override; // vtable+0x1c - // FUNCTION: LEGO1 0x10002e70 - virtual MxLong HandleClick() { return 0; } // vtable+0xcc - - // FUNCTION: LEGO1 0x10002df0 - virtual MxLong HandleNotification0() { return 0; } // vtable+0xd0 - - // FUNCTION: LEGO1 0x10002e80 - virtual MxLong HandleControl(LegoControlManagerNotificationParam&) { return 0; } // vtable+0xd4 - - // FUNCTION: LEGO1 0x10002e90 - virtual MxLong HandleEndAnim(LegoEndAnimNotificationParam&) { return 0; } // vtable+0xd8 - - // FUNCTION: LEGO1 0x10002e00 - virtual MxLong HandlePathStruct(LegoPathStructNotificationParam&) { return 0; } // vtable+0xdc - - virtual void Enter(); // vtable+0xe0 - virtual void Exit(); // vtable+0xe4 - virtual void SpawnPlayer(LegoGameState::Area p_area, MxBool p_enter, MxU8 p_flags); // vtable+0xe8 - virtual void VTable0xec(MxMatrix p_transform, LegoPathBoundary* p_boundary, MxBool p_reset); // vtable+0xec - - // SYNTHETIC: LEGO1 0x10002ff0 - // IslePathActor::`scalar deleting destructor' - void FUN_1001b660(); void Reset() @@ -143,6 +140,9 @@ public: static void RegisterSpawnLocations(); + // SYNTHETIC: LEGO1 0x10002ff0 + // IslePathActor::`scalar deleting destructor' + protected: LegoWorld* m_world; // 0x154 LegoPathActor* m_previousActor; // 0x158 diff --git a/LEGO1/lego/legoomni/include/jetskirace.h b/LEGO1/lego/legoomni/include/jetskirace.h index e880086f..7542d851 100644 --- a/LEGO1/lego/legoomni/include/jetskirace.h +++ b/LEGO1/lego/legoomni/include/jetskirace.h @@ -3,32 +3,6 @@ #include "legorace.h" -// VTABLE: LEGO1 0x100d4fa8 -// VTABLE: BETA10 0x101bd5d0 -// SIZE 0x2c -class JetskiRaceState : public RaceState { -public: - // FUNCTION: LEGO1 0x1000dc40 - // FUNCTION: BETA10 0x100a8f30 - const char* ClassName() const override // vtable+0x0c - { - // STRING: LEGO1 0x100f00ac - // STRING: BETA10 0x101f1d0c - return "JetskiRaceState"; - } - - // FUNCTION: LEGO1 0x1000dc50 - // FUNCTION: BETA10 0x100a8f60 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, JetskiRaceState::ClassName()) || RaceState::IsA(p_name); - } - - // SYNTHETIC: LEGO1 0x1000f680 - // SYNTHETIC: BETA10 0x100a9d10 - // JetskiRaceState::`scalar deleting destructor' -}; - // VTABLE: LEGO1 0x100d4fe8 // VTABLE: BETA10 0x101bd268 // SIZE 0x144 @@ -68,6 +42,32 @@ private: static MxS32 g_unk0x100f0c78; }; +// VTABLE: LEGO1 0x100d4fa8 +// VTABLE: BETA10 0x101bd5d0 +// SIZE 0x2c +class JetskiRaceState : public RaceState { +public: + // FUNCTION: LEGO1 0x1000dc40 + // FUNCTION: BETA10 0x100a8f30 + const char* ClassName() const override // vtable+0x0c + { + // STRING: LEGO1 0x100f00ac + // STRING: BETA10 0x101f1d0c + return "JetskiRaceState"; + } + + // FUNCTION: LEGO1 0x1000dc50 + // FUNCTION: BETA10 0x100a8f60 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, JetskiRaceState::ClassName()) || RaceState::IsA(p_name); + } + + // SYNTHETIC: LEGO1 0x1000f680 + // SYNTHETIC: BETA10 0x100a9d10 + // JetskiRaceState::`scalar deleting destructor' +}; + // SYNTHETIC: LEGO1 0x1000f530 // SYNTHETIC: BETA10 0x100a9b70 // JetskiRace::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/jukebox.h b/LEGO1/lego/legoomni/include/jukebox.h index b3512503..8196f454 100644 --- a/LEGO1/lego/legoomni/include/jukebox.h +++ b/LEGO1/lego/legoomni/include/jukebox.h @@ -24,6 +24,9 @@ public: JukeBoxState() : m_music(e_pasquell), m_active(FALSE) {} + // FUNCTION: LEGO1 0x1000f300 + MxBool IsSerializable() override { return FALSE; } // vtable+0x14 + // FUNCTION: LEGO1 0x1000f310 // FUNCTION: BETA10 0x100389c0 const char* ClassName() const override // vtable+0x0c @@ -38,9 +41,6 @@ public: return !strcmp(p_name, JukeBoxState::ClassName()) || LegoState::IsA(p_name); } - // FUNCTION: LEGO1 0x1000f300 - MxBool IsSerializable() override { return FALSE; } // vtable+0x14 - // SYNTHETIC: LEGO1 0x1000f3d0 // JukeBoxState::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 89da6c41..62c5f04e 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -22,6 +22,9 @@ public: } ~LegoAct2State() override {} + // FUNCTION: LEGO1 0x1000df70 + MxBool IsSerializable() override { return FALSE; } // vtable+0x14 + // FUNCTION: LEGO1 0x1000df80 // FUNCTION: BETA10 0x1003c7e0 const char* ClassName() const override // vtable+0x0c @@ -36,9 +39,6 @@ public: return !strcmp(p_name, LegoAct2State::ClassName()) || LegoState::IsA(p_name); } - // FUNCTION: LEGO1 0x1000df70 - MxBool IsSerializable() override { return FALSE; } // vtable+0x14 - // SYNTHETIC: LEGO1 0x1000e040 // LegoAct2State::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoactor.h b/LEGO1/lego/legoomni/include/legoactor.h index 7c29ee6b..47c399f9 100644 --- a/LEGO1/lego/legoomni/include/legoactor.h +++ b/LEGO1/lego/legoomni/include/legoactor.h @@ -3,6 +3,7 @@ #include "decomp.h" #include "legoentity.h" +#include "mxgeometry/mxmatrix.h" class LegoCacheSound; diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index 4e6cb044..f2d42603 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -8,7 +8,7 @@ #include "legostate.h" #include "legotraninfolist.h" #include "mxcore.h" -#include "mxgeometry/mxgeometry3d.h" +#include "mxgeometry/mxquaternion.h" class LegoAnimPresenter; class LegoEntity; @@ -259,46 +259,46 @@ private: void FUN_100648f0(LegoTranInfo* p_tranInfo, MxLong p_unk0x404); void FUN_10064b50(MxLong p_time); - LegoOmni::World m_worldId; // 0x08 - MxU16 m_animCount; // 0x0c - MxU16 m_unk0x0e; // 0x0e - MxU16 m_unk0x10; // 0x10 - AnimInfo* m_anims; // 0x14 - undefined2 m_unk0x18; // 0x18 - MxBool m_unk0x1a; // 0x1a - MxU32 m_unk0x1c; // 0x1c - LegoTranInfoList* m_tranInfoList; // 0x20 - LegoTranInfoList* m_tranInfoList2; // 0x24 - MxPresenter* m_unk0x28[2]; // 0x28 - MxLong m_unk0x30[2]; // 0x30 - MxBool m_unk0x38; // 0x38 - MxBool m_animRunning; // 0x39 - MxBool m_enableCamAnims; // 0x3a - Extra m_extras[40]; // 0x3c - MxU32 m_lastExtraCharacterId; // 0x3fc - MxBool m_unk0x400; // 0x400 - MxBool m_unk0x401; // 0x401 - MxBool m_unk0x402; // 0x402 - MxLong m_unk0x404; // 0x404 - MxLong m_unk0x408; // 0x408 - MxLong m_unk0x40c; // 0x40c - MxLong m_unk0x410; // 0x410 - MxU32 m_unk0x414; // 0x414 - MxU32 m_numAllowedExtras; // 0x418 - undefined4 m_unk0x41c; // 0x41c - AnimState* m_animState; // 0x420 - LegoROIList* m_unk0x424; // 0x424 - MxBool m_suspendedEnableCamAnims; // 0x428 - MxBool m_unk0x429; // 0x429 - MxBool m_unk0x42a; // 0x42a - MxBool m_suspended; // 0x42b - LegoTranInfo* m_unk0x42c; // 0x42c - MxBool m_unk0x430; // 0x430 - MxLong m_unk0x434; // 0x434 - MxLong m_unk0x438; // 0x438 - MxMatrix m_unk0x43c; // 0x43c - MxMatrix m_unk0x484; // 0x484 - UnknownMx4DPointFloat m_unk0x4cc; // 0x4cc + LegoOmni::World m_worldId; // 0x08 + MxU16 m_animCount; // 0x0c + MxU16 m_unk0x0e; // 0x0e + MxU16 m_unk0x10; // 0x10 + AnimInfo* m_anims; // 0x14 + undefined2 m_unk0x18; // 0x18 + MxBool m_unk0x1a; // 0x1a + MxU32 m_unk0x1c; // 0x1c + LegoTranInfoList* m_tranInfoList; // 0x20 + LegoTranInfoList* m_tranInfoList2; // 0x24 + MxPresenter* m_unk0x28[2]; // 0x28 + MxLong m_unk0x30[2]; // 0x30 + MxBool m_unk0x38; // 0x38 + MxBool m_animRunning; // 0x39 + MxBool m_enableCamAnims; // 0x3a + Extra m_extras[40]; // 0x3c + MxU32 m_lastExtraCharacterId; // 0x3fc + MxBool m_unk0x400; // 0x400 + MxBool m_unk0x401; // 0x401 + MxBool m_unk0x402; // 0x402 + MxLong m_unk0x404; // 0x404 + MxLong m_unk0x408; // 0x408 + MxLong m_unk0x40c; // 0x40c + MxLong m_unk0x410; // 0x410 + MxU32 m_unk0x414; // 0x414 + MxU32 m_numAllowedExtras; // 0x418 + undefined4 m_unk0x41c; // 0x41c + AnimState* m_animState; // 0x420 + LegoROIList* m_unk0x424; // 0x424 + MxBool m_suspendedEnableCamAnims; // 0x428 + MxBool m_unk0x429; // 0x429 + MxBool m_unk0x42a; // 0x42a + MxBool m_suspended; // 0x42b + LegoTranInfo* m_unk0x42c; // 0x42c + MxBool m_unk0x430; // 0x430 + MxLong m_unk0x434; // 0x434 + MxLong m_unk0x438; // 0x438 + MxMatrix m_unk0x43c; // 0x43c + MxMatrix m_unk0x484; // 0x484 + MxQuaternionTransformer m_unk0x4cc; // 0x4cc }; // TEMPLATE: LEGO1 0x10061750 diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 30da04ff..f31423c5 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -7,7 +7,6 @@ class LegoAnim; class LegoWorld; -class LegoAnimActor; class LegoPathBoundary; class MxMatrix; class Vector3; diff --git a/LEGO1/lego/legoomni/include/legocarbuild.h b/LEGO1/lego/legoomni/include/legocarbuild.h index 81e63150..05645477 100644 --- a/LEGO1/lego/legoomni/include/legocarbuild.h +++ b/LEGO1/lego/legoomni/include/legocarbuild.h @@ -4,6 +4,7 @@ #include "legogamestate.h" #include "legostate.h" #include "legoworld.h" +#include "mxgeometry/mxquaternion.h" #include <SDL3/SDL_stdinc.h> @@ -191,7 +192,7 @@ private: MxS32 m_unk0x250[2]; // 0x250 LegoCarBuildAnimPresenter* m_unk0x258; // 0x258 - UnknownMx4DPointFloat m_unk0x25c; // 0x25c + MxQuaternionTransformer m_unk0x25c; // 0x25c // These two are likely locations in pixel space MxS32 m_unk0x290[2]; // 0x290 diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index 3b04e6e0..6b4dca71 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -69,7 +69,7 @@ public: void ReleaseActor(const char* p_name); void ReleaseActor(LegoROI* p_roi); void ReleaseAutoROI(LegoROI* p_roi); - MxBool FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_textureInfo); + MxBool FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_texture); LegoExtraActor* GetExtraActor(const char* p_name); LegoActorInfo* GetActorInfo(const char* p_name); LegoActorInfo* GetActorInfo(LegoROI* p_roi); diff --git a/LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h b/LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h index 6f0e283a..df2f872e 100644 --- a/LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h @@ -4,6 +4,8 @@ #include "legoloopinganimpresenter.h" #include "legoroimaplist.h" +class LegoAnimActor; + // VTABLE: LEGO1 0x100d9170 // SIZE 0xd8 class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter { diff --git a/LEGO1/lego/legoomni/include/legomodelpresenter.h b/LEGO1/lego/legoomni/include/legomodelpresenter.h index 3b754872..075ba3be 100644 --- a/LEGO1/lego/legoomni/include/legomodelpresenter.h +++ b/LEGO1/lego/legoomni/include/legomodelpresenter.h @@ -19,6 +19,9 @@ public: // FUNCTION: LEGO1 0x10067a10 ~LegoModelPresenter() override { Destroy(TRUE); } + // FUNCTION: LEGO1 0x1000cca0 + void Destroy() override { Destroy(FALSE); } // vtable+0x38 + LEGO1_EXPORT static void configureLegoModelPresenter(MxS32 p_modelPresenterConfig); // FUNCTION: BETA10 0x100a7180 @@ -43,7 +46,6 @@ public: void ReadyTickle() override; // vtable+0x18 void ParseExtra() override; // vtable+0x30 - void Destroy() override; // vtable+0x38 MxResult FUN_1007ff70(MxDSChunk& p_chunk, LegoEntity* p_entity, MxBool p_roiVisible, LegoWorld* p_world); diff --git a/LEGO1/lego/legoomni/include/legopartpresenter.h b/LEGO1/lego/legoomni/include/legopartpresenter.h index bf0bed16..7ff7692d 100644 --- a/LEGO1/lego/legoomni/include/legopartpresenter.h +++ b/LEGO1/lego/legoomni/include/legopartpresenter.h @@ -14,6 +14,9 @@ public: // FUNCTION: LEGO1 0x10067300 ~LegoPartPresenter() override { Destroy(TRUE); } + // FUNCTION: LEGO1 0x1000cf60 + void Destroy() override { Destroy(FALSE); } // vtable+0x38 + // FUNCTION: BETA10 0x100a75d0 static const char* HandlerClassName() { @@ -36,7 +39,6 @@ public: void ReadyTickle() override; // vtable+0x18 MxResult AddToManager() override; // vtable+0x34 - void Destroy() override; // vtable+0x38 LEGO1_EXPORT static void configureLegoPartPresenter(MxS32, MxS32); diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 39cf0965..343cd598 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -3,7 +3,6 @@ #include "legoactor.h" #include "misc/legounknown.h" -#include "mxgeometry/mxmatrix.h" #include "mxtypes.h" struct LegoEdge; diff --git a/LEGO1/lego/legoomni/include/legorace.h b/LEGO1/lego/legoomni/include/legorace.h index 43368f99..c508f3ed 100644 --- a/LEGO1/lego/legoomni/include/legorace.h +++ b/LEGO1/lego/legoomni/include/legorace.h @@ -112,6 +112,19 @@ public: return "LegoRace"; } + MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 + + virtual MxLong HandleClick(LegoEventNotificationParam&) = 0; // vtable+0x6c + + // FUNCTION: LEGO1 0x10015b70 + virtual MxLong HandlePathStruct(LegoPathStructNotificationParam&) { return 0; } // vtable+0x70 + + // FUNCTION: LEGO1 0x10015b80 + virtual MxLong HandleEndAction(MxEndActionNotificationParam&) { return 0; } // vtable+0x74 + + // FUNCTION: LEGO1 0x10015b90 + MxBool Escape() override { return FALSE; } // vtable+0x64 + // FUNCTION: LEGO1 0x10015ba0 // FUNCTION: BETA10 0x100a8940 const char* ClassName() const override // vtable+0x0c @@ -126,17 +139,6 @@ public: return !strcmp(p_name, LegoRace::ClassName()) || LegoWorld::IsA(p_name); } - MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - - // FUNCTION: LEGO1 0x1000dae0 - MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c - - MxBool Escape() override; // vtable+0x64 - void Enable(MxBool p_enable) override; // vtable+0x68 - virtual MxLong HandleClick(LegoEventNotificationParam&) = 0; // vtable+0x6c - virtual MxLong HandlePathStruct(LegoPathStructNotificationParam&); // vtable+0x70 - virtual MxLong HandleEndAction(MxEndActionNotificationParam&); // vtable+0x74 - // FUNCTION: LEGO1 0x1000dab0 virtual MxLong HandleType0Notification(MxNotificationParam&) { return 0; } // vtable+0x78 @@ -147,6 +149,11 @@ public: m_maps[p_index] = p_map; } + // FUNCTION: LEGO1 0x1000dae0 + MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c + + void Enable(MxBool p_enable) override; // vtable+0x68 + // SYNTHETIC: LEGO1 0x10015cc0 // LegoRace::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoraceactor.h b/LEGO1/lego/legoomni/include/legoraceactor.h index 9262f258..bc3d54dc 100644 --- a/LEGO1/lego/legoomni/include/legoraceactor.h +++ b/LEGO1/lego/legoomni/include/legoraceactor.h @@ -34,9 +34,7 @@ public: MxU32 VTable0x90(float p_time, Matrix4& p_matrix) override; // vtable+0x90 MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 - // FUNCTION: LEGO1 0x10014aa0 - // FUNCTION: BETA10 0x100ca038 - virtual MxResult FUN_10014aa0() { return SUCCESS; } + virtual MxResult FUN_10014aa0(); // SYNTHETIC: LEGO1 0x10012c10 // LegoRaceActor::`vbase destructor' diff --git a/LEGO1/lego/legoomni/include/legoracers.h b/LEGO1/lego/legoomni/include/legoracers.h index 3cc4df2e..461b3a52 100644 --- a/LEGO1/lego/legoomni/include/legoracers.h +++ b/LEGO1/lego/legoomni/include/legoracers.h @@ -25,81 +25,6 @@ struct SkeletonKickPhase { MxU8 m_userState; // 0x0c }; -// VTABLE: LEGO1 0x100d58a0 LegoRaceActor -// VTABLE: LEGO1 0x100d58a8 LegoAnimActor -// VTABLE: LEGO1 0x100d58b8 LegoPathActor -// VTABLE: LEGO1 0x100d5984 LegoRaceMap -// VTABLE: LEGO1 0x100d5988 LegoCarRaceActor -// VTABLE: BETA10 0x101be6ec LegoRaceActor -// VTABLE: BETA10 0x101be6f0 LegoAnimActor -// VTABLE: BETA10 0x101be708 LegoPathActor -// VTABLE: BETA10 0x101be7f8 LegoRaceMap -// VTABLE: BETA10 0x101be800 LegoCarRaceActor -// SIZE 0x200 -class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap { -public: - LegoRaceCar(); - ~LegoRaceCar() override; - - MxLong Notify(MxParam& p_param) override; // vtable+0x04 - - // FUNCTION: LEGO1 0x100142a0 - // FUNCTION: BETA10 0x100cd500 - const char* ClassName() const override // vtable+0x0c - { - // STRING: LEGO1 0x100f0548 - return "LegoRaceCar"; - } - - // FUNCTION: LEGO1 0x100142c0 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, LegoRaceCar::ClassName()) || LegoCarRaceActor::IsA(p_name); - } - - void ParseAction(char* p_extra) override; // vtable+0x20 - void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 - MxU32 VTable0x6c( - LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 - ) override; // vtable+0x6c - void Animate(float p_time) override; // vtable+0x70 - MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 - void SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) - override; // vtable+0x98 - MxResult VTable0x9c() override; // vtable+0x9c - - virtual void SetMaxLinearVelocity(float p_maxLinearVelocity); - virtual void FUN_10012ff0(float p_param); - virtual MxU32 HandleSkeletonKicks(float p_param1); - - static void FUN_10012de0(); - static void FUN_10012e00(); - static void FUN_10013670(); - - // SYNTHETIC: LEGO1 0x10014240 - // LegoRaceCar::`scalar deleting destructor' - -private: - undefined m_userState; // 0x54 - float m_unk0x58; // 0x58 - Mx3DPointFloat m_unk0x5c; // 0x5c - - // Names verified by BETA10 0x100cb4a9 - LegoAnimActorStruct* m_skelKick1Anim; // 0x70 - LegoAnimActorStruct* m_skelKick2Anim; // 0x74 - - // Name verified by BETA10 0x100cb4f0 - LegoPathBoundary* m_kick1B; // 0x78 - - // Name verified by BETA10 0x100cb537 - LegoPathBoundary* m_kick2B; // 0x7c -}; - // VTABLE: LEGO1 0x100d5a08 LegoCarRaceActor // VTABLE: LEGO1 0x100d5a28 LegoRaceActor // VTABLE: LEGO1 0x100d5a30 LegoAnimActor @@ -134,19 +59,25 @@ public: void ParseAction(char* p_extra) override; // vtable+0x20 void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 - MxU32 VTable0x6c( - LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 - ) override; // vtable+0x6c + + // FUNCTION: LEGO1 0x10014150 + MxU32 VTable0x6c(LegoPathBoundary* p_boundary, Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3) + override + { + return LegoJetskiRaceActor::VTable0x6c(p_boundary, p_v1, p_v2, p_f1, p_f2, p_v3); + } // vtable+0x6c + void Animate(float p_time) override; // vtable+0x70 MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 - void SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) - override; // vtable+0x98 - MxResult VTable0x9c() override; // vtable+0x9c + + // FUNCTION: LEGO1 0x100141d0 + void SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) override + { + LegoJetskiRaceActor::SwitchBoundary(p_boundary, p_edge, p_unk0xe4); + } // vtable+0x98 + + // FUNCTION: LEGO1 0x10014210 + MxResult VTable0x9c() override { return LegoJetskiRaceActor::VTable0x9c(); } // vtable+0x9c virtual void FUN_100136f0(float p_worldSpeed); @@ -154,6 +85,88 @@ public: // LegoJetski::`scalar deleting destructor' }; +// VTABLE: LEGO1 0x100d58a0 LegoRaceActor +// VTABLE: LEGO1 0x100d58a8 LegoAnimActor +// VTABLE: LEGO1 0x100d58b8 LegoPathActor +// VTABLE: LEGO1 0x100d5984 LegoRaceMap +// VTABLE: LEGO1 0x100d5988 LegoCarRaceActor +// VTABLE: BETA10 0x101be6ec LegoRaceActor +// VTABLE: BETA10 0x101be6f0 LegoAnimActor +// VTABLE: BETA10 0x101be708 LegoPathActor +// VTABLE: BETA10 0x101be7f8 LegoRaceMap +// VTABLE: BETA10 0x101be800 LegoCarRaceActor +// SIZE 0x200 +class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap { +public: + LegoRaceCar(); + ~LegoRaceCar() override; + + MxLong Notify(MxParam& p_param) override; // vtable+0x04 + + // FUNCTION: LEGO1 0x100142a0 + // FUNCTION: BETA10 0x100cd500 + const char* ClassName() const override // vtable+0x0c + { + // STRING: LEGO1 0x100f0548 + return "LegoRaceCar"; + } + + // FUNCTION: LEGO1 0x100142c0 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, LegoRaceCar::ClassName()) || LegoCarRaceActor::IsA(p_name); + } + + void ParseAction(char* p_extra) override; // vtable+0x20 + void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 + + // FUNCTION: LEGO1 0x10014500 + // FUNCTION: BETA10 0x100cd5e0 + MxU32 VTable0x6c(LegoPathBoundary* p_boundary, Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3) + override + { + return LegoCarRaceActor::VTable0x6c(p_boundary, p_v1, p_v2, p_f1, p_f2, p_v3); + } // vtable+0x6c + + void Animate(float p_time) override; // vtable+0x70 + MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + + // FUNCTION: LEGO1 0x10014560 + // FUNCTION: BETA10 0x100cd660 + void SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) override + { + LegoCarRaceActor::SwitchBoundary(p_boundary, p_edge, p_unk0xe4); + } // vtable+0x98 + + MxResult VTable0x9c() override; // vtable+0x9c + + virtual void SetMaxLinearVelocity(float p_maxLinearVelocity); + virtual void FUN_10012ff0(float p_param); + virtual MxU32 HandleSkeletonKicks(float p_param1); + + static void FUN_10012de0(); + static void FUN_10012e00(); + static void FUN_10013670(); + + // SYNTHETIC: LEGO1 0x10014240 + // LegoRaceCar::`scalar deleting destructor' + +private: + undefined m_userState; // 0x54 + float m_unk0x58; // 0x58 + Mx3DPointFloat m_unk0x5c; // 0x5c + + // Names verified by BETA10 0x100cb4a9 + LegoAnimActorStruct* m_skelKick1Anim; // 0x70 + LegoAnimActorStruct* m_skelKick2Anim; // 0x74 + + // Name verified by BETA10 0x100cb4f0 + LegoPathBoundary* m_kick1B; // 0x78 + + // Name verified by BETA10 0x100cb537 + LegoPathBoundary* m_kick2B; // 0x7c +}; + // GLOBAL: LEGO1 0x100d5890 // LegoRaceCar::`vbtable'{for `LegoCarRaceActor'} diff --git a/LEGO1/lego/legoomni/include/legostate.h b/LEGO1/lego/legoomni/include/legostate.h index b8b9c47f..09dc1fcf 100644 --- a/LEGO1/lego/legoomni/include/legostate.h +++ b/LEGO1/lego/legoomni/include/legostate.h @@ -84,22 +84,6 @@ public: // FUNCTION: LEGO1 0x10005f40 ~LegoState() override {} - // FUNCTION: LEGO1 0x100060d0 - // FUNCTION: BETA10 0x10017d20 - const char* ClassName() const override // vtable+0x0c - { - // STRING: LEGO1 0x100f01b8 - // STRING: BETA10 0x101dcdac - return "LegoState"; - } - - // FUNCTION: LEGO1 0x100060e0 - // FUNCTION: BETA10 0x100a9000 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, LegoState::ClassName()) || MxCore::IsA(p_name); - } - // FUNCTION: LEGO1 0x10005f90 virtual MxBool IsSerializable() { return TRUE; } // vtable+0x14 @@ -116,6 +100,22 @@ public: return SUCCESS; } // vtable+0x1c + // FUNCTION: LEGO1 0x100060d0 + // FUNCTION: BETA10 0x10017d20 + const char* ClassName() const override // vtable+0x0c + { + // STRING: LEGO1 0x100f01b8 + // STRING: BETA10 0x101dcdac + return "LegoState"; + } + + // FUNCTION: LEGO1 0x100060e0 + // FUNCTION: BETA10 0x100a9000 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, LegoState::ClassName()) || MxCore::IsA(p_name); + } + // SYNTHETIC: LEGO1 0x10006160 // LegoState::`scalar deleting destructor' }; diff --git a/LEGO1/lego/legoomni/include/score.h b/LEGO1/lego/legoomni/include/score.h index 28a67434..36252f6f 100644 --- a/LEGO1/lego/legoomni/include/score.h +++ b/LEGO1/lego/legoomni/include/score.h @@ -15,6 +15,16 @@ class ScoreState : public LegoState { public: ScoreState() : m_playCubeTutorial(TRUE) {} + // FUNCTION: LEGO1 0x1000de20 + MxBool IsSerializable() override { return FALSE; } // vtable+0x14 + + // FUNCTION: LEGO1 0x1000de30 + MxBool Reset() override + { + m_playCubeTutorial = TRUE; + return TRUE; + } // vtable+0x18 + // FUNCTION: LEGO1 0x1000de40 // FUNCTION: BETA10 0x100a7a70 const char* ClassName() const override // vtable+0x0c @@ -29,16 +39,6 @@ public: return !strcmp(p_name, ScoreState::ClassName()) || LegoState::IsA(p_name); } - // FUNCTION: LEGO1 0x1000de20 - MxBool IsSerializable() override { return FALSE; } // vtable+0x14 - - // FUNCTION: LEGO1 0x1000de30 - MxBool Reset() override - { - m_playCubeTutorial = TRUE; - return TRUE; - } // vtable+0x18 - MxBool GetTutorialFlag() { return m_playCubeTutorial; } void SetTutorialFlag(MxBool p_playCubeTutorial) { m_playCubeTutorial = p_playCubeTutorial; } diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index 52506121..014f03a0 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -200,7 +200,7 @@ void Act2Actor::Animate(float p_time) { int dummy1; // for BETA10, not sure what it is being used for -#ifdef NDEBUG +#ifndef BETA10 MxFloat local48float = 0.0f; if (g_unk0x100f0f1c != 0.0f) { local48float = p_time - g_unk0x100f0f1c; @@ -221,14 +221,14 @@ void Act2Actor::Animate(float p_time) m_unk0x20 = 0; } else { -#ifdef NDEBUG +#ifndef BETA10 m_unk0x20 += local48float; #endif MxMatrix matrix = m_roi->GetLocal2World(); matrix[3][1] += 3.0f; m_roi->UpdateTransformationRelativeToParent(matrix); -#ifdef NDEBUG +#ifndef BETA10 LegoROI* brickstrROI = FindROI("brickstr"); MxMatrix brickstrMatrix = brickstrROI->GetLocal2World(); brickstrMatrix[3][1] += 3.0f; @@ -272,7 +272,7 @@ void Act2Actor::Animate(float p_time) CurrentWorld()->RemoveActor(this); return; } -#ifdef NDEBUG +#ifndef BETA10 else if (m_unk0x1e == 4) { if (m_worldSpeed == 0.0f) { return; @@ -340,7 +340,7 @@ void Act2Actor::Animate(float p_time) FUN_100199f0(0); } else -#ifdef NDEBUG +#ifndef BETA10 if (p_time - m_unk0x24 > 3000.0f) { #endif SetWorldSpeed(m_unk0x28 - 1); @@ -350,7 +350,7 @@ void Act2Actor::Animate(float p_time) if (((LegoAct2*) CurrentWorld())->FUN_100516b0() == SUCCESS) { FUN_100199f0(1); } -#ifdef NDEBUG +#ifndef BETA10 } #endif } @@ -869,13 +869,3 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param) return result; } - -// FUNCTION: LEGO1 0x1001a180 -MxS32 Act2Actor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) -{ - if (m_unk0x1f) { - return 0; - } - - return LegoAnimActor::VTable0x68(p_v1, p_v2, p_v3); -} diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index bdec74e4..7751a828 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -419,7 +419,7 @@ void Helicopter::Animate(float p_time) Vector3 v3(m_unk0x1a8[3]); mat.SetIdentity(); - m_unk0x1f4.BETA_1004aaa0(mat, f2); + m_unk0x1f4.InterpolateToMatrix(mat, f2); v2 = v3; v2 -= v1; @@ -482,9 +482,8 @@ void Helicopter::FUN_100042a0(const Matrix4& p_matrix) m_unk0x1f0 = Timer()->GetTime(); - m_unk0x1f4.BETA_1004a9f0(local48); - m_unk0x1f4.FUN_10004620(local90); - m_unk0x1f4.FUN_10004520(); + m_unk0x1f4.SetStartEnd(local48, local90); + m_unk0x1f4.NormalizeDirection(); } // FUNCTION: LEGO1 0x10004640 diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index 647894b1..26e5c90e 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -361,7 +361,7 @@ void LegoCarBuild::VTable0x70() m_unk0x2a0 = sqrt((MxDouble) DISTSQRD2(m_unk0x290, m_unk0x298)); - m_unk0x25c.BETA_1004a9b0(m_unk0x178, m_unk0x208); + m_unk0x25c.SetStartEnd(m_unk0x178, m_unk0x208); } // FUNCTION: LEGO1 0x10023130 @@ -409,7 +409,7 @@ void LegoCarBuild::FUN_10023130(MxLong p_x, MxLong p_y) MxFloat local1c = sqrt((double) (NORMSQRD2(local20))) / m_unk0x2a0; - m_unk0x25c.BETA_1004aaa0(local78, local1c); + m_unk0x25c.InterpolateToMatrix(local78, local1c); local78[3][0] = m_unk0x178[3][0] + local18[0]; local78[3][1] = m_unk0x178[3][1] + local18[1]; @@ -948,7 +948,7 @@ MxS32 LegoCarBuild::FUN_10024850(MxLong p_x, MxLong p_y) return result; } -#ifdef NDEBUG +#ifndef BETA10 // FUNCTION: LEGO1 0x10024890 undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) @@ -1495,8 +1495,7 @@ void LegoCarBuild::FUN_10025720(undefined4 p_param) m_unk0x10a = 0; MxS32 uVar6; -#ifdef NDEBUG - +#ifndef BETA10 if (GameState()->GetCurrentAct() == LegoGameState::e_act2) { // This is most likely related to the helicopter rebuild in Act 2 switch (p_param) { @@ -1598,7 +1597,7 @@ void LegoCarBuild::FUN_10025720(undefined4 p_param) assert(m_numAnimsRun >= 0); return; } -#ifdef NDEBUG +#ifndef BETA10 } #endif diff --git a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp index 602eb746..b3512838 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp @@ -149,7 +149,7 @@ void LegoCarBuildAnimPresenter::ReadyTickle() return; } -#ifdef NDEBUG +#ifndef BETA10 if (!m_anim) { return; } diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 43de0b67..d502fcae 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -2800,8 +2800,8 @@ void LegoAnimationManager::FUN_100648f0(LegoTranInfo* p_tranInfo, MxLong p_unk0x LegoLocation* location = NavController()->GetLocation(p_tranInfo->m_location); if (location != NULL) { CalcLocalTransform(location->m_position, location->m_direction, location->m_up, m_unk0x484); - m_unk0x4cc.BETA_1004a9b0(m_unk0x43c, m_unk0x484); - m_unk0x4cc.FUN_10004520(); + m_unk0x4cc.SetStartEnd(m_unk0x43c, m_unk0x484); + m_unk0x4cc.NormalizeDirection(); } else { p_tranInfo->m_flags &= ~LegoTranInfo::c_bit1; @@ -2835,7 +2835,7 @@ void LegoAnimationManager::FUN_10064b50(MxLong p_time) sub[1] = (m_unk0x484[3][1] - m_unk0x43c[3][1]) * und; sub[2] = (m_unk0x484[3][2] - m_unk0x43c[3][2]) * und; - m_unk0x4cc.BETA_1004aaa0(mat, (float) (p_time - m_unk0x434) / 1000.0f); + m_unk0x4cc.InterpolateToMatrix(mat, (float) (p_time - m_unk0x434) / 1000.0f); VPV3(mat[3], m_unk0x43c[3], sub); mat[3][3] = 1.0f; diff --git a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp index 53041cde..61c02d03 100644 --- a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp @@ -17,6 +17,7 @@ #include "viewmanager/viewmanager.h" #include <SDL3/SDL_stdinc.h> +#include <assert.h> #include <stdio.h> #include <vec.h> @@ -54,10 +55,11 @@ MxU32 g_unk0x100fc4f0 = 0; LegoActorInfo g_actorInfo[66]; // FUNCTION: LEGO1 0x10082a20 +// FUNCTION: BETA10 0x10073c60 LegoCharacterManager::LegoCharacterManager() { m_characters = new LegoCharacterMap(); - Init(); + Init(); // DECOMP: inlined here in BETA10 m_customizeAnimFile = new CustomizeAnimFileVariable("CUSTOMIZE_ANIM_FILE"); VariableTable()->SetVariable(m_customizeAnimFile); @@ -230,8 +232,9 @@ const char* LegoCharacterManager::GetActorName(MxS32 p_index) if (p_index < sizeOfArray(g_actorInfo)) { return g_actorInfo[p_index].m_name; } - - return NULL; + else { + return NULL; + } } // FUNCTION: LEGO1 0x100834f0 @@ -246,9 +249,9 @@ MxU32 LegoCharacterManager::GetNumActors() LegoROI* LegoCharacterManager::GetActorROI(const char* p_name, MxBool p_createEntity) { LegoCharacter* character = NULL; - LegoCharacterMap::iterator it = m_characters->find(const_cast<char*>(p_name)); + LegoCharacterMap::const_iterator it = m_characters->find(const_cast<char*>(p_name)); - if (it != m_characters->end()) { + if (!(it == m_characters->end())) { character = (*it).second; character->AddRef(); } @@ -256,13 +259,9 @@ LegoROI* LegoCharacterManager::GetActorROI(const char* p_name, MxBool p_createEn if (character == NULL) { LegoROI* roi = CreateActorROI(p_name); - if (roi == NULL) { - goto done; - } - - roi->SetVisibility(FALSE); - if (roi != NULL) { + roi->SetVisibility(FALSE); + character = new LegoCharacter(roi); char* name = new char[strlen(p_name) + 1]; @@ -278,7 +277,6 @@ LegoROI* LegoCharacterManager::GetActorROI(const char* p_name, MxBool p_createEn VideoManager()->Get3DManager()->Add(*character->m_roi); } -done: if (character != NULL) { if (p_createEntity && character->m_roi->GetEntity() == NULL) { LegoExtraActor* actor = new LegoExtraActor(); @@ -291,15 +289,15 @@ done: return character->m_roi; } - - return NULL; + else { + return NULL; + } } // FUNCTION: LEGO1 0x10083b20 // FUNCTION: BETA10 0x10074608 MxBool LegoCharacterManager::Exists(const char* p_name) { - LegoCharacter* character = NULL; LegoCharacterMap::iterator it = m_characters->find(const_cast<char*>(p_name)); if (it != m_characters->end()) { @@ -456,6 +454,7 @@ void LegoCharacterManager::RemoveROI(LegoROI* p_roi) } // FUNCTION: LEGO1 0x10084030 +// FUNCTION: BETA10 0x10074e4f LegoROI* LegoCharacterManager::CreateActorROI(const char* p_key) { MxBool success = FALSE; @@ -603,7 +602,7 @@ done: // FUNCTION: LEGO1 0x100849a0 // FUNCTION: BETA10 0x10075b51 -MxBool LegoCharacterManager::FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_textureInfo) +MxBool LegoCharacterManager::FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_texture) { LegoResult result = SUCCESS; LegoROI* head = FindChildROI(p_roi, g_actorLODs[c_headLOD].m_name); @@ -612,24 +611,30 @@ MxBool LegoCharacterManager::FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_tex char lodName[256]; ViewLODList* lodList = GetViewLODListManager()->Lookup(g_actorLODs[c_headLOD].m_parentName); + assert(lodList); + MxS32 lodSize = lodList->Size(); sprintf(lodName, "%s%s%d", p_roi->GetName(), "head", g_unk0x100fc4e8++); ViewLODList* dupLodList = GetViewLODListManager()->Create(lodName, lodSize); + assert(dupLodList); Tgl::Renderer* renderer = VideoManager()->GetRenderer(); - if (p_textureInfo == NULL) { + if (p_texture == NULL) { LegoActorInfo* info = GetActorInfo(p_roi->GetName()); + assert(info); + LegoActorInfo::Part& part = info->m_parts[c_headPart]; - p_textureInfo = TextureContainer()->Get(part.m_unk0x10[part.m_unk0x0c[part.m_unk0x14]]); + p_texture = TextureContainer()->Get(part.m_unk0x10[part.m_unk0x0c[part.m_unk0x14]]); + assert(p_texture); } for (MxS32 i = 0; i < lodSize; i++) { LegoLOD* lod = (LegoLOD*) (*lodList)[i]; LegoLOD* clone = lod->Clone(renderer); - if (p_textureInfo != NULL) { - clone->FUN_100aad70(p_textureInfo); + if (p_texture != NULL) { + clone->FUN_100aad70(p_texture); } dupLodList->PushBack(clone); @@ -674,6 +679,7 @@ LegoExtraActor* LegoCharacterManager::GetExtraActor(const char* p_name) } // FUNCTION: LEGO1 0x10084c60 +// FUNCTION: BETA10 0x10075ede LegoActorInfo* LegoCharacterManager::GetActorInfo(const char* p_name) { MxU32 i; @@ -687,11 +693,13 @@ LegoActorInfo* LegoCharacterManager::GetActorInfo(const char* p_name) if (i < sizeOfArray(g_actorInfo)) { return &g_actorInfo[i]; } - - return NULL; + else { + return NULL; + } } // FUNCTION: LEGO1 0x10084cb0 +// FUNCTION: BETA10 0x10075f66 LegoActorInfo* LegoCharacterManager::GetActorInfo(LegoROI* p_roi) { MxU32 i; @@ -705,21 +713,24 @@ LegoActorInfo* LegoCharacterManager::GetActorInfo(LegoROI* p_roi) if (i < sizeOfArray(g_actorInfo)) { return &g_actorInfo[i]; } - - return NULL; + else { + return NULL; + } } // FUNCTION: LEGO1 0x10084cf0 // FUNCTION: BETA10 0x10075fe2 LegoROI* LegoCharacterManager::FindChildROI(LegoROI* p_roi, const char* p_name) { +#ifdef COMPAT_MODE + CompoundObject::const_iterator it; +#else + CompoundObject::iterator it; +#endif + const CompoundObject* comp = p_roi->GetComp(); -#ifdef COMPAT_MODE - for (CompoundObject::const_iterator it = comp->begin(); !(it == comp->end()); it++) { -#else - for (CompoundObject::iterator it = comp->begin(); !(it == comp->end()); it++) { -#endif + for (it = comp->begin(); it != comp->end(); it++) { LegoROI* roi = (LegoROI*) *it; if (!SDL_strcasecmp(p_name, roi->GetName())) { @@ -913,11 +924,13 @@ MxU32 LegoCharacterManager::GetAnimationId(LegoROI* p_roi) if (info != NULL) { return info->m_move + g_characterAnimationId; } - - return 0; + else { + return 0; + } } // FUNCTION: LEGO1 0x10085140 +// FUNCTION: BETA10 0x10076855 MxU32 LegoCharacterManager::GetSoundId(LegoROI* p_roi, MxBool p_und) { LegoActorInfo* info = GetActorInfo(p_roi); @@ -929,8 +942,9 @@ MxU32 LegoCharacterManager::GetSoundId(LegoROI* p_roi, MxBool p_und) if (info != NULL) { return info->m_sound + g_unk0x100fc4d8; } - - return 0; + else { + return 0; + } } // FUNCTION: LEGO1 0x10085180 @@ -942,8 +956,9 @@ MxU8 LegoCharacterManager::GetMood(LegoROI* p_roi) if (info != NULL) { return info->m_mood; } - - return 0; + else { + return 0; + } } // FUNCTION: LEGO1 0x100851a0 diff --git a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp index b5c4f521..06bf7746 100644 --- a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp +++ b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp @@ -1,5 +1,36 @@ #include "legoobjectfactory.h" +// Headers need to be included in a certain order to match the original binary. +// Some of the following headers were probably not directly included, +// but were included from one of the higher level classes. We should attempt +// to reverse engineer the inclusion "graph" at some point. Until then, to maintain +// correct order in the binary, we include them in the order we want here. +// clang-format off +#include "mxpresenter.h" +#include "legoentity.h" +#include "legopathactor.h" +// The below header inclusions should be sound. +#include "legoloopinganimpresenter.h" +#include "mxcompositemediapresenter.h" +#include "legoactorpresenter.h" +#include "legomodelpresenter.h" +#include "legotexturepresenter.h" +#include "legopartpresenter.h" +#include "legoactioncontrolpresenter.h" +#include "lego3dwavepresenter.h" +#include "jetskirace.h" +#include "carrace.h" +#include "score.h" +#include "legoact2.h" +#include "helicopter.h" +#include "act2policestation.h" +#include "act3.h" +#include "doors.h" +#include "pizzeria.h" +#include "buildings.h" +#include "jukebox.h" +// clang-format on + #include "act2actor.h" #include "act2brick.h" #include "act2genactor.h" diff --git a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp index 52e58567..cda15379 100644 --- a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp +++ b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp @@ -101,7 +101,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ } if (VTable0x80(m_roi->GetWorldPosition(), worldDirection, a, c)) { -#ifdef NDEBUG +#ifndef BETA10 m_unk0x7c = 0; return 0; #else diff --git a/LEGO1/lego/legoomni/src/race/legorace.cpp b/LEGO1/lego/legoomni/src/race/legorace.cpp index 355e2914..de895ad5 100644 --- a/LEGO1/lego/legoomni/src/race/legorace.cpp +++ b/LEGO1/lego/legoomni/src/race/legorace.cpp @@ -35,24 +35,6 @@ LegoRace::LegoRace() NotificationManager()->Register(this); } -// FUNCTION: LEGO1 0x10015b70 -MxLong LegoRace::HandlePathStruct(LegoPathStructNotificationParam&) -{ - return 0; -} - -// FUNCTION: LEGO1 0x10015b80 -MxLong LegoRace::HandleEndAction(MxEndActionNotificationParam&) -{ - return 0; -} - -// FUNCTION: LEGO1 0x10015b90 -MxBool LegoRace::Escape() -{ - return FALSE; -} - // FUNCTION: LEGO1 0x10015ce0 // FUNCTION: BETA10 0x100c7a71 MxResult LegoRace::Create(MxDSAction& p_dsAction) diff --git a/LEGO1/lego/legoomni/src/race/legoraceactor.cpp b/LEGO1/lego/legoomni/src/race/legoraceactor.cpp index a8a7fccd..92c99d4f 100644 --- a/LEGO1/lego/legoomni/src/race/legoraceactor.cpp +++ b/LEGO1/lego/legoomni/src/race/legoraceactor.cpp @@ -116,3 +116,10 @@ MxResult LegoRaceActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) return SUCCESS; } + +// FUNCTION: LEGO1 0x10014aa0 +// FUNCTION: BETA10 0x100ca038 +MxResult LegoRaceActor::FUN_10014aa0() +{ + return SUCCESS; +} diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index f941da66..7ed56012 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -170,11 +170,6 @@ undefined4 g_hitValerieSoundsIndex = 0; // GLOBAL: LEGO1 0x100f0bb4 MxLong g_unk0x100f0bb4 = 0; -// Initialized at LEGO1 0x10012db0 -// GLOBAL: LEGO1 0x10102af0 -// GLOBAL: BETA10 0x102114c0 -Mx3DPointFloat g_unk0x10102af0 = Mx3DPointFloat(0.0f, 2.0f, 0.0f); - // FUNCTION: LEGO1 0x10012950 LegoRaceCar::LegoRaceCar() { @@ -200,6 +195,11 @@ MxLong LegoRaceCar::Notify(MxParam& p_param) return LegoRaceMap::Notify(p_param); } +// Initialized at LEGO1 0x10012db0 +// GLOBAL: LEGO1 0x10102af0 +// GLOBAL: BETA10 0x102114c0 +Mx3DPointFloat g_unk0x10102af0 = Mx3DPointFloat(0.0f, 2.0f, 0.0f); + // FUNCTION: LEGO1 0x10012de0 void LegoRaceCar::FUN_10012de0() { @@ -730,49 +730,3 @@ MxResult LegoJetski::HitActor(LegoPathActor* p_actor, MxBool p_bool) return SUCCESS; } - -// FUNCTION: LEGO1 0x10014150 -MxU32 LegoJetski::VTable0x6c( - LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 -) -{ - return LegoJetskiRaceActor::VTable0x6c(p_boundary, p_v1, p_v2, p_f1, p_f2, p_v3); -} - -// FUNCTION: LEGO1 0x100141d0 -void LegoJetski::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) -{ - LegoJetskiRaceActor::SwitchBoundary(p_boundary, p_edge, p_unk0xe4); -} - -// FUNCTION: LEGO1 0x10014210 -MxResult LegoJetski::VTable0x9c() -{ - return LegoJetskiRaceActor::VTable0x9c(); -} - -// FUNCTION: LEGO1 0x10014500 -// FUNCTION: BETA10 0x100cd5e0 -MxU32 LegoRaceCar::VTable0x6c( - LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 -) -{ - return LegoCarRaceActor::VTable0x6c(p_boundary, p_v1, p_v2, p_f1, p_f2, p_v3); -} - -// FUNCTION: LEGO1 0x10014560 -// FUNCTION: BETA10 0x100cd660 -void LegoRaceCar::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) -{ - LegoCarRaceActor::SwitchBoundary(p_boundary, p_edge, p_unk0xe4); -} diff --git a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp index 60035519..c6294048 100644 --- a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp @@ -272,7 +272,7 @@ MxResult LegoCarRaceActor::VTable0x9c() MxResult res = VTable0x80(m_roi->GetWorldPosition(), point4, point1, point5); -#ifndef NDEBUG // BETA10 only +#ifdef BETA10 if (res) { assert(0); return -1; diff --git a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp index f85c2197..84e0ab24 100644 --- a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp @@ -26,12 +26,6 @@ DECOMP_SIZE_ASSERT(LegoModelPresenter, 0x6c) // GLOBAL: LEGO1 0x100f7ae0 MxS32 g_modelPresenterConfig = 1; -// FUNCTION: LEGO1 0x1000cca0 -void LegoModelPresenter::Destroy() -{ - Destroy(FALSE); -} - // FUNCTION: LEGO1 0x1007f660 void LegoModelPresenter::configureLegoModelPresenter(MxS32 p_modelPresenterConfig) { diff --git a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp index 9a70c5e6..216b7e4e 100644 --- a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp @@ -22,12 +22,6 @@ MxS32 g_partPresenterConfig1 = 1; // GLOBAL: LEGO1 0x100f7aa4 MxS32 g_partPresenterConfig2 = 100; -// FUNCTION: LEGO1 0x1000cf60 -void LegoPartPresenter::Destroy() -{ - Destroy(FALSE); -} - // FUNCTION: LEGO1 0x1007c990 void LegoPartPresenter::configureLegoPartPresenter(MxS32 p_partPresenterConfig1, MxS32 p_partPresenterConfig2) { diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index 8e8f34bf..94d20dbd 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -8,12 +8,12 @@ #include "mxdirectx/mxdirect3d.h" #include "mxdirectx/mxstopwatch.h" #include "mxdisplaysurface.h" +#include "mxgeometry/mxmatrix.h" #include "mxmisc.h" #include "mxpalette.h" #include "mxregion.h" #include "mxtimer.h" #include "mxtransitionmanager.h" -#include "realtime/matrix.h" #include "realtime/realtime.h" #include "roi/legoroi.h" #include "tgl/d3drm/impl.h" diff --git a/LEGO1/lego/legoomni/src/worlds/act3.cpp b/LEGO1/lego/legoomni/src/worlds/act3.cpp index ad0d03d6..6a74b64f 100644 --- a/LEGO1/lego/legoomni/src/worlds/act3.cpp +++ b/LEGO1/lego/legoomni/src/worlds/act3.cpp @@ -800,7 +800,7 @@ void Act3::DebugCopter( const Matrix4& p_destination, const Matrix4& p_startPosition, const Matrix4& p_endPosition, - const UnknownMx4DPointFloat& p_unk0x1f4 + const MxQuaternionTransformer& p_unk0x1f4 ) { DebugPrintf("Copter matrix...\n\n"); @@ -832,10 +832,10 @@ void Act3::DebugCopter( Mx4DPointFloat unk0x00, unk0x18; - if (p_unk0x1f4.GetUnknown0x30() != 0) { + if (p_unk0x1f4.GetFlags() != 0) { // TODO: Match - unk0x00 = p_unk0x1f4.GetUnknown0x00(); - unk0x18 = p_unk0x1f4.GetUnknown0x18(); + unk0x00 = p_unk0x1f4.GetStartQuat(); + unk0x18 = p_unk0x1f4.GetEndQuat(); DebugPrintf("Source quaternion..."); // STRING: LEGO1 0x100f7864 diff --git a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp index 9456f83d..0207973a 100644 --- a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp +++ b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp @@ -50,12 +50,6 @@ GasStation::GasStation() NotificationManager()->Register(this); } -// FUNCTION: LEGO1 0x10004770 -MxBool GasStation::VTable0x5c() -{ - return TRUE; -} - // FUNCTION: LEGO1 0x100048c0 GasStation::~GasStation() { @@ -71,6 +65,7 @@ GasStation::~GasStation() } // FUNCTION: LEGO1 0x10004990 +// FUNCTION: BETA10 0x100286c0 MxResult GasStation::Create(MxDSAction& p_dsAction) { MxResult result = LegoWorld::Create(p_dsAction); @@ -84,13 +79,13 @@ MxResult GasStation::Create(MxDSAction& p_dsAction) m_state = (GasStationState*) GameState()->GetState("GasStationState"); if (!m_state) { m_state = (GasStationState*) GameState()->CreateState("GasStationState"); - m_state->m_unk0x14.m_unk0x00 = 1; + m_state->m_unk0x14 = 1; } - else if (m_state->m_unk0x14.m_unk0x00 == 4) { - m_state->m_unk0x14.m_unk0x00 = 4; + else if (m_state->m_unk0x14 == 4) { + m_state->m_unk0x14 = 4; } else { - m_state->m_unk0x14.m_unk0x00 = 3; + m_state->m_unk0x14 = 3; } GameState()->m_currentArea = LegoGameState::e_garage; @@ -124,6 +119,7 @@ MxLong GasStation::Notify(MxParam& p_param) result = HandleControl((LegoControlManagerNotificationParam&) p_param); break; case c_notificationTransitioned: + assert(m_destLocation != LegoGameState::e_undefined); GameState()->SwitchArea(m_destLocation); break; } @@ -133,6 +129,7 @@ MxLong GasStation::Notify(MxParam& p_param) } // FUNCTION: LEGO1 0x10004b30 +// FUNCTION: BETA10 0x10028a5e void GasStation::ReadyWorld() { PlayMusic(JukeboxScript::c_JBMusic2); @@ -144,22 +141,22 @@ void GasStation::ReadyWorld() case LegoActor::c_pepper: switch (m_state->m_pepperAction) { case 0: - m_state->m_unk0x14.m_unk0x00 = 5; + m_state->m_unk0x14 = 5; PlayAction(GarageScript::c_wgs002nu_RunAnim); m_unk0x106 = 1; break; case 1: - m_state->m_unk0x14.m_unk0x00 = 5; + m_state->m_unk0x14 = 5; PlayAction(GarageScript::c_wgs003nu_RunAnim); m_unk0x106 = 1; break; case 2: - m_state->m_unk0x14.m_unk0x00 = 5; + m_state->m_unk0x14 = 5; PlayAction(GarageScript::c_wgs004nu_RunAnim); m_unk0x106 = 1; break; default: - m_state->m_unk0x14.m_unk0x00 = 6; + m_state->m_unk0x14 = 6; PlayAction(GarageScript::c_wgs008nu_RunAnim); m_unk0x106 = 1; m_unk0x104 = 1; @@ -169,23 +166,21 @@ void GasStation::ReadyWorld() if (m_state->m_pepperAction < 5) { m_state->m_pepperAction++; } - - FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); break; case LegoActor::c_mama: switch (m_state->m_mamaAction) { case 0: - m_state->m_unk0x14.m_unk0x00 = 5; + m_state->m_unk0x14 = 5; PlayAction(GarageScript::c_wgs006nu_RunAnim); m_unk0x106 = 1; break; case 1: - m_state->m_unk0x14.m_unk0x00 = 5; + m_state->m_unk0x14 = 5; PlayAction(GarageScript::c_wgs007nu_RunAnim); m_unk0x106 = 1; break; default: - m_state->m_unk0x14.m_unk0x00 = 6; + m_state->m_unk0x14 = 6; PlayAction(GarageScript::c_wgs008nu_RunAnim); m_unk0x106 = 1; m_unk0x104 = 1; @@ -195,49 +190,21 @@ void GasStation::ReadyWorld() if (m_state->m_mamaAction < 5) { m_state->m_mamaAction++; } - - FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); - break; - case LegoActor::c_papa: - switch (m_state->m_papaAction) { - case 0: - m_state->m_unk0x14.m_unk0x00 = 5; - PlayAction(GarageScript::c_wgs012nu_RunAnim); - m_unk0x106 = 1; - break; - case 1: - m_state->m_unk0x14.m_unk0x00 = 5; - PlayAction(GarageScript::c_wgs014nu_RunAnim); - m_unk0x106 = 1; - break; - default: - m_state->m_unk0x14.m_unk0x00 = 6; - PlayAction(GarageScript::c_wgs017nu_RunAnim); - m_unk0x106 = 1; - m_unk0x104 = 1; - break; - } - - if (m_state->m_papaAction < 5) { - m_state->m_papaAction++; - } - - FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); break; case LegoActor::c_nick: switch (m_state->m_nickAction) { case 0: - m_state->m_unk0x14.m_unk0x00 = 5; + m_state->m_unk0x14 = 5; PlayAction(GarageScript::c_wgs009nu_RunAnim); m_unk0x106 = 1; break; case 1: - m_state->m_unk0x14.m_unk0x00 = 5; + m_state->m_unk0x14 = 5; PlayAction(GarageScript::c_wgs010nu_RunAnim); m_unk0x106 = 1; break; default: - m_state->m_unk0x14.m_unk0x00 = 6; + m_state->m_unk0x14 = 6; PlayAction(GarageScript::c_wgs008nu_RunAnim); m_unk0x106 = 1; m_unk0x104 = 1; @@ -247,23 +214,45 @@ void GasStation::ReadyWorld() if (m_state->m_nickAction < 5) { m_state->m_nickAction++; } + break; + case LegoActor::c_papa: + switch (m_state->m_papaAction) { + case 0: + m_state->m_unk0x14 = 5; + PlayAction(GarageScript::c_wgs012nu_RunAnim); + m_unk0x106 = 1; + break; + case 1: + m_state->m_unk0x14 = 5; + PlayAction(GarageScript::c_wgs014nu_RunAnim); + m_unk0x106 = 1; + break; + default: + m_state->m_unk0x14 = 6; + PlayAction(GarageScript::c_wgs017nu_RunAnim); + m_unk0x106 = 1; + m_unk0x104 = 1; + break; + } - FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); + if (m_state->m_papaAction < 5) { + m_state->m_papaAction++; + } break; case LegoActor::c_laura: switch (m_state->m_lauraAction) { case 0: - m_state->m_unk0x14.m_unk0x00 = 5; + m_state->m_unk0x14 = 5; PlayAction(GarageScript::c_wgs020nu_RunAnim); m_unk0x106 = 1; break; case 1: - m_state->m_unk0x14.m_unk0x00 = 5; + m_state->m_unk0x14 = 5; PlayAction(GarageScript::c_wgs021nu_RunAnim); m_unk0x106 = 1; break; default: - m_state->m_unk0x14.m_unk0x00 = 6; + m_state->m_unk0x14 = 6; PlayAction(GarageScript::c_wgs022nu_RunAnim); m_unk0x106 = 1; m_unk0x104 = 1; @@ -273,13 +262,12 @@ void GasStation::ReadyWorld() if (m_state->m_lauraAction < 5) { m_state->m_lauraAction++; } - - FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); break; default: - FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); break; } + + FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); } // FUNCTION: LEGO1 0x10005590 @@ -317,10 +305,10 @@ MxLong GasStation::HandleEndAction(MxEndActionNotificationParam& p_param) m_state->StopAction((GarageScript::Script) action->GetObjectId()); m_unk0x106 = 0; - switch (m_state->m_unk0x14.m_unk0x00) { + switch (m_state->m_unk0x14) { case 5: g_unk0x100f0160 = 0; - m_state->m_unk0x14.m_unk0x00 = 6; + m_state->m_unk0x14 = 6; m_unk0x115 = TRUE; PlayAction(GarageScript::c_wgs023nu_RunAnim); m_unk0x106 = 1; @@ -331,17 +319,17 @@ MxLong GasStation::HandleEndAction(MxEndActionNotificationParam& p_param) m_unk0x115 = TRUE; if (m_unk0x104 == 3) { - m_state->m_unk0x14.m_unk0x00 = 8; + m_state->m_unk0x14 = 8; PlayAction(GarageScript::c_wgs029nu_RunAnim); m_unk0x106 = 1; } else { - m_state->m_unk0x14.m_unk0x00 = 7; + m_state->m_unk0x14 = 7; m_unk0x114 = TRUE; } break; case 8: - m_state->m_unk0x14.m_unk0x00 = 2; + m_state->m_unk0x14 = 2; ((Act1State*) GameState()->GetState("Act1State"))->m_unk0x018 = 7; m_destLocation = LegoGameState::e_unk28; m_radio.Stop(); @@ -380,8 +368,8 @@ MxLong GasStation::HandleButtonDown(LegoControlManagerNotificationParam& p_param m_unk0x104 = 3; m_unk0x114 = FALSE; - if (m_state->m_unk0x14.m_unk0x00 == 7) { - m_state->m_unk0x14.m_unk0x00 = 8; + if (m_state->m_unk0x14 == 7) { + m_state->m_unk0x14 = 8; PlayAction(GarageScript::c_wgs029nu_RunAnim); m_unk0x106 = 1; } @@ -407,7 +395,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param) switch (p_param.GetClickedObjectId()) { case GarageScript::c_LeftArrow_Ctl: case GarageScript::c_RightArrow_Ctl: - m_state->m_unk0x14.m_unk0x00 = 0; + m_state->m_unk0x14 = 0; m_destLocation = LegoGameState::Area::e_garadoor; m_state->StopActions(); @@ -416,7 +404,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param) TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); break; case GarageScript::c_Info_Ctl: - m_state->m_unk0x14.m_unk0x00 = 0; + m_state->m_unk0x14 = 0; m_destLocation = LegoGameState::Area::e_infomain; m_state->StopActions(); @@ -425,7 +413,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param) TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); break; case GarageScript::c_Buggy_Ctl: - m_state->m_unk0x14.m_unk0x00 = 0; + m_state->m_unk0x14 = 0; m_destLocation = LegoGameState::Area::e_dunecarbuild; m_state->StopActions(); @@ -480,7 +468,7 @@ MxResult GasStation::Tickle() else if (m_unk0x104 != 0) { m_unk0x104 = 0; MxDSAction action; - m_state->m_unk0x14.m_unk0x00 = 9; + m_state->m_unk0x14 = 9; PlayAction(GarageScript::c_wgs031nu_RunAnim); m_unk0x106 = 1; } @@ -503,7 +491,7 @@ MxBool GasStation::Escape() { m_radio.Stop(); m_state->StopActions(); - m_state->m_unk0x14.m_unk0x00 = 0; + m_state->m_unk0x14 = 0; m_destLocation = LegoGameState::Area::e_infomain; return TRUE; } diff --git a/LEGO1/lego/sources/anim/legoanim.cpp b/LEGO1/lego/sources/anim/legoanim.cpp index 39b8921b..562601a5 100644 --- a/LEGO1/lego/sources/anim/legoanim.cpp +++ b/LEGO1/lego/sources/anim/legoanim.cpp @@ -1,6 +1,7 @@ #include "legoanim.h" #include "mxgeometry/mxmatrix.h" +#include "mxgeometry/mxquaternion.h" #include <limits.h> @@ -851,7 +852,7 @@ inline void LegoAnimNodeData::GetTranslation( break; case 2: Mx4DPointFloat a; - UnknownMx4DPointFloat b; + MxQuaternionTransformer b; if (p_rotationKeys[i].TestBit1() || p_rotationKeys[i + 1].TestBit1()) { a[0] = p_rotationKeys[i].GetX(); @@ -878,9 +879,9 @@ inline void LegoAnimNodeData::GetTranslation( c[3] = p_rotationKeys[i + 1].GetAngle(); } - b.BETA_10180b80(a); - b.BETA_10180bc0(c); - b.BETA_1004aaa0( + b.SetStart(a); + b.SetEnd(c); + b.InterpolateToMatrix( p_matrix, (p_time - p_rotationKeys[i].GetTime()) / (p_rotationKeys[i + 1].GetTime() - p_rotationKeys[i].GetTime()) ); diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index 77567bfe..350e31b7 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -4,6 +4,7 @@ #include "decomp.h" #include "legoweedge.h" #include "mxgeometry/mxgeometry3d.h" +#include "mxgeometry/mxgeometry4d.h" class LegoPathStruct; diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index b1a6a9a0..edd378d3 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -4,6 +4,7 @@ #include "legolod.h" #include "misc/legocontainer.h" #include "misc/legostorage.h" +#include "mxgeometry/mxgeometry4d.h" #include "realtime/realtime.h" #include "shape/legobox.h" #include "shape/legosphere.h" diff --git a/LEGO1/library_msvc.h b/LEGO1/library_msvc.h index 38e19a29..d420ffc0 100644 --- a/LEGO1/library_msvc.h +++ b/LEGO1/library_msvc.h @@ -639,6 +639,15 @@ // GLOBAL: LEGO1 0x101028da // __OP_POWjmptab +// GLOBAL: LEGO1 0x1010292a +// __OP_LOG10jmptab + +// GLOBAL: LEGO1 0x1010294a +// __OP_LOGjmptab + +// GLOBAL: LEGO1 0x1010296a +// __OP_EXPjmptab + // GLOBAL: LEGO1 0x101095f8 // __crtheap diff --git a/LEGO1/library_smack.h b/LEGO1/library_smack.h index 8571011f..0967aeab 100644 --- a/LEGO1/library_smack.h +++ b/LEGO1/library_smack.h @@ -12,6 +12,13 @@ // LIBRARY: BETA10 0x1015fe83 // _SmackDoFrameToBuffer +// LIBRARY: LEGO1 0x100cea58 +// LIBRARY: BETA10 0x10160e58 +// _SmackDoFrameToVESA + +// LIBRARY: LEGO1 0x100cfd90 +// _SmackDoPCM + // LIBRARY: LEGO1 0x100d052c // LIBRARY: BETA10 0x1016292c // _SmackGetSizeDeltas @@ -20,4 +27,7 @@ // LIBRARY: BETA10 0x10162943 // _SmackGetRect +// LIBRARY: LEGO1 0x100d0654 +// _SmackRemapTables + #endif diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index 1b41d03e..578d31b2 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -2,8 +2,7 @@ #define MXGEOMETRY3D_H #include "decomp.h" -#include "realtime/matrix.h" -#include "realtime/vector.h" +#include "realtime/vector3d.inl.h" // VTABLE: LEGO1 0x100d4488 // VTABLE: BETA10 0x101b84d0 @@ -53,199 +52,4 @@ private: float m_elements[3]; // 0x08 }; -// VTABLE: LEGO1 0x100d41e8 -// VTABLE: BETA10 0x101bab78 -// SIZE 0x18 -class Mx4DPointFloat : public Vector4 { -public: - // FUNCTION: LEGO1 0x10048290 - // FUNCTION: BETA10 0x100484c0 - Mx4DPointFloat() : Vector4(m_elements) {} - - // FUNCTION: BETA10 0x10073bb0 - Mx4DPointFloat(float p_x, float p_y, float p_z, float p_a) : Vector4(m_elements) - { - m_elements[0] = p_x; - m_elements[1] = p_y; - m_elements[2] = p_z; - m_elements[3] = p_a; - } - - Mx4DPointFloat(const Mx4DPointFloat& p_other) : Vector4(m_elements) { EqualsImpl(p_other.m_data); } - - // FUNCTION: LEGO1 0x10003200 - virtual void operator=(const Vector4& p_impl) { EqualsImpl(p_impl.m_data); } // vtable+0x98 - - // FUNCTION: BETA10 0x1004af10 - float& operator[](int idx) { return m_data[idx]; } - - // According to the PDB, BETA10 will not link this one if it is never used - // const float& operator[](int idx) const { return m_data[idx]; } - - // only used by a couple of BETA10 functions for some unknown reason - // FUNCTION: BETA10 0x1001c950 - float& index_operator(int idx) { return m_data[idx]; } - - // SYNTHETIC: LEGO1 0x10064b20 - // SYNTHETIC: BETA10 0x10070420 - // ??4Mx4DPointFloat@@QAEAAV0@ABV0@@Z - -private: - float m_elements[4]; // 0x08 -}; - -// SIZE 0x34 -class UnknownMx4DPointFloat { -public: - enum { - c_bit1 = 0x01, - c_bit2 = 0x02 - }; - - UnknownMx4DPointFloat() : m_unk0x30(0) {} - - // FUNCTION: BETA10 0x1004a9b0 - void BETA_1004a9b0(Matrix4& p_m1, Matrix4& p_m2) - { - BETA_1004a9f0(p_m1); - FUN_10004620(p_m2); - } - - // FUNCTION: BETA10 0x1004a9f0 - void BETA_1004a9f0(Matrix4& p_m) - { - p_m.ToQuaternion(m_unk0x00); - m_unk0x30 |= c_bit1; - } - - // FUNCTION: LEGO1 0x10004620 - // FUNCTION: BETA10 0x1004aa30 - void FUN_10004620(Matrix4& p_m) - { - p_m.ToQuaternion(m_unk0x18); - m_unk0x30 |= c_bit2; - } - - // FUNCTION: BETA10 0x10180b80 - void BETA_10180b80(Vector4& p_v) - { - m_unk0x00 = p_v; - m_unk0x30 |= c_bit1; - } - - // FUNCTION: BETA10 0x10180bc0 - void BETA_10180bc0(Vector4& p_v) - { - m_unk0x18 = p_v; - m_unk0x30 |= c_bit2; - } - - const Vector4& GetUnknown0x00() const { return m_unk0x00; } - const Vector4& GetUnknown0x18() const { return m_unk0x18; } - undefined4 GetUnknown0x30() const { return m_unk0x30; } - - inline int BETA_1004aaa0(Matrix4& p_matrix, float p_f); - inline long FUN_10004520(); - -private: - inline int FUN_100040a0(Vector4& p_v, float p_f); - - Mx4DPointFloat m_unk0x00; // 0x00 - Mx4DPointFloat m_unk0x18; // 0x18 - undefined4 m_unk0x30; // 0x30 -}; - -// FUNCTION: BETA10 0x1004aaa0 -inline int UnknownMx4DPointFloat::BETA_1004aaa0(Matrix4& p_matrix, float p_f) -{ - float data[4]; - Vector4 v(data); - - if (FUN_100040a0(v, p_f) == 0) { - return p_matrix.FromQuaternion(v); - } - - return -1; -} - -// FUNCTION: LEGO1 0x10004520 -inline long UnknownMx4DPointFloat::FUN_10004520() -{ - if (!m_unk0x30) { - return -1; - } - - Mx4DPointFloat v1; - Mx4DPointFloat v2; - - v1 = m_unk0x00; - v1 += m_unk0x18; - - v2 = m_unk0x00; - v2 -= m_unk0x18; - - if (v1.Dot(v1, v1) < v2.Dot(v2, v2)) { - m_unk0x18 *= -1.0f; - } - - return 0; -} - -// FUNCTION: LEGO1 0x100040a0 -// FUNCTION: BETA10 0x1004ab10 -inline int UnknownMx4DPointFloat::FUN_100040a0(Vector4& p_v, float p_f) -{ - if (m_unk0x30 == c_bit1) { - p_v = m_unk0x00; - p_v[3] = (float) ((1.0 - p_f) * acos((double) p_v[3]) * 2.0); - return p_v.NormalizeQuaternion(); - } - - if (m_unk0x30 == c_bit2) { - p_v = m_unk0x18; - p_v[3] = (float) (p_f * acos((double) p_v[3]) * 2.0); - return p_v.NormalizeQuaternion(); - } - - if (m_unk0x30 == (c_bit1 | c_bit2)) { - int i; - double d1 = p_v.Dot(m_unk0x00, m_unk0x18); - double a; - double b; - - if (d1 + 1.0 > 0.00001) { - if (1.0 - d1 > 0.00001) { - double d2 = acos(d1); - double denominator = sin(d2); - a = sin((1.0 - p_f) * d2) / denominator; - b = sin(p_f * d2) / denominator; - } - else { - a = 1.0 - p_f; - b = p_f; - } - - for (i = 0; i < 4; i++) { - p_v[i] = (float) (m_unk0x00[i] * a + m_unk0x18[i] * b); - } - } - else { - p_v[0] = -m_unk0x00[1]; - p_v[1] = m_unk0x00[0]; - p_v[2] = -m_unk0x00[3]; - p_v[3] = m_unk0x00[2]; - a = sin((1.0 - p_f) * 1.570796326794895); - b = sin(p_f * 1.570796326794895); - - for (i = 0; i < 3; i++) { - p_v[i] = (float) (m_unk0x00[i] * a + p_v[i] * b); - } - } - - return 0; - } - - return -1; -} - #endif // MXGEOMETRY3D_H diff --git a/LEGO1/mxgeometry/mxgeometry4d.h b/LEGO1/mxgeometry/mxgeometry4d.h new file mode 100644 index 00000000..4ebeeb5a --- /dev/null +++ b/LEGO1/mxgeometry/mxgeometry4d.h @@ -0,0 +1,48 @@ +#ifndef MXGEOMETRY4D_H +#define MXGEOMETRY4D_H + +#include "decomp.h" +#include "realtime/vector4d.inl.h" + +// VTABLE: LEGO1 0x100d41e8 +// VTABLE: BETA10 0x101bab78 +// SIZE 0x18 +class Mx4DPointFloat : public Vector4 { +public: + // FUNCTION: LEGO1 0x10048290 + // FUNCTION: BETA10 0x100484c0 + Mx4DPointFloat() : Vector4(m_elements) {} + + // FUNCTION: BETA10 0x10073bb0 + Mx4DPointFloat(float p_x, float p_y, float p_z, float p_a) : Vector4(m_elements) + { + m_elements[0] = p_x; + m_elements[1] = p_y; + m_elements[2] = p_z; + m_elements[3] = p_a; + } + + Mx4DPointFloat(const Mx4DPointFloat& p_other) : Vector4(m_elements) { EqualsImpl(p_other.m_data); } + + // FUNCTION: LEGO1 0x10003200 + virtual void operator=(const Vector4& p_impl) { EqualsImpl(p_impl.m_data); } // vtable+0x98 + + // FUNCTION: BETA10 0x1004af10 + float& operator[](int idx) { return m_data[idx]; } + + // According to the PDB, BETA10 will not link this one if it is never used + // const float& operator[](int idx) const { return m_data[idx]; } + + // only used by a couple of BETA10 functions for some unknown reason + // FUNCTION: BETA10 0x1001c950 + float& index_operator(int idx) { return m_data[idx]; } + + // SYNTHETIC: LEGO1 0x10064b20 + // SYNTHETIC: BETA10 0x10070420 + // ??4Mx4DPointFloat@@QAEAAV0@ABV0@@Z + +private: + float m_elements[4]; // 0x08 +}; + +#endif // MXGEOMETRY4D_H diff --git a/LEGO1/mxgeometry/mxmatrix.h b/LEGO1/mxgeometry/mxmatrix.h index 9f1aa59f..a31a5d4e 100644 --- a/LEGO1/mxgeometry/mxmatrix.h +++ b/LEGO1/mxgeometry/mxmatrix.h @@ -1,7 +1,7 @@ #ifndef MXMATRIX_H #define MXMATRIX_H -#include "realtime/matrix.h" +#include "realtime/matrix4d.inl.h" // VTABLE: LEGO1 0x100d4300 // VTABLE: BETA10 0x101b82e0 @@ -35,4 +35,9 @@ private: float m_elements[4][4]; // 0x08 }; +// Must be included here (not before MxMatrix) for correct ordering in binary. +// FromQuaternion and ToQuaternion in Matrix4 depend on Vector4. +// There's a chance they included mxgeometry4d.h after including this somewhere. +#include "realtime/vector4d.inl.h" + #endif // MXMATRIX_H diff --git a/LEGO1/mxgeometry/mxquaternion.h b/LEGO1/mxgeometry/mxquaternion.h new file mode 100644 index 00000000..a5fb006b --- /dev/null +++ b/LEGO1/mxgeometry/mxquaternion.h @@ -0,0 +1,165 @@ +#ifndef MXQUATERNION_H +#define MXQUATERNION_H + +#include "mxgeometry4d.h" + +// SIZE 0x34 +class MxQuaternionTransformer { +public: + enum { + c_startSet = 0x01, + c_endSet = 0x02 + }; + + MxQuaternionTransformer() : m_flags(0) {} + + inline long NormalizeDirection(); + inline void SetStartEnd(Matrix4& p_m1, Matrix4& p_m2); + inline void SetStart(Matrix4& p_m); + inline void SetEnd(Matrix4& p_m); + inline void SetStart(Vector4& p_v); + 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; } + undefined4 GetFlags() const { return m_flags; } + +private: + inline int Interpolate(Vector4& p_v, float p_f); + + Mx4DPointFloat m_startQuat; // 0x00 + Mx4DPointFloat m_endQuat; // 0x18 + MxU32 m_flags; // 0x30 +}; + +// FUNCTION: LEGO1 0x10004520 +long MxQuaternionTransformer::NormalizeDirection() +{ + if (!m_flags) { + return -1; + } + + Mx4DPointFloat v1; + Mx4DPointFloat v2; + + v1 = m_startQuat; + v1 += m_endQuat; + + v2 = m_startQuat; + v2 -= m_endQuat; + + if (v1.Dot(v1, v1) < v2.Dot(v2, v2)) { + m_endQuat *= -1.0f; + } + + return 0; +} + +// FUNCTION: BETA10 0x1004a9b0 +void MxQuaternionTransformer::SetStartEnd(Matrix4& p_m1, Matrix4& p_m2) +{ + SetStart(p_m1); + SetEnd(p_m2); +} + +// FUNCTION: BETA10 0x1004a9f0 +void MxQuaternionTransformer::SetStart(Matrix4& p_m) +{ + p_m.ToQuaternion(m_startQuat); + m_flags |= c_startSet; +} + +// FUNCTION: LEGO1 0x10004620 +// FUNCTION: BETA10 0x1004aa30 +void MxQuaternionTransformer::SetEnd(Matrix4& p_m) +{ + p_m.ToQuaternion(m_endQuat); + m_flags |= c_endSet; +} + +// FUNCTION: BETA10 0x10180b80 +void MxQuaternionTransformer::SetStart(Vector4& p_v) +{ + m_startQuat = p_v; + m_flags |= c_startSet; +} + +// FUNCTION: BETA10 0x10180bc0 +void MxQuaternionTransformer::SetEnd(Vector4& p_v) +{ + m_endQuat = p_v; + m_flags |= c_endSet; +} + +// FUNCTION: BETA10 0x1004aaa0 +int MxQuaternionTransformer::InterpolateToMatrix(Matrix4& p_matrix, float p_f) +{ + float data[4]; + Vector4 v(data); + + if (Interpolate(v, p_f) == 0) { + return p_matrix.FromQuaternion(v); + } + + return -1; +} + +// FUNCTION: LEGO1 0x100040a0 +// FUNCTION: BETA10 0x1004ab10 +int MxQuaternionTransformer::Interpolate(Vector4& p_v, float p_f) +{ + if (m_flags == c_startSet) { + p_v = m_startQuat; + p_v[3] = (float) ((1.0 - p_f) * acos((double) p_v[3]) * 2.0); + return p_v.NormalizeQuaternion(); + } + + if (m_flags == c_endSet) { + p_v = m_endQuat; + p_v[3] = (float) (p_f * acos((double) p_v[3]) * 2.0); + return p_v.NormalizeQuaternion(); + } + + if (m_flags == (c_startSet | c_endSet)) { + int i; + double d1 = p_v.Dot(m_startQuat, m_endQuat); + double a; + double b; + + if (d1 + 1.0 > 0.00001) { + if (1.0 - d1 > 0.00001) { + double d2 = acos(d1); + double denominator = sin(d2); + a = sin((1.0 - p_f) * d2) / denominator; + b = sin(p_f * d2) / denominator; + } + else { + a = 1.0 - p_f; + b = p_f; + } + + for (i = 0; i < 4; i++) { + p_v[i] = (float) (m_startQuat[i] * a + m_endQuat[i] * b); + } + } + else { + p_v[0] = -m_startQuat[1]; + p_v[1] = m_startQuat[0]; + p_v[2] = -m_startQuat[3]; + p_v[3] = m_startQuat[2]; + a = sin((1.0 - p_f) * 1.570796326794895); + b = sin(p_f * 1.570796326794895); + + for (i = 0; i < 3; i++) { + p_v[i] = (float) (m_startQuat[i] * a + p_v[i] * b); + } + } + + return 0; + } + + return -1; +} + +#endif // MXQUATERNION_H diff --git a/LEGO1/omni/include/mxaudiopresenter.h b/LEGO1/omni/include/mxaudiopresenter.h index ec73e336..67c8cf94 100644 --- a/LEGO1/omni/include/mxaudiopresenter.h +++ b/LEGO1/omni/include/mxaudiopresenter.h @@ -10,6 +10,12 @@ class MxAudioPresenter : public MxMediaPresenter { public: MxAudioPresenter() { m_volume = 100; } + // FUNCTION: LEGO1 0x1000d260 + virtual MxS32 GetVolume() { return m_volume; } // vtable+0x5c + + // FUNCTION: LEGO1 0x1000d270 + virtual void SetVolume(MxS32 p_volume) { m_volume = p_volume; } // vtable+0x60 + // FUNCTION: BETA10 0x1008cba0 static const char* HandlerClassName() { @@ -30,12 +36,6 @@ public: return !strcmp(p_name, MxAudioPresenter::ClassName()) || MxMediaPresenter::IsA(p_name); } - // FUNCTION: LEGO1 0x1000d260 - virtual MxS32 GetVolume() { return m_volume; } // vtable+0x5c - - // FUNCTION: LEGO1 0x1000d270 - virtual void SetVolume(MxS32 p_volume) { m_volume = p_volume; } // vtable+0x60 - protected: MxS32 m_volume; // 0x50 }; diff --git a/LEGO1/omni/include/mxdsbuffer.h b/LEGO1/omni/include/mxdsbuffer.h index 2e48e887..a988ca57 100644 --- a/LEGO1/omni/include/mxdsbuffer.h +++ b/LEGO1/omni/include/mxdsbuffer.h @@ -68,7 +68,7 @@ public: // FUNCTION: BETA10 0x10148c60 MxU8* GetBuffer() { return m_pBuffer; } - MxU8** GetBufferRef() { return &m_pBuffer; } + // FUNCTION: BETA10 0x10164240 undefined4 GetUnknown14() { return m_unk0x14; } // FUNCTION: BETA10 0x10156420 @@ -85,7 +85,10 @@ public: void SetUnknown14(undefined4 p_unk0x14) { m_unk0x14 = p_unk0x14; } void SetUnknown1c(undefined4 p_unk0x1c) { m_unk0x1c = p_unk0x1c; } + + // FUNCTION: BETA10 0x10164260 void SetMode(Type p_mode) { m_mode = p_mode; } + void SetUnk30(MxDSStreamingAction* p_unk0x30) { m_unk0x30 = p_unk0x30; } // SYNTHETIC: LEGO1 0x100c6510 diff --git a/LEGO1/omni/include/mxdschunk.h b/LEGO1/omni/include/mxdschunk.h index af41394a..d3fa7e5a 100644 --- a/LEGO1/omni/include/mxdschunk.h +++ b/LEGO1/omni/include/mxdschunk.h @@ -35,10 +35,12 @@ public: } static MxU32 GetHeaderSize(); - static MxU32* IntoType(MxU8* p_buffer) { return (MxU32*) p_buffer; } - static MxU32* IntoLength(MxU8* p_buffer) { return (MxU32*) (p_buffer + 4); } - static MxU32 Size(MxU32 p_dataSize) { return (p_dataSize & 1) + p_dataSize + 8; } - static MxU8* End(MxU8* p_buffer) { return p_buffer + Size(*IntoLength(p_buffer)); } + + // FUNCTION: BETA10 0x101641f0 + static MxU32 Size(MxU8* p_buffer) { return (*(MxU32*) (p_buffer + 4) & 1) + *(MxU32*) (p_buffer + 4) + 8; } + + // FUNCTION: BETA10 0x10164220 + static MxU8* End(MxU8* p_buffer) { return p_buffer + Size(p_buffer); } void SetChunkFlags(MxU16 p_flags) { m_flags = p_flags; } void SetObjectId(undefined4 p_objectid) { m_objectId = p_objectid; } diff --git a/LEGO1/omni/include/mxdsstreamingaction.h b/LEGO1/omni/include/mxdsstreamingaction.h index dc1c8815..96be50e5 100644 --- a/LEGO1/omni/include/mxdsstreamingaction.h +++ b/LEGO1/omni/include/mxdsstreamingaction.h @@ -6,6 +6,7 @@ class MxDSBuffer; // VTABLE: LEGO1 0x100dd088 +// VTABLE: BETA10 0x101c2850 // SIZE 0xb4 class MxDSStreamingAction : public MxDSAction { public: @@ -14,40 +15,53 @@ public: ~MxDSStreamingAction() override; MxDSStreamingAction* CopyFrom(MxDSStreamingAction& p_dsStreamingAction); - MxDSStreamingAction& operator=(MxDSAction& p_dsAction) - { - MxDSAction::operator=(p_dsAction); - return *this; - } - MxDSStreamingAction& operator=(MxDSStreamingAction& p_dsStreamingAction) - { - MxDSAction::operator=(p_dsStreamingAction); - return *this; - } - MxBool HasId(MxU32 p_objectId) override; // vtable+34; + MxBool HasId(MxU32 p_objectId) override; // vtable+0x34; - MxResult Init(); + void Init(); void SetInternalAction(MxDSAction* p_dsAction); void FUN_100cd2d0(); + // FUNCTION: BETA10 0x10156530 MxU32 GetUnknown94() { return m_unk0x94; } + + // FUNCTION: BETA10 0x10156380 MxS32 GetUnknown9c() { return m_unk0x9c; } + + // FUNCTION: BETA10 0x10156630 MxDSBuffer* GetUnknowna0() { return m_unk0xa0; } + + // FUNCTION: BETA10 0x101563d0 MxDSBuffer* GetUnknowna4() { return m_unk0xa4; } + + // FUNCTION: BETA10 0x10159190 MxLong GetUnknowna8() { return m_unk0xa8; } + MxDSAction* GetInternalAction() { return m_internalAction; } + + // FUNCTION: BETA10 0x10156580 MxU32 GetBufferOffset() { return m_bufferOffset; } + + // FUNCTION: BETA10 0x10156550 void SetUnknown94(MxU32 p_unk0x94) { m_unk0x94 = p_unk0x94; } + + // FUNCTION: BETA10 0x101563a0 void SetUnknown9c(MxS32 p_unk0x9c) { m_unk0x9c = p_unk0x9c; } + + // FUNCTION: BETA10 0x10156470 void SetUnknowna0(MxDSBuffer* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; } + + // FUNCTION: BETA10 0x101563f0 void SetUnknowna4(MxDSBuffer* p_unk0xa4) { m_unk0xa4 = p_unk0xa4; } + + // FUNCTION: BETA10 0x10151150 void SetBufferOffset(MxU32 p_bufferOffset) { m_bufferOffset = p_bufferOffset; } // FUNCTION: BETA10 0x10156650 void ClearUnknowna0() { m_unk0xa0 = NULL; } // SYNTHETIC: LEGO1 0x100cd0b0 + // SYNTHETIC: BETA10 0x101565f0 // MxDSStreamingAction::`scalar deleting destructor' private: diff --git a/LEGO1/omni/include/mxio.h b/LEGO1/omni/include/mxio.h index 4a549ecd..5868c9ba 100644 --- a/LEGO1/omni/include/mxio.h +++ b/LEGO1/omni/include/mxio.h @@ -9,6 +9,9 @@ // We define the bare minimum constants and structures to be compatible with the code in mxio.cpp // This is mostly copy-pasted from the MMSYSTEM.H Windows header. +/* general error return values */ +#define MMSYSERR_NOERROR 0 /* no error */ + /* MMIO error return values */ #define MMIOERR_BASE 256 #define MMIOERR_OUTOFMEMORY (MMIOERR_BASE + 2) /* out of memory */ @@ -39,8 +42,10 @@ #define FOURCC_LIST mmioFOURCC('L', 'I', 'S', 'T') /* various MMIO flags */ -#define MMIO_FINDRIFF 0x0020 /* mmioDescend: find a LIST chunk */ -#define MMIO_FINDLIST 0x0040 /* mmioDescend: find a RIFF chunk */ +#define MMIO_FINDRIFF 0x0020 /* mmioDescend: find a LIST chunk */ +#define MMIO_FINDLIST 0x0040 /* mmioDescend: find a RIFF chunk */ +#define MMIO_CREATERIFF 0x0020 /* mmioCreateChunk: make a LIST chunk */ +#define MMIO_CREATELIST 0x0040 /* mmioCreateChunk: make a RIFF chunk */ /* general MMIO information data structure */ typedef struct _ISLE_MMIOINFO { @@ -84,6 +89,7 @@ public: MxU16 Advance(MxU16); MxU16 Descend(ISLE_MMCKINFO*, const ISLE_MMCKINFO*, MxU16); MxU16 Ascend(ISLE_MMCKINFO*, MxU16); + MxU16 CreateChunk(ISLE_MMCKINFO* p_chunkInfo, MxU16 p_create); // NOTE: In MXIOINFO, the `hmmio` member of MMIOINFO is used like // an HFILE (int) instead of an HMMIO (WORD). diff --git a/LEGO1/omni/include/mxmediapresenter.h b/LEGO1/omni/include/mxmediapresenter.h index 40bb0961..3cfee4bd 100644 --- a/LEGO1/omni/include/mxmediapresenter.h +++ b/LEGO1/omni/include/mxmediapresenter.h @@ -16,6 +16,9 @@ public: // FUNCTION: LEGO1 0x1000c550 ~MxMediaPresenter() override { Destroy(TRUE); } + // FUNCTION: LEGO1 0x1000c5b0 + void Destroy() override { Destroy(FALSE); } // vtable+0x38 + MxResult Tickle() override; // vtable+0x08 // FUNCTION: BETA10 0x10054f50 @@ -42,9 +45,6 @@ public: void RepeatingTickle() override; // vtable+0x24 void DoneTickle() override; // vtable+0x2c - // FUNCTION: LEGO1 0x1000c5b0 - void Destroy() override { Destroy(FALSE); } // vtable+0x38 - MxResult StartAction(MxStreamController*, MxDSAction*) override; // vtable+0x3c void EndAction() override; // vtable+0x40 void Enable(MxBool p_enable) override; // vtable+0x54 diff --git a/LEGO1/omni/include/mxpresenter.h b/LEGO1/omni/include/mxpresenter.h index 3358c832..3af93fd0 100644 --- a/LEGO1/omni/include/mxpresenter.h +++ b/LEGO1/omni/include/mxpresenter.h @@ -28,31 +28,8 @@ public: MxPresenter() { Init(); } - // FUNCTION: LEGO1 0x1000bf00 - ~MxPresenter() override {} // vtable+0x00 - MxResult Tickle() override; // vtable+0x08 - // FUNCTION: BETA10 0x1004d9e0 - static const char* HandlerClassName() - { - // STRING: LEGO1 0x100f0740 - return "MxPresenter"; - } - - // FUNCTION: LEGO1 0x1000bfe0 - // FUNCTION: BETA10 0x1004d9b0 - const char* ClassName() const override // vtable+0x0c - { - return HandlerClassName(); - } - - // FUNCTION: LEGO1 0x1000bff0 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, MxPresenter::ClassName()) || MxCore::IsA(p_name); - } - // FUNCTION: LEGO1 0x1000be30 virtual void VTable0x14() {} // vtable+0x14 @@ -88,6 +65,9 @@ protected: } public: + // FUNCTION: LEGO1 0x1000bf00 + ~MxPresenter() override {} // vtable+0x00 + // FUNCTION: LEGO1 0x1000bf70 virtual MxResult AddToManager() { return SUCCESS; } // vtable+0x34 @@ -115,6 +95,26 @@ public: virtual void Enable(MxBool p_enable); // vtable+0x54 + // FUNCTION: BETA10 0x1004d9e0 + static const char* HandlerClassName() + { + // STRING: LEGO1 0x100f0740 + return "MxPresenter"; + } + + // FUNCTION: LEGO1 0x1000bfe0 + // FUNCTION: BETA10 0x1004d9b0 + const char* ClassName() const override // vtable+0x0c + { + return HandlerClassName(); + } + + // FUNCTION: LEGO1 0x1000bff0 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, MxPresenter::ClassName()) || MxCore::IsA(p_name); + } + MxEntity* CreateEntity(const char* p_defaultName); void SendToCompositePresenter(MxOmni* p_omni); MxBool IsEnabled(); diff --git a/LEGO1/omni/include/mxsoundpresenter.h b/LEGO1/omni/include/mxsoundpresenter.h index e2d80e3d..041b8a17 100644 --- a/LEGO1/omni/include/mxsoundpresenter.h +++ b/LEGO1/omni/include/mxsoundpresenter.h @@ -10,6 +10,9 @@ public: // FUNCTION: LEGO1 0x1000d430 ~MxSoundPresenter() override { Destroy(TRUE); } + // FUNCTION: LEGO1 0x1000d490 + void Destroy() override { Destroy(FALSE); } // vtable+0x38 + // FUNCTION: BETA10 0x1008ca70 static const char* HandlerClassName() { @@ -32,9 +35,6 @@ public: MxResult AddToManager() override; // vtable+0x34 - // FUNCTION: LEGO1 0x1000d490 - void Destroy() override { Destroy(FALSE); } // vtable+0x38 - // SYNTHETIC: LEGO1 0x1000d5c0 // MxSoundPresenter::`scalar deleting destructor' diff --git a/LEGO1/omni/include/mxvideopresenter.h b/LEGO1/omni/include/mxvideopresenter.h index 30d65354..907ddc0e 100644 --- a/LEGO1/omni/include/mxvideopresenter.h +++ b/LEGO1/omni/include/mxvideopresenter.h @@ -14,43 +14,6 @@ class MxVideoPresenter : public MxMediaPresenter { public: MxVideoPresenter() { Init(); } - // FUNCTION: LEGO1 0x1000c740 - ~MxVideoPresenter() override { Destroy(TRUE); } // vtable+0x00 - - // FUNCTION: BETA10 0x100551b0 - static const char* HandlerClassName() - { - // STRING: LEGO1 0x100f0760 - return "MxVideoPresenter"; - } - - // FUNCTION: LEGO1 0x1000c820 - // FUNCTION: BETA10 0x10055180 - const char* ClassName() const override // vtable+0x0c - { - return HandlerClassName(); - } - - // FUNCTION: LEGO1 0x1000c830 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, MxVideoPresenter::ClassName()) || MxMediaPresenter::IsA(p_name); - } - - void ReadyTickle() override; // vtable+0x18 - void StartingTickle() override; // vtable+0x1c - void StreamingTickle() override; // vtable+0x20 - void RepeatingTickle() override; // vtable+0x24 - void FreezingTickle() override; // vtable+0x28 - MxResult AddToManager() override; // vtable+0x34 - - // FUNCTION: LEGO1 0x1000c7a0 - void Destroy() override { Destroy(FALSE); } // vtable+0x38 - - void EndAction() override; // vtable+0x40 - MxResult PutData() override; // vtable+0x4c - MxBool IsHit(MxS32 p_x, MxS32 p_y) override; // vtable+0x50 - // FUNCTION: LEGO1 0x1000c700 // FUNCTION: BETA10 0x10054a80 virtual void LoadHeader(MxStreamChunk* p_chunk) {} // vtable+0x5c @@ -72,6 +35,12 @@ public: virtual undefined VTable0x74(); // vtable+0x74 + // FUNCTION: LEGO1 0x1000c740 + ~MxVideoPresenter() override { Destroy(TRUE); } // vtable+0x00 + + // FUNCTION: LEGO1 0x1000c7a0 + void Destroy() override { Destroy(FALSE); } // vtable+0x38 + // FUNCTION: LEGO1 0x1000c7b0 virtual LPDIRECTDRAWSURFACE VTable0x78() { return m_unk0x58; } // vtable+0x78 @@ -84,6 +53,36 @@ public: // FUNCTION: LEGO1 0x1000c800 virtual MxS32 GetHeight() { return m_alpha ? m_alpha->m_height : m_frameBitmap->GetBmiHeightAbs(); } // vtable+0x84 + // FUNCTION: BETA10 0x100551b0 + static const char* HandlerClassName() + { + // STRING: LEGO1 0x100f0760 + return "MxVideoPresenter"; + } + + // FUNCTION: LEGO1 0x1000c820 + // FUNCTION: BETA10 0x10055180 + const char* ClassName() const override // vtable+0x0c + { + return HandlerClassName(); + } + + // FUNCTION: LEGO1 0x1000c830 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, MxVideoPresenter::ClassName()) || MxMediaPresenter::IsA(p_name); + } + + void ReadyTickle() override; // vtable+0x18 + void StartingTickle() override; // vtable+0x1c + void StreamingTickle() override; // vtable+0x20 + void RepeatingTickle() override; // vtable+0x24 + void FreezingTickle() override; // vtable+0x28 + MxResult AddToManager() override; // vtable+0x34 + void EndAction() override; // vtable+0x40 + MxResult PutData() override; // vtable+0x4c + MxBool IsHit(MxS32 p_x, MxS32 p_y) override; // vtable+0x50 + // VTABLE: LEGO1 0x100dc2bc // SIZE 0x0c struct AlphaMask { diff --git a/LEGO1/omni/include/mxwavepresenter.h b/LEGO1/omni/include/mxwavepresenter.h index bbd4c493..a543da35 100644 --- a/LEGO1/omni/include/mxwavepresenter.h +++ b/LEGO1/omni/include/mxwavepresenter.h @@ -15,6 +15,15 @@ public: // FUNCTION: LEGO1 0x1000d640 ~MxWavePresenter() override { Destroy(TRUE); } // vtable+0x00 + // FUNCTION: LEGO1 0x1000d6a0 + void Destroy() override { Destroy(FALSE); } // vtable+0x38 + + virtual void Pause(); // vtable+0x64 + virtual void Resume(); // vtable+0x68 + + // FUNCTION: LEGO1 0x1000d6b0 + virtual MxBool IsPaused() { return m_paused; } // vtable+0x6c + // FUNCTION: BETA10 0x1008cd00 static const char* HandlerClassName() { @@ -35,26 +44,17 @@ public: return !strcmp(p_name, MxWavePresenter::ClassName()) || MxSoundPresenter::IsA(p_name); } - void ReadyTickle() override; // vtable+0x18 - void StartingTickle() override; // vtable+0x1c - void StreamingTickle() override; // vtable+0x20 - void DoneTickle() override; // vtable+0x2c - void ParseExtra() override; // vtable+0x30 - MxResult AddToManager() override; // vtable+0x34 - - // FUNCTION: LEGO1 0x1000d6a0 - void Destroy() override { Destroy(FALSE); } // vtable+0x38 - + void ReadyTickle() override; // vtable+0x18 + void StartingTickle() override; // vtable+0x1c + void StreamingTickle() override; // vtable+0x20 + void DoneTickle() override; // vtable+0x2c + void ParseExtra() override; // vtable+0x30 + MxResult AddToManager() override; // vtable+0x34 void EndAction() override; // vtable+0x40 MxResult PutData() override; // vtable+0x4c void Enable(MxBool p_enable) override; // vtable+0x54 void LoopChunk(MxStreamChunk* p_chunk) override; // vtable+0x58 void SetVolume(MxS32 p_volume) override; // vtable+0x60 - virtual void Pause(); // vtable+0x64 - virtual void Resume(); // vtable+0x68 - - // FUNCTION: LEGO1 0x1000d6b0 - virtual MxBool IsPaused() { return m_paused; } // vtable+0x6c #pragma pack(push, 1) // SIZE 0x18 diff --git a/LEGO1/omni/src/action/mxdsstreamingaction.cpp b/LEGO1/omni/src/action/mxdsstreamingaction.cpp index 85759897..939cd5e3 100644 --- a/LEGO1/omni/src/action/mxdsstreamingaction.cpp +++ b/LEGO1/omni/src/action/mxdsstreamingaction.cpp @@ -5,25 +5,25 @@ DECOMP_SIZE_ASSERT(MxDSStreamingAction, 0xb4) // FUNCTION: LEGO1 0x100cd010 +// FUNCTION: BETA10 0x1015f380 MxDSStreamingAction::MxDSStreamingAction(MxDSAction& p_dsAction, MxU32 p_offset) { Init(); - *this = p_dsAction; - this->m_unk0x94 = p_offset; - this->m_bufferOffset = p_offset; + MxDSAction::operator=(p_dsAction); + m_unk0x94 = p_offset; + m_bufferOffset = p_offset; } // FUNCTION: LEGO1 0x100cd090 +// FUNCTION: BETA10 0x101565a0 MxBool MxDSStreamingAction::HasId(MxU32 p_objectId) { - if (this->m_internalAction) { - return this->m_internalAction->HasId(p_objectId); - } - return FALSE; + return m_internalAction ? m_internalAction->HasId(p_objectId) : FALSE; } // FUNCTION: LEGO1 0x100cd0d0 +// FUNCTION: BETA10 0x101564a0 MxDSStreamingAction::MxDSStreamingAction(MxDSStreamingAction& p_dsStreamingAction) { Init(); @@ -31,68 +31,71 @@ MxDSStreamingAction::MxDSStreamingAction(MxDSStreamingAction& p_dsStreamingActio } // FUNCTION: LEGO1 0x100cd150 +// FUNCTION: BETA10 0x1015f41d MxDSStreamingAction::~MxDSStreamingAction() { - if (this->m_unk0xa0) { - delete this->m_unk0xa0; + if (m_unk0xa0) { + delete m_unk0xa0; } - if (this->m_unk0xa4) { - delete this->m_unk0xa4; + if (m_unk0xa4) { + delete m_unk0xa4; } - if (this->m_internalAction) { - delete this->m_internalAction; + if (m_internalAction) { + delete m_internalAction; } } // FUNCTION: LEGO1 0x100cd1e0 -MxResult MxDSStreamingAction::Init() +// FUNCTION: BETA10 0x1015f53c +void MxDSStreamingAction::Init() { - this->m_unk0x94 = 0; - this->m_bufferOffset = 0; - this->m_unk0x9c = 0; - this->m_unk0xa0 = NULL; - this->m_unk0xa4 = NULL; - this->m_unk0xa8 = 0; - this->m_unk0xac = 2; - this->m_internalAction = NULL; - return SUCCESS; + m_unk0x94 = 0; + m_bufferOffset = 0; + m_unk0x9c = 0; + m_unk0xa0 = NULL; + m_unk0xa4 = NULL; + m_unk0xa8 = 0; + m_unk0xac = 2; + m_internalAction = NULL; } // FUNCTION: LEGO1 0x100cd220 +// FUNCTION: BETA10 0x1015f5b9 MxDSStreamingAction* MxDSStreamingAction::CopyFrom(MxDSStreamingAction& p_dsStreamingAction) { - *this = p_dsStreamingAction; - this->m_unk0x94 = p_dsStreamingAction.m_unk0x94; - this->m_bufferOffset = p_dsStreamingAction.m_bufferOffset; - this->m_unk0x9c = p_dsStreamingAction.m_unk0x9c; - this->m_unk0xa0 = NULL; - this->m_unk0xa4 = NULL; - this->m_unk0xac = p_dsStreamingAction.m_unk0xac; - this->m_unk0xa8 = p_dsStreamingAction.m_unk0xa8; + MxDSAction::operator=(p_dsStreamingAction); + m_unk0x94 = p_dsStreamingAction.m_unk0x94; + m_bufferOffset = p_dsStreamingAction.m_bufferOffset; + m_unk0x9c = p_dsStreamingAction.m_unk0x9c; + m_unk0xa0 = NULL; + m_unk0xa4 = NULL; + m_unk0xac = p_dsStreamingAction.m_unk0xac; + m_unk0xa8 = p_dsStreamingAction.m_unk0xa8; SetInternalAction(p_dsStreamingAction.m_internalAction ? p_dsStreamingAction.m_internalAction->Clone() : NULL); return this; } // FUNCTION: LEGO1 0x100cd2a0 +// FUNCTION: BETA10 0x1015f698 void MxDSStreamingAction::SetInternalAction(MxDSAction* p_dsAction) { - if (this->m_internalAction) { - delete this->m_internalAction; + if (m_internalAction) { + delete m_internalAction; } - this->m_internalAction = p_dsAction; + m_internalAction = p_dsAction; } // FUNCTION: LEGO1 0x100cd2d0 void MxDSStreamingAction::FUN_100cd2d0() { - if (this->m_duration == -1) { + if (m_duration == -1) { return; } - MxLong duration = this->m_duration / this->m_loopCount; - this->m_loopCount--; + MxLong duration = m_duration / m_loopCount; + m_loopCount--; - this->m_duration -= duration; - this->m_unk0xa8 += duration; + m_duration -= duration; + m_unk0xa8 += duration; } diff --git a/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp b/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp index 614247e4..3cf753d6 100644 --- a/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp +++ b/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp @@ -286,6 +286,7 @@ MxBool MxDiskStreamProvider::FUN_100d1af0(MxDSStreamingAction* p_action) } // FUNCTION: LEGO1 0x100d1b20 +// FUNCTION: BETA10 0x10163712 MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action) { MxDSBuffer* buffer = new MxDSBuffer(); @@ -294,91 +295,74 @@ MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action) return FAILURE; } - MxU32 size = p_action->GetUnknowna0()->GetWriteOffset() - p_action->GetUnknown94() + p_action->GetBufferOffset() + - (p_action->GetUnknowna4() ? p_action->GetUnknowna4()->GetWriteOffset() : 0); + MxU32 size = (p_action->GetUnknowna4() ? p_action->GetUnknowna4()->GetWriteOffset() : 0) + + p_action->GetUnknowna0()->GetWriteOffset() - (p_action->GetUnknown94() - p_action->GetBufferOffset()); if (buffer->AllocateBuffer(size, MxDSBuffer::e_allocate) != SUCCESS) { - if (!buffer) { - return FAILURE; - } - delete buffer; return FAILURE; } - MxDSBuffer* buffer2 = p_action->GetUnknowna4(); - MxU8** pdata; MxU8* data; - if (buffer2 == NULL) { - pdata = buffer->GetBufferRef(); + if (p_action->GetUnknowna4()) { + buffer->FUN_100c7090(p_action->GetUnknowna4()); + data = buffer->GetBuffer() + p_action->GetUnknowna4()->GetWriteOffset(); - memcpy( - data = *pdata, - p_action->GetUnknowna0()->GetBuffer() - p_action->GetBufferOffset() + p_action->GetUnknown94(), - size - ); - } - else { - buffer->FUN_100c7090(buffer2); - pdata = buffer->GetBufferRef(); - - memcpy( - data = (p_action->GetUnknowna4()->GetWriteOffset() + *pdata), - p_action->GetUnknowna0()->GetBuffer(), - p_action->GetUnknowna0()->GetWriteOffset() - ); + memcpy(data, p_action->GetUnknowna0()->GetBuffer(), p_action->GetUnknowna0()->GetWriteOffset()); delete p_action->GetUnknowna4(); } + else { + data = buffer->GetBuffer(); + + memcpy( + data, + p_action->GetUnknowna0()->GetBuffer() + (p_action->GetUnknown94() - p_action->GetBufferOffset()), + size + ); + } p_action->SetUnknowna4(buffer); +#define IntoType(p) ((MxU32*) (p)) + while (data) { - if (*MxDSChunk::IntoType(data) != FOURCC('M', 'x', 'O', 'b')) { - if (*MxStreamChunk::IntoTime(data) > p_action->GetUnknown9c()) { - *MxDSChunk::IntoType(data) = FOURCC('p', 'a', 'd', ' '); + if (*IntoType(data) != FOURCC('M', 'x', 'O', 'b') && + *MxStreamChunk::IntoTime(data) > p_action->GetUnknown9c()) { + *IntoType(data) = FOURCC('p', 'a', 'd', ' '); - memcpy(data + 8, *pdata, buffer->GetWriteOffset() + *pdata - data - 8); - size = ReadData(*pdata, buffer->GetWriteOffset()); + // DECOMP: prefer order that matches retail versus beta + *(MxU32*) (data + 4) = buffer->GetBuffer() + buffer->GetWriteOffset() - data - 8; + memset(data + 8, 0, *(MxU32*) (data + 4)); + size = ReadData(buffer->GetBuffer(), buffer->GetWriteOffset()); - MxDSBuffer* buffer3 = new MxDSBuffer(); - if (!buffer3) { - return FAILURE; - } - - if (buffer3->AllocateBuffer(size, MxDSBuffer::e_allocate) == SUCCESS) { - memcpy(buffer3->GetBuffer(), p_action->GetUnknowna4()->GetBuffer(), size); - p_action->GetUnknowna4()->SetMode(MxDSBuffer::e_allocate); - delete p_action->GetUnknowna4(); - - buffer3->SetMode(MxDSBuffer::e_unknown); - p_action->SetUnknowna4(buffer3); - MxDSBuffer* buffer4 = p_action->GetUnknowna0(); - MxU32 unk0x14 = buffer4->GetUnknown14(); - MxU8* data2 = buffer4->GetBuffer(); - - while (TRUE) { - if (*MxStreamChunk::IntoTime(data2) > p_action->GetUnknown9c()) { - break; - } - - data += MxDSChunk::Size(*MxDSChunk::IntoLength(data)); - unk0x14 += MxDSChunk::Size(*MxDSChunk::IntoLength(data)); - } - - p_action->SetUnknown94(unk0x14); - p_action->SetBufferOffset(p_action->GetUnknowna0()->GetUnknown14()); - delete p_action->GetUnknowna0(); - p_action->SetUnknowna0(NULL); - ((MxDiskStreamController*) m_pLookup)->FUN_100c7890(p_action); - return SUCCESS; - } - else { - delete buffer3; - return FAILURE; - } + buffer = new MxDSBuffer(); + if (buffer == NULL || buffer->AllocateBuffer(size, MxDSBuffer::e_allocate) != SUCCESS) { + delete buffer; + return FAILURE; } + + memcpy(buffer->GetBuffer(), p_action->GetUnknowna4()->GetBuffer(), size); + p_action->GetUnknowna4()->SetMode(MxDSBuffer::e_allocate); + delete p_action->GetUnknowna4(); + + buffer->SetMode(MxDSBuffer::e_unknown); + p_action->SetUnknowna4(buffer); + MxU32 unk0x14 = p_action->GetUnknowna0()->GetUnknown14(); + + for (data = p_action->GetUnknowna0()->GetBuffer(); + *MxStreamChunk::IntoTime(data) <= p_action->GetUnknown9c(); + data = MxDSChunk::End(data)) { + unk0x14 += MxDSChunk::Size(data); + } + + p_action->SetUnknown94(unk0x14); + p_action->SetBufferOffset(p_action->GetUnknowna0()->GetUnknown14()); + delete p_action->GetUnknowna0(); + p_action->ClearUnknowna0(); + ((MxDiskStreamController*) m_pLookup)->FUN_100c7890(p_action); + return SUCCESS; } data = buffer->FUN_100c6fa0(data); @@ -388,6 +372,8 @@ MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action) p_action->SetBufferOffset(GetFileSize() + p_action->GetBufferOffset()); FUN_100d1780(p_action); return SUCCESS; + +#undef IntoType } // FUNCTION: LEGO1 0x100d1e90 diff --git a/LEGO1/omni/src/stream/mxdsbuffer.cpp b/LEGO1/omni/src/stream/mxdsbuffer.cpp index 371b0610..8d627b5e 100644 --- a/LEGO1/omni/src/stream/mxdsbuffer.cpp +++ b/LEGO1/omni/src/stream/mxdsbuffer.cpp @@ -491,6 +491,7 @@ MxU8* MxDSBuffer::FUN_100c6fa0(MxU8* p_data) } // FUNCTION: LEGO1 0x100c7090 +// FUNCTION: BETA10 0x1015842d MxResult MxDSBuffer::FUN_100c7090(MxDSBuffer* p_buf) { MxResult result = FAILURE; diff --git a/LEGO1/omni/src/stream/mxio.cpp b/LEGO1/omni/src/stream/mxio.cpp index 49d55ad2..6efbe5ef 100644 --- a/LEGO1/omni/src/stream/mxio.cpp +++ b/LEGO1/omni/src/stream/mxio.cpp @@ -36,7 +36,7 @@ MxU16 MXIOINFO::Open(const char* p_filename, MxULong p_flags) // [library:filesystem] p_flags is always 0 (OF_READ) assert(p_flags == 0); - MxU16 result = 0; + MxU16 result = MMSYSERR_NOERROR; m_info.lDiskOffset = m_info.lBufOffset = 0; @@ -82,7 +82,7 @@ MxU16 MXIOINFO::Open(const char* p_filename, MxULong p_flags) // FUNCTION: BETA10 0x1015e30b MxU16 MXIOINFO::Close(MxLong p_unused) { - MxU16 result = 0; + MxU16 result = MMSYSERR_NOERROR; if (RAW_M_FILE) { result = Flush(0); @@ -315,7 +315,7 @@ MxLong MXIOINFO::Seek(MxLong p_offset, SDL_IOWhence p_origin) // FUNCTION: BETA10 0x1015e9ad MxU16 MXIOINFO::SetBuffer(char* p_buf, MxLong p_len, MxLong p_unused) { - MxU16 result = 0; + MxU16 result = MMSYSERR_NOERROR; result = Flush(0); if (m_info.dwFlags & MMIO_ALLOCBUF) { @@ -335,7 +335,7 @@ MxU16 MXIOINFO::SetBuffer(char* p_buf, MxLong p_len, MxLong p_unused) // FUNCTION: BETA10 0x1015ea3e MxU16 MXIOINFO::Flush(MxU16 p_unused) { - MxU16 result = 0; + MxU16 result = MMSYSERR_NOERROR; Sint64 bytesWritten; // if buffer is dirty @@ -387,7 +387,7 @@ MxU16 MXIOINFO::Flush(MxU16 p_unused) // FUNCTION: BETA10 0x1015eb8f MxU16 MXIOINFO::Advance(MxU16 p_option) { - MxU16 result = 0; + MxU16 result = MMSYSERR_NOERROR; MxULong rwmode = m_info.dwFlags & MMIO_RWMODE; if (m_info.pchBuffer) { @@ -461,7 +461,7 @@ MxU16 MXIOINFO::Advance(MxU16 p_option) // FUNCTION: BETA10 0x1015edef MxU16 MXIOINFO::Descend(ISLE_MMCKINFO* p_chunkInfo, const ISLE_MMCKINFO* p_parentInfo, MxU16 p_descend) { - MxU16 result = 0; + MxU16 result = MMSYSERR_NOERROR; MxULong ofs; MxU32 readOk; @@ -552,7 +552,7 @@ MxU16 MXIOINFO::Ascend(ISLE_MMCKINFO* p_chunkInfo, MxU16 p_ascend) { MxLong ofs; MxULong size; - MxU16 result = 0; + MxU16 result = MMSYSERR_NOERROR; if (p_chunkInfo == NULL) { return MMIOERR_BASE; @@ -610,3 +610,43 @@ MxU16 MXIOINFO::Ascend(ISLE_MMCKINFO* p_chunkInfo, MxU16 p_ascend) return result; } + +// FUNCTION: BETA10 0x1015f28b +MxU16 MXIOINFO::CreateChunk(ISLE_MMCKINFO* p_chunkInfo, MxU16 p_create) +{ + MxU16 result = MMSYSERR_NOERROR; + + if (p_chunkInfo == NULL) { + return MMIOERR_BASE; + } + + if (p_create == MMIO_CREATERIFF) { + p_chunkInfo->ckid = FOURCC_RIFF; + } + if (p_create == MMIO_CREATELIST) { + p_chunkInfo->ckid = FOURCC_LIST; + } + + p_chunkInfo->dwDataOffset = Seek(0, SDL_IO_SEEK_CUR); + if (p_chunkInfo->dwDataOffset == -1) { + result = MMIOERR_CANNOTSEEK; + } + else { + p_chunkInfo->dwDataOffset += 8; + } + + MxU32 size; + if (p_chunkInfo->ckid == FOURCC_RIFF || p_chunkInfo->ckid == FOURCC_LIST) { + size = 12; + } + else { + size = 8; + } + + if (Write(p_chunkInfo, size) != size) { + result = MMIOERR_CANNOTWRITE; + } + + p_chunkInfo->dwFlags = MMIO_DIRTY; + return result; +} diff --git a/LEGO1/omni/src/stream/mxramstreamprovider.cpp b/LEGO1/omni/src/stream/mxramstreamprovider.cpp index 8282a785..264d3b0a 100644 --- a/LEGO1/omni/src/stream/mxramstreamprovider.cpp +++ b/LEGO1/omni/src/stream/mxramstreamprovider.cpp @@ -102,62 +102,63 @@ done: } // FUNCTION: LEGO1 0x100d0d80 +// FUNCTION: BETA10 0x1016492f MxU32 ReadData(MxU8* p_buffer, MxU32 p_size) { MxU32 id; MxU8* data = p_buffer; - MxU8* end = p_buffer + p_size; MxU8* data2; - if (p_buffer < end) { - do { - if (*MxDSChunk::IntoType(data) == FOURCC('M', 'x', 'O', 'b')) { - data2 = data; - data += 8; +#define IntoType(p) ((MxU32*) (p)) - MxDSObject* obj = DeserializeDSObjectDispatch(data, -1); - id = obj->GetObjectId(); - delete obj; + while (data < p_buffer + p_size) { + if (*IntoType(data) == FOURCC('M', 'x', 'O', 'b')) { + data2 = data; + data = data2 + 8; - data = MxDSChunk::End(data2); - while (data < end) { - if (*MxDSChunk::IntoType(data) == FOURCC('M', 'x', 'C', 'h')) { - MxU8* data3 = data; - MxU32* psize = MxDSChunk::IntoLength(data); - data += MxDSChunk::Size(*psize); + MxDSObject* obj = DeserializeDSObjectDispatch(data, -1); + id = obj->GetObjectId(); + delete obj; - if ((*MxDSChunk::IntoType(data2) == FOURCC('M', 'x', 'C', 'h')) && - (*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_SPLIT)) { - if (*MxStreamChunk::IntoObjectId(data2) == *MxStreamChunk::IntoObjectId(data3) && - (*MxStreamChunk::IntoFlags(data3) & DS_CHUNK_SPLIT) && - *MxStreamChunk::IntoTime(data2) == *MxStreamChunk::IntoTime(data3)) { - MxDSBuffer::Append(data2, data3); - continue; - } - else { - *MxStreamChunk::IntoFlags(data2) &= ~DS_CHUNK_SPLIT; - } + data = MxDSChunk::End(data2); + while (data < p_buffer + p_size) { + if (*IntoType(data) == FOURCC('M', 'x', 'C', 'h')) { + MxU8* data3 = data; + data = MxDSChunk::End(data3); + + if ((*IntoType(data2) == FOURCC('M', 'x', 'C', 'h')) && + (*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_SPLIT)) { + if (*MxStreamChunk::IntoObjectId(data2) == *MxStreamChunk::IntoObjectId(data3) && + (*MxStreamChunk::IntoFlags(data3) & DS_CHUNK_SPLIT) && + *MxStreamChunk::IntoTime(data2) == *MxStreamChunk::IntoTime(data3)) { + MxDSBuffer::Append(data2, data3); + continue; } - - data2 += MxDSChunk::Size(*MxDSChunk::IntoLength(data2)); - memcpy(data2, data3, MxDSChunk::Size(*psize)); - - if (*MxStreamChunk::IntoObjectId(data2) == id && - (*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_END_OF_STREAM)) { - break; + else { + *MxStreamChunk::IntoFlags(data2) &= ~DS_CHUNK_SPLIT; } } - else { - data++; + + data2 = MxDSChunk::End(data2); + memcpy(data2, data3, MxDSChunk::Size(data3)); + + if (*MxStreamChunk::IntoObjectId(data2) == id && + (*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_END_OF_STREAM)) { + break; } } + else { + data++; + } } - else { - data++; - } - } while (data < end); + } + else { + data++; + } } *MxStreamChunk::IntoFlags(data2) &= ~DS_CHUNK_SPLIT; - return MxDSChunk::End(data2) - p_buffer; + return MxDSChunk::Size(data2) + (MxU32) (data2 - p_buffer); + +#undef IntoType } diff --git a/LEGO1/omni/src/stream/mxstreamchunk.cpp b/LEGO1/omni/src/stream/mxstreamchunk.cpp index 24c13445..7944b2f2 100644 --- a/LEGO1/omni/src/stream/mxstreamchunk.cpp +++ b/LEGO1/omni/src/stream/mxstreamchunk.cpp @@ -96,6 +96,7 @@ MxU32* MxStreamChunk::IntoObjectId(MxU8* p_buffer) } // FUNCTION: LEGO1 0x100c31a0 +// FUNCTION: BETA10 0x10151626 MxLong* MxStreamChunk::IntoTime(MxU8* p_buffer) { return (MxLong*) (p_buffer + 0x0e); diff --git a/LEGO1/realtime/matrix.h b/LEGO1/realtime/matrix.h index 8704d739..c792f4da 100644 --- a/LEGO1/realtime/matrix.h +++ b/LEGO1/realtime/matrix.h @@ -3,358 +3,53 @@ #include "vector.h" -#include <memory.h> +// Note: virtual function overloads appear in the virtual table +// in reverse order of appearance. struct UnknownMatrixType { float m_data[4][4]; }; -// Note: Many functions most likely take const references/pointers instead of non-const. -// The class needs to undergo a very careful refactoring to fix that (no matches should break). - // VTABLE: LEGO1 0x100d4350 // VTABLE: BETA10 0x101b8340 // SIZE 0x08 class Matrix4 { +protected: + float (*m_data)[4]; + public: // FUNCTION: LEGO1 0x10004500 // FUNCTION: BETA10 0x1000fc70 Matrix4(float (*p_data)[4]) { SetData(p_data); } - // Note: virtual function overloads appear in the virtual table - // in reverse order of appearance. - - // FUNCTION: LEGO1 0x10002320 - // FUNCTION: BETA10 0x1000fcb0 - virtual void Equals(float (*p_data)[4]) { memcpy(m_data, p_data, sizeof(float) * 4 * 4); } // vtable+0x04 - - // FUNCTION: LEGO1 0x10002340 - // FUNCTION: BETA10 0x1000fcf0 - virtual void Equals(const Matrix4& p_matrix) - { - memcpy(m_data, p_matrix.m_data, sizeof(float) * 4 * 4); - } // vtable+0x00 - - // FUNCTION: LEGO1 0x10002360 - // FUNCTION: BETA10 0x1000fd30 - virtual void SetData(float (*p_data)[4]) { m_data = p_data; } // vtable+0x0c - - // FUNCTION: LEGO1 0x10002370 - // FUNCTION: BETA10 0x1000fd60 - virtual void SetData(UnknownMatrixType& p_matrix) { m_data = p_matrix.m_data; } // vtable+0x08 - - // FUNCTION: LEGO1 0x10002380 - // FUNCTION: BETA10 0x1000fd90 - virtual float (*GetData())[4] { return m_data; } // vtable+0x14 - - // FUNCTION: LEGO1 0x10002390 - // FUNCTION: BETA10 0x1000fdc0 - virtual float (*GetData() const)[4] { return m_data; } // vtable+0x10 - - // FUNCTION: LEGO1 0x100023a0 - // FUNCTION: BETA10 0x1000fdf0 - virtual float* Element(int p_row, int p_col) { return &m_data[p_row][p_col]; } // vtable+0x1c - - // FUNCTION: LEGO1 0x100023c0 - // FUNCTION: BETA10 0x1000fe30 - virtual const float* Element(int p_row, int p_col) const { return &m_data[p_row][p_col]; } // vtable+0x18 - - // FUNCTION: LEGO1 0x100023e0 - // FUNCTION: BETA10 0x1000fe70 - virtual void Clear() { memset(m_data, 0, 16 * sizeof(float)); } // vtable+0x20 - - // FUNCTION: LEGO1 0x100023f0 - // FUNCTION: BETA10 0x1000feb0 - virtual void SetIdentity() - { - Clear(); - m_data[0][0] = 1.0f; - m_data[1][1] = 1.0f; - m_data[2][2] = 1.0f; - m_data[3][3] = 1.0f; - } // vtable+0x24 - - // FUNCTION: LEGO1 0x10002420 - // FUNCTION: BETA10 0x1000ff20 - virtual void operator=(const Matrix4& p_matrix) { Equals(p_matrix); } // vtable+0x28 - - // FUNCTION: LEGO1 0x10002430 - // FUNCTION: BETA10 0x1000ff50 - virtual Matrix4& operator+=(float (*p_data)[4]) - { - for (int i = 0; i < 16; i++) { - ((float*) m_data)[i] += ((float*) p_data)[i]; - } - return *this; - } // vtable+0x2c - - // FUNCTION: LEGO1 0x10002460 - // FUNCTION: BETA10 0x1000ffc0 - virtual void TranslateBy(const float& p_x, const float& p_y, const float& p_z) - { - m_data[3][0] += p_x; - m_data[3][1] += p_y; - m_data[3][2] += p_z; - } // vtable+0x30 - - // FUNCTION: LEGO1 0x100024a0 - // FUNCTION: BETA10 0x10010040 - virtual void SetTranslation(const float& p_x, const float& p_y, const float& p_z) - { - m_data[3][0] = p_x; - m_data[3][1] = p_y; - m_data[3][2] = p_z; - } // vtable+0x34 - - // FUNCTION: LEGO1 0x100024d0 - // FUNCTION: BETA10 0x100100a0 - virtual void Product(float (*p_a)[4], float (*p_b)[4]) - { - float* cur = (float*) m_data; - for (int row = 0; row < 4; row++) { - for (int col = 0; col < 4; col++) { - *cur = 0.0f; - for (int k = 0; k < 4; k++) { - *cur += p_a[row][k] * p_b[k][col]; - } - cur++; - } - } - } // vtable+0x3c - - // FUNCTION: LEGO1 0x10002530 - // FUNCTION: BETA10 0x10010180 - virtual void Product(const Matrix4& p_a, const Matrix4& p_b) { Product(p_a.m_data, p_b.m_data); } // vtable+0x38 - - inline virtual void ToQuaternion(Vector4& p_resultQuat); // vtable+0x40 - inline virtual int FromQuaternion(const Vector4& p_vec); // vtable+0x44 - - // FUNCTION: LEGO1 0x100a0ff0 - // FUNCTION: BETA10 0x1001fe60 - void Scale(const float& p_x, const float& p_y, const float& p_z) - { - for (int i = 0; i < 4; i++) { - m_data[i][0] *= p_x; - m_data[i][1] *= p_y; - m_data[i][2] *= p_z; - } - } - - // FUNCTION: BETA10 0x1001c6a0 - void RotateX(const float& p_angle) - { - float s = sin(p_angle); - float c = cos(p_angle); - float matrix[4][4]; - memcpy(matrix, m_data, sizeof(float) * 16); - for (int i = 0; i < 4; i++) { - m_data[i][1] = matrix[i][1] * c - matrix[i][2] * s; - m_data[i][2] = matrix[i][2] * c + matrix[i][1] * s; - } - } - - // FUNCTION: BETA10 0x1001fd60 - void RotateY(const float& p_angle) - { - float s = sin(p_angle); - float c = cos(p_angle); - float matrix[4][4]; - memcpy(matrix, m_data, sizeof(float) * 16); - for (int i = 0; i < 4; i++) { - m_data[i][0] = matrix[i][0] * c + matrix[i][2] * s; - m_data[i][2] = matrix[i][2] * c - matrix[i][0] * s; - } - } - - // FUNCTION: BETA10 0x1006ab10 - void RotateZ(const float& p_angle) - { - float s = sin(p_angle); - float c = cos(p_angle); - float matrix[4][4]; - memcpy(matrix, m_data, sizeof(float) * 16); - for (int i = 0; i < 4; i++) { - m_data[i][0] = matrix[i][0] * c - matrix[i][1] * s; - m_data[i][1] = matrix[i][1] * c + matrix[i][0] * s; - } - } + inline virtual void Equals(float (*p_data)[4]); // vtable+0x04 + inline virtual void Equals(const Matrix4& p_matrix); // vtable+0x00 + inline virtual void SetData(float (*p_data)[4]); // vtable+0x0c + inline virtual void SetData(UnknownMatrixType& p_matrix); // vtable+0x08 + inline virtual float (*GetData())[4]; // vtable+0x14 + inline virtual float (*GetData() const)[4]; // vtable+0x10 + inline virtual float* Element(int p_row, int p_col); // vtable+0x1c + inline virtual const float* Element(int p_row, int p_col) const; // vtable+0x18 + inline virtual void Clear(); // vtable+0x20 + inline virtual void SetIdentity(); // vtable+0x24 + inline virtual void operator=(const Matrix4& p_matrix); // vtable+0x28 + inline virtual Matrix4& operator+=(float (*p_data)[4]); // vtable+0x2c + inline virtual void TranslateBy(const float& p_x, const float& p_y, const float& p_z); // vtable+0x30 + inline virtual void SetTranslation(const float& p_x, const float& p_y, const float& p_z); // vtable+0x34 + inline virtual void Product(float (*p_a)[4], float (*p_b)[4]); // vtable+0x3c + inline virtual void Product(const Matrix4& p_a, const Matrix4& p_b); // vtable+0x38 + inline virtual void ToQuaternion(Vector4& p_resultQuat); // vtable+0x40 + inline virtual int FromQuaternion(const Vector4& p_vec); // vtable+0x44 + inline void Scale(const float& p_x, const float& p_y, const float& p_z); + inline void RotateX(const float& p_angle); + inline void RotateY(const float& p_angle); + inline void RotateZ(const float& p_angle); inline int BETA_1005a590(Matrix4& p_mat); - - // FUNCTION: LEGO1 0x1006b500 - void Swap(int p_d1, int p_d2) - { - for (int i = 0; i < 4; i++) { - float e = m_data[p_d1][i]; - m_data[p_d1][i] = m_data[p_d2][i]; - m_data[p_d2][i] = e; - } - } + inline void Swap(int p_d1, int p_d2); float* operator[](int idx) { return m_data[idx]; } const float* operator[](int idx) const { return m_data[idx]; } - -protected: - float (*m_data)[4]; }; -// FUNCTION: LEGO1 0x10002550 -// FUNCTION: BETA10 0x100101c0 -inline void Matrix4::ToQuaternion(Vector4& p_outQuat) -{ - float trace; - float localc = m_data[0][0] + m_data[1][1] + m_data[2][2]; - - if (localc > 0) { - trace = (float) sqrt(localc + 1.0); - p_outQuat[3] = trace * 0.5f; - trace = 0.5f / trace; - p_outQuat[0] = (m_data[2][1] - m_data[1][2]) * trace; - p_outQuat[1] = (m_data[0][2] - m_data[2][0]) * trace; - p_outQuat[2] = (m_data[1][0] - m_data[0][1]) * trace; - } - else { - // GLOBAL: LEGO1 0x100d4090 - static int rotateIndex[] = {1, 2, 0}; - - // Largest element along the trace - int largest = 0; - if (m_data[0][0] < m_data[1][1]) { - largest = 1; - } - if (*Element(largest, largest) < m_data[2][2]) { - largest = 2; - } - - int next = rotateIndex[largest]; - int nextNext = rotateIndex[next]; - - trace = (float) sqrt(*Element(largest, largest) - (*Element(nextNext, nextNext) + *Element(next, next)) + 1.0); - - p_outQuat[largest] = trace * 0.5f; - trace = 0.5f / trace; - - p_outQuat[3] = (*Element(nextNext, next) - *Element(next, nextNext)) * trace; - p_outQuat[next] = (*Element(largest, next) + *Element(next, largest)) * trace; - p_outQuat[nextNext] = (*Element(largest, nextNext) + *Element(nextNext, largest)) * trace; - } -} - -// FUNCTION: LEGO1 0x10002710 -// FUNCTION: BETA10 0x10010550 -inline int Matrix4::FromQuaternion(const Vector4& p_vec) -{ - float local14 = p_vec.LenSquared(); - - if (local14 > 0.0f) { - local14 = 2.0f / local14; - - float local24 = p_vec[0] * local14; - float local34 = p_vec[1] * local14; - float local10 = p_vec[2] * local14; - - float local28 = p_vec[3] * local24; - float local2c = p_vec[3] * local34; - float local30 = p_vec[3] * local10; - - float local38 = p_vec[0] * local24; - float local8 = p_vec[0] * local34; - float localc = p_vec[0] * local10; - - float local18 = p_vec[1] * local34; - float local1c = p_vec[1] * local10; - float local20 = p_vec[2] * local10; - - m_data[0][0] = 1.0f - (local18 + local20); - m_data[1][0] = local8 + local30; - m_data[2][0] = localc - local2c; - - m_data[0][1] = local8 - local30; - m_data[1][1] = 1.0f - (local38 + local20); - m_data[2][1] = local1c + local28; - - m_data[0][2] = local2c + localc; - m_data[1][2] = local1c - local28; - m_data[2][2] = 1.0f - (local18 + local38); - - m_data[3][0] = 0.0f; - m_data[3][1] = 0.0f; - m_data[3][2] = 0.0f; - m_data[3][3] = 1.0f; - - m_data[0][3] = 0.0f; - m_data[1][3] = 0.0f; - m_data[2][3] = 0.0f; - return 0; - } - else { - return -1; - } -} - -// FUNCTION: BETA10 0x1005a590 -inline int Matrix4::BETA_1005a590(Matrix4& p_mat) -{ - float local5c[4][4]; - Matrix4 localc(local5c); - - ((Matrix4&) localc) = *this; - p_mat.SetIdentity(); - - for (int i = 0; i < 4; i++) { - int local1c = i; - int local10; - - for (local10 = i + 1; local10 < 4; local10++) { - if (fabs(localc[local1c][i]) < fabs(localc[local10][i])) { - local1c = local10; - } - } - - if (local1c != i) { - localc.Swap(local1c, i); - p_mat.Swap(local1c, i); - } - - if (localc[i][i] < 0.001f && localc[i][i] > -0.001f) { - return -1; - } - - float local60 = localc[i][i]; - int local18; - - for (local18 = 0; local18 < 4; local18++) { - p_mat[i][local18] /= local60; - } - - for (local18 = 0; local18 < 4; local18++) { - localc[i][local18] /= local60; - } - - for (local10 = 0; local10 < 4; local10++) { - if (i != local10) { - float afStack70[4]; - - for (local18 = 0; local18 < 4; local18++) { - afStack70[local18] = p_mat[i][local18] * localc[local10][i]; - } - - for (local18 = 0; local18 < 4; local18++) { - p_mat[local10][local18] -= afStack70[local18]; - } - - for (local18 = 0; local18 < 4; local18++) { - afStack70[local18] = localc[i][local18] * localc[local10][i]; - } - - for (local18 = 0; local18 < 4; local18++) { - localc[local10][local18] -= afStack70[local18]; - } - } - } - } - - return 0; -} - #endif // MATRIX_H diff --git a/LEGO1/realtime/matrix4d.inl.h b/LEGO1/realtime/matrix4d.inl.h new file mode 100644 index 00000000..2bf22a85 --- /dev/null +++ b/LEGO1/realtime/matrix4d.inl.h @@ -0,0 +1,365 @@ +#ifndef MATRIX4D_H +#define MATRIX4D_H + +#include "matrix.h" + +#include <math.h> +#include <memory.h> + +// FUNCTION: LEGO1 0x10002320 +// FUNCTION: BETA10 0x1000fcb0 +void Matrix4::Equals(float (*p_data)[4]) +{ + memcpy(m_data, p_data, sizeof(float) * 4 * 4); +} + +// FUNCTION: LEGO1 0x10002340 +// FUNCTION: BETA10 0x1000fcf0 +void Matrix4::Equals(const Matrix4& p_matrix) +{ + memcpy(m_data, p_matrix.m_data, sizeof(float) * 4 * 4); +} + +// FUNCTION: LEGO1 0x10002360 +// FUNCTION: BETA10 0x1000fd30 +void Matrix4::SetData(float (*p_data)[4]) +{ + m_data = p_data; +} + +// FUNCTION: LEGO1 0x10002370 +// FUNCTION: BETA10 0x1000fd60 +void Matrix4::SetData(UnknownMatrixType& p_matrix) +{ + m_data = p_matrix.m_data; +} + +// FUNCTION: LEGO1 0x10002380 +// FUNCTION: BETA10 0x1000fd90 +float (*Matrix4::GetData())[4] +{ + return m_data; +} + +// FUNCTION: LEGO1 0x10002390 +// FUNCTION: BETA10 0x1000fdc0 +float (*Matrix4::GetData() const)[4] +{ + return m_data; +} + +// FUNCTION: LEGO1 0x100023a0 +// FUNCTION: BETA10 0x1000fdf0 +float* Matrix4::Element(int p_row, int p_col) +{ + return &m_data[p_row][p_col]; +} + +// FUNCTION: LEGO1 0x100023c0 +// FUNCTION: BETA10 0x1000fe30 +const float* Matrix4::Element(int p_row, int p_col) const +{ + return &m_data[p_row][p_col]; +} + +// FUNCTION: LEGO1 0x100023e0 +// FUNCTION: BETA10 0x1000fe70 +void Matrix4::Clear() +{ + memset(m_data, 0, 16 * sizeof(float)); +} + +// FUNCTION: LEGO1 0x100023f0 +// FUNCTION: BETA10 0x1000feb0 +void Matrix4::SetIdentity() +{ + Clear(); + m_data[0][0] = 1.0f; + m_data[1][1] = 1.0f; + m_data[2][2] = 1.0f; + m_data[3][3] = 1.0f; +} + +// FUNCTION: LEGO1 0x10002420 +// FUNCTION: BETA10 0x1000ff20 +void Matrix4::operator=(const Matrix4& p_matrix) +{ + Equals(p_matrix); +} + +// FUNCTION: LEGO1 0x10002430 +// FUNCTION: BETA10 0x1000ff50 +Matrix4& Matrix4::operator+=(float (*p_data)[4]) +{ + for (int i = 0; i < 16; i++) { + ((float*) m_data)[i] += ((float*) p_data)[i]; + } + + return *this; +} + +// FUNCTION: LEGO1 0x10002460 +// FUNCTION: BETA10 0x1000ffc0 +void Matrix4::TranslateBy(const float& p_x, const float& p_y, const float& p_z) +{ + m_data[3][0] += p_x; + m_data[3][1] += p_y; + m_data[3][2] += p_z; +} + +// FUNCTION: LEGO1 0x100024a0 +// FUNCTION: BETA10 0x10010040 +void Matrix4::SetTranslation(const float& p_x, const float& p_y, const float& p_z) +{ + m_data[3][0] = p_x; + m_data[3][1] = p_y; + m_data[3][2] = p_z; +} + +// FUNCTION: LEGO1 0x100024d0 +// FUNCTION: BETA10 0x100100a0 +void Matrix4::Product(float (*p_a)[4], float (*p_b)[4]) +{ + float* cur = (float*) m_data; + + for (int row = 0; row < 4; row++) { + for (int col = 0; col < 4; col++) { + *cur = 0.0f; + for (int k = 0; k < 4; k++) { + *cur += p_a[row][k] * p_b[k][col]; + } + cur++; + } + } +} + +// FUNCTION: LEGO1 0x10002530 +// FUNCTION: BETA10 0x10010180 +void Matrix4::Product(const Matrix4& p_a, const Matrix4& p_b) +{ + Product(p_a.m_data, p_b.m_data); +} + +// FUNCTION: LEGO1 0x10002550 +// FUNCTION: BETA10 0x100101c0 +void Matrix4::ToQuaternion(Vector4& p_outQuat) +{ + float trace; + float localc = m_data[0][0] + m_data[1][1] + m_data[2][2]; + + if (localc > 0) { + trace = (float) sqrt(localc + 1.0); + p_outQuat[3] = trace * 0.5f; + trace = 0.5f / trace; + p_outQuat[0] = (m_data[2][1] - m_data[1][2]) * trace; + p_outQuat[1] = (m_data[0][2] - m_data[2][0]) * trace; + p_outQuat[2] = (m_data[1][0] - m_data[0][1]) * trace; + } + else { + // GLOBAL: LEGO1 0x100d4090 + static int rotateIndex[] = {1, 2, 0}; + + // Largest element along the trace + int largest = 0; + if (m_data[0][0] < m_data[1][1]) { + largest = 1; + } + if (*Element(largest, largest) < m_data[2][2]) { + largest = 2; + } + + int next = rotateIndex[largest]; + int nextNext = rotateIndex[next]; + + trace = (float) sqrt(*Element(largest, largest) - (*Element(nextNext, nextNext) + *Element(next, next)) + 1.0); + + p_outQuat[largest] = trace * 0.5f; + trace = 0.5f / trace; + + p_outQuat[3] = (*Element(nextNext, next) - *Element(next, nextNext)) * trace; + p_outQuat[next] = (*Element(largest, next) + *Element(next, largest)) * trace; + p_outQuat[nextNext] = (*Element(largest, nextNext) + *Element(nextNext, largest)) * trace; + } +} + +// FUNCTION: LEGO1 0x10002710 +// FUNCTION: BETA10 0x10010550 +int Matrix4::FromQuaternion(const Vector4& p_vec) +{ + float local14 = p_vec.LenSquared(); + + if (local14 > 0.0f) { + local14 = 2.0f / local14; + + float local24 = p_vec[0] * local14; + float local34 = p_vec[1] * local14; + float local10 = p_vec[2] * local14; + + float local28 = p_vec[3] * local24; + float local2c = p_vec[3] * local34; + float local30 = p_vec[3] * local10; + + float local38 = p_vec[0] * local24; + float local8 = p_vec[0] * local34; + float localc = p_vec[0] * local10; + + float local18 = p_vec[1] * local34; + float local1c = p_vec[1] * local10; + float local20 = p_vec[2] * local10; + + m_data[0][0] = 1.0f - (local18 + local20); + m_data[1][0] = local8 + local30; + m_data[2][0] = localc - local2c; + + m_data[0][1] = local8 - local30; + m_data[1][1] = 1.0f - (local38 + local20); + m_data[2][1] = local1c + local28; + + m_data[0][2] = local2c + localc; + m_data[1][2] = local1c - local28; + m_data[2][2] = 1.0f - (local18 + local38); + + m_data[3][0] = 0.0f; + m_data[3][1] = 0.0f; + m_data[3][2] = 0.0f; + m_data[3][3] = 1.0f; + + m_data[0][3] = 0.0f; + m_data[1][3] = 0.0f; + m_data[2][3] = 0.0f; + return 0; + } + else { + return -1; + } +} + +// FUNCTION: LEGO1 0x100a0ff0 +// FUNCTION: BETA10 0x1001fe60 +void Matrix4::Scale(const float& p_x, const float& p_y, const float& p_z) +{ + for (int i = 0; i < 4; i++) { + m_data[i][0] *= p_x; + m_data[i][1] *= p_y; + m_data[i][2] *= p_z; + } +} + +// FUNCTION: BETA10 0x1001c6a0 +void Matrix4::RotateX(const float& p_angle) +{ + float s = sin(p_angle); + float c = cos(p_angle); + float matrix[4][4]; + memcpy(matrix, m_data, sizeof(float) * 16); + + for (int i = 0; i < 4; i++) { + m_data[i][1] = matrix[i][1] * c - matrix[i][2] * s; + m_data[i][2] = matrix[i][2] * c + matrix[i][1] * s; + } +} + +// FUNCTION: BETA10 0x1001fd60 +void Matrix4::RotateY(const float& p_angle) +{ + float s = sin(p_angle); + float c = cos(p_angle); + float matrix[4][4]; + memcpy(matrix, m_data, sizeof(float) * 16); + + for (int i = 0; i < 4; i++) { + m_data[i][0] = matrix[i][0] * c + matrix[i][2] * s; + m_data[i][2] = matrix[i][2] * c - matrix[i][0] * s; + } +} + +// FUNCTION: BETA10 0x1006ab10 +void Matrix4::RotateZ(const float& p_angle) +{ + float s = sin(p_angle); + float c = cos(p_angle); + float matrix[4][4]; + memcpy(matrix, m_data, sizeof(float) * 16); + + for (int i = 0; i < 4; i++) { + m_data[i][0] = matrix[i][0] * c - matrix[i][1] * s; + m_data[i][1] = matrix[i][1] * c + matrix[i][0] * s; + } +} + +// FUNCTION: BETA10 0x1005a590 +int Matrix4::BETA_1005a590(Matrix4& p_mat) +{ + float local5c[4][4]; + Matrix4 localc(local5c); + + ((Matrix4&) localc) = *this; + p_mat.SetIdentity(); + + for (int i = 0; i < 4; i++) { + int local1c = i; + int local10; + + for (local10 = i + 1; local10 < 4; local10++) { + if (fabs(localc[local1c][i]) < fabs(localc[local10][i])) { + local1c = local10; + } + } + + if (local1c != i) { + localc.Swap(local1c, i); + p_mat.Swap(local1c, i); + } + + if (localc[i][i] < 0.001f && localc[i][i] > -0.001f) { + return -1; + } + + float local60 = localc[i][i]; + int local18; + + for (local18 = 0; local18 < 4; local18++) { + p_mat[i][local18] /= local60; + } + + for (local18 = 0; local18 < 4; local18++) { + localc[i][local18] /= local60; + } + + for (local10 = 0; local10 < 4; local10++) { + if (i != local10) { + float afStack70[4]; + + for (local18 = 0; local18 < 4; local18++) { + afStack70[local18] = p_mat[i][local18] * localc[local10][i]; + } + + for (local18 = 0; local18 < 4; local18++) { + p_mat[local10][local18] -= afStack70[local18]; + } + + for (local18 = 0; local18 < 4; local18++) { + afStack70[local18] = localc[i][local18] * localc[local10][i]; + } + + for (local18 = 0; local18 < 4; local18++) { + localc[local10][local18] -= afStack70[local18]; + } + } + } + } + + return 0; +} + +// FUNCTION: LEGO1 0x1006b500 +void Matrix4::Swap(int p_d1, int p_d2) +{ + for (int i = 0; i < 4; i++) { + float e = m_data[p_d1][i]; + m_data[p_d1][i] = m_data[p_d2][i]; + m_data[p_d2][i] = e; + } +} + +#endif // MATRIX4D_H diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index e3e71476..defaab57 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -3,173 +3,54 @@ #include "compat.h" -#include <math.h> -#include <memory.h> - -// Note: Many functions most likely take const references/pointers instead of non-const. -// The class needs to undergo a very careful refactoring to fix that (no matches should break). +// Note: virtual function overloads appear in the virtual table +// in reverse order of appearance. // VTABLE: LEGO1 0x100d4288 // VTABLE: BETA10 0x101b8440 // SIZE 0x08 class Vector2 { +protected: + inline virtual void AddImpl(const float* p_value); // vtable+0x04 + inline virtual void AddImpl(float p_value); // vtable+0x00 + inline virtual void SubImpl(const float* p_value); // vtable+0x08 + inline virtual void MulImpl(const float* p_value); // vtable+0x10 + inline virtual void MulImpl(const float& p_value); // vtable+0x0c + inline virtual void DivImpl(const float& p_value); // vtable+0x14 + inline virtual float DotImpl(const float* p_a, const float* p_b) const; // vtable+0x18 + inline virtual void SetData(float* p_data); // vtable+0x1c + inline virtual void EqualsImpl(const float* p_data); // vtable+0x20 + + float* m_data; // 0x04 + public: // FUNCTION: LEGO1 0x1000c0f0 // FUNCTION: BETA10 0x100116a0 Vector2(float* p_data) { SetData(p_data); } - // Note: virtual function overloads appear in the virtual table - // in reverse order of appearance. + // FUNCTION: BETA10 0x100109e0 + Vector2(const float* p_data) { m_data = (float*) p_data; } - // FUNCTION: LEGO1 0x10001f80 - virtual void AddImpl(const float* p_value) - { - m_data[0] += p_value[0]; - m_data[1] += p_value[1]; - } // vtable+0x04 - - // FUNCTION: LEGO1 0x10001fa0 - virtual void AddImpl(float p_value) - { - m_data[0] += p_value; - m_data[1] += p_value; - } // vtable+0x00 - - // FUNCTION: LEGO1 0x10001fc0 - virtual void SubImpl(const float* p_value) - { - m_data[0] -= p_value[0]; - m_data[1] -= p_value[1]; - } // vtable+0x08 - - // FUNCTION: LEGO1 0x10001fe0 - virtual void MulImpl(const float* p_value) - { - m_data[0] *= p_value[0]; - m_data[1] *= p_value[1]; - } // vtable+0x10 - - // FUNCTION: LEGO1 0x10002000 - virtual void MulImpl(const float& p_value) - { - m_data[0] *= p_value; - m_data[1] *= p_value; - } // vtable+0x0c - - // FUNCTION: LEGO1 0x10002020 - virtual void DivImpl(const float& p_value) - { - m_data[0] /= p_value; - m_data[1] /= p_value; - } // vtable+0x14 - - // FUNCTION: LEGO1 0x10002040 - virtual float DotImpl(const float* p_a, const float* p_b) const - { - return p_b[0] * p_a[0] + p_b[1] * p_a[1]; - } // vtable+0x18 - - // FUNCTION: LEGO1 0x10002060 - // FUNCTION: BETA10 0x10010c90 - virtual void SetData(float* p_data) { m_data = p_data; } // vtable+0x1c - - // FUNCTION: LEGO1 0x10002070 - virtual void EqualsImpl(const float* p_data) { memcpy(m_data, p_data, sizeof(float) * 2); } // vtable+0x20 - - // FUNCTION: LEGO1 0x10002090 - virtual float* GetData() { return m_data; } // vtable+0x28 - - // FUNCTION: LEGO1 0x100020a0 - virtual const float* GetData() const { return m_data; } // vtable+0x24 - - // FUNCTION: LEGO1 0x100020b0 - virtual void Clear() { memset(m_data, 0, sizeof(float) * 2); } // vtable+0x2c - - // FUNCTION: LEGO1 0x100020d0 - virtual float Dot(const float* p_a, const float* p_b) const { return DotImpl(p_a, p_b); } // vtable+0x3c - - // FUNCTION: LEGO1 0x100020f0 - // FUNCTION: BETA10 0x100108c0 - virtual float Dot(const Vector2& p_a, const Vector2& p_b) const - { - return DotImpl(p_a.m_data, p_b.m_data); - } // vtable+0x38 - - // FUNCTION: LEGO1 0x10002110 - virtual float Dot(const float* p_a, const Vector2& p_b) const { return DotImpl(p_a, p_b.m_data); } // vtable+0x34 - - // FUNCTION: LEGO1 0x10002130 - virtual float Dot(const Vector2& p_a, const float* p_b) const { return DotImpl(p_a.m_data, p_b); } // vtable+0x30 - - // FUNCTION: LEGO1 0x10002150 - virtual float LenSquared() const { return m_data[0] * m_data[0] + m_data[1] * m_data[1]; } // vtable+0x40 - - // FUNCTION: LEGO1 0x10002160 - // FUNCTION: BETA10 0x10010900 - virtual int Unitize() - { - float sq = LenSquared(); - - if (sq > 0.0f) { - float root = sqrt(sq); - if (root > 0.0f) { - DivImpl(root); - return 0; - } - } - - return -1; - } // vtable+0x44 - - // FUNCTION: LEGO1 0x100021c0 - virtual void operator+=(float p_value) { AddImpl(p_value); } // vtable+0x50 - - // FUNCTION: LEGO1 0x100021d0 - virtual void operator+=(const float* p_other) { AddImpl(p_other); } // vtable+0x4c - - // FUNCTION: LEGO1 0x100021e0 - virtual void operator+=(const Vector2& p_other) { AddImpl(p_other.m_data); } // vtable+0x48 - - // FUNCTION: LEGO1 0x100021f0 - virtual void operator-=(const float* p_other) { SubImpl(p_other); } // vtable+0x58 - - // FUNCTION: LEGO1 0x10002200 - virtual void operator-=(const Vector2& p_other) { SubImpl(p_other.m_data); } // vtable+0x54 - - // FUNCTION: LEGO1 0x10002210 - virtual void operator*=(const float* p_other) { MulImpl(p_other); } // vtable+0x64 - - // FUNCTION: LEGO1 0x10002220 - virtual void operator*=(const Vector2& p_other) { MulImpl(p_other.m_data); } // vtable+0x60 - - // FUNCTION: LEGO1 0x10002230 - virtual void operator*=(const float& p_value) { MulImpl(p_value); } // vtable+0x5c - - // FUNCTION: LEGO1 0x10002240 - virtual void operator/=(const float& p_value) { DivImpl(p_value); } // vtable+0x68 - - // FUNCTION: LEGO1 0x10002250 - virtual void SetVector(const float* p_other) { EqualsImpl(p_other); } // vtable+0x70 - - // FUNCTION: LEGO1 0x10002260 - // FUNCTION: BETA10 0x100110c0 - virtual void SetVector(const Vector2& p_other) { EqualsImpl(p_other.m_data); } // vtable+0x6c - - // Note: it's unclear whether Vector3::operator= has been defined explicitly - // with the same function body as Vector2& operator=. The BETA indicates that; - // however, it makes LEGO1 0x10010be0 disappear and worsens matches in - // at least these functions: - // LEGO1 0x100109b0 - // LEGO1 0x10023130 - // LEGO1 0x1002de10 - // LEGO1 0x10050a80 - // LEGO1 0x10053980 - // LEGO1 0x100648f0 - // LEGO1 0x10064b50 - // LEGO1 0x10084030 - // LEGO1 0x100a9410 - // However, defining it as in the BETA improves at least these functions: - // LEGO1 0x10042300 + inline virtual float* GetData(); // vtable+0x28 + inline virtual const float* GetData() const; // vtable+0x24 + inline virtual void Clear(); // vtable+0x2c + inline virtual float Dot(const float* p_a, const float* p_b) const; // vtable+0x3c + inline virtual float Dot(const Vector2& p_a, const Vector2& p_b) const; // vtable+0x38 + inline virtual float Dot(const float* p_a, const Vector2& p_b) const; // vtable+0x34 + inline virtual float Dot(const Vector2& p_a, const float* p_b) const; // vtable+0x30 + inline virtual float LenSquared() const; // vtable+0x40 + inline virtual int Unitize(); // vtable+0x44 + inline virtual void operator+=(float p_value); // vtable+0x50 + inline virtual void operator+=(const float* p_other); // vtable+0x4c + inline virtual void operator+=(const Vector2& p_other); // vtable+0x48 + inline virtual void operator-=(const float* p_other); // vtable+0x58 + inline virtual void operator-=(const Vector2& p_other); // vtable+0x54 + inline virtual void operator*=(const float* p_other); // vtable+0x64 + inline virtual void operator*=(const Vector2& p_other); // vtable+0x60 + inline virtual void operator*=(const float& p_value); // vtable+0x5c + inline virtual void operator/=(const float& p_value); // vtable+0x68 + inline virtual void operator=(const float* p_other); // vtable+0x70 + inline virtual void operator=(const Vector2& p_other); // vtable+0x6c // SYNTHETIC: LEGO1 0x10010be0 // SYNTHETIC: BETA10 0x100121e0 @@ -178,26 +59,28 @@ public: // SYNTHETIC: BETA10 0x1004af40 // Vector4::operator= - Vector2& operator=(const Vector2& p_other) - { - Vector2::SetVector(p_other); - return *this; - } - // FUNCTION: BETA10 0x1001d140 float& operator[](int idx) { return m_data[idx]; } // FUNCTION: BETA10 0x1001d170 const float& operator[](int idx) const { return m_data[idx]; } - -protected: - float* m_data; // 0x04 }; // VTABLE: LEGO1 0x100d4518 // VTABLE: BETA10 0x101b8398 // SIZE 0x08 class Vector3 : public Vector2 { +protected: + inline void AddImpl(const float* p_value) override; // vtable+0x04 + inline void AddImpl(float p_value) override; // vtable+0x00 + inline void SubImpl(const float* p_value) override; // vtable+0x08 + inline void MulImpl(const float* p_value) override; // vtable+0x10 + inline void MulImpl(const float& p_value) override; // vtable+0x0c + inline void DivImpl(const float& p_value) override; // vtable+0x14 + inline float DotImpl(const float* p_a, const float* p_b) const override; // vtable+0x18 + inline void EqualsImpl(const float* p_data) override; // vtable+0x20 + inline virtual void EqualsCrossImpl(const float* p_a, const float* p_b); // vtable+0x74 + public: // FUNCTION: LEGO1 0x1001d150 // FUNCTION: BETA10 0x10011660 @@ -209,111 +92,14 @@ public: // initialization with a const source fundamentally incompatible. // FUNCTION: BETA10 0x100109a0 - Vector3(const float* p_data) : Vector2((float*) p_data) {} + Vector3(const float* p_data) : Vector2(p_data) {} - // Note: virtual function overloads appear in the virtual table - // in reverse order of appearance. - - // FUNCTION: LEGO1 0x10002270 - // FUNCTION: BETA10 0x10011350 - virtual void EqualsCrossImpl(const float* p_a, const float* p_b) - { - m_data[0] = p_a[1] * p_b[2] - p_a[2] * p_b[1]; - m_data[1] = p_a[2] * p_b[0] - p_a[0] * p_b[2]; - m_data[2] = p_a[0] * p_b[1] - p_a[1] * p_b[0]; - } // vtable+0x74 - - // FUNCTION: LEGO1 0x100022c0 - // FUNCTION: BETA10 0x10011430 - virtual void EqualsCross(const Vector3& p_a, const Vector3& p_b) - { - EqualsCrossImpl(p_a.m_data, p_b.m_data); - } // vtable+0x80 - - // FUNCTION: LEGO1 0x100022e0 - virtual void EqualsCross(const Vector3& p_a, const float* p_b) { EqualsCrossImpl(p_a.m_data, p_b); } // vtable+0x7c - - // FUNCTION: LEGO1 0x10002300 - virtual void EqualsCross(const float* p_a, const Vector3& p_b) { EqualsCrossImpl(p_a, p_b.m_data); } // vtable+0x78 - - // FUNCTION: LEGO1 0x10003bf0 - virtual void Fill(const float& p_value) - { - m_data[0] = p_value; - m_data[1] = p_value; - m_data[2] = p_value; - } // vtable+0x84 - - // Vector2 overrides - - // FUNCTION: LEGO1 0x10003a60 - void AddImpl(const float* p_value) override - { - m_data[0] += p_value[0]; - m_data[1] += p_value[1]; - m_data[2] += p_value[2]; - } // vtable+0x04 - - // FUNCTION: LEGO1 0x10003a90 - void AddImpl(float p_value) override - { - m_data[0] += p_value; - m_data[1] += p_value; - m_data[2] += p_value; - } // vtable+0x00 - - // FUNCTION: LEGO1 0x10003ac0 - void SubImpl(const float* p_value) override - { - m_data[0] -= p_value[0]; - m_data[1] -= p_value[1]; - m_data[2] -= p_value[2]; - } // vtable+0x08 - - // FUNCTION: LEGO1 0x10003af0 - void MulImpl(const float* p_value) override - { - m_data[0] *= p_value[0]; - m_data[1] *= p_value[1]; - m_data[2] *= p_value[2]; - } // vtable+0x10 - - // FUNCTION: LEGO1 0x10003b20 - void MulImpl(const float& p_value) override - { - m_data[0] *= p_value; - m_data[1] *= p_value; - m_data[2] *= p_value; - } // vtable+0x0c - - // FUNCTION: LEGO1 0x10003b50 - void DivImpl(const float& p_value) override - { - m_data[0] /= p_value; - m_data[1] /= p_value; - m_data[2] /= p_value; - } // vtable+0x14 - - // FUNCTION: LEGO1 0x10003b80 - float DotImpl(const float* p_a, const float* p_b) const override - { - return p_a[0] * p_b[0] + p_a[2] * p_b[2] + p_a[1] * p_b[1]; - } // vtable+0x18 - - // FUNCTION: LEGO1 0x10003ba0 - // FUNCTION: BETA10 0x100113f0 - void EqualsImpl(const float* p_data) override { memcpy(m_data, p_data, sizeof(float) * 3); } // vtable+0x20 - - // FUNCTION: LEGO1 0x10003bc0 - // FUNCTION: BETA10 0x100114f0 - void Clear() override { memset(m_data, 0, sizeof(float) * 3); } // vtable+0x2c - - // FUNCTION: LEGO1 0x10003bd0 - // FUNCTION: BETA10 0x10011530 - float LenSquared() const override - { - return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2]; - } // vtable+0x40 + inline void Clear() override; // vtable+0x2c + inline float LenSquared() const override; // vtable+0x40 + inline virtual void EqualsCross(const Vector3& p_a, const Vector3& p_b); // vtable+0x80 + inline virtual void EqualsCross(const Vector3& p_a, const float* p_b); // vtable+0x7c + inline virtual void EqualsCross(const float* p_a, const Vector3& p_b); // vtable+0x78 + inline virtual void Fill(const float& p_value); // vtable+0x84 friend class Mx3DPointFloat; }; @@ -322,6 +108,16 @@ public: // VTABLE: BETA10 0x101bac38 // SIZE 0x08 class Vector4 : public Vector3 { +protected: + inline void AddImpl(const float* p_value) override; // vtable+0x04 + inline void AddImpl(float p_value) override; // vtable+0x00 + inline void SubImpl(const float* p_value) override; // vtable+0x08 + inline void MulImpl(const float* p_value) override; // vtable+0x10 + inline void MulImpl(const float& p_value) override; // vtable+0x0c + inline void DivImpl(const float& p_value) override; // vtable+0x14 + inline float DotImpl(const float* p_a, const float* p_b) const override; // vtable+0x18 + inline void EqualsImpl(const float* p_data) override; // vtable+0x20 + public: // FUNCTION: BETA10 0x10048780 Vector4(float* p_data) : Vector3(p_data) {} @@ -334,112 +130,16 @@ public: // supporting the theory that this decompilation is correct. // FUNCTION: BETA10 0x100701b0 - Vector4(const float* p_data) : Vector3((float*) p_data) {} - - // Note: virtual function overloads appear in the virtual table - // in reverse order of appearance. - - // FUNCTION: LEGO1 0x10002a40 - virtual void SetMatrixProduct(const float* p_vec, const float* p_mat) - { - m_data[0] = p_vec[0] * p_mat[0] + p_vec[1] * p_mat[4] + p_vec[2] * p_mat[8] + p_vec[3] * p_mat[12]; - m_data[1] = p_vec[0] * p_mat[1] + p_vec[1] * p_mat[5] + p_vec[2] * p_mat[9] + p_vec[4] * p_mat[13]; - m_data[2] = p_vec[0] * p_mat[2] + p_vec[1] * p_mat[6] + p_vec[2] * p_mat[10] + p_vec[4] * p_mat[14]; - m_data[3] = p_vec[0] * p_mat[3] + p_vec[1] * p_mat[7] + p_vec[2] * p_mat[11] + p_vec[4] * p_mat[15]; - } // vtable+0x8c - - // FUNCTION: LEGO1 0x10002ae0 - virtual void SetMatrixProduct(const Vector4& p_a, const float* p_b) - { - SetMatrixProduct(p_a.m_data, p_b); - } // vtable+0x88 + Vector4(const float* p_data) : Vector3(p_data) {} + inline void Clear() override; // vtable+0x2c + inline float LenSquared() const override; // vtable+0x40 + inline void Fill(const float& p_value) override; // vtable+0x84 + inline virtual void SetMatrixProduct(const float* p_vec, const float* p_mat); // vtable+0x8c + inline virtual void SetMatrixProduct(const Vector4& p_a, const float* p_b); // vtable+0x88 inline virtual int NormalizeQuaternion(); // vtable+0x90 inline virtual int EqualsHamiltonProduct(const Vector4& p_a, const Vector4& p_b); // vtable+0x94 - // Vector3 overrides - - // FUNCTION: LEGO1 0x10002870 - void AddImpl(const float* p_value) override - { - m_data[0] += p_value[0]; - m_data[1] += p_value[1]; - m_data[2] += p_value[2]; - m_data[3] += p_value[3]; - } // vtable+0x04 - - // FUNCTION: LEGO1 0x100028b0 - void AddImpl(float p_value) override - { - m_data[0] += p_value; - m_data[1] += p_value; - m_data[2] += p_value; - m_data[3] += p_value; - } // vtable+0x00 - - // FUNCTION: LEGO1 0x100028f0 - void SubImpl(const float* p_value) override - { - m_data[0] -= p_value[0]; - m_data[1] -= p_value[1]; - m_data[2] -= p_value[2]; - m_data[3] -= p_value[3]; - } // vtable+0x08 - - // FUNCTION: LEGO1 0x10002930 - void MulImpl(const float* p_value) override - { - m_data[0] *= p_value[0]; - m_data[1] *= p_value[1]; - m_data[2] *= p_value[2]; - m_data[3] *= p_value[3]; - } // vtable+0x10 - - // FUNCTION: LEGO1 0x10002970 - void MulImpl(const float& p_value) override - { - m_data[0] *= p_value; - m_data[1] *= p_value; - m_data[2] *= p_value; - m_data[3] *= p_value; - } // vtable+0x0c - - // FUNCTION: LEGO1 0x100029b0 - void DivImpl(const float& p_value) override - { - m_data[0] /= p_value; - m_data[1] /= p_value; - m_data[2] /= p_value; - m_data[3] /= p_value; - } // vtable+0x14 - - // FUNCTION: LEGO1 0x100029f0 - float DotImpl(const float* p_a, const float* p_b) const override - { - return p_a[0] * p_b[0] + p_a[2] * p_b[2] + (p_a[1] * p_b[1] + p_a[3] * p_b[3]); - } // vtable+0x18 - - // FUNCTION: LEGO1 0x10002a20 - void EqualsImpl(const float* p_data) override { memcpy(m_data, p_data, sizeof(float) * 4); } // vtable+0x20 - - // FUNCTION: LEGO1 0x10002b00 - void Clear() override { memset(m_data, 0, sizeof(float) * 4); } // vtable+0x2c - - // FUNCTION: LEGO1 0x10002b20 - float LenSquared() const override - { - return m_data[1] * m_data[1] + m_data[0] * m_data[0] + m_data[2] * m_data[2] + m_data[3] * m_data[3]; - } // vtable+0x40 - - // FUNCTION: LEGO1 0x10002b40 - void Fill(const float& p_value) override - { - m_data[0] = p_value; - m_data[1] = p_value; - m_data[2] = p_value; - m_data[3] = p_value; - } // vtable+0x84 - float& operator[](int idx) { return m_data[idx]; } // FUNCTION: BETA10 0x10010890 @@ -448,41 +148,4 @@ public: friend class Mx4DPointFloat; }; -// FUNCTION: LEGO1 0x10002b70 -// FUNCTION: BETA10 0x10048ad0 -inline int Vector4::NormalizeQuaternion() -{ - float length = m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2]; - - if (length > 0.0f) { - float theta = m_data[3] * 0.5f; - float magnitude = sin((double) theta); - m_data[3] = cos((double) theta); - - magnitude = magnitude / (float) sqrt((double) length); - m_data[0] *= magnitude; - m_data[1] *= magnitude; - m_data[2] *= magnitude; - return 0; - } - else { - return -1; - } -} - -// FUNCTION: LEGO1 0x10002bf0 -// FUNCTION: BETA10 0x10048c20 -inline int Vector4::EqualsHamiltonProduct(const Vector4& p_a, const Vector4& p_b) -{ - m_data[3] = p_a.m_data[3] * p_b.m_data[3] - - (p_a.m_data[0] * p_b.m_data[0] + p_a.m_data[2] * p_b.m_data[2] + p_a.m_data[1] * p_b.m_data[1]); - - Vector3::EqualsCrossImpl(p_a.m_data, p_b.m_data); - - m_data[0] = p_b.m_data[3] * p_a.m_data[0] + p_a.m_data[3] * p_b.m_data[0] + m_data[0]; - m_data[1] = p_b.m_data[1] * p_a.m_data[3] + p_a.m_data[1] * p_b.m_data[3] + m_data[1]; - m_data[2] = p_b.m_data[2] * p_a.m_data[3] + p_a.m_data[2] * p_b.m_data[3] + m_data[2]; - return 0; -} - #endif // VECTOR_H diff --git a/LEGO1/realtime/vector2d.inl.h b/LEGO1/realtime/vector2d.inl.h new file mode 100644 index 00000000..95e7ea7d --- /dev/null +++ b/LEGO1/realtime/vector2d.inl.h @@ -0,0 +1,203 @@ +#ifndef VECTOR2D_H +#define VECTOR2D_H + +#include "vector.h" + +#include <math.h> +#include <memory.h> + +// FUNCTION: LEGO1 0x10001f80 +void Vector2::AddImpl(const float* p_value) +{ + m_data[0] += p_value[0]; + m_data[1] += p_value[1]; +} + +// FUNCTION: LEGO1 0x10001fa0 +void Vector2::AddImpl(float p_value) +{ + m_data[0] += p_value; + m_data[1] += p_value; +} + +// FUNCTION: LEGO1 0x10001fc0 +void Vector2::SubImpl(const float* p_value) +{ + m_data[0] -= p_value[0]; + m_data[1] -= p_value[1]; +} + +// FUNCTION: LEGO1 0x10001fe0 +void Vector2::MulImpl(const float* p_value) +{ + m_data[0] *= p_value[0]; + m_data[1] *= p_value[1]; +} + +// FUNCTION: LEGO1 0x10002000 +void Vector2::MulImpl(const float& p_value) +{ + m_data[0] *= p_value; + m_data[1] *= p_value; +} + +// FUNCTION: LEGO1 0x10002020 +void Vector2::DivImpl(const float& p_value) +{ + m_data[0] /= p_value; + m_data[1] /= p_value; +} + +// FUNCTION: LEGO1 0x10002040 +float Vector2::DotImpl(const float* p_a, const float* p_b) const +{ + return p_b[0] * p_a[0] + p_b[1] * p_a[1]; +} + +// FUNCTION: LEGO1 0x10002060 +// FUNCTION: BETA10 0x10010c90 +void Vector2::SetData(float* p_data) +{ + m_data = p_data; +} + +// FUNCTION: LEGO1 0x10002070 +void Vector2::EqualsImpl(const float* p_data) +{ + memcpy(m_data, p_data, sizeof(float) * 2); +} + +// FUNCTION: LEGO1 0x10002090 +float* Vector2::GetData() +{ + return m_data; +} + +// FUNCTION: LEGO1 0x100020a0 +const float* Vector2::GetData() const +{ + return m_data; +} + +// FUNCTION: LEGO1 0x100020b0 +void Vector2::Clear() +{ + memset(m_data, 0, sizeof(float) * 2); +} + +// FUNCTION: LEGO1 0x100020d0 +float Vector2::Dot(const float* p_a, const float* p_b) const +{ + return DotImpl(p_a, p_b); +} + +// FUNCTION: LEGO1 0x100020f0 +// FUNCTION: BETA10 0x100108c0 +float Vector2::Dot(const Vector2& p_a, const Vector2& p_b) const +{ + return DotImpl(p_a.m_data, p_b.m_data); +} + +// FUNCTION: LEGO1 0x10002110 +float Vector2::Dot(const float* p_a, const Vector2& p_b) const +{ + return DotImpl(p_a, p_b.m_data); +} + +// FUNCTION: LEGO1 0x10002130 +float Vector2::Dot(const Vector2& p_a, const float* p_b) const +{ + return DotImpl(p_a.m_data, p_b); +} + +// FUNCTION: LEGO1 0x10002150 +float Vector2::LenSquared() const +{ + return m_data[0] * m_data[0] + m_data[1] * m_data[1]; +} + +// FUNCTION: LEGO1 0x10002160 +// FUNCTION: BETA10 0x10010900 +int Vector2::Unitize() +{ + float sq = LenSquared(); + + if (sq > 0.0f) { + float root = sqrt(sq); + if (root > 0.0f) { + DivImpl(root); + return 0; + } + } + + return -1; +} + +// FUNCTION: LEGO1 0x100021c0 +void Vector2::operator+=(float p_value) +{ + AddImpl(p_value); +} + +// FUNCTION: LEGO1 0x100021d0 +void Vector2::operator+=(const float* p_other) +{ + AddImpl(p_other); +} + +// FUNCTION: LEGO1 0x100021e0 +void Vector2::operator+=(const Vector2& p_other) +{ + AddImpl(p_other.m_data); +} + +// FUNCTION: LEGO1 0x100021f0 +void Vector2::operator-=(const float* p_other) +{ + SubImpl(p_other); +} + +// FUNCTION: LEGO1 0x10002200 +void Vector2::operator-=(const Vector2& p_other) +{ + SubImpl(p_other.m_data); +} + +// FUNCTION: LEGO1 0x10002210 +void Vector2::operator*=(const float* p_other) +{ + MulImpl(p_other); +} + +// FUNCTION: LEGO1 0x10002220 +void Vector2::operator*=(const Vector2& p_other) +{ + MulImpl(p_other.m_data); +} + +// FUNCTION: LEGO1 0x10002230 +void Vector2::operator*=(const float& p_value) +{ + MulImpl(p_value); +} + +// FUNCTION: LEGO1 0x10002240 +void Vector2::operator/=(const float& p_value) +{ + DivImpl(p_value); +} + +// FUNCTION: LEGO1 0x10002250 +void Vector2::operator=(const float* p_other) +{ + EqualsImpl(p_other); +} + +// FUNCTION: LEGO1 0x10002260 +// FUNCTION: BETA10 0x100110c0 +void Vector2::operator=(const Vector2& p_other) +{ + EqualsImpl(p_other.m_data); +} + +#endif // VECTOR2D_H diff --git a/LEGO1/realtime/vector3d.inl.h b/LEGO1/realtime/vector3d.inl.h new file mode 100644 index 00000000..517b777f --- /dev/null +++ b/LEGO1/realtime/vector3d.inl.h @@ -0,0 +1,117 @@ +#ifndef VECTOR3D_H +#define VECTOR3D_H + +#include "vector2d.inl.h" + +// FUNCTION: LEGO1 0x10002270 +// FUNCTION: BETA10 0x10011350 +void Vector3::EqualsCrossImpl(const float* p_a, const float* p_b) +{ + m_data[0] = p_a[1] * p_b[2] - p_a[2] * p_b[1]; + m_data[1] = p_a[2] * p_b[0] - p_a[0] * p_b[2]; + m_data[2] = p_a[0] * p_b[1] - p_a[1] * p_b[0]; +} + +// FUNCTION: LEGO1 0x100022c0 +// FUNCTION: BETA10 0x10011430 +void Vector3::EqualsCross(const Vector3& p_a, const Vector3& p_b) +{ + EqualsCrossImpl(p_a.m_data, p_b.m_data); +} + +// FUNCTION: LEGO1 0x100022e0 +void Vector3::EqualsCross(const Vector3& p_a, const float* p_b) +{ + EqualsCrossImpl(p_a.m_data, p_b); +} + +// FUNCTION: LEGO1 0x10002300 +void Vector3::EqualsCross(const float* p_a, const Vector3& p_b) +{ + EqualsCrossImpl(p_a, p_b.m_data); +} + +// FUNCTION: LEGO1 0x10003a60 +void Vector3::AddImpl(const float* p_value) +{ + m_data[0] += p_value[0]; + m_data[1] += p_value[1]; + m_data[2] += p_value[2]; +} + +// FUNCTION: LEGO1 0x10003a90 +void Vector3::AddImpl(float p_value) +{ + m_data[0] += p_value; + m_data[1] += p_value; + m_data[2] += p_value; +} + +// FUNCTION: LEGO1 0x10003ac0 +void Vector3::SubImpl(const float* p_value) +{ + m_data[0] -= p_value[0]; + m_data[1] -= p_value[1]; + m_data[2] -= p_value[2]; +} + +// FUNCTION: LEGO1 0x10003af0 +void Vector3::MulImpl(const float* p_value) +{ + m_data[0] *= p_value[0]; + m_data[1] *= p_value[1]; + m_data[2] *= p_value[2]; +} + +// FUNCTION: LEGO1 0x10003b20 +void Vector3::MulImpl(const float& p_value) +{ + m_data[0] *= p_value; + m_data[1] *= p_value; + m_data[2] *= p_value; +} + +// FUNCTION: LEGO1 0x10003b50 +void Vector3::DivImpl(const float& p_value) +{ + m_data[0] /= p_value; + m_data[1] /= p_value; + m_data[2] /= p_value; +} + +// FUNCTION: LEGO1 0x10003b80 +float Vector3::DotImpl(const float* p_a, const float* p_b) const +{ + return p_a[0] * p_b[0] + p_a[2] * p_b[2] + p_a[1] * p_b[1]; +} + +// FUNCTION: LEGO1 0x10003ba0 +// FUNCTION: BETA10 0x100113f0 +void Vector3::EqualsImpl(const float* p_data) +{ + memcpy(m_data, p_data, sizeof(float) * 3); +} + +// FUNCTION: LEGO1 0x10003bc0 +// FUNCTION: BETA10 0x100114f0 +void Vector3::Clear() +{ + memset(m_data, 0, sizeof(float) * 3); +} + +// FUNCTION: LEGO1 0x10003bd0 +// FUNCTION: BETA10 0x10011530 +float Vector3::LenSquared() const +{ + return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2]; +} + +// FUNCTION: LEGO1 0x10003bf0 +void Vector3::Fill(const float& p_value) +{ + m_data[0] = p_value; + m_data[1] = p_value; + m_data[2] = p_value; +} + +#endif // VECTOR3D_H diff --git a/LEGO1/realtime/vector4d.inl.h b/LEGO1/realtime/vector4d.inl.h new file mode 100644 index 00000000..a94e8f09 --- /dev/null +++ b/LEGO1/realtime/vector4d.inl.h @@ -0,0 +1,145 @@ +#ifndef VECTOR4D_H +#define VECTOR4D_H + +#include "vector.h" + +// FUNCTION: LEGO1 0x10002870 +void Vector4::AddImpl(const float* p_value) +{ + m_data[0] += p_value[0]; + m_data[1] += p_value[1]; + m_data[2] += p_value[2]; + m_data[3] += p_value[3]; +} + +// FUNCTION: LEGO1 0x100028b0 +void Vector4::AddImpl(float p_value) +{ + m_data[0] += p_value; + m_data[1] += p_value; + m_data[2] += p_value; + m_data[3] += p_value; +} + +// FUNCTION: LEGO1 0x100028f0 +void Vector4::SubImpl(const float* p_value) +{ + m_data[0] -= p_value[0]; + m_data[1] -= p_value[1]; + m_data[2] -= p_value[2]; + m_data[3] -= p_value[3]; +} + +// FUNCTION: LEGO1 0x10002930 +void Vector4::MulImpl(const float* p_value) +{ + m_data[0] *= p_value[0]; + m_data[1] *= p_value[1]; + m_data[2] *= p_value[2]; + m_data[3] *= p_value[3]; +} + +// FUNCTION: LEGO1 0x10002970 +void Vector4::MulImpl(const float& p_value) +{ + m_data[0] *= p_value; + m_data[1] *= p_value; + m_data[2] *= p_value; + m_data[3] *= p_value; +} + +// FUNCTION: LEGO1 0x100029b0 +void Vector4::DivImpl(const float& p_value) +{ + m_data[0] /= p_value; + m_data[1] /= p_value; + m_data[2] /= p_value; + m_data[3] /= p_value; +} + +// FUNCTION: LEGO1 0x100029f0 +float Vector4::DotImpl(const float* p_a, const float* p_b) const +{ + return p_a[0] * p_b[0] + p_a[2] * p_b[2] + (p_a[1] * p_b[1] + p_a[3] * p_b[3]); +} + +// FUNCTION: LEGO1 0x10002a20 +void Vector4::EqualsImpl(const float* p_data) +{ + memcpy(m_data, p_data, sizeof(float) * 4); +} + +// FUNCTION: LEGO1 0x10002a40 +void Vector4::SetMatrixProduct(const float* p_vec, const float* p_mat) +{ + m_data[0] = p_vec[0] * p_mat[0] + p_vec[1] * p_mat[4] + p_vec[2] * p_mat[8] + p_vec[3] * p_mat[12]; + m_data[1] = p_vec[0] * p_mat[1] + p_vec[1] * p_mat[5] + p_vec[2] * p_mat[9] + p_vec[4] * p_mat[13]; + m_data[2] = p_vec[0] * p_mat[2] + p_vec[1] * p_mat[6] + p_vec[2] * p_mat[10] + p_vec[4] * p_mat[14]; + m_data[3] = p_vec[0] * p_mat[3] + p_vec[1] * p_mat[7] + p_vec[2] * p_mat[11] + p_vec[4] * p_mat[15]; +} + +// FUNCTION: LEGO1 0x10002ae0 +void Vector4::SetMatrixProduct(const Vector4& p_a, const float* p_b) +{ + SetMatrixProduct(p_a.m_data, p_b); +} + +// FUNCTION: LEGO1 0x10002b00 +void Vector4::Clear() +{ + memset(m_data, 0, sizeof(float) * 4); +} + +// FUNCTION: LEGO1 0x10002b20 +float Vector4::LenSquared() const +{ + return m_data[1] * m_data[1] + m_data[0] * m_data[0] + m_data[2] * m_data[2] + m_data[3] * m_data[3]; +} + +// FUNCTION: LEGO1 0x10002b40 +void Vector4::Fill(const float& p_value) +{ + m_data[0] = p_value; + m_data[1] = p_value; + m_data[2] = p_value; + m_data[3] = p_value; +} + +// FUNCTION: LEGO1 0x10002b70 +// FUNCTION: BETA10 0x10048ad0 +int Vector4::NormalizeQuaternion() +{ + float length = m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2]; + + if (length > 0.0f) { + float theta = m_data[3] * 0.5f; + float magnitude = sin((double) theta); + m_data[3] = cos((double) theta); + + magnitude = magnitude / (float) sqrt((double) length); + m_data[0] *= magnitude; + m_data[1] *= magnitude; + m_data[2] *= magnitude; + return 0; + } + else { + return -1; + } +} + +// FUNCTION: LEGO1 0x10002bf0 +// FUNCTION: BETA10 0x10048c20 +int Vector4::EqualsHamiltonProduct(const Vector4& p_a, const Vector4& p_b) +{ + m_data[3] = p_a.m_data[3] * p_b.m_data[3] - + (p_a.m_data[0] * p_b.m_data[0] + p_a.m_data[2] * p_b.m_data[2] + p_a.m_data[1] * p_b.m_data[1]); + + Vector3::EqualsCrossImpl(p_a.m_data, p_b.m_data); + + m_data[0] = p_b.m_data[3] * p_a.m_data[0] + p_a.m_data[3] * p_b.m_data[0] + m_data[0]; + m_data[1] = p_b.m_data[1] * p_a.m_data[3] + p_a.m_data[1] * p_b.m_data[3] + m_data[1]; + m_data[2] = p_b.m_data[2] * p_a.m_data[3] + p_a.m_data[2] * p_b.m_data[3] + m_data[2]; + return 0; +} + +#endif // VECTOR4D_H