summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Haley2011-02-10 20:45:00 +0000
committerJames Haley2011-02-10 20:45:00 +0000
commit0e7e7ba3b64e6bccfcca85d4120f2f60f1fe05c3 (patch)
treed8d4d753dbd3c0568652b5c87d4ce6f6251c2d8c
parent808f6fd842f581f31aa0d91617a759af46fdc732 (diff)
downloadchocolate-doom-0e7e7ba3b64e6bccfcca85d4120f2f60f1fe05c3.tar.gz
chocolate-doom-0e7e7ba3b64e6bccfcca85d4120f2f60f1fe05c3.tar.bz2
chocolate-doom-0e7e7ba3b64e6bccfcca85d4120f2f60f1fe05c3.zip
Restarted work on hub save code. Brought in multiple filepath handling
routines from Eternity. Subversion-branch: /branches/strife-branch Subversion-revision: 2252
-rw-r--r--src/strife/d_main.c51
-rw-r--r--src/strife/doomdef.h4
-rw-r--r--src/strife/g_game.c47
-rw-r--r--src/strife/m_saves.c323
-rw-r--r--src/strife/m_saves.h8
-rw-r--r--src/strife/p_enemy.c4
-rw-r--r--src/strife/s_sound.c4
7 files changed, 358 insertions, 83 deletions
diff --git a/src/strife/d_main.c b/src/strife/d_main.c
index 12c64016..8ffcc2ad 100644
--- a/src/strife/d_main.c
+++ b/src/strife/d_main.c
@@ -58,6 +58,7 @@
#include "m_controls.h"
#include "m_misc.h"
#include "m_menu.h"
+#include "m_saves.h" // haleyjd [STRIFE]
#include "p_saveg.h"
#include "i_endoom.h"
@@ -80,7 +81,6 @@
#include "p_setup.h"
#include "r_local.h"
-
#include "d_main.h"
//
@@ -793,53 +793,6 @@ static char *GetGameName(char *gamename)
return gamename;
}
-//
-// haleyjd: STRIFE-FIXME: Temporary?
-// Code borrowed from Eternity, and modified to return separator char
-//
-char M_GetFilePath(const char *fn, char *dest, size_t len)
-{
- boolean found_slash = false;
- char *p;
- char sepchar = '\0';
-
- memset(dest, 0, len);
-
- p = dest + len - 1;
-
- strncpy(dest, fn, len);
-
- while(p >= dest)
- {
- if(*p == '/' || *p == '\\')
- {
- sepchar = *p;
- found_slash = true; // mark that the path ended with a slash
- *p = '\0';
- break;
- }
- *p = '\0';
- p--;
- }
-
- // haleyjd: in the case that no slash was ever found, yet the
- // path string is empty, we are dealing with a file local to the
- // working directory. The proper path to return for such a string is
- // not "", but ".", since the format strings add a slash now. When
- // the string is empty but a slash WAS found, we really do want to
- // return the empty string, since the path is relative to the root.
- if(!found_slash && *dest == '\0')
- *dest = '.';
-
- // if a separator is not found, default to forward, because Windows
- // supports that too.
- if(sepchar == '\0')
- sepchar = '/';
-
- return sepchar;
-}
-
-
//
// Find out what version of Doom is playing.
//
@@ -978,6 +931,8 @@ static void SetSaveGameDir(char *iwad_filename)
basefile, DIR_SEPARATOR);
M_MakeDirectory(savegamedir);
+
+ // haleyjd 20110210: Create Strife hub save folders
}
// Check if the IWAD file is the Chex Quest IWAD.
diff --git a/src/strife/doomdef.h b/src/strife/doomdef.h
index 52cfc587..459c43dd 100644
--- a/src/strife/doomdef.h
+++ b/src/strife/doomdef.h
@@ -246,8 +246,8 @@ enum
QF_QUEST1 = (1 << tk_quest1), // Obtained Beldin's ring
QF_QUEST2 = (1 << tk_quest2), // Stole the Chalice
QF_QUEST3 = (1 << tk_quest3), // Permission to visit Irale (visited Macil)
- QF_QUEST4 = (1 << tk_quest4),
- QF_QUEST5 = (1 << tk_quest5),
+ QF_QUEST4 = (1 << tk_quest4), // Accepted Gov. Mourel's "messy" chore
+ QF_QUEST5 = (1 << tk_quest5), // Accepted Gov. Mourel's "bloody" chore
QF_QUEST6 = (1 << tk_quest6), // Destroyed the Power Coupling
QF_QUEST7 = (1 << tk_quest7), // Killed Blue Acolytes ("Scanning Team")
QF_QUEST8 = (1 << tk_quest8),
diff --git a/src/strife/g_game.c b/src/strife/g_game.c
index 225891bd..257becef 100644
--- a/src/strife/g_game.c
+++ b/src/strife/g_game.c
@@ -23,8 +23,6 @@
//
//-----------------------------------------------------------------------------
-
-
#include <string.h>
#include <stdlib.h>
#include <math.h>
@@ -41,6 +39,7 @@
#include "m_controls.h"
#include "m_misc.h"
#include "m_menu.h"
+#include "m_saves.h" // STRIFE
#include "m_random.h"
#include "i_system.h"
#include "i_timer.h"
@@ -53,7 +52,6 @@
#include "hu_stuff.h"
#include "st_stuff.h"
#include "am_map.h"
-#include "m_misc.h" // STRIFE
// Needs access to LFB.
#include "v_video.h"
@@ -117,17 +115,17 @@ angle_t riftangle; // player angle saved during exit
int timelimit;
boolean paused;
-boolean sendpause; // send a pause event next tic
-boolean sendsave; // send a save event next tic
+boolean sendpause; // send a pause event next tic
+boolean sendsave; // send a save event next tic
boolean usergame; // ok to save / end game
boolean timingdemo; // if true, exit with report on completion
boolean nodrawers; // for comparative timing purposes
-int starttime; // for comparative timing purposes
+int starttime; // for comparative timing purposes
boolean viewactive;
-boolean deathmatch; // only if started as net death
+boolean deathmatch; // only if started as net death
boolean netgame; // only true if packets are broadcast
boolean playeringame[MAXPLAYERS];
player_t players[MAXPLAYERS];
@@ -149,15 +147,15 @@ boolean netdemo;
byte* demobuffer;
byte* demo_p;
byte* demoend;
-boolean singledemo; // quit after playing a demo from cmdline
+boolean singledemo; // quit after playing a demo from cmdline
boolean precache = true; // if true, load all graphics at start
boolean testcontrols = false; // Invoked by setup to test controls
-wbstartstruct_t wminfo; // parms for world map / intermission
+wbstartstruct_t wminfo; // parms for world map / intermission
-byte consistancy[MAXPLAYERS][BACKUPTICS];
+byte consistancy[MAXPLAYERS][BACKUPTICS];
#define MAXPLMOVE (forwardmove[1])
@@ -1341,23 +1339,23 @@ G_CheckSpot
void G_DeathMatchSpawnPlayer (int playernum)
{
int i,j;
- int selections;
-
+ int selections;
+
selections = deathmatch_p - deathmatchstarts;
if (selections < 4)
- I_Error ("Only %i deathmatch spots, 4 required", selections);
-
+ I_Error ("Only %i deathmatch spots, 4 required", selections);
+
for (j=0 ; j<20 ; j++)
{
- i = P_Random() % selections;
- if (G_CheckSpot (playernum, &deathmatchstarts[i]) )
- {
- deathmatchstarts[i].type = playernum+1;
- P_SpawnPlayer (&deathmatchstarts[i]);
- return;
- }
+ i = P_Random() % selections;
+ if (G_CheckSpot (playernum, &deathmatchstarts[i]) )
+ {
+ deathmatchstarts[i].type = playernum+1;
+ P_SpawnPlayer (&deathmatchstarts[i]);
+ return;
+ }
}
-
+
// no good spot, so the player will probably get stuck
P_SpawnPlayer (&playerstarts[playernum]);
}
@@ -1819,14 +1817,15 @@ boolean G_WriteSaveName()
dword_86280 = eax0;
- // STRIFE-TODO: yeah good luck making THIS work on Linux.
- if(M_CheckParm(DEH_String("-cdrom")))
+#ifdef _WIN32
+ if(M_CheckParm("-cdrom") > 0)
{
sprintf(savepath2, "c:\\strife.cd\\strfsav%d.ssg\\", 6);
v5 = dword_86280;
dirstr = "c:\\strife.cd\\strfsav%d.ssg\\";
}
else
+#endif
{
sprintf(savepath2, "strfsav%d.ssg\\", 6);
v5 = dword_86280;
diff --git a/src/strife/m_saves.c b/src/strife/m_saves.c
index f845598e..6b99a7a8 100644
--- a/src/strife/m_saves.c
+++ b/src/strife/m_saves.c
@@ -37,21 +37,61 @@
#else
#error Need an include for dirent.h!
#endif
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
#include "z_zone.h"
#include "i_system.h"
#include "d_player.h"
#include "deh_str.h"
+#include "doomstat.h"
#include "m_misc.h"
+#include "m_saves.h"
#include "p_dialog.h"
//
+// File Paths
+//
+// Strife maintains multiple file paths related to savegames.
+//
+char *savepath;
+char *savepath2;
+char *loadpath;
+
+//
// ClearTmp
//
// Clear the temporary save directory
//
void ClearTmp(void)
{
+ DIR *sp2dir = NULL;
+ struct dirent *f = NULL;
+
+ if(savepath2 == NULL)
+ I_Error("you fucked up savedir man!");
+
+ if(!(sp2dir = opendir(savepath2)))
+ I_Error("ClearTmp: Couldn't open dir %s", savepath2);
+
+ while((f = readdir(sp2dir)))
+ {
+ char *filepath = NULL;
+
+ // haleyjd: skip "." and ".." without assuming they're the
+ // first two entries like the original code did.
+ if(!strcmp(f->d_name, ".") || !strcmp(f->d_name, ".."))
+ continue;
+
+ // haleyjd: use M_SafeFilePath, not sprintf
+ filepath = M_SafeFilePath(savepath2, f->d_name);
+ remove(filepath);
+
+ Z_Free(filepath);
+ }
+
+ closedir(sp2dir);
}
//
@@ -61,16 +101,50 @@ void ClearTmp(void)
//
void ClearSlot(void)
{
+ if(savepath == NULL)
+ I_Error("userdir is fucked up man!");
+
+ // STRIFE-TODO
}
//
// FromCurr
//
-// Moving files from one directory to another...
-// STRIFE-TODO: figure out exactly what this is for.
+// Copying files from savepath2 to savepath
//
void FromCurr(void)
{
+ DIR *sp2dir = NULL;
+ struct dirent *f = NULL;
+
+ if(!(sp2dir = opendir(savepath2)))
+ I_Error("FromCurr: Couldn't open dir %s", savepath2);
+
+ while((f = readdir(sp2dir)))
+ {
+ byte *filebuffer = NULL;
+ int filelen = 0;
+ char *srcfilename = NULL;
+ char *dstfilename = NULL;
+
+ // haleyjd: skip "." and ".." without assuming they're the
+ // first two entries like the original code did.
+ if(!strcmp(f->d_name, ".") || !strcmp(f->d_name, ".."))
+ continue;
+
+ // haleyjd: use M_SafeFilePath, NOT sprintf.
+ srcfilename = M_SafeFilePath(savepath2, f->d_name);
+ dstfilename = M_SafeFilePath(savepath, f->d_name);
+
+ filelen = M_ReadFile(srcfilename, &filebuffer);
+ M_WriteFile(dstfilename, filebuffer, filelen);
+
+ Z_Free(filebuffer);
+ Z_Free(srcfilename);
+ Z_Free(dstfilename);
+ }
+
+ closedir(sp2dir);
}
//
@@ -80,6 +154,7 @@ void FromCurr(void)
//
void sub_1B2F4(void)
{
+ // STRIFE-TODO
}
//
@@ -89,6 +164,27 @@ void sub_1B2F4(void)
//
void M_SaveMoveMapToHere(void)
{
+ char *mapsave = NULL;
+ char *heresave = NULL;
+ char tmpnum[33];
+
+ // haleyjd: no itoa available...
+ memset(tmpnum, 0, sizeof(tmpnum));
+ sprintf(tmpnum, "%d", gamemap);
+
+ // haleyjd: use M_SafeFilePath, not sprintf
+ mapsave = M_SafeFilePath(savepath, tmpnum);
+ heresave = M_SafeFilePath(savepath, "here");
+
+ // haleyjd: use M_FileExists, not access
+ if(M_FileExists(mapsave))
+ {
+ remove(heresave);
+ rename(mapsave, heresave);
+ }
+
+ Z_Free(mapsave);
+ Z_Free(heresave);
}
//
@@ -98,6 +194,25 @@ void M_SaveMoveMapToHere(void)
//
void M_SaveMoveHereToMap(void)
{
+ char *mapsave = NULL;
+ char *heresave = NULL;
+ char tmpnum[33];
+
+ // haleyjd: no itoa available...
+ memset(tmpnum, 0, sizeof(tmpnum));
+ sprintf(tmpnum, "%d", gamemap);
+
+ mapsave = M_SafeFilePath(savepath2, tmpnum);
+ heresave = M_SafeFilePath(savepath2, "here");
+
+ if(M_FileExists(heresave))
+ {
+ remove(mapsave);
+ rename(heresave, mapsave);
+ }
+
+ Z_Free(mapsave);
+ Z_Free(heresave);
}
//
@@ -107,10 +222,15 @@ void M_SaveMoveHereToMap(void)
//
boolean M_SaveMisObj(const char *path)
{
- char destpath[100]; // WARNING: not large enough for modern file paths!
+ boolean result;
+ char *destpath = NULL;
+
+ // haleyjd 20110210: use M_SafeFilePath, not sprintf
+ destpath = M_SafeFilePath(path, "mis_obj");
+ result = M_WriteFile(destpath, mission_objective, OBJECTIVE_LEN);
- DEH_snprintf(destpath, sizeof(destpath), "%smis_obj", path);
- return M_WriteFile(destpath, mission_objective, OBJECTIVE_LEN);
+ Z_Free(destpath);
+ return result;
}
//
@@ -120,6 +240,199 @@ boolean M_SaveMisObj(const char *path)
//
void M_ReadMisObj(void)
{
+ FILE *f = NULL;
+ char *srcpath = NULL;
+
+ // haleyjd: use M_SafeFilePath, not sprintf
+ srcpath = M_SafeFilePath(savepath2, "mis_obj");
+
+ if((f = fopen(srcpath, "rb")))
+ {
+ fread(mission_objective, 1, 300, f);
+ fclose(f);
+ }
+
+ Z_Free(srcpath);
+}
+
+//=============================================================================
+//
+// Original Routines
+//
+// haleyjd - None of the below code is derived from Strife itself, but has been
+// adapted or created in order to provide secure, portable filepath handling
+// for the purposes of savegame support. This is partially needed to allow for
+// differences in Choco due to it being multiplatform. The rest exists because
+// I cannot stand programming in an impoverished ANSI C environment that
+// calls sprintf on fixed-size buffers. :P
+//
+
+//
+// M_Calloc
+//
+// haleyjd 20110210 - original routine
+// Because Choco doesn't have Z_Calloc O_o
+//
+void *M_Calloc(size_t n1, size_t n2)
+{
+ return (n1 *= n2) ? memset(Z_Malloc(n1, PU_STATIC, NULL), 0, n1) : NULL;
+}
+
+//
+// M_StringAlloc
+//
+// haleyjd: This routine takes any number of strings and a number of extra
+// characters, calculates their combined length, and calls Z_Alloca to create
+// a temporary buffer of that size. This is extremely useful for allocation of
+// file paths, and is used extensively in d_main.c. The pointer returned is
+// to a temporary Z_Alloca buffer, which lives until the next main loop
+// iteration, so don't cache it. Note that this idiom is not possible with the
+// normal non-standard alloca function, which allocates stack space.
+//
+// [STRIFE] - haleyjd 20110210
+// This routine is taken from the Eternity Engine and adapted to do without
+// Z_Alloca. I need secure string concatenation for filepath handling. The
+// only difference from use in EE is that the pointer returned in *str must
+// be manually freed.
+//
+int M_StringAlloc(char **str, int numstrs, size_t extra, const char *str1, ...)
+{
+ va_list args;
+ size_t len = extra;
+
+ if(numstrs < 1)
+ I_Error("M_StringAlloc: invalid input\n");
+
+ len += strlen(str1);
+
+ --numstrs;
+
+ if(numstrs != 0)
+ {
+ va_start(args, str1);
+
+ while(numstrs != 0)
+ {
+ const char *argstr = va_arg(args, const char *);
+
+ len += strlen(argstr);
+
+ --numstrs;
+ }
+
+ va_end(args);
+ }
+
+ ++len;
+
+ *str = (char *)(M_Calloc(1, len));
+
+ return len;
+}
+
+//
+// M_NormalizeSlashes
+//
+// Remove trailing slashes, translate backslashes to slashes
+// The string to normalize is passed and returned in str
+//
+// killough 11/98: rewritten
+//
+// [STRIFE] - haleyjd 20110210: Borrowed from Eternity and adapted to respect
+// the DIR_SEPARATOR define used by Choco Doom. This routine originated in
+// BOOM.
+//
+void M_NormalizeSlashes(char *str)
+{
+ char *p;
+
+ // Convert all slashes/backslashes to DIR_SEPARATOR
+ for(p = str; *p; p++)
+ {
+ if((*p == '/' || *p == '\\') && *p != DIR_SEPARATOR)
+ *p = DIR_SEPARATOR;
+ }
+
+ // Remove trailing slashes
+ while(p > str && *--p == DIR_SEPARATOR)
+ *p = 0;
+
+ // Collapse multiple slashes
+ for(p = str; (*str++ = *p); )
+ if(*p++ == DIR_SEPARATOR)
+ while(*p == DIR_SEPARATOR)
+ p++;
+}
+
+//
+// M_SafeFilePath
+//
+// haleyjd 20110210 - original routine.
+// This routine performs safe, portable concatenation of a base file path
+// with another path component or file name. The returned string is Z_Malloc'd
+// and should be freed when it has exhausted its usefulness.
+//
+char *M_SafeFilePath(const char *basepath, const char *newcomponent)
+{
+ int newstrlen = 0;
+ char *newstr = NULL;
+
+ // Always throw in a slash. M_NormalizeSlashes will remove it in the case
+ // that either basepath or newcomponent includes a redundant slash at the
+ // end or beginning respectively.
+ newstrlen = M_StringAlloc(&newstr, 3, 1, basepath, "/", newcomponent);
+ snprintf(newstr, newstrlen, "%s/%s", basepath, newcomponent);
+ M_NormalizeSlashes(newstr);
+
+ return newstr;
+}
+
+//
+// M_GetFilePath
+//
+// haleyjd: STRIFE-FIXME: Temporary?
+// Code borrowed from Eternity, and modified to return separator char
+//
+char M_GetFilePath(const char *fn, char *dest, size_t len)
+{
+ boolean found_slash = false;
+ char *p;
+ char sepchar = '\0';
+
+ memset(dest, 0, len);
+
+ p = dest + len - 1;
+
+ strncpy(dest, fn, len);
+
+ while(p >= dest)
+ {
+ if(*p == '/' || *p == '\\')
+ {
+ sepchar = *p;
+ found_slash = true; // mark that the path ended with a slash
+ *p = '\0';
+ break;
+ }
+ *p = '\0';
+ p--;
+ }
+
+ // haleyjd: in the case that no slash was ever found, yet the
+ // path string is empty, we are dealing with a file local to the
+ // working directory. The proper path to return for such a string is
+ // not "", but ".", since the format strings add a slash now. When
+ // the string is empty but a slash WAS found, we really do want to
+ // return the empty string, since the path is relative to the root.
+ if(!found_slash && *dest == '\0')
+ *dest = '.';
+
+ // if a separator is not found, default to forward, because Windows
+ // supports that too.
+ if(sepchar == '\0')
+ sepchar = '/';
+
+ return sepchar;
}
// EOF
diff --git a/src/strife/m_saves.h b/src/strife/m_saves.h
index 9b587c81..b55ffa12 100644
--- a/src/strife/m_saves.h
+++ b/src/strife/m_saves.h
@@ -31,8 +31,16 @@
#ifndef M_SAVES_H__
#define M_SAVES_H__
+// Strife Savegame Functions
boolean M_SaveMisObj(const char *path);
+// Custom Utilities for Filepath Handling
+void *M_Calloc(size_t n1, size_t n2);
+void M_NormalizeSlashes(char *str);
+int M_StringAlloc(char **str, int numstrs, size_t extra, const char *str1, ...);
+char *M_SafeFilePath(const char *basepath, const char *newcomponent);
+char M_GetFilePath(const char *fn, char *dest, size_t len);
+
#endif
// EOF
diff --git a/src/strife/p_enemy.c b/src/strife/p_enemy.c
index 4bfceefe..9cbaf3ed 100644
--- a/src/strife/p_enemy.c
+++ b/src/strife/p_enemy.c
@@ -315,7 +315,7 @@ boolean P_CheckMissileRange(mobj_t* actor)
actor->y-actor->target->y) - 64*FRACUNIT;
if (!actor->info->meleestate)
- dist -= 128*FRACUNIT; // no melee attack, so fire more
+ dist -= 128*FRACUNIT; // no melee attack, so fire more
dist >>= 16;
@@ -669,7 +669,7 @@ void P_NewRandomDir(mobj_t* actor)
dir = DI_SOUTHEAST;
while(1)
{
- // haleyjd 09/05/10: P_TryWalk -> P_Move, missing random code.
+ // haleyjd 09/05/10: missing random code.
if(dir != opposite[actor->movedir])
{
actor->movedir = dir;
diff --git a/src/strife/s_sound.c b/src/strife/s_sound.c
index bedde12c..c29ce392 100644
--- a/src/strife/s_sound.c
+++ b/src/strife/s_sound.c
@@ -538,7 +538,8 @@ static unsigned int S_voiceHash(const char *str)
++c;
}
- return h;}
+ return h;
+}
static voiceinfo_t *voices[NUMVOICECHAINS];
@@ -619,7 +620,6 @@ void I_StartVoice(const char *lumpname)
strncpy(lumpnamedup, lumpname, 9);
lumpnamedup[8] = '\0';
-
if((lumpnum = W_CheckNumForName(lumpnamedup)) != -1)
{
// haleyjd: Choco-specific: get a voice structure