update libretro-common

This commit is contained in:
zeromus 2016-04-22 00:34:34 +00:00
parent 3685c6e1f6
commit b0f4989230
17 changed files with 723 additions and 144 deletions

View File

@ -216,9 +216,6 @@ static int file_archive_get_file_list_cb(
(void)csize; (void)csize;
(void)size; (void)size;
(void)checksum; (void)checksum;
(void)valid_exts;
(void)file_ext;
(void)ext_list;
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
@ -538,10 +535,8 @@ static bool file_archive_parse_file(const char *file, const char *valid_exts,
for (;;) for (;;)
{ {
int ret = file_archive_parse_file_iterate(&state, &returnerr, file, if (file_archive_parse_file_iterate(&state, &returnerr, file,
valid_exts, file_cb, userdata); valid_exts, file_cb, userdata) != 0)
if (ret != 0)
break; break;
} }
@ -656,7 +651,7 @@ bool file_archive_perform_mode(const char *path, const char *valid_exts,
{ {
case ZLIB_MODE_UNCOMPRESSED: case ZLIB_MODE_UNCOMPRESSED:
if (!filestream_write_file(path, cdata, size)) if (!filestream_write_file(path, cdata, size))
return false; goto error;
break; break;
case ZLIB_MODE_DEFLATE: case ZLIB_MODE_DEFLATE:
@ -667,7 +662,7 @@ bool file_archive_perform_mode(const char *path, const char *valid_exts,
if (!handle.backend->stream_decompress_data_to_file_init(&handle, if (!handle.backend->stream_decompress_data_to_file_init(&handle,
cdata, csize, size)) cdata, csize, size))
return false; goto error;
do{ do{
ret = handle.backend->stream_decompress_data_to_file_iterate( ret = handle.backend->stream_decompress_data_to_file_iterate(
@ -677,14 +672,17 @@ bool file_archive_perform_mode(const char *path, const char *valid_exts,
if (!file_archive_decompress_data_to_file(&handle, if (!file_archive_decompress_data_to_file(&handle,
ret, path, valid_exts, ret, path, valid_exts,
cdata, csize, size, crc32)) cdata, csize, size, crc32))
return false; goto error;
} }
break; break;
default: default:
return false; goto error;
} }
return true; return true;
error:
return false;
} }
const struct file_archive_file_backend *file_archive_get_default_file_backend(void) const struct file_archive_file_backend *file_archive_get_default_file_backend(void)

View File

@ -167,7 +167,7 @@ static int zlib_stream_decompress_data_to_file_iterate(void *data)
z_stream *stream = (z_stream*)data; z_stream *stream = (z_stream*)data;
if (!stream) if (!stream)
return -1; goto error;
zstatus = inflate(stream, Z_NO_FLUSH); zstatus = inflate(stream, Z_NO_FLUSH);
@ -175,9 +175,12 @@ static int zlib_stream_decompress_data_to_file_iterate(void *data)
return 1; return 1;
if (zstatus != Z_OK && zstatus != Z_BUF_ERROR) if (zstatus != Z_OK && zstatus != Z_BUF_ERROR)
return -1; goto error;
return 0; return 0;
error:
return -1;
} }
static void zlib_stream_compress_init(void *data, int level) static void zlib_stream_compress_init(void *data, int level)

View File

@ -421,6 +421,15 @@ void rglLinkProgram(GLuint program)
glLinkProgram(program); glLinkProgram(program);
} }
void rglFramebufferTexture(GLenum target, GLenum attachment,
GLuint texture, GLint level)
{
#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES32)
#else
glFramebufferTexture(target, attachment, texture, level);
#endif
}
void rglFramebufferTexture2D(GLenum target, GLenum attachment, void rglFramebufferTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level) GLenum textarget, GLuint texture, GLint level)
{ {
@ -446,7 +455,7 @@ void rglFramebufferRenderbuffer(GLenum target, GLenum attachment,
glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
} }
void rglDeleteFramebuffers(GLsizei n, GLuint *framebuffers) void rglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
{ {
glDeleteFramebuffers(n, framebuffers); glDeleteFramebuffers(n, framebuffers);
} }
@ -703,6 +712,12 @@ void rglUniform4fv(GLint location, GLsizei count, const GLfloat *value)
glUniform4fv(location, count, value); glUniform4fv(location, count, value);
} }
void rglTexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat,
GLsizei width, GLsizei height)
{
glTexStorage2D(target, levels, internalFormat, width, height);
}
void rglPolygonOffset(GLfloat factor, GLfloat units) void rglPolygonOffset(GLfloat factor, GLfloat units)
{ {
glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
@ -712,6 +727,41 @@ void rglPolygonOffset(GLfloat factor, GLfloat units)
gl_state.polygonoffset.units = units; gl_state.polygonoffset.units = units;
} }
void rglDrawBuffers(GLsizei n, const GLenum *bufs)
{
#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES3) && !defined(HAVE_OPENGLES31)
#else
glDrawBuffers(n, bufs);
#endif
}
void rglBlendEquation(GLenum mode)
{
glBlendEquation(mode);
}
void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
glBlendColor(red, green, blue, alpha);
}
void rglBindVertexArray(GLuint array)
{
#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES3) && !defined(HAVE_OPENGLES31)
#else
glBindVertexArray(array);
#endif
}
void rglGenVertexArrays(GLsizei n, GLuint *arrays)
{
#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES3) && !defined(HAVE_OPENGLES31)
#else
glGenVertexArrays(n, arrays);
#endif
}
/* GLSM-side */ /* GLSM-side */
static void glsm_state_setup(void) static void glsm_state_setup(void)

View File

@ -41,6 +41,7 @@ extern "C" {
#define glCompressedTexImage2D rglCompressedTexImage2D #define glCompressedTexImage2D rglCompressedTexImage2D
#define glBindTexture rglBindTexture #define glBindTexture rglBindTexture
#define glActiveTexture rglActiveTexture #define glActiveTexture rglActiveTexture
#define glFramebufferTexture rglFramebufferTexture
#define glFramebufferTexture2D rglFramebufferTexture2D #define glFramebufferTexture2D rglFramebufferTexture2D
#define glFramebufferRenderbuffer rglFramebufferRenderbuffer #define glFramebufferRenderbuffer rglFramebufferRenderbuffer
#define glDeleteFramebuffers rglDeleteFramebuffers #define glDeleteFramebuffers rglDeleteFramebuffers
@ -112,22 +113,35 @@ extern "C" {
#define glReadBuffer rglReadBuffer #define glReadBuffer rglReadBuffer
#define glUniformMatrix4fv rglUniformMatrix4fv #define glUniformMatrix4fv rglUniformMatrix4fv
#define glGetAttribLocation rglGetAttribLocation #define glGetAttribLocation rglGetAttribLocation
#define glTexStorage2D rglTexStorage2D
#define glDrawBuffers rglDrawBuffers
#define glGenVertexArrays rglGenVertexArrays
#define glBindVertexArray rglBindVertexArray
#define glBlendEquation rglBlendEquation
#define glBlendColor rglBlendColor
void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
void rglBlendEquation(GLenum mode);
void rglGenVertexArrays(GLsizei n, GLuint *arrays);
void rglReadBuffer(GLenum mode); void rglReadBuffer(GLenum mode);
void rglPixelStorei(GLenum pname, GLint param); void rglPixelStorei(GLenum pname, GLint param);
void rglTexCoord2f(GLfloat s, GLfloat t); void rglTexCoord2f(GLfloat s, GLfloat t);
void rglDrawElements(GLenum mode, GLsizei count, GLenum type, void rglDrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid * indices); const GLvoid * indices);
void rglTexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat,
GLsizei width, GLsizei height);
void rglCompressedTexImage2D(GLenum target, GLint level, void rglCompressedTexImage2D(GLenum target, GLint level,
GLenum internalformat, GLsizei width, GLsizei height, GLenum internalformat, GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, const GLvoid *data); GLint border, GLsizei imageSize, const GLvoid *data);
void glBindTexture(GLenum target, GLuint texture); void glBindTexture(GLenum target, GLuint texture);
void glActiveTexture(GLenum texture); void glActiveTexture(GLenum texture);
void rglFramebufferTexture(GLenum target, GLenum attachment,
GLuint texture, GLint level);
void rglFramebufferTexture2D(GLenum target, GLenum attachment, void rglFramebufferTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level); GLenum textarget, GLuint texture, GLint level);
void rglFramebufferRenderbuffer(GLenum target, GLenum attachment, void rglFramebufferRenderbuffer(GLenum target, GLenum attachment,
GLenum renderbuffertarget, GLuint renderbuffer); GLenum renderbuffertarget, GLuint renderbuffer);
void rglDeleteFramebuffers(GLsizei n, GLuint *framebuffers); void rglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
void rglRenderbufferStorage(GLenum target, GLenum internalFormat, void rglRenderbufferStorage(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height); GLsizei width, GLsizei height);
void rglDeleteTextures(GLsizei n, const GLuint *textures); void rglDeleteTextures(GLsizei n, const GLuint *textures);
@ -214,6 +228,8 @@ void rglDetachShader(GLuint program, GLuint shader);
void rglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, void rglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value); const GLfloat *value);
GLint rglGetAttribLocation(GLuint program, const GLchar *name); GLint rglGetAttribLocation(GLuint program, const GLchar *name);
void rglDrawBuffers(GLsizei n, const GLenum *bufs);
void rglBindVertexArray(GLuint array);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -65,6 +65,11 @@ bool file_list_append(file_list_t *userdata, const char *path,
const char *label, unsigned type, size_t current_directory_ptr, const char *label, unsigned type, size_t current_directory_ptr,
size_t entry_index); size_t entry_index);
bool file_list_prepend(file_list_t *list,
const char *path, const char *label,
unsigned type, size_t directory_ptr,
size_t entry_idx);
void file_list_pop(file_list_t *list, size_t *directory_ptr); void file_list_pop(file_list_t *list, size_t *directory_ptr);
void file_list_clear(file_list_t *list); void file_list_clear(file_list_t *list);

View File

@ -23,6 +23,10 @@
#ifndef __LIBRETRO_SDK_SEMAPHORE_H #ifndef __LIBRETRO_SDK_SEMAPHORE_H
#define __LIBRETRO_SDK_SEMAPHORE_H #define __LIBRETRO_SDK_SEMAPHORE_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ssem ssem_t; typedef struct ssem ssem_t;
/** /**
@ -37,8 +41,14 @@ ssem_t *ssem_new(int value);
void ssem_free(ssem_t *semaphore); void ssem_free(ssem_t *semaphore);
int ssem_get(ssem_t *semaphore);
void ssem_wait(ssem_t *semaphore); void ssem_wait(ssem_t *semaphore);
void ssem_signal(ssem_t *semaphore); void ssem_signal(ssem_t *semaphore);
#ifdef __cplusplus
}
#endif
#endif /* __LIBRETRO_SDK_SEMAPHORE_H */ #endif /* __LIBRETRO_SDK_SEMAPHORE_H */

View File

@ -66,6 +66,8 @@ int filestream_read_file(const char *path, void **buf, ssize_t *len);
bool filestream_write_file(const char *path, const void *data, ssize_t size); bool filestream_write_file(const char *path, const void *data, ssize_t size);
int filestream_putc(RFILE *stream, int c);
int filestream_get_fd(RFILE *stream); int filestream_get_fd(RFILE *stream);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,85 @@
/* Copyright (C) 2010-2015 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (interface_stream.h).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _LIBRETRO_SDK_INTERFACE_STREAM_H
#define _LIBRETRO_SDK_INTERFACE_STREAM_H
#include <stdint.h>
#include <stddef.h>
#include <boolean.h>
enum intfstream_type
{
INTFSTREAM_FILE = 0,
INTFSTREAM_MEMORY
};
typedef struct intfstream_internal intfstream_internal_t;
typedef struct intfstream intfstream_t;
typedef struct intfstream_info
{
struct
{
struct
{
uint8_t *data;
unsigned size;
} buf;
bool writable;
} memory;
enum intfstream_type type;
} intfstream_info_t;
void *intfstream_init(intfstream_info_t *info);
bool intfstream_resize(intfstream_internal_t *intf,
intfstream_info_t *info);
bool intfstream_open(intfstream_internal_t *intf,
const char *path, unsigned mode, ssize_t len);
ssize_t intfstream_read(intfstream_internal_t *intf,
void *s, size_t len);
ssize_t intfstream_write(intfstream_internal_t *intf,
const void *s, size_t len);
char *intfstream_gets(intfstream_internal_t *intf,
char *buffer, size_t len);
int intfstream_getc(intfstream_internal_t *intf);
int intfstream_seek(intfstream_internal_t *intf,
int offset, int whence);
void intfstream_rewind(intfstream_internal_t *intf);
int intfstream_tell(intfstream_internal_t *intf);
void intfstream_putc(intfstream_internal_t *intf, int c);
int intfstream_close(intfstream_internal_t *intf);
#endif

View File

@ -28,7 +28,7 @@
typedef struct memstream memstream_t; typedef struct memstream memstream_t;
memstream_t *memstream_open(void); memstream_t *memstream_open(unsigned writing);
void memstream_close(memstream_t *stream); void memstream_close(memstream_t *stream);
@ -38,10 +38,14 @@ size_t memstream_write(memstream_t *stream, const void *data, size_t bytes);
int memstream_getc(memstream_t *stream); int memstream_getc(memstream_t *stream);
void memstream_putc(memstream_t *stream, int c);
char *memstream_gets(memstream_t *stream, char *buffer, size_t len); char *memstream_gets(memstream_t *stream, char *buffer, size_t len);
size_t memstream_pos(memstream_t *stream); size_t memstream_pos(memstream_t *stream);
void memstream_rewind(memstream_t *stream);
int memstream_seek(memstream_t *stream, int offset, int whence); int memstream_seek(memstream_t *stream, int offset, int whence);
void memstream_set_buffer(uint8_t *buffer, size_t size); void memstream_set_buffer(uint8_t *buffer, size_t size);

View File

@ -24,7 +24,7 @@ static void (*co_swap)(cothread_t, cothread_t) = 0;
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
//ABI: Win64 /* ABI: Win64 */
static unsigned char co_swap_function[] = { static unsigned char co_swap_function[] = {
0x48, 0x89, 0x22, /* mov [rdx],rsp */ 0x48, 0x89, 0x22, /* mov [rdx],rsp */
0x48, 0x8b, 0x21, /* mov rsp,[rcx] */ 0x48, 0x8b, 0x21, /* mov rsp,[rcx] */
@ -81,7 +81,7 @@ void co_init(void)
sizeof(co_swap_function), PAGE_EXECUTE_READWRITE, &old_privileges); sizeof(co_swap_function), PAGE_EXECUTE_READWRITE, &old_privileges);
} }
#else #else
//ABI: SystemV /* ABI: SystemV */
#ifndef CO_USE_INLINE_ASM #ifndef CO_USE_INLINE_ASM
static unsigned char co_swap_function[] = { static unsigned char co_swap_function[] = {
0x48, 0x89, 0x26, /* mov [rsi],rsp */ 0x48, 0x89, 0x26, /* mov [rsi],rsp */

View File

@ -59,6 +59,49 @@ static bool file_list_capacity(file_list_t *list, size_t cap)
return true; return true;
} }
bool file_list_prepend(file_list_t *list,
const char *path, const char *label,
unsigned type, size_t directory_ptr,
size_t entry_idx)
{
unsigned i;
if (list->size >= list->capacity &&
!file_list_capacity(list, list->capacity * 2 + 1))
return false;
list->size++;
for (i = list->size -1; i > 0; i--)
{
struct item_file *copy = calloc(1, sizeof(struct item_file));
memcpy(copy, &list->list[i-1], sizeof(struct item_file));
memcpy(&list->list[i-1], &list->list[i], sizeof(struct item_file));
memcpy(&list->list[i], copy, sizeof(struct item_file));
free(copy);
}
memset(&list->list[0], 0, sizeof(file_list_t));
list->list[0].label = NULL;
list->list[0].path = NULL;
list->list[0].alt = NULL;
list->list[0].userdata = NULL;
list->list[0].actiondata = NULL;
list->list[0].type = type;
list->list[0].directory_ptr = directory_ptr;
list->list[0].entry_idx = entry_idx;
if (label)
list->list[0].label = strdup(label);
if (path)
list->list[0].path = strdup(path);
return true;
}
bool file_list_append(file_list_t *list, bool file_list_append(file_list_t *list,
const char *path, const char *label, const char *path, const char *label,
unsigned type, size_t directory_ptr, unsigned type, size_t directory_ptr,

View File

@ -175,12 +175,9 @@ void msg_queue_clear(msg_queue_t *queue)
**/ **/
const char *msg_queue_pull(msg_queue_t *queue) const char *msg_queue_pull(msg_queue_t *queue)
{ {
struct queue_elem *front = NULL, *last = NULL, struct queue_elem *front = NULL, *last = NULL;
*parent = NULL, *child = NULL;
size_t tmp_ptr = 1; size_t tmp_ptr = 1;
(void)parent;
(void)child;
(void)tmp_ptr; (void)tmp_ptr;
/* Nothing in queue. */ /* Nothing in queue. */
@ -203,6 +200,8 @@ const char *msg_queue_pull(msg_queue_t *queue)
for (;;) for (;;)
{ {
struct queue_elem *parent = NULL;
struct queue_elem *child = NULL;
size_t switch_index = tmp_ptr; size_t switch_index = tmp_ptr;
bool left = (tmp_ptr * 2 <= queue->ptr) bool left = (tmp_ptr * 2 <= queue->ptr)
&& (queue->elems[tmp_ptr] < queue->elems[tmp_ptr * 2]); && (queue->elems[tmp_ptr] < queue->elems[tmp_ptr * 2]);

View File

@ -20,6 +20,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifdef __unix__
#define _POSIX_C_SOURCE 199309
#endif
#include <stdlib.h> #include <stdlib.h>
#include <rthreads/rthreads.h> #include <rthreads/rthreads.h>
@ -73,6 +77,21 @@ void ssem_free(ssem_t *semaphore)
free((void*)semaphore); free((void*)semaphore);
} }
int ssem_get(ssem_t *semaphore)
{
int val = 0;
if (!semaphore)
return 0;
slock_lock(semaphore->mutex);
val = semaphore->value;
slock_unlock(semaphore->mutex);
return val;
}
void ssem_wait(ssem_t *semaphore) void ssem_wait(ssem_t *semaphore)
{ {
if (!semaphore) if (!semaphore)

View File

@ -20,6 +20,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifdef __unix__
#define _POSIX_C_SOURCE 199309
#endif
#include <stdlib.h> #include <stdlib.h>
#include <boolean.h> #include <boolean.h>

View File

@ -66,10 +66,6 @@
#include <streams/file_stream.h> #include <streams/file_stream.h>
#include <memmap.h> #include <memmap.h>
#if 1
#define HAVE_BUFFERED_IO 1
#endif
struct RFILE struct RFILE
{ {
unsigned hints; unsigned hints;
@ -78,6 +74,9 @@ struct RFILE
#elif defined(__CELLOS_LV2__) #elif defined(__CELLOS_LV2__)
int fd; int fd;
#else #else
#define HAVE_BUFFERED_IO 1
#if defined(HAVE_BUFFERED_IO) #if defined(HAVE_BUFFERED_IO)
FILE *fp; FILE *fp;
#endif #endif
@ -94,28 +93,25 @@ int filestream_get_fd(RFILE *stream)
{ {
if (!stream) if (!stream)
return -1; return -1;
#if defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__)
return stream->fd;
#else
#if defined(HAVE_BUFFERED_IO) #if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
return fileno(stream->fp); return fileno(stream->fp);
#endif #endif
return stream->fd; return stream->fd;
#endif
} }
RFILE *filestream_open(const char *path, unsigned mode, ssize_t len) RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
{ {
int flags = 0; int flags = 0;
int mode_int = 0; int mode_int = 0;
#if defined(HAVE_BUFFERED_IO)
const char *mode_str = NULL; const char *mode_str = NULL;
#endif
RFILE *stream = (RFILE*)calloc(1, sizeof(*stream)); RFILE *stream = (RFILE*)calloc(1, sizeof(*stream));
if (!stream) if (!stream)
return NULL; return NULL;
(void)mode_str;
(void)mode_int; (void)mode_int;
(void)flags; (void)flags;
@ -220,7 +216,8 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
filestream_rewind(stream); filestream_rewind(stream);
stream->mapped = (uint8_t*)mmap((void*)0, stream->mapsize, PROT_READ, MAP_SHARED, stream->fd, 0); stream->mapped = (uint8_t*)mmap((void*)0,
stream->mapsize, PROT_READ, MAP_SHARED, stream->fd, 0);
if (stream->mapped == MAP_FAILED) if (stream->mapped == MAP_FAILED)
stream->hints &= ~RFILE_HINT_MMAP; stream->hints &= ~RFILE_HINT_MMAP;
@ -243,28 +240,25 @@ error:
ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence) ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence)
{ {
int ret = 0; #if defined(__CELLOS_LV2__)
uint64_t pos = 0;
#endif
if (!stream) if (!stream)
return -1; goto error;
(void)ret;
#if defined(VITA) || defined(PSP) #if defined(VITA) || defined(PSP)
ret = sceIoLseek(stream->fd, (SceOff)offset, whence); if (sceIoLseek(stream->fd, (SceOff)offset, whence) == -1)
if (ret == -1) goto error;
return -1;
return 0;
#elif defined(__CELLOS_LV2__) #elif defined(__CELLOS_LV2__)
uint64_t pos = 0;
if (cellFsLseek(stream->fd, offset, whence, &pos) != CELL_FS_SUCCEEDED) if (cellFsLseek(stream->fd, offset, whence, &pos) != CELL_FS_SUCCEEDED)
return -1; goto error;
return 0;
#else #else
#if defined(HAVE_BUFFERED_IO) #if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
return fseek(stream->fp, (long)offset, whence); return fseek(stream->fp, (long)offset, whence);
else
#endif #endif
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
/* Need to check stream->mapped because this function is /* Need to check stream->mapped because this function is
* called in filestream_open() */ * called in filestream_open() */
@ -276,7 +270,7 @@ ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence)
{ {
case SEEK_SET: case SEEK_SET:
if (offset < 0) if (offset < 0)
return -1; goto error;
stream->mappos = offset; stream->mappos = offset;
break; break;
@ -284,57 +278,65 @@ ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence)
case SEEK_CUR: case SEEK_CUR:
if ((offset < 0 && stream->mappos + offset > stream->mappos) || if ((offset < 0 && stream->mappos + offset > stream->mappos) ||
(offset > 0 && stream->mappos + offset < stream->mappos)) (offset > 0 && stream->mappos + offset < stream->mappos))
return -1; goto error;
stream->mappos += offset; stream->mappos += offset;
break; break;
case SEEK_END: case SEEK_END:
if (stream->mapsize + offset < stream->mapsize) if (stream->mapsize + offset < stream->mapsize)
return -1; goto error;
stream->mappos = stream->mapsize + offset; stream->mappos = stream->mapsize + offset;
break; break;
} }
return stream->mappos; return stream->mappos;
} }
else
#endif #endif
{
ret = lseek(stream->fd, offset, whence); if (lseek(stream->fd, offset, whence) < 0)
return ret < 0 ? -1 : ret; goto error;
}
#endif #endif
return 0;
error:
return -1;
} }
ssize_t filestream_tell(RFILE *stream) ssize_t filestream_tell(RFILE *stream)
{ {
if (!stream) #if defined(__CELLOS_LV2__)
return -1;
#if defined(VITA) || defined(PSP)
return sceIoLseek(stream->fd, 0, SEEK_CUR);
#elif defined(__CELLOS_LV2__)
uint64_t pos = 0; uint64_t pos = 0;
#endif
if (!stream)
goto error;
#if defined(VITA) || defined(PSP)
if (sceIoLseek(stream->fd, 0, SEEK_CUR) < 0)
goto error;
#elif defined(__CELLOS_LV2__)
if (cellFsLseek(stream->fd, 0, CELL_FS_SEEK_CUR, &pos) != CELL_FS_SUCCEEDED) if (cellFsLseek(stream->fd, 0, CELL_FS_SEEK_CUR, &pos) != CELL_FS_SUCCEEDED)
return -1; goto error;
return 0;
#else #else
#if defined(HAVE_BUFFERED_IO) #if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
return ftell(stream->fp); return ftell(stream->fp);
else
#endif #endif
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
/* Need to check stream->mapped because this function /* Need to check stream->mapped because this function
* is called in filestream_open() */ * is called in filestream_open() */
if (stream->mapped && stream->hints & RFILE_HINT_MMAP) if (stream->mapped && stream->hints & RFILE_HINT_MMAP)
return stream->mappos; return stream->mappos;
else
#endif #endif
return lseek(stream->fd, 0, SEEK_CUR); if (lseek(stream->fd, 0, SEEK_CUR) < 0)
goto error;
#endif #endif
return 0;
error:
return -1;
} }
void filestream_rewind(RFILE *stream) void filestream_rewind(RFILE *stream)
@ -345,25 +347,24 @@ void filestream_rewind(RFILE *stream)
ssize_t filestream_read(RFILE *stream, void *s, size_t len) ssize_t filestream_read(RFILE *stream, void *s, size_t len)
{ {
if (!stream || !s) if (!stream || !s)
return -1; goto error;
#if defined(VITA) || defined(PSP) #if defined(VITA) || defined(PSP)
return sceIoRead(stream->fd, s, len); return sceIoRead(stream->fd, s, len);
#elif defined(__CELLOS_LV2__) #elif defined(__CELLOS_LV2__)
uint64_t bytes_written; uint64_t bytes_written;
if (cellFsRead(stream->fd, s, len, &bytes_written) != CELL_FS_SUCCEEDED) if (cellFsRead(stream->fd, s, len, &bytes_written) != CELL_FS_SUCCEEDED)
return -1; goto error;
return bytes_written; return bytes_written;
#else #else
#if defined(HAVE_BUFFERED_IO) #if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
return fread(s, 1, len, stream->fp); return fread(s, 1, len, stream->fp);
else
#endif #endif
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
if (stream->hints & RFILE_HINT_MMAP) if (stream->hints & RFILE_HINT_MMAP)
{ {
if (stream->mappos > stream->mapsize) if (stream->mappos > stream->mapsize)
return -1; goto error;
if (stream->mappos + len > stream->mapsize) if (stream->mappos + len > stream->mapsize)
len = stream->mapsize - stream->mappos; len = stream->mapsize - stream->mappos;
@ -373,42 +374,58 @@ ssize_t filestream_read(RFILE *stream, void *s, size_t len)
return len; return len;
} }
else
#endif #endif
return read(stream->fd, s, len); return read(stream->fd, s, len);
#endif #endif
error:
return -1;
} }
ssize_t filestream_write(RFILE *stream, const void *s, size_t len) ssize_t filestream_write(RFILE *stream, const void *s, size_t len)
{ {
if (!stream) if (!stream)
return -1; goto error;
#if defined(VITA) || defined(PSP) #if defined(VITA) || defined(PSP)
return sceIoWrite(stream->fd, s, len); return sceIoWrite(stream->fd, s, len);
#elif defined(__CELLOS_LV2__) #elif defined(__CELLOS_LV2__)
uint64_t bytes_written; uint64_t bytes_written;
if (cellFsWrite(stream->fd, s, len, &bytes_written) != CELL_FS_SUCCEEDED) if (cellFsWrite(stream->fd, s, len, &bytes_written) != CELL_FS_SUCCEEDED)
return -1; goto error;
return bytes_written; return bytes_written;
#else #else
#if defined(HAVE_BUFFERED_IO) #if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
return fwrite(s, 1, len, stream->fp); return fwrite(s, 1, len, stream->fp);
else
#endif #endif
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
if (stream->hints & RFILE_HINT_MMAP) if (stream->hints & RFILE_HINT_MMAP)
return -1; goto error;
else
#endif #endif
return write(stream->fd, s, len); return write(stream->fd, s, len);
#endif #endif
error:
return -1;
}
int filestream_putc(RFILE *stream, int c)
{
if (!stream)
return EOF;
#if defined(HAVE_BUFFERED_IO)
return fputc(c, stream->fp);
#else
/* unimplemented */
return EOF;
#endif
} }
int filestream_close(RFILE *stream) int filestream_close(RFILE *stream)
{ {
if (!stream) if (!stream)
return -1; goto error;
#if defined(VITA) || defined(PSP) #if defined(VITA) || defined(PSP)
if (stream->fd > 0) if (stream->fd > 0)
@ -436,6 +453,9 @@ int filestream_close(RFILE *stream)
free(stream); free(stream);
return 0; return 0;
error:
return -1;
} }
/** /**
@ -534,5 +554,8 @@ bool filestream_write_file(const char *path, const void *data, ssize_t size)
ret = filestream_write(file, data, size); ret = filestream_write(file, data, size);
filestream_close(file); filestream_close(file);
return (ret == size); if (ret != size)
return false;
return true;
} }

View File

@ -0,0 +1,270 @@
/* Copyright (C) 2010-2016 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (interface_stream.c).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <streams/interface_stream.h>
#include <streams/file_stream.h>
#include <streams/memory_stream.h>
struct intfstream_internal
{
enum intfstream_type type;
struct
{
RFILE *fp;
} file;
struct
{
struct
{
uint8_t *data;
unsigned size;
} buf;
memstream_t *fp;
bool writable;
} memory;
};
bool intfstream_resize(intfstream_internal_t *intf, intfstream_info_t *info)
{
if (!intf || !info)
return false;
switch (intf->type)
{
case INTFSTREAM_FILE:
break;
case INTFSTREAM_MEMORY:
intf->memory.buf.data = info->memory.buf.data;
intf->memory.buf.size = info->memory.buf.size;
memstream_set_buffer(intf->memory.buf.data,
intf->memory.buf.size);
break;
}
return true;
}
bool intfstream_open(intfstream_internal_t *intf, const char *path,
unsigned mode, ssize_t len)
{
if (!intf)
return false;
switch (intf->type)
{
case INTFSTREAM_FILE:
intf->file.fp = filestream_open(path, mode, len);
if (!intf->file.fp)
return false;
break;
case INTFSTREAM_MEMORY:
intf->memory.fp = memstream_open(intf->memory.writable);
if (!intf->memory.fp)
return false;
break;
}
return true;
}
int intfstream_close(intfstream_internal_t *intf)
{
if (!intf)
return -1;
switch (intf->type)
{
case INTFSTREAM_FILE:
return filestream_close(intf->file.fp);
case INTFSTREAM_MEMORY:
memstream_close(intf->memory.fp);
return 0;
}
return -1;
}
void *intfstream_init(intfstream_info_t *info)
{
intfstream_internal_t *intf = NULL;
if (!info)
goto error;
intf = (intfstream_internal_t*)calloc(1, sizeof(*intf));
if (!intf)
goto error;
intf->type = info->type;
switch (intf->type)
{
case INTFSTREAM_FILE:
break;
case INTFSTREAM_MEMORY:
intf->memory.writable = info->memory.writable;
if (!intfstream_resize(intf, info))
goto error;
break;
}
return intf;
error:
if (intf)
free(intf);
return NULL;
}
int intfstream_seek(intfstream_internal_t *intf, int offset, int whence)
{
if (!intf)
return -1;
switch (intf->type)
{
case INTFSTREAM_FILE:
return filestream_seek(intf->file.fp, offset, whence);
case INTFSTREAM_MEMORY:
return memstream_seek(intf->memory.fp, offset, whence);
}
return -1;
}
ssize_t intfstream_read(intfstream_internal_t *intf, void *s, size_t len)
{
if (!intf)
return 0;
switch (intf->type)
{
case INTFSTREAM_FILE:
return filestream_read(intf->file.fp, s, len);
case INTFSTREAM_MEMORY:
return memstream_read(intf->memory.fp, s, len);
}
return 0;
}
ssize_t intfstream_write(intfstream_internal_t *intf,
const void *s, size_t len)
{
if (!intf)
return 0;
switch (intf->type)
{
case INTFSTREAM_FILE:
return filestream_write(intf->file.fp, s, len);
case INTFSTREAM_MEMORY:
return memstream_write(intf->memory.fp, s, len);
}
return 0;
}
char *intfstream_gets(intfstream_internal_t *intf,
char *buffer, size_t len)
{
if (!intf)
return NULL;
switch (intf->type)
{
case INTFSTREAM_FILE:
/* unimplemented */
break;
case INTFSTREAM_MEMORY:
return memstream_gets(intf->memory.fp, buffer, len);
}
return NULL;
}
int intfstream_getc(intfstream_internal_t *intf)
{
if (!intf)
return 0;
switch (intf->type)
{
case INTFSTREAM_FILE:
/* unimplemented */
break;
case INTFSTREAM_MEMORY:
return memstream_getc(intf->memory.fp);
}
return 0;
}
int intfstream_tell(intfstream_internal_t *intf)
{
if (!intf)
return -1;
switch (intf->type)
{
case INTFSTREAM_FILE:
return filestream_tell(intf->file.fp);
case INTFSTREAM_MEMORY:
return memstream_pos(intf->memory.fp);
}
return -1;
}
void intfstream_rewind(intfstream_internal_t *intf)
{
switch (intf->type)
{
case INTFSTREAM_FILE:
filestream_rewind(intf->file.fp);
break;
case INTFSTREAM_MEMORY:
memstream_rewind(intf->memory.fp);
break;
}
}
void intfstream_putc(intfstream_internal_t *intf, int c)
{
if (!intf)
return;
switch (intf->type)
{
case INTFSTREAM_FILE:
filestream_putc(intf->file.fp, c);
break;
case INTFSTREAM_MEMORY:
memstream_putc(intf->memory.fp, c);
break;
}
}

View File

@ -32,11 +32,19 @@ static size_t last_file_size = 0;
struct memstream struct memstream
{ {
uint8_t *m_buf; uint8_t *buf;
size_t m_size; size_t size;
size_t m_ptr; size_t ptr;
size_t max_ptr;
unsigned writing;
}; };
static void memstream_update_pos(memstream_t *stream)
{
if (stream->ptr > stream->max_ptr)
stream->max_ptr = stream->ptr;
}
void memstream_set_buffer(uint8_t *buffer, size_t size) void memstream_set_buffer(uint8_t *buffer, size_t size)
{ {
g_buffer = buffer; g_buffer = buffer;
@ -48,21 +56,27 @@ size_t memstream_get_last_size(void)
return last_file_size; return last_file_size;
} }
static void memstream_init(memstream_t *stream, uint8_t *buffer, size_t max_size) static void memstream_init(memstream_t *stream,
uint8_t *buffer, size_t max_size, unsigned writing)
{ {
stream->m_buf = buffer; if (!stream)
stream->m_size = max_size; return;
stream->m_ptr = 0;
stream->buf = buffer;
stream->size = max_size;
stream->ptr = 0;
stream->max_ptr = 0;
stream->writing = writing;
} }
memstream_t *memstream_open(void) memstream_t *memstream_open(unsigned writing)
{ {
memstream_t *stream; memstream_t *stream;
if (!g_buffer || !g_size) if (!g_buffer || !g_size)
return NULL; return NULL;
stream = (memstream_t*)calloc(1, sizeof(*stream)); stream = (memstream_t*)calloc(1, sizeof(*stream));
memstream_init(stream, g_buffer, g_size); memstream_init(stream, g_buffer, g_size, writing);
g_buffer = NULL; g_buffer = NULL;
g_size = 0; g_size = 0;
@ -71,29 +85,44 @@ memstream_t *memstream_open(void)
void memstream_close(memstream_t *stream) void memstream_close(memstream_t *stream)
{ {
last_file_size = stream->m_ptr; if (!stream)
return;
last_file_size = stream->writing ? stream->max_ptr : stream->size;
free(stream); free(stream);
} }
size_t memstream_read(memstream_t *stream, void *data, size_t bytes) size_t memstream_read(memstream_t *stream, void *data, size_t bytes)
{ {
size_t avail = stream->m_size - stream->m_ptr; size_t avail = 0;
if (!stream)
return 0;
avail = stream->size - stream->ptr;
if (bytes > avail) if (bytes > avail)
bytes = avail; bytes = avail;
memcpy(data, stream->m_buf + stream->m_ptr, bytes); memcpy(data, stream->buf + stream->ptr, bytes);
stream->m_ptr += bytes; stream->ptr += bytes;
memstream_update_pos(stream);
return bytes; return bytes;
} }
size_t memstream_write(memstream_t *stream, const void *data, size_t bytes) size_t memstream_write(memstream_t *stream, const void *data, size_t bytes)
{ {
size_t avail = stream->m_size - stream->m_ptr; size_t avail = 0;
if (!stream)
return 0;
avail = stream->size - stream->ptr;
if (bytes > avail) if (bytes > avail)
bytes = avail; bytes = avail;
memcpy(stream->m_buf + stream->m_ptr, data, bytes); memcpy(stream->buf + stream->ptr, data, bytes);
stream->m_ptr += bytes; stream->ptr += bytes;
memstream_update_pos(stream);
return bytes; return bytes;
} }
@ -107,26 +136,32 @@ int memstream_seek(memstream_t *stream, int offset, int whence)
ptr = offset; ptr = offset;
break; break;
case SEEK_CUR: case SEEK_CUR:
ptr = stream->m_ptr + offset; ptr = stream->ptr + offset;
break; break;
case SEEK_END: case SEEK_END:
ptr = stream->m_size + offset; ptr = (stream->writing ? stream->max_ptr : stream->size) + offset;
break; break;
default: default:
return -1; return -1;
} }
if (ptr <= stream->m_size) if (ptr <= stream->size)
{ {
stream->m_ptr = ptr; stream->ptr = ptr;
return 0; return 0;
} }
return -1; return -1;
} }
void memstream_rewind(memstream_t *stream)
{
memstream_seek(stream, 0L, SEEK_SET);
}
size_t memstream_pos(memstream_t *stream) size_t memstream_pos(memstream_t *stream)
{ {
return stream->m_ptr; return stream->ptr;
} }
char *memstream_gets(memstream_t *stream, char *buffer, size_t len) char *memstream_gets(memstream_t *stream, char *buffer, size_t len)
@ -136,7 +171,20 @@ char *memstream_gets(memstream_t *stream, char *buffer, size_t len)
int memstream_getc(memstream_t *stream) int memstream_getc(memstream_t *stream)
{ {
if (stream->m_ptr >= stream->m_size) int ret = 0;
if (stream->ptr >= stream->size)
return EOF; return EOF;
return stream->m_buf[stream->m_ptr++]; ret = stream->buf[stream->ptr++];
memstream_update_pos(stream);
return ret;
}
void memstream_putc(memstream_t *stream, int c)
{
if (stream->ptr < stream->size)
stream->buf[stream->ptr++] = c;
memstream_update_pos(stream);
} }