[openjk] 02/130: Add wrappers for writing saved games
Simon McVittie
smcv at debian.org
Fri Oct 28 11:09:10 UTC 2016
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to branch debian/master
in repository openjk.
commit 7d1b1e704fa5415b24f9bea8181c60d2a2f4d4a5
Author: bibendovsky <bibendovsky at NOSTROMO>
Date: Mon Jun 20 17:06:28 2016 +0300
Add wrappers for writing saved games
---
code/cgame/FxScheduler.cpp | 4 +-
code/cgame/cg_main.cpp | 4 +-
code/game/G_Timer.cpp | 6 +-
code/game/Q3_Interface.cpp | 20 +-
code/game/Q3_Interface.h | 2 +-
code/game/g_main.cpp | 4 +-
code/game/g_objectives.cpp | 2 +-
code/game/g_roff.cpp | 6 +-
code/game/g_savegame.cpp | 14 +-
code/icarus/IcarusImplementation.cpp | 6 +-
code/icarus/IcarusInterface.h | 2 +-
code/qcommon/cm_load.cpp | 2 +-
code/rd-vanilla/G2_misc.cpp | 39 +-
code/server/sv_savegame.cpp | 38 +-
codeJK2/cgame/cg_main.cpp | 4 +-
codeJK2/game/G_Timer.cpp | 8 +-
codeJK2/game/Q3_Interface.cpp | 2 +-
codeJK2/game/Q3_Registers.cpp | 20 +-
codeJK2/game/g_main.cpp | 4 +-
codeJK2/game/g_objectives.cpp | 2 +-
codeJK2/game/g_roff.cpp | 6 +-
codeJK2/game/g_savegame.cpp | 77 +++-
codeJK2/icarus/Instance.cpp | 16 +-
codeJK2/icarus/Sequence.cpp | 26 +-
codeJK2/icarus/Sequencer.cpp | 18 +-
codeJK2/icarus/TaskManager.cpp | 42 +-
codeJK2/icarus/interface.h | 2 +-
codemp/icarus/Q3_Interface.cpp | 2 +-
codemp/icarus/interface.h | 2 +-
shared/qcommon/ojk_sg_wrappers.h | 840 ++++++++++++++++++++++++++++++++++-
30 files changed, 1055 insertions(+), 165 deletions(-)
diff --git a/code/cgame/FxScheduler.cpp b/code/cgame/FxScheduler.cpp
index 020f29c..ae8800b 100644
--- a/code/cgame/FxScheduler.cpp
+++ b/code/cgame/FxScheduler.cpp
@@ -125,7 +125,7 @@ void CFxScheduler::LoadSave_Write()
{
// bsave the data we need...
//
- gi.AppendToSaveGame(INT_ID('F','X','L','E'), mLoopedEffectArray, sizeof(mLoopedEffectArray));
+ ::sg_write_no_cast(::gi, INT_ID('F','X','L','E'), mLoopedEffectArray);
//
// then cope with the fact that the mID field in each struct of the array we've just saved will not
// necessarily point at the same thing when reloading, so save out the actual fx filename strings they
@@ -157,7 +157,7 @@ void CFxScheduler::LoadSave_Write()
// write out this string...
//
- gi.AppendToSaveGame(INT_ID('F','X','F','N'), sFX_Filename, sizeof(sFX_Filename));
+ ::sg_write_no_cast(::gi, INT_ID('F','X','F','N'), sFX_Filename);
}
}
diff --git a/code/cgame/cg_main.cpp b/code/cgame/cg_main.cpp
index 732c9c7..b9646d5 100644
--- a/code/cgame/cg_main.cpp
+++ b/code/cgame/cg_main.cpp
@@ -1905,8 +1905,8 @@ static void CG_GameStateReceived( void ) {
void CG_WriteTheEvilCGHackStuff(void)
{
- gi.AppendToSaveGame(INT_ID('F','P','S','L'), &cg.forcepowerSelect, sizeof(cg.forcepowerSelect));
- gi.AppendToSaveGame(INT_ID('I','V','S','L'), &cg.inventorySelect, sizeof(cg.inventorySelect));
+ ::sg_write<int32_t>(::gi, INT_ID('F','P','S','L'), ::cg.forcepowerSelect);
+ ::sg_write<int32_t>(::gi, INT_ID('I','V','S','L'), ::cg.inventorySelect);
}
void CG_ReadTheEvilCGHackStuff(void)
diff --git a/code/game/G_Timer.cpp b/code/game/G_Timer.cpp
index 6591847..0835dde 100644
--- a/code/game/G_Timer.cpp
+++ b/code/game/G_Timer.cpp
@@ -171,7 +171,7 @@ void TIMER_Save( void )
}
//Write out the timer information
- gi.AppendToSaveGame(INT_ID('T','I','M','E'), (void *)&numTimers, sizeof(numTimers));
+ ::sg_write<uint8_t>(::gi, INT_ID('T','I','M','E'), numTimers);
gtimer_t *p = g_timers[j];
assert ((numTimers && p) || (!numTimers && !p));
@@ -185,10 +185,10 @@ void TIMER_Save( void )
assert( length < 1024 );//This will cause problems when loading the timer if longer
//Write out the id string
- gi.AppendToSaveGame(INT_ID('T','M','I','D'), (void *) timerID, length);
+ ::sg_write_no_cast(::gi, INT_ID('T','M','I','D'), timerID, length);
//Write out the timer data
- gi.AppendToSaveGame(INT_ID('T','D','T','A'), (void *) &time, sizeof( time ) );
+ ::sg_write<int32_t>(::gi, INT_ID('T','D','T','A'), time);
p = p->next;
}
}
diff --git a/code/game/Q3_Interface.cpp b/code/game/Q3_Interface.cpp
index 51b3e79..bb4e71d 100644
--- a/code/game/Q3_Interface.cpp
+++ b/code/game/Q3_Interface.cpp
@@ -7206,7 +7206,7 @@ VariableSaveFloats
void CQuake3GameInterface::VariableSaveFloats( varFloat_m &fmap )
{
int numFloats = fmap.size();
- gi.AppendToSaveGame( INT_ID('F','V','A','R'), &numFloats, sizeof( numFloats ) );
+ ::sg_write<int32_t>(::gi, INT_ID('F','V','A','R'), numFloats);
varFloat_m::iterator vfi;
STL_ITERATE( vfi, fmap )
@@ -7215,11 +7215,11 @@ void CQuake3GameInterface::VariableSaveFloats( varFloat_m &fmap )
int idSize = strlen( ((*vfi).first).c_str() );
//Save out the real data
- gi.AppendToSaveGame( INT_ID('F','I','D','L'), &idSize, sizeof( idSize ) );
- gi.AppendToSaveGame( INT_ID('F','I','D','S'), (void *) ((*vfi).first).c_str(), idSize );
+ ::sg_write<int32_t>(::gi, INT_ID('F','I','D','L'), idSize);
+ ::sg_write_no_cast(::gi, INT_ID('F','I','D','S'), ((*vfi).first).c_str(), idSize);
//Save out the float value
- gi.AppendToSaveGame( INT_ID('F','V','A','L'), &((*vfi).second), sizeof( float ) );
+ ::sg_write_no_cast(::gi, INT_ID('F','V','A','L'), (*vfi).second);
}
}
@@ -7232,7 +7232,7 @@ VariableSaveStrings
void CQuake3GameInterface::VariableSaveStrings( varString_m &smap )
{
int numStrings = smap.size();
- gi.AppendToSaveGame( INT_ID('S','V','A','R'), &numStrings, sizeof( numStrings ) );
+ ::sg_write<int32_t>(::gi, INT_ID('S','V','A','R'), numStrings);
varString_m::iterator vsi;
STL_ITERATE( vsi, smap )
@@ -7241,14 +7241,14 @@ void CQuake3GameInterface::VariableSaveStrings( varString_m &smap )
int idSize = strlen( ((*vsi).first).c_str() );
//Save out the real data
- gi.AppendToSaveGame( INT_ID('S','I','D','L'), &idSize, sizeof( idSize ) );
- gi.AppendToSaveGame( INT_ID('S','I','D','S'), (void *) ((*vsi).first).c_str(), idSize );
+ ::sg_write<int32_t>(::gi, INT_ID('S','I','D','L'), idSize);
+ ::sg_write_no_cast(::gi, INT_ID('S','I','D','S'), ((*vsi).first).c_str(), idSize);
//Save out the string value
idSize = strlen( ((*vsi).second).c_str() );
- gi.AppendToSaveGame( INT_ID('S','V','S','Z'), &idSize, sizeof( idSize ) );
- gi.AppendToSaveGame( INT_ID('S','V','A','L'), (void *) ((*vsi).second).c_str(), idSize );
+ ::sg_write<int32_t>(::gi, INT_ID('S','V','S','Z'), idSize);
+ ::sg_write_no_cast(::gi, INT_ID('S','V','A','L'), ((*vsi).second).c_str(), idSize);
}
}
@@ -11100,7 +11100,7 @@ void CQuake3GameInterface::FreeVariable( const char *name )
}
//Save / Load functions
-int CQuake3GameInterface::WriteSaveData( unsigned int chid, void *data, int length )
+int CQuake3GameInterface::WriteSaveData( unsigned int chid, const void *data, int length )
{
return gi.AppendToSaveGame( chid, data, length );
}
diff --git a/code/game/Q3_Interface.h b/code/game/Q3_Interface.h
index df15fda..56bcb05 100644
--- a/code/game/Q3_Interface.h
+++ b/code/game/Q3_Interface.h
@@ -697,7 +697,7 @@ public:
void FreeVariable( const char *name );
//Save / Load functions
- int WriteSaveData( unsigned int chid, void *data, int length );
+ int WriteSaveData( unsigned int chid, const void *data, int length );
int ReadSaveData( unsigned int chid, void *address, int length, void **addressptr = NULL );
int LinkGame( int entID, int icarusID );
diff --git a/code/game/g_main.cpp b/code/game/g_main.cpp
index 6ddf5c4..8b4154f 100644
--- a/code/game/g_main.cpp
+++ b/code/game/g_main.cpp
@@ -105,7 +105,7 @@ qboolean PInUse(unsigned int entNum)
void WriteInUseBits(void)
{
- gi.AppendToSaveGame(INT_ID('I','N','U','S'), &g_entityInUseBits, sizeof(g_entityInUseBits) );
+ ::sg_write<uint32_t>(::gi, INT_ID('I','N','U','S'), ::g_entityInUseBits);
}
void ReadInUseBits(void)
@@ -2108,7 +2108,7 @@ extern qboolean player_locked;
void G_LoadSave_WriteMiscData(void)
{
- gi.AppendToSaveGame(INT_ID('L','C','K','D'), &player_locked, sizeof(player_locked));
+ ::sg_write<int32_t>(::gi, INT_ID('L','C','K','D'), player_locked);
}
diff --git a/code/game/g_objectives.cpp b/code/game/g_objectives.cpp
index 57d13fd..9805cbc 100644
--- a/code/game/g_objectives.cpp
+++ b/code/game/g_objectives.cpp
@@ -59,7 +59,7 @@ OBJ_SaveMissionObjectives
*/
void OBJ_SaveMissionObjectives( gclient_t *client )
{
- gi.AppendToSaveGame(INT_ID('O','B','J','T'), client->sess.mission_objectives, sizeof(client->sess.mission_objectives));
+ ::sg_write_no_cast(::gi, INT_ID('O','B','J','T'), client->sess.mission_objectives);
}
diff --git a/code/game/g_roff.cpp b/code/game/g_roff.cpp
index 01c671c..588dce0 100644
--- a/code/game/g_roff.cpp
+++ b/code/game/g_roff.cpp
@@ -650,15 +650,15 @@ void G_SaveCachedRoffs()
int i, len;
// Write out the number of cached ROFFs
- gi.AppendToSaveGame( INT_ID('R','O','F','F'), (void *)&num_roffs, sizeof(num_roffs) );
+ ::sg_write<int32_t>(::gi, INT_ID('R','O','F','F'), num_roffs);
// Now dump out the cached ROFF file names in order so they can be loaded on the other end
for ( i = 0; i < num_roffs; i++ )
{
// Dump out the string length to make things a bit easier on the other end...heh heh.
len = strlen( roffs[i].fileName ) + 1;
- gi.AppendToSaveGame( INT_ID('S','L','E','N'), (void *)&len, sizeof(len) );
- gi.AppendToSaveGame( INT_ID('R','S','T','R'), (void *)roffs[i].fileName, len );
+ ::sg_write<int32_t>(::gi, INT_ID('S','L','E','N'), len);
+ ::sg_write_no_cast(::gi, INT_ID('R','S','T','R'), roffs[i].fileName, len);
}
}
diff --git a/code/game/g_savegame.cpp b/code/game/g_savegame.cpp
index f469f6b..ea612f9 100644
--- a/code/game/g_savegame.cpp
+++ b/code/game/g_savegame.cpp
@@ -517,14 +517,14 @@ static void EnumerateFields(const save_field_t *pFields, const byte *pbData, uns
// save out raw data...
//
- gi.AppendToSaveGame(ulChid, pbData, iLen);
+ ::sg_write_no_cast(::gi, ulChid, pbData, static_cast<int>(iLen));
// save out any associated strings..
//
std::list<sstring_t>::iterator it = strList->begin();
for (size_t i=0; i<strList->size(); i++, ++it)
{
- gi.AppendToSaveGame(INT_ID('S','T','R','G'), (void *)(*it).c_str(), (*it).length() + 1);
+ ::sg_write_no_cast(::gi, INT_ID('S','T','R','G'), (*it).c_str(), static_cast<int>((*it).length() + 1));
}
delete strList;
@@ -834,7 +834,7 @@ static void WriteGEntities(qboolean qbAutosave)
}
}
- gi.AppendToSaveGame(INT_ID('N','M','E','D'), &iCount, sizeof(iCount));
+ ::sg_write<int32_t>(::gi, INT_ID('N','M','E','D'), iCount);
for (i=0; i<(qbAutosave?1:globals.num_entities); i++)
{
@@ -842,7 +842,7 @@ static void WriteGEntities(qboolean qbAutosave)
if ( ent->inuse)
{
- gi.AppendToSaveGame(INT_ID('E','D','N','M'), (void *)&i, sizeof(i));
+ ::sg_write<int32_t>(::gi, INT_ID('E','D','N','M'), i);
qboolean qbLinked = ent->linked;
gi.unlinkentity( ent );
@@ -873,7 +873,7 @@ static void WriteGEntities(qboolean qbAutosave)
if (tempEnt.parms)
{
- gi.AppendToSaveGame(INT_ID('P','A','R','M'), ent->parms, sizeof(*ent->parms));
+ ::sg_write_no_cast(::gi, INT_ID('P','A','R','M'), *ent->parms);
}
if (tempEnt.m_pVehicle)
@@ -902,7 +902,7 @@ static void WriteGEntities(qboolean qbAutosave)
// This saves time debugging, and makes things easier to track.
//
static int iBlah = 1234;
- gi.AppendToSaveGame(INT_ID('I','C','O','K'), &iBlah, sizeof(iBlah));
+ ::sg_write<int32_t>(::gi, INT_ID('I','C','O','K'), iBlah);
}
if (!qbAutosave )//really shouldn't need to write these bits at all, just restore them from the ents...
{
@@ -1188,7 +1188,7 @@ void WriteLevel(qboolean qbAutosave)
// put out an end-marker so that the load code can check everything was read in...
//
static int iDONE = 1234;
- gi.AppendToSaveGame(INT_ID('D','O','N','E'), &iDONE, sizeof(iDONE));
+ ::sg_write<int32_t>(::gi, INT_ID('D','O','N','E'), iDONE);
}
void ReadLevel(qboolean qbAutosave, qboolean qbLoadTransition)
diff --git a/code/icarus/IcarusImplementation.cpp b/code/icarus/IcarusImplementation.cpp
index b35870c..71b4394 100644
--- a/code/icarus/IcarusImplementation.cpp
+++ b/code/icarus/IcarusImplementation.cpp
@@ -540,7 +540,7 @@ int CIcarus::Save()
//Save out a ICARUS save block header with the ICARUS version
double version = ICARUS_VERSION;
- game->WriteSaveData( INT_ID('I','C','A','R'), &version, sizeof( version ) );
+ ::sg_write_no_cast(game, INT_ID('I','C','A','R'), version);
//Save out the signals
if ( SaveSignals() == false )
@@ -564,7 +564,7 @@ int CIcarus::Save()
}
// Write out the buffer with all our collected data.
- game->WriteSaveData( INT_ID('I','S','E','Q'), m_byBuffer, m_ulBufferCurPos );
+ ::sg_write_no_cast(game, INT_ID('I','S','E','Q'), m_byBuffer, static_cast<int>(m_ulBufferCurPos));
// De-allocate the temporary buffer.
DestroyBuffer();
@@ -782,7 +782,7 @@ void CIcarus::BufferWrite( void *pSrcData, unsigned long ulNumBytesToWrite )
if ( MAX_BUFFER_SIZE - m_ulBufferCurPos < ulNumBytesToWrite )
{ // Write out the buffer with all our collected data so far...
IGameInterface::GetGame()->DebugPrint( IGameInterface::WL_ERROR, "BufferWrite: Out of buffer space, Flushing." );
- IGameInterface::GetGame()->WriteSaveData( INT_ID('I','S','E','Q'), m_byBuffer, m_ulBufferCurPos );
+ ::sg_write_no_cast(IGameInterface::GetGame(), INT_ID('I','S','E','Q'), m_byBuffer, static_cast<int>(m_ulBufferCurPos));
m_ulBufferCurPos = 0; //reset buffer
}
diff --git a/code/icarus/IcarusInterface.h b/code/icarus/IcarusInterface.h
index baa6981..9ba27ec 100644
--- a/code/icarus/IcarusInterface.h
+++ b/code/icarus/IcarusInterface.h
@@ -144,7 +144,7 @@ public:
// Save / Load functions
- virtual int WriteSaveData( unsigned int chid, void *data, int length ) = 0;
+ virtual int WriteSaveData( unsigned int chid, const void *data, int length ) = 0;
virtual int ReadSaveData( unsigned int chid, void *address, int length, void **addressptr = NULL ) = 0;
virtual int LinkGame( int gameID, int icarusID ) = 0;
diff --git a/code/qcommon/cm_load.cpp b/code/qcommon/cm_load.cpp
index f76f318..a1ff55f 100644
--- a/code/qcommon/cm_load.cpp
+++ b/code/qcommon/cm_load.cpp
@@ -1215,7 +1215,7 @@ int SG_Read(unsigned int chid, void *pvAddress, int iLength, void **ppvAddressPt
void CM_WritePortalState ()
{
- SG_Append(INT_ID('P','R','T','S'), (void *)cmg.areaPortals, cmg.numAreas * cmg.numAreas * sizeof( *cmg.areaPortals ));
+ ::sg_write<int32_t>(::SG_Append, INT_ID('P','R','T','S'), ::cmg.areaPortals, ::cmg.numAreas * ::cmg.numAreas);
}
/*
diff --git a/code/rd-vanilla/G2_misc.cpp b/code/rd-vanilla/G2_misc.cpp
index b9cf1ef..548fa18 100644
--- a/code/rd-vanilla/G2_misc.cpp
+++ b/code/rd-vanilla/G2_misc.cpp
@@ -1778,12 +1778,13 @@ void G2_SaveGhoul2Models(CGhoul2Info_v &ghoul2)
// is there anything to save?
if (!ghoul2.IsValid()||!ghoul2.size())
{
- ri.SG_Append(INT_ID('G','H','L','2'),&pGhoul2Data, 4); //write out a zero buffer
+ uint32_t empty_value = 0;
+ ::sg_write_no_cast(::ri, INT_ID('G','H','L','2'), empty_value); //write out a zero buffer
return;
}
// this one isn't a define since I couldn't work out how to figure it out at compile time
- const int ghoul2BlockSize = (intptr_t)&ghoul2[0].BSAVE_END_FIELD - (intptr_t)&ghoul2[0].BSAVE_START_FIELD;
+ constexpr auto ghoul2BlockSize = static_cast<int>(sizeof(SgCGhoul2Info));
// add in count for number of ghoul2 models
iGhoul2Size += 4;
@@ -1809,51 +1810,75 @@ void G2_SaveGhoul2Models(CGhoul2Info_v &ghoul2)
char *tempBuffer = pGhoul2Data;
// save out how many ghoul2 models we have
- *(int *)tempBuffer = ghoul2.size();
+ *(int32_t*)tempBuffer = static_cast<int32_t>(ghoul2.size());
tempBuffer +=4;
for (int i = 0; i<ghoul2.size();i++)
{
// first save out the ghoul2 details themselves
// OutputDebugString(va("G2_SaveGhoul2Models(): ghoul2[%d].mModelindex = %d\n",i,ghoul2[i].mModelindex));
+#if 0
memcpy(tempBuffer, &ghoul2[i].mModelindex, ghoul2BlockSize);
+#else
+ ::sg_export(
+ ghoul2[i],
+ *reinterpret_cast<SgCGhoul2Info*>(tempBuffer));
+#endif
tempBuffer += ghoul2BlockSize;
// save out how many surfaces we have
- *(int*)tempBuffer = ghoul2[i].mSlist.size();
+ *(int32_t*)tempBuffer = static_cast<int32_t>(ghoul2[i].mSlist.size());
tempBuffer +=4;
// now save the all the surface list info
for (size_t x=0; x<ghoul2[i].mSlist.size(); x++)
{
+#if 0
memcpy(tempBuffer, &ghoul2[i].mSlist[x], SURFACE_SAVE_BLOCK_SIZE);
+#else
+ ::sg_export(
+ ghoul2[i].mSlist[x],
+ *reinterpret_cast<SgSurfaceInfo*>(tempBuffer));
+#endif
tempBuffer += SURFACE_SAVE_BLOCK_SIZE;
}
// save out how many bones we have
- *(int*)tempBuffer = ghoul2[i].mBlist.size();
+ *(int32_t*)tempBuffer = static_cast<int32_t>(ghoul2[i].mBlist.size());
tempBuffer +=4;
// now save the all the bone list info
for (size_t x = 0; x<ghoul2[i].mBlist.size(); x++)
{
+#if 0
memcpy(tempBuffer, &ghoul2[i].mBlist[x], BONE_SAVE_BLOCK_SIZE);
+#else
+ ::sg_export(
+ ghoul2[i].mBlist[x],
+ *reinterpret_cast<SgBoneInfo*>(tempBuffer));
+#endif
tempBuffer += BONE_SAVE_BLOCK_SIZE;
}
// save out how many bolts we have
- *(int*)tempBuffer = ghoul2[i].mBltlist.size();
+ *(int32_t*)tempBuffer = static_cast<int32_t>(ghoul2[i].mBltlist.size());
tempBuffer +=4;
// lastly save the all the bolt list info
for (size_t x = 0; x<ghoul2[i].mBltlist.size(); x++)
{
+#if 0
memcpy(tempBuffer, &ghoul2[i].mBltlist[x], BOLT_SAVE_BLOCK_SIZE);
+#else
+ ::sg_export(
+ ghoul2[i].mBltlist[x],
+ *reinterpret_cast<SgBoltInfo*>(tempBuffer));
+#endif
tempBuffer += BOLT_SAVE_BLOCK_SIZE;
}
}
- ri.SG_Append(INT_ID('G','H','L','2'),pGhoul2Data, iGhoul2Size);
+ ::sg_write_no_cast(::ri, INT_ID('G','H','L','2'), pGhoul2Data, iGhoul2Size);
R_Free(pGhoul2Data);
}
diff --git a/code/server/sv_savegame.cpp b/code/server/sv_savegame.cpp
index 55614a0..99a3a06 100644
--- a/code/server/sv_savegame.cpp
+++ b/code/server/sv_savegame.cpp
@@ -178,7 +178,7 @@ static qboolean SG_Create( const char *psPathlessBaseName )
}
giSaveGameVersion = iSAVEGAME_VERSION;
- SG_Append(INT_ID('_','V','E','R'), &giSaveGameVersion, sizeof(giSaveGameVersion));
+ ::sg_write<int32_t>(::SG_Append, INT_ID('_','V','E','R'), ::giSaveGameVersion);
return qtrue;
}
@@ -539,7 +539,7 @@ void SV_SaveGame_f(void)
//---------------
static void WriteGame(qboolean autosave)
{
- SG_Append(INT_ID('G','A','M','E'), &autosave, sizeof(autosave));
+ ::sg_write<int32_t>(::SG_Append, INT_ID('G','A','M','E'), autosave);
if (autosave)
{
@@ -554,25 +554,25 @@ static void WriteGame(qboolean autosave)
//
memset(s,0,sizeof(s));
Cvar_VariableStringBuffer( sCVARNAME_PLAYERSAVE, s, sizeof(s) );
- SG_Append(INT_ID('C','V','S','V'), &s, sizeof(s));
+ ::sg_write_no_cast(::SG_Append, INT_ID('C','V','S','V'), s);
// write ammo...
//
memset(s,0,sizeof(s));
Cvar_VariableStringBuffer( "playerammo", s, sizeof(s) );
- SG_Append(INT_ID('A','M','M','O'), &s, sizeof(s));
+ ::sg_write_no_cast(::SG_Append, INT_ID('A','M','M','O'), s);
// write inventory...
//
memset(s,0,sizeof(s));
Cvar_VariableStringBuffer( "playerinv", s, sizeof(s) );
- SG_Append(INT_ID('I','V','T','Y'), &s, sizeof(s));
+ ::sg_write_no_cast(::SG_Append, INT_ID('I','V','T','Y'), s);
// the new JK2 stuff - force powers, etc...
//
memset(s,0,sizeof(s));
Cvar_VariableStringBuffer( "playerfplvl", s, sizeof(s) );
- SG_Append(INT_ID('F','P','L','V'), &s, sizeof(s));
+ ::sg_write_no_cast(::SG_Append, INT_ID('F','P','L','V'), s);
}
}
@@ -643,7 +643,7 @@ void SG_WriteCvars(void)
// store count...
//
- SG_Append(INT_ID('C','V','C','N'), &iCount, sizeof(iCount));
+ ::sg_write<int32_t>(::SG_Append, INT_ID('C','V','C','N'), iCount);
// write 'em...
//
@@ -657,8 +657,8 @@ void SG_WriteCvars(void)
{
continue;
}
- SG_Append(INT_ID('C','V','A','R'), var->name, strlen(var->name) + 1);
- SG_Append(INT_ID('V','A','L','U'), var->string, strlen(var->string) + 1);
+ ::sg_write_no_cast(::SG_Append, INT_ID('C','V','A','R'), var->name, static_cast<int>(strlen(var->name) + 1));
+ ::sg_write_no_cast(::SG_Append, INT_ID('V','A','L','U'), var->string, static_cast<int>(strlen(var->string) + 1));
}
}
@@ -700,7 +700,7 @@ void SG_WriteServerConfigStrings( void )
}
}
- SG_Append(INT_ID('C','S','C','N'), &iCount, sizeof(iCount));
+ ::sg_write<int32_t>(::SG_Append, INT_ID('C','S','C','N'), iCount);
// now write 'em...
//
@@ -710,8 +710,8 @@ void SG_WriteServerConfigStrings( void )
{
if (sv.configstrings[i] && strlen(sv.configstrings[i]))
{
- SG_Append(INT_ID('C','S','I','N'), &i, sizeof(i));
- SG_Append(INT_ID('C','S','D','A'), sv.configstrings[i], strlen(sv.configstrings[i])+1);
+ ::sg_write<int32_t>(::SG_Append, INT_ID('C','S','I','N'), i);
+ ::sg_write_no_cast(::SG_Append, INT_ID('C','S','D','A'), ::sv.configstrings[i], static_cast<int>(strlen(::sv.configstrings[i])+1));
}
}
}
@@ -775,11 +775,11 @@ static void SG_WriteComment(qboolean qbAutosave, const char *psMapName)
Q_strncpyz(sComment,saveGameComment, sizeof(sComment));
}
- SG_Append(INT_ID('C','O','M','M'), sComment, sizeof(sComment));
+ ::sg_write_no_cast(::SG_Append, INT_ID('C','O','M','M'), sComment);
// Add Date/Time/Map stamp
unsigned int timestamp = SG_UnixTimestamp (time (NULL));
- SG_Append(INT_ID('C','M','T','M'), ×tamp, sizeof (timestamp));
+ ::sg_write<uint32_t>(::SG_Append, INT_ID('C','M','T','M'), timestamp);
Com_DPrintf("Saving: current (%s)\n", sComment);
}
@@ -975,8 +975,8 @@ static void SG_WriteScreenshot(qboolean qbAutosave, const char *psMapName)
iJPGDataSize = re.SaveJPGToBuffer(pJPGData, bufSize, JPEG_IMAGE_QUALITY, SG_SCR_WIDTH, SG_SCR_HEIGHT, pbRawScreenShot, 0 );
if ( qbAutosave )
delete[] byBlank;
- SG_Append(INT_ID('S','H','L','N'), &iJPGDataSize, sizeof(iJPGDataSize));
- SG_Append(INT_ID('S','H','O','T'), pJPGData, iJPGDataSize);
+ ::sg_write<uint32_t>(::SG_Append, INT_ID('S','H','L','N'), iJPGDataSize);
+ ::sg_write_no_cast(::SG_Append, INT_ID('S','H','O','T'), pJPGData, static_cast<int>(iJPGDataSize));
Z_Free(pJPGData);
SCR_TempRawImage_CleanUp();
}
@@ -1056,7 +1056,7 @@ qboolean SG_WriteSavegame(const char *psPathlessBaseName, qboolean qbAutosave)
#ifdef JK2_MODE
SG_WriteScreenshot(qbAutosave, sMapCmd);
#endif
- SG_Append(INT_ID('M','P','C','M'), sMapCmd, sizeof(sMapCmd));
+ ::sg_write_no_cast(::SG_Append, INT_ID('M','P','C','M'), sMapCmd);
SG_WriteCvars();
WriteGame (qbAutosave);
@@ -1065,8 +1065,8 @@ qboolean SG_WriteSavegame(const char *psPathlessBaseName, qboolean qbAutosave)
//
if (!qbAutosave)
{
- SG_Append(INT_ID('T','I','M','E'), (void *)&sv.time, sizeof(sv.time));
- SG_Append(INT_ID('T','I','M','R'), (void *)&sv.timeResidual, sizeof(sv.timeResidual));
+ ::sg_write<int32_t>(::SG_Append, INT_ID('T','I','M','E'), ::sv.time);
+ ::sg_write<int32_t>(::SG_Append, INT_ID('T','I','M','R'), ::sv.timeResidual);
CM_WritePortalState();
SG_WriteServerConfigStrings();
}
diff --git a/codeJK2/cgame/cg_main.cpp b/codeJK2/cgame/cg_main.cpp
index 15f1ebc..50f1840 100644
--- a/codeJK2/cgame/cg_main.cpp
+++ b/codeJK2/cgame/cg_main.cpp
@@ -1638,8 +1638,8 @@ Ghoul2 Insert End
void CG_WriteTheEvilCGHackStuff(void)
{
- gi.AppendToSaveGame(INT_ID('F','P','S','L'), &cg.forcepowerSelect, sizeof(cg.forcepowerSelect));
- gi.AppendToSaveGame(INT_ID('I','V','S','L'), &cg.inventorySelect, sizeof(cg.inventorySelect));
+ ::sg_write<int32_t>(::gi, INT_ID('F','P','S','L'), ::cg.forcepowerSelect);
+ ::sg_write<int32_t>(::gi, INT_ID('I','V','S','L'), ::cg.inventorySelect);
}
void CG_ReadTheEvilCGHackStuff(void)
diff --git a/codeJK2/game/G_Timer.cpp b/codeJK2/game/G_Timer.cpp
index ef7f2d4..ab1ed3c 100644
--- a/codeJK2/game/G_Timer.cpp
+++ b/codeJK2/game/G_Timer.cpp
@@ -177,7 +177,7 @@ void TIMER_Save( void )
}
//Write out the timer information
- gi.AppendToSaveGame(INT_ID('T','I','M','E'), (void *)&numTimers, sizeof(numTimers));
+ ::sg_write<int32_t>(::gi, INT_ID('T','I','M','E'), numTimers);
gtimer_t *p = g_timers[j];
assert ((numTimers && p) || (!numTimers && !p));
@@ -191,11 +191,11 @@ void TIMER_Save( void )
assert( length < 1024 );//This will cause problems when loading the timer if longer
//Write out the string size and data
- gi.AppendToSaveGame(INT_ID('T','S','L','N'), (void*)&length, sizeof(length));
- gi.AppendToSaveGame(INT_ID('T','S','N','M'), (void*)timerID, length);
+ ::sg_write<int32_t>(::gi, INT_ID('T','S','L','N'), length);
+ ::sg_write_no_cast(::gi, INT_ID('T','S','N','M'), timerID, length);
//Write out the timer data
- gi.AppendToSaveGame(INT_ID('T','D','T','A'), (void *) &time, sizeof( time ) );
+ ::sg_write<int32_t>(::gi, INT_ID('T','D','T','A'), time);
p = p->next;
}
}
diff --git a/codeJK2/game/Q3_Interface.cpp b/codeJK2/game/Q3_Interface.cpp
index 95415ee..bd34699 100644
--- a/codeJK2/game/Q3_Interface.cpp
+++ b/codeJK2/game/Q3_Interface.cpp
@@ -9262,7 +9262,7 @@ void Interface_Init( interface_export_t *pe )
pe->I_FreeVariable = Q3_FreeVariable;
//Save / Load functions
- pe->I_WriteSaveData = (int(*)(unsigned int, void *, int))gi.AppendToSaveGame;
+ pe->I_WriteSaveData = gi.AppendToSaveGame;
pe->I_ReadSaveData = gi.ReadFromSaveGame;
pe->I_LinkEntity = ICARUS_LinkEntity;
diff --git a/codeJK2/game/Q3_Registers.cpp b/codeJK2/game/Q3_Registers.cpp
index 3108138..2264971 100644
--- a/codeJK2/game/Q3_Registers.cpp
+++ b/codeJK2/game/Q3_Registers.cpp
@@ -288,7 +288,7 @@ Q3_VariableSaveFloats
void Q3_VariableSaveFloats( varFloat_m &fmap )
{
int numFloats = fmap.size();
- gi.AppendToSaveGame( INT_ID('F','V','A','R'), &numFloats, sizeof( numFloats ) );
+ ::sg_write<int32_t>(::gi, INT_ID('F','V','A','R'), numFloats);
varFloat_m::iterator vfi;
STL_ITERATE( vfi, fmap )
@@ -297,11 +297,11 @@ void Q3_VariableSaveFloats( varFloat_m &fmap )
int idSize = strlen( ((*vfi).first).c_str() );
//Save out the real data
- gi.AppendToSaveGame( INT_ID('F','I','D','L'), &idSize, sizeof( idSize ) );
- gi.AppendToSaveGame( INT_ID('F','I','D','S'), (void *) ((*vfi).first).c_str(), idSize );
+ ::sg_write<int32_t>(::gi, INT_ID('F','I','D','L'), idSize);
+ ::sg_write_no_cast(::gi, INT_ID('F','I','D','S'), ((*vfi).first).c_str(), idSize);
//Save out the float value
- gi.AppendToSaveGame( INT_ID('F','V','A','L'), &((*vfi).second), sizeof( float ) );
+ ::sg_write_no_cast(::gi, INT_ID('F','V','A','L'), (*vfi).second);
}
}
@@ -314,7 +314,7 @@ Q3_VariableSaveStrings
void Q3_VariableSaveStrings( varString_m &smap )
{
int numStrings = smap.size();
- gi.AppendToSaveGame( INT_ID('S','V','A','R'), &numStrings, sizeof( numStrings ) );
+ ::sg_write<int32_t>(::gi, INT_ID('S','V','A','R'), numStrings);
varString_m::iterator vsi;
STL_ITERATE( vsi, smap )
@@ -323,14 +323,14 @@ void Q3_VariableSaveStrings( varString_m &smap )
int idSize = strlen( ((*vsi).first).c_str() );
//Save out the real data
- gi.AppendToSaveGame( INT_ID('S','I','D','L'), &idSize, sizeof( idSize ) );
- gi.AppendToSaveGame( INT_ID('S','I','D','S'), (void *) ((*vsi).first).c_str(), idSize );
+ ::sg_write<int32_t>(::gi, INT_ID('S','I','D','L'), idSize);
+ ::sg_write_no_cast(::gi, INT_ID('S','I','D','S'), ((*vsi).first).c_str(), idSize);
//Save out the string value
idSize = strlen( ((*vsi).second).c_str() );
- gi.AppendToSaveGame( INT_ID('S','V','S','Z'), &idSize, sizeof( idSize ) );
- gi.AppendToSaveGame( INT_ID('S','V','A','L'), (void *) ((*vsi).second).c_str(), idSize );
+ ::sg_write<int32_t>(::gi, INT_ID('S','V','S','Z'), idSize);
+ ::sg_write_no_cast(::gi, INT_ID('S','V','A','L'), ((*vsi).second).c_str(), idSize);
}
}
@@ -372,7 +372,7 @@ void Q3_VariableLoadFloats( varFloat_m &fmap )
float val;
- ::sg_read<float>(::gi, INT_ID('F','V','A','L'), val);
+ ::sg_read_no_cast(::gi, INT_ID('F','V','A','L'), val);
Q3_DeclareVariable( TK_FLOAT, (const char *) &tempBuffer );
Q3_SetFloatVariable( (const char *) &tempBuffer, val );
diff --git a/codeJK2/game/g_main.cpp b/codeJK2/game/g_main.cpp
index 01e728b..17c1a17 100644
--- a/codeJK2/game/g_main.cpp
+++ b/codeJK2/game/g_main.cpp
@@ -89,7 +89,7 @@ qboolean PInUse2(gentity_t *ent)
void WriteInUseBits(void)
{
- gi.AppendToSaveGame(INT_ID('I','N','U','S'), &g_entityInUseBits, sizeof(g_entityInUseBits) );
+ ::sg_write<uint32_t>(::gi, INT_ID('I','N','U','S'), ::g_entityInUseBits);
}
void ReadInUseBits(void)
@@ -1477,7 +1477,7 @@ extern qboolean player_locked;
void G_LoadSave_WriteMiscData(void)
{
- gi.AppendToSaveGame(INT_ID('L','C','K','D'), &player_locked, sizeof(player_locked));
+ ::sg_write<int32_t>(::gi, INT_ID('L','C','K','D'), player_locked);
}
diff --git a/codeJK2/game/g_objectives.cpp b/codeJK2/game/g_objectives.cpp
index b78ca13..e66a339 100644
--- a/codeJK2/game/g_objectives.cpp
+++ b/codeJK2/game/g_objectives.cpp
@@ -61,7 +61,7 @@ OBJ_SaveMissionObjectives
*/
void OBJ_SaveMissionObjectives( gclient_t *client )
{
- gi.AppendToSaveGame(INT_ID('O','B','J','T'), client->sess.mission_objectives, sizeof(client->sess.mission_objectives));
+ ::sg_write_no_cast(::gi, INT_ID('O','B','J','T'), client->sess.mission_objectives);
}
diff --git a/codeJK2/game/g_roff.cpp b/codeJK2/game/g_roff.cpp
index e0d3d10..eb7ea81 100644
--- a/codeJK2/game/g_roff.cpp
+++ b/codeJK2/game/g_roff.cpp
@@ -625,15 +625,15 @@ void G_SaveCachedRoffs()
int i, len;
// Write out the number of cached ROFFs
- gi.AppendToSaveGame( INT_ID('R','O','F','F'), (void *)&num_roffs, sizeof(num_roffs) );
+ ::sg_write<int32_t>(::gi, INT_ID('R','O','F','F'), num_roffs);
// Now dump out the cached ROFF file names in order so they can be loaded on the other end
for ( i = 0; i < num_roffs; i++ )
{
// Dump out the string length to make things a bit easier on the other end...heh heh.
len = strlen( roffs[i].fileName ) + 1;
- gi.AppendToSaveGame( INT_ID('S','L','E','N'), (void *)&len, sizeof(len) );
- gi.AppendToSaveGame( INT_ID('R','S','T','R'), (void *)(roffs[i].fileName), len );
+ ::sg_write<int32_t>(::gi, INT_ID('S','L','E','N'), len);
+ ::sg_write_no_cast(::gi, INT_ID('R','S','T','R'), roffs[i].fileName, len);
}
}
diff --git a/codeJK2/game/g_savegame.cpp b/codeJK2/game/g_savegame.cpp
index cfd84ce..bc3028c 100644
--- a/codeJK2/game/g_savegame.cpp
+++ b/codeJK2/game/g_savegame.cpp
@@ -338,7 +338,7 @@ void EnumerateField(const field_t *pField, byte *pbBase)
switch (pField->eFieldType)
{
case F_STRING:
- *(int *)pv = GetStringNum(*(char **)pv);
+ *(intptr_t *)pv = GetStringNum(*(char **)pv);
break;
case F_GENTITY:
@@ -346,7 +346,7 @@ void EnumerateField(const field_t *pField, byte *pbBase)
break;
case F_GROUP:
- *(int *)pv = GetGroupNumber(*(AIGroupInfo_t **)pv);
+ *(intptr_t *)pv = GetGroupNumber(*(AIGroupInfo_t **)pv);
break;
case F_GCLIENT:
@@ -373,7 +373,7 @@ void EnumerateField(const field_t *pField, byte *pbBase)
break;
case F_ITEM:
- *(int *)pv = GetGItemNum(*(gitem_t **)pv);
+ *(intptr_t *)pv = GetGItemNum(*(gitem_t **)pv);
break;
case F_BEHAVIORSET:
@@ -382,7 +382,7 @@ void EnumerateField(const field_t *pField, byte *pbBase)
for (int i=0; i<NUM_BSETS; i++)
{
pv = &p[i]; // since you can't ++ a void ptr
- *(int *)pv = GetStringNum(*(char **)pv);
+ *(intptr_t *)pv = GetStringNum(*(char **)pv);
}
}
break;
@@ -441,6 +441,7 @@ void EnumerateField(const field_t *pField, byte *pbBase)
}
}
+#if 0
static void EnumerateFields(const field_t *pFields, byte *pbData, unsigned int ulChid, size_t iLen)
{
strList = new std::list<sstring_t>;
@@ -458,19 +459,63 @@ static void EnumerateFields(const field_t *pFields, byte *pbData, unsigned int u
// save out raw data...
//
- gi.AppendToSaveGame(ulChid, pbData, iLen);
+ ::sg_write_no_cast(::gi, ulChid, pbData, static_cast<int>(iLen));
// save out any associated strings..
//
for (std::list<sstring_t>::iterator it = strList->begin(); it != strList->end(); ++it)
{
- gi.AppendToSaveGame(INT_ID('S','T','R','G'), (void*)it->c_str(), it->length()+1);
+ ::sg_write_no_cast(::gi, INT_ID('S','T','R','G'), it->c_str(), static_cast<int>(it->length()+1));
}
delete strList;
strList = NULL;
}
+#else
+template<typename T>
+static void EnumerateFields(const field_t *pFields, T* src_instance, unsigned int ulChid, size_t iLen)
+{
+ strList = new std::list<sstring_t>;
+
+ auto pbData = reinterpret_cast<byte*>(src_instance);
+
+ // enumerate all the fields...
+ //
+ if (pFields)
+ {
+ for (const field_t *pField = pFields; pField->psName; pField++)
+ {
+ assert(pField->iOffset < iLen);
+ EnumerateField(pField, pbData);
+ }
+ }
+
+ // save out raw data...
+ //
+ using SgType = typename T::SgType;
+
+ constexpr auto dst_size = static_cast<int>(sizeof(SgType));
+
+ auto& dst_buffer = ::sg_get_buffer(
+ dst_size);
+
+ auto dst_instance = reinterpret_cast<SgType*>(dst_buffer.data());
+ ::sg_export(*src_instance, *dst_instance);
+
+ ::sg_write_no_cast(::gi, ulChid, dst_buffer.data(), dst_size);
+
+ // save out any associated strings..
+ //
+ for (std::list<sstring_t>::iterator it = strList->begin(); it != strList->end(); ++it)
+ {
+ ::sg_write_no_cast(::gi, INT_ID('S','T','R','G'), it->c_str(), static_cast<int>(it->length()+1));
+ }
+
+ delete strList;
+ strList = NULL;
+}
+#endif
static void EvaluateField(const field_t *pField, byte *pbBase, byte *pbOriginalRefData/* may be NULL*/)
{
@@ -630,7 +675,7 @@ static void WriteLevelLocals ()
level_locals_t *temp = (level_locals_t *)gi.Malloc(sizeof(level_locals_t), TAG_TEMP_WORKSPACE, qfalse);
*temp = level; // copy out all data into a temp space
- EnumerateFields(savefields_LevelLocals, (byte *)temp, INT_ID('L','V','L','C'), LLOFS(LEVEL_LOCALS_T_SAVESTOP));
+ EnumerateFields(savefields_LevelLocals, temp, INT_ID('L','V','L','C'), LLOFS(LEVEL_LOCALS_T_SAVESTOP));
gi.Free(temp);
}
@@ -671,7 +716,7 @@ static void WriteGEntities(qboolean qbAutosave)
}
}
- gi.AppendToSaveGame(INT_ID('N','M','E','D'), &iCount, sizeof(iCount));
+ ::sg_write<int32_t>(::gi, INT_ID('N','M','E','D'), iCount);
for (i=0; i<(qbAutosave?1:globals.num_entities); i++)
{
@@ -679,7 +724,7 @@ static void WriteGEntities(qboolean qbAutosave)
if ( ent->inuse)
{
- gi.AppendToSaveGame(INT_ID('E','D','N','M'), (void *)&i, sizeof(i));
+ ::sg_write<int32_t>(::gi, INT_ID('E','D','N','M'), i);
qboolean qbLinked = ent->linked;
gi.unlinkentity( ent );
@@ -691,7 +736,7 @@ static void WriteGEntities(qboolean qbAutosave)
gi.linkentity( ent );
}
- EnumerateFields(savefields_gEntity, (byte *)&tempEnt, INT_ID('G','E','N','T'), sizeof(tempEnt));
+ EnumerateFields(savefields_gEntity, &tempEnt, INT_ID('G','E','N','T'), sizeof(tempEnt));
// now for any fiddly bits that would be rather awkward to build into the enumerator...
//
@@ -699,18 +744,18 @@ static void WriteGEntities(qboolean qbAutosave)
{
gNPC_t npc = *ent->NPC; // NOT *tempEnt.NPC; !! :-)
- EnumerateFields(savefields_gNPC, (byte *)&npc, INT_ID('G','N','P','C'), sizeof(npc));
+ EnumerateFields(savefields_gNPC, &npc, INT_ID('G','N','P','C'), sizeof(npc));
}
if (tempEnt.client == (gclient_t *)-2) // I know, I know...
{
gclient_t client = *ent->client; // NOT *tempEnt.client!!
- EnumerateFields(savefields_gClient, (byte *)&client, INT_ID('G','C','L','I'), sizeof(client));
+ EnumerateFields(savefields_gClient, &client, INT_ID('G','C','L','I'), sizeof(client));
}
if (tempEnt.parms)
{
- gi.AppendToSaveGame(INT_ID('P','A','R','M'), ent->parms, sizeof(*ent->parms));
+ ::sg_write_no_cast(::gi, INT_ID('P','A','R','M'), *ent->parms);
}
// the scary ghoul2 saver stuff... (fingers crossed)
@@ -733,7 +778,7 @@ static void WriteGEntities(qboolean qbAutosave)
// This saves time debugging, and makes things easier to track.
//
static int iBlah = 1234;
- gi.AppendToSaveGame(INT_ID('I','C','O','K'), &iBlah, sizeof(iBlah));
+ ::sg_write<int32_t>(::gi, INT_ID('I','C','O','K'), iBlah);
}
if (!qbAutosave )//really shouldn't need to write these bits at all, just restore them from the ents...
{
@@ -956,7 +1001,7 @@ void WriteLevel(qboolean qbAutosave)
//
assert(level.maxclients == 1); // I'll need to know if this changes, otherwise I'll need to change the way ReadGame works
gclient_t client = level.clients[0];
- EnumerateFields(savefields_gClient, (byte *)&client, INT_ID('G','C','L','I'), sizeof(client));
+ EnumerateFields(savefields_gClient, &client, INT_ID('G','C','L','I'), sizeof(client));
WriteLevelLocals(); // level_locals_t level
}
@@ -975,7 +1020,7 @@ void WriteLevel(qboolean qbAutosave)
// put out an end-marker so that the load code can check everything was read in...
//
static int iDONE = 1234;
- gi.AppendToSaveGame(INT_ID('D','O','N','E'), &iDONE, sizeof(iDONE));
+ ::sg_write<int32_t>(::gi, INT_ID('D','O','N','E'), iDONE);
}
void ReadLevel(qboolean qbAutosave, qboolean qbLoadTransition)
diff --git a/codeJK2/icarus/Instance.cpp b/codeJK2/icarus/Instance.cpp
index 0eff61d..299f774 100644
--- a/codeJK2/icarus/Instance.cpp
+++ b/codeJK2/icarus/Instance.cpp
@@ -302,7 +302,7 @@ int ICARUS_Instance::SaveSequenceIDTable( void )
{
//Save out the number of sequences to follow
int numSequences = m_sequences.size();
- m_interface->I_WriteSaveData( INT_ID('#','S','E','Q'), &numSequences, sizeof( numSequences ) );
+ ::sg_write<int32_t>(m_interface, INT_ID('#','S','E','Q'), numSequences);
//Sequences are saved first, by ID and information
sequence_l::iterator sqi;
@@ -319,7 +319,7 @@ int ICARUS_Instance::SaveSequenceIDTable( void )
idTable[itr++] = (*sqi)->GetID();
}
- m_interface->I_WriteSaveData( INT_ID('S','Q','T','B'), idTable, sizeof( int ) * numSequences );
+ ::sg_write<int32_t>(m_interface, INT_ID('S','Q','T','B'), idTable, numSequences);
delete[] idTable;
@@ -357,7 +357,7 @@ int ICARUS_Instance::SaveSequencers( void )
{
//Save out the number of sequences to follow
int numSequencers = m_sequencers.size();
- m_interface->I_WriteSaveData( INT_ID('#','S','Q','R'), &numSequencers, sizeof( numSequencers ) );
+ ::sg_write<int32_t>(m_interface, INT_ID('#','S','Q','R'), numSequencers);
//The sequencers are then saved
sequencer_l::iterator si;
@@ -379,7 +379,7 @@ int ICARUS_Instance::SaveSignals( void )
{
int numSignals = m_signals.size();
- m_interface->I_WriteSaveData( INT_ID('I','S','I','G'), &numSignals, sizeof( numSignals ) );
+ ::sg_write<int32_t>(m_interface, INT_ID('I','S','I','G'), numSignals);
signal_m::iterator si;
STL_ITERATE( si, m_signals )
@@ -393,10 +393,10 @@ int ICARUS_Instance::SaveSignals( void )
int length = strlen( name ) + 1;
//Save out the string size
- m_interface->I_WriteSaveData( INT_ID('S','I','G','#'), &length, sizeof ( length ) );
+ ::sg_write<int32_t>(m_interface, INT_ID('S','I','G','#'), length);
//Write out the string
- m_interface->I_WriteSaveData( INT_ID('S','I','G','N'), (void *) name, length );
+ ::sg_write_no_cast(m_interface, INT_ID('S','I','G','N'), name, length );
}
return true;
@@ -412,7 +412,7 @@ int ICARUS_Instance::Save( void )
{
//Save out a ICARUS save block header with the ICARUS version
double version = ICARUS_VERSION;
- m_interface->I_WriteSaveData( INT_ID('I','C','A','R'), &version, sizeof( version ) );
+ ::sg_write_no_cast(m_interface, INT_ID('I','C','A','R'), version);
//Save out the signals
if ( SaveSignals() == false )
@@ -426,7 +426,7 @@ int ICARUS_Instance::Save( void )
if ( SaveSequencers() == false )
return false;
- m_interface->I_WriteSaveData( INT_ID('I','E','N','D'), &version, sizeof( version ) );
+ ::sg_write_no_cast(m_interface, INT_ID('I','E','N','D'), version);
return true;
}
diff --git a/codeJK2/icarus/Sequence.cpp b/codeJK2/icarus/Sequence.cpp
index c91712a..012ff25 100644
--- a/codeJK2/icarus/Sequence.cpp
+++ b/codeJK2/icarus/Sequence.cpp
@@ -344,15 +344,15 @@ int CSequence::SaveCommand( CBlock *block )
//Save out the block ID
bID = block->GetBlockID();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','L','I','D'), &bID, sizeof ( bID ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('B','L','I','D'), bID);
//Save out the block's flags
flags = block->GetFlags();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','F','L','G'), &flags, sizeof ( flags ) );
+ ::sg_write<uint8_t>(m_owner->GetInterface(), INT_ID('B','F','L','G'), flags);
//Save out the number of members to read
numMembers = block->GetNumMembers();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','N','U','M'), &numMembers, sizeof ( numMembers ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('B','N','U','M'), numMembers);
for ( int i = 0; i < numMembers; i++ )
{
@@ -360,14 +360,14 @@ int CSequence::SaveCommand( CBlock *block )
//Save the block id
bID = bm->GetID();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','M','I','D'), &bID, sizeof ( bID ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('B','M','I','D'), bID);
//Save out the data size
size = bm->GetSize();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','S','I','Z'), &size, sizeof( size ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('B','S','I','Z'), size);
//Save out the raw data
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','M','E','M'), bm->GetData(), size );
+ ::sg_write_no_cast(m_owner->GetInterface(), INT_ID('B','M','E','M'), bm->GetData(), size);
}
return true;
@@ -387,30 +387,30 @@ int CSequence::Save( void )
//Save the parent (by GUID)
id = ( m_parent != NULL ) ? m_parent->GetID() : -1;
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','P','I','D'), &id, sizeof( id ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('S','P','I','D'), id);
//Save the return (by GUID)
id = ( m_return != NULL ) ? m_return->GetID() : -1;
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','R','I','D'), &id, sizeof( id ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('S','R','I','D'), id);
//Save the number of children
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','N','C','H'), &m_numChildren, sizeof( m_numChildren ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('S','N','C','H'), m_numChildren);
//Save out the children (only by GUID)
STL_ITERATE( ci, m_children )
{
id = (*ci)->GetID();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','C','H','D'), &id, sizeof( id ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('S','C','H','D'), id);
}
//Save flags
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','F','L','G'), &m_flags, sizeof( m_flags ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('S','F','L','G'), m_flags);
//Save iterations
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','I','T','R'), &m_iterations, sizeof( m_iterations ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('S','I','T','R'), m_iterations);
//Save the number of commands
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','N','M','C'), &m_numCommands, sizeof( m_numCommands ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('S','N','M','C'), m_numCommands);
//Save the commands
STL_ITERATE( bi, m_commands )
diff --git a/codeJK2/icarus/Sequencer.cpp b/codeJK2/icarus/Sequencer.cpp
index 3d5b051..0d80d5f 100644
--- a/codeJK2/icarus/Sequencer.cpp
+++ b/codeJK2/icarus/Sequencer.cpp
@@ -2330,16 +2330,16 @@ int CSequencer::Save( void )
numSequences = m_sequences.size();
//Save out the owner sequence
- m_ie->I_WriteSaveData( INT_ID('S','Q','R','E'), &m_ownerID, sizeof( m_ownerID ) );
+ ::sg_write<int32_t>(m_ie, INT_ID('S','Q','R','E'), m_ownerID);
//Write out the number of sequences we need to read
- m_ie->I_WriteSaveData( INT_ID('S','Q','R','#'), &numSequences, sizeof( numSequences ) );
+ ::sg_write<int32_t>(m_ie, INT_ID('S','Q','R','#'), numSequences);
//Second pass, save out all sequences, in order
STL_ITERATE( si, m_sequences )
{
id = (*si)->GetID();
- m_ie->I_WriteSaveData( INT_ID('S','Q','R','I'), &id, sizeof( id ) );
+ ::sg_write<int32_t>(m_ie, INT_ID('S','Q','R','I'), id);
}
//Save out the taskManager
@@ -2347,29 +2347,29 @@ int CSequencer::Save( void )
//Save out the task sequences mapping the name to the GUIDs
numTasks = m_taskSequences.size();
- m_ie->I_WriteSaveData( INT_ID('S','Q','T','#'), &numTasks, sizeof ( numTasks ) );
+ ::sg_write<int32_t>(m_ie, INT_ID('S','Q','T','#'), numTasks);
STL_ITERATE( ti, m_taskSequences )
{
//Save the task group's ID
id = ((*ti).first)->GetGUID();
- m_ie->I_WriteSaveData( INT_ID('S','T','I','D'), &id, sizeof( id ) );
+ ::sg_write<int32_t>(m_ie, INT_ID('S','T','I','D'), id);
//Save the sequence's ID
id = ((*ti).second)->GetID();
- m_ie->I_WriteSaveData( INT_ID('S','S','I','D'), &id, sizeof( id ) );
+ ::sg_write<int32_t>(m_ie, INT_ID('S','S','I','D'), id);
}
int curGroupID = ( m_curGroup == NULL ) ? -1 : m_curGroup->GetGUID();
- m_ie->I_WriteSaveData( INT_ID('S','Q','C','T'), &curGroupID, sizeof ( m_numCommands ) );
+ ::sg_write<int32_t>(m_ie, INT_ID('S','Q','C','T'), curGroupID);
//Output the number of commands
- m_ie->I_WriteSaveData( INT_ID('S','Q','#','C'), &m_numCommands, sizeof ( m_numCommands ) ); //FIXME: This can be reconstructed
+ ::sg_write<int32_t>(m_ie, INT_ID('S','Q','#','C'), m_numCommands); //FIXME: This can be reconstructed
//Output the ID of the current sequence
id = ( m_curSequence != NULL ) ? m_curSequence->GetID() : -1;
- m_ie->I_WriteSaveData( INT_ID('S','Q','C','S'), &id, sizeof ( id ) );
+ ::sg_write<int32_t>(m_ie, INT_ID('S','Q','C','S'), id);
return true;
}
diff --git a/codeJK2/icarus/TaskManager.cpp b/codeJK2/icarus/TaskManager.cpp
index 5123b00..f51b492 100644
--- a/codeJK2/icarus/TaskManager.cpp
+++ b/codeJK2/icarus/TaskManager.cpp
@@ -1641,15 +1641,15 @@ int CTaskManager::SaveCommand( CBlock *block )
//Save out the block ID
bID = block->GetBlockID();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','L','I','D'), &bID, sizeof ( bID ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('B','L','I','D'), bID);
//Save out the block's flags
flags = block->GetFlags();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','F','L','G'), &flags, sizeof ( flags ) );
+ ::sg_write<uint8_t>(m_owner->GetInterface(), INT_ID('B','F','L','G'), flags);
//Save out the number of members to read
numMembers = block->GetNumMembers();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','N','U','M'), &numMembers, sizeof ( numMembers ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('B','N','U','M'), numMembers);
for ( int i = 0; i < numMembers; i++ )
{
@@ -1657,14 +1657,14 @@ int CTaskManager::SaveCommand( CBlock *block )
//Save the block id
bID = bm->GetID();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','M','I','D'), &bID, sizeof ( bID ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('B','M','I','D'), bID);
//Save out the data size
size = bm->GetSize();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','S','I','Z'), &size, sizeof( size ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('B','S','I','Z'), size);
//Save out the raw data
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('B','M','E','M'), bm->GetData(), size );
+ ::sg_write_no_cast(m_owner->GetInterface(), INT_ID('B','M','E','M'), bm->GetData(), size);
}
return true;
@@ -1687,11 +1687,11 @@ void CTaskManager::Save( void )
int numWritten;
//Save the taskmanager's GUID
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','M','I','D'), &m_GUID, sizeof( m_GUID ) ); //FIXME: This can be reconstructed
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','M','I','D'), m_GUID); //FIXME: This can be reconstructed
//Save out the number of tasks that will follow
int iNumTasks = m_tasks.size();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','S','K','#'), &iNumTasks, sizeof(iNumTasks) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','S','K','#'), iNumTasks);
//Save out all the tasks
tasks_l::iterator ti;
@@ -1700,11 +1700,11 @@ void CTaskManager::Save( void )
{
//Save the GUID
id = (*ti)->GetGUID();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','K','I','D'), &id, sizeof ( id ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','K','I','D'), id);
//Save the timeStamp (FIXME: Although, this is going to be worthless if time is not consistent...)
timeStamp = (*ti)->GetTimeStamp();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','K','T','S'), &timeStamp, sizeof ( timeStamp ) );
+ ::sg_write<uint32_t>(m_owner->GetInterface(), INT_ID('T','K','T','S'), timeStamp);
//Save out the block
block = (*ti)->GetBlock();
@@ -1713,14 +1713,14 @@ void CTaskManager::Save( void )
//Save out the number of task groups
int numTaskGroups = m_taskGroups.size();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','G','#','G'), &numTaskGroups, sizeof( numTaskGroups ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','G','#','G'), numTaskGroups);
//Save out the IDs of all the task groups
numWritten = 0;
taskGroup_v::iterator tgi;
STL_ITERATE( tgi, m_taskGroups )
{
id = (*tgi)->GetGUID();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','K','G','#'), &id, sizeof( id ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','K','G','#'), id);
numWritten++;
}
assert (numWritten == numTaskGroups);
@@ -1731,11 +1731,11 @@ void CTaskManager::Save( void )
{
//Save out the parent
id = ( (*tgi)->GetParent() == NULL ) ? -1 : ((*tgi)->GetParent())->GetGUID();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','K','G','P'), &id, sizeof( id ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','K','G','P'), id);
//Save out the number of commands
numCommands = (*tgi)->m_completedTasks.size();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','G','N','C'), &numCommands, sizeof( numCommands ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','G','N','C'), numCommands);
//Save out the command map
CTaskGroup::taskCallback_m::iterator tci;
@@ -1744,16 +1744,16 @@ void CTaskManager::Save( void )
{
//Write out the ID
id = (*tci).first;
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('G','M','I','D'), &id, sizeof( id ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('G','M','I','D'), id);
//Write out the state of completion
completed = (*tci).second;
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('G','M','D','N'), &completed, sizeof( completed ) );
+ ::sg_write<uint8_t>(m_owner->GetInterface(), INT_ID('G','M','D','N'), completed);
}
//Save out the number of completed commands
id = (*tgi)->m_numCompleted;
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','G','D','N'), &id, sizeof( id ) ); //FIXME: This can be reconstructed
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','G','D','N'), id); //FIXME: This can be reconstructed
numWritten++;
}
assert (numWritten == numTaskGroups);
@@ -1763,7 +1763,7 @@ void CTaskManager::Save( void )
{
//Save out the currently active group
int curGroupID = ( m_curGroup == NULL ) ? -1 : m_curGroup->GetGUID();
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','G','C','G'), &curGroupID, sizeof( curGroupID ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','G','C','G'), curGroupID);
}
//Save out the task group name maps
@@ -1779,17 +1779,17 @@ void CTaskManager::Save( void )
int length = strlen( name ) + 1;
//Save out the string size
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','G','N','L'), &length, sizeof ( length ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','G','N','L'), length);
//Write out the string
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','G','N','S'), (void *) name, length );
+ ::sg_write_no_cast(m_owner->GetInterface(), INT_ID('T','G','N','S'), name, length);
taskGroup = (*tmi).second;
id = taskGroup->GetGUID();
//Write out the ID
- (m_owner->GetInterface())->I_WriteSaveData( INT_ID('T','G','N','I'), &id, sizeof( id ) );
+ ::sg_write<int32_t>(m_owner->GetInterface(), INT_ID('T','G','N','I'), id);
numWritten++;
}
assert (numWritten == numTaskGroups);
diff --git a/codeJK2/icarus/interface.h b/codeJK2/icarus/interface.h
index aca6e3f..051c8c9 100644
--- a/codeJK2/icarus/interface.h
+++ b/codeJK2/icarus/interface.h
@@ -81,7 +81,7 @@ typedef struct interface_export_s
//Save / Load functions
- int (*I_WriteSaveData)( unsigned int chid, void *data, int length );
+ int (*I_WriteSaveData)( unsigned int chid, const void *data, int length );
int (*I_ReadSaveData)( unsigned int chid, void *address, int length, void **addressptr/* = NULL */);
int (*I_LinkEntity)( int entID, CSequencer *sequencer, CTaskManager *taskManager );
diff --git a/codemp/icarus/Q3_Interface.cpp b/codemp/icarus/Q3_Interface.cpp
index 667bafe..059d65d 100644
--- a/codemp/icarus/Q3_Interface.cpp
+++ b/codemp/icarus/Q3_Interface.cpp
@@ -710,7 +710,7 @@ void CGCam_Anything( void )
}
//These are useless for MP. Just taking it for now since I don't want to remove all calls to this in ICARUS.
-int AppendToSaveGame(unsigned long chid, void *data, int length)
+int AppendToSaveGame(unsigned long chid, const void *data, int length)
{
return 1;
}
diff --git a/codemp/icarus/interface.h b/codemp/icarus/interface.h
index 6013e45..4bfbba5 100644
--- a/codemp/icarus/interface.h
+++ b/codemp/icarus/interface.h
@@ -77,7 +77,7 @@ typedef struct interface_export_s
//Save / Load functions
- int (*I_WriteSaveData)( unsigned long chid, void *data, int length );
+ int (*I_WriteSaveData)( unsigned long chid, const void *data, int length );
// Below changed by BTO (VV). Visual C++ 7.1 compiler no longer allows default args on function pointers. Ack.
int (*I_ReadSaveData)( unsigned long chid, void *address, int length /* , void **addressptr = NULL */ );
int (*I_LinkEntity)( int entID, CSequencer *sequencer, CTaskManager *taskManager );
diff --git a/shared/qcommon/ojk_sg_wrappers.h b/shared/qcommon/ojk_sg_wrappers.h
index 2babdc3..bb08838 100644
--- a/shared/qcommon/ojk_sg_wrappers.h
+++ b/shared/qcommon/ojk_sg_wrappers.h
@@ -20,9 +20,14 @@
using SgReadFunc = std::function<int (
unsigned int chunk_id,
- void *value_storage,
+ void* value_storage,
int value_size,
- void **allocated_value)>;
+ void** allocated_value)>;
+
+using SgWriteFunc = std::function<int (
+ unsigned int chunk_id,
+ const void* value_storage,
+ int value_size)>;
template<typename T, std::size_t TCount>
@@ -146,6 +151,90 @@ private:
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ // WriteSaveData
+
+ template<typename U>
+ static auto test_write_save_data(int) -> decltype(
+ std::declval<U>().WriteSaveData(
+ static_cast<unsigned int>(0),
+ static_cast<const void*>(nullptr),
+ static_cast<int>(0)
+ ) == 0,
+
+ yes()
+ );
+
+ template<typename>
+ static no test_write_save_data(...);
+
+ // WriteSaveData
+ // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+ // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ // I_WriteSaveData
+
+ template<typename U>
+ static auto test_i_write_save_data(int) -> decltype(
+ std::declval<U>().I_WriteSaveData(
+ static_cast<unsigned int>(0),
+ static_cast<const void*>(nullptr),
+ static_cast<int>(0)
+ ) == 0,
+
+ yes()
+ );
+
+ template<typename>
+ static no test_i_write_save_data(...);
+
+ // I_WriteSaveData
+ // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+ // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ // AppendToSaveGame
+
+ template<typename U>
+ static auto test_append_to_save_game(int) -> decltype(
+ std::declval<U>().AppendToSaveGame(
+ static_cast<unsigned int>(0),
+ static_cast<const void*>(nullptr),
+ static_cast<int>(0)
+ ) == 0,
+
+ yes()
+ );
+
+ template<typename>
+ static no test_append_to_save_game(...);
+
+ // AppendToSaveGame
+ // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+ // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ // SG_Append
+
+ template<typename U>
+ static auto test_sg_append(int) -> decltype(
+ std::declval<U>().SG_Append(
+ static_cast<unsigned int>(0),
+ static_cast<const void*>(nullptr),
+ static_cast<int>(0)
+ ) == 0,
+
+ yes()
+ );
+
+ template<typename>
+ static no test_sg_append(...);
+
+ // SG_Append
+ // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+ // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// has_sg_export
template<typename U>
@@ -222,6 +311,26 @@ public:
return std::is_same<decltype(test_read_from_save_game<T>(0)), yes>::value;
}
+ static constexpr bool has_write_save_data()
+ {
+ return std::is_same<decltype(test_write_save_data<T>(0)), yes>::value;
+ }
+
+ static constexpr bool has_i_write_save_data()
+ {
+ return std::is_same<decltype(test_i_write_save_data<T>(0)), yes>::value;
+ }
+
+ static constexpr bool has_append_to_save_game()
+ {
+ return std::is_same<decltype(test_append_to_save_game<T>(0)), yes>::value;
+ }
+
+ static constexpr bool has_sg_append()
+ {
+ return std::is_same<decltype(test_sg_append<T>(0)), yes>::value;
+ }
+
static constexpr bool has_sg_export()
{
return std::is_same<decltype(test_sg_export<T>(0)), yes>::value;
@@ -304,6 +413,26 @@ class SgReadFromSaveGameFuncTag
public:
}; // SgReadFromSaveGameFuncTag
+class SgSgAppendFuncTag
+{
+public:
+}; // SgSgAppendFuncTag
+
+class SgWriteSaveDataFuncTag
+{
+public:
+}; // SgWriteSaveDataFuncTag
+
+class SgIWriteSaveDataFuncTag
+{
+public:
+}; // SgIWriteSaveDataFuncTag
+
+class SgAppendToSaveGameFuncTag
+{
+public:
+}; // SgAppendToSaveGameFuncTag
+
} // detail
@@ -311,8 +440,8 @@ public:
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// sg_get_read_func
//
-// Returns a function wrapper for a function pointer, pointer to an object or
-// a reference to an object.
+// Returns a read function wrapper for a function pointer,
+// pointer to an object or a reference to an object.
//
namespace detail {
@@ -433,6 +562,142 @@ inline SgReadFunc sg_get_read_func(
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// sg_get_write_func
+//
+// Returns a write function wrapper for a function pointer,
+// pointer to an object or a reference to an object.
+//
+
+namespace detail {
+
+
+template<typename TFunc>
+inline SgWriteFunc sg_get_write_func(
+ TFunc& func,
+ SgFuncTag)
+{
+ return func;
+}
+
+template<typename TInstance>
+inline SgWriteFunc sg_get_write_func(
+ TInstance* instance,
+ SgPointerTag,
+ SgSgAppendFuncTag)
+{
+ return instance->SG_Append;
+}
+
+template<typename TInstance>
+inline SgWriteFunc sg_get_write_func(
+ TInstance* instance,
+ SgPointerTag,
+ SgWriteSaveDataFuncTag)
+{
+ return std::bind(
+ &TInstance::WriteSaveData,
+ instance,
+ std::placeholders::_1,
+ std::placeholders::_2,
+ std::placeholders::_3);
+}
+
+template<typename TInstance>
+inline SgWriteFunc sg_get_write_func(
+ TInstance* instance,
+ SgPointerTag,
+ SgIWriteSaveDataFuncTag)
+{
+ return instance->I_WriteSaveData;
+}
+
+template<typename TInstance>
+inline SgWriteFunc sg_get_write_func(
+ TInstance* instance,
+ SgPointerTag,
+ SgAppendToSaveGameFuncTag)
+{
+ return instance->AppendToSaveGame;
+}
+
+template<typename TInstance>
+inline SgWriteFunc sg_get_write_func(
+ TInstance* instance,
+ SgPointerTag)
+{
+ using Tag = typename std::conditional<
+ SgTraits<TInstance>::has_sg_append(),
+ SgSgAppendFuncTag,
+ typename std::conditional<
+ SgTraits<TInstance>::has_write_save_data(),
+ SgWriteSaveDataFuncTag,
+ typename std::conditional<
+ SgTraits<TInstance>::has_i_write_save_data(),
+ SgIWriteSaveDataFuncTag,
+ typename std::conditional<
+ SgTraits<TInstance>::has_append_to_save_game(),
+ SgAppendToSaveGameFuncTag,
+ void
+ >::type
+ >::type
+ >::type
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported instance type.");
+
+ return sg_get_write_func(
+ instance,
+ SgPointerTag(),
+ Tag());
+}
+
+template<typename TInstance>
+inline SgWriteFunc sg_get_write_func(
+ TInstance& instance,
+ SgClassTag)
+{
+ return sg_get_write_func(
+ &instance,
+ SgPointerTag());
+}
+
+template<typename TInstance>
+inline SgWriteFunc sg_get_write_func(
+ TInstance& instance)
+{
+ using Tag = typename std::conditional<
+ std::is_function<TInstance>::value,
+ SgFuncTag,
+ typename std::conditional<
+ std::is_class<TInstance>::value,
+ SgClassTag,
+ typename std::conditional<
+ std::is_pointer<TInstance>::value,
+ SgPointerTag,
+ void
+ >::type
+ >::type
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported instance type.");
+
+ return sg_get_write_func(
+ instance,
+ Tag());
+}
+
+
+} // detail
+
+// sg_get_write_func
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// sg_export
//
// Exports a value or a fixed-array of values from a
@@ -1058,10 +1323,6 @@ inline int sg_read_no_cast(
!std::is_same<Tag, void>::value,
"Unsupported types.");
- if (!dst_values) {
- throw SgException("Null pointer.");
- }
-
return sg_read_no_cast(
read_func,
chunk_id,
@@ -1335,7 +1596,7 @@ inline int sg_read(
SgPointerTag)
{
if (!dst_values) {
- throw SgException("Null destination poiner.");
+ throw SgException("Null pointer.");
}
const auto src_size = static_cast<int>(dst_count * sizeof(TSrc));
@@ -1402,7 +1663,7 @@ inline int sg_read(
"Unsupported types.");
if (dst_count < 0) {
- throw SgException("Negative destination count.");
+ throw SgException("Negative count.");
}
auto read_func = detail::sg_get_read_func(
@@ -1487,6 +1748,565 @@ inline int sg_read_allocate(
}
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// sg_write_no_cast (fixed size)
+//
+// Writes a value or a fixed-size array of values into a
+// saved game without conversion.
+//
+
+namespace detail {
+
+
+template<typename TSrc>
+inline int sg_write_no_cast(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc& src_value,
+ SgNumericTag)
+{
+ constexpr auto src_size = static_cast<int>(sizeof(TSrc));
+
+ return write_func(
+ chunk_id,
+ const_cast<TSrc*>(&src_value),
+ src_size);
+}
+
+template<typename TSrc>
+inline int sg_write_no_cast(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc& src_value,
+ SgClassTag)
+{
+ using SgType = typename TSrc::SgType;
+
+ constexpr auto dst_size = static_cast<int>(sizeof(SgType));
+
+ auto& dst_buffer = sg_get_buffer(
+ dst_size);
+
+ auto& dst_value = *reinterpret_cast<SgType*>(dst_buffer.data());
+
+ ::sg_export(src_value, dst_value);
+
+ return write_func(
+ chunk_id,
+ &dst_value,
+ dst_size);
+}
+
+template<typename TSrc, std::size_t TCount>
+inline int sg_write_no_cast(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc (&src_values)[TCount],
+ SgArray1dTag,
+ SgNumericTag)
+{
+ constexpr auto src_size = static_cast<int>(TCount * sizeof(TSrc));
+
+ return write_func(
+ chunk_id,
+ const_cast<TSrc*>(&src_values[0]),
+ src_size);
+}
+
+template<typename TSrc, std::size_t TCount>
+inline int sg_write_no_cast(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc (&src_values)[TCount],
+ SgArray1dTag,
+ SgClassTag)
+{
+ using SgType = typename TSrc::SgType;
+
+ constexpr auto dst_size = static_cast<int>(TCount * sizeof(SgType));
+
+ auto& dst_buffer = sg_get_buffer(
+ dst_size);
+
+ auto dst_values = reinterpret_cast<SgType*>(dst_buffer.data());
+
+ for (decltype(TCount) i = 0; i < TCount; ++i) {
+ ::sg_export(src_values[i], dst_values[i]);
+ }
+
+ return write_func(
+ chunk_id,
+ dst_values,
+ dst_size);
+}
+
+template<typename TSrc, std::size_t TCount>
+inline int sg_write_no_cast(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc (&src_values)[TCount],
+ SgArray1dTag)
+{
+ using Tag = typename std::conditional<
+ std::is_same<TSrc, bool>::value,
+ void,
+ typename std::conditional<
+ detail::SgTraits<TSrc>::is_numeric(),
+ detail::SgNumericTag,
+ typename std::conditional<
+ detail::SgTraits<TSrc>::has_sg_export(),
+ detail::SgClassTag,
+ void
+ >::type
+ >::type
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported types.");
+
+ return sg_write_no_cast(
+ write_func,
+ chunk_id,
+ src_values,
+ SgArray1dTag(),
+ Tag()
+ );
+}
+
+
+} // detail
+
+
+template<typename TSrc, typename TInstance>
+inline int sg_write_no_cast(
+ TInstance&& instance,
+ unsigned int chunk_id,
+ const TSrc& src_value)
+{
+ using Tag = typename std::conditional<
+ std::is_same<TSrc, bool>::value,
+ void,
+ typename std::conditional<
+ detail::SgTraits<TSrc>::is_numeric(),
+ detail::SgNumericTag,
+ typename std::conditional<
+ detail::SgTraits<TSrc>::has_sg_export(),
+ detail::SgClassTag,
+ typename std::conditional<
+ detail::SgTraits<TSrc>::is_array_1d(),
+ detail::SgArray1dTag,
+ void
+ >::type
+ >::type
+ >::type
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported types.");
+
+ auto write_func = detail::sg_get_write_func(
+ instance);
+
+ return detail::sg_write_no_cast(
+ write_func,
+ chunk_id,
+ src_value,
+ Tag());
+}
+
+// sg_write_no_cast (fixed size)
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// sg_write_no_cast (dynamic size)
+//
+// Writes a specified number of values into a
+// saved game without conversion.
+//
+
+namespace detail {
+
+
+template<typename TSrc>
+inline int sg_write_no_cast(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc* src_values,
+ int src_count,
+ SgPointerTag,
+ SgVoidTag)
+{
+ return write_func(
+ chunk_id,
+ const_cast<TSrc*>(src_values),
+ src_count);
+}
+
+template<typename TSrc>
+inline int sg_write_no_cast(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc* src_values,
+ int src_count,
+ SgPointerTag,
+ SgNumericTag)
+{
+ const auto src_size = static_cast<int>(src_count * sizeof(TSrc));
+
+ return write_func(
+ chunk_id,
+ const_cast<TSrc*>(src_values),
+ src_size);
+}
+
+template<typename TSrc>
+inline int sg_write_no_cast(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc* src_values,
+ int src_count,
+ SgPointerTag)
+{
+ using Tag = typename std::conditional<
+ std::is_same<TSrc, bool>::value,
+ void,
+ typename std::conditional<
+ SgTraits<TSrc>::is_numeric(),
+ SgNumericTag,
+ typename std::conditional<
+ std::is_same<TSrc, void>::value,
+ SgVoidTag,
+ void
+ >::type
+ >::type
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported types.");
+
+ if (!src_values) {
+ throw SgException("Null pointer.");
+ }
+
+ return sg_write_no_cast(
+ write_func,
+ chunk_id,
+ src_values,
+ src_count,
+ SgPointerTag(),
+ Tag());
+}
+
+template<typename TSrc, std::size_t TCount>
+inline int sg_write_no_cast(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc (&src_values)[TCount],
+ int src_count,
+ SgArray1dTag)
+{
+ if (src_count > TCount) {
+ throw SgException("Write overflow.");
+ }
+
+ return sg_write_no_cast(
+ write_func,
+ chunk_id,
+ &src_values[0],
+ src_count,
+ SgPointerTag());
+}
+
+
+} // detail
+
+
+template<typename TSrc, typename TInstance>
+inline int sg_write_no_cast(
+ TInstance&& instance,
+ unsigned int chunk_id,
+ TSrc&& src_value,
+ int src_count)
+{
+ using TSrcTag = typename std::remove_reference<TSrc>::type;
+
+ using Tag = typename std::conditional<
+ std::is_same<TSrcTag, bool>::value,
+ void,
+ typename std::conditional<
+ std::is_pointer<TSrcTag>::value,
+ detail::SgPointerTag,
+ typename std::conditional<
+ detail::SgTraits<TSrcTag>::is_array_1d(),
+ detail::SgArray1dTag,
+ void
+ >::type
+ >::type
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported types.");
+
+
+ auto write_func = detail::sg_get_write_func(
+ instance);
+
+ return detail::sg_write_no_cast(
+ write_func,
+ chunk_id,
+ src_value,
+ src_count,
+ Tag());
+}
+
+// sg_write_no_cast (dynamic size)
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// sg_write (fixed size)
+//
+// Writes a value or a fixed-array of values into a
+// saved game with conversion.
+//
+
+namespace detail {
+
+
+template<typename TDst, typename TSrc>
+inline int sg_write(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc& src_value,
+ SgNumericTag)
+{
+ auto dst_value = static_cast<TDst>(src_value);
+ constexpr auto dst_size = static_cast<int>(sizeof(TDst));
+
+ return write_func(
+ chunk_id,
+ &dst_value,
+ dst_size);
+}
+
+template<typename TDst, typename TSrc>
+inline int sg_write(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc& src_value,
+ SgPointerTag)
+{
+ auto dst_value = static_cast<TDst>(reinterpret_cast<std::intptr_t>(src_value));
+
+ constexpr auto dst_size = static_cast<int>(sizeof(TDst));
+
+ return write_func(
+ chunk_id,
+ &dst_value,
+ dst_size);
+}
+
+template<typename TDst, typename TSrc, std::size_t TCount>
+inline int sg_write(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc (&src_values)[TCount],
+ SgArray1dTag,
+ SgNumericTag)
+{
+ constexpr auto dst_size = static_cast<int>(TCount * sizeof(TDst));
+
+ auto& dst_buffer = sg_get_buffer(
+ dst_size);
+
+ auto dst_values = reinterpret_cast<TDst*>(dst_buffer.data());
+
+ std::uninitialized_copy_n(
+ src_values,
+ TCount,
+ dst_values);
+
+ return write_func(
+ chunk_id,
+ dst_values,
+ dst_size);
+}
+
+template<typename TDst, typename TSrc, std::size_t TCount>
+inline int sg_write(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc (&src_values)[TCount],
+ SgArray1dTag)
+{
+ using Tag = typename std::conditional<
+ SgTraits<TSrc>::is_numeric() && SgTraits<TDst>::is_numeric(),
+ SgNumericTag,
+ void
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported types.");
+
+ return sg_write<TDst>(
+ write_func,
+ chunk_id,
+ src_values,
+ SgArray1dTag(),
+ Tag());
+}
+
+
+} // detail
+
+
+template<typename TDst, typename TSrc, typename TInstance>
+inline int sg_write(
+ TInstance&& instance,
+ unsigned int chunk_id,
+ const TSrc& src_value)
+{
+ using Tag = typename std::conditional<
+ detail::SgTraits<TSrc>::is_numeric() &&
+ detail::SgTraits<TDst>::is_numeric(),
+ detail::SgNumericTag,
+ typename std::conditional<
+ std::is_pointer<TSrc>::value &&
+ detail::SgTraits<TDst>::is_numeric(),
+ detail::SgPointerTag,
+ typename std::conditional<
+ detail::SgTraits<TSrc>::is_array_1d(),
+ detail::SgArray1dTag,
+ void
+ >::type
+ >::type
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported types.");
+
+ auto write_func = detail::sg_get_write_func(
+ instance);
+
+ return detail::sg_write<TDst>(
+ write_func,
+ chunk_id,
+ src_value,
+ Tag());
+}
+
+// sg_write (fixed size)
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// sg_write (dynamic size)
+//
+// Reads a spesified number of values from a
+// saved game with conversion.
+//
+
+namespace detail {
+
+
+template<typename TDst, typename TSrc>
+inline int sg_write(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc* src_values,
+ int src_count,
+ SgPointerTag)
+{
+ if (!src_values) {
+ throw SgException("Null pointer.");
+ }
+
+ const auto dst_size = static_cast<int>(src_count * sizeof(TDst));
+
+ auto& dst_buffer = sg_get_buffer(
+ dst_size);
+
+ auto dst_values = reinterpret_cast<TDst*>(dst_buffer.data());
+
+ std::uninitialized_copy_n(
+ src_values,
+ src_count,
+ dst_values);
+
+ return write_func(
+ chunk_id,
+ dst_values,
+ dst_size);
+}
+
+template<typename TDst, typename TSrc, std::size_t TCount>
+inline int sg_write(
+ SgWriteFunc& write_func,
+ unsigned int chunk_id,
+ const TSrc (&src_values)[TCount],
+ int src_count,
+ SgArray1dTag)
+{
+ return sg_write<TDst>(
+ write_func,
+ chunk_id,
+ &src_values[0],
+ src_count,
+ SgPointerTag());
+}
+
+
+} // detail
+
+
+template<typename TDst, typename TSrc, typename TInstance>
+inline int sg_write(
+ TInstance&& instance,
+ unsigned int chunk_id,
+ const TSrc& src_value,
+ int src_count)
+{
+ using Tag = typename std::conditional<
+ std::is_pointer<TSrc>::value &&
+ detail::SgTraits<TDst>::is_numeric(),
+ detail::SgPointerTag,
+ typename std::conditional<
+ detail::SgTraits<TSrc>::is_array_1d(),
+ detail::SgArray1dTag,
+ void
+ >::type
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported types.");
+
+ if (src_count < 0) {
+ throw SgException("Negative count.");
+ }
+
+ auto write_func = detail::sg_get_write_func(
+ instance);
+
+ return detail::sg_write<TDst>(
+ write_func,
+ chunk_id,
+ src_value,
+ src_count,
+ Tag());
+}
+
+// sg_write (dynamic size)
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
#endif // __cplusplus
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/openjk.git
More information about the Pkg-games-commits
mailing list