snes9x/gtk/src/gtk_file.cpp

562 lines
12 KiB
C++
Raw Normal View History

2010-09-25 17:46:12 +02:00
#include <sys/stat.h>
#include <gtk/gtk.h>
2010-09-26 11:19:15 +02:00
#include <errno.h>
2010-09-25 17:46:12 +02:00
#include "gtk_s9x.h"
2018-05-14 03:17:02 +02:00
static char buf[PATH_MAX];
2010-09-25 17:46:12 +02:00
const char *
S9xChooseMovieFilename (bool8 read_only)
{
if (!gui_config->rom_loaded)
return strdup ("");
return top_level->open_movie_dialog (read_only);
}
const char *
S9xChooseFilename (bool8 read_only)
{
return strdup ("");
}
/* _splitpath/_makepath: Modified from unix.cpp. See file for credits. */
#ifndef SLASH_CHAR
#define SLASH_CHAR '/'
#endif
void
_splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
{
char *slash = strrchr ((char *) path, SLASH_CHAR);
char *dot = strrchr ((char *) path, '.');
*drive = '\0';
if (dot && slash && dot < slash)
{
dot = 0;
}
if (!slash)
{
*dir = '\0';
strcpy (fname, path);
if (dot)
{
fname[dot - path] = '\0';
strcpy (ext, dot + 1);
}
else
{
*ext = '\0';
}
}
else
{
strcpy (dir, path);
dir[slash - path] = '\0';
strcpy (fname, slash + 1);
if (dot)
{
fname[(dot - slash) - 1] = '\0';
strcpy (ext, dot + 1);
}
else
{
*ext = '\0';
}
}
return;
}
void
_makepath (char *path,
const char *drive,
const char *dir,
const char *fname,
const char *ext)
{
if (dir && *dir)
{
strcpy (path, dir);
strcat (path, "/");
}
else
*path = '\0';
strcat (path, fname);
if (ext && *ext)
{
strcat (path, ".");
strcat (path, ext);
}
return;
}
const char *
S9xGetFilenameInc (const char *e, enum s9x_getdirtype dirtype)
{
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];
unsigned int i = 0;
struct stat buf;
const char *d;
_splitpath (Memory.ROMFilename, drive, dir, fname, ext);
d = S9xGetDirectory (dirtype);
do
{
snprintf (filename, sizeof (filename),
"%s" SLASH_STR "%s%03d%s", d, fname, i, e);
i++;
}
while (stat (filename, &buf) == 0 && i != 0); /* Overflow? ...riiight :-) */
return (filename);
}
const char *
S9xGetDirectory (enum s9x_getdirtype dirtype)
{
static char path[PATH_MAX + 1];
2018-05-13 18:02:52 +02:00
char *config_dir;
2010-09-25 17:46:12 +02:00
switch (dirtype)
{
case HOME_DIR:
2018-05-13 18:02:52 +02:00
config_dir = get_config_dir ();
strcpy (path, config_dir);
free (config_dir);
2010-09-25 17:46:12 +02:00
break;
case SNAPSHOT_DIR:
2010-09-26 11:19:15 +02:00
sprintf (path, "%s", gui_config->savestate_directory);
2010-09-25 17:46:12 +02:00
break;
case PATCH_DIR:
2010-09-26 11:19:15 +02:00
sprintf (path, "%s", gui_config->patch_directory);
break;
2010-09-25 17:46:12 +02:00
case CHEAT_DIR:
2010-09-26 11:19:15 +02:00
sprintf (path, "%s", gui_config->cheat_directory);
break;
2010-09-25 17:46:12 +02:00
case SRAM_DIR:
2010-09-26 11:19:15 +02:00
sprintf (path, "%s", gui_config->sram_directory);
break;
2010-09-25 17:46:12 +02:00
2010-09-26 11:19:15 +02:00
case SCREENSHOT_DIR:
case SPC_DIR:
sprintf (path, "%s", gui_config->export_directory);
break;
2010-09-25 17:46:12 +02:00
2010-09-26 11:19:15 +02:00
default:
path[0] = '\0';
}
2010-09-25 17:46:12 +02:00
2010-09-26 11:19:15 +02:00
/* Try and mkdir, whether it exists or not */
if (dirtype != HOME_DIR && path[0] != '\0')
{
mkdir (path, 0755);
chmod (path, 0755);
}
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
2010-09-26 11:19:15 +02:00
strcpy (path, Memory.ROMFilename);
2010-09-25 17:46:12 +02:00
2010-09-26 11:19:15 +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)
{
if (getcwd (path, PATH_MAX + 1) == NULL)
{
strcpy (path, getenv ("HOME"));
}
}
else
{
path[loc - path] = '\0';
}
2010-09-25 17:46:12 +02:00
}
return path;
}
const char *
S9xGetFilename (const char *ex, enum s9x_getdirtype dirtype)
{
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];
_splitpath (Memory.ROMFilename, drive, dir, fname, ext);
snprintf (filename, sizeof (filename), "%s" SLASH_STR "%s%s",
S9xGetDirectory (dirtype), fname, ex);
return (filename);
}
const char *
S9xBasename (const char *f)
{
const char *p;
if ((p = strrchr (f, '/')) != NULL || (p = strrchr (f, '\\')) != NULL)
return (p + 1);
return f;
}
const char *
S9xBasenameNoExt (const char *f)
{
static char filename[PATH_MAX + 1];
const char *base, *ext;
if (!(base = strrchr (f, SLASH_CHAR)))
base = f;
else
base += 1;
ext = strrchr (f, '.');
if (!ext)
strncpy (filename, base, PATH_MAX);
else
{
int len = ext - base;
strncpy (filename, base, len);
filename[len] = '\0';
}
return filename;
}
static int
file_exists (const char *name)
{
FILE *f = NULL;
f = fopen (name, "r");
if (!f)
return 0;
else
{
fclose (f);
return 1;
}
}
bool8
S9xOpenSnapshotFile (const char *fname, bool8 read_only, STREAM *file)
{
char filename [PATH_MAX + 1];
char drive [_MAX_DRIVE + 1];
char dir [_MAX_DIR + 1];
char ext [_MAX_EXT + 1];
_splitpath (fname, drive, dir, filename, ext);
if (*drive || *dir == '/' || (*dir == '.' && (*(dir + 1) == '/')))
{
strncpy (filename, fname, PATH_MAX);
if (!file_exists (filename))
{
if (!*ext)
strcat (filename, ".s9x");
}
}
else
{
strcpy (filename, S9xGetDirectory (SNAPSHOT_DIR));
strcat (filename, SLASH_STR);
strcat (filename, fname);
if (!file_exists (filename))
{
if (!*ext)
strcat (filename, ".s9x");
}
}
#ifdef ZLIB
if (read_only)
{
if ((*file = OPEN_STREAM (filename, "rb")))
return (TRUE);
2010-09-26 11:19:15 +02:00
else
fprintf (stderr,
"Failed to open file stream for reading. (%s)\n",
zError (errno));
2010-09-25 17:46:12 +02:00
}
else
{
if ((*file = OPEN_STREAM (filename, "wb")))
{
2012-04-23 08:40:35 +02:00
return (TRUE);
2010-09-25 17:46:12 +02:00
}
2010-09-26 11:19:15 +02:00
else
{
fprintf (stderr,
"Couldn't open stream with zlib. (%s)\n",
zError (errno));
}
2010-09-25 17:46:12 +02:00
}
2010-09-26 11:19:15 +02:00
fprintf (stderr, "zlib: Couldn't open snapshot file:\n%s\n", filename);
2010-09-25 17:46:12 +02:00
#else
char command [PATH_MAX];
if (read_only)
{
sprintf (command, "gzip -d <\"%s\"", filename);
if (*file = popen (command, "r"))
return (TRUE);
}
else
{
sprintf (command, "gzip --best >\"%s\"", filename);
if (*file = popen (command, "wb"))
return (TRUE);
}
2010-09-26 11:19:15 +02:00
fprintf (stderr, "gzip: Couldn't open snapshot file:\n%s\n", filename);
2010-09-25 17:46:12 +02:00
#endif
2010-09-26 11:19:15 +02:00
2010-09-25 17:46:12 +02:00
return (FALSE);
}
void S9xCloseSnapshotFile (STREAM file)
{
#ifdef ZLIB
CLOSE_STREAM (file);
#else
pclose (file);
#endif
}
extern "C"
{
uint8 snes9x_clear_change_log = 0;
}
extern "C" char *osd_GetPackDir (void)
{
return NULL;
}
void
S9xLoadSDD1Data (void)
{
return;
}
void
S9xAutoSaveSRAM (void)
{
Memory.SaveSRAM (S9xGetFilename (".srm", SRAM_DIR));
S9xSaveCheatFile (S9xGetFilename (".bml", CHEAT_DIR));
2010-09-25 17:46:12 +02:00
return;
}
void
S9xLoadState (const char *filename)
{
if (S9xUnfreezeGame (filename))
{
sprintf (buf, "%s loaded", filename);
S9xSetInfoString (buf);
}
else
{
2010-09-26 11:19:15 +02:00
fprintf (stderr, "Failed to load state file: %s\n", filename);
2010-09-25 17:46:12 +02:00
}
return;
}
void
S9xSaveState (const char *filename)
{
2010-09-26 11:19:15 +02:00
if (S9xFreezeGame (filename))
{
sprintf (buf, "%s saved", filename);
S9xSetInfoString (buf);
}
else
{
fprintf (stderr, "Couldn't save state file: %s\n", filename);
}
2010-09-25 17:46:12 +02:00
return;
}
char *
S9xOpenROMDialog (void)
{
GtkWidget *dialog;
GtkFileFilter *filter;
char *filename = NULL;
gint result;
const char *extensions[] =
{
"*.smc", "*.SMC", "*.fig", "*.FIG", "*.sfc", "*.SFC",
"*.jma", "*.JMA", "*.zip", "*.ZIP", "*.gd3", "*.GD3",
2016-11-08 18:51:00 +01:00
"*.swc", "*.SWC", "*.gz" , "*.GZ", "*.bs", "*.BS",
2010-09-25 17:46:12 +02:00
NULL
};
top_level->pause_from_focus_change ();
dialog = gtk_file_chooser_dialog_new ("Open SNES ROM Image",
top_level->get_window (),
GTK_FILE_CHOOSER_ACTION_OPEN,
2017-12-07 03:30:27 +01:00
"gtk-cancel", GTK_RESPONSE_CANCEL,
"gtk-open", GTK_RESPONSE_ACCEPT,
2010-09-25 17:46:12 +02:00
NULL);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, "SNES ROM Images");
for (int i = 0; extensions[i]; i++)
{
gtk_file_filter_add_pattern (filter, extensions[i]);
}
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, "All Files");
gtk_file_filter_add_pattern (filter, "*.*");
gtk_file_filter_add_pattern (filter, "*");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
if (strcmp (gui_config->last_directory, ""))
{
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
gui_config->last_directory);
}
result = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_hide (dialog);
2010-09-25 17:46:12 +02:00
if (result == GTK_RESPONSE_ACCEPT)
{
char *directory;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
directory =
gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
2014-02-10 23:28:05 +01:00
if (directory)
{
strncpy (gui_config->last_directory, directory, PATH_MAX);
g_free (directory);
}
2010-09-25 17:46:12 +02:00
}
else
{
filename = NULL;
}
gtk_widget_destroy (dialog);
top_level->unpause_from_focus_change ();
return filename;
}
/* QuickSave/Load from S9x base controls.cpp */
void
S9xQuickSaveSlot (int slot)
{
char def[PATH_MAX];
char filename[PATH_MAX];
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char ext[_MAX_EXT];
_splitpath (Memory.ROMFilename, drive, dir, def, ext);
2018-05-14 03:17:02 +02:00
snprintf (filename, PATH_MAX, "%s%s%s.%03d",
2010-09-25 17:46:12 +02:00
S9xGetDirectory (SNAPSHOT_DIR), SLASH_STR, def,
slot);
2010-09-26 11:19:15 +02:00
if (S9xFreezeGame (filename))
{
2018-05-14 03:17:02 +02:00
snprintf (buf, PATH_MAX, "%s.%03d saved", def, slot);
2010-09-25 17:46:12 +02:00
2010-09-26 11:19:15 +02:00
S9xSetInfoString (buf);
}
2010-09-25 17:46:12 +02:00
return;
}
void
S9xQuickLoadSlot (int slot)
{
char def[PATH_MAX];
char filename[PATH_MAX];
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char ext[_MAX_EXT];
_splitpath (Memory.ROMFilename, drive, dir, def, ext);
2018-05-14 03:17:02 +02:00
snprintf (filename, PATH_MAX, "%s%s%s.%03d",
2010-09-25 17:46:12 +02:00
S9xGetDirectory (SNAPSHOT_DIR), SLASH_STR, def,
slot);
if (S9xUnfreezeGame (filename))
{
2018-05-14 03:17:02 +02:00
snprintf (buf, PATH_MAX, "%s.%03d loaded", def, slot);
2010-09-25 17:46:12 +02:00
S9xSetInfoString (buf);
}
else
{
static const char *digits = "t123456789";
_splitpath (Memory.ROMFilename, drive, dir, def, ext);
2018-05-14 03:17:02 +02:00
snprintf (filename, PATH_MAX, "%s%s%s.zs%c",
2010-09-25 17:46:12 +02:00
S9xGetDirectory (SNAPSHOT_DIR), SLASH_STR,
def, digits[slot]);
if (S9xUnfreezeGame (filename))
{
2018-05-14 03:17:02 +02:00
snprintf (buf, PATH_MAX,
2010-09-25 17:46:12 +02:00
"Loaded ZSNES freeze file %s.zs%c",
def, digits [slot]);
S9xSetInfoString (buf);
}
else
S9xMessage (S9X_ERROR,
S9X_FREEZE_FILE_NOT_FOUND,
"Freeze file not found");
}
return;
}