libretro: try to fix enhancement
[pcsx_rearmed.git] / frontend / libretro.c
index 7a7c2ef..1e9929d 100644 (file)
@@ -5,6 +5,7 @@
  * See the COPYING file in the top-level directory.
  */
 
+#define _GNU_SOURCE 1 // strcasestr
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -17,6 +18,7 @@
 #include "../libpcsxcore/cdriso.h"
 #include "../libpcsxcore/cheat.h"
 #include "../plugins/dfsound/out.h"
+#include "../plugins/dfinput/externals.h"
 #include "cspace.h"
 #include "main.h"
 #include "plugin.h"
@@ -49,6 +51,10 @@ int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 };
 int in_keystate;
 int in_enable_vibration;
 
+/* PSX max resolution is 640x512, but with enhancement it's 1024x512 */
+#define VOUT_MAX_WIDTH 1024
+#define VOUT_MAX_HEIGHT 512
+
 static void init_memcard(char *mcd_data)
 {
        unsigned off = 0;
@@ -230,7 +236,25 @@ void out_register_libretro(struct out_driver *drv)
 }
 
 /* libretro */
-void retro_set_environment(retro_environment_t cb) { environ_cb = cb; }
+void retro_set_environment(retro_environment_t cb)
+{
+   static const struct retro_variable vars[] = {
+      { "frameskip", "Frameskip; 0|1|2|3" },
+      { "region", "Region; Auto|NTSC|PAL" },
+#ifdef __ARM_NEON__
+      { "neon_interlace_enable", "Enable interlacing mode(s); disabled|enabled" },
+#if 0
+      { "neon_enhancement_enable", "Enhanced resolution (slow); disabled|enabled" },
+#endif
+#endif
+      { NULL, NULL },
+   };
+
+   environ_cb = cb;
+
+   cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars);
+}
+
 void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; }
 void retro_set_audio_sample(retro_audio_sample_t cb) { (void)cb; }
 void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_batch_cb = cb; }
@@ -262,8 +286,8 @@ void retro_get_system_av_info(struct retro_system_av_info *info)
        info->timing.sample_rate    = 44100;
        info->geometry.base_width   = 320;
        info->geometry.base_height  = 240;
-       info->geometry.max_width    = 640;
-       info->geometry.max_height   = 512;
+       info->geometry.max_width    = VOUT_MAX_WIDTH;
+       info->geometry.max_height   = VOUT_MAX_HEIGHT;
        info->geometry.aspect_ratio = 4.0 / 3.0;
 }
 
@@ -710,11 +734,78 @@ static const unsigned short retro_psx_map[] = {
 };
 #define RETRO_PSX_MAP_LEN (sizeof(retro_psx_map) / sizeof(retro_psx_map[0]))
 
+static void update_variables(bool in_flight)
+{
+   struct retro_variable var;
+   
+   var.value = NULL;
+   var.key = "frameskip";
+
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+      pl_rearmed_cbs.frameskip = atoi(var.value);
+
+   var.value = NULL;
+   var.key = "region";
+
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+   {
+      Config.PsxAuto = 0;
+      if (strcmp(var.value, "Automatic") == 0)
+         Config.PsxAuto = 1;
+      else if (strcmp(var.value, "NTSC") == 0)
+         Config.PsxType = 0;
+      else if (strcmp(var.value, "PAL") == 0)
+         Config.PsxType = 1;
+   }
+#ifdef __ARM_NEON__
+   var.value = "NULL";
+   var.key = "neon_interlace_enable";
+
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+   {
+      if (strcmp(var.value, "disabled") == 0)
+         pl_rearmed_cbs.gpu_neon.allow_interlace = 0;
+      else if (strcmp(var.value, "enabled") == 0)
+         pl_rearmed_cbs.gpu_neon.allow_interlace = 1;
+   }
+
+#if 0
+   var.value = NULL;
+   var.key = "neon_enhancement_enable";
+
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+   {
+      if (strcmp(var.value, "disabled") == 0)
+         pl_rearmed_cbs.gpu_neon.enhancement_enable = 0;
+      else if (strcmp(var.value, "enabled") == 0)
+         pl_rearmed_cbs.gpu_neon.enhancement_enable = 1;
+   }
+#endif
+#endif
+
+       if (in_flight) {
+               // inform core things about possible config changes
+               plugin_call_rearmed_cbs();
+
+               if (GPU_open != NULL && GPU_close != NULL) {
+                       GPU_close();
+                       GPU_open(&gpuDisp, "PCSX", NULL);
+               }
+       }
+
+       dfinput_activate();
+}
+
 void retro_run(void) 
 {
        int i;
 
        input_poll_cb();
+
+       bool updated = false;
+       if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
+               update_variables(true);
+
        in_keystate = 0;
        for (i = 0; i < RETRO_PSX_MAP_LEN; i++)
                if (input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, i))
@@ -749,7 +840,7 @@ void retro_init(void)
                exit(1);
        }
 
-       vout_buf = malloc(640 * 512 * 2);
+       vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
 
        if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
        {
@@ -769,7 +860,15 @@ void retro_init(void)
                fclose(f);
        }
        else
+   {
                SysPrintf("no BIOS files found.\n");
+      struct retro_message msg = 
+      {
+         "no BIOS found, expect bugs!",
+         180
+      };
+      environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg);
+   }
 
        level = 1;
        environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level);
@@ -795,6 +894,8 @@ void retro_init(void)
        SaveFuncs.write = save_write;
        SaveFuncs.seek = save_seek;
        SaveFuncs.close = save_close;
+
+       update_variables(false);
 }
 
 void retro_deinit(void)