bios: rework loading
authornotaz <notasas@gmail.com>
Sat, 7 Mar 2026 00:06:04 +0000 (02:06 +0200)
committernotaz <notasas@gmail.com>
Sun, 8 Mar 2026 01:38:29 +0000 (03:38 +0200)
- bios settings should work on soft-reset
- pick the right bios according to region
- announce the bios file (only for slowboot)

libretro/pcsx_rearmed#908

frontend/libretro.c
frontend/libretro_core_options.h
frontend/main.c
frontend/menu.c
libpcsxcore/misc.c
libpcsxcore/psxbios.c
libpcsxcore/psxcommon.h
libpcsxcore/psxmem.c
maemo/main.c

index 8ad2392..baf53c7 100644 (file)
 #ifndef MIN
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 #endif
-
 #ifndef MAX
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 #endif
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
 
 #define ISHEXDEC ((buf[cursor] >= '0') && (buf[cursor] <= '9')) || ((buf[cursor] >= 'a') && (buf[cursor] <= 'f')) || ((buf[cursor] >= 'A') && (buf[cursor] <= 'F'))
 
@@ -110,7 +112,6 @@ static int vout_width = 256, vout_height = 240, vout_pitch_b = 256*2;
 static int vout_fb_dirty;
 static int psx_w, psx_h;
 static bool vout_can_dupe;
-static bool found_bios;
 static int display_internal_fps;
 static bool libretro_supports_bitmasks = false;
 static bool libretro_supports_option_categories = false;
@@ -1773,15 +1774,15 @@ static void set_retro_memmap(void)
 }
 
 static void show_notification(const char *msg_str,
-      unsigned duration_ms, unsigned priority)
+      unsigned duration_ms, unsigned priority, enum retro_log_level level)
 {
    if (msg_interface_version >= 1)
    {
       struct retro_message_ext msg = {
          msg_str,
          duration_ms,
-         3,
-         RETRO_LOG_WARN,
+         priority,
+         level,
          RETRO_MESSAGE_TARGET_ALL,
          RETRO_MESSAGE_TYPE_NOTIFICATION,
          -1
@@ -1992,7 +1993,8 @@ bool retro_load_game(const struct retro_game_info *info)
 #if !defined(HAVE_CDROM) && !defined(USE_LIBRETRO_VFS)
       ReleasePlugins();
       LogErr("%s\n", "Physical CD-ROM support is not compiled in.");
-      show_notification("Physical CD-ROM support is not compiled in.", 6000, 3);
+      show_notification("Physical CD-ROM support is not compiled in.",
+         6000, 3, RETRO_LOG_ERROR);
       return false;
 #endif
    }
@@ -2075,10 +2077,18 @@ bool retro_load_game(const struct retro_game_info *info)
    for (i = 0; i < 8; ++i)
       in_type[i] = PSE_PAD_TYPE_STANDARD;
 
-   if (!is_exe && CheckCdrom() == -1)
+   if (!is_exe)
    {
-      LogErr("unsupported/invalid CD image: %s\n", info->path);
-      return false;
+      if (CheckCdrom() == -1)
+      {
+         LogErr("unsupported/invalid CD image: %s\n", info->path);
+         return false;
+      }
+   }
+   else
+   {
+      Config.PsxRegion = PSX_REGION_US;
+      Config.PsxType = PSX_TYPE_NTSC;
    }
 
    plugin_call_rearmed_cbs();
@@ -2108,10 +2118,20 @@ bool retro_load_game(const struct retro_game_info *info)
 #endif
    log_mem_usage(0);
 
-   if (check_unsatisfied_libcrypt())
-      show_notification("LibCrypt protected game with missing SBI detected", 3000, 3);
+   if (check_unsatisfied_libcrypt()) {
+      show_notification("LibCrypt protected game with missing SBI detected",
+            3000, 3, RETRO_LOG_WARN);
+   }
+   if (Config.SlowBoot)
+   {
+      char buf[16+64];
+      if (Config.PsxRegion < ARRAY_SIZE(Config.Bios) && Config.Bios[Config.PsxRegion][0]) {
+         snprintf(buf, sizeof(buf), "Booting BIOS: %s", Config.Bios[Config.PsxRegion]);
+         show_notification(buf, 1000, 2, RETRO_LOG_INFO);
+      }
+   }
    if (Config.TurboCD)
-      show_notification("TurboCD is ON", 700, 2);
+      show_notification("TurboCD is ON", 700, 2, RETRO_LOG_INFO);
 
    return true;
 }
@@ -2941,20 +2961,6 @@ static void update_variables(bool in_flight)
    }
 #endif
 
-   if (found_bios)
-   {
-      var.value = NULL;
-      var.key = "pcsx_rearmed_show_bios_bootlogo";
-      if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
-      {
-         Config.SlowBoot = 0;
-         if (strcmp(var.value, "enabled") == 0)
-            Config.SlowBoot = 1;
-         else if (strcmp(var.value, "enabled_no_pcsx") == 0)
-            Config.SlowBoot = 2;
-      }
-   }
-
    if (in_flight)
    {
       // inform core things about possible config changes
@@ -3282,7 +3288,7 @@ static void update_input(void)
                int state = padToggleAnalog(i);
                char msg[32];
                snprintf(msg, sizeof(msg), "ANALOG %s", state ? "ON" : "OFF");
-               show_notification(msg, 800, 1);
+               show_notification(msg, 800, 1, RETRO_LOG_INFO);
                in_dualshock_toggling = true;
             }
             return;
@@ -3375,12 +3381,16 @@ static void print_internal_fps(void)
    }
 }
 
+static bool get_bios_config_hle(void);
+static void prepare_bios(bool use_hle);
+
 void retro_run(void)
 {
    //SysReset must be run while core is running,Not in menu (Locks up Retroarch)
    if (rebootemu != 0)
    {
       rebootemu = 0;
+      prepare_bios(get_bios_config_hle());
       SysReset();
       if (Config.HLE)
          LoadCdrom();
@@ -3462,8 +3472,13 @@ void retro_run(void)
 #endif
 }
 
-static bool try_use_bios(const char *path, bool preferred_only)
+// see Config.Bios
+static char *bios_saved[PSX_REGION_COUNT];
+
+static bool try_use_bios(char *path, size_t path_size, bool preferred_only)
 {
+   const char *guessed_region_name = "US";
+   u8 guessed_region = PSX_REGION_US;
    long size;
    const char *name;
    FILE *fp = fopen(path, "rb");
@@ -3484,11 +3499,20 @@ static bool try_use_bios(const char *path, bool preferred_only)
       return false;
    if (strstr(name, "unirom"))
       return false;
-   // jp bios have an addidional region check
-   if (preferred_only && (strcasestr(name, "00.") || strcasestr(name, "j.bin")))
-      return false;
+   if (strstr(name, "00.") || strcasestr(name, "j.bin")) {
+      guessed_region = PSX_REGION_JP;
+      guessed_region_name = "JP";
+   }
+   else if (strstr(name, "02.") || strstr(name, "52.") || strcasestr(name, "e.bin")) {
+      guessed_region = PSX_REGION_EU;
+      guessed_region_name = "EU";
+   }
 
-   snprintf(Config.Bios, sizeof(Config.Bios), "%s", name);
+   if (bios_saved[guessed_region] == NULL) {
+      bios_saved[guessed_region] = strdup(name);
+      if (bios_saved[guessed_region])
+         SysPrintf("found %s BIOS file: %s\n", guessed_region_name, path);
+   }
    return true;
 }
 
@@ -3496,18 +3520,17 @@ static bool try_use_bios(const char *path, bool preferred_only)
 #include <sys/types.h>
 #include <dirent.h>
 
-static bool find_any_bios(const char *dirpath, char *path, size_t path_size)
+static void find_any_bios(const char *dirpath, char *path, size_t path_size)
 {
    static const char *substr_pref[] = { "scph", "ps" };
    static const char *substr_alt[] = { "scph", "ps", "openbios" };
    DIR *dir;
    struct dirent *ent;
-   bool ret = false;
    size_t i;
 
    dir = opendir(dirpath);
    if (dir == NULL)
-      return false;
+      return;
 
    // try to find a "better" bios
    while ((ent = readdir(dir)))
@@ -3518,8 +3541,8 @@ static bool find_any_bios(const char *dirpath, char *path, size_t path_size)
          if ((strncasecmp(ent->d_name, substr, strlen(substr)) != 0))
             continue;
          snprintf(path, path_size, "%s%c%s", dirpath, SLASH, ent->d_name);
-         ret = try_use_bios(path, true);
-         if (ret)
+         try_use_bios(path, path_size, true);
+         if (bios_saved[0] && bios_saved[1] && bios_saved[2])
             goto finish;
       }
    }
@@ -3534,19 +3557,17 @@ static bool find_any_bios(const char *dirpath, char *path, size_t path_size)
          if ((strncasecmp(ent->d_name, substr, strlen(substr)) != 0))
             continue;
          snprintf(path, path_size, "%s%c%s", dirpath, SLASH, ent->d_name);
-         ret = try_use_bios(path, false);
-         if (ret)
+         try_use_bios(path, path_size, false);
+         if (bios_saved[0] && bios_saved[1] && bios_saved[2])
             goto finish;
       }
    }
 
-
 finish:
    closedir(dir);
-   return ret;
 }
 #else
-#define find_any_bios(...) false
+#define find_any_bios(...)
 #endif
 
 static void check_system_specs(void)
@@ -3601,76 +3622,101 @@ static int init_memcards(void)
    return ret;
 }
 
-static void loadPSXBios(void)
+static bool get_bios_config_hle(void)
 {
-   const char *dir;
-   char path[PATH_MAX];
-   unsigned useHLE = 0;
-
-   const char *bios[] = {
-      "PSXONPSP660", "psxonpsp660",
-      "SCPH101", "scph101",
-      "SCPH5501", "scph5501",
-      "SCPH7001", "scph7001",
-      "SCPH1001", "scph1001"
-   };
-
-   struct retro_variable var = {
-      .key = "pcsx_rearmed_bios",
-      .value = NULL
-   };
-
-   found_bios = 0;
+   struct retro_variable var = { NULL, };
+   bool use_hle = false;
 
+   var.key = "pcsx_rearmed_bios";
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
    {
       if (!strcmp(var.value, "HLE"))
-         useHLE = 1;
+         use_hle = true;
    }
 
-   if (!useHLE)
+   Config.SlowBoot = 0;
+   if (!use_hle)
    {
-      if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
+      var.value = NULL;
+      var.key = "pcsx_rearmed_show_bios_bootlogo";
+      if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
       {
-         unsigned i;
-         snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s", dir);
+         if (strcmp(var.value, "enabled") == 0)
+            Config.SlowBoot = 1;
+         else if (strcmp(var.value, "enabled_no_pcsx") == 0)
+            Config.SlowBoot = 2;
+      }
+   }
+   return use_hle;
+}
 
-         for (i = 0; i < sizeof(bios) / sizeof(bios[0]); i++)
-         {
-            snprintf(path, sizeof(path), "%s%c%s.bin", dir, SLASH, bios[i]);
-            found_bios = try_use_bios(path, true);
-            if (found_bios)
-               break;
+static void prepare_bios(bool use_hle)
+{
+   size_t i, count = sizeof(bios_saved) / sizeof(bios_saved[0]);
+   assert(count == sizeof(Config.Bios) / sizeof(Config.Bios[0]));
+   for (i = 0; i < count; i++) {
+      Config.Bios[i][0] = 0;
+      if (bios_saved[i] && !use_hle) {
+         int r = snprintf(Config.Bios[i], sizeof(Config.Bios[i]), "%s", bios_saved[i]);
+         if (r >= sizeof(Config.Bios[i])) {
+            LogErr("BIOS '%s' name is too long, discarding\n", bios_saved[i]);
+            Config.Bios[i][0] = 0;
          }
-
-         if (!found_bios)
-            found_bios = find_any_bios(dir, path, sizeof(path));
-      }
-      if (found_bios)
-      {
-         SysPrintf("found BIOS file: %s\n", Config.Bios);
       }
    }
+}
+
+static void loadPSXBios(void)
+{
+   char path[PATH_MAX];
+   const char *dir;
+   const char *msg_str = NULL;
+   unsigned duration = 0;
+   const char * const us_bios[] = {
+      "PSXONPSP660", "psxonpsp660",
+      "SCPH101", "scph101",
+      "SCPH5501", "scph5501",
+      "SCPH7001", "scph7001",
+      "SCPH1001", "scph1001"
+   };
+   bool use_hle = get_bios_config_hle();
+   enum retro_log_level level = RETRO_LOG_INFO;
 
-   if (!found_bios)
+   if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
    {
-      const char *msg_str;
-      unsigned duration;
-      if (useHLE)
-      {
-         msg_str = "BIOS set to \'hle\'";
-         SysPrintf("Using HLE BIOS.\n");
-         // shorter as the user probably intentionally wants to use HLE
-         duration = 700;
-      }
-      else
+      unsigned i;
+      snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s", dir);
+
+      for (i = 0; i < sizeof(us_bios) / sizeof(us_bios[0]); i++)
       {
-         msg_str = "No PlayStation BIOS file found - add for better compatibility";
-         SysPrintf("No BIOS files found.\n");
-         duration = 3000;
+         bool found_bios;
+         snprintf(path, sizeof(path), "%s%c%s.bin", dir, SLASH, us_bios[i]);
+         found_bios = try_use_bios(path, sizeof(path), true);
+         if (found_bios)
+            break;
       }
-      show_notification(msg_str, duration, 2);
+
+      find_any_bios(dir, path, sizeof(path));
+   }
+
+   prepare_bios(use_hle);
+
+   if (use_hle)
+   {
+      msg_str = "BIOS set to \'hle\'";
+      SysPrintf("Using HLE BIOS.\n");
+      // shorter as the user probably intentionally wants to use HLE
+      duration = 700;
    }
+   else if (!bios_saved[0] && !bios_saved[1] && !bios_saved[2])
+   {
+      msg_str = "No PlayStation BIOS file found - add for better compatibility";
+      SysPrintf("No BIOS files found.\n");
+      duration = 3000;
+      level = RETRO_LOG_WARN;
+   }
+   if (msg_str)
+      show_notification(msg_str, duration, 2, level);
 }
 
 void retro_init(void)
@@ -3778,6 +3824,8 @@ void retro_init(void)
 
 void retro_deinit(void)
 {
+   size_t i;
+
    if (plugins_opened)
    {
       ClosePlugins();
@@ -3805,6 +3853,10 @@ void retro_deinit(void)
 #ifdef GPU_UNAI
    show_advanced_gpu_unai_settings = true;
 #endif
+   for (i = 0; i < ARRAY_SIZE(bios_saved); i++) {
+      free(bios_saved[i]);
+      bios_saved[i] = NULL;
+   }
 
    /* Have to reset disks struct, otherwise
     * fnames/flabels will leak memory */
index 46b1883..95ea4ab 100644 (file)
@@ -139,7 +139,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
       "pcsx_rearmed_show_bios_bootlogo",
       "Show BIOS Boot Logo",
       NULL,
-      "When using an official BIOS file, specify whether to show the PlayStation logo upon starting or resetting content. Warning: Enabling the boot logo may reduce game compatibility.",
+      "When using an official BIOS file, specify whether to show the PlayStation logo upon starting or resetting content. Also enables the display of BIOS file name in OSD. Warning: Enabling the boot logo may reduce game compatibility.",
       NULL,
       "system",
       {
index 77b3d74..2040f7c 100644 (file)
@@ -445,7 +445,7 @@ int emu_core_preinit(void)
 
        set_default_paths();
        emu_set_default_config();
-       strcpy(Config.Bios, "HLE");
+       strcpy(Config.Bios[0], "HLE");
 
        return 0;
 }
index 809e1d4..436c104 100644 (file)
@@ -373,14 +373,11 @@ static void menu_set_defconfig(void)
 }
 
 #define CE_CONFIG_STR(val) \
-       { #val, 0, Config.val }
+       { #val, sizeof(Config.val), Config.val }
 
 #define CE_CONFIG_VAL(val) \
        { #val, sizeof(Config.val), &Config.val }
 
-#define CE_STR(val) \
-       { #val, 0, val }
-
 #define CE_INTVAL(val) \
        { #val, sizeof(val), &val }
 
@@ -392,7 +389,7 @@ static void menu_set_defconfig(void)
 
 // 'versioned' var, used when defaults change
 #define CE_CONFIG_STR_V(val, ver) \
-       { #val #ver, 0, Config.val }
+       { #val #ver, sizeof(Config.val), Config.val }
 
 #define CE_INTVAL_V(val, ver) \
        { #val #ver, sizeof(val), &val }
@@ -405,7 +402,7 @@ static const struct {
        size_t len;
        void *val;
 } config_data[] = {
-       CE_CONFIG_STR(Bios),
+       { "Bios", sizeof(Config.Bios[0]), Config.Bios[0] },
        CE_CONFIG_STR_V(Gpu, 3),
        CE_CONFIG_STR(Spu),
 //     CE_CONFIG_STR(Cdr),
@@ -548,10 +545,11 @@ static int menu_write_config(int is_game)
 
        for (i = 0; i < ARRAY_SIZE(config_data); i++) {
                fprintf(f, "%s = ", config_data[i].name);
-               switch (config_data[i].len) {
-               case 0:
+               if (config_data[i].len > 8) { // string
                        fprintf(f, "%s\n", (char *)config_data[i].val);
-                       break;
+                       continue;
+               }
+               switch (config_data[i].len) {
                case 1:
                        write_u32_value(f, *(u8 *)config_data[i].val);
                        break;
@@ -612,16 +610,20 @@ out:
        return 0;
 }
 
-static void parse_str_val(char *cval, const char *src)
+static void parse_str_val(char *cval, size_t len, const char *src)
 {
-       char *tmp;
-       strncpy(cval, src, MAXPATHLEN);
-       cval[MAXPATHLEN - 1] = 0;
-       tmp = strchr(cval, '\n');
+       const char *tmp;
+       len--;
+       tmp = strchr(src, '\n');
        if (tmp == NULL)
-               tmp = strchr(cval, '\r');
-       if (tmp != NULL)
-               *tmp = 0;
+               tmp = strchr(src, '\r');
+       if (tmp != NULL) {
+               size_t l1 = tmp - src;
+               if (len > l1)
+                       len = l1;
+       }
+       memcpy(cval, src, len);
+       cval[len] = 0;
 }
 
 static void keys_load_all(const char *cfg);
@@ -671,8 +673,8 @@ int menu_load_config(int is_game)
                        continue;
                tmp += 3;
 
-               if (config_data[i].len == 0) {
-                       parse_str_val(config_data[i].val, tmp);
+               if (config_data[i].len > 8) {
+                       parse_str_val(config_data[i].val, config_data[i].len, tmp);
                        continue;
                }
 
@@ -702,7 +704,7 @@ int menu_load_config(int is_game)
                char *tmp = strstr(cfg, "lastcdimg = ");
                if (tmp != NULL) {
                        tmp += 12;
-                       parse_str_val(last_selected_fname, tmp);
+                       parse_str_val(last_selected_fname, sizeof(last_selected_fname), tmp);
                }
        }
 
@@ -719,7 +721,7 @@ fail:
 
        // sync plugins
        for (i = bios_sel = 0; bioses[i] != NULL; i++)
-               if (strcmp(Config.Bios, bioses[i]) == 0)
+               if (strcmp(Config.Bios[0], bioses[i]) == 0)
                        { bios_sel = i; break; }
 
        for (i = gpu_plugsel = 0; gpu_plugins[i] != NULL; i++)
@@ -1634,7 +1636,7 @@ static int menu_loop_plugin_options(int id, int keys)
        Config.SlowBoot = slowboot_sel;
 
        // sync BIOS/plugins
-       snprintf(Config.Bios, sizeof(Config.Bios), "%s", bioses[bios_sel]);
+       snprintf(Config.Bios[0], sizeof(Config.Bios[0]), "%s", bioses[bios_sel]);
        snprintf(Config.Gpu, sizeof(Config.Gpu), "%s", gpu_plugins[gpu_plugsel]);
        snprintf(Config.Spu, sizeof(Config.Spu), "%s", spu_plugins[spu_plugsel]);
        me_enable(e_menu_main2, MA_MAIN_RUN_BIOS, bios_sel != 0);
@@ -2174,6 +2176,9 @@ static int run_exe(void)
        if (fname == NULL)
                return -1;
 
+       Config.PsxRegion = PSX_REGION_US;
+       Config.PsxType = PSX_TYPE_NTSC;
+
        ready_to_go = 0;
        if (reload_plugins(NULL) != 0)
                return -1;
@@ -2490,7 +2495,7 @@ void menu_loop(void)
                // assume first run
                if (bioses[1] != NULL) {
                        // autoselect BIOS to make user's life easier
-                       snprintf(Config.Bios, sizeof(Config.Bios), "%s", bioses[1]);
+                       snprintf(Config.Bios[0], sizeof(Config.Bios[0]), "%s", bioses[1]);
                        bios_sel = 1;
                }
                else if (!warned_about_bios) {
index 6c10c25..3bb4a5c 100644 (file)
@@ -372,13 +372,19 @@ int CheckCdrom() {
        char *buf;
        unsigned char mdir[4096];
        char exename[256];
-       int lic_region_detected = -1;
-       int i, len, c;
+       int psxtype_from_lic = -1;
+       struct { u8 region; const char *str; } lic_strings[] = {
+               { PSX_REGION_JP, "Inc." },
+               { PSX_REGION_US, "Amer  ica" },
+               { PSX_REGION_EU, "Euro pe" }
+       };
+       size_t i, len, c;
 
        FreePPFCache();
        memset(CdromLabel, 0, sizeof(CdromLabel));
        memset(CdromId, 0, sizeof(CdromId));
        memset(exename, 0, sizeof(exename));
+       Config.PsxRegion = PSX_REGION_US;
 
        if (!Config.HLE && Config.SlowBoot) {
                // boot to BIOS in case of CDDA or lid is open
@@ -386,15 +392,21 @@ int CheckCdrom() {
                if ((stat.Status & 0x10) || stat.Type == 2 || cdra_readTrack(time))
                        return 0;
        }
-       if (Config.PsxAuto) {
-               time[0] = 0;
-               time[1] = 2;
-               time[2] = 4;
-               READTRACK();
-               if (strcmp((char *)buf + 12 + 46, "Entertainment Euro pe   ") == 0)
-                       lic_region_detected = PSX_TYPE_PAL;
-               // else it'll default to NTSC anyway
+       time[0] = 0;
+       time[1] = 2;
+       time[2] = 4;
+       READTRACK();
+       for (i = 0; i < sizeof(lic_strings) / sizeof(lic_strings[0]); i++) {
+               len = strlen(lic_strings[i].str);
+               if (strncmp((char *)buf + 12 + 60, lic_strings[i].str, len) == 0) {
+                       Config.PsxRegion = lic_strings[i].region;
+                       psxtype_from_lic = Config.PsxRegion == PSX_REGION_EU
+                               ? PSX_TYPE_PAL : PSX_TYPE_NTSC;
+                       break;
+               }
        }
+       if (psxtype_from_lic < 0)
+               SysPrintf("CheckCdrom: missing lic sector?\n");
 
        time[0] = 0;
        time[1] = 2;
@@ -435,7 +447,7 @@ int CheckCdrom() {
                /* Workaround for Wild Arms EU/US which has non-standard string causing incorrect region detection */
                if (exename[0] == 'E' && exename[1] == 'X' && exename[2] == 'E' && exename[3] == '\\') {
                        size_t offset = 4;
-                       size_t i, len = strlen(exename) - offset;
+                       len = strlen(exename) - offset;
                        for (i = 0; i < len; i++)
                                exename[i] = exename[i + offset];
                        exename[i] = '\0';
@@ -461,8 +473,8 @@ int CheckCdrom() {
                strcpy(CdromId, "SLUS99999");
 
        if (Config.PsxAuto) { // autodetect system (pal or ntsc)
-               if (lic_region_detected >= 0)
-                       Config.PsxType = lic_region_detected;
+               if (psxtype_from_lic >= 0)
+                       Config.PsxType = psxtype_from_lic;
                else if (
                        /* Make sure Wild Arms SCUS-94608 is not detected as a PAL game. */
                        ((CdromId[0] == 's' || CdromId[0] == 'S') && (CdromId[2] == 'e' || CdromId[2] == 'E')) ||
index 500cc27..de3768f 100644 (file)
@@ -4116,6 +4116,8 @@ void psxBiosInit() {
        ram32[A_RCNT_VBL_ACK/4 + 2] = SWAP32(1);
        ram32[A_RCNT_VBL_ACK/4 + 3] = SWAP32(1);
        ram32[A_RND_SEED/4] = SWAPu32(0x24040001); // was 0xac20cc00
+
+       SysPrintf("HLE BIOS initialized.\n");
 }
 
 void psxBiosShutdown() {
index 7b59c22..845fc61 100644 (file)
@@ -106,13 +106,15 @@ typedef uint8_t boolean;
 // don't change unless you're going to retest hundreds of games
 #define CYCLE_MULT_DEFAULT 175
 
+#define PSX_REGION_COUNT 3
+
 typedef struct {
        char Gpu[MAXPATHLEN];
        char Spu[MAXPATHLEN];
        char Sio1[MAXPATHLEN];
        char Mcd1[MAXPATHLEN];
        char Mcd2[MAXPATHLEN];
-       char Bios[MAXPATHLEN];
+       char Bios[PSX_REGION_COUNT][64]; // us, jp, eu; see psxMemReset()
        char BiosDir[MAXPATHLEN];
        char PluginsDir[MAXPATHLEN];
        char PatchesDir[MAXPATHLEN];
@@ -136,6 +138,7 @@ typedef struct {
        s8 FractionalFramerate; // ~49.75 and ~59.81 instead of 50 and 60
        u8 Cpu; // CPU_DYNAREC or CPU_INTERPRETER
        u8 PsxType; // PSX_TYPE_NTSC or PSX_TYPE_PAL
+       u8 PsxRegion; // PSX_REGION_US, PSX_REGION_JP, PSX_REGION_EU
        struct {
                boolean cdr_read_timing;
                boolean gpu_slow_list_walking;
@@ -169,6 +172,12 @@ enum {
        PSX_TYPE_PAL
 }; // PSX Types
 
+enum {
+       PSX_REGION_US = 0,
+       PSX_REGION_JP,
+       PSX_REGION_EU
+};
+
 enum {
        CPU_DYNAREC = 0,
        CPU_INTERPRETER
index 76e555e..e2f49ea 100644 (file)
@@ -287,6 +287,8 @@ int psxMemInit(void)
 }
 
 void psxMemReset() {
+       size_t count = sizeof(Config.Bios) / sizeof(Config.Bios[0]);
+       size_t i, r = Config.PsxRegion, rret;
        FILE *f = NULL;
        char bios[1024];
 
@@ -298,20 +300,26 @@ void psxMemReset() {
 
        Config.HLE = TRUE;
 
-       if (strcmp(Config.Bios, "HLE") != 0) {
-               sprintf(bios, "%s/%s", Config.BiosDir, Config.Bios);
+       // prefer wrong region bios to HLE
+       for (i = 0; i < count; i++, r++) {
+               if (r >= count)
+                       r = 0;
+               if (!Config.Bios[r][0] || strcmp(Config.Bios[r], "HLE") == 0)
+                       continue;
+               snprintf(bios, sizeof(bios), "%s/%s", Config.BiosDir, Config.Bios[r]);
                f = fopen(bios, "rb");
-
                if (f == NULL) {
-                       SysMessage(_("Could not open BIOS:\"%s\". Enabling HLE Bios!\n"), bios);
-               } else {
-                       if (fread(psxRegs.ptrs.psxR, 1, 0x80000, f) == 0x80000) {
-                               Config.HLE = FALSE;
-                       } else {
-                               SysMessage(_("The selected BIOS:\"%s\" is of wrong size. Enabling HLE Bios!\n"), bios);
-                       }
-                       fclose(f);
+                       SysMessage("Could not open BIOS: \"%s\"\n", bios);
+                       continue;
+               }
+               rret = fread(psxRegs.ptrs.psxR, 1, 0x80000, f);
+               fclose(f);
+               if (rret == 0x80000) {
+                       SysMessage("Loaded BIOS \"%s\".\n", bios);
+                       Config.HLE = FALSE;
+                       break;
                }
+               SysMessage("BIOS \"%s\" is of wrong size, skipping.\n", bios);
        }
        if (Config.HLE)
                memset(psxRegs.ptrs.psxR, 0, 0x80000);
index 44fec65..3917f9e 100644 (file)
@@ -192,7 +192,7 @@ int main(int argc, char **argv)
        snprintf(Config.PatchesDir, sizeof(Config.PatchesDir), "/opt/maemo/usr/games" PATCHES_DIR);
        Config.PsxAuto = 1;
        pl_rearmed_cbs.frameskip = -1;
-       strcpy(Config.Bios, "HLE");
+       strcpy(Config.Bios[0], "HLE");
        spu_config.iUseReverb = 1;
        spu_config.iUseInterpolation = 1;
        in_type1 = PSE_PAD_TYPE_STANDARD;
@@ -243,7 +243,7 @@ int main(int argc, char **argv)
                else if (!strcmp(argv[i], "-nosound"))                  strcpy(Config.Spu, "spunull.so");
                else if (!strcmp(argv[i], "-bdir"))                     sprintf(Config.BiosDir, "%s", argv[++i]);
                else if (!strcmp(argv[i], "-pdir"))                             sprintf(Config.PluginsDir, "%s", argv[++i]);
-               else if (!strcmp(argv[i], "-bios"))                     sprintf(Config.Bios, "%s", argv[++i]);
+               else if (!strcmp(argv[i], "-bios"))                     sprintf(Config.Bios[0], "%s", argv[++i]);
                else if (!strcmp(argv[i], "-gles"))                             { strcpy(Config.Gpu, "gpu_gles.so"); g_maemo_opts |= 8 ;}
                else if (!strcmp(argv[i], "-oldgpu"))                   strcpy(Config.Gpu, "gpu_peops.so");
                else if (!strcmp(argv[i], "-unai"))                         strcpy(Config.Gpu, "gpu_unai.so");