diff --git a/Makefile.libretro b/Makefile.libretro index 19895dee3..0d870ef97 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -840,6 +840,12 @@ LIBRETRO_CFLAGS += $(BPP_DEFINES) \ -DHAVE_OPLL_CORE \ -DMAXROMSIZE=$(MAX_ROM_SIZE) +ifneq (,$(findstring msvc,$(platform))) + LIBRETRO_CFLAGS += -DINLINE="static _inline" +else + LIBRETRO_CFLAGS += -DINLINE="static inline" +endif + OBJOUT = -o LINKOUT = -o diff --git a/core/macros.h b/core/macros.h index f4fea8a37..511de0bd3 100644 --- a/core/macros.h +++ b/core/macros.h @@ -42,12 +42,8 @@ * If you define INLINE in makefile or osd.h, it will override this value. * NOTE: not enabling inline functions will SEVERELY slow down emulation. */ -#ifndef INLINE -#if defined(_MSC_VER) -#define INLINE static _inline -#else -#define INLINE static __inline__ -#endif +#ifndef INLINE +#define INLINE static __inline__ #endif /* INLINE */ /* Alignment macros for cross compiler compatibility */ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index f78c5de81..ac77aca98 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -72,8 +72,7 @@ endif ifeq ($(HAVE_CDROM), 1) SOURCES_C += \ $(LIBRETRO_COMM_DIR)/cdrom/cdrom.c \ - $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation_cdrom.c \ - $(LIBRETRO_COMM_DIR)/time/rtime.c + $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation_cdrom.c endif SOURCES_C += \ $(LIBRETRO_DEPS_DIR)/zlib-1.2.11/adler32.c \ diff --git a/libretro/deps/libchdr/include/libchdr/cdrom.h b/libretro/deps/libchdr/include/libchdr/cdrom.h index 460888de7..5bd4a2e02 100644 --- a/libretro/deps/libchdr/include/libchdr/cdrom.h +++ b/libretro/deps/libchdr/include/libchdr/cdrom.h @@ -16,14 +16,6 @@ #include #include -#ifndef INLINE -#if defined(_MSC_VER) -#define INLINE static _inline -#else -#define INLINE static __inline__ -#endif -#endif /* INLINE */ - /*************************************************************************** CONSTANTS ***************************************************************************/ diff --git a/libretro/libretro-common/cdrom/cdrom.c b/libretro/libretro-common/cdrom/cdrom.c index 58cb5cf18..55fa67368 100644 --- a/libretro/libretro-common/cdrom/cdrom.c +++ b/libretro/libretro-common/cdrom/cdrom.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2020 The RetroArch team +/* Copyright (C) 2010-2019 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (cdrom.c). @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -97,7 +96,6 @@ void increment_msf(unsigned char *min, unsigned char *sec, unsigned char *frame) *frame = (*frame < 74) ? (*frame + 1) : 0; } -#ifdef CDROM_DEBUG static void cdrom_print_sense_data(const unsigned char *sense, size_t len) { unsigned i; @@ -177,7 +175,7 @@ static void cdrom_print_sense_data(const unsigned char *sense, size_t len) break; } - printf("[CDROM] Sense Key: %02X (%s)\n", key, sense_key_text ? sense_key_text : "null"); + printf("[CDROM] Sense Key: %02X (%s)\n", key, sense_key_text); printf("[CDROM] ASC: %02X\n", asc); printf("[CDROM] ASCQ: %02X\n", ascq); @@ -254,7 +252,6 @@ static void cdrom_print_sense_data(const unsigned char *sense, size_t len) fflush(stdout); } -#endif #if defined(_WIN32) && !defined(_XBOX) static int cdrom_send_command_win32(const libretro_vfs_implementation_file *stream, CDROM_CMD_Direction dir, void *buf, size_t len, unsigned char *cmd, size_t cmd_len, unsigned char *sense, size_t sense_len) @@ -522,9 +519,7 @@ static int cdrom_send_command(libretro_vfs_implementation_file *stream, CDROM_CM } else { -#ifdef CDROM_DEBUG cdrom_print_sense_data(sense, sizeof(sense)); -#endif /* INQUIRY/TEST/SENSE should never fail, don't retry. */ /* READ ATIP seems to fail outright on some drives with pressed discs, skip retries. */ @@ -677,9 +672,7 @@ int cdrom_get_sense(libretro_vfs_implementation_file *stream, unsigned char *sen if (rv) return 1; -#ifdef CDROM_DEBUG cdrom_print_sense_data(buf, sizeof(buf)); -#endif return 0; } @@ -938,23 +931,23 @@ int cdrom_read_subq(libretro_vfs_implementation_file *stream, unsigned char *buf if (/*(control == 4 || control == 6) && */adr == 1 && tno == 0 && point >= 1 && point <= 99) { printf("[CDROM] - Session#: %d TNO %d POINT %d ", session_num, tno, point); - printf("Track start time: (aMSF %02u:%02u:%02u) ", (unsigned)pmin, (unsigned)psec, (unsigned)pframe); + printf("[CDROM] Track start time: (MSF %02u:%02u:%02u) ", (unsigned)pmin, (unsigned)psec, (unsigned)pframe); } else if (/*(control == 4 || control == 6) && */adr == 1 && tno == 0 && point == 0xA0) { printf("[CDROM] - Session#: %d TNO %d POINT %d ", session_num, tno, point); - printf("First Track Number: %d ", pmin); - printf("Disc Type: %d ", psec); + printf("[CDROM] First Track Number: %d ", pmin); + printf("[CDROM] Disc Type: %d ", psec); } else if (/*(control == 4 || control == 6) && */adr == 1 && tno == 0 && point == 0xA1) { printf("[CDROM] - Session#: %d TNO %d POINT %d ", session_num, tno, point); - printf("Last Track Number: %d ", pmin); + printf("[CDROM] Last Track Number: %d ", pmin); } else if (/*(control == 4 || control == 6) && */adr == 1 && tno == 0 && point == 0xA2) { printf("[CDROM] - Session#: %d TNO %d POINT %d ", session_num, tno, point); - printf("Lead-out start time: (aMSF %02u:%02u:%02u) ", (unsigned)pmin, (unsigned)psec, (unsigned)pframe); + printf("[CDROM] Lead-out runtime: (MSF %02u:%02u:%02u) ", (unsigned)pmin, (unsigned)psec, (unsigned)pframe); } printf("\n"); @@ -999,10 +992,10 @@ static int cdrom_read_track_info(libretro_vfs_implementation_file *stream, unsig #ifdef CDROM_DEBUG printf("[CDROM] Track %d Info: ", track); - printf("Copy: %d ", (buf[5] & 0x10) > 0); - printf("Data Mode: %d ", toc->track[track - 1].mode); - printf("LBA Start: %d (%d) ", lba, toc->track[track - 1].lba); - printf("Track Size: %d\n", track_size); + printf("[CDROM] Copy: %d ", (buf[5] & 0x10) > 0); + printf("[CDROM] Data Mode: %d ", toc->track[track - 1].mode); + printf("[CDROM] LBA Start: %d (%d) ", lba, toc->track[track - 1].lba); + printf("[CDROM] Track Size: %d\n", track_size); fflush(stdout); #endif @@ -1012,7 +1005,7 @@ static int cdrom_read_track_info(libretro_vfs_implementation_file *stream, unsig int cdrom_set_read_speed(libretro_vfs_implementation_file *stream, unsigned speed) { /* MMC Command: SET CD SPEED */ - unsigned char cmd[] = {0xBB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + unsigned char cmd[] = {0xBB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; cmd[2] = (speed >> 24) & 0xFF; cmd[3] = (speed >> 16) & 0xFF; @@ -1336,35 +1329,24 @@ struct string_list* cdrom_get_available_drives(void) #if defined(__linux__) && !defined(ANDROID) struct string_list *dir_list = dir_list_new("/dev", NULL, false, false, false, false); int i; - bool found = false; if (!dir_list) return list; for (i = 0; i < (int)dir_list->size; i++) { - if (string_starts_with_size(dir_list->elems[i].data, "/dev/sg", - STRLEN_CONST("/dev/sg"))) + if (strstr(dir_list->elems[i].data, "/dev/sg")) { - char drive_string[33]; - libretro_vfs_implementation_file *stream; - char drive_model[32] = {0}; + char drive_model[32] = {0}; + char drive_string[33] = {0}; union string_list_elem_attr attr = {0}; - int dev_index = 0; - RFILE *file = filestream_open( - dir_list->elems[i].data, RETRO_VFS_FILE_ACCESS_READ, 0); - bool is_cdrom = false; - - found = true; + int dev_index = 0; + RFILE *file = filestream_open(dir_list->elems[i].data, RETRO_VFS_FILE_ACCESS_READ, 0); + libretro_vfs_implementation_file *stream; + bool is_cdrom = false; if (!file) - { -#ifdef CDROM_DEBUG - printf("[CDROM] Could not open %s, please check permissions.\n", dir_list->elems[i].data); - fflush(stdout); -#endif continue; - } stream = filestream_get_vfs_handle(file); cdrom_get_inquiry(stream, drive_model, sizeof(drive_model), &is_cdrom); @@ -1373,86 +1355,33 @@ struct string_list* cdrom_get_available_drives(void) if (!is_cdrom) continue; - sscanf(dir_list->elems[i].data + STRLEN_CONST("/dev/sg"), - "%d", &dev_index); + sscanf(dir_list->elems[i].data + strlen("/dev/sg"), "%d", &dev_index); dev_index = '0' + dev_index; - attr.i = dev_index; + attr.i = dev_index; if (!string_is_empty(drive_model)) - strlcpy(drive_string, drive_model, sizeof(drive_string)); + strlcat(drive_string, drive_model, sizeof(drive_string)); else - strlcpy(drive_string, "Unknown Drive", sizeof(drive_string)); + strlcat(drive_string, "Unknown Drive", sizeof(drive_string)); string_list_append(list, drive_string, attr); } } - if (!found) - { - char *buf = NULL; - int64_t len = 0; - - if (filestream_read_file("/proc/modules", (void**)&buf, &len)) - { -#ifdef CDROM_DEBUG - bool found = false; -#endif - struct string_list mods = {0}; - - string_list_initialize(&mods); - - if (string_split_noalloc(&mods, buf, "\n")) - { - for (i = 0; i < (int)mods.size; i++) - { - if (strcasestr(mods.elems[i].data, "sg ")) - { -#ifdef CDROM_DEBUG - found = true; -#endif - break; - } - } - } - string_list_deinitialize(&mods); - free(buf); - -#ifdef CDROM_DEBUG - if (found) - { - printf("[CDROM] No sg devices found but kernel module is loaded.\n"); - fflush(stdout); - } - else - { - printf("[CDROM] No sg devices found and sg kernel module is not loaded.\n"); - fflush(stdout); - } -#endif - } -#ifdef CDROM_DEBUG - else - { - printf("[CDROM] No sg devices found, could not check if sg kernel module is loaded.\n"); - fflush(stdout); - } -#endif - } - string_list_free(dir_list); #endif #if defined(_WIN32) && !defined(_XBOX) DWORD drive_mask = GetLogicalDrives(); int i; - for (i = 0; i < (int)(sizeof(DWORD) * 8); i++) + for (i = 0; i < sizeof(DWORD) * 8; i++) { - char path[] = {"a:\\"}; + char path[] = {"a:\\"}; char cdrom_path[] = {"cdrom://a:/drive-track01.bin"}; - path[0] += i; - cdrom_path[8] += i; + path[0] += i; + cdrom_path[8] += i; /* this drive letter doesn't exist */ if (!(drive_mask & (1 << i))) @@ -1460,14 +1389,15 @@ struct string_list* cdrom_get_available_drives(void) if (GetDriveType(path) != DRIVE_CDROM) continue; - + else { - char drive_string[33]; - libretro_vfs_implementation_file *stream; - bool is_cdrom = false; - char drive_model[32] = {0}; + char drive_model[32] = {0}; + char drive_string[33] = {0}; union string_list_elem_attr attr = {0}; RFILE *file = filestream_open(cdrom_path, RETRO_VFS_FILE_ACCESS_READ, 0); + libretro_vfs_implementation_file *stream; + bool is_cdrom = false; + if (!file) continue; @@ -1481,9 +1411,9 @@ struct string_list* cdrom_get_available_drives(void) attr.i = path[0]; if (!string_is_empty(drive_model)) - strlcpy(drive_string, drive_model, sizeof(drive_string)); + strlcat(drive_string, drive_model, sizeof(drive_string)); else - strlcpy(drive_string, "Unknown Drive", sizeof(drive_string)); + strlcat(drive_string, "Unknown Drive", sizeof(drive_string)); string_list_append(list, drive_string, attr); } @@ -1514,7 +1444,9 @@ bool cdrom_is_media_inserted(libretro_vfs_implementation_file *stream) bool cdrom_drive_has_media(const char drive) { RFILE *file; - char cdrom_path_bin[256] = {0}; + char cdrom_path_bin[256]; + + cdrom_path_bin[0] = '\0'; cdrom_device_fillpath(cdrom_path_bin, sizeof(cdrom_path_bin), drive, 1, false); @@ -1523,7 +1455,9 @@ bool cdrom_drive_has_media(const char drive) if (file) { libretro_vfs_implementation_file *stream = filestream_get_vfs_handle(file); - bool has_media = cdrom_is_media_inserted(stream); + bool has_media = false; + + has_media = cdrom_is_media_inserted(stream); filestream_close(file); @@ -1535,14 +1469,14 @@ bool cdrom_drive_has_media(const char drive) bool cdrom_set_read_cache(libretro_vfs_implementation_file *stream, bool enabled) { - int i; /* MMC Command: MODE SENSE (10) and MODE SELECT (10) */ unsigned char cdb_sense_changeable[] = {0x5A, 0, 0x48, 0, 0, 0, 0, 0, 0x14, 0}; - unsigned char cdb_sense[] = {0x5A, 0, 0x8, 0, 0, 0, 0, 0, 0x14, 0}; - unsigned char cdb_select[] = {0x55, 0x10, 0, 0, 0, 0, 0, 0, 0x14, 0}; - unsigned char buf[20] = {0}; - int rv = cdrom_send_command(stream, DIRECTION_IN, buf, sizeof(buf), - cdb_sense_changeable, sizeof(cdb_sense_changeable), 0); + unsigned char cdb_sense[] = {0x5A, 0, 0x8, 0, 0, 0, 0, 0, 0x14, 0}; + unsigned char cdb_select[] = {0x55, 0x10, 0, 0, 0, 0, 0, 0, 0x14, 0}; + unsigned char buf[20] = {0}; + int rv, i; + + rv = cdrom_send_command(stream, DIRECTION_IN, buf, sizeof(buf), cdb_sense_changeable, sizeof(cdb_sense_changeable), 0); #ifdef CDROM_DEBUG printf("[CDROM] mode sense changeable status code %d\n", rv); @@ -1578,7 +1512,9 @@ bool cdrom_set_read_cache(libretro_vfs_implementation_file *stream, bool enabled printf("Mode sense data for caching mode page: "); for (i = 0; i < (int)sizeof(buf); i++) + { printf("%02X ", buf[i]); + } printf("\n"); fflush(stdout); @@ -1591,7 +1527,7 @@ bool cdrom_set_read_cache(libretro_vfs_implementation_file *stream, bool enabled if (enabled) buf[10] &= ~1; else - buf[10] |= 1; + buf[10] |= 1; rv = cdrom_send_command(stream, DIRECTION_OUT, buf, sizeof(buf), cdb_select, sizeof(cdb_select), 0); @@ -1640,7 +1576,9 @@ bool cdrom_get_timeouts(libretro_vfs_implementation_file *stream, cdrom_group_ti printf("Mode sense data for timeout groups: "); for (i = 0; i < (int)sizeof(buf); i++) + { printf("%02X ", buf[i]); + } printf("\n"); @@ -1662,8 +1600,8 @@ bool cdrom_get_timeouts(libretro_vfs_implementation_file *stream, cdrom_group_ti bool cdrom_has_atip(libretro_vfs_implementation_file *stream) { /* MMC Command: READ TOC/PMA/ATIP */ - unsigned char cdb[] = {0x43, 0x2, 0x4, 0, 0, 0, 0, 0x9, 0x30, 0}; - unsigned char buf[32] = {0}; + unsigned char cdb[] = {0x43, 0x2, 0x4, 0, 0, 0, 0, 0x9, 0x30, 0}; + unsigned char buf[32] = {0}; unsigned short atip_len = 0; int rv = cdrom_send_command(stream, DIRECTION_IN, buf, sizeof(buf), cdb, sizeof(cdb), 0); @@ -1673,10 +1611,7 @@ bool cdrom_has_atip(libretro_vfs_implementation_file *stream) atip_len = buf[0] << 8 | buf[1]; #ifdef CDROM_DEBUG - printf("ATIP Length %d, Disc Type %d, Disc Sub-Type %d\n", - atip_len, - (buf[6] >> 6) & 0x1, - ((buf[6] >> 5) & 0x1) << 2 | ((buf[6] >> 4) & 0x1) << 1 | ((buf[6] >> 3) & 0x1) << 0); + printf("ATIP Length %d, Disc Type %d, Disc Sub-Type %d\n", atip_len, (buf[6] >> 6) & 0x1, ((buf[6] >> 5) & 0x1) << 2 | ((buf[6] >> 4) & 0x1) << 1 | ((buf[6] >> 3) & 0x1) << 0); #endif if (atip_len < 5) @@ -1687,23 +1622,27 @@ bool cdrom_has_atip(libretro_vfs_implementation_file *stream) void cdrom_device_fillpath(char *path, size_t len, char drive, unsigned char track, bool is_cue) { + size_t pos = 0; + if (!path || len == 0) return; + if (is_cue) { #ifdef _WIN32 - size_t pos = strlcpy(path, "cdrom://", len); + pos = strlcpy(path, "cdrom://", len); + if (len > pos) path[pos++] = drive; + pos = strlcat(path, ":/drive.cue", len); #else #ifdef __linux__ - size_t pos = strlcpy(path, "cdrom://drive", len); - if (len > pos + 1) - { + pos = strlcpy(path, "cdrom://drive", len); + + if (len > pos) path[pos++] = drive; - path[pos] = '\0'; - } + pos = strlcat(path, ".cue", len); #endif #endif @@ -1711,18 +1650,19 @@ void cdrom_device_fillpath(char *path, size_t len, char drive, unsigned char tra else { #ifdef _WIN32 - size_t pos = strlcpy(path, "cdrom://", len); - if (len > pos + 1) - { + pos = strlcpy(path, "cdrom://", len); + + if (len > pos) path[pos++] = drive; - path[pos] = '\0'; - } + pos += snprintf(path + pos, len - pos, ":/drive-track%02d.bin", track); #else #ifdef __linux__ - size_t pos = strlcpy(path, "cdrom://drive", len); + pos = strlcpy(path, "cdrom://drive", len); + if (len > pos) path[pos++] = drive; + pos += snprintf(path + pos, len - pos, "-track%02d.bin", track); #endif #endif diff --git a/libretro/libretro-common/compat/compat_posix_string.c b/libretro/libretro-common/compat/compat_posix_string.c index 6a2f07ee4..33a30e577 100644 --- a/libretro/libretro-common/compat/compat_posix_string.c +++ b/libretro/libretro-common/compat/compat_posix_string.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2020 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_posix_string.c). diff --git a/libretro/libretro-common/compat/compat_snprintf.c b/libretro/libretro-common/compat/compat_snprintf.c index d7320cc94..b69ad047a 100644 --- a/libretro/libretro-common/compat/compat_snprintf.c +++ b/libretro/libretro-common/compat/compat_snprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2020 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_snprintf.c). @@ -33,12 +33,12 @@ #if _MSC_VER < 1300 #define _vscprintf c89_vscprintf_retro__ -static int c89_vscprintf_retro__(const char *fmt, va_list pargs) +static int c89_vscprintf_retro__(const char *format, va_list pargs) { int retval; va_list argcopy; va_copy(argcopy, pargs); - retval = vsnprintf(NULL, 0, fmt, argcopy); + retval = vsnprintf(NULL, 0, format, argcopy); va_end(argcopy); return retval; } @@ -46,36 +46,38 @@ static int c89_vscprintf_retro__(const char *fmt, va_list pargs) /* http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 */ -int c99_vsnprintf_retro__(char *s, size_t len, const char *fmt, va_list ap) +int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list ap) { int count = -1; - if (len != 0) + if (size != 0) { #if (_MSC_VER <= 1310) - count = _vsnprintf(s, len - 1, fmt, ap); + count = _vsnprintf(outBuf, size - 1, format, ap); #else - count = _vsnprintf_s(s, len, len - 1, fmt, ap); + count = _vsnprintf_s(outBuf, size, size - 1, format, ap); #endif } if (count == -1) - count = _vscprintf(fmt, ap); + count = _vscprintf(format, ap); - /* there was no room for a NULL, so truncate the last character */ - if (count == len && len) - s[len - 1] = '\0'; + if (count == size) + { + /* there was no room for a NULL, so truncate the last character */ + outBuf[size - 1] = '\0'; + } return count; } -int c99_snprintf_retro__(char *s, size_t len, const char *fmt, ...) +int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...) { int count; va_list ap; - va_start(ap, fmt); - count = c99_vsnprintf_retro__(s, len, fmt, ap); + va_start(ap, format); + count = c99_vsnprintf_retro__(outBuf, size, format, ap); va_end(ap); return count; diff --git a/libretro/libretro-common/compat/compat_strcasestr.c b/libretro/libretro-common/compat/compat_strcasestr.c index 4129dab29..54c93a48d 100644 --- a/libretro/libretro-common/compat/compat_strcasestr.c +++ b/libretro/libretro-common/compat/compat_strcasestr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2020 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_strcasestr.c). diff --git a/libretro/libretro-common/compat/compat_strl.c b/libretro/libretro-common/compat/compat_strl.c index 3a6392cb1..94cb39b62 100644 --- a/libretro/libretro-common/compat/compat_strl.c +++ b/libretro/libretro-common/compat/compat_strl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2020 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_strl.c). @@ -60,3 +60,10 @@ size_t strlcat(char *dest, const char *source, size_t size) return len + strlcpy(dest, source, size); } #endif + +char *strldup(const char *s, size_t n) +{ + char *dst = (char*)malloc(sizeof(char) * (n + 1)); + strlcpy(dst, s, n); + return dst; +} diff --git a/libretro/libretro-common/compat/fopen_utf8.c b/libretro/libretro-common/compat/fopen_utf8.c index 384657b5d..52b481e7e 100644 --- a/libretro/libretro-common/compat/fopen_utf8.c +++ b/libretro/libretro-common/compat/fopen_utf8.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2020 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (fopen_utf8.c). @@ -36,29 +36,25 @@ void *fopen_utf8(const char * filename, const char * mode) { -#if defined(LEGACY_WIN32) +#if defined(_XBOX) + return fopen(filename, mode); +#elif defined(LEGACY_WIN32) + FILE *ret = NULL; char * filename_local = utf8_to_local_string_alloc(filename); + + if (!filename_local) + return NULL; + ret = fopen(filename_local, mode); if (filename_local) - { - FILE *ret = fopen(filename_local, mode); free(filename_local); - return ret; - } + return ret; #else - wchar_t * filename_w = utf8_to_utf16_string_alloc(filename); - if (filename_w) - { - FILE *ret = NULL; - wchar_t *mode_w = utf8_to_utf16_string_alloc(mode); - if (mode_w) - { - ret = _wfopen(filename_w, mode_w); - free(mode_w); - } - free(filename_w); - return ret; - } + wchar_t * filename_w = utf8_to_utf16_string_alloc(filename); + wchar_t * mode_w = utf8_to_utf16_string_alloc(mode); + FILE* ret = _wfopen(filename_w, mode_w); + free(filename_w); + free(mode_w); + return ret; #endif - return NULL; } #endif diff --git a/libretro/libretro-common/encodings/encoding_utf.c b/libretro/libretro-common/encodings/encoding_utf.c index f9c594de6..f7c533f14 100644 --- a/libretro/libretro-common/encodings/encoding_utf.c +++ b/libretro/libretro-common/encodings/encoding_utf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2020 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (encoding_utf.c). @@ -37,8 +37,6 @@ #include #endif -#define UTF8_WALKBYTE(string) (*((*(string))++)) - static unsigned leading_ones(uint8_t c) { unsigned ones = 0; @@ -51,12 +49,9 @@ static unsigned leading_ones(uint8_t c) return ones; } -/** - * utf8_conv_utf32: - * - * Simple implementation. Assumes the sequence is - * properly synchronized and terminated. - **/ +/* Simple implementation. Assumes the sequence is + * properly synchronized and terminated. */ + size_t utf8_conv_utf32(uint32_t *out, size_t out_chars, const char *in, size_t in_size) { @@ -82,7 +77,7 @@ size_t utf8_conv_utf32(uint32_t *out, size_t out_chars, for (i = 0; i < extra; i++, in++, shift -= 6) c |= (*in & 0x3f) << shift; - *out++ = c; + *out++ = c; in_size -= 1 + extra; out_chars--; ret++; @@ -91,22 +86,16 @@ size_t utf8_conv_utf32(uint32_t *out, size_t out_chars, return ret; } -/** - * utf16_conv_utf8: - * - * Leaf function. - **/ bool utf16_conv_utf8(uint8_t *out, size_t *out_chars, const uint16_t *in, size_t in_size) { - size_t out_pos = 0; - size_t in_pos = 0; - static const - uint8_t utf8_limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + static uint8_t kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + size_t out_pos = 0; + size_t in_pos = 0; for (;;) { - unsigned num_adds; + unsigned numAdds; uint32_t value; if (in_pos == in_size) @@ -135,41 +124,37 @@ bool utf16_conv_utf8(uint8_t *out, size_t *out_chars, value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; } - for (num_adds = 1; num_adds < 5; num_adds++) - if (value < (((uint32_t)1) << (num_adds * 5 + 6))) + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((uint32_t)1) << (numAdds * 5 + 6))) break; if (out) - out[out_pos] = (char)(utf8_limits[num_adds - 1] - + (value >> (6 * num_adds))); + out[out_pos] = (char)(kUtf8Limits[numAdds - 1] + + (value >> (6 * numAdds))); out_pos++; do { - num_adds--; + numAdds--; if (out) out[out_pos] = (char)(0x80 - + ((value >> (6 * num_adds)) & 0x3F)); + + ((value >> (6 * numAdds)) & 0x3F)); out_pos++; - }while (num_adds != 0); + }while (numAdds != 0); } *out_chars = out_pos; return false; } -/** - * utf8cpy: - * - * Acts mostly like strlcpy. +/* Acts mostly like strlcpy. * * Copies the given number of UTF-8 characters, - * but at most @d_len bytes. + * but at most d_len bytes. * - * Always NULL terminates. Does not copy half a character. - * @s is assumed valid UTF-8. - * Use only if @chars is considerably less than @d_len. + * Always NULL terminates. + * Does not copy half a character. * - * @return Number of bytes. - **/ + * Returns number of bytes. 's' is assumed valid UTF-8. + * Use only if 'chars' is considerably less than 'd_len'. */ size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars) { const uint8_t *sb = (const uint8_t*)s; @@ -181,15 +166,13 @@ size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars) while (*sb && chars-- > 0) { sb++; - while ((*sb & 0xC0) == 0x80) - sb++; + while ((*sb & 0xC0) == 0x80) sb++; } if ((size_t)(sb - sb_org) > d_len-1 /* NUL */) { sb = sb_org + d_len-1; - while ((*sb & 0xC0) == 0x80) - sb--; + while ((*sb & 0xC0) == 0x80) sb--; } memcpy(d, sb_org, sb-sb_org); @@ -198,34 +181,20 @@ size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars) return sb-sb_org; } -/** - * utf8skip: - * - * Leaf function - **/ const char *utf8skip(const char *str, size_t chars) { const uint8_t *strb = (const uint8_t*)str; - if (!chars) return str; - do { strb++; - while ((*strb & 0xC0)==0x80) - strb++; + while ((*strb & 0xC0)==0x80) strb++; chars--; - }while (chars); - + } while(chars); return (const char*)strb; } -/** - * utf8len: - * - * Leaf function. - **/ size_t utf8len(const char *string) { size_t ret = 0; @@ -242,35 +211,30 @@ size_t utf8len(const char *string) return ret; } -/** - * utf8_walk: - * - * Does not validate the input. - * - * Leaf function. - * - * @return Returns garbage if it's not UTF-8. - **/ +static uint8_t utf8_walkbyte(const char **string) +{ + return *((*string)++); +} + +/* Does not validate the input, returns garbage if it's not UTF-8. */ uint32_t utf8_walk(const char **string) { - uint8_t first = UTF8_WALKBYTE(string); + uint8_t first = utf8_walkbyte(string); uint32_t ret = 0; if (first < 128) return first; - ret = (ret << 6) | (UTF8_WALKBYTE(string) & 0x3F); + ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F); if (first >= 0xE0) - { - ret = (ret << 6) | (UTF8_WALKBYTE(string) & 0x3F); - if (first >= 0xF0) - { - ret = (ret << 6) | (UTF8_WALKBYTE(string) & 0x3F); - return ret | (first & 7) << 18; - } - return ret | (first & 15) << 12; - } + ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F); + if (first >= 0xF0) + ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F); + if (first >= 0xF0) + return ret | (first & 7) << 18; + if (first >= 0xE0) + return ret | (first & 15) << 12; return ret | (first & 31) << 6; } @@ -278,23 +242,24 @@ static bool utf16_to_char(uint8_t **utf_data, size_t *dest_len, const uint16_t *in) { unsigned len = 0; + while (in[len] != '\0') len++; + utf16_conv_utf8(NULL, dest_len, in, len); *dest_len += 1; - if ((*utf_data = (uint8_t*)malloc(*dest_len)) != 0) - return utf16_conv_utf8(*utf_data, dest_len, in, len); - return false; + *utf_data = (uint8_t*)malloc(*dest_len); + if (*utf_data == 0) + return false; + + return utf16_conv_utf8(*utf_data, dest_len, in, len); } -/** - * utf16_to_char_string: - **/ bool utf16_to_char_string(const uint16_t *in, char *s, size_t len) { - size_t dest_len = 0; - uint8_t *utf16_data = NULL; - bool ret = utf16_to_char(&utf16_data, &dest_len, in); + size_t dest_len = 0; + uint8_t *utf16_data = NULL; + bool ret = utf16_to_char(&utf16_data, &dest_len, in); if (ret) { @@ -303,228 +268,247 @@ bool utf16_to_char_string(const uint16_t *in, char *s, size_t len) } free(utf16_data); - utf16_data = NULL; + utf16_data = NULL; return ret; } -#if defined(_WIN32) && !defined(_XBOX) && !defined(UNICODE) -/** - * mb_to_mb_string_alloc: - * - * @return Returned pointer MUST be freed by the caller if non-NULL. - **/ -static char *mb_to_mb_string_alloc(const char *str, +/* Returned pointer MUST be freed by the caller if non-NULL. */ +static char* mb_to_mb_string_alloc(const char *str, enum CodePage cp_in, enum CodePage cp_out) { + char *path_buf = NULL; wchar_t *path_buf_wide = NULL; - int path_buf_wide_len = MultiByteToWideChar(cp_in, 0, str, -1, NULL, 0); - - /* Windows 95 will return 0 from these functions with - * a UTF8 codepage set without MSLU. - * - * From an unknown MSDN version (others omit this info): - * - CP_UTF8 Windows 98/Me, Windows NT 4.0 and later: - * Translate using UTF-8. When this is set, dwFlags must be zero. - * - Windows 95: Under the Microsoft Layer for Unicode, - * MultiByteToWideChar also supports CP_UTF7 and CP_UTF8. - */ + int path_buf_len = 0; + int path_buf_wide_len = 0; - if (!path_buf_wide_len) - return strdup(str); + if (!str || !*str) + return NULL; + + (void)path_buf; + (void)path_buf_wide; + (void)path_buf_len; + (void)path_buf_wide_len; + +#if !defined(_WIN32) || defined(_XBOX) + /* assume string needs no modification if not on Windows */ + return strdup(str); +#else +#ifdef UNICODE + /* TODO/FIXME: Not implemented. */ + return strdup(str); +#else + + /* Windows 95 will return 0 from these functions with a UTF8 codepage set without MSLU. From an unknown MSDN version (others omit this info): + * - CP_UTF8 Windows 98/Me, Windows NT 4.0 and later: Translate using UTF-8. When this is set, dwFlags must be zero. + * - Windows 95: Under the Microsoft Layer for Unicode, MultiByteToWideChar also supports CP_UTF7 and CP_UTF8. + */ + path_buf_wide_len = MultiByteToWideChar(cp_in, 0, str, -1, NULL, 0); - if ((path_buf_wide = (wchar_t*) - calloc(path_buf_wide_len + sizeof(wchar_t), sizeof(wchar_t)))) + if (path_buf_wide_len) { - MultiByteToWideChar(cp_in, 0, - str, -1, path_buf_wide, path_buf_wide_len); + path_buf_wide = (wchar_t*) + calloc(path_buf_wide_len + sizeof(wchar_t), sizeof(wchar_t)); - if (*path_buf_wide) + if (path_buf_wide) { - int path_buf_len = WideCharToMultiByte(cp_out, 0, - path_buf_wide, -1, NULL, 0, NULL, NULL); + MultiByteToWideChar(cp_in, 0, + str, -1, path_buf_wide, path_buf_wide_len); - if (path_buf_len) + if (*path_buf_wide) { - char *path_buf = (char*) - calloc(path_buf_len + sizeof(char), sizeof(char)); + path_buf_len = WideCharToMultiByte(cp_out, 0, + path_buf_wide, -1, NULL, 0, NULL, NULL); - if (path_buf) + if (path_buf_len) { - WideCharToMultiByte(cp_out, 0, - path_buf_wide, -1, path_buf, - path_buf_len, NULL, NULL); + path_buf = (char*) + calloc(path_buf_len + sizeof(char), sizeof(char)); - free(path_buf_wide); + if (path_buf) + { + WideCharToMultiByte(cp_out, 0, + path_buf_wide, -1, path_buf, + path_buf_len, NULL, NULL); - if (*path_buf) - return path_buf; + free(path_buf_wide); - free(path_buf); - return NULL; + if (*path_buf) + return path_buf; + + free(path_buf); + return NULL; + } + } + else + { + free(path_buf_wide); + return strdup(str); } - } - else - { - free(path_buf_wide); - return strdup(str); } } + } + else + return strdup(str); + if (path_buf_wide) free(path_buf_wide); - } return NULL; -} #endif +#endif +} -/** - * utf8_to_local_string_alloc: - * - * @return Returned pointer MUST be freed by the caller if non-NULL. - **/ +/* Returned pointer MUST be freed by the caller if non-NULL. */ char* utf8_to_local_string_alloc(const char *str) { - if (str && *str) -#if defined(_WIN32) && !defined(_XBOX) && !defined(UNICODE) - return mb_to_mb_string_alloc(str, CODEPAGE_UTF8, CODEPAGE_LOCAL); -#else - return strdup(str); /* Assume string needs no modification if not on Windows */ -#endif - return NULL; + return mb_to_mb_string_alloc(str, CODEPAGE_UTF8, CODEPAGE_LOCAL); } -/** - * local_to_utf8_string_alloc: - * - * @return Returned pointer MUST be freed by the caller if non-NULL. - **/ -char *local_to_utf8_string_alloc(const char *str) +/* Returned pointer MUST be freed by the caller if non-NULL. */ +char* local_to_utf8_string_alloc(const char *str) { - if (str && *str) -#if defined(_WIN32) && !defined(_XBOX) && !defined(UNICODE) - return mb_to_mb_string_alloc(str, CODEPAGE_LOCAL, CODEPAGE_UTF8); -#else - return strdup(str); /* Assume string needs no modification if not on Windows */ -#endif - return NULL; + return mb_to_mb_string_alloc(str, CODEPAGE_LOCAL, CODEPAGE_UTF8); } -/** - * utf8_to_utf16_string_alloc: - * - * @return Returned pointer MUST be freed by the caller if non-NULL. - **/ +/* Returned pointer MUST be freed by the caller if non-NULL. */ wchar_t* utf8_to_utf16_string_alloc(const char *str) { #ifdef _WIN32 - int len = 0; + int len = 0; + int out_len = 0; #else - size_t len = 0; + size_t len = 0; + size_t out_len = 0; #endif - wchar_t *buf = NULL; + wchar_t *buf = NULL; if (!str || !*str) return NULL; #ifdef _WIN32 - if ((len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0))) + len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); + + if (len) { - if (!(buf = (wchar_t*)calloc(len, sizeof(wchar_t)))) - return NULL; + buf = (wchar_t*)calloc(len, sizeof(wchar_t)); - if ((MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, len)) < 0) - { - free(buf); + if (!buf) return NULL; - } + + out_len = MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, len); } else { - /* Fallback to ANSI codepage instead */ - if ((len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0))) + /* fallback to ANSI codepage instead */ + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + + if (len) { - if (!(buf = (wchar_t*)calloc(len, sizeof(wchar_t)))) - return NULL; + buf = (wchar_t*)calloc(len, sizeof(wchar_t)); - if ((MultiByteToWideChar(CP_ACP, 0, str, -1, buf, len)) < 0) - { - free(buf); + if (!buf) return NULL; - } + + out_len = MultiByteToWideChar(CP_ACP, 0, str, -1, buf, len); } } + + if (out_len < 0) + { + free(buf); + return NULL; + } #else /* NOTE: For now, assume non-Windows platforms' locale is already UTF-8. */ - if ((len = mbstowcs(NULL, str, 0) + 1)) + len = mbstowcs(NULL, str, 0) + 1; + + if (len) { - if (!(buf = (wchar_t*)calloc(len, sizeof(wchar_t)))) - return NULL; + buf = (wchar_t*)calloc(len, sizeof(wchar_t)); - if ((mbstowcs(buf, str, len)) == (size_t)-1) - { - free(buf); + if (!buf) return NULL; - } + + out_len = mbstowcs(buf, str, len); + } + + if (out_len == (size_t)-1) + { + free(buf); + return NULL; } #endif return buf; } -/** - * utf16_to_utf8_string_alloc: - * - * @return Returned pointer MUST be freed by the caller if non-NULL. - **/ +/* Returned pointer MUST be freed by the caller if non-NULL. */ char* utf16_to_utf8_string_alloc(const wchar_t *str) { #ifdef _WIN32 - int len = 0; + int len = 0; + int out_len = 0; #else - size_t len = 0; + size_t len = 0; + size_t out_len = 0; #endif - char *buf = NULL; + char *buf = NULL; if (!str || !*str) return NULL; #ifdef _WIN32 + len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL); + + if (len) { - UINT code_page = CP_UTF8; + buf = (char*)calloc(len, sizeof(char)); + + if (!buf) + return NULL; + out_len = WideCharToMultiByte(CP_UTF8, 0, str, -1, buf, len, NULL, NULL); + } + else + { /* fallback to ANSI codepage instead */ - if (!(len = WideCharToMultiByte(code_page, - 0, str, -1, NULL, 0, NULL, NULL))) + len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); + + if (len) { - code_page = CP_ACP; - len = WideCharToMultiByte(code_page, - 0, str, -1, NULL, 0, NULL, NULL); - } + buf = (char*)calloc(len, sizeof(char)); - if (!(buf = (char*)calloc(len, sizeof(char)))) - return NULL; + if (!buf) + return NULL; - if (WideCharToMultiByte(code_page, - 0, str, -1, buf, len, NULL, NULL) < 0) - { - free(buf); - return NULL; + out_len = WideCharToMultiByte(CP_ACP, 0, str, -1, buf, len, NULL, NULL); } } + + if (out_len < 0) + { + free(buf); + return NULL; + } #else - /* NOTE: For now, assume non-Windows platforms' - * locale is already UTF-8. */ - if ((len = wcstombs(NULL, str, 0) + 1)) + /* NOTE: For now, assume non-Windows platforms' locale is already UTF-8. */ + len = wcstombs(NULL, str, 0) + 1; + + if (len) { - if (!(buf = (char*)calloc(len, sizeof(char)))) - return NULL; + buf = (char*)calloc(len, sizeof(char)); - if (wcstombs(buf, str, len) == (size_t)-1) - { - free(buf); + if (!buf) return NULL; - } + + out_len = wcstombs(buf, str, len); + } + + if (out_len == (size_t)-1) + { + free(buf); + return NULL; } #endif diff --git a/libretro/libretro-common/file/file_path.c b/libretro/libretro-common/file/file_path.c index c696ff045..bac6a4060 100644 --- a/libretro/libretro-common/file/file_path.c +++ b/libretro/libretro-common/file/file_path.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2020 The RetroArch team +/* Copyright (C) 2010-2019 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (file_path.c). @@ -24,15 +24,16 @@ #include #include #include -#include +#include #include #include #include -#include +#include #include -#include