diff --git a/LEGO1/lego/legoomni/include/doors.h b/LEGO1/lego/legoomni/include/doors.h index 527d1de1..83c551b0 100644 --- a/LEGO1/lego/legoomni/include/doors.h +++ b/LEGO1/lego/legoomni/include/doors.h @@ -7,7 +7,7 @@ // SIZE 0x1f8 class Doors : public LegoPathActor { public: - Doors() : m_unk0x154(0), m_unk0x15c(0), m_unk0x160(0), m_unk0x1f4(0) {} + Doors() : m_unk0x154(0), m_unk0x15c(NULL), m_unk0x160(NULL), m_unk0x1f4(0) {} // FUNCTION: LEGO1 0x1000e430 const char* ClassName() const override // vtable+0x0c @@ -31,12 +31,12 @@ class Doors : public LegoPathActor { private: undefined4 m_unk0x154; // 0x154 - undefined4 m_unk0x158; // 0x158 - undefined4 m_unk0x15c; // 0x15c - undefined4 m_unk0x160; // 0x160 + MxFloat m_unk0x158; // 0x158 + Matrix4* m_unk0x15c; // 0x15c + Matrix4* m_unk0x160; // 0x160 MxMatrix m_unk0x164; // 0x164 MxMatrix m_unk0x1ac; // 0x1ac - undefined4 m_unk0x1f4; // 0x1f4 + MxFloat m_unk0x1f4; // 0x1f4 }; #endif // DOORS_H diff --git a/LEGO1/lego/legoomni/include/gasstation.h b/LEGO1/lego/legoomni/include/gasstation.h index 92f4593e..b53fc0f7 100644 --- a/LEGO1/lego/legoomni/include/gasstation.h +++ b/LEGO1/lego/legoomni/include/gasstation.h @@ -38,19 +38,19 @@ class GasStationState : public LegoState { // SYNTHETIC: LEGO1 0x10006290 // GasStationState::`scalar deleting destructor' - void FUN_10006430(GarageScript::Script); - void FUN_10006460(GarageScript::Script); - void FUN_10006490(); + void PlayAction(GarageScript::Script p_objectId); + void StopAction(GarageScript::Script p_objectId); + void StopActions(); // TODO: Most likely getters/setters are not used according to BETA. - undefined4 m_unk0x08[3]; // 0x08 - Unknown0x14 m_unk0x14; // 0x14 - MxS16 m_unk0x18; // 0x18 - MxS16 m_unk0x1a; // 0x1a - MxS16 m_unk0x1c; // 0x1c - MxS16 m_unk0x1e; // 0x1e - MxS16 m_unk0x20; // 0x20 + GarageScript::Script m_actions[3]; // 0x08 + Unknown0x14 m_unk0x14; // 0x14 + MxS16 m_pepperAction; // 0x18 + MxS16 m_mamaAction; // 0x1a + MxS16 m_papaAction; // 0x1c + MxS16 m_nickAction; // 0x1e + MxS16 m_lauraAction; // 0x20 }; // VTABLE: LEGO1 0x100d4650 diff --git a/LEGO1/lego/legoomni/include/helicopter.h b/LEGO1/lego/legoomni/include/helicopter.h index bf428819..74715234 100644 --- a/LEGO1/lego/legoomni/include/helicopter.h +++ b/LEGO1/lego/legoomni/include/helicopter.h @@ -28,7 +28,7 @@ class HelicopterState : public LegoState { MxBool IsSerializable() override { return FALSE; } // vtable+0x14 // FUNCTION: LEGO1 0x1000e0c0 - MxBool SetFlag() override + MxBool Reset() override { m_unk0x08 = 0; return TRUE; diff --git a/LEGO1/lego/legoomni/include/isle.h b/LEGO1/lego/legoomni/include/isle.h index 5125cc3d..b470bae5 100644 --- a/LEGO1/lego/legoomni/include/isle.h +++ b/LEGO1/lego/legoomni/include/isle.h @@ -3,6 +3,7 @@ #include "actionsfwd.h" #include "legogamestate.h" +#include "legonamedplane.h" #include "legostate.h" #include "legoworld.h" #include "radio.h" @@ -32,47 +33,6 @@ class Act1State : public LegoState { c_floor3 }; - enum { - e_unk953 = 953, - e_unk954 = 954, - e_unk955 = 955, - }; - - // SIZE 0x4c - class NamedPlane { - public: - // FUNCTION: LEGO1 0x10033800 - NamedPlane() {} - - void SetName(const char* p_name) { m_name = p_name; } - const MxString* GetName() const { return &m_name; } - - // FUNCTION: LEGO1 0x100344d0 - MxResult Serialize(LegoFile* p_file) - { - if (p_file->IsWriteMode()) { - p_file->WriteString(m_name); - p_file->WriteVector3(m_point1); - p_file->WriteVector3(m_point2); - p_file->WriteVector3(m_point3); - } - else if (p_file->IsReadMode()) { - p_file->ReadString(m_name); - p_file->ReadVector3(m_point1); - p_file->ReadVector3(m_point2); - p_file->ReadVector3(m_point3); - } - - return SUCCESS; - } - - private: - MxString m_name; // 0x00 - Mx3DPointFloat m_point1; // 0x10 - Mx3DPointFloat m_point2; // 0x24 - Mx3DPointFloat m_point3; // 0x38 - }; - Act1State(); // FUNCTION: LEGO1 0x100338a0 @@ -88,12 +48,12 @@ class Act1State : public LegoState { return !strcmp(p_name, Act1State::ClassName()) || LegoState::IsA(p_name); } - MxBool SetFlag() override; // vtable+0x18 + MxBool Reset() override; // vtable+0x18 MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c - void FUN_10034660(); - void FUN_100346a0(); - void FUN_10034b60(); + void PlayCptClickDialogue(); + void StopCptClickDialogue(); + void RemoveActors(); void FUN_10034d00(); MxU32 GetUnknown18() { return m_unk0x018; } @@ -109,45 +69,38 @@ class Act1State : public LegoState { // TODO: Most likely getters/setters are not used according to BETA. - MxS32* m_unk0x008; // 0x008 FIXME: count for m_unk0x008 - MxS16 m_unk0x00c; // 0x00c - undefined2 m_unk0x00e; // 0x00e - undefined2 m_unk0x010; // 0x010 - undefined m_unk0x012; // 0x012 - MxS32 m_unk0x014; // 0x014 - MxU32 m_unk0x018; // 0x018 - MxS16 m_elevFloor; // 0x01c - MxBool m_unk0x01e; // 0x01e - MxBool m_unk0x01f; // 0x01f - MxBool m_planeActive; // 0x020 - undefined m_unk0x021; // 0x021 - MxBool m_unk0x022; // 0x022 - undefined m_unk0x023; // 0x023 - NamedPlane m_unk0x024; // 0x024 - NamedPlane m_unk0x070; // 0x070 - NamedPlane m_unk0x0bc; // 0x0bc - NamedPlane m_unk0x108; // 0x108 - LegoNamedTexture* m_unk0x154; // 0x154 - LegoNamedTexture* m_unk0x158; // 0x158 - LegoNamedTexture* m_unk0x15c; // 0x15c - Helicopter* m_helicopter; // 0x160 - NamedPlane m_unk0x164; // 0x164 - LegoNamedTexture* m_unk0x1b0; // 0x1b0 - LegoNamedTexture* m_unk0x1b4; // 0x1b4 - Jetski* m_jetski; // 0x1b8 - NamedPlane m_unk0x1bc; // 0x1bc - LegoNamedTexture* m_unk0x208; // 0x208 - DuneBuggy* m_dunebuggy; // 0x20c - NamedPlane m_unk0x210; // 0x210 - LegoNamedTexture* m_unk0x25c; // 0x25c - LegoNamedTexture* m_unk0x260; // 0x260 - LegoNamedTexture* m_unk0x264; // 0x264 - RaceCar* m_racecar; // 0x268 + Playlist m_cptClickDialogue; // 0x008 + IsleScript::Script m_currentCptClickDialogue; // 0x014 + MxU32 m_unk0x018; // 0x018 + MxS16 m_elevFloor; // 0x01c + MxBool m_unk0x01e; // 0x01e + MxBool m_unk0x01f; // 0x01f + MxBool m_planeActive; // 0x020 + undefined m_unk0x021; // 0x021 + MxBool m_unk0x022; // 0x022 + undefined m_unk0x023; // 0x023 + LegoNamedPlane m_motocyclePlane; // 0x024 + LegoNamedPlane m_bikePlane; // 0x070 + LegoNamedPlane m_skateboardPlane; // 0x0bc + LegoNamedPlane m_helicopterPlane; // 0x108 + LegoNamedTexture* m_unk0x154; // 0x154 + LegoNamedTexture* m_unk0x158; // 0x158 + LegoNamedTexture* m_unk0x15c; // 0x15c + Helicopter* m_helicopter; // 0x160 + LegoNamedPlane m_jetskiPlane; // 0x164 + LegoNamedTexture* m_unk0x1b0; // 0x1b0 + LegoNamedTexture* m_unk0x1b4; // 0x1b4 + Jetski* m_jetski; // 0x1b8 + LegoNamedPlane m_dunebuggyPlane; // 0x1bc + LegoNamedTexture* m_unk0x208; // 0x208 + DuneBuggy* m_dunebuggy; // 0x20c + LegoNamedPlane m_racecarPlane; // 0x210 + LegoNamedTexture* m_unk0x25c; // 0x25c + LegoNamedTexture* m_unk0x260; // 0x260 + LegoNamedTexture* m_unk0x264; // 0x264 + RaceCar* m_racecar; // 0x268 }; -// FUNCTION: LEGO1 0x10033a70 -// Act1State::NamedPlane::~NamedPlane - // VTABLE: LEGO1 0x100d6fb8 // SIZE 0x140 class Isle : public LegoWorld { @@ -190,9 +143,12 @@ class Isle : public LegoWorld { virtual void VTable0x6c(LegoPathActor* p_actor); // vtable+6c void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; } + MxBool HasHelicopter() { return m_helicopter != NULL; } void FUN_10033350(); + friend class Act1State; + // SYNTHETIC: LEGO1 0x10030a30 // Isle::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index 3d181985..64727b1e 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -1,7 +1,6 @@ #ifndef LEGOANIMATIONMANAGER_H #define LEGOANIMATIONMANAGER_H -#include "actionsfwd.h" #include "decomp.h" #include "legolocations.h" #include "legostate.h" @@ -68,7 +67,7 @@ class AnimState : public LegoState { return !strcmp(p_name, AnimState::ClassName()) || LegoState::IsA(p_name); } - MxBool SetFlag() override; // vtable+0x18 + MxBool Reset() override; // vtable+0x18 MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c void CopyToAnims(MxU32, AnimInfo* p_anims, MxU32& p_outExtraCharacterId); @@ -161,7 +160,7 @@ class LegoAnimationManager : public MxCore { void FUN_10060570(MxBool p_unk0x1a); MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity); MxResult FUN_10060dc0( - IsleScript::Script p_objectId, + MxU32 p_objectId, MxMatrix* p_matrix, MxBool p_param3, MxBool p_param4, diff --git a/LEGO1/lego/legoomni/include/legocarbuild.h b/LEGO1/lego/legoomni/include/legocarbuild.h index 0afb0824..6337aafd 100644 --- a/LEGO1/lego/legoomni/include/legocarbuild.h +++ b/LEGO1/lego/legoomni/include/legocarbuild.h @@ -6,6 +6,7 @@ #include "legoworld.h" class LegoCarBuildAnimPresenter; +class LegoControlManagerNotificationParam; class LegoEventNotificationParam; class MxControlPresenter; class MxStillPresenter; @@ -21,6 +22,7 @@ class LegoVehicleBuildState : public LegoState { e_entering = 1, e_unknown2 = 2, e_cutscene = 3, + e_unknown4 = 4, e_exiting = 6 }; @@ -71,6 +73,22 @@ typedef LegoVehicleBuildState LegoJetskiBuildState; // SIZE 0x34c class LegoCarBuild : public LegoWorld { public: + // SIZE 0x1c + struct LookupTableActions { + undefined4 m_unk0x00; // 0x00 + undefined4 m_unk0x04; // 0x04 + undefined4 m_unk0x08; // 0x08 + undefined4 m_unk0x0c; // 0x0c + undefined4 m_unk0x10; // 0x10 + undefined4 m_unk0x14; // 0x14 + undefined4 m_unk0x18; // 0x18 + }; + + enum Unknown0xf8 { + c_unknownminusone = -1, + c_unknown8 = 8 + }; + LegoCarBuild(); ~LegoCarBuild() override; @@ -117,16 +135,19 @@ class LegoCarBuild : public LegoWorld { undefined4 FUN_100244e0(MxLong p_x, MxLong p_y); undefined4 FUN_100246e0(MxLong p_x, MxLong p_y); MxS32 FUN_10024850(MxLong p_x, MxLong p_y); - undefined4 FUN_10024890(LegoEventNotificationParam* p_param); + undefined4 FUN_10024890(MxParam* p_param); undefined4 FUN_10024c20(LegoEventNotificationParam* p_param); void FUN_10024ef0(); + void FUN_10024f30(); void FUN_10024f50(); void FUN_10024f70(MxBool p_enabled); void SetPresentersEnabled(MxBool p_enabled); void TogglePresentersEnabled(); void FUN_100250e0(MxBool p_param); + void FUN_10025350(MxS32 p_objectId); void FUN_10025450(); - undefined4 FUN_10025720(undefined4 p_param1); + void FUN_10025720(undefined4 p_param1); + void FUN_10025d10(MxS32 p_param); MxS32 FUN_10025d70(); void FUN_10025db0(const char* p_param1, undefined4 p_param2); void FUN_10025e40(); @@ -139,12 +160,18 @@ class LegoCarBuild : public LegoWorld { // LegoCarBuild::`scalar deleting destructor' private: - undefined4 m_unk0xf8; // 0xf8 - MxS16 m_unk0xfc; // 0xfc - undefined m_unk0xfe[2]; // 0xfe - MxS32 m_unk0x100; // 0x100 - undefined4 m_unk0x104; // 0x104 - MxS8 m_unk0x108; // 0x108 + // inline functions + MxU32 Beta0x10070520(); + void StopActionIn0x344(); + + Unknown0xf8 m_unk0xf8; // 0xf8 + MxS16 m_unk0xfc; // 0xfc + MxS32 m_unk0x100; // 0x100 + undefined4 m_unk0x104; // 0x104 + + // name verified by BETA10 0x1006ebba + MxS8 m_numAnimsRun; // 0x108 + MxU8 m_unk0x109; // 0x109 MxU16 m_unk0x10a; // 0x10a DWORD m_unk0x10c; // 0x10c @@ -197,7 +224,8 @@ class LegoCarBuild : public LegoWorld { // variable name verified by BETA10 0x1006b219 LegoVehicleBuildState* m_buildState; // 0x32c - undefined4 m_unk0x330; // 0x330 + // variable name verified by BETA10 0x1006d742 + undefined4 m_carId; // 0x330 // variable name verified by BETA10 0x1006cba7 LegoGameState::Area m_destLocation; // 0x334 @@ -211,6 +239,7 @@ class LegoCarBuild : public LegoWorld { static MxS16 g_unk0x100f11cc; static MxFloat g_unk0x100d65a4; static MxFloat g_rotationAngleStepYAxis; + static LookupTableActions g_unk0x100d65b0[]; }; #endif // LEGOCARBUILD_H diff --git a/LEGO1/lego/legoomni/include/legocarbuildpresenter.h b/LEGO1/lego/legoomni/include/legocarbuildpresenter.h index b1233ada..2e61b1e5 100644 --- a/LEGO1/lego/legoomni/include/legocarbuildpresenter.h +++ b/LEGO1/lego/legoomni/include/legocarbuildpresenter.h @@ -21,7 +21,7 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { { m_name = NULL; m_wiredName = NULL; - m_unk0x08 = 0; + m_objectId = 0; } // variable name verified by BETA10 0x10071b56 @@ -30,7 +30,8 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { // variable name verified by BETA10 0x100719f0 LegoChar* m_wiredName; // 0x04 - undefined2 m_unk0x08; // 0x08 + // variable name guessed based on the setter at LEGO1 0x0x10079dc0 and its use in LEGO1 0x10024890 + MxS16 m_objectId; // 0x08 }; LegoCarBuildAnimPresenter(); @@ -77,15 +78,33 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { MxBool StringEqualsShelf(const LegoChar* p_string); MxBool StringEndsOnY(const LegoChar* p_string); MxBool StringEndsOnZero(const LegoChar* p_string); + const LegoChar* GetWiredNameByPartName(const LegoChar* p_name); + void SetPartObjectIdByName(const LegoChar* p_name, MxS16 p_objectId); // FUNCTION: BETA10 0x10070180 void SetUnknown0xbc(undefined2 p_unk0xbc) { m_unk0xbc = p_unk0xbc; } + // FUNCTION: BETA10 0x100703b0 + MxMatrix& GetUnknown0xe0() { return m_unk0xe0; } + MxBool StringEndsOnW(LegoChar* p_param); MxBool StringEndsOnYOrN(const LegoChar* p_string); const BoundingSphere& FUN_10079e20(); + // FUNCTION: BETA10 0x100703e0 + const LegoChar* GetWiredNameOfLastPlacedPart() { return m_parts[m_placedPartCount].m_wiredName; } + + MxS16 GetNumberOfParts() { return m_numberOfParts; } + MxS16 GetPlacedPartCount() { return m_placedPartCount; } + + // FUNCTION: BETA10 0x10070270 + MxBool AllPartsPlaced() + { + // this function differs in BETA10 + return m_placedPartCount == m_numberOfParts; + } + // SYNTHETIC: LEGO1 0x10078660 // LegoCarBuildAnimPresenter::`scalar deleting destructor' @@ -118,8 +137,6 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { // name verified by BETA10 0x10070d63 LegoChar* m_mainSourceId; // 0x14c - - friend class LegoCarBuild; }; #endif // LEGOCARBUILDPRESENTER_H diff --git a/LEGO1/lego/legoomni/include/legogamestate.h b/LEGO1/lego/legoomni/include/legogamestate.h index 5e818cc7..dc26f8c3 100644 --- a/LEGO1/lego/legoomni/include/legogamestate.h +++ b/LEGO1/lego/legoomni/include/legogamestate.h @@ -172,13 +172,11 @@ class LegoGameState { Act GetCurrentAct() { return m_currentAct; } Act GetLoadedAct() { return m_loadedAct; } - Area GetCurrentArea() { return m_currentArea; } Area GetPreviousArea() { return m_previousArea; } Area GetUnknown0x42c() { return m_unk0x42c; } History* GetHistory() { return &m_history; } void SetDirty(MxBool p_isDirty) { m_isDirty = p_isDirty; } - void SetCurrentArea(Area p_currentArea) { m_currentArea = p_currentArea; } void SetPreviousArea(Area p_previousArea) { m_previousArea = p_previousArea; } void SetActorId(MxU8 p_actorId) { m_actorId = p_actorId; } void SetUnknown0x42c(Area p_unk0x42c) { m_unk0x42c = p_unk0x42c; } diff --git a/LEGO1/lego/legoomni/include/legoinputmanager.h b/LEGO1/lego/legoomni/include/legoinputmanager.h index d8c7f1cf..160c4d28 100644 --- a/LEGO1/lego/legoomni/include/legoinputmanager.h +++ b/LEGO1/lego/legoomni/include/legoinputmanager.h @@ -120,7 +120,9 @@ class LegoInputManager : public MxPresenter { // FUNCTION: BETA10 0x10031ba0 LegoControlManager* GetControlManager() { return m_controlManager; } + // FUNCTION: BETA10 0x10017870 LegoWorld* GetWorld() { return m_world; } + LegoCameraController* GetCamera() { return m_camera; } void ProcessEvents(); diff --git a/LEGO1/lego/legoomni/include/legomain.h b/LEGO1/lego/legoomni/include/legomain.h index 182500c1..4ac4f309 100644 --- a/LEGO1/lego/legoomni/include/legomain.h +++ b/LEGO1/lego/legoomni/include/legomain.h @@ -147,7 +147,10 @@ class LegoOmni : public MxOmni { void SetNavController(LegoNavController* p_navController) { m_navController = p_navController; } void SetUserActor(LegoPathActor* p_userActor) { m_userActor = p_userActor; } void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; } + + // FUNCTION: BETA10 0x100d55c0 void SetExit(MxBool p_exit) { m_exit = p_exit; } + MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) { return m_unk0x13c ? Start(&p_dsAction) : SUCCESS; } void SetUnknown13c(MxBool p_unk0x13c) { m_unk0x13c = p_unk0x13c; } diff --git a/LEGO1/lego/legoomni/include/legonamedplane.h b/LEGO1/lego/legoomni/include/legonamedplane.h new file mode 100644 index 00000000..a97cd8fb --- /dev/null +++ b/LEGO1/lego/legoomni/include/legonamedplane.h @@ -0,0 +1,50 @@ +#ifndef LEGONAMEDPLANE_H +#define LEGONAMEDPLANE_H + +#include "misc/legostorage.h" +#include "mxgeometry/mxgeometry3d.h" +#include "mxstring.h" + +// SIZE 0x4c +class LegoNamedPlane { +public: + // FUNCTION: LEGO1 0x10033800 + LegoNamedPlane() {} + + // FUNCTION: LEGO1 0x10033a70 + // LegoNamedPlane::~LegoNamedPlane + + void SetName(const char* p_name) { m_name = p_name; } + const MxString* GetName() const { return &m_name; } + + void SetPosition(const Mx3DPointFloat& p_position) { m_position = p_position; } + void SetDirection(const Mx3DPointFloat& p_direction) { m_direction = p_direction; } + void SetUp(const Mx3DPointFloat& p_up) { m_up = p_up; } + + // FUNCTION: LEGO1 0x100344d0 + MxResult Serialize(LegoFile* p_file) + { + if (p_file->IsWriteMode()) { + p_file->WriteString(m_name); + p_file->WriteVector3(m_position); + p_file->WriteVector3(m_direction); + p_file->WriteVector3(m_up); + } + else if (p_file->IsReadMode()) { + p_file->ReadString(m_name); + p_file->ReadVector3(m_position); + p_file->ReadVector3(m_direction); + p_file->ReadVector3(m_up); + } + + return SUCCESS; + } + +private: + MxString m_name; // 0x00 + Mx3DPointFloat m_position; // 0x10 + Mx3DPointFloat m_direction; // 0x24 + Mx3DPointFloat m_up; // 0x38 +}; + +#endif // LEGONAMEDPLANE_H diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 242d46b6..c845c897 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -7,6 +7,7 @@ #include "mxtypes.h" struct LegoEdge; +class LegoNamedPlane; class LegoPathBoundary; class LegoPathController; struct LegoPathEdgeContainer; @@ -140,6 +141,8 @@ class LegoPathActor : public LegoActor { void SetController(LegoPathController* p_controller) { m_controller = p_controller; } + void UpdatePlane(LegoNamedPlane& p_namedPlane); + // SYNTHETIC: LEGO1 0x1002d800 // LegoPathActor::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legostate.h b/LEGO1/lego/legoomni/include/legostate.h index 9aabc4da..68cf0a5b 100644 --- a/LEGO1/lego/legoomni/include/legostate.h +++ b/LEGO1/lego/legoomni/include/legostate.h @@ -27,6 +27,7 @@ class LegoState : public MxCore { }; // FUNCTION: LEGO1 0x10017c00 + // FUNCTION: BETA10 0x10031dc0 Playlist() { m_objectIds = NULL; @@ -35,28 +36,30 @@ class LegoState : public MxCore { m_nextIndex = 0; } - Playlist(MxU32* p_objectIds, MxS16 p_length) + // FUNCTION: BETA10 0x10031e10 + Playlist(MxU32* p_objectIds, MxS16 p_length, MxS16 p_mode) { m_objectIds = p_objectIds; m_length = p_length; - m_mode = e_loop; + m_mode = p_mode; m_nextIndex = 0; } // FUNCTION: LEGO1 0x10071800 - Playlist& operator=(const Playlist& p_shuffle) + // FUNCTION: BETA10 0x10031e70 + Playlist& operator=(const Playlist& p_playlist) { - m_objectIds = p_shuffle.m_objectIds; - m_length = p_shuffle.m_length; - m_nextIndex = p_shuffle.m_nextIndex; - m_mode = p_shuffle.m_mode; + m_objectIds = p_playlist.m_objectIds; + m_length = p_playlist.m_length; + m_nextIndex = p_playlist.m_nextIndex; + m_mode = p_playlist.m_mode; return *this; } MxU32 Next(); MxBool Contains(MxU32 p_objectId); - void SetUnknown0x08(MxS16 p_unk0x08) { m_nextIndex = p_unk0x08; } + void SetNextIndex(MxS16 p_nextIndex) { m_nextIndex = p_nextIndex; } MxResult ReadFromFile(LegoFile* p_file) { @@ -70,7 +73,6 @@ class LegoState : public MxCore { return SUCCESS; } - private: MxU32* m_objectIds; // 0x00 MxS16 m_length; // 0x04 MxS16 m_mode; // 0x06 @@ -97,7 +99,7 @@ class LegoState : public MxCore { virtual MxBool IsSerializable() { return TRUE; } // vtable+0x14 // FUNCTION: LEGO1 0x10005fa0 - virtual MxBool SetFlag() { return FALSE; } // vtable+0x18 + virtual MxBool Reset() { return FALSE; } // vtable+0x18 // FUNCTION: LEGO1 0x10005fb0 virtual MxResult Serialize(LegoFile* p_file) diff --git a/LEGO1/lego/legoomni/include/legoutils.h b/LEGO1/lego/legoomni/include/legoutils.h index b6143c36..8c4b44fe 100644 --- a/LEGO1/lego/legoomni/include/legoutils.h +++ b/LEGO1/lego/legoomni/include/legoutils.h @@ -10,6 +10,9 @@ #define WM_ISLE_SETCURSOR 0x5400 +// name verified by BETA10 0x100d4054 +#define DS_NOT_A_STREAM -1 + enum Cursor { e_cursorArrow = 0, e_cursorBusy, @@ -46,7 +49,7 @@ MxS16 CountTotalTreeNodes(LegoTreeNode* p_node); LegoTreeNode* GetTreeNode(LegoTreeNode* p_node, MxU32 p_index); void FUN_1003e050(LegoAnimPresenter* p_presenter); Extra::ActionType MatchActionString(const char*); -void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_targetEntityId, LegoEntity* p_sender); +void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_streamId, LegoEntity* p_sender); void SetCameraControllerFromIsle(); void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_bOut, float* p_gOut); void PlayCamAnim(LegoPathActor* p_actor, MxBool p_unused, MxU32 p_location, MxBool p_bool); diff --git a/LEGO1/lego/legoomni/include/mxtransitionmanager.h b/LEGO1/lego/legoomni/include/mxtransitionmanager.h index 0af65db5..178b114a 100644 --- a/LEGO1/lego/legoomni/include/mxtransitionmanager.h +++ b/LEGO1/lego/legoomni/include/mxtransitionmanager.h @@ -34,7 +34,7 @@ class MxTransitionManager : public MxCore { virtual MxResult GetDDrawSurfaceFromVideoManager(); // vtable+0x14 enum TransitionType { - e_notTransitioning = 0, + e_idle = 0, // name verified by BETA10 0x100ec4e6 e_noAnimation, e_dissolve, e_mosaic, @@ -45,7 +45,7 @@ class MxTransitionManager : public MxCore { MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim); - TransitionType GetTransitionType() { return m_transitionType; } + TransitionType GetTransitionType() { return m_mode; } // SYNTHETIC: LEGO1 0x1004b9e0 // MxTransitionManager::`scalar deleting destructor' @@ -68,13 +68,16 @@ class MxTransitionManager : public MxCore { FlagBitfield m_copyFlags; // 0x20 undefined4 m_unk0x24; // 0x24 FlagBitfield m_unk0x28; // 0x28 - TransitionType m_transitionType; // 0x2c - LPDIRECTDRAWSURFACE m_ddSurface; // 0x30 - MxU16 m_animationTimer; // 0x34 - MxU16 m_columnOrder[640]; // 0x36 - MxU16 m_randomShift[480]; // 0x536 - MxULong m_systemTime; // 0x8f8 - MxS32 m_animationSpeed; // 0x8fc + + // name verified by BETA10 0x100ec4e6 + TransitionType m_mode; // 0x2c + + LPDIRECTDRAWSURFACE m_ddSurface; // 0x30 + MxU16 m_animationTimer; // 0x34 + MxU16 m_columnOrder[640]; // 0x36 + MxU16 m_randomShift[480]; // 0x536 + MxULong m_systemTime; // 0x8f8 + MxS32 m_animationSpeed; // 0x8fc }; #endif // MXTRANSITIONMANAGER_H diff --git a/LEGO1/lego/legoomni/include/pizza.h b/LEGO1/lego/legoomni/include/pizza.h index e8bd71c9..a9457c24 100644 --- a/LEGO1/lego/legoomni/include/pizza.h +++ b/LEGO1/lego/legoomni/include/pizza.h @@ -1,11 +1,13 @@ #ifndef PIZZA_H #define PIZZA_H +#include "actionsfwd.h" #include "decomp.h" #include "isleactor.h" #include "legostate.h" class Act1State; +class PizzeriaState; class SkateBoard; // VTABLE: LEGO1 0x100d7408 @@ -13,14 +15,89 @@ class SkateBoard; class PizzaMissionState : public LegoState { public: // SIZE 0x20 - struct Entry { - public: + struct Mission { + // FUNCTION: LEGO1 0x10039220 + // FUNCTION: BETA10 0x100ef880 + Mission() {} + + // FUNCTION: BETA10 0x100ef8a0 + Mission( + MxU8 p_actorId, + undefined2 p_unk0x04, + MxLong* p_finishTimes, + IsleScript::Script* p_actions, + MxS16 p_numActions + ) + { + m_numActions = p_numActions; + m_actorId = p_actorId; + m_unk0x04 = p_unk0x04; + m_unk0x06 = 1; + m_unk0x08 = 1; + m_finishTimes = p_finishTimes; + m_startTime = INT_MIN; + m_unk0x14 = 1; + m_score = LegoState::e_grey; + m_hiScore = LegoState::e_grey; + m_actions = p_actions; + } + + // FUNCTION: LEGO1 0x10039230 + Mission& operator=(const Mission& p_mission) + { + m_actorId = p_mission.m_actorId; + m_unk0x04 = p_mission.m_unk0x04; + m_unk0x06 = p_mission.m_unk0x06; + m_unk0x08 = p_mission.m_unk0x08; + m_finishTimes = p_mission.m_finishTimes; + m_startTime = p_mission.m_startTime; + m_unk0x14 = p_mission.m_unk0x14; + m_score = p_mission.m_score; + m_hiScore = p_mission.m_hiScore; + m_actions = p_mission.m_actions; + m_numActions = p_mission.m_numActions; + return *this; + } + + // FUNCTION: BETA10 0x100ef610 + IsleScript::Script GetRedFinishAction() { return m_actions[m_numActions + 6]; } + + // FUNCTION: BETA10 0x100ef640 + IsleScript::Script GetBlueFinishAction() { return m_actions[m_numActions + 7]; } + + // FUNCTION: BETA10 0x100ef670 + IsleScript::Script GetYellowFinishAction() { return m_actions[m_numActions + 8]; } + + // FUNCTION: BETA10 0x100ef6a0 + MxLong GetRedFinishTime() { return m_finishTimes[0]; } + + // FUNCTION: BETA10 0x100ef6d0 + MxLong GetBlueFinishTime() { return m_finishTimes[1]; } + + // FUNCTION: BETA10 0x100ef700 + void UpdateScore(ScoreColor p_score) + { + m_score = p_score; + if (m_hiScore < p_score) { + m_hiScore = p_score; + } + } + + // FUNCTION: BETA10 0x100ef780 + IsleScript::Script* GetActions() { return m_actions; } + + // FUNCTION: BETA10 0x100ef7b0 + IsleScript::Script GetUnknownFinishAction() { return m_actions[m_numActions + 2]; } + + // FUNCTION: BETA10 0x100ef7e0 + MxLong GetTimeoutTime() { return m_finishTimes[3]; } + MxResult WriteToFile(LegoFile* p_file) { Write(p_file, m_unk0x06); Write(p_file, m_unk0x14); - Write(p_file, m_unk0x16); Write(p_file, m_score); + Write(p_file, m_hiScore); return SUCCESS; } @@ -28,21 +105,22 @@ class PizzaMissionState : public LegoState { { Read(p_file, &m_unk0x06); Read(p_file, &m_unk0x14); - Read(p_file, &m_unk0x16); Read(p_file, &m_score); + Read(p_file, &m_hiScore); return SUCCESS; } - undefined2 m_unk0x00; // 0x00 - MxU8 m_id; // 0x02 - undefined m_unk0x03[3]; // 0x03 - MxS16 m_unk0x06; // 0x06 - undefined m_unk0x08[8]; // 0x08 - undefined4 m_unk0x10; // 0x10 - MxS16 m_unk0x14; // 0x14 - MxS16 m_unk0x16; // 0x16 - MxS16 m_score; // 0x18 - undefined m_unk0x1a[6]; // 0x1a + MxS16 m_numActions; // 0x00 + MxU8 m_actorId; // 0x02 + undefined2 m_unk0x04; // 0x04 + MxS16 m_unk0x06; // 0x06 + undefined m_unk0x08; // 0x08 + MxLong* m_finishTimes; // 0x0c + MxLong m_startTime; // 0x10 + MxS16 m_unk0x14; // 0x14 + MxS16 m_score; // 0x16 + MxS16 m_hiScore; // 0x18 + IsleScript::Script* m_actions; // 0x1c }; PizzaMissionState(); @@ -62,17 +140,36 @@ class PizzaMissionState : public LegoState { MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c - MxS16 GetHighScore(MxU8 p_id) { return GetState(p_id)->m_score; } + // FUNCTION: BETA10 0x100ef470 + void SetUnknown0xb0(MxU32 p_unk0xb0) { m_unk0xb0 = p_unk0xb0; } + + // FUNCTION: BETA10 0x100ef850 + MxU32 GetUnknown0xb0() { return m_unk0xb0; } + + MxS16 GetHighScore(MxU8 p_actorId) { return GetMission(p_actorId)->m_hiScore; } // SYNTHETIC: LEGO1 0x10039350 // PizzaMissionState::`scalar deleting destructor' - Entry* GetState(MxU8 p_id); + Mission* GetMission(MxU8 p_actorId); + MxS16 FUN_10039540(); - undefined4 m_unk0x08; // 0x08 - undefined4 m_unk0x0c; // 0x0c - Entry m_state[5]; // 0x10 - undefined4 m_unk0xb0; // 0xb0 + PizzeriaState* m_pizzeriaState; // 0x08 + undefined4 m_unk0x0c; // 0x0c + Mission m_missions[5]; // 0x10 + MxU32 m_unk0xb0; // 0xb0 + + static IsleScript::Script g_pepperActions[]; + static IsleScript::Script g_mamaActions[]; + static IsleScript::Script g_papaActions[]; + static IsleScript::Script g_nickActions[]; + static IsleScript::Script g_lauraActions[]; + + static MxLong g_pepperFinishTimes[]; + static MxLong g_mamaFinishTimes[]; + static MxLong g_papaFinishTimes[]; + static MxLong g_nickFinishTimes[]; + static MxLong g_lauraFinishTimes[]; }; // VTABLE: LEGO1 0x100d7380 @@ -97,31 +194,31 @@ class Pizza : public IsleActor { return !strcmp(p_name, Pizza::ClassName()) || IsleActor::IsA(p_name); } - MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - MxLong HandleClick() override; // vtable+0x68 - MxLong HandleEndAction(MxEndActionNotificationParam&) override; // vtable+0x74 - MxLong HandlePathStruct(LegoPathStructNotificationParam&) override; // vtable+0x80 + MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 + MxLong HandleClick() override; // vtable+0x68 + MxLong HandleEndAction(MxEndActionNotificationParam& p_param) override; // vtable+0x74 + MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param) override; // vtable+0x80 void CreateState(); - void FUN_10038220(MxU32 p_objectId); + void FUN_10038220(IsleScript::Script p_objectId); void FUN_100382b0(); - void FUN_10038380(); - void FUN_10038fe0(MxU32 p_objectId, MxBool); + void StopActions(); + void PlayAction(MxU32 p_objectId, MxBool p_param7); - void SetSkateboard(SkateBoard* p_skateboard) { m_skateboard = p_skateboard; } + void SetSkateboard(SkateBoard* p_skateBoard) { m_skateBoard = p_skateBoard; } // SYNTHETIC: LEGO1 0x100380e0 // Pizza::`scalar deleting destructor' private: - PizzaMissionState* m_state; // 0x7c - PizzaMissionState::Entry* m_entry; // 0x80 - SkateBoard* m_skateboard; // 0x84 - Act1State* m_act1state; // 0x88 - undefined4 m_unk0x8c; // 0x8c - undefined4 m_unk0x90; // 0x90 - undefined4 m_unk0x94; // 0x94 - undefined m_unk0x98; // 0x98 + PizzaMissionState* m_state; // 0x7c + PizzaMissionState::Mission* m_mission; // 0x80 + SkateBoard* m_skateBoard; // 0x84 + Act1State* m_act1state; // 0x88 + IsleScript::Script m_unk0x8c; // 0x8c + MxLong m_unk0x90; // 0x90 + MxLong m_unk0x94; // 0x94 + MxBool m_unk0x98; // 0x98 }; #endif // PIZZA_H diff --git a/LEGO1/lego/legoomni/include/pizzeria.h b/LEGO1/lego/legoomni/include/pizzeria.h index 028b2993..52bb9827 100644 --- a/LEGO1/lego/legoomni/include/pizzeria.h +++ b/LEGO1/lego/legoomni/include/pizzeria.h @@ -1,6 +1,7 @@ #ifndef PIZZERIA_H #define PIZZERIA_H +#include "actionsfwd.h" #include "decomp.h" #include "isleactor.h" #include "legostate.h" @@ -11,15 +12,6 @@ class PizzaMissionState; // SIZE 0x58 class PizzeriaState : public LegoState { public: - // SIZE 0x14 - struct StateStruct { - undefined4 m_unk0x00; // 0x00 - undefined4 m_unk0x04; // 0x04 - undefined4 m_unk0x08; // 0x08 - undefined4 m_unk0x0c; // 0x0c - undefined4 m_unk0x10; // 0x10 - }; - PizzeriaState(); // FUNCTION: LEGO1 0x10017c20 @@ -40,12 +32,17 @@ class PizzeriaState : public LegoState { // SYNTHETIC: LEGO1 0x10017ce0 // PizzeriaState::`scalar deleting destructor' - MxU32 FUN_10017d70(); - - // TODO: Most likely getters/setters are not used according to BETA. + MxS16 FUN_10017d50(); + MxU32 NextAction(); Playlist m_unk0x08[5]; // 0x08 - StateStruct m_unk0x44; // 0x44 + MxS32 m_unk0x44[5]; // 0x44 + + static IsleScript::Script g_pepperActions[]; + static IsleScript::Script g_mamaActions[]; + static IsleScript::Script g_papaActions[]; + static IsleScript::Script g_nickActions[]; + static IsleScript::Script g_lauraActions[]; }; // VTABLE: LEGO1 0x100d5520 diff --git a/LEGO1/lego/legoomni/include/score.h b/LEGO1/lego/legoomni/include/score.h index af072e63..7ad505aa 100644 --- a/LEGO1/lego/legoomni/include/score.h +++ b/LEGO1/lego/legoomni/include/score.h @@ -31,7 +31,7 @@ class ScoreState : public LegoState { MxBool IsSerializable() override { return FALSE; } // vtable+0x14 // FUNCTION: LEGO1 0x1000de30 - MxBool SetFlag() override + MxBool Reset() override { m_playCubeTutorial = TRUE; return TRUE; diff --git a/LEGO1/lego/legoomni/include/skateboard.h b/LEGO1/lego/legoomni/include/skateboard.h index a85ed26e..0bf691c1 100644 --- a/LEGO1/lego/legoomni/include/skateboard.h +++ b/LEGO1/lego/legoomni/include/skateboard.h @@ -35,13 +35,12 @@ class SkateBoard : public IslePathActor { void SetUnknown0x160(MxBool p_unk0x160) { m_unk0x160 = p_unk0x160; } void ActivateSceneActions(); + void EnableScenePresentation(MxBool p_enable); // SYNTHETIC: LEGO1 0x1000ff60 // SkateBoard::`scalar deleting destructor' private: - void EnableScenePresentation(MxBool p_enable); - MxBool m_unk0x160; // 0x160 Act1State* m_act1state; // 0x164 }; diff --git a/LEGO1/lego/legoomni/src/actors/bike.cpp b/LEGO1/lego/legoomni/src/actors/bike.cpp index 0c5420be..4793a2a2 100644 --- a/LEGO1/lego/legoomni/src/actors/bike.cpp +++ b/LEGO1/lego/legoomni/src/actors/bike.cpp @@ -40,7 +40,7 @@ MxResult Bike::Create(MxDSAction& p_dsAction) void Bike::Exit() { IslePathActor::Exit(); - GameState()->SetCurrentArea(LegoGameState::Area::e_bike); + GameState()->m_currentArea = LegoGameState::Area::e_bike; RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_BikeDashboard_Bitmap); RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_BikeArms_Ctl); RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_BikeHorn_Ctl); diff --git a/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp b/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp index 52938ab3..24e6d5c7 100644 --- a/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp +++ b/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp @@ -1,6 +1,7 @@ #include "bumpbouy.h" #include "isle.h" +#include "isle_actions.h" #include "islepathactor.h" #include "legogamestate.h" #include "legovideomanager.h" @@ -44,7 +45,7 @@ MxLong BumpBouy::Notify(MxParam& p_param) assert(isleState); isleState->m_unk0x018 = 5; - Isle* isle = (Isle*) FindWorld(*g_isleScript, 0); + Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle); assert(isle); isle->SetDestLocation(LegoGameState::e_jetrace); diff --git a/LEGO1/lego/legoomni/src/actors/doors.cpp b/LEGO1/lego/legoomni/src/actors/doors.cpp index d4aedd7c..2ac676b3 100644 --- a/LEGO1/lego/legoomni/src/actors/doors.cpp +++ b/LEGO1/lego/legoomni/src/actors/doors.cpp @@ -1,12 +1,21 @@ #include "doors.h" +#include "mxmisc.h" +#include "mxtimer.h" + DECOMP_SIZE_ASSERT(Doors, 0x1f8) -// STUB: LEGO1 0x10066100 +// FUNCTION: LEGO1 0x10066100 MxResult Doors::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) { - // TODO - return 0; + if (m_unk0x154 == 1) { + m_unk0x154 = 2; + m_unk0x158 = Timer()->GetTime(); + m_unk0x164 = m_unk0x15c[2]; + m_unk0x1ac = m_unk0x160[2]; + } + + return m_unk0x1f4 < 0.001 ? SUCCESS : FAILURE; } // STUB: LEGO1 0x10066250 diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 1626f7be..3aff5575 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -76,7 +76,7 @@ void Helicopter::Exit() IslePathActor::Exit(); if (GameState()->GetCurrentAct() == LegoGameState::e_act1) { - GameState()->SetCurrentArea(LegoGameState::e_copter); + GameState()->m_currentArea = LegoGameState::e_copter; if (UserActor() && UserActor()->IsA("IslePathActor")) { ((IslePathActor*) UserActor()) ->SpawnPlayer( @@ -180,7 +180,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param) break; } Exit(); - GameState()->SetCurrentArea(LegoGameState::e_unk66); + GameState()->m_currentArea = LegoGameState::e_unk66; ret = 1; break; case IsleScript::c_Helicopter_TakeOff_Ctl: { diff --git a/LEGO1/lego/legoomni/src/actors/jukeboxentity.cpp b/LEGO1/lego/legoomni/src/actors/jukeboxentity.cpp index a504fcbc..2ac6ed54 100644 --- a/LEGO1/lego/legoomni/src/actors/jukeboxentity.cpp +++ b/LEGO1/lego/legoomni/src/actors/jukeboxentity.cpp @@ -41,7 +41,7 @@ MxLong JukeBoxEntity::Notify(MxParam& p_param) ((IslePathActor*) UserActor())->Exit(); } - ((Isle*) FindWorld(*g_isleScript, 0))->SetDestLocation(LegoGameState::e_jukeboxw); + ((Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle))->SetDestLocation(LegoGameState::e_jukeboxw); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); return 1; } diff --git a/LEGO1/lego/legoomni/src/actors/pizza.cpp b/LEGO1/lego/legoomni/src/actors/pizza.cpp index 593d7f74..346153a5 100644 --- a/LEGO1/lego/legoomni/src/actors/pizza.cpp +++ b/LEGO1/lego/legoomni/src/actors/pizza.cpp @@ -2,30 +2,143 @@ #include "isle.h" #include "isle_actions.h" +#include "jukebox_actions.h" #include "legoanimationmanager.h" +#include "legoeventnotificationparam.h" #include "legogamestate.h" +#include "legoinputmanager.h" +#include "legopathstruct.h" +#include "legoutils.h" #include "legoworld.h" #include "misc.h" +#include "mxactionnotificationparam.h" +#include "mxbackgroundaudiomanager.h" +#include "mxdebug.h" #include "mxmisc.h" #include "mxticklemanager.h" +#include "mxtimer.h" +#include "mxtransitionmanager.h" +#include "pizzeria.h" +#include "skateboard.h" +#include "sndanim_actions.h" DECOMP_SIZE_ASSERT(Pizza, 0x9c) DECOMP_SIZE_ASSERT(PizzaMissionState, 0xb4) -DECOMP_SIZE_ASSERT(PizzaMissionState::Entry, 0x20) +DECOMP_SIZE_ASSERT(PizzaMissionState::Mission, 0x20) // Flags used in isle.cpp extern MxU32 g_isleFlags; +// GLOBAL: LEGO1 0x100f3a80 +IsleScript::Script PizzaMissionState::g_pepperActions[] = { + IsleScript::c_pnsx48pr_RunAnim, + IsleScript::c_pnsx69pr_RunAnim, + IsleScript::c_pns125ni_RunAnim, + IsleScript::c_pns122pr_RunAnim, + IsleScript::c_noneIsle, + IsleScript::c_noneIsle, + IsleScript::c_ppz120pa_RunAnim, + IsleScript::c_ppz117ma_RunAnim, + IsleScript::c_ppz118ma_RunAnim, + IsleScript::c_ppz119ma_RunAnim, + IsleScript::c_nja001pr_RunAnim, + IsleScript::c_nja001pr_RunAnim, + IsleScript::c_nja001pr_RunAnim +}; + +// GLOBAL: LEGO1 0x100f3ab8 +MxLong PizzaMissionState::g_pepperFinishTimes[] = {100000, 200000, 300000, 350000}; + +// GLOBAL: LEGO1 0x100f3ac8 +IsleScript::Script PizzaMissionState::g_lauraActions[] = { + IsleScript::c_pns096pr_RunAnim, + IsleScript::c_pns097pr_RunAnim, + IsleScript::c_pns098pr_RunAnim, + IsleScript::c_pns099pr_RunAnim, + IsleScript::c_noneIsle, + IsleScript::c_ppz086bs_RunAnim, + IsleScript::c_ppz090ma_RunAnim, + IsleScript::c_ppz088ma_RunAnim, + IsleScript::c_ppz089ma_RunAnim, + IsleScript::c_ppz095pe_RunAnim, + IsleScript::c_pho104re_RunAnim, + IsleScript::c_pho105re_RunAnim, + IsleScript::c_pho106re_RunAnim +}; + +// GLOBAL: LEGO1 0x100f3b00 +MxLong PizzaMissionState::g_lauraFinishTimes[] = {100000, 200000, 300000, 350000}; + +// GLOBAL: LEGO1 0x100f3b10 +IsleScript::Script PizzaMissionState::g_nickActions[] = { + IsleScript::c_pns042bm_RunAnim, + IsleScript::c_pns043en_RunAnim, + IsleScript::c_pns045p1_RunAnim, + IsleScript::c_pns048pr_RunAnim, + IsleScript::c_ppz029rd_RunAnim, + IsleScript::c_noneIsle, + IsleScript::c_ppz038ma_RunAnim, + IsleScript::c_ppz037ma_RunAnim, + IsleScript::c_ppz037ma_RunAnim, + IsleScript::c_ppz037ma_RunAnim, + IsleScript::c_pgs050nu_RunAnim, + IsleScript::c_pgs051nu_RunAnim, + IsleScript::c_pgs052nu_RunAnim +}; + +// GLOBAL: LEGO1 0x100f3b48 +MxLong PizzaMissionState::g_nickFinishTimes[] = {100000, 200000, 300000, 350000}; + +// GLOBAL: LEGO1 0x100f3b58 +IsleScript::Script PizzaMissionState::g_mamaActions[] = { + IsleScript::c_pns022pr_RunAnim, + IsleScript::c_pns021dl_RunAnim, + IsleScript::c_pns018rd_RunAnim, + IsleScript::c_pns019pr_RunAnim, + IsleScript::c_ppz008rd_RunAnim, + IsleScript::c_noneIsle, + IsleScript::c_ppz013pa_RunAnim, + IsleScript::c_ppz010pa_RunAnim, + IsleScript::c_ppz011pa_RunAnim, + IsleScript::c_ppz016pe_RunAnim, + IsleScript::c_pps025ni_RunAnim, + IsleScript::c_pps026ni_RunAnim, + IsleScript::c_pps027ni_RunAnim +}; + +// GLOBAL: LEGO1 0x100f3b90 +MxLong PizzaMissionState::g_mamaFinishTimes[] = {100000, 200000, 300000, 350000}; + +// GLOBAL: LEGO1 0x100f3ba0 +IsleScript::Script PizzaMissionState::g_papaActions[] = { + IsleScript::c_pns065rd_RunAnim, + IsleScript::c_pns066db_RunAnim, + IsleScript::c_pns067gd_RunAnim, + IsleScript::c_pns069pr_RunAnim, + IsleScript::c_noneIsle, + IsleScript::c_noneIsle, + IsleScript::c_ppz061ma_RunAnim, + IsleScript::c_ppz059ma_RunAnim, + IsleScript::c_ppz060ma_RunAnim, + IsleScript::c_ppz064ma_RunAnim, + IsleScript::c_prt072sl_RunAnim, + IsleScript::c_prt073sl_RunAnim, + IsleScript::c_prt074sl_RunAnim +}; + +// GLOBAL: LEGO1 0x100f3bd8 +MxLong PizzaMissionState::g_papaFinishTimes[] = {100000, 200000, 300000, 350000}; + // FUNCTION: LEGO1 0x10037ef0 Pizza::Pizza() { m_state = NULL; - m_entry = NULL; - m_skateboard = NULL; + m_mission = NULL; + m_skateBoard = NULL; m_act1state = NULL; - m_unk0x8c = -1; - m_unk0x98 = 0; - m_unk0x90 = 0x80000000; + m_unk0x8c = IsleScript::c_noneIsle; + m_unk0x98 = FALSE; + m_unk0x90 = INT_MIN; } // FUNCTION: LEGO1 0x10038100 @@ -41,13 +154,14 @@ MxResult Pizza::Create(MxDSAction& p_dsAction) if (result == SUCCESS) { CreateState(); - m_skateboard = (SkateBoard*) m_world->Find(m_atomId, IsleScript::c_SkateBoard_Actor); + m_skateBoard = (SkateBoard*) m_world->Find(m_atomId, IsleScript::c_SkateBoard_Actor); } return result; } // FUNCTION: LEGO1 0x100381b0 +// FUNCTION: BETA10 0x100edaec void Pizza::CreateState() { m_state = (PizzaMissionState*) GameState()->GetState("PizzaMissionState"); @@ -62,68 +176,431 @@ void Pizza::CreateState() } // FUNCTION: LEGO1 0x10038220 -void Pizza::FUN_10038220(MxU32 p_objectId) +// FUNCTION: BETA10 0x100edb81 +void Pizza::FUN_10038220(IsleScript::Script p_objectId) { AnimationManager()->FUN_10064740(NULL); - m_entry = m_state->GetState(GameState()->GetActorId()); + m_mission = m_state->GetMission(GameState()->GetActorId()); m_state->m_unk0x0c = 1; m_act1state->m_unk0x018 = 3; - m_entry->m_unk0x10 = 0x80000000; + m_mission->m_startTime = INT_MIN; g_isleFlags &= ~Isle::c_playMusic; AnimationManager()->EnableCamAnims(FALSE); AnimationManager()->FUN_1005f6d0(FALSE); - FUN_10038fe0(p_objectId, FALSE); - m_unk0x8c = -1; + PlayAction(p_objectId, FALSE); + m_unk0x8c = IsleScript::c_noneIsle; } -// STUB: LEGO1 0x100382b0 +// FUNCTION: LEGO1 0x100382b0 +// FUNCTION: BETA10 0x100edc9b void Pizza::FUN_100382b0() { + if (m_state->m_unk0x0c != 8) { + if (m_unk0x8c != IsleScript::c_noneIsle) { + InvokeAction(Extra::e_stop, *g_isleScript, m_unk0x8c, NULL); + } + + m_act1state->m_unk0x018 = 0; + m_state->m_unk0x0c = 0; + UserActor()->SetState(0); + g_isleFlags |= Isle::c_playMusic; + AnimationManager()->EnableCamAnims(TRUE); + AnimationManager()->FUN_1005f6d0(TRUE); + m_mission->m_startTime = INT_MIN; + m_mission = NULL; + m_unk0x98 = FALSE; + m_unk0x8c = IsleScript::c_noneIsle; + BackgroundAudioManager()->RaiseVolume(); + TickleManager()->UnregisterClient(this); + m_unk0x90 = INT_MIN; + m_skateBoard->EnableScenePresentation(FALSE); + m_skateBoard->SetUnknown0x160(FALSE); + MxTrace("Pizza mission: idle\n"); + } } -// STUB: LEGO1 0x10038380 -void Pizza::FUN_10038380() +// FUNCTION: LEGO1 0x10038380 +void Pizza::StopActions() { + InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_pns050p1_RunAnim, NULL); + InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_wns050p1_RunAnim, NULL); + + PizzaMissionState::Mission* mission = m_mission; + if (mission != NULL) { + for (MxS32 i = 0; i < mission->m_numActions; i++) { + InvokeAction(Extra::e_stop, *g_isleScript, mission->GetActions()[i], NULL); + } + } } -// STUB: LEGO1 0x100383f0 +// FUNCTION: LEGO1 0x100383f0 +// FUNCTION: BETA10 0x100edd10 MxLong Pizza::HandleClick() { - // TODO + if (m_state->m_unk0x0c == 1) { + m_state->m_unk0x0c = 2; + m_mission->m_startTime = Timer()->GetTime(); + TickleManager()->RegisterClient(this, 200); + AnimationManager()->FUN_10061010(FALSE); + } + + if (m_state->m_unk0x0c == 2) { + m_act1state->m_unk0x018 = 3; + + if (m_skateBoard == NULL) { + m_skateBoard = (SkateBoard*) m_world->Find(m_atomId, IsleScript::c_SkateBoard_Actor); + assert(m_skateBoard); + } + + IsleScript::Script action; + + switch (m_state->FUN_10039540()) { + case 0: + action = m_mission->m_actions[m_mission->m_numActions + 3]; + break; + case 1: + action = m_mission->m_actions[m_mission->m_numActions + 4]; + break; + default: + action = m_mission->m_actions[m_mission->m_numActions + 5]; + } + + PlayAction(action, TRUE); + m_state->m_unk0x0c = 3; + PlayMusic(JukeboxScript::c_PizzaMission_Music); + return 1; + } + return 0; } -// STUB: LEGO1 0x100384f0 -MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam&) +// FUNCTION: LEGO1 0x100384f0 +// FUNCTION: BETA10 0x100ede53 +MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param) { - // TODO + if (m_state->m_unk0x0c == 4) { + MxLong time = Timer()->GetTime() - m_mission->m_startTime; + + if (p_param.GetTrigger() == LegoPathStruct::c_s && p_param.GetData() == 0x12e && + GameState()->GetActorId() == LegoActor::c_pepper) { + m_state->m_unk0x0c = 5; + m_state->SetUnknown0xb0(SndanimScript::c_TRS302_OpenJailDoor); + + if (time < m_mission->GetRedFinishTime()) { + m_mission->UpdateScore(LegoState::e_red); + } + else if (time < m_mission->GetBlueFinishTime()) { + m_mission->UpdateScore(LegoState::e_blue); + } + else { + m_mission->UpdateScore(LegoState::e_yellow); + } + + MxTrace("Pizza mission: ending\n"); + } + else if ((p_param.GetTrigger() == LegoPathStruct::c_camAnim && ( + ((p_param.GetData() == 0x24 || p_param.GetData() == 0x22) && GameState()->GetActorId() == LegoActor::c_mama) || + (p_param.GetData() == 0x33 && GameState()->GetActorId() == LegoActor::c_papa) || + ((p_param.GetData() == 0x08 || p_param.GetData() == 0x09) && GameState()->GetActorId() == LegoActor::c_nick) || + (p_param.GetData() == 0x0b && GameState()->GetActorId() == LegoActor::c_laura) + )) || (p_param.GetTrigger() == LegoPathStruct::c_w && p_param.GetData() == 0x169 && GameState()->GetActorId() == LegoActor::c_nick)) { + IsleScript::Script action; + + if (time < m_mission->GetRedFinishTime()) { + action = m_mission->GetRedFinishAction(); + m_mission->UpdateScore(LegoState::e_red); + } + else if (time < m_mission->GetBlueFinishTime()) { + action = m_mission->GetBlueFinishAction(); + m_mission->UpdateScore(LegoState::e_blue); + } + else { + action = m_mission->GetYellowFinishAction(); + m_mission->UpdateScore(LegoState::e_yellow); + } + + StopActions(); + + switch (action) { + case IsleScript::c_pps025ni_RunAnim: + case IsleScript::c_pps026ni_RunAnim: + case IsleScript::c_pps027ni_RunAnim: + m_unk0x90 = Timer()->GetTime(); + m_unk0x94 = 3800; + break; + case IsleScript::c_pgs050nu_RunAnim: + case IsleScript::c_pgs051nu_RunAnim: + case IsleScript::c_pgs052nu_RunAnim: + m_unk0x90 = Timer()->GetTime(); + m_unk0x94 = 6400; + break; + case IsleScript::c_prt072sl_RunAnim: + case IsleScript::c_prt073sl_RunAnim: + case IsleScript::c_prt074sl_RunAnim: + m_unk0x90 = Timer()->GetTime(); + m_unk0x94 = 7000; + break; + case IsleScript::c_pho104re_RunAnim: + case IsleScript::c_pho105re_RunAnim: + case IsleScript::c_pho106re_RunAnim: + m_unk0x90 = Timer()->GetTime(); + m_unk0x94 = 6500; + break; + } + + m_state->m_unk0x0c = 5; + PlayAction(action, TRUE); + + MxTrace("Pizza mission: ending\n"); + } + else if (p_param.GetTrigger() == LegoPathStruct::c_w) { + if (p_param.GetData() == 0x15e && GameState()->GetActorId() == LegoActor::c_pepper) { + if (!m_unk0x98) { + m_unk0x98 = TRUE; + InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_pns050p1_RunAnim, NULL); + } + } + else if (p_param.GetData() == 0x15f && GameState()->GetActorId() == LegoActor::c_papa && !m_unk0x98) { + m_unk0x98 = TRUE; + InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_wns050p1_RunAnim, NULL); + } + } + } + return 0; } -// STUB: LEGO1 0x100388a0 +// FUNCTION: LEGO1 0x100388a0 +// FUNCTION: BETA10 0x100ee2d9 MxResult Pizza::Tickle() { - // TODO + MxLong time = Timer()->GetTime(); + + if (m_unk0x90 != INT_MIN && m_unk0x94 + m_unk0x90 <= time) { + m_unk0x90 = INT_MIN; + m_skateBoard->EnableScenePresentation(FALSE); + m_skateBoard->SetUnknown0x160(FALSE); + TickleManager()->UnregisterClient(this); + } + + if (m_mission != NULL && m_mission->m_startTime != INT_MIN) { + if (m_state->m_unk0x0c == 4) { + assert(m_mission); + + if (time > m_mission->m_startTime + m_mission->GetTimeoutTime()) { + StopActions(); + m_mission->UpdateScore(LegoState::e_grey); + FUN_100382b0(); + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_Avo917In_PlayWav, NULL); + MxTrace("Pizza mission: timeout, stop\n"); + } + else if (time >= m_mission->m_startTime + 35000 && m_unk0x8c == IsleScript::c_noneIsle) { + switch (GameState()->GetActorId()) { + case LegoActor::c_pepper: + m_unk0x8c = IsleScript::c_Avo914In_PlayWav; + break; + case LegoActor::c_mama: + m_unk0x8c = IsleScript::c_Avo910In_PlayWav; + break; + case LegoActor::c_papa: + m_unk0x8c = IsleScript::c_Avo912In_PlayWav; + break; + case LegoActor::c_nick: + m_unk0x8c = IsleScript::c_Avo911In_PlayWav; + break; + case LegoActor::c_laura: + m_unk0x8c = IsleScript::c_Avo913In_PlayWav; + break; + } + + BackgroundAudioManager()->LowerVolume(); + + if (m_unk0x8c != IsleScript::c_noneIsle) { + InvokeAction(Extra::e_start, *g_isleScript, m_unk0x8c, NULL); + } + } + } + else if (m_state->m_unk0x0c == 2) { + assert(m_mission); + + if (Timer()->GetTime() > m_mission->m_startTime + 5000) { + m_skateBoard->SetUnknown0x160(FALSE); + m_skateBoard->EnableScenePresentation(FALSE); + TickleManager()->UnregisterClient(this); + m_mission->UpdateScore(LegoState::e_grey); + m_state->m_unk0x0c = 9; + AnimationManager()->FUN_1005f6d0(TRUE); + PlayAction(m_mission->GetUnknownFinishAction(), TRUE); + MxTrace("Pizza mission: timeout, declining\n"); + } + } + } + return SUCCESS; } -// STUB: LEGO1 0x10038b10 -MxLong Pizza::HandleEndAction(MxEndActionNotificationParam&) +// FUNCTION: LEGO1 0x10038b10 +// FUNCTION: BETA10 0x100ee4f5 +MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param) { - // TODO - return 0; + MxLong result = 0; + MxU32 objectId = p_param.GetAction()->GetObjectId(); + + if (m_unk0x8c == objectId) { + BackgroundAudioManager()->RaiseVolume(); + return 1; + } + + switch (m_state->m_unk0x0c) { + case 1: + if (m_state->GetUnknown0xb0() == objectId) { + m_state->m_unk0x0c = 2; + m_mission->m_startTime = Timer()->GetTime(); + TickleManager()->RegisterClient(this, 200); + MxTrace("Pizza mission: proposed\n"); + } + break; + case 3: + if (m_state->GetUnknown0xb0() == objectId) { + m_mission->m_startTime = Timer()->GetTime(); + + PizzaMissionState::Mission* mission = m_mission; + for (MxS32 i = 0; i < mission->m_numActions; i++) { + InvokeAction(Extra::e_start, *g_isleScript, mission->GetActions()[i], NULL); + } + + m_state->m_unk0x0c = 4; + m_state->SetUnknown0xb0(IsleScript::c_noneIsle); + UserActor()->SetState(0); + m_skateBoard->SetUnknown0x160(TRUE); + m_world->PlaceActor(m_skateBoard, "int37", 2, 0.5, 3, 0.5); + +#ifdef COMPAT_MODE + { + LegoEventNotificationParam param(c_notificationClick, NULL, 0, 0, 0, 0); + m_skateBoard->Notify(param); + } +#else + m_skateBoard->Notify(LegoEventNotificationParam(c_notificationClick, NULL, 0, 0, 0, 0)); +#endif + + MxTrace("Pizza mission: continues\n"); + result = 1; + } + break; + case 5: + if (m_state->GetUnknown0xb0() == objectId) { + StopActions(); + + if (GameState()->GetActorId() == LegoActor::c_pepper) { + IsleScript::Script action = IsleScript::c_noneIsle; + + if (!((Isle*) CurrentWorld())->HasHelicopter()) { + switch (m_mission->m_unk0x14) { + case 1: + action = IsleScript::c_pja126br_RunAnim; + m_mission->m_unk0x14++; + m_state->m_unk0x0c = 6; + MxTrace("Pizza mission: succeeds\n"); + break; + case 2: + action = IsleScript::c_pja129br_RunAnim; + m_unk0x90 = Timer()->GetTime(); + m_unk0x94 = 500; + m_mission->m_unk0x14++; + m_state->m_unk0x0c = 6; + MxTrace("Pizza mission: succeeds\n"); + break; + case 3: + action = IsleScript::c_pja131br_RunAnim; + m_unk0x90 = Timer()->GetTime(); + m_unk0x94 = 500; + m_state->m_unk0x0c = 6; + break; + } + } + else { + action = IsleScript::c_pja132br_RunAnim; + m_unk0x90 = Timer()->GetTime(); + m_unk0x94 = 2300; + m_state->m_unk0x0c = 8; + InputManager()->DisableInputProcessing(); + InputManager()->SetUnknown336(TRUE); + MxTrace("Pizza mission: go to Act2\n"); + } + + PlayAction(action, TRUE); + } + else { + FUN_100382b0(); + m_state->m_unk0x0c = 0; + m_state->SetUnknown0xb0(IsleScript::c_noneIsle); + } + } + break; + case 6: + if (m_state->GetUnknown0xb0() == objectId) { + if (objectId == IsleScript::c_pja126br_RunAnim) { + PlayAction(IsleScript::c_pja127br_RunAnim, TRUE); + m_unk0x90 = Timer()->GetTime(); + m_unk0x94 = 700; + } + else if (objectId == IsleScript::c_pja129br_RunAnim) { + PlayAction(IsleScript::c_pja130br_RunAnim, TRUE); + } + else { + FUN_100382b0(); + m_state->m_unk0x0c = 0; + m_state->SetUnknown0xb0(IsleScript::c_noneIsle); + } + } + break; + case 8: + if (m_state->GetUnknown0xb0() == objectId) { + m_act1state->m_unk0x018 = 0; + m_state->m_unk0x0c = 0; + GameState()->m_currentArea = LegoGameState::e_isle; + TickleManager()->UnregisterClient(this); + ((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_act2main); + TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); + } + break; + case 9: + if (m_state->GetUnknown0xb0() == objectId) { + FUN_100382b0(); + } + break; + } + + return result; } -// STUB: LEGO1 0x10038fe0 -void Pizza::FUN_10038fe0(MxU32 p_objectId, MxBool) +// FUNCTION: LEGO1 0x10038fe0 +// FUNCTION: BETA10 0x100ef520 +void Pizza::PlayAction(MxU32 p_objectId, MxBool p_param7) { - // TODO + m_state->SetUnknown0xb0(p_objectId); + + if (m_unk0x8c != IsleScript::c_noneIsle) { + InvokeAction(Extra::e_stop, *g_isleScript, m_unk0x8c, NULL); + } + + AnimationManager()->FUN_10060dc0(p_objectId, NULL, TRUE, FALSE, NULL, FALSE, p_param7, TRUE, TRUE); } -// STUB: LEGO1 0x10039030 +// FUNCTION: LEGO1 0x10039030 +// FUNCTION: BETA10 0x100eea25 PizzaMissionState::PizzaMissionState() { - // TODO + m_unk0x0c = 0; + m_missions[0] = Mission(LegoActor::c_pepper, 2, g_pepperFinishTimes, g_pepperActions, 4); + m_missions[1] = Mission(LegoActor::c_mama, 2, g_mamaFinishTimes, g_mamaActions, 4); + m_missions[2] = Mission(LegoActor::c_papa, 2, g_papaFinishTimes, g_papaActions, 4); + m_missions[3] = Mission(LegoActor::c_nick, 2, g_nickFinishTimes, g_nickActions, 4); + m_missions[4] = Mission(LegoActor::c_laura, 2, g_lauraFinishTimes, g_lauraActions, 4); + m_pizzeriaState = (PizzeriaState*) GameState()->GetState("PizzeriaState"); + m_unk0xb0 = IsleScript::c_noneIsle; } // FUNCTION: LEGO1 0x100393c0 @@ -133,12 +610,12 @@ MxResult PizzaMissionState::Serialize(LegoFile* p_file) if (p_file->IsReadMode()) { for (MxS16 i = 0; i < 5; i++) { - m_state[i].ReadFromFile(p_file); + m_missions[i].ReadFromFile(p_file); } } else if (p_file->IsWriteMode()) { for (MxS16 i = 0; i < 5; i++) { - m_state[i].WriteToFile(p_file); + m_missions[i].WriteToFile(p_file); } } @@ -146,13 +623,19 @@ MxResult PizzaMissionState::Serialize(LegoFile* p_file) } // FUNCTION: LEGO1 0x10039510 -PizzaMissionState::Entry* PizzaMissionState::GetState(MxU8 p_id) +PizzaMissionState::Mission* PizzaMissionState::GetMission(MxU8 p_actorId) { for (MxS16 i = 0; i < 5; i++) { - if (m_state[i].m_id == p_id) { - return m_state + i; + if (m_missions[i].m_actorId == p_actorId) { + return m_missions + i; } } return NULL; } + +// FUNCTION: LEGO1 0x10039540 +MxS16 PizzaMissionState::FUN_10039540() +{ + return m_pizzeriaState->FUN_10017d50(); +} diff --git a/LEGO1/lego/legoomni/src/actors/pizzeria.cpp b/LEGO1/lego/legoomni/src/actors/pizzeria.cpp index 3b61ddb7..a7681f87 100644 --- a/LEGO1/lego/legoomni/src/actors/pizzeria.cpp +++ b/LEGO1/lego/legoomni/src/actors/pizzeria.cpp @@ -13,7 +13,26 @@ DECOMP_SIZE_ASSERT(Pizzeria, 0x84) DECOMP_SIZE_ASSERT(PizzeriaState, 0x58) -DECOMP_SIZE_ASSERT(PizzeriaState::StateStruct, 0x14) + +// GLOBAL: LEGO1 0x100f0ce8 +IsleScript::Script PizzeriaState::g_pepperActions[] = + {IsleScript::c_ppz107ma_RunAnim, IsleScript::c_ppz114pa_RunAnim, IsleScript::c_ppz114pa_RunAnim}; + +// GLOBAL: LEGO1 0x100f0cf8 +IsleScript::Script PizzeriaState::g_mamaActions[] = + {IsleScript::c_ppz001pe_RunAnim, IsleScript::c_ppz006pa_RunAnim, IsleScript::c_ppz007pa_RunAnim}; + +// GLOBAL: LEGO1 0x100f0d08 +IsleScript::Script PizzeriaState::g_papaActions[] = + {IsleScript::c_ppz054ma_RunAnim, IsleScript::c_ppz055ma_RunAnim, IsleScript::c_ppz056ma_RunAnim}; + +// GLOBAL: LEGO1 0x100f0d18 +IsleScript::Script PizzeriaState::g_nickActions[] = + {IsleScript::c_ppz031ma_RunAnim, IsleScript::c_ppz035pa_RunAnim, IsleScript::c_ppz036pa_RunAnim}; + +// GLOBAL: LEGO1 0x100f0d28 +IsleScript::Script PizzeriaState::g_lauraActions[] = + {IsleScript::c_ppz075pa_RunAnim, IsleScript::c_ppz082pa_RunAnim, IsleScript::c_ppz084pa_RunAnim}; // FUNCTION: LEGO1 0x100179c0 MxResult Pizzeria::Create(MxDSAction& p_dsAction) @@ -28,6 +47,7 @@ MxResult Pizzeria::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x100179f0 +// FUNCTION: BETA10 0x100efbfc void Pizzeria::CreateState() { LegoGameState* gameState = GameState(); @@ -46,6 +66,7 @@ void Pizzeria::CreateState() } // FUNCTION: LEGO1 0x10017a50 +// FUNCTION: BETA10 0x100efc91 MxLong Pizzeria::HandleClick() { if (FUN_1003ef60() && m_pizzaMissionState->m_unk0x0c == 0) { @@ -58,22 +79,41 @@ MxLong Pizzeria::HandleClick() AnimationManager()->FUN_10061010(FALSE); Pizza* pizza = (Pizza*) CurrentWorld()->Find(*g_isleScript, IsleScript::c_Pizza_Actor); - pizza->FUN_10038220(m_pizzeriaState->FUN_10017d70()); + pizza->FUN_10038220((IsleScript::Script) m_pizzeriaState->NextAction()); } return 1; } -// STUB: LEGO1 0x10017af0 +// FUNCTION: LEGO1 0x10017af0 +// FUNCTION: BETA10 0x100efd14 PizzeriaState::PizzeriaState() { - // TODO + m_unk0x08[0] = Playlist((MxU32*) g_pepperActions, sizeOfArray(g_pepperActions), Playlist::e_once); + m_unk0x08[1] = Playlist((MxU32*) g_mamaActions, sizeOfArray(g_mamaActions), Playlist::e_once); + m_unk0x08[2] = Playlist((MxU32*) g_papaActions, sizeOfArray(g_papaActions), Playlist::e_once); + m_unk0x08[3] = Playlist((MxU32*) g_nickActions, sizeOfArray(g_nickActions), Playlist::e_once); + m_unk0x08[4] = Playlist((MxU32*) g_lauraActions, sizeOfArray(g_lauraActions), Playlist::e_once); + memset(m_unk0x44, -1, sizeof(m_unk0x44)); } -// STUB: LEGO1 0x10017d70 -MxU32 PizzeriaState::FUN_10017d70() +// FUNCTION: LEGO1 0x10017d50 +MxS16 PizzeriaState::FUN_10017d50() { - return 0; + return m_unk0x44[GameState()->GetActorId() - 1]; +} + +// FUNCTION: LEGO1 0x10017d70 +// FUNCTION: BETA10 0x100effc0 +MxU32 PizzeriaState::NextAction() +{ + MxU8 actorId = GameState()->GetActorId(); + + if (m_unk0x44[actorId - 1] < 2) { + m_unk0x44[actorId - 1]++; + } + + return m_unk0x08[actorId - 1].Next(); } // FUNCTION: LEGO1 0x10017da0 diff --git a/LEGO1/lego/legoomni/src/actors/radio.cpp b/LEGO1/lego/legoomni/src/actors/radio.cpp index 4704ca29..3a22ed16 100644 --- a/LEGO1/lego/legoomni/src/actors/radio.cpp +++ b/LEGO1/lego/legoomni/src/actors/radio.cpp @@ -18,7 +18,7 @@ DECOMP_SIZE_ASSERT(Radio, 0x10) DECOMP_SIZE_ASSERT(RadioState, 0x30) // GLOBAL: LEGO1 0x100f3218 -JukeboxScript::Script g_unk0x100f3218[6] = { +JukeboxScript::Script g_unk0x100f3218[] = { JukeboxScript::c_sns002ra_Audio, JukeboxScript::c_sns001ja_Audio, JukeboxScript::c_snsc01js_Audio, @@ -28,7 +28,7 @@ JukeboxScript::Script g_unk0x100f3218[6] = { }; // GLOBAL: LEGO1 0x100f3230 -JukeboxScript::Script g_unk0x100f3230[14] = { +JukeboxScript::Script g_unk0x100f3230[] = { JukeboxScript::c_ham035ra_Audio, JukeboxScript::c_ham039ra_Audio, JukeboxScript::c_sns005ra_Audio, @@ -46,7 +46,7 @@ JukeboxScript::Script g_unk0x100f3230[14] = { }; // GLOBAL: LEGO1 0x100f3268 -JukeboxScript::Script g_unk0x100f3268[9] = { +JukeboxScript::Script g_unk0x100f3268[] = { JukeboxScript::c_CentralRoads_Music, JukeboxScript::c_BeachBlvd_Music, JukeboxScript::c_ResidentalArea_Music, @@ -214,14 +214,14 @@ RadioState::RadioState() MxS32 random = rand(); m_unk0x2c = random % 3; - m_unk0x08[0] = LegoState::Playlist((MxU32*) g_unk0x100f3218, sizeof(g_unk0x100f3218) / sizeof(g_unk0x100f3218[0])); - m_unk0x08[0].SetUnknown0x08(rand() % (sizeof(g_unk0x100f3218) / sizeof(g_unk0x100f3218[0]))); + m_unk0x08[0] = Playlist((MxU32*) g_unk0x100f3218, sizeOfArray(g_unk0x100f3218), Playlist::e_loop); + m_unk0x08[0].SetNextIndex(rand() % sizeOfArray(g_unk0x100f3218)); - m_unk0x08[1] = LegoState::Playlist((MxU32*) g_unk0x100f3230, sizeof(g_unk0x100f3230) / sizeof(g_unk0x100f3230[0])); - m_unk0x08[1].SetUnknown0x08(rand() % (sizeof(g_unk0x100f3230) / sizeof(g_unk0x100f3230[0]))); + m_unk0x08[1] = Playlist((MxU32*) g_unk0x100f3230, sizeOfArray(g_unk0x100f3230), Playlist::e_loop); + m_unk0x08[1].SetNextIndex(rand() % sizeOfArray(g_unk0x100f3230)); - m_unk0x08[2] = LegoState::Playlist((MxU32*) g_unk0x100f3268, sizeof(g_unk0x100f3268) / sizeof(g_unk0x100f3268[0])); - m_unk0x08[2].SetUnknown0x08(rand() % (sizeof(g_unk0x100f3268) / sizeof(g_unk0x100f3268[0]))); + m_unk0x08[2] = Playlist((MxU32*) g_unk0x100f3268, sizeOfArray(g_unk0x100f3268), Playlist::e_loop); + m_unk0x08[2].SetNextIndex(rand() % sizeOfArray(g_unk0x100f3268)); m_active = FALSE; } diff --git a/LEGO1/lego/legoomni/src/actors/skateboard.cpp b/LEGO1/lego/legoomni/src/actors/skateboard.cpp index b2d00f94..cc577c30 100644 --- a/LEGO1/lego/legoomni/src/actors/skateboard.cpp +++ b/LEGO1/lego/legoomni/src/actors/skateboard.cpp @@ -58,7 +58,7 @@ void SkateBoard::Exit() { if (m_act1state->m_unk0x018 == 3) { Pizza* pizza = (Pizza*) CurrentWorld()->Find(*g_isleScript, IsleScript::c_Pizza_Actor); - pizza->FUN_10038380(); + pizza->StopActions(); pizza->FUN_100382b0(); m_unk0x160 = FALSE; } diff --git a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp index d3e08256..4a921511 100644 --- a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp @@ -300,6 +300,7 @@ void MxBackgroundAudioManager::Stop() } // FUNCTION: LEGO1 0x1007f570 +// FUNCTION: BETA10 0x100e94e6 void MxBackgroundAudioManager::LowerVolume() { if (m_unk0x148 == 0) { diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index 48e6bb03..68b1495f 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -1,8 +1,12 @@ #include "legocarbuild.h" +#include "copter_actions.h" #include "dunebuggy.h" +#include "dunecar_actions.h" #include "helicopter.h" +#include "isle_actions.h" #include "jetski.h" +#include "jetski_actions.h" #include "jukebox_actions.h" #include "legocarbuildpresenter.h" #include "legocontrolmanager.h" @@ -20,14 +24,59 @@ #include "mxstillpresenter.h" #include "mxticklemanager.h" #include "mxtransitionmanager.h" +#include "mxvariabletable.h" #include "racecar.h" +#include "racecar_actions.h" #include "scripts.h" #include #include +// Names and values verified by BETA10 0x1006d742. +// Note that these were probably hard-coded numbers in the original. +#define Helicopter_Actor CopterScript::c_Helicopter_Actor +#define DuneBugy_Actor DunecarScript::c_DuneBugy_Actor +#define Jetski_Actor JetskiScript::c_Jetski_Actor +#define RaceCar_Actor RacecarScript::c_RaceCar_Actor + DECOMP_SIZE_ASSERT(LegoCarBuild, 0x34c) DECOMP_SIZE_ASSERT(LegoVehicleBuildState, 0x50) +DECOMP_SIZE_ASSERT(LegoCarBuild::LookupTableActions, 0x1c); + +// These four structs can be matched to the vehicle types using BETA10 0x10070520 + +// GLOBAL: LEGO1 0x100d65b0 +// GLOBAL: BETA10 0x101bb7c0 +LegoCarBuild::LookupTableActions LegoCarBuild::g_unk0x100d65b0[] = { + {DunecarScript::c_igs001d3_RunAnim, + DunecarScript::c_igs002d3_RunAnim, + DunecarScript::c_igs003d3_RunAnim, + DunecarScript::c_igs004d3_RunAnim, + DunecarScript::c_igs005d3_RunAnim, + DunecarScript::c_igs004d3_RunAnim, + DunecarScript::c_igsxx1d3_RunAnim}, + {JetskiScript::c_ijs001d4_RunAnim, + JetskiScript::c_ijs003d4_RunAnim, + JetskiScript::c_ijs004d4_RunAnim, + JetskiScript::c_ijs005d4_RunAnim, + JetskiScript::c_ijs006d4_RunAnim, + JetskiScript::c_ijs007d4_RunAnim, + JetskiScript::c_ijsxx2d4_RunAnim}, + {CopterScript::c_ips001d2_RunAnim, + CopterScript::c_ips002d2_RunAnim, + CopterScript::c_ips003d2_RunAnim, + CopterScript::c_ips005d2_RunAnim, + CopterScript::c_ips004d2_RunAnim, + CopterScript::c_ips004d2_RunAnim, + CopterScript::c_ipsxx1d2_RunAnim}, + {RacecarScript::c_irt001d1_RunAnim, + RacecarScript::c_irt002d1_RunAnim, + RacecarScript::c_irt003d1_RunAnim, + RacecarScript::c_irt004d1_RunAnim, + RacecarScript::c_irt005d1_RunAnim, + RacecarScript::c_irt004d1_RunAnim, + RacecarScript::c_irtxx4d1_RunAnim} +}; // GLOBAL: LEGO1 0x100d65a4 MxFloat LegoCarBuild::g_unk0x100d65a4 = -0.1f; @@ -44,7 +93,7 @@ LegoCarBuild::LegoCarBuild() { m_unk0x100 = 0; m_unk0x110 = 0; - m_unk0xf8 = 0xffffffff; + m_unk0xf8 = c_unknownminusone; m_unk0x2d4 = FALSE; m_unk0x258 = 0; m_ColorBook_Bitmap = NULL; @@ -72,10 +121,10 @@ LegoCarBuild::LegoCarBuild() m_buildState = NULL; m_unk0x104 = 0; m_unk0x109 = 0; - m_unk0x108 = 0; + m_numAnimsRun = 0; m_unk0x338 = 0; m_destLocation = LegoGameState::e_undefined; - m_unk0x344 = 0xffffffff; + m_unk0x344 = DS_NOT_A_STREAM; m_unk0x174 = 0; NotificationManager()->Register(this); } @@ -87,12 +136,27 @@ MxBool LegoCarBuild::VTable0x5c() return TRUE; } -// STUB: LEGO1 0x10022a80 -// STUB: BETA10 0x1006aea3 +// FUNCTION: LEGO1 0x10022a80 +// FUNCTION: BETA10 0x1006aea3 LegoCarBuild::~LegoCarBuild() { - // TODO - // ... + m_unk0x100 = 0; + m_unk0x110 = NULL; + + if (m_unk0x258) { + m_unk0x258->SetUnknown0xbc(0); + m_unk0x258->SetTickleState(MxPresenter::e_idle); + m_unk0x258 = NULL; + } + + ControlManager()->Unregister(this); + TickleManager()->UnregisterClient(this); + + if (InputManager()->GetWorld() == this) { + InputManager()->ClearWorld(); + } + + InputManager()->UnRegister(this); NotificationManager()->Unregister(this); } @@ -116,23 +180,23 @@ MxResult LegoCarBuild::Create(MxDSAction& p_dsAction) if (m_atomId == *g_copterScript) { buildStateClassName = "LegoCopterBuildState"; - GameState()->SetCurrentArea(LegoGameState::e_copterbuild); - m_unk0x330 = 1; + GameState()->m_currentArea = LegoGameState::e_copterbuild; + m_carId = Helicopter_Actor; } else if (m_atomId == *g_dunecarScript) { buildStateClassName = "LegoDuneCarBuildState"; - GameState()->SetCurrentArea(LegoGameState::e_dunecarbuild); - m_unk0x330 = 2; + GameState()->m_currentArea = LegoGameState::e_dunecarbuild; + m_carId = DuneBugy_Actor; } else if (m_atomId == *g_jetskiScript) { buildStateClassName = "LegoJetskiBuildState"; - GameState()->SetCurrentArea(LegoGameState::e_jetskibuild); - m_unk0x330 = 3; + GameState()->m_currentArea = LegoGameState::e_jetskibuild; + m_carId = Jetski_Actor; } else if (m_atomId == *g_racecarScript) { buildStateClassName = "LegoRaceCarBuildState"; - GameState()->SetCurrentArea(LegoGameState::e_racecarbuild); - m_unk0x330 = 4; + GameState()->m_currentArea = LegoGameState::e_racecarbuild; + m_carId = Helicopter_Actor; } LegoGameState* gameState = GameState(); @@ -409,7 +473,7 @@ MxResult LegoCarBuild::Tickle() return SUCCESS; } - if (m_unk0xf8 == 8) { + if (m_unk0xf8 == c_unknown8) { if (m_unk0xfc == 1) { FUN_10024f50(); } @@ -429,7 +493,7 @@ MxResult LegoCarBuild::Tickle() DWORD time = timeGetTime(); DWORD dTime = (time - m_unk0x10c) / 100; - if (m_unk0x330 == 4) { + if (m_carId == Helicopter_Actor) { switch (m_unk0x10a) { // TODO: Work out constants case 500: @@ -452,7 +516,7 @@ MxResult LegoCarBuild::Tickle() return SUCCESS; } } - else if (m_unk0x330 == 3) { + else if (m_carId == Jetski_Actor) { switch (m_unk0x10a) { case 500: LEGOCARBUILD_TICKLE_CASE(291, 291, 311, "Exit_Ctl") @@ -473,7 +537,7 @@ MxResult LegoCarBuild::Tickle() // return SUCCESS; } } - else if (m_unk0x330 == 2) { + else if (m_carId == DuneBugy_Actor) { switch (m_unk0x10a) { case 500: LEGOCARBUILD_TICKLE_CASE(155, 155, 175, "Exit_Ctl") @@ -490,7 +554,7 @@ MxResult LegoCarBuild::Tickle() return SUCCESS; } } - else if (m_unk0x330 == 1) { + else if (m_carId == Helicopter_Actor) { switch (m_unk0x10a) { case 500: LEGOCARBUILD_TICKLE_CASE(185, 185, 205, "Exit_Ctl") @@ -575,7 +639,7 @@ MxLong LegoCarBuild::Notify(MxParam& p_param) break; case c_notificationControl: - result = FUN_10024890((LegoEventNotificationParam*) &p_param); + result = FUN_10024890(&p_param); if (result == 1) { m_unk0x109 = 0; @@ -583,8 +647,8 @@ MxLong LegoCarBuild::Notify(MxParam& p_param) break; case c_notificationEndAnim: - if (m_unk0x108 > 0) { - m_unk0x108 -= 1; + if (m_numAnimsRun > 0) { + m_numAnimsRun -= 1; } FUN_10025e40(); @@ -605,7 +669,7 @@ MxLong LegoCarBuild::Notify(MxParam& p_param) undefined4 LegoCarBuild::FUN_10024250(LegoEventNotificationParam* p_param) { if (p_param->GetKey() == ' ' && m_buildState->m_animationState != 4 && m_buildState->m_animationState != 2) { - if (m_unk0x108 > 0) { + if (m_numAnimsRun > 0) { DeleteObjects(&m_atomId, 500, 0x1fe); BackgroundAudioManager()->RaiseVolume(); m_unk0x109 = 0; @@ -624,7 +688,7 @@ void LegoCarBuild::ReadyWorld() InitPresenters(); if (BackgroundAudioManager()->GetEnabled()) { - InvokeAction(Extra::ActionType::e_start, *g_jukeboxScript, FUN_10025ee0(m_unk0x330), NULL); + InvokeAction(Extra::ActionType::e_start, *g_jukeboxScript, FUN_10025ee0(m_carId), NULL); m_buildState->m_animationState = LegoVehicleBuildState::e_unknown2; NotificationManager()->Send(this, MxNotificationParam()); } @@ -636,8 +700,8 @@ void LegoCarBuild::ReadyWorld() // FUNCTION: LEGO1 0x100243a0 void LegoCarBuild::FUN_100243a0() { - switch (m_unk0x330) { - case 1: + switch (m_carId) { + case Helicopter_Actor: if (GameState()->GetCurrentAct() == LegoGameState::Act::e_act2) { m_destLocation = LegoGameState::Area::e_act3script; TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE); @@ -648,15 +712,15 @@ void LegoCarBuild::FUN_100243a0() TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE); break; } - case 2: + case DuneBugy_Actor: m_destLocation = LegoGameState::Area::e_garadoor; TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE); break; - case 3: + case Jetski_Actor: m_destLocation = LegoGameState::Area::e_unk17; TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE); break; - case 4: + case RaceCar_Actor: m_destLocation = LegoGameState::Area::e_unk20; TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE); } @@ -771,14 +835,207 @@ MxS32 LegoCarBuild::FUN_10024850(MxLong p_x, MxLong p_y) return result; } -// STUB: LEGO1 0x10024890 -// STUB: BETA10 0x1006d512 -undefined4 LegoCarBuild::FUN_10024890(LegoEventNotificationParam* p_param) +#ifdef NDEBUG + +// FUNCTION: LEGO1 0x10024890 +undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) { - // TODO - return 0; + undefined4 result = 0; + LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param; + assert(m_buildState); + + if (param->m_unk0x28) { + switch (param->m_clickedObjectId) { + // The enum values are all identical between CopterScript, DunecarScript, JetskiScript, and RacecarScript + case CopterScript::c_Info_Ctl: + if (m_buildState->m_animationState != LegoVehicleBuildState::e_unknown4 && + m_buildState->m_animationState != LegoVehicleBuildState::e_unknown2 && + m_buildState->m_animationState != LegoVehicleBuildState::e_exiting && + GameState()->GetCurrentAct() != LegoGameState::e_act2) { + if (m_numAnimsRun > 0) { + DeleteObjects(&m_atomId, 500, 510); + } + + m_unk0x258->SetUnknown0xbc(0); + m_destLocation = LegoGameState::e_infomain; + TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); + result = 1; + } + + break; + case CopterScript::c_Exit_Ctl: + if (m_buildState->m_animationState != LegoVehicleBuildState::e_exiting && + m_buildState->m_animationState != LegoVehicleBuildState::e_unknown4) { + if (m_numAnimsRun > 0) { + DeleteObjects(&m_atomId, 500, 510); + } + + m_unk0x258->SetUnknown0xbc(0); + + if (GameState()->GetCurrentAct() == LegoGameState::e_act2) { + FUN_100243a0(); + } + else if (m_unk0x258->AllPartsPlaced() || m_buildState->m_unk0x4d) { + m_buildState->m_unk0x4d = TRUE; + InvokeAction(Extra::e_start, m_atomId, m_carId, NULL); + + NotificationManager()->Send(this, MxNotificationParam()); + + m_buildState->m_animationState = LegoVehicleBuildState::e_unknown4; + } + else { + FUN_10025720(4); + m_buildState->m_animationState = LegoVehicleBuildState::e_exiting; + } + + result = 1; + } + break; + case CopterScript::c_ShelfUp_Ctl: + FUN_10024f30(); + m_Shelf_Sound->Enable(FALSE); + m_Shelf_Sound->Enable(TRUE); + result = 1; + break; + case CopterScript::c_Platform_Ctl: + FUN_10024f50(); + m_unk0xf8 = c_unknown8; + m_unk0xfc = param->m_unk0x28; + result = 1; + break; + default: + if ((m_Decals_Ctl && m_Decals_Ctl->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl1 && m_Decals_Ctl1->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl2 && m_Decals_Ctl2->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl3 && m_Decals_Ctl3->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl4 && m_Decals_Ctl4->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl5 && m_Decals_Ctl5->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl6 && m_Decals_Ctl6->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl7 && m_Decals_Ctl7->GetAction()->GetObjectId() == param->m_clickedObjectId)) { + m_unk0x258->SetPartObjectIdByName(m_unk0x110->GetName(), param->m_clickedObjectId); + m_Decal_Sound->Enable(FALSE); + m_Decal_Sound->Enable(TRUE); + } + else { + FUN_10025350(param->m_clickedObjectId); + } + + result = 1; + } + } + else { + m_unk0xf8 = c_unknownminusone; + m_unk0xfc = -1; + } + + // It is a bit unexpected that LEGO1 and BETA10 match so well with the `return 1` + // and ignoring the `result` variable, but the match is hard to argue with + return 1; } +#else + +// FUNCTION: BETA10 0x1006d512 +undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) +{ + undefined4 result = 0; + LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param; + assert(m_buildState); + + if (param->m_unk0x28) { + switch (param->m_clickedObjectId) { + case CopterScript::c_Info_Ctl: + m_unk0x258->SetUnknown0xbc(0); + m_destLocation = LegoGameState::e_infomain; + TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); + result = 1; + break; + case CopterScript::c_Exit_Ctl: + if (m_buildState->m_animationState != LegoVehicleBuildState::e_exiting) { + m_unk0x258->SetUnknown0xbc(0); + + if (m_unk0x258->AllPartsPlaced() || m_buildState->m_unk0x4d) { + m_buildState->m_unk0x4d = TRUE; + + // GameState()->GetCurrentAct() returns an MxS16 in BETA10 + if (GameState()->GetCurrentAct() == 0) { + InvokeAction(Extra::e_start, m_atomId, m_carId, NULL); + + NotificationManager()->Send(this, MxNotificationParam()); + + assert(m_buildState); + m_buildState->m_animationState = LegoVehicleBuildState::e_unknown4; + } + + else { + FUN_10025720(5); + m_buildState->m_animationState = LegoVehicleBuildState::e_exiting; + } + } + else { + FUN_10025720(4); + m_buildState->m_animationState = LegoVehicleBuildState::e_exiting; + } + + switch (GameState()->m_currentArea) { + case LegoGameState::e_copterbuild: + assert(m_carId == Helicopter_Actor); + break; + case LegoGameState::e_dunecarbuild: + assert(m_carId == DuneBugy_Actor); + break; + case LegoGameState::e_jetskibuild: + assert(m_carId == Jetski_Actor); + break; + case LegoGameState::e_racecarbuild: + assert(m_carId == RaceCar_Actor); + break; + } + + result = 1; + } + break; + case CopterScript::c_ShelfUp_Ctl: + FUN_10024f30(); + m_Shelf_Sound->Enable(FALSE); + m_Shelf_Sound->Enable(TRUE); + result = 1; + break; + case CopterScript::c_Platform_Ctl: + FUN_10024f50(); + m_unk0xf8 = c_unknown8; + m_unk0xfc = param->m_unk0x28; + result = 1; + break; + default: + if ((m_Decals_Ctl && m_Decals_Ctl->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl1 && m_Decals_Ctl1->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl2 && m_Decals_Ctl2->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl3 && m_Decals_Ctl3->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl4 && m_Decals_Ctl4->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl5 && m_Decals_Ctl5->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl6 && m_Decals_Ctl6->GetAction()->GetObjectId() == param->m_clickedObjectId) || + (m_Decals_Ctl7 && m_Decals_Ctl7->GetAction()->GetObjectId() == param->m_clickedObjectId)) { + m_unk0x258->SetPartObjectIdByName(m_unk0x110->GetName(), param->m_clickedObjectId); + m_Decal_Sound->Enable(FALSE); + m_Decal_Sound->Enable(TRUE); + } + else { + FUN_10025350(param->m_clickedObjectId); + } + result = 1; + } + } + else { + m_unk0xf8 = c_unknownminusone; + m_unk0xfc = -1; + } + + return 1; +} + +#endif + // FUNCTION: LEGO1 0x10024c20 // FUNCTION: BETA10 0x1006db21 undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param) @@ -788,25 +1045,25 @@ undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param) switch (m_buildState->m_animationState) { case 4: - entity = (LegoEntity*) Find(m_atomId, m_unk0x330); + entity = (LegoEntity*) Find(m_atomId, m_carId); if (entity && entity->GetROI()) { // This function was changed between BETA10 and LEGO1. // These lines looks like a relic from older code. LegoWorld* destWorld = NULL; - destWorld = FindWorld(*g_isleScript, 0); + destWorld = FindWorld(*g_isleScript, IsleScript::c__Isle); Act1State* gameState = (Act1State*) GameState()->GetState("Act1State"); - switch (GameState()->GetCurrentArea()) { + switch (GameState()->m_currentArea) { case LegoGameState::e_copterbuild: if (gameState->m_helicopter) { delete gameState->m_helicopter; } gameState->m_helicopter = (Helicopter*) entity; - gameState->m_unk0x108.SetName(""); + gameState->m_helicopterPlane.SetName(""); break; case LegoGameState::e_dunecarbuild: if (gameState->m_dunebuggy) { @@ -814,7 +1071,7 @@ undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param) } gameState->m_dunebuggy = (DuneBuggy*) entity; - gameState->m_unk0x1bc.SetName(""); + gameState->m_dunebuggyPlane.SetName(""); break; case LegoGameState::e_jetskibuild: if (gameState->m_jetski) { @@ -822,7 +1079,7 @@ undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param) } gameState->m_jetski = (Jetski*) entity; - gameState->m_unk0x164.SetName(""); + gameState->m_jetskiPlane.SetName(""); break; case LegoGameState::e_racecarbuild: if (gameState->m_racecar) { @@ -830,14 +1087,14 @@ undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param) } gameState->m_racecar = (RaceCar*) entity; - gameState->m_unk0x210.SetName(""); + gameState->m_racecarPlane.SetName(""); break; } assert(destWorld); m_buildState->m_animationState = LegoVehicleBuildState::e_exiting; - if (m_unk0x258->m_numberOfParts != m_unk0x258->m_placedPartCount) { + if (m_unk0x258->AllPartsPlaced()) { FUN_100243a0(); } else { @@ -852,17 +1109,17 @@ undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param) case 2: MxU32 jukeboxScript; - switch (m_unk0x330) { - case 1: + switch (m_carId) { + case Helicopter_Actor: jukeboxScript = JukeboxScript::c_HelicopterBuild_Music; break; - case 2: + case DuneBugy_Actor: jukeboxScript = JukeboxScript::c_DuneCarBuild_Music; break; - case 3: + case Jetski_Actor: jukeboxScript = JukeboxScript::c_JetskiBuild_Music; break; - case 4: + case RaceCar_Actor: jukeboxScript = JukeboxScript::c_RaceCarBuild_Music; } @@ -893,6 +1150,14 @@ void LegoCarBuild::FUN_10024ef0() FUN_10015820(FALSE, 7); } +// FUNCTION: LEGO1 0x10024f30 +// FUNCTION: BETA10 0x1006dfa0 +void LegoCarBuild::FUN_10024f30() +{ + FUN_10022f30(); + m_unk0x258->SetUnknown0xbc(2); +} + // FUNCTION: LEGO1 0x10024f50 // FUNCTION: BETA10 0x1006dfce void LegoCarBuild::FUN_10024f50() @@ -973,11 +1238,95 @@ void LegoCarBuild::FUN_100250e0(MxBool p_enabled) } } -// STUB: LEGO1 0x10025450 -// STUB: BETA10 0x1006e599 +// FUNCTION: LEGO1 0x10025350 +// FUNCTION: BETA10 0x1006e3c0 +void LegoCarBuild::FUN_10025350(MxS32 p_objectId) +{ + const LegoChar* color; + LegoChar buffer[256]; + + if (!m_unk0x110) { + return; + } + + if (m_Yellow_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego yellow"; + } + else if (m_Red_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego red"; + } + else if (m_Blue_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego blue"; + } + else if (m_Green_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego green"; + } + else if (m_Gray_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego white"; + } + else if (m_Black_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego black"; + } + else { + return; + } + + m_Paint_Sound->Enable(FALSE); + m_Paint_Sound->Enable(TRUE); + m_unk0x110->FUN_100a93b0(color); + sprintf(buffer, "c_%s", m_unk0x110->GetName()); + VariableTable()->SetVariable(buffer, color); +} + +// FUNCTION: LEGO1 0x10025450 +// FUNCTION: BETA10 0x1006e599 void LegoCarBuild::FUN_10025450() { - // TODO + m_unk0x12c = m_unk0x110->GetLocal2World(); + m_unk0x1c0 = m_unk0x12c; + + Vector3 lastColumnOfUnk0x1c0(m_unk0x1c0[3]); + lastColumnOfUnk0x1c0 = Vector3(m_unk0x258->GetUnknown0xe0()[3]); + + // This looks odd, but it improves the LEGO1 match while breaking the BETA10 match. + // I don't know whether this is due to compiler entropy. + // Feel free to replace unk0x178 -> m_unk0x178 and remove this variable if it improves the LEGO1 match + // in the future. + MxMatrix* unk0x178 = &m_unk0x178; + *unk0x178 = m_unk0x12c; + + if (m_unk0x258->PartIsPlaced(m_unk0x110->GetName())) { + m_unk0x2a4 = Vector4(m_unk0x110->GetWorldPosition()); + + if (!m_unk0x2d4) { + m_unk0x2bc = m_unk0x2a4; + + m_unk0x208 = m_unk0x12c; + m_unk0x2a4[0] += m_unk0x1c0[3][0] - m_unk0x208[3][0]; + m_unk0x2a4[1] += m_unk0x1c0[3][1] - m_unk0x208[3][1]; + m_unk0x2a4[2] += m_unk0x1c0[3][2] - m_unk0x208[3][2]; + } + + *unk0x178 = m_unk0x1c0; + } + else { + const LegoChar* wiredName; + + if (!m_unk0x258->FUN_10079c30(m_unk0x110->GetName())) { + wiredName = m_unk0x258->GetWiredNameByPartName(m_unk0x110->GetName()); + } + else { + wiredName = m_unk0x258->GetWiredNameOfLastPlacedPart(); + } + + LegoROI* parentROI = (LegoROI*) m_unk0x110->GetParentROI(); + m_unk0x208 = parentROI->FindChildROI(wiredName, parentROI)->GetLocal2World(); + m_unk0x2bc = Vector4(parentROI->FindChildROI(wiredName, parentROI)->GetWorldPosition()); + m_unk0x2a4 = Vector4(m_unk0x110->GetWorldPosition()); + + m_unk0x2a4[2] += (m_unk0x1c0[3][2] - m_unk0x12c[3][2]); + m_unk0x178[3][2] = m_unk0x1c0[3][2]; + } } // FUNCTION: LEGO1 0x100256c0 @@ -998,11 +1347,172 @@ void LegoCarBuild::Enable(MxBool p_enable) } } -// STUB: LEGO1 0x10025720 -undefined4 LegoCarBuild::FUN_10025720(undefined4 p_param1) +// FUNCTION: BETA10 0x10070520 +inline MxU32 LegoCarBuild::Beta0x10070520() { - // TODO - return 0; + switch (m_carId) { + case Helicopter_Actor: + return 2; + case DuneBugy_Actor: + return 0; + case Jetski_Actor: + return 1; + case RaceCar_Actor: + return 3; + default: + assert(0); + return 0; + } +} + +inline void LegoCarBuild::StopActionIn0x344() +{ + // There is no direct evidence for this inline function in LEGO1, + // but some code doesn't make much sense otherwise. For example, + // sometimes `m_unk0x344` is set to another value right below this call, + // which the original developer would likely have refactored. + if (m_unk0x344 != DS_NOT_A_STREAM) { + InvokeAction(Extra::ActionType::e_stop, m_atomId, m_unk0x344, NULL); + m_unk0x344 = DS_NOT_A_STREAM; + } +} + +// FUNCTION: LEGO1 0x10025720 +// FUNCTION: BETA10 0x1006e9df +void LegoCarBuild::FUN_10025720(undefined4 p_param) +{ + m_numAnimsRun++; + m_unk0x10a = 0; + MxS32 uVar6; + +#ifdef NDEBUG + + if (GameState()->GetCurrentAct() == LegoGameState::e_act2) { + // This is most likely related to the helicopter rebuild in Act 2 + switch (p_param) { + case 0: + case 1: + case 2: + case 3: + switch (rand() % 3) { + case 0: + m_unk0x10a = CopterScript::c_ips004d2_RunAnim; + StopActionIn0x344(); + m_unk0x344 = CopterScript::c_ips004d2_RunAnim; + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::ActionType::e_start, m_atomId, CopterScript::c_ips004d2_RunAnim, NULL); + break; + case 1: + m_unk0x10a = CopterScript::c_ips006d2_RunAnim; + StopActionIn0x344(); + m_unk0x344 = CopterScript::c_ips006d2_RunAnim; + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::ActionType::e_start, m_atomId, CopterScript::c_ips006d2_RunAnim, NULL); + break; + case 2: + m_unk0x10a = CopterScript::c_slp01xd2_RunAnim; + StopActionIn0x344(); + m_unk0x344 = CopterScript::c_slp01xd2_RunAnim; + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::ActionType::e_start, m_atomId, CopterScript::c_slp01xd2_RunAnim, NULL); + break; + } + break; + case 4: + FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x04); + break; + case 5: + FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x08); + break; + case 6: + m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x18; + uVar6 = m_unk0x10a; + StopActionIn0x344(); + + if (uVar6 != DS_NOT_A_STREAM) { + m_unk0x344 = uVar6; + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::ActionType::e_start, m_atomId, uVar6, NULL); + } + + break; + default: + m_numAnimsRun--; + return; + } + } + else { +#endif + // This part doesn't match BETA10 perfectly, but it's the closest we get without hundreds of #ifdef's + switch (p_param) { + case 0: + m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x00; + FUN_10025d10(m_unk0x10a); + break; + case 1: + m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x0c; + FUN_10025d10(m_unk0x10a); + + if (m_carId == 2) { + m_unk0x10a = 0; + } + + break; + case 2: + m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x10; + FUN_10025d10(m_unk0x10a); + + if (m_carId != 3) { + m_unk0x10a = 0; + } + + break; + case 3: + FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x14); + break; + case 4: + FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x04); + break; + case 5: + FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x08); + break; + case 6: + m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x18; + FUN_10025d10(m_unk0x10a); + break; + default: + assert(0); + m_numAnimsRun--; + + // Weird: This assertion can never be executed. The `assert(0)` above was probably introduced later. + assert(m_numAnimsRun >= 0); + return; + } +#ifdef NDEBUG + } +#endif + + if (m_unk0x10a != 0) { + m_unk0x10c = timeGetTime(); + } +} + +// FUNCTION: LEGO1 0x10025d10 +// FUNCTION: BETA10 0x10070490 +void LegoCarBuild::FUN_10025d10(MxS32 p_param) +{ + // this function has a different signature and partially different body in BETA10, but it is called in the same + // places + if (m_unk0x344 != DS_NOT_A_STREAM) { + InvokeAction(Extra::ActionType::e_stop, m_atomId, m_unk0x344, NULL); + m_unk0x344 = DS_NOT_A_STREAM; + } + + if (p_param != DS_NOT_A_STREAM) { + m_unk0x344 = p_param; + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::ActionType::e_start, m_atomId, p_param, NULL); + } } // FUNCTION: LEGO1 0x10025d70 @@ -1057,7 +1567,7 @@ void LegoCarBuild::FUN_10025e40() MxBool LegoCarBuild::Escape() { BackgroundAudioManager()->Init(); - MxS32 targetEntityId = FUN_10025ee0(m_unk0x330); + MxS32 targetEntityId = FUN_10025ee0(m_carId); InvokeAction(Extra::ActionType::e_stop, *g_jukeboxScript, targetEntityId, NULL); DeleteObjects(&m_atomId, 500, 999); diff --git a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp index 28cfbc53..546aac67 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp @@ -627,6 +627,31 @@ MxBool LegoCarBuildAnimPresenter::StringEndsOnZero(const LegoChar* p_string) return (p_string[strlen(p_string) - 2] != '0'); } +// FUNCTION: LEGO1 0x10079d60 +// FUNCTION: BETA10 0x1007284c +const LegoChar* LegoCarBuildAnimPresenter::GetWiredNameByPartName(const LegoChar* p_name) +{ + for (MxS16 i = 0; i < m_numberOfParts; i++) { + if (strcmpi(p_name, m_parts[i].m_name) == 0) { + return m_parts[i].m_wiredName; + } + } + + return NULL; +} + +// FUNCTION: LEGO1 0x10079dc0 +// FUNCTION: BETA10 0x100728d1 +void LegoCarBuildAnimPresenter::SetPartObjectIdByName(const LegoChar* p_name, MxS16 p_objectId) +{ + for (MxS16 i = 0; i < m_numberOfParts; i++) { + if (strcmpi(p_name, m_parts[i].m_name) == 0) { + m_parts[i].m_objectId = p_objectId; + return; + } + } +} + // FUNCTION: LEGO1 0x10079e20 // FUNCTION: BETA10 0x10072959 const BoundingSphere& LegoCarBuildAnimPresenter::FUN_10079e20() diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index fa42d032..9d34a28b 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -383,7 +383,7 @@ void LegoAnimationManager::Reset(MxBool p_und) m_unk0x402 = FALSE; if (p_und && m_animState != NULL) { - m_animState->SetFlag(); + m_animState->Reset(); } MxBool suspended = m_suspended; @@ -1108,7 +1108,7 @@ MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEnt // FUNCTION: LEGO1 0x10060dc0 // FUNCTION: BETA10 0x10041f2c MxResult LegoAnimationManager::FUN_10060dc0( - IsleScript::Script p_objectId, + MxU32 p_objectId, MxMatrix* p_matrix, MxBool p_param3, MxBool p_param4, @@ -2951,7 +2951,7 @@ MxResult AnimState::Serialize(LegoFile* p_file) } // FUNCTION: LEGO1 0x100654f0 -MxBool AnimState::SetFlag() +MxBool AnimState::Reset() { if (m_unk0x10 != NULL) { m_extraCharacterId = 0; diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index a4001bc2..882cc944 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -302,7 +302,7 @@ MxResult LegoGameState::DeleteState() m_stateArray = NULL; for (MxS32 count = 0; count < stateCount; count++) { - if (!stateArray[count]->SetFlag() && stateArray[count]->IsSerializable()) { + if (!stateArray[count]->Reset() && stateArray[count]->IsSerializable()) { delete stateArray[count]; } else { @@ -780,7 +780,7 @@ void LegoGameState::StopArea(Area p_area) inline void LoadIsle() { - LegoWorld* world = FindWorld(*g_isleScript, 0); + LegoWorld* world = FindWorld(*g_isleScript, IsleScript::c__Isle); if (world != NULL) { if (!world->GetUnknown0xd0Empty()) { NotificationManager()->Send(world, MxNotificationParam(c_notificationType20, NULL)); @@ -957,7 +957,7 @@ void LegoGameState::SwitchArea(Area p_area) InvokeAction(Extra::ActionType::e_opendisk, *g_racecarScript, RacecarScript::c__StartUp, NULL); break; case e_act2main: { - LegoWorld* act2main = FindWorld(*g_act2mainScript, 0); + LegoWorld* act2main = FindWorld(*g_act2mainScript, Act2mainScript::c__Act2Main); if (act2main == NULL) { InvokeAction(Extra::ActionType::e_opendisk, *g_act2mainScript, Act2mainScript::c__Act2Main, NULL); @@ -969,7 +969,7 @@ void LegoGameState::SwitchArea(Area p_area) break; } case e_act3script: { - LegoWorld* act3 = FindWorld(*g_act3Script, 0); + LegoWorld* act3 = FindWorld(*g_act3Script, Act3Script::c__Act3); if (act3 == NULL) { InvokeAction(Extra::ActionType::e_opendisk, *g_act3Script, Act3Script::c__Act3, NULL); @@ -1105,7 +1105,7 @@ void LegoGameState::Init() SetCurrentAct(e_act1); if (m_loadedAct == e_act1) { - Isle* isle = (Isle*) FindWorld(*g_isleScript, 0); + Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle); Helicopter* copter = (Helicopter*) isle->Find(*g_copterScript, CopterScript::c_Helicopter_Actor); if (copter) { @@ -1215,13 +1215,13 @@ void LegoGameState::SetCurrentAct(Act p_currentAct) // FUNCTION: LEGO1 0x1003ceb0 void LegoGameState::FindLoadedAct() { - if (FindWorld(*g_isleScript, 0)) { + if (FindWorld(*g_isleScript, IsleScript::c__Isle)) { m_loadedAct = e_act1; } - else if (FindWorld(*g_act2mainScript, 0)) { + else if (FindWorld(*g_act2mainScript, Act2mainScript::c__Act2Main)) { m_loadedAct = e_act2; } - else if (FindWorld(*g_act3Script, 0)) { + else if (FindWorld(*g_act3Script, Act3Script::c__Act3)) { m_loadedAct = e_act3; } else { diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index 73ffec1a..d96931b1 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -3,6 +3,7 @@ #include "3dmanager/lego3dmanager.h" #include "anim/legoanim.h" #include "isle.h" +#include "isle_actions.h" #include "islepathactor.h" #include "legoanimationmanager.h" #include "legoanimpresenter.h" @@ -239,24 +240,31 @@ MxBool CheckIfEntityExists(MxBool p_enable, const char* p_filename, MxS32 p_enti void NotifyEntity(const char* p_filename, MxS32 p_entityId, LegoEntity* p_sender); // FUNCTION: LEGO1 0x1003e430 -void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_targetEntityId, LegoEntity* p_sender) +// FUNCTION: BETA10 0x100d3fda +void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_streamId, LegoEntity* p_sender) { MxDSAction action; action.SetAtomId(p_pAtom); - action.SetObjectId(p_targetEntityId); + action.SetObjectId(p_streamId); switch (p_actionId) { case Extra::ActionType::e_opendisk: - if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) { + assert(p_streamId != DS_NOT_A_STREAM); + + if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId)) { Streamer()->Open(p_pAtom.GetInternal(), MxStreamer::e_diskStream); Start(&action); } + break; case Extra::ActionType::e_openram: - if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) { + assert(p_streamId != DS_NOT_A_STREAM); + + if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId)) { Streamer()->Open(p_pAtom.GetInternal(), MxStreamer::e_RAMStream); Start(&action); } + break; case Extra::ActionType::e_close: action.SetUnknown24(-2); @@ -264,35 +272,47 @@ void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p Streamer()->Close(p_pAtom.GetInternal()); break; case Extra::ActionType::e_start: - if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) { + assert(p_streamId != DS_NOT_A_STREAM); + + if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId)) { Start(&action); } + break; case Extra::ActionType::e_stop: + assert(p_streamId != DS_NOT_A_STREAM); action.SetUnknown24(-2); - if (!RemoveFromCurrentWorld(p_pAtom, p_targetEntityId)) { + + if (!RemoveFromCurrentWorld(p_pAtom, p_streamId)) { DeleteObject(action); } + break; case Extra::ActionType::e_run: _spawnl(0, "\\lego\\sources\\main\\main.exe", "\\lego\\sources\\main\\main.exe", "/script", &p_pAtom, 0); break; + case Extra::ActionType::e_enable: + assert(p_streamId != DS_NOT_A_STREAM); + CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId); + break; + case Extra::ActionType::e_disable: + assert(p_streamId != DS_NOT_A_STREAM); + CheckIfEntityExists(FALSE, p_pAtom.GetInternal(), p_streamId); + break; case Extra::ActionType::e_exit: Lego()->SetExit(TRUE); break; - case Extra::ActionType::e_enable: - CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId); - break; - case Extra::ActionType::e_disable: - CheckIfEntityExists(FALSE, p_pAtom.GetInternal(), p_targetEntityId); - break; case Extra::ActionType::e_notify: - NotifyEntity(p_pAtom.GetInternal(), p_targetEntityId, p_sender); + assert(p_streamId != DS_NOT_A_STREAM); + NotifyEntity(p_pAtom.GetInternal(), p_streamId, p_sender); break; + default: + assert("Invalid Action Control" == NULL); } } // FUNCTION: LEGO1 0x1003e670 +// FUNCTION: BETA10 0x100d43f2 MxBool CheckIfEntityExists(MxBool p_enable, const char* p_filename, MxS32 p_entityId) { LegoWorld* world = FindWorld(MxAtomId(p_filename, e_lowerCase2), p_entityId); @@ -307,6 +327,7 @@ MxBool CheckIfEntityExists(MxBool p_enable, const char* p_filename, MxS32 p_enti } // FUNCTION: LEGO1 0x1003e700 +// FUNCTION: BETA10 0x100d448a void NotifyEntity(const char* p_filename, MxS32 p_entityId, LegoEntity* p_sender) { MxAtomId atom(p_filename, e_lowerCase2); @@ -333,7 +354,7 @@ void NotifyEntity(const char* p_filename, MxS32 p_entityId, LegoEntity* p_sender // FUNCTION: LEGO1 0x1003eab0 void SetCameraControllerFromIsle() { - InputManager()->SetCamera(FindWorld(*g_isleScript, 0)->GetCamera()); + InputManager()->SetCamera(FindWorld(*g_isleScript, IsleScript::c__Isle)->GetCamera()); } // FUNCTION: LEGO1 0x1003eae0 @@ -443,6 +464,7 @@ void FUN_1003eda0() } // FUNCTION: LEGO1 0x1003ee00 +// FUNCTION: BETA10 0x100d4c6f MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id) { LegoWorld* world = CurrentWorld(); diff --git a/LEGO1/lego/legoomni/src/common/misc.cpp b/LEGO1/lego/legoomni/src/common/misc.cpp index f9c78e5d..6c01313f 100644 --- a/LEGO1/lego/legoomni/src/common/misc.cpp +++ b/LEGO1/lego/legoomni/src/common/misc.cpp @@ -33,8 +33,10 @@ LegoVideoManager* VideoManager() } // FUNCTION: LEGO1 0x10015730 +// FUNCTION: BETA10 0x100e484e MxBackgroundAudioManager* BackgroundAudioManager() { + assert(LegoOmni::GetInstance()); return LegoOmni::GetInstance()->GetBackgroundAudioManager(); } @@ -188,8 +190,10 @@ void SetCurrentWorld(LegoWorld* p_world) } // FUNCTION: LEGO1 0x10015900 +// FUNCTION: BETA10 0x100e4f02 MxTransitionManager* TransitionManager() { + assert(LegoOmni::GetInstance()); return LegoOmni::GetInstance()->GetTransitionManager(); } diff --git a/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp b/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp index bb252592..566468e5 100644 --- a/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp @@ -21,7 +21,7 @@ RECT g_fullScreenRect = {0, 0, 640, 480}; MxTransitionManager::MxTransitionManager() { m_animationTimer = 0; - m_transitionType = e_notTransitioning; + m_mode = e_idle; m_ddSurface = NULL; m_waitIndicator = NULL; m_copyBuffer = NULL; @@ -47,20 +47,20 @@ MxTransitionManager::~MxTransitionManager() MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 { LegoVideoManager* videoManager = VideoManager(); - this->m_ddSurface = videoManager->GetDisplaySurface()->GetDirectDrawSurface2(); + m_ddSurface = videoManager->GetDisplaySurface()->GetDirectDrawSurface2(); return SUCCESS; } // FUNCTION: LEGO1 0x1004bac0 MxResult MxTransitionManager::Tickle() { - if (this->m_animationSpeed + this->m_systemTime > timeGetTime()) { + if (m_animationSpeed + m_systemTime > timeGetTime()) { return SUCCESS; } - this->m_systemTime = timeGetTime(); + m_systemTime = timeGetTime(); - switch (this->m_transitionType) { + switch (m_mode) { case e_noAnimation: NoTransition(); break; @@ -84,6 +84,7 @@ MxResult MxTransitionManager::Tickle() } // FUNCTION: LEGO1 0x1004bb70 +// FUNCTION: BETA10 0x100ec4c1 MxResult MxTransitionManager::StartTransition( TransitionType p_animationType, MxS32 p_speed, @@ -91,13 +92,15 @@ MxResult MxTransitionManager::StartTransition( MxBool p_playMusicInAnim ) { - if (this->m_transitionType == e_notTransitioning) { + assert(m_mode == e_idle); + + if (m_mode == e_idle) { if (!p_playMusicInAnim) { MxBackgroundAudioManager* backgroundAudioManager = BackgroundAudioManager(); backgroundAudioManager->Stop(); } - this->m_transitionType = p_animationType; + m_mode = p_animationType; m_copyFlags.m_bit0 = p_doCopy; @@ -110,9 +113,9 @@ MxResult MxTransitionManager::StartTransition( } MxU32 time = timeGetTime(); - this->m_systemTime = time; + m_systemTime = time; - this->m_animationSpeed = p_speed; + m_animationSpeed = p_speed; MxTickleManager* tickleManager = TickleManager(); tickleManager->RegisterClient(this, p_speed); @@ -133,8 +136,8 @@ MxResult MxTransitionManager::StartTransition( // FUNCTION: LEGO1 0x1004bc30 void MxTransitionManager::EndTransition(MxBool p_notifyWorld) { - if (m_transitionType != e_notTransitioning) { - m_transitionType = e_notTransitioning; + if (m_mode != e_idle) { + m_mode = e_idle; m_copyFlags.m_bit0 = FALSE; diff --git a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp index b8125c50..f54fb548 100644 --- a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp +++ b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp @@ -45,6 +45,7 @@ void LegoControlManager::Register(MxCore* p_listener) } // FUNCTION: LEGO1 0x10028ea0 +// FUNCTION: BETA10 0x1007c330 void LegoControlManager::Unregister(MxCore* p_listener) { LegoNotifyListCursor cursor(&m_notifyList); diff --git a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp index a0fb6fa5..33162b11 100644 --- a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp +++ b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp @@ -276,6 +276,7 @@ void LegoInputManager::SetWorld(LegoWorld* p_world) } // FUNCTION: LEGO1 0x1005c730 +// FUNCTION: BETA10 0x100896dc void LegoInputManager::ClearWorld() { m_world = NULL; diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index e8aa7044..0479e05d 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -4,6 +4,7 @@ #include "geom/legounkown100db7f4.h" #include "legocachesoundmanager.h" #include "legocameracontroller.h" +#include "legonamedplane.h" #include "legonavcontroller.h" #include "legopathboundary.h" #include "legopathedgecontainer.h" @@ -718,3 +719,12 @@ void LegoPathActor::VTable0xa8() FUN_10010c30(); } } + +// FUNCTION: LEGO1 0x1002f770 +void LegoPathActor::UpdatePlane(LegoNamedPlane& p_namedPlane) +{ + p_namedPlane.SetName(m_boundary->GetName()); + p_namedPlane.SetPosition(GetWorldPosition()); + p_namedPlane.SetDirection(GetWorldDirection()); + p_namedPlane.SetUp(GetWorldUp()); +} diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index 9a41de96..5d9fbf1d 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -285,7 +285,7 @@ void LegoVideoManager::ToggleFPS(MxBool p_visible) MxResult LegoVideoManager::Tickle() { if (m_unk0x554 && !m_videoParam.Flags().GetFlipSurfaces() && - TransitionManager()->GetTransitionType() == MxTransitionManager::e_notTransitioning) { + TransitionManager()->GetTransitionType() == MxTransitionManager::e_idle) { Sleep(30); } diff --git a/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp b/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp index cfe25812..8fefddf4 100644 --- a/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp +++ b/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp @@ -45,7 +45,7 @@ MxResult ElevatorBottom::Create(MxDSAction& p_dsAction) SetIsWorldActive(FALSE); - GameState()->SetCurrentArea(LegoGameState::e_elevbott); + GameState()->m_currentArea = LegoGameState::e_elevbott; GameState()->StopArea(LegoGameState::e_previousArea); return result; diff --git a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp index 453b0862..ebdf7d4a 100644 --- a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp +++ b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp @@ -91,7 +91,7 @@ MxResult GasStation::Create(MxDSAction& p_dsAction) m_state->m_unk0x14.m_unk0x00 = 3; } - GameState()->SetCurrentArea(LegoGameState::e_garage); + GameState()->m_currentArea = LegoGameState::e_garage; GameState()->StopArea(LegoGameState::e_previousArea); InputManager()->Register(this); @@ -138,7 +138,7 @@ void GasStation::ReadyWorld() switch (m_currentActorId) { case LegoActor::c_pepper: - switch (m_state->m_unk0x18) { + switch (m_state->m_pepperAction) { case 0: m_state->m_unk0x14.m_unk0x00 = 5; PlayAction(GarageScript::c_wgs002nu_RunAnim); @@ -162,14 +162,14 @@ void GasStation::ReadyWorld() break; } - if (m_state->m_unk0x18 < 5) { - m_state->m_unk0x18++; + 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_unk0x1a) { + switch (m_state->m_mamaAction) { case 0: m_state->m_unk0x14.m_unk0x00 = 5; PlayAction(GarageScript::c_wgs006nu_RunAnim); @@ -188,14 +188,14 @@ void GasStation::ReadyWorld() break; } - if (m_state->m_unk0x1a < 5) { - m_state->m_unk0x1a++; + 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_unk0x1c) { + switch (m_state->m_papaAction) { case 0: m_state->m_unk0x14.m_unk0x00 = 5; PlayAction(GarageScript::c_wgs012nu_RunAnim); @@ -214,14 +214,14 @@ void GasStation::ReadyWorld() break; } - if (m_state->m_unk0x1c < 5) { - m_state->m_unk0x1c++; + 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_unk0x1e) { + switch (m_state->m_nickAction) { case 0: m_state->m_unk0x14.m_unk0x00 = 5; PlayAction(GarageScript::c_wgs009nu_RunAnim); @@ -240,14 +240,14 @@ void GasStation::ReadyWorld() break; } - if (m_state->m_unk0x1e < 5) { - m_state->m_unk0x1e++; + if (m_state->m_nickAction < 5) { + m_state->m_nickAction++; } FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); break; case LegoActor::c_laura: - switch (m_state->m_unk0x20) { + switch (m_state->m_lauraAction) { case 0: m_state->m_unk0x14.m_unk0x00 = 5; PlayAction(GarageScript::c_wgs020nu_RunAnim); @@ -266,8 +266,8 @@ void GasStation::ReadyWorld() break; } - if (m_state->m_unk0x20 < 5) { - m_state->m_unk0x20++; + if (m_state->m_lauraAction < 5) { + m_state->m_lauraAction++; } FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); @@ -288,7 +288,7 @@ inline void GasStation::PlayAction(GarageScript::Script p_objectId) BackgroundAudioManager()->LowerVolume(); Start(&action); - m_state->FUN_10006430(p_objectId); + m_state->PlayAction(p_objectId); } // FUNCTION: BETA10 0x10029f00 @@ -297,7 +297,7 @@ inline void GasStation::StopAction(GarageScript::Script p_objectId) if (p_objectId != GarageScript::c_noneGarage) { InvokeAction(Extra::e_stop, *g_garageScript, p_objectId, NULL); BackgroundAudioManager()->RaiseVolume(); - m_state->FUN_10006460(p_objectId); + m_state->StopAction(p_objectId); } } @@ -310,7 +310,7 @@ MxLong GasStation::HandleEndAction(MxEndActionNotificationParam& p_param) MxDSAction* action = p_param.GetAction(); if (action->GetAtomId() == m_atomId && action->GetObjectId()) { - m_state->FUN_10006460((GarageScript::Script) action->GetObjectId()); + m_state->StopAction((GarageScript::Script) action->GetObjectId()); m_unk0x106 = 0; switch (m_state->m_unk0x14.m_unk0x00) { @@ -357,7 +357,7 @@ MxLong GasStation::HandleEndAction(MxEndActionNotificationParam& p_param) MxLong GasStation::HandleKeyPress(MxS8 p_key) { if (p_key == VK_SPACE && g_unk0x100f0160 == 0 && m_unk0x106 != 0) { - m_state->FUN_10006490(); + m_state->StopActions(); return 1; } @@ -394,6 +394,7 @@ MxLong GasStation::HandleButtonDown(LegoControlManagerNotificationParam& p_param } // FUNCTION: LEGO1 0x10005b20 +// FUNCTION: BETA10 0x10029445 MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param) { if (p_param.GetUnknown0x28() == 1) { @@ -405,7 +406,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param) m_state->m_unk0x14.m_unk0x00 = 0; m_destLocation = LegoGameState::Area::e_garadoor; - m_state->FUN_10006490(); + m_state->StopActions(); m_radio.Stop(); BackgroundAudioManager()->Stop(); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); @@ -414,7 +415,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param) m_state->m_unk0x14.m_unk0x00 = 0; m_destLocation = LegoGameState::Area::e_infomain; - m_state->FUN_10006490(); + m_state->StopActions(); m_radio.Stop(); BackgroundAudioManager()->Stop(); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); @@ -423,7 +424,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param) m_state->m_unk0x14.m_unk0x00 = 0; m_destLocation = LegoGameState::Area::e_dunecarbuild; - m_state->FUN_10006490(); + m_state->StopActions(); m_radio.Stop(); BackgroundAudioManager()->Stop(); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); @@ -435,6 +436,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param) } // FUNCTION: LEGO1 0x10005c40 +// FUNCTION: BETA10 0x10029551 void GasStation::Enable(MxBool p_enable) { LegoWorld::Enable(p_enable); @@ -451,6 +453,7 @@ void GasStation::Enable(MxBool p_enable) } // FUNCTION: LEGO1 0x10005c90 +// FUNCTION: BETA10 0x100295c6 MxResult GasStation::Tickle() { if (!m_worldStarted) { @@ -495,64 +498,79 @@ MxResult GasStation::Tickle() MxBool GasStation::Escape() { m_radio.Stop(); - m_state->FUN_10006490(); + m_state->StopActions(); m_state->m_unk0x14.m_unk0x00 = 0; m_destLocation = LegoGameState::Area::e_infomain; return TRUE; } // FUNCTION: LEGO1 0x10005eb0 +// FUNCTION: BETA10 0x100296b8 GasStationState::GasStationState() { - m_unk0x18 = 0; - m_unk0x1a = 0; - m_unk0x1c = 0; - m_unk0x1e = 0; - m_unk0x20 = 0; - - undefined4* unk0x08 = m_unk0x08; - unk0x08[0] = -1; - unk0x08[1] = -1; - unk0x08[2] = -1; + m_pepperAction = 0; + m_mamaAction = 0; + m_papaAction = 0; + m_nickAction = 0; + m_lauraAction = 0; + memset(m_actions, GarageScript::c_noneGarage, sizeof(m_actions)); } // FUNCTION: LEGO1 0x10006300 +// FUNCTION: BETA10 0x10029754 MxResult GasStationState::Serialize(LegoFile* p_file) { LegoState::Serialize(p_file); if (p_file->IsWriteMode()) { - Write(p_file, m_unk0x18); - Write(p_file, m_unk0x1a); - Write(p_file, m_unk0x1c); - Write(p_file, m_unk0x1e); - Write(p_file, m_unk0x20); + Write(p_file, m_pepperAction); + Write(p_file, m_mamaAction); + Write(p_file, m_papaAction); + Write(p_file, m_nickAction); + Write(p_file, m_lauraAction); } else if (p_file->IsReadMode()) { - Read(p_file, &m_unk0x18); - Read(p_file, &m_unk0x1a); - Read(p_file, &m_unk0x1c); - Read(p_file, &m_unk0x1e); - Read(p_file, &m_unk0x20); + Read(p_file, &m_pepperAction); + Read(p_file, &m_mamaAction); + Read(p_file, &m_papaAction); + Read(p_file, &m_nickAction); + Read(p_file, &m_lauraAction); } return SUCCESS; } -// STUB: LEGO1 0x10006430 -void GasStationState::FUN_10006430(GarageScript::Script) +// FUNCTION: LEGO1 0x10006430 +void GasStationState::PlayAction(GarageScript::Script p_objectId) { - // TODO + for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_actions); i++) { + if (m_actions[i] == GarageScript::c_noneGarage) { + m_actions[i] = p_objectId; + return; + } + } } -// STUB: LEGO1 0x10006460 -void GasStationState::FUN_10006460(GarageScript::Script) +// FUNCTION: LEGO1 0x10006460 +void GasStationState::StopAction(GarageScript::Script p_objectId) { - // TODO + for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_actions); i++) { + if (m_actions[i] == p_objectId) { + m_actions[i] = GarageScript::c_noneGarage; + return; + } + } } -// STUB: LEGO1 0x10006490 -void GasStationState::FUN_10006490() +// FUNCTION: LEGO1 0x10006490 +void GasStationState::StopActions() { - // TODO + for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_actions); i++) { + if (m_actions[i] != GarageScript::c_noneGarage) { + InvokeAction(Extra::e_stop, *g_garageScript, m_actions[i], NULL); + m_actions[i] = GarageScript::c_noneGarage; + } + } + + BackgroundAudioManager()->RaiseVolume(); } diff --git a/LEGO1/lego/legoomni/src/worlds/historybook.cpp b/LEGO1/lego/legoomni/src/worlds/historybook.cpp index 4287fe56..bec6764f 100644 --- a/LEGO1/lego/legoomni/src/worlds/historybook.cpp +++ b/LEGO1/lego/legoomni/src/worlds/historybook.cpp @@ -39,7 +39,7 @@ MxResult HistoryBook::Create(MxDSAction& p_dsAction) InputManager()->SetCamera(NULL); InputManager()->Register(this); - GameState()->SetCurrentArea(LegoGameState::Area::e_histbook); + GameState()->m_currentArea = LegoGameState::Area::e_histbook; GameState()->StopArea(LegoGameState::Area::e_previousArea); return result; } diff --git a/LEGO1/lego/legoomni/src/worlds/hospital.cpp b/LEGO1/lego/legoomni/src/worlds/hospital.cpp index 2bf024f2..6b3c8e5a 100644 --- a/LEGO1/lego/legoomni/src/worlds/hospital.cpp +++ b/LEGO1/lego/legoomni/src/worlds/hospital.cpp @@ -96,7 +96,7 @@ MxResult Hospital::Create(MxDSAction& p_dsAction) m_hospitalState->m_unk0x08.m_unk0x00 = 3; } - GameState()->SetCurrentArea(LegoGameState::e_hospital); + GameState()->m_currentArea = LegoGameState::e_hospital; GameState()->StopArea(LegoGameState::e_previousArea); InputManager()->Register(this); diff --git a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp index 48e04d38..1e248c07 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp @@ -210,7 +210,7 @@ MxResult Infocenter::Create(MxDSAction& p_dsAction) } } - GameState()->SetCurrentArea(LegoGameState::e_infomain); + GameState()->m_currentArea = LegoGameState::e_infomain; GameState()->StopArea(LegoGameState::e_previousArea); if (m_infocenterState->GetUnknown0x74() == 4) { @@ -523,9 +523,9 @@ void Infocenter::ReadyWorld() bgRed->Enable(TRUE); if (GameState()->GetCurrentAct() == GameState()->GetLoadedAct()) { - GameState()->SetCurrentArea(LegoGameState::e_act2main); + GameState()->m_currentArea = LegoGameState::e_act2main; GameState()->StopArea(LegoGameState::e_act2main); - GameState()->SetCurrentArea(LegoGameState::e_infomain); + GameState()->m_currentArea = LegoGameState::e_infomain; } m_infocenterState->SetUnknown0x74(5); @@ -579,9 +579,9 @@ void Infocenter::ReadyWorld() bgRed->Enable(TRUE); if (GameState()->GetCurrentAct() == GameState()->GetLoadedAct()) { - GameState()->SetCurrentArea(LegoGameState::e_act3script); + GameState()->m_currentArea = LegoGameState::e_act3script; GameState()->StopArea(LegoGameState::e_act3script); - GameState()->SetCurrentArea(LegoGameState::e_infomain); + GameState()->m_currentArea = LegoGameState::e_infomain; } m_infocenterState->SetUnknown0x74(5); @@ -1404,7 +1404,7 @@ void Infocenter::Reset() HelicopterState* state = (HelicopterState*) GameState()->GetState("HelicopterState"); if (state) { - state->SetFlag(); + state->Reset(); } } @@ -1549,28 +1549,29 @@ void Infocenter::StopBookAnimation() // FUNCTION: LEGO1 0x10071600 InfocenterState::InfocenterState() { - m_exitDialogueAct1 = LegoState::Playlist((MxU32*) g_exitDialogueAct1, sizeOfArray(g_exitDialogueAct1)); - m_exitDialogueAct23 = LegoState::Playlist((MxU32*) g_exitDialogueAct23, sizeOfArray(g_exitDialogueAct23) - 1); + m_exitDialogueAct1 = Playlist((MxU32*) g_exitDialogueAct1, sizeOfArray(g_exitDialogueAct1), Playlist::e_loop); + m_exitDialogueAct23 = + Playlist((MxU32*) g_exitDialogueAct23, sizeOfArray(g_exitDialogueAct23) - 1, Playlist::e_loop); m_returnDialogue[LegoGameState::e_act1] = - LegoState::Playlist((MxU32*) g_returnDialogueAct1, sizeOfArray(g_returnDialogueAct1) - 1); + Playlist((MxU32*) g_returnDialogueAct1, sizeOfArray(g_returnDialogueAct1) - 1, Playlist::e_loop); m_returnDialogue[LegoGameState::e_act2] = - LegoState::Playlist((MxU32*) g_returnDialogueAct2, sizeOfArray(g_returnDialogueAct2) - 1); + Playlist((MxU32*) g_returnDialogueAct2, sizeOfArray(g_returnDialogueAct2) - 1, Playlist::e_loop); m_returnDialogue[LegoGameState::e_act3] = - LegoState::Playlist((MxU32*) g_returnDialogueAct3, sizeOfArray(g_returnDialogueAct3)); + Playlist((MxU32*) g_returnDialogueAct3, sizeOfArray(g_returnDialogueAct3), Playlist::e_loop); m_leaveDialogue[LegoGameState::e_act1] = - LegoState::Playlist((MxU32*) g_leaveDialogueAct1, sizeOfArray(g_leaveDialogueAct1)); + Playlist((MxU32*) g_leaveDialogueAct1, sizeOfArray(g_leaveDialogueAct1), Playlist::e_loop); m_leaveDialogue[LegoGameState::e_act2] = - LegoState::Playlist((MxU32*) g_leaveDialogueAct2, sizeOfArray(g_leaveDialogueAct2)); + Playlist((MxU32*) g_leaveDialogueAct2, sizeOfArray(g_leaveDialogueAct2), Playlist::e_loop); m_leaveDialogue[LegoGameState::e_act3] = - LegoState::Playlist((MxU32*) g_leaveDialogueAct3, sizeOfArray(g_leaveDialogueAct3) - 1); + Playlist((MxU32*) g_leaveDialogueAct3, sizeOfArray(g_leaveDialogueAct3) - 1, Playlist::e_loop); - m_bricksterDialogue = LegoState::Playlist((MxU32*) g_bricksterDialogue, sizeOfArray(g_bricksterDialogue)); + m_bricksterDialogue = Playlist((MxU32*) g_bricksterDialogue, sizeOfArray(g_bricksterDialogue), Playlist::e_loop); memset(m_letters, 0, sizeof(m_letters)); } diff --git a/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp b/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp index 4b6d7850..5f3ae04c 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp @@ -48,7 +48,7 @@ MxResult InfocenterDoor::Create(MxDSAction& p_dsAction) SetIsWorldActive(FALSE); - GameState()->SetCurrentArea(LegoGameState::e_infodoor); + GameState()->m_currentArea = LegoGameState::e_infodoor; GameState()->StopArea(LegoGameState::e_previousArea); return result; diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 13ea3cbf..c715dd34 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -33,23 +33,21 @@ #include "mxvariabletable.h" #include "pizza.h" #include "pizzeria.h" +#include "racecar.h" #include "scripts.h" #include "skateboard.h" #include "towtrack.h" DECOMP_SIZE_ASSERT(Act1State, 0x26c) -DECOMP_SIZE_ASSERT(Act1State::NamedPlane, 0x4c) +DECOMP_SIZE_ASSERT(LegoNamedPlane, 0x4c) DECOMP_SIZE_ASSERT(Isle, 0x140) // GLOBAL: LEGO1 0x100f1198 MxU32 g_isleFlags = 0x7f; // GLOBAL: LEGO1 0x100f37f0 -MxS32 g_unk0x100f37f0[] = { - Act1State::e_unk953, - Act1State::e_unk954, - Act1State::e_unk955, -}; +IsleScript::Script g_cptClickDialogue[] = + {IsleScript::c_Avo905Ps_PlayWav, IsleScript::c_Avo906Ps_PlayWav, IsleScript::c_Avo907Ps_PlayWav}; // FUNCTION: LEGO1 0x10030820 Isle::Isle() @@ -111,8 +109,8 @@ MxResult Isle::Create(MxDSAction& p_dsAction) m_destLocation = LegoGameState::e_infomain; } - if (GameState()->GetCurrentArea() == LegoGameState::e_isle) { - GameState()->SetCurrentArea(LegoGameState::e_undefined); + if (GameState()->m_currentArea == LegoGameState::e_isle) { + GameState()->m_currentArea = LegoGameState::e_undefined; } LegoGameState* gameState = GameState(); @@ -364,14 +362,14 @@ MxLong Isle::HandleControl(LegoControlManagerNotificationParam& p_param) TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); break; case IsleScript::c_Observe_LeftArrow_Ctl: - m_act1state->FUN_100346a0(); + m_act1state->StopCptClickDialogue(); m_radio.Stop(); case IsleScript::c_SeaView_RightArrow_Ctl: m_destLocation = LegoGameState::e_elevopen; TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); break; case IsleScript::c_Observe_RightArrow_Ctl: - m_act1state->FUN_100346a0(); + m_act1state->StopCptClickDialogue(); m_radio.Stop(); case IsleScript::c_SeaView_LeftArrow_Ctl: m_destLocation = LegoGameState::e_elevdown; @@ -422,7 +420,7 @@ MxLong Isle::HandleControl(LegoControlManagerNotificationParam& p_param) break; case IsleScript::c_Observe_Draw1_Ctl: case IsleScript::c_Observe_Draw2_Ctl: - m_act1state->FUN_10034660(); + m_act1state->PlayCptClickDialogue(); break; case IsleScript::c_ElevDown_Elevator_Ctl: m_destLocation = LegoGameState::e_elevride2; @@ -853,7 +851,7 @@ void Isle::Enable(MxBool p_enable) InputManager()->ClearWorld(); } - m_act1state->FUN_10034b60(); + m_act1state->RemoveActors(); } } @@ -1190,7 +1188,7 @@ MxBool Isle::Escape() switch (m_act1state->m_unk0x018) { case 3: if (UserActor() != NULL) { - m_pizza->FUN_10038380(); + m_pizza->StopActions(); m_pizza->FUN_100382b0(); } break; @@ -1257,7 +1255,7 @@ void Isle::FUN_10033350() if (m_act1state->m_unk0x018 == 3) { if (UserActor() != NULL) { - m_pizza->FUN_10038380(); + m_pizza->StopActions(); m_pizza->FUN_100382b0(); } } @@ -1282,17 +1280,17 @@ void Isle::FUN_10033350() m_destLocation = LegoGameState::e_infomain; } -// STUB: LEGO1 0x100334b0 -Act1State::Act1State() : m_unk0x00c(0), m_unk0x00e(0), m_unk0x008(NULL), m_unk0x010(0) +// FUNCTION: LEGO1 0x100334b0 +// FUNCTION: BETA10 0x10035197 +Act1State::Act1State() { - m_unk0x01e = FALSE; + m_elevFloor = Act1State::c_floor1; m_unk0x018 = 1; - m_unk0x010 = 0; - m_planeActive = FALSE; - m_unk0x00e = 0; + m_unk0x01e = FALSE; + m_cptClickDialogue = Playlist((MxU32*) g_cptClickDialogue, sizeOfArray(g_cptClickDialogue), Playlist::e_loop); m_unk0x01f = FALSE; - m_unk0x008 = g_unk0x100f37f0; - m_unk0x014 = -1; + m_planeActive = FALSE; + m_currentCptClickDialogue = IsleScript::c_noneIsle; m_unk0x022 = FALSE; m_unk0x154 = NULL; m_unk0x158 = NULL; @@ -1300,8 +1298,6 @@ Act1State::Act1State() : m_unk0x00c(0), m_unk0x00e(0), m_unk0x008(NULL), m_unk0x m_helicopter = NULL; m_unk0x1b0 = NULL; m_unk0x021 = 1; - m_elevFloor = Act1State::c_floor1; - m_unk0x00c = sizeOfArray(g_unk0x100f37f0); m_unk0x1b4 = NULL; m_jetski = NULL; m_unk0x208 = NULL; @@ -1310,24 +1306,25 @@ Act1State::Act1State() : m_unk0x00c(0), m_unk0x00e(0), m_unk0x008(NULL), m_unk0x m_unk0x260 = NULL; m_unk0x264 = NULL; m_racecar = NULL; - SetFlag(); + Reset(); } // FUNCTION: LEGO1 0x10033ac0 +// FUNCTION: BETA10 0x1003524f MxResult Act1State::Serialize(LegoFile* p_file) { LegoState::Serialize(p_file); - m_unk0x024.Serialize(p_file); - m_unk0x070.Serialize(p_file); - m_unk0x0bc.Serialize(p_file); - m_unk0x108.Serialize(p_file); - m_unk0x164.Serialize(p_file); - m_unk0x1bc.Serialize(p_file); - m_unk0x210.Serialize(p_file); + m_motocyclePlane.Serialize(p_file); + m_bikePlane.Serialize(p_file); + m_skateboardPlane.Serialize(p_file); + m_helicopterPlane.Serialize(p_file); + m_jetskiPlane.Serialize(p_file); + m_dunebuggyPlane.Serialize(p_file); + m_racecarPlane.Serialize(p_file); if (p_file->IsWriteMode()) { - if (m_unk0x108.GetName()->Compare("") != 0) { + if (m_helicopterPlane.GetName()->Compare("") != 0) { if (m_unk0x154) { WriteNamedTexture(p_file, m_unk0x154); } @@ -1347,7 +1344,7 @@ MxResult Act1State::Serialize(LegoFile* p_file) FUN_1003f540(p_file, "chjetr.gif"); } } - if (m_unk0x164.GetName()->Compare("") != 0) { + if (m_jetskiPlane.GetName()->Compare("") != 0) { if (m_unk0x1b0) { WriteNamedTexture(p_file, m_unk0x1b0); } @@ -1361,7 +1358,7 @@ MxResult Act1State::Serialize(LegoFile* p_file) FUN_1003f540(p_file, "jswnsh.gif"); } } - if (m_unk0x1bc.GetName()->Compare("") != 0) { + if (m_dunebuggyPlane.GetName()->Compare("") != 0) { if (m_unk0x208) { WriteNamedTexture(p_file, m_unk0x208); } @@ -1369,7 +1366,7 @@ MxResult Act1State::Serialize(LegoFile* p_file) FUN_1003f540(p_file, "dbfrfn.gif"); } } - if (m_unk0x210.GetName()->Compare("") != 0) { + if (m_racecarPlane.GetName()->Compare("") != 0) { if (m_unk0x25c) { WriteNamedTexture(p_file, m_unk0x25c); } @@ -1390,11 +1387,11 @@ MxResult Act1State::Serialize(LegoFile* p_file) } } - Write(p_file, m_unk0x010); + Write(p_file, m_cptClickDialogue.m_nextIndex); Write(p_file, m_unk0x022); } else if (p_file->IsReadMode()) { - if (m_unk0x108.GetName()->Compare("") != 0) { + if (m_helicopterPlane.GetName()->Compare("") != 0) { m_unk0x154 = ReadNamedTexture(p_file); if (m_unk0x154 == NULL) { return FAILURE; @@ -1410,7 +1407,7 @@ MxResult Act1State::Serialize(LegoFile* p_file) return FAILURE; } } - if (m_unk0x164.GetName()->Compare("") != 0) { + if (m_jetskiPlane.GetName()->Compare("") != 0) { m_unk0x1b0 = ReadNamedTexture(p_file); if (m_unk0x1b0 == NULL) { return FAILURE; @@ -1421,13 +1418,13 @@ MxResult Act1State::Serialize(LegoFile* p_file) return FAILURE; } } - if (m_unk0x1bc.GetName()->Compare("") != 0) { + if (m_dunebuggyPlane.GetName()->Compare("") != 0) { m_unk0x208 = ReadNamedTexture(p_file); if (m_unk0x208 == NULL) { return FAILURE; } } - if (m_unk0x210.GetName()->Compare("") != 0) { + if (m_racecarPlane.GetName()->Compare("") != 0) { m_unk0x25c = ReadNamedTexture(p_file); if (m_unk0x25c == NULL) { return FAILURE; @@ -1444,7 +1441,7 @@ MxResult Act1State::Serialize(LegoFile* p_file) } } - Read(p_file, &m_unk0x010); + Read(p_file, &m_cptClickDialogue.m_nextIndex); Read(p_file, &m_unk0x022); } @@ -1452,29 +1449,35 @@ MxResult Act1State::Serialize(LegoFile* p_file) return SUCCESS; } -// STUB: LEGO1 0x10034660 -void Act1State::FUN_10034660() +// FUNCTION: LEGO1 0x10034660 +void Act1State::PlayCptClickDialogue() { - // TODO + StopCptClickDialogue(); + m_currentCptClickDialogue = (IsleScript::Script) m_cptClickDialogue.Next(); + BackgroundAudioManager()->LowerVolume(); + + if (m_currentCptClickDialogue != IsleScript::c_noneIsle) { + InvokeAction(Extra::e_start, *g_isleScript, m_currentCptClickDialogue, NULL); + } } // FUNCTION: LEGO1 0x100346a0 -void Act1State::FUN_100346a0() +void Act1State::StopCptClickDialogue() { - if (m_unk0x014 != -1) { - InvokeAction(Extra::e_stop, *g_isleScript, m_unk0x014, NULL); - m_unk0x014 = -1; + if (m_currentCptClickDialogue != IsleScript::c_noneIsle) { + InvokeAction(Extra::e_stop, *g_isleScript, m_currentCptClickDialogue, NULL); + m_currentCptClickDialogue = IsleScript::c_noneIsle; } } // FUNCTION: LEGO1 0x100346d0 -MxBool Act1State::SetFlag() +MxBool Act1State::Reset() { - m_unk0x024.SetName(""); - m_unk0x070.SetName(""); - m_unk0x0bc.SetName(""); + m_motocyclePlane.SetName(""); + m_bikePlane.SetName(""); + m_skateboardPlane.SetName(""); m_unk0x022 = FALSE; - m_unk0x108.SetName(""); + m_helicopterPlane.SetName(""); if (m_unk0x154) { delete m_unk0x154; @@ -1496,7 +1499,7 @@ MxBool Act1State::SetFlag() m_helicopter = NULL; } - m_unk0x164.SetName(""); + m_jetskiPlane.SetName(""); if (m_unk0x1b0) { delete m_unk0x1b0; @@ -1513,7 +1516,7 @@ MxBool Act1State::SetFlag() m_jetski = NULL; } - m_unk0x1bc.SetName(""); + m_dunebuggyPlane.SetName(""); if (m_unk0x208) { delete m_unk0x208; @@ -1525,7 +1528,7 @@ MxBool Act1State::SetFlag() m_dunebuggy = NULL; } - m_unk0x210.SetName(""); + m_racecarPlane.SetName(""); if (m_unk0x25c) { delete m_unk0x25c; @@ -1550,10 +1553,50 @@ MxBool Act1State::SetFlag() return TRUE; } -// STUB: LEGO1 0x10034b60 -void Act1State::FUN_10034b60() +// FUNCTION: LEGO1 0x10034b60 +void Act1State::RemoveActors() { - // TODO + Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle); + + isle->m_motocycle->UpdatePlane(m_motocyclePlane); + isle->m_bike->UpdatePlane(m_bikePlane); + isle->m_skateboard->UpdatePlane(m_skateboardPlane); + + if (isle->m_helicopter != NULL) { + isle->m_helicopter->UpdatePlane(m_helicopterPlane); + m_helicopter = isle->m_helicopter; + isle->RemoveActor(m_helicopter); + isle->VTable0x6c(m_helicopter); + m_helicopter->SetBoundary(NULL); + m_helicopter->SetController(NULL); + } + + if (isle->m_jetski != NULL) { + isle->m_jetski->UpdatePlane(m_jetskiPlane); + m_jetski = isle->m_jetski; + isle->RemoveActor(m_jetski); + isle->VTable0x6c(m_jetski); + m_jetski->SetBoundary(NULL); + m_jetski->SetController(NULL); + } + + if (isle->m_dunebuggy != NULL) { + isle->m_dunebuggy->UpdatePlane(m_dunebuggyPlane); + m_dunebuggy = isle->m_dunebuggy; + isle->RemoveActor(m_dunebuggy); + isle->VTable0x6c(m_dunebuggy); + m_dunebuggy->SetBoundary(NULL); + m_dunebuggy->SetController(NULL); + } + + if (isle->m_racecar != NULL) { + isle->m_racecar->UpdatePlane(m_racecarPlane); + m_racecar = isle->m_racecar; + isle->RemoveActor(m_racecar); + isle->VTable0x6c(m_racecar); + m_racecar->SetBoundary(NULL); + m_racecar->SetController(NULL); + } } // STUB: LEGO1 0x10034d00 diff --git a/LEGO1/lego/legoomni/src/worlds/jukebox.cpp b/LEGO1/lego/legoomni/src/worlds/jukebox.cpp index ca27142d..fe476499 100644 --- a/LEGO1/lego/legoomni/src/worlds/jukebox.cpp +++ b/LEGO1/lego/legoomni/src/worlds/jukebox.cpp @@ -61,7 +61,7 @@ MxResult JukeBox::Create(MxDSAction& p_dsAction) m_state->m_music = JukeBoxState::e_pasquell; } - GameState()->SetCurrentArea(LegoGameState::e_jukeboxw); + GameState()->m_currentArea = LegoGameState::e_jukeboxw; GameState()->StopArea(LegoGameState::e_previousArea); TickleManager()->RegisterClient(this, 2000); return ret; diff --git a/LEGO1/lego/legoomni/src/worlds/police.cpp b/LEGO1/lego/legoomni/src/worlds/police.cpp index cf7bb0f8..43bd67bf 100644 --- a/LEGO1/lego/legoomni/src/worlds/police.cpp +++ b/LEGO1/lego/legoomni/src/worlds/police.cpp @@ -63,7 +63,7 @@ MxResult Police::Create(MxDSAction& p_dsAction) } m_policeState = policeState; - GameState()->SetCurrentArea(LegoGameState::e_police); + GameState()->m_currentArea = LegoGameState::e_police; GameState()->StopArea(LegoGameState::e_previousArea); return ret; } diff --git a/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp b/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp index 234903bf..fe4ac424 100644 --- a/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp +++ b/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp @@ -97,7 +97,7 @@ MxResult RegistrationBook::Create(MxDSAction& p_dsAction) SetIsWorldActive(FALSE); InputManager()->Register(this); - GameState()->SetCurrentArea(LegoGameState::e_regbook); + GameState()->m_currentArea = LegoGameState::e_regbook; GameState()->StopArea(LegoGameState::e_previousArea); m_infocenterState = (InfocenterState*) GameState()->GetState("InfocenterState"); diff --git a/LEGO1/lego/legoomni/src/worlds/score.cpp b/LEGO1/lego/legoomni/src/worlds/score.cpp index db9a24ec..3ecae676 100644 --- a/LEGO1/lego/legoomni/src/worlds/score.cpp +++ b/LEGO1/lego/legoomni/src/worlds/score.cpp @@ -63,7 +63,7 @@ MxResult Score::Create(MxDSAction& p_dsAction) LegoGameState* gameState = GameState(); ScoreState* state = (ScoreState*) gameState->GetState("ScoreState"); m_state = state ? state : (ScoreState*) gameState->CreateState("ScoreState"); - GameState()->SetCurrentArea(LegoGameState::e_infoscor); + GameState()->m_currentArea = LegoGameState::e_infoscor; GameState()->StopArea(LegoGameState::e_previousArea); } diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index 1e774abf..1adbac27 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -48,7 +48,7 @@ class LegoWEGEdge : public LegoWEEdge { Mx4DPointFloat* GetEdgeNormal(int index) { return &m_edgeNormals[index]; } // FUNCTION: BETA10 0x1001c9b0 - LegoChar* GetName() { return m_name; } + const LegoChar* GetName() { return m_name; } void SetFlag0x10(LegoU32 p_disable) { diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index 94fed7c6..87b8a3a0 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -475,6 +475,7 @@ LegoResult LegoROI::SetFrame(LegoAnim* p_anim, LegoTime p_time) } // FUNCTION: LEGO1 0x100a9170 +// FUNCTION: BETA10 0x1018ae09 LegoResult LegoROI::FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha) { LegoResult result = SUCCESS; @@ -552,6 +553,13 @@ LegoResult LegoROI::GetTexture(LegoTextureInfo*& p_textureInfo) return FAILURE; } +// FUNCTION: LEGO1 0x100a9330 +// FUNCTION: BETA10 0x1018b22c +LegoResult LegoROI::FUN_100a9330(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha) +{ + return FUN_100a9170(p_red, p_green, p_blue, p_alpha); +} + // FUNCTION: LEGO1 0x100a9350 // FUNCTION: BETA10 0x1018b25c LegoResult LegoROI::FUN_100a9350(const LegoChar* p_color) @@ -564,6 +572,18 @@ LegoResult LegoROI::FUN_100a9350(const LegoChar* p_color) return SUCCESS; } +// FUNCTION: LEGO1 0x100a93b0 +// FUNCTION: BETA10 0x1018b2c0 +LegoResult LegoROI::FUN_100a93b0(const LegoChar* p_color) +{ + MxFloat red, green, blue, alpha; + if (ColorAliasLookup(p_color, red, green, blue, alpha)) { + return FUN_100a9330(red, green, blue, alpha); + } + + return 0; +} + // FUNCTION: LEGO1 0x100a9410 // FUNCTION: BETA10 0x1018b324 LegoU32 LegoROI::FUN_100a9410( @@ -746,6 +766,7 @@ LegoBool LegoROI::FUN_100a9bf0(const LegoChar* p_param, float& p_red, float& p_g } // FUNCTION: LEGO1 0x100a9c50 +// FUNCTION: BETA10 0x1018bdd9 LegoBool LegoROI::ColorAliasLookup(const LegoChar* p_param, float& p_red, float& p_green, float& p_blue, float& p_alpha) { for (LegoU32 i = 0; i < sizeOfArray(g_roiColorAliases); i++) { diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index babb566a..541cfac5 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -38,7 +38,9 @@ class LegoROI : public ViewROI { LegoResult FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha); LegoResult FUN_100a9210(LegoTextureInfo* p_textureInfo); LegoResult GetTexture(LegoTextureInfo*& p_textureInfo); + LegoResult FUN_100a9330(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha); LegoResult FUN_100a9350(const LegoChar* p_color); + LegoResult FUN_100a93b0(const LegoChar* p_color); LegoU32 FUN_100a9410(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3, LegoBool p_collideBox); void SetName(const LegoChar* p_name); diff --git a/LEGO1/library_msvc.h b/LEGO1/library_msvc.h index 49e2efbd..c4a46848 100644 --- a/LEGO1/library_msvc.h +++ b/LEGO1/library_msvc.h @@ -19,6 +19,7 @@ // _free // LIBRARY: LEGO1 0x1008b020 +// LIBRARY: BETA10 0x100f8d20 // ___CxxFrameHandler // LIBRARY: LEGO1 0x1008b24c @@ -731,6 +732,12 @@ // LIBRARY: BETA10 0x1018ed70 // _strupr +// LIBRARY: BETA10 0x100f9690 +// sprintf + +// LIBRARY: BETA10 0x100fb150 +// _spawnl + // LIBRARY: BETA10 0x1001d1a0 // `vector constructor iterator' diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index 58d36198..b2f4d53a 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -78,6 +78,7 @@ class Mx4DPointFloat : public Vector4 { const float& operator[](int idx) const { return m_data[idx]; } // SYNTHETIC: LEGO1 0x10064b20 + // SYNTHETIC: BETA10 0x10070420 // Mx4DPointFloat::operator= private: diff --git a/LEGO1/mxgeometry/mxmatrix.h b/LEGO1/mxgeometry/mxmatrix.h index 5ac9b2be..a9249225 100644 --- a/LEGO1/mxgeometry/mxmatrix.h +++ b/LEGO1/mxgeometry/mxmatrix.h @@ -20,6 +20,7 @@ class MxMatrix : public Matrix4 { // FUNCTION: BETA10 0x10010860 float* operator[](int idx) { return m_data[idx]; } + // FUNCTION: BETA10 0x1001c670 const float* operator[](int idx) const { return m_data[idx]; } // FUNCTION: LEGO1 0x10002850 diff --git a/LEGO1/omni/src/notify/mxnotificationmanager.cpp b/LEGO1/omni/src/notify/mxnotificationmanager.cpp index dec49818..61e051f7 100644 --- a/LEGO1/omni/src/notify/mxnotificationmanager.cpp +++ b/LEGO1/omni/src/notify/mxnotificationmanager.cpp @@ -178,6 +178,7 @@ void MxNotificationManager::Register(MxCore* p_listener) } // FUNCTION: LEGO1 0x100acdf0 +// FUNCTION: BETA10 0x10126785 void MxNotificationManager::Unregister(MxCore* p_listener) { AUTOLOCK(m_lock); diff --git a/LEGO1/realtime/orientableroi.h b/LEGO1/realtime/orientableroi.h index 5e70aa5e..8daf1f51 100644 --- a/LEGO1/realtime/orientableroi.h +++ b/LEGO1/realtime/orientableroi.h @@ -51,6 +51,7 @@ class OrientableROI : public ROI { // FUNCTION: BETA10 0x1004aa70 const float* GetWorldUp() const { return m_local2world[1]; } + // FUNCTION: BETA10 0x10070380 OrientableROI* GetParentROI() const { return m_parentROI; } void SetParentROI(OrientableROI* p_parentROI) { m_parentROI = p_parentROI; } diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index a09e62c4..8f871474 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -152,6 +152,7 @@ class Vector2 { virtual void SetVector(const Vector2* p_other) { EqualsImpl(p_other->m_data); } // vtable+0x6c // SYNTHETIC: LEGO1 0x10010be0 + // SYNTHETIC: BETA10 0x100121e0 // Vector3::operator= // SYNTHETIC: BETA10 0x1004af40 @@ -301,10 +302,14 @@ class Vector4 : public Vector3 { // FUNCTION: BETA10 0x10048780 Vector4(float* p_data) : Vector3(p_data) {} - // Hack: Some code initializes a Vector4 from a (most likely) const float* source. - // Example: LegoCarBuild::VTable0x6c + // Some code initializes a Vector4 from a `const float*` source. + // Example: `LegoCarBuild::VTable0x6c` // Vector4 however is a class that can mutate its underlying source, making // initialization with a const source fundamentally incompatible. + // BETA10 appears to have two separate constructors for Vector4 as well, + // 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