diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp
index 22a73179..5af4071a 100644
--- a/src/control/AutoPilot.cpp
+++ b/src/control/AutoPilot.cpp
@@ -50,41 +50,41 @@ void CAutoPilot::RemoveOnePathNode()
 #ifdef COMPATIBLE_SAVES
 void CAutoPilot::Save(uint8*& buf)
 {
-	WriteSaveBuf<int32>(buf, m_nCurrentRouteNode);
-	WriteSaveBuf<int32>(buf, m_nNextRouteNode);
-	WriteSaveBuf<int32>(buf, m_nPrevRouteNode);
-	WriteSaveBuf<int32>(buf, m_nTimeEnteredCurve);
-	WriteSaveBuf<int32>(buf, m_nTimeToSpendOnCurrentCurve);
-	WriteSaveBuf<uint32>(buf, m_nCurrentPathNodeInfo);
-	WriteSaveBuf<uint32>(buf, m_nNextPathNodeInfo);
-	WriteSaveBuf<uint32>(buf, m_nPreviousPathNodeInfo);
-	WriteSaveBuf<uint32>(buf, m_nAntiReverseTimer);
-	WriteSaveBuf<uint32>(buf, m_nTimeToStartMission);
-	WriteSaveBuf<int8>(buf, m_nPreviousDirection);
-	WriteSaveBuf<int8>(buf, m_nCurrentDirection);
-	WriteSaveBuf<int8>(buf, m_nNextDirection);
-	WriteSaveBuf<int8>(buf, m_nCurrentLane);
-	WriteSaveBuf<int8>(buf, m_nNextLane);
-	WriteSaveBuf<uint8>(buf, m_nDrivingStyle);
-	WriteSaveBuf<uint8>(buf, m_nCarMission);
-	WriteSaveBuf<uint8>(buf, m_nTempAction);
-	WriteSaveBuf<uint32>(buf, m_nTimeTempAction);
-	WriteSaveBuf<float>(buf, m_fMaxTrafficSpeed);
-	WriteSaveBuf<uint8>(buf, m_nCruiseSpeed);
+	WriteSaveBuf(buf, m_nCurrentRouteNode);
+	WriteSaveBuf(buf, m_nNextRouteNode);
+	WriteSaveBuf(buf, m_nPrevRouteNode);
+	WriteSaveBuf(buf, m_nTimeEnteredCurve);
+	WriteSaveBuf(buf, m_nTimeToSpendOnCurrentCurve);
+	WriteSaveBuf(buf, m_nCurrentPathNodeInfo);
+	WriteSaveBuf(buf, m_nNextPathNodeInfo);
+	WriteSaveBuf(buf, m_nPreviousPathNodeInfo);
+	WriteSaveBuf(buf, m_nAntiReverseTimer);
+	WriteSaveBuf(buf, m_nTimeToStartMission);
+	WriteSaveBuf(buf, m_nPreviousDirection);
+	WriteSaveBuf(buf, m_nCurrentDirection);
+	WriteSaveBuf(buf, m_nNextDirection);
+	WriteSaveBuf(buf, m_nCurrentLane);
+	WriteSaveBuf(buf, m_nNextLane);
+	WriteSaveBuf(buf, m_nDrivingStyle);
+	WriteSaveBuf(buf, m_nCarMission);
+	WriteSaveBuf(buf, m_nTempAction);
+	WriteSaveBuf(buf, m_nTimeTempAction);
+	WriteSaveBuf(buf, m_fMaxTrafficSpeed);
+	WriteSaveBuf(buf, m_nCruiseSpeed);
 	uint8 flags = 0;
 	if (m_bSlowedDownBecauseOfCars) flags |= BIT(0);
 	if (m_bSlowedDownBecauseOfPeds) flags |= BIT(1);
 	if (m_bStayInCurrentLevel) flags |= BIT(2);
 	if (m_bStayInFastLane) flags |= BIT(3);
 	if (m_bIgnorePathfinding) flags |= BIT(4);
-	WriteSaveBuf<uint8>(buf, flags);
-	SkipSaveBuf(buf, 2);
-	WriteSaveBuf<float>(buf, m_vecDestinationCoors.x);
-	WriteSaveBuf<float>(buf, m_vecDestinationCoors.y);
-	WriteSaveBuf<float>(buf, m_vecDestinationCoors.z);
-	SkipSaveBuf(buf, 32);
-	WriteSaveBuf<int16>(buf, m_nPathFindNodesCount);
-	SkipSaveBuf(buf, 6);
+	WriteSaveBuf(buf, flags);
+	ZeroSaveBuf(buf, 2);
+	WriteSaveBuf(buf, m_vecDestinationCoors.x);
+	WriteSaveBuf(buf, m_vecDestinationCoors.y);
+	WriteSaveBuf(buf, m_vecDestinationCoors.z);
+	ZeroSaveBuf(buf, 32);
+	WriteSaveBuf(buf, m_nPathFindNodesCount);
+	ZeroSaveBuf(buf, 6);
 }
 
 void CAutoPilot::Load(uint8*& buf)
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index 3410c881..91971ae7 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -26,13 +26,6 @@
 #include "World.h"
 #include "SaveBuf.h"
 
-#define CRUSHER_GARAGE_X1 (1135.5f)
-#define CRUSHER_GARAGE_Y1 (57.0f)
-#define CRUSHER_GARAGE_Z1 (-1.0f)
-#define CRUSHER_GARAGE_X2 (1149.5f)
-#define CRUSHER_GARAGE_Y2 (63.7f)
-#define CRUSHER_GARAGE_Z2 (3.5f)
-
 #define ROTATED_DOOR_OPEN_SPEED (0.015f)
 #define ROTATED_DOOR_CLOSE_SPEED (0.02f)
 #define DEFAULT_DOOR_OPEN_SPEED (0.035f)
@@ -1883,11 +1876,12 @@ void CStoredCar::StoreCar(CVehicle* pVehicle)
 	m_nRadioStation = pVehicle->m_nRadioStation;
 	m_nVariationA = pVehicle->m_aExtras[0];
 	m_nVariationB = pVehicle->m_aExtras[1];
-	m_bBulletproof = pVehicle->bBulletProof;
-	m_bFireproof = pVehicle->bFireProof;
-	m_bExplosionproof = pVehicle->bExplosionProof;
-	m_bCollisionproof = pVehicle->bCollisionProof;
-	m_bMeleeproof = pVehicle->bMeleeProof;
+	m_nFlags = 0;
+	if (pVehicle->bBulletProof) m_nFlags |= FLAG_BULLETPROOF;
+	if (pVehicle->bFireProof) m_nFlags |= FLAG_FIREPROOF;
+	if (pVehicle->bExplosionProof) m_nFlags |= FLAG_EXPLOSIONPROOF;
+	if (pVehicle->bCollisionProof) m_nFlags |= FLAG_COLLISIONPROOF;
+	if (pVehicle->bMeleeProof) m_nFlags |= FLAG_MELEEPROOF;
 	if (pVehicle->IsCar())
 		m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType;
 }
@@ -1936,11 +1930,11 @@ CVehicle* CStoredCar::RestoreCar()
 	}
 	pVehicle->bHasBeenOwnedByPlayer = true;
 	pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
-	pVehicle->bBulletProof = m_bBulletproof;
-	pVehicle->bFireProof = m_bFireproof;
-	pVehicle->bExplosionProof = m_bExplosionproof;
-	pVehicle->bCollisionProof = m_bCollisionproof;
-	pVehicle->bMeleeProof = m_bMeleeproof;
+	if (m_nFlags & FLAG_BULLETPROOF) pVehicle->bBulletProof = true;
+	if (m_nFlags & FLAG_FIREPROOF) pVehicle->bFireProof = true;
+	if (m_nFlags & FLAG_EXPLOSIONPROOF) pVehicle->bExplosionProof = true;
+	if (m_nFlags & FLAG_COLLISIONPROOF) pVehicle->bCollisionProof = true;
+	if (m_nFlags & FLAG_MELEEPROOF) pVehicle->bMeleeProof = true;
 	return pVehicle;
 }
 
@@ -2327,8 +2321,47 @@ void CGarages::Save(uint8 * buf, uint32 * size)
 		WriteSaveBuf(buf, aCarsInSafeHouse2[i]);
 		WriteSaveBuf(buf, aCarsInSafeHouse3[i]);
 	}
-	for (int i = 0; i < NUM_GARAGES; i++)
+	for (int i = 0; i < NUM_GARAGES; i++) {
+#ifdef COMPATIBLE_SAVES
+		WriteSaveBuf(buf, aGarages[i].m_eGarageType);
+		WriteSaveBuf(buf, aGarages[i].m_eGarageState);
+		WriteSaveBuf(buf, aGarages[i].field_2);
+		WriteSaveBuf(buf, aGarages[i].m_bClosingWithoutTargetCar);
+		WriteSaveBuf(buf, aGarages[i].m_bDeactivated);
+		WriteSaveBuf(buf, aGarages[i].m_bResprayHappened);
+		ZeroSaveBuf(buf, 2);
+		WriteSaveBuf(buf, aGarages[i].m_nTargetModelIndex);
+		ZeroSaveBuf(buf, 4 + 4);
+		WriteSaveBuf(buf, aGarages[i].m_bDoor1PoolIndex);
+		WriteSaveBuf(buf, aGarages[i].m_bDoor2PoolIndex);
+		WriteSaveBuf(buf, aGarages[i].m_bDoor1IsDummy);
+		WriteSaveBuf(buf, aGarages[i].m_bDoor2IsDummy);
+		WriteSaveBuf(buf, aGarages[i].m_bRecreateDoorOnNextRefresh);
+		WriteSaveBuf(buf, aGarages[i].m_bRotatedDoor);
+		WriteSaveBuf(buf, aGarages[i].m_bCameraFollowsPlayer);
+		ZeroSaveBuf(buf, 1);
+		WriteSaveBuf(buf, aGarages[i].m_fX1);
+		WriteSaveBuf(buf, aGarages[i].m_fX2);
+		WriteSaveBuf(buf, aGarages[i].m_fY1);
+		WriteSaveBuf(buf, aGarages[i].m_fY2);
+		WriteSaveBuf(buf, aGarages[i].m_fZ1);
+		WriteSaveBuf(buf, aGarages[i].m_fZ2);
+		WriteSaveBuf(buf, aGarages[i].m_fDoorPos);
+		WriteSaveBuf(buf, aGarages[i].m_fDoorHeight);
+		WriteSaveBuf(buf, aGarages[i].m_fDoor1X);
+		WriteSaveBuf(buf, aGarages[i].m_fDoor1Y);
+		WriteSaveBuf(buf, aGarages[i].m_fDoor2X);
+		WriteSaveBuf(buf, aGarages[i].m_fDoor2Y);
+		WriteSaveBuf(buf, aGarages[i].m_fDoor1Z);
+		WriteSaveBuf(buf, aGarages[i].m_fDoor2Z);
+		WriteSaveBuf(buf, aGarages[i].m_nTimeToStartAction);
+		WriteSaveBuf(buf, aGarages[i].m_bCollectedCarsState);
+		ZeroSaveBuf(buf, 3 + 4 + 4);
+		ZeroSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
+#else
 		WriteSaveBuf(buf, aGarages[i]);
+#endif
+	}
 #ifdef FIX_GARAGE_SIZE
 	VALIDATESAVEBUF(*size);
 #endif
@@ -2339,11 +2372,7 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
 	m_nModelIndex = other.m_nModelIndex;
 	m_vecPos = other.m_vecPos;
 	m_vecAngle = other.m_vecAngle;
-	m_bBulletproof = other.m_bBulletproof;
-	m_bFireproof = other.m_bFireproof;
-	m_bExplosionproof = other.m_bExplosionproof;
-	m_bCollisionproof = other.m_bCollisionproof;
-	m_bMeleeproof = other.m_bMeleeproof;
+	m_nFlags = other.m_nFlags;
 	m_nPrimaryColor = other.m_nPrimaryColor;
 	m_nSecondaryColor = other.m_nSecondaryColor;
 	m_nRadioStation = other.m_nRadioStation;
@@ -2357,7 +2386,7 @@ void CGarages::Load(uint8* buf, uint32 size)
 {
 #ifdef FIX_GARAGE_SIZE
 	INITSAVEBUF
-	assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
+	assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)));
 #else
 	assert(size == 5484);
 #endif
@@ -2380,7 +2409,45 @@ void CGarages::Load(uint8* buf, uint32 size)
 		ReadSaveBuf(&aCarsInSafeHouse3[i], buf);
 	}
 	for (int i = 0; i < NUM_GARAGES; i++) {
+#ifdef COMPATIBLE_SAVES
+		ReadSaveBuf(&aGarages[i].m_eGarageType, buf);
+		ReadSaveBuf(&aGarages[i].m_eGarageState, buf);
+		ReadSaveBuf(&aGarages[i].field_2, buf);
+		ReadSaveBuf(&aGarages[i].m_bClosingWithoutTargetCar, buf);
+		ReadSaveBuf(&aGarages[i].m_bDeactivated, buf);
+		ReadSaveBuf(&aGarages[i].m_bResprayHappened, buf);
+		SkipSaveBuf(buf, 2);
+		ReadSaveBuf(&aGarages[i].m_nTargetModelIndex, buf);
+		SkipSaveBuf(buf, 4 + 4);
+		ReadSaveBuf(&aGarages[i].m_bDoor1PoolIndex, buf);
+		ReadSaveBuf(&aGarages[i].m_bDoor2PoolIndex, buf);
+		ReadSaveBuf(&aGarages[i].m_bDoor1IsDummy, buf);
+		ReadSaveBuf(&aGarages[i].m_bDoor2IsDummy, buf);
+		ReadSaveBuf(&aGarages[i].m_bRecreateDoorOnNextRefresh, buf);
+		ReadSaveBuf(&aGarages[i].m_bRotatedDoor, buf);
+		ReadSaveBuf(&aGarages[i].m_bCameraFollowsPlayer, buf);
+		SkipSaveBuf(buf, 1);
+		ReadSaveBuf(&aGarages[i].m_fX1, buf);
+		ReadSaveBuf(&aGarages[i].m_fX2, buf);
+		ReadSaveBuf(&aGarages[i].m_fY1, buf);
+		ReadSaveBuf(&aGarages[i].m_fY2, buf);
+		ReadSaveBuf(&aGarages[i].m_fZ1, buf);
+		ReadSaveBuf(&aGarages[i].m_fZ2, buf);
+		ReadSaveBuf(&aGarages[i].m_fDoorPos, buf);
+		ReadSaveBuf(&aGarages[i].m_fDoorHeight, buf);
+		ReadSaveBuf(&aGarages[i].m_fDoor1X, buf);
+		ReadSaveBuf(&aGarages[i].m_fDoor1Y, buf);
+		ReadSaveBuf(&aGarages[i].m_fDoor2X, buf);
+		ReadSaveBuf(&aGarages[i].m_fDoor2Y, buf);
+		ReadSaveBuf(&aGarages[i].m_fDoor1Z, buf);
+		ReadSaveBuf(&aGarages[i].m_fDoor2Z, buf);
+		ReadSaveBuf(&aGarages[i].m_nTimeToStartAction, buf);
+		ReadSaveBuf(&aGarages[i].m_bCollectedCarsState, buf);
+		SkipSaveBuf(buf, 3 + 4 + 4);
+		SkipSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
+#else
 		ReadSaveBuf(&aGarages[i], buf);
+#endif
 		aGarages[i].m_pDoor1 = nil;
 		aGarages[i].m_pDoor2 = nil;
 		aGarages[i].m_pTarget = nil;
diff --git a/src/control/Garages.h b/src/control/Garages.h
index a7dfa462..8a9fd1b6 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -51,14 +51,17 @@ enum
 
 class CStoredCar
 {
+	enum {
+		FLAG_BULLETPROOF = 0x1,
+		FLAG_FIREPROOF = 0x2,
+		FLAG_EXPLOSIONPROOF = 0x4,
+		FLAG_COLLISIONPROOF = 0x8,
+		FLAG_MELEEPROOF = 0x10,
+	};
 	int32 m_nModelIndex;
 	CVector m_vecPos;
 	CVector m_vecAngle;
-	int32 m_bBulletproof : 1;
-	int32 m_bFireproof : 1;
-	int32 m_bExplosionproof : 1;
-	int32 m_bCollisionproof : 1;
-	int32 m_bMeleeproof : 1;
+	int32 m_nFlags;
 	int8 m_nPrimaryColor;
 	int8 m_nSecondaryColor;
 	int8 m_nRadioStation;
@@ -78,6 +81,13 @@ VALIDATE_SIZE(CStoredCar, 0x28);
 
 #define SWITCH_GARAGE_DISTANCE_CLOSE 40.0f
 
+#define CRUSHER_GARAGE_X1 (1135.5f)
+#define CRUSHER_GARAGE_Y1 (57.0f)
+#define CRUSHER_GARAGE_Z1 (-1.0f)
+#define CRUSHER_GARAGE_X2 (1149.5f)
+#define CRUSHER_GARAGE_Y2 (63.7f)
+#define CRUSHER_GARAGE_Z2 (3.5f)
+
 class CGarage
 {
 public:
@@ -87,7 +97,7 @@ public:
 	bool m_bClosingWithoutTargetCar;
 	bool m_bDeactivated;
 	bool m_bResprayHappened;
-	int m_nTargetModelIndex;
+	int32 m_nTargetModelIndex;
 	CEntity *m_pDoor1;
 	CEntity *m_pDoor2;
 	uint8 m_bDoor1PoolIndex;
diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp
index f9cb1421..7632cfa3 100644
--- a/src/control/Phones.cpp
+++ b/src/control/Phones.cpp
@@ -18,6 +18,12 @@
 #include "Replay.h"
 #endif
 
+#ifdef COMPATIBLE_SAVES
+#define PHONEINFO_SAVE_SIZE 0xA30
+#else
+#define PHONEINFO_SAVE_SIZE sizeof(CPhoneInfo)
+#endif
+
 CPhoneInfo gPhoneInfo;
 
 bool CPhoneInfo::bDisplayingPhoneMessage;  // is phone picked up
@@ -209,6 +215,22 @@ CPhoneInfo::IsMessageBeingDisplayed(int phoneId)
 	return pPhoneDisplayingMessages == &m_aPhones[phoneId];
 }
 
+#ifdef COMPATIBLE_SAVES
+static inline void
+LoadPhone(CPhone &phone, uint8 *&buf)
+{
+	ReadSaveBuf(&phone.m_vecPos, buf);
+	SkipSaveBuf(buf, 6 * 4);
+	ReadSaveBuf<uint32>(&phone.m_repeatedMessagePickupStart, buf);
+	uint32 tmp;
+	ReadSaveBuf(&tmp, buf);
+	phone.m_pEntity = (CEntity*)(uintptr)tmp;
+	ReadSaveBuf<PhoneState>(&phone.m_nState, buf);
+	ReadSaveBuf<bool>(&phone.m_visibleToCam, buf);
+	SkipSaveBuf(buf, 3);
+}
+#endif
+
 void
 CPhoneInfo::Load(uint8 *buf, uint32 size)
 {
@@ -226,7 +248,12 @@ INITSAVEBUF
 	// We can do it without touching saves. We'll only load script phones, others are already loaded in Initialise
 	for (int i = 0; i < 50; i++) {
 		CPhone phoneToLoad;
+#ifdef COMPATIBLE_SAVES
+		phoneToLoad.m_apMessages[0]=phoneToLoad.m_apMessages[1]=phoneToLoad.m_apMessages[2]=phoneToLoad.m_apMessages[3]=phoneToLoad.m_apMessages[4]=phoneToLoad.m_apMessages[5] = nil;
+		LoadPhone(phoneToLoad, buf);
+#else
 		ReadSaveBuf(&phoneToLoad, buf);
+#endif
 
 		if (ignoreOtherPhones)
 			continue;
@@ -252,7 +279,11 @@ INITSAVEBUF
 	m_nScriptPhonesMax = scriptPhonesMax;
 
 	for (int i = 0; i < NUMPHONES; i++) {
+#ifdef COMPATIBLE_SAVES
+		LoadPhone(m_aPhones[i], buf);
+#else
 		ReadSaveBuf(&m_aPhones[i], buf);
+#endif
 		// It's saved as building pool index in save file, convert it to true entity
 		if (m_aPhones[i].m_pEntity) {
 			m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((uintptr)m_aPhones[i].m_pEntity - 1);
@@ -376,7 +407,7 @@ CPhoneInfo::Initialise(void)
 void
 CPhoneInfo::Save(uint8 *buf, uint32 *size)
 {
-	*size = sizeof(CPhoneInfo);
+	*size = PHONEINFO_SAVE_SIZE;
 INITSAVEBUF
 	WriteSaveBuf(buf, m_nMax);
 	WriteSaveBuf(buf, m_nScriptPhonesMax);
@@ -385,12 +416,24 @@ INITSAVEBUF
 #else
 	for (int phoneId = 0; phoneId < NUMPHONES; phoneId++) {
 #endif
+#ifdef COMPATIBLE_SAVES
+		WriteSaveBuf(buf, m_aPhones[phoneId].m_vecPos);
+		ZeroSaveBuf(buf, 6 * 4);
+		WriteSaveBuf(buf, m_aPhones[phoneId].m_repeatedMessagePickupStart);
+		// Convert entity pointer to building pool index while saving
+		int32 tmp = m_aPhones[phoneId].m_pEntity ? CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)m_aPhones[phoneId].m_pEntity) + 1 : 0;
+		WriteSaveBuf(buf, tmp);
+		WriteSaveBuf(buf, m_aPhones[phoneId].m_nState);
+		WriteSaveBuf(buf, m_aPhones[phoneId].m_visibleToCam);
+		ZeroSaveBuf(buf, 3);
+#else
 		CPhone* phone = WriteSaveBuf(buf, m_aPhones[phoneId]);
 
 		// Convert entity pointer to building pool index while saving
 		if (phone->m_pEntity) {
 			phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)phone->m_pEntity) + 1);
 		}
+#endif
 	}
 VALIDATESAVEBUF(*size)
 }
diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp
index 10175fba..8d3472ea 100644
--- a/src/control/Pickups.cpp
+++ b/src/control/Pickups.cpp
@@ -32,6 +32,12 @@
 #include "WaterLevel.h"
 #include "World.h"
 
+#ifdef COMPATIBLE_SAVES
+#define PICKUPS_SAVE_SIZE 0x24C0
+#else
+#define PICKUPS_SAVE_SIZE sizeof(aPickUps)
+#endif
+
 CPickup CPickups::aPickUps[NUMPICKUPS];
 int16 CPickups::NumMessages;
 int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];
@@ -1000,10 +1006,23 @@ CPickups::Load(uint8 *buf, uint32 size)
 INITSAVEBUF
 
 	for (int32 i = 0; i < NUMPICKUPS; i++) {
+#ifdef COMPATIBLE_SAVES
+		ReadSaveBuf(&aPickUps[i].m_eType, buf);
+		ReadSaveBuf(&aPickUps[i].m_bRemoved, buf);
+		ReadSaveBuf(&aPickUps[i].m_nQuantity, buf);
+		int32 tmp;
+		ReadSaveBuf(&tmp, buf);
+		aPickUps[i].m_pObject = aPickUps[i].m_eType != PICKUP_NONE && tmp != 0 ? CPools::GetObjectPool()->GetSlot(tmp - 1) : nil;
+		ReadSaveBuf(&aPickUps[i].m_nTimer, buf);
+		ReadSaveBuf(&aPickUps[i].m_eModelIndex, buf);
+		ReadSaveBuf(&aPickUps[i].m_nIndex, buf);
+		ReadSaveBuf(&aPickUps[i].m_vecPos, buf);
+#else
 		ReadSaveBuf(&aPickUps[i], buf);
 
 		if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil)
 			aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pObject - 1);
+#endif
 	}
 
 	ReadSaveBuf(&CollectedPickUpIndex, buf);
@@ -1019,14 +1038,26 @@ VALIDATESAVEBUF(size)
 void
 CPickups::Save(uint8 *buf, uint32 *size)
 {
-	*size = sizeof(aPickUps) + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
+	*size = PICKUPS_SAVE_SIZE + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
 
 INITSAVEBUF
 
 	for (int32 i = 0; i < NUMPICKUPS; i++) {
+#ifdef COMPATIBLE_SAVES
+		WriteSaveBuf(buf, aPickUps[i].m_eType);
+		WriteSaveBuf(buf, aPickUps[i].m_bRemoved);
+		WriteSaveBuf(buf, aPickUps[i].m_nQuantity);
+		int32 tmp = aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aPickUps[i].m_pObject) + 1 : 0;
+		WriteSaveBuf(buf, tmp);
+		WriteSaveBuf(buf, aPickUps[i].m_nTimer);
+		WriteSaveBuf(buf, aPickUps[i].m_eModelIndex);
+		WriteSaveBuf(buf, aPickUps[i].m_nIndex);
+		WriteSaveBuf(buf, aPickUps[i].m_vecPos);
+#else
 		CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]);
 		if (buf_pickup->m_eType != PICKUP_NONE && buf_pickup->m_pObject != nil)
 			buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pObject) + 1);
+#endif
 	}
 
 	WriteSaveBuf(buf, CollectedPickUpIndex);
diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp
index a9aec18e..953a1f50 100644
--- a/src/control/Script5.cpp
+++ b/src/control/Script5.cpp
@@ -2089,33 +2089,33 @@ VALIDATESAVEBUF(size)
 void CRunningScript::Save(uint8*& buf)
 {
 #ifdef COMPATIBLE_SAVES
-	SkipSaveBuf(buf, 8);
+	ZeroSaveBuf(buf, 8);
 	for (int i = 0; i < 8; i++)
-		WriteSaveBuf<char>(buf, m_abScriptName[i]);
-	WriteSaveBuf<uint32>(buf, m_nIp);
+		WriteSaveBuf(buf, m_abScriptName[i]);
+	WriteSaveBuf(buf, m_nIp);
 #ifdef CHECK_STRUCT_SIZES
 	static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
 #endif
 	for (int i = 0; i < MAX_STACK_DEPTH; i++)
-		WriteSaveBuf<uint32>(buf, m_anStack[i]);
-	WriteSaveBuf<uint16>(buf, m_nStackPointer);
-	SkipSaveBuf(buf, 2);
+		WriteSaveBuf(buf, m_anStack[i]);
+	WriteSaveBuf(buf, m_nStackPointer);
+	ZeroSaveBuf(buf, 2);
 #ifdef CHECK_STRUCT_SIZES
 	static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
 #endif
 	for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
-		WriteSaveBuf<int32>(buf, m_anLocalVariables[i]);
-	WriteSaveBuf<bool>(buf, m_bCondResult);
-	WriteSaveBuf<bool>(buf, m_bIsMissionScript);
-	WriteSaveBuf<bool>(buf, m_bSkipWakeTime);
-	SkipSaveBuf(buf, 1);
-	WriteSaveBuf<uint32>(buf, m_nWakeTime);
-	WriteSaveBuf<uint16>(buf, m_nAndOrState);
-	WriteSaveBuf<bool>(buf, m_bNotFlag);
-	WriteSaveBuf<bool>(buf, m_bDeatharrestEnabled);
-	WriteSaveBuf<bool>(buf, m_bDeatharrestExecuted);
-	WriteSaveBuf<bool>(buf, m_bMissionFlag);
-	SkipSaveBuf(buf, 2);
+		WriteSaveBuf(buf, m_anLocalVariables[i]);
+	WriteSaveBuf(buf, m_bCondResult);
+	WriteSaveBuf(buf, m_bIsMissionScript);
+	WriteSaveBuf(buf, m_bSkipWakeTime);
+	ZeroSaveBuf(buf, 1);
+	WriteSaveBuf(buf, m_nWakeTime);
+	WriteSaveBuf(buf, m_nAndOrState);
+	WriteSaveBuf(buf, m_bNotFlag);
+	WriteSaveBuf(buf, m_bDeatharrestEnabled);
+	WriteSaveBuf(buf, m_bDeatharrestExecuted);
+	WriteSaveBuf(buf, m_bMissionFlag);
+	ZeroSaveBuf(buf, 2);
 #else
 	WriteSaveBuf(buf, *this);
 #endif
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index 5cffe9e4..b0248664 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -281,9 +281,9 @@ INITSAVEBUF
 #else
 			if ((pVehicle->IsCar() || pVehicle->IsBoat()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
 #endif
-				WriteSaveBuf<uint32>(buf, pVehicle->m_vehType);
-				WriteSaveBuf<int16>(buf, pVehicle->GetModelIndex());
-				WriteSaveBuf<int32>(buf, GetVehicleRef(pVehicle));
+				WriteSaveBuf(buf, pVehicle->m_vehType);
+				WriteSaveBuf(buf, pVehicle->GetModelIndex());
+				WriteSaveBuf(buf, GetVehicleRef(pVehicle));
 				pVehicle->Save(buf);
 			}
 #else
@@ -292,7 +292,7 @@ INITSAVEBUF
 #else
 			if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
 #endif
-				WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
+				WriteSaveBuf(buf, pVehicle->m_vehType);
 				WriteSaveBuf(buf, pVehicle->GetModelIndex());
 				WriteSaveBuf(buf, GetVehicleRef(pVehicle));
 				memcpy(buf, pVehicle, sizeof(CAutomobile));
@@ -303,7 +303,7 @@ INITSAVEBUF
 #else
 			if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
 #endif
-				WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
+				WriteSaveBuf(buf, pVehicle->m_vehType);
 				WriteSaveBuf(buf, pVehicle->GetModelIndex());
 				WriteSaveBuf(buf, GetVehicleRef(pVehicle));
 				memcpy(buf, pVehicle, sizeof(CBoat));
diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp
index 107b1db8..82fbc047 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -10,6 +10,14 @@
 #include "Timer.h"
 #include "SaveBuf.h"
 
+#ifdef COMPATIBLE_SAVES
+#define ZONEARRAY_SAVE_SIZE 0xAF0
+#define MAPZONEARRAY_SAVE_SIZE 0x578
+#else
+#define ZONEARRAY_SAVE_SIZE sizeof(ZoneArray)
+#define MAPZONEARRAY_SAVE_SIZE sizeof(MapZoneArray)
+#endif
+
 eLevelName CTheZones::m_CurrLevel;
 CZone *CTheZones::m_pPlayersZone;
 int16 CTheZones::FindIndex;
@@ -633,6 +641,28 @@ CTheZones::InitialiseAudioZoneArray(void)
 		}
 }
 
+#ifdef COMPATIBLE_SAVES
+static inline void
+SaveOneZone(CZone &zone, uint8 *&buffer)
+{
+	memcpy(buffer, zone.name, sizeof(zone.name));
+	SkipSaveBuf(buffer, sizeof(zone.name));
+	WriteSaveBuf(buffer, zone.minx);
+	WriteSaveBuf(buffer, zone.miny);
+	WriteSaveBuf(buffer, zone.minz);
+	WriteSaveBuf(buffer, zone.maxx);
+	WriteSaveBuf(buffer, zone.maxy);
+	WriteSaveBuf(buffer, zone.maxz);
+	WriteSaveBuf(buffer, zone.type);
+	WriteSaveBuf(buffer, zone.level);
+	WriteSaveBuf(buffer, zone.zoneinfoDay);
+	WriteSaveBuf(buffer, zone.zoneinfoNight);
+	WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.child));
+	WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.parent));
+	WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.next));
+}
+#endif
+
 void
 CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
 {
@@ -643,9 +673,9 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
 		+ sizeof(int32) // GetIndexForZonePointer
 		+ sizeof(m_CurrLevel) + sizeof(FindIndex)
 		+ sizeof(int16) // padding
-		+ sizeof(ZoneArray) + sizeof(ZoneInfoArray)
+		+ ZONEARRAY_SAVE_SIZE + sizeof(ZoneInfoArray)
 		+ sizeof(TotalNumberOfZones) + sizeof(TotalNumberOfZoneInfos)
-		+ sizeof(MapZoneArray) + sizeof(AudioZoneArray)
+		+ MAPZONEARRAY_SAVE_SIZE + sizeof(AudioZoneArray)
 		+ sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones);
 
 	WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE);
@@ -656,10 +686,14 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
 	WriteSaveBuf(buffer, (int16)0); // padding
 
 	for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
+#ifdef COMPATIBLE_SAVES
+		SaveOneZone(ZoneArray[i], buffer);
+#else
 		CZone *zone = WriteSaveBuf(buffer, ZoneArray[i]);
 		zone->child = (CZone*)GetIndexForZonePointer(ZoneArray[i].child);
 		zone->parent = (CZone*)GetIndexForZonePointer(ZoneArray[i].parent);
 		zone->next = (CZone*)GetIndexForZonePointer(ZoneArray[i].next);
+#endif
 	}
 
 	for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
@@ -669,7 +703,9 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
 	WriteSaveBuf(buffer, TotalNumberOfZoneInfos);
 
 	for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) {
+#ifndef COMPATIBLE_SAVES
 		CZone* zone = WriteSaveBuf(buffer, MapZoneArray[i]);
+#endif
 
 		/*
 		The call of GetIndexForZonePointer is wrong, as it is
@@ -679,9 +715,13 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
 		assert(MapZoneArray[i].child == nil);
 		assert(MapZoneArray[i].parent == nil);
 		assert(MapZoneArray[i].next == nil);
+#ifndef COMPATIBLE_SAVES
 		zone->child = (CZone*)GetIndexForZonePointer(MapZoneArray[i].child);
 		zone->parent = (CZone*)GetIndexForZonePointer(MapZoneArray[i].parent);
 		zone->next = (CZone*)GetIndexForZonePointer(MapZoneArray[i].next);
+#else
+		SaveOneZone(MapZoneArray[i], buffer);
+#endif
 	}
 
 	for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
@@ -693,6 +733,32 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
 	VALIDATESAVEBUF(*size)
 }
 
+#ifdef COMPATIBLE_SAVES
+static inline void
+LoadOneZone(CZone &zone, uint8 *&buffer)
+{
+	memcpy(zone.name, buffer, sizeof(zone.name));
+	SkipSaveBuf(buffer, sizeof(zone.name));
+	ReadSaveBuf(&zone.minx, buffer);
+	ReadSaveBuf(&zone.miny, buffer);
+	ReadSaveBuf(&zone.minz, buffer);
+	ReadSaveBuf(&zone.maxx, buffer);
+	ReadSaveBuf(&zone.maxy, buffer);
+	ReadSaveBuf(&zone.maxz, buffer);
+	ReadSaveBuf(&zone.type, buffer);
+	ReadSaveBuf(&zone.level, buffer);
+	ReadSaveBuf(&zone.zoneinfoDay, buffer);
+	ReadSaveBuf(&zone.zoneinfoNight, buffer);
+	int32 tmp;
+	ReadSaveBuf(&tmp, buffer);
+	zone.child = CTheZones::GetPointerForZoneIndex(tmp);
+	ReadSaveBuf(&tmp, buffer);
+	zone.parent = CTheZones::GetPointerForZoneIndex(tmp);
+	ReadSaveBuf(&tmp, buffer);
+	zone.next = CTheZones::GetPointerForZoneIndex(tmp);
+}
+#endif
+
 void
 CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
 {
@@ -708,11 +774,15 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
 	SkipSaveBuf(buffer, 2);
 
 	for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
+#ifdef COMPATIBLE_SAVES
+		LoadOneZone(ZoneArray[i], buffer);
+#else
 		ReadSaveBuf(&ZoneArray[i], buffer);
 
 		ZoneArray[i].child = GetPointerForZoneIndex((uintptr)ZoneArray[i].child);
 		ZoneArray[i].parent = GetPointerForZoneIndex((uintptr)ZoneArray[i].parent);
 		ZoneArray[i].next = GetPointerForZoneIndex((uintptr)ZoneArray[i].next);
+#endif
 	}
 
 	for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
@@ -722,6 +792,9 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
 	ReadSaveBuf(&TotalNumberOfZoneInfos, buffer);
 
 	for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){
+#ifdef COMPATIBLE_SAVES
+		LoadOneZone(MapZoneArray[i], buffer);
+#else
 		ReadSaveBuf(&MapZoneArray[i], buffer);
 
 		/*
@@ -732,6 +805,7 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
 		MapZoneArray[i].child = GetPointerForZoneIndex((uintptr)MapZoneArray[i].child);
 		MapZoneArray[i].parent = GetPointerForZoneIndex((uintptr)MapZoneArray[i].parent);
 		MapZoneArray[i].next = GetPointerForZoneIndex((uintptr)MapZoneArray[i].next);
+#endif
 		assert(MapZoneArray[i].child == nil);
 		assert(MapZoneArray[i].parent == nil);
 		assert(MapZoneArray[i].next == nil);
diff --git a/src/core/config.h b/src/core/config.h
index d7d43b62..a8b83577 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -237,7 +237,8 @@ enum Config {
 
 #define FIX_BUGS		// fixes bugs that we've came across during reversing. You can undefine this only on release builds.
 #define MORE_LANGUAGES		// Add more translations to the game
-#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible
+#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible, and keeps saves compatible between platforms
+#define FIX_INCOMPATIBLE_SAVES // try to fix incompatible saves, requires COMPATIBLE_SAVES
 #define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS
 
 #define NO_MOVIES	// add option to disable intro videos
@@ -466,6 +467,7 @@ enum Config {
 #define THIS_IS_STUPID
 #undef MORE_LANGUAGES
 #undef COMPATIBLE_SAVES
+#undef FIX_INCOMPATIBLE_SAVES
 #undef LOAD_INI_SETTINGS
 
 #undef ASPECT_RATIO_SCALE
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index a7f4bd45..c38f12c7 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -732,7 +732,7 @@ CEntity::SaveEntityFlags(uint8*& buf)
 	if (bZoneCulled) tmp |= BIT(30);
 	if (bZoneCulled2) tmp |= BIT(31);
 
-	WriteSaveBuf<uint32>(buf, tmp);
+	WriteSaveBuf(buf, tmp);
 
 	tmp = 0;
 
@@ -748,7 +748,7 @@ CEntity::SaveEntityFlags(uint8*& buf)
 	if (bDistanceFade) tmp |= BIT(8);
 	if (m_flagE2) tmp |= BIT(9);
 
-	WriteSaveBuf<uint32>(buf, tmp);
+	WriteSaveBuf(buf, tmp);
 }
 
 void
diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp
index 211a568c..5d480ecc 100644
--- a/src/objects/ParticleObject.cpp
+++ b/src/objects/ParticleObject.cpp
@@ -10,6 +10,12 @@
 #include "DMAudio.h"
 #include "screendroplets.h"
 
+#ifdef COMPATIBLE_SAVES
+#define PARTICLE_OBJECT_SIZEOF 0x88
+#else
+#define PARTICLE_OBJECT_SIZEOF sizeof(CParticleObject)
+#endif
+
 
 CParticleObject gPObjectArray[MAX_PARTICLEOBJECTS];
 
@@ -1111,6 +1117,49 @@ CParticleObject::UpdateFar(void)
 	}
 }
 
+#ifdef COMPATIBLE_SAVES
+static inline void
+SaveOneParticle(CParticleObject *p, uint8 *&buffer)
+{
+#define SkipBuf(buf, num) buf += num
+#define ZeroBuf(buf, num) memset(buf, 0, num); SkipBuf(buf, num)
+#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipBuf(buf, sizeof(data))
+	// CPlaceable
+	{
+		ZeroBuf(buffer, 4);
+		CopyToBuf(buffer, p->GetMatrix().f);
+		ZeroBuf(buffer, 4);
+		CopyToBuf(buffer, p->GetMatrix().m_hasRwMatrix);
+		ZeroBuf(buffer, 3);
+	}
+
+	// CParticleObject
+	{
+		ZeroBuf(buffer, 4);
+		ZeroBuf(buffer, 4);
+		ZeroBuf(buffer, 4);
+		CopyToBuf(buffer, p->m_nRemoveTimer);
+		CopyToBuf(buffer, p->m_Type);
+		CopyToBuf(buffer, p->m_ParticleType);
+		CopyToBuf(buffer, p->m_nNumEffectCycles);
+		CopyToBuf(buffer, p->m_nSkipFrames);
+		CopyToBuf(buffer, p->m_nFrameCounter);
+		CopyToBuf(buffer, p->m_nState);
+		ZeroBuf(buffer, 2);
+		CopyToBuf(buffer, p->m_vecTarget);
+		CopyToBuf(buffer, p->m_fRandVal);
+		CopyToBuf(buffer, p->m_fSize);
+		CopyToBuf(buffer, p->m_Color);
+		CopyToBuf(buffer, p->m_bRemove);
+		CopyToBuf(buffer, p->m_nCreationChance);
+		ZeroBuf(buffer, 2);
+	}
+#undef SkipBuf
+#undef ZeroBuf
+#undef CopyToBuf
+}
+#endif
+
 bool
 CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
 {
@@ -1128,27 +1177,35 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
 	*(int32 *)buffer = numObjects;
 	buffer += sizeof(int32);
 	
-	int32 objectsLength = sizeof(CParticleObject) * (numObjects + 1);
+	int32 objectsLength = PARTICLE_OBJECT_SIZEOF * (numObjects + 1);
 	int32 dataLength = objectsLength + sizeof(int32);
 	
 	for ( CParticleObject *p = pCloseListHead; p != NULL; p = p->m_pNext )
 	{
-#if 0 // todo better
+#ifdef COMPATIBLE_SAVES
+		SaveOneParticle(p, buffer);
+#else
+#ifdef THIS_IS_STUPID
 		*(CParticleObject*)buffer = *p;
 #else
 		memcpy(buffer, p, sizeof(CParticleObject));
 #endif
 		buffer += sizeof(CParticleObject);
+#endif
 	}
 	
 	for ( CParticleObject *p = pFarListHead; p != NULL; p = p->m_pNext )
 	{
-#if 0 // todo better
+#ifdef COMPATIBLE_SAVES
+		SaveOneParticle(p, buffer);
+#else
+#ifdef THIS_IS_STUPID
 		*(CParticleObject*)buffer = *p;
 #else
 		memcpy(buffer, p, sizeof(CParticleObject));
 #endif
 		buffer += sizeof(CParticleObject);
+#endif
 	}
 	
 	*length = dataLength;
@@ -1166,7 +1223,7 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32  length)
 	int32 numObjects = *(int32 *)buffer;
 	buffer += sizeof(int32);
 	
-	if ( length != sizeof(CParticleObject) * (numObjects + 1) + sizeof(int32) )
+	if ( length != PARTICLE_OBJECT_SIZEOF * (numObjects + 1) + sizeof(int32) )
 		return false;
 	
 	if ( numObjects == 0 )
@@ -1177,14 +1234,17 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32  length)
 	while ( i < numObjects )
 	{
 		CParticleObject *dst = pUnusedListHead;
+#ifndef COMPATIBLE_SAVES
 		CParticleObject *src = (CParticleObject *)buffer;
 		buffer += sizeof(CParticleObject);
+#endif
 		
 		if ( dst == NULL )
 			return false;
 		
 		MoveToList(&pUnusedListHead, &pCloseListHead, dst);
 		
+#ifndef COMPATIBLE_SAVES
 		dst->m_nState           = POBJECTSTATE_UPDATE_CLOSE;
 		dst->m_Type             = src->m_Type;
 		dst->m_ParticleType     = src->m_ParticleType;
@@ -1200,6 +1260,47 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32  length)
 		dst->m_nNumEffectCycles = src->m_nNumEffectCycles;
 		dst->m_nSkipFrames      = src->m_nSkipFrames;
 		dst->m_nCreationChance  = src->m_nCreationChance;
+#else
+		dst->m_nState = POBJECTSTATE_UPDATE_CLOSE;
+		dst->m_pParticle = NULL;
+
+#define SkipBuf(buf, num) buf += num
+#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipBuf(buf, sizeof(data))
+		// CPlaceable
+		{
+			SkipBuf(buffer, 4);
+			CMatrix matrix;
+			CopyFromBuf(buffer, matrix.f);
+			SkipBuf(buffer, 4);
+			CopyFromBuf(buffer, matrix.m_hasRwMatrix);
+			SkipBuf(buffer, 3);
+			dst->SetPosition(matrix.GetPosition());
+		}
+
+		// CParticleObject
+		{
+			SkipBuf(buffer, 4);
+			SkipBuf(buffer, 4);
+			SkipBuf(buffer, 4);
+			CopyFromBuf(buffer, dst->m_nRemoveTimer);
+			CopyFromBuf(buffer, dst->m_Type);
+			CopyFromBuf(buffer, dst->m_ParticleType);
+			CopyFromBuf(buffer, dst->m_nNumEffectCycles);
+			CopyFromBuf(buffer, dst->m_nSkipFrames);
+			CopyFromBuf(buffer, dst->m_nFrameCounter);
+			SkipBuf(buffer, 2);
+			SkipBuf(buffer, 2);
+			CopyFromBuf(buffer, dst->m_vecTarget);
+			CopyFromBuf(buffer, dst->m_fRandVal);
+			CopyFromBuf(buffer, dst->m_fSize);
+			CopyFromBuf(buffer, dst->m_Color);
+			CopyFromBuf(buffer, dst->m_bRemove);
+			CopyFromBuf(buffer, dst->m_nCreationChance);
+			SkipBuf(buffer, 2);
+		}
+#undef CopyFromBuf
+#undef SkipBuf
+#endif
 		
 		i++;
 	}
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 4d80cac2..5b52d021 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -8496,21 +8496,21 @@ CPed::renderLimb(int node)
 void
 CPed::Save(uint8*& buf)
 {
-	SkipSaveBuf(buf, 52);
+	ZeroSaveBuf(buf, 52);
 	CopyToBuf(buf, GetPosition().x);
 	CopyToBuf(buf, GetPosition().y);
 	CopyToBuf(buf, GetPosition().z);
-	SkipSaveBuf(buf, 288);
+	ZeroSaveBuf(buf, 288);
 	CopyToBuf(buf, CharCreatedBy);
-	SkipSaveBuf(buf, 351);
+	ZeroSaveBuf(buf, 351);
 	CopyToBuf(buf, m_fHealth);
 	CopyToBuf(buf, m_fArmour);
-	SkipSaveBuf(buf, 148);
+	ZeroSaveBuf(buf, 148);
 	for (int i = 0; i < 13; i++) // has to be hardcoded
 		m_weapons[i].Save(buf);
-	SkipSaveBuf(buf, 5);
+	ZeroSaveBuf(buf, 5);
 	CopyToBuf(buf, m_maxWeaponTypeAllowed);
-	SkipSaveBuf(buf, 162);
+	ZeroSaveBuf(buf, 162);
 }
 
 void
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 93a403bd..6d6fc714 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -1492,14 +1492,14 @@ void
 CPlayerPed::Save(uint8*& buf)
 {
 	CPed::Save(buf);
-	SkipSaveBuf(buf, 16);
+	ZeroSaveBuf(buf, 16);
 	CopyToBuf(buf, m_fMaxStamina);
-	SkipSaveBuf(buf, 28);
+	ZeroSaveBuf(buf, 28);
 	CopyToBuf(buf, m_nTargettableObjects[0]);
 	CopyToBuf(buf, m_nTargettableObjects[1]);
 	CopyToBuf(buf, m_nTargettableObjects[2]);
 	CopyToBuf(buf, m_nTargettableObjects[3]);
-	SkipSaveBuf(buf, 116);
+	ZeroSaveBuf(buf, 116);
 }
 
 void
diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp
index 23a8fd6a..f51f8233 100644
--- a/src/save/GenericGameStorage.cpp
+++ b/src/save/GenericGameStorage.cpp
@@ -600,6 +600,552 @@ align4bytes(int32 size)
 	return (size + 3) & 0xFFFFFFFC;
 }
 
+#ifdef FIX_INCOMPATIBLE_SAVES
+#define LoadSaveDataBlockNoCheck(buf, file, size) \
+do { \
+	CFileMgr::Read(file, (const char *)&size, sizeof(size)); \
+	size = align4bytes(size); \
+	CFileMgr::Read(file, (const char *)work_buff, size); \
+	buf = work_buff; \
+} while(0)
+
+#define WriteSavaDataBlockNoFunc(buf, file, size) \
+do { \
+	if (!PcSaveHelper.PcClassSaveRoutine(file, buf, size)) \
+		goto fail; \
+	totalSize += size; \
+} while(0)
+
+#define FixSaveDataBlock(fix_func, file, size) \
+do { \
+	ReadDataFromBufferPointer(buf, size); \
+	memset(work_buff2, 0, sizeof(work_buff2)); \
+	buf2 = work_buff2; \
+	reserved = 0; \
+	MakeSpaceForSizeInBufferPointer(presize, buf2, postsize); \
+	fix_func(save_type, buf, buf2, &size); \
+	CopySizeAndPreparePointer(presize, buf2, postsize, reserved, size); \
+	if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff2, buf2 - work_buff2)) \
+		goto fail; \
+	totalSize += buf2 - work_buff2; \
+} while(0)
+
+#define ReadDataFromBufferPointerWithSize(buf, to, size) memcpy(&to, buf, size); buf += align4bytes(size)
+
+#define ReadBuf(buf, to) memcpy(&to, buf, sizeof(to)); buf += sizeof(to)
+#define WriteBuf(buf, from) memcpy(buf, &from, sizeof(from)); buf += sizeof(from)
+#define CopyBuf(from, to, size) memcpy(to, from, size); to += (size); from += (size)
+#define CopyPtr(from, to) memcpy(to, from, 4); to += 4; from += 8
+#define SkipBuf(buf, size) buf += (size)
+#define SkipBoth(from, to, size) to += (size); from += (size)
+#define SkipPtr(from, to) to += 4; from += 8
+
+// unfortunately we need a 2nd buffer of the same size to store the fixed output ...
+static uint8 work_buff2[sizeof(work_buff)];
+
+enum
+{
+	SAVE_TYPE_NONE = 0,
+	SAVE_TYPE_32_BIT = 1,
+	SAVE_TYPE_64_BIT = 2,
+	SAVE_TYPE_MSVC = 4,
+	SAVE_TYPE_GCC = 8,
+};
+
+uint8
+GetSaveType(char *savename)
+{
+	uint8 save_type = SAVE_TYPE_NONE;
+	int file = CFileMgr::OpenFile(savename, "rb");
+
+	uint32 size;
+	CFileMgr::Read(file, (const char *)&size, sizeof(size));
+
+	uint8 *buf = work_buff;
+	CFileMgr::Read(file, (const char *)work_buff, size); // simple vars + scripts
+
+	LoadSaveDataBlockNoCheck(buf, file, size); // ped pool
+
+	LoadSaveDataBlockNoCheck(buf, file, size); // garages
+	ReadDataFromBufferPointer(buf, size);
+
+	// store for later after we know how much data we need to skip
+	ReadDataFromBufferPointerWithSize(buf, work_buff2, size);
+
+	LoadSaveDataBlockNoCheck(buf, file, size); // vehicle pool
+	LoadSaveDataBlockNoCheck(buf, file, size); // object pool
+	LoadSaveDataBlockNoCheck(buf, file, size); // paths
+
+	LoadSaveDataBlockNoCheck(buf, file, size); // cranes
+
+	CFileMgr::CloseFile(file);
+
+	ReadDataFromBufferPointer(buf, size);
+
+	if (size == 1032)
+		save_type |= SAVE_TYPE_32_BIT;
+	else if (size == 1160)
+		save_type |= SAVE_TYPE_64_BIT;
+	else
+		assert(0); // this should never happen
+
+	buf = work_buff2;
+
+	buf += 760; // skip everything before the first garage
+	buf += save_type & SAVE_TYPE_32_BIT ? 28 : 40; // skip first garage up to m_fX1
+
+	// now the values we want to verify
+	float fX1, fX2, fY1, fY2, fZ1, fZ2;
+
+	ReadBuf(buf, fX1);
+	ReadBuf(buf, fX2);
+	ReadBuf(buf, fY1);
+	ReadBuf(buf, fY2);
+	ReadBuf(buf, fZ1);
+	ReadBuf(buf, fZ2);
+
+	if (fX1 == CRUSHER_GARAGE_X1 && fX2 == CRUSHER_GARAGE_X2 &&
+		fY1 == CRUSHER_GARAGE_Y1 && fY2 == CRUSHER_GARAGE_Y2 &&
+		fZ1 == CRUSHER_GARAGE_Z1 && fZ2 == CRUSHER_GARAGE_Z2)
+		save_type |= SAVE_TYPE_MSVC;
+	else
+		save_type |= SAVE_TYPE_GCC;
+
+	return save_type;
+}
+
+static void
+FixGarages(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+	// hardcoded: 5484
+	// x86 msvc: 5240
+	// x86 gcc: 5040
+	// amd64 msvc: 5880
+	// amd64 gcc: 5808
+
+	uint8 *buf_start = buf;
+	uint8 *buf2_start = buf2;
+	uint32 read;
+	uint32 written = 5240;
+
+	if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_GCC)
+		read = 5040;
+	else if (save_type & SAVE_TYPE_64_BIT && save_type & SAVE_TYPE_GCC)
+		read = 5808;
+	else
+		read = 5880;
+
+	uint32 ptrsize = save_type & SAVE_TYPE_32_BIT ? 4 : 8;
+
+	CopyBuf(buf, buf2, 4 * 6);
+	CopyBuf(buf, buf2, 4 * TOTAL_COLLECTCARS_GARAGES);
+	CopyBuf(buf, buf2, 4);
+
+	if (save_type & SAVE_TYPE_GCC)
+	{
+		for (int32 i = 0; i < NUM_GARAGE_STORED_CARS; i++)
+		{
+#define FixStoredCar(buf, buf2) \
+do { \
+	CopyBuf(buf, buf2, 4 + sizeof(CVector) + sizeof(CVector)); \
+	uint8 nFlags8; \
+	ReadBuf(buf, nFlags8); \
+	int32 nFlags32 = nFlags8; \
+	WriteBuf(buf2, nFlags32); \
+	CopyBuf(buf, buf2, 1 * 6); \
+	SkipBuf(buf, 1); \
+	SkipBuf(buf2, 2); \
+} while(0)
+
+			FixStoredCar(buf, buf2);
+			FixStoredCar(buf, buf2);
+			FixStoredCar(buf, buf2);
+
+#undef FixStoredCar
+		}
+	}
+	else
+	{
+		CopyBuf(buf, buf2, sizeof(CStoredCar) * NUM_GARAGE_STORED_CARS);
+		CopyBuf(buf, buf2, sizeof(CStoredCar) * NUM_GARAGE_STORED_CARS);
+		CopyBuf(buf, buf2, sizeof(CStoredCar) * NUM_GARAGE_STORED_CARS);
+	}
+
+	for (int32 i = 0; i < NUM_GARAGES; i++)
+	{
+		// skip the last 5 garages in 64bit builds without FIX_GARAGE_SIZE since they weren't actually saved and are unused
+		if (save_type & SAVE_TYPE_64_BIT && *size == 5484 && i >= NUM_GARAGES - 5)
+		{
+			SkipBuf(buf, 160); // sizeof(CGarage) on x64
+			SkipBuf(buf2, 140); // sizeof(CGarage) on x86
+		}
+		else
+		{
+			CopyBuf(buf, buf2, 1 * 6);
+			SkipBoth(buf, buf2, 2);
+			CopyBuf(buf, buf2, 4);
+			SkipBuf(buf, ptrsize - 4); // write 4 bytes padding if 8 byte pointer, if not, write 0
+			SkipBuf(buf, ptrsize * 2);
+			SkipBuf(buf2, 4 * 2);
+			CopyBuf(buf, buf2, 1 * 7);
+			SkipBoth(buf, buf2, 1);
+			CopyBuf(buf, buf2, 4 * 15 + 1);
+			SkipBoth(buf, buf2, 3);
+			SkipBuf(buf, ptrsize * 2);
+			SkipBuf(buf2, 4 * 2);
+
+			if (save_type & SAVE_TYPE_GCC)
+				SkipBuf(buf, save_type & SAVE_TYPE_64_BIT ? 36 + 4 : 36); // sizeof(CStoredCar) on gcc 64/32 before fix
+			else
+				SkipBuf(buf, sizeof(CStoredCar));
+
+			SkipBuf(buf2, sizeof(CStoredCar));
+		}
+	}
+
+	*size = 0;
+
+	assert(buf - buf_start == read);
+	assert(buf2 - buf2_start == written);
+
+#ifdef FIX_GARAGE_SIZE
+	*size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CGarages::CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
+#else
+	*size = 5484;
+#endif
+}
+
+static void
+FixCranes(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+	uint8 *buf_start = buf;
+	uint8 *buf2_start = buf2;
+	uint32 read = 2 * sizeof(uint32) + 0x480; // sizeof(aCranes)
+	uint32 written = 2 * sizeof(uint32) + 0x400; // see CRANES_SAVE_SIZE
+
+	CopyBuf(buf, buf2, 4 + 4);
+
+	for (int32 i = 0; i < NUM_CRANES; i++)
+	{
+		CopyPtr(buf, buf2);
+		CopyPtr(buf, buf2);
+		CopyBuf(buf, buf2, 15 * 4 + sizeof(CVector) * 3 + sizeof(CVector2D));
+		CopyPtr(buf, buf2);
+		CopyBuf(buf, buf2, 4 + 7 * 1);
+		SkipBuf(buf, 5);
+		SkipBuf(buf2, 1);
+	}
+
+	*size = 0;
+
+	assert(buf - buf_start == read);
+	assert(buf2 - buf2_start == written);
+
+	*size = written;
+}
+
+static void
+FixPickups(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+	uint8 *buf_start = buf;
+	uint8 *buf2_start = buf2;
+	uint32 read = 0x3480 + sizeof(uint16) + sizeof(uint16) + sizeof(int32) * NUMCOLLECTEDPICKUPS; // sizeof(aPickUps)
+	uint32 written = 0x24C0 + sizeof(uint16) + sizeof(uint16) + sizeof(int32) * NUMCOLLECTEDPICKUPS; // see PICKUPS_SAVE_SIZE
+
+	for (int32 i = 0; i < NUMPICKUPS; i++)
+	{
+		CopyBuf(buf, buf2, 1 + 1 + 2);
+		SkipBuf(buf, 4);
+		CopyPtr(buf, buf2);
+		CopyBuf(buf, buf2, 4 + 2 + 2 + sizeof(CVector));
+		SkipBuf(buf, 4);
+	}
+
+	CopyBuf(buf, buf2, 2);
+	SkipBoth(buf, buf2, 2);
+
+	CopyBuf(buf, buf2, NUMCOLLECTEDPICKUPS * 4);
+
+	*size = 0;
+
+	assert(buf - buf_start == read);
+	assert(buf2 - buf2_start == written);
+
+	*size = written;
+}
+
+static void
+FixPhoneInfo(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+	uint8 *buf_start = buf;
+	uint8 *buf2_start = buf2;
+	uint32 read = 0x1138; // sizeof(CPhoneInfo)
+	uint32 written = 0xA30; // see PHONEINFO_SAVE_SIZE
+
+	CopyBuf(buf, buf2, 4 + 4);
+
+	for (int32 i = 0; i < NUMPHONES; i++)
+	{
+		CopyBuf(buf, buf2, sizeof(CVector));
+		SkipBuf(buf, 4);
+		SkipPtr(buf, buf2);
+		SkipPtr(buf, buf2);
+		SkipPtr(buf, buf2);
+		SkipPtr(buf, buf2);
+		SkipPtr(buf, buf2);
+		SkipPtr(buf, buf2);
+		CopyBuf(buf, buf2, 4);
+		SkipBuf(buf, 4);
+		CopyPtr(buf, buf2);
+		CopyBuf(buf, buf2, 4 + 1);
+		SkipBoth(buf, buf2, 3);
+	}
+
+	*size = 0;
+
+	assert(buf - buf_start == read);
+	assert(buf2 - buf2_start == written);
+
+	*size = written;
+}
+
+static void
+FixZones(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+	uint8 *buf_start = buf;
+	uint8 *buf2_start = buf2;
+	uint32 read = 11300; // see SaveAllZones
+	uint32 written = 10100; // see SaveAllZones
+
+	CopyBuf(buf, buf2, 1 * 4);
+
+	SkipBuf(buf, 4);
+	uint32 hdr_size = 10100 - (1 * 4 + 4); // see SaveAllZones
+	WriteBuf(buf2, hdr_size);
+
+	CopyBuf(buf, buf2, 4 * 2 + 2);
+	SkipBoth(buf, buf2, 2);
+
+#define FixOneZone(buf, buf2) \
+do { \
+	CopyBuf(buf, buf2, 8 + 8 * 4 + 2 * 2); \
+	SkipBuf(buf, 4); \
+	CopyPtr(buf, buf2); \
+	CopyPtr(buf, buf2); \
+	CopyPtr(buf, buf2); \
+} while(0)
+
+	for (int32 i = 0; i < NUMZONES; i++)
+		FixOneZone(buf, buf2);
+
+	CopyBuf(buf, buf2, sizeof(CZoneInfo) * NUMZONES * 2);
+	CopyBuf(buf, buf2, 2 + 2);
+
+	for (int32 i = 0; i < NUMMAPZONES; i++)
+		FixOneZone(buf, buf2);
+
+	CopyBuf(buf, buf2, 2 * NUMAUDIOZONES);
+	CopyBuf(buf, buf2, 2 + 2);
+
+#undef FixOneZone
+
+	*size = 0;
+
+	assert(buf - buf_start == read);
+	assert(buf2 - buf2_start == written);
+
+	*size = written;
+}
+
+static void
+FixParticles(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+	uint8 *buf_start = buf;
+	uint8 *buf2_start = buf2;
+
+	int32 numObjects;
+	ReadBuf(buf, numObjects);
+	WriteBuf(buf2, numObjects);
+
+	uint32 read = 0xA0 * (numObjects + 1) + 4; // sizeof(CParticleObject)
+	uint32 written = 0x88 * (numObjects + 1) + 4; // see PARTICLE_OBJECT_SIZEOF
+
+	for (int32 i = 0; i < numObjects; i++)
+	{
+		// CPlaceable
+		SkipPtr(buf, buf2);
+		CopyBuf(buf, buf2, 4 * 4 * 4);
+		SkipPtr(buf, buf2);
+		CopyBuf(buf, buf2, 1);
+		SkipBuf(buf, 7);
+		SkipBuf(buf2, 3);
+
+		// CParticleObject
+		SkipPtr(buf, buf2);
+		SkipPtr(buf, buf2);
+		SkipPtr(buf, buf2);
+		CopyBuf(buf, buf2, 4 * 3 + 2 * 1 + 2 * 2);
+		SkipBoth(buf, buf2, 2);
+		CopyBuf(buf, buf2, sizeof(CVector) + 2 * 4 + sizeof(CRGBA) + 2 * 1);
+		SkipBoth(buf, buf2, 2);
+	}
+
+	SkipBuf(buf, 0xA0); // sizeof(CParticleObject)
+	SkipBuf(buf2, 0x88); // see PARTICLE_OBJECT_SIZEOF
+
+	*size = 0;
+
+	assert(buf - buf_start == read);
+	assert(buf2 - buf2_start == written);
+
+	*size = written;
+}
+
+bool
+FixSave(int32 slot, uint8 save_type)
+{
+	if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_MSVC)
+		return true;
+
+	bool success = false;
+
+	uint8 *buf, *presize, *postsize, *buf2;
+	uint32 size;
+	uint32 reserved;
+
+	uint32 totalSize;
+
+	char savename[MAX_PATH];
+	char savename_bak[MAX_PATH];
+
+	sprintf(savename, "%s%i%s", DefaultPCSaveFileName, slot + 1, ".b");
+	sprintf(savename_bak, "%s%i%s.%lld.bak", DefaultPCSaveFileName, slot + 1, ".b", time(nil));
+
+	assert(caserename(savename, savename_bak) == 0);
+
+	int file_in = CFileMgr::OpenFile(savename_bak, "rb");
+	int file_out = CFileMgr::OpenFileForWriting(savename);
+
+	CheckSum = 0;
+	totalSize = 0;
+
+	CFileMgr::Read(file_in, (const char *)&size, sizeof(size));
+
+	buf = work_buff;
+	CFileMgr::Read(file_in, (const char *)work_buff, size); // simple vars + scripts
+
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // ped pool
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // garages
+	FixSaveDataBlock(FixGarages, file_out, size); // garages need to be fixed in either case
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // vehicle pool
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // object pool
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // paths
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // cranes
+	if (save_type & SAVE_TYPE_64_BIT)
+		FixSaveDataBlock(FixCranes, file_out, size);
+	else
+		WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // pickups
+	if (save_type & SAVE_TYPE_64_BIT)
+		FixSaveDataBlock(FixPickups, file_out, size);
+	else
+		WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // phoneinfo
+	if (save_type & SAVE_TYPE_64_BIT)
+		FixSaveDataBlock(FixPhoneInfo, file_out, size);
+	else
+		WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // restart
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // radar blips
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // zones
+	if (save_type & SAVE_TYPE_64_BIT)
+		FixSaveDataBlock(FixZones, file_out, size);
+	else
+		WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // gang data
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // car generators
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // particles
+	if (save_type & SAVE_TYPE_64_BIT)
+		FixSaveDataBlock(FixParticles, file_out, size);
+	else
+		WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // audio script objects
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // player info
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // stats
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // streaming
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	LoadSaveDataBlockNoCheck(buf, file_in, size); // ped type
+	WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+	memset(work_buff, 0, sizeof(work_buff));
+
+	for (int i = 0; i < 4; i++) {
+		size = align4bytes(SIZE_OF_ONE_GAME_IN_BYTES - totalSize - 4);
+		if (size > sizeof(work_buff))
+			size = sizeof(work_buff);
+		if (size > 4) {
+			if (!PcSaveHelper.PcClassSaveRoutine(file_out, work_buff, size))
+				goto fail;
+			totalSize += size;
+		}
+	}
+
+	if (!CFileMgr::Write(file_out, (const char *)&CheckSum, sizeof(CheckSum)))
+		goto fail;
+
+	success = true;
+
+fail:;
+	CFileMgr::CloseFile(file_in);
+	CFileMgr::CloseFile(file_out);
+
+	return success;
+}
+
+#undef LoadSaveDataBlockNoCheck
+#undef WriteSavaDataBlockNoFunc
+#undef FixSaveDataBlock
+#undef ReadDataFromBufferPointerWithSize
+#undef ReadBuf
+#undef WriteBuf
+#undef CopyBuf
+#undef CopyPtr
+#undef SkipBuf
+#undef SkipBoth
+#undef SkipPtr
+#endif
+
 #ifdef MISSION_REPLAY
 
 void DisplaySaveResult(int unk, char* name)
diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h
index 069ba7cd..b291ddf9 100644
--- a/src/save/GenericGameStorage.h
+++ b/src/save/GenericGameStorage.h
@@ -22,6 +22,11 @@ bool CheckDataNotCorrupt(int32 slot, char *name);
 bool RestoreForStartLoad();
 int align4bytes(int32 size);
 
+#ifdef FIX_INCOMPATIBLE_SAVES
+uint8 GetSaveType(char *savename);
+bool FixSave(int32 slot, uint8 save_type);
+#endif
+
 extern class CDate CompileDateAndTime;
 
 extern char DefaultPCSaveFileName[260];
diff --git a/src/save/PCSave.cpp b/src/save/PCSave.cpp
index a9df00af..0c228a6d 100644
--- a/src/save/PCSave.cpp
+++ b/src/save/PCSave.cpp
@@ -122,6 +122,13 @@ C_PcSave::PopulateSlotInfo()
 		}
 		if (Slots[i + 1] == SLOT_OK) {
 			if (CheckDataNotCorrupt(i, savename)) {
+#ifdef FIX_INCOMPATIBLE_SAVES
+				if (!FixSave(i, GetSaveType(savename))) {
+					CMessages::InsertNumberInString(TheText.Get("FEC_SLC"), i + 1, -1, -1, -1, -1, -1, SlotFileName[i]);
+					Slots[i + 1] = SLOT_CORRUPTED;
+					continue;
+				}
+#endif
 				SYSTEMTIME st;
 				memcpy(&st, &header.SaveDateTime, sizeof(SYSTEMTIME));
 				const char *month;
diff --git a/src/save/PCSave.h b/src/save/PCSave.h
index 4a2d9a66..83471b5d 100644
--- a/src/save/PCSave.h
+++ b/src/save/PCSave.h
@@ -33,7 +33,7 @@ public:
 	void PopulateSlotInfo();
 	bool DeleteSlot(int32 slot);
 	bool SaveSlot(int32 slot);
-	bool PcClassSaveRoutine(int32 a2, uint8 *data, uint32 size);
+	bool PcClassSaveRoutine(int32 file, uint8 *data, uint32 size);
 	static void SetSaveDirectory(const char *path);
 };
 
diff --git a/src/save/SaveBuf.h b/src/save/SaveBuf.h
index 98fe888b..aad2e1a8 100644
--- a/src/save/SaveBuf.h
+++ b/src/save/SaveBuf.h
@@ -36,6 +36,15 @@ WriteSaveBuf(uint8 *&buf, const T &value)
 	return p;
 }
 
+#ifdef COMPATIBLE_SAVES
+inline void
+ZeroSaveBuf(uint8 *&buf, uint32 length)
+{
+	memset(buf, 0, length);
+	SkipSaveBuf(buf, length);
+}
+#endif
+
 #define SAVE_HEADER_SIZE (4 * sizeof(char) + sizeof(uint32))
 
 #define WriteSaveHeader(buf, a, b, c, d, size) \
diff --git a/src/skel/crossplatform.cpp b/src/skel/crossplatform.cpp
index 1d49ebd2..577983b6 100644
--- a/src/skel/crossplatform.cpp
+++ b/src/skel/crossplatform.cpp
@@ -155,6 +155,29 @@ FILE* _fcaseopen(char const* filename, char const* mode)
     return result;
 }
 
+int _caserename(const char *old_filename, const char *new_filename)
+{
+    int result;
+    char *real_old = casepath(old_filename);
+    char *real_new = casepath(new_filename);
+
+    // hack so we don't even try to rename it to new_filename if it already exists
+    if (!real_new) {
+        free(real_old);
+        return -1;
+    }
+
+    if (!real_old)
+        result = rename(old_filename, real_new);
+    else
+        result = rename(real_old, real_new);
+
+    free(real_old);
+    free(real_new);
+
+    return result;
+}
+
 // Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
 // Returned string should freed manually (if exists)
 char* casepath(char const* path, bool checkPathFirst)
diff --git a/src/skel/crossplatform.h b/src/skel/crossplatform.h
index 2dd9c162..aa90ce5a 100644
--- a/src/skel/crossplatform.h
+++ b/src/skel/crossplatform.h
@@ -29,6 +29,7 @@ enum eWinVersion
 #endif
 extern DWORD _dwOperatingSystemVersion;
 #define fcaseopen fopen
+#define caserename rename
 #else
 char *strupr(char *str);
 char *strlwr(char *str);
@@ -51,6 +52,8 @@ extern long _dwOperatingSystemVersion;
 char *casepath(char const *path, bool checkPathFirst = true);
 FILE *_fcaseopen(char const *filename, char const *mode);
 #define fcaseopen _fcaseopen
+int _caserename(const char *old_filename, const char *new_filename);
+#define caserename _caserename
 #endif
 
 #ifdef RW_GL3
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 3de3e12b..7d942dcd 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -4717,8 +4717,8 @@ void
 CAutomobile::Save(uint8*& buf)
 {
 	CVehicle::Save(buf);
-	WriteSaveBuf<CDamageManager>(buf, Damage);
-	SkipSaveBuf(buf, 800 - sizeof(CDamageManager));
+	WriteSaveBuf(buf, Damage);
+	ZeroSaveBuf(buf, 800 - sizeof(CDamageManager));
 }
 
 void
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 88444e95..65cdd8c6 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -940,7 +940,7 @@ void
 CBoat::Save(uint8*& buf)
 {
 	CVehicle::Save(buf);
-	SkipSaveBuf(buf, 1156 - 648);
+	ZeroSaveBuf(buf, 1156 - 648);
 }
 
 void
diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp
index 0f1b8b4c..db9d2e00 100644
--- a/src/vehicles/Cranes.cpp
+++ b/src/vehicles/Cranes.cpp
@@ -37,6 +37,12 @@
 #define MIN_VALID_POSITION (-10000.0f)
 #define DEFAULT_OFFSET (20.0f)
 
+#ifdef COMPATIBLE_SAVES
+#define CRANES_SAVE_SIZE 0x400
+#else
+#define CRANES_SAVE_SIZE sizeof(aCranes)
+#endif
+
 uint32 TimerForCamInterpolation;
 
 uint32 CCranes::CarsCollectedMilitaryCrane;
@@ -634,10 +640,46 @@ void CCranes::Save(uint8* buf, uint32* size)
 {
 	INITSAVEBUF
 
-	*size = 2 * sizeof(uint32) + sizeof(aCranes);
+	*size = 2 * sizeof(uint32) + CRANES_SAVE_SIZE;
 	WriteSaveBuf(buf, NumCranes);
 	WriteSaveBuf(buf, CarsCollectedMilitaryCrane);
 	for (int i = 0; i < NUM_CRANES; i++) {
+#ifdef COMPATIBLE_SAVES
+		int32 tmp = aCranes[i].m_pCraneEntity != nil ? CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(aCranes[i].m_pCraneEntity) + 1 : 0;
+		WriteSaveBuf(buf, tmp);
+		tmp = aCranes[i].m_pHook != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aCranes[i].m_pHook) + 1 : 0;
+		WriteSaveBuf(buf, tmp);
+		WriteSaveBuf(buf, aCranes[i].m_nAudioEntity);
+		WriteSaveBuf(buf, aCranes[i].m_fPickupX1);
+		WriteSaveBuf(buf, aCranes[i].m_fPickupX2);
+		WriteSaveBuf(buf, aCranes[i].m_fPickupY1);
+		WriteSaveBuf(buf, aCranes[i].m_fPickupY2);
+		WriteSaveBuf(buf, aCranes[i].m_vecDropoffTarget);
+		WriteSaveBuf(buf, aCranes[i].m_fDropoffHeading);
+		WriteSaveBuf(buf, aCranes[i].m_fPickupAngle);
+		WriteSaveBuf(buf, aCranes[i].m_fDropoffAngle);
+		WriteSaveBuf(buf, aCranes[i].m_fPickupDistance);
+		WriteSaveBuf(buf, aCranes[i].m_fDropoffDistance);
+		WriteSaveBuf(buf, aCranes[i].m_fPickupHeight);
+		WriteSaveBuf(buf, aCranes[i].m_fDropoffHeight);
+		WriteSaveBuf(buf, aCranes[i].m_fHookAngle);
+		WriteSaveBuf(buf, aCranes[i].m_fHookOffset);
+		WriteSaveBuf(buf, aCranes[i].m_fHookHeight);
+		WriteSaveBuf(buf, aCranes[i].m_vecHookInitPos);
+		WriteSaveBuf(buf, aCranes[i].m_vecHookCurPos);
+		WriteSaveBuf(buf, aCranes[i].m_vecHookVelocity);
+		tmp = aCranes[i].m_pVehiclePickedUp != nil ? CPools::GetVehiclePool()->GetJustIndex_NoFreeAssert(aCranes[i].m_pVehiclePickedUp) + 1 : 0;
+		WriteSaveBuf(buf, tmp);
+		WriteSaveBuf(buf, aCranes[i].m_nTimeForNextCheck);
+		WriteSaveBuf(buf, aCranes[i].m_nCraneStatus);
+		WriteSaveBuf(buf, aCranes[i].m_nCraneState);
+		WriteSaveBuf(buf, aCranes[i].m_nVehiclesCollected);
+		WriteSaveBuf(buf, aCranes[i].m_bIsCrusher);
+		WriteSaveBuf(buf, aCranes[i].m_bIsMilitaryCrane);
+		WriteSaveBuf(buf, aCranes[i].m_bWasMilitaryCrane);
+		WriteSaveBuf(buf, aCranes[i].m_bIsTop);
+		ZeroSaveBuf(buf, 1);
+#else
 		CCrane *pCrane = WriteSaveBuf(buf, aCranes[i]);
 		if (pCrane->m_pCraneEntity != nil)
 			pCrane->m_pCraneEntity = (CBuilding*)(CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(pCrane->m_pCraneEntity) + 1);
@@ -645,6 +687,7 @@ void CCranes::Save(uint8* buf, uint32* size)
 			pCrane->m_pHook = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pCrane->m_pHook) + 1);
 		if (pCrane->m_pVehiclePickedUp != nil)
 			pCrane->m_pVehiclePickedUp = (CVehicle*)(CPools::GetVehiclePool()->GetJustIndex_NoFreeAssert(pCrane->m_pVehiclePickedUp) + 1);
+#endif
 	}
 
 	VALIDATESAVEBUF(*size);
@@ -656,8 +699,46 @@ void CCranes::Load(uint8* buf, uint32 size)
 
 	ReadSaveBuf(&NumCranes, buf);
 	ReadSaveBuf(&CarsCollectedMilitaryCrane, buf);
-	for (int i = 0; i < NUM_CRANES; i++)
+	for (int i = 0; i < NUM_CRANES; i++) {
+#ifdef COMPATIBLE_SAVES
+		int32 tmp;
+		ReadSaveBuf(&tmp, buf);
+		aCranes[i].m_pCraneEntity = tmp != 0 ? CPools::GetBuildingPool()->GetSlot(tmp - 1) : nil;
+		ReadSaveBuf(&tmp, buf);
+		aCranes[i].m_pHook = tmp != 0 ? CPools::GetObjectPool()->GetSlot(tmp - 1) : nil;
+		ReadSaveBuf(&aCranes[i].m_nAudioEntity, buf);
+		ReadSaveBuf(&aCranes[i].m_fPickupX1, buf);
+		ReadSaveBuf(&aCranes[i].m_fPickupX2, buf);
+		ReadSaveBuf(&aCranes[i].m_fPickupY1, buf);
+		ReadSaveBuf(&aCranes[i].m_fPickupY2, buf);
+		ReadSaveBuf(&aCranes[i].m_vecDropoffTarget, buf);
+		ReadSaveBuf(&aCranes[i].m_fDropoffHeading, buf);
+		ReadSaveBuf(&aCranes[i].m_fPickupAngle, buf);
+		ReadSaveBuf(&aCranes[i].m_fDropoffAngle, buf);
+		ReadSaveBuf(&aCranes[i].m_fPickupDistance, buf);
+		ReadSaveBuf(&aCranes[i].m_fDropoffDistance, buf);
+		ReadSaveBuf(&aCranes[i].m_fPickupHeight, buf);
+		ReadSaveBuf(&aCranes[i].m_fDropoffHeight, buf);
+		ReadSaveBuf(&aCranes[i].m_fHookAngle, buf);
+		ReadSaveBuf(&aCranes[i].m_fHookOffset, buf);
+		ReadSaveBuf(&aCranes[i].m_fHookHeight, buf);
+		ReadSaveBuf(&aCranes[i].m_vecHookInitPos, buf);
+		ReadSaveBuf(&aCranes[i].m_vecHookCurPos, buf);
+		ReadSaveBuf(&aCranes[i].m_vecHookVelocity, buf);
+		ReadSaveBuf(&tmp, buf);
+		aCranes[i].m_pVehiclePickedUp = tmp != 0 ? CPools::GetVehiclePool()->GetSlot(tmp - 1) : nil;
+		ReadSaveBuf(&aCranes[i].m_nTimeForNextCheck, buf);
+		ReadSaveBuf(&aCranes[i].m_nCraneStatus, buf);
+		ReadSaveBuf(&aCranes[i].m_nCraneState, buf);
+		ReadSaveBuf(&aCranes[i].m_nVehiclesCollected, buf);
+		ReadSaveBuf(&aCranes[i].m_bIsCrusher, buf);
+		ReadSaveBuf(&aCranes[i].m_bIsMilitaryCrane, buf);
+		ReadSaveBuf(&aCranes[i].m_bWasMilitaryCrane, buf);
+		ReadSaveBuf(&aCranes[i].m_bIsTop, buf);
+		SkipSaveBuf(buf, 1);
+#else
 		ReadSaveBuf(&aCranes[i], buf);
+	}
 	for (int i = 0; i < NUM_CRANES; i++) {
 		CCrane *pCrane = &aCranes[i];
 		if (pCrane->m_pCraneEntity != nil)
@@ -666,6 +747,7 @@ void CCranes::Load(uint8* buf, uint32 size)
 			pCrane->m_pHook = CPools::GetObjectPool()->GetSlot((uintptr)pCrane->m_pHook - 1);
 		if (pCrane->m_pVehiclePickedUp != nil)
 			pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uintptr)pCrane->m_pVehiclePickedUp - 1);
+#endif
 	}
 	for (int i = 0; i < NUM_CRANES; i++) {
 		aCranes[i].m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[i]);
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index 3d3ba8f2..4259f9d8 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -1262,42 +1262,42 @@ DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle)
 void
 CVehicle::Save(uint8*& buf)
 {
-	SkipSaveBuf(buf, 4);
-	WriteSaveBuf<float>(buf, GetRight().x);
-	WriteSaveBuf<float>(buf, GetRight().y);
-	WriteSaveBuf<float>(buf, GetRight().z);
-	SkipSaveBuf(buf, 4);
-	WriteSaveBuf<float>(buf, GetForward().x);
-	WriteSaveBuf<float>(buf, GetForward().y);
-	WriteSaveBuf<float>(buf, GetForward().z);
-	SkipSaveBuf(buf, 4);
-	WriteSaveBuf<float>(buf, GetUp().x);
-	WriteSaveBuf<float>(buf, GetUp().y);
-	WriteSaveBuf<float>(buf, GetUp().z);
-	SkipSaveBuf(buf, 4);
-	WriteSaveBuf<float>(buf, GetPosition().x);
-	WriteSaveBuf<float>(buf, GetPosition().y);
-	WriteSaveBuf<float>(buf, GetPosition().z);
-	SkipSaveBuf(buf, 16);
+	ZeroSaveBuf(buf, 4);
+	WriteSaveBuf(buf, GetRight().x);
+	WriteSaveBuf(buf, GetRight().y);
+	WriteSaveBuf(buf, GetRight().z);
+	ZeroSaveBuf(buf, 4);
+	WriteSaveBuf(buf, GetForward().x);
+	WriteSaveBuf(buf, GetForward().y);
+	WriteSaveBuf(buf, GetForward().z);
+	ZeroSaveBuf(buf, 4);
+	WriteSaveBuf(buf, GetUp().x);
+	WriteSaveBuf(buf, GetUp().y);
+	WriteSaveBuf(buf, GetUp().z);
+	ZeroSaveBuf(buf, 4);
+	WriteSaveBuf(buf, GetPosition().x);
+	WriteSaveBuf(buf, GetPosition().y);
+	WriteSaveBuf(buf, GetPosition().z);
+	ZeroSaveBuf(buf, 16);
 	SaveEntityFlags(buf);
-	SkipSaveBuf(buf, 212);
+	ZeroSaveBuf(buf, 212);
 	AutoPilot.Save(buf);
-	WriteSaveBuf<int8>(buf, m_currentColour1);
-	WriteSaveBuf<int8>(buf, m_currentColour2);
-	SkipSaveBuf(buf, 2);
-	WriteSaveBuf<int16>(buf, m_nAlarmState);
-	SkipSaveBuf(buf, 43);
-	WriteSaveBuf<uint8>(buf, m_nNumMaxPassengers);
-	SkipSaveBuf(buf, 2);
-	WriteSaveBuf<float>(buf, field_1D0[0]);
-	WriteSaveBuf<float>(buf, field_1D0[1]);
-	WriteSaveBuf<float>(buf, field_1D0[2]);
-	WriteSaveBuf<float>(buf, field_1D0[3]);
-	SkipSaveBuf(buf, 8);
-	WriteSaveBuf<float>(buf, m_fSteerAngle);
-	WriteSaveBuf<float>(buf, m_fGasPedal);
-	WriteSaveBuf<float>(buf, m_fBrakePedal);
-	WriteSaveBuf<uint8>(buf, VehicleCreatedBy);
+	WriteSaveBuf(buf, m_currentColour1);
+	WriteSaveBuf(buf, m_currentColour2);
+	ZeroSaveBuf(buf, 2);
+	WriteSaveBuf(buf, m_nAlarmState);
+	ZeroSaveBuf(buf, 43);
+	WriteSaveBuf(buf, m_nNumMaxPassengers);
+	ZeroSaveBuf(buf, 2);
+	WriteSaveBuf(buf, field_1D0[0]);
+	WriteSaveBuf(buf, field_1D0[1]);
+	WriteSaveBuf(buf, field_1D0[2]);
+	WriteSaveBuf(buf, field_1D0[3]);
+	ZeroSaveBuf(buf, 8);
+	WriteSaveBuf(buf, m_fSteerAngle);
+	WriteSaveBuf(buf, m_fGasPedal);
+	WriteSaveBuf(buf, m_fBrakePedal);
+	WriteSaveBuf(buf, VehicleCreatedBy);
 	uint8 flags = 0;
 	if (bIsLawEnforcer) flags |= BIT(0);
 	if (bIsLocked) flags |= BIT(3);
@@ -1305,19 +1305,19 @@ CVehicle::Save(uint8*& buf)
 	if (bIsHandbrakeOn) flags |= BIT(5);
 	if (bLightsOn) flags |= BIT(6);
 	if (bFreebies) flags |= BIT(7);
-	WriteSaveBuf<uint8>(buf, flags);
-	SkipSaveBuf(buf, 10);
-	WriteSaveBuf<float>(buf, m_fHealth);
-	WriteSaveBuf<uint8>(buf, m_nCurrentGear);
-	SkipSaveBuf(buf, 3);
-	WriteSaveBuf<float>(buf, m_fChangeGearTime);
-	SkipSaveBuf(buf, 4);
-	WriteSaveBuf<uint32>(buf, m_nTimeOfDeath);
-	SkipSaveBuf(buf, 2);
-	WriteSaveBuf<int16>(buf, m_nBombTimer);
-	SkipSaveBuf(buf, 12);
-	WriteSaveBuf<int8>(buf, m_nDoorLock);
-	SkipSaveBuf(buf, 99);
+	WriteSaveBuf(buf, flags);
+	ZeroSaveBuf(buf, 10);
+	WriteSaveBuf(buf, m_fHealth);
+	WriteSaveBuf(buf, m_nCurrentGear);
+	ZeroSaveBuf(buf, 3);
+	WriteSaveBuf(buf, m_fChangeGearTime);
+	ZeroSaveBuf(buf, 4);
+	WriteSaveBuf(buf, m_nTimeOfDeath);
+	ZeroSaveBuf(buf, 2);
+	WriteSaveBuf(buf, m_nBombTimer);
+	ZeroSaveBuf(buf, 12);
+	WriteSaveBuf(buf, m_nDoorLock);
+	ZeroSaveBuf(buf, 96);
 }
 
 void
@@ -1379,8 +1379,7 @@ CVehicle::Load(uint8*& buf)
 	SkipSaveBuf(buf, 2);
 	ReadSaveBuf(&m_nBombTimer, buf);
 	SkipSaveBuf(buf, 12);
-	ReadSaveBuf(&flags, buf);
-	m_nDoorLock = (eCarLock)flags;
-	SkipSaveBuf(buf, 99);
+	ReadSaveBuf(&m_nDoorLock, buf);
+	SkipSaveBuf(buf, 96);
 }
 #endif
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index 43a85db8..6f0e9094 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -2337,7 +2337,7 @@ CWeapon::Save(uint8*& buf)
 	CopyToBuf(buf, m_nAmmoTotal);
 	CopyToBuf(buf, m_nTimer);
 	CopyToBuf(buf, m_bAddRotOffset);
-	SkipSaveBuf(buf, 3);
+	ZeroSaveBuf(buf, 3);
 }
 
 void