aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile57
-rw-r--r--Makefile.common1
-rwxr-xr-xhakchi/bin/snes38
-rwxr-xr-xhakchi/bin/snes0538
-rw-r--r--hakchi/etc/preinit.d/pe9b0_retroarch_snes1
-rw-r--r--hakchi/readme.md23
-rw-r--r--jni/Android.mk44
-rw-r--r--libretro-common/include/boolean.h39
-rw-r--r--libretro-common/include/compat/msvc.h132
-rw-r--r--libretro-common/include/compat/msvc/stdint.h258
-rw-r--r--libretro-common/include/retro_miscellaneous.h155
-rw-r--r--libretro.c83
-rw-r--r--libretro.h41
-rw-r--r--source/apu_blargg.c73
-rw-r--r--source/cpuexec.h4
-rw-r--r--source/getset.c (renamed from source/getset.h)20
-rw-r--r--source/gfx.c10
-rw-r--r--source/memmap.c13
-rw-r--r--source/port.h6
-rw-r--r--source/ppu.h2
-rw-r--r--source/snes9x.h10
21 files changed, 948 insertions, 100 deletions
diff --git a/Makefile b/Makefile
index 186d36a..fb4bb75 100644
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,8 @@ ifeq ($(shell uname -p),powerpc)
endif
else ifneq ($(findstring MINGW,$(shell uname -a)),)
platform = win
+else ifneq ($(findstring SunOS,$(shell uname -a)),)
+ platform = sun
endif
endif
@@ -45,7 +47,13 @@ ifneq ($(GIT_VERSION)," unknown")
endif
DEFS :=
+ifneq (,$(findstring msvc,$(platform)))
+LIBM :=
+else
LIBM := -lm
+endif
+LDFLAGS :=
+LIBS :=
ifeq ($(platform), unix)
TARGET := $(TARGET_NAME)_libretro.so
@@ -58,6 +66,12 @@ else ifeq ($(platform), linux-portable)
SHARED := -shared -Wl,--version-script=link.T
CFLAGS += -fno-builtin -fno-exceptions -ffunction-sections
LIBM :=
+else ifeq ($(platform),sun)
+ TARGET := $(TARGET_NAME)_libretro.so
+ fpic := -fPIC
+ SHARED := -shared -z defs
+ CFLAGS += -fno-builtin -fno-exceptions -ffunction-sections
+ CC = gcc
else ifeq ($(platform), osx)
TARGET := $(TARGET_NAME)_libretro.dylib
fpic := -fPIC
@@ -209,6 +223,12 @@ else ifeq ($(platform), gcw0)
LIBM :=
LOAD_FROM_MEMORY_TEST = 0
CFLAGS += -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float
+#Nintendo Classics (Hakchi)
+else ifeq ($(platform), nintendoc)
+ TARGET := $(TARGET_NAME)_libretro.so
+ fpic := -fPIC
+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T
+ CFLAGS += -fno-builtin -fno-exceptions -ffunction-sections -DARM -marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
# Windows MSVC 2010 x86
else ifeq ($(platform), windows_msvc2010_x86)
@@ -230,6 +250,28 @@ TARGET := $(TARGET_NAME)_libretro.dll
PSS_STYLE :=2
LDFLAGS += -DLL
OLD_GCC = 1
+
+# Windows MSVC 2003 x86
+else ifeq ($(platform), windows_msvc2003_x86)
+ CC = cl.exe
+ CXX = cl.exe
+
+PATH := $(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../../Vc7/bin"):$(PATH)
+PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../IDE")
+INCLUDE := $(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../../Vc7/include")
+LIB := $(shell IFS=$$'\n'; cygpath -w "$(VS71COMNTOOLS)../../Vc7/lib")
+BIN := $(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../../Vc7/bin")
+
+WindowsSdkDir := $(INETSDK)
+
+export INCLUDE := $(INCLUDE);$(INETSDK)/Include;libretro-common/include/compat/msvc
+export LIB := $(LIB);$(WindowsSdkDir);$(INETSDK)/Lib
+TARGET := $(TARGET_NAME)_libretro.dll
+PSS_STYLE :=2
+LDFLAGS += -DLL
+CFLAGS += -D_CRT_SECURE_NO_DEPRECATE
+NO_GCC = 1
+
else
TARGET := $(TARGET_NAME)_libretro.dll
CC = gcc
@@ -309,7 +351,6 @@ endif
%.o: %.c
$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
-
ifeq ($(platform), theos_ios)
COMMON_FLAGS := -DIOS $(COMMON_DEFINES) $(INCFLAGS) -I$(THEOS_INCLUDE_PATH) -Wno-error
$(LIBRARY_NAME)_CFLAGS += $(COMMON_FLAGS) $(CFLAGS)
@@ -321,11 +362,21 @@ $(TARGET): $(OBJECTS)
ifeq ($(STATIC_LINKING), 1)
$(AR) rcs $@ $(OBJECTS)
else
- $(CC) $(LINKOUT)$@ $(OBJECTS) $(LDFLAGS)
+ $(CC) $(LINKOUT)$@ $(OBJECTS) $(LDFLAGS) $(LIBS)
endif
+ifeq ($(platform),nintendoc)
+ @echo "** BUILDING HAKCHI HMOD PACKAGE **"
+ mkdir -p hakchi/etc/libretro/core/ hakchi/etc/libretro/info/ hakchi/etc/preinit.d/
+ rm -f hakchi/etc/libretro/info/*
+ cp $(TARGET_NAME)_libretro.so hakchi/etc/libretro/core/
+ cd hakchi/etc/libretro/info/; wget https://buildbot.libretro.com/assets/frontend/info/$(TARGET_NAME)_libretro.info
+ cd hakchi/; tar -czvf "CORE_$(TARGET_NAME).hmod" *
+endif
+
+
clean:
- rm -f $(TARGET) $(OBJECTS)
+ rm -f $(TARGET) $(OBJECTS) hakchi/CORE_$(TARGET_NAME).hmod
.PHONY: clean
endif
diff --git a/Makefile.common b/Makefile.common
index 0a44db3..48256bb 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -17,6 +17,7 @@ SOURCES_C := \
$(CORE_DIR)/fxemu.c \
$(CORE_DIR)/fxinst.c \
$(CORE_DIR)/gfx.c \
+ $(CORE_DIR)/getset.c \
$(CORE_DIR)/globals.c \
$(CORE_DIR)/memmap.c \
$(CORE_DIR)/obc1.c \
diff --git a/hakchi/bin/snes b/hakchi/bin/snes
new file mode 100755
index 0000000..4447455
--- /dev/null
+++ b/hakchi/bin/snes
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+setFileName(){
+ filename="$(readlink -f "$1")"
+ filebase="$(basename "$filename")"
+ extension="${filebase##*.}"
+}
+
+getSfrom(){
+ local rom="$(hexdump -e '1/4 "%u"' -s8 -n4 "$1")"
+ local footer="$(hexdump -e '1/4 "%u"' -s20 -n4 "$1")"
+ local size="$(hexdump -e '1/4 "%u"' -s$((footer+1)) -n4 "$1")"
+ dd "status=none" "if=$1" "iflag=skip_bytes" "skip=$rom" "bs=$size" "count=1"
+}
+
+setFileName "$1"
+shift
+
+tmppath="/tmp/rom"
+rm -rf "$tmppath"
+mkdir -p "$tmppath"
+cd "$tmppath"
+
+if [ "$extension" = "7z" ]; then
+ tiny7zx x "$filename"
+ filename="$tmppath/$(ls | head -n1)"
+ filename_str="${filename// /_}"
+ mv "$filename" "$filename_str"
+ setFileName "$filename_str"
+fi
+
+if [ "$extension" = "sfrom" ]; then
+ filename_str="$filebase.sfc"
+ getSfrom "$filename" > "$filename_str"
+ setFileName "$filename_str"
+fi
+
+exec retroarch-clover snes9x "$filename" "$@"
diff --git a/hakchi/bin/snes05 b/hakchi/bin/snes05
new file mode 100755
index 0000000..c6da74b
--- /dev/null
+++ b/hakchi/bin/snes05
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+setFileName(){
+ filename="$(readlink -f "$1")"
+ filebase="$(basename "$filename")"
+ extension="${filebase##*.}"
+}
+
+getSfrom(){
+ local rom="$(hexdump -e '1/4 "%u"' -s8 -n4 "$1")"
+ local footer="$(hexdump -e '1/4 "%u"' -s20 -n4 "$1")"
+ local size="$(hexdump -e '1/4 "%u"' -s$((footer+1)) -n4 "$1")"
+ dd "status=none" "if=$1" "iflag=skip_bytes" "skip=$rom" "bs=$size" "count=1"
+}
+
+setFileName "$1"
+shift
+
+tmppath="/tmp/rom"
+rm -rf "$tmppath"
+mkdir -p "$tmppath"
+cd "$tmppath"
+
+if [ "$extension" = "7z" ]; then
+ tiny7zx x "$filename"
+ filename="$tmppath/$(ls | head -n1)"
+ filename_str="${filename// /_}"
+ mv "$filename" "$filename_str"
+ setFileName "$filename_str"
+fi
+
+if [ "$extension" = "sfrom" ]; then
+ filename_str="$filebase.sfc"
+ getSfrom "$filename" > "$filename_str"
+ setFileName "$filename_str"
+fi
+
+exec retroarch-clover snes9x2005 "$filename" "$@"
diff --git a/hakchi/etc/preinit.d/pe9b0_retroarch_snes b/hakchi/etc/preinit.d/pe9b0_retroarch_snes
new file mode 100644
index 0000000..82b9be4
--- /dev/null
+++ b/hakchi/etc/preinit.d/pe9b0_retroarch_snes
@@ -0,0 +1 @@
+[ -f "$mountpoint/usr/bin/clover-canoe-shvc" ] && overmount /usr/bin/clover-canoe-shvc
diff --git a/hakchi/readme.md b/hakchi/readme.md
new file mode 100644
index 0000000..18bc086
--- /dev/null
+++ b/hakchi/readme.md
@@ -0,0 +1,23 @@
+-----------------------
+Name: SNES9x2005
+Creator: Libretro
+Category: RetroArch Cores
+-----------------------
+=== SNES9x2005 Core for RetroArch ===
+
+Module adds support for Super Famicom / Super Nintendo
+
+Available executables and arguments to run Core:
+- /bin/snes <rom> <clover_args>
+- /bin/snes05 <rom> <clover_args>
+
+Core by libretro
+
+Built and assembled by HakchiCloud - [Website](https://hakchiresources.com)
+
+Hakchi module system by madmonkey
+
+NES/SNES Mini shell integration by Cluster
+
+(c) 2016-2018
+
diff --git a/jni/Android.mk b/jni/Android.mk
index e832e41..e5cf6e3 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -1,38 +1,24 @@
LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
-ifneq ($(GIT_VERSION)," unknown")
- LOCAL_CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
-endif
-
-CORE_DIR := ../source
-LIBRETRO_DIR := ..
+ROOT_DIR := $(LOCAL_PATH)/..
+CORE_DIR := $(ROOT_DIR)/source
+LIBRETRO_DIR := $(ROOT_DIR)
-DEBUG = 0
-PERF_TEST = 0
-LOAD_FROM_MEMORY_TEST = 1
-USE_BLARGG_APU = 0
-
-LOCAL_MODULE := retro
+LOAD_FROM_MEMORY_TEST := 1
+FLAGS :=
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_CFLAGS += -DANDROID_ARM
-LOCAL_ARM_MODE := arm
-endif
+include $(ROOT_DIR)/Makefile.common
-ifeq ($(TARGET_ARCH),x86)
-LOCAL_CFLAGS += -DANDROID_X86
-endif
+COREFLAGS := -ffast-math $(FLAGS)
-ifeq ($(TARGET_ARCH),mips)
-LOCAL_CFLAGS += -DANDROID_MIPS -D__mips__ -D__MIPSEL__
+GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
+ifneq ($(GIT_VERSION)," unknown")
+ COREFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
endif
-include ../Makefile.common
-
-LOCAL_SRC_FILES += $(SOURCES_C)
-LOCAL_CFLAGS += -std=gnu99 -ffast-math $(FLAGS)
-
+include $(CLEAR_VARS)
+LOCAL_MODULE := retro
+LOCAL_SRC_FILES := $(SOURCES_C)
+LOCAL_CFLAGS := $(COREFLAGS)
+LOCAL_LDFLAGS := -Wl,-version-script=$(LIBRETRO_DIR)/link.T
include $(BUILD_SHARED_LIBRARY)
diff --git a/libretro-common/include/boolean.h b/libretro-common/include/boolean.h
new file mode 100644
index 0000000..2c18ef7
--- /dev/null
+++ b/libretro-common/include/boolean.h
@@ -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
diff --git a/libretro-common/include/compat/msvc.h b/libretro-common/include/compat/msvc.h
new file mode 100644
index 0000000..5175214
--- /dev/null
+++ b/libretro-common/include/compat/msvc.h
@@ -0,0 +1,132 @@
+/* Copyright (C) 2010-2017 The RetroArch team
+ *
+ * ---------------------------------------------------------------------------------------
+ * The following license statement only applies to this file (msvc.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 and va_copy is available since MSVC 2013 */
+#if _MSC_VER < 1800
+#define roundf(in) (in >= 0.0f ? floorf(in + 0.5f) : ceilf(in - 0.5f))
+#define va_copy(x, y) ((x) = (y))
+#endif
+
+#if _MSC_VER <= 1200
+ #ifndef __cplusplus
+ /* VC6 math.h doesn't define some functions when in C mode.
+ * Trying to define a prototype gives "undefined reference".
+ * But providing an implementation then gives "function already has body".
+ * So the equivalent of the implementations from math.h are used as
+ * defines here instead, and it seems to work.
+ */
+ #define cosf(x) ((float)cos((double)x))
+ #define powf(x, y) ((float)pow((double)x, (double)y))
+ #define sinf(x) ((float)sin((double)x))
+ #define ceilf(x) ((float)ceil((double)x))
+ #define floorf(x) ((float)floor((double)x))
+ #define sqrtf(x) ((float)sqrt((double)x))
+ #endif
+
+ #ifndef _vscprintf
+ #define _vscprintf c89_vscprintf_retro__
+ int c89_vscprintf_retro__(const char *format, va_list pargs);
+ #endif
+
+ #ifndef _strtoui64
+ #define _strtoui64(x, y, z) (_atoi64(x))
+ #endif
+
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX _MAX_PATH
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX _UI32_MAX
+#endif
+
+#endif
+#endif
+
diff --git a/libretro-common/include/compat/msvc/stdint.h b/libretro-common/include/compat/msvc/stdint.h
new file mode 100644
index 0000000..c791176
--- /dev/null
+++ b/libretro-common/include/compat/msvc/stdint.h
@@ -0,0 +1,258 @@
+/* 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
+#if _MSC_VER <= 1200
+extern "C++" {
+#else
+extern "C" {
+#endif
+#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
+
diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h
new file mode 100644
index 0000000..e526d6e
--- /dev/null
+++ b/libretro-common/include/retro_miscellaneous.h
@@ -0,0 +1,155 @@
+/* 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 <boolean.h>
+#include <retro_inline.h>
+
+#if defined(_WIN32) && !defined(_XBOX)
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#elif defined(_WIN32) && defined(_XBOX)
+#include <Xtl.h>
+#endif
+
+#if defined(__CELLOS_LV2__)
+#include <sys/fs_external.h>
+#endif
+
+#include <limits.h>
+
+#ifdef _MSC_VER
+#include <compat/msvc.h>
+#endif
+
+static INLINE void bits_or_bits(uint32_t *a, uint32_t *b, uint32_t count)
+{
+ uint32_t i;
+ for (i = 0; i < count;i++)
+ a[i] |= b[i];
+}
+
+static INLINE void bits_clear_bits(uint32_t *a, uint32_t *b, uint32_t count)
+{
+ uint32_t i;
+ for (i = 0; i < count;i++)
+ a[i] &= ~b[i];
+}
+
+static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count)
+{
+ uint32_t i;
+ for (i = 0; i < count; i++)
+ {
+ if (ptr[i] != 0)
+ return true;
+ }
+ return false;
+}
+
+#ifndef PATH_MAX_LENGTH
+#if defined(__CELLOS_LV2__)
+#define PATH_MAX_LENGTH CELL_FS_MAX_FS_PATH_LENGTH
+#elif defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(GEKKO)|| defined(WIIU)
+#define PATH_MAX_LENGTH 512
+#else
+#define PATH_MAX_LENGTH 4096
+#endif
+#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 BITS_GET_ELEM(a, i) ((a).data[i])
+#define BITS_GET_ELEM_PTR(a, i) ((a)->data[i])
+
+#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] >> ((bit) & 7)) & 1)
+
+#define BIT16_SET(a, bit) ((a) |= (1 << ((bit) & 15)))
+#define BIT16_CLEAR(a, bit) ((a) &= ~(1 << ((bit) & 15)))
+#define BIT16_GET(a, bit) (((a) >> ((bit) & 15)) & 1)
+#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) >> ((bit) & 31)) & 1)
+#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) >> ((bit) & 63)) & 1)
+#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] >> ((bit) & 31)) & 1)
+#define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a))
+
+#define BIT128_SET_PTR(a, bit) BIT128_SET(*a, bit)
+#define BIT128_CLEAR_PTR(a, bit) BIT128_CLEAR(*a, bit)
+#define BIT128_GET_PTR(a, bit) BIT128_GET(*a, bit)
+#define BIT128_CLEAR_ALL_PTR(a) BIT128_CLEAR_ALL(*a)
+
+#define BIT256_SET(a, bit) BIT128_SET(a, bit)
+#define BIT256_CLEAR(a, bit) BIT128_CLEAR(a, bit)
+#define BIT256_GET(a, bit) BIT128_GET(a, bit)
+#define BIT256_CLEAR_ALL(a) BIT128_CLEAR_ALL(a)
+
+#define BIT256_SET_PTR(a, bit) BIT256_SET(*a, bit)
+#define BIT256_CLEAR_PTR(a, bit) BIT256_CLEAR(*a, bit)
+#define BIT256_GET_PTR(a, bit) BIT256_GET(*a, bit)
+#define BIT256_CLEAR_ALL_PTR(a) BIT256_CLEAR_ALL(*a)
+
+#define BITS_COPY16_PTR(a,bits) \
+{ \
+ BIT128_CLEAR_ALL_PTR(a); \
+ BITS_GET_ELEM_PTR(a, 0) = (bits) & 0xffff; \
+}
+
+#define BITS_COPY32_PTR(a,bits) \
+{ \
+ BIT128_CLEAR_ALL_PTR(a); \
+ BITS_GET_ELEM_PTR(a, 0) = (bits); \
+}
+
+/* Helper macros and struct to keep track of many booleans. */
+/* This struct has 256 bits. */
+typedef struct
+{
+ uint32_t data[8];
+} retro_bits_t;
+
+#endif
diff --git a/libretro.c b/libretro.c
index 5b31eac..a3d2beb 100644
--- a/libretro.c
+++ b/libretro.c
@@ -20,6 +20,7 @@
#endif
#include <libretro.h>
+#include <retro_miscellaneous.h>
#ifdef _3DS
void* linearMemAlign(size_t size, size_t alignment);
@@ -34,8 +35,11 @@ static retro_audio_sample_batch_t audio_batch_cb = NULL;
static retro_environment_t environ_cb = NULL;
struct retro_perf_callback perf_cb;
-char retro_save_directory[PATH_MAX];
-char retro_base_name[PATH_MAX];
+char retro_save_directory[PATH_MAX_LENGTH];
+char retro_base_name[PATH_MAX_LENGTH];
+bool overclock_cycles = false;
+bool reduce_sprite_flicker = false;
+int one_c, slow_one_c, two_c;
#ifdef _WIN32
char slash = '\\';
@@ -170,7 +174,7 @@ void S9xInitDisplay(void)
GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1;
}
-#ifndef __WIN32__
+#ifndef _WIN32
void _makepath(char* path, const char* drive, const char* dir, const char* fname, const char* ext)
{
(void) drive;
@@ -245,17 +249,6 @@ const char* S9xGetFilename(const char* in)
return filename;
}
-void GetBaseName(const char* ex)
-{
- char drive [_MAX_DRIVE + 1];
- char dir [_MAX_DIR + 1];
- char fname [_MAX_FNAME + 1];
- char ext [_MAX_EXT + 1];
- (void) ex;
- _splitpath(Memory.ROMFilename, drive, dir, fname, ext);
- snprintf(retro_base_name,sizeof(retro_base_name),"%s",fname);
-}
-
void init_sfc_setting(void)
{
memset(&Settings, 0, sizeof(Settings));
@@ -305,6 +298,8 @@ void retro_init(void)
static const struct retro_variable vars[] =
{
{ "catsfc_VideoMode", "Video Mode; auto|NTSC|PAL" },
+ { "catsfc_overclock_cycles", "Reduce Slowdown (Hack, Unsafe, Restart); disabled|compatible|max" },
+ { "catsfc_reduce_sprite_flicker", "Reduce Flickering (Hack, Unsafe); disabled|enabled" },
{ NULL, NULL },
};
@@ -389,6 +384,40 @@ static void check_variables(void)
Settings.ForceNTSC = !strcmp(var.value, "NTSC");
Settings.ForcePAL = !strcmp(var.value, "PAL");
}
+
+ var.key = "catsfc_overclock_cycles";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "compatible") == 0)
+ {
+ overclock_cycles = true;
+ one_c = 4;
+ slow_one_c = 5;
+ two_c = 6;
+ }
+ else if (strcmp(var.value, "max") == 0)
+ {
+ overclock_cycles = true;
+ one_c = 3;
+ slow_one_c = 3;
+ two_c = 3;
+ }
+ else
+ overclock_cycles = false;
+ }
+
+ var.key = "catsfc_reduce_sprite_flicker";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ reduce_sprite_flicker = true;
+ else
+ reduce_sprite_flicker = false;
+ }
}
#ifdef PSP
@@ -399,6 +428,8 @@ static int32_t samples_to_play = 0;
void retro_run(void)
{
bool updated = false;
+ int result;
+ bool okay;
#ifndef USE_BLARGG_APU
static int16_t audio_buf[2048];
#endif
@@ -411,6 +442,28 @@ void retro_run(void)
IPPU.RenderThisFrame = false;
#endif
+ result = -1;
+ okay = environ_cb(RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE, &result);
+ if (okay)
+ {
+ bool audioEnabled = 0 != (result & 2);
+ bool videoEnabled = 0 != (result & 1);
+ bool hardDisableAudio = 0 != (result & 8);
+ IPPU.RenderThisFrame = videoEnabled;
+#ifdef USE_BLARGG_APU
+ S9xSetSoundMute(!audioEnabled || hardDisableAudio);
+#endif
+ Settings.HardDisableAudio = hardDisableAudio;
+ }
+ else
+ {
+ IPPU.RenderThisFrame = true;
+#ifdef USE_BLARGG_APU
+ S9xSetSoundMute(false);
+#endif
+ Settings.HardDisableAudio = false;
+ }
+
poll_cb();
RETRO_PERFORMANCE_INIT(S9xMainLoop_func);
@@ -427,6 +480,8 @@ void retro_run(void)
audio_batch_cb(audio_buf, samples_to_play);
samples_to_play = 0;
}
+#else
+ S9xAudioCallback();
#endif
#ifdef NO_VIDEO_OUTPUT
diff --git a/libretro.h b/libretro.h
index 469b86a..ed1902b 100644
--- a/libretro.h
+++ b/libretro.h
@@ -901,6 +901,47 @@ enum retro_mod
* writeable (and readable).
*/
+#define RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE (47 | RETRO_ENVIRONMENT_EXPERIMENTAL)
+ /* int * --
+ * Tells the core if the frontend wants audio or video.
+ * If disabled, the frontend will discard the audio or video,
+ * so the core may decide to skip generating a frame or generating audio.
+ * This is mainly used for increasing performance.
+ * Bit 0 (value 1): Enable Video
+ * Bit 1 (value 2): Enable Audio
+ * Bit 2 (value 4): Use Fast Savestates.
+ * Bit 3 (value 8): Hard Disable Audio
+ * Other bits are reserved for future use and will default to zero.
+ * If video is disabled:
+ * * The frontend wants the core to not generate any video,
+ * including presenting frames via hardware acceleration.
+ * * The frontend's video frame callback will do nothing.
+ * * After running the frame, the video output of the next frame should be
+ * no different than if video was enabled, and saving and loading state
+ * should have no issues.
+ * If audio is disabled:
+ * * The frontend wants the core to not generate any audio.
+ * * The frontend's audio callbacks will do nothing.
+ * * After running the frame, the audio output of the next frame should be
+ * no different than if audio was enabled, and saving and loading state
+ * should have no issues.
+ * Fast Savestates:
+ * * Guaranteed to be created by the same binary that will load them.
+ * * Will not be written to or read from the disk.
+ * * Suggest that the core assumes loading state will succeed.
+ * * Suggest that the core updates its memory buffers in-place if possible.
+ * * Suggest that the core skips clearing memory.
+ * * Suggest that the core skips resetting the system.
+ * * Suggest that the core may skip validation steps.
+ * Hard Disable Audio:
+ * * Used for a secondary core when running ahead.
+ * * Indicates that the frontend will never need audio from the core.
+ * * Suggests that the core may stop synthesizing audio, but this should not
+ * compromise emulation accuracy.
+ * * Audio output for the next frame does not matter, and the frontend will
+ * never need an accurate audio state in the future.
+ * * State will never be saved when using Hard Disable Audio.
+ */
enum retro_hw_render_interface_type
{
RETRO_HW_RENDER_INTERFACE_VULKAN = 0,
diff --git a/source/apu_blargg.c b/source/apu_blargg.c
index d87d8d3..2976580 100644
--- a/source/apu_blargg.c
+++ b/source/apu_blargg.c
@@ -761,7 +761,8 @@ V(V9_V6_V3,2) -> V(V9,2) V(V6,3) V(V3,4) */
static void dsp_run( int32_t clocks_remain )
{
int32_t phase;
-
+ if (Settings.HardDisableAudio)
+ return;
phase = dsp_m.phase;
dsp_m.phase = (phase + clocks_remain) & 31;
@@ -2891,7 +2892,6 @@ static int32_t r_left[4], r_right[4];
#define SPACE_EMPTY() (rb_buffer_size - rb_size)
#define SPACE_FILLED() (rb_size)
#define MAX_WRITE() (SPACE_EMPTY() >> 1)
-#define AVAIL() (((((uint32_t) rb_size) << 14) - r_frac) / r_step * 2)
#define RESAMPLER_MIN(a, b) ((a) < (b) ? (a) : (b))
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
@@ -2934,6 +2934,34 @@ static void resampler_time_ratio(double ratio)
static void resampler_read(int16_t *data, int32_t num_samples)
{
+ if (r_step == 65536)
+ {
+ //direct copy if we are not resampling
+ int bytesUntilBufferEnd = rb_buffer_size - rb_start;
+ while (num_samples > 0)
+ {
+ int bytesToConsume = num_samples * sizeof(int16_t);
+ if (bytesToConsume >= bytesUntilBufferEnd)
+ {
+ bytesToConsume = bytesUntilBufferEnd;
+ }
+ if (rb_start >= rb_buffer_size)
+ {
+ rb_start = 0;
+ }
+ memcpy(data, &rb_buffer[rb_start], bytesToConsume);
+ data += bytesToConsume / sizeof(int16_t);
+ rb_start += bytesToConsume;
+ rb_size -= bytesToConsume;
+ num_samples -= bytesToConsume / sizeof(int16_t);
+ if (rb_start >= rb_buffer_size)
+ {
+ rb_start = 0;
+ }
+ }
+ return;
+ }
+
int32_t i_position, o_position, consumed;
int16_t *internal_buffer;
@@ -2944,16 +2972,13 @@ static void resampler_read(int16_t *data, int32_t num_samples)
while (o_position < num_samples && consumed < rb_buffer_size)
{
- int32_t s_left, s_right, max_samples;
- int32_t hermite_val;
-
- s_left = internal_buffer[i_position];
- s_right = internal_buffer[i_position + 1];
- max_samples = rb_buffer_size >> 1;
+ int32_t s_left = internal_buffer[i_position];
+ int32_t s_right = internal_buffer[i_position + 1];
+ int32_t max_samples = rb_buffer_size >> 1;
while (r_frac <= 65536 && o_position < num_samples)
{
- hermite_val = hermite(r_frac >> 1, r_left [0], r_left [1], r_left [2], r_left [3]);
+ int32_t hermite_val = hermite(r_frac >> 1, r_left [0], r_left [1], r_left [2], r_left [3]);
data[o_position] = SHORT_CLAMP (hermite_val);
hermite_val = hermite(r_frac >> 1, r_right[0], r_right[1], r_right[2], r_right[3]);
data[o_position + 1] = SHORT_CLAMP (hermite_val);
@@ -3005,10 +3030,9 @@ static void resampler_new(int32_t num_samples)
static INLINE bool resampler_push(int16_t *src, int32_t num_samples)
{
- int32_t bytes, end, first_write_size;
- uint8_t *src_ring;
-
- bytes = num_samples << 1;
+ int32_t end, first_write_size;
+ uint8_t *src_ring;
+ int32_t bytes = num_samples << 1;
if (MAX_WRITE() < num_samples || SPACE_EMPTY() < bytes)
return false;
@@ -3045,7 +3069,7 @@ static INLINE void resampler_resize (int32_t num_samples)
bool S9xMixSamples (int16_t *buffer, uint32_t sample_count)
{
- if (AVAIL() >= (sample_count + lag))
+ if (S9xGetSampleCount() >= (sample_count + lag))
{
resampler_read(buffer, sample_count);
if (lag == lag_master)
@@ -3065,16 +3089,18 @@ bool S9xMixSamples (int16_t *buffer, uint32_t sample_count)
int32_t S9xGetSampleCount()
{
- return AVAIL();
+ if (r_step == 65536)
+ return rb_size / sizeof(int16_t);
+ return (((((uint32_t)rb_size) << 14) - r_frac) / r_step * 2);
}
/* Sets destination for output samples */
static void spc_set_output( int16_t* out, int32_t size )
{
- int16_t *out_end, *in;
+ int16_t *in;
+ int16_t *out_end = out + size;
- out_end = out + size;
m.buf_begin = out;
m.buf_end = out_end;
@@ -3098,11 +3124,9 @@ static void spc_set_output( int16_t* out, int32_t size )
dsp_set_output( out, out_end - out );
}
-void S9xFinalizeSamples()
+void S9xFinalizeSamples(void)
{
- bool ret;
-
- ret = resampler_push(landing_buffer, SPC_SAMPLE_COUNT());
+ bool ret = resampler_push(landing_buffer, SPC_SAMPLE_COUNT());
sound_in_sync = false;
/* We weren't able to process the entire buffer. Potential overrun. */
@@ -3116,7 +3140,7 @@ void S9xFinalizeSamples()
spc_set_output(landing_buffer, buffer_size);
}
-void S9xClearSamples()
+void S9xClearSamples(void)
{
resampler_clear();
lag = lag_master;
@@ -3236,6 +3260,11 @@ static int8_t const reg_times_ [256] =
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
};
+void S9xSetSoundMute(bool mute)
+{
+ Settings.Mute = mute;
+}
+
bool S9xInitAPU()
{
int32_t i;
diff --git a/source/cpuexec.h b/source/cpuexec.h
index 3a5075b..4898207 100644
--- a/source/cpuexec.h
+++ b/source/cpuexec.h
@@ -5,11 +5,7 @@
typedef struct
{
-#ifdef __WIN32__
- void (__cdecl* S9xOpcode)(void);
-#else
void (*S9xOpcode)(void);
-#endif
} SOpcodes;
#include "ppu.h"
diff --git a/source/getset.h b/source/getset.c
index a5fd6f3..eefc5b5 100644
--- a/source/getset.h
+++ b/source/getset.c
@@ -1,8 +1,5 @@
#include "../copyright"
-#ifndef _GETSET_H_
-#define _GETSET_H_
-
#include "ppu.h"
#include "dsp1.h"
#include "cpuexec.h"
@@ -11,11 +8,9 @@
#include "obc1.h"
#include "seta.h"
-#include <retro_inline.h>
-
extern uint8_t OpenBus;
-INLINE uint8_t S9xGetByte(uint32_t Address)
+uint8_t S9xGetByte(uint32_t Address)
{
int32_t block;
uint8_t* GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK];
@@ -67,7 +62,7 @@ INLINE uint8_t S9xGetByte(uint32_t Address)
}
}
-INLINE uint16_t S9xGetWord(uint32_t Address)
+uint16_t S9xGetWord(uint32_t Address)
{
int32_t block;
uint8_t* GetAddress;
@@ -138,7 +133,7 @@ INLINE uint16_t S9xGetWord(uint32_t Address)
}
}
-INLINE void S9xSetByte(uint8_t Byte, uint32_t Address)
+void S9xSetByte(uint8_t Byte, uint32_t Address)
{
int32_t block;
uint8_t* SetAddress = Memory.WriteMap [block = ((Address >> MEMMAP_SHIFT) & MEMMAP_MASK)];
@@ -209,7 +204,7 @@ INLINE void S9xSetByte(uint8_t Byte, uint32_t Address)
}
}
-INLINE void S9xSetWord(uint16_t Word, uint32_t Address)
+void S9xSetWord(uint16_t Word, uint32_t Address)
{
int32_t block;
uint8_t* SetAddress;
@@ -313,7 +308,7 @@ INLINE void S9xSetWord(uint16_t Word, uint32_t Address)
}
}
-INLINE uint8_t* GetBasePointer(uint32_t Address)
+uint8_t* GetBasePointer(uint32_t Address)
{
uint8_t* GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK];
if (GetAddress >= (uint8_t*) MAP_LAST)
@@ -347,7 +342,7 @@ INLINE uint8_t* GetBasePointer(uint32_t Address)
}
}
-INLINE uint8_t* S9xGetMemPointer(uint32_t Address)
+uint8_t* S9xGetMemPointer(uint32_t Address)
{
uint8_t* GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK];
if (GetAddress >= (uint8_t*) MAP_LAST)
@@ -384,7 +379,7 @@ INLINE uint8_t* S9xGetMemPointer(uint32_t Address)
}
}
-INLINE void S9xSetPCBase(uint32_t Address)
+void S9xSetPCBase(uint32_t Address)
{
int32_t block;
uint8_t* GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK];
@@ -421,4 +416,3 @@ INLINE void S9xSetPCBase(uint32_t Address)
CPU.PC = CPU.PCBase + (Address & 0xffff);
}
-#endif
diff --git a/source/gfx.c b/source/gfx.c
index e01538d..00fb4d1 100644
--- a/source/gfx.c
+++ b/source/gfx.c
@@ -36,6 +36,8 @@ extern SLineMatrixData LineMatrixData [240];
extern uint8_t Mode7Depths [2];
+extern bool reduce_sprite_flicker;
+
#define CLIP_10_BIT_SIGNED(a) \
((a) & ((1 << 10) - 1)) + (((((a) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3)
@@ -476,10 +478,10 @@ void S9xEndScreenRefresh(void)
GFX.Pitch = GFX.Pitch2 = GFX.RealPitch;
GFX.PPL = GFX.PPLx2 >> 1;
+ }
#ifdef LAGFIX
- finishedFrame = true;
+ finishedFrame = true;
#endif
- }
S9xApplyCheats();
@@ -611,7 +613,7 @@ void S9xSetupOBJ(void)
for (i = 0; i < SNES_HEIGHT_EXTENDED; i++)
{
GFX.OBJLines[i].RTOFlags = 0;
- GFX.OBJLines[i].Tiles = 34;
+ GFX.OBJLines[i].Tiles = (reduce_sprite_flicker ? 60 : 34);
}
FirstSprite = PPU.FirstSprite;
S = FirstSprite;
@@ -733,7 +735,7 @@ void S9xSetupOBJ(void)
for (Y = 0; Y < SNES_HEIGHT_EXTENDED; Y++)
{
GFX.OBJLines[Y].RTOFlags = Y ? GFX.OBJLines[Y - 1].RTOFlags : 0;
- GFX.OBJLines[Y].Tiles = 34;
+ GFX.OBJLines[Y].Tiles = (reduce_sprite_flicker ? 60 : 34);
j = 0;
if (AnyOBJOnLine[Y])
{
diff --git a/source/memmap.c b/source/memmap.c
index cfdc997..4f76fc8 100644
--- a/source/memmap.c
+++ b/source/memmap.c
@@ -24,6 +24,11 @@
#include <malloc.h>
#endif
+#ifdef _MSC_VER
+/* Necessary to build on MSVC */
+#define strnicmp _strnicmp
+#endif
+
#define MAP_HIROM_SRAM_OR_NONE (Memory.SRAMSize == 0 ? (uint8_t*) MAP_NONE : (uint8_t*) MAP_HIROM_SRAM)
#define MAP_LOROM_SRAM_OR_NONE (Memory.SRAMSize == 0 ? (uint8_t*) MAP_NONE : (uint8_t*) MAP_LOROM_SRAM)
#define MAP_RONLY_SRAM_OR_NONE (Memory.SRAMSize == 0 ? (uint8_t*) MAP_NONE : (uint8_t*) MAP_RONLY_SRAM)
@@ -471,7 +476,7 @@ static uint32_t FileLoader(uint8_t* buffer, const char* filename, int32_t maxsiz
_splitpath(filename, drive, dir, name, ext);
_makepath(fname, drive, dir, name, ext);
-#ifdef __WIN32__
+#ifdef _WIN32
/* memmove required: Overlapping addresses [Neb] */
memmove(&ext [0], &ext[1], 4);
#endif
@@ -524,7 +529,7 @@ static uint32_t FileLoader(uint8_t* buffer, const char* filename, int32_t maxsiz
{
more = true;
ext [0]++;
-#ifdef __WIN32__
+#ifdef _WIN32
/* memmove required: Overlapping addresses [Neb] */
memmove(&ext [1], &ext [0], 4);
ext [0] = '.';
@@ -535,7 +540,7 @@ static uint32_t FileLoader(uint8_t* buffer, const char* filename, int32_t maxsiz
{
more = true;
name [len - 1]++;
-#ifdef __WIN32__
+#ifdef _WIN32
/* memmove required: Overlapping addresses [Neb] */
memmove(&ext [1], &ext [0], 4);
ext [0] = '.';
@@ -3044,5 +3049,3 @@ void ParseSNESHeader(uint8_t* RomHeader)
else
sprintf(Memory.CompanyId, "%02X", RomHeader[0x2A]);
}
-
-#include "getset.h"
diff --git a/source/port.h b/source/port.h
index c2a9b7f..fcfe836 100644
--- a/source/port.h
+++ b/source/port.h
@@ -18,7 +18,7 @@
#include "pixform.h"
-#ifndef __WIN32__
+#ifndef _WIN32
#ifndef PATH_MAX
#define PATH_MAX 1024
@@ -46,7 +46,7 @@
void _makepath(char* path, const char* drive, const char* dir, const char* fname, const char* ext);
void _splitpath(const char* path, char* drive, char* dir, char* fname, char* ext);
-#else /* __WIN32__ */
+#else /* _WIN32 */
#define strcasecmp stricmp
#define strncasecmp strnicmp
#endif
@@ -54,7 +54,7 @@ void _splitpath(const char* path, char* drive, char* dir, char* fname, char* ext
#define SLASH_STR "/"
#define SLASH_CHAR '/'
-#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__WIN32__) || defined(__alpha__)
+#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(_XBOX1) || defined(__alpha__)
#define FAST_LSB_WORD_ACCESS
#elif defined(__MIPSEL__)
/* On little-endian MIPS, a 16-bit word can be read directly from an address
diff --git a/source/ppu.h b/source/ppu.h
index e04c4ad..447f7f1 100644
--- a/source/ppu.h
+++ b/source/ppu.h
@@ -2,6 +2,8 @@
#define _PPU_H_
#include "../copyright"
+#include <stdint.h>
+#include <boolean.h>
#include <retro_inline.h>
#define FIRST_VISIBLE_LINE 1
diff --git a/source/snes9x.h b/source/snes9x.h
index 9e7d91d..ad410e1 100644
--- a/source/snes9x.h
+++ b/source/snes9x.h
@@ -46,9 +46,9 @@
#define SNES_CYCLES_PER_SCANLINE ((uint32_t) ((SNES_SCANLINE_TIME / SNES_CLOCK_LEN) * 6 + 0.5))
-#define ONE_CYCLE 6u
-#define SLOW_ONE_CYCLE 8u
-#define TWO_CYCLES 12u
+#define ONE_CYCLE (overclock_cycles ? one_c : 6u)
+#define SLOW_ONE_CYCLE (overclock_cycles ? slow_one_c : 8u)
+#define TWO_CYCLES (overclock_cycles ? two_c : 12u)
#define SNES_TR_MASK (1u << 4)
#define SNES_TL_MASK (1u << 5)
@@ -63,6 +63,9 @@
#define SNES_Y_MASK (1u << 14)
#define SNES_B_MASK (1u << 15)
+extern bool overclock_cycles;
+extern int one_c, slow_one_c, two_c;
+
enum
{
SNES_MULTIPLAYER5,
@@ -211,6 +214,7 @@ typedef struct
bool Justifier;
bool SecondJustifier;
int8_t SETA;
+ bool HardDisableAudio;
} SSettings;
extern SSettings Settings;