Update libretro API

This commit is contained in:
twinaphex 2017-12-16 14:12:38 +01:00
parent 2974258589
commit 6622cb0810
9 changed files with 115 additions and 38 deletions

View File

@ -967,6 +967,23 @@ enum retro_mod
* core supports VFS before it starts handing out paths. * core supports VFS before it starts handing out paths.
* It is recomended to do so in retro_set_environment */ * It is recomended to do so in retro_set_environment */
/* VFS functionality */
/* File paths:
* File paths passed as parameters when using this api shall be well formed unix-style,
* using "/" (unquoted forward slash) as directory separator regardless of the platform's native separator.
* Paths shall also include at least one forward slash ("game.bin" is an invalid path, use "./game.bin" instead).
* Other than the directory separator, cores shall not make assumptions about path format:
* "C:/path/game.bin", "http://example.com/game.bin", "#game/game.bin", "./game.bin" (without quotes) are all valid paths.
* Cores may replace the basename or remove path components from the end, and/or add new components;
* however, cores shall not append "./", "../" or multiple consecutive forward slashes ("//") to paths they request to front end.
* The frontend is encouraged to make such paths work as well as it can, but is allowed to give up if the core alters paths too much.
* Frontends are encouraged, but not required, to support native file system paths (modulo replacing the directory separator, if applicable).
* Cores are allowed to try using them, but must remain functional if the front rejects such requests.
* Cores are encouraged to use the libretro-common filestream functions for file I/O,
* as they seamlessly integrate with VFS, deal with directory separator replacement as appropriate
* and provide platform-specific fallbacks in cases where front ends do not support VFS. */
/* Opaque file handle /* Opaque file handle
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */
struct retro_vfs_file_handle; struct retro_vfs_file_handle;
@ -985,6 +1002,11 @@ struct retro_vfs_file_handle;
/* Indicate that the file will be accessed many times. The frontend should aggressively cache everything. */ /* Indicate that the file will be accessed many times. The frontend should aggressively cache everything. */
#define RETRO_VFS_FILE_ACCESS_HINT_FREQUENT_ACCESS (1 << 0) #define RETRO_VFS_FILE_ACCESS_HINT_FREQUENT_ACCESS (1 << 0)
/* Seek positions */
#define RETRO_VFS_SEEK_POSITION_START 0
#define RETRO_VFS_SEEK_POSITION_CURRENT 1
#define RETRO_VFS_SEEK_POSITION_END 2
/* Get path from opaque handle. Returns the exact same path passed to file_open when getting the handle /* Get path from opaque handle. Returns the exact same path passed to file_open when getting the handle
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */
typedef const char *(RETRO_CALLCONV *retro_vfs_get_path_t)(struct retro_vfs_file_handle *stream); typedef const char *(RETRO_CALLCONV *retro_vfs_get_path_t)(struct retro_vfs_file_handle *stream);
@ -1009,7 +1031,7 @@ typedef int64_t (RETRO_CALLCONV *retro_vfs_tell_t)(struct retro_vfs_file_handle
/* Set the current read/write position for the file. Returns the new position, -1 for error. /* Set the current read/write position for the file. Returns the new position, -1 for error.
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */
typedef int64_t (RETRO_CALLCONV *retro_vfs_seek_t)(struct retro_vfs_file_handle *stream, int64_t offset, int whence); typedef int64_t (RETRO_CALLCONV *retro_vfs_seek_t)(struct retro_vfs_file_handle *stream, int64_t offset, int seek_position);
/* Read data from a file. Returns the number of bytes read, or -1 for error. /* Read data from a file. Returns the number of bytes read, or -1 for error.
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */

View File

@ -60,7 +60,7 @@ int64_t filestream_get_size(RFILE *stream);
**/ **/
RFILE *filestream_open(const char *path, unsigned mode, unsigned hints); RFILE *filestream_open(const char *path, unsigned mode, unsigned hints);
ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence); ssize_t filestream_seek(RFILE *stream, ssize_t offset, int seek_position);
ssize_t filestream_read(RFILE *stream, void *data, int64_t len); ssize_t filestream_read(RFILE *stream, void *data, int64_t len);

View File

@ -48,7 +48,7 @@ int64_t retro_vfs_file_size_impl(libretro_vfs_implementation_file *stream);
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 whence); int64_t retro_vfs_file_seek_impl(libretro_vfs_implementation_file *stream, int64_t offset, int seek_position);
int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, void *s, uint64_t len); int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, void *s, uint64_t len);

View File

@ -401,17 +401,17 @@ int chdstream_seek(chdstream_t *stream, ssize_t offset, int whence)
switch (whence) switch (whence)
{ {
case SEEK_SET: case SEEK_SET:
new_offset = offset; new_offset = offset;
break; break;
case SEEK_CUR: case SEEK_CUR:
new_offset = stream->offset + offset; new_offset = stream->offset + offset;
break; break;
case SEEK_END: case SEEK_END:
new_offset = stream->track_end + offset; new_offset = stream->track_end + offset;
break; break;
default: default:
return -1; return -1;
} }
if (new_offset < 0) if (new_offset < 0)

View File

@ -188,14 +188,14 @@ int filestream_getc(RFILE *stream)
return EOF; return EOF;
} }
ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence) ssize_t filestream_seek(RFILE *stream, ssize_t offset, int seek_position)
{ {
int64_t output; int64_t output;
if (filestream_seek_cb != NULL) if (filestream_seek_cb != NULL)
output = filestream_seek_cb(stream->hfile, offset, whence); output = filestream_seek_cb(stream->hfile, offset, seek_position);
else else
output = retro_vfs_file_seek_impl((libretro_vfs_implementation_file*)stream->hfile, offset, whence); 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->error_flag = true;
@ -233,7 +233,7 @@ void filestream_rewind(RFILE *stream)
{ {
if (!stream) if (!stream)
return; return;
filestream_seek(stream, 0L, SEEK_SET); filestream_seek(stream, 0L, RETRO_VFS_SEEK_POSITION_START);
stream->error_flag = false; stream->error_flag = false;
} }

View File

@ -53,7 +53,21 @@ long rftell(RFILE* stream)
int rfseek(RFILE* stream, long offset, int origin) int rfseek(RFILE* stream, long offset, int origin)
{ {
return filestream_seek(stream, offset, origin); int seek_position = -1;
switch (origin)
{
case SEEK_SET:
seek_position = RETRO_VFS_SEEK_POSITION_START;
break;
case SEEK_CUR:
seek_position = RETRO_VFS_SEEK_POSITION_CURRENT;
break;
case SEEK_END:
seek_position = RETRO_VFS_SEEK_POSITION_END;
break;
}
return filestream_seek(stream, offset, seek_position);
} }
size_t rfread(void* buffer, size_t rfread(void* buffer,

View File

@ -223,7 +223,23 @@ int intfstream_seek(intfstream_internal_t *intf, int offset, int whence)
switch (intf->type) switch (intf->type)
{ {
case INTFSTREAM_FILE: case INTFSTREAM_FILE:
return (int)filestream_seek(intf->file.fp, (int)offset, whence); {
int seek_position = 0;
switch (whence)
{
case SEEK_SET:
seek_position = RETRO_VFS_SEEK_POSITION_START;
break;
case SEEK_CUR:
seek_position = RETRO_VFS_SEEK_POSITION_CURRENT;
break;
case SEEK_END:
seek_position = RETRO_VFS_SEEK_POSITION_END;
break;
}
return (int)filestream_seek(intf->file.fp, (int)offset,
seek_position);
}
case INTFSTREAM_MEMORY: case INTFSTREAM_MEMORY:
return (int)memstream_seek(intf->memory.fp, offset, whence); return (int)memstream_seek(intf->memory.fp, offset, whence);
case INTFSTREAM_CHD: case INTFSTREAM_CHD:

View File

@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
@ -376,9 +377,23 @@ int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream)
return 0; return 0;
} }
int64_t retro_vfs_file_seek_impl(libretro_vfs_implementation_file *stream, int64_t offset, int whence) int64_t retro_vfs_file_seek_impl(libretro_vfs_implementation_file *stream, int64_t offset, int seek_position)
{ {
return retro_vfs_file_seek_internal(stream, offset, whence); int whence = -1;
switch (seek_position)
{
case RETRO_VFS_SEEK_POSITION_START:
whence = SEEK_SET;
break;
case RETRO_VFS_SEEK_POSITION_CURRENT:
whence = SEEK_CUR;
break;
case RETRO_VFS_SEEK_POSITION_END:
whence = SEEK_END;
break;
}
return retro_vfs_file_seek_internal(stream, offset, whence);
} }
int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, void *s, uint64_t len) int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, void *s, uint64_t len)

View File

@ -143,14 +143,15 @@ int libretrodb_create(RFILE *fd, libretrodb_value_provider value_provider,
struct rmsgpack_dom_value item; struct rmsgpack_dom_value item;
uint64_t item_count = 0; uint64_t item_count = 0;
libretrodb_header_t header = {{0}}; libretrodb_header_t header = {{0}};
ssize_t root = filestream_seek(fd, 0, SEEK_CUR); ssize_t root = filestream_seek(fd, 0, RETRO_VFS_SEEK_POSITION_CURRENT);
memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1); memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1);
/* We write the header in the end because we need to know the size of /* We write the header in the end because we need to know the size of
* the db first */ * the db first */
filestream_seek(fd, sizeof(libretrodb_header_t), SEEK_CUR); filestream_seek(fd, sizeof(libretrodb_header_t),
RETRO_VFS_SEEK_POSITION_CURRENT);
item.type = RDT_NULL; item.type = RDT_NULL;
while ((rv = value_provider(ctx, &item)) == 0) while ((rv = value_provider(ctx, &item)) == 0)
@ -172,10 +173,11 @@ int libretrodb_create(RFILE *fd, libretrodb_value_provider value_provider,
if ((rv = rmsgpack_dom_write(fd, &sentinal)) < 0) if ((rv = rmsgpack_dom_write(fd, &sentinal)) < 0)
goto clean; goto clean;
header.metadata_offset = swap_if_little64(filestream_seek(fd, 0, SEEK_CUR)); header.metadata_offset = swap_if_little64(filestream_seek(
fd, 0, RETRO_VFS_SEEK_POSITION_CURRENT));
md.count = item_count; md.count = item_count;
libretrodb_write_metadata(fd, &md); libretrodb_write_metadata(fd, &md);
filestream_seek(fd, root, SEEK_SET); filestream_seek(fd, root, RETRO_VFS_SEEK_POSITION_START);
filestream_write(fd, &header, sizeof(header)); filestream_write(fd, &header, sizeof(header));
clean: clean:
rmsgpack_dom_value_free(&item); rmsgpack_dom_value_free(&item);
@ -228,7 +230,7 @@ int libretrodb_open(const char *path, libretrodb_t *db)
free(db->path); free(db->path);
db->path = strdup(path); db->path = strdup(path);
db->root = filestream_seek(fd, 0, SEEK_CUR); db->root = filestream_seek(fd, 0, RETRO_VFS_SEEK_POSITION_CURRENT);
if ((rv = (int)filestream_read(fd, &header, sizeof(header))) == -1) if ((rv = (int)filestream_read(fd, &header, sizeof(header))) == -1)
{ {
@ -243,7 +245,8 @@ int libretrodb_open(const char *path, libretrodb_t *db)
} }
header.metadata_offset = swap_if_little64(header.metadata_offset); header.metadata_offset = swap_if_little64(header.metadata_offset);
filestream_seek(fd, (ssize_t)header.metadata_offset, SEEK_SET); filestream_seek(fd, (ssize_t)header.metadata_offset,
RETRO_VFS_SEEK_POSITION_START);
if (libretrodb_read_metadata(fd, &md) < 0) if (libretrodb_read_metadata(fd, &md) < 0)
{ {
@ -251,9 +254,10 @@ int libretrodb_open(const char *path, libretrodb_t *db)
goto error; goto error;
} }
db->count = md.count; db->count = md.count;
db->first_index_offset = filestream_seek(fd, 0, SEEK_CUR); db->first_index_offset = filestream_seek(fd, 0,
db->fd = fd; RETRO_VFS_SEEK_POSITION_CURRENT);
db->fd = fd;
return 0; return 0;
error: error:
@ -265,9 +269,11 @@ error:
static int libretrodb_find_index(libretrodb_t *db, const char *index_name, static int libretrodb_find_index(libretrodb_t *db, const char *index_name,
libretrodb_index_t *idx) libretrodb_index_t *idx)
{ {
ssize_t eof = filestream_seek(db->fd, 0, SEEK_END); ssize_t eof = filestream_seek(db->fd, 0,
RETRO_VFS_SEEK_POSITION_END);
ssize_t offset = filestream_seek(db->fd, ssize_t offset = filestream_seek(db->fd,
(ssize_t)db->first_index_offset, SEEK_SET); (ssize_t)db->first_index_offset,
RETRO_VFS_SEEK_POSITION_START);
while (offset < eof) while (offset < eof)
{ {
@ -276,7 +282,8 @@ static int libretrodb_find_index(libretrodb_t *db, const char *index_name,
if (strncmp(index_name, idx->name, strlen(idx->name)) == 0) if (strncmp(index_name, idx->name, strlen(idx->name)) == 0)
return 0; return 0;
offset = filestream_seek(db->fd, (ssize_t)idx->next, SEEK_CUR); offset = filestream_seek(db->fd, (ssize_t)idx->next,
RETRO_VFS_SEEK_POSITION_CURRENT);
} }
return -1; return -1;
@ -341,7 +348,8 @@ int libretrodb_find_entry(libretrodb_t *db, const char *index_name,
free(buff); free(buff);
if (rv == 0) if (rv == 0)
filestream_seek(db->fd, (ssize_t)offset, SEEK_SET); filestream_seek(db->fd, (ssize_t)offset,
RETRO_VFS_SEEK_POSITION_START);
return rmsgpack_dom_read(db->fd, out); return rmsgpack_dom_read(db->fd, out);
} }
@ -359,7 +367,7 @@ int libretrodb_cursor_reset(libretrodb_cursor_t *cursor)
cursor->eof = 0; cursor->eof = 0;
return (int)filestream_seek(cursor->fd, return (int)filestream_seek(cursor->fd,
(ssize_t)(cursor->db->root + sizeof(libretrodb_header_t)), (ssize_t)(cursor->db->root + sizeof(libretrodb_header_t)),
SEEK_SET); RETRO_VFS_SEEK_POSITION_START);
} }
int libretrodb_cursor_read_item(libretrodb_cursor_t *cursor, int libretrodb_cursor_read_item(libretrodb_cursor_t *cursor,
@ -466,7 +474,8 @@ static int node_iter(void *value, void *ctx)
static uint64_t libretrodb_tell(libretrodb_t *db) static uint64_t libretrodb_tell(libretrodb_t *db)
{ {
return filestream_seek(db->fd, 0, SEEK_CUR); return filestream_seek(db->fd, 0,
RETRO_VFS_SEEK_POSITION_CURRENT);
} }
static int node_compare(const void *a, const void *b, void *ctx) static int node_compare(const void *a, const void *b, void *ctx)
@ -557,7 +566,8 @@ int libretrodb_create_index(libretrodb_t *db,
item_loc = libretrodb_tell(db); item_loc = libretrodb_tell(db);
} }
idx_header_offset = filestream_seek(db->fd, 0, SEEK_END); idx_header_offset = filestream_seek(db->fd, 0,
RETRO_VFS_SEEK_POSITION_END);
(void)idx_header_offset; (void)idx_header_offset;