mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-24 00:31:16 +00:00
Fixes, refactorings
This commit is contained in:
parent
d7835c95c1
commit
9acc23d59f
@ -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
|
||||
|
||||
@ -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];
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
48
LEGO1/legounksavedatawriter.cpp
Normal file
48
LEGO1/legounksavedatawriter.cpp
Normal 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;
|
||||
}
|
||||
40
LEGO1/legounksavedatawriter.h
Normal file
40
LEGO1/legounksavedatawriter.h
Normal 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
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user