From 5c57b805de5b6c15cca9d575d0c0e15dd020edca Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 11 Jan 2025 11:39:27 -0700 Subject: [PATCH 1/3] Fix regression in `LegoWorld::Enable` (#1329) * Fix regression in `LegoWorld::Enable` * Update legoworld.cpp --- LEGO1/lego/legoomni/src/entity/legoworld.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index b49df6c3..34e77757 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -741,7 +741,7 @@ void LegoWorld::Enable(MxBool p_enable) SetIsWorldActive(TRUE); #endif } - else if (!p_enable && m_set0xd0.size() != 0) { + else if (!p_enable && m_set0xd0.size() == 0) { MxPresenter* presenter; LegoPathController* controller; LegoPathActor* actor = UserActor(); From f95eedd0cee8b07c6ede744673cfa201cfff76b7 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sun, 12 Jan 2025 13:31:58 -0700 Subject: [PATCH 2/3] Improve match of `LegoPathActor::FUN_1002edd0`, reorder (#1332) * Relocate annotation * Improve match of `LegoBuildingManager::ScheduleAnimation` * try fix * Revert "try fix" This reverts commit e8f5db6fec92e87fae5cd177f6b4880e81519bfe. * Order isle * Move annotation --- LEGO1/lego/legoomni/include/isle.h | 17 ++-- LEGO1/lego/legoomni/include/legopathactor.h | 3 + .../src/common/legobuildingmanager.cpp | 6 +- .../lego/legoomni/src/paths/legopathactor.cpp | 91 ++++++++++--------- LEGO1/lego/legoomni/src/worlds/isle.cpp | 6 ++ 5 files changed, 67 insertions(+), 56 deletions(-) diff --git a/LEGO1/lego/legoomni/include/isle.h b/LEGO1/lego/legoomni/include/isle.h index 9eb7e760..cb845914 100644 --- a/LEGO1/lego/legoomni/include/isle.h +++ b/LEGO1/lego/legoomni/include/isle.h @@ -118,6 +118,9 @@ class Isle : public LegoWorld { MxLong Notify(MxParam& p_param) override; // vtable+0x04 + // FUNCTION: LEGO1 0x10030900 + MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c + // FUNCTION: LEGO1 0x10030910 // FUNCTION: BETA10 0x10035d70 const char* ClassName() const override // vtable+0x0c @@ -135,16 +138,10 @@ class Isle : public LegoWorld { MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 void ReadyWorld() override; // vtable+0x50 void Add(MxCore* p_object) override; // vtable+0x58 - - // FUNCTION: LEGO1 0x10030900 - MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c - - // 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 VTable0x60() override; // vtable+0x60 + 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; } MxBool HasHelicopter() { return m_helicopter != NULL; } diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 343cd598..98c41d08 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -198,6 +198,9 @@ class LegoPathActor : public LegoActor { MxFloat m_unk0x150; // 0x150 }; +// FUNCTION: LEGO1 0x1002edd0 +// LegoPathActor::FUN_1002edd0 + // TEMPLATE: LEGO1 0x10018b70 // List::~List diff --git a/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp index 2d97b3ef..fa6f83ef 100644 --- a/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp @@ -680,7 +680,11 @@ void LegoBuildingManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_lengt entry->m_entity = p_entity; 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_muted = p_haveSound == FALSE; FUN_100307b0(p_entity, -2); diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index 6c367f19..69a624ee 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -491,29 +491,6 @@ MxU32 LegoPathActor::VTable0x6c( 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 boundaries; - - return FUN_1002edd0(boundaries, m_boundary, p_v1, v2, len, radius, p_v3, 0); -} - -// FUNCTION: LEGO1 0x1002edd0 inline MxU32 LegoPathActor::FUN_1002edd0( list& p_boundaries, 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); - if (result == 0) { - p_boundaries.push_back(p_boundary); + if (result != 0) { + return result; + } - if (p_und >= 2) { - return 0; - } + p_boundaries.push_back(p_boundary); - LegoS32 numEdges = p_boundary->GetNumEdges(); - for (MxS32 i = 0; i < numEdges; i++) { - LegoUnknown100db7f4* edge = ((LegoUnknown100db7f4*) p_boundary->GetEdges()[i]); - LegoPathBoundary* boundary = (LegoPathBoundary*) edge->OtherFace(p_boundary); + if (p_und >= 2) { + return 0; + } - if (boundary != NULL) { - list::iterator it; + LegoS32 numEdges = p_boundary->GetNumEdges(); + 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 ((*it) == boundary) { - break; - } + if (boundary != NULL) { + list::const_iterator it; + + for (it = p_boundaries.begin(); !(it == p_boundaries.end()); it++) { + if ((*it) == boundary) { + break; } + } - if (it == p_boundaries.end()) { - result = FUN_1002edd0(p_boundaries, boundary, p_v1, p_v2, p_f1, p_f2, p_v3, p_und + 1); + if (it == p_boundaries.end()) { + result = FUN_1002edd0(p_boundaries, boundary, p_v1, p_v2, p_f1, p_f2, p_v3, p_und + 1); - if (result != 0) { - return result; - } + if (result != 0) { + return result; } } } + } + + return 0; +} - result = 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; } - return result; + len = sqrt((double) len); + v2 /= len; + + float radius = m_roi->GetWorldBoundingSphere().Radius(); + list boundaries; + + return FUN_1002edd0(boundaries, m_boundary, p_v1, v2, len, radius, p_v3, 0); } // FUNCTION: LEGO1 0x1002f020 diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 1d62e557..88fa83d7 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -1186,6 +1186,12 @@ void Isle::CreateState() } } +// FUNCTION: LEGO1 0x10033170 +void Isle::VTable0x60() +{ + // empty +} + // FUNCTION: LEGO1 0x10033180 MxBool Isle::Escape() { From 77a3dc079558f8a4da554ceaa5a9fc7eaea78478 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 15 Jan 2025 16:52:29 -0700 Subject: [PATCH 3/3] Match `Serialize` functions to BETA10 (#1334) * Begin refactor Serialize functions * Match more Serialize functions * Match `LegoVehicleBuildState::Serialize` * Match `LegoGameState::Username::Serialize` * Match `LegoGameState::ScoreItem::Serialize` * Match `LegoGameState::History::Serialize` * Var name * Var name * Revert "Var name" This reverts commit 1c0cccfba799450cfe4f75566dc1f32db1c76a6b. * Add other Serialize implementations * Add remaining Serialize implementations * Add Read for char* * Improvements --- LEGO1/lego/legoomni/include/legocarbuild.h | 7 +- LEGO1/lego/legoomni/include/legogamestate.h | 14 +- LEGO1/lego/legoomni/include/legonamedplane.h | 19 ++- LEGO1/lego/legoomni/include/legorace.h | 15 +- LEGO1/lego/legoomni/include/legostate.h | 20 +-- LEGO1/lego/legoomni/include/pizza.h | 18 -- LEGO1/lego/legoomni/src/actors/ambulance.cpp | 41 ++--- LEGO1/lego/legoomni/src/actors/pizza.cpp | 12 +- LEGO1/lego/legoomni/src/actors/pizzeria.cpp | 4 +- LEGO1/lego/legoomni/src/actors/radio.cpp | 7 +- LEGO1/lego/legoomni/src/actors/towtrack.cpp | 41 ++--- .../lego/legoomni/src/build/legocarbuild.cpp | 21 ++- .../src/common/legoanimationmanager.cpp | 98 ++++++----- .../legoomni/src/common/legogamestate.cpp | 107 ++++++------ LEGO1/lego/legoomni/src/common/legoutils.cpp | 6 +- LEGO1/lego/legoomni/src/worlds/gasstation.cpp | 20 +-- LEGO1/lego/legoomni/src/worlds/hospital.cpp | 25 +-- LEGO1/lego/legoomni/src/worlds/isle.cpp | 80 ++++----- LEGO1/lego/legoomni/src/worlds/police.cpp | 5 +- LEGO1/lego/sources/misc/legostorage.h | 156 ++++++++++++++---- 20 files changed, 399 insertions(+), 317 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocarbuild.h b/LEGO1/lego/legoomni/include/legocarbuild.h index 6add3be3..8afbee01 100644 --- a/LEGO1/lego/legoomni/include/legocarbuild.h +++ b/LEGO1/lego/legoomni/include/legocarbuild.h @@ -15,6 +15,7 @@ class MxSoundPresenter; class MxActionNotificationParam; // VTABLE: LEGO1 0x100d66e0 +// VTABLE: BETA10 0x101bb910 // SIZE 0x50 class LegoVehicleBuildState : public LegoState { public: @@ -32,13 +33,13 @@ class LegoVehicleBuildState : public LegoState { // FUNCTION: LEGO1 0x10025ff0 const char* ClassName() const override // vtable+0x0c { - return this->m_className.GetData(); + return m_className.GetData(); } // FUNCTION: LEGO1 0x10026000 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 @@ -56,7 +57,7 @@ class LegoVehicleBuildState : public LegoState { MxString m_className; // 0x38 AnimationState m_animationState; // 0x48 - undefined m_unk0x4c; // 0x4c + MxU8 m_unk0x4c; // 0x4c MxBool m_unk0x4d; // 0x4d MxBool m_unk0x4e; // 0x4e MxU8 m_placedPartCount; // 0x4f diff --git a/LEGO1/lego/legoomni/include/legogamestate.h b/LEGO1/lego/legoomni/include/legogamestate.h index b7eb47d9..858c13e6 100644 --- a/LEGO1/lego/legoomni/include/legogamestate.h +++ b/LEGO1/lego/legoomni/include/legogamestate.h @@ -111,7 +111,7 @@ class LegoGameState { Username(Username& p_other) { Set(p_other); } 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); MxS16 m_letters[7]; // 0x00 @@ -121,10 +121,10 @@ class LegoGameState { struct ScoreItem { MxResult Serialize(LegoFile* p_file); - MxS16 m_totalScore; // 0x00 - MxU8 m_scores[5][5]; // 0x02 - Username m_name; // 0x1c - undefined2 m_unk0x2a; // 0x2a + MxS16 m_totalScore; // 0x00 + MxU8 m_scores[5][5]; // 0x02 + Username m_name; // 0x1c + MxS16 m_unk0x2a; // 0x2a }; // SIZE 0x372 @@ -141,7 +141,7 @@ class LegoGameState { MxS16 m_count; // 0x00 ScoreItem m_scores[20]; // 0x02 - undefined2 m_unk0x372; // 0x372 + MxS16 m_unk0x372; // 0x372 }; LegoGameState(); @@ -214,7 +214,7 @@ class LegoGameState { // TODO: Most likely getters/setters are not used according to BETA for the following members: public: - MxU16 m_unk0x24; // 0x24 + MxS16 m_unk0x24; // 0x24 MxS16 m_playerCount; // 0x26 Username m_players[9]; // 0x28 History m_history; // 0xa6 diff --git a/LEGO1/lego/legoomni/include/legonamedplane.h b/LEGO1/lego/legoomni/include/legonamedplane.h index 43f97506..df91828a 100644 --- a/LEGO1/lego/legoomni/include/legonamedplane.h +++ b/LEGO1/lego/legoomni/include/legonamedplane.h @@ -24,6 +24,7 @@ class LegoNamedPlane { void SetDirection(const Mx3DPointFloat& p_direction) { m_direction = p_direction; } void SetUp(const Mx3DPointFloat& p_up) { m_up = p_up; } + // TODO: Unclear whether this was defined MxBool IsPresent() { return strcmp(m_name.GetData(), "") != 0; } void Reset() { m_name = ""; } @@ -31,22 +32,22 @@ class LegoNamedPlane { MxResult Serialize(LegoFile* p_file) { if (p_file->IsWriteMode()) { - p_file->WriteString(m_name); - p_file->WriteVector3(m_position); - p_file->WriteVector3(m_direction); - p_file->WriteVector3(m_up); + p_file->Write(MxString(m_name)); + p_file->Write(m_position); + p_file->Write(m_direction); + p_file->Write(m_up); } else if (p_file->IsReadMode()) { - p_file->ReadString(m_name); - p_file->ReadVector3(m_position); - p_file->ReadVector3(m_direction); - p_file->ReadVector3(m_up); + p_file->Read(m_name); + p_file->Read(m_position); + p_file->Read(m_direction); + p_file->Read(m_up); } return SUCCESS; } -private: + // private: MxString m_name; // 0x00 Mx3DPointFloat m_position; // 0x10 Mx3DPointFloat m_direction; // 0x24 diff --git a/LEGO1/lego/legoomni/include/legorace.h b/LEGO1/lego/legoomni/include/legorace.h index c508f3ed..cee2e4b6 100644 --- a/LEGO1/lego/legoomni/include/legorace.h +++ b/LEGO1/lego/legoomni/include/legorace.h @@ -42,14 +42,17 @@ class RaceState : public LegoState { MxResult Serialize(LegoFile* p_file) { if (p_file->IsReadMode()) { - Read(p_file, &m_id); - Read(p_file, &m_unk0x02); - Read(p_file, &m_score); + p_file->Read(m_id); + p_file->Read(m_unk0x02); + p_file->Read(m_score); } else if (p_file->IsWriteMode()) { - Write(p_file, m_id); - Write(p_file, m_unk0x02); - Write(p_file, m_score); + p_file->Write(m_id); + p_file->Write(m_unk0x02); + p_file->Write(m_score); + } + else { + return FAILURE; } return SUCCESS; diff --git a/LEGO1/lego/legoomni/include/legostate.h b/LEGO1/lego/legoomni/include/legostate.h index 09dc1fcf..940abe72 100644 --- a/LEGO1/lego/legoomni/include/legostate.h +++ b/LEGO1/lego/legoomni/include/legostate.h @@ -18,8 +18,7 @@ class LegoState : public MxCore { }; // SIZE 0x0c - class Playlist { - public: + struct Playlist { enum Mode { e_loop, e_once, @@ -60,21 +59,6 @@ class LegoState : public MxCore { MxU32 Next(); 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 MxS16 m_length; // 0x04 MxS16 m_mode; // 0x06 @@ -95,7 +79,7 @@ class LegoState : public MxCore { virtual MxResult Serialize(LegoFile* p_file) { if (p_file->IsWriteMode()) { - p_file->WriteString(ClassName()); + p_file->Write(MxString(ClassName())); } return SUCCESS; } // vtable+0x1c diff --git a/LEGO1/lego/legoomni/include/pizza.h b/LEGO1/lego/legoomni/include/pizza.h index b08e5310..855f2b59 100644 --- a/LEGO1/lego/legoomni/include/pizza.h +++ b/LEGO1/lego/legoomni/include/pizza.h @@ -93,24 +93,6 @@ class PizzaMissionState : public LegoState { // FUNCTION: BETA10 0x100ef7e0 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 MxU8 m_actorId; // 0x02 undefined2 m_unk0x04; // 0x04 diff --git a/LEGO1/lego/legoomni/src/actors/ambulance.cpp b/LEGO1/lego/legoomni/src/actors/ambulance.cpp index c2234f0a..a3f438f4 100644 --- a/LEGO1/lego/legoomni/src/actors/ambulance.cpp +++ b/LEGO1/lego/legoomni/src/actors/ambulance.cpp @@ -646,33 +646,34 @@ AmbulanceMissionState::AmbulanceMissionState() } // FUNCTION: LEGO1 0x10037440 +// FUNCTION: BETA10 0x10024480 MxResult AmbulanceMissionState::Serialize(LegoFile* p_file) { LegoState::Serialize(p_file); if (p_file->IsReadMode()) { - Read(p_file, &m_peScore); - Read(p_file, &m_maScore); - Read(p_file, &m_paScore); - Read(p_file, &m_niScore); - Read(p_file, &m_laScore); - Read(p_file, &m_peHighScore); - Read(p_file, &m_maHighScore); - Read(p_file, &m_paHighScore); - Read(p_file, &m_niHighScore); - Read(p_file, &m_laHighScore); + p_file->Read(m_peScore); + p_file->Read(m_maScore); + p_file->Read(m_paScore); + p_file->Read(m_niScore); + p_file->Read(m_laScore); + p_file->Read(m_peHighScore); + p_file->Read(m_maHighScore); + p_file->Read(m_paHighScore); + p_file->Read(m_niHighScore); + p_file->Read(m_laHighScore); } else if (p_file->IsWriteMode()) { - Write(p_file, m_peScore); - Write(p_file, m_maScore); - Write(p_file, m_paScore); - Write(p_file, m_niScore); - Write(p_file, m_laScore); - Write(p_file, m_peHighScore); - Write(p_file, m_maHighScore); - Write(p_file, m_paHighScore); - Write(p_file, m_niHighScore); - Write(p_file, m_laHighScore); + p_file->Write(m_peScore); + p_file->Write(m_maScore); + p_file->Write(m_paScore); + p_file->Write(m_niScore); + p_file->Write(m_laScore); + p_file->Write(m_peHighScore); + p_file->Write(m_maHighScore); + p_file->Write(m_paHighScore); + p_file->Write(m_niHighScore); + p_file->Write(m_laHighScore); } return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/actors/pizza.cpp b/LEGO1/lego/legoomni/src/actors/pizza.cpp index 7fd07808..a3a91218 100644 --- a/LEGO1/lego/legoomni/src/actors/pizza.cpp +++ b/LEGO1/lego/legoomni/src/actors/pizza.cpp @@ -605,18 +605,25 @@ PizzaMissionState::PizzaMissionState() } // FUNCTION: LEGO1 0x100393c0 +// FUNCTION: BETA10 0x100eebf2 MxResult PizzaMissionState::Serialize(LegoFile* p_file) { LegoState::Serialize(p_file); if (p_file->IsReadMode()) { 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()) { 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; } diff --git a/LEGO1/lego/legoomni/src/actors/pizzeria.cpp b/LEGO1/lego/legoomni/src/actors/pizzeria.cpp index a7681f87..54bf583b 100644 --- a/LEGO1/lego/legoomni/src/actors/pizzeria.cpp +++ b/LEGO1/lego/legoomni/src/actors/pizzeria.cpp @@ -124,12 +124,12 @@ MxResult PizzeriaState::Serialize(LegoFile* p_file) if (p_file->IsReadMode()) { for (MxS16 i = 0; i < 5; i++) { - m_unk0x08[i].ReadFromFile(p_file); + p_file->Read(m_unk0x08[i].m_nextIndex); } } else { for (MxS16 i = 0; i < 5; i++) { - m_unk0x08[i].WriteToFile(p_file); + p_file->Write(m_unk0x08[i].m_nextIndex); } } diff --git a/LEGO1/lego/legoomni/src/actors/radio.cpp b/LEGO1/lego/legoomni/src/actors/radio.cpp index 0291c18c..71fbf2bc 100644 --- a/LEGO1/lego/legoomni/src/actors/radio.cpp +++ b/LEGO1/lego/legoomni/src/actors/radio.cpp @@ -209,6 +209,7 @@ void Radio::CreateState() } // FUNCTION: LEGO1 0x1002ce10 +// FUNCTION: BETA10 0x100f20f6 RadioState::RadioState() { srand(Timer()->GetTime()); @@ -217,13 +218,13 @@ RadioState::RadioState() m_unk0x2c = random % 3; 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].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].SetNextIndex(rand() % sizeOfArray(g_unk0x100f3268)); + m_unk0x08[2].m_nextIndex = (rand() % sizeOfArray(g_unk0x100f3268)); m_active = FALSE; } diff --git a/LEGO1/lego/legoomni/src/actors/towtrack.cpp b/LEGO1/lego/legoomni/src/actors/towtrack.cpp index de2cb291..6baedc9b 100644 --- a/LEGO1/lego/legoomni/src/actors/towtrack.cpp +++ b/LEGO1/lego/legoomni/src/actors/towtrack.cpp @@ -609,33 +609,34 @@ TowTrackMissionState::TowTrackMissionState() } // FUNCTION: LEGO1 0x1004dde0 +// FUNCTION: BETA10 0x100f8720 MxResult TowTrackMissionState::Serialize(LegoFile* p_file) { LegoState::Serialize(p_file); if (p_file->IsReadMode()) { - Read(p_file, &m_peScore); - Read(p_file, &m_maScore); - Read(p_file, &m_paScore); - Read(p_file, &m_niScore); - Read(p_file, &m_laScore); - Read(p_file, &m_peHighScore); - Read(p_file, &m_maHighScore); - Read(p_file, &m_paHighScore); - Read(p_file, &m_niHighScore); - Read(p_file, &m_laHighScore); + p_file->Read(m_peScore); + p_file->Read(m_maScore); + p_file->Read(m_paScore); + p_file->Read(m_niScore); + p_file->Read(m_laScore); + p_file->Read(m_peHighScore); + p_file->Read(m_maHighScore); + p_file->Read(m_paHighScore); + p_file->Read(m_niHighScore); + p_file->Read(m_laHighScore); } else if (p_file->IsWriteMode()) { - Write(p_file, m_peScore); - Write(p_file, m_maScore); - Write(p_file, m_paScore); - Write(p_file, m_niScore); - Write(p_file, m_laScore); - Write(p_file, m_peHighScore); - Write(p_file, m_maHighScore); - Write(p_file, m_paHighScore); - Write(p_file, m_niHighScore); - Write(p_file, m_laHighScore); + p_file->Write(m_peScore); + p_file->Write(m_maScore); + p_file->Write(m_paScore); + p_file->Write(m_niScore); + p_file->Write(m_laScore); + p_file->Write(m_peHighScore); + p_file->Write(m_maHighScore); + p_file->Write(m_paHighScore); + p_file->Write(m_niHighScore); + p_file->Write(m_laHighScore); } return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index c65064c1..c5516b37 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -1704,21 +1704,26 @@ LegoVehicleBuildState::LegoVehicleBuildState(const char* p_classType) } // FUNCTION: LEGO1 0x10026120 +// FUNCTION: BETA10 0x1006eef0 MxResult LegoVehicleBuildState::Serialize(LegoFile* p_file) { LegoState::Serialize(p_file); if (p_file->IsReadMode()) { - Read(p_file, &m_unk0x4c); - Read(p_file, &m_unk0x4d); - Read(p_file, &m_unk0x4e); - Read(p_file, &m_placedPartCount); + p_file->Read(m_unk0x4c); + p_file->Read(m_unk0x4d); + p_file->Read(m_unk0x4e); +#ifndef BETA10 + p_file->Read(m_placedPartCount); +#endif } else { - Write(p_file, m_unk0x4c); - Write(p_file, m_unk0x4d); - Write(p_file, m_unk0x4e); - Write(p_file, m_placedPartCount); + p_file->Write(m_unk0x4c); + p_file->Write(m_unk0x4d); + p_file->Write(m_unk0x4e); +#ifndef BETA10 + p_file->Write(m_placedPartCount); +#endif } return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index aa1a6b40..b51d814b 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -2937,67 +2937,75 @@ void AnimState::InitFromAnims(MxU32 p_animsLength, AnimInfo* p_anims, MxU32 p_ex // FUNCTION: BETA10 0x10046621 MxResult AnimState::Serialize(LegoFile* p_file) { - // These two are equivalent up to the order of some deallocation. - // Choose as needed to get 100 %. - // Option 1: - // LegoState::Serialize(p_file); - // Option 2: - if (p_file->IsWriteMode()) { - p_file->WriteString(ClassName()); - } + MxResult result = LegoState::Serialize(p_file); - if (p_file->IsReadMode()) { - Read(p_file, &m_extraCharacterId); + if (result == SUCCESS) { + if (p_file->IsReadMode()) { + MxS32 i; - if (m_unk0x10) { - delete[] m_unk0x10; - } + p_file->Read(m_extraCharacterId); + + if (m_unk0x10) { + delete[] m_unk0x10; + } + + p_file->Read(m_unk0x0c); - Read(p_file, &m_unk0x0c); - if (m_unk0x0c != 0) { +#ifndef BETA10 + if (m_unk0x0c != 0) { + m_unk0x10 = new MxU16[m_unk0x0c]; + } + else { + m_unk0x10 = NULL; + } +#else m_unk0x10 = new MxU16[m_unk0x0c]; - } - else { - m_unk0x10 = NULL; - } +#endif - for (MxS32 i = 0; i < m_unk0x0c; i++) { - Read(p_file, &m_unk0x10[i]); - } + for (i = 0; i < m_unk0x0c; i++) { + p_file->Read(m_unk0x10[i]); + } - // Note that here we read first and then free memory in contrast to above - Read(p_file, &m_locationsFlagsLength); + // Note that here we read first and then free memory in contrast to above + p_file->Read(m_locationsFlagsLength); - if (m_locationsFlags) { - delete[] m_locationsFlags; - } +#ifndef BETA10 + 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]; - } - else { - m_locationsFlags = NULL; - } +#endif - for (MxS32 j = 0; j < m_locationsFlagsLength; j++) { - Read(p_file, &m_locationsFlags[j]); + for (i = 0; i < m_locationsFlagsLength; i++) { + p_file->Read(m_locationsFlags[i]); + } } - } - else if (p_file->IsWriteMode()) { - Write(p_file, m_extraCharacterId); + else if (p_file->IsWriteMode()) { + MxS32 i; - Write(p_file, m_unk0x0c); - for (MxS32 i = 0; i < m_unk0x0c; i++) { - Write(p_file, m_unk0x10[i]); - } + p_file->Write(m_extraCharacterId); + p_file->Write(m_unk0x0c); - Write(p_file, m_locationsFlagsLength); - for (MxS32 j = 0; j < m_locationsFlagsLength; j++) { - Write(p_file, m_locationsFlags[j]); + for (i = 0; i < m_unk0x0c; i++) { + p_file->Write(m_unk0x10[i]); + } + + 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 diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index 0db04109..6585d2f4 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -171,6 +171,7 @@ LegoGameState::~LegoGameState() } // FUNCTION: LEGO1 0x10039780 +// FUNCTION: BETA10 0x10083d43 void LegoGameState::SetActor(MxU8 p_actorId) { if (p_actorId) { @@ -238,7 +239,7 @@ MxResult LegoGameState::Save(MxULong p_slot) } MxResult result = FAILURE; - LegoFile fileStorage; + LegoFile storage; MxVariableTable* variableTable = VariableTable(); MxS16 count = 0; MxU32 i; @@ -248,32 +249,32 @@ MxResult LegoGameState::Save(MxULong p_slot) MxString savePath; GetFileSavePath(&savePath, p_slot); - if (fileStorage.Open(savePath.GetData(), LegoFile::c_write) == FAILURE) { + if (storage.Open(savePath.GetData(), LegoFile::c_write) == FAILURE) { goto done; } - Write(&fileStorage, 0x1000c); - Write(&fileStorage, m_unk0x24); - Write(&fileStorage, (MxU16) m_currentAct); - Write(&fileStorage, m_actorId); + storage.Write(0x1000c); + storage.Write(m_unk0x24); + storage.Write((MxU16) m_currentAct); + storage.Write(m_actorId); 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; } } - if (WriteVariable(&fileStorage, variableTable, "backgroundcolor") == FAILURE) { + if (WriteVariable(&storage, variableTable, "backgroundcolor") == FAILURE) { goto done; } - if (WriteVariable(&fileStorage, variableTable, "lightposition") == FAILURE) { + if (WriteVariable(&storage, variableTable, "lightposition") == FAILURE) { goto done; } - WriteEndOfVariables(&fileStorage); - CharacterManager()->Write(&fileStorage); - PlantManager()->Write(&fileStorage); - result = BuildingManager()->Write(&fileStorage); + WriteEndOfVariables(&storage); + CharacterManager()->Write(&storage); + PlantManager()->Write(&storage); + result = BuildingManager()->Write(&storage); for (j = 0; j < m_stateCount; j++) { if (m_stateArray[j]->IsSerializable()) { @@ -281,16 +282,16 @@ MxResult LegoGameState::Save(MxULong p_slot) } } - Write(&fileStorage, count); + storage.Write(count); for (j = 0; j < m_stateCount; j++) { if (m_stateArray[j]->IsSerializable()) { - m_stateArray[j]->Serialize(&fileStorage); + m_stateArray[j]->Serialize(&storage); } } area = m_unk0x42c; - Write(&fileStorage, (MxU16) area); + storage.Write((MxU16) area); SerializeScoreHistory(2); m_isDirty = FALSE; @@ -322,42 +323,43 @@ MxResult LegoGameState::DeleteState() } // FUNCTION: LEGO1 0x10039c60 +// FUNCTION: BETA10 0x10084329 MxResult LegoGameState::Load(MxULong p_slot) { MxResult result = FAILURE; - LegoFile fileStorage; + LegoFile storage; MxVariableTable* variableTable = VariableTable(); MxString savePath; GetFileSavePath(&savePath, p_slot); - if (fileStorage.Open(savePath.GetData(), LegoFile::c_read) == FAILURE) { + if (storage.Open(savePath.GetData(), LegoFile::c_read) == FAILURE) { goto done; } - MxU32 version, status; + MxS32 version; + MxU32 status; MxS16 count, actArea; const char* lightPosition; - Read(&fileStorage, &version); + storage.Read(version); if (version != 0x1000c) { OmniError("Saved game version mismatch", 0); goto done; } - Read(&fileStorage, &m_unk0x24); + storage.Read(m_unk0x24); + storage.Read(actArea); - Read(&fileStorage, &actArea); SetCurrentAct((Act) actArea); - - Read(&fileStorage, &m_actorId); + storage.Read(m_actorId); if (m_actorId) { SetActor(m_actorId); } do { - status = ReadVariable(&fileStorage, variableTable); + status = ReadVariable(&storage, variableTable); if (status == 1) { goto done; } @@ -370,13 +372,13 @@ MxResult LegoGameState::Load(MxULong p_slot) SetLightPosition(atoi(lightPosition)); } - if (CharacterManager()->Read(&fileStorage) == FAILURE) { + if (CharacterManager()->Read(&storage) == FAILURE) { goto done; } - if (PlantManager()->Read(&fileStorage) == FAILURE) { + if (PlantManager()->Read(&storage) == FAILURE) { goto done; } - if (BuildingManager()->Read(&fileStorage) == FAILURE) { + if (BuildingManager()->Read(&storage) == FAILURE) { goto done; } if (DeleteState() != SUCCESS) { @@ -384,14 +386,11 @@ MxResult LegoGameState::Load(MxULong p_slot) } char stateName[80]; - Read(&fileStorage, &count); + storage.Read(count); if (count) { for (MxS16 i = 0; i < count; i++) { - MxS16 stateNameLength; - Read(&fileStorage, &stateNameLength); - Read(&fileStorage, stateName, (MxULong) stateNameLength); - stateName[stateNameLength] = 0; + storage.Read(stateName); LegoState* state = GetState(stateName); if (!state) { @@ -402,11 +401,11 @@ MxResult LegoGameState::Load(MxULong p_slot) } } - state->Serialize(&fileStorage); + state->Serialize(&storage); } } - Read(&fileStorage, &actArea); + storage.Read(actArea); if (m_currentAct == e_act1) { m_unk0x42c = e_undefined; @@ -537,10 +536,10 @@ void LegoGameState::SerializePlayersInfo(MxS16 p_flags) if (fileStorage.Open(playersGSI.GetData(), p_flags) == SUCCESS) { if (fileStorage.IsReadMode()) { - Read(&fileStorage, &m_playerCount); + fileStorage.Read(m_playerCount); } else if (fileStorage.IsWriteMode()) { - Write(&fileStorage, m_playerCount); + fileStorage.Write(m_playerCount); } for (MxS16 i = 0; i < m_playerCount; i++) { @@ -1153,16 +1152,16 @@ LegoGameState::Username::Username() // FUNCTION: LEGO1 0x1003c690 // 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++) { - 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++) { - Write(p_storage, m_letters[i]); + p_file->Write(m_letters[i]); } } @@ -1182,28 +1181,28 @@ LegoGameState::Username& LegoGameState::Username::operator=(const Username& p_ot MxResult LegoGameState::ScoreItem::Serialize(LegoFile* p_file) { if (p_file->IsReadMode()) { - Read(p_file, &m_totalScore); + p_file->Read(m_totalScore); for (MxS32 i = 0; i < 5; i++) { 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); - Read(p_file, &m_unk0x2a); + p_file->Read(m_unk0x2a); } else if (p_file->IsWriteMode()) { - Write(p_file, m_totalScore); + p_file->Write(m_totalScore); for (MxS32 i = 0; i < 5; i++) { 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); - Write(p_file, m_unk0x2a); + p_file->Write(m_unk0x2a); } return SUCCESS; @@ -1328,21 +1327,21 @@ LegoGameState::ScoreItem* LegoGameState::History::FUN_1003cc90( MxResult LegoGameState::History::Serialize(LegoFile* p_file) { if (p_file->IsReadMode()) { - Read(p_file, &m_unk0x372); - Read(p_file, &m_count); + p_file->Read(m_unk0x372); + p_file->Read(m_count); for (MxS16 i = 0; i < m_count; i++) { MxS16 j; - Read(p_file, &j); + p_file->Read(j); m_scores[i].Serialize(p_file); } } else if (p_file->IsWriteMode()) { - Write(p_file, m_unk0x372); - Write(p_file, m_count); + p_file->Write(m_unk0x372); + p_file->Write(m_count); for (MxS16 i = 0; i < m_count; i++) { - Write(p_file, i); + p_file->Write(i); m_scores[i].Serialize(p_file); } } diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index e1a61a38..d6c7f84c 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -668,7 +668,7 @@ LegoNamedTexture* ReadNamedTexture(LegoFile* p_file) LegoNamedTexture* namedTexture = NULL; MxString string; - p_file->ReadString(string); + p_file->Read(string); texture = new LegoTexture(); if (texture != NULL) { @@ -743,7 +743,7 @@ void WriteDefaultTexture(LegoFile* p_file, const char* p_name) LegoTexture texture; texture.SetImage(image); - p_file->WriteString(name); + p_file->Write(MxString(name)); texture.Write(p_file); } else { @@ -760,7 +760,7 @@ void WriteDefaultTexture(LegoFile* p_file, const char* p_name) // FUNCTION: LEGO1 0x1003f8a0 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); } diff --git a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp index 77e7da06..34981d64 100644 --- a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp +++ b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp @@ -513,18 +513,18 @@ MxResult GasStationState::Serialize(LegoFile* p_file) LegoState::Serialize(p_file); if (p_file->IsWriteMode()) { - Write(p_file, m_pepperAction); - Write(p_file, m_mamaAction); - Write(p_file, m_papaAction); - Write(p_file, m_nickAction); - Write(p_file, m_lauraAction); + p_file->Write(m_pepperAction); + p_file->Write(m_mamaAction); + p_file->Write(m_papaAction); + p_file->Write(m_nickAction); + p_file->Write(m_lauraAction); } else if (p_file->IsReadMode()) { - Read(p_file, &m_pepperAction); - Read(p_file, &m_mamaAction); - Read(p_file, &m_papaAction); - Read(p_file, &m_nickAction); - Read(p_file, &m_lauraAction); + p_file->Read(m_pepperAction); + p_file->Read(m_mamaAction); + p_file->Read(m_papaAction); + p_file->Read(m_nickAction); + p_file->Read(m_lauraAction); } return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/worlds/hospital.cpp b/LEGO1/lego/legoomni/src/worlds/hospital.cpp index cfec6955..2f5f915e 100644 --- a/LEGO1/lego/legoomni/src/worlds/hospital.cpp +++ b/LEGO1/lego/legoomni/src/worlds/hospital.cpp @@ -694,25 +694,26 @@ HospitalState::HospitalState() } // FUNCTION: LEGO1 0x10076530 +// FUNCTION: BETA10 0x1002db26 MxResult HospitalState::Serialize(LegoFile* p_file) { LegoState::Serialize(p_file); if (p_file->IsWriteMode()) { - Write(p_file, m_unk0x0c); - Write(p_file, m_unk0x0e); - Write(p_file, m_unk0x10); - Write(p_file, m_unk0x12); - Write(p_file, m_unk0x14); - Write(p_file, m_unk0x16); + p_file->Write(m_unk0x0c); + p_file->Write(m_unk0x0e); + p_file->Write(m_unk0x10); + p_file->Write(m_unk0x12); + p_file->Write(m_unk0x14); + p_file->Write(m_unk0x16); } else if (p_file->IsReadMode()) { - Read(p_file, &m_unk0x0c); - Read(p_file, &m_unk0x0e); - Read(p_file, &m_unk0x10); - Read(p_file, &m_unk0x12); - Read(p_file, &m_unk0x14); - Read(p_file, &m_unk0x16); + p_file->Read(m_unk0x0c); + p_file->Read(m_unk0x0e); + p_file->Read(m_unk0x10); + p_file->Read(m_unk0x12); + p_file->Read(m_unk0x14); + p_file->Read(m_unk0x16); } return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 88fa83d7..6c3b0859 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -1337,82 +1337,83 @@ MxResult Act1State::Serialize(LegoFile* p_file) m_racecarPlane.Serialize(p_file); if (p_file->IsWriteMode()) { - if (m_helicopterPlane.IsPresent()) { - if (m_helicopterWindshield) { - WriteNamedTexture(p_file, m_helicopterWindshield); + // TODO: Seems to match better when using strcmp directly instead of IsPresent + if (strcmp(m_helicopterPlane.m_name.GetData(), "")) { + if (!m_helicopterWindshield) { + WriteDefaultTexture(p_file, "chwind.gif"); } else { - WriteDefaultTexture(p_file, "chwind.gif"); + WriteNamedTexture(p_file, m_helicopterWindshield); } - if (m_helicopterJetLeft) { - WriteNamedTexture(p_file, m_helicopterJetLeft); + if (!m_helicopterJetLeft) { + WriteDefaultTexture(p_file, "chjetl.gif"); } else { - WriteDefaultTexture(p_file, "chjetl.gif"); + WriteNamedTexture(p_file, m_helicopterJetLeft); } - if (m_helicopterJetRight) { - WriteNamedTexture(p_file, m_helicopterJetRight); + if (!m_helicopterJetRight) { + WriteDefaultTexture(p_file, "chjetr.gif"); } else { - WriteDefaultTexture(p_file, "chjetr.gif"); + WriteNamedTexture(p_file, m_helicopterJetRight); } } - if (m_jetskiPlane.IsPresent()) { - if (m_jetskiFront) { - WriteNamedTexture(p_file, m_jetskiFront); + if (strcmp(m_jetskiPlane.m_name.GetData(), "")) { + if (!m_jetskiFront) { + WriteDefaultTexture(p_file, "jsfrnt.gif"); } else { - WriteDefaultTexture(p_file, "jsfrnt.gif"); + WriteNamedTexture(p_file, m_jetskiFront); } - if (m_jetskiWindshield) { - WriteNamedTexture(p_file, m_jetskiWindshield); + if (!m_jetskiWindshield) { + WriteDefaultTexture(p_file, "jswnsh.gif"); } else { - WriteDefaultTexture(p_file, "jswnsh.gif"); + WriteNamedTexture(p_file, m_jetskiWindshield); } } - if (m_dunebuggyPlane.IsPresent()) { - if (m_dunebuggyFront) { - WriteNamedTexture(p_file, m_dunebuggyFront); + if (strcmp(m_dunebuggyPlane.m_name.GetData(), "")) { + if (!m_dunebuggyFront) { + WriteDefaultTexture(p_file, "dbfrfn.gif"); } else { - WriteDefaultTexture(p_file, "dbfrfn.gif"); + WriteNamedTexture(p_file, m_dunebuggyFront); } } - if (m_racecarPlane.IsPresent()) { - if (m_racecarFront) { - WriteNamedTexture(p_file, m_racecarFront); + if (strcmp(m_racecarPlane.m_name.GetData(), "")) { + if (!m_racecarFront) { + WriteDefaultTexture(p_file, "rcfrnt.gif"); } else { - WriteDefaultTexture(p_file, "rcfrnt.gif"); + WriteNamedTexture(p_file, m_racecarFront); } - if (m_racecarBack) { - WriteNamedTexture(p_file, m_racecarBack); + if (!m_racecarBack) { + WriteDefaultTexture(p_file, "rcback.gif"); } else { - WriteDefaultTexture(p_file, "rcback.gif"); + WriteNamedTexture(p_file, m_racecarBack); } - if (m_racecarTail) { - WriteNamedTexture(p_file, m_racecarTail); + if (!m_racecarTail) { + WriteDefaultTexture(p_file, "rctail.gif"); } else { - WriteDefaultTexture(p_file, "rctail.gif"); + WriteNamedTexture(p_file, m_racecarTail); } } - m_cptClickDialogue.WriteToFile(p_file); - Write(p_file, m_unk0x022); + p_file->Write(m_cptClickDialogue.m_nextIndex); + p_file->Write(m_unk0x022); } else if (p_file->IsReadMode()) { - if (m_helicopterPlane.IsPresent()) { + if (strcmp(m_helicopterPlane.m_name.GetData(), "")) { m_helicopterWindshield = ReadNamedTexture(p_file); if (m_helicopterWindshield == NULL) { return FAILURE; @@ -1429,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); if (m_jetskiFront == NULL) { return FAILURE; @@ -1441,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); if (m_dunebuggyFront == NULL) { return FAILURE; } } - if (m_racecarPlane.IsPresent()) { + if (strcmp(m_racecarPlane.m_name.GetData(), "")) { m_racecarFront = ReadNamedTexture(p_file); if (m_racecarFront == NULL) { return FAILURE; @@ -1465,11 +1466,10 @@ MxResult Act1State::Serialize(LegoFile* p_file) } } - m_cptClickDialogue.ReadFromFile(p_file); - Read(p_file, &m_unk0x022); + p_file->Read(m_cptClickDialogue.m_nextIndex); + p_file->Read(m_unk0x022); } - // TODO return SUCCESS; } diff --git a/LEGO1/lego/legoomni/src/worlds/police.cpp b/LEGO1/lego/legoomni/src/worlds/police.cpp index 7bf48e9b..32e90395 100644 --- a/LEGO1/lego/legoomni/src/worlds/police.cpp +++ b/LEGO1/lego/legoomni/src/worlds/police.cpp @@ -208,15 +208,16 @@ PoliceState::PoliceState() } // FUNCTION: LEGO1 0x1005e990 +// FUNCTION: BETA10 0x100f08b0 MxResult PoliceState::Serialize(LegoFile* p_file) { LegoState::Serialize(p_file); if (p_file->IsReadMode()) { - Read(p_file, &m_policeScript); + p_file->Read((MxS32&) m_policeScript); } else { - Write(p_file, m_policeScript); + p_file->Write((MxS32) m_policeScript); } return SUCCESS; diff --git a/LEGO1/lego/sources/misc/legostorage.h b/LEGO1/lego/sources/misc/legostorage.h index 553983fd..f46c7a1f 100644 --- a/LEGO1/lego/sources/misc/legostorage.h +++ b/LEGO1/lego/sources/misc/legostorage.h @@ -40,18 +40,6 @@ class LegoStorage { LegoU8 m_mode; // 0x04 }; -template -inline void Read(LegoStorage* p_storage, T* p_variable, LegoU32 p_size = sizeof(T)) -{ - p_storage->Read(p_variable, p_size); -} - -template -inline void Write(LegoStorage* p_storage, T p_variable) -{ - p_storage->Write(&p_variable, sizeof(p_variable)); -} - // VTABLE: LEGO1 0x100db710 // SIZE 0x10 class LegoMemory : public LegoStorage { @@ -98,50 +86,148 @@ class LegoFile : public LegoStorage { LegoResult SetPosition(LegoU32 p_position) override; // vtable+0x10 LegoResult Open(const char* p_name, LegoU32 p_mode); + // FUNCTION: LEGO1 0x10006030 + // FUNCTION: BETA10 0x10017bb0 + LegoStorage* Write(MxString p_data) + { + Write(p_data.GetData()); + return this; + } + + // FUNCTION: BETA10 0x10017c80 + LegoStorage* Write(const char* p_data) + { + LegoS16 length = strlen(p_data); + Write(length); + 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* WriteVector3(Mx3DPointFloat p_vec3) + LegoStorage* Write(Mx3DPointFloat p_vec) { - ::Write(this, p_vec3[0]); - ::Write(this, p_vec3[1]); - ::Write(this, p_vec3[2]); + Write(p_vec[0]); + Write(p_vec[1]); + Write(p_vec[2]); return this; } - // FUNCTION: LEGO1 0x10034430 - LegoStorage* ReadVector3(Mx3DPointFloat& p_vec3) + LegoStorage* Read(char* p_data) { - ::Read(this, &p_vec3[0]); - ::Read(this, &p_vec3[1]); - ::Read(this, &p_vec3[2]); + LegoS16 length; + Read(length); + Read(p_data, length); + p_data[length] = '\0'; return this; } // FUNCTION: LEGO1 0x10034470 - LegoStorage* ReadString(MxString& p_str) + LegoStorage* Read(MxString& p_data) { - MxS16 len; - Read(&len, sizeof(MxS16)); + LegoS16 length; + Read(length); - char* text = new char[len + 1]; - Read(text, len); + char* text = new char[length + 1]; + Read(text, length); - text[len] = '\0'; - p_str = text; + text[length] = '\0'; + p_data = text; delete[] text; + return this; + } + // FUNCTION: BETA10 0x1004b190 + LegoStorage* Read(LegoU8& p_data) + { + Read(&p_data, sizeof(p_data)); return this; } - // FUNCTION: LEGO1 0x10006030 - LegoStorage* WriteString(MxString p_str) + // FUNCTION: BETA10 0x10024680 + LegoStorage* Read(LegoS16& p_data) { - const char* data = p_str.GetData(); - LegoU32 fullLength = strlen(data); + Read(&p_data, sizeof(p_data)); + return this; + } - LegoU16 limitedLength = (LegoU16) fullLength; - Write(&limitedLength, sizeof(limitedLength)); - Write((char*) data, (LegoS16) fullLength); + // 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; }