From 2fb7ba22e50229a1ac8f0e4bd0c4fb6d158e09b8 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 7 Mar 2020 21:27:38 +0100 Subject: [PATCH 01/14] PSL1GHT port Working: * packaging * running cores * switching cores * gamepad including axis * rgui * audio * video Not working: * OSD * menus other than rgui * shaders * Graphical acceleration * Proper signing * ODE build * rumble * keyboard * mouse Not tested: * A lot --- Makefile.psl1ght | 96 +-- Makefile.psl1ght.salamander | 119 +++ defines/ps3_defines.h | 9 +- dist-scripts/dist-cores.sh | 47 +- frontend/drivers/platform_ps3.c | 188 +++-- gfx/drivers/gcm_gfx.c | 692 ++++++++++++++++++ gfx/drivers_context/ps3_ctx.c | 2 - griffin/griffin.c | 10 +- input/drivers/ps3_input.c | 2 - input/drivers/psl1ght_input.c | 407 ++++++++++ input/drivers_joypad/ps3_joypad.c | 19 - libretro-common/features/features_cpu.c | 10 +- libretro-common/file/file_path.c | 2 +- libretro-common/file/file_path_io.c | 2 +- libretro-common/include/retro_miscellaneous.h | 4 +- libretro-common/vfs/vfs_implementation.c | 20 +- menu/menu_setting.c | 2 +- pkg/psl1ght/pkg/ICON0.PNG | Bin 0 -> 20179 bytes pkg/psl1ght/pkg/PARAM.SFO | Bin 0 -> 1040 bytes pkg/psl1ght/pkg/USRDIR/.empty | 0 pkg/psl1ght/pkg/USRDIR/cores/.empty | 0 pkg/psl1ght/pkg/USRDIR/cores/presets/.empty | 0 .../pkg/USRDIR/cores/savestates/.empty | 0 pkg/psl1ght/pkg/USRDIR/cores/sram/.empty | 0 pkg/psl1ght/pkg/USRDIR/cores/system/.empty | 0 retroarch.c | 5 +- retroarch.h | 1 + 27 files changed, 1450 insertions(+), 187 deletions(-) create mode 100644 Makefile.psl1ght.salamander create mode 100644 gfx/drivers/gcm_gfx.c create mode 100644 input/drivers/psl1ght_input.c create mode 100644 pkg/psl1ght/pkg/ICON0.PNG create mode 100644 pkg/psl1ght/pkg/PARAM.SFO create mode 100644 pkg/psl1ght/pkg/USRDIR/.empty create mode 100644 pkg/psl1ght/pkg/USRDIR/cores/.empty create mode 100644 pkg/psl1ght/pkg/USRDIR/cores/presets/.empty create mode 100644 pkg/psl1ght/pkg/USRDIR/cores/savestates/.empty create mode 100644 pkg/psl1ght/pkg/USRDIR/cores/sram/.empty create mode 100644 pkg/psl1ght/pkg/USRDIR/cores/system/.empty diff --git a/Makefile.psl1ght b/Makefile.psl1ght index 907d1cbe7c..9ac19921bc 100644 --- a/Makefile.psl1ght +++ b/Makefile.psl1ght @@ -1,29 +1,39 @@ +#------------------------------------------------------------------------------- +# Clear the implicit built in rules +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- +ifeq ($(strip $(PSL1GHT)),) +$(error "Please set PSL1GHT in your environment. export PSL1GHT=") +endif + +include $(PSL1GHT)/ppu_rules + include version.all DEBUG = 0 HAVE_LOGGER = 0 -HAVE_FILE_LOGGER = 0 +HAVE_FILE_LOGGER = 1 PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7" PC_DEVELOPMENT_UDP_PORT = 3490 -CC = $(PS3DEV)/ppu/bin/ppu-gcc -CXX = $(PS3DEV)/ppu/bin/ppu-g++ -LD = $(PS3DEV)/ppu/bin/ppu-ld - -CONTENT_ID_FULL = UP0001-SSNE10000_00-0000000000000001 +CONTENTID = UP0001-SSNE10001_00-0000000000000001 +APPID = SSNE10001 +TITLE = Retroarch PSL1GHT +PACKAGE_BASENAME := retroarch_psl1ght ELF_TARGET := retroarch_psl1ght.elf -EBOOT_PATH = pkg/ps3/USRDIR/EBOOT.BIN -CORE_PATH = pkg/ps3/USRDIR/cores/CORE.SELF +SELF_TARGET := $(ELF_TARGET:.elf=.self) +CORE_PATH = pkg/psl1ght/pkg/USRDIR/cores/CORE.SELF -INCLUDE := -I. -I$(PS3DEV)/ppu/include -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib -LIBDIRS := -L$(PS3DEV)/ppu/lib -L$(PS3DEV)/portlibs/ppu/lib -L. +INCLUDE += -I. -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib -Ilibretro-common/include $(LIBPSL1GHT_INC) -Iinclude +LIBDIRS += -L. -MACHDEP := -D__CELLOS_LV2__ -D__PSL1GHT__ +MACHDEP := -D__CELLOS_LV2__ -D__PSL1GHT__ -mcpu=cell CFLAGS += -Wall $(MACHDEP) $(INCLUDE) LDFLAGS := $(MACHDEP) -LIBS := -lrgl_ps3 -lretro_psl1ght -laudio -lrsx -lgcm_sys -lnet -lio -lsysutil -lsysmodule -lm -ljpgdec -lpngdec -llv2 -lnet -lnetctl +LIBS := -lretro_psl1ght -laudio -lrsx -lgcm_sys -lnet -lio -lsysutil -lsysmodule -lm -ljpgdec -lpngdec -llv2 -lnet -lnetctl # system platform system_platform = unix @@ -38,46 +48,10 @@ endif PKG_SCRIPT = tools/ps3/ps3py/pkg.py ifeq ($(shell uname), Linux) -PKG_FINALIZE = package_finalize -MAKE_SELF_WC = make_self_wc -MAKE_SELF = make_self_npdrm -PYTHON2 = python2 GIT = git else -PKG_FINALIZE = package_finalize.exe -MAKE_SELF_WC = make_self_wc.exe -MAKE_SELF = make_self_npdrm.exe -PYTHON2 = python2.exe GIT = git.exe endif -# system platform -system_platform = unix -ifeq ($(shell uname -a),) -EXE_EXT = .exe - system_platform = win -else ifneq ($(findstring Darwin,$(shell uname -a)),) - system_platform = osx -else ifneq ($(findstring MINGW,$(shell uname -a)),) - system_platform = win -endif - -PKG_SCRIPT = tools/ps3/ps3py/pkg.py -ifeq ($(shell uname), Linux) -PKG_FINALIZE = package_finalize -MAKE_SELF_WC = make_self_wc -MAKE_SELF = make_self_npdrm -PYTHON2 = python2 -GIT = git -else -PKG_FINALIZE = package_finalize.exe -MAKE_SELF_WC = make_self_wc.exe -MAKE_SELF = make_self_npdrm.exe -PYTHON2 = python2.exe -GIT = git.exe -endif - -MAKE_FSELF_NPDRM = $(CELL_SDK)/host-win32/bin/make_fself_npdrm.exe -MAKE_PACKAGE_NPDRM = $(CELL_SDK)/host-win32/bin/make_package_npdrm.exe OBJ = griffin/griffin.o @@ -92,7 +66,7 @@ endif SHARED_FLAGS := SHARED_FLAGS += -DHAVE_VIDEO_LAYOUT -SHARED_FLAGS += -DHAVE_MENU -DHAVE_CONFIGFILE -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_OPENGLES -DHAVE_OPENGLES1 -DHAVE_PSGL -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_GCMGL -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_GRIFFIN=1 -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts -DHAVE_CC_RESAMPLER +SHARED_FLAGS += -DHAVE_MENU -DHAVE_CONFIGFILE -DRARCH_CONSOLE -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_GCMGL -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_GRIFFIN=1 -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts -DHAVE_CC_RESAMPLER -DRARCH_INTERNAL -DHAVE_MULTIMAN -DHAVE_RGUI CFLAGS += -std=gnu99 $(SHARED_FLAGS) CXXFLAGS += $(SHARED_FLAGS) @@ -103,28 +77,18 @@ else CXXFLAGS += -03 -g endif -all: $(ELF_TARGET) +all: $(SELF_TARGET) $(ELF_TARGET): $(OBJ) $(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS) -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< +create-core: $(SELF_TARGET) + cp $(SELF_TARGET) $(CORE_PATH) -%.o: %.cpp - $(CXX) $(CFLAGS) -c -o $@ $< - -create-npdrm-core: - $(MAKE_FSELF_NPDRM) $(ELF_TARGET) $(CORE_PATH) - -create-core: - $(MAKE_SELF_WC) $(ELF_TARGET) $(CORE_PATH) - -pkg: $(ELF_TARGET) create-npdrm-core - $(MAKE_PACKAGE_NPDRM) pkg/ps3/package.conf ps3/pkg - -pkg-signed: $(ELF_TARGET) create-core - $(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION).pkg +pkg: create-core + $(PKG) --contentid $(CONTENTID) pkg/psl1ght/pkg/ $(PACKAGE_BASENAME).pkg +# cp $(PACKAGE_BASENAME).pkg $(PACKAGE_BASENAME).gnpdrm.pkg +# $(PACKAGE_FINALIZE) $(PACKAGE_BASENAME).gnpdrm.pkg clean: rm -f $(ELF_TARGET) diff --git a/Makefile.psl1ght.salamander b/Makefile.psl1ght.salamander new file mode 100644 index 0000000000..cb9ad3898c --- /dev/null +++ b/Makefile.psl1ght.salamander @@ -0,0 +1,119 @@ +#------------------------------------------------------------------------------- +# Clear the implicit built in rules +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- +ifeq ($(strip $(PSL1GHT)),) +$(error "Please set PSL1GHT in your environment. export PSL1GHT=") +endif + +include $(PSL1GHT)/ppu_rules + +include version.all + +DEBUG = 0 +HAVE_LOGGER = 0 +HAVE_FILE_LOGGER = 1 + +PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7" +PC_DEVELOPMENT_UDP_PORT = 3490 + +CONTENTID = UP0001-SSNE10001_00-0000000000000001 +APPID = SSNE10001 +TITLE = Retroarch PSL1GHT +PACKAGE_BASENAME := retroarch_psl1ght + +ELF_TARGET := retroarch_psl1ght_salamander.elf +ELF_TARGET_NONSTRIPPED := retroarch_psl1ght_salamander_nonstripped.elf +EBOOT_PATH = pkg/psl1ght/pkg/USRDIR/EBOOT.BIN + +INCLUDE += -I. -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib -Ilibretro-common/include $(LIBPSL1GHT_INC) -Iinclude +LIBDIRS += -L. + +MACHDEP := -D__CELLOS_LV2__ -D__PSL1GHT__ -mcpu=cell -mhard-float -fmodulo-sched -ffunction-sections -fdata-sections +CFLAGS += -Wall $(MACHDEP) $(INCLUDE) +LDFLAGS := $(MACHDEP) +LIBS := -lgcm_sys -lrsx -lsysutil -lio -lnet -lsysmodule -lrt -llv2 -lm + +# system platform +system_platform = unix +ifeq ($(shell uname -a),) +EXE_EXT = .exe + system_platform = win +else ifneq ($(findstring Darwin,$(shell uname -a)),) + system_platform = osx +else ifneq ($(findstring MINGW,$(shell uname -a)),) + system_platform = win +endif + +PKG_SCRIPT = tools/ps3/ps3py/pkg.py +ifeq ($(shell uname), Linux) +GIT = git +else +GIT = git.exe +endif + +OBJ = frontend/frontend_salamander.o \ + frontend/frontend_driver.o \ + frontend/drivers/platform_ps3.o \ + libretro-common/file/file_path.o \ + libretro-common/file/file_path_io.o \ + libretro-common/lists/dir_list.o \ + libretro-common/lists/string_list.o \ + libretro-common/file/retro_dirent.o \ + libretro-common/hash/rhash.o \ + libretro-common/string/stdstring.o \ + libretro-common/encodings/encoding_utf.o \ + libretro-common/compat/compat_strl.o \ + libretro-common/compat/compat_strcasestr.o \ + libretro-common/compat/fopen_utf8.o \ + libretro-common/streams/file_stream.o \ + libretro-common/vfs/vfs_implementation.o \ + libretro-common/file/config_file.o \ + file_path_str.o \ + verbosity.o + +ifeq ($(HAVE_LOGGER), 1) +CFLAGS += -DHAVE_LOGGER +endif + +ifeq ($(HAVE_FILE_LOGGER), 1) +CFLAGS += -DHAVE_FILE_LOGGER +endif + +SHARED_FLAGS := + +SHARED_FLAGS += -DHAVE_VIDEO_LAYOUT +SHARED_FLAGS += -DHAVE_MENU -DHAVE_CONFIGFILE -DRARCH_CONSOLE -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_GCMGL -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_GRIFFIN=1 -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts -DHAVE_CC_RESAMPLER -DHAVE_MULTIMAN -DHAVE_RGUI -DIS_SALAMANDER +CFLAGS += -std=gnu99 $(SHARED_FLAGS) +CXXFLAGS += $(SHARED_FLAGS) + +ifeq ($(DEBUG), 1) + CFLAGS += -O0 -g +else + CFLAGS += -O3 -g + CXXFLAGS += -03 -g +endif + +all: create-salamander + +$(ELF_TARGET_NONSTRIPPED): $(OBJ) + $(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS) + +$(ELF_TARGET): $(ELF_TARGET_NONSTRIPPED) + $(STRIP) $< -o $@ + $(SPRX) $@ + +create-salamander: $(ELF_TARGET) + $(SELF_NPDRM) $(ELF_TARGET) $(EBOOT_PATH) $(CONTENTID) + +pkg: create-salamander + $(PKG) --contentid $(CONTENTID) pkg/psl1ght/pkg/ $(PACKAGE_BASENAME).pkg +# cp $(PACKAGE_BASENAME).pkg $(PACKAGE_BASENAME).gnpdrm.pkg +# $(PACKAGE_FINALIZE) $(PACKAGE_BASENAME).gnpdrm.pkg + +clean: + rm -f $(ELF_TARGET) + rm -f $(OBJ) + +.PHONY: clean diff --git a/defines/ps3_defines.h b/defines/ps3_defines.h index 2b4b0b3d75..5fb6b94c16 100644 --- a/defines/ps3_defines.h +++ b/defines/ps3_defines.h @@ -17,8 +17,6 @@ #ifndef _PS3_DEFINES_H #define _PS3_DEFINES_H -#include - /*============================================================ AUDIO PROTOTYPES ============================================================ */ @@ -71,6 +69,7 @@ extern int audioAddData(uint32_t portNum, float *data, uint32_t frames, float vo #define sys_semaphore_t sys_sem_t #else +#include #include #include #include @@ -330,6 +329,11 @@ extern int audioAddData(uint32_t portNum, float *data, uint32_t frames, float vo #define sys_ppu_thread_join sysThreadJoin #define sys_ppu_thread_exit sysThreadExit +#define sys_process_exit sysProcessExit +#define sys_game_process_exitspawn sysProcessExitSpawn2 + +#define SYS_PROCESS_PRIMARY_STACK_SIZE_1M SYS_PROCESS_SPAWN_STACK_SIZE_1M + #define SYS_PPU_THREAD_CREATE_JOINABLE 0 /* FIXME - not sure if this is correct */ #elif defined(__CELLOS_LV2__) #include @@ -572,6 +576,7 @@ extern int audioAddData(uint32_t portNum, float *data, uint32_t frames, float vo #define socketclose close #define sys_net_initialize_network netInitialize +#define sys_net_finalize_network netFinalizeNetwork #else #include #include diff --git a/dist-scripts/dist-cores.sh b/dist-scripts/dist-cores.sh index 2f2bcd2444..91ac5d144e 100755 --- a/dist-scripts/dist-cores.sh +++ b/dist-scripts/dist-cores.sh @@ -80,6 +80,13 @@ platform=ngc MAKEFILE_GRIFFIN=yes EXT=a +# PSL1GHT +elif [ $PLATFORM = "psl1ght" ] ; then +platform=psl1ght +SALAMANDER=yes +EXT=a +ps3appid=SSNE10001 + # DEX PS3 elif [ $PLATFORM = "dex-ps3" ] ; then platform=ps3 @@ -250,7 +257,13 @@ for f in `ls -v *_${platform}.${EXT}`; do fi # Move executable files - if [ $platform = "ps3" ] ; then + if [ $platform = "psl1ght" ] ; then + mv -fv ../retroarch_psl1ght.self ../pkg/psl1ght/pkg/USRDIR/cores/"${name}_libretro_${platform}.SELF" + if [ -d ../../dist/info ]; then + mkdir -p ../pkg/psl1ght/USRDIR/cores/info + cp -fv ../../dist/info/"${name}_libretro.info" ../pkg/psl1ght/USRDIR/pkg/cores/info/"${name}_libretro.info" + fi + elif [ $platform = "ps3" ] ; then if [ $PLATFORM = "ode-ps3" ] ; then mv -fv ../CORE.SELF ../pkg/${platform}_iso/PS3_GAME/USRDIR/cores/"${name}_libretro_${platform}.SELF" if [ -d ../../dist/info ]; then @@ -299,7 +312,9 @@ for f in `ls -v *_${platform}.${EXT}`; do fi # Remove executable files - if [ $platform = "ps3" ] ; then + if [ $platform = "psl1ght" ] ; then + rm -f ../retroarch_${platform}.elf ../retroarch_${platform}.self ../CORE.SELF + elif [ $platform = "ps3" ] ; then rm -f ../retroarch_${platform}.elf ../retroarch_${platform}.self ../CORE.SELF elif [ $PLATFORM = "ps2" ] ; then rm -f ../retroarchps2.elf @@ -340,7 +355,7 @@ for f in `ls -v *_${platform}.${EXT}`; do done # Additional build step -if [ $platform = "ps3" ] ; then +if [ $platform = "ps3" ] || [ $platform = "psl1ght" ] ; then if [ $PLATFORM = "ode-ps3" ] ; then echo Deploy : Assets... if [ -d ../media/assets ]; then @@ -367,29 +382,33 @@ if [ $platform = "ps3" ] ; then cp -r ../media/shaders_cg/* ../pkg/${platform}_iso/PS3_GAME/USRDIR/cores/shaders_cg fi else + ps3pkgdir=pkg/ps3/SSNE10000 + if [ $platform = psl1ght ]; then + ps3pkgdir=pkg/psl1ght/pkg + fi echo Deploy : Assets... if [ -d ../media/assets ]; then - mkdir -p ../pkg/${platform}/SSNE10000/USRDIR/cores/assets - cp -r ../media/assets/* ../pkg/${platform}/SSNE10000/USRDIR/cores/assets + mkdir -p ../${ps3pkgdir}/USRDIR/cores/assets + cp -r ../media/assets/* ../${ps3pkgdir}/USRDIR/cores/assets fi echo Deploy : Databases... if [ -d ../media/libretrodb/rdb ]; then - mkdir -p ../pkg/${platform}/SSNE10000/USRDIR/cores/database/rdb - cp -r ../media/libretrodb/rdb/* ../pkg/${platform}/SSNE10000/USRDIR/cores/database/rdb + mkdir -p ../${ps3pkgdir}/USRDIR/cores/database/rdb + cp -r ../media/libretrodb/rdb/* ../${ps3pkgdir}/USRDIR/cores/database/rdb fi if [ -d ../media/libretrodb/cursors ]; then - mkdir -p ../pkg/${platform}/SSNE10000/USRDIR/cores/database/cursors - cp -r ../media/libretrodb/cursors/* ../pkg/${platform}/SSNE10000/USRDIR/cores/database/cursors + mkdir -p ../${ps3pkgdir}/USRDIR/cores/database/cursors + cp -r ../media/libretrodb/cursors/* ../${ps3pkgdir}/USRDIR/cores/database/cursors fi echo Deploy : Overlays... if [ -d ../media/overlays ]; then - mkdir -p ../pkg/${platform}/SSNE10000/USRDIR/cores/overlays - cp -r ../media/overlays/* ../pkg/${platform}/SSNE10000/USRDIR/cores/overlays + mkdir -p ../${ps3pkgdir}/USRDIR/cores/overlays + cp -r ../media/overlays/* ../${ps3pkgdir}/USRDIR/cores/overlays fi echo Deploy : Shaders... if [ -d ../media/shaders_cg ]; then - mkdir -p ../pkg/${platform}/SSNE10000/USRDIR/cores/shaders_cg - cp -r ../media/shaders_cg/* ../pkg/${platform}/SSNE10000/USRDIR/cores/shaders_cg + mkdir -p ../${ps3pkgdir}/USRDIR/cores/shaders_cg + cp -r ../media/shaders_cg/* ../${ps3pkgdir}/USRDIR/cores/shaders_cg fi fi fi @@ -408,6 +427,8 @@ elif [ $PLATFORM = "cex-ps3" ] ; then (cd ../tools/ps3/ps3py && python2 setup.py build) find ../tools/ps3/ps3py/build -name '*.dll' -exec cp {} ../tools/ps3/ps3py \; ../tools/ps3/ps3py/pkg.py --contentid UP0001-SSNE10000_00-0000000000000001 ../pkg/${platform}/SSNE10000/ ../pkg/${platform}/RetroArch.PS3.CEX.PS3.pkg +elif [ $PLATFORM = "psl1ght" ] ; then + pkg.py --contentid UP0001-SSNE10001_00-0000000000000001 ../pkg/psl1ght/pkg/ ../pkg/psl1ght/RetroArch.PSL1GHT.pkg elif [ $PLATFORM = "ode-ps3" ] ; then rsync -av ../pkg/${platform}_iso/PS3_GAME/USRDIR/cores/*.SELF ../pkg/${platform}/${PLATFORM}/ $SCETOOL_PATH $SCETOOL_FLAGS_ODE ../retroarch-salamander_${platform}.elf ../pkg/${platform}_iso/PS3_GAME/USRDIR/EBOOT.BIN diff --git a/frontend/drivers/platform_ps3.c b/frontend/drivers/platform_ps3.c index f4d63fea6d..23f04bbddf 100644 --- a/frontend/drivers/platform_ps3.c +++ b/frontend/drivers/platform_ps3.c @@ -17,14 +17,17 @@ #include #include +#if !defined(__PSL1GHT__) #include -#ifdef IS_SALAMANDER +#endif +#if defined (IS_SALAMANDER) && !defined(__PSL1GHT__) #include #include #include #include #endif +#include #include #ifdef HAVE_CONFIG_H @@ -45,7 +48,11 @@ #include "../../defaults.h" #include "../../verbosity.h" +#ifdef __PSL1GHT__ +#define EMULATOR_CONTENT_DIR "SSNE10001" +#else #define EMULATOR_CONTENT_DIR "SSNE10000" +#endif #ifndef __PSL1GHT__ #define NP_POOL_SIZE (128*1024) @@ -100,6 +107,108 @@ static void callback_sysutil_exit(uint64_t status, } #endif +static void fill_derived_paths() +{ + strlcpy(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY], + g_defaults.dirs[DEFAULT_DIR_PORT], + sizeof(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], + g_defaults.dirs[DEFAULT_DIR_PORT], + "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], + g_defaults.dirs[DEFAULT_DIR_CORE], + "info", + sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SAVESTATE], + g_defaults.dirs[DEFAULT_DIR_CORE], + "savestates", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SRAM], + g_defaults.dirs[DEFAULT_DIR_CORE], + "savefiles", sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], + g_defaults.dirs[DEFAULT_DIR_CORE], + "system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SHADER], + g_defaults.dirs[DEFAULT_DIR_CORE], + "shaders_cg", sizeof(g_defaults.dirs[DEFAULT_DIR_SHADER])); + fill_pathname_join(g_defaults.path.config, g_defaults.dirs[DEFAULT_DIR_PORT], + file_path_str(FILE_PATH_MAIN_CONFIG), sizeof(g_defaults.path.config)); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], + g_defaults.dirs[DEFAULT_DIR_CORE], + "overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY])); +#ifdef HAVE_VIDEO_LAYOUT + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT], + g_defaults.dirs[DEFAULT_DIR_CORE], + "layouts", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT])); +#endif + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], + g_defaults.dirs[DEFAULT_DIR_CORE], + "assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CURSOR], + g_defaults.dirs[DEFAULT_DIR_CORE], + "database/cursors", sizeof(g_defaults.dirs[DEFAULT_DIR_CURSOR])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], + g_defaults.dirs[DEFAULT_DIR_CORE], + "database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], + g_defaults.dirs[DEFAULT_DIR_CORE], + "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], + g_defaults.dirs[DEFAULT_DIR_CORE], + "downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CHEATS], + g_defaults.dirs[DEFAULT_DIR_CORE], "cheats", + sizeof(g_defaults.dirs[DEFAULT_DIR_CHEATS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG], + g_defaults.dirs[DEFAULT_DIR_CORE], + "autoconfig", sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + g_defaults.dirs[DEFAULT_DIR_CORE], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); +} + +static void use_app_path(char *content_info_path) +{ + fill_pathname_join(content_info_path, "/dev_hdd0/game/", + EMULATOR_CONTENT_DIR, PATH_MAX_LENGTH); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PORT], content_info_path, + "USRDIR", sizeof(g_defaults.dirs[DEFAULT_DIR_PORT])); +} + +#ifdef __PSL1GHT__ +static void frontend_ps3_get_environment_settings(int *argc, char *argv[], + void *args, void *params_data) +{ +#ifndef IS_SALAMANDER + bool original_verbose = verbosity_is_enabled(); + verbosity_enable(); +#endif + + (void)args; +#if defined(HAVE_LOGGER) && !defined(IS_SALAMANDER) + logger_init(); +#elif defined(HAVE_FILE_LOGGER) +#ifndef IS_SALAMANDER + retro_main_log_file_init("/dev_hdd0/game/" EMULATOR_CONTENT_DIR "/USRDIR/retroarch-log.txt", false); +#else + retro_main_log_file_init("/dev_hdd0/game/" EMULATOR_CONTENT_DIR "/USRDIR/retroarch-log-salamander.txt", false); +#endif +#endif + + char content_info_path[PATH_MAX_LENGTH] = {0}; + + use_app_path(content_info_path); + fill_derived_paths(); + +#ifndef IS_SALAMANDER + if (original_verbose) + verbosity_enable(); + else + verbosity_disable(); +#endif +} + +#else static void frontend_ps3_get_environment_settings(int *argc, char *argv[], void *args, void *params_data) { @@ -113,7 +222,7 @@ static void frontend_ps3_get_environment_settings(int *argc, char *argv[], #if defined(HAVE_LOGGER) logger_init(); #elif defined(HAVE_FILE_LOGGER) - retro_main_log_file_init("/retroarch-log.txt"); + retro_main_log_file_init("/dev_hdd0/retroarch-log.txt", false); #endif #endif @@ -199,10 +308,7 @@ static void frontend_ps3_get_environment_settings(int *argc, char *argv[], #ifdef HAVE_MULTIMAN if (multiman_detected) { - fill_pathname_join(content_info_path, "/dev_hdd0/game/", - EMULATOR_CONTENT_DIR, sizeof(content_info_path)); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PORT], content_info_path, - "USRDIR", sizeof(g_defaults.dirs[DEFAULT_DIR_PORT])); + use_app_path(content_info_path); } #endif @@ -215,62 +321,7 @@ static void frontend_ps3_get_environment_settings(int *argc, char *argv[], RARCH_LOG("usrDirPath : [%s].\n", g_defaults.dirs[DEFAULT_DIR_PORT]); } - strlcpy(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY], - g_defaults.dirs[DEFAULT_DIR_PORT], - sizeof(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], - g_defaults.dirs[DEFAULT_DIR_PORT], - "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], - g_defaults.dirs[DEFAULT_DIR_CORE], - "info", - sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SAVESTATE], - g_defaults.dirs[DEFAULT_DIR_CORE], - "savestates", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SRAM], - g_defaults.dirs[DEFAULT_DIR_CORE], - "savefiles", sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], - g_defaults.dirs[DEFAULT_DIR_CORE], - "system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SHADER], - g_defaults.dirs[DEFAULT_DIR_CORE], - "shaders_cg", sizeof(g_defaults.dirs[DEFAULT_DIR_SHADER])); - fill_pathname_join(g_defaults.path.config, g_defaults.dirs[DEFAULT_DIR_PORT], - file_path_str(FILE_PATH_MAIN_CONFIG), sizeof(g_defaults.path.config)); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], - g_defaults.dirs[DEFAULT_DIR_CORE], - "overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY])); -#ifdef HAVE_VIDEO_LAYOUT - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT], - g_defaults.dirs[DEFAULT_DIR_CORE], - "layouts", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT])); -#endif - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], - g_defaults.dirs[DEFAULT_DIR_CORE], - "assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CURSOR], - g_defaults.dirs[DEFAULT_DIR_CORE], - "database/cursors", sizeof(g_defaults.dirs[DEFAULT_DIR_CURSOR])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], - g_defaults.dirs[DEFAULT_DIR_CORE], - "database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], - g_defaults.dirs[DEFAULT_DIR_CORE], - "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], - g_defaults.dirs[DEFAULT_DIR_CORE], - "downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CHEATS], - g_defaults.dirs[DEFAULT_DIR_CORE], "cheats", - sizeof(g_defaults.dirs[DEFAULT_DIR_CHEATS])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG], - g_defaults.dirs[DEFAULT_DIR_CORE], - "autoconfig", sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], - g_defaults.dirs[DEFAULT_DIR_CORE], - "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); + fill_derived_paths(); } #ifndef IS_SALAMANDER @@ -280,6 +331,7 @@ static void frontend_ps3_get_environment_settings(int *argc, char *argv[], verbosity_disable(); #endif } +#endif static void frontend_ps3_init(void *data) { @@ -401,15 +453,21 @@ static int frontend_ps3_exec_exitspawn(const char *path, int ret; unsigned i; char spawn_data[256]; +#ifndef __PSL1GHT__ SceNpDrmKey *license_data = NULL; +#endif for(i = 0; i < sizeof(spawn_data); ++i) spawn_data[i] = i & 0xff; +#ifndef __PSL1GHT__ ret = sceNpDrmProcessExitSpawn(license_data, path, (const char** const)argv, envp, (sys_addr_t)spawn_data, 256, 1000, SYS_PROCESS_PRIMARY_STACK_SIZE_1M); - +#else + ret = -1; +#endif + if(ret < 0) { RARCH_WARN("SELF file is not of NPDRM type, trying another approach to boot it...\n"); @@ -452,7 +510,9 @@ static void frontend_ps3_exec(const char *path, bool should_load_game) NULL, NULL); } +#ifndef __PSL1GHT__ sceNpTerm(); +#endif sys_net_finalize_network(); cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_NP); cellSysmoduleUnloadModule(CELL_SYSMODULE_NET); @@ -498,7 +558,9 @@ static void frontend_ps3_exitspawn(char *s, size_t len, char *args) frontend_ps3_exec(s, should_load_game); #ifdef IS_SALAMANDER +#ifndef __PSL1GHT__ cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_GAME); +#endif cellSysmoduleLoadModule(CELL_SYSMODULE_FS); cellSysmoduleLoadModule(CELL_SYSMODULE_IO); #endif diff --git a/gfx/drivers/gcm_gfx.c b/gfx/drivers/gcm_gfx.c new file mode 100644 index 0000000000..ba16247c79 --- /dev/null +++ b/gfx/drivers/gcm_gfx.c @@ -0,0 +1,692 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2020 Google + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include +#include + +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#ifdef HAVE_MENU +#include "../../menu/menu_driver.h" +#endif + +#include "../font_driver.h" + +#include "../../configuration.h" +#include "../../command.h" +#include "../../driver.h" + +#include "../../retroarch.h" +#include "../../verbosity.h" + +#ifndef HAVE_THREADS +#include "../../tasks/tasks_internal.h" +#endif + +#include "../../defines/ps3_defines.h" + +#include +#include + +#define CB_SIZE 0x100000 +#define HOST_SIZE (32*1024*1024) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_BUFFERS 2 + +typedef struct +{ + + int height; + int width; + int id; + uint32_t *ptr; + // Internal stuff + uint32_t offset; +} rsxBuffer; + +typedef struct +{ + float v; + float u; + float y; + float x; +} gcm_scale_vector_t; + +typedef struct +{ + s16 x0, y0, x1, y1; + s16 u0, v0, u1, v1; +} gcm_vertex_t; + +typedef struct gcm_video +{ + video_viewport_t vp; + rsxBuffer buffers[MAX_BUFFERS]; + rsxBuffer menuBuffers[MAX_BUFFERS]; + int currentBuffer, menuBuffer; + gcmContextData *context; + u16 width; + u16 height; + bool menu_frame_enable; + bool rgb32; + bool vsync; + u32 depth_pitch; + u32 depth_offset; + u32 *depth_buffer; + + bool smooth; + unsigned rotation; + bool keep_aspect; + bool should_resize; + bool msg_rendering_enabled; + +} gcm_video_t; + +#ifndef HAVE_THREADS +static bool gcm_tasks_finder(retro_task_t *task,void *userdata) +{ + return task; +} +task_finder_data_t gcm_tasks_finder_data = {gcm_tasks_finder, NULL}; +#endif + +static int +makeBuffer (rsxBuffer * buffer, u16 width, u16 height, int id) +{ + int depth = sizeof(u32); + int pitch = depth * width; + int size = depth * width * height; + + buffer->ptr = (uint32_t*) rsxMemalign (64, size); + if (buffer->ptr == NULL) + goto error; + + if (rsxAddressToOffset (buffer->ptr, &buffer->offset) != 0) + goto error; + + /* Register the display buffer with the RSX */ + if (gcmSetDisplayBuffer (id, buffer->offset, pitch, width, height) != 0) + goto error; + + buffer->width = width; + buffer->height = height; + buffer->id = id; + + return TRUE; + + error: + if (buffer->ptr != NULL) + rsxFree (buffer->ptr); + + return FALSE; +} + +static int +flip (gcmContextData *context, s32 buffer) +{ + if (gcmSetFlip (context, buffer) == 0) { + rsxFlushBuffer (context); + // Prevent the RSX from continuing until the flip has finished. + gcmSetWaitFlip (context); + + return TRUE; + } + return FALSE; +} + +#define GCM_LABEL_INDEX 255 + +static void waitRSXIdle(gcmContextData *context); + +static void +waitFlip () +{ + while (gcmGetFlipStatus () != 0) + usleep (200); /* Sleep, to not stress the cpu. */ + gcmResetFlipStatus (); +} + +static gcmContextData * +initScreen (gcm_video_t* gcm) +{ + gcmContextData *context = NULL; /* Context to keep track of the RSX buffer. */ + static gcmContextData *saved_context = NULL; + videoState state; + videoConfiguration vconfig; + videoResolution res; /* Screen Resolution */ + + if (!saved_context) { + /* Allocate a 1Mb buffer, alligned to a 1Mb boundary + * to be our shared IO memory with the RSX. */ + void *host_addr = memalign (1024*1024, HOST_SIZE); + + if (host_addr == NULL) + goto error; + + /* Initilise Reality, which sets up the command buffer and shared IO memory */ + context = rsxInit (CB_SIZE, HOST_SIZE, host_addr); + if (context == NULL) + goto error; + saved_context = context; + } else { + context = saved_context; + } + + /* Get the state of the display */ + if (videoGetState (0, 0, &state) != 0) + goto error; + + /* Make sure display is enabled */ + if (state.state != 0) + goto error; + + /* Get the current resolution */ + if (videoGetResolution (state.displayMode.resolution, &res) != 0) + goto error; + + /* Configure the buffer format to xRGB */ + memset (&vconfig, 0, sizeof(videoConfiguration)); + vconfig.resolution = state.displayMode.resolution; + vconfig.format = VIDEO_BUFFER_FORMAT_XRGB; + vconfig.pitch = res.width * sizeof(u32); + vconfig.aspect = state.displayMode.aspect; + + gcm->width = res.width; + gcm->height = res.height; + + waitRSXIdle(context); + + if (videoConfigure (0, &vconfig, NULL, 0) != 0) + goto error; + + if (videoGetState (0, 0, &state) != 0) + goto error; + + gcmSetFlipMode (GCM_FLIP_VSYNC); // Wait for VSYNC to flip + + gcm->depth_pitch = res.width * sizeof(u32); + gcm->depth_buffer = (u32 *) rsxMemalign (64, (res.height * gcm->depth_pitch)* 2); + rsxAddressToOffset (gcm->depth_buffer, &gcm->depth_offset); + + gcmResetFlipStatus(); + + return context; + + error: + // if (context) + // rsxFinish (context, 0); + + // if (gcm->host_addr) + // free (gcm->host_addr); + + return NULL; +} + + +static void +waitFinish(gcmContextData *context, u32 sLabelVal) +{ + rsxSetWriteBackendLabel (context, GCM_LABEL_INDEX, sLabelVal); + + rsxFlushBuffer (context); + + while(*(vu32 *) gcmGetLabelAddress (GCM_LABEL_INDEX) != sLabelVal) + usleep(30); + + sLabelVal++; +} + +static void +waitRSXIdle(gcmContextData *context) +{ + u32 sLabelVal = 1; + + rsxSetWriteBackendLabel (context, GCM_LABEL_INDEX, sLabelVal); + rsxSetWaitLabel (context, GCM_LABEL_INDEX, sLabelVal); + + sLabelVal++; + + waitFinish(context, sLabelVal); +} + +static void* gcm_init(const video_info_t* video, + input_driver_t** input, void** input_data) +{ + RARCH_LOG("Reached gcm_init\n"); + gcm_video_t* gcm = malloc(sizeof(gcm_video_t)); + + if (!gcm) + return NULL; + + memset(gcm, 0, sizeof(gcm_video_t)); + + int i; + + gcm->context = initScreen (gcm); + + for (i = 0; i < MAX_BUFFERS; i++) + makeBuffer( &gcm->buffers[i], gcm->width, gcm->height, i); + + for (i = 0; i < MAX_BUFFERS; i++) + makeBuffer( &gcm->menuBuffers[i], gcm->width, gcm->height, i + MAX_BUFFERS); + + flip(gcm->context, MAX_BUFFERS - 1); + + gcm->vp.x = 0; + gcm->vp.y = 0; + gcm->vp.width = gcm->width; + gcm->vp.height = gcm->height; + gcm->vp.full_width = gcm->width; + gcm->vp.full_height = gcm->height; + gcm->rgb32 = video->rgb32; + video_driver_set_size(gcm->vp.width, gcm->vp.height); + + if (input && input_data) + { + void *ps3input = input_ps3.init(ps3_joypad.ident); + *input = ps3input ? &input_ps3 : NULL; + *input_data = ps3input; + } + RARCH_LOG("gcm_init done\n"); + + return gcm; +} + +static void black (uint32_t *dst, uint32_t *dst_end, size_t sz) +{ + if (sz > dst_end - dst) + sz = dst_end - dst; + memset (dst, 0, sz * 4); +} + +static void blitBuffer(rsxBuffer *buffer, const void *frame, unsigned width, + unsigned height, unsigned pitch, int rgb32, bool do_scaling) +{ + if (width > buffer->width) + width = buffer->width; + if (height > buffer->height) + height = buffer->height; + int scale = 1, xofs = 0, yofs = 0; + + if (do_scaling) { + scale = buffer->width / width; + if (scale > buffer->height / height) + scale = buffer->height / height; + if (scale >= 10) + scale = 10; + if (scale >= 1) { + xofs = (buffer->width - width * scale) / 2; + yofs = (buffer->height - height * scale) / 2; + } else + scale = 1; + } + + // TODO: let rsx do the copy + int i; + int pre_clean = xofs + buffer->width * yofs; + uint32_t *dst = buffer->ptr; + uint32_t *dst_end = buffer->ptr + buffer->width * buffer->height; + + memset (dst, 0, pre_clean * 4); + dst += pre_clean; + + if (scale == 1) { + if (rgb32) { + const uint8_t *src = frame; + for (i = 0; i < height; i++) + { + memcpy(dst, src, width * 4); + black(dst + width, dst_end, buffer->width - width); + dst += buffer->width; + src += pitch; + } + } else { + const uint16_t *src = frame; + for (i = 0; i < height; i++) + { + for (int j = 0; j < width; j++, src++, dst++) { + u16 rgb565 = *src; + u8 r = ((rgb565 >> 8) & 0xf8); + u8 g = ((rgb565 >> 3) & 0xfc); + u8 b = ((rgb565 << 3) & 0xfc); + *dst = (r<<16) | (g<<8) | b; + } + black(dst, dst_end, buffer->width - width); + + dst += buffer->width - width; + src += pitch / 2 - width; + } + } + } else { + if (rgb32) { + const uint32_t *src = frame; + for (i = 0; i < height; i++) + { + for (int j = 0; j < width; j++, src++) { + u32 c = *src; + for (int k = 0; k < scale; k++, dst++) + for (int l = 0; l < scale; l++) + dst[l * buffer->width] = c; + } + for (int l = 0; l < scale; l++) + black(dst + l * buffer->width, dst_end, buffer->width - width * scale); + + dst += buffer->width * scale - width * scale; + src += pitch / 4 - width; + } + } else { + const uint16_t *src = frame; + for (i = 0; i < height; i++) + { + for (int j = 0; j < width; j++, src++) { + u16 rgb565 = *src; + u8 r = ((rgb565 >> 8) & 0xf8); + u8 g = ((rgb565 >> 3) & 0xfc); + u8 b = ((rgb565 << 3) & 0xfc); + u32 c = (r<<16) | (g<<8) | b; + for (int k = 0; k < scale; k++, dst++) + for (int l = 0; l < scale; l++) + dst[l * buffer->width] = c; + } + for (int l = 0; l < scale; l++) + black(dst + l * buffer->width, dst_end, buffer->width - width * scale); + + dst += buffer->width * scale - width * scale; + src += pitch / 2 - width; + } + } + } + if (dst < dst_end) + memset(dst, 0, 4 * (dst_end - dst)); +} + +static void gcm_update_screen(gcm_video_t *gcm) { + rsxBuffer *buffer = gcm->menu_frame_enable + ? &gcm->menuBuffers[gcm->menuBuffer] + : &gcm->buffers[gcm->currentBuffer]; + flip(gcm->context, buffer->id); + if (gcm->vsync) + waitFlip(); +#ifdef HAVE_SYSUTILS + cellSysutilCheckCallback(); +#endif +} + +static bool gcm_frame(void* data, const void* frame, + unsigned width, unsigned height, + uint64_t frame_count, + unsigned pitch, const char* msg, video_frame_info_t *video_info) +{ + gcm_video_t *gcm = (gcm_video_t*)data; + + if(frame && width && height) + { + gcm->currentBuffer++; + if (gcm->currentBuffer >= MAX_BUFFERS) + gcm->currentBuffer = 0; + blitBuffer(&gcm->buffers[gcm->currentBuffer], frame, width, height, pitch, + gcm->rgb32, true); + } + + // TODO: translucid menu + gcm_update_screen(gcm); + + return true; + +#ifdef HAVE_MENU + if (video_info->statistics_show) + { + struct font_params *osd_params = (struct font_params*) + &video_info->osd_stat_params; + + if (osd_params) + { + font_driver_render_msg(gcm, video_info->stat_text, + (const struct font_params*)&video_info->osd_stat_params, NULL); + } + } +#endif + + if (msg) + font_driver_render_msg(gcm, msg, NULL, NULL); + return true; +} + +static void gcm_set_nonblock_state(void* data, bool toggle, + bool a, unsigned b) +{ + gcm_video_t* gcm = (gcm_video_t*)data; + + if (gcm) + gcm->vsync = !toggle; +} + +static bool gcm_alive(void* data) +{ + (void)data; + return true; +} + +static bool gcm_focus(void* data) +{ + (void)data; + return true; +} + +static bool gcm_suppress_screensaver(void* data, bool enable) +{ + (void)data; + (void)enable; + return false; +} + +static void gcm_free(void* data) +{ + gcm_video_t* gcm = (gcm_video_t*)data; + + if (!gcm) + return; + + gcmSetWaitFlip(gcm->context); + for (int i = 0; i < MAX_BUFFERS; i++) + rsxFree(gcm->buffers[i].ptr); + for (int i = 0; i < MAX_BUFFERS; i++) + rsxFree(gcm->menuBuffers[i].ptr); + + //rsxFinish(gcm->context, 1); + // free(gcm->host_addr); + free (gcm); +} + +static void gcm_set_texture_frame(void* data, const void* frame, bool rgb32, + unsigned width, unsigned height, float alpha) +{ + gcm_video_t* gcm = (gcm_video_t*)data; + + int newBuffer = gcm->menuBuffer + 1; + if (newBuffer >= MAX_BUFFERS) + newBuffer = 0; + // TODO: respect alpha + blitBuffer(&gcm->menuBuffers[newBuffer], frame, width, height, + width * (rgb32 ? 4 : 2), rgb32, true); + gcm->menuBuffer = newBuffer; + + gcm_update_screen(gcm); +} + +static void gcm_set_texture_enable(void* data, bool state, bool full_screen) +{ + (void) full_screen; + + gcm_video_t* gcm = (gcm_video_t*)data; + + if (!gcm) + return; + + gcm->menu_frame_enable = state; + + gcm_update_screen(gcm); +} + +static void gcm_set_rotation(void* data, unsigned rotation) +{ + gcm_video_t* gcm = (gcm_video_t*)data; + + if (!gcm) + return; + + gcm->rotation = rotation; + gcm->should_resize = true; +} +static void gcm_set_filtering(void* data, unsigned index, bool smooth) +{ + gcm_video_t* gcm = (gcm_video_t*)data; + + if (gcm) + gcm->smooth = smooth; +} + +static void gcm_set_aspect_ratio(void* data, unsigned aspect_ratio_idx) +{ + gcm_video_t *gcm = (gcm_video_t*)data; + + if(!gcm) + return; + + gcm->keep_aspect = true; + gcm->should_resize = true; +} + +static void gcm_apply_state_changes(void* data) +{ + gcm_video_t* gcm = (gcm_video_t*)data; + + if (gcm) + gcm->should_resize = true; + +} + +static void gcm_viewport_info(void* data, struct video_viewport* vp) +{ + gcm_video_t* gcm = (gcm_video_t*)data; + + if (gcm) + *vp = gcm->vp; +} + + +static void gcm_set_osd_msg(void *data, + video_frame_info_t *video_info, + const char *msg, + const void *params, void *font) +{ + gcm_video_t* gcm = (gcm_video_t*)data; + + if (gcm && gcm->msg_rendering_enabled) + font_driver_render_msg(data, msg, params, font); +} + +static uint32_t gcm_get_flags(void *data) +{ + uint32_t flags = 0; + + return flags; +} + +static const video_poke_interface_t gcm_poke_interface = { + gcm_get_flags, + NULL, /* load_texture */ + NULL, /* unload_texture */ + NULL, + NULL, + gcm_set_filtering, + NULL, /* get_video_output_size */ + NULL, /* get_video_output_prev */ + NULL, /* get_video_output_next */ + NULL, /* get_current_framebuffer */ + NULL, + gcm_set_aspect_ratio, + gcm_apply_state_changes, + gcm_set_texture_frame, + gcm_set_texture_enable, + gcm_set_osd_msg, + NULL, /* show_mouse */ + NULL, /* grab_mouse_toggle */ + NULL, /* get_current_shader */ + NULL, /* get_current_software_framebuffer */ + NULL /* get_hw_render_interface */ +}; + +static void gcm_get_poke_interface(void* data, + const video_poke_interface_t** iface) +{ + (void)data; + *iface = &gcm_poke_interface; +} + +static bool gcm_set_shader(void* data, + enum rarch_shader_type type, const char* path) +{ + (void)data; + (void)type; + (void)path; + + return false; +} + +video_driver_t video_gcm = +{ + gcm_init, + gcm_frame, + gcm_set_nonblock_state, + gcm_alive, + gcm_focus, + gcm_suppress_screensaver, + NULL, /* has_windowed */ + gcm_set_shader, + gcm_free, + "gcm", + NULL, /* set_viewport */ + gcm_set_rotation, + gcm_viewport_info, + NULL, /* read_viewport */ + NULL, /* read_frame_raw */ +#ifdef HAVE_OVERLAY + NULL, +#endif +#ifdef HAVE_VIDEO_LAYOUT + NULL, +#endif + gcm_get_poke_interface +}; diff --git a/gfx/drivers_context/ps3_ctx.c b/gfx/drivers_context/ps3_ctx.c index 353e12ac85..88f03dc719 100644 --- a/gfx/drivers_context/ps3_ctx.c +++ b/gfx/drivers_context/ps3_ctx.c @@ -20,9 +20,7 @@ #include "config.h" #endif -#ifndef __PSL1GHT__ #include -#endif #include diff --git a/griffin/griffin.c b/griffin/griffin.c index e2df73a06d..b03ba37afb 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -240,7 +240,7 @@ VIDEO CONTEXT #endif -#if defined(__CELLOS_LV2__) +#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) #include "../gfx/drivers_context/ps3_ctx.c" #elif defined(ANDROID) #include "../gfx/drivers_context/android_ctx.c" @@ -488,7 +488,9 @@ VIDEO DRIVER #include "../gfx/drivers/xvideo.c" #endif -#if defined(GEKKO) +#if defined(__PSL1GHT__) +#include "../gfx/drivers/gcm_gfx.c" +#elif defined(GEKKO) #include "../gfx/drivers/gx_gfx.c" #elif defined(PSP) #include "../gfx/drivers/psp1_gfx.c" @@ -648,8 +650,12 @@ INPUT #include "../input/input_autodetect_builtin.c" #if defined(__CELLOS_LV2__) +#ifdef __PSL1GHT__ +#include "../input/drivers/psl1ght_input.c" +#else #include "../input/drivers/ps3_input.c" #include "../input/drivers_joypad/ps3_joypad.c" +#endif #elif defined(SN_TARGET_PSP2) || defined(PSP) || defined(VITA) #include "../input/drivers/psp_input.c" #include "../input/drivers_joypad/psp_joypad.c" diff --git a/input/drivers/ps3_input.c b/input/drivers/ps3_input.c index 7e7adb8ee7..d1a2bc1f1e 100644 --- a/input/drivers/ps3_input.c +++ b/input/drivers/ps3_input.c @@ -31,10 +31,8 @@ #include "../input_driver.h" #ifdef HAVE_MOUSE -#ifndef __PSL1GHT__ #define MAX_MICE 7 #endif -#endif /* TODO/FIXME - * fix game focus toggle */ diff --git a/input/drivers/psl1ght_input.c b/input/drivers/psl1ght_input.c new file mode 100644 index 0000000000..9be9de07a4 --- /dev/null +++ b/input/drivers/psl1ght_input.c @@ -0,0 +1,407 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2020 Google + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#include "../../defines/ps3_defines.h" + +#include "../input_driver.h" + +#include + +#include "../../config.def.h" + +#include "../../tasks/tasks_internal.h" + +#ifdef HAVE_MOUSE +#define MAX_MICE 7 +#endif + +/* TODO/FIXME - + * fix game focus toggle */ + +typedef struct +{ + float x; + float y; + float z; +} sensor_t; + +typedef struct ps3_input +{ +#ifdef HAVE_MOUSE + unsigned mice_connected; +#endif + const input_device_driver_t *joypad; +} ps3_input_t; + +static void ps3_input_poll(void *data) +{ + ps3_input_t *ps3 = (ps3_input_t*)data; + + if (ps3 && ps3->joypad) + ps3->joypad->poll(); +} + +#ifdef HAVE_MOUSE +static int16_t ps3_mouse_device_state(ps3_input_t *ps3, + unsigned user, unsigned id) +{ + RARCH_LOG("alive " __FILE__ ":%d\n", __LINE__); +} + +#endif + +static int16_t ps3_input_state(void *data, + rarch_joypad_info_t *joypad_info, + const struct retro_keybind **binds, + unsigned port, unsigned device, + unsigned idx, unsigned id) +{ + ps3_input_t *ps3 = (ps3_input_t*)data; + + if (!ps3) + return 0; + + switch (device) + { + case RETRO_DEVICE_JOYPAD: + if (id == RETRO_DEVICE_ID_JOYPAD_MASK) + { + unsigned i; + int16_t ret = 0; + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[port][i].joykey != NO_BTN) + ? binds[port][i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[port][i].joyaxis != AXIS_NONE) + ? binds[port][i].joyaxis : joypad_info->auto_binds[i].joyaxis; + + if ((uint16_t)joykey != NO_BTN && ps3->joypad->button( + joypad_info->joy_idx, (uint16_t)joykey)) + { + ret |= (1 << i); + continue; + } + else if (((float)abs(ps3->joypad->axis( + joypad_info->joy_idx, joyaxis)) / 0x8000) > joypad_info->axis_threshold) + { + ret |= (1 << i); + continue; + } + } + + return ret; + } + else + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[port][id].joykey != NO_BTN) + ? binds[port][id].joykey : joypad_info->auto_binds[id].joykey; + const uint32_t joyaxis = (binds[port][id].joyaxis != AXIS_NONE) + ? binds[port][id].joyaxis : joypad_info->auto_binds[id].joyaxis; + + if ((uint16_t)joykey != NO_BTN && ps3->joypad->button( + joypad_info->joy_idx, (uint16_t)joykey)) + return true; + if (((float)abs(ps3->joypad->axis(joypad_info->joy_idx, joyaxis)) / 0x8000) > joypad_info->axis_threshold) + return true; + } + break; + case RETRO_DEVICE_ANALOG: + if (binds[port]) + return input_joypad_analog(ps3->joypad, joypad_info, port, idx, id, binds[port]); + break; + } + + return 0; +} + +static void ps3_input_free_input(void *data) +{ + RARCH_LOG("alive " __FILE__ ":%d\n", __LINE__); +} + +static void* ps3_input_init(const char *joypad_driver) +{ + ps3_input_t *ps3 = (ps3_input_t*)calloc(1, sizeof(*ps3)); + if (!ps3) + return NULL; + + ps3->joypad = input_joypad_init_driver(joypad_driver, ps3); + + if (ps3->joypad) + ps3->joypad->init(ps3); + + return ps3; +} + +static uint64_t ps3_input_get_capabilities(void *data) +{ + (void)data; + return +#ifdef HAVE_MOUSE + (1 << RETRO_DEVICE_MOUSE) | +#endif + (1 << RETRO_DEVICE_JOYPAD) | + (1 << RETRO_DEVICE_ANALOG); +} + +static bool ps3_input_set_sensor_state(void *data, unsigned port, + enum retro_sensor_action action, unsigned event_rate) +{ + RARCH_LOG("alive " __FILE__ ":%d\n", __LINE__); + return false; +} + +static bool ps3_input_set_rumble(void *data, unsigned port, + enum retro_rumble_effect effect, uint16_t strength) +{ + RARCH_LOG("alive " __FILE__ ":%d\n", __LINE__); + return false; +} + +static const input_device_driver_t *ps3_input_get_joypad_driver(void *data) +{ + ps3_input_t *ps3 = (ps3_input_t*)data; + if (ps3) + return ps3->joypad; + return NULL; +} + +static void ps3_input_grab_mouse(void *data, bool state) +{ + (void)data; + (void)state; +} + +input_driver_t input_ps3 = { + ps3_input_init, + ps3_input_poll, + ps3_input_state, + ps3_input_free_input, + ps3_input_set_sensor_state, + NULL, + ps3_input_get_capabilities, + "ps3", + + ps3_input_grab_mouse, + NULL, + ps3_input_set_rumble, + ps3_input_get_joypad_driver, + NULL, + false +}; + +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include + +static padData pad_state[MAX_PADS]; +static bool pads_connected[MAX_PADS]; + +static INLINE int16_t convert_u8_to_s16(uint8_t val) +{ + if (val == 0) + return -0x7fff; + return val * 0x0101 - 0x8000; +} + +static const char *ps3_joypad_name(unsigned pad) +{ + return "SixAxis Controller"; +} + +static void ps3_joypad_autodetect_add(unsigned autoconf_pad) +{ + input_autoconfigure_connect( + ps3_joypad_name(autoconf_pad), + NULL, + ps3_joypad.ident, + autoconf_pad, + 0, + 0 + ); +} + +static bool ps3_joypad_init(void *data) +{ + (void)data; + ioPadInit(7); + + return true; +} + +static u16 transform_buttons(const padData *data) { + return ( + (data->BTN_CROSS << RETRO_DEVICE_ID_JOYPAD_B) + | (data->BTN_SQUARE << RETRO_DEVICE_ID_JOYPAD_Y) + | (data->BTN_SELECT << RETRO_DEVICE_ID_JOYPAD_SELECT) + | (data->BTN_START << RETRO_DEVICE_ID_JOYPAD_START) + | (data->BTN_UP << RETRO_DEVICE_ID_JOYPAD_UP) + | (data->BTN_DOWN << RETRO_DEVICE_ID_JOYPAD_DOWN) + | (data->BTN_LEFT << RETRO_DEVICE_ID_JOYPAD_LEFT) + | (data->BTN_RIGHT << RETRO_DEVICE_ID_JOYPAD_RIGHT) + | (data->BTN_CIRCLE << RETRO_DEVICE_ID_JOYPAD_A) + | (data->BTN_TRIANGLE << RETRO_DEVICE_ID_JOYPAD_X) + | (data->BTN_L1 << RETRO_DEVICE_ID_JOYPAD_L) + | (data->BTN_R1 << RETRO_DEVICE_ID_JOYPAD_R) + | (data->BTN_L2 << RETRO_DEVICE_ID_JOYPAD_L2) + | (data->BTN_R2 << RETRO_DEVICE_ID_JOYPAD_R2) + | (data->BTN_L3 << RETRO_DEVICE_ID_JOYPAD_L3) + | (data->BTN_R3 << RETRO_DEVICE_ID_JOYPAD_R3) + ); +} + +static bool ps3_joypad_button(unsigned port_num, uint16_t joykey) +{ + if (port_num >= MAX_PADS) + return false; + + return !!(transform_buttons(&pad_state[port_num]) & (UINT64_C(1) << joykey)); +} + +static void ps3_joypad_get_buttons(unsigned port_num, input_bits_t *state) +{ + if (port_num < MAX_PADS) + { + u16 v = transform_buttons(&pad_state[port_num]); + BITS_COPY16_PTR( state, v); + } + else + BIT256_CLEAR_ALL_PTR(state); +} + +static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis) +{ + int val = 0x80; + int axis = -1; + bool is_neg = false; + bool is_pos = false; + + if (joyaxis == AXIS_NONE || port_num >= DEFAULT_MAX_PADS) + return 0; + + if (AXIS_NEG_GET(joyaxis) < 4) + { + axis = AXIS_NEG_GET(joyaxis); + is_neg = true; + } + else if (AXIS_POS_GET(joyaxis) < 4) + { + axis = AXIS_POS_GET(joyaxis); + is_pos = true; + } + + switch (axis) + { + case 0: + val = pad_state[port_num].ANA_L_H; + break; + case 1: + val = pad_state[port_num].ANA_L_V; + break; + case 2: + val = pad_state[port_num].ANA_R_H; + break; + case 3: + val = pad_state[port_num].ANA_R_V; + break; + } + + val = (val - 0x7f) * 0xff; + if (is_neg && val > 0) + val = 0; + else if (is_pos && val < 0) + val = 0; + + return val; +} + +static void ps3_joypad_poll(void) +{ + padInfo padinfo; + ioPadGetInfo(&padinfo); + for(int port=0; port #endif +#ifdef __PSL1GHT__ +#include +#endif + #if defined(__CELLOS_LV2__) || ( defined(__OpenBSD__) && defined(__powerpc__) ) #ifndef _PPU_INTRINSICS_H #include @@ -226,6 +230,8 @@ retro_time_t cpu_features_get_time_usec(void) if (!QueryPerformanceCounter(&count)) return 0; return (count.QuadPart / freq.QuadPart * 1000000) + (count.QuadPart % freq.QuadPart * 1000000 / freq.QuadPart); +#elif defined(__PSL1GHT__) + return sysGetSystemTime(); #elif defined(__CELLOS_LV2__) return sys_time_get_system_time(); #elif defined(GEKKO) @@ -234,7 +240,7 @@ retro_time_t cpu_features_get_time_usec(void) return ticks_to_us(OSGetSystemTime()); #elif defined(SWITCH) || defined(HAVE_LIBNX) return (svcGetSystemTick() * 10) / 192; -#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(__QNX__) || defined(ANDROID) || defined(__MACH__) +#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(__QNX__) || defined(ANDROID) || defined(__MACH__) || defined(__PSL1GHT__) struct timespec tv = {0}; if (ra_clock_gettime(CLOCK_MONOTONIC, &tv) < 0) return 0; @@ -492,7 +498,7 @@ unsigned cpu_features_get_core_amount(void) return sysinfo.dwNumberOfProcessors; #elif defined(GEKKO) return 1; -#elif defined(PSP) || defined(PS2) +#elif defined(PSP) || defined(PS2) || defined(__CELLOS_LV2__) return 1; #elif defined(VITA) return 4; diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index 86e15646d1..90320c7caa 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -85,7 +85,7 @@ #include #endif -#if defined(__CELLOS_LV2__) +#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) #include #endif diff --git a/libretro-common/file/file_path_io.c b/libretro-common/file/file_path_io.c index 28825979cc..4ca02051df 100644 --- a/libretro-common/file/file_path_io.c +++ b/libretro-common/file/file_path_io.c @@ -87,7 +87,7 @@ #include #endif -#if defined(__CELLOS_LV2__) +#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) #include #endif diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index 746836ef08..45ef20d0ce 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -39,7 +39,7 @@ #include #endif -#if defined(__CELLOS_LV2__) +#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) #include #endif @@ -75,7 +75,7 @@ static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count) } #ifndef PATH_MAX_LENGTH -#if defined(__CELLOS_LV2__) +#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) #define PATH_MAX_LENGTH CELL_FS_MAX_FS_PATH_LENGTH #elif defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(PS2) || defined(GEKKO)|| defined(WIIU) || defined(ORBIS) #define PATH_MAX_LENGTH 512 diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index bd4fd20706..38d844bbc0 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -68,7 +68,7 @@ # endif #endif -#ifdef __CELLOS_LV2__ +#if defined (__CELLOS_LV2__) && !defined(__PSL1GHT__) #include #define O_RDONLY CELL_FS_O_RDONLY #define O_WRONLY CELL_FS_O_WRONLY @@ -151,7 +151,7 @@ #include #endif -#if defined(__CELLOS_LV2__) +#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) #include #endif @@ -949,7 +949,7 @@ int retro_vfs_stat_impl(const char *path, int32_t *size) return RETRO_VFS_STAT_IS_VALID | (is_dir ? RETRO_VFS_STAT_IS_DIRECTORY : 0) | (is_character_special ? RETRO_VFS_STAT_IS_CHARACTER_SPECIAL : 0); -#elif defined(__CELLOS_LV2__) +#elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) /* CellOS Lv2 */ bool is_dir; bool is_character_special = false; @@ -1095,7 +1095,7 @@ struct libretro_vfs_implementation_dir #elif defined(PS2) int directory; iox_dirent_t entry; -#elif defined(__CELLOS_LV2__) +#elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) CellFsErrno error; int directory; CellFsDirent entry; @@ -1114,7 +1114,7 @@ static bool dirent_check_error(libretro_vfs_implementation_dir *rdir) return (rdir->directory == INVALID_HANDLE_VALUE); #elif defined(VITA) || defined(PSP) || defined(PS2) || defined(ORBIS) return (rdir->directory < 0); -#elif defined(__CELLOS_LV2__) +#elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) return (rdir->error != CELL_FS_SUCCEEDED); #else return !(rdir->directory); @@ -1181,7 +1181,7 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl( #elif defined(_3DS) rdir->directory = !string_is_empty(name) ? opendir(name) : NULL; rdir->entry = NULL; -#elif defined(__CELLOS_LV2__) +#elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) rdir->error = cellFsOpendir(name, &rdir->directory); #elif defined(ORBIS) rdir->directory = orbisDopen(name); @@ -1223,7 +1223,7 @@ bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *rdir) int ret = ps2fileXioDread(rdir->directory, &record); rdir->entry = record; return ( ret > 0); -#elif defined(__CELLOS_LV2__) +#elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) uint64_t nread; rdir->error = cellFsReaddir(rdir->directory, &rdir->entry, &nread); return (nread != 0); @@ -1257,7 +1257,7 @@ const char *retro_vfs_dirent_get_name_impl(libretro_vfs_implementation_dir *rdir } #endif return (char*)rdir->entry.cFileName; -#elif defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__) || defined(ORBIS) +#elif defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) || defined(ORBIS) return rdir->entry.d_name; #elif defined(PS2) return rdir->entry.name; @@ -1283,7 +1283,7 @@ bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *rdir) #elif defined(PS2) const iox_dirent_t *entry = (const iox_dirent_t*)&rdir->entry; return FIO_S_ISDIR(entry->stat.mode); -#elif defined(__CELLOS_LV2__) +#elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) CellFsDirent *entry = (CellFsDirent*)&rdir->entry; return (entry->d_type == CELL_FS_TYPE_DIRECTORY); #elif defined(ORBIS) @@ -1324,7 +1324,7 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir) sceIoDclose(rdir->directory); #elif defined(PS2) ps2fileXioDclose(rdir->directory); -#elif defined(__CELLOS_LV2__) +#elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) rdir->error = cellFsClosedir(rdir->directory); #elif defined(ORBIS) orbisDclose(rdir->directory); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 5bebf9364b..ad4e11b19b 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -43,7 +43,7 @@ #include "../config.def.h" #include "../config.def.keybinds.h" -#if defined(__CELLOS_LV2__) +#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) #include #if (CELL_SDK_VERSION > 0x340000) diff --git a/pkg/psl1ght/pkg/ICON0.PNG b/pkg/psl1ght/pkg/ICON0.PNG new file mode 100644 index 0000000000000000000000000000000000000000..4a1fc52964aa07e4d609a5fff48e4e2c9c81e38a GIT binary patch literal 20179 zcmeI4c{r5o`@r8ZvSo=jvJWZ8GWKP%n;43+6q02yF$9=!VgUev z%>aco1ptT^C_iLk0Dp)26f=TPz=MGHm-6ry z*$DDi93;lu5s&pGU~wKo@%nyW?w&sqd3b+k2U3LlqdnoW(lYSh zIXOB0@bUD)yRBcElOr7ChH=Mu5WGP@+28tky5I;nZx`IZr2H}buZh7qF*5p*`?uHY z?*7}<-h}MoyvcrEN6w=jQUsXbTEwCO=I6rT3HTbVC zKj-^rGz=0=z-WN$QAJ8tMoLD-TviDotAHTO@(39jiXa=7zr--YIblx({4RzPLQ$47 z28HFXF~It9LKD#crzn)R6mgs!5hrkXcQio*>yCEDz&$;j)!;vs6qY|$6+##1hQouG zh0%~#ga1xV;kCZf5C$IJ1hj`E#sH}SDx|SkCxnWVoUAGujgfM|V3ees-7k(d!V6j40jz5gLhe^dVQv_s~xNVQ32Xe}q1S$AX;>?M7ikzWV<( z#c#s=BNYnk4X)1siggRF-t}H)hVlBl_OAgq?0Qe~MB}|N={Z(>5n%IvXMfO>* zTm;&Y+|4u`$pwLNQiK0Z`}4AXcz$=o{(mQMBR+-uzvu9C!Fc>{1+@`s-Rj?ic;ikG z{LpxewllaU{x7w@5%uqGzlK+Xle@ng_U{w1q5b>({Iz2LIiG6eriK950(f2M^*NAL zga1SKGxLVMC3#NWeAeyd zHH8GjN-L(NI!Ulvh-P|Em7g<1p4A<7SD(f)(sdUYGK6;GL~I{W|hnPphAv zvdT)7o)jbBJvXL{;*q{Sn;Tki!vOA8;6FAif1l_d#qeJie%{i5IWT27S`tbcRAm}2 zs)#5JXt*e8P?c%8s3M{?py8sVK~<*VqKb&pfQE~b2347ciz*^Y0~#($8dPN(E~wg#z@H>Bg;FtT%81CtUUkns-M41`^ zK;Uiw2tN$~izM*x5CHhd0Kl+403eb9U?(oo?u8xz?AUF9)He6;_;w@6bNi9hy2|?( zUAed}`JGi^ck^}B3Z5j2a_^2QlXKbfkk6#%*vU_cIxHr|Crx-5U0sjvb3uy;=Q&7pvT$Ufo+LA`;&;D8i*ye*at*{ zC0CZ6EKF4LOh57Ejsq+saF|@2$)a{l?v8{V2OMV35+@i91wRWdTi8P(PuZ%977Ggt zKhF%c=*1}q&bX+=WxX2W4wt)Y4i$kCQQCHHp)jo;-z{TkL$RxPu2a z71RloPdwYK=fHUmd8e%Gm|unf=ha3Q;i1F+@k4*0SC?k>&Nq7TeJI45Ws5Bs?yCE; zyR*ve<6|Q^Ik}h`htZCr{GN%u5~uH&O_txzI=er52aovE>(}`*b8_zLPek?R%`T00 zSK2YKa@&hCMDK*hDX!(^!%$`0?H?1L_6}PN4JTq-?(v9M-O`ORw6U>~Z2E8-t1##7 zV_TW7AKyUa6p4um2?!`9`1%glu7wl(9>P!vrE0-*FWWsXdrkEjh)YT;m=e#NIWzS} zx%*DJzRZ>OywXyu^XJdU#4Ki*q~FQRG*JE;3&X2QMBMS-D*0}EU-fCm-O9@CDD5kk zE}>jqvvP%+h%bwT1xB)veT5%i6c-g4SXo__9r{ug0WHh-*qKnD4LlQD7#+39b?bU+ zb;(qZrQp#c)4;$$Le%mxWGLS=SpjjFU5O0=hs%3?Rle>ex5Qni=V#gS36*v-)69z` zy4Bd+W2u3|;vz53DaNO9ooNylD9$kL3Z{I?rJ-^xXi7TLPUKB9I1b@ia5wXwYV@%9dm4`!E+9655X zS4FS3u%yKD*s;Rmtzpuz=gC8nB|EcyIjYOb5IhPlThvcY#@@x*R)PQygoLQi&xzD% zeQD%Muq`(1$ajp&-?#1AFy~Cm$bd?mTX%(e8+X_9*J7e;bhfv$GLB>&mcGQ-9zl6oS;_e$0&H^ikv{`0$PL-&&SBC>`~L{*PXMBtAsv$m6%_;sj8_{<5MAa z>sa}`?eP-N>X+4RIo4580)b!!t^uDlr5bL?8)kO%Jcv$##2EbPqac3wafg~&{kDVx z@!;gw>1T6$O*>;=9X&WIOk7Yu)n;a9Ci3CKhuYfy1bqSK9vQ+pRO+n`%WKa@R77Ar zO3GFB;_Nd%XLB9(gbJQ!9k^$F<7D>xC^p_5uRggd`uO( z_GItUHaq=u^{JSpfyMLN=DN)QcAll&Ozl>ASOU|72M=UUw(b?__5%yyb+Rn<&6_t7 zywUgWiILyjH@+b^6#`a~-jO5QVF{?i{nBQttDNC2;!oMr)ob$!7cQdnOova!p8mGy zc@#$-c<-|IRR9=mX3*sIb=9q-qoWZ#ryoC7BELxsUCK-tfA!|g3$mS?^r|g+m1}|7c9jB#R~KVPZuoUoKMk0UStWkn zU0zkcaIqZLtq|6jx$1n!y5^Ra zmT_obe?Pj0$mttc!OoS1<|&Z`mq#u*x|tWCyWiU)oLCJ&Zz;l$?c}zu3szPXF&99QrcTvZ$5eQ@ipXLnKWtM zKZgYN&CQYY5#>SiOShnHqL%5*e|C1phAhtoefp3xY<3SefvI+jL6&rogl`MuWYsk%_S#%ZD?p9KwS+< zPwI_G@;>~L{;^^f@{ohFKFKb)6VA@PXL&s)mJrfVnXY>b+&(8eJ37wKcZYSqhWv5d zdHg;k_*=hRMSeb~ejFbflc43fFo9N3Q1CAgUJ)0+V2@22Y@Ha2> ztn1DoZqBpG44YpA)tOP`H)Mkyy8O-Q45-!kEz7sq2Rm8Gx+|dW33$~kMxZ+ACi|cb z^v;?-3IHWzQ|q3QR1(@y`Bh^h``xvql$7Wf(L3*FbK3?E?Y_RxFV04oCFwYxSs>_J z{w4mf&N3gBkd75-``ot=r%SyD^p;%`iGAXCj~VeXRM~Wg6=Y|#T3J~Qe*30?=P&N` zwJwbJ*pa|`*E|m%@m8HwTv*upUfxpiIM{QJr;)79&HL(o`@x1K9+EM<-Qsw)d#{Zx zl#%@)*6n;oz?BT%TPp;b2NnAW zq_ZD$ch3=AvMU1TeXR3|m7=H(p$cm|5`J%&Ju8268bii3>FT4{nh6q*D$$sfzIrB- zE%u&zy{o1@>%NrCk-dj%Ig($qURcxAp<`GLAKQs@T68rfwMd2?s&-t>yLC(W@=|vi zKuAtTLQAe;aF-4Ng**$XOyRDp8jD~rNC#(ML_dyTt+5s#@qC4|`{a!7ZK>0WuO>=L zGoW9;el4@9gXHnrw-!A%Af@TaGd)@JD>i-5ST(ga4g}YxVlD+3W^%CAhzVAmGnYDT z^G!xCl*z= zN&v6@TU2P(nzB|G=>RJHOGveW5_wtC3l4{C9$&6I@L;ymF8U=4G^*b7iHDLFm#@QM zxLq{y9NQ+?pIuKgpw}Kgclop{Y1YWIOTH6GH%#4BZrD&7eg|UA-Q2WOg(Czlt`#XLJfUlQ_A2fxeOT}NlmR& z%C&1@sn7f220Kl!j_jOgobgu`oDZpektvKGfDsLIqp!cru=#i?(uk`)RC|hWt^Uok&z)?&kLo#$oH?o z-Gr?F#OF(V%QejM#X5B*@De(&PdoVvAWQiqL4XfIV2WbrcR0b-1HE_DBlBKaSw{}! zO5ODJ3;tKCQkO|g!lFD&L3W;MAkt$UV4*Mx*Eieo%cL?4F0NLByKC0fa=7J3V6}vl zv_)r0H*9Qk+^on;`opB@i(xwwPC&cmBXzOY!?+T{6eiRI_zVkbO5px#3LpFGPKKKZ zUe#Z1l284-#qt#wd&CWJs6?k7aKwhUf{Bl|2=X@?n5BB>34$rEYn@Q zMv#l#$tCcGeMnI=WFuM^SOJZhLoBERh=06L&NQAkFDLrwyOobK}lBKyL6 zM`B{$JUJX5rcUloOw5}=IqqY}0*p*XTf~;X*~^;OE)u+TQJ0!5C}KU*0#Tpwsmg}K z_Q}EUt7ZLg;FEWgda|PH(VL97Gc%c8+p^JmTe$WdQk$ed%ONN*=t@Mw%HkyezLzUm zVaWc;Izf(L8N0AmpA!ng%rag*$WMOVA?S*lOyKCgvH{ZBGvFgfE}hvRT%mal$Cbd! zSVdo=Mp9-g1awe=ZLcvv?Y^>p9Jh;$ixyZS^4BiVXJlpRIyySOhZn$R*gWUQI$xjA zQP~_*+j@nyIR!MM|m+SZHgwh?-y$UUd!M4de1(KF)n2Tp2(*#aWZXj_wa~z$Y~8SWMW;U6(egPrI<~e69eZo z*qXuOA>YB>kl!Rr`ggR8B|bS&M#q+%lhd>VNnsfzv1%W@bJ`(N@;1S>{7=c1~1}$i&X-q z>i2}4tABQ8^K&Iaae;0?H(+sgw>7xGA3bpE$kC%`-5-Au2RCf^I)1+et`tSrwn*$? zs$@)N7oRtqGZk$Xm40tuv*C%vz92*W7*V>c~iQ6=h-GAST zTtET&=Gb%akt%f**3UslbHe)L)%&3zODyl1$%?+qze5BSu7bTh7EQS1*1 zi9bJn92qiTmevdGLl$4Z^pu@}4 zO`3uud9(5{@BO^2Z}E~(I*VKd&z|Y1g5{IV)0Pv%ou5z4W`HVw!Xsw98!Nr-QKe)C$KEK;{_wLSh)@GeX_K6g0yW-Z5M|KYW12_B(4;_k^J_|nG;&~Ju zbic4}OW<&ySn3}bcm-~U3HR}a$hA}x@7R79POLBQQ}7gZKwCRPN}xI(*(awLd*_io z3^sLz&9)LH3VZkNT}O&B(g~5iL;haz;B|(gqN2phmod@$6Goi%POYd1=lgft_#QoS zWU&W4k-4_##s;)7i|p__F4)4>w=_Evat?c4pxT04Ht{?xKriX?^89!b1j?{rx|e*M zKO$O*so{znmnehS6uKn9^WQW!Ub%Mdn&o83HBOPx9d#ive6I=8?$QWXHc>Pm=MXp}(Q-Fpq&!c=~D}-PiawluzpCzA+ZpXD| zn7nOmy(1CBz*&0TgjQ$pM6U*S zYT>$`en?WM*Nzu5FoBT4yG<+!SCp^X+PB6GRN)BFwN|r3i#x&s>CdH|OT$LDbA%sE z(@<|?{Tw#LHZ95_w-oG`D-qt%VAwqsE}-3G(PP~^Df!IQg_lT)(@iZ11IoBwK6`KsF+PKmiK^y;T-JRQL7(D}In z)k6+r!X@_Ablp>t0@@C+%$&)kh@j<7!gkpobhm(DLd6P>*lLcA?o57~e}Y3B43~JY zhm~`&TxwlgvhtS}W$*el^mA9J_8Z}iB%;+dMYSVQ3v+Wpu_gsdN!jn$1FCFo+m$C+ zQf$XPRex}>3sJUiMye11~+Lg7TRiV{?Zlt z<+bjpz^N-=(Sz!zj9*?HyAOo&KD;_sV3_&Gl&U_9cAx+plzaQlmNj~-`xi_5u~}pn1&ASV8bWo>xl$ShJde?!CanuYS9#4k}d^TCx<=B{P3^3O8QH10;UE zc>9c9_Gw{Qk?=_fVpIUov@qny1ff#I7B+=1FF6Qq%Y{tXp{JS7o@ADUeE?YKd^>I! zX7;*m#+LF`@M$&s&SMW7`b6$#FpLb`CoHP&r2>91tE8pFWFWtW16;gHFSiEYG$#Ms OIfMP+C#pL3r~U_`YqMbh literal 0 HcmV?d00001 diff --git a/pkg/psl1ght/pkg/PARAM.SFO b/pkg/psl1ght/pkg/PARAM.SFO new file mode 100644 index 0000000000000000000000000000000000000000..f4a8ed966147d8f0e61622d7ce766a508159ee37 GIT binary patch literal 1040 zcmeHG!Ab)$5S`XVL_A0-D0u0if(I#CdJ+$kw$trOx(Uf_p{E5!=uIr*+0XG4{189L zmt_z6f?hN*dGjW3-z-ByE-ZUJq8}o1z%w9G)<4F6(&iDfEQ{5yHb{8XUqOG=ou328 z-S^Zd8iL;@`XOrfiT@?|V{$$MuM<87e}aAhpHIXM_zwIOdF=HC{+9TCgKOuS4SUie zzMR#)uLHi zzt%!h3e4KQDHnuhA!@KxK2ZvIjlei*RS*@ Date: Mon, 30 Mar 2020 08:43:19 +0200 Subject: [PATCH 02/14] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 43fa91093f..f3b7155289 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ - MENU/OZONE: Prevent glitches when rendering Ozone's selection cursor - MENU/XMB: Fix thumbnail switching via 'scan' button functionality - ODROID GO ADVANCE: Add DRM HW context driver +- PSL1GHT: Initial port - SCANNER: Prevent redundant playlist entries when handling M3U content - SCANNER/ANDROID: Fix content scanner being unable to identify certain games from CHD images (raw data sector/subcode) From 2a579f44183817151ff23b2974b6a58bad1992e7 Mon Sep 17 00:00:00 2001 From: Weedy Weed Smoker Date: Mon, 30 Mar 2020 22:00:25 +0700 Subject: [PATCH 03/14] French: Add drm_go2_ctx for odroidgo2 --- intl/msg_hash_fr.c | 4 ++-- intl/msg_hash_fr.h | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/intl/msg_hash_fr.c b/intl/msg_hash_fr.c index a1bc982177..ad14ff125e 100644 --- a/intl/msg_hash_fr.c +++ b/intl/msg_hash_fr.c @@ -1808,9 +1808,9 @@ int menu_hash_get_help_fr_enum(enum msg_hash_enums msg, char *s, size_t len) case MENU_ENUM_LABEL_VIDEO_CTX_SCALING: snprintf(s, len, #ifdef HAVE_ODROIDGO2 - "RGA scaling and bicubic filtering. May break widgets." + "Mise à l'échelle RGA et filtrage bicubique. Peut affecter les widgets." #else - "Hardware context scaling (if available)." + "Mise à l'échelle selon le contexte matériel (si disponible)." #endif ); break; diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 3077dd1381..f685d4f017 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -4312,6 +4312,17 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, "Filtre bilinéaire" ) +#ifdef HAVE_ODROIDGO2 +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_CTX_SCALING, + "Mise à l'échelle RGA" + ) +#else +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_CTX_SCALING, + "Mise à l'échelle spécifique au contexte" + ) +#endif MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, "Filtre logiciel" @@ -6075,6 +6086,17 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SMOOTH, "Ajoute un léger flou à l'image pour atténuer le contour des pixels bruts. Cette option a très peu d'impact sur les performances." ) +#ifdef HAVE_ODROIDGO2 +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_CTX_SCALING, + "Mise à l'échelle RGA et filtrage bicubique. Peut affecter les widgets." + ) +#else +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_CTX_SCALING, + "Mise à l'échelle selon le contexte matériel (si disponible)." + ) +#endif MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_FILTER, "Applique un filtre vidéo produit par le processeur.\n" From 73bcd7a69268381af14b7f8fc9d215f86782ff63 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 31 Mar 2020 16:49:16 +0100 Subject: [PATCH 04/14] Enable correct vertical alignment of text (+ font rendering fixes) --- gfx/drivers_font/caca_font.c | 3 +- gfx/drivers_font/ctr_font.c | 16 +- gfx/drivers_font/d3d10_font.c | 17 +- gfx/drivers_font/d3d11_font.c | 16 +- gfx/drivers_font/d3d12_font.c | 17 +- gfx/drivers_font/d3d_w32_font.c | 3 +- gfx/drivers_font/gdi_font.c | 9 +- gfx/drivers_font/gl1_raster_font.c | 17 +- gfx/drivers_font/gl_core_raster_font.c | 17 +- gfx/drivers_font/gl_raster_font.c | 17 +- gfx/drivers_font/metal_raster_font.m | 12 +- gfx/drivers_font/ps2_font.c | 1 + gfx/drivers_font/sixel_font.c | 3 +- gfx/drivers_font/switch_font.c | 16 +- gfx/drivers_font/vga_font.c | 3 +- gfx/drivers_font/vita2d_font.c | 17 +- gfx/drivers_font/vulkan_raster_font.c | 17 +- gfx/drivers_font/wiiu_font.c | 16 +- gfx/drivers_font/xdk1_xfonts.c | 3 +- gfx/drivers_font_renderer/bitmap.h | 5 +- gfx/drivers_font_renderer/bitmapfont.c | 23 ++- gfx/drivers_font_renderer/coretext.c | 28 ++- gfx/drivers_font_renderer/freetype.c | 18 +- gfx/drivers_font_renderer/stb.c | 28 ++- gfx/drivers_font_renderer/stb_unicode.c | 50 ++++-- gfx/font_driver.c | 65 ++++++- gfx/font_driver.h | 14 +- menu/drivers/materialui.c | 221 ++++++++++++++---------- 28 files changed, 423 insertions(+), 249 deletions(-) diff --git a/gfx/drivers_font/caca_font.c b/gfx/drivers_font/caca_font.c index 8b8f0d7cfb..62ad35acef 100644 --- a/gfx/drivers_font/caca_font.c +++ b/gfx/drivers_font/caca_font.c @@ -143,5 +143,6 @@ font_renderer_t caca_font = { caca_font_get_glyph, /* get_glyph */ NULL, /* bind_block */ NULL, /* flush */ - caca_get_message_width /* get_message_width */ + caca_get_message_width, /* get_message_width */ + NULL /* get_line_metrics */ }; diff --git a/gfx/drivers_font/ctr_font.c b/gfx/drivers_font/ctr_font.c index 0bef51cebb..34b4675644 100644 --- a/gfx/drivers_font/ctr_font.c +++ b/gfx/drivers_font/ctr_font.c @@ -312,14 +312,16 @@ static void ctr_font_render_message( const unsigned int color, float pos_x, float pos_y, unsigned width, unsigned height, unsigned text_align) { - int lines = 0; + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; if (!msg || !*msg) return; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { ctr_font_render_line(ctr, font, msg, strlen(msg), scale, color, pos_x, pos_y, @@ -327,7 +329,7 @@ static void ctr_font_render_message( return; } - line_height = scale / font->font_driver->get_line_height(font->font_data); + line_height = scale / line_metrics->height; for (;;) { @@ -454,14 +456,14 @@ static const struct font_glyph* ctr_font_get_glyph( return font->font_driver->get_glyph((void*)font->font_driver, code); } -static int ctr_font_get_line_height(void *data) +static bool ctr_font_get_line_metrics(void* data, struct font_line_metrics **metrics) { ctr_font_t* font = (ctr_font_t*)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t ctr_font = @@ -474,5 +476,5 @@ font_renderer_t ctr_font = NULL, /* bind_block */ NULL, /* flush_block */ ctr_font_get_message_width, - ctr_font_get_line_height + ctr_font_get_line_metrics }; diff --git a/gfx/drivers_font/d3d10_font.c b/gfx/drivers_font/d3d10_font.c index 47df69a6e7..a3bedcdbb3 100644 --- a/gfx/drivers_font/d3d10_font.c +++ b/gfx/drivers_font/d3d10_font.c @@ -237,14 +237,16 @@ static void d3d10_font_render_message( unsigned height, unsigned text_align) { - int lines = 0; + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; if (!msg || !*msg) return; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { d3d10_font_render_line(d3d10, font, msg, strlen(msg), scale, color, pos_x, pos_y, @@ -252,8 +254,7 @@ static void d3d10_font_render_message( return; } - line_height = font->font_driver->get_line_height(font->font_data) - * scale / height; + line_height = line_metrics->height * scale / height; for (;;) { @@ -377,14 +378,14 @@ static const struct font_glyph* d3d10_font_get_glyph(void *data, uint32_t code) return font->font_driver->get_glyph((void*)font->font_driver, code); } -static int d3d10_font_get_line_height(void *data) +static bool d3d10_font_get_line_metrics(void* data, struct font_line_metrics **metrics) { d3d10_font_t* font = (d3d10_font_t*)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t d3d10_font = { @@ -396,5 +397,5 @@ font_renderer_t d3d10_font = { NULL, /* bind_block */ NULL, /* flush */ d3d10_font_get_message_width, - d3d10_font_get_line_height + d3d10_font_get_line_metrics }; diff --git a/gfx/drivers_font/d3d11_font.c b/gfx/drivers_font/d3d11_font.c index b60ecd34e7..1a037523e6 100644 --- a/gfx/drivers_font/d3d11_font.c +++ b/gfx/drivers_font/d3d11_font.c @@ -234,14 +234,16 @@ static void d3d11_font_render_message( unsigned height, unsigned text_align) { + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; - int lines = 0; if (!msg || !*msg) return; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { d3d11_font_render_line(d3d11, font, msg, strlen(msg), scale, color, pos_x, pos_y, @@ -249,7 +251,7 @@ static void d3d11_font_render_message( return; } - line_height = font->font_driver->get_line_height(font->font_data) * scale / height; + line_height = line_metrics->height * scale / height; for (;;) { @@ -372,14 +374,14 @@ static const struct font_glyph* d3d11_font_get_glyph(void *data, uint32_t code) return font->font_driver->get_glyph((void*)font->font_driver, code); } -static int d3d11_font_get_line_height(void *data) +static bool d3d11_font_get_line_metrics(void* data, struct font_line_metrics **metrics) { d3d11_font_t* font = (d3d11_font_t*)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t d3d11_font = { @@ -391,5 +393,5 @@ font_renderer_t d3d11_font = { NULL, /* bind_block */ NULL, /* flush */ d3d11_font_get_message_width, - d3d11_font_get_line_height + d3d11_font_get_line_metrics }; diff --git a/gfx/drivers_font/d3d12_font.c b/gfx/drivers_font/d3d12_font.c index 063123dba8..7ed6634d05 100644 --- a/gfx/drivers_font/d3d12_font.c +++ b/gfx/drivers_font/d3d12_font.c @@ -248,14 +248,16 @@ static void d3d12_font_render_message( unsigned height, unsigned text_align) { - int lines = 0; + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; if (!msg || !*msg) return; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { d3d12_font_render_line(d3d12, font, msg, strlen(msg), @@ -263,8 +265,7 @@ static void d3d12_font_render_message( return; } - line_height = font->font_driver->get_line_height(font->font_data) - * scale / height; + line_height = line_metrics->height * scale / height; for (;;) { @@ -386,14 +387,14 @@ static const struct font_glyph* d3d12_font_get_glyph( return font->font_driver->get_glyph((void*)font->font_driver, code); } -static int d3d12_font_get_line_height(void *data) +static bool d3d12_font_get_line_metrics(void* data, struct font_line_metrics **metrics) { d3d12_font_t* font = (d3d12_font_t*)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t d3d12_font = { @@ -405,5 +406,5 @@ font_renderer_t d3d12_font = { NULL, /* bind_block */ NULL, /* flush */ d3d12_font_get_message_width, - d3d12_font_get_line_height + d3d12_font_get_line_metrics }; diff --git a/gfx/drivers_font/d3d_w32_font.c b/gfx/drivers_font/d3d_w32_font.c index 92158b3847..b4091e0bcd 100644 --- a/gfx/drivers_font/d3d_w32_font.c +++ b/gfx/drivers_font/d3d_w32_font.c @@ -236,5 +236,6 @@ font_renderer_t d3d_win32_font = { NULL, /* get_glyph */ NULL, /* bind_block */ NULL, /* flush */ - d3dfonts_w32_get_message_width + d3dfonts_w32_get_message_width, + NULL /* get_line_metrics */ }; diff --git a/gfx/drivers_font/gdi_font.c b/gfx/drivers_font/gdi_font.c index 30c64fbb62..ecbf58a732 100644 --- a/gfx/drivers_font/gdi_font.c +++ b/gfx/drivers_font/gdi_font.c @@ -209,8 +209,9 @@ font_renderer_t gdi_font = { gdi_render_free_font, gdi_render_msg, "gdi font", - gdi_font_get_glyph, /* get_glyph */ - NULL, /* bind_block */ - NULL, /* flush */ - gdi_get_message_width /* get_message_width */ + gdi_font_get_glyph, /* get_glyph */ + NULL, /* bind_block */ + NULL, /* flush */ + gdi_get_message_width, /* get_message_width */ + NULL /* get_line_metrics */ }; diff --git a/gfx/drivers_font/gl1_raster_font.c b/gfx/drivers_font/gl1_raster_font.c index 7b31a78881..5b62eee9bd 100644 --- a/gfx/drivers_font/gl1_raster_font.c +++ b/gfx/drivers_font/gl1_raster_font.c @@ -383,11 +383,13 @@ static void gl1_raster_font_render_message( const GLfloat color[4], GLfloat pos_x, GLfloat pos_y, unsigned text_align) { + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; - int lines = 0; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { gl1_raster_font_render_line(font, msg, (unsigned)strlen(msg), scale, color, pos_x, @@ -395,8 +397,7 @@ static void gl1_raster_font_render_message( return; } - line_height = (float) font->font_driver->get_line_height(font->font_data) * - scale / font->gl->vp.height; + line_height = line_metrics->height * scale / font->gl->vp.height; for (;;) { @@ -576,14 +577,14 @@ static void gl1_raster_font_bind_block(void *data, void *userdata) font->block = block; } -static int gl1_get_line_height(void *data) +static bool gl1_get_line_metrics(void* data, struct font_line_metrics **metrics) { gl1_raster_t *font = (gl1_raster_t*)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t gl1_raster_font = { @@ -595,5 +596,5 @@ font_renderer_t gl1_raster_font = { gl1_raster_font_bind_block, gl1_raster_font_flush_block, gl1_get_message_width, - gl1_get_line_height + gl1_get_line_metrics }; diff --git a/gfx/drivers_font/gl_core_raster_font.c b/gfx/drivers_font/gl_core_raster_font.c index a9eeabb75a..b3094699c9 100644 --- a/gfx/drivers_font/gl_core_raster_font.c +++ b/gfx/drivers_font/gl_core_raster_font.c @@ -293,11 +293,13 @@ static void gl_core_raster_font_render_message( const GLfloat color[4], GLfloat pos_x, GLfloat pos_y, unsigned text_align) { + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; - int lines = 0; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { gl_core_raster_font_render_line(font, msg, (unsigned)strlen(msg), scale, color, pos_x, @@ -305,8 +307,7 @@ static void gl_core_raster_font_render_message( return; } - line_height = (float) font->font_driver->get_line_height(font->font_data) * - scale / font->gl->vp.height; + line_height = line_metrics->height * scale / font->gl->vp.height; for (;;) { @@ -477,14 +478,14 @@ static void gl_core_raster_font_bind_block(void *data, void *userdata) font->block = block; } -static int gl_core_get_line_height(void *data) +static bool gl_core_get_line_metrics(void* data, struct font_line_metrics **metrics) { gl_core_raster_t *font = (gl_core_raster_t*)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t gl_core_raster_font = { @@ -496,5 +497,5 @@ font_renderer_t gl_core_raster_font = { gl_core_raster_font_bind_block, gl_core_raster_font_flush_block, gl_core_get_message_width, - gl_core_get_line_height + gl_core_get_line_metrics }; diff --git a/gfx/drivers_font/gl_raster_font.c b/gfx/drivers_font/gl_raster_font.c index 24ef42056f..783d6e84b9 100644 --- a/gfx/drivers_font/gl_raster_font.c +++ b/gfx/drivers_font/gl_raster_font.c @@ -362,11 +362,13 @@ static void gl_raster_font_render_message( const GLfloat color[4], GLfloat pos_x, GLfloat pos_y, unsigned text_align) { + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; - int lines = 0; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { gl_raster_font_render_line(font, msg, (unsigned)strlen(msg), scale, color, pos_x, @@ -374,8 +376,7 @@ static void gl_raster_font_render_message( return; } - line_height = (float) font->font_driver->get_line_height(font->font_data) * - scale / font->gl->vp.height; + line_height = line_metrics->height * scale / font->gl->vp.height; for (;;) { @@ -557,14 +558,14 @@ static void gl_raster_font_bind_block(void *data, void *userdata) font->block = block; } -static int gl_get_line_height(void *data) +static bool gl_get_line_metrics(void* data, struct font_line_metrics **metrics) { gl_raster_t *font = (gl_raster_t*)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t gl_raster_font = { @@ -576,5 +577,5 @@ font_renderer_t gl_raster_font = { gl_raster_font_bind_block, gl_raster_font_flush_block, gl_get_message_width, - gl_get_line_height + gl_get_line_metrics }; diff --git a/gfx/drivers_font/metal_raster_font.m b/gfx/drivers_font/metal_raster_font.m index 06390c626c..724d8d4fff 100644 --- a/gfx/drivers_font/metal_raster_font.m +++ b/gfx/drivers_font/metal_raster_font.m @@ -350,15 +350,18 @@ static INLINE void write_quad6(SpriteVertex *pv, posY:(float)posY aligned:(unsigned)aligned { - /* If the font height is not supported just draw as usual */ - if (!_font_driver->get_line_height) + struct font_line_metrics *line_metrics = NULL; + + /* If font line metrics are not supported just draw as usual */ + if (!_font_driver->get_line_metrics || + !_font_driver->get_line_metrics(_font_data, &line_metrics)) { [self _renderLine:msg length:strlen(msg) scale:scale color:color posX:posX posY:posY aligned:aligned]; return; } int lines = 0; - float line_height = _font_driver->get_line_height(_font_data) * scale / height; + float line_height = line_metrics->height * scale / height; for (;;) { @@ -545,5 +548,6 @@ font_renderer_t metal_raster_font = { .get_glyph = metal_raster_font_get_glyph, NULL, /* bind_block */ NULL, /* flush_block */ - .get_message_width = metal_get_message_width + .get_message_width = metal_get_message_width, + NULL /* get_line_metrics */ }; diff --git a/gfx/drivers_font/ps2_font.c b/gfx/drivers_font/ps2_font.c index ac4cef0f67..d0406a5b88 100644 --- a/gfx/drivers_font/ps2_font.c +++ b/gfx/drivers_font/ps2_font.c @@ -165,4 +165,5 @@ font_renderer_t ps2_font = { NULL, /* bind_block */ NULL, /* flush */ NULL, /* get_message_width */ + NULL /* get_line_metrics */ }; diff --git a/gfx/drivers_font/sixel_font.c b/gfx/drivers_font/sixel_font.c index 6101166a93..884be5f2bd 100644 --- a/gfx/drivers_font/sixel_font.c +++ b/gfx/drivers_font/sixel_font.c @@ -141,5 +141,6 @@ font_renderer_t sixel_font = { sixel_font_get_glyph, /* get_glyph */ NULL, /* bind_block */ NULL, /* flush */ - sixel_get_message_width /* get_message_width */ + sixel_get_message_width, /* get_message_width */ + NULL /* get_line_metrics */ }; diff --git a/gfx/drivers_font/switch_font.c b/gfx/drivers_font/switch_font.c index 88e3fcc532..5759c65f02 100644 --- a/gfx/drivers_font/switch_font.c +++ b/gfx/drivers_font/switch_font.c @@ -193,14 +193,16 @@ static void switch_font_render_message( const unsigned int color, float pos_x, float pos_y, unsigned text_align) { + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; - int lines = 0; if (!msg || !*msg) return; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { int msgLen = strlen(msg); if (msgLen <= AVG_GLPYH_LIMIT) @@ -211,7 +213,7 @@ static void switch_font_render_message( } return; } - line_height = scale / font->font_driver->get_line_height(font->font_data); + line_height = scale / line_metrics->height; for (;;) { @@ -312,13 +314,13 @@ static const struct font_glyph *switch_font_get_glyph( return font->font_driver->get_glyph((void *)font->font_driver, code); } -static int switch_font_get_line_height(void *data) +static bool switch_font_get_line_metrics(void* data, struct font_line_metrics **metrics) { switch_font_t *font = (switch_font_t *)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t switch_font = @@ -331,5 +333,5 @@ font_renderer_t switch_font = NULL, /* bind_block */ NULL, /* flush_block */ switch_font_get_message_width, - switch_font_get_line_height + switch_font_get_line_metrics }; diff --git a/gfx/drivers_font/vga_font.c b/gfx/drivers_font/vga_font.c index 3ff417c4cf..0b479e3e14 100644 --- a/gfx/drivers_font/vga_font.c +++ b/gfx/drivers_font/vga_font.c @@ -141,5 +141,6 @@ font_renderer_t vga_font = { vga_font_get_glyph, /* get_glyph */ NULL, /* bind_block */ NULL, /* flush */ - vga_get_message_width /* get_message_width */ + vga_get_message_width, /* get_message_width */ + NULL /* get_line_metrics */ }; diff --git a/gfx/drivers_font/vita2d_font.c b/gfx/drivers_font/vita2d_font.c index 3b47d6cec0..cdd434822d 100644 --- a/gfx/drivers_font/vita2d_font.c +++ b/gfx/drivers_font/vita2d_font.c @@ -225,22 +225,23 @@ static void vita2d_font_render_message( const unsigned int color, float pos_x, float pos_y, unsigned width, unsigned height, unsigned text_align) { + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; - int lines = 0; if (!msg || !*msg) return; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { vita2d_font_render_line(font, msg, strlen(msg), scale, color, pos_x, pos_y, width, height, text_align); return; } - line_height = font->font_driver->get_line_height(font->font_data) * - scale / font->vita->vp.height; + line_height = line_metrics->height * scale / font->vita->vp.height; for (;;) { @@ -358,14 +359,14 @@ static const struct font_glyph *vita2d_font_get_glyph( return font->font_driver->get_glyph((void*)font->font_driver, code); } -static int vita2d_font_get_line_height(void *data) +static bool vita2d_font_get_line_metrics(void* data, struct font_line_metrics **metrics) { vita_font_t *font = (vita_font_t*)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t vita2d_vita_font = { @@ -377,5 +378,5 @@ font_renderer_t vita2d_vita_font = { NULL, /* bind_block */ NULL, /* flush */ vita2d_font_get_message_width, - vita2d_font_get_line_height + vita2d_font_get_line_metrics }; diff --git a/gfx/drivers_font/vulkan_raster_font.c b/gfx/drivers_font/vulkan_raster_font.c index 720f4efd6e..3ba6567a5b 100644 --- a/gfx/drivers_font/vulkan_raster_font.c +++ b/gfx/drivers_font/vulkan_raster_font.c @@ -233,14 +233,16 @@ static void vulkan_raster_font_render_message( const float color[4], float pos_x, float pos_y, unsigned text_align) { - int lines = 0; + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; if (!msg || !*msg || !font->vk) return; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { if (font->vk) vulkan_raster_font_render_line(font, msg, strlen(msg), @@ -248,8 +250,7 @@ static void vulkan_raster_font_render_message( return; } - line_height = (float) font->font_driver->get_line_height(font->font_data) * - scale / font->vk->vp.height; + line_height = line_metrics->height * scale / font->vk->vp.height; for (;;) { @@ -452,14 +453,14 @@ static const struct font_glyph *vulkan_raster_font_get_glyph( return glyph; } -static int vulkan_get_line_height(void *data) +static bool vulkan_get_line_metrics(void* data, struct font_line_metrics **metrics) { vulkan_raster_t *font = (vulkan_raster_t*)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t vulkan_raster_font = { @@ -471,5 +472,5 @@ font_renderer_t vulkan_raster_font = { NULL, /* bind_block */ NULL, /* flush_block */ vulkan_get_message_width, - vulkan_get_line_height + vulkan_get_line_metrics }; diff --git a/gfx/drivers_font/wiiu_font.c b/gfx/drivers_font/wiiu_font.c index 7b410702c9..0e5105d573 100644 --- a/gfx/drivers_font/wiiu_font.c +++ b/gfx/drivers_font/wiiu_font.c @@ -241,14 +241,16 @@ static void wiiu_font_render_message( const unsigned int color, float pos_x, float pos_y, unsigned width, unsigned height, unsigned text_align) { - int lines = 0; + struct font_line_metrics *line_metrics = NULL; + int lines = 0; float line_height; if (!msg || !*msg) return; - /* If the font height is not supported just draw as usual */ - if (!font->font_driver->get_line_height) + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) { wiiu_font_render_line(wiiu, font, msg, strlen(msg), scale, color, pos_x, pos_y, @@ -256,7 +258,7 @@ static void wiiu_font_render_message( return; } - line_height = scale / font->font_driver->get_line_height(font->font_data); + line_height = scale / line_metrics->height; for (;;) { @@ -381,14 +383,14 @@ static const struct font_glyph* wiiu_font_get_glyph( return font->font_driver->get_glyph((void*)font->font_driver, code); } -static int wiiu_font_get_line_height(void *data) +static bool wiiu_font_get_line_metrics(void* data, struct font_line_metrics **metrics) { wiiu_font_t* font = (wiiu_font_t*)data; if (!font || !font->font_driver || !font->font_data) return -1; - return font->font_driver->get_line_height(font->font_data); + return font->font_driver->get_line_metrics(font->font_data, metrics); } font_renderer_t wiiu_font = @@ -401,5 +403,5 @@ font_renderer_t wiiu_font = NULL, /* bind_block */ NULL, /* flush */ wiiu_font_get_message_width, - wiiu_font_get_line_height + wiiu_font_get_line_metrics }; diff --git a/gfx/drivers_font/xdk1_xfonts.c b/gfx/drivers_font/xdk1_xfonts.c index 60def69781..6cde9353d5 100644 --- a/gfx/drivers_font/xdk1_xfonts.c +++ b/gfx/drivers_font/xdk1_xfonts.c @@ -118,5 +118,6 @@ font_renderer_t d3d_xdk1_font = { NULL, /* get_glyph */ NULL, /* bind_block */ NULL, /* flush */ - NULL /* get_message_width */ + NULL, /* get_message_width */ + NULL /* get_line_metrics */ }; diff --git a/gfx/drivers_font_renderer/bitmap.h b/gfx/drivers_font_renderer/bitmap.h index 8483021532..59300d8b81 100644 --- a/gfx/drivers_font_renderer/bitmap.h +++ b/gfx/drivers_font_renderer/bitmap.h @@ -19,7 +19,10 @@ #define FONT_WIDTH 5 #define FONT_HEIGHT 10 -#define FONT_HEIGHT_BASELINE 8 +/* FONT_HEIGHT_BASELINE_OFFSET: + * Distance in pixels from top of character + * to baseline */ +#define FONT_HEIGHT_BASELINE_OFFSET 8 #define FONT_WIDTH_STRIDE (FONT_WIDTH + 1) #define FONT_HEIGHT_STRIDE (FONT_HEIGHT + 1) diff --git a/gfx/drivers_font_renderer/bitmapfont.c b/gfx/drivers_font_renderer/bitmapfont.c index ed5e72d542..4f18864e78 100644 --- a/gfx/drivers_font_renderer/bitmapfont.c +++ b/gfx/drivers_font_renderer/bitmapfont.c @@ -33,6 +33,7 @@ typedef struct bm_renderer unsigned scale_factor; struct font_glyph glyphs[BMP_ATLAS_SIZE]; struct font_atlas atlas; + struct font_line_metrics line_metrics; } bm_renderer_t; static struct font_atlas *font_renderer_bmp_get_atlas(void *data) @@ -113,11 +114,15 @@ static void *font_renderer_bmp_init(const char *font_path, float font_size) handle->glyphs[i].atlas_offset_x = x; handle->glyphs[i].atlas_offset_y = y; handle->glyphs[i].draw_offset_x = 0; - handle->glyphs[i].draw_offset_y = -FONT_HEIGHT_BASELINE * (int)handle->scale_factor; - handle->glyphs[i].advance_x = (FONT_WIDTH + 1) * handle->scale_factor; + handle->glyphs[i].draw_offset_y = -FONT_HEIGHT_BASELINE_OFFSET * handle->scale_factor; + handle->glyphs[i].advance_x = FONT_WIDTH_STRIDE * handle->scale_factor; handle->glyphs[i].advance_y = 0; } + handle->line_metrics.ascender = (float)FONT_HEIGHT_BASELINE_OFFSET * handle->scale_factor; + handle->line_metrics.descender = (float)(FONT_HEIGHT - FONT_HEIGHT_BASELINE_OFFSET) * handle->scale_factor; + handle->line_metrics.height = (float)FONT_HEIGHT_STRIDE * handle->scale_factor; + return handle; } @@ -135,14 +140,16 @@ static const char *font_renderer_bmp_get_default_font(void) return ""; } -static int font_renderer_bmp_get_line_height(void* data) +static bool font_renderer_bmp_get_line_metrics( + void* data, struct font_line_metrics **metrics) { - bm_renderer_t *handle = (bm_renderer_t*)data; + bm_renderer_t *handle = (bm_renderer_t*)data; - if (!handle) - return FONT_HEIGHT; + if (!handle) + return false; - return FONT_HEIGHT * handle->scale_factor; + *metrics = &handle->line_metrics; + return true; } font_renderer_driver_t bitmap_font_renderer = { @@ -152,5 +159,5 @@ font_renderer_driver_t bitmap_font_renderer = { font_renderer_bmp_free, font_renderer_bmp_get_default_font, "bitmap", - font_renderer_bmp_get_line_height, + font_renderer_bmp_get_line_metrics }; diff --git a/gfx/drivers_font_renderer/coretext.c b/gfx/drivers_font_renderer/coretext.c index 69568628a7..b4b0751921 100644 --- a/gfx/drivers_font_renderer/coretext.c +++ b/gfx/drivers_font_renderer/coretext.c @@ -52,7 +52,7 @@ typedef struct coretext_renderer struct font_atlas atlas; coretext_atlas_slot_t atlas_slots[CT_ATLAS_SIZE]; coretext_atlas_slot_t *uc_map[0x100]; - CGFloat metrics_height; + struct font_line_metrics line_metrics; } ct_font_renderer_t; static struct font_atlas *font_renderer_ct_get_atlas(void *data) @@ -162,9 +162,19 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer handle->atlas.width = max_width * CT_ATLAS_COLS; handle->atlas.height = max_height * CT_ATLAS_ROWS; - handle->metrics_height += CTFontGetAscent(face); - handle->metrics_height += CTFontGetDescent(face); - handle->metrics_height += CTFontGetLeading(face); + + handle->line_metrics.ascender = (float)CTFontGetAscent(face); + handle->line_metrics.descender = (float)CTFontGetDescent(face); + /* CTFontGetDescent() should return a positive value, + * but I have seen several reports online of the + * value being negative + * > Since I cannot test this on real hardware, add + * a simple safety check... */ + handle->line_metrics.descender = (handle->line_metrics.descender < 0.0f) ? + (-1.0f * handle->line_metrics.descender) : handle->line_metrics.descender; + handle->line_metrics.height = + handle->line_metrics.ascender + handle->line_metrics.descender + + (float)CTFontGetLeading(face); handle->atlas.buffer = (uint8_t*) calloc(handle->atlas.width * handle->atlas.height, 1); @@ -343,12 +353,14 @@ static const char *font_renderer_ct_get_default_font(void) return default_font; } -static int font_renderer_ct_get_line_height(void *data) +static bool font_renderer_ct_get_line_metrics( + void* data, struct font_line_metrics **metrics) { ct_font_renderer_t *handle = (ct_font_renderer_t*)data; if (!handle) - return 0; - return handle->metrics_height; + return false; + *metrics = &handle->line_metrics; + return true; } font_renderer_driver_t coretext_font_renderer = { @@ -358,5 +370,5 @@ font_renderer_driver_t coretext_font_renderer = { font_renderer_ct_free, font_renderer_ct_get_default_font, "coretext", - font_renderer_ct_get_line_height + font_renderer_ct_get_line_metrics }; diff --git a/gfx/drivers_font_renderer/freetype.c b/gfx/drivers_font_renderer/freetype.c index f3158bb00d..189630e731 100644 --- a/gfx/drivers_font_renderer/freetype.c +++ b/gfx/drivers_font_renderer/freetype.c @@ -54,6 +54,7 @@ typedef struct freetype_renderer freetype_atlas_slot_t atlas_slots[FT_ATLAS_SIZE]; freetype_atlas_slot_t* uc_map[0x100]; unsigned usage_counter; + struct font_line_metrics line_metrics; } ft_font_renderer_t; static struct font_atlas *font_renderer_ft_get_atlas(void *data) @@ -261,6 +262,10 @@ static void *font_renderer_ft_init(const char *font_path, float font_size) if (!font_renderer_create_atlas(handle, font_size)) goto error; + handle->line_metrics.ascender = (float)handle->face->size->metrics.ascender / 64.0f; + handle->line_metrics.descender = (float)(-handle->face->size->metrics.descender) / 64.0f; + handle->line_metrics.height = (float)handle->face->size->metrics.height / 64.0f; + return handle; error: @@ -315,12 +320,15 @@ static const char *font_renderer_ft_get_default_font(void) #endif } -static int font_renderer_ft_get_line_height(void* data) +static bool font_renderer_ft_get_line_metrics( + void* data, struct font_line_metrics **metrics) { ft_font_renderer_t *handle = (ft_font_renderer_t*)data; - if (!handle || !handle->face) - return 0; - return handle->face->size->metrics.height/64; + if (!handle) + return false; + + *metrics = &handle->line_metrics; + return true; } font_renderer_driver_t freetype_font_renderer = { @@ -330,5 +338,5 @@ font_renderer_driver_t freetype_font_renderer = { font_renderer_ft_free, font_renderer_ft_get_default_font, "freetype", - font_renderer_ft_get_line_height, + font_renderer_ft_get_line_metrics }; diff --git a/gfx/drivers_font_renderer/stb.c b/gfx/drivers_font_renderer/stb.c index 7a9a733239..f342254ea6 100644 --- a/gfx/drivers_font_renderer/stb.c +++ b/gfx/drivers_font_renderer/stb.c @@ -36,7 +36,7 @@ typedef struct { - int line_height; + struct font_line_metrics line_metrics; struct font_atlas atlas; struct font_glyph glyphs[256]; } stb_font_renderer_t; @@ -141,6 +141,7 @@ error: static void *font_renderer_stb_init(const char *font_path, float font_size) { int ascent, descent, line_gap; + float scale_factor; stbtt_fontinfo info; uint8_t *font_data = NULL; stb_font_renderer_t *self = (stb_font_renderer_t*) calloc(1, sizeof(*self)); @@ -161,12 +162,17 @@ static void *font_renderer_stb_init(const char *font_path, float font_size) goto error; stbtt_GetFontVMetrics(&info, &ascent, &descent, &line_gap); - self->line_height = ascent - descent; - if (font_size < 0) - self->line_height *= stbtt_ScaleForMappingEmToPixels(&info, -font_size); - else - self->line_height *= stbtt_ScaleForPixelHeight(&info, font_size); + scale_factor = (font_size < 0) ? + stbtt_ScaleForMappingEmToPixels(&info, -font_size) : + stbtt_ScaleForPixelHeight(&info, font_size); + + /* Ascender, descender and line_gap values always + * end up ~0.5 pixels too small when scaled... + * > Add a manual correction factor */ + self->line_metrics.ascender = 0.5f + (float)ascent * scale_factor; + self->line_metrics.descender = 0.5f + (float)(-descent) * scale_factor; + self->line_metrics.height = 0.5f + (float)(ascent - descent + line_gap) * scale_factor; free(font_data); @@ -226,10 +232,14 @@ static const char *font_renderer_stb_get_default_font(void) return NULL; } -static int font_renderer_stb_get_line_height(void* data) +static bool font_renderer_stb_get_line_metrics( + void* data, struct font_line_metrics **metrics) { stb_font_renderer_t *handle = (stb_font_renderer_t*)data; - return handle->line_height; + if (!handle) + return false; + *metrics = &handle->line_metrics; + return true; } font_renderer_driver_t stb_font_renderer = { @@ -239,5 +249,5 @@ font_renderer_driver_t stb_font_renderer = { font_renderer_stb_free, font_renderer_stb_get_default_font, "stb", - font_renderer_stb_get_line_height, + font_renderer_stb_get_line_metrics }; diff --git a/gfx/drivers_font_renderer/stb_unicode.c b/gfx/drivers_font_renderer/stb_unicode.c index c3f2962caa..2395e77dae 100644 --- a/gfx/drivers_font_renderer/stb_unicode.c +++ b/gfx/drivers_font_renderer/stb_unicode.c @@ -57,8 +57,8 @@ typedef struct int max_glyph_width; int max_glyph_height; - int line_height; float scale_factor; + struct font_line_metrics line_metrics; struct font_atlas atlas; stb_unicode_atlas_slot_t atlas_slots[STB_UNICODE_ATLAS_SIZE]; @@ -66,13 +66,6 @@ typedef struct unsigned usage_counter; } stb_unicode_font_renderer_t; -/* Ugly little thing... */ -static int INLINE round_away_from_zero(float f) -{ - double round = (f < 0.0) ? floor((double)f) : ceil((double)f); - return (int)round; -} - static struct font_atlas *font_renderer_stb_unicode_get_atlas(void *data) { stb_unicode_font_renderer_t *self = (stb_unicode_font_renderer_t*)data; @@ -125,6 +118,8 @@ static const struct font_glyph *font_renderer_stb_unicode_get_glyph( uint8_t *dst = NULL; stb_unicode_atlas_slot_t* atlas_slot = NULL; stb_unicode_font_renderer_t *self = (stb_unicode_font_renderer_t*)data; + float glyph_advance_x = 0.0f; + float glyph_draw_offset_y = 0.0f; if(!self) return NULL; @@ -145,9 +140,9 @@ static const struct font_glyph *font_renderer_stb_unicode_get_glyph( atlas_slot = font_renderer_stb_unicode_get_slot(self); atlas_slot->charcode = charcode; atlas_slot->next = self->uc_map[map_id]; - self->uc_map[map_id] = atlas_slot; + self->uc_map[map_id] = atlas_slot; - glyph_index = stbtt_FindGlyphIndex(&self->info, charcode); + glyph_index = stbtt_FindGlyphIndex(&self->info, charcode); dst = (uint8_t*)self->atlas.buffer + atlas_slot->glyph.atlas_offset_x + atlas_slot->glyph.atlas_offset_y * self->atlas.width; @@ -171,15 +166,25 @@ static const struct font_glyph *font_renderer_stb_unicode_get_glyph( atlas_slot->glyph.width = self->max_glyph_width; atlas_slot->glyph.height = self->max_glyph_height; - atlas_slot->glyph.advance_x = round_away_from_zero((float)advance_width * self->scale_factor); + /* advance_x must always be rounded to the + * *nearest* integer */ + glyph_advance_x = (float)advance_width * self->scale_factor; + atlas_slot->glyph.advance_x = (int)((glyph_advance_x > 0.0f) ? + (glyph_advance_x + 0.5f) : (glyph_advance_x - 0.5f)); + /* advance_y is always zero */ atlas_slot->glyph.advance_y = 0; - atlas_slot->glyph.draw_offset_x = round_away_from_zero((float)x0 * self->scale_factor); - atlas_slot->glyph.draw_offset_y = round_away_from_zero((float)(-y1) * self->scale_factor); + /* draw_offset_x must always be rounded *down* + * to the nearest integer */ + atlas_slot->glyph.draw_offset_x = (int)((float)x0 * self->scale_factor); + /* draw_offset_y must always be rounded *up* + * to the nearest integer */ + glyph_draw_offset_y = (float)(-y1) * self->scale_factor; + atlas_slot->glyph.draw_offset_y = (int)((glyph_draw_offset_y < 0.0f) ? + floor((double)glyph_draw_offset_y) : ceil((double)glyph_draw_offset_y)); self->atlas.dirty = true; atlas_slot->last_used = self->usage_counter++; return &atlas_slot->glyph; - } static bool font_renderer_stb_unicode_create_atlas( @@ -259,7 +264,12 @@ static void *font_renderer_stb_unicode_init(const char *font_path, float font_si else self->scale_factor = stbtt_ScaleForPixelHeight(&self->info, font_size); - self->line_height = (ascent - descent) * self->scale_factor; + /* Ascender, descender and line_gap values always + * end up ~0.5 pixels too small when scaled... + * > Add a manual correction factor */ + self->line_metrics.ascender = 0.5f + (float)ascent * self->scale_factor; + self->line_metrics.descender = 0.5f + ((float)(-descent) * self->scale_factor); + self->line_metrics.height = 0.5f + (float)(ascent - descent + line_gap) * self->scale_factor; if (!font_renderer_stb_unicode_create_atlas(self, font_size)) goto error; @@ -321,10 +331,14 @@ static const char *font_renderer_stb_unicode_get_default_font(void) #endif } -static int font_renderer_stb_unicode_get_line_height(void* data) +static bool font_renderer_stb_unicode_get_line_metrics( + void* data, struct font_line_metrics **metrics) { stb_unicode_font_renderer_t *handle = (stb_unicode_font_renderer_t*)data; - return handle->line_height; + if (!handle) + return false; + *metrics = &handle->line_metrics; + return true; } font_renderer_driver_t stb_unicode_font_renderer = { @@ -334,5 +348,5 @@ font_renderer_driver_t stb_unicode_font_renderer = { font_renderer_stb_unicode_free, font_renderer_stb_unicode_get_default_font, "stb-unicode", - font_renderer_stb_unicode_get_line_height, + font_renderer_stb_unicode_get_line_metrics }; diff --git a/gfx/font_driver.c b/gfx/font_driver.c index 1e2682009a..f57d0a1f1d 100644 --- a/gfx/font_driver.c +++ b/gfx/font_driver.c @@ -1083,16 +1083,67 @@ int font_driver_get_message_width(void *font_data, int font_driver_get_line_height(void *font_data, float scale) { - int line_height; + struct font_line_metrics *metrics = NULL; font_data_t *font = (font_data_t*)(font_data ? font_data : video_font_driver); - /* First try the line height implementation */ - if (font && font->renderer && font->renderer->get_line_height) - if ((line_height = font->renderer->get_line_height(font->renderer_data)) != -1) - return (int)(line_height * roundf(scale)); + /* First try the line metrics implementation */ + if (font && font->renderer && font->renderer->get_line_metrics) + if ((font->renderer->get_line_metrics(font->renderer_data, &metrics))) + return (int)roundf(metrics->height * scale); - /* Else return an approximation (width of 'a') */ - return font_driver_get_message_width(font_data, "a", 1, scale); + /* Else return an approximation + * (uses a fudge of standard font metrics - mostly garbage...) + * > font_size = (width of 'a') / 0.6 + * > line_height = font_size * 1.7f */ + return (int)roundf(1.7f * (float)font_driver_get_message_width(font_data, "a", 1, scale) / 0.6f); +} + +int font_driver_get_line_ascender(void *font_data, float scale) +{ + struct font_line_metrics *metrics = NULL; + font_data_t *font = (font_data_t*)(font_data ? font_data : video_font_driver); + + /* First try the line metrics implementation */ + if (font && font->renderer && font->renderer->get_line_metrics) + if ((font->renderer->get_line_metrics(font->renderer_data, &metrics))) + return (int)roundf(metrics->ascender * scale); + + /* Else return an approximation + * (uses a fudge of standard font metrics - mostly garbage...) + * > font_size = (width of 'a') / 0.6 + * > ascender = 1.58 * font_size * 0.75 */ + return (int)roundf(1.58f * 0.75f * (float)font_driver_get_message_width(font_data, "a", 1, scale) / 0.6f); +} + +int font_driver_get_line_descender(void *font_data, float scale) +{ + struct font_line_metrics *metrics = NULL; + font_data_t *font = (font_data_t*)(font_data ? font_data : video_font_driver); + + /* First try the line metrics implementation */ + if (font && font->renderer && font->renderer->get_line_metrics) + if ((font->renderer->get_line_metrics(font->renderer_data, &metrics))) + return (int)roundf(metrics->descender * scale); + + /* Else return an approximation + * (uses a fudge of standard font metrics - mostly garbage...) + * > font_size = (width of 'a') / 0.6 + * > descender = 1.58 * font_size * 0.25 */ + return (int)roundf(1.58f * 0.25f * (float)font_driver_get_message_width(font_data, "a", 1, scale) / 0.6f); +} + +int font_driver_get_line_centre_offset(void *font_data, float scale) +{ + struct font_line_metrics *metrics = NULL; + font_data_t *font = (font_data_t*)(font_data ? font_data : video_font_driver); + + /* First try the line metrics implementation */ + if (font && font->renderer && font->renderer->get_line_metrics) + if ((font->renderer->get_line_metrics(font->renderer_data, &metrics))) + return (int)roundf((metrics->ascender - metrics->descender) * 0.5f * scale); + + /* Else return an approximation... */ + return (int)roundf((1.58f * 0.5f * (float)font_driver_get_message_width(font_data, "a", 1, scale) / 0.6f) / 2.0f); } void font_driver_free(void *font_data) diff --git a/gfx/font_driver.h b/gfx/font_driver.h index 5f0d2e3144..ef929497d2 100644 --- a/gfx/font_driver.h +++ b/gfx/font_driver.h @@ -81,6 +81,13 @@ struct font_params enum text_alignment text_align; }; +struct font_line_metrics +{ + float height; + float ascender; + float descender; +}; + typedef struct font_renderer { void *(*init)(void *data, const char *font_path, @@ -96,7 +103,7 @@ typedef struct font_renderer void (*flush)(unsigned width, unsigned height, void *data); int (*get_message_width)(void *data, const char *msg, unsigned msg_len_full, float scale); - int (*get_line_height)(void* data); + bool (*get_line_metrics)(void* data, struct font_line_metrics **metrics); } font_renderer_t; typedef struct font_renderer_driver @@ -114,7 +121,7 @@ typedef struct font_renderer_driver const char *ident; - int (*get_line_height)(void* data); + bool (*get_line_metrics)(void* data, struct font_line_metrics **metrics); } font_renderer_driver_t; typedef struct @@ -159,6 +166,9 @@ void font_driver_init_osd( void font_driver_free_osd(void); int font_driver_get_line_height(void *font_data, float scale); +int font_driver_get_line_ascender(void *font_data, float scale); +int font_driver_get_line_descender(void *font_data, float scale); +int font_driver_get_line_centre_offset(void *font_data, float scale); extern font_renderer_t gl_raster_font; extern font_renderer_t gl_core_raster_font; diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 70af7a9c00..827e5014be 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -1194,8 +1194,10 @@ typedef struct { font_data_t *font; video_font_raster_block_t raster_block; - int font_height; unsigned glyph_width; + int line_height; + int line_ascender; + int line_centre_offset; } materialui_font_data_t; #define MUI_BATTERY_PERCENT_MAX_LENGTH 12 @@ -1273,6 +1275,8 @@ typedef struct materialui_handle unsigned sys_bar_margin; unsigned landscape_entry_margin; unsigned entry_divider_width; + unsigned sublabel_gap; + unsigned sublabel_padding; /* Navigation bar parameters * Note: layout width and height are convenience @@ -1928,7 +1932,7 @@ static void materialui_render_messagebox(materialui_handle_t *mui, /* Get coordinates of message box centre */ x = video_width / 2; - y = (int)(y_centre - (list->size - 1) * (mui->font_data.list.font_height / 2)); + y = (int)(y_centre - (list->size * mui->font_data.list.line_height) / 2); /* TODO/FIXME: Reduce text scale if width or height * are too large to fit on screen */ @@ -1960,9 +1964,9 @@ static void materialui_render_messagebox(materialui_handle_t *mui, video_width, video_height, x - longest_width / 2.0 - mui->margin * 2.0, - y - mui->font_data.list.font_height / 2.0 - mui->margin * 2.0, + y - mui->margin * 2.0, longest_width + mui->margin * 4.0, - mui->font_data.list.font_height * list->size + mui->margin * 4.0, + mui->font_data.list.line_height * list->size + mui->margin * 4.0, video_width, video_height, mui->colors.surface_background); @@ -1976,8 +1980,7 @@ static void materialui_render_messagebox(materialui_handle_t *mui, gfx_display_draw_text( mui->font_data.list.font, line, x - longest_width/2.0, - y + i * mui->font_data.list.font_height - + mui->font_data.list.font_height / 3, + y + (i * mui->font_data.list.line_height) + mui->font_data.list.line_ascender, video_width, video_height, mui->colors.list_text, TEXT_ALIGN_LEFT, 1.0f, false, 0, true); } @@ -2061,7 +2064,7 @@ static void materialui_compute_entries_box( if (mui->list_view_type == MUI_LIST_VIEW_PLAYLIST_THUMB_DUAL_ICON) { /* One line of list text */ - float node_text_height = (float)mui->font_data.list.font_height; + float node_text_height = (float)mui->font_data.list.line_height; /* List text + thumbnail height + padding */ float node_entry_height = node_text_height + (float)mui->thumbnail_height_max + @@ -2140,7 +2143,7 @@ static void materialui_compute_entries_box( if (!string_is_empty(sublabel_str)) { - int sublabel_width_max = usable_width; + int sublabel_width_max = usable_width - (int)mui->sublabel_padding; /* If this is a default menu list with an icon, * must subtract icon size from sublabel width */ @@ -2157,8 +2160,8 @@ static void materialui_compute_entries_box( num_sublabel_lines = materialui_count_lines(wrapped_sublabel_str); } - node->text_height = mui->font_data.list.font_height + - (num_sublabel_lines * mui->font_data.hint.font_height); + node->text_height = mui->font_data.list.line_height + + (num_sublabel_lines * mui->font_data.hint.line_height); node->entry_height = node->text_height + mui->dip_base_unit_size / 10; @@ -2814,16 +2817,33 @@ static void materialui_render_menu_entry_default( * affects y offset positions */ if (!string_is_empty(entry_sublabel)) { - int sublabel_y = - entry_y + (int)(mui->dip_base_unit_size / 5.0f) + - (int)mui->font_data.list.font_height; + /* Note: Due to the way the selection highlight + * marker is drawn (height is effectively 1px larger + * than the entry height, to avoid visible seams), + * drawing the label+sublabel text at the exact centre + * of the entry gives the illusion of misalignment + * > Have to offset the label downwards by half a pixel + * (rounded up) */ + int vertical_margin = ((node->entry_height - node->text_height) / 2.0f) - (float)mui->sublabel_gap + 1.0f; + int sublabel_y; char wrapped_sublabel[MENU_SUBLABEL_MAX_LENGTH]; wrapped_sublabel[0] = '\0'; + /* Label + sublabel 'block' is drawn at the + * vertical centre of the current node. + * > Value icon is drawn in line with the centre + * of the part of the label above the baseline + * (needs a little extra padding at the top, since + * the line ascender is usually somewhat taller + * than the visible text) */ + label_y = entry_y + vertical_margin + mui->font_data.list.line_ascender; + value_icon_y = label_y + (mui->dip_base_unit_size / 60.0f) - (mui->font_data.list.line_ascender / 2.0f) - (mui->icon_size / 2.0f); + sublabel_y = entry_y + vertical_margin + mui->font_data.list.line_height + (int)mui->sublabel_gap + mui->font_data.hint.line_ascender; + /* Wrap sublabel string */ word_wrap(wrapped_sublabel, entry_sublabel, - (int)(usable_width / mui->font_data.hint.glyph_width), + (int)((usable_width - (int)mui->sublabel_padding) / mui->font_data.hint.glyph_width), true, 0); /* Draw sublabel string @@ -2839,22 +2859,13 @@ static void materialui_render_menu_entry_default( (entry_selected || touch_feedback_active) ? mui->colors.list_hint_text_highlighted : mui->colors.list_hint_text, TEXT_ALIGN_LEFT, 1.0f, false, 0, draw_text_outside || (sublabel_y < 0)); - - /* If we have a sublabel, entry label y position has a - * fixed vertical offset */ - label_y = entry_y + (int)(mui->dip_base_unit_size / 5.0f); - value_icon_y = entry_y + (int)((mui->dip_base_unit_size / 6.0f) - (mui->icon_size / 2.0f)); } else { /* If we don't have a sublabel, entry label is drawn - * at the vertical centre of the current node - * Note: Text is drawn relative to the baseline, - * so we can't do this accurately - but as a general - * rule of thumb, the descender of a font is at least - * 20% of it's height - so we just add (font_height / 5) */ - label_y = entry_y + (int)((node->entry_height / 2.0f) + (mui->font_data.list.font_height / 5.0f)); - value_icon_y = entry_y + (int)((node->entry_height / 2.0f) - (mui->icon_size / 2.0f)); + * at the vertical centre of the current node */ + label_y = entry_y + (node->entry_height / 2.0f) + mui->font_data.list.line_centre_offset; + value_icon_y = entry_y + (node->entry_height / 2.0f) - (mui->icon_size / 2.0f); } /* Draw entry value */ @@ -3048,16 +3059,7 @@ static void materialui_render_menu_entry_playlist_list( int entry_margin = (int)mui->margin + (int)mui->landscape_entry_margin; int usable_width = (int)width - (int)(mui->margin * 2) - (int)(mui->landscape_entry_margin * 2) - (int)mui->nav_bar_layout_width; - /* The label + sublabel text block is always drawn at - * the vertical centre of the current node - * Note: Text is drawn relative to the baseline, - * so we can't do this accurately - but tests - * indicate that the ascender of Material UI's - * font accounts for 7/20 of its height, so we - * just add (13/20) * font_height */ - int label_y = - entry_y + ((float)(node->entry_height - node->text_height) / 2.0f) + - (13.0f * (float)mui->font_data.list.font_height / 20.0f); + int label_y = 0; bool draw_text_outside = (x_offset != 0); /* Initial ticker configuration @@ -3149,6 +3151,53 @@ static void materialui_render_menu_entry_playlist_list( (int)mui->landscape_entry_margin : (int)mui->margin; } + /* Draw entry sublabel + * > Must be done before label, since it + * affects y offset positions */ + if (!string_is_empty(entry_sublabel)) + { + /* Note: Due to the way the selection highlight + * marker is drawn (height is effectively 1px larger + * than the entry height, to avoid visible seams), + * drawing the label+sublabel text at the exact centre + * of the entry gives the illusion of misalignment + * > Have to offset the label downwards by half a pixel + * (rounded up) */ + int vertical_margin = ((node->entry_height - node->text_height) / 2.0f) - (float)mui->sublabel_gap + 1.0f; + int sublabel_y; + char wrapped_sublabel[MENU_SUBLABEL_MAX_LENGTH]; + + wrapped_sublabel[0] = '\0'; + + /* Label + sublabel 'block' is drawn at the + * vertical centre of the current node */ + label_y = entry_y + vertical_margin + mui->font_data.list.line_ascender; + sublabel_y = entry_y + vertical_margin + mui->font_data.list.line_height + (int)mui->sublabel_gap + mui->font_data.hint.line_ascender; + + /* Wrap sublabel string */ + word_wrap(wrapped_sublabel, entry_sublabel, + (int)((usable_width - (int)mui->sublabel_padding) / mui->font_data.hint.glyph_width), + true, 0); + + /* Draw sublabel string + * > Note: We must allow text to be drawn off-screen + * if the current y position is negative, otherwise topmost + * entries with very long sublabels may get 'clipped' too + * early as they are scrolled upwards beyond the top edge + * of the screen */ + gfx_display_draw_text(mui->font_data.hint.font, wrapped_sublabel, + x_offset + entry_margin, + sublabel_y, + width, height, + (entry_selected || touch_feedback_active) ? + mui->colors.list_hint_text_highlighted : mui->colors.list_hint_text, + TEXT_ALIGN_LEFT, 1.0f, false, 0, draw_text_outside || (sublabel_y < 0)); + } + /* If we don't have a sublabel, entry label is drawn + * at the vertical centre of the current node */ + else + label_y = entry_y + (node->entry_height / 2.0f) + mui->font_data.list.line_centre_offset; + /* Draw entry label */ if (!string_is_empty(entry_label)) { @@ -3190,45 +3239,15 @@ static void materialui_render_menu_entry_playlist_list( } } - /* Draw entry sublabel */ - if (!string_is_empty(entry_sublabel)) - { - int sublabel_y = label_y + (int)mui->font_data.list.font_height; - char wrapped_sublabel[MENU_SUBLABEL_MAX_LENGTH]; - - wrapped_sublabel[0] = '\0'; - - /* Wrap sublabel string */ - word_wrap(wrapped_sublabel, entry_sublabel, - (int)(usable_width / mui->font_data.hint.glyph_width), - true, 0); - - /* Draw sublabel string - * > Note: We must allow text to be drawn off-screen - * if the current y position is negative, otherwise topmost - * entries with very long sublabels may get 'clipped' too - * early as they are scrolled upwards beyond the top edge - * of the screen */ - gfx_display_draw_text(mui->font_data.hint.font, wrapped_sublabel, - x_offset + entry_margin, - sublabel_y, - width, height, - (entry_selected || touch_feedback_active) ? - mui->colors.list_hint_text_highlighted : mui->colors.list_hint_text, - TEXT_ALIGN_LEFT, 1.0f, false, 0, draw_text_outside || (sublabel_y < 0)); - } - - /* When using the larger thumbnail views, the horizontal + /* When using thumbnail views, the horizontal * text area is unpleasantly vacuous, such that the * label + sublabel strings float in a sea of nothingness. * We can partially mitigate the visual 'emptiness' of this * by drawing a divider between entries. This is particularly * beneficial when dual thumbnails are enabled, since it - * 'ties' the left/right thumbnails together - * NOTE: This does not work at all for the smallest thumbnail - * list view, or when thumbnails are disabled - the result is - * just too 'busy'/visually cluttered */ - if ((mui->list_view_type == MUI_LIST_VIEW_PLAYLIST_THUMB_LIST_MEDIUM) || + * 'ties' the left/right thumbnails together */ + if ((mui->list_view_type == MUI_LIST_VIEW_PLAYLIST_THUMB_LIST_SMALL) || + (mui->list_view_type == MUI_LIST_VIEW_PLAYLIST_THUMB_LIST_MEDIUM) || (mui->list_view_type == MUI_LIST_VIEW_PLAYLIST_THUMB_LIST_LARGE)) { if (usable_width > 0) @@ -3323,8 +3342,9 @@ static void materialui_render_menu_entry_playlist_dual_icon( * with a small vertical margin */ float label_y = thumbnail_y + (float)mui->thumbnail_height_max + - ((float)mui->dip_base_unit_size / 10.0f) + - (9.0f * (float)mui->font_data.list.font_height / 20.0f); + ((float)mui->dip_base_unit_size / 20.0f) + + ((float)mui->font_data.list.line_height / 2.0f) + + (float)mui->font_data.list.line_centre_offset; bool draw_text_outside = (x_offset != 0); char label_buf[255]; @@ -3386,7 +3406,7 @@ static void materialui_render_menu_entry_playlist_dual_icon( (float)(x_offset + (int)mui->margin + (int)mui->landscape_entry_margin), thumbnail_y + (float)mui->thumbnail_height_max + ((float)mui->dip_base_unit_size / 10.0f) + - (float)mui->font_data.list.font_height, + (float)mui->font_data.list.line_height, (unsigned)usable_width, mui->entry_divider_width, width, @@ -3814,7 +3834,7 @@ static void materialui_render_header( int usable_title_bar_width = usable_sys_bar_width; size_t sys_bar_battery_width = 0; size_t sys_bar_clock_width = 0; - int sys_bar_text_y = (int)(((float)mui->sys_bar_height / 2.0f) + ((float)mui->font_data.hint.font_height / 4.0f)); + int sys_bar_text_y = (int)(((float)mui->sys_bar_height / 2.0f) + (float)mui->font_data.hint.line_centre_offset); int title_x = 0; bool show_back_icon = menu_entries_ctl(MENU_ENTRIES_CTL_SHOW_BACK, NULL); bool show_search_icon = mui->is_playlist || mui->is_file_list; @@ -4211,7 +4231,7 @@ static void materialui_render_header( gfx_display_draw_text(mui->font_data.title.font, menu_title_buf, title_x, - (int)(mui->sys_bar_height + (mui->title_bar_height / 2.0f) + (mui->font_data.title.font_height / 4.0f)), + (int)(mui->sys_bar_height + (mui->title_bar_height / 2.0f) + mui->font_data.title.line_centre_offset), width, height, mui->colors.header_text, TEXT_ALIGN_LEFT, 1.0f, false, 0, false); } @@ -5458,8 +5478,8 @@ static void materialui_set_thumbnail_dimensions(materialui_handle_t *mui) * > One line of list text + three lines of * hint text + padding */ mui->thumbnail_height_max = - mui->font_data.list.font_height + - (3 * mui->font_data.hint.font_height) + + mui->font_data.list.line_height + + (3 * mui->font_data.hint.line_height) + (mui->dip_base_unit_size / 10); /* Set thumbnail width based on max height @@ -5481,8 +5501,8 @@ static void materialui_set_thumbnail_dimensions(materialui_handle_t *mui) * > Two lines of list text + three lines of * hint text (no padding) */ mui->thumbnail_height_max = - (mui->font_data.list.font_height + - (3 * mui->font_data.hint.font_height)) * 2; + (mui->font_data.list.line_height + + (3 * mui->font_data.hint.line_height)) * 2; /* Set thumbnail width based on max height */ mui->thumbnail_width_max = @@ -5719,6 +5739,13 @@ static void materialui_layout(materialui_handle_t *mui, bool video_is_threaded) mui->entry_divider_width = (mui->last_scale_factor > 1.0f) ? (unsigned)(mui->last_scale_factor + 0.5f) : 1; + /* Additional vertical spacing between label and + * sublabel text */ + mui->sublabel_gap = mui->dip_base_unit_size / 42; + /* Additional horizontal padding inserted at the + * end of sublabel text to prevent line overflow */ + mui->sublabel_padding = mui->dip_base_unit_size / 20; + /* Note: We used to set scrollbar width here, but * since we now have several scrollbar parameters * that cannot be determined until materialui_compute_entries_box() @@ -5791,40 +5818,46 @@ static void materialui_layout(materialui_handle_t *mui, bool video_is_threaded) if (mui->font_data.title.font) { /* Calculate a more realistic ticker_limit */ - unsigned title_char_width = + int title_char_width = font_driver_get_message_width(mui->font_data.title.font, "a", 1, 1); - if (title_char_width) - mui->font_data.title.glyph_width = title_char_width; + if (title_char_width > 0) + mui->font_data.title.glyph_width = (unsigned)title_char_width; - /* Get font height */ - mui->font_data.title.font_height = font_driver_get_line_height(mui->font_data.title.font, 1.0f); + /* Get line metrics */ + mui->font_data.title.line_height = font_driver_get_line_height(mui->font_data.title.font, 1.0f); + mui->font_data.title.line_ascender = font_driver_get_line_ascender(mui->font_data.title.font, 1.0f); + mui->font_data.title.line_centre_offset = font_driver_get_line_centre_offset(mui->font_data.title.font, 1.0f); } if (mui->font_data.list.font) { /* Calculate a more realistic ticker_limit */ - unsigned list_char_width = + int list_char_width = font_driver_get_message_width(mui->font_data.list.font, "a", 1, 1); - if (list_char_width) - mui->font_data.list.glyph_width = list_char_width; + if (list_char_width > 0) + mui->font_data.list.glyph_width = (unsigned)list_char_width; - /* Get font height */ - mui->font_data.list.font_height = font_driver_get_line_height(mui->font_data.list.font, 1.0f); + /* Get line metrics */ + mui->font_data.list.line_height = font_driver_get_line_height(mui->font_data.list.font, 1.0f); + mui->font_data.list.line_ascender = font_driver_get_line_ascender(mui->font_data.list.font, 1.0f); + mui->font_data.list.line_centre_offset = font_driver_get_line_centre_offset(mui->font_data.list.font, 1.0f); } if (mui->font_data.hint.font) { /* Calculate a more realistic ticker_limit */ - unsigned hint_char_width = + int hint_char_width = font_driver_get_message_width(mui->font_data.hint.font, "t", 1, 1); - if (hint_char_width) - mui->font_data.hint.glyph_width = hint_char_width; + if (hint_char_width > 0) + mui->font_data.hint.glyph_width = (unsigned)hint_char_width; - /* Get font height */ - mui->font_data.hint.font_height = font_driver_get_line_height(mui->font_data.hint.font, 1.0f); + /* Get line metrics */ + mui->font_data.hint.line_height = font_driver_get_line_height(mui->font_data.hint.font, 1.0f); + mui->font_data.hint.line_ascender = font_driver_get_line_ascender(mui->font_data.hint.font, 1.0f); + mui->font_data.hint.line_centre_offset = font_driver_get_line_centre_offset(mui->font_data.hint.font, 1.0f); } /* When updating the layout, the system bar From 7fe952ddebb4024f1a216fd2eb79546b57c0ba0e Mon Sep 17 00:00:00 2001 From: Jamiras Date: Tue, 31 Mar 2020 11:08:35 -0600 Subject: [PATCH 05/14] don't ignore errors from decompress_v5_map --- libretro-common/formats/libchdr/libchdr_chd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libretro-common/formats/libchdr/libchdr_chd.c b/libretro-common/formats/libchdr/libchdr_chd.c index d076ee1291..698a6cc21a 100644 --- a/libretro-common/formats/libchdr/libchdr_chd.c +++ b/libretro-common/formats/libchdr/libchdr_chd.c @@ -826,14 +826,13 @@ chd_error chd_open_file(RFILE *file, int mode, chd_file *parent, chd_file **chd) if (newchd->header.version < 5) { err = map_read(newchd); - if (err != CHDERR_NONE) - EARLY_EXIT(err); } else { err = decompress_v5_map(newchd, &(newchd->header)); - (void)err; } + if (err != CHDERR_NONE) + EARLY_EXIT(err); #ifdef NEED_CACHE_HUNK /* allocate and init the hunk cache */ From 9d0585a2800b068106cc15686952db390ac9d609 Mon Sep 17 00:00:00 2001 From: Autechre Date: Tue, 31 Mar 2020 20:17:09 +0200 Subject: [PATCH 06/14] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index f3b7155289..60f223b2af 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,6 @@ # Future - AUTOCONFIG: Use correct port index in input device configured/disconnected notifications +- CHD: Fixes a crash caused by ignoring the return value from one of the CHD library functions. - MENU: Prevent font-related segfaults when using extremely small scales/window sizes - MENU: Fix 'gfx_display_draw_texture_slice()' - MENU/OZONE: Update timedate style options for Last Played sublabel metadata From 5a2e4237c4522155ecae0a9606a5b2e95d9e6d51 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Tue, 31 Mar 2020 00:57:59 +0200 Subject: [PATCH 07/14] Fix qnx compilation --- frontend/drivers/platform_qnx.c | 6 ------ input/drivers/qnx_input.c | 9 ++------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/frontend/drivers/platform_qnx.c b/frontend/drivers/platform_qnx.c index 0f249619b0..2396e6e089 100644 --- a/frontend/drivers/platform_qnx.c +++ b/frontend/drivers/platform_qnx.c @@ -102,8 +102,6 @@ static void frontend_qnx_get_environment_settings(int *argc, char *argv[], fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT], data_path, "layouts", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT])); #endif - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SHADERS], data_path, - "shaders", sizeof(g_defaults.dirs[DEFAULT_DIR_SHADERS])); /* user data */ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CHEATS], user_path, @@ -116,8 +114,6 @@ static void frontend_qnx_get_environment_settings(int *argc, char *argv[], "downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], user_path, "filters/audio", sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER])); - fill_pathname_join(g_defaults.dirs[DEFAULT_VIDEO_FILTER], user_path, - "filters/video", sizeof(g_defaults.dirs[DEFAULT_VIDEO_FILTER])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], user_path, "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP], user_path, @@ -130,8 +126,6 @@ static void frontend_qnx_get_environment_settings(int *argc, char *argv[], "states", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], user_path, "system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAIL], user_path, - "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAIL])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS], user_path, "wallpapers", sizeof(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, diff --git a/input/drivers/qnx_input.c b/input/drivers/qnx_input.c index 4b642f4a80..cd14bc143d 100644 --- a/input/drivers/qnx_input.c +++ b/input/drivers/qnx_input.c @@ -135,7 +135,6 @@ static void qnx_process_gamepad_event( int i; screen_device_t device; qnx_input_device_t* controller = NULL; - uint64_t *state_cur = NULL; (void)type; @@ -596,7 +595,6 @@ static void qnx_handle_screen_event(qnx_input_t *qnx, bps_event_t *event) static void qnx_handle_navigator_event( qnx_input_t *qnx, bps_event_t *event) { - navigator_window_state_t state; bps_event_t *event_pause = NULL; switch (bps_event_get_code(event)) @@ -652,9 +650,6 @@ static void qnx_handle_navigator_event( return; - togglemenu: - command_event(CMD_EVENT_MENU_TOGGLE, NULL); - return; shutdown: rarch_ctl(RARCH_CTL_SET_SHUTDOWN, NULL); return; @@ -808,7 +803,7 @@ static int16_t qnx_input_state(void *data, for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) { if (qnx_is_pressed( - qnx, joypad_info, port, binds[port], i)) + qnx, joypad_info, binds[port], port, i)) { ret |= (1 << i); continue; @@ -818,7 +813,7 @@ static int16_t qnx_input_state(void *data, return ret; } else - if (qnx_is_pressed(qnx, joypad_info, port, binds[port], id)) + if (qnx_is_pressed(qnx, joypad_info, binds[port], port, id)) return true; break; case RETRO_DEVICE_KEYBOARD: From c5e2099dd9f2581730655a32292c289e003c8abc Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 1 Apr 2020 16:47:38 +0200 Subject: [PATCH 08/14] Add makefile for qnx Usage: make -f Makefile.griffin platform=qnx clean all --- Makefile.griffin | 51 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/Makefile.griffin b/Makefile.griffin index 1f31a62650..1353cb54b4 100644 --- a/Makefile.griffin +++ b/Makefile.griffin @@ -75,15 +75,22 @@ ifeq ($(WHOLE_ARCHIVE_LINK), 1) WHOLE_END := -Wl,--no-whole-archive endif +STATIC_BUILD = 1 ifneq (,$(findstring msvc,$(platform))) - LIBS := $(WHOLE_START) $(WHOLE_END) -else + STATIC_BUILD = 0 +endif ifneq (,$(findstring unix,$(platform))) + STATIC_BUILD = 0 +endif +ifeq (qnx, $(platform)) + STATIC_BUILD = 0 +endif + +ifeq ($(STATIC_BUILD), 0) LIBS := $(WHOLE_START) $(WHOLE_END) else LIBS := $(WHOLE_START) -lretro_$(platform) $(WHOLE_END) endif -endif libogc_platform := @@ -791,6 +798,44 @@ else ifneq (,$(findstring windows_msvc2015,$(platform))) export INCLUDE := $(INCLUDE);libretro-common\include;libretro-common\include\compat\msvc;gfx\include;deps;deps\stb export LIB := $(LIB) endif +else ifeq (qnx,$(platform)) + HAVE_AUDIOMIXER := 1 + HAVE_RPNG := 1 + HAVE_RJPEG := 1 + HAVE_RBMP := 1 + HAVE_RTGA := 1 + HAVE_ZLIB := 1 + HAVE_7ZIP := 1 + HAVE_NETWORKING := 1 + HAVE_NETWORK_CMD := 1 + HAVE_NETPLAYDISCOVERY := 1 + HAVE_OVERLAY := 1 + HAVE_VIDEO_LAYOUT := 0 + HAVE_MATERIALUI := 1 + HAVE_XMB := 1 + HAVE_STB_FONT := 1 + HAVE_THREADS := 1 + HAVE_LIBRETRODB := 1 + HAVE_COMMAND := 1 + HAVE_STDIN_CMD := 1 + HAVE_CMD := 1 + HAVE_DYLIB := 1 + HAVE_DYNAMIC := 1 + HAVE_GRIFFIN_CPP := 0 + WANT_GLSLANG := 0 + HAVE_CONFIGFILE := 1 + CC=qcc -Vgcc_ntoarmv7le + CXX=QCC -Vgcc_ntoarmv7le + + ifeq ($(DEBUG), 1) + LDFLAGS += -g + endif + + PLATCFLAGS += -DHAVE_SHADERPIPELINE -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_OZONE -DHAVE_CC_RESAMPLER -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_FBO -DHAVE_GL_SYNC -DHAVE_GLSLANG -DHAVE_BUILTINGLSLANG -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_RUNAHEAD -DHAVE_GFX_WIDGETS -DHAVE_CONFIGFILE -DHAVE_SPIRV_CROSS -DHAVE_STB_FONT -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DHAVE_XMB -DRARCH_INTERNAL -DWANT_GLSLANG -DHAVE_XCB -DHAVE_EGL -DHAVE_BB10 -DHAVE_GLSL -DHAVE_AL -DRARCH_MOBILE + EXT_TARGET := $(TARGET_NAME) + EXT_INTER_TARGET := $(TARGET_NAME) + INCLUDE += -Ilibretro-common/include -Igfx/include -Ideps -Ideps/stb -Ideps/rcheevos/include -Ideps/SPIRV-Cross -Ideps/glslang -I. + LIBS += -lEGL -lbps -lscreen -lsocket -lm -lGLESv2 -lOpenAL else ifneq (,$(findstring unix,$(platform))) HAVE_AUDIOMIXER := 1 HAVE_RPNG := 1 From ab34a0a34f90cf5f418625bd09120f858ef6c1f2 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 1 Apr 2020 11:36:02 +0200 Subject: [PATCH 09/14] Handle errors in qnx_input I had errors with null driver. While this setup is not really usable, we shouldn't crash on it --- input/drivers/qnx_input.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/input/drivers/qnx_input.c b/input/drivers/qnx_input.c index cd14bc143d..01c5b53956 100644 --- a/input/drivers/qnx_input.c +++ b/input/drivers/qnx_input.c @@ -306,18 +306,35 @@ static void qnx_handle_device(qnx_input_t *qnx, } /* Find currently connected gamepads. */ -static void qnx_discover_controllers(qnx_input_t *qnx) +static int qnx_discover_controllers(qnx_input_t *qnx) { /* Get an array of all available devices. */ - int deviceCount; + int deviceCount = 0; + int ret; unsigned i; - screen_get_context_property_iv(screen_ctx, + ret = screen_get_context_property_iv(screen_ctx, SCREEN_PROPERTY_DEVICE_COUNT, &deviceCount); + if (ret < 0) { + RARCH_ERR("Error querying SCREEN_PROPERTY_DEVICE_COUNT: [%d] %s\n", + errno, strerror(errno)); + return false; + } screen_device_t* devices_found = (screen_device_t*) calloc(deviceCount, sizeof(screen_device_t)); - screen_get_context_property_pv(screen_ctx, + if (!devices_found) { + RARCH_ERR("Error allocating devices_found, deviceCount=%d\n", + deviceCount); + return false; + } + + ret = screen_get_context_property_pv(screen_ctx, SCREEN_PROPERTY_DEVICES, (void**)devices_found); + if (ret < 0) { + RARCH_ERR("Error querying SCREEN_PROPERTY_DEVICES: [%d] %s\n", + errno, strerror(errno)); + return false; + } /* Scan the list for gamepad and joystick devices. */ for(i = 0; i < qnx->pads_connected; ++i) @@ -347,6 +364,8 @@ static void qnx_discover_controllers(qnx_input_t *qnx) } free(devices_found); + + return true; } #endif From 2ff9bfb24da9880b90d79ac152f57b11a7851a20 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 1 Apr 2020 16:18:05 +0200 Subject: [PATCH 10/14] qnx: support analog sticks --- input/drivers/qnx_input.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/input/drivers/qnx_input.c b/input/drivers/qnx_input.c index 01c5b53956..0a65408fe3 100644 --- a/input/drivers/qnx_input.c +++ b/input/drivers/qnx_input.c @@ -835,6 +835,11 @@ static int16_t qnx_input_state(void *data, if (qnx_is_pressed(qnx, joypad_info, binds[port], port, id)) return true; break; + case RETRO_DEVICE_ANALOG: + if (binds[port]) + return input_joypad_analog(qnx->joypad, joypad_info, + port, idx, id, binds[port]); + return 0; case RETRO_DEVICE_KEYBOARD: return qnx_keyboard_pressed(qnx, id); case RETRO_DEVICE_POINTER: From c809ecd623138e7bbda241826202ca8eb4a1e74a Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 1 Apr 2020 16:27:58 +0200 Subject: [PATCH 11/14] Add qnx packaging Put your cores into pkg/qnx/pkg/assets/cores and info into pkg/qnx/pkg/assets/info. set QNX_DEBUGTOKEN to your debug token. Then: make -f Makefile.griffin platform=qnx clean retroarch-dev.bar To install: blackberry-deploy -installApp DEVICEIP retroarch-dev.bar -password YOURPASSWORD --- Makefile.griffin | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Makefile.griffin b/Makefile.griffin index 1353cb54b4..7398a72330 100644 --- a/Makefile.griffin +++ b/Makefile.griffin @@ -1141,7 +1141,12 @@ $(APP_BOOTER_DIR)/app_booter.bin: $(MAKE) -C $(APP_BOOTER_DIR) pkg: all -ifeq ($(platform), wii) +ifeq ($(platform), qnx) + mkdir -p pkg/qnx/pkg + cp -r $(EXT_TARGET) pkg/qnx/pkg/RetroArch + cp -r media/canvas.png pkg/qnx/pkg/canvas.png + cp -r media/retroarch-96x96.png pkg/qnx/pkg/retroarch-96x96.png +else ifeq ($(platform), wii) cp -r $(EXT_TARGET) pkg/wii/CORE.dol else ifeq ($(platform), ngc) cp -r $(EXT_TARGET) pkg/ngc/CORE.dol @@ -1149,6 +1154,18 @@ else ifeq ($(platform), psp1) psp-fixup-imports$(EXT) $(EXT_TARGET) endif +ifeq ($(platform), qnx) +retroarch-dev.bar: pkg +ifeq ($(QNX_DEBUGTOKEN),) + blackberry-nativepackager -package $@ -devMode pkg/qnx/bar-descriptor.xml -C pkg/qnx/pkg pkg/qnx/pkg/* +else + blackberry-nativepackager -package $@ -devMode -debugToken $(QNX_DEBUGTOKEN) pkg/qnx/bar-descriptor.xml -C pkg/qnx/pkg pkg/qnx/pkg/* +endif + +retroarch-release.bar: pkg + blackberry-nativepackager -package $@ pkg/qnx/bar-descriptor.xml -C pkg/qnx/pkg pkg/qnx/pkg/* +endif + shaders-checkout: @if test -d $(SHADER_CG_DIR); then \ echo "[SHADER CHECKOUT::] Git pulling common-shaders..."; \ From d0a9de01a35dad7255a1011844c6db5da2b53d77 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 1 Apr 2020 20:41:38 +0200 Subject: [PATCH 12/14] (GL) Fix unused variable setting --- gfx/drivers/gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index b1d2eaf3a9..88bf0bcc12 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -783,8 +783,8 @@ static void gl2_create_fbo_texture(gl_t *gl, bool smooth = false; settings_t *settings = config_get_ptr(); bool video_smooth = settings->bools.video_smooth; - bool video_ctx_scaling = settings->bools.video_ctx_scaling; #if HAVE_ODROIDGO2 + bool video_ctx_scaling = settings->bools.video_ctx_scaling; if (video_ctx_scaling) video_smooth = false; #endif From 8292f31ea0db0d057b8dde320080fd99687c8ba1 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 1 Apr 2020 20:43:03 +0200 Subject: [PATCH 13/14] Fix unused variable warning --- gfx/drivers/gl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 88bf0bcc12..19a03cc282 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -3996,9 +3996,8 @@ static void gl2_update_tex_filter_frame(gl_t *gl) bool smooth = false; settings_t *settings = config_get_ptr(); bool video_smooth = settings->bools.video_smooth; - bool video_ctx_scaling = settings->bools.video_ctx_scaling; - #ifdef HAVE_ODROIDGO2 + bool video_ctx_scaling = settings->bools.video_ctx_scaling; if (video_ctx_scaling) video_smooth = false; #endif From 2004545f96534ce8ef53bc744ade26df7e3b0c70 Mon Sep 17 00:00:00 2001 From: Autechre Date: Wed, 1 Apr 2020 21:00:15 +0200 Subject: [PATCH 14/14] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 60f223b2af..dda7fa474a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ - CHD: Fixes a crash caused by ignoring the return value from one of the CHD library functions. - MENU: Prevent font-related segfaults when using extremely small scales/window sizes - MENU: Fix 'gfx_display_draw_texture_slice()' +- MENU/FONT: Enable correct vertical alignment of text (+ font rendering fixes) - MENU/OZONE: Update timedate style options for Last Played sublabel metadata - MENU/OZONE: Hide 'Menu Color Theme' setting when 'Use preferred system color theme' is enabled - MENU/OZONE: Fix thumbnail switching via 'scan' button functionality