mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
libretro, update libretro-common
This commit is contained in:
parent
8717984c12
commit
b4e7cd1b51
39 changed files with 1767 additions and 738 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2010-2018 The RetroArch team
|
||||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_stream.c).
|
||||
|
@ -31,11 +31,23 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <compat/msvc.h>
|
||||
#endif
|
||||
|
||||
#include <string/stdstring.h>
|
||||
#include <streams/file_stream.h>
|
||||
#define VFS_FRONTEND
|
||||
#include <vfs/vfs_implementation.h>
|
||||
|
||||
static const int64_t vfs_error_return_value = -1;
|
||||
#define VFS_ERROR_RETURN_VALUE -1
|
||||
|
||||
struct RFILE
|
||||
{
|
||||
struct retro_vfs_file_handle *hfile;
|
||||
bool error_flag;
|
||||
bool eof_flag;
|
||||
};
|
||||
|
||||
static retro_vfs_get_path_t filestream_get_path_cb = NULL;
|
||||
static retro_vfs_open_t filestream_open_cb = NULL;
|
||||
|
@ -50,18 +62,12 @@ static retro_vfs_flush_t filestream_flush_cb = NULL;
|
|||
static retro_vfs_remove_t filestream_remove_cb = NULL;
|
||||
static retro_vfs_rename_t filestream_rename_cb = NULL;
|
||||
|
||||
struct RFILE
|
||||
{
|
||||
struct retro_vfs_file_handle *hfile;
|
||||
bool error_flag;
|
||||
bool eof_flag;
|
||||
};
|
||||
|
||||
/* VFS Initialization */
|
||||
|
||||
void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info)
|
||||
{
|
||||
const struct retro_vfs_interface* vfs_iface;
|
||||
const struct retro_vfs_interface *
|
||||
vfs_iface = vfs_info->iface;
|
||||
|
||||
filestream_get_path_cb = NULL;
|
||||
filestream_open_cb = NULL;
|
||||
|
@ -76,9 +82,9 @@ void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info)
|
|||
filestream_remove_cb = NULL;
|
||||
filestream_rename_cb = NULL;
|
||||
|
||||
vfs_iface = vfs_info->iface;
|
||||
|
||||
if (vfs_info->required_interface_version < FILESTREAM_REQUIRED_VFS_VERSION
|
||||
if (
|
||||
(vfs_info->required_interface_version <
|
||||
FILESTREAM_REQUIRED_VFS_VERSION)
|
||||
|| !vfs_iface)
|
||||
return;
|
||||
|
||||
|
@ -99,19 +105,24 @@ void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info)
|
|||
/* Callback wrappers */
|
||||
bool filestream_exists(const char *path)
|
||||
{
|
||||
RFILE *dummy = NULL;
|
||||
RFILE *dummy = NULL;
|
||||
|
||||
if (!path || !*path)
|
||||
return false;
|
||||
|
||||
dummy = filestream_open(path,
|
||||
dummy = filestream_open(
|
||||
path,
|
||||
RETRO_VFS_FILE_ACCESS_READ,
|
||||
RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
|
||||
if (!dummy)
|
||||
return false;
|
||||
|
||||
filestream_close(dummy);
|
||||
if (filestream_close(dummy) != 0)
|
||||
if (dummy)
|
||||
free(dummy);
|
||||
|
||||
dummy = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -119,12 +130,13 @@ int64_t filestream_get_size(RFILE *stream)
|
|||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_size_cb != NULL)
|
||||
if (filestream_size_cb)
|
||||
output = filestream_size_cb(stream->hfile);
|
||||
else
|
||||
output = retro_vfs_file_size_impl((libretro_vfs_implementation_file*)stream->hfile);
|
||||
output = retro_vfs_file_size_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile);
|
||||
|
||||
if (output == vfs_error_return_value)
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
return output;
|
||||
|
@ -134,12 +146,13 @@ int64_t filestream_truncate(RFILE *stream, int64_t length)
|
|||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_truncate_cb != NULL)
|
||||
if (filestream_truncate_cb)
|
||||
output = filestream_truncate_cb(stream->hfile, length);
|
||||
else
|
||||
output = retro_vfs_file_truncate_impl((libretro_vfs_implementation_file*)stream->hfile, length);
|
||||
output = retro_vfs_file_truncate_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile, length);
|
||||
|
||||
if (output == vfs_error_return_value)
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
return output;
|
||||
|
@ -159,7 +172,7 @@ RFILE* filestream_open(const char *path, unsigned mode, unsigned hints)
|
|||
struct retro_vfs_file_handle *fp = NULL;
|
||||
RFILE* output = NULL;
|
||||
|
||||
if (filestream_open_cb != NULL)
|
||||
if (filestream_open_cb)
|
||||
fp = (struct retro_vfs_file_handle*)
|
||||
filestream_open_cb(path, mode, hints);
|
||||
else
|
||||
|
@ -203,22 +216,19 @@ char* filestream_gets(RFILE *stream, char *s, size_t len)
|
|||
int filestream_getc(RFILE *stream)
|
||||
{
|
||||
char c = 0;
|
||||
if (!stream)
|
||||
return EOF;
|
||||
if (filestream_read(stream, &c, 1) == 1)
|
||||
if (stream && filestream_read(stream, &c, 1) == 1)
|
||||
return (int)(unsigned char)c;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
int filestream_scanf(RFILE *stream, const char* format, ...)
|
||||
int filestream_vscanf(RFILE *stream, const char* format, va_list *args)
|
||||
{
|
||||
char buf[4096];
|
||||
char subfmt[64];
|
||||
va_list args;
|
||||
|
||||
va_list args_copy;
|
||||
const char * bufiter = buf;
|
||||
int64_t startpos = filestream_tell(stream);
|
||||
int ret = 0;
|
||||
int64_t startpos = filestream_tell(stream);
|
||||
int64_t maxlen = filestream_read(stream, buf, sizeof(buf)-1);
|
||||
|
||||
if (maxlen <= 0)
|
||||
|
@ -226,14 +236,22 @@ int filestream_scanf(RFILE *stream, const char* format, ...)
|
|||
|
||||
buf[maxlen] = '\0';
|
||||
|
||||
va_start(args, format);
|
||||
/* Have to copy the input va_list here
|
||||
* > Calling va_arg() on 'args' directly would
|
||||
* cause the va_list to have an indeterminate value
|
||||
* in the function calling filestream_vscanf(),
|
||||
* leading to unexpected behaviour */
|
||||
#ifdef __va_copy
|
||||
__va_copy(args_copy, *args);
|
||||
#else
|
||||
va_copy(args_copy, *args);
|
||||
#endif
|
||||
|
||||
while (*format)
|
||||
{
|
||||
if (*format == '%')
|
||||
{
|
||||
int sublen;
|
||||
|
||||
char* subfmtiter = subfmt;
|
||||
bool asterisk = false;
|
||||
|
||||
|
@ -243,19 +261,25 @@ int filestream_scanf(RFILE *stream, const char* format, ...)
|
|||
|
||||
if (*format == '*')
|
||||
{
|
||||
asterisk = true;
|
||||
asterisk = true;
|
||||
*subfmtiter++ = *format++;
|
||||
}
|
||||
|
||||
while (isdigit(*format)) *subfmtiter++ = *format++; /* width */
|
||||
while (ISDIGIT((unsigned char)*format))
|
||||
*subfmtiter++ = *format++; /* width */
|
||||
|
||||
/* length */
|
||||
if (*format == 'h' || *format == 'l')
|
||||
{
|
||||
if (format[1] == format[0]) *subfmtiter++ = *format++;
|
||||
*subfmtiter++ = *format++;
|
||||
if (format[1] == format[0])
|
||||
*subfmtiter++ = *format++;
|
||||
*subfmtiter++ = *format++;
|
||||
}
|
||||
else if (*format == 'j' || *format == 'z' || *format == 't' || *format == 'L')
|
||||
else if (
|
||||
*format == 'j' ||
|
||||
*format == 'z' ||
|
||||
*format == 't' ||
|
||||
*format == 'L')
|
||||
{
|
||||
*subfmtiter++ = *format++;
|
||||
}
|
||||
|
@ -263,31 +287,44 @@ int filestream_scanf(RFILE *stream, const char* format, ...)
|
|||
/* specifier - always a single character (except ]) */
|
||||
if (*format == '[')
|
||||
{
|
||||
while (*format != ']') *subfmtiter++ = *format++;
|
||||
*subfmtiter++ = *format++;
|
||||
while (*format != ']')
|
||||
*subfmtiter++ = *format++;
|
||||
*subfmtiter++ = *format++;
|
||||
}
|
||||
else *subfmtiter++ = *format++;
|
||||
else
|
||||
*subfmtiter++ = *format++;
|
||||
|
||||
*subfmtiter++ = '%';
|
||||
*subfmtiter++ = 'n';
|
||||
*subfmtiter++ = '\0';
|
||||
*subfmtiter++ = '%';
|
||||
*subfmtiter++ = 'n';
|
||||
*subfmtiter++ = '\0';
|
||||
|
||||
if (sizeof(void*) != sizeof(long*))
|
||||
abort(); /* all pointers must have the same size */
|
||||
|
||||
if (sizeof(void*) != sizeof(long*)) abort(); /* all pointers must have the same size */
|
||||
if (asterisk)
|
||||
{
|
||||
if (sscanf(bufiter, subfmt, &sublen) != 0) break;
|
||||
int v = sscanf(bufiter, subfmt, &sublen);
|
||||
if (v == EOF)
|
||||
return EOF;
|
||||
if (v != 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sscanf(bufiter, subfmt, va_arg(args, void*), &sublen) != 1) break;
|
||||
int v = sscanf(bufiter, subfmt, va_arg(args_copy, void*), &sublen);
|
||||
if (v == EOF)
|
||||
return EOF;
|
||||
if (v != 1)
|
||||
break;
|
||||
}
|
||||
|
||||
ret++;
|
||||
bufiter += sublen;
|
||||
}
|
||||
else if (isspace(*format))
|
||||
else if (isspace((unsigned char)*format))
|
||||
{
|
||||
while (isspace(*bufiter)) bufiter++;
|
||||
while (isspace((unsigned char)*bufiter))
|
||||
bufiter++;
|
||||
format++;
|
||||
}
|
||||
else
|
||||
|
@ -299,24 +336,38 @@ int filestream_scanf(RFILE *stream, const char* format, ...)
|
|||
}
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
filestream_seek(stream, startpos+(bufiter-buf), RETRO_VFS_SEEK_POSITION_START);
|
||||
va_end(args_copy);
|
||||
filestream_seek(stream, startpos+(bufiter-buf),
|
||||
RETRO_VFS_SEEK_POSITION_START);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int filestream_scanf(RFILE *stream, const char* format, ...)
|
||||
{
|
||||
int result;
|
||||
va_list vl;
|
||||
va_start(vl, format);
|
||||
result = filestream_vscanf(stream, format, &vl);
|
||||
va_end(vl);
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position)
|
||||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_seek_cb != NULL)
|
||||
if (filestream_seek_cb)
|
||||
output = filestream_seek_cb(stream->hfile, offset, seek_position);
|
||||
else
|
||||
output = retro_vfs_file_seek_impl((libretro_vfs_implementation_file*)stream->hfile, offset, seek_position);
|
||||
output = retro_vfs_file_seek_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile,
|
||||
offset, seek_position);
|
||||
|
||||
if (output == vfs_error_return_value)
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
stream->eof_flag = false;
|
||||
|
||||
stream->eof_flag = false;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -330,12 +381,13 @@ int64_t filestream_tell(RFILE *stream)
|
|||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_size_cb != NULL)
|
||||
if (filestream_size_cb)
|
||||
output = filestream_tell_cb(stream->hfile);
|
||||
else
|
||||
output = retro_vfs_file_tell_impl((libretro_vfs_implementation_file*)stream->hfile);
|
||||
output = retro_vfs_file_tell_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile);
|
||||
|
||||
if (output == vfs_error_return_value)
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
return output;
|
||||
|
@ -347,23 +399,23 @@ void filestream_rewind(RFILE *stream)
|
|||
return;
|
||||
filestream_seek(stream, 0L, RETRO_VFS_SEEK_POSITION_START);
|
||||
stream->error_flag = false;
|
||||
stream->eof_flag = false;
|
||||
stream->eof_flag = false;
|
||||
}
|
||||
|
||||
int64_t filestream_read(RFILE *stream, void *s, int64_t len)
|
||||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_read_cb != NULL)
|
||||
if (filestream_read_cb)
|
||||
output = filestream_read_cb(stream->hfile, s, len);
|
||||
else
|
||||
output = retro_vfs_file_read_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile, s, len);
|
||||
|
||||
if (output == vfs_error_return_value)
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
if (output < len)
|
||||
stream->eof_flag = true;
|
||||
stream->eof_flag = true;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -372,12 +424,13 @@ int filestream_flush(RFILE *stream)
|
|||
{
|
||||
int output;
|
||||
|
||||
if (filestream_flush_cb != NULL)
|
||||
if (filestream_flush_cb)
|
||||
output = filestream_flush_cb(stream->hfile);
|
||||
else
|
||||
output = retro_vfs_file_flush_impl((libretro_vfs_implementation_file*)stream->hfile);
|
||||
output = retro_vfs_file_flush_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile);
|
||||
|
||||
if (output == vfs_error_return_value)
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
return output;
|
||||
|
@ -385,7 +438,7 @@ int filestream_flush(RFILE *stream)
|
|||
|
||||
int filestream_delete(const char *path)
|
||||
{
|
||||
if (filestream_remove_cb != NULL)
|
||||
if (filestream_remove_cb)
|
||||
return filestream_remove_cb(path);
|
||||
|
||||
return retro_vfs_file_remove_impl(path);
|
||||
|
@ -393,7 +446,7 @@ int filestream_delete(const char *path)
|
|||
|
||||
int filestream_rename(const char *old_path, const char *new_path)
|
||||
{
|
||||
if (filestream_rename_cb != NULL)
|
||||
if (filestream_rename_cb)
|
||||
return filestream_rename_cb(old_path, new_path);
|
||||
|
||||
return retro_vfs_file_rename_impl(old_path, new_path);
|
||||
|
@ -401,22 +454,24 @@ int filestream_rename(const char *old_path, const char *new_path)
|
|||
|
||||
const char* filestream_get_path(RFILE *stream)
|
||||
{
|
||||
if (filestream_get_path_cb != NULL)
|
||||
if (filestream_get_path_cb)
|
||||
return filestream_get_path_cb(stream->hfile);
|
||||
|
||||
return retro_vfs_file_get_path_impl((libretro_vfs_implementation_file*)stream->hfile);
|
||||
return retro_vfs_file_get_path_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile);
|
||||
}
|
||||
|
||||
int64_t filestream_write(RFILE *stream, const void *s, int64_t len)
|
||||
{
|
||||
int64_t output;
|
||||
|
||||
if (filestream_write_cb != NULL)
|
||||
if (filestream_write_cb)
|
||||
output = filestream_write_cb(stream->hfile, s, len);
|
||||
else
|
||||
output = retro_vfs_file_write_impl((libretro_vfs_implementation_file*)stream->hfile, s, len);
|
||||
output = retro_vfs_file_write_impl(
|
||||
(libretro_vfs_implementation_file*)stream->hfile, s, len);
|
||||
|
||||
if (output == vfs_error_return_value)
|
||||
if (output == VFS_ERROR_RETURN_VALUE)
|
||||
stream->error_flag = true;
|
||||
|
||||
return output;
|
||||
|
@ -427,13 +482,16 @@ int filestream_putc(RFILE *stream, int c)
|
|||
char c_char = (char)c;
|
||||
if (!stream)
|
||||
return EOF;
|
||||
return filestream_write(stream, &c_char, 1)==1 ? (int)(unsigned char)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)
|
||||
{
|
||||
static char buffer[8 * 1024];
|
||||
int64_t num_chars = vsprintf(buffer, format, args);
|
||||
int64_t num_chars = vsnprintf(buffer, sizeof(buffer),
|
||||
format, args);
|
||||
|
||||
if (num_chars < 0)
|
||||
return -1;
|
||||
|
@ -465,10 +523,11 @@ int filestream_close(RFILE *stream)
|
|||
int output;
|
||||
struct retro_vfs_file_handle* fp = stream->hfile;
|
||||
|
||||
if (filestream_close_cb != NULL)
|
||||
if (filestream_close_cb)
|
||||
output = filestream_close_cb(fp);
|
||||
else
|
||||
output = retro_vfs_file_close_impl((libretro_vfs_implementation_file*)fp);
|
||||
output = retro_vfs_file_close_impl(
|
||||
(libretro_vfs_implementation_file*)fp);
|
||||
|
||||
if (output == 0)
|
||||
free(stream);
|
||||
|
@ -481,10 +540,11 @@ int filestream_close(RFILE *stream)
|
|||
* @path : path to file.
|
||||
* @buf : buffer to allocate and read the contents of the
|
||||
* file into. Needs to be freed manually.
|
||||
* @len : optional output integer containing bytes read.
|
||||
*
|
||||
* Read the contents of a file into @buf.
|
||||
*
|
||||
* Returns: number of items read, -1 on error.
|
||||
* Returns: non zero on success.
|
||||
*/
|
||||
int64_t filestream_read_file(const char *path, void **buf, int64_t *len)
|
||||
{
|
||||
|
@ -497,8 +557,8 @@ int64_t filestream_read_file(const char *path, void **buf, int64_t *len)
|
|||
|
||||
if (!file)
|
||||
{
|
||||
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
|
||||
goto error;
|
||||
*buf = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
content_buf_size = filestream_get_size(file);
|
||||
|
@ -515,12 +575,11 @@ int64_t filestream_read_file(const char *path, void **buf, int64_t *len)
|
|||
|
||||
ret = filestream_read(file, content_buf, (int64_t)content_buf_size);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to read %s: %s\n", path, strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
filestream_close(file);
|
||||
if (filestream_close(file) != 0)
|
||||
if (file)
|
||||
free(file);
|
||||
|
||||
*buf = content_buf;
|
||||
|
||||
|
@ -535,7 +594,8 @@ int64_t filestream_read_file(const char *path, void **buf, int64_t *len)
|
|||
|
||||
error:
|
||||
if (file)
|
||||
filestream_close(file);
|
||||
if (filestream_close(file) != 0)
|
||||
free(file);
|
||||
if (content_buf)
|
||||
free(content_buf);
|
||||
if (len)
|
||||
|
@ -564,7 +624,9 @@ bool filestream_write_file(const char *path, const void *data, int64_t size)
|
|||
return false;
|
||||
|
||||
ret = filestream_write(file, data, size);
|
||||
filestream_close(file);
|
||||
if (filestream_close(file) != 0)
|
||||
if (file)
|
||||
free(file);
|
||||
|
||||
if (ret != size)
|
||||
return false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue