2018-11-16 00:42:29 +01:00
|
|
|
/*****************************************************************************\
|
|
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
|
|
This file is licensed under the Snes9x License.
|
|
|
|
For further information, consult the LICENSE file in the root directory.
|
|
|
|
\*****************************************************************************/
|
|
|
|
|
2010-09-25 17:46:12 +02:00
|
|
|
#include <sys/stat.h>
|
2010-09-26 11:19:15 +02:00
|
|
|
#include <errno.h>
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
#include "gtk_compat.h"
|
2010-09-25 17:46:12 +02:00
|
|
|
#include "gtk_s9x.h"
|
2020-07-05 00:53:38 +02:00
|
|
|
#include "display.h"
|
|
|
|
#include "memmap.h"
|
|
|
|
#include "snapshot.h"
|
|
|
|
#include "cheats.h"
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2018-05-14 03:17:02 +02:00
|
|
|
static char buf[PATH_MAX];
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
const char *S9xGetFilenameInc(const char *e, enum s9x_getdirtype dirtype)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
static char filename[PATH_MAX + 1];
|
|
|
|
char dir[_MAX_DIR + 1];
|
|
|
|
char drive[_MAX_DRIVE + 1];
|
|
|
|
char fname[_MAX_FNAME + 1];
|
|
|
|
char ext[_MAX_EXT + 1];
|
2010-09-25 17:46:12 +02:00
|
|
|
unsigned int i = 0;
|
2020-07-05 00:53:38 +02:00
|
|
|
struct stat buf;
|
|
|
|
const char *d;
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
|
|
|
|
d = S9xGetDirectory(dirtype);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
snprintf(filename, PATH_MAX, "%s" SLASH_STR "%s%03d%s", d, fname, i, e);
|
2010-09-25 17:46:12 +02:00
|
|
|
i++;
|
2020-07-05 00:53:38 +02:00
|
|
|
} while (stat(filename, &buf) == 0 && i != 0); /* Overflow? ...riiight :-) */
|
2010-09-25 17:46:12 +02:00
|
|
|
|
|
|
|
return (filename);
|
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
const char *S9xGetDirectory(enum s9x_getdirtype dirtype)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
static char path[PATH_MAX + 1];
|
|
|
|
|
|
|
|
switch (dirtype)
|
|
|
|
{
|
2020-06-20 17:44:11 +02:00
|
|
|
case HOME_DIR:
|
2020-06-21 22:25:54 +02:00
|
|
|
snprintf(path, PATH_MAX + 1, "%s", get_config_dir().c_str());
|
2020-06-20 17:44:11 +02:00
|
|
|
break;
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-06-20 17:44:11 +02:00
|
|
|
case SNAPSHOT_DIR:
|
2020-06-21 22:25:54 +02:00
|
|
|
snprintf(path, PATH_MAX + 1, "%s", gui_config->savestate_directory.c_str());
|
2020-06-20 17:44:11 +02:00
|
|
|
break;
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-06-20 17:44:11 +02:00
|
|
|
case PATCH_DIR:
|
2020-06-21 22:25:54 +02:00
|
|
|
snprintf(path, PATH_MAX + 1, "%s", gui_config->patch_directory.c_str());
|
2020-06-20 17:44:11 +02:00
|
|
|
break;
|
2010-09-26 11:19:15 +02:00
|
|
|
|
2020-06-20 17:44:11 +02:00
|
|
|
case CHEAT_DIR:
|
2020-06-21 22:25:54 +02:00
|
|
|
snprintf(path, PATH_MAX + 1, "%s", gui_config->cheat_directory.c_str());
|
2020-06-20 17:44:11 +02:00
|
|
|
break;
|
2010-09-26 11:19:15 +02:00
|
|
|
|
2020-06-20 17:44:11 +02:00
|
|
|
case SRAM_DIR:
|
2020-06-21 22:25:54 +02:00
|
|
|
snprintf(path, PATH_MAX + 1, "%s", gui_config->sram_directory.c_str());
|
2020-06-20 17:44:11 +02:00
|
|
|
break;
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-06-20 17:44:11 +02:00
|
|
|
case SCREENSHOT_DIR:
|
|
|
|
case SPC_DIR:
|
2020-06-21 22:25:54 +02:00
|
|
|
snprintf(path, PATH_MAX + 1, "%s", gui_config->export_directory.c_str());
|
2020-06-20 17:44:11 +02:00
|
|
|
break;
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-06-20 17:44:11 +02:00
|
|
|
default:
|
|
|
|
path[0] = '\0';
|
2010-09-26 11:19:15 +02:00
|
|
|
}
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2019-10-11 01:42:50 +02:00
|
|
|
/* Check if directory exists, make it and/or set correct permissions */
|
2010-09-26 11:19:15 +02:00
|
|
|
if (dirtype != HOME_DIR && path[0] != '\0')
|
|
|
|
{
|
2019-10-11 01:42:50 +02:00
|
|
|
struct stat file_info;
|
|
|
|
|
|
|
|
if (stat(path, &file_info) == -1)
|
|
|
|
{
|
|
|
|
mkdir(path, 0755);
|
|
|
|
chmod(path, 0755);
|
|
|
|
}
|
|
|
|
else if (!(file_info.st_mode & 0700))
|
|
|
|
chmod(path, file_info.st_mode | 0700);
|
2010-09-26 11:19:15 +02:00
|
|
|
}
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2010-09-26 11:19:15 +02:00
|
|
|
/* Anything else, use ROM filename path */
|
|
|
|
if (path[0] == '\0')
|
|
|
|
{
|
|
|
|
char *loc;
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
strcpy(path, Memory.ROMFilename);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
loc = strrchr(path, SLASH_CHAR);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2010-09-26 11:19:15 +02:00
|
|
|
if (loc == NULL)
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
if (getcwd(path, PATH_MAX + 1) == NULL)
|
2010-09-26 11:19:15 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
strcpy(path, getenv("HOME"));
|
2010-09-26 11:19:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
path[loc - path] = '\0';
|
|
|
|
}
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
const char *S9xGetFilename(const char *ex, enum s9x_getdirtype dirtype)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
static char filename[PATH_MAX + 1];
|
2020-07-05 00:53:38 +02:00
|
|
|
char dir[_MAX_DIR + 1];
|
|
|
|
char drive[_MAX_DRIVE + 1];
|
|
|
|
char fname[_MAX_FNAME + 1];
|
|
|
|
char ext[_MAX_EXT + 1];
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
snprintf(filename, sizeof(filename), "%s" SLASH_STR "%s%s",
|
|
|
|
S9xGetDirectory(dirtype), fname, ex);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
|
|
|
return (filename);
|
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
const char *S9xBasename(const char *f)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
const char *p;
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
if ((p = strrchr(f, '/')) != NULL || (p = strrchr(f, '\\')) != NULL)
|
2010-09-25 17:46:12 +02:00
|
|
|
return (p + 1);
|
|
|
|
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
const char *S9xBasenameNoExt(const char *f)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2018-11-18 18:33:18 +01:00
|
|
|
static char filename[PATH_MAX];
|
2010-09-25 17:46:12 +02:00
|
|
|
const char *base, *ext;
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
if (!(base = strrchr(f, SLASH_CHAR)))
|
2010-09-25 17:46:12 +02:00
|
|
|
base = f;
|
|
|
|
else
|
|
|
|
base += 1;
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
ext = strrchr(f, '.');
|
2010-09-25 17:46:12 +02:00
|
|
|
|
|
|
|
if (!ext)
|
2020-07-05 00:53:38 +02:00
|
|
|
snprintf(filename, PATH_MAX, "%s", base);
|
2010-09-25 17:46:12 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
int len = ext - base;
|
2020-07-05 00:53:38 +02:00
|
|
|
strncpy(filename, base, len);
|
2010-09-25 17:46:12 +02:00
|
|
|
filename[len] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
return filename;
|
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
static int file_exists(const char *name)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
FILE *f = NULL;
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
f = fopen(name, "r");
|
2010-09-25 17:46:12 +02:00
|
|
|
|
|
|
|
if (!f)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
fclose(f);
|
2010-09-25 17:46:12 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
bool8 S9xOpenSnapshotFile(const char *fname, bool8 read_only, STREAM *file)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
char filename[PATH_MAX + 1];
|
|
|
|
char drive[_MAX_DRIVE + 1];
|
|
|
|
char dir[_MAX_DIR + 1];
|
|
|
|
char ext[_MAX_EXT + 1];
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
_splitpath(fname, drive, dir, filename, ext);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
|
|
|
if (*drive || *dir == '/' || (*dir == '.' && (*(dir + 1) == '/')))
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
snprintf(filename, PATH_MAX + 1, "%s", fname);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
if (!file_exists(filename))
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
if (!*ext)
|
2020-07-05 00:53:38 +02:00
|
|
|
strcat(filename, ".s9x");
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
strcpy(filename, S9xGetDirectory(SNAPSHOT_DIR));
|
|
|
|
strcat(filename, SLASH_STR);
|
|
|
|
strcat(filename, fname);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
if (!file_exists(filename))
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
if (!*ext)
|
2020-07-05 00:53:38 +02:00
|
|
|
strcat(filename, ".s9x");
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef ZLIB
|
|
|
|
if (read_only)
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
if ((*file = OPEN_STREAM(filename, "rb")))
|
2018-12-28 23:32:32 +01:00
|
|
|
return (true);
|
2010-09-26 11:19:15 +02:00
|
|
|
else
|
2020-07-05 00:53:38 +02:00
|
|
|
fprintf(stderr,
|
|
|
|
"Failed to open file stream for reading. (%s)\n",
|
|
|
|
zError(errno));
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
if ((*file = OPEN_STREAM(filename, "wb")))
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2018-12-28 23:32:32 +01:00
|
|
|
return (true);
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
2010-09-26 11:19:15 +02:00
|
|
|
else
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
fprintf(stderr,
|
|
|
|
"Couldn't open stream with zlib. (%s)\n",
|
|
|
|
zError(errno));
|
2010-09-26 11:19:15 +02:00
|
|
|
}
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
2010-09-26 11:19:15 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
fprintf(stderr, "zlib: Couldn't open snapshot file:\n%s\n", filename);
|
2010-09-26 11:19:15 +02:00
|
|
|
|
2010-09-25 17:46:12 +02:00
|
|
|
#else
|
2020-07-05 00:53:38 +02:00
|
|
|
char command[PATH_MAX];
|
2010-09-25 17:46:12 +02:00
|
|
|
|
|
|
|
if (read_only)
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
sprintf(command, "gzip -d <\"%s\"", filename);
|
|
|
|
if (*file = popen(command, "r"))
|
2018-12-28 23:32:32 +01:00
|
|
|
return (true);
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
sprintf(command, "gzip --best >\"%s\"", filename);
|
|
|
|
if (*file = popen(command, "wb"))
|
2018-12-28 23:32:32 +01:00
|
|
|
return (true);
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
2010-09-26 11:19:15 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
fprintf(stderr, "gzip: Couldn't open snapshot file:\n%s\n", filename);
|
2010-09-26 11:19:15 +02:00
|
|
|
|
2010-09-25 17:46:12 +02:00
|
|
|
#endif
|
2010-09-26 11:19:15 +02:00
|
|
|
|
2018-12-28 23:32:32 +01:00
|
|
|
return (false);
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
void S9xCloseSnapshotFile(STREAM file)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
#ifdef ZLIB
|
2020-07-05 00:53:38 +02:00
|
|
|
CLOSE_STREAM(file);
|
2010-09-25 17:46:12 +02:00
|
|
|
#else
|
2020-07-05 00:53:38 +02:00
|
|
|
pclose(file);
|
2010-09-25 17:46:12 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
void S9xAutoSaveSRAM()
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
Memory.SaveSRAM(S9xGetFilename(".srm", SRAM_DIR));
|
|
|
|
S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
void S9xLoadState(const char *filename)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR));
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
if (S9xUnfreezeGame(filename))
|
2010-09-26 11:19:15 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
sprintf(buf, "%s loaded", filename);
|
|
|
|
S9xSetInfoString(buf);
|
2010-09-26 11:19:15 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
fprintf(stderr, "Failed to load state file: %s\n", filename);
|
2010-09-26 11:19:15 +02:00
|
|
|
}
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
void S9xSaveState(const char *filename)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
if (S9xFreezeGame(filename))
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
sprintf(buf, "%s saved", filename);
|
|
|
|
S9xSetInfoString(buf);
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
fprintf(stderr, "Couldn't save state file: %s\n", filename);
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* QuickSave/Load from S9x base controls.cpp */
|
2020-07-05 00:53:38 +02:00
|
|
|
void S9xQuickSaveSlot(int slot)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
char def[PATH_MAX];
|
|
|
|
char filename[PATH_MAX];
|
|
|
|
char drive[_MAX_DRIVE];
|
|
|
|
char dir[_MAX_DIR];
|
|
|
|
char ext[_MAX_EXT];
|
|
|
|
|
2018-11-06 23:30:50 +01:00
|
|
|
if (!gui_config->rom_loaded)
|
|
|
|
return;
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
_splitpath(Memory.ROMFilename, drive, dir, def, ext);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
snprintf(filename, PATH_MAX, "%s%s%s.%03d",
|
|
|
|
S9xGetDirectory(SNAPSHOT_DIR), SLASH_STR, def,
|
2010-09-25 17:46:12 +02:00
|
|
|
slot);
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
if (S9xFreezeGame(filename))
|
2010-09-26 11:19:15 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
snprintf(buf, PATH_MAX, "%s.%03d saved", def, slot);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
S9xSetInfoString(buf);
|
2010-09-26 11:19:15 +02:00
|
|
|
}
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
void S9xQuickLoadSlot(int slot)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
char def[PATH_MAX];
|
|
|
|
char filename[PATH_MAX];
|
|
|
|
char drive[_MAX_DRIVE];
|
|
|
|
char dir[_MAX_DIR];
|
|
|
|
char ext[_MAX_EXT];
|
|
|
|
|
2018-11-06 23:30:50 +01:00
|
|
|
if (!gui_config->rom_loaded)
|
|
|
|
return;
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
_splitpath(Memory.ROMFilename, drive, dir, def, ext);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
snprintf(filename, PATH_MAX, "%s%s%s.%03d",
|
|
|
|
S9xGetDirectory(SNAPSHOT_DIR), SLASH_STR, def,
|
2010-09-25 17:46:12 +02:00
|
|
|
slot);
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
if (file_exists(filename))
|
|
|
|
S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR));
|
2018-06-21 20:46:29 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
if (S9xUnfreezeGame(filename))
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
snprintf(buf, PATH_MAX, "%s.%03d loaded", def, slot);
|
|
|
|
S9xSetInfoString(buf);
|
2018-06-09 17:23:26 +02:00
|
|
|
return;
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-09 17:23:26 +02:00
|
|
|
static const char *digits = "t123456789";
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
_splitpath(Memory.ROMFilename, drive, dir, def, ext);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
snprintf(filename, PATH_MAX, "%s%s%s.zs%c",
|
|
|
|
S9xGetDirectory(SNAPSHOT_DIR), SLASH_STR,
|
|
|
|
def, digits[slot]);
|
2018-06-09 17:23:26 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
if (file_exists(filename))
|
|
|
|
S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR));
|
2018-06-21 20:46:29 +02:00
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
if (S9xUnfreezeGame(filename))
|
2018-06-09 17:23:26 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
snprintf(buf, PATH_MAX,
|
|
|
|
"Loaded ZSNES freeze file %s.zs%c",
|
|
|
|
def, digits[slot]);
|
|
|
|
S9xSetInfoString(buf);
|
2018-06-09 17:23:26 +02:00
|
|
|
return;
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
S9xMessage(S9X_ERROR,
|
|
|
|
S9X_FREEZE_FILE_NOT_FOUND,
|
|
|
|
"Freeze file not found");
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|