Implement AnimState (#1042)

* Implement LegoAnim

* fix: minor issues

* fix ncc complaints

* refactor: address review comments

---------

Co-authored-by: jonschz <jonschz@users.noreply.github.com>
This commit is contained in:
jonschz 2024-06-21 20:41:01 +02:00 committed by GitHub
parent 1d666f62e5
commit c9c130eb87
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 102 additions and 41 deletions

View file

@ -71,22 +71,23 @@ class AnimState : public LegoState {
MxBool SetFlag() override; // vtable+0x18 MxBool SetFlag() override; // vtable+0x18
MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
void FUN_100651d0(MxU32, AnimInfo*, MxU32&); void CopyToAnims(MxU32, AnimInfo* p_anims, MxU32& p_outExtraCharacterId);
void FUN_10065240(MxU32, AnimInfo*, MxU32); void InitFromAnims(MxU32 p_animsLength, AnimInfo* p_anims, MxU32 p_extraCharacterId);
// SYNTHETIC: LEGO1 0x10065130 // SYNTHETIC: LEGO1 0x10065130
// AnimState::`scalar deleting destructor' // AnimState::`scalar deleting destructor'
private: private:
undefined4 m_unk0x08; // 0x08 MxU32 m_extraCharacterId; // 0x08
// appears to store the length of m_unk0x10 // appears to store the length of m_unk0x10
undefined4 m_unk0x0c; // 0x0c MxU32 m_unk0x0c; // 0x0c
// dynamically sized array of two-byte elements // dynamically sized array of MxU16, corresponding to AnimInfo::m_unk0x22
undefined2* m_unk0x10; // 0x10 MxU16* m_unk0x10; // 0x10
// appears to store the length of m_unk0x18
undefined4 m_unk0x14; // 0x14 MxU32 m_locationsFlagsLength; // 0x14
// dynamically sized array of one-byte elements // dynamically sized array of bools, corresponding to LegoLocation.m_unk0x5c
undefined* m_unk0x18; // 0x18 MxBool* m_locationsFlags; // 0x18
}; };
// VTABLE: LEGO1 0x100d8c18 // VTABLE: LEGO1 0x100d8c18

View file

@ -74,6 +74,7 @@ class LegoNavController : public MxCore {
); );
static MxResult UpdateLocation(MxU32 p_location); static MxResult UpdateLocation(MxU32 p_location);
static MxResult UpdateLocation(const char* p_location); static MxResult UpdateLocation(const char* p_location);
static MxS32 GetNumLocations();
static LegoLocation* GetLocation(MxU32 p_location); static LegoLocation* GetLocation(MxU32 p_location);
inline void SetLinearVel(MxFloat p_linearVel) { m_linearVel = p_linearVel; } inline void SetLinearVel(MxFloat p_linearVel) { m_linearVel = p_linearVel; }

View file

@ -416,7 +416,7 @@ void LegoAnimationManager::Suspend()
} }
if (m_worldId == 0) { if (m_worldId == 0) {
m_animState->FUN_10065240(m_animCount, m_anims, m_lastExtraCharacterId); m_animState->InitFromAnims(m_animCount, m_anims, m_lastExtraCharacterId);
} }
if (!m_suspended) { if (!m_suspended) {
@ -615,7 +615,7 @@ MxResult LegoAnimationManager::LoadWorldInfo(MxS32 p_worldId)
} }
if (m_worldId == 0) { if (m_worldId == 0) {
m_animState->FUN_10065240(m_animCount, m_anims, m_lastExtraCharacterId); m_animState->InitFromAnims(m_animCount, m_anims, m_lastExtraCharacterId);
} }
DeleteAnimations(); DeleteAnimations();
@ -727,7 +727,7 @@ MxResult LegoAnimationManager::LoadWorldInfo(MxS32 p_worldId)
} }
if (p_worldId == 0) { if (p_worldId == 0) {
m_animState->FUN_100651d0(m_animCount, m_anims, m_lastExtraCharacterId); m_animState->CopyToAnims(m_animCount, m_anims, m_lastExtraCharacterId);
} }
} }
@ -2828,26 +2828,59 @@ AnimState::AnimState()
{ {
m_unk0x0c = 0; m_unk0x0c = 0;
m_unk0x10 = NULL; m_unk0x10 = NULL;
m_unk0x14 = 0; m_locationsFlagsLength = 0;
m_unk0x18 = NULL; m_locationsFlags = NULL;
} }
// STUB: LEGO1 0x10065150 // FUNCTION: LEGO1 0x10065150
AnimState::~AnimState() AnimState::~AnimState()
{ {
// TODO delete[] m_unk0x10;
delete[] m_locationsFlags;
} }
// STUB: LEGO1 0x100651d0 // FUNCTION: LEGO1 0x100651d0
void AnimState::FUN_100651d0(MxU32, AnimInfo*, MxU32&) void AnimState::CopyToAnims(MxU32, AnimInfo* p_anims, MxU32& p_outExtraCharacterId)
{ {
// TODO if (m_unk0x10 != NULL) {
for (MxS32 i = 0; i < m_unk0x0c; i++) {
p_anims[i].m_unk0x22 = m_unk0x10[i];
}
p_outExtraCharacterId = m_extraCharacterId;
for (MxS32 j = 0; j < m_locationsFlagsLength; j++) {
LegoLocation* location = LegoNavController::GetLocation(j);
if (location != NULL) {
location->m_unk0x5c = m_locationsFlags[j];
}
}
}
} }
// STUB: LEGO1 0x10065240 // FUNCTION: LEGO1 0x10065240
void AnimState::FUN_10065240(MxU32, AnimInfo*, MxU32) void AnimState::InitFromAnims(MxU32 p_animsLength, AnimInfo* p_anims, MxU32 p_extraCharacterId)
{ {
// TODO if (m_unk0x10 == NULL) {
m_unk0x0c = p_animsLength;
m_unk0x10 = new MxU16[p_animsLength];
MxS32 numLocations = LegoNavController::GetNumLocations();
m_locationsFlagsLength = numLocations;
m_locationsFlags = new MxBool[numLocations];
}
m_extraCharacterId = p_extraCharacterId;
for (MxS32 i = 0; i < m_unk0x0c; i++) {
m_unk0x10[i] = p_anims[i].m_unk0x22;
}
for (MxS32 j = 0; j < m_locationsFlagsLength; j++) {
LegoLocation* location = LegoNavController::GetLocation(j);
if (location != NULL) {
m_locationsFlags[j] = location->m_unk0x5c;
}
}
} }
// FUNCTION: LEGO1 0x100652d0 // FUNCTION: LEGO1 0x100652d0
@ -2864,57 +2897,77 @@ MxResult AnimState::Serialize(LegoFile* p_file)
} }
if (p_file->IsReadMode()) { if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x08); Read(p_file, &m_extraCharacterId);
// m_unk0x10_len and m_unk0x10
if (m_unk0x10) { if (m_unk0x10) {
delete[] m_unk0x10; delete[] m_unk0x10;
} }
Read(p_file, &m_unk0x0c); Read(p_file, &m_unk0x0c);
if (m_unk0x0c != 0) { if (m_unk0x0c != 0) {
m_unk0x10 = new undefined2[m_unk0x0c]; m_unk0x10 = new MxU16[m_unk0x0c];
} }
else { else {
m_unk0x10 = NULL; m_unk0x10 = NULL;
} }
for (MxS32 i = 0; i < m_unk0x0c; i++) { for (MxS32 i = 0; i < m_unk0x0c; i++) {
Read(p_file, &m_unk0x10[i]); Read(p_file, &m_unk0x10[i]);
} }
// m_unk0x18_len and m_unk0x18
// Note that here we read first and then free memory in contrast to above // Note that here we read first and then free memory in contrast to above
Read(p_file, &m_unk0x14); Read(p_file, &m_locationsFlagsLength);
if (m_unk0x18) {
delete[] m_unk0x18; if (m_locationsFlags) {
delete[] m_locationsFlags;
} }
if (m_unk0x14 != 0) {
m_unk0x18 = new undefined[m_unk0x14]; if (m_locationsFlagsLength != 0) {
m_locationsFlags = new MxBool[m_locationsFlagsLength];
} }
else { else {
m_unk0x18 = NULL; m_locationsFlags = NULL;
} }
for (MxS32 j = 0; j < m_unk0x14; j++) {
Read(p_file, &m_unk0x18[j]); for (MxS32 j = 0; j < m_locationsFlagsLength; j++) {
Read(p_file, &m_locationsFlags[j]);
} }
} }
else if (p_file->IsWriteMode()) { else if (p_file->IsWriteMode()) {
Write(p_file, m_unk0x08); Write(p_file, m_extraCharacterId);
Write(p_file, m_unk0x0c); Write(p_file, m_unk0x0c);
for (MxS32 i = 0; i < m_unk0x0c; i++) { for (MxS32 i = 0; i < m_unk0x0c; i++) {
Write(p_file, m_unk0x10[i]); Write(p_file, m_unk0x10[i]);
} }
Write(p_file, m_unk0x14);
for (MxS32 j = 0; j < m_unk0x14; j++) { Write(p_file, m_locationsFlagsLength);
Write(p_file, m_unk0x18[j]); for (MxS32 j = 0; j < m_locationsFlagsLength; j++) {
Write(p_file, m_locationsFlags[j]);
} }
} }
return SUCCESS; return SUCCESS;
} }
// STUB: LEGO1 0x100654f0 // FUNCTION: LEGO1 0x100654f0
MxBool AnimState::SetFlag() MxBool AnimState::SetFlag()
{ {
// TODO if (m_unk0x10 != NULL) {
m_extraCharacterId = NULL;
for (MxS32 i = 0; i < m_unk0x0c; i++) {
m_unk0x10[i] = 0;
}
for (MxS32 j = 0; j < m_locationsFlagsLength; j++) {
if (LegoNavController::GetLocation(j) != NULL) {
m_locationsFlags[j] = 0;
}
}
return TRUE;
}
return FALSE; return FALSE;
} }

View file

@ -482,6 +482,12 @@ LegoLocation* LegoNavController::GetLocation(MxU32 p_location)
return NULL; return NULL;
} }
// FUNCTION: LEGO1 0x10055740
MxS32 LegoNavController::GetNumLocations()
{
return sizeOfArray(g_locations);
}
// FUNCTION: LEGO1 0x10055750 // FUNCTION: LEGO1 0x10055750
MxResult LegoNavController::ProcessJoystickInput(MxBool& p_und) MxResult LegoNavController::ProcessJoystickInput(MxBool& p_und)
{ {