mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-25 18:55:57 +00:00
Compare commits
122 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e34fa1e868 | |||
| f85dc57d8d | |||
| 722bd07dbf | |||
| 56caa156b6 | |||
| ffc06b999b | |||
| 51833f6b82 | |||
| 643d78b0e3 | |||
| 38fd46eba4 | |||
| 33a0446b53 | |||
| c186cb9fc3 | |||
| 9c6c03acd1 | |||
| f4a0227426 | |||
| e631bae857 | |||
| 6cfa4ddc12 | |||
| d34a536690 | |||
| 8b4d074049 | |||
| bf7046d522 | |||
| 5ea19d0cdb | |||
| b243e2cb75 | |||
| 22f77b1024 | |||
| f8cfa2e4b1 | |||
| 84a21089e5 | |||
| 411ded7dcb | |||
| cda51e6be1 | |||
| c9ed08854a | |||
| 7d5461d73c | |||
| 3c31ce4d2e | |||
| 4ddbfed915 | |||
| 3ce6bc710b | |||
| 7fa966acde | |||
| fcbebef9f7 | |||
| 80b9b30f46 | |||
| 4c2f42f3a0 | |||
| a03160e381 | |||
| 627691d7a2 | |||
| 91c376a45f | |||
| f929f71b3c | |||
| b23fe40585 | |||
| 9627b84d33 | |||
| 12d4276fff | |||
| 30c81da18d | |||
| 076c7dd844 | |||
| 18dc426a8c | |||
| f820bd6ff0 | |||
| 0f030ae48f | |||
| ad8cea3da9 | |||
| ac4e7380b6 | |||
| 3ca742e6b1 | |||
| 088f3339de | |||
| bf2eed5fe2 | |||
| 4946e09eed | |||
| 71ca489704 | |||
| d224edfd16 | |||
| 5202095e1d | |||
| bb84074ecf | |||
| 692ce90e70 | |||
| 9ce4b67ab3 | |||
| e91b7b9ac5 | |||
| 86b1ed4ebd | |||
| bf98f8a96b | |||
| 25ff105c05 | |||
| 93f5af68c9 | |||
| e64b9da3a4 | |||
| ef3faf230f | |||
| f693011515 | |||
| 53583b4cc9 | |||
| 411f97c733 | |||
| b131f7f760 | |||
| 527fa0a083 | |||
| 725be65530 | |||
| 92f1e551b3 | |||
| 8096fd960f | |||
| f785cf3615 | |||
| 861cdbf912 | |||
| 32b066fb76 | |||
| 6957b45a44 | |||
| 9ce7e97db9 | |||
| b8e2616da7 | |||
| e769501611 | |||
| 7a388127bb | |||
| d97157e46b | |||
| ff3cbb7b05 | |||
| 2676a946a4 | |||
| 9e45bc4fb5 | |||
| fb81acab22 | |||
| 8f40bdb99a | |||
| 1de83fad38 | |||
| 47d59cf994 | |||
| a291a95645 | |||
| 99e3c4d2fa | |||
| cbeae28bd1 | |||
| 1019bed75b | |||
| 35b653e5fb | |||
| 0f86d527de | |||
| 4d948ce757 | |||
| 35c47438fb | |||
| e0748f02cd | |||
| cce9c1af6b | |||
| e9efa2c954 | |||
| 96b7e498f5 | |||
| c3707ba54c | |||
| 5eb11d3c7b | |||
| da45ac4f22 | |||
| 2a82754448 | |||
| 5262e18252 | |||
| 938666b672 | |||
| 781d1872f7 | |||
| 8f15dea93e | |||
| d0bfb8ed12 | |||
| 6f160733f5 | |||
| 97657104f7 | |||
| 60488f486e | |||
| 43c7f1c872 | |||
| 44848ea04c | |||
| ca086e59df | |||
| f24c00f3c0 | |||
| 939e79a71c | |||
| 076f42c8a9 | |||
| 264cff37a1 | |||
| 372c96a908 | |||
| 0228ef19df | |||
| c66efe83be |
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#!/usr/local/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
[ -z ${OO_PS4_TOOLCHAIN+x} ] && exit
|
||||
|
||||
# cmake
|
||||
[ -f "ps4-toolchain.cmake" ] || cat << EOF >"ps4-toolchain.cmake"
|
||||
set(CMAKE_SYSROOT "$OO_PS4_TOOLCHAIN")
|
||||
set(CMAKE_STAGING_PREFIX "$OO_PS4_TOOLCHAIN")
|
||||
set(CMAKE_SYSTEM_NAME "OpenOrbis")
|
||||
|
||||
set(CMAKE_C_FLAGS "-D__OPENORBIS__ -D_LIBCPP_HAS_MUSL_LIBC=1 -D_GNU_SOURCE=1 --target=x86_64-pc-freebsd12-elf -mtune=btver2 -march=btver2 -fPIC -funwind-tables -femulated-tls")
|
||||
set(CMAKE_CXX_FLAGS "-D__OPENORBIS__ -D_LIBCPP_HAS_MUSL_LIBC=1 -D_GNU_SOURCE=1 --target=x86_64-pc-freebsd12-elf -mtune=btver2 -march=btver2 -fPIC -funwind-tables -femulated-tls")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-m elf_x86_64 -pie -T $OO_PS4_TOOLCHAIN/link.x --eh-frame-hdr -L$OO_PS4_TOOLCHAIN/lib")
|
||||
set(CMAKE_C_LINK_FLAGS "-m elf_x86_64 -pie -T $OO_PS4_TOOLCHAIN/link.x --eh-frame-hdr -L$OO_PS4_TOOLCHAIN/lib")
|
||||
set(CMAKE_CXX_LINK_FLAGS "-m elf_x86_64 -pie -T $OO_PS4_TOOLCHAIN/link.x --eh-frame-hdr -L$OO_PS4_TOOLCHAIN/lib")
|
||||
|
||||
set(CMAKE_C_COMPILER clang)
|
||||
set(CMAKE_CXX_COMPILER clang++)
|
||||
set(CMAKE_LINKER ld.lld)
|
||||
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_C_LINK_FLAGS> <OBJECTS> -o <TARGET> -lc -lkernel -lSceUserService -lSceSysmodule -lSceNet -lSceLibcInternal $OO_PS4_TOOLCHAIN/lib/crt1.o <LINK_LIBRARIES>")
|
||||
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <OBJECTS> -o <TARGET> -lc -lkernel -lc++ -lSceUserService -lSceSysmodule -lSceNet -lSceLibcInternal $OO_PS4_TOOLCHAIN/lib/crt1.o <LINK_LIBRARIES>")
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
|
||||
# TODO: Why does cmake not set this?
|
||||
set(CMAKE_SIZEOF_VOID_P 8)
|
||||
EOF
|
||||
|
||||
[ -z ${NPROC+x} ] && NPROC=$(nproc || 1)
|
||||
|
||||
# Normally a platform has a package manager
|
||||
# PS4 does not, atleast not in the normal sense
|
||||
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" $@)
|
||||
[ -f "build/Makefile" ] || cmake -S . -B build -G "Unix Makefiles" \
|
||||
-DCMAKE_TOOLCHAIN_FILE="ps4-toolchain.cmake" \
|
||||
-DENABLE_QT_TRANSLATION=OFF \
|
||||
-DENABLE_CUBEB=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_CXX_FLAGS="$ARCH_FLAGS" \
|
||||
-DCMAKE_C_FLAGS="$ARCH_FLAGS" \
|
||||
-DENABLE_SDL2=ON \
|
||||
-DENABLE_LIBUSB=OFF \
|
||||
-DENABLE_UPDATE_CHECKER=OFF \
|
||||
-DENABLE_QT=OFF \
|
||||
-DENABLE_OPENGL=ON \
|
||||
-DENABLE_WEB_SERVICE=OFF \
|
||||
-DUSE_DISCORD_PRESENCE=OFF \
|
||||
-DCPMUTIL_FORCE_BUNDLED=ON \
|
||||
-DYUZU_USE_EXTERNAL_FFMPEG=ON \
|
||||
-DYUZU_USE_CPM=ON \
|
||||
-DDYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=OFF \
|
||||
-DDYNARMIC_TESTS=ON \
|
||||
-DYUZU_TESTS=ON \
|
||||
-DYUZU_USE_EXTERNAL_SDL2=ON \
|
||||
"${EXTRA_CMAKE_FLAGS[@]}" || exit
|
||||
|
||||
cmake --build build -t yuzu-cmd_pkg -- -j$NPROC
|
||||
#cmake --build build -t dynarmic_tests_pkg -- -j$NPROC
|
||||
#cmake --build build -t testps4_pkg -- -j$NPROC
|
||||
+2
-2
@@ -64,5 +64,5 @@ artifacts
|
||||
vulkansdk*.exe
|
||||
*.tar.zst
|
||||
|
||||
# Build-time generated external sources
|
||||
externals/generated
|
||||
# PS4 toolchain stuff
|
||||
ps4-toolchain.cmake
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/libs/cobalt/include/boost/cobalt/concepts.hpp b/libs/cobalt/include/boost/cobalt/concepts.hpp
|
||||
index d49f2ec..a9bdb80 100644
|
||||
--- a/libs/cobalt/include/boost/cobalt/concepts.hpp
|
||||
+++ b/libs/cobalt/include/boost/cobalt/concepts.hpp
|
||||
@@ -62,7 +62,7 @@ struct enable_awaitables
|
||||
template <typename T>
|
||||
concept with_get_executor = requires (T& t)
|
||||
{
|
||||
- {t.get_executor()} -> asio::execution::executor;
|
||||
+ t.get_executor();
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
diff --git a/libs/asio/include/boost/asio/detail/impl/socket_ops.ipp b/libs/asio/include/boost/asio/detail/impl/socket_ops.ipp
|
||||
index 0129511c..10fc9b04 100644
|
||||
--- a/libs/asio/include/boost/asio/detail/impl/socket_ops.ipp
|
||||
+++ b/libs/asio/include/boost/asio/detail/impl/socket_ops.ipp
|
||||
@@ -15,6 +15,12 @@
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
+// hacky fix for ps4
|
||||
+#if defined(__OPENORBIS__)
|
||||
+# define FIONBIO 0
|
||||
+# define FIONREAD 1
|
||||
+#endif
|
||||
+
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#include <cctype>
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/unix.c b/unix.c
|
||||
index 6669216..86a2faa 100644
|
||||
--- a/unix.c
|
||||
+++ b/unix.c
|
||||
@@ -53,7 +53,7 @@
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
-#if !defined(HAS_SOCKLEN_T) && !defined(__socklen_t_defined)
|
||||
+#if !defined(__OPENORBIS__) && !defined(HAS_SOCKLEN_T) && !defined(__socklen_t_defined)
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
|
||||
index 03e2720..874258f 100644
|
||||
--- a/libavutil/cpu.c
|
||||
+++ b/libavutil/cpu.c
|
||||
@@ -43,8 +43,10 @@
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
+#ifndef __OPENORBIS__
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
+#endif
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
diff --git a/cmake/ConfigureOpenSSL.cmake b/cmake/ConfigureOpenSSL.cmake
|
||||
index 3012e05..2ae23ff 100644
|
||||
--- a/cmake/ConfigureOpenSSL.cmake
|
||||
+++ b/cmake/ConfigureOpenSSL.cmake
|
||||
@@ -108,7 +108,8 @@ function(configure_openssl)
|
||||
)
|
||||
|
||||
if(NOT "${CONFIGURE_OPTIONS_OLD}" STREQUAL "")
|
||||
- if(CONFIGURE_OPTIONS STREQUAL CONFIGURE_OPTIONS_OLD)
|
||||
+ # TODO(lizzie): Emscripten has issues with rebuilding due to the wrapper it uses
|
||||
+ if(CMAKE_SYSTEM_NAME MATCHES "Emscripten" OR CONFIGURE_OPTIONS STREQUAL CONFIGURE_OPTIONS_OLD)
|
||||
message(STATUS "Found previous configure results. Don't perform configuration")
|
||||
return()
|
||||
endif()
|
||||
@@ -134,10 +135,24 @@ function(configure_openssl)
|
||||
set(VERBOSE_OPTION OUTPUT_QUIET)
|
||||
endif()
|
||||
|
||||
+ if (CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
+ set(EMSCRIPTEN_CMAKE_WRAPPER "emcmake")
|
||||
+ find_program(EMCC emcc REQUIRED)
|
||||
+ set(EMSCRIPTEN_LINKER ${EMCC})
|
||||
+ list(APPEND CONFIGURE_COMMAND wasm64)
|
||||
+ else()
|
||||
+ set(EMSCRIPTEN_CMAKE_WRAPPER "")
|
||||
+ set(EMSCRIPTEN_LINKER ${CMAKE_LINKER})
|
||||
+ endif ()
|
||||
+
|
||||
execute_process(
|
||||
- COMMAND ${CMAKE_COMMAND} -E env
|
||||
+ COMMAND ${EMSCRIPTEN_CMAKE_WRAPPER} ${CMAKE_COMMAND} -E env
|
||||
"CFLAGS=${CMAKE_C_FLAGS}"
|
||||
"CXXFLAGS=${CMAKE_CXX_FLAGS}"
|
||||
+ "LDFLAGS=${CMAKE_CXX_LINK_FLAGS}"
|
||||
+ "CC=${CMAKE_C_COMPILER}"
|
||||
+ "CXX=${CMAKE_CXX_COMPILER}"
|
||||
+ "LD=${EMSCRIPTEN_LINKER}"
|
||||
${CONFIGURE_COMMAND}
|
||||
WORKING_DIRECTORY ${CONFIGURE_BUILD_DIR}
|
||||
${VERBOSE_OPTION}
|
||||
@@ -0,0 +1,33 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 1ca57e1..593fd62 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -148,6 +148,16 @@ if(NOT BUILD_SHARED_LIBS)
|
||||
list(APPEND OPENSSL_CONFIGURE_OPTIONS no-shared)
|
||||
endif()
|
||||
|
||||
+list(APPEND OPENSSL_CONFIGURE_OPTIONS
|
||||
+ no-threads no-thread-pool no-shared no-afalgeng no-async no-capieng no-cmp no-cms no-comp no-ct
|
||||
+ no-docs no-dgram no-dso no-dynamic-engine no-engine no-filenames no-gost
|
||||
+ no-http no-legacy no-module no-nextprotoneg no-ocsp no-padlockeng no-quic
|
||||
+ no-srp no-srtp no-ssl-trace no-static-engine no-tests no-thread-pool no-ts
|
||||
+ no-ui-console no-uplink no-ssl3-method no-tls1-method no-tls1_1-method
|
||||
+ no-dtls1-method no-dtls1_2-method no-argon2 no-bf no-blake2 no-cast
|
||||
+ no-dsa no-idea no-md4 no-mdc2 no-ocb no-rc2 no-rc4 no-rmd160 no-scrypt
|
||||
+ no-siphash no-siv no-sm2 no-sm3 no-sm4 no-whirlpool no-apps)
|
||||
+
|
||||
list(SORT OPENSSL_CONFIGURE_OPTIONS)
|
||||
list(REMOVE_DUPLICATES OPENSSL_CONFIGURE_OPTIONS)
|
||||
list(PREPEND OPENSSL_CONFIGURE_OPTIONS ${OPENSSL_TARGET_PLATFORM})
|
||||
diff --git a/cmake/ConfigureOpenSSL.cmake b/cmake/ConfigureOpenSSL.cmake
|
||||
index 2ae23ff..22a4a27 100644
|
||||
--- a/cmake/ConfigureOpenSSL.cmake
|
||||
+++ b/cmake/ConfigureOpenSSL.cmake
|
||||
@@ -154,6 +154,7 @@ function(configure_openssl)
|
||||
"CXX=${CMAKE_CXX_COMPILER}"
|
||||
"LD=${EMSCRIPTEN_LINKER}"
|
||||
${CONFIGURE_COMMAND}
|
||||
+ "--prefix=${CMAKE_SYSROOT}"
|
||||
WORKING_DIRECTORY ${CONFIGURE_BUILD_DIR}
|
||||
${VERBOSE_OPTION}
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/crypto/o_str.c b/crypto/o_str.c
|
||||
index 8aadff5..ba427c9 100644
|
||||
--- a/crypto/o_str.c
|
||||
+++ b/crypto/o_str.c
|
||||
@@ -385,7 +385,7 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen)
|
||||
* It can return a pointer to some (immutable) static string in which case
|
||||
* buf is left unused.
|
||||
*/
|
||||
- err = strerror_r(errnum, buf, buflen);
|
||||
+ err = (char *)strerror_r(errnum, buf, buflen);
|
||||
if (err == NULL || buflen == 0)
|
||||
return 0;
|
||||
/*
|
||||
@@ -1,11 +0,0 @@
|
||||
--- a/source/effect_lexer.cpp
|
||||
+++ b/source/effect_lexer.cpp
|
||||
@@ -1181,7 +1181,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
-#if 0
|
||||
+#if !defined(__cpp_lib_to_chars)
|
||||
exponent += decimal_location - mantissa_size;
|
||||
|
||||
const bool exponent_negative = exponent < 0;
|
||||
@@ -0,0 +1,196 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 8872895..b0eeca8 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -1770,7 +1770,6 @@ elseif(EMSCRIPTEN)
|
||||
|
||||
CheckPTHREAD()
|
||||
CheckLibUnwind()
|
||||
-
|
||||
elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
|
||||
|
||||
set(SDL_DISABLE_DLOPEN_NOTES TRUE)
|
||||
@@ -3647,10 +3646,30 @@ if(NOT HAVE_CAMERA)
|
||||
)
|
||||
endif()
|
||||
|
||||
+# Always on?
|
||||
+if (OPENORBIS)
|
||||
+ sdl_sources(
|
||||
+ "${SDL3_SOURCE_DIR}/src/thread/pthread/SDL_systhread.c"
|
||||
+ "${SDL3_SOURCE_DIR}/src/thread/pthread/SDL_sysmutex.c" # Can be faked, if necessary
|
||||
+ "${SDL3_SOURCE_DIR}/src/thread/pthread/SDL_syscond.c" # Can be faked, if necessary
|
||||
+ "${SDL3_SOURCE_DIR}/src/thread/pthread/SDL_sysrwlock.c" # Can be faked, if necessary
|
||||
+ "${SDL3_SOURCE_DIR}/src/thread/pthread/SDL_systls.c"
|
||||
+ "${SDL3_SOURCE_DIR}/src/thread/generic/SDL_syssem.c"
|
||||
+ )
|
||||
+ sdl_glob_sources("${SDL3_SOURCE_DIR}/src/time/unix/*.c")
|
||||
+ sdl_glob_sources("${SDL3_SOURCE_DIR}/src/timer/unix/*.c")
|
||||
+ set(HAVE_SDL_THREADS TRUE)
|
||||
+ set(HAVE_SDL_TIMERS TRUE)
|
||||
+ set(HAVE_SDL_TIME TRUE)
|
||||
+ set(SDL_TIME_UNIX 1)
|
||||
+ set(SDL_TIMER_UNIX 1)
|
||||
+ set(SDL_THREAD_PTHREAD 1)
|
||||
+endif ()
|
||||
+
|
||||
# We always need to have threads and timers around
|
||||
if(NOT HAVE_SDL_THREADS)
|
||||
# The Emscripten and N-Gage platform has been carefully vetted to work without threads
|
||||
- if(EMSCRIPTEN OR NGAGE)
|
||||
+ if(EMSCRIPTEN OR NGAGE OR OPENORBIS)
|
||||
set(SDL_THREADS_DISABLED 1)
|
||||
sdl_glob_sources(
|
||||
"${SDL3_SOURCE_DIR}/src/thread/generic/*.c"
|
||||
diff --git a/build-scripts/rename_macros.py b/build-scripts/rename_macros.py
|
||||
index 978120c..b6063dd 100755
|
||||
--- a/build-scripts/rename_macros.py
|
||||
+++ b/build-scripts/rename_macros.py
|
||||
@@ -124,6 +124,7 @@ RENAMED_MACROS = {
|
||||
"__RISCOS__": "SDL_PLATFORM_RISCOS",
|
||||
"__SOLARIS__": "SDL_PLATFORM_SOLARIS",
|
||||
"__PSP__": "SDL_PLATFORM_PSP",
|
||||
+ "__PS4__": "SDL_PLATFORM_PS4",
|
||||
"__PS2__": "SDL_PLATFORM_PS2",
|
||||
"__VITA__": "SDL_PLATFORM_VITA",
|
||||
"__3DS__": "SDL_PLATFORM_3DS",
|
||||
diff --git a/include/SDL3/SDL_platform_defines.h b/include/SDL3/SDL_platform_defines.h
|
||||
index 7963149..6c0dd5d 100644
|
||||
--- a/include/SDL3/SDL_platform_defines.h
|
||||
+++ b/include/SDL3/SDL_platform_defines.h
|
||||
@@ -442,6 +442,16 @@
|
||||
#define SDL_PLATFORM_PSP 1
|
||||
#endif
|
||||
|
||||
+#if defined(__PS4__) || defined(__OPENORBIS__)
|
||||
+
|
||||
+/**
|
||||
+ * A preprocessor macro that is only defined if compiling for Sony PSP.
|
||||
+ *
|
||||
+ * \since This macro is available since SDL 3.2.0.
|
||||
+ */
|
||||
+#define SDL_PLATFORM_PS4 1
|
||||
+#endif
|
||||
+
|
||||
#if defined(__PS2__) || defined(PS2)
|
||||
|
||||
/**
|
||||
diff --git a/src/SDL.c b/src/SDL.c
|
||||
index b1a1a56..0a3fec6 100644
|
||||
--- a/src/SDL.c
|
||||
+++ b/src/SDL.c
|
||||
@@ -714,7 +714,7 @@ void SDL_Quit(void)
|
||||
SDL_DBus_Quit();
|
||||
#endif
|
||||
|
||||
-#if defined(SDL_PLATFORM_UNIX) && !defined(SDL_PLATFORM_ANDROID) && !defined(SDL_PLATFORM_EMSCRIPTEN) && !defined(SDL_PLATFORM_PRIVATE)
|
||||
+#if defined(SDL_PLATFORM_UNIX) && !defined(SDL_PLATFORM_ANDROID) && !defined(SDL_PLATFORM_EMSCRIPTEN) && !defined(SDL_PLATFORM_PRIVATE) && !defined(SDL_PLATFORM_PS4)
|
||||
SDL_Gtk_Quit();
|
||||
#endif
|
||||
|
||||
@@ -813,6 +813,8 @@ const char *SDL_GetPlatform(void)
|
||||
return "tvOS";
|
||||
#elif defined(SDL_PLATFORM_PS2)
|
||||
return "PlayStation 2";
|
||||
+#elif defined(SDL_PLATFORM_PS4)
|
||||
+ return "PlayStation 4";
|
||||
#elif defined(SDL_PLATFORM_PSP)
|
||||
return "PlayStation Portable";
|
||||
#elif defined(SDL_PLATFORM_VITA)
|
||||
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
|
||||
index c1e4241..65b1e6d 100644
|
||||
--- a/src/audio/SDL_audio.c
|
||||
+++ b/src/audio/SDL_audio.c
|
||||
@@ -80,6 +80,9 @@ static const AudioBootStrap *const bootstrap[] = {
|
||||
#ifdef SDL_AUDIO_DRIVER_NGAGE
|
||||
&NGAGEAUDIO_bootstrap,
|
||||
#endif
|
||||
+#ifdef SDL_AUDIO_DRIVER_PS4
|
||||
+ &PS4AUDIO_bootstrap,
|
||||
+#endif
|
||||
#ifdef SDL_AUDIO_DRIVER_EMSCRIPTEN
|
||||
&EMSCRIPTENAUDIO_bootstrap,
|
||||
#endif
|
||||
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
|
||||
index 60c9743..2d12c3a 100644
|
||||
--- a/src/joystick/SDL_joystick.c
|
||||
+++ b/src/joystick/SDL_joystick.c
|
||||
@@ -106,6 +106,9 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = {
|
||||
#ifdef SDL_JOYSTICK_N3DS
|
||||
&SDL_N3DS_JoystickDriver,
|
||||
#endif
|
||||
+#ifdef SDL_JOYSTICK_PS4
|
||||
+ &SDL_PS4_JoystickDriver,
|
||||
+#endif
|
||||
#if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED)
|
||||
&SDL_DUMMY_JoystickDriver
|
||||
#endif
|
||||
diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h
|
||||
index 47ce42c..42ab9de 100644
|
||||
--- a/src/joystick/SDL_sysjoystick.h
|
||||
+++ b/src/joystick/SDL_sysjoystick.h
|
||||
@@ -253,6 +253,7 @@ extern SDL_JoystickDriver SDL_HAIKU_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_HIDAPI_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_IOS_JoystickDriver;
|
||||
+extern SDL_JoystickDriver SDL_PS4_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_LINUX_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_WGI_JoystickDriver;
|
||||
diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h
|
||||
index a1bb44a..51843c4 100644
|
||||
--- a/src/render/SDL_sysrender.h
|
||||
+++ b/src/render/SDL_sysrender.h
|
||||
@@ -381,6 +381,7 @@ extern SDL_RenderDriver NGAGE_RenderDriver;
|
||||
extern SDL_RenderDriver VULKAN_RenderDriver;
|
||||
extern SDL_RenderDriver PS2_RenderDriver;
|
||||
extern SDL_RenderDriver PSP_RenderDriver;
|
||||
+extern SDL_RenderDriver PS4_RenderDriver;
|
||||
extern SDL_RenderDriver SW_RenderDriver;
|
||||
extern SDL_RenderDriver VITA_GXM_RenderDriver;
|
||||
extern SDL_RenderDriver GPU_RenderDriver;
|
||||
diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
|
||||
index 4a870f6..69ca1db 100644
|
||||
--- a/src/stdlib/SDL_string.c
|
||||
+++ b/src/stdlib/SDL_string.c
|
||||
@@ -32,7 +32,9 @@
|
||||
|
||||
#include "SDL_casefolding.h"
|
||||
|
||||
-#if defined(__SIZEOF_WCHAR_T__)
|
||||
+#if defined(SDL_PLATFORM_PS4)
|
||||
+#define SDL_SIZEOF_WCHAR_T 2
|
||||
+#elif defined(__SIZEOF_WCHAR_T__)
|
||||
#define SDL_SIZEOF_WCHAR_T __SIZEOF_WCHAR_T__
|
||||
#elif defined(SDL_PLATFORM_NGAGE)
|
||||
#define SDL_SIZEOF_WCHAR_T 2
|
||||
@@ -43,7 +45,6 @@
|
||||
#endif
|
||||
SDL_COMPILE_TIME_ASSERT(sizeof_wchar_t, sizeof(wchar_t) == SDL_SIZEOF_WCHAR_T);
|
||||
|
||||
-
|
||||
char *SDL_UCS4ToUTF8(Uint32 codepoint, char *dst)
|
||||
{
|
||||
if (!dst) {
|
||||
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
|
||||
index f650f27..e23424f 100644
|
||||
--- a/src/video/SDL_video.c
|
||||
+++ b/src/video/SDL_video.c
|
||||
@@ -131,6 +131,9 @@ static VideoBootStrap *bootstrap[] = {
|
||||
#ifdef SDL_VIDEO_DRIVER_NGAGE
|
||||
&NGAGE_bootstrap,
|
||||
#endif
|
||||
+#ifdef SDL_VIDEO_DRIVER_PS4
|
||||
+ &PS4_bootstrap,
|
||||
+#endif
|
||||
#ifdef SDL_VIDEO_DRIVER_KMSDRM
|
||||
&KMSDRM_bootstrap,
|
||||
#endif
|
||||
@@ -314,6 +317,7 @@ static bool SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window *window,
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
|
||||
if (!data) {
|
||||
+
|
||||
SDL_Renderer *renderer = NULL;
|
||||
const char *render_driver = NULL;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
diff --git a/source/opt/loop_dependence.cpp b/source/opt/loop_dependence.cpp
|
||||
index e41c044..a51b53b 100644
|
||||
--- a/source/opt/loop_dependence.cpp
|
||||
+++ b/source/opt/loop_dependence.cpp
|
||||
@@ -12,6 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
+// PS4: issue?
|
||||
+#ifdef __PS4__
|
||||
+#pragma clang diagnostic ignored "-Wabsolute-value"
|
||||
+#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
+#endif
|
||||
+
|
||||
#include "source/opt/loop_dependence.h"
|
||||
|
||||
#include <functional>
|
||||
@@ -19,6 +25,7 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
+#include <cstdlib>
|
||||
|
||||
#include "source/opt/instruction.h"
|
||||
#include "source/opt/scalar_analysis_nodes.h"
|
||||
+8
-5
@@ -23,6 +23,7 @@ include(UseCcache)
|
||||
include(CMakeDependentOption)
|
||||
include(CTest)
|
||||
include(CPMUtil)
|
||||
include(OpenOrbis)
|
||||
|
||||
if (NOT DEFINED ARCHITECTURE)
|
||||
message(FATAL_ERROR "Architecture didn't make it out of scope, did you delete DetectArchitecture.cmake?")
|
||||
@@ -85,8 +86,6 @@ option(ENABLE_WERROR "Enable -Werror diagnostics" ON)
|
||||
# Lossless Scaling frame generation. Only Android.
|
||||
cmake_dependent_option(ENABLE_LSFG "Enable Lossless Scaling frame generation" ON "ANDROID" OFF)
|
||||
|
||||
option(ENABLE_RESHADE "Enable ReShade FX post-processing effects" ON)
|
||||
|
||||
# non-linux bundled qt are static
|
||||
if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX))
|
||||
set(YUZU_STATIC_BUILD ON)
|
||||
@@ -417,9 +416,12 @@ AddJsonPackage(boost)
|
||||
set(BOOST_NO_HEADERS ${Boost_ADDED})
|
||||
|
||||
if (Boost_ADDED)
|
||||
add_compile_definitions(YUZU_BOOST_v1)
|
||||
if (MSVC OR ANDROID)
|
||||
add_compile_definitions(YUZU_BOOST_v1)
|
||||
endif()
|
||||
|
||||
if (NOT MSVC OR CXX_CLANG)
|
||||
# solaris sucks
|
||||
# boost sucks
|
||||
if (SOLARIS)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-pthreads>)
|
||||
endif()
|
||||
@@ -428,7 +430,8 @@ if (Boost_ADDED)
|
||||
target_compile_options(boost_icl INTERFACE $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-shadow>)
|
||||
target_compile_options(boost_asio INTERFACE
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-conversion>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-fallthrough>)
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-fallthrough>
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -18,10 +18,13 @@ if (DEFINED GIT_RELEASE)
|
||||
set(BUILD_VERSION "${GIT_TAG}")
|
||||
set(GIT_REFSPEC "${GIT_RELEASE}")
|
||||
set(IS_DEV_BUILD false)
|
||||
else()
|
||||
elseif(DEFINED GIT_COMMIT)
|
||||
string(SUBSTRING ${GIT_COMMIT} 0 10 BUILD_VERSION)
|
||||
set(BUILD_VERSION "${BUILD_VERSION}-${GIT_REFSPEC}")
|
||||
set(IS_DEV_BUILD true)
|
||||
else()
|
||||
set(BUILD_VERSION "NoGitInfo")
|
||||
set(IS_DEV_BUILD true)
|
||||
endif()
|
||||
|
||||
if (NIGHTLY_BUILD)
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
function(create_ps4_eboot project target content_id)
|
||||
set(sce_sys_dir sce_sys)
|
||||
set(sce_sys_param ${sce_sys_dir}/param.sfo)
|
||||
add_custom_command(
|
||||
OUTPUT "${target}.pkg"
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/create-fself -in=bin/${target} -out=${target}.oelf --eboot ${target}_eboot.bin
|
||||
VERBATIM
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
DEPENDS ${project}
|
||||
)
|
||||
add_custom_target(${project}_pkg ALL DEPENDS "${target}.pkg")
|
||||
endfunction()
|
||||
|
||||
function(create_ps4_pkg project target content_id)
|
||||
set(sce_sys_dir sce_sys)
|
||||
set(sce_sys_param ${sce_sys_dir}/param.sfo)
|
||||
add_custom_command(
|
||||
OUTPUT "${target}.pkg"
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/create-fself -in=bin/${target} -out=${target}.oelf --eboot ${target}_eboot.bin
|
||||
COMMAND mkdir -p ${sce_sys_dir}
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_new ${sce_sys_param}
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} APP_TYPE --type Integer --maxsize 4 --value 1
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} APP_VER --type Utf8 --maxsize 8 --value 1.03
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} ATTRIBUTE --type Integer --maxsize 4 --value 0
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} CATEGORY --type Utf8 --maxsize 4 --value gd
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} CONTENT_ID --type Utf8 --maxsize 48 --value ${content_id}
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} DOWNLOAD_DATA_SIZE --type Integer --maxsize 4 --value 0
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} SYSTEM_VER --type Integer --maxsize 4 --value 0
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} TITLE --type Utf8 --maxsize 128 --value ${target}
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} TITLE_ID --type Utf8 --maxsize 12 --value BREW00090
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} VERSION --type Utf8 --maxsize 8 --value 1.03
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/create-gp4 -out ${target}.gp4 --content-id=${content_id} --files "${target}_eboot.bin ${sce_sys_param} sce_module/libc.prx sce_module/libSceFios2.prx"
|
||||
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core pkg_build ${target}.gp4 .
|
||||
VERBATIM
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
DEPENDS ${project}
|
||||
)
|
||||
add_custom_target(${project}_pkg ALL DEPENDS "${target}.pkg")
|
||||
endfunction()
|
||||
|
||||
if (NOT DEFINED ENV{OO_PS4_TOOLCHAIN})
|
||||
set(ENV{OO_PS4_TOOLCHAIN} ${CMAKE_SYSROOT})
|
||||
endif ()
|
||||
+28
-19
@@ -6,19 +6,23 @@
|
||||
"version": "v0.19.0"
|
||||
},
|
||||
"boost": {
|
||||
"artifact": "boost-%VERSION%.tar.zst",
|
||||
"artifact": "%VERSION%-cmake.tar.xz",
|
||||
"find_args": "CONFIG OPTIONAL_COMPONENTS headers context system fiber filesystem",
|
||||
"hash": "681d97be4386767662e230b2e7c9754d45e709cc5db4e747c23c27d1f5b0e87770bdf19b0bc44dcb0e8349324887bbb8fffb432098f4d0ce74a5043021a90afc",
|
||||
"hash": "6ae6e94664fe7f2fb01976b59b276ac5df8085c7503fa829d810fbfe495960cfec44fa2c36e2cb23480bc19c956ed199d4952b02639a00a6c07625d4e7130c2d",
|
||||
"min_version": "1.57",
|
||||
"package": "Boost",
|
||||
"repo": "eden-emulator/ext-boost",
|
||||
"version": "1.92.0"
|
||||
"patches": [
|
||||
"0001-clang-cl.patch",
|
||||
"0004-openorbis.patch"
|
||||
],
|
||||
"repo": "boostorg/boost",
|
||||
"version": "boost-1.90.0"
|
||||
},
|
||||
"boost_headers": {
|
||||
"bundled": true,
|
||||
"hash": "c5fa2cd72f6e6666b7963b97bc359c75284b8fb540c30f3629a028b85270c9bc66c8a051383964f2bd4c1e005a4691593d15696e7ef39ea87cf6cff9e5691fb2",
|
||||
"hash": "4ef845775e2277a8104ded6ddf749aa262ce52cf8438042869a048f9a0156dd772fbbcfa74efa1378fecef339b7286f6fe4b4feb5c45d49966b35d08e3e83507",
|
||||
"repo": "boostorg/headers",
|
||||
"version": "boost-1.91.0"
|
||||
"version": "boost-1.90.0"
|
||||
},
|
||||
"catch2": {
|
||||
"hash": "7eea385d79d88a5690cde131fe7ccda97d5c54ea09d6f515000d7bf07c828809d61c1ac99912c1ee507cf933f61c1c47ecdcc45df7850ffa82714034b0fccf35",
|
||||
@@ -67,12 +71,18 @@
|
||||
"hash": "a0d2fa8c957704dd49e00a726284ac5ca034b50b00d2b20a94fa1bbfbb80841467834bfdc84aa0ed0d6aab894608fd6c86c3b94eee46343f0e6d9c22e391dbf9",
|
||||
"min_version": "1.3",
|
||||
"repo": "lsalzman/enet",
|
||||
"version": "v1.3.18"
|
||||
"version": "v1.3.18",
|
||||
"patches": [
|
||||
"0001-openorbis.patch"
|
||||
]
|
||||
},
|
||||
"ffmpeg": {
|
||||
"hash": "ed177621176b3961bdcaa339187d3a7688c1c8b060b79c4bb0257cbc67ad7021ae5d5adca5303b45625abbbe3d9aafdd87ce777b8690ac295290d744c875489a",
|
||||
"repo": "FFmpeg/FFmpeg",
|
||||
"version": "c7b5f1537d"
|
||||
"version": "c7b5f1537d",
|
||||
"patches": [
|
||||
"0001-sysctl-openorbis.patch"
|
||||
]
|
||||
},
|
||||
"ffmpeg-ci": {
|
||||
"ci": true,
|
||||
@@ -180,7 +190,8 @@
|
||||
"min_version": "3.0.0",
|
||||
"package": "OpenSSL",
|
||||
"patches": [
|
||||
"0001-add-bundled-cert.patch"
|
||||
"0001-add-bundled-cert.patch",
|
||||
"0002-fix-gnu-openorbis.patch"
|
||||
],
|
||||
"repo": "openssl/openssl",
|
||||
"version": "openssl-3.6.2"
|
||||
@@ -202,7 +213,9 @@
|
||||
"0001-cpmutil-compat.patch",
|
||||
"0002-use-ccache.patch",
|
||||
"0003-use-cmake-compiler-flags.patch",
|
||||
"0004-use-shell-wrapper.patch"
|
||||
"0004-use-shell-wrapper.patch",
|
||||
"0005-wasm-support.patch",
|
||||
"0006-openorbis-prefix.patch"
|
||||
],
|
||||
"repo": "jimmy-park/openssl-cmake",
|
||||
"version": "3.6.2"
|
||||
@@ -235,20 +248,16 @@
|
||||
"repo": "stachenov/quazip",
|
||||
"version": "2e95c9001b"
|
||||
},
|
||||
"reshade": {
|
||||
"hash": "6fc9b39821ca6e2d91160f05846b3a42159fec759f5d6fba91d1a57801a1bdaf6047740578c136f0b1a60a9c29ad160d87dbfe0dbfbcdf6ea879a8a078377b8c",
|
||||
"patches": [
|
||||
"0001-from-chars-fallback.patch"
|
||||
],
|
||||
"repo": "crosire/reshade",
|
||||
"version": "v6.8.0"
|
||||
},
|
||||
"sdl3": {
|
||||
"hash": "df5a323af7ac366661a3c0e887969c72584d232f3cc211419d59b0487b620b6b2859d4549c9e8df002ee489290062e466fcfddf7edc0872a37b1f2845e81c0f3",
|
||||
"min_version": "3.2.10",
|
||||
"package": "SDL3",
|
||||
"repo": "libsdl-org/SDL",
|
||||
"version": "release-3.4.8"
|
||||
"version": "release-3.4.8",
|
||||
"patches": [
|
||||
"0001-ps4.patch",
|
||||
"0002-ps4-drivers.patch"
|
||||
]
|
||||
},
|
||||
"sdl3-ci": {
|
||||
"ci": true,
|
||||
|
||||
Vendored
+223
@@ -0,0 +1,223 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
fill="none"
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg7"
|
||||
sodipodi:docname="ps4.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
inkscape:export-filename="base.svg.2026_01_12_14_43_47.0.svg"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs7">
|
||||
<linearGradient
|
||||
id="linearGradient5"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#003e74;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4" />
|
||||
<stop
|
||||
style="stop-color:#2ea8ff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient1"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#3579ff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2" />
|
||||
<stop
|
||||
style="stop-color:#0b00ff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch37"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop37" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch28"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#252525;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop28" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch27"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop27" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch15"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop16" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient14"
|
||||
inkscape:swatch="gradient">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop14" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop15" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch9"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop10" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch8"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop9" />
|
||||
</linearGradient>
|
||||
<rect
|
||||
x="22.627417"
|
||||
y="402.76802"
|
||||
width="521.34025"
|
||||
height="248.94868"
|
||||
id="rect24" />
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath18">
|
||||
<circle
|
||||
style="opacity:1;mix-blend-mode:normal;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.8382;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
||||
id="circle18"
|
||||
cx="-246.8315"
|
||||
cy="246.8338"
|
||||
inkscape:label="Circle"
|
||||
r="191.89999" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath22">
|
||||
<circle
|
||||
style="opacity:1;mix-blend-mode:normal;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.8382;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
||||
id="circle22"
|
||||
cx="256"
|
||||
cy="256"
|
||||
inkscape:label="Circle"
|
||||
r="191.89999" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath128">
|
||||
<circle
|
||||
style="fill:none;fill-opacity:1;stroke:#03ffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle128"
|
||||
cx="256"
|
||||
cy="256"
|
||||
r="192" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1"
|
||||
id="linearGradient3"
|
||||
x1="256"
|
||||
y1="64"
|
||||
x2="256"
|
||||
y2="448"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1874952,0,0,-1.1874952,-47.370662,560.66391)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5"
|
||||
id="linearGradient4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-1.1874952,0,0,1.1874952,560.61528,-47.345282)"
|
||||
x1="256"
|
||||
y1="64"
|
||||
x2="256"
|
||||
y2="448" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="262.69017"
|
||||
inkscape:cy="76.367532"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="849"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg7" />
|
||||
<circle
|
||||
style="opacity:1;mix-blend-mode:screen;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:15.907;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path1"
|
||||
cx="256.61652"
|
||||
cy="257.31778"
|
||||
r="227.33479" />
|
||||
<path
|
||||
id="path8-7"
|
||||
style="display:inline;mix-blend-mode:multiply;fill:url(#linearGradient3);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
||||
inkscape:label="Circle"
|
||||
d="m 256.62812,484.66422 a 227.99908,228.00372 0 0 1 -94.5288,-20.52182 c 17.54241,-0.96226 34.77843,-4.71825 46.2868,-10.46733 12.69502,-6.3416 25.70492,-17.24174 35.38366,-26.3736 h 36.45053 c 0.93211,0.61234 1.88758,1.23061 2.86668,1.85086 4.89722,14.18571 13.27668,38.80747 17.49933,51.23264 a 227.99908,228.00372 0 0 1 -43.9582,4.27925 z m 55.26491,-6.80041 -16.39068,-41.47736 c 6.99845,3.71973 14.6813,7.07649 22.62503,9.76921 20.75463,7.03513 39.46594,9.14022 49.31353,9.76688 a 227.99908,228.00372 0 0 1 -55.54788,21.94127 z m 58.6952,-23.72487 c -8.69086,-4.31956 -29.66977,-14.9556 -49.97917,-26.83747 h 87.23219 a 227.99908,228.00372 0 0 1 -37.25302,26.83747 z m -241.49988,-8.48659 a 227.99908,228.00372 0 0 1 -23.67337,-18.35088 h 95.80906 c -1.32304,0.72101 -2.11058,1.13186 -2.11058,1.13186 l 9.37935,10.63433 -34.47214,-6.30174 c 0,-2e-5 -10.96427,4.13624 -36.05858,11.02861 -3.09966,0.85131 -6.06162,1.45425 -8.87374,1.85782 z M 96.054184,418.52496 A 227.99908,228.00372 0 0 1 64.743277,379.80069 h 53.833883 c 16.2593,10.82121 36.03109,20.56336 55.93056,22.04797 47.50893,3.54468 62.979,-1.67459 62.979,-1.67459 0,0 -4.13964,4.3321 -13.0323,12.01204 -2.4447,2.11135 -5.46123,4.28998 -8.54904,6.33885 z m 156.603246,0 c 4.10483,-4.24043 6.54978,-7.04162 6.54978,-7.04162 0,0 3.17296,2.8621 8.63949,7.04162 z m 54.10293,0 c -19.35695,-13.88741 -22.86161,-25.14433 -22.86161,-25.14433 0,0 49.2172,17.2685 90.39112,0.28064 10.4477,-4.31055 19.37408,-9.1049 26.88099,-13.86058 h 47.3421 a 227.99908,228.00372 0 0 1 -31.31091,38.72427 z M 59.385631,371.02418 A 227.99908,228.00372 0 0 1 41.543041,332.29992 H 159.20017 c 1.30773,2.3199 2.75142,4.57103 4.34409,6.73083 12.77878,17.32895 25.06121,26.96783 33.0852,31.99343 h -27.15468 c -5.2719,-0.84 -10.81534,-1.78919 -16.40924,-2.84819 -27.04349,-5.11994 -72.845405,-20.48007 -72.845405,-20.48007 0,0 10.296355,11.13669 26.131855,23.32826 z m 238.424449,0 c 30.05703,-10.10404 47.05829,-24.07021 56.34572,-38.72426 h 117.55739 a 227.99908,228.00372 0 0 1 -17.84258,38.72426 h -40.22176 c 13.33114,-10.41219 19.38725,-18.85882 19.38725,-18.85882 0,0 -30.08919,11.11726 -59.29823,18.85882 z m -41.2585,-14.62133 c -0.90134,-0.01 -9.08983,-0.64727 -40.38179,-18.55498 -2.80164,-1.60327 -5.61377,-3.47048 -8.41452,-5.54795 h 37.53597 c 6.43727,15.58979 11.34615,24.10293 11.34615,24.10293 0,0 -0.0258,6.4e-4 -0.0858,0 z m 12.72847,-0.0418 c 0,0 -2.97304,-8.3824 -6.55675,-24.06118 h 46.48163 c -24.16151,23.08045 -39.92488,24.06123 -39.92488,24.06123 z M 38.653164,323.52341 a 227.99908,228.00372 0 0 1 -8.28,-38.72426 H 147.25331 c 0.50409,11.4347 2.40394,25.61361 7.73264,38.72426 z m 158.567726,0 c -12.80955,-11.77756 -24.77977,-26.58932 -33.71374,-38.72426 h 65.85729 c 4.01234,15.08912 8.39298,28.09557 12.44549,38.72426 z m 63.60057,0 c -2.16662,-10.57203 -4.40101,-23.55135 -6.23667,-38.72426 h 95.8253 c -7.46906,9.7857 -18.55287,23.51811 -32.62829,38.72426 z m 97.99155,0 c 5.95644,-13.69644 6.2152,-27.44278 5.00743,-38.72426 h 119.06262 a 227.99908,228.00372 0 0 1 -8.28,38.72426 z M 29.452392,276.02264 A 227.99908,228.00372 0 0 1 28.62903,256.6605 227.99908,228.00372 0 0 1 29.452392,237.29836 H 219.64878 c 2.02639,13.95226 4.61647,26.90106 7.48446,38.72428 H 157.2241 c -5.80191,-8.33616 -9.27267,-13.98815 -9.27267,-13.98815 0,0 -0.7416,5.5263 -0.8396,13.98815 z m 224.144368,0 c -1.22897,-11.76966 -2.19512,-24.70616 -2.7113,-38.72428 h 232.91837 a 227.99908,228.00372 0 0 1 0.82337,19.36214 227.99908,228.00372 0 0 1 -0.82337,19.36214 H 362.56568 c -0.39943,-2.2888 -0.8157,-4.40137 -1.19214,-6.30638 0,0 -1.52342,2.281 -4.43454,6.30638 z M 30.373164,228.52186 a 227.99908,228.00372 0 0 1 8.28,-38.72427 H 218.96921 c -1.16001,13.8461 -1.41371,26.99937 -0.37573,38.72427 z m 220.252536,0 c -0.27246,-12.17105 -0.19776,-25.09608 0.33166,-38.72427 h 223.6457 a 227.99908,228.00372 0 0 1 8.28,38.72427 z M 41.540725,181.02109 a 227.99908,228.00372 0 0 1 17.84259,-38.72427 H 225.63264 c -2.42151,12.98777 -4.45297,26.07281 -5.81919,38.72427 z m 209.892105,0 c 1.03997,-13.90922 3.42234,-26.81596 6.74692,-38.72427 h 195.69317 a 227.99908,228.00372 0 0 1 17.84258,38.72427 z M 64.740961,133.52032 A 227.99908,228.00372 0 0 1 96.051856,94.796041 H 236.06961 c -3.05987,12.287259 -6.07477,25.390049 -8.74155,38.724279 z m 196.112969,0 c 4.80192,-14.52175 10.96848,-27.42708 17.67095,-38.724279 h 138.6795 a 227.99908,228.00372 0 0 1 31.3109,38.724279 z M 105.41267,86.019537 A 227.99908,228.00372 0 0 1 254.61726,28.666053 c -3.30134,10.858112 -9.7429,31.901037 -16.31878,57.353484 z m 178.62756,0 C 299.82749,62.260898 317.24402,46.83239 326.52798,39.636692 a 227.99908,228.00372 0 0 1 81.31559,46.382845 z"
|
||||
sodipodi:insensitive="true" />
|
||||
<path
|
||||
id="path8-7-2"
|
||||
style="display:inline;mix-blend-mode:multiply;fill:url(#linearGradient4);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
||||
inkscape:label="Circle"
|
||||
d="m 256.61651,28.654412 a 227.99908,228.00372 0 0 1 94.5288,20.521817 C 333.6029,50.138492 316.36688,53.89448 304.85851,59.64356 292.1635,65.985164 279.15359,76.8853 269.47486,86.017162 h -36.45054 c -0.93211,-0.612343 -1.88758,-1.230613 -2.86668,-1.850865 -4.89722,-14.18571 -13.27667,-38.807461 -17.49932,-51.232639 a 227.99908,228.00372 0 0 1 43.95819,-4.279246 z m -55.26491,6.800405 16.39068,41.477366 c -6.99844,-3.719734 -14.6813,-7.076497 -22.62503,-9.769213 -20.75463,-7.035126 -39.46594,-9.140222 -49.31352,-9.766875 A 227.99908,228.00372 0 0 1 201.3516,35.454817 Z m -58.6952,23.724872 c 8.69086,4.319561 29.66977,14.955598 49.97917,26.837473 H 105.40338 A 227.99908,228.00372 0 0 1 142.6564,59.179689 Z m 241.49988,8.486589 a 227.99908,228.00372 0 0 1 23.67337,18.350884 h -95.80906 c 1.32305,-0.721011 2.11058,-1.131861 2.11058,-1.131861 l -9.37935,-10.634328 34.47215,6.30174 c 0,1.2e-5 10.96426,-4.136248 36.05857,-11.028611 3.09966,-0.851315 6.06162,-1.454254 8.87374,-1.857824 z m 33.03417,27.127388 a 227.99908,228.00372 0 0 1 31.31091,38.724274 h -53.83388 c -16.25931,-10.82121 -36.0311,-20.56336 -55.93057,-22.04797 -47.50892,-3.54468 -62.97899,1.67459 -62.97899,1.67459 0,0 4.13963,-4.3321 13.03229,-12.01204 2.4447,-2.111347 5.46123,-4.289985 8.54904,-6.338854 z m -156.60325,0 c -4.10482,4.240439 -6.54978,7.041624 -6.54978,7.041624 0,0 -3.17295,-2.862104 -8.63949,-7.041624 z m -54.10293,0 c 19.35695,13.887414 22.86161,25.144334 22.86161,25.144334 0,0 -49.2172,-17.2685 -90.39112,-0.28064 -10.4477,4.31055 -19.37408,9.1049 -26.88099,13.86058 H 64.73166 A 227.99908,228.00372 0 0 1 96.042582,94.793666 Z m 247.37474,47.500784 a 227.99908,228.00372 0 0 1 17.84257,38.72426 H 354.04446 c -1.30773,-2.3199 -2.75142,-4.57103 -4.34409,-6.73083 -12.77878,-17.32895 -25.06121,-26.96783 -33.0852,-31.99343 h 27.15468 c 5.2719,0.84 10.81534,1.78919 16.40924,2.84819 27.04349,5.11994 72.84541,20.48007 72.84541,20.48007 0,0 -10.29636,-11.13669 -26.13186,-23.32826 z m -238.42446,0 c -30.05702,10.10404 -47.05829,24.07021 -56.34572,38.72426 H 41.531435 a 227.99908,228.00372 0 0 1 17.842579,-38.72426 h 40.221767 c -13.331141,10.41219 -19.387248,18.85882 -19.387248,18.85882 0,0 30.089197,-11.11726 59.298227,-18.85882 z m 41.2585,14.62133 c 0.90134,0.009 9.08984,0.64727 40.38179,18.55498 2.80164,1.60327 5.61377,3.47048 8.41452,5.54795 h -37.53597 c -6.43727,-15.58979 -11.34615,-24.10293 -11.34615,-24.10293 0,0 0.0258,-6.4e-4 0.0859,0 z m -12.72847,0.0418 c 0,0 2.97304,8.3824 6.55675,24.06118 H 204.0397 c 24.16152,-23.08045 39.92488,-24.06123 39.92488,-24.06123 z m 230.62688,32.83764 a 227.99908,228.00372 0 0 1 8.28,38.72426 H 365.99132 c -0.50409,-11.4347 -2.40394,-25.61361 -7.73264,-38.72426 z m -158.56772,0 c 12.80955,11.77756 24.77977,26.58932 33.71374,38.72426 h -65.85729 c -4.01234,-15.08912 -8.39298,-28.09557 -12.44549,-38.72426 z m -63.60057,0 c 2.16662,10.57203 4.40101,23.55135 6.23667,38.72426 h -95.8253 c 7.46906,-9.7857 18.55287,-23.51811 32.62829,-38.72426 z m -97.99154,0 c -5.95644,13.69644 -6.21521,27.44278 -5.00743,38.72426 H 30.361558 a 227.99908,228.00372 0 0 1 8.280001,-38.72426 z m 329.3606,47.50077 a 227.99908,228.00372 0 0 1 0.82336,19.36214 227.99908,228.00372 0 0 1 -0.82336,19.36214 H 293.59585 c -2.02639,-13.95226 -4.61647,-26.90106 -7.48446,-38.72428 h 69.90914 c 5.80191,8.33616 9.27267,13.98815 9.27267,13.98815 0,0 0.74161,-5.5263 0.8396,-13.98815 z m -224.14436,0 c 1.22897,11.76966 2.19512,24.70616 2.7113,38.72428 H 29.440786 a 227.99908,228.00372 0 0 1 -0.823361,-19.36214 227.99908,228.00372 0 0 1 0.823361,-19.36214 H 150.67895 c 0.39943,2.2888 0.8157,4.40137 1.19214,6.30638 0,0 1.52343,-2.281 4.43455,-6.30638 z m 223.22359,47.50078 a 227.99908,228.00372 0 0 1 -8.28,38.72427 H 294.27542 c 1.16002,-13.8461 1.41371,-26.99937 0.37574,-38.72427 z m -220.25252,0 c 0.27245,12.17105 0.19775,25.09608 -0.33167,38.72427 H 38.641559 a 227.99908,228.00372 0 0 1 -8.280001,-38.72427 z m 209.08496,47.50077 a 227.99908,228.00372 0 0 1 -17.84258,38.72427 H 287.61199 c 2.42151,-12.98777 4.45297,-26.07281 5.81919,-38.72427 z m -209.89209,0 c -1.03998,13.90921 -3.42235,26.81596 -6.74692,38.72427 H 59.371698 A 227.99908,228.00372 0 0 1 41.52912,332.29754 Z m 186.69187,47.50077 a 227.99908,228.00372 0 0 1 -31.3109,38.72428 H 277.17503 c 3.05986,-12.28726 6.07476,-25.39005 8.74154,-38.72428 z m -196.11297,0 c -4.80193,14.52175 -10.96849,27.42708 -17.67095,38.72428 H 96.040255 A 227.99908,228.00372 0 0 1 64.729344,379.79831 Z m 155.44125,47.50078 a 227.99908,228.00372 0 0 1 -149.20459,57.35348 c 3.30135,-10.85811 9.7429,-31.90104 16.31879,-57.35348 z m -178.62756,0 c -15.78726,23.75863 -33.20379,39.18714 -42.48775,46.38284 a 227.99908,228.00372 0 0 1 -81.31558,-46.38284 z"
|
||||
sodipodi:insensitive="true" />
|
||||
<ellipse
|
||||
style="fill:none;fill-opacity:0.679924;stroke:#97f0e5;stroke-width:17.5749;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path192"
|
||||
cx="88.20919"
|
||||
cy="216.80666"
|
||||
rx="43.306744"
|
||||
ry="42.75507" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:0.679924;stroke:#97f0e5;stroke-width:17.5749;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 211.35225,346.71976 151.38374,303.96994 137.1338,384.12586 Z"
|
||||
id="path195" />
|
||||
<path
|
||||
id="path196-7"
|
||||
style="fill:none;fill-opacity:0.679924;stroke:#97f0e5;stroke-width:17.5749;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 309.50171,362.30735 86.0678,57.93833 m -75.48269,11.93227 57.93833,-86.0678" />
|
||||
<rect
|
||||
style="fill:none;fill-opacity:0.679924;stroke:#97f0e5;stroke-width:13.9781;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect197"
|
||||
width="66.112526"
|
||||
height="59.501274"
|
||||
x="93.831078"
|
||||
y="-503.61469"
|
||||
transform="rotate(108)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 16 KiB |
Vendored
+685
-840
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+605
-759
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+605
-759
File diff suppressed because it is too large
Load Diff
Vendored
+608
-762
File diff suppressed because it is too large
Load Diff
Vendored
+605
-759
File diff suppressed because it is too large
Load Diff
Vendored
+605
-759
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+610
-762
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
+606
-761
File diff suppressed because it is too large
Load Diff
Vendored
+606
-760
File diff suppressed because it is too large
Load Diff
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
name=Anime
|
||||
description=Cel shaded look: the picture is cleaned first, then the lighting is collapsed into flat bands with inked edges, finished with a small glow.
|
||||
chain=Denoise.fx|Denoise|Strength=0.18,Radius=1.2;CelShading.fx|CelShading|Bands=5,BandContrast=0.35,BandEdge=0.2,Detail=0.7,OutlineStrength=0.7,OutlineThreshold=0.2,Saturation=1.3;Bloom.fx|Bloom|Radius=1.2,Amount=0.25
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
name=Cinematic
|
||||
description=Film look: soft glow on the highlights, a filmic contrast curve, cool shadows against warm highlights, fine grain and a gentle vignette.
|
||||
chain=Bloom.fx|Bloom|Radius=1.6,Amount=0.35;FilmicCurve.fx|FilmicCurve|Toe=1.35,Shoulder=1.3,Amount=0.85;SplitToning.fx|SplitToning|ShadowHue=210,ShadowStrength=0.25,HighlightHue=38,HighlightStrength=0.3;FilmGrain.fx|FilmGrain|Intensity=0.022;Vignette.fx|Vignette|Strength=0.5
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
name=Clean
|
||||
description=Cleans up a low internal resolution: removes dithering and compression noise, smooths banded skies and brings edge detail back. The safe starting point if you are not sure what you want.
|
||||
chain=Denoise.fx|Denoise|Strength=0.14,Curve=1.2;Deband.fx|Deband|;Sharpen.fx|Sharpen|Amount=0.75
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
name=Dreamy
|
||||
description=Soft focus: the centre of the screen stays sharp while everything around it blurs, with a wide glow over the highlights. Good for slower games and cutscenes.
|
||||
chain=Blur.fx|Blur|Radius=6,Strength=0.85,FocusSize=0.28,FocusSoftness=0.5;Bloom.fx|Bloom|Radius=2.0,Amount=0.55
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
name=Retro
|
||||
description=Old television look: colour fringing at the edges of the screen, curved scanlines with a phosphor mask, and darkened corners. The scanline roll is switched off so it does not crawl.
|
||||
chain=ChromaticAberration.fx|ChromaticAberration|Strength=1.0;CRT.fx|CRT|RollSpeed=0,Bleed=1.2;Vignette.fx|Vignette|Strength=0.7
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
name=Vivid
|
||||
description=Punchier colour without stylising the image: warmer and more saturated, blacks and whites pushed to the ends of the range, and a light sharpen.
|
||||
chain=NaturalColors.fx|NaturalColors|Luma=1.15,Chroma=1.35;Levels.fx|Levels|InputBlack=0.02,InputWhite=0.98;Sharpen.fx|Sharpen|Amount=0.5
|
||||
Vendored
-70
@@ -1,70 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// Ported from bloomnoblur.fsh in PPSSPP.
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Radius <
|
||||
ui_type = "slider";
|
||||
ui_label = "Radius";
|
||||
ui_tooltip = "How far the glow spreads from bright areas.";
|
||||
ui_min = 0.0; ui_max = 4.0; ui_step = 0.05;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Amount <
|
||||
ui_type = "slider";
|
||||
ui_label = "Amount";
|
||||
ui_tooltip = "Strength of the glow added on top of the image.";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
||||
> = 0.6;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float Weight(float3 color)
|
||||
{
|
||||
float gray = (color.r + color.g + color.b) / 3.0;
|
||||
float saturation = (abs(color.r - gray) + abs(color.g - gray) + abs(color.b - gray)) / 3.0;
|
||||
return gray * gray / max(saturation, 0.25);
|
||||
}
|
||||
|
||||
float4 PS_Bloom(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float3 color = tex2D(BackBuffer, uv).rgb;
|
||||
|
||||
float gray = (color.r + color.g + color.b) / 3.0;
|
||||
float saturation = (abs(color.r - gray) + abs(color.g - gray) + abs(color.b - gray)) / 3.0;
|
||||
float spread = 0.002 * gray / max(saturation, 0.25) * Radius;
|
||||
|
||||
float3 sum = float3(0.0, 0.0, 0.0);
|
||||
[unroll] for (int x = -3; x <= 3; x += 2)
|
||||
{
|
||||
[unroll] for (int y = -3; y <= 3; y += 2)
|
||||
{
|
||||
float3 tap = tex2D(BackBuffer, uv + float2(x, y) * spread).rgb;
|
||||
sum += tap * Weight(tap);
|
||||
}
|
||||
}
|
||||
sum /= 16.0;
|
||||
|
||||
return float4(saturate(color + sum * Amount), 1.0);
|
||||
}
|
||||
|
||||
technique Bloom <
|
||||
ui_label = "Bloom";
|
||||
ui_tooltip = "Bleeds light out of the brightest areas into a soft halo, the way a camera does when pointed at something too bright.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Bloom;
|
||||
}
|
||||
}
|
||||
Vendored
-87
@@ -1,87 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Radius <
|
||||
ui_type = "slider";
|
||||
ui_label = "Radius";
|
||||
ui_tooltip = "How far the blur reaches, in pixels.";
|
||||
ui_min = 1.0; ui_max = 12.0; ui_step = 0.5;
|
||||
> = 4.0;
|
||||
|
||||
uniform float Strength <
|
||||
ui_type = "slider";
|
||||
ui_label = "Strength";
|
||||
ui_tooltip = "Blend between the original image and the blurred one.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 1.0;
|
||||
|
||||
uniform float FocusSize <
|
||||
ui_type = "slider";
|
||||
ui_label = "Sharp Centre";
|
||||
ui_tooltip = "Size of the region left in focus at the centre of the screen. At zero the whole image is blurred evenly.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.0;
|
||||
|
||||
uniform float FocusSoftness <
|
||||
ui_type = "slider";
|
||||
ui_label = "Focus Falloff";
|
||||
ui_tooltip = "How gradually the sharp centre gives way to the blur.";
|
||||
ui_min = 0.05; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.4;
|
||||
|
||||
static const int TAPS = 17;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_Blur(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
||||
float3 original = tex2D(BackBuffer, uv).rgb;
|
||||
|
||||
float2 centred = (uv - 0.5) * float2(BUFFER_WIDTH * BUFFER_RCP_HEIGHT, 1.0) * 2.0;
|
||||
float distance_from_centre = length(centred);
|
||||
float no_focus = 1.0 - step(0.001, FocusSize);
|
||||
float focus = max(smoothstep(FocusSize, FocusSize + FocusSoftness, distance_from_centre), no_focus);
|
||||
float amount = Strength * focus;
|
||||
|
||||
float angle = frac(sin(dot(pos.xy, float2(12.9898, 78.233))) * 43758.5453) * 6.2831853;
|
||||
float2 spoke = float2(cos(angle), sin(angle));
|
||||
|
||||
const float2 turn = float2(cos(2.39996323), sin(2.39996323));
|
||||
const float decay = exp(-2.0 / float(TAPS));
|
||||
float weight = exp(-1.0 / float(TAPS));
|
||||
|
||||
float3 sum = float3(0.0, 0.0, 0.0);
|
||||
float total = 0.0;
|
||||
[unroll] for (int i = 0; i < TAPS; ++i)
|
||||
{
|
||||
float reach = sqrt((float(i) + 0.5) / float(TAPS));
|
||||
sum += tex2D(BackBuffer, uv + spoke * reach * texel * Radius).rgb * weight;
|
||||
total += weight;
|
||||
weight *= decay;
|
||||
spoke = float2(spoke.x * turn.x - spoke.y * turn.y,
|
||||
spoke.x * turn.y + spoke.y * turn.x);
|
||||
}
|
||||
|
||||
float3 blurred = sum / total;
|
||||
return float4(lerp(original, blurred, amount), 1.0);
|
||||
}
|
||||
|
||||
technique Blur <
|
||||
ui_label = "Blur";
|
||||
ui_tooltip = "Gaussian blur with an optional sharp centre, for softening the picture or faking depth of field.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Blur;
|
||||
}
|
||||
}
|
||||
Vendored
-74
@@ -1,74 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// Ported from crt.fsh in PPSSPP, by KillaMaaki.
|
||||
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Timer < source = "timer"; > = 0.0;
|
||||
|
||||
uniform float Density <
|
||||
ui_type = "slider";
|
||||
ui_label = "Line Density";
|
||||
ui_min = 60.0; ui_max = 720.0; ui_step = 10.0;
|
||||
> = 272.0;
|
||||
|
||||
uniform float RollSpeed <
|
||||
ui_type = "slider";
|
||||
ui_label = "Roll Speed";
|
||||
ui_tooltip = "Speed of the rolling bar. Zero disables it.";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Bleed <
|
||||
ui_type = "slider";
|
||||
ui_label = "Colour Bleed";
|
||||
ui_tooltip = "Horizontal separation of the red and green channels.";
|
||||
ui_min = 0.0; ui_max = 4.0; ui_step = 0.1;
|
||||
> = 1.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_CRT(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float seconds = Timer * 0.001;
|
||||
float scan = floor((uv.y + seconds * RollSpeed * 0.5) * Density);
|
||||
float line_intensity = frac(scan * 0.5) * 2.0;
|
||||
|
||||
float2 shift = float2(line_intensity * 0.0005, 0.0);
|
||||
float2 bleed = float2(BUFFER_RCP_WIDTH * Bleed, 0.0);
|
||||
|
||||
float r = tex2D(BackBuffer, uv + bleed + shift).r;
|
||||
float g = tex2D(BackBuffer, uv - bleed + shift).g;
|
||||
float b = tex2D(BackBuffer, uv).b;
|
||||
|
||||
float3 color = float3(r, g * 0.99, b) * clamp(line_intensity, 0.85, 1.0);
|
||||
|
||||
if (RollSpeed > 0.0)
|
||||
{
|
||||
float rollbar = sin((uv.y + seconds * RollSpeed) * 4.0);
|
||||
color += rollbar * 0.02;
|
||||
}
|
||||
|
||||
return float4(saturate(color), 1.0);
|
||||
}
|
||||
|
||||
technique CRT <
|
||||
ui_label = "CRT";
|
||||
ui_tooltip = "Curved scanlines and the phosphor mask of a CRT television, for games that were drawn with that kind of screen in mind.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_CRT;
|
||||
}
|
||||
}
|
||||
Vendored
-79
@@ -1,79 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
||||
// SPDX-FileCopyrightText: guest(r)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// Ported from cartoon.fsh in PPSSPP, Advanced Cartoon shader I by guest(r).
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float EdgeStrength <
|
||||
ui_type = "slider";
|
||||
ui_label = "Edge Strength";
|
||||
ui_tooltip = "Darkness of the ink outline drawn around detected edges.";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
||||
> = 0.5;
|
||||
|
||||
uniform float Levels <
|
||||
ui_type = "slider";
|
||||
ui_label = "Colour Levels";
|
||||
ui_tooltip = "How many bands the colours are quantised into.";
|
||||
ui_min = 2.0; ui_max = 16.0; ui_step = 1.0;
|
||||
> = 4.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_Cartoon(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
||||
|
||||
float3 c00 = tex2D(BackBuffer, uv + texel * float2(-1.0, -1.0)).rgb;
|
||||
float3 c10 = tex2D(BackBuffer, uv + texel * float2( 0.0, -1.0)).rgb;
|
||||
float3 c20 = tex2D(BackBuffer, uv + texel * float2( 1.0, -1.0)).rgb;
|
||||
float3 c01 = tex2D(BackBuffer, uv + texel * float2(-1.0, 0.0)).rgb;
|
||||
float3 c11 = tex2D(BackBuffer, uv).rgb;
|
||||
float3 c21 = tex2D(BackBuffer, uv + texel * float2( 1.0, 0.0)).rgb;
|
||||
float3 c02 = tex2D(BackBuffer, uv + texel * float2(-1.0, 1.0)).rgb;
|
||||
float3 c12 = tex2D(BackBuffer, uv + texel * float2( 0.0, 1.0)).rgb;
|
||||
float3 c22 = tex2D(BackBuffer, uv + texel * float2( 1.0, 1.0)).rgb;
|
||||
|
||||
const float3 dt = float3(1.0, 1.0, 1.0);
|
||||
|
||||
float d1 = dot(abs(c00 - c22), dt);
|
||||
float d2 = dot(abs(c20 - c02), dt);
|
||||
float hl = dot(abs(c01 - c21), dt);
|
||||
float vl = dot(abs(c10 - c12), dt);
|
||||
float edge = EdgeStrength * (d1 + d2 + hl + vl) / (dot(c11, dt) + 0.15);
|
||||
|
||||
float lc = Levels * length(c11);
|
||||
float f = frac(lc);
|
||||
f *= f;
|
||||
lc = (floor(lc) + f * f) / Levels + 0.05;
|
||||
|
||||
float3 unit = normalize(max(c11, 0.0001));
|
||||
float3 quant = Levels * unit;
|
||||
float3 frct = frac(quant);
|
||||
frct *= frct;
|
||||
quant = floor(quant) + 0.05 * dt + frct * frct;
|
||||
|
||||
float3 color = lc * (1.1 - edge * sqrt(edge)) * quant / Levels;
|
||||
return float4(saturate(color), 1.0);
|
||||
}
|
||||
|
||||
technique Cartoon <
|
||||
ui_label = "Cartoon";
|
||||
ui_tooltip = "Ink outlines and flat colour bands. Faithful port of the PPSSPP shader; the outline gets heavy in dark scenes, so try Cartoon Soft or Cel Shading if the blacks smear.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Cartoon;
|
||||
}
|
||||
}
|
||||
Vendored
-100
@@ -1,100 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
||||
// SPDX-FileCopyrightText: guest(r)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float EdgeStrength <
|
||||
ui_type = "slider";
|
||||
ui_label = "Edge Strength";
|
||||
ui_tooltip = "Darkness of the ink outline drawn around detected edges.";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
||||
> = 0.45;
|
||||
|
||||
uniform float ShadowGuard <
|
||||
ui_type = "slider";
|
||||
ui_label = "Shadow Guard";
|
||||
ui_tooltip = "Holds the outline back in dark areas. Raise it if shadows turn into black blobs.";
|
||||
ui_min = 0.1; ui_max = 2.0; ui_step = 0.05;
|
||||
> = 0.8;
|
||||
|
||||
uniform float Levels <
|
||||
ui_type = "slider";
|
||||
ui_label = "Colour Levels";
|
||||
ui_tooltip = "How many bands the colours are quantised into.";
|
||||
ui_min = 2.0; ui_max = 16.0; ui_step = 1.0;
|
||||
> = 6.0;
|
||||
|
||||
uniform float Smoothing <
|
||||
ui_type = "slider";
|
||||
ui_label = "Banding";
|
||||
ui_tooltip = "How far the picture is pushed towards flat bands.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.75;
|
||||
|
||||
uniform float Saturation <
|
||||
ui_type = "slider";
|
||||
ui_label = "Saturation";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
||||
> = 1.15;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_CartoonSoft(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
||||
|
||||
float3 c00 = tex2D(BackBuffer, uv + texel * float2(-1.0, -1.0)).rgb;
|
||||
float3 c10 = tex2D(BackBuffer, uv + texel * float2( 0.0, -1.0)).rgb;
|
||||
float3 c20 = tex2D(BackBuffer, uv + texel * float2( 1.0, -1.0)).rgb;
|
||||
float3 c01 = tex2D(BackBuffer, uv + texel * float2(-1.0, 0.0)).rgb;
|
||||
float3 c11 = tex2D(BackBuffer, uv).rgb;
|
||||
float3 c21 = tex2D(BackBuffer, uv + texel * float2( 1.0, 0.0)).rgb;
|
||||
float3 c02 = tex2D(BackBuffer, uv + texel * float2(-1.0, 1.0)).rgb;
|
||||
float3 c12 = tex2D(BackBuffer, uv + texel * float2( 0.0, 1.0)).rgb;
|
||||
float3 c22 = tex2D(BackBuffer, uv + texel * float2( 1.0, 1.0)).rgb;
|
||||
|
||||
const float3 dt = float3(1.0, 1.0, 1.0);
|
||||
const float3 luma_weights = float3(0.299, 0.587, 0.114);
|
||||
|
||||
float d1 = dot(abs(c00 - c22), dt);
|
||||
float d2 = dot(abs(c20 - c02), dt);
|
||||
float hl = dot(abs(c01 - c21), dt);
|
||||
float vl = dot(abs(c10 - c12), dt);
|
||||
|
||||
float luma = dot(c11, luma_weights);
|
||||
float response = (d1 + d2 + hl + vl) / (luma * 2.0 + ShadowGuard);
|
||||
float ink = 1.0 - saturate(response * EdgeStrength);
|
||||
|
||||
float scaled = luma * Levels;
|
||||
float step_position = frac(scaled);
|
||||
float eased = step_position * step_position * (3.0 - 2.0 * step_position);
|
||||
float banded = (floor(scaled) + eased) / Levels;
|
||||
float target = lerp(luma, banded, Smoothing);
|
||||
|
||||
float3 tinted = c11 * (target / max(luma, 0.001));
|
||||
float3 grey = dot(tinted, luma_weights);
|
||||
float3 color = lerp(grey, tinted, Saturation) * ink;
|
||||
|
||||
return float4(saturate(color), 1.0);
|
||||
}
|
||||
|
||||
technique CartoonSoft <
|
||||
ui_label = "Cartoon Soft";
|
||||
ui_tooltip = "Ink outlines and flat colour bands, with the outline held back in the shadows so dark scenes do not turn into black blobs.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_CartoonSoft;
|
||||
}
|
||||
}
|
||||
Vendored
-120
@@ -1,120 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Bands <
|
||||
ui_type = "slider";
|
||||
ui_label = "Shading Bands";
|
||||
ui_tooltip = "How many flat steps the lighting is collapsed into. Three or four gives the classic look.";
|
||||
ui_min = 2.0; ui_max = 8.0; ui_step = 1.0;
|
||||
> = 4.0;
|
||||
|
||||
uniform float BandContrast <
|
||||
ui_type = "slider";
|
||||
ui_label = "Band Contrast";
|
||||
ui_tooltip = "Spreads the bands towards pure black and white. Lower it if the shadows crush.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.5;
|
||||
|
||||
uniform float BandEdge <
|
||||
ui_type = "slider";
|
||||
ui_label = "Band Edge";
|
||||
ui_tooltip = "Width of the transition between bands. Low values give hard cel steps.";
|
||||
ui_min = 0.02; ui_max = 1.0; ui_step = 0.02;
|
||||
> = 0.15;
|
||||
|
||||
uniform float Detail <
|
||||
ui_type = "slider";
|
||||
ui_label = "Texture Detail";
|
||||
ui_tooltip = "How much surface texture survives the flattening. At zero the bands are completely flat.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.6;
|
||||
|
||||
uniform float OutlineStrength <
|
||||
ui_type = "slider";
|
||||
ui_label = "Outline Strength";
|
||||
ui_tooltip = "Opacity of the ink line drawn along detected edges.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.8;
|
||||
|
||||
uniform float OutlineThreshold <
|
||||
ui_type = "slider";
|
||||
ui_label = "Outline Threshold";
|
||||
ui_tooltip = "How strong an edge has to be before it is inked. Raise it to keep ink off textures and specular highlights.";
|
||||
ui_min = 0.01; ui_max = 0.4; ui_step = 0.01;
|
||||
> = 0.18;
|
||||
|
||||
uniform float Saturation <
|
||||
ui_type = "slider";
|
||||
ui_label = "Saturation";
|
||||
ui_tooltip = "Colour intensity of the flat regions.";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
||||
> = 1.25;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_CelShading(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
const float3 luma_weights = float3(0.2126, 0.7152, 0.0722);
|
||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
||||
|
||||
float3 centre = tex2D(BackBuffer, uv).rgb;
|
||||
float luma = dot(centre, luma_weights);
|
||||
|
||||
float2 near = texel * 1.5;
|
||||
float2 far = texel * 3.5;
|
||||
|
||||
float a00 = dot(tex2D(BackBuffer, uv + near * float2(-1.0, -1.0)).rgb, luma_weights);
|
||||
float a20 = dot(tex2D(BackBuffer, uv + near * float2( 1.0, -1.0)).rgb, luma_weights);
|
||||
float a02 = dot(tex2D(BackBuffer, uv + near * float2(-1.0, 1.0)).rgb, luma_weights);
|
||||
float a22 = dot(tex2D(BackBuffer, uv + near * float2( 1.0, 1.0)).rgb, luma_weights);
|
||||
|
||||
float b00 = dot(tex2D(BackBuffer, uv + far * float2(-1.0, -1.0)).rgb, luma_weights);
|
||||
float b20 = dot(tex2D(BackBuffer, uv + far * float2( 1.0, -1.0)).rgb, luma_weights);
|
||||
float b02 = dot(tex2D(BackBuffer, uv + far * float2(-1.0, 1.0)).rgb, luma_weights);
|
||||
float b22 = dot(tex2D(BackBuffer, uv + far * float2( 1.0, 1.0)).rgb, luma_weights);
|
||||
|
||||
float gx = (a00 + a02) - (a20 + a22);
|
||||
float gy = (a00 + a20) - (a02 + a22);
|
||||
float gradient = sqrt(gx * gx + gy * gy);
|
||||
float ink = smoothstep(OutlineThreshold, OutlineThreshold + 0.04, gradient);
|
||||
|
||||
float lighting = (a00 + a20 + a02 + a22 + b00 + b20 + b02 + b22) * 0.125;
|
||||
float detail = luma - lighting;
|
||||
|
||||
float softness = max(BandEdge, 0.001);
|
||||
float coord = lighting * Bands - softness * 0.5;
|
||||
float index = floor(coord) + smoothstep(1.0 - softness, 1.0, frac(coord));
|
||||
|
||||
float centred = (index + 0.5) / Bands;
|
||||
float stretched = index / max(Bands - 1.0, 1.0);
|
||||
float banded = saturate(lerp(centred, stretched, BandContrast));
|
||||
|
||||
float target = saturate(banded + detail * Detail);
|
||||
|
||||
float gain = min(target / max(luma, 0.001), 4.0);
|
||||
float3 shaded = centre * gain;
|
||||
float3 grey = dot(shaded, luma_weights);
|
||||
float3 color = lerp(grey, shaded, Saturation);
|
||||
color *= 1.0 - ink * OutlineStrength;
|
||||
|
||||
return float4(saturate(color), 1.0);
|
||||
}
|
||||
|
||||
technique CelShading <
|
||||
ui_label = "Cel Shading";
|
||||
ui_tooltip = "Collapses the lighting into a few hard steps and inks the edges, keeping texture detail and hue intact.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_CelShading;
|
||||
}
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Strength <
|
||||
ui_type = "slider";
|
||||
ui_label = "Strength";
|
||||
ui_tooltip = "Channel separation in pixels, measured at the edge of the screen.";
|
||||
ui_min = 0.0; ui_max = 8.0; ui_step = 0.1;
|
||||
> = 1.5;
|
||||
|
||||
uniform float Falloff <
|
||||
ui_type = "slider";
|
||||
ui_label = "Falloff";
|
||||
ui_tooltip = "How fast the separation grows away from the centre. Higher keeps the middle clean.";
|
||||
ui_min = 1.0; ui_max = 4.0; ui_step = 0.1;
|
||||
> = 2.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_ChromaticAberration(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
||||
|
||||
float2 direction = uv - float2(0.5, 0.5);
|
||||
float radius = length(direction);
|
||||
float2 unit = direction / max(radius, 0.0001);
|
||||
float2 offset = unit * Strength * pow(radius * 2.0, Falloff) * texel;
|
||||
|
||||
float red = tex2D(BackBuffer, uv + offset).r;
|
||||
float green = tex2D(BackBuffer, uv).g;
|
||||
float blue = tex2D(BackBuffer, uv - offset).b;
|
||||
|
||||
return float4(red, green, blue, 1.0);
|
||||
}
|
||||
|
||||
technique ChromaticAberration <
|
||||
ui_label = "Chromatic Aberration";
|
||||
ui_tooltip = "Splits the colour channels apart towards the edges of the screen, the way a cheap lens fails to focus every colour on the same spot.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_ChromaticAberration;
|
||||
}
|
||||
}
|
||||
Vendored
-64
@@ -1,64 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// Based on colorcorrection.fsh in PPSSPP.
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Saturation <
|
||||
ui_type = "slider";
|
||||
ui_label = "Saturation";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Brightness <
|
||||
ui_type = "slider";
|
||||
ui_label = "Brightness";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Contrast <
|
||||
ui_type = "slider";
|
||||
ui_label = "Contrast";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Gamma <
|
||||
ui_type = "slider";
|
||||
ui_label = "Gamma";
|
||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 1.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_ColorGrade(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
||||
|
||||
float luma = dot(rgb, float3(0.2126, 0.7152, 0.0722));
|
||||
rgb = lerp(float3(luma, luma, luma), rgb, Saturation);
|
||||
rgb *= Brightness;
|
||||
rgb = (rgb - 0.5) * Contrast + 0.5;
|
||||
rgb = pow(max(rgb, 0.0), 1.0 / max(Gamma, 0.0001));
|
||||
|
||||
return float4(saturate(rgb), 1.0);
|
||||
}
|
||||
|
||||
technique ColorGrade <
|
||||
ui_label = "Colour Grade";
|
||||
ui_tooltip = "The four basic colour controls in one pass: saturation, brightness, contrast and gamma. Reach for this before anything more specialised.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_ColorGrade;
|
||||
}
|
||||
}
|
||||
Vendored
-91
@@ -1,91 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2015 Niklas Haas
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Threshold <
|
||||
ui_type = "slider";
|
||||
ui_label = "Threshold";
|
||||
ui_tooltip = "How flat a neighbourhood must be before it gets smoothed. Raise it to catch wider bands, lower it to keep more detail.";
|
||||
ui_min = 0.002; ui_max = 0.05; ui_step = 0.001;
|
||||
> = 0.012;
|
||||
|
||||
uniform float Radius <
|
||||
ui_type = "slider";
|
||||
ui_label = "Radius";
|
||||
ui_tooltip = "How far the sampling reaches, in pixels. Wider gradients need a larger radius.";
|
||||
ui_min = 1.0; ui_max = 32.0; ui_step = 1.0;
|
||||
> = 8.0;
|
||||
|
||||
uniform float Grain <
|
||||
ui_type = "slider";
|
||||
ui_label = "Dither";
|
||||
ui_tooltip = "Noise added to break up whatever banding survives the smoothing.";
|
||||
ui_min = 0.0; ui_max = 0.02; ui_step = 0.001;
|
||||
> = 0.004;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float Hash(float2 p)
|
||||
{
|
||||
float3 scattered = frac(float3(p.x, p.y, p.x) * 0.1031);
|
||||
scattered += dot(scattered, scattered.yzx + 33.33);
|
||||
return frac((scattered.x + scattered.y) * scattered.z);
|
||||
}
|
||||
|
||||
float4 PS_Deband(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
||||
|
||||
float3 centre = tex2D(BackBuffer, uv).rgb;
|
||||
float base = Hash(pos.xy) * 6.2831853;
|
||||
|
||||
float3 total = float3(0.0, 0.0, 0.0);
|
||||
float3 deviation = float3(0.0, 0.0, 0.0);
|
||||
|
||||
[unroll] for (int ring = 1; ring <= 2; ++ring)
|
||||
{
|
||||
float angle = base + float(ring) * 2.3999632;
|
||||
float reach = Radius * float(ring) * 0.5;
|
||||
float2 along = float2(cos(angle), sin(angle)) * reach;
|
||||
float2 across = float2(-along.y, along.x);
|
||||
|
||||
float3 s0 = tex2D(BackBuffer, uv + along * texel).rgb;
|
||||
float3 s1 = tex2D(BackBuffer, uv - along * texel).rgb;
|
||||
float3 s2 = tex2D(BackBuffer, uv + across * texel).rgb;
|
||||
float3 s3 = tex2D(BackBuffer, uv - across * texel).rgb;
|
||||
|
||||
total += s0 + s1 + s2 + s3;
|
||||
deviation = max(deviation, max(max(abs(s0 - centre), abs(s1 - centre)),
|
||||
max(abs(s2 - centre), abs(s3 - centre))));
|
||||
}
|
||||
|
||||
float3 average = total * 0.125;
|
||||
float3 flatness = float3(1.0, 1.0, 1.0) -
|
||||
smoothstep(Threshold * 0.5, Threshold, deviation);
|
||||
float3 result = lerp(centre, average, flatness);
|
||||
|
||||
float dither = (Hash(pos.xy + float2(71.3, 41.7)) - 0.5) * Grain;
|
||||
|
||||
return float4(saturate(result + dither), 1.0);
|
||||
}
|
||||
|
||||
technique Deband <
|
||||
ui_label = "Deband";
|
||||
ui_tooltip = "Smooths the visible steps in gradients such as skies, then dithers whatever survives. Worth adding whenever large flat areas show rings.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Deband;
|
||||
}
|
||||
}
|
||||
Vendored
-83
@@ -1,83 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019-2021 bloc97
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Strength <
|
||||
ui_type = "slider";
|
||||
ui_label = "Strength";
|
||||
ui_min = 0.01; ui_max = 0.5; ui_step = 0.01;
|
||||
> = 0.1;
|
||||
|
||||
uniform float Radius <
|
||||
ui_type = "slider";
|
||||
ui_label = "Radius";
|
||||
ui_min = 0.3; ui_max = 2.0; ui_step = 0.05;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Curve <
|
||||
ui_type = "slider";
|
||||
ui_label = "Shadow Bias";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
||||
> = 1.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float3 IntensityWeight(float3 value, float3 sigma, float3 centre)
|
||||
{
|
||||
float3 scaled = (value - centre) / sigma;
|
||||
return exp(-0.5 * scaled * scaled);
|
||||
}
|
||||
|
||||
float SpatialWeight(float distance, float sigma)
|
||||
{
|
||||
float scaled = distance / sigma;
|
||||
return exp(-0.5 * scaled * scaled);
|
||||
}
|
||||
|
||||
float4 PS_Denoise(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
||||
|
||||
float3 centre = tex2D(BackBuffer, uv).rgb;
|
||||
float3 intensity_sigma = max(pow(centre + 0.0001, Curve) * Strength, 0.0001);
|
||||
float spatial_sigma = max(Radius, 0.05);
|
||||
|
||||
float3 sum = float3(0.0, 0.0, 0.0);
|
||||
float3 total = float3(0.0, 0.0, 0.0);
|
||||
|
||||
[unroll] for (int y = -2; y <= 2; ++y)
|
||||
{
|
||||
[unroll] for (int x = -2; x <= 2; ++x)
|
||||
{
|
||||
float2 offset = float2(x, y);
|
||||
float3 tap = tex2D(BackBuffer, uv + offset * texel).rgb;
|
||||
float3 weight = IntensityWeight(tap, intensity_sigma, centre) *
|
||||
SpatialWeight(length(offset), spatial_sigma);
|
||||
sum += weight * tap;
|
||||
total += weight;
|
||||
}
|
||||
}
|
||||
|
||||
return float4(sum / total, 1.0);
|
||||
}
|
||||
|
||||
technique Denoise <
|
||||
ui_label = "Denoise";
|
||||
ui_tooltip = "Edge preserving blur that clears dithering and compression noise while leaving outlines sharp. Ported from Anime4K.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Denoise;
|
||||
}
|
||||
}
|
||||
Vendored
-65
@@ -1,65 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Intensity <
|
||||
ui_type = "slider";
|
||||
ui_label = "Intensity";
|
||||
ui_min = 0.0; ui_max = 0.2; ui_step = 0.005;
|
||||
> = 0.03;
|
||||
|
||||
uniform float Size <
|
||||
ui_type = "slider";
|
||||
ui_label = "Size";
|
||||
ui_tooltip = "Grain cell size in pixels.";
|
||||
ui_min = 1.0; ui_max = 4.0; ui_step = 1.0;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Colored <
|
||||
ui_type = "slider";
|
||||
ui_label = "Colour";
|
||||
ui_tooltip = "Zero gives monochrome grain, one gives independent noise per channel.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
|
||||
> = 0.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float Hash(float2 p)
|
||||
{
|
||||
float3 scattered = frac(float3(p.x, p.y, p.x) * 0.1031);
|
||||
scattered += dot(scattered, scattered.yzx + 33.33);
|
||||
return frac((scattered.x + scattered.y) * scattered.z);
|
||||
}
|
||||
|
||||
float4 PS_FilmGrain(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
||||
|
||||
float2 cell = floor(pos.xy / max(Size, 1.0));
|
||||
float mono = Hash(cell) - 0.5;
|
||||
float3 chroma = float3(Hash(cell + 11.7), Hash(cell + 23.1), Hash(cell + 37.5)) - 0.5;
|
||||
float3 noise = lerp(float3(mono, mono, mono), chroma, Colored);
|
||||
|
||||
float luma = dot(rgb, float3(0.2126, 0.7152, 0.0722));
|
||||
float response = 1.0 - abs(luma * 2.0 - 1.0);
|
||||
|
||||
return float4(saturate(rgb + noise * Intensity * response), 1.0);
|
||||
}
|
||||
|
||||
technique FilmGrain <
|
||||
ui_label = "Film Grain";
|
||||
ui_tooltip = "Adds photographic grain, strongest in the midtones and fading out in blacks and whites.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_FilmGrain;
|
||||
}
|
||||
}
|
||||
Vendored
-60
@@ -1,60 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Exposure <
|
||||
ui_type = "slider";
|
||||
ui_label = "Exposure";
|
||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Toe <
|
||||
ui_type = "slider";
|
||||
ui_label = "Toe";
|
||||
ui_tooltip = "Above 1.0 deepens the shadows, below 1.0 lifts them.";
|
||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 1.2;
|
||||
|
||||
uniform float Shoulder <
|
||||
ui_type = "slider";
|
||||
ui_label = "Shoulder";
|
||||
ui_tooltip = "Above 1.0 opens up the highlights, below 1.0 compresses them.";
|
||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 1.2;
|
||||
|
||||
uniform float Amount <
|
||||
ui_type = "slider";
|
||||
ui_label = "Amount";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
|
||||
> = 0.7;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_FilmicCurve(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
||||
|
||||
float3 curved = saturate(rgb * Exposure);
|
||||
curved = pow(max(curved, 0.0), Toe);
|
||||
curved = 1.0 - pow(max(1.0 - curved, 0.0), Shoulder);
|
||||
|
||||
return float4(saturate(lerp(rgb, curved, Amount)), 1.0);
|
||||
}
|
||||
|
||||
technique FilmicCurve <
|
||||
ui_label = "Filmic Curve";
|
||||
ui_tooltip = "Filmic contrast curve. Deepens the shadows and opens the highlights without clipping either end.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_FilmicCurve;
|
||||
}
|
||||
}
|
||||
Vendored
-53
@@ -1,53 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Distortion <
|
||||
ui_type = "slider";
|
||||
ui_label = "Distortion";
|
||||
ui_tooltip = "Positive bulges the picture outwards, negative pinches it inwards.";
|
||||
ui_min = -0.5; ui_max = 0.5; ui_step = 0.01;
|
||||
> = 0.1;
|
||||
|
||||
uniform float Zoom <
|
||||
ui_type = "slider";
|
||||
ui_label = "Zoom";
|
||||
ui_tooltip = "Scales the picture to hide the edges the warp pulls in.";
|
||||
ui_min = 0.5; ui_max = 1.5; ui_step = 0.01;
|
||||
> = 1.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_LensDistortion(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float aspect = BUFFER_WIDTH * BUFFER_RCP_HEIGHT;
|
||||
float2 half_size = float2(aspect, 1.0);
|
||||
float2 unit = half_size / length(half_size);
|
||||
|
||||
float2 centred = (uv - 0.5) * 2.0 * unit;
|
||||
float r2 = dot(centred, centred);
|
||||
centred *= 1.0 + Distortion * r2;
|
||||
centred /= max(Zoom, 0.001);
|
||||
|
||||
float2 source = centred / (2.0 * unit) + 0.5;
|
||||
|
||||
return float4(tex2D(BackBuffer, source).rgb, 1.0);
|
||||
}
|
||||
|
||||
technique LensDistortion <
|
||||
ui_label = "Lens Distortion";
|
||||
ui_tooltip = "Barrel or pincushion warp, like looking through a wide angle lens.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_LensDistortion;
|
||||
}
|
||||
}
|
||||
Vendored
-66
@@ -1,66 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float InputBlack <
|
||||
ui_type = "slider";
|
||||
ui_label = "Input Black";
|
||||
ui_tooltip = "Input level mapped to black. Raise it to deepen washed out shadows.";
|
||||
ui_min = 0.0; ui_max = 0.5; ui_step = 0.005;
|
||||
> = 0.0;
|
||||
|
||||
uniform float InputWhite <
|
||||
ui_type = "slider";
|
||||
ui_label = "Input White";
|
||||
ui_min = 0.5; ui_max = 1.0; ui_step = 0.005;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Gamma <
|
||||
ui_type = "slider";
|
||||
ui_label = "Gamma";
|
||||
ui_min = 0.2; ui_max = 3.0; ui_step = 0.01;
|
||||
> = 1.0;
|
||||
|
||||
uniform float OutputBlack <
|
||||
ui_type = "slider";
|
||||
ui_label = "Output Black";
|
||||
ui_tooltip = "Lifts crushed shadows so detail stops collapsing into one flat black.";
|
||||
ui_min = 0.0; ui_max = 0.5; ui_step = 0.005;
|
||||
> = 0.0;
|
||||
|
||||
uniform float OutputWhite <
|
||||
ui_type = "slider";
|
||||
ui_label = "Output White";
|
||||
ui_min = 0.5; ui_max = 1.0; ui_step = 0.005;
|
||||
> = 1.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_Levels(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
||||
|
||||
rgb = saturate((rgb - InputBlack) / max(InputWhite - InputBlack, 0.001));
|
||||
rgb = pow(max(rgb, 0.0), 1.0 / max(Gamma, 0.001));
|
||||
rgb = lerp(OutputBlack, OutputWhite, rgb);
|
||||
|
||||
return float4(saturate(rgb), 1.0);
|
||||
}
|
||||
|
||||
technique Levels <
|
||||
ui_label = "Levels";
|
||||
ui_tooltip = "Black point, white point, gamma and output range. Use it to fix crushed or washed out shadows.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Levels;
|
||||
}
|
||||
}
|
||||
Vendored
-88
@@ -1,88 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Length <
|
||||
ui_type = "slider";
|
||||
ui_label = "Length";
|
||||
ui_tooltip = "How far the streaks reach, as a percentage of screen height.";
|
||||
ui_min = 0.0; ui_max = 20.0; ui_step = 0.5;
|
||||
> = 5.0;
|
||||
|
||||
uniform float Zoom <
|
||||
ui_type = "slider";
|
||||
ui_label = "Zoom";
|
||||
ui_tooltip = "Streaks running out from the centre of the screen, as if rushing forward. The centre stays sharp.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Pan <
|
||||
ui_type = "slider";
|
||||
ui_label = "Pan";
|
||||
ui_tooltip = "Streaks running in one fixed direction, as if the camera were sweeping across.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.0;
|
||||
|
||||
uniform float Angle <
|
||||
ui_type = "slider";
|
||||
ui_label = "Pan Angle";
|
||||
ui_tooltip = "Direction of the sweep, in degrees.";
|
||||
ui_min = 0.0; ui_max = 360.0; ui_step = 5.0;
|
||||
> = 0.0;
|
||||
|
||||
uniform float Spin <
|
||||
ui_type = "slider";
|
||||
ui_label = "Spin";
|
||||
ui_tooltip = "Streaks curling around the centre, as if the camera were rolling. Negative turns the other way.";
|
||||
ui_min = -1.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.0;
|
||||
|
||||
static const int TAPS = 24;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_MotionBlur(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float aspect = BUFFER_WIDTH * BUFFER_RCP_HEIGHT;
|
||||
float2 to_screen = float2(aspect, 1.0);
|
||||
|
||||
float2 centred = (uv - 0.5) * to_screen * 2.0;
|
||||
float2 outward = centred;
|
||||
float2 around = float2(-centred.y, centred.x);
|
||||
|
||||
float radians_angle = Angle * 0.01745329;
|
||||
float2 sweep = float2(cos(radians_angle), sin(radians_angle));
|
||||
|
||||
float2 velocity = sweep * Pan + outward * Zoom + around * Spin;
|
||||
velocity *= Length * 0.01;
|
||||
velocity /= to_screen;
|
||||
|
||||
float jitter = frac(sin(dot(pos.xy, float2(12.9898, 78.233))) * 43758.5453);
|
||||
|
||||
float3 sum = float3(0.0, 0.0, 0.0);
|
||||
[unroll] for (int i = 0; i < TAPS; ++i)
|
||||
{
|
||||
float t = (float(i) + jitter) / float(TAPS) - 0.5;
|
||||
sum += tex2D(BackBuffer, uv + velocity * t).rgb;
|
||||
}
|
||||
|
||||
return float4(sum / float(TAPS), 1.0);
|
||||
}
|
||||
|
||||
technique MotionBlur <
|
||||
ui_label = "Motion Blur";
|
||||
ui_tooltip = "Camera style motion blur: streaks the picture outwards, sideways or around, without touching still detail at the centre.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_MotionBlur;
|
||||
}
|
||||
}
|
||||
Vendored
-60
@@ -1,60 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// Ported from naturalA.fsh in PPSSPP, by ShadX, modified by SimoneT.
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Luma <
|
||||
ui_type = "slider";
|
||||
ui_label = "Luma Curve";
|
||||
ui_tooltip = "Gamma applied to the luminance channel in YIQ space.";
|
||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 1.2;
|
||||
|
||||
uniform float Chroma <
|
||||
ui_type = "slider";
|
||||
ui_label = "Chroma Gain";
|
||||
ui_tooltip = "Boost applied to the two colour difference channels.";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 1.2;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_Natural(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
const float3x3 RGBtoYIQ = float3x3(0.299, 0.587, 0.114,
|
||||
0.596, -0.275, -0.321,
|
||||
0.212, -0.523, 0.311);
|
||||
|
||||
const float3x3 YIQtoRGB = float3x3(1.0, 0.95568806, 0.61985809,
|
||||
1.0, -0.27158180, -0.64687382,
|
||||
1.0, -1.10817733, 1.70506456);
|
||||
|
||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
||||
float3 yiq = mul(RGBtoYIQ, rgb);
|
||||
|
||||
yiq.x = pow(max(yiq.x, 0.0), Luma);
|
||||
yiq.yz *= Chroma;
|
||||
|
||||
return float4(saturate(mul(YIQtoRGB, yiq)), 1.0);
|
||||
}
|
||||
|
||||
technique NaturalColors <
|
||||
ui_label = "Natural Colours";
|
||||
ui_tooltip = "Warms the picture and lifts saturation for a less washed out look. Ported from the PPSSPP shader.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Natural;
|
||||
}
|
||||
}
|
||||
Vendored
-90
@@ -1,90 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Timer < source = "timer"; > = 0.0;
|
||||
|
||||
uniform float Horizon <
|
||||
ui_type = "slider";
|
||||
ui_label = "Reflection Line";
|
||||
ui_tooltip = "Height on screen where the reflective floor begins. Everything above it is left untouched.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
|
||||
> = 0.55;
|
||||
|
||||
uniform float Amount <
|
||||
ui_type = "slider";
|
||||
ui_label = "Amount";
|
||||
ui_tooltip = "How strongly the reflection shows through the floor.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.35;
|
||||
|
||||
uniform float Falloff <
|
||||
ui_type = "slider";
|
||||
ui_label = "Falloff";
|
||||
ui_tooltip = "How quickly the reflection fades as the floor comes towards the viewer. At zero it stays even.";
|
||||
ui_min = 0.0; ui_max = 4.0; ui_step = 0.1;
|
||||
> = 1.2;
|
||||
|
||||
uniform float Perspective <
|
||||
ui_type = "slider";
|
||||
ui_label = "Perspective";
|
||||
ui_tooltip = "Stretches or squashes the mirrored image. One is a true mirror, higher values pull it towards the line.";
|
||||
ui_min = 0.2; ui_max = 2.0; ui_step = 0.05;
|
||||
> = 1.0;
|
||||
|
||||
uniform float Ripple <
|
||||
ui_type = "slider";
|
||||
ui_label = "Ripple";
|
||||
ui_tooltip = "Amplitude of the waves disturbing the reflection. At zero the mirror is perfectly still.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.0;
|
||||
|
||||
uniform float RippleSpeed <
|
||||
ui_type = "slider";
|
||||
ui_label = "Ripple Speed";
|
||||
ui_tooltip = "How fast the waves travel.";
|
||||
ui_min = 0.0; ui_max = 4.0; ui_step = 0.1;
|
||||
> = 1.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_Reflections(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float3 color = tex2D(BackBuffer, uv).rgb;
|
||||
|
||||
float depth = uv.y - Horizon;
|
||||
float on_floor = step(0.0, depth);
|
||||
float span = max(1.0 - Horizon, 0.001);
|
||||
float distance_down = saturate(depth / span);
|
||||
|
||||
float seconds = Timer * 0.001;
|
||||
float wave = sin(uv.x * 38.0 + seconds * RippleSpeed * 2.0) *
|
||||
sin(uv.y * 21.0 - seconds * RippleSpeed * 1.3);
|
||||
float2 disturbance = float2(wave * 0.004, wave * 0.002) * Ripple * distance_down;
|
||||
|
||||
float2 mirrored = float2(uv.x, Horizon - depth * Perspective) + disturbance;
|
||||
float3 reflection = tex2D(BackBuffer, saturate(mirrored)).rgb;
|
||||
|
||||
float fade = pow(max(1.0 - distance_down, 0.0001), Falloff);
|
||||
float strength = Amount * fade * on_floor;
|
||||
|
||||
return float4(lerp(color, reflection, strength), 1.0);
|
||||
}
|
||||
|
||||
technique Reflections <
|
||||
ui_label = "Reflections";
|
||||
ui_tooltip = "Mirrors the picture into a reflective floor below a line you choose, with optional water ripples.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Reflections;
|
||||
}
|
||||
}
|
||||
Vendored
-66
@@ -1,66 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// Ported from scanlines.fsh in PPSSPP.
|
||||
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Density <
|
||||
ui_type = "slider";
|
||||
ui_label = "Line Density";
|
||||
ui_tooltip = "Number of scanline pairs across the screen.";
|
||||
ui_min = 60.0; ui_max = 720.0; ui_step = 10.0;
|
||||
> = 340.0;
|
||||
|
||||
uniform float Intensity <
|
||||
ui_type = "slider";
|
||||
ui_label = "Intensity";
|
||||
ui_tooltip = "How dark the gaps between lines become.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 0.5;
|
||||
|
||||
uniform float Tint <
|
||||
ui_type = "slider";
|
||||
ui_label = "Phosphor Tint";
|
||||
ui_tooltip = "Strength of the green-warm phosphor cast.";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
||||
> = 1.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_Scanlines(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float line_pos = uv.y * Density * 0.5;
|
||||
float gate = cos((frac(line_pos) - 0.5) * 3.1415926 * Intensity) * 1.5;
|
||||
|
||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
||||
float3 color = rgb * 0.5 + 0.5 * rgb * rgb * 1.2;
|
||||
|
||||
float3 phosphor = lerp(float3(1.0, 1.0, 1.0), float3(0.9, 1.0, 0.7), Tint);
|
||||
color *= phosphor;
|
||||
|
||||
float2 diff = uv - 0.5;
|
||||
color *= 1.1 - 0.6 * (dot(diff, diff) * 2.0);
|
||||
|
||||
return float4(saturate(color * saturate(gate)), 1.0);
|
||||
}
|
||||
|
||||
technique Scanlines <
|
||||
ui_label = "Scanlines";
|
||||
ui_tooltip = "Darkens alternating rows of pixels to imitate the horizontal scanlines of a CRT. Cheaper than the full CRT effect when you only want the lines.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Scanlines;
|
||||
}
|
||||
}
|
||||
Vendored
-43
@@ -1,43 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Amount <
|
||||
ui_type = "slider";
|
||||
ui_label = "Amount";
|
||||
ui_min = 0.0; ui_max = 3.0; ui_step = 0.01;
|
||||
> = 0.6;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_Sharpen(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
||||
|
||||
float3 centre = tex2D(BackBuffer, uv).rgb;
|
||||
float3 blur = tex2D(BackBuffer, uv + float2(-texel.x, 0.0)).rgb;
|
||||
blur += tex2D(BackBuffer, uv + float2(texel.x, 0.0)).rgb;
|
||||
blur += tex2D(BackBuffer, uv + float2(0.0, -texel.y)).rgb;
|
||||
blur += tex2D(BackBuffer, uv + float2(0.0, texel.y)).rgb;
|
||||
blur *= 0.25;
|
||||
|
||||
return float4(centre + (centre - blur) * Amount, 1.0);
|
||||
}
|
||||
|
||||
technique Sharpen <
|
||||
ui_label = "Sharpen";
|
||||
ui_tooltip = "Unsharp mask that brings back edge detail lost to scaling. Most useful after upscaling a low internal resolution.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Sharpen;
|
||||
}
|
||||
}
|
||||
Vendored
-75
@@ -1,75 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float ShadowHue <
|
||||
ui_type = "slider";
|
||||
ui_label = "Shadow Hue";
|
||||
ui_min = 0.0; ui_max = 360.0; ui_step = 1.0;
|
||||
> = 210.0;
|
||||
|
||||
uniform float ShadowStrength <
|
||||
ui_type = "slider";
|
||||
ui_label = "Shadow Strength";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
|
||||
> = 0.0;
|
||||
|
||||
uniform float HighlightHue <
|
||||
ui_type = "slider";
|
||||
ui_label = "Highlight Hue";
|
||||
ui_min = 0.0; ui_max = 360.0; ui_step = 1.0;
|
||||
> = 45.0;
|
||||
|
||||
uniform float HighlightStrength <
|
||||
ui_type = "slider";
|
||||
ui_label = "Highlight Strength";
|
||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
|
||||
> = 0.0;
|
||||
|
||||
uniform float Balance <
|
||||
ui_type = "slider";
|
||||
ui_label = "Balance";
|
||||
ui_tooltip = "Moves the split between what counts as shadow and what counts as highlight.";
|
||||
ui_min = -0.5; ui_max = 0.5; ui_step = 0.01;
|
||||
> = 0.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float3 HueToRGB(float hue)
|
||||
{
|
||||
float h = frac(hue / 360.0) * 6.0;
|
||||
return saturate(float3(abs(h - 3.0) - 1.0, 2.0 - abs(h - 2.0), 2.0 - abs(h - 4.0)));
|
||||
}
|
||||
|
||||
float4 PS_SplitToning(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
||||
|
||||
float luma = saturate(dot(rgb, float3(0.2126, 0.7152, 0.0722)) + Balance);
|
||||
|
||||
float3 shadow_tint = HueToRGB(ShadowHue) - 0.5;
|
||||
float3 highlight_tint = HueToRGB(HighlightHue) - 0.5;
|
||||
|
||||
rgb += shadow_tint * ShadowStrength * 0.25 * (1.0 - luma);
|
||||
rgb += highlight_tint * HighlightStrength * 0.25 * luma;
|
||||
|
||||
return float4(saturate(rgb), 1.0);
|
||||
}
|
||||
|
||||
technique SplitToning <
|
||||
ui_label = "Split Toning";
|
||||
ui_tooltip = "Tints the shadows and the highlights towards two different hues.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_SplitToning;
|
||||
}
|
||||
}
|
||||
Vendored
-52
@@ -1,52 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// Ported from vignette.fsh in PPSSPP, by Henrik Rydgard.
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Strength <
|
||||
ui_type = "slider";
|
||||
ui_label = "Strength";
|
||||
ui_tooltip = "How dark the corners become.";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 0.6;
|
||||
|
||||
uniform float Aspect <
|
||||
ui_type = "slider";
|
||||
ui_label = "Aspect";
|
||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 1.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 PS_Vignette(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float2 diff = uv - 0.5;
|
||||
diff.x *= Aspect;
|
||||
diff.y /= max(Aspect, 0.0001);
|
||||
|
||||
float falloff = 1.0 - min(1.0, Strength * dot(diff, diff) * 2.0);
|
||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
||||
|
||||
return float4(rgb * falloff, 1.0);
|
||||
}
|
||||
|
||||
technique Vignette <
|
||||
ui_label = "Vignette";
|
||||
ui_tooltip = "Darkens the corners of the screen to pull the eye towards the middle, the way a camera lens falls off at its edges.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_Vignette;
|
||||
}
|
||||
}
|
||||
Vendored
-76
@@ -1,76 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
texture BackBufferTex : COLOR;
|
||||
sampler BackBuffer { Texture = BackBufferTex; };
|
||||
|
||||
uniform float Temperature <
|
||||
ui_type = "slider";
|
||||
ui_label = "Temperature";
|
||||
ui_tooltip = "Negative cools the picture towards blue, positive warms it towards orange.";
|
||||
ui_min = -100.0; ui_max = 100.0; ui_step = 1.0;
|
||||
> = 0.0;
|
||||
|
||||
uniform float Tint <
|
||||
ui_type = "slider";
|
||||
ui_label = "Tint";
|
||||
ui_tooltip = "Negative shifts towards green, positive towards magenta.";
|
||||
ui_min = -100.0; ui_max = 100.0; ui_step = 1.0;
|
||||
> = 0.0;
|
||||
|
||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
||||
{
|
||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float3 WhitePointLMS(float t1, float t2)
|
||||
{
|
||||
float shift = 0.05;
|
||||
if (t1 < 0.0)
|
||||
{
|
||||
shift = 0.10;
|
||||
}
|
||||
float x = 0.31271 - t1 * shift;
|
||||
float y = 2.87 * x - 3.0 * x * x - 0.27509507 + t2 * 0.05;
|
||||
|
||||
float big_y = 1.0;
|
||||
float big_x = big_y * x / y;
|
||||
float big_z = big_y * (1.0 - x - y) / y;
|
||||
|
||||
return float3( 0.7328 * big_x + 0.4296 * big_y - 0.1624 * big_z,
|
||||
-0.7036 * big_x + 1.6975 * big_y + 0.0061 * big_z,
|
||||
0.0030 * big_x + 0.0136 * big_y + 0.9834 * big_z);
|
||||
}
|
||||
|
||||
float4 PS_WhiteBalance(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
||||
{
|
||||
float3 rgb = pow(max(tex2D(BackBuffer, uv).rgb, 0.0), 2.2);
|
||||
|
||||
float3 balance = float3(0.949237, 1.03542, 1.08728) /
|
||||
WhitePointLMS(Temperature / 65.0, Tint / 65.0);
|
||||
|
||||
const float3x3 rgb_to_lms = float3x3(0.390405, 0.549941, 0.008926,
|
||||
0.070841, 0.963172, 0.001358,
|
||||
0.023108, 0.128021, 0.936245);
|
||||
const float3x3 lms_to_rgb = float3x3( 2.858470, -1.628790, -0.024891,
|
||||
-0.210182, 1.158200, 0.000324,
|
||||
-0.041812, -0.118169, 1.068670);
|
||||
|
||||
float3 lms = mul(rgb_to_lms, rgb) * balance;
|
||||
rgb = mul(lms_to_rgb, lms);
|
||||
|
||||
return float4(saturate(pow(max(rgb, 0.0), 1.0 / 2.2)), 1.0);
|
||||
}
|
||||
|
||||
technique WhiteBalance <
|
||||
ui_label = "White Balance";
|
||||
ui_tooltip = "Corrects a picture that looks too cool, too warm or tinted.";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = VS_PostProcess;
|
||||
PixelShader = PS_WhiteBalance;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
- [NetBSD](#netbsd)
|
||||
- [MSYS2](#msys2)
|
||||
- [RedoxOS](#redoxos)
|
||||
- [PlayStation 4](#playstation-4)
|
||||
<!-- /TOC -->
|
||||
|
||||
## Arch Linux
|
||||
@@ -242,3 +243,14 @@ find ./*/ -name "*.dll" | while read -r dll; do deps "$dll"; done
|
||||
The package install may randomly hang at times, in which case it has to be restarted. ALWAYS do a `sudo pkg update` or the chances of it hanging will be close to 90%. If "multiple" installs fail at once, try installing 1 by 1 the packages.
|
||||
|
||||
When CMake invokes certain file syscalls - it may sometimes cause crashes or corruptions on the (kernel?) address space - so reboot the system if there is a "hang" in CMake.
|
||||
|
||||
## PlayStation 4
|
||||
|
||||
```sh
|
||||
export OO_PS4_TOOLCHAIN="$HOME/OpenOrbis/PS4Toolchain/prefix"
|
||||
export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
|
||||
```
|
||||
|
||||
```sh
|
||||
cp $OO_PS4_TOOLCHAIN/include/endian.h $OO_PS4_TOOLCHAIN/include/sys/endian.h
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Design Overview
|
||||
|
||||
Modern game consoles require heavy power to emulate. This is why the emulator uses an approach known as HLE (High-Level-Emulation), in a nutshell: Instead of accurately emulating every subsystem that forms part of a component, emulate the resulting visible output of said interface instead.
|
||||
Modern game consoles require heavy power to be emulated appropriately. This is why the emulator uses an approach known as HLE (High-Level-Emulation), in a nutshell: Instead of accurately emulating every subsystem that forms part of a component, emulate the resulting visible I/O interface instead.
|
||||
|
||||
For example, take a disk write, instead of emulating a proper SD card we instead use the C++ standard library for I/O. Additionally we use the abstractions provided by the `fs` service to "lie" to programs about certain SD card properties. Notably this includes making up sizes for the fake SD card, giving "realistic" values or expected outputs for a given card, and so on. And instead of writing to an actual SD card, the emulator simply writes to a file.
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Subsystem: HLE
|
||||
|
||||
## HOS Kernel
|
||||
# HOS Kernel
|
||||
|
||||
In brief, the HOS kernel is a microkernel, all services and programs run in userspace, the primary way to do communication between these is via `HIPC` (not covered here); otherwise most of the primitives reside in the forms of syscalls invoked via `svc #imm`. The kernel supports both 32-bit and 64-bit programs, and has the capacity to use 32, 36 and 39 bits of address space for spawned processes. Most of the networking stack is based off FreeBSD's network stack.
|
||||
|
||||
@@ -31,42 +29,3 @@ Every process keeps it's own tracking of the following structures:
|
||||
The emulator willingly restricts itself to only use 4 threads (to emulate 4 cores), this is because most existing applications do not benefit greatly from the added core count, and in fact can be detrimental due to extra contention. This translates equitatively to about 4 `ArmInterface` slots for each process, these are then redirected to whatever is the last `pc` of the last thread running on the core is meant to be; proceed to run it, then when returning (due to halt or interruption), proceed to reschedule the thread.
|
||||
|
||||
The scheduler as-is isn't 100% faithful to the original (for example the original is cooperative and not preemptive), and has great timing variance (especially due to the fact the emulator can run in systems with wildly different timings).
|
||||
|
||||
## Services
|
||||
|
||||
Consult [SwitchBrew](https://switchbrew.org/) for per-service methods, and implementation details.
|
||||
|
||||
All services are instatiated implicitly using `ServiceFramework`. To register a new interface or service, you can inherit from said class, providing additionally a template parameter that references `Self`, for example:
|
||||
|
||||
```c++
|
||||
// Follows as:
|
||||
// class MyInterface [final] : public ServiceFramework<MyInterface> { ... };
|
||||
// [final] is optional, but should be used whenever there is no intention of this class itself being inherited.
|
||||
class IFloatingRegistrationRequest final : public ServiceFramework<IFloatingRegistrationRequest> {
|
||||
public:
|
||||
// ctor, you can pass extra parameters here (if so required)
|
||||
explicit IFloatingRegistrationRequest(Core::System& system_)
|
||||
: ServiceFramework{system_, "IFloatingRegistrationRequest"}
|
||||
{}
|
||||
|
||||
// Define here your functions and methods, please order them.
|
||||
// Use FindRequestTipc for TIPC handlers.
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "GetSessionId"},
|
||||
FunctionInfo{12, nullptr, "GetAccountId"},
|
||||
FunctionInfo{13, nullptr, "GetLinkedNintendoAccountId"},
|
||||
FunctionInfo{14, nullptr, "GetNickname"},
|
||||
FunctionInfo{15, nullptr, "GetProfileImage"},
|
||||
FunctionInfo{16, nullptr, "GetProfileLargeImage", MakeVersionGate({18,0,0})},
|
||||
FunctionInfo{21, nullptr, "LoadIdTokenCache"},
|
||||
FunctionInfo{100, nullptr, "RegisterUser"},
|
||||
FunctionInfo{101, nullptr, "RegisterUserWithUid"},
|
||||
FunctionInfo{102, nullptr, "RegisterNetworkServiceAccountAsync", MakeVersionGate({4,0,0})},
|
||||
FunctionInfo{103, nullptr, "RegisterNetworkServiceAccountWithUidAsync", MakeVersionGate({4,0,0})},
|
||||
FunctionInfo{110, nullptr, "SetSystemProgramIdentification"},
|
||||
FunctionInfo{111, nullptr, "EnsureIdTokenCacheAsync"}
|
||||
);
|
||||
}
|
||||
};
|
||||
```
|
||||
+1
-1
@@ -21,7 +21,7 @@ This contains documentation created by developers, build instructions, guideline
|
||||
- Subsystems:
|
||||
- **[Design Overview](./DesignOverview.md)**
|
||||
- **[Dynarmic](./dynarmic/README.md)**
|
||||
- **[Subsystem: HLE](./SubsystemHLE.md)**
|
||||
- **[HOS Kernel](./HosKernel.md)**
|
||||
- **[Settings](./Settings.md)**
|
||||
|
||||
## Policies
|
||||
|
||||
@@ -35,6 +35,7 @@ Eden will store configuration files in the following directories:
|
||||
- **Android**: Data is stored internally.
|
||||
- **Linux, macOS, FreeBSD, Solaris, OpenBSD**: `$XDG_DATA_HOME`, `$XDG_CACHE_HOME`, `$XDG_CONFIG_HOME`.
|
||||
- **HaikuOS**: `/boot/home/config/settings/eden`
|
||||
- **PlayStation 4**: `/data/eden`
|
||||
|
||||
If a `user` directory is present in the current working directory, that will override all global configuration directories and the emulator will use the `user` directory instead.
|
||||
|
||||
|
||||
+21
-33
@@ -1,44 +1,32 @@
|
||||
# User Handbook - Command Line
|
||||
|
||||
There are two main applications, an SDL-based app (`eden-cli`) and a Qt based app (`eden`); both accept the same command line arguments.
|
||||
There are two main applications, an SDL-based app (`eden-cli`) and a Qt based app (`eden`); both accept command line arguments.
|
||||
|
||||
## eden
|
||||
|
||||
- `./eden <path>`: Running with a single argument and nothing else, will make the emulator look for the given file and load it, this behavior is similar to `eden-cli`; allows dragging and dropping games into the application.
|
||||
- `--debug/-d`: Enter debug mode, allow gdb stub at port `1234`
|
||||
- `--config/-c`: Specify alternate configuration file.
|
||||
- `--fullscreen/-f`: Use fullscreen.
|
||||
- `--help/-h`: Display help.
|
||||
- `--game/-g <path>`: Alternate way to specify what to load, overrides. However let it be noted that arguments that use `-` will be treated as options/ignored, if your game, for some reason, starts with `-`, in order to safely handle it you may need to specify it as an argument.
|
||||
- `--multiplayer/-m`: Specify multiplayer options.
|
||||
- `--program/-p`: Specify the program arguments to pass (optional).
|
||||
- `--user/-u <number>`: Specify the user index.
|
||||
- `--version/-v`: Display version and quit.
|
||||
- `--input-profile/-i <name>`: Specifies input profile name to use (for player #0 only).
|
||||
- `--null-render/-n`: Forces the usage of the "Null" render backend irrespective of settings.
|
||||
- `--filter/-x`: Sets the debug log filter irrespective of settings.
|
||||
- `--singlecore/-s`: Forces single-core regardless of settings.
|
||||
|
||||
Only the Qt frontend supports the following arguments:
|
||||
|
||||
- `-g <path>`: Alternate way to specify what to load, overrides. However let it be noted that arguments that use `-` will be treated as options/ignored, if your game, for some reason, starts with `-`, in order to safely handle it you may need to specify it as an argument.
|
||||
- `-f`: Use fullscreen.
|
||||
- `-u <number>`: Select the index of the user to load as.
|
||||
- `-input-profile <name>`: Specifies input profile name to use (for player #0 only).
|
||||
- `-qlaunch`: Launch QLaunch.
|
||||
- `-hlaunch`: Launch homebrew launcher `nx-hbloader`.
|
||||
- Requires a copy of Atmosphere to be extracted onto `sdmc`.
|
||||
- This is a shorthand for `<eden folder>/sdmc/atmosphere/hbl.nsp`.
|
||||
- `-setup`: Launch setup applet.
|
||||
|
||||
`eden` (provided with `--room`), and `eden-room` supports the following options as well:
|
||||
## eden-cli
|
||||
|
||||
- `-n/--room-name`: The name of the room.
|
||||
- `-d/--room-description`: The room description.
|
||||
- `-s/--bind-address`: The bind address for the room.
|
||||
- `-p/--port`: The port used for the room.
|
||||
- `-m/--max-members`: The maximum number of players for this room.
|
||||
- `-w/--password`: The password for the room.
|
||||
- `-g/--preferred-game`: The preferred game for this room.
|
||||
- `-i/--preferred-game-id`: The preferred game-id for this room.
|
||||
- `-u/--username`: The username used for announce.
|
||||
- `-t/--token`: The token used for announce.
|
||||
- `-a/--web-api-url`: yuzu Web API url.
|
||||
- `-b/--ban-list-file`: The file for storing the room ban list.
|
||||
- `-l/--log-file`: The file for storing the room log.
|
||||
- `-h/--help`: Display this help and exit.
|
||||
- `-v/--version`: Output version information and exit.
|
||||
- `--debug/-d`: Enter debug mode, allow gdb stub at port `1234`
|
||||
- `--config/-c`: Specify alternate configuration file.
|
||||
- `--fullscreen/-f`: Set fullscreen.
|
||||
- `--help/-h`: Display help.
|
||||
- `--game/-g`: Specify the game to run.
|
||||
- `--multiplayer/-m`: Specify multiplayer options.
|
||||
- `--program/-p`: Specify the program arguments to pass (optional).
|
||||
- `--user/-u`: Specify the user index.
|
||||
- `--version/-v`: Display version and quit.
|
||||
- `--input-profile/-i`: Specifies input profile name to use (for player #0 only).
|
||||
- `--null-render/-n`: Forces the usage of the "Null" render backend irrespective of settings.
|
||||
- `--filter/-x`: Sets the debug log filter irrespective of settings.
|
||||
- `--singlecore/-s`: Forces single-core regardless of settings.
|
||||
|
||||
Vendored
+5
-44
@@ -195,50 +195,6 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# reshadefx
|
||||
if (ENABLE_RESHADE)
|
||||
AddJsonPackage(NAME reshade DOWNLOAD_ONLY)
|
||||
|
||||
set(RESHADEFX_SHIM_DIR ${CMAKE_CURRENT_BINARY_DIR}/reshadefx_shim)
|
||||
file(WRITE ${RESHADEFX_SHIM_DIR}/spirv.hpp "#include <spirv/unified1/spirv.hpp>\n")
|
||||
file(WRITE ${RESHADEFX_SHIM_DIR}/GLSL.std.450.h "#include <spirv/unified1/GLSL.std.450.h>\n")
|
||||
if (APPLE)
|
||||
file(WRITE ${RESHADEFX_SHIM_DIR}/malloc.h "#include <stdlib.h>\n#include <alloca.h>\n")
|
||||
endif()
|
||||
|
||||
add_library(reshadefx STATIC
|
||||
${reshade_SOURCE_DIR}/source/effect_codegen_spirv.cpp
|
||||
${reshade_SOURCE_DIR}/source/effect_expression.cpp
|
||||
${reshade_SOURCE_DIR}/source/effect_lexer.cpp
|
||||
${reshade_SOURCE_DIR}/source/effect_parser_exp.cpp
|
||||
${reshade_SOURCE_DIR}/source/effect_parser_stmt.cpp
|
||||
${reshade_SOURCE_DIR}/source/effect_preprocessor.cpp
|
||||
${reshade_SOURCE_DIR}/source/effect_symbol_table.cpp
|
||||
)
|
||||
|
||||
target_include_directories(reshadefx SYSTEM PUBLIC ${reshade_SOURCE_DIR}/source)
|
||||
target_include_directories(reshadefx PRIVATE ${RESHADEFX_SHIM_DIR})
|
||||
target_link_libraries(reshadefx PUBLIC SPIRV-Headers::SPIRV-Headers)
|
||||
|
||||
if (NOT MSVC)
|
||||
target_compile_options(reshadefx PRIVATE -w -fno-char8_t)
|
||||
else()
|
||||
target_compile_options(reshadefx PRIVATE /w /Zc:char8_t-)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
if (NOT MSVC)
|
||||
target_compile_options(reshadefx PRIVATE -include share.h)
|
||||
else()
|
||||
target_compile_options(reshadefx PRIVATE /FIshare.h)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT TARGET reshadefx::reshadefx)
|
||||
add_library(reshadefx::reshadefx ALIAS reshadefx)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Catch2
|
||||
if (YUZU_TESTS OR DYNARMIC_TESTS)
|
||||
AddJsonPackage(catch2)
|
||||
@@ -299,6 +255,11 @@ target_include_directories(tz PUBLIC ./tz)
|
||||
add_library(bc_decoder bc_decoder/bc_decoder.cpp)
|
||||
target_include_directories(bc_decoder PUBLIC ./bc_decoder)
|
||||
|
||||
if (OPENORBIS)
|
||||
add_library(ps4sup ps4sup/emutls.c ps4sup/stub.cpp)
|
||||
target_include_directories(ps4sup PUBLIC ./ps4sup)
|
||||
endif()
|
||||
|
||||
if (NOT TARGET RenderDoc::API)
|
||||
add_library(renderdoc INTERFACE)
|
||||
target_include_directories(renderdoc SYSTEM INTERFACE ./renderdoc)
|
||||
|
||||
Vendored
+184
@@ -0,0 +1,184 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* ===---------- emutls.c - Implements __emutls_get_address ---------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//#include "int_util.h"
|
||||
|
||||
/* Default is not to use posix_memalign, so systems like Android
|
||||
* can use thread local data without heavier POSIX memory allocators.
|
||||
*/
|
||||
#ifndef EMUTLS_USE_POSIX_MEMALIGN
|
||||
#define EMUTLS_USE_POSIX_MEMALIGN 0
|
||||
#endif
|
||||
|
||||
/* For every TLS variable xyz,
|
||||
* there is one __emutls_control variable named __emutls_v.xyz.
|
||||
* If xyz has non-zero initial value, __emutls_v.xyz's "value"
|
||||
* will point to __emutls_t.xyz, which has the initial value.
|
||||
*/
|
||||
typedef struct __emutls_control {
|
||||
size_t size; /* size of the object in bytes */
|
||||
size_t align; /* alignment of the object in bytes */
|
||||
union {
|
||||
uintptr_t index; /* data[index-1] is the object address */
|
||||
void* address; /* object address, when in single thread env */
|
||||
} object;
|
||||
void* value; /* null or non-zero initial value for the object */
|
||||
} __emutls_control;
|
||||
|
||||
static inline void* emutls_memalign_alloc(size_t align, size_t size) {
|
||||
void *base;
|
||||
#if EMUTLS_USE_POSIX_MEMALIGN
|
||||
if (posix_memalign(&base, align, size) != 0)
|
||||
abort();
|
||||
#else
|
||||
#define EXTRA_ALIGN_PTR_BYTES (align - 1 + sizeof(void*))
|
||||
char* object;
|
||||
if ((object = malloc(EXTRA_ALIGN_PTR_BYTES + size)) == NULL)
|
||||
abort();
|
||||
base = (void*)(((uintptr_t)(object + EXTRA_ALIGN_PTR_BYTES))
|
||||
& ~(uintptr_t)(align - 1));
|
||||
|
||||
((void**)base)[-1] = object;
|
||||
#endif
|
||||
return base;
|
||||
}
|
||||
|
||||
static inline void emutls_memalign_free(void* base) {
|
||||
#if EMUTLS_USE_POSIX_MEMALIGN
|
||||
free(base);
|
||||
#else
|
||||
/* The mallocated address is in ((void**)base)[-1] */
|
||||
free(((void**)base)[-1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Emulated TLS objects are always allocated at run-time. */
|
||||
static inline void* emutls_allocate_object(__emutls_control* control) {
|
||||
/* Use standard C types, check with gcc's emutls.o. */
|
||||
//typedef unsigned int gcc_word __attribute__((mode(word)));
|
||||
//typedef unsigned int gcc_pointer __attribute__((mode(pointer)));
|
||||
//COMPILE_TIME_ASSERT(sizeof(size_t) == sizeof(gcc_word));
|
||||
//COMPILE_TIME_ASSERT(sizeof(uintptr_t) == sizeof(gcc_pointer));
|
||||
//COMPILE_TIME_ASSERT(sizeof(uintptr_t) == sizeof(void*));
|
||||
|
||||
size_t size = control->size;
|
||||
size_t align = control->align;
|
||||
if (align < sizeof(void*))
|
||||
align = sizeof(void*);
|
||||
/* Make sure that align is power of 2. */
|
||||
if ((align & (align - 1)) != 0)
|
||||
abort();
|
||||
|
||||
void* base = emutls_memalign_alloc(align, size);
|
||||
if (control->value)
|
||||
memcpy(base, control->value, size);
|
||||
else
|
||||
memset(base, 0, size);
|
||||
return base;
|
||||
}
|
||||
|
||||
static pthread_mutex_t emutls_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static size_t emutls_num_object = 0; /* number of allocated TLS objects */
|
||||
|
||||
typedef struct emutls_address_array {
|
||||
uintptr_t size; /* number of elements in the 'data' array */
|
||||
void* data[];
|
||||
} emutls_address_array;
|
||||
|
||||
static pthread_key_t emutls_pthread_key;
|
||||
|
||||
static void emutls_key_destructor(void* ptr) {
|
||||
emutls_address_array* array = (emutls_address_array*)ptr;
|
||||
uintptr_t i;
|
||||
for (i = 0; i < array->size; ++i) {
|
||||
if (array->data[i])
|
||||
emutls_memalign_free(array->data[i]);
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void emutls_init(void) {
|
||||
if (pthread_key_create(&emutls_pthread_key, emutls_key_destructor) != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Returns control->object.index; set index if not allocated yet. */
|
||||
static inline uintptr_t emutls_get_index(__emutls_control* control) {
|
||||
uintptr_t index = __atomic_load_n(&control->object.index, __ATOMIC_ACQUIRE);
|
||||
if (!index) {
|
||||
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||
pthread_once(&once, emutls_init);
|
||||
pthread_mutex_lock(&emutls_mutex);
|
||||
index = control->object.index;
|
||||
if (!index) {
|
||||
index = ++emutls_num_object;
|
||||
__atomic_store_n(&control->object.index, index, __ATOMIC_RELEASE);
|
||||
}
|
||||
pthread_mutex_unlock(&emutls_mutex);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/* Updates newly allocated thread local emutls_address_array. */
|
||||
static inline void emutls_check_array_set_size(emutls_address_array* array,
|
||||
uintptr_t size) {
|
||||
if (array == NULL)
|
||||
abort();
|
||||
array->size = size;
|
||||
pthread_setspecific(emutls_pthread_key, (void*)array);
|
||||
}
|
||||
|
||||
/* Returns the new 'data' array size, number of elements,
|
||||
* which must be no smaller than the given index.
|
||||
*/
|
||||
static inline uintptr_t emutls_new_data_array_size(uintptr_t index) {
|
||||
/* Need to allocate emutls_address_array with one extra slot
|
||||
* to store the data array size.
|
||||
* Round up the emutls_address_array size to multiple of 16.
|
||||
*/
|
||||
return ((index + 1 + 15) & ~((uintptr_t)15)) - 1;
|
||||
}
|
||||
|
||||
/* Returns the thread local emutls_address_array.
|
||||
* Extends its size if necessary to hold address at index.
|
||||
*/
|
||||
static inline emutls_address_array* emutls_get_address_array(uintptr_t index) {
|
||||
emutls_address_array* array = pthread_getspecific(emutls_pthread_key);
|
||||
if (array == NULL) {
|
||||
uintptr_t new_size = emutls_new_data_array_size(index);
|
||||
array = calloc(new_size + 1, sizeof(void*));
|
||||
emutls_check_array_set_size(array, new_size);
|
||||
} else if (index > array->size) {
|
||||
uintptr_t orig_size = array->size;
|
||||
uintptr_t new_size = emutls_new_data_array_size(index);
|
||||
array = realloc(array, (new_size + 1) * sizeof(void*));
|
||||
if (array)
|
||||
memset(array->data + orig_size, 0,
|
||||
(new_size - orig_size) * sizeof(void*));
|
||||
emutls_check_array_set_size(array, new_size);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
void* __emutls_get_address(__emutls_control* control) {
|
||||
uintptr_t index = emutls_get_index(control);
|
||||
emutls_address_array* array = emutls_get_address_array(index);
|
||||
if (array->data[index - 1] == NULL)
|
||||
array->data[index - 1] = emutls_allocate_object(control);
|
||||
return array->data[index - 1];
|
||||
}
|
||||
Vendored
+44
@@ -0,0 +1,44 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define STUB_WEAK(name) \
|
||||
extern "C" void name() { \
|
||||
printf("called " #name); \
|
||||
asm volatile("ud2"); \
|
||||
}
|
||||
|
||||
#define STUB_ZERO(name) \
|
||||
extern "C" int name() { \
|
||||
printf("called " #name " = ret zero"); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
|
||||
extern "C" int __pthread_cxa_finalize();
|
||||
extern "C" void __cxa_thread_atexit_impl() {
|
||||
//printf("__cxa_thread_atexit_impl called!\n");
|
||||
//__pthread_cxa_finalize();
|
||||
}
|
||||
|
||||
STUB_WEAK(ZSTD_trace_compress_begin)
|
||||
STUB_WEAK(ZSTD_trace_compress_end)
|
||||
STUB_WEAK(ZSTD_trace_decompress_begin)
|
||||
STUB_WEAK(ZSTD_trace_decompress_end)
|
||||
|
||||
extern "C" thread_local struct {
|
||||
char pad[512];
|
||||
} _ThreadRuneLocale = {};
|
||||
extern "C" struct {
|
||||
char pad[512];
|
||||
} __h_errno = {};
|
||||
|
||||
FILE* __stderrp = stdout;
|
||||
FILE* __stdinp = stdin;
|
||||
|
||||
#undef STUB_WEAK
|
||||
|
||||
// THIS MAKES STD::COUT AND SUCH WORK :)
|
||||
#include <iostream>
|
||||
std::ios_base::Init init;
|
||||
@@ -3,13 +3,10 @@
|
||||
|
||||
package org.yuzu.yuzu_emu.dialogs
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Rect
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RadioGroup
|
||||
import android.widget.TextView
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
@@ -21,28 +18,11 @@ import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||
import org.yuzu.yuzu_emu.fragments.EmulationFragment
|
||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractShortSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
||||
|
||||
class QuickSettings(val emulationFragment: EmulationFragment) {
|
||||
private val expandedShaders = mutableSetOf<Int>()
|
||||
|
||||
private fun forgetShaderSlot(index: Int) {
|
||||
val shifted = mutableSetOf<Int>()
|
||||
for (slot in expandedShaders) {
|
||||
if (slot < index) {
|
||||
shifted.add(slot)
|
||||
}
|
||||
if (slot > index) {
|
||||
shifted.add(slot - 1)
|
||||
}
|
||||
}
|
||||
expandedShaders.clear()
|
||||
expandedShaders.addAll(shifted)
|
||||
}
|
||||
|
||||
private fun saveSettings() {
|
||||
if (emulationFragment.shouldUseCustom) {
|
||||
NativeConfig.savePerGameConfig()
|
||||
@@ -252,589 +232,6 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
|
||||
container.addView(itemView)
|
||||
}
|
||||
|
||||
fun addChoice(
|
||||
title: String,
|
||||
container: ViewGroup,
|
||||
choices: List<String>,
|
||||
selectedIndex: Int,
|
||||
onSelected: (Int) -> Unit
|
||||
) {
|
||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
||||
val itemView = inflater.inflate(R.layout.item_quick_settings_menu, container, false)
|
||||
val headerView = itemView.findViewById<ViewGroup>(R.id.setting_header)
|
||||
val titleView = itemView.findViewById<TextView>(R.id.setting_title)
|
||||
val valueView = itemView.findViewById<TextView>(R.id.setting_value)
|
||||
val expandIcon = itemView.findViewById<android.widget.ImageView>(R.id.expand_icon)
|
||||
val radioGroup = itemView.findViewById<RadioGroup>(R.id.radio_group)
|
||||
|
||||
titleView.text = title
|
||||
|
||||
var current = ""
|
||||
if (selectedIndex in choices.indices) {
|
||||
current = choices[selectedIndex]
|
||||
}
|
||||
valueView.text = current
|
||||
headerView.visibility = View.VISIBLE
|
||||
|
||||
var isExpanded = false
|
||||
choices.forEachIndexed { index, name ->
|
||||
val radioButton = com.google.android.material.radiobutton.MaterialRadioButton(
|
||||
emulationFragment.requireContext()
|
||||
)
|
||||
radioButton.text = name
|
||||
radioButton.id = View.generateViewId()
|
||||
radioButton.isChecked = index == selectedIndex
|
||||
radioButton.setPadding(16, 8, 16, 8)
|
||||
|
||||
radioButton.setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked) {
|
||||
valueView.text = name
|
||||
onSelected(index)
|
||||
}
|
||||
}
|
||||
radioGroup.addView(radioButton)
|
||||
}
|
||||
|
||||
headerView.setOnClickListener {
|
||||
isExpanded = !isExpanded
|
||||
if (isExpanded) {
|
||||
radioGroup.visibility = View.VISIBLE
|
||||
expandIcon.animate().rotation(180f).setDuration(200).start()
|
||||
} else {
|
||||
radioGroup.visibility = View.GONE
|
||||
expandIcon.animate().rotation(0f).setDuration(200).start()
|
||||
}
|
||||
}
|
||||
|
||||
container.addView(itemView)
|
||||
}
|
||||
|
||||
fun addStepSlider(
|
||||
title: String,
|
||||
container: ViewGroup,
|
||||
steps: Int,
|
||||
selectedStep: Int,
|
||||
describe: (Int) -> String,
|
||||
onCommitted: (Int) -> Unit,
|
||||
onChanged: (Int) -> Unit
|
||||
) {
|
||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
||||
val itemView = inflater.inflate(R.layout.item_quick_settings_menu, container, false)
|
||||
|
||||
val sliderContainer = itemView.findViewById<ViewGroup>(R.id.slider_container)
|
||||
val titleView = itemView.findViewById<TextView>(R.id.slider_title)
|
||||
val valueDisplay = itemView.findViewById<TextView>(R.id.slider_value_display)
|
||||
val slider = itemView.findViewById<com.google.android.material.slider.Slider>(
|
||||
R.id.setting_slider
|
||||
)
|
||||
|
||||
titleView.text = title
|
||||
sliderContainer.visibility = View.VISIBLE
|
||||
|
||||
slider.valueFrom = 0f
|
||||
slider.valueTo = steps.toFloat()
|
||||
slider.stepSize = 1f
|
||||
slider.value = selectedStep.toFloat().coerceIn(0f, steps.toFloat())
|
||||
valueDisplay.text = describe(slider.value.toInt())
|
||||
|
||||
slider.addOnChangeListener { _, value, fromUser ->
|
||||
if (fromUser) {
|
||||
val step = value.toInt()
|
||||
onChanged(step)
|
||||
valueDisplay.text = describe(step)
|
||||
}
|
||||
}
|
||||
|
||||
var pressedValue = slider.value
|
||||
|
||||
slider.setOnTouchListener { _, event ->
|
||||
val drawer = emulationFragment.view?.findViewById<DrawerLayout>(R.id.drawer_layout)
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
drawer?.requestDisallowInterceptTouchEvent(true)
|
||||
pressedValue = slider.value
|
||||
}
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||
drawer?.requestDisallowInterceptTouchEvent(false)
|
||||
if (slider.value != pressedValue) {
|
||||
onCommitted(slider.value.toInt())
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
container.addView(itemView)
|
||||
}
|
||||
|
||||
fun addShaderCard(
|
||||
index: Int,
|
||||
title: String,
|
||||
summary: String,
|
||||
container: ViewGroup,
|
||||
onRemove: () -> Unit
|
||||
): ViewGroup {
|
||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
||||
val itemView = inflater.inflate(R.layout.item_quick_settings_shader, container, false)
|
||||
|
||||
val headerView = itemView.findViewById<ViewGroup>(R.id.shader_header)
|
||||
val titleView = itemView.findViewById<TextView>(R.id.shader_title)
|
||||
val summaryView = itemView.findViewById<TextView>(R.id.shader_summary)
|
||||
val removeView = itemView.findViewById<android.widget.ImageView>(R.id.shader_remove)
|
||||
val expandIcon = itemView.findViewById<android.widget.ImageView>(R.id.shader_expand)
|
||||
val bodyView = itemView.findViewById<ViewGroup>(R.id.shader_body)
|
||||
|
||||
titleView.text = title
|
||||
if (summary.isEmpty()) {
|
||||
summaryView.visibility = View.GONE
|
||||
} else {
|
||||
summaryView.text = summary
|
||||
}
|
||||
|
||||
var isExpanded = expandedShaders.contains(index)
|
||||
if (isExpanded) {
|
||||
bodyView.visibility = View.VISIBLE
|
||||
expandIcon.rotation = 180f
|
||||
}
|
||||
|
||||
headerView.setOnClickListener {
|
||||
isExpanded = !isExpanded
|
||||
if (isExpanded) {
|
||||
expandedShaders.add(index)
|
||||
bodyView.visibility = View.VISIBLE
|
||||
expandIcon.animate().rotation(180f).setDuration(200).start()
|
||||
} else {
|
||||
expandedShaders.remove(index)
|
||||
bodyView.visibility = View.GONE
|
||||
expandIcon.animate().rotation(0f).setDuration(200).start()
|
||||
}
|
||||
}
|
||||
|
||||
removeView.setOnClickListener {
|
||||
onRemove()
|
||||
}
|
||||
|
||||
container.addView(itemView)
|
||||
return bodyView
|
||||
}
|
||||
|
||||
fun addEffectPicker(
|
||||
container: ViewGroup,
|
||||
choices: List<String>,
|
||||
hasEffects: Boolean,
|
||||
onRemoveAll: () -> Unit,
|
||||
onPicked: (Int) -> Unit
|
||||
) {
|
||||
val context = emulationFragment.requireContext()
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val itemView = inflater.inflate(R.layout.item_quick_settings_add, container, false)
|
||||
|
||||
val button = itemView.findViewById<com.google.android.material.button.MaterialButton>(
|
||||
R.id.add_button
|
||||
)
|
||||
val removeButton =
|
||||
itemView.findViewById<com.google.android.material.button.MaterialButton>(
|
||||
R.id.remove_all_button
|
||||
)
|
||||
val choiceGroup = itemView.findViewById<RadioGroup>(R.id.add_choices)
|
||||
|
||||
choices.forEachIndexed { index, name ->
|
||||
val radioButton = com.google.android.material.radiobutton.MaterialRadioButton(context)
|
||||
radioButton.text = name
|
||||
radioButton.id = View.generateViewId()
|
||||
radioButton.setPadding(16, 8, 16, 8)
|
||||
radioButton.setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked) {
|
||||
onPicked(index)
|
||||
}
|
||||
}
|
||||
choiceGroup.addView(radioButton)
|
||||
}
|
||||
|
||||
var closedLabel = R.string.post_processing_add
|
||||
if (hasEffects) {
|
||||
closedLabel = R.string.post_processing_open_list
|
||||
removeButton.visibility = View.VISIBLE
|
||||
}
|
||||
button.setText(closedLabel)
|
||||
|
||||
val removeBackground = MaterialColors.getColor(
|
||||
removeButton,
|
||||
com.google.android.material.R.attr.colorErrorContainer
|
||||
)
|
||||
val removeForeground = MaterialColors.getColor(
|
||||
removeButton,
|
||||
com.google.android.material.R.attr.colorOnErrorContainer
|
||||
)
|
||||
removeButton.backgroundTintList = ColorStateList.valueOf(removeBackground)
|
||||
removeButton.setTextColor(removeForeground)
|
||||
removeButton.iconTint = ColorStateList.valueOf(removeForeground)
|
||||
removeButton.setOnClickListener {
|
||||
onRemoveAll()
|
||||
}
|
||||
|
||||
val slide = context.resources.displayMetrics.density * 24.0f
|
||||
|
||||
var isOpen = false
|
||||
button.setOnClickListener {
|
||||
isOpen = !isOpen
|
||||
if (isOpen) {
|
||||
choiceGroup.alpha = 0.0f
|
||||
choiceGroup.translationY = slide
|
||||
choiceGroup.visibility = View.VISIBLE
|
||||
choiceGroup.animate()
|
||||
.alpha(1.0f)
|
||||
.translationY(0.0f)
|
||||
.setDuration(220)
|
||||
.withEndAction {
|
||||
choiceGroup.requestRectangleOnScreen(
|
||||
Rect(0, 0, choiceGroup.width, choiceGroup.height),
|
||||
false
|
||||
)
|
||||
}
|
||||
.start()
|
||||
|
||||
button.setText(R.string.post_processing_close_list)
|
||||
button.setIconResource(R.drawable.ic_clear)
|
||||
} else {
|
||||
choiceGroup.animate()
|
||||
.alpha(0.0f)
|
||||
.translationY(slide)
|
||||
.setDuration(160)
|
||||
.withEndAction {
|
||||
choiceGroup.visibility = View.GONE
|
||||
}
|
||||
.start()
|
||||
|
||||
button.setText(closedLabel)
|
||||
button.setIconResource(R.drawable.ic_add)
|
||||
}
|
||||
}
|
||||
|
||||
container.addView(itemView)
|
||||
}
|
||||
|
||||
fun addPresetBand(container: ViewGroup, name: String, summary: String) {
|
||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
||||
val itemView = inflater.inflate(R.layout.item_quick_settings_preset, container, false)
|
||||
|
||||
val titleView = itemView.findViewById<TextView>(R.id.preset_title)
|
||||
val summaryView = itemView.findViewById<TextView>(R.id.preset_summary)
|
||||
val switchView = itemView.findViewById<MaterialSwitch>(R.id.preset_switch)
|
||||
|
||||
titleView.text = name
|
||||
if (summary.isEmpty()) {
|
||||
summaryView.visibility = View.GONE
|
||||
} else {
|
||||
summaryView.text = summary
|
||||
}
|
||||
|
||||
switchView.isChecked = NativePostProcessing.isEnabled()
|
||||
switchView.setOnCheckedChangeListener { _, checked ->
|
||||
emulationFragment.editPostProcessing {
|
||||
NativePostProcessing.setEnabled(checked)
|
||||
}
|
||||
}
|
||||
|
||||
container.addView(itemView)
|
||||
}
|
||||
|
||||
fun addPostProcessing(container: ViewGroup, onStructureChanged: () -> Unit) {
|
||||
val usable = NativePostProcessing.catalog().filter { it.valid }
|
||||
if (usable.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val preset = NativePostProcessing.getActivePreset()
|
||||
if (preset.isNotEmpty()) {
|
||||
addDivider(container)
|
||||
|
||||
var summary = ""
|
||||
val described = NativePostProcessing.presets().firstOrNull { it.name == preset }
|
||||
if (described != null) {
|
||||
summary = described.description
|
||||
}
|
||||
if (summary.isEmpty()) {
|
||||
summary =
|
||||
YuzuApplication.appContext.getString(R.string.post_processing_preset_locked)
|
||||
}
|
||||
if (NativePostProcessing.isPresetModified()) {
|
||||
summary = summary + "\n" +
|
||||
YuzuApplication.appContext.getString(R.string.post_processing_preset_modified)
|
||||
}
|
||||
|
||||
addPresetBand(container, preset, summary)
|
||||
return
|
||||
}
|
||||
|
||||
val labels = mutableListOf<String>()
|
||||
val files = mutableListOf<String>()
|
||||
val techniques = mutableListOf<String>()
|
||||
|
||||
for (effect in usable) {
|
||||
for (technique in effect.techniques) {
|
||||
var label = effect.label
|
||||
if (effect.techniques.size > 1) {
|
||||
label = effect.label + " \u00b7 " + technique
|
||||
}
|
||||
labels.add(label)
|
||||
files.add(effect.file)
|
||||
techniques.add(technique)
|
||||
}
|
||||
}
|
||||
|
||||
addDivider(container)
|
||||
|
||||
val chain = NativePostProcessing.chain()
|
||||
chain.forEachIndexed { index, entry ->
|
||||
val effect = usable.firstOrNull { it.file == entry.file }
|
||||
|
||||
var title = entry.file
|
||||
var summary = ""
|
||||
if (effect != null) {
|
||||
title = effect.label
|
||||
if (effect.techniques.size > 1) {
|
||||
title = effect.label + " \u00b7 " + entry.technique
|
||||
}
|
||||
summary = effect.description
|
||||
}
|
||||
|
||||
val body = addShaderCard(index, title, summary, container) {
|
||||
emulationFragment.editPostProcessing {
|
||||
NativePostProcessing.remove(index)
|
||||
}
|
||||
forgetShaderSlot(index)
|
||||
onStructureChanged()
|
||||
}
|
||||
|
||||
if (effect != null) {
|
||||
for (uniform in effect.uniforms) {
|
||||
addUniformSliders(body, index, uniform)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addEffectPicker(
|
||||
container,
|
||||
labels,
|
||||
chain.isNotEmpty(),
|
||||
{
|
||||
emulationFragment.editPostProcessing {
|
||||
NativePostProcessing.clearChain()
|
||||
}
|
||||
expandedShaders.clear()
|
||||
onStructureChanged()
|
||||
}
|
||||
) { picked ->
|
||||
emulationFragment.editPostProcessing {
|
||||
NativePostProcessing.append(files[picked], techniques[picked])
|
||||
}
|
||||
onStructureChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addUniformSliders(
|
||||
container: ViewGroup,
|
||||
index: Int,
|
||||
uniform: NativePostProcessing.Uniform
|
||||
) {
|
||||
if (uniform.uiType == NativePostProcessing.UI_HIDDEN) {
|
||||
return
|
||||
}
|
||||
|
||||
for (component in 0 until uniform.components) {
|
||||
var title = uniform.label
|
||||
if (uniform.components > 1) {
|
||||
title = uniform.label + " [" + component + "]"
|
||||
}
|
||||
|
||||
var value = uniform.defaultAt(component)
|
||||
if (NativePostProcessing.hasValue(index, uniform.name)) {
|
||||
value = NativePostProcessing.getValue(index, uniform.name, component)
|
||||
}
|
||||
|
||||
val steps = uniform.steps
|
||||
val step = Math.round((value - uniform.min) / uniform.step)
|
||||
|
||||
addStepSlider(
|
||||
title,
|
||||
container,
|
||||
steps,
|
||||
step,
|
||||
{ position -> uniform.describe(position) },
|
||||
{ emulationFragment.persistPostProcessing() }
|
||||
) { position ->
|
||||
NativePostProcessing.setValue(
|
||||
index,
|
||||
uniform.name,
|
||||
component,
|
||||
uniform.min + position * uniform.step
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addFrameGenCell(inflater: LayoutInflater, row: ViewGroup): TextView {
|
||||
val cell = inflater.inflate(R.layout.item_quick_settings_frame_gen_cell, row, false)
|
||||
as TextView
|
||||
row.addView(cell)
|
||||
return cell
|
||||
}
|
||||
|
||||
fun addFrameGen(container: ViewGroup) {
|
||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
||||
val itemView = inflater.inflate(R.layout.item_quick_settings_frame_gen, container, false)
|
||||
|
||||
val multiplierRow = itemView.findViewById<LinearLayout>(R.id.frame_gen_multipliers)
|
||||
val targetRow = itemView.findViewById<LinearLayout>(R.id.frame_gen_targets)
|
||||
val targetSection = itemView.findViewById<ViewGroup>(R.id.frame_gen_target_section)
|
||||
val flowRow = itemView.findViewById<LinearLayout>(R.id.frame_gen_flow)
|
||||
val flowSection = itemView.findViewById<ViewGroup>(R.id.frame_gen_flow_section)
|
||||
|
||||
val multiplierNames =
|
||||
emulationFragment.resources.getStringArray(R.array.frameGenMultiplierNames)
|
||||
val multiplierValues =
|
||||
emulationFragment.resources.getIntArray(R.array.frameGenMultiplierValues)
|
||||
val targetValues =
|
||||
emulationFragment.resources.getIntArray(R.array.frameGenTargetRateValues)
|
||||
val flowValues =
|
||||
emulationFragment.resources.getIntArray(R.array.frameGenFlowScaleValues)
|
||||
|
||||
val columns = maxOf(
|
||||
multiplierValues.size + 1,
|
||||
targetValues.size,
|
||||
flowValues.size + 1
|
||||
).toFloat()
|
||||
multiplierRow.weightSum = columns
|
||||
targetRow.weightSum = columns
|
||||
flowRow.weightSum = columns
|
||||
|
||||
val powerCell = addFrameGenCell(inflater, multiplierRow)
|
||||
|
||||
val multiplierCells = mutableListOf<TextView>()
|
||||
for (name in multiplierNames) {
|
||||
val cell = addFrameGenCell(inflater, multiplierRow)
|
||||
cell.text = name
|
||||
multiplierCells.add(cell)
|
||||
}
|
||||
|
||||
val targetCells = mutableListOf<TextView>()
|
||||
for (value in targetValues) {
|
||||
val cell = addFrameGenCell(inflater, targetRow)
|
||||
if (value == 0) {
|
||||
cell.setText(R.string.frame_gen_fixed)
|
||||
} else {
|
||||
cell.text = value.toString()
|
||||
}
|
||||
targetCells.add(cell)
|
||||
}
|
||||
|
||||
val autoCell = addFrameGenCell(inflater, flowRow)
|
||||
autoCell.setText(R.string.frame_gen_flow_auto)
|
||||
|
||||
val flowCells = mutableListOf<TextView>()
|
||||
for (value in flowValues) {
|
||||
val cell = addFrameGenCell(inflater, flowRow)
|
||||
cell.text = "$value%"
|
||||
flowCells.add(cell)
|
||||
}
|
||||
|
||||
val inactiveAlpha = 0.38f
|
||||
|
||||
fun refresh() {
|
||||
val enabled = BooleanSetting.RENDERER_FRAME_GEN.getBoolean(needsGlobal = false)
|
||||
val multiplier = IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.getInt(needsGlobal = false)
|
||||
val target = IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.getInt(needsGlobal = false)
|
||||
val fixed = target == 0
|
||||
val flowAuto =
|
||||
BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.getBoolean(needsGlobal = false)
|
||||
val flowScale = IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE.getInt(needsGlobal = false)
|
||||
|
||||
var powerLabel = R.string.frame_gen_off
|
||||
var rowAlpha = inactiveAlpha
|
||||
if (enabled) {
|
||||
powerLabel = R.string.frame_gen_on
|
||||
rowAlpha = 1.0f
|
||||
}
|
||||
|
||||
var multiplierAlpha = inactiveAlpha
|
||||
if (enabled && fixed) {
|
||||
multiplierAlpha = 1.0f
|
||||
}
|
||||
|
||||
powerCell.setText(powerLabel)
|
||||
powerCell.isSelected = enabled
|
||||
|
||||
multiplierCells.forEachIndexed { index, cell ->
|
||||
cell.isEnabled = enabled
|
||||
cell.isSelected = enabled && fixed && multiplierValues[index] == multiplier
|
||||
cell.alpha = multiplierAlpha
|
||||
}
|
||||
|
||||
targetSection.alpha = rowAlpha
|
||||
targetCells.forEachIndexed { index, cell ->
|
||||
cell.isEnabled = enabled
|
||||
cell.isSelected = enabled && targetValues[index] == target
|
||||
}
|
||||
|
||||
flowSection.alpha = rowAlpha
|
||||
autoCell.isEnabled = enabled
|
||||
autoCell.isSelected = enabled && flowAuto
|
||||
|
||||
flowCells.forEachIndexed { index, cell ->
|
||||
cell.isEnabled = enabled
|
||||
cell.isSelected = enabled && !flowAuto && flowValues[index] == flowScale
|
||||
}
|
||||
}
|
||||
|
||||
powerCell.setOnClickListener {
|
||||
if (BooleanSetting.RENDERER_FRAME_GEN.getBoolean(needsGlobal = false)) {
|
||||
BooleanSetting.RENDERER_FRAME_GEN.setBoolean(false)
|
||||
} else {
|
||||
IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.setInt(multiplierValues.first())
|
||||
IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.setInt(0)
|
||||
BooleanSetting.RENDERER_FRAME_GEN.setBoolean(true)
|
||||
}
|
||||
saveSettings()
|
||||
refresh()
|
||||
}
|
||||
|
||||
multiplierCells.forEachIndexed { index, cell ->
|
||||
cell.setOnClickListener {
|
||||
IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.setInt(multiplierValues[index])
|
||||
IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.setInt(0)
|
||||
saveSettings()
|
||||
refresh()
|
||||
}
|
||||
}
|
||||
|
||||
targetCells.forEachIndexed { index, cell ->
|
||||
cell.setOnClickListener {
|
||||
IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.setInt(targetValues[index])
|
||||
saveSettings()
|
||||
refresh()
|
||||
}
|
||||
}
|
||||
|
||||
autoCell.setOnClickListener {
|
||||
BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.setBoolean(true)
|
||||
saveSettings()
|
||||
refresh()
|
||||
}
|
||||
|
||||
flowCells.forEachIndexed { index, cell ->
|
||||
cell.setOnClickListener {
|
||||
IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE.setInt(flowValues[index])
|
||||
BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.setBoolean(false)
|
||||
saveSettings()
|
||||
refresh()
|
||||
}
|
||||
}
|
||||
|
||||
refresh()
|
||||
container.addView(itemView)
|
||||
}
|
||||
|
||||
fun addDivider(container: ViewGroup) {
|
||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
||||
val dividerView = inflater.inflate(R.layout.item_quick_settings_divider, container, false)
|
||||
|
||||
+2
@@ -38,7 +38,9 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||
RENDERER_VERTEX_INPUT_DYNAMIC_STATE("vertex_input_dynamic_state"),
|
||||
RENDERER_SAMPLE_SHADING("sample_shading"),
|
||||
RENDERER_FRAME_GEN("frame_gen"),
|
||||
RENDERER_FRAME_GEN_FP16("frame_gen_fp16"),
|
||||
RENDERER_FRAME_GEN_FLOW_SCALE_AUTO("frame_gen_flow_scale_auto"),
|
||||
RENDERER_FRAME_GEN_DUMP_FLOW("frame_gen_dump_flow"),
|
||||
GPU_UNSWIZZLE_ENABLED("gpu_unswizzle_enabled"),
|
||||
PICTURE_IN_PICTURE("picture_in_picture"),
|
||||
USE_CUSTOM_RTC("custom_rtc_enabled"),
|
||||
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.model
|
||||
|
||||
class FxPresetNameSetting(private val onNamed: (String) -> Unit) : AbstractStringSetting {
|
||||
override val key: String
|
||||
get() = "fx_preset_name"
|
||||
|
||||
override val defaultValue: Any
|
||||
get() = ""
|
||||
|
||||
override val isRuntimeModifiable: Boolean
|
||||
get() = true
|
||||
|
||||
override val pairedSettingKey: String
|
||||
get() = ""
|
||||
|
||||
override val isSwitchable: Boolean
|
||||
get() = false
|
||||
|
||||
override val isSaveable: Boolean
|
||||
get() = true
|
||||
|
||||
override var global: Boolean
|
||||
get() = true
|
||||
set(_) {}
|
||||
|
||||
override fun getString(needsGlobal: Boolean): String = ""
|
||||
|
||||
override fun setString(value: String) = onNamed(value)
|
||||
|
||||
override fun getValueAsString(needsGlobal: Boolean): String = ""
|
||||
|
||||
override fun reset() {}
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.model
|
||||
|
||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
abstract class FxUniformSetting(
|
||||
protected val index: Int,
|
||||
protected val uniform: NativePostProcessing.Uniform,
|
||||
protected val component: Int
|
||||
) : AbstractSetting {
|
||||
override val key: String
|
||||
get() = "fx_${index}_${uniform.name}_$component"
|
||||
|
||||
override val isRuntimeModifiable: Boolean
|
||||
get() = true
|
||||
|
||||
override val pairedSettingKey: String
|
||||
get() = ""
|
||||
|
||||
override val isSwitchable: Boolean
|
||||
get() = false
|
||||
|
||||
override val isSaveable: Boolean
|
||||
get() = true
|
||||
|
||||
override var global: Boolean
|
||||
get() = true
|
||||
set(_) {}
|
||||
|
||||
protected fun currentValue(): Float {
|
||||
if (NativePostProcessing.hasValue(index, uniform.name)) {
|
||||
return NativePostProcessing.getValue(index, uniform.name, component)
|
||||
}
|
||||
return uniform.defaultAt(component)
|
||||
}
|
||||
|
||||
protected fun commit(value: Float) {
|
||||
NativePostProcessing.setValue(index, uniform.name, component, value)
|
||||
NativePostProcessing.store()
|
||||
}
|
||||
|
||||
override fun reset() = commit(uniform.defaultAt(component))
|
||||
}
|
||||
|
||||
class FxUniformSliderSetting(
|
||||
index: Int,
|
||||
uniform: NativePostProcessing.Uniform,
|
||||
component: Int
|
||||
) : FxUniformSetting(index, uniform, component), AbstractIntSetting {
|
||||
override val defaultValue: Any
|
||||
get() = ((uniform.defaultAt(component) - uniform.min) / uniform.step).roundToInt()
|
||||
|
||||
override fun getInt(needsGlobal: Boolean): Int =
|
||||
((currentValue() - uniform.min) / uniform.step).roundToInt()
|
||||
|
||||
override fun setInt(value: Int) = commit(uniform.min + value * uniform.step)
|
||||
|
||||
override fun getValueAsString(needsGlobal: Boolean): String {
|
||||
if (uniform.kind == NativePostProcessing.KIND_FLOAT) {
|
||||
return String.format("%.3f", currentValue())
|
||||
}
|
||||
return currentValue().roundToInt().toString()
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ object Settings {
|
||||
SECTION_SYSTEM(R.string.preferences_system),
|
||||
SECTION_RENDERER(R.string.preferences_graphics),
|
||||
SECTION_FRAME_GEN(R.string.frame_gen),
|
||||
SECTION_POST_PROCESSING(R.string.post_processing),
|
||||
SECTION_PERFORMANCE_STATS(R.string.stats_overlay_options),
|
||||
SECTION_INPUT_OVERLAY(R.string.input_overlay_options),
|
||||
SECTION_SOC_OVERLAY(R.string.soc_overlay_options),
|
||||
|
||||
-1
@@ -13,7 +13,6 @@ enum class StringSetting(override val key: String) : AbstractStringSetting {
|
||||
DEVICE_NAME("device_name"),
|
||||
LOG_FILTER("log_filter"),
|
||||
PROGRAM_ARGS("program_args"),
|
||||
POST_SHADER_CHAIN("post_shader_chain"),
|
||||
|
||||
WEB_TOKEN("eden_token"),
|
||||
WEB_USERNAME("eden_username")
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
|
||||
class FxButtonSetting(
|
||||
@StringRes titleId: Int,
|
||||
val onClick: () -> Unit
|
||||
) : SettingsItem(emptySetting, titleId, "", 0, "") {
|
||||
override val type = TYPE_FX_BUTTON
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||
|
||||
class FxPresetSetting(
|
||||
titleString: String,
|
||||
descriptionString: String = "",
|
||||
val deletable: Boolean = false,
|
||||
val onApply: () -> Unit,
|
||||
val onDelete: () -> Unit = {}
|
||||
) : SettingsItem(emptySetting, 0, titleString, 0, descriptionString) {
|
||||
override val type = TYPE_FX_PRESET
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||
|
||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
||||
|
||||
class FxShaderCardSetting(
|
||||
titleString: String,
|
||||
descriptionString: String,
|
||||
val index: Int,
|
||||
val expanded: Boolean,
|
||||
val uniforms: List<NativePostProcessing.Uniform>,
|
||||
val onToggle: () -> Unit,
|
||||
val onRemove: () -> Unit,
|
||||
val onReset: () -> Unit
|
||||
) : SettingsItem(emptySetting, 0, titleString, 0, descriptionString) {
|
||||
override val type = TYPE_FX_SHADER
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
|
||||
class FxToolbarSetting(
|
||||
@StringRes val addLabelId: Int,
|
||||
val listOpen: Boolean,
|
||||
val presetLabel: String,
|
||||
val hasEffects: Boolean,
|
||||
val createPreset: StringInputSetting,
|
||||
val onAdd: () -> Unit,
|
||||
val onPresets: () -> Unit,
|
||||
val onRemoveAll: () -> Unit
|
||||
) : SettingsItem(emptySetting, 0, "", 0, "") {
|
||||
override val type = TYPE_FX_TOOLBAR
|
||||
}
|
||||
+17
-5
@@ -123,7 +123,9 @@ abstract class SettingsItem(
|
||||
IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key,
|
||||
IntSetting.RENDERER_FRAME_GEN_QUEUE_TARGET.key,
|
||||
BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.key,
|
||||
IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE.key
|
||||
IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE.key,
|
||||
BooleanSetting.RENDERER_FRAME_GEN_FP16.key,
|
||||
BooleanSetting.RENDERER_FRAME_GEN_DUMP_FLOW.key
|
||||
)
|
||||
|
||||
const val TYPE_HEADER = 0
|
||||
@@ -142,10 +144,6 @@ abstract class SettingsItem(
|
||||
const val TYPE_LAUNCHABLE = 13
|
||||
const val TYPE_PATH = 14
|
||||
const val TYPE_GPU_UNSWIZZLE = 15
|
||||
const val TYPE_FX_TOOLBAR = 16
|
||||
const val TYPE_FX_PRESET = 17
|
||||
const val TYPE_FX_SHADER = 18
|
||||
const val TYPE_FX_BUTTON = 19
|
||||
|
||||
const val FASTMEM_COMBINED = "fastmem_combined"
|
||||
const val GPU_UNSWIZZLE_COMBINED = "gpu_unswizzle_combined"
|
||||
@@ -707,6 +705,20 @@ abstract class SettingsItem(
|
||||
units = "%"
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.RENDERER_FRAME_GEN_FP16,
|
||||
titleId = R.string.frame_gen_fp16,
|
||||
descriptionId = R.string.frame_gen_fp16_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.RENDERER_FRAME_GEN_DUMP_FLOW,
|
||||
titleId = R.string.frame_gen_dump_flow,
|
||||
descriptionId = R.string.frame_gen_dump_flow_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.RENDERER_SCREEN_LAYOUT,
|
||||
|
||||
-32
@@ -23,10 +23,6 @@ import com.google.android.material.timepicker.TimeFormat
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.SettingsNavigationDirections
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxButtonBinding
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxPresetBinding
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxShaderBinding
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxToolbarBinding
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingInputBinding
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingsHeaderBinding
|
||||
@@ -110,34 +106,6 @@ class SettingsAdapter(
|
||||
GpuUnswizzleViewHolder(ListItemSettingBinding.inflate(inflater), this)
|
||||
}
|
||||
|
||||
SettingsItem.TYPE_FX_TOOLBAR -> {
|
||||
FxToolbarViewHolder(
|
||||
ListItemSettingFxToolbarBinding.inflate(inflater, parent, false),
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
SettingsItem.TYPE_FX_PRESET -> {
|
||||
FxPresetViewHolder(
|
||||
ListItemSettingFxPresetBinding.inflate(inflater, parent, false),
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
SettingsItem.TYPE_FX_SHADER -> {
|
||||
FxShaderCardViewHolder(
|
||||
ListItemSettingFxShaderBinding.inflate(inflater, parent, false),
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
SettingsItem.TYPE_FX_BUTTON -> {
|
||||
FxButtonViewHolder(
|
||||
ListItemSettingFxButtonBinding.inflate(inflater, parent, false),
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this)
|
||||
}
|
||||
|
||||
+2
-214
@@ -18,7 +18,6 @@ import org.yuzu.yuzu_emu.features.input.model.NpadStyleIndex
|
||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.FxPresetNameSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.ByteSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.LongSetting
|
||||
@@ -31,7 +30,6 @@ import org.yuzu.yuzu_emu.features.settings.model.view.*
|
||||
import org.yuzu.yuzu_emu.utils.InputHandler
|
||||
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
||||
import org.yuzu.yuzu_emu.utils.FullscreenHelper
|
||||
import androidx.core.content.edit
|
||||
@@ -46,14 +44,6 @@ class SettingsFragmentPresenter(
|
||||
) {
|
||||
private var settingsList = ArrayList<SettingsItem>()
|
||||
|
||||
private val expandedShaderSlots = mutableSetOf<Int>()
|
||||
|
||||
private var shaderPickerOpen = false
|
||||
|
||||
private var presetPickerOpen = false
|
||||
|
||||
private var postProcessingSynced = false
|
||||
|
||||
private val context get() = YuzuApplication.appContext
|
||||
|
||||
// Extension for altering settings list based on each setting's properties
|
||||
@@ -124,6 +114,7 @@ class SettingsFragmentPresenter(
|
||||
) {
|
||||
add(IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE.key)
|
||||
}
|
||||
add(BooleanSetting.RENDERER_FRAME_GEN_FP16.key)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +163,6 @@ class SettingsFragmentPresenter(
|
||||
MenuTag.SECTION_SYSTEM -> addSystemSettings(sl)
|
||||
MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl)
|
||||
MenuTag.SECTION_FRAME_GEN -> addFrameGenSettings(sl)
|
||||
MenuTag.SECTION_POST_PROCESSING -> addPostProcessingSettings(sl)
|
||||
MenuTag.SECTION_PERFORMANCE_STATS -> addPerformanceOverlaySettings(sl)
|
||||
MenuTag.SECTION_SOC_OVERLAY -> addSocOverlaySettings(sl)
|
||||
MenuTag.SECTION_INPUT_OVERLAY -> addInputOverlaySettings(sl)
|
||||
@@ -200,209 +190,6 @@ class SettingsFragmentPresenter(
|
||||
}
|
||||
}
|
||||
|
||||
private fun addPostProcessingSettings(sl: ArrayList<SettingsItem>) {
|
||||
if (!postProcessingSynced) {
|
||||
postProcessingSynced = true
|
||||
NativePostProcessing.reload()
|
||||
}
|
||||
|
||||
val usable = NativePostProcessing.catalog().filter { it.valid }
|
||||
|
||||
sl.apply {
|
||||
if (usable.isEmpty()) {
|
||||
add(
|
||||
RunnableSetting(
|
||||
titleId = R.string.post_processing_empty,
|
||||
descriptionString = NativePostProcessing.getShaderDirectory(),
|
||||
isRunnable = false
|
||||
) {}
|
||||
)
|
||||
return@apply
|
||||
}
|
||||
|
||||
val labels = mutableListOf<String>()
|
||||
val summaries = mutableListOf<String>()
|
||||
val files = mutableListOf<String>()
|
||||
val techniques = mutableListOf<String>()
|
||||
for (effect in usable) {
|
||||
for (technique in effect.techniques) {
|
||||
if (effect.techniques.size == 1) {
|
||||
labels.add(effect.label)
|
||||
} else {
|
||||
labels.add(effect.label + " \u00b7 " + technique)
|
||||
}
|
||||
summaries.add(effect.description)
|
||||
files.add(effect.file)
|
||||
techniques.add(technique)
|
||||
}
|
||||
}
|
||||
|
||||
val chain = NativePostProcessing.chain()
|
||||
val active = NativePostProcessing.getActivePreset()
|
||||
|
||||
var addLabel = R.string.post_processing_add
|
||||
if (chain.isNotEmpty()) {
|
||||
addLabel = R.string.post_processing_open_list
|
||||
}
|
||||
if (shaderPickerOpen) {
|
||||
addLabel = R.string.post_processing_close_list
|
||||
}
|
||||
|
||||
var presetLabel = context.getString(R.string.post_processing_presets)
|
||||
if (active.isNotEmpty()) {
|
||||
presetLabel = active
|
||||
}
|
||||
|
||||
val createPreset = StringInputSetting(
|
||||
setting = FxPresetNameSetting { name ->
|
||||
NativePostProcessing.savePreset(name, "")
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
},
|
||||
titleId = R.string.post_processing_preset_new,
|
||||
descriptionId = R.string.post_processing_preset_new_description,
|
||||
validator = { it != null && it.isNotBlank() && !it.contains('=') },
|
||||
errorId = R.string.post_processing_preset_name_invalid
|
||||
)
|
||||
|
||||
add(
|
||||
FxToolbarSetting(
|
||||
addLabelId = addLabel,
|
||||
listOpen = shaderPickerOpen,
|
||||
presetLabel = presetLabel,
|
||||
hasEffects = chain.isNotEmpty(),
|
||||
createPreset = createPreset,
|
||||
onAdd = {
|
||||
shaderPickerOpen = !shaderPickerOpen
|
||||
presetPickerOpen = false
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
},
|
||||
onPresets = {
|
||||
presetPickerOpen = !presetPickerOpen
|
||||
shaderPickerOpen = false
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
},
|
||||
onRemoveAll = {
|
||||
NativePostProcessing.clearChain()
|
||||
NativePostProcessing.clearPreset()
|
||||
NativePostProcessing.store()
|
||||
expandedShaderSlots.clear()
|
||||
shaderPickerOpen = false
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
if (shaderPickerOpen) {
|
||||
for (choice in labels.indices) {
|
||||
add(
|
||||
RunnableSetting(
|
||||
titleString = labels[choice],
|
||||
descriptionString = summaries[choice],
|
||||
isRunnable = true
|
||||
) {
|
||||
NativePostProcessing.append(files[choice], techniques[choice])
|
||||
NativePostProcessing.store()
|
||||
shaderPickerOpen = false
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (presetPickerOpen) {
|
||||
add(
|
||||
FxPresetSetting(
|
||||
titleString = context.getString(R.string.post_processing_preset_none),
|
||||
onApply = {
|
||||
NativePostProcessing.clearPreset()
|
||||
presetPickerOpen = false
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
}
|
||||
)
|
||||
)
|
||||
for (preset in NativePostProcessing.presets()) {
|
||||
add(
|
||||
FxPresetSetting(
|
||||
titleString = preset.name,
|
||||
descriptionString = preset.description,
|
||||
deletable = !preset.bundled,
|
||||
onApply = {
|
||||
NativePostProcessing.applyPreset(preset.name)
|
||||
NativePostProcessing.store()
|
||||
presetPickerOpen = false
|
||||
expandedShaderSlots.clear()
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
},
|
||||
onDelete = {
|
||||
NativePostProcessing.deletePreset(preset.name)
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (active.isNotEmpty()) {
|
||||
add(
|
||||
FxButtonSetting(titleId = R.string.post_processing_preset_reset) {
|
||||
NativePostProcessing.applyPreset(active)
|
||||
NativePostProcessing.store()
|
||||
expandedShaderSlots.clear()
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
for (index in chain.indices) {
|
||||
val entry = chain[index]
|
||||
val effect = usable.firstOrNull { it.file == entry.file }
|
||||
|
||||
var header = entry.file
|
||||
var summary = ""
|
||||
var uniforms = emptyList<NativePostProcessing.Uniform>()
|
||||
if (effect != null) {
|
||||
header = effect.label
|
||||
if (effect.techniques.size > 1) {
|
||||
header = effect.label + " \u00b7 " + entry.technique
|
||||
}
|
||||
summary = effect.description
|
||||
uniforms = effect.uniforms
|
||||
}
|
||||
|
||||
val isOpen = expandedShaderSlots.contains(index)
|
||||
|
||||
add(
|
||||
FxShaderCardSetting(
|
||||
titleString = header,
|
||||
descriptionString = summary,
|
||||
index = index,
|
||||
expanded = isOpen,
|
||||
uniforms = uniforms,
|
||||
onToggle = {
|
||||
if (isOpen) {
|
||||
expandedShaderSlots.remove(index)
|
||||
} else {
|
||||
expandedShaderSlots.add(index)
|
||||
}
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
},
|
||||
onRemove = {
|
||||
NativePostProcessing.remove(index)
|
||||
NativePostProcessing.store()
|
||||
expandedShaderSlots.clear()
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
},
|
||||
onReset = {
|
||||
NativePostProcessing.resetValues(index)
|
||||
NativePostProcessing.store()
|
||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
|
||||
sl.apply {
|
||||
add(
|
||||
@@ -1552,6 +1339,7 @@ class SettingsFragmentPresenter(
|
||||
add(BooleanSetting.DUMP_GUEST_SHADERS.key)
|
||||
add(BooleanSetting.GPU_LOG_SHADER_DUMPS.key)
|
||||
add(BooleanSetting.DUMP_MACROS.key)
|
||||
add(BooleanSetting.RENDERER_FRAME_GEN_DUMP_FLOW.key)
|
||||
add(BooleanSetting.GPU_LOG_MEMORY_TRACKING.key)
|
||||
add(BooleanSetting.GPU_LOG_DRIVER_DEBUG.key)
|
||||
add(IntSetting.GPU_LOG_RING_BUFFER_SIZE.key)
|
||||
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
|
||||
|
||||
import android.view.View
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxButtonBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.FxButtonSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
||||
|
||||
class FxButtonViewHolder(
|
||||
val binding: ListItemSettingFxButtonBinding,
|
||||
adapter: SettingsAdapter
|
||||
) : SettingViewHolder(binding.root, adapter) {
|
||||
private lateinit var setting: FxButtonSetting
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
setting = item as FxButtonSetting
|
||||
|
||||
binding.fxButton.text = item.title
|
||||
binding.fxButton.setOnClickListener { setting.onClick.invoke() }
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean = true
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
|
||||
|
||||
import android.view.View
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxPresetBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.FxPresetSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
||||
|
||||
class FxPresetViewHolder(
|
||||
val binding: ListItemSettingFxPresetBinding,
|
||||
adapter: SettingsAdapter
|
||||
) : SettingViewHolder(binding.root, adapter) {
|
||||
private lateinit var setting: FxPresetSetting
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
setting = item as FxPresetSetting
|
||||
|
||||
binding.presetName.text = item.title
|
||||
binding.presetDescription.text = item.description
|
||||
binding.presetDescription.setVisible(item.description.isNotEmpty())
|
||||
|
||||
binding.presetRow.setOnClickListener { setting.onApply.invoke() }
|
||||
|
||||
binding.presetDelete.setVisible(setting.deletable)
|
||||
binding.presetDelete.setOnClickListener { setting.onDelete.invoke() }
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean = true
|
||||
}
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import org.yuzu.yuzu_emu.databinding.ItemSettingFxActionsBinding
|
||||
import org.yuzu.yuzu_emu.databinding.ItemSettingFxSliderBinding
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxShaderBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.FxUniformSliderSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.FxShaderCardSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
||||
|
||||
class FxShaderCardViewHolder(
|
||||
val binding: ListItemSettingFxShaderBinding,
|
||||
adapter: SettingsAdapter
|
||||
) : SettingViewHolder(binding.root, adapter) {
|
||||
private lateinit var setting: FxShaderCardSetting
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
setting = item as FxShaderCardSetting
|
||||
|
||||
binding.shaderTitle.text = item.title
|
||||
binding.shaderSummary.text = item.description
|
||||
binding.shaderSummary.setVisible(item.description.isNotEmpty())
|
||||
|
||||
var rotation = 0f
|
||||
if (setting.expanded) {
|
||||
rotation = 180f
|
||||
}
|
||||
binding.shaderExpand.rotation = rotation
|
||||
|
||||
binding.shaderHeader.setOnClickListener { setting.onToggle.invoke() }
|
||||
binding.shaderRemove.setOnClickListener { setting.onRemove.invoke() }
|
||||
|
||||
binding.shaderBody.removeAllViews()
|
||||
binding.shaderBody.setVisible(setting.expanded)
|
||||
if (!setting.expanded) {
|
||||
return
|
||||
}
|
||||
|
||||
val inflater = LayoutInflater.from(binding.root.context)
|
||||
for (uniform in setting.uniforms) {
|
||||
if (uniform.uiType == NativePostProcessing.UI_HIDDEN) {
|
||||
continue
|
||||
}
|
||||
for (component in 0 until uniform.components) {
|
||||
addSlider(inflater, uniform, component)
|
||||
}
|
||||
}
|
||||
addActions(inflater)
|
||||
}
|
||||
|
||||
private fun addSlider(
|
||||
inflater: LayoutInflater,
|
||||
uniform: NativePostProcessing.Uniform,
|
||||
component: Int
|
||||
) {
|
||||
val row = ItemSettingFxSliderBinding.inflate(inflater, binding.shaderBody, false)
|
||||
val value = FxUniformSliderSetting(setting.index, uniform, component)
|
||||
|
||||
var title = uniform.label
|
||||
if (uniform.components > 1) {
|
||||
title = uniform.label + " [" + component + "]"
|
||||
}
|
||||
row.fxSliderTitle.text = title
|
||||
|
||||
val steps = uniform.steps.toFloat()
|
||||
row.fxSlider.valueFrom = 0f
|
||||
row.fxSlider.valueTo = steps
|
||||
row.fxSlider.stepSize = 1f
|
||||
row.fxSlider.value = value.getInt(false).toFloat().coerceIn(0f, steps)
|
||||
row.fxSliderValue.text = uniform.describe(row.fxSlider.value.toInt())
|
||||
|
||||
row.fxSlider.addOnChangeListener { _, position, fromUser ->
|
||||
if (fromUser) {
|
||||
value.setInt(position.toInt())
|
||||
row.fxSliderValue.text = uniform.describe(position.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
binding.shaderBody.addView(row.root)
|
||||
}
|
||||
|
||||
private fun addActions(inflater: LayoutInflater) {
|
||||
val row = ItemSettingFxActionsBinding.inflate(inflater, binding.shaderBody, false)
|
||||
|
||||
row.fxReset.setOnClickListener { setting.onReset.invoke() }
|
||||
|
||||
binding.shaderBody.addView(row.root)
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean = true
|
||||
}
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.view.View
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxToolbarBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.FxToolbarSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
||||
|
||||
class FxToolbarViewHolder(
|
||||
val binding: ListItemSettingFxToolbarBinding,
|
||||
adapter: SettingsAdapter
|
||||
) : SettingViewHolder(binding.root, adapter) {
|
||||
private lateinit var setting: FxToolbarSetting
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
setting = item as FxToolbarSetting
|
||||
|
||||
binding.fxAdd.setText(setting.addLabelId)
|
||||
var addIcon = R.drawable.ic_add
|
||||
if (setting.listOpen) {
|
||||
addIcon = R.drawable.ic_clear
|
||||
}
|
||||
binding.fxAdd.setIconResource(addIcon)
|
||||
binding.fxAdd.setOnClickListener { setting.onAdd.invoke() }
|
||||
|
||||
binding.fxPresets.text = setting.presetLabel
|
||||
binding.fxPresets.setOnClickListener { setting.onPresets.invoke() }
|
||||
|
||||
binding.fxCreatePreset.isEnabled = setting.hasEffects
|
||||
binding.fxCreatePreset.setOnClickListener {
|
||||
adapter.onStringInputClick(setting.createPreset, bindingAdapterPosition)
|
||||
}
|
||||
|
||||
val removeBackground = MaterialColors.getColor(
|
||||
binding.fxRemoveAll,
|
||||
com.google.android.material.R.attr.colorErrorContainer
|
||||
)
|
||||
val removeForeground = MaterialColors.getColor(
|
||||
binding.fxRemoveAll,
|
||||
com.google.android.material.R.attr.colorOnErrorContainer
|
||||
)
|
||||
binding.fxRemoveAll.backgroundTintList = ColorStateList.valueOf(removeBackground)
|
||||
binding.fxRemoveAll.iconTint = ColorStateList.valueOf(removeForeground)
|
||||
binding.fxRemoveAll.isEnabled = setting.hasEffects
|
||||
binding.fxRemoveAll.setOnClickListener { setting.onRemoveAll.invoke() }
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean = true
|
||||
}
|
||||
@@ -92,10 +92,8 @@ import org.yuzu.yuzu_emu.utils.GameIconUtils
|
||||
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
||||
import org.yuzu.yuzu_emu.utils.InputHandler
|
||||
import org.yuzu.yuzu_emu.utils.Log
|
||||
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
import org.yuzu.yuzu_emu.utils.NativeFreedrenoConfig
|
||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
||||
import org.yuzu.yuzu_emu.utils.ViewUtils
|
||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
||||
import org.yuzu.yuzu_emu.utils.collect
|
||||
@@ -885,8 +883,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
if (shouldUseCustom) {
|
||||
SettingsFile.loadCustomConfig(game!!)
|
||||
}
|
||||
refreshPostProcessing()
|
||||
addQuickSettings()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1091,34 +1087,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
}
|
||||
}
|
||||
|
||||
private fun withPerGameConfig(create: Boolean, action: () -> Unit) {
|
||||
val target = game
|
||||
var owned = false
|
||||
if (target != null && !NativeConfig.isPerGameConfigLoaded()) {
|
||||
if (create || SettingsFile.getCustomSettingsFile(target).exists()) {
|
||||
SettingsFile.loadCustomConfig(target)
|
||||
owned = true
|
||||
}
|
||||
}
|
||||
action()
|
||||
if (owned) {
|
||||
NativeConfig.unloadPerGameConfig()
|
||||
}
|
||||
}
|
||||
|
||||
fun refreshPostProcessing() = withPerGameConfig(false) {
|
||||
NativePostProcessing.reload()
|
||||
}
|
||||
|
||||
fun persistPostProcessing() = withPerGameConfig(true) {
|
||||
NativePostProcessing.persist()
|
||||
}
|
||||
|
||||
fun editPostProcessing(action: () -> Unit) = withPerGameConfig(true) {
|
||||
action()
|
||||
NativePostProcessing.persist()
|
||||
}
|
||||
|
||||
private fun addQuickSettings() {
|
||||
binding.quickSettingsSheet.apply {
|
||||
val container = binding.quickSettingsSheet.findViewById<ViewGroup>(R.id.quick_settings_container)
|
||||
@@ -1189,11 +1157,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
|
||||
quickSettings.addDivider(container)
|
||||
|
||||
if (LosslessScalingHelper.isInstalled() && LosslessScalingHelper.isSupportedByGpu()) {
|
||||
quickSettings.addFrameGen(container)
|
||||
quickSettings.addDivider(container)
|
||||
}
|
||||
|
||||
quickSettings.addIntSetting(
|
||||
R.string.renderer_accuracy,
|
||||
container,
|
||||
@@ -1231,10 +1194,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
R.array.rendererAntiAliasingNames,
|
||||
R.array.rendererAntiAliasingValues
|
||||
)
|
||||
|
||||
quickSettings.addPostProcessing(container) {
|
||||
addQuickSettings()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user