├── .gitignore ├── .gitlab-ci.yml ├── .travis.yml ├── COPYING ├── Makefile ├── Makefile.common ├── jni ├── Android.mk └── Application.mk ├── libretro-common ├── compat │ ├── compat_snprintf.c │ └── compat_strl.c └── include │ ├── boolean.h │ ├── compat │ ├── apple_compat.h │ ├── fnmatch.h │ ├── getopt.h │ ├── ifaddrs.h │ ├── intrinsics.h │ ├── msvc.h │ ├── msvc │ │ └── stdint.h │ ├── posix_string.h │ ├── strcasestr.h │ └── strl.h │ ├── libretro.h │ ├── retro_common.h │ ├── retro_common_api.h │ ├── retro_environment.h │ ├── retro_inline.h │ ├── retro_miscellaneous.h │ └── retro_stat.h ├── libretro.cpp ├── libretro_core_options.h ├── libretro_core_options_intl.h ├── link.T └── mednafen ├── git.h ├── hw_cpu └── v810 │ ├── fpu-new │ ├── softfloat-macros.h │ ├── softfloat-specialize.h │ ├── softfloat.c │ └── softfloat.h │ ├── v810_cpu.cpp │ ├── v810_cpu.h │ ├── v810_do_am.h │ ├── v810_op_table.inc │ ├── v810_op_table_msvc.inc │ ├── v810_oploop.inc │ └── v810_opt.h ├── include └── blip │ └── Blip_Buffer.h ├── masmem.h ├── math_ops.h ├── mednafen-types.h ├── mempatcher-driver.h ├── mempatcher.cpp ├── mempatcher.h ├── msvc_compat.h ├── settings.c ├── settings.h ├── sound └── Blip_Buffer.c ├── state.c ├── state.h ├── state_helpers.h ├── vb ├── input.c ├── input.h ├── timer.c ├── timer.h ├── vb.h ├── vip.c ├── vip.h ├── vip_draw.inc ├── vsu.c └── vsu.h └── video └── surface.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.dll 4 | *.dylib 5 | /old 6 | *.a 7 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper) 2 | 3 | ############################################################################## 4 | ################################# BOILERPLATE ################################ 5 | ############################################################################## 6 | 7 | # Core definitions 8 | .core-defs: 9 | variables: 10 | JNI_PATH: . 11 | CORENAME: mednafen_vb 12 | 13 | # Inclusion templates, required for the build to work 14 | include: 15 | ################################## DESKTOPS ################################ 16 | # Windows 64-bit 17 | - project: 'libretro-infrastructure/ci-templates' 18 | file: '/windows-x64-mingw.yml' 19 | 20 | # Windows 32-bit 21 | - project: 'libretro-infrastructure/ci-templates' 22 | file: '/windows-i686-mingw.yml' 23 | 24 | # Windows msvc10 64-bit 25 | - project: 'libretro-infrastructure/ci-templates' 26 | file: '/windows-x64-msvc10-msys2.yml' 27 | 28 | # Windows msvc10 32-bit 29 | - project: 'libretro-infrastructure/ci-templates' 30 | file: '/windows-i686-msvc10-msys2.yml' 31 | 32 | # Windows msvc05 32-bit 33 | - project: 'libretro-infrastructure/ci-templates' 34 | file: '/windows-i686-msvc05-msys2.yml' 35 | 36 | # Linux 64-bit 37 | - project: 'libretro-infrastructure/ci-templates' 38 | file: '/linux-x64.yml' 39 | 40 | # Linux 32-bit 41 | - project: 'libretro-infrastructure/ci-templates' 42 | file: '/linux-i686.yml' 43 | 44 | # MacOS 64-bit 45 | - project: 'libretro-infrastructure/ci-templates' 46 | file: '/osx-x64.yml' 47 | 48 | # MacOS ARM 64-bit 49 | - project: 'libretro-infrastructure/ci-templates' 50 | file: '/osx-arm64.yml' 51 | 52 | ################################## CELLULAR ################################ 53 | # Android 54 | - project: 'libretro-infrastructure/ci-templates' 55 | file: '/android-jni.yml' 56 | 57 | # iOS 58 | - project: 'libretro-infrastructure/ci-templates' 59 | file: '/ios-arm64.yml' 60 | 61 | # iOS (armv7) 62 | - project: 'libretro-infrastructure/ci-templates' 63 | file: '/ios9.yml' 64 | 65 | ################################## CONSOLES ################################ 66 | # PlayStation3 67 | - project: 'libretro-infrastructure/ci-templates' 68 | file: '/psl1ght-static.yml' 69 | 70 | # PlayStation Vita 71 | - project: 'libretro-infrastructure/ci-templates' 72 | file: '/vita-static.yml' 73 | 74 | # Nintendo 3DS 75 | - project: 'libretro-infrastructure/ci-templates' 76 | file: '/ctr-static.yml' 77 | 78 | # Nintendo Wii 79 | - project: 'libretro-infrastructure/ci-templates' 80 | file: '/wii-static.yml' 81 | 82 | # Nintendo WiiU 83 | - project: 'libretro-infrastructure/ci-templates' 84 | file: '/wiiu-static.yml' 85 | 86 | # Nintendo Switch 87 | - project: 'libretro-infrastructure/ci-templates' 88 | file: '/libnx-static.yml' 89 | 90 | # tvOS (AppleTV) 91 | - project: 'libretro-infrastructure/ci-templates' 92 | file: '/tvos-arm64.yml' 93 | 94 | #################################### MISC ################################## 95 | # Emscripten 96 | - project: 'libretro-infrastructure/ci-templates' 97 | file: '/emscripten-static.yml' 98 | 99 | # Stages for building 100 | stages: 101 | - build-prepare 102 | - build-shared 103 | - build-static 104 | 105 | ############################################################################## 106 | #################################### STAGES ################################## 107 | ############################################################################## 108 | # 109 | ################################### DESKTOPS ################################# 110 | # Windows 64-bit 111 | libretro-build-windows-x64: 112 | extends: 113 | - .libretro-windows-x64-mingw-make-default 114 | - .core-defs 115 | 116 | # Windows 32-bit 117 | libretro-build-windows-i686: 118 | extends: 119 | - .libretro-windows-i686-mingw-make-default 120 | - .core-defs 121 | 122 | # Windows msvc10 64-bit 123 | libretro-build-windows-msvc10-x64: 124 | extends: 125 | - .libretro-windows-x64-msvc10-msys2-make-default 126 | - .core-defs 127 | 128 | # Windows msvc10 32-bit 129 | libretro-build-windows-msvc10-i686: 130 | extends: 131 | - .libretro-windows-i686-msvc10-msys2-make-default 132 | - .core-defs 133 | 134 | # Windows msvc05 32-bit 135 | libretro-build-windows-msvc05-i686: 136 | extends: 137 | - .libretro-windows-i686-msvc05-msys2-make-default 138 | - .core-defs 139 | 140 | # Linux 64-bit 141 | libretro-build-linux-x64: 142 | extends: 143 | - .libretro-linux-x64-make-default 144 | - .core-defs 145 | 146 | # Linux 32-bit 147 | libretro-build-linux-i686: 148 | extends: 149 | - .libretro-linux-i686-make-default 150 | - .core-defs 151 | 152 | # MacOS 64-bit 153 | libretro-build-osx-x64: 154 | extends: 155 | - .libretro-osx-x64-make-default 156 | - .core-defs 157 | 158 | # MacOS ARM 64-bit 159 | libretro-build-osx-arm64: 160 | extends: 161 | - .libretro-osx-arm64-make-default 162 | - .core-defs 163 | 164 | ################################### CELLULAR ################################# 165 | # Android ARMv7a 166 | android-armeabi-v7a: 167 | extends: 168 | - .libretro-android-jni-armeabi-v7a 169 | - .core-defs 170 | 171 | # Android ARMv8a 172 | android-arm64-v8a: 173 | extends: 174 | - .libretro-android-jni-arm64-v8a 175 | - .core-defs 176 | 177 | # Android 64-bit x86 178 | android-x86_64: 179 | extends: 180 | - .libretro-android-jni-x86_64 181 | - .core-defs 182 | 183 | # Android 32-bit x86 184 | android-x86: 185 | extends: 186 | - .libretro-android-jni-x86 187 | - .core-defs 188 | 189 | # iOS 190 | libretro-build-ios-arm64: 191 | extends: 192 | - .libretro-ios-arm64-make-default 193 | - .core-defs 194 | 195 | # iOS (armv7) [iOS 9 and up] 196 | libretro-build-ios9: 197 | extends: 198 | - .libretro-ios9-make-default 199 | - .core-defs 200 | 201 | # tvOS 202 | libretro-build-tvos-arm64: 203 | extends: 204 | - .libretro-tvos-arm64-make-default 205 | - .core-defs 206 | 207 | ################################### CONSOLES ################################# 208 | # PlayStation3 209 | libretro-build-psl1ght: 210 | extends: 211 | - .libretro-psl1ght-static-retroarch-master 212 | - .core-defs 213 | 214 | # PlayStation Vita 215 | libretro-build-vita: 216 | extends: 217 | - .libretro-vita-static-retroarch-master 218 | - .core-defs 219 | 220 | # Nintendo 3DS 221 | libretro-build-ctr: 222 | extends: 223 | - .libretro-ctr-static-retroarch-master 224 | - .core-defs 225 | 226 | # Nintendo Wii 227 | libretro-build-wii: 228 | extends: 229 | - .libretro-wii-static-retroarch-master 230 | - .core-defs 231 | 232 | # Nintendo WiiU 233 | libretro-build-wiiu: 234 | extends: 235 | - .libretro-wiiu-static-retroarch-master 236 | - .core-defs 237 | 238 | # Nintendo Switch 239 | libretro-build-libnx-aarch64: 240 | extends: 241 | - .libretro-libnx-static-retroarch-master 242 | - .core-defs 243 | 244 | #################################### MISC ################################## 245 | # Emscripten 246 | libretro-build-emscripten: 247 | extends: 248 | - .libretro-emscripten-static-retroarch-master 249 | - .core-defs 250 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: generic 2 | os: linux 3 | dist: trusty 4 | sudo: required 5 | addons: 6 | apt: 7 | packages: 8 | - g++-7 9 | sources: 10 | - ubuntu-toolchain-r-test 11 | env: 12 | global: 13 | - CORE=mednafen_vb 14 | - COMPILER_NAME=gcc CXX=g++-7 CC=gcc-7 15 | matrix: 16 | - PLATFORM=3ds 17 | - PLATFORM=linux_x64 18 | - PLATFORM=ngc 19 | - PLATFORM=wii 20 | - PLATFORM=wiiu 21 | before_script: 22 | - pwd 23 | - mkdir -p ~/bin 24 | - ln -s /usr/bin/gcc-7 ~/bin/gcc 25 | - ln -s /usr/bin/g++-7 ~/bin/g++ 26 | - ln -s /usr/bin/cpp-7 ~/bin/cpp 27 | - export PATH=~/bin:$PATH 28 | - ls -l ~/bin 29 | - echo $PATH 30 | - g++-7 --version 31 | - g++ --version 32 | script: 33 | - cd ~/ 34 | - git clone --depth=50 https://github.com/libretro/libretro-super 35 | - cd libretro-super/travis 36 | - ./build.sh 37 | -------------------------------------------------------------------------------- /Makefile.common: -------------------------------------------------------------------------------- 1 | SOURCES_CXX := 2 | SOURCES_C := 3 | 4 | MEDNAFEN_DIR := $(CORE_DIR)/mednafen 5 | CORE_EMU_DIR := $(MEDNAFEN_DIR)/vb 6 | LIBRETRO_COMM_DIR := $(CORE_DIR)/libretro-common 7 | 8 | INCFLAGS := -I$(CORE_DIR) \ 9 | -I$(MEDNAFEN_DIR) \ 10 | -I$(MEDNAFEN_DIR)/include \ 11 | -I$(MEDNAFEN_DIR)/hw_sound \ 12 | -I$(MEDNAFEN_DIR)/hw_cpu \ 13 | -I$(MEDNAFEN_DIR)/hw_misc \ 14 | -I$(LIBRETRO_COMM_DIR)/include 15 | 16 | ifneq (,$(findstring msvc2003,$(platform))) 17 | INCFLAGS += -I$(LIBRETRO_COMM_DIR)/include/compat/msvc 18 | endif 19 | 20 | ifneq ($(HAVE_GRIFFIN),1) 21 | SOURCES_CXX += \ 22 | $(MEDNAFEN_DIR)/hw_cpu/v810/v810_cpu.cpp 23 | 24 | SOURCES_C += \ 25 | $(CORE_EMU_DIR)/vsu.c \ 26 | $(CORE_EMU_DIR)/input.c \ 27 | $(CORE_EMU_DIR)/timer.c \ 28 | $(CORE_EMU_DIR)/vip.c \ 29 | $(MEDNAFEN_DIR)/hw_cpu/v810/fpu-new/softfloat.c 30 | endif 31 | 32 | ifeq ($(NEED_BLIP), 1) 33 | SOURCES_C += $(MEDNAFEN_DIR)/sound/Blip_Buffer.c 34 | endif 35 | 36 | ifeq ($(NEED_DEINTERLACER), 1) 37 | FLAGS += -DNEED_DEINTERLACER 38 | endif 39 | 40 | ifeq ($(NEED_BPP), 8) 41 | FLAGS += -DWANT_8BPP 42 | endif 43 | 44 | ifeq ($(NEED_BPP), 16) 45 | FLAGS += -DWANT_16BPP 46 | endif 47 | 48 | ifeq ($(NEED_BPP), 32) 49 | FLAGS += -DWANT_32BPP 50 | endif 51 | 52 | ifeq ($(NO_COMPUTED_GOTO), 1) 53 | FLAGS += -DNO_COMPUTED_GOTO 54 | endif 55 | 56 | ifeq ($(FRONTEND_SUPPORTS_RGB565), 1) 57 | FLAGS += -DFRONTEND_SUPPORTS_RGB565 58 | endif 59 | 60 | ifneq ($(HAVE_GRIFFIN), 1) 61 | SOURCES_CXX += \ 62 | $(MEDNAFEN_DIR)/mempatcher.cpp \ 63 | $(CORE_DIR)/libretro.cpp 64 | 65 | SOURCES_C += \ 66 | $(MEDNAFEN_DIR)/state.c \ 67 | $(MEDNAFEN_DIR)/settings.c 68 | 69 | ifneq ($(STATIC_LINKING), 1) 70 | SOURCES_C += \ 71 | $(LIBRETRO_COMM_DIR)/compat/compat_strl.c \ 72 | $(LIBRETRO_COMM_DIR)/compat/compat_snprintf.c 73 | endif 74 | endif 75 | -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | CORE_DIR := $(LOCAL_PATH)/.. 4 | 5 | DEBUG := 0 6 | FRONTEND_SUPPORTS_RGB565 := 1 7 | NEED_BPP := 32 8 | NEED_BLIP := 1 9 | IS_X86 := 0 10 | FLAGS := 11 | 12 | ifeq ($(TARGET_ARCH),x86) 13 | IS_X86 := 1 14 | endif 15 | 16 | include $(CORE_DIR)/Makefile.common 17 | 18 | COREFLAGS := -funroll-loops $(INCFLAGS) -DMEDNAFEN_VERSION=\"0.9.26\" -DMEDNAFEN_VERSION_NUMERIC=926 -D__LIBRETRO__ -DINLINE="inline" $(FLAGS) 19 | COREFLAGS += -DWANT_VB_EMU 20 | 21 | GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)" 22 | ifneq ($(GIT_VERSION)," unknown") 23 | COREFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\" 24 | endif 25 | 26 | include $(CLEAR_VARS) 27 | LOCAL_MODULE := retro 28 | LOCAL_SRC_FILES := $(SOURCES_CXX) $(SOURCES_C) 29 | LOCAL_CFLAGS := $(COREFLAGS) 30 | LOCAL_CXXFLAGS := $(COREFLAGS) 31 | LOCAL_LDFLAGS := -Wl,-version-script=$(CORE_DIR)/link.T 32 | LOCAL_CPP_FEATURES := exceptions 33 | include $(BUILD_SHARED_LIBRARY) 34 | -------------------------------------------------------------------------------- /jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_STL := c++_static 2 | APP_ABI := all 3 | -------------------------------------------------------------------------------- /libretro-common/compat/compat_snprintf.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (compat_snprintf.c). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | /* THIS FILE HAS NOT BEEN VALIDATED ON PLATFORMS BESIDES MSVC */ 24 | #ifdef _MSC_VER 25 | 26 | #include 27 | #include 28 | 29 | #if _MSC_VER < 1800 30 | #define va_copy(dst, src) ((dst) = (src)) 31 | #endif 32 | 33 | #if _MSC_VER < 1300 34 | #define _vscprintf c89_vscprintf_retro__ 35 | 36 | static int c89_vscprintf_retro__(const char *fmt, va_list pargs) 37 | { 38 | int retval; 39 | va_list argcopy; 40 | va_copy(argcopy, pargs); 41 | retval = vsnprintf(NULL, 0, fmt, argcopy); 42 | va_end(argcopy); 43 | return retval; 44 | } 45 | #endif 46 | 47 | /* http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 */ 48 | 49 | int c99_vsnprintf_retro__(char *s, size_t len, const char *fmt, va_list ap) 50 | { 51 | int count = -1; 52 | 53 | if (len != 0) 54 | { 55 | #if (_MSC_VER <= 1310) 56 | count = _vsnprintf(s, len - 1, fmt, ap); 57 | #else 58 | count = _vsnprintf_s(s, len, len - 1, fmt, ap); 59 | #endif 60 | } 61 | 62 | if (count == -1) 63 | count = _vscprintf(fmt, ap); 64 | 65 | /* there was no room for a NULL, so truncate the last character */ 66 | if (count == len && len) 67 | s[len - 1] = '\0'; 68 | 69 | return count; 70 | } 71 | 72 | int c99_snprintf_retro__(char *s, size_t len, const char *fmt, ...) 73 | { 74 | int count; 75 | va_list ap; 76 | 77 | va_start(ap, fmt); 78 | count = c99_vsnprintf_retro__(s, len, fmt, ap); 79 | va_end(ap); 80 | 81 | return count; 82 | } 83 | #endif 84 | -------------------------------------------------------------------------------- /libretro-common/compat/compat_strl.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (compat_strl.c). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | /* Implementation of strlcpy()/strlcat() based on OpenBSD. */ 29 | 30 | #ifndef __MACH__ 31 | 32 | size_t strlcpy(char *dest, const char *source, size_t size) 33 | { 34 | size_t src_size = 0; 35 | size_t n = size; 36 | 37 | if (n) 38 | while (--n && (*dest++ = *source++)) src_size++; 39 | 40 | if (!n) 41 | { 42 | if (size) *dest = '\0'; 43 | while (*source++) src_size++; 44 | } 45 | 46 | return src_size; 47 | } 48 | 49 | size_t strlcat(char *dest, const char *source, size_t size) 50 | { 51 | size_t len = strlen(dest); 52 | 53 | dest += len; 54 | 55 | if (len > size) 56 | size = 0; 57 | else 58 | size -= len; 59 | 60 | return len + strlcpy(dest, source, size); 61 | } 62 | #endif 63 | 64 | char *strldup(const char *s, size_t n) 65 | { 66 | char *dst = (char*)malloc(sizeof(char) * (n + 1)); 67 | strlcpy(dst, s, n); 68 | return dst; 69 | } 70 | -------------------------------------------------------------------------------- /libretro-common/include/boolean.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (boolean.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_BOOLEAN_H 24 | #define __LIBRETRO_SDK_BOOLEAN_H 25 | 26 | #ifndef __cplusplus 27 | 28 | #if defined(_MSC_VER) && _MSC_VER < 1800 && !defined(SN_TARGET_PS3) 29 | /* Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant. */ 30 | #define bool unsigned char 31 | #define true 1 32 | #define false 0 33 | #else 34 | #include 35 | #endif 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /libretro-common/include/compat/apple_compat.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (apple_compat.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __APPLE_COMPAT_H 24 | #define __APPLE_COMPAT_H 25 | 26 | #ifdef __APPLE__ 27 | #include 28 | #endif 29 | 30 | #ifdef __OBJC__ 31 | 32 | #if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4) 33 | typedef int NSInteger; 34 | typedef unsigned NSUInteger; 35 | typedef float CGFloat; 36 | #endif 37 | 38 | #ifndef __has_feature 39 | /* Compatibility with non-Clang compilers. */ 40 | #define __has_feature(x) 0 41 | #endif 42 | 43 | #ifndef CF_RETURNS_RETAINED 44 | #if __has_feature(attribute_cf_returns_retained) 45 | #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) 46 | #else 47 | #define CF_RETURNS_RETAINED 48 | #endif 49 | #endif 50 | 51 | #ifndef NS_INLINE 52 | #define NS_INLINE inline 53 | #endif 54 | 55 | NS_INLINE CF_RETURNS_RETAINED CFTypeRef CFBridgingRetainCompat(id X) 56 | { 57 | #if __has_feature(objc_arc) 58 | return (__bridge_retained CFTypeRef)X; 59 | #else 60 | return X; 61 | #endif 62 | } 63 | 64 | #endif 65 | 66 | #ifdef IOS 67 | #ifndef __IPHONE_5_0 68 | #warning "This project uses features only available in iOS SDK 5.0 and later." 69 | #endif 70 | 71 | #ifdef __OBJC__ 72 | #import 73 | #import 74 | #import 75 | #endif 76 | 77 | #else 78 | 79 | #ifdef __OBJC__ 80 | #include 81 | #endif 82 | #endif 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /libretro-common/include/compat/fnmatch.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (fnmatch.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_COMPAT_FNMATCH_H__ 24 | #define __LIBRETRO_SDK_COMPAT_FNMATCH_H__ 25 | 26 | #define FNM_NOMATCH 1 27 | 28 | int rl_fnmatch(const char *pattern, const char *string, int flags); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /libretro-common/include/compat/getopt.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (getopt.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_COMPAT_GETOPT_H 24 | #define __LIBRETRO_SDK_COMPAT_GETOPT_H 25 | 26 | #if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H) 27 | #include "../../../config.h" 28 | #endif 29 | 30 | /* Custom implementation of the GNU getopt_long for portability. 31 | * Not designed to be fully compatible, but compatible with 32 | * the features RetroArch uses. */ 33 | 34 | #ifdef HAVE_GETOPT_LONG 35 | #include 36 | #else 37 | /* Avoid possible naming collisions during link since we 38 | * prefer to use the actual name. */ 39 | #define getopt_long(argc, argv, optstring, longopts, longindex) __getopt_long_retro(argc, argv, optstring, longopts, longindex) 40 | 41 | #include 42 | 43 | RETRO_BEGIN_DECLS 44 | 45 | struct option 46 | { 47 | const char *name; 48 | int has_arg; 49 | int *flag; 50 | int val; 51 | }; 52 | 53 | /* argv[] is declared with char * const argv[] in GNU, 54 | * but this makes no sense, as non-POSIX getopt_long 55 | * mutates argv (non-opts are moved to the end). */ 56 | int getopt_long(int argc, char *argv[], 57 | const char *optstring, const struct option *longopts, int *longindex); 58 | extern char *optarg; 59 | extern int optind, opterr, optopt; 60 | 61 | RETRO_END_DECLS 62 | 63 | /* If these are variously #defined, then we have bigger problems */ 64 | #ifndef no_argument 65 | #define no_argument 0 66 | #define required_argument 1 67 | #define optional_argument 2 68 | #endif 69 | 70 | /* HAVE_GETOPT_LONG */ 71 | #endif 72 | 73 | /* pragma once */ 74 | #endif 75 | -------------------------------------------------------------------------------- /libretro-common/include/compat/ifaddrs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995, 1999 3 | * Berkeley Software Design, Inc. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND 12 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 13 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 14 | * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE 15 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 17 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 18 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 19 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 20 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 21 | * SUCH DAMAGE. 22 | * 23 | * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp 24 | */ 25 | 26 | #ifndef _IFADDRS_H_ 27 | #define _IFADDRS_H_ 28 | 29 | struct ifaddrs 30 | { 31 | struct ifaddrs *ifa_next; 32 | char *ifa_name; 33 | unsigned int ifa_flags; 34 | struct sockaddr *ifa_addr; 35 | struct sockaddr *ifa_netmask; 36 | struct sockaddr *ifa_dstaddr; 37 | void *ifa_data; 38 | }; 39 | 40 | /* 41 | * This may have been defined in . Note that if is 42 | * to be included it must be included before this header file. 43 | */ 44 | #ifndef ifa_broadaddr 45 | #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ 46 | #endif 47 | 48 | #include 49 | 50 | extern int getifaddrs(struct ifaddrs **ifap); 51 | extern void freeifaddrs(struct ifaddrs *ifa); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /libretro-common/include/compat/intrinsics.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (intrinsics.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_COMPAT_INTRINSICS_H 24 | #define __LIBRETRO_SDK_COMPAT_INTRINSICS_H 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | #include 32 | 33 | #if defined(_MSC_VER) && !defined(_XBOX) 34 | #if (_MSC_VER > 1310) 35 | #include 36 | #endif 37 | #endif 38 | 39 | RETRO_BEGIN_DECLS 40 | 41 | /* Count Leading Zero, unsigned 16bit input value */ 42 | static INLINE unsigned compat_clz_u16(uint16_t val) 43 | { 44 | #if defined(__GNUC__) 45 | return __builtin_clz(val << 16 | 0x8000); 46 | #else 47 | unsigned ret = 0; 48 | 49 | while(!(val & 0x8000) && ret < 16) 50 | { 51 | val <<= 1; 52 | ret++; 53 | } 54 | 55 | return ret; 56 | #endif 57 | } 58 | 59 | /* Count Trailing Zero */ 60 | static INLINE int compat_ctz(unsigned x) 61 | { 62 | #if defined(__GNUC__) && !defined(RARCH_CONSOLE) 63 | return __builtin_ctz(x); 64 | #elif _MSC_VER >= 1400 && !defined(_XBOX) && !defined(__WINRT__) 65 | unsigned long r = 0; 66 | _BitScanReverse((unsigned long*)&r, x); 67 | return (int)r; 68 | #else 69 | /* Only checks at nibble granularity, 70 | * because that's what we need. */ 71 | if (x & 0x000f) 72 | return 0; 73 | if (x & 0x00f0) 74 | return 4; 75 | if (x & 0x0f00) 76 | return 8; 77 | if (x & 0xf000) 78 | return 12; 79 | return 16; 80 | #endif 81 | } 82 | 83 | RETRO_END_DECLS 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /libretro-common/include/compat/msvc.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (msvc.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_COMPAT_MSVC_H 24 | #define __LIBRETRO_SDK_COMPAT_MSVC_H 25 | 26 | #ifdef _MSC_VER 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /* Pre-MSVC 2015 compilers don't implement snprintf, vsnprintf in a cross-platform manner. */ 33 | #if _MSC_VER < 1900 34 | #include 35 | #include 36 | #include 37 | 38 | #ifndef snprintf 39 | #define snprintf c99_snprintf_retro__ 40 | #endif 41 | int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...); 42 | 43 | #ifndef vsnprintf 44 | #define vsnprintf c99_vsnprintf_retro__ 45 | #endif 46 | int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list ap); 47 | #endif 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #undef UNICODE /* Do not bother with UNICODE at this time. */ 54 | #include 55 | #include 56 | 57 | #define _USE_MATH_DEFINES 58 | #include 59 | 60 | /* Python headers defines ssize_t and sets HAVE_SSIZE_T. 61 | * Cannot duplicate these efforts. 62 | */ 63 | #ifndef HAVE_SSIZE_T 64 | #if defined(_WIN64) 65 | typedef __int64 ssize_t; 66 | #elif defined(_WIN32) 67 | typedef int ssize_t; 68 | #endif 69 | #endif 70 | 71 | #define mkdir(dirname, unused) _mkdir(dirname) 72 | #define strtoull _strtoui64 73 | #undef strcasecmp 74 | #define strcasecmp _stricmp 75 | #undef strncasecmp 76 | #define strncasecmp _strnicmp 77 | 78 | /* Disable some of the annoying warnings. */ 79 | #pragma warning(disable : 4800) 80 | #pragma warning(disable : 4805) 81 | #pragma warning(disable : 4244) 82 | #pragma warning(disable : 4305) 83 | #pragma warning(disable : 4146) 84 | #pragma warning(disable : 4267) 85 | #pragma warning(disable : 4723) 86 | #pragma warning(disable : 4996) 87 | 88 | /* roundf and va_copy is available since MSVC 2013 */ 89 | #if _MSC_VER < 1800 90 | #define roundf(in) (in >= 0.0f ? floorf(in + 0.5f) : ceilf(in - 0.5f)) 91 | #define va_copy(x, y) ((x) = (y)) 92 | #endif 93 | 94 | #if _MSC_VER <= 1310 95 | #ifndef __cplusplus 96 | /* VC6 math.h doesn't define some functions when in C mode. 97 | * Trying to define a prototype gives "undefined reference". 98 | * But providing an implementation then gives "function already has body". 99 | * So the equivalent of the implementations from math.h are used as 100 | * defines here instead, and it seems to work. 101 | */ 102 | #define cosf(x) ((float)cos((double)x)) 103 | #define powf(x, y) ((float)pow((double)x, (double)y)) 104 | #define sinf(x) ((float)sin((double)x)) 105 | #define ceilf(x) ((float)ceil((double)x)) 106 | #define floorf(x) ((float)floor((double)x)) 107 | #define sqrtf(x) ((float)sqrt((double)x)) 108 | #define fabsf(x) ((float)fabs((double)(x))) 109 | #endif 110 | 111 | #ifndef _strtoui64 112 | #define _strtoui64(x, y, z) (_atoi64(x)) 113 | #endif 114 | 115 | #endif 116 | 117 | #ifndef PATH_MAX 118 | #define PATH_MAX _MAX_PATH 119 | #endif 120 | 121 | #ifndef SIZE_MAX 122 | #define SIZE_MAX _UI32_MAX 123 | #endif 124 | 125 | #endif 126 | #endif 127 | -------------------------------------------------------------------------------- /libretro-common/include/compat/msvc/stdint.h: -------------------------------------------------------------------------------- 1 | /* ISO C9x compliant stdint.h for Microsoft Visual Studio 2 | * Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 3 | * 4 | * Copyright (c) 2006-2008 Alexander Chemeris 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * 3. The name of the author may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 20 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 22 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef __RARCH_STDINT_H 32 | #define __RARCH_STDINT_H 33 | 34 | #if _MSC_VER && (_MSC_VER < 1600) 35 | /* Pre-MSVC 2010 needs an implementation of stdint.h. */ 36 | 37 | #if _MSC_VER > 1000 38 | #pragma once 39 | #endif 40 | 41 | #include 42 | 43 | /* For Visual Studio 6 in C++ mode and for many Visual Studio versions when 44 | * compiling for ARM we should wrap include with 'extern "C++" {}' 45 | * or compiler give many errors like this: 46 | * 47 | * error C2733: second C linkage of overloaded function 'wmemchr' not allowed 48 | */ 49 | #ifdef __cplusplus 50 | #if _MSC_VER <= 1200 51 | extern "C++" { 52 | #else 53 | extern "C" { 54 | #endif 55 | #endif 56 | # include 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | /* Define _W64 macros to mark types changing their size, like intptr_t. */ 62 | #ifndef _W64 63 | # if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 64 | # define _W64 __w64 65 | # else 66 | # define _W64 67 | # endif 68 | #endif 69 | 70 | /* 7.18.1 Integer types. */ 71 | 72 | /* 7.18.1.1 Exact-width integer types. */ 73 | 74 | /* Visual Studio 6 and Embedded Visual C++ 4 doesn't 75 | * realize that, e.g. char has the same size as __int8 76 | * so we give up on __intX for them. 77 | */ 78 | #if (_MSC_VER < 1300) 79 | typedef signed char int8_t; 80 | typedef signed short int16_t; 81 | typedef signed int int32_t; 82 | typedef unsigned char uint8_t; 83 | typedef unsigned short uint16_t; 84 | typedef unsigned int uint32_t; 85 | #else 86 | typedef signed __int8 int8_t; 87 | typedef signed __int16 int16_t; 88 | typedef signed __int32 int32_t; 89 | typedef unsigned __int8 uint8_t; 90 | typedef unsigned __int16 uint16_t; 91 | typedef unsigned __int32 uint32_t; 92 | #endif 93 | typedef signed __int64 int64_t; 94 | typedef unsigned __int64 uint64_t; 95 | 96 | /* 7.18.1.2 Minimum-width integer types. */ 97 | typedef int8_t int_least8_t; 98 | typedef int16_t int_least16_t; 99 | typedef int32_t int_least32_t; 100 | typedef int64_t int_least64_t; 101 | typedef uint8_t uint_least8_t; 102 | typedef uint16_t uint_least16_t; 103 | typedef uint32_t uint_least32_t; 104 | typedef uint64_t uint_least64_t; 105 | 106 | /* 7.18.1.3 Fastest minimum-width integer types. */ 107 | typedef int8_t int_fast8_t; 108 | typedef int16_t int_fast16_t; 109 | typedef int32_t int_fast32_t; 110 | typedef int64_t int_fast64_t; 111 | typedef uint8_t uint_fast8_t; 112 | typedef uint16_t uint_fast16_t; 113 | typedef uint32_t uint_fast32_t; 114 | typedef uint64_t uint_fast64_t; 115 | 116 | /* 7.18.1.4 Integer types capable of holding object pointers. */ 117 | #ifdef _WIN64 /* [ */ 118 | typedef signed __int64 intptr_t; 119 | typedef unsigned __int64 uintptr_t; 120 | #else /* _WIN64 ][ */ 121 | typedef _W64 signed int intptr_t; 122 | typedef _W64 unsigned int uintptr_t; 123 | #endif /* _WIN64 ] */ 124 | 125 | /* 7.18.1.5 Greatest-width integer types. */ 126 | typedef int64_t intmax_t; 127 | typedef uint64_t uintmax_t; 128 | 129 | /* 7.18.2 Limits of specified-width integer types. */ 130 | 131 | #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) 132 | /* [ See footnote 220 at page 257 and footnote 221 at page 259. */ 133 | 134 | /* 7.18.2.1 Limits of exact-width integer types. */ 135 | #define INT8_MIN ((int8_t)_I8_MIN) 136 | #define INT8_MAX _I8_MAX 137 | #define INT16_MIN ((int16_t)_I16_MIN) 138 | #define INT16_MAX _I16_MAX 139 | #define INT32_MIN ((int32_t)_I32_MIN) 140 | #define INT32_MAX _I32_MAX 141 | #define INT64_MIN ((int64_t)_I64_MIN) 142 | #define INT64_MAX _I64_MAX 143 | #define UINT8_MAX _UI8_MAX 144 | #define UINT16_MAX _UI16_MAX 145 | #define UINT32_MAX _UI32_MAX 146 | #define UINT64_MAX _UI64_MAX 147 | 148 | /* 7.18.2.2 Limits of minimum-width integer types. */ 149 | #define INT_LEAST8_MIN INT8_MIN 150 | #define INT_LEAST8_MAX INT8_MAX 151 | #define INT_LEAST16_MIN INT16_MIN 152 | #define INT_LEAST16_MAX INT16_MAX 153 | #define INT_LEAST32_MIN INT32_MIN 154 | #define INT_LEAST32_MAX INT32_MAX 155 | #define INT_LEAST64_MIN INT64_MIN 156 | #define INT_LEAST64_MAX INT64_MAX 157 | #define UINT_LEAST8_MAX UINT8_MAX 158 | #define UINT_LEAST16_MAX UINT16_MAX 159 | #define UINT_LEAST32_MAX UINT32_MAX 160 | #define UINT_LEAST64_MAX UINT64_MAX 161 | 162 | /* 7.18.2.3 Limits of fastest minimum-width integer types. */ 163 | #define INT_FAST8_MIN INT8_MIN 164 | #define INT_FAST8_MAX INT8_MAX 165 | #define INT_FAST16_MIN INT16_MIN 166 | #define INT_FAST16_MAX INT16_MAX 167 | #define INT_FAST32_MIN INT32_MIN 168 | #define INT_FAST32_MAX INT32_MAX 169 | #define INT_FAST64_MIN INT64_MIN 170 | #define INT_FAST64_MAX INT64_MAX 171 | #define UINT_FAST8_MAX UINT8_MAX 172 | #define UINT_FAST16_MAX UINT16_MAX 173 | #define UINT_FAST32_MAX UINT32_MAX 174 | #define UINT_FAST64_MAX UINT64_MAX 175 | 176 | /* 7.18.2.4 Limits of integer types capable of holding object pointers. */ 177 | #ifdef _WIN64 /* [ */ 178 | # define INTPTR_MIN INT64_MIN 179 | # define INTPTR_MAX INT64_MAX 180 | # define UINTPTR_MAX UINT64_MAX 181 | #else /* _WIN64 ][ */ 182 | # define INTPTR_MIN INT32_MIN 183 | # define INTPTR_MAX INT32_MAX 184 | # define UINTPTR_MAX UINT32_MAX 185 | #endif /* _WIN64 ] */ 186 | 187 | /* 7.18.2.5 Limits of greatest-width integer types */ 188 | #define INTMAX_MIN INT64_MIN 189 | #define INTMAX_MAX INT64_MAX 190 | #define UINTMAX_MAX UINT64_MAX 191 | 192 | /* 7.18.3 Limits of other integer types */ 193 | 194 | #ifdef _WIN64 /* [ */ 195 | # define PTRDIFF_MIN _I64_MIN 196 | # define PTRDIFF_MAX _I64_MAX 197 | #else /* _WIN64 ][ */ 198 | # define PTRDIFF_MIN _I32_MIN 199 | # define PTRDIFF_MAX _I32_MAX 200 | #endif /* _WIN64 ] */ 201 | 202 | #define SIG_ATOMIC_MIN INT_MIN 203 | #define SIG_ATOMIC_MAX INT_MAX 204 | 205 | #ifndef SIZE_MAX /* [ */ 206 | # ifdef _WIN64 /* [ */ 207 | # define SIZE_MAX _UI64_MAX 208 | # else /* _WIN64 ][ */ 209 | # define SIZE_MAX _UI32_MAX 210 | # endif /* _WIN64 ] */ 211 | #endif /* SIZE_MAX ] */ 212 | 213 | /* WCHAR_MIN and WCHAR_MAX are also defined in */ 214 | #ifndef WCHAR_MIN /* [ */ 215 | # define WCHAR_MIN 0 216 | #endif /* WCHAR_MIN ] */ 217 | #ifndef WCHAR_MAX // [ 218 | # define WCHAR_MAX _UI16_MAX 219 | #endif /* WCHAR_MAX ] */ 220 | 221 | #define WINT_MIN 0 222 | #define WINT_MAX _UI16_MAX 223 | 224 | #endif /* __STDC_LIMIT_MACROS ] */ 225 | 226 | /* 7.18.4 Limits of other integer types */ 227 | 228 | #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) 229 | /* [ See footnote 224 at page 260 */ 230 | 231 | /* 7.18.4.1 Macros for minimum-width integer constants */ 232 | 233 | #define INT8_C(val) val##i8 234 | #define INT16_C(val) val##i16 235 | #define INT32_C(val) val##i32 236 | #define INT64_C(val) val##i64 237 | 238 | #define UINT8_C(val) val##ui8 239 | #define UINT16_C(val) val##ui16 240 | #define UINT32_C(val) val##ui32 241 | #define UINT64_C(val) val##ui64 242 | 243 | /* 7.18.4.2 Macros for greatest-width integer constants */ 244 | #define INTMAX_C INT64_C 245 | #define UINTMAX_C UINT64_C 246 | 247 | #endif 248 | /* __STDC_CONSTANT_MACROS ] */ 249 | 250 | #else 251 | /* Sanity for everything else. */ 252 | #include 253 | #endif 254 | 255 | #endif 256 | -------------------------------------------------------------------------------- /libretro-common/include/compat/posix_string.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (posix_string.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_COMPAT_POSIX_STRING_H 24 | #define __LIBRETRO_SDK_COMPAT_POSIX_STRING_H 25 | 26 | #include 27 | 28 | #ifdef _MSC_VER 29 | #include 30 | #endif 31 | 32 | RETRO_BEGIN_DECLS 33 | 34 | #ifdef _WIN32 35 | #undef strtok_r 36 | #define strtok_r(str, delim, saveptr) retro_strtok_r__(str, delim, saveptr) 37 | 38 | char *strtok_r(char *str, const char *delim, char **saveptr); 39 | #endif 40 | 41 | #ifdef _MSC_VER 42 | #undef strcasecmp 43 | #undef strdup 44 | #define strcasecmp(a, b) retro_strcasecmp__(a, b) 45 | #define strdup(orig) retro_strdup__(orig) 46 | int strcasecmp(const char *a, const char *b); 47 | char *strdup(const char *orig); 48 | 49 | /* isblank is available since MSVC 2013 */ 50 | #if _MSC_VER < 1800 51 | #undef isblank 52 | #define isblank(c) retro_isblank__(c) 53 | int isblank(int c); 54 | #endif 55 | 56 | #endif 57 | 58 | RETRO_END_DECLS 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /libretro-common/include/compat/strcasestr.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (strcasestr.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_COMPAT_STRCASESTR_H 24 | #define __LIBRETRO_SDK_COMPAT_STRCASESTR_H 25 | 26 | #include 27 | 28 | #if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H) 29 | #include "../../../config.h" 30 | #endif 31 | 32 | #ifndef HAVE_STRCASESTR 33 | 34 | #include 35 | 36 | RETRO_BEGIN_DECLS 37 | 38 | /* Avoid possible naming collisions during link 39 | * since we prefer to use the actual name. */ 40 | #define strcasestr(haystack, needle) strcasestr_retro__(haystack, needle) 41 | 42 | char *strcasestr(const char *haystack, const char *needle); 43 | 44 | RETRO_END_DECLS 45 | 46 | #endif 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /libretro-common/include/compat/strl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (strl.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_COMPAT_STRL_H 24 | #define __LIBRETRO_SDK_COMPAT_STRL_H 25 | 26 | #include 27 | #include 28 | 29 | #if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H) 30 | #include "../../../config.h" 31 | #endif 32 | 33 | #include 34 | 35 | RETRO_BEGIN_DECLS 36 | 37 | #ifdef __MACH__ 38 | #ifndef HAVE_STRL 39 | #define HAVE_STRL 40 | #endif 41 | #endif 42 | 43 | #ifndef HAVE_STRL 44 | /* Avoid possible naming collisions during link since 45 | * we prefer to use the actual name. */ 46 | #define strlcpy(dst, src, size) strlcpy_retro__(dst, src, size) 47 | 48 | #define strlcat(dst, src, size) strlcat_retro__(dst, src, size) 49 | 50 | size_t strlcpy(char *dest, const char *source, size_t size); 51 | size_t strlcat(char *dest, const char *source, size_t size); 52 | 53 | #endif 54 | 55 | char *strldup(const char *s, size_t n); 56 | 57 | RETRO_END_DECLS 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /libretro-common/include/retro_common.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (retro_common.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _LIBRETRO_COMMON_RETRO_COMMON_H 24 | #define _LIBRETRO_COMMON_RETRO_COMMON_H 25 | 26 | /* 27 | This file is designed to normalize the libretro-common compiling environment. 28 | It is not to be used in public API headers, as they should be designed as leanly as possible. 29 | Nonetheless.. in the meantime, if you do something like use ssize_t, which is not fully portable, 30 | in a public API, you may need this. 31 | */ 32 | 33 | /* conditional compilation is handled inside here */ 34 | #include 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /libretro-common/include/retro_common_api.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (retro_common_api.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _LIBRETRO_COMMON_RETRO_COMMON_API_H 24 | #define _LIBRETRO_COMMON_RETRO_COMMON_API_H 25 | 26 | /* 27 | This file is designed to normalize the libretro-common compiling environment 28 | for public API headers. This should be leaner than a normal compiling environment, 29 | since it gets #included into other project's sources. 30 | */ 31 | 32 | /* ------------------------------------ */ 33 | 34 | /* 35 | Ordinarily we want to put #ifdef __cplusplus extern "C" in C library 36 | headers to enable them to get used by c++ sources. 37 | However, we want to support building this library as C++ as well, so a 38 | special technique is called for. 39 | */ 40 | 41 | #define RETRO_BEGIN_DECLS 42 | #define RETRO_END_DECLS 43 | 44 | #ifdef __cplusplus 45 | 46 | #ifdef CXX_BUILD 47 | /* build wants everything to be built as c++, so no extern "C" */ 48 | #else 49 | #undef RETRO_BEGIN_DECLS 50 | #undef RETRO_END_DECLS 51 | #define RETRO_BEGIN_DECLS extern "C" { 52 | #define RETRO_END_DECLS } 53 | #endif 54 | 55 | #else 56 | 57 | /* header is included by a C source file, so no extern "C" */ 58 | 59 | #endif 60 | 61 | /* 62 | IMO, this non-standard ssize_t should not be used. 63 | However, it's a good example of how to handle something like this. 64 | */ 65 | #ifdef _MSC_VER 66 | #ifndef HAVE_SSIZE_T 67 | #define HAVE_SSIZE_T 68 | #if defined(_WIN64) 69 | typedef __int64 ssize_t; 70 | #elif defined(_WIN32) 71 | typedef int ssize_t; 72 | #endif 73 | #endif 74 | #elif defined(__MACH__) 75 | #include 76 | #endif 77 | 78 | #ifdef _MSC_VER 79 | #if _MSC_VER >= 1800 80 | #include 81 | #else 82 | #ifndef PRId64 83 | #define PRId64 "I64d" 84 | #define PRIu64 "I64u" 85 | #define PRIuPTR "Iu" 86 | #endif 87 | #endif 88 | #else 89 | /* C++11 says this one isn't needed, but apparently (some versions of) mingw require it anyways */ 90 | /* https://stackoverflow.com/questions/8132399/how-to-printf-uint64-t-fails-with-spurious-trailing-in-format */ 91 | /* https://github.com/libretro/RetroArch/issues/6009 */ 92 | #ifndef __STDC_FORMAT_MACROS 93 | #define __STDC_FORMAT_MACROS 1 94 | #endif 95 | #include 96 | #endif 97 | #ifndef PRId64 98 | #error "inttypes.h is being screwy" 99 | #endif 100 | #define STRING_REP_INT64 "%" PRId64 101 | #define STRING_REP_UINT64 "%" PRIu64 102 | #define STRING_REP_USIZE "%" PRIuPTR 103 | 104 | /* 105 | I would like to see retro_inline.h moved in here; possibly boolean too. 106 | 107 | rationale: these are used in public APIs, and it is easier to find problems 108 | and write code that works the first time portably when theyre included uniformly 109 | than to do the analysis from scratch each time you think you need it, for each feature. 110 | 111 | Moreover it helps force you to make hard decisions: if you EVER bring in boolean.h, 112 | then you should pay the price everywhere, so you can see how much grief it will cause. 113 | 114 | Of course, another school of thought is that you should do as little damage as possible 115 | in as few places as possible... 116 | */ 117 | 118 | /* _LIBRETRO_COMMON_RETRO_COMMON_API_H */ 119 | #endif 120 | -------------------------------------------------------------------------------- /libretro-common/include/retro_environment.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (retro_environment.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_ENVIRONMENT_H 24 | #define __LIBRETRO_SDK_ENVIRONMENT_H 25 | 26 | /* 27 | This file is designed to create a normalized environment for compiling 28 | libretro-common's private implementations, or any other sources which might 29 | enjoy use of it's environment (RetroArch for instance). 30 | This should be an elaborately crafted environment so that sources don't 31 | need to be full of platform-specific workarounds. 32 | */ 33 | 34 | #if defined (__cplusplus) 35 | #if 0 36 | printf("This is C++, version %d.\n", __cplusplus); 37 | #endif 38 | /* The expected values would be 39 | * 199711L, for ISO/IEC 14882:1998 or 14882:2003 40 | */ 41 | 42 | #elif defined(__STDC__) 43 | /* This is standard C. */ 44 | 45 | #if (__STDC__ == 1) 46 | /* The implementation is ISO-conforming. */ 47 | #define __STDC_ISO__ 48 | #else 49 | /* The implementation is not ISO-conforming. */ 50 | #endif 51 | 52 | #if defined(__STDC_VERSION__) 53 | #if (__STDC_VERSION__ >= 201112L) 54 | /* This is C11. */ 55 | #define __STDC_C11__ 56 | #elif (__STDC_VERSION__ >= 199901L) 57 | /* This is C99. */ 58 | #define __STDC_C99__ 59 | #elif (__STDC_VERSION__ >= 199409L) 60 | /* This is C89 with amendment 1. */ 61 | #define __STDC_C89__ 62 | #define __STDC_C89_AMENDMENT_1__ 63 | #else 64 | /* This is C89 without amendment 1. */ 65 | #define __STDC_C89__ 66 | #endif 67 | #else /* !defined(__STDC_VERSION__) */ 68 | /* This is C89. __STDC_VERSION__ is not defined. */ 69 | #define __STDC_C89__ 70 | #endif 71 | 72 | #else /* !defined(__STDC__) */ 73 | /* This is not standard C. __STDC__ is not defined. */ 74 | #endif 75 | 76 | #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) 77 | /* Try to find out if we're compiling for WinRT or non-WinRT */ 78 | #if defined(_MSC_VER) && defined(__has_include) 79 | #if __has_include() 80 | #define HAVE_WINAPIFAMILY_H 1 81 | #else 82 | #define HAVE_WINAPIFAMILY_H 0 83 | #endif 84 | 85 | /* If _USING_V110_SDK71_ is defined it means we are using the Windows XP toolset. */ 86 | #elif defined(_MSC_VER) && (_MSC_VER >= 1700 && !_USING_V110_SDK71_) /* _MSC_VER == 1700 for Visual Studio 2012 */ 87 | #define HAVE_WINAPIFAMILY_H 1 88 | #else 89 | #define HAVE_WINAPIFAMILY_H 0 90 | #endif 91 | 92 | #if HAVE_WINAPIFAMILY_H 93 | #include 94 | #define WINAPI_FAMILY_WINRT (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) 95 | #else 96 | #define WINAPI_FAMILY_WINRT 0 97 | #endif /* HAVE_WINAPIFAMILY_H */ 98 | 99 | #if WINAPI_FAMILY_WINRT 100 | #undef __WINRT__ 101 | #define __WINRT__ 1 102 | #endif 103 | 104 | /* MSVC obviously has to have some non-standard constants... */ 105 | #if _M_IX86_FP == 1 106 | #define __SSE__ 1 107 | #elif _M_IX86_FP == 2 || (defined(_M_AMD64) || defined(_M_X64)) 108 | #define __SSE__ 1 109 | #define __SSE2__ 1 110 | #endif 111 | 112 | #endif 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /libretro-common/include/retro_inline.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (retro_inline.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_INLINE_H 24 | #define __LIBRETRO_SDK_INLINE_H 25 | 26 | #ifndef INLINE 27 | 28 | #if defined(_WIN32) || defined(__INTEL_COMPILER) 29 | #define INLINE __inline 30 | #elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L 31 | #define INLINE inline 32 | #elif defined(__GNUC__) 33 | #define INLINE __inline__ 34 | #else 35 | #define INLINE 36 | #endif 37 | 38 | #endif 39 | #endif 40 | -------------------------------------------------------------------------------- /libretro-common/include/retro_miscellaneous.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (retro_miscellaneous.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __RARCH_MISCELLANEOUS_H 24 | #define __RARCH_MISCELLANEOUS_H 25 | 26 | #define RARCH_MAX_SUBSYSTEMS 10 27 | #define RARCH_MAX_SUBSYSTEM_ROMS 10 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #if defined(_WIN32) 34 | 35 | #if defined(_XBOX) 36 | #include 37 | #else 38 | #ifndef WIN32_LEAN_AND_MEAN 39 | #define WIN32_LEAN_AND_MEAN 40 | #endif 41 | #include 42 | #endif 43 | 44 | #endif 45 | 46 | #include 47 | 48 | #ifdef _MSC_VER 49 | #include 50 | #endif 51 | 52 | static INLINE void bits_or_bits(uint32_t *a, uint32_t *b, uint32_t count) 53 | { 54 | uint32_t i; 55 | for (i = 0; i < count;i++) 56 | a[i] |= b[i]; 57 | } 58 | 59 | static INLINE void bits_clear_bits(uint32_t *a, uint32_t *b, uint32_t count) 60 | { 61 | uint32_t i; 62 | for (i = 0; i < count;i++) 63 | a[i] &= ~b[i]; 64 | } 65 | 66 | static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count) 67 | { 68 | uint32_t i; 69 | for (i = 0; i < count; i++) 70 | { 71 | if (ptr[i] != 0) 72 | return true; 73 | } 74 | return false; 75 | } 76 | 77 | #ifndef PATH_MAX_LENGTH 78 | #if defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(PS2) || defined(GEKKO)|| defined(WIIU) || defined(ORBIS) 79 | #define PATH_MAX_LENGTH 512 80 | #else 81 | #define PATH_MAX_LENGTH 4096 82 | #endif 83 | #endif 84 | 85 | #ifndef MAX 86 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) 87 | #endif 88 | 89 | #ifndef MIN 90 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) 91 | #endif 92 | 93 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 94 | 95 | #define BITS_GET_ELEM(a, i) ((a).data[i]) 96 | #define BITS_GET_ELEM_PTR(a, i) ((a)->data[i]) 97 | 98 | #define BIT_SET(a, bit) ((a)[(bit) >> 3] |= (1 << ((bit) & 7))) 99 | #define BIT_CLEAR(a, bit) ((a)[(bit) >> 3] &= ~(1 << ((bit) & 7))) 100 | #define BIT_GET(a, bit) (((a)[(bit) >> 3] >> ((bit) & 7)) & 1) 101 | 102 | #define BIT16_SET(a, bit) ((a) |= (1 << ((bit) & 15))) 103 | #define BIT16_CLEAR(a, bit) ((a) &= ~(1 << ((bit) & 15))) 104 | #define BIT16_GET(a, bit) (((a) >> ((bit) & 15)) & 1) 105 | #define BIT16_CLEAR_ALL(a) ((a) = 0) 106 | 107 | #define BIT32_SET(a, bit) ((a) |= (UINT32_C(1) << ((bit) & 31))) 108 | #define BIT32_CLEAR(a, bit) ((a) &= ~(UINT32_C(1) << ((bit) & 31))) 109 | #define BIT32_GET(a, bit) (((a) >> ((bit) & 31)) & 1) 110 | #define BIT32_CLEAR_ALL(a) ((a) = 0) 111 | 112 | #define BIT64_SET(a, bit) ((a) |= (UINT64_C(1) << ((bit) & 63))) 113 | #define BIT64_CLEAR(a, bit) ((a) &= ~(UINT64_C(1) << ((bit) & 63))) 114 | #define BIT64_GET(a, bit) (((a) >> ((bit) & 63)) & 1) 115 | #define BIT64_CLEAR_ALL(a) ((a) = 0) 116 | 117 | #define BIT128_SET(a, bit) ((a).data[(bit) >> 5] |= (UINT32_C(1) << ((bit) & 31))) 118 | #define BIT128_CLEAR(a, bit) ((a).data[(bit) >> 5] &= ~(UINT32_C(1) << ((bit) & 31))) 119 | #define BIT128_GET(a, bit) (((a).data[(bit) >> 5] >> ((bit) & 31)) & 1) 120 | #define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a)) 121 | 122 | #define BIT128_SET_PTR(a, bit) BIT128_SET(*a, bit) 123 | #define BIT128_CLEAR_PTR(a, bit) BIT128_CLEAR(*a, bit) 124 | #define BIT128_GET_PTR(a, bit) BIT128_GET(*a, bit) 125 | #define BIT128_CLEAR_ALL_PTR(a) BIT128_CLEAR_ALL(*a) 126 | 127 | #define BIT256_SET(a, bit) BIT128_SET(a, bit) 128 | #define BIT256_CLEAR(a, bit) BIT128_CLEAR(a, bit) 129 | #define BIT256_GET(a, bit) BIT128_GET(a, bit) 130 | #define BIT256_CLEAR_ALL(a) BIT128_CLEAR_ALL(a) 131 | 132 | #define BIT256_SET_PTR(a, bit) BIT256_SET(*a, bit) 133 | #define BIT256_CLEAR_PTR(a, bit) BIT256_CLEAR(*a, bit) 134 | #define BIT256_GET_PTR(a, bit) BIT256_GET(*a, bit) 135 | #define BIT256_CLEAR_ALL_PTR(a) BIT256_CLEAR_ALL(*a) 136 | 137 | #define BITS_COPY16_PTR(a,bits) \ 138 | { \ 139 | BIT128_CLEAR_ALL_PTR(a); \ 140 | BITS_GET_ELEM_PTR(a, 0) = (bits) & 0xffff; \ 141 | } 142 | 143 | #define BITS_COPY32_PTR(a,bits) \ 144 | { \ 145 | BIT128_CLEAR_ALL_PTR(a); \ 146 | BITS_GET_ELEM_PTR(a, 0) = (bits); \ 147 | } 148 | 149 | /* Helper macros and struct to keep track of many booleans. */ 150 | /* This struct has 256 bits. */ 151 | typedef struct 152 | { 153 | uint32_t data[8]; 154 | } retro_bits_t; 155 | 156 | #ifdef _WIN32 157 | # ifdef _WIN64 158 | # define PRI_SIZET PRIu64 159 | # else 160 | # if _MSC_VER == 1800 161 | # define PRI_SIZET PRIu32 162 | # else 163 | # define PRI_SIZET "u" 164 | # endif 165 | # endif 166 | #elif defined(PS2) 167 | # define PRI_SIZET "u" 168 | #else 169 | # if (SIZE_MAX == 0xFFFF) 170 | # define PRI_SIZET "hu" 171 | # elif (SIZE_MAX == 0xFFFFFFFF) 172 | # define PRI_SIZET "u" 173 | # elif (SIZE_MAX == 0xFFFFFFFFFFFFFFFF) 174 | # define PRI_SIZET "lu" 175 | # else 176 | # error PRI_SIZET: unknown SIZE_MAX 177 | # endif 178 | #endif 179 | 180 | #endif 181 | -------------------------------------------------------------------------------- /libretro-common/include/retro_stat.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2015 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (retro_stat.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __RETRO_STAT_H 24 | #define __RETRO_STAT_H 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | /** 36 | * path_is_directory: 37 | * @path : path 38 | * 39 | * Checks if path is a directory. 40 | * 41 | * Returns: true (1) if path is a directory, otherwise false (0). 42 | */ 43 | bool path_is_directory(const char *path); 44 | 45 | bool path_is_character_special(const char *path); 46 | 47 | bool path_is_valid(const char *path); 48 | 49 | int32_t path_get_size(const char *path); 50 | 51 | /** 52 | * path_mkdir_norecurse: 53 | * @dir : directory 54 | * 55 | * Create directory on filesystem. 56 | * 57 | * Returns: true (1) if directory could be created, otherwise false (0). 58 | **/ 59 | bool mkdir_norecurse(const char *dir); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /libretro_core_options.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRETRO_CORE_OPTIONS_H__ 2 | #define LIBRETRO_CORE_OPTIONS_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #ifndef HAVE_NO_LANGEXTRA 11 | #include "libretro_core_options_intl.h" 12 | #endif 13 | 14 | /* 15 | ******************************** 16 | * VERSION: 1.3 17 | ******************************** 18 | * 19 | * - 1.3: Move translations to libretro_core_options_intl.h 20 | * - libretro_core_options_intl.h includes BOM and utf-8 21 | * fix for MSVC 2010-2013 22 | * - Added HAVE_NO_LANGEXTRA flag to disable translations 23 | * on platforms/compilers without BOM support 24 | * - 1.2: Use core options v1 interface when 25 | * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1 26 | * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1) 27 | * - 1.1: Support generation of core options v0 retro_core_option_value 28 | * arrays containing options with a single value 29 | * - 1.0: First commit 30 | */ 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /* 37 | ******************************** 38 | * Core Option Definitions 39 | ******************************** 40 | */ 41 | 42 | /* RETRO_LANGUAGE_ENGLISH */ 43 | 44 | /* Default language: 45 | * - All other languages must include the same keys and values 46 | * - Will be used as a fallback in the event that frontend language 47 | * is not available 48 | * - Will be used as a fallback for any missing entries in 49 | * frontend language definition */ 50 | 51 | struct retro_core_option_definition option_defs_us[] = { 52 | { 53 | "vb_3dmode", 54 | "3D mode", 55 | "Select the 3D mode. Anaglyph - used in conjunction with classic dual-lens-color glasses. Cyberscope - intended for use with the CyberScope 3D device. sidebyside - the left-eye image is displayed on the left, and the right-eye image is displayed on the right. vli - Vertical lines alternate between left and right view. hli - Horizontal lines alternate between left and right view.", 56 | { 57 | { "anaglyph", NULL }, 58 | { "cyberscope", NULL }, 59 | { "side-by-side", NULL }, 60 | { "vli", NULL}, 61 | { "hli", NULL}, 62 | { NULL, NULL }, 63 | }, 64 | "anaglyph", 65 | }, 66 | { 67 | "vb_anaglyph_preset", 68 | "Anaglyph preset", 69 | "Anaglyph preset colors.", 70 | { 71 | { "disabled", NULL }, 72 | { "red & blue", NULL }, 73 | { "red & cyan", NULL }, 74 | { "red & electric cyan", NULL }, 75 | { "green & magenta", NULL }, 76 | { "yellow & blue", NULL }, 77 | { NULL, NULL}, 78 | }, 79 | "disabled", 80 | }, 81 | { 82 | "vb_color_mode", 83 | "Palette", 84 | "", 85 | { 86 | { "black & red", NULL }, 87 | { "black & white", NULL }, 88 | { "black & blue", NULL }, 89 | { "black & cyan", NULL }, 90 | { "black & electric cyan", NULL }, 91 | { "black & green", NULL }, 92 | { "black & magenta", NULL }, 93 | { "black & yellow", NULL }, 94 | { NULL, NULL}, 95 | }, 96 | "black & red", 97 | }, 98 | { 99 | "vb_right_analog_to_digital", 100 | "Right analog to digital", 101 | "", 102 | { 103 | { "disabled", NULL }, 104 | { "enabled", NULL }, 105 | { "invert x", NULL }, 106 | { "invert y", NULL }, 107 | { "invert both", NULL }, 108 | { NULL, NULL }, 109 | }, 110 | "disabled", 111 | }, 112 | { 113 | "vb_cpu_emulation", 114 | "CPU emulation (Restart)", 115 | "Choose between faster and accurate (slower) emulation.", 116 | { 117 | { "accurate", NULL }, 118 | { "fast", NULL }, 119 | { NULL, NULL}, 120 | }, 121 | "fast", 122 | }, 123 | { NULL, NULL, NULL, { NULL, NULL }, NULL }, 124 | }; 125 | 126 | /* 127 | ******************************** 128 | * Language Mapping 129 | ******************************** 130 | */ 131 | 132 | #ifndef HAVE_NO_LANGEXTRA 133 | struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = { 134 | option_defs_us, /* RETRO_LANGUAGE_ENGLISH */ 135 | NULL, /* RETRO_LANGUAGE_JAPANESE */ 136 | NULL, /* RETRO_LANGUAGE_FRENCH */ 137 | NULL, /* RETRO_LANGUAGE_SPANISH */ 138 | NULL, /* RETRO_LANGUAGE_GERMAN */ 139 | NULL, /* RETRO_LANGUAGE_ITALIAN */ 140 | NULL, /* RETRO_LANGUAGE_DUTCH */ 141 | NULL, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */ 142 | NULL, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */ 143 | NULL, /* RETRO_LANGUAGE_RUSSIAN */ 144 | NULL, /* RETRO_LANGUAGE_KOREAN */ 145 | NULL, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */ 146 | NULL, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */ 147 | NULL, /* RETRO_LANGUAGE_ESPERANTO */ 148 | NULL, /* RETRO_LANGUAGE_POLISH */ 149 | NULL, /* RETRO_LANGUAGE_VIETNAMESE */ 150 | NULL, /* RETRO_LANGUAGE_ARABIC */ 151 | NULL, /* RETRO_LANGUAGE_GREEK */ 152 | option_defs_tr, /* RETRO_LANGUAGE_TURKISH */ 153 | }; 154 | #endif 155 | 156 | /* 157 | ******************************** 158 | * Functions 159 | ******************************** 160 | */ 161 | 162 | /* Handles configuration/setting of core options. 163 | * Should be called as early as possible - ideally inside 164 | * retro_set_environment(), and no later than retro_load_game() 165 | * > We place the function body in the header to avoid the 166 | * necessity of adding more .c files (i.e. want this to 167 | * be as painless as possible for core devs) 168 | */ 169 | 170 | static INLINE void libretro_set_core_options(retro_environment_t environ_cb) 171 | { 172 | unsigned version = 0; 173 | 174 | if (!environ_cb) 175 | return; 176 | 177 | if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version >= 1)) 178 | { 179 | #ifndef HAVE_NO_LANGEXTRA 180 | struct retro_core_options_intl core_options_intl; 181 | unsigned language = 0; 182 | 183 | core_options_intl.us = option_defs_us; 184 | core_options_intl.local = NULL; 185 | 186 | if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) && 187 | (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH)) 188 | core_options_intl.local = option_defs_intl[language]; 189 | 190 | environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_intl); 191 | #else 192 | environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, &option_defs_us); 193 | #endif 194 | } 195 | else 196 | { 197 | size_t i; 198 | size_t num_options = 0; 199 | struct retro_variable *variables = NULL; 200 | char **values_buf = NULL; 201 | 202 | /* Determine number of options */ 203 | while (true) 204 | { 205 | if (option_defs_us[num_options].key) 206 | num_options++; 207 | else 208 | break; 209 | } 210 | 211 | /* Allocate arrays */ 212 | variables = (struct retro_variable *)calloc(num_options + 1, sizeof(struct retro_variable)); 213 | values_buf = (char **)calloc(num_options, sizeof(char *)); 214 | 215 | if (!variables || !values_buf) 216 | goto error; 217 | 218 | /* Copy parameters from option_defs_us array */ 219 | for (i = 0; i < num_options; i++) 220 | { 221 | const char *key = option_defs_us[i].key; 222 | const char *desc = option_defs_us[i].desc; 223 | const char *default_value = option_defs_us[i].default_value; 224 | struct retro_core_option_value *values = option_defs_us[i].values; 225 | size_t buf_len = 3; 226 | size_t default_index = 0; 227 | 228 | values_buf[i] = NULL; 229 | 230 | if (desc) 231 | { 232 | size_t num_values = 0; 233 | 234 | /* Determine number of values */ 235 | while (true) 236 | { 237 | if (values[num_values].value) 238 | { 239 | /* Check if this is the default value */ 240 | if (default_value) 241 | if (strcmp(values[num_values].value, default_value) == 0) 242 | default_index = num_values; 243 | 244 | buf_len += strlen(values[num_values].value); 245 | num_values++; 246 | } 247 | else 248 | break; 249 | } 250 | 251 | /* Build values string */ 252 | if (num_values > 0) 253 | { 254 | size_t j; 255 | 256 | buf_len += num_values - 1; 257 | buf_len += strlen(desc); 258 | 259 | values_buf[i] = (char *)calloc(buf_len, sizeof(char)); 260 | if (!values_buf[i]) 261 | goto error; 262 | 263 | strcpy(values_buf[i], desc); 264 | strcat(values_buf[i], "; "); 265 | 266 | /* Default value goes first */ 267 | strcat(values_buf[i], values[default_index].value); 268 | 269 | /* Add remaining values */ 270 | for (j = 0; j < num_values; j++) 271 | { 272 | if (j != default_index) 273 | { 274 | strcat(values_buf[i], "|"); 275 | strcat(values_buf[i], values[j].value); 276 | } 277 | } 278 | } 279 | } 280 | 281 | variables[i].key = key; 282 | variables[i].value = values_buf[i]; 283 | } 284 | 285 | /* Set variables */ 286 | environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables); 287 | 288 | error: 289 | 290 | /* Clean up */ 291 | if (values_buf) 292 | { 293 | for (i = 0; i < num_options; i++) 294 | { 295 | if (values_buf[i]) 296 | { 297 | free(values_buf[i]); 298 | values_buf[i] = NULL; 299 | } 300 | } 301 | 302 | free(values_buf); 303 | values_buf = NULL; 304 | } 305 | 306 | if (variables) 307 | { 308 | free(variables); 309 | variables = NULL; 310 | } 311 | } 312 | } 313 | 314 | #ifdef __cplusplus 315 | } 316 | #endif 317 | 318 | #endif 319 | -------------------------------------------------------------------------------- /libretro_core_options_intl.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRETRO_CORE_OPTIONS_INTL_H__ 2 | #define LIBRETRO_CORE_OPTIONS_INTL_H__ 3 | 4 | #if defined(_MSC_VER) && (_MSC_VER >= 1500 && _MSC_VER < 1900) 5 | /* https://support.microsoft.com/en-us/kb/980263 */ 6 | #pragma execution_character_set("utf-8") 7 | #pragma warning(disable:4566) 8 | #endif 9 | 10 | #include 11 | 12 | /* 13 | ******************************** 14 | * VERSION: 1.3 15 | ******************************** 16 | * 17 | * - 1.3: Move translations to libretro_core_options_intl.h 18 | * - libretro_core_options_intl.h includes BOM and utf-8 19 | * fix for MSVC 2010-2013 20 | * - Added HAVE_NO_LANGEXTRA flag to disable translations 21 | * on platforms/compilers without BOM support 22 | * - 1.2: Use core options v1 interface when 23 | * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1 24 | * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1) 25 | * - 1.1: Support generation of core options v0 retro_core_option_value 26 | * arrays containing options with a single value 27 | * - 1.0: First commit 28 | */ 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /* 35 | ******************************** 36 | * Core Option Definitions 37 | ******************************** 38 | */ 39 | 40 | /* RETRO_LANGUAGE_JAPANESE */ 41 | 42 | /* RETRO_LANGUAGE_FRENCH */ 43 | 44 | /* RETRO_LANGUAGE_SPANISH */ 45 | 46 | /* RETRO_LANGUAGE_GERMAN */ 47 | 48 | /* RETRO_LANGUAGE_ITALIAN */ 49 | 50 | /* RETRO_LANGUAGE_DUTCH */ 51 | 52 | /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */ 53 | 54 | /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */ 55 | 56 | /* RETRO_LANGUAGE_RUSSIAN */ 57 | 58 | /* RETRO_LANGUAGE_KOREAN */ 59 | 60 | /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */ 61 | 62 | /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */ 63 | 64 | /* RETRO_LANGUAGE_ESPERANTO */ 65 | 66 | /* RETRO_LANGUAGE_POLISH */ 67 | 68 | /* RETRO_LANGUAGE_VIETNAMESE */ 69 | 70 | /* RETRO_LANGUAGE_ARABIC */ 71 | 72 | /* RETRO_LANGUAGE_GREEK */ 73 | 74 | /* RETRO_LANGUAGE_TURKISH */ 75 | 76 | struct retro_core_option_definition option_defs_tr[] = { 77 | { 78 | "vb_3dmode", 79 | "3B modu", 80 | "3B modunu seçin. Anaglif - klasik çift lens renkli camlarla birlikte kullanılır. Cyberscope - CyberScope ile kullanılmak üzere tasarlanan 3B cihaz. sidebyside - sol göz resmi solda ve sağ göz resmi sağda görüntülenir. vli - Dikey çizgiler sol ve sağ görünüm arasında değişir. hli - Yatay çizgiler sol ve sağ görünüm arasında değişir.", 81 | { 82 | { "anaglyph", "Anaglif" }, 83 | { "cyberscope", NULL }, 84 | { "side-by-side", NULL }, 85 | { "vli", NULL}, 86 | { "hli", NULL}, 87 | { NULL, NULL }, 88 | }, 89 | "anaglyph", 90 | }, 91 | { 92 | "vb_anaglyph_preset", 93 | "Anaglif Ön ayarı", 94 | "Anaglif önceden ayarlanmış renkler.", 95 | { 96 | { "disabled", "devre dışı" }, 97 | { "red & blue", NULL }, 98 | { "red & cyan", NULL }, 99 | { "red & electric cyan", NULL }, 100 | { "green & magenta", NULL }, 101 | { "yellow & blue", NULL }, 102 | { NULL, NULL}, 103 | }, 104 | "disabled", 105 | }, 106 | { 107 | "vb_color_mode", 108 | "Palet", 109 | "", 110 | { 111 | { "black & red", NULL }, 112 | { "black & white", NULL }, 113 | { "black & blue", NULL }, 114 | { "black & cyan", NULL }, 115 | { "black & electric cyan", NULL }, 116 | { "black & green", NULL }, 117 | { "black & magenta", NULL }, 118 | { "black & yellow", NULL }, 119 | { NULL, NULL}, 120 | }, 121 | "black & red", 122 | }, 123 | { 124 | "vb_right_analog_to_digital", 125 | "Dijital sağ analog", 126 | "", 127 | { 128 | { "disabled", "devre dışı" }, 129 | { "enabled", "etkin" }, 130 | { "invert x", NULL }, 131 | { "invert y", NULL }, 132 | { "invert both", NULL }, 133 | { NULL, NULL }, 134 | }, 135 | "disabled", 136 | }, 137 | { 138 | "vb_cpu_emulation", 139 | "CPU emülasyonu (Yeniden başlatma gerekir)", 140 | "Daha hızlı ve doğru (daha yavaş) emülasyon arasında seçim yapın.", 141 | { 142 | { "accurate", "doğru" }, 143 | { "fast", "hızlı" }, 144 | { NULL, NULL}, 145 | }, 146 | "fast", 147 | }, 148 | { NULL, NULL, NULL, { NULL, NULL }, NULL }, 149 | }; 150 | 151 | #ifdef __cplusplus 152 | } 153 | #endif 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /link.T: -------------------------------------------------------------------------------- 1 | { 2 | global: retro_*; 3 | local: *; 4 | }; 5 | 6 | -------------------------------------------------------------------------------- /mednafen/git.h: -------------------------------------------------------------------------------- 1 | #ifndef _GIT_H 2 | #define _GIT_H 3 | 4 | #include 5 | 6 | #include "video/surface.h" 7 | 8 | #include "state.h" 9 | 10 | struct MemoryPatch; 11 | 12 | struct CheatFormatStruct 13 | { 14 | const char *FullName; //"Game Genie", "GameShark", "Pro Action Catplay", etc. 15 | const char *Description; // Whatever? 16 | }; 17 | 18 | struct CheatFormatInfoStruct 19 | { 20 | unsigned NumFormats; 21 | 22 | struct CheatFormatStruct *Formats; 23 | }; 24 | 25 | typedef struct 26 | { 27 | // Pitch(32-bit) must be equal to width and >= the "fb_width" specified in the MDFNGI struct for the emulated system. 28 | // Height must be >= to the "fb_height" specified in the MDFNGI struct for the emulated system. 29 | // The framebuffer pointed to by surface->pixels is written to by the system emulation code. 30 | struct MDFN_Surface *surface; 31 | 32 | // Will be set to TRUE if the video pixel format has changed since the last call to Emulate(), FALSE otherwise. 33 | // Will be set to TRUE on the first call to the Emulate() function/method 34 | bool VideoFormatChanged; 35 | 36 | // Set by the system emulation code every frame, to denote the horizontal and vertical offsets of the image, and the size 37 | // of the image. If the emulated system sets the elements of LineWidths, then the horizontal offset(x) and width(w) of this structure 38 | // are ignored while drawing the image. 39 | MDFN_Rect DisplayRect; 40 | 41 | // Maximum size of the sound buffer, in frames. Set by the driver code. 42 | int32 SoundBufMaxSize; 43 | 44 | // Number of frames currently in internal sound buffer. Set by the system emulation code, to be read by the driver code. 45 | int32 SoundBufSize; 46 | } EmulateSpecStruct; 47 | 48 | #ifdef __cplusplus 49 | extern "C" { 50 | #endif 51 | int StateAction(StateMem *sm, int load, int data_only); 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /mednafen/hw_cpu/v810/fpu-new/softfloat-specialize.h: -------------------------------------------------------------------------------- 1 | 2 | /*============================================================================ 3 | 4 | This C source fragment is part of the SoftFloat IEC/IEEE Floating-point 5 | Arithmetic Package, Release 2b. 6 | 7 | Written by John R. Hauser. This work was made possible in part by the 8 | International Computer Science Institute, located at Suite 600, 1947 Center 9 | Street, Berkeley, California 94704. Funding was partially provided by the 10 | National Science Foundation under grant MIP-9311980. The original version 11 | of this code was written as part of a project to build a fixed-point vector 12 | processor in collaboration with the University of California at Berkeley, 13 | overseen by Profs. Nelson Morgan and John Wawrzynek. More information 14 | is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ 15 | arithmetic/SoftFloat.html'. 16 | 17 | THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has 18 | been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES 19 | RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS 20 | AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, 21 | COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE 22 | EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE 23 | INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR 24 | OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. 25 | 26 | Derivative works are acceptable, even for commercial purposes, so long as 27 | (1) the source code for the derivative work includes prominent notice that 28 | the work is derivative, and (2) the source code includes prominent notice with 29 | these four paragraphs for those parts of this code that are retained. 30 | 31 | =============================================================================*/ 32 | 33 | /*---------------------------------------------------------------------------- 34 | | Raises the exceptions specified by `flags'. Floating-point traps can be 35 | | defined here if desired. It is currently not possible for such a trap 36 | | to substitute a result value. If traps are not implemented, this routine 37 | | should be simply `float_exception_flags |= flags;'. 38 | *----------------------------------------------------------------------------*/ 39 | 40 | #define float_raise(flags) (float_exception_flags |= (flags)) 41 | 42 | /*---------------------------------------------------------------------------- 43 | | Internal canonical NaN format. 44 | *----------------------------------------------------------------------------*/ 45 | typedef struct { 46 | char sign; 47 | uint32_t high, low; 48 | } commonNaNT; 49 | 50 | /*---------------------------------------------------------------------------- 51 | | The pattern for a default generated single-precision NaN. 52 | *----------------------------------------------------------------------------*/ 53 | enum { 54 | float32_default_nan = 0xFFFFFFFF 55 | }; 56 | 57 | /*---------------------------------------------------------------------------- 58 | | Returns 1 if the single-precision floating-point value `a' is a NaN; 59 | | otherwise returns 0. 60 | *----------------------------------------------------------------------------*/ 61 | 62 | char float32_is_nan( float32 a ) 63 | { 64 | return ( 0xFF000000 < (uint32_t) ( a<<1 ) ); 65 | } 66 | 67 | /*---------------------------------------------------------------------------- 68 | | Returns 1 if the single-precision floating-point value `a' is a signaling 69 | | NaN; otherwise returns 0. 70 | *----------------------------------------------------------------------------*/ 71 | 72 | char float32_is_signaling_nan( float32 a ) 73 | { 74 | return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 75 | } 76 | 77 | /*---------------------------------------------------------------------------- 78 | | Takes two single-precision floating-point values `a' and `b', one of which 79 | | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 80 | | signaling NaN, the invalid exception is raised. 81 | *----------------------------------------------------------------------------*/ 82 | 83 | static float32 propagateFloat32NaN( float32 a, float32 b ) 84 | { 85 | char aIsNaN = float32_is_nan( a ); 86 | char aIsSignalingNaN = float32_is_signaling_nan( a ); 87 | char bIsNaN = float32_is_nan( b ); 88 | char bIsSignalingNaN = float32_is_signaling_nan( b ); 89 | a |= 0x00400000; 90 | b |= 0x00400000; 91 | if ( aIsSignalingNaN | bIsSignalingNaN ) 92 | float_raise( float_flag_invalid ); 93 | if ( aIsNaN ) 94 | return ( aIsSignalingNaN & bIsNaN ) ? b : a; 95 | return b; 96 | } 97 | -------------------------------------------------------------------------------- /mednafen/hw_cpu/v810/fpu-new/softfloat.h: -------------------------------------------------------------------------------- 1 | 2 | /*============================================================================ 3 | 4 | This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic 5 | Package, Release 2b. 6 | 7 | Written by John R. Hauser. This work was made possible in part by the 8 | International Computer Science Institute, located at Suite 600, 1947 Center 9 | Street, Berkeley, California 94704. Funding was partially provided by the 10 | National Science Foundation under grant MIP-9311980. The original version 11 | of this code was written as part of a project to build a fixed-point vector 12 | processor in collaboration with the University of California at Berkeley, 13 | overseen by Profs. Nelson Morgan and John Wawrzynek. More information 14 | is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ 15 | arithmetic/SoftFloat.html'. 16 | 17 | THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has 18 | been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES 19 | RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS 20 | AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, 21 | COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE 22 | EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE 23 | INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR 24 | OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. 25 | 26 | Derivative works are acceptable, even for commercial purposes, so long as 27 | (1) the source code for the derivative work includes prominent notice that 28 | the work is derivative, and (2) the source code includes prominent notice with 29 | these four paragraphs for those parts of this code that are retained. 30 | 31 | =============================================================================*/ 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #include "../../../mednafen-types.h" 38 | 39 | /*---------------------------------------------------------------------------- 40 | | Software IEC/IEEE floating-point types. 41 | *----------------------------------------------------------------------------*/ 42 | typedef uint32 float32; 43 | 44 | /*---------------------------------------------------------------------------- 45 | | Software IEC/IEEE floating-point rounding mode. 46 | *----------------------------------------------------------------------------*/ 47 | enum { 48 | float_round_nearest_even = 0, 49 | float_round_to_zero = 1, 50 | float_round_down = 2, 51 | float_round_up = 3 52 | }; 53 | 54 | /*---------------------------------------------------------------------------- 55 | | Software IEC/IEEE floating-point exception flags. 56 | *----------------------------------------------------------------------------*/ 57 | extern int8 float_exception_flags; 58 | enum { 59 | float_flag_inexact = 1, 60 | float_flag_underflow = 2, 61 | float_flag_overflow = 4, 62 | float_flag_divbyzero = 8, 63 | float_flag_invalid = 16 64 | }; 65 | 66 | /*---------------------------------------------------------------------------- 67 | | Routine to raise any or all of the software IEC/IEEE floating-point 68 | | exception flags. 69 | *----------------------------------------------------------------------------*/ 70 | void float_raise( int8 ); 71 | 72 | /*---------------------------------------------------------------------------- 73 | | Software IEC/IEEE integer-to-floating-point conversion routines. 74 | *----------------------------------------------------------------------------*/ 75 | float32 int32_to_float32( int32 ); 76 | 77 | /*---------------------------------------------------------------------------- 78 | | Software IEC/IEEE single-precision conversion routines. 79 | *----------------------------------------------------------------------------*/ 80 | int32 float32_to_int32( float32 ); 81 | int32 float32_to_int32_round_to_zero( float32 ); 82 | 83 | /*---------------------------------------------------------------------------- 84 | | Software IEC/IEEE single-precision operations. 85 | *----------------------------------------------------------------------------*/ 86 | float32 float32_round_to_int( float32 ); 87 | float32 float32_add( float32, float32 ); 88 | float32 float32_sub( float32, float32 ); 89 | float32 float32_mul( float32, float32 ); 90 | float32 float32_div( float32, float32 ); 91 | float32 float32_rem( float32, float32 ); 92 | float32 float32_sqrt( float32 ); 93 | char float32_eq( float32, float32 ); 94 | char float32_le( float32, float32 ); 95 | char float32_lt( float32, float32 ); 96 | char float32_eq_signaling( float32, float32 ); 97 | char float32_le_quiet( float32, float32 ); 98 | char float32_lt_quiet( float32, float32 ); 99 | char float32_is_signaling_nan( float32 ); 100 | 101 | #ifdef __cplusplus 102 | }; 103 | #endif 104 | -------------------------------------------------------------------------------- /mednafen/hw_cpu/v810/v810_cpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Defines for the V810 CPU 3 | */ 4 | 5 | #ifndef V810_CPU_H_ 6 | #define V810_CPU_H_ 7 | 8 | #include "fpu-new/softfloat.h" 9 | #include "../../mednafen-types.h" 10 | #include "../../state.h" 11 | 12 | #define V810_FAST_MAP_SHIFT 16 13 | #define V810_FAST_MAP_PSIZE (1 << V810_FAST_MAP_SHIFT) 14 | #define V810_FAST_MAP_TRAMPOLINE_SIZE 1024 15 | 16 | /* Exception codes */ 17 | enum 18 | { 19 | ECODE_TRAP_BASE = 0xFFA0, 20 | ECODE_INVALID_OP = 0xFF90, 21 | ECODE_ZERO_DIV = 0xFF80, // Integer divide by 0 22 | ECODE_FIV = 0xFF70, // Floating point invalid operation 23 | ECODE_FZD = 0xFF68, // Floating point zero division 24 | ECODE_FOV = 0xFF64, // Floating point overflow 25 | #if 0 26 | #define ECODE_FUD 0xFF62 // Floating point underflow(unused on V810) 27 | #define ECODE_FPR 0xFF61 // Floating point precision degradation(unused on V810) 28 | #endif 29 | ECODE_FRO = 0xFF60 // Floating point reserved operand 30 | }; 31 | 32 | enum 33 | { 34 | INVALID_OP_HANDLER_ADDR = 0xFFFFFF90, /* Invalid opcode/instruction code! */ 35 | ZERO_DIV_HANDLER_ADDR = 0xFFFFFF80, /* Integer divide by 0 exception */ 36 | FPU_HANDLER_ADDR = 0xFFFFFF60, /* FPU exception */ 37 | TRAP_HANDLER_BASE = 0xFFFFFFA0 /* TRAP instruction */ 38 | }; 39 | 40 | /* System Register Defines (these are the only valid system registers!) */ 41 | #define EIPC 0 /* Exception/Interupt PC */ 42 | #define EIPSW 1 /* Exception/Interupt PSW */ 43 | 44 | #define FEPC 2 /* Fatal Error PC */ 45 | #define FEPSW 3 /* Fatal Error PSW */ 46 | 47 | #define ECR 4 /* Exception Cause Register */ 48 | #define PSW 5 /* Program Status Word */ 49 | #define PIR 6 /* Processor ID Register */ 50 | #define TKCW 7 /* Task Control Word */ 51 | #define CHCW 24 /* Cache Control Word */ 52 | #define ADDTRE 25 /* ADDTRE */ 53 | 54 | /* PSW Specifics */ 55 | #define PSW_IA 0xF0000 /* All Interupt bits... */ 56 | #define PSW_I3 0x80000 57 | #define PSW_I2 0x40000 58 | #define PSW_I1 0x20000 59 | #define PSW_I0 0x10000 60 | 61 | #define PSW_NP 0x08000 62 | #define PSW_EP 0x04000 63 | 64 | #define PSW_AE 0x02000 65 | 66 | #define PSW_ID 0x01000 67 | 68 | #define PSW_FRO 0x00200 /* Floating point reserved operand 69 | (set on denormal, NaN, 70 | or indefinite) */ 71 | #define PSW_FIV 0x00100 /* Floating point invalid operation 72 | (set when trying to convert a number 73 | too large to an (un)signed integer) */ 74 | 75 | #define PSW_FZD 0x00080 /* Floating point divide by zero */ 76 | #define PSW_FOV 0x00040 /* Floating point overflow */ 77 | #define PSW_FUD 0x00020 /* Floating point underflow */ 78 | #define PSW_FPR 0x00010 /* Floating point precision degradation */ 79 | 80 | #define PSW_CY 0x00008 81 | #define PSW_OV 0x00004 82 | #define PSW_S 0x00002 83 | #define PSW_Z 0x00001 84 | 85 | /* condition codes */ 86 | #define COND_V 0 87 | #define COND_C 1 88 | #define COND_Z 2 89 | #define COND_NH 3 90 | #define COND_S 4 91 | #define COND_T 5 92 | #define COND_LT 6 93 | #define COND_LE 7 94 | #define COND_NV 8 95 | #define COND_NC 9 96 | #define COND_NZ 10 97 | #define COND_H 11 98 | #define COND_NS 12 99 | #define COND_F 13 100 | #define COND_GE 14 101 | #define COND_GT 15 102 | 103 | #define TESTCOND_V (S_REG[PSW]&PSW_OV) 104 | 105 | #define TESTCOND_L (S_REG[PSW]&PSW_CY) 106 | #define TESTCOND_C TESTCOND_L 107 | 108 | #define TESTCOND_E (S_REG[PSW]&PSW_Z) 109 | #define TESTCOND_Z TESTCOND_E 110 | 111 | #define TESTCOND_NH ( (S_REG[PSW]&PSW_Z) || (S_REG[PSW]&PSW_CY) ) 112 | #define TESTCOND_N (S_REG[PSW]&PSW_S) 113 | #define TESTCOND_S TESTCOND_N 114 | 115 | #define TESTCOND_LT ( (!!(S_REG[PSW]&PSW_S)) ^ (!!(S_REG[PSW]&PSW_OV)) ) 116 | #define TESTCOND_LE ( ((!!(S_REG[PSW]&PSW_S)) ^ (!!(S_REG[PSW]&PSW_OV))) || (S_REG[PSW]&PSW_Z) ) 117 | #define TESTCOND_NV (!(S_REG[PSW]&PSW_OV)) 118 | 119 | #define TESTCOND_NL (!(S_REG[PSW]&PSW_CY)) 120 | #define TESTCOND_NC TESTCOND_NL 121 | 122 | #define TESTCOND_NE (!(S_REG[PSW]&PSW_Z)) 123 | #define TESTCOND_NZ TESTCOND_NE 124 | 125 | #define TESTCOND_H ( !((S_REG[PSW]&PSW_Z) || (S_REG[PSW]&PSW_CY)) ) 126 | #define TESTCOND_P (!(S_REG[PSW] & PSW_S)) 127 | #define TESTCOND_NS TESTCOND_P 128 | 129 | #define TESTCOND_GE (!((!!(S_REG[PSW]&PSW_S))^(!!(S_REG[PSW]&PSW_OV)))) 130 | #define TESTCOND_GT (! (((!!(S_REG[PSW]&PSW_S))^(!!(S_REG[PSW]&PSW_OV))) || (S_REG[PSW]&PSW_Z)) ) 131 | 132 | /* Tag layout 133 | * Bit 0-21: TAG31-TAG10 134 | * Bit 22-23: Validity bits(one for each 4-byte subblock) 135 | * Bit 24-27: NECRV("Reserved") 136 | * Bit 28-31: 0 137 | */ 138 | 139 | typedef enum 140 | { 141 | V810_EMU_MODE_FAST = 0, 142 | V810_EMU_MODE_ACCURATE = 1, 143 | _V810_EMU_MODE_COUNT 144 | } V810_Emu_Mode; 145 | 146 | /* 147 | * WARNING: Do NOT instantiate this class in multiple threads in such a way that both threads can be inside a method of this class at the same time. 148 | * To fix this, you'll need to put locks or something(re-engineer it to use state passed in through pointers) around the SoftFloat code. 149 | */ 150 | 151 | 152 | class V810 153 | { 154 | public: 155 | 156 | V810(); 157 | ~V810(); 158 | 159 | /* Pass TRUE for vb_mode if we're emulating a VB-specific 160 | enhanced V810 CPU core 161 | */ 162 | bool Init(V810_Emu_Mode mode, bool vb_mode); 163 | void Kill(void); 164 | 165 | void SetInt(int level); 166 | 167 | void SetMemWriteBus32(uint8 A, bool value); 168 | void SetMemReadBus32(uint8 A, bool value); 169 | 170 | void SetMemReadHandlers(uint8 MDFN_FASTCALL (*read8)(v810_timestamp_t &, uint32), uint16 MDFN_FASTCALL (*read16)(v810_timestamp_t &, uint32), uint32 MDFN_FASTCALL (*read32)(v810_timestamp_t &, uint32)); 171 | void SetMemWriteHandlers(void MDFN_FASTCALL (*write8)(v810_timestamp_t &, uint32, uint8), void MDFN_FASTCALL (*write16)(v810_timestamp_t &, uint32, uint16), void MDFN_FASTCALL (*write32)(v810_timestamp_t &, uint32, uint32)); 172 | 173 | void SetIOReadHandlers(uint8 MDFN_FASTCALL (*read8)(v810_timestamp_t &, uint32), uint16 MDFN_FASTCALL (*read16)(v810_timestamp_t &, uint32), uint32 MDFN_FASTCALL (*read32)(v810_timestamp_t &, uint32)); 174 | void SetIOWriteHandlers(void MDFN_FASTCALL (*write8)(v810_timestamp_t &, uint32, uint8), void MDFN_FASTCALL (*write16)(v810_timestamp_t &, uint32, uint16), void MDFN_FASTCALL (*write32)(v810_timestamp_t &, uint32, uint32)); 175 | 176 | /* Length specifies the number of bytes to map in, 177 | * at each location specified 178 | * by addresses[] (for mirroring) */ 179 | uint8 *SetFastMap(uint32 addresses[], uint32 length, unsigned int num_addresses, const char *name); 180 | 181 | INLINE void ResetTS(v810_timestamp_t new_base_timestamp) 182 | { 183 | next_event_ts -= (v810_timestamp - new_base_timestamp); 184 | v810_timestamp = new_base_timestamp; 185 | } 186 | 187 | INLINE void SetEventNT(const v810_timestamp_t timestamp) 188 | { 189 | next_event_ts = timestamp; 190 | } 191 | 192 | INLINE v810_timestamp_t GetEventNT(void) 193 | { 194 | return(next_event_ts); 195 | } 196 | 197 | v810_timestamp_t Run(int32 MDFN_FASTCALL (*event_handler)(const v810_timestamp_t timestamp)); 198 | void Exit(void); 199 | 200 | void Reset(void); 201 | 202 | int StateAction(StateMem *sm, int load, int data_only); 203 | 204 | uint32 GetPC(void); 205 | void SetPC(uint32); 206 | 207 | uint32 GetPR(const unsigned int which); 208 | void SetPR(const unsigned int which, uint32 value); 209 | 210 | uint32 GetSR(const unsigned int which); 211 | 212 | private: 213 | 214 | /* Make sure P_REG[] is the first variable/array in this class, 215 | so non-zero offset encoding (at assembly level) 216 | isn't necessary to access it. 217 | */ 218 | uint32 P_REG[32]; /* Program registers PR0-PR31 */ 219 | uint32 S_REG[32]; /* System registers SR0-SR31 */ 220 | uint32 PC; 221 | uint8 *PC_ptr; 222 | uint8 *PC_base; 223 | 224 | uint32 IPendingCache; 225 | void RecalcIPendingCache(void); 226 | 227 | public: 228 | v810_timestamp_t v810_timestamp; /* Will never be less than 0. */ 229 | 230 | private: 231 | v810_timestamp_t next_event_ts; 232 | 233 | enum 234 | { 235 | LASTOP_NORMAL = 0, 236 | LASTOP_LOAD = 1, 237 | LASTOP_STORE = 2, 238 | LASTOP_IN = 3, 239 | LASTOP_OUT = 4, 240 | LASTOP_HEAVY_MATH = 5 241 | }; 242 | 243 | V810_Emu_Mode EmuMode; 244 | bool VBMode; 245 | 246 | void Run_Fast(int32 MDFN_FASTCALL (*event_handler)(const v810_timestamp_t timestamp)) NO_INLINE; 247 | void Run_Accurate(int32 MDFN_FASTCALL (*event_handler)(const v810_timestamp_t timestamp)) NO_INLINE; 248 | 249 | uint8 MDFN_FASTCALL (*MemRead8)(v810_timestamp_t ×tamp, uint32 A); 250 | uint16 MDFN_FASTCALL (*MemRead16)(v810_timestamp_t ×tamp, uint32 A); 251 | uint32 MDFN_FASTCALL (*MemRead32)(v810_timestamp_t ×tamp, uint32 A); 252 | 253 | void MDFN_FASTCALL (*MemWrite8)(v810_timestamp_t ×tamp, uint32 A, uint8 V); 254 | void MDFN_FASTCALL (*MemWrite16)(v810_timestamp_t ×tamp, uint32 A, uint16 V); 255 | void MDFN_FASTCALL (*MemWrite32)(v810_timestamp_t ×tamp, uint32 A, uint32 V); 256 | 257 | uint8 MDFN_FASTCALL (*IORead8)(v810_timestamp_t ×tamp, uint32 A); 258 | uint16 MDFN_FASTCALL (*IORead16)(v810_timestamp_t ×tamp, uint32 A); 259 | uint32 MDFN_FASTCALL (*IORead32)(v810_timestamp_t ×tamp, uint32 A); 260 | 261 | void MDFN_FASTCALL (*IOWrite8)(v810_timestamp_t ×tamp, uint32 A, uint8 V); 262 | void MDFN_FASTCALL (*IOWrite16)(v810_timestamp_t ×tamp, uint32 A, uint16 V); 263 | void MDFN_FASTCALL (*IOWrite32)(v810_timestamp_t ×tamp, uint32 A, uint32 V); 264 | 265 | bool MemReadBus32[256]; /* Corresponding to the upper 8 bits 266 | of the memory address map. */ 267 | bool MemWriteBus32[256]; 268 | 269 | int32 lastop; /* Set to -1 on FP/MUL/DIV, 0x100 on LD, 0x200 on ST, 270 | 0x400 on in, 271 | 0x800 on out, and the actual 272 | opcode * 2(or >= 0) on everything else. */ 273 | 274 | #define LASTOP_LD 0x100 275 | #define LASTOP_ST 0x200 276 | #define LASTOP_IN 0x400 277 | #define LASTOP_OUT 0x800 278 | 279 | enum 280 | { 281 | HALT_NONE = 0, 282 | HALT_HALT = 1, 283 | HALT_FATAL_EXCEPTION = 2 284 | }; 285 | 286 | uint8 Halted; 287 | 288 | bool Running; 289 | 290 | int ilevel; 291 | 292 | bool in_bstr; 293 | uint16 in_bstr_to; 294 | 295 | bool bstr_subop(v810_timestamp_t ×tamp, int sub_op, int arg1); 296 | void fpu_subop(v810_timestamp_t ×tamp, int sub_op, int arg1, int arg2); 297 | 298 | void Exception(uint32 handler, uint16 eCode); 299 | 300 | /* Caching-related: */ 301 | typedef struct 302 | { 303 | uint32 tag; 304 | uint32 data[2]; 305 | bool data_valid[2]; 306 | } V810_CacheEntry_t; 307 | 308 | V810_CacheEntry_t Cache[128]; 309 | 310 | /* Bitstring variables. */ 311 | uint32 src_cache; 312 | uint32 dst_cache; 313 | bool have_src_cache, have_dst_cache; 314 | 315 | uint8 *FastMap[(1ULL << 32) / V810_FAST_MAP_PSIZE]; 316 | uint8 *FastMapAllocList; 317 | 318 | /* For CacheDump and CacheRestore */ 319 | void CacheOpMemStore(v810_timestamp_t ×tamp, uint32 A, uint32 V); 320 | uint32 CacheOpMemLoad(v810_timestamp_t ×tamp, uint32 A); 321 | 322 | void CacheClear(v810_timestamp_t ×tamp, uint32 start, uint32 count); 323 | void CacheDump(v810_timestamp_t ×tamp, const uint32 SA); 324 | void CacheRestore(v810_timestamp_t ×tamp, const uint32 SA); 325 | 326 | uint32 RDCACHE(v810_timestamp_t ×tamp, uint32 addr); 327 | 328 | /* 329 | * End caching related 330 | */ 331 | 332 | uint16 RDOP(v810_timestamp_t ×tamp, uint32 addr, uint32 meow); 333 | void SetFlag(uint32 n, bool condition); 334 | void SetSZ(uint32 value); 335 | 336 | void SetSREG(v810_timestamp_t ×tamp, unsigned int which, uint32 value); 337 | uint32 GetSREG(unsigned int which); 338 | 339 | 340 | bool IsSubnormal(uint32 fpval); 341 | void FPU_Math_Template(float32 (*func)(float32, float32), uint32 arg1, uint32 arg2); 342 | void FPU_DoException(void); 343 | bool CheckFPInputException(uint32 fpval); 344 | bool FPU_DoesExceptionKillResult(void); 345 | void SetFPUOPNonFPUFlags(uint32 result); 346 | 347 | 348 | uint32 BSTR_RWORD(v810_timestamp_t ×tamp, uint32 A); 349 | void BSTR_WWORD(v810_timestamp_t ×tamp, uint32 A, uint32 V); 350 | bool Do_BSTR_Search(v810_timestamp_t ×tamp, const int inc_mul, unsigned int bit_test); 351 | 352 | 353 | uint8 DummyRegion[V810_FAST_MAP_PSIZE + V810_FAST_MAP_TRAMPOLINE_SIZE]; 354 | }; 355 | 356 | #endif 357 | 358 | -------------------------------------------------------------------------------- /mednafen/hw_cpu/v810/v810_do_am.h: -------------------------------------------------------------------------------- 1 | #define DO_MOV_AM(); DO_AM_I(); 2 | #define DO_ADD_AM(); DO_AM_I(); 3 | #define DO_SUB_AM(); DO_AM_I(); 4 | #define DO_CMP_AM(); DO_AM_I(); 5 | #define DO_SHL_AM(); DO_AM_I(); 6 | #define DO_SHR_AM(); DO_AM_I(); 7 | #define DO_JMP_AM(); DO_AM_I(); 8 | #define DO_SAR_AM(); DO_AM_I(); 9 | #define DO_MUL_AM(); DO_AM_I(); 10 | #define DO_DIV_AM(); DO_AM_I(); 11 | #define DO_MULU_AM(); DO_AM_I(); 12 | #define DO_DIVU_AM(); DO_AM_I(); 13 | #define DO_OR_AM(); DO_AM_I(); 14 | #define DO_AND_AM(); DO_AM_I(); 15 | #define DO_XOR_AM(); DO_AM_I(); 16 | #define DO_NOT_AM(); DO_AM_I(); 17 | #define DO_MOV_I_AM(); DO_AM_II(); 18 | #define DO_ADD_I_AM(); DO_AM_II(); 19 | #define DO_SETF_AM(); DO_AM_II(); 20 | #define DO_CMP_I_AM(); DO_AM_II(); 21 | #define DO_SHL_I_AM(); DO_AM_II(); 22 | #define DO_SHR_I_AM(); DO_AM_II(); 23 | #define DO_EI_AM(); DO_AM_II(); 24 | #define DO_SAR_I_AM(); DO_AM_II(); 25 | #define DO_TRAP_AM(); DO_AM_II(); 26 | #define DO_RETI_AM(); DO_AM_IX(); 27 | #define DO_HALT_AM(); DO_AM_IX(); 28 | #define DO_LDSR_AM(); DO_AM_II(); 29 | #define DO_STSR_AM(); DO_AM_II(); 30 | #define DO_DI_AM(); DO_AM_II(); 31 | #define DO_BSTR_AM(); DO_AM_BSTR(); 32 | #define DO_MOVEA_AM(); DO_AM_V(); 33 | #define DO_ADDI_AM(); DO_AM_V(); 34 | #define DO_JR_AM(); DO_AM_IV(); 35 | #define DO_JAL_AM(); DO_AM_IV(); 36 | #define DO_ORI_AM(); DO_AM_V(); 37 | #define DO_ANDI_AM(); DO_AM_V(); 38 | #define DO_XORI_AM(); DO_AM_V(); 39 | #define DO_MOVHI_AM(); DO_AM_V(); 40 | #define DO_LD_B_AM(); DO_AM_VIa(); 41 | #define DO_LD_H_AM(); DO_AM_VIa(); 42 | #define DO_LD_W_AM(); DO_AM_VIa(); 43 | #define DO_ST_B_AM(); DO_AM_VIb(); 44 | #define DO_ST_H_AM(); DO_AM_VIb(); 45 | #define DO_ST_W_AM(); DO_AM_VIb(); 46 | #define DO_IN_B_AM(); DO_AM_VIa(); 47 | #define DO_IN_H_AM(); DO_AM_VIa(); 48 | #define DO_CAXI_AM(); DO_AM_VIa(); 49 | #define DO_IN_W_AM(); DO_AM_VIa(); 50 | #define DO_OUT_B_AM(); DO_AM_VIb(); 51 | #define DO_OUT_H_AM(); DO_AM_VIb(); 52 | #define DO_FPP_AM(); DO_AM_FPP(); 53 | #define DO_OUT_W_AM(); DO_AM_VIb(); 54 | #define DO_BV_AM(); DO_AM_III(); 55 | #define DO_BL_AM(); DO_AM_III(); 56 | #define DO_BE_AM(); DO_AM_III(); 57 | #define DO_BNH_AM(); DO_AM_III(); 58 | #define DO_BN_AM(); DO_AM_III(); 59 | #define DO_BR_AM(); DO_AM_III(); 60 | #define DO_BLT_AM(); DO_AM_III(); 61 | #define DO_BLE_AM(); DO_AM_III(); 62 | #define DO_BNV_AM(); DO_AM_III(); 63 | #define DO_BNL_AM(); DO_AM_III(); 64 | #define DO_BNE_AM(); DO_AM_III(); 65 | #define DO_BH_AM(); DO_AM_III(); 66 | #define DO_BP_AM(); DO_AM_III(); 67 | #define DO_NOP_AM(); DO_AM_III(); 68 | #define DO_BGE_AM(); DO_AM_III(); 69 | #define DO_BGT_AM(); DO_AM_III(); 70 | 71 | 72 | #define DO_INVALID_AM(); DO_AM_UDEF(); 73 | -------------------------------------------------------------------------------- /mednafen/hw_cpu/v810/v810_op_table.inc: -------------------------------------------------------------------------------- 1 | 2 | &&op_MOV, &&op_MOV, &&op_ADD, &&op_ADD, &&op_SUB, &&op_SUB, &&op_CMP, &&op_CMP, 3 | &&op_SHL, &&op_SHL, &&op_SHR, &&op_SHR, &&op_JMP, &&op_JMP, &&op_SAR, &&op_SAR, 4 | &&op_MUL, &&op_MUL, &&op_DIV, &&op_DIV, &&op_MULU, &&op_MULU, &&op_DIVU, &&op_DIVU, 5 | &&op_OR, &&op_OR, &&op_AND, &&op_AND, &&op_XOR, &&op_XOR, &&op_NOT, &&op_NOT, 6 | &&op_MOV_I, &&op_MOV_I, &&op_ADD_I, &&op_ADD_I, &&op_SETF, &&op_SETF, &&op_CMP_I, &&op_CMP_I, 7 | &&op_SHL_I, &&op_SHL_I, &&op_SHR_I, &&op_SHR_I, &&op_EI, &&op_EI, &&op_SAR_I, &&op_SAR_I, 8 | &&op_TRAP, &&op_TRAP, &&op_RETI, &&op_RETI, &&op_HALT, &&op_HALT, &&op_INVALID, &&op_INVALID, 9 | &&op_LDSR, &&op_LDSR, &&op_STSR, &&op_STSR, &&op_DI, &&op_DI, &&op_BSTR, &&op_BSTR, 10 | &&op_BV, &&op_BL, &&op_BE, &&op_BNH, &&op_BN, &&op_BR, &&op_BLT, &&op_BLE, 11 | &&op_BNV, &&op_BNL, &&op_BNE, &&op_BH, &&op_BP, &&op_NOP, &&op_BGE, &&op_BGT, 12 | &&op_MOVEA, &&op_MOVEA, &&op_ADDI, &&op_ADDI, &&op_JR, &&op_JR, &&op_JAL, &&op_JAL, 13 | &&op_ORI, &&op_ORI, &&op_ANDI, &&op_ANDI, &&op_XORI, &&op_XORI, &&op_MOVHI, &&op_MOVHI, 14 | &&op_LD_B, &&op_LD_B, &&op_LD_H, &&op_LD_H, &&op_INVALID, &&op_INVALID, &&op_LD_W, &&op_LD_W, 15 | &&op_ST_B, &&op_ST_B, &&op_ST_H, &&op_ST_H, &&op_INVALID, &&op_INVALID, &&op_ST_W, &&op_ST_W, 16 | &&op_IN_B, &&op_IN_B, &&op_IN_H, &&op_IN_H, &&op_CAXI, &&op_CAXI, &&op_IN_W, &&op_IN_W, 17 | &&op_OUT_B, &&op_OUT_B, &&op_OUT_H, &&op_OUT_H, &&op_FPP, &&op_FPP, &&op_OUT_W, &&op_OUT_W, 18 | 19 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 20 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 21 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 22 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 23 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 24 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 25 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 26 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 27 | 28 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 29 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 30 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 31 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 32 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 33 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 34 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, 35 | &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INVALID, &&op_INT_HANDLER 36 | 37 | -------------------------------------------------------------------------------- /mednafen/hw_cpu/v810/v810_op_table_msvc.inc: -------------------------------------------------------------------------------- 1 | switch(opcode) 2 | { 3 | case 0: 4 | case 1: 5 | goto op_MOV; 6 | break; 7 | case 2: 8 | case 3: 9 | goto op_ADD; 10 | break; 11 | case 4: 12 | case 5: 13 | goto op_SUB; 14 | break; 15 | case 6: 16 | case 7: 17 | goto op_CMP; 18 | break; 19 | case 8: 20 | case 9: 21 | goto op_SHL; 22 | break; 23 | case 10: 24 | case 11: 25 | goto op_SHR; 26 | break; 27 | case 12: 28 | case 13: 29 | goto op_JMP; 30 | break; 31 | case 14: 32 | case 15: 33 | goto op_SAR; 34 | break; 35 | case 16: 36 | case 17: 37 | goto op_MUL; 38 | break; 39 | case 18: 40 | case 19: 41 | goto op_DIV; 42 | break; 43 | case 20: 44 | case 21: 45 | goto op_MULU; 46 | break; 47 | case 22: 48 | case 23: 49 | goto op_DIVU; 50 | break; 51 | case 24: 52 | case 25: 53 | goto op_OR; 54 | break; 55 | case 26: 56 | case 27: 57 | goto op_AND; 58 | break; 59 | case 28: 60 | case 29: 61 | goto op_XOR; 62 | break; 63 | case 30: 64 | case 31: 65 | goto op_NOT; 66 | break; 67 | case 32: 68 | case 33: 69 | goto op_MOV_I; 70 | break; 71 | case 34: 72 | case 35: 73 | goto op_ADD_I; 74 | break; 75 | case 36: 76 | case 37: 77 | goto op_SETF; 78 | break; 79 | case 38: 80 | case 39: 81 | goto op_CMP_I; 82 | break; 83 | case 40: 84 | case 41: 85 | goto op_SHL_I; 86 | break; 87 | case 42: 88 | case 43: 89 | goto op_SHR_I; 90 | break; 91 | case 44: 92 | case 45: 93 | goto op_EI; 94 | break; 95 | case 46: 96 | case 47: 97 | goto op_SAR_I; 98 | break; 99 | case 48: 100 | case 49: 101 | goto op_TRAP; 102 | break; 103 | case 50: 104 | case 51: 105 | goto op_RETI; 106 | break; 107 | case 52: 108 | case 53: 109 | goto op_HALT; 110 | break; 111 | case 54: 112 | case 55: 113 | goto op_INVALID; 114 | break; 115 | case 56: 116 | case 57: 117 | goto op_LDSR; 118 | break; 119 | case 58: 120 | case 59: 121 | goto op_STSR; 122 | break; 123 | case 60: 124 | case 61: 125 | goto op_DI; 126 | break; 127 | case 62: 128 | case 63: 129 | goto op_BSTR; 130 | break; 131 | case 64: 132 | goto op_BV; 133 | break; 134 | case 65: 135 | goto op_BL; 136 | break; 137 | case 66: 138 | goto op_BE; 139 | break; 140 | case 67: 141 | goto op_BNH; 142 | break; 143 | case 68: 144 | goto op_BN; 145 | break; 146 | case 69: 147 | goto op_BR; 148 | break; 149 | case 70: 150 | goto op_BLT; 151 | break; 152 | case 71: 153 | goto op_BLE; 154 | break; 155 | case 72: 156 | goto op_BNV; 157 | break; 158 | case 73: 159 | goto op_BNL; 160 | break; 161 | case 74: 162 | goto op_BNE; 163 | break; 164 | case 75: 165 | goto op_BH; 166 | break; 167 | case 76: 168 | goto op_BP; 169 | break; 170 | case 77: 171 | goto op_NOP; 172 | break; 173 | case 78: 174 | goto op_BGE; 175 | break; 176 | case 79: 177 | goto op_BGT; 178 | break; 179 | case 80: 180 | case 81: 181 | goto op_MOVEA; 182 | break; 183 | case 82: 184 | case 83: 185 | goto op_ADDI; 186 | break; 187 | case 84: 188 | case 85: 189 | goto op_JR; 190 | break; 191 | case 86: 192 | case 87: 193 | goto op_JAL; 194 | break; 195 | case 88: 196 | case 89: 197 | goto op_ORI; 198 | break; 199 | case 90: 200 | case 91: 201 | goto op_ANDI; 202 | break; 203 | case 92: 204 | case 93: 205 | goto op_XORI; 206 | break; 207 | case 94: 208 | case 95: 209 | goto op_MOVHI; 210 | break; 211 | case 96: 212 | case 97: 213 | goto op_LD_B; 214 | break; 215 | case 98: 216 | case 99: 217 | goto op_LD_H; 218 | break; 219 | case 100: 220 | case 101: 221 | goto op_INVALID; 222 | break; 223 | case 102: 224 | case 103: 225 | goto op_LD_W; 226 | break; 227 | case 104: 228 | case 105: 229 | goto op_ST_B; 230 | break; 231 | case 106: 232 | case 107: 233 | goto op_ST_H; 234 | break; 235 | case 108: 236 | case 109: 237 | goto op_INVALID; 238 | break; 239 | case 110: 240 | case 111: 241 | goto op_ST_W; 242 | break; 243 | case 112: 244 | case 113: 245 | goto op_IN_B; 246 | break; 247 | case 114: 248 | case 115: 249 | goto op_IN_H; 250 | break; 251 | case 116: 252 | case 117: 253 | goto op_CAXI; 254 | break; 255 | case 118: 256 | case 119: 257 | goto op_IN_W; 258 | break; 259 | case 120: 260 | case 121: 261 | goto op_OUT_B; 262 | break; 263 | case 122: 264 | case 123: 265 | goto op_OUT_H; 266 | break; 267 | case 124: 268 | case 125: 269 | goto op_FPP; 270 | break; 271 | case 126: 272 | case 127: 273 | goto op_OUT_W; 274 | break; 275 | case 255: 276 | goto op_INT_HANDLER; 277 | break; 278 | default: 279 | goto op_INVALID; 280 | break; 281 | } 282 | -------------------------------------------------------------------------------- /mednafen/hw_cpu/v810/v810_opt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: v810_opt.h 3 | * 4 | * Description: Defines used in v810_dis.cpp 5 | */ 6 | 7 | #ifndef V810_OPT_H_ 8 | #define V810_OPT_H_ 9 | 10 | #define sign_26(num) ((uint32)sign_x_to_s32(26, num)) 11 | #define sign_16(num) ((uint32)(int16)(num)) 12 | #define sign_14(num) ((uint32)sign_x_to_s32(14, num)) 13 | #define sign_12(num) ((uint32)sign_x_to_s32(12, num)) 14 | #define sign_9(num) ((uint32)sign_x_to_s32(9, num)) 15 | #define sign_8(_value) ((uint32)(int8)(_value)) 16 | #define sign_5(num) ((uint32)sign_x_to_s32(5, num)) 17 | 18 | /* 19 | * Define Modes 20 | */ 21 | #define AM_I 0x01 22 | #define AM_II 0x02 23 | #define AM_III 0x03 24 | #define AM_IV 0x04 25 | #define AM_V 0x05 26 | #define AM_VIa 0x06 /* Mode6 form1 */ 27 | #define AM_VIb 0x0A /* Mode6 form2 */ 28 | #define AM_VII 0x07 29 | #define AM_VIII 0x08 30 | #define AM_IX 0x09 31 | #define AM_BSTR 0x0B /* Bit String Instructions */ 32 | #define AM_FPP 0x0C /* Floating Point Instructions */ 33 | #define AM_UDEF 0x0D /* Unknown/Undefined Instructions */ 34 | 35 | /* 36 | * Opcodes for V810 Instruction set 37 | */ 38 | #define MOV 0x00 39 | #define ADD 0x01 40 | #define SUB 0x02 41 | #define CMP 0x03 42 | #define SHL 0x04 43 | #define SHR 0x05 44 | #define JMP 0x06 45 | #define SAR 0x07 46 | #define MUL 0x08 47 | #define DIV 0x09 48 | #define MULU 0x0A 49 | #define DIVU 0x0B 50 | #define OR 0x0C 51 | #define AND 0x0D 52 | #define XOR 0x0E 53 | #define NOT 0x0F 54 | #define MOV_I 0x10 55 | #define ADD_I 0x11 56 | #define SETF 0x12 57 | #define CMP_I 0x13 58 | #define SHL_I 0x14 59 | #define SHR_I 0x15 60 | #define EI 0x16 61 | #define SAR_I 0x17 62 | #define TRAP 0x18 63 | #define RETI 0x19 64 | #define HALT 0x1A 65 | //0x1B 66 | #define LDSR 0x1C 67 | #define STSR 0x1D 68 | #define DI 0x1E 69 | #define BSTR 0x1F //Special Bit String Inst 70 | //0x20 - 0x27 // Lost to Branch Instructions 71 | #define MOVEA 0x28 72 | #define ADDI 0x29 73 | #define JR 0x2A 74 | #define JAL 0x2B 75 | #define ORI 0x2C 76 | #define ANDI 0x2D 77 | #define XORI 0x2E 78 | #define MOVHI 0x2F 79 | #define LD_B 0x30 80 | #define LD_H 0x31 81 | //0x32 82 | #define LD_W 0x33 83 | #define ST_B 0x34 84 | #define ST_H 0x35 85 | //0x36 86 | #define ST_W 0x37 87 | #define IN_B 0x38 88 | #define IN_H 0x39 89 | #define CAXI 0x3A 90 | #define IN_W 0x3B 91 | #define OUT_B 0x3C 92 | #define OUT_H 0x3D 93 | #define FPP 0x3E //Special Float Inst 94 | #define OUT_W 0x3F 95 | 96 | 97 | /* Branch Instructions ( Extended opcode only for Branch command) 98 | * Common instrcutions commented out 99 | */ 100 | 101 | #define BV 0x40 102 | #define BL 0x41 103 | #define BE 0x42 104 | #define BNH 0x43 105 | #define BN 0x44 106 | #define BR 0x45 107 | #define BLT 0x46 108 | #define BLE 0x47 109 | #define BNV 0x48 110 | #define BNL 0x49 111 | #define BNE 0x4A 112 | #define BH 0x4B 113 | #define BP 0x4C 114 | #define NOP 0x4D 115 | #define BGE 0x4E 116 | #define BGT 0x4F 117 | 118 | /* Bit String Subopcodes */ 119 | #define SCH0BSU 0x00 120 | #define SCH0BSD 0x01 121 | #define SCH1BSU 0x02 122 | #define SCH1BSD 0x03 123 | 124 | #define ORBSU 0x08 125 | #define ANDBSU 0x09 126 | #define XORBSU 0x0A 127 | #define MOVBSU 0x0B 128 | #define ORNBSU 0x0C 129 | #define ANDNBSU 0x0D 130 | #define XORNBSU 0x0E 131 | #define NOTBSU 0x0F 132 | 133 | 134 | /* Floating Point Subopcodes */ 135 | #define CMPF_S 0x00 136 | 137 | #define CVT_WS 0x02 138 | #define CVT_SW 0x03 139 | #define ADDF_S 0x04 140 | #define SUBF_S 0x05 141 | #define MULF_S 0x06 142 | #define DIVF_S 0x07 143 | #define XB 0x08 144 | #define XH 0x09 145 | #define REV 0x0A 146 | #define TRNC_SW 0x0B 147 | #define MPYHW 0x0C 148 | 149 | #endif /* DEFINE_H */ 150 | 151 | -------------------------------------------------------------------------------- /mednafen/include/blip/Blip_Buffer.h: -------------------------------------------------------------------------------- 1 | // Band-limited sound synthesis buffer 2 | // Various changes and hacks for use in Mednafen. 3 | 4 | // Blip_Buffer 0.4.1 5 | #ifndef BLIP_BUFFER_H 6 | #define BLIP_BUFFER_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | 16 | // Internal 17 | typedef int32_t blip_long; 18 | typedef uint32_t blip_ulong; 19 | typedef int64_t blip_s64; 20 | typedef uint64_t blip_u64; 21 | 22 | // Time unit at source clock rate 23 | typedef blip_long blip_time_t; 24 | 25 | // Output samples are 16-bit signed, with a range of -32768 to 32767 26 | typedef short blip_sample_t; 27 | enum { blip_sample_max = 32767 }; 28 | 29 | typedef const char* blargg_err_t; 30 | typedef blip_u64 blip_resampled_time_t; 31 | typedef blip_resampled_time_t resampled_time_t; 32 | typedef blip_time_t blip_buf_t_; 33 | 34 | typedef struct 35 | { 36 | blip_u64 factor; 37 | blip_resampled_time_t offset; 38 | blip_buf_t_* buffer; 39 | blip_long buffer_size; 40 | blip_long reader_accum; 41 | int bass_shift; 42 | long sample_rate; 43 | long clock_rate; 44 | int bass_freq; 45 | int length; 46 | int modified; 47 | } Blip_Buffer; 48 | 49 | void Blip_Buffer_init(Blip_Buffer* bbuf); 50 | void Blip_Buffer_deinit(Blip_Buffer* bbuf); 51 | 52 | // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults 53 | // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there 54 | // isn't enough memory, returns error without affecting current buffer setup. 55 | blargg_err_t Blip_Buffer_set_sample_rate(Blip_Buffer* bbuf, 56 | long samples_per_sec, int msec_length /*= 1000 / 4*/); 57 | 58 | // End current time frame of specified duration and make its samples available 59 | // (along with any still-unread samples) for reading with read_samples(). Begins 60 | // a new time frame at the end of the current frame. 61 | void Blip_Buffer_end_frame(Blip_Buffer* bbuf, blip_time_t time); 62 | 63 | // Read at most 'max_samples' out of buffer into 'dest', removing them from from 64 | // the buffer. Returns number of samples actually read and removed. If stereo is 65 | // true, increments 'dest' one extra time after writing each sample, to allow 66 | // easy interleving of two channels into a stereo output buffer. 67 | long Blip_Buffer_read_samples(Blip_Buffer* bbuf, blip_sample_t* dest, 68 | long max_samples); 69 | 70 | // Additional optional features 71 | 72 | // Set frequency high-pass filter frequency, where higher values reduce bass more 73 | void Blip_Buffer_bass_freq(Blip_Buffer* bbuf, int frequency); 74 | 75 | // Remove all available samples and clear buffer to silence. If 'entire_buffer' is 76 | // false, just clears out any samples waiting rather than the entire buffer. 77 | void Blip_Buffer_clear(Blip_Buffer* bbuf, int entire_buffer /*= 1*/); 78 | 79 | // Number of samples available for reading with read_samples() 80 | static INLINE long Blip_Buffer_samples_avail(Blip_Buffer* bbuf); 81 | 82 | // Remove 'count' samples from those waiting to be read 83 | void Blip_Buffer_remove_samples(Blip_Buffer* bbuf, long count); 84 | 85 | // Experimental features 86 | 87 | // Number of raw samples that can be mixed within frame of specified duration. 88 | long Blip_Buffer_count_samples(Blip_Buffer* bbuf, blip_time_t duration); 89 | 90 | // Mix 'count' samples from 'buf' into buffer. 91 | void Blip_Buffer_mix_samples(Blip_Buffer* bbuf, blip_sample_t const* buf, 92 | long count); 93 | 94 | void Blip_Buffer_remove_silence(Blip_Buffer* bbuf, long count); 95 | 96 | static INLINE blip_resampled_time_t Blip_Buffer_resampled_time( 97 | Blip_Buffer* bbuf, blip_time_t t) 98 | { 99 | return t * bbuf->factor + bbuf->offset; 100 | } 101 | blip_resampled_time_t Blip_Buffer_clock_rate_factor(Blip_Buffer* bbuf, 102 | long clock_rate); 103 | 104 | 105 | #define BLIP_BUFFER_ACCURACY 32 106 | #define BLIP_PHASE_BITS 8 107 | 108 | // Number of bits in resample ratio fraction. Higher values give a more accurate ratio 109 | // but reduce maximum buffer size. 110 | //#ifndef BLIP_BUFFER_ACCURACY 111 | // #define BLIP_BUFFER_ACCURACY 16 112 | //#endif 113 | 114 | // Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in 115 | // noticeable broadband noise when synthesizing high frequency square waves. 116 | // Affects size of Blip_Synth objects since they store the waveform directly. 117 | //#ifndef BLIP_PHASE_BITS 118 | // #if BLIP_BUFFER_FAST 119 | // #define BLIP_PHASE_BITS 8 120 | // #else 121 | // #define BLIP_PHASE_BITS 6 122 | // #endif 123 | //#endif 124 | 125 | // Internal 126 | #define blip_widest_impulse_ 16 127 | #define blip_buffer_extra_ (blip_widest_impulse_ + 2) 128 | #define blip_res (1 << BLIP_PHASE_BITS) 129 | #define blip_sample_bits 30 130 | 131 | // Range specifies the greatest expected change in amplitude. Calculate it 132 | // by finding the difference between the maximum and minimum expected 133 | // amplitudes (max - min). 134 | 135 | 136 | typedef struct 137 | { 138 | int delta_factor; 139 | } Blip_Synth; 140 | 141 | static INLINE void Blip_Synth_set_volume(Blip_Synth* synth, double v, int range) 142 | { 143 | synth->delta_factor = ((v * (1.0 / (range < 0 ? -range : range))) * 144 | (1L << blip_sample_bits) + 0.5); 145 | } 146 | // Works directly in terms of fractional output samples. Contact author for more info. 147 | static INLINE void Blip_Synth_offset_resampled(Blip_Synth* synth, blip_resampled_time_t, 148 | int delta, Blip_Buffer*); 149 | 150 | // Add an amplitude transition of specified delta, optionally into specified buffer 151 | // rather than the one set with output(). Delta can be positive or negative. 152 | // The actual change in amplitude is delta * (volume / range) 153 | 154 | static INLINE void Blip_Synth_offset(Blip_Synth* synth, blip_time_t t, int delta, 155 | Blip_Buffer* buf) 156 | { 157 | Blip_Synth_offset_resampled(synth, t * buf->factor + buf->offset, delta, buf); 158 | } 159 | 160 | // Optimized reading from Blip_Buffer, for use in custom sample output 161 | 162 | // Begin reading from buffer. Name should be unique to the current block. 163 | #define BLIP_READER_BEGIN( name, blip_buffer ) \ 164 | const blip_buf_t_* name##_reader_buf = (blip_buffer).buffer;\ 165 | blip_long name##_reader_accum = (blip_buffer).reader_accum 166 | 167 | // Get value to pass to BLIP_READER_NEXT() 168 | #define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift) 169 | 170 | // Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal 171 | // code at the cost of having no bass control 172 | #define BLIP_READER_DEFAULT_BASS 9 173 | 174 | // Current sample 175 | #define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16)) 176 | 177 | // Current raw sample in full internal resolution 178 | #define BLIP_READER_READ_RAW( name ) (name##_reader_accum) 179 | 180 | // Advance to next sample 181 | #define BLIP_READER_NEXT( name, bass ) \ 182 | (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass))) 183 | 184 | // End reading samples from buffer. The number of samples read must now be removed 185 | // using Blip_Buffer_remove_samples(). 186 | #define BLIP_READER_END( name, blip_buffer ) \ 187 | (void) ((blip_buffer).reader_accum = name##_reader_accum) 188 | 189 | // End of public interface 190 | 191 | 192 | static INLINE void Blip_Synth_offset_resampled( 193 | Blip_Synth* synth, 194 | blip_resampled_time_t time, 195 | int delta, Blip_Buffer* blip_buf) 196 | { 197 | blip_long *buf, left, right; 198 | int phase; 199 | 200 | // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the 201 | // need for a longer buffer as set by set_sample_rate(). 202 | delta *= synth->delta_factor; 203 | buf = blip_buf->buffer + (time >> 204 | BLIP_BUFFER_ACCURACY); 205 | phase = (int)(time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & 206 | (blip_res - 1)); 207 | 208 | left = buf [0] + delta; 209 | 210 | // Kind of crappy, but doing shift after multiply results in overflow. 211 | // Alternate way of delaying multiply by delta_factor results in worse 212 | // sub-sample resolution. 213 | right = (delta >> BLIP_PHASE_BITS) * phase; 214 | left -= right; 215 | right += buf [1]; 216 | 217 | buf [0] = left; 218 | buf [1] = right; 219 | } 220 | 221 | static INLINE long Blip_Buffer_samples_avail(Blip_Buffer* bbuf) 222 | { 223 | return (long)(bbuf->offset >> BLIP_BUFFER_ACCURACY); 224 | } 225 | 226 | static INLINE void Blip_Buffer_set_clock_rate(Blip_Buffer* bbuf, long cps) 227 | { 228 | bbuf->factor = Blip_Buffer_clock_rate_factor(bbuf, bbuf->clock_rate = cps); 229 | } 230 | 231 | #ifdef __cplusplus 232 | } 233 | #endif 234 | 235 | #endif 236 | -------------------------------------------------------------------------------- /mednafen/masmem.h: -------------------------------------------------------------------------------- 1 | #ifndef __MDFN_PSX_MASMEM_H 2 | #define __MDFN_PSX_MASMEM_H 3 | 4 | #include "mednafen-types.h" 5 | 6 | // TODO, WIP (big-endian stores and loads not fully supported yet) 7 | 8 | static INLINE uint16 LoadU16_RBO(const uint16 *a) 9 | { 10 | #ifdef ARCH_POWERPC 11 | uint16 tmp; 12 | 13 | __asm__ ("lhbrx %0, %y1" : "=r"(tmp) : "Z"(*a)); 14 | 15 | return(tmp); 16 | 17 | #else 18 | uint16 tmp = *a; 19 | return((tmp << 8) | (tmp >> 8)); 20 | #endif 21 | } 22 | 23 | static INLINE void StoreU16_RBO(uint16 *a, const uint16 v) 24 | { 25 | #ifdef ARCH_POWERPC 26 | __asm__ ("sthbrx %0, %y1" : : "r"(v), "Z"(*a)); 27 | #else 28 | uint16 tmp = (v << 8) | (v >> 8); 29 | *a = tmp; 30 | #endif 31 | } 32 | 33 | static INLINE uint16 LoadU16_LE(const uint16 *a) 34 | { 35 | #ifdef MSB_FIRST 36 | return LoadU16_RBO(a); 37 | #else 38 | return *a; 39 | #endif 40 | } 41 | 42 | static INLINE void StoreU16_LE(uint16 *a, const uint16 v) 43 | { 44 | #ifdef MSB_FIRST 45 | StoreU16_RBO(a, v); 46 | #else 47 | *a = v; 48 | #endif 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /mednafen/math_ops.h: -------------------------------------------------------------------------------- 1 | #ifndef __MDFN_MATH_OPS_H 2 | #define __MDFN_MATH_OPS_H 3 | 4 | // Some compilers' optimizers and some platforms might fubar the generated code from these macros, 5 | // so some tests are run in...tests.cpp 6 | #define sign_8_to_s16(_value) ((int16)(int8)(_value)) 7 | #define sign_9_to_s16(_value) (((int16)((unsigned int)(_value) << 7)) >> 7) 8 | #define sign_10_to_s16(_value) (((int16)((uint32)(_value) << 6)) >> 6) 9 | #define sign_11_to_s16(_value) (((int16)((uint32)(_value) << 5)) >> 5) 10 | #define sign_12_to_s16(_value) (((int16)((uint32)(_value) << 4)) >> 4) 11 | #define sign_13_to_s16(_value) (((int16)((uint32)(_value) << 3)) >> 3) 12 | #define sign_14_to_s16(_value) (((int16)((uint32)(_value) << 2)) >> 2) 13 | #define sign_15_to_s16(_value) (((int16)((uint32)(_value) << 1)) >> 1) 14 | 15 | // This obviously won't convert higher-than-32 bit numbers to signed 32-bit ;) 16 | // Also, this shouldn't be used for 8-bit and 16-bit signed numbers, since you can 17 | // convert those faster with typecasts... 18 | #define sign_x_to_s32(_bits, _value) (((int32)((uint32)(_value) << (32 - _bits))) >> (32 - _bits)) 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /mednafen/mednafen-types.h: -------------------------------------------------------------------------------- 1 | #ifndef __MDFN_TYPES 2 | #define __MDFN_TYPES 3 | 4 | #include 5 | 6 | typedef int8_t int8; 7 | typedef int16_t int16; 8 | typedef int32_t int32; 9 | typedef int64_t int64; 10 | 11 | typedef uint8_t uint8; 12 | typedef uint16_t uint16; 13 | typedef uint32_t uint32; 14 | typedef uint64_t uint64; 15 | 16 | #ifdef __GNUC__ 17 | #define MDFN_UNLIKELY(n) __builtin_expect((n) != 0, 0) 18 | #define MDFN_LIKELY(n) __builtin_expect((n) != 0, 1) 19 | 20 | #define NO_INLINE __attribute__((noinline)) 21 | 22 | #if defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) 23 | #define MDFN_FASTCALL __attribute__((fastcall)) 24 | #else 25 | #define MDFN_FASTCALL 26 | #endif 27 | 28 | #define MDFN_ALIGN(n) __attribute__ ((aligned (n))) 29 | #define MDFN_FORMATSTR(a,b,c) __attribute__ ((format (a, b, c))); 30 | #define MDFN_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) 31 | #define MDFN_NOWARN_UNUSED __attribute__((unused)) 32 | 33 | #elif defined(_MSC_VER) 34 | /* roundf and va_copy is available since MSVC 2013 */ 35 | #if _MSC_VER < 1800 36 | #define roundf(in) (in >= 0.0f ? floorf(in + 0.5f) : ceilf(in - 0.5f)) 37 | #endif 38 | 39 | #define NO_INLINE 40 | #define MDFN_LIKELY(n) ((n) != 0) 41 | #define MDFN_UNLIKELY(n) ((n) != 0) 42 | 43 | #define MDFN_FASTCALL 44 | 45 | #define MDFN_ALIGN(n) __declspec(align(n)) 46 | 47 | #define MDFN_FORMATSTR(a,b,c) 48 | 49 | #define MDFN_WARN_UNUSED_RESULT 50 | #define MDFN_NOWARN_UNUSED 51 | 52 | #else 53 | #error "Not compiling with GCC nor MSVC" 54 | #define NO_INLINE 55 | 56 | #define MDFN_FASTCALL 57 | 58 | #define MDFN_ALIGN(n) // hence the #error. 59 | 60 | #define MDFN_FORMATSTR(a,b,c) 61 | 62 | #define MDFN_WARN_UNUSED_RESULT 63 | 64 | #endif 65 | 66 | #define MDFN_COLD 67 | 68 | typedef int32 v810_timestamp_t; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /mednafen/mempatcher-driver.h: -------------------------------------------------------------------------------- 1 | #ifndef __MDFN_MEMPATCHER_DRIVER_H 2 | #define __MDFN_MEMPATCHER_DRIVER_H 3 | 4 | #include "mednafen-types.h" 5 | 6 | int MDFNI_DecodePAR(const char *code, uint32 *a, uint8 *v, uint8 *c, char *type); 7 | int MDFNI_DecodeGG(const char *str, uint32 *a, uint8 *v, uint8 *c, char *type); 8 | int MDFNI_AddCheat(const char *name, uint32 addr, uint64 val, uint64 compare, char type, unsigned int length, bool bigendian); 9 | int MDFNI_DelCheat(uint32 which); 10 | int MDFNI_ToggleCheat(uint32 which); 11 | 12 | void MDFNI_ListCheats(int (*callb)(char *name, uint32 a, uint64 v, uint64 compare, int s, char type, unsigned int length, bool bigendian, void *data), void *data); 13 | 14 | int MDFNI_GetCheat(uint32 which, char **name, uint32 *a, uint64 *v, uint64 *compare, int *s, char *type, unsigned int *length, bool *bigendian); 15 | int MDFNI_SetCheat(uint32 which, const char *name, uint32 a, uint64 v, uint64 compare, int s, char type, unsigned int length, bool bigendian); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /mednafen/mempatcher.cpp: -------------------------------------------------------------------------------- 1 | /* Mednafen - Multi-system Emulator 2 | * 3 | * This program is free software; you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation; either version 2 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program; if not, write to the Free Software 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | 27 | #include "mednafen-types.h" 28 | 29 | #include "mempatcher.h" 30 | 31 | #ifdef _WIN32 32 | #include "msvc_compat.h" 33 | #endif 34 | 35 | #include "settings.h" 36 | 37 | static uint8 **RAMPtrs = NULL; 38 | static uint32 PageSize; 39 | static uint32 NumPages; 40 | 41 | typedef struct __CHEATF 42 | { 43 | char *name; 44 | char *conditions; 45 | 46 | uint32 addr; 47 | uint64 val; 48 | uint64 compare; 49 | 50 | unsigned int length; 51 | bool bigendian; 52 | unsigned int icount; // Instance count 53 | char type; /* 'R' for replace, 'S' for substitute(GG), 'C' for substitute with compare */ 54 | int status; 55 | } CHEATF; 56 | 57 | static std::vector cheats; 58 | static bool CheatsActive = true; 59 | 60 | static std::vector SubCheats[8]; 61 | 62 | static void RebuildSubCheats(void) 63 | { 64 | std::vector::iterator chit; 65 | 66 | for(int x = 0; x < 8; x++) 67 | SubCheats[x].clear(); 68 | 69 | if(!CheatsActive) return; 70 | 71 | for(chit = cheats.begin(); chit != cheats.end(); chit++) 72 | { 73 | if(chit->status && chit->type != 'R') 74 | { 75 | for(unsigned int x = 0; x < chit->length; x++) 76 | { 77 | SUBCHEAT tmpsub; 78 | unsigned int shiftie; 79 | 80 | if(chit->bigendian) 81 | shiftie = (chit->length - 1 - x) * 8; 82 | else 83 | shiftie = x * 8; 84 | 85 | tmpsub.addr = chit->addr + x; 86 | tmpsub.value = (chit->val >> shiftie) & 0xFF; 87 | if(chit->type == 'C') 88 | tmpsub.compare = (chit->compare >> shiftie) & 0xFF; 89 | else 90 | tmpsub.compare = -1; 91 | SubCheats[(chit->addr + x) & 0x7].push_back(tmpsub); 92 | } 93 | } 94 | } 95 | } 96 | 97 | bool MDFNMP_Init(uint32 ps, uint32 numpages) 98 | { 99 | PageSize = ps; 100 | NumPages = numpages; 101 | 102 | RAMPtrs = (uint8 **)calloc(numpages, sizeof(uint8 *)); 103 | 104 | CheatsActive = MDFN_GetSettingB("cheats"); 105 | return(1); 106 | } 107 | 108 | void MDFNMP_Kill(void) 109 | { 110 | if(RAMPtrs) 111 | { 112 | free(RAMPtrs); 113 | RAMPtrs = NULL; 114 | } 115 | } 116 | 117 | 118 | void MDFNMP_AddRAM(uint32 size, uint32 A, uint8 *RAM) 119 | { 120 | uint32 AB = A / PageSize; 121 | 122 | size /= PageSize; 123 | 124 | for(unsigned int x = 0; x < size; x++) 125 | { 126 | RAMPtrs[AB + x] = RAM; 127 | if(RAM) // Don't increment the RAM pointer if we're passed a NULL pointer 128 | RAM += PageSize; 129 | } 130 | } 131 | 132 | void MDFNMP_InstallReadPatches(void) 133 | { 134 | if(!CheatsActive) return; 135 | 136 | std::vector::iterator chit; 137 | } 138 | 139 | void MDFNMP_RemoveReadPatches(void) 140 | { 141 | } 142 | 143 | /* This function doesn't allocate any memory for "name" */ 144 | static int AddCheatEntry(char *name, char *conditions, uint32 addr, uint64 val, uint64 compare, int status, char type, unsigned int length, bool bigendian) 145 | { 146 | CHEATF temp; 147 | 148 | memset(&temp, 0, sizeof(CHEATF)); 149 | 150 | temp.name=name; 151 | temp.conditions = conditions; 152 | temp.addr=addr; 153 | temp.val=val; 154 | temp.status=status; 155 | temp.compare=compare; 156 | temp.length = length; 157 | temp.bigendian = bigendian; 158 | temp.type=type; 159 | 160 | cheats.push_back(temp); 161 | return(1); 162 | } 163 | 164 | void MDFN_LoadGameCheats(void *override_ptr) 165 | { 166 | RebuildSubCheats(); 167 | } 168 | 169 | void MDFN_FlushGameCheats(int nosave) 170 | { 171 | std::vector::iterator chit; 172 | 173 | for(chit = cheats.begin(); chit != cheats.end(); chit++) 174 | { 175 | free(chit->name); 176 | if(chit->conditions) 177 | free(chit->conditions); 178 | } 179 | cheats.clear(); 180 | 181 | RebuildSubCheats(); 182 | } 183 | 184 | int MDFNI_AddCheat(const char *name, uint32 addr, uint64 val, uint64 compare, char type, unsigned int length, bool bigendian) 185 | { 186 | char *t; 187 | 188 | if(!(t = strdup(name))) 189 | { 190 | /* Error allocating memory for cheat data. */ 191 | return(0); 192 | } 193 | 194 | if(!AddCheatEntry(t, NULL, addr,val,compare,1,type, length, bigendian)) 195 | { 196 | free(t); 197 | return(0); 198 | } 199 | 200 | MDFNMP_RemoveReadPatches(); 201 | RebuildSubCheats(); 202 | MDFNMP_InstallReadPatches(); 203 | 204 | return(1); 205 | } 206 | 207 | int MDFNI_DelCheat(uint32 which) 208 | { 209 | free(cheats[which].name); 210 | cheats.erase(cheats.begin() + which); 211 | 212 | MDFNMP_RemoveReadPatches(); 213 | RebuildSubCheats(); 214 | MDFNMP_InstallReadPatches(); 215 | 216 | return(1); 217 | } 218 | 219 | /* 220 | Condition format(ws = white space): 221 | 222 |
223 | [,second condition...etc.] 224 | 225 | Value should be unsigned integer, hex(with a 0x prefix) or 226 | base-10. 227 | 228 | Operations: 229 | >= 230 | <= 231 | > 232 | < 233 | == 234 | != 235 | & // Result of AND between two values is nonzero 236 | !& // Result of AND between two values is zero 237 | ^ // same, XOR 238 | !^ 239 | | // same, OR 240 | !| 241 | 242 | Full example: 243 | 244 | 2 L 0xADDE == 0xDEAD, 1 L 0xC000 == 0xA0 245 | 246 | */ 247 | 248 | static bool TestConditions(const char *string) 249 | { 250 | char address[64]; 251 | char operation[64]; 252 | char value[64]; 253 | char endian; 254 | unsigned int bytelen; 255 | bool passed = 1; 256 | 257 | while(sscanf(string, "%u %c %63s %63s %63s", &bytelen, &endian, address, operation, value) == 5 && passed) 258 | { 259 | uint64 v_value; 260 | uint64 value_at_address; 261 | 262 | 263 | if(value[0] == '0' && value[1] == 'x') 264 | v_value = strtoull(value + 2, NULL, 16); 265 | else 266 | v_value = strtoull(value, NULL, 0); 267 | 268 | value_at_address = 0; 269 | 270 | if(!strcmp(operation, ">=")) 271 | { 272 | if(!(value_at_address >= v_value)) 273 | passed = 0; 274 | } 275 | else if(!strcmp(operation, "<=")) 276 | { 277 | if(!(value_at_address <= v_value)) 278 | passed = 0; 279 | } 280 | else if(!strcmp(operation, ">")) 281 | { 282 | if(!(value_at_address > v_value)) 283 | passed = 0; 284 | } 285 | else if(!strcmp(operation, "<")) 286 | { 287 | if(!(value_at_address < v_value)) 288 | passed = 0; 289 | } 290 | else if(!strcmp(operation, "==")) 291 | { 292 | if(!(value_at_address == v_value)) 293 | passed = 0; 294 | } 295 | else if(!strcmp(operation, "!=")) 296 | { 297 | if(!(value_at_address != v_value)) 298 | passed = 0; 299 | } 300 | else if(!strcmp(operation, "&")) 301 | { 302 | if(!(value_at_address & v_value)) 303 | passed = 0; 304 | } 305 | else if(!strcmp(operation, "!&")) 306 | { 307 | if(value_at_address & v_value) 308 | passed = 0; 309 | } 310 | else if(!strcmp(operation, "^")) 311 | { 312 | if(!(value_at_address ^ v_value)) 313 | passed = 0; 314 | } 315 | else if(!strcmp(operation, "!^")) 316 | { 317 | if(value_at_address ^ v_value) 318 | passed = 0; 319 | } 320 | else if(!strcmp(operation, "|")) 321 | { 322 | if(!(value_at_address | v_value)) 323 | passed = 0; 324 | } 325 | else if(!strcmp(operation, "!|")) 326 | { 327 | if(value_at_address | v_value) 328 | passed = 0; 329 | } 330 | string = strchr(string, ','); 331 | if(!string) 332 | break; 333 | string++; 334 | } 335 | 336 | return(passed); 337 | } 338 | 339 | void MDFNMP_ApplyPeriodicCheats(void) 340 | { 341 | std::vector::iterator chit; 342 | 343 | 344 | if(!CheatsActive) 345 | return; 346 | 347 | for(chit = cheats.begin(); chit != cheats.end(); chit++) 348 | { 349 | if(chit->status && chit->type == 'R') 350 | { 351 | if(!chit->conditions || TestConditions(chit->conditions)) 352 | for(unsigned int x = 0; x < chit->length; x++) 353 | { 354 | uint32 page = ((chit->addr + x) / PageSize) % NumPages; 355 | if(RAMPtrs[page]) 356 | { 357 | uint64 tmpval = chit->val; 358 | 359 | if(chit->bigendian) 360 | tmpval >>= (chit->length - 1 - x) * 8; 361 | else 362 | tmpval >>= x * 8; 363 | 364 | RAMPtrs[page][(chit->addr + x) % PageSize] = tmpval; 365 | } 366 | } 367 | } 368 | } 369 | } 370 | 371 | 372 | void MDFNI_ListCheats(int (*callb)(char *name, uint32 a, uint64 v, uint64 compare, int s, char type, unsigned int length, bool bigendian, void *data), void *data) 373 | { 374 | std::vector::iterator chit; 375 | 376 | for(chit = cheats.begin(); chit != cheats.end(); chit++) 377 | { 378 | if(!callb(chit->name, chit->addr, chit->val, chit->compare, chit->status, chit->type, chit->length, chit->bigendian, data)) break; 379 | } 380 | } 381 | 382 | int MDFNI_GetCheat(uint32 which, char **name, uint32 *a, uint64 *v, uint64 *compare, int *s, char *type, unsigned int *length, bool *bigendian) 383 | { 384 | CHEATF *next = &cheats[which]; 385 | 386 | if(name) 387 | *name=next->name; 388 | if(a) 389 | *a=next->addr; 390 | if(v) 391 | *v=next->val; 392 | if(s) 393 | *s=next->status; 394 | if(compare) 395 | *compare=next->compare; 396 | if(type) 397 | *type=next->type; 398 | if(length) 399 | *length = next->length; 400 | if(bigendian) 401 | *bigendian = next->bigendian; 402 | return(1); 403 | } 404 | 405 | static uint8 CharToNibble(char thechar) 406 | { 407 | const char lut[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 408 | 409 | thechar = toupper(thechar); 410 | 411 | for(int x = 0; x < 16; x++) 412 | if(lut[x] == thechar) 413 | return(x); 414 | 415 | return(0xFF); 416 | } 417 | 418 | bool MDFNI_DecodeGBGG(const char *instr, uint32 *a, uint8 *v, uint8 *c, char *type) 419 | { 420 | char str[10]; 421 | int len; 422 | 423 | for(int x = 0; x < 9; x++) 424 | { 425 | while(*instr && CharToNibble(*instr) == 255) 426 | instr++; 427 | if(!(str[x] = *instr)) break; 428 | instr++; 429 | } 430 | str[9] = 0; 431 | 432 | len = strlen(str); 433 | 434 | if(len != 9 && len != 6) 435 | return(0); 436 | 437 | uint32 tmp_address; 438 | uint8 tmp_value; 439 | uint8 tmp_compare = 0; 440 | 441 | tmp_address = (CharToNibble(str[5]) << 12) | (CharToNibble(str[2]) << 8) | (CharToNibble(str[3]) << 4) | (CharToNibble(str[4]) << 0); 442 | tmp_address ^= 0xF000; 443 | tmp_value = (CharToNibble(str[0]) << 4) | (CharToNibble(str[1]) << 0); 444 | 445 | if(len == 9) 446 | { 447 | tmp_compare = (CharToNibble(str[6]) << 4) | (CharToNibble(str[8]) << 0); 448 | tmp_compare = (tmp_compare >> 2) | ((tmp_compare << 6) & 0xC0); 449 | tmp_compare ^= 0xBA; 450 | } 451 | 452 | *a = tmp_address; 453 | *v = tmp_value; 454 | 455 | if(len == 9) 456 | { 457 | *c = tmp_compare; 458 | *type = 'C'; 459 | } 460 | else 461 | { 462 | *c = 0; 463 | *type = 'S'; 464 | } 465 | 466 | return(1); 467 | } 468 | 469 | static int GGtobin(char c) 470 | { 471 | static char lets[16]={'A','P','Z','L','G','I','T','Y','E','O','X','U','K','S','V','N'}; 472 | int x; 473 | 474 | for(x=0;x<16;x++) 475 | if(lets[x] == toupper(c)) return(x); 476 | return(0); 477 | } 478 | 479 | /* Returns 1 on success, 0 on failure. Sets *a,*v,*c. */ 480 | int MDFNI_DecodeGG(const char *str, uint32 *a, uint8 *v, uint8 *c, char *type) 481 | { 482 | uint16 A; 483 | uint8 V,C; 484 | uint8 t; 485 | int s; 486 | 487 | A=0x8000; 488 | V=0; 489 | C=0; 490 | 491 | s=strlen(str); 492 | if(s!=6 && s!=8) return(0); 493 | 494 | t=GGtobin(*str++); 495 | V|=(t&0x07); 496 | V|=(t&0x08)<<4; 497 | 498 | t=GGtobin(*str++); 499 | V|=(t&0x07)<<4; 500 | A|=(t&0x08)<<4; 501 | 502 | t=GGtobin(*str++); 503 | A|=(t&0x07)<<4; 504 | //if(t&0x08) return(0); /* 8-character code?! */ 505 | 506 | t=GGtobin(*str++); 507 | A|=(t&0x07)<<12; 508 | A|=(t&0x08); 509 | 510 | t=GGtobin(*str++); 511 | A|=(t&0x07); 512 | A|=(t&0x08)<<8; 513 | 514 | if(s==6) 515 | { 516 | t=GGtobin(*str++); 517 | A|=(t&0x07)<<8; 518 | V|=(t&0x08); 519 | 520 | *a=A; 521 | *v=V; 522 | *type = 'S'; 523 | *c = 0; 524 | } 525 | else 526 | { 527 | t=GGtobin(*str++); 528 | A|=(t&0x07)<<8; 529 | C|=(t&0x08); 530 | 531 | t=GGtobin(*str++); 532 | C|=(t&0x07); 533 | C|=(t&0x08)<<4; 534 | 535 | t=GGtobin(*str++); 536 | C|=(t&0x07)<<4; 537 | V|=(t&0x08); 538 | *a=A; 539 | *v=V; 540 | *c=C; 541 | *type = 'C'; 542 | } 543 | 544 | return(1); 545 | } 546 | 547 | int MDFNI_DecodePAR(const char *str, uint32 *a, uint8 *v, uint8 *c, char *type) 548 | { 549 | int boo[4]; 550 | if(strlen(str)!=8) return(0); 551 | 552 | sscanf(str,"%02x%02x%02x%02x",boo,boo+1,boo+2,boo+3); 553 | 554 | *c = 0; 555 | 556 | if(1) 557 | { 558 | *a=(boo[3]<<8)|(boo[2]+0x7F); 559 | *v=0; 560 | } 561 | else 562 | { 563 | *v=boo[3]; 564 | *a=boo[2]|(boo[1]<<8); 565 | } 566 | 567 | *type = 'S'; 568 | return(1); 569 | } 570 | 571 | /* name can be NULL if the name isn't going to be changed. */ 572 | int MDFNI_SetCheat(uint32 which, const char *name, uint32 a, uint64 v, uint64 compare, int s, char type, unsigned int length, bool bigendian) 573 | { 574 | CHEATF *next = &cheats[which]; 575 | 576 | if(name) 577 | { 578 | char *t; 579 | if(!(t=(char *)realloc(next->name,strlen(name)+1))) 580 | return(0); 581 | next->name=t; 582 | strcpy(next->name,name); 583 | } 584 | next->addr=a; 585 | next->val=v; 586 | next->status=s; 587 | next->compare=compare; 588 | next->type=type; 589 | next->length = length; 590 | next->bigendian = bigendian; 591 | 592 | RebuildSubCheats(); 593 | 594 | return(1); 595 | } 596 | 597 | /* Convenience function. */ 598 | int MDFNI_ToggleCheat(uint32 which) 599 | { 600 | cheats[which].status = !cheats[which].status; 601 | RebuildSubCheats(); 602 | 603 | return(cheats[which].status); 604 | } 605 | 606 | static void SettingChanged(const char *name) 607 | { 608 | MDFNMP_RemoveReadPatches(); 609 | 610 | CheatsActive = MDFN_GetSettingB("cheats"); 611 | 612 | RebuildSubCheats(); 613 | 614 | MDFNMP_InstallReadPatches(); 615 | } 616 | -------------------------------------------------------------------------------- /mednafen/mempatcher.h: -------------------------------------------------------------------------------- 1 | #ifndef __MDFN_MEMPATCHER_H 2 | #define __MDFN_MEMPATCHER_H 3 | 4 | #include "mempatcher-driver.h" 5 | 6 | typedef struct __SUBCHEAT 7 | { 8 | uint32 addr; 9 | uint8 value; 10 | int compare; // < 0 on no compare 11 | } SUBCHEAT; 12 | 13 | bool MDFNMP_Init(uint32 ps, uint32 numpages); 14 | void MDFNMP_AddRAM(uint32 size, uint32 address, uint8 *RAM); 15 | void MDFNMP_Kill(void); 16 | 17 | void MDFNMP_InstallReadPatches(void); 18 | void MDFNMP_RemoveReadPatches(void); 19 | 20 | void MDFNMP_ApplyPeriodicCheats(void); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /mednafen/msvc_compat.h: -------------------------------------------------------------------------------- 1 | /* RetroArch - A frontend for libretro. 2 | * Copyright (C) 2010-2012 - Hans-Kristian Arntzen 3 | * 4 | * RetroArch is free software: you can redistribute it and/or modify it under the terms 5 | * of the GNU General Public License as published by the Free Software Found- 6 | * ation, either version 3 of the License, or (at your option) any later version. 7 | * 8 | * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 10 | * PURPOSE. See the GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License along with RetroArch. 13 | * If not, see . 14 | */ 15 | 16 | #ifndef __RARCH_MSVC_COMPAT_H 17 | #define __RARCH_MSVC_COMPAT_H 18 | 19 | #ifdef _MSC_VER 20 | 21 | #undef UNICODE // Do not bother with UNICODE at this time. 22 | #undef _UNICODE // Do not bother with UNICODE at this time. 23 | #include 24 | #include 25 | #include 26 | 27 | // Python headers defines ssize_t and sets HAVE_SSIZE_T. Cannot duplicate these efforts. 28 | #ifndef HAVE_SSIZE_T 29 | #if defined(_WIN64) 30 | typedef __int64 ssize_t; 31 | #elif defined(_WIN32) 32 | typedef int ssize_t; 33 | #endif 34 | #endif 35 | 36 | #define snprintf _snprintf 37 | #define strtoll _strtoi64 38 | #define strtoull _strtoui64 39 | #define strcasecmp _stricmp 40 | #define strncasecmp _strnicmp 41 | #define strdup _strdup 42 | #define lseek _lseek 43 | 44 | #include 45 | #define strlen _tcslen 46 | 47 | # define S_IRUSR S_IREAD /* read, user */ 48 | # define S_IWUSR S_IWRITE /* write, user */ 49 | 50 | // Disable some of the annoying warnings. 51 | #pragma warning(disable : 4800) 52 | #pragma warning(disable : 4244) 53 | #pragma warning(disable : 4305) 54 | #pragma warning(disable : 4146) 55 | #pragma warning(disable : 4267) 56 | 57 | /* roundf and va_copy is available since MSVC 2013 */ 58 | #if _MSC_VER < 1800 59 | #define roundf(in) (in >= 0.0f ? floorf(in + 0.5f) : ceilf(in - 0.5f)) 60 | #endif 61 | 62 | #ifndef PATH_MAX 63 | #define PATH_MAX MAX_PATH 64 | #endif 65 | 66 | #endif 67 | #endif 68 | 69 | -------------------------------------------------------------------------------- /mednafen/settings.c: -------------------------------------------------------------------------------- 1 | /* Mednafen - Multi-system Emulator 2 | * 3 | * This program is free software; you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation; either version 2 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program; if not, write to the Free Software 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "settings.h" 22 | 23 | uint32_t setting_vb_lcolor=0xFF0000; 24 | uint32_t setting_vb_rcolor=0x000000; 25 | uint32_t setting_vb_anaglyph_preset=0; 26 | bool setting_vb_right_analog_to_digital=false; 27 | bool setting_vb_right_invert_x=false; 28 | bool setting_vb_right_invert_y=false; 29 | uint32_t setting_vb_cpu_emulation=0; 30 | uint32_t setting_vb_3dmode=0; 31 | uint32_t setting_vb_liprescale=1; 32 | uint32_t setting_vb_default_color=0xFFFFFF; 33 | 34 | uint64_t MDFN_GetSettingUI(const char *name) 35 | { 36 | if (!strcmp("vb.anaglyph.lcolor", name)) 37 | return setting_vb_lcolor; 38 | if (!strcmp("vb.anaglyph.rcolor", name)) 39 | return setting_vb_rcolor; 40 | if (!strcmp("vb.3dmode", name)) 41 | return setting_vb_3dmode; 42 | if (!strcmp("vb.liprescale", name)) 43 | return setting_vb_liprescale; 44 | if (!strcmp("vb.default_color", name)) 45 | return setting_vb_default_color; 46 | return 0; 47 | } 48 | 49 | int64_t MDFN_GetSettingI(const char *name) 50 | { 51 | if (!strcmp("vb.anaglyph.preset", name)) 52 | return setting_vb_anaglyph_preset; 53 | if (!strcmp("vb.cpu_emulation", name)) 54 | return setting_vb_cpu_emulation; 55 | return 0; 56 | } 57 | 58 | bool MDFN_GetSettingB(const char *name) 59 | { 60 | if (!strcmp("cheats", name)) 61 | return 0; 62 | /* LIBRETRO */ 63 | if (!strcmp("vb.instant_display_hack", name)) 64 | return 1; 65 | if (!strcmp("vb.allow_draw_skip", name)) 66 | return 1; 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /mednafen/settings.h: -------------------------------------------------------------------------------- 1 | #ifndef MDFN_SETTINGS_H 2 | #define MDFN_SETTINGS_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | extern uint32_t setting_vb_lcolor; 14 | extern uint32_t setting_vb_rcolor; 15 | extern uint32_t setting_vb_anaglyph_preset; 16 | extern bool setting_vb_right_analog_to_digital; 17 | extern bool setting_vb_right_invert_x; 18 | extern bool setting_vb_right_invert_y; 19 | extern uint32_t setting_vb_cpu_emulation; 20 | extern uint32_t setting_vb_3dmode; 21 | extern uint32_t setting_vb_liprescale; 22 | extern uint32_t setting_vb_default_color; 23 | 24 | /* This should assert() or something if the 25 | * setting isn't found, since it would 26 | * be a totally tubular error! */ 27 | uint64_t MDFN_GetSettingUI(const char *name); 28 | int64_t MDFN_GetSettingI(const char *name); 29 | bool MDFN_GetSettingB(const char *name); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /mednafen/sound/Blip_Buffer.c: -------------------------------------------------------------------------------- 1 | // Blip_Buffer 0.4.1. http://www.slack.net/~ant/ 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #ifndef ULLONG_MAX 11 | #define ULLONG_MAX 18446744073709551615ULL 12 | #endif 13 | 14 | /* Copyright (C) 2003-2006 Shay Green. This module is free software; you 15 | can redistribute it and/or modify it under the terms of the GNU Lesser 16 | General Public License as published by the Free Software Foundation; either 17 | version 2.1 of the License, or (at your option) any later version. This 18 | module is distributed in the hope that it will be useful, but WITHOUT ANY 19 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 20 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 21 | details. You should have received a copy of the GNU Lesser General Public 22 | License along with this module; if not, write to the Free Software Foundation, 23 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 24 | 25 | void Blip_Buffer_init(Blip_Buffer* bbuf) 26 | { 27 | bbuf->factor = (blip_u64)ULLONG_MAX; 28 | bbuf->offset = 0; 29 | bbuf->buffer = 0; 30 | bbuf->buffer_size = 0; 31 | bbuf->sample_rate = 0; 32 | bbuf->reader_accum = 0; 33 | bbuf->bass_shift = 0; 34 | bbuf->clock_rate = 0; 35 | bbuf->bass_freq = 16; 36 | bbuf->length = 0; 37 | } 38 | 39 | void Blip_Buffer_deinit(Blip_Buffer* bbuf) 40 | { 41 | if (bbuf->buffer) 42 | free(bbuf->buffer); 43 | } 44 | 45 | void Blip_Buffer_clear(Blip_Buffer* bbuf, int entire_buffer) 46 | { 47 | bbuf->offset = 0; 48 | bbuf->reader_accum = 0; 49 | bbuf->modified = 0; 50 | if (bbuf->buffer) 51 | { 52 | long count = (entire_buffer ? bbuf->buffer_size : Blip_Buffer_samples_avail(bbuf)); 53 | memset(bbuf->buffer, 0, (count + blip_buffer_extra_) * sizeof(blip_buf_t_)); 54 | } 55 | } 56 | 57 | blargg_err_t Blip_Buffer_set_sample_rate(Blip_Buffer* bbuf, long new_rate, 58 | int msec) 59 | { 60 | // start with maximum length that resampled time can represent 61 | blip_s64 new_size = (ULLONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 62 | 64; 63 | 64 | // simple safety check, since code elsewhere may not be safe for sizes approaching (2 ^ 31). 65 | if (new_size > ((1LL << 30) - 1)) 66 | new_size = (1LL << 30) - 1; 67 | 68 | if (msec != 0) 69 | { 70 | blip_s64 s = ((blip_s64)new_rate * (msec + 1) + 999) / 1000; 71 | if (s < new_size) 72 | new_size = s; 73 | } 74 | 75 | if (bbuf->buffer_size != new_size) 76 | { 77 | void* p = realloc(bbuf->buffer, (new_size + blip_buffer_extra_) * sizeof (bbuf->buffer)); 78 | if (!p) 79 | return "Out of memory"; 80 | 81 | bbuf->buffer = (blip_buf_t_*) p; 82 | } 83 | 84 | bbuf->buffer_size = new_size; 85 | 86 | // update things based on the sample rate 87 | bbuf->sample_rate = new_rate; 88 | bbuf->length = new_size * 1000 / new_rate - 1; 89 | if (bbuf->clock_rate) 90 | Blip_Buffer_set_clock_rate(bbuf, bbuf->clock_rate); 91 | Blip_Buffer_bass_freq(bbuf, bbuf->bass_freq); 92 | 93 | Blip_Buffer_clear(bbuf, 1); 94 | 95 | return 0; // success 96 | } 97 | 98 | blip_resampled_time_t Blip_Buffer_clock_rate_factor(Blip_Buffer* bbuf, 99 | long rate) 100 | { 101 | double ratio = (double) bbuf->sample_rate / rate; 102 | blip_s64 factor = (blip_s64) floor(ratio * (1LL << BLIP_BUFFER_ACCURACY) + 0.5); 103 | return (blip_resampled_time_t) factor; 104 | } 105 | 106 | void Blip_Buffer_bass_freq(Blip_Buffer* bbuf, int freq) 107 | { 108 | int shift = 31; 109 | bbuf->bass_freq = freq; 110 | if (freq > 0) 111 | { 112 | long f; 113 | shift = 13; 114 | f = (freq << 16) / bbuf->sample_rate; 115 | while ((f >>= 1) && --shift) { } 116 | } 117 | bbuf->bass_shift = shift; 118 | } 119 | 120 | void Blip_Buffer_end_frame(Blip_Buffer* bbuf, blip_time_t t) 121 | { 122 | bbuf->offset += t * bbuf->factor; 123 | } 124 | 125 | void Blip_Buffer_remove_silence(Blip_Buffer* bbuf, long count) 126 | { 127 | bbuf->offset -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; 128 | } 129 | 130 | long Blip_Buffer_count_samples(Blip_Buffer* bbuf, blip_time_t t) 131 | { 132 | unsigned long last_sample = Blip_Buffer_resampled_time(bbuf, t) >> BLIP_BUFFER_ACCURACY; 133 | unsigned long first_sample = bbuf->offset >> BLIP_BUFFER_ACCURACY; 134 | return (long)(last_sample - first_sample); 135 | } 136 | 137 | void Blip_Buffer_remove_samples(Blip_Buffer* bbuf, long count) 138 | { 139 | if (count) 140 | { 141 | long remain; 142 | 143 | Blip_Buffer_remove_silence(bbuf, count); 144 | 145 | // copy remaining samples to beginning and clear old samples 146 | remain = Blip_Buffer_samples_avail(bbuf) + blip_buffer_extra_; 147 | memmove(bbuf->buffer, bbuf->buffer + count, remain * sizeof(bbuf->buffer)); 148 | memset(bbuf->buffer + remain, 0, count * sizeof(bbuf->buffer)); 149 | } 150 | } 151 | 152 | long Blip_Buffer_read_samples(Blip_Buffer* bbuf, blip_sample_t* out, 153 | long max_samples) 154 | { 155 | long count = Blip_Buffer_samples_avail(bbuf); 156 | if (count > max_samples) 157 | count = max_samples; 158 | 159 | if (count) 160 | { 161 | blip_long n; 162 | int const bass = BLIP_READER_BASS(*bbuf); 163 | 164 | BLIP_READER_BEGIN(reader, *bbuf); 165 | 166 | for (n = count; n; --n) 167 | { 168 | blip_long s = BLIP_READER_READ(reader); 169 | if ((blip_sample_t) s != s) 170 | s = 0x7FFF - (s >> 24); 171 | *out = (blip_sample_t) s; 172 | out += 2; 173 | BLIP_READER_NEXT(reader, bass); 174 | } 175 | 176 | BLIP_READER_END(reader, *bbuf); 177 | 178 | Blip_Buffer_remove_samples(bbuf, count); 179 | } 180 | return count; 181 | } 182 | 183 | void Blip_Buffer_mix_samples(Blip_Buffer* bbuf, blip_sample_t const* in, long count) 184 | { 185 | blip_buf_t_* out = bbuf->buffer + (bbuf->offset >> BLIP_BUFFER_ACCURACY) + 186 | blip_widest_impulse_ / 2; 187 | 188 | int const sample_shift = blip_sample_bits - 16; 189 | int prev = 0; 190 | while (count--) 191 | { 192 | blip_long s = (blip_long) * in++ << sample_shift; 193 | *out += s - prev; 194 | prev = s; 195 | ++out; 196 | } 197 | *out -= prev; 198 | } 199 | -------------------------------------------------------------------------------- /mednafen/state.c: -------------------------------------------------------------------------------- 1 | /* Mednafen - Multi-system Emulator 2 | * 3 | * This program is free software; you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation; either version 2 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program; if not, write to the Free Software 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "state.h" 29 | 30 | #define SSEEK_END 2 31 | #define SSEEK_CUR 1 32 | #define SSEEK_SET 0 33 | 34 | #define RLSB MDFNSTATE_RLSB /* 0x80000000 */ 35 | 36 | /* Forward declaration */ 37 | extern int StateAction(StateMem *sm, int load, int data_only); 38 | 39 | static INLINE void MDFN_en32lsb(uint8_t *buf, uint32_t morp) 40 | { 41 | buf[0]=morp; 42 | buf[1]=morp>>8; 43 | buf[2]=morp>>16; 44 | buf[3]=morp>>24; 45 | } 46 | 47 | static INLINE uint32_t MDFN_de32lsb(const uint8_t *morp) 48 | { 49 | return morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24); 50 | } 51 | 52 | #ifdef MSB_FIRST 53 | static INLINE void Endian_A64_Swap(void *src, uint32_t nelements) 54 | { 55 | uint32_t i; 56 | uint8_t *nsrc = (uint8_t *)src; 57 | 58 | for(i = 0; i < nelements; i++) 59 | { 60 | unsigned z; 61 | uint8_t *base = &nsrc[i * 8]; 62 | 63 | for(z = 0; z < 4; z++) 64 | { 65 | uint8_t tmp = base[z]; 66 | 67 | base[z] = base[7 - z]; 68 | base[7 - z] = tmp; 69 | } 70 | } 71 | } 72 | 73 | static INLINE void Endian_A32_Swap(void *src, uint32_t nelements) 74 | { 75 | uint32_t i; 76 | uint8_t *nsrc = (uint8_t *)src; 77 | 78 | for(i = 0; i < nelements; i++) 79 | { 80 | uint8_t tmp1 = nsrc[i * 4]; 81 | uint8_t tmp2 = nsrc[i * 4 + 1]; 82 | 83 | nsrc[i * 4] = nsrc[i * 4 + 3]; 84 | nsrc[i * 4 + 1] = nsrc[i * 4 + 2]; 85 | 86 | nsrc[i * 4 + 2] = tmp2; 87 | nsrc[i * 4 + 3] = tmp1; 88 | } 89 | } 90 | 91 | static void Endian_A16_Swap(void *src, uint32_t nelements) 92 | { 93 | uint32_t i; 94 | uint8_t *nsrc = (uint8_t *)src; 95 | 96 | for(i = 0; i < nelements; i++) 97 | { 98 | uint8_t tmp = nsrc[i * 2]; 99 | 100 | nsrc[i * 2] = nsrc[i * 2 + 1]; 101 | nsrc[i * 2 + 1] = tmp; 102 | } 103 | } 104 | 105 | static INLINE void FlipByteOrder(uint8_t *src, uint32_t count) 106 | { 107 | uint8_t *start=src; 108 | uint8_t *end=src+count-1; 109 | 110 | if((count&1) || !count) 111 | return; /* This shouldn't happen. */ 112 | 113 | count >>= 1; 114 | 115 | while(count--) 116 | { 117 | uint8_t tmp; 118 | 119 | tmp=*end; 120 | *end=*start; 121 | *start=tmp; 122 | end--; 123 | start++; 124 | } 125 | } 126 | #endif 127 | 128 | static int32_t smem_read(StateMem *st, void *buffer, uint32_t len) 129 | { 130 | if ((len + st->loc) > st->len) 131 | return 0; 132 | 133 | memcpy(buffer, st->data + st->loc, len); 134 | st->loc += len; 135 | 136 | return len; 137 | } 138 | 139 | static int32_t smem_write(StateMem *st, void *buffer, uint32_t len) 140 | { 141 | if ((len + st->loc) > st->malloced) 142 | { 143 | uint32_t newsize = (st->malloced >= 32768) ? st->malloced : 32768; 144 | 145 | while(newsize < (len + st->loc)) 146 | newsize *= 2; 147 | st->data = (uint8_t *)realloc(st->data, newsize); 148 | st->malloced = newsize; 149 | } 150 | memcpy(st->data + st->loc, buffer, len); 151 | st->loc += len; 152 | 153 | if (st->loc > st->len) 154 | st->len = st->loc; 155 | 156 | return len; 157 | } 158 | 159 | static int32_t smem_seek(StateMem *st, uint32_t offset, int whence) 160 | { 161 | switch(whence) 162 | { 163 | case SSEEK_SET: st->loc = offset; break; 164 | case SSEEK_END: st->loc = st->len - offset; break; 165 | case SSEEK_CUR: st->loc += offset; break; 166 | } 167 | 168 | if(st->loc > st->len) 169 | { 170 | st->loc = st->len; 171 | return -1; 172 | } 173 | 174 | return 0; 175 | } 176 | 177 | static int smem_write32le(StateMem *st, uint32_t b) 178 | { 179 | uint8_t s[4]; 180 | s[0]=b; 181 | s[1]=b>>8; 182 | s[2]=b>>16; 183 | s[3]=b>>24; 184 | return (smem_write(st, s, 4) < 4) ? 0 : 4; 185 | } 186 | 187 | static int smem_read32le(StateMem *st, uint32_t *b) 188 | { 189 | uint8_t s[4]; 190 | 191 | if(smem_read(st, s, 4) < 4) 192 | return 0; 193 | 194 | *b = s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); 195 | 196 | return 4; 197 | } 198 | 199 | static bool SubWrite(StateMem *st, SFORMAT *sf) 200 | { 201 | while(sf->size || sf->name) // Size can sometimes be zero, so also check for the text name. These two should both be zero only at the end of a struct. 202 | { 203 | int32_t bytesize; 204 | char nameo[1 + 256]; 205 | 206 | if(!sf->size || !sf->v) 207 | { 208 | sf++; 209 | continue; 210 | } 211 | 212 | if(sf->size == (uint32_t)~0) /* Link to another struct. */ 213 | { 214 | if(!SubWrite(st, (SFORMAT *)sf->v)) 215 | return 0; 216 | 217 | sf++; 218 | continue; 219 | } 220 | 221 | bytesize = sf->size; 222 | nameo[0] = strlcpy(nameo + 1, sf->name, 256); 223 | 224 | smem_write(st, nameo, 1 + nameo[0]); 225 | smem_write32le(st, bytesize); 226 | 227 | #ifdef MSB_FIRST 228 | /* Flip the byte order... */ 229 | if(sf->flags & MDFNSTATE_BOOL) 230 | { 231 | 232 | } 233 | else if(sf->flags & MDFNSTATE_RLSB64) 234 | Endian_A64_Swap(sf->v, bytesize / sizeof(uint64_t)); 235 | else if(sf->flags & MDFNSTATE_RLSB32) 236 | Endian_A32_Swap(sf->v, bytesize / sizeof(uint32_t)); 237 | else if(sf->flags & MDFNSTATE_RLSB16) 238 | Endian_A16_Swap(sf->v, bytesize / sizeof(uint16_t)); 239 | else if(sf->flags & RLSB) 240 | FlipByteOrder((uint8_t*)sf->v, bytesize); 241 | #endif 242 | 243 | // Special case for the evil bool type, to convert bool to 1-byte elements. 244 | // Don't do it if we're only saving the raw data. 245 | if(sf->flags & MDFNSTATE_BOOL) 246 | { 247 | int32_t bool_monster; 248 | for(bool_monster = 0; bool_monster < bytesize; bool_monster++) 249 | { 250 | uint8_t tmp_bool = ((bool *)sf->v)[bool_monster]; 251 | smem_write(st, &tmp_bool, 1); 252 | } 253 | } 254 | else 255 | smem_write(st, (uint8_t *)sf->v, bytesize); 256 | 257 | #ifdef MSB_FIRST 258 | /* Now restore the original byte order. */ 259 | if(sf->flags & MDFNSTATE_BOOL) 260 | { 261 | 262 | } 263 | else if(sf->flags & MDFNSTATE_RLSB64) 264 | Endian_A64_Swap(sf->v, bytesize / sizeof(uint64_t)); 265 | else if(sf->flags & MDFNSTATE_RLSB32) 266 | Endian_A32_Swap(sf->v, bytesize / sizeof(uint32_t)); 267 | else if(sf->flags & MDFNSTATE_RLSB16) 268 | Endian_A16_Swap(sf->v, bytesize / sizeof(uint16_t)); 269 | else if(sf->flags & RLSB) 270 | FlipByteOrder((uint8_t*)sf->v, bytesize); 271 | #endif 272 | sf++; 273 | } 274 | 275 | return true; 276 | } 277 | 278 | static int WriteStateChunk(StateMem *st, const char *sname, SFORMAT *sf) 279 | { 280 | int32_t data_start_pos; 281 | int32_t end_pos; 282 | 283 | uint8_t sname_tmp[32]; 284 | size_t sname_len = strlen(sname); 285 | 286 | memset(sname_tmp, 0, sizeof(sname_tmp)); 287 | memcpy((char *)sname_tmp, sname, (sname_len < 32) ? sname_len : 32); 288 | 289 | smem_write(st, sname_tmp, 32); 290 | 291 | smem_write32le(st, 0); // We'll come back and write this later. 292 | 293 | data_start_pos = st->loc; 294 | 295 | if(!SubWrite(st, sf)) 296 | return 0; 297 | 298 | end_pos = st->loc; 299 | 300 | smem_seek(st, data_start_pos - 4, SSEEK_SET); 301 | smem_write32le(st, end_pos - data_start_pos); 302 | smem_seek(st, end_pos, SSEEK_SET); 303 | 304 | return (end_pos - data_start_pos); 305 | } 306 | 307 | static SFORMAT *FindSF(const char *name, SFORMAT *sf) 308 | { 309 | /* Size can sometimes be zero, so also check for the text name. 310 | * These two should both be zero only at the end of a struct. */ 311 | while(sf->size || sf->name) 312 | { 313 | if(!sf->size || !sf->v) 314 | { 315 | sf++; 316 | continue; 317 | } 318 | 319 | /* Link to another SFORMAT structure. */ 320 | if (sf->size == (uint32_t)~0) 321 | { 322 | SFORMAT *temp_sf = FindSF(name, (SFORMAT*)sf->v); 323 | if (temp_sf) 324 | return temp_sf; 325 | } 326 | else 327 | { 328 | if (!strcmp(sf->name, name)) 329 | return sf; 330 | } 331 | 332 | sf++; 333 | } 334 | 335 | return NULL; 336 | } 337 | 338 | static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size) 339 | { 340 | int temp = st->loc; 341 | 342 | while (st->loc < (temp + size)) 343 | { 344 | /* Don't change to char unless cast 345 | * toa[0] to unsigned to smem_read() 346 | * and other places. */ 347 | uint8_t toa[1 + 256]; 348 | uint32_t recorded_size = 0; /* In bytes */ 349 | SFORMAT *tmp = NULL; 350 | 351 | if(smem_read(st, toa, 1) != 1) 352 | return 0; 353 | 354 | if(smem_read(st, toa + 1, toa[0]) != toa[0]) 355 | return 0; 356 | 357 | toa[1 + toa[0]] = 0; 358 | 359 | smem_read32le(st, &recorded_size); 360 | 361 | tmp = FindSF((char*)toa + 1, sf); 362 | 363 | if(tmp) 364 | { 365 | uint32_t expected_size = tmp->size; /* In bytes */ 366 | 367 | if(recorded_size != expected_size) 368 | { 369 | if(smem_seek(st, recorded_size, SSEEK_CUR) < 0) 370 | return 0; 371 | } 372 | else 373 | { 374 | smem_read(st, (uint8_t *)tmp->v, expected_size); 375 | 376 | if(tmp->flags & MDFNSTATE_BOOL) 377 | { 378 | int32_t bool_monster; 379 | /* Converting downwards is necessary 380 | * for the case of sizeof(bool) > 1 */ 381 | for(bool_monster = expected_size - 1; bool_monster >= 0; bool_monster--) 382 | ((bool *)tmp->v)[bool_monster] = ((uint8_t *)tmp->v)[bool_monster]; 383 | } 384 | 385 | #ifdef MSB_FIRST 386 | if(tmp->flags & MDFNSTATE_RLSB64) 387 | Endian_A64_Swap(tmp->v, expected_size / sizeof(uint64_t)); 388 | else if(tmp->flags & MDFNSTATE_RLSB32) 389 | Endian_A32_Swap(tmp->v, expected_size / sizeof(uint32_t)); 390 | else if(tmp->flags & MDFNSTATE_RLSB16) 391 | Endian_A16_Swap(tmp->v, expected_size / sizeof(uint16_t)); 392 | else if(tmp->flags & RLSB) 393 | FlipByteOrder((uint8_t*)tmp->v, expected_size); 394 | #endif 395 | } 396 | } 397 | else 398 | { 399 | if(smem_seek(st, recorded_size, SSEEK_CUR) < 0) 400 | return 0; 401 | } 402 | } 403 | 404 | return 1; 405 | } 406 | 407 | static int MDFNSS_StateAction_internal(StateMem *st, 408 | int load, int data_only, 409 | struct SSDescriptor *section) 410 | { 411 | if(load) 412 | { 413 | char sname[32]; 414 | 415 | uint32_t tmp_size = 0; 416 | int found = 0; 417 | uint32_t total = 0; 418 | 419 | while(smem_read(st, (uint8_t *)sname, 32) == 32) 420 | { 421 | if(smem_read32le(st, &tmp_size) != 4) 422 | return 0; 423 | 424 | total += tmp_size + 32 + 4; 425 | 426 | // Yay, we found the section 427 | if(!strncmp(sname, section->name, 32)) 428 | { 429 | if(!ReadStateChunk(st, section->sf, tmp_size)) 430 | return 0; 431 | found = 1; 432 | break; 433 | } 434 | else 435 | { 436 | if(smem_seek(st, tmp_size, SSEEK_CUR) < 0) 437 | return 0; 438 | } 439 | } 440 | 441 | if(smem_seek(st, -total, SSEEK_CUR) < 0) 442 | return 0; 443 | 444 | if(!found && !section->optional) // Not found. We are sad! 445 | return 0; 446 | } 447 | else 448 | { 449 | if(!WriteStateChunk(st, section->name, section->sf)) 450 | return 0; 451 | } 452 | 453 | return 1; 454 | } 455 | 456 | int MDFNSS_StateAction(void *st_p, int load, int data_only, SFORMAT *sf, const char *name, bool optional) 457 | { 458 | struct SSDescriptor love; 459 | StateMem *st = (StateMem*)st_p; 460 | 461 | love.sf = sf; 462 | love.name = name; 463 | love.optional = optional; 464 | 465 | return MDFNSS_StateAction_internal(st, load, 0, &love); 466 | } 467 | 468 | int MDFNSS_SaveSM(void *st_p, int a, int b, const void*c, const void*d, const void*e) 469 | { 470 | uint32_t sizy; 471 | uint8_t header[32]; 472 | StateMem *st = (StateMem*)st_p; 473 | static const char *header_magic = "MDFNSVST"; 474 | int neowidth = 0, neoheight = 0; 475 | 476 | memset(header, 0, sizeof(header)); 477 | memcpy(header, header_magic, 8); 478 | 479 | MDFN_en32lsb(header + 16, MEDNAFEN_VERSION_NUMERIC); 480 | MDFN_en32lsb(header + 24, neowidth); 481 | MDFN_en32lsb(header + 28, neoheight); 482 | smem_write(st, header, 32); 483 | 484 | if(!StateAction(st, 0, 0)) 485 | return 0; 486 | 487 | sizy = st->loc; 488 | smem_seek(st, 16 + 4, SSEEK_SET); 489 | smem_write32le(st, sizy); 490 | 491 | return 1; 492 | } 493 | 494 | int MDFNSS_LoadSM(void *st_p, int a, int b) 495 | { 496 | uint8_t header[32]; 497 | uint32_t stateversion; 498 | StateMem *st = (StateMem*)st_p; 499 | 500 | smem_read(st, header, 32); 501 | 502 | if(memcmp(header, "MEDNAFENSVESTATE", 16) && memcmp(header, "MDFNSVST", 8)) 503 | return 0; 504 | 505 | stateversion = MDFN_de32lsb(header + 16); 506 | 507 | return StateAction(st, stateversion, 0); 508 | } 509 | -------------------------------------------------------------------------------- /mednafen/state.h: -------------------------------------------------------------------------------- 1 | #ifndef _STATE_H 2 | #define _STATE_H 3 | 4 | #include 5 | #include 6 | 7 | /* Flag for a single, >= 1 byte native-endian variable */ 8 | #define MDFNSTATE_RLSB 0x80000000 9 | /* 32-bit native-endian elements */ 10 | #define MDFNSTATE_RLSB32 0x40000000 11 | /* 16-bit native-endian elements */ 12 | #define MDFNSTATE_RLSB16 0x20000000 13 | /* 64-bit native-endian elements */ 14 | #define MDFNSTATE_RLSB64 0x10000000 15 | 16 | #define MDFNSTATE_BOOL 0x08000000 17 | 18 | typedef struct 19 | { 20 | uint8_t *data; 21 | uint32_t loc; 22 | uint32_t len; 23 | uint32_t malloced; 24 | } StateMem; 25 | 26 | typedef struct 27 | { 28 | void *v; /* Pointer to the variable/array */ 29 | uint32_t size; /* Length, in bytes, of the data to be saved EXCEPT: 30 | * In the case of MDFNSTATE_BOOL, it is the 31 | * number of bool elements to save(bool is not always 1-byte). 32 | * If 0, the subchunk isn't saved. 33 | */ 34 | uint32_t flags; /* Flags */ 35 | const char *name; /* Name */ 36 | } SFORMAT; 37 | 38 | /* State-Section Descriptor */ 39 | struct SSDescriptor 40 | { 41 | SFORMAT *sf; 42 | const char *name; 43 | bool optional; 44 | }; 45 | 46 | #ifdef __cplusplus 47 | extern "C" { 48 | #endif 49 | 50 | int MDFNSS_SaveSM(void *st, int a, int b, const void *c, const void *d, const void *e); 51 | int MDFNSS_LoadSM(void *st, int a, int b); 52 | 53 | int MDFNSS_StateAction(void *st, int load, int data_only, SFORMAT *sf, const char *name, bool optional); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /mednafen/state_helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef _STATE_HELPERS_H 2 | #define _STATE_HELPERS_H 3 | 4 | #include 5 | 6 | #define SFVARN_BOOL(x, n) { &(x), 1, MDFNSTATE_RLSB | MDFNSTATE_BOOL, n } 7 | #define SFVARN(x, n) { &(x), (uint32_t)sizeof(x), MDFNSTATE_RLSB, n } 8 | #define SFVAR(x) SFVARN((x), #x) 9 | 10 | #define SFARRAYN(x, l, n) { (x), (uint32_t)(l), 0, n } 11 | #define SFARRAY(x, l) SFARRAYN((x), (l), #x) 12 | 13 | #define SFARRAYBN(x, l, n) { (x), (uint32_t)(l), MDFNSTATE_BOOL, n } 14 | #define SFARRAYB(x, l) SFARRAYBN((x), (l), #x) 15 | 16 | #define SFARRAY16N(x, l, n) { (x), (uint32_t)((l) * sizeof(uint16_t)), MDFNSTATE_RLSB16, n } 17 | #define SFARRAY16(x, l) SFARRAY16N((x), (l), #x) 18 | 19 | #define SFARRAY32N(x, l, n) { (x), (uint32_t)((l) * sizeof(uint32_t)), MDFNSTATE_RLSB32, n } 20 | #define SFARRAY32(x, l) SFARRAY32N((x), (l), #x) 21 | 22 | #define SFARRAY64N(x, l, n) { (x), (uint32_t)((l) * sizeof(uint64_t)), MDFNSTATE_RLSB64, n } 23 | #define SFARRAY64(x, l) SFARRAY64N((x), (l), #x) 24 | 25 | #define SFARRAYDN(x, l, n) { (x), (uint32_t)((l) * 8), MDFNSTATE_RLSB64, n } 26 | #define SFARRAYD(x, l) SFARRAYDN((x), (l), #x) 27 | 28 | #define SFEND { 0, 0, 0, 0 } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /mednafen/vb/input.c: -------------------------------------------------------------------------------- 1 | /* Mednafen - Multi-system Emulator 2 | * 3 | * This program is free software; you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation; either version 2 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program; if not, write to the Free Software 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | 20 | #include "../state_helpers.h" 21 | 22 | #include "input.h" 23 | #include "vb.h" 24 | 25 | static bool InstantReadHack; 26 | 27 | static bool IntPending; 28 | 29 | static uint8* data_ptr[2]; 30 | 31 | static uint16 PadData; 32 | static uint16 PadLatched; 33 | 34 | static uint8 SCR; 35 | static uint16 SDR; 36 | 37 | #define SCR_S_ABT_DIS 0x01 38 | #define SCR_SI_STAT 0x02 39 | #define SCR_HW_SI 0x04 40 | #define SCR_SOFT_CLK 0x10 41 | 42 | #define SCR_PARA_SI 0x20 43 | #define SCR_K_INT_INH 0x80 44 | 45 | static uint32 ReadBitPos; 46 | static int32 ReadCounter; 47 | 48 | static v810_timestamp_t last_ts; 49 | 50 | void VBINPUT_Init(void) 51 | { 52 | InstantReadHack = true; 53 | } 54 | 55 | void VBINPUT_SetInstantReadHack(bool enabled) 56 | { 57 | InstantReadHack = enabled; 58 | } 59 | 60 | void VBINPUT_SetInput(int port, const char *type, void *ptr) 61 | { 62 | data_ptr[port] = (uint8 *)ptr; 63 | } 64 | 65 | uint8 VBINPUT_Read(v810_timestamp_t timestamp, uint32 A) 66 | { 67 | uint8_t ret = 0; 68 | 69 | VBINPUT_Update(timestamp); 70 | 71 | switch(A & 0xFF) 72 | { 73 | case 0x10: 74 | if(InstantReadHack) 75 | ret = PadData; 76 | else 77 | ret = SDR & 0xFF; 78 | break; 79 | case 0x14: 80 | if(InstantReadHack) 81 | ret = PadData >> 8; 82 | else 83 | ret = SDR >> 8; 84 | break; 85 | case 0x28: 86 | ret = SCR | (0x40 | 0x08 | SCR_HW_SI); 87 | if(ReadCounter > 0) 88 | ret |= SCR_SI_STAT; 89 | break; 90 | } 91 | 92 | VB_SetEvent(VB_EVENT_INPUT, (ReadCounter > 0) ? (timestamp + ReadCounter) : VB_EVENT_NONONO); 93 | 94 | return(ret); 95 | } 96 | 97 | void VBINPUT_Write(v810_timestamp_t timestamp, uint32 A, uint8 V) 98 | { 99 | VBINPUT_Update(timestamp); 100 | 101 | switch(A & 0xFF) 102 | { 103 | case 0x28: 104 | if((V & SCR_HW_SI) && !(SCR & SCR_S_ABT_DIS) && ReadCounter <= 0) 105 | { 106 | PadLatched = PadData; 107 | ReadBitPos = 0; 108 | ReadCounter = 640; 109 | } 110 | 111 | if(V & SCR_S_ABT_DIS) 112 | { 113 | ReadCounter = 0; 114 | ReadBitPos = 0; 115 | } 116 | 117 | if(V & SCR_K_INT_INH) 118 | { 119 | IntPending = false; 120 | VBIRQ_Assert(VBIRQ_SOURCE_INPUT, IntPending); 121 | } 122 | 123 | SCR = V & (0x80 | 0x20 | 0x10 | 1); 124 | break; 125 | } 126 | 127 | VB_SetEvent(VB_EVENT_INPUT, (ReadCounter > 0) ? (timestamp + ReadCounter) : VB_EVENT_NONONO); 128 | } 129 | 130 | static INLINE uint16_t MDFN_de16lsb(const uint8_t *morp) 131 | { 132 | return(morp[0] | (morp[1] << 8)); 133 | } 134 | 135 | void VBINPUT_Frame(void) 136 | { 137 | PadData = (MDFN_de16lsb(data_ptr[0]) << 2) | 0x2 | (*data_ptr[1] & 0x1); 138 | } 139 | 140 | v810_timestamp_t VBINPUT_Update(const v810_timestamp_t timestamp) 141 | { 142 | int32 clocks = timestamp - last_ts; 143 | 144 | if(ReadCounter > 0) 145 | { 146 | ReadCounter -= clocks; 147 | 148 | while(ReadCounter <= 0) 149 | { 150 | SDR &= ~(1 << ReadBitPos); 151 | SDR |= PadLatched & (1 << ReadBitPos); 152 | 153 | ReadBitPos++; 154 | if(ReadBitPos < 16) 155 | ReadCounter += 640; 156 | else 157 | { 158 | if(!(SCR & SCR_K_INT_INH)) 159 | { 160 | IntPending = true; 161 | VBIRQ_Assert(VBIRQ_SOURCE_INPUT, IntPending); 162 | } 163 | break; 164 | } 165 | } 166 | 167 | } 168 | 169 | 170 | last_ts = timestamp; 171 | 172 | return((ReadCounter > 0) ? (timestamp + ReadCounter) : VB_EVENT_NONONO); 173 | } 174 | 175 | void VBINPUT_ResetTS(void) 176 | { 177 | last_ts = 0; 178 | } 179 | 180 | void VBINPUT_Power(void) 181 | { 182 | last_ts = 0; 183 | PadData = 0; 184 | PadLatched = 0; 185 | SDR = 0; 186 | SCR = 0; 187 | ReadBitPos = 0; 188 | ReadCounter = 0; 189 | IntPending = false; 190 | 191 | VBIRQ_Assert(VBIRQ_SOURCE_INPUT, 0); 192 | } 193 | 194 | int VBINPUT_StateAction(StateMem *sm, int load, int data_only) 195 | { 196 | SFORMAT StateRegs[] = 197 | { 198 | SFVARN(PadData, "PadData"), 199 | SFVARN(PadLatched, "PadLatched"), 200 | SFVARN(SCR, "SCR"), 201 | SFVARN(SDR, "SDR"), 202 | SFVARN(ReadBitPos, "ReadBitPos"), 203 | SFVARN(ReadCounter, "ReadCounter"), 204 | SFVARN_BOOL(IntPending, "IntPending"), 205 | SFEND 206 | }; 207 | 208 | return MDFNSS_StateAction(sm, load, data_only, StateRegs, "INPUT", false); 209 | } 210 | -------------------------------------------------------------------------------- /mednafen/vb/input.h: -------------------------------------------------------------------------------- 1 | #ifndef __VB_INPUT_H 2 | #define __VB_INPUT_H 3 | 4 | #include "../mednafen-types.h" 5 | 6 | #include "../state.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | void VBINPUT_Init(void); 13 | void VBINPUT_SetInstantReadHack(bool); 14 | 15 | void VBINPUT_SetInput(int port, const char *type, void *ptr); 16 | 17 | uint8 VBINPUT_Read(v810_timestamp_t timestamp, uint32 A); 18 | 19 | void VBINPUT_Write(v810_timestamp_t timestamp, uint32 A, uint8 V); 20 | 21 | void VBINPUT_Frame(void); 22 | int VBINPUT_StateAction(StateMem *sm, int load, int data_only); 23 | 24 | int32 VBINPUT_Update(const int32 timestamp); 25 | void VBINPUT_ResetTS(void); 26 | 27 | void VBINPUT_Power(void); 28 | 29 | int VBINPUT_StateAction(StateMem *sm, int load, int data_only); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /mednafen/vb/timer.c: -------------------------------------------------------------------------------- 1 | /* Mednafen - Multi-system Emulator 2 | * 3 | * This program is free software; you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation; either version 2 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program; if not, write to the Free Software 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include "vb.h" 19 | #include "timer.h" 20 | 21 | #include "../state_helpers.h" 22 | 23 | #define TC_TENABLE 0x01 24 | #define TC_ZSTAT 0x02 25 | #define TC_ZSTATCLR 0x04 26 | #define TC_TIMZINT 0x08 27 | #define TC_TCLKSEL 0x10 28 | 29 | static uint8 TimerControl; 30 | static uint16 TimerReloadValue; 31 | static uint16 TimerCounter; 32 | static int32 TimerDivider; 33 | static v810_timestamp_t TimerLastTS; 34 | static bool TimerStatus, TimerStatusShadow; 35 | static bool ReloadPending; 36 | 37 | v810_timestamp_t TIMER_Update(v810_timestamp_t timestamp) 38 | { 39 | int32 run_time = timestamp - TimerLastTS; 40 | 41 | if(TimerControl & TC_TENABLE) 42 | { 43 | TimerDivider -= run_time; 44 | while(TimerDivider <= 0) 45 | { 46 | if(!TimerCounter || ReloadPending) 47 | { 48 | TimerCounter = TimerReloadValue; 49 | ReloadPending = false; 50 | } 51 | 52 | if(TimerCounter) 53 | TimerCounter--; 54 | 55 | if(!TimerCounter || TimerStatus) 56 | { 57 | TimerStatusShadow = TimerStatus = true; 58 | } 59 | 60 | VBIRQ_Assert(VBIRQ_SOURCE_TIMER, TimerStatusShadow && (TimerControl & TC_TIMZINT)); 61 | TimerDivider += (TimerControl & TC_TCLKSEL) ? 400 : 2000; 62 | } 63 | } 64 | 65 | TimerLastTS = timestamp; 66 | 67 | return((TimerControl & TC_TENABLE) ? (timestamp + TimerDivider) : VB_EVENT_NONONO); 68 | } 69 | 70 | void TIMER_ResetTS(void) 71 | { 72 | TimerLastTS = 0; 73 | } 74 | 75 | uint8 TIMER_Read(const v810_timestamp_t timestamp, uint32 A) 76 | { 77 | TIMER_Update(timestamp); 78 | 79 | switch(A & 0xFF) 80 | { 81 | case 0x18: 82 | return TimerCounter; 83 | case 0x1C: 84 | return TimerCounter >> 8; 85 | case 0x20: 86 | return TimerControl | (0xE0 | TC_ZSTATCLR) | (TimerStatus ? TC_ZSTAT : 0); 87 | } 88 | 89 | return 0; 90 | } 91 | 92 | void TIMER_Write(const v810_timestamp_t timestamp, uint32 A, uint8 V) 93 | { 94 | if(A & 0x3) 95 | return; 96 | 97 | TIMER_Update(timestamp); 98 | 99 | switch(A & 0xFF) 100 | { 101 | case 0x18: 102 | TimerReloadValue &= 0xFF00; 103 | TimerReloadValue |= V; 104 | ReloadPending = true; 105 | break; 106 | 107 | case 0x1C: 108 | TimerReloadValue &= 0x00FF; 109 | TimerReloadValue |= V << 8; 110 | ReloadPending = true; 111 | break; 112 | 113 | case 0x20: 114 | if(V & TC_ZSTATCLR) 115 | { 116 | /* Faulty Z-Stat-Clr */ 117 | if((TimerControl & TC_TENABLE) && TimerCounter == 0) { } 118 | else 119 | TimerStatus = false; 120 | TimerStatusShadow = false; 121 | } 122 | if((V & TC_TENABLE) && !(TimerControl & TC_TENABLE)) 123 | TimerDivider = (V & TC_TCLKSEL) ? 500 : 2000; 124 | TimerControl = V & (0x10 | 0x08 | 0x01); 125 | 126 | if(!(TimerControl & TC_TIMZINT)) 127 | TimerStatus = TimerStatusShadow = false; 128 | 129 | VBIRQ_Assert(VBIRQ_SOURCE_TIMER, TimerStatusShadow && (TimerControl & TC_TIMZINT)); 130 | 131 | if(TimerControl & TC_TENABLE) 132 | VB_SetEvent(VB_EVENT_TIMER, timestamp + TimerDivider); 133 | break; 134 | } 135 | } 136 | 137 | void TIMER_Power(void) 138 | { 139 | TimerLastTS = 0; 140 | 141 | TimerCounter = 0xFFFF; 142 | TimerReloadValue = 0xFFFF; 143 | TimerDivider = 2000; 144 | 145 | TimerStatus = false; 146 | TimerStatusShadow = false; 147 | TimerControl = 0; 148 | 149 | ReloadPending = false; 150 | 151 | VBIRQ_Assert(VBIRQ_SOURCE_TIMER, false); 152 | } 153 | 154 | int TIMER_StateAction(StateMem *sm, int load, int data_only) 155 | { 156 | SFORMAT StateRegs[] = 157 | { 158 | SFVARN(TimerCounter, "TimerCounter"), 159 | SFVARN(TimerReloadValue, "TimerReloadValue"), 160 | SFVARN(TimerDivider, "TimerDivider"), 161 | SFVARN_BOOL(TimerStatus, "TimerStatus"), 162 | SFVARN_BOOL(TimerStatusShadow, "TimerStatusShadow"), 163 | SFVARN(TimerControl, "TimerControl"), 164 | SFVARN_BOOL(ReloadPending, "ReloadPending"), 165 | SFEND 166 | }; 167 | 168 | return MDFNSS_StateAction(sm, load, data_only, StateRegs, "TIMER", false); 169 | } 170 | 171 | uint32 TIMER_GetRegister(const unsigned int id, char *special, const uint32 special_len) 172 | { 173 | switch(id) 174 | { 175 | case TIMER_GSREG_TCR: 176 | return TimerControl; 177 | case TIMER_GSREG_DIVCOUNTER: 178 | return TimerDivider; 179 | case TIMER_GSREG_RELOAD_VALUE: 180 | return TimerReloadValue; 181 | case TIMER_GSREG_COUNTER: 182 | return TimerCounter; 183 | } 184 | 185 | return 0xDEADBEEF; 186 | } 187 | 188 | void TIMER_SetRegister(const unsigned int id, const uint32 value) 189 | { 190 | switch(id) 191 | { 192 | case TIMER_GSREG_TCR: 193 | TimerControl = value & (TC_TENABLE | TC_TIMZINT | TC_TCLKSEL); 194 | break; 195 | 196 | case TIMER_GSREG_DIVCOUNTER: 197 | TimerDivider = value % ((TimerControl & TC_TCLKSEL) ? 500 : 2000); 198 | break; 199 | 200 | case TIMER_GSREG_RELOAD_VALUE: 201 | TimerReloadValue = value; 202 | break; 203 | 204 | case TIMER_GSREG_COUNTER: 205 | TimerCounter = value; 206 | break; 207 | 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /mednafen/vb/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __MDFN_VB_TIMER_H 2 | #define __MDFN_VB_TIMER_H 3 | 4 | #include "../state.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | enum 11 | { 12 | TIMER_GSREG_TCR, 13 | TIMER_GSREG_DIVCOUNTER, 14 | TIMER_GSREG_RELOAD_VALUE, 15 | TIMER_GSREG_COUNTER 16 | }; 17 | 18 | v810_timestamp_t TIMER_Update(v810_timestamp_t timestamp); 19 | 20 | void TIMER_ResetTS(void); 21 | 22 | uint8 TIMER_Read(const v810_timestamp_t timestamp, uint32 A); 23 | 24 | void TIMER_Write(const v810_timestamp_t timestamp, uint32 A, uint8 V); 25 | 26 | void TIMER_Power(void) MDFN_COLD; 27 | 28 | int TIMER_StateAction(StateMem *sm, int load, int data_only); 29 | 30 | uint32 TIMER_GetRegister(const unsigned int id, char *special, const uint32 special_len); 31 | 32 | void TIMER_SetRegister(const unsigned int id, const uint32 value); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /mednafen/vb/vb.h: -------------------------------------------------------------------------------- 1 | #ifndef __VB_VB_H 2 | #define __VB_VB_H 3 | 4 | #include 5 | 6 | enum 7 | { 8 | VB3DMODE_ANAGLYPH = 0, 9 | VB3DMODE_CSCOPE = 1, 10 | VB3DMODE_SIDEBYSIDE = 2, 11 | VB3DMODE_OVERUNDER = 3, 12 | VB3DMODE_VLI, 13 | VB3DMODE_HLI 14 | }; 15 | 16 | enum 17 | { 18 | VB_EVENT_VIP = 0, 19 | VB_EVENT_TIMER, 20 | VB_EVENT_INPUT, 21 | // VB_EVENT_COMM 22 | }; 23 | 24 | #define VB_MASTER_CLOCK 20000000.0 25 | 26 | #define VB_EVENT_NONONO 0x7fffffff 27 | 28 | #define VBIRQ_SOURCE_INPUT 0 29 | #define VBIRQ_SOURCE_TIMER 1 30 | #define VBIRQ_SOURCE_EXPANSION 2 31 | #define VBIRQ_SOURCE_COMM 3 32 | #define VBIRQ_SOURCE_VIP 4 33 | 34 | #include "../mednafen-types.h" 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | void VB_SetEvent(const int type, const v810_timestamp_t next_timestamp); 41 | 42 | void VBIRQ_Assert(int source, bool assert); 43 | 44 | void VB_ExitLoop(void); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /mednafen/vb/vip.h: -------------------------------------------------------------------------------- 1 | #ifndef __VB_VIP_H 2 | #define __VB_VIP_H 3 | 4 | #include "../git.h" 5 | #include "../state.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | enum 12 | { 13 | VIP_GSREG_IPENDING = 0, /* Current pending interrupt(bits) */ 14 | VIP_GSREG_IENABLE, 15 | 16 | VIP_GSREG_DPCTRL, 17 | 18 | VIP_GSREG_BRTA, 19 | VIP_GSREG_BRTB, 20 | VIP_GSREG_BRTC, 21 | VIP_GSREG_REST, 22 | VIP_GSREG_FRMCYC, 23 | VIP_GSREG_XPCTRL, 24 | 25 | VIP_GSREG_SPT0, 26 | VIP_GSREG_SPT1, 27 | VIP_GSREG_SPT2, 28 | VIP_GSREG_SPT3, 29 | 30 | VIP_GSREG_GPLT0, 31 | VIP_GSREG_GPLT1, 32 | VIP_GSREG_GPLT2, 33 | VIP_GSREG_GPLT3, 34 | 35 | VIP_GSREG_JPLT0, 36 | VIP_GSREG_JPLT1, 37 | VIP_GSREG_JPLT2, 38 | VIP_GSREG_JPLT3, 39 | 40 | VIP_GSREG_BKCOL 41 | }; 42 | 43 | bool VIP_Init(void) MDFN_COLD; 44 | void VIP_Power(void) MDFN_COLD; 45 | 46 | void VIP_SetInstantDisplayHack(bool); 47 | void VIP_SetAllowDrawSkip(bool); 48 | void VIP_Set3DMode(uint32 mode, bool reverse, uint32 prescale, uint32 sbs_separation); 49 | void VIP_SetParallaxDisable(bool disabled); 50 | void VIP_SetDefaultColor(uint32 default_color); 51 | void VIP_SetAnaglyphColors(uint32 lcolor, uint32 rcolor); /* R << 16, G << 8, B << 0 */ 52 | 53 | v810_timestamp_t MDFN_FASTCALL VIP_Update(const v810_timestamp_t timestamp); 54 | void VIP_ResetTS(void); 55 | 56 | void VIP_StartFrame(EmulateSpecStruct *espec); 57 | 58 | uint8 VIP_Read8(v810_timestamp_t timestamp, uint32 A); 59 | uint16 VIP_Read16(v810_timestamp_t timestamp, uint32 A); 60 | 61 | void VIP_Write8(v810_timestamp_t timestamp, uint32 A, uint8 V); 62 | void VIP_Write16(v810_timestamp_t timestamp, uint32 A, uint16 V); 63 | 64 | int VIP_StateAction(StateMem *sm, int load, int data_only); 65 | 66 | uint32 VIP_GetRegister(const unsigned int id, char *special, const uint32 special_len); 67 | void VIP_SetRegister(const unsigned int id, const uint32 value); 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /mednafen/vb/vip_draw.inc: -------------------------------------------------------------------------------- 1 | #include "vb.h" 2 | 3 | #define BGM_AFFINE 0x2 4 | #define BGM_OBJ 0x3 5 | 6 | 7 | static void DrawBG(uint8 *target, uint16 RealY, bool lr, uint8 bgmap_base_raw, bool overplane, uint16 overplane_char, uint32 SourceX, uint32 SourceY, uint32 scx, uint32 scy, uint16 DestX, uint16 DestY, uint16 DestWidth, uint16 DestHeight) 8 | { 9 | int x; 10 | const uint16 *CHR16 = CHR_RAM; 11 | const uint16 *BGMap = DRAM; 12 | uint32 BGMap_Base = bgmap_base_raw << 12; 13 | int32 start_x, final_x; 14 | const uint32 bgsc_overplane = DRAM[overplane_char]; 15 | const uint32 BGMap_XCount = 1 << scx; 16 | const uint32 BGMap_YCount = 1 << scy; 17 | const uint32 SourceX_Size = 512 * BGMap_XCount; 18 | const uint32 SourceY_Size = 512 * BGMap_YCount; 19 | const uint32 SourceX_Mask = overplane ? 0x1FFF : (SourceX_Size - 1); 20 | const uint32 SourceY_Mask = overplane ? 0x1FFF : (SourceY_Size - 1); 21 | 22 | if((uint16)(RealY - DestY) > DestHeight) 23 | return; 24 | 25 | DestX = sign_10_to_s16(DestX); 26 | 27 | if(DestX & 0x8000) 28 | SourceX -= DestX; 29 | 30 | start_x = (int16)DestX; 31 | final_x = (int16)DestX + DestWidth; 32 | 33 | if(start_x < 0) 34 | start_x = 0; 35 | 36 | if(final_x > 383) 37 | final_x = 383; 38 | 39 | if(start_x > final_x) 40 | return; 41 | 42 | /* Optimization: */ 43 | SourceY &= SourceY_Mask; 44 | BGMap_Base |= (((SourceY >> 3) & 0x3F) * 0x40) | (((SourceY << 3) & ~0xFFF) << scx); 45 | 46 | for(x = start_x; x <= final_x; x++) 47 | { 48 | unsigned int char_sub_y; 49 | uint32 bgsc; 50 | uint32 char_no; 51 | uint32 palette_selector; 52 | uint32 hflip_xor; 53 | uint32 vflip_xor; 54 | 55 | SourceX &= SourceX_Mask; 56 | 57 | bgsc = bgsc_overplane; 58 | 59 | if(SourceX < SourceX_Size && SourceY < SourceY_Size) 60 | bgsc = BGMap[(BGMap_Base | ((SourceX << 3) & ~0xFFF) | ((SourceX >> 3) & 0x3F)) & 0xFFFF]; 61 | 62 | char_no = bgsc & 0x7FF; 63 | palette_selector = bgsc >> 14; 64 | hflip_xor = (bgsc & 0x2000) ? 7 : 0; 65 | vflip_xor = (bgsc & 0x1000) ? 7 : 0; 66 | 67 | char_sub_y = vflip_xor ^ (SourceY & 0x7); 68 | 69 | if(!(SourceX & 7) && (x + 7) <= final_x) 70 | { 71 | uint32 pixels = CHR16[char_no * 8 + char_sub_y]; 72 | 73 | if(bgsc & 0x2000) 74 | { 75 | if((pixels >> 14) & 3) target[0 + x] = GPLT_Cache[palette_selector][(pixels >> 14) & 3]; 76 | if((pixels >> 12) & 3) target[1 + x] = GPLT_Cache[palette_selector][(pixels >> 12) & 3]; 77 | if((pixels >> 10) & 3) target[2 + x] = GPLT_Cache[palette_selector][(pixels >> 10) & 3]; 78 | if((pixels >> 8) & 3) target[3 + x] = GPLT_Cache[palette_selector][(pixels >> 8) & 3]; 79 | if((pixels >> 6) & 3) target[4 + x] = GPLT_Cache[palette_selector][(pixels >> 6) & 3]; 80 | if((pixels >> 4) & 3) target[5 + x] = GPLT_Cache[palette_selector][(pixels >> 4) & 3]; 81 | if((pixels >> 2) & 3) target[6 + x] = GPLT_Cache[palette_selector][(pixels >> 2) & 3]; 82 | if((pixels >> 0) & 3) target[7 + x] = GPLT_Cache[palette_selector][(pixels >> 0) & 3]; 83 | } 84 | else 85 | { 86 | if((pixels >> 0) & 3) target[0 + x] = GPLT_Cache[palette_selector][(pixels >> 0) & 3]; 87 | if((pixels >> 2) & 3) target[1 + x] = GPLT_Cache[palette_selector][(pixels >> 2) & 3]; 88 | if((pixels >> 4) & 3) target[2 + x] = GPLT_Cache[palette_selector][(pixels >> 4) & 3]; 89 | if((pixels >> 6) & 3) target[3 + x] = GPLT_Cache[palette_selector][(pixels >> 6) & 3]; 90 | if((pixels >> 8) & 3) target[4 + x] = GPLT_Cache[palette_selector][(pixels >> 8) & 3]; 91 | if((pixels >> 10) & 3) target[5 + x] = GPLT_Cache[palette_selector][(pixels >> 10) & 3]; 92 | if((pixels >> 12) & 3) target[6 + x] = GPLT_Cache[palette_selector][(pixels >> 12) & 3]; 93 | if((pixels >> 14) & 3) target[7 + x] = GPLT_Cache[palette_selector][(pixels >> 14) & 3]; 94 | } 95 | 96 | x += 7; 97 | SourceX += 8; 98 | } 99 | else 100 | { 101 | unsigned int char_sub_x = hflip_xor ^ (SourceX & 0x7); 102 | uint8 pixel = (CHR16[char_no * 8 + char_sub_y] >> (char_sub_x * 2)) & 0x3; 103 | 104 | if(pixel) 105 | target[x] = GPLT_Cache[palette_selector][pixel]; 106 | SourceX++; 107 | } 108 | } 109 | } 110 | 111 | static void DrawAffine(uint8 *target, uint16 RealY, bool lr, uint32 ParamBase, uint32 BGMap_Base, bool OverplaneMode, uint16 OverplaneChar, uint32 scx, uint32 scy, 112 | uint16 DestX, uint16 DestY, uint16 DestWidth, uint16 DestHeight) 113 | { 114 | const uint16 *CHR16 = CHR_RAM; 115 | const uint16 *BGMap = DRAM; 116 | 117 | const uint32 BGMap_XCount = 1 << scx; 118 | const uint32 BGMap_YCount = 1 << scy; 119 | const uint32 SourceX_Size = 512 * BGMap_XCount; 120 | const uint32 SourceY_Size = 512 * BGMap_YCount; 121 | 122 | const uint16 *param_ptr = &DRAM[(ParamBase + 8 * (RealY - DestY)) & 0xFFFF]; 123 | int16 mx = param_ptr[0], mp = (ParallaxDisabled ? 0 : param_ptr[1]), my = param_ptr[2], dx = param_ptr[3], dy = param_ptr[4]; 124 | 125 | uint32 SourceX, SourceY; 126 | uint32 SourceX_Mask, SourceY_Mask; 127 | 128 | int32 start_x, final_x; 129 | const uint32 bgsc_overplane = DRAM[OverplaneChar]; 130 | 131 | 132 | DestX = sign_10_to_s16(DestX); 133 | 134 | if((uint16)(RealY - DestY) > DestHeight) 135 | return; 136 | 137 | SourceX = (int32)mx << 6; 138 | SourceY = (int32)my << 6; 139 | 140 | if(DestX & 0x8000) 141 | { 142 | SourceX += dx * (65536 - DestX); 143 | SourceY += dy * (65536 - DestX); 144 | } 145 | 146 | if(mp >= 0 && lr) 147 | { 148 | SourceX += dx * mp; 149 | SourceY += dy * mp; 150 | } 151 | else if(mp < 0 && !lr) 152 | { 153 | SourceX += dx * -mp; 154 | SourceY += dy * -mp; 155 | } 156 | 157 | if(OverplaneMode) 158 | { 159 | SourceX_Mask = 0x3FFFFFF; 160 | SourceY_Mask = 0x3FFFFFF; 161 | } 162 | else 163 | { 164 | SourceX_Mask = ((uint32)SourceX_Size << 9) - 1; 165 | SourceY_Mask = ((uint32)SourceY_Size << 9) - 1; 166 | } 167 | 168 | start_x = (int16)DestX; 169 | final_x = (int16)DestX + DestWidth; 170 | 171 | if(start_x < 0) 172 | start_x = 0; 173 | 174 | if(final_x > 383) 175 | final_x = 383; 176 | 177 | if(dy == 0) /* Optimization for no rotation. */ 178 | { 179 | int x; 180 | SourceY &= SourceY_Mask; 181 | 182 | if(SourceY >= (SourceY_Size << 9)) 183 | return; 184 | 185 | BGMap_Base |= (((SourceY >> 6) & ~0xFFF) << scx) | (((SourceY >> 12) & 0x3F) * 0x40); 186 | for(x = start_x; x <= final_x; x++) 187 | { 188 | unsigned int char_sub_y; 189 | unsigned int char_sub_x; 190 | uint32 bgsc; 191 | uint32 hflip_xor; 192 | uint32 vflip_xor; 193 | uint32 pixel = 0; 194 | 195 | SourceX &= SourceX_Mask; 196 | 197 | bgsc = bgsc_overplane; 198 | 199 | if(SourceX < (SourceX_Size << 9)) 200 | bgsc = BGMap[(BGMap_Base | ((SourceX >> 6) & ~0xFFF) | ((SourceX >> 12) & 0x3F)) & 0xFFFF]; 201 | 202 | hflip_xor = ((int32)(bgsc << 18) >> 30) & 0xE; 203 | vflip_xor = ((int32)(bgsc << 19) >> 31) & 0x7; 204 | 205 | char_sub_y = vflip_xor ^ ((SourceY >> 9) & 0x7); 206 | char_sub_x = hflip_xor ^ ((SourceX >> 8) & 0xE); 207 | 208 | pixel = (CHR16[((bgsc & 0x7FF) * 8) | char_sub_y] >> char_sub_x) & 0x3; 209 | 210 | if(pixel) 211 | target[x] = GPLT_Cache[bgsc >> 14][pixel]; 212 | 213 | SourceX += dx; 214 | } 215 | } 216 | else 217 | { 218 | int x; 219 | for(x = start_x; x <= final_x; x++) 220 | { 221 | uint32 bgsc; 222 | uint32 char_no; 223 | uint32 palette_selector; 224 | uint32 hflip_xor; 225 | uint32 vflip_xor; 226 | uint8 pixel = 0; 227 | unsigned int char_sub_y; 228 | unsigned int char_sub_x; 229 | 230 | SourceX &= SourceX_Mask; 231 | SourceY &= SourceY_Mask; 232 | 233 | bgsc = bgsc_overplane; 234 | 235 | if(SourceX < (SourceX_Size << 9) && SourceY < (SourceY_Size << 9)) 236 | { 237 | uint32 m_index = ((SourceX >> 6) & ~0xFFF) + (((SourceY >> 6) & ~0xFFF) << scx); 238 | uint32 sub_index = ((SourceX >> 12) & 0x3F) + (((SourceY >> 12) & 0x3F) * 0x40); 239 | 240 | bgsc = BGMap[(BGMap_Base | m_index | sub_index) & 0xFFFF]; 241 | } 242 | char_no = bgsc & 0x7FF; 243 | palette_selector = bgsc >> 14; 244 | hflip_xor = bgsc & 0x2000 ? 7 : 0; 245 | vflip_xor = bgsc & 0x1000 ? 7 : 0; 246 | 247 | char_sub_y = vflip_xor ^ ((SourceY >> 9) & 0x7); 248 | char_sub_x = hflip_xor ^ ((SourceX >> 9) & 0x7); 249 | 250 | pixel = (CHR16[char_no * 8 + char_sub_y] >> (char_sub_x * 2)) & 0x3; 251 | 252 | if(pixel) 253 | target[x] = GPLT_Cache[palette_selector][pixel]; 254 | 255 | SourceX += dx; 256 | SourceY += dy; 257 | } 258 | } 259 | } 260 | 261 | static int obj_search_which; 262 | 263 | static void DrawOBJ(uint8 *fb[2], uint16 Y, bool lron[2]) 264 | { 265 | int32 oam; 266 | const uint16 *CHR16 = CHR_RAM; 267 | 268 | int32 start_oam; 269 | int32 end_oam; 270 | 271 | start_oam = SPT[obj_search_which]; 272 | 273 | end_oam = 1023; 274 | if(obj_search_which) 275 | end_oam = SPT[obj_search_which - 1]; 276 | 277 | oam = start_oam; 278 | do 279 | { 280 | int lr; 281 | uint32 pixels_save; 282 | uint32 char_no; 283 | uint32 jx, jp; 284 | uint32 palette_selector; 285 | uint32 vflip_xor; 286 | uint32 char_sub_y; 287 | bool jlron[2]; 288 | const uint16 *oam_ptr = &DRAM[(0x1E000 + (oam * 8)) >> 1]; 289 | const uint32 jy = oam_ptr[2]; 290 | const uint32 tile_y = (Y - jy) & 0xFF; 291 | 292 | if(tile_y >= 8) 293 | continue; 294 | 295 | jx = oam_ptr[0]; 296 | jp = ParallaxDisabled ? 0 : (oam_ptr[1] & 0x3FFF); 297 | palette_selector = oam_ptr[3] >> 14; 298 | vflip_xor = (oam_ptr[3] & 0x1000) ? 7 : 0; 299 | char_sub_y = vflip_xor ^ tile_y; 300 | jlron[0] = (bool)(oam_ptr[1] & 0x8000); 301 | jlron[1] = (bool)(oam_ptr[1] & 0x4000); 302 | char_no = oam_ptr[3] & 0x7FF; 303 | pixels_save = CHR16[char_no * 8 + char_sub_y]; 304 | 305 | for(lr = 0; lr < 2; lr++) 306 | { 307 | uint32 pixels; 308 | int32 x; 309 | if(!(jlron[lr] & lron[lr])) 310 | continue; 311 | 312 | pixels = pixels_save; 313 | x = sign_x_to_s32(10, (jx + (lr ? jp : -jp))); /* It may actually be 9, TODO? */ 314 | 315 | if(x >= -7 && x < 384) /* Make sure we always keep the pitch of our 384x8 buffer large enough(with padding before and after the visible space) */ 316 | { 317 | uint8 *target = &fb[lr][x]; 318 | 319 | if(oam_ptr[3] & 0x2000) 320 | { 321 | int meow; 322 | target += 7; 323 | 324 | for(meow = 8; meow; meow--) 325 | { 326 | if(pixels & 3) 327 | *target = JPLT_Cache[palette_selector][pixels & 3]; 328 | target--; 329 | pixels >>= 2; 330 | } 331 | } 332 | else 333 | { 334 | int meow; 335 | for(meow = 8; meow; meow--) 336 | { 337 | if(pixels & 3) 338 | *target = JPLT_Cache[palette_selector][pixels & 3]; 339 | target++; 340 | pixels >>= 2; 341 | } 342 | } 343 | 344 | } 345 | 346 | } 347 | } while( (oam = (oam - 1) & 1023) != end_oam); 348 | 349 | } 350 | 351 | 352 | void VIP_DrawBlock(uint8 block_no, uint8 *fb_l, uint8 *fb_r) 353 | { 354 | int y, world, lr; 355 | for( y = 0; y < 8; y++) 356 | { 357 | memset(fb_l + y * 512, BKCOL, 384); 358 | memset(fb_r + y * 512, BKCOL, 384); 359 | } 360 | 361 | obj_search_which = 3; 362 | 363 | for(world = 31; world >= 0; world--) 364 | { 365 | const uint16 *world_ptr = &DRAM[(0x1D800 + world * 0x20) >> 1]; 366 | 367 | uint32 bgmap_base = world_ptr[0] & 0xF; 368 | bool end = world_ptr[0] & 0x40; 369 | bool over = world_ptr[0] & 0x80; 370 | uint32 scy = (world_ptr[0] >> 8) & 3; 371 | uint32 scx = (world_ptr[0] >> 10) & 3; 372 | uint32 bgm = (world_ptr[0] >> 12) & 3; 373 | bool lron[2] = { (bool)(world_ptr[0] & 0x8000), (bool)(world_ptr[0] & 0x4000) }; 374 | 375 | uint16 gx = sign_11_to_s16(world_ptr[1]); 376 | uint16 gp = ParallaxDisabled ? 0 : sign_9_to_s16(world_ptr[2]); 377 | uint16 gy = sign_11_to_s16(world_ptr[3]); 378 | uint16 mx = world_ptr[4]; 379 | uint16 mp = ParallaxDisabled ? 0 : sign_9_to_s16(world_ptr[5]); 380 | uint16 my = world_ptr[6]; 381 | uint16 window_width = sign_11_to_s16(world_ptr[7]); 382 | uint16 window_height = (world_ptr[8] & 0x3FF); 383 | uint32 param_base = (world_ptr[9] & 0xFFF0); 384 | uint16 overplane_char = world_ptr[10]; 385 | 386 | if(end) 387 | break; 388 | 389 | for(y = 0; y < 8; y++) 390 | { 391 | uint8 *fb[2] = { &fb_l[y * 512], &fb_r[y * 512] }; 392 | 393 | if(bgm == BGM_OBJ) 394 | DrawOBJ(fb, (block_no * 8) + y, lron); 395 | else if(bgm == BGM_AFFINE) 396 | { 397 | for(lr = 0; lr < 2; lr++) 398 | { 399 | if(lron[lr]) 400 | { 401 | DrawAffine(fb[lr], (block_no * 8) + y, lr, param_base, bgmap_base * 4096, over, overplane_char, scx, scy, 402 | gx + (lr ? gp : -gp), gy, window_width, window_height); 403 | } 404 | } 405 | } 406 | else 407 | for(lr = 0; lr < 2; lr++) 408 | { 409 | uint16 srcX, srcY; 410 | uint16 RealY = (block_no * 8) + y; 411 | uint16 DestX; 412 | uint16 DestY; 413 | 414 | srcX = mx + (lr ? mp : -mp); 415 | srcY = my + (RealY - gy); 416 | 417 | DestX = gx + (lr ? gp : -gp); 418 | DestY = gy; 419 | 420 | if(lron[lr]) 421 | { 422 | if(bgm == 1) /* HBias */ 423 | srcX += (int16)DRAM[(param_base + (((RealY - DestY) * 2) | lr)) & 0xFFFF]; 424 | 425 | DrawBG(fb[lr], RealY, lr, bgmap_base, over, overplane_char, (int32)(int16)srcX, (int32)(int16)srcY, scx, scy, DestX, DestY, window_width, window_height); 426 | } 427 | } 428 | } 429 | 430 | if(bgm == BGM_OBJ) 431 | if(obj_search_which) 432 | obj_search_which--; 433 | 434 | } 435 | 436 | 437 | } 438 | -------------------------------------------------------------------------------- /mednafen/vb/vsu.h: -------------------------------------------------------------------------------- 1 | #ifndef __VB_VSU_H 2 | #define __VB_VSU_H 3 | 4 | #include "../include/blip/Blip_Buffer.h" 5 | 6 | #include "../state.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | void VSU_Init(Blip_Buffer *bb_l, Blip_Buffer *bb_r) MDFN_COLD; 13 | 14 | void VSU_Power(void) MDFN_COLD; 15 | 16 | void VSU_Write(int32 timestamp, uint32 A, uint8 V); 17 | 18 | void VSU_EndFrame(int32 timestamp); 19 | 20 | int VSU_StateAction(StateMem *sm, int load, int data_only); 21 | 22 | uint8 VSU_PeekWave(const unsigned int which, uint32 Address); 23 | void VSU_PokeWave(const unsigned int which, uint32 Address, uint8 value); 24 | 25 | uint8 VSU_PeekModWave(uint32 Address); 26 | void VSU_PokeModWave(uint32 Address, uint8 value); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /mednafen/video/surface.h: -------------------------------------------------------------------------------- 1 | #ifndef __MDFN_SURFACE_H 2 | #define __MDFN_SURFACE_H 3 | 4 | #include "../mednafen-types.h" 5 | 6 | #if defined(WANT_32BPP) 7 | #define RED_SHIFT 16 8 | #define GREEN_SHIFT 8 9 | #define BLUE_SHIFT 0 10 | #define ALPHA_SHIFT 24 11 | #define MAKECOLOR(r, g, b, a) ((r << RED_SHIFT) | (g << GREEN_SHIFT) | (b << BLUE_SHIFT) | (a << ALPHA_SHIFT)) 12 | #elif defined(WANT_16BPP) && defined(FRONTEND_SUPPORTS_RGB565) 13 | /* 16bit color - RGB565 */ 14 | #define RED_MASK 0xf800 15 | #define GREEN_MASK 0x7e0 16 | #define BLUE_MASK 0x1f 17 | #define RED_EXPAND 3 18 | #define GREEN_EXPAND 2 19 | #define BLUE_EXPAND 3 20 | #define RED_SHIFT 11 21 | #define GREEN_SHIFT 5 22 | #define BLUE_SHIFT 0 23 | #define MAKECOLOR(r, g, b, a) (((r >> RED_EXPAND) << RED_SHIFT) | ((g >> GREEN_EXPAND) << GREEN_SHIFT) | ((b >> BLUE_EXPAND) << BLUE_SHIFT)) 24 | #elif defined(WANT_16BPP) && !defined(FRONTEND_SUPPORTS_RGB565) 25 | /* 16bit color - RGB555 */ 26 | #define RED_MASK 0x7c00 27 | #define GREEN_MASK 0x3e0 28 | #define BLUE_MASK 0x1f 29 | #define RED_EXPAND 3 30 | #define GREEN_EXPAND 3 31 | #define BLUE_EXPAND 3 32 | #define RED_SHIFT 10 33 | #define GREEN_SHIFT 5 34 | #define BLUE_SHIFT 0 35 | #define MAKECOLOR(r, g, b, a) (((r >> RED_EXPAND) << RED_SHIFT) | ((g >> GREEN_EXPAND) << GREEN_SHIFT) | ((b >> BLUE_EXPAND) << BLUE_SHIFT)) 36 | #endif 37 | 38 | typedef struct 39 | { 40 | int32 x, y, w, h; 41 | } MDFN_Rect; 42 | 43 | enum 44 | { 45 | MDFN_COLORSPACE_RGB = 0 46 | }; 47 | 48 | struct MDFN_PixelFormat 49 | { 50 | unsigned int bpp; 51 | unsigned int colorspace; 52 | 53 | uint8 Rshift; // Bit position of the lowest bit of the red component 54 | uint8 Gshift; // [...] green component 55 | uint8 Bshift; // [...] blue component 56 | uint8 Ashift; // [...] alpha component. 57 | }; // MDFN_PixelFormat; 58 | 59 | // Supports 32-bit RGBA 60 | // 16-bit is WIP 61 | struct MDFN_Surface //typedef struct 62 | { 63 | uint8 *pixels8; 64 | uint16 *pixels16; 65 | uint32 *pixels; 66 | 67 | // w, h, and pitch32 should always be > 0 68 | int32 w; 69 | int32 h; 70 | 71 | union 72 | { 73 | int32 pitch32; // In pixels, not in bytes. 74 | int32 pitchinpix; // New name, new code should use this. 75 | }; 76 | 77 | struct MDFN_PixelFormat format; 78 | }; 79 | 80 | #endif 81 | --------------------------------------------------------------------------------