ref: 551df9d933a3f8d4c7dd633f62671433dc70cc1d
parent: 0ac394902ef009fe0b41f77095b069d4f6d7e632
author: Simon Howard <[email protected]>
date: Tue Sep 24 16:52:59 EDT 2013
Add portable functions to read integers from savegame files and use these instead of reading directly from memory buffers. Subversion-branch: /branches/v2-branch Subversion-revision: 2682
--- a/src/heretic/doomdef.h
+++ b/src/heretic/doomdef.h
@@ -553,8 +553,6 @@
#define SAVEGAMESIZE 0x30000
#define SAVESTRINGSIZE 24
-extern byte *savebuffer;
-extern byte *save_p;
extern mapthing_t *deathmatch_p;
extern mapthing_t deathmatchstarts[10];
@@ -668,11 +666,16 @@
// Support routines for saving games
char *SV_Filename(int slot);
void SV_Open(char *fileName);
+void SV_OpenRead(char *fileName);
void SV_Close(char *fileName);
void SV_Write(void *buffer, int size);
void SV_WriteByte(byte val);
void SV_WriteWord(unsigned short val);
void SV_WriteLong(unsigned int val);
+void SV_Read(void *buffer, int size);
+byte SV_ReadByte(void);
+uint16_t SV_ReadWord(void);
+uint32_t SV_ReadLong(void);
extern char *savegamedir;
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -126,9 +126,7 @@
// TODO: Heretic uses 16-bit shorts for consistency?
byte consistancy[MAXPLAYERS][BACKUPTICS];
-
char *savegamedir;
-byte *savebuffer, *save_p;
boolean testcontrols = false;
int testcontrols_mousespeed;
@@ -1413,39 +1411,41 @@
{
int i;
int a, b, c;
- char vcheck[VERSIONSIZE];
+ char savestr[SAVESTRINGSIZE];
+ char vcheck[VERSIONSIZE], readversion[VERSIONSIZE];
gameaction = ga_nothing;
- M_ReadFile(savename, &savebuffer);
+ SV_OpenRead(savename);
+
free(savename);
savename = NULL;
- save_p = savebuffer + SAVESTRINGSIZE;
// Skip the description field
- memset(vcheck, 0, sizeof(vcheck));
+ SV_Read(savestr, SAVESTRINGSIZE);
+ memset(vcheck, 0, sizeof(vcheck));
DEH_snprintf(vcheck, VERSIONSIZE, "version %i", HERETIC_VERSION);
+ SV_Read(readversion, VERSIONSIZE);
- if (strcmp((char *) save_p, vcheck) != 0)
+ if (strncmp(readversion, vcheck, VERSIONSIZE) != 0)
{ // Bad version
return;
}
- save_p += VERSIONSIZE;
- gameskill = *save_p++;
- gameepisode = *save_p++;
- gamemap = *save_p++;
+ gameskill = SV_ReadByte();
+ gameepisode = SV_ReadByte();
+ gamemap = SV_ReadByte();
for (i = 0; i < MAXPLAYERS; i++)
{
- playeringame[i] = *save_p++;
+ playeringame[i] = SV_ReadByte();
}
// Load a base level
G_InitNew(gameskill, gameepisode, gamemap);
// Create leveltime
- a = *save_p++;
- b = *save_p++;
- c = *save_p++;
+ a = SV_ReadByte();
+ b = SV_ReadByte();
+ c = SV_ReadByte();
leveltime = (a << 16) + (b << 8) + c;
// De-archive all the modifications
@@ -1454,11 +1454,10 @@
P_UnArchiveThinkers();
P_UnArchiveSpecials();
- if (*save_p != SAVE_GAME_TERMINATOR)
+ if (SV_ReadByte() != SAVE_GAME_TERMINATOR)
{ // Missing savegame termination marker
I_Error("Bad savegame");
}
- Z_Free(savebuffer);
}
--- a/src/heretic/p_saveg.c
+++ b/src/heretic/p_saveg.c
@@ -25,6 +25,7 @@
// P_tick.c
#include "doomdef.h"
+#include "i_swap.h"
#include "i_system.h"
#include "m_misc.h"
#include "p_local.h"
@@ -33,9 +34,11 @@
#define SVG_RAM 0
#define SVG_FILE 1
-FILE *SaveGameFP;
-int SaveGameType;
+static FILE *SaveGameFP;
+static int SaveGameType;
+static byte *savebuffer, *save_p;
+
//==========================================================================
//
// SV_Filename
@@ -67,6 +70,12 @@
SaveGameFP = fopen(fileName, "wb");
}
+void SV_OpenRead(char *filename)
+{
+ SaveGameType = SVG_FILE;
+ SaveGameFP = fopen(filename, "rb");
+}
+
//==========================================================================
//
// SV_Close
@@ -120,14 +129,57 @@
void SV_WriteWord(unsigned short val)
{
+ val = SHORT(val);
SV_Write(&val, sizeof(unsigned short));
}
void SV_WriteLong(unsigned int val)
{
+ val = LONG(val);
SV_Write(&val, sizeof(int));
}
+//==========================================================================
+//
+// SV_Write
+//
+//==========================================================================
+
+void SV_Read(void *buffer, int size)
+{
+ if (SaveGameType == SVG_RAM)
+ {
+ memcpy(buffer, save_p, size);
+ save_p += size;
+ }
+ else
+ { // SVG_FILE
+ fread(buffer, size, 1, SaveGameFP);
+ }
+}
+
+byte SV_ReadByte(void)
+{
+ byte result;
+ SV_Read(&result, sizeof(byte));
+ return result;
+}
+
+uint16_t SV_ReadWord(void)
+{
+ uint16_t result;
+ SV_Read(&result, sizeof(unsigned short));
+ return SHORT(result);
+}
+
+uint32_t SV_ReadLong(void)
+{
+ uint32_t result;
+ SV_Read(&result, sizeof(int));
+ return LONG(result);
+}
+
+
/*
====================
=
@@ -177,8 +229,7 @@
{
if (!playeringame[i])
continue;
- memcpy(&players[i], save_p, sizeof(player_t));
- save_p += sizeof(player_t);
+ SV_Read(&players[i], sizeof(player_t));
players[i].mo = NULL; // will be set when unarc thinker
players[i].message = NULL;
players[i].attacker = NULL;
@@ -255,22 +306,19 @@
sector_t *sec;
line_t *li;
side_t *si;
- short *get;
- get = (short *) save_p;
-
//
// do sectors
//
for (i = 0, sec = sectors; i < numsectors; i++, sec++)
{
- sec->floorheight = *get++ << FRACBITS;
- sec->ceilingheight = *get++ << FRACBITS;
- sec->floorpic = *get++;
- sec->ceilingpic = *get++;
- sec->lightlevel = *get++;
- sec->special = *get++; // needed?
- sec->tag = *get++; // needed?
+ sec->floorheight = SV_ReadWord() << FRACBITS;
+ sec->ceilingheight = SV_ReadWord() << FRACBITS;
+ sec->floorpic = SV_ReadWord();
+ sec->ceilingpic = SV_ReadWord();
+ sec->lightlevel = SV_ReadWord();
+ sec->special = SV_ReadWord(); // needed?
+ sec->tag = SV_ReadWord(); // needed?
sec->specialdata = 0;
sec->soundtarget = 0;
}
@@ -280,23 +328,21 @@
//
for (i = 0, li = lines; i < numlines; i++, li++)
{
- li->flags = *get++;
- li->special = *get++;
- li->tag = *get++;
+ li->flags = SV_ReadWord();
+ li->special = SV_ReadWord();
+ li->tag = SV_ReadWord();
for (j = 0; j < 2; j++)
{
if (li->sidenum[j] == -1)
continue;
si = &sides[li->sidenum[j]];
- si->textureoffset = *get++ << FRACBITS;
- si->rowoffset = *get++ << FRACBITS;
- si->toptexture = *get++;
- si->bottomtexture = *get++;
- si->midtexture = *get++;
+ si->textureoffset = SV_ReadWord() << FRACBITS;
+ si->rowoffset = SV_ReadWord() << FRACBITS;
+ si->toptexture = SV_ReadWord();
+ si->bottomtexture = SV_ReadWord();
+ si->midtexture = SV_ReadWord();
}
}
-
- save_p = (byte *) get;
}
//=============================================================================
@@ -373,7 +419,7 @@
// read in saved thinkers
while (1)
{
- tclass = *save_p++;
+ tclass = SV_ReadByte();
switch (tclass)
{
case tc_end:
@@ -381,8 +427,7 @@
case tc_mobj:
mobj = Z_Malloc(sizeof(*mobj), PU_LEVEL, NULL);
- memcpy(mobj, save_p, sizeof(*mobj));
- save_p += sizeof(*mobj);
+ SV_Read(mobj, sizeof(*mobj));
mobj->state = &states[(int) mobj->state];
mobj->target = NULL;
if (mobj->player)
@@ -535,7 +580,7 @@
// read in saved thinkers
while (1)
{
- tclass = *save_p++;
+ tclass = SV_ReadByte();
switch (tclass)
{
case tc_endspecials:
@@ -543,8 +588,7 @@
case tc_ceiling:
ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVEL, NULL);
- memcpy(ceiling, save_p, sizeof(*ceiling));
- save_p += sizeof(*ceiling);
+ SV_Read(ceiling, sizeof(*ceiling));
ceiling->sector = §ors[(int) ceiling->sector];
ceiling->sector->specialdata = T_MoveCeiling;
if (ceiling->thinker.function)
@@ -555,8 +599,7 @@
case tc_door:
door = Z_Malloc(sizeof(*door), PU_LEVEL, NULL);
- memcpy(door, save_p, sizeof(*door));
- save_p += sizeof(*door);
+ SV_Read(door, sizeof(*door));
door->sector = §ors[(int) door->sector];
door->sector->specialdata = door;
door->thinker.function = T_VerticalDoor;
@@ -565,8 +608,7 @@
case tc_floor:
floor = Z_Malloc(sizeof(*floor), PU_LEVEL, NULL);
- memcpy(floor, save_p, sizeof(*floor));
- save_p += sizeof(*floor);
+ SV_Read(floor, sizeof(*floor));
floor->sector = §ors[(int) floor->sector];
floor->sector->specialdata = T_MoveFloor;
floor->thinker.function = T_MoveFloor;
@@ -575,8 +617,7 @@
case tc_plat:
plat = Z_Malloc(sizeof(*plat), PU_LEVEL, NULL);
- memcpy(plat, save_p, sizeof(*plat));
- save_p += sizeof(*plat);
+ SV_Read(plat, sizeof(*plat));
plat->sector = §ors[(int) plat->sector];
plat->sector->specialdata = T_PlatRaise;
if (plat->thinker.function)
@@ -587,8 +628,7 @@
case tc_flash:
flash = Z_Malloc(sizeof(*flash), PU_LEVEL, NULL);
- memcpy(flash, save_p, sizeof(*flash));
- save_p += sizeof(*flash);
+ SV_Read(flash, sizeof(*flash));
flash->sector = §ors[(int) flash->sector];
flash->thinker.function = T_LightFlash;
P_AddThinker(&flash->thinker);
@@ -596,8 +636,7 @@
case tc_strobe:
strobe = Z_Malloc(sizeof(*strobe), PU_LEVEL, NULL);
- memcpy(strobe, save_p, sizeof(*strobe));
- save_p += sizeof(*strobe);
+ SV_Read(strobe, sizeof(*strobe));
strobe->sector = §ors[(int) strobe->sector];
strobe->thinker.function = T_StrobeFlash;
P_AddThinker(&strobe->thinker);
@@ -605,8 +644,7 @@
case tc_glow:
glow = Z_Malloc(sizeof(*glow), PU_LEVEL, NULL);
- memcpy(glow, save_p, sizeof(*glow));
- save_p += sizeof(*glow);
+ SV_Read(glow, sizeof(*glow));
glow->sector = §ors[(int) glow->sector];
glow->thinker.function = T_Glow;
P_AddThinker(&glow->thinker);