Merge remote-tracking branch 'isle/master'

This commit is contained in:
Christian Semmler 2025-01-15 16:53:43 -07:00
commit 83fb9f04a7
No known key found for this signature in database
GPG key ID: 086DAA1360BEEE5C
25 changed files with 478 additions and 385 deletions

View file

@ -118,6 +118,9 @@ public:
MxLong Notify(MxParam& p_param) override; // vtable+0x04 MxLong Notify(MxParam& p_param) override; // vtable+0x04
// FUNCTION: LEGO1 0x10030900
MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c
// FUNCTION: LEGO1 0x10030910 // FUNCTION: LEGO1 0x10030910
// FUNCTION: BETA10 0x10035d70 // FUNCTION: BETA10 0x10035d70
const char* ClassName() const override // vtable+0x0c const char* ClassName() const override // vtable+0x0c
@ -135,16 +138,10 @@ public:
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
void ReadyWorld() override; // vtable+0x50 void ReadyWorld() override; // vtable+0x50
void Add(MxCore* p_object) override; // vtable+0x58 void Add(MxCore* p_object) override; // vtable+0x58
void VTable0x60() override; // vtable+0x60
// FUNCTION: LEGO1 0x10030900 MxBool Escape() override; // vtable+0x64
MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c void Enable(MxBool p_enable) override; // vtable+0x68
virtual void VTable0x6c(LegoPathActor* p_actor); // vtable+0x6c
// FUNCTION: LEGO1 0x10033170
void VTable0x60() override {} // vtable+60
MxBool Escape() override; // vtable+0x64
void Enable(MxBool p_enable) override; // vtable+0x68
virtual void VTable0x6c(LegoPathActor* p_actor); // vtable+0x6c
void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; } void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; }
MxBool HasHelicopter() { return m_helicopter != NULL; } MxBool HasHelicopter() { return m_helicopter != NULL; }

View file

@ -17,6 +17,7 @@ class MxSoundPresenter;
class MxActionNotificationParam; class MxActionNotificationParam;
// VTABLE: LEGO1 0x100d66e0 // VTABLE: LEGO1 0x100d66e0
// VTABLE: BETA10 0x101bb910
// SIZE 0x50 // SIZE 0x50
class LegoVehicleBuildState : public LegoState { class LegoVehicleBuildState : public LegoState {
public: public:
@ -34,13 +35,13 @@ public:
// FUNCTION: LEGO1 0x10025ff0 // FUNCTION: LEGO1 0x10025ff0
const char* ClassName() const override // vtable+0x0c const char* ClassName() const override // vtable+0x0c
{ {
return this->m_className.GetData(); return m_className.GetData();
} }
// FUNCTION: LEGO1 0x10026000 // FUNCTION: LEGO1 0x10026000
MxBool IsA(const char* p_name) const override // vtable+0x10 MxBool IsA(const char* p_name) const override // vtable+0x10
{ {
return !strcmp(p_name, this->m_className.GetData()) || LegoState::IsA(p_name); return !strcmp(p_name, m_className.GetData()) || LegoState::IsA(p_name);
} }
MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
@ -58,7 +59,7 @@ public:
MxString m_className; // 0x38 MxString m_className; // 0x38
AnimationState m_animationState; // 0x48 AnimationState m_animationState; // 0x48
undefined m_unk0x4c; // 0x4c MxU8 m_unk0x4c; // 0x4c
MxBool m_unk0x4d; // 0x4d MxBool m_unk0x4d; // 0x4d
MxBool m_unk0x4e; // 0x4e MxBool m_unk0x4e; // 0x4e
MxU8 m_placedPartCount; // 0x4f MxU8 m_placedPartCount; // 0x4f

View file

@ -112,7 +112,7 @@ public:
Username(Username& p_other) { Set(p_other); } Username(Username& p_other) { Set(p_other); }
void Set(Username& p_other) { memcpy(m_letters, p_other.m_letters, sizeof(m_letters)); } void Set(Username& p_other) { memcpy(m_letters, p_other.m_letters, sizeof(m_letters)); }
MxResult Serialize(LegoStorage* p_storage); MxResult Serialize(LegoFile* p_file);
Username& operator=(const Username& p_other); Username& operator=(const Username& p_other);
MxS16 m_letters[7]; // 0x00 MxS16 m_letters[7]; // 0x00
@ -122,10 +122,10 @@ public:
struct ScoreItem { struct ScoreItem {
MxResult Serialize(LegoFile* p_file); MxResult Serialize(LegoFile* p_file);
MxS16 m_totalScore; // 0x00 MxS16 m_totalScore; // 0x00
MxU8 m_scores[5][5]; // 0x02 MxU8 m_scores[5][5]; // 0x02
Username m_name; // 0x1c Username m_name; // 0x1c
undefined2 m_unk0x2a; // 0x2a MxS16 m_unk0x2a; // 0x2a
}; };
// SIZE 0x372 // SIZE 0x372
@ -142,7 +142,7 @@ public:
MxS16 m_count; // 0x00 MxS16 m_count; // 0x00
ScoreItem m_scores[20]; // 0x02 ScoreItem m_scores[20]; // 0x02
undefined2 m_unk0x372; // 0x372 MxS16 m_unk0x372; // 0x372
}; };
LEGO1_EXPORT LegoGameState(); LEGO1_EXPORT LegoGameState();
@ -215,7 +215,7 @@ private:
// TODO: Most likely getters/setters are not used according to BETA for the following members: // TODO: Most likely getters/setters are not used according to BETA for the following members:
public: public:
MxU16 m_unk0x24; // 0x24 MxS16 m_unk0x24; // 0x24
MxS16 m_playerCount; // 0x26 MxS16 m_playerCount; // 0x26
Username m_players[9]; // 0x28 Username m_players[9]; // 0x28
History m_history; // 0xa6 History m_history; // 0xa6

View file

@ -24,6 +24,7 @@ public:
void SetDirection(const Mx3DPointFloat& p_direction) { m_direction = p_direction; } void SetDirection(const Mx3DPointFloat& p_direction) { m_direction = p_direction; }
void SetUp(const Mx3DPointFloat& p_up) { m_up = p_up; } void SetUp(const Mx3DPointFloat& p_up) { m_up = p_up; }
// TODO: Unclear whether this was defined
MxBool IsPresent() { return strcmp(m_name.GetData(), "") != 0; } MxBool IsPresent() { return strcmp(m_name.GetData(), "") != 0; }
void Reset() { m_name = ""; } void Reset() { m_name = ""; }
@ -31,22 +32,22 @@ public:
MxResult Serialize(LegoFile* p_file) MxResult Serialize(LegoFile* p_file)
{ {
if (p_file->IsWriteMode()) { if (p_file->IsWriteMode()) {
p_file->WriteString(m_name); p_file->Write(MxString(m_name));
p_file->WriteVector3(m_position); p_file->Write(m_position);
p_file->WriteVector3(m_direction); p_file->Write(m_direction);
p_file->WriteVector3(m_up); p_file->Write(m_up);
} }
else if (p_file->IsReadMode()) { else if (p_file->IsReadMode()) {
p_file->ReadString(m_name); p_file->Read(m_name);
p_file->ReadVector3(m_position); p_file->Read(m_position);
p_file->ReadVector3(m_direction); p_file->Read(m_direction);
p_file->ReadVector3(m_up); p_file->Read(m_up);
} }
return SUCCESS; return SUCCESS;
} }
private: // private:
MxString m_name; // 0x00 MxString m_name; // 0x00
Mx3DPointFloat m_position; // 0x10 Mx3DPointFloat m_position; // 0x10
Mx3DPointFloat m_direction; // 0x24 Mx3DPointFloat m_direction; // 0x24

View file

@ -198,6 +198,9 @@ protected:
MxFloat m_unk0x150; // 0x150 MxFloat m_unk0x150; // 0x150
}; };
// FUNCTION: LEGO1 0x1002edd0
// LegoPathActor::FUN_1002edd0
// TEMPLATE: LEGO1 0x10018b70 // TEMPLATE: LEGO1 0x10018b70
// List<LegoBoundaryEdge>::~List<LegoBoundaryEdge> // List<LegoBoundaryEdge>::~List<LegoBoundaryEdge>

View file

@ -42,14 +42,17 @@ public:
MxResult Serialize(LegoFile* p_file) MxResult Serialize(LegoFile* p_file)
{ {
if (p_file->IsReadMode()) { if (p_file->IsReadMode()) {
Read(p_file, &m_id); p_file->Read(m_id);
Read(p_file, &m_unk0x02); p_file->Read(m_unk0x02);
Read(p_file, &m_score); p_file->Read(m_score);
} }
else if (p_file->IsWriteMode()) { else if (p_file->IsWriteMode()) {
Write(p_file, m_id); p_file->Write(m_id);
Write(p_file, m_unk0x02); p_file->Write(m_unk0x02);
Write(p_file, m_score); p_file->Write(m_score);
}
else {
return FAILURE;
} }
return SUCCESS; return SUCCESS;

View file

@ -18,8 +18,7 @@ public:
}; };
// SIZE 0x0c // SIZE 0x0c
class Playlist { struct Playlist {
public:
enum Mode { enum Mode {
e_loop, e_loop,
e_once, e_once,
@ -60,21 +59,6 @@ public:
MxU32 Next(); MxU32 Next();
MxBool Contains(MxU32 p_objectId); MxBool Contains(MxU32 p_objectId);
void SetNextIndex(MxS16 p_nextIndex) { m_nextIndex = p_nextIndex; }
MxResult ReadFromFile(LegoFile* p_file)
{
Read(p_file, &m_nextIndex);
return SUCCESS;
}
MxResult WriteToFile(LegoFile* p_file)
{
Write(p_file, m_nextIndex);
return SUCCESS;
}
private:
MxU32* m_objectIds; // 0x00 MxU32* m_objectIds; // 0x00
MxS16 m_length; // 0x04 MxS16 m_length; // 0x04
MxS16 m_mode; // 0x06 MxS16 m_mode; // 0x06
@ -95,7 +79,7 @@ public:
virtual MxResult Serialize(LegoFile* p_file) virtual MxResult Serialize(LegoFile* p_file)
{ {
if (p_file->IsWriteMode()) { if (p_file->IsWriteMode()) {
p_file->WriteString(ClassName()); p_file->Write(MxString(ClassName()));
} }
return SUCCESS; return SUCCESS;
} // vtable+0x1c } // vtable+0x1c

View file

@ -95,24 +95,6 @@ public:
// FUNCTION: BETA10 0x100ef7e0 // FUNCTION: BETA10 0x100ef7e0
MxLong GetTimeoutTime() { return m_finishTimes[3]; } MxLong GetTimeoutTime() { return m_finishTimes[3]; }
MxResult WriteToFile(LegoFile* p_file)
{
Write(p_file, m_unk0x06);
Write(p_file, m_unk0x14);
Write(p_file, m_score);
Write(p_file, m_hiScore);
return SUCCESS;
}
MxResult ReadFromFile(LegoFile* p_file)
{
Read(p_file, &m_unk0x06);
Read(p_file, &m_unk0x14);
Read(p_file, &m_score);
Read(p_file, &m_hiScore);
return SUCCESS;
}
MxS16 m_numActions; // 0x00 MxS16 m_numActions; // 0x00
MxU8 m_actorId; // 0x02 MxU8 m_actorId; // 0x02
undefined2 m_unk0x04; // 0x04 undefined2 m_unk0x04; // 0x04

View file

@ -649,33 +649,34 @@ AmbulanceMissionState::AmbulanceMissionState()
} }
// FUNCTION: LEGO1 0x10037440 // FUNCTION: LEGO1 0x10037440
// FUNCTION: BETA10 0x10024480
MxResult AmbulanceMissionState::Serialize(LegoFile* p_file) MxResult AmbulanceMissionState::Serialize(LegoFile* p_file)
{ {
LegoState::Serialize(p_file); LegoState::Serialize(p_file);
if (p_file->IsReadMode()) { if (p_file->IsReadMode()) {
Read(p_file, &m_peScore); p_file->Read(m_peScore);
Read(p_file, &m_maScore); p_file->Read(m_maScore);
Read(p_file, &m_paScore); p_file->Read(m_paScore);
Read(p_file, &m_niScore); p_file->Read(m_niScore);
Read(p_file, &m_laScore); p_file->Read(m_laScore);
Read(p_file, &m_peHighScore); p_file->Read(m_peHighScore);
Read(p_file, &m_maHighScore); p_file->Read(m_maHighScore);
Read(p_file, &m_paHighScore); p_file->Read(m_paHighScore);
Read(p_file, &m_niHighScore); p_file->Read(m_niHighScore);
Read(p_file, &m_laHighScore); p_file->Read(m_laHighScore);
} }
else if (p_file->IsWriteMode()) { else if (p_file->IsWriteMode()) {
Write(p_file, m_peScore); p_file->Write(m_peScore);
Write(p_file, m_maScore); p_file->Write(m_maScore);
Write(p_file, m_paScore); p_file->Write(m_paScore);
Write(p_file, m_niScore); p_file->Write(m_niScore);
Write(p_file, m_laScore); p_file->Write(m_laScore);
Write(p_file, m_peHighScore); p_file->Write(m_peHighScore);
Write(p_file, m_maHighScore); p_file->Write(m_maHighScore);
Write(p_file, m_paHighScore); p_file->Write(m_paHighScore);
Write(p_file, m_niHighScore); p_file->Write(m_niHighScore);
Write(p_file, m_laHighScore); p_file->Write(m_laHighScore);
} }
return SUCCESS; return SUCCESS;

View file

@ -605,18 +605,25 @@ PizzaMissionState::PizzaMissionState()
} }
// FUNCTION: LEGO1 0x100393c0 // FUNCTION: LEGO1 0x100393c0
// FUNCTION: BETA10 0x100eebf2
MxResult PizzaMissionState::Serialize(LegoFile* p_file) MxResult PizzaMissionState::Serialize(LegoFile* p_file)
{ {
LegoState::Serialize(p_file); LegoState::Serialize(p_file);
if (p_file->IsReadMode()) { if (p_file->IsReadMode()) {
for (MxS16 i = 0; i < 5; i++) { for (MxS16 i = 0; i < 5; i++) {
m_missions[i].ReadFromFile(p_file); p_file->Read(m_missions[i].m_unk0x06);
p_file->Read(m_missions[i].m_unk0x14);
p_file->Read(m_missions[i].m_score);
p_file->Read(m_missions[i].m_hiScore);
} }
} }
else if (p_file->IsWriteMode()) { else if (p_file->IsWriteMode()) {
for (MxS16 i = 0; i < 5; i++) { for (MxS16 i = 0; i < 5; i++) {
m_missions[i].WriteToFile(p_file); p_file->Write(m_missions[i].m_unk0x06);
p_file->Write(m_missions[i].m_unk0x14);
p_file->Write(m_missions[i].m_score);
p_file->Write(m_missions[i].m_hiScore);
} }
} }
@ -633,6 +640,7 @@ PizzaMissionState::Mission* PizzaMissionState::GetMission(MxU8 p_actorId)
} }
} }
assert("No pizza mission for this character!" == NULL);
return NULL; return NULL;
} }

View file

@ -124,12 +124,12 @@ MxResult PizzeriaState::Serialize(LegoFile* p_file)
if (p_file->IsReadMode()) { if (p_file->IsReadMode()) {
for (MxS16 i = 0; i < 5; i++) { for (MxS16 i = 0; i < 5; i++) {
m_unk0x08[i].ReadFromFile(p_file); p_file->Read(m_unk0x08[i].m_nextIndex);
} }
} }
else { else {
for (MxS16 i = 0; i < 5; i++) { for (MxS16 i = 0; i < 5; i++) {
m_unk0x08[i].WriteToFile(p_file); p_file->Write(m_unk0x08[i].m_nextIndex);
} }
} }

View file

@ -209,6 +209,7 @@ void Radio::CreateState()
} }
// FUNCTION: LEGO1 0x1002ce10 // FUNCTION: LEGO1 0x1002ce10
// FUNCTION: BETA10 0x100f20f6
RadioState::RadioState() RadioState::RadioState()
{ {
srand(Timer()->GetTime()); srand(Timer()->GetTime());
@ -217,13 +218,13 @@ RadioState::RadioState()
m_unk0x2c = random % 3; m_unk0x2c = random % 3;
m_unk0x08[0] = Playlist((MxU32*) g_unk0x100f3218, sizeOfArray(g_unk0x100f3218), Playlist::e_loop); m_unk0x08[0] = Playlist((MxU32*) g_unk0x100f3218, sizeOfArray(g_unk0x100f3218), Playlist::e_loop);
m_unk0x08[0].SetNextIndex(rand() % sizeOfArray(g_unk0x100f3218)); m_unk0x08[0].m_nextIndex = (rand() % sizeOfArray(g_unk0x100f3218));
m_unk0x08[1] = Playlist((MxU32*) g_unk0x100f3230, sizeOfArray(g_unk0x100f3230), Playlist::e_loop); m_unk0x08[1] = Playlist((MxU32*) g_unk0x100f3230, sizeOfArray(g_unk0x100f3230), Playlist::e_loop);
m_unk0x08[1].SetNextIndex(rand() % sizeOfArray(g_unk0x100f3230)); m_unk0x08[1].m_nextIndex = (rand() % sizeOfArray(g_unk0x100f3230));
m_unk0x08[2] = Playlist((MxU32*) g_unk0x100f3268, sizeOfArray(g_unk0x100f3268), Playlist::e_loop); m_unk0x08[2] = Playlist((MxU32*) g_unk0x100f3268, sizeOfArray(g_unk0x100f3268), Playlist::e_loop);
m_unk0x08[2].SetNextIndex(rand() % sizeOfArray(g_unk0x100f3268)); m_unk0x08[2].m_nextIndex = (rand() % sizeOfArray(g_unk0x100f3268));
m_active = FALSE; m_active = FALSE;
} }

View file

@ -611,33 +611,34 @@ TowTrackMissionState::TowTrackMissionState()
} }
// FUNCTION: LEGO1 0x1004dde0 // FUNCTION: LEGO1 0x1004dde0
// FUNCTION: BETA10 0x100f8720
MxResult TowTrackMissionState::Serialize(LegoFile* p_file) MxResult TowTrackMissionState::Serialize(LegoFile* p_file)
{ {
LegoState::Serialize(p_file); LegoState::Serialize(p_file);
if (p_file->IsReadMode()) { if (p_file->IsReadMode()) {
Read(p_file, &m_peScore); p_file->Read(m_peScore);
Read(p_file, &m_maScore); p_file->Read(m_maScore);
Read(p_file, &m_paScore); p_file->Read(m_paScore);
Read(p_file, &m_niScore); p_file->Read(m_niScore);
Read(p_file, &m_laScore); p_file->Read(m_laScore);
Read(p_file, &m_peHighScore); p_file->Read(m_peHighScore);
Read(p_file, &m_maHighScore); p_file->Read(m_maHighScore);
Read(p_file, &m_paHighScore); p_file->Read(m_paHighScore);
Read(p_file, &m_niHighScore); p_file->Read(m_niHighScore);
Read(p_file, &m_laHighScore); p_file->Read(m_laHighScore);
} }
else if (p_file->IsWriteMode()) { else if (p_file->IsWriteMode()) {
Write(p_file, m_peScore); p_file->Write(m_peScore);
Write(p_file, m_maScore); p_file->Write(m_maScore);
Write(p_file, m_paScore); p_file->Write(m_paScore);
Write(p_file, m_niScore); p_file->Write(m_niScore);
Write(p_file, m_laScore); p_file->Write(m_laScore);
Write(p_file, m_peHighScore); p_file->Write(m_peHighScore);
Write(p_file, m_maHighScore); p_file->Write(m_maHighScore);
Write(p_file, m_paHighScore); p_file->Write(m_paHighScore);
Write(p_file, m_niHighScore); p_file->Write(m_niHighScore);
Write(p_file, m_laHighScore); p_file->Write(m_laHighScore);
} }
return SUCCESS; return SUCCESS;

View file

@ -1707,21 +1707,26 @@ LegoVehicleBuildState::LegoVehicleBuildState(const char* p_classType)
} }
// FUNCTION: LEGO1 0x10026120 // FUNCTION: LEGO1 0x10026120
// FUNCTION: BETA10 0x1006eef0
MxResult LegoVehicleBuildState::Serialize(LegoFile* p_file) MxResult LegoVehicleBuildState::Serialize(LegoFile* p_file)
{ {
LegoState::Serialize(p_file); LegoState::Serialize(p_file);
if (p_file->IsReadMode()) { if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x4c); p_file->Read(m_unk0x4c);
Read(p_file, &m_unk0x4d); p_file->Read(m_unk0x4d);
Read(p_file, &m_unk0x4e); p_file->Read(m_unk0x4e);
Read(p_file, &m_placedPartCount); #ifndef BETA10
p_file->Read(m_placedPartCount);
#endif
} }
else { else {
Write(p_file, m_unk0x4c); p_file->Write(m_unk0x4c);
Write(p_file, m_unk0x4d); p_file->Write(m_unk0x4d);
Write(p_file, m_unk0x4e); p_file->Write(m_unk0x4e);
Write(p_file, m_placedPartCount); #ifndef BETA10
p_file->Write(m_placedPartCount);
#endif
} }
return SUCCESS; return SUCCESS;

View file

@ -2940,67 +2940,75 @@ void AnimState::InitFromAnims(MxU32 p_animsLength, AnimInfo* p_anims, MxU32 p_ex
// FUNCTION: BETA10 0x10046621 // FUNCTION: BETA10 0x10046621
MxResult AnimState::Serialize(LegoFile* p_file) MxResult AnimState::Serialize(LegoFile* p_file)
{ {
// These two are equivalent up to the order of some deallocation. MxResult result = LegoState::Serialize(p_file);
// Choose as needed to get 100 %.
// Option 1:
// LegoState::Serialize(p_file);
// Option 2:
if (p_file->IsWriteMode()) {
p_file->WriteString(ClassName());
}
if (p_file->IsReadMode()) { if (result == SUCCESS) {
Read(p_file, &m_extraCharacterId); if (p_file->IsReadMode()) {
MxS32 i;
if (m_unk0x10) { p_file->Read(m_extraCharacterId);
delete[] m_unk0x10;
}
Read(p_file, &m_unk0x0c); if (m_unk0x10) {
if (m_unk0x0c != 0) { delete[] m_unk0x10;
}
p_file->Read(m_unk0x0c);
#ifndef BETA10
if (m_unk0x0c != 0) {
m_unk0x10 = new MxU16[m_unk0x0c];
}
else {
m_unk0x10 = NULL;
}
#else
m_unk0x10 = new MxU16[m_unk0x0c]; m_unk0x10 = new MxU16[m_unk0x0c];
} #endif
else {
m_unk0x10 = NULL;
}
for (MxS32 i = 0; i < m_unk0x0c; i++) { for (i = 0; i < m_unk0x0c; i++) {
Read(p_file, &m_unk0x10[i]); p_file->Read(m_unk0x10[i]);
} }
// Note that here we read first and then free memory in contrast to above // Note that here we read first and then free memory in contrast to above
Read(p_file, &m_locationsFlagsLength); p_file->Read(m_locationsFlagsLength);
if (m_locationsFlags) { #ifndef BETA10
delete[] m_locationsFlags; if (m_locationsFlags) {
} delete[] m_locationsFlags;
}
if (m_locationsFlagsLength != 0) { if (m_locationsFlagsLength != 0) {
m_locationsFlags = new MxBool[m_locationsFlagsLength];
}
else {
m_locationsFlags = NULL;
}
#else
m_locationsFlags = new MxBool[m_locationsFlagsLength]; m_locationsFlags = new MxBool[m_locationsFlagsLength];
} #endif
else {
m_locationsFlags = NULL;
}
for (MxS32 j = 0; j < m_locationsFlagsLength; j++) { for (i = 0; i < m_locationsFlagsLength; i++) {
Read(p_file, &m_locationsFlags[j]); p_file->Read(m_locationsFlags[i]);
}
} }
} else if (p_file->IsWriteMode()) {
else if (p_file->IsWriteMode()) { MxS32 i;
Write(p_file, m_extraCharacterId);
Write(p_file, m_unk0x0c); p_file->Write(m_extraCharacterId);
for (MxS32 i = 0; i < m_unk0x0c; i++) { p_file->Write(m_unk0x0c);
Write(p_file, m_unk0x10[i]);
}
Write(p_file, m_locationsFlagsLength); for (i = 0; i < m_unk0x0c; i++) {
for (MxS32 j = 0; j < m_locationsFlagsLength; j++) { p_file->Write(m_unk0x10[i]);
Write(p_file, m_locationsFlags[j]); }
p_file->Write(m_locationsFlagsLength);
for (i = 0; i < m_locationsFlagsLength; i++) {
p_file->Write(m_locationsFlags[i]);
}
} }
} }
return SUCCESS; return result;
} }
// FUNCTION: LEGO1 0x100654f0 // FUNCTION: LEGO1 0x100654f0

View file

@ -680,7 +680,11 @@ void LegoBuildingManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_lengt
entry->m_entity = p_entity; entry->m_entity = p_entity;
entry->m_roi = p_entity->GetROI(); entry->m_roi = p_entity->GetROI();
entry->m_time = Timer()->GetTime() + p_length + 1000;
MxLong time = Timer()->GetTime();
time += p_length;
entry->m_time = time + 1000;
entry->m_unk0x0c = entry->m_roi->GetWorldPosition()[1]; entry->m_unk0x0c = entry->m_roi->GetWorldPosition()[1];
entry->m_muted = p_haveSound == FALSE; entry->m_muted = p_haveSound == FALSE;
FUN_100307b0(p_entity, -2); FUN_100307b0(p_entity, -2);

View file

@ -173,6 +173,7 @@ LegoGameState::~LegoGameState()
} }
// FUNCTION: LEGO1 0x10039780 // FUNCTION: LEGO1 0x10039780
// FUNCTION: BETA10 0x10083d43
void LegoGameState::SetActor(MxU8 p_actorId) void LegoGameState::SetActor(MxU8 p_actorId)
{ {
if (p_actorId) { if (p_actorId) {
@ -240,7 +241,7 @@ MxResult LegoGameState::Save(MxULong p_slot)
} }
MxResult result = FAILURE; MxResult result = FAILURE;
LegoFile fileStorage; LegoFile storage;
MxVariableTable* variableTable = VariableTable(); MxVariableTable* variableTable = VariableTable();
MxS16 count = 0; MxS16 count = 0;
MxU32 i; MxU32 i;
@ -250,32 +251,32 @@ MxResult LegoGameState::Save(MxULong p_slot)
MxString savePath; MxString savePath;
GetFileSavePath(&savePath, p_slot); GetFileSavePath(&savePath, p_slot);
if (fileStorage.Open(savePath.GetData(), LegoFile::c_write) == FAILURE) { if (storage.Open(savePath.GetData(), LegoFile::c_write) == FAILURE) {
goto done; goto done;
} }
Write(&fileStorage, 0x1000c); storage.Write(0x1000c);
Write(&fileStorage, m_unk0x24); storage.Write(m_unk0x24);
Write(&fileStorage, (MxU16) m_currentAct); storage.Write((MxU16) m_currentAct);
Write(&fileStorage, m_actorId); storage.Write(m_actorId);
for (i = 0; i < sizeOfArray(g_colorSaveData); i++) { for (i = 0; i < sizeOfArray(g_colorSaveData); i++) {
if (WriteVariable(&fileStorage, variableTable, g_colorSaveData[i].m_targetName) == FAILURE) { if (WriteVariable(&storage, variableTable, g_colorSaveData[i].m_targetName) == FAILURE) {
goto done; goto done;
} }
} }
if (WriteVariable(&fileStorage, variableTable, "backgroundcolor") == FAILURE) { if (WriteVariable(&storage, variableTable, "backgroundcolor") == FAILURE) {
goto done; goto done;
} }
if (WriteVariable(&fileStorage, variableTable, "lightposition") == FAILURE) { if (WriteVariable(&storage, variableTable, "lightposition") == FAILURE) {
goto done; goto done;
} }
WriteEndOfVariables(&fileStorage); WriteEndOfVariables(&storage);
CharacterManager()->Write(&fileStorage); CharacterManager()->Write(&storage);
PlantManager()->Write(&fileStorage); PlantManager()->Write(&storage);
result = BuildingManager()->Write(&fileStorage); result = BuildingManager()->Write(&storage);
for (j = 0; j < m_stateCount; j++) { for (j = 0; j < m_stateCount; j++) {
if (m_stateArray[j]->IsSerializable()) { if (m_stateArray[j]->IsSerializable()) {
@ -283,16 +284,16 @@ MxResult LegoGameState::Save(MxULong p_slot)
} }
} }
Write(&fileStorage, count); storage.Write(count);
for (j = 0; j < m_stateCount; j++) { for (j = 0; j < m_stateCount; j++) {
if (m_stateArray[j]->IsSerializable()) { if (m_stateArray[j]->IsSerializable()) {
m_stateArray[j]->Serialize(&fileStorage); m_stateArray[j]->Serialize(&storage);
} }
} }
area = m_unk0x42c; area = m_unk0x42c;
Write(&fileStorage, (MxU16) area); storage.Write((MxU16) area);
SerializeScoreHistory(2); SerializeScoreHistory(2);
m_isDirty = FALSE; m_isDirty = FALSE;
@ -324,42 +325,43 @@ MxResult LegoGameState::DeleteState()
} }
// FUNCTION: LEGO1 0x10039c60 // FUNCTION: LEGO1 0x10039c60
// FUNCTION: BETA10 0x10084329
MxResult LegoGameState::Load(MxULong p_slot) MxResult LegoGameState::Load(MxULong p_slot)
{ {
MxResult result = FAILURE; MxResult result = FAILURE;
LegoFile fileStorage; LegoFile storage;
MxVariableTable* variableTable = VariableTable(); MxVariableTable* variableTable = VariableTable();
MxString savePath; MxString savePath;
GetFileSavePath(&savePath, p_slot); GetFileSavePath(&savePath, p_slot);
if (fileStorage.Open(savePath.GetData(), LegoFile::c_read) == FAILURE) { if (storage.Open(savePath.GetData(), LegoFile::c_read) == FAILURE) {
goto done; goto done;
} }
MxU32 version, status; MxS32 version;
MxU32 status;
MxS16 count, actArea; MxS16 count, actArea;
const char* lightPosition; const char* lightPosition;
Read(&fileStorage, &version); storage.Read(version);
if (version != 0x1000c) { if (version != 0x1000c) {
OmniError("Saved game version mismatch", 0); OmniError("Saved game version mismatch", 0);
goto done; goto done;
} }
Read(&fileStorage, &m_unk0x24); storage.Read(m_unk0x24);
storage.Read(actArea);
Read(&fileStorage, &actArea);
SetCurrentAct((Act) actArea); SetCurrentAct((Act) actArea);
storage.Read(m_actorId);
Read(&fileStorage, &m_actorId);
if (m_actorId) { if (m_actorId) {
SetActor(m_actorId); SetActor(m_actorId);
} }
do { do {
status = ReadVariable(&fileStorage, variableTable); status = ReadVariable(&storage, variableTable);
if (status == 1) { if (status == 1) {
goto done; goto done;
} }
@ -372,13 +374,13 @@ MxResult LegoGameState::Load(MxULong p_slot)
SetLightPosition(atoi(lightPosition)); SetLightPosition(atoi(lightPosition));
} }
if (CharacterManager()->Read(&fileStorage) == FAILURE) { if (CharacterManager()->Read(&storage) == FAILURE) {
goto done; goto done;
} }
if (PlantManager()->Read(&fileStorage) == FAILURE) { if (PlantManager()->Read(&storage) == FAILURE) {
goto done; goto done;
} }
if (BuildingManager()->Read(&fileStorage) == FAILURE) { if (BuildingManager()->Read(&storage) == FAILURE) {
goto done; goto done;
} }
if (DeleteState() != SUCCESS) { if (DeleteState() != SUCCESS) {
@ -386,14 +388,11 @@ MxResult LegoGameState::Load(MxULong p_slot)
} }
char stateName[80]; char stateName[80];
Read(&fileStorage, &count); storage.Read(count);
if (count) { if (count) {
for (MxS16 i = 0; i < count; i++) { for (MxS16 i = 0; i < count; i++) {
MxS16 stateNameLength; storage.Read(stateName);
Read(&fileStorage, &stateNameLength);
Read(&fileStorage, stateName, (MxULong) stateNameLength);
stateName[stateNameLength] = 0;
LegoState* state = GetState(stateName); LegoState* state = GetState(stateName);
if (!state) { if (!state) {
@ -404,11 +403,11 @@ MxResult LegoGameState::Load(MxULong p_slot)
} }
} }
state->Serialize(&fileStorage); state->Serialize(&storage);
} }
} }
Read(&fileStorage, &actArea); storage.Read(actArea);
if (m_currentAct == e_act1) { if (m_currentAct == e_act1) {
m_unk0x42c = e_undefined; m_unk0x42c = e_undefined;
@ -539,10 +538,10 @@ void LegoGameState::SerializePlayersInfo(MxS16 p_flags)
if (fileStorage.Open(playersGSI.GetData(), p_flags) == SUCCESS) { if (fileStorage.Open(playersGSI.GetData(), p_flags) == SUCCESS) {
if (fileStorage.IsReadMode()) { if (fileStorage.IsReadMode()) {
Read(&fileStorage, &m_playerCount); fileStorage.Read(m_playerCount);
} }
else if (fileStorage.IsWriteMode()) { else if (fileStorage.IsWriteMode()) {
Write(&fileStorage, m_playerCount); fileStorage.Write(m_playerCount);
} }
for (MxS16 i = 0; i < m_playerCount; i++) { for (MxS16 i = 0; i < m_playerCount; i++) {
@ -1155,16 +1154,16 @@ LegoGameState::Username::Username()
// FUNCTION: LEGO1 0x1003c690 // FUNCTION: LEGO1 0x1003c690
// FUNCTION: BETA10 0x10086c57 // FUNCTION: BETA10 0x10086c57
MxResult LegoGameState::Username::Serialize(LegoStorage* p_storage) MxResult LegoGameState::Username::Serialize(LegoFile* p_file)
{ {
if (p_storage->IsReadMode()) { if (p_file->IsReadMode()) {
for (MxS16 i = 0; i < (MxS16) sizeOfArray(m_letters); i++) { for (MxS16 i = 0; i < (MxS16) sizeOfArray(m_letters); i++) {
Read(p_storage, &m_letters[i]); p_file->Read(m_letters[i]);
} }
} }
else if (p_storage->IsWriteMode()) { else if (p_file->IsWriteMode()) {
for (MxS16 i = 0; i < (MxS16) sizeOfArray(m_letters); i++) { for (MxS16 i = 0; i < (MxS16) sizeOfArray(m_letters); i++) {
Write(p_storage, m_letters[i]); p_file->Write(m_letters[i]);
} }
} }
@ -1184,28 +1183,28 @@ LegoGameState::Username& LegoGameState::Username::operator=(const Username& p_ot
MxResult LegoGameState::ScoreItem::Serialize(LegoFile* p_file) MxResult LegoGameState::ScoreItem::Serialize(LegoFile* p_file)
{ {
if (p_file->IsReadMode()) { if (p_file->IsReadMode()) {
Read(p_file, &m_totalScore); p_file->Read(m_totalScore);
for (MxS32 i = 0; i < 5; i++) { for (MxS32 i = 0; i < 5; i++) {
for (MxS32 j = 0; j < 5; j++) { for (MxS32 j = 0; j < 5; j++) {
Read(p_file, &m_scores[i][j]); p_file->Read(m_scores[i][j]);
} }
} }
m_name.Serialize(p_file); m_name.Serialize(p_file);
Read(p_file, &m_unk0x2a); p_file->Read(m_unk0x2a);
} }
else if (p_file->IsWriteMode()) { else if (p_file->IsWriteMode()) {
Write(p_file, m_totalScore); p_file->Write(m_totalScore);
for (MxS32 i = 0; i < 5; i++) { for (MxS32 i = 0; i < 5; i++) {
for (MxS32 j = 0; j < 5; j++) { for (MxS32 j = 0; j < 5; j++) {
Write(p_file, m_scores[i][j]); p_file->Write(m_scores[i][j]);
} }
} }
m_name.Serialize(p_file); m_name.Serialize(p_file);
Write(p_file, m_unk0x2a); p_file->Write(m_unk0x2a);
} }
return SUCCESS; return SUCCESS;
@ -1330,21 +1329,21 @@ LegoGameState::ScoreItem* LegoGameState::History::FUN_1003cc90(
MxResult LegoGameState::History::Serialize(LegoFile* p_file) MxResult LegoGameState::History::Serialize(LegoFile* p_file)
{ {
if (p_file->IsReadMode()) { if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x372); p_file->Read(m_unk0x372);
Read(p_file, &m_count); p_file->Read(m_count);
for (MxS16 i = 0; i < m_count; i++) { for (MxS16 i = 0; i < m_count; i++) {
MxS16 j; MxS16 j;
Read(p_file, &j); p_file->Read(j);
m_scores[i].Serialize(p_file); m_scores[i].Serialize(p_file);
} }
} }
else if (p_file->IsWriteMode()) { else if (p_file->IsWriteMode()) {
Write(p_file, m_unk0x372); p_file->Write(m_unk0x372);
Write(p_file, m_count); p_file->Write(m_count);
for (MxS16 i = 0; i < m_count; i++) { for (MxS16 i = 0; i < m_count; i++) {
Write(p_file, i); p_file->Write(i);
m_scores[i].Serialize(p_file); m_scores[i].Serialize(p_file);
} }
} }

View file

@ -689,7 +689,7 @@ LegoNamedTexture* ReadNamedTexture(LegoFile* p_file)
LegoNamedTexture* namedTexture = NULL; LegoNamedTexture* namedTexture = NULL;
MxString string; MxString string;
p_file->ReadString(string); p_file->Read(string);
texture = new LegoTexture(); texture = new LegoTexture();
if (texture != NULL) { if (texture != NULL) {
@ -766,7 +766,7 @@ void WriteDefaultTexture(LegoFile* p_file, const char* p_name)
LegoTexture texture; LegoTexture texture;
texture.SetImage(image); texture.SetImage(image);
p_file->WriteString(name); p_file->Write(MxString(name));
texture.Write(p_file); texture.Write(p_file);
} }
else { else {
@ -783,7 +783,7 @@ void WriteDefaultTexture(LegoFile* p_file, const char* p_name)
// FUNCTION: LEGO1 0x1003f8a0 // FUNCTION: LEGO1 0x1003f8a0
void WriteNamedTexture(LegoFile* p_file, LegoNamedTexture* p_namedTexture) void WriteNamedTexture(LegoFile* p_file, LegoNamedTexture* p_namedTexture)
{ {
p_file->WriteString(*p_namedTexture->GetName()); p_file->Write(MxString(*p_namedTexture->GetName()));
p_namedTexture->GetTexture()->Write(p_file); p_namedTexture->GetTexture()->Write(p_file);
} }

View file

@ -743,7 +743,7 @@ void LegoWorld::Enable(MxBool p_enable)
SetIsWorldActive(TRUE); SetIsWorldActive(TRUE);
#endif #endif
} }
else if (!p_enable && m_set0xd0.size() != 0) { else if (!p_enable && m_set0xd0.size() == 0) {
MxPresenter* presenter; MxPresenter* presenter;
LegoPathController* controller; LegoPathController* controller;
LegoPathActor* actor = UserActor(); LegoPathActor* actor = UserActor();

View file

@ -491,29 +491,6 @@ MxU32 LegoPathActor::VTable0x6c(
return 0; return 0;
} }
// FUNCTION: LEGO1 0x1002ebe0
// FUNCTION: BETA10 0x100af35e
MxS32 LegoPathActor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3)
{
Mx3DPointFloat v2(p_v2);
v2 -= p_v1;
float len = v2.LenSquared();
if (len <= 0.001) {
return 0;
}
len = sqrt(len);
v2 /= len;
float radius = m_roi->GetWorldBoundingSphere().Radius();
list<LegoPathBoundary*> boundaries;
return FUN_1002edd0(boundaries, m_boundary, p_v1, v2, len, radius, p_v3, 0);
}
// FUNCTION: LEGO1 0x1002edd0
inline MxU32 LegoPathActor::FUN_1002edd0( inline MxU32 LegoPathActor::FUN_1002edd0(
list<LegoPathBoundary*>& p_boundaries, list<LegoPathBoundary*>& p_boundaries,
LegoPathBoundary* p_boundary, LegoPathBoundary* p_boundary,
@ -527,41 +504,65 @@ inline MxU32 LegoPathActor::FUN_1002edd0(
{ {
MxU32 result = VTable0x6c(p_boundary, p_v1, p_v2, p_f1, p_f2, p_v3); MxU32 result = VTable0x6c(p_boundary, p_v1, p_v2, p_f1, p_f2, p_v3);
if (result == 0) { if (result != 0) {
p_boundaries.push_back(p_boundary); return result;
}
if (p_und >= 2) { p_boundaries.push_back(p_boundary);
return 0;
}
LegoS32 numEdges = p_boundary->GetNumEdges(); if (p_und >= 2) {
for (MxS32 i = 0; i < numEdges; i++) { return 0;
LegoUnknown100db7f4* edge = ((LegoUnknown100db7f4*) p_boundary->GetEdges()[i]); }
LegoPathBoundary* boundary = (LegoPathBoundary*) edge->OtherFace(p_boundary);
if (boundary != NULL) { LegoS32 numEdges = p_boundary->GetNumEdges();
list<LegoPathBoundary*>::iterator it; for (MxS32 i = 0; i < numEdges; i++) {
LegoUnknown100db7f4* edge = p_boundary->GetEdges()[i];
LegoPathBoundary* boundary = (LegoPathBoundary*) edge->OtherFace(p_boundary);
for (it = p_boundaries.begin(); it != p_boundaries.end(); it++) { if (boundary != NULL) {
if ((*it) == boundary) { list<LegoPathBoundary*>::const_iterator it;
break;
} for (it = p_boundaries.begin(); !(it == p_boundaries.end()); it++) {
if ((*it) == boundary) {
break;
} }
}
if (it == p_boundaries.end()) { if (it == p_boundaries.end()) {
result = FUN_1002edd0(p_boundaries, boundary, p_v1, p_v2, p_f1, p_f2, p_v3, p_und + 1); result = FUN_1002edd0(p_boundaries, boundary, p_v1, p_v2, p_f1, p_f2, p_v3, p_und + 1);
if (result != 0) { if (result != 0) {
return result; return result;
}
} }
} }
} }
result = 0;
} }
return result; return 0;
}
// FUNCTION: LEGO1 0x1002ebe0
// FUNCTION: BETA10 0x100af35e
MxS32 LegoPathActor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3)
{
assert(m_boundary && m_roi);
Mx3DPointFloat v2(p_v2);
v2 -= p_v1;
float len = v2.LenSquared();
if (len <= 0.001) {
return 0;
}
len = sqrt((double) len);
v2 /= len;
float radius = m_roi->GetWorldBoundingSphere().Radius();
list<LegoPathBoundary*> boundaries;
return FUN_1002edd0(boundaries, m_boundary, p_v1, v2, len, radius, p_v3, 0);
} }
// FUNCTION: LEGO1 0x1002f020 // FUNCTION: LEGO1 0x1002f020

View file

@ -515,18 +515,18 @@ MxResult GasStationState::Serialize(LegoFile* p_file)
LegoState::Serialize(p_file); LegoState::Serialize(p_file);
if (p_file->IsWriteMode()) { if (p_file->IsWriteMode()) {
Write(p_file, m_pepperAction); p_file->Write(m_pepperAction);
Write(p_file, m_mamaAction); p_file->Write(m_mamaAction);
Write(p_file, m_papaAction); p_file->Write(m_papaAction);
Write(p_file, m_nickAction); p_file->Write(m_nickAction);
Write(p_file, m_lauraAction); p_file->Write(m_lauraAction);
} }
else if (p_file->IsReadMode()) { else if (p_file->IsReadMode()) {
Read(p_file, &m_pepperAction); p_file->Read(m_pepperAction);
Read(p_file, &m_mamaAction); p_file->Read(m_mamaAction);
Read(p_file, &m_papaAction); p_file->Read(m_papaAction);
Read(p_file, &m_nickAction); p_file->Read(m_nickAction);
Read(p_file, &m_lauraAction); p_file->Read(m_lauraAction);
} }
return SUCCESS; return SUCCESS;

View file

@ -696,25 +696,26 @@ HospitalState::HospitalState()
} }
// FUNCTION: LEGO1 0x10076530 // FUNCTION: LEGO1 0x10076530
// FUNCTION: BETA10 0x1002db26
MxResult HospitalState::Serialize(LegoFile* p_file) MxResult HospitalState::Serialize(LegoFile* p_file)
{ {
LegoState::Serialize(p_file); LegoState::Serialize(p_file);
if (p_file->IsWriteMode()) { if (p_file->IsWriteMode()) {
Write(p_file, m_unk0x0c); p_file->Write(m_unk0x0c);
Write(p_file, m_unk0x0e); p_file->Write(m_unk0x0e);
Write(p_file, m_unk0x10); p_file->Write(m_unk0x10);
Write(p_file, m_unk0x12); p_file->Write(m_unk0x12);
Write(p_file, m_unk0x14); p_file->Write(m_unk0x14);
Write(p_file, m_unk0x16); p_file->Write(m_unk0x16);
} }
else if (p_file->IsReadMode()) { else if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x0c); p_file->Read(m_unk0x0c);
Read(p_file, &m_unk0x0e); p_file->Read(m_unk0x0e);
Read(p_file, &m_unk0x10); p_file->Read(m_unk0x10);
Read(p_file, &m_unk0x12); p_file->Read(m_unk0x12);
Read(p_file, &m_unk0x14); p_file->Read(m_unk0x14);
Read(p_file, &m_unk0x16); p_file->Read(m_unk0x16);
} }
return SUCCESS; return SUCCESS;

View file

@ -1186,6 +1186,12 @@ void Isle::CreateState()
} }
} }
// FUNCTION: LEGO1 0x10033170
void Isle::VTable0x60()
{
// empty
}
// FUNCTION: LEGO1 0x10033180 // FUNCTION: LEGO1 0x10033180
MxBool Isle::Escape() MxBool Isle::Escape()
{ {
@ -1331,82 +1337,83 @@ MxResult Act1State::Serialize(LegoFile* p_file)
m_racecarPlane.Serialize(p_file); m_racecarPlane.Serialize(p_file);
if (p_file->IsWriteMode()) { if (p_file->IsWriteMode()) {
if (m_helicopterPlane.IsPresent()) { // TODO: Seems to match better when using strcmp directly instead of IsPresent
if (m_helicopterWindshield) { if (strcmp(m_helicopterPlane.m_name.GetData(), "")) {
WriteNamedTexture(p_file, m_helicopterWindshield); if (!m_helicopterWindshield) {
}
else {
WriteDefaultTexture(p_file, "chwind.gif"); WriteDefaultTexture(p_file, "chwind.gif");
} }
if (m_helicopterJetLeft) {
WriteNamedTexture(p_file, m_helicopterJetLeft);
}
else { else {
WriteNamedTexture(p_file, m_helicopterWindshield);
}
if (!m_helicopterJetLeft) {
WriteDefaultTexture(p_file, "chjetl.gif"); WriteDefaultTexture(p_file, "chjetl.gif");
} }
if (m_helicopterJetRight) {
WriteNamedTexture(p_file, m_helicopterJetRight);
}
else { else {
WriteNamedTexture(p_file, m_helicopterJetLeft);
}
if (!m_helicopterJetRight) {
WriteDefaultTexture(p_file, "chjetr.gif"); WriteDefaultTexture(p_file, "chjetr.gif");
} }
else {
WriteNamedTexture(p_file, m_helicopterJetRight);
}
} }
if (m_jetskiPlane.IsPresent()) { if (strcmp(m_jetskiPlane.m_name.GetData(), "")) {
if (m_jetskiFront) { if (!m_jetskiFront) {
WriteNamedTexture(p_file, m_jetskiFront);
}
else {
WriteDefaultTexture(p_file, "jsfrnt.gif"); WriteDefaultTexture(p_file, "jsfrnt.gif");
} }
if (m_jetskiWindshield) {
WriteNamedTexture(p_file, m_jetskiWindshield);
}
else { else {
WriteNamedTexture(p_file, m_jetskiFront);
}
if (!m_jetskiWindshield) {
WriteDefaultTexture(p_file, "jswnsh.gif"); WriteDefaultTexture(p_file, "jswnsh.gif");
} }
else {
WriteNamedTexture(p_file, m_jetskiWindshield);
}
} }
if (m_dunebuggyPlane.IsPresent()) { if (strcmp(m_dunebuggyPlane.m_name.GetData(), "")) {
if (m_dunebuggyFront) { if (!m_dunebuggyFront) {
WriteNamedTexture(p_file, m_dunebuggyFront);
}
else {
WriteDefaultTexture(p_file, "dbfrfn.gif"); WriteDefaultTexture(p_file, "dbfrfn.gif");
} }
else {
WriteNamedTexture(p_file, m_dunebuggyFront);
}
} }
if (m_racecarPlane.IsPresent()) { if (strcmp(m_racecarPlane.m_name.GetData(), "")) {
if (m_racecarFront) { if (!m_racecarFront) {
WriteNamedTexture(p_file, m_racecarFront);
}
else {
WriteDefaultTexture(p_file, "rcfrnt.gif"); WriteDefaultTexture(p_file, "rcfrnt.gif");
} }
if (m_racecarBack) {
WriteNamedTexture(p_file, m_racecarBack);
}
else { else {
WriteNamedTexture(p_file, m_racecarFront);
}
if (!m_racecarBack) {
WriteDefaultTexture(p_file, "rcback.gif"); WriteDefaultTexture(p_file, "rcback.gif");
} }
else {
WriteNamedTexture(p_file, m_racecarBack);
}
if (m_racecarTail) { if (!m_racecarTail) {
WriteNamedTexture(p_file, m_racecarTail); WriteDefaultTexture(p_file, "rctail.gif");
} }
else { else {
WriteDefaultTexture(p_file, "rctail.gif"); WriteNamedTexture(p_file, m_racecarTail);
} }
} }
m_cptClickDialogue.WriteToFile(p_file); p_file->Write(m_cptClickDialogue.m_nextIndex);
Write(p_file, m_unk0x022); p_file->Write(m_unk0x022);
} }
else if (p_file->IsReadMode()) { else if (p_file->IsReadMode()) {
if (m_helicopterPlane.IsPresent()) { if (strcmp(m_helicopterPlane.m_name.GetData(), "")) {
m_helicopterWindshield = ReadNamedTexture(p_file); m_helicopterWindshield = ReadNamedTexture(p_file);
if (m_helicopterWindshield == NULL) { if (m_helicopterWindshield == NULL) {
return FAILURE; return FAILURE;
@ -1423,7 +1430,7 @@ MxResult Act1State::Serialize(LegoFile* p_file)
} }
} }
if (m_jetskiPlane.IsPresent()) { if (strcmp(m_jetskiPlane.m_name.GetData(), "")) {
m_jetskiFront = ReadNamedTexture(p_file); m_jetskiFront = ReadNamedTexture(p_file);
if (m_jetskiFront == NULL) { if (m_jetskiFront == NULL) {
return FAILURE; return FAILURE;
@ -1435,14 +1442,14 @@ MxResult Act1State::Serialize(LegoFile* p_file)
} }
} }
if (m_dunebuggyPlane.IsPresent()) { if (strcmp(m_dunebuggyPlane.m_name.GetData(), "")) {
m_dunebuggyFront = ReadNamedTexture(p_file); m_dunebuggyFront = ReadNamedTexture(p_file);
if (m_dunebuggyFront == NULL) { if (m_dunebuggyFront == NULL) {
return FAILURE; return FAILURE;
} }
} }
if (m_racecarPlane.IsPresent()) { if (strcmp(m_racecarPlane.m_name.GetData(), "")) {
m_racecarFront = ReadNamedTexture(p_file); m_racecarFront = ReadNamedTexture(p_file);
if (m_racecarFront == NULL) { if (m_racecarFront == NULL) {
return FAILURE; return FAILURE;
@ -1459,11 +1466,10 @@ MxResult Act1State::Serialize(LegoFile* p_file)
} }
} }
m_cptClickDialogue.ReadFromFile(p_file); p_file->Read(m_cptClickDialogue.m_nextIndex);
Read(p_file, &m_unk0x022); p_file->Read(m_unk0x022);
} }
// TODO
return SUCCESS; return SUCCESS;
} }

View file

@ -208,15 +208,16 @@ PoliceState::PoliceState()
} }
// FUNCTION: LEGO1 0x1005e990 // FUNCTION: LEGO1 0x1005e990
// FUNCTION: BETA10 0x100f08b0
MxResult PoliceState::Serialize(LegoFile* p_file) MxResult PoliceState::Serialize(LegoFile* p_file)
{ {
LegoState::Serialize(p_file); LegoState::Serialize(p_file);
if (p_file->IsReadMode()) { if (p_file->IsReadMode()) {
Read(p_file, &m_policeScript); p_file->Read((MxS32&) m_policeScript);
} }
else { else {
Write(p_file, m_policeScript); p_file->Write((MxS32) m_policeScript);
} }
return SUCCESS; return SUCCESS;

View file

@ -40,18 +40,6 @@ protected:
LegoU8 m_mode; // 0x04 LegoU8 m_mode; // 0x04
}; };
template <class T>
inline void Read(LegoStorage* p_storage, T* p_variable, LegoU32 p_size = sizeof(T))
{
p_storage->Read(p_variable, p_size);
}
template <class T>
inline void Write(LegoStorage* p_storage, T p_variable)
{
p_storage->Write(&p_variable, sizeof(p_variable));
}
// VTABLE: LEGO1 0x100db710 // VTABLE: LEGO1 0x100db710
// SIZE 0x10 // SIZE 0x10
class LegoMemory : public LegoStorage { class LegoMemory : public LegoStorage {
@ -98,50 +86,148 @@ public:
LegoResult SetPosition(LegoU32 p_position) override; // vtable+0x10 LegoResult SetPosition(LegoU32 p_position) override; // vtable+0x10
LegoResult Open(const char* p_name, LegoU32 p_mode); LegoResult Open(const char* p_name, LegoU32 p_mode);
// FUNCTION: LEGO1 0x100343d0 // FUNCTION: LEGO1 0x10006030
LegoStorage* WriteVector3(Mx3DPointFloat p_vec3) // FUNCTION: BETA10 0x10017bb0
LegoStorage* Write(MxString p_data)
{ {
::Write(this, p_vec3[0]); Write(p_data.GetData());
::Write(this, p_vec3[1]);
::Write(this, p_vec3[2]);
return this; return this;
} }
// FUNCTION: LEGO1 0x10034430 // FUNCTION: BETA10 0x10017c80
LegoStorage* ReadVector3(Mx3DPointFloat& p_vec3) LegoStorage* Write(const char* p_data)
{ {
::Read(this, &p_vec3[0]); LegoS16 length = strlen(p_data);
::Read(this, &p_vec3[1]); Write(length);
::Read(this, &p_vec3[2]); Write(p_data, length);
return this;
}
// FUNCTION: BETA10 0x1004b0d0
LegoStorage* Write(LegoU8 p_data)
{
Write(&p_data, sizeof(p_data));
return this;
}
// FUNCTION: BETA10 0x10017ce0
LegoStorage* Write(LegoS16 p_data)
{
Write(&p_data, sizeof(p_data));
return this;
}
// FUNCTION: BETA10 0x1004b110
LegoStorage* Write(LegoU16 p_data)
{
Write(&p_data, sizeof(p_data));
return this;
}
// TODO: Type might be different (LegoS32). MxS32 is incompatible with LegoS32.
// FUNCTION: BETA10 0x10088540
LegoStorage* Write(MxS32 p_data)
{
Write(&p_data, sizeof(p_data));
return this;
}
// TODO: Type might be different (LegoU32). MxU32 is incompatible with LegoU32.
// FUNCTION: BETA10 0x1004b150
LegoStorage* Write(MxU32 p_data)
{
Write(&p_data, sizeof(p_data));
return this;
}
LegoStorage* Write(LegoFloat p_data)
{
Write(&p_data, sizeof(p_data));
return this;
}
// FUNCTION: LEGO1 0x100343d0
LegoStorage* Write(Mx3DPointFloat p_vec)
{
Write(p_vec[0]);
Write(p_vec[1]);
Write(p_vec[2]);
return this;
}
LegoStorage* Read(char* p_data)
{
LegoS16 length;
Read(length);
Read(p_data, length);
p_data[length] = '\0';
return this; return this;
} }
// FUNCTION: LEGO1 0x10034470 // FUNCTION: LEGO1 0x10034470
LegoStorage* ReadString(MxString& p_str) LegoStorage* Read(MxString& p_data)
{ {
MxS16 len; LegoS16 length;
Read(&len, sizeof(MxS16)); Read(length);
char* text = new char[len + 1]; char* text = new char[length + 1];
Read(text, len); Read(text, length);
text[len] = '\0'; text[length] = '\0';
p_str = text; p_data = text;
delete[] text; delete[] text;
return this; return this;
} }
// FUNCTION: LEGO1 0x10006030 // FUNCTION: BETA10 0x1004b190
LegoStorage* WriteString(MxString p_str) LegoStorage* Read(LegoU8& p_data)
{ {
const char* data = p_str.GetData(); Read(&p_data, sizeof(p_data));
LegoU32 fullLength = strlen(data); return this;
}
LegoU16 limitedLength = (LegoU16) fullLength; // FUNCTION: BETA10 0x10024680
Write(&limitedLength, sizeof(limitedLength)); LegoStorage* Read(LegoS16& p_data)
Write((char*) data, (LegoS16) fullLength); {
Read(&p_data, sizeof(p_data));
return this;
}
// FUNCTION: BETA10 0x1004b1d0
LegoStorage* Read(LegoU16& p_data)
{
Read(&p_data, sizeof(p_data));
return this;
}
// TODO: Type might be different (LegoS32). MxS32 is incompatible with LegoS32.
// FUNCTION: BETA10 0x10088580
LegoStorage* Read(MxS32& p_data)
{
Read(&p_data, sizeof(p_data));
return this;
}
// TODO: Type might be different (LegoU32). MxU32 is incompatible with LegoU32.
// FUNCTION: BETA10 0x1004b210
LegoStorage* Read(MxU32& p_data)
{
Read(&p_data, sizeof(p_data));
return this;
}
LegoStorage* Read(LegoFloat& p_data)
{
Read(&p_data, sizeof(p_data));
return this;
}
// FUNCTION: LEGO1 0x10034430
LegoStorage* Read(Mx3DPointFloat& p_vec)
{
Read(p_vec[0]);
Read(p_vec[1]);
Read(p_vec[2]);
return this; return this;
} }