From 2bebc09da3ac73733b3b12c0a6654fdded9e46b4 Mon Sep 17 00:00:00 2001 From: Nathan M Gilbert Date: Wed, 24 Jan 2024 12:12:57 -0500 Subject: [PATCH] Implement misc.lib (#483) * Implement misc.lib * Lowercase files * Minor changes * Fix file cases * Fixes * Fix missing dtor * Add override * Match LegoImage::Read * Fix delete call --------- Co-authored-by: Christian Semmler --- CMakeLists.txt | 4 +- LEGO1/lego/legoomni/include/act1state.h | 4 +- .../legoomni/include/ambulancemissionstate.h | 2 +- LEGO1/lego/legoomni/include/animstate.h | 4 +- LEGO1/lego/legoomni/include/gasstationstate.h | 2 +- LEGO1/lego/legoomni/include/hospitalstate.h | 2 +- .../lego/legoomni/include/legoanimpresenter.h | 8 +- LEGO1/lego/legoomni/include/legogamestate.h | 9 +- LEGO1/lego/legoomni/include/legostate.h | 8 +- LEGO1/lego/legoomni/include/legostream.h | 91 -------- .../legoomni/include/legounksavedatawriter.h | 4 +- .../legoomni/include/legovehiclebuildstate.h | 2 +- LEGO1/lego/legoomni/include/legoworld.h | 8 +- .../lego/legoomni/include/pizzamissionstate.h | 2 +- LEGO1/lego/legoomni/include/pizzeriastate.h | 2 +- LEGO1/lego/legoomni/include/policestate.h | 2 +- LEGO1/lego/legoomni/include/racestate.h | 2 +- .../legoomni/include/towtrackmissionstate.h | 2 +- LEGO1/lego/legoomni/src/act1/act1state.cpp | 2 +- .../src/build/legovehiclebuildstate.cpp | 2 +- LEGO1/lego/legoomni/src/common/animstate.cpp | 2 +- .../legoomni/src/common/legogamestate.cpp | 77 ++++++- LEGO1/lego/legoomni/src/common/legostate.cpp | 19 +- LEGO1/lego/legoomni/src/common/legostream.cpp | 201 ------------------ .../src/common/legounksavedatawriter.cpp | 3 +- .../src/gasstation/gasstationstate.cpp | 2 +- .../src/hospital/ambulancemissionstate.cpp | 2 +- .../legoomni/src/hospital/hospitalstate.cpp | 2 +- .../src/pizzeria/pizzamissionstate.cpp | 2 +- .../legoomni/src/pizzeria/pizzeriastate.cpp | 2 +- .../lego/legoomni/src/police/policestate.cpp | 12 +- LEGO1/lego/legoomni/src/race/racestate.cpp | 2 +- .../src/towtrack/towtrackmissionstate.cpp | 50 ++--- .../legoomni/src/video/legoanimpresenter.cpp | 5 +- .../src/video/legopalettepresenter.cpp | 4 +- LEGO1/lego/sources/misc/legoimage.cpp | 176 +++++++++++++++ LEGO1/lego/sources/misc/legoimage.h | 54 +++++ LEGO1/lego/sources/misc/legostorage.cpp | 139 ++++++++++++ LEGO1/lego/sources/misc/legostorage.h | 95 +++++++++ LEGO1/lego/sources/misc/legotexture.cpp | 31 +++ LEGO1/lego/sources/misc/legotexture.h | 23 ++ LEGO1/lego/sources/misc/legotypes.h | 44 ++++ LEGO1/lego/sources/misc/legoutil.h | 54 +++++ LEGO1/lego/sources/misc/version.h | 6 + 44 files changed, 772 insertions(+), 397 deletions(-) delete mode 100644 LEGO1/lego/legoomni/include/legostream.h delete mode 100644 LEGO1/lego/legoomni/src/common/legostream.cpp create mode 100644 LEGO1/lego/sources/misc/legoimage.cpp create mode 100644 LEGO1/lego/sources/misc/legoimage.h create mode 100644 LEGO1/lego/sources/misc/legostorage.cpp create mode 100644 LEGO1/lego/sources/misc/legostorage.h create mode 100644 LEGO1/lego/sources/misc/legotexture.cpp create mode 100644 LEGO1/lego/sources/misc/legotexture.h create mode 100644 LEGO1/lego/sources/misc/legotypes.h create mode 100644 LEGO1/lego/sources/misc/legoutil.h create mode 100644 LEGO1/lego/sources/misc/version.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b7c93768..9192c542 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,6 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp LEGO1/lego/legoomni/src/common/legoplantmanager.cpp LEGO1/lego/legoomni/src/common/legostate.cpp - LEGO1/lego/legoomni/src/common/legostream.cpp LEGO1/lego/legoomni/src/common/legounksavedatawriter.cpp LEGO1/lego/legoomni/src/common/legoutil.cpp LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp @@ -148,6 +147,9 @@ add_library(lego1 SHARED LEGO1/lego/sources/3dmanager/lego3dview.cpp LEGO1/lego/sources/3dmanager/legoview1.cpp LEGO1/lego/sources/3dmanager/tglsurface.cpp + LEGO1/lego/sources/misc/legoimage.cpp + LEGO1/lego/sources/misc/legostorage.cpp + LEGO1/lego/sources/misc/legotexture.cpp LEGO1/lego/sources/roi/legoroi.cpp LEGO1/main.cpp LEGO1/mxdirectx/mxdirect3d.cpp diff --git a/LEGO1/lego/legoomni/include/act1state.h b/LEGO1/lego/legoomni/include/act1state.h index 4babf08a..3bc28a0d 100644 --- a/LEGO1/lego/legoomni/include/act1state.h +++ b/LEGO1/lego/legoomni/include/act1state.h @@ -22,8 +22,8 @@ public: return !strcmp(p_name, Act1State::ClassName()) || LegoState::IsA(p_name); }; - virtual MxBool SetFlag() override; // vtable+0x18 - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1c + virtual MxBool SetFlag() override; // vtable+0x18 + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1c inline void SetUnknown18(MxU32 p_unk0x18) { m_unk0x18 = p_unk0x18; } inline MxU32 GetUnknown18() { return m_unk0x18; } diff --git a/LEGO1/lego/legoomni/include/ambulancemissionstate.h b/LEGO1/lego/legoomni/include/ambulancemissionstate.h index ea5cfb3e..923a0cc3 100644 --- a/LEGO1/lego/legoomni/include/ambulancemissionstate.h +++ b/LEGO1/lego/legoomni/include/ambulancemissionstate.h @@ -22,7 +22,7 @@ public: return !strcmp(p_name, AmbulanceMissionState::ClassName()) || LegoState::IsA(p_name); } - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1c + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1c inline MxU16 GetColor(MxU8 p_id) { diff --git a/LEGO1/lego/legoomni/include/animstate.h b/LEGO1/lego/legoomni/include/animstate.h index fe39ccc7..9ac03a4c 100644 --- a/LEGO1/lego/legoomni/include/animstate.h +++ b/LEGO1/lego/legoomni/include/animstate.h @@ -23,8 +23,8 @@ public: return !strcmp(p_name, AnimState::ClassName()) || LegoState::IsA(p_name); } - virtual MxBool SetFlag() override; // vtable+0x18 - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1C + virtual MxBool SetFlag() override; // vtable+0x18 + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1C // SYNTHETIC: LEGO1 0x10065130 // AnimState::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/gasstationstate.h b/LEGO1/lego/legoomni/include/gasstationstate.h index 4f77e307..57fd0d39 100644 --- a/LEGO1/lego/legoomni/include/gasstationstate.h +++ b/LEGO1/lego/legoomni/include/gasstationstate.h @@ -22,7 +22,7 @@ public: return !strcmp(p_name, GasStationState::ClassName()) || LegoState::IsA(p_name); } - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1c + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1c // SYNTHETIC: LEGO1 0x10006290 // GasStationState::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/hospitalstate.h b/LEGO1/lego/legoomni/include/hospitalstate.h index af876f89..a38cfd2e 100644 --- a/LEGO1/lego/legoomni/include/hospitalstate.h +++ b/LEGO1/lego/legoomni/include/hospitalstate.h @@ -23,7 +23,7 @@ public: return !strcmp(p_name, HospitalState::ClassName()) || LegoState::IsA(p_name); } - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1c + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1c // SYNTHETIC: LEGO1 0x100764c0 // HospitalState::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 3eeea936..94832a61 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -1,11 +1,11 @@ #ifndef LEGOANIMPRESENTER_H #define LEGOANIMPRESENTER_H +#include "lego/sources/misc/legostorage.h" #include "mxgeometry/mxgeometry3d.h" #include "mxvideopresenter.h" class LegoWorld; -class LegoMemoryStream; class LegoAnimClass; // VTABLE: LEGO1 0x100d90c8 @@ -97,9 +97,9 @@ public: LegoAnimClass(); virtual ~LegoAnimClass() override; - virtual void VTable0x8() override; // vtable+0x08 - virtual void VTable0xc() override; // vtable+0x0c - virtual MxResult VTable0x10(LegoMemoryStream* p_stream, MxS32); // vtable+0x10 + virtual void VTable0x8() override; // vtable+0x08 + virtual void VTable0xc() override; // vtable+0x0c + virtual MxResult VTable0x10(LegoMemory* p_stream, MxS32); // vtable+0x10 MxLong m_unk0x8; // 0x08 undefined4 m_unk0xc; // 0x0c diff --git a/LEGO1/lego/legoomni/include/legogamestate.h b/LEGO1/lego/legoomni/include/legogamestate.h index ae39654c..534ac5b9 100644 --- a/LEGO1/lego/legoomni/include/legogamestate.h +++ b/LEGO1/lego/legoomni/include/legogamestate.h @@ -2,10 +2,11 @@ #define LEGOGAMESTATE_H #include "decomp.h" +#include "lego/sources/misc/legostorage.h" #include "legobackgroundcolor.h" #include "legofullscreenmovie.h" -#include "legostream.h" #include "mxtypes.h" +#include "mxvariabletable.h" class LegoState; class MxVariable; @@ -47,7 +48,7 @@ public: struct ScoreStruct { void WriteScoreHistory(); - void FUN_1003ccf0(LegoFileStream&); + void FUN_1003ccf0(LegoFile&); MxU16 m_unk0x00; undefined m_unk0x02[0x2c][20]; @@ -55,7 +56,9 @@ public: private: void RegisterState(LegoState* p_state); - MxResult WriteEndOfVariables(LegoStream* p_stream); + MxResult WriteVariable(LegoStorage* p_stream, MxVariableTable* p_from, const char* p_variableName); + MxResult WriteEndOfVariables(LegoStorage* p_stream); + MxS32 ReadVariable(LegoStorage* p_stream, MxVariableTable* p_to); void SetROIHandlerFunction(); char* m_savePath; // 0x0 diff --git a/LEGO1/lego/legoomni/include/legostate.h b/LEGO1/lego/legoomni/include/legostate.h index 215d64d4..e6d11bd1 100644 --- a/LEGO1/lego/legoomni/include/legostate.h +++ b/LEGO1/lego/legoomni/include/legostate.h @@ -2,7 +2,7 @@ #define LEGOSTATE_H #include "decomp.h" -#include "legostream.h" +#include "lego/sources/misc/legostorage.h" #include "mxcore.h" #include "mxstring.h" @@ -24,9 +24,9 @@ public: return !strcmp(p_name, LegoState::ClassName()) || MxCore::IsA(p_name); } - virtual MxBool VTable0x14(); // vtable+0x14 - virtual MxBool SetFlag(); // vtable+0x18 - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream); // vtable+0x1C + virtual MxBool VTable0x14(); // vtable+0x14 + virtual MxBool SetFlag(); // vtable+0x18 + virtual MxResult VTable0x1c(LegoFile* p_legoFile); // vtable+0x1C // SYNTHETIC: LEGO1 0x10006160 // LegoState::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legostream.h b/LEGO1/lego/legoomni/include/legostream.h deleted file mode 100644 index 601e94e2..00000000 --- a/LEGO1/lego/legoomni/include/legostream.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef LEGOSTREAM_H -#define LEGOSTREAM_H - -#include "compat.h" -#include "decomp.h" -#include "mxstring.h" -#include "mxtypes.h" - -#pragma warning(disable : 4237) -#include - -#define LEGOSTREAM_MODE_READ 1 -#define LEGOSTREAM_MODE_WRITE 2 - -class MxVariableTable; - -// VTABLE: LEGO1 0x100d7d80 -class LegoStream { -public: - LegoStream() : m_mode(0) {} - // FUNCTION: LEGO1 0x10045ad0 - inline virtual ~LegoStream() {} - - virtual MxResult Read(void* p_buffer, MxU32 p_size) = 0; - virtual MxResult Write(const void* p_buffer, MxU32 p_size) = 0; - virtual MxResult Tell(MxU32* p_offset) = 0; - virtual MxResult Seek(MxU32 p_offset) = 0; - - virtual MxBool IsWriteMode(); - virtual MxBool IsReadMode(); - - enum OpenFlags { - c_readBit = 1, - c_writeBit = 2, - c_binaryBit = 4, - }; - - static MxResult __stdcall WriteVariable(LegoStream* p_stream, MxVariableTable* p_from, const char* p_variableName); - static MxS32 __stdcall ReadVariable(LegoStream* p_stream, MxVariableTable* p_to); - -protected: - MxU8 m_mode; -}; - -// SYNTHETIC: LEGO1 0x10045b00 -// LegoStream::`scalar deleting destructor' - -// VTABLE: LEGO1 0x100db730 -class LegoFileStream : public LegoStream { -public: - LegoFileStream(); - virtual ~LegoFileStream() override; - - MxResult Read(void* p_buffer, MxU32 p_size) override; - MxResult Write(const void* p_buffer, MxU32 p_size) override; - MxResult Tell(MxU32* p_offset) override; - MxResult Seek(MxU32 p_offset) override; - - MxResult Open(const char* p_filename, OpenFlags p_mode); - - LegoFileStream* FUN_10006030(MxString p_str); - -private: - FILE* m_hFile; -}; - -// SYNTHETIC: LEGO1 0x10099230 -// LegoFileStream::`scalar deleting destructor' - -// VTABLE: LEGO1 0x100db710 -class LegoMemoryStream : public LegoStream { -public: - LegoMemoryStream(char* p_buffer); - - MxResult Read(void* p_buffer, MxU32 p_size) override; - MxResult Write(const void* p_buffer, MxU32 p_size) override; - MxResult Tell(MxU32* p_offset) override; - MxResult Seek(MxU32 p_offset) override; - -private: - char* m_buffer; - MxU32 m_offset; -}; - -// SYNTHETIC: LEGO1 0x10045a80 -// LegoMemoryStream::~LegoMemoryStream - -// SYNTHETIC: LEGO1 0x100990f0 -// LegoMemoryStream::`scalar deleting destructor' - -#endif // LEGOSTREAM_H diff --git a/LEGO1/lego/legoomni/include/legounksavedatawriter.h b/LEGO1/lego/legoomni/include/legounksavedatawriter.h index 4623ec7a..d33cfc56 100644 --- a/LEGO1/lego/legoomni/include/legounksavedatawriter.h +++ b/LEGO1/lego/legoomni/include/legounksavedatawriter.h @@ -2,11 +2,11 @@ #define LEGOUNKSAVEDATAWRITER_H #include "decomp.h" +#include "lego/sources/misc/legostorage.h" #include "mxtypes.h" class AutoROI; class LegoROI; -class LegoStream; struct LegoSaveDataEntry3 { char* m_name; @@ -35,7 +35,7 @@ struct LegoSaveDataEntry3 { class LegoUnkSaveDataWriter { public: - MxResult WriteSaveData3(LegoStream* p_stream); + MxResult WriteSaveData3(LegoStorage* p_stream); AutoROI* FUN_10083500(undefined4, undefined4); void FUN_10083db0(LegoROI* p_roi); }; diff --git a/LEGO1/lego/legoomni/include/legovehiclebuildstate.h b/LEGO1/lego/legoomni/include/legovehiclebuildstate.h index 8deed7a5..a155595e 100644 --- a/LEGO1/lego/legoomni/include/legovehiclebuildstate.h +++ b/LEGO1/lego/legoomni/include/legovehiclebuildstate.h @@ -23,7 +23,7 @@ public: return !strcmp(p_name, this->m_className.GetData()) || LegoState::IsA(p_name); } - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1c + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1c // SYNTHETIC: LEGO1 0x100260a0 // LegoVehicleBuildState::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoworld.h b/LEGO1/lego/legoomni/include/legoworld.h index 13ca9737..4fea4672 100644 --- a/LEGO1/lego/legoomni/include/legoworld.h +++ b/LEGO1/lego/legoomni/include/legoworld.h @@ -13,7 +13,7 @@ class IslePathActor; class LegoPathBoundary; struct PresenterSetCompare { - int operator()(MxPresenter* const& p_a, MxPresenter* const& p_b) const { return p_a > p_b; } + MxS32 operator()(MxPresenter* const& p_a, MxPresenter* const& p_b) const { return p_a > p_b; } }; typedef set MxPresenterSet; @@ -23,7 +23,7 @@ typedef set MxPresenterSet; class LegoWorld : public LegoEntity { public: __declspec(dllexport) LegoWorld(); - __declspec(dllexport) virtual ~LegoWorld(); // vtable+0x0 + __declspec(dllexport) virtual ~LegoWorld() override; // vtable+0x0 virtual MxLong Notify(MxParam& p_param) override; // vtable+0x4 virtual MxResult Tickle() override; // vtable+0x8 @@ -119,7 +119,6 @@ protected: // TEMPLATE: LEGO1 0x1001df00 // Set::~Set -// clang-format om // SYNTHETIC: LEGO1 0x1001eed0 // MxPresenterListCursor::`scalar deleting destructor' @@ -143,6 +142,7 @@ protected: // MxListCursor::MxListCursor // GLOBAL: LEGO1 0x100f11a0 -// _Tree >::_Kfn,PresenterSetCompare,allocator >::_Nil +// _Tree>::_Kfn,PresenterSetCompare,allocator >::_Nil +// clang-format on #endif // LEGOWORLD_H diff --git a/LEGO1/lego/legoomni/include/pizzamissionstate.h b/LEGO1/lego/legoomni/include/pizzamissionstate.h index e3867728..7c792ed4 100644 --- a/LEGO1/lego/legoomni/include/pizzamissionstate.h +++ b/LEGO1/lego/legoomni/include/pizzamissionstate.h @@ -28,7 +28,7 @@ public: return !strcmp(p_name, PizzaMissionState::ClassName()) || LegoState::IsA(p_name); } - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1c + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1c inline MxU16 GetColor(MxU8 p_id) { return GetState(p_id)->m_color; } diff --git a/LEGO1/lego/legoomni/include/pizzeriastate.h b/LEGO1/lego/legoomni/include/pizzeriastate.h index 402981ff..1e9da6d3 100644 --- a/LEGO1/lego/legoomni/include/pizzeriastate.h +++ b/LEGO1/lego/legoomni/include/pizzeriastate.h @@ -22,7 +22,7 @@ public: return !strcmp(p_name, PizzeriaState::ClassName()) || LegoState::IsA(p_name); } - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1c + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1c // SYNTHETIC: LEGO1 0x10017ce0 // PizzeriaState::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/policestate.h b/LEGO1/lego/legoomni/include/policestate.h index 976588a3..77005cef 100644 --- a/LEGO1/lego/legoomni/include/policestate.h +++ b/LEGO1/lego/legoomni/include/policestate.h @@ -23,7 +23,7 @@ public: return !strcmp(p_name, PoliceState::ClassName()) || LegoState::IsA(p_name); } - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1c + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1c // SYNTHETIC: LEGO1 0x1005e920 // PoliceState::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/racestate.h b/LEGO1/lego/legoomni/include/racestate.h index bfae3525..7d2de4f6 100644 --- a/LEGO1/lego/legoomni/include/racestate.h +++ b/LEGO1/lego/legoomni/include/racestate.h @@ -30,7 +30,7 @@ public: return !strcmp(p_name, RaceState::ClassName()) || LegoState::IsA(p_name); } - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1c + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1c inline MxU16 GetColor(MxU8 p_id) { return GetState(p_id)->m_color; } diff --git a/LEGO1/lego/legoomni/include/towtrackmissionstate.h b/LEGO1/lego/legoomni/include/towtrackmissionstate.h index be2e2689..ef5bacda 100644 --- a/LEGO1/lego/legoomni/include/towtrackmissionstate.h +++ b/LEGO1/lego/legoomni/include/towtrackmissionstate.h @@ -21,7 +21,7 @@ public: { return !strcmp(p_name, TowTrackMissionState::ClassName()) || LegoState::IsA(p_name); } - virtual MxResult VTable0x1c(LegoFileStream* p_legoFileStream) override; // vtable+0x1C + virtual MxResult VTable0x1c(LegoFile* p_legoFile) override; // vtable+0x1C inline MxU16 GetColor(MxU8 p_id) { diff --git a/LEGO1/lego/legoomni/src/act1/act1state.cpp b/LEGO1/lego/legoomni/src/act1/act1state.cpp index 6a36e3c3..cd39f1e2 100644 --- a/LEGO1/lego/legoomni/src/act1/act1state.cpp +++ b/LEGO1/lego/legoomni/src/act1/act1state.cpp @@ -14,7 +14,7 @@ Act1State::Act1State() } // STUB: LEGO1 0x10033ac0 -MxResult Act1State::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult Act1State::VTable0x1c(LegoFile* p_legoFile) { // TODO return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/build/legovehiclebuildstate.cpp b/LEGO1/lego/legoomni/src/build/legovehiclebuildstate.cpp index df9a0de6..a7b68529 100644 --- a/LEGO1/lego/legoomni/src/build/legovehiclebuildstate.cpp +++ b/LEGO1/lego/legoomni/src/build/legovehiclebuildstate.cpp @@ -25,7 +25,7 @@ LegoVehicleBuildState::LegoVehicleBuildState(char* p_classType) } // STUB: LEGO1 0x10026120 -MxResult LegoVehicleBuildState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult LegoVehicleBuildState::VTable0x1c(LegoFile* p_legoFile) { // TODO return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/common/animstate.cpp b/LEGO1/lego/legoomni/src/common/animstate.cpp index 1a08890b..c20841b7 100644 --- a/LEGO1/lego/legoomni/src/common/animstate.cpp +++ b/LEGO1/lego/legoomni/src/common/animstate.cpp @@ -18,7 +18,7 @@ AnimState::~AnimState() } // STUB: LEGO1 0x100652d0 -MxResult AnimState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult AnimState::VTable0x1c(LegoFile* p_legoFile) { // TODO return FAILURE; diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index 0bb0b066..93a9544b 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -4,7 +4,6 @@ #include "legoanimationmanager.h" #include "legoomni.h" #include "legostate.h" -#include "legostream.h" #include "legoutil.h" #include "legovideomanager.h" #include "mxbackgroundaudiomanager.h" @@ -31,6 +30,13 @@ const char* g_playersGSI = "Players.gsi"; // STRING: LEGO1 0x100f3e24 const char* g_historyGSI = "History.gsi"; +// This is a pointer to the end of the global variable name table, which has +// the text "END_OF_VARIABLES" in it. +// TODO: make g_endOfVariables reference the actual end of the variable array. +// GLOBAL: LEGO1 0x100f3e50 +// STRING: LEGO1 0x100f3e00 +const char* g_endOfVariables = "END_OF_VARIABLES"; + // GLOBAL: LEGO1 0x100f3e58 ColorStringStruct g_colorSaveData[43] = { {"c_dbbkfny0", "lego red"}, {"c_dbbkxly0", "lego white"}, {"c_chbasey0", "lego black"}, @@ -119,8 +125,8 @@ MxResult LegoGameState::Save(MxULong p_slot) MxVariableTable* variableTable = VariableTable(); MxString savePath; GetFileSavePath(&savePath, p_slot); - LegoFileStream fileStream; - if (fileStream.Open(savePath.GetData(), LegoStream::c_writeBit) != FAILURE) { + LegoFile fileStream; + if (fileStream.Open(savePath.GetData(), LegoFile::c_write) != FAILURE) { MxU32 maybeVersion = 0x1000C; fileStream.Write(&maybeVersion, 4); fileStream.Write(&m_unk0x24, 2); @@ -128,12 +134,12 @@ MxResult LegoGameState::Save(MxULong p_slot) fileStream.Write(&m_unk0xc, 1); for (MxS32 i = 0; i < sizeof(g_colorSaveData) / sizeof(g_colorSaveData[0]); ++i) { - if (LegoStream::WriteVariable(&fileStream, variableTable, g_colorSaveData[i].m_targetName) == FAILURE) + if (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 (WriteVariable(&fileStream, variableTable, "backgroundcolor") != FAILURE) { + if (WriteVariable(&fileStream, variableTable, "lightposition") != FAILURE) { WriteEndOfVariables(&fileStream); // TODO: Calls down to more aggregate writing functions @@ -166,8 +172,27 @@ void LegoGameState::SetSavePath(char* p_savePath) m_savePath = NULL; } +// FUNCTION: LEGO1 0x10039f70 +MxResult LegoGameState::WriteVariable(LegoStorage* p_stream, MxVariableTable* p_from, const char* p_variableName) +{ + MxResult result = FAILURE; + const char* variableValue = p_from->GetVariable(p_variableName); + + if (variableValue) { + MxU8 length = strlen(p_variableName); + 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); + } + } + } + return result; +} + // FUNCTION: LEGO1 0x1003a020 -MxResult LegoGameState::WriteEndOfVariables(LegoStream* p_stream) +MxResult LegoGameState::WriteEndOfVariables(LegoStorage* p_stream) { MxU8 len = strlen(g_endOfVariables); if (p_stream->Write(&len, 1) == SUCCESS) @@ -175,6 +200,36 @@ MxResult LegoGameState::WriteEndOfVariables(LegoStream* p_stream) return FAILURE; } +// 95% match, just some instruction ordering differences on the call to +// MxVariableTable::SetVariable at the end. +// FUNCTION: LEGO1 0x1003a080 +MxS32 LegoGameState::ReadVariable(LegoStorage* p_stream, MxVariableTable* p_to) +{ + MxS32 result = 1; + MxU8 length; + + if (p_stream->Read((char*) &length, 1) == SUCCESS) { + char nameBuffer[256]; + if (p_stream->Read(nameBuffer, length) == SUCCESS) { + nameBuffer[length] = '\0'; + if (strcmp(nameBuffer, g_endOfVariables) == 0) + // 2 -> "This was the last entry, done reading." + result = 2; + else { + if (p_stream->Read((char*) &length, 1) == SUCCESS) { + char valueBuffer[256]; + if (p_stream->Read(valueBuffer, length) == SUCCESS) { + result = 0; + valueBuffer[length] = '\0'; + p_to->SetVariable(nameBuffer, valueBuffer); + } + } + } + } + } + return result; +} + // FUNCTION: LEGO1 0x1003a170 void LegoGameState::GetFileSavePath(MxString* p_outPath, MxULong p_slotn) { @@ -312,7 +367,7 @@ void LegoGameState::ScoreStruct::WriteScoreHistory() } // STUB: LEGO1 0x1003ccf0 -void LegoGameState::ScoreStruct::FUN_1003ccf0(LegoFileStream&) +void LegoGameState::ScoreStruct::FUN_1003ccf0(LegoFile&) { // TODO } @@ -320,16 +375,16 @@ void LegoGameState::ScoreStruct::FUN_1003ccf0(LegoFileStream&) // FUNCTION: LEGO1 0x1003cdd0 void LegoGameState::SerializeScoreHistory(MxS16 p_flags) { - LegoFileStream stream; + LegoFile stream; MxString savePath(m_savePath); savePath += "\\"; savePath += g_historyGSI; - if (p_flags == LegoStream::c_writeBit) { + if (p_flags == LegoFile::c_write) { m_unk0xa6.WriteScoreHistory(); } - if (stream.Open(savePath.GetData(), (LegoStream::OpenFlags) p_flags) == SUCCESS) { + if (stream.Open(savePath.GetData(), p_flags) == SUCCESS) { m_unk0xa6.FUN_1003ccf0(stream); } } diff --git a/LEGO1/lego/legoomni/src/common/legostate.cpp b/LEGO1/lego/legoomni/src/common/legostate.cpp index c99fb708..16beb159 100644 --- a/LEGO1/lego/legoomni/src/common/legostate.cpp +++ b/LEGO1/lego/legoomni/src/common/legostate.cpp @@ -20,23 +20,10 @@ MxBool LegoState::SetFlag() } // FUNCTION: LEGO1 0x10005fb0 -MxResult LegoState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult LegoState::VTable0x1c(LegoFile* p_legoFile) { - if (p_legoFileStream->IsWriteMode()) { - p_legoFileStream->FUN_10006030(this->ClassName()); + if (p_legoFile->IsWriteMode()) { + p_legoFile->FUN_10006030(this->ClassName()); } return SUCCESS; } - -// FUNCTION: LEGO1 0x10006030 -LegoFileStream* LegoFileStream::FUN_10006030(MxString p_str) -{ - const char* data = p_str.GetData(); - MxU32 fullLength = strlen(data); - - MxU16 limitedLength = fullLength; - Write(&limitedLength, sizeof(limitedLength)); - Write(data, (MxS16) fullLength); - - return this; -} diff --git a/LEGO1/lego/legoomni/src/common/legostream.cpp b/LEGO1/lego/legoomni/src/common/legostream.cpp deleted file mode 100644 index f54d5982..00000000 --- a/LEGO1/lego/legoomni/src/common/legostream.cpp +++ /dev/null @@ -1,201 +0,0 @@ - -#include "legostream.h" - -#include "mxvariabletable.h" - -#include -#include - -// This is a pointer to the end of the global variable name table, which has -// the text "END_OF_VARIABLES" in it. -// TODO: make g_endOfVariables reference the actual end of the variable array. -// GLOBAL: LEGO1 0x100f3e50 -// STRING: LEGO1 0x100f3e00 -const char* g_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. -DECOMP_SIZE_ASSERT(LegoStream, 0x8); -DECOMP_SIZE_ASSERT(LegoFileStream, 0xC); -DECOMP_SIZE_ASSERT(LegoMemoryStream, 0x10); - -// FUNCTION: LEGO1 0x10039f70 -MxResult LegoStream::WriteVariable(LegoStream* p_stream, MxVariableTable* p_from, const char* p_variableName) -{ - MxResult result = FAILURE; - const char* variableValue = p_from->GetVariable(p_variableName); - - if (variableValue) { - MxU8 length = strlen(p_variableName); - 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); - } - } - } - return result; -} - -// 95% match, just some instruction ordering differences on the call to -// MxVariableTable::SetVariable at the end. -// FUNCTION: LEGO1 0x1003a080 -MxS32 LegoStream::ReadVariable(LegoStream* p_stream, MxVariableTable* p_to) -{ - MxS32 result = 1; - MxU8 length; - - if (p_stream->Read((char*) &length, 1) == SUCCESS) { - char nameBuffer[256]; - if (p_stream->Read(nameBuffer, length) == SUCCESS) { - nameBuffer[length] = '\0'; - if (strcmp(nameBuffer, g_endOfVariables) == 0) - // 2 -> "This was the last entry, done reading." - result = 2; - else { - if (p_stream->Read((char*) &length, 1) == SUCCESS) { - char valueBuffer[256]; - if (p_stream->Read(valueBuffer, length) == SUCCESS) { - result = 0; - valueBuffer[length] = '\0'; - p_to->SetVariable(nameBuffer, valueBuffer); - } - } - } - } - } - return result; -} - -// FUNCTION: LEGO1 0x10045ae0 -MxBool LegoStream::IsWriteMode() -{ - return m_mode == LEGOSTREAM_MODE_WRITE; -} - -// FUNCTION: LEGO1 0x10045af0 -MxBool LegoStream::IsReadMode() -{ - return m_mode == LEGOSTREAM_MODE_READ; -} - -// FUNCTION: LEGO1 0x10099080 -LegoMemoryStream::LegoMemoryStream(char* p_buffer) : LegoStream() -{ - m_buffer = p_buffer; - m_offset = 0; -} - -// FUNCTION: LEGO1 0x10099160 -MxResult LegoMemoryStream::Read(void* p_buffer, MxU32 p_size) -{ - memcpy(p_buffer, m_buffer + m_offset, p_size); - m_offset += p_size; - return SUCCESS; -} - -// FUNCTION: LEGO1 0x10099190 -MxResult LegoMemoryStream::Write(const void* p_buffer, MxU32 p_size) -{ - memcpy(m_buffer + m_offset, p_buffer, p_size); - m_offset += p_size; - return SUCCESS; -} - -// FUNCTION: LEGO1 0x100991c0 -LegoFileStream::LegoFileStream() : LegoStream() -{ - m_hFile = NULL; -} - -// FUNCTION: LEGO1 0x10099250 -LegoFileStream::~LegoFileStream() -{ - if (m_hFile != NULL) - fclose(m_hFile); -} - -// FUNCTION: LEGO1 0x100992c0 -MxResult LegoFileStream::Read(void* p_buffer, MxU32 p_size) -{ - if (m_hFile == NULL) - return FAILURE; - - return (fread(p_buffer, 1, p_size, m_hFile) == p_size) ? SUCCESS : FAILURE; -} - -// FUNCTION: LEGO1 0x10099300 -MxResult LegoFileStream::Write(const void* p_buffer, MxU32 p_size) -{ - if (m_hFile == NULL) - return FAILURE; - - return (fwrite(p_buffer, 1, p_size, m_hFile) == p_size) ? SUCCESS : FAILURE; -} - -// FUNCTION: LEGO1 0x10099340 -MxResult LegoFileStream::Tell(MxU32* p_offset) -{ - if (m_hFile == NULL) - return FAILURE; - - int got = ftell(m_hFile); - if (got == -1) - return FAILURE; - - *p_offset = got; - return SUCCESS; -} - -// FUNCTION: LEGO1 0x10099370 -MxResult LegoFileStream::Seek(MxU32 p_offset) -{ - if (m_hFile == NULL) - return FAILURE; - - return (fseek(m_hFile, p_offset, 0) == 0) ? SUCCESS : FAILURE; -} - -// FUNCTION: LEGO1 0x100993a0 -MxResult LegoFileStream::Open(const char* p_filename, OpenFlags p_mode) -{ - char modeString[4]; - - if (m_hFile != NULL) - fclose(m_hFile); - - modeString[0] = '\0'; - if (p_mode & c_readBit) { - m_mode = LEGOSTREAM_MODE_READ; - strcat(modeString, "r"); - } - - if (p_mode & c_writeBit) { - if (m_mode != LEGOSTREAM_MODE_READ) - m_mode = LEGOSTREAM_MODE_WRITE; - strcat(modeString, "w"); - } - - if ((p_mode & c_binaryBit) != 0) - strcat(modeString, "b"); - else - strcat(modeString, "t"); - - return (m_hFile = fopen(p_filename, modeString)) ? SUCCESS : FAILURE; -} - -// FUNCTION: LEGO1 0x100994a0 -MxResult LegoMemoryStream::Tell(MxU32* p_offset) -{ - *p_offset = m_offset; - return SUCCESS; -} - -// FUNCTION: LEGO1 0x100994b0 -MxResult LegoMemoryStream::Seek(MxU32 p_offset) -{ - m_offset = p_offset; - return SUCCESS; -} diff --git a/LEGO1/lego/legoomni/src/common/legounksavedatawriter.cpp b/LEGO1/lego/legoomni/src/common/legounksavedatawriter.cpp index c06ebb7e..551dea32 100644 --- a/LEGO1/lego/legoomni/src/common/legounksavedatawriter.cpp +++ b/LEGO1/lego/legoomni/src/common/legounksavedatawriter.cpp @@ -1,7 +1,6 @@ #include "legounksavedatawriter.h" #include "legogamestate.h" -#include "legostream.h" #include "roi/legoroi.h" DECOMP_SIZE_ASSERT(LegoSaveDataEntry3, 0x108); @@ -10,7 +9,7 @@ DECOMP_SIZE_ASSERT(LegoSaveDataEntry3, 0x108); LegoSaveDataEntry3 g_saveData3[66]; // FUNCTION: LEGO1 0x10083310 -MxResult LegoUnkSaveDataWriter::WriteSaveData3(LegoStream* p_stream) +MxResult LegoUnkSaveDataWriter::WriteSaveData3(LegoStorage* p_stream) { MxResult result = FAILURE; diff --git a/LEGO1/lego/legoomni/src/gasstation/gasstationstate.cpp b/LEGO1/lego/legoomni/src/gasstation/gasstationstate.cpp index 5bbcdde6..b4b242ac 100644 --- a/LEGO1/lego/legoomni/src/gasstation/gasstationstate.cpp +++ b/LEGO1/lego/legoomni/src/gasstation/gasstationstate.cpp @@ -18,7 +18,7 @@ GasStationState::GasStationState() } // STUB: LEGO1 0x10006300 -MxResult GasStationState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult GasStationState::VTable0x1c(LegoFile* p_legoFile) { // TODO return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/hospital/ambulancemissionstate.cpp b/LEGO1/lego/legoomni/src/hospital/ambulancemissionstate.cpp index 601f1ccd..eb74f64c 100644 --- a/LEGO1/lego/legoomni/src/hospital/ambulancemissionstate.cpp +++ b/LEGO1/lego/legoomni/src/hospital/ambulancemissionstate.cpp @@ -20,7 +20,7 @@ AmbulanceMissionState::AmbulanceMissionState() } // STUB: LEGO1 0x10037440 -MxResult AmbulanceMissionState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult AmbulanceMissionState::VTable0x1c(LegoFile* p_legoFile) { // TODO return 0; diff --git a/LEGO1/lego/legoomni/src/hospital/hospitalstate.cpp b/LEGO1/lego/legoomni/src/hospital/hospitalstate.cpp index 5921cd0c..012d9c4a 100644 --- a/LEGO1/lego/legoomni/src/hospital/hospitalstate.cpp +++ b/LEGO1/lego/legoomni/src/hospital/hospitalstate.cpp @@ -14,7 +14,7 @@ HospitalState::HospitalState() } // STUB: LEGO1 0x10076530 -MxResult HospitalState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult HospitalState::VTable0x1c(LegoFile* p_legoFile) { // TODO return 0; diff --git a/LEGO1/lego/legoomni/src/pizzeria/pizzamissionstate.cpp b/LEGO1/lego/legoomni/src/pizzeria/pizzamissionstate.cpp index 6fb460a1..6d1cac49 100644 --- a/LEGO1/lego/legoomni/src/pizzeria/pizzamissionstate.cpp +++ b/LEGO1/lego/legoomni/src/pizzeria/pizzamissionstate.cpp @@ -4,7 +4,7 @@ DECOMP_SIZE_ASSERT(PizzaMissionStateEntry, 0x20) DECOMP_SIZE_ASSERT(PizzaMissionState, 0xb0) // STUB: LEGO1 0x100393c0 -MxResult PizzaMissionState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult PizzaMissionState::VTable0x1c(LegoFile* p_legoFile) { // TODO return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/pizzeria/pizzeriastate.cpp b/LEGO1/lego/legoomni/src/pizzeria/pizzeriastate.cpp index 3422c68d..6694e4d8 100644 --- a/LEGO1/lego/legoomni/src/pizzeria/pizzeriastate.cpp +++ b/LEGO1/lego/legoomni/src/pizzeria/pizzeriastate.cpp @@ -7,7 +7,7 @@ PizzeriaState::PizzeriaState() } // STUB: LEGO1 0x10017da0 -MxResult PizzeriaState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult PizzeriaState::VTable0x1c(LegoFile* p_legoFile) { // TODO return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/police/policestate.cpp b/LEGO1/lego/legoomni/src/police/policestate.cpp index b0011ccb..6e026c79 100644 --- a/LEGO1/lego/legoomni/src/police/policestate.cpp +++ b/LEGO1/lego/legoomni/src/police/policestate.cpp @@ -12,18 +12,18 @@ PoliceState::PoliceState() } // FUNCTION: LEGO1 0x1005e990 -MxResult PoliceState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult PoliceState::VTable0x1c(LegoFile* p_legoFile) { - if (p_legoFileStream->IsWriteMode()) { - p_legoFileStream->FUN_10006030(ClassName()); + if (p_legoFile->IsWriteMode()) { + p_legoFile->FUN_10006030(ClassName()); } - if (p_legoFileStream->IsReadMode()) { - p_legoFileStream->Read(&m_unk0x8, sizeof(m_unk0x8)); + if (p_legoFile->IsReadMode()) { + p_legoFile->Read(&m_unk0x8, sizeof(m_unk0x8)); } else { undefined4 unk0x8 = m_unk0x8; - p_legoFileStream->Write(&unk0x8, sizeof(m_unk0x8)); + p_legoFile->Write(&unk0x8, sizeof(m_unk0x8)); } return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/race/racestate.cpp b/LEGO1/lego/legoomni/src/race/racestate.cpp index bdc003f0..db6d96dc 100644 --- a/LEGO1/lego/legoomni/src/race/racestate.cpp +++ b/LEGO1/lego/legoomni/src/race/racestate.cpp @@ -12,7 +12,7 @@ RaceState::RaceState() } // STUB: LEGO1 0x10016140 -MxResult RaceState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult RaceState::VTable0x1c(LegoFile* p_legoFile) { // TODO return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/towtrack/towtrackmissionstate.cpp b/LEGO1/lego/legoomni/src/towtrack/towtrackmissionstate.cpp index a5719da5..9a85e0b6 100644 --- a/LEGO1/lego/legoomni/src/towtrack/towtrackmissionstate.cpp +++ b/LEGO1/lego/legoomni/src/towtrack/towtrackmissionstate.cpp @@ -21,54 +21,54 @@ TowTrackMissionState::TowTrackMissionState() } // FUNCTION: LEGO1 0x1004dde0 -MxResult TowTrackMissionState::VTable0x1c(LegoFileStream* p_legoFileStream) +MxResult TowTrackMissionState::VTable0x1c(LegoFile* p_legoFile) { - if (p_legoFileStream->IsWriteMode()) { - p_legoFileStream->FUN_10006030(this->ClassName()); + if (p_legoFile->IsWriteMode()) { + p_legoFile->FUN_10006030(this->ClassName()); } - if (p_legoFileStream->IsReadMode()) { - p_legoFileStream->Read(&m_unk0x12, sizeof(MxU16)); - p_legoFileStream->Read(&m_unk0x14, sizeof(MxU16)); - p_legoFileStream->Read(&m_unk0x16, sizeof(MxU16)); - p_legoFileStream->Read(&m_unk0x18, sizeof(MxU16)); - p_legoFileStream->Read(&m_unk0x1a, sizeof(MxU16)); - p_legoFileStream->Read(&m_unk0x1c, sizeof(MxU16)); - p_legoFileStream->Read(&m_color1, sizeof(MxU16)); - p_legoFileStream->Read(&m_color2, sizeof(MxU16)); - p_legoFileStream->Read(&m_color3, sizeof(MxU16)); - p_legoFileStream->Read(&m_color4, sizeof(MxU16)); + if (p_legoFile->IsReadMode()) { + p_legoFile->Read(&m_unk0x12, sizeof(MxU16)); + p_legoFile->Read(&m_unk0x14, sizeof(MxU16)); + p_legoFile->Read(&m_unk0x16, sizeof(MxU16)); + p_legoFile->Read(&m_unk0x18, sizeof(MxU16)); + p_legoFile->Read(&m_unk0x1a, sizeof(MxU16)); + p_legoFile->Read(&m_unk0x1c, sizeof(MxU16)); + p_legoFile->Read(&m_color1, sizeof(MxU16)); + p_legoFile->Read(&m_color2, sizeof(MxU16)); + p_legoFile->Read(&m_color3, sizeof(MxU16)); + p_legoFile->Read(&m_color4, sizeof(MxU16)); } - else if (p_legoFileStream->IsWriteMode()) { + else if (p_legoFile->IsWriteMode()) { MxU16 write = m_unk0x12; - p_legoFileStream->Write(&write, sizeof(MxU16)); + p_legoFile->Write(&write, sizeof(MxU16)); write = m_unk0x14; - p_legoFileStream->Write(&write, sizeof(MxU16)); + p_legoFile->Write(&write, sizeof(MxU16)); write = m_unk0x16; - p_legoFileStream->Write(&write, sizeof(MxU16)); + p_legoFile->Write(&write, sizeof(MxU16)); write = m_unk0x18; - p_legoFileStream->Write(&write, sizeof(MxU16)); + p_legoFile->Write(&write, sizeof(MxU16)); write = m_unk0x1a; - p_legoFileStream->Write(&write, sizeof(MxU16)); + p_legoFile->Write(&write, sizeof(MxU16)); write = m_unk0x1c; - p_legoFileStream->Write(&write, sizeof(MxU16)); + p_legoFile->Write(&write, sizeof(MxU16)); write = m_color1; - p_legoFileStream->Write(&write, sizeof(MxU16)); + p_legoFile->Write(&write, sizeof(MxU16)); write = m_color2; - p_legoFileStream->Write(&write, sizeof(MxU16)); + p_legoFile->Write(&write, sizeof(MxU16)); write = m_color3; - p_legoFileStream->Write(&write, sizeof(MxU16)); + p_legoFile->Write(&write, sizeof(MxU16)); write = m_color4; - p_legoFileStream->Write(&write, sizeof(MxU16)); + p_legoFile->Write(&write, sizeof(MxU16)); } return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index 027a3b83..0167833d 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -1,7 +1,6 @@ #include "legoanimpresenter.h" #include "legoomni.h" -#include "legostream.h" #include "legoworld.h" #include "mxcompositepresenter.h" #include "mxdsanim.h" @@ -60,7 +59,7 @@ void LegoAnimPresenter::Destroy(MxBool p_fromDestructor) MxResult LegoAnimPresenter::VTable0x88(MxStreamChunk* p_chunk) { MxResult result = FAILURE; - LegoMemoryStream stream((char*) p_chunk->GetData()); + LegoMemory stream((char*) p_chunk->GetData()); MxS32 magicSig; MxS32 val2 = 0; @@ -238,7 +237,7 @@ LegoAnimClass::~LegoAnimClass() } // STUB: LEGO1 0x100a0c70 -MxResult LegoAnimClass::VTable0x10(LegoMemoryStream* p_stream, MxS32) +MxResult LegoAnimClass::VTable0x10(LegoMemory* p_stream, MxS32) { return SUCCESS; } diff --git a/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp b/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp index ce352f7e..7fff790f 100644 --- a/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp @@ -1,7 +1,7 @@ #include "legopalettepresenter.h" +#include "lego/sources/misc/legostorage.h" #include "legoomni.h" -#include "legostream.h" #include "legovideomanager.h" #include "mxstreamchunk.h" @@ -52,7 +52,7 @@ MxResult LegoPalettePresenter::ParsePalette(MxStreamChunk* p_chunk) RGBQUAD palette[256]; MxResult result = FAILURE; - LegoMemoryStream stream((char*) p_chunk->GetData()); + LegoMemory stream((char*) p_chunk->GetData()); if (stream.Read(buffer, sizeof(buffer)) == SUCCESS) { if (stream.Read(palette, sizeof(palette)) == SUCCESS) { m_palette = new MxPalette(palette); diff --git a/LEGO1/lego/sources/misc/legoimage.cpp b/LEGO1/lego/sources/misc/legoimage.cpp new file mode 100644 index 00000000..34d4978f --- /dev/null +++ b/LEGO1/lego/sources/misc/legoimage.cpp @@ -0,0 +1,176 @@ +#include "legoimage.h" + +#include "decomp.h" +#include "legostorage.h" +#include "memory.h" + +DECOMP_SIZE_ASSERT(LegoPaletteEntry, 0x3); +DECOMP_SIZE_ASSERT(LegoImage, 0x310); + +// FUNCTION: LEGO1 0x100994c0 +LegoPaletteEntry::LegoPaletteEntry() +{ + m_red = 0; + m_green = 0; + m_blue = 0; +} + +// FUNCTION: LEGO1 0x100994d0 +LegoResult LegoPaletteEntry::Read(LegoStorage* p_storage) +{ + LegoResult result; + if ((result = p_storage->Read(&m_red, sizeof(m_red))) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_green, sizeof(m_green))) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_blue, sizeof(m_blue))) != SUCCESS) { + return result; + } + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10099520 +LegoResult LegoPaletteEntry::Write(LegoStorage* p_storage) +{ + LegoResult result; + if ((result = p_storage->Write(&m_red, sizeof(m_red))) != SUCCESS) { + return result; + } + if ((result = p_storage->Write(&m_green, sizeof(m_green))) != SUCCESS) { + return result; + } + if ((result = p_storage->Write(&m_blue, sizeof(m_blue))) != SUCCESS) { + return result; + } + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10099570 +LegoImage::LegoImage() +{ + m_width = 0; + m_height = 0; + m_count = 0; + m_bits = NULL; +} + +// FUNCTION: LEGO1 0x100995a0 +LegoImage::LegoImage(LegoU32 p_width, LegoU32 p_height) +{ + m_width = p_width; + m_height = p_height; + m_count = 0; + m_bits = new LegoU8[m_width * m_height]; +} + +// FUNCTION: LEGO1 0x100995f0 +LegoImage::~LegoImage() +{ + if (m_bits) { + delete[] m_bits; + } +} + +// FUNCTION: LEGO1 0x10099610 +LegoResult LegoImage::Read(LegoStorage* p_storage, LegoU32 p_square) +{ + LegoResult result; + if ((result = p_storage->Read(&m_width, sizeof(m_width))) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_height, sizeof(m_height))) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_count, sizeof(m_height))) != SUCCESS) { + return result; + } + for (LegoU32 i = 0; i < m_count; i++) { + if ((result = m_palette[i].Read(p_storage)) != SUCCESS) { + return result; + } + } + if (m_bits) { + delete[] m_bits; + } + m_bits = new LegoU8[m_width * m_height]; + if ((result = p_storage->Read(m_bits, m_width * m_height)) != SUCCESS) { + return result; + } + + if (p_square && m_width != m_height) { + LegoU8* newBits; + + if (m_height < m_width) { + LegoU32 aspect = m_width / m_height; + newBits = new LegoU8[m_width * m_width]; + LegoU8* src = m_bits; + LegoU8* dst = newBits; + + for (LegoU32 row = 0; row < m_height; row++) { + if (aspect) { + for (LegoU32 dup = aspect; dup; dup--) { + memcpy(dst, src, m_width); + dst += m_width; + } + } + src += m_width; + } + + m_height = m_width; + } + else { + LegoU32 aspect = m_height / m_width; + newBits = new LegoU8[m_height * m_height]; + LegoU8* src = m_bits; + LegoU8* dst = newBits; + + for (LegoU32 row = 0; row < m_height; row++) { + for (LegoU32 col = 0; col < m_width; col++) { + if (aspect) { + for (LegoU32 dup = aspect; dup; dup--) { + *dst = *src; + dst++; + } + } + + src++; + } + } + + m_width = m_height; + } + + delete[] m_bits; + m_bits = newBits; + } + + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100997e0 +LegoResult LegoImage::Write(LegoStorage* p_storage) +{ + LegoResult result; + if ((result = p_storage->Write(&m_width, sizeof(m_width))) != SUCCESS) { + return result; + } + if ((result = p_storage->Write(&m_height, sizeof(m_height))) != SUCCESS) { + return result; + } + if ((result = p_storage->Write(&m_count, sizeof(m_height))) != SUCCESS) { + return result; + } + for (LegoU32 i = 0; i < m_count; i++) { + if ((result = m_palette[i].Write(p_storage)) != SUCCESS) { + return result; + } + } + if (m_bits) { + if ((result = p_storage->Write(m_bits, m_width * m_height)) != SUCCESS) { + return result; + } + } + return SUCCESS; +} diff --git a/LEGO1/lego/sources/misc/legoimage.h b/LEGO1/lego/sources/misc/legoimage.h new file mode 100644 index 00000000..7990277e --- /dev/null +++ b/LEGO1/lego/sources/misc/legoimage.h @@ -0,0 +1,54 @@ +#ifndef __LEGOIMAGE_H +#define __LEGOIMAGE_H + +#include "legotypes.h" + +class LegoStorage; + +// SIZE 0x3 +class LegoPaletteEntry { +public: + LegoPaletteEntry(); + // LegoPaletteEntry(LegoU8 p_red, LegoU8 p_green, LegoU8 p_blue); + LegoU8 GetRed() { return m_red; } + void SetRed(LegoU8 p_red) { m_red = p_red; } + LegoU8 GetGreen() { return m_green; } + void SetGreen(LegoU8 p_green) { m_green = p_green; } + LegoU8 GetBlue() { return m_blue; } + void SetBlue(LegoU8 p_blue) { m_blue = p_blue; } + LegoResult Read(LegoStorage* p_storage); + LegoResult Write(LegoStorage* p_storage); + +protected: + LegoU8 m_red; // 0x00 + LegoU8 m_green; // 0x01 + LegoU8 m_blue; // 0x02 +}; + +// 0x310 +class LegoImage { +public: + LegoImage(); + LegoImage(LegoU32 p_width, LegoU32 p_height); + ~LegoImage(); + LegoU32 GetWidth() { return m_width; } + void SetWidth(LegoU32 p_width) { m_width = p_width; } + LegoU32 GetHeight() { return m_height; } + void SetHeight(LegoU32 p_height) { m_height = p_height; } + LegoPaletteEntry* GetPalette() { return m_palette; } + LegoPaletteEntry& GetPaletteEntry(LegoU32 p_i) { return m_palette[p_i]; } + void SetPaletteEntry(LegoU32 p_i, LegoPaletteEntry& p_paletteEntry) { m_palette[p_i] = p_paletteEntry; } + LegoU8* GetBits() { return m_bits; } + void SetBits(LegoU8* p_bits) { m_bits = p_bits; } + LegoResult Read(LegoStorage* p_storage, LegoU32 p_square); + LegoResult Write(LegoStorage* p_storage); + +protected: + LegoU32 m_width; // 0x00 + LegoU32 m_height; // 0x04 + LegoU32 m_count; // 0x08 + LegoPaletteEntry m_palette[256]; // 0x0c + LegoU8* m_bits; // 0x30c +}; + +#endif // __LEGOIMAGE_H diff --git a/LEGO1/lego/sources/misc/legostorage.cpp b/LEGO1/lego/sources/misc/legostorage.cpp new file mode 100644 index 00000000..50621f73 --- /dev/null +++ b/LEGO1/lego/sources/misc/legostorage.cpp @@ -0,0 +1,139 @@ +#include "legostorage.h" + +#include "decomp.h" + +#include +#include + +DECOMP_SIZE_ASSERT(LegoStorage, 0x8); +DECOMP_SIZE_ASSERT(LegoMemory, 0x10); +DECOMP_SIZE_ASSERT(LegoFile, 0xc); + +// FUNCTION: LEGO1 0x10099080 +LegoMemory::LegoMemory(void* p_buffer) : LegoStorage() +{ + m_buffer = (LegoU8*) p_buffer; + m_position = 0; +} + +// FUNCTION: LEGO1 0x10099160 +LegoResult LegoMemory::Read(void* p_buffer, LegoU32 p_size) +{ + memcpy(p_buffer, m_buffer + m_position, p_size); + m_position += p_size; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10099190 +LegoResult LegoMemory::Write(const void* p_buffer, LegoU32 p_size) +{ + memcpy(m_buffer + m_position, p_buffer, p_size); + m_position += p_size; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100991c0 +LegoFile::LegoFile() +{ + m_file = NULL; +} + +// FUNCTION: LEGO1 0x10099250 +LegoFile::~LegoFile() +{ + if (m_file) { + fclose(m_file); + } +} + +// FUNCTION: LEGO1 0x100992c0 +LegoResult LegoFile::Read(void* p_buffer, LegoU32 p_size) +{ + if (!m_file) { + return FAILURE; + } + if (fread(p_buffer, 1, p_size, m_file) != p_size) { + return FAILURE; + } + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10099300 +LegoResult LegoFile::Write(const void* p_buffer, LegoU32 p_size) +{ + if (!m_file) { + return FAILURE; + } + if (fwrite(p_buffer, 1, p_size, m_file) != p_size) { + return FAILURE; + } + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10099340 +LegoResult LegoFile::GetPosition(LegoU32& p_position) +{ + if (!m_file) { + return FAILURE; + } + LegoU32 position = ftell(m_file); + if (position == -1) { + return FAILURE; + } + p_position = position; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10099370 +LegoResult LegoFile::SetPosition(LegoU32 p_position) +{ + if (!m_file) { + return FAILURE; + } + if (fseek(m_file, p_position, SEEK_SET) != 0) { + return FAILURE; + } + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100993a0 +LegoResult LegoFile::Open(const char* p_name, LegoU32 p_mode) +{ + if (m_file) { + fclose(m_file); + } + char mode[4]; + mode[0] = '\0'; + if (p_mode & c_read) { + m_mode = c_read; + strcat(mode, "r"); + } + if (p_mode & c_write) { + if (m_mode != c_read) + m_mode = c_write; + strcat(mode, "w"); + } + if ((p_mode & c_text) != 0) + strcat(mode, "t"); + else + strcat(mode, "b"); + + if (!(m_file = fopen(p_name, mode))) { + return FAILURE; + } + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100994a0 +LegoResult LegoMemory::GetPosition(LegoU32& p_position) +{ + p_position = m_position; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100994b0 +LegoResult LegoMemory::SetPosition(LegoU32 p_position) +{ + m_position = p_position; + return SUCCESS; +} diff --git a/LEGO1/lego/sources/misc/legostorage.h b/LEGO1/lego/sources/misc/legostorage.h new file mode 100644 index 00000000..5bd6ea67 --- /dev/null +++ b/LEGO1/lego/sources/misc/legostorage.h @@ -0,0 +1,95 @@ +#ifndef __LEGOSTORAGE_H +#define __LEGOSTORAGE_H + +#include "legotypes.h" +#include "mxstring.h" + +#include + +// VTABLE: LEGO1 0x100d7d80 +// SIZE 0x08 +class LegoStorage { +public: + enum OpenFlags { + c_read = 1, + c_write = 2, + c_text = 4 + }; + + LegoStorage() : m_mode(0) {} + + // FUNCTION: LEGO1 0x10045ad0 + virtual ~LegoStorage(){}; + + virtual LegoResult Read(void* p_buffer, LegoU32 p_size) = 0; + virtual LegoResult Write(const void* p_buffer, LegoU32 p_size) = 0; + virtual LegoResult GetPosition(LegoU32& p_position) = 0; + virtual LegoResult SetPosition(LegoU32 p_position) = 0; + + // FUNCTION: LEGO1 0x10045ae0 + virtual LegoBool IsWriteMode() { return m_mode == c_write; } + + // FUNCTION: LEGO1 0x10045af0 + virtual LegoBool IsReadMode() { return m_mode == c_read; } + + // SYNTHETIC: LEGO1 0x10045b00 + // LegoStorage::`scalar deleting destructor' + +protected: + LegoU8 m_mode; // 0x04 +}; + +// VTABLE: LEGO1 0x100db710 +// SIZE 0x10 +class LegoMemory : public LegoStorage { +public: + LegoMemory(void* p_buffer); + virtual LegoResult Read(void* p_buffer, LegoU32 p_size); + virtual LegoResult Write(const void* p_buffer, LegoU32 p_size); + virtual LegoResult GetPosition(LegoU32& p_position); + virtual LegoResult SetPosition(LegoU32 p_position); + + // SYNTHETIC: LEGO1 0x10045a80 + // LegoMemory::~LegoMemory + + // SYNTHETIC: LEGO1 0x100990f0 + // LegoMemory::`scalar deleting destructor' + +protected: + LegoU8* m_buffer; // 0x04 + LegoU32 m_position; // 0x08 +}; + +// VTABLE: LEGO1 0x100db730 +// SIZE 0x0c +class LegoFile : public LegoStorage { +public: + LegoFile(); + virtual ~LegoFile() override; + virtual LegoResult Read(void* p_buffer, LegoU32 p_size); + virtual LegoResult Write(const void* p_buffer, LegoU32 p_size); + virtual LegoResult GetPosition(LegoU32& p_position); + virtual LegoResult SetPosition(LegoU32 p_position); + LegoResult Open(const char* p_name, LegoU32 p_mode); + + // FUNCTION: LEGO1 0x10006030 + LegoStorage* FUN_10006030(MxString p_str) + { + const char* data = p_str.GetData(); + LegoU32 fullLength = strlen(data); + + LegoU16 limitedLength = fullLength; + Write(&limitedLength, sizeof(limitedLength)); + Write((char*) data, (LegoS16) fullLength); + + return this; + } + + // SYNTHETIC: LEGO1 0x10099230 + // LegoFile::`scalar deleting destructor' + +protected: + FILE* m_file; // 0x08 +}; + +#endif // __LEGOSTORAGE_H diff --git a/LEGO1/lego/sources/misc/legotexture.cpp b/LEGO1/lego/sources/misc/legotexture.cpp new file mode 100644 index 00000000..8eb74bfe --- /dev/null +++ b/LEGO1/lego/sources/misc/legotexture.cpp @@ -0,0 +1,31 @@ +#include "legotexture.h" + +#include "decomp.h" +#include "legoimage.h" +#include "legostorage.h" + +DECOMP_SIZE_ASSERT(LegoTexture, 0x4); + +// FUNCTION: LEGO1 0x10098fb0 +LegoTexture::LegoTexture() +{ + m_image = new LegoImage(); +} + +// FUNCTION: LEGO1 0x10099030 +LegoTexture::~LegoTexture() +{ + delete m_image; +} + +// FUNCTION: LEGO1 0x10099050 +LegoResult LegoTexture::Read(LegoStorage* p_storage, LegoU32 p_square) +{ + return m_image->Read(p_storage, p_square); +} + +// FUNCTION: LEGO1 0x10099070 +LegoResult LegoTexture::Write(LegoStorage* p_storage) +{ + return m_image->Write(p_storage); +} diff --git a/LEGO1/lego/sources/misc/legotexture.h b/LEGO1/lego/sources/misc/legotexture.h new file mode 100644 index 00000000..1e279660 --- /dev/null +++ b/LEGO1/lego/sources/misc/legotexture.h @@ -0,0 +1,23 @@ +#ifndef __LEGOTEXTURE_H +#define __LEGOTEXTURE_H + +#include "legotypes.h" + +class LegoImage; +class LegoStorage; + +// SIZE 0x04 +class LegoTexture { +public: + LegoTexture(); + ~LegoTexture(); + LegoImage* GetImage() { return m_image; } + void SetImage(LegoImage* p_image) { m_image = p_image; } + LegoResult Read(LegoStorage* p_storage, LegoU32 p_square); + LegoResult Write(LegoStorage* p_storage); + +protected: + LegoImage* m_image; // 0x00 +}; + +#endif // __LEGOTEXTURE_H diff --git a/LEGO1/lego/sources/misc/legotypes.h b/LEGO1/lego/sources/misc/legotypes.h new file mode 100644 index 00000000..7ba6ada1 --- /dev/null +++ b/LEGO1/lego/sources/misc/legotypes.h @@ -0,0 +1,44 @@ +/* + This unpublished source code contains trade secrets and + copyrighted materials which are the property of Mindscape, Inc. + Unauthorized use, copying or distribution is a violation of U.S. + and international laws and is strictly prohibited. +*/ + +#ifndef __LEGOTYPES_H +#define __LEGOTYPES_H + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef SUCCESS +#define SUCCESS 0 +#endif + +#ifndef FAILURE +#define FAILURE -1 +#endif + +typedef char LegoS8; +typedef unsigned char LegoU8; +typedef short LegoS16; +typedef unsigned short LegoU16; +typedef long LegoS32; +typedef unsigned long LegoU32; +typedef float LegoFloat; +typedef char LegoChar; + +typedef LegoU8 LegoBool; +typedef LegoS32 LegoTime; +typedef LegoS32 LegoResult; + +#endif // __LEGOTYPES_H diff --git a/LEGO1/lego/sources/misc/legoutil.h b/LEGO1/lego/sources/misc/legoutil.h new file mode 100644 index 00000000..92bb84c2 --- /dev/null +++ b/LEGO1/lego/sources/misc/legoutil.h @@ -0,0 +1,54 @@ +#ifndef __LEGOUTIL_H +#define __LEGOUTIL_H + +template +inline T Min(T p_t1, T p_t2) +{ + return p_t1 < p_t2 ? p_t1 : p_t2; +} + +template +inline T Min(T p_t1, T p_t2, T p_t3) +{ + return Min(p_t1, Min(p_t2, p_t3)); +} + +template +inline T Max(T p_t1, T p_t2) +{ + return p_t1 > p_t2 ? p_t1 : p_t2; +} + +template +inline T Max(T p_t1, T p_t2, T p_t3) +{ + return Max(p_t1, Max(p_t2, p_t3)); +} + +template +inline T Abs(T p_t) +{ + return p_t < 0 ? -p_t : p_t; +} + +template +inline void Swap(T& p_t1, T& p_t2) +{ + T t = p_t1; + p_t1 = p_t2; + p_t2 = t; +} + +template +inline T DToR(T p_d) +{ + return p_d * 3.1416F / 180.0F; +} + +template +inline T RToD(T p_r) +{ + return p_r * 180.0F / 3.1416F; +} + +#endif // __LEGOUTIL_H diff --git a/LEGO1/lego/sources/misc/version.h b/LEGO1/lego/sources/misc/version.h new file mode 100644 index 00000000..1eaa84af --- /dev/null +++ b/LEGO1/lego/sources/misc/version.h @@ -0,0 +1,6 @@ +#ifndef __VERSION_H +#define __VERSION_H + +#define MODEL_VERSION 3 + +#endif // __VERSION_H