Merge pull request #759 from Sergeanur/VC/ZoneSaveLoad

Zones saving and loading
This commit is contained in:
Sergeanur 2020-10-12 04:16:30 +03:00 committed by GitHub
commit 239e09ad07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 136 additions and 89 deletions

View File

@ -9,7 +9,7 @@
#include "World.h" #include "World.h"
#include "Timer.h" #include "Timer.h"
//--MIAMI: file almost done (loading/saving will perhaps stay different) //--MIAMI: file done
eLevelName CTheZones::m_CurrLevel; eLevelName CTheZones::m_CurrLevel;
int16 CTheZones::FindIndex; int16 CTheZones::FindIndex;
@ -638,127 +638,132 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
+ sizeof(int16) // padding + sizeof(int16) // padding
+ sizeof(NavigationZoneArray) + sizeof(InfoZoneArray) + sizeof(ZoneInfoArray) + sizeof(NavigationZoneArray) + sizeof(InfoZoneArray) + sizeof(ZoneInfoArray)
+ sizeof(TotalNumberOfNavigationZones) + sizeof(TotalNumberOfInfoZones) + sizeof(TotalNumberOfZoneInfos) + sizeof(TotalNumberOfNavigationZones) + sizeof(TotalNumberOfInfoZones) + sizeof(TotalNumberOfZoneInfos)
+ sizeof(int16) // padding
+ sizeof(MapZoneArray) + sizeof(AudioZoneArray) + sizeof(MapZoneArray) + sizeof(AudioZoneArray)
+ sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones); + sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones);
WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE); uint32 length = 0;
WriteSaveHeaderWithLength(buffer, length, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE);
WriteSaveBuf(buffer, m_CurrLevel); WriteSaveBuf(buffer, length, m_CurrLevel);
WriteSaveBuf(buffer, FindIndex); WriteSaveBuf(buffer, length, FindIndex);
WriteSaveBuf(buffer, (int16)0); // padding WriteSaveBuf(buffer, length, (int16)0); // padding
// TODO(MIAMI) ? implement SaveOneZone for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++)
for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){ SaveOneZone(&NavigationZoneArray[i], &buffer, &length, ZONE_NAVIG);
CZone *zone = WriteSaveBuf(buffer, NavigationZoneArray[i]);
zone->child = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].child);
zone->parent = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].parent);
zone->next = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].next);
}
for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){ for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++)
CZone *zone = WriteSaveBuf(buffer, InfoZoneArray[i]); SaveOneZone(&InfoZoneArray[i], &buffer, &length, ZONE_INFO);
/*
The call of GetIndexForZonePointer is wrong, as it is
meant for a different array, but the game doesn't brake
if those fields are nil. Let's make sure they are.
*/
assert(InfoZoneArray[i].child == nil);
assert(InfoZoneArray[i].parent == nil);
assert(InfoZoneArray[i].next == nil);
zone->child = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].child);
zone->parent = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].parent);
zone->next = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].next);
}
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++) for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
WriteSaveBuf(buffer, ZoneInfoArray[i]); WriteSaveBuf(buffer, length, ZoneInfoArray[i]);
WriteSaveBuf(buffer, TotalNumberOfNavigationZones); WriteSaveBuf(buffer, length, TotalNumberOfNavigationZones);
WriteSaveBuf(buffer, TotalNumberOfInfoZones); WriteSaveBuf(buffer, length, TotalNumberOfInfoZones);
WriteSaveBuf(buffer, TotalNumberOfZoneInfos); WriteSaveBuf(buffer, length, TotalNumberOfZoneInfos);
WriteSaveBuf(buffer, length, (int16)0); // padding
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) { for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++)
CZone* zone = WriteSaveBuf(buffer, MapZoneArray[i]); SaveOneZone(&MapZoneArray[i], &buffer, &length, ZONE_MAPZONE);
// see above
assert(MapZoneArray[i].child == nil);
assert(MapZoneArray[i].parent == nil);
assert(MapZoneArray[i].next == nil);
zone->child = (CZone*)GetIndexForZonePointer(MapZoneArray[i].child);
zone->parent = (CZone*)GetIndexForZonePointer(MapZoneArray[i].parent);
zone->next = (CZone*)GetIndexForZonePointer(MapZoneArray[i].next);
}
for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++) for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
WriteSaveBuf(buffer, AudioZoneArray[i]); WriteSaveBuf(buffer, length, AudioZoneArray[i]);
WriteSaveBuf(buffer, TotalNumberOfMapZones); WriteSaveBuf(buffer, length, TotalNumberOfMapZones);
WriteSaveBuf(buffer, NumberOfAudioZones); WriteSaveBuf(buffer, length, NumberOfAudioZones);
VALIDATESAVEBUF(*size) VALIDATESAVEBUF(*size)
} }
void
CTheZones::SaveOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType)
{
WriteSaveBuf(*buffer, *length, *(uint32*)&zone->name[0]);
WriteSaveBuf(*buffer, *length, *(uint32*)&zone->name[4]);
WriteSaveBuf(*buffer, *length, zone->minx);
WriteSaveBuf(*buffer, *length, zone->miny);
WriteSaveBuf(*buffer, *length, zone->minz);
WriteSaveBuf(*buffer, *length, zone->maxx);
WriteSaveBuf(*buffer, *length, zone->maxy);
WriteSaveBuf(*buffer, *length, zone->maxz);
WriteSaveBuf(*buffer, *length, zone->type);
WriteSaveBuf(*buffer, *length, zone->level);
WriteSaveBuf(*buffer, *length, zone->zoneinfoDay);
WriteSaveBuf(*buffer, *length, zone->zoneinfoNight);
int32 zoneId;
zoneId = GetIndexForZonePointer(zone->child);
WriteSaveBuf(*buffer, *length, zoneId);
zoneId = GetIndexForZonePointer(zone->parent);
WriteSaveBuf(*buffer, *length, zoneId);
zoneId = GetIndexForZonePointer(zone->next);
WriteSaveBuf(*buffer, *length, zoneId);
}
void void
CTheZones::LoadAllZones(uint8 *buffer, uint32 size) CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
{ {
INITSAVEBUF INITSAVEBUF
int i; int i;
CheckSaveHeader(buffer, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE); uint32 length = 0;
CheckSaveHeaderWithLength(buffer, length, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE);
m_CurrLevel = ReadSaveBuf<eLevelName>(buffer); m_CurrLevel = ReadSaveBuf<eLevelName>(buffer, length);
FindIndex = ReadSaveBuf<int16>(buffer); FindIndex = ReadSaveBuf<int16>(buffer, length);
ReadSaveBuf<int16>(buffer); ReadSaveBuf<int16>(buffer, length);
// TODO(MIAMI) ? implement LoadOneZone for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++)
for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){ LoadOneZone(&NavigationZoneArray[i], &buffer, &length, ZONE_NAVIG);
NavigationZoneArray[i] = ReadSaveBuf<CZone>(buffer);
NavigationZoneArray[i].child = GetPointerForZoneIndex((uintptr)NavigationZoneArray[i].child); for (i = 0; i < ARRAY_SIZE(InfoZoneArray); i++)
NavigationZoneArray[i].parent = GetPointerForZoneIndex((uintptr)NavigationZoneArray[i].parent); LoadOneZone(&InfoZoneArray[i], &buffer, &length, ZONE_INFO);
NavigationZoneArray[i].next = GetPointerForZoneIndex((uintptr)NavigationZoneArray[i].next);
}
for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){
InfoZoneArray[i] = ReadSaveBuf<CZone>(buffer);
/*
The call of GetPointerForZoneIndex is wrong, as it is
meant for a different array, but the game doesn't brake
if save data stored is -1.
*/
InfoZoneArray[i].child = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].child);
InfoZoneArray[i].parent = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].parent);
InfoZoneArray[i].next = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].next);
assert(InfoZoneArray[i].child == nil);
assert(InfoZoneArray[i].parent == nil);
assert(InfoZoneArray[i].next == nil);
}
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++) for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
ZoneInfoArray[i] = ReadSaveBuf<CZoneInfo>(buffer); ZoneInfoArray[i] = ReadSaveBuf<CZoneInfo>(buffer, length);
TotalNumberOfNavigationZones = ReadSaveBuf<int16>(buffer); TotalNumberOfNavigationZones = ReadSaveBuf<int16>(buffer, length);
TotalNumberOfInfoZones = ReadSaveBuf<int16>(buffer); TotalNumberOfInfoZones = ReadSaveBuf<int16>(buffer, length);
TotalNumberOfZoneInfos = ReadSaveBuf<int16>(buffer); TotalNumberOfZoneInfos = ReadSaveBuf<int16>(buffer, length);
ReadSaveBuf<int16>(buffer, length);
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){ for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++)
MapZoneArray[i] = ReadSaveBuf<CZone>(buffer); LoadOneZone(&MapZoneArray[i], &buffer, &length, ZONE_MAPZONE);
// see above
MapZoneArray[i].child = GetPointerForZoneIndex((uintptr)MapZoneArray[i].child);
MapZoneArray[i].parent = GetPointerForZoneIndex((uintptr)MapZoneArray[i].parent);
MapZoneArray[i].next = GetPointerForZoneIndex((uintptr)MapZoneArray[i].next);
assert(MapZoneArray[i].child == nil);
assert(MapZoneArray[i].parent == nil);
assert(MapZoneArray[i].next == nil);
}
for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++) for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
AudioZoneArray[i] = ReadSaveBuf<int16>(buffer); AudioZoneArray[i] = ReadSaveBuf<int16>(buffer, length);
TotalNumberOfMapZones = ReadSaveBuf<uint16>(buffer); TotalNumberOfMapZones = ReadSaveBuf<uint16>(buffer, length);
NumberOfAudioZones = ReadSaveBuf<uint16>(buffer); NumberOfAudioZones = ReadSaveBuf<uint16>(buffer, length);
VALIDATESAVEBUF(size) VALIDATESAVEBUF(size)
} }
void
CTheZones::LoadOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType)
{
*(uint32*)&zone->name[0] = ReadSaveBuf<uint32>(*buffer, *length);
*(uint32*)&zone->name[4] = ReadSaveBuf<uint32>(*buffer, *length);
zone->minx = ReadSaveBuf<float>(*buffer, *length);
zone->miny = ReadSaveBuf<float>(*buffer, *length);
zone->minz = ReadSaveBuf<float>(*buffer, *length);
zone->maxx = ReadSaveBuf<float>(*buffer, *length);
zone->maxy = ReadSaveBuf<float>(*buffer, *length);
zone->maxz = ReadSaveBuf<float>(*buffer, *length);
zone->type = ReadSaveBuf<eZoneType>(*buffer, *length);
zone->level = ReadSaveBuf<eLevelName>(*buffer, *length);
zone->zoneinfoDay = ReadSaveBuf<int16>(*buffer, *length);
zone->zoneinfoNight = ReadSaveBuf<int16>(*buffer, *length);
int32 zoneId;
zoneId = ReadSaveBuf<int32>(*buffer, *length);
zone->child = GetPointerForZoneIndex(zoneId);
zoneId = ReadSaveBuf<int32>(*buffer, *length);
zone->parent = GetPointerForZoneIndex(zoneId);
zoneId = ReadSaveBuf<int32>(*buffer, *length);
zone->next = GetPointerForZoneIndex(zoneId);
}

View File

@ -108,5 +108,7 @@ public:
static void AddZoneToAudioZoneArray(CZone *zone); static void AddZoneToAudioZoneArray(CZone *zone);
static void InitialiseAudioZoneArray(void); static void InitialiseAudioZoneArray(void);
static void SaveAllZones(uint8 *buffer, uint32 *length); static void SaveAllZones(uint8 *buffer, uint32 *length);
static void SaveOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType);
static void LoadAllZones(uint8 *buffer, uint32 length); static void LoadAllZones(uint8 *buffer, uint32 length);
static void LoadOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType);
}; };

View File

@ -412,6 +412,15 @@ inline void SkipSaveBuf(uint8 *&buf, int32 skip)
#endif #endif
} }
inline void SkipSaveBuf(uint8*& buf, uint32 &length, int32 skip)
{
buf += skip;
length += skip;
#ifdef VALIDATE_SAVE_SIZE
_saveBufCount += skip;
#endif
}
template<typename T> template<typename T>
inline const T ReadSaveBuf(uint8 *&buf) inline const T ReadSaveBuf(uint8 *&buf)
{ {
@ -420,6 +429,14 @@ inline const T ReadSaveBuf(uint8 *&buf)
return value; return value;
} }
template<typename T>
inline const T ReadSaveBuf(uint8 *&buf, uint32 &length)
{
T &value = *(T*)buf;
SkipSaveBuf(buf, length, sizeof(T));
return value;
}
template<typename T> template<typename T>
inline T *WriteSaveBuf(uint8 *&buf, const T &value) inline T *WriteSaveBuf(uint8 *&buf, const T &value)
{ {
@ -429,6 +446,15 @@ inline T *WriteSaveBuf(uint8 *&buf, const T &value)
return p; return p;
} }
template<typename T>
inline T *WriteSaveBuf(uint8 *&buf, uint32 &length, const T &value)
{
T *p = (T*)buf;
*p = value;
SkipSaveBuf(buf, length, sizeof(T));
return p;
}
#define SAVE_HEADER_SIZE (4*sizeof(char)+sizeof(uint32)) #define SAVE_HEADER_SIZE (4*sizeof(char)+sizeof(uint32))
@ -439,6 +465,13 @@ inline T *WriteSaveBuf(uint8 *&buf, const T &value)
WriteSaveBuf(buf, d);\ WriteSaveBuf(buf, d);\
WriteSaveBuf<uint32>(buf, size); WriteSaveBuf<uint32>(buf, size);
#define WriteSaveHeaderWithLength(buf,len,a,b,c,d,size) \
WriteSaveBuf(buf, len, a);\
WriteSaveBuf(buf, len, b);\
WriteSaveBuf(buf, len, c);\
WriteSaveBuf(buf, len, d);\
WriteSaveBuf<uint32>(buf, len, size);
#define CheckSaveHeader(buf,a,b,c,d,size)\ #define CheckSaveHeader(buf,a,b,c,d,size)\
assert(ReadSaveBuf<char>(buf) == a);\ assert(ReadSaveBuf<char>(buf) == a);\
assert(ReadSaveBuf<char>(buf) == b);\ assert(ReadSaveBuf<char>(buf) == b);\
@ -446,5 +479,12 @@ inline T *WriteSaveBuf(uint8 *&buf, const T &value)
assert(ReadSaveBuf<char>(buf) == d);\ assert(ReadSaveBuf<char>(buf) == d);\
assert(ReadSaveBuf<uint32>(buf) == size); assert(ReadSaveBuf<uint32>(buf) == size);
#define CheckSaveHeaderWithLength(buf,len,a,b,c,d,size)\
assert(ReadSaveBuf<char>(buf,len) == a);\
assert(ReadSaveBuf<char>(buf,len) == b);\
assert(ReadSaveBuf<char>(buf,len) == c);\
assert(ReadSaveBuf<char>(buf,len) == d);\
assert(ReadSaveBuf<uint32>(buf,len) == size);
void cprintf(char*, ...); void cprintf(char*, ...);