mirror of
https://github.com/FunKey-Project/picodrive-irixxxx.git
synced 2026-09-17 12:52:00 +02:00
Merge pull request #113 from negativeExponent/scd_memmap
Update libretro-common, add Sega CD memory map
This commit is contained in:
@@ -36,9 +36,7 @@
|
|||||||
|
|
||||||
void *fopen_utf8(const char * filename, const char * mode)
|
void *fopen_utf8(const char * filename, const char * mode)
|
||||||
{
|
{
|
||||||
#if defined(_XBOX)
|
#if defined(LEGACY_WIN32)
|
||||||
return fopen(filename, mode);
|
|
||||||
#elif defined(LEGACY_WIN32)
|
|
||||||
FILE *ret = NULL;
|
FILE *ret = NULL;
|
||||||
char * filename_local = utf8_to_local_string_alloc(filename);
|
char * filename_local = utf8_to_local_string_alloc(filename);
|
||||||
|
|
||||||
|
|||||||
@@ -211,10 +211,7 @@ size_t utf8len(const char *string)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t utf8_walkbyte(const char **string)
|
#define utf8_walkbyte(string) (*((*(string))++))
|
||||||
{
|
|
||||||
return *((*string)++);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Does not validate the input, returns garbage if it's not UTF-8. */
|
/* Does not validate the input, returns garbage if it's not UTF-8. */
|
||||||
uint32_t utf8_walk(const char **string)
|
uint32_t utf8_walk(const char **string)
|
||||||
@@ -227,14 +224,16 @@ uint32_t utf8_walk(const char **string)
|
|||||||
|
|
||||||
ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F);
|
ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F);
|
||||||
if (first >= 0xE0)
|
if (first >= 0xE0)
|
||||||
|
{
|
||||||
ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F);
|
ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F);
|
||||||
if (first >= 0xF0)
|
if (first >= 0xF0)
|
||||||
ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F);
|
{
|
||||||
|
ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F);
|
||||||
if (first >= 0xF0)
|
return ret | (first & 7) << 18;
|
||||||
return ret | (first & 7) << 18;
|
}
|
||||||
if (first >= 0xE0)
|
|
||||||
return ret | (first & 15) << 12;
|
return ret | (first & 15) << 12;
|
||||||
|
}
|
||||||
|
|
||||||
return ret | (first & 31) << 6;
|
return ret | (first & 31) << 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,37 +272,25 @@ bool utf16_to_char_string(const uint16_t *in, char *s, size_t len)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(_XBOX) && !defined(UNICODE)
|
||||||
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
||||||
static char* mb_to_mb_string_alloc(const char *str,
|
static char *mb_to_mb_string_alloc(const char *str,
|
||||||
enum CodePage cp_in, enum CodePage cp_out)
|
enum CodePage cp_in, enum CodePage cp_out)
|
||||||
{
|
{
|
||||||
char *path_buf = NULL;
|
char *path_buf = NULL;
|
||||||
wchar_t *path_buf_wide = NULL;
|
wchar_t *path_buf_wide = NULL;
|
||||||
int path_buf_len = 0;
|
int path_buf_len = 0;
|
||||||
int path_buf_wide_len = 0;
|
int path_buf_wide_len = MultiByteToWideChar(cp_in, 0, str, -1, NULL, 0);
|
||||||
|
|
||||||
if (!str || !*str)
|
/* Windows 95 will return 0 from these functions with
|
||||||
return NULL;
|
* a UTF8 codepage set without MSLU.
|
||||||
|
*
|
||||||
(void)path_buf;
|
* From an unknown MSDN version (others omit this info):
|
||||||
(void)path_buf_wide;
|
* - CP_UTF8 Windows 98/Me, Windows NT 4.0 and later:
|
||||||
(void)path_buf_len;
|
* Translate using UTF-8. When this is set, dwFlags must be zero.
|
||||||
(void)path_buf_wide_len;
|
* - Windows 95: Under the Microsoft Layer for Unicode,
|
||||||
|
* MultiByteToWideChar also supports CP_UTF7 and CP_UTF8.
|
||||||
#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_len)
|
if (path_buf_wide_len)
|
||||||
{
|
{
|
||||||
@@ -355,20 +342,37 @@ static char* mb_to_mb_string_alloc(const char *str,
|
|||||||
free(path_buf_wide);
|
free(path_buf_wide);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 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)
|
char* utf8_to_local_string_alloc(const char *str)
|
||||||
{
|
{
|
||||||
return mb_to_mb_string_alloc(str, CODEPAGE_UTF8, CODEPAGE_LOCAL);
|
if (str && *str)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) && !defined(_XBOX) && !defined(UNICODE)
|
||||||
|
return mb_to_mb_string_alloc(str, CODEPAGE_UTF8, CODEPAGE_LOCAL);
|
||||||
|
#else
|
||||||
|
/* assume string needs no modification if not on Windows */
|
||||||
|
return strdup(str);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
||||||
char* local_to_utf8_string_alloc(const char *str)
|
char* local_to_utf8_string_alloc(const char *str)
|
||||||
{
|
{
|
||||||
return mb_to_mb_string_alloc(str, CODEPAGE_LOCAL, CODEPAGE_UTF8);
|
if (str && *str)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) && !defined(_XBOX) && !defined(UNICODE)
|
||||||
|
return mb_to_mb_string_alloc(str, CODEPAGE_LOCAL, CODEPAGE_UTF8);
|
||||||
|
#else
|
||||||
|
/* assume string needs no modification if not on Windows */
|
||||||
|
return strdup(str);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
/* Returned pointer MUST be freed by the caller if non-NULL. */
|
||||||
@@ -447,52 +451,44 @@ wchar_t* utf8_to_utf16_string_alloc(const char *str)
|
|||||||
char* utf16_to_utf8_string_alloc(const wchar_t *str)
|
char* utf16_to_utf8_string_alloc(const wchar_t *str)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int out_len = 0;
|
|
||||||
#else
|
#else
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
size_t out_len = 0;
|
|
||||||
#endif
|
#endif
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
|
||||||
if (!str || !*str)
|
if (!str || !*str)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
|
|
||||||
|
|
||||||
if (len)
|
|
||||||
{
|
{
|
||||||
|
UINT code_page = CP_UTF8;
|
||||||
|
len = WideCharToMultiByte(code_page,
|
||||||
|
0, str, -1, NULL, 0, NULL, NULL);
|
||||||
|
|
||||||
|
/* fallback to ANSI codepage instead */
|
||||||
|
if (!len)
|
||||||
|
{
|
||||||
|
code_page = CP_ACP;
|
||||||
|
len = WideCharToMultiByte(code_page,
|
||||||
|
0, str, -1, NULL, 0, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
buf = (char*)calloc(len, sizeof(char));
|
buf = (char*)calloc(len, sizeof(char));
|
||||||
|
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
out_len = WideCharToMultiByte(CP_UTF8, 0, str, -1, buf, len, NULL, NULL);
|
if (WideCharToMultiByte(code_page,
|
||||||
}
|
0, str, -1, buf, len, NULL, NULL) < 0)
|
||||||
else
|
|
||||||
{
|
|
||||||
/* fallback to ANSI codepage instead */
|
|
||||||
len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
|
|
||||||
|
|
||||||
if (len)
|
|
||||||
{
|
{
|
||||||
buf = (char*)calloc(len, sizeof(char));
|
free(buf);
|
||||||
|
return NULL;
|
||||||
if (!buf)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
out_len = WideCharToMultiByte(CP_ACP, 0, str, -1, buf, len, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out_len < 0)
|
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
/* NOTE: For now, assume non-Windows platforms' locale is already UTF-8. */
|
/* NOTE: For now, assume non-Windows platforms'
|
||||||
|
* locale is already UTF-8. */
|
||||||
len = wcstombs(NULL, str, 0) + 1;
|
len = wcstombs(NULL, str, 0) + 1;
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
@@ -502,13 +498,11 @@ char* utf16_to_utf8_string_alloc(const wchar_t *str)
|
|||||||
if (!buf)
|
if (!buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
out_len = wcstombs(buf, str, len);
|
if (wcstombs(buf, str, len) == (size_t)-1)
|
||||||
}
|
{
|
||||||
|
free(buf);
|
||||||
if (out_len == (size_t)-1)
|
return NULL;
|
||||||
{
|
}
|
||||||
free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -72,4 +72,3 @@ RETRO_END_DECLS
|
|||||||
|
|
||||||
/* pragma once */
|
/* pragma once */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ RETRO_BEGIN_DECLS
|
|||||||
/* Count Leading Zero, unsigned 16bit input value */
|
/* Count Leading Zero, unsigned 16bit input value */
|
||||||
static INLINE unsigned compat_clz_u16(uint16_t val)
|
static INLINE unsigned compat_clz_u16(uint16_t val)
|
||||||
{
|
{
|
||||||
#ifdef __GNUC__
|
#if defined(__GNUC__) && !defined(PS2)
|
||||||
return __builtin_clz(val << 16 | 0x8000);
|
return __builtin_clz(val << 16 | 0x8000);
|
||||||
#else
|
#else
|
||||||
unsigned ret = 0;
|
unsigned ret = 0;
|
||||||
@@ -61,7 +61,7 @@ static INLINE int compat_ctz(unsigned x)
|
|||||||
{
|
{
|
||||||
#if defined(__GNUC__) && !defined(RARCH_CONSOLE)
|
#if defined(__GNUC__) && !defined(RARCH_CONSOLE)
|
||||||
return __builtin_ctz(x);
|
return __builtin_ctz(x);
|
||||||
#elif _MSC_VER >= 1400 && !defined(_XBOX)
|
#elif _MSC_VER >= 1400 && !defined(_XBOX) && !defined(__WINRT__)
|
||||||
unsigned long r = 0;
|
unsigned long r = 0;
|
||||||
_BitScanReverse((unsigned long*)&r, x);
|
_BitScanReverse((unsigned long*)&r, x);
|
||||||
return (int)r;
|
return (int)r;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ extern "C" {
|
|||||||
|
|
||||||
/* Pre-MSVC 2015 compilers don't implement snprintf in a cross-platform manner. */
|
/* Pre-MSVC 2015 compilers don't implement snprintf in a cross-platform manner. */
|
||||||
#if _MSC_VER < 1900
|
#if _MSC_VER < 1900
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef snprintf
|
#ifndef snprintf
|
||||||
#define snprintf c99_snprintf_retro__
|
#define snprintf c99_snprintf_retro__
|
||||||
@@ -39,8 +40,9 @@ extern "C" {
|
|||||||
int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...);
|
int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Pre-MSVC 2010 compilers don't implement vsnprintf in a cross-platform manner? Not sure about this one. */
|
/* Pre-MSVC 2008 compilers don't implement vsnprintf in a cross-platform manner? Not sure about this one. */
|
||||||
#if _MSC_VER < 1600
|
#if _MSC_VER < 1500
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef vsnprintf
|
#ifndef vsnprintf
|
||||||
@@ -56,6 +58,8 @@ extern "C" {
|
|||||||
#undef UNICODE /* Do not bother with UNICODE at this time. */
|
#undef UNICODE /* Do not bother with UNICODE at this time. */
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
/* Python headers defines ssize_t and sets HAVE_SSIZE_T.
|
/* Python headers defines ssize_t and sets HAVE_SSIZE_T.
|
||||||
@@ -125,4 +129,3 @@ typedef int ssize_t;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ extern "C" {
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* 7.18.1 Integer types. */
|
/* 7.18.1 Integer types. */
|
||||||
|
|
||||||
/* 7.18.1.1 Exact-width integer types. */
|
/* 7.18.1.1 Exact-width integer types. */
|
||||||
@@ -94,7 +93,6 @@ extern "C" {
|
|||||||
typedef signed __int64 int64_t;
|
typedef signed __int64 int64_t;
|
||||||
typedef unsigned __int64 uint64_t;
|
typedef unsigned __int64 uint64_t;
|
||||||
|
|
||||||
|
|
||||||
/* 7.18.1.2 Minimum-width integer types. */
|
/* 7.18.1.2 Minimum-width integer types. */
|
||||||
typedef int8_t int_least8_t;
|
typedef int8_t int_least8_t;
|
||||||
typedef int16_t int_least16_t;
|
typedef int16_t int_least16_t;
|
||||||
@@ -255,4 +253,3 @@ typedef uint64_t uintmax_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,10 @@
|
|||||||
#include <compat/msvc.h>
|
#include <compat/msvc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(PS2)
|
||||||
|
#include <compat_ctype.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
RETRO_BEGIN_DECLS
|
RETRO_BEGIN_DECLS
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -55,7 +59,6 @@ int isblank(int c);
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
RETRO_END_DECLS
|
RETRO_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -25,6 +25,10 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(PS2)
|
||||||
|
#include <compat_ctype.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
|
#if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
|
||||||
#include "../../../config.h"
|
#include "../../../config.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -46,4 +50,3 @@ RETRO_END_DECLS
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -57,4 +57,3 @@ char *strldup(const char *s, size_t n);
|
|||||||
RETRO_END_DECLS
|
RETRO_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1117,7 +1117,7 @@ enum retro_mod
|
|||||||
* This may be still be done regardless of the core options
|
* This may be still be done regardless of the core options
|
||||||
* interface version.
|
* interface version.
|
||||||
*
|
*
|
||||||
* If version is >= 1 however, core options may instead be set by
|
* If version is 1 however, core options may instead be set by
|
||||||
* passing an array of retro_core_option_definition structs to
|
* passing an array of retro_core_option_definition structs to
|
||||||
* RETRO_ENVIRONMENT_SET_CORE_OPTIONS, or a 2D array of
|
* RETRO_ENVIRONMENT_SET_CORE_OPTIONS, or a 2D array of
|
||||||
* retro_core_option_definition structs to RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL.
|
* retro_core_option_definition structs to RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL.
|
||||||
@@ -1132,8 +1132,8 @@ enum retro_mod
|
|||||||
* GET_VARIABLE.
|
* GET_VARIABLE.
|
||||||
* This allows the frontend to present these variables to
|
* This allows the frontend to present these variables to
|
||||||
* a user dynamically.
|
* a user dynamically.
|
||||||
* This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION
|
* This should only be called if RETRO_ENVIRONMENT_GET_ENHANCED_CORE_OPTIONS
|
||||||
* returns an API version of >= 1.
|
* returns an API version of 1.
|
||||||
* This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES.
|
* This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES.
|
||||||
* This should be called the first time as early as
|
* This should be called the first time as early as
|
||||||
* possible (ideally in retro_set_environment).
|
* possible (ideally in retro_set_environment).
|
||||||
@@ -1169,6 +1169,8 @@ enum retro_mod
|
|||||||
* i.e. it should be feasible to cycle through options
|
* i.e. it should be feasible to cycle through options
|
||||||
* without a keyboard.
|
* without a keyboard.
|
||||||
*
|
*
|
||||||
|
* First entry should be treated as a default.
|
||||||
|
*
|
||||||
* Example entry:
|
* Example entry:
|
||||||
* {
|
* {
|
||||||
* "foo_option",
|
* "foo_option",
|
||||||
@@ -1194,8 +1196,8 @@ enum retro_mod
|
|||||||
* GET_VARIABLE.
|
* GET_VARIABLE.
|
||||||
* This allows the frontend to present these variables to
|
* This allows the frontend to present these variables to
|
||||||
* a user dynamically.
|
* a user dynamically.
|
||||||
* This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION
|
* This should only be called if RETRO_ENVIRONMENT_GET_ENHANCED_CORE_OPTIONS
|
||||||
* returns an API version of >= 1.
|
* returns an API version of 1.
|
||||||
* This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES.
|
* This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES.
|
||||||
* This should be called the first time as early as
|
* This should be called the first time as early as
|
||||||
* possible (ideally in retro_set_environment).
|
* possible (ideally in retro_set_environment).
|
||||||
@@ -1246,6 +1248,16 @@ enum retro_mod
|
|||||||
* default when calling SET_VARIABLES/SET_CORE_OPTIONS.
|
* default when calling SET_VARIABLES/SET_CORE_OPTIONS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER 56
|
||||||
|
/* unsigned * --
|
||||||
|
*
|
||||||
|
* Allows an implementation to ask frontend preferred hardware
|
||||||
|
* context to use. Core should use this information to deal
|
||||||
|
* with what specific context to request with SET_HW_RENDER.
|
||||||
|
*
|
||||||
|
* 'data' points to an unsigned variable
|
||||||
|
*/
|
||||||
|
|
||||||
/* VFS functionality */
|
/* VFS functionality */
|
||||||
|
|
||||||
/* File paths:
|
/* File paths:
|
||||||
@@ -1922,6 +1934,10 @@ enum retro_sensor_action
|
|||||||
{
|
{
|
||||||
RETRO_SENSOR_ACCELEROMETER_ENABLE = 0,
|
RETRO_SENSOR_ACCELEROMETER_ENABLE = 0,
|
||||||
RETRO_SENSOR_ACCELEROMETER_DISABLE,
|
RETRO_SENSOR_ACCELEROMETER_DISABLE,
|
||||||
|
RETRO_SENSOR_GYROSCOPE_ENABLE,
|
||||||
|
RETRO_SENSOR_GYROSCOPE_DISABLE,
|
||||||
|
RETRO_SENSOR_ILLUMINANCE_ENABLE,
|
||||||
|
RETRO_SENSOR_ILLUMINANCE_DISABLE,
|
||||||
|
|
||||||
RETRO_SENSOR_DUMMY = INT_MAX
|
RETRO_SENSOR_DUMMY = INT_MAX
|
||||||
};
|
};
|
||||||
@@ -1930,6 +1946,10 @@ enum retro_sensor_action
|
|||||||
#define RETRO_SENSOR_ACCELEROMETER_X 0
|
#define RETRO_SENSOR_ACCELEROMETER_X 0
|
||||||
#define RETRO_SENSOR_ACCELEROMETER_Y 1
|
#define RETRO_SENSOR_ACCELEROMETER_Y 1
|
||||||
#define RETRO_SENSOR_ACCELEROMETER_Z 2
|
#define RETRO_SENSOR_ACCELEROMETER_Z 2
|
||||||
|
#define RETRO_SENSOR_GYROSCOPE_X 3
|
||||||
|
#define RETRO_SENSOR_GYROSCOPE_Y 4
|
||||||
|
#define RETRO_SENSOR_GYROSCOPE_Z 5
|
||||||
|
#define RETRO_SENSOR_ILLUMINANCE 6
|
||||||
|
|
||||||
typedef bool (RETRO_CALLCONV *retro_set_sensor_state_t)(unsigned port,
|
typedef bool (RETRO_CALLCONV *retro_set_sensor_state_t)(unsigned port,
|
||||||
enum retro_sensor_action action, unsigned rate);
|
enum retro_sensor_action action, unsigned rate);
|
||||||
@@ -2502,20 +2522,8 @@ struct retro_core_option_display
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Maximum number of values permitted for a core option
|
/* Maximum number of values permitted for a core option
|
||||||
* > Note: We have to set a maximum value due the limitations
|
* NOTE: This may be increased on a core-by-core basis
|
||||||
* of the C language - i.e. it is not possible to create an
|
* if required (doing so has no effect on the frontend) */
|
||||||
* array of structs each containing a variable sized array,
|
|
||||||
* so the retro_core_option_definition values array must
|
|
||||||
* have a fixed size. The size limit of 128 is a balancing
|
|
||||||
* act - it needs to be large enough to support all 'sane'
|
|
||||||
* core options, but setting it too large may impact low memory
|
|
||||||
* platforms. In practise, if a core option has more than
|
|
||||||
* 128 values then the implementation is likely flawed.
|
|
||||||
* To quote the above API reference:
|
|
||||||
* "The number of possible options should be very limited
|
|
||||||
* i.e. it should be feasible to cycle through options
|
|
||||||
* without a keyboard."
|
|
||||||
*/
|
|
||||||
#define RETRO_NUM_CORE_OPTION_VALUES_MAX 128
|
#define RETRO_NUM_CORE_OPTION_VALUES_MAX 128
|
||||||
|
|
||||||
struct retro_core_option_value
|
struct retro_core_option_value
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#if defined(__CELLOS_LV2__) || defined(PSP) || defined(GEKKO) || defined(VITA) || defined(_XBOX) || defined(_3DS) || defined(WIIU) || defined(SWITCH)
|
#if defined(__CELLOS_LV2__) || defined(PSP) || defined(PS2) || defined(GEKKO) || defined(VITA) || defined(_XBOX) || defined(_3DS) || defined(WIIU) || defined(SWITCH) || defined(HAVE_LIBNX)
|
||||||
/* No mman available */
|
/* No mman available */
|
||||||
#elif defined(_WIN32) && !defined(_XBOX)
|
#elif defined(_WIN32) && !defined(_XBOX)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|||||||
@@ -34,4 +34,3 @@ in a public API, you may need this.
|
|||||||
#include <compat/msvc.h>
|
#include <compat/msvc.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,9 @@ typedef int ssize_t;
|
|||||||
/* C++11 says this one isn't needed, but apparently (some versions of) mingw require it anyways */
|
/* C++11 says this one isn't needed, but apparently (some versions of) mingw require it anyways */
|
||||||
/* https://stackoverflow.com/questions/8132399/how-to-printf-uint64-t-fails-with-spurious-trailing-in-format */
|
/* https://stackoverflow.com/questions/8132399/how-to-printf-uint64-t-fails-with-spurious-trailing-in-format */
|
||||||
/* https://github.com/libretro/RetroArch/issues/6009 */
|
/* https://github.com/libretro/RetroArch/issues/6009 */
|
||||||
#define __STDC_FORMAT_MACROS
|
#ifndef __STDC_FORMAT_MACROS
|
||||||
|
#define __STDC_FORMAT_MACROS 1
|
||||||
|
#endif
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef PRId64
|
#ifndef PRId64
|
||||||
@@ -113,6 +115,5 @@ Of course, another school of thought is that you should do as little damage as p
|
|||||||
in as few places as possible...
|
in as few places as possible...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* _LIBRETRO_COMMON_RETRO_COMMON_API_H */
|
/* _LIBRETRO_COMMON_RETRO_COMMON_API_H */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2010-2018 The RetroArch team
|
/* Copyright (C) 2010-2019 The RetroArch team
|
||||||
*
|
*
|
||||||
* ---------------------------------------------------------------------------------------
|
* ---------------------------------------------------------------------------------------
|
||||||
* The following license statement only applies to this file (retro_dirent.h).
|
* The following license statement only applies to this file (retro_dirent.h).
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#ifndef __RETRO_DIRENT_H
|
#ifndef __RETRO_DIRENT_H
|
||||||
#define __RETRO_DIRENT_H
|
#define __RETRO_DIRENT_H
|
||||||
|
|
||||||
|
#include <libretro.h>
|
||||||
#include <retro_common_api.h>
|
#include <retro_common_api.h>
|
||||||
#include <retro_miscellaneous.h>
|
#include <retro_miscellaneous.h>
|
||||||
|
|
||||||
@@ -30,6 +31,10 @@
|
|||||||
|
|
||||||
RETRO_BEGIN_DECLS
|
RETRO_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define DIRENT_REQUIRED_VFS_VERSION 3
|
||||||
|
|
||||||
|
void dirent_vfs_init(const struct retro_vfs_interface_info* vfs_info);
|
||||||
|
|
||||||
typedef struct RDIR RDIR;
|
typedef struct RDIR RDIR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,25 +49,27 @@ typedef struct RDIR RDIR;
|
|||||||
*/
|
*/
|
||||||
struct RDIR *retro_opendir(const char *name);
|
struct RDIR *retro_opendir(const char *name);
|
||||||
|
|
||||||
|
struct RDIR *retro_opendir_include_hidden(const char *name, bool include_hidden);
|
||||||
|
|
||||||
int retro_readdir(struct RDIR *rdir);
|
int retro_readdir(struct RDIR *rdir);
|
||||||
|
|
||||||
|
/* Deprecated, returns false, left for compatibility */
|
||||||
bool retro_dirent_error(struct RDIR *rdir);
|
bool retro_dirent_error(struct RDIR *rdir);
|
||||||
|
|
||||||
void retro_dirent_include_hidden(struct RDIR *rdir, bool include_hidden);
|
|
||||||
|
|
||||||
const char *retro_dirent_get_name(struct RDIR *rdir);
|
const char *retro_dirent_get_name(struct RDIR *rdir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* retro_dirent_is_dir:
|
* retro_dirent_is_dir:
|
||||||
* @rdir : pointer to the directory entry.
|
* @rdir : pointer to the directory entry.
|
||||||
|
* @unused : deprecated, included for compatibility reasons, pass NULL
|
||||||
*
|
*
|
||||||
* Is the directory listing entry a directory?
|
* Is the directory listing entry a directory?
|
||||||
*
|
*
|
||||||
* Returns: true if directory listing entry is
|
* Returns: true if directory listing entry is
|
||||||
* a directory, false if not.
|
* a directory, false if not.
|
||||||
*/
|
*/
|
||||||
bool retro_dirent_is_dir(struct RDIR *rdir, const char *path);
|
bool retro_dirent_is_dir(struct RDIR *rdir, const char *unused);
|
||||||
|
|
||||||
void retro_closedir(struct RDIR *rdir);
|
void retro_closedir(struct RDIR *rdir);
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,42 @@ printf("This is C++, version %d.\n", __cplusplus);
|
|||||||
/* This is not standard C. __STDC__ is not defined. */
|
/* This is not standard C. __STDC__ is not defined. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
|
||||||
|
/* Try to find out if we're compiling for WinRT or non-WinRT */
|
||||||
|
#if defined(_MSC_VER) && defined(__has_include)
|
||||||
|
#if __has_include(<winapifamily.h>)
|
||||||
|
#define HAVE_WINAPIFAMILY_H 1
|
||||||
|
#else
|
||||||
|
#define HAVE_WINAPIFAMILY_H 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If _USING_V110_SDK71_ is defined it means we are using the Windows XP toolset. */
|
||||||
|
#elif defined(_MSC_VER) && (_MSC_VER >= 1700 && !_USING_V110_SDK71_) /* _MSC_VER == 1700 for Visual Studio 2012 */
|
||||||
|
#define HAVE_WINAPIFAMILY_H 1
|
||||||
|
#else
|
||||||
|
#define HAVE_WINAPIFAMILY_H 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_WINAPIFAMILY_H
|
||||||
|
#include <winapifamily.h>
|
||||||
|
#define WINAPI_FAMILY_WINRT (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP))
|
||||||
|
#else
|
||||||
|
#define WINAPI_FAMILY_WINRT 0
|
||||||
|
#endif /* HAVE_WINAPIFAMILY_H */
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY_WINRT
|
||||||
|
#undef __WINRT__
|
||||||
|
#define __WINRT__ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MSVC obviously has to have some non-standard constants... */
|
||||||
|
#if _M_IX86_FP == 1
|
||||||
|
#define __SSE__ 1
|
||||||
|
#elif _M_IX86_FP == 2 || (defined(_M_AMD64) || defined(_M_X64))
|
||||||
|
#define __SSE__ 1
|
||||||
|
#define __SSE2__ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count)
|
|||||||
#ifndef PATH_MAX_LENGTH
|
#ifndef PATH_MAX_LENGTH
|
||||||
#if defined(__CELLOS_LV2__)
|
#if defined(__CELLOS_LV2__)
|
||||||
#define PATH_MAX_LENGTH CELL_FS_MAX_FS_PATH_LENGTH
|
#define PATH_MAX_LENGTH CELL_FS_MAX_FS_PATH_LENGTH
|
||||||
#elif defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(GEKKO)|| defined(WIIU)
|
#elif defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(PS2) || defined(GEKKO)|| defined(WIIU) || defined(ORBIS)
|
||||||
#define PATH_MAX_LENGTH 512
|
#define PATH_MAX_LENGTH 512
|
||||||
#else
|
#else
|
||||||
#define PATH_MAX_LENGTH 4096
|
#define PATH_MAX_LENGTH 4096
|
||||||
@@ -155,4 +155,28 @@ typedef struct
|
|||||||
uint32_t data[8];
|
uint32_t data[8];
|
||||||
} retro_bits_t;
|
} retro_bits_t;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# ifdef _WIN64
|
||||||
|
# define PRI_SIZET PRIu64
|
||||||
|
# else
|
||||||
|
# if _MSC_VER == 1800
|
||||||
|
# define PRI_SIZET PRIu32
|
||||||
|
# else
|
||||||
|
# define PRI_SIZET "u"
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#elif PS2
|
||||||
|
# define PRI_SIZET "u"
|
||||||
|
#else
|
||||||
|
# if (SIZE_MAX == 0xFFFF)
|
||||||
|
# define PRI_SIZET "hu"
|
||||||
|
# elif (SIZE_MAX == 0xFFFFFFFF)
|
||||||
|
# define PRI_SIZET "u"
|
||||||
|
# elif (SIZE_MAX == 0xFFFFFFFFFFFFFFFF)
|
||||||
|
# define PRI_SIZET "lu"
|
||||||
|
# else
|
||||||
|
# error PRI_SIZET: unknown SIZE_MAX
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -36,19 +36,22 @@
|
|||||||
#include <boolean.h>
|
#include <boolean.h>
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <vfs/vfs_implementation.h>
|
||||||
|
|
||||||
#define FILESTREAM_REQUIRED_VFS_VERSION 1
|
#define FILESTREAM_REQUIRED_VFS_VERSION 2
|
||||||
|
|
||||||
RETRO_BEGIN_DECLS
|
RETRO_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct RFILE RFILE;
|
typedef struct RFILE RFILE;
|
||||||
|
|
||||||
#define FILESTREAM_REQUIRED_VFS_VERSION 1
|
#define FILESTREAM_REQUIRED_VFS_VERSION 2
|
||||||
|
|
||||||
void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info);
|
void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info);
|
||||||
|
|
||||||
int64_t filestream_get_size(RFILE *stream);
|
int64_t filestream_get_size(RFILE *stream);
|
||||||
|
|
||||||
|
int64_t filestream_truncate(RFILE *stream, int64_t length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* filestream_open:
|
* filestream_open:
|
||||||
* @path : path to file
|
* @path : path to file
|
||||||
@@ -58,7 +61,7 @@ int64_t filestream_get_size(RFILE *stream);
|
|||||||
* Opens a file for reading or writing, depending on the requested mode.
|
* Opens a file for reading or writing, depending on the requested mode.
|
||||||
* Returns a pointer to an RFILE if opened successfully, otherwise NULL.
|
* Returns a pointer to an RFILE if opened successfully, otherwise NULL.
|
||||||
**/
|
**/
|
||||||
RFILE *filestream_open(const char *path, unsigned mode, unsigned hints);
|
RFILE* filestream_open(const char *path, unsigned mode, unsigned hints);
|
||||||
|
|
||||||
int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position);
|
int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position);
|
||||||
|
|
||||||
@@ -74,10 +77,12 @@ int filestream_close(RFILE *stream);
|
|||||||
|
|
||||||
int64_t filestream_read_file(const char *path, void **buf, int64_t *len);
|
int64_t filestream_read_file(const char *path, void **buf, int64_t *len);
|
||||||
|
|
||||||
char *filestream_gets(RFILE *stream, char *s, size_t len);
|
char* filestream_gets(RFILE *stream, char *s, size_t len);
|
||||||
|
|
||||||
int filestream_getc(RFILE *stream);
|
int filestream_getc(RFILE *stream);
|
||||||
|
|
||||||
|
int filestream_scanf(RFILE *stream, const char* format, ...);
|
||||||
|
|
||||||
int filestream_eof(RFILE *stream);
|
int filestream_eof(RFILE *stream);
|
||||||
|
|
||||||
bool filestream_write_file(const char *path, const void *data, int64_t size);
|
bool filestream_write_file(const char *path, const void *data, int64_t size);
|
||||||
@@ -96,11 +101,14 @@ int filestream_delete(const char *path);
|
|||||||
|
|
||||||
int filestream_rename(const char *old_path, const char *new_path);
|
int filestream_rename(const char *old_path, const char *new_path);
|
||||||
|
|
||||||
const char *filestream_get_path(RFILE *stream);
|
const char* filestream_get_path(RFILE *stream);
|
||||||
|
|
||||||
bool filestream_exists(const char *path);
|
bool filestream_exists(const char *path);
|
||||||
|
|
||||||
char *filestream_getline(RFILE *stream);
|
/* Returned pointer must be freed by the caller. */
|
||||||
|
char* filestream_getline(RFILE *stream);
|
||||||
|
|
||||||
|
libretro_vfs_implementation_file* filestream_get_vfs_handle(RFILE *stream);
|
||||||
|
|
||||||
RETRO_END_DECLS
|
RETRO_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
RETRO_BEGIN_DECLS
|
RETRO_BEGIN_DECLS
|
||||||
|
|
||||||
|
#ifndef SKIP_STDIO_REDEFINES
|
||||||
|
|
||||||
#define FILE RFILE
|
#define FILE RFILE
|
||||||
|
|
||||||
#undef fopen
|
#undef fopen
|
||||||
@@ -41,9 +43,11 @@ RETRO_BEGIN_DECLS
|
|||||||
#undef fgetc
|
#undef fgetc
|
||||||
#undef fwrite
|
#undef fwrite
|
||||||
#undef fputc
|
#undef fputc
|
||||||
|
#undef fflush
|
||||||
#undef fprintf
|
#undef fprintf
|
||||||
#undef ferror
|
#undef ferror
|
||||||
#undef feof
|
#undef feof
|
||||||
|
#undef fscanf
|
||||||
|
|
||||||
#define fopen rfopen
|
#define fopen rfopen
|
||||||
#define fclose rfclose
|
#define fclose rfclose
|
||||||
@@ -54,9 +58,13 @@ RETRO_BEGIN_DECLS
|
|||||||
#define fgetc rfgetc
|
#define fgetc rfgetc
|
||||||
#define fwrite rfwrite
|
#define fwrite rfwrite
|
||||||
#define fputc rfputc
|
#define fputc rfputc
|
||||||
|
#define fflush rfflush
|
||||||
#define fprintf rfprintf
|
#define fprintf rfprintf
|
||||||
#define ferror rferror
|
#define ferror rferror
|
||||||
#define feof rfeof
|
#define feof rfeof
|
||||||
|
#define fscanf rfscanf
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
RFILE* rfopen(const char *path, const char *mode);
|
RFILE* rfopen(const char *path, const char *mode);
|
||||||
|
|
||||||
@@ -78,12 +86,16 @@ int64_t rfwrite(void const* buffer,
|
|||||||
|
|
||||||
int rfputc(int character, RFILE * stream);
|
int rfputc(int character, RFILE * stream);
|
||||||
|
|
||||||
|
int64_t rfflush(RFILE * stream);
|
||||||
|
|
||||||
int rfprintf(RFILE * stream, const char * format, ...);
|
int rfprintf(RFILE * stream, const char * format, ...);
|
||||||
|
|
||||||
int rferror(RFILE* stream);
|
int rferror(RFILE* stream);
|
||||||
|
|
||||||
int rfeof(RFILE* stream);
|
int rfeof(RFILE* stream);
|
||||||
|
|
||||||
|
int rfscanf(RFILE * stream, const char * format, ...);
|
||||||
|
|
||||||
RETRO_END_DECLS
|
RETRO_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2010-2018 The RetroArch team
|
/* Copyright (C) 2010-2019 The RetroArch team
|
||||||
*
|
*
|
||||||
* ---------------------------------------------------------------------------------------
|
* ---------------------------------------------------------------------------------------
|
||||||
* The following license statement only applies to this file (stdstring.h).
|
* The following license statement only applies to this file (stdstring.h).
|
||||||
@@ -37,43 +37,20 @@ RETRO_BEGIN_DECLS
|
|||||||
|
|
||||||
static INLINE bool string_is_empty(const char *data)
|
static INLINE bool string_is_empty(const char *data)
|
||||||
{
|
{
|
||||||
return (data == NULL) || (*data == '\0');
|
return !data || (*data == '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE bool string_is_equal(const char *a, const char *b)
|
static INLINE bool string_is_equal(const char *a, const char *b)
|
||||||
{
|
{
|
||||||
if (!a || !b)
|
return (a && b) ? !strcmp(a, b) : false;
|
||||||
return false;
|
|
||||||
while(*a && (*a == *b))
|
|
||||||
a++, b++;
|
|
||||||
return (*(const unsigned char*)a - *(const unsigned char*)b) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE bool string_is_not_equal(const char *a, const char *b)
|
#define STRLEN_CONST(x) ((sizeof((x))-1))
|
||||||
{
|
|
||||||
return !string_is_equal(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define string_add_pair_open(s, size) strlcat((s), " (", (size))
|
#define string_is_not_equal(a, b) !string_is_equal((a), (b))
|
||||||
#define string_add_pair_close(s, size) strlcat((s), ")", (size))
|
|
||||||
#define string_add_bracket_open(s, size) strlcat((s), "{", (size))
|
|
||||||
#define string_add_bracket_close(s, size) strlcat((s), "}", (size))
|
|
||||||
#define string_add_single_quote(s, size) strlcat((s), "'", (size))
|
|
||||||
#define string_add_quote(s, size) strlcat((s), "\"", (size))
|
|
||||||
#define string_add_colon(s, size) strlcat((s), ":", (size))
|
|
||||||
#define string_add_glob_open(s, size) strlcat((s), "glob('*", (size))
|
|
||||||
#define string_add_glob_close(s, size) strlcat((s), "*')", (size))
|
|
||||||
|
|
||||||
static INLINE void string_add_between_pairs(char *s, const char *str,
|
|
||||||
size_t size)
|
|
||||||
{
|
|
||||||
string_add_pair_open(s, size);
|
|
||||||
strlcat(s, str, size);
|
|
||||||
string_add_pair_close(s, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define string_is_not_equal_fast(a, b, size) (memcmp(a, b, size) != 0)
|
#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 string_is_equal_fast(a, b, size) (memcmp(a, b, size) == 0)
|
||||||
|
|
||||||
static INLINE bool string_is_equal_case_insensitive(const char *a,
|
static INLINE bool string_is_equal_case_insensitive(const char *a,
|
||||||
const char *b)
|
const char *b)
|
||||||
@@ -116,7 +93,7 @@ char *string_to_upper(char *s);
|
|||||||
|
|
||||||
char *string_to_lower(char *s);
|
char *string_to_lower(char *s);
|
||||||
|
|
||||||
char *string_ucwords(char* s);
|
char *string_ucwords(char *s);
|
||||||
|
|
||||||
char *string_replace_substring(const char *in, const char *pattern,
|
char *string_replace_substring(const char *in, const char *pattern,
|
||||||
const char *by);
|
const char *by);
|
||||||
@@ -130,7 +107,44 @@ char *string_trim_whitespace_right(char *const s);
|
|||||||
/* Remove leading and trailing whitespaces */
|
/* Remove leading and trailing whitespaces */
|
||||||
char *string_trim_whitespace(char *const s);
|
char *string_trim_whitespace(char *const s);
|
||||||
|
|
||||||
char *word_wrap(char* buffer, const char *string, int line_width, bool unicode);
|
/* max_lines == 0 means no limit */
|
||||||
|
char *word_wrap(char *buffer, const char *string,
|
||||||
|
int line_width, bool unicode, unsigned max_lines);
|
||||||
|
|
||||||
|
/* Splits string into tokens seperated by 'delim'
|
||||||
|
* > Returned token string must be free()'d
|
||||||
|
* > Returns NULL if token is not found
|
||||||
|
* > After each call, 'str' is set to the position after the
|
||||||
|
* last found token
|
||||||
|
* > Tokens *include* empty strings
|
||||||
|
* Usage example:
|
||||||
|
* char *str = "1,2,3,4,5,6,7,,,10,";
|
||||||
|
* char **str_ptr = &str;
|
||||||
|
* char *token = NULL;
|
||||||
|
* while((token = string_tokenize(str_ptr, ",")))
|
||||||
|
* {
|
||||||
|
* printf("%s\n", token);
|
||||||
|
* free(token);
|
||||||
|
* token = NULL;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
char* string_tokenize(char **str, const char *delim);
|
||||||
|
|
||||||
|
/* Removes every instance of character 'c' from 'str' */
|
||||||
|
void string_remove_all_chars(char *str, char c);
|
||||||
|
|
||||||
|
/* Replaces every instance of character 'find' in 'str'
|
||||||
|
* with character 'replace' */
|
||||||
|
void string_replace_all_chars(char *str, char find, char replace);
|
||||||
|
|
||||||
|
/* Converts string to unsigned integer.
|
||||||
|
* Returns 0 if string is invalid */
|
||||||
|
unsigned string_to_unsigned(const char *str);
|
||||||
|
|
||||||
|
/* Converts hexadecimal string to unsigned integer.
|
||||||
|
* Handles optional leading '0x'.
|
||||||
|
* Returns 0 if string is invalid */
|
||||||
|
unsigned string_hex_to_unsigned(const char *str);
|
||||||
|
|
||||||
RETRO_END_DECLS
|
RETRO_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2010-2018 The RetroArch team
|
/* Copyright (C) 2010-2019 The RetroArch team
|
||||||
*
|
*
|
||||||
* ---------------------------------------------------------------------------------------
|
* ---------------------------------------------------------------------------------------
|
||||||
* The following license statement only applies to this file (vfs_implementation.h).
|
* The following license statement only applies to this file (vfs_implementation.h).
|
||||||
@@ -23,20 +23,13 @@
|
|||||||
#ifndef __LIBRETRO_SDK_VFS_IMPLEMENTATION_H
|
#ifndef __LIBRETRO_SDK_VFS_IMPLEMENTATION_H
|
||||||
#define __LIBRETRO_SDK_VFS_IMPLEMENTATION_H
|
#define __LIBRETRO_SDK_VFS_IMPLEMENTATION_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <libretro.h>
|
#include <libretro.h>
|
||||||
|
#include <retro_environment.h>
|
||||||
|
#include <vfs/vfs.h>
|
||||||
|
|
||||||
/* Replace the following symbol with something appropriate
|
RETRO_BEGIN_DECLS
|
||||||
* to signify the file is being compiled for a front end instead of a core.
|
|
||||||
* This allows the same code to act as reference implementation
|
|
||||||
* for VFS and as fallbacks for when the front end does not provide VFS functionality.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef VFS_FRONTEND
|
|
||||||
typedef struct retro_vfs_file_handle libretro_vfs_implementation_file;
|
|
||||||
#else
|
|
||||||
typedef struct libretro_vfs_implementation_file libretro_vfs_implementation_file;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, unsigned mode, unsigned hints);
|
libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, unsigned mode, unsigned hints);
|
||||||
|
|
||||||
@@ -46,6 +39,8 @@ int retro_vfs_file_error_impl(libretro_vfs_implementation_file *stream);
|
|||||||
|
|
||||||
int64_t retro_vfs_file_size_impl(libretro_vfs_implementation_file *stream);
|
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);
|
||||||
|
|
||||||
int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream);
|
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);
|
int64_t retro_vfs_file_seek_impl(libretro_vfs_implementation_file *stream, int64_t offset, int seek_position);
|
||||||
@@ -62,4 +57,20 @@ int retro_vfs_file_rename_impl(const char *old_path, const char *new_path);
|
|||||||
|
|
||||||
const char *retro_vfs_file_get_path_impl(libretro_vfs_implementation_file *stream);
|
const char *retro_vfs_file_get_path_impl(libretro_vfs_implementation_file *stream);
|
||||||
|
|
||||||
|
int retro_vfs_stat_impl(const char *path, int32_t *size);
|
||||||
|
|
||||||
|
int retro_vfs_mkdir_impl(const char *dir);
|
||||||
|
|
||||||
|
libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *dir, bool include_hidden);
|
||||||
|
|
||||||
|
bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *dirstream);
|
||||||
|
|
||||||
|
const char *retro_vfs_dirent_get_name_impl(libretro_vfs_implementation_dir *dirstream);
|
||||||
|
|
||||||
|
bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *dirstream);
|
||||||
|
|
||||||
|
int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *dirstream);
|
||||||
|
|
||||||
|
RETRO_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@@ -40,6 +41,7 @@ static retro_vfs_get_path_t filestream_get_path_cb = NULL;
|
|||||||
static retro_vfs_open_t filestream_open_cb = NULL;
|
static retro_vfs_open_t filestream_open_cb = NULL;
|
||||||
static retro_vfs_close_t filestream_close_cb = NULL;
|
static retro_vfs_close_t filestream_close_cb = NULL;
|
||||||
static retro_vfs_size_t filestream_size_cb = NULL;
|
static retro_vfs_size_t filestream_size_cb = NULL;
|
||||||
|
static retro_vfs_truncate_t filestream_truncate_cb = NULL;
|
||||||
static retro_vfs_tell_t filestream_tell_cb = NULL;
|
static retro_vfs_tell_t filestream_tell_cb = NULL;
|
||||||
static retro_vfs_seek_t filestream_seek_cb = NULL;
|
static retro_vfs_seek_t filestream_seek_cb = NULL;
|
||||||
static retro_vfs_read_t filestream_read_cb = NULL;
|
static retro_vfs_read_t filestream_read_cb = NULL;
|
||||||
@@ -66,6 +68,7 @@ void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info)
|
|||||||
filestream_close_cb = NULL;
|
filestream_close_cb = NULL;
|
||||||
filestream_tell_cb = NULL;
|
filestream_tell_cb = NULL;
|
||||||
filestream_size_cb = NULL;
|
filestream_size_cb = NULL;
|
||||||
|
filestream_truncate_cb = NULL;
|
||||||
filestream_seek_cb = NULL;
|
filestream_seek_cb = NULL;
|
||||||
filestream_read_cb = NULL;
|
filestream_read_cb = NULL;
|
||||||
filestream_write_cb = NULL;
|
filestream_write_cb = NULL;
|
||||||
@@ -83,6 +86,7 @@ void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info)
|
|||||||
filestream_open_cb = vfs_iface->open;
|
filestream_open_cb = vfs_iface->open;
|
||||||
filestream_close_cb = vfs_iface->close;
|
filestream_close_cb = vfs_iface->close;
|
||||||
filestream_size_cb = vfs_iface->size;
|
filestream_size_cb = vfs_iface->size;
|
||||||
|
filestream_truncate_cb = vfs_iface->truncate;
|
||||||
filestream_tell_cb = vfs_iface->tell;
|
filestream_tell_cb = vfs_iface->tell;
|
||||||
filestream_seek_cb = vfs_iface->seek;
|
filestream_seek_cb = vfs_iface->seek;
|
||||||
filestream_read_cb = vfs_iface->read;
|
filestream_read_cb = vfs_iface->read;
|
||||||
@@ -126,6 +130,21 @@ int64_t filestream_get_size(RFILE *stream)
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t filestream_truncate(RFILE *stream, int64_t length)
|
||||||
|
{
|
||||||
|
int64_t output;
|
||||||
|
|
||||||
|
if (filestream_truncate_cb != NULL)
|
||||||
|
output = filestream_truncate_cb(stream->hfile, length);
|
||||||
|
else
|
||||||
|
output = retro_vfs_file_truncate_impl((libretro_vfs_implementation_file*)stream->hfile, length);
|
||||||
|
|
||||||
|
if (output == vfs_error_return_value)
|
||||||
|
stream->error_flag = true;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* filestream_open:
|
* filestream_open:
|
||||||
* @path : path to file
|
* @path : path to file
|
||||||
@@ -135,7 +154,7 @@ int64_t filestream_get_size(RFILE *stream)
|
|||||||
* Opens a file for reading or writing, depending on the requested mode.
|
* Opens a file for reading or writing, depending on the requested mode.
|
||||||
* Returns a pointer to an RFILE if opened successfully, otherwise NULL.
|
* Returns a pointer to an RFILE if opened successfully, otherwise NULL.
|
||||||
**/
|
**/
|
||||||
RFILE *filestream_open(const char *path, unsigned mode, unsigned hints)
|
RFILE* filestream_open(const char *path, unsigned mode, unsigned hints)
|
||||||
{
|
{
|
||||||
struct retro_vfs_file_handle *fp = NULL;
|
struct retro_vfs_file_handle *fp = NULL;
|
||||||
RFILE* output = NULL;
|
RFILE* output = NULL;
|
||||||
@@ -157,7 +176,7 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints)
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *filestream_gets(RFILE *stream, char *s, size_t len)
|
char* filestream_gets(RFILE *stream, char *s, size_t len)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
char *p = s;
|
char *p = s;
|
||||||
@@ -185,12 +204,107 @@ int filestream_getc(RFILE *stream)
|
|||||||
{
|
{
|
||||||
char c = 0;
|
char c = 0;
|
||||||
if (!stream)
|
if (!stream)
|
||||||
return 0;
|
return EOF;
|
||||||
if(filestream_read(stream, &c, 1) == 1)
|
if (filestream_read(stream, &c, 1) == 1)
|
||||||
return (int)c;
|
return (int)(unsigned char)c;
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int filestream_scanf(RFILE *stream, const char* format, ...)
|
||||||
|
{
|
||||||
|
char buf[4096];
|
||||||
|
char subfmt[64];
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
const char * bufiter = buf;
|
||||||
|
int64_t startpos = filestream_tell(stream);
|
||||||
|
int ret = 0;
|
||||||
|
int64_t maxlen = filestream_read(stream, buf, sizeof(buf)-1);
|
||||||
|
|
||||||
|
if (maxlen <= 0)
|
||||||
|
return EOF;
|
||||||
|
|
||||||
|
buf[maxlen] = '\0';
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
while (*format)
|
||||||
|
{
|
||||||
|
if (*format == '%')
|
||||||
|
{
|
||||||
|
int sublen;
|
||||||
|
|
||||||
|
char* subfmtiter = subfmt;
|
||||||
|
bool asterisk = false;
|
||||||
|
|
||||||
|
*subfmtiter++ = *format++; /* '%' */
|
||||||
|
|
||||||
|
/* %[*][width][length]specifier */
|
||||||
|
|
||||||
|
if (*format == '*')
|
||||||
|
{
|
||||||
|
asterisk = true;
|
||||||
|
*subfmtiter++ = *format++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (isdigit(*format)) *subfmtiter++ = *format++; /* width */
|
||||||
|
|
||||||
|
/* length */
|
||||||
|
if (*format == 'h' || *format == 'l')
|
||||||
|
{
|
||||||
|
if (format[1] == format[0]) *subfmtiter++ = *format++;
|
||||||
|
*subfmtiter++ = *format++;
|
||||||
|
}
|
||||||
|
else if (*format == 'j' || *format == 'z' || *format == 't' || *format == 'L')
|
||||||
|
{
|
||||||
|
*subfmtiter++ = *format++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* specifier - always a single character (except ]) */
|
||||||
|
if (*format == '[')
|
||||||
|
{
|
||||||
|
while (*format != ']') *subfmtiter++ = *format++;
|
||||||
|
*subfmtiter++ = *format++;
|
||||||
|
}
|
||||||
|
else *subfmtiter++ = *format++;
|
||||||
|
|
||||||
|
*subfmtiter++ = '%';
|
||||||
|
*subfmtiter++ = 'n';
|
||||||
|
*subfmtiter++ = '\0';
|
||||||
|
|
||||||
|
if (sizeof(void*) != sizeof(long*)) abort(); /* all pointers must have the same size */
|
||||||
|
if (asterisk)
|
||||||
|
{
|
||||||
|
if (sscanf(bufiter, subfmt, &sublen) != 0) break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sscanf(bufiter, subfmt, va_arg(args, void*), &sublen) != 1) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret++;
|
||||||
|
bufiter += sublen;
|
||||||
|
}
|
||||||
|
else if (isspace(*format))
|
||||||
|
{
|
||||||
|
while (isspace(*bufiter)) bufiter++;
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*bufiter != *format)
|
||||||
|
break;
|
||||||
|
bufiter++;
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
filestream_seek(stream, startpos+(bufiter-buf), RETRO_VFS_SEEK_POSITION_START);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position)
|
int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position)
|
||||||
{
|
{
|
||||||
int64_t output;
|
int64_t output;
|
||||||
@@ -212,7 +326,6 @@ int filestream_eof(RFILE *stream)
|
|||||||
return stream->eof_flag;
|
return stream->eof_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int64_t filestream_tell(RFILE *stream)
|
int64_t filestream_tell(RFILE *stream)
|
||||||
{
|
{
|
||||||
int64_t output;
|
int64_t output;
|
||||||
@@ -286,7 +399,7 @@ int filestream_rename(const char *old_path, const char *new_path)
|
|||||||
return retro_vfs_file_rename_impl(old_path, new_path);
|
return retro_vfs_file_rename_impl(old_path, new_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *filestream_get_path(RFILE *stream)
|
const char* filestream_get_path(RFILE *stream)
|
||||||
{
|
{
|
||||||
if (filestream_get_path_cb != NULL)
|
if (filestream_get_path_cb != NULL)
|
||||||
return filestream_get_path_cb(stream->hfile);
|
return filestream_get_path_cb(stream->hfile);
|
||||||
@@ -314,7 +427,7 @@ int filestream_putc(RFILE *stream, int c)
|
|||||||
char c_char = (char)c;
|
char c_char = (char)c;
|
||||||
if (!stream)
|
if (!stream)
|
||||||
return EOF;
|
return EOF;
|
||||||
return filestream_write(stream, &c_char, 1)==1 ? c : EOF;
|
return filestream_write(stream, &c_char, 1)==1 ? (int)(unsigned char)c : EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
int filestream_vprintf(RFILE *stream, const char* format, va_list args)
|
int filestream_vprintf(RFILE *stream, const char* format, va_list args)
|
||||||
@@ -459,13 +572,14 @@ bool filestream_write_file(const char *path, const void *data, int64_t size)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *filestream_getline(RFILE *stream)
|
/* Returned pointer must be freed by the caller. */
|
||||||
|
char* filestream_getline(RFILE *stream)
|
||||||
{
|
{
|
||||||
char* newline_tmp = NULL;
|
char *newline_tmp = NULL;
|
||||||
size_t cur_size = 8;
|
size_t cur_size = 8;
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
int in = 0;
|
int in = 0;
|
||||||
char* newline = (char*)malloc(9);
|
char *newline = (char*)malloc(9);
|
||||||
|
|
||||||
if (!stream || !newline)
|
if (!stream || !newline)
|
||||||
{
|
{
|
||||||
@@ -499,3 +613,8 @@ char *filestream_getline(RFILE *stream)
|
|||||||
newline[idx] = '\0';
|
newline[idx] = '\0';
|
||||||
return newline;
|
return newline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libretro_vfs_implementation_file* filestream_get_vfs_handle(RFILE *stream)
|
||||||
|
{
|
||||||
|
return (libretro_vfs_implementation_file*)stream->hfile;
|
||||||
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ int64_t rfseek(RFILE* stream, int64_t offset, int origin)
|
|||||||
int64_t rfread(void* buffer,
|
int64_t rfread(void* buffer,
|
||||||
size_t elem_size, size_t elem_count, RFILE* stream)
|
size_t elem_size, size_t elem_count, RFILE* stream)
|
||||||
{
|
{
|
||||||
return filestream_read(stream, buffer, elem_size * elem_count);
|
return (filestream_read(stream, buffer, elem_size * elem_count) / elem_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rfgets(char *buffer, int maxCount, RFILE* stream)
|
char *rfgets(char *buffer, int maxCount, RFILE* stream)
|
||||||
@@ -109,7 +109,7 @@ char *rfgets(char *buffer, int maxCount, RFILE* stream)
|
|||||||
|
|
||||||
int rfgetc(RFILE* stream)
|
int rfgetc(RFILE* stream)
|
||||||
{
|
{
|
||||||
return filestream_getc(stream);
|
return filestream_getc(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t rfwrite(void const* buffer,
|
int64_t rfwrite(void const* buffer,
|
||||||
@@ -123,14 +123,19 @@ int rfputc(int character, RFILE * stream)
|
|||||||
return filestream_putc(stream, character);
|
return filestream_putc(stream, character);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t rfflush(RFILE * stream)
|
||||||
|
{
|
||||||
|
return filestream_flush(stream);
|
||||||
|
}
|
||||||
|
|
||||||
int rfprintf(RFILE * stream, const char * format, ...)
|
int rfprintf(RFILE * stream, const char * format, ...)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, format);
|
va_start(vl, format);
|
||||||
result = filestream_vprintf(stream, format, vl);
|
result = filestream_vprintf(stream, format, vl);
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rferror(RFILE* stream)
|
int rferror(RFILE* stream)
|
||||||
@@ -142,3 +147,13 @@ int rfeof(RFILE* stream)
|
|||||||
{
|
{
|
||||||
return filestream_eof(stream);
|
return filestream_eof(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rfscanf(RFILE * stream, const char * format, ...)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, format);
|
||||||
|
result = filestream_scanf(stream, format, vl);
|
||||||
|
va_end(vl);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
@@ -82,6 +82,10 @@ char *string_replace_substring(const char *in,
|
|||||||
|
|
||||||
outlen = strlen(in) - pattern_len*numhits + replacement_len*numhits;
|
outlen = strlen(in) - pattern_len*numhits + replacement_len*numhits;
|
||||||
out = (char *)malloc(outlen+1);
|
out = (char *)malloc(outlen+1);
|
||||||
|
|
||||||
|
if (!out)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
outat = out;
|
outat = out;
|
||||||
inat = in;
|
inat = in;
|
||||||
inprev = in;
|
inprev = in;
|
||||||
@@ -105,15 +109,17 @@ char *string_trim_whitespace_left(char *const s)
|
|||||||
{
|
{
|
||||||
if(s && *s)
|
if(s && *s)
|
||||||
{
|
{
|
||||||
size_t len = strlen(s);
|
size_t len = strlen(s);
|
||||||
char *cur = s;
|
char *current = s;
|
||||||
|
|
||||||
while(*cur && isspace((unsigned char)*cur))
|
while(*current && isspace((unsigned char)*current))
|
||||||
++cur, --len;
|
{
|
||||||
|
++current;
|
||||||
if(s != cur)
|
--len;
|
||||||
memmove(s, cur, len + 1);
|
}
|
||||||
|
|
||||||
|
if(s != current)
|
||||||
|
memmove(s, current, len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
@@ -124,13 +130,16 @@ char *string_trim_whitespace_right(char *const s)
|
|||||||
{
|
{
|
||||||
if(s && *s)
|
if(s && *s)
|
||||||
{
|
{
|
||||||
size_t len = strlen(s);
|
size_t len = strlen(s);
|
||||||
char *cur = s + len - 1;
|
char *current = s + len - 1;
|
||||||
|
|
||||||
while(cur != s && isspace((unsigned char)*cur))
|
while(current != s && isspace((unsigned char)*current))
|
||||||
--cur, --len;
|
{
|
||||||
|
--current;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
|
||||||
cur[isspace((unsigned char)*cur) ? 0 : 1] = '\0';
|
current[isspace((unsigned char)*current) ? 0 : 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
@@ -145,14 +154,16 @@ char *string_trim_whitespace(char *const s)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *word_wrap(char* buffer, const char *string, int line_width, bool unicode)
|
char *word_wrap(char* buffer, const char *string, int line_width, bool unicode, unsigned max_lines)
|
||||||
{
|
{
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
unsigned len = (unsigned)strlen(string);
|
unsigned len = (unsigned)strlen(string);
|
||||||
|
unsigned lines = 1;
|
||||||
|
|
||||||
while (i < len)
|
while (i < len)
|
||||||
{
|
{
|
||||||
unsigned counter;
|
unsigned counter;
|
||||||
|
int pos = (int)(&buffer[i] - buffer);
|
||||||
|
|
||||||
/* copy string until the end of the line is reached */
|
/* copy string until the end of the line is reached */
|
||||||
for (counter = 1; counter <= (unsigned)line_width; counter++)
|
for (counter = 1; counter <= (unsigned)line_width; counter++)
|
||||||
@@ -184,14 +195,21 @@ char *word_wrap(char* buffer, const char *string, int line_width, bool unicode)
|
|||||||
/* check for newlines embedded in the original input
|
/* check for newlines embedded in the original input
|
||||||
* and reset the index */
|
* and reset the index */
|
||||||
if (buffer[j] == '\n')
|
if (buffer[j] == '\n')
|
||||||
|
{
|
||||||
|
lines++;
|
||||||
counter = 1;
|
counter = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for whitespace */
|
/* check for whitespace */
|
||||||
if (string[i] == ' ')
|
if (string[i] == ' ')
|
||||||
{
|
{
|
||||||
buffer[i] = '\n';
|
if ((max_lines == 0 || lines < max_lines))
|
||||||
i++;
|
{
|
||||||
|
buffer[i] = '\n';
|
||||||
|
i++;
|
||||||
|
lines++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -200,14 +218,18 @@ char *word_wrap(char* buffer, const char *string, int line_width, bool unicode)
|
|||||||
/* check for nearest whitespace back in string */
|
/* check for nearest whitespace back in string */
|
||||||
for (k = i; k > 0; k--)
|
for (k = i; k > 0; k--)
|
||||||
{
|
{
|
||||||
if (string[k] != ' ')
|
if (string[k] != ' ' || (max_lines != 0 && lines >= max_lines))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
buffer[k] = '\n';
|
buffer[k] = '\n';
|
||||||
/* set string index back to character after this one */
|
/* set string index back to character after this one */
|
||||||
i = k + 1;
|
i = k + 1;
|
||||||
|
lines++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (&buffer[i] - buffer == pos)
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,3 +237,148 @@ char *word_wrap(char* buffer, const char *string, int line_width, bool unicode)
|
|||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Splits string into tokens seperated by 'delim'
|
||||||
|
* > Returned token string must be free()'d
|
||||||
|
* > Returns NULL if token is not found
|
||||||
|
* > After each call, 'str' is set to the position after the
|
||||||
|
* last found token
|
||||||
|
* > Tokens *include* empty strings
|
||||||
|
* Usage example:
|
||||||
|
* char *str = "1,2,3,4,5,6,7,,,10,";
|
||||||
|
* char **str_ptr = &str;
|
||||||
|
* char *token = NULL;
|
||||||
|
* while((token = string_tokenize(str_ptr, ",")))
|
||||||
|
* {
|
||||||
|
* printf("%s\n", token);
|
||||||
|
* free(token);
|
||||||
|
* token = NULL;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
char* string_tokenize(char **str, const char *delim)
|
||||||
|
{
|
||||||
|
/* Taken from https://codereview.stackexchange.com/questions/216956/strtok-function-thread-safe-supports-empty-tokens-doesnt-change-string# */
|
||||||
|
char *str_ptr = NULL;
|
||||||
|
char *delim_ptr = NULL;
|
||||||
|
char *token = NULL;
|
||||||
|
size_t token_len = 0;
|
||||||
|
|
||||||
|
/* Sanity checks */
|
||||||
|
if (!str || string_is_empty(delim))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
str_ptr = *str;
|
||||||
|
|
||||||
|
/* Note: we don't check string_is_empty() here,
|
||||||
|
* empty strings are valid */
|
||||||
|
if (!str_ptr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Search for delimiter */
|
||||||
|
delim_ptr = strstr(str_ptr, delim);
|
||||||
|
|
||||||
|
if (delim_ptr)
|
||||||
|
token_len = delim_ptr - str_ptr;
|
||||||
|
else
|
||||||
|
token_len = strlen(str_ptr);
|
||||||
|
|
||||||
|
/* Allocate token string */
|
||||||
|
token = (char *)malloc((token_len + 1) * sizeof(char));
|
||||||
|
|
||||||
|
if (!token)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Copy token */
|
||||||
|
strlcpy(token, str_ptr, (token_len + 1) * sizeof(char));
|
||||||
|
token[token_len] = '\0';
|
||||||
|
|
||||||
|
/* Update input string pointer */
|
||||||
|
*str = delim_ptr ? delim_ptr + strlen(delim) : NULL;
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Removes every instance of character 'c' from 'str' */
|
||||||
|
void string_remove_all_chars(char *str, char c)
|
||||||
|
{
|
||||||
|
char *read_ptr = NULL;
|
||||||
|
char *write_ptr = NULL;
|
||||||
|
|
||||||
|
if (string_is_empty(str))
|
||||||
|
return;
|
||||||
|
|
||||||
|
read_ptr = str;
|
||||||
|
write_ptr = str;
|
||||||
|
|
||||||
|
while (*read_ptr != '\0')
|
||||||
|
{
|
||||||
|
*write_ptr = *read_ptr++;
|
||||||
|
write_ptr += (*write_ptr != c) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*write_ptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replaces every instance of character 'find' in 'str'
|
||||||
|
* with character 'replace' */
|
||||||
|
void string_replace_all_chars(char *str, char find, char replace)
|
||||||
|
{
|
||||||
|
char *str_ptr = str;
|
||||||
|
|
||||||
|
if (string_is_empty(str))
|
||||||
|
return;
|
||||||
|
|
||||||
|
while((str_ptr = strchr(str_ptr, find)) != NULL)
|
||||||
|
*str_ptr++ = replace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Converts string to unsigned integer.
|
||||||
|
* Returns 0 if string is invalid */
|
||||||
|
unsigned string_to_unsigned(const char *str)
|
||||||
|
{
|
||||||
|
const char *ptr = NULL;
|
||||||
|
|
||||||
|
if (string_is_empty(str))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (ptr = str; *ptr != '\0'; ptr++)
|
||||||
|
{
|
||||||
|
if (!isdigit(*ptr))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned)strtoul(str, NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Converts hexadecimal string to unsigned integer.
|
||||||
|
* Handles optional leading '0x'.
|
||||||
|
* Returns 0 if string is invalid */
|
||||||
|
unsigned string_hex_to_unsigned(const char *str)
|
||||||
|
{
|
||||||
|
const char *hex_str = str;
|
||||||
|
const char *ptr = NULL;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (string_is_empty(str))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Remove leading '0x', if required */
|
||||||
|
len = strlen(str);
|
||||||
|
|
||||||
|
if (len >= 2)
|
||||||
|
if ((str[0] == '0') &&
|
||||||
|
((str[1] == 'x') || (str[1] == 'X')))
|
||||||
|
hex_str = str + 2;
|
||||||
|
|
||||||
|
if (string_is_empty(hex_str))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Check for valid characters */
|
||||||
|
for (ptr = hex_str; *ptr != '\0'; ptr++)
|
||||||
|
{
|
||||||
|
if (!isxdigit(*ptr))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned)strtoul(hex_str, NULL, 16);
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1038,6 +1038,26 @@ static const char *find_bios(int *region, const char *cd_fname)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_memory_maps(void)
|
||||||
|
{
|
||||||
|
if (PicoIn.AHW & PAHW_MCD)
|
||||||
|
{
|
||||||
|
const size_t SCD_BIT = 1ULL << 31ULL;
|
||||||
|
const uint64_t mem = RETRO_MEMDESC_SYSTEM_RAM;
|
||||||
|
struct retro_memory_map mmaps;
|
||||||
|
struct retro_memory_descriptor descs[] = {
|
||||||
|
{ mem, PicoMem.ram, 0, 0xFF0000, 0, 0, 0x10000, "68KRAM" },
|
||||||
|
/* virtual address using SCD_BIT so all 512M of prg_ram can be accessed */
|
||||||
|
/* at address $80020000 */
|
||||||
|
{ mem, Pico_mcd->prg_ram, 0, SCD_BIT | 0x020000, 0, 0, 0x80000, "PRGRAM" },
|
||||||
|
};
|
||||||
|
|
||||||
|
mmaps.descriptors = descs;
|
||||||
|
mmaps.num_descriptors = sizeof(descs) / sizeof(descs[0]);
|
||||||
|
environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &mmaps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool retro_load_game(const struct retro_game_info *info)
|
bool retro_load_game(const struct retro_game_info *info)
|
||||||
{
|
{
|
||||||
enum media_type_e media_type;
|
enum media_type_e media_type;
|
||||||
@@ -1156,6 +1176,9 @@ bool retro_load_game(const struct retro_game_info *info)
|
|||||||
PicoIn.sndOut = sndBuffer;
|
PicoIn.sndOut = sndBuffer;
|
||||||
PsndRerate(0);
|
PsndRerate(0);
|
||||||
|
|
||||||
|
/* Setup retro memory maps */
|
||||||
|
set_memory_maps();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user