Implement/match LegoAnimPresenter::ParseExtra (#848)

* Implement/match LegoAnimPresenter::ParseExtra

* Fix
This commit is contained in:
Christian Semmler 2024-04-25 10:00:58 -04:00 committed by GitHub
parent 311b27b697
commit 916c039e72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 198 additions and 33 deletions

View file

@ -12,10 +12,26 @@ const char* g_strANIMATION = "ANIMATION";
// STRING: LEGO1 0x10102024 // STRING: LEGO1 0x10102024
const char* g_strATTACH_CAMERA = "ATTACH_CAMERA"; const char* g_strATTACH_CAMERA = "ATTACH_CAMERA";
// GLOBAL: LEGO1 0x10102080
// STRING: LEGO1 0x100f4368
const char* g_strFROM_PARENT = "FROM_PARENT";
// GLOBAL: LEGO1 0x10102084
// STRING: LEGO1 0x10101fa4
const char* g_strHIDE_ON_STOP = "HIDE_ON_STOP";
// GLOBAL: LEGO1 0x10102098
// STRING: LEGO1 0x10101f60
const char* g_strMUST_SUCCEED = "MUST_SUCCEED";
// GLOBAL: LEGO1 0x1010209c // GLOBAL: LEGO1 0x1010209c
// STRING: LEGO1 0x10101f58 // STRING: LEGO1 0x10101f58
const char* g_strOBJECT = "OBJECT"; const char* g_strOBJECT = "OBJECT";
// GLOBAL: LEGO1 0x101020a8
// STRING: LEGO1 0x10101f38
const char* g_strPTATCAM = "PTATCAM";
// GLOBAL: LEGO1 0x101020b0 // GLOBAL: LEGO1 0x101020b0
// STRING: LEGO1 0x10101f20 // STRING: LEGO1 0x10101f20
const char* g_strSOUND = "SOUND"; const char* g_strSOUND = "SOUND";
@ -28,6 +44,10 @@ const char* g_strMUTE = "MUTE";
// STRING: LEGO1 0x100f09cc // STRING: LEGO1 0x100f09cc
const char* g_strSPEED = "SPEED"; const char* g_strSPEED = "SPEED";
// GLOBAL: LEGO1 0x101020bc
// STRING: LEGO1 0x10101f10
const char* g_strSUBST = "SUBST";
// GLOBAL: LEGO1 0x101020cc // GLOBAL: LEGO1 0x101020cc
// STRING: LEGO1 0x100f3808 // STRING: LEGO1 0x100f3808
const char* g_strVISIBILITY = "VISIBILITY"; const char* g_strVISIBILITY = "VISIBILITY";

View file

@ -14,5 +14,10 @@ extern const char* g_strSPEED;
extern const char* g_strATTACH_CAMERA; extern const char* g_strATTACH_CAMERA;
extern const char* g_strMUTE; extern const char* g_strMUTE;
extern const char* g_strANIMMAN_ID; extern const char* g_strANIMMAN_ID;
extern const char* g_strFROM_PARENT;
extern const char* g_strHIDE_ON_STOP;
extern const char* g_strMUST_SUCCEED;
extern const char* g_strSUBST;
extern const char* g_strPTATCAM;
#endif // DEFINE_H #endif // DEFINE_H

View file

@ -16,6 +16,10 @@ struct LegoAnimStructComparator {
MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; } MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; }
}; };
struct LegoAnimSubstComparator {
MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; }
};
// SIZE 0x08 // SIZE 0x08
struct LegoAnimStruct { struct LegoAnimStruct {
LegoROI* m_roi; // 0x00 LegoROI* m_roi; // 0x00
@ -23,14 +27,15 @@ struct LegoAnimStruct {
}; };
typedef map<const char*, LegoAnimStruct, LegoAnimStructComparator> LegoAnimPresenterMap; typedef map<const char*, LegoAnimStruct, LegoAnimStructComparator> LegoAnimPresenterMap;
typedef map<const char*, const char*, LegoAnimSubstComparator> LegoAnimSubstMap;
// VTABLE: LEGO1 0x100d90c8 // VTABLE: LEGO1 0x100d90c8
// SIZE 0xbc // SIZE 0xbc
class LegoAnimPresenter : public MxVideoPresenter { class LegoAnimPresenter : public MxVideoPresenter {
public: public:
enum { enum {
c_bit1 = 0x01, c_hideOnStop = 0x01,
c_bit2 = 0x02 c_mustSucceed = 0x02
}; };
LegoAnimPresenter(); LegoAnimPresenter();
@ -108,15 +113,15 @@ class LegoAnimPresenter : public MxVideoPresenter {
MxMatrix* m_unk0x78; // 0x78 MxMatrix* m_unk0x78; // 0x78
MxU32 m_flags; // 0x7c MxU32 m_flags; // 0x7c
LegoWorld* m_currentWorld; // 0x80 LegoWorld* m_currentWorld; // 0x80
MxAtomId m_animAtom; // 0x84 MxAtomId m_worldAtom; // 0x84
undefined4 m_unk0x88; // 0x88 MxS32 m_worldId; // 0x88
LegoROI** m_unk0x8c; // 0x8c LegoROI** m_unk0x8c; // 0x8c
const char** m_unk0x90; // 0x90 char** m_unk0x90; // 0x90
MxU8 m_unk0x94; // 0x94 MxU8 m_unk0x94; // 0x94
undefined m_unk0x95; // 0x95 undefined m_unk0x95; // 0x95
MxBool m_unk0x96; // 0x96 MxBool m_unk0x96; // 0x96
undefined m_unk0x97; // 0x97 undefined m_unk0x97; // 0x97
undefined4 m_unk0x98; // 0x98 LegoAnimSubstMap* m_substMap; // 0x98
MxS16 m_unk0x9c; // 0x9c MxS16 m_unk0x9c; // 0x9c
undefined4 m_unk0xa0; // 0xa0 undefined4 m_unk0xa0; // 0xa0
undefined4 m_unk0xa4; // 0xa4 undefined4 m_unk0xa4; // 0xa4
@ -127,6 +132,21 @@ class LegoAnimPresenter : public MxVideoPresenter {
// SYNTHETIC: LEGO1 0x10068650 // SYNTHETIC: LEGO1 0x10068650
// LegoAnimPresenter::`scalar deleting destructor' // LegoAnimPresenter::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100689c0
// map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::~map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >
// TEMPLATE: LEGO1 0x10068a10
// _Tree<char const *,pair<char const * const,char const *>,map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::_Kfn,LegoAnimSubstComparator,allocator<char const *> >::~_Tree<char const *,pair<char const * const,char const *>,map
// TEMPLATE: LEGO1 0x10068ae0
// _Tree<char const *,pair<char const * const,char const *>,map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::_Kfn,LegoAnimSubstComparator,allocator<char const *> >::iterator::_Inc
// TEMPLATE: LEGO1 0x10068b20
// _Tree<char const *,pair<char const * const,char const *>,map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::_Kfn,LegoAnimSubstComparator,allocator<char const *> >::erase
// TEMPLATE: LEGO1 0x10068f70
// _Tree<char const *,pair<char const * const,char const *>,map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::_Kfn,LegoAnimSubstComparator,allocator<char const *> >::_Erase
// TEMPLATE: LEGO1 0x10069d80 // TEMPLATE: LEGO1 0x10069d80
// _Tree<char const *,pair<char const * const,LegoAnimStruct>,map<char const *,LegoAnimStruct,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Kfn,LegoAnimStructComparator,allocator<LegoAnimStruct> >::~_Tree<char const *,pair<char const * const,LegoAni // _Tree<char const *,pair<char const * const,LegoAnimStruct>,map<char const *,LegoAnimStruct,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Kfn,LegoAnimStructComparator,allocator<LegoAnimStruct> >::~_Tree<char const *,pair<char const * const,LegoAni
@ -151,6 +171,21 @@ class LegoAnimPresenter : public MxVideoPresenter {
// TEMPLATE: LEGO1 0x1006a7a0 // TEMPLATE: LEGO1 0x1006a7a0
// _Tree<char const *,pair<char const * const,LegoAnimStruct>,map<char const *,LegoAnimStruct,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Kfn,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Insert // _Tree<char const *,pair<char const * const,LegoAnimStruct>,map<char const *,LegoAnimStruct,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Kfn,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Insert
// TEMPLATE: LEGO1 0x1006c1b0
// _Tree<char const *,pair<char const * const,char const *>,map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::_Kfn,LegoAnimSubstComparator,allocator<char const *> >::iterator::_Dec
// TEMPLATE: LEGO1 0x1006c200
// _Tree<char const *,pair<char const * const,char const *>,map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::_Kfn,LegoAnimSubstComparator,allocator<char const *> >::_Insert
// TEMPLATE: LEGO1 0x1006c4b0
// list<char *,allocator<char *> >::~list<char *,allocator<char *> >
// TEMPLATE: LEGO1 0x1006c520
// List<char *>::~List<char *>
// GLOBAL: LEGO1 0x100f7680
// _Tree<char const *,pair<char const * const,char const *>,map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::_Kfn,LegoAnimSubstComparator,allocator<char const *> >::_Nil
// GLOBAL: LEGO1 0x100f7688 // GLOBAL: LEGO1 0x100f7688
// _Tree<char const *,pair<char const * const,LegoAnimStruct>,map<char const *,LegoAnimStruct,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Kfn,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Nil // _Tree<char const *,pair<char const * const,LegoAnimStruct>,map<char const *,LegoAnimStruct,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Kfn,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Nil
// clang-format on // clang-format on

View file

@ -3,11 +3,11 @@
#include "geom/legounkown100db7f4.h" #include "geom/legounkown100db7f4.h"
#include "legoactor.h" #include "legoactor.h"
#include "legopathboundary.h"
#include "misc/legounknown.h" #include "misc/legounknown.h"
#include "mxtypes.h" #include "mxtypes.h"
#include "realtime/matrix.h" #include "realtime/matrix.h"
class LegoPathBoundary;
class LegoPathController; class LegoPathController;
// VTABLE: LEGO1 0x100d6e28 // VTABLE: LEGO1 0x100d6e28

View file

@ -2,6 +2,7 @@
#include "legoanimationmanager.h" #include "legoanimationmanager.h"
#include "legonavcontroller.h" #include "legonavcontroller.h"
#include "legopathboundary.h"
#include "legoutils.h" #include "legoutils.h"
#include "misc.h" #include "misc.h"
#include "mxnotificationparam.h" #include "mxnotificationparam.h"

View file

@ -4,6 +4,7 @@
#include "define.h" #include "define.h"
#include "islepathactor.h" #include "islepathactor.h"
#include "legoanimationmanager.h" #include "legoanimationmanager.h"
#include "legoanimpresenter.h"
#include "legotraninfo.h" #include "legotraninfo.h"
#include "legovideomanager.h" #include "legovideomanager.h"
#include "legoworld.h" #include "legoworld.h"

View file

@ -2,6 +2,7 @@
#include "act1state.h" #include "act1state.h"
#include "islepathactor.h" #include "islepathactor.h"
#include "legoanimpresenter.h"
#include "legogamestate.h" #include "legogamestate.h"
#include "legoinputmanager.h" #include "legoinputmanager.h"
#include "legonamedtexture.h" #include "legonamedtexture.h"

View file

@ -2,6 +2,7 @@
#include "define.h" #include "define.h"
#include "legolocomotionanimpresenter.h" #include "legolocomotionanimpresenter.h"
#include "legopathboundary.h"
#include "legoworld.h" #include "legoworld.h"
#include "misc.h" #include "misc.h"
#include "mxutilities.h" #include "mxutilities.h"

View file

@ -1,6 +1,7 @@
#include "legoextraactor.h" #include "legoextraactor.h"
#include "legolocomotionanimpresenter.h" #include "legolocomotionanimpresenter.h"
#include "legopathboundary.h"
#include "legosoundmanager.h" #include "legosoundmanager.h"
#include "misc.h" #include "misc.h"
#include "mxmisc.h" #include "mxmisc.h"

View file

@ -1,6 +1,7 @@
#include "legopathactor.h" #include "legopathactor.h"
#include "legonavcontroller.h" #include "legonavcontroller.h"
#include "legopathboundary.h"
#include "legosoundmanager.h" #include "legosoundmanager.h"
#include "misc.h" #include "misc.h"
#include "mxmisc.h" #include "mxmisc.h"

View file

@ -1,8 +1,10 @@
#include "legoanimpresenter.h" #include "legoanimpresenter.h"
#include "define.h"
#include "legoanimationmanager.h" #include "legoanimationmanager.h"
#include "legoanimmmpresenter.h" #include "legoanimmmpresenter.h"
#include "legocharactermanager.h" #include "legocharactermanager.h"
#include "legopathboundary.h"
#include "legovideomanager.h" #include "legovideomanager.h"
#include "legoworld.h" #include "legoworld.h"
#include "misc.h" #include "misc.h"
@ -13,6 +15,7 @@
#include "mxstreamchunk.h" #include "mxstreamchunk.h"
#include "mxtimer.h" #include "mxtimer.h"
#include "mxtype18notificationparam.h" #include "mxtype18notificationparam.h"
#include "mxutilities.h"
#include "mxvideomanager.h" #include "mxvideomanager.h"
#include "realtime/realtime.h" #include "realtime/realtime.h"
@ -44,9 +47,9 @@ void LegoAnimPresenter::Init()
m_unk0xa4 = 0; m_unk0xa4 = 0;
m_currentWorld = NULL; m_currentWorld = NULL;
m_unk0x95 = 0; m_unk0x95 = 0;
m_unk0x88 = -1; m_worldId = -1;
m_unk0x98 = 0; m_substMap = NULL;
m_animAtom.Clear(); m_worldAtom.Clear();
m_unk0x9c = 0; m_unk0x9c = 0;
m_unk0x8c = NULL; m_unk0x8c = NULL;
m_unk0x90 = NULL; m_unk0x90 = NULL;
@ -645,7 +648,7 @@ void LegoAnimPresenter::StartingTickle()
FUN_100692b0(); FUN_100692b0();
FUN_100695c0(); FUN_100695c0();
if (m_flags & c_bit2 && !FUN_1006aba0()) { if (m_flags & c_mustSucceed && !FUN_1006aba0()) {
goto done; goto done;
} }
@ -799,10 +802,106 @@ void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p
LegoROI::FUN_100a8e80(root, mat, p_time, m_roiMap); LegoROI::FUN_100a8e80(root, mat, p_time, m_roiMap);
} }
// STUB: LEGO1 0x1006bac0 // FUNCTION: LEGO1 0x1006bac0
// FUNCTION: BETA10 0x100512e1
void LegoAnimPresenter::ParseExtra() void LegoAnimPresenter::ParseExtra()
{ {
// TODO MxU16 extraLength;
char* extraData;
m_action->GetExtra(extraLength, extraData);
if (extraLength & MAXWORD) {
char extraCopy[256];
memcpy(extraCopy, extraData, extraLength & MAXWORD);
extraCopy[extraLength & MAXWORD] = '\0';
char output[256];
if (KeyValueStringParse(NULL, g_strFROM_PARENT, extraCopy) && m_compositePresenter != NULL) {
m_compositePresenter->GetAction()->GetExtra(extraLength, extraData);
if (extraLength & MAXWORD) {
memcpy(extraCopy, extraData, extraLength & MAXWORD);
extraCopy[extraLength & MAXWORD] = '\0';
}
}
if (KeyValueStringParse(output, g_strHIDE_ON_STOP, extraCopy)) {
m_flags |= c_hideOnStop;
}
if (KeyValueStringParse(output, g_strMUST_SUCCEED, extraCopy)) {
m_flags |= c_mustSucceed;
}
if (KeyValueStringParse(output, g_strSUBST, extraCopy)) {
m_substMap = new LegoAnimSubstMap();
char* substToken = output;
char *key, *value;
while ((key = strtok(substToken, g_parseExtraTokens))) {
substToken = NULL;
if ((value = strtok(NULL, g_parseExtraTokens))) {
char* keyCopy = new char[strlen(key) + 1];
strcpy(keyCopy, key);
char* valueCopy = new char[strlen(value) + 1];
strcpy(valueCopy, value);
(*m_substMap)[keyCopy] = valueCopy;
}
}
}
if (KeyValueStringParse(output, g_strWORLD, extraCopy)) {
char* token = strtok(output, g_parseExtraTokens);
m_worldAtom = MxAtomId(token, e_lowerCase2);
token = strtok(NULL, g_parseExtraTokens);
m_worldId = atoi(token);
}
if (KeyValueStringParse(output, g_strPTATCAM, extraCopy)) {
list<char*> tmp;
if (m_unk0x90 != NULL) {
for (MxS32 i = 0; i < m_unk0x94; i++) {
if (m_unk0x90[i] != NULL) {
// (modernization) critical bug: wrong free
delete[] m_unk0x90;
}
}
delete[] m_unk0x90;
m_unk0x90 = NULL;
}
if (m_unk0x8c != NULL) {
delete[] m_unk0x8c;
m_unk0x8c = NULL;
}
char* token = strtok(output, g_parseExtraTokens);
while (token != NULL) {
char* valueCopy = new char[strlen(token) + 1];
strcpy(valueCopy, token);
tmp.push_back(valueCopy);
token = strtok(NULL, g_parseExtraTokens);
}
m_unk0x94 = tmp.size();
if (m_unk0x94 != 0) {
m_unk0x8c = new LegoROI*[m_unk0x94];
m_unk0x90 = new char*[m_unk0x94];
memset(m_unk0x8c, 0, sizeof(*m_unk0x8c) * m_unk0x94);
memset(m_unk0x90, 0, sizeof(*m_unk0x90) * m_unk0x94);
MxS32 i = 0;
for (list<char*>::iterator it = tmp.begin(); it != tmp.end(); it++, i++) {
m_unk0x90[i] = *it;
}
}
}
}
} }
// FUNCTION: LEGO1 0x1006c570 // FUNCTION: LEGO1 0x1006c570
@ -845,7 +944,7 @@ void LegoAnimPresenter::EndAction()
FUN_1006b9a0(m_anim, m_anim->GetDuration(), m_unk0x78); FUN_1006b9a0(m_anim, m_anim->GetDuration(), m_unk0x78);
} }
if (m_roiMapSize != 0 && m_roiMap != NULL && m_roiMap[1] != NULL && m_flags & c_bit1) { if (m_roiMapSize != 0 && m_roiMap != NULL && m_roiMap[1] != NULL && m_flags & c_hideOnStop) {
for (MxS16 i = 1; i <= m_roiMapSize; i++) { for (MxS16 i = 1; i <= m_roiMapSize; i++) {
if (m_roiMap[i] != NULL) { if (m_roiMap[i] != NULL) {
m_roiMap[i]->SetVisibility(FALSE); m_roiMap[i]->SetVisibility(FALSE);
@ -876,7 +975,7 @@ void LegoAnimPresenter::VTable0x8c()
} }
if (m_currentWorld == NULL) { if (m_currentWorld == NULL) {
m_currentWorld = m_unk0x88 != -1 ? FindWorld(m_animAtom, m_unk0x88) : CurrentWorld(); m_currentWorld = m_worldId != -1 ? FindWorld(m_worldAtom, m_worldId) : CurrentWorld();
} }
if (m_currentWorld) { if (m_currentWorld) {

View file

@ -58,7 +58,7 @@ MxResult ModelDbPart::Read(FILE* p_file)
return FAILURE; return FAILURE;
} }
// Critical bug: buffer overrun // (modernization) critical bug: buffer overrun
if (fread(buff, len, 1, p_file) != 1) { if (fread(buff, len, 1, p_file) != 1) {
return FAILURE; return FAILURE;
} }