diff options
author | James Haley | 2011-02-10 20:45:00 +0000 |
---|---|---|
committer | James Haley | 2011-02-10 20:45:00 +0000 |
commit | 0e7e7ba3b64e6bccfcca85d4120f2f60f1fe05c3 (patch) | |
tree | d8d4d753dbd3c0568652b5c87d4ce6f6251c2d8c | |
parent | 808f6fd842f581f31aa0d91617a759af46fdc732 (diff) | |
download | chocolate-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.c | 51 | ||||
-rw-r--r-- | src/strife/doomdef.h | 4 | ||||
-rw-r--r-- | src/strife/g_game.c | 47 | ||||
-rw-r--r-- | src/strife/m_saves.c | 323 | ||||
-rw-r--r-- | src/strife/m_saves.h | 8 | ||||
-rw-r--r-- | src/strife/p_enemy.c | 4 | ||||
-rw-r--r-- | src/strife/s_sound.c | 4 |
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 |