cmd line parsing fixes, non-.smc roms allowed
authorJavier S. Pedro <javier@javispedro.com>
Sun, 23 Aug 2009 18:09:32 +0000 (20:09 +0200)
committerJavier S. Pedro <javier@javispedro.com>
Sun, 23 Aug 2009 18:09:32 +0000 (20:09 +0200)
Added --audio-rate, less usage of PATH_MAX, ability to handle non-smc
ROM files, and removed some cruft.

display.h
memmap.cpp
platform/config.cpp
platform/path.c
platform/platform.h
platform/sdl.cpp
port.h
sdd1.cpp
snapshot.cpp
snes9x.h

index a737e9f..64ee520 100644 (file)
--- a/display.h
+++ b/display.h
@@ -65,22 +65,10 @@ void S9xToggleSoundChannel (int channel);
 void S9xSetInfoString (const char *string);
 int S9xMinCommandLineArgs ();
 void S9xNextController ();
-bool8_32 S9xLoadROMImage (const char *string);
-const char *S9xSelectFilename (const char *def, const char *dir,
-                              const char *ext, const char *title);
 
-const char *S9xChooseFilename (bool8_32 read_only);
 bool8_32 S9xOpenSnapshotFile (const char *base, bool8_32 read_only, STREAM *file);
 void S9xCloseSnapshotFile (STREAM file);
 
-const char *S9xBasename (const char *filename);
-
-int S9xFStrcmp (FILE *, const char *);
-const char *S9xGetHomeDirectory ();
-const char *S9xGetSnapshotDirectory ();
-const char *S9xGetROMDirectory ();
-const char *S9xGetSRAMFilename ();
-const char *S9xGetFilename (const char *extension);
 END_EXTERN_C
 
 #endif
index 7eedcd8..87820d4 100644 (file)
@@ -339,17 +339,8 @@ bool8_32 CMemory::LoadROM (const char *filename)
 
     CalculatedSize = 0;
 again:
-#ifndef _SNESPPC
-    _splitpath (filename, drive, dir, name, ext);
-    _makepath (fname, drive, dir, name, ext);
-#else
-       strcpy(fname, filename);
-//     strupr(fname);
-#endif
-
-#ifdef __WIN32__
-    memmove (&ext [0], &ext[1], 4);
-#endif
+    PathSplit(filename, drive, dir, name, ext);
+    PathMake(fname, drive, dir, name, ext);
 
     int32 TotalFileSize = 0;
 
@@ -393,15 +384,9 @@ again:
            if (ptr - ROM < MAX_ROM_SIZE + 0x200 &&
                (isdigit (ext [0]) && ext [1] == 0 && ext [0] < '9'))
            {
-               more = TRUE;
-               ext [0]++;
-#ifdef __WIN32__
-                memmove (&ext [1], &ext [0], 4);
-                ext [0] = '.';
-#endif
-#ifndef _SNESPPC
-               _makepath (fname, drive, dir, name, ext);
-#endif
+                       more = TRUE;
+                       ext [0]++;
+                       PathMake(fname, drive, dir, name, ext);
                }
            else
            if (ptr - ROM < MAX_ROM_SIZE + 0x200 &&
@@ -410,18 +395,12 @@ again:
                 isdigit (name [2]) && isdigit (name [3]) && isdigit (name [4]) &&
                 isdigit (name [5]) && isalpha (name [len - 1])))
            {
-               more = TRUE;
-               name [len - 1]++;
-#ifdef __WIN32__
-                memmove (&ext [1], &ext [0], 4);
-                ext [0] = '.';
-#endif
-#ifndef _SNESPPC
-               _makepath (fname, drive, dir, name, ext);
-#endif
+                       more = TRUE;
+                       name [len - 1]++;
+                       PathMake(fname, drive, dir, name, ext);
                }
            else
-               more = FALSE;
+                       more = FALSE;
        } while (more && (ROMFile = OPEN_STREAM (fname, "rb")) != NULL);
     }
 
@@ -657,7 +636,7 @@ again:
     FreeSDD1Data ();
     InitROM (Tales);
        
-    S9xLoadCheatFile (S9xGetFilename(".cht"));
+    S9xLoadCheatFile (S9xGetFilename(FILE_CHT));
     S9xInitCheatData ();
     S9xApplyCheats ();
 
@@ -2599,7 +2578,7 @@ void CMemory::CheckForIPSPatch (const char *rom_filename, bool8_32 header,
     FILE  *patch_file  = NULL;
     long  offset = header ? 512 : 0;
 
-    if (!(patch_file = fopen(S9xGetFilename (".ips"), "rb"))) return;
+    if (!(patch_file = fopen(S9xGetFilename(FILE_IPS), "rb"))) return;
 
     if (fread (fname, 1, 5, patch_file) != 5 || strncmp (fname, "PATCH", 5) != 0)
     {
index de0c8ff..34f6d91 100644 (file)
 
 struct config Config;
 
-static const struct poptOption optionsTable[] = {
+/** Path to current rom file, with extension. */
+static char * romFile;
+/** Path to rom file, without extension.
+ *  Used as a simple optimization to S9xGetFilename
+ */
+static char * basePath;
+
+static struct poptOption commonOptionsTable[] = {
        { "disable-audio", 'a', POPT_ARG_NONE, 0, 1,
        "disable emulation and output of audio", 0 },
        { "display-framerate", 'r', POPT_ARG_NONE, 0, 2,
@@ -44,6 +51,12 @@ static const struct poptOption optionsTable[] = {
        "Enable SuperScope", 0},
        { "snapshot", 'o', POPT_ARG_NONE, 0, 13,
        "Unfreeze previous game on start and freeze game on exit", 0 },
+       { "audio-rate", 'u', POPT_ARG_INT, 0, 14,
+       "Audio output rate", "HZ" },
+       POPT_TABLEEND
+};
+
+static struct poptOption configOptionsTable[] = {
        { "scancode", '\0', POPT_ARG_INT, 0, 100,
        "Scancode to map", "CODE" },
        { "button", '\0', POPT_ARG_STRING, 0, 101,
@@ -52,6 +65,14 @@ static const struct poptOption optionsTable[] = {
        "Emulator action to do (fullscreen, quit, ...)", "action" },
        { "hacks-file", '\0', POPT_ARG_STRING, 0, 200,
        "Path to snesadvance.dat file", "FILE" },
+       POPT_TABLEEND
+};
+
+static struct poptOption optionsTable[] = {
+       { 0, '\0', POPT_ARG_INCLUDE_TABLE, commonOptionsTable, 0,
+       "Common options", 0 },
+       { 0, '\0', POPT_ARG_INCLUDE_TABLE, configOptionsTable, 0,
+       "Configuration file options", 0 },
        POPT_AUTOHELP
        POPT_TABLEEND
 };
@@ -96,33 +117,37 @@ static unsigned char actionNameToBit(const char *s) {
        }
 }
 
-const char * S9xFiletitle(const char * f)
-{
-       if (!f) return 0;
-       
-       const char * p = strrchr (f, '.');
-
-       if (p)
-               return p + 1;
-
-       return f;
-}
-
-const char * S9xBasename(const char * f)
-{
-       const char * p = strrchr (f, '/');
-
-       if (p)
-               return p + 1;
-
-       return f;
-}
-
-const char * S9xGetFilename(const char * ext)
+const char * S9xGetFilename(FileTypes file)
 {
        static char filename [PATH_MAX + 1];
-       sprintf(filename, "%s%s", Config.romFile, ext);
+       const char * ext;
+       switch (file) {
+               case FILE_ROM:
+                       return romFile;
+               case FILE_SRAM:
+                       ext = "srm";
+                       break;
+               case FILE_FREEZE:
+                       ext = "frz.gz";
+                       break;
+               case FILE_CHT:
+                       ext = "cht";
+                       break;
+               case FILE_IPS:
+                       ext = "ips";
+                       break;
+               case FILE_SCREENSHOT:
+                       ext = "png";
+                       break;
+               case FILE_SDD1_DAT:
+                       ext = "dat";
+                       break;
+               default:
+                       ext = "???";
+                       break;
+       }
 
+       snprintf(filename, PATH_MAX, "%s.%s", basePath, ext);
        return filename;
 }
 
@@ -131,10 +156,14 @@ static void loadDefaults()
        ZeroMemory(&Settings, sizeof(Settings));
        ZeroMemory(&Config, sizeof(Config)); 
        
+       romFile = 0;
+       basePath = 0;
+
        Config.quitting = false;
        Config.enableAudio = true;
        Config.fullscreen = false;
        Config.xsp = false;
+       Config.hacksFile = 0;
 
        Settings.JoystickEnabled = FALSE;
        Settings.SoundPlaybackRate = 22050;
@@ -167,9 +196,6 @@ static void loadDefaults()
        Settings.ApplyCheats = FALSE;
        Settings.TurboMode = FALSE;
        Settings.TurboSkipFrames = 15;
-       //Settings.ThreadSound = FALSE;
-       //Settings.SoundSync = FALSE;
-       //Settings.NoPatch = true;
     
     Settings.ForcePAL = FALSE;
     Settings.ForceNTSC = FALSE;
@@ -184,15 +210,24 @@ static void loadDefaults()
 
 void S9xSetRomFile(const char * path)
 {
-       char drive[1], dir[PATH_MAX], fname[PATH_MAX], ext[PATH_MAX];
-       
-       _splitpath (path, drive, dir, fname, ext);
-       sprintf(Config.romFile, "%s%s%s", dir, strlen(dir) > 0 ? "/" : "", fname);
+       if (romFile) {
+               free(romFile);
+               free(basePath);
+       }
+
+       romFile = strndup(path, PATH_MAX);
+       basePath = strdup(romFile);
+
+       // Truncate base path at the last '.' char
+       char * c = strrchr(basePath, '.');
+       if (c) {
+               *c = '\0';
+       }
 }
 
 static bool gotRomFile() 
 {
-       return Config.romFile[0] != '\0';
+       return romFile ? true : false;
 }
 
 static void setHacks(const char * value)
@@ -305,6 +340,9 @@ static void parseArgs(poptContext optCon)
                                Config.snapshotLoad = true;
                                Config.snapshotSave = true;
                                break;
+                       case 14:
+                               Settings.SoundPlaybackRate = atoi(poptGetOptArg(optCon));
+                               break;
                        case 100:
                                scancode = atoi(poptGetOptArg(optCon));
                                break;
@@ -317,7 +355,8 @@ static void parseArgs(poptContext optCon)
                                        actionNameToBit(poptGetOptArg(optCon));
                                break;
                        case 200:
-                               strcpy(Config.hacksFile, poptGetOptArg(optCon));
+                               free(Config.hacksFile);
+                               Config.hacksFile = strdup(poptGetOptArg(optCon));
                                break;
                        default:
                                DIE("Invalid popt argument (this is a bug): %d", rc);
@@ -368,3 +407,19 @@ void S9xLoadConfig(int argc, const char ** argv)
        poptFreeContext(optCon);
 }
 
+void S9xUnloadConfig()
+{
+       if (romFile) {
+               free(romFile);
+               romFile = 0;
+       }
+       if (basePath) {
+               free(basePath);
+               basePath = 0;
+       }
+       if (Config.hacksFile) {
+               free(Config.hacksFile);
+               Config.hacksFile = 0;
+       }
+}
+
index ac48064..0adb2fe 100644 (file)
@@ -2,26 +2,23 @@
 
 #include "port.h"
 
-void _makepath (char *path, const char *drive, const char *dir,
+void PathMake(char *path, const char *drive, const char *dir,
        const char *fname, const char *ext)
 {
-       if (dir && *dir)
-       {
+       if (dir && *dir) {
                strcpy (path, dir);
                strcat (path, "/");
+       } else {
+               *path = 0;
        }
-       else
-       *path = 0;
        strcat (path, fname);
-       if (ext && *ext)
-       {
+       if (ext && *ext) {
                strcat (path, ".");
                strcat (path, ext);
        }
 }
 
-void _splitpath (const char *path, char *drive, char *dir, char *fname,
-       char *ext)
+void PathSplit(const char *path, char *drive, char *dir, char *fname, char *ext)
 {
        *drive = 0;
 
@@ -59,4 +56,15 @@ void _splitpath (const char *path, char *drive, char *dir, char *fname,
                else
                        strcpy (ext, "");
        }
-} 
+}
+
+const char * PathBasename(const char * path)
+{
+       const char * p = strrchr (path, '/');
+
+       if (p)
+               return p + 1;
+
+       return path;
+}
+
index 1837dd6..b0d2803 100644 (file)
@@ -1,14 +1,13 @@
-#ifndef _PLATFORM_SDL_H_
-#define _PLATFORM_SDL_H_
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
 
 #include "port.h"
 
 // Configuration and command line parsing
 void S9xLoadConfig(int argc, const char ** argv);
+void S9xUnloadConfig();
 void S9xSetRomFile(const char * file);
 extern struct config {
-       char romFile[PATH_MAX + 1];
-       char hacksFile[PATH_MAX + 1];
        /** Unfreeze from .frz.gz snapshot on start */
        bool snapshotLoad;
        /** Freeze to .frz.gz on exit */
@@ -19,8 +18,12 @@ extern struct config {
        bool xsp;
        /** Audio output enabled */
        bool enableAudio;
+       /** Speedhacks file to use */
+       char * hacksFile;
+       /** Current scancode->joypad mapping */
        unsigned short joypad1Mapping[256];
        unsigned char action[256];
+       /** If true, next time the main loop is entered application will close */
        bool quitting;
 } Config;
 
@@ -40,7 +43,4 @@ void S9xAudioOutputEnable(bool enable);
 
 void S9xDoAction(unsigned char action);
 
-// Path things
-const char * S9xFiletitle (const char * f);
-
 #endif
index 9790da8..0978504 100644 (file)
@@ -15,7 +15,7 @@
 #include "hgw.h"
 
 #define kPollEveryNFrames              5               //Poll input only every this many frames
-#define kPollHgwEveryNFrames   10              //Poll osso only every this many frames
+#define kPollHgwEveryNFrames   10              //Poll dbus only every this many frames
 
 #define TRACE printf("trace: %s:%s\n", __FILE__, __func__);
 #define DIE(format, ...) do { \
@@ -36,7 +36,7 @@ void S9xLoadSDD1Data()
 
 void S9xAutoSaveSRAM()
 {
-       Memory.SaveSRAM(S9xGetFilename(".srm"));
+       Memory.SaveSRAM(S9xGetFilename(FILE_SRAM));
 }
 
 static void S9xInit() 
@@ -59,14 +59,14 @@ static void S9xInit()
 
 static void loadRom()
 {
-       const char * file = S9xGetFilename(".smc");
+       const char * file = S9xGetFilename(FILE_ROM);
 
        printf("ROM: %s\n", file);
 
        if (!Memory.LoadROM(file))
                DIE("Loading ROM failed");
        
-       file = S9xGetFilename(".srm");
+       file = S9xGetFilename(FILE_SRAM);
        printf("SRAM: %s\n", file);
        Memory.LoadSRAM(file); 
 }
@@ -75,7 +75,7 @@ static void resumeGame()
 {
        if (!Config.snapshotLoad) return;
 
-       const char * file = S9xGetFilename(".frz.gz");
+       const char * file = S9xGetFilename(FILE_FREEZE);
        int result = S9xUnfreezeGame(file);
 
        printf("Unfreeze: %s", file);
@@ -103,7 +103,7 @@ static void pauseGame()
 {
        if (!Config.snapshotSave) return;
 
-       const char * file = S9xGetFilename(".frz.gz");
+       const char * file = S9xGetFilename(FILE_FREEZE);
        int result = S9xFreezeGame(file);
 
        printf("Freeze: %s", file);
@@ -235,23 +235,23 @@ int main(int argc, const char ** argv) {
        // Initialise SDL
        if (SDL_Init(0) < 0) 
                DIE("SDL_Init: %s", SDL_GetError());
-       
+
        // Configure snes9x
        HgwInit();                                              // Hildon-games-wrapper initialization.
        S9xLoadConfig(argc, argv);              // Load config files and parse cmd line.
        HgwConfig();                                    // Apply specific hildon-games config.
-       
+
        // S9x initialization
        S9xInitDisplay(argc, argv);
        S9xInitAudioOutput();
        S9xInitInputDevices();
        S9xInit();
        S9xReset();
-       
+
        // Load rom and related files: state, unfreeze if needed
        loadRom();
        resumeGame();
-       
+
        // Late initialization
        sprintf(String, "DrNokSnes - %s", Memory.ROMName);
        S9xSetTitle(String);
@@ -273,12 +273,13 @@ int main(int argc, const char ** argv) {
        S9xDeinitDisplay();
 
        // Save state
-       Memory.SaveSRAM(S9xGetFilename(".srm"));
+       Memory.SaveSRAM(S9xGetFilename(FILE_SRAM));
        pauseGame();
 
        // Late deinitialization
        S9xGraphicsDeinit();
        Memory.Deinit();
+       S9xUnloadConfig();
        HgwDeinit();
 
        SDL_Quit();
@@ -290,7 +291,7 @@ void S9xDoAction(unsigned char action)
 {
        if (action & kActionQuit) 
                Config.quitting = true;
-               
+
        if (action & kActionToggleFullscreen)
                S9xVideoToggleFullscreen();
 }
diff --git a/port.h b/port.h
index e10cc8a..14c2ab3 100644 (file)
--- a/port.h
+++ b/port.h
@@ -82,22 +82,22 @@ typedef int8_t                      int8_32;
 typedef int16_t                        int16_32;
 
 //Defines for Extern C
-#define EXTERN_C extern "C"
 #ifdef __cplusplus
+#define EXTERN_C extern "C"
 #define START_EXTERN_C EXTERN_C {
 #define END_EXTERN_C }
 #else
+#define EXTERN_C extern
 #define START_EXTERN_C
 #define END_EXTERN_C
 #endif
 
 //Path Defines
-#undef  _MAX_PATH
 #define _MAX_DIR PATH_MAX
 #define _MAX_DRIVE 1
-#define _MAX_FNAME PATH_MAX
-#define _MAX_EXT PATH_MAX
-#define _MAX_PATH (PATH_MAX)
+#define _MAX_FNAME NAME_MAX
+#define _MAX_EXT NAME_MAX
+#define _MAX_PATH PATH_MAX
 
 //True/False Defines
 #define TRUE 1
@@ -128,14 +128,12 @@ typedef int16_t                   int16_32;
 #endif
 
 START_EXTERN_C
-
-void S9xGenerateSound ();
-
-void _makepath (char *path, const char *drive, const char *dir,
-               const char *fname, const char *ext);
-void _splitpath (const char *path, char *drive, char *dir, char *fname,
-                char *ext);
-
+// Path functions
+void PathMake(char *path, const char *drive, const char *dir,
+       const char *fname, const char *ext);
+void PathSplit(const char *path, char *drive, char *dir, char *fname, char *ext);
+/** A simplified basename function returning a pointer inside the same string */
+const char * PathBasename(const char * path);
 END_EXTERN_C
 
 #endif
index 3baae1b..e8f5afb 100644 (file)
--- a/sdd1.cpp
+++ b/sdd1.cpp
@@ -102,7 +102,8 @@ void S9xSDD1SaveLoggedData ()
        qsort (Memory.SDD1LoggedData, Memory.SDD1LoggedDataCount, 8,
               S9xCompareSDD1LoggedDataEntries);
 
-       FILE *fs = fopen (S9xGetFilename (".dat"), "wb");
+       const char * sdd1_dat_file = S9xGetFilename(FILE_SDD1_DAT);
+       FILE *fs = fopen (sdd1_dat_file, "wb");
 
        if (fs)
        {
@@ -110,7 +111,7 @@ void S9xSDD1SaveLoggedData ()
                    Memory.SDD1LoggedDataCount, fs);
            fclose (fs);
 #if defined(__linux)
-           chown (S9xGetFilename (".dat"), getuid (), getgid ());
+           chown (sdd1_dat_file, getuid (), getgid ());
 #endif
        }
        Memory.SDD1LoggedDataCountPrev = Memory.SDD1LoggedDataCount;
@@ -119,7 +120,7 @@ void S9xSDD1SaveLoggedData ()
 
 void S9xSDD1LoadLoggedData ()
 {
-    FILE *fs = fopen (S9xGetFilename (".dat"), "rb");
+    FILE *fs = fopen (S9xGetFilename(FILE_SDD1_DAT), "rb");
 
     Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = 0;
 
index 46ab45d..14229bd 100644 (file)
@@ -563,7 +563,7 @@ static int Unfreeze()
        }
        
     if (strcasecmp (rom_filename, Memory.ROMFilename) != 0 &&
-       strcasecmp (S9xBasename (rom_filename), S9xBasename (Memory.ROMFilename)) != 0)
+       strcasecmp (PathBasename(rom_filename), PathBasename(Memory.ROMFilename)) != 0)
     {
                S9xMessage (S9X_WARNING, S9X_FREEZE_ROM_NAME,
                    "Current loaded ROM image doesn't match that required by freeze-game file.");
index cafa119..3e4482e 100644 (file)
--- a/snes9x.h
+++ b/snes9x.h
@@ -383,6 +383,7 @@ void S9xMessage (int type, int number, const char *message);
 void S9xLoadSDD1Data ();
 END_EXTERN_C
 
+START_EXTERN_C
 enum {
     PAUSE_NETPLAY_CONNECT = (1 << 0),
     PAUSE_TOGGLE_FULL_SCREEN = (1 << 1),
@@ -395,5 +396,26 @@ enum {
 };
 void S9xSetPause (uint32 mask);
 void S9xClearPause (uint32 mask);
+END_EXTERN_C
+
+START_EXTERN_C
+enum FileTypes {
+       FILE_ROM = 0,
+       FILE_SRAM,
+       /** The default freeze filename (base.frz.gz) */
+       FILE_FREEZE,
+       FILE_CHT,
+       FILE_IPS,
+       FILE_SCREENSHOT,
+       FILE_SDD1_DAT
+};
+/** This routine allows to get path to files whose name depends on the basename
+ *  of the current ROM.
+ *  Note that FILE_FREEZE is currently not implemented here.
+ *  @param file see enum FileTypes.
+ *  @return wanted filepath. Do not free the returned string.
+ */
+const char *S9xGetFilename(enum FileTypes file);
+END_EXTERN_C
 
 #endif