Fixes, refactorings

This commit is contained in:
Christian Semmler 2023-10-12 11:46:40 -04:00
parent d7835c95c1
commit 9acc23d59f
16 changed files with 259 additions and 261 deletions

View File

@ -90,6 +90,7 @@ add_library(lego1 SHARED
LEGO1/legostream.cpp
LEGO1/legotexturepresenter.cpp
LEGO1/legoutil.cpp
LEGO1/legounksavedatawriter.cpp
LEGO1/legovideomanager.cpp
LEGO1/legoworld.cpp
LEGO1/legoworldpresenter.cpp

View File

@ -26,34 +26,37 @@ class InfocenterState : public LegoState
return !strcmp(name, InfocenterState::ClassName()) || LegoState::IsA(name);
}
inline MxU32 GetInfocenterBufferElement(int p_index) { return m_buffer[p_index]; }
inline MxU32 GetInfocenterBufferElement(MxS32 p_index) { return m_buffer[p_index]; }
private:
// Size: 0xC
struct SomeStruct
{
undefined4 unk1;
undefined2 unk2;
undefined2 unk3;
undefined2 unk4;
};
/*
struct SomeStruct
{
undefined4 unk1;
undefined2 unk2;
undefined2 unk3;
undefined2 unk4;
};
undefined2 unk1;
undefined2 unk2;
undefined4 unk3;
undefined4 padding1;
void *unk4;
undefined2 unk5;
undefined2 unk6;
undefined2 unk7;
undefined2 padding2;
void *unk8;
undefined2 unk9;
undefined2 unk10;
undefined2 unk11;
undefined2 padding3;
SomeStruct unk12[6];
undefined4 unk13;
undefined2 unk1;
undefined2 unk2;
undefined4 unk3;
undefined4 padding1;
void *unk4;
undefined2 unk5;
undefined2 unk6;
undefined2 unk7;
undefined2 padding2;
void *unk8;
undefined2 unk9;
undefined2 unk10;
undefined2 unk11;
undefined2 padding3;
SomeStruct unk12[6];
undefined4 unk13;
*/
undefined pad[0x70];
MxU32 m_buffer[7];
};

View File

@ -4,6 +4,7 @@
#include "legostate.h"
#include "infocenterstate.h"
#include "legostream.h"
#include "mxobjectfactory.h"
#include "mxvariabletable.h"
#include "mxstring.h"
@ -11,67 +12,10 @@
// There may be other members that come after.
DECOMP_SIZE_ASSERT(LegoGameState, 0x430)
// OFFSET: LEGO1 0x10039550
LegoGameState::LegoGameState()
{
// TODO
m_stateCount = 0;
m_backgroundColor = new LegoBackgroundColor("backgroundcolor", "set 56 54 68");
VariableTable()->SetVariable(m_backgroundColor);
m_tempBackgroundColor = new LegoBackgroundColor("tempBackgroundcolor", "set 56 54 68");
VariableTable()->SetVariable(m_tempBackgroundColor);
m_fullScreenMovie = new LegoFullScreenMovie("fsmovie", "disable");
VariableTable()->SetVariable(m_fullScreenMovie);
VariableTable()->SetVariable("lightposition", "2");
SerializeScoreHistory(1);
}
// OFFSET: LEGO1 0x10039720 STUB
LegoGameState::~LegoGameState()
{
// TODO
}
// OFFSET: LEGO1 0x10039c60 STUB
MxResult LegoGameState::Load(MxULong)
{
// TODO
return 0;
}
// OFFSET: LEGO1 0x100f3e40
// GLOBAL OFFSET: LEGO1 0x100f3e40
const char *g_fileExtensionGS = ".GS";
// OFFSET: LEGO1 0x1003a170
void LegoGameState::GetFileSavePath(MxString *p_outPath, MxULong p_slotn)
{
char baseForSlot[2] = "0";
char path[1024] = "";
// Save path base
if (m_savePath != NULL)
strcpy(path, m_savePath);
// Slot: "G0", "G1", ...
strcat(path, "G");
baseForSlot[0] += p_slotn;
strcat(path, baseForSlot);
// Extension: ".GS"
strcat(path, g_fileExtensionGS);
*p_outPath = &MxString(path);
}
struct ColorStringStruct
{
const char *m_targetName;
const char *m_colorName;
};
// OFFSET: LEGO1 0x100f3e58
// GLOBAL OFFSET: LEGO1 0x100f3e58
ColorStringStruct g_colorSaveData[43] = {
{"c_dbbkfny0", "lego red"},
{"c_dbbkxly0", "lego white"},
@ -120,145 +64,102 @@ ColorStringStruct g_colorSaveData[43] = {
// NOTE: This offset = the end of the variables table, the last entry
// in that table is a special entry, the string "END_OF_VARIABLES"
// OFFSET: LEGO1 0x100f3e50
// GLOBAL OFFSET: LEGO1 0x100f3e50
extern const char *s_endOfVariables;
// OFFSET: LEGO1 0x1003a020
MxResult __stdcall WriteEndOfVariables(LegoStream *p_stream)
// OFFSET: LEGO1 0x10039550
LegoGameState::LegoGameState()
{
unsigned char len = strlen(s_endOfVariables);
// TODO
m_stateCount = 0;
m_backgroundColor = new LegoBackgroundColor("backgroundcolor", "set 56 54 68");
VariableTable()->SetVariable(m_backgroundColor);
m_tempBackgroundColor = new LegoBackgroundColor("tempBackgroundcolor", "set 56 54 68");
VariableTable()->SetVariable(m_tempBackgroundColor);
m_fullScreenMovie = new LegoFullScreenMovie("fsmovie", "disable");
VariableTable()->SetVariable(m_fullScreenMovie);
VariableTable()->SetVariable("lightposition", "2");
SerializeScoreHistory(1);
}
// OFFSET: LEGO1 0x10039720 STUB
LegoGameState::~LegoGameState()
{
// TODO
}
// OFFSET: LEGO1 0x10039c60 STUB
MxResult LegoGameState::Load(MxULong)
{
// TODO
return 0;
}
// OFFSET: LEGO1 0x1003a170
void LegoGameState::GetFileSavePath(MxString *p_outPath, MxULong p_slotn)
{
char baseForSlot[2] = "0";
char path[1024] = "";
// Save path base
if (m_savePath != NULL)
strcpy(path, m_savePath);
// Slot: "G0", "G1", ...
strcat(path, "G");
baseForSlot[0] += p_slotn;
strcat(path, baseForSlot);
// Extension: ".GS"
strcat(path, g_fileExtensionGS);
*p_outPath = MxString(path);
}
// OFFSET: LEGO1 0x1003a020
MxResult LegoGameState::WriteEndOfVariables(LegoStream *p_stream)
{
MxU8 len = strlen(s_endOfVariables);
if (p_stream->Write(&len, 1) == SUCCESS)
return p_stream->Write(s_endOfVariables, len);
return FAILURE;
}
struct LegoSaveDataEntry3
{
char *m_name;
void *m_pSomething1;
void *m_pSomething2;
int m_savePart1;
int m_savePart2;
MxU8 m_savePart3;
undefined padding1[3];
undefined unk1[24];
MxU8 m_frameOffsetInDwords;
int *m_pFrameData;
MxU8 m_currentFrame;
undefined padding2[3];
undefined unk2[8];
MxU8 m_savePart5;
undefined padding3[3];
undefined unk3[20];
MxU8 m_savePart6;
undefined padding4[3];
undefined unk4[44];
MxU8 m_savePart7;
undefined padding5[3];
undefined unk5[20];
MxU8 m_savePart8;
undefined padding6[3];
undefined unk6[68];
MxU8 m_savePart9;
undefined padding7[3];
undefined unk7[20];
MxU8 m_savePart10;
undefined padding8[3];
};
DECOMP_SIZE_ASSERT(LegoSaveDataEntry3, 0x108);
// OFFSET: LEGO1 0x10104f20
LegoSaveDataEntry3 g_saveData3[66];
// Some Mx singleton which is in 0x8C of LegoOmni
class UnknownWritingSaveData3 {
MxResult WriteSaveData3(LegoStream *p_stream);
};
// Match except for swapped registers
// OFFSET: LEGO1 0x10083310
MxResult UnknownWritingSaveData3::WriteSaveData3(LegoStream *p_stream)
{
MxResult result = FAILURE;
// This should probably be a for loop but I can't figure out how to
// make it match as a for loop.
LegoSaveDataEntry3 *entry = g_saveData3;
const LegoSaveDataEntry3 *end = &g_saveData3[66];
while (true)
{
if (p_stream->Write(&entry->m_savePart1, 4) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart2, 4) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart3, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_currentFrame, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart5, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart6, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart7, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart8, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart9, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart10, 1) != SUCCESS)
break;
if (++entry >= end)
{
result = SUCCESS;
break;
}
}
return result;
}
// OFFSET: LEGO1 0x10039980 STUB
// OFFSET: LEGO1 0x10039980
MxResult LegoGameState::Save(MxULong p_slot)
{
MxResult result;
InfocenterState *infocenterState = (InfocenterState *)GameState()->GetState("InfocenterState");
if (infocenterState == NULL || infocenterState->GetInfocenterBufferElement(0) == 0)
{
if (!infocenterState || infocenterState->GetInfocenterBufferElement(0) == 0)
result = SUCCESS;
}
else
{
else {
result = FAILURE;
MxVariableTable *variableTable = VariableTable();
MxString savePath;
GetFileSavePath(&savePath, p_slot);
LegoFileStream fileStream;
if (fileStream.Open(savePath.GetData(), LegoStream::WriteBit) != FAILURE)
{
if (fileStream.Open(savePath.GetData(), LegoStream::WriteBit) != FAILURE) {
MxU32 maybeVersion = 0x1000C;
fileStream.Write(&maybeVersion, 4);
fileStream.Write(&m_secondThingWritten, 2);
fileStream.Write(&m_someEnumState, 2);
fileStream.Write(&m_someModeSwitch, 1);
for (int i = 0; i < sizeof(g_colorSaveData) / sizeof(g_colorSaveData[0]); ++i)
{
for (MxS32 i = 0; i < sizeof(g_colorSaveData) / sizeof(g_colorSaveData[0]); ++i) {
if (LegoStream::WriteVariable(&fileStream, variableTable, g_colorSaveData[i].m_targetName) == FAILURE)
return result;
}
if (LegoStream::WriteVariable(&fileStream, variableTable, "backgroundcolor") != FAILURE)
{
if (LegoStream::WriteVariable(&fileStream, variableTable, "lightposition") != FAILURE)
{
if (LegoStream::WriteVariable(&fileStream, variableTable, "backgroundcolor") != FAILURE) {
if (LegoStream::WriteVariable(&fileStream, variableTable, "lightposition") != FAILURE) {
WriteEndOfVariables(&fileStream);
// TODO: Calls down to more aggregate writing functions
return SUCCESS;
}
}
}
}
return result;
@ -280,30 +181,22 @@ void LegoGameState::SerializeScoreHistory(MxS16 p)
void LegoGameState::SetSavePath(char *p_savePath)
{
if (m_savePath != NULL)
{
delete[] m_savePath;
}
if (p_savePath)
{
if (p_savePath) {
m_savePath = new char[strlen(p_savePath) + 1];
strcpy(m_savePath, p_savePath);
}
else
{
m_savePath = NULL;
}
}
// OFFSET: LEGO1 0x1003bbb0
LegoState *LegoGameState::GetState(char *p_stateName)
{
for (MxS32 i = 0; i < m_stateCount; ++i)
{
if (m_stateArray[i]->IsA(p_stateName))
{
return m_stateArray[i];
}
}
return NULL;
}
@ -319,27 +212,25 @@ LegoState *LegoGameState::CreateState(char *p_stateName)
// OFFSET: LEGO1 0x1003bc30
void LegoGameState::RegisterState(LegoState *p_state)
{
int targetIndex;
MxS32 targetIndex;
for (targetIndex = 0; targetIndex < m_stateCount; ++targetIndex)
{
if (m_stateArray[targetIndex]->IsA(p_state->ClassName()))
break;
}
if (targetIndex == m_stateCount)
{
LegoState **newBuffer = (LegoState**)malloc(m_stateCount * 4 + 4);
if (m_stateCount != 0)
{
if (targetIndex == m_stateCount) {
LegoState **newBuffer = new LegoState*[m_stateCount + 1];
if (m_stateCount != 0) {
memcpy(newBuffer, m_stateArray, m_stateCount * sizeof(LegoState*));
free(m_stateArray);
delete[] m_stateArray;
}
newBuffer[m_stateCount++] = p_state;
m_stateArray = newBuffer;
return;
}
if (m_stateArray[targetIndex] != NULL)
{
if (m_stateArray[targetIndex])
delete m_stateArray[targetIndex];
}
m_stateArray[targetIndex] = p_state;
}
}

View File

@ -7,9 +7,16 @@
#include "legofullscreenmovie.h"
class LegoState;
class LegoStream;
class MxVariable;
class MxString;
struct ColorStringStruct
{
const char *m_targetName;
const char *m_colorName;
};
// SIZE 0x430 (at least)
class LegoGameState
{
@ -29,6 +36,7 @@ class LegoGameState
private:
void RegisterState(LegoState *p_state);
MxResult WriteEndOfVariables(LegoStream *p_stream);
private:
char *m_savePath; // 0x0
@ -41,7 +49,7 @@ class LegoGameState
LegoBackgroundColor *m_tempBackgroundColor; // 0x1c
LegoFullScreenMovie *m_fullScreenMovie; // 0x20
MxU16 m_secondThingWritten;
undefined m_unk24[1036];
undefined m_unk24[1032];
};
#endif // LEGOGAMESTATE_H

View File

@ -1,13 +1,12 @@
#include "legoobjectfactory.h"
#include "infocenterstate.h"
#include "decomp.h"
// TODO: Uncomment once we have all the relevant types ready
// DECOMP_SIZE_ASSERT(LegoObjectFactory, 0x1c4);
// DECOMP_SIZE_ASSERT(LegoObjectFactory, 0x1c8);
// OFFSET: LEGO1 0x100b0d80
// OFFSET: LEGO1 0x10006e40
LegoObjectFactory::LegoObjectFactory()
{
#define X(V) this->m_id##V = MxAtomId(#V, LookupMode_Exact);
@ -15,8 +14,8 @@ LegoObjectFactory::LegoObjectFactory()
#undef X
}
// OFFSET: LEGO1 0x100b12c0
void *LegoObjectFactory::Create(const char *p_name)
// OFFSET: LEGO1 0x10009a90
MxCore *LegoObjectFactory::Create(const char *p_name)
{
MxAtomId atom(p_name, LookupMode_Exact);
@ -29,7 +28,8 @@ void *LegoObjectFactory::Create(const char *p_name)
}
}
// OFFSET: LEGO1 0x100b1a30 STUB
void LegoObjectFactory::Destroy(void *p_object) {
// FIXME
// OFFSET: LEGO1 0x1000fb30 STUB
void LegoObjectFactory::Destroy(void *p_object)
{
// TODO
}

View File

@ -6,13 +6,13 @@
#define FOR_LEGOOBJECTFACTORY_OBJECTS(X) \
X(InfocenterState)
// VTABLE 0x100dc220
// VTABLE 0x100d4768
class LegoObjectFactory : public MxObjectFactory
{
public:
LegoObjectFactory();
virtual void *Create(const char *p_name); // vtable 0x14
virtual void Destroy(void *p_object); // vtable 0x18
virtual MxCore *Create(const char *p_name) override; // vtable 0x14
virtual void Destroy(void *p_object) override; // vtable 0x18
private:
#define X(V) MxAtomId m_id##V;
FOR_LEGOOBJECTFACTORY_OBJECTS(X)

View File

@ -262,7 +262,7 @@ void LegoOmni::Init()
m_currentWorld = NULL;
m_unk80 = FALSE;
m_isle = NULL;
m_unk8c = 0;
m_unkLegoSaveDataWriter = NULL;
m_plantManager = NULL;
m_gameState = NULL;
m_animationManager = NULL;

View File

@ -16,6 +16,7 @@ class LegoPathBoundary;
class LegoPlantManager;
class LegoROI;
class LegoSoundManager;
class LegoUnkSaveDataWriter;
class LegoVideoManager;
class LegoWorld;
class MxAtomId;
@ -77,8 +78,8 @@ class LegoOmni : public MxOmni
LegoWorld *GetCurrentWorld() { return m_currentWorld; }
private:
int m_unk68;
int m_unk6c;
undefined4 m_unk68;
undefined4 m_unk6c;
LegoInputManager *m_inputMgr; // 0x70
undefined4 m_unk74;
undefined4 m_unk78;
@ -86,7 +87,7 @@ class LegoOmni : public MxOmni
MxBool m_unk80;
LegoNavController *m_navController; // 0x84
Isle* m_isle; // 0x88
undefined4 m_unk8c;
LegoUnkSaveDataWriter* m_unkLegoSaveDataWriter;
LegoPlantManager* m_plantManager; // 0x90
LegoAnimationManager* m_animationManager;
LegoBuildingManager* m_buildingManager; // 0x98

View File

@ -6,6 +6,12 @@
#include "mxvariabletable.h"
// This is a pointer to the end of the global variable name table, which has
// the text "END_OF_VARIABLES" in it.
// TODO: make s_endOfVariables reference the actual end of the variable array.
// GLOBAL OFFSET: LEGO1 0x100f3e50
const char *s_endOfVariables = "END_OF_VARIABLES";
// Very likely but not certain sizes.
// The classes are only used on the stack in functions we have not 100% matched
// yet, we can confirm the size once we have.
@ -153,13 +159,11 @@ MxResult LegoStream::WriteVariable(LegoStream* p_stream, MxVariableTable* p_from
{
MxResult result = FAILURE;
const char *variableValue = p_from->GetVariable(p_variableName);
if (variableValue != NULL)
{
if (variableValue) {
MxU8 length = strlen(p_variableName);
if (p_stream->Write((char*)&length, 1) == SUCCESS)
{
if (p_stream->Write(p_variableName, length) == SUCCESS)
{
if (p_stream->Write((char*)&length, 1) == SUCCESS) {
if (p_stream->Write(p_variableName, length) == SUCCESS) {
length = strlen(variableValue);
if (p_stream->Write((char*)&length, 1) == SUCCESS)
result = p_stream->Write((char *)variableValue, length);
@ -169,37 +173,25 @@ MxResult LegoStream::WriteVariable(LegoStream* p_stream, MxVariableTable* p_from
return result;
}
// This is a pointer to the end of the global variable name table, which has
// the text "END_OF_VARIABLES" in it.
// TODO: make s_endOfVariables reference the actual end of the variable array.
// OFFSET: LEGO1 0x100f3e50
const char *s_endOfVariables = "END_OF_VARIABLES";
// 95% match, just some instruction ordering differences on the call to
// MxVariableTable::SetVariable at the end.
// OFFSET: LEGO1 0x1003a080
int LegoStream::ReadVariable(LegoStream* p_stream, MxVariableTable* p_to)
MxS32 LegoStream::ReadVariable(LegoStream* p_stream, MxVariableTable* p_to)
{
int result = 1;
MxS32 result = 1;
MxU8 length;
if (p_stream->Read((char*)&length, 1) == SUCCESS)
{
if (p_stream->Read((char*)&length, 1) == SUCCESS) {
char nameBuffer[256];
if (p_stream->Read(nameBuffer, length) == SUCCESS)
{
if (p_stream->Read(nameBuffer, length) == SUCCESS) {
nameBuffer[length] = '\0';
if (strcmp(nameBuffer, s_endOfVariables) == 0)
{
// 2 -> "This was the last entry, done reading."
result = 2;
}
else
{
if (p_stream->Read((char*)&length, 1) == SUCCESS)
{
else {
if (p_stream->Read((char*)&length, 1) == SUCCESS) {
char valueBuffer[256];
if (p_stream->Read(valueBuffer, length) == SUCCESS)
{
if (p_stream->Read(valueBuffer, length) == SUCCESS) {
result = 0;
valueBuffer[length] = '\0';
p_to->SetVariable(nameBuffer, valueBuffer);

View File

@ -34,8 +34,8 @@ class LegoStream
BinaryBit = 4,
};
static MxResult __stdcall WriteVariable(LegoStream* p_stream, MxVariableTable* p_from, const char* p_variableName);
static int __stdcall ReadVariable(LegoStream* p_stream, MxVariableTable* p_to);
static MxResult WriteVariable(LegoStream* p_stream, MxVariableTable* p_from, const char* p_variableName);
static MxS32 ReadVariable(LegoStream* p_stream, MxVariableTable* p_to);
protected:
MxU8 m_mode;

View File

@ -0,0 +1,48 @@
#include "legounksavedatawriter.h"
#include "legogamestate.h"
#include "legostream.h"
DECOMP_SIZE_ASSERT(LegoSaveDataEntry3, 0x108);
// GLOBAL OFFSET: LEGO1 0x10104f20
LegoSaveDataEntry3 g_saveData3[66];
// OFFSET: LEGO1 0x10083310
MxResult LegoUnkSaveDataWriter::WriteSaveData3(LegoStream *p_stream)
{
MxResult result = FAILURE;
// This should probably be a for loop but I can't figure out how to
// make it match as a for loop.
LegoSaveDataEntry3 *entry = g_saveData3;
const LegoSaveDataEntry3 *end = &g_saveData3[66];
while (TRUE) {
if (p_stream->Write(&entry->m_savePart1, 4) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart2, 4) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart3, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_currentFrame, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart5, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart6, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart7, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart8, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart9, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart10, 1) != SUCCESS)
break;
if (++entry >= end) {
result = SUCCESS;
break;
}
}
return result;
}

View File

@ -0,0 +1,40 @@
#ifndef LEGOUNKSAVEDATAWRITER_H
#define LEGOUNKSAVEDATAWRITER_H
#include "mxtypes.h"
#include "decomp.h"
class LegoStream;
struct LegoSaveDataEntry3
{
char *m_name;
void *m_unk0x04;
void *m_unk0x08;
MxS32 m_savePart1;
MxS32 m_savePart2;
MxU8 m_savePart3;
undefined4 m_unk0x18[6];
MxU8 m_frameOffsetInDwords; // 0x30
MxS32 *m_pFrameData;
MxU8 m_currentFrame;
undefined4 m_unk0x3c[2];
MxU8 m_savePart5; // 0x44
undefined4 m_unk0x48[5];
MxU8 m_savePart6; // 0x5c
undefined4 m_unk0x60[11];
MxU8 m_savePart7; // 0x8c
undefined4 m_unk0x90[5];
MxU8 m_savePart8; // 0xa4
undefined4 m_unk0xa8[17];
MxU8 m_savePart9; // 0xec
undefined4 m_unk0xf0[5];
MxU8 m_savePart10; // 0x104
};
class LegoUnkSaveDataWriter
{
MxResult WriteSaveData3(LegoStream *p_stream);
};
#endif // LEGOUNKSAVEDATAWRITER_H

View File

@ -15,7 +15,7 @@ MxAtomId::MxAtomId(const char *p_str, LookupMode p_mode)
counter->Inc();
}
// OFFSET: LEGO1 0x100acfd0 STUB
// OFFSET: LEGO1 0x100acfd0
MxAtomId::~MxAtomId()
{
Destroy();

View File

@ -26,7 +26,7 @@ MxObjectFactory::MxObjectFactory()
}
// OFFSET: LEGO1 0x100b12c0
void *MxObjectFactory::Create(const char *p_name)
MxCore *MxObjectFactory::Create(const char *p_name)
{
MxAtomId atom(p_name, LookupMode_Exact);

View File

@ -23,7 +23,21 @@ class MxObjectFactory : public MxCore
{
public:
MxObjectFactory();
virtual void *Create(const char *p_name); // vtable 0x14
// OFFSET: LEGO1 0x1008f70
inline virtual const char *ClassName() const override // vtable+0xc
{
// 0x100f0730
return "MxObjectFactory";
}
// OFFSET: LEGO1 0x1008f80
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, MxObjectFactory::ClassName()) || MxCore::IsA(name);
}
virtual MxCore *Create(const char *p_name); // vtable 0x14
virtual void Destroy(void *p_object); // vtable 0x18
private:
#define X(V) MxAtomId m_id##V;

View File

@ -93,9 +93,9 @@ __declspec(dllexport) MxVariableTable * VariableTable();
__declspec(dllexport) MxMusicManager * MusicManager();
__declspec(dllexport) MxEventManager * EventManager();
__declspec(dllexport) MxNotificationManager * NotificationManager();
MxVideoManager * MVideoManager();
MxAtomIdCounterSet* AtomIdCounterSet();
MxVideoManager *MVideoManager();
MxAtomIdCounterSet *AtomIdCounterSet();
MxObjectFactory *ObjectFactory();
#endif // MXOMNI_H