cdrom: change pause timing again
[pcsx_rearmed.git] / frontend / libretro.c
index 5cd0aee..6a719ae 100644 (file)
@@ -131,7 +131,8 @@ static unsigned previous_width = 0;
 static unsigned previous_height = 0;
 
 static int plugins_opened;
-static int is_pal_mode;
+
+#define is_pal_mode Config.PsxType
 
 /* memory card data */
 extern char Mcd1Data[MCD_SIZE];
@@ -294,16 +295,17 @@ static void convert(void *buf, size_t bytes)
 static void addCrosshair(int port, int crosshair_color, unsigned short *buffer, int bufferStride, int pos_x, int pos_y, int thickness, int size_x, int size_y) {
    for (port = 0; port < 2; port++) {
       // Draw the horizontal line of the crosshair
-      for (int i = pos_y - thickness / 2; i <= pos_y + thickness / 2; i++) {
-         for (int j = pos_x - size_x / 2; j <= pos_x + size_x / 2; j++) {
+      int i, j;
+      for (i = pos_y - thickness / 2; i <= pos_y + thickness / 2; i++) {
+         for (j = pos_x - size_x / 2; j <= pos_x + size_x / 2; j++) {
             if ((i + vout_height) >= 0 && (i + vout_height) < bufferStride && j >= 0 && j < bufferStride && in_enable_crosshair[port] > 0)
                buffer[i * bufferStride + j] = crosshair_color;
-      }
          }
+      }
 
       // Draw the vertical line of the crosshair
-      for (int i = pos_x - thickness / 2; i <= pos_x + thickness / 2; i++) {
-         for (int j = pos_y - size_y / 2; j <= pos_y + size_y / 2; j++) {
+      for (i = pos_x - thickness / 2; i <= pos_x + thickness / 2; i++) {
+         for (j = pos_y - size_y / 2; j <= pos_y + size_y / 2; j++) {
             if (i >= 0 && i < bufferStride && (j + vout_height) >= 0 && (j + vout_height) < bufferStride && in_enable_crosshair[port] > 0)
                buffer[j * bufferStride + i] = crosshair_color;
          }
@@ -366,8 +368,8 @@ static void vout_flip(const void *vram, int stride, int bgr24,
    for (port = 0; port < 2; port++) {
       if (in_enable_crosshair[port] > 0 && (in_type[port] == PSE_PAD_TYPE_GUNCON || in_type[port] == PSE_PAD_TYPE_GUN))
       {
-        struct CrosshairInfo crosshairInfo;
-        CrosshairDimensions(port, &crosshairInfo);
+         struct CrosshairInfo crosshairInfo;
+         CrosshairDimensions(port, &crosshairInfo);
          addCrosshair(port, in_enable_crosshair[port], dest, dstride, crosshairInfo.pos_x, crosshairInfo.pos_y, crosshairInfo.thickness, crosshairInfo.size_x, crosshairInfo.size_y);
       }
    }
@@ -585,7 +587,6 @@ void pl_frame_limit(void)
 
 void pl_timing_prepare(int is_pal)
 {
-   is_pal_mode = is_pal;
 }
 
 void plat_trigger_vibrate(int pad, int low, int high)
@@ -727,8 +728,8 @@ static bool update_option_visibility(void)
             "pcsx_rearmed_negcon_deadzone",
             "pcsx_rearmed_negcon_response",
             "pcsx_rearmed_input_sensitivity",
-           "pcsx_rearmed_crosshair1",
-           "pcsx_rearmed_crosshair2",
+            "pcsx_rearmed_crosshair1",
+            "pcsx_rearmed_crosshair2",
             "pcsx_rearmed_konamigunadjustx",
             "pcsx_rearmed_konamigunadjusty",
             "pcsx_rearmed_gunconadjustx",
@@ -1001,7 +1002,7 @@ void retro_get_system_av_info(struct retro_system_av_info *info)
    unsigned geom_width           = vout_width;
 
    memset(info, 0, sizeof(*info));
-   info->timing.fps              = is_pal_mode ? 50.0 : 60.0;
+   info->timing.fps              = psxGetFps();
    info->timing.sample_rate      = 44100.0;
    info->geometry.base_width     = geom_width;
    info->geometry.base_height    = geom_height;
@@ -1241,20 +1242,26 @@ static void disk_init(void)
 #ifdef HAVE_CDROM
 static long CALLBACK rcdrom_open(void);
 static long CALLBACK rcdrom_close(void);
+static void rcdrom_stop_thread(void);
 #endif
 
 static bool disk_set_eject_state(bool ejected)
 {
-   // weird PCSX API..
+   if (ejected != disk_ejected)
+      SysPrintf("new eject_state: %d\n", ejected);
+
+   // weird PCSX API...
    SetCdOpenCaseTime(ejected ? -1 : (time(NULL) + 2));
    LidInterrupt();
 
 #ifdef HAVE_CDROM
-   if (CDR_open == rcdrom_open) {
-      // likely the real cd was also changed - rescan
-      rcdrom_close();
-      if (!ejected)
+   if (CDR_open == rcdrom_open && ejected != disk_ejected) {
+      rcdrom_stop_thread();
+      if (!ejected) {
+         // likely the real cd was also changed - rescan
+         rcdrom_close();
          rcdrom_open();
+      }
    }
 #endif
    disk_ejected = ejected;
@@ -1530,6 +1537,7 @@ static struct {
    struct cached_buf *buf;
    unsigned int buf_cnt, thread_exit, do_prefetch;
    unsigned int total_lba, prefetch_lba;
+   int check_eject_delay;
 } rcdrom;
 
 static void lbacache_do(unsigned int lba)
@@ -1547,9 +1555,10 @@ static void lbacache_do(unsigned int lba)
    if (ret) {
       rcdrom.do_prefetch = 0;
       slock_unlock(rcdrom.buf_lock);
-      LogErr("cdrom_read_sector failed for lba %d\n", ret, lba);
+      LogErr("prefetch: cdrom_read_sector failed for lba %d\n", lba);
       return;
    }
+   rcdrom.check_eject_delay = 100;
 
    if (lba != rcdrom.buf[i].lba) {
       memcpy(rcdrom.buf[i].buf, buf, sizeof(rcdrom.buf[i].buf));
@@ -1750,13 +1759,17 @@ static int rcdrom_read_msf(unsigned char m, unsigned char s, unsigned char f,
       rcdrom.do_prefetch = 0;
       if (lock)
          slock_lock(lock);
-      if (rcdrom.h)
+      if (rcdrom.h) {
          ret = cdrom_read_sector(rcdrom.h, lba, buf);
+         if (ret)
+            LogErr("cdrom_read_sector failed for lba %d\n", lba);
+      }
       if (lock)
          slock_unlock(lock);
    }
    else
       ret = 0;
+   rcdrom.check_eject_delay = ret ? 0 : 100;
    //printf("%s %d:%02d:%02d -> %d hit %d\n", func, m, s, f, ret, hit);
    return ret;
 }
@@ -1793,6 +1806,17 @@ static long CALLBACK rcdrom_getStatus(struct CdrStat *stat)
    stat->Type = toc->track[0].audio ? 2 : 1;
    return 0;
 }
+
+static void rcdrom_check_eject(void)
+{
+   bool media_inserted;
+   if (!rcdrom.h || rcdrom.do_prefetch || rcdrom.check_eject_delay-- > 0)
+      return;
+   rcdrom.check_eject_delay = 100;
+   media_inserted = cdrom_is_media_inserted(rcdrom.h); // 1-2ms
+   if (!media_inserted != disk_ejected)
+      disk_set_eject_state(!media_inserted);
+}
 #endif // HAVE_CDROM
 
 #if defined(__QNX__) || defined(_WIN32)
@@ -2241,6 +2265,7 @@ static void update_variables(bool in_flight)
    int gpu_peops_fix = GPU_PEOPS_OLD_FRAME_SKIP;
 #endif
    frameskip_type_t prev_frameskip_type;
+   double old_fps = psxGetFps();
 
    var.value = NULL;
    var.key = "pcsx_rearmed_frameskip_type";
@@ -2682,6 +2707,18 @@ static void update_variables(bool in_flight)
          Config.GpuListWalking = -1;
    }
 
+   var.value = NULL;
+   var.key = "pcsx_rearmed_fractional_framerate";
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+   {
+      if (strcmp(var.value, "disabled") == 0)
+         Config.FractionalFramerate = 0;
+      else if (strcmp(var.value, "enabled") == 0)
+         Config.FractionalFramerate = 1;
+      else // auto
+         Config.FractionalFramerate = -1;
+   }
+
    var.value = NULL;
    var.key = "pcsx_rearmed_screen_centering";
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
@@ -2981,6 +3018,13 @@ static void update_variables(bool in_flight)
    }
 
    update_option_visibility();
+
+   if (old_fps != psxGetFps())
+   {
+      struct retro_system_av_info info;
+      retro_get_system_av_info(&info);
+      environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info);
+   }
 }
 
 // Taken from beetle-psx-libretro
@@ -3433,6 +3477,11 @@ void retro_run(void)
    video_cb((vout_fb_dirty || !vout_can_dupe) ? vout_buf_ptr : NULL,
        vout_width, vout_height, vout_pitch * 2);
    vout_fb_dirty = 0;
+
+#ifdef HAVE_CDROM
+   if (CDR_open == rcdrom_open)
+      rcdrom_check_eject();
+#endif
 }
 
 static bool try_use_bios(const char *path, bool preferred_only)