From c7f3cc746f2113b3c4a309c9b073f1bf3a64afce Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 22 Mar 2024 00:21:20 +0200 Subject: [PATCH] libretro: try to handle physical cdrom ejection notaz/pcsx_rearmed#335 --- frontend/libretro-cdrom.c | 1 - frontend/libretro.c | 42 ++++++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/frontend/libretro-cdrom.c b/frontend/libretro-cdrom.c index 654de1c5..1c71f8a2 100644 --- a/frontend/libretro-cdrom.c +++ b/frontend/libretro-cdrom.c @@ -41,7 +41,6 @@ int cdrom_set_read_speed_x(libretro_vfs_implementation_file *stream, unsigned sp int ret; ret = cdrom_send_command_once(stream, DIRECTION_NONE, NULL, 0, cmd1, sizeof(cmd1)); if (ret) { - printf("DA failed\n"); #if defined(__linux__) && !defined(ANDROID) // doesn't work, too late? //ret = ioctl(fileno(stream->fp), CDROM_SELECT_SPEED, &speed); diff --git a/frontend/libretro.c b/frontend/libretro.c index 5cd0aee8..ffd64c7e 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -1241,20 +1241,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 +1536,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 +1554,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 +1758,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 +1805,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) @@ -3433,6 +3456,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) -- 2.39.5