From d6c854abd8ad70de15fe25170a7d5a532d8f1502 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 20 Apr 2021 16:18:54 +0800 Subject: [PATCH] Use fopen_utf8 instead of fopen --- Makefile.common | 3 +- src/drivers/libretro/griffin.c | 1 + .../libretro-common/compat/fopen_utf8.c | 63 +++++++++++++++++++ .../include/compat/fopen_utf8.h | 34 ++++++++++ .../libretro-common/include/libretro.h | 4 ++ .../include/string/stdstring.h | 22 +++---- src/file.c | 4 +- 7 files changed, 118 insertions(+), 13 deletions(-) create mode 100644 src/drivers/libretro/libretro-common/compat/fopen_utf8.c create mode 100644 src/drivers/libretro/libretro-common/include/compat/fopen_utf8.h diff --git a/Makefile.common b/Makefile.common index 8c75113..9876d85 100644 --- a/Makefile.common +++ b/Makefile.common @@ -53,7 +53,8 @@ SOURCES_C += $(CORE_DIR)/drivers/libretro/libretro-common/streams/memory_stream. $(CORE_DIR)/drivers/libretro/libretro-common/compat/compat_snprintf.c \ $(CORE_DIR)/drivers/libretro/libretro-common/string/stdstring.c \ $(CORE_DIR)/drivers/libretro/libretro-common/encodings/encoding_utf.c \ - $(CORE_DIR)/drivers/libretro/libretro-common/compat/compat_strl.c + $(CORE_DIR)/drivers/libretro/libretro-common/compat/compat_strl.c \ + $(CORE_DIR)/drivers/libretro/libretro-common/compat/fopen_utf8.c endif ifeq ($(DEBUG),1) diff --git a/src/drivers/libretro/griffin.c b/src/drivers/libretro/griffin.c index 3158363..9a215eb 100644 --- a/src/drivers/libretro/griffin.c +++ b/src/drivers/libretro/griffin.c @@ -7,6 +7,7 @@ #include "drivers/libretro/libretro-common/string/stdstring.c" #include "drivers/libretro/libretro-common/encodings/encoding_utf.c" #include "drivers/libretro/libretro-common/compat/compat_strl.c" +#include "drivers/libretro/libretro-common/compat/fopen_utf8.c" #endif #include "cart.c" diff --git a/src/drivers/libretro/libretro-common/compat/fopen_utf8.c b/src/drivers/libretro/libretro-common/compat/fopen_utf8.c new file mode 100644 index 0000000..85abb59 --- /dev/null +++ b/src/drivers/libretro/libretro-common/compat/fopen_utf8.c @@ -0,0 +1,63 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (fopen_utf8.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) +#ifndef LEGACY_WIN32 +#define LEGACY_WIN32 +#endif +#endif + +#ifdef _WIN32 +#undef fopen + +void *fopen_utf8(const char * filename, const char * mode) +{ +#if 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) + free(filename_local); + return ret; +#else + wchar_t * filename_w = utf8_to_utf16_string_alloc(filename); + wchar_t * mode_w = utf8_to_utf16_string_alloc(mode); + FILE* ret = NULL; + + if (filename_w && mode_w) + ret = _wfopen(filename_w, mode_w); + if (filename_w) + free(filename_w); + if (mode_w) + free(mode_w); + return ret; +#endif +} +#endif diff --git a/src/drivers/libretro/libretro-common/include/compat/fopen_utf8.h b/src/drivers/libretro/libretro-common/include/compat/fopen_utf8.h new file mode 100644 index 0000000..97d4404 --- /dev/null +++ b/src/drivers/libretro/libretro-common/include/compat/fopen_utf8.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (fopen_utf8.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __LIBRETRO_SDK_COMPAT_FOPEN_UTF8_H +#define __LIBRETRO_SDK_COMPAT_FOPEN_UTF8_H + +#ifdef _WIN32 +/* Defined to error rather than fopen_utf8, to make it clear to everyone reading the code that not worrying about utf16 is fine */ +/* TODO: enable */ +/* #define fopen (use fopen_utf8 instead) */ +void *fopen_utf8(const char * filename, const char * mode); +#else +#define fopen_utf8 fopen +#endif +#endif diff --git a/src/drivers/libretro/libretro-common/include/libretro.h b/src/drivers/libretro/libretro-common/include/libretro.h index d843114..8a5da86 100644 --- a/src/drivers/libretro/libretro-common/include/libretro.h +++ b/src/drivers/libretro/libretro-common/include/libretro.h @@ -282,6 +282,7 @@ enum retro_language RETRO_LANGUAGE_PERSIAN = 20, RETRO_LANGUAGE_HEBREW = 21, RETRO_LANGUAGE_ASTURIAN = 22, + RETRO_LANGUAGE_FINNISH = 23, RETRO_LANGUAGE_LAST, /* Ensure sizeof(enum) == sizeof(int) */ @@ -712,6 +713,9 @@ enum retro_mod * state of rumble motors in controllers. * A strong and weak motor is supported, and they can be * controlled indepedently. + * Should be called from either retro_init() or retro_load_game(). + * Should not be called from retro_set_environment(). + * Returns false if rumble functionality is unavailable. */ #define RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES 24 /* uint64_t * -- diff --git a/src/drivers/libretro/libretro-common/include/string/stdstring.h b/src/drivers/libretro/libretro-common/include/string/stdstring.h index 5d8c31b..82e038b 100644 --- a/src/drivers/libretro/libretro-common/include/string/stdstring.h +++ b/src/drivers/libretro/libretro-common/include/string/stdstring.h @@ -44,20 +44,20 @@ RETRO_BEGIN_DECLS #define string_is_not_equal_fast(a, b, size) (memcmp(a, b, size) != 0) #define string_is_equal_fast(a, b, size) (memcmp(a, b, size) == 0) -#define TOLOWER(c) (c | (lr_char_props[c] & 0x20)) -#define TOUPPER(c) (c & ~(lr_char_props[c] & 0x20)) +#define TOLOWER(c) ((c) | (lr_char_props[(unsigned char)(c)] & 0x20)) +#define TOUPPER(c) ((c) & ~(lr_char_props[(unsigned char)(c)] & 0x20)) /* C standard says \f \v are space, but this one disagrees */ -#define ISSPACE(c) (lr_char_props[c] & 0x80) +#define ISSPACE(c) (lr_char_props[(unsigned char)(c)] & 0x80) -#define ISDIGIT(c) (lr_char_props[c] & 0x40) -#define ISALPHA(c) (lr_char_props[c] & 0x20) -#define ISLOWER(c) (lr_char_props[c] & 0x04) -#define ISUPPER(c) (lr_char_props[c] & 0x02) -#define ISALNUM(c) (lr_char_props[c] & 0x60) -#define ISUALPHA(c) (lr_char_props[c] & 0x28) -#define ISUALNUM(c) (lr_char_props[c] & 0x68) -#define IS_XDIGIT(c) (lr_char_props[c] & 0x01) +#define ISDIGIT(c) (lr_char_props[(unsigned char)(c)] & 0x40) +#define ISALPHA(c) (lr_char_props[(unsigned char)(c)] & 0x20) +#define ISLOWER(c) (lr_char_props[(unsigned char)(c)] & 0x04) +#define ISUPPER(c) (lr_char_props[(unsigned char)(c)] & 0x02) +#define ISALNUM(c) (lr_char_props[(unsigned char)(c)] & 0x60) +#define ISUALPHA(c) (lr_char_props[(unsigned char)(c)] & 0x28) +#define ISUALNUM(c) (lr_char_props[(unsigned char)(c)] & 0x68) +#define IS_XDIGIT(c) (lr_char_props[(unsigned char)(c)] & 0x01) /* Deprecated alias, all callers should use string_is_equal_case_insensitive instead */ #define string_is_equal_noncase string_is_equal_case_insensitive diff --git a/src/file.c b/src/file.c index 2ceb96f..07da9f8 100644 --- a/src/file.c +++ b/src/file.c @@ -34,6 +34,8 @@ #include "driver.h" #include "general.h" +#include "compat/fopen_utf8.h" + #ifndef __GNUC__ #define strcasecmp strcmp #endif @@ -85,7 +87,7 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, fceufp->fp = MakeMemWrapBuffer(path, 0, buffer, bufsize); else { - void *t = fopen(path, mode); + void *t = fopen_utf8(path, mode); if (!t) {