mirror of
https://github.com/yquake2/zaero.git
synced 2024-11-10 06:32:04 +00:00
Merge outstanding savegame changes from yquake.
- Switch from an whitelist base approach regarding platforms and systems to an blacklist approach. This is savegame version 2. - Fix coop_respan struct not fully initialized after savegame load while running in coop mode. This is savegame version 3. Support for savegame version 2 was added to keep the divergence between zaero and the other addons low.
This commit is contained in:
parent
4e031fe308
commit
4bdd8facd5
5 changed files with 135 additions and 52 deletions
24
Makefile
24
Makefile
|
@ -28,19 +28,16 @@ endif
|
|||
|
||||
# Detect the architecture
|
||||
ifeq ($(OSTYPE), Windows)
|
||||
# At this time only i386 is supported on Windows
|
||||
ARCH := i386
|
||||
# seems like mingw doesn't set CC by default
|
||||
CC := gcc
|
||||
ifdef PROCESSOR_ARCHITEW6432
|
||||
# 64 bit Windows
|
||||
ARCH := $(PROCESSOR_ARCHITEW6432)
|
||||
else
|
||||
# Some platforms call it "amd64" and some "x86_64"
|
||||
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/amd64/x86_64/)
|
||||
# 32 bit Windows
|
||||
ARCH := $(PROCESSOR_ARCHITECTURE)
|
||||
endif
|
||||
|
||||
# Refuse all other platforms as a firewall against PEBKAC
|
||||
# (You'll need some #ifdef for your unsupported plattform!)
|
||||
ifeq ($(findstring $(ARCH), i386 x86_64 sparc64 ia64),)
|
||||
$(error arch $(ARCH) is currently not supported)
|
||||
else
|
||||
# Normalize some abiguous ARCH strings
|
||||
ARCH := $(shell uname -m | sed -e 's/i.86/i386/' -e 's/amd64/x86_64/' -e 's/^arm.*/arm/')
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
@ -73,6 +70,11 @@ endif
|
|||
|
||||
# ----------
|
||||
|
||||
# Defines the operating system and architecture
|
||||
CFLAGS += -DOSTYPE=\"$(OSTYPE)\" -DARCH=\"$(ARCH)\"
|
||||
|
||||
# ----------
|
||||
|
||||
# Base LDFLAGS.
|
||||
ifeq ($(OSTYPE), Darwin)
|
||||
LDFLAGS := -shared -arch i386 -arch x86_64
|
||||
|
|
|
@ -641,6 +641,7 @@ typedef struct
|
|||
int ofs;
|
||||
fieldtype_t type;
|
||||
int flags;
|
||||
short save_ver;
|
||||
} field_t;
|
||||
|
||||
|
||||
|
|
|
@ -54,40 +54,49 @@
|
|||
* in tables/ are changed, otherwise
|
||||
* strange things may happen.
|
||||
*/
|
||||
#define SAVEGAMEVER "YQ2-2"
|
||||
#define SAVEGAMEVER "YQ2-3"
|
||||
|
||||
/*
|
||||
* This macros are used to
|
||||
* prohibit loading of savegames
|
||||
* created on other systems or
|
||||
* architectures. This will
|
||||
* crash q2 in spectecular
|
||||
* ways
|
||||
* This macros are used to prohibit loading of savegames
|
||||
* created on other systems or architectures. This will
|
||||
* crash q2 in spectacular ways
|
||||
*/
|
||||
#if defined(__FreeBSD__)
|
||||
#define OS "FreeBSD"
|
||||
#elif defined(__APPLE__)
|
||||
#define OS "MacOS X"
|
||||
#ifndef OSTYPE
|
||||
#error OSTYPE should be defined by the build system
|
||||
#endif
|
||||
|
||||
#ifndef ARCH
|
||||
#error ARCH should be defined by the build system
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Older operating system and architecture detection
|
||||
* macros, implemented by savegame version YQ2-1.
|
||||
*/
|
||||
#if defined(__APPLE__)
|
||||
#define OSTYPE_1 "MacOS X"
|
||||
#elif defined(__FreeBSD__)
|
||||
#define OSTYPE_1 "FreeBSD"
|
||||
#elif defined(__OpenBSD__)
|
||||
#define OS "OpenBSD"
|
||||
#define OSTYPE_1 "OpenBSD"
|
||||
#elif defined(__linux__)
|
||||
#define OS "Linux"
|
||||
#define OSTYPE_1 "Linux"
|
||||
#elif defined(_WIN32)
|
||||
#define OS "Windows"
|
||||
#define OSTYPE_1 "Windows"
|
||||
#else
|
||||
#define OS "Unknown"
|
||||
#define OSTYPE_1 "Unknown"
|
||||
#endif
|
||||
|
||||
#if defined(__i386__)
|
||||
#define ARCH "i386"
|
||||
#define ARCH_1 "i386"
|
||||
#elif defined(__x86_64__)
|
||||
#define ARCH "amd64"
|
||||
#define ARCH_1 "amd64"
|
||||
#elif defined(__sparc__)
|
||||
#define ARCH "sparc64"
|
||||
#define ARCH_1 "sparc64"
|
||||
#elif defined(__ia64__)
|
||||
#define ARCH "ia64"
|
||||
#define ARCH_1 "ia64"
|
||||
#else
|
||||
#define ARCH "unknown"
|
||||
#define ARCH_1 "unknown"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -692,7 +701,7 @@ WriteClient(FILE *f, gclient_t *client)
|
|||
* Read the client struct from a file
|
||||
*/
|
||||
void
|
||||
ReadClient(FILE *f, gclient_t *client)
|
||||
ReadClient(FILE *f, gclient_t *client, short save_ver)
|
||||
{
|
||||
field_t *field;
|
||||
|
||||
|
@ -701,6 +710,16 @@ ReadClient(FILE *f, gclient_t *client)
|
|||
for (field = clientfields; field->name; field++)
|
||||
{
|
||||
ReadField(f, field, (byte *)client);
|
||||
|
||||
if (field->save_ver <= save_ver)
|
||||
{
|
||||
ReadField(f, field, (byte *)client);
|
||||
}
|
||||
}
|
||||
|
||||
if (save_ver < 3)
|
||||
{
|
||||
InitClientResp(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -746,7 +765,7 @@ WriteGame(const char *filename, qboolean autosave)
|
|||
|
||||
strncpy(str_ver, SAVEGAMEVER, sizeof(str_ver));
|
||||
strncpy(str_game, GAMEVERSION, sizeof(str_game));
|
||||
strncpy(str_os, OS, sizeof(str_os));
|
||||
strncpy(str_os, OSTYPE, sizeof(str_os) - 1);
|
||||
strncpy(str_arch, ARCH, sizeof(str_arch));
|
||||
|
||||
fwrite(str_ver, sizeof(str_ver), 1, f);
|
||||
|
@ -780,6 +799,7 @@ ReadGame(const char *filename)
|
|||
char str_game[32];
|
||||
char str_os[32];
|
||||
char str_arch[32];
|
||||
short save_ver = 0;
|
||||
|
||||
gi.FreeTags(TAG_GAME);
|
||||
|
||||
|
@ -796,27 +816,84 @@ ReadGame(const char *filename)
|
|||
fread(str_os, sizeof(str_os), 1, f);
|
||||
fread(str_arch, sizeof(str_arch), 1, f);
|
||||
|
||||
if (strcmp(str_ver, SAVEGAMEVER))
|
||||
if (!strcmp(str_ver, SAVEGAMEVER))
|
||||
{
|
||||
save_ver = 3;
|
||||
|
||||
if (strcmp(str_game, GAMEVERSION))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other game.so.\n");
|
||||
}
|
||||
else if (strcmp(str_os, OSTYPE))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other os.\n");
|
||||
}
|
||||
else if (strcmp(str_arch, ARCH))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other architecure.\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(str_ver, "YQ2-2"))
|
||||
{
|
||||
save_ver = 2;
|
||||
|
||||
if (strcmp(str_game, GAMEVERSION))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other game.so.\n");
|
||||
}
|
||||
else if (strcmp(str_os, OSTYPE))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other os.\n");
|
||||
}
|
||||
else if (strcmp(str_arch, ARCH))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other architecure.\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(str_ver, "YQ2-1"))
|
||||
{
|
||||
save_ver = 1;
|
||||
|
||||
if (strcmp(str_game, GAMEVERSION))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other game.so.\n");
|
||||
}
|
||||
else if (strcmp(str_os, OSTYPE_1))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other os.\n");
|
||||
}
|
||||
|
||||
if (!strcmp(str_os, "Windows"))
|
||||
{
|
||||
/* Windows was forced to i386 */
|
||||
if (strcmp(str_arch, "i386"))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other architecure.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(str_arch, ARCH_1))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other architecure.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an incompatible version.\n");
|
||||
}
|
||||
else if (strcmp(str_game, GAMEVERSION))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other game.so.\n");
|
||||
}
|
||||
else if (strcmp(str_os, OS))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other os.\n");
|
||||
}
|
||||
|
||||
else if (strcmp(str_arch, ARCH))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from an other architecure.\n");
|
||||
}
|
||||
|
||||
g_edicts = gi.TagMalloc(game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
|
||||
globals.edicts = g_edicts;
|
||||
|
@ -827,7 +904,7 @@ ReadGame(const char *filename)
|
|||
|
||||
for (i = 0; i < game.maxclients; i++)
|
||||
{
|
||||
ReadClient(f, &game.clients[i]);
|
||||
ReadClient(f, &game.clients[i], save_ver);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
|
|
@ -12,4 +12,7 @@
|
|||
{"newweapon", CLOFS(newweapon), F_ITEM},
|
||||
{"", CLOFS(zCameraTrack), F_EDICT},
|
||||
{"", CLOFS(zCameraLocalEntity), F_EDICT},
|
||||
{"resp.coop_respawn.weapon", CLOFS(resp.coop_respawn.weapon), F_ITEM, 0, 3},
|
||||
{"resp.coop_respawn.lastweapon", CLOFS(resp.coop_respawn.lastweapon), F_ITEM, 0, 3},
|
||||
{"resp.coop_respawn.lastweapon2", CLOFS(resp.coop_respawn.lastweapon2), F_ITEM, 0, 3},
|
||||
{NULL, 0, F_INT}
|
||||
|
|
|
@ -14,7 +14,7 @@ extern void WriteLevelLocals ( FILE * f ) ;
|
|||
extern void WriteEdict ( FILE * f , edict_t * ent ) ;
|
||||
extern void ReadGame ( const char * filename ) ;
|
||||
extern void WriteGame ( const char * filename , qboolean autosave ) ;
|
||||
extern void ReadClient ( FILE * f , gclient_t * client ) ;
|
||||
extern void ReadClient ( FILE * f , gclient_t * client , short save_ver ) ;
|
||||
extern void WriteClient ( FILE * f , gclient_t * client ) ;
|
||||
extern void ReadField ( FILE * f , field_t * field , byte * base ) ;
|
||||
extern void WriteField2 ( FILE * f , field_t * field , byte * base ) ;
|
||||
|
|
Loading…
Reference in a new issue