defaut dualshock to digital again, unless overriden
[pcsx_rearmed.git] / frontend / libretro.c
index 8a2447a..7f33157 100644 (file)
@@ -28,6 +28,7 @@
 #include "../libpcsxcore/cheat.h"
 #include "../libpcsxcore/r3000a.h"
 #include "../libpcsxcore/gpu.h"
+#include "../libpcsxcore/database.h"
 #include "../plugins/dfsound/out.h"
 #include "../plugins/dfsound/spu_config.h"
 #include "cspace.h"
@@ -79,7 +80,7 @@ static unsigned msg_interface_version = 0;
 
 static void *vout_buf;
 static void *vout_buf_ptr;
-static int vout_width, vout_height;
+static int vout_width = 256, vout_height = 240, vout_pitch = 256;
 static int vout_fb_dirty;
 static int psx_w, psx_h;
 static bool vout_can_dupe;
@@ -97,6 +98,7 @@ static bool show_advanced_gpu_peops_settings = true;
 static bool show_advanced_gpu_unai_settings = true;
 #endif
 static float mouse_sensitivity = 1.0f;
+static unsigned int disk_current_index;
 
 typedef enum
 {
@@ -143,7 +145,9 @@ int in_mouse[8][2];
 int multitap1 = 0;
 int multitap2 = 0;
 int in_enable_vibration = 1;
-int in_enable_crosshair[2] = { 0, 0 };
+static int in_enable_crosshair[2] = { 0, 0 };
+static bool in_dualshock_toggle_enable = 0;
+static bool in_dualshock_toggling = 0;
 
 // NegCon adjustment parameters
 // > The NegCon 'twist' action is somewhat awkward when mapped
@@ -232,8 +236,13 @@ static void set_vout_fb()
    fb.height         = vout_height;
    fb.access_flags   = RETRO_MEMORY_ACCESS_WRITE;
 
-   if (environ_cb(RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER, &fb) && fb.format == RETRO_PIXEL_FORMAT_RGB565)
-      vout_buf_ptr = (uint16_t *)fb.data;
+   vout_pitch = vout_width;
+   if (environ_cb(RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER, &fb) && fb.format == RETRO_PIXEL_FORMAT_RGB565) {
+      vout_buf_ptr = fb.data;
+      if (fb.pitch / 2 != vout_pitch && fb.pitch != vout_width * 2)
+         SysPrintf("got unusual pitch %zd for resolution %dx%d\n", fb.pitch, vout_width, vout_height);
+      vout_pitch = fb.pitch / 2;
+   }
    else
       vout_buf_ptr = vout_buf;
 }
@@ -315,7 +324,7 @@ static void vout_flip(const void *vram, int stride, int bgr24,
 {
    unsigned short *dest = vout_buf_ptr;
    const unsigned short *src = vram;
-   int dstride = vout_width, h1 = h;
+   int dstride = vout_pitch, h1 = h;
    int port = 0;
 
    if (vram == NULL || dims_changed || (in_enable_crosshair[0] + in_enable_crosshair[1]) > 0)
@@ -355,7 +364,7 @@ static void vout_flip(const void *vram, int stride, int bgr24,
 
 out:
 #ifndef FRONTEND_SUPPORTS_RGB565
-   convert(vout_buf_ptr, vout_width * vout_height * 2);
+   convert(vout_buf_ptr, vout_pitch * vout_height * 2);
 #endif
    vout_fb_dirty = 1;
    pl_rearmed_cbs.flip_cnt++;
@@ -375,7 +384,7 @@ psx_map_t custom_psx_maps[] = {
    { NULL, 0x12800000, 0x010000, MAP_TAG_OTHER }, // 0x1f800000
    { NULL, 0x12c00000, 0x080000, MAP_TAG_OTHER }, // 0x1fc00000
    { NULL, 0x11000000, 0x800000, MAP_TAG_LUTS }, // 0x08000000
-   { NULL, 0x12000000, 0x200000, MAP_TAG_VRAM }, // 0x00000000
+   { NULL, 0x12000000, 0x201000, MAP_TAG_VRAM }, // 0x00000000
 };
 
 void *pl_3ds_mmap(unsigned long addr, size_t size, int is_fixed,
@@ -393,6 +402,7 @@ void *pl_3ds_mmap(unsigned long addr, size_t size, int is_fixed,
          if ((custom_map->size == size) && (custom_map->tag == tag))
          {
             uint32_t ptr_aligned, tmp;
+            void *ret;
 
             custom_map->buffer = malloc(size + 0x1000);
             ptr_aligned = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF;
@@ -403,12 +413,14 @@ void *pl_3ds_mmap(unsigned long addr, size_t size, int is_fixed,
                exit(1);
             }
 
-            return (void *)custom_map->target_map;
+            ret = (void *)custom_map->target_map;
+            memset(ret, 0, size);
+            return ret;
          }
       }
    }
 
-   return malloc(size);
+   return calloc(size, 1);
 }
 
 void pl_3ds_munmap(void *ptr, size_t size, enum psxMapTag tag)
@@ -444,19 +456,20 @@ void pl_3ds_munmap(void *ptr, size_t size, enum psxMapTag tag)
 typedef struct
 {
    void *buffer;
-   uint32_t target_map;
    size_t size;
    enum psxMapTag tag;
+   int used;
 } psx_map_t;
 
-void *addr = NULL;
+static void *addr = NULL;
 
 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
+   { NULL, 0x800000, MAP_TAG_LUTS },
+   { NULL, 0x080000, MAP_TAG_OTHER },
+   { NULL, 0x010000, MAP_TAG_OTHER },
+   { NULL, 0x201000, MAP_TAG_VRAM },
+   { NULL, 0x802000, MAP_TAG_VRAM }, // enhanced renderer
+   { NULL, 0x210000, MAP_TAG_RAM },
 };
 
 int init_vita_mmap()
@@ -466,12 +479,14 @@ int init_vita_mmap()
    addr = malloc(64 * 1024 * 1024);
    if (addr == NULL)
       return -1;
-   tmpaddr = ((u32)(addr + 0xFFFFFF)) & ~0xFFFFFF;
-   custom_psx_maps[0].buffer = tmpaddr + 0x2000000;
-   custom_psx_maps[1].buffer = tmpaddr + 0x1800000;
-   custom_psx_maps[2].buffer = tmpaddr + 0x1c00000;
-   custom_psx_maps[3].buffer = tmpaddr + 0x0000000;
+   tmpaddr = (void *)(((size_t)addr + 0xFFFFFF) & ~0xFFFFFF);
+   custom_psx_maps[0].buffer = tmpaddr + 0x0000000;
+   custom_psx_maps[1].buffer = tmpaddr + 0x0800000;
+   custom_psx_maps[2].buffer = tmpaddr + 0x0880000;
+   custom_psx_maps[3].buffer = tmpaddr + 0x0900000;
    custom_psx_maps[4].buffer = tmpaddr + 0x1000000;
+   custom_psx_maps[5].buffer = tmpaddr + 0x2000000;
+   memset(tmpaddr, 0, 0x2210000);
 #if 0
    for(n = 0; n < 5; n++){
    sceClibPrintf("addr reserved %x\n",custom_psx_maps[n].buffer);
@@ -482,6 +497,11 @@ int init_vita_mmap()
 
 void deinit_vita_mmap()
 {
+   size_t i;
+   for (i = 0; i < sizeof(custom_psx_maps) / sizeof(custom_psx_maps[0]); i++) {
+      custom_psx_maps[i].buffer = NULL;
+      custom_psx_maps[i].used = 0;
+   }
    free(addr);
 }
 
@@ -495,13 +515,14 @@ void *pl_vita_mmap(unsigned long addr, size_t size, int is_fixed,
 
    for (; custom_map->size; custom_map++)
    {
-      if ((custom_map->size == size) && (custom_map->tag == tag))
+      if (custom_map->size == size && custom_map->tag == tag && !custom_map->used)
       {
+         custom_map->used = 1;
          return custom_map->buffer;
       }
    }
 
-   return malloc(size);
+   return calloc(size, 1);
 }
 
 void pl_vita_munmap(void *ptr, size_t size, enum psxMapTag tag)
@@ -514,6 +535,7 @@ void pl_vita_munmap(void *ptr, size_t size, enum psxMapTag tag)
    {
       if ((custom_map->buffer == ptr))
       {
+         custom_map->used = 0;
          return;
       }
    }
@@ -965,8 +987,8 @@ void retro_get_system_info(struct retro_system_info *info)
 
 void retro_get_system_av_info(struct retro_system_av_info *info)
 {
-   unsigned geom_height          = vout_height > 0 ? vout_height : 240;
-   unsigned geom_width           = vout_width > 0 ? vout_width : 320;
+   unsigned geom_height          = vout_height;
+   unsigned geom_width           = vout_width;
 
    memset(info, 0, sizeof(*info));
    info->timing.fps              = is_pal_mode ? 50.0 : 60.0;
@@ -1069,14 +1091,24 @@ static void save_close(void *file)
 
 bool retro_serialize(void *data, size_t size)
 {
-   int ret = SaveState(data);
+   int ret;
+   CdromFrontendId = disk_current_index;
+   ret = SaveState(data);
    return ret == 0 ? true : false;
 }
 
+static bool disk_set_image_index(unsigned int index);
+
 bool retro_unserialize(const void *data, size_t size)
 {
-   int ret = LoadState(data);
-   return ret == 0 ? true : false;
+   int ret;
+   CdromFrontendId = -1;
+   ret = LoadState(data);
+   if (ret)
+      return false;
+   if (CdromFrontendId != -1 && CdromFrontendId != disk_current_index)
+      disk_set_image_index(CdromFrontendId);
+   return true;
 }
 
 /* cheats */
@@ -1142,7 +1174,6 @@ finish:
 static unsigned int disk_initial_index;
 static char disk_initial_path[PATH_MAX];
 static bool disk_ejected;
-static unsigned int disk_current_index;
 static unsigned int disk_count;
 static struct disks_state
 {
@@ -1502,6 +1533,32 @@ static void set_retro_memmap(void)
 #endif
 }
 
+static void show_notification(const char *msg_str,
+      unsigned duration_ms, unsigned priority)
+{
+   if (msg_interface_version >= 1)
+   {
+      struct retro_message_ext msg = {
+         msg_str,
+         duration_ms,
+         3,
+         RETRO_LOG_WARN,
+         RETRO_MESSAGE_TARGET_ALL,
+         RETRO_MESSAGE_TYPE_NOTIFICATION,
+         -1
+      };
+      environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, &msg);
+   }
+   else
+   {
+      struct retro_message msg = {
+         msg_str,
+         180
+      };
+      environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
+   }
+}
+
 static void retro_audio_buff_status_cb(
    bool active, unsigned occupancy, bool underrun_likely)
 {
@@ -1781,6 +1838,9 @@ bool retro_load_game(const struct retro_game_info *info)
    set_retro_memmap();
    retro_set_audio_buff_status_cb();
 
+   if (check_unsatisfied_libcrypt())
+      show_notification("LibCrypt protected game with missing SBI detected", 3000, 3);
+
    return true;
 }
 
@@ -1953,6 +2013,14 @@ static void update_variables(bool in_flight)
          in_enable_vibration = 1;
    }
 
+   var.value = NULL;
+   var.key = "pcsx_rearmed_analog_toggle";
+
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+   {
+      in_dualshock_toggle_enable = (strcmp(var.value, "enabled") == 0);
+   }
+
    var.value = NULL;
    var.key = "pcsx_rearmed_dithering";
 
@@ -2182,6 +2250,7 @@ static void update_variables(bool in_flight)
          spu_config.iUseInterpolation = 0;
    }
 
+#if P_HAVE_PTHREAD
    var.value = NULL;
    var.key = "pcsx_rearmed_spu_thread";
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
@@ -2191,7 +2260,9 @@ static void update_variables(bool in_flight)
       else
          spu_config.iUseThread = 0;
    }
+#endif
 
+#if 0 // currently disabled, see USE_READ_THREAD in libpcsxcore/cdriso.c
    if (P_HAVE_PTHREAD) {
           var.value = NULL;
           var.key = "pcsx_rearmed_async_cd";
@@ -2214,6 +2285,7 @@ static void update_variables(bool in_flight)
                  }
        }
    }
+#endif
 
    var.value = NULL;
    var.key = "pcsx_rearmed_noxadecoding";
@@ -2253,8 +2325,10 @@ static void update_variables(bool in_flight)
    {
       if (strcmp(var.value, "game") == 0)
          pl_rearmed_cbs.screen_centering_type = 1;
-      else if (strcmp(var.value, "manual") == 0)
+      else if (strcmp(var.value, "borderless") == 0)
          pl_rearmed_cbs.screen_centering_type = 2;
+      else if (strcmp(var.value, "manual") == 0)
+         pl_rearmed_cbs.screen_centering_type = 3;
       else // auto
          pl_rearmed_cbs.screen_centering_type = 0;
    }
@@ -2513,6 +2587,18 @@ static void update_variables(bool in_flight)
       mouse_sensitivity = atof(var.value);
    }
 
+   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;
+      }
+   }
+
    if (in_flight)
    {
       // inform core things about possible config changes
@@ -2530,27 +2616,6 @@ static void update_variables(bool in_flight)
 
       /* dfinput_activate(); */
    }
-   else
-   {
-      //not yet running
-
-      //bootlogo display hack
-      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;
-            rebootemu = 0;
-            if (strcmp(var.value, "enabled") == 0)
-            {
-               Config.SlowBoot = 1;
-               rebootemu = 1;
-            }
-         }
-      }
-   }
 
    update_option_visibility();
 }
@@ -2808,10 +2873,14 @@ static void update_input_mouse(int port, int ret)
 
 static void update_input(void)
 {
-   // reset all keystate, query libretro for keystate
+   int16_t analog_combo =
+      (1 << RETRO_DEVICE_ID_JOYPAD_L) |
+      (1 << RETRO_DEVICE_ID_JOYPAD_R) |
+      (1 << RETRO_DEVICE_ID_JOYPAD_SELECT);
    int i;
    int j;
 
+   // reset all keystate, query libretro for keystate
    for (i = 0; i < PORTS_NUMBER; i++)
    {
       int16_t ret = 0;
@@ -2848,7 +2917,23 @@ static void update_input(void)
          update_input_mouse(i, ret);
          break;      
       default:
-         // Query digital inputs
+         // dualshock ANALOG toggle?
+         if (type == PSE_PAD_TYPE_ANALOGPAD && in_dualshock_toggle_enable
+             && (ret & analog_combo) == analog_combo)
+         {
+            if (!in_dualshock_toggling)
+            {
+               int state = padToggleAnalog(i);
+               char msg[32];
+               snprintf(msg, sizeof(msg), "ANALOG %s", state ? "ON" : "OFF");
+               show_notification(msg, 800, 1);
+               in_dualshock_toggling = true;
+            }
+            return;
+         }
+         in_dualshock_toggling = false;
+
+         // Set digital inputs
          for (j = 0; j < RETRO_PSX_MAP_LEN; j++)
             if (ret & (1 << j))
                in_keystate[i] |= retro_psx_map[j];
@@ -2921,6 +3006,7 @@ void retro_run(void)
          LoadCdrom();
    }
 
+   set_vout_fb();
    print_internal_fps();
 
    /* Check whether current frame should
@@ -2982,10 +3068,8 @@ void retro_run(void)
    }
 
    video_cb((vout_fb_dirty || !vout_can_dupe || !duping_enable) ? vout_buf_ptr : NULL,
-       vout_width, vout_height, vout_width * 2);
+       vout_width, vout_height, vout_pitch * 2);
    vout_fb_dirty = 0;
-
-   set_vout_fb();
 }
 
 static bool try_use_bios(const char *path, bool preferred_only)
@@ -3181,38 +3265,21 @@ static void loadPSXBios(void)
    if (!found_bios)
    {
       const char *msg_str;
+      unsigned duration;
       if (useHLE)
       {
-         msg_str = "BIOS set to \'hle\' in core options - real BIOS will be ignored";
+         msg_str = "BIOS set to \'hle\'";
          SysPrintf("Using HLE BIOS.\n");
+         // shorter as the user probably intentionally wants to use HLE
+         duration = 700;
       }
       else
       {
          msg_str = "No PlayStation BIOS file found - add for better compatibility";
          SysPrintf("No BIOS files found.\n");
+         duration = 3000;
       }
-
-      if (msg_interface_version >= 1)
-      {
-         struct retro_message_ext msg = {
-            msg_str,
-            3000,
-            3,
-            RETRO_LOG_WARN,
-            RETRO_MESSAGE_TARGET_ALL,
-            RETRO_MESSAGE_TYPE_NOTIFICATION,
-            -1
-         };
-         environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, &msg);
-      }
-      else
-      {
-         struct retro_message msg = {
-            msg_str,
-            180
-         };
-         environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
-      }
+      show_notification(msg_str, duration, 2);
    }
 }
 
@@ -3260,8 +3327,10 @@ void retro_init(void)
 #elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) && P_HAVE_POSIX_MEMALIGN
    if (posix_memalign(&vout_buf, 16, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2) != 0)
       vout_buf = (void *) 0;
+   else
+      memset(vout_buf, 0, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
 #else
-   vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
+   vout_buf = calloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT, 2);
 #endif
 
    vout_buf_ptr = vout_buf;