From f04fe9bf5bfe8fc6a3ce3ee2c90747daf579258c Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 25 Mar 2020 10:17:07 +0100 Subject: [PATCH 01/21] Consider the overscan setting when getting the aspect ratio --- bsnes/target-libretro/libretro.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/bsnes/target-libretro/libretro.cpp b/bsnes/target-libretro/libretro.cpp index 0a1e6b43..68123f66 100644 --- a/bsnes/target-libretro/libretro.cpp +++ b/bsnes/target-libretro/libretro.cpp @@ -46,20 +46,27 @@ static int aspect_ratio_mode = 0; static double get_aspect_ratio() { + double ratio; + if (aspect_ratio_mode == 0 && program->superFamicom.region == "NTSC") - return 1.306122; + ratio = 1.306122; else if (aspect_ratio_mode == 0 && program->superFamicom.region == "PAL") - return 1.584216; + ratio = 1.584216; else if (aspect_ratio_mode == 1) // 8:7 - return 8.0/7.0; + ratio = 8.0/7.0; else if (aspect_ratio_mode == 2) // 4:3 return 4.0/3.0; else if (aspect_ratio_mode == 3) // NTSC - return 1.306122; + ratio = 1.306122; else if (aspect_ratio_mode == 4) // PAL - return 1.584216; + ratio = 1.584216; else - return 8.0/7.0; // Default + ratio = 8.0/7.0; // Default + + if (program->overscan) + return (ratio / 240) * 224; + else + return ratio; } static void flush_variables() From 0bbe5b58f3e80d400d6f2bacbd7d33f0dc4d9210 Mon Sep 17 00:00:00 2001 From: Sanaki Date: Sat, 20 Jun 2020 02:45:50 -0700 Subject: [PATCH 02/21] Corrected valid extensions to fix archive loading of GB/GBC --- bsnes/target-libretro/libretro.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsnes/target-libretro/libretro.cpp b/bsnes/target-libretro/libretro.cpp index 68123f66..fcec9723 100644 --- a/bsnes/target-libretro/libretro.cpp +++ b/bsnes/target-libretro/libretro.cpp @@ -533,7 +533,7 @@ RETRO_API void retro_get_system_info(retro_system_info *info) info->library_name = "bsnes"; info->library_version = Emulator::Version; info->need_fullpath = true; - info->valid_extensions = "smc|sfc"; + info->valid_extensions = "smc|sfc|gb|gbc"; info->block_extract = false; } From 76f508f731110705179b8be133bb6189b92fa078 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 13 Oct 2020 10:05:45 +0200 Subject: [PATCH 03/21] Add Makefile and Makefile.common --- Makefile | 508 ++++++++++++++++++++++++++++++++++++++++++++++++ Makefile.common | 56 ++++++ 2 files changed, 564 insertions(+) create mode 100644 Makefile create mode 100644 Makefile.common diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..80ea1dae --- /dev/null +++ b/Makefile @@ -0,0 +1,508 @@ +DEBUG = 0 +FRONTEND_SUPPORTS_RGB565 = 1 + +CORE_DIR := . +CFLAGS := +CXXFLAGS := + +SPACE := +SPACE := $(SPACE) $(SPACE) +BACKSLASH := +BACKSLASH := \$(BACKSLASH) +filter_out1 = $(filter-out $(firstword $1),$1) +filter_out2 = $(call filter_out1,$(call filter_out1,$1)) + +ifeq ($(platform),) +platform = unix +ifeq ($(shell uname -s),) + platform = win +else ifneq ($(findstring MINGW,$(shell uname -s)),) + platform = win +else ifneq ($(findstring Darwin,$(shell uname -s)),) + platform = osx +else ifneq ($(findstring win,$(shell uname -s)),) + platform = win +endif +endif + +# system platform +system_platform = unix +ifeq ($(shell uname -s),) + EXE_EXT = .exe + system_platform = win +else ifneq ($(findstring Darwin,$(shell uname -s)),) + system_platform = osx +ifeq ($(shell uname -p),powerpc) + arch = ppc +else + arch = intel +endif +else ifneq ($(findstring MINGW,$(shell uname -s)),) + system_platform = win +endif + +# profile-guided optimization mode +# pgo := instrument +# pgo := optimize + +ifeq ($(PGO),instrument) + CFLAGS += -fprofile-generate + CXXFLAGS += -fprofile-generate + LDFLAGS += -lgcov +else ifeq ($(PGO),optimize) + CFLAGS += -fprofile-use + CXXFLAGS += -fprofile-use +endif + +CORE_DEFINE := + +TARGET_NAME := bsnes +GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)" +ifneq ($(GIT_VERSION)," unknown") + CXXFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\" +endif + +ifeq ($(platform), unix) + TARGET := $(TARGET_NAME)_libretro.so + fpic := -fPIC + SHARED := -shared -Wl,--no-undefined -Wl,--version-script=$(CORE_DIR)/bsnes/target-libretro/link.T + ifneq ($(shell uname -p | grep -E '((i.|x)86|amd64)'),) + IS_X86 = 1 + endif + ifneq ($(findstring Haiku,$(shell uname -s)),) + CXXFLAGS += -fpermissive + endif + LDFLAGS += -ldl +else ifeq ($(platform), osx) + TARGET := $(TARGET_NAME)_libretro.dylib + fpic := -fPIC + SHARED := -dynamiclib +ifeq ($(arch),ppc) + ENDIANNESS_DEFINES := -DMSB_FIRST + OLD_GCC := 1 +endif + OSXVER = `sw_vers -productVersion | cut -d. -f 2` + OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"` + fpic += -mmacosx-version-min=10.1 + +# iOS +else ifneq (,$(findstring ios,$(platform))) + + TARGET := $(TARGET_NAME)_libretro_ios.dylib + fpic := -fPIC + SHARED := -dynamiclib + +ifeq ($(IOSSDK),) + IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path) +endif + +ifeq ($(platform),ios-arm64) + CC = cc -arch arm64 -isysroot $(IOSSDK) + CXX = c++ -arch arm64 -isysroot $(IOSSDK) +else + CC = cc -arch armv7 -isysroot $(IOSSDK) + CXX = c++ -arch armv7 -isysroot $(IOSSDK) +endif +IPHONEMINVER := +ifeq ($(platform),$(filter $(platform),ios9 ios-arm64)) + IPHONEMINVER = -miphoneos-version-min=8.0 +else + IPHONEMINVER = -miphoneos-version-min=5.0 +endif + LDFLAGS += $(IPHONEMINVER) + FLAGS += $(IPHONEMINVER) + CC += $(IPHONEMINVER) + CXX += $(IPHONEMINVER) + +# tvOS +else ifeq ($(platform), tvos-arm64) + TARGET := $(TARGET_NAME)_libretro_tvos.dylib + fpic := -fPIC + SHARED := -dynamiclib + +ifeq ($(IOSSDK),) + IOSSDK := $(shell xcodebuild -version -sdk appletvos Path) +endif + +else ifeq ($(platform), qnx) + TARGET := $(TARGET_NAME)_libretro_$(platform).so + fpic := -fPIC + SHARED := -lcpp -lm -shared -Wl,--no-undefined -Wl,--version-script=$(CORE_DIR)/bsnes/target-libretro/link.T + CC = qcc -Vgcc_ntoarmv7le + CXX = QCC -Vgcc_ntoarmv7le_cpp + AR = QCC -Vgcc_ntoarmv7le + FLAGS += -D__BLACKBERRY_QNX__ -marm -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp +else ifeq ($(platform), ps3) + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe + CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe + AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe + ENDIANNESS_DEFINES := -DMSB_FIRST + OLD_GCC := 1 + FLAGS += -DARCH_POWERPC_ALTIVEC + STATIC_LINKING = 1 +else ifeq ($(platform), sncps3) + TARGET := $(TARGET_NAME)_libretro_ps3.a + CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe + CXX = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe + AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe + ENDIANNESS_DEFINES := -DMSB_FIRST + CXXFLAGS += -Xc+=exceptions + OLD_GCC := 1 + NO_GCC := 1 + FLAGS += -DARCH_POWERPC_ALTIVEC + STATIC_LINKING = 1 +else ifeq ($(platform), psl1ght) + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = $(PS3DEV)/ppu/bin/ppu-gcc$(EXE_EXT) + CXX = $(PS3DEV)/ppu/bin/ppu-g++$(EXE_EXT) + AR = $(PS3DEV)/ppu/bin/ppu-ar$(EXE_EXT) + ENDIANNESS_DEFINES := -DMSB_FIRST + STATIC_LINKING = 1 + +# PSP +else ifeq ($(platform), psp1) + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = psp-gcc$(EXE_EXT) + CXX = psp-g++$(EXE_EXT) + AR = psp-ar$(EXE_EXT) + FLAGS += -DPSP -G0 + STATIC_LINKING = 1 + EXTRA_INCLUDES := -I$(shell psp-config --pspsdk-path)/include + +# Vita +else ifeq ($(platform), vita) + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = arm-vita-eabi-gcc$(EXE_EXT) + CXX = arm-vita-eabi-g++$(EXE_EXT) + AR = arm-vita-eabi-ar$(EXE_EXT) + FLAGS += -DVITA + STATIC_LINKING = 1 + +# Xbox 360 +else ifeq ($(platform), xenon) + TARGET := $(TARGET_NAME)_libretro_xenon360.a + CC = xenon-gcc$(EXE_EXT) + CXX = xenon-g++$(EXE_EXT) + AR = xenon-ar$(EXE_EXT) + ENDIANNESS_DEFINES += -D__LIBXENON__ -m32 -D__ppc__ -DMSB_FIRST + LIBS := + STATIC_LINKING = 1 + +# Nintendo Switch (libnx) +else ifeq ($(platform), libnx) +include $(DEVKITPRO)/libnx/switch_rules + TARGET := $(TARGET_NAME)_libretro_$(platform).a + DEFINES := -DSWITCH=1 -U__linux__ -U__linux -DRARCH_INTERNAL + CFLAGS += $(DEFINES) -fPIE -I$(LIBNX)/include/ -ffunction-sections -fdata-sections -ftls-model=local-exec -Wl,--allow-multiple-definition -specs=$(LIBNX)/switch.specs + CFLAGS += $(INCDIRS) + CFLAGS += $(INCLUDE) -D__SWITCH__ -DHAVE_LIBNX + CXXFLAGS += $(ASFLAGS) $(CFLAGS) -fexceptions -fno-rtti -std=gnu++11 + CFLAGS += -std=gnu11 + STATIC_LINKING = 1 + +# Nintendo Gamecube +else ifeq ($(platform), ngc) + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) + CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT) + AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) + ENDIANNESS_DEFINES += -DGEKKO -DHW_DOL -mrvl -mcpu=750 -meabi -mhard-float -DMSB_FIRST + FLAGS += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int + + EXTRA_INCLUDES := -I$(DEVKITPRO)/libogc/include + STATIC_LINKING = 1 + +# wii +else ifeq ($(platform), wii) + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) + CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT) + AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) + ENDIANNESS_DEFINES += -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float -DMSB_FIRST + FLAGS += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int + + EXTRA_INCLUDES := -I$(DEVKITPRO)/libogc/include + STATIC_LINKING = 1 + +# wiiu +else ifeq ($(platform), wiiu) + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) + CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT) + AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) + ENDIANNESS_DEFINES += -DGEKKO -DWIIU -DHW_RVL -mwup -mcpu=750 -meabi -mhard-float -DMSB_FIRST + FLAGS += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int + + EXTRA_INCLUDES := -I$(DEVKITPRO)/libogc/include + STATIC_LINKING = 1 + +else ifneq (,$(findstring armv,$(platform))) + TARGET := $(TARGET_NAME)_libretro.so + fpic := -fPIC + SHARED := -shared -Wl,--no-undefined -Wl,--version-script=$(CORE_DIR)/bsnes/target-libretro/link.T + CC = gcc + IS_X86 = 0 +ifneq (,$(findstring cortexa8,$(platform))) + FLAGS += -marm -mcpu=cortex-a8 + ASFLAGS += -mcpu=cortex-a8 +else ifneq (,$(findstring cortexa9,$(platform))) + FLAGS += -marm -mcpu=cortex-a9 + ASFLAGS += -mcpu=cortex-a9 +endif + +ifneq (,$(findstring neon,$(platform))) + FLAGS += -mfpu=neon + ASFLAGS += -mfpu=neon + HAVE_NEON = 1 +endif +ifneq (,$(findstring softfloat,$(platform))) + FLAGS += -mfloat-abi=softfp +else ifneq (,$(findstring hardfloat,$(platform))) + FLAGS += -mfloat-abi=hard +endif + FLAGS += -DARM + +# Windows MSVC 2017 all architectures +else ifneq (,$(findstring windows_msvc2017,$(platform))) + + NO_GCC := 1 + CFLAGS += -DNOMINMAX + CXXFLAGS += -DNOMINMAX + WINDOWS_VERSION = 1 + + PlatformSuffix = $(subst windows_msvc2017_,,$(platform)) + ifneq (,$(findstring desktop,$(PlatformSuffix))) + WinPartition = desktop + MSVC2017CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -FS + LDFLAGS += -MANIFEST -LTCG:incremental -NXCOMPAT -DYNAMICBASE -DEBUG -OPT:REF -INCREMENTAL:NO -SUBSYSTEM:WINDOWS -MANIFESTUAC:"level='asInvoker' uiAccess='false'" -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1 + LIBS += kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib + else ifneq (,$(findstring uwp,$(PlatformSuffix))) + WinPartition = uwp + MSVC2017CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_APP -D_WINDLL -D_UNICODE -DUNICODE -D__WRL_NO_DEFAULT_LIB__ -EHsc -FS + LDFLAGS += -APPCONTAINER -NXCOMPAT -DYNAMICBASE -MANIFEST:NO -LTCG -OPT:REF -SUBSYSTEM:CONSOLE -MANIFESTUAC:NO -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1 -DEBUG:FULL -WINMD:NO + LIBS += WindowsApp.lib + endif + + CFLAGS += $(MSVC2017CompileFlags) + CXXFLAGS += $(MSVC2017CompileFlags) + + TargetArchMoniker = $(subst $(WinPartition)_,,$(PlatformSuffix)) + + CC = cl.exe + CXX = cl.exe + LD = link.exe + + reg_query = $(call filter_out2,$(subst $2,,$(shell reg query "$2" -v "$1" 2>nul))) + fix_path = $(subst $(SPACE),\ ,$(subst \,/,$1)) + + ProgramFiles86w := $(shell cmd //c "echo %PROGRAMFILES(x86)%") + ProgramFiles86 := $(shell cygpath "$(ProgramFiles86w)") + + WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0) + WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0) + WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0) + WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0) + WindowsSdkDir := $(WindowsSdkDir) + + WindowsSDKVersion ?= $(firstword $(foreach folder,$(subst $(subst \,/,$(WindowsSdkDir)Include/),,$(wildcard $(call fix_path,$(WindowsSdkDir)Include\*))),$(if $(wildcard $(call fix_path,$(WindowsSdkDir)Include/$(folder)/um/Windows.h)),$(folder),)))$(BACKSLASH) + WindowsSDKVersion := $(WindowsSDKVersion) + + VsInstallBuildTools = $(ProgramFiles86)/Microsoft Visual Studio/2017/BuildTools + VsInstallEnterprise = $(ProgramFiles86)/Microsoft Visual Studio/2017/Enterprise + VsInstallProfessional = $(ProgramFiles86)/Microsoft Visual Studio/2017/Professional + VsInstallCommunity = $(ProgramFiles86)/Microsoft Visual Studio/2017/Community + + VsInstallRoot ?= $(shell if [ -d "$(VsInstallBuildTools)" ]; then echo "$(VsInstallBuildTools)"; fi) + ifeq ($(VsInstallRoot), ) + VsInstallRoot = $(shell if [ -d "$(VsInstallEnterprise)" ]; then echo "$(VsInstallEnterprise)"; fi) + endif + ifeq ($(VsInstallRoot), ) + VsInstallRoot = $(shell if [ -d "$(VsInstallProfessional)" ]; then echo "$(VsInstallProfessional)"; fi) + endif + ifeq ($(VsInstallRoot), ) + VsInstallRoot = $(shell if [ -d "$(VsInstallCommunity)" ]; then echo "$(VsInstallCommunity)"; fi) + endif + VsInstallRoot := $(VsInstallRoot) + + VcCompilerToolsVer := $(shell cat "$(VsInstallRoot)/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt" | grep -o '[0-9\.]*') + VcCompilerToolsDir := $(VsInstallRoot)/VC/Tools/MSVC/$(VcCompilerToolsVer) + + WindowsSDKSharedIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\shared") + WindowsSDKUCRTIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\ucrt") + WindowsSDKUMIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\um") + WindowsSDKUCRTLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib\$(WindowsSDKVersion)\ucrt\$(TargetArchMoniker)") + WindowsSDKUMLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib\$(WindowsSDKVersion)\um\$(TargetArchMoniker)") + + # For some reason the HostX86 compiler doesn't like compiling for x64 + # ("no such file" opening a shared library), and vice-versa. + # Work around it for now by using the strictly x86 compiler for x86, and x64 for x64. + # NOTE: What about ARM? + ifneq (,$(findstring x64,$(TargetArchMoniker))) + VCCompilerToolsBinDir := $(VcCompilerToolsDir)\bin\HostX64 + else + VCCompilerToolsBinDir := $(VcCompilerToolsDir)\bin\HostX86 + endif + + PATH := $(shell IFS=$$'\n'; cygpath "$(VCCompilerToolsBinDir)/$(TargetArchMoniker)"):$(PATH) + PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VsInstallRoot)/Common7/IDE") + INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/include") + LIB := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/lib/$(TargetArchMoniker)") + ifneq (,$(findstring uwp,$(PlatformSuffix))) + LIB := $(shell IFS=$$'\n'; cygpath -w "$(LIB)/store") + endif + + export INCLUDE := $(INCLUDE);$(WindowsSDKSharedIncludeDir);$(WindowsSDKUCRTIncludeDir);$(WindowsSDKUMIncludeDir) + export LIB := $(LIB);$(WindowsSDKUCRTLibDir);$(WindowsSDKUMLibDir) + TARGET := $(TARGET_NAME)_libretro.dll + LDFLAGS += -DLL + +# Emscripten +else ifeq ($(platform), emscripten) + TARGET := $(TARGET_NAME)_libretro_$(platform).bc + STATIC_LINKING = 1 + +# Windows MSVC 2005 x86 +else ifeq ($(platform), windows_msvc2005_x86) + CC = cl.exe + CXX = cl.exe + +PATH := $(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../../VC/bin"):$(PATH) +PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../IDE") +INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VS80COMNTOOLS)../../VC/include") +LIB := $(shell IFS=$$'\n'; cygpath -w "$(VS80COMNTOOLS)../../VC/lib") +BIN := $(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../../VC/bin") + +WindowsSdkDir := $(INETSDK) + +export INCLUDE := $(INCLUDE);$(INETSDK)/Include;libretro-common/include/compat/msvc +export LIB := $(LIB);$(WindowsSdkDir);$(INETSDK)/Lib +TARGET := $(TARGET_NAME)_libretro.dll +LDFLAGS += -DLL +CFLAGS += -D_CRT_SECURE_NO_DEPRECATE +LIBS = +WINDOWS_VERSION=1 + +# Windows MSVC 2003 x86 +else ifeq ($(platform), windows_msvc2003_x86) + CC = cl.exe + CXX = cl.exe + +PATH := $(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../../Vc7/bin"):$(PATH) +PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../IDE") +INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VS71COMNTOOLS)../../Vc7/include") +LIB := $(shell IFS=$$'\n'; cygpath -w "$(VS71COMNTOOLS)../../Vc7/lib") +BIN := $(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../../Vc7/bin") + +WindowsSdkDir := $(INETSDK) + +export INCLUDE := $(INCLUDE);$(INETSDK)/Include;libretro-common/include/compat/msvc +export LIB := $(LIB);$(WindowsSdkDir);$(INETSDK)/Lib +TARGET := $(TARGET_NAME)_libretro.dll +LDFLAGS += -DLL +CFLAGS += -D_CRT_SECURE_NO_DEPRECATE +WINDOWS_VERSION=1 + +# Windows +else + TARGET := $(TARGET_NAME)_libretro.dll + CC ?= gcc + CXX ?= g++ + IS_X86 = 1 + SHARED := -shared -Wl,--no-undefined -Wl,--version-script=$(CORE_DIR)/bsnes/target-libretro/link.T + LDFLAGS += -static-libgcc -static-libstdc++ -lwinmm -lws2_32 + WINDOWS_VERSION = 1 +endif + +include Makefile.common + +ifneq (,$(findstring msvc,$(platform))) +WARNINGS := +else +WARNINGS := -Wall \ + -Wno-sign-compare \ + -Wno-unused-variable \ + -Wno-unused-function \ + -Wno-uninitialized \ + $(NEW_GCC_WARNING_FLAGS) \ + -Wno-strict-aliasing +endif + +EXTRA_GCC_FLAGS := -funroll-loops + +ifeq ($(NO_GCC),1) + EXTRA_GCC_FLAGS := + WARNINGS := +else + EXTRA_GCC_FLAGS := +endif + +OBJECTS := $(SOURCES_CXX:.cpp=.o) $(SOURCES_C:.c=.o) + +all: $(TARGET) + +ifeq ($(DEBUG),0) + FLAGS += -O3 $(EXTRA_GCC_FLAGS) +else + FLAGS += -O0 -g +endif + +LDFLAGS += $(fpic) $(SHARED) +FLAGS += $(fpic) $(NEW_GCC_FLAGS) $(INCFLAGS) + +FLAGS += $(ENDIANNESS_DEFINES) $(WARNINGS) $(CORE_DEFINE) -DSTDC_HEADERS -D__STDC_LIMIT_MACROS -D__LIBRETRO__ -DSFC_LAGFIX -DGB_INTERNAL -DDISABLE_DEBUGGER $(EXTRA_INCLUDES) $(SOUND_DEFINE) + +CXXFLAGS += -std=c++17 $(FLAGS) +CFLAGS += $(FLAGS) + +OBJOUT = -o +LINKOUT = -o + +ifneq (,$(findstring msvc,$(platform))) + OBJOUT = -Fo + LINKOUT = -out: +ifeq ($(STATIC_LINKING),1) + LD ?= lib.exe + STATIC_LINKING=0 + + ifeq ($(DEBUG), 1) + CFLAGS += -MTd + CXXFLAGS += -MTd + else + CFLAGS += -MT + CXXFLAGS += -MT + endif +else + LD = link.exe + + ifeq ($(DEBUG), 1) + CFLAGS += -MDd + CXXFLAGS += -MDd + else + CFLAGS += -MD + CXXFLAGS += -MD + endif +endif +else + LD = $(CXX) +endif + +$(TARGET): $(OBJECTS) +ifeq ($(platform), emscripten) + $(CXX) $(CXXFLAGS) $(OBJOUT)$@ $^ +else ifeq ($(STATIC_LINKING), 1) + $(AR) rcs $@ $(OBJECTS) +else + $(LD) $(LINKOUT)$@ $^ $(LDFLAGS) $(LIBS) +endif + +%.o: %.cpp + $(CXX) -c $(OBJOUT)$@ $< $(CXXFLAGS) + +%.o: %.c + $(CC) -c $(OBJOUT)$@ $< $(CFLAGS) + +clean: + rm -f $(TARGET) $(OBJECTS) + +.PHONY: clean diff --git a/Makefile.common b/Makefile.common new file mode 100644 index 00000000..6ce50a8a --- /dev/null +++ b/Makefile.common @@ -0,0 +1,56 @@ +SOURCES_CXX := +SOURCES_C := + +BSNES_DIR := $(CORE_DIR)/bsnes +GB_DIR := $(BSNES_DIR)/gb +SNES_DIR := $(BSNES_DIR)/sfc + +INCFLAGS := \ + -I$(CORE_DIR) \ + -I$(BSNES_DIR) \ + -I$(GB_DIR) \ + -I$(SNES_DIR) + +SOURCES_C += $(CORE_DIR)/libco/libco.c \ + $(GB_DIR)/Core/apu.c \ + $(GB_DIR)/Core/camera.c \ + $(GB_DIR)/Core/display.c \ + $(GB_DIR)/Core/gb.c \ + $(GB_DIR)/Core/joypad.c \ + $(GB_DIR)/Core/mbc.c \ + $(GB_DIR)/Core/memory.c \ + $(GB_DIR)/Core/printer.c \ + $(GB_DIR)/Core/random.c \ + $(GB_DIR)/Core/rewind.c \ + $(GB_DIR)/Core/save_state.c \ + $(GB_DIR)/Core/sgb.c \ + $(GB_DIR)/Core/sm83_cpu.c \ + $(GB_DIR)/Core/symbol_hash.c \ + $(GB_DIR)/Core/timing.c \ + +SOURCES_CXX += \ + $(BSNES_DIR)/target-libretro/libretro.cpp \ + $(BSNES_DIR)/emulator/emulator.cpp \ + $(BSNES_DIR)/filter/filter.cpp \ + $(BSNES_DIR)/lzma/lzma.cpp \ + $(SNES_DIR)/interface/interface.cpp \ + $(SNES_DIR)/system/system.cpp \ + $(SNES_DIR)/controller/controller.cpp \ + $(SNES_DIR)/cartridge/cartridge.cpp \ + $(SNES_DIR)/memory/memory.cpp \ + $(SNES_DIR)/cpu/cpu.cpp \ + $(SNES_DIR)/smp/smp.cpp \ + $(SNES_DIR)/dsp/dsp.cpp \ + $(SNES_DIR)/ppu/ppu.cpp \ + $(SNES_DIR)/ppu-fast/ppu.cpp \ + $(SNES_DIR)/expansion/expansion.cpp \ + $(SNES_DIR)/coprocessor/coprocessor.cpp \ + $(SNES_DIR)/slot/slot.cpp \ + $(BSNES_DIR)/processor/arm7tdmi/arm7tdmi.cpp \ + $(BSNES_DIR)/processor/spc700/spc700.cpp \ + $(BSNES_DIR)/processor/wdc65816/wdc65816.cpp + +ifneq ($(STATIC_LINKING), 1) + SOURCES_CXX += + SOURCES_C += +endif From 884b06ec31f6af789b9b09561bc6a1e8aa086335 Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 27 Dec 2020 08:11:57 -1000 Subject: [PATCH 04/21] first cut at semi-working touchscreen superscope implementation --- .../controller/super-scope/super-scope.cpp | 5 +- bsnes/target-libretro/GNUmakefile | 16 +- bsnes/target-libretro/program.cpp | 149 ++++++++++++++++++ 3 files changed, 160 insertions(+), 10 deletions(-) diff --git a/bsnes/sfc/controller/super-scope/super-scope.cpp b/bsnes/sfc/controller/super-scope/super-scope.cpp index 5b4455f5..9642880b 100644 --- a/bsnes/sfc/controller/super-scope/super-scope.cpp +++ b/bsnes/sfc/controller/super-scope/super-scope.cpp @@ -92,8 +92,9 @@ auto SuperScope::latch(bool data) -> void { auto SuperScope::latch() -> void { int nx = platform->inputPoll(port, ID::Device::SuperScope, X); int ny = platform->inputPoll(port, ID::Device::SuperScope, Y); - x = max(-16, min(256 + 16, nx + x)); - y = max(-16, min((int)ppu.vdisp() + 16, ny + y)); + printf("yoshi debug: sscope::latch x=%i, nx=%i, y=%i, ny=%i\n",x,nx,y,ny); + x = max(-16, min(256 + 16, nx)); + y = max(-16, min((int)ppu.vdisp() + 16, ny)); offscreen = (x < 0 || y < 0 || x >= 256 || y >= (int)ppu.vdisp()); if(!offscreen) ppu.latchCounters(x, y); } diff --git a/bsnes/target-libretro/GNUmakefile b/bsnes/target-libretro/GNUmakefile index 71e156d4..1e703e94 100644 --- a/bsnes/target-libretro/GNUmakefile +++ b/bsnes/target-libretro/GNUmakefile @@ -24,13 +24,13 @@ else ifeq ($(platform),windows) else ifeq ($(platform),macos) $(strip $(compiler) -o out/$(name).dylib -shared $(objects) $(options)) else ifeq ($(platform), ios-arm64) - ifeq ($(IOSSDK),) - IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path) - endif - $(strip c++ -arch arm64 -marm -miphoneos-version-min=11.0 -isysroot $(IOSSDK) -o out/$(name)_ios.dylib -shared $(objects) -lpthread -ldl) +# ifeq ($(IOSSDK),) +# IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path) +# endif + $(strip c++ -arch arm64 -marm -miphoneos-version-min=11.0 -isysroot $(shell xcodebuild -version -sdk iphoneos Path) -o out/$(name)_ios.dylib -shared $(objects) -lpthread -ldl) else ifeq ($(platform), tvos-arm64) - ifeq ($(IOSSDK),) - IOSSDK := $(shell xcodebuild -version -sdk appletvos Path) - endif - $(strip c++ -arch arm64 -marm -mtvos-version-min=11.0 -isysroot $(IOSSDK) -o out/$(name)_tvos.dylib -shared $(objects) -lpthread -ldl) +# ifeq ($(IOSSDK),) +# IOSSDK := $(shell xcodebuild -version -sdk appletvos Path) +# endif + $(strip c++ -arch arm64 -marm -mtvos-version-min=11.0 -isysroot $(shell xcodebuild -version -sdk appletvos Path) -o out/$(name)_tvos.dylib -shared $(objects) -lpthread -ldl) endif diff --git a/bsnes/target-libretro/program.cpp b/bsnes/target-libretro/program.cpp index af314de6..6370180e 100644 --- a/bsnes/target-libretro/program.cpp +++ b/bsnes/target-libretro/program.cpp @@ -18,8 +18,134 @@ using namespace nall; #include "resources.hpp" +#include "libretro.h" +#define RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 0) + static Emulator::Interface *emulator; +// Touchscreen sensitivity vars +static int pointer_pressed = 0; +static const int POINTER_PRESSED_CYCLES = 4; +static int pointer_cycles_after_released = 0; +static int pointer_pressed_last_x = 0; +static int pointer_pressed_last_y = 0; +static int superscope_last_pressed_trigger = 0; +static int superscope_last_pressed_cursor = 0; +static int superscope_last_pressed_turbo = 0; +static int superscope_last_pressed_paused = 0; + +struct retro_pointer_state +{ + int x; + int y; + bool superscope_trigger_pressed; + bool superscope_cursor_pressed; + bool superscope_turbo_pressed; + bool superscope_start_pressed; +}; + +static retro_pointer_state retro_pointer = { 0, 0, false, false, false, false }; + +static void input_update_pointer_lightgun( unsigned port, unsigned gun_device) +{ + int x, y; + x = input_state(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X); + y = input_state(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y); + + int screen_width = 256; + int screen_height = 224; + + /*scale & clamp*/ + x = ( ( x + 0x7FFF ) * screen_width ) / 0xFFFF; + if ( x < 0 ) + x = 0; + else if ( x >= screen_width ) + x = screen_width - 1; + + /*scale & clamp*/ + y = ( ( y + 0x7FFF ) * screen_height ) / 0xFFFF; + if ( y < 0 ) + y = 0; + else if ( y >= screen_height ) + y = screen_height - 1; + + // Touch sensitivity: Keep the gun position held for a fixed number of cycles after touch is released + // because a very light touch can result in a misfire + if ( pointer_cycles_after_released > 0 && pointer_cycles_after_released < POINTER_PRESSED_CYCLES ) { + pointer_cycles_after_released++; + retro_pointer.x = pointer_pressed_last_x; + retro_pointer.y = pointer_pressed_last_y; + return; + } + + if ( input_state( port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED ) ) + { + pointer_pressed = 1; + pointer_cycles_after_released = 0; + pointer_pressed_last_x = x; + pointer_pressed_last_y = y; + } else if ( pointer_pressed ) { + pointer_cycles_after_released++; + pointer_pressed = 0; + x = pointer_pressed_last_x; + y = pointer_pressed_last_y; + // unpress the primary trigger + retro_pointer.superscope_trigger_pressed = false; + return; + } + retro_pointer.x = x; + retro_pointer.y = y; + + // triggers + switch (gun_device) + { + case RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE: + { + bool start_pressed = false; + bool trigger_pressed = false; + bool turbo_pressed = false; + bool cursor_pressed = false; + if ( input_state(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) ) { + int touch_count = input_state(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT); + if ( touch_count == 4 ) { + // start button + start_pressed = true; + } else if ( touch_count == 3 ) { + turbo_pressed = true; + } else if ( touch_count == 2 ) { + // todo: handle reverse buttons setting + cursor_pressed = true; + // if ( setting_superscope_reverse_buttons ) + // { + // trigger_pressed = true; + // } else + // { + // cursor_pressed = true; + // } + } else { + // todo: handle reverse buttons setting + trigger_pressed = true; + // if ( setting_superscope_reverse_buttons ) + // { + // cursor_pressed = true; + // } else + // { + // trigger_pressed = true; + // } + } + } + retro_pointer.superscope_trigger_pressed = trigger_pressed; + retro_pointer.superscope_cursor_pressed = cursor_pressed; + retro_pointer.superscope_start_pressed = start_pressed; + retro_pointer.superscope_turbo_pressed = turbo_pressed; + break; + } + default: + break; + } +} + + struct Program : Emulator::Platform { Program(); @@ -312,6 +438,29 @@ auto pollInputDevices(uint port, uint device, uint input) -> int16 // TODO: SuperScope/Justifiers. // Do we care? The v94 port hasn't hooked them up. :) + case SuperFamicom::ID::Device::SuperScope: + { + libretro_device = RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE; + input_update_pointer_lightgun(libretro_port, libretro_device); + printf("yoshi debug: x: %i, y: %i, trig: %i, curs: %i, turbo: %i, start: %i", retro_pointer.x, retro_pointer.y, retro_pointer.superscope_trigger_pressed, retro_pointer.superscope_cursor_pressed, retro_pointer.superscope_turbo_pressed, retro_pointer.superscope_start_pressed); + switch (input) + { + case 0: // X + return retro_pointer.x; + case 1: // Y + return retro_pointer.y; + case 2: // Trigger + // todo: reverse button setting + return retro_pointer.superscope_trigger_pressed ? 1 : 0; + case 3: // Turbo + return retro_pointer.superscope_turbo_pressed ? 1 : 0; + case 4: // Pause + return retro_pointer.superscope_start_pressed ? 1 : 0; + default: + printf("Unknown input for super scope!\n"); + } + break; + } default: return 0; From 07a9ad0f36349e0a8ec2b6eec7098aaa580182d5 Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 27 Dec 2020 08:26:24 -1000 Subject: [PATCH 05/21] added config option for pointer relative mode (default is false for now) --- bsnes/sfc/controller/super-scope/super-scope.cpp | 5 +++-- bsnes/sfc/interface/configuration.cpp | 2 ++ bsnes/sfc/interface/configuration.hpp | 6 ++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bsnes/sfc/controller/super-scope/super-scope.cpp b/bsnes/sfc/controller/super-scope/super-scope.cpp index 9642880b..b3e51977 100644 --- a/bsnes/sfc/controller/super-scope/super-scope.cpp +++ b/bsnes/sfc/controller/super-scope/super-scope.cpp @@ -93,8 +93,9 @@ auto SuperScope::latch() -> void { int nx = platform->inputPoll(port, ID::Device::SuperScope, X); int ny = platform->inputPoll(port, ID::Device::SuperScope, Y); printf("yoshi debug: sscope::latch x=%i, nx=%i, y=%i, ny=%i\n",x,nx,y,ny); - x = max(-16, min(256 + 16, nx)); - y = max(-16, min((int)ppu.vdisp() + 16, ny)); + bool relativeMode = configuration.input.pointer.relative; + x = max(-16, min(256 + 16, relativeMode ? x + nx : nx )); + y = max(-16, min((int)ppu.vdisp() + 16, relativeMode ? y + ny : ny)); offscreen = (x < 0 || y < 0 || x >= 256 || y >= (int)ppu.vdisp()); if(!offscreen) ppu.latchCounters(x, y); } diff --git a/bsnes/sfc/interface/configuration.cpp b/bsnes/sfc/interface/configuration.cpp index c689ad11..1c6943c6 100644 --- a/bsnes/sfc/interface/configuration.cpp +++ b/bsnes/sfc/interface/configuration.cpp @@ -39,6 +39,8 @@ auto Configuration::process(Markup::Node document, bool load) -> void { bind(natural, "Hacks/SA1/Overclock", hacks.sa1.overclock); bind(natural, "Hacks/SuperFX/Overclock", hacks.superfx.overclock); + bind(boolean, "Input/Pointer/Relative", input.pointer.relative); + #undef bind } diff --git a/bsnes/sfc/interface/configuration.hpp b/bsnes/sfc/interface/configuration.hpp index bcf6345c..6dc48117 100644 --- a/bsnes/sfc/interface/configuration.hpp +++ b/bsnes/sfc/interface/configuration.hpp @@ -65,6 +65,12 @@ struct Configuration { } superfx; } hacks; + struct Input { + struct Pointer { + bool relative = false; + } pointer; + } input; + private: auto process(Markup::Node document, bool load) -> void; }; From cd8ec6524b9bb39437ed810b0ce6e9ce03eeebe4 Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 27 Dec 2020 08:51:15 -1000 Subject: [PATCH 06/21] fixed turbo and pause button handling; refactored to touchscreen input handling methods --- .../controller/super-scope/super-scope.cpp | 2 +- bsnes/target-libretro/program.cpp | 49 ++++++++++--------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/bsnes/sfc/controller/super-scope/super-scope.cpp b/bsnes/sfc/controller/super-scope/super-scope.cpp index b3e51977..055eb5d4 100644 --- a/bsnes/sfc/controller/super-scope/super-scope.cpp +++ b/bsnes/sfc/controller/super-scope/super-scope.cpp @@ -92,8 +92,8 @@ auto SuperScope::latch(bool data) -> void { auto SuperScope::latch() -> void { int nx = platform->inputPoll(port, ID::Device::SuperScope, X); int ny = platform->inputPoll(port, ID::Device::SuperScope, Y); - printf("yoshi debug: sscope::latch x=%i, nx=%i, y=%i, ny=%i\n",x,nx,y,ny); bool relativeMode = configuration.input.pointer.relative; + printf("yoshi debug: sscope::latch relative=%i x=%i, nx=%i, y=%i, ny=%i\n",relativeMode,x,nx,y,ny); x = max(-16, min(256 + 16, relativeMode ? x + nx : nx )); y = max(-16, min((int)ppu.vdisp() + 16, relativeMode ? y + ny : ny)); offscreen = (x < 0 || y < 0 || x >= 256 || y >= (int)ppu.vdisp()); diff --git a/bsnes/target-libretro/program.cpp b/bsnes/target-libretro/program.cpp index 6370180e..9ecfcd32 100644 --- a/bsnes/target-libretro/program.cpp +++ b/bsnes/target-libretro/program.cpp @@ -29,10 +29,6 @@ static const int POINTER_PRESSED_CYCLES = 4; static int pointer_cycles_after_released = 0; static int pointer_pressed_last_x = 0; static int pointer_pressed_last_y = 0; -static int superscope_last_pressed_trigger = 0; -static int superscope_last_pressed_cursor = 0; -static int superscope_last_pressed_turbo = 0; -static int superscope_last_pressed_paused = 0; struct retro_pointer_state { @@ -145,6 +141,30 @@ static void input_update_pointer_lightgun( unsigned port, unsigned gun_device) } } +static int input_handle_touchscreen_lightgun( unsigned port, unsigned gun_device, unsigned inputId) +{ + input_update_pointer_lightgun(port, gun_device); + printf("yoshi debug: x: %i, y: %i, trig: %i, curs: %i, turbo: %i, start: %i\n", retro_pointer.x, retro_pointer.y, retro_pointer.superscope_trigger_pressed, retro_pointer.superscope_cursor_pressed, retro_pointer.superscope_turbo_pressed, retro_pointer.superscope_start_pressed); + switch (inputId) + { + case 0: // X + return retro_pointer.x; + case 1: // Y + return retro_pointer.y; + case 2: // Trigger + // todo: reverse button setting + return retro_pointer.superscope_trigger_pressed ? 1 : 0; + case 3: // Cursor + return retro_pointer.superscope_cursor_pressed ? 1 : 0; + case 4: // Turbo + return retro_pointer.superscope_turbo_pressed ? 1 : 0; + case 5: // Pause + return retro_pointer.superscope_start_pressed ? 1 : 0; + default: + printf("Unknown input for super scope: %i \n",inputId); + return 0; + } +} struct Program : Emulator::Platform { @@ -439,28 +459,9 @@ auto pollInputDevices(uint port, uint device, uint input) -> int16 // TODO: SuperScope/Justifiers. // Do we care? The v94 port hasn't hooked them up. :) case SuperFamicom::ID::Device::SuperScope: - { libretro_device = RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE; - input_update_pointer_lightgun(libretro_port, libretro_device); - printf("yoshi debug: x: %i, y: %i, trig: %i, curs: %i, turbo: %i, start: %i", retro_pointer.x, retro_pointer.y, retro_pointer.superscope_trigger_pressed, retro_pointer.superscope_cursor_pressed, retro_pointer.superscope_turbo_pressed, retro_pointer.superscope_start_pressed); - switch (input) - { - case 0: // X - return retro_pointer.x; - case 1: // Y - return retro_pointer.y; - case 2: // Trigger - // todo: reverse button setting - return retro_pointer.superscope_trigger_pressed ? 1 : 0; - case 3: // Turbo - return retro_pointer.superscope_turbo_pressed ? 1 : 0; - case 4: // Pause - return retro_pointer.superscope_start_pressed ? 1 : 0; - default: - printf("Unknown input for super scope!\n"); - } + return input_handle_touchscreen_lightgun(libretro_port, libretro_device, input); break; - } default: return 0; From c00db1d65aad7b16d192fca1770c490cce18bdf1 Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 27 Dec 2020 15:56:12 -1000 Subject: [PATCH 07/21] support for core option for touchscreen lightgun --- .../controller/super-scope/super-scope.cpp | 1 - bsnes/target-libretro/libretro.cpp | 16 ++++++ bsnes/target-libretro/program.cpp | 53 ++++++++++--------- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/bsnes/sfc/controller/super-scope/super-scope.cpp b/bsnes/sfc/controller/super-scope/super-scope.cpp index 055eb5d4..4d0b7b1d 100644 --- a/bsnes/sfc/controller/super-scope/super-scope.cpp +++ b/bsnes/sfc/controller/super-scope/super-scope.cpp @@ -93,7 +93,6 @@ auto SuperScope::latch() -> void { int nx = platform->inputPoll(port, ID::Device::SuperScope, X); int ny = platform->inputPoll(port, ID::Device::SuperScope, Y); bool relativeMode = configuration.input.pointer.relative; - printf("yoshi debug: sscope::latch relative=%i x=%i, nx=%i, y=%i, ny=%i\n",relativeMode,x,nx,y,ny); x = max(-16, min(256 + 16, relativeMode ? x + nx : nx )); y = max(-16, min((int)ppu.vdisp() + 16, relativeMode ? y + ny : ny)); offscreen = (x < 0 || y < 0 || x >= 256 || y >= (int)ppu.vdisp()); diff --git a/bsnes/target-libretro/libretro.cpp b/bsnes/target-libretro/libretro.cpp index fcec9723..a3d3bfc6 100644 --- a/bsnes/target-libretro/libretro.cpp +++ b/bsnes/target-libretro/libretro.cpp @@ -285,6 +285,21 @@ static void flush_variables() else run_ahead_frames = atoi(variable.value); } + + variable = { "bsnes_touchscreen_lightgun", nullptr }; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &variable) && variable.value) + { + if (strcmp(variable.value, "ON") == 0) + { + emulator->configure("Input/Pointer/Relative", false); + retro_pointer_enabled = true; + } + else + { + emulator->configure("Input/Pointer/Relative", true); + retro_pointer_enabled = false; + } + } // Refresh Geometry struct retro_system_av_info avinfo; @@ -471,6 +486,7 @@ static void set_environment_info(retro_environment_t cb) { "bsnes_coprocessor_prefer_hle", "Coprocessor Prefer HLE; ON|OFF" }, { "bsnes_sgb_bios", "Preferred Super GameBoy BIOS (restart); SGB1.sfc|SGB2.sfc" }, { "bsnes_run_ahead_frames", "Amount of frames for run-ahead; OFF|1|2|3|4" }, + { "bsnes_touchscreen_lightgun", "Enable Touchscreen Lightgun; ON|OFF" }, { nullptr }, }; cb(RETRO_ENVIRONMENT_SET_VARIABLES, const_cast(vars)); diff --git a/bsnes/target-libretro/program.cpp b/bsnes/target-libretro/program.cpp index 9ecfcd32..06baa5e5 100644 --- a/bsnes/target-libretro/program.cpp +++ b/bsnes/target-libretro/program.cpp @@ -23,13 +23,8 @@ using namespace nall; static Emulator::Interface *emulator; -// Touchscreen sensitivity vars -static int pointer_pressed = 0; -static const int POINTER_PRESSED_CYCLES = 4; -static int pointer_cycles_after_released = 0; -static int pointer_pressed_last_x = 0; -static int pointer_pressed_last_y = 0; - +// Touchscreen Lightgun Support +static const int POINTER_PRESSED_CYCLES = 4; // For touchscreen sensitivity struct retro_pointer_state { int x; @@ -38,9 +33,14 @@ struct retro_pointer_state bool superscope_cursor_pressed; bool superscope_turbo_pressed; bool superscope_start_pressed; -}; + int pointer_pressed = 0; + int pointer_cycles_after_released = 0; + int pointer_pressed_last_x = 0; + int pointer_pressed_last_y = 0; +}; static retro_pointer_state retro_pointer = { 0, 0, false, false, false, false }; +static bool retro_pointer_enabled = false; static void input_update_pointer_lightgun( unsigned port, unsigned gun_device) { @@ -67,24 +67,24 @@ static void input_update_pointer_lightgun( unsigned port, unsigned gun_device) // Touch sensitivity: Keep the gun position held for a fixed number of cycles after touch is released // because a very light touch can result in a misfire - if ( pointer_cycles_after_released > 0 && pointer_cycles_after_released < POINTER_PRESSED_CYCLES ) { - pointer_cycles_after_released++; - retro_pointer.x = pointer_pressed_last_x; - retro_pointer.y = pointer_pressed_last_y; + if ( retro_pointer.pointer_cycles_after_released > 0 && retro_pointer.pointer_cycles_after_released < POINTER_PRESSED_CYCLES ) { + retro_pointer.pointer_cycles_after_released++; + retro_pointer.x = retro_pointer.pointer_pressed_last_x; + retro_pointer.y = retro_pointer.pointer_pressed_last_y; return; } if ( input_state( port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED ) ) { - pointer_pressed = 1; - pointer_cycles_after_released = 0; - pointer_pressed_last_x = x; - pointer_pressed_last_y = y; - } else if ( pointer_pressed ) { - pointer_cycles_after_released++; - pointer_pressed = 0; - x = pointer_pressed_last_x; - y = pointer_pressed_last_y; + retro_pointer.pointer_pressed = 1; + retro_pointer.pointer_cycles_after_released = 0; + retro_pointer.pointer_pressed_last_x = x; + retro_pointer.pointer_pressed_last_y = y; + } else if ( retro_pointer.pointer_pressed ) { + retro_pointer.pointer_cycles_after_released++; + retro_pointer.pointer_pressed = 0; + x = retro_pointer.pointer_pressed_last_x; + y = retro_pointer.pointer_pressed_last_y; // unpress the primary trigger retro_pointer.superscope_trigger_pressed = false; return; @@ -144,7 +144,6 @@ static void input_update_pointer_lightgun( unsigned port, unsigned gun_device) static int input_handle_touchscreen_lightgun( unsigned port, unsigned gun_device, unsigned inputId) { input_update_pointer_lightgun(port, gun_device); - printf("yoshi debug: x: %i, y: %i, trig: %i, curs: %i, turbo: %i, start: %i\n", retro_pointer.x, retro_pointer.y, retro_pointer.superscope_trigger_pressed, retro_pointer.superscope_cursor_pressed, retro_pointer.superscope_turbo_pressed, retro_pointer.superscope_start_pressed); switch (inputId) { case 0: // X @@ -161,8 +160,7 @@ static int input_handle_touchscreen_lightgun( unsigned port, unsigned gun_device case 5: // Pause return retro_pointer.superscope_start_pressed ? 1 : 0; default: - printf("Unknown input for super scope: %i \n",inputId); - return 0; + return 0; // Unknown input } } @@ -459,9 +457,14 @@ auto pollInputDevices(uint port, uint device, uint input) -> int16 // TODO: SuperScope/Justifiers. // Do we care? The v94 port hasn't hooked them up. :) case SuperFamicom::ID::Device::SuperScope: + { libretro_device = RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE; - return input_handle_touchscreen_lightgun(libretro_port, libretro_device, input); + if (retro_pointer_enabled) + { + return input_handle_touchscreen_lightgun(libretro_port, libretro_device, input); + } break; + } default: return 0; From db94af8c0444049132d396274fcf8a5137615e5b Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 27 Dec 2020 16:03:30 -1000 Subject: [PATCH 08/21] support core option of reversing super scope trigger and cursor buttons for touchscreen lightgun --- bsnes/target-libretro/libretro.cpp | 16 +++++++++++++- bsnes/target-libretro/program.cpp | 34 +++++++++++++----------------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/bsnes/target-libretro/libretro.cpp b/bsnes/target-libretro/libretro.cpp index a3d3bfc6..1686fcab 100644 --- a/bsnes/target-libretro/libretro.cpp +++ b/bsnes/target-libretro/libretro.cpp @@ -300,6 +300,19 @@ static void flush_variables() retro_pointer_enabled = false; } } + + variable = { "bsnes_touchscreen_lightgun_superscope_reverse", nullptr }; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &variable) && variable.value) + { + if (strcmp(variable.value, "ON") == 0) + { + retro_pointer_superscope_reverse_buttons = true; + } + else + { + retro_pointer_superscope_reverse_buttons = false; + } + } // Refresh Geometry struct retro_system_av_info avinfo; @@ -486,7 +499,8 @@ static void set_environment_info(retro_environment_t cb) { "bsnes_coprocessor_prefer_hle", "Coprocessor Prefer HLE; ON|OFF" }, { "bsnes_sgb_bios", "Preferred Super GameBoy BIOS (restart); SGB1.sfc|SGB2.sfc" }, { "bsnes_run_ahead_frames", "Amount of frames for run-ahead; OFF|1|2|3|4" }, - { "bsnes_touchscreen_lightgun", "Enable Touchscreen Lightgun; ON|OFF" }, + { "bsnes_touchscreen_lightgun", "Enable Touchscreen Lightgun; ON|OFF" }, + { "bsnes_touchscreen_lightgun_superscope_reverse", "Super Scope Reverse Trigger Buttons; OFF|ON" }, { nullptr }, }; cb(RETRO_ENVIRONMENT_SET_VARIABLES, const_cast(vars)); diff --git a/bsnes/target-libretro/program.cpp b/bsnes/target-libretro/program.cpp index 06baa5e5..e2a84353 100644 --- a/bsnes/target-libretro/program.cpp +++ b/bsnes/target-libretro/program.cpp @@ -41,7 +41,7 @@ struct retro_pointer_state }; static retro_pointer_state retro_pointer = { 0, 0, false, false, false, false }; static bool retro_pointer_enabled = false; - +static bool retro_pointer_superscope_reverse_buttons = false; static void input_update_pointer_lightgun( unsigned port, unsigned gun_device) { int x, y; @@ -109,25 +109,21 @@ static void input_update_pointer_lightgun( unsigned port, unsigned gun_device) } else if ( touch_count == 3 ) { turbo_pressed = true; } else if ( touch_count == 2 ) { - // todo: handle reverse buttons setting - cursor_pressed = true; - // if ( setting_superscope_reverse_buttons ) - // { - // trigger_pressed = true; - // } else - // { - // cursor_pressed = true; - // } + if ( retro_pointer_superscope_reverse_buttons ) + { + trigger_pressed = true; + } else + { + cursor_pressed = true; + } } else { - // todo: handle reverse buttons setting - trigger_pressed = true; - // if ( setting_superscope_reverse_buttons ) - // { - // cursor_pressed = true; - // } else - // { - // trigger_pressed = true; - // } + if ( retro_pointer_superscope_reverse_buttons ) + { + cursor_pressed = true; + } else + { + trigger_pressed = true; + } } } retro_pointer.superscope_trigger_pressed = trigger_pressed; From 55cade4577daf23a9a608d161afbd2df6ce86f95 Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 27 Dec 2020 16:15:26 -1000 Subject: [PATCH 09/21] fixed building for iOS/tvOS --- bsnes/target-libretro/GNUmakefile | 6 ------ 1 file changed, 6 deletions(-) diff --git a/bsnes/target-libretro/GNUmakefile b/bsnes/target-libretro/GNUmakefile index 1e703e94..c799a15d 100644 --- a/bsnes/target-libretro/GNUmakefile +++ b/bsnes/target-libretro/GNUmakefile @@ -24,13 +24,7 @@ else ifeq ($(platform),windows) else ifeq ($(platform),macos) $(strip $(compiler) -o out/$(name).dylib -shared $(objects) $(options)) else ifeq ($(platform), ios-arm64) -# ifeq ($(IOSSDK),) -# IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path) -# endif $(strip c++ -arch arm64 -marm -miphoneos-version-min=11.0 -isysroot $(shell xcodebuild -version -sdk iphoneos Path) -o out/$(name)_ios.dylib -shared $(objects) -lpthread -ldl) else ifeq ($(platform), tvos-arm64) -# ifeq ($(IOSSDK),) -# IOSSDK := $(shell xcodebuild -version -sdk appletvos Path) -# endif $(strip c++ -arch arm64 -marm -mtvos-version-min=11.0 -isysroot $(shell xcodebuild -version -sdk appletvos Path) -o out/$(name)_tvos.dylib -shared $(objects) -lpthread -ldl) endif From 1e02f2c47a03a75481533aee1d370733ae7b7a48 Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 27 Dec 2020 16:17:49 -1000 Subject: [PATCH 10/21] fix case condition for super scope to return 0 if not supported --- bsnes/target-libretro/program.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bsnes/target-libretro/program.cpp b/bsnes/target-libretro/program.cpp index e2a84353..f32c6dbd 100644 --- a/bsnes/target-libretro/program.cpp +++ b/bsnes/target-libretro/program.cpp @@ -458,8 +458,9 @@ auto pollInputDevices(uint port, uint device, uint input) -> int16 if (retro_pointer_enabled) { return input_handle_touchscreen_lightgun(libretro_port, libretro_device, input); + } else { + return 0; } - break; } default: From 66fdfbf135b9728b9d5571856b09debc5fd567d7 Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 27 Dec 2020 16:27:01 -1000 Subject: [PATCH 11/21] fix touchscreen sensitivity fix when retro_pointer_superscope_reverse_buttons enabled --- bsnes/target-libretro/program.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bsnes/target-libretro/program.cpp b/bsnes/target-libretro/program.cpp index f32c6dbd..81c3b90c 100644 --- a/bsnes/target-libretro/program.cpp +++ b/bsnes/target-libretro/program.cpp @@ -86,7 +86,10 @@ static void input_update_pointer_lightgun( unsigned port, unsigned gun_device) x = retro_pointer.pointer_pressed_last_x; y = retro_pointer.pointer_pressed_last_y; // unpress the primary trigger - retro_pointer.superscope_trigger_pressed = false; + if (retro_pointer_superscope_reverse_buttons) + retro_pointer.superscope_cursor_pressed = false; + else + retro_pointer.superscope_trigger_pressed = false; return; } retro_pointer.x = x; From 2d5b69bfb94067202867ba7f6e20c0a847fc6cee Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 27 Dec 2020 16:28:05 -1000 Subject: [PATCH 12/21] removed todo comment --- bsnes/target-libretro/program.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/bsnes/target-libretro/program.cpp b/bsnes/target-libretro/program.cpp index 81c3b90c..327ffafc 100644 --- a/bsnes/target-libretro/program.cpp +++ b/bsnes/target-libretro/program.cpp @@ -150,7 +150,6 @@ static int input_handle_touchscreen_lightgun( unsigned port, unsigned gun_device case 1: // Y return retro_pointer.y; case 2: // Trigger - // todo: reverse button setting return retro_pointer.superscope_trigger_pressed ? 1 : 0; case 3: // Cursor return retro_pointer.superscope_cursor_pressed ? 1 : 0; From a6bd1e4c57cc26e5aa1d6de7f1c117c5fd64109d Mon Sep 17 00:00:00 2001 From: Autechre Date: Mon, 11 Jan 2021 15:07:52 +0100 Subject: [PATCH 13/21] Create .gitlab-ci.yml --- .gitlab-ci.yml | 154 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..bc915af9 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,154 @@ +# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper) + +############################################################################## +################################# BOILERPLATE ################################ +############################################################################## + +# Core definitions +.core-defs: + variables: + CORENAME: bsnes + JNI_PATH: bsnes/target-libretro + MAKEFILE_PATH: bsnes + MAKEFILE: GNUmakefile + binary: library + target: libretro + +.core-defs-windows: + extends: .core-defs + after_script: + - mv ${MAKEFILE_PATH}/out/${CORENAME}_libretro.dll ${CORENAME}_libretro.dll + variables: + platform: windows + +.core-defs-linux: + extends: .core-defs + after_script: + - mv ${MAKEFILE_PATH}/out/${CORENAME}_libretro.so ${CORENAME}_libretro.so + variables: + platform: linux + +.core-defs-osx: + extends: .core-defs + after_script: + - mv ${MAKEFILE_PATH}/out/${CORENAME}_libretro.dylib ${CORENAME}_libretro.dylib + variables: + platform: macos + +# Inclusion templates, required for the build to work +include: + ################################## DESKTOPS ################################ + # Windows 64-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/windows-x64-mingw.yml' + + # Windows 32-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/windows-i686-mingw.yml' + + # Linux 64-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/linux-x64.yml' + + # Linux 32-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/linux-i686.yml' + + # MacOS 64-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/osx-x64.yml' + + ################################## CELLULAR ################################ + # Android + - project: 'libretro-infrastructure/ci-templates' + file: '/android-jni.yml' + + ################################## CONSOLES ################################ + # Nintendo Switch + - project: 'libretro-infrastructure/ci-templates' + file: '/libnx-static.yml' + +# Stages for building +stages: + - build-prepare + - build-shared + - build-static + +############################################################################## +#################################### STAGES ################################## +############################################################################## +# +################################### DESKTOPS ################################# +# Windows 64-bit +libretro-build-windows-x64: + extends: + - .libretro-windows-x64-mingw-make-default + - .core-defs-windows + variables: + compiler: x86_64-w64-mingw32.static-g++ + +# Windows 32-bit +libretro-build-windows-i686: + extends: + - .libretro-windows-i686-mingw-make-default + - .core-defs-windows + variables: + compiler: i686-w64-mingw32.static-g++ + +# Linux 64-bit +libretro-build-linux-x64: + extends: + - .libretro-linux-x64-make-default + - .core-defs-linux + +# Linux 32-bit +libretro-build-linux-i686: + extends: + - .libretro-linux-i686-make-default + - .core-defs-linux + +# MacOS 64-bit +libretro-build-osx-x64: + extends: + - .libretro-osx-x64-make-default + - .core-defs-osx + +################################### CELLULAR ################################# +# Android ARMv7a +android-armeabi-v7a: + extends: + - .libretro-android-jni-armeabi-v7a + - .core-defs + +# Android ARMv8a +android-arm64-v8a: + extends: + - .libretro-android-jni-arm64-v8a + - .core-defs + +# Android 64-bit x86 +android-x86_64: + extends: + - .libretro-android-jni-x86_64 + - .core-defs + +# Android 32-bit x86 +android-x86: + extends: + - .libretro-android-jni-x86 + - .core-defs + +################################### CONSOLES ################################# +# Nintendo Switch +libretro-build-libnx-aarch64: + extends: + - .libretro-libnx-static-retroarch-master + - .core-defs + script: + - make -C ${MAKEFILE_PATH} -f ${MAKEFILE} -j$NUMPROC platform=libnx + - mv ${MAKEFILE_PATH}/out/${CORENAME}_libretro_libnx.a retroarch-precompiled/libretro_libnx.a + - cd retroarch-precompiled/ + - make -f Makefile.libnx -j10 + - mv retroarch_switch.nro ../${CORENAME}_libretro_libnx.nro + - mv retroarch_switch.elf ../${CORENAME}_libretro_libnx.elf + - cd ../ From f2e02df9d5fec13880e39025c178c9413c1d5426 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 11 Jan 2021 14:45:17 +0000 Subject: [PATCH 14/21] Fix gitlab builds --- bsnes/GNUmakefile | 4 ++-- nall/GNUmakefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bsnes/GNUmakefile b/bsnes/GNUmakefile index 9450f39c..8cf89980 100644 --- a/bsnes/GNUmakefile +++ b/bsnes/GNUmakefile @@ -1,5 +1,5 @@ -target := bsnes -binary := application +target ?= bsnes +binary ?= application build := performance openmp := true local := true diff --git a/nall/GNUmakefile b/nall/GNUmakefile index c3473391..77d1b818 100755 --- a/nall/GNUmakefile +++ b/nall/GNUmakefile @@ -116,7 +116,7 @@ ifeq ($(platform),windows) options += -mthreads -lpthread -lws2_32 -lole32 options += $(if $(findstring g++,$(compiler)),-static -static-libgcc -static-libstdc++) options += $(if $(findstring true,$(console)),-mconsole,-mwindows) - windres := windres + windres ?= windres endif # macos settings From 96c88b1b78ea57e4f5d5093d30b2003f2a684a68 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 11 Jan 2021 14:59:45 +0000 Subject: [PATCH 15/21] Fix LIBNX build --- bsnes/emulator/emulator.hpp | 2 ++ bsnes/target-libretro/GNUmakefile | 7 ++++++ libco/settings.h | 9 +++++++ nall/GNUmakefile | 13 +++++++++++ nall/file-map.hpp | 4 ++++ nall/horizon/mman.hpp | 39 +++++++++++++++++++++++++++++++ nall/intrinsics.hpp | 11 +++++++-- nall/nall.hpp | 2 ++ nall/platform.hpp | 2 ++ nall/service.hpp | 5 ++-- nall/shared-memory.hpp | 5 ++-- 11 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 nall/horizon/mman.hpp diff --git a/bsnes/emulator/emulator.hpp b/bsnes/emulator/emulator.hpp index cb172969..db430f48 100644 --- a/bsnes/emulator/emulator.hpp +++ b/bsnes/emulator/emulator.hpp @@ -6,7 +6,9 @@ #include #include #include +#ifndef PLATFORM_HORIZON #include +#endif // PLATFORM_HORIZON #include #include #include diff --git a/bsnes/target-libretro/GNUmakefile b/bsnes/target-libretro/GNUmakefile index c799a15d..edbc831d 100644 --- a/bsnes/target-libretro/GNUmakefile +++ b/bsnes/target-libretro/GNUmakefile @@ -9,6 +9,11 @@ ifeq ($(platform), ios-arm64) else ifeq ($(platform), tvos-arm64) flags += -fPIC -mtvos-version-min=11.0 -Wno-error=implicit-function-declaration -DHAVE_POSIX_MEMALIGN options += -dynamiclib +else ifeq ($(platform), libnx) + flags += -march=armv8-a+crc -mtune=cortex-a57 -mtp=soft -mcpu=cortex-a57+crc+fp+simd -DHAVE_POSIX_MEMALIGN + flags += -O2 -ftree-vectorize -ffast-math -funsafe-math-optimizations -fPIE -I$(PORTLIBS)/include/ -I$(LIBNX)/include/ -ffunction-sections -fdata-sections -ftls-model=local-exec + flags += -D__SWITCH__=1 -D__aarch64__=1 -DSWITCH -DHAVE_LIBNX + name := bsnes_libretro_libnx endif objects := libretro $(objects) @@ -21,6 +26,8 @@ ifeq ($(platform),linux) $(strip $(compiler) -o out/$(name).so -shared $(objects) -Wl,--no-undefined -Wl,--version-script=target-libretro/link.T -lgomp -Wl,-Bdynamic $(options)) else ifeq ($(platform),windows) $(strip $(compiler) -o out/$(name).dll -shared $(objects) -Wl,--no-undefined -Wl,--version-script=target-libretro/link.T -lgomp -Wl,-Bdynamic $(options)) +else ifeq ($(platform),libnx) + $(strip $(AR) rcs out/$(name).a $(objects)) else ifeq ($(platform),macos) $(strip $(compiler) -o out/$(name).dylib -shared $(objects) $(options)) else ifeq ($(platform), ios-arm64) diff --git a/libco/settings.h b/libco/settings.h index d8037bc4..dbf7994d 100644 --- a/libco/settings.h +++ b/libco/settings.h @@ -30,6 +30,15 @@ #define section(name) __declspec(allocate("." #name)) #elif defined(__APPLE__) #define section(name) __attribute__((section("__TEXT,__" #name))) +#elif defined(__SWITCH__) + /* + This is basically the same as the last case, however the "#" suffix will create a secondary .text section. + Because of that, the toolchain will treat the section as non-executable. This might be related to the linker scripts + used for libnx homebrew. The reason that this is a seperate ifdef, is purely to silence a cosmetic warn + about ignoring the +w attribute on .text which would happen on other platforms under some conditions (said warning is by design + when data is being merged like this into .text). + */ + #define section(name) __attribute__((section("." #name))) #else #define section(name) __attribute__((section("." #name "#"))) #endif diff --git a/nall/GNUmakefile b/nall/GNUmakefile index 77d1b818..bbe963d7 100755 --- a/nall/GNUmakefile +++ b/nall/GNUmakefile @@ -68,6 +68,14 @@ ifeq ($(compiler),) compiler := clang++ else ifeq ($(platform),linux) compiler := g++ + else ifeq ($(platform),libnx) + include $(DEVKITPRO)/libnx/switch_rules + PORTLIBS := $(PORTLIBS_PATH)/switch + PATH := $(PORTLIBS)/bin:$(PATH) + LIBNX ?= $(DEVKITPRO)/libnx + compiler = $(CC) -std=gnu11 + compiler.cpp = $(CXX) -std=gnu++17 + openmp = false else ifeq ($(platform),bsd) compiler := g++8 else @@ -130,6 +138,11 @@ ifeq ($(platform),linux) options += -ldl endif +# libnx settings +ifeq ($(platform),libnx) + flags += -D__SWITCH__=1 -DSWITCH -DHAVE_LIBNX +endif + # bsd settings ifeq ($(platform),bsd) flags += -I/usr/local/include diff --git a/nall/file-map.hpp b/nall/file-map.hpp index 647a823b..3068a76b 100755 --- a/nall/file-map.hpp +++ b/nall/file-map.hpp @@ -10,7 +10,11 @@ #else #include #include +#if defined(PLATFORM_HORIZON) + #include +#else #include +#endif // PLATFORM_HORIZON #include #include #endif diff --git a/nall/horizon/mman.hpp b/nall/horizon/mman.hpp new file mode 100644 index 00000000..aa74f6e5 --- /dev/null +++ b/nall/horizon/mman.hpp @@ -0,0 +1,39 @@ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +// Workaround since we don't support file mappings on Horizon, but this is currently not functional. +// To make it work, the file could be read when the file_map is opened +#define PROT_READ 0b001 +#define PROT_WRITE 0b010 +#define PROT_EXEC 0b100 +#define MAP_PRIVATE 2 +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_FAILED ((void *)-1) +#define MAP_SHARED 0 + +static inline void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) +{ + return malloc(len); +} + +static inline int mprotect(void *addr, size_t len, int prot) +{ + return 0; +} + +static inline int munmap(void *addr, size_t len) +{ + free(addr); + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/nall/intrinsics.hpp b/nall/intrinsics.hpp index 01fdec40..ad132dbc 100755 --- a/nall/intrinsics.hpp +++ b/nall/intrinsics.hpp @@ -4,7 +4,7 @@ namespace nall { using uint = unsigned; enum class Compiler : uint { Clang, GCC, Microsoft, Unknown }; - enum class Platform : uint { Windows, MacOS, Linux, BSD, Android, Unknown }; + enum class Platform : uint { Windows, MacOS, Linux, BSD, Android, Horizon, Unknown }; enum class API : uint { Windows, Posix, Unknown }; enum class DisplayServer : uint { Windows, Quartz, Xorg, Unknown }; enum class Architecture : uint { x86, amd64, ARM32, ARM64, PPC32, PPC64, Unknown }; @@ -91,6 +91,13 @@ namespace nall { constexpr auto platform() -> Platform { return Platform::Android; } constexpr auto api() -> API { return API::Posix; } constexpr auto display() -> DisplayServer { return DisplayServer::Unknown; } +#elif defined(__SWITCH__) + #define PLATFORM_HORIZON + #define API_POSIX + #define DISPLAY_UNKNOWN + constexpr auto platform() -> Platform { return Platform::Horizon; } + constexpr auto api() -> API { return API::Posix; } + constexpr auto display() -> DisplayServer { return DisplayServer::Unknown; } #elif defined(linux) || defined(__linux__) #define PLATFORM_LINUX #define API_POSIX @@ -159,7 +166,7 @@ namespace nall { namespace nall { -#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(__i386__) || defined(__amd64__) || defined(_M_IX86) || defined(_M_AMD64) +#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(__i386__) || defined(__amd64__) || defined(_M_IX86) || defined(_M_AMD64) || defined(__aarch64__) #define ENDIAN_LSB constexpr auto endian() -> Endian { return Endian::LSB; } #elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(__powerpc__) || defined(_M_PPC) diff --git a/nall/nall.hpp b/nall/nall.hpp index ec04866e..98f1b7eb 100755 --- a/nall/nall.hpp +++ b/nall/nall.hpp @@ -24,7 +24,9 @@ #include #include #include +#if !defined(PLATFORM_HORIZON) #include +#endif // PLATFORM_HORIZON #include #include #include diff --git a/nall/platform.hpp b/nall/platform.hpp index bf8711c6..c4f9479e 100755 --- a/nall/platform.hpp +++ b/nall/platform.hpp @@ -45,7 +45,9 @@ namespace Math { #include #if !defined(PLATFORM_WINDOWS) +#if !defined(PLATFORM_HORIZON) #include +#endif // PLATFORM_HORIZON #include #include #include diff --git a/nall/service.hpp b/nall/service.hpp index 3d3c9024..2ba63888 100755 --- a/nall/service.hpp +++ b/nall/service.hpp @@ -4,10 +4,11 @@ #include -#if defined(API_POSIX) +#if defined(API_POSIX) && !defined(PLATFORM_HORIZON) #include #endif -#if defined(API_WINDOWS) +// For Horizon we re-use the Windows stub +#if defined(API_WINDOWS) || defined(PLATFORM_HORIZON) #include #endif diff --git a/nall/shared-memory.hpp b/nall/shared-memory.hpp index 9d40bca6..e768dc94 100755 --- a/nall/shared-memory.hpp +++ b/nall/shared-memory.hpp @@ -3,10 +3,11 @@ #include #include -#if defined(API_POSIX) +#if defined(API_POSIX) && !defined(PLATFORM_HORIZON) #include #endif -#if defined(API_WINDOWS) +// For Horizon we re-use the Windows stub +#if defined(API_WINDOWS) || defined(PLATFORM_HORIZON) #include #endif From f8fde2cd7c1f671c92c912d593d7b32f65b7e315 Mon Sep 17 00:00:00 2001 From: ds22x <45218067+ds22x@users.noreply.github.com> Date: Fri, 29 Jan 2021 01:43:16 +0100 Subject: [PATCH 16/21] Add files via upload This change allows for a SGB boot rom with the same name as a SGB rom to be loaded from the same folder, which allows for MSU-1 enhanced SGB games to work without having to rely on the subsystem menu. If it fails to load a SGB boot rom from the same folder, it will first revert to the already implemented method of loading the boot rom from the system directory and etc. --- bsnes/target-libretro/libretro.cpp | 35 +++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/bsnes/target-libretro/libretro.cpp b/bsnes/target-libretro/libretro.cpp index 1686fcab..3c877f5d 100644 --- a/bsnes/target-libretro/libretro.cpp +++ b/bsnes/target-libretro/libretro.cpp @@ -681,17 +681,42 @@ RETRO_API bool retro_load_game(const retro_game_info *game) flush_variables(); - if (string(game->path).endsWith(".gb") || string(game->path).endsWith(".gbc")) + if (string(game->path).endsWith(".gb")) { const char *system_dir; environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir); - string sgb_full_path = string(system_dir, "/", sgb_bios).transform("\\", "/"); - if (!file::exists(sgb_full_path)) { + string sgb_full_path = string(game->path).transform("\\", "/"); + string sgb_full_path2 = string(sgb_full_path).replace(".gb", ".sfc"); + if (!file::exists(sgb_full_path2)) { + string sgb_full_path = string(system_dir, "/", sgb_bios).transform("\\", "/"); + program->superFamicom.location = sgb_full_path; + } + else { + program->superFamicom.location = sgb_full_path2; + } + program->gameBoy.location = string(game->path); + if (!file::exists(program->superFamicom.location)) { + return false; + } + } + else if (string(game->path).endsWith(".gbc")) + { + const char *system_dir; + environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir); + string sgb_full_path = string(game->path).transform("\\", "/"); + string sgb_full_path2 = string(sgb_full_path).replace(".gbc", ".sfc"); + if (!file::exists(sgb_full_path2)) { + string sgb_full_path = string(system_dir, "/", sgb_bios).transform("\\", "/"); + program->superFamicom.location = sgb_full_path; + } + else { + program->superFamicom.location = sgb_full_path2; + } + program->gameBoy.location = string(game->path); + if (!file::exists(program->superFamicom.location)) { return false; } - program->superFamicom.location = sgb_full_path; - program->gameBoy.location = string(game->path); } else { From e568913840b03a539c70c9a53c20195b281db170 Mon Sep 17 00:00:00 2001 From: ds22x <45218067+ds22x@users.noreply.github.com> Date: Sat, 30 Jan 2021 15:23:37 +0100 Subject: [PATCH 17/21] Backport https://github.com/bsnes-emu/bsnes/commit/d0efbfbcd937142969b47d65a04ffe4f5a77b50d Also added a direct way of loading .bs games by using BS-X.bin in the system directory as a firmware file. --- bsnes/target-libretro/libretro.cpp | 62 ++++++++++++++++++++++-------- bsnes/target-libretro/program.cpp | 59 ++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 15 deletions(-) diff --git a/bsnes/target-libretro/libretro.cpp b/bsnes/target-libretro/libretro.cpp index 3c877f5d..0f5ac53c 100644 --- a/bsnes/target-libretro/libretro.cpp +++ b/bsnes/target-libretro/libretro.cpp @@ -41,8 +41,10 @@ static int aspect_ratio_mode = 0; #define RETRO_DEVICE_LIGHTGUN_JUSTIFIERS RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 2) #define RETRO_GAME_TYPE_SGB 0x101 | 0x1000 +#define RETRO_GAME_TYPE_BSX 0x110 | 0x1000 #define RETRO_MEMORY_SGB_SRAM ((1 << 8) | RETRO_MEMORY_SAVE_RAM) #define RETRO_MEMORY_GB_SRAM ((2 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_BSX_SRAM ((3 << 8) | RETRO_MEMORY_SAVE_RAM) static double get_aspect_ratio() { @@ -361,23 +363,33 @@ static void set_controller_ports(unsigned port, unsigned device) static void set_environment_info(retro_environment_t cb) { - static const struct retro_subsystem_memory_info sgb_memory[] = { - { "srm", RETRO_MEMORY_SGB_SRAM }, - }; + static const struct retro_subsystem_memory_info sgb_memory[] = { + { "srm", RETRO_MEMORY_SGB_SRAM }, + }; - static const struct retro_subsystem_memory_info gb_memory[] = { - { "srm", RETRO_MEMORY_GB_SRAM }, - }; + static const struct retro_subsystem_memory_info gb_memory[] = { + { "srm", RETRO_MEMORY_GB_SRAM }, + }; - static const struct retro_subsystem_rom_info sgb_roms[] = { - { "Game Boy ROM", "gb|gbc", true, false, true, gb_memory, 1 }, - { "Super Game Boy ROM", "smc|sfc|swc|fig|bs", true, false, true, sgb_memory, 1 }, - }; + static const struct retro_subsystem_memory_info bsx_memory[] = { + { "srm", RETRO_MEMORY_BSX_SRAM }, + }; - static const struct retro_subsystem_info subsystems[] = { - { "Super Game Boy", "sgb", sgb_roms, 2, RETRO_GAME_TYPE_SGB }, - {} - }; + static const struct retro_subsystem_rom_info sgb_roms[] = { + { "Game Boy ROM", "gb|gbc", true, false, true, gb_memory, 1 }, + { "Super Game Boy ROM", "smc|sfc|swc|fig", true, false, true, sgb_memory, 1 }, + }; + + static const struct retro_subsystem_rom_info bsx_roms[] = { + { "BS-X ROM", "bs", true, false, true, bsx_memory, 1 }, + { "BS-X BIOS ROM", "smc|sfc|swc|fig", true, false, true, bsx_memory, 1 }, + }; + + static const struct retro_subsystem_info subsystems[] = { + { "Super Game Boy", "sgb", sgb_roms, 2, RETRO_GAME_TYPE_SGB }, + { "BS-X Satellaview", "bsx", bsx_roms, 2, RETRO_GAME_TYPE_BSX }, + {} + }; cb(RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO, (void*)subsystems); @@ -563,7 +575,7 @@ RETRO_API void retro_get_system_info(retro_system_info *info) info->library_name = "bsnes"; info->library_version = Emulator::Version; info->need_fullpath = true; - info->valid_extensions = "smc|sfc|gb|gbc"; + info->valid_extensions = "smc|sfc|gb|gbc|bs"; info->block_extract = false; } @@ -718,6 +730,18 @@ RETRO_API bool retro_load_game(const retro_game_info *game) } } + else if (string(game->path).endsWith(".bs")) + { + const char *system_dir; + environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir); + string bs_full_path = string(system_dir, "/", "BS-X.bin").transform("\\", "/"); + if (!file::exists(bs_full_path)) { + return false; + } + + program->superFamicom.location = bs_full_path; + program->bsMemory.location = string(game->path); + } else { program->superFamicom.location = string(game->path); @@ -748,6 +772,14 @@ RETRO_API bool retro_load_game_special(unsigned game_type, program->superFamicom.location = info[1].path; } break; + case RETRO_GAME_TYPE_BSX: + { + libretro_print(RETRO_LOG_INFO, "BS-X ROM: %s\n", info[0].path); + libretro_print(RETRO_LOG_INFO, "BS-X BIOS ROM: %s\n", info[1].path); + program->bsMemory.location = info[0].path; + program->superFamicom.location = info[1].path; + } + break; default: return false; } diff --git a/bsnes/target-libretro/program.cpp b/bsnes/target-libretro/program.cpp index 327ffafc..26ae2ad7 100644 --- a/bsnes/target-libretro/program.cpp +++ b/bsnes/target-libretro/program.cpp @@ -15,6 +15,7 @@ using namespace nall; #include #include #include +#include #include "resources.hpp" @@ -178,11 +179,13 @@ struct Program : Emulator::Platform auto loadFile(string location) -> vector; auto loadSuperFamicom(string location) -> bool; auto loadGameBoy(string location) -> bool; + auto loadBSMemory(string location) -> bool; auto save() -> void; auto openRomSuperFamicom(string name, vfs::file::mode mode) -> shared_pointer; auto openRomGameBoy(string name, vfs::file::mode mode) -> shared_pointer; + auto openRomBSMemory(string name, vfs::file::mode mode) -> shared_pointer; auto hackPatchMemory(vector& data) -> void; @@ -214,6 +217,10 @@ public: struct GameBoy : Game { vector program; } gameBoy; + + struct BSMemory : Game { + vector program; + } bsMemory; }; static Program *program = nullptr; @@ -274,6 +281,21 @@ auto Program::open(uint id, string name, vfs::file::mode mode, bool required) -> result = openRomGameBoy(name, mode); } } + else if (id == 3) { //BS Memory + if (name == "manifest.bml" && mode == vfs::file::mode::read) { + result = vfs::memory::file::open(bsMemory.manifest.data(), bsMemory.manifest.size()); + } + else if (name == "program.rom" && mode == vfs::file::mode::read) { + result = vfs::memory::file::open(bsMemory.program.data(), bsMemory.program.size()); + } + else if(name == "program.flash") { + //writes are not flushed to disk in bsnes + result = vfs::memory::file::open(bsMemory.program.data(), bsMemory.program.size()); + } + else { + result = openRomBSMemory(name, mode); + } + } return result; } @@ -359,6 +381,11 @@ auto Program::load(uint id, string name, string type, vector options) -> return { id, NULL }; } } + else if (id == 3) { + if (loadBSMemory(bsMemory.location)) { + return { id, NULL }; + } + } return { id, options(0) }; } @@ -569,6 +596,21 @@ auto Program::openRomGameBoy(string name, vfs::file::mode mode) -> shared_pointe return {}; } +auto Program::openRomBSMemory(string name, vfs::file::mode mode) -> shared_pointer { + if (name == "program.rom" && mode == vfs::file::mode::read) + { + return vfs::memory::file::open(bsMemory.program.data(), bsMemory.program.size()); + } + + if (name == "program.flash") + { + //writes are not flushed to disk + return vfs::memory::file::open(bsMemory.program.data(), bsMemory.program.size()); + } + + return {}; +} + auto Program::loadFile(string location) -> vector { if(Location::suffix(location).downcase() == ".zip") { @@ -658,6 +700,23 @@ auto Program::loadGameBoy(string location) -> bool { return true; } +auto Program::loadBSMemory(string location) -> bool { + vector rom; + rom = loadFile(location); + + if (rom.size() < 0x8000) return false; + + auto heuristics = Heuristics::BSMemory(rom, location); + auto sha256 = Hash::SHA256(rom).digest(); + + bsMemory.manifest = heuristics.manifest(); + bsMemory.document = BML::unserialize(bsMemory.manifest); + bsMemory.location = location; + + bsMemory.program = rom; + return true; +} + auto Program::hackPatchMemory(vector& data) -> void { auto title = superFamicom.title; From 349913cc7767835236abea58c56f24e16e1e333e Mon Sep 17 00:00:00 2001 From: ds22x <45218067+ds22x@users.noreply.github.com> Date: Wed, 3 Feb 2021 00:32:43 +0100 Subject: [PATCH 18/21] Allow Satellaview games smaller than 1024kb to work Also prevents them from crashing bsnes when unloading them. --- bsnes/heuristics/bs-memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsnes/heuristics/bs-memory.cpp b/bsnes/heuristics/bs-memory.cpp index ffb255c5..df2e5d16 100644 --- a/bsnes/heuristics/bs-memory.cpp +++ b/bsnes/heuristics/bs-memory.cpp @@ -26,7 +26,7 @@ auto BSMemory::manifest() const -> string { output.append(" label: ", Location::prefix(location), "\n"); output.append(" name: ", Location::prefix(location), "\n"); output.append(" board\n"); - output.append(Memory{}.type("Flash").size(data.size()).content("Program").text()); + output.append(Memory{}.type("Flash").size(0x100000()).content("Program").text()); return output; } From 0735908d9a45b3e8334bdf65f58b2c190cb8cd73 Mon Sep 17 00:00:00 2001 From: ds22x <45218067+ds22x@users.noreply.github.com> Date: Wed, 3 Feb 2021 02:11:27 +0100 Subject: [PATCH 19/21] Fixed a small typo --- bsnes/heuristics/bs-memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsnes/heuristics/bs-memory.cpp b/bsnes/heuristics/bs-memory.cpp index df2e5d16..49cb8748 100644 --- a/bsnes/heuristics/bs-memory.cpp +++ b/bsnes/heuristics/bs-memory.cpp @@ -26,7 +26,7 @@ auto BSMemory::manifest() const -> string { output.append(" label: ", Location::prefix(location), "\n"); output.append(" name: ", Location::prefix(location), "\n"); output.append(" board\n"); - output.append(Memory{}.type("Flash").size(0x100000()).content("Program").text()); + output.append(Memory{}.type("Flash").size(0x100000).content("Program").text()); return output; } From 9ef05f2b8ee9592a341ee1de867c79e7cf42027d Mon Sep 17 00:00:00 2001 From: ds22x <45218067+ds22x@users.noreply.github.com> Date: Mon, 8 Feb 2021 16:02:53 +0100 Subject: [PATCH 20/21] Simplify SGB path code With thanks to Screwtapello for the suggestion. --- bsnes/target-libretro/libretro.cpp | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/bsnes/target-libretro/libretro.cpp b/bsnes/target-libretro/libretro.cpp index 0f5ac53c..80108162 100644 --- a/bsnes/target-libretro/libretro.cpp +++ b/bsnes/target-libretro/libretro.cpp @@ -693,12 +693,12 @@ RETRO_API bool retro_load_game(const retro_game_info *game) flush_variables(); - if (string(game->path).endsWith(".gb")) + if (string(game->path).endsWith(".gb") || string(game->path).endsWith(".gbc")) { const char *system_dir; environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir); string sgb_full_path = string(game->path).transform("\\", "/"); - string sgb_full_path2 = string(sgb_full_path).replace(".gb", ".sfc"); + string sgb_full_path2 = string(sgb_full_path).replace(".gbc", ".sfc").replace(".gb", ".sfc"); if (!file::exists(sgb_full_path2)) { string sgb_full_path = string(system_dir, "/", sgb_bios).transform("\\", "/"); program->superFamicom.location = sgb_full_path; @@ -711,25 +711,6 @@ RETRO_API bool retro_load_game(const retro_game_info *game) return false; } } - else if (string(game->path).endsWith(".gbc")) - { - const char *system_dir; - environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir); - string sgb_full_path = string(game->path).transform("\\", "/"); - string sgb_full_path2 = string(sgb_full_path).replace(".gbc", ".sfc"); - if (!file::exists(sgb_full_path2)) { - string sgb_full_path = string(system_dir, "/", sgb_bios).transform("\\", "/"); - program->superFamicom.location = sgb_full_path; - } - else { - program->superFamicom.location = sgb_full_path2; - } - program->gameBoy.location = string(game->path); - if (!file::exists(program->superFamicom.location)) { - return false; - } - - } else if (string(game->path).endsWith(".bs")) { const char *system_dir; From b747a52b4b7c83218b8cc71dd4ae4f72d3f5f172 Mon Sep 17 00:00:00 2001 From: ds22x <45218067+ds22x@users.noreply.github.com> Date: Mon, 8 Feb 2021 16:40:11 +0100 Subject: [PATCH 21/21] Remove flashing bottom line when playing SGB games --- bsnes/target-libretro/program.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bsnes/target-libretro/program.cpp b/bsnes/target-libretro/program.cpp index 26ae2ad7..81b9b660 100644 --- a/bsnes/target-libretro/program.cpp +++ b/bsnes/target-libretro/program.cpp @@ -394,7 +394,14 @@ auto Program::videoFrame(const uint16* data, uint pitch, uint width, uint height { uint multiplier = height / 240; data += 8 * (pitch >> 1) * multiplier; - height -= 16 * multiplier; + if (program->gameBoy.program) + { + height -= 16.1 * multiplier; + } + else + { + height -= 16 * multiplier; + } } video_cb(data, width, height, pitch); }