From 70b0f76fa1388064b04789902d4e1c6a1f3f42db Mon Sep 17 00:00:00 2001
From: Christian Semmler <mail@csemmler.com>
Date: Thu, 16 Jan 2025 16:13:23 -0700
Subject: [PATCH] Move Read/Write functions to `LegoStorage` base class, match
 `Act1State::Serialize` (#1335)

* Move Read/Write function to LegoStorage base class

* Proper const use for vector / BETA match

* Match `Act1State::Serialize`
---
 LEGO1/lego/legoomni/include/act3ammo.h        |   2 +-
 LEGO1/lego/legoomni/include/ambulance.h       |   2 +-
 LEGO1/lego/legoomni/include/gasstation.h      |   2 +-
 LEGO1/lego/legoomni/include/hospital.h        |   2 +-
 LEGO1/lego/legoomni/include/isle.h            |   4 +-
 .../legoomni/include/legoanimationmanager.h   |   8 +-
 LEGO1/lego/legoomni/include/legocarbuild.h    |   2 +-
 LEGO1/lego/legoomni/include/legogamestate.h   |   6 +-
 LEGO1/lego/legoomni/include/legonamedplane.h  |  22 +-
 LEGO1/lego/legoomni/include/legorace.h        |  20 +-
 LEGO1/lego/legoomni/include/legostate.h       |   6 +-
 LEGO1/lego/legoomni/include/legoutils.h       |   8 +-
 LEGO1/lego/legoomni/include/pizza.h           |   2 +-
 LEGO1/lego/legoomni/include/pizzeria.h        |   2 +-
 LEGO1/lego/legoomni/include/police.h          |   2 +-
 LEGO1/lego/legoomni/include/towtrack.h        |   2 +-
 LEGO1/lego/legoomni/src/actors/act3ammo.cpp   |   2 +-
 LEGO1/lego/legoomni/src/actors/ambulance.cpp  |  48 +--
 LEGO1/lego/legoomni/src/actors/pizza.cpp      |  24 +-
 LEGO1/lego/legoomni/src/actors/pizzeria.cpp   |  10 +-
 LEGO1/lego/legoomni/src/actors/towtrack.cpp   |  48 +--
 .../lego/legoomni/src/build/legocarbuild.cpp  |  22 +-
 .../src/build/legocarbuildpresenter.cpp       |   6 +-
 .../src/common/legoanimationmanager.cpp       |  78 ++---
 .../legoomni/src/common/legogamestate.cpp     | 100 +++---
 LEGO1/lego/legoomni/src/common/legoutils.cpp  |  18 +-
 .../legoomni/src/entity/legonavcontroller.cpp |   1 +
 LEGO1/lego/legoomni/src/race/legorace.cpp     |   6 +-
 LEGO1/lego/legoomni/src/worlds/gasstation.cpp |  28 +-
 LEGO1/lego/legoomni/src/worlds/hospital.cpp   |  32 +-
 LEGO1/lego/legoomni/src/worlds/isle.cpp       |  94 +++---
 LEGO1/lego/legoomni/src/worlds/police.cpp     |  10 +-
 LEGO1/lego/sources/geom/legounkown100db7f4.h  |   8 +-
 LEGO1/lego/sources/misc/legostorage.h         | 290 +++++++++---------
 LEGO1/lego/sources/misc/legounknown.cpp       |   8 +-
 LEGO1/lego/sources/misc/legounknown.h         |   7 +-
 LEGO1/mxgeometry/mxgeometry3d.h               |   6 +-
 LEGO1/omni/include/mxdsaction.h               |   6 +-
 LEGO1/viewmanager/viewmanager.cpp             |   1 +
 39 files changed, 472 insertions(+), 473 deletions(-)

diff --git a/LEGO1/lego/legoomni/include/act3ammo.h b/LEGO1/lego/legoomni/include/act3ammo.h
index 28de0263..ee4e3dc1 100644
--- a/LEGO1/lego/legoomni/include/act3ammo.h
+++ b/LEGO1/lego/legoomni/include/act3ammo.h
@@ -82,7 +82,7 @@ public:
 
 	MxResult Remove();
 	MxResult Create(Act3* p_world, MxU32 p_isPizza, MxS32 p_index);
-	MxResult FUN_10053b40(Vector3& p_srcLoc, Vector3& p_srcDir, Vector3& p_srcUp);
+	MxResult FUN_10053b40(const Vector3& p_srcLoc, const Vector3& p_srcDir, const Vector3& p_srcUp);
 	MxResult FUN_10053cb0(LegoPathController* p_p, LegoPathBoundary* p_boundary, MxFloat p_unk0x19c);
 	MxResult FUN_10053d30(LegoPathController* p_p, MxFloat p_unk0x19c);
 
diff --git a/LEGO1/lego/legoomni/include/ambulance.h b/LEGO1/lego/legoomni/include/ambulance.h
index 09028188..7bb1fd3f 100644
--- a/LEGO1/lego/legoomni/include/ambulance.h
+++ b/LEGO1/lego/legoomni/include/ambulance.h
@@ -27,7 +27,7 @@ public:
 		return !strcmp(p_name, AmbulanceMissionState::ClassName()) || LegoState::IsA(p_name);
 	}
 
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	// FUNCTION: BETA10 0x10088770
 	MxS16 GetHighScore(MxU8 p_actorId)
diff --git a/LEGO1/lego/legoomni/include/gasstation.h b/LEGO1/lego/legoomni/include/gasstation.h
index d3ed67df..e5168c97 100644
--- a/LEGO1/lego/legoomni/include/gasstation.h
+++ b/LEGO1/lego/legoomni/include/gasstation.h
@@ -30,7 +30,7 @@ public:
 		return !strcmp(p_name, GasStationState::ClassName()) || LegoState::IsA(p_name);
 	}
 
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	// SYNTHETIC: LEGO1 0x10006290
 	// GasStationState::`scalar deleting destructor'
diff --git a/LEGO1/lego/legoomni/include/hospital.h b/LEGO1/lego/legoomni/include/hospital.h
index 41465550..ef16252c 100644
--- a/LEGO1/lego/legoomni/include/hospital.h
+++ b/LEGO1/lego/legoomni/include/hospital.h
@@ -38,7 +38,7 @@ public:
 		return !strcmp(p_name, HospitalState::ClassName()) || LegoState::IsA(p_name);
 	}
 
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	// SYNTHETIC: LEGO1 0x100764c0
 	// HospitalState::`scalar deleting destructor'
diff --git a/LEGO1/lego/legoomni/include/isle.h b/LEGO1/lego/legoomni/include/isle.h
index cb845914..2c6c8091 100644
--- a/LEGO1/lego/legoomni/include/isle.h
+++ b/LEGO1/lego/legoomni/include/isle.h
@@ -50,8 +50,8 @@ public:
 		return !strcmp(p_name, Act1State::ClassName()) || LegoState::IsA(p_name);
 	}
 
-	MxBool Reset() override;                       // vtable+0x18
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxBool Reset() override;                             // vtable+0x18
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	void PlayCptClickDialogue();
 	void StopCptClickDialogue();
diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h
index 5c7546e0..f216ca30 100644
--- a/LEGO1/lego/legoomni/include/legoanimationmanager.h
+++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h
@@ -70,8 +70,8 @@ public:
 		return !strcmp(p_name, AnimState::ClassName()) || LegoState::IsA(p_name);
 	}
 
-	MxBool Reset() override;                       // vtable+0x18
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxBool Reset() override;                             // vtable+0x18
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	void CopyToAnims(MxU32, AnimInfo* p_anims, MxU32& p_outExtraCharacterId);
 	void InitFromAnims(MxU32 p_animsLength, AnimInfo* p_anims, MxU32 p_extraCharacterId);
@@ -164,8 +164,8 @@ public:
 	void EnableCamAnims(MxBool p_enableCamAnims);
 	MxResult LoadWorldInfo(LegoOmni::World p_worldId);
 	MxBool FindVehicle(const char* p_name, MxU32& p_index);
-	MxResult ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info);
-	MxResult ReadModelInfo(LegoFile* p_file, ModelInfo* p_info);
+	MxResult ReadAnimInfo(LegoStorage* p_storage, AnimInfo* p_info);
+	MxResult ReadModelInfo(LegoStorage* p_storage, ModelInfo* p_info);
 	void FUN_10060480(const LegoChar* p_characterNames[], MxU32 p_numCharacterNames);
 	void FUN_100604d0(MxBool p_unk0x08);
 	void FUN_100604f0(MxS32 p_objectIds[], MxU32 p_numObjectIds);
diff --git a/LEGO1/lego/legoomni/include/legocarbuild.h b/LEGO1/lego/legoomni/include/legocarbuild.h
index 8afbee01..a28e29b9 100644
--- a/LEGO1/lego/legoomni/include/legocarbuild.h
+++ b/LEGO1/lego/legoomni/include/legocarbuild.h
@@ -42,7 +42,7 @@ public:
 		return !strcmp(p_name, m_className.GetData()) || LegoState::IsA(p_name);
 	}
 
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	// SYNTHETIC: LEGO1 0x100260a0
 	// LegoVehicleBuildState::`scalar deleting destructor'
diff --git a/LEGO1/lego/legoomni/include/legogamestate.h b/LEGO1/lego/legoomni/include/legogamestate.h
index 858c13e6..da9d9319 100644
--- a/LEGO1/lego/legoomni/include/legogamestate.h
+++ b/LEGO1/lego/legoomni/include/legogamestate.h
@@ -111,7 +111,7 @@ public:
 		Username(Username& p_other) { Set(p_other); }
 		void Set(Username& p_other) { memcpy(m_letters, p_other.m_letters, sizeof(m_letters)); }
 
-		MxResult Serialize(LegoFile* p_file);
+		MxResult Serialize(LegoStorage* p_storage);
 		Username& operator=(const Username& p_other);
 
 		MxS16 m_letters[7]; // 0x00
@@ -119,7 +119,7 @@ public:
 
 	// SIZE 0x2c
 	struct ScoreItem {
-		MxResult Serialize(LegoFile* p_file);
+		MxResult Serialize(LegoStorage* p_storage);
 
 		MxS16 m_totalScore;  // 0x00
 		MxU8 m_scores[5][5]; // 0x02
@@ -131,7 +131,7 @@ public:
 	struct History {
 		History();
 		void WriteScoreHistory();
-		MxResult Serialize(LegoFile* p_file);
+		MxResult Serialize(LegoStorage* p_storage);
 		ScoreItem* FUN_1003cc90(Username* p_player, MxU16 p_unk0x24, MxS32& p_unk0x2c);
 
 		// FUNCTION: BETA10 0x1002c2b0
diff --git a/LEGO1/lego/legoomni/include/legonamedplane.h b/LEGO1/lego/legoomni/include/legonamedplane.h
index df91828a..fd759e81 100644
--- a/LEGO1/lego/legoomni/include/legonamedplane.h
+++ b/LEGO1/lego/legoomni/include/legonamedplane.h
@@ -29,19 +29,19 @@ public:
 	void Reset() { m_name = ""; }
 
 	// FUNCTION: LEGO1 0x100344d0
-	MxResult Serialize(LegoFile* p_file)
+	MxResult Serialize(LegoStorage* p_storage)
 	{
-		if (p_file->IsWriteMode()) {
-			p_file->Write(MxString(m_name));
-			p_file->Write(m_position);
-			p_file->Write(m_direction);
-			p_file->Write(m_up);
+		if (p_storage->IsWriteMode()) {
+			p_storage->WriteMxString(m_name);
+			p_storage->WriteVector(m_position);
+			p_storage->WriteVector(m_direction);
+			p_storage->WriteVector(m_up);
 		}
-		else if (p_file->IsReadMode()) {
-			p_file->Read(m_name);
-			p_file->Read(m_position);
-			p_file->Read(m_direction);
-			p_file->Read(m_up);
+		else if (p_storage->IsReadMode()) {
+			p_storage->ReadMxString(m_name);
+			p_storage->ReadVector(m_position);
+			p_storage->ReadVector(m_direction);
+			p_storage->ReadVector(m_up);
 		}
 
 		return SUCCESS;
diff --git a/LEGO1/lego/legoomni/include/legorace.h b/LEGO1/lego/legoomni/include/legorace.h
index cee2e4b6..344136f3 100644
--- a/LEGO1/lego/legoomni/include/legorace.h
+++ b/LEGO1/lego/legoomni/include/legorace.h
@@ -39,17 +39,17 @@ public:
 		MxS16 GetHighScore() { return m_score; }
 
 		// FUNCTION: BETA10 0x100c96f0
-		MxResult Serialize(LegoFile* p_file)
+		MxResult Serialize(LegoStorage* p_storage)
 		{
-			if (p_file->IsReadMode()) {
-				p_file->Read(m_id);
-				p_file->Read(m_unk0x02);
-				p_file->Read(m_score);
+			if (p_storage->IsReadMode()) {
+				p_storage->ReadU8(m_id);
+				p_storage->ReadS16(m_unk0x02);
+				p_storage->ReadS16(m_score);
 			}
-			else if (p_file->IsWriteMode()) {
-				p_file->Write(m_id);
-				p_file->Write(m_unk0x02);
-				p_file->Write(m_score);
+			else if (p_storage->IsWriteMode()) {
+				p_storage->WriteU8(m_id);
+				p_storage->WriteS16(m_unk0x02);
+				p_storage->WriteS16(m_score);
 			}
 			else {
 				return FAILURE;
@@ -82,7 +82,7 @@ public:
 		return !strcmp(p_name, RaceState::ClassName()) || LegoState::IsA(p_name);
 	}
 
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	Entry* GetState(MxU8 p_id);
 
diff --git a/LEGO1/lego/legoomni/include/legostate.h b/LEGO1/lego/legoomni/include/legostate.h
index 940abe72..fa055e0d 100644
--- a/LEGO1/lego/legoomni/include/legostate.h
+++ b/LEGO1/lego/legoomni/include/legostate.h
@@ -76,10 +76,10 @@ public:
 
 	// FUNCTION: LEGO1 0x10005fb0
 	// FUNCTION: BETA10 0x10017af0
-	virtual MxResult Serialize(LegoFile* p_file)
+	virtual MxResult Serialize(LegoStorage* p_storage)
 	{
-		if (p_file->IsWriteMode()) {
-			p_file->Write(MxString(ClassName()));
+		if (p_storage->IsWriteMode()) {
+			p_storage->WriteMxString(ClassName());
 		}
 		return SUCCESS;
 	} // vtable+0x1c
diff --git a/LEGO1/lego/legoomni/include/legoutils.h b/LEGO1/lego/legoomni/include/legoutils.h
index ef816382..3780e700 100644
--- a/LEGO1/lego/legoomni/include/legoutils.h
+++ b/LEGO1/lego/legoomni/include/legoutils.h
@@ -31,11 +31,11 @@ enum Cursor {
 class BoundingSphere;
 class MxAtomId;
 class LegoEntity;
-class LegoFile;
 class LegoAnimPresenter;
 class LegoNamedTexture;
 class LegoPathActor;
 class LegoROI;
+class LegoStorage;
 class LegoTreeNode;
 
 extern MxAtomId* g_isleScript;
@@ -63,9 +63,9 @@ MxBool FUN_1003ef60();
 MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_worldAtom, MxS32 p_worldEntityId);
 MxS32 UpdateLightPosition(MxS32 p_increase);
 void SetLightPosition(MxS32 p_index);
-LegoNamedTexture* ReadNamedTexture(LegoFile* p_file);
-void WriteDefaultTexture(LegoFile* p_file, const char* p_name);
-void WriteNamedTexture(LegoFile* p_file, LegoNamedTexture* p_namedTexture);
+LegoNamedTexture* ReadNamedTexture(LegoStorage* p_storage);
+void WriteDefaultTexture(LegoStorage* p_storage, const char* p_name);
+void WriteNamedTexture(LegoStorage* p_storage, LegoNamedTexture* p_namedTexture);
 void FUN_1003f930(LegoNamedTexture* p_namedTexture);
 
 // FUNCTION: BETA10 0x100260a0
diff --git a/LEGO1/lego/legoomni/include/pizza.h b/LEGO1/lego/legoomni/include/pizza.h
index 855f2b59..89b19cb0 100644
--- a/LEGO1/lego/legoomni/include/pizza.h
+++ b/LEGO1/lego/legoomni/include/pizza.h
@@ -122,7 +122,7 @@ public:
 		return !strcmp(p_name, PizzaMissionState::ClassName()) || LegoState::IsA(p_name);
 	}
 
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	// FUNCTION: BETA10 0x100ef470
 	void SetUnknown0xb0(MxU32 p_unk0xb0) { m_unk0xb0 = p_unk0xb0; }
diff --git a/LEGO1/lego/legoomni/include/pizzeria.h b/LEGO1/lego/legoomni/include/pizzeria.h
index 395dc1ca..a959abb3 100644
--- a/LEGO1/lego/legoomni/include/pizzeria.h
+++ b/LEGO1/lego/legoomni/include/pizzeria.h
@@ -29,7 +29,7 @@ public:
 		return !strcmp(p_name, PizzeriaState::ClassName()) || LegoState::IsA(p_name);
 	}
 
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	// SYNTHETIC: LEGO1 0x10017ce0
 	// PizzeriaState::`scalar deleting destructor'
diff --git a/LEGO1/lego/legoomni/include/police.h b/LEGO1/lego/legoomni/include/police.h
index 5f67d546..e89ad3a7 100644
--- a/LEGO1/lego/legoomni/include/police.h
+++ b/LEGO1/lego/legoomni/include/police.h
@@ -33,7 +33,7 @@ public:
 		return !strcmp(p_name, PoliceState::ClassName()) || LegoState::IsA(p_name);
 	}
 
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	// SYNTHETIC: LEGO1 0x1005e920
 	// PoliceState::`scalar deleting destructor'
diff --git a/LEGO1/lego/legoomni/include/towtrack.h b/LEGO1/lego/legoomni/include/towtrack.h
index 4bf7d84a..7a5f50b4 100644
--- a/LEGO1/lego/legoomni/include/towtrack.h
+++ b/LEGO1/lego/legoomni/include/towtrack.h
@@ -28,7 +28,7 @@ public:
 		return !strcmp(p_name, TowTrackMissionState::ClassName()) || LegoState::IsA(p_name);
 	}
 
-	MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
+	MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
 
 	// FUNCTION: BETA10 0x10088890
 	MxS16 GetHighScore(MxU8 p_actorId)
diff --git a/LEGO1/lego/legoomni/src/actors/act3ammo.cpp b/LEGO1/lego/legoomni/src/actors/act3ammo.cpp
index 2eaae385..6eb4c70a 100644
--- a/LEGO1/lego/legoomni/src/actors/act3ammo.cpp
+++ b/LEGO1/lego/legoomni/src/actors/act3ammo.cpp
@@ -109,7 +109,7 @@ MxResult Act3Ammo::Create(Act3* p_world, MxU32 p_isPizza, MxS32 p_index)
 
 // FUNCTION: LEGO1 0x10053b40
 // FUNCTION: BETA10 0x1001db2a
-MxResult Act3Ammo::FUN_10053b40(Vector3& p_srcLoc, Vector3& p_srcDir, Vector3& p_srcUp)
+MxResult Act3Ammo::FUN_10053b40(const Vector3& p_srcLoc, const Vector3& p_srcDir, const Vector3& p_srcUp)
 {
 	assert(p_srcDir[1] != 0);
 
diff --git a/LEGO1/lego/legoomni/src/actors/ambulance.cpp b/LEGO1/lego/legoomni/src/actors/ambulance.cpp
index a3f438f4..ca2c0ddb 100644
--- a/LEGO1/lego/legoomni/src/actors/ambulance.cpp
+++ b/LEGO1/lego/legoomni/src/actors/ambulance.cpp
@@ -647,33 +647,33 @@ AmbulanceMissionState::AmbulanceMissionState()
 
 // FUNCTION: LEGO1 0x10037440
 // FUNCTION: BETA10 0x10024480
-MxResult AmbulanceMissionState::Serialize(LegoFile* p_file)
+MxResult AmbulanceMissionState::Serialize(LegoStorage* p_storage)
 {
-	LegoState::Serialize(p_file);
+	LegoState::Serialize(p_storage);
 
-	if (p_file->IsReadMode()) {
-		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);
+	if (p_storage->IsReadMode()) {
+		p_storage->ReadS16(m_peScore);
+		p_storage->ReadS16(m_maScore);
+		p_storage->ReadS16(m_paScore);
+		p_storage->ReadS16(m_niScore);
+		p_storage->ReadS16(m_laScore);
+		p_storage->ReadS16(m_peHighScore);
+		p_storage->ReadS16(m_maHighScore);
+		p_storage->ReadS16(m_paHighScore);
+		p_storage->ReadS16(m_niHighScore);
+		p_storage->ReadS16(m_laHighScore);
 	}
-	else if (p_file->IsWriteMode()) {
-		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);
+	else if (p_storage->IsWriteMode()) {
+		p_storage->WriteS16(m_peScore);
+		p_storage->WriteS16(m_maScore);
+		p_storage->WriteS16(m_paScore);
+		p_storage->WriteS16(m_niScore);
+		p_storage->WriteS16(m_laScore);
+		p_storage->WriteS16(m_peHighScore);
+		p_storage->WriteS16(m_maHighScore);
+		p_storage->WriteS16(m_paHighScore);
+		p_storage->WriteS16(m_niHighScore);
+		p_storage->WriteS16(m_laHighScore);
 	}
 
 	return SUCCESS;
diff --git a/LEGO1/lego/legoomni/src/actors/pizza.cpp b/LEGO1/lego/legoomni/src/actors/pizza.cpp
index a3a91218..98d711f2 100644
--- a/LEGO1/lego/legoomni/src/actors/pizza.cpp
+++ b/LEGO1/lego/legoomni/src/actors/pizza.cpp
@@ -606,24 +606,24 @@ PizzaMissionState::PizzaMissionState()
 
 // FUNCTION: LEGO1 0x100393c0
 // FUNCTION: BETA10 0x100eebf2
-MxResult PizzaMissionState::Serialize(LegoFile* p_file)
+MxResult PizzaMissionState::Serialize(LegoStorage* p_storage)
 {
-	LegoState::Serialize(p_file);
+	LegoState::Serialize(p_storage);
 
-	if (p_file->IsReadMode()) {
+	if (p_storage->IsReadMode()) {
 		for (MxS16 i = 0; i < 5; i++) {
-			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);
+			p_storage->ReadS16(m_missions[i].m_unk0x06);
+			p_storage->ReadS16(m_missions[i].m_unk0x14);
+			p_storage->ReadS16(m_missions[i].m_score);
+			p_storage->ReadS16(m_missions[i].m_hiScore);
 		}
 	}
-	else if (p_file->IsWriteMode()) {
+	else if (p_storage->IsWriteMode()) {
 		for (MxS16 i = 0; i < 5; i++) {
-			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);
+			p_storage->WriteS16(m_missions[i].m_unk0x06);
+			p_storage->WriteS16(m_missions[i].m_unk0x14);
+			p_storage->WriteS16(m_missions[i].m_score);
+			p_storage->WriteS16(m_missions[i].m_hiScore);
 		}
 	}
 
diff --git a/LEGO1/lego/legoomni/src/actors/pizzeria.cpp b/LEGO1/lego/legoomni/src/actors/pizzeria.cpp
index 54bf583b..d2d98956 100644
--- a/LEGO1/lego/legoomni/src/actors/pizzeria.cpp
+++ b/LEGO1/lego/legoomni/src/actors/pizzeria.cpp
@@ -118,18 +118,18 @@ MxU32 PizzeriaState::NextAction()
 
 // FUNCTION: LEGO1 0x10017da0
 // FUNCTION: BETA10 0x100efe33
-MxResult PizzeriaState::Serialize(LegoFile* p_file)
+MxResult PizzeriaState::Serialize(LegoStorage* p_storage)
 {
-	MxResult res = LegoState::Serialize(p_file);
+	MxResult res = LegoState::Serialize(p_storage);
 
-	if (p_file->IsReadMode()) {
+	if (p_storage->IsReadMode()) {
 		for (MxS16 i = 0; i < 5; i++) {
-			p_file->Read(m_unk0x08[i].m_nextIndex);
+			p_storage->ReadS16(m_unk0x08[i].m_nextIndex);
 		}
 	}
 	else {
 		for (MxS16 i = 0; i < 5; i++) {
-			p_file->Write(m_unk0x08[i].m_nextIndex);
+			p_storage->WriteS16(m_unk0x08[i].m_nextIndex);
 		}
 	}
 
diff --git a/LEGO1/lego/legoomni/src/actors/towtrack.cpp b/LEGO1/lego/legoomni/src/actors/towtrack.cpp
index 6baedc9b..878d4e90 100644
--- a/LEGO1/lego/legoomni/src/actors/towtrack.cpp
+++ b/LEGO1/lego/legoomni/src/actors/towtrack.cpp
@@ -610,33 +610,33 @@ TowTrackMissionState::TowTrackMissionState()
 
 // FUNCTION: LEGO1 0x1004dde0
 // FUNCTION: BETA10 0x100f8720
-MxResult TowTrackMissionState::Serialize(LegoFile* p_file)
+MxResult TowTrackMissionState::Serialize(LegoStorage* p_storage)
 {
-	LegoState::Serialize(p_file);
+	LegoState::Serialize(p_storage);
 
-	if (p_file->IsReadMode()) {
-		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);
+	if (p_storage->IsReadMode()) {
+		p_storage->ReadS16(m_peScore);
+		p_storage->ReadS16(m_maScore);
+		p_storage->ReadS16(m_paScore);
+		p_storage->ReadS16(m_niScore);
+		p_storage->ReadS16(m_laScore);
+		p_storage->ReadS16(m_peHighScore);
+		p_storage->ReadS16(m_maHighScore);
+		p_storage->ReadS16(m_paHighScore);
+		p_storage->ReadS16(m_niHighScore);
+		p_storage->ReadS16(m_laHighScore);
 	}
-	else if (p_file->IsWriteMode()) {
-		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);
+	else if (p_storage->IsWriteMode()) {
+		p_storage->WriteS16(m_peScore);
+		p_storage->WriteS16(m_maScore);
+		p_storage->WriteS16(m_paScore);
+		p_storage->WriteS16(m_niScore);
+		p_storage->WriteS16(m_laScore);
+		p_storage->WriteS16(m_peHighScore);
+		p_storage->WriteS16(m_maHighScore);
+		p_storage->WriteS16(m_paHighScore);
+		p_storage->WriteS16(m_niHighScore);
+		p_storage->WriteS16(m_laHighScore);
 	}
 
 	return SUCCESS;
diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp
index c5516b37..65a0dc69 100644
--- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp
+++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp
@@ -1705,24 +1705,24 @@ LegoVehicleBuildState::LegoVehicleBuildState(const char* p_classType)
 
 // FUNCTION: LEGO1 0x10026120
 // FUNCTION: BETA10 0x1006eef0
-MxResult LegoVehicleBuildState::Serialize(LegoFile* p_file)
+MxResult LegoVehicleBuildState::Serialize(LegoStorage* p_storage)
 {
-	LegoState::Serialize(p_file);
+	LegoState::Serialize(p_storage);
 
-	if (p_file->IsReadMode()) {
-		p_file->Read(m_unk0x4c);
-		p_file->Read(m_unk0x4d);
-		p_file->Read(m_unk0x4e);
+	if (p_storage->IsReadMode()) {
+		p_storage->ReadU8(m_unk0x4c);
+		p_storage->ReadU8(m_unk0x4d);
+		p_storage->ReadU8(m_unk0x4e);
 #ifndef BETA10
-		p_file->Read(m_placedPartCount);
+		p_storage->ReadU8(m_placedPartCount);
 #endif
 	}
 	else {
-		p_file->Write(m_unk0x4c);
-		p_file->Write(m_unk0x4d);
-		p_file->Write(m_unk0x4e);
+		p_storage->WriteU8(m_unk0x4c);
+		p_storage->WriteU8(m_unk0x4d);
+		p_storage->WriteU8(m_unk0x4e);
 #ifndef BETA10
-		p_file->Write(m_placedPartCount);
+		p_storage->WriteU8(m_placedPartCount);
 #endif
 	}
 
diff --git a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp
index 2489b1ec..91d3650c 100644
--- a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp
+++ b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp
@@ -260,9 +260,9 @@ void LegoCarBuildAnimPresenter::StreamingTickle()
 
 	Mx3DPointFloat dirVec;
 
-	Vector3 cameraPosition(camera->GetWorldPosition());
-	Vector3 upVec(camera->GetWorldUp());
-	Vector3 targetPosition(targetROI->GetWorldPosition());
+	const Vector3 cameraPosition(camera->GetWorldPosition());
+	const Vector3 upVec(camera->GetWorldUp());
+	const Vector3 targetPosition(targetROI->GetWorldPosition());
 
 	MxMatrix localTransform;
 
diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp
index b51d814b..51f9cea1 100644
--- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp
+++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp
@@ -621,7 +621,7 @@ MxResult LegoAnimationManager::LoadWorldInfo(LegoOmni::World p_worldId)
 
 		DeleteAnimations();
 
-		LegoFile file;
+		LegoFile storage;
 
 		if (p_worldId == LegoOmni::e_undefined) {
 			result = SUCCESS;
@@ -653,12 +653,12 @@ MxResult LegoAnimationManager::LoadWorldInfo(LegoOmni::World p_worldId)
 			}
 		}
 
-		if (file.Open(path, LegoFile::c_read) == FAILURE) {
+		if (storage.Open(path, LegoFile::c_read) == FAILURE) {
 			goto done;
 		}
 
 		MxU32 version;
-		if (file.Read(&version, sizeof(version)) == FAILURE) {
+		if (storage.Read(&version, sizeof(version)) == FAILURE) {
 			goto done;
 		}
 
@@ -667,7 +667,7 @@ MxResult LegoAnimationManager::LoadWorldInfo(LegoOmni::World p_worldId)
 			goto done;
 		}
 
-		if (file.Read(&m_animCount, sizeof(m_animCount)) == FAILURE) {
+		if (storage.Read(&m_animCount, sizeof(m_animCount)) == FAILURE) {
 			goto done;
 		}
 
@@ -675,7 +675,7 @@ MxResult LegoAnimationManager::LoadWorldInfo(LegoOmni::World p_worldId)
 		memset(m_anims, 0, m_animCount * sizeof(*m_anims));
 
 		for (j = 0; j < m_animCount; j++) {
-			if (ReadAnimInfo(&file, &m_anims[j]) == FAILURE) {
+			if (ReadAnimInfo(&storage, &m_anims[j]) == FAILURE) {
 				goto done;
 			}
 
@@ -754,49 +754,49 @@ MxBool LegoAnimationManager::FindVehicle(const char* p_name, MxU32& p_index)
 }
 
 // FUNCTION: LEGO1 0x10060180
-MxResult LegoAnimationManager::ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info)
+MxResult LegoAnimationManager::ReadAnimInfo(LegoStorage* p_storage, AnimInfo* p_info)
 {
 	MxResult result = FAILURE;
 	MxU8 length;
 	MxS32 i, j;
 
-	if (p_file->Read(&length, sizeof(length)) == FAILURE) {
+	if (p_storage->Read(&length, sizeof(length)) == FAILURE) {
 		goto done;
 	}
 
 	p_info->m_name = new char[length + 1];
-	if (p_file->Read(p_info->m_name, length) == FAILURE) {
+	if (p_storage->Read(p_info->m_name, length) == FAILURE) {
 		goto done;
 	}
 
 	p_info->m_name[length] = 0;
-	if (p_file->Read(&p_info->m_objectId, sizeof(p_info->m_objectId)) == FAILURE) {
+	if (p_storage->Read(&p_info->m_objectId, sizeof(p_info->m_objectId)) == FAILURE) {
 		goto done;
 	}
 
-	if (p_file->Read(&p_info->m_location, sizeof(p_info->m_location)) == FAILURE) {
+	if (p_storage->Read(&p_info->m_location, sizeof(p_info->m_location)) == FAILURE) {
 		goto done;
 	}
-	if (p_file->Read(&p_info->m_unk0x0a, sizeof(p_info->m_unk0x0a)) == FAILURE) {
+	if (p_storage->Read(&p_info->m_unk0x0a, sizeof(p_info->m_unk0x0a)) == FAILURE) {
 		goto done;
 	}
-	if (p_file->Read(&p_info->m_unk0x0b, sizeof(p_info->m_unk0x0b)) == FAILURE) {
+	if (p_storage->Read(&p_info->m_unk0x0b, sizeof(p_info->m_unk0x0b)) == FAILURE) {
 		goto done;
 	}
-	if (p_file->Read(&p_info->m_unk0x0c, sizeof(p_info->m_unk0x0c)) == FAILURE) {
+	if (p_storage->Read(&p_info->m_unk0x0c, sizeof(p_info->m_unk0x0c)) == FAILURE) {
 		goto done;
 	}
-	if (p_file->Read(&p_info->m_unk0x0d, sizeof(p_info->m_unk0x0d)) == FAILURE) {
+	if (p_storage->Read(&p_info->m_unk0x0d, sizeof(p_info->m_unk0x0d)) == FAILURE) {
 		goto done;
 	}
 
 	for (i = 0; i < (MxS32) sizeOfArray(p_info->m_unk0x10); i++) {
-		if (p_file->Read(&p_info->m_unk0x10[i], sizeof(*p_info->m_unk0x10)) != SUCCESS) {
+		if (p_storage->Read(&p_info->m_unk0x10[i], sizeof(*p_info->m_unk0x10)) != SUCCESS) {
 			goto done;
 		}
 	}
 
-	if (p_file->Read(&p_info->m_modelCount, sizeof(p_info->m_modelCount)) == FAILURE) {
+	if (p_storage->Read(&p_info->m_modelCount, sizeof(p_info->m_modelCount)) == FAILURE) {
 		goto done;
 	}
 
@@ -804,7 +804,7 @@ MxResult LegoAnimationManager::ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info)
 	memset(p_info->m_models, 0, p_info->m_modelCount * sizeof(*p_info->m_models));
 
 	for (j = 0; j < p_info->m_modelCount; j++) {
-		if (ReadModelInfo(p_file, &p_info->m_models[j]) == FAILURE) {
+		if (ReadModelInfo(p_storage, &p_info->m_models[j]) == FAILURE) {
 			goto done;
 		}
 	}
@@ -816,35 +816,35 @@ done:
 }
 
 // FUNCTION: LEGO1 0x10060310
-MxResult LegoAnimationManager::ReadModelInfo(LegoFile* p_file, ModelInfo* p_info)
+MxResult LegoAnimationManager::ReadModelInfo(LegoStorage* p_storage, ModelInfo* p_info)
 {
 	MxResult result = FAILURE;
 	MxU8 length;
 
-	if (p_file->Read(&length, 1) == FAILURE) {
+	if (p_storage->Read(&length, 1) == FAILURE) {
 		goto done;
 	}
 
 	p_info->m_name = new char[length + 1];
-	if (p_file->Read(p_info->m_name, length) == FAILURE) {
+	if (p_storage->Read(p_info->m_name, length) == FAILURE) {
 		goto done;
 	}
 
 	p_info->m_name[length] = 0;
-	if (p_file->Read(&p_info->m_unk0x04, sizeof(p_info->m_unk0x04)) == FAILURE) {
+	if (p_storage->Read(&p_info->m_unk0x04, sizeof(p_info->m_unk0x04)) == FAILURE) {
 		goto done;
 	}
 
-	if (p_file->Read(p_info->m_location, sizeof(p_info->m_location)) != SUCCESS) {
+	if (p_storage->Read(p_info->m_location, sizeof(p_info->m_location)) != SUCCESS) {
 		goto done;
 	}
-	if (p_file->Read(p_info->m_direction, sizeof(p_info->m_direction)) != SUCCESS) {
+	if (p_storage->Read(p_info->m_direction, sizeof(p_info->m_direction)) != SUCCESS) {
 		goto done;
 	}
-	if (p_file->Read(p_info->m_up, sizeof(p_info->m_up)) != SUCCESS) {
+	if (p_storage->Read(p_info->m_up, sizeof(p_info->m_up)) != SUCCESS) {
 		goto done;
 	}
-	if (p_file->Read(&p_info->m_unk0x2c, sizeof(p_info->m_unk0x2c)) == FAILURE) {
+	if (p_storage->Read(&p_info->m_unk0x2c, sizeof(p_info->m_unk0x2c)) == FAILURE) {
 		goto done;
 	}
 
@@ -2935,21 +2935,21 @@ void AnimState::InitFromAnims(MxU32 p_animsLength, AnimInfo* p_anims, MxU32 p_ex
 
 // FUNCTION: LEGO1 0x100652d0
 // FUNCTION: BETA10 0x10046621
-MxResult AnimState::Serialize(LegoFile* p_file)
+MxResult AnimState::Serialize(LegoStorage* p_storage)
 {
-	MxResult result = LegoState::Serialize(p_file);
+	MxResult result = LegoState::Serialize(p_storage);
 
 	if (result == SUCCESS) {
-		if (p_file->IsReadMode()) {
+		if (p_storage->IsReadMode()) {
 			MxS32 i;
 
-			p_file->Read(m_extraCharacterId);
+			p_storage->ReadU32(m_extraCharacterId);
 
 			if (m_unk0x10) {
 				delete[] m_unk0x10;
 			}
 
-			p_file->Read(m_unk0x0c);
+			p_storage->ReadU32(m_unk0x0c);
 
 #ifndef BETA10
 			if (m_unk0x0c != 0) {
@@ -2963,11 +2963,11 @@ MxResult AnimState::Serialize(LegoFile* p_file)
 #endif
 
 			for (i = 0; i < m_unk0x0c; i++) {
-				p_file->Read(m_unk0x10[i]);
+				p_storage->ReadU16(m_unk0x10[i]);
 			}
 
 			// Note that here we read first and then free memory in contrast to above
-			p_file->Read(m_locationsFlagsLength);
+			p_storage->ReadU32(m_locationsFlagsLength);
 
 #ifndef BETA10
 			if (m_locationsFlags) {
@@ -2985,22 +2985,22 @@ MxResult AnimState::Serialize(LegoFile* p_file)
 #endif
 
 			for (i = 0; i < m_locationsFlagsLength; i++) {
-				p_file->Read(m_locationsFlags[i]);
+				p_storage->ReadU8(m_locationsFlags[i]);
 			}
 		}
-		else if (p_file->IsWriteMode()) {
+		else if (p_storage->IsWriteMode()) {
 			MxS32 i;
 
-			p_file->Write(m_extraCharacterId);
-			p_file->Write(m_unk0x0c);
+			p_storage->WriteU32(m_extraCharacterId);
+			p_storage->WriteU32(m_unk0x0c);
 
 			for (i = 0; i < m_unk0x0c; i++) {
-				p_file->Write(m_unk0x10[i]);
+				p_storage->WriteU16(m_unk0x10[i]);
 			}
 
-			p_file->Write(m_locationsFlagsLength);
+			p_storage->WriteU32(m_locationsFlagsLength);
 			for (i = 0; i < m_locationsFlagsLength; i++) {
-				p_file->Write(m_locationsFlags[i]);
+				p_storage->WriteU8(m_locationsFlags[i]);
 			}
 		}
 	}
diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp
index 6585d2f4..80745b95 100644
--- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp
+++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp
@@ -253,10 +253,10 @@ MxResult LegoGameState::Save(MxULong p_slot)
 		goto done;
 	}
 
-	storage.Write(0x1000c);
-	storage.Write(m_unk0x24);
-	storage.Write((MxU16) m_currentAct);
-	storage.Write(m_actorId);
+	storage.WriteS32(0x1000c);
+	storage.WriteS16(m_unk0x24);
+	storage.WriteU16(m_currentAct);
+	storage.WriteU8(m_actorId);
 
 	for (i = 0; i < sizeOfArray(g_colorSaveData); i++) {
 		if (WriteVariable(&storage, variableTable, g_colorSaveData[i].m_targetName) == FAILURE) {
@@ -282,7 +282,7 @@ MxResult LegoGameState::Save(MxULong p_slot)
 		}
 	}
 
-	storage.Write(count);
+	storage.WriteS16(count);
 
 	for (j = 0; j < m_stateCount; j++) {
 		if (m_stateArray[j]->IsSerializable()) {
@@ -291,7 +291,7 @@ MxResult LegoGameState::Save(MxULong p_slot)
 	}
 
 	area = m_unk0x42c;
-	storage.Write((MxU16) area);
+	storage.WriteU16(area);
 	SerializeScoreHistory(2);
 	m_isDirty = FALSE;
 
@@ -342,18 +342,18 @@ MxResult LegoGameState::Load(MxULong p_slot)
 	MxS16 count, actArea;
 	const char* lightPosition;
 
-	storage.Read(version);
+	storage.ReadS32(version);
 
 	if (version != 0x1000c) {
 		OmniError("Saved game version mismatch", 0);
 		goto done;
 	}
 
-	storage.Read(m_unk0x24);
-	storage.Read(actArea);
+	storage.ReadS16(m_unk0x24);
+	storage.ReadS16(actArea);
 
 	SetCurrentAct((Act) actArea);
-	storage.Read(m_actorId);
+	storage.ReadU8(m_actorId);
 	if (m_actorId) {
 		SetActor(m_actorId);
 	}
@@ -386,11 +386,11 @@ MxResult LegoGameState::Load(MxULong p_slot)
 	}
 
 	char stateName[80];
-	storage.Read(count);
+	storage.ReadS16(count);
 
 	if (count) {
 		for (MxS16 i = 0; i < count; i++) {
-			storage.Read(stateName);
+			storage.ReadString(stateName);
 
 			LegoState* state = GetState(stateName);
 			if (!state) {
@@ -405,7 +405,7 @@ MxResult LegoGameState::Load(MxULong p_slot)
 		}
 	}
 
-	storage.Read(actArea);
+	storage.ReadS16(actArea);
 
 	if (m_currentAct == e_act1) {
 		m_unk0x42c = e_undefined;
@@ -528,22 +528,22 @@ void LegoGameState::GetFileSavePath(MxString* p_outPath, MxU8 p_slotn)
 // FUNCTION: LEGO1 0x1003a2e0
 void LegoGameState::SerializePlayersInfo(MxS16 p_flags)
 {
-	LegoFile fileStorage;
+	LegoFile storage;
 	MxString playersGSI = MxString(m_savePath);
 
 	playersGSI += "\\";
 	playersGSI += g_playersGSI;
 
-	if (fileStorage.Open(playersGSI.GetData(), p_flags) == SUCCESS) {
-		if (fileStorage.IsReadMode()) {
-			fileStorage.Read(m_playerCount);
+	if (storage.Open(playersGSI.GetData(), p_flags) == SUCCESS) {
+		if (storage.IsReadMode()) {
+			storage.ReadS16(m_playerCount);
 		}
-		else if (fileStorage.IsWriteMode()) {
-			fileStorage.Write(m_playerCount);
+		else if (storage.IsWriteMode()) {
+			storage.WriteS16(m_playerCount);
 		}
 
 		for (MxS16 i = 0; i < m_playerCount; i++) {
-			m_players[i].Serialize(&fileStorage);
+			m_players[i].Serialize(&storage);
 		}
 	}
 }
@@ -1152,16 +1152,16 @@ LegoGameState::Username::Username()
 
 // FUNCTION: LEGO1 0x1003c690
 // FUNCTION: BETA10 0x10086c57
-MxResult LegoGameState::Username::Serialize(LegoFile* p_file)
+MxResult LegoGameState::Username::Serialize(LegoStorage* p_storage)
 {
-	if (p_file->IsReadMode()) {
+	if (p_storage->IsReadMode()) {
 		for (MxS16 i = 0; i < (MxS16) sizeOfArray(m_letters); i++) {
-			p_file->Read(m_letters[i]);
+			p_storage->ReadS16(m_letters[i]);
 		}
 	}
-	else if (p_file->IsWriteMode()) {
+	else if (p_storage->IsWriteMode()) {
 		for (MxS16 i = 0; i < (MxS16) sizeOfArray(m_letters); i++) {
-			p_file->Write(m_letters[i]);
+			p_storage->WriteS16(m_letters[i]);
 		}
 	}
 
@@ -1178,31 +1178,31 @@ LegoGameState::Username& LegoGameState::Username::operator=(const Username& p_ot
 
 // FUNCTION: LEGO1 0x1003c740
 // FUNCTION: BETA10 0x10086d39
-MxResult LegoGameState::ScoreItem::Serialize(LegoFile* p_file)
+MxResult LegoGameState::ScoreItem::Serialize(LegoStorage* p_storage)
 {
-	if (p_file->IsReadMode()) {
-		p_file->Read(m_totalScore);
+	if (p_storage->IsReadMode()) {
+		p_storage->ReadS16(m_totalScore);
 
 		for (MxS32 i = 0; i < 5; i++) {
 			for (MxS32 j = 0; j < 5; j++) {
-				p_file->Read(m_scores[i][j]);
+				p_storage->ReadU8(m_scores[i][j]);
 			}
 		}
 
-		m_name.Serialize(p_file);
-		p_file->Read(m_unk0x2a);
+		m_name.Serialize(p_storage);
+		p_storage->ReadS16(m_unk0x2a);
 	}
-	else if (p_file->IsWriteMode()) {
-		p_file->Write(m_totalScore);
+	else if (p_storage->IsWriteMode()) {
+		p_storage->WriteS16(m_totalScore);
 
 		for (MxS32 i = 0; i < 5; i++) {
 			for (MxS32 j = 0; j < 5; j++) {
-				p_file->Write(m_scores[i][j]);
+				p_storage->WriteU8(m_scores[i][j]);
 			}
 		}
 
-		m_name.Serialize(p_file);
-		p_file->Write(m_unk0x2a);
+		m_name.Serialize(p_storage);
+		p_storage->WriteS16(m_unk0x2a);
 	}
 
 	return SUCCESS;
@@ -1324,25 +1324,25 @@ LegoGameState::ScoreItem* LegoGameState::History::FUN_1003cc90(
 
 // FUNCTION: LEGO1 0x1003ccf0
 // FUNCTION: BETA10 0x100873e7
-MxResult LegoGameState::History::Serialize(LegoFile* p_file)
+MxResult LegoGameState::History::Serialize(LegoStorage* p_storage)
 {
-	if (p_file->IsReadMode()) {
-		p_file->Read(m_unk0x372);
-		p_file->Read(m_count);
+	if (p_storage->IsReadMode()) {
+		p_storage->ReadS16(m_unk0x372);
+		p_storage->ReadS16(m_count);
 
 		for (MxS16 i = 0; i < m_count; i++) {
 			MxS16 j;
-			p_file->Read(j);
-			m_scores[i].Serialize(p_file);
+			p_storage->ReadS16(j);
+			m_scores[i].Serialize(p_storage);
 		}
 	}
-	else if (p_file->IsWriteMode()) {
-		p_file->Write(m_unk0x372);
-		p_file->Write(m_count);
+	else if (p_storage->IsWriteMode()) {
+		p_storage->WriteS16(m_unk0x372);
+		p_storage->WriteS16(m_count);
 
 		for (MxS16 i = 0; i < m_count; i++) {
-			p_file->Write(i);
-			m_scores[i].Serialize(p_file);
+			p_storage->WriteS16(i);
+			m_scores[i].Serialize(p_storage);
 		}
 	}
 
@@ -1352,7 +1352,7 @@ MxResult LegoGameState::History::Serialize(LegoFile* p_file)
 // FUNCTION: LEGO1 0x1003cdd0
 void LegoGameState::SerializeScoreHistory(MxS16 p_flags)
 {
-	LegoFile stream;
+	LegoFile storage;
 	MxString savePath(m_savePath);
 	savePath += "\\";
 	savePath += g_historyGSI;
@@ -1361,8 +1361,8 @@ void LegoGameState::SerializeScoreHistory(MxS16 p_flags)
 		m_history.WriteScoreHistory();
 	}
 
-	if (stream.Open(savePath.GetData(), p_flags) == SUCCESS) {
-		m_history.Serialize(&stream);
+	if (storage.Open(savePath.GetData(), p_flags) == SUCCESS) {
+		m_history.Serialize(&storage);
 	}
 }
 
diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp
index d6c7f84c..d141e32c 100644
--- a/LEGO1/lego/legoomni/src/common/legoutils.cpp
+++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp
@@ -662,17 +662,17 @@ void SetLightPosition(MxS32 p_index)
 }
 
 // FUNCTION: LEGO1 0x1003f3b0
-LegoNamedTexture* ReadNamedTexture(LegoFile* p_file)
+LegoNamedTexture* ReadNamedTexture(LegoStorage* p_storage)
 {
 	LegoTexture* texture = NULL;
 	LegoNamedTexture* namedTexture = NULL;
 	MxString string;
 
-	p_file->Read(string);
+	p_storage->ReadMxString(string);
 
 	texture = new LegoTexture();
 	if (texture != NULL) {
-		if (texture->Read(p_file, 0) != SUCCESS) {
+		if (texture->Read(p_storage, 0) != SUCCESS) {
 			delete texture;
 			return namedTexture;
 		}
@@ -687,7 +687,7 @@ LegoNamedTexture* ReadNamedTexture(LegoFile* p_file)
 }
 
 // FUNCTION: LEGO1 0x1003f540
-void WriteDefaultTexture(LegoFile* p_file, const char* p_name)
+void WriteDefaultTexture(LegoStorage* p_storage, const char* p_name)
 {
 	MxString name(p_name);
 	LegoTextureInfo* textureInfo = TextureContainer()->Get(p_name);
@@ -743,8 +743,8 @@ void WriteDefaultTexture(LegoFile* p_file, const char* p_name)
 					LegoTexture texture;
 					texture.SetImage(image);
 
-					p_file->Write(MxString(name));
-					texture.Write(p_file);
+					p_storage->WriteMxString(name);
+					texture.Write(p_storage);
 				}
 				else {
 					delete image;
@@ -758,10 +758,10 @@ void WriteDefaultTexture(LegoFile* p_file, const char* p_name)
 }
 
 // FUNCTION: LEGO1 0x1003f8a0
-void WriteNamedTexture(LegoFile* p_file, LegoNamedTexture* p_namedTexture)
+void WriteNamedTexture(LegoStorage* p_storage, LegoNamedTexture* p_namedTexture)
 {
-	p_file->Write(MxString(*p_namedTexture->GetName()));
-	p_namedTexture->GetTexture()->Write(p_file);
+	p_storage->WriteMxString(*p_namedTexture->GetName());
+	p_namedTexture->GetTexture()->Write(p_storage);
 }
 
 // FUNCTION: LEGO1 0x1003f930
diff --git a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp
index 58b27935..24ea5af5 100644
--- a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp
+++ b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp
@@ -316,6 +316,7 @@ float LegoNavController::CalculateNewVel(float p_targetVel, float p_currentVel,
 }
 
 // FUNCTION: LEGO1 0x10055080
+// FUNCTION: BETA10 0x1009b26b
 MxBool LegoNavController::CalculateNewPosDir(
 	const Vector3& p_curPos,
 	const Vector3& p_curDir,
diff --git a/LEGO1/lego/legoomni/src/race/legorace.cpp b/LEGO1/lego/legoomni/src/race/legorace.cpp
index de895ad5..a2c0555d 100644
--- a/LEGO1/lego/legoomni/src/race/legorace.cpp
+++ b/LEGO1/lego/legoomni/src/race/legorace.cpp
@@ -135,12 +135,12 @@ RaceState::RaceState()
 
 // FUNCTION: LEGO1 0x10016140
 // FUNCTION: BETA10 0x100c7d9f
-MxResult RaceState::Serialize(LegoFile* p_file)
+MxResult RaceState::Serialize(LegoStorage* p_storage)
 {
-	LegoState::Serialize(p_file);
+	LegoState::Serialize(p_storage);
 
 	for (MxS16 i = 0; i < 5; i++) {
-		m_state[i].Serialize(p_file);
+		m_state[i].Serialize(p_storage);
 	}
 
 	return SUCCESS;
diff --git a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp
index 34981d64..f9972f07 100644
--- a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp
+++ b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp
@@ -508,23 +508,23 @@ GasStationState::GasStationState()
 
 // FUNCTION: LEGO1 0x10006300
 // FUNCTION: BETA10 0x10029754
-MxResult GasStationState::Serialize(LegoFile* p_file)
+MxResult GasStationState::Serialize(LegoStorage* p_storage)
 {
-	LegoState::Serialize(p_file);
+	LegoState::Serialize(p_storage);
 
-	if (p_file->IsWriteMode()) {
-		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);
+	if (p_storage->IsWriteMode()) {
+		p_storage->WriteS16(m_pepperAction);
+		p_storage->WriteS16(m_mamaAction);
+		p_storage->WriteS16(m_papaAction);
+		p_storage->WriteS16(m_nickAction);
+		p_storage->WriteS16(m_lauraAction);
 	}
-	else if (p_file->IsReadMode()) {
-		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);
+	else if (p_storage->IsReadMode()) {
+		p_storage->ReadS16(m_pepperAction);
+		p_storage->ReadS16(m_mamaAction);
+		p_storage->ReadS16(m_papaAction);
+		p_storage->ReadS16(m_nickAction);
+		p_storage->ReadS16(m_lauraAction);
 	}
 
 	return SUCCESS;
diff --git a/LEGO1/lego/legoomni/src/worlds/hospital.cpp b/LEGO1/lego/legoomni/src/worlds/hospital.cpp
index 2f5f915e..303d7b90 100644
--- a/LEGO1/lego/legoomni/src/worlds/hospital.cpp
+++ b/LEGO1/lego/legoomni/src/worlds/hospital.cpp
@@ -695,25 +695,25 @@ HospitalState::HospitalState()
 
 // FUNCTION: LEGO1 0x10076530
 // FUNCTION: BETA10 0x1002db26
-MxResult HospitalState::Serialize(LegoFile* p_file)
+MxResult HospitalState::Serialize(LegoStorage* p_storage)
 {
-	LegoState::Serialize(p_file);
+	LegoState::Serialize(p_storage);
 
-	if (p_file->IsWriteMode()) {
-		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);
+	if (p_storage->IsWriteMode()) {
+		p_storage->WriteS16(m_unk0x0c);
+		p_storage->WriteS16(m_unk0x0e);
+		p_storage->WriteS16(m_unk0x10);
+		p_storage->WriteS16(m_unk0x12);
+		p_storage->WriteS16(m_unk0x14);
+		p_storage->WriteS16(m_unk0x16);
 	}
-	else if (p_file->IsReadMode()) {
-		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);
+	else if (p_storage->IsReadMode()) {
+		p_storage->ReadS16(m_unk0x0c);
+		p_storage->ReadS16(m_unk0x0e);
+		p_storage->ReadS16(m_unk0x10);
+		p_storage->ReadS16(m_unk0x12);
+		p_storage->ReadS16(m_unk0x14);
+		p_storage->ReadS16(m_unk0x16);
 	}
 
 	return SUCCESS;
diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp
index 6c3b0859..d904c12e 100644
--- a/LEGO1/lego/legoomni/src/worlds/isle.cpp
+++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp
@@ -1324,150 +1324,140 @@ Act1State::Act1State()
 
 // FUNCTION: LEGO1 0x10033ac0
 // FUNCTION: BETA10 0x1003524f
-MxResult Act1State::Serialize(LegoFile* p_file)
+MxResult Act1State::Serialize(LegoStorage* p_storage)
 {
-	LegoState::Serialize(p_file);
+	LegoState::Serialize(p_storage);
 
-	m_motocyclePlane.Serialize(p_file);
-	m_bikePlane.Serialize(p_file);
-	m_skateboardPlane.Serialize(p_file);
-	m_helicopterPlane.Serialize(p_file);
-	m_jetskiPlane.Serialize(p_file);
-	m_dunebuggyPlane.Serialize(p_file);
-	m_racecarPlane.Serialize(p_file);
+	m_motocyclePlane.Serialize(p_storage);
+	m_bikePlane.Serialize(p_storage);
+	m_skateboardPlane.Serialize(p_storage);
+	m_helicopterPlane.Serialize(p_storage);
+	m_jetskiPlane.Serialize(p_storage);
+	m_dunebuggyPlane.Serialize(p_storage);
+	m_racecarPlane.Serialize(p_storage);
 
-	if (p_file->IsWriteMode()) {
-		// TODO: Seems to match better when using strcmp directly instead of IsPresent
+	if (p_storage->IsWriteMode()) {
 		if (strcmp(m_helicopterPlane.m_name.GetData(), "")) {
 			if (!m_helicopterWindshield) {
-				WriteDefaultTexture(p_file, "chwind.gif");
+				WriteDefaultTexture(p_storage, "chwind.gif");
 			}
 			else {
-				WriteNamedTexture(p_file, m_helicopterWindshield);
+				WriteNamedTexture(p_storage, m_helicopterWindshield);
 			}
 
 			if (!m_helicopterJetLeft) {
-				WriteDefaultTexture(p_file, "chjetl.gif");
+				WriteDefaultTexture(p_storage, "chjetl.gif");
 			}
 			else {
-				WriteNamedTexture(p_file, m_helicopterJetLeft);
+				WriteNamedTexture(p_storage, m_helicopterJetLeft);
 			}
 
 			if (!m_helicopterJetRight) {
-				WriteDefaultTexture(p_file, "chjetr.gif");
+				WriteDefaultTexture(p_storage, "chjetr.gif");
 			}
 			else {
-				WriteNamedTexture(p_file, m_helicopterJetRight);
+				WriteNamedTexture(p_storage, m_helicopterJetRight);
 			}
 		}
 
 		if (strcmp(m_jetskiPlane.m_name.GetData(), "")) {
 			if (!m_jetskiFront) {
-				WriteDefaultTexture(p_file, "jsfrnt.gif");
+				WriteDefaultTexture(p_storage, "jsfrnt.gif");
 			}
 			else {
-				WriteNamedTexture(p_file, m_jetskiFront);
+				WriteNamedTexture(p_storage, m_jetskiFront);
 			}
 
 			if (!m_jetskiWindshield) {
-				WriteDefaultTexture(p_file, "jswnsh.gif");
+				WriteDefaultTexture(p_storage, "jswnsh.gif");
 			}
 			else {
-				WriteNamedTexture(p_file, m_jetskiWindshield);
+				WriteNamedTexture(p_storage, m_jetskiWindshield);
 			}
 		}
 
 		if (strcmp(m_dunebuggyPlane.m_name.GetData(), "")) {
 			if (!m_dunebuggyFront) {
-				WriteDefaultTexture(p_file, "dbfrfn.gif");
+				WriteDefaultTexture(p_storage, "dbfrfn.gif");
 			}
 			else {
-				WriteNamedTexture(p_file, m_dunebuggyFront);
+				WriteNamedTexture(p_storage, m_dunebuggyFront);
 			}
 		}
 
 		if (strcmp(m_racecarPlane.m_name.GetData(), "")) {
 			if (!m_racecarFront) {
-				WriteDefaultTexture(p_file, "rcfrnt.gif");
+				WriteDefaultTexture(p_storage, "rcfrnt.gif");
 			}
 			else {
-				WriteNamedTexture(p_file, m_racecarFront);
+				WriteNamedTexture(p_storage, m_racecarFront);
 			}
 
 			if (!m_racecarBack) {
-				WriteDefaultTexture(p_file, "rcback.gif");
+				WriteDefaultTexture(p_storage, "rcback.gif");
 			}
 			else {
-				WriteNamedTexture(p_file, m_racecarBack);
+				WriteNamedTexture(p_storage, m_racecarBack);
 			}
 
 			if (!m_racecarTail) {
-				WriteDefaultTexture(p_file, "rctail.gif");
+				WriteDefaultTexture(p_storage, "rctail.gif");
 			}
 			else {
-				WriteNamedTexture(p_file, m_racecarTail);
+				WriteNamedTexture(p_storage, m_racecarTail);
 			}
 		}
 
-		p_file->Write(m_cptClickDialogue.m_nextIndex);
-		p_file->Write(m_unk0x022);
+		p_storage->WriteS16(m_cptClickDialogue.m_nextIndex);
+		p_storage->WriteU8(m_unk0x022);
 	}
-	else if (p_file->IsReadMode()) {
+	else if (p_storage->IsReadMode()) {
 		if (strcmp(m_helicopterPlane.m_name.GetData(), "")) {
-			m_helicopterWindshield = ReadNamedTexture(p_file);
-			if (m_helicopterWindshield == NULL) {
+			if ((m_helicopterWindshield = ReadNamedTexture(p_storage)) == NULL) {
 				return FAILURE;
 			}
 
-			m_helicopterJetLeft = ReadNamedTexture(p_file);
-			if (m_helicopterJetLeft == NULL) {
+			if ((m_helicopterJetLeft = ReadNamedTexture(p_storage)) == NULL) {
 				return FAILURE;
 			}
 
-			m_helicopterJetRight = ReadNamedTexture(p_file);
-			if (m_helicopterJetRight == NULL) {
+			if ((m_helicopterJetRight = ReadNamedTexture(p_storage)) == NULL) {
 				return FAILURE;
 			}
 		}
 
 		if (strcmp(m_jetskiPlane.m_name.GetData(), "")) {
-			m_jetskiFront = ReadNamedTexture(p_file);
-			if (m_jetskiFront == NULL) {
+			if ((m_jetskiFront = ReadNamedTexture(p_storage)) == NULL) {
 				return FAILURE;
 			}
 
-			m_jetskiWindshield = ReadNamedTexture(p_file);
-			if (m_jetskiWindshield == NULL) {
+			if ((m_jetskiWindshield = ReadNamedTexture(p_storage)) == NULL) {
 				return FAILURE;
 			}
 		}
 
 		if (strcmp(m_dunebuggyPlane.m_name.GetData(), "")) {
-			m_dunebuggyFront = ReadNamedTexture(p_file);
-			if (m_dunebuggyFront == NULL) {
+			if ((m_dunebuggyFront = ReadNamedTexture(p_storage)) == NULL) {
 				return FAILURE;
 			}
 		}
 
 		if (strcmp(m_racecarPlane.m_name.GetData(), "")) {
-			m_racecarFront = ReadNamedTexture(p_file);
-			if (m_racecarFront == NULL) {
+			if ((m_racecarFront = ReadNamedTexture(p_storage)) == NULL) {
 				return FAILURE;
 			}
 
-			m_racecarBack = ReadNamedTexture(p_file);
-			if (m_racecarBack == NULL) {
+			if ((m_racecarBack = ReadNamedTexture(p_storage)) == NULL) {
 				return FAILURE;
 			}
 
-			m_racecarTail = ReadNamedTexture(p_file);
-			if (m_racecarTail == NULL) {
+			if ((m_racecarTail = ReadNamedTexture(p_storage)) == NULL) {
 				return FAILURE;
 			}
 		}
 
-		p_file->Read(m_cptClickDialogue.m_nextIndex);
-		p_file->Read(m_unk0x022);
+		p_storage->ReadS16(m_cptClickDialogue.m_nextIndex);
+		p_storage->ReadU8(m_unk0x022);
 	}
 
 	return SUCCESS;
diff --git a/LEGO1/lego/legoomni/src/worlds/police.cpp b/LEGO1/lego/legoomni/src/worlds/police.cpp
index 32e90395..7b3533d8 100644
--- a/LEGO1/lego/legoomni/src/worlds/police.cpp
+++ b/LEGO1/lego/legoomni/src/worlds/police.cpp
@@ -209,15 +209,15 @@ PoliceState::PoliceState()
 
 // FUNCTION: LEGO1 0x1005e990
 // FUNCTION: BETA10 0x100f08b0
-MxResult PoliceState::Serialize(LegoFile* p_file)
+MxResult PoliceState::Serialize(LegoStorage* p_storage)
 {
-	LegoState::Serialize(p_file);
+	LegoState::Serialize(p_storage);
 
-	if (p_file->IsReadMode()) {
-		p_file->Read((MxS32&) m_policeScript);
+	if (p_storage->IsReadMode()) {
+		p_storage->ReadS32((MxS32&) m_policeScript);
 	}
 	else {
-		p_file->Write((MxS32) m_policeScript);
+		p_storage->WriteS32(m_policeScript);
 	}
 
 	return SUCCESS;
diff --git a/LEGO1/lego/sources/geom/legounkown100db7f4.h b/LEGO1/lego/sources/geom/legounkown100db7f4.h
index 1c9c266d..d54e3730 100644
--- a/LEGO1/lego/sources/geom/legounkown100db7f4.h
+++ b/LEGO1/lego/sources/geom/legounkown100db7f4.h
@@ -22,12 +22,12 @@ public:
 
 	// FUNCTION: LEGO1 0x1002ddc0
 	// FUNCTION: BETA10 0x100372a0
-	LegoResult FUN_1002ddc0(LegoWEEdge& p_f, Vector3& p_point)
+	LegoResult FUN_1002ddc0(LegoWEEdge& p_f, Vector3& p_point) const
 	{
 		if (p_f.IsEqual(m_faceA)) {
-			p_point[0] = -m_unk0x28.index_operator(0);
-			p_point[1] = -m_unk0x28.index_operator(1);
-			p_point[2] = -m_unk0x28.index_operator(2);
+			p_point[0] = -m_unk0x28[0];
+			p_point[1] = -m_unk0x28[1];
+			p_point[2] = -m_unk0x28[2];
 		}
 		else {
 			// clang-format off
diff --git a/LEGO1/lego/sources/misc/legostorage.h b/LEGO1/lego/sources/misc/legostorage.h
index f46c7a1f..fb65c4c7 100644
--- a/LEGO1/lego/sources/misc/legostorage.h
+++ b/LEGO1/lego/sources/misc/legostorage.h
@@ -33,6 +33,151 @@ public:
 	// FUNCTION: LEGO1 0x10045af0
 	virtual LegoBool IsReadMode() { return m_mode == c_read; } // vtable+0x18
 
+	// FUNCTION: LEGO1 0x10006030
+	// FUNCTION: BETA10 0x10017bb0
+	LegoStorage* WriteMxString(MxString p_data)
+	{
+		WriteString(p_data.GetData());
+		return this;
+	}
+
+	// FUNCTION: BETA10 0x10017c80
+	LegoStorage* WriteString(const char* p_data)
+	{
+		LegoS16 length = strlen(p_data);
+		WriteS16(length);
+		Write(p_data, length);
+		return this;
+	}
+
+	// FUNCTION: BETA10 0x1004b0d0
+	LegoStorage* WriteU8(LegoU8 p_data)
+	{
+		Write(&p_data, sizeof(p_data));
+		return this;
+	}
+
+	// FUNCTION: BETA10 0x10017ce0
+	LegoStorage* WriteS16(LegoS16 p_data)
+	{
+		Write(&p_data, sizeof(p_data));
+		return this;
+	}
+
+	// FUNCTION: BETA10 0x1004b110
+	LegoStorage* WriteU16(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* WriteS32(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* WriteU32(MxU32 p_data)
+	{
+		Write(&p_data, sizeof(p_data));
+		return this;
+	}
+
+	LegoStorage* WriteFloat(LegoFloat p_data)
+	{
+		Write(&p_data, sizeof(p_data));
+		return this;
+	}
+
+	// FUNCTION: LEGO1 0x100343d0
+	LegoStorage* WriteVector(Mx3DPointFloat p_data)
+	{
+		WriteFloat(p_data[0]);
+		WriteFloat(p_data[1]);
+		WriteFloat(p_data[2]);
+		return this;
+	}
+
+	// FUNCTION: LEGO1 0x10034470
+	LegoStorage* ReadMxString(MxString& p_data)
+	{
+		LegoS16 length;
+		ReadS16(length);
+
+		char* text = new char[length + 1];
+		Read(text, length);
+
+		text[length] = '\0';
+		p_data = text;
+		delete[] text;
+		return this;
+	}
+
+	LegoStorage* ReadString(char* p_data)
+	{
+		LegoS16 length;
+		ReadS16(length);
+		Read(p_data, length);
+		p_data[length] = '\0';
+		return this;
+	}
+
+	// FUNCTION: BETA10 0x1004b190
+	LegoStorage* ReadU8(LegoU8& p_data)
+	{
+		Read(&p_data, sizeof(p_data));
+		return this;
+	}
+
+	// FUNCTION: BETA10 0x10024680
+	LegoStorage* ReadS16(LegoS16& p_data)
+	{
+		Read(&p_data, sizeof(p_data));
+		return this;
+	}
+
+	// FUNCTION: BETA10 0x1004b1d0
+	LegoStorage* ReadU16(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* ReadS32(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* ReadU32(MxU32& p_data)
+	{
+		Read(&p_data, sizeof(p_data));
+		return this;
+	}
+
+	LegoStorage* ReadFloat(LegoFloat& p_data)
+	{
+		Read(&p_data, sizeof(p_data));
+		return this;
+	}
+
+	// FUNCTION: LEGO1 0x10034430
+	LegoStorage* ReadVector(Mx3DPointFloat& p_data)
+	{
+		ReadFloat(p_data[0]);
+		ReadFloat(p_data[1]);
+		ReadFloat(p_data[2]);
+		return this;
+	}
+
 	// SYNTHETIC: LEGO1 0x10045b00
 	// LegoStorage::`scalar deleting destructor'
 
@@ -86,151 +231,6 @@ public:
 	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* Write(Mx3DPointFloat p_vec)
-	{
-		Write(p_vec[0]);
-		Write(p_vec[1]);
-		Write(p_vec[2]);
-		return this;
-	}
-
-	LegoStorage* Read(char* p_data)
-	{
-		LegoS16 length;
-		Read(length);
-		Read(p_data, length);
-		p_data[length] = '\0';
-		return this;
-	}
-
-	// FUNCTION: LEGO1 0x10034470
-	LegoStorage* Read(MxString& p_data)
-	{
-		LegoS16 length;
-		Read(length);
-
-		char* text = new char[length + 1];
-		Read(text, length);
-
-		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: BETA10 0x10024680
-	LegoStorage* Read(LegoS16& p_data)
-	{
-		Read(&p_data, sizeof(p_data));
-		return this;
-	}
-
-	// FUNCTION: BETA10 0x1004b1d0
-	LegoStorage* Read(LegoU16& p_data)
-	{
-		Read(&p_data, sizeof(p_data));
-		return this;
-	}
-
-	// TODO: Type might be different (LegoS32). MxS32 is incompatible with LegoS32.
-	// FUNCTION: BETA10 0x10088580
-	LegoStorage* Read(MxS32& p_data)
-	{
-		Read(&p_data, sizeof(p_data));
-		return this;
-	}
-
-	// TODO: Type might be different (LegoU32). MxU32 is incompatible with LegoU32.
-	// FUNCTION: BETA10 0x1004b210
-	LegoStorage* Read(MxU32& p_data)
-	{
-		Read(&p_data, sizeof(p_data));
-		return this;
-	}
-
-	LegoStorage* Read(LegoFloat& p_data)
-	{
-		Read(&p_data, sizeof(p_data));
-		return this;
-	}
-
-	// FUNCTION: LEGO1 0x10034430
-	LegoStorage* Read(Mx3DPointFloat& p_vec)
-	{
-		Read(p_vec[0]);
-		Read(p_vec[1]);
-		Read(p_vec[2]);
-		return this;
-	}
-
 	// SYNTHETIC: LEGO1 0x10099230
 	// LegoFile::`scalar deleting destructor'
 
diff --git a/LEGO1/lego/sources/misc/legounknown.cpp b/LEGO1/lego/sources/misc/legounknown.cpp
index d1af890d..db3f056c 100644
--- a/LEGO1/lego/sources/misc/legounknown.cpp
+++ b/LEGO1/lego/sources/misc/legounknown.cpp
@@ -18,7 +18,13 @@ LegoUnknown::~LegoUnknown()
 }
 
 // FUNCTION: LEGO1 0x1009a140
-void LegoUnknown::FUN_1009a140(const Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4)
+// FUNCTION: BETA10 0x10182c2f
+void LegoUnknown::FUN_1009a140(
+	const Vector3& p_point1,
+	const Vector3& p_point2,
+	const Vector3& p_point3,
+	const Vector3& p_point4
+)
 {
 	m_unk0x00[0] = p_point1;
 	m_unk0x00[1] = p_point2;
diff --git a/LEGO1/lego/sources/misc/legounknown.h b/LEGO1/lego/sources/misc/legounknown.h
index 5659feb7..e129952c 100644
--- a/LEGO1/lego/sources/misc/legounknown.h
+++ b/LEGO1/lego/sources/misc/legounknown.h
@@ -12,7 +12,12 @@ public:
 	LegoUnknown();
 	~LegoUnknown();
 
-	void FUN_1009a140(const Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4);
+	void FUN_1009a140(
+		const Vector3& p_point1,
+		const Vector3& p_point2,
+		const Vector3& p_point3,
+		const Vector3& p_point4
+	);
 	LegoResult FUN_1009a1e0(float p_f1, MxMatrix& p_mat, Vector3& p_v, LegoU32 p_und);
 
 private:
diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h
index 578d31b2..0a6ec12e 100644
--- a/LEGO1/mxgeometry/mxgeometry3d.h
+++ b/LEGO1/mxgeometry/mxgeometry3d.h
@@ -38,12 +38,8 @@ public:
 	// FUNCTION: BETA10 0x10013460
 	float& operator[](int idx) { return m_data[idx]; }
 
-	// According to the PDB, BETA10 will not link this one if it is never used
-	// const float& operator[](int idx) const { return m_data[idx]; }
-
-	// only used by LegoUnknown100db7f4::FUN_1002ddc0() for some unknown reason
 	// FUNCTION: BETA10 0x100373c0
-	float& index_operator(int idx) { return m_data[idx]; }
+	const float& operator[](int idx) const { return m_data[idx]; }
 
 	// SYNTHETIC: LEGO1 0x10010c00
 	// ??4Mx3DPointFloat@@QAEAAV0@ABV0@@Z
diff --git a/LEGO1/omni/include/mxdsaction.h b/LEGO1/omni/include/mxdsaction.h
index 807700c5..c003496e 100644
--- a/LEGO1/omni/include/mxdsaction.h
+++ b/LEGO1/omni/include/mxdsaction.h
@@ -87,13 +87,13 @@ public:
 	void SetLoopCount(MxS32 p_loopCount) { m_loopCount = p_loopCount; }
 
 	// FUNCTION: BETA10 0x1003db50
-	Vector3& GetLocation() { return m_location; }
+	const Vector3& GetLocation() { return m_location; }
 
 	// FUNCTION: BETA10 0x1003db80
-	Vector3& GetDirection() { return m_direction; }
+	const Vector3& GetDirection() { return m_direction; }
 
 	// FUNCTION: BETA10 0x1003dbb0
-	Vector3& GetUp() { return m_up; }
+	const Vector3& GetUp() { return m_up; }
 
 	// FUNCTION: BETA10 0x100153b0
 	void SetLocation(const Vector3& p_location) { m_location = p_location; }
diff --git a/LEGO1/viewmanager/viewmanager.cpp b/LEGO1/viewmanager/viewmanager.cpp
index 8f92f6f2..9c6b8434 100644
--- a/LEGO1/viewmanager/viewmanager.cpp
+++ b/LEGO1/viewmanager/viewmanager.cpp
@@ -471,6 +471,7 @@ void ViewManager::SetPOVSource(const OrientableROI* point_of_view)
 }
 
 // FUNCTION: LEGO1 0x100a6dc0
+// FUNCTION: BETA10 0x101739b8
 float ViewManager::ProjectedSize(const BoundingSphere& p_bounding_sphere)
 {
 	// The algorithm projects the radius of bounding sphere onto the perpendicular