diff options
author | Sergeanur <s.anureev@yandex.ua> | 2019-10-11 01:51:25 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-11 01:51:25 +0300 |
commit | 0408b30a9ffba583f0437c294a98a2cecef74e1d (patch) | |
tree | 5fc346badb4cac417ea73b457831c3de89bc450f | |
parent | fd1edbc0c8923d8cd5385017a700bbaadbf7a63f (diff) | |
parent | aa173a454ceaa32b2bc752fa3648f06e64b90064 (diff) |
Merge pull request #229 from Sergeanur/SaveLoadTemplates
Added read/write template functions for save data
-rw-r--r-- | src/control/CarGen.cpp | 136 | ||||
-rw-r--r-- | src/control/CarGen.h | 4 | ||||
-rw-r--r-- | src/control/PathFind.cpp | 18 | ||||
-rw-r--r-- | src/control/PathFind.h | 4 | ||||
-rw-r--r-- | src/control/Phones.cpp | 43 | ||||
-rw-r--r-- | src/control/Phones.h | 4 | ||||
-rw-r--r-- | src/control/Pickups.cpp | 48 | ||||
-rw-r--r-- | src/control/Pickups.h | 4 | ||||
-rw-r--r-- | src/core/Streaming.cpp | 18 | ||||
-rw-r--r-- | src/core/common.h | 51 | ||||
-rw-r--r-- | src/core/config.h | 1 | ||||
-rw-r--r-- | src/peds/PedType.cpp | 57 | ||||
-rw-r--r-- | src/peds/PedType.h | 4 |
13 files changed, 199 insertions, 193 deletions
diff --git a/src/control/CarGen.cpp b/src/control/CarGen.cpp index 65a23c8c..49a96f50 100644 --- a/src/control/CarGen.cpp +++ b/src/control/CarGen.cpp @@ -187,48 +187,57 @@ bool CCarGenerator::CheckIfWithinRangeOfAnyPlayer() return DotProduct2D(direction, FindPlayerSpeed()) <= 0; } -void CCarGenerator::Save(uint8* buffer) +void CCarGenerator::Save(uint8 *&buffer) { - *(uint32*)(buffer) = m_nModelIndex; - *(CVector*)(buffer + 4) = m_vecPos; - *(float*)(buffer + 16) = m_fAngle; - *(int16*)(buffer + 20) = m_nColor1; - *(int16*)(buffer + 22) = m_nColor2; - *(bool*)(buffer + 24) = m_bForceSpawn; - *(uint8*)(buffer + 25) = m_nAlarm; - *(uint8*)(buffer + 26) = m_nDoorlock; - *(uint8*)(buffer + 27) = 0; - *(uint16*)(buffer + 28) = m_nMinDelay; - *(uint16*)(buffer + 30) = m_nMaxDelay; - *(uint32*)(buffer + 32) = m_nTimer; - *(int32*)(buffer + 36) = m_nVehicleHandle; - *(uint16*)(buffer + 40) = m_nUsesRemaining; - *(bool*)(buffer + 42) = m_bIsBlocking; - *(uint8*)(buffer + 43) = 0; - *(CVector*)(buffer + 44) = m_vecInf; - *(CVector*)(buffer + 56) = m_vecSup; - *(float*)(buffer + 68) = m_fSize; + WriteSaveBuf(buffer, m_nModelIndex); + WriteSaveBuf(buffer, m_vecPos); + WriteSaveBuf(buffer, m_fAngle); + WriteSaveBuf(buffer, m_nColor1); + WriteSaveBuf(buffer, m_nColor2); + WriteSaveBuf(buffer, m_bForceSpawn); + WriteSaveBuf(buffer, m_nAlarm); + WriteSaveBuf(buffer, m_nDoorlock); + WriteSaveBuf(buffer, (uint8)0); + WriteSaveBuf(buffer, m_nMinDelay); + WriteSaveBuf(buffer, m_nMaxDelay); + WriteSaveBuf(buffer, m_nTimer); + WriteSaveBuf(buffer, m_nVehicleHandle); + WriteSaveBuf(buffer, m_nUsesRemaining); + WriteSaveBuf(buffer, m_bIsBlocking); + WriteSaveBuf(buffer, (uint8)0); + WriteSaveBuf(buffer, m_vecInf); + WriteSaveBuf(buffer, m_vecSup); + WriteSaveBuf(buffer, m_fSize); + + // or + //WriteSaveBuf(buffer, *this); + } -void CCarGenerator::Load(uint8* buffer) +void CCarGenerator::Load(uint8 *&buffer) { - m_nModelIndex = *(uint32*)(buffer); - m_vecPos = *(CVector*)(buffer + 4); - m_fAngle = *(float*)(buffer + 16); - m_nColor1 = *(int16*)(buffer + 20); - m_nColor2 = *(int16*)(buffer + 22); - m_bForceSpawn = *(bool*)(buffer + 24); - m_nAlarm = *(uint8*)(buffer + 25); - m_nDoorlock = *(uint8*)(buffer + 26); - m_nMinDelay = *(uint16*)(buffer + 28); - m_nMaxDelay = *(uint16*)(buffer + 30); - m_nTimer = *(uint32*)(buffer + 32); - m_nVehicleHandle = *(int32*)(buffer + 36); - m_nUsesRemaining = *(uint16*)(buffer + 40); - m_bIsBlocking = *(bool*)(buffer + 42); - m_vecInf = *(CVector*)(buffer + 44); - m_vecSup = *(CVector*)(buffer + 56); - m_fSize = *(float*)(buffer + 68); + m_nModelIndex = ReadSaveBuf<uint32>(buffer); + m_vecPos = ReadSaveBuf<CVector>(buffer); + m_fAngle = ReadSaveBuf<float>(buffer); + m_nColor1 = ReadSaveBuf<int16>(buffer); + m_nColor2 = ReadSaveBuf<int16>(buffer); + m_bForceSpawn = ReadSaveBuf<uint8>(buffer); + m_nAlarm = ReadSaveBuf<uint8>(buffer); + m_nDoorlock = ReadSaveBuf<uint8>(buffer); + ReadSaveBuf<uint8>(buffer); + m_nMinDelay = ReadSaveBuf<uint16>(buffer); + m_nMaxDelay = ReadSaveBuf<uint16>(buffer); + m_nTimer = ReadSaveBuf<uint32>(buffer); + m_nVehicleHandle = ReadSaveBuf<int32>(buffer); + m_nUsesRemaining = ReadSaveBuf<uint16>(buffer); + m_bIsBlocking = ReadSaveBuf<bool>(buffer); + ReadSaveBuf<uint8>(buffer); + m_vecInf = ReadSaveBuf<CVector>(buffer); + m_vecSup = ReadSaveBuf<CVector>(buffer); + m_fSize = ReadSaveBuf<float>(buffer); + + // or + //*this = ReadSaveBuf<CCarGenerator>(buffer); } void CTheCarGenerators::Process() @@ -259,45 +268,40 @@ void CTheCarGenerators::Init() void CTheCarGenerators::SaveAllCarGenerators(uint8 *buffer, uint32 *size) { - *size = 28 + 72 * NUM_CARGENS; - buffer[0] = 'C'; - buffer[1] = 'G'; - buffer[2] = 'N'; - buffer[3] = '\0'; - *(uint32*)(buffer + 4) = *size - 8; - *(uint32*)(buffer + 8) = 12; /* what is this? */ - *(uint32*)(buffer + 12) = NumOfCarGenerators; - *(uint32*)(buffer + 16) = CurrentActiveCount; - *(uint8*)(buffer + 20) = ProcessCounter; - *(uint8*)(buffer + 21) = GenerateEvenIfPlayerIsCloseCounter; - *(uint16*)(buffer + 22) = 0; - *(uint32*)(buffer + 24) = 72 * NUM_CARGENS; - buffer += 28; + *size = 20 + sizeof(CarGeneratorArray) + SAVE_HEADER_SIZE; +INITSAVEBUF + WriteSaveHeader(buffer, 'C','G','N','\0', *size - SAVE_HEADER_SIZE); + + WriteSaveBuf(buffer, 12); /* what is this? */ + WriteSaveBuf(buffer, NumOfCarGenerators); + WriteSaveBuf(buffer, CurrentActiveCount); + WriteSaveBuf(buffer, ProcessCounter); + WriteSaveBuf(buffer, GenerateEvenIfPlayerIsCloseCounter); + WriteSaveBuf(buffer, (int16)0); + WriteSaveBuf(buffer, sizeof(CarGeneratorArray)); for (int i = 0; i < NUM_CARGENS; i++){ CarGeneratorArray[i].Save(buffer); - buffer += 72; } +VALIDATESAVEBUF(*size) } void CTheCarGenerators::LoadAllCarGenerators(uint8* buffer, uint32 size) { Init(); - assert(size == 28 + NUM_CARGENS * 72); - assert(buffer[0] == 'C'); - assert(buffer[1] == 'G'); - assert(buffer[2] == 'N'); - assert(buffer[3] == '\0'); - assert(*(uint32*)(buffer + 4) == size - 8); - NumOfCarGenerators = *(uint32*)(buffer + 12); - CurrentActiveCount = *(uint32*)(buffer + 16); - ProcessCounter = *(uint8*)(buffer + 20); - GenerateEvenIfPlayerIsCloseCounter = *(uint8*)(buffer + 21); - assert(*(uint32*)(buffer + 24) == 72 * NUM_CARGENS); - buffer += 28; +INITSAVEBUF + assert(size == 20 + sizeof(CarGeneratorArray) + SAVE_HEADER_SIZE); + CheckSaveHeader(buffer, 'C','G','N','\0', size - SAVE_HEADER_SIZE); + ReadSaveBuf<uint32>(buffer); + NumOfCarGenerators = ReadSaveBuf<uint32>(buffer); + CurrentActiveCount = ReadSaveBuf<uint32>(buffer); + ProcessCounter = ReadSaveBuf<uint8>(buffer); + GenerateEvenIfPlayerIsCloseCounter = ReadSaveBuf<uint8>(buffer); + ReadSaveBuf<int16>(buffer); + assert(ReadSaveBuf<uint32>(buffer) == sizeof(CarGeneratorArray)); for (int i = 0; i < NUM_CARGENS; i++) { CarGeneratorArray[i].Load(buffer); - buffer += 72; } +VALIDATESAVEBUF(size) } STARTPATCHES diff --git a/src/control/CarGen.h b/src/control/CarGen.h index c1ca304c..75acdd56 100644 --- a/src/control/CarGen.h +++ b/src/control/CarGen.h @@ -34,8 +34,8 @@ public: void Setup(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay); bool CheckForBlockage(); bool CheckIfWithinRangeOfAnyPlayer(); - void Save(uint8*); - void Load(uint8*); + void Save(uint8*&); + void Load(uint8*&); void SetUsesRemaining(uint16 uses) { m_nUsesRemaining = uses; } }; diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp index e9b33395..e9276dde 100644 --- a/src/control/PathFind.cpp +++ b/src/control/PathFind.cpp @@ -1409,40 +1409,40 @@ CPathFind::TestCoorsCloseness(CVector target, uint8 type, CVector start) } void -CPathFind::Save(uint8 *buffer, uint32 *length) +CPathFind::Save(uint8 *buf, uint32 *size) { int i; int n = m_numPathNodes/8 + 1; - *length = 2*n; + *size = 2*n; for(i = 0; i < m_numPathNodes; i++) if(m_pathNodes[i].bDisabled) - buffer[i/8] |= 1 << i%8; + buf[i/8] |= 1 << i%8; else - buffer[i/8] &= ~(1 << i%8); + buf[i/8] &= ~(1 << i%8); for(i = 0; i < m_numPathNodes; i++) if(m_pathNodes[i].bBetweenLevels) - buffer[i/8 + n] |= 1 << i%8; + buf[i/8 + n] |= 1 << i%8; else - buffer[i/8 + n] &= ~(1 << i%8); + buf[i/8 + n] &= ~(1 << i%8); } void -CPathFind::Load(uint8 *buffer, uint32 length) +CPathFind::Load(uint8 *buf, uint32 size) { int i; int n = m_numPathNodes/8 + 1; for(i = 0; i < m_numPathNodes; i++) - if(buffer[i/8] & (1 << i%8)) + if(buf[i/8] & (1 << i%8)) m_pathNodes[i].bDisabled = true; else m_pathNodes[i].bDisabled = false; for(i = 0; i < m_numPathNodes; i++) - if(buffer[i/8 + n] & (1 << i%8)) + if(buf[i/8 + n] & (1 << i%8)) m_pathNodes[i].bBetweenLevels = true; else m_pathNodes[i].bBetweenLevels = false; diff --git a/src/control/PathFind.h b/src/control/PathFind.h index 91e2e0b1..de30d70b 100644 --- a/src/control/PathFind.h +++ b/src/control/PathFind.h @@ -186,8 +186,8 @@ public: void FindNextNodeWandering(uint8, CVector, CPathNode**, CPathNode**, uint8, uint8*); void DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector target, CPathNode **nodes, int16 *numNodes, int16 maxNumNodes, CVehicle *vehicle, float *dist, float distLimit, int32 forcedTargetNode); bool TestCoorsCloseness(CVector target, uint8 type, CVector start); - void Save(uint8 *buffer, uint32 *length); - void Load(uint8 *buffer, uint32 length); + void Save(uint8 *buf, uint32 *size); + void Load(uint8 *buf, uint32 size); }; static_assert(sizeof(CPathFind) == 0x49bf4, "CPathFind: error"); diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp index e2a9ee13..f8005899 100644 --- a/src/control/Phones.cpp +++ b/src/control/Phones.cpp @@ -65,27 +65,19 @@ CPhoneInfo::IsMessageBeingDisplayed(int phoneId) } void -CPhoneInfo::Load(CPhoneInfo *source, uint8 buffer) +CPhoneInfo::Load(uint8 *buf, uint32 size) { - // Buffer isn't used. - - m_nMax = source->m_nMax; - m_nNum = source->m_nNum; - for (int phoneId = 0; phoneId < 50; phoneId++) { - CPhone *phone = &source->m_aPhones[phoneId]; - - m_aPhones[phoneId].m_vecPos = phone->m_vecPos; - memcpy(m_aPhones[phoneId].m_apMessages, phone->m_apMessages, sizeof(wchar*) * 6); - m_aPhones[phoneId].m_lastTimeRepeatedMsgShown = phone->m_lastTimeRepeatedMsgShown; - m_aPhones[phoneId].m_pEntity = phone->m_pEntity; - m_aPhones[phoneId].m_nState = phone->m_nState; - m_aPhones[phoneId].field_30 = phone->field_30; - +INITSAVEBUF + m_nMax = ReadSaveBuf<int32>(buf); + m_nNum = ReadSaveBuf<int32>(buf); + for (int i = 0; i < 50; i++) { + m_aPhones[i] = ReadSaveBuf<CPhone>(buf); // It's saved as building pool index in save file, convert it to true entity - if (phone->m_pEntity) { - m_aPhones[phoneId].m_pEntity = CPools::GetBuildingPool()->GetSlot((int)phone->m_pEntity - 1); + if (m_aPhones[i].m_pEntity) { + m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((int)m_aPhones[i].m_pEntity - 1); } } +VALIDATESAVEBUF(size) } void @@ -174,26 +166,21 @@ CPhoneInfo::Initialise(void) } void -CPhoneInfo::Save(CPhoneInfo *destination, uint32 *size) +CPhoneInfo::Save(uint8 *buf, uint32 *size) { *size = sizeof(CPhoneInfo); - destination->m_nMax = this->m_nMax; - destination->m_nNum = m_nNum; +INITSAVEBUF + WriteSaveBuf(buf, m_nMax); + WriteSaveBuf(buf, m_nNum); for(int phoneId = 0; phoneId < 50; phoneId++) { - CPhone* phone = &destination->m_aPhones[phoneId]; - - phone->m_vecPos = m_aPhones[phoneId].m_vecPos; - memcpy(phone->m_apMessages, m_aPhones[phoneId].m_apMessages, sizeof(wchar*) * 6); - phone->m_lastTimeRepeatedMsgShown = m_aPhones[phoneId].m_lastTimeRepeatedMsgShown; - phone->m_pEntity = m_aPhones[phoneId].m_pEntity; - phone->m_nState = m_aPhones[phoneId].m_nState; - phone->field_30 = m_aPhones[phoneId].field_30; + 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((CBuilding*)phone->m_pEntity) + 1); } } +VALIDATESAVEBUF(*size) } void diff --git a/src/control/Phones.h b/src/control/Phones.h index 35389f3f..6842eef4 100644 --- a/src/control/Phones.h +++ b/src/control/Phones.h @@ -49,12 +49,12 @@ public: bool PhoneAtThisPosition(CVector); bool HasMessageBeenDisplayed(int); bool IsMessageBeingDisplayed(int); - void Load(CPhoneInfo *source, uint8 buffer); + void Load(uint8 *buf, uint32 size); + void Save(uint8 *buf, uint32 *size); void SetPhoneMessage_JustOnce(int phoneId, wchar *msg1, wchar *msg2, wchar *msg3, wchar *msg4, wchar *msg5, wchar *msg6); void SetPhoneMessage_Repeatedly(int phoneId, wchar *msg1, wchar *msg2, wchar *msg3, wchar *msg4, wchar *msg5, wchar *msg6); int GrabPhone(float, float); void Initialise(void); - void Save(CPhoneInfo*, uint32*); void Shutdown(void); }; diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index d77975e6..0646e0f6 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -961,53 +961,47 @@ CPickups::RenderPickUpText() }
void
-CPickups::Load(uint8 *buffer, uint32 size)
+CPickups::Load(uint8 *buf, uint32 size)
{
+INITSAVEBUF
+
for (int32 i = 0; i < NUMPICKUPS; i++) {
- CPickup *buf_pickup = (CPickup*)buffer;
- aPickUps[i] = *buf_pickup;
+ aPickUps[i] = ReadSaveBuf<CPickup>(buf);
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil)
aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((int32)aPickUps[i].m_pObject - 1);
-
- buffer += sizeof(CPickup);
}
- CollectedPickUpIndex = *(uint16*)buffer;
- buffer += sizeof(uint16);
+ CollectedPickUpIndex = ReadSaveBuf<uint16>(buf);
+ ReadSaveBuf<uint16>(buf);
NumMessages = 0;
- buffer += sizeof(uint16);
- for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++) {
- aPickUpsCollected[i] = *(int32*)buffer;
- buffer += sizeof(int32);
- }
+ for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
+ aPickUpsCollected[i] = ReadSaveBuf<int32>(buf);
+
+VALIDATESAVEBUF(size)
}
void
-CPickups::Save(uint8 *buffer, uint32 *size)
+CPickups::Save(uint8 *buf, uint32 *size)
{
- *size = sizeof(CPickup) * NUMPICKUPS;
- *size += sizeof(uint32) * NUMCOLLECTEDPICKUPS + 4;
+ *size = sizeof(CPickup) * NUMPICKUPS + sizeof(uint16) + sizeof(uint16) + sizeof(uint32) * NUMCOLLECTEDPICKUPS;
+
+INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
- CPickup *buf_pickup = (CPickup*)buffer;
- *buf_pickup = aPickUps[i];
+ 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(buf_pickup->m_pObject) + 1);
-
- buffer += sizeof(CPickup);
}
- *(uint16*)buffer = CollectedPickUpIndex;
- buffer += sizeof(uint16);
- *(uint16*)buffer = 0; // possibly was NumMessages
- buffer += sizeof(uint16);
+ WriteSaveBuf(buf, CollectedPickUpIndex);
+ WriteSaveBuf(buf, (uint16)0); // possibly was NumMessages
- for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++) {
- *(int32*)buffer = aPickUpsCollected[i];
- buffer += sizeof(int32);
- }
+ for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
+ WriteSaveBuf(buf, aPickUpsCollected[i]);
+
+VALIDATESAVEBUF(*size)
}
STARTPATCHES
diff --git a/src/control/Pickups.h b/src/control/Pickups.h index b49a5544..cbf3f245 100644 --- a/src/control/Pickups.h +++ b/src/control/Pickups.h @@ -86,8 +86,8 @@ public: static int32 GetNewUniquePickupIndex(int32 slot);
static void PassTime(uint32 time);
static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex);
- static void Load(uint8 *buffer, uint32 size);
- static void Save(uint8 *buffer, uint32 *size);
+ static void Load(uint8 *buf, uint32 size);
+ static void Save(uint8 *buf, uint32 *size);
static CPickup(&aPickUps)[NUMPICKUPS];
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index e59b2b39..d9dc8628 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -2401,28 +2401,28 @@ CStreaming::LoadScene(const CVector &pos) } void -CStreaming::MemoryCardSave(uint8 *buffer, uint32 *length) +CStreaming::MemoryCardSave(uint8 *buf, uint32 *size) { int i; - *length = NUM_DEFAULT_MODELS; + *size = NUM_DEFAULT_MODELS; for(i = 0; i < NUM_DEFAULT_MODELS; i++) if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED) - buffer[i] = ms_aInfoForModel[i].m_flags; + buf[i] = ms_aInfoForModel[i].m_flags; else - buffer[i] = 0xFF; + buf[i] = 0xFF; } void -CStreaming::MemoryCardLoad(uint8 *buffer, uint32 length) +CStreaming::MemoryCardLoad(uint8 *buf, uint32 size) { uint32 i; - assert(length == NUM_DEFAULT_MODELS); - for(i = 0; i < length; i++) + assert(size == NUM_DEFAULT_MODELS); + for(i = 0; i < size; i++) if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED) - if(buffer[i] != 0xFF) - ms_aInfoForModel[i].m_flags = buffer[i]; + if(buf[i] != 0xFF) + ms_aInfoForModel[i].m_flags = buf[i]; } void diff --git a/src/core/common.h b/src/core/common.h index caa305d6..3ea37071 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -317,3 +317,54 @@ _TWEEKCLASS(CTweakUInt32, uint32); _TWEEKCLASS(CTweakFloat, float); #undef _TWEEKCLASS + +#ifdef VALIDATE_SAVE_SIZE +static int32 _bufBytesRead; +#define INITSAVEBUF _bufBytesRead = 0; +#define VALIDATESAVEBUF(b) assert(_bufBytesRead == b); +#else +#define INITSAVEBUF +#define VALIDATESAVEBUF(b) +#endif + +inline void SkipSaveBuf(uint8 *&buf, int32 skip) +{ + buf += skip; +#ifdef VALIDATE_SAVE_SIZE + _bufBytesRead += skip; +#endif +} + +template<typename T> +inline const T ReadSaveBuf(uint8 *&buf) +{
+ T &value = *(T*)buf; + SkipSaveBuf(buf, sizeof(T)); + return value; +} + +template<typename T> +inline T *WriteSaveBuf(uint8 *&buf, const T &value) +{
+ T *p = (T*)buf;
+ *p = value; + SkipSaveBuf(buf, sizeof(T)); + return p; +} + + +#define SAVE_HEADER_SIZE (4*sizeof(char)+sizeof(uint32)) + +#define WriteSaveHeader(buf,a,b,c,d,size) \
+ WriteSaveBuf(buf, a);\
+ WriteSaveBuf(buf, b);\
+ WriteSaveBuf(buf, c);\
+ WriteSaveBuf(buf, d);\
+ WriteSaveBuf(buf, size); + +#define CheckSaveHeader(buf,a,b,c,d,size)\ + assert(ReadSaveBuf<char>(buf) == a);\ + assert(ReadSaveBuf<char>(buf) == b);\ + assert(ReadSaveBuf<char>(buf) == c);\ + assert(ReadSaveBuf<char>(buf) == d);\ + assert(ReadSaveBuf<uint32>(buf) == size);
\ No newline at end of file diff --git a/src/core/config.h b/src/core/config.h index a3fbac1b..08ddd007 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -126,6 +126,7 @@ enum Config { // only in master builds #else // not in master builds + #define VALIDATE_SAVE_SIZE #endif #ifdef FINAL diff --git a/src/peds/PedType.cpp b/src/peds/PedType.cpp index 66eb49a1..a8e052c7 100644 --- a/src/peds/PedType.cpp +++ b/src/peds/PedType.cpp @@ -181,56 +181,25 @@ CPedType::FindPedFlag(char *type) } void -CPedType::Save(uint8 *buffer, uint32 *length) +CPedType::Save(uint8 *buf, uint32 *size) { - int i; - - *length = 8 + NUM_PEDTYPES*32; - - buffer[0] = 'P'; - buffer[1] = 'T'; - buffer[2] = 'P'; - buffer[3] = '\0'; - *(uint32*)(buffer+4) = *length - 8; - buffer += 8; - - for(i = 0; i < NUM_PEDTYPES; i++){ - *(uint32*)(buffer) = ms_apPedType[i]->m_flag; - *(float*)(buffer+4) = ms_apPedType[i]->unknown1; - *(float*)(buffer+8) = ms_apPedType[i]->unknown2; - *(float*)(buffer+12) = ms_apPedType[i]->unknown3; - *(float*)(buffer+16) = ms_apPedType[i]->unknown4; - *(float*)(buffer+20) = ms_apPedType[i]->unknown5; - *(uint32*)(buffer+24) = ms_apPedType[i]->m_threats; - *(uint32*)(buffer+28) = ms_apPedType[i]->m_avoid; - buffer += 32; - } + *size = sizeof(CPedType) * NUM_PEDTYPES + SAVE_HEADER_SIZE; +INITSAVEBUF + WriteSaveHeader(buf, 'P','T','P','\0', *size - SAVE_HEADER_SIZE); + for(int i = 0; i < NUM_PEDTYPES; i++) + WriteSaveBuf(buf, *ms_apPedType[i]); +VALIDATESAVEBUF(*size) } void -CPedType::Load(uint8 *buffer, uint32 length) +CPedType::Load(uint8 *buf, uint32 size) { - int i; - - assert(length == 8 + NUM_PEDTYPES*32); - assert(buffer[0] == 'P'); - assert(buffer[1] == 'T'); - assert(buffer[2] == 'P'); - assert(buffer[3] == '\0'); - assert(*(uint32*)(buffer+4) == length - 8); - buffer += 8; +INITSAVEBUF + CheckSaveHeader(buf, 'P','T','P','\0', size - SAVE_HEADER_SIZE); - for(i = 0; i < NUM_PEDTYPES; i++){ - ms_apPedType[i]->m_flag = *(uint32*)(buffer); - ms_apPedType[i]->unknown1 = *(float*)(buffer+4); - ms_apPedType[i]->unknown2 = *(float*)(buffer+8); - ms_apPedType[i]->unknown3 = *(float*)(buffer+12); - ms_apPedType[i]->unknown4 = *(float*)(buffer+16); - ms_apPedType[i]->unknown5 = *(float*)(buffer+20); - ms_apPedType[i]->m_threats = *(uint32*)(buffer+24); - ms_apPedType[i]->m_avoid = *(uint32*)(buffer+28); - buffer += 32; - } + for(int i = 0; i < NUM_PEDTYPES; i++) + *ms_apPedType[i] = ReadSaveBuf<CPedType>(buf); +VALIDATESAVEBUF(size) } STARTPATCHES diff --git a/src/peds/PedType.h b/src/peds/PedType.h index 455d8d8d..9d284318 100644 --- a/src/peds/PedType.h +++ b/src/peds/PedType.h @@ -79,8 +79,8 @@ public: static void LoadPedData(void); static int32 FindPedType(char *type); static uint32 FindPedFlag(char *type); - static void Save(uint8 *buffer, uint32 *length); - static void Load(uint8 *buffer, uint32 length); + static void Save(uint8 *buf, uint32 *size); + static void Load(uint8 *buf, uint32 size); static uint32 GetFlag(int type) { return ms_apPedType[type]->m_flag; } static uint32 GetAvoid(int type) { return ms_apPedType[type]->m_avoid; } |