25 #include "../../cl_shared.h"
26 #include "../cl_game.h"
69 len = strlen(header->
name);
70 if (len >
sizeof(header->
name)) {
80 if (len >
sizeof(header->
gameDate)) {
85 if (len >
sizeof(header->
realDate)) {
90 cgi->Com_DPrintf(
DEBUG_CLIENT,
"Savefile has incompatible amount of subsystems\n");
94 if (header->
xmlSize > 15 * 1024 * 1024) {
95 cgi->Com_Printf(
"Save size seems to be to large (over 15 MB) %i.\n", header->
xmlSize);
99 cgi->Com_Printf(
"Version is invalid - must be greater than zero\n");
103 cgi->Com_Printf(
"Savefile is newer than the game!\n");
125 cgi->Com_Printf(
"Couldn't open file '%s'\n", filename);
159 const int clen =
cgi->FS_OpenFile(filename, &f,
FILE_READ);
161 cgi->Com_Printf(
"Couldn't open file '%s'\n", filename);
162 *error =
"File not found";
167 if (
cgi->FS_Read(cbuf, clen, &f) != clen)
168 cgi->Com_Printf(
"Warning: Could not read %i bytes from savefile\n", clen);
169 cgi->Com_Printf(
"Loading savegame xml (size %d)\n", clen);
172 memcpy(&header, cbuf,
sizeof(header));
180 cgi->Com_Printf(
"The Header of the savegame '%s.%s' is corrupted. Loading aborted\n", filename,
SAVEGAME_EXTENSION);
182 *error =
"Corrupted header";
186 cgi->Com_Printf(
"Loading savegame\n"
188 "...game version: %s\n"
189 "...xml Size: %i, compressed? %c\n",
197 const int res = uncompress(buf, &len, cbuf +
sizeof(header), clen -
sizeof(header));
203 *error =
_(
"Error decompressing data");
204 cgi->Com_Printf(
"Error decompressing data in '%s'.\n", filename);
210 cgi->Com_Printf(
"Error: Failure in loading the xml data!\n");
211 *error =
"Corrupted xml data";
216 topNode =
cgi->
XML_Parse((
const char*)(cbuf +
sizeof(header)));
219 cgi->Com_Printf(
"Error: Failure in loading the xml data!\n");
220 *error =
"Corrupted xml data";
226 cgi->GAME_ReloadMode();
229 cgi->Com_Printf(
"Error: Failure in loading the xml data! (savegame node not found)\n");
231 *error =
"Invalid xml data";
237 if (!saveSubsystems[
i].load)
239 cgi->Com_Printf(
"...Running subsystem '%s'\n", saveSubsystems[
i].
name);
240 if (!saveSubsystems[
i].load(node)) {
241 cgi->Com_Printf(
"...subsystem '%s' returned false - savegame could not be loaded\n",
242 saveSubsystems[
i].name);
243 *error =
va(
"Could not load subsystem %s", saveSubsystems[
i].name);
246 cgi->Com_Printf(
"...subsystem '%s' - loaded.\n", saveSubsystems[
i].name);
252 cgi->Com_Printf(
"Savegame postprocessing returned false - savegame could not be loaded\n");
253 *error =
"Postprocessing failed";
257 cgi->Com_Printf(
"File '%s' successfully loaded from %s xml savegame.\n",
258 filename, header.
compressed ?
"compressed" :
"");
260 cgi->UI_InitStack(
"geoscape",
"campaign_main");
271 *error =
_(
"Saving is not possible: Campaign is not active.");
274 if (
cgi->CL_OnBattlescape()) {
276 *error =
_(
"Saving is not possible: Cannot save the Battlescape.");
281 *error =
_(
"Saving is not possible: No base is built.");
296 cgi->Com_Printf(*error);
303 char timeStampBuffer[32];
320 cgi->Com_Printf(
"Calling subsystems\n");
322 if (!saveSubsystems[
i].save)
324 if (!saveSubsystems[
i].save(node))
325 cgi->Com_Printf(
"...subsystem '%s' failed to save the data\n", saveSubsystems[
i].
name);
327 cgi->Com_Printf(
"...subsystem '%s' - saved\n", saveSubsystems[
i].name);
344 int requiredBufferLength = mxmlSaveString(topNode, dummy, 2, MXML_NO_CALLBACK);
350 *error =
_(
"Could not allocate enough memory to save this game");
351 cgi->Com_Printf(
"Error: Could not allocate enough memory to save this game\n");
354 int res = mxmlSaveString(topNode, (
char*)buf, requiredBufferLength + 1, MXML_NO_CALLBACK);
356 cgi->Com_Printf(
"XML Written to buffer (%d Bytes)\n", res);
360 bufLen = compressBound(requiredBufferLength);
362 bufLen = requiredBufferLength;
365 memcpy(fbuf, &header,
sizeof(header));
368 res = compress(fbuf +
sizeof(header), &bufLen, buf, requiredBufferLength);
373 *error =
_(
"Memory error compressing save-game data - set save_compressed cvar to 0");
374 cgi->Com_Printf(
"Memory error compressing save-game data (%s) (Error: %i)!\n", comment, res);
378 memcpy(fbuf +
sizeof(header), buf, requiredBufferLength);
383 cgi->FS_WriteFile(fbuf, bufLen +
sizeof(header), savegame);
404 cgi->Com_Printf(
"added %s subsystem\n", subsystem->
name);
440 cgi->Com_Printf(
"\n--- save subsystem initialization --\n");
465 save_compressed =
cgi->
Cvar_Get(
"save_compressed",
"1",
CVAR_ARCHIVE,
"Save the savefiles compressed if set to 1");
bool E_SaveXML(xmlNode_t *p)
Save callback for savegames in XML Format.
bool(* save)(xmlNode_t *parent)
void SAV_Init(void)
Register all save-subsystems and init some cvars and commands.
struct saveFileHeader_s saveFileHeader_t
bool B_SaveXML(xmlNode_t *parent)
Save callback for saving in xml format.
void RADAR_SetRadarAfterLoading(void)
Set radar to proper values after loading.
bool BS_SaveXML(xmlNode_t *parent)
Save callback for savegames.
bool CP_IsRunning(void)
Checks whether a campaign mode game is running.
static saveSubsystems_t saveSubsystems[MAX_SAVESUBSYSTEMS]
static bool SAV_GameActionsAfterLoad(void)
Perform actions after loading a game for single player campaign.
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
bool AIR_PostLoadInit(void)
Actions needs to be done after loading the savegame.
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
static bool SAV_VerifyHeader(saveFileHeader_t const *const header)
Tries to verify the Header of the savegame.
bool E_LoadXML(xmlNode_t *p)
Load callback for savegames in XML Format.
bool MS_LoadXML(xmlNode_t *p)
Load callback for messages.
static cvar_t * save_compressed
#define SAVEGAME_EXTENSION
bool RS_LoadXML(xmlNode_t *parent)
Load callback for research and technologies.
#define B_AtLeastOneExists()
bool XVI_SaveXML(xmlNode_t *parent)
XVI map saving callback.
bool B_LoadXML(xmlNode_t *parent)
Loads base data.
bool INS_SaveXML(xmlNode_t *p)
Save callback for savegames in xml.
Defines some savefile structures.
bool BS_LoadXML(xmlNode_t *parent)
Load callback for savegames.
bool STATS_SaveXML(xmlNode_t *parent)
Save callback for savegames in XML Format.
XML tag constants for savegame.
const char *IMPORT * GetRelativeSavePath(char *buf, size_t bufSize)
bool HOS_LoadXML(xmlNode_t *p)
Saving function for hospital related data.
xmlNode_t *IMPORT * XML_Parse(const char *buffer)
bool CP_TriggerEventSaveXML(xmlNode_t *p)
bool TR_LoadXML(xmlNode_t *parent)
Load callback for xml savegames.
memPool_t * cp_campaignPool
bool TR_SaveXML(xmlNode_t *parent)
Save callback for xml savegames.
bool INT_LoadXML(xmlNode_t *parent)
Load callback for savegames in XML Format.
const char * Date_GetMonthName(int month)
Returns the short monthame to the given month index.
bool AB_LoadXML(xmlNode_t *p)
Load callback for alien base data.
bool CP_LoadXML(xmlNode_t *parent)
Load callback for savegames in XML Format.
bool STATS_LoadXML(xmlNode_t *parent)
Load callback for savegames in XML Format.
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
bool NAT_LoadXML(xmlNode_t *p)
Nation loading xml callback.
bool SAV_LoadHeader(const char *filename, saveFileHeader_t *header)
Loads and verifies a savegame header.
void CP_UpdateTime(void)
Updates date/time and timescale (=timelapse) on the geoscape menu.
bool SAV_AddSubsystem(saveSubsystems_t *subsystem)
Adds a subsystem to the saveSubsystems array.
bool US_SaveXML(xmlNode_t *parent)
Save callback for savegames in XML Format.
const cgame_import_t * cgi
bool MSO_SaveXML(xmlNode_t *p)
saves current notification and pause settings
bool HOS_SaveXML(xmlNode_t *p)
Saving function for hospital related data.
bool MS_SaveXML(xmlNode_t *p)
Save callback for messages.
Campaign geoscape time header.
bool INS_LoadXML(xmlNode_t *p)
Load callback for savegames.
cvar_t *IMPORT * Cvar_Get(const char *varName, const char *value, int flags, const char *desc)
bool XVI_LoadXML(xmlNode_t *parent)
Load the XVI map from the savegame.
bool MIS_SaveXML(xmlNode_t *parent)
Save callback for savegames in XML Format.
#define MAX_SAVESUBSYSTEMS
#define SAVE_FILE_VERSION
#define Mem_PoolAllocTypeN(type, n, pool)
void Com_MakeTimestamp(char *ts, const size_t tslen)
Creates a timestamp with date and time at the specified location.
Human readable time information in the game.
bool US_LoadXML(xmlNode_t *parent)
Load callback for xml savegames.
QGL_EXTERN GLuint GLchar GLuint * len
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
bool PR_LoadXML(xmlNode_t *p)
Load callback for xml savegames.
bool B_PostLoadInit(void)
Set the capacity stuff for all the bases after loading a savegame.
bool NAT_SaveXML(xmlNode_t *p)
Nation saving callback.
void CP_DateConvertLong(const date_t *date, dateLong_t *dateLong)
Converts a date from the engine in a (longer) human-readable format.
bool SAV_GameSave(const char *filename, const char *comment, char **error)
This is a savegame function which stores the game in xml-Format.
bool MSO_LoadXML(xmlNode_t *p)
Restores the notification and pause settings from savegame.
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
static int saveSubsystemsAmount
bool SAV_GameSaveAllowed(char **error=nullptr)
Determines if saving is allowed.
Header file for single player campaign control.
bool RS_SaveXML(xmlNode_t *parent)
Save callback for research and technologies.
bool INT_SaveXML(xmlNode_t *parent)
Save callback for savegames in XML Format.
xmlNode_t *IMPORT * XML_AddNode(xmlNode_t *parent, const char *name)
bool CP_SaveXML(xmlNode_t *parent)
Save callback for savegames in XML Format.
bool AIR_LoadXML(xmlNode_t *parent)
bool PR_SaveXML(xmlNode_t *p)
Save callback for savegames in XML Format.
bool CP_TriggerEventLoadXML(xmlNode_t *p)
void CP_UpdateXVIMapButton(void)
This will hide or show the geoscape button for handling the xvi overlay map.
bool PR_PostLoadInit(void)
actions to do with productions after loading a savegame
bool AIR_SaveXML(xmlNode_t *parent)
Save callback for savegames in xml format.
bool AB_SaveXML(xmlNode_t *p)
Save callback for alien base data.
xmlNode_t *IMPORT * XML_GetNode(xmlNode_t *parent, const char *name)
bool SAV_GameLoad(const char *file, const char **error)
Loads the given savegame from an xml File.
bool(* load)(xmlNode_t *parent)
bool MIS_LoadXML(xmlNode_t *parent)
Load callback for savegames in XML Format.
bool AC_LoadXML(xmlNode_t *parent)
Load callback for savin in XML Format.