Animmanager (#712)

* Implement LegoAnimationManager::StartEntityAction
Fix some class definitions

* Fix style issues

* Add size annotations

* Fix global pointer

* Style/naming

---------

Co-authored-by: Christian Semmler <mail@csemmler.com>
This commit is contained in:
Nathan M Gilbert 2024-03-23 10:09:20 -04:00 committed by GitHub
parent fca8f74bd8
commit 8b21e8136e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 165 additions and 49 deletions

View file

@ -363,6 +363,7 @@ add_library(lego1 SHARED
LEGO1/lego/legoomni/src/main/legoomni.cpp
LEGO1/lego/legoomni/src/notify/legoeventnotificationparam.cpp
LEGO1/lego/legoomni/src/paths/legoanimactor.cpp
LEGO1/lego/legoomni/src/paths/legoextraactor.cpp
LEGO1/lego/legoomni/src/paths/legopathactor.cpp
LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp
LEGO1/lego/legoomni/src/paths/legopathpresenter.cpp

View file

@ -41,8 +41,8 @@ class Act3 : public LegoWorld {
// SYNTHETIC: LEGO1 0x10072630
// Act3::`scalar deleting destructor'
MxBool FUN_100727e0(MxU32, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up);
MxBool FUN_10072980(MxU32, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up);
MxBool FUN_100727e0(LegoPathController*, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up);
MxBool FUN_10072980(LegoPathController*, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up);
void FUN_10073400();
void FUN_10073430();

View file

@ -4,16 +4,35 @@
#include "actionsfwd.h"
#include "animstate.h"
#include "decomp.h"
#include "legoentity.h"
#include "legotraninfolist.h"
#include "mxcore.h"
// SIZE 0x18
struct Character {
char* m_name; // 0x00
undefined m_unk0x04[0x10]; // 0x04
undefined m_unk0x04; // 0x04
MxS8 m_vehicleId; // 0x05
undefined m_unk0x06; // 0x06
MxBool m_unk0x07; // 0x07
undefined m_unk0x08[12]; // 0x08
MxBool m_active; // 0x14
};
// SIZE 0x08
struct Vehicle {
char* m_name; // 0x00
undefined m_unk0x04; // 0x04
MxBool m_unk0x05; // 0x05
};
// SIZE 0x18
struct Unknown0x3c {
LegoROI* m_roi; // 0x00
MxU32 m_id; // 0x04
undefined m_unk0x08[0x10]; // 0x08
};
// VTABLE: LEGO1 0x100d8c18
// SIZE 0x500
class LegoAnimationManager : public MxCore {
@ -47,6 +66,7 @@ class LegoAnimationManager : public MxCore {
MxResult ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info);
MxResult ReadModelInfo(LegoFile* p_file, ModelInfo* p_info);
void FUN_100603c0();
MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity);
undefined4 FUN_10060dc0(
IsleScript::Script,
undefined4,
@ -86,7 +106,7 @@ class LegoAnimationManager : public MxCore {
undefined m_unk0x38; // 0x38
undefined m_unk0x39; // 0x39
undefined m_unk0x3a; // 0x3a
undefined m_unk0x3b[0x3c1]; // 0x3b
Unknown0x3c m_unk0x3c[40]; // 0x3c
undefined4 m_unk0x3fc; // 0x3fc
MxU8 m_unk0x400; // 0x400
undefined m_unk0x401; // 0x401

View file

@ -2,6 +2,7 @@
#define LEGOCHARACTERMANAGER_H
#include "decomp.h"
#include "legoextraactor.h"
#include "legovariables.h"
#include "misc/legostorage.h"
#include "mxstl/stlcompat.h"
@ -51,6 +52,7 @@ class LegoCharacterManager {
void FUN_100832a0();
void FUN_10083db0(LegoROI* p_roi);
void FUN_10083f10(LegoROI* p_roi);
LegoExtraActor* FUN_10084c40(const LegoChar*);
LegoCharacterData* Find(const char* p_key);
MxBool FUN_10084ec0(LegoROI* p_roi);
MxU32 FUN_10085140(LegoROI*, MxBool);

View file

@ -70,9 +70,10 @@ class LegoEntity : public MxEntity {
Mx3DPointFloat GetWorldUp();
Mx3DPointFloat GetWorldPosition();
inline LegoROI* GetROI() { return m_roi; }
inline MxU8 GetFlags() { return m_flags; }
inline MxBool GetUnknown0x10IsSet(MxU8 p_flag) { return m_unk0x10 & p_flag; }
inline MxU8 GetFlags() { return m_flags; }
inline LegoROI* GetROI() { return m_roi; }
inline MxU8 GetUnknown0x59() { return m_unk0x59; }
inline void SetFlags(MxU8 p_flags) { m_flags = p_flags; }
inline void SetFlag(MxU8 p_flag) { m_flags |= p_flag; }
@ -90,7 +91,7 @@ class LegoEntity : public MxEntity {
MxFloat m_worldSpeed; // 0x50
LegoROI* m_roi; // 0x54
MxBool m_cameraFlag; // 0x58
undefined m_unk0x59; // 0x59
MxU8 m_unk0x59; // 0x59
// For tokens from the extra string that look like this:
// "Action:openram;\lego\scripts\Race\CarRaceR;0"
Extra::ActionType m_actionType; // 0x5c

View file

@ -200,6 +200,7 @@ class LegoOmni : public MxOmni {
void RemoveWorld(const MxAtomId& p_atom, MxLong p_objectId);
MxResult RegisterScripts();
MxS32 GetScriptIndex(const char* p_key);
void DeleteAction();
static MxS32 GetCurrPathInfo(LegoPathBoundary**, MxS32&);
const char* FindScript(MxU32 p_id);
@ -228,6 +229,13 @@ class LegoOmni : public MxOmni {
inline void SetCurrentActor(IslePathActor* p_currentActor) { m_currentActor = p_currentActor; }
inline void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; }
inline void SetExit(MxBool p_exit) { m_exit = p_exit; }
inline MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction)
{
if (m_unk0x13c) {
return Start(&p_dsAction);
}
return SUCCESS;
}
inline void CloseMainWindow() { PostMessageA(m_windowHandle, WM_CLOSE, 0, 0); }

View file

@ -5,6 +5,8 @@
#include "mxtypes.h"
#include "realtime/matrix.h"
class LegoPathController;
// VTABLE: LEGO1 0x100d6e28
// SIZE 0x154
class LegoPathActor : public LegoActor {
@ -82,22 +84,29 @@ class LegoPathActor : public LegoActor {
virtual void VTable0xc8(MxU8 p_unk0x148) { m_unk0x148 = p_unk0x148; } // vtable+0xc8
inline MxU32 GetUnknown88() { return m_unk0x88; }
inline LegoPathController* GetController() { return m_controller; }
inline void SetUnknown88(MxU32 p_unk0x88) { m_unk0x88 = p_unk0x88; }
inline void SetUnknownDC(MxU32 p_unk0xdc) { m_unk0xdc = p_unk0xdc; }
inline void ClearController() { m_controller = NULL; }
// SYNTHETIC: LEGO1 0x1002d800
// LegoPathActor::`scalar deleting destructor'
protected:
undefined m_unk0x78[0x10]; // 0x78
undefined m_unk0x78[0xa]; // 0x78
MxBool m_userNavFlag; // 0x82
undefined4 m_unk0x84; // 0x84
MxU32 m_unk0x88; // 0x88
undefined m_unk0x8c[0x50]; // 0x8c
undefined4 m_boundary; // 0x8c
undefined m_unk0x8c[0x4c]; // 0x90
MxU32 m_unk0xdc; // 0xdc
undefined m_unk0xe0[0xa]; // 0xe0
undefined4 m_unk0xe0; // 0xe0
undefined4 m_destEdge; // 0xe4
undefined2 m_unk0xe8; // 0xe8
MxU8 m_unk0xea; // 0xea
undefined m_unk0xef[0x4d]; // 0xef
MxU32 m_unk0x138; // 0x138
LegoPathController* m_controller; // 0x138
MxFloat m_unk0x13c; // 0x13c
MxFloat m_unk0x140; // 0x140
MxFloat m_unk0x144; // 0x144

View file

@ -2,9 +2,8 @@
#define LEGOPATHCONTROLLER_H
#include "decomp.h"
#include "legopathactor.h"
#include "mxcore.h"
class IslePathActor;
class LegoPathBoundary;
// VTABLE: LEGO1 0x100d7d60
@ -35,7 +34,7 @@ class LegoPathController : public MxCore {
virtual void VTable0x14(); // vtable+0x14
virtual void Destroy(); // vtable+0x18
undefined4 FUN_10046770(IslePathActor* p_actor);
undefined4 FUN_10046770(LegoPathActor* p_actor);
MxResult FUN_10046b30(LegoPathBoundary** p_path, MxS32& p_value);
void Enable(MxBool p_enable);

View file

@ -3,6 +3,9 @@
#include "compat.h"
#include "decomp.h"
#include "legoinputmanager.h"
#include "legoomni.h"
#include "legovideomanager.h"
// Long include path due to dependency of misc library on LegoOmni
#include "lego/legoomni/include/actions/actionsfwd.h"
#include "mxtypes.h"
@ -13,7 +16,6 @@ class LegoBuildingManager;
class LegoCharacterManager;
class LegoControlManager;
class LegoGameState;
class LegoInputManager;
class LegoNavController;
class LegoOmni;
class LegoPlantManager;
@ -32,32 +34,40 @@ class ViewManager;
extern MxBool g_isWorldActive;
LegoOmni* Lego();
LegoInputManager* InputManager();
LegoSoundManager* SoundManager();
MxBackgroundAudioManager* BackgroundAudioManager();
LegoGameState* GameState();
MxTransitionManager* TransitionManager();
LegoVideoManager* VideoManager();
MxBackgroundAudioManager* BackgroundAudioManager();
LegoInputManager* InputManager();
LegoControlManager* ControlManager();
LegoGameState* GameState();
LegoAnimationManager* AnimationManager();
LegoNavController* NavController();
LegoBuildingManager* BuildingManager();
LegoControlManager* ControlManager();
IslePathActor* CurrentActor();
ViewManager* GetViewManager();
LegoPlantManager* PlantManager();
LegoWorld* CurrentWorld();
LegoCharacterManager* CharacterManager();
ViewManager* GetViewManager();
LegoPlantManager* PlantManager();
LegoBuildingManager* BuildingManager();
LegoTextureContainer* TextureContainer();
ViewLODListManager* GetViewLODListManager();
LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid);
void FUN_10015820(MxBool p_disable, MxU16 p_flags);
LegoROI* FindROI(const char* p_name);
void SetROIVisible(const char* p_name, MxBool p_visible);
void SetCurrentActor(IslePathActor* p_currentActor);
MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction);
void DeleteAction();
LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid);
MxDSAction& GetCurrentAction();
void SetCurrentWorld(LegoWorld* p_world);
MxTransitionManager* TransitionManager();
void PlayMusic(JukeboxScript::Script p_script);
void SetIsWorldActive(MxBool p_isWorldActive);
void DeleteObjects(MxAtomId* p_id, MxS32 p_first, MxS32 p_last);
void SetCurrentWorld(LegoWorld* p_world);
void FUN_10015820(MxBool p_disable, MxU16 p_flags);
void SetROIVisible(const char* p_name, MxBool p_visible);
void SetCurrentActor(IslePathActor* p_currentActor);
// FUNCTION: LEGO1 0x10015890
inline MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction)
{
return LegoOmni::GetInstance()->StartActionIfUnknown0x13c(p_dsAction);
}
#endif // MISC_H

View file

@ -220,10 +220,10 @@ MxU32 Helicopter::VTable0xd4(LegoControlManagerEvent& p_param)
va4.EqualsCross(v68, dir);
v7c.EqualsCross(va4, v90);
if (ret) {
if (((Act3*) m_world)->FUN_100727e0(m_unk0x138, loc, dir, v7c)) {
if (((Act3*) m_world)->FUN_100727e0(m_controller, loc, dir, v7c)) {
break;
}
else if (((Act3*) m_world)->FUN_10072980(m_unk0x138, loc, dir, v7c)) {
else if (((Act3*) m_world)->FUN_10072980(m_controller, loc, dir, v7c)) {
break;
}
}

View file

@ -1,13 +1,22 @@
#include "legoanimationmanager.h"
#include "legocharactermanager.h"
#include "legogamestate.h"
#include "legoomni.h"
#include "misc.h"
#include "mxutilities.h"
#include "roi/legoroi.h"
#include <io.h>
DECOMP_SIZE_ASSERT(LegoAnimationManager, 0x500)
DECOMP_SIZE_ASSERT(Character, 0x18)
DECOMP_SIZE_ASSERT(Vehicle, 0x8)
DECOMP_SIZE_ASSERT(Unknown0x3c, 0x18)
// GLOBAL: LEGO1 0x100f6d20
Vehicle g_vehicles[] = {"bikebd", 0, FALSE, "bikepg", 0, FALSE, "bikerd", 0, FALSE, "bikesy", 0,
FALSE, "motoni", 0, FALSE, "motola", 0, FALSE, "board", 0, FALSE};
// GLOBAL: LEGO1 0x100f7048
Character g_characters[47]; // TODO: Initialize this
@ -344,6 +353,45 @@ void LegoAnimationManager::FUN_100603c0()
// TODO
}
// FUNCTION: LEGO1 0x10060d00
MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity)
{
MxResult result = FAILURE;
LegoROI* roi = p_entity->GetROI();
if (p_entity->GetUnknown0x59() == 0) {
LegoPathActor* actor = CharacterManager()->FUN_10084c40(roi->GetName());
if (actor) {
LegoPathController* controller = actor->GetController();
if (controller) {
controller->FUN_10046770(actor);
actor->ClearController();
for (MxS32 i = 0; i < (MxS32) _countof(m_unk0x3c); i++) {
if (m_unk0x3c[i].m_roi == roi) {
MxU32 characterId = m_unk0x3c[i].m_id;
g_characters[characterId].m_unk0x07 = TRUE;
MxS32 vehicleId = g_characters[characterId].m_vehicleId;
if (vehicleId >= 0) {
g_vehicles[vehicleId].m_unk0x05 = FALSE;
}
break;
}
}
}
}
}
if (StartActionIfUnknown0x13c(p_dsAction) == SUCCESS) {
result = SUCCESS;
}
return result;
}
// STUB: LEGO1 0x10060dc0
undefined4 LegoAnimationManager::FUN_10060dc0(
IsleScript::Script,

View file

@ -170,7 +170,7 @@ LegoROI* LegoCharacterManager::GetROI(const char* p_key, MxBool p_createEntity)
if (character != NULL) {
if (p_createEntity && character->m_roi->GetEntity() == NULL) {
// TODO: Match
LegoAnimActor* actor = new LegoAnimActor();
LegoExtraActor* actor = new LegoExtraActor();
actor->SetROI(character->m_roi, FALSE, FALSE);
actor->FUN_100114e0(0);
@ -352,6 +352,11 @@ MxBool LegoCharacterManager::FUN_10084c00(const LegoChar*)
return FALSE;
}
// STUB: LEGO1 0x10084c40
LegoExtraActor* LegoCharacterManager::FUN_10084c40(const LegoChar*)
{
return NULL;
}
// FUNCTION: LEGO1 0x10084c60
LegoCharacterData* LegoCharacterManager::Find(const char* p_key)
{

View file

@ -1,8 +1,5 @@
#include "misc.h"
#include "legoinputmanager.h"
#include "legoomni.h"
#include "legovideomanager.h"
#include "mxbackgroundaudiomanager.h"
#include "mxmisc.h"
@ -139,6 +136,12 @@ void SetCurrentActor(IslePathActor* p_currentActor)
LegoOmni::GetInstance()->SetCurrentActor(p_currentActor);
}
// FUNCTION: LEGO1 0x100158b0
void DeleteAction()
{
LegoOmni::GetInstance()->DeleteAction();
}
// FUNCTION: LEGO1 0x100158c0
LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid)
{

View file

@ -1,5 +1,6 @@
#include "legoworld.h"
#include "islepathactor.h"
#include "legoanimationmanager.h"
#include "legoanimpresenter.h"
#include "legobuildingmanager.h"

View file

@ -771,6 +771,15 @@ MxResult LegoOmni::Start(MxDSAction* p_dsAction)
return result;
}
// FUNCTION: LEGO1 0x1005b5c0
void LegoOmni::DeleteAction()
{
if (m_action.GetObjectId() != -1) {
DeleteObject(m_action);
m_action.SetObjectId(-1);
}
}
// FUNCTION: LEGO1 0x1005b5f0
MxLong LegoOmni::Notify(MxParam& p_param)
{

View file

@ -28,7 +28,7 @@ MxResult LegoPathController::Tickle()
}
// STUB: LEGO1 0x10046770
undefined4 LegoPathController::FUN_10046770(IslePathActor* p_actor)
undefined4 LegoPathController::FUN_10046770(LegoPathActor* p_actor)
{
return 0;
}

View file

@ -21,13 +21,13 @@ Act3::~Act3()
}
// STUB: LEGO1 0x100727e0
MxBool Act3::FUN_100727e0(MxU32, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up)
MxBool Act3::FUN_100727e0(LegoPathController*, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up)
{
return FALSE;
}
// STUB: LEGO1 0x10072980
MxBool Act3::FUN_10072980(MxU32, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up)
MxBool Act3::FUN_10072980(LegoPathController*, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up)
{
return FALSE;
}