quick save slots
authorJavier S. Pedro <maemo@javispedro.com>
Thu, 10 Sep 2009 23:27:00 +0000 (01:27 +0200)
committerJavier S. Pedro <maemo@javispedro.com>
Thu, 10 Sep 2009 23:27:00 +0000 (01:27 +0200)
display.h
gfx.cpp
gfx.h
gui/controls.c
platform/config.cpp
platform/hgw.cpp
platform/platform.h
platform/sdl.cpp
snes9x.h

index 64ee520..5d25932 100644 (file)
--- a/display.h
+++ b/display.h
@@ -62,7 +62,7 @@ void S9xProcessEvents (bool8_32 block);
 void S9xPutImage (int width, int height);
 void S9xParseDisplayArg (char **argv, int &index, int argc);
 void S9xToggleSoundChannel (int channel);
-void S9xSetInfoString (const char *string);
+void S9xSetInfoString (const char * fmt, ...);
 int S9xMinCommandLineArgs ();
 void S9xNextController ();
 
diff --git a/gfx.cpp b/gfx.cpp
index a22ce72..a357d09 100644 (file)
--- a/gfx.cpp
+++ b/gfx.cpp
@@ -38,6 +38,9 @@
  * Super NES and Super Nintendo Entertainment System are trademarks of
  * Nintendo Co., Limited and its subsidiary companies.
  */
+
+#include <stdarg.h>
+
 #include "snes9x.h"
 
 #include "memmap.h"
@@ -430,8 +433,10 @@ void S9xBuildDirectColourMaps ()
 
 void S9xStartScreenRefresh ()
 {
-    if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0)
-       GFX.InfoString = NULL;
+       if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0) {
+               free(GFX.InfoString);
+               GFX.InfoString = NULL;
+       }
 
     if (IPPU.RenderThisFrame)
     {
@@ -591,10 +596,19 @@ void S9xEndScreenRefresh()
     }
 }
 
-void S9xSetInfoString (const char *string)
+void S9xSetInfoString (const char * fmt, ...)
 {
-    GFX.InfoString = string;
-    GFX.InfoStringTimeout = 120;
+       va_list ap;
+       va_start(ap, fmt);
+
+       if (vasprintf(&GFX.InfoString, fmt, ap) > 0) {
+               GFX.InfoStringTimeout = 120;
+       } else {
+               GFX.InfoString = 0;
+               GFX.InfoStringTimeout = 0;
+       }
+
+    va_end(ap);
 }
 
 INLINE void SelectTileRenderer (bool8_32 normal)
diff --git a/gfx.h b/gfx.h
index 279fec8..281f418 100644 (file)
--- a/gfx.h
+++ b/gfx.h
@@ -69,7 +69,7 @@ struct SGFX{
     uint8  Z1;
     uint8  Z2;
     uint32 FixedColour;
-    const char *InfoString;
+    char *InfoString;
     uint32 InfoStringTimeout;
     uint32 StartY;
     uint32 EndY;
index ae147b1..f46d7f3 100644 (file)
@@ -50,8 +50,12 @@ typedef struct ButtonEntry {
 } ButtonEntry;
 #define BUTTON_INITIALIZER(desc, name, default) \
        { desc, kGConfKeysPath "/" name, 0, default }
+
+#define ACTION_INITIALIZER(...) BUTTON_INITIALIZER(__VA_ARGS__)
+
 #define BUTTON_LAST    \
        { 0 }
+
 static ButtonEntry buttons[] = {
        BUTTON_INITIALIZER("A", "a", 48),
        BUTTON_INITIALIZER("B", "b", 20),
@@ -65,8 +69,12 @@ static ButtonEntry buttons[] = {
        BUTTON_INITIALIZER("Down", "down", 116),
        BUTTON_INITIALIZER("Left", "left", 113),
        BUTTON_INITIALIZER("Right", "right", 114),
-       BUTTON_INITIALIZER("Return to launcher", "quit", 9),
-       BUTTON_INITIALIZER("Fullscreen", "fullscreen", 72),
+       ACTION_INITIALIZER("Return to launcher", "quit", 9),
+       ACTION_INITIALIZER("Fullscreen", "fullscreen", 72),
+       ACTION_INITIALIZER("Quick Load 1", "quickload1", 0),
+       ACTION_INITIALIZER("Quick Save 1", "quicksave1", 0),
+       ACTION_INITIALIZER("Quick Load 2", "quickload2", 0),
+       ACTION_INITIALIZER("Quick Save 2", "quicksave2", 0),
        BUTTON_LAST
 };
 
@@ -220,21 +228,35 @@ static void cb_dialog_response(GtkWidget * button, gpointer data)
 void controls_setup()
 {
        GConfValue* mapping = gconf_client_get(gcc, kGConfMapping, NULL);
+       int i;
 
        if (!mapping) {
                // Key not set; setup defaults
-               int i;
                for (i = 0; buttons[i].name; i++) {
-                       gconf_client_set_int(gcc,
-                               buttons[i].gconf_key, buttons[i].default_scancode, NULL);
+                       gconf_client_set_int(gcc, buttons[i].gconf_key,
+                               buttons[i].default_scancode, NULL);
                }
 
                g_debug("Loading default key mappings\n");
 
                gconf_client_set_int(gcc, kGConfMapping, 1, NULL);
        } else {
-               // If this is set, consider defaults loaded.
+               // If this key is set, consider defaults loaded.
                gconf_value_free(mapping);
+
+               // We still have to check if all the keys exist
+               gconf_client_preload(gcc, kGConfKeysPath, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+               for (i = 0; buttons[i].name; i++) {
+                       mapping = gconf_client_get(gcc, buttons[i].gconf_key, NULL);
+
+                       if (!mapping) {
+                               // Not set; set to default.
+                               gconf_client_set_int(gcc, buttons[i].gconf_key,
+                                       buttons[i].default_scancode, NULL);
+                       } else {
+                               gconf_value_free(mapping);
+                       }
+               }
        }
 }
 
index 151feee..db04ae0 100644 (file)
@@ -116,6 +116,14 @@ static unsigned char actionNameToBit(const char *s) {
                return kActionQuit;
        } else if (strcasecmp(s, "fullscreen") == 0) {
                return kActionToggleFullscreen;
+       } else if (strcasecmp(s, "quickload1") == 0) {
+               return kActionQuickLoad1;
+       } else if (strcasecmp(s, "quicksave1") == 0) {
+               return kActionQuickSave1;
+       } else if (strcasecmp(s, "quickload2") == 0) {
+               return kActionQuickLoad2;
+       } else if (strcasecmp(s, "quicksave2") == 0) {
+               return kActionQuickSave2;
        } else {
                DIE("Bad action name: %s\n", s);
        }
@@ -123,7 +131,7 @@ static unsigned char actionNameToBit(const char *s) {
 
 const char * S9xGetFilename(FileTypes file)
 {
-       static char filename [PATH_MAX + 1];
+       static char filename[PATH_MAX + 1];
        const char * ext;
        switch (file) {
                case FILE_ROM:
@@ -155,6 +163,13 @@ const char * S9xGetFilename(FileTypes file)
        return filename;
 }
 
+const char * S9xGetQuickSaveFilename(unsigned int slot)
+{
+       static char filename[PATH_MAX + 1];
+       snprintf(filename, PATH_MAX, "%s.frz.%u.gz", basePath, slot);
+       return filename;
+}
+
 static void loadDefaults()
 {
        ZeroMemory(&Settings, sizeof(Settings));
index 18e6ca7..a690176 100644 (file)
@@ -225,6 +225,10 @@ static const ButtonEntry buttons[] = {
        BUTTON_INITIALIZER(RIGHT, "right"),
        ACTION_INITIALIZER(Quit, "quit"),
        ACTION_INITIALIZER(ToggleFullscreen, "fullscreen"),
+       ACTION_INITIALIZER(QuickLoad1, "quickload1"),
+       ACTION_INITIALIZER(QuickSave1, "quicksave1"),
+       ACTION_INITIALIZER(QuickLoad2, "quickload2"),
+       ACTION_INITIALIZER(QuickSave2, "quicksave2"),
        BUTTON_LAST
 };
 
index 2a7e805..d47f187 100644 (file)
@@ -53,6 +53,10 @@ void S9xInputScreenChanged();
 #define kActionNone                                            0
 #define kActionQuit                                    (1U << 0)
 #define        kActionToggleFullscreen         (1U << 1)
+#define kActionQuickLoad1                      (1U << 2)
+#define kActionQuickSave1                      (1U << 3)
+#define kActionQuickLoad2                      (1U << 4)
+#define kActionQuickSave2                      (1U << 5)
 
 void S9xDoAction(unsigned char action);
 
index b78b48e..375519f 100644 (file)
@@ -269,5 +269,33 @@ void S9xDoAction(unsigned char action)
                S9xVideoToggleFullscreen();
                S9xInputScreenChanged();
        }
+
+       if (action & kActionQuickLoad1) {
+               const char * file = S9xGetQuickSaveFilename(1);
+               int result = S9xUnfreezeGame(file);
+               S9xSetInfoString("Load slot %u: %s", 1,
+                       (result ? "done" : "failed"));
+       }
+
+       if (action & kActionQuickSave1) {
+               const char * file = S9xGetQuickSaveFilename(1);
+               int result = S9xFreezeGame(file);
+               S9xSetInfoString("Save slot %u: %s", 1,
+                       (result ? "done" : "failed"));
+       }
+
+       if (action & kActionQuickLoad2) {
+               const char * file = S9xGetQuickSaveFilename(2);
+               int result = S9xUnfreezeGame(file);
+               S9xSetInfoString("Load slot %u: %s", 2,
+                       (result ? "done" : "failed"));
+       }
+
+       if (action & kActionQuickSave2) {
+               const char * file = S9xGetQuickSaveFilename(2);
+               int result = S9xFreezeGame(file);
+               S9xSetInfoString("Save slot %u: %s", 2,
+                       (result ? "done" : "failed"));
+       }
 }
 
index 6b9dd04..86e21b9 100644 (file)
--- a/snes9x.h
+++ b/snes9x.h
@@ -403,11 +403,15 @@ enum FileTypes {
 };
 /** 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);
+/** Returns the path to freeze file for the selected quick save slot.
+ *  @param slot slot number
+ *  @return wanted filepath. Do not free the returned string.
+ */
+const char *S9xGetQuickSaveFilename(unsigned int slot);
 END_EXTERN_C
 
 #endif