cdrom: Support subchannel reads with HW players
authorPaul Cercueil <paul@crapouillou.net>
Mon, 14 Apr 2025 19:54:38 +0000 (21:54 +0200)
committernotaz <notasas@gmail.com>
Tue, 22 Apr 2025 22:07:51 +0000 (01:07 +0300)
Add function rcdrom_readSub(), that can be implemented by frontends, and
update rcdrom_open() to take an extra parameter, that can be set by the
frontend to tell the async CD-ROM code whether or not subchannel reads
are supported.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
frontend/libretro-cdrom.c
libpcsxcore/cdrom-async.c
libpcsxcore/cdrom-async.h

index 91528d7..46f0d39 100644 (file)
@@ -71,7 +71,7 @@ int rcdrom_readSector(void *stream, unsigned int lba, void *b)
    return cdrom_send_command_once(stream, DIRECTION_IN, b, 2352, cmd, sizeof(cmd));
 }
 
-void *rcdrom_open(const char *name, u32 *total_lba)
+void *rcdrom_open(const char *name, u32 *total_lba, u32 *have_subchannel)
 {
    void *g_cd_handle = retro_vfs_file_open_impl(name, RETRO_VFS_FILE_ACCESS_READ,
         RETRO_VFS_FILE_ACCESS_HINT_NONE);
@@ -86,6 +86,7 @@ void *rcdrom_open(const char *name, u32 *total_lba)
       const cdrom_track_t *last = &toc->track[toc->num_tracks - 1];
       unsigned int lba = MSF2SECT(last->min, last->sec, last->frame);
       *total_lba = lba + last->track_size;
+      *have_subchannel = 0;
       //cdrom_get_current_config_random_readable(acdrom.h);
       //cdrom_get_current_config_multiread(acdrom.h);
       //cdrom_get_current_config_cdread(acdrom.h);
@@ -138,4 +139,9 @@ int rcdrom_isMediaInserted(void *stream)
    return cdrom_is_media_inserted(stream);
 }
 
+int rcdrom_readSub(void *stream, unsigned int lba, void *b)
+{
+   return -1;
+}
+
 // vim:sw=3:ts=3:expandtab
index a694c2a..7658096 100644 (file)
@@ -30,12 +30,13 @@ static void *g_cd_handle;
 
 #ifndef HAVE_CDROM
 
-static void *rcdrom_open(const char *name, u32 *total_lba) { return NULL; }
+static void *rcdrom_open(const char *name, u32 *total_lba, u32 *have_sub) { return NULL; }
 static void rcdrom_close(void *stream) {}
 static int  rcdrom_getTN(void *stream, u8 *tn) { return -1; }
 static int  rcdrom_getTD(void *stream, u32 total_lba, u8 track, u8 *rt) { return -1; }
 static int  rcdrom_getStatus(void *stream, struct CdrStat *stat) { return -1; }
 static int  rcdrom_readSector(void *stream, unsigned int lba, void *b) { return -1; }
+static int  rcdrom_readSub(void *stream, unsigned int lba, void *b) { return -1; }
 static int  rcdrom_isMediaInserted(void *stream) { return 0; }
 
 #endif
@@ -72,8 +73,12 @@ static void lbacache_do(u32 lba)
       ret = rcdrom_readSector(g_cd_handle, lba, buf);
    else
       ret = ISOreadTrack(msf, buf);
-   if (acdrom.have_subchannel)
-      ret |= ISOreadSub(msf, buf_sub);
+   if (acdrom.have_subchannel) {
+      if (g_cd_handle)
+         ret |= rcdrom_readSub(g_cd_handle, lba, buf_sub);
+      else
+         ret |= ISOreadSub(msf, buf_sub);
+   }
 
    slock_lock(acdrom.buf_lock);
    slock_unlock(acdrom.read_lock);
@@ -227,7 +232,7 @@ int cdra_open(void)
    acdrom_dbg("%s %s\n", __func__, name);
    acdrom.have_subchannel = 0;
    if (!strncmp(name, "cdrom:", 6)) {
-      g_cd_handle = rcdrom_open(name, &acdrom.total_lba);
+      g_cd_handle = rcdrom_open(name, &acdrom.total_lba, &acdrom.have_subchannel);
       if (!!g_cd_handle)
          ret = 0;
    }
@@ -324,8 +329,12 @@ static int cdra_do_read(const unsigned char *time, int cdda,
       acdrom.do_prefetch = 0;
       if (!buf)
          buf = acdrom.buf_local;
-      if (g_cd_handle)
-         ret = rcdrom_readSector(g_cd_handle, lba, buf);
+      if (g_cd_handle) {
+         if (buf_sub)
+            ret = rcdrom_readSub(g_cd_handle, lba, buf_sub);
+         else
+            ret = rcdrom_readSector(g_cd_handle, lba, buf);
+      }
       else if (buf_sub)
          ret = ISOreadSub(time, buf_sub);
       else if (cdda)
index 0dc632a..4d622b5 100644 (file)
@@ -7,12 +7,13 @@ extern "C" {
 struct CdrStat;
 
 #ifdef HAVE_CDROM
-void *rcdrom_open(const char *name, u32 *total_lba);
+void *rcdrom_open(const char *name, u32 *total_lba, u32 *have_sub);
 void rcdrom_close(void *stream);
 int  rcdrom_getTN(void *stream, u8 *tn);
 int  rcdrom_getTD(void *stream, u32 total_lba, u8 track, u8 *rt);
 int  rcdrom_getStatus(void *stream, struct CdrStat *stat);
 int  rcdrom_readSector(void *stream, unsigned int lba, void *b);
+int  rcdrom_readSub(void *stream, unsigned int lba, void *b);
 int  rcdrom_isMediaInserted(void *stream);
 #endif