mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-10 23:02:03 +00:00
Rewrite the savegame format in terms of the generic saving/loading system.
This makes savegames practically the same as the initial snapshot of a demo. Saves are now named 'dukesavX.esv' (demos: 'edemoX.edm'). Additionally, many changes that couldn't/needn't be cleanly separated are added with this commit: - make spriteext_t have the same size across 32/64 bit platforms (actor_t partially) - prevent saving/loading in MP games (it certainly didn't work and still doesn't) - it's time we start using assertions! Define NDEBUG for releasse builds. - reset savegame major and minor versions (we have a new magic string, so no conflict) git-svn-id: https://svn.eduke32.com/eduke32@2207 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
61257b0f6b
commit
b3474c75b2
10 changed files with 768 additions and 316 deletions
|
@ -84,6 +84,8 @@ ifneq (0,$(RELEASE))
|
|||
endif
|
||||
ifeq (0,$(DEBUGANYWAY))
|
||||
debug+= -fomit-frame-pointer
|
||||
else
|
||||
debug+= -DNDEBUG
|
||||
endif
|
||||
ifneq (0,$(LTO))
|
||||
LIBS+= -flto
|
||||
|
|
|
@ -240,10 +240,13 @@ typedef struct {
|
|||
uint8_t filler;
|
||||
float alpha;
|
||||
spritetype *tspr;
|
||||
#if defined LUNATIC_ENABLE && UINTPTR_MAX == 0xffffffff
|
||||
#if !defined UINTPTR_MAX
|
||||
# error Need UINTPTR_MAX define to select between 32- and 64-bit structs
|
||||
#endif
|
||||
#if UINTPTR_MAX == 0xffffffff
|
||||
/* On a 32-bit build, pad the struct so it has the same size everywhere.
|
||||
* REMINDER: Will break savegames. */
|
||||
void *dummy_;
|
||||
const intptr_t dummy_;
|
||||
#endif
|
||||
} spriteext_t;
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ typedef struct {
|
|||
int8_t filler[6]; // 6b
|
||||
} projectile_t;
|
||||
|
||||
// (+ 40 8 6 16 16 4 8 6 4 4 16)
|
||||
// (+ 40 8 6 16 16 4 8 6 4 20)
|
||||
typedef struct {
|
||||
#ifdef SAMESIZE_ACTOR_T
|
||||
int32_t t_data[10]; // 40b sometimes used to hold offsets to con code
|
||||
|
@ -108,12 +108,16 @@ typedef struct {
|
|||
void *lightptr;
|
||||
#endif
|
||||
|
||||
#if !defined SAMESIZE_ACTOR_T || UINTPTR_MAX == 0xffffffff
|
||||
/* 32-bit or old, same-declaration version */
|
||||
int8_t filler[24]; // pad struct to 128 bytes
|
||||
// pad struct to 128 bytes
|
||||
#if !defined UINTPTR_MAX
|
||||
# error Need UINTPTR_MAX define to select between 32- and 64-bit structs
|
||||
#endif
|
||||
#if UINTPTR_MAX == 0xffffffff
|
||||
/* 32-bit */
|
||||
const int8_t filler[20];
|
||||
#else
|
||||
/* 64-bit, will break older savegames */
|
||||
int8_t filler[16];
|
||||
/* 64-bit */
|
||||
const int8_t filler[12];
|
||||
#endif
|
||||
} actor_t;
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "menus.h"
|
||||
#include "savegame.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
char firstdemofile[BMAX_PATH];
|
||||
|
||||
FILE *g_demo_filePtr = (FILE *)NULL;
|
||||
|
@ -35,7 +37,7 @@ int32_t g_demo_soundToggle;
|
|||
int32_t g_demo_paused=0;
|
||||
int32_t g_demo_rewind=0;
|
||||
int32_t g_demo_showStats=1;
|
||||
int32_t g_demo_recFilePtr;
|
||||
int32_t g_demo_recFilePtr = -1;
|
||||
|
||||
static int32_t demo_hasdiffs, demorec_diffs=1, demorec_difftics = 2*(TICRATE/TICSPERFRAME);
|
||||
int32_t demoplay_diffs=1;
|
||||
|
@ -69,11 +71,13 @@ void demo_preparewarp(void)
|
|||
}
|
||||
|
||||
|
||||
int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine
|
||||
static int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine
|
||||
{
|
||||
char d[14];
|
||||
int32_t i;
|
||||
|
||||
savehead_t saveh;
|
||||
|
||||
Bstrcpy(d, "edemo_.edm");
|
||||
|
||||
if (g_whichDemo == 10)
|
||||
|
@ -87,9 +91,19 @@ int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine
|
|||
}
|
||||
else if ((g_demo_recFilePtr = kopen4loadfrommod(d,g_loadFromGroupOnly)) == -1) return(0);
|
||||
|
||||
i=sv_loadsnapshot(g_demo_recFilePtr, &demo_hasdiffs, &g_demo_totalCnt, &demo_synccompress);
|
||||
if (i==0)
|
||||
assert(g_whichDemo >= 1);
|
||||
i = sv_loadsnapshot(g_demo_recFilePtr, -g_whichDemo, &saveh);
|
||||
if (i)
|
||||
{
|
||||
OSD_Printf(OSD_ERROR "There were errors opening demo %d (code: %d).\n", g_whichDemo, i);
|
||||
kclose(g_demo_recFilePtr); g_demo_recFilePtr = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
demo_hasdiffs = saveh.recdiffsp;
|
||||
g_demo_totalCnt = saveh.reccnt;
|
||||
demo_synccompress = saveh.synccompress;
|
||||
|
||||
demo_hasseeds = demo_synccompress&2;
|
||||
demo_synccompress &= 1;
|
||||
|
||||
|
@ -108,20 +122,6 @@ int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine
|
|||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
OSD_Printf(OSD_ERROR "There were errors opening demo %d (code: %d).\n", g_whichDemo, i);
|
||||
kclose(g_demo_recFilePtr);
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
corrupt:
|
||||
OSD_Printf(OSD_ERROR "Demo %d header is corrupt.\n",g_whichDemo);
|
||||
ud.reccnt = 0;
|
||||
kclose(g_demo_recFilePtr);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if KRANDDEBUG
|
||||
extern void krd_enable(int32_t which);
|
||||
|
@ -133,7 +133,11 @@ void G_OpenDemoWrite(void)
|
|||
char d[14];
|
||||
int32_t i, demonum=1;
|
||||
|
||||
if (ud.recstat == 2) kclose(g_demo_recFilePtr);
|
||||
if (ud.recstat == 2)
|
||||
{
|
||||
kclose(g_demo_recFilePtr);
|
||||
g_demo_recFilePtr = -1;
|
||||
}
|
||||
|
||||
if ((g_player[myconnectindex].ps->gm&MODE_GAME) && g_player[myconnectindex].ps->dead_flag)
|
||||
{
|
||||
|
@ -178,7 +182,7 @@ void G_OpenDemoWrite(void)
|
|||
|
||||
if ((g_demo_filePtr = Bfopen(d,"wb")) == NULL) return;
|
||||
|
||||
i=sv_saveandmakesnapshot(g_demo_filePtr, demorec_diffs_cvar, demorec_diffcompress_cvar,
|
||||
i=sv_saveandmakesnapshot(g_demo_filePtr, -1, demorec_diffs_cvar, demorec_diffcompress_cvar,
|
||||
demorec_synccompress_cvar|(demorec_seeds_cvar<<1));
|
||||
if (i)
|
||||
{
|
||||
|
@ -260,8 +264,9 @@ void G_CloseDemoWrite(void)
|
|||
|
||||
fwrite("EnD!", 4, 1, g_demo_filePtr);
|
||||
|
||||
if (fseek(g_demo_filePtr, 20, SEEK_SET))
|
||||
perror("G_CloseDemoWrite: fseek");
|
||||
// lastly, we need to write the number of written recsyncs to the demo file
|
||||
if (fseek(g_demo_filePtr, offsetof(savehead_t, reccnt), SEEK_SET))
|
||||
perror("G_CloseDemoWrite: final fseek");
|
||||
else
|
||||
fwrite(&g_demo_cnt, sizeof(g_demo_cnt), 1, g_demo_filePtr);
|
||||
|
||||
|
@ -411,7 +416,6 @@ RECHECK:
|
|||
}
|
||||
else
|
||||
{
|
||||
// j = sv_loadsnapshot(g_demo_recFilePtr, &g_demo_totalCnt);
|
||||
j = doupdatestate(1);
|
||||
if (!j)
|
||||
{
|
||||
|
@ -486,7 +490,7 @@ corrupt:
|
|||
nextdemo:
|
||||
foundemo = 0;
|
||||
ud.reccnt = 0;
|
||||
kclose(g_demo_recFilePtr);
|
||||
kclose(g_demo_recFilePtr); g_demo_recFilePtr = -1;
|
||||
g_player[myconnectindex].ps->gm |= MODE_MENU;
|
||||
if (g_demo_goalCnt>0)
|
||||
{
|
||||
|
@ -502,7 +506,7 @@ nextdemo:
|
|||
|
||||
TRAVERSE_CONNECT(j)
|
||||
{
|
||||
copybufbyte(&recsync[bigi], &inputfifo[0][j], sizeof(input_t));
|
||||
Bmemcpy(&inputfifo[0][j], &recsync[bigi], sizeof(input_t));
|
||||
bigi++;
|
||||
ud.reccnt--;
|
||||
}
|
||||
|
@ -663,13 +667,13 @@ nextdemo:
|
|||
#if KRANDDEBUG
|
||||
krd_print("krandplay.log");
|
||||
#endif
|
||||
kclose(g_demo_recFilePtr);
|
||||
kclose(g_demo_recFilePtr); g_demo_recFilePtr = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ud.multimode = numplayers; // fixes 2 infinite loops after watching demo
|
||||
kclose(g_demo_recFilePtr);
|
||||
kclose(g_demo_recFilePtr); g_demo_recFilePtr = -1;
|
||||
|
||||
#if 0
|
||||
{
|
||||
|
|
|
@ -43,7 +43,6 @@ extern int32_t g_demo_showStats;
|
|||
extern int32_t g_demo_soundToggle;
|
||||
extern int32_t g_demo_totalCnt;
|
||||
|
||||
int32_t G_OpenDemoRead(int32_t g_whichDemo);
|
||||
int32_t G_PlaybackDemo(void);
|
||||
void demo_preparewarp(void);
|
||||
void G_CloseDemoWrite(void);
|
||||
|
|
|
@ -7784,9 +7784,16 @@ FAKE_F3:
|
|||
/* inputloc = Bstrlen(&ud.savegame[g_lastSaveSlot][0]);
|
||||
g_currentMenu = 360+g_lastSaveSlot;
|
||||
probey = g_lastSaveSlot; */
|
||||
if ((g_netServer || ud.multimode > 1))
|
||||
G_SavePlayer(-1-(g_lastSaveSlot));
|
||||
else G_SavePlayer(g_lastSaveSlot);
|
||||
if (g_netServer || ud.multimode > 1)
|
||||
{
|
||||
Bstrcpy(ScriptQuotes[QUOTE_RESERVED4], "MULTIPLAYER SAVING NOT SUPPORTED YET");
|
||||
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
|
||||
//G_SavePlayer(-1-(g_lastSaveSlot));
|
||||
}
|
||||
else
|
||||
{
|
||||
G_SavePlayer(g_lastSaveSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7844,10 +7851,13 @@ FAKE_F3:
|
|||
KB_ClearKeysDown();
|
||||
FX_StopAllSounds();
|
||||
|
||||
if ((g_netServer || ud.multimode > 1))
|
||||
if (g_netServer || ud.multimode > 1)
|
||||
{
|
||||
G_LoadPlayer(-1-g_lastSaveSlot);
|
||||
g_player[myconnectindex].ps->gm = MODE_GAME;
|
||||
Bstrcpy(ScriptQuotes[QUOTE_RESERVED4], "MULTIPLAYER LOADING NOT SUPPORTED YET");
|
||||
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
|
||||
|
||||
// G_LoadPlayer(-1-g_lastSaveSlot);
|
||||
// g_player[myconnectindex].ps->gm = MODE_GAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -34,7 +34,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include <sys/stat.h>
|
||||
|
||||
extern char inputloc;
|
||||
extern int32_t g_demo_recFilePtr;
|
||||
int16_t g_skillSoundID=-1;
|
||||
int32_t probey=0;
|
||||
static int32_t lastsavehead=0,last_menu_pos=0,last_menu,sh,onbar,buttonstat;
|
||||
|
@ -472,10 +471,11 @@ static void modval(int32_t min, int32_t max,int32_t *p,int32_t dainc,int32_t dam
|
|||
#define MWIN(X) rotatesprite( 320<<15,200<<15,X,0,MENUSCREEN,-16,0,10+64,0,0,xdim-1,ydim-1)
|
||||
#define MWINXY(X,OX,OY) rotatesprite( ( 320+(OX) )<<15, ( 200+(OY) )<<15,X,0,MENUSCREEN,-16,0,10+64,0,0,xdim-1,ydim-1)
|
||||
|
||||
extern int32_t G_LoadSaveHeader(char spot,struct savehead_ *saveh);
|
||||
//extern int32_t G_LoadSaveHeader(char spot,struct savehead_ *saveh);
|
||||
|
||||
#pragma pack(push,1)
|
||||
static struct savehead_ savehead;
|
||||
static savehead_t savehead;
|
||||
//static struct savehead_ savehead;
|
||||
#pragma pack(pop)
|
||||
|
||||
//static int32_t volnum,levnum,plrskl,numplr;
|
||||
|
@ -559,7 +559,7 @@ void G_CheckPlayerColor(int32_t *color, int32_t prev_color)
|
|||
static void Menus_LoadSave_DisplayCommon1(void)
|
||||
{
|
||||
if (lastsavehead != probey)
|
||||
G_LoadSaveHeader(probey,&savehead);
|
||||
G_LoadSaveHeaderNew(probey, &savehead);
|
||||
lastsavehead = probey;
|
||||
|
||||
rotatesprite(101<<16,97<<16,65536L>>1,512,TILE_LOADSHOT,-32,0,4+10+64,0,0,xdim-1,ydim-1);
|
||||
|
@ -567,9 +567,9 @@ static void Menus_LoadSave_DisplayCommon1(void)
|
|||
if (ud.savegame[probey][20] == 32)
|
||||
{
|
||||
menutext(40,70,0,0,"OLD VERSION");
|
||||
Bsprintf(tempbuf,"SAVED: %d", savehead.byteversion);
|
||||
Bsprintf(tempbuf,"SAVED: %d.%d.%d", savehead.majorver, savehead.minorver, savehead.bytever);
|
||||
mgametext(40,82,tempbuf,0,2+8+16);
|
||||
Bsprintf(tempbuf,"OUR: %d", BYTEVERSION);
|
||||
Bsprintf(tempbuf,"OUR: %d.%d.%d", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION);
|
||||
mgametext(40+16,92,tempbuf,0,2+8+16);
|
||||
}
|
||||
}
|
||||
|
@ -1342,10 +1342,13 @@ void M_DisplayMenus(void)
|
|||
KB_ClearKeysDown();
|
||||
FX_StopAllSounds();
|
||||
|
||||
if ((g_netServer || ud.multimode > 1))
|
||||
if (g_netServer || ud.multimode > 1)
|
||||
{
|
||||
G_LoadPlayer(-1-g_lastSaveSlot);
|
||||
g_player[myconnectindex].ps->gm = MODE_GAME;
|
||||
Bstrcpy(ScriptQuotes[QUOTE_RESERVED4], "MULTIPLAYER LOADING NOT SUPPORTED YET");
|
||||
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
|
||||
|
||||
// G_LoadPlayer(-1-g_lastSaveSlot);
|
||||
// g_player[myconnectindex].ps->gm = MODE_GAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1477,10 +1480,11 @@ void M_DisplayMenus(void)
|
|||
|
||||
M_DisplaySaveGameList();
|
||||
|
||||
Bsprintf(tempbuf,"PLAYERS: %-2d ",savehead.numplr);
|
||||
Bsprintf(tempbuf,"PLAYERS: %-2d ",savehead.numplayers);
|
||||
mgametext(160,156,tempbuf,0,2+8+16);
|
||||
|
||||
Bsprintf(tempbuf,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",1+savehead.volnum,1+savehead.levnum,savehead.plrskl);
|
||||
Bsprintf(tempbuf,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",
|
||||
1+savehead.volnum, 1+savehead.levnum, savehead.skill);
|
||||
mgametext(160,168,tempbuf,0,2+8+16);
|
||||
|
||||
if (savehead.volnum == 0 && savehead.levnum == 7)
|
||||
|
@ -4740,9 +4744,16 @@ cheat_for_port_credits:
|
|||
ud.savegame[g_currentMenu-360][20] = 127;
|
||||
}
|
||||
|
||||
if ((g_netServer || ud.multimode > 1))
|
||||
G_SavePlayer(-1-(g_currentMenu-360));
|
||||
else G_SavePlayer(g_currentMenu-360);
|
||||
if (g_netServer || ud.multimode > 1)
|
||||
{
|
||||
Bstrcpy(ScriptQuotes[QUOTE_RESERVED4], "MULTIPLAYER SAVING NOT SUPPORTED YET");
|
||||
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
|
||||
//G_SavePlayer(-1-(g_currentMenu-360));
|
||||
}
|
||||
else
|
||||
{
|
||||
G_SavePlayer(g_currentMenu-360);
|
||||
}
|
||||
g_lastSaveSlot = g_currentMenu-360;
|
||||
g_player[myconnectindex].ps->gm = MODE_GAME;
|
||||
|
||||
|
@ -4773,9 +4784,10 @@ cheat_for_port_credits:
|
|||
{
|
||||
Menus_LoadSave_DisplayCommon1();
|
||||
|
||||
Bsprintf(tempbuf,"PLAYERS: %-2d ",savehead.numplr);
|
||||
Bsprintf(tempbuf,"PLAYERS: %-2d ", savehead.numplayers);
|
||||
mgametext(160,156,tempbuf,0,2+8+16);
|
||||
Bsprintf(tempbuf,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",1+savehead.volnum,1+savehead.levnum,savehead.plrskl);
|
||||
Bsprintf(tempbuf,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",
|
||||
1+savehead.volnum, 1+savehead.levnum, savehead.skill);
|
||||
mgametext(160,168,tempbuf,0,2+8+16);
|
||||
if (savehead.volnum == 0 && savehead.levnum == 7)
|
||||
mgametext(160,180,savehead.boardfn,0,2+8+16);
|
||||
|
|
|
@ -27,14 +27,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
extern char inputloc;
|
||||
extern int16_t g_skillSoundID;
|
||||
extern int32_t g_demo_recFilePtr;
|
||||
extern int32_t g_lastSaveSlot;
|
||||
extern int32_t g_quitDeadline;
|
||||
extern int32_t probey;
|
||||
extern int32_t voting;
|
||||
int32_t G_LoadSaveHeader(char spot,struct savehead_ *saveh);
|
||||
int32_t menutext_(int32_t x,int32_t y,int32_t s,int32_t p,char *t,int32_t bits);
|
||||
void ChangeToMenu(int32_t cm);
|
||||
void G_CheckPlayerColor(int32_t *color,int32_t prev_color);
|
||||
void M_DisplayMenus(void);
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -23,7 +23,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#ifndef __savegame_h__
|
||||
#define __savegame_h__
|
||||
|
||||
#define SV_MAJOR_VER 1
|
||||
#define SV_MINOR_VER 1
|
||||
|
||||
#pragma pack(push,1)
|
||||
# if 0
|
||||
struct savehead_
|
||||
{
|
||||
char name[21];
|
||||
|
@ -31,17 +35,41 @@ struct savehead_
|
|||
int32_t numplr,volnum,levnum,plrskl;
|
||||
char boardfn[BMAX_PATH];
|
||||
};
|
||||
# endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char headerstr[11];
|
||||
uint8_t majorver, minorver, ptrsize;
|
||||
uint16_t bytever;
|
||||
// 16 bytes
|
||||
|
||||
uint8_t comprthres;
|
||||
uint8_t recdiffsp, diffcompress, synccompress;
|
||||
// 4 bytes
|
||||
|
||||
int32_t reccnt, snapsiz;
|
||||
// 8 bytes
|
||||
|
||||
char savename[22]; // should be of the same length as ud.savegame[i]
|
||||
uint8_t numplayers, volnum, levnum, skill;
|
||||
char boardfn[256]; // BMAX_PATH
|
||||
// 282 bytes
|
||||
} savehead_t; // 310 bytes
|
||||
#pragma pack(pop)
|
||||
|
||||
int32_t sv_updatestate(int32_t frominit);
|
||||
int32_t sv_readdiff(int32_t fil);
|
||||
uint32_t sv_writediff(FILE *fil);
|
||||
int32_t sv_loadsnapshot(int32_t fil,int32_t *ret_hasdiffs,int32_t *ret_demoticcnt,int32_t *ret_synccompress);
|
||||
int32_t sv_saveandmakesnapshot(FILE *fil,int32_t recdiffs,int32_t diffcompress,int32_t synccompress);
|
||||
int32_t sv_loadheader(int32_t fil, int32_t spot, savehead_t *h);
|
||||
int32_t sv_loadsnapshot(int32_t fil, int32_t spot, savehead_t *h);
|
||||
int32_t sv_saveandmakesnapshot(FILE *fil, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress);
|
||||
void sv_freemem();
|
||||
int32_t G_SavePlayer(int32_t spot);
|
||||
int32_t G_LoadPlayer(int32_t spot);
|
||||
int32_t G_LoadSaveHeader(char spot,struct savehead_ *saveh);
|
||||
int32_t G_LoadSaveHeaderNew(int32_t spot, savehead_t *saveh);
|
||||
//int32_t G_LoadSaveHeader(char spot,struct savehead_ *saveh);
|
||||
void ReadSaveGameHeaders(void);
|
||||
extern char *bitptr;
|
||||
|
||||
|
|
Loading…
Reference in a new issue