Compare commits
2 commits
master
...
descriptor
Author | SHA1 | Date | |
---|---|---|---|
fe663b4467 | |||
7435d70e1e |
126 changed files with 654 additions and 1576 deletions
|
@ -13,8 +13,8 @@ fi
|
||||||
cd src/android
|
cd src/android
|
||||||
chmod +x ./gradlew
|
chmod +x ./gradlew
|
||||||
|
|
||||||
./gradlew assembleMainlineRelease
|
./gradlew assembleRelease
|
||||||
./gradlew bundleMainlineRelease
|
./gradlew bundleRelease
|
||||||
|
|
||||||
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
|
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
|
||||||
rm "${ANDROID_KEYSTORE_FILE}"
|
rm "${ANDROID_KEYSTORE_FILE}"
|
||||||
|
|
|
@ -287,13 +287,6 @@ if (ANDROID)
|
||||||
set(CMAKE_POLICY_VERSION_MINIMUM 3.5) # Workaround for Oboe
|
set(CMAKE_POLICY_VERSION_MINIMUM 3.5) # Workaround for Oboe
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# We need to downgrade debug info (/Zi -> /Z7) to use an older but more cacheable format
|
|
||||||
# See https://github.com/nanoant/CMakePCHCompiler/issues/21
|
|
||||||
if(WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
|
|
||||||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
|
||||||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Default to a Release build
|
# Default to a Release build
|
||||||
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE)
|
if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE)
|
||||||
|
|
1
docs/build/Android.md
vendored
1
docs/build/Android.md
vendored
|
@ -33,7 +33,6 @@ Eden by default will be cloned into -
|
||||||
4. Navigate to `eden/src/android`.
|
4. Navigate to `eden/src/android`.
|
||||||
5. Then Build with `./gradlew assembleRelWithDebInfo`.
|
5. Then Build with `./gradlew assembleRelWithDebInfo`.
|
||||||
6. To build the optimised build use `./gradlew assembleGenshinSpoofRelWithDebInfo`.
|
6. To build the optimised build use `./gradlew assembleGenshinSpoofRelWithDebInfo`.
|
||||||
7. You can pass extra variables to cmake via `-PYUZU_ANDROID_ARGS="-D..."`
|
|
||||||
|
|
||||||
### Script
|
### Script
|
||||||
A convenience script for building is provided in `.ci/android/build.sh`. The built APK can be put into an `artifacts` directory via `.ci/android/package.sh`. On Windows, these must be done in the Git Bash or MinGW terminal.
|
A convenience script for building is provided in `.ci/android/build.sh`. The built APK can be put into an `artifacts` directory via `.ci/android/package.sh`. On Windows, these must be done in the Git Bash or MinGW terminal.
|
||||||
|
|
|
@ -63,8 +63,6 @@ While all modern Linux distributions are supported (Fedora >40, Ubuntu >24.04, D
|
||||||
|
|
||||||
Intel and Nvidia GPU support is limited. AMD (RADV) drivers receive first-class testing and are known to provide the most stable Eden experience possible.
|
Intel and Nvidia GPU support is limited. AMD (RADV) drivers receive first-class testing and are known to provide the most stable Eden experience possible.
|
||||||
|
|
||||||
Wayland is not recommended. Testing has shown significantly worse performance on most Wayland compositors compared to X11, alongside mysterious bugs and compatibility errors. For now, set `QT_QPA_PLATFORM=xcb` when running Eden, or pass `-platform xcb` to the launch arguments.
|
|
||||||
|
|
||||||
## Windows
|
## Windows
|
||||||
|
|
||||||
Windows 10 and 11 are supported. Support for Windows 8.x is unknown, and Windows 7 support is unlikely to ever be added.
|
Windows 10 and 11 are supported. Support for Windows 8.x is unknown, and Windows 7 support is unlikely to ever be added.
|
||||||
|
|
14
externals/CMakeLists.txt
vendored
14
externals/CMakeLists.txt
vendored
|
@ -155,14 +155,12 @@ if (YUZU_USE_BUNDLED_SIRIT)
|
||||||
AddJsonPackage(sirit-ci)
|
AddJsonPackage(sirit-ci)
|
||||||
else()
|
else()
|
||||||
AddJsonPackage(sirit)
|
AddJsonPackage(sirit)
|
||||||
# Change to old-but-more-cacheable debug info on Windows
|
if(MSVC AND USE_CCACHE AND sirit_ADDED)
|
||||||
if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
|
get_target_property(_opts sirit COMPILE_OPTIONS)
|
||||||
get_target_property(sirit_opts sirit COMPILE_OPTIONS)
|
list(FILTER _opts EXCLUDE REGEX "/Zi")
|
||||||
list(FILTER sirit_opts EXCLUDE REGEX "/Zi")
|
list(APPEND _opts "/Z7")
|
||||||
list(APPEND sirit_opts "/Z7")
|
set_target_properties(siritobj PROPERTIES COMPILE_OPTIONS "${_opts}")
|
||||||
set_target_properties(sirit PROPERTIES COMPILE_OPTIONS "${sirit_opts}")
|
elseif(MSVC AND CXX_CLANG)
|
||||||
endif()
|
|
||||||
if(MSVC AND CXX_CLANG)
|
|
||||||
target_compile_options(siritobj PRIVATE -Wno-error=unused-command-line-argument)
|
target_compile_options(siritobj PRIVATE -Wno-error=unused-command-line-argument)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
6
externals/cpmfile.json
vendored
6
externals/cpmfile.json
vendored
|
@ -117,9 +117,9 @@
|
||||||
},
|
},
|
||||||
"spirv-tools": {
|
"spirv-tools": {
|
||||||
"package": "SPIRV-Tools",
|
"package": "SPIRV-Tools",
|
||||||
"repo": "crueter/SPIRV-Tools",
|
"repo": "KhronosGroup/SPIRV-Tools",
|
||||||
"sha": "2fa2d44485",
|
"tag": "v%VERSION%",
|
||||||
"hash": "45b198be1d09974ccb2438e8bfa5683f23a0421b058297c28eacfd77e454ec2cf87e77850eddd202efff34b004d8d6b4d12e9615e59bd72be904c196f5eb2169",
|
"hash": "b17940433ced72e004c5eeffd7dd411b6afcc6a52ee31de6427d88edceb8172369be8ec8bf5b65708a78bf41fdae264d554aa7750b2209831679ab36bc867567",
|
||||||
"git_version": "2025.4",
|
"git_version": "2025.4",
|
||||||
"options": [
|
"options": [
|
||||||
"SPIRV_SKIP_EXECUTABLES ON"
|
"SPIRV_SKIP_EXECUTABLES ON"
|
||||||
|
|
|
@ -101,9 +101,15 @@ if (MSVC AND NOT CXX_CLANG)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
|
if (USE_CCACHE OR YUZU_USE_PRECOMPILED_HEADERS)
|
||||||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
# when caching, we need to use /Z7 to downgrade debug info to use an older but more cacheable format
|
||||||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
# Precompiled headers are deleted if not using /Z7. See https://github.com/nanoant/CMakePCHCompiler/issues/21
|
||||||
|
add_compile_options(/Z7)
|
||||||
|
# Avoid D9025 warning
|
||||||
|
string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||||
|
string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||||
|
else()
|
||||||
|
add_compile_options(/Zi)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ARCHITECTURE_x86_64)
|
if (ARCHITECTURE_x86_64)
|
||||||
|
|
|
@ -75,8 +75,6 @@ android {
|
||||||
|
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
val extraCMakeArgs = (project.findProperty("YUZU_ANDROID_ARGS") as String?)?.split("\\s+".toRegex()) ?: emptyList()
|
|
||||||
|
|
||||||
arguments.addAll(listOf(
|
arguments.addAll(listOf(
|
||||||
"-DENABLE_QT=0", // Don't use QT
|
"-DENABLE_QT=0", // Don't use QT
|
||||||
"-DENABLE_SDL2=0", // Don't use SDL
|
"-DENABLE_SDL2=0", // Don't use SDL
|
||||||
|
@ -89,8 +87,7 @@ android {
|
||||||
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
|
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
|
||||||
"-DBUILD_TESTING=OFF",
|
"-DBUILD_TESTING=OFF",
|
||||||
"-DYUZU_TESTS=OFF",
|
"-DYUZU_TESTS=OFF",
|
||||||
"-DDYNARMIC_TESTS=OFF",
|
"-DDYNARMIC_TESTS=OFF"
|
||||||
*extraCMakeArgs.toTypedArray()
|
|
||||||
))
|
))
|
||||||
|
|
||||||
abiFilters("arm64-v8a")
|
abiFilters("arm64-v8a")
|
||||||
|
|
|
@ -51,6 +51,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||||
|
|
||||||
SOC_OVERLAY_BACKGROUND("soc_overlay_background"),
|
SOC_OVERLAY_BACKGROUND("soc_overlay_background"),
|
||||||
|
|
||||||
|
ENABLE_RAII("enable_raii"),
|
||||||
FRAME_INTERPOLATION("frame_interpolation"),
|
FRAME_INTERPOLATION("frame_interpolation"),
|
||||||
// FRAME_SKIPPING("frame_skipping"),
|
// FRAME_SKIPPING("frame_skipping"),
|
||||||
|
|
||||||
|
@ -70,6 +71,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||||
DEBUG_FLUSH_BY_LINE("flush_line"),
|
DEBUG_FLUSH_BY_LINE("flush_line"),
|
||||||
USE_LRU_CACHE("use_lru_cache");
|
USE_LRU_CACHE("use_lru_cache");
|
||||||
|
|
||||||
|
external fun isRaiiEnabled(): Boolean
|
||||||
|
|
||||||
// external fun isFrameSkippingEnabled(): Boolean
|
// external fun isFrameSkippingEnabled(): Boolean
|
||||||
external fun isFrameInterpolationEnabled(): Boolean
|
external fun isFrameInterpolationEnabled(): Boolean
|
||||||
|
|
|
@ -229,6 +229,13 @@ abstract class SettingsItem(
|
||||||
|
|
||||||
override fun reset() = BooleanSetting.USE_DOCKED_MODE.reset()
|
override fun reset() = BooleanSetting.USE_DOCKED_MODE.reset()
|
||||||
}
|
}
|
||||||
|
put(
|
||||||
|
SwitchSetting(
|
||||||
|
BooleanSetting.ENABLE_RAII,
|
||||||
|
titleId = R.string.enable_raii,
|
||||||
|
descriptionId = R.string.enable_raii_description
|
||||||
|
)
|
||||||
|
)
|
||||||
put(
|
put(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
BooleanSetting.FRAME_INTERPOLATION,
|
BooleanSetting.FRAME_INTERPOLATION,
|
||||||
|
@ -826,4 +833,3 @@ abstract class SettingsItem(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -462,6 +462,7 @@ class SettingsFragmentPresenter(
|
||||||
add(IntSetting.RENDERER_SAMPLE_SHADING_FRACTION.key)
|
add(IntSetting.RENDERER_SAMPLE_SHADING_FRACTION.key)
|
||||||
|
|
||||||
add(HeaderSetting(R.string.veil_renderer))
|
add(HeaderSetting(R.string.veil_renderer))
|
||||||
|
add(BooleanSetting.ENABLE_RAII.key)
|
||||||
add(BooleanSetting.RENDERER_EARLY_RELEASE_FENCES.key)
|
add(BooleanSetting.RENDERER_EARLY_RELEASE_FENCES.key)
|
||||||
add(IntSetting.DMA_ACCURACY.key)
|
add(IntSetting.DMA_ACCURACY.key)
|
||||||
add(BooleanSetting.BUFFER_REORDER_DISABLE.key)
|
add(BooleanSetting.BUFFER_REORDER_DISABLE.key)
|
||||||
|
|
|
@ -1039,7 +1039,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
||||||
scale /= 100f
|
scale /= 100f
|
||||||
|
|
||||||
// Apply individual scale
|
// Apply individual scale
|
||||||
scale *= overlayControlData.individualScale.let { if (it > 0f) it else 1f }
|
scale *= overlayControlData.individualScale
|
||||||
|
|
||||||
// Initialize the InputOverlayDrawableButton.
|
// Initialize the InputOverlayDrawableButton.
|
||||||
val defaultStateBitmap = getBitmap(context, defaultResId, scale)
|
val defaultStateBitmap = getBitmap(context, defaultResId, scale)
|
||||||
|
@ -1114,7 +1114,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
||||||
|
|
||||||
// Apply individual scale
|
// Apply individual scale
|
||||||
if (dpadData != null) {
|
if (dpadData != null) {
|
||||||
scale *= dpadData.individualScale.let { if (it > 0f) it else 1f }
|
scale *= dpadData.individualScale
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the InputOverlayDrawableDpad.
|
// Initialize the InputOverlayDrawableDpad.
|
||||||
|
@ -1191,7 +1191,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
||||||
scale /= 100f
|
scale /= 100f
|
||||||
|
|
||||||
// Apply individual scale
|
// Apply individual scale
|
||||||
scale *= overlayControlData.individualScale.let { if (it > 0f) it else 1f }
|
scale *= overlayControlData.individualScale
|
||||||
|
|
||||||
// Initialize the InputOverlayDrawableJoystick.
|
// Initialize the InputOverlayDrawableJoystick.
|
||||||
val bitmapOuter = getBitmap(context, resOuter, scale)
|
val bitmapOuter = getBitmap(context, resOuter, scale)
|
||||||
|
|
|
@ -64,6 +64,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">امتدادات GPU</string>
|
<string name="veil_extensions">امتدادات GPU</string>
|
||||||
<string name="veil_renderer">العارض</string>
|
<string name="veil_renderer">العارض</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">طريقة لإدارة الموارد تلقائيًا في فولكان تضمن الإفراج الصحيح عن الموارد عندما لا تكون هناك حاجة إليها، ولكن قد تسبب تعطل الألعاب المجمعة.</string>
|
||||||
<string name="veil_misc">وحدة المعالجة المركزية والذاكرة</string>
|
<string name="veil_misc">وحدة المعالجة المركزية والذاكرة</string>
|
||||||
<string name="eden_veil">حجاب عدن</string>
|
<string name="eden_veil">حجاب عدن</string>
|
||||||
<string name="eden_veil_description">إعدادات تجريبية لتحسين الأداء والقدرة. قد تسبب هذه الإعدادات شاشات سوداء أو مشاكل أخرى في اللعبة.</string>
|
<string name="eden_veil_description">إعدادات تجريبية لتحسين الأداء والقدرة. قد تسبب هذه الإعدادات شاشات سوداء أو مشاكل أخرى في اللعبة.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">پاشکۆکانی GPU</string>
|
<string name="veil_extensions">پاشکۆکانی GPU</string>
|
||||||
<string name="veil_renderer">رێندرەر</string>
|
<string name="veil_renderer">رێندرەر</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">ڕێگایەکی بەڕێوەبردنی سەرچاوەکان بە خۆکار لە ڤولکان کە دڵنیای دەکاتەوە لە ئازادکردنی گونجاوی سەرچاوەکان کاتێک کە چیتر پێویستیان نییە، بەڵام لەوانەیە ببێتە هۆی کەوتنی یارییە کۆکراوەکان.</string>
|
||||||
<string name="veil_misc">CPU و بیرگە</string>
|
<string name="veil_misc">CPU و بیرگە</string>
|
||||||
<string name="eden_veil">حجاب عدن</string>
|
<string name="eden_veil">حجاب عدن</string>
|
||||||
<string name="eden_veil_description">ڕێکخستنە تاقیکارییەکان بۆ باشترکردنی کارایی و توانا. ئەم ڕێکخستنانە لەوانەیە ببێتە هۆی شاشە ڕەشەکان یان کێشەیتری یاری.</string>
|
<string name="eden_veil_description">ڕێکخستنە تاقیکارییەکان بۆ باشترکردنی کارایی و توانا. ئەم ڕێکخستنانە لەوانەیە ببێتە هۆی شاشە ڕەشەکان یان کێشەیتری یاری.</string>
|
||||||
|
|
|
@ -64,6 +64,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">Rozšíření GPU</string>
|
<string name="veil_extensions">Rozšíření GPU</string>
|
||||||
<string name="veil_renderer">Renderer</string>
|
<string name="veil_renderer">Renderer</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Metoda automatické správy prostředků ve Vulkanu, která zajišťuje správné uvolnění prostředků, když již nejsou potřeba, ale může způsobit pády v balených hrách.</string>
|
||||||
<string name="veil_misc">CPU a paměť</string>
|
<string name="veil_misc">CPU a paměť</string>
|
||||||
<string name="eden_veil">Edenův závoj</string>
|
<string name="eden_veil">Edenův závoj</string>
|
||||||
<string name="eden_veil_description">Experimentální nastavení pro zlepšení výkonu a schopností. Tato nastavení mohou způsobit černé obrazovky nebo další herní problémy.</string>
|
<string name="eden_veil_description">Experimentální nastavení pro zlepšení výkonu a schopností. Tato nastavení mohou způsobit černé obrazovky nebo další herní problémy.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">GPU-Erweiterungen</string>
|
<string name="veil_extensions">GPU-Erweiterungen</string>
|
||||||
<string name="veil_renderer">Renderer</string>
|
<string name="veil_renderer">Renderer</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Eine Methode zur automatischen Ressourcenverwaltung in Vulkan, die eine ordnungsgemäße Freigabe von Ressourcen gewährleistet, wenn sie nicht mehr benötigt werden, aber bei gebündelten Spielen Abstürze verursachen kann.</string>
|
||||||
<string name="veil_misc">CPU und Speicher</string>
|
<string name="veil_misc">CPU und Speicher</string>
|
||||||
<string name="eden_veil">Edens Schleier</string>
|
<string name="eden_veil">Edens Schleier</string>
|
||||||
<string name="eden_veil_description">Experimentelle Einstellungen zur Verbesserung der Leistung und Funktionalität. Diese Einstellungen können schwarze Bildschirme oder andere Spielprobleme verursachen.</string>
|
<string name="eden_veil_description">Experimentelle Einstellungen zur Verbesserung der Leistung und Funktionalität. Diese Einstellungen können schwarze Bildschirme oder andere Spielprobleme verursachen.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">Extensiones de GPU</string>
|
<string name="veil_extensions">Extensiones de GPU</string>
|
||||||
<string name="veil_renderer">Renderizador</string>
|
<string name="veil_renderer">Renderizador</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Un método de gestión automática de recursos en Vulkan que garantiza la liberación adecuada de recursos cuando ya no son necesarios, pero puede causar fallos en juegos empaquetados.</string>
|
||||||
<string name="veil_misc">CPU y memoria</string>
|
<string name="veil_misc">CPU y memoria</string>
|
||||||
<string name="eden_veil">Velo de Edén</string>
|
<string name="eden_veil">Velo de Edén</string>
|
||||||
<string name="eden_veil_description">Configuraciones experimentales para mejorar el rendimiento y la capacidad. Estas configuraciones pueden causar pantallas negras u otros problemas en el juego.</string>
|
<string name="eden_veil_description">Configuraciones experimentales para mejorar el rendimiento y la capacidad. Estas configuraciones pueden causar pantallas negras u otros problemas en el juego.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">افزونههای GPU</string>
|
<string name="veil_extensions">افزونههای GPU</string>
|
||||||
<string name="veil_renderer">رندرر</string>
|
<string name="veil_renderer">رندرر</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">روشی برای مدیریت خودکار منابع در ولکان که تضمین میکند منابع به درستی آزاد شوند وقتی دیگر مورد نیاز نیستند، اما ممکن است باعث کرش شدن بازیهای بستهبندی شده شود.</string>
|
||||||
<string name="veil_misc">پردازنده و حافظه</string>
|
<string name="veil_misc">پردازنده و حافظه</string>
|
||||||
<string name="eden_veil">پرده عدن</string>
|
<string name="eden_veil">پرده عدن</string>
|
||||||
<string name="eden_veil_description">تنظیمات آزمایشی برای بهبود عملکرد و قابلیت. این تنظیمات ممکن است باعث نمایش صفحه سیاه یا سایر مشکلات بازی شود.</string>
|
<string name="eden_veil_description">تنظیمات آزمایشی برای بهبود عملکرد و قابلیت. این تنظیمات ممکن است باعث نمایش صفحه سیاه یا سایر مشکلات بازی شود.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">Extensions GPU</string>
|
<string name="veil_extensions">Extensions GPU</string>
|
||||||
<string name="veil_renderer">Rendu</string>
|
<string name="veil_renderer">Rendu</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Une méthode de gestion automatique des ressources dans Vulkan qui assure la libération correcte des ressources lorsqu\'elles ne sont plus nécessaires, mais peut provoquer des plantages dans les jeux regroupés.</string>
|
||||||
<string name="veil_misc">CPU et mémoire</string>
|
<string name="veil_misc">CPU et mémoire</string>
|
||||||
<string name="eden_veil">Voile d\'Eden</string>
|
<string name="eden_veil">Voile d\'Eden</string>
|
||||||
<string name="eden_veil_description">Paramètres expérimentaux pour améliorer les performances et les capacités. Ces paramètres peuvent causer des écrans noirs ou d\'autres problèmes de jeu.</string>
|
<string name="eden_veil_description">Paramètres expérimentaux pour améliorer les performances et les capacités. Ces paramètres peuvent causer des écrans noirs ou d\'autres problèmes de jeu.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">הרחבות GPU</string>
|
<string name="veil_extensions">הרחבות GPU</string>
|
||||||
<string name="veil_renderer">רנדרר</string>
|
<string name="veil_renderer">רנדרר</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">שיטה לניהול אוטומטי של משאבים ב-Vulkan המבטיחה שחרור נכון של משאבים כאשר הם כבר לא נחוצים, אך עלולה לגרום לקריסות במשחקים מאוגדים.</string>
|
||||||
<string name="veil_misc">מעבד וזיכרון</string>
|
<string name="veil_misc">מעבד וזיכרון</string>
|
||||||
<string name="eden_veil">עדן וייל</string>
|
<string name="eden_veil">עדן וייל</string>
|
||||||
<string name="eden_veil_description">הגדרות ניסיוניות לשיפור ביצועים ויכולות. הגדרות אלו עלולות לגרום למסכים שחורים או לבעיות אחרות במשחק.</string>
|
<string name="eden_veil_description">הגדרות ניסיוניות לשיפור ביצועים ויכולות. הגדרות אלו עלולות לגרום למסכים שחורים או לבעיות אחרות במשחק.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">GPU kiterjesztések</string>
|
<string name="veil_extensions">GPU kiterjesztések</string>
|
||||||
<string name="veil_renderer">Megjelenítő</string>
|
<string name="veil_renderer">Megjelenítő</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">A Vulkan erőforrás-kezelési módszere, amely biztosítja az erőforrások megfelelő felszabadítását, ha már nincs rájuk szükség, de csomagolt játékok összeomlását okozhatja.</string>
|
||||||
<string name="veil_misc">CPU és memória</string>
|
<string name="veil_misc">CPU és memória</string>
|
||||||
<string name="eden_veil">Eden Fátyla</string>
|
<string name="eden_veil">Eden Fátyla</string>
|
||||||
<string name="eden_veil_description">Kísérleti beállítások a teljesítmény és képesség javításához. Ezek a beállítások fekete képernyőket vagy más játékproblémákat okozhatnak.</string>
|
<string name="eden_veil_description">Kísérleti beállítások a teljesítmény és képesség javításához. Ezek a beállítások fekete képernyőket vagy más játékproblémákat okozhatnak.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">Ekstensi GPU</string>
|
<string name="veil_extensions">Ekstensi GPU</string>
|
||||||
<string name="veil_renderer">Renderer</string>
|
<string name="veil_renderer">Renderer</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Metode manajemen sumber daya otomatis di Vulkan yang memastikan pelepasan sumber daya yang tepat ketika tidak lagi diperlukan, tetapi dapat menyebabkan crash pada game yang dibundel.</string>
|
||||||
<string name="veil_misc">CPU dan Memori</string>
|
<string name="veil_misc">CPU dan Memori</string>
|
||||||
<string name="eden_veil">Eden\'s Veil</string>
|
<string name="eden_veil">Eden\'s Veil</string>
|
||||||
<string name="eden_veil_description">Pengaturan eksperimental untuk meningkatkan kinerja dan kemampuan. Pengaturan ini dapat menyebabkan layar hitam atau masalah game lainnya.</string>
|
<string name="eden_veil_description">Pengaturan eksperimental untuk meningkatkan kinerja dan kemampuan. Pengaturan ini dapat menyebabkan layar hitam atau masalah game lainnya.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">Estensioni GPU</string>
|
<string name="veil_extensions">Estensioni GPU</string>
|
||||||
<string name="veil_renderer">Renderer</string>
|
<string name="veil_renderer">Renderer</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Un metodo di gestione automatica delle risorse in Vulkan che garantisce il corretto rilascio delle risorse quando non sono più necessarie, ma può causare crash nei giochi in bundle.</string>
|
||||||
<string name="veil_misc">CPU e Memoria</string>
|
<string name="veil_misc">CPU e Memoria</string>
|
||||||
<string name="eden_veil">Velo di Eden</string>
|
<string name="eden_veil">Velo di Eden</string>
|
||||||
<string name="eden_veil_description">Impostazioni sperimentali per migliorare prestazioni e capacità. Queste impostazioni possono causare schermate nere o altri problemi di gioco.</string>
|
<string name="eden_veil_description">Impostazioni sperimentali per migliorare prestazioni e capacità. Queste impostazioni possono causare schermate nere o altri problemi di gioco.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">GPU拡張機能</string>
|
<string name="veil_extensions">GPU拡張機能</string>
|
||||||
<string name="veil_renderer">レンダラー</string>
|
<string name="veil_renderer">レンダラー</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Vulkanにおける自動リソース管理の方法で、不要になったリソースを適切に解放しますが、バンドルされたゲームでクラッシュを引き起こす可能性があります。</string>
|
||||||
<string name="veil_misc">CPUとメモリ</string>
|
<string name="veil_misc">CPUとメモリ</string>
|
||||||
<string name="eden_veil">エデンのベール</string>
|
<string name="eden_veil">エデンのベール</string>
|
||||||
<string name="eden_veil_description">パフォーマンスと機能を向上させる実験的な設定。これらの設定は黒画面やその他のゲームの問題を引き起こす可能性があります。</string>
|
<string name="eden_veil_description">パフォーマンスと機能を向上させる実験的な設定。これらの設定は黒画面やその他のゲームの問題を引き起こす可能性があります。</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">GPU 확장 기능</string>
|
<string name="veil_extensions">GPU 확장 기능</string>
|
||||||
<string name="veil_renderer">렌더러</string>
|
<string name="veil_renderer">렌더러</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Vulkan에서 자동 리소스 관리를 위한 방법으로, 더 이상 필요하지 않은 리소스를 적절히 해제하지만 번들된 게임에서 충돌을 일으킬 수 있습니다.</string>
|
||||||
<string name="veil_misc">CPU 및 메모리</string>
|
<string name="veil_misc">CPU 및 메모리</string>
|
||||||
<string name="eden_veil">에덴의 베일</string>
|
<string name="eden_veil">에덴의 베일</string>
|
||||||
<string name="eden_veil_description">성능 및 기능을 향상시키기 위한 실험적 설정. 이 설정은 검은 화면 또는 기타 게임 문제를 일으킬 수 있습니다.</string>
|
<string name="eden_veil_description">성능 및 기능을 향상시키기 위한 실험적 설정. 이 설정은 검은 화면 또는 기타 게임 문제를 일으킬 수 있습니다.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">GPU-utvidelser</string>
|
<string name="veil_extensions">GPU-utvidelser</string>
|
||||||
<string name="veil_renderer">Renderer</string>
|
<string name="veil_renderer">Renderer</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">En metode for automatisk ressurshåndtering i Vulkan som sikrer riktig frigjøring av ressurser når de ikke lenger trengs, men kan føre til krasj i bundlede spill.</string>
|
||||||
<string name="veil_misc">CPU og minne</string>
|
<string name="veil_misc">CPU og minne</string>
|
||||||
<string name="eden_veil">Edens slør</string>
|
<string name="eden_veil">Edens slør</string>
|
||||||
<string name="eden_veil_description">Eksperimentelle innstillinger for å forbedre ytelse og funksjonalitet. Disse innstillingene kan forårsake svarte skjermer eller andre spillproblemer.</string>
|
<string name="eden_veil_description">Eksperimentelle innstillinger for å forbedre ytelse og funksjonalitet. Disse innstillingene kan forårsake svarte skjermer eller andre spillproblemer.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">Rozszerzenia GPU</string>
|
<string name="veil_extensions">Rozszerzenia GPU</string>
|
||||||
<string name="veil_renderer">Renderer</string>
|
<string name="veil_renderer">Renderer</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Metoda automatycznego zarządzania zasobami w Vulkanie, która zapewnia prawidłowe zwalnianie zasobów, gdy nie są już potrzebne, ale może powodować awarie w pakietowych grach.</string>
|
||||||
<string name="veil_misc">Procesor i pamięć</string>
|
<string name="veil_misc">Procesor i pamięć</string>
|
||||||
<string name="eden_veil">Zasłona Edenu</string>
|
<string name="eden_veil">Zasłona Edenu</string>
|
||||||
<string name="eden_veil_description">Eksperymentalne ustawienia poprawiające wydajność i możliwości. Te ustawienia mogą powodować czarne ekrany lub inne problemy z grą.</string>
|
<string name="eden_veil_description">Eksperymentalne ustawienia poprawiające wydajność i możliwości. Te ustawienia mogą powodować czarne ekrany lub inne problemy z grą.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">Extensões da GPU</string>
|
<string name="veil_extensions">Extensões da GPU</string>
|
||||||
<string name="veil_renderer">Renderizador</string>
|
<string name="veil_renderer">Renderizador</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Um método de gerenciamento automático de recursos no Vulkan que garante a liberação adequada de recursos quando não são mais necessários, mas pode causar falhas em jogos empacotados.</string>
|
||||||
<string name="veil_misc">CPU e Memória</string>
|
<string name="veil_misc">CPU e Memória</string>
|
||||||
<string name="eden_veil">Véu do Éden</string>
|
<string name="eden_veil">Véu do Éden</string>
|
||||||
<string name="eden_veil_description">Configurações experimentais para melhorar desempenho e capacidade. Essas configurações podem causar telas pretas ou outros problemas no jogo.</string>
|
<string name="eden_veil_description">Configurações experimentais para melhorar desempenho e capacidade. Essas configurações podem causar telas pretas ou outros problemas no jogo.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">Extensões da GPU</string>
|
<string name="veil_extensions">Extensões da GPU</string>
|
||||||
<string name="veil_renderer">Renderizador</string>
|
<string name="veil_renderer">Renderizador</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Um método de gestão automática de recursos no Vulkan que garante a libertação adequada de recursos quando já não são necessários, mas pode causar falhas em jogos empacotados.</string>
|
||||||
<string name="veil_misc">CPU e Memória</string>
|
<string name="veil_misc">CPU e Memória</string>
|
||||||
<string name="eden_veil">Véu do Éden</string>
|
<string name="eden_veil">Véu do Éden</string>
|
||||||
<string name="eden_veil_description">Definições experimentais para melhorar o desempenho e capacidade. Estas definições podem causar ecrãs pretos ou outros problemas no jogo.</string>
|
<string name="eden_veil_description">Definições experimentais para melhorar o desempenho e capacidade. Estas definições podem causar ecrãs pretos ou outros problemas no jogo.</string>
|
||||||
|
|
|
@ -72,6 +72,8 @@
|
||||||
<string name="eden_veil_warning_description">Настройки в Покров Эдема являются экспериментальными и могут вызывать проблемы. Если ваша игра не запускается, отключите все расширения.</string>
|
<string name="eden_veil_warning_description">Настройки в Покров Эдема являются экспериментальными и могут вызывать проблемы. Если ваша игра не запускается, отключите все расширения.</string>
|
||||||
<string name="frame_skipping">В разработке: Пропуск кадров</string>
|
<string name="frame_skipping">В разработке: Пропуск кадров</string>
|
||||||
<string name="frame_skipping_description">Включите или отключите пропуск кадров для повышения производительности за счет уменьшения количества отображаемых кадров. Эта функция находится в разработке и будет включена в будущих версиях.</string>
|
<string name="frame_skipping_description">Включите или отключите пропуск кадров для повышения производительности за счет уменьшения количества отображаемых кадров. Эта функция находится в разработке и будет включена в будущих версиях.</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Метод автоматического управления ресурсами в Vulkan, который обеспечивает правильное освобождение ресурсов при их ненадобности, но может вызывать сбои в бандл-играх.</string>
|
||||||
<string name="frame_interpolation">Улучшенная синхронизация кадров</string>
|
<string name="frame_interpolation">Улучшенная синхронизация кадров</string>
|
||||||
<string name="frame_interpolation_description">Обеспечивает плавную и стабильную подачу кадров за счет синхронизации их времени, уменьшая подтормаживания и неравномерную анимацию. Идеально для игр с нестабильным временем кадров или микро-подтормаживаниями во время игры.</string>
|
<string name="frame_interpolation_description">Обеспечивает плавную и стабильную подачу кадров за счет синхронизации их времени, уменьшая подтормаживания и неравномерную анимацию. Идеально для игр с нестабильным временем кадров или микро-подтормаживаниями во время игры.</string>
|
||||||
<string name="renderer_early_release_fences">Ранний релиз ограждений</string>
|
<string name="renderer_early_release_fences">Ранний релиз ограждений</string>
|
||||||
|
|
|
@ -81,6 +81,8 @@
|
||||||
<string name="descriptor_indexing_description">Побољшава текстуру и руковање међуспремника, као и преводилачки слој Маквелл. Подржани од стране неких Вулкана 1.1 ГПУ-а и сви Вулкан 1.2+ ГПУ.</string>
|
<string name="descriptor_indexing_description">Побољшава текстуру и руковање међуспремника, као и преводилачки слој Маквелл. Подржани од стране неких Вулкана 1.1 ГПУ-а и сви Вулкан 1.2+ ГПУ.</string>
|
||||||
|
|
||||||
<string name="veil_renderer">Рендерер</string>
|
<string name="veil_renderer">Рендерер</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Метод аутоматског управљања ресурсима у Vulkan-у који осигурава правилно ослобађање ресурса када више нису потребни, али може изазвати падове у пакованим играма.</string>
|
||||||
<string name="frame_interpolation">Побољшани оквирни пејсинг</string>
|
<string name="frame_interpolation">Побољшани оквирни пејсинг</string>
|
||||||
<string name="frame_interpolation_description">Осигурава глатку и доследан испоруку оквира синхронизацијом времена између оквира, смањење муцања и неуједначене анимације. Идеално за игре које доживљавају временски оквир нестабилност или микро-штитнике током играња.</string>
|
<string name="frame_interpolation_description">Осигурава глатку и доследан испоруку оквира синхронизацијом времена између оквира, смањење муцања и неуједначене анимације. Идеално за игре које доживљавају временски оквир нестабилност или микро-штитнике током играња.</string>
|
||||||
<string name="renderer_early_release_fences">Ranije oslobađanje ograda</string>
|
<string name="renderer_early_release_fences">Ranije oslobađanje ograda</string>
|
||||||
|
|
|
@ -70,6 +70,8 @@
|
||||||
<string name="eden_veil_description">Експериментальні налаштування для покращення продуктивності та сумісності. Ці налаштування можуть викликати збої, зокрема чорний екран.</string>
|
<string name="eden_veil_description">Експериментальні налаштування для покращення продуктивності та сумісності. Ці налаштування можуть викликати збої, зокрема чорний екран.</string>
|
||||||
<string name="eden_veil_warning_title">Експериментальні налаштування</string>
|
<string name="eden_veil_warning_title">Експериментальні налаштування</string>
|
||||||
<string name="eden_veil_warning_description">Налаштування Завіси Eden є експериментальними та можуть спричинити проблеми. Якщо ваша гра не запускається — вимкніть усі розширення.</string>
|
<string name="eden_veil_warning_description">Налаштування Завіси Eden є експериментальними та можуть спричинити проблеми. Якщо ваша гра не запускається — вимкніть усі розширення.</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Метод автоматичного керування ресурсами у Vulkan, який забезпечує правильне звільнення ресурсів після завершення їх використання, проте він може спричинити збої в ігрових збірниках.</string>
|
||||||
<string name="frame_skipping">В розробці: Пропуск кадрів</string>
|
<string name="frame_skipping">В розробці: Пропуск кадрів</string>
|
||||||
<string name="frame_skipping_description">Увімкніть або вимкніть пропуск кадрів для покращення продуктивності за рахунок зменшення кількості візуалізованих кадрів. Ця функція ще розробляється та буде доступна у майбутніх версіях.</string>
|
<string name="frame_skipping_description">Увімкніть або вимкніть пропуск кадрів для покращення продуктивності за рахунок зменшення кількості візуалізованих кадрів. Ця функція ще розробляється та буде доступна у майбутніх версіях.</string>
|
||||||
<string name="frame_interpolation">Покращена синхронізація кадрів</string>
|
<string name="frame_interpolation">Покращена синхронізація кадрів</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">Tiện ích mở rộng GPU</string>
|
<string name="veil_extensions">Tiện ích mở rộng GPU</string>
|
||||||
<string name="veil_renderer">Trình kết xuất</string>
|
<string name="veil_renderer">Trình kết xuất</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Phương pháp quản lý tài nguyên tự động trong Vulkan đảm bảo giải phóng tài nguyên đúng cách khi không còn cần thiết, nhưng có thể gây ra sự cố trong các trò chơi được đóng gói.</string>
|
||||||
<string name="veil_misc">CPU và Bộ nhớ</string>
|
<string name="veil_misc">CPU và Bộ nhớ</string>
|
||||||
<string name="eden_veil">Mành che của Eden</string>
|
<string name="eden_veil">Mành che của Eden</string>
|
||||||
<string name="eden_veil_description">Cài đặt thử nghiệm để cải thiện hiệu suất và khả năng. Những cài đặt này có thể gây ra màn hình đen hoặc các vấn đề khác trong trò chơi.</string>
|
<string name="eden_veil_description">Cài đặt thử nghiệm để cải thiện hiệu suất và khả năng. Những cài đặt này có thể gây ra màn hình đen hoặc các vấn đề khác trong trò chơi.</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">GPU扩展</string>
|
<string name="veil_extensions">GPU扩展</string>
|
||||||
<string name="veil_renderer">渲染器</string>
|
<string name="veil_renderer">渲染器</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Vulkan中的一种自动资源管理方法,确保在不再需要时正确释放资源,但可能导致捆绑游戏崩溃。</string>
|
||||||
<string name="veil_misc">CPU和内存</string>
|
<string name="veil_misc">CPU和内存</string>
|
||||||
<string name="eden_veil">伊甸之幕</string>
|
<string name="eden_veil">伊甸之幕</string>
|
||||||
<string name="eden_veil_description">实验性设置以提高性能和能力。这些设置可能会导致黑屏或其他游戏问题。</string>
|
<string name="eden_veil_description">实验性设置以提高性能和能力。这些设置可能会导致黑屏或其他游戏问题。</string>
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<!-- Eden\'s Veil -->
|
<!-- Eden\'s Veil -->
|
||||||
<string name="veil_extensions">GPU擴充功能</string>
|
<string name="veil_extensions">GPU擴充功能</string>
|
||||||
<string name="veil_renderer">渲染器</string>
|
<string name="veil_renderer">渲染器</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">Vulkan中的一種自動資源管理方法,確保在不再需要時正確釋放資源,但可能導致捆綁遊戲崩潰。</string>
|
||||||
<string name="veil_misc">CPU與記憶體</string>
|
<string name="veil_misc">CPU與記憶體</string>
|
||||||
<string name="eden_veil">伊甸之幕</string>
|
<string name="eden_veil">伊甸之幕</string>
|
||||||
<string name="eden_veil_description">實驗性設定以提高效能和能力。這些設定可能會導致黑屏或其他遊戲問題。</string>
|
<string name="eden_veil_description">實驗性設定以提高效能和能力。這些設定可能會導致黑屏或其他遊戲問題。</string>
|
||||||
|
|
|
@ -180,7 +180,6 @@
|
||||||
<item>@string/resolution_half</item>
|
<item>@string/resolution_half</item>
|
||||||
<item>@string/resolution_three_quarter</item>
|
<item>@string/resolution_three_quarter</item>
|
||||||
<item>@string/resolution_one</item>
|
<item>@string/resolution_one</item>
|
||||||
<item>@string/resolution_five_quarter</item>
|
|
||||||
<item>@string/resolution_three_half</item>
|
<item>@string/resolution_three_half</item>
|
||||||
<item>@string/resolution_two</item>
|
<item>@string/resolution_two</item>
|
||||||
<item>@string/resolution_three</item>
|
<item>@string/resolution_three</item>
|
||||||
|
@ -203,7 +202,6 @@
|
||||||
<item>5</item>
|
<item>5</item>
|
||||||
<item>6</item>
|
<item>6</item>
|
||||||
<item>7</item>
|
<item>7</item>
|
||||||
<item>8</item>
|
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
<integer-array name="rendererVSyncValues">
|
<integer-array name="rendererVSyncValues">
|
||||||
|
@ -253,16 +251,12 @@
|
||||||
<item>@string/scaling_filter_nearest_neighbor</item>
|
<item>@string/scaling_filter_nearest_neighbor</item>
|
||||||
<item>@string/scaling_filter_bilinear</item>
|
<item>@string/scaling_filter_bilinear</item>
|
||||||
<item>@string/scaling_filter_bicubic</item>
|
<item>@string/scaling_filter_bicubic</item>
|
||||||
|
<item>@string/scaling_filter_spline1</item>
|
||||||
<item>@string/scaling_filter_gaussian</item>
|
<item>@string/scaling_filter_gaussian</item>
|
||||||
<item>@string/scaling_filter_lanczos</item>
|
<item>@string/scaling_filter_lanczos</item>
|
||||||
<item>@string/scaling_filter_scale_force</item>
|
<item>@string/scaling_filter_scale_force</item>
|
||||||
<item>@string/scaling_filter_fsr</item>
|
<item>@string/scaling_filter_fsr</item>
|
||||||
<item>@string/scaling_filter_area</item>
|
<item>@string/scaling_filter_area</item>
|
||||||
<item>@string/scaling_filter_mmpx</item>
|
|
||||||
<item>@string/scaling_filter_zero_tangent</item>
|
|
||||||
<item>@string/scaling_filter_bspline</item>
|
|
||||||
<item>@string/scaling_filter_mitchell</item>
|
|
||||||
<item>@string/scaling_filter_spline1</item>
|
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<integer-array name="rendererScalingFilterValues">
|
<integer-array name="rendererScalingFilterValues">
|
||||||
|
@ -275,10 +269,6 @@
|
||||||
<item>6</item>
|
<item>6</item>
|
||||||
<item>7</item>
|
<item>7</item>
|
||||||
<item>8</item>
|
<item>8</item>
|
||||||
<item>9</item>
|
|
||||||
<item>10</item>
|
|
||||||
<item>11</item>
|
|
||||||
<item>12</item>
|
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="rendererAntiAliasingNames">
|
<string-array name="rendererAntiAliasingNames">
|
||||||
|
|
|
@ -109,6 +109,8 @@
|
||||||
<string name="sample_shading_fraction_description">The intensity of the sample shading pass. Higher values improve quality more but also reduce performance to a greater extent.</string>
|
<string name="sample_shading_fraction_description">The intensity of the sample shading pass. Higher values improve quality more but also reduce performance to a greater extent.</string>
|
||||||
|
|
||||||
<string name="veil_renderer">Renderer</string>
|
<string name="veil_renderer">Renderer</string>
|
||||||
|
<string name="enable_raii">RAII</string>
|
||||||
|
<string name="enable_raii_description">A method of automatic resource management in Vulkan that ensures proper release of resources when they are no longer needed, but may cause crashes in bundled games.</string>
|
||||||
<string name="frame_interpolation">Enhanced Frame Pacing</string>
|
<string name="frame_interpolation">Enhanced Frame Pacing</string>
|
||||||
<string name="frame_interpolation_description">Ensures smooth and consistent frame delivery by synchronizing the timing between frames, reducing stuttering and uneven animation. Ideal for games that experience frame timing instability or micro-stutters during gameplay.</string>
|
<string name="frame_interpolation_description">Ensures smooth and consistent frame delivery by synchronizing the timing between frames, reducing stuttering and uneven animation. Ideal for games that experience frame timing instability or micro-stutters during gameplay.</string>
|
||||||
<string name="renderer_early_release_fences">Release Fences Early</string>
|
<string name="renderer_early_release_fences">Release Fences Early</string>
|
||||||
|
@ -994,7 +996,6 @@
|
||||||
<string name="resolution_half">0.5X (360p/540p)</string>
|
<string name="resolution_half">0.5X (360p/540p)</string>
|
||||||
<string name="resolution_three_quarter">0.75X (540p/810p)</string>
|
<string name="resolution_three_quarter">0.75X (540p/810p)</string>
|
||||||
<string name="resolution_one">1X (720p/1080p)</string>
|
<string name="resolution_one">1X (720p/1080p)</string>
|
||||||
<string name="resolution_five_quarter">1.25X (900p/1350p)</string>
|
|
||||||
<string name="resolution_three_half">1.5X (1080p/1620p)</string>
|
<string name="resolution_three_half">1.5X (1080p/1620p)</string>
|
||||||
<string name="resolution_two">2X (1440p/2160p) (Slow)</string>
|
<string name="resolution_two">2X (1440p/2160p) (Slow)</string>
|
||||||
<string name="resolution_three">3X (2160p/3240p) (Slow)</string>
|
<string name="resolution_three">3X (2160p/3240p) (Slow)</string>
|
||||||
|
@ -1016,10 +1017,6 @@
|
||||||
<string name="scaling_filter_scale_force">ScaleForce</string>
|
<string name="scaling_filter_scale_force">ScaleForce</string>
|
||||||
<string name="scaling_filter_fsr">AMD FidelityFX™ Super Resolution</string>
|
<string name="scaling_filter_fsr">AMD FidelityFX™ Super Resolution</string>
|
||||||
<string name="scaling_filter_area">Area</string>
|
<string name="scaling_filter_area">Area</string>
|
||||||
<string name="scaling_filter_zero_tangent">Zero-Tangent</string>
|
|
||||||
<string name="scaling_filter_bspline">B-Spline</string>
|
|
||||||
<string name="scaling_filter_mitchell">Mitchell</string>
|
|
||||||
<string name="scaling_filter_mmpx">MMPX</string>
|
|
||||||
|
|
||||||
<!-- Anti-Aliasing -->
|
<!-- Anti-Aliasing -->
|
||||||
<string name="anti_aliasing_none">None</string>
|
<string name="anti_aliasing_none">None</string>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
constexpr u32 CurrentRevision = 15;
|
constexpr u32 CurrentRevision = 16;
|
||||||
|
|
||||||
enum class SupportTags {
|
enum class SupportTags {
|
||||||
CommandProcessingTimeEstimatorVersion4,
|
CommandProcessingTimeEstimatorVersion4,
|
||||||
|
@ -47,10 +47,6 @@ enum class SupportTags {
|
||||||
DelayChannelMappingChange,
|
DelayChannelMappingChange,
|
||||||
ReverbChannelMappingChange,
|
ReverbChannelMappingChange,
|
||||||
I3dl2ReverbChannelMappingChange,
|
I3dl2ReverbChannelMappingChange,
|
||||||
SplitterPrevVolumeReset,
|
|
||||||
SplitterBiquadFilterParameter,
|
|
||||||
SplitterDestinationV2b,
|
|
||||||
VoiceInParameterV2,
|
|
||||||
|
|
||||||
// Not a real tag, just here to get the count.
|
// Not a real tag, just here to get the count.
|
||||||
Size
|
Size
|
||||||
|
@ -95,10 +91,6 @@ constexpr bool CheckFeatureSupported(SupportTags tag, u32 user_revision) {
|
||||||
{SupportTags::DelayChannelMappingChange, 11},
|
{SupportTags::DelayChannelMappingChange, 11},
|
||||||
{SupportTags::ReverbChannelMappingChange, 11},
|
{SupportTags::ReverbChannelMappingChange, 11},
|
||||||
{SupportTags::I3dl2ReverbChannelMappingChange, 11},
|
{SupportTags::I3dl2ReverbChannelMappingChange, 11},
|
||||||
{SupportTags::SplitterBiquadFilterParameter, 12},
|
|
||||||
{SupportTags::SplitterPrevVolumeReset, 13},
|
|
||||||
{SupportTags::SplitterDestinationV2b, 15},
|
|
||||||
{SupportTags::VoiceInParameterV2, 15},
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
const auto& feature =
|
const auto& feature =
|
||||||
|
|
|
@ -193,20 +193,4 @@ bool BehaviorInfo::IsI3dl2ReverbChannelMappingChanged() const {
|
||||||
return CheckFeatureSupported(SupportTags::I3dl2ReverbChannelMappingChange, user_revision);
|
return CheckFeatureSupported(SupportTags::I3dl2ReverbChannelMappingChange, user_revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BehaviorInfo::IsSplitterPrevVolumeResetSupported() const {
|
|
||||||
return CheckFeatureSupported(SupportTags::SplitterPrevVolumeReset, user_revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BehaviorInfo::IsSplitterDestinationV2bSupported() const {
|
|
||||||
return CheckFeatureSupported(SupportTags::SplitterDestinationV2b, user_revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BehaviorInfo::IsVoiceInParameterV2Supported() const {
|
|
||||||
return CheckFeatureSupported(SupportTags::VoiceInParameterV2, user_revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BehaviorInfo::IsBiquadFilterParameterForSplitterEnabled() const {
|
|
||||||
return CheckFeatureSupported(SupportTags::SplitterBiquadFilterParameter, user_revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace AudioCore::Renderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -364,38 +361,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool IsI3dl2ReverbChannelMappingChanged() const;
|
bool IsI3dl2ReverbChannelMappingChanged() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if explicit previous mix volume reset is supported for splitters.
|
|
||||||
* This allows splitters to explicitly reset their previous mix volumes instead of
|
|
||||||
* doing so implicitly on first use.
|
|
||||||
*
|
|
||||||
* @return True if supported, otherwise false.
|
|
||||||
*/
|
|
||||||
bool IsSplitterPrevVolumeResetSupported() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if splitter destination v2b parameter format is supported (revision 15+).
|
|
||||||
* This uses the extended parameter format with biquad filter fields.
|
|
||||||
*
|
|
||||||
* @return True if supported, otherwise false.
|
|
||||||
*/
|
|
||||||
bool IsSplitterDestinationV2bSupported() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if voice input parameter v2 format is supported (revision 15+).
|
|
||||||
* This uses the extended parameter format with float biquad filters.
|
|
||||||
*
|
|
||||||
* @return True if supported, otherwise false.
|
|
||||||
*/
|
|
||||||
bool IsVoiceInParameterV2Supported() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if splitter destinations can carry biquad filter parameters (revision 12+).
|
|
||||||
*
|
|
||||||
* @return True if supported, otherwise false.
|
|
||||||
*/
|
|
||||||
bool IsBiquadFilterParameterForSplitterEnabled() const;
|
|
||||||
|
|
||||||
/// Host version
|
/// Host version
|
||||||
u32 process_revision;
|
u32 process_revision;
|
||||||
/// User version
|
/// User version
|
||||||
|
|
|
@ -64,6 +64,8 @@ Result InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||||
const PoolMapper pool_mapper(process_handle, memory_pools, memory_pool_count,
|
const PoolMapper pool_mapper(process_handle, memory_pools, memory_pool_count,
|
||||||
behaviour.IsMemoryForceMappingEnabled());
|
behaviour.IsMemoryForceMappingEnabled());
|
||||||
const auto voice_count{voice_context.GetCount()};
|
const auto voice_count{voice_context.GetCount()};
|
||||||
|
std::span<const VoiceInfo::InParameter> in_params{
|
||||||
|
reinterpret_cast<const VoiceInfo::InParameter*>(input), voice_count};
|
||||||
std::span<VoiceInfo::OutStatus> out_params{reinterpret_cast<VoiceInfo::OutStatus*>(output),
|
std::span<VoiceInfo::OutStatus> out_params{reinterpret_cast<VoiceInfo::OutStatus*>(output),
|
||||||
voice_count};
|
voice_count};
|
||||||
|
|
||||||
|
@ -74,104 +76,8 @@ Result InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||||
|
|
||||||
u32 new_voice_count{0};
|
u32 new_voice_count{0};
|
||||||
|
|
||||||
// Two input formats exist: legacy (0x170) and v2 with float biquad (0x188).
|
|
||||||
const bool use_v2 = behaviour.IsVoiceInParameterV2Supported();
|
|
||||||
const u32 in_stride = use_v2 ? 0x188u : static_cast<u32>(sizeof(VoiceInfo::InParameter));
|
|
||||||
|
|
||||||
for (u32 i = 0; i < voice_count; i++) {
|
for (u32 i = 0; i < voice_count; i++) {
|
||||||
VoiceInfo::InParameter local_in{};
|
const auto& in_param{in_params[i]};
|
||||||
std::array<VoiceInfo::BiquadFilterParameter2, MaxBiquadFilters> float_biquads{};
|
|
||||||
|
|
||||||
if (!use_v2) {
|
|
||||||
const auto* in_param_ptr = reinterpret_cast<const VoiceInfo::InParameter*>(
|
|
||||||
input + i * sizeof(VoiceInfo::InParameter));
|
|
||||||
local_in = *in_param_ptr;
|
|
||||||
} else {
|
|
||||||
struct VoiceInParameterV2 {
|
|
||||||
u32 id;
|
|
||||||
u32 node_id;
|
|
||||||
bool is_new;
|
|
||||||
bool in_use;
|
|
||||||
PlayState play_state;
|
|
||||||
SampleFormat sample_format;
|
|
||||||
u32 sample_rate;
|
|
||||||
u32 priority;
|
|
||||||
u32 sort_order;
|
|
||||||
u32 channel_count;
|
|
||||||
f32 pitch;
|
|
||||||
f32 volume;
|
|
||||||
// Two BiquadFilterParameter2 (0x18 each) -> ignored/converted
|
|
||||||
struct BiquadV2 {
|
|
||||||
bool enable;
|
|
||||||
u8 r1;
|
|
||||||
u8 r2;
|
|
||||||
u8 r3;
|
|
||||||
std::array<f32, 3> b;
|
|
||||||
std::array<f32, 2> a;
|
|
||||||
} biquads[2];
|
|
||||||
u32 wave_buffer_count;
|
|
||||||
u32 wave_buffer_index;
|
|
||||||
u32 reserved1;
|
|
||||||
u64 src_data_address;
|
|
||||||
u64 src_data_size;
|
|
||||||
s32 mix_id;
|
|
||||||
u32 splitter_id;
|
|
||||||
std::array<VoiceInfo::WaveBufferInternal, MaxWaveBuffers> wavebuffers;
|
|
||||||
std::array<u32, MaxChannels> channel_resource_ids;
|
|
||||||
bool clear_voice_drop;
|
|
||||||
u8 flush_wave_buffer_count;
|
|
||||||
u16 reserved2;
|
|
||||||
VoiceInfo::Flags flags;
|
|
||||||
SrcQuality src_quality;
|
|
||||||
u32 external_ctx;
|
|
||||||
u32 external_ctx_size;
|
|
||||||
u32 reserved3[2];
|
|
||||||
};
|
|
||||||
const auto* vin = reinterpret_cast<const VoiceInParameterV2*>(input + i * in_stride);
|
|
||||||
local_in.id = vin->id;
|
|
||||||
local_in.node_id = vin->node_id;
|
|
||||||
local_in.is_new = vin->is_new;
|
|
||||||
local_in.in_use = vin->in_use;
|
|
||||||
local_in.play_state = vin->play_state;
|
|
||||||
local_in.sample_format = vin->sample_format;
|
|
||||||
local_in.sample_rate = vin->sample_rate;
|
|
||||||
local_in.priority = static_cast<s32>(vin->priority);
|
|
||||||
local_in.sort_order = static_cast<s32>(vin->sort_order);
|
|
||||||
local_in.channel_count = vin->channel_count;
|
|
||||||
local_in.pitch = vin->pitch;
|
|
||||||
local_in.volume = vin->volume;
|
|
||||||
|
|
||||||
// For REV15+, we keep float coefficients separate and only convert for compatibility
|
|
||||||
for (size_t filter_idx = 0; filter_idx < MaxBiquadFilters; filter_idx++) {
|
|
||||||
const auto& src = vin->biquads[filter_idx];
|
|
||||||
auto& dst = local_in.biquads[filter_idx];
|
|
||||||
dst.enabled = src.enable;
|
|
||||||
// Convert float coefficients to fixed-point Q2.14 for legacy path
|
|
||||||
dst.b[0] = static_cast<s16>(std::clamp(src.b[0] * 16384.0f, -32768.0f, 32767.0f));
|
|
||||||
dst.b[1] = static_cast<s16>(std::clamp(src.b[1] * 16384.0f, -32768.0f, 32767.0f));
|
|
||||||
dst.b[2] = static_cast<s16>(std::clamp(src.b[2] * 16384.0f, -32768.0f, 32767.0f));
|
|
||||||
dst.a[0] = static_cast<s16>(std::clamp(src.a[0] * 16384.0f, -32768.0f, 32767.0f));
|
|
||||||
dst.a[1] = static_cast<s16>(std::clamp(src.a[1] * 16384.0f, -32768.0f, 32767.0f));
|
|
||||||
|
|
||||||
// Also store the native float version
|
|
||||||
float_biquads[filter_idx].enabled = src.enable;
|
|
||||||
float_biquads[filter_idx].numerator = src.b;
|
|
||||||
float_biquads[filter_idx].denominator = src.a;
|
|
||||||
}
|
|
||||||
local_in.wave_buffer_count = vin->wave_buffer_count;
|
|
||||||
local_in.wave_buffer_index = static_cast<u16>(vin->wave_buffer_index);
|
|
||||||
local_in.src_data_address = static_cast<CpuAddr>(vin->src_data_address);
|
|
||||||
local_in.src_data_size = vin->src_data_size;
|
|
||||||
local_in.mix_id = static_cast<u32>(vin->mix_id);
|
|
||||||
local_in.splitter_id = vin->splitter_id;
|
|
||||||
local_in.wave_buffer_internal = vin->wavebuffers;
|
|
||||||
local_in.channel_resource_ids = vin->channel_resource_ids;
|
|
||||||
local_in.clear_voice_drop = vin->clear_voice_drop;
|
|
||||||
local_in.flush_buffer_count = vin->flush_wave_buffer_count;
|
|
||||||
local_in.flags = vin->flags;
|
|
||||||
local_in.src_quality = vin->src_quality;
|
|
||||||
}
|
|
||||||
const auto& in_param = local_in;
|
|
||||||
std::array<VoiceState*, MaxChannels> voice_states{};
|
std::array<VoiceState*, MaxChannels> voice_states{};
|
||||||
|
|
||||||
if (!in_param.in_use) {
|
if (!in_param.in_use) {
|
||||||
|
@ -195,14 +101,6 @@ Result InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||||
BehaviorInfo::ErrorInfo update_error{};
|
BehaviorInfo::ErrorInfo update_error{};
|
||||||
voice_info.UpdateParameters(update_error, in_param, pool_mapper, behaviour);
|
voice_info.UpdateParameters(update_error, in_param, pool_mapper, behaviour);
|
||||||
|
|
||||||
// For REV15+, store the native float biquad coefficients
|
|
||||||
if (use_v2) {
|
|
||||||
voice_info.use_float_biquads = true;
|
|
||||||
voice_info.biquads_float = float_biquads;
|
|
||||||
} else {
|
|
||||||
voice_info.use_float_biquads = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!update_error.error_code.IsSuccess()) {
|
if (!update_error.error_code.IsSuccess()) {
|
||||||
behaviour.AppendError(update_error);
|
behaviour.AppendError(update_error);
|
||||||
}
|
}
|
||||||
|
@ -223,7 +121,7 @@ Result InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||||
new_voice_count += in_param.channel_count;
|
new_voice_count += in_param.channel_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto consumed_input_size{voice_count * in_stride};
|
auto consumed_input_size{voice_count * static_cast<u32>(sizeof(VoiceInfo::InParameter))};
|
||||||
auto consumed_output_size{voice_count * static_cast<u32>(sizeof(VoiceInfo::OutStatus))};
|
auto consumed_output_size{voice_count * static_cast<u32>(sizeof(VoiceInfo::OutStatus))};
|
||||||
if (consumed_input_size != in_header->voices_size) {
|
if (consumed_input_size != in_header->voices_size) {
|
||||||
LOG_ERROR(Service_Audio, "Consumed an incorrect voices size, header size={}, consumed={}",
|
LOG_ERROR(Service_Audio, "Consumed an incorrect voices size, header size={}, consumed={}",
|
||||||
|
@ -359,31 +257,18 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co
|
||||||
EffectContext& effect_context, SplitterContext& splitter_context) {
|
EffectContext& effect_context, SplitterContext& splitter_context) {
|
||||||
s32 mix_count{0};
|
s32 mix_count{0};
|
||||||
u32 consumed_input_size{0};
|
u32 consumed_input_size{0};
|
||||||
u32 input_mix_size{0};
|
|
||||||
|
|
||||||
if (behaviour.IsMixInParameterDirtyOnlyUpdateSupported()) {
|
if (behaviour.IsMixInParameterDirtyOnlyUpdateSupported()) {
|
||||||
auto in_dirty_params{reinterpret_cast<const MixInfo::InDirtyParameter*>(input)};
|
auto in_dirty_params{reinterpret_cast<const MixInfo::InDirtyParameter*>(input)};
|
||||||
mix_count = in_dirty_params->count;
|
mix_count = in_dirty_params->count;
|
||||||
|
|
||||||
// Validate against expected header size to ensure structure is correct
|
|
||||||
if (mix_count < 0 || mix_count > 0x100) {
|
|
||||||
LOG_ERROR(
|
|
||||||
Service_Audio,
|
|
||||||
"Invalid mix count from dirty parameter: count={}, magic=0x{:X}, expected_size={}",
|
|
||||||
mix_count, in_dirty_params->magic, in_header->mix_size);
|
|
||||||
return Service::Audio::ResultInvalidUpdateInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
consumed_input_size += static_cast<u32>(sizeof(MixInfo::InDirtyParameter));
|
|
||||||
input += sizeof(MixInfo::InDirtyParameter);
|
input += sizeof(MixInfo::InDirtyParameter);
|
||||||
|
consumed_input_size = static_cast<u32>(sizeof(MixInfo::InDirtyParameter) +
|
||||||
|
mix_count * sizeof(MixInfo::InParameter));
|
||||||
} else {
|
} else {
|
||||||
mix_count = mix_context.GetCount();
|
mix_count = mix_context.GetCount();
|
||||||
|
consumed_input_size = static_cast<u32>(mix_count * sizeof(MixInfo::InParameter));
|
||||||
}
|
}
|
||||||
|
|
||||||
input_mix_size = static_cast<u32>(mix_count * sizeof(MixInfo::InParameter));
|
|
||||||
consumed_input_size += input_mix_size;
|
|
||||||
|
|
||||||
|
|
||||||
if (mix_buffer_count == 0) {
|
if (mix_buffer_count == 0) {
|
||||||
return Service::Audio::ResultInvalidUpdateInfo;
|
return Service::Audio::ResultInvalidUpdateInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,13 +237,6 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, VoiceInfo& vo
|
||||||
|
|
||||||
cmd.biquad = voice_info.biquads[biquad_index];
|
cmd.biquad = voice_info.biquads[biquad_index];
|
||||||
|
|
||||||
if (voice_info.use_float_biquads) {
|
|
||||||
cmd.biquad_float = voice_info.biquads_float[biquad_index];
|
|
||||||
cmd.use_float_coefficients = true;
|
|
||||||
} else {
|
|
||||||
cmd.use_float_coefficients = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.state = memory_pool->Translate(CpuAddr(voice_state.biquad_states[biquad_index].data()),
|
cmd.state = memory_pool->Translate(CpuAddr(voice_state.biquad_states[biquad_index].data()),
|
||||||
MaxBiquadFilters * sizeof(VoiceState::BiquadFilterState));
|
MaxBiquadFilters * sizeof(VoiceState::BiquadFilterState));
|
||||||
|
|
||||||
|
@ -270,9 +263,6 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas
|
||||||
cmd.biquad.b = parameter.b;
|
cmd.biquad.b = parameter.b;
|
||||||
cmd.biquad.a = parameter.a;
|
cmd.biquad.a = parameter.a;
|
||||||
|
|
||||||
// Effects use legacy fixed-point format
|
|
||||||
cmd.use_float_coefficients = false;
|
|
||||||
|
|
||||||
cmd.state = memory_pool->Translate(CpuAddr(state),
|
cmd.state = memory_pool->Translate(CpuAddr(state),
|
||||||
MaxBiquadFilters * sizeof(VoiceState::BiquadFilterState));
|
MaxBiquadFilters * sizeof(VoiceState::BiquadFilterState));
|
||||||
|
|
||||||
|
@ -668,13 +658,6 @@ void CommandBuffer::GenerateMultitapBiquadFilterCommand(const s32 node_id, Voice
|
||||||
cmd.output = buffer_count + channel;
|
cmd.output = buffer_count + channel;
|
||||||
cmd.biquads = voice_info.biquads;
|
cmd.biquads = voice_info.biquads;
|
||||||
|
|
||||||
if (voice_info.use_float_biquads) {
|
|
||||||
cmd.biquads_float = voice_info.biquads_float;
|
|
||||||
cmd.use_float_coefficients = true;
|
|
||||||
} else {
|
|
||||||
cmd.use_float_coefficients = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.states[0] =
|
cmd.states[0] =
|
||||||
memory_pool->Translate(CpuAddr(voice_state.biquad_states[0].data()),
|
memory_pool->Translate(CpuAddr(voice_state.biquad_states[0].data()),
|
||||||
MaxBiquadFilters * sizeof(VoiceState::BiquadFilterState));
|
MaxBiquadFilters * sizeof(VoiceState::BiquadFilterState));
|
||||||
|
|
|
@ -51,40 +51,6 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
|
||||||
state.s3 = Common::BitCast<s64>(s[3]);
|
state.s3 = Common::BitCast<s64>(s[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Biquad filter float implementation with native float coefficients.
|
|
||||||
*/
|
|
||||||
void ApplyBiquadFilterFloat2(std::span<s32> output, std::span<const s32> input,
|
|
||||||
std::array<f32, 3>& b, std::array<f32, 2>& a,
|
|
||||||
VoiceState::BiquadFilterState& state, const u32 sample_count) {
|
|
||||||
constexpr f64 min{std::numeric_limits<s32>::min()};
|
|
||||||
constexpr f64 max{std::numeric_limits<s32>::max()};
|
|
||||||
|
|
||||||
std::array<f64, 3> b_double{static_cast<f64>(b[0]), static_cast<f64>(b[1]),
|
|
||||||
static_cast<f64>(b[2])};
|
|
||||||
std::array<f64, 2> a_double{static_cast<f64>(a[0]), static_cast<f64>(a[1])};
|
|
||||||
std::array<f64, 4> s{Common::BitCast<f64>(state.s0), Common::BitCast<f64>(state.s1),
|
|
||||||
Common::BitCast<f64>(state.s2), Common::BitCast<f64>(state.s3)};
|
|
||||||
|
|
||||||
for (u32 i = 0; i < sample_count; i++) {
|
|
||||||
f64 in_sample{static_cast<f64>(input[i])};
|
|
||||||
auto sample{in_sample * b_double[0] + s[0] * b_double[1] + s[1] * b_double[2] +
|
|
||||||
s[2] * a_double[0] + s[3] * a_double[1]};
|
|
||||||
|
|
||||||
output[i] = static_cast<s32>(std::clamp(sample, min, max));
|
|
||||||
|
|
||||||
s[1] = s[0];
|
|
||||||
s[0] = in_sample;
|
|
||||||
s[3] = s[2];
|
|
||||||
s[2] = sample;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.s0 = Common::BitCast<s64>(s[0]);
|
|
||||||
state.s1 = Common::BitCast<s64>(s[1]);
|
|
||||||
state.s2 = Common::BitCast<s64>(s[2]);
|
|
||||||
state.s3 = Common::BitCast<s64>(s[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Biquad filter s32 implementation.
|
* Biquad filter s32 implementation.
|
||||||
*
|
*
|
||||||
|
@ -132,14 +98,8 @@ void BiquadFilterCommand::Process(const AudioRenderer::CommandListProcessor& pro
|
||||||
processor.mix_buffers.subspan(output * processor.sample_count, processor.sample_count)};
|
processor.mix_buffers.subspan(output * processor.sample_count, processor.sample_count)};
|
||||||
|
|
||||||
if (use_float_processing) {
|
if (use_float_processing) {
|
||||||
// REV15+: Use native float coefficients if available
|
ApplyBiquadFilterFloat(output_buffer, input_buffer, biquad.b, biquad.a, *state_,
|
||||||
if (use_float_coefficients) {
|
processor.sample_count);
|
||||||
ApplyBiquadFilterFloat2(output_buffer, input_buffer, biquad_float.numerator,
|
|
||||||
biquad_float.denominator, *state_, processor.sample_count);
|
|
||||||
} else {
|
|
||||||
ApplyBiquadFilterFloat(output_buffer, input_buffer, biquad.b, biquad.a, *state_,
|
|
||||||
processor.sample_count);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ApplyBiquadFilterInt(output_buffer, input_buffer, biquad.b, biquad.a, *state_,
|
ApplyBiquadFilterInt(output_buffer, input_buffer, biquad.b, biquad.a, *state_,
|
||||||
processor.sample_count);
|
processor.sample_count);
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -53,16 +50,12 @@ struct BiquadFilterCommand : ICommand {
|
||||||
s16 output;
|
s16 output;
|
||||||
/// Input parameters for biquad
|
/// Input parameters for biquad
|
||||||
VoiceInfo::BiquadFilterParameter biquad;
|
VoiceInfo::BiquadFilterParameter biquad;
|
||||||
/// Input parameters for biquad (REV15+ native float)
|
|
||||||
VoiceInfo::BiquadFilterParameter2 biquad_float;
|
|
||||||
/// Biquad state, updated each call
|
/// Biquad state, updated each call
|
||||||
CpuAddr state;
|
CpuAddr state;
|
||||||
/// If true, reset the state
|
/// If true, reset the state
|
||||||
bool needs_init;
|
bool needs_init;
|
||||||
/// If true, use float processing rather than int
|
/// If true, use float processing rather than int
|
||||||
bool use_float_processing;
|
bool use_float_processing;
|
||||||
/// If true, use native float coefficients (REV15+)
|
|
||||||
bool use_float_coefficients;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,18 +72,4 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
|
||||||
std::array<s16, 3>& b, std::array<s16, 2>& a,
|
std::array<s16, 3>& b, std::array<s16, 2>& a,
|
||||||
VoiceState::BiquadFilterState& state, const u32 sample_count);
|
VoiceState::BiquadFilterState& state, const u32 sample_count);
|
||||||
|
|
||||||
/**
|
|
||||||
* Biquad filter float implementation with native float coefficients (SDK REV15+).
|
|
||||||
*
|
|
||||||
* @param output - Output container for filtered samples.
|
|
||||||
* @param input - Input container for samples to be filtered.
|
|
||||||
* @param b - Feedforward coefficients (float).
|
|
||||||
* @param a - Feedback coefficients (float).
|
|
||||||
* @param state - State to track previous samples.
|
|
||||||
* @param sample_count - Number of samples to process.
|
|
||||||
*/
|
|
||||||
void ApplyBiquadFilterFloat2(std::span<s32> output, std::span<const s32> input,
|
|
||||||
std::array<f32, 3>& b, std::array<f32, 2>& a,
|
|
||||||
VoiceState::BiquadFilterState& state, const u32 sample_count);
|
|
||||||
|
|
||||||
} // namespace AudioCore::Renderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -36,14 +33,8 @@ void MultiTapBiquadFilterCommand::Process(const AudioRenderer::CommandListProces
|
||||||
*state = {};
|
*state = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// REV15+: Use native float coefficients if available
|
ApplyBiquadFilterFloat(output_buffer, input_buffer, biquads[i].b, biquads[i].a, *state,
|
||||||
if (use_float_coefficients) {
|
processor.sample_count);
|
||||||
ApplyBiquadFilterFloat2(output_buffer, input_buffer, biquads_float[i].numerator,
|
|
||||||
biquads_float[i].denominator, *state, processor.sample_count);
|
|
||||||
} else {
|
|
||||||
ApplyBiquadFilterFloat(output_buffer, input_buffer, biquads[i].b, biquads[i].a, *state,
|
|
||||||
processor.sample_count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -52,16 +49,12 @@ struct MultiTapBiquadFilterCommand : ICommand {
|
||||||
s16 output;
|
s16 output;
|
||||||
/// Biquad parameters
|
/// Biquad parameters
|
||||||
std::array<VoiceInfo::BiquadFilterParameter, MaxBiquadFilters> biquads;
|
std::array<VoiceInfo::BiquadFilterParameter, MaxBiquadFilters> biquads;
|
||||||
/// Biquad parameters (REV15+ native float)
|
|
||||||
std::array<VoiceInfo::BiquadFilterParameter2, MaxBiquadFilters> biquads_float;
|
|
||||||
/// Biquad states, updated each call
|
/// Biquad states, updated each call
|
||||||
std::array<CpuAddr, MaxBiquadFilters> states;
|
std::array<CpuAddr, MaxBiquadFilters> states;
|
||||||
/// If each biquad needs initialisation
|
/// If each biquad needs initialisation
|
||||||
std::array<bool, MaxBiquadFilters> needs_init;
|
std::array<bool, MaxBiquadFilters> needs_init;
|
||||||
/// Number of active biquads
|
/// Number of active biquads
|
||||||
u8 filter_tap_count;
|
u8 filter_tap_count;
|
||||||
/// If true, use native float coefficients (REV15+)
|
|
||||||
bool use_float_coefficients;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::Renderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -35,16 +35,12 @@ SplitterDestinationData& SplitterContext::GetData(const u32 index) {
|
||||||
|
|
||||||
void SplitterContext::Setup(std::span<SplitterInfo> splitter_infos_, const u32 splitter_info_count_,
|
void SplitterContext::Setup(std::span<SplitterInfo> splitter_infos_, const u32 splitter_info_count_,
|
||||||
SplitterDestinationData* splitter_destinations_,
|
SplitterDestinationData* splitter_destinations_,
|
||||||
const u32 destination_count_, const bool splitter_bug_fixed_,
|
const u32 destination_count_, const bool splitter_bug_fixed_) {
|
||||||
const BehaviorInfo& behavior) {
|
|
||||||
splitter_infos = splitter_infos_;
|
splitter_infos = splitter_infos_;
|
||||||
info_count = splitter_info_count_;
|
info_count = splitter_info_count_;
|
||||||
splitter_destinations = splitter_destinations_;
|
splitter_destinations = splitter_destinations_;
|
||||||
destinations_count = destination_count_;
|
destinations_count = destination_count_;
|
||||||
splitter_bug_fixed = splitter_bug_fixed_;
|
splitter_bug_fixed = splitter_bug_fixed_;
|
||||||
splitter_prev_volume_reset_supported = behavior.IsSplitterPrevVolumeResetSupported();
|
|
||||||
splitter_biquad_param_supported = behavior.IsBiquadFilterParameterForSplitterEnabled();
|
|
||||||
splitter_float_coeff_supported = behavior.IsSplitterDestinationV2bSupported();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SplitterContext::UsingSplitter() const {
|
bool SplitterContext::UsingSplitter() const {
|
||||||
|
@ -88,7 +84,7 @@ bool SplitterContext::Initialize(const BehaviorInfo& behavior,
|
||||||
}
|
}
|
||||||
|
|
||||||
Setup(splitter_infos, params.splitter_infos, splitter_destinations,
|
Setup(splitter_infos, params.splitter_infos, splitter_destinations,
|
||||||
params.splitter_destinations, behavior.IsSplitterBugFixed(), behavior);
|
params.splitter_destinations, behavior.IsSplitterBugFixed());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -141,104 +137,19 @@ u32 SplitterContext::UpdateInfo(const u8* input, u32 offset, const u32 splitter_
|
||||||
|
|
||||||
u32 SplitterContext::UpdateData(const u8* input, u32 offset, const u32 count) {
|
u32 SplitterContext::UpdateData(const u8* input, u32 offset, const u32 count) {
|
||||||
for (u32 i = 0; i < count; i++) {
|
for (u32 i = 0; i < count; i++) {
|
||||||
// Version selection based on feature flags:
|
auto data_header{
|
||||||
// - REV12: integer biquad params (Version2a)
|
reinterpret_cast<const SplitterDestinationData::InParameter*>(input + offset)};
|
||||||
// - REV15: float coeff/biquad v2b
|
|
||||||
// - older: no biquad fields
|
|
||||||
if (!splitter_biquad_param_supported) {
|
|
||||||
const auto* data_header =
|
|
||||||
reinterpret_cast<const SplitterDestinationData::InParameter*>(input + offset);
|
|
||||||
|
|
||||||
if (data_header->magic != GetSplitterSendDataMagic()) {
|
if (data_header->magic != GetSplitterSendDataMagic()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if (data_header->id < 0 || data_header->id > destinations_count) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto modified_params = *data_header;
|
|
||||||
if (!splitter_prev_volume_reset_supported) {
|
|
||||||
modified_params.reset_prev_volume = false;
|
|
||||||
}
|
|
||||||
splitter_destinations[data_header->id].Update(modified_params);
|
|
||||||
offset += sizeof(SplitterDestinationData::InParameter);
|
|
||||||
} else if (!splitter_float_coeff_supported) {
|
|
||||||
// Version 2a: struct contains legacy fixed-point biquad filter fields (REV12+)
|
|
||||||
const auto* data_header_v2a =
|
|
||||||
reinterpret_cast<const SplitterDestinationData::InParameterVersion2a*>(input +
|
|
||||||
offset);
|
|
||||||
|
|
||||||
if (data_header_v2a->magic != GetSplitterSendDataMagic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (data_header_v2a->id < 0 || data_header_v2a->id > destinations_count) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map common fields to the base format
|
|
||||||
SplitterDestinationData::InParameter mapped{};
|
|
||||||
mapped.magic = data_header_v2a->magic;
|
|
||||||
mapped.id = data_header_v2a->id;
|
|
||||||
mapped.mix_volumes = data_header_v2a->mix_volumes;
|
|
||||||
mapped.mix_id = data_header_v2a->mix_id;
|
|
||||||
mapped.in_use = data_header_v2a->in_use;
|
|
||||||
mapped.reset_prev_volume =
|
|
||||||
splitter_prev_volume_reset_supported ? data_header_v2a->reset_prev_volume : false;
|
|
||||||
|
|
||||||
auto& destination = splitter_destinations[data_header_v2a->id];
|
|
||||||
destination.Update(mapped);
|
|
||||||
|
|
||||||
// Convert legacy fixed-point biquad params into float representation
|
|
||||||
auto biquad_filters = destination.GetBiquadFilters();
|
|
||||||
for (size_t filter_idx = 0; filter_idx < MaxBiquadFilters; filter_idx++) {
|
|
||||||
const auto& legacy = data_header_v2a->biquad_filters[filter_idx];
|
|
||||||
auto& out = biquad_filters[filter_idx];
|
|
||||||
out.enabled = legacy.enabled;
|
|
||||||
// s16 fixed-point scale: use Q14 like voices (b and a are s16, 1.0 ~= 1<<14)
|
|
||||||
constexpr float scale = 1.0f / static_cast<float>(1 << 14);
|
|
||||||
out.numerator[0] = static_cast<float>(legacy.b[0]) * scale;
|
|
||||||
out.numerator[1] = static_cast<float>(legacy.b[1]) * scale;
|
|
||||||
out.numerator[2] = static_cast<float>(legacy.b[2]) * scale;
|
|
||||||
out.denominator[0] = static_cast<float>(legacy.a[0]) * scale;
|
|
||||||
out.denominator[1] = static_cast<float>(legacy.a[1]) * scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += static_cast<u32>(sizeof(SplitterDestinationData::InParameterVersion2a));
|
|
||||||
} else {
|
|
||||||
// Version 2b: struct contains extra biquad filter fields with float coeffs
|
|
||||||
const auto* data_header_v2b =
|
|
||||||
reinterpret_cast<const SplitterDestinationData::InParameterVersion2b*>(input +
|
|
||||||
offset);
|
|
||||||
|
|
||||||
if (data_header_v2b->magic != GetSplitterSendDataMagic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (data_header_v2b->id < 0 || data_header_v2b->id > destinations_count) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map common fields to the old format
|
|
||||||
SplitterDestinationData::InParameter mapped{};
|
|
||||||
mapped.magic = data_header_v2b->magic;
|
|
||||||
mapped.id = data_header_v2b->id;
|
|
||||||
mapped.mix_volumes = data_header_v2b->mix_volumes;
|
|
||||||
mapped.mix_id = data_header_v2b->mix_id;
|
|
||||||
mapped.in_use = data_header_v2b->in_use;
|
|
||||||
mapped.reset_prev_volume =
|
|
||||||
splitter_prev_volume_reset_supported ? data_header_v2b->reset_prev_volume : false;
|
|
||||||
|
|
||||||
// Store biquad filters from V2b (REV15+)
|
|
||||||
auto& destination = splitter_destinations[data_header_v2b->id];
|
|
||||||
destination.Update(mapped);
|
|
||||||
|
|
||||||
// Copy biquad filter parameters
|
|
||||||
auto biquad_filters = destination.GetBiquadFilters();
|
|
||||||
for (size_t filter_idx = 0; filter_idx < MaxBiquadFilters; filter_idx++) {
|
|
||||||
biquad_filters[filter_idx] = data_header_v2b->biquad_filters[filter_idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += static_cast<u32>(sizeof(SplitterDestinationData::InParameterVersion2b));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data_header->id < 0 || data_header->id > destinations_count) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
splitter_destinations[data_header->id].Update(*data_header);
|
||||||
|
offset += sizeof(SplitterDestinationData::InParameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -171,11 +168,10 @@ private:
|
||||||
* @param splitter_destinations - Workbuffer for splitter destinations.
|
* @param splitter_destinations - Workbuffer for splitter destinations.
|
||||||
* @param destination_count - Number of destinations in the workbuffer.
|
* @param destination_count - Number of destinations in the workbuffer.
|
||||||
* @param splitter_bug_fixed - Is the splitter bug fixed?
|
* @param splitter_bug_fixed - Is the splitter bug fixed?
|
||||||
* @param behavior - Behavior info for feature support.
|
|
||||||
*/
|
*/
|
||||||
void Setup(std::span<SplitterInfo> splitter_infos, u32 splitter_info_count,
|
void Setup(std::span<SplitterInfo> splitter_infos, u32 splitter_info_count,
|
||||||
SplitterDestinationData* splitter_destinations, u32 destination_count,
|
SplitterDestinationData* splitter_destinations, u32 destination_count,
|
||||||
bool splitter_bug_fixed, const BehaviorInfo& behavior);
|
bool splitter_bug_fixed);
|
||||||
|
|
||||||
/// Workbuffer for splitters
|
/// Workbuffer for splitters
|
||||||
std::span<SplitterInfo> splitter_infos{};
|
std::span<SplitterInfo> splitter_infos{};
|
||||||
|
@ -187,12 +183,6 @@ private:
|
||||||
s32 destinations_count{};
|
s32 destinations_count{};
|
||||||
/// Is the splitter bug fixed?
|
/// Is the splitter bug fixed?
|
||||||
bool splitter_bug_fixed{};
|
bool splitter_bug_fixed{};
|
||||||
/// Is explicit previous mix volume reset supported?
|
|
||||||
bool splitter_prev_volume_reset_supported{};
|
|
||||||
/// Is biquad filter parameter for splitter (REV12) supported?
|
|
||||||
bool splitter_biquad_param_supported{};
|
|
||||||
/// Is float coefficient/biquad filter v2b parameter supported?
|
|
||||||
bool splitter_float_coeff_supported{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Renderer
|
} // namespace Renderer
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -87,14 +84,4 @@ void SplitterDestinationData::SetNext(SplitterDestinationData* next_) {
|
||||||
next = next_;
|
next = next_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::span<SplitterDestinationData::BiquadFilterParameter2>
|
|
||||||
SplitterDestinationData::GetBiquadFilters() {
|
|
||||||
return biquad_filters;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::span<const SplitterDestinationData::BiquadFilterParameter2>
|
|
||||||
SplitterDestinationData::GetBiquadFilters() const {
|
|
||||||
return biquad_filters;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace AudioCore::Renderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -19,72 +16,16 @@ namespace AudioCore::Renderer {
|
||||||
*/
|
*/
|
||||||
class SplitterDestinationData {
|
class SplitterDestinationData {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Biquad filter parameter with float coefficients (SDK REV15+).
|
|
||||||
* Defined here to avoid circular dependency with VoiceInfo.
|
|
||||||
*/
|
|
||||||
struct BiquadFilterParameter2 {
|
|
||||||
/* 0x00 */ bool enabled;
|
|
||||||
/* 0x01 */ u8 reserved1;
|
|
||||||
/* 0x02 */ u8 reserved2;
|
|
||||||
/* 0x03 */ u8 reserved3;
|
|
||||||
/* 0x04 */ std::array<f32, 3> numerator; // b0, b1, b2
|
|
||||||
/* 0x10 */ std::array<f32, 2> denominator; // a1, a2 (a0 = 1)
|
|
||||||
};
|
|
||||||
static_assert(sizeof(BiquadFilterParameter2) == 0x18,
|
|
||||||
"BiquadFilterParameter2 has the wrong size!");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Legacy biquad filter parameter with fixed-point coefficients (SDK REV12+ for splitters).
|
|
||||||
* Matches the old voice biquad format.
|
|
||||||
*/
|
|
||||||
struct BiquadFilterParameterLegacy {
|
|
||||||
/* 0x00 */ bool enabled;
|
|
||||||
/* 0x02 */ std::array<s16, 3> b; // numerator
|
|
||||||
/* 0x08 */ std::array<s16, 2> a; // denominator (a0 = 1)
|
|
||||||
};
|
|
||||||
static_assert(sizeof(BiquadFilterParameterLegacy) == 0xC,
|
|
||||||
"BiquadFilterParameterLegacy has the wrong size!");
|
|
||||||
|
|
||||||
struct InParameter {
|
struct InParameter {
|
||||||
/* 0x00 */ u32 magic; // 'SNDD'
|
/* 0x00 */ u32 magic; // 'SNDD'
|
||||||
/* 0x04 */ s32 id;
|
/* 0x04 */ s32 id;
|
||||||
/* 0x08 */ std::array<f32, MaxMixBuffers> mix_volumes;
|
/* 0x08 */ std::array<f32, MaxMixBuffers> mix_volumes;
|
||||||
/* 0x68 */ u32 mix_id;
|
/* 0x68 */ u32 mix_id;
|
||||||
/* 0x6C */ bool in_use;
|
/* 0x6C */ bool in_use;
|
||||||
/* 0x6D */ bool reset_prev_volume;
|
|
||||||
};
|
};
|
||||||
static_assert(sizeof(InParameter) == 0x70,
|
static_assert(sizeof(InParameter) == 0x70,
|
||||||
"SplitterDestinationData::InParameter has the wrong size!");
|
"SplitterDestinationData::InParameter has the wrong size!");
|
||||||
|
|
||||||
struct InParameterVersion2a {
|
|
||||||
/* 0x00 */ u32 magic; // 'SNDD'
|
|
||||||
/* 0x04 */ s32 id;
|
|
||||||
/* 0x08 */ std::array<f32, MaxMixBuffers> mix_volumes;
|
|
||||||
/* 0x68 */ u32 mix_id;
|
|
||||||
/* 0x6C */ std::array<SplitterDestinationData::BiquadFilterParameterLegacy, MaxBiquadFilters>
|
|
||||||
biquad_filters;
|
|
||||||
/* 0x84 */ bool in_use;
|
|
||||||
/* 0x85 */ bool reset_prev_volume; // only effective if supported
|
|
||||||
/* 0x86 */ u8 reserved[10];
|
|
||||||
};
|
|
||||||
static_assert(sizeof(InParameterVersion2a) == 0x90,
|
|
||||||
"SplitterDestinationData::InParameterVersion2a has the wrong size!");
|
|
||||||
|
|
||||||
struct InParameterVersion2b {
|
|
||||||
/* 0x00 */ u32 magic; // 'SNDD'
|
|
||||||
/* 0x04 */ s32 id;
|
|
||||||
/* 0x08 */ std::array<f32, MaxMixBuffers> mix_volumes;
|
|
||||||
/* 0x68 */ u32 mix_id;
|
|
||||||
/* 0x6C */ std::array<SplitterDestinationData::BiquadFilterParameter2, MaxBiquadFilters>
|
|
||||||
biquad_filters;
|
|
||||||
/* 0x9C */ bool in_use;
|
|
||||||
/* 0x9D */ bool reset_prev_volume;
|
|
||||||
/* 0x9E */ u8 reserved[10];
|
|
||||||
};
|
|
||||||
static_assert(sizeof(InParameterVersion2b) == 0xA8,
|
|
||||||
"SplitterDestinationData::InParameterVersion2b has the wrong size!");
|
|
||||||
|
|
||||||
SplitterDestinationData(s32 id);
|
SplitterDestinationData(s32 id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,7 +78,7 @@ public:
|
||||||
f32 GetMixVolumePrev(u32 index) const;
|
f32 GetMixVolumePrev(u32 index) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the previous mix volumes for all mix buffers.
|
* Get the previous mix volumes for all mix buffers in this destination.
|
||||||
*
|
*
|
||||||
* @return Span of previous mix buffer volumes.
|
* @return Span of previous mix buffer volumes.
|
||||||
*/
|
*/
|
||||||
|
@ -174,20 +115,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void SetNext(SplitterDestinationData* next);
|
void SetNext(SplitterDestinationData* next);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get biquad filter parameters for this destination (REV15+ or mapped from REV12).
|
|
||||||
*
|
|
||||||
* @return Span of biquad filter parameters.
|
|
||||||
*/
|
|
||||||
std::span<BiquadFilterParameter2> GetBiquadFilters();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get const biquad filter parameters for this destination (REV15+ or mapped from REV12).
|
|
||||||
*
|
|
||||||
* @return Const span of biquad filter parameters.
|
|
||||||
*/
|
|
||||||
std::span<const BiquadFilterParameter2> GetBiquadFilters() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Id of this destination
|
/// Id of this destination
|
||||||
const s32 id;
|
const s32 id;
|
||||||
|
@ -197,8 +124,6 @@ private:
|
||||||
std::array<f32, MaxMixBuffers> mix_volumes{0.0f};
|
std::array<f32, MaxMixBuffers> mix_volumes{0.0f};
|
||||||
/// Previous mix volumes
|
/// Previous mix volumes
|
||||||
std::array<f32, MaxMixBuffers> prev_mix_volumes{0.0f};
|
std::array<f32, MaxMixBuffers> prev_mix_volumes{0.0f};
|
||||||
/// Biquad filter parameters (REV15+ or mapped from REV12)
|
|
||||||
std::array<BiquadFilterParameter2, MaxBiquadFilters> biquad_filters{};
|
|
||||||
/// Next destination in the mix chain
|
/// Next destination in the mix chain
|
||||||
SplitterDestinationData* next{};
|
SplitterDestinationData* next{};
|
||||||
/// Is this destination in use?
|
/// Is this destination in use?
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -138,17 +135,6 @@ public:
|
||||||
static_assert(sizeof(BiquadFilterParameter) == 0xC,
|
static_assert(sizeof(BiquadFilterParameter) == 0xC,
|
||||||
"VoiceInfo::BiquadFilterParameter has the wrong size!");
|
"VoiceInfo::BiquadFilterParameter has the wrong size!");
|
||||||
|
|
||||||
struct BiquadFilterParameter2 {
|
|
||||||
/* 0x00 */ bool enabled;
|
|
||||||
/* 0x01 */ u8 reserved1;
|
|
||||||
/* 0x02 */ u8 reserved2;
|
|
||||||
/* 0x03 */ u8 reserved3;
|
|
||||||
/* 0x04 */ std::array<f32, 3> numerator; // b0, b1, b2
|
|
||||||
/* 0x10 */ std::array<f32, 2> denominator; // a1, a2 (a0 = 1)
|
|
||||||
};
|
|
||||||
static_assert(sizeof(BiquadFilterParameter2) == 0x18,
|
|
||||||
"VoiceInfo::BiquadFilterParameter2 has the wrong size!");
|
|
||||||
|
|
||||||
struct InParameter {
|
struct InParameter {
|
||||||
/* 0x000 */ u32 id;
|
/* 0x000 */ u32 id;
|
||||||
/* 0x004 */ u32 node_id;
|
/* 0x004 */ u32 node_id;
|
||||||
|
@ -182,43 +168,6 @@ public:
|
||||||
};
|
};
|
||||||
static_assert(sizeof(InParameter) == 0x170, "VoiceInfo::InParameter has the wrong size!");
|
static_assert(sizeof(InParameter) == 0x170, "VoiceInfo::InParameter has the wrong size!");
|
||||||
|
|
||||||
struct InParameter2 {
|
|
||||||
/* 0x000 */ u32 id;
|
|
||||||
/* 0x004 */ u32 node_id;
|
|
||||||
/* 0x008 */ bool is_new;
|
|
||||||
/* 0x009 */ bool in_use;
|
|
||||||
/* 0x00A */ PlayState play_state;
|
|
||||||
/* 0x00B */ SampleFormat sample_format;
|
|
||||||
/* 0x00C */ u32 sample_rate;
|
|
||||||
/* 0x010 */ s32 priority;
|
|
||||||
/* 0x014 */ s32 sort_order;
|
|
||||||
/* 0x018 */ u32 channel_count;
|
|
||||||
/* 0x01C */ f32 pitch;
|
|
||||||
/* 0x020 */ f32 volume;
|
|
||||||
/* 0x024 */ std::array<BiquadFilterParameter2, MaxBiquadFilters> biquads;
|
|
||||||
/* 0x054 */ u32 wave_buffer_count;
|
|
||||||
/* 0x058 */ u32 wave_buffer_index;
|
|
||||||
/* 0x05C */ u32 reserved1;
|
|
||||||
/* 0x060 */ CpuAddr src_data_address;
|
|
||||||
/* 0x068 */ u64 src_data_size;
|
|
||||||
/* 0x070 */ u32 mix_id;
|
|
||||||
/* 0x074 */ u32 splitter_id;
|
|
||||||
/* 0x078 */ std::array<WaveBufferInternal, MaxWaveBuffers> wave_buffer_internal;
|
|
||||||
/* 0x158 */ std::array<s32, MaxChannels> channel_resource_ids;
|
|
||||||
/* 0x170 */ bool clear_voice_drop;
|
|
||||||
/* 0x171 */ u8 flush_buffer_count;
|
|
||||||
/* 0x172 */ u16 reserved2;
|
|
||||||
/* 0x174 */ Flags flags;
|
|
||||||
/* 0x175 */ u8 reserved3;
|
|
||||||
/* 0x176 */ SrcQuality src_quality;
|
|
||||||
/* 0x177 */ u8 reserved4;
|
|
||||||
/* 0x178 */ u32 external_context;
|
|
||||||
/* 0x17C */ u32 external_context_size;
|
|
||||||
/* 0x180 */ u32 reserved5;
|
|
||||||
/* 0x184 */ u32 reserved6;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(InParameter2) == 0x188, "VoiceInfo::InParameter2 has the wrong size!");
|
|
||||||
|
|
||||||
struct OutStatus {
|
struct OutStatus {
|
||||||
/* 0x00 */ u64 played_sample_count;
|
/* 0x00 */ u64 played_sample_count;
|
||||||
/* 0x08 */ u32 wave_buffers_consumed;
|
/* 0x08 */ u32 wave_buffers_consumed;
|
||||||
|
@ -400,10 +349,6 @@ public:
|
||||||
f32 prev_volume{};
|
f32 prev_volume{};
|
||||||
/// Biquad filters for generating filter commands on this voice
|
/// Biquad filters for generating filter commands on this voice
|
||||||
std::array<BiquadFilterParameter, MaxBiquadFilters> biquads{};
|
std::array<BiquadFilterParameter, MaxBiquadFilters> biquads{};
|
||||||
/// Float biquad filters for REV15+ (native float coefficients)
|
|
||||||
std::array<BiquadFilterParameter2, MaxBiquadFilters> biquads_float{};
|
|
||||||
/// Use float biquad coefficients (REV15+)
|
|
||||||
bool use_float_biquads{};
|
|
||||||
/// Number of active wavebuffers
|
/// Number of active wavebuffers
|
||||||
u32 wave_buffer_count{};
|
u32 wave_buffer_count{};
|
||||||
/// Current playing wavebuffer index
|
/// Current playing wavebuffer index
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
|
|
|
@ -301,10 +301,6 @@ void TranslateResolutionInfo(ResolutionSetup setup, ResolutionScalingInfo& info)
|
||||||
info.up_scale = 3;
|
info.up_scale = 3;
|
||||||
info.down_shift = 1;
|
info.down_shift = 1;
|
||||||
break;
|
break;
|
||||||
case ResolutionSetup::Res5_4X:
|
|
||||||
info.up_scale = 5;
|
|
||||||
info.down_shift = 2;
|
|
||||||
break;
|
|
||||||
case ResolutionSetup::Res2X:
|
case ResolutionSetup::Res2X:
|
||||||
info.up_scale = 2;
|
info.up_scale = 2;
|
||||||
info.down_shift = 0;
|
info.down_shift = 0;
|
||||||
|
|
|
@ -336,6 +336,7 @@ struct Values {
|
||||||
"shader_backend", Category::Renderer, Specialization::RuntimeList};
|
"shader_backend", Category::Renderer, Specialization::RuntimeList};
|
||||||
SwitchableSetting<int> vulkan_device{linkage, 0, "vulkan_device", Category::Renderer,
|
SwitchableSetting<int> vulkan_device{linkage, 0, "vulkan_device", Category::Renderer,
|
||||||
Specialization::RuntimeList};
|
Specialization::RuntimeList};
|
||||||
|
SwitchableSetting<bool> enable_raii{linkage, false, "enable_raii", Category::Renderer};
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
SwitchableSetting<bool> frame_interpolation{linkage, true, "frame_interpolation", Category::Renderer,
|
SwitchableSetting<bool> frame_interpolation{linkage, true, "frame_interpolation", Category::Renderer,
|
||||||
Specialization::RuntimeList};
|
Specialization::RuntimeList};
|
||||||
|
|
|
@ -142,8 +142,8 @@ ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb)
|
||||||
ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
|
ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
|
||||||
ENUM(FullscreenMode, Borderless, Exclusive);
|
ENUM(FullscreenMode, Borderless, Exclusive);
|
||||||
ENUM(NvdecEmulation, Off, Cpu, Gpu);
|
ENUM(NvdecEmulation, Off, Cpu, Gpu);
|
||||||
ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res5_4X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X);
|
ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X);
|
||||||
ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Gaussian, Lanczos, ScaleForce, Fsr, Area, ZeroTangent, BSpline, Mitchell, Spline1, Mmpx, MaxEnum);
|
ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum);
|
||||||
ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
|
ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
|
||||||
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
|
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
|
||||||
ENUM(ConsoleMode, Handheld, Docked);
|
ENUM(ConsoleMode, Handheld, Docked);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project
|
// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project
|
||||||
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
@ -17,8 +18,9 @@
|
||||||
#else
|
#else
|
||||||
#if defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
#if defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
#include <pthread_np.h>
|
#include <pthread_np.h>
|
||||||
#endif
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -91,35 +93,33 @@ void SetCurrentThreadName(const char* name) {
|
||||||
#else // !MSVC_VER, so must be POSIX threads
|
#else // !MSVC_VER, so must be POSIX threads
|
||||||
|
|
||||||
// MinGW with the POSIX threading model does not support pthread_setname_np
|
// MinGW with the POSIX threading model does not support pthread_setname_np
|
||||||
|
#if !defined(_WIN32) || defined(_MSC_VER)
|
||||||
void SetCurrentThreadName(const char* name) {
|
void SetCurrentThreadName(const char* name) {
|
||||||
// See for reference
|
|
||||||
// https://gitlab.freedesktop.org/mesa/mesa/-/blame/main/src/util/u_thread.c?ref_type=heads#L75
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
pthread_setname_np(name);
|
pthread_setname_np(name);
|
||||||
#elif defined(__HAIKU__)
|
|
||||||
rename_thread(find_thread(NULL), name);
|
|
||||||
#elif defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
#elif defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
pthread_set_name_np(pthread_self(), name);
|
pthread_set_name_np(pthread_self(), name);
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
pthread_setname_np(pthread_self(), "%s", (void*)name);
|
pthread_setname_np(pthread_self(), "%s", (void*)name);
|
||||||
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__sun__) || defined(__glibc__) || defined(__managarm__)
|
#elif defined(__linux__)
|
||||||
int ret = pthread_setname_np(pthread_self(), name);
|
// Linux limits thread names to 15 characters and will outright reject any
|
||||||
if (ret == ERANGE) {
|
// attempt to set a longer name with ERANGE.
|
||||||
// Linux limits thread names to 15 characters and will outright reject any
|
std::string truncated(name, (std::min)(strlen(name), static_cast<size_t>(15)));
|
||||||
// attempt to set a longer name with ERANGE.
|
if (int e = pthread_setname_np(pthread_self(), truncated.c_str())) {
|
||||||
char buf[16];
|
errno = e;
|
||||||
size_t const len = std::min<size_t>(std::strlen(name), sizeof(buf) - 1);
|
LOG_ERROR(Common, "Failed to set thread name to '{}': {}", truncated, GetLastErrorMsg());
|
||||||
std::memcpy(buf, name, len);
|
|
||||||
buf[len] = '\0';
|
|
||||||
pthread_setname_np(pthread_self(), buf);
|
|
||||||
}
|
}
|
||||||
#elif !defined(_WIN32) || defined(_MSC_VER)
|
|
||||||
// mingw stub
|
|
||||||
(void)name;
|
|
||||||
#else
|
#else
|
||||||
pthread_setname_np(pthread_self(), name);
|
pthread_setname_np(pthread_self(), name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
void SetCurrentThreadName(const char* name) {
|
||||||
|
// Do Nothing on MingW
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
@ -128,6 +129,10 @@ std::string SaveDataFactory::GetFullPath(ProgramId program_id, VirtualDir dir,
|
||||||
|
|
||||||
std::string out = GetSaveDataSpaceIdPath(space);
|
std::string out = GetSaveDataSpaceIdPath(space);
|
||||||
|
|
||||||
|
LOG_INFO(Common_Filesystem, "Save ID: {:016X}", save_id);
|
||||||
|
LOG_INFO(Common_Filesystem, "User ID[1]: {:016X}", user_id[1]);
|
||||||
|
LOG_INFO(Common_Filesystem, "User ID[0]: {:016X}", user_id[0]);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SaveDataType::System:
|
case SaveDataType::System:
|
||||||
return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]);
|
return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]);
|
||||||
|
|
|
@ -4,17 +4,13 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <filesystem>
|
|
||||||
#include <iostream>
|
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
#include <fmt/ranges.h>
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
#include "common/fs/file.h"
|
#include "common/fs/file.h"
|
||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
#include "common/fs/fs_types.h"
|
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
@ -94,11 +90,6 @@ bool ProfileManager::RemoveProfileAtIndex(std::size_t index) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileManager::RemoveAllProfiles()
|
|
||||||
{
|
|
||||||
profiles = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper function to register a user to the system
|
/// Helper function to register a user to the system
|
||||||
Result ProfileManager::AddUser(const ProfileInfo& user) {
|
Result ProfileManager::AddUser(const ProfileInfo& user) {
|
||||||
if (!AddToProfiles(user)) {
|
if (!AddToProfiles(user)) {
|
||||||
|
@ -268,9 +259,8 @@ void ProfileManager::CloseUser(UUID uuid) {
|
||||||
/// Gets all valid user ids on the system
|
/// Gets all valid user ids on the system
|
||||||
UserIDArray ProfileManager::GetAllUsers() const {
|
UserIDArray ProfileManager::GetAllUsers() const {
|
||||||
UserIDArray output{};
|
UserIDArray output{};
|
||||||
std::ranges::transform(profiles, output.begin(), [](const ProfileInfo& p) {
|
std::ranges::transform(profiles, output.begin(),
|
||||||
return p.user_uuid;
|
[](const ProfileInfo& p) { return p.user_uuid; });
|
||||||
});
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,19 +387,18 @@ bool ProfileManager::SetProfileBaseAndData(Common::UUID uuid, const ProfileBase&
|
||||||
void ProfileManager::ParseUserSaveFile() {
|
void ProfileManager::ParseUserSaveFile() {
|
||||||
const auto save_path(FS::GetEdenPath(FS::EdenPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH /
|
const auto save_path(FS::GetEdenPath(FS::EdenPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH /
|
||||||
"profiles.dat");
|
"profiles.dat");
|
||||||
|
|
||||||
const FS::IOFile save(save_path, FS::FileAccessMode::Read, FS::FileType::BinaryFile);
|
const FS::IOFile save(save_path, FS::FileAccessMode::Read, FS::FileType::BinaryFile);
|
||||||
|
|
||||||
if (!save.IsOpen()) {
|
if (!save.IsOpen()) {
|
||||||
LOG_WARNING(Service_ACC, "Failed to load profile data from save data... Generating new "
|
LOG_WARNING(Service_ACC, "Failed to load profile data from save data... Generating new "
|
||||||
"user 'Eden' with random UUID.");
|
"user 'eden' with random UUID.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileDataRaw data;
|
ProfileDataRaw data;
|
||||||
if (!save.ReadObject(data)) {
|
if (!save.ReadObject(data)) {
|
||||||
LOG_WARNING(Service_ACC, "profiles.dat is smaller than expected... Generating new user "
|
LOG_WARNING(Service_ACC, "profiles.dat is smaller than expected... Generating new user "
|
||||||
"'Eden' with random UUID.");
|
"'eden' with random UUID.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,82 +471,6 @@ void ProfileManager::WriteUserSaveFile() {
|
||||||
is_save_needed = false;
|
is_save_needed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileManager::ResetUserSaveFile()
|
|
||||||
{
|
|
||||||
RemoveAllProfiles();
|
|
||||||
ParseUserSaveFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> ProfileManager::FindOrphanedProfiles()
|
|
||||||
{
|
|
||||||
std::vector<std::string> good_uuids;
|
|
||||||
|
|
||||||
for (const ProfileInfo& p : profiles) {
|
|
||||||
std::string uuid_string = [p]() -> std::string {
|
|
||||||
auto uuid = p.user_uuid;
|
|
||||||
|
|
||||||
// "ignore" invalid uuids
|
|
||||||
if (uuid.IsInvalid()) {
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto user_id = uuid.AsU128();
|
|
||||||
|
|
||||||
return fmt::format("{:016X}{:016X}", user_id[1], user_id[0]);
|
|
||||||
}();
|
|
||||||
|
|
||||||
good_uuids.emplace_back(uuid_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
// used for acnh, etc
|
|
||||||
good_uuids.emplace_back("00000000000000000000000000000000");
|
|
||||||
|
|
||||||
// TODO: fetch save_id programmatically
|
|
||||||
const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir)
|
|
||||||
/ "user/save/0000000000000000";
|
|
||||||
|
|
||||||
std::vector<std::string> orphaned_profiles;
|
|
||||||
|
|
||||||
Common::FS::IterateDirEntries(
|
|
||||||
path,
|
|
||||||
[&good_uuids, &orphaned_profiles](const std::filesystem::directory_entry& entry) -> bool {
|
|
||||||
const std::string uuid = entry.path().stem().string();
|
|
||||||
|
|
||||||
// first off, we should always clear empty profiles
|
|
||||||
// 99% of the time these are useless. If not, they are recreated anyways...
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
const auto is_empty = [&entry]() -> bool {
|
|
||||||
try {
|
|
||||||
for (const auto& file : fs::recursive_directory_iterator(entry.path())) {
|
|
||||||
if (file.is_regular_file()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (const fs::filesystem_error& e) {
|
|
||||||
// if we get an error--no worries, just pretend it's not empty
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}();
|
|
||||||
|
|
||||||
if (!is_empty) {
|
|
||||||
fs::remove_all(entry);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if profiles.dat contains the UUID--all good
|
|
||||||
// if not--it's an orphaned profile and should be resolved by the user
|
|
||||||
if (std::find(good_uuids.begin(), good_uuids.end(), uuid) == good_uuids.end()) {
|
|
||||||
orphaned_profiles.emplace_back(uuid);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
Common::FS::DirEntryFilter::Directory);
|
|
||||||
|
|
||||||
return orphaned_profiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProfileManager::SetUserPosition(u64 position, Common::UUID uuid) {
|
void ProfileManager::SetUserPosition(u64 position, Common::UUID uuid) {
|
||||||
auto idxOpt = GetUserIndex(uuid);
|
auto idxOpt = GetUserIndex(uuid);
|
||||||
if (!idxOpt)
|
if (!idxOpt)
|
||||||
|
|
|
@ -103,15 +103,10 @@ public:
|
||||||
|
|
||||||
void WriteUserSaveFile();
|
void WriteUserSaveFile();
|
||||||
|
|
||||||
void ResetUserSaveFile();
|
|
||||||
|
|
||||||
std::vector<std::string> FindOrphanedProfiles();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ParseUserSaveFile();
|
void ParseUserSaveFile();
|
||||||
std::optional<std::size_t> AddToProfiles(const ProfileInfo& profile);
|
std::optional<std::size_t> AddToProfiles(const ProfileInfo& profile);
|
||||||
bool RemoveProfileAtIndex(std::size_t index);
|
bool RemoveProfileAtIndex(std::size_t index);
|
||||||
void RemoveAllProfiles();
|
|
||||||
|
|
||||||
bool is_save_needed{};
|
bool is_save_needed{};
|
||||||
std::array<ProfileInfo, MAX_USERS> profiles{};
|
std::array<ProfileInfo, MAX_USERS> profiles{};
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -71,6 +68,42 @@ std::string ResolveURL(const std::string& url) {
|
||||||
return url.substr(0, index) + "lp1" + url.substr(index + 1);
|
return url.substr(0, index) + "lp1" + url.substr(index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebArgInputTLVMap ReadWebArgs(const std::vector<u8>& web_arg, WebArgHeader& web_arg_header) {
|
||||||
|
std::memcpy(&web_arg_header, web_arg.data(), sizeof(WebArgHeader));
|
||||||
|
|
||||||
|
if (web_arg.size() == sizeof(WebArgHeader)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
WebArgInputTLVMap input_tlv_map;
|
||||||
|
|
||||||
|
u64 current_offset = sizeof(WebArgHeader);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < web_arg_header.total_tlv_entries; ++i) {
|
||||||
|
if (web_arg.size() < current_offset + sizeof(WebArgInputTLV)) {
|
||||||
|
return input_tlv_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebArgInputTLV input_tlv;
|
||||||
|
std::memcpy(&input_tlv, web_arg.data() + current_offset, sizeof(WebArgInputTLV));
|
||||||
|
|
||||||
|
current_offset += sizeof(WebArgInputTLV);
|
||||||
|
|
||||||
|
if (web_arg.size() < current_offset + input_tlv.arg_data_size) {
|
||||||
|
return input_tlv_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u8> data(input_tlv.arg_data_size);
|
||||||
|
std::memcpy(data.data(), web_arg.data() + current_offset, input_tlv.arg_data_size);
|
||||||
|
|
||||||
|
current_offset += input_tlv.arg_data_size;
|
||||||
|
|
||||||
|
input_tlv_map.insert_or_assign(input_tlv.input_tlv_type, std::move(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
return input_tlv_map;
|
||||||
|
}
|
||||||
|
|
||||||
FileSys::VirtualFile GetOfflineRomFS(Core::System& system, u64 title_id,
|
FileSys::VirtualFile GetOfflineRomFS(Core::System& system, u64 title_id,
|
||||||
FileSys::ContentRecordType nca_type) {
|
FileSys::ContentRecordType nca_type) {
|
||||||
if (nca_type == FileSys::ContentRecordType::Data) {
|
if (nca_type == FileSys::ContentRecordType::Data) {
|
||||||
|
@ -111,43 +144,6 @@ FileSys::VirtualFile GetOfflineRomFS(Core::System& system, u64 title_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef YUZU_USE_QT_WEB_ENGINE
|
|
||||||
WebArgInputTLVMap ReadWebArgs(const std::vector<u8>& web_arg, WebArgHeader& web_arg_header) {
|
|
||||||
std::memcpy(&web_arg_header, web_arg.data(), sizeof(WebArgHeader));
|
|
||||||
|
|
||||||
if (web_arg.size() == sizeof(WebArgHeader)) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
WebArgInputTLVMap input_tlv_map;
|
|
||||||
|
|
||||||
u64 current_offset = sizeof(WebArgHeader);
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < web_arg_header.total_tlv_entries; ++i) {
|
|
||||||
if (web_arg.size() < current_offset + sizeof(WebArgInputTLV)) {
|
|
||||||
return input_tlv_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebArgInputTLV input_tlv;
|
|
||||||
std::memcpy(&input_tlv, web_arg.data() + current_offset, sizeof(WebArgInputTLV));
|
|
||||||
|
|
||||||
current_offset += sizeof(WebArgInputTLV);
|
|
||||||
|
|
||||||
if (web_arg.size() < current_offset + input_tlv.arg_data_size) {
|
|
||||||
return input_tlv_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<u8> data(input_tlv.arg_data_size);
|
|
||||||
std::memcpy(data.data(), web_arg.data() + current_offset, input_tlv.arg_data_size);
|
|
||||||
|
|
||||||
current_offset += input_tlv.arg_data_size;
|
|
||||||
|
|
||||||
input_tlv_map.insert_or_assign(input_tlv.input_tlv_type, std::move(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
return input_tlv_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExtractSharedFonts(Core::System& system) {
|
void ExtractSharedFonts(Core::System& system) {
|
||||||
static constexpr std::array<const char*, 7> DECRYPTED_SHARED_FONTS{
|
static constexpr std::array<const char*, 7> DECRYPTED_SHARED_FONTS{
|
||||||
"FontStandard.ttf",
|
"FontStandard.ttf",
|
||||||
|
@ -225,7 +221,6 @@ void ExtractSharedFonts(Core::System& system) {
|
||||||
FileSys::VfsRawCopy(decrypted_font, out_file);
|
FileSys::VfsRawCopy(decrypted_font, out_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -237,7 +232,6 @@ WebBrowser::WebBrowser(Core::System& system_, std::shared_ptr<Applet> applet_,
|
||||||
WebBrowser::~WebBrowser() = default;
|
WebBrowser::~WebBrowser() = default;
|
||||||
|
|
||||||
void WebBrowser::Initialize() {
|
void WebBrowser::Initialize() {
|
||||||
#ifdef YUZU_USE_QT_WEB_ENGINE
|
|
||||||
FrontendApplet::Initialize();
|
FrontendApplet::Initialize();
|
||||||
|
|
||||||
LOG_INFO(Service_AM, "Initializing Web Browser Applet.");
|
LOG_INFO(Service_AM, "Initializing Web Browser Applet.");
|
||||||
|
@ -290,7 +284,6 @@ void WebBrowser::Initialize() {
|
||||||
ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind);
|
ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WebBrowser::GetStatus() const {
|
Result WebBrowser::GetStatus() const {
|
||||||
|
@ -302,7 +295,6 @@ void WebBrowser::ExecuteInteractive() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebBrowser::Execute() {
|
void WebBrowser::Execute() {
|
||||||
#ifdef YUZU_USE_QT_WEB_ENGINE
|
|
||||||
switch (web_arg_header.shim_kind) {
|
switch (web_arg_header.shim_kind) {
|
||||||
case ShimKind::Shop:
|
case ShimKind::Shop:
|
||||||
ExecuteShop();
|
ExecuteShop();
|
||||||
|
@ -330,10 +322,6 @@ void WebBrowser::Execute() {
|
||||||
WebBrowserExit(WebExitReason::EndButtonPressed);
|
WebBrowserExit(WebExitReason::EndButtonPressed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
LOG_INFO(Service_AM, "Web Browser Applet disabled, skipping.");
|
|
||||||
WebBrowserExit(WebExitReason::EndButtonPressed);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebBrowser::ExtractOfflineRomFS() {
|
void WebBrowser::ExtractOfflineRomFS() {
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -178,7 +175,6 @@ ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_
|
||||||
{0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"},
|
{0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"},
|
||||||
{1, nullptr, "TerminateAllLibraryApplets"},
|
{1, nullptr, "TerminateAllLibraryApplets"},
|
||||||
{2, nullptr, "AreAnyLibraryAppletsLeft"},
|
{2, nullptr, "AreAnyLibraryAppletsLeft"},
|
||||||
{3, D<&ILibraryAppletCreator::CreateLibraryAppletEx>, "CreateLibraryAppletEx"},
|
|
||||||
{10, D<&ILibraryAppletCreator::CreateStorage>, "CreateStorage"},
|
{10, D<&ILibraryAppletCreator::CreateStorage>, "CreateStorage"},
|
||||||
{11, D<&ILibraryAppletCreator::CreateTransferMemoryStorage>, "CreateTransferMemoryStorage"},
|
{11, D<&ILibraryAppletCreator::CreateTransferMemoryStorage>, "CreateTransferMemoryStorage"},
|
||||||
{12, D<&ILibraryAppletCreator::CreateHandleStorage>, "CreateHandleStorage"},
|
{12, D<&ILibraryAppletCreator::CreateHandleStorage>, "CreateHandleStorage"},
|
||||||
|
@ -214,32 +210,6 @@ Result ILibraryAppletCreator::CreateLibraryApplet(
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ILibraryAppletCreator::CreateLibraryAppletEx(
|
|
||||||
Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id,
|
|
||||||
LibraryAppletMode library_applet_mode, u64 thread_id) {
|
|
||||||
LOG_DEBUG(Service_AM, "called with applet_id={} applet_mode={} thread_id={}", applet_id,
|
|
||||||
library_applet_mode, thread_id);
|
|
||||||
|
|
||||||
std::shared_ptr<ILibraryAppletAccessor> library_applet;
|
|
||||||
if (ShouldCreateGuestApplet(applet_id)) {
|
|
||||||
library_applet =
|
|
||||||
CreateGuestApplet(system, m_window_system, m_applet, applet_id, library_applet_mode);
|
|
||||||
}
|
|
||||||
if (!library_applet) {
|
|
||||||
library_applet =
|
|
||||||
CreateFrontendApplet(system, m_window_system, m_applet, applet_id, library_applet_mode);
|
|
||||||
}
|
|
||||||
if (!library_applet) {
|
|
||||||
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
|
|
||||||
R_THROW(ResultUnknown);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Applet is created, can now be launched.
|
|
||||||
m_applet->library_applet_launchable_event.Signal();
|
|
||||||
*out_library_applet_accessor = library_applet;
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILibraryAppletCreator::CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size) {
|
Result ILibraryAppletCreator::CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size) {
|
||||||
LOG_DEBUG(Service_AM, "called, size={}", size);
|
LOG_DEBUG(Service_AM, "called, size={}", size);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -27,9 +24,6 @@ private:
|
||||||
Result CreateLibraryApplet(
|
Result CreateLibraryApplet(
|
||||||
Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id,
|
Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id,
|
||||||
LibraryAppletMode library_applet_mode);
|
LibraryAppletMode library_applet_mode);
|
||||||
Result CreateLibraryAppletEx(
|
|
||||||
Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id,
|
|
||||||
LibraryAppletMode library_applet_mode, u64 thread_id);
|
|
||||||
Result CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size);
|
Result CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size);
|
||||||
Result CreateTransferMemoryStorage(
|
Result CreateTransferMemoryStorage(
|
||||||
Out<SharedPointer<IStorage>> out_storage, bool is_writable, s64 size,
|
Out<SharedPointer<IStorage>> out_storage, bool is_writable, s64 size,
|
||||||
|
|
|
@ -128,7 +128,6 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
|
||||||
{406, nullptr, "GetApplicationControlProperty"},
|
{406, nullptr, "GetApplicationControlProperty"},
|
||||||
{407, nullptr, "ListApplicationTitle"},
|
{407, nullptr, "ListApplicationTitle"},
|
||||||
{408, nullptr, "ListApplicationIcon"},
|
{408, nullptr, "ListApplicationIcon"},
|
||||||
{419, D<&IApplicationManagerInterface::RequestDownloadApplicationControlDataInBackground>, "RequestDownloadApplicationControlDataInBackground"},
|
|
||||||
{502, nullptr, "RequestCheckGameCardRegistration"},
|
{502, nullptr, "RequestCheckGameCardRegistration"},
|
||||||
{503, nullptr, "RequestGameCardRegistrationGoldPoint"},
|
{503, nullptr, "RequestGameCardRegistrationGoldPoint"},
|
||||||
{504, nullptr, "RequestRegisterGameCard"},
|
{504, nullptr, "RequestRegisterGameCard"},
|
||||||
|
@ -211,7 +210,6 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
|
||||||
{1703, nullptr, "GetApplicationViewDownloadErrorContext"},
|
{1703, nullptr, "GetApplicationViewDownloadErrorContext"},
|
||||||
{1704, D<&IApplicationManagerInterface::GetApplicationViewWithPromotionInfo>, "GetApplicationViewWithPromotionInfo"},
|
{1704, D<&IApplicationManagerInterface::GetApplicationViewWithPromotionInfo>, "GetApplicationViewWithPromotionInfo"},
|
||||||
{1705, nullptr, "IsPatchAutoDeletableApplication"},
|
{1705, nullptr, "IsPatchAutoDeletableApplication"},
|
||||||
{1706, D<&IApplicationManagerInterface::Unknown1706>, "Unknown1706"},
|
|
||||||
{1800, nullptr, "IsNotificationSetupCompleted"},
|
{1800, nullptr, "IsNotificationSetupCompleted"},
|
||||||
{1801, nullptr, "GetLastNotificationInfoCount"},
|
{1801, nullptr, "GetLastNotificationInfoCount"},
|
||||||
{1802, nullptr, "ListLastNotificationInfo"},
|
{1802, nullptr, "ListLastNotificationInfo"},
|
||||||
|
@ -311,7 +309,6 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
|
||||||
{4022, D<&IApplicationManagerInterface::Unknown4022>, "Unknown4022"},
|
{4022, D<&IApplicationManagerInterface::Unknown4022>, "Unknown4022"},
|
||||||
{4023, D<&IApplicationManagerInterface::Unknown4023>, "Unknown4023"},
|
{4023, D<&IApplicationManagerInterface::Unknown4023>, "Unknown4023"},
|
||||||
{4088, D<&IApplicationManagerInterface::Unknown4022>, "Unknown4088"},
|
{4088, D<&IApplicationManagerInterface::Unknown4022>, "Unknown4088"},
|
||||||
{4053, D<&IApplicationManagerInterface::Unknown4053>, "Unknown4053"},
|
|
||||||
{9999, nullptr, "GetApplicationCertificate"},
|
{9999, nullptr, "GetApplicationCertificate"},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
@ -529,37 +526,6 @@ Result IApplicationManagerInterface::GetApplicationTerminateResult(Out<Result> o
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IApplicationManagerInterface::RequestDownloadApplicationControlDataInBackground(
|
|
||||||
u64 unk, u64 application_id) {
|
|
||||||
LOG_WARNING(Service_NS, "(STUBBED), app={:016X} unk={}", application_id, unk);
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IApplicationManagerInterface::Unknown1706(
|
|
||||||
OutBuffer<BufferAttr_HipcAutoSelect> out_buffer_58,
|
|
||||||
InBuffer<BufferAttr_HipcMapAlias> in_buffer_8) {
|
|
||||||
LOG_WARNING(Service_NS, "(STUBBED) Unknown1706 called: out_size={} in_size={}",
|
|
||||||
out_buffer_58.size(), in_buffer_8.size());
|
|
||||||
|
|
||||||
if (out_buffer_58.size() < 0x58 || in_buffer_8.size() < 0x8) {
|
|
||||||
R_THROW(ResultUnknown);
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 application_id = 0;
|
|
||||||
std::memcpy(&application_id, in_buffer_8.data(), sizeof(u64));
|
|
||||||
|
|
||||||
ApplicationView view{};
|
|
||||||
view.application_id = application_id;
|
|
||||||
view.unk = 0x70000;
|
|
||||||
view.flags = 0x401f17;
|
|
||||||
|
|
||||||
std::memset(out_buffer_58.data(), 0, out_buffer_58.size());
|
|
||||||
std::memcpy(out_buffer_58.data(), &view, sizeof(ApplicationView));
|
|
||||||
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IApplicationManagerInterface::Unknown4022(
|
Result IApplicationManagerInterface::Unknown4022(
|
||||||
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
LOG_WARNING(Service_NS, "(STUBBED) called");
|
LOG_WARNING(Service_NS, "(STUBBED) called");
|
||||||
|
@ -573,9 +539,4 @@ Result IApplicationManagerInterface::Unknown4023(Out<u64> out_result) {
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IApplicationManagerInterface::Unknown4053() {
|
|
||||||
LOG_WARNING(Service_NS, "(STUBBED) called.");
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::NS
|
} // namespace Service::NS
|
||||||
|
|
|
@ -55,12 +55,6 @@ public:
|
||||||
Result GetApplicationTerminateResult(Out<Result> out_result, u64 application_id);
|
Result GetApplicationTerminateResult(Out<Result> out_result, u64 application_id);
|
||||||
Result Unknown4022(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
Result Unknown4022(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||||
Result Unknown4023(Out<u64> out_result);
|
Result Unknown4023(Out<u64> out_result);
|
||||||
Result Unknown4053();
|
|
||||||
|
|
||||||
Result RequestDownloadApplicationControlDataInBackground(u64 unk,
|
|
||||||
u64 application_id);
|
|
||||||
Result Unknown1706(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer_58,
|
|
||||||
InBuffer<BufferAttr_HipcMapAlias> in_buffer_8);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KernelHelpers::ServiceContext service_context;
|
KernelHelpers::ServiceContext service_context;
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -84,11 +81,10 @@ static_assert(sizeof(PromotionInfo) == 0x20, "PromotionInfo has incorrect size."
|
||||||
|
|
||||||
/// NsApplicationViewWithPromotionInfo
|
/// NsApplicationViewWithPromotionInfo
|
||||||
struct ApplicationViewWithPromotionInfo {
|
struct ApplicationViewWithPromotionInfo {
|
||||||
ApplicationView view; ///< \ref NsApplicationView
|
ApplicationView view; ///< \ref NsApplicationView
|
||||||
PromotionInfo promotion; ///< \ref NsPromotionInfo
|
PromotionInfo promotion; ///< \ref NsPromotionInfo
|
||||||
std::array<u8, 0x8> padding{}; ///< Extra padding for newer HOS versions
|
|
||||||
};
|
};
|
||||||
static_assert(sizeof(ApplicationViewWithPromotionInfo) == 0x78,
|
static_assert(sizeof(ApplicationViewWithPromotionInfo) == 0x70,
|
||||||
"ApplicationViewWithPromotionInfo has incorrect size.");
|
"ApplicationViewWithPromotionInfo has incorrect size.");
|
||||||
|
|
||||||
struct ApplicationOccupiedSizeEntity {
|
struct ApplicationOccupiedSizeEntity {
|
||||||
|
@ -117,10 +113,4 @@ struct Uid {
|
||||||
};
|
};
|
||||||
static_assert(sizeof(Uid) == 0x10, "Uid has incorrect size.");
|
static_assert(sizeof(Uid) == 0x10, "Uid has incorrect size.");
|
||||||
|
|
||||||
struct ApplicationDisplayData {
|
|
||||||
std::array<char, 0x200> application_name;
|
|
||||||
std::array<char, 0x100> developer_name;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(ApplicationDisplayData) == 0x300, "ApplicationDisplayData has incorrect size.");
|
|
||||||
|
|
||||||
} // namespace Service::NS
|
} // namespace Service::NS
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -32,7 +29,7 @@ IQueryService::IQueryService(Core::System& system_) : ServiceFramework{system_,
|
||||||
{14, nullptr, "QueryRecentlyPlayedApplication"},
|
{14, nullptr, "QueryRecentlyPlayedApplication"},
|
||||||
{15, nullptr, "GetRecentlyPlayedApplicationUpdateEvent"},
|
{15, nullptr, "GetRecentlyPlayedApplicationUpdateEvent"},
|
||||||
{16, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystemV0"},
|
{16, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystemV0"},
|
||||||
{17, D<&IQueryService::QueryLastPlayTime>, "QueryLastPlayTime"},
|
{17, nullptr, "QueryLastPlayTime"},
|
||||||
{18, nullptr, "QueryApplicationPlayStatisticsForSystem"},
|
{18, nullptr, "QueryApplicationPlayStatisticsForSystem"},
|
||||||
{19, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystem"},
|
{19, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystem"},
|
||||||
};
|
};
|
||||||
|
@ -56,13 +53,4 @@ Result IQueryService::QueryPlayStatisticsByApplicationIdAndUserAccountId(
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IQueryService::QueryLastPlayTime(
|
|
||||||
Out<s32> out_entries, u8 unknown,
|
|
||||||
OutArray<LastPlayTime, BufferAttr_HipcMapAlias> out_last_play_times,
|
|
||||||
InArray<s32, BufferAttr_HipcMapAlias> application_ids) {
|
|
||||||
*out_entries = 1;
|
|
||||||
*out_last_play_times = {};
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::NS
|
} // namespace Service::NS
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -26,8 +23,6 @@ struct PlayStatistics {
|
||||||
};
|
};
|
||||||
static_assert(sizeof(PlayStatistics) == 0x28, "PlayStatistics is an invalid size");
|
static_assert(sizeof(PlayStatistics) == 0x28, "PlayStatistics is an invalid size");
|
||||||
|
|
||||||
struct LastPlayTime {};
|
|
||||||
|
|
||||||
class IQueryService final : public ServiceFramework<IQueryService> {
|
class IQueryService final : public ServiceFramework<IQueryService> {
|
||||||
public:
|
public:
|
||||||
explicit IQueryService(Core::System& system_);
|
explicit IQueryService(Core::System& system_);
|
||||||
|
@ -36,9 +31,6 @@ public:
|
||||||
private:
|
private:
|
||||||
Result QueryPlayStatisticsByApplicationIdAndUserAccountId(
|
Result QueryPlayStatisticsByApplicationIdAndUserAccountId(
|
||||||
Out<PlayStatistics> out_play_statistics, bool unknown, u64 application_id, Uid account_id);
|
Out<PlayStatistics> out_play_statistics, bool unknown, u64 application_id, Uid account_id);
|
||||||
Result QueryLastPlayTime(Out<s32> out_entries, u8 unknown,
|
|
||||||
OutArray<LastPlayTime, BufferAttr_HipcMapAlias> out_last_play_times,
|
|
||||||
InArray<s32, BufferAttr_HipcMapAlias> application_ids);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::NS
|
} // namespace Service::NS
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -10,7 +7,6 @@
|
||||||
#include "core/file_sys/vfs/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/ns/language.h"
|
#include "core/hle/service/ns/language.h"
|
||||||
#include "core/hle/service/ns/ns_types.h"
|
|
||||||
#include "core/hle/service/ns/ns_results.h"
|
#include "core/hle/service/ns/ns_results.h"
|
||||||
#include "core/hle/service/ns/read_only_application_control_data_interface.h"
|
#include "core/hle/service/ns/read_only_application_control_data_interface.h"
|
||||||
#include "core/hle/service/set/settings_server.h"
|
#include "core/hle/service/set/settings_server.h"
|
||||||
|
@ -27,7 +23,6 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
|
||||||
{2, D<&IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode>, "ConvertApplicationLanguageToLanguageCode"},
|
{2, D<&IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode>, "ConvertApplicationLanguageToLanguageCode"},
|
||||||
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
|
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
|
||||||
{4, nullptr, "SelectApplicationDesiredLanguage"},
|
{4, nullptr, "SelectApplicationDesiredLanguage"},
|
||||||
{5, D<&IReadOnlyApplicationControlDataInterface::GetApplicationDisplayData>, "GetApplicationDisplayData"},
|
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
@ -124,33 +119,4 @@ Result IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLan
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IReadOnlyApplicationControlDataInterface::GetApplicationDisplayData(
|
|
||||||
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u64> out_size, u64 language_code,
|
|
||||||
u64 application_id) {
|
|
||||||
LOG_INFO(Service_NS, "called with application_id={:016X}, language_code={:016X}",
|
|
||||||
application_id, language_code);
|
|
||||||
|
|
||||||
constexpr u64 payload_size = sizeof(ApplicationDisplayData);
|
|
||||||
|
|
||||||
if (out_buffer.size() < payload_size) {
|
|
||||||
LOG_ERROR(Service_NS, "output buffer is too small! (actual={}, expected_min={})",
|
|
||||||
out_buffer.size(), payload_size);
|
|
||||||
R_THROW(ResultUnknown);
|
|
||||||
}
|
|
||||||
|
|
||||||
const FileSys::PatchManager pm{application_id, system.GetFileSystemController(),
|
|
||||||
system.GetContentProvider()};
|
|
||||||
const auto control = pm.GetControlMetadata();
|
|
||||||
|
|
||||||
ApplicationDisplayData display_data{};
|
|
||||||
|
|
||||||
std::memset(display_data.application_name.data(), 0, display_data.application_name.size());
|
|
||||||
std::memset(display_data.developer_name.data(), 0, display_data.developer_name.size());
|
|
||||||
|
|
||||||
std::memcpy(out_buffer.data(), &display_data, payload_size);
|
|
||||||
*out_size = payload_size;
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::NS
|
} // namespace Service::NS
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/hle/service/cmif_types.h"
|
#include "core/hle/service/cmif_types.h"
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
#include "core/hle/service/ns/language.h"
|
#include "core/hle/service/ns/language.h"
|
||||||
#include "core/hle/service/ns/ns_types.h"
|
#include "core/hle/service/ns/ns_types.h"
|
||||||
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
namespace Service::NS {
|
namespace Service::NS {
|
||||||
|
|
||||||
|
@ -19,6 +16,7 @@ public:
|
||||||
explicit IReadOnlyApplicationControlDataInterface(Core::System& system_);
|
explicit IReadOnlyApplicationControlDataInterface(Core::System& system_);
|
||||||
~IReadOnlyApplicationControlDataInterface() override;
|
~IReadOnlyApplicationControlDataInterface() override;
|
||||||
|
|
||||||
|
public:
|
||||||
Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
|
Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
|
||||||
Out<u32> out_actual_size,
|
Out<u32> out_actual_size,
|
||||||
ApplicationControlSource application_control_source,
|
ApplicationControlSource application_control_source,
|
||||||
|
@ -27,10 +25,6 @@ public:
|
||||||
u32 supported_languages);
|
u32 supported_languages);
|
||||||
Result ConvertApplicationLanguageToLanguageCode(Out<u64> out_language_code,
|
Result ConvertApplicationLanguageToLanguageCode(Out<u64> out_language_code,
|
||||||
ApplicationLanguage application_language);
|
ApplicationLanguage application_language);
|
||||||
|
|
||||||
Result GetApplicationDisplayData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
|
|
||||||
Out<u64> out_size, u64 language_code,
|
|
||||||
u64 application_id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::NS
|
} // namespace Service::NS
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/ns/read_only_application_record_interface.h"
|
#include "core/hle/service/ns/read_only_application_record_interface.h"
|
||||||
#include "core/hle/service/ns/ns_types.h"
|
|
||||||
#include "core/hle/service/ns/application_manager_interface.h"
|
|
||||||
|
|
||||||
namespace Service::NS {
|
namespace Service::NS {
|
||||||
|
|
||||||
|
@ -18,8 +13,6 @@ IReadOnlyApplicationRecordInterface::IReadOnlyApplicationRecordInterface(Core::S
|
||||||
{1, nullptr, "NotifyApplicationFailure"},
|
{1, nullptr, "NotifyApplicationFailure"},
|
||||||
{2, D<&IReadOnlyApplicationRecordInterface::IsDataCorruptedResult>,
|
{2, D<&IReadOnlyApplicationRecordInterface::IsDataCorruptedResult>,
|
||||||
"IsDataCorruptedResult"},
|
"IsDataCorruptedResult"},
|
||||||
{3, D<&IReadOnlyApplicationRecordInterface::ListApplicationRecord>,
|
|
||||||
"ListApplicationRecord"},
|
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
@ -42,14 +35,4 @@ Result IReadOnlyApplicationRecordInterface::IsDataCorruptedResult(
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IReadOnlyApplicationRecordInterface::ListApplicationRecord(
|
|
||||||
OutArray<ApplicationRecord, BufferAttr_HipcMapAlias> out_records, Out<s32> out_count,
|
|
||||||
s32 entry_offset) {
|
|
||||||
LOG_DEBUG(Service_NS, "delegating to IApplicationManagerInterface::ListApplicationRecord, offset={} limit={}",
|
|
||||||
entry_offset, out_records.size());
|
|
||||||
|
|
||||||
R_RETURN(IApplicationManagerInterface(system).ListApplicationRecord(out_records, out_count,
|
|
||||||
entry_offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::NS
|
} // namespace Service::NS
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -8,7 +5,6 @@
|
||||||
|
|
||||||
#include "core/hle/service/cmif_types.h"
|
#include "core/hle/service/cmif_types.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "core/hle/service/ns/ns_types.h"
|
|
||||||
|
|
||||||
namespace Service::NS {
|
namespace Service::NS {
|
||||||
|
|
||||||
|
@ -21,9 +17,6 @@ public:
|
||||||
private:
|
private:
|
||||||
Result HasApplicationRecord(Out<bool> out_has_application_record, u64 program_id);
|
Result HasApplicationRecord(Out<bool> out_has_application_record, u64 program_id);
|
||||||
Result IsDataCorruptedResult(Out<bool> out_is_data_corrupted_result, Result result);
|
Result IsDataCorruptedResult(Out<bool> out_is_data_corrupted_result, Result result);
|
||||||
Result ListApplicationRecord(
|
|
||||||
OutArray<ApplicationRecord, BufferAttr_HipcMapAlias> out_records, Out<s32> out_count,
|
|
||||||
s32 entry_offset);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::NS
|
} // namespace Service::NS
|
||||||
|
|
|
@ -38,7 +38,6 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili
|
||||||
{1016, nullptr, "ConfirmShowNewsPermission"},
|
{1016, nullptr, "ConfirmShowNewsPermission"},
|
||||||
{1017, D<&IParentalControlService::EndFreeCommunication>, "EndFreeCommunication"},
|
{1017, D<&IParentalControlService::EndFreeCommunication>, "EndFreeCommunication"},
|
||||||
{1018, D<&IParentalControlService::IsFreeCommunicationAvailable>, "IsFreeCommunicationAvailable"},
|
{1018, D<&IParentalControlService::IsFreeCommunicationAvailable>, "IsFreeCommunicationAvailable"},
|
||||||
{1019, D<&IParentalControlService::ConfirmLaunchApplicationPermission>, "ConfirmLaunchApplicationPermission"},
|
|
||||||
{1031, D<&IParentalControlService::IsRestrictionEnabled>, "IsRestrictionEnabled"},
|
{1031, D<&IParentalControlService::IsRestrictionEnabled>, "IsRestrictionEnabled"},
|
||||||
{1032, D<&IParentalControlService::GetSafetyLevel>, "GetSafetyLevel"},
|
{1032, D<&IParentalControlService::GetSafetyLevel>, "GetSafetyLevel"},
|
||||||
{1033, nullptr, "SetSafetyLevel"},
|
{1033, nullptr, "SetSafetyLevel"},
|
||||||
|
|
|
@ -25,7 +25,11 @@ option(DYNARMIC_IGNORE_ASSERTS "Ignore asserts" OFF)
|
||||||
option(DYNARMIC_TESTS_USE_UNICORN "Enable fuzzing tests against unicorn" OFF)
|
option(DYNARMIC_TESTS_USE_UNICORN "Enable fuzzing tests against unicorn" OFF)
|
||||||
CMAKE_DEPENDENT_OPTION(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF "NOT YUZU_DISABLE_LLVM" OFF)
|
CMAKE_DEPENDENT_OPTION(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF "NOT YUZU_DISABLE_LLVM" OFF)
|
||||||
|
|
||||||
option(DYNARMIC_USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF)
|
if (PLATFORM_OPENBSD)
|
||||||
|
option(DYNARMIC_USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF)
|
||||||
|
else()
|
||||||
|
option(DYNARMIC_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(DYNARMIC_INSTALL "Install dynarmic headers and CMake files" OFF)
|
option(DYNARMIC_INSTALL "Install dynarmic headers and CMake files" OFF)
|
||||||
option(DYNARMIC_USE_BUNDLED_EXTERNALS "Use all bundled externals (useful when e.g. cross-compiling)" OFF)
|
option(DYNARMIC_USE_BUNDLED_EXTERNALS "Use all bundled externals (useful when e.g. cross-compiling)" OFF)
|
||||||
|
@ -77,6 +81,7 @@ if (MSVC)
|
||||||
/wd4592 # Symbol will be dynamically initialized (implementation limitation)
|
/wd4592 # Symbol will be dynamically initialized (implementation limitation)
|
||||||
/permissive- # Stricter C++ standards conformance
|
/permissive- # Stricter C++ standards conformance
|
||||||
/MP
|
/MP
|
||||||
|
/Zi
|
||||||
/Zo
|
/Zo
|
||||||
/EHsc
|
/EHsc
|
||||||
/Zc:externConstexpr # Allows external linkage for variables declared "extern constexpr", as the standard permits.
|
/Zc:externConstexpr # Allows external linkage for variables declared "extern constexpr", as the standard permits.
|
||||||
|
@ -86,11 +91,6 @@ if (MSVC)
|
||||||
/bigobj # Increase number of sections in .obj files
|
/bigobj # Increase number of sections in .obj files
|
||||||
/DNOMINMAX)
|
/DNOMINMAX)
|
||||||
|
|
||||||
if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
|
|
||||||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
|
||||||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (DYNARMIC_WARNINGS_AS_ERRORS)
|
if (DYNARMIC_WARNINGS_AS_ERRORS)
|
||||||
list(APPEND DYNARMIC_CXX_FLAGS
|
list(APPEND DYNARMIC_CXX_FLAGS
|
||||||
/WX)
|
/WX)
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
#include <mcl/mp/metavalue/lift_value.hpp>
|
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
|
|
||||||
#include "dynarmic/common/always_false.h"
|
#include "dynarmic/common/always_false.h"
|
||||||
|
|
|
@ -23,12 +23,6 @@ template<typename... Ts>
|
||||||
} \
|
} \
|
||||||
}())
|
}())
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSERT_FALSE
|
|
||||||
#define ASSERT_FALSE(...) \
|
|
||||||
([&]() { \
|
|
||||||
assert_terminate("false", __VA_ARGS__); \
|
|
||||||
}())
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ASSERT
|
#ifndef ASSERT
|
||||||
#define ASSERT(_a_) ASSERT_MSG(_a_, "")
|
#define ASSERT(_a_) ASSERT_MSG(_a_, "")
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2016 MerryMage
|
* Copyright (c) 2016 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
@ -9,7 +6,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Dynarmic::Common {
|
namespace Dynarmic::Common {
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
@ -162,17 +159,6 @@ struct NpadGcTriggerState {
|
||||||
};
|
};
|
||||||
static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
|
static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
|
||||||
|
|
||||||
// This is nn::hid::NpadCondition (global controller condition structure)
|
|
||||||
struct NpadCondition {
|
|
||||||
u32 _00{};
|
|
||||||
u32 is_initialized{1};
|
|
||||||
u32 hold_type{static_cast<u32>(NpadJoyHoldType::Horizontal)};
|
|
||||||
u32 is_valid{1};
|
|
||||||
};
|
|
||||||
static_assert(sizeof(NpadCondition) == 0x10, "NpadCondition is an invalid size");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This is nn::hid::NpadSystemProperties
|
// This is nn::hid::NpadSystemProperties
|
||||||
struct NPadSystemProperties {
|
struct NPadSystemProperties {
|
||||||
union {
|
union {
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -47,7 +44,8 @@ struct Lifo {
|
||||||
buffer_count++;
|
buffer_count++;
|
||||||
}
|
}
|
||||||
buffer_tail = GetNextEntryIndex();
|
buffer_tail = GetNextEntryIndex();
|
||||||
entries[buffer_tail].sampling_number = new_state.sampling_number << 1;
|
const auto& previous_entry = ReadPreviousEntry();
|
||||||
|
entries[buffer_tail].sampling_number = previous_entry.sampling_number + 1;
|
||||||
entries[buffer_tail].state = new_state;
|
entries[buffer_tail].state = new_state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
@ -204,9 +201,7 @@ static_assert(sizeof(ConsoleSixAxisSensorSharedMemoryFormat) == 0x20,
|
||||||
|
|
||||||
// This is nn::hid::detail::SharedMemoryFormat
|
// This is nn::hid::detail::SharedMemoryFormat
|
||||||
struct SharedMemoryFormat {
|
struct SharedMemoryFormat {
|
||||||
void Initialize() {
|
void Initialize() {}
|
||||||
npad_condition = NpadCondition{};
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugPadSharedMemoryFormat debug_pad;
|
DebugPadSharedMemoryFormat debug_pad;
|
||||||
TouchScreenSharedMemoryFormat touch_screen;
|
TouchScreenSharedMemoryFormat touch_screen;
|
||||||
|
@ -223,9 +218,7 @@ struct SharedMemoryFormat {
|
||||||
ConsoleSixAxisSensorSharedMemoryFormat console;
|
ConsoleSixAxisSensorSharedMemoryFormat console;
|
||||||
INSERT_PADDING_BYTES(0x19E0);
|
INSERT_PADDING_BYTES(0x19E0);
|
||||||
MouseSharedMemoryFormat debug_mouse;
|
MouseSharedMemoryFormat debug_mouse;
|
||||||
INSERT_PADDING_BYTES(0x200);
|
INSERT_PADDING_BYTES(0x2000);
|
||||||
NpadCondition npad_condition;
|
|
||||||
INSERT_PADDING_BYTES(0x1DF0);
|
|
||||||
};
|
};
|
||||||
static_assert(offsetof(SharedMemoryFormat, debug_pad) == 0x0, "debug_pad has wrong offset");
|
static_assert(offsetof(SharedMemoryFormat, debug_pad) == 0x0, "debug_pad has wrong offset");
|
||||||
static_assert(offsetof(SharedMemoryFormat, touch_screen) == 0x400, "touch_screen has wrong offset");
|
static_assert(offsetof(SharedMemoryFormat, touch_screen) == 0x400, "touch_screen has wrong offset");
|
||||||
|
@ -243,8 +236,6 @@ static_assert(offsetof(SharedMemoryFormat, npad) == 0x9A00, "npad has wrong offs
|
||||||
static_assert(offsetof(SharedMemoryFormat, gesture) == 0x3BA00, "gesture has wrong offset");
|
static_assert(offsetof(SharedMemoryFormat, gesture) == 0x3BA00, "gesture has wrong offset");
|
||||||
static_assert(offsetof(SharedMemoryFormat, console) == 0x3C200, "console has wrong offset");
|
static_assert(offsetof(SharedMemoryFormat, console) == 0x3C200, "console has wrong offset");
|
||||||
static_assert(offsetof(SharedMemoryFormat, debug_mouse) == 0x3DC00, "debug_mouse has wrong offset");
|
static_assert(offsetof(SharedMemoryFormat, debug_mouse) == 0x3DC00, "debug_mouse has wrong offset");
|
||||||
static_assert(offsetof(SharedMemoryFormat, npad_condition) == 0x3E200,
|
|
||||||
"npad_condition has wrong offset");
|
|
||||||
static_assert(sizeof(SharedMemoryFormat) == 0x40000, "SharedMemoryFormat is an invalid size");
|
static_assert(sizeof(SharedMemoryFormat) == 0x40000, "SharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -45,10 +45,6 @@ if (NOT APPLE AND ENABLE_OPENGL)
|
||||||
target_compile_definitions(qt_common PUBLIC HAS_OPENGL)
|
target_compile_definitions(qt_common PUBLIC HAS_OPENGL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE)
|
if (NOT WIN32)
|
||||||
if (TARGET Qt6::GuiPrivate)
|
target_include_directories(qt_common PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||||
target_link_libraries(qt_common PRIVATE Qt6::GuiPrivate)
|
|
||||||
else()
|
|
||||||
target_include_directories(qt_common PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "qt_common/qt_game_util.h"
|
|
||||||
#include "qt_content_util.h"
|
#include "qt_content_util.h"
|
||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
|
||||||
#include "frontend_common/content_manager.h"
|
#include "frontend_common/content_manager.h"
|
||||||
#include "frontend_common/firmware_manager.h"
|
#include "frontend_common/firmware_manager.h"
|
||||||
#include "qt_common/qt_common.h"
|
#include "qt_common/qt_common.h"
|
||||||
|
@ -312,40 +310,4 @@ void VerifyInstalledContents() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixProfiles()
|
|
||||||
{
|
|
||||||
// Reset user save files after config is initialized and migration is done.
|
|
||||||
// Doing it at init time causes profiles to read from the wrong place entirely if NAND dir is not default
|
|
||||||
// TODO: better solution
|
|
||||||
system->GetProfileManager().ResetUserSaveFile();
|
|
||||||
std::vector<std::string> orphaned = system->GetProfileManager().FindOrphanedProfiles();
|
|
||||||
|
|
||||||
// no orphaned dirs--all good :)
|
|
||||||
if (orphaned.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// otherwise, let the user know
|
|
||||||
QString qorphaned;
|
|
||||||
|
|
||||||
// max. of 8 orphaned profiles is fair, I think
|
|
||||||
// 33 = 32 (UUID) + 1 (\n)
|
|
||||||
qorphaned.reserve(8 * 33);
|
|
||||||
|
|
||||||
for (const std::string& s : orphaned) {
|
|
||||||
qorphaned += "\n" + QString::fromStdString(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
QtCommon::Frontend::Critical(
|
|
||||||
tr("Orphaned Profiles Detected!"),
|
|
||||||
tr("UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!\n"
|
|
||||||
"Eden has detected the following save directories with no attached profile:\n"
|
|
||||||
"%1\n\n"
|
|
||||||
"Click \"OK\" to open your save folder and fix up your profiles.\n"
|
|
||||||
"Hint: copy the contents of the largest or last-modified folder elsewhere, "
|
|
||||||
"delete all orphaned profiles, and move your copied contents to the good profile.")
|
|
||||||
.arg(qorphaned));
|
|
||||||
|
|
||||||
QtCommon::Game::OpenSaveFolder();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace QtCommon::Content
|
} // namespace QtCommon::Content
|
||||||
|
|
|
@ -45,8 +45,5 @@ void InstallKeys();
|
||||||
// Content //
|
// Content //
|
||||||
void VerifyGameContents(const std::string &game_path);
|
void VerifyGameContents(const std::string &game_path);
|
||||||
void VerifyInstalledContents();
|
void VerifyInstalledContents();
|
||||||
|
|
||||||
// Profiles //
|
|
||||||
void FixProfiles();
|
|
||||||
}
|
}
|
||||||
#endif // QT_CONTENT_UTIL_H
|
#endif // QT_CONTENT_UTIL_H
|
||||||
|
|
|
@ -178,12 +178,6 @@ void OpenNANDFolder()
|
||||||
OpenEdenFolder(Common::FS::EdenPath::NANDDir);
|
OpenEdenFolder(Common::FS::EdenPath::NANDDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenSaveFolder()
|
|
||||||
{
|
|
||||||
const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "user/save/0000000000000000";
|
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(path.string())));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenSDMCFolder()
|
void OpenSDMCFolder()
|
||||||
{
|
{
|
||||||
OpenEdenFolder(Common::FS::EdenPath::SDMCDir);
|
OpenEdenFolder(Common::FS::EdenPath::SDMCDir);
|
||||||
|
@ -385,21 +379,21 @@ void RemoveCacheStorage(u64 program_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadata //
|
// Metadata //
|
||||||
void ResetMetadata(bool show_message)
|
void ResetMetadata()
|
||||||
{
|
{
|
||||||
const QString title = tr("Reset Metadata Cache");
|
const QString title = tr("Reset Metadata Cache");
|
||||||
|
|
||||||
if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir)
|
if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir)
|
||||||
/ "game_list/")) {
|
/ "game_list/")) {
|
||||||
if (show_message) QtCommon::Frontend::Warning(rootObject, title, tr("The metadata cache is already empty."));
|
QtCommon::Frontend::Warning(rootObject, title, tr("The metadata cache is already empty."));
|
||||||
} else if (Common::FS::RemoveDirRecursively(
|
} else if (Common::FS::RemoveDirRecursively(
|
||||||
Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) {
|
Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) {
|
||||||
if (show_message) QtCommon::Frontend::Information(rootObject,
|
QtCommon::Frontend::Information(rootObject,
|
||||||
title,
|
title,
|
||||||
tr("The operation completed successfully."));
|
tr("The operation completed successfully."));
|
||||||
UISettings::values.is_game_list_reload_pending.exchange(true);
|
UISettings::values.is_game_list_reload_pending.exchange(true);
|
||||||
} else {
|
} else {
|
||||||
if (show_message) QtCommon::Frontend::Warning(
|
QtCommon::Frontend::Warning(
|
||||||
rootObject,
|
rootObject,
|
||||||
title,
|
title,
|
||||||
tr("The metadata cache couldn't be deleted. It might be in use or non-existent."));
|
tr("The metadata cache couldn't be deleted. It might be in use or non-existent."));
|
||||||
|
@ -579,4 +573,5 @@ void CreateHomeMenuShortcut(ShortcutTarget target) {
|
||||||
CreateShortcut(game_path, QLaunchId, "Switch Home Menu", target, "-qlaunch", false);
|
CreateShortcut(game_path, QLaunchId, "Switch Home Menu", target, "-qlaunch", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace QtCommon::Game
|
} // namespace QtCommon::Game
|
||||||
|
|
|
@ -52,7 +52,6 @@ bool MakeShortcutIcoPath(const u64 program_id,
|
||||||
void OpenEdenFolder(const Common::FS::EdenPath &path);
|
void OpenEdenFolder(const Common::FS::EdenPath &path);
|
||||||
void OpenRootDataFolder();
|
void OpenRootDataFolder();
|
||||||
void OpenNANDFolder();
|
void OpenNANDFolder();
|
||||||
void OpenSaveFolder();
|
|
||||||
void OpenSDMCFolder();
|
void OpenSDMCFolder();
|
||||||
void OpenModFolder();
|
void OpenModFolder();
|
||||||
void OpenLogFolder();
|
void OpenLogFolder();
|
||||||
|
@ -68,7 +67,7 @@ void RemoveCustomConfiguration(u64 program_id, const std::string& game_path);
|
||||||
void RemoveCacheStorage(u64 program_id);
|
void RemoveCacheStorage(u64 program_id);
|
||||||
|
|
||||||
// Metadata //
|
// Metadata //
|
||||||
void ResetMetadata(bool show_message = true);
|
void ResetMetadata();
|
||||||
|
|
||||||
// Shortcuts //
|
// Shortcuts //
|
||||||
void CreateShortcut(const std::string& game_path,
|
void CreateShortcut(const std::string& game_path,
|
||||||
|
|
|
@ -320,6 +320,12 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
|
||||||
tr("Improves rendering of transparency effects in specific games."));
|
tr("Improves rendering of transparency effects in specific games."));
|
||||||
|
|
||||||
// Renderer (Extensions)
|
// Renderer (Extensions)
|
||||||
|
INSERT(Settings,
|
||||||
|
enable_raii,
|
||||||
|
tr("RAII"),
|
||||||
|
tr("A method of automatic resource management in Vulkan "
|
||||||
|
"that ensures proper release of resources "
|
||||||
|
"when they are no longer needed, but may cause crashes in bundled games."));
|
||||||
INSERT(Settings,
|
INSERT(Settings,
|
||||||
dyna_state,
|
dyna_state,
|
||||||
tr("Extended Dynamic State"),
|
tr("Extended Dynamic State"),
|
||||||
|
@ -534,7 +540,6 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
|
||||||
PAIR(ResolutionSetup, Res1_2X, tr("0.5X (360p/540p) [EXPERIMENTAL]")),
|
PAIR(ResolutionSetup, Res1_2X, tr("0.5X (360p/540p) [EXPERIMENTAL]")),
|
||||||
PAIR(ResolutionSetup, Res3_4X, tr("0.75X (540p/810p) [EXPERIMENTAL]")),
|
PAIR(ResolutionSetup, Res3_4X, tr("0.75X (540p/810p) [EXPERIMENTAL]")),
|
||||||
PAIR(ResolutionSetup, Res1X, tr("1X (720p/1080p)")),
|
PAIR(ResolutionSetup, Res1X, tr("1X (720p/1080p)")),
|
||||||
PAIR(ResolutionSetup, Res5_4X, tr("1.25X (900p/1350p) [EXPERIMENTAL]")),
|
|
||||||
PAIR(ResolutionSetup, Res3_2X, tr("1.5X (1080p/1620p) [EXPERIMENTAL]")),
|
PAIR(ResolutionSetup, Res3_2X, tr("1.5X (1080p/1620p) [EXPERIMENTAL]")),
|
||||||
PAIR(ResolutionSetup, Res2X, tr("2X (1440p/2160p)")),
|
PAIR(ResolutionSetup, Res2X, tr("2X (1440p/2160p)")),
|
||||||
PAIR(ResolutionSetup, Res3X, tr("3X (2160p/3240p)")),
|
PAIR(ResolutionSetup, Res3X, tr("3X (2160p/3240p)")),
|
||||||
|
@ -549,16 +554,12 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
|
||||||
PAIR(ScalingFilter, NearestNeighbor, tr("Nearest Neighbor")),
|
PAIR(ScalingFilter, NearestNeighbor, tr("Nearest Neighbor")),
|
||||||
PAIR(ScalingFilter, Bilinear, tr("Bilinear")),
|
PAIR(ScalingFilter, Bilinear, tr("Bilinear")),
|
||||||
PAIR(ScalingFilter, Bicubic, tr("Bicubic")),
|
PAIR(ScalingFilter, Bicubic, tr("Bicubic")),
|
||||||
|
PAIR(ScalingFilter, Spline1, tr("Spline-1")),
|
||||||
PAIR(ScalingFilter, Gaussian, tr("Gaussian")),
|
PAIR(ScalingFilter, Gaussian, tr("Gaussian")),
|
||||||
PAIR(ScalingFilter, Lanczos, tr("Lanczos")),
|
PAIR(ScalingFilter, Lanczos, tr("Lanczos")),
|
||||||
PAIR(ScalingFilter, ScaleForce, tr("ScaleForce")),
|
PAIR(ScalingFilter, ScaleForce, tr("ScaleForce")),
|
||||||
PAIR(ScalingFilter, Fsr, tr("AMD FidelityFX™️ Super Resolution")),
|
PAIR(ScalingFilter, Fsr, tr("AMD FidelityFX™️ Super Resolution")),
|
||||||
PAIR(ScalingFilter, Area, tr("Area")),
|
PAIR(ScalingFilter, Area, tr("Area")),
|
||||||
PAIR(ScalingFilter, Mmpx, tr("MMPX")),
|
|
||||||
PAIR(ScalingFilter, ZeroTangent, tr("Zero-Tangent")),
|
|
||||||
PAIR(ScalingFilter, BSpline, tr("B-Spline")),
|
|
||||||
PAIR(ScalingFilter, Mitchell, tr("Mitchell")),
|
|
||||||
PAIR(ScalingFilter, Spline1, tr("Spline-1")),
|
|
||||||
}});
|
}});
|
||||||
translations->insert({Settings::EnumMetadata<Settings::AntiAliasing>::Index(),
|
translations->insert({Settings::EnumMetadata<Settings::AntiAliasing>::Index(),
|
||||||
{
|
{
|
||||||
|
@ -715,4 +716,3 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
|
||||||
return translations;
|
return translations;
|
||||||
}
|
}
|
||||||
} // namespace ConfigurationShared
|
} // namespace ConfigurationShared
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,6 @@ static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map
|
||||||
{Settings::ScalingFilter::Bilinear,
|
{Settings::ScalingFilter::Bilinear,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bilinear"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bilinear"))},
|
||||||
{Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))},
|
{Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))},
|
||||||
{Settings::ScalingFilter::ZeroTangent, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Zero-Tangent"))},
|
|
||||||
{Settings::ScalingFilter::BSpline, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "B-Spline"))},
|
|
||||||
{Settings::ScalingFilter::Mitchell, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Mitchell"))},
|
|
||||||
{Settings::ScalingFilter::Spline1,
|
{Settings::ScalingFilter::Spline1,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Spline-1"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Spline-1"))},
|
||||||
{Settings::ScalingFilter::Gaussian,
|
{Settings::ScalingFilter::Gaussian,
|
||||||
|
@ -51,7 +48,6 @@ static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleForce"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleForce"))},
|
||||||
{Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))},
|
{Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))},
|
||||||
{Settings::ScalingFilter::Area, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Area"))},
|
{Settings::ScalingFilter::Area, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Area"))},
|
||||||
{Settings::ScalingFilter::Mmpx, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "MMPX"))},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map = {
|
static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map = {
|
||||||
|
|
|
@ -386,9 +386,11 @@ void BufferCache<P>::BindHostComputeBuffers() {
|
||||||
template <class P>
|
template <class P>
|
||||||
void BufferCache<P>::SetUniformBuffersState(const std::array<u32, NUM_STAGES>& mask,
|
void BufferCache<P>::SetUniformBuffersState(const std::array<u32, NUM_STAGES>& mask,
|
||||||
const UniformBufferSizes* sizes) {
|
const UniformBufferSizes* sizes) {
|
||||||
if (channel_state->enabled_uniform_buffer_masks != mask) {
|
if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
|
||||||
channel_state->fast_bound_uniform_buffers.fill(0);
|
if (channel_state->enabled_uniform_buffer_masks != mask) {
|
||||||
if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
|
if constexpr (IS_OPENGL) {
|
||||||
|
channel_state->fast_bound_uniform_buffers.fill(0);
|
||||||
|
}
|
||||||
channel_state->dirty_uniform_buffers.fill(~u32{0});
|
channel_state->dirty_uniform_buffers.fill(~u32{0});
|
||||||
channel_state->uniform_buffer_binding_sizes.fill({});
|
channel_state->uniform_buffer_binding_sizes.fill({});
|
||||||
}
|
}
|
||||||
|
@ -804,7 +806,7 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
|
||||||
channel_state->uniform_buffer_binding_sizes[stage][binding_index] != size;
|
channel_state->uniform_buffer_binding_sizes[stage][binding_index] != size;
|
||||||
if (should_fast_bind) {
|
if (should_fast_bind) {
|
||||||
// We only have to bind when the currently bound buffer is not the fast version
|
// We only have to bind when the currently bound buffer is not the fast version
|
||||||
channel_state->fast_bound_uniform_buffers[stage] |= 1u << binding_index;
|
channel_state->fast_bound_uniform_buffers[stage] |= 1U << binding_index;
|
||||||
channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
|
channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
|
||||||
runtime.BindFastUniformBuffer(stage, binding_index, size);
|
runtime.BindFastUniformBuffer(stage, binding_index, size);
|
||||||
}
|
}
|
||||||
|
@ -813,8 +815,10 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
channel_state->fast_bound_uniform_buffers[stage] |= 1u << binding_index;
|
if constexpr (IS_OPENGL) {
|
||||||
channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
|
channel_state->fast_bound_uniform_buffers[stage] |= 1U << binding_index;
|
||||||
|
channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
|
||||||
|
}
|
||||||
// Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan
|
// Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan
|
||||||
const std::span<u8> span = runtime.BindMappedUniformBuffer(stage, binding_index, size);
|
const std::span<u8> span = runtime.BindMappedUniformBuffer(stage, binding_index, size);
|
||||||
device_memory.ReadBlockUnsafe(device_addr, span.data(), size);
|
device_memory.ReadBlockUnsafe(device_addr, span.data(), size);
|
||||||
|
@ -835,6 +839,9 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
|
||||||
}
|
}
|
||||||
const u32 offset = buffer.Offset(device_addr);
|
const u32 offset = buffer.Offset(device_addr);
|
||||||
if constexpr (IS_OPENGL) {
|
if constexpr (IS_OPENGL) {
|
||||||
|
// Fast buffer will be unbound
|
||||||
|
channel_state->fast_bound_uniform_buffers[stage] &= ~(1U << binding_index);
|
||||||
|
|
||||||
// Mark the index as dirty if offset doesn't match
|
// Mark the index as dirty if offset doesn't match
|
||||||
const bool is_copy_bind = offset != 0 && !runtime.SupportsNonZeroUniformOffset();
|
const bool is_copy_bind = offset != 0 && !runtime.SupportsNonZeroUniformOffset();
|
||||||
channel_state->dirty_uniform_buffers[stage] |= (is_copy_bind ? 1U : 0U) << index;
|
channel_state->dirty_uniform_buffers[stage] |= (is_copy_bind ? 1U : 0U) << index;
|
||||||
|
@ -848,7 +855,6 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
|
||||||
} else {
|
} else {
|
||||||
runtime.BindUniformBuffer(buffer, offset, size);
|
runtime.BindUniformBuffer(buffer, offset, size);
|
||||||
}
|
}
|
||||||
channel_state->fast_bound_uniform_buffers[stage] &= ~(1u << binding_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
|
@ -1783,7 +1789,12 @@ std::span<u8> BufferCache<P>::ImmediateBuffer(size_t wanted_capacity) {
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
bool BufferCache<P>::HasFastUniformBufferBound(size_t stage, u32 binding_index) const noexcept {
|
bool BufferCache<P>::HasFastUniformBufferBound(size_t stage, u32 binding_index) const noexcept {
|
||||||
return ((channel_state->fast_bound_uniform_buffers[stage] >> binding_index) & 1u) != 0;
|
if constexpr (IS_OPENGL) {
|
||||||
|
return ((channel_state->fast_bound_uniform_buffers[stage] >> binding_index) & 1) != 0;
|
||||||
|
} else {
|
||||||
|
// Only OpenGL has fast uniform buffers
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
|
|
|
@ -54,8 +54,6 @@ constexpr u32 NUM_STORAGE_BUFFERS = 16;
|
||||||
constexpr u32 NUM_TEXTURE_BUFFERS = 32;
|
constexpr u32 NUM_TEXTURE_BUFFERS = 32;
|
||||||
constexpr u32 NUM_STAGES = 5;
|
constexpr u32 NUM_STAGES = 5;
|
||||||
|
|
||||||
static_assert(NUM_GRAPHICS_UNIFORM_BUFFERS <= 32, "fast bitmask must fit u32");
|
|
||||||
|
|
||||||
using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>;
|
using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>;
|
||||||
using ComputeUniformBufferSizes = std::array<u32, NUM_COMPUTE_UNIFORM_BUFFERS>;
|
using ComputeUniformBufferSizes = std::array<u32, NUM_COMPUTE_UNIFORM_BUFFERS>;
|
||||||
|
|
||||||
|
@ -139,8 +137,8 @@ public:
|
||||||
u32 written_compute_texture_buffers = 0;
|
u32 written_compute_texture_buffers = 0;
|
||||||
u32 image_compute_texture_buffers = 0;
|
u32 image_compute_texture_buffers = 0;
|
||||||
|
|
||||||
std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS> uniform_cache_hits{};
|
std::array<u32, 16> uniform_cache_hits{};
|
||||||
std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS> uniform_cache_shots{};
|
std::array<u32, 16> uniform_cache_shots{};
|
||||||
|
|
||||||
u32 uniform_buffer_skip_cache_size = DEFAULT_SKIP_CACHE_SIZE;
|
u32 uniform_buffer_skip_cache_size = DEFAULT_SKIP_CACHE_SIZE;
|
||||||
|
|
||||||
|
|
|
@ -44,13 +44,9 @@ set(SHADER_FILES
|
||||||
pitch_unswizzle.comp
|
pitch_unswizzle.comp
|
||||||
present_area.frag
|
present_area.frag
|
||||||
present_bicubic.frag
|
present_bicubic.frag
|
||||||
present_zero_tangent.frag
|
|
||||||
present_bspline.frag
|
|
||||||
present_mitchell.frag
|
|
||||||
present_gaussian.frag
|
present_gaussian.frag
|
||||||
present_lanczos.frag
|
present_lanczos.frag
|
||||||
present_spline1.frag
|
present_spline1.frag
|
||||||
present_mmpx.frag
|
|
||||||
queries_prefix_scan_sum.comp
|
queries_prefix_scan_sum.comp
|
||||||
queries_prefix_scan_sum_nosubgroups.comp
|
queries_prefix_scan_sum_nosubgroups.comp
|
||||||
resolve_conditional_render.comp
|
resolve_conditional_render.comp
|
||||||
|
|
|
@ -1,37 +1,56 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#version 460 core
|
#version 460 core
|
||||||
|
|
||||||
|
|
||||||
layout (location = 0) in vec2 frag_tex_coord;
|
layout (location = 0) in vec2 frag_tex_coord;
|
||||||
|
|
||||||
layout (location = 0) out vec4 color;
|
layout (location = 0) out vec4 color;
|
||||||
|
|
||||||
layout (binding = 0) uniform sampler2D color_texture;
|
layout (binding = 0) uniform sampler2D color_texture;
|
||||||
vec4 cubic(float x) {
|
|
||||||
float x2 = x * x;
|
vec4 cubic(float v) {
|
||||||
float x3 = x2 * x;
|
vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v;
|
||||||
return vec4(1.0, x, x2, x3) * transpose(mat4x4(
|
vec4 s = n * n * n;
|
||||||
0.0, 2.0, 0.0, 0.0,
|
float x = s.x;
|
||||||
-1.0, 0.0, 1.0, 0.0,
|
float y = s.y - 4.0 * s.x;
|
||||||
2.0, -5.0, 4.0, -1.0,
|
float z = s.z - 4.0 * s.y + 6.0 * s.x;
|
||||||
-1.0, 3.0, -3.0, 1.0
|
float w = 6.0 - x - y - z;
|
||||||
) * (1.0 / 2.0));
|
return vec4(x, y, z, w) * (1.0 / 6.0);
|
||||||
}
|
}
|
||||||
vec4 textureBicubic(sampler2D samp, vec2 uv) {
|
|
||||||
vec2 tex_size = vec2(textureSize(samp, 0));
|
vec4 textureBicubic( sampler2D textureSampler, vec2 texCoords ) {
|
||||||
vec2 cc_tex = uv * tex_size - 0.5f;
|
|
||||||
vec2 fex = cc_tex - floor(cc_tex);
|
vec2 texSize = textureSize(textureSampler, 0);
|
||||||
vec4 xcubic = cubic(fex.x);
|
vec2 invTexSize = 1.0 / texSize;
|
||||||
vec4 ycubic = cubic(fex.y);
|
|
||||||
vec4 c = floor(cc_tex).xxyy + vec2(-0.5f, 1.5f).xyxy;
|
texCoords = texCoords * texSize - 0.5;
|
||||||
vec4 z = vec4(xcubic.yw, ycubic.yw);
|
|
||||||
vec4 s = vec4(xcubic.xz, ycubic.xz) + z;
|
vec2 fxy = fract(texCoords);
|
||||||
vec4 offset = (c + z / s) * (1.0f / tex_size).xxyy;
|
texCoords -= fxy;
|
||||||
vec2 n = vec2(s.x / (s.x + s.y), s.z / (s.z + s.w));
|
|
||||||
return mix(
|
vec4 xcubic = cubic(fxy.x);
|
||||||
mix(texture(samp, offset.yw), texture(samp, offset.xw), n.x),
|
vec4 ycubic = cubic(fxy.y);
|
||||||
mix(texture(samp, offset.yz), texture(samp, offset.xz), n.x),
|
|
||||||
n.y);
|
vec4 c = texCoords.xxyy + vec2(-0.5, +1.5).xyxy;
|
||||||
|
|
||||||
|
vec4 s = vec4(xcubic.xz + xcubic.yw, ycubic.xz + ycubic.yw);
|
||||||
|
vec4 offset = c + vec4(xcubic.yw, ycubic.yw) / s;
|
||||||
|
|
||||||
|
offset *= invTexSize.xxyy;
|
||||||
|
|
||||||
|
vec4 sample0 = texture(textureSampler, offset.xz);
|
||||||
|
vec4 sample1 = texture(textureSampler, offset.yz);
|
||||||
|
vec4 sample2 = texture(textureSampler, offset.xw);
|
||||||
|
vec4 sample3 = texture(textureSampler, offset.yw);
|
||||||
|
|
||||||
|
float sx = s.x / (s.x + s.y);
|
||||||
|
float sy = s.z / (s.z + s.w);
|
||||||
|
|
||||||
|
return mix(mix(sample3, sample2, sx), mix(sample1, sample0, sx), sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
color = textureBicubic(color_texture, frag_tex_coord);
|
color = textureBicubic(color_texture, frag_tex_coord);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#version 460 core
|
|
||||||
layout (location = 0) in vec2 frag_tex_coord;
|
|
||||||
layout (location = 0) out vec4 color;
|
|
||||||
layout (binding = 0) uniform sampler2D color_texture;
|
|
||||||
vec4 cubic(float x) {
|
|
||||||
float x2 = x * x;
|
|
||||||
float x3 = x2 * x;
|
|
||||||
return vec4(1.0, x, x2, x3) * transpose(mat4x4(
|
|
||||||
1.0, 4.0, 1.0, 0.0,
|
|
||||||
-3.0, 0.0, 3.0, 0.0,
|
|
||||||
3.0, -6.0, 3.0, 0.0,
|
|
||||||
-1.0, 3.0, -3.0, 1.0
|
|
||||||
) * (1.0 / 6.0));
|
|
||||||
}
|
|
||||||
vec4 textureBicubic(sampler2D samp, vec2 uv) {
|
|
||||||
vec2 tex_size = vec2(textureSize(samp, 0));
|
|
||||||
vec2 cc_tex = uv * tex_size - 0.5f;
|
|
||||||
vec2 fex = cc_tex - floor(cc_tex);
|
|
||||||
vec4 xcubic = cubic(fex.x);
|
|
||||||
vec4 ycubic = cubic(fex.y);
|
|
||||||
vec4 c = floor(cc_tex).xxyy + vec2(-0.5f, 1.5f).xyxy;
|
|
||||||
vec4 z = vec4(xcubic.yw, ycubic.yw);
|
|
||||||
vec4 s = vec4(xcubic.xz, ycubic.xz) + z;
|
|
||||||
vec4 offset = (c + z / s) * (1.0f / tex_size).xxyy;
|
|
||||||
vec2 n = vec2(s.x / (s.x + s.y), s.z / (s.z + s.w));
|
|
||||||
return mix(
|
|
||||||
mix(texture(samp, offset.yw), texture(samp, offset.xw), n.x),
|
|
||||||
mix(texture(samp, offset.yz), texture(samp, offset.xz), n.x),
|
|
||||||
n.y);
|
|
||||||
}
|
|
||||||
void main() {
|
|
||||||
color = textureBicubic(color_texture, frag_tex_coord);
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#version 460 core
|
|
||||||
layout (location = 0) in vec2 frag_tex_coord;
|
|
||||||
layout (location = 0) out vec4 color;
|
|
||||||
layout (binding = 0) uniform sampler2D color_texture;
|
|
||||||
vec4 cubic(float x) {
|
|
||||||
float x2 = x * x;
|
|
||||||
float x3 = x2 * x;
|
|
||||||
return vec4(1.0, x, x2, x3) * transpose(mat4x4(
|
|
||||||
1.0, 16.0, 1.0, 0.0,
|
|
||||||
-9.0, 0.0, 9.0, 0.0,
|
|
||||||
15.0, -36.0, 27.0, -6.0,
|
|
||||||
-7.0, 21.0, -21.0, 7.0
|
|
||||||
) * (1.0 / 18.0));
|
|
||||||
}
|
|
||||||
vec4 textureBicubic(sampler2D samp, vec2 uv) {
|
|
||||||
vec2 tex_size = vec2(textureSize(samp, 0));
|
|
||||||
vec2 cc_tex = uv * tex_size - 0.5f;
|
|
||||||
vec2 fex = cc_tex - floor(cc_tex);
|
|
||||||
vec4 xcubic = cubic(fex.x);
|
|
||||||
vec4 ycubic = cubic(fex.y);
|
|
||||||
vec4 c = floor(cc_tex).xxyy + vec2(-0.5f, 1.5f).xyxy;
|
|
||||||
vec4 z = vec4(xcubic.yw, ycubic.yw);
|
|
||||||
vec4 s = vec4(xcubic.xz, ycubic.xz) + z;
|
|
||||||
vec4 offset = (c + z / s) * (1.0f / tex_size).xxyy;
|
|
||||||
vec2 n = vec2(s.x / (s.x + s.y), s.z / (s.z + s.w));
|
|
||||||
return mix(
|
|
||||||
mix(texture(samp, offset.yw), texture(samp, offset.xw), n.x),
|
|
||||||
mix(texture(samp, offset.yz), texture(samp, offset.xz), n.x),
|
|
||||||
n.y);
|
|
||||||
}
|
|
||||||
void main() {
|
|
||||||
color = textureBicubic(color_texture, frag_tex_coord);
|
|
||||||
}
|
|
|
@ -1,131 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
// Copyright 2023 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#version 460 core
|
|
||||||
layout(location = 0) in vec2 tex_coord;
|
|
||||||
layout(location = 0) out vec4 frag_color;
|
|
||||||
layout(binding = 0) uniform sampler2D tex;
|
|
||||||
|
|
||||||
#define src(x, y) texture(tex, coord + vec2(x, y) * 1.0 / source_size)
|
|
||||||
|
|
||||||
float luma(vec4 col) {
|
|
||||||
return dot(col.rgb, vec3(0.2126, 0.7152, 0.0722)) * (1.0 - col.a);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool same(vec4 B, vec4 A0) {
|
|
||||||
return all(equal(B, A0));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool notsame(vec4 B, vec4 A0) {
|
|
||||||
return any(notEqual(B, A0));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool all_eq2(vec4 B, vec4 A0, vec4 A1) {
|
|
||||||
return (same(B,A0) && same(B,A1));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool all_eq3(vec4 B, vec4 A0, vec4 A1, vec4 A2) {
|
|
||||||
return (same(B,A0) && same(B,A1) && same(B,A2));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool all_eq4(vec4 B, vec4 A0, vec4 A1, vec4 A2, vec4 A3) {
|
|
||||||
return (same(B,A0) && same(B,A1) && same(B,A2) && same(B,A3));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool any_eq3(vec4 B, vec4 A0, vec4 A1, vec4 A2) {
|
|
||||||
return (same(B,A0) || same(B,A1) || same(B,A2));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool none_eq2(vec4 B, vec4 A0, vec4 A1) {
|
|
||||||
return (notsame(B,A0) && notsame(B,A1));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool none_eq4(vec4 B, vec4 A0, vec4 A1, vec4 A2, vec4 A3) {
|
|
||||||
return (notsame(B,A0) && notsame(B,A1) && notsame(B,A2) && notsame(B,A3));
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec2 source_size = vec2(textureSize(tex, 0));
|
|
||||||
vec2 pos = fract(tex_coord * source_size) - vec2(0.5, 0.5);
|
|
||||||
vec2 coord = tex_coord - pos / source_size;
|
|
||||||
|
|
||||||
vec4 E = src(0.0,0.0);
|
|
||||||
|
|
||||||
vec4 A = src(-1.0,-1.0);
|
|
||||||
vec4 B = src(0.0,-1.0);
|
|
||||||
vec4 C = src(1.0,-1.0);
|
|
||||||
|
|
||||||
vec4 D = src(-1.0,0.0);
|
|
||||||
vec4 F = src(1.0,0.0);
|
|
||||||
|
|
||||||
vec4 G = src(-1.0,1.0);
|
|
||||||
vec4 H = src(0.0,1.0);
|
|
||||||
vec4 I = src(1.0,1.0);
|
|
||||||
|
|
||||||
vec4 J = E;
|
|
||||||
vec4 K = E;
|
|
||||||
vec4 L = E;
|
|
||||||
vec4 M = E;
|
|
||||||
|
|
||||||
frag_color = E;
|
|
||||||
|
|
||||||
if(same(E,A) && same(E,B) && same(E,C) && same(E,D) && same(E,F) && same(E,G) && same(E,H) && same(E,I)) return;
|
|
||||||
|
|
||||||
vec4 P = src(0.0,2.0);
|
|
||||||
vec4 Q = src(-2.0,0.0);
|
|
||||||
vec4 R = src(2.0,0.0);
|
|
||||||
vec4 S = src(0.0,2.0);
|
|
||||||
|
|
||||||
float Bl = luma(B);
|
|
||||||
float Dl = luma(D);
|
|
||||||
float El = luma(E);
|
|
||||||
float Fl = luma(F);
|
|
||||||
float Hl = luma(H);
|
|
||||||
|
|
||||||
if (((same(D,B) && notsame(D,H) && notsame(D,F))) && ((El>=Dl) || same(E,A)) && any_eq3(E,A,C,G) && ((El<Dl) || notsame(A,D) || notsame(E,P) || notsame(E,Q))) J=mix(D, J, 0.5);
|
|
||||||
if (((same(B,F) && notsame(B,D) && notsame(B,H))) && ((El>=Bl) || same(E,C)) && any_eq3(E,A,C,I) && ((El<Bl) || notsame(C,B) || notsame(E,P) || notsame(E,R))) K=mix(B, K, 0.5);
|
|
||||||
if (((same(H,D) && notsame(H,F) && notsame(H,B))) && ((El>=Hl) || same(E,G)) && any_eq3(E,A,G,I) && ((El<Hl) || notsame(G,H) || notsame(E,S) || notsame(E,Q))) L=mix(H, L, 0.5);
|
|
||||||
if (((same(F,H) && notsame(F,B) && notsame(F,D))) && ((El>=Fl) || same(E,I)) && any_eq3(E,C,G,I) && ((El<Fl) || notsame(I,H) || notsame(E,R) || notsame(E,S))) M=mix(F, M, 0.5);
|
|
||||||
|
|
||||||
if ((notsame(E,F) && all_eq4(E,C,I,D,Q) && all_eq2(F,B,H)) && notsame(F,src(3.0,0.0))) {M=mix(M, F, 0.5); K=mix(K, M, 0.5);};
|
|
||||||
if ((notsame(E,D) && all_eq4(E,A,G,F,R) && all_eq2(D,B,H)) && notsame(D,src(-3.0,0.0))) {L=mix(L, D, 0.5); J=mix(J, L, 0.5);};
|
|
||||||
if ((notsame(E,H) && all_eq4(E,G,I,B,P) && all_eq2(H,D,F)) && notsame(H,src(0.0,3.0))) {M=mix(M, H, 0.5); L=mix(L, M, 0.5);};
|
|
||||||
if ((notsame(E,B) && all_eq4(E,A,C,H,S) && all_eq2(B,D,F)) && notsame(B,src(0.0,-3.0))) {K=mix(K, B, 0.5); J=mix(J, K, 0.5);};
|
|
||||||
|
|
||||||
if ((Bl<El) && all_eq4(E,G,H,I,S) && none_eq4(E,A,D,C,F)) {K=mix(K, B, 0.5); J=mix(J, K, 0.5);}
|
|
||||||
if ((Hl<El) && all_eq4(E,A,B,C,P) && none_eq4(E,D,G,I,F)) {M=mix(M, H, 0.5); L=mix(L, M, 0.5);}
|
|
||||||
if ((Fl<El) && all_eq4(E,A,D,G,Q) && none_eq4(E,B,C,I,H)) {M=mix(M, F, 0.5); K=mix(K, M, 0.5);}
|
|
||||||
if ((Dl<El) && all_eq4(E,C,F,I,R) && none_eq4(E,B,A,G,H)) {L=mix(L, D, 0.5); J=mix(J, L, 0.5);}
|
|
||||||
|
|
||||||
if (notsame(H,B)) {
|
|
||||||
if (notsame(H,A) && notsame(H,E) && notsame(H,C)) {
|
|
||||||
if (all_eq3(H,G,F,R) && none_eq2(H,D,src(2.0,-1.0))) L=mix(M, L, 0.5);
|
|
||||||
if (all_eq3(H,I,D,Q) && none_eq2(H,F,src(-2.0,-1.0))) M=mix(L, M, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notsame(B,I) && notsame(B,G) && notsame(B,E)) {
|
|
||||||
if (all_eq3(B,A,F,R) && none_eq2(B,D,src(2.0,1.0))) J=mix(K, L, 0.5);
|
|
||||||
if (all_eq3(B,C,D,Q) && none_eq2(B,F,src(-2.0,1.0))) K=mix(J, K, 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notsame(F,D)) {
|
|
||||||
if (notsame(D,I) && notsame(D,E) && notsame(D,C)) {
|
|
||||||
if (all_eq3(D,A,H,S) && none_eq2(D,B,src(1.0,2.0))) J=mix(L, J, 0.5);
|
|
||||||
if (all_eq3(D,G,B,P) && none_eq2(D,H,src(1.0,2.0))) L=mix(J, L, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notsame(F,E) && notsame(F,A) && notsame(F,G)) {
|
|
||||||
if (all_eq3(F,C,H,S) && none_eq2(F,B,src(-1.0,2.0))) K=mix(M, K, 0.5);
|
|
||||||
if (all_eq3(F,I,B,P) && none_eq2(F,H,src(-1.0,-2.0))) M=mix(K, M, 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 a = fract(tex_coord * source_size);
|
|
||||||
vec4 colour = (a.x < 0.5) ? (a.y < 0.5 ? J : L) : (a.y < 0.5 ? K : M);
|
|
||||||
frag_color = colour;
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#version 460 core
|
|
||||||
layout (location = 0) in vec2 frag_tex_coord;
|
|
||||||
layout (location = 0) out vec4 color;
|
|
||||||
layout (binding = 0) uniform sampler2D color_texture;
|
|
||||||
vec4 cubic(float x) {
|
|
||||||
float x2 = x * x;
|
|
||||||
float x3 = x2 * x;
|
|
||||||
return vec4(1.0, x, x2, x3) * transpose(mat4x4(
|
|
||||||
0.0, 2.0, 0.0, 0.0,
|
|
||||||
-2.0, 0.0, 2.0, 0.0,
|
|
||||||
4.0, -4.0, 2.0, -2.0,
|
|
||||||
-2.0, 2.0, -2.0, 1.0
|
|
||||||
) * (1.0 / 2.0));
|
|
||||||
}
|
|
||||||
vec4 textureBicubic(sampler2D samp, vec2 uv) {
|
|
||||||
vec2 tex_size = vec2(textureSize(samp, 0));
|
|
||||||
vec2 cc_tex = uv * tex_size - 0.5f;
|
|
||||||
vec2 fex = cc_tex - floor(cc_tex);
|
|
||||||
vec4 xcubic = cubic(fex.x);
|
|
||||||
vec4 ycubic = cubic(fex.y);
|
|
||||||
vec4 c = floor(cc_tex).xxyy + vec2(-0.5f, 1.5f).xyxy;
|
|
||||||
vec4 z = vec4(xcubic.yw, ycubic.yw);
|
|
||||||
vec4 s = vec4(xcubic.xz, ycubic.xz) + z;
|
|
||||||
vec4 offset = (c + z / s) * (1.0f / tex_size).xxyy;
|
|
||||||
vec2 n = vec2(s.x / (s.x + s.y), s.z / (s.z + s.w));
|
|
||||||
return mix(
|
|
||||||
mix(texture(samp, offset.yw), texture(samp, offset.xw), n.x),
|
|
||||||
mix(texture(samp, offset.yz), texture(samp, offset.xz), n.x),
|
|
||||||
n.y);
|
|
||||||
}
|
|
||||||
void main() {
|
|
||||||
color = textureBicubic(color_texture, frag_tex_coord);
|
|
||||||
}
|
|
|
@ -8,7 +8,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/settings_enums.h"
|
|
||||||
#include "video_core/present.h"
|
#include "video_core/present.h"
|
||||||
#include "video_core/renderer_opengl/gl_blit_screen.h"
|
#include "video_core/renderer_opengl/gl_blit_screen.h"
|
||||||
#include "video_core/renderer_opengl/gl_state_tracker.h"
|
#include "video_core/renderer_opengl/gl_state_tracker.h"
|
||||||
|
@ -87,15 +86,6 @@ void BlitScreen::CreateWindowAdapt() {
|
||||||
case Settings::ScalingFilter::Bicubic:
|
case Settings::ScalingFilter::Bicubic:
|
||||||
window_adapt = MakeBicubic(device);
|
window_adapt = MakeBicubic(device);
|
||||||
break;
|
break;
|
||||||
case Settings::ScalingFilter::ZeroTangent:
|
|
||||||
window_adapt = MakeZeroTangent(device);
|
|
||||||
break;
|
|
||||||
case Settings::ScalingFilter::BSpline:
|
|
||||||
window_adapt = MakeBSpline(device);
|
|
||||||
break;
|
|
||||||
case Settings::ScalingFilter::Mitchell:
|
|
||||||
window_adapt = MakeMitchell(device);
|
|
||||||
break;
|
|
||||||
case Settings::ScalingFilter::Gaussian:
|
case Settings::ScalingFilter::Gaussian:
|
||||||
window_adapt = MakeGaussian(device);
|
window_adapt = MakeGaussian(device);
|
||||||
break;
|
break;
|
||||||
|
@ -111,9 +101,6 @@ void BlitScreen::CreateWindowAdapt() {
|
||||||
case Settings::ScalingFilter::Area:
|
case Settings::ScalingFilter::Area:
|
||||||
window_adapt = MakeArea(device);
|
window_adapt = MakeArea(device);
|
||||||
break;
|
break;
|
||||||
case Settings::ScalingFilter::Mmpx:
|
|
||||||
window_adapt = MakeMmpx(device);
|
|
||||||
break;
|
|
||||||
case Settings::ScalingFilter::Fsr:
|
case Settings::ScalingFilter::Fsr:
|
||||||
case Settings::ScalingFilter::Bilinear:
|
case Settings::ScalingFilter::Bilinear:
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -14,10 +14,6 @@
|
||||||
#include "video_core/host_shaders/present_gaussian_frag.h"
|
#include "video_core/host_shaders/present_gaussian_frag.h"
|
||||||
#include "video_core/host_shaders/present_lanczos_frag.h"
|
#include "video_core/host_shaders/present_lanczos_frag.h"
|
||||||
#include "video_core/host_shaders/present_spline1_frag.h"
|
#include "video_core/host_shaders/present_spline1_frag.h"
|
||||||
#include "video_core/host_shaders/present_mitchell_frag.h"
|
|
||||||
#include "video_core/host_shaders/present_bspline_frag.h"
|
|
||||||
#include "video_core/host_shaders/present_zero_tangent_frag.h"
|
|
||||||
#include "video_core/host_shaders/present_mmpx_frag.h"
|
|
||||||
#include "video_core/renderer_opengl/present/filters.h"
|
#include "video_core/renderer_opengl/present/filters.h"
|
||||||
#include "video_core/renderer_opengl/present/util.h"
|
#include "video_core/renderer_opengl/present/util.h"
|
||||||
|
|
||||||
|
@ -43,21 +39,6 @@ std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device) {
|
||||||
HostShaders::PRESENT_BICUBIC_FRAG);
|
HostShaders::PRESENT_BICUBIC_FRAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeMitchell(const Device& device) {
|
|
||||||
return std::make_unique<WindowAdaptPass>(device, CreateBilinearSampler(),
|
|
||||||
HostShaders::PRESENT_MITCHELL_FRAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeZeroTangent(const Device& device) {
|
|
||||||
return std::make_unique<WindowAdaptPass>(device, CreateBilinearSampler(),
|
|
||||||
HostShaders::PRESENT_ZERO_TANGENT_FRAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBSpline(const Device& device) {
|
|
||||||
return std::make_unique<WindowAdaptPass>(device, CreateBilinearSampler(),
|
|
||||||
HostShaders::PRESENT_BSPLINE_FRAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device) {
|
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device) {
|
||||||
return std::make_unique<WindowAdaptPass>(device, CreateBilinearSampler(),
|
return std::make_unique<WindowAdaptPass>(device, CreateBilinearSampler(),
|
||||||
HostShaders::PRESENT_GAUSSIAN_FRAG);
|
HostShaders::PRESENT_GAUSSIAN_FRAG);
|
||||||
|
@ -79,9 +60,4 @@ std::unique_ptr<WindowAdaptPass> MakeArea(const Device& device) {
|
||||||
HostShaders::PRESENT_AREA_FRAG);
|
HostShaders::PRESENT_AREA_FRAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeMmpx(const Device& device) {
|
|
||||||
return std::make_unique<WindowAdaptPass>(device, CreateNearestNeighborSampler(),
|
|
||||||
HostShaders::PRESENT_MMPX_FRAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
|
@ -17,14 +17,10 @@ namespace OpenGL {
|
||||||
std::unique_ptr<WindowAdaptPass> MakeNearestNeighbor(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeNearestNeighbor(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeZeroTangent(const Device& device);
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeMitchell(const Device& device);
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBSpline(const Device& device);
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeScaleForce(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeScaleForce(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeArea(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeArea(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeMmpx(const Device& device);
|
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <vulkan/vulkan_core.h>
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "video_core/host_shaders/present_area_frag_spv.h"
|
#include "video_core/host_shaders/present_area_frag_spv.h"
|
||||||
|
@ -16,10 +14,6 @@
|
||||||
#include "video_core/host_shaders/present_gaussian_frag_spv.h"
|
#include "video_core/host_shaders/present_gaussian_frag_spv.h"
|
||||||
#include "video_core/host_shaders/present_lanczos_frag_spv.h"
|
#include "video_core/host_shaders/present_lanczos_frag_spv.h"
|
||||||
#include "video_core/host_shaders/present_spline1_frag_spv.h"
|
#include "video_core/host_shaders/present_spline1_frag_spv.h"
|
||||||
#include "video_core/host_shaders/present_mitchell_frag_spv.h"
|
|
||||||
#include "video_core/host_shaders/present_bspline_frag_spv.h"
|
|
||||||
#include "video_core/host_shaders/present_zero_tangent_frag_spv.h"
|
|
||||||
#include "video_core/host_shaders/present_mmpx_frag_spv.h"
|
|
||||||
#include "video_core/host_shaders/vulkan_present_frag_spv.h"
|
#include "video_core/host_shaders/vulkan_present_frag_spv.h"
|
||||||
#include "video_core/host_shaders/vulkan_present_scaleforce_fp16_frag_spv.h"
|
#include "video_core/host_shaders/vulkan_present_scaleforce_fp16_frag_spv.h"
|
||||||
#include "video_core/host_shaders/vulkan_present_scaleforce_fp32_frag_spv.h"
|
#include "video_core/host_shaders/vulkan_present_scaleforce_fp32_frag_spv.h"
|
||||||
|
@ -58,28 +52,13 @@ std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device, VkFormat fram
|
||||||
BuildShader(device, PRESENT_SPLINE1_FRAG_SPV));
|
BuildShader(device, PRESENT_SPLINE1_FRAG_SPV));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format, VkCubicFilterWeightsQCOM qcom_weights) {
|
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format) {
|
||||||
// No need for handrolled shader -- if the VK impl can do it for us ;)
|
// No need for handrolled shader -- if the VK impl can do it for us ;)
|
||||||
// Catmull-Rom is default bicubic for all implementations...
|
if (device.IsExtFilterCubicSupported())
|
||||||
if (device.IsExtFilterCubicSupported() && (device.IsQcomFilterCubicWeightsSupported() || qcom_weights == VK_CUBIC_FILTER_WEIGHTS_CATMULL_ROM_QCOM)) {
|
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateCubicSampler(device),
|
||||||
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateCubicSampler(device,
|
BuildShader(device, VULKAN_PRESENT_FRAG_SPV));
|
||||||
qcom_weights), BuildShader(device, VULKAN_PRESENT_FRAG_SPV));
|
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
|
||||||
} else {
|
BuildShader(device, PRESENT_BICUBIC_FRAG_SPV));
|
||||||
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device), [&](){
|
|
||||||
switch (qcom_weights) {
|
|
||||||
case VK_CUBIC_FILTER_WEIGHTS_CATMULL_ROM_QCOM:
|
|
||||||
return BuildShader(device, PRESENT_BICUBIC_FRAG_SPV);
|
|
||||||
case VK_CUBIC_FILTER_WEIGHTS_ZERO_TANGENT_CARDINAL_QCOM:
|
|
||||||
return BuildShader(device, PRESENT_ZERO_TANGENT_FRAG_SPV);
|
|
||||||
case VK_CUBIC_FILTER_WEIGHTS_B_SPLINE_QCOM:
|
|
||||||
return BuildShader(device, PRESENT_BSPLINE_FRAG_SPV);
|
|
||||||
case VK_CUBIC_FILTER_WEIGHTS_MITCHELL_NETRAVALI_QCOM:
|
|
||||||
return BuildShader(device, PRESENT_MITCHELL_FRAG_SPV);
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device, VkFormat frame_format) {
|
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device, VkFormat frame_format) {
|
||||||
|
@ -102,9 +81,4 @@ std::unique_ptr<WindowAdaptPass> MakeArea(const Device& device, VkFormat frame_f
|
||||||
BuildShader(device, PRESENT_AREA_FRAG_SPV));
|
BuildShader(device, PRESENT_AREA_FRAG_SPV));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeMmpx(const Device& device, VkFormat frame_format) {
|
|
||||||
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateNearestNeighborSampler(device),
|
|
||||||
BuildShader(device, PRESENT_MMPX_FRAG_SPV));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
|
@ -17,12 +17,11 @@ class MemoryAllocator;
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeNearestNeighbor(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeNearestNeighbor(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format, VkCubicFilterWeightsQCOM qcom_weights);
|
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeScaleForce(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeScaleForce(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeArea(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeArea(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeMmpx(const Device& device, VkFormat frame_format);
|
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue