mirror of
https://github.com/libretro/beetle-pce-fast-libretro.git
synced 2024-11-23 07:50:03 +00:00
Update libretro-common
This commit is contained in:
parent
51eb6a241a
commit
79f0550469
@ -119,7 +119,7 @@ SOURCES_C += $(MEDNAFEN_DIR)/trio/trio.c \
|
||||
$(MEDNAFEN_DIR)/trio/triostr.c
|
||||
|
||||
ifneq ($(STATIC_LINKING), 1)
|
||||
SOURCES_C += $(LIBRETRO_DIR)/file/retro_file.c \
|
||||
SOURCES_C += $(LIBRETRO_DIR)/streams/file_stream.c \
|
||||
$(LIBRETRO_DIR)/file/retro_stat.c
|
||||
|
||||
ifeq ($(NEED_THREADING), 1)
|
||||
|
@ -1,388 +0,0 @@
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_file.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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# ifdef _MSC_VER
|
||||
# define setmode _setmode
|
||||
# endif
|
||||
# ifdef _XBOX
|
||||
# include <xtl.h>
|
||||
# define INVALID_FILE_ATTRIBUTES -1
|
||||
# else
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
# include <direct.h>
|
||||
# include <windows.h>
|
||||
# endif
|
||||
#elif defined(VITA)
|
||||
# include <psp2/io/fcntl.h>
|
||||
# include <psp2/io/dirent.h>
|
||||
|
||||
#define PSP_O_RDONLY PSP2_O_RDONLY
|
||||
#define PSP_O_RDWR PSP2_O_RDWR
|
||||
#define PSP_O_CREAT PSP2_O_CREAT
|
||||
#define PSP_O_WRONLY PSP2_O_WRONLY
|
||||
#define PSP_O_TRUNC PSP2_O_TRUNC
|
||||
#else
|
||||
# if defined(PSP)
|
||||
# include <pspiofilemgr.h>
|
||||
# endif
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <dirent.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
#include <cell/cell_fs.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef RARCH_INTERNAL
|
||||
#include <retro_log.h>
|
||||
#endif
|
||||
|
||||
#include <retro_file.h>
|
||||
|
||||
#if 1
|
||||
#define HAVE_BUFFERED_IO 1
|
||||
#endif
|
||||
|
||||
struct RFILE
|
||||
{
|
||||
#if defined(PSP) || defined(VITA)
|
||||
SceUID fd;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
int fd;
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
FILE *fd;
|
||||
#else
|
||||
int fd;
|
||||
#endif
|
||||
};
|
||||
|
||||
int retro_get_fd(RFILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return -1;
|
||||
#if defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__)
|
||||
return stream->fd;
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
return fileno(stream->fd);
|
||||
#else
|
||||
return stream->fd;
|
||||
#endif
|
||||
}
|
||||
|
||||
RFILE *retro_fopen(const char *path, unsigned mode, ssize_t len)
|
||||
{
|
||||
int flags = 0;
|
||||
int mode_int = 0;
|
||||
const char *mode_str = NULL;
|
||||
RFILE *stream = (RFILE*)calloc(1, sizeof(*stream));
|
||||
|
||||
if (!stream)
|
||||
return NULL;
|
||||
|
||||
(void)mode_str;
|
||||
(void)mode_int;
|
||||
(void)flags;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case RFILE_MODE_READ:
|
||||
#if defined(VITA) || defined(PSP)
|
||||
mode_int = 0777;
|
||||
flags = PSP_O_RDONLY;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
mode_int = 0777;
|
||||
flags = CELL_FS_O_RDONLY;
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
mode_str = "rb";
|
||||
#else
|
||||
flags = O_RDONLY;
|
||||
#endif
|
||||
break;
|
||||
case RFILE_MODE_WRITE:
|
||||
#if defined(VITA) || defined(PSP)
|
||||
mode_int = 0777;
|
||||
flags = PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
mode_int = 0777;
|
||||
flags = CELL_FS_O_CREAT | CELL_FS_O_WRONLY | CELL_FS_O_TRUNC;
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
mode_str = "wb";
|
||||
#else
|
||||
flags = O_WRONLY | O_CREAT | O_TRUNC | S_IRUSR | S_IWUSR;
|
||||
#endif
|
||||
break;
|
||||
case RFILE_MODE_READ_WRITE:
|
||||
#if defined(VITA) || defined(PSP)
|
||||
mode_int = 0777;
|
||||
flags = PSP_O_RDWR;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
mode_int = 0777;
|
||||
flags = CELL_FS_O_RDWR;
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
mode_str = "w+";
|
||||
#else
|
||||
flags = O_RDWR;
|
||||
#ifdef _WIN32
|
||||
flags |= O_BINARY;
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(VITA) || defined(PSP)
|
||||
stream->fd = sceIoOpen(path, flags, mode_int);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
cellFsOpen(path, flags, &stream->fd, NULL, 0);
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
stream->fd = fopen(path, mode_str);
|
||||
#else
|
||||
stream->fd = open(path, flags);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if (!stream->fd)
|
||||
goto error;
|
||||
#else
|
||||
if (stream->fd == -1)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
return stream;
|
||||
|
||||
error:
|
||||
retro_fclose(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssize_t retro_fseek(RFILE *stream, ssize_t offset, int whence)
|
||||
{
|
||||
int ret = 0;
|
||||
if (!stream)
|
||||
return -1;
|
||||
|
||||
(void)ret;
|
||||
|
||||
#if defined(VITA) || defined(PSP)
|
||||
ret = sceIoLseek(stream->fd, (SceOff)offset, whence);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
uint64_t pos = 0;
|
||||
if (cellFsLseek(stream->fd, offset, whence, &pos) != CELL_FS_SUCCEEDED)
|
||||
return -1;
|
||||
return 0;
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
return fseek(stream->fd, (long)offset, whence);
|
||||
#else
|
||||
ret = lseek(stream->fd, offset, whence);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t retro_ftell(RFILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return -1;
|
||||
#if defined(VITA) || defined(PSP)
|
||||
return sceIoLseek(stream->fd, 0, SEEK_CUR);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
uint64_t pos = 0;
|
||||
if (cellFsLseek(stream->fd, 0, CELL_FS_SEEK_CUR, &pos) != CELL_FS_SUCCEEDED)
|
||||
return -1;
|
||||
return 0;
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
return ftell(stream->fd);
|
||||
#else
|
||||
return lseek(stream->fd, 0, SEEK_CUR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void retro_frewind(RFILE *stream)
|
||||
{
|
||||
retro_fseek(stream, 0L, SEEK_SET);
|
||||
}
|
||||
|
||||
ssize_t retro_fread(RFILE *stream, void *s, size_t len)
|
||||
{
|
||||
if (!stream || !s)
|
||||
return -1;
|
||||
#if defined(VITA) || defined(PSP)
|
||||
return sceIoRead(stream->fd, s, len);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
uint64_t bytes_written;
|
||||
if (cellFsRead(stream->fd, s, len, &bytes_written) != CELL_FS_SUCCEEDED)
|
||||
return -1;
|
||||
return bytes_written;
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
return fread(s, 1, len, stream->fd);
|
||||
#else
|
||||
return read(stream->fd, s, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t retro_fwrite(RFILE *stream, const void *s, size_t len)
|
||||
{
|
||||
if (!stream)
|
||||
return -1;
|
||||
#if defined(VITA) || defined(PSP)
|
||||
return sceIoWrite(stream->fd, s, len);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
uint64_t bytes_written;
|
||||
if (cellFsWrite(stream->fd, s, len, &bytes_written) != CELL_FS_SUCCEEDED)
|
||||
return -1;
|
||||
return bytes_written;
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
return fwrite(s, 1, len, stream->fd);
|
||||
#else
|
||||
return write(stream->fd, s, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
int retro_fclose(RFILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return -1;
|
||||
|
||||
#if defined(VITA) || defined(PSP)
|
||||
if (stream->fd > 0)
|
||||
sceIoClose(stream->fd);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
if (stream->fd > 0)
|
||||
cellFsClose(stream->fd);
|
||||
#elif defined(HAVE_BUFFERED_IO)
|
||||
if (stream->fd)
|
||||
fclose(stream->fd);
|
||||
#else
|
||||
if (stream->fd > 0)
|
||||
close(stream->fd);
|
||||
#endif
|
||||
free(stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* retro_read_file:
|
||||
* @path : path to file.
|
||||
* @buf : buffer to allocate and read the contents of the
|
||||
* file into. Needs to be freed manually.
|
||||
*
|
||||
* Read the contents of a file into @buf.
|
||||
*
|
||||
* Returns: number of items read, -1 on error.
|
||||
*/
|
||||
int retro_read_file(const char *path, void **buf, ssize_t *len)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
ssize_t content_buf_size = 0;
|
||||
void *content_buf = NULL;
|
||||
RFILE *file = retro_fopen(path, RFILE_MODE_READ, -1);
|
||||
|
||||
if (!file)
|
||||
goto error;
|
||||
|
||||
if (retro_fseek(file, 0, SEEK_END) != 0)
|
||||
goto error;
|
||||
|
||||
content_buf_size = retro_ftell(file);
|
||||
if (content_buf_size < 0)
|
||||
goto error;
|
||||
|
||||
retro_frewind(file);
|
||||
|
||||
content_buf = malloc(content_buf_size + 1);
|
||||
|
||||
if (!content_buf)
|
||||
goto error;
|
||||
|
||||
if ((ret = retro_fread(file, content_buf, content_buf_size)) < content_buf_size)
|
||||
{
|
||||
#ifdef RARCH_INTERNAL
|
||||
RARCH_WARN("Didn't read whole file: %s.\n", path);
|
||||
#else
|
||||
printf("Didn't read whole file: %s.\n", path);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!content_buf)
|
||||
goto error;
|
||||
|
||||
*buf = content_buf;
|
||||
|
||||
/* Allow for easy reading of strings to be safe.
|
||||
* Will only work with sane character formatting (Unix). */
|
||||
((char*)content_buf)[content_buf_size] = '\0';
|
||||
|
||||
if (retro_fclose(file) != 0)
|
||||
printf("Failed to close file stream.\n");
|
||||
|
||||
if (len)
|
||||
*len = ret;
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
retro_fclose(file);
|
||||
if (content_buf)
|
||||
free(content_buf);
|
||||
if (len)
|
||||
*len = -1;
|
||||
*buf = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* retro_write_file:
|
||||
* @path : path to file.
|
||||
* @data : contents to write to the file.
|
||||
* @size : size of the contents.
|
||||
*
|
||||
* Writes data to a file.
|
||||
*
|
||||
* Returns: true (1) on success, false (0) otherwise.
|
||||
*/
|
||||
bool retro_write_file(const char *path, const void *data, ssize_t size)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
RFILE *file = retro_fopen(path, RFILE_MODE_WRITE, -1);
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
ret = retro_fwrite(file, data, size);
|
||||
retro_fclose(file);
|
||||
|
||||
return (ret == size);
|
||||
}
|
@ -1,20 +1,27 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (boolean.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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 __RARCH_BOOLEAN_H
|
||||
#define __RARCH_BOOLEAN_H
|
||||
#ifndef __LIBRETRO_SDK_BOOLEAN_H
|
||||
#define __LIBRETRO_SDK_BOOLEAN_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
@ -30,4 +37,3 @@
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
49
libretro-common/include/compat/apple_compat.h
Normal file
49
libretro-common/include/compat/apple_compat.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (apple_compat.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.
|
||||
*/
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <AvailabilityMacros.h>
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4)
|
||||
typedef int NSInteger;
|
||||
typedef unsigned NSUInteger;
|
||||
typedef float CGFloat;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IOS
|
||||
#ifndef __IPHONE_5_0
|
||||
#warning "This project uses features only available in iOS SDK 5.0 and later."
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <GLKit/GLKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <objc/objc-runtime.h>
|
||||
#endif
|
||||
#endif
|
30
libretro-common/include/compat/fnmatch.h
Normal file
30
libretro-common/include/compat/fnmatch.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_fnmatch.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_FNMATCH_H__
|
||||
#define __LIBRETRO_SDK_COMPAT_FNMATCH_H__
|
||||
|
||||
#define FNM_NOMATCH 1
|
||||
|
||||
int rl_fnmatch(const char *pattern, const char *string, int flags);
|
||||
|
||||
#endif
|
76
libretro-common/include/compat/getopt.h
Normal file
76
libretro-common/include/compat/getopt.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_getopt.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_GETOPT_H
|
||||
#define __LIBRETRO_SDK_COMPAT_GETOPT_H
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
/* Custom implementation of the GNU getopt_long for portability.
|
||||
* Not designed to be fully compatible, but compatible with
|
||||
* the features RetroArch uses. */
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
#include <getopt.h>
|
||||
#else
|
||||
/* Avoid possible naming collisions during link since we
|
||||
* prefer to use the actual name. */
|
||||
#define getopt_long(argc, argv, optstring, longopts, longindex) __getopt_long_retro(argc, argv, optstring, longopts, longindex)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct option
|
||||
{
|
||||
const char *name;
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* argv[] is declared with char * const argv[] in GNU,
|
||||
* but this makes no sense, as non-POSIX getopt_long
|
||||
* mutates argv (non-opts are moved to the end). */
|
||||
int getopt_long(int argc, char *argv[],
|
||||
const char *optstring, const struct option *longopts, int *longindex);
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If these are variously #defined, then we have bigger problems */
|
||||
#ifndef no_argument
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
#endif
|
||||
|
||||
/* HAVE_GETOPT_LONG */
|
||||
#endif
|
||||
|
||||
/* pragma once */
|
||||
#endif
|
||||
|
53
libretro-common/include/compat/ifaddrs.h
Normal file
53
libretro-common/include/compat/ifaddrs.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 1999
|
||||
* Berkeley Software Design, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
|
||||
*/
|
||||
|
||||
#ifndef _IFADDRS_H_
|
||||
#define _IFADDRS_H_
|
||||
|
||||
struct ifaddrs
|
||||
{
|
||||
struct ifaddrs *ifa_next;
|
||||
char *ifa_name;
|
||||
unsigned int ifa_flags;
|
||||
struct sockaddr *ifa_addr;
|
||||
struct sockaddr *ifa_netmask;
|
||||
struct sockaddr *ifa_dstaddr;
|
||||
void *ifa_data;
|
||||
};
|
||||
|
||||
/*
|
||||
* This may have been defined in <net/if.h>. Note that if <net/if.h> is
|
||||
* to be included it must be included before this header file.
|
||||
*/
|
||||
#ifndef ifa_broadaddr
|
||||
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
extern int getifaddrs(struct ifaddrs **ifap);
|
||||
extern void freeifaddrs(struct ifaddrs *ifa);
|
||||
|
||||
#endif
|
104
libretro-common/include/compat/msvc.h
Normal file
104
libretro-common/include/compat/msvc.h
Normal file
@ -0,0 +1,104 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (msvc_compat.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_MSVC_H
|
||||
#define __LIBRETRO_SDK_COMPAT_MSVC_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Pre-MSVC 2015 compilers don't implement snprintf in a cross-platform manner. */
|
||||
#if _MSC_VER < 1900
|
||||
#include <stdlib.h>
|
||||
#ifndef snprintf
|
||||
#define snprintf c99_snprintf_retro__
|
||||
#endif
|
||||
|
||||
int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...);
|
||||
#endif
|
||||
|
||||
/* Pre-MSVC 2010 compilers don't implement vsnprintf in a cross-platform manner? Not sure about this one. */
|
||||
#if _MSC_VER < 1600
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef vsnprintf
|
||||
#define vsnprintf c99_vsnprintf_retro__
|
||||
#endif
|
||||
int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list ap);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef UNICODE /* Do not bother with UNICODE at this time. */
|
||||
#include <direct.h>
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Python headers defines ssize_t and sets HAVE_SSIZE_T.
|
||||
* Cannot duplicate these efforts.
|
||||
*/
|
||||
#ifndef HAVE_SSIZE_T
|
||||
#if defined(_WIN64)
|
||||
typedef __int64 ssize_t;
|
||||
#elif defined(_WIN32)
|
||||
typedef int ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define mkdir(dirname, unused) _mkdir(dirname)
|
||||
#define strtoull _strtoui64
|
||||
#undef strcasecmp
|
||||
#define strcasecmp _stricmp
|
||||
#undef strncasecmp
|
||||
#define strncasecmp _strnicmp
|
||||
|
||||
/* Disable some of the annoying warnings. */
|
||||
#pragma warning(disable : 4800)
|
||||
#pragma warning(disable : 4805)
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4305)
|
||||
#pragma warning(disable : 4146)
|
||||
#pragma warning(disable : 4267)
|
||||
#pragma warning(disable : 4723)
|
||||
#pragma warning(disable : 4996)
|
||||
|
||||
/* roundf is available since MSVC 2013 */
|
||||
#if _MSC_VER < 1800
|
||||
#define roundf(in) (in >= 0.0f ? floorf(in + 0.5f) : ceilf(in - 0.5f))
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX _MAX_PATH
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX _UI32_MAX
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
254
libretro-common/include/compat/msvc/stdint.h
Normal file
254
libretro-common/include/compat/msvc/stdint.h
Normal file
@ -0,0 +1,254 @@
|
||||
/* ISO C9x compliant stdint.h for Microsoft Visual Studio
|
||||
* Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
*
|
||||
* Copyright (c) 2006-2008 Alexander Chemeris
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of the author may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_STDINT_H
|
||||
#define __RARCH_STDINT_H
|
||||
|
||||
#if _MSC_VER && (_MSC_VER < 1600)
|
||||
/* Pre-MSVC 2010 needs an implementation of stdint.h. */
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/* For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||
* compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
||||
* or compiler give many errors like this:
|
||||
*
|
||||
* error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
# include <wchar.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Define _W64 macros to mark types changing their size, like intptr_t. */
|
||||
#ifndef _W64
|
||||
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
||||
# define _W64 __w64
|
||||
# else
|
||||
# define _W64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* 7.18.1 Integer types. */
|
||||
|
||||
/* 7.18.1.1 Exact-width integer types. */
|
||||
|
||||
/* Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||
* realize that, e.g. char has the same size as __int8
|
||||
* so we give up on __intX for them.
|
||||
*/
|
||||
#if (_MSC_VER < 1300)
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
|
||||
/* 7.18.1.2 Minimum-width integer types. */
|
||||
typedef int8_t int_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef int64_t int_least64_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
typedef uint64_t uint_least64_t;
|
||||
|
||||
/* 7.18.1.3 Fastest minimum-width integer types. */
|
||||
typedef int8_t int_fast8_t;
|
||||
typedef int16_t int_fast16_t;
|
||||
typedef int32_t int_fast32_t;
|
||||
typedef int64_t int_fast64_t;
|
||||
typedef uint8_t uint_fast8_t;
|
||||
typedef uint16_t uint_fast16_t;
|
||||
typedef uint32_t uint_fast32_t;
|
||||
typedef uint64_t uint_fast64_t;
|
||||
|
||||
/* 7.18.1.4 Integer types capable of holding object pointers. */
|
||||
#ifdef _WIN64 /* [ */
|
||||
typedef signed __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else /* _WIN64 ][ */
|
||||
typedef _W64 signed int intptr_t;
|
||||
typedef _W64 unsigned int uintptr_t;
|
||||
#endif /* _WIN64 ] */
|
||||
|
||||
/* 7.18.1.5 Greatest-width integer types. */
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
|
||||
/* 7.18.2 Limits of specified-width integer types. */
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
|
||||
/* [ See footnote 220 at page 257 and footnote 221 at page 259. */
|
||||
|
||||
/* 7.18.2.1 Limits of exact-width integer types. */
|
||||
#define INT8_MIN ((int8_t)_I8_MIN)
|
||||
#define INT8_MAX _I8_MAX
|
||||
#define INT16_MIN ((int16_t)_I16_MIN)
|
||||
#define INT16_MAX _I16_MAX
|
||||
#define INT32_MIN ((int32_t)_I32_MIN)
|
||||
#define INT32_MAX _I32_MAX
|
||||
#define INT64_MIN ((int64_t)_I64_MIN)
|
||||
#define INT64_MAX _I64_MAX
|
||||
#define UINT8_MAX _UI8_MAX
|
||||
#define UINT16_MAX _UI16_MAX
|
||||
#define UINT32_MAX _UI32_MAX
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
|
||||
/* 7.18.2.2 Limits of minimum-width integer types. */
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
/* 7.18.2.3 Limits of fastest minimum-width integer types. */
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MIN INT16_MIN
|
||||
#define INT_FAST16_MAX INT16_MAX
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT16_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
/* 7.18.2.4 Limits of integer types capable of holding object pointers. */
|
||||
#ifdef _WIN64 /* [ */
|
||||
# define INTPTR_MIN INT64_MIN
|
||||
# define INTPTR_MAX INT64_MAX
|
||||
# define UINTPTR_MAX UINT64_MAX
|
||||
#else /* _WIN64 ][ */
|
||||
# define INTPTR_MIN INT32_MIN
|
||||
# define INTPTR_MAX INT32_MAX
|
||||
# define UINTPTR_MAX UINT32_MAX
|
||||
#endif /* _WIN64 ] */
|
||||
|
||||
/* 7.18.2.5 Limits of greatest-width integer types */
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
/* 7.18.3 Limits of other integer types */
|
||||
|
||||
#ifdef _WIN64 /* [ */
|
||||
# define PTRDIFF_MIN _I64_MIN
|
||||
# define PTRDIFF_MAX _I64_MAX
|
||||
#else /* _WIN64 ][ */
|
||||
# define PTRDIFF_MIN _I32_MIN
|
||||
# define PTRDIFF_MAX _I32_MAX
|
||||
#endif /* _WIN64 ] */
|
||||
|
||||
#define SIG_ATOMIC_MIN INT_MIN
|
||||
#define SIG_ATOMIC_MAX INT_MAX
|
||||
|
||||
#ifndef SIZE_MAX /* [ */
|
||||
# ifdef _WIN64 /* [ */
|
||||
# define SIZE_MAX _UI64_MAX
|
||||
# else /* _WIN64 ][ */
|
||||
# define SIZE_MAX _UI32_MAX
|
||||
# endif /* _WIN64 ] */
|
||||
#endif /* SIZE_MAX ] */
|
||||
|
||||
/* WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> */
|
||||
#ifndef WCHAR_MIN /* [ */
|
||||
# define WCHAR_MIN 0
|
||||
#endif /* WCHAR_MIN ] */
|
||||
#ifndef WCHAR_MAX // [
|
||||
# define WCHAR_MAX _UI16_MAX
|
||||
#endif /* WCHAR_MAX ] */
|
||||
|
||||
#define WINT_MIN 0
|
||||
#define WINT_MAX _UI16_MAX
|
||||
|
||||
#endif /* __STDC_LIMIT_MACROS ] */
|
||||
|
||||
/* 7.18.4 Limits of other integer types */
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
|
||||
/* [ See footnote 224 at page 260 */
|
||||
|
||||
/* 7.18.4.1 Macros for minimum-width integer constants */
|
||||
|
||||
#define INT8_C(val) val##i8
|
||||
#define INT16_C(val) val##i16
|
||||
#define INT32_C(val) val##i32
|
||||
#define INT64_C(val) val##i64
|
||||
|
||||
#define UINT8_C(val) val##ui8
|
||||
#define UINT16_C(val) val##ui16
|
||||
#define UINT32_C(val) val##ui32
|
||||
#define UINT64_C(val) val##ui64
|
||||
|
||||
/* 7.18.4.2 Macros for greatest-width integer constants */
|
||||
#define INTMAX_C INT64_C
|
||||
#define UINTMAX_C UINT64_C
|
||||
|
||||
#endif
|
||||
/* __STDC_CONSTANT_MACROS ] */
|
||||
|
||||
#else
|
||||
/* Sanity for everything else. */
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
63
libretro-common/include/compat/posix_string.h
Normal file
63
libretro-common/include/compat/posix_string.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (posix_string.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_POSIX_STRING_H
|
||||
#define __LIBRETRO_SDK_COMPAT_POSIX_STRING_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <compat/msvc.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef strtok_r
|
||||
#define strtok_r(str, delim, saveptr) retro_strtok_r__(str, delim, saveptr)
|
||||
|
||||
char *strtok_r(char *str, const char *delim, char **saveptr);
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#undef strcasecmp
|
||||
#undef strdup
|
||||
#define strcasecmp(a, b) retro_strcasecmp__(a, b)
|
||||
#define strdup(orig) retro_strdup__(orig)
|
||||
int strcasecmp(const char *a, const char *b);
|
||||
char *strdup(const char *orig);
|
||||
|
||||
/* isblank is available since MSVC 2013 */
|
||||
#if _MSC_VER < 1800
|
||||
#undef isblank
|
||||
#define isblank(c) retro_isblank__(c)
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
49
libretro-common/include/compat/strcasestr.h
Normal file
49
libretro-common/include/compat/strcasestr.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (strcasestr.h). * ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_STRCASESTR_H
|
||||
#define __LIBRETRO_SDK_COMPAT_STRCASESTR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASESTR
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Avoid possible naming collisions during link
|
||||
* since we prefer to use the actual name. */
|
||||
#define strcasestr(haystack, needle) strcasestr_retro__(haystack, needle)
|
||||
|
||||
char *strcasestr(const char *haystack, const char *needle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_file.h).
|
||||
* The following license statement only applies to this file (strl.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
@ -20,51 +20,41 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RETRO_FILE_H
|
||||
#define __RETRO_FILE_H
|
||||
#ifndef __LIBRETRO_SDK_COMPAT_STRL_H
|
||||
#define __LIBRETRO_SDK_COMPAT_STRL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct RFILE RFILE;
|
||||
#ifdef __MACH__
|
||||
#ifndef HAVE_STRL
|
||||
#define HAVE_STRL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
RFILE_MODE_READ = 0,
|
||||
RFILE_MODE_WRITE,
|
||||
RFILE_MODE_READ_WRITE
|
||||
};
|
||||
#ifndef HAVE_STRL
|
||||
/* Avoid possible naming collisions during link since
|
||||
* we prefer to use the actual name. */
|
||||
#define strlcpy(dst, src, size) strlcpy_retro__(dst, src, size)
|
||||
|
||||
RFILE *retro_fopen(const char *path, unsigned mode, ssize_t len);
|
||||
#define strlcat(dst, src, size) strlcat_retro__(dst, src, size)
|
||||
|
||||
ssize_t retro_fseek(RFILE *stream, ssize_t offset, int whence);
|
||||
size_t strlcpy(char *dest, const char *source, size_t size);
|
||||
size_t strlcat(char *dest, const char *source, size_t size);
|
||||
|
||||
ssize_t retro_fread(RFILE *stream, void *s, size_t len);
|
||||
|
||||
ssize_t retro_fwrite(RFILE *stream, const void *s, size_t len);
|
||||
|
||||
ssize_t retro_ftell(RFILE *stream);
|
||||
|
||||
void retro_frewind(RFILE *stream);
|
||||
|
||||
int retro_fclose(RFILE *stream);
|
||||
|
||||
int retro_read_file(const char *path, void **buf, ssize_t *len);
|
||||
|
||||
bool retro_write_file(const char *path, const void *data, ssize_t size);
|
||||
|
||||
int retro_get_fd(RFILE *stream);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
34
libretro-common/include/libco.h
Normal file
34
libretro-common/include/libco.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
libco
|
||||
version: 0.16 (2010-12-24)
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#ifndef LIBCO_H
|
||||
#define LIBCO_H
|
||||
|
||||
#ifdef LIBCO_C
|
||||
#ifdef LIBCO_MP
|
||||
#define thread_local __thread
|
||||
#else
|
||||
#define thread_local
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* cothread_t;
|
||||
|
||||
cothread_t co_active();
|
||||
cothread_t co_create(unsigned int, void (*)(void));
|
||||
void co_delete(cothread_t);
|
||||
void co_switch(cothread_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ifndef LIBCO_H */
|
||||
#endif
|
49
libretro-common/include/memmap.h
Normal file
49
libretro-common/include/memmap.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (memmap.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_MEMMAP_H
|
||||
#define _LIBRETRO_MEMMAP_H
|
||||
|
||||
#if defined(__CELLOS_LV2__) || defined(PSP) || defined(GEKKO) || defined(VITA) || defined(_XBOX) || defined(_3DS)
|
||||
/* No mman available */
|
||||
#elif defined(_WIN32) && !defined(_XBOX)
|
||||
#include <windows.h>
|
||||
#include <errno.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#define HAVE_MMAN
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_MMAN) || defined(_WIN32)
|
||||
void* mmap(void *addr, size_t len, int mmap_prot, int mmap_flags, int fildes, size_t off);
|
||||
|
||||
int munmap(void *addr, size_t len);
|
||||
|
||||
int mprotect(void *addr, size_t len, int prot);
|
||||
#endif
|
||||
|
||||
int memsync(void *start, void *end);
|
||||
|
||||
int memprotect(void *addr, size_t len);
|
||||
|
||||
#endif
|
155
libretro-common/include/queues/task_queue.h
Normal file
155
libretro-common/include/queues/task_queue.h
Normal file
@ -0,0 +1,155 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (task_queue.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_TASK_QUEUE_H__
|
||||
#define __LIBRETRO_SDK_TASK_QUEUE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum task_queue_ctl_state
|
||||
{
|
||||
TASK_QUEUE_CTL_NONE = 0,
|
||||
|
||||
/* Deinitializes the task system.
|
||||
* This deinitializes the task system.
|
||||
* The tasks that are running at
|
||||
* the moment will stay on hold
|
||||
* until TASK_QUEUE_CTL_INIT is called again. */
|
||||
TASK_QUEUE_CTL_DEINIT,
|
||||
|
||||
/* Initializes the task system.
|
||||
* This initializes the task system
|
||||
* and chooses an appropriate
|
||||
* implementation according to the settings.
|
||||
*
|
||||
* This must only be called from the main thread. */
|
||||
TASK_QUEUE_CTL_INIT,
|
||||
|
||||
/**
|
||||
* Calls func for every running task
|
||||
* until it returns true.
|
||||
* Returns a task or NULL if not found.
|
||||
*/
|
||||
TASK_QUEUE_CTL_FIND,
|
||||
|
||||
/* Blocks until all tasks have finished.
|
||||
* This must only be called from the main thread. */
|
||||
TASK_QUEUE_CTL_WAIT,
|
||||
|
||||
/* Checks for finished tasks
|
||||
* Takes the finished tasks, if any,
|
||||
* and runs their callbacks.
|
||||
* This must only be called from the main thread. */
|
||||
TASK_QUEUE_CTL_CHECK,
|
||||
|
||||
/* Pushes a task
|
||||
* The task will start as soon as possible. */
|
||||
TASK_QUEUE_CTL_PUSH,
|
||||
|
||||
/* Sends a signal to terminate all the tasks.
|
||||
*
|
||||
* This won't terminate the tasks immediately.
|
||||
* They will finish as soon as possible.
|
||||
*
|
||||
* This must only be called from the main thread. */
|
||||
TASK_QUEUE_CTL_RESET,
|
||||
|
||||
TASK_QUEUE_CTL_SET_THREADED,
|
||||
|
||||
TASK_QUEUE_CTL_UNSET_THREADED,
|
||||
|
||||
TASK_QUEUE_CTL_IS_THREADED
|
||||
};
|
||||
|
||||
typedef struct retro_task retro_task_t;
|
||||
typedef void (*retro_task_callback_t)(void *task_data,
|
||||
void *user_data, const char *error);
|
||||
|
||||
typedef void (*retro_task_handler_t)(retro_task_t *task);
|
||||
|
||||
typedef bool (*retro_task_finder_t)(retro_task_t *task,
|
||||
void *userdata);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *source_file;
|
||||
} decompress_task_data_t;
|
||||
|
||||
struct retro_task
|
||||
{
|
||||
retro_task_handler_t handler;
|
||||
|
||||
/* always called from the main loop */
|
||||
retro_task_callback_t callback;
|
||||
|
||||
/* set to true by the handler to signal
|
||||
* the task has finished executing. */
|
||||
bool finished;
|
||||
|
||||
/* set to true by the task system
|
||||
* to signal the task *must* end. */
|
||||
bool cancelled;
|
||||
|
||||
/* created by the handler, destroyed by the user */
|
||||
void *task_data;
|
||||
|
||||
/* owned by the user */
|
||||
void *user_data;
|
||||
|
||||
/* created and destroyed by the code related to the handler */
|
||||
void *state;
|
||||
|
||||
/* created by task handler; destroyed by main loop
|
||||
* (after calling the callback) */
|
||||
char *error;
|
||||
|
||||
/* -1 = unmettered, 0-100 progress value */
|
||||
int8_t progress;
|
||||
|
||||
/* handler can modify but will be
|
||||
* free()d automatically if non-NULL. */
|
||||
char *title;
|
||||
|
||||
/* don't touch this. */
|
||||
retro_task_t *next;
|
||||
};
|
||||
|
||||
typedef struct task_finder_data
|
||||
{
|
||||
retro_task_finder_t func;
|
||||
void *userdata;
|
||||
} task_finder_data_t;
|
||||
|
||||
void task_queue_push_progress(retro_task_t *task);
|
||||
|
||||
bool task_queue_ctl(enum task_queue_ctl_state state, void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
36
libretro-common/include/retro_common.h
Normal file
36
libretro-common/include/retro_common.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_common.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_COMMON_RETRO_COMMON_H
|
||||
#define _LIBRETRO_COMMON_RETRO_COMMON_H
|
||||
|
||||
/*
|
||||
This file is designed to normalize the libretro-common compiling environment.
|
||||
It is not to be used in public API headers, as they should be designed as leanly as possible.
|
||||
Nonetheless.. in the meantime, if you do something like use ssize_t, which is not fully portable,
|
||||
in a public API, you may need this.
|
||||
*/
|
||||
|
||||
/* conditional compilation is handled inside here */
|
||||
#include <compat/msvc.h>
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_miscellaneous.h).
|
||||
@ -24,6 +24,7 @@
|
||||
#define __RARCH_MISCELLANEOUS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)
|
||||
#include <sys/timer.h>
|
||||
@ -56,8 +57,24 @@
|
||||
#include <retro_inline.h>
|
||||
|
||||
#ifndef PATH_MAX_LENGTH
|
||||
#if defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(GEKKO)
|
||||
#define PATH_MAX_LENGTH 512
|
||||
#else
|
||||
#define PATH_MAX_LENGTH 4096
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define RARCH_SCALE_BASE 256
|
||||
@ -128,13 +145,26 @@ static INLINE uint32_t prev_pow2(uint32_t v)
|
||||
return v - (v >> 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* db_to_gain:
|
||||
* @db : Decibels.
|
||||
*
|
||||
* Converts decibels to voltage gain.
|
||||
*
|
||||
* Returns: voltage gain value.
|
||||
**/
|
||||
static INLINE float db_to_gain(float db)
|
||||
{
|
||||
return powf(10.0f, db / 20.0f);
|
||||
}
|
||||
|
||||
/* Helper macros and struct to keep track of many booleans.
|
||||
* To check for multiple bits, use &&, not &.
|
||||
* For OR, | can be used. */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[8];
|
||||
} rarch_bits_t;
|
||||
} retro_bits_t;
|
||||
|
||||
#define BIT_SET(a, bit) ((a)[(bit) >> 3] |= (1 << ((bit) & 7)))
|
||||
#define BIT_CLEAR(a, bit) ((a)[(bit) >> 3] &= ~(1 << ((bit) & 7)))
|
||||
|
35
libretro-common/include/rthreads/async_job.h
Normal file
35
libretro-common/include/rthreads/async_job.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (async_job.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_ASYNC_JOB_H
|
||||
#define __LIBRETRO_SDK_ASYNC_JOB_H
|
||||
|
||||
typedef struct async_job async_job_t;
|
||||
typedef void (*async_task_t)(void *payload);
|
||||
|
||||
async_job_t *async_job_new(void);
|
||||
|
||||
void async_job_free(async_job_t *ajob);
|
||||
|
||||
int async_job_add(async_job_t *ajob, async_task_t task, void *payload);
|
||||
|
||||
#endif /* __LIBRETRO_SDK_ASYNC_JOB_H */
|
44
libretro-common/include/rthreads/rsemaphore.h
Normal file
44
libretro-common/include/rthreads/rsemaphore.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rsemaphore.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_SEMAPHORE_H
|
||||
#define __LIBRETRO_SDK_SEMAPHORE_H
|
||||
|
||||
typedef struct ssem ssem_t;
|
||||
|
||||
/**
|
||||
* ssem_create:
|
||||
* @value : initial value for the semaphore
|
||||
*
|
||||
* Create a new semaphore.
|
||||
*
|
||||
* Returns: pointer to new semaphore if successful, otherwise NULL.
|
||||
*/
|
||||
ssem_t *ssem_new(int value);
|
||||
|
||||
void ssem_free(ssem_t *semaphore);
|
||||
|
||||
void ssem_wait(ssem_t *semaphore);
|
||||
|
||||
void ssem_signal(ssem_t *semaphore);
|
||||
|
||||
#endif /* __LIBRETRO_SDK_SEMAPHORE_H */
|
75
libretro-common/include/streams/file_stream.h
Normal file
75
libretro-common/include/streams/file_stream.h
Normal file
@ -0,0 +1,75 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_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_FILE_STREAM_H
|
||||
#define __LIBRETRO_SDK_FILE_STREAM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <retro_common.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct RFILE RFILE;
|
||||
|
||||
enum
|
||||
{
|
||||
RFILE_MODE_READ = 0,
|
||||
RFILE_MODE_WRITE,
|
||||
RFILE_MODE_READ_WRITE,
|
||||
|
||||
/* There is no garantee these requests will be attended. */
|
||||
RFILE_HINT_UNBUFFERED = 1<<8,
|
||||
RFILE_HINT_MMAP = 1<<9 /* requires RFILE_MODE_READ */
|
||||
};
|
||||
|
||||
RFILE *filestream_open(const char *path, unsigned mode, ssize_t len);
|
||||
|
||||
ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence);
|
||||
|
||||
ssize_t filestream_read(RFILE *stream, void *data, size_t len);
|
||||
|
||||
ssize_t filestream_write(RFILE *stream, const void *data, size_t len);
|
||||
|
||||
ssize_t filestream_tell(RFILE *stream);
|
||||
|
||||
void filestream_rewind(RFILE *stream);
|
||||
|
||||
int filestream_close(RFILE *stream);
|
||||
|
||||
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);
|
||||
|
||||
int filestream_get_fd(RFILE *stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
461
libretro-common/queues/task_queue.c
Normal file
461
libretro-common/queues/task_queue.c
Normal file
@ -0,0 +1,461 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (task_queue.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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <queues/task_queue.h>
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
#include <rthreads/rthreads.h>
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
retro_task_t *front;
|
||||
retro_task_t *back;
|
||||
} task_queue_t;
|
||||
|
||||
struct retro_task_impl
|
||||
{
|
||||
void (*push_running)(retro_task_t *);
|
||||
void (*reset)(void);
|
||||
void (*wait)(void);
|
||||
void (*gather)(void);
|
||||
bool (*find)(retro_task_finder_t, void*);
|
||||
void (*init)(void);
|
||||
void (*deinit)(void);
|
||||
};
|
||||
|
||||
static task_queue_t tasks_running = {NULL, NULL};
|
||||
static task_queue_t tasks_finished = {NULL, NULL};
|
||||
|
||||
#ifndef RARCH_INTERNAL
|
||||
static void task_queue_msg_push(unsigned prio, unsigned duration,
|
||||
bool flush, const char *fmt, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
/* print something here */
|
||||
}
|
||||
|
||||
void task_queue_push_progress(retro_task_t *task)
|
||||
{
|
||||
if (task->title)
|
||||
{
|
||||
if (task->finished)
|
||||
{
|
||||
if (task->error)
|
||||
task_queue_msg_push(1, 60, true, "%s: %s",
|
||||
"Task failed\n", task->title);
|
||||
else
|
||||
task_queue_msg_push(1, 60, true, "100%%: %s", task->title);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (task->progress >= 0 && task->progress <= 100)
|
||||
task_queue_msg_push(1, 60, true, "%i%%: %s",
|
||||
task->progress, task->title);
|
||||
else
|
||||
task_queue_msg_push(1, 60, true, "%s...", task->title);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void task_queue_put(task_queue_t *queue, retro_task_t *task)
|
||||
{
|
||||
task->next = NULL;
|
||||
|
||||
if (queue->front)
|
||||
queue->back->next = task;
|
||||
else
|
||||
queue->front = task;
|
||||
|
||||
queue->back = task;
|
||||
}
|
||||
|
||||
static retro_task_t *task_queue_get(task_queue_t *queue)
|
||||
{
|
||||
retro_task_t *task = queue->front;
|
||||
|
||||
if (task)
|
||||
{
|
||||
queue->front = task->next;
|
||||
task->next = NULL;
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
static void retro_task_internal_gather(void)
|
||||
{
|
||||
retro_task_t *task = NULL;
|
||||
while ((task = task_queue_get(&tasks_finished)) != NULL)
|
||||
{
|
||||
task_queue_push_progress(task);
|
||||
|
||||
if (task->callback)
|
||||
task->callback(task->task_data, task->user_data, task->error);
|
||||
|
||||
if (task->error)
|
||||
free(task->error);
|
||||
|
||||
if (task->title)
|
||||
free(task->title);
|
||||
|
||||
free(task);
|
||||
}
|
||||
}
|
||||
|
||||
static void retro_task_regular_push_running(retro_task_t *task)
|
||||
{
|
||||
task_queue_put(&tasks_running, task);
|
||||
}
|
||||
|
||||
static void retro_task_regular_gather(void)
|
||||
{
|
||||
retro_task_t *task = NULL;
|
||||
retro_task_t *queue = NULL;
|
||||
retro_task_t *next = NULL;
|
||||
|
||||
while ((task = task_queue_get(&tasks_running)) != NULL)
|
||||
{
|
||||
task->next = queue;
|
||||
queue = task;
|
||||
}
|
||||
|
||||
for (task = queue; task; task = next)
|
||||
{
|
||||
next = task->next;
|
||||
task->handler(task);
|
||||
|
||||
task_queue_push_progress(task);
|
||||
|
||||
if (task->finished)
|
||||
task_queue_put(&tasks_finished, task);
|
||||
else
|
||||
retro_task_regular_push_running(task);
|
||||
}
|
||||
|
||||
retro_task_internal_gather();
|
||||
}
|
||||
|
||||
static void retro_task_regular_wait(void)
|
||||
{
|
||||
while (tasks_running.front)
|
||||
retro_task_regular_gather();
|
||||
}
|
||||
|
||||
static void retro_task_regular_reset(void)
|
||||
{
|
||||
retro_task_t *task = tasks_running.front;
|
||||
|
||||
for (; task; task = task->next)
|
||||
task->cancelled = true;
|
||||
}
|
||||
|
||||
static void retro_task_regular_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void retro_task_regular_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
static bool retro_task_regular_find(retro_task_finder_t func, void *user_data)
|
||||
{
|
||||
retro_task_t *task = tasks_running.front;
|
||||
|
||||
for (; task; task = task->next)
|
||||
{
|
||||
if (func(task, user_data))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct retro_task_impl impl_regular = {
|
||||
retro_task_regular_push_running,
|
||||
retro_task_regular_reset,
|
||||
retro_task_regular_wait,
|
||||
retro_task_regular_gather,
|
||||
retro_task_regular_find,
|
||||
retro_task_regular_init,
|
||||
retro_task_regular_deinit
|
||||
};
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
static slock_t *running_lock = NULL;
|
||||
static slock_t *finished_lock = NULL;
|
||||
static scond_t *worker_cond = NULL;
|
||||
static sthread_t *worker_thread = NULL;
|
||||
static bool worker_continue = true; /* use running_lock when touching it */
|
||||
|
||||
static void retro_task_threaded_push_running(retro_task_t *task)
|
||||
{
|
||||
slock_lock(running_lock);
|
||||
task_queue_put(&tasks_running, task);
|
||||
scond_signal(worker_cond);
|
||||
slock_unlock(running_lock);
|
||||
}
|
||||
|
||||
static void retro_task_threaded_gather(void)
|
||||
{
|
||||
retro_task_t *task = NULL;
|
||||
|
||||
slock_lock(running_lock);
|
||||
for (task = tasks_running.front; task; task = task->next)
|
||||
task_queue_push_progress(task);
|
||||
|
||||
slock_unlock(running_lock);
|
||||
|
||||
slock_lock(finished_lock);
|
||||
retro_task_internal_gather();
|
||||
slock_unlock(finished_lock);
|
||||
}
|
||||
|
||||
static void retro_task_threaded_wait(void)
|
||||
{
|
||||
bool wait = false;
|
||||
|
||||
do
|
||||
{
|
||||
retro_task_threaded_gather();
|
||||
|
||||
slock_lock(running_lock);
|
||||
wait = (tasks_running.front != NULL);
|
||||
slock_unlock(running_lock);
|
||||
} while (wait);
|
||||
}
|
||||
|
||||
static void retro_task_threaded_reset(void)
|
||||
{
|
||||
retro_task_t *task = NULL;
|
||||
|
||||
slock_lock(running_lock);
|
||||
for (task = tasks_running.front; task; task = task->next)
|
||||
task->cancelled = true;
|
||||
slock_unlock(running_lock);
|
||||
}
|
||||
|
||||
|
||||
static bool retro_task_threaded_find(
|
||||
retro_task_finder_t func, void *user_data)
|
||||
{
|
||||
retro_task_t *task = NULL;
|
||||
|
||||
slock_lock(running_lock);
|
||||
for (task = tasks_running.front; task; task = task->next)
|
||||
{
|
||||
if (func(task, user_data))
|
||||
return true;
|
||||
}
|
||||
slock_unlock(running_lock);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void threaded_worker(void *userdata)
|
||||
{
|
||||
(void)userdata;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
retro_task_t *queue = NULL;
|
||||
retro_task_t *task = NULL;
|
||||
retro_task_t *next = NULL;
|
||||
|
||||
/* pop all into a local queue,
|
||||
* tasks are in the reverse order here. */
|
||||
slock_lock(running_lock);
|
||||
|
||||
if (!worker_continue)
|
||||
break; /* should we keep running until all tasks finished? */
|
||||
|
||||
while ((task = task_queue_get(&tasks_running)) != NULL)
|
||||
{
|
||||
task->next = queue;
|
||||
queue = task;
|
||||
}
|
||||
|
||||
if (queue == NULL) /* no tasks running, lets wait a bit */
|
||||
{
|
||||
scond_wait(worker_cond, running_lock);
|
||||
slock_unlock(running_lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
slock_unlock(running_lock);
|
||||
|
||||
for (task = queue; task; task = next)
|
||||
{
|
||||
next = task->next;
|
||||
task->handler(task);
|
||||
|
||||
if (task->finished)
|
||||
{
|
||||
slock_lock(finished_lock);
|
||||
task_queue_put(&tasks_finished, task);
|
||||
slock_unlock(finished_lock);
|
||||
}
|
||||
else
|
||||
retro_task_threaded_push_running(task);
|
||||
}
|
||||
}
|
||||
|
||||
slock_unlock(running_lock);
|
||||
}
|
||||
|
||||
static void retro_task_threaded_init(void)
|
||||
{
|
||||
running_lock = slock_new();
|
||||
finished_lock = slock_new();
|
||||
worker_cond = scond_new();
|
||||
|
||||
slock_lock(running_lock);
|
||||
worker_continue = true;
|
||||
slock_unlock(running_lock);
|
||||
|
||||
worker_thread = sthread_create(threaded_worker, NULL);
|
||||
}
|
||||
|
||||
static void retro_task_threaded_deinit(void)
|
||||
{
|
||||
slock_lock(running_lock);
|
||||
worker_continue = false;
|
||||
scond_signal(worker_cond);
|
||||
slock_unlock(running_lock);
|
||||
|
||||
sthread_join(worker_thread);
|
||||
|
||||
scond_free(worker_cond);
|
||||
slock_free(running_lock);
|
||||
slock_free(finished_lock);
|
||||
|
||||
worker_thread = NULL;
|
||||
worker_cond = NULL;
|
||||
running_lock = NULL;
|
||||
finished_lock = NULL;
|
||||
}
|
||||
|
||||
static struct retro_task_impl impl_threaded = {
|
||||
retro_task_threaded_push_running,
|
||||
retro_task_threaded_reset,
|
||||
retro_task_threaded_wait,
|
||||
retro_task_threaded_gather,
|
||||
retro_task_threaded_find,
|
||||
retro_task_threaded_init,
|
||||
retro_task_threaded_deinit
|
||||
};
|
||||
#endif
|
||||
|
||||
bool task_queue_ctl(enum task_queue_ctl_state state, void *data)
|
||||
{
|
||||
static struct retro_task_impl *impl_current = NULL;
|
||||
static bool task_threaded_enable = false;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case TASK_QUEUE_CTL_DEINIT:
|
||||
if (impl_current)
|
||||
impl_current->deinit();
|
||||
impl_current = NULL;
|
||||
break;
|
||||
case TASK_QUEUE_CTL_SET_THREADED:
|
||||
task_threaded_enable = true;
|
||||
break;
|
||||
case TASK_QUEUE_CTL_UNSET_THREADED:
|
||||
task_threaded_enable = false;
|
||||
break;
|
||||
case TASK_QUEUE_CTL_IS_THREADED:
|
||||
return task_threaded_enable;
|
||||
case TASK_QUEUE_CTL_INIT:
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
bool *boolean_val = (bool*)data;
|
||||
#endif
|
||||
|
||||
impl_current = &impl_regular;
|
||||
#ifdef HAVE_THREADS
|
||||
if (*boolean_val)
|
||||
{
|
||||
task_queue_ctl(TASK_QUEUE_CTL_SET_THREADED, NULL);
|
||||
impl_current = &impl_threaded;
|
||||
}
|
||||
#endif
|
||||
|
||||
impl_current->init();
|
||||
}
|
||||
break;
|
||||
case TASK_QUEUE_CTL_FIND:
|
||||
{
|
||||
task_finder_data_t *find_data = (task_finder_data_t*)data;
|
||||
if (!impl_current->find(find_data->func, find_data->userdata))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case TASK_QUEUE_CTL_CHECK:
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
bool current_threaded = (impl_current == &impl_threaded);
|
||||
bool want_threaded =
|
||||
task_queue_ctl(TASK_QUEUE_CTL_IS_THREADED, NULL);
|
||||
|
||||
if (want_threaded != current_threaded)
|
||||
task_queue_ctl(TASK_QUEUE_CTL_DEINIT, NULL);
|
||||
|
||||
if (!impl_current)
|
||||
task_queue_ctl(TASK_QUEUE_CTL_INIT, NULL);
|
||||
#endif
|
||||
|
||||
impl_current->gather();
|
||||
}
|
||||
break;
|
||||
case TASK_QUEUE_CTL_PUSH:
|
||||
{
|
||||
/* The lack of NULL checks in the following functions
|
||||
* is proposital to ensure correct control flow by the users. */
|
||||
retro_task_t *task = (retro_task_t*)data;
|
||||
impl_current->push_running(task);
|
||||
break;
|
||||
}
|
||||
case TASK_QUEUE_CTL_RESET:
|
||||
impl_current->reset();
|
||||
break;
|
||||
case TASK_QUEUE_CTL_WAIT:
|
||||
impl_current->wait();
|
||||
break;
|
||||
case TASK_QUEUE_CTL_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
149
libretro-common/rthreads/async_job.c
Normal file
149
libretro-common/rthreads/async_job.c
Normal file
@ -0,0 +1,149 @@
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (async_job.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 <rthreads/rthreads.h>
|
||||
#include <rthreads/rsemaphore.h>
|
||||
#include <rthreads/async_job.h>
|
||||
|
||||
typedef struct async_job_node async_job_node_t;
|
||||
|
||||
struct async_job_node
|
||||
{
|
||||
async_task_t task;
|
||||
void *payload;
|
||||
async_job_node_t *next;
|
||||
};
|
||||
|
||||
struct async_job
|
||||
{
|
||||
async_job_node_t *first;
|
||||
async_job_node_t *last;
|
||||
volatile int finish;
|
||||
slock_t *lock;
|
||||
ssem_t *sem;
|
||||
sthread_t* thread;
|
||||
};
|
||||
|
||||
static void async_job_processor(void *userdata)
|
||||
{
|
||||
async_job_node_t *node = NULL;
|
||||
async_job_t *ajob = (async_job_t*)userdata;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ssem_wait(ajob->sem);
|
||||
|
||||
if (ajob->finish)
|
||||
return;
|
||||
|
||||
slock_lock(ajob->lock);
|
||||
|
||||
node = ajob->first;
|
||||
ajob->first = node->next;
|
||||
|
||||
slock_unlock(ajob->lock);
|
||||
|
||||
node->task(node->payload);
|
||||
free((void*)node);
|
||||
}
|
||||
}
|
||||
|
||||
async_job_t *async_job_new(void)
|
||||
{
|
||||
async_job_t *ajob = (async_job_t*)calloc(1, sizeof(*ajob));
|
||||
|
||||
if (!ajob)
|
||||
return NULL;
|
||||
|
||||
ajob->lock = slock_new();
|
||||
|
||||
if (!ajob->lock)
|
||||
goto error;
|
||||
|
||||
ajob->sem = ssem_new(0);
|
||||
|
||||
if (!ajob->sem)
|
||||
goto error;
|
||||
|
||||
ajob->thread = sthread_create(async_job_processor, (void*)ajob);
|
||||
|
||||
if (!ajob->thread)
|
||||
goto error;
|
||||
|
||||
return ajob;
|
||||
|
||||
error:
|
||||
if (ajob->lock)
|
||||
slock_free(ajob->lock);
|
||||
ajob->lock = NULL;
|
||||
if (ajob->sem)
|
||||
ssem_free(ajob->sem);
|
||||
if (ajob)
|
||||
free((void*)ajob);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void async_job_free(async_job_t *ajob)
|
||||
{
|
||||
if (!ajob)
|
||||
return;
|
||||
|
||||
ajob->finish = 1;
|
||||
ssem_signal(ajob->sem);
|
||||
sthread_join(ajob->thread);
|
||||
ssem_free(ajob->sem);
|
||||
|
||||
free((void*)ajob);
|
||||
}
|
||||
|
||||
int async_job_add(async_job_t *ajob, async_task_t task, void *payload)
|
||||
{
|
||||
async_job_node_t *node;
|
||||
|
||||
if (!ajob)
|
||||
return -1;
|
||||
|
||||
node = (async_job_node_t*)calloc(1, sizeof(*node));
|
||||
|
||||
if (!node)
|
||||
return -1;
|
||||
|
||||
node->task = task;
|
||||
node->payload = payload;
|
||||
|
||||
slock_lock(ajob->lock);
|
||||
|
||||
if (ajob->first)
|
||||
{
|
||||
ajob->last->next = node;
|
||||
ajob->last = node;
|
||||
}
|
||||
else
|
||||
ajob->first = ajob->last = node;
|
||||
|
||||
slock_unlock(ajob->lock);
|
||||
ssem_signal(ajob->sem);
|
||||
|
||||
return 0;
|
||||
}
|
116
libretro-common/rthreads/rsemaphore.c
Normal file
116
libretro-common/rthreads/rsemaphore.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright 2005 Allen B. Downey
|
||||
|
||||
This file contains an example program from The Little Book of
|
||||
Semaphores, available from Green Tea Press, greenteapress.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses/gpl.html
|
||||
or write to the Free Software Foundation, Inc., 51 Franklin St,
|
||||
Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Code taken from http://greenteapress.com/semaphores/semaphore.c
|
||||
* and changed to use libretro-common's mutexes and conditions.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rthreads/rthreads.h>
|
||||
#include <rthreads/rsemaphore.h>
|
||||
|
||||
struct ssem
|
||||
{
|
||||
int value;
|
||||
int wakeups;
|
||||
slock_t *mutex;
|
||||
scond_t *cond;
|
||||
};
|
||||
|
||||
ssem_t *ssem_new(int value)
|
||||
{
|
||||
ssem_t *semaphore = (ssem_t*)calloc(1, sizeof(*semaphore));
|
||||
|
||||
if (!semaphore)
|
||||
goto error;
|
||||
|
||||
semaphore->value = value;
|
||||
semaphore->wakeups = 0;
|
||||
semaphore->mutex = slock_new();
|
||||
|
||||
if (!semaphore->mutex)
|
||||
goto error;
|
||||
|
||||
semaphore->cond = scond_new();
|
||||
|
||||
if (!semaphore->cond)
|
||||
goto error;
|
||||
|
||||
return semaphore;
|
||||
|
||||
error:
|
||||
if (semaphore->mutex)
|
||||
slock_free(semaphore->mutex);
|
||||
semaphore->mutex = NULL;
|
||||
if (semaphore)
|
||||
free((void*)semaphore);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ssem_free(ssem_t *semaphore)
|
||||
{
|
||||
if (!semaphore)
|
||||
return;
|
||||
|
||||
scond_free(semaphore->cond);
|
||||
slock_free(semaphore->mutex);
|
||||
free((void*)semaphore);
|
||||
}
|
||||
|
||||
void ssem_wait(ssem_t *semaphore)
|
||||
{
|
||||
if (!semaphore)
|
||||
return;
|
||||
|
||||
slock_lock(semaphore->mutex);
|
||||
semaphore->value--;
|
||||
|
||||
if (semaphore->value < 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
scond_wait(semaphore->cond, semaphore->mutex);
|
||||
}while (semaphore->wakeups < 1);
|
||||
|
||||
semaphore->wakeups--;
|
||||
}
|
||||
|
||||
slock_unlock(semaphore->mutex);
|
||||
}
|
||||
|
||||
void ssem_signal(ssem_t *semaphore)
|
||||
{
|
||||
if (!semaphore)
|
||||
return;
|
||||
|
||||
slock_lock(semaphore->mutex);
|
||||
semaphore->value++;
|
||||
|
||||
if (semaphore->value <= 0)
|
||||
{
|
||||
semaphore->wakeups++;
|
||||
scond_signal(semaphore->cond);
|
||||
}
|
||||
|
||||
slock_unlock(semaphore->mutex);
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <rthreads/rthreads.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
@ -104,34 +105,37 @@ static void *thread_wrap(void *data_)
|
||||
*/
|
||||
sthread_t *sthread_create(void (*thread_func)(void*), void *userdata)
|
||||
{
|
||||
sthread_t *thread = (sthread_t*)calloc(1, sizeof(*thread));
|
||||
struct thread_data *data;
|
||||
bool thread_created = false;
|
||||
struct thread_data *data = NULL;
|
||||
sthread_t *thread = (sthread_t*)calloc(1, sizeof(*thread));
|
||||
|
||||
if (!thread)
|
||||
return NULL;
|
||||
|
||||
data = (struct thread_data*)calloc(1, sizeof(*data));
|
||||
data = (struct thread_data*)calloc(1, sizeof(*data));
|
||||
if (!data)
|
||||
{
|
||||
free(thread);
|
||||
return NULL;
|
||||
}
|
||||
goto error;
|
||||
|
||||
data->func = thread_func;
|
||||
data->userdata = userdata;
|
||||
|
||||
#ifdef _WIN32
|
||||
thread->thread = CreateThread(NULL, 0, thread_wrap, data, 0, NULL);
|
||||
if (!thread->thread)
|
||||
thread_created = thread->thread;
|
||||
#else
|
||||
if (pthread_create(&thread->id, NULL, thread_wrap, data) < 0)
|
||||
thread_created = pthread_create(&thread->id, NULL, thread_wrap, data) == 0;
|
||||
#endif
|
||||
{
|
||||
free(data);
|
||||
free(thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!thread_created)
|
||||
goto error;
|
||||
|
||||
return thread;
|
||||
|
||||
error:
|
||||
if (data)
|
||||
free(data);
|
||||
free(thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,22 +192,26 @@ void sthread_join(sthread_t *thread)
|
||||
**/
|
||||
slock_t *slock_new(void)
|
||||
{
|
||||
slock_t *lock = (slock_t*)calloc(1, sizeof(*lock));
|
||||
bool mutex_created = false;
|
||||
slock_t *lock = (slock_t*)calloc(1, sizeof(*lock));
|
||||
if (!lock)
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
lock->lock = CreateMutex(NULL, FALSE, NULL);
|
||||
if (!lock->lock)
|
||||
lock->lock = CreateMutex(NULL, FALSE, NULL);
|
||||
mutex_created = lock->lock;
|
||||
#else
|
||||
if (pthread_mutex_init(&lock->lock, NULL) < 0)
|
||||
mutex_created = (pthread_mutex_init(&lock->lock, NULL) == 0);
|
||||
#endif
|
||||
{
|
||||
free(lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!mutex_created)
|
||||
goto error;
|
||||
|
||||
return lock;
|
||||
|
||||
error:
|
||||
free(lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -268,22 +276,27 @@ void slock_unlock(slock_t *lock)
|
||||
**/
|
||||
scond_t *scond_new(void)
|
||||
{
|
||||
scond_t *cond = (scond_t*)calloc(1, sizeof(*cond));
|
||||
bool event_created = false;
|
||||
scond_t *cond = (scond_t*)calloc(1, sizeof(*cond));
|
||||
|
||||
if (!cond)
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
cond->event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (!cond->event)
|
||||
cond->event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
event_created = cond->event;
|
||||
#else
|
||||
if (pthread_cond_init(&cond->cond, NULL) < 0)
|
||||
event_created = (pthread_cond_init(&cond->cond, NULL) == 0);
|
||||
#endif
|
||||
{
|
||||
free(cond);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!event_created)
|
||||
goto error;
|
||||
|
||||
return cond;
|
||||
|
||||
error:
|
||||
free(cond);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
538
libretro-common/streams/file_stream.c
Normal file
538
libretro-common/streams/file_stream.c
Normal file
@ -0,0 +1,538 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# ifdef _MSC_VER
|
||||
# define setmode _setmode
|
||||
# endif
|
||||
# ifdef _XBOX
|
||||
# include <xtl.h>
|
||||
# define INVALID_FILE_ATTRIBUTES -1
|
||||
# else
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
# include <direct.h>
|
||||
# include <windows.h>
|
||||
# endif
|
||||
#elif defined(VITA)
|
||||
# include <psp2/io/fcntl.h>
|
||||
# include <psp2/io/dirent.h>
|
||||
|
||||
#define PSP_O_RDONLY PSP2_O_RDONLY
|
||||
#define PSP_O_RDWR PSP2_O_RDWR
|
||||
#define PSP_O_CREAT PSP2_O_CREAT
|
||||
#define PSP_O_WRONLY PSP2_O_WRONLY
|
||||
#define PSP_O_TRUNC PSP2_O_TRUNC
|
||||
#else
|
||||
# if defined(PSP)
|
||||
# include <pspiofilemgr.h>
|
||||
# endif
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <dirent.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
#include <cell/cell_fs.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <streams/file_stream.h>
|
||||
#include <memmap.h>
|
||||
|
||||
#if 1
|
||||
#define HAVE_BUFFERED_IO 1
|
||||
#endif
|
||||
|
||||
struct RFILE
|
||||
{
|
||||
unsigned hints;
|
||||
#if defined(PSP) || defined(VITA)
|
||||
SceUID fd;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
int fd;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
FILE *fp;
|
||||
#endif
|
||||
#if defined(HAVE_MMAP)
|
||||
uint8_t *mapped;
|
||||
uint64_t mappos;
|
||||
uint64_t mapsize;
|
||||
#endif
|
||||
int fd;
|
||||
#endif
|
||||
};
|
||||
|
||||
int filestream_get_fd(RFILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return -1;
|
||||
#if defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__)
|
||||
return stream->fd;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
return fileno(stream->fp);
|
||||
#endif
|
||||
return stream->fd;
|
||||
#endif
|
||||
}
|
||||
|
||||
RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
|
||||
{
|
||||
int flags = 0;
|
||||
int mode_int = 0;
|
||||
const char *mode_str = NULL;
|
||||
RFILE *stream = (RFILE*)calloc(1, sizeof(*stream));
|
||||
|
||||
if (!stream)
|
||||
return NULL;
|
||||
|
||||
(void)mode_str;
|
||||
(void)mode_int;
|
||||
(void)flags;
|
||||
|
||||
stream->hints = mode;
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
if (stream->hints & RFILE_HINT_MMAP && (stream->hints & 0xff) == RFILE_MODE_READ)
|
||||
stream->hints |= RFILE_HINT_UNBUFFERED;
|
||||
else
|
||||
#endif
|
||||
stream->hints &= ~RFILE_HINT_MMAP;
|
||||
|
||||
switch (mode & 0xff)
|
||||
{
|
||||
case RFILE_MODE_READ:
|
||||
#if defined(VITA) || defined(PSP)
|
||||
mode_int = 0777;
|
||||
flags = PSP_O_RDONLY;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
mode_int = 0777;
|
||||
flags = CELL_FS_O_RDONLY;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
mode_str = "rb";
|
||||
#endif
|
||||
/* No "else" here */
|
||||
flags = O_RDONLY;
|
||||
#endif
|
||||
break;
|
||||
case RFILE_MODE_WRITE:
|
||||
#if defined(VITA) || defined(PSP)
|
||||
mode_int = 0777;
|
||||
flags = PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
mode_int = 0777;
|
||||
flags = CELL_FS_O_CREAT | CELL_FS_O_WRONLY | CELL_FS_O_TRUNC;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
mode_str = "wb";
|
||||
#endif
|
||||
else
|
||||
{
|
||||
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
#ifndef _WIN32
|
||||
flags |= S_IRUSR | S_IWUSR;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case RFILE_MODE_READ_WRITE:
|
||||
#if defined(VITA) || defined(PSP)
|
||||
mode_int = 0777;
|
||||
flags = PSP_O_RDWR;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
mode_int = 0777;
|
||||
flags = CELL_FS_O_RDWR;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
mode_str = "w+";
|
||||
#endif
|
||||
else
|
||||
{
|
||||
flags = O_RDWR;
|
||||
#ifdef _WIN32
|
||||
flags |= O_BINARY;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(VITA) || defined(PSP)
|
||||
stream->fd = sceIoOpen(path, flags, mode_int);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
cellFsOpen(path, flags, &stream->fd, NULL, 0);
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
{
|
||||
stream->fp = fopen(path, mode_str);
|
||||
if (!stream->fp)
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
stream->fd = open(path, flags);
|
||||
if (stream->fd == -1)
|
||||
goto error;
|
||||
#ifdef HAVE_MMAP
|
||||
if (stream->hints & RFILE_HINT_MMAP)
|
||||
{
|
||||
stream->mappos = 0;
|
||||
stream->mapped = NULL;
|
||||
stream->mapsize = filestream_seek(stream, 0, SEEK_END);
|
||||
|
||||
if (stream->mapsize == (uint64_t)-1)
|
||||
goto error;
|
||||
|
||||
filestream_rewind(stream);
|
||||
|
||||
stream->mapped = (uint8_t*)mmap((void*)0, stream->mapsize, PROT_READ, MAP_SHARED, stream->fd, 0);
|
||||
|
||||
if (stream->mapped == MAP_FAILED)
|
||||
stream->hints &= ~RFILE_HINT_MMAP;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__)
|
||||
if (stream->fd == -1)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
return stream;
|
||||
|
||||
error:
|
||||
filestream_close(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence)
|
||||
{
|
||||
int ret = 0;
|
||||
if (!stream)
|
||||
return -1;
|
||||
|
||||
(void)ret;
|
||||
|
||||
#if defined(VITA) || defined(PSP)
|
||||
ret = sceIoLseek(stream->fd, (SceOff)offset, whence);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
uint64_t pos = 0;
|
||||
if (cellFsLseek(stream->fd, offset, whence, &pos) != CELL_FS_SUCCEEDED)
|
||||
return -1;
|
||||
return 0;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
return fseek(stream->fp, (long)offset, whence);
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_MMAP
|
||||
/* Need to check stream->mapped because this function is
|
||||
* called in filestream_open() */
|
||||
if (stream->mapped && stream->hints & RFILE_HINT_MMAP)
|
||||
{
|
||||
/* fseek() returns error on under/overflow but allows cursor > EOF for
|
||||
read-only file descriptors. */
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
if (offset < 0)
|
||||
return -1;
|
||||
|
||||
stream->mappos = offset;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
if ((offset < 0 && stream->mappos + offset > stream->mappos) ||
|
||||
(offset > 0 && stream->mappos + offset < stream->mappos))
|
||||
return -1;
|
||||
|
||||
stream->mappos += offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
if (stream->mapsize + offset < stream->mapsize)
|
||||
return -1;
|
||||
|
||||
stream->mappos = stream->mapsize + offset;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return stream->mappos;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = lseek(stream->fd, offset, whence);
|
||||
return ret < 0 ? -1 : ret;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t filestream_tell(RFILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return -1;
|
||||
#if defined(VITA) || defined(PSP)
|
||||
return sceIoLseek(stream->fd, 0, SEEK_CUR);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
uint64_t pos = 0;
|
||||
if (cellFsLseek(stream->fd, 0, CELL_FS_SEEK_CUR, &pos) != CELL_FS_SUCCEEDED)
|
||||
return -1;
|
||||
return 0;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
return ftell(stream->fp);
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_MMAP
|
||||
/* Need to check stream->mapped because this function
|
||||
* is called in filestream_open() */
|
||||
if (stream->mapped && stream->hints & RFILE_HINT_MMAP)
|
||||
return stream->mappos;
|
||||
else
|
||||
#endif
|
||||
return lseek(stream->fd, 0, SEEK_CUR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void filestream_rewind(RFILE *stream)
|
||||
{
|
||||
filestream_seek(stream, 0L, SEEK_SET);
|
||||
}
|
||||
|
||||
ssize_t filestream_read(RFILE *stream, void *s, size_t len)
|
||||
{
|
||||
if (!stream || !s)
|
||||
return -1;
|
||||
#if defined(VITA) || defined(PSP)
|
||||
return sceIoRead(stream->fd, s, len);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
uint64_t bytes_written;
|
||||
if (cellFsRead(stream->fd, s, len, &bytes_written) != CELL_FS_SUCCEEDED)
|
||||
return -1;
|
||||
return bytes_written;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
return fread(s, 1, len, stream->fp);
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_MMAP
|
||||
if (stream->hints & RFILE_HINT_MMAP)
|
||||
{
|
||||
if (stream->mappos > stream->mapsize)
|
||||
return -1;
|
||||
|
||||
if (stream->mappos + len > stream->mapsize)
|
||||
len = stream->mapsize - stream->mappos;
|
||||
|
||||
memcpy(s, &stream->mapped[stream->mappos], len);
|
||||
stream->mappos += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return read(stream->fd, s, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t filestream_write(RFILE *stream, const void *s, size_t len)
|
||||
{
|
||||
if (!stream)
|
||||
return -1;
|
||||
#if defined(VITA) || defined(PSP)
|
||||
return sceIoWrite(stream->fd, s, len);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
uint64_t bytes_written;
|
||||
if (cellFsWrite(stream->fd, s, len, &bytes_written) != CELL_FS_SUCCEEDED)
|
||||
return -1;
|
||||
return bytes_written;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
return fwrite(s, 1, len, stream->fp);
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_MMAP
|
||||
if (stream->hints & RFILE_HINT_MMAP)
|
||||
return -1;
|
||||
else
|
||||
#endif
|
||||
return write(stream->fd, s, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
int filestream_close(RFILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return -1;
|
||||
|
||||
#if defined(VITA) || defined(PSP)
|
||||
if (stream->fd > 0)
|
||||
sceIoClose(stream->fd);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
if (stream->fd > 0)
|
||||
cellFsClose(stream->fd);
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
{
|
||||
if (stream->fp)
|
||||
fclose(stream->fp);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_MMAP
|
||||
if (stream->hints & RFILE_HINT_MMAP)
|
||||
munmap(stream->mapped, stream->mapsize);
|
||||
#endif
|
||||
|
||||
if (stream->fd > 0)
|
||||
close(stream->fd);
|
||||
#endif
|
||||
free(stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* filestream_read_file:
|
||||
* @path : path to file.
|
||||
* @buf : buffer to allocate and read the contents of the
|
||||
* file into. Needs to be freed manually.
|
||||
*
|
||||
* Read the contents of a file into @buf.
|
||||
*
|
||||
* Returns: number of items read, -1 on error.
|
||||
*/
|
||||
int filestream_read_file(const char *path, void **buf, ssize_t *len)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
ssize_t content_buf_size = 0;
|
||||
void *content_buf = NULL;
|
||||
RFILE *file = filestream_open(path, RFILE_MODE_READ, -1);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
fprintf(stderr, "%s: Failed to open %s: %s\n", __FUNCTION__, path, strerror(errno));
|
||||
#else
|
||||
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
|
||||
#endif
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (filestream_seek(file, 0, SEEK_END) != 0)
|
||||
goto error;
|
||||
|
||||
content_buf_size = filestream_tell(file);
|
||||
if (content_buf_size < 0)
|
||||
goto error;
|
||||
|
||||
filestream_rewind(file);
|
||||
|
||||
content_buf = malloc(content_buf_size + 1);
|
||||
|
||||
if (!content_buf)
|
||||
goto error;
|
||||
|
||||
ret = filestream_read(file, content_buf, content_buf_size);
|
||||
if (ret < 0)
|
||||
{
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
fprintf(stderr, "%s: Failed to read %s: %s\n", __FUNCTION__, path, strerror(errno));
|
||||
#else
|
||||
fprintf(stderr, "Failed to read %s: %s\n", path, strerror(errno));
|
||||
#endif
|
||||
goto error;
|
||||
}
|
||||
|
||||
filestream_close(file);
|
||||
|
||||
*buf = content_buf;
|
||||
|
||||
/* Allow for easy reading of strings to be safe.
|
||||
* Will only work with sane character formatting (Unix). */
|
||||
((char*)content_buf)[content_buf_size] = '\0';
|
||||
|
||||
if (len)
|
||||
*len = ret;
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
if (file)
|
||||
filestream_close(file);
|
||||
if (content_buf)
|
||||
free(content_buf);
|
||||
if (len)
|
||||
*len = -1;
|
||||
*buf = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* filestream_write_file:
|
||||
* @path : path to file.
|
||||
* @data : contents to write to the file.
|
||||
* @size : size of the contents.
|
||||
*
|
||||
* Writes data to a file.
|
||||
*
|
||||
* Returns: true (1) on success, false (0) otherwise.
|
||||
*/
|
||||
bool filestream_write_file(const char *path, const void *data, ssize_t size)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
RFILE *file = filestream_open(path, RFILE_MODE_WRITE, -1);
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
ret = filestream_write(file, data, size);
|
||||
filestream_close(file);
|
||||
|
||||
return (ret == size);
|
||||
}
|
@ -27,7 +27,7 @@
|
||||
|
||||
FileStream::FileStream(const char *path, const int mode): OpenedMode(mode)
|
||||
{
|
||||
fp = retro_fopen(path, (mode == MODE_WRITE) ? RFILE_MODE_WRITE : RFILE_MODE_READ, -1);
|
||||
fp = filestream_open(path, (mode == MODE_WRITE) ? RFILE_MODE_WRITE : RFILE_MODE_READ, -1);
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
@ -68,28 +68,28 @@ uint64_t FileStream::read(void *data, uint64_t count, bool error_on_eos)
|
||||
{
|
||||
if (!fp)
|
||||
return 0;
|
||||
return retro_fread(fp, data, count);
|
||||
return filestream_read(fp, data, count);
|
||||
}
|
||||
|
||||
void FileStream::write(const void *data, uint64_t count)
|
||||
{
|
||||
if (!fp)
|
||||
return;
|
||||
retro_fwrite(fp, data, count);
|
||||
filestream_write(fp, data, count);
|
||||
}
|
||||
|
||||
void FileStream::seek(int64_t offset, int whence)
|
||||
{
|
||||
if (!fp)
|
||||
return;
|
||||
retro_fseek(fp, offset, whence);
|
||||
filestream_seek(fp, offset, whence);
|
||||
}
|
||||
|
||||
int64_t FileStream::tell(void)
|
||||
{
|
||||
if (!fp)
|
||||
return -1;
|
||||
return retro_ftell(fp);
|
||||
return filestream_tell(fp);
|
||||
}
|
||||
|
||||
int64_t FileStream::size(void)
|
||||
@ -104,5 +104,5 @@ void FileStream::close(void)
|
||||
{
|
||||
if (!fp)
|
||||
return;
|
||||
retro_fclose(fp);
|
||||
filestream_close(fp);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef __MDFN_FILESTREAM_H
|
||||
#define __MDFN_FILESTREAM_H
|
||||
|
||||
#include <retro_file.h>
|
||||
#include <streams/file_stream.h>
|
||||
#include <retro_stat.h>
|
||||
|
||||
#include "Stream.h"
|
||||
|
Loading…
Reference in New Issue
Block a user