Merge branch 'master' into animpresenter-destroy

This commit is contained in:
Christian Semmler 2024-04-25 10:03:38 -04:00
commit d0cf3976ee
33 changed files with 591 additions and 109 deletions

View File

@ -12,10 +12,26 @@ const char* g_strANIMATION = "ANIMATION";
// STRING: LEGO1 0x10102024
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
// STRING: LEGO1 0x10101f58
const char* g_strOBJECT = "OBJECT";
// GLOBAL: LEGO1 0x101020a8
// STRING: LEGO1 0x10101f38
const char* g_strPTATCAM = "PTATCAM";
// GLOBAL: LEGO1 0x101020b0
// STRING: LEGO1 0x10101f20
const char* g_strSOUND = "SOUND";
@ -28,6 +44,10 @@ const char* g_strMUTE = "MUTE";
// STRING: LEGO1 0x100f09cc
const char* g_strSPEED = "SPEED";
// GLOBAL: LEGO1 0x101020bc
// STRING: LEGO1 0x10101f10
const char* g_strSUBST = "SUBST";
// GLOBAL: LEGO1 0x101020cc
// STRING: LEGO1 0x100f3808
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_strMUTE;
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

View File

@ -8,6 +8,9 @@
#include "legotraninfolist.h"
#include "mxcore.h"
class LegoAnimPresenter;
class LegoROIList;
// SIZE 0x18
struct Character {
char* m_name; // 0x00
@ -92,6 +95,8 @@ class LegoAnimationManager : public MxCore {
void FUN_10062770();
void FUN_100627d0(MxBool);
void FUN_100629b0(MxU32, MxBool);
void FUN_10063270(LegoROIList*, LegoAnimPresenter*);
void FUN_10063780(LegoROIList*);
void FUN_10064670(MxBool);
void FUN_10064740(MxBool);

View File

@ -10,11 +10,16 @@
class LegoWorld;
class LegoAnimClass;
class LegoAnimActor;
class LegoPathBoundary;
struct LegoAnimStructComparator {
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
struct LegoAnimStruct {
LegoROI* m_roi; // 0x00
@ -22,14 +27,15 @@ struct LegoAnimStruct {
};
typedef map<const char*, LegoAnimStruct, LegoAnimStructComparator> LegoAnimPresenterMap;
typedef map<const char*, const char*, LegoAnimSubstComparator> LegoAnimSubstMap;
// VTABLE: LEGO1 0x100d90c8
// SIZE 0xbc
class LegoAnimPresenter : public MxVideoPresenter {
public:
enum {
c_bit1 = 0x01,
c_bit2 = 0x02
c_hideOnStop = 0x01,
c_mustSucceed = 0x02
};
LegoAnimPresenter();
@ -62,7 +68,7 @@ class LegoAnimPresenter : public MxVideoPresenter {
virtual void VTable0x8c(); // vtable+0x8c
virtual void VTable0x90(); // vtable+0x90
virtual MxResult VTable0x94(Vector3&, Vector3&, float, float, Vector3&); // vtable+0x94
virtual void VTable0x98(); // vtable+0x98
virtual MxResult VTable0x98(LegoPathBoundary* p_boundary); // vtable+0x98
// FUNCTION: LEGO1 0x1000c990
virtual LegoROI** GetROIMap(MxU32& p_roiMapSize)
@ -71,16 +77,14 @@ class LegoAnimPresenter : public MxVideoPresenter {
return m_roiMap;
} // vtable+0x9c
virtual void VTable0xa0(Matrix4*); // vtable+0xa0
virtual void VTable0xa0(Matrix4& p_matrix); // vtable+0xa0
MxResult FUN_1006afc0(MxMatrix*&, undefined4);
MxResult FUN_1006afc0(MxMatrix*& p_matrix, float p_und);
MxResult FUN_1006b140(LegoROI* p_roi);
void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value);
const char* GetActionObjectName();
inline LegoAnim* GetAnimation() { return m_anim; }
const char* GetActionObjectName();
protected:
void Init();
void Destroy(MxBool p_fromDestructor);
@ -98,36 +102,52 @@ class LegoAnimPresenter : public MxVideoPresenter {
LegoBool FUN_1006aba0();
MxBool FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi);
void FUN_1006ac90();
void FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix);
void FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix);
void FUN_1006c8a0(MxBool p_bool);
LegoAnim* m_anim; // 0x64
LegoROI** m_roiMap; // 0x68
MxU32 m_roiMapSize; // 0x6c
LegoROIList* m_unk0x70; // 0x70
LegoROIList* m_unk0x74; // 0x74
MxMatrix* m_unk0x78; // 0x78
MxU32 m_flags; // 0x7c
LegoWorld* m_currentWorld; // 0x80
MxAtomId m_animAtom; // 0x84
undefined4 m_unk0x88; // 0x88
LegoROI** m_unk0x8c; // 0x8c
char** m_unk0x90; // 0x90
MxU8 m_unk0x94; // 0x94
undefined m_unk0x95; // 0x95
MxBool m_unk0x96; // 0x96
undefined m_unk0x97; // 0x97
undefined4 m_unk0x98; // 0x98
MxS16 m_unk0x9c; // 0x9c
undefined4* m_unk0xa0; // 0xa0
undefined4 m_unk0xa4; // 0xa4
Mx3DPointFloat m_unk0xa8; // 0xa8
LegoAnim* m_anim; // 0x64
LegoROI** m_roiMap; // 0x68
MxU32 m_roiMapSize; // 0x6c
LegoROIList* m_unk0x70; // 0x70
LegoROIList* m_unk0x74; // 0x74
MxMatrix* m_unk0x78; // 0x78
MxU32 m_flags; // 0x7c
LegoWorld* m_currentWorld; // 0x80
MxAtomId m_worldAtom; // 0x84
MxS32 m_worldId; // 0x88
LegoROI** m_unk0x8c; // 0x8c
char** m_unk0x90; // 0x90
MxU8 m_unk0x94; // 0x94
undefined m_unk0x95; // 0x95
MxBool m_unk0x96; // 0x96
undefined m_unk0x97; // 0x97
LegoAnimSubstMap* m_substMap; // 0x98
MxS16 m_unk0x9c; // 0x9c
undefined4* m_unk0xa0; // 0xa0
undefined4 m_unk0xa4; // 0xa4
Mx3DPointFloat m_unk0xa8; // 0xa8
};
// clang-format off
// SYNTHETIC: LEGO1 0x10068650
// 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
// _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
@ -152,6 +172,21 @@ class LegoAnimPresenter : public MxVideoPresenter {
// TEMPLATE: LEGO1 0x1006a7a0
// _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
// _Tree<char const *,pair<char const * const,LegoAnimStruct>,map<char const *,LegoAnimStruct,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Kfn,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Nil
// clang-format on

View File

@ -2,7 +2,6 @@
#define LEGOEXTRAACTOR_H
#include "legoanimactor.h"
#include "legoanimpresenter.h"
// VTABLE: LEGO1 0x100d6c00 LegoAnimActor
// VTABLE: LEGO1 0x100d6c10 LegoPathActor

View File

@ -35,6 +35,8 @@ class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter {
// SYNTHETIC: LEGO1 0x1006cfe0
// LegoLocomotionAnimPresenter::`scalar deleting destructor'
void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value);
inline void DecrementUnknown0xd4()
{
if (m_unk0xd4) {

View File

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

View File

@ -5,6 +5,7 @@
#include "legopathactor.h"
#include "mxcore.h"
class LegoAnimPresenter;
class LegoPathBoundary;
class LegoWorld;
@ -41,6 +42,8 @@ class LegoPathController : public MxCore {
virtual void Destroy(); // vtable+0x18
undefined4 FUN_10046770(LegoPathActor* p_actor);
void FUN_100468f0(LegoAnimPresenter* p_presenter);
void FUN_10046930(LegoAnimPresenter* p_presenter);
MxResult FUN_10046b30(LegoPathBoundary** p_path, MxS32& p_value);
void Enable(MxBool p_enable);
void FUN_10046bb0(LegoWorld* p_world);

View File

@ -12,12 +12,14 @@
// class MxList<LegoPhoneme *>
// VTABLE: LEGO1 0x100d9d00
// VTABLE: BETA10 0x101bef58
// SIZE 0x18
class LegoPhonemeList : public MxList<LegoPhoneme*> {
public:
LegoPhonemeList() { SetDestroy(Destroy); }
// FUNCTION: LEGO1 0x1007b210
// FUNCTION: BETA10 0x100d8340
MxS8 Compare(LegoPhoneme* p_a, LegoPhoneme* p_b) override
{
MxString a(p_a->GetName());

View File

@ -75,6 +75,7 @@ class LegoWorld : public LegoEntity {
);
void FUN_1001fc80(IslePathActor* p_actor);
void FUN_1001fda0(LegoAnimPresenter* p_presenter);
void FUN_1001fe90(LegoAnimPresenter* p_presenter);
void AddPath(LegoPathController* p_controller);
MxResult GetCurrPathInfo(LegoPathBoundary** p_path, MxS32& p_value);
MxCore* Find(const char* p_class, const char* p_name);

View File

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

View File

@ -621,6 +621,18 @@ void LegoAnimationManager::FUN_100629b0(MxU32, MxBool)
// TODO
}
// STUB: LEGO1 0x10063270
void LegoAnimationManager::FUN_10063270(LegoROIList*, LegoAnimPresenter*)
{
// TODO
}
// STUB: LEGO1 0x10063780
void LegoAnimationManager::FUN_10063780(LegoROIList*)
{
// TODO
}
// STUB: LEGO1 0x10064670
void LegoAnimationManager::FUN_10064670(MxBool)
{

View File

@ -4,6 +4,7 @@
#include "define.h"
#include "islepathactor.h"
#include "legoanimationmanager.h"
#include "legoanimpresenter.h"
#include "legotraninfo.h"
#include "legovideomanager.h"
#include "legoworld.h"
@ -149,7 +150,7 @@ void LegoAnimMMPresenter::ReadyTickle()
}
if (m_tranInfo != NULL && m_tranInfo->m_unk0x0c != NULL) {
m_presenter->VTable0xa0(m_tranInfo->m_unk0x0c);
m_presenter->VTable0xa0(*m_tranInfo->m_unk0x0c);
}
if (m_presenter != NULL) {

View File

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

View File

@ -68,12 +68,13 @@ const char* g_nick = "Nick";
const char* g_laura = "Laura";
// FUNCTION: LEGO1 0x10037d00
// FUNCTION: BETA10 0x100d5620
void VisibilityVariable::SetValue(const char* p_value)
{
MxVariable::SetValue(p_value);
if (p_value) {
char* instruction = strtok(m_value.GetDataPtr(), g_delimiter2);
char* instruction = strtok(m_value.GetData(), g_delimiter2);
char* name = strtok(NULL, g_delimiter2);
MxBool show;

View File

@ -299,10 +299,28 @@ void LegoWorld::FUN_1001fc80(IslePathActor* p_actor)
}
}
// STUB: LEGO1 0x1001fda0
// FUNCTION: LEGO1 0x1001fda0
// FUNCTION: BETA10 0x100da621
void LegoWorld::FUN_1001fda0(LegoAnimPresenter* p_presenter)
{
// TODO
LegoPathControllerListCursor cursor(&m_list0x68);
LegoPathController* controller;
while (cursor.Next(controller)) {
controller->FUN_100468f0(p_presenter);
}
}
// FUNCTION: LEGO1 0x1001fe90
// FUNCTION: BETA10 0x100da6b5
void LegoWorld::FUN_1001fe90(LegoAnimPresenter* p_presenter)
{
LegoPathControllerListCursor cursor(&m_list0x68);
LegoPathController* controller;
while (cursor.Next(controller)) {
controller->FUN_10046930(p_presenter);
}
}
// FUNCTION: LEGO1 0x1001ff80

View File

@ -1,7 +1,8 @@
#include "legoanimactor.h"
#include "define.h"
#include "legoanimpresenter.h"
#include "legolocomotionanimpresenter.h"
#include "legopathboundary.h"
#include "legoworld.h"
#include "misc.h"
#include "mxutilities.h"
@ -200,7 +201,8 @@ void LegoAnimActor::ParseAction(char* p_extra)
char* token = strtok(value, g_parseExtraTokens);
while (token) {
LegoAnimPresenter* presenter = (LegoAnimPresenter*) world->Find("LegoAnimPresenter", token);
LegoLocomotionAnimPresenter* presenter =
(LegoLocomotionAnimPresenter*) world->Find("LegoAnimPresenter", token);
if (presenter != NULL) {
token = strtok(NULL, g_parseExtraTokens);

View File

@ -1,5 +1,7 @@
#include "legoextraactor.h"
#include "legolocomotionanimpresenter.h"
#include "legopathboundary.h"
#include "legosoundmanager.h"
#include "misc.h"
#include "mxmisc.h"
@ -11,10 +13,10 @@ DECOMP_SIZE_ASSERT(LegoExtraActor, 0x1dc)
LegoWorld* g_unk0x100f31d0 = NULL;
// GLOBAL: LEGO1 0x100f31d4
LegoAnimPresenter* m_assAnimP = NULL;
LegoLocomotionAnimPresenter* m_assAnimP = NULL;
// GLOBAL: LEGO1 0x100f31d8
LegoAnimPresenter* m_disAnimP = NULL;
LegoLocomotionAnimPresenter* m_disAnimP = NULL;
// GLOBAL: LEGO1 0x100f31dc
MxS32 g_unk0x100f31dc = 0;
@ -156,8 +158,8 @@ inline void LegoExtraActor::FUN_1002ad8a()
if (g_unk0x100f31d0 != w) {
g_unk0x100f31d0 = w;
m_assAnimP = (LegoAnimPresenter*) w->Find("LegoAnimPresenter", "BNsAss01");
m_disAnimP = (LegoAnimPresenter*) w->Find("LegoAnimPresenter", "BNsDis01");
m_assAnimP = (LegoLocomotionAnimPresenter*) w->Find("LegoAnimPresenter", "BNsAss01");
m_disAnimP = (LegoLocomotionAnimPresenter*) w->Find("LegoAnimPresenter", "BNsDis01");
}
if (!m_assAnim) {

View File

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

View File

@ -33,6 +33,18 @@ undefined4 LegoPathController::FUN_10046770(LegoPathActor* p_actor)
return 0;
}
// STUB: LEGO1 0x100468f0
// FUNCTION: BETA10 0x100b72f7
void LegoPathController::FUN_100468f0(LegoAnimPresenter* p_presenter)
{
}
// STUB: LEGO1 0x10046930
// FUNCTION: BETA10 0x100b737b
void LegoPathController::FUN_10046930(LegoAnimPresenter* p_presenter)
{
}
// STUB: LEGO1 0x10046b30
MxResult LegoPathController::FUN_10046b30(LegoPathBoundary** p_path, MxS32& p_value)
{

View File

@ -1,7 +1,10 @@
#include "legoanimpresenter.h"
#include "define.h"
#include "legoanimationmanager.h"
#include "legoanimmmpresenter.h"
#include "legocharactermanager.h"
#include "legopathboundary.h"
#include "legovideomanager.h"
#include "legoworld.h"
#include "misc.h"
@ -13,6 +16,7 @@
#include "mxstreamchunk.h"
#include "mxtimer.h"
#include "mxtype18notificationparam.h"
#include "mxutilities.h"
#include "mxvideomanager.h"
#include "realtime/realtime.h"
@ -44,9 +48,9 @@ void LegoAnimPresenter::Init()
m_unk0xa4 = 0;
m_currentWorld = NULL;
m_unk0x95 = 0;
m_unk0x88 = -1;
m_unk0x98 = 0;
m_animAtom.Clear();
m_worldId = -1;
m_substMap = NULL;
m_worldAtom.Clear();
m_unk0x9c = 0;
m_unk0x8c = NULL;
m_unk0x90 = NULL;
@ -505,10 +509,15 @@ void LegoAnimPresenter::FUN_1006aa60()
// TODO
}
// STUB: LEGO1 0x1006ab70
// FUNCTION: LEGO1 0x1006ab70
void LegoAnimPresenter::FUN_1006ab70()
{
// TODO
if (m_unk0x96) {
AnimationManager()->FUN_10063270(m_unk0x74, this);
}
else {
AnimationManager()->FUN_10063780(m_unk0x74);
}
}
// FUNCTION: LEGO1 0x1006aba0
@ -627,11 +636,32 @@ void LegoAnimPresenter::PutFrame()
}
}
// STUB: LEGO1 0x1006afc0
// FUNCTION: LEGO1 0x1006afc0
// FUNCTION: BETA10 0x1005059a
MxResult LegoAnimPresenter::FUN_1006afc0(MxMatrix*&, undefined4)
MxResult LegoAnimPresenter::FUN_1006afc0(MxMatrix*& p_matrix, float p_und)
{
// TODO
MxU32 length = m_roiMapSize + 1;
p_matrix = new MxMatrix[length];
MxS32 i;
for (i = 1; i < length; i++) {
if (m_roiMap[i] != NULL) {
p_matrix[i] = m_roiMap[i]->GetLocal2World();
}
}
FUN_1006b900(m_anim, p_und, m_unk0x78);
for (i = 1; i < length; i++) {
MxMatrix mat;
if (m_roiMap[i] != NULL) {
mat = p_matrix[i];
p_matrix[i] = m_roiMap[i]->GetLocal2World();
m_roiMap[i]->FUN_100a58f0(mat);
}
}
return SUCCESS;
}
@ -674,7 +704,7 @@ void LegoAnimPresenter::StartingTickle()
FUN_100692b0();
FUN_100695c0();
if (m_flags & c_bit2 && !FUN_1006aba0()) {
if (m_flags & c_mustSucceed && !FUN_1006aba0()) {
goto done;
}
@ -770,6 +800,31 @@ const char* LegoAnimPresenter::GetActionObjectName()
return m_action->GetObjectName();
}
// FUNCTION: LEGO1 0x1006b900
// FUNCTION: BETA10 0x100510d8
void LegoAnimPresenter::FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix)
{
LegoTreeNode* root = p_anim->GetRoot();
MxMatrix mat;
LegoAnimNodeData* data = (LegoAnimNodeData*) root->GetData();
if (p_matrix != NULL) {
mat = *p_matrix;
}
else {
LegoROI* roi = m_roiMap[data->GetUnknown0x20()];
if (roi != NULL) {
mat = roi->GetLocal2World();
}
else {
mat.SetIdentity();
}
}
LegoROI::FUN_100a8fd0(root, mat, p_time, m_roiMap);
}
// FUNCTION: LEGO1 0x1006b9a0
void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix)
{
@ -803,16 +858,117 @@ void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p
LegoROI::FUN_100a8e80(root, mat, p_time, m_roiMap);
}
// STUB: LEGO1 0x1006bac0
// FUNCTION: LEGO1 0x1006bac0
// FUNCTION: BETA10 0x100512e1
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;
}
}
}
}
}
// STUB: LEGO1 0x1006c570
void LegoAnimPresenter::VTable0xa0(Matrix4*)
// FUNCTION: LEGO1 0x1006c570
// FUNCTION: BETA10 0x10051ab3
void LegoAnimPresenter::VTable0xa0(Matrix4& p_matrix)
{
// TODO
if (m_unk0x78 != NULL) {
delete m_unk0x78;
}
m_unk0x78 = new MxMatrix(p_matrix);
}
// FUNCTION: LEGO1 0x1006c620
@ -844,7 +1000,7 @@ void LegoAnimPresenter::EndAction()
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++) {
if (m_roiMap[i] != NULL) {
m_roiMap[i]->SetVisibility(FALSE);
@ -864,6 +1020,7 @@ void LegoAnimPresenter::EndAction()
}
// FUNCTION: LEGO1 0x1006c7d0
// FUNCTION: BETA10 0x10051e07
void LegoAnimPresenter::VTable0x8c()
{
if (m_unk0x78) {
@ -874,7 +1031,7 @@ void LegoAnimPresenter::VTable0x8c()
}
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) {
@ -885,10 +1042,19 @@ void LegoAnimPresenter::VTable0x8c()
}
}
// STUB: LEGO1 0x1006c860
// FUNCTION: LEGO1 0x1006c860
// FUNCTION: BETA10 0x10051f45
void LegoAnimPresenter::VTable0x90()
{
// TODO
if (m_currentWorld != NULL) {
m_currentWorld->FUN_1001fe90(this);
if (m_compositePresenter != NULL && m_compositePresenter->IsA("LegoAnimMMPresenter")) {
return;
}
m_currentWorld->Remove(this);
}
}
// FUNCTION: LEGO1 0x1006c8a0
@ -917,14 +1083,17 @@ MxResult LegoAnimPresenter::VTable0x94(Vector3&, Vector3&, float, float, Vector3
return SUCCESS;
}
// STUB: LEGO1 0x1006ca50
void LegoAnimPresenter::VTable0x98()
// FUNCTION: LEGO1 0x1006ca50
// FUNCTION: BETA10 0x100521d0
MxResult LegoAnimPresenter::VTable0x98(LegoPathBoundary* p_boundary)
{
// TODO
}
for (MxU32 i = 1; i <= m_roiMapSize; i++) {
LegoEntity* entity = m_roiMap[i]->GetEntity();
// STUB: LEGO1 0x1006d680
void LegoAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value)
{
// TODO
if (entity != NULL) {
p_boundary->AddActor((LegoPathActor*) entity);
}
}
return SUCCESS;
}

View File

@ -113,3 +113,9 @@ void LegoLocomotionAnimPresenter::EndAction()
MxVideoPresenter::EndAction();
}
}
// STUB: LEGO1 0x1006d680
void LegoLocomotionAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value)
{
// TODO
}

View File

@ -405,14 +405,14 @@ LegoResult LegoROI::FUN_100a8da0(LegoTreeNode* p_node, const Matrix4& p_matrix,
}
// FUNCTION: LEGO1 0x100a8e80
void LegoROI::FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_rois)
void LegoROI::FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap)
{
MxMatrix mat;
LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData();
FUN_100a8cb0(data, p_time, mat);
LegoROI* roi = p_rois[data->GetUnknown0x20()];
LegoROI* roi = p_roiMap[data->GetUnknown0x20()];
if (roi != NULL) {
roi->m_local2world.Product(mat, p_matrix);
roi->VTable0x1c();
@ -421,7 +421,7 @@ void LegoROI::FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_t
roi->SetVisibility(und);
for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) {
FUN_100a8e80(p_node->GetChild(i), roi->m_local2world, p_time, p_rois);
FUN_100a8e80(p_node->GetChild(i), roi->m_local2world, p_time, p_roiMap);
}
}
else {
@ -429,7 +429,34 @@ void LegoROI::FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_t
local2world.Product(mat, p_matrix);
for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) {
FUN_100a8e80(p_node->GetChild(i), local2world, p_time, p_rois);
FUN_100a8e80(p_node->GetChild(i), local2world, p_time, p_roiMap);
}
}
}
// FUNCTION: LEGO1 0x100a8fd0
// FUNCTION: BETA10 0x1018ac81
void LegoROI::FUN_100a8fd0(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap)
{
MxMatrix mat;
LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData();
FUN_100a8cb0(data, p_time, mat);
LegoROI* roi = p_roiMap[data->GetUnknown0x20()];
if (roi != NULL) {
roi->m_local2world.Product(mat, p_matrix);
for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) {
FUN_100a8fd0(p_node->GetChild(i), roi->m_local2world, p_time, p_roiMap);
}
}
else {
MxMatrix local2world;
local2world.Product(mat, p_matrix);
for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) {
FUN_100a8fd0(p_node->GetChild(i), local2world, p_time, p_roiMap);
}
}
}

View File

@ -32,7 +32,8 @@ class LegoROI : public ViewROI {
);
LegoROI* FindChildROI(const LegoChar* p_name, LegoROI* p_roi);
LegoResult FUN_100a8da0(LegoTreeNode* p_node, const Matrix4& p_matrix, LegoTime p_time, LegoROI* p_roi);
static void FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_rois);
static void FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap);
static void FUN_100a8fd0(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap);
LegoResult SetFrame(LegoAnim* p_anim, LegoTime p_time);
LegoResult FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult FUN_100a9210(LegoTextureInfo* p_textureInfo);

View File

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

View File

@ -7,6 +7,7 @@
// SIZE 0x48
class MxMatrix : public Matrix4 {
public:
// FUNCTION: LEGO1 0x1006b120
inline MxMatrix() : Matrix4(m_elements) {}
// FUNCTION: LEGO1 0x10032770
@ -26,7 +27,7 @@ class MxMatrix : public Matrix4 {
virtual void operator=(const MxMatrix& p_matrix) { Equals(p_matrix); } // vtable+0x48
private:
float m_elements[4][4];
float m_elements[4][4]; // 0x08
};
#endif // MXMATRIX_H

View File

@ -4,28 +4,42 @@
#include "mxcore.h"
// VTABLE: LEGO1 0x100dc110
// VTABLE: BETA10 0x101c1be0
// SIZE 0x10
class MxString : public MxCore {
public:
MxString(const MxString& p_str);
~MxString() override;
const MxString& operator=(const char* p_data);
MxString();
MxString(const char*);
MxString(const MxString& p_str);
MxString(const char* p_str);
MxString(const char* p_str, MxU16 p_maxlen);
~MxString() override;
void Reverse();
void ToUpperCase();
void ToLowerCase();
MxString& operator=(const MxString& p_str);
MxString operator+(const char* p_str);
const MxString& operator=(const char* p_str);
MxString operator+(const MxString& p_str) const;
MxString operator+(const char* p_str) const;
MxString& operator+=(const char* p_str);
inline MxS8 Compare(const MxString& p_str) const { return strcmp(m_data, p_str.m_data); }
inline MxBool Equal(const MxString& p_str) const { return strcmp(m_data, p_str.m_data) == 0; }
inline const char* GetData() const { return m_data; }
inline char* GetDataPtr() const { return m_data; }
static void CharSwap(char* p_a, char* p_b);
// FUNCTION: BETA10 0x10017c50
inline char* GetData() const { return m_data; }
// FUNCTION: BETA10 0x10067630
inline const MxU16 GetLength() const { return m_length; }
// FUNCTION: BETA10 0x100d8a30
inline MxBool Equal(const MxString& p_str) const { return strcmp(m_data, p_str.m_data) == 0; }
// FUNCTION: BETA10 0x1012a810
inline MxS8 Compare(const MxString& p_str) const { return strcmp(m_data, p_str.m_data); }
// SYNTHETIC: LEGO1 0x100ae280
// SYNTHETIC: BETA10 0x1012c9d0
// MxString::`scalar deleting destructor'
private:

View File

@ -8,6 +8,7 @@
DECOMP_SIZE_ASSERT(MxString, 0x10)
// FUNCTION: LEGO1 0x100ae200
// FUNCTION: BETA10 0x1012c110
MxString::MxString()
{
// Set string to one char in length and set that char to null terminator
@ -17,6 +18,7 @@ MxString::MxString()
}
// FUNCTION: LEGO1 0x100ae2a0
// FUNCTION: BETA10 0x1012c1a1
MxString::MxString(const MxString& p_str)
{
this->m_length = p_str.m_length;
@ -25,6 +27,7 @@ MxString::MxString(const MxString& p_str)
}
// FUNCTION: LEGO1 0x100ae350
// FUNCTION: BETA10 0x1012c24f
MxString::MxString(const char* p_str)
{
if (p_str) {
@ -39,25 +42,65 @@ MxString::MxString(const char* p_str)
}
}
// FUNCTION: BETA10 0x1012c330
MxString::MxString(const char* p_str, MxU16 p_maxlen)
{
if (p_str) {
if (strlen(p_str) <= p_maxlen) {
this->m_length = strlen(p_str);
}
else {
this->m_length = p_maxlen;
}
// Basically strncpy
this->m_data = new char[this->m_length + 1];
memcpy(this->m_data, p_str, this->m_length);
this->m_data[this->m_length] = '\0';
}
else {
this->m_data = new char[1];
this->m_data[0] = 0;
this->m_length = 0;
}
}
// FUNCTION: LEGO1 0x100ae420
// FUNCTION: BETA10 0x1012c45b
MxString::~MxString()
{
delete[] this->m_data;
}
// FUNCTION: BETA10 0x1012c4de
void MxString::Reverse()
{
char* start = this->m_data;
char* end = this->m_data + this->m_length - 1;
while (start < end) {
CharSwap(start, end);
start++;
end--;
}
}
// FUNCTION: LEGO1 0x100ae490
// FUNCTION: BETA10 0x1012c537
void MxString::ToUpperCase()
{
strupr(this->m_data);
}
// FUNCTION: LEGO1 0x100ae4a0
// FUNCTION: BETA10 0x1012c55c
void MxString::ToLowerCase()
{
strlwr(this->m_data);
}
// FUNCTION: LEGO1 0x100ae4b0
// FUNCTION: BETA10 0x1012c581
MxString& MxString::operator=(const MxString& p_str)
{
if (this->m_data != p_str.m_data) {
@ -71,22 +114,39 @@ MxString& MxString::operator=(const MxString& p_str)
}
// FUNCTION: LEGO1 0x100ae510
const MxString& MxString::operator=(const char* p_data)
// FUNCTION: BETA10 0x1012c606
const MxString& MxString::operator=(const char* p_str)
{
if (this->m_data != p_data) {
if (this->m_data != p_str) {
delete[] this->m_data;
this->m_length = strlen(p_data);
this->m_length = strlen(p_str);
this->m_data = new char[this->m_length + 1];
strcpy(this->m_data, p_data);
strcpy(this->m_data, p_str);
}
return *this;
}
// FUNCTION: BETA10 0x1012c68a
MxString MxString::operator+(const MxString& p_str) const
{
MxString tmp;
delete[] tmp.m_data;
tmp.m_length = p_str.m_length + this->m_length;
tmp.m_data = new char[tmp.m_length + 1];
strcpy(tmp.m_data, this->m_data);
strcpy(tmp.m_data + this->m_length, p_str.m_data);
return MxString(tmp);
}
// Return type is intentionally just MxString, not MxString&.
// This forces MSVC to add $ReturnUdt$ to the stack for 100% match.
// FUNCTION: LEGO1 0x100ae580
MxString MxString::operator+(const char* p_str)
// FUNCTION: BETA10 0x1012c78d
MxString MxString::operator+(const char* p_str) const
{
// MxString constructor allocates 1 byte for m_data, so free that first
MxString tmp;
@ -102,6 +162,7 @@ MxString MxString::operator+(const char* p_str)
}
// FUNCTION: LEGO1 0x100ae690
// FUNCTION: BETA10 0x1012c92f
MxString& MxString::operator+=(const char* p_str)
{
int newlen = this->m_length + strlen(p_str);
@ -111,8 +172,16 @@ MxString& MxString::operator+=(const char* p_str)
strcpy(tmp + this->m_length, p_str);
delete[] this->m_data;
this->m_length = newlen;
this->m_data = tmp;
this->m_length = newlen;
return *this;
}
// FUNCTION: BETA10 0x1012ca10
void MxString::CharSwap(char* p_a, char* p_b)
{
char t = *p_a;
*p_a = *p_b;
*p_b = t;
}

View File

@ -56,7 +56,7 @@ class ParseAsm:
def __init__(
self,
relocate_lookup: Optional[Callable[[int], bool]] = None,
name_lookup: Optional[Callable[[int], str]] = None,
name_lookup: Optional[Callable[[int, bool], str]] = None,
bin_lookup: Optional[Callable[[int, int], Optional[bytes]]] = None,
) -> None:
self.relocate_lookup = relocate_lookup
@ -86,13 +86,15 @@ def float_replace(self, addr: int, data_size: int) -> Optional[str]:
return None
def lookup(self, addr: int, use_cache: bool = True) -> Optional[str]:
def lookup(
self, addr: int, use_cache: bool = True, exact: bool = False
) -> Optional[str]:
"""Return a replacement name for this address if we find one."""
if use_cache and (cached := self.replacements.get(addr, None)) is not None:
return cached
if callable(self.name_lookup):
if (name := self.name_lookup(addr)) is not None:
if (name := self.name_lookup(addr, exact)) is not None:
if use_cache:
self.replacements[addr] = name
@ -210,7 +212,7 @@ def sanitize(self, inst: DisasmLiteInst) -> Tuple[str, str]:
# If we have a name for this address, use it. If not,
# do not create a new placeholder. We will instead
# fall through to generic jump handling below.
potential_name = self.lookup(op_str_address)
potential_name = self.lookup(op_str_address, exact=True)
if potential_name is not None:
return (inst.mnemonic, potential_name)

View File

@ -2,6 +2,7 @@
import logging
import difflib
import struct
import uuid
from dataclasses import dataclass
from typing import Callable, Iterable, List, Optional
from isledecomp.bin import Bin as IsleBin, InvalidVirtualAddressError
@ -71,6 +72,9 @@ def __init__(
self.recomp_bin = recomp_bin
self.pdb_file = pdb_file
self.code_dir = code_dir
# Controls whether we dump the asm output to a file
self.debug: bool = False
self.runid: str = uuid.uuid4().hex[:8]
self._lines_db = LinesDb(code_dir)
self._db = CompareDb()
@ -452,6 +456,16 @@ def _find_vtordisp(self):
)
self._db.set_function_pair(orig_addr, recomp_addr)
def _dump_asm(self, orig_combined, recomp_combined):
"""Append the provided assembly output to the debug files"""
with open(f"orig-{self.runid}.txt", "a", encoding="utf-8") as f:
for addr, line in orig_combined:
f.write(f"{addr}: {line}\n")
with open(f"recomp-{self.runid}.txt", "a", encoding="utf-8") as f:
for addr, line in recomp_combined:
f.write(f"{addr}: {line}\n")
def _compare_function(self, match: MatchInfo) -> DiffReport:
# Detect when the recomp function size would cause us to read
# enough bytes from the original function that we cross into
@ -478,19 +492,33 @@ def _compare_function(self, match: MatchInfo) -> DiffReport:
except IndexError:
pass
def orig_lookup(addr: int) -> Optional[str]:
m = self._db.get_by_orig(addr)
def orig_lookup(addr: int, exact: bool) -> Optional[str]:
m = self._db.get_by_orig(addr, exact)
if m is None:
return None
return m.match_name()
if m.orig_addr == addr:
return m.match_name()
def recomp_lookup(addr: int) -> Optional[str]:
m = self._db.get_by_recomp(addr)
offset = addr - m.orig_addr
if m.compare_type != SymbolType.DATA or offset >= m.size:
return None
return m.offset_name(offset)
def recomp_lookup(addr: int, exact: bool) -> Optional[str]:
m = self._db.get_by_recomp(addr, exact)
if m is None:
return None
return m.match_name()
if m.recomp_addr == addr:
return m.match_name()
offset = addr - m.recomp_addr
if m.compare_type != SymbolType.DATA or offset >= m.size:
return None
return m.offset_name(offset)
orig_should_replace = create_reloc_lookup(self.orig_bin)
recomp_should_replace = create_reloc_lookup(self.recomp_bin)
@ -512,6 +540,9 @@ def recomp_lookup(addr: int) -> Optional[str]:
orig_combined = orig_parse.parse_asm(orig_raw, match.orig_addr)
recomp_combined = recomp_parse.parse_asm(recomp_raw, match.recomp_addr)
if self.debug:
self._dump_asm(orig_combined, recomp_combined)
# Detach addresses from asm lines for the text diff.
orig_asm = [x[1] for x in orig_combined]
recomp_asm = [x[1] for x in recomp_combined]

View File

@ -53,7 +53,7 @@ def __init__(
self.name = name
self.size = size
def match_name(self) -> str:
def match_name(self) -> Optional[str]:
"""Combination of the name and compare type.
Intended for name substitution in the diff. If there is a diff,
it will be more obvious what this symbol indicates."""
@ -64,6 +64,12 @@ def match_name(self) -> str:
name = repr(self.name) if ctype == "STRING" else self.name
return f"{name} ({ctype})"
def offset_name(self, ofs: int) -> Optional[str]:
if self.name is None:
return None
return f"{self.name}+{ofs} (OFFSET)"
def matchinfo_factory(_, row):
return MatchInfo(*row)
@ -135,7 +141,32 @@ def get_one_match(self, addr: int) -> Optional[MatchInfo]:
cur.row_factory = matchinfo_factory
return cur.fetchone()
def get_by_orig(self, addr: int) -> Optional[MatchInfo]:
def _get_closest_orig(self, addr: int) -> Optional[int]:
value = self._db.execute(
"""SELECT max(orig_addr) FROM `symbols`
WHERE ? >= orig_addr
LIMIT 1
""",
(addr,),
).fetchone()
return value[0] if value is not None else None
def _get_closest_recomp(self, addr: int) -> Optional[int]:
value = self._db.execute(
"""SELECT max(recomp_addr) FROM `symbols`
WHERE ? >= recomp_addr
LIMIT 1
""",
(addr,),
).fetchone()
return value[0] if value is not None else None
def get_by_orig(self, addr: int, exact: bool = True) -> Optional[MatchInfo]:
if not exact and not self._orig_used(addr):
addr = self._get_closest_orig(addr)
if addr is None:
return None
cur = self._db.execute(
"""SELECT * FROM `match_info`
WHERE orig_addr = ?
@ -145,7 +176,12 @@ def get_by_orig(self, addr: int) -> Optional[MatchInfo]:
cur.row_factory = matchinfo_factory
return cur.fetchone()
def get_by_recomp(self, addr: int) -> Optional[MatchInfo]:
def get_by_recomp(self, addr: int, exact: bool = True) -> Optional[MatchInfo]:
if not exact and not self._recomp_used(addr):
addr = self._get_closest_recomp(addr)
if addr is None:
return None
cur = self._db.execute(
"""SELECT * FROM `match_info`
WHERE recomp_addr = ?

View File

@ -113,7 +113,7 @@ def relocate_lookup(addr: int) -> bool:
def test_name_replace(start, end):
"""Make sure the name lookup function is called if present"""
def substitute(_: int) -> str:
def substitute(_: int, __: bool) -> str:
return "_substitute_"
p = ParseAsm(name_lookup=substitute)
@ -137,7 +137,7 @@ def test_replacement_numbering():
"""If we can use the name lookup for the first address but not the second,
the second replacement should be <OFFSET2> not <OFFSET1>."""
def substitute_1234(addr: int) -> Optional[str]:
def substitute_1234(addr: int, _: bool) -> Optional[str]:
return "_substitute_" if addr == 0x1234 else None
p = ParseAsm(name_lookup=substitute_1234)
@ -171,7 +171,7 @@ def test_jump_to_function():
assume this is the case for all jumps. Only replace the jump with a name
if we can find it using our lookup."""
def substitute_1234(addr: int) -> Optional[str]:
def substitute_1234(addr: int, _: bool) -> Optional[str]:
return "_substitute_" if addr == 0x1234 else None
p = ParseAsm(name_lookup=substitute_1234)
@ -212,7 +212,7 @@ def test_float_variable():
"""If there is a variable at the address referenced by a float instruction,
use the name instead of calling into the float replacement handler."""
def name_lookup(addr: int) -> Optional[str]:
def name_lookup(addr: int, _: bool) -> Optional[str]:
return "g_myFloatVariable" if addr == 0x1234 else None
p = ParseAsm(name_lookup=name_lookup)
@ -234,7 +234,7 @@ def relocate_lookup(addr: int) -> bool:
return addr in (0x1234, 0x5555)
# Only 0x5555 is a "known" address
def name_lookup(addr: int) -> Optional[str]:
def name_lookup(addr: int, _: bool) -> Optional[str]:
return "hello" if addr == 0x5555 else None
p = ParseAsm(relocate_lookup=relocate_lookup, name_lookup=name_lookup)
@ -263,7 +263,7 @@ def test_absolute_indirect():
we have it, but there are some circumstances where we want to replace
with the pointer's name (i.e. an import function)."""
def name_lookup(addr: int) -> Optional[str]:
def name_lookup(addr: int, _: bool) -> Optional[str]:
return {
0x1234: "Hello",
0x4321: "xyz",

View File

@ -241,6 +241,9 @@ def main():
isle_compare = IsleCompare(origfile, recompfile, args.pdb, args.decomp_dir)
if args.loglevel == logging.DEBUG:
isle_compare.debug = True
print()
### Compare one or none.