implement per-PWAD savegame directories (#1237)

* implement per-PWAD savegame directories

Fixs #793

* do not report savegame directory

* save savegames in `savegames` subdirectory

* do not call M_ForceUppercase() on string of unknown length

* fix infinite loop for WADs not containing maps
This commit is contained in:
Fabian Greffrath 2023-10-27 13:02:11 +02:00 committed by GitHub
parent 1cec87ee7e
commit 22fc605394
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 105 additions and 10 deletions

View File

@ -659,9 +659,10 @@ static boolean D_AddZipFile(const char *file)
// killough 11/98: remove limit on number of files
//
static int numwadfiles;
void D_AddFile(const char *file)
{
static int numwadfiles, numwadfiles_alloc;
static int numwadfiles_alloc;
char *path = D_TryFindWADByName(file);
@ -903,6 +904,63 @@ static void CheckIWAD(const char *iwadname)
}
}
static boolean FileContainsMaps(const char *filename)
{
int i;
FILE *file = NULL;
wadinfo_t header;
filelump_t *fileinfo = NULL;
boolean ret = false;
while (ret == false)
{
if (filename == NULL)
{
break;
}
file = M_fopen(filename, "rb");
if (file == NULL)
{
break;
}
if (fread(&header, sizeof(header), 1, file) != 1)
{
break;
}
header.numlumps = LONG(header.numlumps);
header.infotableofs = LONG(header.infotableofs);
fileinfo = malloc(header.numlumps * sizeof(filelump_t));
if (fseek(file, header.infotableofs, SEEK_SET) ||
fread(fileinfo, sizeof(filelump_t), header.numlumps, file) != header.numlumps)
{
break;
}
for (i = 0; i < header.numlumps; i++)
{
if (StartsWithMapIdentifier(fileinfo[i].name))
{
ret = true;
break;
}
}
break;
}
if (fileinfo)
free(fileinfo);
if (file)
fclose(file);
return ret;
}
//
// IdentifyVersion
//
@ -1905,6 +1963,7 @@ static boolean CheckHaveSSG (void)
void D_DoomMain(void)
{
int p;
int mainwadfile = 0;
setbuf(stdout,NULL);
@ -2133,6 +2192,7 @@ void D_DoomMain(void)
// killough 11/98: allow multiple -file parameters
boolean file = modifiedgame = true; // homebrew levels
mainwadfile = numwadfiles;
while (++p < myargc)
if (*myargv[p] == '-')
file = !strcasecmp(myargv[p],"-file");
@ -2141,6 +2201,36 @@ void D_DoomMain(void)
D_AddFile(myargv[p]);
}
if (!M_CheckParm("-save"))
{
int i;
char *wadname = wadfiles[0], *oldsavegame = basesavegame;
for (i = mainwadfile; i < numwadfiles; i++)
{
if (FileContainsMaps(wadfiles[i]))
{
wadname = wadfiles[i];
break;
}
}
basesavegame = M_StringJoin(oldsavegame, DIR_SEPARATOR_S,
"savegames", NULL);
free(oldsavegame);
NormalizeSlashes(basesavegame);
M_MakeDirectory(basesavegame);
oldsavegame = basesavegame;
basesavegame = M_StringJoin(oldsavegame, DIR_SEPARATOR_S,
M_BaseName(wadname), NULL);
free(oldsavegame);
NormalizeSlashes(basesavegame);
M_MakeDirectory(basesavegame);
}
// add wad files from autoload PWAD directories
D_AutoloadPWadDir();

View File

@ -1133,20 +1133,23 @@ static void SetDefaultSaveName (int slot)
}
// [FG] override savegame name if it already starts with a map identifier
static boolean StartsWithMapIdentifier (char *str)
boolean StartsWithMapIdentifier (char *str)
{
M_ForceUppercase(str);
if (strlen(str) >= 4 &&
str[0] == 'E' && isdigit(str[1]) &&
str[2] == 'M' && isdigit(str[3]))
if (strnlen(str, 8) >= 4 &&
toupper(str[0]) == 'E' &&
isdigit(str[1]) &&
toupper(str[2]) == 'M' &&
isdigit(str[3]))
{
return true;
}
if (strlen(str) >= 5 &&
str[0] == 'M' && str[1] == 'A' && str[2] == 'P' &&
isdigit(str[3]) && isdigit(str[4]))
if (strnlen(str, 8) >= 5 &&
toupper(str[0]) == 'M' &&
toupper(str[1]) == 'A' &&
toupper(str[2]) == 'P' &&
isdigit(str[3]) &&
isdigit(str[4]))
{
return true;
}

View File

@ -191,6 +191,8 @@ extern void M_SetQuickSaveSlot (int slot);
#define MAX_MIDI_PLAYER_MENU_ITEMS 128
extern void M_GetMidiDevices(void);
extern boolean StartsWithMapIdentifier (char *str);
#endif
//----------------------------------------------------------------------------