Added read/write template functions for save data, small Load/Save arguments unification

This commit is contained in:
Sergeanur 2019-10-08 23:07:11 +03:00
parent 69963cea68
commit 101192dd32
12 changed files with 197 additions and 191 deletions

View File

@ -189,46 +189,55 @@ bool CCarGenerator::CheckIfWithinRangeOfAnyPlayer()
void CCarGenerator::Save(uint8 *buffer) void CCarGenerator::Save(uint8 *buffer)
{ {
*(uint32*)(buffer) = m_nModelIndex; WriteSaveBuf(buffer, m_nModelIndex);
*(CVector*)(buffer + 4) = m_vecPos; WriteSaveBuf(buffer, m_vecPos);
*(float*)(buffer + 16) = m_fAngle; WriteSaveBuf(buffer, m_fAngle);
*(int16*)(buffer + 20) = m_nColor1; WriteSaveBuf(buffer, m_nColor1);
*(int16*)(buffer + 22) = m_nColor2; WriteSaveBuf(buffer, m_nColor2);
*(bool*)(buffer + 24) = m_bForceSpawn; WriteSaveBuf(buffer, m_bForceSpawn);
*(uint8*)(buffer + 25) = m_nAlarm; WriteSaveBuf(buffer, m_nAlarm);
*(uint8*)(buffer + 26) = m_nDoorlock; WriteSaveBuf(buffer, m_nDoorlock);
*(uint8*)(buffer + 27) = 0; WriteSaveBuf(buffer, (uint8)0);
*(uint16*)(buffer + 28) = m_nMinDelay; WriteSaveBuf(buffer, m_nMinDelay);
*(uint16*)(buffer + 30) = m_nMaxDelay; WriteSaveBuf(buffer, m_nMaxDelay);
*(uint32*)(buffer + 32) = m_nTimer; WriteSaveBuf(buffer, m_nTimer);
*(int32*)(buffer + 36) = m_nVehicleHandle; WriteSaveBuf(buffer, m_nVehicleHandle);
*(uint16*)(buffer + 40) = m_nUsesRemaining; WriteSaveBuf(buffer, m_nUsesRemaining);
*(bool*)(buffer + 42) = m_bIsBlocking; WriteSaveBuf(buffer, m_bIsBlocking);
*(uint8*)(buffer + 43) = 0; WriteSaveBuf(buffer, (uint8)0);
*(CVector*)(buffer + 44) = m_vecInf; WriteSaveBuf(buffer, m_vecInf);
*(CVector*)(buffer + 56) = m_vecSup; WriteSaveBuf(buffer, m_vecSup);
*(float*)(buffer + 68) = m_fSize; WriteSaveBuf(buffer, m_fSize);
// or
//WriteSaveBuf(buffer, *this);
} }
void CCarGenerator::Load(uint8 *buffer) void CCarGenerator::Load(uint8 *buffer)
{ {
m_nModelIndex = *(uint32*)(buffer); m_nModelIndex = ReadSaveBuf<uint32>(buffer);
m_vecPos = *(CVector*)(buffer + 4); m_vecPos = ReadSaveBuf<CVector>(buffer);
m_fAngle = *(float*)(buffer + 16); m_fAngle = ReadSaveBuf<float>(buffer);
m_nColor1 = *(int16*)(buffer + 20); m_nColor1 = ReadSaveBuf<int16>(buffer);
m_nColor2 = *(int16*)(buffer + 22); m_nColor2 = ReadSaveBuf<int16>(buffer);
m_bForceSpawn = *(bool*)(buffer + 24); m_bForceSpawn = ReadSaveBuf<uint8>(buffer);
m_nAlarm = *(uint8*)(buffer + 25); m_nAlarm = ReadSaveBuf<uint8>(buffer);
m_nDoorlock = *(uint8*)(buffer + 26); m_nDoorlock = ReadSaveBuf<uint8>(buffer);
m_nMinDelay = *(uint16*)(buffer + 28); ReadSaveBuf<uint8>(buffer);
m_nMaxDelay = *(uint16*)(buffer + 30); m_nMinDelay = ReadSaveBuf<uint16>(buffer);
m_nTimer = *(uint32*)(buffer + 32); m_nMaxDelay = ReadSaveBuf<uint16>(buffer);
m_nVehicleHandle = *(int32*)(buffer + 36); m_nTimer = ReadSaveBuf<uint32>(buffer);
m_nUsesRemaining = *(uint16*)(buffer + 40); m_nVehicleHandle = ReadSaveBuf<int32>(buffer);
m_bIsBlocking = *(bool*)(buffer + 42); m_nUsesRemaining = ReadSaveBuf<uint16>(buffer);
m_vecInf = *(CVector*)(buffer + 44); m_bIsBlocking = ReadSaveBuf<bool>(buffer);
m_vecSup = *(CVector*)(buffer + 56); ReadSaveBuf<uint8>(buffer);
m_fSize = *(float*)(buffer + 68); m_vecInf = ReadSaveBuf<CVector>(buffer);
m_vecSup = ReadSaveBuf<CVector>(buffer);
m_fSize = ReadSaveBuf<float>(buffer);
// or
//*this = ReadSaveBuf<CCarGenerator>(buffer);
} }
void CTheCarGenerators::Process() void CTheCarGenerators::Process()
@ -259,45 +268,40 @@ void CTheCarGenerators::Init()
void CTheCarGenerators::SaveAllCarGenerators(uint8 *buffer, uint32 *size) void CTheCarGenerators::SaveAllCarGenerators(uint8 *buffer, uint32 *size)
{ {
*size = 28 + 72 * NUM_CARGENS; *size = 20 + sizeof(CarGeneratorArray) + SAVE_HEADER_SIZE;
buffer[0] = 'C'; INITSAVEBUF
buffer[1] = 'G'; WriteSaveHeader(buffer, 'C','G','N','\0', *size - SAVE_HEADER_SIZE);
buffer[2] = 'N';
buffer[3] = '\0'; WriteSaveBuf(buffer, 12); /* what is this? */
*(uint32*)(buffer + 4) = *size - 8; WriteSaveBuf(buffer, NumOfCarGenerators);
*(uint32*)(buffer + 8) = 12; /* what is this? */ WriteSaveBuf(buffer, CurrentActiveCount);
*(uint32*)(buffer + 12) = NumOfCarGenerators; WriteSaveBuf(buffer, ProcessCounter);
*(uint32*)(buffer + 16) = CurrentActiveCount; WriteSaveBuf(buffer, GenerateEvenIfPlayerIsCloseCounter);
*(uint8*)(buffer + 20) = ProcessCounter; WriteSaveBuf(buffer, (int16)0);
*(uint8*)(buffer + 21) = GenerateEvenIfPlayerIsCloseCounter; WriteSaveBuf(buffer, sizeof(CarGeneratorArray));
*(uint16*)(buffer + 22) = 0;
*(uint32*)(buffer + 24) = 72 * NUM_CARGENS;
buffer += 28;
for (int i = 0; i < NUM_CARGENS; i++){ for (int i = 0; i < NUM_CARGENS; i++){
CarGeneratorArray[i].Save(buffer); CarGeneratorArray[i].Save(buffer);
buffer += 72;
} }
VALIDATESAVEBUF(*size)
} }
void CTheCarGenerators::LoadAllCarGenerators(uint8* buffer, uint32 size) void CTheCarGenerators::LoadAllCarGenerators(uint8* buffer, uint32 size)
{ {
Init(); Init();
assert(size == 28 + NUM_CARGENS * 72); INITSAVEBUF
assert(buffer[0] == 'C'); assert(size == 20 + sizeof(CarGeneratorArray) + SAVE_HEADER_SIZE);
assert(buffer[1] == 'G'); CheckSaveHeader(buffer, 'C','G','N','\0', size - SAVE_HEADER_SIZE);
assert(buffer[2] == 'N'); ReadSaveBuf<uint32>(buffer);
assert(buffer[3] == '\0'); NumOfCarGenerators = ReadSaveBuf<uint32>(buffer);
assert(*(uint32*)(buffer + 4) == size - 8); CurrentActiveCount = ReadSaveBuf<uint32>(buffer);
NumOfCarGenerators = *(uint32*)(buffer + 12); ProcessCounter = ReadSaveBuf<uint8>(buffer);
CurrentActiveCount = *(uint32*)(buffer + 16); GenerateEvenIfPlayerIsCloseCounter = ReadSaveBuf<uint8>(buffer);
ProcessCounter = *(uint8*)(buffer + 20); ReadSaveBuf<int16>(buffer);
GenerateEvenIfPlayerIsCloseCounter = *(uint8*)(buffer + 21); assert(ReadSaveBuf<uint32>(buffer) == sizeof(CarGeneratorArray));
assert(*(uint32*)(buffer + 24) == 72 * NUM_CARGENS);
buffer += 28;
for (int i = 0; i < NUM_CARGENS; i++) { for (int i = 0; i < NUM_CARGENS; i++) {
CarGeneratorArray[i].Load(buffer); CarGeneratorArray[i].Load(buffer);
buffer += 72;
} }
VALIDATESAVEBUF(size)
} }
STARTPATCHES STARTPATCHES

View File

@ -1409,40 +1409,40 @@ CPathFind::TestCoorsCloseness(CVector target, uint8 type, CVector start)
} }
void void
CPathFind::Save(uint8 *buffer, uint32 *length) CPathFind::Save(uint8 *buf, uint32 *size)
{ {
int i; int i;
int n = m_numPathNodes/8 + 1; int n = m_numPathNodes/8 + 1;
*length = 2*n; *size = 2*n;
for(i = 0; i < m_numPathNodes; i++) for(i = 0; i < m_numPathNodes; i++)
if(m_pathNodes[i].bDisabled) if(m_pathNodes[i].bDisabled)
buffer[i/8] |= 1 << i%8; buf[i/8] |= 1 << i%8;
else else
buffer[i/8] &= ~(1 << i%8); buf[i/8] &= ~(1 << i%8);
for(i = 0; i < m_numPathNodes; i++) for(i = 0; i < m_numPathNodes; i++)
if(m_pathNodes[i].bBetweenLevels) if(m_pathNodes[i].bBetweenLevels)
buffer[i/8 + n] |= 1 << i%8; buf[i/8 + n] |= 1 << i%8;
else else
buffer[i/8 + n] &= ~(1 << i%8); buf[i/8 + n] &= ~(1 << i%8);
} }
void void
CPathFind::Load(uint8 *buffer, uint32 length) CPathFind::Load(uint8 *buf, uint32 size)
{ {
int i; int i;
int n = m_numPathNodes/8 + 1; int n = m_numPathNodes/8 + 1;
for(i = 0; i < m_numPathNodes; i++) 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; m_pathNodes[i].bDisabled = true;
else else
m_pathNodes[i].bDisabled = false; m_pathNodes[i].bDisabled = false;
for(i = 0; i < m_numPathNodes; i++) 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; m_pathNodes[i].bBetweenLevels = true;
else else
m_pathNodes[i].bBetweenLevels = false; m_pathNodes[i].bBetweenLevels = false;

View File

@ -186,8 +186,8 @@ public:
void FindNextNodeWandering(uint8, CVector, CPathNode**, CPathNode**, uint8, uint8*); 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); 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); bool TestCoorsCloseness(CVector target, uint8 type, CVector start);
void Save(uint8 *buffer, uint32 *length); void Save(uint8 *buf, uint32 *size);
void Load(uint8 *buffer, uint32 length); void Load(uint8 *buf, uint32 size);
}; };
static_assert(sizeof(CPathFind) == 0x49bf4, "CPathFind: error"); static_assert(sizeof(CPathFind) == 0x49bf4, "CPathFind: error");

View File

@ -65,27 +65,19 @@ CPhoneInfo::IsMessageBeingDisplayed(int phoneId)
} }
void void
CPhoneInfo::Load(CPhoneInfo *source, uint8 buffer) CPhoneInfo::Load(uint8 *buf, uint32 size)
{ {
// Buffer isn't used. INITSAVEBUF
m_nMax = ReadSaveBuf<int32>(buf);
m_nMax = source->m_nMax; m_nNum = ReadSaveBuf<int32>(buf);
m_nNum = source->m_nNum; for (int i = 0; i < 50; i++) {
for (int phoneId = 0; phoneId < 50; phoneId++) { m_aPhones[i] = ReadSaveBuf<CPhone>(buf);
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;
// It's saved as building pool index in save file, convert it to true entity // It's saved as building pool index in save file, convert it to true entity
if (phone->m_pEntity) { if (m_aPhones[i].m_pEntity) {
m_aPhones[phoneId].m_pEntity = CPools::GetBuildingPool()->GetSlot((int)phone->m_pEntity - 1); m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((int)m_aPhones[i].m_pEntity - 1);
} }
} }
VALIDATESAVEBUF(size)
} }
void void
@ -174,26 +166,21 @@ CPhoneInfo::Initialise(void)
} }
void void
CPhoneInfo::Save(CPhoneInfo *destination, uint32 *size) CPhoneInfo::Save(uint8 *buf, uint32 *size)
{ {
*size = sizeof(CPhoneInfo); *size = sizeof(CPhoneInfo);
destination->m_nMax = this->m_nMax; INITSAVEBUF
destination->m_nNum = m_nNum; WriteSaveBuf(buf, m_nMax);
WriteSaveBuf(buf, m_nNum);
for(int phoneId = 0; phoneId < 50; phoneId++) { for(int phoneId = 0; phoneId < 50; phoneId++) {
CPhone* phone = &destination->m_aPhones[phoneId]; CPhone* phone = WriteSaveBuf(buf, 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;
// Convert entity pointer to building pool index while saving // Convert entity pointer to building pool index while saving
if (phone->m_pEntity) { if (phone->m_pEntity) {
phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex((CBuilding*)phone->m_pEntity) + 1); phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex((CBuilding*)phone->m_pEntity) + 1);
} }
} }
VALIDATESAVEBUF(*size)
} }
void void

View File

@ -49,12 +49,12 @@ public:
bool PhoneAtThisPosition(CVector); bool PhoneAtThisPosition(CVector);
bool HasMessageBeenDisplayed(int); bool HasMessageBeenDisplayed(int);
bool IsMessageBeingDisplayed(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_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); void SetPhoneMessage_Repeatedly(int phoneId, wchar *msg1, wchar *msg2, wchar *msg3, wchar *msg4, wchar *msg5, wchar *msg6);
int GrabPhone(float, float); int GrabPhone(float, float);
void Initialise(void); void Initialise(void);
void Save(CPhoneInfo*, uint32*);
void Shutdown(void); void Shutdown(void);
}; };

View File

@ -961,53 +961,47 @@ CPickups::RenderPickUpText()
} }
void void
CPickups::Load(uint8 *buffer, uint32 size) CPickups::Load(uint8 *buf, uint32 size)
{ {
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) { for (int32 i = 0; i < NUMPICKUPS; i++) {
CPickup *buf_pickup = (CPickup*)buffer; aPickUps[i] = ReadSaveBuf<CPickup>(buf);
aPickUps[i] = *buf_pickup;
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil) 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); aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((int32)aPickUps[i].m_pObject - 1);
buffer += sizeof(CPickup);
} }
CollectedPickUpIndex = *(uint16*)buffer; CollectedPickUpIndex = ReadSaveBuf<uint16>(buf);
buffer += sizeof(uint16); ReadSaveBuf<uint16>(buf);
NumMessages = 0; NumMessages = 0;
buffer += sizeof(uint16);
for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++) { for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
aPickUpsCollected[i] = *(int32*)buffer; aPickUpsCollected[i] = ReadSaveBuf<int32>(buf);
buffer += sizeof(int32);
} VALIDATESAVEBUF(size)
} }
void void
CPickups::Save(uint8 *buffer, uint32 *size) CPickups::Save(uint8 *buf, uint32 *size)
{ {
*size = sizeof(CPickup) * NUMPICKUPS; *size = sizeof(CPickup) * NUMPICKUPS + sizeof(uint16) + sizeof(uint16) + sizeof(uint32) * NUMCOLLECTEDPICKUPS;
*size += sizeof(uint32) * NUMCOLLECTEDPICKUPS + 4;
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) { for (int32 i = 0; i < NUMPICKUPS; i++) {
CPickup *buf_pickup = (CPickup*)buffer; CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]);
*buf_pickup = aPickUps[i];
if (buf_pickup->m_eType != PICKUP_NONE && buf_pickup->m_pObject != nil) 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); buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex(buf_pickup->m_pObject) + 1);
buffer += sizeof(CPickup);
} }
*(uint16*)buffer = CollectedPickUpIndex; WriteSaveBuf(buf, CollectedPickUpIndex);
buffer += sizeof(uint16); WriteSaveBuf(buf, (uint16)0); // possibly was NumMessages
*(uint16*)buffer = 0; // possibly was NumMessages
buffer += sizeof(uint16);
for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++) { for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
*(int32*)buffer = aPickUpsCollected[i]; WriteSaveBuf(buf, aPickUpsCollected[i]);
buffer += sizeof(int32);
} VALIDATESAVEBUF(*size)
} }
STARTPATCHES STARTPATCHES

View File

@ -86,8 +86,8 @@ public:
static int32 GetNewUniquePickupIndex(int32 slot); static int32 GetNewUniquePickupIndex(int32 slot);
static void PassTime(uint32 time); static void PassTime(uint32 time);
static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex); static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex);
static void Load(uint8 *buffer, uint32 size); static void Load(uint8 *buf, uint32 size);
static void Save(uint8 *buffer, uint32 *size); static void Save(uint8 *buf, uint32 *size);
static CPickup(&aPickUps)[NUMPICKUPS]; static CPickup(&aPickUps)[NUMPICKUPS];

View File

@ -2401,28 +2401,28 @@ CStreaming::LoadScene(const CVector &pos)
} }
void void
CStreaming::MemoryCardSave(uint8 *buffer, uint32 *length) CStreaming::MemoryCardSave(uint8 *buf, uint32 *size)
{ {
int i; int i;
*length = NUM_DEFAULT_MODELS; *size = NUM_DEFAULT_MODELS;
for(i = 0; i < NUM_DEFAULT_MODELS; i++) for(i = 0; i < NUM_DEFAULT_MODELS; i++)
if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED) if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED)
buffer[i] = ms_aInfoForModel[i].m_flags; buf[i] = ms_aInfoForModel[i].m_flags;
else else
buffer[i] = 0xFF; buf[i] = 0xFF;
} }
void void
CStreaming::MemoryCardLoad(uint8 *buffer, uint32 length) CStreaming::MemoryCardLoad(uint8 *buf, uint32 size)
{ {
uint32 i; uint32 i;
assert(length == NUM_DEFAULT_MODELS); assert(size == NUM_DEFAULT_MODELS);
for(i = 0; i < length; i++) for(i = 0; i < size; i++)
if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED) if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED)
if(buffer[i] != 0xFF) if(buf[i] != 0xFF)
ms_aInfoForModel[i].m_flags = buffer[i]; ms_aInfoForModel[i].m_flags = buf[i];
} }
void void

View File

@ -317,3 +317,54 @@ _TWEEKCLASS(CTweakUInt32, uint32);
_TWEEKCLASS(CTweakFloat, float); _TWEEKCLASS(CTweakFloat, float);
#undef _TWEEKCLASS #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);

View File

@ -126,6 +126,7 @@ enum Config {
// only in master builds // only in master builds
#else #else
// not in master builds // not in master builds
#define VALIDATE_SAVE_SIZE
#endif #endif
#ifdef FINAL #ifdef FINAL

View File

@ -181,56 +181,25 @@ CPedType::FindPedFlag(char *type)
} }
void void
CPedType::Save(uint8 *buffer, uint32 *length) CPedType::Save(uint8 *buf, uint32 *size)
{ {
int i; *size = sizeof(CPedType) * NUM_PEDTYPES + SAVE_HEADER_SIZE;
INITSAVEBUF
*length = 8 + NUM_PEDTYPES*32; WriteSaveHeader(buf, 'P','T','P','\0', *size - SAVE_HEADER_SIZE);
for(int i = 0; i < NUM_PEDTYPES; i++)
buffer[0] = 'P'; WriteSaveBuf(buf, *ms_apPedType[i]);
buffer[1] = 'T'; VALIDATESAVEBUF(*size)
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;
}
} }
void void
CPedType::Load(uint8 *buffer, uint32 length) CPedType::Load(uint8 *buf, uint32 size)
{ {
int i; INITSAVEBUF
CheckSaveHeader(buf, 'P','T','P','\0', size - SAVE_HEADER_SIZE);
assert(length == 8 + NUM_PEDTYPES*32); for(int i = 0; i < NUM_PEDTYPES; i++)
assert(buffer[0] == 'P'); *ms_apPedType[i] = ReadSaveBuf<CPedType>(buf);
assert(buffer[1] == 'T'); VALIDATESAVEBUF(size)
assert(buffer[2] == 'P');
assert(buffer[3] == '\0');
assert(*(uint32*)(buffer+4) == length - 8);
buffer += 8;
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;
}
} }
STARTPATCHES STARTPATCHES

View File

@ -79,8 +79,8 @@ public:
static void LoadPedData(void); static void LoadPedData(void);
static int32 FindPedType(char *type); static int32 FindPedType(char *type);
static uint32 FindPedFlag(char *type); static uint32 FindPedFlag(char *type);
static void Save(uint8 *buffer, uint32 *length); static void Save(uint8 *buf, uint32 *size);
static void Load(uint8 *buffer, uint32 length); static void Load(uint8 *buf, uint32 size);
static uint32 GetFlag(int type) { return ms_apPedType[type]->m_flag; } static uint32 GetFlag(int type) { return ms_apPedType[type]->m_flag; }
static uint32 GetAvoid(int type) { return ms_apPedType[type]->m_avoid; } static uint32 GetAvoid(int type) { return ms_apPedType[type]->m_avoid; }