mirror of
https://github.com/libretro/gambatte-libretro.git
synced 2024-11-23 07:49:48 +00:00
style cleanup, use libretro-common string and file I/O functions
This commit is contained in:
parent
8ec4084a59
commit
fddcf2a166
@ -1,4 +1,4 @@
|
|||||||
INCFLAGS := -I$(CORE_DIR) -I$(CORE_DIR)/../include -I$(CORE_DIR)/../../common -I$(CORE_DIR)/../../common/resample -I$(CORE_DIR)/../libretro
|
INCFLAGS := -I$(CORE_DIR) -I$(CORE_DIR)/../include -I$(CORE_DIR)/../../common -I$(CORE_DIR)/../../common/resample -I$(CORE_DIR)/../libretro -I$(CORE_DIR)/../libretro-common/include
|
||||||
|
|
||||||
SOURCES_CXX := $(CORE_DIR)/bootloader.cpp \
|
SOURCES_CXX := $(CORE_DIR)/bootloader.cpp \
|
||||||
$(CORE_DIR)/cpu.cpp \
|
$(CORE_DIR)/cpu.cpp \
|
||||||
@ -34,4 +34,8 @@ ifeq ($(HAVE_NETWORK),1)
|
|||||||
SOURCES_CXX += $(CORE_DIR)/../libretro/net_serial.cpp
|
SOURCES_CXX += $(CORE_DIR)/../libretro/net_serial.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SOURCES_C := $(CORE_DIR)/../libretro/blipper.c
|
SOURCES_C := $(CORE_DIR)/../libretro/blipper.c \
|
||||||
|
$(CORE_DIR)/../libretro-common/streams/file_stream.c \
|
||||||
|
$(CORE_DIR)/../libretro-common/string/stdstring.c
|
||||||
|
|
||||||
|
INCFLAGS := -I$(CORE_DIR) -I$(CORE_DIR)/../include -I$(CORE_DIR)/../../common -I$(CORE_DIR)/../../common/resample -I$(CORE_DIR)/../libretro -I$(CORE_DIR)/../libretro-common/include
|
||||||
|
@ -81,12 +81,12 @@ public:
|
|||||||
* @param colorNum 0 <= colorNum < 4
|
* @param colorNum 0 <= colorNum < 4
|
||||||
*/
|
*/
|
||||||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32);
|
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32);
|
||||||
|
|
||||||
/** Sets the callback used for getting input state. */
|
/** Sets the callback used for getting input state. */
|
||||||
void setInputGetter(InputGetter *getInput);
|
void setInputGetter(InputGetter *getInput);
|
||||||
|
|
||||||
/** Sets the callback used for getting the bootloader data. */
|
/** Sets the callback used for getting the bootloader data. */
|
||||||
void setBootloaderGetter(bool (*getter)(void* userdata, bool isgbc, uint8_t* data, uint32_t buf_size));
|
void setBootloaderGetter(bool (*getter)(void *userdata, bool isgbc, uint8_t *data, uint32_t buf_size));
|
||||||
|
|
||||||
#ifdef HAVE_NETWORK
|
#ifdef HAVE_NETWORK
|
||||||
/** Sets the callback used for transferring serial data. */
|
/** Sets the callback used for transferring serial data. */
|
||||||
|
39
libgambatte/libretro-common/include/boolean.h
Normal file
39
libgambatte/libretro-common/include/boolean.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* Copyright (C) 2010-2017 The RetroArch team
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
* The following license statement only applies to this file (boolean.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_BOOLEAN_H
|
||||||
|
#define __LIBRETRO_SDK_BOOLEAN_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && !defined(SN_TARGET_PS3)
|
||||||
|
/* Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant. */
|
||||||
|
#define bool unsigned char
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#else
|
||||||
|
#include <stdbool.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
49
libgambatte/libretro-common/include/memmap.h
Normal file
49
libgambatte/libretro-common/include/memmap.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* Copyright (C) 2010-2017 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) || defined(WIIU)
|
||||||
|
/* 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
|
108
libgambatte/libretro-common/include/retro_common_api.h
Normal file
108
libgambatte/libretro-common/include/retro_common_api.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/* Copyright (C) 2010-2017 The RetroArch team
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
* The following license statement only applies to this file (retro_common_api.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_API_H
|
||||||
|
#define _LIBRETRO_COMMON_RETRO_COMMON_API_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file is designed to normalize the libretro-common compiling environment
|
||||||
|
for public API headers. This should be leaner than a normal compiling environment,
|
||||||
|
since it gets #included into other project's sources.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------------------ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ordinarily we want to put #ifdef __cplusplus extern "C" in C library
|
||||||
|
headers to enable them to get used by c++ sources.
|
||||||
|
However, we want to support building this library as C++ as well, so a
|
||||||
|
special technique is called for.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RETRO_BEGIN_DECLS
|
||||||
|
#define RETRO_END_DECLS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#ifdef CXX_BUILD
|
||||||
|
/* build wants everything to be built as c++, so no extern "C" */
|
||||||
|
#else
|
||||||
|
#undef RETRO_BEGIN_DECLS
|
||||||
|
#undef RETRO_END_DECLS
|
||||||
|
#define RETRO_BEGIN_DECLS extern "C" {
|
||||||
|
#define RETRO_END_DECLS }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* header is included by a C source file, so no extern "C" */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
IMO, this non-standard ssize_t should not be used.
|
||||||
|
However, it's a good example of how to handle something like this.
|
||||||
|
*/
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#ifndef HAVE_SSIZE_T
|
||||||
|
#define HAVE_SSIZE_T
|
||||||
|
#if defined(_WIN64)
|
||||||
|
typedef __int64 ssize_t;
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
typedef int ssize_t;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#elif defined(__MACH__)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define STRING_REP_INT64 "%I64u"
|
||||||
|
#define STRING_REP_UINT64 "%I64u"
|
||||||
|
#define STRING_REP_ULONG "%Iu"
|
||||||
|
#elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L && !defined(VITA)
|
||||||
|
#define STRING_REP_INT64 "%llu"
|
||||||
|
#define STRING_REP_UINT64 "%llu"
|
||||||
|
#define STRING_REP_ULONG "%zu"
|
||||||
|
#else
|
||||||
|
#define STRING_REP_INT64 "%llu"
|
||||||
|
#define STRING_REP_UINT64 "%llu"
|
||||||
|
#define STRING_REP_ULONG "%lu"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
I would like to see retro_inline.h moved in here; possibly boolean too.
|
||||||
|
|
||||||
|
rationale: these are used in public APIs, and it is easier to find problems
|
||||||
|
and write code that works the first time portably when theyre included uniformly
|
||||||
|
than to do the analysis from scratch each time you think you need it, for each feature.
|
||||||
|
|
||||||
|
Moreover it helps force you to make hard decisions: if you EVER bring in boolean.h,
|
||||||
|
then you should pay the price everywhere, so you can see how much grief it will cause.
|
||||||
|
|
||||||
|
Of course, another school of thought is that you should do as little damage as possible
|
||||||
|
in as few places as possible...
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* _LIBRETRO_COMMON_RETRO_COMMON_API_H */
|
||||||
|
#endif
|
39
libgambatte/libretro-common/include/retro_inline.h
Normal file
39
libgambatte/libretro-common/include/retro_inline.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* Copyright (C) 2010-2017 The RetroArch team
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
* The following license statement only applies to this file (retro_inline.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_INLINE_H
|
||||||
|
#define __LIBRETRO_SDK_INLINE_H
|
||||||
|
|
||||||
|
#ifndef INLINE
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(__INTEL_COMPILER)
|
||||||
|
#define INLINE __inline
|
||||||
|
#elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
|
||||||
|
#define INLINE inline
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define INLINE __inline__
|
||||||
|
#else
|
||||||
|
#define INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
230
libgambatte/libretro-common/include/retro_miscellaneous.h
Normal file
230
libgambatte/libretro-common/include/retro_miscellaneous.h
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
/* Copyright (C) 2010-2017 The RetroArch team
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
* The following license statement only applies to this file (retro_miscellaneous.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 __RARCH_MISCELLANEOUS_H
|
||||||
|
#define __RARCH_MISCELLANEOUS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)
|
||||||
|
#include <sys/timer.h>
|
||||||
|
#elif defined(XENON)
|
||||||
|
#include <time/time.h>
|
||||||
|
#elif defined(GEKKO) || defined(__PSL1GHT__) || defined(__QNX__)
|
||||||
|
#include <unistd.h>
|
||||||
|
#elif defined(WIIU)
|
||||||
|
#include <wiiu/os/thread.h>
|
||||||
|
#elif defined(PSP)
|
||||||
|
#include <pspthreadman.h>
|
||||||
|
#elif defined(VITA)
|
||||||
|
#include <psp2/kernel/threadmgr.h>
|
||||||
|
#elif defined(_3DS)
|
||||||
|
#include <3ds.h>
|
||||||
|
#else
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(_XBOX)
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#elif defined(_WIN32) && defined(_XBOX)
|
||||||
|
#include <Xtl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <compat/msvc.h>
|
||||||
|
#endif
|
||||||
|
#include <retro_inline.h>
|
||||||
|
|
||||||
|
#ifndef PATH_MAX_LENGTH
|
||||||
|
#if defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(GEKKO)|| defined(WIIU)
|
||||||
|
#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
|
||||||
|
|
||||||
|
#ifdef DJGPP
|
||||||
|
#define timespec timeval
|
||||||
|
#define tv_nsec tv_usec
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
extern int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
|
||||||
|
|
||||||
|
static int nanosleepDOS(const struct timespec *rqtp, struct timespec *rmtp)
|
||||||
|
{
|
||||||
|
usleep(1000000 * rqtp->tv_sec + rqtp->tv_nsec / 1000);
|
||||||
|
|
||||||
|
if (rmtp)
|
||||||
|
rmtp->tv_sec = rmtp->tv_nsec=0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define nanosleep nanosleepDOS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retro_sleep:
|
||||||
|
* @msec : amount in milliseconds to sleep
|
||||||
|
*
|
||||||
|
* Sleeps for a specified amount of milliseconds (@msec).
|
||||||
|
**/
|
||||||
|
static INLINE void retro_sleep(unsigned msec)
|
||||||
|
{
|
||||||
|
#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)
|
||||||
|
sys_timer_usleep(1000 * msec);
|
||||||
|
#elif defined(PSP) || defined(VITA)
|
||||||
|
sceKernelDelayThread(1000 * msec);
|
||||||
|
#elif defined(_3DS)
|
||||||
|
svcSleepThread(1000000 * (s64)msec);
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
Sleep(msec);
|
||||||
|
#elif defined(XENON)
|
||||||
|
udelay(1000 * msec);
|
||||||
|
#elif defined(GEKKO) || defined(__PSL1GHT__) || defined(__QNX__)
|
||||||
|
usleep(1000 * msec);
|
||||||
|
#elif defined(WIIU)
|
||||||
|
OSSleepTicks(ms_to_ticks(msec));
|
||||||
|
#else
|
||||||
|
struct timespec tv = {0};
|
||||||
|
tv.tv_sec = msec / 1000;
|
||||||
|
tv.tv_nsec = (msec % 1000) * 1000000;
|
||||||
|
nanosleep(&tv, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* next_pow2:
|
||||||
|
* @v : initial value
|
||||||
|
*
|
||||||
|
* Get next power of 2 value based on initial value.
|
||||||
|
*
|
||||||
|
* Returns: next power of 2 value (derived from @v).
|
||||||
|
**/
|
||||||
|
static INLINE uint32_t next_pow2(uint32_t v)
|
||||||
|
{
|
||||||
|
v--;
|
||||||
|
v |= v >> 1;
|
||||||
|
v |= v >> 2;
|
||||||
|
v |= v >> 4;
|
||||||
|
v |= v >> 8;
|
||||||
|
v |= v >> 16;
|
||||||
|
v++;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* prev_pow2:
|
||||||
|
* @v : initial value
|
||||||
|
*
|
||||||
|
* Get previous power of 2 value based on initial value.
|
||||||
|
*
|
||||||
|
* Returns: previous power of 2 value (derived from @v).
|
||||||
|
**/
|
||||||
|
static INLINE uint32_t prev_pow2(uint32_t v)
|
||||||
|
{
|
||||||
|
v |= v >> 1;
|
||||||
|
v |= v >> 2;
|
||||||
|
v |= v >> 4;
|
||||||
|
v |= v >> 8;
|
||||||
|
v |= v >> 16;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE uint32_t read_le(const uint8_t *data, unsigned size)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
uint32_t val = 0;
|
||||||
|
|
||||||
|
size *= 8;
|
||||||
|
for (i = 0; i < size; i += 8)
|
||||||
|
val |= (uint32_t)*data++ << i;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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];
|
||||||
|
} 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)))
|
||||||
|
#define BIT_GET(a, bit) ((a)[(bit) >> 3] & (1 << ((bit) & 7)))
|
||||||
|
|
||||||
|
#define BIT16_SET(a, bit) ((a) |= (1 << ((bit) & 15)))
|
||||||
|
#define BIT16_CLEAR(a, bit) ((a) &= ~(1 << ((bit) & 15)))
|
||||||
|
#define BIT16_GET(a, bit) (!!((a) & (1 << ((bit) & 15))))
|
||||||
|
#define BIT16_CLEAR_ALL(a) ((a) = 0)
|
||||||
|
|
||||||
|
#define BIT32_SET(a, bit) ((a) |= (1 << ((bit) & 31)))
|
||||||
|
#define BIT32_CLEAR(a, bit) ((a) &= ~(1 << ((bit) & 31)))
|
||||||
|
#define BIT32_GET(a, bit) (!!((a) & (1 << ((bit) & 31))))
|
||||||
|
#define BIT32_CLEAR_ALL(a) ((a) = 0)
|
||||||
|
|
||||||
|
#define BIT64_SET(a, bit) ((a) |= (UINT64_C(1) << ((bit) & 63)))
|
||||||
|
#define BIT64_CLEAR(a, bit) ((a) &= ~(UINT64_C(1) << ((bit) & 63)))
|
||||||
|
#define BIT64_GET(a, bit) (!!((a) & (UINT64_C(1) << ((bit) & 63))))
|
||||||
|
#define BIT64_CLEAR_ALL(a) ((a) = 0)
|
||||||
|
|
||||||
|
#define BIT128_SET(a, bit) ((a).data[(bit) >> 5] |= (1 << ((bit) & 31)))
|
||||||
|
#define BIT128_CLEAR(a, bit) ((a).data[(bit) >> 5] &= ~(1 << ((bit) & 31)))
|
||||||
|
#define BIT128_GET(a, bit) ((a).data[(bit) >> 5] & (1 << ((bit) & 31)))
|
||||||
|
#define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a));
|
||||||
|
|
||||||
|
#endif
|
82
libgambatte/libretro-common/include/streams/file_stream.h
Normal file
82
libgambatte/libretro-common/include/streams/file_stream.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/* Copyright (C) 2010-2017 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_api.h>
|
||||||
|
#include <boolean.h>
|
||||||
|
|
||||||
|
RETRO_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct RFILE RFILE;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RFILE_MODE_READ = 0,
|
||||||
|
RFILE_MODE_READ_TEXT,
|
||||||
|
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);
|
||||||
|
|
||||||
|
char *filestream_gets(RFILE *stream, char *s, size_t len);
|
||||||
|
|
||||||
|
char *filestream_getline(RFILE *stream);
|
||||||
|
|
||||||
|
int filestream_getc(RFILE *stream);
|
||||||
|
|
||||||
|
int filestream_eof(RFILE *stream);
|
||||||
|
|
||||||
|
bool filestream_write_file(const char *path, const void *data, ssize_t size);
|
||||||
|
|
||||||
|
int filestream_putc(RFILE *stream, int c);
|
||||||
|
|
||||||
|
int filestream_get_fd(RFILE *stream);
|
||||||
|
|
||||||
|
RETRO_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
63
libgambatte/libretro-common/include/string/stdstring.h
Normal file
63
libgambatte/libretro-common/include/string/stdstring.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* Copyright (C) 2010-2017 The RetroArch team
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
* The following license statement only applies to this file (stdstring.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_STDSTRING_H
|
||||||
|
#define __LIBRETRO_SDK_STDSTRING_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <boolean.h>
|
||||||
|
|
||||||
|
#include <retro_common_api.h>
|
||||||
|
|
||||||
|
RETRO_BEGIN_DECLS
|
||||||
|
|
||||||
|
bool string_is_empty(const char *data);
|
||||||
|
|
||||||
|
bool string_is_equal(const char *a, const char *b);
|
||||||
|
|
||||||
|
bool string_is_equal_noncase(const char *a, const char *b);
|
||||||
|
|
||||||
|
char *string_to_upper(char *s);
|
||||||
|
|
||||||
|
char *string_to_lower(char *s);
|
||||||
|
|
||||||
|
char *string_ucwords(char* s);
|
||||||
|
|
||||||
|
char *string_replace_substring(const char *in, const char *pattern,
|
||||||
|
const char *by);
|
||||||
|
|
||||||
|
/* Remove leading whitespaces */
|
||||||
|
char *string_trim_whitespace_left(char *const s);
|
||||||
|
|
||||||
|
/* Remove trailing whitespaces */
|
||||||
|
char *string_trim_whitespace_right(char *const s);
|
||||||
|
|
||||||
|
/* Remove leading and trailing whitespaces */
|
||||||
|
char *string_trim_whitespace(char *const s);
|
||||||
|
|
||||||
|
char* word_wrap(char* buffer, char* string, int line_width);
|
||||||
|
|
||||||
|
RETRO_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
612
libgambatte/libretro-common/streams/file_stream.c
Normal file
612
libgambatte/libretro-common/streams/file_stream.c
Normal file
@ -0,0 +1,612 @@
|
|||||||
|
/* Copyright (C) 2010-2017 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
|
||||||
|
#else
|
||||||
|
# if defined(PSP)
|
||||||
|
# include <pspiofilemgr.h>
|
||||||
|
# endif
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <sys/stat.h>
|
||||||
|
# if !defined(VITA)
|
||||||
|
# include <dirent.h>
|
||||||
|
# endif
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __CELLOS_LV2__
|
||||||
|
#include <cell/cell_fs.h>
|
||||||
|
#define O_RDONLY CELL_FS_O_RDONLY
|
||||||
|
#define O_WRONLY CELL_FS_O_WRONLY
|
||||||
|
#define O_CREAT CELL_FS_O_CREAT
|
||||||
|
#define O_TRUNC CELL_FS_O_TRUNC
|
||||||
|
#define O_RDWR CELL_FS_O_RDWR
|
||||||
|
#else
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <streams/file_stream.h>
|
||||||
|
#include <memmap.h>
|
||||||
|
#include <retro_miscellaneous.h>
|
||||||
|
|
||||||
|
struct RFILE
|
||||||
|
{
|
||||||
|
unsigned hints;
|
||||||
|
#if defined(PSP)
|
||||||
|
SceUID fd;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define HAVE_BUFFERED_IO 1
|
||||||
|
|
||||||
|
#define MODE_STR_READ "r"
|
||||||
|
#define MODE_STR_READ_UNBUF "rb"
|
||||||
|
#define MODE_STR_WRITE_UNBUF "wb"
|
||||||
|
#define MODE_STR_WRITE_PLUS "w+"
|
||||||
|
|
||||||
|
#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(HAVE_BUFFERED_IO)
|
||||||
|
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||||
|
return fileno(stream->fp);
|
||||||
|
#endif
|
||||||
|
return stream->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
int mode_int = 0;
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
const char *mode_str = NULL;
|
||||||
|
#endif
|
||||||
|
RFILE *stream = (RFILE*)calloc(1, sizeof(*stream));
|
||||||
|
|
||||||
|
if (!stream)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
(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_TEXT:
|
||||||
|
#if defined(PSP)
|
||||||
|
mode_int = 0666;
|
||||||
|
flags = PSP_O_RDONLY;
|
||||||
|
#else
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||||
|
mode_str = MODE_STR_READ;
|
||||||
|
#endif
|
||||||
|
/* No "else" here */
|
||||||
|
flags = O_RDONLY;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case RFILE_MODE_READ:
|
||||||
|
#if defined(PSP)
|
||||||
|
mode_int = 0666;
|
||||||
|
flags = PSP_O_RDONLY;
|
||||||
|
#else
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||||
|
mode_str = MODE_STR_READ_UNBUF;
|
||||||
|
#endif
|
||||||
|
/* No "else" here */
|
||||||
|
flags = O_RDONLY;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case RFILE_MODE_WRITE:
|
||||||
|
#if defined(PSP)
|
||||||
|
mode_int = 0666;
|
||||||
|
flags = PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC;
|
||||||
|
#else
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||||
|
mode_str = MODE_STR_WRITE_UNBUF;
|
||||||
|
#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(PSP)
|
||||||
|
mode_int = 0666;
|
||||||
|
flags = PSP_O_RDWR;
|
||||||
|
#else
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||||
|
mode_str = MODE_STR_WRITE_PLUS;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flags = O_RDWR;
|
||||||
|
#ifdef _WIN32
|
||||||
|
flags |= O_BINARY;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(PSP)
|
||||||
|
stream->fd = sceIoOpen(path, flags, mode_int);
|
||||||
|
#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
|
||||||
|
{
|
||||||
|
/* FIXME: HAVE_BUFFERED_IO is always 1, but if it is ever changed, open() needs to be changed to _wopen() for WIndows. */
|
||||||
|
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(PSP)
|
||||||
|
if (stream->fd == -1)
|
||||||
|
goto error;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
|
||||||
|
error:
|
||||||
|
filestream_close(stream);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *filestream_getline(RFILE *stream)
|
||||||
|
{
|
||||||
|
char* newline = (char*)malloc(9);
|
||||||
|
char* newline_tmp = NULL;
|
||||||
|
size_t cur_size = 8;
|
||||||
|
size_t idx = 0;
|
||||||
|
int in = filestream_getc(stream);
|
||||||
|
|
||||||
|
if (!newline)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (in != EOF && in != '\n')
|
||||||
|
{
|
||||||
|
if (idx == cur_size)
|
||||||
|
{
|
||||||
|
cur_size *= 2;
|
||||||
|
newline_tmp = (char*)realloc(newline, cur_size + 1);
|
||||||
|
|
||||||
|
if (!newline_tmp)
|
||||||
|
{
|
||||||
|
free(newline);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
newline = newline_tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
newline[idx++] = in;
|
||||||
|
in = filestream_getc(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
newline[idx] = '\0';
|
||||||
|
return newline;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *filestream_gets(RFILE *stream, char *s, size_t len)
|
||||||
|
{
|
||||||
|
if (!stream)
|
||||||
|
return NULL;
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
return fgets(s, len, stream->fp);
|
||||||
|
#elif defined(PSP)
|
||||||
|
if(filestream_read(stream,s,len)==len)
|
||||||
|
return s;
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
return gets(s);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int filestream_getc(RFILE *stream)
|
||||||
|
{
|
||||||
|
char c = 0;
|
||||||
|
(void)c;
|
||||||
|
if (!stream)
|
||||||
|
return 0;
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
return fgetc(stream->fp);
|
||||||
|
#elif defined(PSP)
|
||||||
|
if(filestream_read(stream, &c, 1) == 1)
|
||||||
|
return (int)c;
|
||||||
|
return EOF;
|
||||||
|
#else
|
||||||
|
return getc(stream->fd);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence)
|
||||||
|
{
|
||||||
|
if (!stream)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
#if defined(PSP)
|
||||||
|
if (sceIoLseek(stream->fd, (SceOff)offset, whence) == -1)
|
||||||
|
goto error;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||||
|
return fseek(stream->fp, (long)offset, whence);
|
||||||
|
#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)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
stream->mappos = offset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SEEK_CUR:
|
||||||
|
if ((offset < 0 && stream->mappos + offset > stream->mappos) ||
|
||||||
|
(offset > 0 && stream->mappos + offset < stream->mappos))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
stream->mappos += offset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SEEK_END:
|
||||||
|
if (stream->mapsize + offset < stream->mapsize)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
stream->mappos = stream->mapsize + offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return stream->mappos;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (lseek(stream->fd, offset, whence) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int filestream_eof(RFILE *stream)
|
||||||
|
{
|
||||||
|
size_t current_position = filestream_tell(stream);
|
||||||
|
size_t end_position = filestream_seek(stream, 0, SEEK_END);
|
||||||
|
|
||||||
|
filestream_seek(stream, current_position, SEEK_SET);
|
||||||
|
|
||||||
|
if (current_position >= end_position)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t filestream_tell(RFILE *stream)
|
||||||
|
{
|
||||||
|
if (!stream)
|
||||||
|
goto error;
|
||||||
|
#if defined(PSP)
|
||||||
|
if (sceIoLseek(stream->fd, 0, SEEK_CUR) < 0)
|
||||||
|
goto error;
|
||||||
|
#else
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||||
|
return ftell(stream->fp);
|
||||||
|
#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;
|
||||||
|
#endif
|
||||||
|
if (lseek(stream->fd, 0, SEEK_CUR) < 0)
|
||||||
|
goto error;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
goto error;
|
||||||
|
#if defined(PSP)
|
||||||
|
return sceIoRead(stream->fd, s, len);
|
||||||
|
#else
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||||
|
return fread(s, 1, len, stream->fp);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
if (stream->hints & RFILE_HINT_MMAP)
|
||||||
|
{
|
||||||
|
if (stream->mappos > stream->mapsize)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (stream->mappos + len > stream->mapsize)
|
||||||
|
len = stream->mapsize - stream->mappos;
|
||||||
|
|
||||||
|
memcpy(s, &stream->mapped[stream->mappos], len);
|
||||||
|
stream->mappos += len;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return read(stream->fd, s, len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t filestream_write(RFILE *stream, const void *s, size_t len)
|
||||||
|
{
|
||||||
|
if (!stream)
|
||||||
|
goto error;
|
||||||
|
#if defined(PSP)
|
||||||
|
return sceIoWrite(stream->fd, s, len);
|
||||||
|
#else
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||||
|
return fwrite(s, 1, len, stream->fp);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
if (stream->hints & RFILE_HINT_MMAP)
|
||||||
|
goto error;
|
||||||
|
#endif
|
||||||
|
return write(stream->fd, s, len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int filestream_putc(RFILE *stream, int c)
|
||||||
|
{
|
||||||
|
if (!stream)
|
||||||
|
return EOF;
|
||||||
|
|
||||||
|
#if defined(HAVE_BUFFERED_IO)
|
||||||
|
return fputc(c, stream->fp);
|
||||||
|
#else
|
||||||
|
/* unimplemented */
|
||||||
|
return EOF;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int filestream_close(RFILE *stream)
|
||||||
|
{
|
||||||
|
if (!stream)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
#if defined(PSP)
|
||||||
|
if (stream->fd > 0)
|
||||||
|
sceIoClose(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;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to read %s: %s\n", path, strerror(errno));
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (ret != size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
218
libgambatte/libretro-common/string/stdstring.c
Normal file
218
libgambatte/libretro-common/string/stdstring.c
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/* Copyright (C) 2010-2017 The RetroArch team
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
* The following license statement only applies to this file (stdstring.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 <stdint.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <string/stdstring.h>
|
||||||
|
|
||||||
|
bool string_is_empty(const char *data)
|
||||||
|
{
|
||||||
|
return (data == NULL) || (*data == '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool string_is_equal(const char *a, const char *b)
|
||||||
|
{
|
||||||
|
if (!a || !b)
|
||||||
|
return false;
|
||||||
|
return (strcmp(a, b) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool string_is_equal_noncase(const char *a, const char *b)
|
||||||
|
{
|
||||||
|
if (!a || !b)
|
||||||
|
return false;
|
||||||
|
return (strcasecmp(a, b) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *string_to_upper(char *s)
|
||||||
|
{
|
||||||
|
char *cs = (char *)s;
|
||||||
|
for ( ; *cs != '\0'; cs++)
|
||||||
|
*cs = toupper(*cs);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *string_to_lower(char *s)
|
||||||
|
{
|
||||||
|
char *cs = (char *)s;
|
||||||
|
for ( ; *cs != '\0'; cs++)
|
||||||
|
*cs = tolower(*cs);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *string_ucwords(char *s)
|
||||||
|
{
|
||||||
|
char *cs = (char *)s;
|
||||||
|
for ( ; *cs != '\0'; cs++)
|
||||||
|
{
|
||||||
|
if (*cs == ' ')
|
||||||
|
{
|
||||||
|
*(cs+1) = toupper(*(cs+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s[0] = toupper(s[0]);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *string_replace_substring(const char *in,
|
||||||
|
const char *pattern, const char *replacement)
|
||||||
|
{
|
||||||
|
size_t numhits, pattern_len, replacement_len, outlen;
|
||||||
|
const char *inat = NULL;
|
||||||
|
const char *inprev = NULL;
|
||||||
|
char *out = NULL;
|
||||||
|
char *outat = NULL;
|
||||||
|
|
||||||
|
/* if either pattern or replacement is NULL,
|
||||||
|
* duplicate in and let caller handle it. */
|
||||||
|
if (!pattern || !replacement)
|
||||||
|
return strdup(in);
|
||||||
|
|
||||||
|
pattern_len = strlen(pattern);
|
||||||
|
replacement_len = strlen(replacement);
|
||||||
|
numhits = 0;
|
||||||
|
inat = in;
|
||||||
|
|
||||||
|
while ((inat = strstr(inat, pattern)))
|
||||||
|
{
|
||||||
|
inat += pattern_len;
|
||||||
|
numhits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
outlen = strlen(in) - pattern_len*numhits + replacement_len*numhits;
|
||||||
|
out = (char *)malloc(outlen+1);
|
||||||
|
outat = out;
|
||||||
|
inat = in;
|
||||||
|
inprev = in;
|
||||||
|
|
||||||
|
while ((inat = strstr(inat, pattern)))
|
||||||
|
{
|
||||||
|
memcpy(outat, inprev, inat-inprev);
|
||||||
|
outat += inat-inprev;
|
||||||
|
memcpy(outat, replacement, replacement_len);
|
||||||
|
outat += replacement_len;
|
||||||
|
inat += pattern_len;
|
||||||
|
inprev = inat;
|
||||||
|
}
|
||||||
|
strcpy(outat, inprev);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove leading whitespaces */
|
||||||
|
char *string_trim_whitespace_left(char *const s)
|
||||||
|
{
|
||||||
|
if(s && *s)
|
||||||
|
{
|
||||||
|
size_t len = strlen(s);
|
||||||
|
char *cur = s;
|
||||||
|
|
||||||
|
while(*cur && isspace(*cur))
|
||||||
|
++cur, --len;
|
||||||
|
|
||||||
|
if(s != cur)
|
||||||
|
memmove(s, cur, len + 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove trailing whitespaces */
|
||||||
|
char *string_trim_whitespace_right(char *const s)
|
||||||
|
{
|
||||||
|
if(s && *s)
|
||||||
|
{
|
||||||
|
size_t len = strlen(s);
|
||||||
|
char *cur = s + len - 1;
|
||||||
|
|
||||||
|
while(cur != s && isspace(*cur))
|
||||||
|
--cur, --len;
|
||||||
|
|
||||||
|
cur[isspace(*cur) ? 0 : 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove leading and trailing whitespaces */
|
||||||
|
char *string_trim_whitespace(char *const s)
|
||||||
|
{
|
||||||
|
string_trim_whitespace_right(s); /* order matters */
|
||||||
|
string_trim_whitespace_left(s);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* word_wrap(char* buffer, char* string, int line_width)
|
||||||
|
{
|
||||||
|
unsigned i = 0;
|
||||||
|
int k, counter;
|
||||||
|
|
||||||
|
while(i < strlen(string))
|
||||||
|
{
|
||||||
|
/* copy string until the end of the line is reached */
|
||||||
|
for (counter = 1; counter <= line_width; counter++)
|
||||||
|
{
|
||||||
|
/* check if end of string reached */
|
||||||
|
if (i == strlen(string))
|
||||||
|
{
|
||||||
|
buffer[i] = 0;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i] = string[i];
|
||||||
|
|
||||||
|
/* check for newlines embedded in the original input
|
||||||
|
* and reset the index */
|
||||||
|
if (buffer[i] == '\n')
|
||||||
|
counter = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
/* check for whitespace */
|
||||||
|
if (string[i] == ' ')
|
||||||
|
{
|
||||||
|
buffer[i] = '\n';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* check for nearest whitespace back in string */
|
||||||
|
for (k = i; k > 0; k--)
|
||||||
|
{
|
||||||
|
if (string[k] == ' ')
|
||||||
|
{
|
||||||
|
buffer[k] = '\n';
|
||||||
|
/* set string index back to character after this one */
|
||||||
|
i = k + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i] = 0;
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
@ -6,6 +6,8 @@
|
|||||||
#ifdef HAVE_NETWORK
|
#ifdef HAVE_NETWORK
|
||||||
#include "net_serial.h"
|
#include "net_serial.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include <string/stdstring.h>
|
||||||
|
#include <streams/file_stream.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
@ -50,39 +52,52 @@ bool get_bootloader_from_file(void* userdata, bool isgbc, uint8_t* data, uint32_
|
|||||||
{
|
{
|
||||||
struct retro_variable var = {0};
|
struct retro_variable var = {0};
|
||||||
var.key = "gambatte_gb_bootloaderenabled";
|
var.key = "gambatte_gb_bootloaderenabled";
|
||||||
|
|
||||||
if (!environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || !var.value)
|
if (!environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || !var.value)
|
||||||
return false;
|
return false;
|
||||||
if(!(strcmp(var.value,"enabled") == 0))
|
if (!string_is_equal(var.value, "enabled"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//get path
|
// get path
|
||||||
const char* systemdirtmp = NULL;
|
const char *systemdirtmp = NULL;
|
||||||
bool worked = environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY,&systemdirtmp);
|
bool worked = environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &systemdirtmp);
|
||||||
if(!worked)return false;
|
|
||||||
|
if(!worked)
|
||||||
|
return false;
|
||||||
|
|
||||||
std::string path = systemdirtmp;
|
std::string path = systemdirtmp;
|
||||||
path += "/";//retroarch/libretro does not add a slash at the end of directory names
|
path += "/"; //retroarch/libretro does not add a slash at the end of directory names
|
||||||
|
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
if(isgbc){
|
|
||||||
|
if (isgbc)
|
||||||
|
{
|
||||||
path += "gbc_bios.bin";
|
path += "gbc_bios.bin";
|
||||||
size = 0x900;
|
size = 0x900;
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
path += "gb_bios.bin";
|
path += "gb_bios.bin";
|
||||||
size = 0x100;
|
size = 0x100;
|
||||||
}
|
}
|
||||||
if(size > buf_size)return false;
|
|
||||||
|
if(size > buf_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
//open file
|
// open file
|
||||||
int n = 0;
|
int n = 0;
|
||||||
FILE *fp = fopen(path.c_str(), "rb");
|
RFILE *fp = filestream_open(path.c_str(), RFILE_MODE_READ | RFILE_HINT_UNBUFFERED, 0);
|
||||||
if(fp){
|
|
||||||
n = fread(data, size, 1, fp);
|
if (fp)
|
||||||
fclose(fp);
|
{
|
||||||
|
n = filestream_read(fp, data, size);
|
||||||
|
filestream_close(fp);
|
||||||
}
|
}
|
||||||
else return false;
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
if(n != 1)return false;
|
if (n != size)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -116,9 +131,9 @@ class SNESInput : public gambatte::InputGetter
|
|||||||
|
|
||||||
#ifdef HAVE_NETWORK
|
#ifdef HAVE_NETWORK
|
||||||
enum SerialMode {
|
enum SerialMode {
|
||||||
SERIAL_NONE,
|
SERIAL_NONE,
|
||||||
SERIAL_SERVER,
|
SERIAL_SERVER,
|
||||||
SERIAL_CLIENT
|
SERIAL_CLIENT
|
||||||
};
|
};
|
||||||
static NetSerial gb_net_serial;
|
static NetSerial gb_net_serial;
|
||||||
static SerialMode gb_serialMode = SERIAL_NONE;
|
static SerialMode gb_serialMode = SERIAL_NONE;
|
||||||
@ -215,8 +230,8 @@ void retro_init(void)
|
|||||||
void retro_deinit()
|
void retro_deinit()
|
||||||
{
|
{
|
||||||
#ifndef CC_RESAMPLER
|
#ifndef CC_RESAMPLER
|
||||||
blipper_free(resampler_l);;
|
blipper_free(resampler_l);
|
||||||
blipper_free(resampler_r);;
|
blipper_free(resampler_r);
|
||||||
#endif
|
#endif
|
||||||
#ifdef _3DS
|
#ifdef _3DS
|
||||||
linearFree(video_buf);
|
linearFree(video_buf);
|
||||||
@ -386,7 +401,7 @@ static void load_custom_palette(void)
|
|||||||
if (!palette_file.is_open())// && !findGbcTitlePal(internal_game_name))
|
if (!palette_file.is_open())// && !findGbcTitlePal(internal_game_name))
|
||||||
{
|
{
|
||||||
// try again with default.pal
|
// try again with default.pal
|
||||||
//- removed last line if colorization is enabled
|
//- removed last line if colorization is enabled
|
||||||
custom_palette_path = system_directory + "/palettes/" + "default.pal";
|
custom_palette_path = system_directory + "/palettes/" + "default.pal";
|
||||||
palette_file.open(custom_palette_path.c_str());
|
palette_file.open(custom_palette_path.c_str());
|
||||||
}
|
}
|
||||||
@ -441,7 +456,7 @@ static void load_custom_palette(void)
|
|||||||
else if (startswith(line, "Background1="))
|
else if (startswith(line, "Background1="))
|
||||||
gb.setDmgPaletteColor(0, 1, rgb32);
|
gb.setDmgPaletteColor(0, 1, rgb32);
|
||||||
else if (startswith(line, "Background2="))
|
else if (startswith(line, "Background2="))
|
||||||
gb.setDmgPaletteColor(0, 2, rgb32);
|
gb.setDmgPaletteColor(0, 2, rgb32);
|
||||||
else if (startswith(line, "Background3="))
|
else if (startswith(line, "Background3="))
|
||||||
gb.setDmgPaletteColor(0, 3, rgb32);
|
gb.setDmgPaletteColor(0, 3, rgb32);
|
||||||
else if (startswith(line, "Sprite%2010="))
|
else if (startswith(line, "Sprite%2010="))
|
||||||
@ -473,54 +488,54 @@ static void check_variables(void)
|
|||||||
gb.setColorCorrection(colorCorrection);
|
gb.setColorCorrection(colorCorrection);
|
||||||
|
|
||||||
#ifdef HAVE_NETWORK
|
#ifdef HAVE_NETWORK
|
||||||
gb_serialMode = SERIAL_NONE;
|
gb_serialMode = SERIAL_NONE;
|
||||||
var.key = "gambatte_gb_link_mode";
|
var.key = "gambatte_gb_link_mode";
|
||||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
||||||
if (!strcmp(var.value, "Network Server")) {
|
if (!strcmp(var.value, "Network Server")) {
|
||||||
gb_serialMode = SERIAL_SERVER;
|
gb_serialMode = SERIAL_SERVER;
|
||||||
} else if (!strcmp(var.value, "Network Client")) {
|
} else if (!strcmp(var.value, "Network Client")) {
|
||||||
gb_serialMode = SERIAL_CLIENT;
|
gb_serialMode = SERIAL_CLIENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var.key = "gambatte_gb_link_network_port";
|
var.key = "gambatte_gb_link_network_port";
|
||||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
||||||
gb_NetworkPort=atoi(var.value);
|
gb_NetworkPort=atoi(var.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_NetworkClientAddr = "";
|
gb_NetworkClientAddr = "";
|
||||||
var.key = "gambatte_gb_link_network_server_ip_octet1";
|
var.key = "gambatte_gb_link_network_server_ip_octet1";
|
||||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
||||||
gb_NetworkClientAddr += std::string(var.value);
|
gb_NetworkClientAddr += std::string(var.value);
|
||||||
}
|
}
|
||||||
var.key = "gambatte_gb_link_network_server_ip_octet2";
|
var.key = "gambatte_gb_link_network_server_ip_octet2";
|
||||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
||||||
gb_NetworkClientAddr += "." + std::string(var.value);
|
gb_NetworkClientAddr += "." + std::string(var.value);
|
||||||
}
|
}
|
||||||
var.key = "gambatte_gb_link_network_server_ip_octet3";
|
var.key = "gambatte_gb_link_network_server_ip_octet3";
|
||||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
||||||
gb_NetworkClientAddr += "." + std::string(var.value);
|
gb_NetworkClientAddr += "." + std::string(var.value);
|
||||||
}
|
}
|
||||||
var.key = "gambatte_gb_link_network_server_ip_octet4";
|
var.key = "gambatte_gb_link_network_server_ip_octet4";
|
||||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
||||||
gb_NetworkClientAddr += "." + std::string(var.value);
|
gb_NetworkClientAddr += "." + std::string(var.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(gb_serialMode)
|
switch(gb_serialMode)
|
||||||
{
|
{
|
||||||
case SERIAL_SERVER:
|
case SERIAL_SERVER:
|
||||||
gb_net_serial.start(true, gb_NetworkPort, gb_NetworkClientAddr);
|
gb_net_serial.start(true, gb_NetworkPort, gb_NetworkClientAddr);
|
||||||
gb.setSerialIO(&gb_net_serial);
|
gb.setSerialIO(&gb_net_serial);
|
||||||
break;
|
break;
|
||||||
case SERIAL_CLIENT:
|
case SERIAL_CLIENT:
|
||||||
gb_net_serial.start(false, gb_NetworkPort, gb_NetworkClientAddr);
|
gb_net_serial.start(false, gb_NetworkPort, gb_NetworkClientAddr);
|
||||||
gb.setSerialIO(&gb_net_serial);
|
gb.setSerialIO(&gb_net_serial);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gb_net_serial.stop();
|
gb_net_serial.stop();
|
||||||
gb.setSerialIO(NULL);
|
gb.setSerialIO(NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var.key = "gambatte_gb_colorization";
|
var.key = "gambatte_gb_colorization";
|
||||||
@ -561,21 +576,21 @@ static void check_variables(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
load_custom_palette();
|
load_custom_palette();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
var.key = "gambatte_gb_internal_palette";
|
var.key = "gambatte_gb_internal_palette";
|
||||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||||
{
|
{
|
||||||
// Load the selected internal palette
|
// Load the selected internal palette
|
||||||
gbc_bios_palette = const_cast<unsigned short*>(findGbcDirPal(var.value));
|
gbc_bios_palette = const_cast<unsigned short*>(findGbcDirPal(var.value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gbc_bios_palette = const_cast<unsigned short*>(findGbcDirPal("GBC - Grayscale"));
|
gbc_bios_palette = const_cast<unsigned short*>(findGbcDirPal("GBC - Grayscale"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//gambatte is using custom colorization then we have a previously palette loaded,
|
//gambatte is using custom colorization then we have a previously palette loaded,
|
||||||
//skip this loop then
|
//skip this loop then
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <cstdint>
|
#include <stdint.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef BOOTLOADER_H
|
#ifndef BOOTLOADER_H
|
||||||
#define BOOTLOADER_H
|
#define BOOTLOADER_H
|
||||||
|
|
||||||
#include <cstdint>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace gambatte {
|
namespace gambatte {
|
||||||
|
@ -53,7 +53,7 @@ long GB::runFor(gambatte::video_pixel_t *const videoBuf, const int pitch,
|
|||||||
return cyclesSinceBlit < 0 ? cyclesSinceBlit : static_cast<long>(samples) - (cyclesSinceBlit >> 1);
|
return cyclesSinceBlit < 0 ? cyclesSinceBlit : static_cast<long>(samples) - (cyclesSinceBlit >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GB::Priv::full_init(){
|
void GB::Priv::full_init() {
|
||||||
SaveState state;
|
SaveState state;
|
||||||
|
|
||||||
cpu.setStatePtrs(state);
|
cpu.setStatePtrs(state);
|
||||||
@ -62,9 +62,10 @@ void GB::Priv::full_init(){
|
|||||||
cpu.mem_.bootloader.reset();
|
cpu.mem_.bootloader.reset();
|
||||||
cpu.mem_.bootloader.set_address_space_start((void*)cpu.rombank0_ptr());
|
cpu.mem_.bootloader.set_address_space_start((void*)cpu.rombank0_ptr());
|
||||||
cpu.mem_.bootloader.load(cpu.isCgb(), gbaCgbMode);
|
cpu.mem_.bootloader.load(cpu.isCgb(), gbaCgbMode);
|
||||||
if(cpu.mem_.bootloader.booting_with_bootloader()){
|
|
||||||
|
if (cpu.mem_.bootloader.booting_with_bootloader()) {
|
||||||
state.cpu.pc = 0x0000;
|
state.cpu.pc = 0x0000;
|
||||||
//the hw registers must be zeroed out to prevent the logo from being garbled
|
// the hw registers must be zeroed out to prevent the logo from being garbled
|
||||||
memset((void*)(state.mem.ioamhram.get() + 0x100), 0x00, 0x100);
|
memset((void*)(state.mem.ioamhram.get() + 0x100), 0x00, 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user