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

View file

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

View file

@ -416,7 +416,7 @@ void LegoAnimationManager::Suspend()
}
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) {
@ -615,7 +615,7 @@ MxResult LegoAnimationManager::LoadWorldInfo(MxS32 p_worldId)
}
if (m_worldId == 0) {
m_animState->FUN_10065240(m_animCount, m_anims, m_lastExtraCharacterId);
m_animState->InitFromAnims(m_animCount, m_anims, m_lastExtraCharacterId);
}
DeleteAnimations();
@ -727,7 +727,7 @@ MxResult LegoAnimationManager::LoadWorldInfo(MxS32 p_worldId)
}
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_unk0x10 = NULL;
m_unk0x14 = 0;
m_unk0x18 = NULL;
m_locationsFlagsLength = 0;
m_locationsFlags = NULL;
}
// STUB: LEGO1 0x10065150
// FUNCTION: LEGO1 0x10065150
AnimState::~AnimState()
{
// TODO
delete[] m_unk0x10;
delete[] m_locationsFlags;
}
// STUB: LEGO1 0x100651d0
void AnimState::FUN_100651d0(MxU32, AnimInfo*, MxU32&)
// FUNCTION: LEGO1 0x100651d0
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
void AnimState::FUN_10065240(MxU32, AnimInfo*, MxU32)
// FUNCTION: LEGO1 0x10065240
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
@ -2864,57 +2897,77 @@ MxResult AnimState::Serialize(LegoFile* p_file)
}
if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x08);
Read(p_file, &m_extraCharacterId);
// m_unk0x10_len and m_unk0x10
if (m_unk0x10) {
delete[] m_unk0x10;
}
Read(p_file, &m_unk0x0c);
if (m_unk0x0c != 0) {
m_unk0x10 = new undefined2[m_unk0x0c];
m_unk0x10 = new MxU16[m_unk0x0c];
}
else {
m_unk0x10 = NULL;
}
for (MxS32 i = 0; i < m_unk0x0c; 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
Read(p_file, &m_unk0x14);
if (m_unk0x18) {
delete[] m_unk0x18;
Read(p_file, &m_locationsFlagsLength);
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 {
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()) {
Write(p_file, m_unk0x08);
Write(p_file, m_extraCharacterId);
Write(p_file, m_unk0x0c);
for (MxS32 i = 0; i < m_unk0x0c; i++) {
Write(p_file, m_unk0x10[i]);
}
Write(p_file, m_unk0x14);
for (MxS32 j = 0; j < m_unk0x14; j++) {
Write(p_file, m_unk0x18[j]);
Write(p_file, m_locationsFlagsLength);
for (MxS32 j = 0; j < m_locationsFlagsLength; j++) {
Write(p_file, m_locationsFlags[j]);
}
}
return SUCCESS;
}
// STUB: LEGO1 0x100654f0
// FUNCTION: LEGO1 0x100654f0
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;
}

View file

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