diff --git a/src/fatfs/ff.h b/src/fatfs/ff.h index 6df78a8e40..cf48d510f7 100644 --- a/src/fatfs/ff.h +++ b/src/fatfs/ff.h @@ -35,15 +35,7 @@ extern "C" { /* Integer types used for FatFs API */ -#if defined(_WIN32) /* Windows VC++ (for development only) */ -#define FF_INTDEF 2 -#include -typedef unsigned __int64 QWORD; -#include -#define isnan(v) _isnan(v) -#define isinf(v) (!_finite(v)) - -#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */ #define FF_INTDEF 2 #include typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ @@ -53,6 +45,12 @@ typedef uint32_t DWORD; /* 32-bit unsigned integer */ typedef uint64_t QWORD; /* 64-bit unsigned integer */ typedef WORD WCHAR; /* UTF-16 character type */ +#if defined(_WIN32) +#include +#define isnan(v) _isnan(v) +#define isinf(v) (!_finite(v)) +#endif + #else /* Earlier than C99 */ #define FF_INTDEF 1 typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ diff --git a/src/libretro/libretro-common/include/vfs/vfs.h b/src/libretro/libretro-common/include/vfs/vfs.h index b876f438b6..bd61c69aa9 100644 --- a/src/libretro/libretro-common/include/vfs/vfs.h +++ b/src/libretro/libretro-common/include/vfs/vfs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2019 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vfs_implementation.h). @@ -41,17 +41,17 @@ typedef void* HANDLE; #ifdef HAVE_CDROM typedef struct { + int64_t byte_pos; char *cue_buf; size_t cue_len; - int64_t byte_pos; - char drive; + unsigned cur_lba; + unsigned last_frame_lba; unsigned char cur_min; unsigned char cur_sec; unsigned char cur_frame; unsigned char cur_track; - unsigned cur_lba; - unsigned last_frame_lba; unsigned char last_frame[2352]; + char drive; bool last_frame_valid; } vfs_cdrom_t; #endif @@ -62,29 +62,29 @@ enum vfs_scheme VFS_SCHEME_CDROM }; -#ifndef __WINRT__ +#if !(defined(__WINRT__) && defined(__cplusplus_winrt)) #ifdef VFS_FRONTEND struct retro_vfs_file_handle #else struct libretro_vfs_implementation_file #endif { - int fd; - unsigned hints; +#ifdef HAVE_CDROM + vfs_cdrom_t cdrom; /* int64_t alignment */ +#endif int64_t size; - char *buf; + uint64_t mappos; + uint64_t mapsize; FILE *fp; #ifdef _WIN32 HANDLE fh; #endif + char *buf; char* orig_path; - uint64_t mappos; - uint64_t mapsize; uint8_t *mapped; + int fd; + unsigned hints; enum vfs_scheme scheme; -#ifdef HAVE_CDROM - vfs_cdrom_t cdrom; -#endif }; #endif diff --git a/src/libretro/libretro-common/include/vfs/vfs_implementation.h b/src/libretro/libretro-common/include/vfs/vfs_implementation.h index c981cf72f7..b88d2f3d2b 100644 --- a/src/libretro/libretro-common/include/vfs/vfs_implementation.h +++ b/src/libretro/libretro-common/include/vfs/vfs_implementation.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2019 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vfs_implementation.h). @@ -71,6 +71,12 @@ bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *dirstream); int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *dirstream); +#ifdef __WINRT__ + +void uwp_set_acl(const wchar_t* path, const wchar_t* AccessString); + +#endif + RETRO_END_DECLS #endif diff --git a/src/libretro/libretro-common/include/vfs/vfs_implementation_cdrom.h b/src/libretro/libretro-common/include/vfs/vfs_implementation_cdrom.h index 3996fbe877..f809963f4f 100644 --- a/src/libretro/libretro-common/include/vfs/vfs_implementation_cdrom.h +++ b/src/libretro/libretro-common/include/vfs/vfs_implementation_cdrom.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2019 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vfs_implementation_cdrom.h). diff --git a/src/libretro/libretro-common/vfs/vfs_implementation.c b/src/libretro/libretro-common/vfs/vfs_implementation.c index 9a139f6a33..a84569acd2 100644 --- a/src/libretro/libretro-common/vfs/vfs_implementation.c +++ b/src/libretro/libretro-common/vfs/vfs_implementation.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2019 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vfs_implementation.c). @@ -26,7 +26,7 @@ #include #include -#include +#include /* string_is_empty */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -51,58 +51,35 @@ # if defined(PSP) # include # endif -# if defined(PS2) -# include -# include -# endif # include # include # if !defined(VITA) # include # endif # include -# if defined(ORBIS) -# include -# include -# include +# if defined(WIIU) +# include # endif #endif -#ifdef __CELLOS_LV2__ -#include -#define O_RDONLY CELL_FS_O_RDONLY -#define O_WRONLY CELL_FS_O_WRONLY -#define O_CREAT CELL_FS_O_CREAT -#define O_TRUNC CELL_FS_O_TRUNC -#define O_RDWR CELL_FS_O_RDWR -#else #include -#endif /* TODO: Some things are duplicated but I'm really afraid of breaking other platforms by touching this */ #if defined(VITA) # include # include # include -#elif defined(ORBIS) -# include -# include -# include -# include #elif !defined(_WIN32) # if defined(PSP) # include # endif -# if defined(PS2) -# include -# endif # include # include # include # include #endif -#if (defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)) || defined(__QNX__) || defined(PSP) || defined(PS2) +#if defined(__QNX__) || defined(PSP) #include /* stat() is defined here */ #endif @@ -137,29 +114,74 @@ #include #endif -#if defined(ORBIS) -#include -#include -#include -#endif + #if defined(PSP) #include #endif -#if defined(PS2) -#include -#include +#if defined(__PS3__) || defined(__PSL1GHT__) +#define FS_SUCCEEDED 0 +#define FS_TYPE_DIR 1 +#ifdef __PSL1GHT__ +#include +#ifndef O_RDONLY +#define O_RDONLY SYS_O_RDONLY #endif - -#if defined(__CELLOS_LV2__) +#ifndef O_WRONLY +#define O_WRONLY SYS_O_WRONLY +#endif +#ifndef O_CREAT +#define O_CREAT SYS_O_CREAT +#endif +#ifndef O_TRUNC +#define O_TRUNC SYS_O_TRUNC +#endif +#ifndef O_RDWR +#define O_RDWR SYS_O_RDWR +#endif +#else #include +#ifndef O_RDONLY +#define O_RDONLY CELL_FS_O_RDONLY +#endif +#ifndef O_WRONLY +#define O_WRONLY CELL_FS_O_WRONLY +#endif +#ifndef O_CREAT +#define O_CREAT CELL_FS_O_CREAT +#endif +#ifndef O_TRUNC +#define O_TRUNC CELL_FS_O_TRUNC +#endif +#ifndef O_RDWR +#define O_RDWR CELL_FS_O_RDWR +#endif +#ifndef sysFsStat +#define sysFsStat cellFsStat +#endif +#ifndef sysFSDirent +#define sysFSDirent CellFsDirent +#endif +#ifndef sysFsOpendir +#define sysFsOpendir cellFsOpendir +#endif +#ifndef sysFsReaddir +#define sysFsReaddir cellFsReaddir +#endif +#ifndef sysFSDirent +#define sysFSDirent CellFsDirent +#endif +#ifndef sysFsClosedir +#define sysFsClosedir cellFsClosedir +#endif +#endif #endif #if defined(VITA) #define FIO_S_ISDIR SCE_S_ISDIR #endif -#if (defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)) || defined(__QNX__) || defined(PSP) +#if defined(__QNX__) || defined(PSP) #include /* stat() is defined here */ #endif @@ -173,14 +195,16 @@ #endif #if defined(_WIN32) -#if !defined(_MSC_VER) || (defined(_MSC_VER) && _MSC_VER >= 1400) +#if defined(_MSC_VER) && _MSC_VER >= 1400 #define ATLEAST_VC2005 #endif #endif #include #include +#if defined(HAVE_MMAP) #include +#endif #include #include #include @@ -189,9 +213,17 @@ #include #endif +#if (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0) >= 200112) || (defined(__POSIX_VISIBLE) && __POSIX_VISIBLE >= 200112) || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112) || __USE_LARGEFILE || (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) +#ifndef HAVE_64BIT_OFFSETS +#define HAVE_64BIT_OFFSETS +#endif +#endif + #define RFILE_HINT_UNBUFFERED (1 << 8) -int64_t retro_vfs_file_seek_internal(libretro_vfs_implementation_file *stream, int64_t offset, int whence) +int64_t retro_vfs_file_seek_internal( + libretro_vfs_implementation_file *stream, + int64_t offset, int whence) { if (!stream) return -1; @@ -202,28 +234,13 @@ int64_t retro_vfs_file_seek_internal(libretro_vfs_implementation_file *stream, i if (stream->scheme == VFS_SCHEME_CDROM) return retro_vfs_file_seek_cdrom(stream, offset, whence); #endif -/* VC2005 and up have a special 64-bit fseek */ #ifdef ATLEAST_VC2005 + /* VC2005 and up have a special 64-bit fseek */ return _fseeki64(stream->fp, offset, whence); -#elif defined(__CELLOS_LV2__) || defined(_MSC_VER) && _MSC_VER <= 1310 - return fseek(stream->fp, (long)offset, whence); -#elif defined(PS2) - { - int64_t ret = fileXioLseek(fileno(stream->fp), (off_t)offset, whence); - /* fileXioLseek could return positive numbers */ - if (ret > 0) - return 0; - return ret; - } -#elif defined(ORBIS) - { - int ret = orbisLseek(stream->fd, offset, whence); - if (ret < 0) - return -1; - return 0; - } -#else +#elif defined(HAVE_64BIT_OFFSETS) return fseeko(stream->fp, (off_t)offset, whence); +#else + return fseek(stream->fp, (long)offset, whence); #endif } #ifdef HAVE_MMAP @@ -263,7 +280,7 @@ int64_t retro_vfs_file_seek_internal(libretro_vfs_implementation_file *stream, i } #endif - if (lseek(stream->fd, offset, whence) < 0) + if (lseek(stream->fd, (off_t)offset, whence) < 0) return -1; return 0; @@ -284,45 +301,72 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl( { int flags = 0; const char *mode_str = NULL; - int path_len = (int)strlen(path); - libretro_vfs_implementation_file *stream = (libretro_vfs_implementation_file*) - calloc(1, sizeof(*stream)); + libretro_vfs_implementation_file *stream = + (libretro_vfs_implementation_file*) + malloc(sizeof(*stream)); -#ifdef VFS_FRONTEND - const char *dumb_prefix = "vfsonly://"; - size_t dumb_prefix_siz = strlen(dumb_prefix); - int dumb_prefix_len = (int)dumb_prefix_siz; + if (!stream) + return NULL; - if (path_len >= dumb_prefix_len) - { - if (!memcmp(path, dumb_prefix, dumb_prefix_len)) - path += dumb_prefix_siz; - } + stream->fd = 0; + stream->hints = hints; + stream->size = 0; + stream->buf = NULL; + stream->fp = NULL; +#ifdef _WIN32 + stream->fh = 0; +#endif + stream->orig_path = NULL; + stream->mappos = 0; + stream->mapsize = 0; + stream->mapped = NULL; + stream->scheme = VFS_SCHEME_NONE; + +#ifdef VFS_FRONTEND + if ( path + && path[0] == 'v' + && path[1] == 'f' + && path[2] == 's' + && path[3] == 'o' + && path[4] == 'n' + && path[5] == 'l' + && path[6] == 'y' + && path[7] == ':' + && path[8] == '/' + && path[9] == '/') + path += sizeof("vfsonly://")-1; #endif #ifdef HAVE_CDROM + stream->cdrom.cue_buf = NULL; + stream->cdrom.cue_len = 0; + stream->cdrom.byte_pos = 0; + stream->cdrom.drive = 0; + stream->cdrom.cur_min = 0; + stream->cdrom.cur_sec = 0; + stream->cdrom.cur_frame = 0; + stream->cdrom.cur_track = 0; + stream->cdrom.cur_lba = 0; + stream->cdrom.last_frame_lba = 0; + stream->cdrom.last_frame[0] = '\0'; + stream->cdrom.last_frame_valid = false; + + if ( path + && path[0] == 'c' + && path[1] == 'd' + && path[2] == 'r' + && path[3] == 'o' + && path[4] == 'm' + && path[5] == ':' + && path[6] == '/' + && path[7] == '/' + && path[8] != '\0') { - const char *cdrom_prefix = "cdrom://"; - size_t cdrom_prefix_siz = strlen(cdrom_prefix); - int cdrom_prefix_len = (int)cdrom_prefix_siz; - - if (path_len > cdrom_prefix_len) - { - if (!memcmp(path, cdrom_prefix, cdrom_prefix_len)) - { - path += cdrom_prefix_siz; - stream->scheme = VFS_SCHEME_CDROM; - } - } + path += sizeof("cdrom://")-1; + stream->scheme = VFS_SCHEME_CDROM; } #endif - if (!stream) - return NULL; - - (void)flags; - - stream->hints = hints; stream->orig_path = strdup(path); #ifdef HAVE_MMAP @@ -347,28 +391,20 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl( mode_str = "wb"; flags = O_WRONLY | O_CREAT | O_TRUNC; -#if !defined(ORBIS) -#if defined(PS2) - flags |= FIO_S_IRUSR | FIO_S_IWUSR; -#elif !defined(_WIN32) +#if !defined(_WIN32) flags |= S_IRUSR | S_IWUSR; #else flags |= O_BINARY; -#endif #endif break; case RETRO_VFS_FILE_ACCESS_READ_WRITE: mode_str = "w+b"; flags = O_RDWR | O_CREAT | O_TRUNC; -#if !defined(ORBIS) -#if defined(PS2) - flags |= FIO_S_IRUSR | FIO_S_IWUSR; -#elif !defined(_WIN32) +#if !defined(_WIN32) flags |= S_IRUSR | S_IWUSR; #else flags |= O_BINARY; -#endif #endif break; @@ -377,14 +413,10 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl( mode_str = "r+b"; flags = O_RDWR; -#if !defined(ORBIS) -#if defined(PS2) - flags |= FIO_S_IRUSR | FIO_S_IWUSR; -#elif !defined(_WIN32) +#if !defined(_WIN32) flags |= S_IRUSR | S_IWUSR; #else flags |= O_BINARY; -#endif #endif break; @@ -394,15 +426,6 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl( if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) { -#ifdef ORBIS - int fd = orbisOpen(path, flags, 0644); - if (fd < 0) - { - stream->fd = -1; - goto error; - } - stream->fd = fd; -#else FILE *fp; #ifdef HAVE_CDROM if (stream->scheme == VFS_SCHEME_CDROM) @@ -419,31 +442,43 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl( else #endif { - fp = (FILE*)fopen_utf8(path, mode_str); - - if (!fp) + if (!(fp = (FILE*)fopen_utf8(path, mode_str))) goto error; stream->fp = fp; } + /* Regarding setvbuf: * * https://www.freebsd.org/cgi/man.cgi?query=setvbuf&apropos=0&sektion=0&manpath=FreeBSD+11.1-RELEASE&arch=default&format=html * - * If the size argument is not zero but buf is NULL, a buffer of the given size will be allocated immediately, and + * If the size argument is not zero but buf is NULL, + * a buffer of the given size will be allocated immediately, and * released on close. This is an extension to ANSI C. * - * Since C89 does not support specifying a null buffer with a non-zero size, we create and track our own buffer for it. + * Since C89 does not support specifying a NULL buffer + * with a non-zero size, we create and track our own buffer for it. */ - /* TODO: this is only useful for a few platforms, find which and add ifdef */ -#if !defined(PS2) && !defined(PSP) + /* TODO: this is only useful for a few platforms, + * find which and add ifdef */ +#if defined(_3DS) if (stream->scheme != VFS_SCHEME_CDROM) { + stream->buf = (char*)calloc(1, 0x10000); + if (stream->fp) + setvbuf(stream->fp, stream->buf, _IOFBF, 0x10000); + } +#elif defined(WIIU) + if (stream->scheme != VFS_SCHEME_CDROM) + { + const int bufsize = 128 * 1024; + stream->buf = (char*)memalign(0x40, bufsize); + if (stream->fp) + setvbuf(stream->fp, stream->buf, _IOFBF, bufsize); stream->buf = (char*)calloc(1, 0x4000); if (stream->fp) setvbuf(stream->fp, stream->buf, _IOFBF, 0x4000); } -#endif #endif } else @@ -479,18 +514,12 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl( retro_vfs_file_seek_internal(stream, 0, SEEK_SET); - stream->mapped = (uint8_t*)mmap((void*)0, - stream->mapsize, PROT_READ, MAP_SHARED, stream->fd, 0); - - if (stream->mapped == MAP_FAILED) + if ((stream->mapped = (uint8_t*)mmap((void*)0, + stream->mapsize, PROT_READ, MAP_SHARED, stream->fd, 0)) == MAP_FAILED) stream->hints &= ~RETRO_VFS_FILE_ACCESS_HINT_FREQUENT_ACCESS; } #endif } -#ifdef ORBIS - stream->size = orbisLseek(stream->fd, 0, SEEK_END); - orbisLseek(stream->fd, 0, SEEK_SET); -#else #ifdef HAVE_CDROM if (stream->scheme == VFS_SCHEME_CDROM) { @@ -511,7 +540,6 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl( retro_vfs_file_seek_internal(stream, 0, SEEK_SET); } -#endif return stream; error: @@ -535,9 +563,7 @@ int retro_vfs_file_close_impl(libretro_vfs_implementation_file *stream) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) { if (stream->fp) - { fclose(stream->fp); - } } else { @@ -548,14 +574,7 @@ int retro_vfs_file_close_impl(libretro_vfs_implementation_file *stream) } if (stream->fd > 0) - { -#ifdef ORBIS - orbisClose(stream->fd); - stream->fd = -1; -#else close(stream->fd); -#endif - } #ifdef HAVE_CDROM end: if (stream->cdrom.cue_buf) @@ -578,12 +597,7 @@ int retro_vfs_file_error_impl(libretro_vfs_implementation_file *stream) if (stream->scheme == VFS_SCHEME_CDROM) return retro_vfs_file_error_cdrom(stream); #endif -#ifdef ORBIS - /* TODO/FIXME - implement this? */ - return 0; -#else return ferror(stream->fp); -#endif } int64_t retro_vfs_file_size_impl(libretro_vfs_implementation_file *stream) @@ -595,18 +609,20 @@ int64_t retro_vfs_file_size_impl(libretro_vfs_implementation_file *stream) int64_t retro_vfs_file_truncate_impl(libretro_vfs_implementation_file *stream, int64_t length) { - if (!stream) - return -1; - #ifdef _WIN32 - if (_chsize(_fileno(stream->fp), length) != 0) - return -1; + if (stream && _chsize(_fileno(stream->fp), length) == 0) + { + stream->size = length; + return 0; + } #elif !defined(VITA) && !defined(PSP) && !defined(PS2) && !defined(ORBIS) && (!defined(SWITCH) || defined(HAVE_LIBNX)) - if (ftruncate(fileno(stream->fp), length) != 0) - return -1; + if (stream && ftruncate(fileno(stream->fp), (off_t)length) == 0) + { + stream->size = length; + return 0; + } #endif - - return 0; + return -1; } int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream) @@ -620,26 +636,20 @@ int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream) if (stream->scheme == VFS_SCHEME_CDROM) return retro_vfs_file_tell_cdrom(stream); #endif -#ifdef ORBIS - { - int64_t ret = orbisLseek(stream->fd, 0, SEEK_CUR); - if (ret < 0) - return -1; - return ret; - } -#else - /* VC2005 and up have a special 64-bit ftell */ #ifdef ATLEAST_VC2005 + /* VC2005 and up have a special 64-bit ftell */ return _ftelli64(stream->fp); +#elif defined(HAVE_64BIT_OFFSETS) + return ftello(stream->fp); #else return ftell(stream->fp); -#endif #endif } #ifdef HAVE_MMAP /* Need to check stream->mapped because this function * is called in filestream_open() */ - if (stream->mapped && stream->hints & RETRO_VFS_FILE_ACCESS_HINT_FREQUENT_ACCESS) + if (stream->mapped && stream->hints & + RETRO_VFS_FILE_ACCESS_HINT_FREQUENT_ACCESS) return stream->mappos; #endif if (lseek(stream->fd, 0, SEEK_CUR) < 0) @@ -651,21 +661,7 @@ int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream) int64_t retro_vfs_file_seek_impl(libretro_vfs_implementation_file *stream, int64_t offset, int seek_position) { - int whence = -1; - switch (seek_position) - { - case RETRO_VFS_SEEK_POSITION_START: - whence = SEEK_SET; - break; - case RETRO_VFS_SEEK_POSITION_CURRENT: - whence = SEEK_CUR; - break; - case RETRO_VFS_SEEK_POSITION_END: - whence = SEEK_END; - break; - } - - return retro_vfs_file_seek_internal(stream, offset, whence); + return retro_vfs_file_seek_internal(stream, offset, seek_position); } int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, @@ -680,13 +676,7 @@ int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, if (stream->scheme == VFS_SCHEME_CDROM) return retro_vfs_file_read_cdrom(stream, s, len); #endif -#ifdef ORBIS - if (orbisRead(stream->fd, s, (size_t)len) < 0) - return -1; - return 0; -#else return fread(s, 1, (size_t)len, stream->fp); -#endif } #ifdef HAVE_MMAP if (stream->hints & RETRO_VFS_FILE_ACCESS_HINT_FREQUENT_ACCESS) @@ -709,36 +699,41 @@ int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, int64_t retro_vfs_file_write_impl(libretro_vfs_implementation_file *stream, const void *s, uint64_t len) { + int64_t pos = 0; + size_t result = -1; + if (!stream) return -1; if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) { -#ifdef ORBIS - if (orbisWrite(stream->fd, s, (size_t)len) < 0) - return -1; - return 0; -#else - return fwrite(s, 1, (size_t)len, stream->fp); -#endif - } + pos = retro_vfs_file_tell_impl(stream); + result = fwrite(s, 1, (size_t)len, stream->fp); + + if (result != -1 && pos + result > stream->size) + stream->size = pos + result; + return result; + } #ifdef HAVE_MMAP if (stream->hints & RETRO_VFS_FILE_ACCESS_HINT_FREQUENT_ACCESS) return -1; #endif - return write(stream->fd, s, (size_t)len); + + pos = retro_vfs_file_tell_impl(stream); + result = write(stream->fd, s, (size_t)len); + + if (result != -1 && pos + result > stream->size) + stream->size = pos + result; + + return result; } int retro_vfs_file_flush_impl(libretro_vfs_implementation_file *stream) { - if (!stream) - return -1; -#ifdef ORBIS - return 0; -#else - return fflush(stream->fp) == 0 ? 0 : -1; -#endif + if (stream && fflush(stream->fp) == 0) + return 0; + return -1; } int retro_vfs_file_remove_impl(const char *path) @@ -754,9 +749,7 @@ int retro_vfs_file_remove_impl(const char *path) if (!path || !*path) return -1; #if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 - path_local = utf8_to_local_string_alloc(path); - - if (path_local) + if ((path_local = utf8_to_local_string_alloc(path))) { int ret = remove(path_local); free(path_local); @@ -765,9 +758,7 @@ int retro_vfs_file_remove_impl(const char *path) return 0; } #else - path_wide = utf8_to_utf16_string_alloc(path); - - if (path_wide) + if ((path_wide = utf8_to_utf16_string_alloc(path))) { int ret = _wremove(path_wide); free(path_wide); @@ -776,16 +767,11 @@ int retro_vfs_file_remove_impl(const char *path) return 0; } #endif - return -1; -#elif defined(ORBIS) - /* Orbis - * TODO/FIXME - stub for now */ - return 0; #else if (remove(path) == 0) return 0; - return -1; #endif + return -1; } int retro_vfs_file_rename_impl(const char *old_path, const char *new_path) @@ -837,13 +823,6 @@ int retro_vfs_file_rename_impl(const char *old_path, const char *new_path) #endif return ret; -#elif defined(ORBIS) - /* Orbis */ - /* TODO/FIXME - Stub for now */ - if (!old_path || !*old_path || !new_path || !*new_path) - return -1; - return 0; - #else /* Every other platform */ if (!old_path || !*old_path || !new_path || !*new_path) @@ -863,12 +842,12 @@ const char *retro_vfs_file_get_path_impl( int retro_vfs_stat_impl(const char *path, int32_t *size) { -#if defined(VITA) || defined(PSP) - /* Vita / PSP */ - SceIoStat buf; - int stat_ret; bool is_dir = false; bool is_character_special = false; +#if defined(VITA) + /* Vita / PSP */ + SceIoStat buf; + int dir_ret; char *tmp = NULL; size_t len = 0; @@ -878,99 +857,34 @@ int retro_vfs_stat_impl(const char *path, int32_t *size) tmp = strdup(path); len = strlen(tmp); if (tmp[len-1] == '/') - tmp[len-1] = '\0'; + tmp[len-1] = '\0'; - stat_ret = sceIoGetstat(tmp, &buf); + dir_ret = sceIoGetstat(tmp, &buf); free(tmp); - if (stat_ret < 0) - return 0; - - if (size) - *size = (int32_t)buf.st_size; - - is_dir = FIO_S_ISDIR(buf.st_mode); - - return RETRO_VFS_STAT_IS_VALID | (is_dir ? RETRO_VFS_STAT_IS_DIRECTORY : 0) | (is_character_special ? RETRO_VFS_STAT_IS_CHARACTER_SPECIAL : 0); - -#elif defined(ORBIS) - /* Orbis */ - bool is_dir, is_character_special; - int dir_ret; - - if (!path || !*path) - return 0; - - if (size) - *size = (int32_t)buf.st_size; - - dir_ret = orbisDopen(path); - is_dir = dir_ret > 0; - orbisDclose(dir_ret); - - is_character_special = S_ISCHR(buf.st_mode); - - return RETRO_VFS_STAT_IS_VALID | (is_dir ? RETRO_VFS_STAT_IS_DIRECTORY : 0) | (is_character_special ? RETRO_VFS_STAT_IS_CHARACTER_SPECIAL : 0); - -#elif defined(PS2) - /* PS2 */ - iox_stat_t buf; - bool is_dir; - bool is_character_special = false; - char *tmp = NULL; - size_t len = 0; - - if (!path || !*path) + if (dir_ret < 0) return 0; - tmp = strdup(path); - len = strlen(tmp); - if (tmp[len-1] == '/') - tmp[len-1] = '\0'; - - fileXioGetStat(tmp, &buf); - free(tmp); - if (size) - *size = (int32_t)buf.size; - - if (!buf.mode) - { - /* if fileXioGetStat fails */ - int dir_ret = fileXioDopen(path); - is_dir = dir_ret > 0; - if (is_dir) { - fileXioDclose(dir_ret); - } - } - else - is_dir = FIO_S_ISDIR(buf.mode); - - return RETRO_VFS_STAT_IS_VALID | (is_dir ? RETRO_VFS_STAT_IS_DIRECTORY : 0) | (is_character_special ? RETRO_VFS_STAT_IS_CHARACTER_SPECIAL : 0); + *size = (int32_t)buf.st_size; -#elif defined(__CELLOS_LV2__) - /* CellOS Lv2 */ - bool is_dir; - bool is_character_special = false; - CellFsStat buf; + is_dir = FIO_S_ISDIR(buf.st_mode); +#elif defined(__PSL1GHT__) || defined(__PS3__) + /* Lowlevel Lv2 */ + sysFSStat buf; if (!path || !*path) return 0; - if (cellFsStat(path, &buf) < 0) + if (sysFsStat(path, &buf) < 0) return 0; if (size) - *size = (int32_t)buf.st_size; - - is_dir = ((buf.st_mode & S_IFMT) == S_IFDIR); - - return RETRO_VFS_STAT_IS_VALID | (is_dir ? RETRO_VFS_STAT_IS_DIRECTORY : 0) | (is_character_special ? RETRO_VFS_STAT_IS_CHARACTER_SPECIAL : 0); + *size = (int32_t)buf.st_size; + is_dir = ((buf.st_mode & S_IFMT) == S_IFDIR); #elif defined(_WIN32) /* Windows */ - bool is_dir; DWORD file_info; struct _stat buf; - bool is_character_special = false; #if defined(LEGACY_WIN32) char *path_local = NULL; #else @@ -981,8 +895,8 @@ int retro_vfs_stat_impl(const char *path, int32_t *size) return 0; #if defined(LEGACY_WIN32) - path_local = utf8_to_local_string_alloc(path); - file_info = GetFileAttributes(path_local); + path_local = utf8_to_local_string_alloc(path); + file_info = GetFileAttributes(path_local); if (!string_is_empty(path_local)) _stat(path_local, &buf); @@ -990,8 +904,8 @@ int retro_vfs_stat_impl(const char *path, int32_t *size) if (path_local) free(path_local); #else - path_wide = utf8_to_utf16_string_alloc(path); - file_info = GetFileAttributesW(path_wide); + path_wide = utf8_to_utf16_string_alloc(path); + file_info = GetFileAttributesW(path_wide); _wstat(path_wide, &buf); @@ -1007,11 +921,39 @@ int retro_vfs_stat_impl(const char *path, int32_t *size) is_dir = (file_info & FILE_ATTRIBUTE_DIRECTORY); - return RETRO_VFS_STAT_IS_VALID | (is_dir ? RETRO_VFS_STAT_IS_DIRECTORY : 0) | (is_character_special ? RETRO_VFS_STAT_IS_CHARACTER_SPECIAL : 0); +#elif defined(GEKKO) + /* On GEKKO platforms, paths cannot have + * trailing slashes - we must therefore + * remove them */ + char *path_buf = NULL; + int stat_ret = -1; + struct stat stat_buf; + size_t len; + + if (string_is_empty(path)) + return 0; + + if (!(path_buf = strdup(path))) + return 0; + + if ((len = strlen(path_buf)) > 0) + if (path_buf[len - 1] == '/') + path_buf[len - 1] = '\0'; + + stat_ret = stat(path_buf, &stat_buf); + free(path_buf); + + if (stat_ret < 0) + return 0; + + if (size) + *size = (int32_t)stat_buf.st_size; + + is_dir = S_ISDIR(stat_buf.st_mode); + is_character_special = S_ISCHR(stat_buf.st_mode); #else /* Every other platform */ - bool is_dir, is_character_special; struct stat buf; if (!path || !*path) @@ -1024,14 +966,13 @@ int retro_vfs_stat_impl(const char *path, int32_t *size) is_dir = S_ISDIR(buf.st_mode); is_character_special = S_ISCHR(buf.st_mode); - - return RETRO_VFS_STAT_IS_VALID | (is_dir ? RETRO_VFS_STAT_IS_DIRECTORY : 0) | (is_character_special ? RETRO_VFS_STAT_IS_CHARACTER_SPECIAL : 0); #endif + return RETRO_VFS_STAT_IS_VALID | (is_dir ? RETRO_VFS_STAT_IS_DIRECTORY : 0) | (is_character_special ? RETRO_VFS_STAT_IS_CHARACTER_SPECIAL : 0); } #if defined(VITA) #define path_mkdir_error(ret) (((ret) == SCE_ERROR_ERRNO_EEXIST)) -#elif defined(PSP) || defined(PS2) || defined(_3DS) || defined(WIIU) || defined(SWITCH) || defined(ORBIS) +#elif defined(PSP) || defined(PS2) || defined(_3DS) || defined(WIIU) || defined(SWITCH) #define path_mkdir_error(ret) ((ret) == -1) #else #define path_mkdir_error(ret) ((ret) < 0 && errno == EEXIST) @@ -1041,27 +982,45 @@ int retro_vfs_mkdir_impl(const char *dir) { #if defined(_WIN32) #ifdef LEGACY_WIN32 - int ret = _mkdir(dir); + int ret = _mkdir(dir); #else - wchar_t *dirW = utf8_to_utf16_string_alloc(dir); - int ret = -1; + wchar_t *dir_w = utf8_to_utf16_string_alloc(dir); + int ret = -1; - if (dirW) + if (dir_w) { - ret = _wmkdir(dirW); - free(dirW); + ret = _wmkdir(dir_w); + free(dir_w); } #endif #elif defined(IOS) int ret = mkdir(dir, 0755); -#elif defined(VITA) || defined(PSP) +#elif defined(VITA) int ret = sceIoMkdir(dir, 0777); -#elif defined(PS2) - int ret = fileXioMkdir(dir, 0777); -#elif defined(ORBIS) - int ret = orbisMkdir(dir, 0755); #elif defined(__QNX__) int ret = mkdir(dir, 0777); +#elif defined(GEKKO) || defined(WIIU) + /* On GEKKO platforms, mkdir() fails if + * the path has a trailing slash. We must + * therefore remove it. */ + int ret = -1; + if (!string_is_empty(dir)) + { + char *dir_buf = strdup(dir); + + if (dir_buf) + { + size_t len = strlen(dir_buf); + + if (len > 0) + if (dir_buf[len - 1] == '/') + dir_buf[len - 1] = '\0'; + + ret = mkdir(dir_buf, 0750); + + free(dir_buf); + } + } #else int ret = mkdir(dir, 0750); #endif @@ -1087,19 +1046,13 @@ struct libretro_vfs_implementation_dir HANDLE directory; bool next; char path[PATH_MAX_LENGTH]; -#elif defined(VITA) || defined(PSP) +#elif defined(VITA) SceUID directory; SceIoDirent entry; -#elif defined(PS2) +#elif defined(__PSL1GHT__) || defined(__PS3__) + int error; int directory; - iox_dirent_t entry; -#elif defined(__CELLOS_LV2__) - CellFsErrno error; - int directory; - CellFsDirent entry; -#elif defined(ORBIS) - int directory; - struct dirent entry; + sysFSDirent entry; #else DIR *directory; const struct dirent *entry; @@ -1110,10 +1063,10 @@ static bool dirent_check_error(libretro_vfs_implementation_dir *rdir) { #if defined(_WIN32) return (rdir->directory == INVALID_HANDLE_VALUE); -#elif defined(VITA) || defined(PSP) || defined(PS2) || defined(ORBIS) +#elif defined(VITA) || defined(ORBIS) return (rdir->directory < 0); -#elif defined(__CELLOS_LV2__) - return (rdir->error != CELL_FS_SUCCEEDED); +#elif defined(__PSL1GHT__) || defined(__PS3__) + return (rdir->error != FS_SUCCEEDED); #else return !(rdir->directory); #endif @@ -1123,7 +1076,6 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl( const char *name, bool include_hidden) { #if defined(_WIN32) - unsigned path_len; char path_buf[1024]; size_t copied = 0; #if defined(LEGACY_WIN32) @@ -1134,28 +1086,25 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl( #endif libretro_vfs_implementation_dir *rdir; - /*Reject null or empty string paths*/ + /* Reject NULL or empty string paths*/ if (!name || (*name == 0)) return NULL; /*Allocate RDIR struct. Tidied later with retro_closedir*/ - rdir = (libretro_vfs_implementation_dir*)calloc(1, sizeof(*rdir)); - if (!rdir) + if (!(rdir = (libretro_vfs_implementation_dir*) + calloc(1, sizeof(*rdir)))) return NULL; rdir->orig_path = strdup(name); #if defined(_WIN32) - path_buf[0] = '\0'; - path_len = strlen(name); - copied = strlcpy(path_buf, name, sizeof(path_buf)); /* Non-NT platforms don't like extra slashes in the path */ - if (name[path_len - 1] != '\\') - path_buf[copied++] = '\\'; + if (path_buf[copied - 1] != '\\') + path_buf [copied++] = '\\'; - path_buf[copied] = '*'; + path_buf[copied ] = '*'; path_buf[copied+1] = '\0'; #if defined(LEGACY_WIN32) @@ -1172,17 +1121,13 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl( free(path_wide); #endif -#elif defined(VITA) || defined(PSP) +#elif defined(VITA) rdir->directory = sceIoDopen(name); -#elif defined(PS2) - rdir->directory = ps2fileXioDopen(name); #elif defined(_3DS) rdir->directory = !string_is_empty(name) ? opendir(name) : NULL; rdir->entry = NULL; -#elif defined(__CELLOS_LV2__) - rdir->error = cellFsOpendir(name, &rdir->directory); -#elif defined(ORBIS) - rdir->directory = orbisDopen(name); +#elif defined(__PSL1GHT__) || defined(__PS3__) + rdir->error = sysFsOpendir(name, &rdir->directory); #else rdir->directory = opendir(name); rdir->entry = NULL; @@ -1214,19 +1159,12 @@ bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *rdir) rdir->next = true; return (rdir->directory != INVALID_HANDLE_VALUE); -#elif defined(VITA) || defined(PSP) +#elif defined(VITA) return (sceIoDread(rdir->directory, &rdir->entry) > 0); -#elif defined(PS2) - iox_dirent_t record; - int ret = ps2fileXioDread(rdir->directory, &record); - rdir->entry = record; - return ( ret > 0); -#elif defined(__CELLOS_LV2__) +#elif defined(__PSL1GHT__) || defined(__PS3__) uint64_t nread; - rdir->error = cellFsReaddir(rdir->directory, &rdir->entry, &nread); + rdir->error = sysFsReaddir(rdir->directory, &rdir->entry, &nread); return (nread != 0); -#elif defined(ORBIS) - return (orbisDread(rdir->directory, &rdir->entry) > 0); #else return ((rdir->entry = readdir(rdir->directory)) != NULL); #endif @@ -1236,29 +1174,17 @@ const char *retro_vfs_dirent_get_name_impl(libretro_vfs_implementation_dir *rdir { #if defined(_WIN32) #if defined(LEGACY_WIN32) - { - char *name_local = local_to_utf8_string_alloc(rdir->entry.cFileName); - memset(rdir->entry.cFileName, 0, sizeof(rdir->entry.cFileName)); - strlcpy(rdir->entry.cFileName, name_local, sizeof(rdir->entry.cFileName)); - - if (name_local) - free(name_local); - } + char *name = local_to_utf8_string_alloc(rdir->entry.cFileName); #else - { - char *name = utf16_to_utf8_string_alloc(rdir->entry.cFileName); - memset(rdir->entry.cFileName, 0, sizeof(rdir->entry.cFileName)); - strlcpy((char*)rdir->entry.cFileName, name, sizeof(rdir->entry.cFileName)); - - if (name) - free(name); - } + char *name = utf16_to_utf8_string_alloc(rdir->entry.cFileName); #endif + memset(rdir->entry.cFileName, 0, sizeof(rdir->entry.cFileName)); + strlcpy((char*)rdir->entry.cFileName, name, sizeof(rdir->entry.cFileName)); + if (name) + free(name); return (char*)rdir->entry.cFileName; -#elif defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__) || defined(ORBIS) +#elif defined(VITA) || defined(__PSL1GHT__) || defined(__PS3__) return rdir->entry.d_name; -#elif defined(PS2) - return rdir->entry.name; #else if (!rdir || !rdir->entry) return NULL; @@ -1271,25 +1197,12 @@ bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *rdir) #if defined(_WIN32) const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)&rdir->entry; return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; -#elif defined(PSP) || defined(VITA) - const SceIoDirent *entry = (const SceIoDirent*)&rdir->entry; -#if defined(PSP) - return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR; #elif defined(VITA) + const SceIoDirent *entry = (const SceIoDirent*)&rdir->entry; return SCE_S_ISDIR(entry->d_stat.st_mode); -#endif -#elif defined(PS2) - const iox_dirent_t *entry = (const iox_dirent_t*)&rdir->entry; - return FIO_S_ISDIR(entry->stat.mode); -#elif defined(__CELLOS_LV2__) - CellFsDirent *entry = (CellFsDirent*)&rdir->entry; - return (entry->d_type == CELL_FS_TYPE_DIRECTORY); -#elif defined(ORBIS) - const struct dirent *entry = &rdir->entry; - if (entry->d_type == DT_DIR) - return true; - if (!(entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK)) - return false; +#elif defined(__PSL1GHT__) || defined(__PS3__) + sysFSDirent *entry = (sysFSDirent*)&rdir->entry; + return (entry->d_type == FS_TYPE_DIR); #else struct stat buf; char path[PATH_MAX_LENGTH]; @@ -1302,8 +1215,7 @@ bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *rdir) return false; #endif /* dirent struct doesn't have d_type, do it the slow way ... */ - path[0] = '\0'; - fill_pathname_join(path, rdir->orig_path, retro_vfs_dirent_get_name_impl(rdir), sizeof(path)); + fill_pathname_join_special(path, rdir->orig_path, retro_vfs_dirent_get_name_impl(rdir), sizeof(path)); if (stat(path, &buf) < 0) return false; return S_ISDIR(buf.st_mode); @@ -1318,14 +1230,10 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir) #if defined(_WIN32) if (rdir->directory != INVALID_HANDLE_VALUE) FindClose(rdir->directory); -#elif defined(VITA) || defined(PSP) +#elif defined(VITA) sceIoDclose(rdir->directory); -#elif defined(PS2) - ps2fileXioDclose(rdir->directory); -#elif defined(__CELLOS_LV2__) - rdir->error = cellFsClosedir(rdir->directory); -#elif defined(ORBIS) - orbisDclose(rdir->directory); +#elif defined(__PSL1GHT__) || defined(__PS3__) + rdir->error = sysFsClosedir(rdir->directory); #else if (rdir->directory) closedir(rdir->directory); diff --git a/src/libretro/libretro-common/vfs/vfs_implementation_cdrom.c b/src/libretro/libretro-common/vfs/vfs_implementation_cdrom.c index 537dc7acac..093cd9cc02 100644 --- a/src/libretro/libretro-common/vfs/vfs_implementation_cdrom.c +++ b/src/libretro/libretro-common/vfs/vfs_implementation_cdrom.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2019 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vfs_implementation_cdrom.c). @@ -30,6 +30,7 @@ #include #endif +/* TODO/FIXME - static global variable */ static cdrom_toc_t vfs_cdrom_toc = {0}; const cdrom_toc_t* retro_vfs_file_get_cdrom_toc(void) @@ -37,7 +38,9 @@ const cdrom_toc_t* retro_vfs_file_get_cdrom_toc(void) return &vfs_cdrom_toc; } -int64_t retro_vfs_file_seek_cdrom(libretro_vfs_implementation_file *stream, int64_t offset, int whence) +int64_t retro_vfs_file_seek_cdrom( + libretro_vfs_implementation_file *stream, + int64_t offset, int whence) { const char *ext = path_get_extension(stream->orig_path); @@ -52,68 +55,84 @@ int64_t retro_vfs_file_seek_cdrom(libretro_vfs_implementation_file *stream, int6 stream->cdrom.byte_pos += offset; break; case SEEK_END: - stream->cdrom.byte_pos = (stream->cdrom.cue_len - 1) + offset; + stream->cdrom.byte_pos = (stream->cdrom.cue_len - 1) + offset; break; } #ifdef CDROM_DEBUG - printf("[CDROM] Seek: Path %s Offset %" PRIu64 " is now at %" PRIu64 "\n", stream->orig_path, offset, stream->cdrom.byte_pos); + printf("[CDROM] Seek: Path %s Offset %" PRIu64 " is now at %" PRIu64 "\n", + stream->orig_path, + offset, + stream->cdrom.byte_pos); fflush(stdout); #endif } else if (string_is_equal_noncase(ext, "bin")) { - int lba = (offset / 2352); - unsigned char min = 0; - unsigned char sec = 0; - unsigned char frame = 0; + int lba = (offset / 2352); + unsigned char min = 0; + unsigned char sec = 0; + unsigned char frame = 0; +#ifdef CDROM_DEBUG const char *seek_type = "SEEK_SET"; - - (void)seek_type; +#endif switch (whence) { case SEEK_CUR: - { - unsigned new_lba; - - stream->cdrom.byte_pos += offset; - new_lba = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352); - seek_type = "SEEK_CUR"; - - cdrom_lba_to_msf(new_lba, &min, &sec, &frame); + { + unsigned new_lba; +#ifdef CDROM_DEBUG + seek_type = "SEEK_CUR"; +#endif + stream->cdrom.byte_pos += offset; + new_lba = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352); + cdrom_lba_to_msf(new_lba, &min, &sec, &frame); + } break; - } case SEEK_END: - { - ssize_t pregap_lba_len = (vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].audio ? 0 : (vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba - vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba_start)); - ssize_t lba_len = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_size - pregap_lba_len; - - cdrom_lba_to_msf(lba_len + lba, &min, &sec, &frame); - - stream->cdrom.byte_pos = lba_len * 2352; - seek_type = "SEEK_END"; + { + ssize_t pregap_lba_len = (vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].audio + ? 0 + : (vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba - vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba_start)); + ssize_t lba_len = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_size - pregap_lba_len; +#ifdef CDROM_DEBUG + seek_type = "SEEK_END"; +#endif + cdrom_lba_to_msf(lba_len + lba, &min, &sec, &frame); + stream->cdrom.byte_pos = lba_len * 2352; + } break; - } case SEEK_SET: default: - { - seek_type = "SEEK_SET"; - stream->cdrom.byte_pos = offset; - cdrom_lba_to_msf(vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352), &min, &sec, &frame); + { +#ifdef CDROM_DEBUG + seek_type = "SEEK_SET"; +#endif + stream->cdrom.byte_pos = offset; + cdrom_lba_to_msf(vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352), &min, &sec, &frame); + } break; - } } - stream->cdrom.cur_min = min; - stream->cdrom.cur_sec = sec; + stream->cdrom.cur_min = min; + stream->cdrom.cur_sec = sec; stream->cdrom.cur_frame = frame; - stream->cdrom.cur_lba = cdrom_msf_to_lba(min, sec, frame); + stream->cdrom.cur_lba = cdrom_msf_to_lba(min, sec, frame); #ifdef CDROM_DEBUG - printf("[CDROM] Seek %s: Path %s Offset %" PRIu64 " is now at %" PRIu64 " (MSF %02u:%02u:%02u) (LBA %u)...\n", seek_type, stream->orig_path, offset, stream->cdrom.byte_pos, (unsigned)stream->cdrom.cur_min, (unsigned)stream->cdrom.cur_sec, (unsigned)stream->cdrom.cur_frame, stream->cdrom.cur_lba); + printf( + "[CDROM] Seek %s: Path %s Offset %" PRIu64 " is now at %" PRIu64 " (MSF %02u:%02u:%02u) (LBA %u)...\n", + seek_type, + stream->orig_path, + offset, + stream->cdrom.byte_pos, + (unsigned)stream->cdrom.cur_min, + (unsigned)stream->cdrom.cur_sec, + (unsigned)stream->cdrom.cur_frame, + stream->cdrom.cur_lba); fflush(stdout); #endif } @@ -128,20 +147,21 @@ void retro_vfs_file_open_cdrom( const char *path, unsigned mode, unsigned hints) { #if defined(__linux__) && !defined(ANDROID) - char cdrom_path[] = "/dev/sg1"; - size_t path_len = strlen(path); - const char *ext = path_get_extension(path); + char cdrom_path[] = "/dev/sg1"; + size_t path_len = strlen(path); + const char *ext = path_get_extension(path); stream->cdrom.cur_track = 1; - if (!string_is_equal_noncase(ext, "cue") && !string_is_equal_noncase(ext, "bin")) + if ( !string_is_equal_noncase(ext, "cue") + && !string_is_equal_noncase(ext, "bin")) return; - if (path_len >= strlen("drive1-track01.bin")) + if (path_len >= STRLEN_CONST("drive1-track01.bin")) { - if (!memcmp(path, "drive", strlen("drive"))) + if (!memcmp(path, "drive", STRLEN_CONST("drive"))) { - if (!memcmp(path + 6, "-track", strlen("-track"))) + if (!memcmp(path + 6, "-track", STRLEN_CONST("-track"))) { if (sscanf(path + 12, "%02u", (unsigned*)&stream->cdrom.cur_track)) { @@ -154,13 +174,13 @@ void retro_vfs_file_open_cdrom( } } - if (path_len >= strlen("drive1.cue")) + if (path_len >= STRLEN_CONST("drive1.cue")) { - if (!memcmp(path, "drive", strlen("drive"))) + if (!memcmp(path, "drive", STRLEN_CONST("drive"))) { if (path[5] >= '0' && path[5] <= '9') { - cdrom_path[7] = path[5]; + cdrom_path[7] = path[5]; stream->cdrom.drive = path[5]; vfs_cdrom_toc.drive = stream->cdrom.drive; } @@ -184,7 +204,12 @@ void retro_vfs_file_open_cdrom( stream->cdrom.cue_buf = NULL; } - cdrom_write_cue(stream, &stream->cdrom.cue_buf, &stream->cdrom.cue_len, stream->cdrom.drive, &vfs_cdrom_toc.num_tracks, &vfs_cdrom_toc); + cdrom_write_cue(stream, + &stream->cdrom.cue_buf, + &stream->cdrom.cue_len, + stream->cdrom.drive, + &vfs_cdrom_toc.num_tracks, + &vfs_cdrom_toc); cdrom_get_timeouts(stream, &vfs_cdrom_toc.timeouts); #ifdef CDROM_DEBUG @@ -203,15 +228,16 @@ void retro_vfs_file_open_cdrom( #endif #if defined(_WIN32) && !defined(_XBOX) char cdrom_path[] = "\\\\.\\D:"; - size_t path_len = strlen(path); - const char *ext = path_get_extension(path); + size_t path_len = strlen(path); + const char *ext = path_get_extension(path); - if (!string_is_equal_noncase(ext, "cue") && !string_is_equal_noncase(ext, "bin")) + if ( !string_is_equal_noncase(ext, "cue") + && !string_is_equal_noncase(ext, "bin")) return; - if (path_len >= strlen("d:/drive-track01.bin")) + if (path_len >= STRLEN_CONST("d:/drive-track01.bin")) { - if (!memcmp(path + 1, ":/drive-track", strlen(":/drive-track"))) + if (!memcmp(path + 1, ":/drive-track", STRLEN_CONST(":/drive-track"))) { if (sscanf(path + 14, "%02u", (unsigned*)&stream->cdrom.cur_track)) { @@ -223,13 +249,13 @@ void retro_vfs_file_open_cdrom( } } - if (path_len >= strlen("d:/drive.cue")) + if (path_len >= STRLEN_CONST("d:/drive.cue")) { - if (!memcmp(path + 1, ":/drive", strlen(":/drive"))) + if (!memcmp(path + 1, ":/drive", STRLEN_CONST(":/drive"))) { if ((path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z')) { - cdrom_path[4] = path[0]; + cdrom_path[4] = path[0]; stream->cdrom.drive = path[0]; vfs_cdrom_toc.drive = stream->cdrom.drive; } @@ -240,7 +266,13 @@ void retro_vfs_file_open_cdrom( printf("[CDROM] Open: Path %s URI %s\n", cdrom_path, path); fflush(stdout); #endif - stream->fh = CreateFile(cdrom_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + stream->fh = CreateFile(cdrom_path, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); if (stream->fh == INVALID_HANDLE_VALUE) return; @@ -253,8 +285,14 @@ void retro_vfs_file_open_cdrom( stream->cdrom.cue_buf = NULL; } - cdrom_write_cue(stream, &stream->cdrom.cue_buf, &stream->cdrom.cue_len, stream->cdrom.drive, &vfs_cdrom_toc.num_tracks, &vfs_cdrom_toc); - cdrom_get_timeouts(stream, &vfs_cdrom_toc.timeouts); + cdrom_write_cue(stream, + &stream->cdrom.cue_buf, + &stream->cdrom.cue_len, + stream->cdrom.drive, + &vfs_cdrom_toc.num_tracks, + &vfs_cdrom_toc); + cdrom_get_timeouts(stream, + &vfs_cdrom_toc.timeouts); #ifdef CDROM_DEBUG if (string_is_empty(stream->cdrom.cue_buf)) @@ -272,17 +310,17 @@ void retro_vfs_file_open_cdrom( #endif if (vfs_cdrom_toc.num_tracks > 1 && stream->cdrom.cur_track) { - stream->cdrom.cur_min = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].min; - stream->cdrom.cur_sec = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].sec; + stream->cdrom.cur_min = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].min; + stream->cdrom.cur_sec = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].sec; stream->cdrom.cur_frame = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].frame; - stream->cdrom.cur_lba = cdrom_msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame); + stream->cdrom.cur_lba = cdrom_msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame); } else { - stream->cdrom.cur_min = vfs_cdrom_toc.track[0].min; - stream->cdrom.cur_sec = vfs_cdrom_toc.track[0].sec; + stream->cdrom.cur_min = vfs_cdrom_toc.track[0].min; + stream->cdrom.cur_sec = vfs_cdrom_toc.track[0].sec; stream->cdrom.cur_frame = vfs_cdrom_toc.track[0].frame; - stream->cdrom.cur_lba = cdrom_msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame); + stream->cdrom.cur_lba = cdrom_msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame); } } @@ -340,52 +378,69 @@ int64_t retro_vfs_file_read_cdrom(libretro_vfs_implementation_file *stream, if (string_is_equal_noncase(ext, "cue")) { - if ((int64_t)len < (int64_t)stream->cdrom.cue_len - stream->cdrom.byte_pos) - { + if ((int64_t)len >= (int64_t)stream->cdrom.cue_len + - stream->cdrom.byte_pos) + len = stream->cdrom.cue_len - stream->cdrom.byte_pos - 1; #ifdef CDROM_DEBUG - printf("[CDROM] Read: Reading %" PRIu64 " bytes from cuesheet starting at %" PRIu64 "...\n", len, stream->cdrom.byte_pos); - fflush(stdout); + printf( + "[CDROM] Read: Reading %" PRIu64 " bytes from cuesheet starting at %" PRIu64 "...\n", + len, + stream->cdrom.byte_pos); + fflush(stdout); #endif - memcpy(s, stream->cdrom.cue_buf + stream->cdrom.byte_pos, len); - stream->cdrom.byte_pos += len; + memcpy(s, stream->cdrom.cue_buf + stream->cdrom.byte_pos, len); + stream->cdrom.byte_pos += len; - return len; - } - else - { -#ifdef CDROM_DEBUG - printf("[CDROM] Read: Reading %" PRIu64 " bytes from cuesheet starting at %" PRIu64 " failed.\n", len, stream->cdrom.byte_pos); - fflush(stdout); -#endif - return 0; - } + return len; } else if (string_is_equal_noncase(ext, "bin")) { - size_t skip = stream->cdrom.byte_pos % 2352; - unsigned char min = 0; - unsigned char sec = 0; - unsigned char frame = 0; - unsigned char rmin = 0; - unsigned char rsec = 0; + unsigned char min = 0; + unsigned char sec = 0; + unsigned char frame = 0; + unsigned char rmin = 0; + unsigned char rsec = 0; unsigned char rframe = 0; + size_t skip = stream->cdrom.byte_pos % 2352; - if (stream->cdrom.byte_pos >= vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_bytes) + if (stream->cdrom.byte_pos >= + vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_bytes) return 0; - if (stream->cdrom.byte_pos + len > vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_bytes) - len -= (stream->cdrom.byte_pos + len) - vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_bytes; + if (stream->cdrom.byte_pos + len > + vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_bytes) + len -= (stream->cdrom.byte_pos + len) + - vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_bytes; cdrom_lba_to_msf(stream->cdrom.cur_lba, &min, &sec, &frame); - cdrom_lba_to_msf(stream->cdrom.cur_lba - vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba, &rmin, &rsec, &rframe); + cdrom_lba_to_msf(stream->cdrom.cur_lba + - vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba, + &rmin, &rsec, &rframe); #ifdef CDROM_DEBUG - printf("[CDROM] Read: Reading %" PRIu64 " bytes from %s starting at byte offset %" PRIu64 " (rMSF %02u:%02u:%02u aMSF %02u:%02u:%02u) (LBA %u) skip %" PRIu64 "...\n", len, stream->orig_path, stream->cdrom.byte_pos, (unsigned)rmin, (unsigned)rsec, (unsigned)rframe, (unsigned)min, (unsigned)sec, (unsigned)frame, stream->cdrom.cur_lba, skip); + printf( + "[CDROM] Read: Reading %" PRIu64 " bytes from %s starting at byte offset %" PRIu64 " (rMSF %02u:%02u:%02u aMSF %02u:%02u:%02u) (LBA %u) skip %" PRIu64 "...\n", + len, + stream->orig_path, + stream->cdrom.byte_pos, + (unsigned)rmin, + (unsigned)rsec, + (unsigned)rframe, + (unsigned)min, + (unsigned)sec, + (unsigned)frame, + stream->cdrom.cur_lba, + skip); fflush(stdout); #endif - rv = cdrom_read(stream, &vfs_cdrom_toc.timeouts, min, sec, frame, s, (size_t)len, skip); - /*rv = cdrom_read_lba(stream, stream->cdrom.cur_lba, s, (size_t)len, skip);*/ +#if 1 + rv = cdrom_read(stream, &vfs_cdrom_toc.timeouts, min, sec, + frame, s, (size_t)len, skip); +#else + rv = cdrom_read_lba(stream, stream->cdrom.cur_lba, s, + (size_t)len, skip); +#endif if (rv) { @@ -397,12 +452,28 @@ int64_t retro_vfs_file_read_cdrom(libretro_vfs_implementation_file *stream, } stream->cdrom.byte_pos += len; - stream->cdrom.cur_lba = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352); + stream->cdrom.cur_lba = + vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + + (stream->cdrom.byte_pos / 2352); - cdrom_lba_to_msf(stream->cdrom.cur_lba, &stream->cdrom.cur_min, &stream->cdrom.cur_sec, &stream->cdrom.cur_frame); + cdrom_lba_to_msf(stream->cdrom.cur_lba, + &stream->cdrom.cur_min, + &stream->cdrom.cur_sec, + &stream->cdrom.cur_frame); #ifdef CDROM_DEBUG - printf("[CDROM] read %" PRIu64 " bytes, position is now: %" PRIu64 " (MSF %02u:%02u:%02u) (LBA %u)\n", len, stream->cdrom.byte_pos, (unsigned)stream->cdrom.cur_min, (unsigned)stream->cdrom.cur_sec, (unsigned)stream->cdrom.cur_frame, cdrom_msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame)); + printf( + "[CDROM] read %" PRIu64 " bytes, position is now: %" PRIu64 " (MSF %02u:%02u:%02u) (LBA %u)\n", + len, + stream->cdrom.byte_pos, + (unsigned)stream->cdrom.cur_min, + (unsigned)stream->cdrom.cur_sec, + (unsigned)stream->cdrom.cur_frame, + cdrom_msf_to_lba( + stream->cdrom.cur_min, + stream->cdrom.cur_sec, + stream->cdrom.cur_frame) + ); fflush(stdout); #endif @@ -417,7 +488,8 @@ int retro_vfs_file_error_cdrom(libretro_vfs_implementation_file *stream) return 0; } -const vfs_cdrom_t* retro_vfs_file_get_cdrom_position(const libretro_vfs_implementation_file *stream) +const vfs_cdrom_t* retro_vfs_file_get_cdrom_position( + const libretro_vfs_implementation_file *stream) { return &stream->cdrom; }