From 58824199e7bf045876c70c3301093dc081e470ec Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 18 Mar 2024 02:37:51 +0200 Subject: [PATCH] libretro: preliminary physical cdrom support --- Makefile | 16 ++++-- Makefile.libretro | 13 +++++ frontend/libretro.c | 116 +++++++++++++++++++++++++++++++++++++++++++ libpcsxcore/cdriso.c | 2 +- libpcsxcore/cdriso.h | 1 + 5 files changed, 143 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index bb183a42..17bd644d 100644 --- 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 diff --git a/Makefile.libretro b/Makefile.libretro index ab62610b..a215cb56 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -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 diff --git a/frontend/libretro.c b/frontend/libretro.c index 0a98e83e..a3c3610b 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -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; diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c index 37e67d4d..218007b0 100644 --- a/libpcsxcore/cdriso.c +++ b/libpcsxcore/cdriso.c @@ -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; } diff --git a/libpcsxcore/cdriso.h b/libpcsxcore/cdriso.h index 16ad52ff..079e0b8c 100644 --- a/libpcsxcore/cdriso.h +++ b/libpcsxcore/cdriso.h @@ -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; -- 2.39.5