libretro: preliminary physical cdrom support
authornotaz <notasas@gmail.com>
Mon, 18 Mar 2024 00:37:51 +0000 (02:37 +0200)
committernotaz <notasas@gmail.com>
Wed, 20 Mar 2024 23:52:17 +0000 (01:52 +0200)
Makefile
Makefile.libretro
frontend/libretro.c
libpcsxcore/cdriso.c
libpcsxcore/cdriso.h

index bb183a4..17bd644 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -336,17 +336,25 @@ CFLAGS += `pkg-config --cflags glib-2.0 libosso dbus-1 hildon-fm-2`
 LDFLAGS += `pkg-config --libs glib-2.0 libosso dbus-1 hildon-fm-2`
 endif
 ifeq "$(PLATFORM)" "libretro"
+ifneq "$(HAVE_PHYSICAL_CDROM)$(USE_LIBRETRO_VFS)" "00"
+OBJS += deps/libretro-common/compat/compat_strl.o
+OBJS += deps/libretro-common/file/file_path.o
+OBJS += deps/libretro-common/string/stdstring.o
+OBJS += deps/libretro-common/vfs/vfs_implementation.o
+endif
+ifeq "$(HAVE_PHYSICAL_CDROM)" "1"
+OBJS += deps/libretro-common/cdrom/cdrom.o
+OBJS += deps/libretro-common/memmap/memalign.o
+OBJS += deps/libretro-common/vfs/vfs_implementation_cdrom.o
+CFLAGS += -DHAVE_CDROM
+endif
 ifeq "$(USE_LIBRETRO_VFS)" "1"
 OBJS += deps/libretro-common/compat/compat_posix_string.o
 OBJS += deps/libretro-common/compat/fopen_utf8.o
-OBJS += deps/libretro-common/compat/compat_strl.o
 OBJS += deps/libretro-common/encodings/encoding_utf.o
-OBJS += deps/libretro-common/file/file_path.o
 OBJS += deps/libretro-common/streams/file_stream.o
 OBJS += deps/libretro-common/streams/file_stream_transforms.o
-OBJS += deps/libretro-common/string/stdstring.o
 OBJS += deps/libretro-common/time/rtime.o
-OBJS += deps/libretro-common/vfs/vfs_implementation.o
 CFLAGS += -DUSE_LIBRETRO_VFS
 endif
 OBJS += frontend/libretro.o
index ab62610..a215cb5 100644 (file)
@@ -3,6 +3,7 @@
 DEBUG ?= 0
 WANT_ZLIB ?= 1
 HAVE_CHD ?= 1
+HAVE_PHYSICAL_CDROM ?= 1
 USE_LIBRETRO_VFS ?= 0
 
 # Dynarec options: lightrec, ari64
@@ -173,6 +174,7 @@ else ifeq ($(platform), osx)
        CFLAGS  += $(ARCHFLAGS)
        CXXFLAGS  += $(ARCHFLAGS)
        LDFLAGS += $(ARCHFLAGS)
+       HAVE_PHYSICAL_CDROM = 0
 
 # iOS
 else ifneq (,$(findstring ios,$(platform)))
@@ -228,6 +230,7 @@ endif
        BUILTIN_GPU = neon
        HAVE_NEON = 1
        DYNAREC = 0
+       HAVE_PHYSICAL_CDROM = 0
        CC_AS = perl ./tools/gas-preprocessor.pl $(CC)
 
 # Nintendo Switch (libnx)
@@ -250,6 +253,7 @@ else ifeq ($(platform), libnx)
    BUILTIN_GPU = neon
    HAVE_NEON = 1
    DYNAREC = ari64
+   HAVE_PHYSICAL_CDROM = 0
 
 # Lakka Switch (arm64)
 else ifeq ($(platform), arm64)
@@ -258,6 +262,7 @@ else ifeq ($(platform), arm64)
    BUILTIN_GPU = neon
    HAVE_NEON = 1
    DYNAREC = ari64
+   HAVE_PHYSICAL_CDROM = 0
    fpic := -fPIC
    CFLAGS := $(filter-out -O2, $(CFLAGS))
    CFLAGS += -O3 -ftree-vectorize
@@ -274,11 +279,13 @@ else ifeq ($(platform), psl1ght)
        LIBPTHREAD :=
        LIBDL :=
        NEED_SYSCONF := 1
+       HAVE_PHYSICAL_CDROM = 0
 
 # PSP
 else ifeq ($(platform), psp1)
        TARGET := $(TARGET_NAME)_libretro_psp1.a
        CFLAGS += -DPSP -G0
+       HAVE_PHYSICAL_CDROM = 0
 
 # Vita
 else ifeq ($(platform), vita)
@@ -302,6 +309,7 @@ else ifeq ($(platform), vita)
        STATIC_LINKING = 1
        NO_PTHREAD=1
        NO_POSIX_MEMALIGN := 1
+       HAVE_PHYSICAL_CDROM = 0
 
 # CTR(3DS)
 else ifeq ($(platform), ctr)
@@ -324,11 +332,13 @@ else ifeq ($(platform), ctr)
        HAVE_NEON = 0
        STATIC_LINKING = 1
        NO_POSIX_MEMALIGN := 1
+       HAVE_PHYSICAL_CDROM = 0
 
 # Xbox 360
 else ifeq ($(platform), xenon)
        TARGET := $(TARGET_NAME)_libretro_xenon360.a
        CFLAGS += -D__LIBXENON__ -m32 -D__ppc__
+       HAVE_PHYSICAL_CDROM = 0
 
 # Nintendo GC/Wii/WiiU
 else ifneq (,$(filter $(platform),ngc wii wiiu))
@@ -359,6 +369,7 @@ else ifneq (,$(filter $(platform),ngc wii wiiu))
        LIBDL :=
        LIBPTHREAD :=
        LIBRT :=
+       HAVE_PHYSICAL_CDROM = 0
 
 # QNX
 else ifeq ($(platform), qnx)
@@ -375,6 +386,7 @@ else ifeq ($(platform), qnx)
        LIBPTHREAD :=
        LIBDL :=
        LIBM :=
+       HAVE_PHYSICAL_CDROM = 0
 
 #Raspberry Pi 1
 else ifeq ($(platform), rpi1)
@@ -551,6 +563,7 @@ else ifeq ($(platform), emscripten)
    NO_PTHREAD=1
    DYNAREC =
    STATIC_LINKING = 1
+   HAVE_PHYSICAL_CDROM = 0
 
 # Windows
 else
index 0a98e83..a3c3610 100644 (file)
@@ -1497,6 +1497,103 @@ static void extract_directory(char *buf, const char *path, size_t size)
    }
 }
 
+// raw cdrom support
+#ifdef HAVE_CDROM
+#include "vfs/vfs_implementation.h"
+#include "vfs/vfs_implementation_cdrom.h"
+#include "cdrom/cdrom.h"
+static libretro_vfs_implementation_file *rcdrom_h;
+
+static long CALLBACK rcdrom_open(void)
+{
+   //printf("%s %s\n", __func__, GetIsoFile());
+   rcdrom_h = retro_vfs_file_open_impl(GetIsoFile(), RETRO_VFS_FILE_ACCESS_READ,
+      RETRO_VFS_FILE_ACCESS_HINT_NONE);
+   return rcdrom_h ? 0 : -1;
+}
+
+static long CALLBACK rcdrom_close(void)
+{
+   //printf("%s\n", __func__);
+   if (rcdrom_h) {
+      retro_vfs_file_close_impl(rcdrom_h);
+      rcdrom_h = NULL;
+   }
+   return 0;
+}
+
+static long CALLBACK rcdrom_getTN(unsigned char *tn)
+{
+   const cdrom_toc_t *toc = retro_vfs_file_get_cdrom_toc();
+   tn[0] = 1;
+   tn[1] = toc->num_tracks;
+   //printf("%s -> %d %d\n", __func__, tn[0], tn[1]);
+   return 0;
+}
+
+static long CALLBACK rcdrom_getTD(unsigned char track, unsigned char *rt)
+{
+   const cdrom_toc_t *toc = retro_vfs_file_get_cdrom_toc();
+   rt[0] = 0, rt[1] = 2, rt[2] = 0;
+   if (track == 0) {
+      const cdrom_track_t *last = &toc->track[toc->num_tracks - 1];
+      unsigned lba = cdrom_msf_to_lba(last->min, last->sec, last->frame);
+      lba += last->track_size;
+      cdrom_lba_to_msf(lba, &rt[2], &rt[1], &rt[0]);
+   }
+   else if (track <= toc->num_tracks) {
+      int i = track - 1;
+      rt[2] = toc->track[i].min;
+      rt[1] = toc->track[i].sec;
+      rt[0] = toc->track[i].frame;
+   }
+   //printf("%s %d -> %d:%02d:%02d\n", __func__, track, rt[2], rt[1], rt[0]);
+   return 0;
+}
+
+static boolean CALLBACK rcdrom_readTrack(unsigned char *time)
+{
+   void *buf = ISOgetBuffer();
+   int ret = -1;
+   if (rcdrom_h)
+      ret = cdrom_read(rcdrom_h, NULL,
+           btoi(time[0]), btoi(time[1]), btoi(time[2]), buf, 2340, 12);
+   //printf("%s %x:%02x:%02x -> %d\n", __func__, time[0], time[1], time[2], ret);
+   return !ret;
+}
+
+static unsigned char * CALLBACK rcdrom_getBuffer(void)
+{
+   //printf("%s\n", __func__);
+   return ISOgetBuffer();
+}
+
+static unsigned char * CALLBACK rcdrom_getBufferSub(int sector)
+{
+   //printf("%s %d %d\n", __func__, sector, rcdrom_h->cdrom.last_frame_lba);
+   return NULL;
+}
+
+static long CALLBACK rcdrom_getStatus(struct CdrStat *stat)
+{
+   const cdrom_toc_t *toc = retro_vfs_file_get_cdrom_toc();
+   //printf("%s %p\n", __func__, stat);
+   CDR__getStatus(stat);
+   stat->Type = toc->track[0].audio ? 2 : 1;
+   return 0;
+}
+
+static long CALLBACK rcdrom_readCDDA(unsigned char m, unsigned char s, unsigned char f,
+      unsigned char *buffer)
+{
+   int ret = -1;
+   if (rcdrom_h)
+      ret = cdrom_read(rcdrom_h, NULL, m, s, f, buffer, 2352, 0);
+   //printf("%s %d:%02d:%02d -> %d\n", __func__, m, s, f, ret);
+   return ret;
+}
+#endif // HAVE_CDROM
+
 #if defined(__QNX__) || defined(_WIN32)
 /* Blackberry QNX doesn't have strcasestr */
 
@@ -1742,6 +1839,25 @@ bool retro_load_game(const struct retro_game_info *info)
       LogErr("failed to load plugins\n");
       return false;
    }
+   if (!strncmp(info->path, "cdrom:", 6))
+   {
+#ifdef HAVE_CDROM
+      CDR_open = rcdrom_open;
+      CDR_close = rcdrom_close;
+      CDR_getTN = rcdrom_getTN;
+      CDR_getTD = rcdrom_getTD;
+      CDR_readTrack = rcdrom_readTrack;
+      CDR_getBuffer = rcdrom_getBuffer;
+      CDR_getBufferSub = rcdrom_getBufferSub;
+      CDR_getStatus = rcdrom_getStatus;
+      CDR_readCDDA = rcdrom_readCDDA;
+#else
+      ReleasePlugins();
+      LogErr("%s\n", "Physical CD-ROM support is not compiled in.");
+      show_notification("Physical CD-ROM support is not compiled in.", 6000, 3);
+      return false;
+#endif
+   }
 
    plugins_opened = 1;
    NetOpened = 0;
index 37e67d4..218007b 100644 (file)
@@ -1587,7 +1587,7 @@ static unsigned char * CALLBACK ISOgetBuffer_async(void) {
 }
 #endif
 
-static unsigned char * CALLBACK ISOgetBuffer(void) {
+unsigned char * CALLBACK ISOgetBuffer(void) {
        return cdbuffer + 12;
 }
 
index 16ad52f..079e0b8 100644 (file)
@@ -27,6 +27,7 @@ extern "C" {
 
 void cdrIsoInit(void);
 int cdrIsoActive(void);
+unsigned char * CALLBACK ISOgetBuffer(void);
 
 extern unsigned int cdrIsoMultidiskCount;
 extern unsigned int cdrIsoMultidiskSelect;