Add BIOS core option, selects between using HLE or real bios file
[pcsx_rearmed.git] / frontend / libretro.c
index f96ccf2..6017117 100644 (file)
@@ -22,6 +22,7 @@
 #include "../libpcsxcore/cdrom.h"
 #include "../libpcsxcore/cdriso.h"
 #include "../libpcsxcore/cheat.h"
+#include "../libpcsxcore/r3000a.h"
 #include "../plugins/dfsound/out.h"
 #include "../plugins/dfsound/spu_config.h"
 #include "../plugins/dfinput/externals.h"
@@ -57,7 +58,7 @@ static retro_input_poll_t input_poll_cb;
 static retro_input_state_t input_state_cb;
 static retro_environment_t environ_cb;
 static retro_audio_sample_batch_t audio_batch_cb;
-static struct retro_rumble_interface rumble;
+static retro_set_rumble_state_t rumble_cb;
 static struct retro_log_callback logging;
 static retro_log_printf_t log_cb;
 
@@ -430,10 +431,13 @@ void pl_timing_prepare(int is_pal)
 
 void plat_trigger_vibrate(int pad, int low, int high)
 {
-       if(in_enable_vibration)
+       if (!rumble_cb)
+               return;
+
+       if (in_enable_vibration)
        {
-       rumble.set_rumble_state(pad, RETRO_RUMBLE_STRONG, high << 8);
-       rumble.set_rumble_state(pad, RETRO_RUMBLE_WEAK, low ? 0xffff : 0x0);
+               rumble_cb(pad, RETRO_RUMBLE_STRONG, high << 8);
+               rumble_cb(pad, RETRO_RUMBLE_WEAK, low ? 0xffff : 0x0);
     }
 }
 
@@ -462,6 +466,7 @@ void retro_set_environment(retro_environment_t cb)
 {
    static const struct retro_variable vars[] = {
       { "pcsx_rearmed_frameskip", "Frameskip; 0|1|2|3" },
+      { "pcsx_rearmed_bios", "Use BIOS; auto|HLE" },
       { "pcsx_rearmed_region", "Region; auto|NTSC|PAL" },
       { "pcsx_rearmed_memcard2", "Enable second memory card; disabled|enabled" },
       { "pcsx_rearmed_pad1type", "Pad 1 Type; default|none|standard|analog|dualshock|negcon" },
@@ -481,7 +486,7 @@ void retro_set_environment(retro_environment_t cb)
 #ifndef DRC_DISABLE
       { "pcsx_rearmed_drc", "Dynamic recompiler; enabled|disabled" },
 #endif
-#if defined(__ARM_NEON__) && !defined(__aarch64__)
+#ifdef __ARM_NEON__
       { "pcsx_rearmed_neon_interlace_enable", "Enable interlacing mode(s); disabled|enabled" },
       { "pcsx_rearmed_neon_enhancement_enable", "Enhanced resolution (slow); disabled|enabled" },
       { "pcsx_rearmed_neon_enhancement_no_main", "Enhanced resolution speed hack; disabled|enabled" },
@@ -1286,7 +1291,10 @@ bool retro_load_game(const struct retro_game_info *info)
                return false;
        }
 
-       SysReset();
+       /* TODO: Calling SysReset() outside retro_run for some system
+        * causes RetroArch to freeze, e.g Ludo */
+       //SysReset();
+       rebootemu = 1;
 
        if (LoadCdrom() == -1) {
                log_cb(RETRO_LOG_INFO, "could not load CD\n");
@@ -1576,7 +1584,9 @@ static void update_variables(bool in_flight)
          if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
          {
             if (strcmp(var.value, "enabled") == 0)
-               rebootemu = 1;
+               Config.SlowBoot = 1;
+            else
+               Config.SlowBoot = 0;
          }
       }
    }
@@ -1616,11 +1626,15 @@ static uint16_t get_analog_button(retro_input_state_t input_state_cb, int player
 
 void retro_run(void)
 {
-    int i;
-    //SysReset must be run while core is running,Not in menu (Locks up Retroarch)
-    if(rebootemu != 0){
-      rebootemu = 0;
-      SysReset();
+       int i;
+       //SysReset must be run while core is running,Not in menu (Locks up Retroarch)
+       if (rebootemu != 0) {
+               rebootemu = 0;
+               SysReset();
+               if (!Config.HLE && !Config.SlowBoot) {
+                       // skip BIOS logos
+                       psxRegs.pc = psxRegs.GPR.n.ra;
+               }
     }
 
        input_poll_cb();
@@ -1881,17 +1895,67 @@ static int init_memcards(void)
        return ret;
 }
 
-void retro_init(void)
+static void loadPSXBios(void)
 {
+       const char *dir;
+       char path[256];
+       unsigned useHLE = 0;
+
        const char *bios[] = {
                "SCPH101", "SCPH7001", "SCPH5501", "SCPH1001",
                "scph101", "scph7001", "scph5501", "scph1001"
        };
-       const char *dir;
-       char path[256];
-       int i, ret;
-   
-   found_bios = false;
+
+       struct retro_variable var = {
+               .key = "pcsx_rearmed_bios",
+               .value = NULL
+       };
+
+       found_bios = 0;
+
+       if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+               if (!strcmp(var.value, "HLE"))
+                       useHLE = 1;
+       }
+
+       if (!useHLE)
+       {
+               if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
+               {
+                       unsigned i;
+                       snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s", dir);
+
+                       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);
+                               if (found_bios)
+                                       break;
+                       }
+
+                       if (!found_bios)
+                               found_bios = find_any_bios(dir, path, sizeof(path));
+               }
+               if (found_bios) {
+                       SysPrintf("found BIOS file: %s\n", Config.Bios);
+               }
+       }
+
+       if (useHLE || !found_bios)
+       {
+               SysPrintf("no BIOS files found.\n");
+               struct retro_message msg =
+               {
+                       "No PlayStation BIOS file found - add for better compatibility",
+                       180
+               };
+               environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg);
+       }
+}
+
+void retro_init(void)
+{
+       struct retro_rumble_interface rumble;
+       int ret;
 
 #ifdef __MACH__
        // magic sauce to make the dynarec work on iOS
@@ -1930,39 +1994,16 @@ void retro_init(void)
        vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
 #endif
   
-  vout_buf_ptr = vout_buf;
-  
-       if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
-       {
-               snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s", dir);
-
-               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);
-                       if (found_bios)
-                               break;
-               }
+       vout_buf_ptr = vout_buf;
 
-               if (!found_bios)
-                       found_bios = find_any_bios(dir, path, sizeof(path));
-       }
-       if (found_bios) {
-               SysPrintf("found BIOS file: %s\n", Config.Bios);
-       }
-       else
-       {
-               SysPrintf("no BIOS files found.\n");
-               struct retro_message msg =
-               {
-                       "No PlayStation BIOS file found - add for better compatibility",
-                       180
-               };
-               environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg);
-       }
+       loadPSXBios();
 
        environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &vout_can_dupe);
        environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control);
-       environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble);
+
+       rumble_cb = NULL;
+       if (environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble))
+               rumble_cb = rumble.set_rumble_state;
 
        /* Set how much slower PSX CPU runs * 100 (so that 200 is 2 times)
         * we have to do this because cache misses and some IO penalties