Merge branch 'mainline' into libretro
[pcsx_rearmed.git] / frontend / libretro.c
index 936776e..1e86509 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
+#ifdef __MACH__
+#include <unistd.h>
+#include <sys/syscall.h>
+#endif
 
 #include "../libpcsxcore/misc.h"
 #include "../libpcsxcore/psxcounters.h"
@@ -56,10 +60,10 @@ extern char Mcd1Data[MCD_SIZE];
 extern char McdDisable[2];
 
 /* PCSX ReARMed core calls and stuff */
-int in_type[8] =  { PSE_PAD_TYPE_STANDARD, PSE_PAD_TYPE_STANDARD,
-                  PSE_PAD_TYPE_STANDARD, PSE_PAD_TYPE_STANDARD,
-                  PSE_PAD_TYPE_STANDARD, PSE_PAD_TYPE_STANDARD,
-                  PSE_PAD_TYPE_STANDARD, PSE_PAD_TYPE_STANDARD };
+int in_type[8] =  { PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE,
+                  PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE,
+                  PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE,
+                  PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE };
 int in_analog_left[8][2] = {{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 }};
 int in_analog_right[8][2] = {{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 }};
 unsigned short in_keystate[PORTS_NUMBER];
@@ -256,6 +260,85 @@ void pl_3ds_munmap(void *ptr, size_t size, enum psxMapTag tag)
 }
 #endif
 
+#ifdef VITA
+typedef struct
+{
+   void* buffer;
+   uint32_t target_map;
+   size_t size;
+   enum psxMapTag tag;
+}psx_map_t;
+
+psx_map_t custom_psx_maps[] = {
+   {NULL, NULL, 0x210000, MAP_TAG_RAM},   // 0x80000000
+   {NULL, NULL, 0x010000, MAP_TAG_OTHER}, // 0x1f800000
+   {NULL, NULL, 0x080000, MAP_TAG_OTHER}, // 0x1fc00000
+   {NULL, NULL, 0x800000, MAP_TAG_LUTS},  // 0x08000000
+   {NULL, NULL, 0x200000, MAP_TAG_VRAM},  // 0x00000000
+};
+
+void* pl_vita_mmap(unsigned long addr, size_t size, int is_fixed,
+       enum psxMapTag tag)
+{
+   (void)is_fixed;
+   (void)addr;
+
+
+    psx_map_t* custom_map = custom_psx_maps;
+
+    for (; custom_map->size; custom_map++)
+    {
+       if ((custom_map->size == size) && (custom_map->tag == tag))
+       {
+          int block, ret;
+          char blockname[32];
+          sprintf(blockname, "CODE 0x%08X",tag);
+
+          block = sceKernelAllocMemBlock(blockname, size + 0x1000);
+          if(block<=0){
+            sceClibPrintf("could not alloc mem block @0x%08X 0x%08X \n", block, tag);
+            exit(1);
+          }
+
+          // get base address
+          ret = sceKernelGetMemBlockBase(block, &custom_map->buffer);
+          if (ret < 0)
+          {
+            sceClibPrintf("could get address @0x%08X 0x%08X 0x%08X \n", block, ret, tag);
+            exit(1);
+          }
+          custom_map->buffer = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF;
+          custom_map->target_map = block;
+
+          return custom_map->buffer;
+       }
+    }
+
+
+   return malloc(size);
+}
+
+void pl_vita_munmap(void *ptr, size_t size, enum psxMapTag tag)
+{
+   (void)tag;
+
+   psx_map_t* custom_map = custom_psx_maps;
+
+  for (; custom_map->size; custom_map++)
+  {
+     if ((custom_map->buffer == ptr))
+     {
+        sceKernelFreeMemBlock(custom_map->target_map);
+        custom_map->buffer = NULL;
+        custom_map->target_map = NULL;
+        return;
+     }
+  }
+
+   free(ptr);
+}
+#endif
+
 static void *pl_mmap(unsigned int size)
 {
        return psxMap(0, size, 0, MAP_TAG_VRAM);
@@ -377,43 +460,53 @@ unsigned retro_api_version(void)
        return RETRO_API_VERSION;
 }
 
-static void update_controller_port_device(unsigned port, unsigned device)
+static int controller_port_variable(unsigned port, struct retro_variable *var)
 {
        if (port >= PORTS_NUMBER)
-               return;
+               return 0;
 
-       struct retro_variable var;
-       int default_case = 0;
+       if (!environ_cb)
+               return 0;
 
-       var.value = NULL;
+       var->value = NULL;
        switch (port) {
        case 0:
-               var.key = "pcsx_rearmed_pad1type";
+               var->key = "pcsx_rearmed_pad1type";
                break;
        case 1:
-               var.key = "pcsx_rearmed_pad2type";
+               var->key = "pcsx_rearmed_pad2type";
                break;
        case 2:
-               var.key = "pcsx_rearmed_pad3type";
+               var->key = "pcsx_rearmed_pad3type";
                break;
        case 3:
-               var.key = "pcsx_rearmed_pad4type";
+               var->key = "pcsx_rearmed_pad4type";
                break;
        case 4:
-               var.key = "pcsx_rearmed_pad5type";
+               var->key = "pcsx_rearmed_pad5type";
                break;
        case 5:
-               var.key = "pcsx_rearmed_pad6type";
+               var->key = "pcsx_rearmed_pad6type";
                break;
        case 6:
-               var.key = "pcsx_rearmed_pad7type";
+               var->key = "pcsx_rearmed_pad7type";
                break;
        case 7:
-               var.key = "pcsx_rearmed_pad8type";
+               var->key = "pcsx_rearmed_pad8type";
                break;
        }
 
-       if (environ_cb && (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value))
+       return environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, var) || var->value;
+}
+
+static void update_controller_port_variable(unsigned port)
+{
+       if (port >= PORTS_NUMBER)
+               return;
+
+       struct retro_variable var;
+
+       if (controller_port_variable(port, &var))
        {
                if (strcmp(var.value, "standard") == 0)
                        in_type[0] = PSE_PAD_TYPE_STANDARD;
@@ -423,37 +516,47 @@ static void update_controller_port_device(unsigned port, unsigned device)
                        in_type[0] = PSE_PAD_TYPE_NEGCON;
                else if (strcmp(var.value, "none") == 0)
                        in_type[0] = PSE_PAD_TYPE_NONE;
-               else // 'default' case
-                       default_case = 1;
+               // else 'default' case, do nothing
        }
-       else
-               default_case = 1;
+}
 
-       if (default_case)
-               switch (device)
-               {
-               case RETRO_DEVICE_JOYPAD:
-                       in_type[port] = PSE_PAD_TYPE_STANDARD;
-                       break;
-               case RETRO_DEVICE_ANALOG:
-                       in_type[port] = PSE_PAD_TYPE_ANALOGPAD;
-                       break;
-               case RETRO_DEVICE_MOUSE:
-                       in_type[port] = PSE_PAD_TYPE_MOUSE;
-                       break;
-               case RETRO_DEVICE_LIGHTGUN:
-                       in_type[port] = PSE_PAD_TYPE_GUN;
-                       break;
-               case RETRO_DEVICE_NONE:
-               default:
-                       in_type[port] = PSE_PAD_TYPE_NONE;
-               }
+static void update_controller_port_device(unsigned port, unsigned device)
+{
+       if (port >= PORTS_NUMBER)
+               return;
+
+       struct retro_variable var;
+
+       if (!controller_port_variable(port, &var))
+               return;
+
+       if (strcmp(var.value, "default") != 0)
+               return;
+
+       switch (device)
+       {
+       case RETRO_DEVICE_JOYPAD:
+               in_type[port] = PSE_PAD_TYPE_STANDARD;
+               break;
+       case RETRO_DEVICE_ANALOG:
+               in_type[port] = PSE_PAD_TYPE_ANALOGPAD;
+               break;
+       case RETRO_DEVICE_MOUSE:
+               in_type[port] = PSE_PAD_TYPE_MOUSE;
+               break;
+       case RETRO_DEVICE_LIGHTGUN:
+               in_type[port] = PSE_PAD_TYPE_GUN;
+               break;
+       case RETRO_DEVICE_NONE:
+       default:
+               in_type[port] = PSE_PAD_TYPE_NONE;
+       }
 }
 
 static void update_multitap()
 {
        struct retro_variable var;
-       int auto_case;
+       int auto_case, port;
 
        var.value = NULL;
        var.key = "pcsx_rearmed_multitap1";
@@ -468,13 +571,13 @@ static void update_multitap()
                        auto_case = 1;
        }
        else
-               auto_case == 1;
+               auto_case = 1;
 
        if (auto_case)
        {
                // If a gamepad is plugged after port 2, we need a first multitap.
                multitap1 = 0;
-               for (int port = 2; port < PORTS_NUMBER; port++)
+               for (port = 2; port < PORTS_NUMBER; port++)
                        multitap1 |= in_type[port] != PSE_PAD_TYPE_NONE;
        }
 
@@ -491,13 +594,13 @@ static void update_multitap()
                        auto_case = 1;
        }
        else
-               auto_case == 1;
+               auto_case = 1;
 
        if (auto_case)
        {
                // If a gamepad is plugged after port 4, we need a second multitap.
                multitap2 = 0;
-               for (int port = 4; port < PORTS_NUMBER; port++)
+               for (port = 4; port < PORTS_NUMBER; port++)
                        multitap2 |= in_type[port] != PSE_PAD_TYPE_NONE;
        }
 }
@@ -1184,6 +1287,7 @@ static const unsigned short retro_psx_map[] = {
 static void update_variables(bool in_flight)
 {
    struct retro_variable var;
+   int i;
 
    var.value = NULL;
    var.key = "pcsx_rearmed_frameskip";
@@ -1203,8 +1307,8 @@ static void update_variables(bool in_flight)
          Config.PsxType = 1;
    }
 
-   for (int i = 0; i < PORTS_NUMBER; i++)
-      update_controller_port_device(i, RETRO_DEVICE_NONE);
+   for (i = 0; i < PORTS_NUMBER; i++)
+      update_controller_port_variable(i);
 
    update_multitap();
 
@@ -1450,9 +1554,18 @@ void retro_init(void)
        int i, ret;
        bool found_bios = false;
 
+#ifdef __MACH__
+       // magic sauce to make the dynarec work on iOS
+       syscall(SYS_ptrace, 0 /*PTRACE_TRACEME*/, 0, 0, 0);
+#endif
+
 #ifdef _3DS
    psxMapHook = pl_3ds_mmap;
    psxUnmapHook = pl_3ds_munmap;
+#endif
+#ifdef VITA
+   psxMapHook = pl_vita_mmap;
+   psxUnmapHook = pl_vita_munmap;
 #endif
        ret = emu_core_preinit();
 #ifdef _3DS