initial Caanoo port
[gpsp.git] / gui.c
diff --git a/gui.c b/gui.c
index f03aa49..b28392d 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -16,6 +16,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "common.h"
+#include "font.h"
+
 #ifndef _WIN32_WCE
 
 #include <sys/stat.h>
 #ifndef _WIN32_WCE
 
 #include <sys/stat.h>
 
 #endif
 
 
 #endif
 
-#ifndef GP2X_BUILD
-#include "gp2x/cpuctrl.h"
-#endif
-
-#include "common.h"
-#include "font.h"
-
 #define MAX_PATH 1024
 
 // Blatantly stolen and trimmed from MZX (megazeux.sourceforge.net)
 
 #ifdef GP2X_BUILD
 
 #define MAX_PATH 1024
 
 // Blatantly stolen and trimmed from MZX (megazeux.sourceforge.net)
 
 #ifdef GP2X_BUILD
 
-#define FILE_LIST_ROWS ((int)((SDL_SCREEN_HEIGHT - 40) / FONT_HEIGHT))
+#define FILE_LIST_ROWS 20
 #define FILE_LIST_POSITION 5
 #define DIR_LIST_POSITION 260
 
 #define FILE_LIST_POSITION 5
 #define DIR_LIST_POSITION 260
 
 
 #define FILE_LIST_ROWS 25
 #define FILE_LIST_POSITION 5
 
 #define FILE_LIST_ROWS 25
 #define FILE_LIST_POSITION 5
-#define DIR_LIST_POSITION 360
+#define DIR_LIST_POSITION (resolution_width * 3 / 4)
 
 #endif
 
 #ifdef PSP_BUILD
 
 
 #endif
 
 #ifdef PSP_BUILD
 
+#define COLOR_BG            color16(2, 8, 10)
+
 #define color16(red, green, blue)                                             \
   (blue << 11) | (green << 5) | red                                           \
 
 #else
 
 #define color16(red, green, blue)                                             \
   (blue << 11) | (green << 5) | red                                           \
 
 #else
 
-#define color16(red, green, blue)                                             \
-  (red << 11) | (green << 5) | blue                                           \
-
-#endif
-
-#ifdef GP2X_BUILD
-
 #define COLOR_BG            color16(0, 0, 0)
 
 #define COLOR_BG            color16(0, 0, 0)
 
-#else
-
-#define COLOR_BG            color16(2, 8, 10)
+#define color16(red, green, blue)                                             \
+  (red << 11) | (green << 5) | blue                                           \
 
 #endif
 
 
 #endif
 
 #define COLOR_HELP_TEXT     color16(16, 40, 24)
 
 #ifdef PSP_BUILD
 #define COLOR_HELP_TEXT     color16(16, 40, 24)
 
 #ifdef PSP_BUILD
-  #define get_clock_speed() \
+  static const char *clock_speed_options[] =
+  {
+    "33MHz", "66MHz", "100MHz", "133MHz", "166MHz", "200MHz", "233MHz",
+    "266MHz", "300MHz", "333MHz"
+  };
+  #define menu_get_clock_speed() \
     clock_speed = (clock_speed_number + 1) * 33
   #define get_clock_speed_number() \
     clock_speed_number = (clock_speed / 33) - 1
     clock_speed = (clock_speed_number + 1) * 33
   #define get_clock_speed_number() \
     clock_speed_number = (clock_speed / 33) - 1
-#elif defined(WIZ_BUILD)
-  #define get_clock_speed() \
+#elif defined(POLLUX_BUILD)
+  static const char *clock_speed_options[] =
+  {
+    "300MHz", "333MHz", "366MHz", "400MHz", "433MHz",
+    "466MHz", "500MHz", "533MHz", "566MHz", "600MHz",
+    "633MHz", "666MHz", "700MHz", "733MHz", "766MHz",
+    "800MHz", "833MHz", "866MHz", "900MHz"
+  };
+  #define menu_get_clock_speed() \
     clock_speed = 300 + (clock_speed_number * 3333) / 100
   #define get_clock_speed_number() \
     clock_speed_number = (clock_speed - 300) / 33
 #elif defined(GP2X_BUILD)
     clock_speed = 300 + (clock_speed_number * 3333) / 100
   #define get_clock_speed_number() \
     clock_speed_number = (clock_speed - 300) / 33
 #elif defined(GP2X_BUILD)
-  #define get_clock_speed() \
+  static const char *clock_speed_options[] =
+  {
+    "150MHz", "160MHz", "170MHz", "180MHz", "190MHz",
+    "200MHz", "210MHz", "220MHz", "230MHz", "240MHz",
+    "250MHz", "260MHz", "270MHz", "280MHz", "290MHz"
+  };
+  #define menu_get_clock_speed() \
     clock_speed = 150 + clock_speed_number * 10
   #define get_clock_speed_number() \
     clock_speed_number = (clock_speed - 150) / 10
 #else
     clock_speed = 150 + clock_speed_number * 10
   #define get_clock_speed_number() \
     clock_speed_number = (clock_speed - 150) / 10
 #else
-  #define get_clock_speed() 0
-  #define get_clock_speed_number() 0
+  static const char *clock_speed_options[] =
+  {
+    "0"
+  };
+  #define menu_get_clock_speed()
+  #define get_clock_speed_number()
 #endif
 
 #endif
 
-const int
-#ifdef WIZ_BUILD
-  default_clock_speed = 533;
-#elif defined(GP2X_BUILD)
-  default_clock_speed = 200;
-#else
-  default_clock_speed = 333;
-#endif
+
 int sort_function(const void *dest_str_ptr, const void *src_str_ptr)
 {
   char *dest_str = *((char **)dest_str_ptr);
 int sort_function(const void *dest_str_ptr, const void *src_str_ptr)
 {
   char *dest_str = *((char **)dest_str_ptr);
@@ -120,25 +125,24 @@ int sort_function(const void *dest_str_ptr, const void *src_str_ptr)
   return strcasecmp(dest_str, src_str);
 }
 
   return strcasecmp(dest_str, src_str);
 }
 
-s32 load_file(u8 **wildcards, u8 *result)
+s32 load_file(const char **wildcards, char *result)
 {
   DIR *current_dir;
   struct dirent *current_file;
   struct stat file_info;
 {
   DIR *current_dir;
   struct dirent *current_file;
   struct stat file_info;
-  u8 current_dir_name[MAX_PATH];
-  u8 current_dir_short[81];
+  char current_dir_name[MAX_PATH];
+  char current_dir_short[81];
   u32 current_dir_length;
   u32 total_filenames_allocated;
   u32 total_dirnames_allocated;
   u32 current_dir_length;
   u32 total_filenames_allocated;
   u32 total_dirnames_allocated;
-  u8 **file_list;
-  u8 **dir_list;
+  char **file_list;
+  char **dir_list;
   u32 num_files;
   u32 num_dirs;
   u32 num_files;
   u32 num_dirs;
-  u8 *file_name;
+  char *file_name;
   u32 file_name_length;
   u32 ext_pos = -1;
   u32 chosen_file, chosen_dir;
   u32 file_name_length;
   u32 ext_pos = -1;
   u32 chosen_file, chosen_dir;
-  u32 dialog_result = 1;
   s32 return_value = 1;
   s32 current_file_selection;
   s32 current_file_scroll_value;
   s32 return_value = 1;
   s32 current_file_selection;
   s32 current_file_scroll_value;
@@ -163,10 +167,10 @@ s32 load_file(u8 **wildcards, u8 *result)
 
     total_filenames_allocated = 32;
     total_dirnames_allocated = 32;
 
     total_filenames_allocated = 32;
     total_dirnames_allocated = 32;
-    file_list = (u8 **)malloc(sizeof(u8 *) * 32);
-    dir_list = (u8 **)malloc(sizeof(u8 *) * 32);
-    memset(file_list, 0, sizeof(u8 *) * 32);
-    memset(dir_list, 0, sizeof(u8 *) * 32);
+    file_list = (char **)malloc(sizeof(char *) * 32);
+    dir_list = (char **)malloc(sizeof(char *) * 32);
+    memset(file_list, 0, sizeof(char *) * 32);
+    memset(dir_list, 0, sizeof(char *) * 32);
 
     num_files = 0;
     num_dirs = 0;
 
     num_files = 0;
     num_dirs = 0;
@@ -194,8 +198,7 @@ s32 load_file(u8 **wildcards, u8 *result)
         {
           if(S_ISDIR(file_info.st_mode))
           {
         {
           if(S_ISDIR(file_info.st_mode))
           {
-            dir_list[num_dirs] =
-             (u8 *)malloc(file_name_length + 1);
+            dir_list[num_dirs] = malloc(file_name_length + 1);
 
             sprintf(dir_list[num_dirs], "%s", file_name);
 
 
             sprintf(dir_list[num_dirs], "%s", file_name);
 
@@ -222,7 +225,7 @@ s32 load_file(u8 **wildcards, u8 *result)
                  wildcards[i]))
                 {
                   file_list[num_files] =
                  wildcards[i]))
                 {
                   file_list[num_files] =
-                   (u8 *)malloc(file_name_length + 1);
+                   malloc(file_name_length + 1);
 
                   sprintf(file_list[num_files], "%s", file_name);
 
 
                   sprintf(file_list[num_files], "%s", file_name);
 
@@ -236,26 +239,26 @@ s32 load_file(u8 **wildcards, u8 *result)
 
         if(num_files == total_filenames_allocated)
         {
 
         if(num_files == total_filenames_allocated)
         {
-          file_list = (u8 **)realloc(file_list, sizeof(u8 *) *
+          file_list = (char **)realloc(file_list, sizeof(char *) *
            total_filenames_allocated * 2);
           memset(file_list + total_filenames_allocated, 0,
            total_filenames_allocated * 2);
           memset(file_list + total_filenames_allocated, 0,
-           sizeof(u8 *) * total_filenames_allocated);
+           sizeof(char *) * total_filenames_allocated);
           total_filenames_allocated *= 2;
         }
 
         if(num_dirs == total_dirnames_allocated)
         {
           total_filenames_allocated *= 2;
         }
 
         if(num_dirs == total_dirnames_allocated)
         {
-          dir_list = (u8 **)realloc(dir_list, sizeof(u8 *) *
+          dir_list = (char **)realloc(dir_list, sizeof(char *) *
            total_dirnames_allocated * 2);
           memset(dir_list + total_dirnames_allocated, 0,
            total_dirnames_allocated * 2);
           memset(dir_list + total_dirnames_allocated, 0,
-           sizeof(u8 *) * total_dirnames_allocated);
+           sizeof(char *) * total_dirnames_allocated);
           total_dirnames_allocated *= 2;
         }
       }
     } while(current_file);
 
           total_dirnames_allocated *= 2;
         }
       }
     } while(current_file);
 
-    qsort((void *)file_list, num_files, sizeof(u8 *), sort_function);
-    qsort((void *)dir_list, num_dirs, sizeof(u8 *), sort_function);
+    qsort((void *)file_list, num_files, sizeof(char *), sort_function);
+    qsort((void *)dir_list, num_dirs, sizeof(char *), sort_function);
 
     closedir(current_dir);
 
 
     closedir(current_dir);
 
@@ -291,8 +294,6 @@ s32 load_file(u8 **wildcards, u8 *result)
 
     clear_screen(COLOR_BG);
   {
 
     clear_screen(COLOR_BG);
   {
-    u8 print_buffer[81];
-
     while(repeat)
     {
       flip_screen();
     while(repeat)
     {
       flip_screen();
@@ -521,6 +522,9 @@ s32 load_file(u8 **wildcards, u8 *result)
           return_value = -1;
           repeat = 0;
           break;
           return_value = -1;
           repeat = 0;
           break;
+
+        default:
+          break;
       }
     }
   }
       }
     }
   }
@@ -564,11 +568,11 @@ struct _menu_option_type
   void (* action_function)();
   void (* passive_function)();
   struct _menu_type *sub_menu;
   void (* action_function)();
   void (* passive_function)();
   struct _menu_type *sub_menu;
-  char *display_string;
+  const char *display_string;
   void *options;
   u32 *current_option;
   u32 num_options;
   void *options;
   u32 *current_option;
   u32 num_options;
-  char *help_string;
+  const char *help_string;
   u32 line_number;
   menu_option_type_enum option_type;
 };
   u32 line_number;
   menu_option_type_enum option_type;
 };
@@ -731,17 +735,62 @@ u32 gamepad_config_line_to_button[] =
 #ifdef GP2X_BUILD
 
 u32 gamepad_config_line_to_button[] =
 #ifdef GP2X_BUILD
 
 u32 gamepad_config_line_to_button[] =
- { 0, 2, 1, 3, 8, 9, 10, 11, 6, 7, 4, 5, 14 };
+ { 0, 2, 1, 3, 8, 9, 10, 11, 6, 7, 4, 5, 14, 15 };
+
+#endif
+
+#ifdef PND_BUILD
+
+u32 gamepad_config_line_to_button[] =
+ { 0, 2, 1, 3, 8, 9, 10, 11, 6, 7, 4, 5, 12, 13, 14, 15 };
+
+#endif
+
+static const char *scale_options[] =
+{
+#ifdef PSP_BUILD
+  "unscaled 3:2", "scaled 3:2", "fullscreen 16:9"
+#elif defined(WIZ_BUILD)
+  "unscaled 3:2", "scaled 3:2 (slower)",
+  "unscaled 3:2 (anti-tear)", "scaled 3:2 (anti-tear)"
+#elif defined(POLLUX_BUILD)
+  "unscaled 3:2", "scaled 3:2 (slower)"
+#elif defined(PND_BUILD)
+  "unscaled", "2x", "3x", "fullscreen"
+#elif defined(GP2X_BUILD)
+  "unscaled 3:2", "scaled 3:2", "fullscreen", "scaled 3:2 (software)"
+#else
+  "unscaled 3:2"
+#endif
+};
 
 
+const char *filter2_options[] =
+{
+  "none", "scale2x", "scale3x", "eagle2x"
+};
+
+#ifndef PSP_BUILD
+static const char *audio_buffer_options[] =
+{
+  "16 bytes", "32 bytes", "64 bytes",
+  "128 bytes", "256 bytes", "512 bytes", "1024 bytes", "2048 bytes",
+  "4096 bytes", "8192 bytes", "16284 bytes"
+};
+#else
+const char *audio_buffer_options[] =
+{
+  "3072 bytes", "4096 bytes", "5120 bytes", "6144 bytes", "7168 bytes",
+  "8192 bytes", "9216 bytes", "10240 bytes", "11264 bytes", "12288 bytes"
+};
 #endif
 
 
 s32 load_game_config_file()
 {
 #endif
 
 
 s32 load_game_config_file()
 {
-  u8 game_config_filename[512];
+  char game_config_filename[512];
   u32 file_loaded = 0;
   u32 i;
   u32 file_loaded = 0;
   u32 i;
-  change_ext(gamepak_filename, game_config_filename, ".cfg");
+  make_rpath(game_config_filename, sizeof(game_config_filename), ".cfg");
 
   file_open(game_config_file, game_config_filename, read);
 
 
   file_open(game_config_file, game_config_filename, read);
 
@@ -760,7 +809,7 @@ s32 load_game_config_file()
       random_skip = file_options[2] % 2;
       clock_speed = file_options[3];
 
       random_skip = file_options[2] % 2;
       clock_speed = file_options[3];
 
-#ifdef WIZ_BUILD
+#ifdef POLLUX_BUILD
       if(clock_speed > 900)
         clock_speed = 533;
 #elif defined(GP2X_BUILD)
       if(clock_speed > 900)
         clock_speed = 533;
 #elif defined(GP2X_BUILD)
@@ -782,7 +831,7 @@ s32 load_game_config_file()
 
       for(i = 0; i < 10; i++)
       {
 
       for(i = 0; i < 10; i++)
       {
-        cheats[i].cheat_active = file_options[3 + i] % 2;
+        cheats[i].cheat_active = file_options[4 + i] % 2;
         cheats[i].cheat_name[0] = 0;
       }
 
         cheats[i].cheat_name[0] = 0;
       }
 
@@ -796,7 +845,7 @@ s32 load_game_config_file()
 
   current_frameskip_type = auto_frameskip;
   frameskip_value = 4;
 
   current_frameskip_type = auto_frameskip;
   frameskip_value = 4;
-#ifdef WIZ_BUILD
+#ifdef POLLUX_BUILD
   frameskip_value = 1;
 #endif
   random_skip = 0;
   frameskip_value = 1;
 #endif
   random_skip = 0;
@@ -811,15 +860,28 @@ s32 load_game_config_file()
   return -1;
 }
 
   return -1;
 }
 
+enum file_options {
+  fo_screen_scale = 0,
+  fo_screen_filter,
+  fo_global_enable_audio,
+  fo_audio_buffer_size,
+  fo_update_backup_flag,
+  fo_global_enable_analog,
+  fo_analog_sensitivity_level,
+  fo_screen_filter2,
+  fo_main_option_count,
+};
+
+#ifdef PC_BUILD
+#define PLAT_BUTTON_COUNT 0
+#endif
+#define FILE_OPTION_COUNT (fo_main_option_count + PLAT_BUTTON_COUNT)
+
 s32 load_config_file()
 {
 s32 load_config_file()
 {
-  u8 config_path[512];
+  char config_path[512];
 
 
-  #if (defined(PSP_BUILD) || defined(ARM_ARCH)) && !defined(_WIN32_WCE)
-    sprintf(config_path, "%s/%s", main_path, GPSP_CONFIG_FILENAME);
-  #else
-    sprintf(config_path, "%s\\%s", main_path, GPSP_CONFIG_FILENAME);
-  #endif
+  sprintf(config_path, "%s" PATH_SEPARATOR "%s", main_path, GPSP_CONFIG_FILENAME);
 
   file_open(config_file, config_path, read);
 
 
   file_open(config_file, config_path, read);
 
@@ -828,26 +890,24 @@ s32 load_config_file()
     u32 file_size = file_length(config_path, config_file);
 
     // Sanity check: File size must be the right size
     u32 file_size = file_length(config_path, config_file);
 
     // Sanity check: File size must be the right size
-    if(file_size == 92)
+    if(file_size == FILE_OPTION_COUNT * 4)
     {
       u32 file_options[file_size / 4];
     {
       u32 file_options[file_size / 4];
-      u32 i;
-      s32 menu_button = -1;
       file_read_array(config_file, file_options);
 
       file_read_array(config_file, file_options);
 
-      screen_scale = file_options[0] % 3;
-      screen_filter = file_options[1] % 2;
-      global_enable_audio = file_options[2] % 2;
+      screen_scale = file_options[fo_screen_scale] %
+        (sizeof(scale_options) / sizeof(scale_options[0]));
+      screen_filter = file_options[fo_screen_filter] % 2;
+      global_enable_audio = file_options[fo_global_enable_audio] % 2;
+      screen_filter2 = file_options[fo_screen_filter2] %
+        (sizeof(filter2_options) / sizeof(filter2_options[0]));
 
 
-#ifdef PSP_BUILD
-      audio_buffer_size_number = file_options[3] % 10;
-#else
-      audio_buffer_size_number = file_options[3] % 11;
-#endif
+      audio_buffer_size_number = file_options[fo_audio_buffer_size] %
+        (sizeof(audio_buffer_options) / sizeof(audio_buffer_options[0]));
 
 
-      update_backup_flag = file_options[4] % 2;
-      global_enable_analog = file_options[5] % 2;
-      analog_sensitivity_level = file_options[6] % 8;
+      update_backup_flag = file_options[fo_update_backup_flag] % 2;
+      global_enable_analog = file_options[fo_global_enable_analog] % 2;
+      analog_sensitivity_level = file_options[fo_analog_sensitivity_level] % 8;
 
 #ifdef PSP_BUILD
     scePowerSetClockFrequency(clock_speed, clock_speed, clock_speed / 2);
 
 #ifdef PSP_BUILD
     scePowerSetClockFrequency(clock_speed, clock_speed, clock_speed / 2);
@@ -857,9 +917,11 @@ s32 load_config_file()
       // key, if not assign to triangle
 
 #ifndef PC_BUILD
       // key, if not assign to triangle
 
 #ifndef PC_BUILD
-      for(i = 0; i < 16; i++)
+      u32 i;
+      s32 menu_button = -1;
+      for(i = 0; i < PLAT_BUTTON_COUNT; i++)
       {
       {
-        gamepad_config_map[i] = file_options[7 + i] %
+        gamepad_config_map[i] = file_options[fo_main_option_count + i] %
          (BUTTON_ID_NONE + 1);
 
         if(gamepad_config_map[i] == BUTTON_ID_MENU)
          (BUTTON_ID_NONE + 1);
 
         if(gamepad_config_map[i] == BUTTON_ID_MENU)
@@ -868,9 +930,9 @@ s32 load_config_file()
         }
       }
 
         }
       }
 
-      if(menu_button == -1)
+      if(menu_button == -1 && PLAT_MENU_BUTTON >= 0)
       {
       {
-        gamepad_config_map[0] = BUTTON_ID_MENU;
+        gamepad_config_map[PLAT_MENU_BUTTON] = BUTTON_ID_MENU;
       }
 #endif
 
       }
 #endif
 
@@ -885,10 +947,10 @@ s32 load_config_file()
 
 s32 save_game_config_file()
 {
 
 s32 save_game_config_file()
 {
-  u8 game_config_filename[512];
+  char game_config_filename[512];
   u32 i;
 
   u32 i;
 
-  change_ext(gamepak_filename, game_config_filename, ".cfg");
+  make_rpath(game_config_filename, sizeof(game_config_filename), ".cfg");
 
   file_open(game_config_file, game_config_filename, write);
 
 
   file_open(game_config_file, game_config_filename, write);
 
@@ -918,13 +980,9 @@ s32 save_game_config_file()
 
 s32 save_config_file()
 {
 
 s32 save_config_file()
 {
-  u8 config_path[512];
+  char config_path[512];
 
 
-  #if (defined(PSP_BUILD) || defined(ARM_ARCH)) && !defined(_WIN32_WCE)
-    sprintf(config_path, "%s/%s", main_path, GPSP_CONFIG_FILENAME);
-  #else
-    sprintf(config_path, "%s\\%s", main_path, GPSP_CONFIG_FILENAME);
-  #endif
+  sprintf(config_path, "%s" PATH_SEPARATOR "%s", main_path, GPSP_CONFIG_FILENAME);
 
   file_open(config_file, config_path, write);
 
 
   file_open(config_file, config_path, write);
 
@@ -932,21 +990,22 @@ s32 save_config_file()
 
   if(file_check_valid(config_file))
   {
 
   if(file_check_valid(config_file))
   {
-    u32 file_options[23];
-    u32 i;
+    u32 file_options[FILE_OPTION_COUNT];
 
 
-    file_options[0] = screen_scale;
-    file_options[1] = screen_filter;
-    file_options[2] = global_enable_audio;
-    file_options[3] = audio_buffer_size_number;
-    file_options[4] = update_backup_flag;
-    file_options[5] = global_enable_analog;
-    file_options[6] = analog_sensitivity_level;
+    file_options[fo_screen_scale] = screen_scale;
+    file_options[fo_screen_filter] = screen_filter;
+    file_options[fo_global_enable_audio] = global_enable_audio;
+    file_options[fo_audio_buffer_size] = audio_buffer_size_number;
+    file_options[fo_update_backup_flag] = update_backup_flag;
+    file_options[fo_global_enable_analog] = global_enable_analog;
+    file_options[fo_analog_sensitivity_level] = analog_sensitivity_level;
+    file_options[fo_screen_filter2] = screen_filter2;
 
 #ifndef PC_BUILD
 
 #ifndef PC_BUILD
-    for(i = 0; i < 16; i++)
+    u32 i;
+    for(i = 0; i < PLAT_BUTTON_COUNT; i++)
     {
     {
-      file_options[7 + i] = gamepad_config_map[i];
+      file_options[fo_main_option_count + i] = gamepad_config_map[i];
     }
 #endif
 
     }
 #endif
 
@@ -971,16 +1030,16 @@ typedef enum
 
 u32 savestate_slot = 0;
 
 
 u32 savestate_slot = 0;
 
-void get_savestate_snapshot(u8 *savestate_filename)
+void get_savestate_snapshot(char *savestate_filename)
 {
   u16 snapshot_buffer[240 * 160];
 {
   u16 snapshot_buffer[240 * 160];
-  u8 savestate_timestamp_string[80];
+  char savestate_timestamp_string[80];
 
   file_open(savestate_file, savestate_filename, read);
 
   if(file_check_valid(savestate_file))
   {
 
   file_open(savestate_file, savestate_filename, read);
 
   if(file_check_valid(savestate_file))
   {
-    u8 weekday_strings[7][11] =
+    const char weekday_strings[7][11] =
     {
       "Sunday", "Monday", "Tuesday", "Wednesday",
       "Thursday", "Friday", "Saturday"
     {
       "Sunday", "Monday", "Tuesday", "Wednesday",
       "Thursday", "Friday", "Saturday"
@@ -1006,7 +1065,7 @@ void get_savestate_snapshot(u8 *savestate_filename)
   else
   {
     memset(snapshot_buffer, 0, 240 * 160 * 2);
   else
   {
     memset(snapshot_buffer, 0, 240 * 160 * 2);
-    print_string_ext("No savestate exists for this slot.",
+    print_string_ext("No savestate in this slot.",
      0xFFFF, 0x0000, 15, 75, snapshot_buffer, 240, 0, 0, FONT_HEIGHT);
     print_string("---------- --/--/---- --:--:--          ", COLOR_HELP_TEXT,
      COLOR_BG, 10, 40);
      0xFFFF, 0x0000, 15, 75, snapshot_buffer, 240, 0, 0, FONT_HEIGHT);
     print_string("---------- --/--/---- --:--:--          ", COLOR_HELP_TEXT,
      COLOR_BG, 10, 40);
@@ -1017,22 +1076,18 @@ void get_savestate_snapshot(u8 *savestate_filename)
 #endif
 }
 
 #endif
 }
 
-void get_savestate_filename(u32 slot, u8 *name_buffer)
+void get_savestate_filename_noshot(u32 slot, char *name_buffer)
 {
 {
-  u8 savestate_ext[16];
+  char savestate_ext[16];
 
   sprintf(savestate_ext, "%d.svs", slot);
 
   sprintf(savestate_ext, "%d.svs", slot);
-  change_ext(gamepak_filename, name_buffer, savestate_ext);
-
-  get_savestate_snapshot(name_buffer);
+  make_rpath(name_buffer, 512, savestate_ext);
 }
 
 }
 
-void get_savestate_filename_noshot(u32 slot, u8 *name_buffer)
+void get_savestate_filename(u32 slot, char *name_buffer)
 {
 {
-  u8 savestate_ext[16];
-
-  sprintf(savestate_ext, "%d.svs", slot);
-  change_ext(gamepak_filename, name_buffer, savestate_ext);
+  get_savestate_filename_noshot(slot, name_buffer);
+  get_savestate_snapshot(name_buffer);
 }
 
 #ifdef PSP_BUILD
 }
 
 #ifdef PSP_BUILD
@@ -1044,20 +1099,16 @@ void get_savestate_filename_noshot(u32 slot, u8 *name_buffer)
 
 u32 menu(u16 *original_screen)
 {
 
 u32 menu(u16 *original_screen)
 {
+  char print_buffer[81];
   u32 clock_speed_number;
   u32 clock_speed_number;
-  static u32 clock_speed_old = default_clock_speed;
-  u8 print_buffer[81];
-  u32 _current_option = 0;
   gui_action_type gui_action;
   gui_action_type gui_action;
-  menu_enum _current_menu = MAIN_MENU;
   u32 i;
   u32 repeat = 1;
   u32 return_value = 0;
   u32 first_load = 0;
   u32 i;
   u32 repeat = 1;
   u32 return_value = 0;
   u32 first_load = 0;
-  u8 savestate_ext[16];
-  u8 current_savestate_filename[512];
-  u8 line_buffer[80];
-  u8 cheat_format_str[10][41];
+  char current_savestate_filename[512];
+  char line_buffer[80];
+  char cheat_format_str[10][41];
 
   menu_type *current_menu;
   menu_option_type *current_option;
 
   menu_type *current_menu;
   menu_option_type *current_option;
@@ -1067,7 +1118,8 @@ u32 menu(u16 *original_screen)
   auto void choose_menu();
   auto void clear_help();
 
   auto void choose_menu();
   auto void clear_help();
 
-  u8 *gamepad_help[] =
+#ifndef PC_BUILD
+  static const char * const gamepad_help[] =
   {
     "Up button on GBA d-pad.",
     "Down button on GBA d-pad.",
   {
     "Up button on GBA d-pad.",
     "Down button on GBA d-pad.",
@@ -1093,6 +1145,44 @@ u32 menu(u16 *original_screen)
     "Does nothing."
   };
 
     "Does nothing."
   };
 
+  static const char *gamepad_config_buttons[] =
+  {
+    "UP",
+    "DOWN",
+    "LEFT",
+    "RIGHT",
+    "A",
+    "B",
+    "L",
+    "R",
+    "START",
+    "SELECT",
+    "MENU",
+    "FASTFORWARD",
+    "LOAD STATE",
+    "SAVE STATE",
+    "RAPIDFIRE A",
+    "RAPIDFIRE B",
+    "RAPIDFIRE L",
+    "RAPIDFIRE R",
+    "VOLUME UP",
+    "VOLUME DOWN",
+    "DISPLAY FPS",
+    "NOTHING"
+  };
+#endif
+
+  void menu_update_clock()
+  {
+    get_clock_speed_number();
+    if (clock_speed_number < 0 || clock_speed_number >=
+     sizeof(clock_speed_options) / sizeof(clock_speed_options[0]))
+    {
+      clock_speed = default_clock_speed;
+      get_clock_speed_number();
+    }
+  }
+
   void menu_exit()
   {
     if(!first_load)
   void menu_exit()
   {
     if(!first_load)
@@ -1101,15 +1191,15 @@ u32 menu(u16 *original_screen)
 
   void menu_quit()
   {
 
   void menu_quit()
   {
-    get_clock_speed();
+    menu_get_clock_speed();
     save_config_file();
     quit();
   }
 
   void menu_load()
   {
     save_config_file();
     quit();
   }
 
   void menu_load()
   {
-    u8 *file_ext[] = { ".gba", ".bin", ".zip", NULL };
-    u8 load_filename[512];
+    const char *file_ext[] = { ".gba", ".bin", ".zip", NULL };
+    char load_filename[512];
     save_game_config_file();
     if(load_file(file_ext, load_filename) != -1)
     {
     save_game_config_file();
     if(load_file(file_ext, load_filename) != -1)
     {
@@ -1121,6 +1211,7 @@ u32 menu(u16 *original_screen)
        return_value = 1;
        repeat = 0;
        reg[CHANGED_PC_STATUS] = 1;
        return_value = 1;
        repeat = 0;
        reg[CHANGED_PC_STATUS] = 1;
+       menu_update_clock();
     }
     else
     {
     }
     else
     {
@@ -1167,8 +1258,8 @@ u32 menu(u16 *original_screen)
 
   void menu_load_state_file()
   {
 
   void menu_load_state_file()
   {
-    u8 *file_ext[] = { ".svs", NULL };
-    u8 load_filename[512];
+    const char *file_ext[] = { ".svs", NULL };
+    char load_filename[512];
     if(load_file(file_ext, load_filename) != -1)
     {
       load_state(load_filename);
     if(load_file(file_ext, load_filename) != -1)
     {
       load_state(load_filename);
@@ -1229,91 +1320,13 @@ u32 menu(u16 *original_screen)
      current_savestate_filename);
   }
 
      current_savestate_filename);
   }
 
-  u8 *yes_no_options[] = { "no", "yes" };
-  u8 *enable_disable_options[] = { "disabled", "enabled" };
-
-  u8 *scale_options[] =
-  {
-#ifdef WIZ_BUILD
-    "unscaled 3:2", "scaled 3:2 (slower)",
-    "unscaled 3:2 (anti-tear)", "scaled 3:2 (anti-tear)"
-#else
-    "unscaled 3:2", "scaled 3:2", "fullscreen"
-#ifdef PSP_BUILD
-    " 16:9"
-#endif
-#endif
-  };
-
-  u8 *frameskip_options[] = { "automatic", "manual", "off" };
-  u8 *frameskip_variation_options[] = { "uniform", "random" };
+  const char *yes_no_options[] = { "no", "yes" };
+  const char *enable_disable_options[] = { "disabled", "enabled" };
 
 
-#ifndef PSP_BUILD
-  u8 *audio_buffer_options[] =
-  {
-    "16 bytes", "32 bytes", "64 bytes",
-    "128 bytes", "256 bytes", "512 bytes", "1024 bytes", "2048 bytes",
-    "4096 bytes", "8192 bytes", "16284 bytes"
-  };
-#else
-  u8 *audio_buffer_options[] =
-  {
-    "3072 bytes", "4096 bytes", "5120 bytes", "6144 bytes", "7168 bytes",
-    "8192 bytes", "9216 bytes", "10240 bytes", "11264 bytes", "12288 bytes"
-  };
-
-#endif
-
-  u8 *update_backup_options[] = { "Exit only", "Automatic" };
-
-#ifdef WIZ_BUILD
-  u8 *clock_speed_options[] =
-  {
-    "300MHz", "333MHz", "366MHz", "400MHz", "433MHz",
-    "466MHz", "500MHz", "533MHz", "566MHz", "600MHz",
-    "633MHz", "666MHz", "700MHz", "733MHz", "766MHz",
-    "800MHz", "833MHz", "866MHz", "900MHz"
-  };
-#elif defined(GP2X_BUILD)
-  u8 *clock_speed_options[] =
-  {
-    "150MHz", "160MHz", "170MHz", "180MHz", "190MHz",
-    "200MHz", "210MHz", "220MHz", "230MHz", "240MHz",
-    "250MHz", "260MHz", "270MHz", "280MHz", "290MHz"
-  };
-#else
-  u8 *clock_speed_options[] =
-  {
-    "33MHz", "66MHz", "100MHz", "133MHz", "166MHz", "200MHz", "233MHz",
-    "266MHz", "300MHz", "333MHz"
-  };
-#endif
+  const char *frameskip_options[] = { "automatic", "manual", "off" };
+  const char *frameskip_variation_options[] = { "uniform", "random" };
 
 
-  u8 *gamepad_config_buttons[] =
-  {
-    "UP",
-    "DOWN",
-    "LEFT",
-    "RIGHT",
-    "A",
-    "B",
-    "L",
-    "R",
-    "START",
-    "SELECT",
-    "MENU",
-    "FASTFORWARD",
-    "LOAD STATE",
-    "SAVE STATE",
-    "RAPIDFIRE A",
-    "RAPIDFIRE B",
-    "RAPIDFIRE L",
-    "RAPIDFIRE R",
-    "VOLUME UP",
-    "VOLUME DOWN",
-    "DISPLAY FPS",
-    "NOTHING"
-  };
+  static const char *update_backup_options[] = { "Exit only", "Automatic" };
 
   // Marker for help information, don't go past this mark (except \n)------*
   menu_option_type graphics_sound_options[] =
 
   // Marker for help information, don't go past this mark (except \n)------*
   menu_option_type graphics_sound_options[] =
@@ -1322,19 +1335,28 @@ u32 menu(u16 *original_screen)
      (u32 *)(&screen_scale),
      sizeof(scale_options) / sizeof(scale_options[0]),
 #ifndef GP2X_BUILD
      (u32 *)(&screen_scale),
      sizeof(scale_options) / sizeof(scale_options[0]),
 #ifndef GP2X_BUILD
-     "Determines how the GBA screen is resized in relation to the entire\n"
-     "screen. Select unscaled 3:2 for GBA resolution, scaled 3:2 for GBA\n"
+     "Determines how the GBA screen is resized in relation to the\n"
+     "entire screen."
+#ifdef PSP_BUILD
+     " Select unscaled 3:2 for GBA resolution, scaled 3:2 for GBA\n"
      "aspect ratio scaled to fill the height of the PSP screen, and\n"
      "fullscreen to fill the entire PSP screen."
      "aspect ratio scaled to fill the height of the PSP screen, and\n"
      "fullscreen to fill the entire PSP screen."
+#endif
 #endif
      "", 2),
 #ifndef GP2X_BUILD
     string_selection_option(NULL, "Screen filtering", yes_no_options,
      (u32 *)(&screen_filter), 2,
 #endif
      "", 2),
 #ifndef GP2X_BUILD
     string_selection_option(NULL, "Screen filtering", yes_no_options,
      (u32 *)(&screen_filter), 2,
-     "Determines whether or not bilinear filtering should be used when\n"
+     "Determines whether or not filtering should be used when\n"
      "scaling the screen. Selecting this will produce a more even and\n"
      "smooth image, at the cost of being blurry and having less vibrant\n"
      "colors.", 3),
      "scaling the screen. Selecting this will produce a more even and\n"
      "smooth image, at the cost of being blurry and having less vibrant\n"
      "colors.", 3),
+#endif
+#ifdef PND_BUILD
+    string_selection_option(NULL, "Scaling filter", filter2_options,
+     (u32 *)(&screen_filter2),
+     sizeof(filter2_options) / sizeof(filter2_options[0]),
+     "Optional pixel art scaling filter", 4),
 #endif
     string_selection_option(NULL, "Frameskip type", frameskip_options,
      (u32 *)(&current_frameskip_type), 3,
 #endif
     string_selection_option(NULL, "Frameskip type", frameskip_options,
      (u32 *)(&current_frameskip_type), 3,
@@ -1359,8 +1381,8 @@ u32 menu(u16 *original_screen)
 #ifndef GP2X_BUILD
      "If objects in the game flicker at a regular rate certain manual\n"
      "frameskip values may cause them to normally disappear. Change this\n"
 #ifndef GP2X_BUILD
      "If objects in the game flicker at a regular rate certain manual\n"
      "frameskip values may cause them to normally disappear. Change this\n"
-     "value to 'random' to avoid this. Do not use otherwise, as it tends to\n"
-     "make the image quality worse, especially in high motion games."
+     "value to 'random' to avoid this. Do not use otherwise, as it tends\n"
+     "to make the image quality worse, especially in high motion games."
 #endif
      "", 7),
     string_selection_option(NULL, "Audio output", yes_no_options,
 #endif
      "", 7),
     string_selection_option(NULL, "Audio output", yes_no_options,
@@ -1382,7 +1404,8 @@ u32 menu(u16 *original_screen)
      "This option requires gpSP to be restarted before it will take effect.",
 #else
      "Set the size (in bytes) of the audio buffer.\n"
      "This option requires gpSP to be restarted before it will take effect.",
 #else
      "Set the size (in bytes) of the audio buffer.\n"
-     "This option requires gpSP restart to take effect.",
+     "This option requires gpSP restart to take effect.\n"
+     "Settable values may be limited by SDL implementation.",
 #endif
      10),
     submenu_option(NULL, "Back", "Return to the main menu.", 12)
 #endif
      10),
     submenu_option(NULL, "Back", "Return to the main menu.", 12)
@@ -1402,25 +1425,29 @@ u32 menu(u16 *original_screen)
     cheat_option(7),
     cheat_option(8),
     cheat_option(9),
     cheat_option(7),
     cheat_option(8),
     cheat_option(9),
+#if defined(PSP_BUILD) || defined(GP2X_BUILD)
     string_selection_option(NULL, "Clock speed",
      clock_speed_options, &clock_speed_number,
      sizeof(clock_speed_options) / sizeof(clock_speed_options[0]),
      "Change the clock speed of the device. Higher clock\n"
      "speed will yield better performance, but will drain\n"
      "battery life further.", 11),
     string_selection_option(NULL, "Clock speed",
      clock_speed_options, &clock_speed_number,
      sizeof(clock_speed_options) / sizeof(clock_speed_options[0]),
      "Change the clock speed of the device. Higher clock\n"
      "speed will yield better performance, but will drain\n"
      "battery life further.", 11),
+#endif
     string_selection_option(NULL, "Update backup",
      update_backup_options, &update_backup_flag, 2,
 #ifdef GP2X_BUILD
      "Determines when in-game save files should be\n"
     string_selection_option(NULL, "Update backup",
      update_backup_options, &update_backup_flag, 2,
 #ifdef GP2X_BUILD
      "Determines when in-game save files should be\n"
-     "written back to SD card.",
+     "written back to SD card."
 #else
      "Determines when in-game save files should be written back to\n"
 #else
      "Determines when in-game save files should be written back to\n"
-     "memstick. If set to 'automatic' writebacks will occur shortly after\n"
-     "the game's backup is altered. On 'exit only' it will only be written\n"
-     "back when you exit from this menu (NOT from using the home button).\n"
-     "Use the latter with extreme care.",
+     "card. If set to 'automatic' writebacks will occur shortly after\n"
+     "the game's backup is altered. On 'exit only' it will only be\n"
+     "written back when you exit from this menu.\n"
+#ifdef PSP
+     "(NOT from using the home button), use the latter with extreme care."
 #endif
 #endif
-     12),
+#endif
+     "", 12),
     submenu_option(NULL, "Back", "Return to the main menu.", 14)
   };
 
     submenu_option(NULL, "Back", "Return to the main menu.", 14)
   };
 
@@ -1490,7 +1517,7 @@ u32 menu(u16 *original_screen)
 
 #endif
 
 
 #endif
 
-#ifdef GP2X_BUILD
+#if defined(GP2X_BUILD) || defined(PND_BUILD)
 
   menu_option_type gamepad_config_options[] =
   {
 
   menu_option_type gamepad_config_options[] =
   {
@@ -1506,19 +1533,40 @@ u32 menu(u16 *original_screen)
     gamepad_config_option("Right Trigger", 9),
 #ifdef WIZ_BUILD
     gamepad_config_option("Menu         ", 10),
     gamepad_config_option("Right Trigger", 9),
 #ifdef WIZ_BUILD
     gamepad_config_option("Menu         ", 10),
-#else
+    gamepad_config_option("Select       ", 11),
+#elif defined(POLLUX_BUILD)
+    gamepad_config_option("I            ", 10),
+    gamepad_config_option("II           ", 11),
+    gamepad_config_option("Push         ", 12),
+    gamepad_config_option("Home         ", 13),
+#elif defined(PND_BUILD)
+    gamepad_config_option("Start        ", 10),
+    gamepad_config_option("Select       ", 11),
+    gamepad_config_option("1            ", 12),
+    gamepad_config_option("2            ", 13),
+    gamepad_config_option("3            ", 14),
+    gamepad_config_option("4            ", 15),
+#else // GP2X
     gamepad_config_option("Start        ", 10),
     gamepad_config_option("Start        ", 10),
-#endif
     gamepad_config_option("Select       ", 11),
     gamepad_config_option("Select       ", 11),
-#ifndef WIZ_BUILD
     gamepad_config_option("Stick Push   ", 12),
 #endif
     gamepad_config_option("Stick Push   ", 12),
 #endif
+#ifdef PND_BUILD
+    submenu_option(NULL, "Back", "Return to the main menu.", 16)
+#else
     submenu_option(NULL, "Back", "Return to the main menu.", 14)
     submenu_option(NULL, "Back", "Return to the main menu.", 14)
+#endif
   };
 
 
   menu_option_type analog_config_options[] =
   {
   };
 
 
   menu_option_type analog_config_options[] =
   {
+#if defined(POLLUX_BUILD)
+    numeric_selection_option(NULL, "Analog sensitivity",
+     &analog_sensitivity_level, 10,
+     "Determine sensitivity/responsiveness of the analog input.\n"
+     "Lower numbers are less sensitive.", 8),
+#endif
     submenu_option(NULL, "Back", "Return to the main menu.", 11)
   };
 
     submenu_option(NULL, "Back", "Return to the main menu.", 11)
   };
 
@@ -1563,9 +1611,9 @@ u32 menu(u16 *original_screen)
     submenu_option(&gamepad_config_menu, "Configure gamepad input",
      "Select to change the in-game behavior of buttons\n"
      "and d-pad.", 6),
     submenu_option(&gamepad_config_menu, "Configure gamepad input",
      "Select to change the in-game behavior of buttons\n"
      "and d-pad.", 6),
-#ifndef GP2X_BUILD
+#ifndef WIZ_BUILD
     submenu_option(&analog_config_menu, "Configure analog input",
     submenu_option(&analog_config_menu, "Configure analog input",
-     "Select to change the in-game behavior of the PSP analog nub.", 7),
+     "Select to change the in-game behavior of the analog nub.", 7),
 #endif
     submenu_option(&cheats_misc_menu, "Cheats and Miscellaneous options",
      "Select to manage cheats, set backup behavior,\n"
 #endif
     submenu_option(&cheats_misc_menu, "Cheats and Miscellaneous options",
      "Select to manage cheats, set backup behavior,\n"
@@ -1610,14 +1658,7 @@ u32 menu(u16 *original_screen)
     }
   }
 
     }
   }
 
-  get_clock_speed_number();
-  if (clock_speed_number < 0 || clock_speed_number >=
-   sizeof(clock_speed_options) / sizeof(clock_speed_options[0]))
-  {
-    clock_speed = default_clock_speed;
-    get_clock_speed_number();
-  }
-
+  menu_update_clock();
   video_resolution_large();
 
 #ifndef GP2X_BUILD
   video_resolution_large();
 
 #ifndef GP2X_BUILD
@@ -1679,13 +1720,13 @@ u32 menu(u16 *original_screen)
 
       if(display_option == current_option)
       {
 
       if(display_option == current_option)
       {
-        print_string_pad(line_buffer, COLOR_ACTIVE_ITEM, COLOR_BG, 10,
-         (display_option->line_number * 10) + 40, 41);
+        print_string_pad(line_buffer, COLOR_ACTIVE_ITEM, COLOR_BG, 6,
+         (display_option->line_number * 10) + 40, 36);
       }
       else
       {
       }
       else
       {
-        print_string_pad(line_buffer, COLOR_INACTIVE_ITEM, COLOR_BG, 10,
-         (display_option->line_number * 10) + 40, 41);
+        print_string_pad(line_buffer, COLOR_INACTIVE_ITEM, COLOR_BG, 6,
+         (display_option->line_number * 10) + 40, 36);
       }
     }
 
       }
     }
 
@@ -1761,25 +1802,19 @@ u32 menu(u16 *original_screen)
         if(current_option->option_type & SUBMENU_OPTION)
           choose_menu(current_option->sub_menu);
         break;
         if(current_option->option_type & SUBMENU_OPTION)
           choose_menu(current_option->sub_menu);
         break;
+
+      default:
+        break;
     }
   }
 
   set_gba_resolution(screen_scale);
   video_resolution_small();
     }
   }
 
   set_gba_resolution(screen_scale);
   video_resolution_small();
-
-  get_clock_speed();
-  if (clock_speed != clock_speed_old)
-  {
-    printf("about to set CPU clock to %iMHz\n", clock_speed);
-  #ifdef PSP_BUILD
-    scePowerSetClockFrequency(clock_speed, clock_speed, clock_speed / 2);
-  #elif defined(GP2X_BUILD)
-    set_FCLK(clock_speed);
-  #endif
-    clock_speed_old = clock_speed;
-  }
+  menu_get_clock_speed();
+  set_clock_speed();
 
   SDL_PauseAudio(0);
 
   SDL_PauseAudio(0);
+  num_skipped_frames = 100;
 
   return return_value;
 }
 
   return return_value;
 }