Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

11
backends/platform/libretro/.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
build/libs/
build/obj/
deps/
*.o
*.a
scummvm.zip
scummvm_libretro.*
config.mk.engines.lite
shared_modules.mk
script.mri
ScummVM.dat

View File

@@ -0,0 +1,267 @@
# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper)
##############################################################################
################################# BOILERPLATE ################################
##############################################################################
# Core definitions
.core-defs:
variables:
JNI_PATH: backends/platform/libretro
MAKEFILE_PATH: backends/platform/libretro
CORENAME: scummvm
.win-defs:
variables:
platform: win
# Inclusion templates, required for the build to work
include:
################################## DESKTOPS ################################
# Windows 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/windows-x64-mingw.yml'
# Windows 32-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/windows-i686-mingw.yml'
# Linux 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/linux-x64.yml'
# Linux 32-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/linux-i686.yml'
# MacOS 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/osx-x64.yml'
# MacOS ARM 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/osx-arm64.yml'
################################## CELLULAR ################################
# Android
- project: 'libretro-infrastructure/ci-templates'
file: '/android-jni.yml'
# iOS
- project: 'libretro-infrastructure/ci-templates'
file: '/ios-arm64.yml'
# iOS (armv7)
- project: 'libretro-infrastructure/ci-templates'
file: '/ios9.yml'
################################## CONSOLES ################################
# Nintendo Wii
- project: 'libretro-infrastructure/ci-templates'
file: '/wii-static.yml'
# Nintendo WiiU
- project: 'libretro-infrastructure/ci-templates'
file: '/wiiu-static.yml'
# Nintendo 3DS
- project: 'libretro-infrastructure/ci-templates'
file: '/ctr-legacy-static.yml'
# Nintendo Switch
- project: 'libretro-infrastructure/ci-templates'
file: '/libnx-static.yml'
# OpenDingux
- project: 'libretro-infrastructure/ci-templates'
file: '/dingux-mips32.yml'
# OpenDingux (ARM)
- project: 'libretro-infrastructure/ci-templates'
file: '/dingux-arm32.yml'
# PlayStation Vita
- project: 'libretro-infrastructure/ci-templates'
file: '/vita-static.yml'
# PlayStation3
- project: 'libretro-infrastructure/ci-templates'
file: '/psl1ght-static.yml'
# tvOS (AppleTV)
- project: 'libretro-infrastructure/ci-templates'
file: '/tvos-arm64.yml'
#################################### MISC ##################################
# Emscripten
- project: 'libretro-infrastructure/ci-templates'
file: '/emscripten-static.yml'
# Stages for building
stages:
- build-prepare
- build-shared
- build-static
##############################################################################
#################################### STAGES ##################################
##############################################################################
#
################################### DESKTOPS #################################
# Windows 64-bit
libretro-build-windows-x64:
extends:
- .libretro-windows-x64-mingw-make-default
- .core-defs
- .win-defs
variables:
TOOLSET: x86_64-w64-mingw32.static-
# Windows 64-bit
libretro-build-windows-i686:
extends:
- .libretro-windows-i686-mingw-make-default
- .core-defs
- .win-defs
variables:
TOOLSET: i686-w64-mingw32.static-
# Linux 64-bit
libretro-build-linux-x64:
extends:
- .libretro-linux-x64-make-default
- .core-defs
# Linux 32-bit
libretro-build-linux-i686:
extends:
- .libretro-linux-i686-make-default
- .core-defs
variables:
BUILD_64BIT: 0
# MacOS 64-bit
libretro-build-osx-x64:
tags:
- macosx-packaging
extends:
- .libretro-osx-x64-make-default
- .core-defs
# MacOS ARM 64-bit
libretro-build-osx-arm64:
tags:
- macosx-packaging
extends:
- .libretro-osx-arm64-make-default
- .core-defs
################################### CELLULAR #################################
# Android ARMv7a
android-armeabi-v7a:
extends:
- .libretro-android-jni-armeabi-v7a
- .core-defs
# Android ARMv8a
android-arm64-v8a:
extends:
- .libretro-android-jni-arm64-v8a
- .core-defs
# Android 64-bit x86
android-x86_64:
extends:
- .libretro-android-jni-x86_64
- .core-defs
# Android 32-bit x86
android-x86:
extends:
- .libretro-android-jni-x86
- .core-defs
# iOS
libretro-build-ios-arm64:
tags:
- macosx-packaging
extends:
- .libretro-ios-arm64-make-default
- .core-defs
# iOS (armv7) [iOS 9 and up]
libretro-build-ios9:
extends:
- .libretro-ios9-make-default
- .core-defs
# tvOS
libretro-build-tvos-arm64:
tags:
- macosx-packaging
extends:
- .libretro-tvos-arm64-make-default
- .core-defs
################################### CONSOLES #################################
# Nintendo Wii
libretro-build-wii:
extends:
- .libretro-wii-static-retroarch-master
- .core-defs
# Nintendo WiiU
libretro-build-wiiu:
extends:
- .libretro-wiiu-static-retroarch-master
- .core-defs
# Nintendo 3DS
libretro-build-ctr:
extends:
- .libretro-ctr-legacy-static-retroarch-master
- .core-defs
# Nintendo Switch
libretro-build-libnx-aarch64:
extends:
- .libretro-libnx-static-retroarch-master
- .core-defs
# OpenDingux
libretro-build-dingux-mips32:
extends:
- .libretro-dingux-mips32-make-default
- .core-defs
# OpenDingux Beta
libretro-build-dingux-odbeta-mips32:
extends:
- .libretro-dingux-odbeta-mips32-make-default
- .core-defs
# PlayStation Vita
libretro-build-vita:
extends:
- .libretro-vita-static-retroarch-master
- .core-defs
# PlayStation3
libretro-build-psl1ght:
extends:
- .libretro-psl1ght-static-retroarch-master
- .core-defs
# Miyoo
libretro-build-miyoo-arm32:
extends:
- .libretro-miyoo-arm32-make-default
- .core-defs
#################################### MISC ##################################
# Emscripten
libretro-build-emscripten:
extends:
- .libretro-emscripten-static-retroarch-master
- .core-defs

View File

@@ -0,0 +1,46 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
### Description
[Description of the bug]
### Expected behavior
[What you expected to happen]
### Actual behavior
[What is actually happening]
### Screenshots
[If applicable, add screenshots to help explain your problem]
### Steps to reproduce the bug
1. [First step]
2. [Second step]
3. [and so on...]
### Version/Commit
[You can find this information under Information->Core Information / System Information]
- ScummVM core: [version/commit]
- RetroArch: [version/commit]
### Working on stand-alone ScummVM
[Specify if the same issue also occurs with the daily build of stand-alone ScummVM]
### ScummVM game/engine
[Provide exact game version, better with ScummVM game ID]
### Environment information
- Device:
- OS: [The operating system you're running]
### RetroArch logs
[Provide RetroArch logs with DEBUG level set both for frontend and cores]
### Additional context
[Add any other context about the problem here]

View File

@@ -0,0 +1,722 @@
ROOT_PATH := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
# Output files prefix
TARGET_NAME = scummvm
HIDE := @
SPACE :=
SPACE := $(SPACE) $(SPACE)
BACKSLASH :=
BACKSLASH := \$(BACKSLASH)
filter_out1 = $(filter-out $(firstword $1),$1)
filter_out2 = $(call filter_out1,$(call filter_out1,$1))
unixpath = $(subst \,/,$1)
unixcygpath = /$(subst :,,$(call unixpath,$1))
ifeq ($(shell uname -a),)
EXE_EXT = .exe
endif
ifeq ($(BUILD_64BIT),)
ifeq (,$(findstring 64,$(platform) $(TOOLSET)))
BUILD_64BIT := 0
else
BUILD_64BIT := 1
endif
endif
TARGET_64BIT := $(BUILD_64BIT)
LD = $(CXX)
AR := ar cru
RANLIB := ranlib
LS := ls
MKDIR := mkdir -p
RM := rm -f
RM_REC := rm -rf
CP := cp
LDFLAGS :=
# Raspberry Pi 1
ifeq ($(platform), rpi1)
TARGET = $(TARGET_NAME)_libretro.so
DEFINES += -fPIC -D_ARM_ASSEM_ -DUSE_CXX11 -marm -DARM
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CFLAGS += -fPIC -marm -mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -fomit-frame-pointer -ffast-math
CXXFLAGS = $(CFLAGS) -frtti -std=c++11
HAVE_OPENGLES2 := 1
# Raspberry Pi 3
else ifeq ($(platform), rpi3)
TARGET = $(TARGET_NAME)_libretro.so
DEFINES += -fPIC -D_ARM_ASSEM_ -DUSE_CXX11 -marm -DARM
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CFLAGS += -fPIC -mcpu=cortex-a53 -mtune=cortex-a53 -fomit-frame-pointer -ffast-math
CXXFLAGS = $(CFLAGS) -frtti -std=c++11
HAVE_OPENGLES2 := 1
HAVE_NEON := 1
# Raspberry Pi 3 (64 bit)
else ifeq ($(platform), rpi3_64)
TARGET = $(TARGET_NAME)_libretro.so
DEFINES += -fPIC -D_ARM_ASSEM_ -DUSE_CXX11 -DARM -DDEFAULT_PERF_TUNER
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CFLAGS += -fPIC -mcpu=cortex-a53 -mtune=cortex-a53 -fomit-frame-pointer -ffast-math
CXXFLAGS = $(CFLAGS) -frtti -std=c++11
HAVE_OPENGLES2 := 1
HAVE_NEON := 1
# Raspberry Pi 5 (64 bit)
else ifeq ($(platform), rpi5_64)
TARGET = $(TARGET_NAME)_libretro.so
DEFINES += -fPIC -D_ARM_ASSEM_ -DUSE_CXX11 -DARM
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CFLAGS += -fPIC -mcpu=cortex-a76 -mtune=cortex-a76 -fomit-frame-pointer -ffast-math
CXXFLAGS = $(CFLAGS) -frtti -std=c++11
HAVE_OPENGLES2 := 1
HAVE_NEON := 1
# Raspberry Pi 4 (64 bit)
else ifeq ($(platform), rpi4_64)
TARGET = $(TARGET_NAME)_libretro.so
DEFINES += -fPIC -D_ARM_ASSEM_ -DUSE_CXX11 -DARM
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CFLAGS += -fPIC -mcpu=cortex-a72 -mtune=cortex-a72 -fomit-frame-pointer -ffast-math
CXXFLAGS = $(CFLAGS) -frtti -std=c++11
HAVE_OPENGLES2 := 1
HAVE_NEON := 1
# webOS (32 bit)
else ifeq ($(platform), webos)
TARGET = $(TARGET_NAME)_libretro.so
DEFINES += -fPIC -D_ARM_ASSEM_ -DUSE_CXX11 -marm -DARM
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC -static-libgcc -static-libstdc++
CFLAGS += -fPIC -mcpu=cortex-a9 -mtune=cortex-a53 -mfloat-abi=softfp -fomit-frame-pointer -ffast-math
CXXFLAGS = $(CFLAGS) -frtti -std=c++11
HAVE_OPENGLES2 := 1
HAVE_NEON := 1
# iOS
else ifneq (,$(findstring ios,$(platform)))
TARGET := $(TARGET_NAME)_libretro_ios.dylib
DEFINES += -fPIC -DHAVE_POSIX_MEMALIGN=1 -DIOS
LDFLAGS += -dynamiclib -fPIC
MINVERSION :=
HAVE_OPENGLES2 := 1
HAVE_NEON := 1
ifeq ($(IOSSDK),)
IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path)
endif
ifeq ($(platform),ios-arm64)
CC = cc -arch arm64 -isysroot $(IOSSDK)
CXX = c++ -arch arm64 -isysroot $(IOSSDK)
else
CC = cc -arch armv7 -isysroot $(IOSSDK)
CXX = c++ -arch armv7 -isysroot $(IOSSDK)
DEFINES = -marm -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon
endif
ifeq ($(platform),$(filter $(platform),ios9 ios-arm64))
MINVERSION += -miphoneos-version-min=8.0
else
MINVERSION += -miphoneos-version-min=5.0
endif
CFLAGS += $(MINVERSION)
CXXFLAGS += $(MINVERSION) -std=c++11
else ifeq ($(platform), tvos-arm64)
EXT?=dylib
TARGET := $(TARGET_NAME)_libretro_tvos.$(EXT)
DEFINES += -fPIC -DHAVE_POSIX_MEMALIGN=1 -DIOS
LDFLAGS += -dynamiclib -fPIC
HAVE_OPENGLES2 := 1
HAVE_NEON := 1
ifeq ($(IOSSDK),)
IOSSDK := $(shell xcodebuild -version -sdk appletvos Path)
endif
CC = cc -arch arm64 -isysroot $(IOSSDK)
CXX = c++ -arch arm64 -isysroot $(IOSSDK) -std=c++11
# QNX
else ifeq ($(platform), qnx)
TARGET := $(TARGET_NAME)_libretro_$(platform).so
DEFINES += -fPIC -DSYSTEM_NOT_SUPPORTING_D_TYPE -DDEFAULT_PERF_TUNER
DEFINES += -D__BLACKBERRY_QNX__ -marm -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CC = qcc -Vgcc_ntoarmv7le
CXX = QCC -Vgcc_ntoarmv7le
LD = QCC -Vgcc_ntoarmv7le
AR = qcc -Vgcc_ntoarmv7le -A
RANLIB="${QNX_HOST}/usr/bin/ntoarmv7-ranlib"
HAVE_OPENGLES2 := 1.
HAVE_NEON := 1
# Genode
else ifeq ($(platform), genode)
TARGET := $(TARGET_NAME)_libretro_$(platform).so
DEFINES += -fPIC -DSYSTEM_NOT_SUPPORTING_D_TYPE -DDEFAULT_PERF_TUNER
C_PKGS = libc
CXX_PKGS = stdcxx genode-base
CFLAGS += -D__GENODE__ $(shell pkg-config --cflags $(C_PKGS))
CXXFLAGS += -D__GENODE__ $(shell pkg-config --cflags $(CXX_PKGS))
LIBS += $(shell pkg-config --libs $(C_PKGS) $(CXX_PKGS) genode-lib)
CC = $(shell pkg-config genode-base --variable=cc)
CXX = $(shell pkg-config genode-base --variable=cxx)
LD = $(shell pkg-config genode-base --variable=ld)
AR = $(shell pkg-config genode-base --variable=ar) rcs
RANLIB = genode-x86-ranlib
HAVE_OPENGL := 1
# Lightweight PS3 Homebrew SDK
else ifneq (,$(filter $(platform), ps3 psl1ght))
TARGET := $(TARGET_NAME)_libretro_$(platform).a
CC = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)gcc$(EXE_EXT)
CXX = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)g++$(EXE_EXT)
AR = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)ar$(EXE_EXT) rcs
DEFINES := -DPLAYSTATION3 -D__PS3__ -DRETRO_IS_BIG_ENDIAN=1 -DRETRO_IS_LITTLE_ENDIAN=0 -DWORDS_BIGENDIAN=1 -mcpu=cell -mno-fp-in-toc -I$(PS3DEV)/ppu/include
ifeq ($(platform), psl1ght)
DEFINES += -D__PSL1GHT__
CFLAGS += -mvsx -mvsx-timode
CXXFLAGS += -mvsx -mvsx-timode
HAVE_OPENGL := 1
endif
STATIC_LINKING = 1
# Nintendo Wii
else ifeq ($(platform), wii)
TARGET := $(TARGET_NAME)_libretro_wii.a
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) rcs
DEFINES += -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float -D__ppc__ -I$(DEVKITPRO)/libogc/include -DDEFAULT_PERF_TUNER -DRETRO_IS_BIG_ENDIAN=1 -DRETRO_IS_LITTLE_ENDIAN=0 -DWORDS_BIGENDIAN=1
LITE := 1
STATIC_LINKING = 1
# Nintendo Switch (libnx)
else ifeq ($(platform), libnx)
export DEPSDIR := $(CURDIR)
include $(DEVKITPRO)/libnx/switch_rules
EXT=a
TARGET := $(TARGET_NAME)_libretro_$(platform).$(EXT)
AR = $(DEVKITPRO)/devkitA64/aarch64-none-elf/bin/ar$(EXE_EXT) rcs
DEFINES := -DSWITCH=1 -U__linux__ -U__linux
DEFINES += -g -O3 -fPIE -I$(LIBNX)/include/ -ffunction-sections -fdata-sections -ftls-model=local-exec -ffast-math -mcpu=cortex-a57+crc+fp+simd -march=armv8-a -mtune=cortex-a57 -mtp=soft
DEFINES += $(INCDIRS)
DEFINES += -D__SWITCH__ -DHAVE_LIBNX -D__arm64__ -D__ARM_NEON__
CXXFLAGS += $(ASFLAGS) -std=gnu++11 -fpermissive
STATIC_LINKING = 1
HAVE_OPENGL := 1
HAVE_NEON := 1
# Nintendo Wii U
else ifeq ($(platform), wiiu)
TARGET := $(TARGET_NAME)_libretro_wiiu.a
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) rcs
AR_ALONE = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT)
DEFINES += -mwup -mcpu=750 -meabi -mhard-float -D__POWERPC__ -D__ppc__ -DRETRO_IS_BIG_ENDIAN=1 -DRETRO_IS_LITTLE_ENDIAN=0 -DWORDS_BIGENDIAN=1
DEFINES += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int
DEFINES += -DHAVE_STRTOUL -DWIIU
CXXFLAGS := -fpermissive
LITE := 1
STATIC_LINKING = 1
# Nintendo 3DS
else ifeq ($(platform), ctr)
TARGET := $(TARGET_NAME)_libretro_$(platform).a
CC = $(DEVKITARM)/bin/arm-none-eabi-gcc$(EXE_EXT)
CXX = $(DEVKITARM)/bin/arm-none-eabi-g++$(EXE_EXT)
AR = $(DEVKITARM)/bin/arm-none-eabi-ar$(EXE_EXT) rcs
RANLIB = $(DEVKITARM)/bin/arm-none-eabi-ranlib$(EXE_EXT)
ifeq ($(strip $(CTRULIB)),)
$(error "Please set CTRULIB in your environment. export CTRULIB=<path to>libctru")
endif
DEFINES += -DARM11 -D_3DS -D__3DS__ -DARM -I$(CTRULIB)/include
DEFINES += -march=armv6k -mtune=mpcore -mfloat-abi=hard
DEFINES += -Wall -mword-relocations
DEFINES += -fomit-frame-pointer -ffast-math -DDEFAULT_PERF_TUNER
CXXFLAGS += -std=gnu++11 -fpermissive
USE_VORBIS = 0
USE_THEORADEC = 0
USE_TREMOR = 1
USE_MT32EMU = 0
STATIC_LINKING = 1
# Vita
else ifeq ($(platform), vita)
TARGET := $(TARGET_NAME)_libretro_$(platform).a
CC = arm-vita-eabi-gcc$(EXE_EXT)
CXX = arm-vita-eabi-g++$(EXE_EXT)
AR = arm-vita-eabi-ar$(EXE_EXT) rcs
DEFINES += -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=hard -mfpu=neon -marm
DEFINES += -fno-optimize-sibling-calls -mlong-calls -mword-relocations
DEFINES += -DVITA -DREDUCE_MEMORY_USAGE -DUNCACHED_PLUGINS -DPSP2 -DSYSTEM_NOT_SUPPORTING_D_TYPE
USE_LIBCO = 0
LITE := 1
STATIC_LINKING = 1
HAVE_OPENGLES2 := 1
HAVE_NEON := 1
# GCW0
else ifeq ($(platform), gcw0)
TARGET := $(TARGET_NAME)_libretro.so
CC = /opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc
CXX = /opt/gcw0-toolchain/usr/bin/mipsel-linux-g++
LD = /opt/gcw0-toolchain/usr/bin/mipsel-linux-g++
AR = /opt/gcw0-toolchain/usr/bin/mipsel-linux-ar cru
RANLIB = /opt/gcw0-toolchain/usr/bin/mipsel-linux-ranlib
DEFINES += -DDINGUX -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float -fPIC
DEFINES += -DPRId64=\"lld\" -DPRIu64=\"llu\"
DEFINES += -ffunction-sections -fdata-sections -DDEFAULT_PERF_TUNER
LDFLAGS += -shared -Wl,--gc-sections -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CFLAGS += -std=gnu99
CXXFLAGS += -std=c++11
HAVE_OPENGLES2 := 1
USE_VORBIS = 0
USE_THEORADEC = 0
USE_TREMOR = 1
USE_LIBCO = 0
USE_CURL = 0
USE_MT32EMU = 0
USE_HIGHRES := 0
USE_IMGUI := 0
# MIYOO
else ifeq ($(platform), miyoo)
TARGET := $(TARGET_NAME)_libretro.so
CC = /opt/miyoo/usr/bin/arm-linux-gcc
CXX = /opt/miyoo/usr/bin/arm-linux-g++
LD = /opt/miyoo/usr/bin/arm-linux-g++
AR = /opt/miyoo/usr/bin/arm-linux-ar cru
RANLIB = /opt/miyoo/usr/bin/arm-linux-ranlib
DEFINES += -DDINGUX -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s -fPIC
DEFINES += -ffunction-sections -fdata-sections -DDEFAULT_PERF_TUNER -DREDUCE_MEMORY_USAGE -DUNCACHED_PLUGINS
LDFLAGS += -shared -Wl,--gc-sections -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
USE_VORBIS = 0
USE_THEORADEC = 0
USE_TREMOR = 1
USE_LIBCO = 0
USE_CURL = 0
USE_MT32EMU = 0
USE_HIGHRES := 0
# MIYOOMINI
else ifeq ($(platform), miyoomini)
TARGET := $(TARGET_NAME)_libretro.so
CC = /usr/bin/arm-linux-gnueabihf-gcc
CXX = /usr/bin/arm-linux-gnueabihf-g++
LD = /usr/bin/arm-linux-gnueabihf-g++
AR = /usr/bin/arm-linux-gnueabihf-ar cru
RANLIB = /usr/bin/arm-linux-gnueabihf-ranlib
DEFINES += -fomit-frame-pointer -ffast-math -marm -march=armv7ve+simd -mtune=cortex-a7 -fPIC
DEFINES += -ffunction-sections -fdata-sections -DDEFAULT_PERF_TUNER -DREDUCE_MEMORY_USAGE -DUNCACHED_PLUGINS
LDFLAGS += -shared -Wl,--gc-sections -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
USE_VORBIS = 0
USE_THEORADEC = 0
USE_TREMOR = 1
USE_LIBCO = 0
USE_MT32EMU = 0
USE_HIGHRES = 0
# ARM v7
else ifneq (,$(findstring armv7,$(platform)))
TARGET := $(TARGET_NAME)_libretro.so
DEFINES += -fPIC -D_ARM_ASSEM_ -DUSE_CXX11 -marm -DARM -DDEFAULT_PERF_TUNER
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
USE_VORBIS = 0
USE_THEORADEC = 0
USE_TREMOR = 1
USE_MT32EMU = 0
CXXFLAGS := -std=c++11
ifneq (,$(findstring cortexa8,$(platform)))
DEFINES += -marm -mcpu=cortex-a8
else ifneq (,$(findstring cortexa9,$(platform)))
DEFINES += -marm -mcpu=cortex-a9
endif
ifneq (,$(findstring neon,$(platform)))
DEFINES += -mfpu=neon
HAVE_NEON := 1
endif
ifneq (,$(findstring softfloat,$(platform)))
DEFINES += -mfloat-abi=softfp
else ifneq (,$(findstring hardfloat,$(platform)))
DEFINES += -mfloat-abi=hard
endif
HAVE_OPENGLES2 := 1
# ARM v8
else ifneq (,$(findstring armv8,$(platform)))
TARGET := $(TARGET_NAME)_libretro.so
DEFINES += -fPIC -D_ARM_ASSEM_ -DARM -marm -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -march=armv8-a+crc -DDEFAULT_PERF_TUNER
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CFLAGS += -fPIC
HAVE_NEON := 1
HAVE_OPENGLES2 := 1
# Odroid Go Advance
else ifneq (,$(findstring odroidgo2,$(platform)))
TARGET := $(TARGET_NAME)_libretro.so
DEFINES += -fPIC -D_ARM_ASSEM_ -DARM -DUSE_CXX11 -marm -mtune=cortex-a35 -mfpu=neon-fp-armv8 -mfloat-abi=hard -march=armv8-a+crc
DEFINES += -fPIC -D_ARM_ASSEM_ -DUSE_CXX11 -DARM
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CFLAGS += -fPIC -mcpu=cortex-a35 -fomit-frame-pointer -ffast-math
CXXFLAGS = $(CFLAGS) -frtti -std=c++11
HAVE_OPENGLES2 := 1
HAVE_NEON = 1
# RG353x
else ifneq (,$(findstring rg353x,$(platform)))
TARGET = $(TARGET_NAME)_libretro.so
DEFINES += -fPIC -D_ARM_ASSEM_ -DUSE_CXX11 -DARM
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CFLAGS += -fPIC -mcpu=cortex-a55 -mtune=cortex-a55 -fomit-frame-pointer -ffast-math
CXXFLAGS = $(CFLAGS) -frtti -std=c++11
HAVE_OPENGLES2 := 1
HAVE_NEON = 1
# Emscripten
else ifeq ($(platform), emscripten)
TARGET := $(TARGET_NAME)_libretro_$(platform).bc
AR_ALONE := emar
AR := emar rcs
DEFINES += -DEMSCRIPTEN -DUSE_CXX11
CXXFLAGS += -std=c++11
STATIC_LINKING = 1
USE_LIBCO = 0
# Windows MSVC 2017 all architectures
else ifneq (,$(findstring windows_msvc2017,$(platform)))
NO_GCC := 1
CFLAGS += -DNOMINMAX
CXXFLAGS += -DNOMINMAX
WINDOWS_VERSION = 1
PlatformSuffix = $(subst windows_msvc2017_,,$(platform))
ifneq (,$(findstring desktop,$(PlatformSuffix)))
WinPartition = desktop
MSVC2017CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -FS
LDFLAGS += -MANIFEST -LTCG:incremental -NXCOMPAT -DYNAMICBASE -DEBUG -OPT:REF -INCREMENTAL:NO -SUBSYSTEM:WINDOWS -MANIFESTUAC:"level='asInvoker' uiAccess='false'" -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1
LIBS += kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
else ifneq (,$(findstring uwp,$(PlatformSuffix)))
WinPartition = uwp
MSVC2017CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_APP -D_WINDLL -D_UNICODE -DUNICODE -D__WRL_NO_DEFAULT_LIB__ -EHsc -FS
LDFLAGS += -APPCONTAINER -NXCOMPAT -DYNAMICBASE -MANIFEST:NO -LTCG -OPT:REF -SUBSYSTEM:CONSOLE -MANIFESTUAC:NO -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1 -DEBUG:FULL -WINMD:NO
LIBS += WindowsApp.lib
endif
CFLAGS += $(MSVC2017CompileFlags)
CXXFLAGS += $(MSVC2017CompileFlags)
TargetArchMoniker = $(subst $(WinPartition)_,,$(PlatformSuffix))
CC = cl.exe
CXX = cl.exe
LD = link.exe
reg_query = $(call filter_out2,$(subst $2,,$(shell reg query "$2" -v "$1" 2>nul)))
fix_path = $(subst $(SPACE),\ ,$(subst \,/,$1))
ProgramFiles86w := $(shell cmd /c "echo %PROGRAMFILES(x86)%")
ProgramFiles86 := $(shell cygpath "$(ProgramFiles86w)")
WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0)
WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0)
WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0)
WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0)
WindowsSdkDir := $(WindowsSdkDir)
WindowsSDKVersion ?= $(firstword $(foreach folder,$(subst $(subst \,/,$(WindowsSdkDir)Include/),,$(wildcard $(call fix_path,$(WindowsSdkDir)Include\*))),$(if $(wildcard $(call fix_path,$(WindowsSdkDir)Include/$(folder)/um/Windows.h)),$(folder),)))$(BACKSLASH)
WindowsSDKVersion := $(WindowsSDKVersion)
VsInstallBuildTools = $(ProgramFiles86)/Microsoft Visual Studio/2017/BuildTools
VsInstallEnterprise = $(ProgramFiles86)/Microsoft Visual Studio/2017/Enterprise
VsInstallProfessional = $(ProgramFiles86)/Microsoft Visual Studio/2017/Professional
VsInstallCommunity = $(ProgramFiles86)/Microsoft Visual Studio/2017/Community
VsInstallRoot ?= $(shell if [ -d "$(VsInstallBuildTools)" ]; then echo "$(VsInstallBuildTools)"; fi)
ifeq ($(VsInstallRoot), )
VsInstallRoot = $(shell if [ -d "$(VsInstallEnterprise)" ]; then echo "$(VsInstallEnterprise)"; fi)
endif
ifeq ($(VsInstallRoot), )
VsInstallRoot = $(shell if [ -d "$(VsInstallProfessional)" ]; then echo "$(VsInstallProfessional)"; fi)
endif
ifeq ($(VsInstallRoot), )
VsInstallRoot = $(shell if [ -d "$(VsInstallCommunity)" ]; then echo "$(VsInstallCommunity)"; fi)
endif
VsInstallRoot := $(VsInstallRoot)
VcCompilerToolsVer := $(shell cat "$(VsInstallRoot)/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt" | grep -o '[0-9\.]*')
VcCompilerToolsDir := $(VsInstallRoot)/VC/Tools/MSVC/$(VcCompilerToolsVer)
WindowsSDKSharedIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\shared")
WindowsSDKUCRTIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\ucrt")
WindowsSDKUMIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\um")
WindowsSDKUCRTLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib\$(WindowsSDKVersion)\ucrt\$(TargetArchMoniker)")
WindowsSDKUMLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib\$(WindowsSDKVersion)\um\$(TargetArchMoniker)")
# For some reason the HostX86 compiler doesn't like compiling for x64
# ("no such file" opening a shared library), and vice-versa.
# Work around it for now by using the strictly x86 compiler for x86, and x64 for x64.
# NOTE: What about ARM?
ifneq (,$(findstring x64,$(TargetArchMoniker)))
VCCompilerToolsBinDir := $(VcCompilerToolsDir)\bin\HostX64
else
VCCompilerToolsBinDir := $(VcCompilerToolsDir)\bin\HostX86
endif
PATH := $(shell IFS=$$'\n'; cygpath "$(VCCompilerToolsBinDir)/$(TargetArchMoniker)"):$(PATH)
PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VsInstallRoot)/Common7/IDE")
INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/include")
LIB := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/lib/$(TargetArchMoniker)")
ifneq (,$(findstring uwp,$(PlatformSuffix)))
LIB := $(LIB);$(shell IFS=$$'\n'; cygpath -w "$(LIB)/store")
endif
export INCLUDE := $(INCLUDE);$(WindowsSDKSharedIncludeDir);$(WindowsSDKUCRTIncludeDir);$(WindowsSDKUMIncludeDir)
export LIB := $(LIB);$(WindowsSDKUCRTLibDir);$(WindowsSDKUMLibDir)
TARGET := $(TARGET_NAME)_libretro.dll
PSS_STYLE :=2
LDFLAGS += -DLL
HAVE_OPENGL := 1
else ifeq ($(platform), win)
# let out for next test block
else ifeq ($(platform), osx)
# let out for next test block
else ifeq ($(platform), unix)
# let out for next test block
else
# Nothing found for specified platform or none set
override platform = unix
ifeq ($(shell uname -a),)
override platform = win
else ifneq ($(findstring MINGW,$(shell uname -a)),)
override platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
override platform = osx
override arch = intel
ifeq ($(shell uname -p),arm64)
override arch = arm
endif
ifeq ($(shell uname -p),powerpc)
override arch = ppc
endif
else ifneq ($(findstring win,$(shell uname -a)),)
override platform = win
endif
ifeq (,$(findstring 64,$(shell uname -m)))
BUILD_64BIT := 0
else
BUILD_64BIT := 1
endif
TARGET_64BIT := $(BUILD_64BIT)
endif
# Unix fallback
ifeq ($(platform), unix)
TARGET := $(TARGET_NAME)_libretro.so
DEFINES += -DHAVE_POSIX_MEMALIGN=1 -DUSE_CXX11
LDFLAGS += -shared -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
CFLAGS += -fPIC
CXXFLAGS += $(CFLAGS) -std=c++11
HAVE_OPENGL := 1
# Win fallback
else ifeq ($(platform), win)
CC ?= gcc
TARGET := $(TARGET_NAME)_libretro.dll
DEFINES += -DHAVE_FSEEKO -DHAVE_INTTYPES_H -fPIC
CXXFLAGS += -fno-permissive
LDFLAGS += -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=$(ROOT_PATH)/link.T -fPIC
ifneq ($(TARGET_64BIT),1)
DEFINES += -DRETRO_CALLCONV=__cdecl
endif
HAVE_OPENGL := 1
# OS X
else ifeq ($(platform), osx)
TARGET := $(TARGET_NAME)_libretro.dylib
DEFINES += -fPIC -Wno-undefined-var-template -Wno-pragma-pack -DHAVE_POSIX_MEMALIGN=1 -DUSE_CXX11
LDFLAGS += -dynamiclib -fPIC
CXXFLAGS := -std=c++11
HAVE_OPENGL := 0 # cocoagl does not support GLAD
ifeq ($(CROSS_COMPILE),1)
TARGET_RULE = -target $(LIBRETRO_APPLE_PLATFORM) -isysroot $(LIBRETRO_APPLE_ISYSROOT)
CFLAGS += $(TARGET_RULE)
CPPFLAGS += $(TARGET_RULE)
CXXFLAGS += $(TARGET_RULE)
LDFLAGS += $(TARGET_RULE)
# Hardcode TARGET_64BIT for now
TARGET_64BIT = 1
endif
endif
ifneq (,$(findstring $(platform), wiiu vita))
DEFINES += -Os
else ifneq (,$(findstring $(platform), ios osx))
DEFINES += -O1
else ifneq (,$(findstring armv7, $(platform))) # fixes a GCC 15.1 internal compiler error. TODO check if it is fixed in GCC newer releases.
DEFINES += -O1
else ifneq (,$(findstring $(platform), msvc genode rpi))
DEFINES += -O2
else
DEFINES += -O3
endif
ifeq ($(TARGET_64BIT), 1)
DEFINES += -DSIZEOF_SIZE_T=8 -DSCUMM_64BITS
else
DEFINES += -DSIZEOF_SIZE_T=4
endif
# Define toolset
ifdef TOOLSET
CC = $(TOOLSET)gcc
CXX = $(TOOLSET)g++
LD = $(TOOLSET)g++
AR = $(TOOLSET)ar cru
RANLIB = $(TOOLSET)ranlib
endif
# Define build flags
DEPDIR = .deps
CXXFLAGS += -Wno-reorder
# Compile platform specific parts (e.g. filesystem)
ifeq ($(platform), win)
WIN32 = 1
DEFINES += -DWIN32 -DUSE_CXX11
CXXFLAGS += -std=c++11
LIBS += -lwinmm
endif
$(info Platform is $(platform) $(shell test $(TARGET_64BIT) = 1 && echo 64bit || echo 32bit))
include $(ROOT_PATH)/Makefile.common
######################################################################
# The build rules follow - normally you should have no need to
# touch whatever comes after here.
######################################################################
# Concat DEFINES and INCLUDES to form the CPPFLAGS
CPPFLAGS := $(DEFINES) $(INCLUDES)
CXXFLAGS += $(DEFINES) $(INCLUDES)
CFLAGS += $(DEFINES) $(INCLUDES)
# Include the build instructions for all modules
include $(addprefix $(SCUMMVM_PATH)/, $(addsuffix /module.mk,$(MODULES)))
include $(ROOT_PATH)/overrides.mk
# Depdir information
DEPDIRS := $(addsuffix $(DEPDIR),$(MODULE_PATHS))
# Hack for libnx DEPSDIR issues
libnx-ln:
ifeq ($(platform), libnx)
ln -s $(SCUMMVM_PATH)/audio/ audio
ln -s $(SCUMMVM_PATH)/backends/ backends
ln -s $(SCUMMVM_PATH)/base/ base
ln -s $(SCUMMVM_PATH)/common/ common
ln -s $(SCUMMVM_PATH)/engines/ engines
ln -s $(SCUMMVM_PATH)/graphics/ graphics
ln -s $(SCUMMVM_PATH)/gui/ gui
ln -s $(SCUMMVM_PATH)/image/ image
ln -s $(SCUMMVM_PATH)/video/ video
touch libnx-ln
endif
OBJOUT = -o
LINKOUT = -o
ifneq (,$(findstring msvc,$(platform)))
OBJOUT = -Fo
LINKOUT = -out:
ifeq ($(STATIC_LINKING),1)
LD ?= lib.exe
STATIC_LINKING=0
else
LD ?= link.exe
endif
endif
ifneq (,$(filter $(platform), wiiu emscripten))
$(TARGET): $(OBJS) libdeps.a libdetect.a
$(MKDIR) libtemp
$(CP) $+ libtemp/
$(AR_ALONE) -M < $(ROOT_PATH)/script.mri
else ifeq ($(platform), libnx)
$(TARGET): libnx-ln $(OBJS) libdeps.a libdetect.a
$(MKDIR) libtemp
cp $+ libtemp/
$(AR) -M < $(ROOT_PATH)/script.mri
else ifeq ($(STATIC_LINKING), 1)
$(TARGET): $(OBJS) libdeps.a libdetect.a
$(MKDIR) libtemp
$(CP) $+ libtemp/
@echo Linking $@...
$(AR) -M < $(ROOT_PATH)/script.mri
else
$(TARGET): $(DETECT_OBJS) $(OBJS) libdeps.a
@echo Linking $@...
$(HIDE)$(LD) $(LDFLAGS) $+ $(LIBS) $(LINKOUT)$@
endif
libdeps.a: $(OBJS_DEPS)
@echo Linking $@...
$(HIDE)$(AR) $@ $^
libdetect.a: $(DETECT_OBJS)
@echo Linking $@...
$(HIDE)$(AR) $@ $^
%.o: %.c
@echo Compiling $(<F)...
@$(MKDIR) $(*D)
$(HIDE)$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<
%.o: %.cpp
@echo Compiling $(<F)...
@$(MKDIR) $(*D)
$(HIDE)$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
# Create empty config.mk, if required by any module.mk (e.g. audio/softsynth/mt32/module.mk)
config.mk:
@touch config.mk
# Dumb compile rule, for C++ compilers that don't allow dependency tracking or
# where it is broken (such as GCC 2.95).
.cpp.o:
@$(MKDIR) $(*D)
@echo Compiling $<...
$(HIDE)$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(<) $(OBJOUT)$*.o
clean:
@echo Cleaning project...
$(HIDE)$(RM_REC) $(DEPDIRS) $(DEPS_PATH)
$(HIDE)$(RM) $(OBJS) $(DETECT_OBJS) $(OBJS_DEPS) libdeps.a libdetect.a $(TARGET) *.a
$(HIDE)$(RM_REC) libtemp $(MODULES)
$(HIDE)$(RM) libnx-ln
$(HIDE)$(RM) scummvm.zip $(TARGET_NAME)_libretro.* script.mri config.mk.engines.lite ScummVM.dat
$(HIDE)$(RM) $(ROOT_PATH)/shared_modules.mk $(SCUMMVM_PATH)/engines/engines.mk $(SCUMMVM_PATH)/engines/detection_table.h $(SCUMMVM_PATH)/engines/plugins_table.h
# Include the dependency tracking files.
-include $(wildcard $(addsuffix /*.d,$(DEPDIRS)))
# Mark *.d files and most *.mk files as PHONY. This stops make from trying to
# recreate them (which it can't), and in particular from looking for potential
# source files. This can save quite a bit of disk access time.
.PHONY: $(wildcard $(addsuffix /*.d,$(DEPDIRS))) $(addprefix $(SCUMMVM_PATH)/, $(addsuffix /module.mk,$(MODULES))) \
$(SCUMMVM_PATH)/$(port_mk) $(SCUMMVM_PATH)/rules.mk $(SCUMMVM_PATH)/engines/engines.mk
.PHONY: clean

View File

@@ -0,0 +1,356 @@
######################################################################
# Common settings and defaults
######################################################################
# Reset flags (DEFINES not reset as used in Makefile)
INCLUDES :=
OBJS_DEPS :=
OBJS :=
DETECT_OBJS :=
$(foreach MODULE,$(MODULES),$(MODULE_OBJS-$(MODULE)) :=)
MODULES :=
# Defaults
LOAD_RULES_MK = 1
POSIX = 1
USE_RGB_COLOR = 1
ENABLE_VKEYBD = 1
HAVE_GCC3 = 1
STATIC_LINKING ?= 0
LITE ?= 0
NO_WIP ?= 1
USE_LIBCO ?= 1
USE_MT32EMU ?= 1
USE_SID_AUDIO ?= 1
DEBUG ?= 0
FORCE_OPENGL ?= 0
FORCE_OPENGLES2 ?= 0
FORCE_OPENGLNONE ?= 0
DEBUG_ALLOW_DIRTY_SUBMODULES ?= 0
# Variable engines dependencies
UNAVAILABLE_DEPS :=
check_deps_availability = $(shell [ ! $(1) = 1 ] && echo $(2))
# Handle OpenGL flags
ifeq ($(FORCE_OPENGL), 1)
HAVE_OPENGL := 1
HAVE_OPENGLES2 :=
endif
ifeq ($(FORCE_OPENGLES2), 1)
HAVE_OPENGL :=
HAVE_OPENGLES2 := 1
endif
ifeq ($(FORCE_OPENGLNONE), 1)
HAVE_OPENGL :=
HAVE_OPENGLES2 :=
endif
# Features
ifeq ($(or $(HAVE_OPENGL), $(HAVE_OPENGLES2)), 1)
USE_OPENGL := 1
USE_OPENGL_GAME := 1
USE_OPENGL_SHADERS := 1
DEFINES += -DUSE_OPENGL -DUSE_GLAD -DUSE_OPENGL_GAME -DUSE_OPENGL_SHADERS
ifeq ($(DEBUG), 1)
DEFINES += -DOPENGL_DEBUG
endif
ifeq ($(HAVE_OPENGL), 1)
DEFINES += -DHAVE_OPENGL
$(info Support for OpenGL requested)
else
DEFINES += -DHAVE_OPENGLES2
$(info Support for OpenGLES2 requested)
endif
else
UNAVAILABLE_DEPS += opengl_game_shaders opengl_game_classic
$(info No support for OpenGL/OpenGLES2 requested)
endif
USE_HIGHRES ?= 1
ifeq ($(USE_HIGHRES),1)
DEFINES += -DUSE_HIGHRES
endif
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_HIGHRES), highres)
USE_BINK = 1
DEFINES += -DUSE_BINK
# Features with baked-in libs (defines handled in dependencies.mk)
USE_FLUIDSYNTH ?= 1
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_FLUIDSYNTH), fluidsynth)
USE_TREMOR ?=
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_TREMOR), tremor)
USE_VORBIS ?= 1
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_VORBIS), vorbis)
USE_FRIBIDI = 1
USE_ZLIB = 1
USE_FLAC = 1
USE_MAD = 1
USE_FAAD = 1
USE_PNG = 1
USE_JPEG = 1
USE_FREETYPE2 = 1
USE_CLOUD ?=
# Components (defines handled by engines.awk)
USE_THEORADEC ?= 1
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_THEORADEC), component_theoradec)
# handled in dependencies.mk
USE_HNM ?= 1
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_HNM), component_hnm)
ifneq ($(USE_HNM),1)
USE_HNM=
else
DEFINES += -DUSE_HNM
endif
USE_ENET ?= 0
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_ENET), component_enet)
ifneq ($(USE_ENET),1)
USE_ENET=
else
DEFINES += -DUSE_ENET
endif
USE_IMGUI ?= 1
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_IMGUI), component_imgui)
ifneq ($(USE_IMGUI),1)
USE_IMGUI=
else
DEFINES += -DUSE_IMGUI
endif
USE_MPEG2 ?= 1
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_MPEG2), component_mpeg2)
ifneq ($(USE_MPEG2),1)
USE_MPEG2=
else
DEFINES += -DUSE_MPEG2
endif
USE_GIF ?= 1
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_GIF), component_gif)
ifneq ($(USE_GIF),1)
USE_GIF=
else
DEFINES += -DUSE_GIF
endif
USE_VPX ?= 0
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_VPX), component_vpx)
ifneq ($(USE_VPX),1)
USE_VPX=
else
DEFINES += -DUSE_VPX
endif
USE_MPCDEC ?= 0
UNAVAILABLE_DEPS += $(call check_deps_availability, $(USE_MPCDEC), component_mpcdec)
ifneq ($(USE_MPCDEC),1)
USE_MPCDEC=
else
DEFINES += -DUSE_MPCDEC
endif
USE_TINYGL = 1
DEFINES += -DUSE_TINYGL
USE_LUA = 1
DEFINES += -DUSE_LUA
# Paths
SCUMMVM_PATH := $(ROOT_PATH)/../../..
DEPS_PATH := $(ROOT_PATH)/deps
CORE_PATH := $(ROOT_PATH)/src
SCRIPTS_PATH := $(ROOT_PATH)/scripts
srcdir := $(SCUMMVM_PATH)
VPATH := $(SCUMMVM_PATH)
UP_COMMON_MAKE := $(SCUMMVM_PATH)/Makefile.common
SHARED_MOD_MAKE := $(ROOT_PATH)/shared_modules.mk
# Core version shown in frontend
GIT_TAG := $(shell cd $(ROOT_PATH) 2>/dev/null && git describe --tags 2>/dev/null)
ifeq ($(GIT_TAG),)
GIT_HASH := $(shell cd $(ROOT_PATH) 2>/dev/null && git rev-parse --short HEAD 2>/dev/null)
ifneq ($(GIT_HASH),)
DEFINES += -DGIT_HASH=\"$(GIT_HASH)\"
endif
else
DEFINES += -DGIT_TAG=\"$(GIT_TAG)\"
endif
# Nice name shown in frontend
CORE_NAME = "ScummVM"
# Pipe separated allowed file extensions that core can handle
CORE_EXTENSIONS = "scummvm"
# Subdirs for datafiles bundle
SCUMMVM_SYSTEM_SUBDIR := scummvm
SCUMMVM_EXTRA_SUBDIR := extra
SCUMMVM_THEME_SUBDIR := theme
INCLUDES += -I$(SCUMMVM_PATH)
DEFINES += -D__LIBRETRO__ -DNONSTANDARD_PORT -DUSE_RGB_COLOR -DUSE_OSD -DUSE_TRANSLATION -DDETECTION_STATIC -DHAVE_CONFIG_H -DENABLE_VKEYBD
DEFINES += -DCORE_NAME=\"$(CORE_NAME)\" -DCORE_EXTENSIONS=\"$(CORE_EXTENSIONS)\" -DSCUMMVM_SYSTEM_SUBDIR=\"$(SCUMMVM_SYSTEM_SUBDIR)\" -DSCUMMVM_EXTRA_SUBDIR=\"$(SCUMMVM_EXTRA_SUBDIR)\" -DSCUMMVM_THEME_SUBDIR=\"$(SCUMMVM_THEME_SUBDIR)\"
CXXFLAGS += -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder -Wno-undefined-var-template
ifeq ($(USE_LIBCO), 1)
DEFINES += -DUSE_LIBCO
else
LDFLAGS += -lpthread
endif
ifeq ($(TARGET_64BIT), 1)
DEFINES += -DSIZEOF_SIZE_T=8 -DSCUMM_64BITS
else
DEFINES += -DSIZEOF_SIZE_T=4
endif
ifeq ($(DEBUG), 1)
DEFINES += -O0 -g -DLIBRETRO_DEBUG -DDEBUG_BUILD
else
DEFINES += -DDISABLE_TEXT_CONSOLE -DRELEASE_BUILD
endif
ifeq ($(HAVE_NEON), 1)
SCUMMVM_NEON := 1
DEFINES += -DSCUMMVM_NEON
endif
######################################################################
# Libretro settings
######################################################################
INCLUDES += -I$(ROOT_PATH)/include
MODULE_PATHS += $(CORE_PATH)
LIBRETRO_OBJS := $(CORE_PATH)/libretro-core.o \
$(CORE_PATH)/libretro-fs.o \
$(CORE_PATH)/libretro-fs-factory.o \
$(CORE_PATH)/libretro-os-base.o \
$(CORE_PATH)/libretro-os-events.o \
$(CORE_PATH)/libretro-os-inputs.o \
$(CORE_PATH)/libretro-os-utils.o \
$(CORE_PATH)/libretro-threads.o \
$(CORE_PATH)/libretro-timer.o \
$(CORE_PATH)/libretro-mapper.o \
$(CORE_PATH)/libretro-options-widget.o \
$(CORE_PATH)/libretro-graphics-surface.o
ifeq ($(or $(HAVE_OPENGL), $(HAVE_OPENGLES2)), 1)
LIBRETRO_OBJS += $(CORE_PATH)/libretro-graphics-opengl.o
endif
OBJS += $(LIBRETRO_OBJS)
######################################################################
# External dependencies settings
######################################################################
ifeq (,$(filter datafiles coreinfo,$(MAKECMDGOALS)))
$(info Configuring dependencies...)
include $(ROOT_PATH)/dependencies.mk
endif
######################################################################
# Module settings
######################################################################
INCLUDES += -I$(SCUMMVM_PATH)/engines -I$(SCUMMVM_PATH)/backends/vkeybd
# Base modules
MODULES := base
# script.mri head
ifeq ($(STATIC_LINKING),1)
$(shell printf "CREATE $(TARGET)\n" > $(ROOT_PATH)/script.mri)
endif
# Engine modules
# Following script generates configuration engines files (build/config.mk.engines, engines/engines.mk, engines/plugins_table.h, engines/detection_table.h) from actual source in $(SCUMMVM_PATH).
ifneq (,$(filter noengine,$(MAKECMDGOALS)))
LITE := 2
endif
ifeq (,$(filter clean datafiles coreinfo,$(MAKECMDGOALS)))
$(info Configuring ScummVM engines...)
ifneq ($(shell cd $(SCRIPTS_PATH); ./configure_engines.sh $(ROOT_PATH) $(SCUMMVM_PATH) $(NO_WIP) $(STATIC_LINKING) $(LITE) $(UNAVAILABLE_DEPS)),0)
$(error Configuring ScummVM engines failed)
else
-include $(SCUMMVM_PATH)/config.mk.engines
-include $(SCUMMVM_PATH)/engines/engines.mk
$(info - ScummVM engines configured)
endif
endif
ifeq ($(USE_MT32EMU),1)
INCLUDES += -I$(SCUMMVM_PATH)/audio/softsynth/mt32/sha1
DEFINES += -DUSE_MT32EMU
endif
ifeq ($(USE_SID_AUDIO),1)
DEFINES += -DUSE_SID_AUDIO
endif
# Retrieve shared modules definitions from main Makefile.common
RETRIEVED_SHARED_MODULES := $(shell cat $(UP_COMMON_MAKE) | tr -s "\n" "\00" | sed -e 's|.*-include engines/engines.mk||' -e 's|\#\#\#.*||' | tr -s "\00" "\n" > $(SHARED_MOD_MAKE) && printf ok || printf error)
ifeq ($(RETRIEVED_SHARED_MODULES), ok)
include $(SHARED_MOD_MAKE)
else
$(error Error retrieving shared modules definitions from main Makefile.common)
endif
# script.mri tail
ifeq ($(STATIC_LINKING),1)
MRI_LIBS := $(shell res=""; for path in $(MODULES) ; do [ ! -z "$$(cat $(SCUMMVM_PATH)/$${path}/module.mk | grep rules.mk)" ] && res="$$res $$path" ; done ; printf "$$res")
$(shell printf "$(addprefix ADDLIB libtemp/lib, $(addsuffix .a\n,$(notdir $(MRI_LIBS))))" >> $(ROOT_PATH)/script.mri)
$(shell printf "ADDLIB libtemp/libdeps.a\n" >> $(ROOT_PATH)/script.mri)
$(shell printf "ADDLIB libtemp/libdetect.a\n" >> $(ROOT_PATH)/script.mri)
$(shell printf "$(addprefix ADDMOD libtemp/, $(addsuffix \n,$(notdir $(LIBRETRO_OBJS))))" >> $(ROOT_PATH)/script.mri)
$(shell printf "SAVE\n" >> $(ROOT_PATH)/script.mri)
$(shell printf "END\n" >> $(ROOT_PATH)/script.mri)
$(shell sed -i.bak -e "s/^ //g" $(ROOT_PATH)/script.mri;rm -f $(ROOT_PATH)/script.mri.bak)
endif
######################################################################
# Rules
######################################################################
core: $(TARGET)
noengine: $(TARGET)
datafiles: scummvm.zip
coreinfo: $(TARGET_NAME)_libretro.info
all: $(TARGET) scummvm.zip $(TARGET_NAME)_libretro.info
#bundle_files
scummvm.zip: $(SCUMMVM_PATH)/dists/scummvm.rc
@echo Preparing $@
ifeq (, $(shell which zip))
$(error "No zip found, consider doing apt-get install zip")
endif
@$(SCRIPTS_PATH)/bundle_datafiles.sh $(ROOT_PATH) $(SCUMMVM_PATH) bundle $(TARGET_NAME)
$(TARGET_NAME)_libretro.info: $(SCUMMVM_PATH)/dists/scummvm.rc
@echo Preparing $@
@$(SCRIPTS_PATH)/bundle_datafiles.sh $(ROOT_PATH) $(SCUMMVM_PATH) info $(TARGET_NAME) $(CORE_NAME) $(CORE_EXTENSIONS) $(SCUMMVM_SYSTEM_SUBDIR) $(SCUMMVM_EXTRA_SUBDIR) $(SCUMMVM_THEME_SUBDIR)
.PHONY: all core datafiles coreinfo

View File

@@ -0,0 +1,77 @@
# ScummVM libretro port
## Building ScummVM core
To build the core with the default configuration, type in a shell the following:
```
git clone https://github.com/scummvm/scummvm
cd scummvm/backends/platform/libretro
make
```
Use `make all` to build the core along with datafiles/themes (`scummvm.zip`) and core info file (which can be built separately with `make datafiles`/`make coreinfo`).
"Work in progress" engines are not built by default, to include them pass `NO_WIP=0` to make.
To crossbuild for specific platforms, pass the relevant `platform` variable to make (refer to Makefile for supported ones).
### Build for Android
To build for Android:
* install android-sdk
* install android-ndk (e.g. through sdkmanager included in android-sdk/cmdline-tools)
* make sure all needed sdk/ndk paths are included in PATH
* type in a shell the following:
```
git clone https://github.com/scummvm/scummvm
cd scummvm/backends/platform/libretro/jni
ndk-build
```
Core will be built for all available android targets by default
### Data files and themes
[Data files](https://wiki.scummvm.org/index.php/Datafiles) required for certain games and core functions (e.g. virtual keyboard) and default [ScummVM GUI themes](https://wiki.scummvm.org/index.php/GUI_Themes) are bundled during the build process in `scummvm.zip` file. Libretro core info file is created during build as well.
Extract `scummvm.zip` and select relevant paths in ScummVM GUI (or modify `scummvm.ini` accordingly) to load properly needed data files/themes in the core.
Note that both datafiles and themes included in `scummvm.zip` need to be consistent with ScummVM version in use, hence need to be generally rebuilt and replaced for each new version.
## Libretro playlists for ScummVM core
Playlists used in Libretro frontends (e.g. Retroarch) are plain text lists used to directly launch a game with a specific core from the user interface. Those lists are structured to pass to the core the path of a specific content file to be loaded (e.g. a ROM zip fiile). Detailed info can be found in [Libretro documentation](https://docs.libretro.com/guides/roms-playlists-thumbnails/).
> WARNING: ScummVM core playlist generation with Retroarch Scanner is **NOT recommended** as it is based on a third party database instead of ScummVM game detection system, hence it is not guaranteed to work properly.
ScummVM core can accept as content the playlist-provided path to any of the files inside a valid game folder, the ScummVM internal detection system will try to autodetect the game from the content file parent folder and run the game with default ScummVM options.
The core also supports dedicated per game **hook** plain text files with `.scummvm` extension, which can be used as target path in the playlist. Content of this file shall be a string corresponding to one of the following ScummVM identifiers:
- **target**: this is the game identifier of each entry in the internal Launcher list, hence corresponding to entries in ScummVM configuration file (e.g. 'scummvm.ini'). In this case the game must be added from ScummVM GUI first, and the hook files can be placed anywhere, as the path for the game files is already part of the target configuration. The game will be launched with the options set in ScummVM
- **game ID**: this is a unique identifier for any game supported by ScummVM. This identifier is hard coded in each engine source and can be subject to change, hence it is **not a recommended choice**. A list of current game IDs is available [here](https://scummvm.org/compatibility). In this case the game will be launched even if not added in ScummVM Launcher, the hook file must be placed in the game folder and the game will be launched with default ScummVM options
### Creating ScummVM core playlist
The recommended way to generate a ScummVM core playlist is from within the ScummVM Launcher (i.e. the interal core GUI) with the Playlist Generator tool. Both needed hook files and the playlist are created automatically, based on ScummVM Launcher games list.
- Load the core from RetroArch and start it to reach the ScummVM GUI (i.e. the Launcher)
- Add games to the list as required using the GUI buttons ('Mass Add' available).
- Select **Global Options** and then the **Backend** tab.
- Check or select the path of frontend playlists. A `ScummVM.lpl` file will be created or overwritten in there.
- Check the 'Hooks location' setting, to have one `.scummvm` in each game folder or all of them in a `scummvm_hooks` folder in the `save` path.
- Check the 'Playlist version' setting. JSON format should be selected, 6-lines format is deprecated and provided for backwards compatibility only.
- Select the 'Clear existing hooks' checkbox to remove any existing `.scummvm` file in the working folders.
- Press the 'Generate playlist' button.
Operation status will be shown in the same dialog, while details will be given in the frontend logs.
## Core options
### Cursor Movement
- **Exclusive cursor control with RetroPad**: allows the use of RetroPad only to control mouse cursor, excluding the other inputs (e.g. physical mouse, touch screen).
- **Gamepad Cursor Speed**: sets the mouse cursor speed multiplier when moving the cursor with the RetroPad left analog stick or D-Pad. The default value of '1.0' is optimised for games that have a native resolution of '320x200' or '320x240'. When running 'high definition' games with a resolution of '640x400' or '640x480', a Gamepad Cursor Speed of '2.0' is recommended.
- **Gamepad Cursor Acceleration**: the amount of time (In seconds) it takes for the cursor to reach full speed
- **Analog Cursor Response**: determines how the speed of the cursor varies when tilting the RetroPad left analog stick. 'Linear': Speed is directly proportional to analog stick displacement. This is standard behaviour with which most users will be familiar. 'Quadratic': Speed increases quadratically with analog stick displacement. This allows for greater precision when making small movements without sacrificing maximum speed at full analog range. This mode may require practice for effective use.
- **Analog Deadzone**: sets the deadzone in percentage of the RetroPad analog sticks. Used to eliminate cursor drift/unwanted input.
- **Mouse Speed**: sets the mouse cursor speed multiplier when moving the cursor with the RetroMouse.
- **Mouse Fine Control Speed Reduction**: sets the mouse cursor speed reduction as percentage of normal speed when fine control is activated.
### Video settings
- **Hardware acceleration**: request video hardware acceleration (OpenGL or OpenGLES2) to the frontend if supported. It is needed to reload the core to apply this setting.
- **ScummVM Launcher aspect ratio**: set ScummVM Launcher aspect ratio.
- **ScummVM Launcher resolution**: set ScummVM Launcher aspect ratio.
### Timing
- **Frame rate cap**: set core frame rate upper limit. Reducing the limit will improve the performance on lower end devices. Changing this setting will reset the core.
- **Sample rate**: set core sample rate. Reducing the rate will slightly improve the performance on lower end devices. Changing this setting will reset the core.
### RetroPad mapping
Settings to map each RetroPad key to ScummVM controls.

View File

@@ -0,0 +1,681 @@
######################################################################
# Common settings and functions
######################################################################
# Submodules functions
DEPS_SUBMODULES := libretro-deps libretro-common
DEPS_FOLDER_libretro-deps := libretro-deps
DEPS_URL_libretro-deps := https://github.com/libretro/libretro-deps
DEPS_COMMIT_libretro-deps := 7e6e34f0319f4c7448d72f0e949e76265ccf55a1
DEPS_FOLDER_libretro-common := libretro-common
DEPS_URL_libretro-common := https://github.com/libretro/libretro-common
DEPS_COMMIT_libretro-common := 70ed90c42ddea828f53dd1b984c6443ddb39dbd6
submodule_test = $(if $(shell result=$$($(SCRIPTS_PATH)/configure_submodules.sh $(DEPS_URL_$(1)) $(DEPS_COMMIT_$(1)) $(DEPS_PATH) $(DEBUG_ALLOW_DIRTY_SUBMODULES) $(DEPS_FOLDER_$(1))) ; { [ -z $$result ] || [ ! $$result = 0 ] ; } && printf error),$(1))
$(info Configuring submodules...)
SUBMODULE_FAILED = $(strip $(findstring $(foreach SUBMODULE,$(DEPS_SUBMODULES),$(call submodule_test,$(SUBMODULE))),$(DEPS_SUBMODULES)))
ifneq ($(SUBMODULE_FAILED),)
$(error Configuration of following submodules failed: $(SUBMODULE_FAILED))
else
$(info - Submodules configured)
endif
# Shared libs functions
this_lib_available := no
sharedlibs_test_cc = '\#include <$(this_lib_subpath)$(this_lib_header)>\nint main(){return 0;}'
sharedlibs_get_include_path = $(shell printf $(sharedlibs_test_cc) | $(CC) -E -Wp,-v - 2>/dev/null | grep "$(this_lib_subpath)$(this_lib_header)" | cut -d \" -f 2 | sed "s|/$(this_lib_header)||" | head -n 1)
sharedlibs_this_lib_includes = $(if $(this_lib_subpath),-I$(call sharedlibs_get_include_path))
sharedlibs_is_lib_available = $(if $(shell result=$$(printf $(sharedlibs_test_cc) | $(CC) -xc -Wall -O -o /dev/null $(this_lib_flags) $(sharedlibs_this_lib_includes) - > /dev/null 2>&1 ; printf $$?) ; { [ -z $$result ] || [ ! $$result = 0 ] ; } && printf error),no,yes)
sharedlibs_system_lib_message = $(info - Use system shared $(shell printf ' $(this_lib_flags)' | sed -e "s|.*-l||" -e "s| .*||"): $(this_lib_available))
######################################################################
# libretro-common settings
######################################################################
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/include \
-I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/include/compat
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/file/file_path_io.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/file/file_path.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/file/retro_dirent.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/vfs/vfs_implementation.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/string/stdstring.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/time/rtime.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/streams/file_stream.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/features/features_cpu.o
ifeq ($(USE_LIBCO), 1)
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/libco/libco.o
ifeq ($(platform), genode)
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/libco/genode.o
endif
else
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/rthreads/rthreads.o
endif
ifneq ($(STATIC_LINKING), 1)
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/encodings/encoding_utf.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/compat/fopen_utf8.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/compat/compat_strl.o
endif
######################################################################
# fluidsynth\fluidlite settings
######################################################################
ifeq ($(USE_FLUIDSYNTH), 1)
DEFINES += -DUSE_FLUIDSYNTH
this_lib_subpath :=
this_lib_header := fluidsynth.h
this_lib_flags := -lfluidsynth
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
DEFINES += -DUSE_FLUIDLITE
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/include \
-I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src \
-I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/include \
-I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libogg/include
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_chan.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_chorus.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_conv.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_defsfont.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_dsp_float.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_gen.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_hash.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_list.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_mod.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_ramsfont.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_rev.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_settings.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_synth.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_sys.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_tuning.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_voice.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fluidlite/src/fluid_init.o
endif
endif
######################################################################
# libFLAC settings
######################################################################
ifeq ($(USE_FLAC), 1)
DEFINES += -DUSE_FLAC
this_lib_subpath :=
this_lib_header := FLAC/format.h
this_lib_flags := -lFLAC
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/include
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/bitreader.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/cpu.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/crc.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/fixed.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/format.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/lpc.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/md5.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/memory.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/metadata_object.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/stream_decoder.o
ifeq ($(platform), win)
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libFLAC/share/win_utf8_io/win_utf8_io.o \
$(SCUMMVM_PATH)/backends/platform/sdl/win32/win32_wrapper.o
endif
endif
endif
######################################################################
# libvorbis settings
######################################################################
ifeq ($(USE_VORBIS), 1)
DEFINES += -DUSE_VORBIS -DUSE_OGG
this_lib_subpath :=
this_lib_header := vorbis/codec.h
this_lib_flags := -lvorbis
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libogg/include \
-I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/include \
-I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libogg/src/bitwise.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libogg/src/framing.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/analysis.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/bitrate.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/block.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/codebook.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/envelope.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/floor0.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/floor1.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/info.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/lookup.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/lpc.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/lsp.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/mapping0.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/mdct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/psy.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/registry.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/res0.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/sharedbook.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/smallft.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/synthesis.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/vorbisenc.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/vorbisfile.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libvorbis/lib/window.o
endif
endif
######################################################################
# tremor settings
######################################################################
ifeq ($(USE_TREMOR), 1)
DEFINES += -DUSE_TREMOR -DUSE_VORBIS -DUSE_OGG
this_lib_subpath :=
this_lib_header := tremor/ivorbiscodec.h
this_lib_flags := -ltremor
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/bitwise.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/block.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/codebook.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/floor0.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/floor1.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/framing.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/info.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/mapping0.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/mdct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/registry.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/res012.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/sharedbook.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/synthesis.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/vorbisfile.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/tremor/window.o
endif
endif
######################################################################
# libz settings
######################################################################
ifeq ($(USE_ZLIB), 1)
DEFINES += -DUSE_ZLIB -DWANT_ZLIB
this_lib_subpath :=
this_lib_header := zlib.h
this_lib_flags := -lz
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/deflate.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/gzlib.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/uncompr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/zutil.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/inffast.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/gzread.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/crc32.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/gzwrite.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/inflate.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/infback.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/inftrees.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/trees.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/gzclose.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/compress.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/adler32.o
endif
endif
######################################################################
# libmad settings
######################################################################
ifeq ($(USE_MAD), 1)
DEFINES += -DUSE_MAD -DFPM_DEFAULT
this_lib_subpath :=
this_lib_header := mad.h
this_lib_flags := -lmad
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmad
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmad/bit.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmad/decoder.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmad/frame.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmad/huffman.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmad/layer12.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmad/layer3.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmad/stream.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmad/synth.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmad/timer.o
endif
endif
######################################################################
# libfaad settings
######################################################################
ifeq ($(USE_FAAD), 1)
DEFINES += -DUSE_FAAD
this_lib_subpath :=
this_lib_header := faad.h
this_lib_flags := -lfaad
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/include -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/bits.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/cfft.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/common.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/decoder.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/drc.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/error.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/filtbank.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/hcr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/huffman.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/ic_predict.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/is.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/lt_predict.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/mdct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/mp4.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/ms.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/output.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/pns.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/pulse.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/ps_dec.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/ps_syntax.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/rvlc.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/sbr_dct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/sbr_dec.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/sbr_e_nf.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/sbr_fbt.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/sbr_hfadj.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/sbr_hfgen.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/sbr_huff.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/sbr_qmf.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/sbr_syntax.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/sbr_tf_grid.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/specrec.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/syntax.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libfaad/libfaad/tns.o
endif
endif
######################################################################
# libpng settings
######################################################################
ifeq ($(USE_PNG), 1)
DEFINES += -DUSE_PNG
this_lib_subpath :=
this_lib_header := png.h
this_lib_flags := -lpng
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/png.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngerror.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngget.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngmem.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngpread.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngread.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngrio.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngrtran.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngrutil.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngset.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngtrans.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngwrite.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngwutil.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngwtran.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libpng/pngwio.o
endif
endif
######################################################################
# libjpeg settings
######################################################################
ifeq ($(USE_JPEG), 1)
DEFINES += -DUSE_JPEG -DJDCT_DEFAULT=JDCT_IFAST
this_lib_subpath :=
this_lib_header := jerror.h
this_lib_flags := -ljpeg
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jaricom.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcapimin.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcapistd.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcarith.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jccoefct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jccolor.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcdctmgr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcinit.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jchuff.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcmarker.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcmainct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcmaster.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcomapi.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcphuff.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcprepct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jcsample.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdapimin.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdapistd.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdarith.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdcoefct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdcolor.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jddctmgr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdhuff.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdinput.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdmarker.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdmainct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdmaster.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdmerge.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdphuff.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdpostct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdsample.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jdtrans.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jerror.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jidctflt.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jidctfst.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jidctint.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jidctred.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jfdctflt.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jfdctfst.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jfdctint.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jmemmgr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jmemnobs.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jquant1.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jquant2.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jutils.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libjpeg/jsimd_none.o
endif
endif
######################################################################
# theora settings
######################################################################
ifeq ($(USE_THEORADEC), 1)
DEFINES += -DUSE_THEORADEC
this_lib_subpath :=
this_lib_header := theora/theoradec.h
this_lib_flags := -ltheora
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/include
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/bitpack.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/decinfo.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/decode.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/dequant.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/fragment.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/huffdec.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/idct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/info.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/internal.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/quant.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/theora/lib/state.o
endif
else
#undefine as in ScummVM macro definition is tested to enable theora
USE_THEORADEC =
endif
######################################################################
# freetype settings
######################################################################
ifeq ($(USE_FREETYPE2), 1)
DEFINES += -DUSE_FREETYPE2
# ft2build.h is included in scummvm sources, while freetype2/ft2build.h is available in includes path
this_lib_subpath := freetype2/
this_lib_header := ft2build.h
this_lib_flags := -lfreetype
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
DEFINES += -DFT2_BUILD_LIBRARY
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/include
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afangles.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afblue.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afcjk.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afdummy.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afglobal.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afhints.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afindic.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/aflatin.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afloader.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afmodule.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afpic.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afranges.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afshaper.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/autofit/afwarp.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/basepic.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftadvanc.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftapi.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftbitmap.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftcalc.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftgloadr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftglyph.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/fthash.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftinit.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftsnames.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftobjs.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftsystem.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftoutln.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftrfork.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftstream.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftstroke.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/fttrigon.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/base/ftutil.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/bdf/bdfdrivr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/bdf/bdflib.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cid/cidriver.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cid/cidgload.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cid/cidload.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cid/cidobjs.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cid/cidparse.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cf2arrst.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cf2blues.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cf2error.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cf2ft.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cf2font.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cf2hints.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cf2intrp.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cf2read.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cf2stack.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cffcmap.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cffgload.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cffload.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cffobjs.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cffparse.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cffpic.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/cff/cffdrivr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/gzip/ftgzip.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/lzw/ftlzw.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pcf/pcfdrivr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pcf/pcfread.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pcf/pcfutil.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pfr/pfrcmap.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pfr/pfrdrivr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pfr/pfrgload.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pfr/pfrload.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pfr/pfrobjs.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pfr/pfrsbit.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/psaux/afmparse.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/psaux/psconv.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/psaux/psobjs.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/psaux/t1cmap.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/psaux/t1decode.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/psaux/psauxmod.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pshinter/pshalgo.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pshinter/pshglob.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pshinter/pshmod.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pshinter/pshpic.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/pshinter/pshrec.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/psnames/psmodule.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/raster/ftrend1.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/raster/ftraster.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/raster/rastpic.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/sfnt/sfdriver.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/sfnt/sfntpic.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/sfnt/sfobjs.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/sfnt/ttbdf.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/sfnt/ttcmap.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/sfnt/ttkern.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/sfnt/ttload.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/sfnt/ttmtx.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/sfnt/ttpost.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/sfnt/ttsbit.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/smooth/ftgrays.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/smooth/ftsmooth.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/type1/t1afm.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/type1/t1driver.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/type1/t1gload.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/type1/t1load.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/type1/t1objs.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/type1/t1parse.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/type42/t42drivr.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/type42/t42objs.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/type42/t42parse.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/truetype/ttdriver.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/truetype/ttgload.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/truetype/ttgxvar.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/truetype/ttinterp.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/truetype/ttobjs.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/truetype/ttpload.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/freetype/src/winfonts/winfnt.o
endif
endif
######################################################################
# fribidi settings
######################################################################
ifeq ($(USE_FRIBIDI), 1)
DEFINES += -DUSE_FRIBIDI
this_lib_subpath :=
this_lib_header := fribidi/fribidi.h
this_lib_flags := -lfribidi
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps) -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi
OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-arabic.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-bidi-types.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-bidi.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-brackets.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-char-sets-cap-rtl.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-char-sets-cp1255.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-char-sets-cp1256.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-char-sets-iso8859-6.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-char-sets-iso8859-8.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-char-sets-utf8.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-char-sets.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-deprecated.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-joining-types.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-joining.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-mirroring.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-run.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi-shape.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/fribidi/fribidi.o
endif
endif
######################################################################
# libmpeg2 settings
######################################################################
ifeq ($(USE_MPEG2), 1)
DEFINES += -DUSE_MPEG2
this_lib_subpath :=
this_lib_header := mpeg2dec/mpeg2.h
this_lib_flags := -lmpeg2
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += \
-I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/include \
-I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/include/mpeg2dec \
-I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2
OBJS_DEPS += \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/alloc.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/header.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/decode.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/slice.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/motion_comp.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/idct.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/cpu_accel.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/cpu_state.o
# --- Optional accelerations --------------
# x86/x64 -> MMX
ifneq ($(findstring x86,$(platform))$(findstring x64,$(platform)),)
OBJS_DEPS += \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/motion_comp_mmx.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/idct_mmx.o
endif
# PowerPC (PS3/PSL1GHT) -> AltiVec/VMX
ifneq ($(findstring ps3,$(platform))$(findstring psl1ght,$(platform)),)
OBJS_DEPS += \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/motion_comp_altivec.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/idct_altivec.o
endif
# ARM families (rpi*, libnx, ios/tvos, vita, ctr, miyoo/miyoomini)
ifneq ($(findstring rpi,$(platform))$(findstring armv7,$(platform))$(findstring armv8,$(platform))$(findstring libnx,$(platform))$(findstring ios,$(platform))$(findstring tvos,$(platform))$(findstring vita,$(platform))$(findstring ctr,$(platform))$(findstring miyoo,$(platform))$(findstring miyoomini,$(platform)),)
OBJS_DEPS += \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libmpeg2/libmpeg2/motion_comp_arm.o
endif
endif
endif
######################################################################
# giflib settings
######################################################################
ifeq ($(USE_GIF), 1)
DEFINES += -DUSE_GIF
this_lib_subpath :=
this_lib_header := gif_lib.h
this_lib_flags := -lgif
include $(ROOT_PATH)/sharedlib_test.mk
ifneq ($(this_lib_available), yes)
INCLUDES += \
-I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/giflib
OBJS_DEPS += \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/giflib/dgif_lib.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/giflib/egif_lib.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/giflib/gifalloc.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/giflib/gif_err.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/giflib/gif_hash.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/giflib/quantize.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/giflib/gif_font.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/giflib/openbsd-reallocarray.o \
$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/giflib/qprintf.o
endif
endif
######################################################################
# libcurl settings
######################################################################
ifeq ($(USE_CLOUD), 1)
this_lib_available := no
this_lib_subpath :=
this_lib_header := curl/curl.h
this_lib_flags := -lcurl
# No baked-in solution in libretro-deps, shared lib is the only option at this time
# ifeq ($(USE_SYSTEM_LIBS), 1)
this_lib_available := $(call sharedlibs_is_lib_available)
# endif
$(call sharedlibs_system_lib_message)
ifeq ($(this_lib_available), yes)
LDFLAGS += $(this_lib_flags)
INCLUDES += $(sharedlibs_this_lib_includes)
USE_LIBCURL := 1
USE_HTTP := 1
DEFINES += -DUSE_CLOUD -DUSE_LIBCURL -DUSE_HTTP
else
$(info System libcurl not available, dropping cloud feature.)
endif
endif

View File

@@ -0,0 +1,34 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CONFIG_H
#define CONFIG_H
#if defined(WIIU) || defined(__CELLOS_LV2__) || defined(GEKKO)
#undef SCUMM_LITTLE_ENDIAN
#define SCUMM_BIG_ENDIAN
#else
#define SCUMM_LITTLE_ENDIAN
#endif
#define SCUMM_NEED_ALIGNMENT
#endif /* CONFIG_H */

View File

@@ -0,0 +1,733 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef LIBRETRO_CORE_OPTIONS_INTL_H__
#define LIBRETRO_CORE_OPTIONS_INTL_H__
#if defined(_MSC_VER) && (_MSC_VER >= 1500 && _MSC_VER < 1900)
/* https://support.microsoft.com/en-us/kb/980263 */
#pragma execution_character_set("utf-8")
#pragma warning(disable : 4566)
#endif
#include <libretro.h>
/*
********************************
* VERSION: 2.0
********************************
*
* - 2.0: Add support for core options v2 interface
* - 1.3: Move translations to libretro_core_options_intl.h
* - libretro_core_options_intl.h includes BOM and utf-8
* fix for MSVC 2010-2013
* - Added HAVE_NO_LANGEXTRA flag to disable translations
* on platforms/compilers without BOM support
* - 1.2: Use core options v1 interface when
* RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1
* (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1)
* - 1.1: Support generation of core options v0 retro_core_option_value
* arrays containing options with a single value
* - 1.0: First commit
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
********************************
* Core Option Definitions
********************************
*/
/* RETRO_LANGUAGE_JAPANESE */
/* RETRO_LANGUAGE_FRENCH */
/* RETRO_LANGUAGE_SPANISH */
/* RETRO_LANGUAGE_GERMAN */
/* RETRO_LANGUAGE_ITALIAN */
struct retro_core_option_v2_category option_cats_it[] = {
{
"video",
NULL,
"Configura le impostazioni video"
},
{
"cursor",
"Cursore",
"Impostazioni relative al movimento del cursore"
},
{
"timing",
NULL,
"Impostazioni relative al timing"
},
{
"retropad",
"Mappatura RetroPad",
"Configura la mappatura del RetroPad"
},
{ NULL, NULL, NULL },
};
struct retro_core_option_v2_definition option_defs_it[] = {
{
"scummvm_gamepad_cursor_only",
"Cursore > Controllo esclusivo del cursore con RetroPad",
"Controllo esclusivo del cursore con RetroPad",
"Consente di usare solo RetroPad per il controllo del cursore del mouse, escludento gli altri input (es. mouse fisico, touch screen).",
NULL,
"cursor",
{
{"disabled", NULL},
{"enabled", NULL},
{NULL, NULL},
},
"disabled"
},
{
"scummvm_gamepad_cursor_speed",
"Cursore > Velocità del cursore",
"Velocità del cursore",
"Moltiplicatore della velocità del cursore del mouse quando si usa la leva analogica sinistra o il D-Pad del RetroPad. Il valore di default di '1.0' è ottimizzato per i giochi con risoluzione nativa di '320x200' o '320x240'. Per i giochi ad 'alta definizione' con risoluzione di '640x400' or '640x480', si raccomanda il valore di '2.0'",
NULL,
NULL,
{
{NULL, NULL},
},
NULL
},
{
"scummvm_gamepad_cursor_acceleration_time",
"Cursore > Accelerazione del cursore",
"Accelerazione del cursore",
"Il tempo (in secondi) necessario al cursore del mouse per raggiungere la piena velocità quando si usa la leva analogica sinistra o il D-Pad del RetroPad.",
NULL,
NULL,
{
{NULL, NULL},
},
NULL
},
{
"scummvm_analog_response",
"Cursore > Risposta analogica del cursore",
"Risposta analogica del cursore",
"Modalità di risposta della velocità del cursore del mouse allo spostamento della leva analogica sinistra del RetroPad. 'Lineare': La velocità è direttamente proporzionale allo spostamento della leva. Questa è l'impostazione di default adatta alla maggior parte degli utenti. 'Quadratica': La velocità aumenta con il quadrato dello spostamento della leva. Questo permette maggior precisione nei piccoli movimenti senza sacrificare il raggiungimento della velocità massima a spostamento completo. Questa modalità può richiedere pratica per un uso efficace.",
NULL,
NULL,
{
{"linear", "Lineare"},
{"quadratic", "Quadratica"},
{NULL, NULL},
},
NULL
},
{
"scummvm_analog_deadzone",
"Cursore > Zona morta analogica",
"Zona morta analogica",
"Zona morta percentuale delle leve analogiche del RetroPad. Può essere usata per eliminare scorrimenti indesiderati del cursore.",
NULL,
NULL,
{
{NULL, NULL},
},
NULL
},
{
"scummvm_mouse_speed",
"Cursore > Velocità del mouse",
"Velocità del mouse",
"Moltiplicatore della velocità del cursore del mouse quando si usa RetroMouse.",
NULL,
NULL,
{
{NULL, NULL},
},
NULL
},
{
"scummvm_mouse_fine_control_speed_reduction",
"Cursore > Riduzione velocità con controllo fine del mouse",
"Riduzione velocità con controllo fine del mouse",
"Riduzione della velocità del cursore del mouse come percentuale della velocità normale quando il controllo fine è attivato.",
NULL,
NULL,
{
{NULL, NULL},
},
NULL
},
{
"scummvm_framerate",
"Timing > Tetto frequenza dei fotogrammi",
"Tetto frequenza dei fotogrammi",
"Imposta il limite superiore della frequenza dei fotogrammi. La riduzione del limite migliora le prestazioni sui dispositivi di fascia bassa. Il cambio di questa impostazione causerà il reset del core.",
NULL,
NULL,
{
{ NULL, NULL },
},
NULL
},
{
"scummvm_samplerate",
"Timing > Frequenza di campionamento",
"Frequenza di campionamento",
"Imposta la frequenza di campionamento. La riduzione della frequenza migliora leggermente le prestazioni sui dispositivi di fascia bassa. Il cambio di questa impostazione causerà il reset del core.",
NULL,
NULL,
{
{ NULL, NULL },
},
NULL
},
/* Button mappings */
{
"scummvm_mapper_up",
"RetroPad > Su",
"Su",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_down",
"RetroPad > Giù",
"Giù",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_left",
"RetroPad > Sinistra",
"Sinistra",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_right",
"RetroPad > Destra",
"Destra",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_a",
"RetroPad > A",
"A",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_b",
"RetroPad > B",
"B",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_x",
"RetroPad > X",
"X",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_y",
"RetroPad > Y",
"Y",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_select",
"RetroPad > Select",
"Select",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_start",
"RetroPad > Start",
"Start",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_l",
"RetroPad > L",
"L",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_r",
"RetroPad > R",
"R",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_l2",
"RetroPad > L2",
"L2",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_r2",
"RetroPad > R2",
"R2",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_l3",
"RetroPad > L3",
"L3",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_r3",
"RetroPad > R3",
"R3",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
/* Left Stick */
{
"scummvm_mapper_lu",
"RetroPad > Leva Analogica Sinistra > Su",
"Leva Analogica Sinistra > Su",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_ld",
"RetroPad > Leva Analogica Sinistra > Giù",
"Leva Analogica Sinistra > Giù",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_ll",
"RetroPad > Leva Analogica Sinistra > Sinistra",
"Leva Analogica Sinistra > Sinistra",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_lr",
"RetroPad > Leva Analogica Sinistra > Destra",
"Leva Analogica Sinistra > Destra",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
/* Right Stick */
{
"scummvm_mapper_ru",
"RetroPad > Leva Analogica Destra > Su",
"Leva Analogica Destra > Su",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_rd",
"RetroPad > Leva Analogica Destra > Giù",
"Leva Analogica Destra > Giù",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_rl",
"RetroPad > Leva Analogica Destra > Sinistra",
"Leva Analogica Destra > Sinistra",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_mapper_rr",
"RetroPad > Leva Analogica Destra > Destra",
"Leva Analogica Destra > Destra",
NULL,
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_video_hw_acceleration",
"Video > Accelerazione hardware",
"Accelerazione hardware",
"Richiede accelerazione hardware (OpenGL or OpenGLES2) al frontend, se supportata. È necessario ricaricare il core per rendere effettiva questa opzione",
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
#ifdef USE_HIGHRES
{
"scummvm_gui_aspect_ratio",
"Video > Rapporto aspetto GUI",
"Rapporto aspetto ScummVM Launcher",
"Imposta il rapporto d'aspetto per ScummVM Launcher.",
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
{
"scummvm_gui_h_res",
"Video > Risoluzione GUI",
"Risoluzione ScummVM Launcher",
"Imposta la risoluzione per ScummVM Launcher.",
NULL,
NULL,
{
{ NULL, NULL }
},
NULL,
},
#endif
{ NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },
};
struct retro_core_options_v2 options_it = {
option_cats_it,
option_defs_it
};
/* List has been reduced to fit RETRO_NUM_CORE_OPTION_VALUES_MAX.
* Latest element {NULL, NULL} has been omitted in this case as the array is exactly sized
* RETRO_NUM_CORE_OPTION_VALUES_MAX; in case the array size will be reduced, {NULL, NULL}
* element to be uncommented.
*/
struct retro_core_option_value retro_keys_label_it [] = {
{"---", "---"},
{"RETROKE_VKBD", "Attiva/disattiva Tastiera Virtuale"},
{"RETROKE_LEFT", "Cursore Mouse Sinistra"},
{"RETROKE_UP", "Cursore Mouse Su"},
{"RETROKE_DOWN", "Cursore Mouse Giù"},
{"RETROKE_RIGHT", "Cursore Mouse Destra"},
{"RETROKE_LEFT_BUTTON", "Tasto Mouse Sinistra"},
{"RETROKE_RIGHT_BUTTON", "Tasto Mouse Destra"},
{"RETROKE_FINE_CONTROL", "Controllo Fine Cursore Mouse"},
{"RETROKE_SCUMMVM_GUI", "ScummVM GUI"},
{"RETROKE_SHIFT_MOD", "Tastiera Shift (Modificatore)"},
{"RETROKE_CTRL_MOD", "Tastiera Control (Modificatore)"},
{"RETROKE_ALT_MOD", "Tastiera Alt (Modificatore)"},
{"RETROK_BACKSPACE", "Tastiera Backspace"},
{"RETROK_TAB", "Tastiera Tab"},
{"RETROK_CLEAR", "Tastiera Clear"},
{"RETROK_RETURN", "Tastiera Return"},
{"RETROK_PAUSE", "Tastiera Pause"},
{"RETROK_ESCAPE", "Tastiera Escape"},
{"RETROK_SPACE", "Tastiera Space"},
{"RETROK_EXCLAIM", "Tastiera !"},
{"RETROK_QUOTEDBL", "Tastiera \""},
{"RETROK_HASH", "Tastiera #"},
{"RETROK_DOLLAR", "Tastiera $"},
{"RETROK_AMPERSAND", "Tastiera &"},
{"RETROK_QUOTE", "Tastiera \'"},
{"RETROK_LEFTPAREN", "Tastiera ("},
{"RETROK_RIGHTPAREN", "Tastiera )"},
{"RETROK_ASTERISK", "Tastiera *"},
{"RETROK_PLUS", "Tastiera +"},
{"RETROK_COMMA", "Tastiera ,"},
{"RETROK_MINUS", "Tastiera -"},
{"RETROK_PERIOD", "Tastiera ."},
{"RETROK_SLASH", "Tastiera /"},
{"RETROK_0", "Tastiera 0"},
{"RETROK_1", "Tastiera 1"},
{"RETROK_2", "Tastiera 2"},
{"RETROK_3", "Tastiera 3"},
{"RETROK_4", "Tastiera 4"},
{"RETROK_5", "Tastiera 5"},
{"RETROK_6", "Tastiera 6"},
{"RETROK_7", "Tastiera 7"},
{"RETROK_8", "Tastiera 8"},
{"RETROK_9", "Tastiera 9"},
{"RETROK_COLON", "Tastiera :"},
{"RETROK_SEMICOLON", "Tastiera ;"},
{"RETROK_LESS", "Tastiera <"},
{"RETROK_EQUALS", "Tastiera ="},
{"RETROK_GREATER", "Tastiera >"},
{"RETROK_QUESTION", "Tastiera ?"},
{"RETROK_AT", "Tastiera @"},
{"RETROK_LEFTBRACKET", "Tastiera ["},
{"RETROK_BACKSLASH", "Tastiera \\"},
{"RETROK_RIGHTBRACKET", "Tastiera ]"},
{"RETROK_CARET", "Tastiera ^"},
{"RETROK_UNDERSCORE", "Tastiera _"},
{"RETROK_BACKQUOTE", "Tastiera `"},
{"RETROK_a", "Tastiera a"},
{"RETROK_b", "Tastiera b"},
{"RETROK_c", "Tastiera c"},
{"RETROK_d", "Tastiera d"},
{"RETROK_e", "Tastiera e"},
{"RETROK_f", "Tastiera f"},
{"RETROK_g", "Tastiera g"},
{"RETROK_h", "Tastiera h"},
{"RETROK_i", "Tastiera i"},
{"RETROK_j", "Tastiera j"},
{"RETROK_k", "Tastiera k"},
{"RETROK_l", "Tastiera l"},
{"RETROK_m", "Tastiera m"},
{"RETROK_n", "Tastiera n"},
{"RETROK_o", "Tastiera o"},
{"RETROK_p", "Tastiera p"},
{"RETROK_q", "Tastiera q"},
{"RETROK_r", "Tastiera r"},
{"RETROK_s", "Tastiera s"},
{"RETROK_t", "Tastiera t"},
{"RETROK_u", "Tastiera u"},
{"RETROK_v", "Tastiera v"},
{"RETROK_w", "Tastiera w"},
{"RETROK_x", "Tastiera x"},
{"RETROK_y", "Tastiera y"},
{"RETROK_z", "Tastiera z"},
{"RETROK_KP0", "Tastiera Numpad 0"},
{"RETROK_KP1", "Tastiera Numpad 1"},
{"RETROK_KP2", "Tastiera Numpad 2"},
{"RETROK_KP3", "Tastiera Numpad 3"},
{"RETROK_KP4", "Tastiera Numpad 4"},
{"RETROK_KP5", "Tastiera Numpad 5"},
{"RETROK_KP6", "Tastiera Numpad 6"},
{"RETROK_KP7", "Tastiera Numpad 7"},
{"RETROK_KP8", "Tastiera Numpad 8"},
{"RETROK_KP9", "Tastiera Numpad 9"},
{"RETROK_KP_PERIOD", "Tastiera Numpad ."},
{"RETROK_KP_DIVIDE", "Tastiera Numpad /"},
{"RETROK_KP_MULTIPLY", "Tastiera Numpad *"},
{"RETROK_KP_MINUS", "Tastiera Numpad -"},
{"RETROK_KP_PLUS", "Tastiera Numpad +"},
{"RETROK_KP_ENTER", "Tastiera Numpad Enter"},
{"RETROK_KP_EQUALS", "Tastiera Numpad ="},
{"RETROK_UP", "Tastiera Su"},
{"RETROK_DOWN", "Tastiera Giù"},
{"RETROK_LEFT", "Tastiera Sinistra"},
{"RETROK_RIGHT", "Tastiera Destra"},
{"RETROK_INSERT", "Tastiera Insert"},
{"RETROK_DELETE", "Tastiera Delete"},
{"RETROK_HOME", "Tastiera Home"},
{"RETROK_END", "Tastiera End"},
{"RETROK_PAGEUP", "Tastiera PageUp"},
{"RETROK_PAGEDOWN", "Tastiera PageDown"},
{"RETROK_F1", "Tastiera F1"},
{"RETROK_F2", "Tastiera F2"},
{"RETROK_F3", "Tastiera F3"},
{"RETROK_F4", "Tastiera F4"},
{"RETROK_F5", "Tastiera F5"},
{"RETROK_F6", "Tastiera F6"},
{"RETROK_F7", "Tastiera F7"},
{"RETROK_F8", "Tastiera F8"},
{"RETROK_F9", "Tastiera F9"},
{"RETROK_F10", "Tastiera F10"},
{"RETROK_F11", "Tastiera F11"},
{"RETROK_F12", "Tastiera F12"},
//{"RETROK_F13","Tastiera F13"},
//{"RETROK_F14","Tastiera F14"},
//{"RETROK_F15","Tastiera F15"},
//{"RETROK_NUMLOCK","Tastiera NumLock"},
//{"RETROK_CAPSLOCK","Tastiera Caps Lock"},
//{"RETROK_SCROLLOCK","Tastiera Scroll Lock"},
{"RETROK_LSHIFT", "Tastiera Shift Sinistra"},
{"RETROK_RSHIFT", "Tastiera Shift Destra"},
{"RETROK_LCTRL", "Tastiera Control Sinistra"},
{"RETROK_RCTRL", "Tastiera Control Destra"},
{"RETROK_LALT", "Tastiera Alt Sinistra"},
{"RETROK_RALT", "Tastiera Alt Destra"},
//{"RETROK_LMETA","Tastiera Left Meta"},
//{"RETROK_RMETA","Tastiera Right Meta"},
//{"RETROK_LSUPER","Tastiera Left Super"},
//{"RETROK_RSUPER","Tastiera Right Super"},
//{"RETROK_MODE","Tastiera Mode"},
//{"RETROK_COMPOSE","Tastiera Compose"},
//{"RETROK_HELP","Tastiera Help"},
//{"RETROK_PRINT","Tastiera Print"},
//{"RETROK_SYSREQ","Tastiera SysReq"},
//{"RETROK_BREAK","Tastiera Break"},
//{"RETROK_MENU","Tastiera Menu"},
//{"RETROK_POWER","Tastiera Power"},
//{"RETROK_EURO","Tastiera Euro"},
//{"RETROK_UNDO","Tastiera Undo"},
};
/* RETRO_LANGUAGE_DUTCH */
/* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
/* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
/* RETRO_LANGUAGE_RUSSIAN */
/* RETRO_LANGUAGE_KOREAN */
/* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
/* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
/* RETRO_LANGUAGE_ESPERANTO */
/* RETRO_LANGUAGE_POLISH */
/* RETRO_LANGUAGE_VIETNAMESE */
/* RETRO_LANGUAGE_ARABIC */
/* RETRO_LANGUAGE_GREEK */
/* RETRO_LANGUAGE_TURKISH */
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef LIBRETRO_CORE_H
#define LIBRETRO_CORE_H
#include <libretro.h>
extern retro_log_printf_t retro_log_cb;
extern retro_input_state_t retro_input_cb;
bool retro_get_input_bitmask_supported(void);
void retro_osd_notification(const char *msg);
int retro_get_input_device(void);
const char *retro_get_core_dir(void);
const char *retro_get_system_dir(void);
const char *retro_get_save_dir(void);
const char *retro_get_playlist_dir(void);
float retro_setting_get_frame_rate(void);
uint16 retro_setting_get_sample_rate(void);
uint16 retro_setting_get_audio_samples_buffer_size(void);
int retro_setting_get_analog_deadzone(void);
bool retro_setting_get_analog_response_is_quadratic(void);
float retro_setting_get_mouse_speed(void);
int retro_setting_get_mouse_fine_control_speed_reduction(void);
bool retro_setting_get_gamepad_cursor_only(void);
float retro_setting_get_gamepad_cursor_speed(void);
float retro_setting_get_gamepad_acceleration_time(void);
int retro_setting_get_gui_res_w(void);
int retro_setting_get_gui_res_h(void);
void retro_set_size(unsigned width, unsigned height);
uint8 retro_get_video_hw_mode(void);
#ifdef USE_OPENGL
uintptr_t retro_get_hw_fb(void);
void *retro_get_proc_address(const char *name);
#endif
#endif // LIBRETRO_CORE_H

View File

@@ -0,0 +1,68 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef LIBRETRO_DEFS_H
#define LIBRETRO_DEFS_H
/* Workaround for a RetroArch audio driver
* limitation: a maximum of 1024 frames
* can be written per call of audio_batch_cb() */
#define AUDIO_BATCH_FRAMES_MAX 1024
// System analog stick range is -0x8000 to 0x8000
#define ANALOG_RANGE 0x8000
#define DEFAULT_SAMPLE_RATE 48000
#define DEFAULT_REFRESH_RATE 60
#define FRAMESKIP_MAX DEFAULT_REFRESH_RATE / 2
#define DEFAULT_SOUNDFONT_FILENAME "Roland_SC-55.sf2"
// Audio status
#define AUDIO_STATUS_MUTE (1 << 0)
#define AUDIO_STATUS_UPDATE_LATENCY (1 << 1)
#define AV_STATUS_UPDATE_AV_INFO (1 << 2)
#define AV_STATUS_RESET_PENDING (1 << 3)
#define AV_STATUS_UPDATE_GEOMETRY (1 << 4)
#define AV_STATUS_UPDATE_GUI (1 << 5)
// Video status
#define VIDEO_GRAPHIC_MODE_REQUEST_SW (1 << 0)
#define VIDEO_GRAPHIC_MODE_REQUEST_HW (1 << 1)
#define VIDEO_GRAPHIC_MODE_HAVE_OPENGL (1 << 2)
#define VIDEO_GRAPHIC_MODE_HAVE_OPENGLES2 (1 << 3)
#define VIDEO_GRAPHIC_MODE_RESET_PENDING (1 << 4)
// Preliminary scan results
#define TEST_GAME_OK_TARGET_FOUND 0
#define TEST_GAME_OK_ID_FOUND 1
#define TEST_GAME_OK_ID_AUTODETECTED 2
#define TEST_GAME_KO_NOT_FOUND 3
#define TEST_GAME_KO_MULTIPLE_RESULTS 4
#ifndef F_OK
#define F_OK 0
#endif
#ifndef W_OK
#define W_OK 2
#endif
#ifndef R_OK
#define R_OK 4
#endif
#endif

View File

@@ -0,0 +1,39 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef LIBRETRO_FILESYSTEM_FACTORY_H
#define LIBRETRO_FILESYSTEM_FACTORY_H
#include "backends/fs/fs-factory.h"
/**
* Creates LibRetroFilesystemNode objects.
*
* Parts of this class are documented in the base interface class, FilesystemFactory.
*/
class LibRetroFilesystemFactory : public FilesystemFactory {
protected:
virtual AbstractFSNode *makeRootFileNode() const;
virtual AbstractFSNode *makeCurrentDirectoryFileNode() const;
virtual AbstractFSNode *makeFileNodePath(const Common::String &path) const;
};
#endif /*LIBRETRO_FILESYSTEM_FACTORY_H*/

View File

@@ -0,0 +1,101 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef LIBRETRO_FILESYSTEM_H
#define LIBRETRO_FILESYSTEM_H
#include "backends/fs/abstract-fs.h"
#ifdef MACOSX
#include <sys/types.h>
#endif
#include <unistd.h>
/**
* Implementation of the ScummVM file system API based on LibRetro.
*
* Parts of this class are documented in the base interface class, AbstractFSNode.
*/
class LibRetroFilesystemNode : public AbstractFSNode {
protected:
Common::String _displayName;
Common::String _path;
bool _isDirectory;
bool _isValid;
bool _isReadable;
bool _isWritable;
virtual AbstractFSNode *makeNode(const Common::String &path) const {
return new LibRetroFilesystemNode(path);
}
/**
* Plain constructor, for internal use only (hence protected).
*/
LibRetroFilesystemNode() : _isDirectory(false), _isValid(false) {}
public:
/**
* Creates a LibRetroFilesystemNode for a given path.
*
* @param path the path the new node should point to.
*/
LibRetroFilesystemNode(const Common::String &path);
virtual bool exists() const {
return access(_path.c_str(), F_OK) == 0;
}
virtual Common::U32String getDisplayName() const {
return _displayName;
}
virtual Common::String getName() const {
return _displayName;
}
virtual Common::String getPath() const {
return _path;
}
virtual bool isDirectory() const {
return _isDirectory && _isReadable;
}
virtual bool isReadable() const {
return _isReadable;
}
virtual bool isWritable() const {
return _isWritable;
}
virtual AbstractFSNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
virtual AbstractFSNode *getParent() const;
virtual Common::SeekableReadStream *createReadStream();
virtual Common::SeekableWriteStream *createWriteStream(bool atomic);
virtual bool createDirectory();
static Common::String getHomeDir(void);
private:
/**
* Tests and sets the _isValid and _isDirectory flags, using the stat() function.
*/
virtual void setFlags();
};
#endif

View File

@@ -0,0 +1,57 @@
/* Copyright (C) 2024 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_LIBRETRO_GRAPHICS_OPENGL_H
#define BACKENDS_LIBRETRO_GRAPHICS_OPENGL_H
#include "backends/graphics/opengl/opengl-graphics.h"
#include "backends/graphics/opengl/texture.h"
namespace OpenGL {
class Surface;
}
class LibretroOpenGLGraphics : public OpenGL::OpenGLGraphicsManager {
public:
LibretroOpenGLGraphics(OpenGL::ContextType contextType);
bool loadVideoMode(uint requestedWidth, uint requestedHeight, bool resizable, int antialiasing) override {
return true;
}
void refreshScreen() override;
void setSystemMousePosition(const int x, const int y) override {};
void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) override;
void initSize(uint width, uint height, const Graphics::PixelFormat *format) override;
void setMousePosition(int x, int y);
void resetContext(OpenGL::ContextType contextType);
OSystem::TransactionError endGFXTransaction() override;
bool hasFeature(OSystem::Feature f) const override;
protected:
bool gameNeedsAspectRatioCorrection() const override {
return false;
}
void handleResizeImpl(const int width, const int height) override;
private:
void overrideCursorScaling(void);
};
class LibretroHWFramebuffer : public OpenGL::Backbuffer {
protected:
void activateInternal() override;
};
#endif //BACKENDS_LIBRETRO_GRAPHICS_OPENGL_H

View File

@@ -0,0 +1,114 @@
/* Copyright (C) 2024 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_LIBRETRO_GRAPHICS_SURFACE_H
#define BACKENDS_LIBRETRO_GRAPHICS_SURFACE_H
#include "common/system.h"
#include "graphics/palette.h"
#include "graphics/managed_surface.h"
#include "backends/graphics/windowed.h"
class LibretroGraphics : public WindowedGraphicsManager {
public:
Graphics::ManagedSurface _screen;
Graphics::Surface _gameScreen;
Graphics::Surface _overlay;
Graphics::Surface _cursor;
Graphics::Palette _cursorPalette;
Graphics::Palette _gamePalette;
private:
bool _cursorDontScale;
bool _cursorPaletteEnabled;
bool _screenUpdatePending;
int _cursorHotspotX;
int _cursorHotspotY;
int _cursorKeyColor;
int _screenChangeID;
int _cursorHotspotXScaled;
int _cursorHotspotYScaled;
float _cursorWidthScaled;
float _cursorHeightScaled;
public:
LibretroGraphics();
~LibretroGraphics();
Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
const OSystem::GraphicsMode *getSupportedGraphicsModes(void) const override;
void initSize(uint width, uint height, const Graphics::PixelFormat *format) override;
int16 getHeight(void) const override;
int16 getWidth(void) const override;
Graphics::PixelFormat getScreenFormat(void) const override;
void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
void updateScreen(void) override;
void clearOverlay(void) override;
void grabOverlay(Graphics::Surface &surface) const override;
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
int16 getOverlayHeight(void) const override;
int16 getOverlayWidth(void) const override;
Graphics::PixelFormat getOverlayFormat() const override;
const Graphics::ManagedSurface *getScreen(void);
void warpMouse(int x, int y) override;
void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, bool dontScale = false, const Graphics::PixelFormat *format = NULL, const byte *mask = nullptr) override;
void setCursorPalette(const byte *colors, uint start, uint num) override;
bool isOverlayInGUI(void);
bool hasFeature(OSystem::Feature f) const override;
void setFeatureState(OSystem::Feature f, bool enable) override;
bool getFeatureState(OSystem::Feature f) const override;
int getDefaultGraphicsMode() const override {
return 0;
}
bool setGraphicsMode(int mode, uint flags = OSystem::kGfxModeNoFlags) override {
return true;
}
int getGraphicsMode() const override {
return 0;
}
Graphics::Surface *lockScreen() override {
return &_gameScreen;
}
void unlockScreen() override {}
int getScreenChangeID() const override;
void beginGFXTransaction() override {}
OSystem::TransactionError endGFXTransaction() override;
void fillScreen(uint32 col) override {}
void fillScreen(const Common::Rect &r, uint32 col) override {}
void setFocusRectangle(const Common::Rect &rect) override {}
void clearFocusRectangle() override {}
void realUpdateScreen(void);
bool gameNeedsAspectRatioCorrection() const override {
return false;
}
void handleResizeImpl(const int width, const int height) override;
void setSystemMousePosition(const int x, const int y) override {}
void setMousePosition(int x, int y);
void displayMessageOnOSD(const Common::U32String &msg) override;
protected:
void setPalette(const byte *colors, uint start, uint num) override;
void grabPalette(byte *colors, uint start, uint num) const override;
private:
void overrideCursorScaling();
};
#endif //BACKENDS_LIBRETRO_GRAPHICS_SURFACE_H

View File

@@ -0,0 +1,262 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef LIBRETRO_MAPPER_H
#define LIBRETRO_MAPPER_H
#include <libretro.h>
#include "common/keyboard.h"
#define RETRO_DEVICE_KEY_STATUS 0
#define RETRO_DEVICE_KEY_PREV_STATUS 1
#define RETRO_DEVICE_KEY_CHANGED 2
#define RETRO_DEVICE_ID_JOYPAD_ANALOG 16
#define RETRO_DEVICE_ID_JOYPAD_LR 16
#define RETRO_DEVICE_ID_JOYPAD_LL 17
#define RETRO_DEVICE_ID_JOYPAD_LD 18
#define RETRO_DEVICE_ID_JOYPAD_LU 19
#define RETRO_DEVICE_ID_JOYPAD_RR 20
#define RETRO_DEVICE_ID_JOYPAD_RL 21
#define RETRO_DEVICE_ID_JOYPAD_RD 22
#define RETRO_DEVICE_ID_JOYPAD_RU 23
#define RETRO_DEVICE_ID_JOYPAD_LAST 24
#define RETROKE_VKBD -1
#define RETROKE_LEFT -2
#define RETROKE_UP -3
#define RETROKE_DOWN -4
#define RETROKE_RIGHT -5
#define RETROKE_LEFT_BUTTON -6
#define RETROKE_RIGHT_BUTTON -7
#define RETROKE_FINE_CONTROL -8
#define RETROKE_SCUMMVM_GUI -9
#define RETROKE_SHIFT_MOD -10
#define RETROKE_CTRL_MOD -11
#define RETROKE_ALT_MOD -12
/* libretro.cpp functions */
extern retro_input_state_t retro_input_cb;
extern int retro_setting_get_analog_deadzone(void);
extern bool retro_get_input_bitmask_supported(void);
struct retro_keymap {
int retro_id;
int scummvm_id;
const char *value;
};
static const struct retro_keymap retro_keys[] = {
{0, 0, "---"},
{RETROKE_VKBD, 0, "RETROKE_VKBD"},
{RETROKE_LEFT, 0, "RETROKE_LEFT"},
{RETROKE_UP, 0, "RETROKE_UP"},
{RETROKE_DOWN, 0, "RETROKE_DOWN"},
{RETROKE_RIGHT, 0, "RETROKE_RIGHT"},
{RETROKE_LEFT_BUTTON, 0, "RETROKE_LEFT_BUTTON"},
{RETROKE_RIGHT_BUTTON, 0, "RETROKE_RIGHT_BUTTON"},
{RETROKE_FINE_CONTROL, 0, "RETROKE_FINE_CONTROL"},
{RETROKE_SCUMMVM_GUI, 0, "RETROKE_SCUMMVM_GUI"},
{RETROKE_SHIFT_MOD, 0, "RETROKE_SHIFT_MOD"},
{RETROKE_CTRL_MOD, 0, "RETROKE_CTRL_MOD"},
{RETROKE_ALT_MOD, 0, "RETROKE_ALT_MOD"},
{RETROK_BACKSPACE, Common::KEYCODE_BACKSPACE, "RETROK_BACKSPACE"},
{RETROK_TAB, Common::KEYCODE_TAB, "RETROK_TAB"},
{RETROK_CLEAR, Common::KEYCODE_CLEAR, "RETROK_CLEAR"},
{RETROK_RETURN, Common::KEYCODE_RETURN, "RETROK_RETURN"},
{RETROK_PAUSE, Common::KEYCODE_PAUSE, "RETROK_PAUSE"},
{RETROK_ESCAPE, Common::KEYCODE_ESCAPE, "RETROK_ESCAPE"},
{RETROK_SPACE, Common::KEYCODE_SPACE, "RETROK_SPACE"},
{RETROK_EXCLAIM, Common::KEYCODE_EXCLAIM, "RETROK_EXCLAIM"},
{RETROK_QUOTEDBL, Common::KEYCODE_QUOTEDBL, "RETROK_QUOTEDBL"},
{RETROK_HASH, Common::KEYCODE_HASH, "RETROK_HASH"},
{RETROK_DOLLAR, Common::KEYCODE_DOLLAR, "RETROK_DOLLAR"},
{RETROK_AMPERSAND, Common::KEYCODE_AMPERSAND, "RETROK_AMPERSAND"},
{RETROK_QUOTE, Common::KEYCODE_QUOTE, "RETROK_QUOTE"},
{RETROK_LEFTPAREN, Common::KEYCODE_LEFTPAREN, "RETROK_LEFTPAREN"},
{RETROK_RIGHTPAREN, Common::KEYCODE_RIGHTPAREN, "RETROK_RIGHTPAREN"},
{RETROK_ASTERISK, Common::KEYCODE_ASTERISK, "RETROK_ASTERISK"},
{RETROK_PLUS, Common::KEYCODE_PLUS, "RETROK_PLUS"},
{RETROK_COMMA, Common::KEYCODE_COMMA, "RETROK_COMMA"},
{RETROK_MINUS, Common::KEYCODE_MINUS, "RETROK_MINUS"},
{RETROK_PERIOD, Common::KEYCODE_PERIOD, "RETROK_PERIOD"},
{RETROK_SLASH, Common::KEYCODE_SLASH, "RETROK_SLASH"},
{RETROK_0, Common::KEYCODE_0, "RETROK_0"},
{RETROK_1, Common::KEYCODE_1, "RETROK_1"},
{RETROK_2, Common::KEYCODE_2, "RETROK_2"},
{RETROK_3, Common::KEYCODE_3, "RETROK_3"},
{RETROK_4, Common::KEYCODE_4, "RETROK_4"},
{RETROK_5, Common::KEYCODE_5, "RETROK_5"},
{RETROK_6, Common::KEYCODE_6, "RETROK_6"},
{RETROK_7, Common::KEYCODE_7, "RETROK_7"},
{RETROK_8, Common::KEYCODE_8, "RETROK_8"},
{RETROK_9, Common::KEYCODE_9, "RETROK_9"},
{RETROK_COLON, Common::KEYCODE_COLON, "RETROK_COLON"},
{RETROK_SEMICOLON, Common::KEYCODE_SEMICOLON, "RETROK_SEMICOLON"},
{RETROK_LESS, Common::KEYCODE_LESS, "RETROK_LESS"},
{RETROK_EQUALS, Common::KEYCODE_EQUALS, "RETROK_EQUALS"},
{RETROK_GREATER, Common::KEYCODE_GREATER, "RETROK_GREATER"},
{RETROK_QUESTION, Common::KEYCODE_QUESTION, "RETROK_QUESTION"},
{RETROK_AT, Common::KEYCODE_AT, "RETROK_AT"},
{RETROK_LEFTBRACKET, Common::KEYCODE_LEFTBRACKET, "RETROK_LEFTBRACKET"},
{RETROK_BACKSLASH, Common::KEYCODE_BACKSLASH, "RETROK_BACKSLASH"},
{RETROK_RIGHTBRACKET, Common::KEYCODE_RIGHTBRACKET, "RETROK_RIGHTBRACKET"},
{RETROK_CARET, Common::KEYCODE_CARET, "RETROK_CARET"},
{RETROK_UNDERSCORE, Common::KEYCODE_UNDERSCORE, "RETROK_UNDERSCORE"},
{RETROK_BACKQUOTE, Common::KEYCODE_BACKQUOTE, "RETROK_BACKQUOTE"},
{RETROK_a, Common::KEYCODE_a, "RETROK_a"},
{RETROK_b, Common::KEYCODE_b, "RETROK_b"},
{RETROK_c, Common::KEYCODE_c, "RETROK_c"},
{RETROK_d, Common::KEYCODE_d, "RETROK_d"},
{RETROK_e, Common::KEYCODE_e, "RETROK_e"},
{RETROK_f, Common::KEYCODE_f, "RETROK_f"},
{RETROK_g, Common::KEYCODE_g, "RETROK_g"},
{RETROK_h, Common::KEYCODE_h, "RETROK_h"},
{RETROK_i, Common::KEYCODE_i, "RETROK_i"},
{RETROK_j, Common::KEYCODE_j, "RETROK_j"},
{RETROK_k, Common::KEYCODE_k, "RETROK_k"},
{RETROK_l, Common::KEYCODE_l, "RETROK_l"},
{RETROK_m, Common::KEYCODE_m, "RETROK_m"},
{RETROK_n, Common::KEYCODE_n, "RETROK_n"},
{RETROK_o, Common::KEYCODE_o, "RETROK_o"},
{RETROK_p, Common::KEYCODE_p, "RETROK_p"},
{RETROK_q, Common::KEYCODE_q, "RETROK_q"},
{RETROK_r, Common::KEYCODE_r, "RETROK_r"},
{RETROK_s, Common::KEYCODE_s, "RETROK_s"},
{RETROK_t, Common::KEYCODE_t, "RETROK_t"},
{RETROK_u, Common::KEYCODE_u, "RETROK_u"},
{RETROK_v, Common::KEYCODE_v, "RETROK_v"},
{RETROK_w, Common::KEYCODE_w, "RETROK_w"},
{RETROK_x, Common::KEYCODE_x, "RETROK_x"},
{RETROK_y, Common::KEYCODE_y, "RETROK_y"},
{RETROK_z, Common::KEYCODE_z, "RETROK_z"},
{RETROK_KP0, Common::KEYCODE_KP0, "RETROK_KP0"},
{RETROK_KP1, Common::KEYCODE_KP1, "RETROK_KP1"},
{RETROK_KP2, Common::KEYCODE_KP2, "RETROK_KP2"},
{RETROK_KP3, Common::KEYCODE_KP3, "RETROK_KP3"},
{RETROK_KP4, Common::KEYCODE_KP4, "RETROK_KP4"},
{RETROK_KP5, Common::KEYCODE_KP5, "RETROK_KP5"},
{RETROK_KP6, Common::KEYCODE_KP6, "RETROK_KP6"},
{RETROK_KP7, Common::KEYCODE_KP7, "RETROK_KP7"},
{RETROK_KP8, Common::KEYCODE_KP8, "RETROK_KP8"},
{RETROK_KP9, Common::KEYCODE_KP9, "RETROK_KP9"},
{RETROK_KP_PERIOD, Common::KEYCODE_KP_PERIOD, "RETROK_KP_PERIOD"},
{RETROK_KP_DIVIDE, Common::KEYCODE_KP_DIVIDE, "RETROK_KP_DIVIDE"},
{RETROK_KP_MULTIPLY, Common::KEYCODE_KP_MULTIPLY, "RETROK_KP_MULTIPLY"},
{RETROK_KP_MINUS, Common::KEYCODE_KP_MINUS, "RETROK_KP_MINUS"},
{RETROK_KP_PLUS, Common::KEYCODE_KP_PLUS, "RETROK_KP_PLUS"},
{RETROK_KP_ENTER, Common::KEYCODE_KP_ENTER, "RETROK_KP_ENTER"},
{RETROK_KP_EQUALS, Common::KEYCODE_KP_EQUALS, "RETROK_KP_EQUALS"},
{RETROK_UP, Common::KEYCODE_UP, "RETROK_UP"},
{RETROK_DOWN, Common::KEYCODE_DOWN, "RETROK_DOWN"},
{RETROK_LEFT, Common::KEYCODE_LEFT, "RETROK_LEFT"},
{RETROK_RIGHT, Common::KEYCODE_RIGHT, "RETROK_RIGHT"},
{RETROK_INSERT, Common::KEYCODE_INSERT, "RETROK_INSERT"},
{RETROK_DELETE, Common::KEYCODE_DELETE, "RETROK_DELETE"},
{RETROK_HOME, Common::KEYCODE_HOME, "RETROK_HOME"},
{RETROK_END, Common::KEYCODE_END, "RETROK_END"},
{RETROK_PAGEUP, Common::KEYCODE_PAGEUP, "RETROK_PAGEUP"},
{RETROK_PAGEDOWN, Common::KEYCODE_PAGEDOWN, "RETROK_PAGEDOWN"},
{RETROK_F1, Common::KEYCODE_F1, "RETROK_F1"},
{RETROK_F2, Common::KEYCODE_F2, "RETROK_F2"},
{RETROK_F3, Common::KEYCODE_F3, "RETROK_F3"},
{RETROK_F4, Common::KEYCODE_F4, "RETROK_F4"},
{RETROK_F5, Common::KEYCODE_F5, "RETROK_F5"},
{RETROK_F6, Common::KEYCODE_F6, "RETROK_F6"},
{RETROK_F7, Common::KEYCODE_F7, "RETROK_F7"},
{RETROK_F8, Common::KEYCODE_F8, "RETROK_F8"},
{RETROK_F9, Common::KEYCODE_F9, "RETROK_F9"},
{RETROK_F10, Common::KEYCODE_F10, "RETROK_F10"},
{RETROK_F11, Common::KEYCODE_F11, "RETROK_F11"},
{RETROK_F12, Common::KEYCODE_F12, "RETROK_F12"},
{RETROK_F13, Common::KEYCODE_F13, "RETROK_F13"},
{RETROK_F14, Common::KEYCODE_F14, "RETROK_F14"},
{RETROK_F15, Common::KEYCODE_F15, "RETROK_F15"},
{RETROK_NUMLOCK, Common::KEYCODE_NUMLOCK, "RETROK_NUMLOCK"},
{RETROK_CAPSLOCK, Common::KEYCODE_CAPSLOCK, "RETROK_CAPSLOCK"},
{RETROK_SCROLLOCK, Common::KEYCODE_SCROLLOCK, "RETROK_SCROLLOCK"},
{RETROK_LSHIFT, Common::KEYCODE_LSHIFT, "RETROK_LSHIFT"},
{RETROK_RSHIFT, Common::KEYCODE_RSHIFT, "RETROK_RSHIFT"},
{RETROK_LCTRL, Common::KEYCODE_LCTRL, "RETROK_LCTRL"},
{RETROK_RCTRL, Common::KEYCODE_RCTRL, "RETROK_RCTRL"},
{RETROK_LALT, Common::KEYCODE_LALT, "RETROK_LALT"},
{RETROK_RALT, Common::KEYCODE_RALT, "RETROK_RALT"},
{RETROK_LMETA, Common::KEYCODE_LMETA, "RETROK_LMETA"},
{RETROK_RMETA, Common::KEYCODE_RMETA, "RETROK_RMETA"},
{RETROK_LSUPER, Common::KEYCODE_LSUPER, "RETROK_LSUPER"},
{RETROK_RSUPER, Common::KEYCODE_RSUPER, "RETROK_RSUPER"},
{RETROK_MODE, Common::KEYCODE_MODE, "RETROK_MODE"},
{RETROK_COMPOSE, Common::KEYCODE_COMPOSE, "RETROK_COMPOSE"},
{RETROK_HELP, Common::KEYCODE_HELP, "RETROK_HELP"},
{RETROK_PRINT, Common::KEYCODE_PRINT, "RETROK_PRINT"},
{RETROK_SYSREQ, Common::KEYCODE_SYSREQ, "RETROK_SYSREQ"},
{RETROK_BREAK, Common::KEYCODE_BREAK, "RETROK_BREAK"},
{RETROK_MENU, Common::KEYCODE_MENU, "RETROK_MENU"},
{RETROK_POWER, Common::KEYCODE_POWER, "RETROK_POWER"},
{RETROK_EURO, Common::KEYCODE_EURO, "RETROK_EURO"},
{RETROK_UNDO, Common::KEYCODE_UNDO, "RETROK_UNDO"},
{RETROK_LAST, 0, ""}
};
const struct retro_controller_description retro_controller_list[] = {
{"None", RETRO_DEVICE_NONE},
{"Automatic", RETRO_DEVICE_JOYPAD},
{NULL, 0}
};
const struct retro_controller_info retro_controller_lists[] = {
{retro_controller_list, sizeof(retro_controller_list) / sizeof(retro_controller_list[0])},
{NULL, 0}
};
static struct retro_input_descriptor retro_input_desc[] = {
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B / Fire / Red"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A / 2nd fire / Blue"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y / Green"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X / Yellow"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start / Play"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L / Rewind"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R / Forward"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3"},
{0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3"},
{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X"},
{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y"},
{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X"},
{0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y"},
{0}
};
void mapper_poll_device(void);
bool mapper_set_device_keys(unsigned int retro_device_id, const char *retro_key_value);
uint8 mapper_get_device_key_status(unsigned int retro_device_id);
int16 mapper_get_device_key_value(unsigned int retro_device_id);
int16 mapper_get_device_key_retro_id(unsigned int retro_device_id);
int16 mapper_get_device_key_scummvm_id(unsigned int retro_device_id);
int8 mapper_get_mapper_key_index(int16 key_retro_id, uint8 start_index = 0);
uint8 mapper_get_mapper_key_status(int16 key_retro_id);
int16 mapper_get_mapper_key_value(int16 key_retro_id);
#endif // LIBRETRO_MAPPER_H

View File

@@ -0,0 +1,46 @@
/* Copyright (C) 2024 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "gui/browser.h"
#include "gui/gui-manager.h"
#include "gui/ThemeEval.h"
#include "gui/widget.h"
#include "gui/widgets/list.h"
#include "gui/widgets/popup.h"
#include "gui/widgets/richtext.h"
#define COMMON_HOOKS_FOLDER "scummvm_hooks"
class LibretroOptionsWidget final : public GUI::OptionsContainerWidget {
public:
explicit LibretroOptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain);
~LibretroOptionsWidget() override;
void load() override;
bool save() override;
private:
void defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const override;
void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) override;
bool generatePlaylist(Common::String playlistPath);
bool cleanFolder(Common::String &path);
GUI::StaticTextWidget *_playlistPath;
GUI::StaticTextWidget *_playlistStatus;
GUI::PopUpWidget *_playlistVersion;
GUI::PopUpWidget *_hooksLocation;
GUI::CheckboxWidget *_hooksClear;
};

View File

@@ -0,0 +1,138 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_LIBRETRO_OS_H
#define BACKENDS_LIBRETRO_OS_H
#include "audio/mixer_intern.h"
#include "base/main.h"
//#include "backends/base-backend.h"
#include "common/system.h"
#include "common/mutex.h"
#include "common/list.h"
#include "common/events.h"
#include "backends/modular-backend.h"
#include "graphics/managed_surface.h"
#define BASE_CURSOR_SPEED 4
#define CURSOR_STATUS_DOING_JOYSTICK (1 << 0)
#define CURSOR_STATUS_DOING_MOUSE (1 << 1)
#define CURSOR_STATUS_DOING_X (1 << 2)
#define CURSOR_STATUS_DOING_Y (1 << 3)
#define CURSOR_STATUS_DOING_SLOWER (1 << 4)
#define LIBRETRO_G_SYSTEM dynamic_cast<OSystem_libretro *>(g_system)
/**
* Dummy mutex implementation
*/
class LibretroMutexInternal final : public Common::MutexInternal {
public:
LibretroMutexInternal() {};
~LibretroMutexInternal() override {};
bool lock() override {
return 0;
}
bool unlock() override {
return 0;
};
};
class OSystem_libretro : public EventsBaseBackend, public ModularGraphicsBackend {
private:
int _relMouseX;
int _relMouseY;
float _mouseXAcc;
float _mouseYAcc;
float _dpadXAcc;
float _dpadYAcc;
float _dpadXVel;
float _dpadYVel;
float _adjusted_cursor_speed;
float _inverse_acceleration_time;
uint32 _startTime;
uint8 _cursorStatus;
Common::String s_systemDir;
Common::String s_saveDir;
Common::String s_playlistDir;
Common::List<Common::Event> _events;
public:
Audio::MixerImpl *_mixer;
bool _mouseButtons[2];
bool _ptrmouseButton;
int _mouseX;
int _mouseY;
/* Base */
OSystem_libretro(void);
~OSystem_libretro(void) override;
void initBackend(void) override;
void engineInit(void) override;
void refreshRetroSettings(void);
void refreshScreen(void);
void destroy(void);
void quit() override {}
void resetGraphicsManager(void);
void getScreen(const Graphics::ManagedSurface *&screen);
int16 getScreenWidth(void);
int16 getScreenHeight(void);
bool inLauncher(void);
#ifdef USE_OPENGL
void resetGraphicsContext(void);
#ifdef USE_GLAD
void *getOpenGLProcAddress(const char *name) const override;
#endif
#endif
/* Events */
public:
bool pollEvent(Common::Event &event) override;
uint32 getMillis(bool skipRecord = false) override;
void delayMillis(uint msecs) override;
Common::MutexInternal *createMutex(void) override;
void requestQuit(void);
void resetQuit(void);
void setMousePosition(int x, int y);
/* Utils */
void getTimeAndDate(TimeDate &t, bool skipRecord) const override;
Audio::Mixer *getMixer(void) override;
Common::Path getDefaultConfigFileName(void) override;
void logMessage(LogMessageType::Type type, const char *message) override;
int testGame(const char *filedata, bool autodetect);
void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0) override;
const char *const *buildHelpDialogData() override;
Common::String getSaveDir(void);
GUI::OptionsContainerWidget *buildBackendOptionsWidget(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const override;
void applyBackendSettings() override;
private:
bool parseGameName(const Common::String &gameName, Common::String &engineId, Common::String &gameId);
bool checkPathSetting(const char *setting, Common::String const &defaultPath, bool isDirectory = true);
void setLibretroDir(const char *path, Common::String &var);
/* Inputs */
public:
void processInputs(void);
void processKeyEvent(bool down, unsigned keycode, uint32 character, uint16 key_modifiers);
private:
void updateMouseXY(float deltaAcc, float *cumulativeXYAcc, int doing_x);
void getMouseXYFromAnalog(bool is_x, int16 coor);
void getMouseXYFromButton(bool is_x, int16 sign);
};
#endif

View File

@@ -0,0 +1,67 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef LIBRETRO_THREADS_H
#define LIBRETRO_THREADS_H
/* ScummVM doesn't have a top-level main loop that we can use, so instead we run it in its own thread
* and switch between it and the main thread. Calling these function will block the current thread
* and unblock the other. Each function should be called from the other thread.
*/
void retro_switch_to_emu_thread(void);
void retro_switch_to_main_thread(void);
/* Initialize the emulation thread and any related resources.
*
* This function should be called from the main thread.
*/
bool retro_init_emu_thread(void);
/* Destroy the emulation thread and any related resources. Only call this after the emulation thread
* has finished (or canceled) and joined.
*
* This function should be called from the main thread.
*/
void retro_deinit_emu_thread(void);
/* Returns true if the emulation thread was initialized successfully.
*
* This function should be called from the main thread.
*/
bool retro_emu_thread_initialized(void);
/* Returns true if the emulation thread has exited naturally.
*
* This function can be called from either the main or the emulation thread.
*/
bool retro_emu_thread_exited(void);
/* Returns scummvm_main return code or -1 if not available */
int retro_get_scummvm_res(void);
/* Returns true if the emulation thread was started successfully.
*
* This function should be called from the main thread.
*/
bool retro_emu_thread_started(void);
#endif

View File

@@ -0,0 +1,44 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef LIBRETRO_TIMER_H
#define LIBRETRO_TIMER_H
// Thread switch caller
#define THREAD_SWITCH_POLL (1 << 0)
#define THREAD_SWITCH_DELAY (1 << 1)
#define THREAD_SWITCH_UPDATE (1 << 2)
#include "backends/timer/default/default-timer.h"
#include "backends/platform/libretro/include/libretro-defs.h"
class LibretroTimerManager : public DefaultTimerManager {
uint32 _interval;
uint32 _nextSwitchTime;
uint32 _spentOnMainThread;
uint8 _threadSwitchCaller;
public:
LibretroTimerManager(uint32 refresh_rate);
~LibretroTimerManager(void) {};
void switchThread(uint8 caller = 0);
bool checkThread(uint8 caller = 0);
uint32 timeToNextSwitch(void);
uint32 spentOnMainThread(void);
uint8 getThreadSwitchCaller(void);
};
#endif // LIBRETRO_TIMER_H

View File

@@ -0,0 +1,60 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>
#include <new>
#include <limits>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
/* newlib ctype.h defines _X for hex digit flag.
This conflicts with the use of _X as a variable name. */
#undef _X
#ifndef USE_HIGHRES
#define RES_W_OVERLAY 320
#define RES_H_OVERLAY 200
#define RES_INIT_MAX_W 320
#define RES_INIT_MAX_H 200
#else
#define RES_W_OVERLAY 1280
#define RES_H_OVERLAY 720
#define RES_INIT_MAX_W 1280 /* crab engine */
#define RES_INIT_MAX_H 768 /* e.g. director engine */
#endif
// HACK: With MinGW, GRIM engine seems to crash when using setjmp and longjmp if not using builtin versions
#if defined __MINGW64__ || defined __MINGW32__
#include <setjmp.h>
#undef setjmp
#undef longjmp
#define setjmp(a) (__builtin_setjmp(a))
#define longjmp(a, b) (__builtin_longjmp(a, b))
#endif

View File

@@ -0,0 +1,277 @@
#pragma once
#include <wiiu/types.h>
#include "time.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct OSThread OSThread;
typedef int (*OSThreadEntryPointFn)(int argc, const char **argv);
typedef void (*OSThreadCleanupCallbackFn)(OSThread *thread, void *stack);
typedef void (*OSThreadDeallocatorFn)(OSThread *thread, void *stack);
enum OS_THREAD_STATE
{
OS_THREAD_STATE_NONE = 0,
/*! Thread is ready to run */
OS_THREAD_STATE_READY = 1 << 0,
/*! Thread is running */
OS_THREAD_STATE_RUNNING = 1 << 1,
/*! Thread is waiting, i.e. on a mutex */
OS_THREAD_STATE_WAITING = 1 << 2,
/*! Thread is about to terminate */
OS_THREAD_STATE_MORIBUND = 1 << 3,
};
typedef uint8_t OSThreadState;
enum OS_THREAD_REQUEST
{
OS_THREAD_REQUEST_NONE = 0,
OS_THREAD_REQUEST_SUSPEND = 1,
OS_THREAD_REQUEST_CANCEL = 2,
};
typedef uint32_t OSThreadRequest;
enum OS_THREAD_ATTRIB
{
/*! Allow the thread to run on CPU0. */
OS_THREAD_ATTRIB_AFFINITY_CPU0 = 1 << 0,
/*! Allow the thread to run on CPU1. */
OS_THREAD_ATTRIB_AFFINITY_CPU1 = 1 << 1,
/*! Allow the thread to run on CPU2. */
OS_THREAD_ATTRIB_AFFINITY_CPU2 = 1 << 2,
/*! Allow the thread to run any CPU. */
OS_THREAD_ATTRIB_AFFINITY_ANY = ((1 << 0) | (1 << 1) | (1 << 2)),
/*! Start the thread detached. */
OS_THREAD_ATTRIB_DETACHED = 1 << 3,
/*! Enables tracking of stack usage. */
OS_THREAD_ATTRIB_STACK_USAGE = 1 << 5
};
typedef uint8_t OSThreadAttributes;
#define OS_CONTEXT_TAG 0x4F53436F6E747874ull
typedef struct OSContext
{
/*! Should always be set to the value OS_CONTEXT_TAG. */
uint64_t tag;
uint32_t gpr[32];
uint32_t cr;
uint32_t lr;
uint32_t ctr;
uint32_t xer;
uint32_t srr0;
uint32_t srr1;
uint32_t __unknown[0x5];
uint32_t fpscr;
double fpr[32];
uint16_t spinLockCount;
uint16_t state;
uint32_t gqr[8];
uint32_t __unknown0;
double psf[32];
uint64_t coretime[3];
uint64_t starttime;
uint32_t error;
uint32_t __unknown1;
uint32_t pmc1;
uint32_t pmc2;
uint32_t pmc3;
uint32_t pmc4;
uint32_t mmcr0;
uint32_t mmcr1;
} OSContext;
typedef struct OSMutex OSMutex;
typedef struct OSFastMutex OSFastMutex;
typedef struct OSMutexQueue
{
OSMutex *head;
OSMutex *tail;
void *parent;
uint32_t __unknown;
} OSMutexQueue;
typedef struct OSFastMutexQueue
{
OSFastMutex *head;
OSFastMutex *tail;
} OSFastMutexQueue;
typedef struct
{
OSThread *prev;
OSThread *next;
} OSThreadLink;
typedef struct
{
OSThread *head;
OSThread *tail;
void *parent;
uint32_t __unknown;
} OSThreadQueue;
typedef struct
{
OSThread *head;
OSThread *tail;
} OSThreadSimpleQueue;
#define OS_THREAD_TAG 0x74487244u
#pragma pack(push, 1)
typedef struct __attribute__ ((aligned (8))) OSThread
{
OSContext context;
/*! Should always be set to the value OS_THREAD_TAG. */
uint32_t tag;
/*! Bitfield of OS_THREAD_STATE */
OSThreadState state;
/*! Bitfield of OS_THREAD_ATTRIB */
OSThreadAttributes attr;
/*! Unique thread ID */
uint16_t id;
/*! Suspend count (increased by OSSuspendThread). */
int32_t suspendCounter;
/*! Actual priority of thread. */
int32_t priority;
/*! Base priority of thread, 0 is highest priority, 31 is lowest priority. */
int32_t basePriority;
/*! Exit value */
int32_t exitValue;
uint32_t unknown0[0x9];
/*! Queue the thread is currently waiting on */
OSThreadQueue *queue;
/*! Link used for thread queue */
OSThreadLink link;
/*! Queue of threads waiting to join this thread */
OSThreadQueue joinQueue;
/*! Mutex this thread is waiting to lock */
OSMutex *mutex;
/*! Queue of mutexes this thread owns */
OSMutexQueue mutexQueue;
/*! Link for global active thread queue */
OSThreadLink activeLink;
/*! Stack start (top, highest address) */
void *stackStart;
/*! Stack end (bottom, lowest address) */
void *stackEnd;
/*! Thread entry point */
OSThreadEntryPointFn entryPoint;
uint32_t unknown1[0x77];
/*! Thread specific values, accessed with OSSetThreadSpecific and OSGetThreadSpecific. */
uint32_t specific[0x10];
uint32_t unknown2;
/*! Thread name, accessed with OSSetThreadName and OSGetThreadName. */
const char *name;
uint32_t unknown3;
/*! The stack pointer passed in OSCreateThread. */
void *userStackPointer;
/*! Called just before thread is terminated, set with OSSetThreadCleanupCallback */
OSThreadCleanupCallbackFn cleanupCallback;
/*! Called just after a thread is terminated, set with OSSetThreadDeallocator */
OSThreadDeallocatorFn deallocator;
/*! If TRUE then a thread can be cancelled or suspended, set with OSSetThreadCancelState */
BOOL cancelState;
/*! Current thread request, used for cancelleing and suspending the thread. */
OSThreadRequest requestFlag;
/*! Pending suspend request count */
int32_t needSuspend;
/*! Result of thread suspend */
int32_t suspendResult;
/*! Queue of threads waiting for a thread to be suspended. */
OSThreadQueue suspendQueue;
uint32_t unknown4[0x2B];
} OSThread;
#pragma pack(pop)
void
OSCancelThread(OSThread *thread);
int32_t OSCheckActiveThreads();
int32_t OSCheckThreadStackUsage(OSThread *thread);
void OSClearThreadStackUsage(OSThread *thread);
void OSContinueThread(OSThread *thread);
BOOL OSCreateThread(OSThread *thread, OSThreadEntryPointFn entry, int32_t argc, char *argv,
void *stack, uint32_t stackSize, int32_t priority, OSThreadAttributes attributes);
void OSDetachThread(OSThread *thread);
void OSExitThread(int32_t result);
void OSGetActiveThreadLink(OSThread *thread, OSThreadLink *link);
OSThread *OSGetCurrentThread();
OSThread *OSGetDefaultThread(uint32_t coreID);
uint32_t OSGetStackPointer();
uint32_t OSGetThreadAffinity(OSThread *thread);
const char *OSGetThreadName(OSThread *thread);
int32_t OSGetThreadPriority(OSThread *thread);
uint32_t OSGetThreadSpecific(uint32_t id);
BOOL OSIsThreadSuspended(OSThread *thread);
BOOL OSIsThreadTerminated(OSThread *thread);
BOOL OSJoinThread(OSThread *thread, int *threadResult);
int32_t OSResumeThread(OSThread *thread);
BOOL OSRunThread(OSThread *thread, OSThreadEntryPointFn entry, int argc, const char **argv);
BOOL OSSetThreadAffinity(OSThread *thread, uint32_t affinity);
BOOL OSSetThreadCancelState(BOOL state);
OSThreadCleanupCallbackFn OSSetThreadCleanupCallback(OSThread *thread,
OSThreadCleanupCallbackFn callback);
OSThreadDeallocatorFn OSSetThreadDeallocator(OSThread *thread, OSThreadDeallocatorFn deallocator);
void OSSetThreadName(OSThread *thread, const char *name);
BOOL OSSetThreadPriority(OSThread *thread, int32_t priority);
BOOL OSSetThreadRunQuantum(OSThread *thread, uint32_t quantum);
void OSSetThreadSpecific(uint32_t id, uint32_t value);
BOOL OSSetThreadStackUsage(OSThread *thread);
void OSSleepThread(OSThreadQueue *queue);
void OSSleepTicks(OSTime ticks);
uint32_t OSSuspendThread(OSThread *thread);
void OSTestThreadCancel();
void OSWakeupThread(OSThreadQueue *queue);
void OSYieldThread();
void OSInitThreadQueue(OSThreadQueue *queue);
void OSInitThreadQueueEx(OSThreadQueue *queue, void *parent);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,49 @@
#pragma once
#include <wiiu/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define OSOneSecond ((OSGetSystemInfo()->clockSpeed) / 4)
#define OSMilliseconds(val) ((((uint64_t)(val)) * (uint64_t)(OSOneSecond)) / 1000ull)
#define OSMicroseconds(val) ((((uint64_t)(val)) * (uint64_t)(OSOneSecond)) / 1000000ull)
#define OSNanoseconds(val) ((((uint64_t)(val)) * (uint64_t)(OSOneSecond)) / 1000000000ull)
#define wiiu_bus_clock (17 * 13 * 5*5*5 * 5*5*5 * 3*3 * 2*2*2) /* 248.625000 Mhz */
#define wiiu_cpu_clock (17 * 13 * 5*5*5 * 5*5*5 * 5 * 3*3 * 2*2*2) /* 1243.125000 Mhz */
#define wiiu_timer_clock (17 * 13 * 5*5*5 * 5*5*5 * 3*3 * 2) /* 62.156250 Mhz */
#define sec_to_ticks(s) (((17 * 13 * 5*5*5 * 5*5*5 * 3*3 * 2) * (uint64_t)(s)))
#define ms_to_ticks(ms) (((17 * 13 * 5*5*5 * 3*3) * (uint64_t)(ms)) / (2*2))
#define us_to_ticks(us) (((17 * 13 * 3*3) * (uint64_t)(us)) / (2*2* 2*2*2))
#define ns_to_ticks(ns) (((17 * 13 * 3*3) * (uint64_t)(ns)) / (2*2* 2*2*2* 2*2*2 *5*5*5))
#define ticks_to_sec(ticks) (((uint64_t)(ticks)) / (17 * 13 * 5*5*5 * 5*5*5 * 3*3 * 2))
#define ticks_to_ms(ticks) (((uint64_t)(ticks) * (2*2)) / (17 * 13 * 5*5*5 * 3*3))
#define ticks_to_us(ticks) (((uint64_t)(ticks) * (2*2 * 2*2*2)) / (17 * 13 * 3*3))
#define ticks_to_ns(ticks) (((uint64_t)(ticks) * (2*2 * 2*2*2 * 2*2*2 * 5*5*5)) / (17 * 13 * 3*3))
typedef int32_t OSTick;
typedef int64_t OSTime;
typedef struct
{
int32_t tm_sec;
int32_t tm_min;
int32_t tm_hour;
int32_t tm_mday;
int32_t tm_mon;
int32_t tm_year;
}OSCalendarTime;
OSTime OSGetTime();
OSTime OSGetSystemTime();
OSTick OSGetTick();
OSTick OSGetSystemTick();
OSTime OSCalendarTimeToTicks(OSCalendarTime *calendarTime);
void OSTicksToCalendarTime(OSTime time, OSCalendarTime *calendarTime);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,41 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef int BOOL;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
typedef volatile u64 vu64;
typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef volatile s64 vs64;
typedef float f32;
typedef double f64;
typedef volatile float vf32;
typedef volatile double vf64;
#define countof(array) (sizeof(array) / sizeof(*array))

View File

@@ -0,0 +1,45 @@
LOCAL_PATH := $(call my-dir)
ROOT_PATH := $(LOCAL_PATH)/..
TARGET_NAME := scummvm
HAVE_OPENGLES2 := 1
USE_IMGUI := 0
# Reset flags not reset to Makefile.common
DEFINES :=
# All current 64-bit archs have 64 in the abi name
ifneq (,$(findstring 64,$(TARGET_ARCH_ABI)))
TARGET_64BIT := 1
endif
ifneq (,$(findstring arm64,$(TARGET_ARCH_ABI)))
HAVE_NEON := 1
endif
include $(ROOT_PATH)/Makefile.common
include $(addprefix $(SCUMMVM_PATH)/, $(addsuffix /module.mk,$(MODULES)))
OBJS_MODULES := $(addprefix $(SCUMMVM_PATH)/, $(foreach MODULE,$(MODULES),$(MODULE_OBJS-$(MODULE))))
#TODO:
# -O2 or higher causes segmentation fault with some engines (e.g. hopkins)
# -Fortify triggers abort with some engines (e.g. sword25)
COREFLAGS := $(DEFINES) -DUSE_CXX11 -O1 -U_FORTIFY_SOURCE -Wno-undefined-var-template
ifeq ($(TARGET_ARCH),arm)
COREFLAGS += -D_ARM_ASSEM_
endif
include $(CLEAR_VARS)
LOCAL_MODULE := retro
LOCAL_MODULE_FILENAME := libretro
LOCAL_SRC_FILES := $(DETECT_OBJS:%.o=$(SCUMMVM_PATH)/%.cpp) $(OBJS_DEPS:%.o=%.c) $(OBJS_MODULES:%.o=%.cpp) $(OBJS:%.o=%.cpp)
LOCAL_C_INCLUDES := $(subst -I,,$(INCLUDES))
LOCAL_CPPFLAGS := $(COREFLAGS) -std=c++11
LOCAL_CFLAGS := $(COREFLAGS)
LOCAL_LDFLAGS := -Wl,-version-script=$(ROOT_PATH)/link.T
LOCAL_LDLIBS := -lz -llog
LOCAL_CPP_FEATURES := rtti
LOCAL_ARM_MODE := arm
include $(BUILD_SHARED_LIBRARY)

View File

@@ -0,0 +1,2 @@
APP_ABI := all
APP_STL := c++_static

View File

@@ -0,0 +1,5 @@
{
global: retro_*;
local: *;
};

View File

@@ -0,0 +1,32 @@
agi
agos
agos2
cine
cruise
draci
drascula
eob
gob
groovie
he
ihnm
kyra
lol
lure
made
mortevielle
parallaction
queen
saga
sci
sci32
scumm
scumm_7_8
sherlock
sky
sword1
sword2
teenagent
tinsel
touche
tucker

View File

@@ -0,0 +1,20 @@
# Specific platform overrides, to be dropped asap...
# -DEMSCRIPTEN flag should not be needed for emscripten build of libretro core, as it is a specific Project flag
# needed for emscripten backend. Anyways in several places, both in ScummVM and libretro-common,
# it is used as platform flag instead of __EMSCRIPTEN__, hence we need to keep EMSCRIPTEN flag for now, and apply
# the following workaround to solve relevant conflicts of the libretro core with emscripten backend at build time.
ifeq ($(platform), emscripten)
backends/fs/emscripten/%.o:
@:
backends/libbackends.a:
@:
MODULE_OBJS-backends := $(filter-out backends/fs/emscripten/%,$(MODULE_OBJS-backends))
backends/libbackends.a: $(MODULE_OBJS-backends)
$(AR) $@ $(MODULE_OBJS-backends)
$(RANLIB) $@
$(SCUMMVM_PATH)/gui/textviewer.o: CXXFLAGS += -UEMSCRIPTEN
$(SCUMMVM_PATH)/gui/textviewer.o: CFLAGS += -UEMSCRIPTEN
$(SCUMMVM_PATH)/gui/textviewer.o: CPPFLAGS += -UEMSCRIPTEN
endif

View File

@@ -0,0 +1,170 @@
#!/bin/bash
# Copyright (C) 2022 Giovanni Cascione <ing.cascione@gmail.com>
#
# This program 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 Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
set -e
function get_firmware_entry(){
echo "
firmware$1_desc = \"$2\"
firmware$1_path = \"$3/$2\"
firmware$1_opt = \"true\"
"
}
function process_group(){
local dirname="$1"
shift
local target="$1"
shift
local arr=("$@")
for item in "${arr[@]}"; do
[ $target = "bundle" ] && cp $item "${TMP_PATH}/${dirname}/"
fragment=$(get_firmware_entry $count $(echo "$item" | sed "s|^.*/||g") "$dirname")
CORE_INFO_DATS="${CORE_INFO_DATS}${fragment}"
count=$(expr $count + 1)
done
}
# Externally passed variables shall be:
# $1 [REQ] BUILD_PATH
# $2 [REQ] SCUMMVM_PATH
# $3 [REQ] target build ("bundle" to build scummvm.zip, any other string to build core info file)
# $4 [OPT] target name (prefix for core info file)
# $5 [OPT] displayed core name (shown in frontend)
# $6 [OPT] allowed extensions - backup if ScummVM.dat is not available
# $7 [OPT] target scummvm folder name in frontend system folder
# $8 [OPT] target extra folder name in scummvm system folder
# $9 [OPT] target theme folder name in scummvm system folder
# Exit if in parameters are not provided
if [ -z $1 ] || [ -z $2 ] || [ -z $3 ] ; then
exit 1
fi
[ -z $4 ] && INFO_FILE_PRE=scummvm || INFO_FILE_PRE=$4
[ -z $5 ] && NICE_NAME=ScummVM || NICE_NAME=$5
[ -z $6 ] && ALLOWED_EXT=scummvm || ALLOWED_EXT=$6
[ -z $7 ] && BUNDLE_DIR=scummvm || BUNDLE_DIR="$7"
[ -z $8 ] && BUNDLE_DATAFILES_DIR="${BUNDLE_DIR}/extra" || BUNDLE_DATAFILES_DIR="${BUNDLE_DIR}/$8"
[ -z $9 ] && BUNDLE_THEME_DIR="${BUNDLE_DIR}/theme" || BUNDLE_THEME_DIR="${BUNDLE_DIR}/$9"
# Set variables
BUILD_PATH="$1"
SCUMMVM_PATH="$2"
TMP_PATH="${BUILD_PATH}/tmp_data"
TARGET_PATH="${BUILD_PATH}"
BUNDLE_ZIP_FILE="${BUNDLE_DIR}.zip"
BUNDLE_LOCAL_DATAFILES_DIR="${BUILD_PATH}/dist"
# Retrieve data file info from ScummVM source
THEMES_LIST=$(cat "${SCUMMVM_PATH}/dists/scummvm.rc" 2>/dev/null | grep FILE.*gui/themes.*\* | sed "s|.*\"\(.*\)\"|${SCUMMVM_PATH}/\1|g")
DATAFILES_LIST_DATA=$(cat "${SCUMMVM_PATH}/dists/engine-data/engine_data.mk" 2>/dev/null| grep DIST_FILES_LIST | sed "s|DIST_FILES_LIST += \(.*\)|${SCUMMVM_PATH}/\1|g")
DATAFILES_LIST_DATA_BIG=$(cat "${SCUMMVM_PATH}/dists/engine-data/engine_data_big.mk" 2>/dev/null| grep DIST_FILES_LIST | sed "s|DIST_FILES_LIST += \(.*\)|${SCUMMVM_PATH}/\1|g")
DATAFILES_LIST_DATA_CORE=$(cat "${SCUMMVM_PATH}/dists/engine-data/engine_data_core.mk" 2>/dev/null| grep DIST_FILES_LIST | sed "s|DIST_FILES_LIST += \(.*\)|${SCUMMVM_PATH}/\1|g")
SOUNDFONTS_LIST=$(cat "${SCUMMVM_PATH}/dists/scummvm.rc" 2>/dev/null| grep FILE.*dists/soundfonts | sed "s|.*\"\(.*\)\"|${SCUMMVM_PATH}/\1|g")
SHADERS_LIST=$(cat "${SCUMMVM_PATH}/dists/scummvm.rc" 2>/dev/null| grep FILE.*/shaders/ | sed "s|.*\"\(.*\)\"|${SCUMMVM_PATH}/\1|g")
# Put retrieved data into arrays
set +e
read -a THEME_ARRAY -d '' -r <<< "${THEMES_LIST}"
read -a DATAFILES_ARRAY -d '' -r <<< "$DATAFILES_LIST_DATA $DATAFILES_LIST_DATA_BIG $DATAFILES_LIST_DATA_CORE"
read -a SOUNDFONTS_ARRAY -d '' -r <<< "$SOUNDFONTS_LIST"
read -a SHADERS_ARRAY -d '' -r <<< "$SHADERS_LIST"
set -e
# Add specific data files
DATAFILES_ARRAY[${#DATAFILES_ARRAY[@]}]="${SCUMMVM_PATH}"/backends/vkeybd/packs/vkeybd_default.zip
# Make sure target folders exist
[ $3 = "bundle" ] && mkdir -p "${TMP_PATH}/${BUNDLE_THEME_DIR}/"
[ $3 = "bundle" ] && mkdir -p "${TMP_PATH}/${BUNDLE_DATAFILES_DIR}/"
[ $3 = "bundle" ] && mkdir -p "${TMP_PATH}/${BUNDLE_DATAFILES_DIR}/shaders"
count=0
# Process themes
process_group "$BUNDLE_THEME_DIR" $3 ${THEME_ARRAY[@]}
# Process datafiles
process_group "$BUNDLE_DATAFILES_DIR" $3 ${DATAFILES_ARRAY[@]}
process_group "$BUNDLE_DATAFILES_DIR" $3 ${SOUNDFONTS_ARRAY[@]}
process_group "$BUNDLE_DATAFILES_DIR/shaders" $3 ${SHADERS_ARRAY[@]}
# Process additional local bundle files
if [ -d "$BUNDLE_LOCAL_DATAFILES_DIR" -a ! -z "$(ls -A ${BUNDLE_LOCAL_DATAFILES_DIR} 2>/dev/null)" ] ; then
for item in $BUNDLE_LOCAL_DATAFILES_DIR/*; do
[ ! $(echo "$item" | sed "s|^.*/||g") = "README.md" ] && LOCAL_EXTRA_ARRAY+=("$item")
done
process_group "$BUNDLE_DATAFILES_DIR" $3 ${LOCAL_EXTRA_ARRAY[@]}
fi
if [ ! $3 = "bundle" ]; then
# Create core.info file
set +e
read -d '' CORE_INFO_CONTENT <<EOF
# Software Information
display_name = "$NICE_NAME"
authors = "ScummVM Team"
supported_extensions = "$ALLOWED_EXT"
corename = "$NICE_NAME"
categories = "Game"
license = "GPLv3"
permissions = ""
display_version = $(cat $SCUMMVM_PATH/base/internal_version.h 2>/dev/null | grep SCUMMVM_VERSION | sed "s|^.*SCUMMVM_VERSION *||g")
# Hardware Information
manufacturer = "Various"
systemname = "Game engine"
systemid = "scummvm"
# Libretro Features
database = "ScummVM"
supports_no_game = "true"
savestate = "false"
savestate_features = "null"
cheats = "false"
input_descriptors = "true"
memory_descriptors = "false"
libretro_saves = "false"
core_options = "true"
core_options_version = "1.3"
load_subsystem = "false"
hw_render = "false"
needs_fullpath = "true"
disk_control = "false"
is_experimental = "false"
# Firmware / BIOS
firmware_count = $count
EOF
set -e
CORE_INFO_CONTENT="${CORE_INFO_CONTENT}${CORE_INFO_DATS}
description = \"The ScummVM official port to libretro core.\""
echo "$CORE_INFO_CONTENT" > "${TARGET_PATH}/${INFO_FILE_PRE}_libretro.info"
echo "${INFO_FILE_PRE}_libretro.info created successfully"
else
# Create archive
rm -f "${TARGET_PATH}/$BUNDLE_ZIP_FILE"
cd "${TMP_PATH}"
zip -rq "${TARGET_PATH}/$BUNDLE_ZIP_FILE" "${BUNDLE_DIR}" > /dev/null 2>&1
cd - > /dev/null
# Remove temporary directories
rm -rf "$TMP_PATH"
echo "$BUNDLE_ZIP_FILE created successfully"
fi

View File

@@ -0,0 +1,119 @@
#!/bin/bash
# Copyright (C) 2022 Giovanni Cascione <ing.cascione@gmail.com>
#
# This program 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 Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
# Externally passed variables shall be:
# $1 [REQ] BUILD_PATH
# $2 [REQ] SCUMMVM_PATH
# $3 [REQ] NO_WIP [0,1]
# $4 [REQ] STATIC_LINKING [0,1]
# $5 [REQ] LITE [0,1,2]
# $[...] [OPT] Engines dependencies/components not available
set -e
# Exit if in parameters are not provided
if [ -z $1 ] || [ -z $2 ] || [ -z $3 ] || [ -z $4 ] || [ -z $5 ] ; then
exit 1
fi
# Get parameters
BUILD_PATH="$1"
shift
SCUMMVM_PATH="$1"
shift
NO_WIP=$1
shift
STATIC_LINKING=$1
shift
LITE=$1
shift
no_deps_comps=$@
cd "${SCUMMVM_PATH}"
# Retrieve all configure functions
sed -i.bak -e "s/exit 0/return 0/g" configure
. configure -h > /dev/null 2>&1
mv configure.bak configure > /dev/null 2>&1
_parent_engines_list=""
tot_deps=""
# Separate unavailable dependencies from components
for item in $no_deps_comps ; do
case $item in
component_*)
append_var no_comps "${item#component_}"
;;
*)
append_var no_deps "${item}"
;;
esac
done
# Test NO_WIP
[ $NO_WIP -ne 1 ] && engine_enable_all
# Test LITE
[ $LITE -ne 0 ] && engine_disable_all
if [ $LITE -eq 1 ] ; then
for eng in $(cat "${BUILD_PATH}"/lite_engines.list) ; do
engine_enable "$eng"
done
fi
# Define engines list
for a in $_engines ; do
# Collect all default engines dependencies and force to yes
for dep in $(get_var _engine_${a}_deps) ; do
found=0
for rec_dep in $tot_deps ; do
[ $dep = $rec_dep ] && found=1
done
[ $found -eq 0 ] && append_var tot_deps "$dep"
done
done
# Set all deps to yes then set no for the one in no_deps list. Engines will be disabled in engines.awk if needed
for dep in $tot_deps ; do
set_var _$dep yes
done
for dep in $no_deps ; do
set_var _$dep no
done
# Disable unavailable components
for comp in $(get_var _components); do
for dep in $no_comps ; do
if [ $comp = $dep ] ; then
set_var _feature_${comp}_settings no
break
fi
done
done
# Create needed engines build files
awk -f "./engines.awk" < /dev/null > /dev/null 2>&1
mkdir -p "engines"
copy_if_changed engines/engines.mk.new "engines/engines.mk"
copy_if_changed engines/detection_table.h.new "engines/detection_table.h"
copy_if_changed engines/plugins_table.h.new "engines/plugins_table.h"
echo 0

View File

@@ -0,0 +1,76 @@
#!/bin/bash
# Copyright (C) 2022 Giovanni Cascione <ing.cascione@gmail.com>
#
# This program 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 Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
# Externally passed variables shall be:
# $1 [REQ] repository URL
# $2 [REQ] target commit
# $3 [REQ] submodules folder
# $4 [REQ] allow dirty submodules [0,1]
# $5 [OPT] submodule folder (if not specified will be the same name of the repository)
# Any error response will interrupt the script and will not reach the "0" output, to be used for success test upstream
set -e
TARGET_URL=$1
TARGET_COMMIT=$2
SUBMODULES_PATH=$3
[ -z $4 ] && ALLOW_DIRTY=0 || ALLOW_DIRTY=$4
[ -z $5 ] && SUBMODULE_FOLDER=$(echo $TARGET_URL | sed "s|.*/||") || SUBMODULE_FOLDER=$5
clone=0
reset=0
# Exit if in parameters are not provided
if [ -z $TARGET_URL ] || [ -z $TARGET_COMMIT ] || [ -z $SUBMODULES_PATH ] || [ -z $SUBMODULE_FOLDER ] ; then
exit 1
fi
# Create submodules folder if does not exist and move into it
[ ! -d $SUBMODULES_PATH ] && mkdir -p $SUBMODULES_PATH
cd $SUBMODULES_PATH
# Folder exists
if [ -d $SUBMODULE_FOLDER ]; then
# Folder is not our repo, not our commit or not git repo at all, remove and clone (no history) again
if [ ! $(cd $SUBMODULE_FOLDER && git config --get remote.origin.url 2>/dev/null) = $TARGET_URL ] || [ ! $(cd $SUBMODULE_FOLDER && git rev-parse HEAD 2>/dev/null) = $TARGET_COMMIT ] ; then
rm -rf ${SUBMODULE_FOLDER} && clone=1
fi
# Dirty repo in folder, reset hard
[ $ALLOW_DIRTY -ne 1 ] && [ $clone -ne 1 ] && [ ! -z "$(cd $SUBMODULE_FOLDER && git diff --shortstat 2>/dev/null)" ] && reset=1
# Folder does not exist
else
clone=1
fi
# Apply collected actions
if [ $clone -eq 1 ] ; then
mkdir -p $SUBMODULE_FOLDER
git -C $SUBMODULE_FOLDER init > /dev/null 2>&1
git -C $SUBMODULE_FOLDER remote add origin $TARGET_URL > /dev/null 2>&1
git -C $SUBMODULE_FOLDER fetch --depth 1 origin $TARGET_COMMIT > /dev/null 2>&1
git -C $SUBMODULE_FOLDER checkout FETCH_HEAD > /dev/null 2>&1
git -C $SUBMODULE_FOLDER submodule update --init --recursive --depth 1 > /dev/null 2>&1
fi
cd $SUBMODULE_FOLDER
[ $reset -eq 1 ] && git reset --hard > /dev/null 2>&1
# Success
echo 0

View File

@@ -0,0 +1,29 @@
#!/bin/bash
# Copyright (C) 2022 Giovanni Cascione <ing.cascione@gmail.com>
#
# This program 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 Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
# This script is to extract shared modules definitions from ScummVM
# Makefile.common, in order to be in sync with modifications upstream
# Externally passed variables shall be:
# $1 [REQ] ScummVM Makefile.common full path
if [ -f "$1" ] ; then
sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/§/g' -e 's|.*-include engines/engines.mk||' -e 's/###.*//' -e 's/§/\n/g' -e 's|MODULES|SHARED_MODULES|g' "$1"
else
printf "\$(error Error retrieving shared modules definitions from main Makefile.common)"
fi

View File

@@ -0,0 +1,9 @@
this_lib_available := no
ifeq ($(USE_SYSTEM_$(shell printf ' $(this_lib_flags)' | sed -e "s|.*-l||" -e "s| .*||")), 1)
this_lib_available := $(call sharedlibs_is_lib_available)
endif
$(call sharedlibs_system_lib_message)
ifeq ($(this_lib_available), yes)
LDFLAGS += $(this_lib_flags)
INCLUDES += $(sharedlibs_this_lib_includes)
endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __LIBRETRO__
// Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h.
// Also with clock() in sys/time.h in some Mac OS X SDKs.
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir
#define FORBIDDEN_SYMBOL_EXCEPTION_exit // Needed for IRIX's unistd.h
#include "backends/platform/libretro/include/libretro-fs-factory.h"
#include "backends/platform/libretro/include/libretro-fs.h"
AbstractFSNode *LibRetroFilesystemFactory::makeRootFileNode() const {
return new LibRetroFilesystemNode("/");
}
AbstractFSNode *LibRetroFilesystemFactory::makeCurrentDirectoryFileNode() const {
#ifdef PLAYSTATION3
return new LibRetroFilesystemNode("/");
#else
char *cwd = getcwd(NULL, 0);
AbstractFSNode *node = cwd ? new LibRetroFilesystemNode(Common::String(cwd)) : NULL;
if (cwd)
free(cwd);
return node;
#endif
}
AbstractFSNode *LibRetroFilesystemFactory::makeFileNodePath(const Common::String &path) const {
assert(!path.empty());
return new LibRetroFilesystemNode(path);
}
#endif

View File

@@ -0,0 +1,263 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h.
// Also with clock() in sys/time.h in some Mac OS X SDKs.
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir
#define FORBIDDEN_SYMBOL_EXCEPTION_getenv
#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
#define FORBIDDEN_SYMBOL_EXCEPTION_exit // Needed for IRIX's unistd.h
#include <file/file_path.h>
#include <retro_dirent.h>
#include <retro_stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include "backends/platform/libretro/include/libretro-fs.h"
#include "backends/fs/stdiostream.h"
#include "common/algorithm.h"
void LibRetroFilesystemNode::setFlags() {
const char *fspath = _path.c_str();
_isValid = path_is_valid(fspath);
_isDirectory = path_is_directory(fspath);
_isReadable = access(fspath, R_OK) == 0;
_isWritable = access(_path.c_str(), W_OK) == 0;
}
LibRetroFilesystemNode::LibRetroFilesystemNode(const Common::String &p) {
assert(p.size() > 0);
// Expand "~/" to the value of the HOME env variable
if (p.hasPrefix("~/") || p.hasPrefix("~\\")) {
Common::String homeDir = getHomeDir();
if (homeDir.empty())
homeDir = ".";
// Skip over the tilda. We know that p contains at least
// two chars, so this is safe:
_path = homeDir + (p.c_str() + 1);
} else
_path = p;
char portable_path[_path.size() + 1];
strcpy(portable_path, _path.c_str());
pathname_make_slashes_portable(portable_path);
// Normalize the path (that is, remove unneeded slashes etc.)
_path = Common::normalizePath(Common::String(portable_path), '/');
_displayName = Common::lastPathComponent(_path, '/');
setFlags();
}
AbstractFSNode *LibRetroFilesystemNode::getChild(const Common::String &n) const {
assert(!_path.empty());
assert(_isDirectory);
// Make sure the string contains no slashes
assert(!n.contains('/'));
// We assume here that _path is already normalized (hence don't bother to call
// Common::normalizePath on the final path).
Common::String newPath(_path);
if (_path.lastChar() != '/')
newPath += '/';
newPath += n;
return makeNode(newPath);
}
bool LibRetroFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
assert(_isDirectory);
struct RDIR *dirp = retro_opendir(_path.c_str());
if (dirp == NULL)
return false;
// loop over dir entries using readdir
while ((retro_readdir(dirp))) {
const char *d_name = retro_dirent_get_name(dirp);
// Skip 'invisible' files if necessary
if (d_name[0] == '.' && !hidden) {
continue;
}
// Skip '.' and '..' to avoid cycles
if ((d_name[0] == '.' && d_name[1] == 0) || (d_name[0] == '.' && d_name[1] == '.')) {
continue;
}
// Start with a clone of this node, with the correct path set
LibRetroFilesystemNode entry(*this);
entry._displayName = d_name;
if (_path.lastChar() != '/')
entry._path += '/';
entry._path += entry._displayName;
entry._isValid = true;
entry._isDirectory = retro_dirent_is_dir(dirp, entry._path.c_str());
// Skip files that are invalid for some reason (e.g. because we couldn't
// properly stat them).
if (!entry._isValid)
continue;
// Honor the chosen mode
if ((mode == Common::FSNode::kListFilesOnly && entry._isDirectory) || (mode == Common::FSNode::kListDirectoriesOnly && !entry._isDirectory))
continue;
myList.push_back(new LibRetroFilesystemNode(entry));
}
retro_closedir(dirp);
return true;
}
AbstractFSNode *LibRetroFilesystemNode::getParent() const {
if (_path == "/")
return 0; // The filesystem root has no parent
const char *start = _path.c_str();
const char *end = start + _path.size();
// Strip of the last component. We make use of the fact that at this
// point, _path is guaranteed to be normalized
while (end > start && *(end - 1) != '/')
end--;
if (end == start) {
return 0;
}
AbstractFSNode *parent = makeNode(Common::String(start, end));
if (parent->isDirectory() == false)
return 0;
return parent;
}
Common::SeekableReadStream *LibRetroFilesystemNode::createReadStream() {
return StdioStream::makeFromPath(getPath(), StdioStream::WriteMode_Read);
}
Common::SeekableWriteStream *LibRetroFilesystemNode::createWriteStream(bool atomic) {
return StdioStream::makeFromPath(getPath(), atomic ? StdioStream::WriteMode_WriteAtomic : StdioStream::WriteMode_Write);
}
bool LibRetroFilesystemNode::createDirectory() {
if (path_mkdir(_path.c_str()))
setFlags();
return _isValid && _isDirectory;
}
namespace Posix {
bool assureDirectoryExists(const Common::String &dir, const char *prefix) {
// Check whether the prefix exists if one is supplied.
if (prefix) {
if (!path_is_valid(prefix)) {
return false;
} else if (!path_is_directory(prefix)) {
return false;
}
}
// Obtain absolute path.
Common::String path;
if (prefix) {
path = prefix;
path += '/';
path += dir;
} else {
path = dir;
}
path = Common::normalizePath(path, '/');
const Common::String::iterator end = path.end();
Common::String::iterator cur = path.begin();
if (*cur == '/')
++cur;
do {
if (cur + 1 != end) {
if (*cur != '/') {
continue;
}
// It is kind of ugly and against the purpose of Common::String to
// insert 0s inside, but this is just for a local string and
// simplifies the code a lot.
*cur = '\0';
}
if (!path_mkdir(path.c_str())) {
if (errno == EEXIST) {
if (!path_is_valid(path.c_str())) {
return false;
} else if (!path_is_directory(path.c_str())) {
return false;
}
} else {
return false;
}
}
*cur = '/';
} while (cur++ != end);
return true;
}
} // End of namespace Posix
Common::String LibRetroFilesystemNode::getHomeDir(void) {
Common::String path;
const char *home = nullptr;
#ifdef _WIN32
const char *drv = getenv("HOMEDRIVE");
const char *pth = getenv("HOMEPATH");
if (drv && *drv && pth && *pth) {
Common::String s = Common::String(drv);
s += pth;
return s;
}
#else
home = getenv("HOME");
#endif
if (home && *home)
path = home;
return path;
}

View File

@@ -0,0 +1,127 @@
/* Copyright (C) 2024 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/graphics/opengl/opengl-graphics.h"
#include "backends/graphics/opengl/framebuffer.h"
#include "graphics/opengl/debug.h"
#include "backends/platform/libretro/include/libretro-defs.h"
#include "backends/platform/libretro/include/libretro-core.h"
#include "backends/platform/libretro/include/libretro-os.h"
#include "backends/platform/libretro/include/libretro-timer.h"
#include "backends/platform/libretro/include/libretro-graphics-opengl.h"
#include "gui/gui-manager.h"
LibretroOpenGLGraphics::LibretroOpenGLGraphics(OpenGL::ContextType contextType) {
resetContext(contextType);
}
void LibretroOpenGLGraphics::refreshScreen() {
dynamic_cast<LibretroTimerManager *>(LIBRETRO_G_SYSTEM->getTimerManager())->checkThread(THREAD_SWITCH_UPDATE);
}
void LibretroOpenGLGraphics::setMousePosition(int x, int y) {
OpenGL::OpenGLGraphicsManager::setMousePosition(x, y);
}
void LibretroOpenGLGraphics::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
/* Workaround to fix a cursor glitch (e.g. GUI with Classic theme) occurring when any overlay is activated from retroarch (e.g. keyboard overlay).
Currently no feedback is available from frontend to detect if overlays are toggled to delete _cursor only if needed.
@TODO: root cause to be investigated. */
delete _cursor;
_cursor = nullptr;
OpenGL::OpenGLGraphicsManager::setMouseCursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format, mask);
overrideCursorScaling();
}
void LibretroOpenGLGraphics::overrideCursorScaling() {
OpenGL::OpenGLGraphicsManager::recalculateCursorScaling();
if (_cursor) {
const frac_t screenScaleFactor = (_cursorDontScale || ! _overlayVisible) ? intToFrac(1) : intToFrac(getWindowHeight()) / 200; /* hard coded as base resolution 320x200 is hard coded upstream */
_cursorHotspotXScaled = fracToInt(_cursorHotspotX * screenScaleFactor);
_cursorWidthScaled = fracToDouble(_cursor->getWidth() * screenScaleFactor);
_cursorHotspotYScaled = fracToInt(_cursorHotspotY * screenScaleFactor);
_cursorHeightScaled = fracToDouble(_cursor->getHeight() * screenScaleFactor);
}
}
void LibretroOpenGLGraphics::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
bool force_gui_redraw = false;
/* Override for ScummVM Launcher */
if (nullptr == ConfMan.getActiveDomain()) {
/* 0 w/h is used to notify libretro gui res settings is changed */
force_gui_redraw = (width == 0);
width = retro_setting_get_gui_res_w();
height = retro_setting_get_gui_res_h();
}
/* no need to update now libretro gui res settings changes if not in ScummVM launcher */
if (! width)
return;
retro_set_size(width, height);
handleResize(width, height);
OpenGL::OpenGLGraphicsManager::initSize(width, height, format);
LIBRETRO_G_SYSTEM->refreshRetroSettings();
if (force_gui_redraw)
g_gui.checkScreenChange();
}
OSystem::TransactionError LibretroOpenGLGraphics::endGFXTransaction() {
OSystem::TransactionError res = OpenGL::OpenGLGraphicsManager::endGFXTransaction();
overrideCursorScaling();
return res;
}
void LibretroOpenGLGraphics::handleResizeImpl(const int width, const int height) {
OpenGL::OpenGLGraphicsManager::handleResizeImpl(width, height);
overrideCursorScaling();
}
bool LibretroOpenGLGraphics::hasFeature(OSystem::Feature f) const {
return
#ifdef SCUMMVM_NEON
(f == OSystem::kFeatureCpuNEON) ||
#endif
#ifdef USE_OPENGL_GAME
(f == OSystem::kFeatureOpenGLForGame) ||
#endif
#ifdef USE_OPENGL_SHADERS
(f == OSystem::kFeatureShadersForGame) ||
#endif
OpenGL::OpenGLGraphicsManager::hasFeature(f);
}
void LibretroHWFramebuffer::activateInternal() {
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, retro_get_hw_fb()));
}
void LibretroOpenGLGraphics::resetContext(OpenGL::ContextType contextType) {
const Graphics::PixelFormat rgba8888 = OpenGL::Texture::getRGBAPixelFormat();
notifyContextDestroy();
notifyContextCreate(contextType, new LibretroHWFramebuffer(), rgba8888, rgba8888);
if (_overlayInGUI)
g_gui.checkScreenChange();
}

View File

@@ -0,0 +1,259 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "graphics/colormasks.h"
#include "graphics/palette.h"
#include "graphics/managed_surface.h"
#include "gui/message.h"
#include "gui/gui-manager.h"
#include "backends/platform/libretro/include/libretro-defs.h"
#include "backends/platform/libretro/include/libretro-core.h"
#include "backends/platform/libretro/include/libretro-os.h"
#include "backends/platform/libretro/include/libretro-timer.h"
#include "backends/platform/libretro/include/libretro-graphics-surface.h"
LibretroGraphics::LibretroGraphics() : _cursorPaletteEnabled(false),
_cursorKeyColor(0),
_cursorDontScale(false),
_screenUpdatePending(false),
_gamePalette(256),
_cursorPalette(256),
_screenChangeID(1 << (sizeof(int) * 8 - 2)) {}
LibretroGraphics::~LibretroGraphics() {
_gameScreen.free();
_overlay.free();
_cursor.free();
_screen.free();
}
Common::List<Graphics::PixelFormat> LibretroGraphics::getSupportedFormats() const {
Common::List<Graphics::PixelFormat> result;
#ifdef SCUMM_LITTLE_ENDIAN
/* RGBA8888 */
result.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
#else
/* ABGR8888 */
result.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
#endif
/* RGB565 - overlay */
result.push_back(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
/* RGB555 - fmtowns */
result.push_back(Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15));
/* Palette - most games */
result.push_back(Graphics::PixelFormat::createFormatCLUT8());
return result;
}
const OSystem::GraphicsMode *LibretroGraphics::getSupportedGraphicsModes() const {
static const OSystem::GraphicsMode s_noGraphicsModes[] = {{0, 0, 0}};
return s_noGraphicsModes;
}
void LibretroGraphics::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
Graphics::PixelFormat actFormat = format ? *format : Graphics::PixelFormat::createFormatCLUT8();
bool force_gui_redraw = false;
/* Override for ScummVM Launcher */
if (nullptr == ConfMan.getActiveDomain()) {
/* 0 w/h is used to notify libretro gui res settings is changed */
force_gui_redraw = (width == 0);
width = retro_setting_get_gui_res_w();
height = retro_setting_get_gui_res_h();
}
/* no need to update now libretro gui res settings changes if not in ScummVM launcher */
if (! width)
return;
if (_gameScreen.w != width || _gameScreen.h != height || _gameScreen.format != actFormat)
_gameScreen.create(width, height, actFormat);
if (_overlay.w != width || _overlay.h != height)
_overlay.create(width, height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
if (getWindowWidth() != width || getWindowHeight() != height)
_screen.create(width, height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
handleResize(width, height);
recalculateDisplayAreas();
retro_set_size(width, height);
LIBRETRO_G_SYSTEM->refreshRetroSettings();
++_screenChangeID;
if (force_gui_redraw)
g_gui.checkScreenChange();
}
int16 LibretroGraphics::getHeight() const {
return _gameScreen.h;
}
int16 LibretroGraphics::getWidth() const {
return _gameScreen.w;
}
Graphics::PixelFormat LibretroGraphics::getScreenFormat() const {
return _gameScreen.format;
}
void LibretroGraphics::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
_gameScreen.copyRectToSurface(buf, pitch, x, y, w, h);
}
void LibretroGraphics::updateScreen() {
_screenUpdatePending = true;
dynamic_cast<LibretroTimerManager *>(LIBRETRO_G_SYSTEM->getTimerManager())->checkThread(THREAD_SWITCH_UPDATE);
}
void LibretroGraphics::realUpdateScreen(void) {
const Graphics::Surface &srcSurface = _overlayVisible ? _overlay : _gameScreen;
if (srcSurface.w && srcSurface.h)
_screen.blitFrom(srcSurface, Common::Rect(srcSurface.w, srcSurface.h), Common::Rect(_screen.w, _screen.h), &_gamePalette);
if (_cursorVisible && _cursor.w && _cursor.h) {
Common::Point topLeft(_cursorX - _cursorHotspotXScaled, _cursorY - _cursorHotspotYScaled);
_screen.transBlitFrom(_cursor, Common::Rect(_cursor.w, _cursor.h), Common::Rect(topLeft, topLeft + Common::Point(_cursorWidthScaled, _cursorHeightScaled)), _cursorKeyColor, false, 0xff, _cursorPaletteEnabled ? &_cursorPalette : &_gamePalette);
}
_screenUpdatePending = false;
}
void LibretroGraphics::clearOverlay() {
_overlay.fillRect(Common::Rect(_overlay.w, _overlay.h), 0);
}
void LibretroGraphics::grabOverlay(Graphics::Surface &surface) const {
surface.copyFrom(_overlay);
}
void LibretroGraphics::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
_overlay.copyRectToSurface(buf, pitch, x, y, w, h);
}
int16 LibretroGraphics::getOverlayHeight() const {
return _overlay.h;
}
int16 LibretroGraphics::getOverlayWidth() const {
return _overlay.w;
}
Graphics::PixelFormat LibretroGraphics::getOverlayFormat() const {
return _overlay.format;
}
void LibretroGraphics::warpMouse(int x, int y) {
LIBRETRO_G_SYSTEM->_mouseX = x;
LIBRETRO_G_SYSTEM->_mouseY = y;
WindowedGraphicsManager::warpMouse(x, y);
}
void LibretroGraphics::overrideCursorScaling() {
const frac_t screenScaleFactor = (_cursorDontScale || ! _overlayVisible) ? intToFrac(1) : intToFrac(getWindowHeight()) / 200; /* hard coded as base resolution 320x200 is hard coded upstream */
_cursorHotspotXScaled = fracToInt(_cursorHotspotX * screenScaleFactor);
_cursorWidthScaled = fracToDouble(_cursor.w * screenScaleFactor);
_cursorHotspotYScaled = fracToInt(_cursorHotspotY * screenScaleFactor);
_cursorHeightScaled = fracToDouble(_cursor.h * screenScaleFactor);
}
void LibretroGraphics::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
if (!buf || !w || !h)
return;
const Graphics::PixelFormat mformat = format ? *format : Graphics::PixelFormat::createFormatCLUT8();
if (_cursor.w != w || _cursor.h != h || _cursor.format != mformat)
_cursor.create(w, h, mformat);
_cursor.copyRectToSurface(buf, _cursor.pitch, 0, 0, w, h);
_cursorHotspotX = hotspotX;
_cursorHotspotY = hotspotY;
_cursorKeyColor = keycolor;
_cursorDontScale = dontScale;
overrideCursorScaling();
}
OSystem::TransactionError LibretroGraphics::endGFXTransaction() {
overrideCursorScaling();
return OSystem::TransactionError::kTransactionSuccess;
}
void LibretroGraphics::handleResizeImpl(const int width, const int height) {
overrideCursorScaling();
}
void LibretroGraphics::setCursorPalette(const byte *colors, uint start, uint num) {
_cursorPalette.set(colors, start, num);
_cursorPaletteEnabled = true;
}
bool LibretroGraphics::isOverlayInGUI(void) {
return _overlayInGUI;
}
const Graphics::ManagedSurface *LibretroGraphics::getScreen() {
return &_screen;
}
void LibretroGraphics::setPalette(const byte *colors, uint start, uint num) {
_gamePalette.set(colors, start, num);
}
void LibretroGraphics::grabPalette(byte *colors, uint start, uint num) const {
_gamePalette.grab(colors, start, num);
}
bool LibretroGraphics::hasFeature(OSystem::Feature f) const {
return (f == OSystem::kFeatureCursorPalette) ||
#ifdef SCUMMVM_NEON
(f == OSystem::kFeatureCpuNEON) ||
#endif
(f == OSystem::kFeatureCursorAlpha);
}
void LibretroGraphics::setFeatureState(OSystem::Feature f, bool enable) {
if (f == OSystem::kFeatureCursorPalette)
_cursorPaletteEnabled = enable;
}
bool LibretroGraphics::getFeatureState(OSystem::Feature f) const {
return (f == OSystem::kFeatureCursorPalette) ? _cursorPaletteEnabled : false;
}
void LibretroGraphics::setMousePosition(int x, int y) {
WindowedGraphicsManager::setMousePosition(x, y);
}
void LibretroGraphics::displayMessageOnOSD(const Common::U32String &msg) {
// Display the message for 3 seconds
GUI::TimedMessageDialog dialog(msg, 3000);
dialog.runModal();
}
int LibretroGraphics::getScreenChangeID() const {
return _screenChangeID;
}

View File

@@ -0,0 +1,166 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
#include "backends/platform/libretro/include/libretro-mapper.h"
struct retro_keymap mapper_keys[RETRO_DEVICE_ID_JOYPAD_LAST] = {0};
static int16 mapper_digital_buttons_status = 0;
static uint32 mapper_digital_buttons_prev_status = 0;
static int16 mapper_analog_stick_status [2][2] = {0};
void mapper_poll_device(void) {
//Store previous on/off status
mapper_digital_buttons_prev_status = mapper_digital_buttons_status;
for (int8 i = RETRO_DEVICE_ID_JOYPAD_ANALOG; i < RETRO_DEVICE_ID_JOYPAD_LAST; i++)
mapper_digital_buttons_prev_status |= mapper_get_device_key_value(i) ? 1 << i : 0;
//Get current status
mapper_digital_buttons_status = 0;
// Store real digital buttons status
if (retro_get_input_bitmask_supported())
mapper_digital_buttons_status = retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
else
for (int8 i = 0; i < RETRO_DEVICE_ID_JOYPAD_ANALOG; i++)
mapper_digital_buttons_status |= (retro_input_cb(0, RETRO_DEVICE_JOYPAD, 0, i) << i);
//Store analog sticks (analog) status
for (int8 i = 0; i < 2; i++)
for (int8 j = 0; j < 2; j++)
mapper_analog_stick_status[i][j] = retro_input_cb(0, RETRO_DEVICE_ANALOG, i, j);
}
static int16 mapper_get_retro_key_index(const char *retro_key_value) {
uint16 i = 0;
while (retro_keys[i].retro_id != RETROK_LAST) {
if (strcmp(retro_keys[i].value, retro_key_value) == 0)
return i;
++i;
}
return -1;
}
int8 mapper_get_mapper_key_index(int16 key_retro_id, uint8 start_index) {
uint8 i = start_index;
while (i < RETRO_DEVICE_ID_JOYPAD_LAST) {
if (mapper_keys[i].retro_id == key_retro_id)
return i;
++i;
}
return -1;
}
bool mapper_set_device_keys(unsigned int retro_device_id, const char *retro_key_value) {
int16 retro_key_index = mapper_get_retro_key_index(retro_key_value);
if (retro_key_index > -1 && retro_device_id < RETRO_DEVICE_ID_JOYPAD_LAST) {
mapper_keys[retro_device_id] = retro_keys[retro_key_index];
return true;
}
return false;
}
int16 mapper_get_device_key_value(unsigned int retro_device_id) {
if (retro_device_id < RETRO_DEVICE_ID_JOYPAD_ANALOG) {
return (mapper_digital_buttons_status & (1 << retro_device_id)) > 0;
} else if (retro_device_id < RETRO_DEVICE_ID_JOYPAD_LAST) {
int16 res;
int16 sign;
switch (retro_device_id) {
case RETRO_DEVICE_ID_JOYPAD_LU:
res = mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y];
sign = -1;
break;
case RETRO_DEVICE_ID_JOYPAD_LD:
res = mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y];
sign = 1;
break;
case RETRO_DEVICE_ID_JOYPAD_LL:
res = mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X];
sign = -1;
break;
case RETRO_DEVICE_ID_JOYPAD_LR:
res = mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X];
sign = 1;
break;
case RETRO_DEVICE_ID_JOYPAD_RU:
res = mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y];
sign = -1;
break;
case RETRO_DEVICE_ID_JOYPAD_RD:
res = mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y];
sign = 1;
break;
case RETRO_DEVICE_ID_JOYPAD_RL:
res = mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X];
sign = -1;
break;
case RETRO_DEVICE_ID_JOYPAD_RR:
res = mapper_analog_stick_status[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X];
sign = 1;
}
bool check_sign = (res > 0) - (res < 0) == sign;
res = abs(res);
/* discard analog values of 1 to discriminate from digital inputs */
return check_sign && res > 1 && res > retro_setting_get_analog_deadzone() ? res : 0;
}
return 0;
}
uint8 mapper_get_device_key_status(unsigned int retro_device_id) {
uint8 status = mapper_get_device_key_value(retro_device_id) ? 1 << RETRO_DEVICE_KEY_STATUS : 0;
status |= (mapper_digital_buttons_prev_status & (1 << retro_device_id)) ? 1 << RETRO_DEVICE_KEY_PREV_STATUS : 0;
status |= ((status & (1 << RETRO_DEVICE_KEY_STATUS)) > 0) == ((status & (1 << RETRO_DEVICE_KEY_PREV_STATUS)) > 0) ? 0 : 1 << RETRO_DEVICE_KEY_CHANGED;
return status;
}
int16 mapper_get_mapper_key_value(int16 retro_key_retro_id) {
int16 result = 0;
int8 retro_key_index = 0;
while (retro_key_index > -1) {
retro_key_index = mapper_get_mapper_key_index(retro_key_retro_id, retro_key_index);
if (retro_key_index > -1) {
if (mapper_get_device_key_value(retro_key_index) > result)
result = mapper_get_device_key_value(retro_key_index);
retro_key_index++;
}
}
return result;
}
uint8 mapper_get_mapper_key_status(int16 retro_key_retro_id) {
uint8 status = 0;
int8 retro_key_index = 0;
while (retro_key_index > -1) {
retro_key_index = mapper_get_mapper_key_index(retro_key_retro_id, retro_key_index);
if (retro_key_index > -1) {
status |= mapper_get_device_key_status(retro_key_index);
retro_key_index++;
}
}
return status;
}
int16 mapper_get_device_key_retro_id(unsigned int retro_device_id) {
return mapper_keys[retro_device_id].retro_id;
}
int16 mapper_get_device_key_scummvm_id(unsigned int retro_device_id) {
return mapper_keys[retro_device_id].scummvm_id;
}

View File

@@ -0,0 +1,323 @@
/* Copyright (C) 2024 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include <streams/file_stream.h>
#include "backends/platform/libretro/include/libretro-options-widget.h"
#include "backends/platform/libretro/include/libretro-core.h"
#include "backends/platform/libretro/include/libretro-fs.h"
#include "backends/platform/libretro/include/libretro-os.h"
#include "gui/launcher.h"
#include "common/translation.h"
#include "common/formats/json.h"
enum {
kPlaylistPathCmd = 'pchp',
kPlaylistPathClearCmd = 'pclp',
kPlaylistGenerateCmd = 'pgen'
};
enum {
kPlaylistFormatJSON = 0,
kPlaylistFormat6lines,
};
enum {
kHooksLocationSave = 0,
kHooksLocationGame,
};
LibretroOptionsWidget::LibretroOptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain) :
OptionsContainerWidget(boss, name, "LibretroOptionsDialog", domain) {
new GUI::StaticTextWidget(widgetsBoss(), "LibretroOptionsDialog.PlaylistHeader", _("LIBRETRO PLAYLIST GENERATOR"));
new GUI::StaticTextWidget(widgetsBoss(), "LibretroOptionsDialog.PlaylistSubheader", _("(check '? > Libretro playlist' for detailed info)"));
(new GUI::ButtonWidget(widgetsBoss(), "LibretroOptionsDialog.PlaylistPathButton", _("Playlists Path"), Common::U32String(), kPlaylistPathCmd))->setTarget(this);
_playlistPath = new GUI::StaticTextWidget(widgetsBoss(), "LibretroOptionsDialog.PlaylistPath", _("Specifies where your playlist will be saved."));
GUI::addClearButton(widgetsBoss(), "LibretroOptionsDialog.PlaylistPathButtonClear", kPlaylistPathClearCmd);
new GUI::StaticTextWidget(widgetsBoss(), "LibretroOptionsDialog.PlaylistVersionText", _("Playlist format:"));
_playlistVersion = new GUI::PopUpWidget(widgetsBoss(), "LibretroOptionsDialog.PlaylistVersion");
_playlistVersion->appendEntry(Common::U32String("JSON "), kPlaylistFormatJSON);
_playlistVersion->appendEntry(Common::U32String("6-lines"), kPlaylistFormat6lines);
new GUI::StaticTextWidget(widgetsBoss(), "LibretroOptionsDialog.HooksLocationText", _("Hooks location:"));
_hooksLocation = new GUI::PopUpWidget(widgetsBoss(), "LibretroOptionsDialog.HooksLocation");
_hooksLocation->appendEntry(_("All in save folder"), kHooksLocationSave);
_hooksLocation->appendEntry(_("One in each game folder"), kHooksLocationGame);
_hooksClear = new GUI::CheckboxWidget(widgetsBoss(), "LibretroOptionsDialog.HooksClear", _("Clear existing hooks"));
(new GUI::ButtonWidget(widgetsBoss(), "LibretroOptionsDialog.PlaylistGenerateButton", _("Generate playlist"), Common::U32String(), kPlaylistGenerateCmd))->setTarget(this);
new GUI::StaticTextWidget(widgetsBoss(), "LibretroOptionsDialog.PlaylistStatusText", _("Status: "));
_playlistStatus = new GUI::StaticTextWidget(widgetsBoss(), "LibretroOptionsDialog.PlaylistStatus", Common::String("-"));
}
LibretroOptionsWidget::~LibretroOptionsWidget() {
}
void LibretroOptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const {
layouts.addDialog(layoutName, overlayedLayout)
.addLayout(GUI::ThemeLayout::kLayoutVertical, 8)
.addPadding(0, 0, 0, 0)
.addWidget("PlaylistHeader", "", -1, layouts.getVar("Globals.Line.Height"))
.addWidget("PlaylistSubheader", "", -1, layouts.getVar("Globals.Line.Height"))
.addLayout(GUI::ThemeLayout::kLayoutHorizontal, 10, GUI::ThemeLayout::kItemAlignCenter)
.addPadding(0, 0, 0, 0)
.addWidget("PlaylistPathButton", "Button")
.addWidget("PlaylistPath", "", -1, layouts.getVar("Globals.Line.Height"))
.addWidget("PlaylistPathButtonClear", "SearchClearButton", layouts.getVar("Globals.Line.Height"), layouts.getVar("Globals.Line.Height"))
.closeLayout()
.addLayout(GUI::ThemeLayout::kLayoutHorizontal)
.addPadding(0, 0, 0, 0)
.addWidget("PlaylistVersionText", "OptionsLabel")
.addWidget("PlaylistVersion", "PopUp")
.closeLayout()
.addLayout(GUI::ThemeLayout::kLayoutHorizontal)
.addPadding(0, 0, 0, 0)
.addWidget("HooksLocationText", "OptionsLabel")
.addWidget("HooksLocation", "PopUp")
.closeLayout()
.addLayout(GUI::ThemeLayout::kLayoutHorizontal)
.addPadding(0, 0, 0, 0)
.addWidget("HooksClear", "Checkbox")
.closeLayout()
.addLayout(GUI::ThemeLayout::kLayoutHorizontal)
.addPadding(0, 0, 0, 0)
.addWidget("PlaylistGenerateButton", "WideButton")
.addSpace(layouts.getVar("Globals.Line.Height") * 2)
.addWidget("PlaylistStatusText", "", -1, layouts.getVar("Globals.Line.Height"))
.addWidget("PlaylistStatus", "", -1, layouts.getVar("Globals.Line.Height"))
.closeLayout()
.closeLayout()
.closeDialog();
}
bool LibretroOptionsWidget::cleanFolder(Common::String &path) {
bool res = true;
Common::ArchiveMemberList listHooks;
Common::FSNode(Common::Path(path)).listChildren(listHooks, "*." CORE_EXTENSIONS);
for (Common::ArchiveMemberPtr hook : listHooks) {
Common::FSNode *fshook = dynamic_cast<Common::FSNode *>(hook.get());
if (fshook->isDirectory())
continue;
if (remove(fshook->getPath().toString().c_str()) == 0)
retro_log_cb(RETRO_LOG_INFO, "Hook file deleted in '%s'.\n", fshook->getPath().toString().c_str());
else {
res = false;
retro_log_cb(RETRO_LOG_WARN, "Failed to delete hook file in '%s'.\n", fshook->getPath().toString().c_str());
}
}
return res;
}
bool LibretroOptionsWidget::generatePlaylist(Common::String playlistPath) {
bool isFirstEntry = true;
bool success = true;
bool cleanSuccess = true;
Common::String playlistElement;
Common::String playlistFooter;
Common::String path;
char separator[2] = {0};
Common::String hookPath;
Common::String hookFilePath;
Common::String title;
Common::JSONObject root;
Common::JSONArray items;
/* Create playlist file */
RFILE *playlistFile = filestream_open(Common::String(playlistPath + "/" + CORE_NAME + ".lpl").c_str(), RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if (!playlistFile) {
_playlistStatus->setLabel(_("Failed, can't access playlist file"));
retro_log_cb(RETRO_LOG_ERROR, "Failed to access playlst file at '%s'.\n", Common::String(playlistPath + "/" + CORE_NAME + ".lpl").c_str());
return false;
} else
retro_log_cb(RETRO_LOG_INFO, "Playlist file created in '%s'.\n", Common::String(playlistPath + CORE_NAME + ".lpl").c_str());
/* Create common hook folder */
if (ConfMan.getInt("libretro_hooks_location", _domain) != kHooksLocationGame) {
hookPath = LibRetroFilesystemNode(Common::String(LIBRETRO_G_SYSTEM->getSaveDir())).getPath() + "/" + COMMON_HOOKS_FOLDER;
LibRetroFilesystemNode(hookPath).createDirectory();
if (ConfMan.getBool("libretro_hooks_clear", _domain)) {
cleanSuccess = cleanFolder(hookPath);
}
}
/* Setup playlist template */
if (ConfMan.getInt("libretro_playlist_version", _domain) != kPlaylistFormat6lines) {
const char *cCorePath = retro_get_core_dir();
LibRetroFilesystemNode corePath(".");
if (cCorePath)
corePath = LibRetroFilesystemNode(Common::String(cCorePath));
root["version"] = new Common::JSONValue(Common::String("1.5"));
root["default_core_path"] = new Common::JSONValue(corePath.exists() ? corePath.getPath() : Common::String(""));
root["default_core_name"] = new Common::JSONValue(Common::String("ScummVM"));
root["label_display_mode"] = new Common::JSONValue((long long)0);
root["right_thumbnail_mode"] = new Common::JSONValue((long long)2);
root["left_thumbnail_mode"] = new Common::JSONValue((long long)3);
root["sort_mode"] = new Common::JSONValue((long long)0);
} else
playlistElement = "%s%s\n%s\nDETECT\nDETECT\nDETECT\nScummVM.lpl\n";
/* Crawl ScummVM game list */
Common::ConfigManager::DomainMap::iterator iter = ConfMan.beginGameDomains();
for (; iter != ConfMan.endGameDomains(); ++iter) {
if (!iter->_value.tryGetVal("path", path) || iter->_value.contains("id_came_from_command_line"))
continue;
Common::Path cleanPath = Common::Path::fromConfig(path);
if (!Common::FSNode(cleanPath).isDirectory())
continue;
if (ConfMan.getInt("libretro_hooks_location", _domain) == kHooksLocationGame) {
hookPath = LibRetroFilesystemNode(cleanPath.toString()).getPath();
if (ConfMan.getBool("libretro_hooks_clear", _domain))
if (!cleanFolder(hookPath)) cleanSuccess = false;
}
title = iter->_key;
iter->_value.tryGetVal("description", title);
hookFilePath = hookPath + + "/" + iter->_key.c_str() + "." + CORE_EXTENSIONS;
if (ConfMan.getInt("libretro_playlist_version", _domain) != kPlaylistFormat6lines) {
Common::JSONObject item;
item["path"] = new Common::JSONValue(hookFilePath);
item["label"] = new Common::JSONValue(title);
item["core_path"] = new Common::JSONValue(Common::String("DETECT"));
item["core_name"] = new Common::JSONValue(Common::String("DETECT"));
item["crc32"] = new Common::JSONValue(Common::String("DETECT"));
item["db_name"] = new Common::JSONValue(Common::String(CORE_NAME ".lpl"));
items.push_back(new Common::JSONValue(item));
} else {
filestream_printf(playlistFile, playlistElement.c_str(), separator, hookFilePath.c_str(), title.c_str());
if (isFirstEntry) {
*separator = ',';
isFirstEntry = false;
}
}
/* Create hook file */
RFILE *hookFile = filestream_open(hookFilePath.c_str(), RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
if (!hookFile) {
retro_log_cb(RETRO_LOG_ERROR, "Failed to access/create hook file at '%s'.\n", hookFilePath.c_str());
success = false;
break;
} else
retro_log_cb(RETRO_LOG_INFO, "Hook file created in '%s'.\n", hookFilePath.c_str());
filestream_printf(hookFile, "%s", iter->_key.c_str());
filestream_close(hookFile);
}
if (ConfMan.getInt("libretro_playlist_version", _domain) != kPlaylistFormat6lines) {
root["items"] = new Common::JSONValue(items);
Common::JSONValue *rootVal = new Common::JSONValue(root);
Common::String out = Common::JSON::stringify(rootVal);
filestream_write(playlistFile, out.c_str(), out.size());
delete rootVal;
} else {
filestream_printf(playlistFile, playlistFooter.c_str());
}
filestream_close(playlistFile);
Common::String response;
if (success) {
response = _("Done");
if (!cleanSuccess)
response += " (" + _("cleaning failed") + ")";
} else
response = _("Failed, can't create hook files");
_playlistStatus->setLabel(response);
return success;
}
void LibretroOptionsWidget::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kPlaylistPathCmd: {
GUI::BrowserDialog browser(_("Select Playlist directory"), true);
if (browser.runModal() > 0) {
Common::FSNode dir(browser.getResult());
_playlistPath->setLabel(dir.getPath().toString());
}
break;
}
case kPlaylistPathClearCmd: {
_playlistPath->setLabel(_c("None", "path"));
break;
}
case kPlaylistGenerateCmd: {
save();
_playlistStatus->setLabel(Common::String("-"));
generatePlaylist(ConfMan.get("libretro_playlist_path"));
break;
}
default:
GUI::OptionsContainerWidget::handleCommand(sender, cmd, data);
}
}
void LibretroOptionsWidget::load() {
_playlistPath->setLabel(ConfMan.get("libretro_playlist_path"));
if (ConfMan.getInt("libretro_playlist_version", _domain) == kPlaylistFormat6lines)
_playlistVersion->setSelected(kPlaylistFormat6lines);
else
_playlistVersion->setSelected(kPlaylistFormatJSON);
if (ConfMan.getInt("libretro_hooks_location", _domain) == kHooksLocationGame)
_hooksLocation->setSelected(kHooksLocationGame);
else
_hooksLocation->setSelected(kHooksLocationSave);
_hooksClear->setState(ConfMan.getBool("libretro_hooks_clear", _domain));
}
bool LibretroOptionsWidget::save() {
Common::String data = _playlistPath->getLabel();
if (data.empty())
ConfMan.set("libretro_playlist_path", "", _domain);
else
ConfMan.set("libretro_playlist_path", data, _domain);
if (_playlistVersion->getSelected() == kPlaylistFormat6lines)
ConfMan.setInt("libretro_playlist_version", kPlaylistFormat6lines, _domain);
else
ConfMan.setInt("libretro_playlist_version", kPlaylistFormatJSON, _domain);
if (_hooksLocation->getSelected() == kHooksLocationGame)
ConfMan.setInt("libretro_hooks_location", kHooksLocationGame, _domain);
else
ConfMan.setInt("libretro_hooks_location", kHooksLocationSave, _domain);
ConfMan.setBool("libretro_hooks_clear", _hooksClear->getState(), _domain);
/* Always return true to call applyBackendSettings every time settings are applied */
return true;
}

View File

@@ -0,0 +1,166 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#if defined(_WIN32)
#include "backends/fs/windows/windows-fs-factory.h"
#define FS_SYSTEM_FACTORY WindowsFilesystemFactory
#else
#include "backends/platform/libretro/include/libretro-fs-factory.h"
#define FS_SYSTEM_FACTORY LibRetroFilesystemFactory
#endif
#include <features/features_cpu.h>
#include "audio/mixer_intern.h"
#include "backends/base-backend.h"
#include "common/config-manager.h"
#include "common/system.h"
#include "graphics/surface.h"
#include "backends/saves/default/default-saves.h"
#include "backends/platform/libretro/include/libretro-defs.h"
#include "backends/platform/libretro/include/libretro-core.h"
#include "backends/platform/libretro/include/libretro-timer.h"
#include "backends/platform/libretro/include/libretro-os.h"
#include "backends/platform/libretro/include/libretro-graphics-surface.h"
#ifdef USE_OPENGL
#include "backends/platform/libretro/include/libretro-graphics-opengl.h"
#endif
OSystem_libretro::OSystem_libretro() : _mouseX(0), _mouseY(0), _mouseXAcc(0.0), _mouseYAcc(0.0), _dpadXAcc(0.0), _dpadYAcc(0.0), _dpadXVel(0.0f), _dpadYVel(0.0f), _mixer(0), _startTime(0), _cursorStatus(0) {
_fsFactory = new FS_SYSTEM_FACTORY();
setLibretroDir(retro_get_system_dir(), s_systemDir);
setLibretroDir(retro_get_save_dir(), s_saveDir);
setLibretroDir(retro_get_playlist_dir(), s_playlistDir);
memset(_mouseButtons, 0, sizeof(_mouseButtons));
_startTime = (uint32)(cpu_features_get_time_usec() / 1000);
}
OSystem_libretro::~OSystem_libretro() {
delete _mixer;
_mixer = nullptr;
}
void OSystem_libretro::initBackend() {
/* ScummVM paths checks are triggered by applyBackendSettings on setupGraphics() */
/* Initialize other settings */
if (! ConfMan.hasKey("libretro_playlist_version"))
ConfMan.set("libretro_playlist_version", 0);
if (! ConfMan.hasKey("libretro_hooks_location"))
ConfMan.set("libretro_hooks_location", 0);
if (! ConfMan.hasKey("libretro_hooks_clear"))
ConfMan.set("libretro_hooks_clear", 0);
_savefileManager = new DefaultSaveFileManager();
_mixer = new Audio::MixerImpl(retro_setting_get_sample_rate(), true, retro_setting_get_audio_samples_buffer_size());
retro_log_cb(RETRO_LOG_DEBUG, "Mixer set up at %dHz\n", retro_setting_get_sample_rate());
_timerManager = new LibretroTimerManager(retro_setting_get_frame_rate());
_mixer->setReady(true);
resetGraphicsManager();
EventsBaseBackend::initBackend();
refreshRetroSettings();
}
void OSystem_libretro::engineInit() {
Common::String engineId = ConfMan.get("engineid");
if (engineId.equalsIgnoreCase("scumm") && ConfMan.getBool("original_gui")) {
ConfMan.setBool("original_gui", false);
retro_log_cb(RETRO_LOG_INFO, "\"original_gui\" setting forced to false\n");
}
/* See LibretroPalette::set workaround */
/*if (retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_REQUEST_SW){
dynamic_cast<LibretroGraphics *>(_graphicsManager)->_mousePalette.reset();
dynamic_cast<LibretroGraphics *>(_graphicsManager)->_gamePalette.reset();
}*/
}
Audio::Mixer *OSystem_libretro::getMixer() {
return _mixer;
}
void OSystem_libretro::refreshRetroSettings() {
_adjusted_cursor_speed = (float)BASE_CURSOR_SPEED * retro_setting_get_gamepad_cursor_speed() * (float)getScreenWidth() / 320.0f; // Dpad cursor speed should always be based off a 320 wide screen, to keep speeds consistent;
_inverse_acceleration_time = (retro_setting_get_gamepad_acceleration_time() > 0.0) ? (1.0f / (float)retro_setting_get_frame_rate()) * (1.0f / retro_setting_get_gamepad_acceleration_time()) : 1.0f;
}
void OSystem_libretro::destroy() {
delete this;
}
void OSystem_libretro::getScreen(const Graphics::ManagedSurface *&screen) {
if (retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_REQUEST_SW)
screen = dynamic_cast<LibretroGraphics *>(_graphicsManager)->getScreen();
}
void OSystem_libretro::refreshScreen(void) {
if (retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_REQUEST_SW)
dynamic_cast<LibretroGraphics *>(_graphicsManager)->realUpdateScreen();
}
#ifdef USE_OPENGL
#ifdef USE_GLAD
void *OSystem_libretro::getOpenGLProcAddress(const char *name) const {
return retro_get_proc_address(name);
}
#endif
void OSystem_libretro::resetGraphicsContext(void) {
if ((retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_REQUEST_HW) && (retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_HAVE_OPENGL))
dynamic_cast<LibretroOpenGLGraphics *>(_graphicsManager)->resetContext(OpenGL::kContextGL);
else if ((retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_REQUEST_HW) && (retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_HAVE_OPENGLES2))
dynamic_cast<LibretroOpenGLGraphics *>(_graphicsManager)->resetContext(OpenGL::kContextGLES2);
}
#endif
int16 OSystem_libretro::getScreenWidth(void) {
return dynamic_cast<WindowedGraphicsManager *>(_graphicsManager)->getWindowWidth();
}
int16 OSystem_libretro::getScreenHeight(void) {
return dynamic_cast<WindowedGraphicsManager *>(_graphicsManager)->getWindowHeight();
}
void OSystem_libretro::resetGraphicsManager(void) {
if (_graphicsManager) {
delete _graphicsManager;
_graphicsManager = nullptr;
}
#ifdef USE_OPENGL
if ((retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_REQUEST_HW) && (retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_HAVE_OPENGL))
_graphicsManager = new LibretroOpenGLGraphics(OpenGL::kContextGL);
else if ((retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_REQUEST_HW) && (retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_HAVE_OPENGLES2))
_graphicsManager = new LibretroOpenGLGraphics(OpenGL::kContextGLES2);
else
#endif
_graphicsManager = new LibretroGraphics();
}
bool OSystem_libretro::inLauncher() {
return (nullptr == ConfMan.getActiveDomain());
}

View File

@@ -0,0 +1,81 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <unistd.h>
#include <features/features_cpu.h>
#include "common/list.h"
#include "common/events.h"
#include "backends/platform/libretro/include/libretro-defs.h"
#include "backends/platform/libretro/include/libretro-core.h"
#include "backends/platform/libretro/include/libretro-os.h"
#include "backends/platform/libretro/include/libretro-timer.h"
#include "backends/platform/libretro/include/libretro-graphics-surface.h"
#ifdef USE_OPENGL
#include "backends/platform/libretro/include/libretro-graphics-opengl.h"
#endif
bool OSystem_libretro::pollEvent(Common::Event &event) {
((LibretroTimerManager *)_timerManager)->checkThread(THREAD_SWITCH_POLL);
if (!_events.empty()) {
event = _events.front();
_events.pop_front();
return true;
}
return false;
}
uint32 OSystem_libretro::getMillis(bool skipRecord) {
return (uint32)(cpu_features_get_time_usec() / 1000) - _startTime;
}
void OSystem_libretro::delayMillis(uint msecs) {
uint32 start_time = getMillis();
uint32 elapsed_time = 0;
while (elapsed_time < msecs) {
if (!((LibretroTimerManager *)_timerManager)->checkThread(THREAD_SWITCH_DELAY))
usleep(1000);
elapsed_time = getMillis() - start_time;
}
}
Common::MutexInternal *OSystem_libretro::createMutex(void) {
return new LibretroMutexInternal();
}
void OSystem_libretro::requestQuit() {
Common::Event ev;
ev.type = Common::EVENT_QUIT;
LIBRETRO_G_SYSTEM->getEventManager()->pushEvent(ev);
}
void OSystem_libretro::resetQuit() {
LIBRETRO_G_SYSTEM->getEventManager()->resetQuit();
}
void OSystem_libretro::setMousePosition(int x, int y) {
#ifdef USE_OPENGL
if (retro_get_video_hw_mode() & VIDEO_GRAPHIC_MODE_REQUEST_HW)
dynamic_cast<LibretroOpenGLGraphics *>(_graphicsManager)->setMousePosition(x, y);
else
#endif
dynamic_cast<LibretroGraphics *>(_graphicsManager)->setMousePosition(x, y);
}

View File

@@ -0,0 +1,338 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
#include "backends/platform/libretro/include/libretro-defs.h"
#include "backends/platform/libretro/include/libretro-os.h"
#include "backends/platform/libretro/include/libretro-mapper.h"
#include "backends/platform/libretro/include/libretro-core.h"
#include "backends/platform/libretro/include/libretro-graphics-surface.h"
#ifdef USE_OPENGL
#include "backends/platform/libretro/include/libretro-graphics-opengl.h"
#endif
void OSystem_libretro::updateMouseXY(float deltaAcc, float *cumulativeXYAcc, int doing_x) {
int *mouseXY;
int16 screen_wh;
int *relMouseXY;
int cumulativeXYAcc_int;
if (! deltaAcc)
return;
if (_cursorStatus & CURSOR_STATUS_DOING_SLOWER)
deltaAcc /= retro_setting_get_mouse_fine_control_speed_reduction();
if (doing_x) {
_cursorStatus |= CURSOR_STATUS_DOING_X;
mouseXY = &_mouseX;
screen_wh = getScreenWidth();
relMouseXY = &_relMouseX;
} else {
_cursorStatus |= CURSOR_STATUS_DOING_Y;
mouseXY = &_mouseY;
screen_wh = getScreenHeight();
relMouseXY = &_relMouseY;
}
*cumulativeXYAcc += deltaAcc;
cumulativeXYAcc_int = (int) * cumulativeXYAcc;
if (cumulativeXYAcc_int != 0) {
// Set mouse position
*mouseXY += cumulativeXYAcc_int;
*mouseXY = (*mouseXY < 0) ? 0 : *mouseXY;
*mouseXY = (*mouseXY >= screen_wh) ? (screen_wh ? screen_wh - 1 : 0) : *mouseXY;
// Update accumulator
*cumulativeXYAcc -= (float)cumulativeXYAcc_int;
}
*relMouseXY = (int)deltaAcc;
}
void OSystem_libretro::getMouseXYFromAnalog(bool is_x, int16 coor) {
int16 sign = (coor > 0) - (coor < 0);
uint16 abs_coor = abs(coor);
float *mouseAcc;
if (abs_coor < retro_setting_get_analog_deadzone()) return;
_cursorStatus |= CURSOR_STATUS_DOING_JOYSTICK;
if (is_x) {
mouseAcc = &_mouseXAcc;
} else {
mouseAcc = &_mouseYAcc;
}
*mouseAcc = ((*mouseAcc > 0) - (*mouseAcc < 0)) == sign ? *mouseAcc : 0;
float analog_amplitude = (float)(abs_coor - retro_setting_get_analog_deadzone()) / (float)(ANALOG_RANGE - retro_setting_get_analog_deadzone());
if (retro_setting_get_analog_response_is_quadratic())
analog_amplitude *= analog_amplitude;
updateMouseXY(sign * analog_amplitude * _adjusted_cursor_speed, mouseAcc, is_x);
}
void OSystem_libretro::getMouseXYFromButton(bool is_x, int16 sign) {
float *dpadVel;
float *dpadAcc;
if (is_x) {
dpadVel = &_dpadXVel;
dpadAcc = &_dpadXAcc;
} else {
dpadVel = &_dpadYVel;
dpadAcc = &_dpadYAcc;
}
if ((*dpadAcc && ((*dpadAcc > 0) - (*dpadAcc < 0)) != sign) || ! sign) {
*dpadVel = 0.0f;
*dpadAcc = 0.0f;
}
if (! sign)
return;
_cursorStatus |= CURSOR_STATUS_DOING_JOYSTICK;
*dpadVel = MIN(*dpadVel + _inverse_acceleration_time, 1.0f);
updateMouseXY(sign * *dpadVel * _adjusted_cursor_speed, dpadAcc, is_x);
}
void OSystem_libretro::processInputs(void) {
int16 x, y;
float deltaAcc;
int key_modifiers [3][2] = {{RETROKE_SHIFT_MOD, RETROKMOD_SHIFT}, {RETROKE_CTRL_MOD, RETROKMOD_CTRL}, {RETROKE_ALT_MOD, RETROKMOD_ALT}};
int key_flags = 0;
int retropad_value = 0;
static const uint32 retroButtons[2] = {RETRO_DEVICE_ID_MOUSE_LEFT, RETRO_DEVICE_ID_MOUSE_RIGHT};
static const Common::EventType eventID[2][2] = {{Common::EVENT_LBUTTONDOWN, Common::EVENT_LBUTTONUP}, {Common::EVENT_RBUTTONDOWN, Common::EVENT_RBUTTONUP}};
_cursorStatus = 0;
// Process input from RetroPad
mapper_poll_device();
// Reduce cursor speed, if required
if (retro_get_input_device() == RETRO_DEVICE_JOYPAD && mapper_get_mapper_key_status(RETROKE_FINE_CONTROL)) {
_cursorStatus |= CURSOR_STATUS_DOING_SLOWER;
} else {
_cursorStatus &= ~CURSOR_STATUS_DOING_SLOWER;
}
// Handle x,y
int x_coor_cursor = mapper_get_mapper_key_value(RETROKE_RIGHT) - mapper_get_mapper_key_value(RETROKE_LEFT);
int y_coor_cursor = mapper_get_mapper_key_value(RETROKE_DOWN) - mapper_get_mapper_key_value(RETROKE_UP);
if (abs(x_coor_cursor) > 1) {
getMouseXYFromAnalog(true, x_coor_cursor);
} else
getMouseXYFromButton(true, x_coor_cursor);
if (abs(y_coor_cursor) > 1)
getMouseXYFromAnalog(false, y_coor_cursor);
else
getMouseXYFromButton(false, y_coor_cursor);
if (_cursorStatus & CURSOR_STATUS_DOING_JOYSTICK) {
Common::Event ev;
ev.type = Common::EVENT_MOUSEMOVE;
ev.mouse.x = _mouseX;
ev.mouse.y = _mouseY;
ev.relMouse.x = _cursorStatus & CURSOR_STATUS_DOING_X ? _relMouseX : 0;
ev.relMouse.y = _cursorStatus & CURSOR_STATUS_DOING_Y ? _relMouseY : 0;
_events.push_back(ev);
setMousePosition(_mouseX, _mouseY);
}
// Handle special functions
if (mapper_get_mapper_key_value(RETROKE_SCUMMVM_GUI)) {
Common::Event ev;
ev.type = Common::EVENT_MAINMENU;
_events.push_back(ev);
}
if ((mapper_get_mapper_key_status(RETROKE_VKBD) & ((1 << RETRO_DEVICE_KEY_STATUS) | (1 << RETRO_DEVICE_KEY_CHANGED))) == ((1 << RETRO_DEVICE_KEY_STATUS) | (1 << RETRO_DEVICE_KEY_CHANGED))) {
Common::Event ev;
ev.type = Common::EVENT_VIRTUAL_KEYBOARD;
_events.push_back(ev);
}
// Handle mouse buttons
retropad_value = mapper_get_mapper_key_status(RETROKE_LEFT_BUTTON);
if (retropad_value & (1 << RETRO_DEVICE_KEY_CHANGED)) {
Common::Event ev;
ev.type = eventID[0][(retropad_value & (1 << RETRO_DEVICE_KEY_STATUS)) ? 0 : 1];
ev.mouse.x = _mouseX;
ev.mouse.y = _mouseY;
_events.push_back(ev);
}
retropad_value = mapper_get_mapper_key_status(RETROKE_RIGHT_BUTTON);
if (retropad_value & (1 << RETRO_DEVICE_KEY_CHANGED)) {
Common::Event ev;
ev.type = eventID[1][(retropad_value & (1 << RETRO_DEVICE_KEY_STATUS)) ? 0 : 1];
ev.mouse.x = _mouseX;
ev.mouse.y = _mouseY;
_events.push_back(ev);
}
// Handle keyboard buttons
for (uint8 i = 0; i < sizeof(key_modifiers) / sizeof(key_modifiers[0]); i++) {
if (mapper_get_mapper_key_value(key_modifiers[i][0]))
key_flags |= key_modifiers[i][1];
}
for (uint8 i = 0; i < RETRO_DEVICE_ID_JOYPAD_LAST; i++) {
if (mapper_get_device_key_retro_id(i) <= 0)
continue;
retropad_value = mapper_get_device_key_status(i);
if (retropad_value & (1 << RETRO_DEVICE_KEY_CHANGED)) {
processKeyEvent((retropad_value & (1 << RETRO_DEVICE_KEY_STATUS)), mapper_get_device_key_scummvm_id(i), 0, key_flags);
}
}
if (retro_setting_get_gamepad_cursor_only())
return;
#if defined(WIIU) || defined(__SWITCH__)
int p_x = retro_input_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
int p_y = retro_input_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
int p_press = retro_input_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED);
int px = (int)((p_x + 0x7fff) * getScreenWidth() / 0xffff);
int py = (int)((p_y + 0x7fff) * getScreenHeight() / 0xffff);
static int ptrhold = 0;
if (p_press)
ptrhold++;
else
ptrhold = 0;
if (ptrhold > 0) {
_mouseX = px;
_mouseY = py;
Common::Event ev;
ev.type = Common::EVENT_MOUSEMOVE;
ev.mouse.x = _mouseX;
ev.mouse.y = _mouseY;
_events.push_back(ev);
setMousePosition(_mouseX, _mouseY);
}
if (ptrhold > 10 && _ptrmouseButton == 0) {
_ptrmouseButton = 1;
Common::Event ev;
ev.type = eventID[0][_ptrmouseButton ? 0 : 1];
ev.mouse.x = _mouseX;
ev.mouse.y = _mouseY;
_events.push_back(ev);
} else if (ptrhold == 0 && _ptrmouseButton == 1) {
_ptrmouseButton = 0;
Common::Event ev;
ev.type = eventID[0][_ptrmouseButton ? 0 : 1];
ev.mouse.x = _mouseX;
ev.mouse.y = _mouseY;
_events.push_back(ev);
}
#endif
// Process input from physical mouse
x = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
y = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
// > X Axis
if (x != 0) {
_cursorStatus |= (CURSOR_STATUS_DOING_MOUSE | CURSOR_STATUS_DOING_X);
if (x > 0) {
// Reset accumulator when changing direction
_mouseXAcc = (_mouseXAcc < 0.0) ? 0.0 : _mouseXAcc;
}
if (x < 0) {
// Reset accumulator when changing direction
_mouseXAcc = (_mouseXAcc > 0.0) ? 0.0 : _mouseXAcc;
}
deltaAcc = (float)x * retro_setting_get_mouse_speed();
updateMouseXY(deltaAcc, &_mouseXAcc, 1);
}
// > Y Axis
if (y != 0) {
_cursorStatus |= (CURSOR_STATUS_DOING_MOUSE | CURSOR_STATUS_DOING_Y);
if (y > 0) {
// Reset accumulator when changing direction
_mouseYAcc = (_mouseYAcc < 0.0) ? 0.0 : _mouseYAcc;
}
if (y < 0) {
// Reset accumulator when changing direction
_mouseYAcc = (_mouseYAcc > 0.0) ? 0.0 : _mouseYAcc;
}
deltaAcc = (float)y * retro_setting_get_mouse_speed();
updateMouseXY(deltaAcc, &_mouseYAcc, 0);
}
if (_cursorStatus & CURSOR_STATUS_DOING_MOUSE) {
Common::Event ev;
ev.type = Common::EVENT_MOUSEMOVE;
ev.mouse.x = _mouseX;
ev.mouse.y = _mouseY;
ev.relMouse.x = _cursorStatus & CURSOR_STATUS_DOING_X ? _relMouseX : 0;
ev.relMouse.y = _cursorStatus & CURSOR_STATUS_DOING_Y ? _relMouseY : 0;
_events.push_back(ev);
setMousePosition(_mouseX, _mouseY);
}
for (int i = 0; i < 2; i++) {
Common::Event ev;
bool down = retro_input_cb(0, RETRO_DEVICE_MOUSE, 0, retroButtons[i]);
if (down != _mouseButtons[i]) {
_mouseButtons[i] = down;
ev.type = eventID[i][down ? 0 : 1];
ev.mouse.x = _mouseX;
ev.mouse.y = _mouseY;
_events.push_back(ev);
}
}
}
void OSystem_libretro::processKeyEvent(bool down, unsigned keycode, uint32 character, uint16 key_modifiers) {
int _keyflags = 0;
_keyflags |= (key_modifiers & RETROKMOD_CTRL) ? Common::KBD_CTRL : 0;
_keyflags |= (key_modifiers & RETROKMOD_ALT) ? Common::KBD_ALT : 0;
_keyflags |= (key_modifiers & RETROKMOD_SHIFT) ? Common::KBD_SHIFT : 0;
_keyflags |= (key_modifiers & RETROKMOD_META) ? Common::KBD_META : 0;
_keyflags |= (key_modifiers & RETROKMOD_CAPSLOCK) ? Common::KBD_CAPS : 0;
_keyflags |= (key_modifiers & RETROKMOD_NUMLOCK) ? Common::KBD_NUM : 0;
_keyflags |= (key_modifiers & RETROKMOD_SCROLLOCK) ? Common::KBD_SCRL : 0;
Common::Event ev;
ev.type = down ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
ev.kbd.keycode = (Common::KeyCode)keycode;
ev.kbd.flags = _keyflags;
ev.kbd.ascii = keycode;
/* If shift was down then send upper case letter to engine */
if (ev.kbd.ascii >= 97 && ev.kbd.ascii <= 122 && (_keyflags & Common::KBD_SHIFT))
ev.kbd.ascii = ev.kbd.ascii & ~0x20;
_events.push_back(ev);
}

View File

@@ -0,0 +1,283 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include <features/features_cpu.h>
#include "common/tokenizer.h"
#include "common/config-manager.h"
#include "common/translation.h"
#include "base/commandLine.h"
#include "base/plugins.h"
#include "engines/game.h"
#include "engines/metaengine.h"
#include "backends/platform/libretro/include/libretro-defs.h"
#include "backends/platform/libretro/include/libretro-core.h"
#include "backends/platform/libretro/include/libretro-os.h"
#include "backends/platform/libretro/include/libretro-options-widget.h"
#include "backends/platform/libretro/include/libretro-fs.h"
void OSystem_libretro::getTimeAndDate(TimeDate &t, bool skipRecord) const {
uint32 curTime = (uint32)(cpu_features_get_time_usec() / 1000000);
#define YEAR0 1900
#define EPOCH_YR 1970
#define SECS_DAY (24L * 60L * 60L)
#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
#define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
const int _ytab[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
int year = EPOCH_YR;
unsigned long dayclock = (unsigned long)curTime % SECS_DAY;
unsigned long dayno = (unsigned long)curTime / SECS_DAY;
t.tm_sec = dayclock % 60;
t.tm_min = (dayclock % 3600) / 60;
t.tm_hour = dayclock / 3600;
t.tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */
while (dayno >= YEARSIZE(year)) {
dayno -= YEARSIZE(year);
year++;
}
t.tm_year = year - YEAR0;
t.tm_mon = 0;
while (dayno >= _ytab[LEAPYEAR(year)][t.tm_mon]) {
dayno -= _ytab[LEAPYEAR(year)][t.tm_mon];
t.tm_mon++;
}
t.tm_mday = dayno + 1;
}
Common::Path OSystem_libretro::getDefaultConfigFileName() {
if (s_systemDir.empty())
return Common::Path("scummvm.ini");
else
return Common::Path(s_systemDir).appendComponent("scummvm.ini");
}
void OSystem_libretro::logMessage(LogMessageType::Type type, const char *message) {
retro_log_level loglevel = RETRO_LOG_INFO;
switch (type) {
case LogMessageType::kDebug:
loglevel = RETRO_LOG_DEBUG;
break;
case LogMessageType::kWarning:
loglevel = RETRO_LOG_WARN;
break;
case LogMessageType::kError:
loglevel = RETRO_LOG_ERROR;
break;
}
if (retro_log_cb)
retro_log_cb(loglevel, "%s\n", message);
}
bool OSystem_libretro::parseGameName(const Common::String &gameName, Common::String &engineId,
Common::String &gameId) {
Common::StringTokenizer tokenizer(gameName, ":");
Common::String token1, token2;
if (!tokenizer.empty()) {
token1 = tokenizer.nextToken();
}
if (!tokenizer.empty()) {
token2 = tokenizer.nextToken();
}
if (!tokenizer.empty()) {
return false; // Stray colon
}
if (!token1.empty() && !token2.empty()) {
engineId = token1;
gameId = token2;
return true;
} else if (!token1.empty()) {
engineId.clear();
gameId = token1;
return true;
}
return false;
}
int OSystem_libretro::testGame(const char *filedata, bool autodetect) {
Common::String game_id;
Common::String engine_id;
Common::String data = filedata;
int res = TEST_GAME_KO_NOT_FOUND;
PluginManager::instance().init();
PluginManager::instance().loadAllPlugins();
PluginManager::instance().loadDetectionPlugin();
if (autodetect) {
Common::FSNode dir = Common::FSNode(Common::Path(data));
Common::FSList files;
dir.getChildren(files, Common::FSNode::kListAll);
DetectionResults detectionResults = EngineMan.detectGames(files);
if (!detectionResults.listRecognizedGames().empty()) {
res = TEST_GAME_OK_ID_AUTODETECTED;
}
} else {
ConfMan.loadDefaultConfigFile(getDefaultConfigFileName().toString().c_str());
if (ConfMan.hasGameDomain(data)) {
res = TEST_GAME_OK_TARGET_FOUND;
} else {
parseGameName(data, engine_id, game_id);
QualifiedGameList games = EngineMan.findGamesMatching(engine_id, game_id);
if (games.size() == 1) {
res = TEST_GAME_OK_ID_FOUND;
} else if (games.size() > 1) {
res = TEST_GAME_KO_MULTIPLE_RESULTS;
}
}
}
PluginManager::destroy();
return res;
}
GUI::OptionsContainerWidget *OSystem_libretro::buildBackendOptionsWidget(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const {
if (target.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain))
return new LibretroOptionsWidget(boss, name, target);
else
return nullptr;
}
bool OSystem_libretro::checkPathSetting(const char *setting, Common::String const &defaultPath, bool isDirectory) {
Common::String setPath;
if (ConfMan.hasKey(setting))
setPath = Common::Path::fromConfig(ConfMan.get(setting)).toString();
if (setPath.empty() || !(isDirectory ? LibRetroFilesystemNode(setPath).isDirectory() : LibRetroFilesystemNode(setPath).exists()))
ConfMan.removeKey(setting, Common::ConfigManager::kApplicationDomain);
if (! ConfMan.hasKey(setting))
if (defaultPath.empty())
return false;
else
ConfMan.set(setting, defaultPath);
return true;
}
void OSystem_libretro::setLibretroDir(const char *path, Common::String &var) {
var = Common::String(path ? path : "");
if (! var.empty())
if (! LibRetroFilesystemNode(var).isDirectory())
var.clear();
return;
}
void OSystem_libretro::applyBackendSettings() {
/* ScummVM paths checks at startup and on settings applied */
Common::String s_homeDir(LibRetroFilesystemNode::getHomeDir());
Common::String s_themeDir(s_systemDir + "/" + SCUMMVM_SYSTEM_SUBDIR + "/" + SCUMMVM_THEME_SUBDIR);
Common::String s_extraDir(s_systemDir + "/" + SCUMMVM_SYSTEM_SUBDIR + "/" + SCUMMVM_EXTRA_SUBDIR);
Common::String s_soundfontPath(s_extraDir + "/" + DEFAULT_SOUNDFONT_FILENAME);
if (! LibRetroFilesystemNode(s_themeDir).isDirectory())
s_themeDir.clear();
if (! LibRetroFilesystemNode(s_extraDir).isDirectory())
s_extraDir.clear();
if (! LibRetroFilesystemNode(s_soundfontPath).exists())
s_soundfontPath.clear();
if (s_homeDir.empty() || ! LibRetroFilesystemNode(s_homeDir).isDirectory())
s_homeDir = s_systemDir;
//Register default paths
if (! s_homeDir.empty()) {
ConfMan.registerDefault("browser_lastpath", s_homeDir);
retro_log_cb(RETRO_LOG_DEBUG, "Default browser last path set to: %s\n", s_homeDir.c_str());
}
if (! s_saveDir.empty()) {
ConfMan.registerDefault("savepath", s_saveDir);
retro_log_cb(RETRO_LOG_DEBUG, "Default save path set to: %s\n", s_saveDir.c_str());
}
//Check current path settings
if (!checkPathSetting("savepath", s_saveDir)) {
ConfMan.setAndFlush("savepath", s_homeDir);
retro_osd_notification("ScummVM save folder not found.");
}
if (!checkPathSetting("themepath", s_themeDir))
retro_osd_notification("ScummVM theme folder not found.");
if (!checkPathSetting("extrapath", s_extraDir))
retro_osd_notification("ScummVM extra folder not found. Some engines/features (e.g. Virtual Keyboard) will not work without relevant datafiles.");
checkPathSetting("soundfont", s_soundfontPath, false);
checkPathSetting("browser_lastpath", s_homeDir);
checkPathSetting("libretro_playlist_path", s_playlistDir.empty() ? s_homeDir : s_playlistDir);
checkPathSetting("iconspath", "");
}
static const char *const helpTabs[] = {
_s("Libretro playlist"),
"",
_s(
"## Libretro playlists for ScummVM core\n"
"Playlists used in Libretro frontends (e.g. Retroarch) are plain text lists used to directly launch a game with a specific core from the user interface. Those lists are structured to pass to the core the path of a specific content file to be loaded (e.g. ROM).\n"
"\n"
"ScummVM core can accept as content the playlist-provided path to any of the files inside a valid game folder, the detection system will try to autodetect the game from the content file parent folder and run the game with default ScummVM options.\n"
"\n"
"The core also supports dedicated per game **hook** plain text files with **." CORE_EXTENSIONS "** extension, which can be used as target in the playlist to specify one of the following ScummVM identifiers:\n"
"\n"
" - **target**: this is the game identifier of each entry in the internal Launcher list, hence corresponding to entries in ScummVM configuration file (e.g. 'scummvm.ini'). In this case the game must be added from ScummVM GUI first, and the hook files can be placed anywhere, as the path for the game files is already part of the target configuration. The game will be launched with the options set in ScummVM\n"
"\n"
" - **game ID**: this is a unique identifier for any game supported by ScummVM. This identifier is hard coded in each engine source and can be subject to change, hence it is **not a recommended choice**. A list of current game IDs is available [here](https://scummvm.org/compatibility). In this case the game will be launched even if not added in ScummVM Launcher, the hook file must be placed in the game folder and the game will be launched with default ScummVM options\n"
"\n"
"## Creating ScummVM core playlist\n"
"The recommended way to generate a ScummVM core playlist is from within the ScummVM Launcher (i.e. the interal core GUI) with the Playlist Generator tool. Both needed hook files and the playlist are created automatically, based on ScummVM Launcher games list.\n"
"\n"
" - Load the core from RetroArch and start it to reach the ScummVM GUI (i.e. the Launcher)\n"
"\n"
" - Add games to the list as required using the GUI buttons ('Mass Add' available).\n"
"\n"
" - Select **Global Options** and then the **Backend** tab.\n"
"\n"
" - Check or select the path of frontend playlists. A '" CORE_NAME ".lpl' file will be created or overwritten in there.\n"
"\n"
" - Check the 'Hooks location' setting, to have one '." CORE_EXTENSIONS "' in each game folder or all of them in a '" COMMON_HOOKS_FOLDER "' folder in the 'save' path.\n"
"\n"
" - Check the 'Playlist version' setting. JSON format should be selected, 6-lines format is deprecated and provided for backwards compatibility only.\n"
"\n"
" - Select the 'Clear existing hooks' checkbox to remove any existing '." CORE_EXTENSIONS "' file in the working folders.\n"
"\n"
" - Press the 'Generate playlist' button.\n"
"\n"
"Operation status will be shown in the same dialog, while details will be given in frontend logs."
),
0 // End of list
};
const char *const *OSystem_libretro::buildHelpDialogData() {
return helpTabs;
}
Common::String OSystem_libretro::getSaveDir(void) {
return s_saveDir;
}
void OSystem_libretro::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
if (!s_systemDir.empty())
s.add("systemDir", new Common::FSDirectory(Common::FSNode(Common::Path(s_systemDir))), priority);
}

View File

@@ -0,0 +1,176 @@
/* Copyright (C) 2022 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <libretro.h>
#include "base/main.h"
#include "backends/platform/libretro/include/libretro-threads.h"
#define EMU_WAITING (1 << 0)
#define MAIN_WAITING (1 << 1)
#define EMU_STARTED (1 << 2)
#define EMU_EXITED (1 << 3)
static uint8 status = EMU_WAITING | MAIN_WAITING;
static int scummvm_res = -1;
#ifdef USE_LIBCO
#include <libco.h>
static cothread_t main_thread;
static cothread_t emu_thread;
#else
#include <rthreads/rthreads.h>
static uintptr_t main_thread_id;
static sthread_t *emu_thread;
static slock_t *emu_lock;
static slock_t *main_lock;
static scond_t *emu_cond;
static scond_t *main_cond;
#endif
extern char cmd_params[20][200];
extern char cmd_params_num;
static void retro_exit_to_main_thread() {
#ifdef USE_LIBCO
co_switch(main_thread);
#else
slock_lock(main_lock);
status &= ~MAIN_WAITING;
slock_unlock(main_lock);
slock_lock(emu_lock);
scond_signal(main_cond);
status |= EMU_WAITING;
while (status & EMU_WAITING) {
scond_wait(emu_cond, emu_lock);
}
slock_unlock(emu_lock);
#endif
}
static int retro_run_emulator(void) {
static const char *argv[20] = {0};
for (int i = 0; i < cmd_params_num; i++)
argv[i] = cmd_params[i];
return scummvm_main(cmd_params_num, argv);
}
static void retro_wrap_emulator(void) {
status &= ~EMU_EXITED;
status |= EMU_STARTED;
scummvm_res = retro_run_emulator();
status |= EMU_EXITED;
status &= ~EMU_STARTED;
retro_exit_to_main_thread();
}
#ifndef USE_LIBCO
static void retro_wrap_emulator(void *args) {
retro_wrap_emulator();
}
#endif
static void retro_free_emu_thread() {
#ifdef USE_LIBCO
if (emu_thread)
co_delete(emu_thread);
#else
if (main_lock)
slock_free(main_lock);
if (emu_lock)
slock_free(emu_lock);
if (main_cond)
scond_free(main_cond);
if (emu_cond)
scond_free(emu_cond);
#endif
emu_thread = NULL;
}
void retro_switch_to_emu_thread() {
if (retro_emu_thread_exited() || !retro_emu_thread_initialized())
return;
#ifdef USE_LIBCO
co_switch(emu_thread);
#else
slock_lock(emu_lock);
status &= ~EMU_WAITING;
slock_unlock(emu_lock);
slock_lock(main_lock);
scond_signal(emu_cond);
status |= MAIN_WAITING;
while (status & MAIN_WAITING) {
scond_wait(main_cond, main_lock);
}
slock_unlock(main_lock);
#endif
}
void retro_switch_to_main_thread() {
retro_exit_to_main_thread();
}
bool retro_emu_thread_initialized() {
return (bool)emu_thread;
}
bool retro_emu_thread_exited() {
return (bool)(status & EMU_EXITED);
}
bool retro_init_emu_thread(void) {
if (retro_emu_thread_initialized())
return true;
bool success = true;
#ifdef USE_LIBCO
main_thread = co_active();
emu_thread = co_create(65536 * sizeof(void *), retro_wrap_emulator);
if (!emu_thread)
#else
main_thread_id = sthread_get_current_thread_id();
main_lock = slock_new();
emu_lock = slock_new();
main_cond = scond_new();
emu_cond = scond_new();
emu_thread = sthread_create(retro_wrap_emulator, NULL);
if (!main_lock || !emu_lock || !main_cond || !emu_cond || !emu_thread)
#endif
success = false;
if (!success)
retro_free_emu_thread();
else
status &= ~(EMU_EXITED | EMU_STARTED);
return success;
}
void retro_deinit_emu_thread() {
if (retro_emu_thread_initialized())
retro_free_emu_thread();
}
int retro_get_scummvm_res() {
return scummvm_res;
}
bool retro_emu_thread_started(void) {
return (bool)(status & EMU_STARTED);
}

View File

@@ -0,0 +1,61 @@
/* Copyright (C) 2023 Giovanni Cascione <ing.cascione@gmail.com>
*
* This program 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 Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#if defined(__LIBRETRO__)
#include "common/scummsys.h"
#include "common/timer.h"
#include "backends/platform/libretro/include/libretro-os.h"
#include "backends/platform/libretro/include/libretro-threads.h"
#include "backends/platform/libretro/include/libretro-timer.h"
#include "backends/platform/libretro/include/libretro-defs.h"
LibretroTimerManager::LibretroTimerManager(uint32 refresh_rate) {
_interval = 1000 / refresh_rate / 2;
_nextSwitchTime = _interval + g_system->getMillis();
}
void LibretroTimerManager::switchThread(uint8 caller) {
_spentOnMainThread = g_system->getMillis();
_threadSwitchCaller = caller;
LIBRETRO_G_SYSTEM->refreshScreen();
retro_switch_to_main_thread();
_spentOnMainThread = g_system->getMillis() - _spentOnMainThread;
_nextSwitchTime = g_system->getMillis() + _interval;
handler();
}
bool LibretroTimerManager::checkThread(uint8 caller) {
if (g_system->getMillis() >= _nextSwitchTime) {
switchThread(caller);
return true;
} else
return false;
}
uint32 LibretroTimerManager::timeToNextSwitch(void) {
uint32 now = g_system->getMillis();
return _nextSwitchTime > now ? _nextSwitchTime - now : 0;
}
uint32 LibretroTimerManager::spentOnMainThread(void) {
return _spentOnMainThread;
}
uint8 LibretroTimerManager::getThreadSwitchCaller(void) {
return _threadSwitchCaller;
}
#endif