Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 726f4621ea | |||
| 6069529cec | |||
| bd6e843037 | |||
| fa9a087af7 | |||
| 9e750f7359 | |||
| f283b4ed36 | |||
| cd284033e3 | |||
| 17dccfe052 | |||
| 39af7d4c11 | |||
| 56126d3e2e | |||
| e45257eb86 | |||
| ca7ea96040 | |||
| dba2d68ca2 | |||
| 39db9f9362 | |||
| 71117e0542 | |||
| 301dd07881 | |||
| 261491fa94 | |||
| 8b3d425ca1 | |||
| 0d736d49d6 | |||
| 0c74a495f5 | |||
| c6afeb2bf8 | |||
| d9067d85af | |||
| 2aa2ac7d9a | |||
| 90164197dc | |||
| 573e06131d | |||
| 06c8926a2e | |||
| eabd1017cc | |||
| b870bd255c | |||
| 37b5cf6003 | |||
| d761ecba8c | |||
| 83683440b2 | |||
| 9b18d0b111 | |||
| 46cfd9b6f3 | |||
| 889545e1ee | |||
| 24dc3834b6 | |||
| 2a66b40267 | |||
| feb8c5f88e | |||
| 300a646a34 | |||
| e875a3196b | |||
| 4eb082485d |
@@ -7,7 +7,7 @@
|
|||||||
EXCLUDE_FILES="CPM.cmake CPMUtil.cmake GetSCMRev.cmake renderdoc_app.h tools/cpm tools/shellcheck.sh tools/update-cpm.sh tools/windows/vcvarsall.sh externals/stb externals/glad externals/getopt externals/gamemode externals/FidelityFX-FSR externals/demangle externals/bc_decoder externals/cmake-modules"
|
EXCLUDE_FILES="CPM.cmake CPMUtil.cmake GetSCMRev.cmake renderdoc_app.h tools/cpm tools/shellcheck.sh tools/update-cpm.sh tools/windows/vcvarsall.sh externals/stb externals/glad externals/getopt externals/gamemode externals/FidelityFX-FSR externals/demangle externals/bc_decoder externals/cmake-modules"
|
||||||
|
|
||||||
# license header constants, please change when needed :))))
|
# license header constants, please change when needed :))))
|
||||||
YEAR=2026
|
YEAR=$(date "+%Y")
|
||||||
HOLDER="Eden Emulator Project"
|
HOLDER="Eden Emulator Project"
|
||||||
LICENSE="GPL-3.0-or-later"
|
LICENSE="GPL-3.0-or-later"
|
||||||
|
|
||||||
@@ -112,10 +112,10 @@ for file in $FILES; do
|
|||||||
[ "$excluded" = "true" ] && continue
|
[ "$excluded" = "true" ] && continue
|
||||||
|
|
||||||
case "$file" in
|
case "$file" in
|
||||||
*.cmake|*.sh|*CMakeLists.txt)
|
*.cmake|*.sh|*.ps1|*.py|*.rb|*.perl|*.pl|*.nix|*CMakeLists.txt)
|
||||||
begin="#"
|
begin="#"
|
||||||
;;
|
;;
|
||||||
*.kt*|*.cpp|*.h|*.qml)
|
*.kt|*.kts|*.cpp|*.h|*.qml|*.c|*.hpp|*.hxx|*.cxx|*.h.in|*.inc)
|
||||||
begin="//"
|
begin="//"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@@ -185,11 +185,12 @@ if [ "$UPDATE" = "true" ]; then
|
|||||||
|
|
||||||
for file in $SRC_FILES $OTHER_FILES; do
|
for file in $SRC_FILES $OTHER_FILES; do
|
||||||
case $(basename -- "$file") in
|
case $(basename -- "$file") in
|
||||||
*.cmake|*CMakeLists.txt)
|
# Windows Powershell wont use shebangs
|
||||||
|
*.cmake|*.ps1|*CMakeLists.txt)
|
||||||
begin="#"
|
begin="#"
|
||||||
shell="false"
|
shell="false"
|
||||||
;;
|
;;
|
||||||
*.sh)
|
*.sh|*.py|*.rb|*.perl|*.pl|*.nix)
|
||||||
begin="#"
|
begin="#"
|
||||||
shell=true
|
shell=true
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
# git-archive-all
|
|
||||||
export PATH="$PATH:/home/$USER/.local/bin"
|
|
||||||
|
|
||||||
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
|
|
||||||
GITREV="`git show -s --format='%h'`"
|
|
||||||
REV_NAME="eden-unified-source-${GITDATE}-${GITREV}"
|
|
||||||
|
|
||||||
COMPAT_LIST='dist/compatibility_list/compatibility_list.json'
|
|
||||||
|
|
||||||
mkdir artifacts
|
|
||||||
|
|
||||||
touch "${COMPAT_LIST}"
|
|
||||||
git describe --abbrev=0 --always HEAD > GIT-COMMIT
|
|
||||||
git describe --tags HEAD > GIT-TAG || echo 'unknown' > GIT-TAG
|
|
||||||
git-archive-all --include "${COMPAT_LIST}" --include GIT-COMMIT --include GIT-TAG --force-submodules artifacts/"${REV_NAME}.tar"
|
|
||||||
|
|
||||||
cd artifacts/
|
|
||||||
xz -T0 -9 "${REV_NAME}.tar"
|
|
||||||
sha256sum "${REV_NAME}.tar.xz" > "${REV_NAME}.tar.xz.sha256sum"
|
|
||||||
cd ..
|
|
||||||
@@ -75,6 +75,8 @@ cmake_dependent_option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet im
|
|||||||
set(YUZU_QT_MIRROR "" CACHE STRING "What mirror to use for downloading the bundled Qt libraries")
|
set(YUZU_QT_MIRROR "" CACHE STRING "What mirror to use for downloading the bundled Qt libraries")
|
||||||
cmake_dependent_option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF)
|
cmake_dependent_option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF)
|
||||||
|
|
||||||
|
option(ENABLE_DEBUG_TOOLS "Enable debugging tools (maxwell disassembler, SPIRV translator, etc)" OFF)
|
||||||
|
|
||||||
# non-linux bundled qt are static
|
# non-linux bundled qt are static
|
||||||
if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX))
|
if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX))
|
||||||
set(YUZU_STATIC_BUILD ON)
|
set(YUZU_STATIC_BUILD ON)
|
||||||
@@ -582,8 +584,6 @@ if (ENABLE_QT)
|
|||||||
else()
|
else()
|
||||||
AddQt(6.9.3)
|
AddQt(6.9.3)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(YUZU_STATIC_BUILD ON)
|
|
||||||
else()
|
else()
|
||||||
message(STATUS "Using system Qt")
|
message(STATUS "Using system Qt")
|
||||||
if (NOT Qt6_DIR)
|
if (NOT Qt6_DIR)
|
||||||
@@ -592,23 +592,7 @@ if (ENABLE_QT)
|
|||||||
list(APPEND CMAKE_PREFIX_PATH "${Qt6_DIR}")
|
list(APPEND CMAKE_PREFIX_PATH "${Qt6_DIR}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Qt6 CONFIG REQUIRED COMPONENTS Widgets Charts Concurrent)
|
find_package(Qt6 REQUIRED COMPONENTS Core)
|
||||||
|
|
||||||
if (YUZU_USE_QT_MULTIMEDIA)
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Multimedia)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (PLATFORM_LINUX OR PLATFORM_FREEBSD)
|
|
||||||
# yes Qt, we get it
|
|
||||||
set(QT_NO_PRIVATE_MODULE_WARNING ON)
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS DBus OPTIONAL_COMPONENTS GuiPrivate)
|
|
||||||
elseif (UNIX AND NOT APPLE)
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS DBus Gui)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (ENABLE_QT_TRANSLATION)
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT DEFINED QT_TARGET_PATH)
|
if (NOT DEFINED QT_TARGET_PATH)
|
||||||
get_target_property(qtcore_path Qt6::Core LOCATION_Release)
|
get_target_property(qtcore_path Qt6::Core LOCATION_Release)
|
||||||
@@ -631,21 +615,27 @@ if (ENABLE_QT)
|
|||||||
## Components ##
|
## Components ##
|
||||||
|
|
||||||
# Best practice is to ask for all components at once, so they are from the same version
|
# Best practice is to ask for all components at once, so they are from the same version
|
||||||
set(YUZU_QT_COMPONENTS Core Widgets Charts Concurrent)
|
set(YUZU_QT_COMPONENTS Core Widgets Charts Concurrent Gui)
|
||||||
if (PLATFORM_LINUX)
|
if (PLATFORM_LINUX OR PLATFORM_FREEBSD)
|
||||||
list(APPEND YUZU_QT_COMPONENTS DBus)
|
list(APPEND YUZU_QT_COMPONENTS DBus)
|
||||||
|
# yes Qt, we get it
|
||||||
|
set(QT_NO_PRIVATE_MODULE_WARNING ON)
|
||||||
|
list(APPEND YUZU_QT_OPTIONAL GuiPrivate)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (YUZU_USE_QT_MULTIMEDIA)
|
if (YUZU_USE_QT_MULTIMEDIA)
|
||||||
list(APPEND YUZU_QT_COMPONENTS Multimedia)
|
list(APPEND YUZU_QT_COMPONENTS Multimedia)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (YUZU_USE_QT_WEB_ENGINE)
|
if (YUZU_USE_QT_WEB_ENGINE)
|
||||||
list(APPEND YUZU_QT_COMPONENTS WebEngineCore WebEngineWidgets)
|
list(APPEND YUZU_QT_COMPONENTS WebEngineCore WebEngineWidgets)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ENABLE_QT_TRANSLATION)
|
if (ENABLE_QT_TRANSLATION)
|
||||||
list(APPEND YUZU_QT_COMPONENTS LinguistTools)
|
list(APPEND YUZU_QT_COMPONENTS LinguistTools)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS ${YUZU_QT_COMPONENTS})
|
find_package(Qt6 REQUIRED COMPONENTS ${YUZU_QT_COMPONENTS} OPTIONAL_COMPONENTS ${YUZU_QT_OPTIONAL})
|
||||||
set(QT_MAJOR_VERSION 6)
|
set(QT_MAJOR_VERSION 6)
|
||||||
# Qt6 sets cxx_std_17 and we need to undo that
|
# Qt6 sets cxx_std_17 and we need to undo that
|
||||||
set_target_properties(Qt6::Platform PROPERTIES INTERFACE_COMPILE_FEATURES "")
|
set_target_properties(Qt6::Platform PROPERTIES INTERFACE_COMPILE_FEATURES "")
|
||||||
@@ -713,6 +703,12 @@ endif()
|
|||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
if (ENABLE_DEBUG_TOOLS)
|
||||||
|
add_subdirectory(tools/maxwell-disas)
|
||||||
|
add_subdirectory(tools/maxwell-spirv)
|
||||||
|
add_subdirectory(tools/maxwell-ir)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Set yuzu project or yuzu-cmd project as default StartUp Project in Visual Studio depending on whether QT is enabled or not
|
# Set yuzu project or yuzu-cmd project as default StartUp Project in Visual Studio depending on whether QT is enabled or not
|
||||||
if(ENABLE_QT)
|
if(ENABLE_QT)
|
||||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT yuzu)
|
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT yuzu)
|
||||||
|
|||||||
@@ -715,8 +715,8 @@ function(AddCIPackage)
|
|||||||
"${${ARTIFACT_PACKAGE}_SOURCE_DIR}" PARENT_SCOPE)
|
"${${ARTIFACT_PACKAGE}_SOURCE_DIR}" PARENT_SCOPE)
|
||||||
|
|
||||||
if (PKG_ARGS_MODULE)
|
if (PKG_ARGS_MODULE)
|
||||||
list(APPEND CMAKE_PREFIX_PATH "${${ARTIFACT_PACKAGE}_SOURCE_DIR}")
|
list(PREPEND CMAKE_PREFIX_PATH "${${ARTIFACT_PACKAGE}_SOURCE_DIR}")
|
||||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
|
Propagate(CMAKE_PREFIX_PATH)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
find_package(${ARTIFACT_PACKAGE} ${ARTIFACT_MIN_VERSION} REQUIRED)
|
find_package(${ARTIFACT_PACKAGE} ${ARTIFACT_MIN_VERSION} REQUIRED)
|
||||||
@@ -730,7 +730,7 @@ function(AddQt version)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
AddCIPackage(
|
AddCIPackage(
|
||||||
NAME Qt
|
NAME qt
|
||||||
PACKAGE Qt6
|
PACKAGE Qt6
|
||||||
VERSION ${version}
|
VERSION ${version}
|
||||||
MIN_VERSION 6
|
MIN_VERSION 6
|
||||||
@@ -740,5 +740,8 @@ function(AddQt version)
|
|||||||
freebsd-amd64 solaris-amd64 openbsd-amd64
|
freebsd-amd64 solaris-amd64 openbsd-amd64
|
||||||
MODULE)
|
MODULE)
|
||||||
|
|
||||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
|
find_package(Qt6 REQUIRED PATHS ${Qt6_SOURCE_DIR} NO_DEFAULT_PATH)
|
||||||
|
|
||||||
|
Propagate(CMAKE_PREFIX_PATH)
|
||||||
|
Propagate(Qt6_SOURCE_DIR)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|||||||
@@ -112,7 +112,8 @@
|
|||||||
"options": [
|
"options": [
|
||||||
"QUAZIP_QT_MAJOR_VERSION 6",
|
"QUAZIP_QT_MAJOR_VERSION 6",
|
||||||
"QUAZIP_INSTALL OFF",
|
"QUAZIP_INSTALL OFF",
|
||||||
"QUAZIP_ENABLE_QTEXTCODEC OFF"
|
"QUAZIP_ENABLE_QTEXTCODEC OFF",
|
||||||
|
"QUAZIP_BZIP2 OFF"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
viewBox="0 0 512 512"
|
viewBox="0 0 512 512"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg7"
|
id="svg7"
|
||||||
sodipodi:docname="1stanni.svg"
|
sodipodi:docname="base.svg.2026_01_12_14_43_47.0.svg"
|
||||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
inkscape:version="1.4.2 (ebf0e94, 2025-05-08)"
|
||||||
inkscape:export-filename="base.svg.2026_01_12_14_43_47.0.svg"
|
inkscape:export-filename="base.svg.2026_01_12_14_43_47.0.svg"
|
||||||
inkscape:export-xdpi="96"
|
inkscape:export-xdpi="96"
|
||||||
inkscape:export-ydpi="96"
|
inkscape:export-ydpi="96"
|
||||||
@@ -19,34 +19,36 @@
|
|||||||
<defs
|
<defs
|
||||||
id="defs7">
|
id="defs7">
|
||||||
<linearGradient
|
<linearGradient
|
||||||
id="linearGradient34"
|
id="linearGradient1"
|
||||||
inkscape:collect="always">
|
inkscape:collect="always">
|
||||||
<stop
|
<stop
|
||||||
style="stop-color:#ffd700;stop-opacity:1;"
|
style="stop-color:#ff2e88;stop-opacity:0.5;"
|
||||||
offset="0"
|
offset="0"
|
||||||
id="stop34" />
|
id="stop3" />
|
||||||
<stop
|
<stop
|
||||||
style="stop-color:#ffd700;stop-opacity:0.48031053;"
|
style="stop-color:#bf42f6;stop-opacity:0.5;"
|
||||||
offset="1"
|
offset="0.44631511"
|
||||||
id="stop35" />
|
id="stop4" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#5da5ed;stop-opacity:0.5;"
|
||||||
|
offset="0.90088946"
|
||||||
|
id="stop2" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<rect
|
|
||||||
x="20.999999"
|
|
||||||
y="287.30493"
|
|
||||||
width="487.07235"
|
|
||||||
height="134.69506"
|
|
||||||
id="rect22" />
|
|
||||||
<linearGradient
|
<linearGradient
|
||||||
id="linearGradient21"
|
id="linearGradient138"
|
||||||
inkscape:collect="always">
|
inkscape:collect="always">
|
||||||
<stop
|
<stop
|
||||||
style="stop-color:#3a0057;stop-opacity:1;"
|
style="stop-color:#ff2e88;stop-opacity:1;"
|
||||||
offset="0"
|
offset="0"
|
||||||
id="stop21" />
|
id="stop152" />
|
||||||
<stop
|
<stop
|
||||||
style="stop-color:#830091;stop-opacity:1;"
|
style="stop-color:#bf42f6;stop-opacity:1;"
|
||||||
offset="1"
|
offset="0.44971901"
|
||||||
id="stop22" />
|
id="stop137" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#5da5ed;stop-opacity:1;"
|
||||||
|
offset="0.89793283"
|
||||||
|
id="stop138" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<linearGradient
|
<linearGradient
|
||||||
id="swatch37"
|
id="swatch37"
|
||||||
@@ -114,6 +116,33 @@
|
|||||||
width="521.34025"
|
width="521.34025"
|
||||||
height="248.94868"
|
height="248.94868"
|
||||||
id="rect24" />
|
id="rect24" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient11"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ff2e88;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop11" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#bf42f6;stop-opacity:1;"
|
||||||
|
offset="0.44971901"
|
||||||
|
id="stop154" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#5da5ed;stop-opacity:1;"
|
||||||
|
offset="0.89793283"
|
||||||
|
id="stop12" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient138"
|
||||||
|
id="linearGradient6"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.118028,0,0,1.116699,-46.314723,-42.388667)"
|
||||||
|
x1="270.39996"
|
||||||
|
y1="40.000019"
|
||||||
|
x2="270.39996"
|
||||||
|
y2="494.39996"
|
||||||
|
spreadMethod="pad" />
|
||||||
<clipPath
|
<clipPath
|
||||||
clipPathUnits="userSpaceOnUse"
|
clipPathUnits="userSpaceOnUse"
|
||||||
id="clipPath18">
|
id="clipPath18">
|
||||||
@@ -136,6 +165,16 @@
|
|||||||
inkscape:label="Circle"
|
inkscape:label="Circle"
|
||||||
r="191.89999" />
|
r="191.89999" />
|
||||||
</clipPath>
|
</clipPath>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient11"
|
||||||
|
id="linearGradient27"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(-6.9401139e-5,-2.8678628)"
|
||||||
|
x1="256.00012"
|
||||||
|
y1="102.94693"
|
||||||
|
x2="256.00012"
|
||||||
|
y2="409.05307" />
|
||||||
<clipPath
|
<clipPath
|
||||||
clipPathUnits="userSpaceOnUse"
|
clipPathUnits="userSpaceOnUse"
|
||||||
id="clipPath128">
|
id="clipPath128">
|
||||||
@@ -148,106 +187,14 @@
|
|||||||
</clipPath>
|
</clipPath>
|
||||||
<linearGradient
|
<linearGradient
|
||||||
inkscape:collect="always"
|
inkscape:collect="always"
|
||||||
xlink:href="#linearGradient21"
|
xlink:href="#linearGradient1"
|
||||||
id="linearGradient22"
|
id="linearGradient2"
|
||||||
x1="256"
|
x1="256"
|
||||||
y1="0"
|
y1="64"
|
||||||
x2="256"
|
x2="256"
|
||||||
y2="512"
|
y2="448"
|
||||||
gradientUnits="userSpaceOnUse" />
|
gradientUnits="userSpaceOnUse"
|
||||||
<linearGradient
|
gradientTransform="matrix(1.3229974,0,0,1.3214002,-82.687336,-82.290326)" />
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient34"
|
|
||||||
id="linearGradient35"
|
|
||||||
x1="256"
|
|
||||||
y1="-0.048701428"
|
|
||||||
x2="256"
|
|
||||||
y2="512.04932"
|
|
||||||
gradientUnits="userSpaceOnUse" />
|
|
||||||
<filter
|
|
||||||
inkscape:label="Glowing Bubble"
|
|
||||||
inkscape:menu="Ridges"
|
|
||||||
inkscape:menu-tooltip="Bubble effect with refraction and glow"
|
|
||||||
x="-0.19420711"
|
|
||||||
y="-0.11239541"
|
|
||||||
width="1.3884142"
|
|
||||||
height="1.2247908"
|
|
||||||
style="color-interpolation-filters:sRGB;"
|
|
||||||
id="filter61">
|
|
||||||
<feGaussianBlur
|
|
||||||
stdDeviation="1"
|
|
||||||
result="result1"
|
|
||||||
id="feGaussianBlur56" />
|
|
||||||
<feGaussianBlur
|
|
||||||
stdDeviation="10"
|
|
||||||
result="result6"
|
|
||||||
in="result1"
|
|
||||||
id="feGaussianBlur57" />
|
|
||||||
<feComposite
|
|
||||||
operator="atop"
|
|
||||||
in="result6"
|
|
||||||
in2="result1"
|
|
||||||
result="result8"
|
|
||||||
id="feComposite57" />
|
|
||||||
<feComposite
|
|
||||||
operator="xor"
|
|
||||||
result="fbSourceGraphic"
|
|
||||||
in="result6"
|
|
||||||
in2="result8"
|
|
||||||
id="feComposite58" />
|
|
||||||
<feColorMatrix
|
|
||||||
result="fbSourceGraphicAlpha"
|
|
||||||
in="fbSourceGraphic"
|
|
||||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 2 0 "
|
|
||||||
id="feColorMatrix58" />
|
|
||||||
<feGaussianBlur
|
|
||||||
result="result0"
|
|
||||||
in="fbSourceGraphicAlpha"
|
|
||||||
stdDeviation="1"
|
|
||||||
id="feGaussianBlur58" />
|
|
||||||
<feSpecularLighting
|
|
||||||
specularExponent="35"
|
|
||||||
specularConstant="1.5"
|
|
||||||
surfaceScale="-2"
|
|
||||||
lighting-color="rgb(255,255,255)"
|
|
||||||
result="result1"
|
|
||||||
in="result0"
|
|
||||||
id="feSpecularLighting58">
|
|
||||||
<feDistantLight
|
|
||||||
azimuth="230"
|
|
||||||
elevation="60"
|
|
||||||
id="feDistantLight58" />
|
|
||||||
</feSpecularLighting>
|
|
||||||
<feComposite
|
|
||||||
operator="in"
|
|
||||||
result="result2"
|
|
||||||
in="result1"
|
|
||||||
in2="fbSourceGraphicAlpha"
|
|
||||||
id="feComposite59" />
|
|
||||||
<feComposite
|
|
||||||
k3="1.2"
|
|
||||||
k2="1.1"
|
|
||||||
operator="arithmetic"
|
|
||||||
result="result4"
|
|
||||||
in="fbSourceGraphic"
|
|
||||||
in2="result2"
|
|
||||||
id="feComposite60" />
|
|
||||||
<feGaussianBlur
|
|
||||||
result="result80"
|
|
||||||
in="result4"
|
|
||||||
stdDeviation="0.5"
|
|
||||||
id="feGaussianBlur60" />
|
|
||||||
<feComposite
|
|
||||||
operator="atop"
|
|
||||||
in="result9"
|
|
||||||
in2="result80"
|
|
||||||
result="result91"
|
|
||||||
id="feComposite61" />
|
|
||||||
<feBlend
|
|
||||||
mode="multiply"
|
|
||||||
in2="result91"
|
|
||||||
id="feBlend61" />
|
|
||||||
</filter>
|
|
||||||
</defs>
|
</defs>
|
||||||
<sodipodi:namedview
|
<sodipodi:namedview
|
||||||
id="namedview7"
|
id="namedview7"
|
||||||
@@ -258,29 +205,23 @@
|
|||||||
inkscape:pageopacity="0.0"
|
inkscape:pageopacity="0.0"
|
||||||
inkscape:pagecheckerboard="0"
|
inkscape:pagecheckerboard="0"
|
||||||
inkscape:deskcolor="#d1d1d1"
|
inkscape:deskcolor="#d1d1d1"
|
||||||
inkscape:zoom="1"
|
inkscape:zoom="1.4142136"
|
||||||
inkscape:cx="213.49999"
|
inkscape:cx="261.62951"
|
||||||
inkscape:cy="248.99999"
|
inkscape:cy="230.87036"
|
||||||
inkscape:window-width="1600"
|
inkscape:window-width="1920"
|
||||||
inkscape:window-height="849"
|
inkscape:window-height="1008"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="1080"
|
||||||
inkscape:window-y="27"
|
inkscape:window-y="351"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="svg7" />
|
inkscape:current-layer="svg7" />
|
||||||
<circle
|
|
||||||
style="fill:url(#linearGradient22);fill-opacity:1;stroke:none;stroke-width:8"
|
|
||||||
id="path21"
|
|
||||||
cx="256"
|
|
||||||
cy="256"
|
|
||||||
r="256" />
|
|
||||||
<path
|
<path
|
||||||
id="path8-7"
|
id="path8-7"
|
||||||
style="display:inline;mix-blend-mode:normal;fill:url(#linearGradient35);fill-opacity:1;fill-rule:nonzero;stroke:#320081;stroke-width:4.067;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
style="display:inline;mix-blend-mode:multiply;fill:url(#linearGradient6);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2);stroke-width:3.9666;stroke-dasharray:none;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
||||||
inkscape:label="Circle"
|
inkscape:label="Circle"
|
||||||
d="M 256,2.2792898 A 254.0155,253.71401 0 0 0 150.68475,25.115202 c 19.54414,1.070775 38.74692,5.250294 51.56848,11.647658 14.14361,7.056691 28.63804,19.185961 39.4212,29.347551 h 40.60981 c 1.03847,-0.68139 2.10297,-1.36938 3.1938,-2.05957 5.45602,-15.78533 14.79164,-43.183497 19.49612,-57.0097682 A 254.0155,253.71401 0 0 0 256,2.2792898 Z m 61.57106,7.567234 -18.26098,46.1544672 c 7.79702,-4.13918 16.35655,-7.87447 25.20671,-10.87081 23.1229,-7.828433 43.96931,-10.170904 54.94058,-10.868226 A 254.0155,253.71401 0 0 0 317.57106,9.8465238 Z m 65.39277,26.4001532 c -9.68256,4.806644 -33.05532,16.642034 -55.68217,29.863734 H 424.4677 A 254.0155,253.71401 0 0 0 382.96383,36.246677 Z M 113.90698,45.690231 A 254.0155,253.71401 0 0 0 87.532302,66.110411 H 194.2739 c -1.47402,-0.80231 -2.35141,-1.25949 -2.35141,-1.25949 l 10.4496,-11.83348 -38.40568,7.01234 c 0,1e-5 -12.21537,-4.60266 -40.17313,-12.27223 -3.45336,-0.94731 -6.75329,-1.61824 -9.8863,-2.06732 z m -36.803618,30.18635 a 254.0155,253.71401 0 0 0 -34.88372,43.090929 h 59.976738 c 18.11461,-12.04145 40.14252,-22.882149 62.31266,-24.534159 52.93006,-3.9444 70.16538,1.86342 70.16538,1.86342 0,0 -4.612,-4.8206 -14.51938,-13.36656 -2.72366,-2.34942 -6.0844,-4.77373 -9.52455,-7.05363 z m 174.472868,0 c 4.57322,4.7186 7.29716,7.83565 7.29716,7.83565 0,0 3.53501,-3.18484 9.62532,-7.83565 z m 60.27649,0 c -21.56573,15.45339 -25.4703,27.979669 -25.4703,27.979669 0,0 54.83326,-19.215729 100.70543,-0.31228 11.63986,4.79661 21.58481,10.13159 29.94832,15.42354 h 52.74419 A 254.0155,253.71401 0 0 0 434.89664,75.876581 Z M 36.250648,128.73367 A 254.0155,253.71401 0 0 0 16.372095,171.82459 H 147.45478 c 1.45695,-2.5815 3.06539,-5.08648 4.83979,-7.48982 14.23694,-19.28301 27.92088,-30.0088 36.86047,-35.6011 h -30.25323 c -5.87346,0.93472 -12.04945,1.99094 -18.28166,3.16937 -30.12936,5.69727 -81.157618,22.78945 -81.157618,22.78945 0,0 11.47125,-12.39249 29.11369,-25.95882 z m 265.630492,0 c 33.48676,11.2434 52.42799,26.78443 62.7752,43.09092 h 130.97157 a 254.0155,253.71401 0 0 0 -19.87856,-43.09092 h -44.81136 c 14.85233,11.5863 21.59948,20.9854 21.59948,20.9854 0,0 -33.5226,-12.37087 -66.0646,-20.9854 z m -45.96641,16.27007 c -1.00419,0.0106 -10.12705,0.72026 -44.98966,20.64729 -3.12132,1.78406 -6.25434,3.86182 -9.37468,6.17356 h 41.81911 c 7.17181,-17.34774 12.64083,-26.82085 12.64083,-26.82085 0,0 -0.0287,-7.1e-4 -0.0957,0 z m 14.18088,0.0465 c 0,0 -3.31228,9.32762 -7.30492,26.77438 h 51.78554 C 287.6577,146.14158 270.09561,145.0502 270.09561,145.0502 Z M 13.152456,181.59075 A 254.0155,253.71401 0 0 0 3.927651,224.68167 H 134.1447 c 0.56161,-12.72411 2.67825,-28.50188 8.61499,-43.09092 z m 176.661504,0 c -14.27121,13.10564 -27.60733,29.58761 -37.56073,43.09092 h 73.3721 c 4.47018,-16.79061 9.35068,-31.26371 13.86562,-43.09092 z m 70.85787,0 c -2.41384,11.76417 -4.9032,26.20707 -6.94831,43.09092 H 360.4832 c -8.32133,-10.88917 -20.66988,-26.17008 -36.35141,-43.09092 z m 109.17313,0 c 6.63611,15.24089 6.92441,30.5373 5.57882,43.09092 h 132.64857 a 254.0155,253.71401 0 0 0 -9.22481,-43.09092 z M 2.90181,234.44783 A 254.0155,253.71401 0 0 0 1.984498,255.9933 254.0155,253.71401 0 0 0 2.90181,277.53876 h 211.89923 c 2.25762,-15.52555 5.14325,-29.93448 8.3385,-43.09093 h -77.8863 c -6.46396,9.27617 -10.33076,15.56549 -10.33076,15.56549 0,0 -0.82623,-6.14945 -0.9354,-15.56549 z m 249.72093,0 c -1.3692,13.09684 -2.4456,27.49209 -3.02068,43.09093 h 259.49613 a 254.0155,253.71401 0 0 0 0.91731,-21.54546 254.0155,253.71401 0 0 0 -0.91731,-21.54547 H 374.02584 c -0.445,2.5469 -0.90878,4.89768 -1.32817,7.01751 0,0 -1.69726,-2.53821 -4.94056,-7.01751 z M 3.927651,287.30493 a 254.0155,253.71401 0 0 0 9.224805,43.09091 H 214.04393 c -1.29238,-15.40742 -1.57503,-30.04388 -0.41861,-43.09091 z m 245.385009,0 c -0.30355,13.54349 -0.22032,27.92598 0.36951,43.09091 h 249.16537 a 254.0155,253.71401 0 0 0 9.22481,-43.09091 z M 16.369511,340.16201 a 254.0155,253.71401 0 0 0 19.878554,43.09091 H 221.4677 c -2.69781,-14.4523 -4.96108,-29.01285 -6.4832,-43.09091 z m 233.842379,0 c 1.15864,15.47765 3.81286,29.83979 7.51679,43.09091 h 218.02325 a 254.0155,253.71401 0 0 0 19.87856,-43.09091 z M 42.217052,393.01909 a 254.0155,253.71401 0 0 0 34.88372,43.09093 H 233.09561 c -3.40902,-13.67281 -6.76794,-28.2531 -9.73902,-43.09093 z m 218.490958,0 c 5.34985,16.15926 12.22007,30.51982 19.68733,43.09093 h 154.50389 a 254.0155,253.71401 0 0 0 34.88371,-43.09093 z M 87.529722,445.87618 a 254.0155,253.71401 0 0 0 166.229968,63.8208 c -3.67805,-12.0825 -10.85464,-35.49828 -18.18088,-63.8208 z m 199.010328,0 c 17.5887,26.43772 36.99259,43.60598 47.33592,51.61309 a 254.0155,253.71401 0 0 0 90.59431,-51.61309 z" />
|
d="M 256,2.2792898 A 254.0155,253.71401 0 0 0 150.68475,25.115202 c 19.54414,1.070775 38.74692,5.250294 51.56848,11.647658 14.14361,7.056691 28.63804,19.185961 39.4212,29.347551 h 40.60981 c 1.03847,-0.68139 2.10297,-1.36938 3.1938,-2.05957 5.45602,-15.78533 14.79164,-43.183497 19.49612,-57.0097682 A 254.0155,253.71401 0 0 0 256,2.2792898 Z m 61.57106,7.567234 -18.26098,46.1544672 c 7.79702,-4.13918 16.35655,-7.87447 25.20671,-10.87081 23.1229,-7.828433 43.96931,-10.170904 54.94058,-10.868226 A 254.0155,253.71401 0 0 0 317.57106,9.8465238 Z m 65.39277,26.4001532 c -9.68256,4.806644 -33.05532,16.642034 -55.68217,29.863734 H 424.4677 A 254.0155,253.71401 0 0 0 382.96383,36.246677 Z M 113.90698,45.690231 A 254.0155,253.71401 0 0 0 87.532302,66.110411 H 194.2739 c -1.47402,-0.80231 -2.35141,-1.25949 -2.35141,-1.25949 l 10.4496,-11.83348 -38.40568,7.01234 c 0,1e-5 -12.21537,-4.60266 -40.17313,-12.27223 -3.45336,-0.94731 -6.75329,-1.61824 -9.8863,-2.06732 z m -36.803618,30.18635 a 254.0155,253.71401 0 0 0 -34.88372,43.090929 h 59.976738 c 18.11461,-12.04145 40.14252,-22.882149 62.31266,-24.534159 52.93006,-3.9444 70.16538,1.86342 70.16538,1.86342 0,0 -4.612,-4.8206 -14.51938,-13.36656 -2.72366,-2.34942 -6.0844,-4.77373 -9.52455,-7.05363 z m 174.472868,0 c 4.57322,4.7186 7.29716,7.83565 7.29716,7.83565 0,0 3.53501,-3.18484 9.62532,-7.83565 z m 60.27649,0 c -21.56573,15.45339 -25.4703,27.979669 -25.4703,27.979669 0,0 54.83326,-19.215729 100.70543,-0.31228 11.63986,4.79661 21.58481,10.13159 29.94832,15.42354 h 52.74419 A 254.0155,253.71401 0 0 0 434.89664,75.876581 Z M 36.250648,128.73367 A 254.0155,253.71401 0 0 0 16.372095,171.82459 H 147.45478 c 1.45695,-2.5815 3.06539,-5.08648 4.83979,-7.48982 14.23694,-19.28301 27.92088,-30.0088 36.86047,-35.6011 h -30.25323 c -5.87346,0.93472 -12.04945,1.99094 -18.28166,3.16937 -30.12936,5.69727 -81.157618,22.78945 -81.157618,22.78945 0,0 11.47125,-12.39249 29.11369,-25.95882 z m 265.630492,0 c 33.48676,11.2434 52.42799,26.78443 62.7752,43.09092 h 130.97157 a 254.0155,253.71401 0 0 0 -19.87856,-43.09092 h -44.81136 c 14.85233,11.5863 21.59948,20.9854 21.59948,20.9854 0,0 -33.5226,-12.37087 -66.0646,-20.9854 z m -45.96641,16.27007 c -1.00419,0.0106 -10.12705,0.72026 -44.98966,20.64729 -3.12132,1.78406 -6.25434,3.86182 -9.37468,6.17356 h 41.81911 c 7.17181,-17.34774 12.64083,-26.82085 12.64083,-26.82085 0,0 -0.0287,-7.1e-4 -0.0957,0 z m 14.18088,0.0465 c 0,0 -3.31228,9.32762 -7.30492,26.77438 h 51.78554 C 287.6577,146.14158 270.09561,145.0502 270.09561,145.0502 Z M 13.152456,181.59075 A 254.0155,253.71401 0 0 0 3.927651,224.68167 H 134.1447 c 0.56161,-12.72411 2.67825,-28.50188 8.61499,-43.09092 z m 176.661504,0 c -14.27121,13.10564 -27.60733,29.58761 -37.56073,43.09092 h 73.3721 c 4.47018,-16.79061 9.35068,-31.26371 13.86562,-43.09092 z m 70.85787,0 c -2.41384,11.76417 -4.9032,26.20707 -6.94831,43.09092 H 360.4832 c -8.32133,-10.88917 -20.66988,-26.17008 -36.35141,-43.09092 z m 109.17313,0 c 6.63611,15.24089 6.92441,30.5373 5.57882,43.09092 h 132.64857 a 254.0155,253.71401 0 0 0 -9.22481,-43.09092 z M 2.90181,234.44783 A 254.0155,253.71401 0 0 0 1.984498,255.9933 254.0155,253.71401 0 0 0 2.90181,277.53876 h 211.89923 c 2.25762,-15.52555 5.14325,-29.93448 8.3385,-43.09093 h -77.8863 c -6.46396,9.27617 -10.33076,15.56549 -10.33076,15.56549 0,0 -0.82623,-6.14945 -0.9354,-15.56549 z m 249.72093,0 c -1.3692,13.09684 -2.4456,27.49209 -3.02068,43.09093 h 259.49613 a 254.0155,253.71401 0 0 0 0.91731,-21.54546 254.0155,253.71401 0 0 0 -0.91731,-21.54547 H 374.02584 c -0.445,2.5469 -0.90878,4.89768 -1.32817,7.01751 0,0 -1.69726,-2.53821 -4.94056,-7.01751 z M 3.927651,287.30493 a 254.0155,253.71401 0 0 0 9.224805,43.09091 H 214.04393 c -1.29238,-15.40742 -1.57503,-30.04388 -0.41861,-43.09091 z m 245.385009,0 c -0.30355,13.54349 -0.22032,27.92598 0.36951,43.09091 h 249.16537 a 254.0155,253.71401 0 0 0 9.22481,-43.09091 z M 16.369511,340.16201 a 254.0155,253.71401 0 0 0 19.878554,43.09091 H 221.4677 c -2.69781,-14.4523 -4.96108,-29.01285 -6.4832,-43.09091 z m 233.842379,0 c 1.15864,15.47765 3.81286,29.83979 7.51679,43.09091 h 218.02325 a 254.0155,253.71401 0 0 0 19.87856,-43.09091 z M 42.217052,393.01909 a 254.0155,253.71401 0 0 0 34.88372,43.09093 H 233.09561 c -3.40902,-13.67281 -6.76794,-28.2531 -9.73902,-43.09093 z m 218.490958,0 c 5.34985,16.15926 12.22007,30.51982 19.68733,43.09093 h 154.50389 a 254.0155,253.71401 0 0 0 34.88371,-43.09093 z M 87.529722,445.87618 a 254.0155,253.71401 0 0 0 166.229968,63.8208 c -3.67805,-12.0825 -10.85464,-35.49828 -18.18088,-63.8208 z m 199.010328,0 c 17.5887,26.43772 36.99259,43.60598 47.33592,51.61309 a 254.0155,253.71401 0 0 0 90.59431,-51.61309 z" />
|
||||||
<path
|
<path
|
||||||
id="path27"
|
id="path27"
|
||||||
style="display:inline;mix-blend-mode:multiply;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
|
style="display:inline;mix-blend-mode:multiply;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient27);stroke-width:3;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
d="m 318.98012,441.7375 c -9.87518,-6.73978 -64.39137,-49.0272 -67.68975,-127.81978 -3.69298,-88.21893 15.36468,-141.91029 15.36468,-141.91029 0,0 16.00378,0.99513 39.80316,26.53195 23.79939,25.53753 37.74965,46.43102 37.74965,46.43102 3.91262,-19.79992 12.84563,-66.32402 -60.72865,-87.55523 0,0 12.82326,-5.38883 39.3925,-3.81382 26.56907,1.57572 81.6822,21.93799 81.6822,21.93799 0,0 -14.79766,-20.63773 -49.47063,-34.94295 -34.67291,-14.30533 -76.1182,0.23644 -76.1182,0.23644 0,0 3.86959,-12.43127 27.22669,-26.38478 23.35718,-13.9537 49.27409,-26.501533 49.27409,-26.501533 0,0 -21.97854,-0.26548 -47.67725,8.44535 -6.68948,2.267506 -13.15863,5.094213 -19.05208,8.226563 l 16.05803,-40.634103 -4.4617,-1.89059 -5.1305,-0.95965 c 0,0 -11.24072,33.12428 -16.92051,49.576513 -12.13137,7.68489 -20.11005,14.87735 -20.11005,14.87735 0,0 -21.90573,-25.09227 -42.79668,-35.527803 -26.03412,-13.00525 -86.88249,-13.90359 -94.0044,10.401173 0,0 13.56804,-7.884703 34.70032,-2.080917 21.13214,5.803997 30.3644,9.287307 30.3644,9.287307 l 29.02989,-5.30681 -7.89811,8.95527 c 0,0 13.8496,7.21324 21.33822,13.68063 7.48859,6.46722 10.9757,10.11472 10.9757,10.11472 0,0 -13.02739,-4.39388 -53.03507,-1.40893 -40.00771,2.98473 -79.40016,45.60209 -79.40016,45.60209 0,0 38.57037,-12.93531 61.34393,-17.24677 22.77354,-4.31126 44.52166,-6.46757 44.52166,-6.46757 0,0 -17.23298,5.97003 -35.69792,31.00932 -18.46522,25.03987 -13.13146,64.83866 -13.13146,64.83866 0,0 29.33874,-47.7577 57.44675,-63.84249 28.10798,-16.08527 34.0799,-15.6238 34.0799,-15.6238 0,0 -22.56785,39.13486 -31.39017,101.98268 -8.03005,57.2039 26.77689,163.75449 31.1572,178.89699"
|
d="m 318.98012,441.7375 c -9.87518,-6.73978 -64.39137,-49.0272 -67.68975,-127.81978 -3.69298,-88.21893 15.36468,-141.91029 15.36468,-141.91029 0,0 16.00378,0.99513 39.80316,26.53195 23.79939,25.53753 37.74965,46.43102 37.74965,46.43102 3.91262,-19.79992 12.84563,-66.32402 -60.72865,-87.55523 0,0 12.82326,-5.38883 39.3925,-3.81382 26.56907,1.57572 81.6822,21.93799 81.6822,21.93799 0,0 -14.79766,-20.63773 -49.47063,-34.94295 -34.67291,-14.30533 -76.1182,0.23644 -76.1182,0.23644 0,0 3.86959,-12.43127 27.22669,-26.38478 23.35718,-13.9537 49.27409,-26.501533 49.27409,-26.501533 0,0 -21.97854,-0.26548 -47.67725,8.44535 -6.68948,2.267506 -13.15863,5.094213 -19.05208,8.226563 l 16.05803,-40.634103 -4.4617,-1.89059 -5.1305,-0.95965 c 0,0 -11.24072,33.12428 -16.92051,49.576513 -12.13137,7.68489 -20.11005,14.87735 -20.11005,14.87735 0,0 -21.90573,-25.09227 -42.79668,-35.527803 -26.03412,-13.00525 -86.88249,-13.90359 -94.0044,10.401173 0,0 13.56804,-7.884703 34.70032,-2.080917 21.13214,5.803997 30.3644,9.287307 30.3644,9.287307 l 29.02989,-5.30681 -7.89811,8.95527 c 0,0 13.8496,7.21324 21.33822,13.68063 7.48859,6.46722 10.9757,10.11472 10.9757,10.11472 0,0 -13.02739,-4.39388 -53.03507,-1.40893 -40.00771,2.98473 -79.40016,45.60209 -79.40016,45.60209 0,0 38.57037,-12.93531 61.34393,-17.24677 22.77354,-4.31126 44.52166,-6.46757 44.52166,-6.46757 0,0 -17.23298,5.97003 -35.69792,31.00932 -18.46522,25.03987 -13.13146,64.83866 -13.13146,64.83866 0,0 29.33874,-47.7577 57.44675,-63.84249 28.10798,-16.08527 34.0799,-15.6238 34.0799,-15.6238 0,0 -22.56785,39.13486 -31.39017,101.98268 -8.03005,57.2039 26.77689,163.75449 31.1572,178.89699"
|
||||||
sodipodi:nodetypes="cscsccscscscsccccccscscccscscscscscsc"
|
sodipodi:nodetypes="cscsccscscscsccccccscscccscscscscscsc"
|
||||||
inkscape:label="MainOutline"
|
inkscape:label="MainOutline"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 256 KiB |
|
Before Width: | Height: | Size: 556 KiB After Width: | Height: | Size: 335 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 35 KiB |
@@ -46,7 +46,7 @@ Qt Widgets appears to be broken. For now, add `-DENABLE_QT=OFF` to your configur
|
|||||||
This is needed for some dependencies that call cc directly (tz):
|
This is needed for some dependencies that call cc directly (tz):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
echo '#!/bin/sh' >cc
|
echo '#!/bin/sh -e' >cc
|
||||||
echo 'gcc $@' >>cc
|
echo 'gcc $@' >>cc
|
||||||
chmod +x cc
|
chmod +x cc
|
||||||
export PATH="$PATH:$PWD"
|
export PATH="$PATH:$PWD"
|
||||||
|
|||||||
@@ -9,3 +9,11 @@ At the moment of writing, we do not support CFW such as Atmosphere, due to:
|
|||||||
We do however, maintain HLE compatibility with the former mentioned CFW, applications that require Atmosphere to run will run fine in the emulator without any adjustments.
|
We do however, maintain HLE compatibility with the former mentioned CFW, applications that require Atmosphere to run will run fine in the emulator without any adjustments.
|
||||||
|
|
||||||
If they don't run - then that's a bug!
|
If they don't run - then that's a bug!
|
||||||
|
|
||||||
|
## Atmosphere
|
||||||
|
|
||||||
|
Fusee Galee, the bootloader and other low-level mechanisms are not emulated at the moment.
|
||||||
|
|
||||||
|
Having OFW is recommended, but may not be required (untested).
|
||||||
|
|
||||||
|
Extract the contents of Atmosphere into `sdmc`. Then to launch simply use `-hlaunch` instead (orthogonal to `-qlaunch`).
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ There are two main applications, an SDL-based app (`eden-cli`) and a Qt based ap
|
|||||||
- `-u <number>`: Select the index of the user to load as.
|
- `-u <number>`: Select the index of the user to load as.
|
||||||
- `-input-profile <name>`: Specifies input profile name to use (for player #0 only).
|
- `-input-profile <name>`: Specifies input profile name to use (for player #0 only).
|
||||||
- `-qlaunch`: Launch QLaunch.
|
- `-qlaunch`: Launch QLaunch.
|
||||||
|
- `-hlaunch`: Launch homebrew launcher `nx-hbloader`.
|
||||||
|
- Requires a copy of Atmosphere to be extracted onto `sdmc`.
|
||||||
|
- This is a shorthand for `<eden folder>/sdmc/atmosphere/hbl.nsp`.
|
||||||
- `-setup`: Launch setup applet.
|
- `-setup`: Launch setup applet.
|
||||||
|
|
||||||
## eden-cli
|
## eden-cli
|
||||||
|
|||||||
@@ -44,6 +44,10 @@ Various graphical filters exist - each of them aimed at a specific target/image
|
|||||||
- **MMPX**: Nearest-neighbour filter aimed at providing higher pixel-art quality.
|
- **MMPX**: Nearest-neighbour filter aimed at providing higher pixel-art quality.
|
||||||
- **Pros**: Offers decent pixel-art upscaling.
|
- **Pros**: Offers decent pixel-art upscaling.
|
||||||
- **Cons**: Only works for pixel-art.
|
- **Cons**: Only works for pixel-art.
|
||||||
|
- **SGSR**: Uses Snapdragon Studios Game Super Resolution to enhance image quality (similar to FSR, but for Adreno devices).
|
||||||
|
- **Pros**: Optimized for Adreno devices.
|
||||||
|
- **Cons**: Doesn't play nicely with non-Adreno devices.
|
||||||
|
- **SGSR Edge**: Almost the same pipeline as SGSR, but with improved edge detection.
|
||||||
|
|
||||||
### Anisotropy values
|
### Anisotropy values
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ EmuDeck will automatically create an *Emulators - Emulators* parser for ***Steam
|
|||||||
4. Paste the following code into the contents of the file, save and close the file.
|
4. Paste the following code into the contents of the file, save and close the file.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/sh -e
|
||||||
emuName="eden" #parameterize me
|
emuName="eden" #parameterize me
|
||||||
|
|
||||||
. "$HOME/.config/EmuDeck/backend/functions/all.sh"
|
. "$HOME/.config/EmuDeck/backend/functions/all.sh"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ The main origin repository is always at https://git.eden-emu.dev/eden-emu/eden.
|
|||||||
|
|
||||||
- https://github.com/eden-emulator/mirror
|
- https://github.com/eden-emulator/mirror
|
||||||
- https://git.crueter.xyz/mirror/eden
|
- https://git.crueter.xyz/mirror/eden
|
||||||
|
- https://codeberg.org/eden-emu/eden
|
||||||
- https://collective.taymaerz.de/eden/eden
|
- https://collective.taymaerz.de/eden/eden
|
||||||
|
|
||||||
Other mirrors obviously exist on the internet, but we can't guarantee their reliability and/or availability.
|
Other mirrors obviously exist on the internet, but we can't guarantee their reliability and/or availability.
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
# SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
# SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -10,20 +12,19 @@ paths_to_check="src/ CMakeLists.txt"
|
|||||||
|
|
||||||
# If there are whitespace errors, print the offending file names and fail.
|
# If there are whitespace errors, print the offending file names and fail.
|
||||||
if ! git diff --cached --check -- $paths_to_check ; then
|
if ! git diff --cached --check -- $paths_to_check ; then
|
||||||
cat<<END
|
cat<<EOF
|
||||||
|
|
||||||
Error: This commit would contain trailing spaces or tabs, which is against this repo's policy.
|
Error: This commit would contain trailing spaces or tabs, which is against this repo's policy.
|
||||||
Please correct those issues before committing. (Use 'git diff --check' for more details)
|
Please correct those issues before committing. (Use 'git diff --check' for more details)
|
||||||
If you know what you are doing, you can try 'git commit --no-verify' to bypass the check
|
If you know what you are doing, you can try 'git commit --no-verify' to bypass the check
|
||||||
END
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for tabs, since tab-in-indent catches only those at the beginning of a line
|
# Check for tabs, since tab-in-indent catches only those at the beginning of a line
|
||||||
if git diff --cached -- $paths_to_check | egrep '^\+.* '; then
|
if git diff --cached -- $paths_to_check | egrep '^\+.* '; then
|
||||||
cat<<END
|
cat<<EOF
|
||||||
Error: This commit would contain a tab, which is against this repo's policy.
|
Error: This commit would contain a tab, which is against this repo's policy.
|
||||||
If you know what you are doing, you can try 'git commit --no-verify' to bypass the check.
|
If you know what you are doing, you can try 'git commit --no-verify' to bypass the check.
|
||||||
END
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
#!/usr/bin/nix-shell
|
||||||
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
let
|
let
|
||||||
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05";
|
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05";
|
||||||
pkgs = import nixpkgs { config = {}; overlays = []; };
|
pkgs = import nixpkgs { config = {}; overlays = []; };
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
NativeConfig.reloadGlobalConfig()
|
||||||
|
|
||||||
InputHandler.updateControllerData()
|
InputHandler.updateControllerData()
|
||||||
val players = NativeConfig.getInputSettings(true)
|
val players = NativeConfig.getInputSettings(true)
|
||||||
var hasConfiguredControllers = false
|
var hasConfiguredControllers = false
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
|||||||
RENDERER_USE_SPEED_LIMIT("use_speed_limit"),
|
RENDERER_USE_SPEED_LIMIT("use_speed_limit"),
|
||||||
USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
|
USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
|
||||||
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
|
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
|
||||||
|
ANTIFLICKER("antiflicker"),
|
||||||
FIX_BLOOM_EFFECTS("fix_bloom_effects"),
|
FIX_BLOOM_EFFECTS("fix_bloom_effects"),
|
||||||
EMULATE_BGR565("emulate_bgr565"),
|
EMULATE_BGR565("emulate_bgr565"),
|
||||||
RESCALE_HACK("rescale_hack"),
|
RESCALE_HACK("rescale_hack"),
|
||||||
|
|||||||
@@ -750,6 +750,13 @@ abstract class SettingsItem(
|
|||||||
descriptionId = R.string.skip_cpu_inner_invalidation_description
|
descriptionId = R.string.skip_cpu_inner_invalidation_description
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
put(
|
||||||
|
SwitchSetting(
|
||||||
|
BooleanSetting.ANTIFLICKER,
|
||||||
|
titleId = R.string.antiflicker,
|
||||||
|
descriptionId = R.string.antiflicker_description
|
||||||
|
)
|
||||||
|
)
|
||||||
put(
|
put(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
BooleanSetting.FIX_BLOOM_EFFECTS,
|
BooleanSetting.FIX_BLOOM_EFFECTS,
|
||||||
|
|||||||
@@ -76,18 +76,25 @@ class SettingsFragmentPresenter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isFsrScalingFilterSelected(): Boolean {
|
private fun isSharpnessScalingFilterSelected(): Boolean {
|
||||||
val fsrFilterValue = resolveFsrScalingFilterValue() ?: return false
|
|
||||||
val needsGlobal = getNeedsGlobalForKey(IntSetting.RENDERER_SCALING_FILTER.key)
|
val needsGlobal = getNeedsGlobalForKey(IntSetting.RENDERER_SCALING_FILTER.key)
|
||||||
val selectedFilter = IntSetting.RENDERER_SCALING_FILTER.getInt(needsGlobal)
|
val selectedFilter = IntSetting.RENDERER_SCALING_FILTER.getInt(needsGlobal)
|
||||||
return selectedFilter == fsrFilterValue
|
return selectedFilter in resolveSharpnessScalingFilterValues()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveFsrScalingFilterValue(): Int? {
|
private fun resolveSharpnessScalingFilterValues(): Set<Int> {
|
||||||
val names = context.resources.getStringArray(R.array.rendererScalingFilterNames)
|
val names = context.resources.getStringArray(R.array.rendererScalingFilterNames)
|
||||||
val values = context.resources.getIntArray(R.array.rendererScalingFilterValues)
|
val values = context.resources.getIntArray(R.array.rendererScalingFilterValues)
|
||||||
val fsrIndex = names.indexOf(context.getString(R.string.scaling_filter_fsr))
|
val sharpnessFilterNames = setOf(
|
||||||
return if (fsrIndex in values.indices) values[fsrIndex] else null
|
context.getString(R.string.scaling_filter_fsr),
|
||||||
|
context.getString(R.string.scaling_filter_sgsr),
|
||||||
|
context.getString(R.string.scaling_filter_sgsr_edge),
|
||||||
|
)
|
||||||
|
return names.asSequence()
|
||||||
|
.mapIndexedNotNull { index, name ->
|
||||||
|
if (name in sharpnessFilterNames && index in values.indices) values[index] else null
|
||||||
|
}
|
||||||
|
.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allows you to show/hide abstract settings based on the paired setting key
|
// Allows you to show/hide abstract settings based on the paired setting key
|
||||||
@@ -267,7 +274,7 @@ class SettingsFragmentPresenter(
|
|||||||
add(IntSetting.RENDERER_RESOLUTION.key)
|
add(IntSetting.RENDERER_RESOLUTION.key)
|
||||||
add(IntSetting.RENDERER_VSYNC.key)
|
add(IntSetting.RENDERER_VSYNC.key)
|
||||||
add(IntSetting.RENDERER_SCALING_FILTER.key)
|
add(IntSetting.RENDERER_SCALING_FILTER.key)
|
||||||
if (isFsrScalingFilterSelected()) {
|
if (isSharpnessScalingFilterSelected()) {
|
||||||
add(IntSetting.FSR_SHARPENING_SLIDER.key)
|
add(IntSetting.FSR_SHARPENING_SLIDER.key)
|
||||||
}
|
}
|
||||||
add(IntSetting.RENDERER_ANTI_ALIASING.key)
|
add(IntSetting.RENDERER_ANTI_ALIASING.key)
|
||||||
@@ -291,6 +298,7 @@ class SettingsFragmentPresenter(
|
|||||||
|
|
||||||
add(IntSetting.FAST_GPU_TIME.key)
|
add(IntSetting.FAST_GPU_TIME.key)
|
||||||
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
|
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
|
||||||
|
add(BooleanSetting.ANTIFLICKER.key)
|
||||||
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
|
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
|
||||||
add(BooleanSetting.EMULATE_BGR565.key)
|
add(BooleanSetting.EMULATE_BGR565.key)
|
||||||
add(BooleanSetting.RESCALE_HACK.key)
|
add(BooleanSetting.RESCALE_HACK.key)
|
||||||
|
|||||||
@@ -1090,7 +1090,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
private fun addQuickSettings() {
|
private fun addQuickSettings() {
|
||||||
binding.quickSettingsSheet.apply {
|
binding.quickSettingsSheet.apply {
|
||||||
val container = binding.quickSettingsSheet.findViewById<ViewGroup>(R.id.quick_settings_container)
|
val container = binding.quickSettingsSheet.findViewById<ViewGroup>(R.id.quick_settings_container)
|
||||||
val isFsrSelected = isFsrScalingFilterSelected()
|
val isSharpnessFilterSelected = isSharpnessScalingFilterSelected()
|
||||||
|
|
||||||
container.removeAllViews()
|
container.removeAllViews()
|
||||||
|
|
||||||
@@ -1176,7 +1176,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
addQuickSettings()
|
addQuickSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFsrSelected) {
|
if (isSharpnessFilterSelected) {
|
||||||
quickSettings.addSliderSetting(
|
quickSettings.addSliderSetting(
|
||||||
R.string.fsr_sharpness,
|
R.string.fsr_sharpness,
|
||||||
container,
|
container,
|
||||||
@@ -1197,17 +1197,24 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isFsrScalingFilterSelected(): Boolean {
|
private fun isSharpnessScalingFilterSelected(): Boolean {
|
||||||
val fsrFilterValue = resolveFsrScalingFilterValue() ?: return false
|
|
||||||
val selectedFilter = IntSetting.RENDERER_SCALING_FILTER.getInt(needsGlobal = false)
|
val selectedFilter = IntSetting.RENDERER_SCALING_FILTER.getInt(needsGlobal = false)
|
||||||
return selectedFilter == fsrFilterValue
|
return selectedFilter in resolveSharpnessScalingFilterValues()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveFsrScalingFilterValue(): Int? {
|
private fun resolveSharpnessScalingFilterValues(): Set<Int> {
|
||||||
val names = resources.getStringArray(R.array.rendererScalingFilterNames)
|
val names = resources.getStringArray(R.array.rendererScalingFilterNames)
|
||||||
val values = resources.getIntArray(R.array.rendererScalingFilterValues)
|
val values = resources.getIntArray(R.array.rendererScalingFilterValues)
|
||||||
val fsrIndex = names.indexOf(getString(R.string.scaling_filter_fsr))
|
val sharpnessFilterNames = setOf(
|
||||||
return if (fsrIndex in values.indices) values[fsrIndex] else null
|
getString(R.string.scaling_filter_fsr),
|
||||||
|
getString(R.string.scaling_filter_sgsr),
|
||||||
|
getString(R.string.scaling_filter_sgsr_edge),
|
||||||
|
)
|
||||||
|
return names.asSequence()
|
||||||
|
.mapIndexedNotNull { index, name ->
|
||||||
|
if (name in sharpnessFilterNames && index in values.indices) values[index] else null
|
||||||
|
}
|
||||||
|
.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openQuickSettingsMenu() {
|
private fun openQuickSettingsMenu() {
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ AndroidConfig::AndroidConfig(const std::string& config_name, ConfigType config_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AndroidConfig::ReloadAllValues() {
|
void AndroidConfig::ReloadAllValues() {
|
||||||
|
// Ensure the INI file is current before reloading values.
|
||||||
|
SetUpIni();
|
||||||
|
|
||||||
Reload();
|
Reload();
|
||||||
ReadAndroidValues();
|
ReadAndroidValues();
|
||||||
SaveAndroidValues();
|
SaveAndroidValues();
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 67 KiB |
@@ -459,6 +459,9 @@
|
|||||||
<string name="renderer_anti_aliasing">Méthode d\'anticrénelage</string>
|
<string name="renderer_anti_aliasing">Méthode d\'anticrénelage</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="advanced">Avancé</string>
|
||||||
|
|
||||||
|
<string name="renderer_accuracy">Mode GPU</string>
|
||||||
<string name="dma_accuracy">Précision DMA</string>
|
<string name="dma_accuracy">Précision DMA</string>
|
||||||
<string name="dma_accuracy_description">Contrôle la précision du DMA. Une précision sûre peut résoudre les problèmes dans certains jeux, mais peut aussi affecter les performances dans certains cas. Si vous n\'êtes pas sûr, laissez ce paramètre sur Par défaut.</string>
|
<string name="dma_accuracy_description">Contrôle la précision du DMA. Une précision sûre peut résoudre les problèmes dans certains jeux, mais peut aussi affecter les performances dans certains cas. Si vous n\'êtes pas sûr, laissez ce paramètre sur Par défaut.</string>
|
||||||
<string name="anisotropic_filtering">Filtrage anisotropique</string>
|
<string name="anisotropic_filtering">Filtrage anisotropique</string>
|
||||||
@@ -474,15 +477,29 @@
|
|||||||
<string name="use_disk_shader_cache_description">Réduire les saccades en stockant et en chargeant localement les shaders générés</string>
|
<string name="use_disk_shader_cache_description">Réduire les saccades en stockant et en chargeant localement les shaders générés</string>
|
||||||
<string name="renderer_force_max_clock">Forcer les fréquences maximales (Adreno uniquement)</string>
|
<string name="renderer_force_max_clock">Forcer les fréquences maximales (Adreno uniquement)</string>
|
||||||
<string name="renderer_force_max_clock_description">Forcer le GPU à fonctionner à ses fréquences maximales possibles (les contraintes thermiques seront toujours appliquées).</string>
|
<string name="renderer_force_max_clock_description">Forcer le GPU à fonctionner à ses fréquences maximales possibles (les contraintes thermiques seront toujours appliquées).</string>
|
||||||
|
<string name="renderer_asynchronous_gpu_emulation">Émulation GPU asynchrone </string>
|
||||||
|
<string name="renderer_asynchronous_gpu_emulation_description">Ce contournement peut améliorer les performances en faisant tourner l\'émulation GPU de manière asynchrone au détriment de la fidélité graphique et de la stabilité (plantages plus fréquents) dus à des erreurs de cadence.</string>
|
||||||
<string name="renderer_reactive_flushing">Utiliser le vidage réactif</string>
|
<string name="renderer_reactive_flushing">Utiliser le vidage réactif</string>
|
||||||
<string name="renderer_reactive_flushing_description">Améliore la précision du rendu dans certains jeux au détriment des performances.</string>
|
<string name="renderer_reactive_flushing_description">Améliore la précision du rendu dans certains jeux au détriment des performances.</string>
|
||||||
|
<string name="enable_buffer_history">Activer l\'historique du tampon</string>
|
||||||
|
<string name="hacks">Contournements</string>
|
||||||
|
|
||||||
|
<string name="fast_gpu_time">Temps GPU rapide</string>
|
||||||
<string name="skip_cpu_inner_invalidation">Ignorer l\'invalidation interne du CPU</string>
|
<string name="skip_cpu_inner_invalidation">Ignorer l\'invalidation interne du CPU</string>
|
||||||
<string name="skip_cpu_inner_invalidation_description">Ignore certaines invalidations de cache côté CPU lors des mises à jour mémoire, réduisant l\'utilisation du CPU et améliorant ses performances. Peut causer des bugs ou plantages sur certains jeux.</string>
|
<string name="skip_cpu_inner_invalidation_description">Ignore certaines invalidations de cache côté CPU lors des mises à jour mémoire, réduisant l\'utilisation du CPU et améliorant ses performances. Peut causer des bugs ou plantages sur certains jeux.</string>
|
||||||
|
<string name="emulate_bgr565">Emuler BGR565</string>
|
||||||
<string name="renderer_asynchronous_shaders">Utiliser les shaders asynchrones</string>
|
<string name="renderer_asynchronous_shaders">Utiliser les shaders asynchrones</string>
|
||||||
<string name="renderer_asynchronous_shaders_description">Compile les shaders de manière asynchrone. Cela peut réduire les saccades mais peut aussi provoquer des problèmes graphiques.</string>
|
<string name="renderer_asynchronous_shaders_description">Compile les shaders de manière asynchrone. Cela peut réduire les saccades mais peut aussi provoquer des problèmes graphiques.</string>
|
||||||
|
<string name="gpu_unswizzle_disabled">Désactivé</string>
|
||||||
|
<string name="gpu_unswizzle_default_button">Par défaut</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="extensions">Extensions</string>
|
||||||
|
|
||||||
<string name="dyna_state">État dynamique étendu</string>
|
<string name="dyna_state">État dynamique étendu</string>
|
||||||
<string name="disabled">Désactivé</string>
|
<string name="disabled">Désactivé</string>
|
||||||
<string name="vertex_input_dynamic_state">État dynamique d\'entrée de sommet</string>
|
<string name="vertex_input_dynamic_state">État dynamique d\'entrée de sommet</string>
|
||||||
|
<string name="sample_shading_fraction">Échantillonnage de shading</string>
|
||||||
<string name="display">Affichage</string>
|
<string name="display">Affichage</string>
|
||||||
|
|
||||||
<string name="renderer_screen_layout">Orientation</string>
|
<string name="renderer_screen_layout">Orientation</string>
|
||||||
@@ -508,6 +525,21 @@
|
|||||||
<string name="flush_by_line">Vider les journaux de débogage ligne par ligne</string>
|
<string name="flush_by_line">Vider les journaux de débogage ligne par ligne</string>
|
||||||
<string name="flush_by_line_description">Vide les journaux de débogage à chaque ligne écrite, facilitant le débogage en cas de plantage ou de gel.</string>
|
<string name="flush_by_line_description">Vide les journaux de débogage à chaque ligne écrite, facilitant le débogage en cas de plantage ou de gel.</string>
|
||||||
|
|
||||||
|
<!-- GPU Logging strings -->
|
||||||
|
<string name="gpu_logging_header">Journalisation GPU</string>
|
||||||
|
<string name="gpu_logging_enabled">Activer la journalisation GPU</string>
|
||||||
|
<string name="gpu_log_level">Niveau de journalisation</string>
|
||||||
|
<string name="gpu_log_vulkan_calls">Journaliser les appels API Vulkan</string>
|
||||||
|
<string name="gpu_log_shader_dumps">Extraire les shaders</string>
|
||||||
|
<string name="gpu_log_shader_dumps_description">Sauvegarder le shader SPIR-V complié dans les fichiers</string>
|
||||||
|
<string name="gpu_log_memory_tracking">Monitorer la mémoire GPU</string>
|
||||||
|
<string name="gpu_log_memory_tracking_description">Monitorer les allocations et désallocations de la mémoire GPU</string>
|
||||||
|
<string name="gpu_log_driver_debug">Informations de débogage du pilote</string>
|
||||||
|
<string name="gpu_log_ring_buffer_size_description">Nombre d\'appels Vulkans récents à monitorer (par défaut : 512)</string>
|
||||||
|
<string name="gpu_log_ring_buffer_size_hint">64 à 4096 entrées</string>
|
||||||
|
|
||||||
|
<string name="general">Général</string>
|
||||||
|
|
||||||
<!-- Audio settings strings -->
|
<!-- Audio settings strings -->
|
||||||
<string name="audio_output_engine">Moteur de sortie</string>
|
<string name="audio_output_engine">Moteur de sortie</string>
|
||||||
<string name="audio_volume">Volume</string>
|
<string name="audio_volume">Volume</string>
|
||||||
@@ -590,6 +622,7 @@
|
|||||||
|
|
||||||
<!-- Miscellaneous -->
|
<!-- Miscellaneous -->
|
||||||
<string name="slider_default">Par défaut</string>
|
<string name="slider_default">Par défaut</string>
|
||||||
|
<string name="default_string">Par défaut</string>
|
||||||
<string name="loading">Chargement...</string>
|
<string name="loading">Chargement...</string>
|
||||||
<string name="shutting_down">Extinction en cours...</string>
|
<string name="shutting_down">Extinction en cours...</string>
|
||||||
<string name="reset_setting_confirmation">Voulez-vous réinitialiser ce paramètre à sa valeur par défaut ?</string>
|
<string name="reset_setting_confirmation">Voulez-vous réinitialiser ce paramètre à sa valeur par défaut ?</string>
|
||||||
@@ -628,6 +661,7 @@
|
|||||||
<string name="select_gpu_driver_default">Par défaut</string>
|
<string name="select_gpu_driver_default">Par défaut</string>
|
||||||
<string name="select_gpu_driver_error">Pilote non valide sélectionné</string>
|
<string name="select_gpu_driver_error">Pilote non valide sélectionné</string>
|
||||||
<string name="driver_already_installed">Pilote déjà installé</string>
|
<string name="driver_already_installed">Pilote déjà installé</string>
|
||||||
|
<string name="installed_label">%1$s (Installé)</string>
|
||||||
<string name="system_gpu_driver">Pilote du GPU du système</string>
|
<string name="system_gpu_driver">Pilote du GPU du système</string>
|
||||||
<string name="installing_driver">Installation du pilote...</string>
|
<string name="installing_driver">Installation du pilote...</string>
|
||||||
|
|
||||||
@@ -647,6 +681,7 @@
|
|||||||
<string name="installing">Installation en cours…</string>
|
<string name="installing">Installation en cours…</string>
|
||||||
<string name="latest">Dernière</string>
|
<string name="latest">Dernière</string>
|
||||||
<string name="recommended_driver">Pilote recommandé :</string>
|
<string name="recommended_driver">Pilote recommandé :</string>
|
||||||
|
<string name="gpu_model">Modèle GPU</string>
|
||||||
<string name="unsupported_gpu">GPU non pris en charge</string>
|
<string name="unsupported_gpu">GPU non pris en charge</string>
|
||||||
<string name="unsupported_gpu_warning">Votre GPU ne prend pas en charge l\'injection de pilotes. Il n\'est pas recommandé de définir des pilotes personnalisés.</string>
|
<string name="unsupported_gpu_warning">Votre GPU ne prend pas en charge l\'injection de pilotes. Il n\'est pas recommandé de définir des pilotes personnalisés.</string>
|
||||||
|
|
||||||
@@ -656,6 +691,9 @@
|
|||||||
<string name="preferences_system_description">Mode TV, région, langue</string>
|
<string name="preferences_system_description">Mode TV, région, langue</string>
|
||||||
<string name="preferences_graphics">Vidéo</string>
|
<string name="preferences_graphics">Vidéo</string>
|
||||||
<string name="preferences_graphics_description">Niveau de précision, résolution, cache de shaders</string>
|
<string name="preferences_graphics_description">Niveau de précision, résolution, cache de shaders</string>
|
||||||
|
<string name="quick_settings">Paramètres rapides</string>
|
||||||
|
<string name="enable_quick_settings">Activer les paramètres rapides</string>
|
||||||
|
<string name="enable_quick_settings_description">Autoriser l\'accès aux paramètres rapides par le balayage de l\'écran et le bouton du menu</string>
|
||||||
<string name="preferences_audio">Audio</string>
|
<string name="preferences_audio">Audio</string>
|
||||||
<string name="preferences_audio_description">Moteur de sortie, volume</string>
|
<string name="preferences_audio_description">Moteur de sortie, volume</string>
|
||||||
<string name="preferences_controls">Contrôles</string>
|
<string name="preferences_controls">Contrôles</string>
|
||||||
@@ -663,6 +701,25 @@
|
|||||||
<string name="preferences_player">Joueur %d</string>
|
<string name="preferences_player">Joueur %d</string>
|
||||||
<string name="preferences_debug">Débogage</string>
|
<string name="preferences_debug">Débogage</string>
|
||||||
<string name="preferences_debug_description">Débogage CPU/GPU, API graphique, fastmem</string>
|
<string name="preferences_debug_description">Débogage CPU/GPU, API graphique, fastmem</string>
|
||||||
|
<string name="preferences_custom_paths">Chemins personnalisés</string>
|
||||||
|
<string name="preferences_custom_paths_description">Sauvegarder le répertoire des données</string>
|
||||||
|
|
||||||
|
<!-- Custom Paths settings -->
|
||||||
|
<string name="custom_save_directory">Sauvegarder le répertoire des données</string>
|
||||||
|
<string name="custom_save_directory_description">Définir un chemin personnalisé pour les sauvegardes</string>
|
||||||
|
<string name="reset_to_nand">Réinitialiser par défaut</string>
|
||||||
|
<string name="migrate_save_data">Migrer les données de sauvegarde</string>
|
||||||
|
<string name="save_migration_complete">Données de sauvegarde supprimées avec succès</string>
|
||||||
|
<string name="save_migration_failed">Échec de la migration des données de sauvegarde</string>
|
||||||
|
<string name="destination_has_saves">La destination contient déjà des données. Voulez-vous les écraser \?</string>
|
||||||
|
<string name="grant_permission">Accorder la permission</string>
|
||||||
|
<string name="custom_nand_directory">Dossier NAND</string>
|
||||||
|
<string name="custom_nand_directory_description">Définir un chemin personnalisé pour le stockage NAND</string>
|
||||||
|
<string name="custom_sdmc_directory">Répertoire de carte SD</string>
|
||||||
|
<string name="custom_sdmc_directory_description">Définir un chemin personnalisé pour le stockage de la carte SD virtuelle</string>
|
||||||
|
<string name="path_set">Chemin défini avec succès</string>
|
||||||
|
<string name="skip_migration">Sauter</string>
|
||||||
|
|
||||||
<!-- Game properties -->
|
<!-- Game properties -->
|
||||||
<string name="info">Info</string>
|
<string name="info">Info</string>
|
||||||
<string name="info_description">ID du programme, développeur, version</string>
|
<string name="info_description">ID du programme, développeur, version</string>
|
||||||
@@ -676,6 +733,7 @@
|
|||||||
<string name="copy_details">Copier les détails</string>
|
<string name="copy_details">Copier les détails</string>
|
||||||
<string name="add_ons">Extensions</string>
|
<string name="add_ons">Extensions</string>
|
||||||
<string name="add_ons_description">Activer les mods, mises à jour et DLC</string>
|
<string name="add_ons_description">Activer les mods, mises à jour et DLC</string>
|
||||||
|
<string name="playtime">Temps de jeu :</string>
|
||||||
<string name="reset_playtime">Réinitialiser le Temps de Jeu</string>
|
<string name="reset_playtime">Réinitialiser le Temps de Jeu</string>
|
||||||
<string name="reset_playtime_description">Réinitialiser le temps de jeu du jeu actuel à 0 seconde</string>
|
<string name="reset_playtime_description">Réinitialiser le temps de jeu du jeu actuel à 0 seconde</string>
|
||||||
<string name="reset_playtime_warning_description">Cela effacera les données de temps de jeu du jeu actuel. Êtes-vous sûr \?</string>
|
<string name="reset_playtime_warning_description">Cela effacera les données de temps de jeu du jeu actuel. Êtes-vous sûr \?</string>
|
||||||
@@ -683,6 +741,9 @@
|
|||||||
<string name="edit_playtime">Modifier le Temps de Jeu</string>
|
<string name="edit_playtime">Modifier le Temps de Jeu</string>
|
||||||
<string name="hours">Heures</string>
|
<string name="hours">Heures</string>
|
||||||
<string name="minutes">Minutes</string>
|
<string name="minutes">Minutes</string>
|
||||||
|
<string name="hours_abbr">h</string>
|
||||||
|
<string name="minutes_abbr">m</string>
|
||||||
|
<string name="seconds_abbr">s</string>
|
||||||
<string name="hours_must_be_between_0_and_9999">Les heures doivent être comprises entre 0 et 9999</string>
|
<string name="hours_must_be_between_0_and_9999">Les heures doivent être comprises entre 0 et 9999</string>
|
||||||
<string name="minutes_must_be_between_0_and_59">Les minutes doivent être comprises entre 0 et 59</string>
|
<string name="minutes_must_be_between_0_and_59">Les minutes doivent être comprises entre 0 et 59</string>
|
||||||
<string name="seconds_must_be_between_0_and_59">Les secondes doivent être comprises entre 0 et 59</string>
|
<string name="seconds_must_be_between_0_and_59">Les secondes doivent être comprises entre 0 et 59</string>
|
||||||
@@ -714,6 +775,7 @@
|
|||||||
<string name="confirm_uninstall">Confirmer la désinstallation</string>
|
<string name="confirm_uninstall">Confirmer la désinstallation</string>
|
||||||
<string name="confirm_uninstall_description">Êtes-vous sûr de vouloir désinstaller cette extension ?</string>
|
<string name="confirm_uninstall_description">Êtes-vous sûr de vouloir désinstaller cette extension ?</string>
|
||||||
<string name="verify_integrity">Vérifier l\'intégrité</string>
|
<string name="verify_integrity">Vérifier l\'intégrité</string>
|
||||||
|
<string name="verifying">Vérification...</string>
|
||||||
<string name="verify_success">La vérification de l\'intégrité a réussi !</string>
|
<string name="verify_success">La vérification de l\'intégrité a réussi !</string>
|
||||||
<string name="verify_failure">La vérification de l\'intégrité a échoué !</string>
|
<string name="verify_failure">La vérification de l\'intégrité a échoué !</string>
|
||||||
<string name="verify_failure_description">Le contenu d\'un fichier peut être corrompu</string>
|
<string name="verify_failure_description">Le contenu d\'un fichier peut être corrompu</string>
|
||||||
@@ -785,6 +847,7 @@
|
|||||||
<string name="emulation_control_opacity">Opacité</string>
|
<string name="emulation_control_opacity">Opacité</string>
|
||||||
<string name="emulation_touch_overlay_reset">Réinitialiser l\'overlay</string>
|
<string name="emulation_touch_overlay_reset">Réinitialiser l\'overlay</string>
|
||||||
<string name="emulation_touch_overlay_edit">Modifier l\'overlay</string>
|
<string name="emulation_touch_overlay_edit">Modifier l\'overlay</string>
|
||||||
|
<string name="emulation_snap_to_grid">Aimanter à la grille</string>
|
||||||
<string name="emulation_pause">Mettre en pause l\'émulation</string>
|
<string name="emulation_pause">Mettre en pause l\'émulation</string>
|
||||||
<string name="emulation_unpause">Reprendre l\'émulation</string>
|
<string name="emulation_unpause">Reprendre l\'émulation</string>
|
||||||
<string name="emulation_input_overlay">Options de l\'overlay</string>
|
<string name="emulation_input_overlay">Options de l\'overlay</string>
|
||||||
@@ -838,6 +901,32 @@
|
|||||||
<string name="clock_boost">Boost (1700MHz)</string>
|
<string name="clock_boost">Boost (1700MHz)</string>
|
||||||
<string name="clock_fast">Rapide (2000MHz)</string>
|
<string name="clock_fast">Rapide (2000MHz)</string>
|
||||||
|
|
||||||
|
<!-- GPU overclock factors -->
|
||||||
|
<string name="off">Désactivé</string>
|
||||||
|
<string name="fast_gpu_medium">Moyen (256)</string>
|
||||||
|
<string name="fast_gpu_high">Élevé (512)</string>
|
||||||
|
|
||||||
|
<!-- GPU swizzle texture size -->
|
||||||
|
<string name="gpu_texturesizeswizzle_verysmall">Très petit (16 Mo)</string>
|
||||||
|
<string name="gpu_texturesizeswizzle_small">Petit (32 Mo)</string>
|
||||||
|
<string name="gpu_texturesizeswizzle_normal">Normal (128 Mo)</string>
|
||||||
|
<string name="gpu_texturesizeswizzle_large">Large (256 Mo)</string>
|
||||||
|
<string name="gpu_texturesizeswizzle_verylarge">Très large (512 Mo)</string>
|
||||||
|
|
||||||
|
<!-- GPU swizzle streams -->
|
||||||
|
<string name="gpu_swizzle_verylow">Très faible (4 Mo)</string>
|
||||||
|
<string name="gpu_swizzle_low">Faible (8 Mo)</string>
|
||||||
|
<string name="gpu_swizzle_normal">Normal (16 Mo)</string>
|
||||||
|
<string name="gpu_swizzle_medium">Moyen (32 Mo)</string>
|
||||||
|
<string name="gpu_swizzle_high">Élevé (64 Mo)</string>
|
||||||
|
|
||||||
|
<!-- GPU swizzle chunks -->
|
||||||
|
<string name="gpu_swizzlechunk_verylow">Très faible (32)</string>
|
||||||
|
<string name="gpu_swizzlechunk_low">Faible (64)</string>
|
||||||
|
<string name="gpu_swizzlechunk_normal">Normal (128)</string>
|
||||||
|
<string name="gpu_swizzlechunk_medium">Moyen (256)</string>
|
||||||
|
<string name="gpu_swizzlechunk_high">Élevé (512)</string>
|
||||||
|
|
||||||
<!-- Temperature Units -->
|
<!-- Temperature Units -->
|
||||||
<string name="temperature_celsius">Celsius</string>
|
<string name="temperature_celsius">Celsius</string>
|
||||||
<string name="temperature_fahrenheit">Fahrenheit</string>
|
<string name="temperature_fahrenheit">Fahrenheit</string>
|
||||||
@@ -853,6 +942,11 @@
|
|||||||
|
|
||||||
<string name="renderer_none">Aucune</string>
|
<string name="renderer_none">Aucune</string>
|
||||||
|
|
||||||
|
<!-- Renderer Accuracy -->
|
||||||
|
<string name="renderer_accuracy_low">Rapide</string>
|
||||||
|
<string name="renderer_accuracy_medium">Moyen</string>
|
||||||
|
<string name="renderer_accuracy_high">Précis</string>
|
||||||
|
|
||||||
<!-- DMA Accuracy -->
|
<!-- DMA Accuracy -->
|
||||||
<string name="dma_accuracy_default">Défaut</string>
|
<string name="dma_accuracy_default">Défaut</string>
|
||||||
<string name="dma_accuracy_unsafe">Dangereux</string>
|
<string name="dma_accuracy_unsafe">Dangereux</string>
|
||||||
@@ -886,6 +980,26 @@
|
|||||||
<string name="cpu_accuracy_paranoid">Paranoïaque</string>
|
<string name="cpu_accuracy_paranoid">Paranoïaque</string>
|
||||||
<string name="cpu_accuracy_debugging">Débogage</string>
|
<string name="cpu_accuracy_debugging">Débogage</string>
|
||||||
|
|
||||||
|
<!-- Freedreno Settings -->
|
||||||
|
<string name="freedreno_settings_title">Paramètres de Freedreno</string>
|
||||||
|
<string name="gpu_driver_settings">Paramètres du pilote GPU</string>
|
||||||
|
<string name="freedreno_presets">Préréglages rapides</string>
|
||||||
|
<string name="freedreno_current_settings">Paramètres actuels</string>
|
||||||
|
<string name="freedreno_debug">Paramètres avancés</string>
|
||||||
|
<string name="freedreno_var_value">Valeur de la variable</string>
|
||||||
|
<string name="freedreno_add_variable">Ajouter la variable</string>
|
||||||
|
<string name="freedreno_clear_all">Effacer tout</string>
|
||||||
|
<string name="freedreno_saved">Configuration Freedreno sauvegardée</string>
|
||||||
|
<string name="freedreno_cleared_all">Toutes les variables Freedreno effacées</string>
|
||||||
|
<string name="freedreno_variable_added">Variable %1$s ajouté</string>
|
||||||
|
<string name="freedreno_preset_applied">Préréglage \'%1$s\' appliqué</string>
|
||||||
|
<string name="freedreno_error_empty_name">Le nom de la variable ne peut pas être vide</string>
|
||||||
|
<string name="freedreno_error_setting_variable">Échec de l\'assignation de la variable</string>
|
||||||
|
<string name="freedreno_info_title">À propos de la configuration Freedreno</string>
|
||||||
|
<string name="freedreno_per_game_title">Paramètres de Freedreno</string>
|
||||||
|
<string name="freedreno_per_game_description">Configurer les paramètres du pilote GPU pour ce jeu</string>
|
||||||
|
<string name="freedreno_per_game_saved">Configuration Freedreno sauvegardée</string>
|
||||||
|
|
||||||
<!-- Gamepad Buttons -->
|
<!-- Gamepad Buttons -->
|
||||||
<string name="gamepad_d_pad">Pavé directionnel</string>
|
<string name="gamepad_d_pad">Pavé directionnel</string>
|
||||||
<string name="gamepad_left_stick">Stick gauche</string>
|
<string name="gamepad_left_stick">Stick gauche</string>
|
||||||
@@ -902,26 +1016,37 @@
|
|||||||
<string name="theme_material_you">Material You</string>
|
<string name="theme_material_you">Material You</string>
|
||||||
<string name="app_settings">Paramètres de l’App</string>
|
<string name="app_settings">Paramètres de l’App</string>
|
||||||
<string name="theme_and_color">Thème et Couleur</string>
|
<string name="theme_and_color">Thème et Couleur</string>
|
||||||
|
<string name="fullscreen_mode">Mode plein écran</string>
|
||||||
<!-- Theme Modes -->
|
<!-- Theme Modes -->
|
||||||
<string name="change_theme_mode">Changer le mode de thème</string>
|
<string name="change_theme_mode">Changer le mode de thème</string>
|
||||||
<string name="theme_mode_follow_system">Automatique</string>
|
<string name="theme_mode_follow_system">Automatique</string>
|
||||||
<string name="theme_mode_light">Lumineux</string>
|
<string name="theme_mode_light">Lumineux</string>
|
||||||
<string name="theme_mode_dark">Sombre</string>
|
<string name="theme_mode_dark">Sombre</string>
|
||||||
|
|
||||||
|
<string name="multiplier_none">Aucun</string>
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Arrière-plan noir</string>
|
<string name="use_black_backgrounds">Arrière-plan noir</string>
|
||||||
<string name="use_black_backgrounds_description">Lorsque vous utilisez le thème sombre, appliquer un arrière-plan noir.</string>
|
<string name="use_black_backgrounds_description">Lorsque vous utilisez le thème sombre, appliquer un arrière-plan noir.</string>
|
||||||
|
|
||||||
|
<!-- Buttons -->
|
||||||
|
<string name="enable_folder_button">Dossier</string>
|
||||||
|
<string name="enable_folder_button_description">Afficher le bouton pour ajouter les dossiers de jeu</string>
|
||||||
|
<string name="enable_qlaunch_button">QLaunch</string>
|
||||||
|
<string name="enable_qlaunch_button_description">Afficher le bouton pour lancer QLaunch</string>
|
||||||
|
|
||||||
<!-- App Language -->
|
<!-- App Language -->
|
||||||
<string name="app_language">Language de l\'application</string>
|
<string name="app_language">Language de l\'application</string>
|
||||||
<string name="app_language_description">Changer la langue de l\'interface</string>
|
<string name="app_language_description">Changer la langue de l\'interface</string>
|
||||||
<string name="app_language_system">Suivre le système</string>
|
<string name="app_language_system">Suivre le système</string>
|
||||||
<!-- Static Themes -->
|
<!-- Static Themes -->
|
||||||
<string name="static_theme_color">Couleur du thème</string>
|
<string name="static_theme_color">Couleur du thème</string>
|
||||||
|
<string name="eden_theme">Eden</string>
|
||||||
<string name="violet">Violet (Par défaut)</string>
|
<string name="violet">Violet (Par défaut)</string>
|
||||||
<string name="blue">Bleu</string>
|
<string name="blue">Bleu</string>
|
||||||
<string name="cyan">Cyan</string>
|
<string name="cyan">Cyan</string>
|
||||||
<string name="red">Rouge</string>
|
<string name="red">Rouge</string>
|
||||||
|
<string name="green">Vert</string>
|
||||||
<string name="yellow">Jaune</string>
|
<string name="yellow">Jaune</string>
|
||||||
<string name="orange">Orange</string>
|
<string name="orange">Orange</string>
|
||||||
<string name="pink">Rose</string>
|
<string name="pink">Rose</string>
|
||||||
@@ -940,6 +1065,8 @@
|
|||||||
|
|
||||||
<!-- Applet Modes -->
|
<!-- Applet Modes -->
|
||||||
<string name="applets_menu">Applets</string>
|
<string name="applets_menu">Applets</string>
|
||||||
|
<string name="applets_menu_description">Modifier les frontends et paramètres des applets</string>
|
||||||
|
|
||||||
<string name="applet_hle">Frontend personnalisé</string>
|
<string name="applet_hle">Frontend personnalisé</string>
|
||||||
<string name="applet_lle">Applet réel</string>
|
<string name="applet_lle">Applet réel</string>
|
||||||
|
|
||||||
@@ -948,7 +1075,39 @@
|
|||||||
<string name="airplane_mode">Mode avion</string>
|
<string name="airplane_mode">Mode avion</string>
|
||||||
<string name="airplane_mode_description">Passe le mode avion au système d\'exploitation Switch</string>
|
<string name="airplane_mode_description">Passe le mode avion au système d\'exploitation Switch</string>
|
||||||
|
|
||||||
|
<string name="enable_overlay">Activer l\'applet d\'overlay</string>
|
||||||
|
<!-- Profile Management -->
|
||||||
|
<string name="profile_manager">Gestionnaire de profil</string>
|
||||||
|
<string name="profile_manager_description">Gérer les profils utilisateurs</string>
|
||||||
|
<string name="profile_add_user">Ajouter un utilisateur</string>
|
||||||
|
<string name="profile_new_user">Nouvel utilisateur</string>
|
||||||
|
<string name="profile_edit_user">Modifier l\'utilisateur</string>
|
||||||
|
<string name="profile_edit">Éditer</string>
|
||||||
|
<string name="profile_delete">Supprimer</string>
|
||||||
|
<string name="profile_username">Nom d\'utilisateur</string>
|
||||||
|
<string name="profile_uuid">ID de l\'utilisateur (UUID)</string>
|
||||||
|
<string name="profile_uuid_description">Il s\'agit de l\'identifiant unique de ce profil utilisateur. Il ne peut pas être changé après sa création.</string>
|
||||||
|
<string name="profile_generate">Générer</string>
|
||||||
|
<string name="profile_avatar">Avatar de l\'utilisateur</string>
|
||||||
|
<string name="profile_select_image">Sélectionner l\'image</string>
|
||||||
|
<string name="profile_firmware_avatars">Avatars du firmware</string>
|
||||||
|
<string name="profile_firmware_avatars_unavailable">Avatars du firmware non disponibles. Veuillez installer le firmware pour utiliser cette fonctionnalité.</string>
|
||||||
|
<string name="profile_revert_image">Restaurer à la valeur par défaut</string>
|
||||||
|
<string name="profile_current_user">Utilisateur actuel</string>
|
||||||
|
<string name="profile_max_users_title">Nombre d\'Utilisateurs Maximum Atteint</string>
|
||||||
|
<string name="profile_max_users_message">Vous ne pouvez pas créer plus du 8 profils utilisateurs. Veuillez supprimer un des profils existants pour en créer un nouveau.</string>
|
||||||
|
<string name="profile_delete_confirm_title">Supprimer le profil \?</string>
|
||||||
|
<string name="profile_create_failed">Échec de la création du profil utilisateur</string>
|
||||||
|
<string name="profile_update_failed">Échec de la mise à jour du profil utilisateur</string>
|
||||||
|
<string name="profile_image_load_error">Échec du chargement de l\'image : %1$s</string>
|
||||||
|
<string name="profile_image_save_error">Échec de la sauvegarde de l\'image : %1$s</string>
|
||||||
|
<string name="error">Erreur</string>
|
||||||
|
|
||||||
<!-- Licenses screen strings -->
|
<!-- Licenses screen strings -->
|
||||||
<string name="licenses">Licences</string>
|
<string name="licenses">Licences</string>
|
||||||
<string name="license_fidelityfx_fsr_description">Mise à l\'échelle de haute qualité par AMD.</string>
|
<string name="license_fidelityfx_fsr_description">Mise à l\'échelle de haute qualité par AMD.</string>
|
||||||
</resources>
|
<string name="external_content">Contenu externe</string>
|
||||||
|
<string name="add_folders">Ajouter un dossier</string>
|
||||||
|
<string name="percent">%1$d%%</string>
|
||||||
|
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<string name="notification_permission_not_granted">알림 권한이 부여되지 않았습니다!</string>
|
<string name="notification_permission_not_granted">알림 권한이 부여되지 않았습니다!</string>
|
||||||
<!-- Stats Overlay settings -->
|
<!-- Stats Overlay settings -->
|
||||||
<string name="process_ram">프로세스 RAM: %1$d MB</string>
|
<string name="process_ram">프로세스 RAM: %1$d MB</string>
|
||||||
<string name="shaders_prefix">셰이더</string>
|
<string name="shaders_prefix">구축 중</string>
|
||||||
<string name="shaders_suffix">빌드 중</string>
|
<string name="shaders_suffix">개 셰이더</string>
|
||||||
<string name="charging">(충전 중)</string>
|
<string name="charging">(충전 중)</string>
|
||||||
|
|
||||||
<string name="system_info_label">시스템:</string>
|
<string name="system_info_label">시스템:</string>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<string name="app_disclaimer">Цей застосунок запускає ігри для ігрової консолі Nintendo Switch. Він не містить ігор чи ключів.<br /><br />Перш ніж почати, укажіть розташування файлу <![CDATA[<b> prod.keys </b>]]> у пам’яті вашого пристрою.<br /><br /><![CDATA[<a href=\"https://yuzu-mirror.github.io/help/quickstart\">Дізнатися більше</a>]]></string>
|
<string name="app_disclaimer">Цей застосунок запускає ігри для ігрової консолі Nintendo Switch. Він не містить ігор чи ключів.<br /><br />Перш ніж почати, укажіть розташування файлу <![CDATA[<b> prod.keys </b>]]> у пам’яті вашого пристрою.<br /><br /><![CDATA[<a href=\"https://yuzu-mirror.github.io/help/quickstart\">Дізнатися більше</a>]]></string>
|
||||||
<string name="notice_notification_channel_name">Сповіщення та помилки</string>
|
<string name="notice_notification_channel_name">Сповіщення та помилки</string>
|
||||||
<string name="notice_notification_channel_description">Виводить сповіщення у разі виникнення проблем.</string>
|
<string name="notice_notification_channel_description">Показує сповіщення у разі виникнення проблем.</string>
|
||||||
<string name="notification_permission_not_granted">Дозвіл на сповіщення не надано!</string>
|
<string name="notification_permission_not_granted">Дозвіл на сповіщення не надано!</string>
|
||||||
<string name="app_notification_channel_description">Сповіщення емулятора Switch Eden</string>
|
<string name="app_notification_channel_description">Сповіщення емулятора Switch Eden</string>
|
||||||
<string name="app_notification_running">Eden працює</string>
|
<string name="app_notification_running">Eden працює</string>
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
|
|
||||||
<!-- NVDEC Emulation -->
|
<!-- NVDEC Emulation -->
|
||||||
<string name="nvdec_emulation">NVDEC模拟</string>
|
<string name="nvdec_emulation">NVDEC模拟</string>
|
||||||
<string name="nvdec_emulation_description">选择视频解码处理方式</string>
|
<string name="nvdec_emulation_description">播放过场与开场动画期间的视频解码处理方式(NVDEC)。</string>
|
||||||
<string name="nvdec_emulation_none">禁用</string>
|
<string name="nvdec_emulation_none">禁用</string>
|
||||||
|
|
||||||
<!-- Optimize SPIRV output -->
|
<!-- Optimize SPIRV output -->
|
||||||
@@ -181,14 +181,14 @@
|
|||||||
<string name="multiplayer_hide_full_rooms">隐藏满员房间</string>
|
<string name="multiplayer_hide_full_rooms">隐藏满员房间</string>
|
||||||
<string name="multiplayer_hide_empty_rooms">隐藏空房间</string>
|
<string name="multiplayer_hide_empty_rooms">隐藏空房间</string>
|
||||||
<string name="multiplayer_tap_refresh_to_check_again">点击刷新重试</string>
|
<string name="multiplayer_tap_refresh_to_check_again">点击刷新重试</string>
|
||||||
<string name="multiplayer_search_public_lobbies">搜索房间…</string>
|
<string name="multiplayer_search_public_lobbies">搜索游戏大厅…</string>
|
||||||
<string name="multiplayer_preferred_game_name">首选游戏</string>
|
<string name="multiplayer_preferred_game_name">首选游戏</string>
|
||||||
<string name="multiplayer_lobby_type">大厅类型</string>
|
<string name="multiplayer_lobby_type">游戏大厅类型</string>
|
||||||
<string name="multiplayer_room_name_error">长度需为3-20个字符</string>
|
<string name="multiplayer_room_name_error">长度需为3-20个字符</string>
|
||||||
<string name="multiplayer_required">必填</string>
|
<string name="multiplayer_required">必填</string>
|
||||||
<string name="multiplayer_token_required">需要Web令牌,请前往高级设置 -> 系统 -> 网络</string>
|
<string name="multiplayer_token_required">需要Web令牌,请前往高级设置 -> 系统 -> 网络</string>
|
||||||
<string name="multiplayer_ip_error">IP格式无效</string>
|
<string name="multiplayer_ip_error">IP格式无效</string>
|
||||||
<string name="multiplayer_username_error">必须为4-20个字符(仅字母数字、点号、连字符、下划线和空格)</string>
|
<string name="multiplayer_username_error">必须为4至20个字符,且仅包含字母、数字、点号、连字符、下划线和空格</string>
|
||||||
<string name="multiplayer_nickname_invalid">用户名无效,请在系统→网络中检查设置</string>
|
<string name="multiplayer_nickname_invalid">用户名无效,请在系统→网络中检查设置</string>
|
||||||
<string name="multiplayer_token_error">必须为48个字符,且仅包含小写字母a-z</string>
|
<string name="multiplayer_token_error">必须为48个字符,且仅包含小写字母a-z</string>
|
||||||
<string name="multiplayer_port_error">端口需为1-65535</string>
|
<string name="multiplayer_port_error">端口需为1-65535</string>
|
||||||
@@ -437,15 +437,15 @@
|
|||||||
<string name="custom_cpu_ticks_description">设置自定义的CPU时钟值。更高的值可能提高性能,但也可能导致游戏卡顿。建议范围为77-21000。</string>
|
<string name="custom_cpu_ticks_description">设置自定义的CPU时钟值。更高的值可能提高性能,但也可能导致游戏卡顿。建议范围为77-21000。</string>
|
||||||
<string name="cpu_ticks">时钟</string>
|
<string name="cpu_ticks">时钟</string>
|
||||||
<string name="memory_layout">内存布局</string>
|
<string name="memory_layout">内存布局</string>
|
||||||
<string name="memory_layout_description">(实验性) 更改模拟内存布局。此设置不会提高性能,但可能有助于通过模组使用高分辨率的游戏。不要在 RAM 为 8GB 或更少的手机上使用。</string>
|
<string name="memory_layout_description">(实验性) 更改模拟内存布局。此项设置并不会提升性能,但可能有助于游戏通过 mods 来利用高分辨率。请不要在内存不大于 8GB 的手机上使用。仅适用于 Dynamic(JIT)后端。</string>
|
||||||
|
|
||||||
<string name="generate">生成</string>
|
<string name="generate">生成</string>
|
||||||
|
|
||||||
<!-- Network settings strings -->
|
<!-- Network settings strings -->
|
||||||
<string name="web_token">网络令牌</string>
|
<string name="web_token">网络令牌</string>
|
||||||
<string name="web_token_description">用于创建公共房间的网络令牌。它是一个48个字符的字符串,仅包含小写字母a-z。</string>
|
<string name="web_token_description">用于创建公共游戏大厅的 web token。这是一个仅包含小写字母 a-z 的 48 位字符串。</string>
|
||||||
<string name="web_username">网络用户名</string>
|
<string name="web_username">网络用户名</string>
|
||||||
<string name="web_username_description">多人游戏房间中显示的用户名。必须为4-20个字符(仅字母数字、连字符、点号、下划线和空格)。</string>
|
<string name="web_username_description">在多人游戏大厅中显示的用户名。用户名必须为4至20个字符,且仅可包含字母、数字、连字符、点号、下划线和空格。</string>
|
||||||
<string name="network">网络</string>
|
<string name="network">网络</string>
|
||||||
|
|
||||||
<!-- Graphics settings strings -->
|
<!-- Graphics settings strings -->
|
||||||
@@ -453,7 +453,7 @@
|
|||||||
<string name="renderer_vsync">垂直同步模式</string>
|
<string name="renderer_vsync">垂直同步模式</string>
|
||||||
<string name="renderer_scaling_filter">窗口滤镜</string>
|
<string name="renderer_scaling_filter">窗口滤镜</string>
|
||||||
<string name="fsr_sharpness">FSR 锐化度</string>
|
<string name="fsr_sharpness">FSR 锐化度</string>
|
||||||
<string name="fsr_sharpness_description">指定使用 FSR 时图像的锐化程度</string>
|
<string name="fsr_sharpness_description">确定使用 FSR 的动态对比度功能时的图像锐化程度</string>
|
||||||
<string name="renderer_anti_aliasing">抗锯齿方式</string>
|
<string name="renderer_anti_aliasing">抗锯齿方式</string>
|
||||||
|
|
||||||
|
|
||||||
@@ -496,7 +496,7 @@
|
|||||||
<string name="fix_bloom_effects">修复 Bloom 效果</string>
|
<string name="fix_bloom_effects">修复 Bloom 效果</string>
|
||||||
<string name="fix_bloom_effects_description">减少《塞尔达传说:智慧的再现》(Adreno A6XX - A7XX/ Turnip)中的 bloom 模糊,并移除《Burnout》中的 bloom 效果。警告:可能会导致在其他游戏中出现图形异常。</string>
|
<string name="fix_bloom_effects_description">减少《塞尔达传说:智慧的再现》(Adreno A6XX - A7XX/ Turnip)中的 bloom 模糊,并移除《Burnout》中的 bloom 效果。警告:可能会导致在其他游戏中出现图形异常。</string>
|
||||||
<string name="emulate_bgr565">模拟 BGR565</string>
|
<string name="emulate_bgr565">模拟 BGR565</string>
|
||||||
<string name="emulate_bgr565_description">修复了游戏中的颜色反转以及出现的异常画面瑕疵或奇怪阴影问题</string>
|
<string name="emulate_bgr565_description">修复游戏中的颜色反转或是异常的画面瑕疵或阴影问题</string>
|
||||||
<string name="rescale_hack">启用旧版缩放处理</string>
|
<string name="rescale_hack">启用旧版缩放处理</string>
|
||||||
<string name="rescale_hack_description">启用通过使用快速缩放路径,来为游戏提供缩放配置处理的传统处理方式</string>
|
<string name="rescale_hack_description">启用通过使用快速缩放路径,来为游戏提供缩放配置处理的传统处理方式</string>
|
||||||
<string name="renderer_asynchronous_shaders">使用异步着色器</string>
|
<string name="renderer_asynchronous_shaders">使用异步着色器</string>
|
||||||
@@ -508,9 +508,9 @@
|
|||||||
<string name="gpu_unswizzle_texture_size">GPU 还原最大纹理尺寸</string>
|
<string name="gpu_unswizzle_texture_size">GPU 还原最大纹理尺寸</string>
|
||||||
<string name="gpu_unswizzle_texture_size_description">设置基于 GPU 的纹理还原的最大尺寸(单位:MiB)。\n虽然 GPU 在处理中型和大型纹理时速度更快,但对于非常小的纹理,CPU 的效率可能更高。\n调整此设置,以便在 GPU 加速和 CPU 开销之间找到最佳平衡点。</string>
|
<string name="gpu_unswizzle_texture_size_description">设置基于 GPU 的纹理还原的最大尺寸(单位:MiB)。\n虽然 GPU 在处理中型和大型纹理时速度更快,但对于非常小的纹理,CPU 的效率可能更高。\n调整此设置,以便在 GPU 加速和 CPU 开销之间找到最佳平衡点。</string>
|
||||||
<string name="gpu_unswizzle_stream_size">GPU 还原流大小</string>
|
<string name="gpu_unswizzle_stream_size">GPU 还原流大小</string>
|
||||||
<string name="gpu_unswizzle_stream_size_description">设置每帧还原大型纹理的数据限制。较高的数值可以加快纹理加载速度,但代价是增加帧延迟(影响响应速度/平滑度);较低的数值可以减少 GPU 开销,但可能会导致明显的纹理突然出现(Pop-in)现象。</string>
|
<string name="gpu_unswizzle_stream_size_description">设置用于 unswizzling 大型纹理时的每帧数据限制。较高的数值可以加快纹理的加载速度,但会增加帧延迟。而较低的数值可以降低 GPU 的开销,但可能会导致可见的纹理 闪现。</string>
|
||||||
<string name="gpu_unswizzle_chunk_size">GPU 还原块大小</string>
|
<string name="gpu_unswizzle_chunk_size">GPU 还原块大小</string>
|
||||||
<string name="gpu_unswizzle_chunk_size_description">定义了 3D 纹理在单个批次(Batch)中处理的深度切片(Depth Slices)数量。增加此数值可以提升强力 GPU 的吞吐效率,但在性能较弱的硬件上可能会引起卡顿或驱动程序超时(Driver Timeouts)。</string>
|
<string name="gpu_unswizzle_chunk_size_description">定义了 3D 纹理每批次处理的深度切片数量。增加此数值可在高性能 GPU 上提升吞吐效率,但在性能较弱的硬件上可能会导致卡顿或驱动超时。</string>
|
||||||
<string name="gpu_unswizzle_default_button">默认</string>
|
<string name="gpu_unswizzle_default_button">默认</string>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -240,6 +240,8 @@
|
|||||||
<item>@string/scaling_filter_bspline</item>
|
<item>@string/scaling_filter_bspline</item>
|
||||||
<item>@string/scaling_filter_mitchell</item>
|
<item>@string/scaling_filter_mitchell</item>
|
||||||
<item>@string/scaling_filter_spline1</item>
|
<item>@string/scaling_filter_spline1</item>
|
||||||
|
<item>@string/scaling_filter_sgsr</item>
|
||||||
|
<item>@string/scaling_filter_sgsr_edge</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<integer-array name="rendererScalingFilterValues">
|
<integer-array name="rendererScalingFilterValues">
|
||||||
@@ -256,6 +258,8 @@
|
|||||||
<item>10</item>
|
<item>10</item>
|
||||||
<item>11</item>
|
<item>11</item>
|
||||||
<item>12</item>
|
<item>12</item>
|
||||||
|
<item>13</item>
|
||||||
|
<item>14</item>
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="rendererAntiAliasingNames">
|
<string-array name="rendererAntiAliasingNames">
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?><resources><color name='ic_launcher_background'>#ffd700</color></resources>
|
<?xml version='1.0' encoding='utf-8'?><resources><color name='ic_launcher_background'>#1F143C</color></resources>
|
||||||
|
|||||||
@@ -468,8 +468,8 @@
|
|||||||
<string name="renderer_resolution">Resolution (Handheld/Docked)</string>
|
<string name="renderer_resolution">Resolution (Handheld/Docked)</string>
|
||||||
<string name="renderer_vsync">VSync mode</string>
|
<string name="renderer_vsync">VSync mode</string>
|
||||||
<string name="renderer_scaling_filter">Window adapting filter</string>
|
<string name="renderer_scaling_filter">Window adapting filter</string>
|
||||||
<string name="fsr_sharpness">FSR sharpness</string>
|
<string name="fsr_sharpness">FSR/SGSR sharpness</string>
|
||||||
<string name="fsr_sharpness_description">Determines how sharpened the image will look while using FSR\'s dynamic contrast</string>
|
<string name="fsr_sharpness_description">Determines how sharpened the image will look while using FSR or SGSR filters</string>
|
||||||
<string name="renderer_anti_aliasing">Anti-aliasing method</string>
|
<string name="renderer_anti_aliasing">Anti-aliasing method</string>
|
||||||
|
|
||||||
|
|
||||||
@@ -509,6 +509,8 @@
|
|||||||
<string name="fast_gpu_time_description">Forces most games to run at their highest native resolution. Use 256 for maximal performance and 512 for maximal graphics fidelity.</string>
|
<string name="fast_gpu_time_description">Forces most games to run at their highest native resolution. Use 256 for maximal performance and 512 for maximal graphics fidelity.</string>
|
||||||
<string name="skip_cpu_inner_invalidation">Skip CPU Inner Invalidation</string>
|
<string name="skip_cpu_inner_invalidation">Skip CPU Inner Invalidation</string>
|
||||||
<string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string>
|
<string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string>
|
||||||
|
<string name="antiflicker">Anti-Flicker</string>
|
||||||
|
<string name="antiflicker_description">Forces GPU fence callbacks to wait for submitted GPU work. Use with Fast GPU mode, to avoid flicker with lower performance impact.</string>
|
||||||
<string name="fix_bloom_effects">Fix Bloom Effects</string>
|
<string name="fix_bloom_effects">Fix Bloom Effects</string>
|
||||||
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno A6XX - A7XX/ Turnip), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
|
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno A6XX - A7XX/ Turnip), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
|
||||||
<string name="emulate_bgr565">Emulate BGR565</string>
|
<string name="emulate_bgr565">Emulate BGR565</string>
|
||||||
@@ -1078,6 +1080,8 @@
|
|||||||
<string name="scaling_filter_bspline" translatable="false">B-Spline</string>
|
<string name="scaling_filter_bspline" translatable="false">B-Spline</string>
|
||||||
<string name="scaling_filter_mitchell" translatable="false">Mitchell</string>
|
<string name="scaling_filter_mitchell" translatable="false">Mitchell</string>
|
||||||
<string name="scaling_filter_mmpx" translatable="false">MMPX</string>
|
<string name="scaling_filter_mmpx" translatable="false">MMPX</string>
|
||||||
|
<string name="scaling_filter_sgsr" translatable="false">Snapdragon GSR</string>
|
||||||
|
<string name="scaling_filter_sgsr_edge" translatable="false">Snapdragon GSR EdgeDir</string>
|
||||||
|
|
||||||
<!-- Anti-Aliasing -->
|
<!-- Anti-Aliasing -->
|
||||||
<string name="anti_aliasing_none">None</string>
|
<string name="anti_aliasing_none">None</string>
|
||||||
|
|||||||
@@ -29,8 +29,96 @@ void AudioRenderer::Start() {
|
|||||||
CreateSinkStreams();
|
CreateSinkStreams();
|
||||||
|
|
||||||
mailbox.Initialize(AppMailboxId::AudioRenderer);
|
mailbox.Initialize(AppMailboxId::AudioRenderer);
|
||||||
|
// Main AudioRenderer thread, responsible for processing the command lists.
|
||||||
|
main_thread = std::jthread([this](std::stop_token stop_token) {
|
||||||
|
Common::SetCurrentThreadName("DSP_AudioRenderer_Main");
|
||||||
|
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
|
||||||
|
|
||||||
main_thread = std::jthread([this](std::stop_token stop_token) { Main(stop_token); });
|
// TODO: Create buffer map/unmap thread + mailbox
|
||||||
|
// TODO: Create gMix devices, initialize them here
|
||||||
|
|
||||||
|
if (mailbox.Receive(Direction::DSP) != Message::InitializeOK) {
|
||||||
|
LOG_ERROR(Service_Audio, "ADSP Audio Renderer -- Failed to receive initialize message from host!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mailbox.Send(Direction::Host, Message::InitializeOK);
|
||||||
|
|
||||||
|
// 0.12 seconds (2,304,000 / 19,200,000)
|
||||||
|
constexpr u64 max_process_time{2'304'000ULL};
|
||||||
|
while (!stop_token.stop_requested()) {
|
||||||
|
auto msg{mailbox.Receive(Direction::DSP)};
|
||||||
|
switch (msg) {
|
||||||
|
case Message::Shutdown:
|
||||||
|
mailbox.Send(Direction::Host, Message::Shutdown);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Message::Render: {
|
||||||
|
if (system.IsShuttingDown()) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
mailbox.Send(Direction::Host, Message::RenderResponse);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::array<bool, MaxRendererSessions> buffers_reset{};
|
||||||
|
std::array<u64, MaxRendererSessions> render_times_taken{};
|
||||||
|
const auto start_time{system.CoreTiming().GetGlobalTimeUs().count()};
|
||||||
|
|
||||||
|
for (u32 index = 0; index < MaxRendererSessions; index++) {
|
||||||
|
auto& command_buffer{command_buffers[index]};
|
||||||
|
auto& command_list_processor{command_list_processors[index]};
|
||||||
|
|
||||||
|
// Check this buffer is valid, as it may not be used.
|
||||||
|
if (command_buffer.buffer != 0) {
|
||||||
|
// If there are no remaining commands (from the previous list),
|
||||||
|
// this is a new command list, initialize it.
|
||||||
|
if (command_buffer.remaining_command_count == 0) {
|
||||||
|
command_list_processor.Initialize(system, *command_buffer.process,
|
||||||
|
command_buffer.buffer,
|
||||||
|
command_buffer.size, streams[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command_buffer.reset_buffer && !buffers_reset[index]) {
|
||||||
|
streams[index]->ClearQueue();
|
||||||
|
buffers_reset[index] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 max_time{max_process_time};
|
||||||
|
if (index == 1 && command_buffer.applet_resource_user_id ==
|
||||||
|
command_buffers[0].applet_resource_user_id) {
|
||||||
|
max_time = max_process_time - render_times_taken[0];
|
||||||
|
if (render_times_taken[0] > max_process_time) {
|
||||||
|
max_time = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
max_time = (std::min)(command_buffer.time_limit, max_time);
|
||||||
|
command_list_processor.SetProcessTimeMax(max_time);
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
streams[index]->WaitFreeSpace(stop_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the command list
|
||||||
|
{
|
||||||
|
render_times_taken[index] =
|
||||||
|
command_list_processor.Process(index) - start_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto end_time{system.CoreTiming().GetGlobalTimeUs().count()};
|
||||||
|
|
||||||
|
command_buffer.remaining_command_count =
|
||||||
|
command_list_processor.GetRemainingCommandCount();
|
||||||
|
command_buffer.render_time_taken_us = end_time - start_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mailbox.Send(Direction::Host, Message::RenderResponse);
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
LOG_WARNING(Service_Audio, "ADSP AudioRenderer received an invalid message, msg={:02X}!", msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
mailbox.Send(Direction::DSP, Message::InitializeOK);
|
mailbox.Send(Direction::DSP, Message::InitializeOK);
|
||||||
if (mailbox.Receive(Direction::Host) != Message::InitializeOK) {
|
if (mailbox.Receive(Direction::Host) != Message::InitializeOK) {
|
||||||
@@ -129,95 +217,4 @@ void AudioRenderer::CreateSinkStreams() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioRenderer::Main(std::stop_token stop_token) {
|
|
||||||
Common::SetCurrentThreadName("DSP_AudioRenderer_Main");
|
|
||||||
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
|
|
||||||
|
|
||||||
// TODO: Create buffer map/unmap thread + mailbox
|
|
||||||
// TODO: Create gMix devices, initialize them here
|
|
||||||
|
|
||||||
if (mailbox.Receive(Direction::DSP) != Message::InitializeOK) {
|
|
||||||
LOG_ERROR(Service_Audio, "ADSP Audio Renderer -- Failed to receive initialize message from host!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mailbox.Send(Direction::Host, Message::InitializeOK);
|
|
||||||
|
|
||||||
// 0.12 seconds (2,304,000 / 19,200,000)
|
|
||||||
constexpr u64 max_process_time{2'304'000ULL};
|
|
||||||
|
|
||||||
while (!stop_token.stop_requested()) {
|
|
||||||
auto msg{mailbox.Receive(Direction::DSP)};
|
|
||||||
switch (msg) {
|
|
||||||
case Message::Shutdown:
|
|
||||||
mailbox.Send(Direction::Host, Message::Shutdown);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case Message::Render: {
|
|
||||||
if (system.IsShuttingDown()) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
|
||||||
mailbox.Send(Direction::Host, Message::RenderResponse);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::array<bool, MaxRendererSessions> buffers_reset{};
|
|
||||||
std::array<u64, MaxRendererSessions> render_times_taken{};
|
|
||||||
const auto start_time{system.CoreTiming().GetGlobalTimeUs().count()};
|
|
||||||
|
|
||||||
for (u32 index = 0; index < MaxRendererSessions; index++) {
|
|
||||||
auto& command_buffer{command_buffers[index]};
|
|
||||||
auto& command_list_processor{command_list_processors[index]};
|
|
||||||
|
|
||||||
// Check this buffer is valid, as it may not be used.
|
|
||||||
if (command_buffer.buffer != 0) {
|
|
||||||
// If there are no remaining commands (from the previous list),
|
|
||||||
// this is a new command list, initialize it.
|
|
||||||
if (command_buffer.remaining_command_count == 0) {
|
|
||||||
command_list_processor.Initialize(system, *command_buffer.process,
|
|
||||||
command_buffer.buffer,
|
|
||||||
command_buffer.size, streams[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command_buffer.reset_buffer && !buffers_reset[index]) {
|
|
||||||
streams[index]->ClearQueue();
|
|
||||||
buffers_reset[index] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 max_time{max_process_time};
|
|
||||||
if (index == 1 && command_buffer.applet_resource_user_id ==
|
|
||||||
command_buffers[0].applet_resource_user_id) {
|
|
||||||
max_time = max_process_time - render_times_taken[0];
|
|
||||||
if (render_times_taken[0] > max_process_time) {
|
|
||||||
max_time = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
max_time = (std::min)(command_buffer.time_limit, max_time);
|
|
||||||
command_list_processor.SetProcessTimeMax(max_time);
|
|
||||||
|
|
||||||
if (index == 0) {
|
|
||||||
streams[index]->WaitFreeSpace(stop_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process the command list
|
|
||||||
{
|
|
||||||
render_times_taken[index] =
|
|
||||||
command_list_processor.Process(index) - start_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto end_time{system.CoreTiming().GetGlobalTimeUs().count()};
|
|
||||||
|
|
||||||
command_buffer.remaining_command_count =
|
|
||||||
command_list_processor.GetRemainingCommandCount();
|
|
||||||
command_buffer.render_time_taken_us = end_time - start_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mailbox.Send(Direction::Host, Message::RenderResponse);
|
|
||||||
} break;
|
|
||||||
default:
|
|
||||||
LOG_WARNING(Service_Audio, "ADSP AudioRenderer received an invalid message, msg={:02X}!", msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace AudioCore::ADSP::AudioRenderer
|
} // namespace AudioCore::ADSP::AudioRenderer
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
@@ -82,11 +82,6 @@ public:
|
|||||||
u64 GetRenderingStartTick(s32 session_id) const noexcept;
|
u64 GetRenderingStartTick(s32 session_id) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
* Main AudioRenderer thread, responsible for processing the command lists.
|
|
||||||
*/
|
|
||||||
void Main(std::stop_token stop_token);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the streams which will receive the processed samples.
|
* Creates the streams which will receive the processed samples.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ bool IsValidMultiStreamStreamCounts(s32 total_stream_count, s32 stereo_stream_co
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
OpusDecoder::OpusDecoder(Core::System& system_) : system{system_} {
|
OpusDecoder::OpusDecoder(Core::System& system_) : system{system_} {
|
||||||
init_thread = std::jthread([this](std::stop_token stop_token) { Init(stop_token); });
|
init_thread = std::jthread([this](std::stop_token stop_token) {
|
||||||
|
Init(stop_token);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
OpusDecoder::~OpusDecoder() {
|
OpusDecoder::~OpusDecoder() {
|
||||||
@@ -64,206 +66,203 @@ u32 OpusDecoder::Receive(Direction dir, std::stop_token stop_token) {
|
|||||||
return mailbox.Receive(dir, stop_token);
|
return mailbox.Receive(dir, stop_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpusDecoder::Init(std::stop_token stop_token) {
|
void OpusDecoder::Init(std::stop_token rc_stop_token) {
|
||||||
Common::SetCurrentThreadName("DSP_OpusDecoder_Init");
|
Common::SetCurrentThreadName("DSP_OpusDecoder_Init");
|
||||||
|
|
||||||
if (Receive(Direction::DSP, stop_token) != Message::Start) {
|
if (Receive(Direction::DSP, rc_stop_token) != Message::Start) {
|
||||||
LOG_ERROR(Service_Audio,
|
LOG_ERROR(Service_Audio, "DSP OpusDecoder failed to receive Start message. Opus initialization failed.");
|
||||||
"DSP OpusDecoder failed to receive Start message. Opus initialization failed.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
main_thread = std::jthread([this](std::stop_token st) { Main(st); });
|
// Main OpusDecoder thread, responsible for processing the incoming Opus packets.
|
||||||
|
main_thread = std::jthread([this](std::stop_token stop_token) {
|
||||||
|
Common::SetCurrentThreadName("DSP_OpusDecoder_Main");
|
||||||
|
while (!stop_token.stop_requested()) {
|
||||||
|
auto msg = Receive(Direction::DSP, stop_token);
|
||||||
|
switch (msg) {
|
||||||
|
case Shutdown:
|
||||||
|
Send(Direction::Host, Message::ShutdownOK);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case GetWorkBufferSize: {
|
||||||
|
auto channel_count = static_cast<s32>(shared_memory->host_send_data[0]);
|
||||||
|
|
||||||
|
ASSERT(IsValidChannelCount(channel_count));
|
||||||
|
|
||||||
|
shared_memory->dsp_return_data[0] = OpusDecodeObject::GetWorkBufferSize(channel_count);
|
||||||
|
Send(Direction::Host, Message::GetWorkBufferSizeOK);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case InitializeDecodeObject: {
|
||||||
|
auto buffer = shared_memory->host_send_data[0];
|
||||||
|
auto buffer_size = shared_memory->host_send_data[1];
|
||||||
|
auto sample_rate = static_cast<s32>(shared_memory->host_send_data[2]);
|
||||||
|
auto channel_count = static_cast<s32>(shared_memory->host_send_data[3]);
|
||||||
|
|
||||||
|
ASSERT(sample_rate >= 0);
|
||||||
|
ASSERT(IsValidChannelCount(channel_count));
|
||||||
|
ASSERT(buffer_size >= OpusDecodeObject::GetWorkBufferSize(channel_count));
|
||||||
|
|
||||||
|
auto& decoder_object = OpusDecodeObject::Initialize(buffer, buffer);
|
||||||
|
shared_memory->dsp_return_data[0] =
|
||||||
|
decoder_object.InitializeDecoder(sample_rate, channel_count);
|
||||||
|
|
||||||
|
Send(Direction::Host, Message::InitializeDecodeObjectOK);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShutdownDecodeObject: {
|
||||||
|
auto buffer = shared_memory->host_send_data[0];
|
||||||
|
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
|
||||||
|
|
||||||
|
auto& decoder_object = OpusDecodeObject::Initialize(buffer, buffer);
|
||||||
|
shared_memory->dsp_return_data[0] = decoder_object.Shutdown();
|
||||||
|
|
||||||
|
Send(Direction::Host, Message::ShutdownDecodeObjectOK);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DecodeInterleaved: {
|
||||||
|
auto start_time = system.CoreTiming().GetGlobalTimeUs();
|
||||||
|
|
||||||
|
auto buffer = shared_memory->host_send_data[0];
|
||||||
|
auto input_data = shared_memory->host_send_data[1];
|
||||||
|
auto input_data_size = shared_memory->host_send_data[2];
|
||||||
|
auto output_data = shared_memory->host_send_data[3];
|
||||||
|
auto output_data_size = shared_memory->host_send_data[4];
|
||||||
|
auto final_range = static_cast<u32>(shared_memory->host_send_data[5]);
|
||||||
|
auto reset_requested = shared_memory->host_send_data[6];
|
||||||
|
|
||||||
|
u32 decoded_samples{0};
|
||||||
|
|
||||||
|
auto& decoder_object = OpusDecodeObject::Initialize(buffer, buffer);
|
||||||
|
s32 error_code{OPUS_OK};
|
||||||
|
if (reset_requested) {
|
||||||
|
error_code = decoder_object.ResetDecoder();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code == OPUS_OK) {
|
||||||
|
error_code = decoder_object.Decode(decoded_samples, output_data, output_data_size,
|
||||||
|
input_data, input_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code == OPUS_OK) {
|
||||||
|
if (final_range && decoder_object.GetFinalRange() != final_range) {
|
||||||
|
error_code = OPUS_INVALID_PACKET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto end_time = system.CoreTiming().GetGlobalTimeUs();
|
||||||
|
shared_memory->dsp_return_data[0] = error_code;
|
||||||
|
shared_memory->dsp_return_data[1] = decoded_samples;
|
||||||
|
shared_memory->dsp_return_data[2] = (end_time - start_time).count();
|
||||||
|
|
||||||
|
Send(Direction::Host, Message::DecodeInterleavedOK);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case MapMemory: {
|
||||||
|
[[maybe_unused]] auto buffer = shared_memory->host_send_data[0];
|
||||||
|
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
|
||||||
|
Send(Direction::Host, Message::MapMemoryOK);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case UnmapMemory: {
|
||||||
|
[[maybe_unused]] auto buffer = shared_memory->host_send_data[0];
|
||||||
|
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
|
||||||
|
Send(Direction::Host, Message::UnmapMemoryOK);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case GetWorkBufferSizeForMultiStream: {
|
||||||
|
auto total_stream_count = static_cast<s32>(shared_memory->host_send_data[0]);
|
||||||
|
auto stereo_stream_count = static_cast<s32>(shared_memory->host_send_data[1]);
|
||||||
|
|
||||||
|
ASSERT(IsValidMultiStreamStreamCounts(total_stream_count, stereo_stream_count));
|
||||||
|
|
||||||
|
shared_memory->dsp_return_data[0] = OpusMultiStreamDecodeObject::GetWorkBufferSize(
|
||||||
|
total_stream_count, stereo_stream_count);
|
||||||
|
Send(Direction::Host, Message::GetWorkBufferSizeForMultiStreamOK);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case InitializeMultiStreamDecodeObject: {
|
||||||
|
auto buffer = shared_memory->host_send_data[0];
|
||||||
|
auto buffer_size = shared_memory->host_send_data[1];
|
||||||
|
auto sample_rate = static_cast<s32>(shared_memory->host_send_data[2]);
|
||||||
|
auto channel_count = static_cast<s32>(shared_memory->host_send_data[3]);
|
||||||
|
auto total_stream_count = static_cast<s32>(shared_memory->host_send_data[4]);
|
||||||
|
auto stereo_stream_count = static_cast<s32>(shared_memory->host_send_data[5]);
|
||||||
|
// Nintendo seem to have a bug here, they try to use &host_send_data[6] for the channel
|
||||||
|
// mappings, but [6] is never set, and there is not enough room in the argument data for
|
||||||
|
// more than 40 channels, when 255 are possible.
|
||||||
|
// It also means the mapping values are undefined, though likely always 0,
|
||||||
|
// and the mappings given by the game are ignored. The mappings are copied to this
|
||||||
|
// dedicated buffer host side, so let's do as intended.
|
||||||
|
auto mappings = shared_memory->channel_mapping.data();
|
||||||
|
|
||||||
|
ASSERT(IsValidMultiStreamStreamCounts(total_stream_count, stereo_stream_count));
|
||||||
|
ASSERT(sample_rate >= 0);
|
||||||
|
ASSERT(buffer_size >= OpusMultiStreamDecodeObject::GetWorkBufferSize(
|
||||||
|
total_stream_count, stereo_stream_count));
|
||||||
|
|
||||||
|
auto& decoder_object = OpusMultiStreamDecodeObject::Initialize(buffer, buffer);
|
||||||
|
shared_memory->dsp_return_data[0] = decoder_object.InitializeDecoder(
|
||||||
|
sample_rate, total_stream_count, channel_count, stereo_stream_count, mappings);
|
||||||
|
|
||||||
|
Send(Direction::Host, Message::InitializeMultiStreamDecodeObjectOK);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShutdownMultiStreamDecodeObject: {
|
||||||
|
auto buffer = shared_memory->host_send_data[0];
|
||||||
|
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
|
||||||
|
|
||||||
|
auto& decoder_object = OpusMultiStreamDecodeObject::Initialize(buffer, buffer);
|
||||||
|
shared_memory->dsp_return_data[0] = decoder_object.Shutdown();
|
||||||
|
|
||||||
|
Send(Direction::Host, Message::ShutdownMultiStreamDecodeObjectOK);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DecodeInterleavedForMultiStream: {
|
||||||
|
auto start_time = system.CoreTiming().GetGlobalTimeUs();
|
||||||
|
|
||||||
|
auto buffer = shared_memory->host_send_data[0];
|
||||||
|
auto input_data = shared_memory->host_send_data[1];
|
||||||
|
auto input_data_size = shared_memory->host_send_data[2];
|
||||||
|
auto output_data = shared_memory->host_send_data[3];
|
||||||
|
auto output_data_size = shared_memory->host_send_data[4];
|
||||||
|
auto final_range = static_cast<u32>(shared_memory->host_send_data[5]);
|
||||||
|
auto reset_requested = shared_memory->host_send_data[6];
|
||||||
|
|
||||||
|
u32 decoded_samples{0};
|
||||||
|
|
||||||
|
auto& decoder_object = OpusMultiStreamDecodeObject::Initialize(buffer, buffer);
|
||||||
|
s32 error_code{OPUS_OK};
|
||||||
|
if (reset_requested) {
|
||||||
|
error_code = decoder_object.ResetDecoder();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code == OPUS_OK) {
|
||||||
|
error_code = decoder_object.Decode(decoded_samples, output_data, output_data_size,
|
||||||
|
input_data, input_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code == OPUS_OK) {
|
||||||
|
if (final_range && decoder_object.GetFinalRange() != final_range) {
|
||||||
|
error_code = OPUS_INVALID_PACKET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto end_time = system.CoreTiming().GetGlobalTimeUs();
|
||||||
|
shared_memory->dsp_return_data[0] = error_code;
|
||||||
|
shared_memory->dsp_return_data[1] = decoded_samples;
|
||||||
|
shared_memory->dsp_return_data[2] = (end_time - start_time).count();
|
||||||
|
|
||||||
|
Send(Direction::Host, Message::DecodeInterleavedForMultiStreamOK);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_ERROR(Service_Audio, "Invalid OpusDecoder command {}", msg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
running = true;
|
running = true;
|
||||||
Send(Direction::Host, Message::StartOK);
|
Send(Direction::Host, Message::StartOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpusDecoder::Main(std::stop_token stop_token) {
|
|
||||||
Common::SetCurrentThreadName("DSP_OpusDecoder_Main");
|
|
||||||
|
|
||||||
while (!stop_token.stop_requested()) {
|
|
||||||
auto msg = Receive(Direction::DSP, stop_token);
|
|
||||||
switch (msg) {
|
|
||||||
case Shutdown:
|
|
||||||
Send(Direction::Host, Message::ShutdownOK);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case GetWorkBufferSize: {
|
|
||||||
auto channel_count = static_cast<s32>(shared_memory->host_send_data[0]);
|
|
||||||
|
|
||||||
ASSERT(IsValidChannelCount(channel_count));
|
|
||||||
|
|
||||||
shared_memory->dsp_return_data[0] = OpusDecodeObject::GetWorkBufferSize(channel_count);
|
|
||||||
Send(Direction::Host, Message::GetWorkBufferSizeOK);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case InitializeDecodeObject: {
|
|
||||||
auto buffer = shared_memory->host_send_data[0];
|
|
||||||
auto buffer_size = shared_memory->host_send_data[1];
|
|
||||||
auto sample_rate = static_cast<s32>(shared_memory->host_send_data[2]);
|
|
||||||
auto channel_count = static_cast<s32>(shared_memory->host_send_data[3]);
|
|
||||||
|
|
||||||
ASSERT(sample_rate >= 0);
|
|
||||||
ASSERT(IsValidChannelCount(channel_count));
|
|
||||||
ASSERT(buffer_size >= OpusDecodeObject::GetWorkBufferSize(channel_count));
|
|
||||||
|
|
||||||
auto& decoder_object = OpusDecodeObject::Initialize(buffer, buffer);
|
|
||||||
shared_memory->dsp_return_data[0] =
|
|
||||||
decoder_object.InitializeDecoder(sample_rate, channel_count);
|
|
||||||
|
|
||||||
Send(Direction::Host, Message::InitializeDecodeObjectOK);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case ShutdownDecodeObject: {
|
|
||||||
auto buffer = shared_memory->host_send_data[0];
|
|
||||||
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
|
|
||||||
|
|
||||||
auto& decoder_object = OpusDecodeObject::Initialize(buffer, buffer);
|
|
||||||
shared_memory->dsp_return_data[0] = decoder_object.Shutdown();
|
|
||||||
|
|
||||||
Send(Direction::Host, Message::ShutdownDecodeObjectOK);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DecodeInterleaved: {
|
|
||||||
auto start_time = system.CoreTiming().GetGlobalTimeUs();
|
|
||||||
|
|
||||||
auto buffer = shared_memory->host_send_data[0];
|
|
||||||
auto input_data = shared_memory->host_send_data[1];
|
|
||||||
auto input_data_size = shared_memory->host_send_data[2];
|
|
||||||
auto output_data = shared_memory->host_send_data[3];
|
|
||||||
auto output_data_size = shared_memory->host_send_data[4];
|
|
||||||
auto final_range = static_cast<u32>(shared_memory->host_send_data[5]);
|
|
||||||
auto reset_requested = shared_memory->host_send_data[6];
|
|
||||||
|
|
||||||
u32 decoded_samples{0};
|
|
||||||
|
|
||||||
auto& decoder_object = OpusDecodeObject::Initialize(buffer, buffer);
|
|
||||||
s32 error_code{OPUS_OK};
|
|
||||||
if (reset_requested) {
|
|
||||||
error_code = decoder_object.ResetDecoder();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_code == OPUS_OK) {
|
|
||||||
error_code = decoder_object.Decode(decoded_samples, output_data, output_data_size,
|
|
||||||
input_data, input_data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_code == OPUS_OK) {
|
|
||||||
if (final_range && decoder_object.GetFinalRange() != final_range) {
|
|
||||||
error_code = OPUS_INVALID_PACKET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto end_time = system.CoreTiming().GetGlobalTimeUs();
|
|
||||||
shared_memory->dsp_return_data[0] = error_code;
|
|
||||||
shared_memory->dsp_return_data[1] = decoded_samples;
|
|
||||||
shared_memory->dsp_return_data[2] = (end_time - start_time).count();
|
|
||||||
|
|
||||||
Send(Direction::Host, Message::DecodeInterleavedOK);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case MapMemory: {
|
|
||||||
[[maybe_unused]] auto buffer = shared_memory->host_send_data[0];
|
|
||||||
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
|
|
||||||
Send(Direction::Host, Message::MapMemoryOK);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case UnmapMemory: {
|
|
||||||
[[maybe_unused]] auto buffer = shared_memory->host_send_data[0];
|
|
||||||
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
|
|
||||||
Send(Direction::Host, Message::UnmapMemoryOK);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case GetWorkBufferSizeForMultiStream: {
|
|
||||||
auto total_stream_count = static_cast<s32>(shared_memory->host_send_data[0]);
|
|
||||||
auto stereo_stream_count = static_cast<s32>(shared_memory->host_send_data[1]);
|
|
||||||
|
|
||||||
ASSERT(IsValidMultiStreamStreamCounts(total_stream_count, stereo_stream_count));
|
|
||||||
|
|
||||||
shared_memory->dsp_return_data[0] = OpusMultiStreamDecodeObject::GetWorkBufferSize(
|
|
||||||
total_stream_count, stereo_stream_count);
|
|
||||||
Send(Direction::Host, Message::GetWorkBufferSizeForMultiStreamOK);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case InitializeMultiStreamDecodeObject: {
|
|
||||||
auto buffer = shared_memory->host_send_data[0];
|
|
||||||
auto buffer_size = shared_memory->host_send_data[1];
|
|
||||||
auto sample_rate = static_cast<s32>(shared_memory->host_send_data[2]);
|
|
||||||
auto channel_count = static_cast<s32>(shared_memory->host_send_data[3]);
|
|
||||||
auto total_stream_count = static_cast<s32>(shared_memory->host_send_data[4]);
|
|
||||||
auto stereo_stream_count = static_cast<s32>(shared_memory->host_send_data[5]);
|
|
||||||
// Nintendo seem to have a bug here, they try to use &host_send_data[6] for the channel
|
|
||||||
// mappings, but [6] is never set, and there is not enough room in the argument data for
|
|
||||||
// more than 40 channels, when 255 are possible.
|
|
||||||
// It also means the mapping values are undefined, though likely always 0,
|
|
||||||
// and the mappings given by the game are ignored. The mappings are copied to this
|
|
||||||
// dedicated buffer host side, so let's do as intended.
|
|
||||||
auto mappings = shared_memory->channel_mapping.data();
|
|
||||||
|
|
||||||
ASSERT(IsValidMultiStreamStreamCounts(total_stream_count, stereo_stream_count));
|
|
||||||
ASSERT(sample_rate >= 0);
|
|
||||||
ASSERT(buffer_size >= OpusMultiStreamDecodeObject::GetWorkBufferSize(
|
|
||||||
total_stream_count, stereo_stream_count));
|
|
||||||
|
|
||||||
auto& decoder_object = OpusMultiStreamDecodeObject::Initialize(buffer, buffer);
|
|
||||||
shared_memory->dsp_return_data[0] = decoder_object.InitializeDecoder(
|
|
||||||
sample_rate, total_stream_count, channel_count, stereo_stream_count, mappings);
|
|
||||||
|
|
||||||
Send(Direction::Host, Message::InitializeMultiStreamDecodeObjectOK);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case ShutdownMultiStreamDecodeObject: {
|
|
||||||
auto buffer = shared_memory->host_send_data[0];
|
|
||||||
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
|
|
||||||
|
|
||||||
auto& decoder_object = OpusMultiStreamDecodeObject::Initialize(buffer, buffer);
|
|
||||||
shared_memory->dsp_return_data[0] = decoder_object.Shutdown();
|
|
||||||
|
|
||||||
Send(Direction::Host, Message::ShutdownMultiStreamDecodeObjectOK);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DecodeInterleavedForMultiStream: {
|
|
||||||
auto start_time = system.CoreTiming().GetGlobalTimeUs();
|
|
||||||
|
|
||||||
auto buffer = shared_memory->host_send_data[0];
|
|
||||||
auto input_data = shared_memory->host_send_data[1];
|
|
||||||
auto input_data_size = shared_memory->host_send_data[2];
|
|
||||||
auto output_data = shared_memory->host_send_data[3];
|
|
||||||
auto output_data_size = shared_memory->host_send_data[4];
|
|
||||||
auto final_range = static_cast<u32>(shared_memory->host_send_data[5]);
|
|
||||||
auto reset_requested = shared_memory->host_send_data[6];
|
|
||||||
|
|
||||||
u32 decoded_samples{0};
|
|
||||||
|
|
||||||
auto& decoder_object = OpusMultiStreamDecodeObject::Initialize(buffer, buffer);
|
|
||||||
s32 error_code{OPUS_OK};
|
|
||||||
if (reset_requested) {
|
|
||||||
error_code = decoder_object.ResetDecoder();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_code == OPUS_OK) {
|
|
||||||
error_code = decoder_object.Decode(decoded_samples, output_data, output_data_size,
|
|
||||||
input_data, input_data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_code == OPUS_OK) {
|
|
||||||
if (final_range && decoder_object.GetFinalRange() != final_range) {
|
|
||||||
error_code = OPUS_INVALID_PACKET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto end_time = system.CoreTiming().GetGlobalTimeUs();
|
|
||||||
shared_memory->dsp_return_data[0] = error_code;
|
|
||||||
shared_memory->dsp_return_data[1] = decoded_samples;
|
|
||||||
shared_memory->dsp_return_data[2] = (end_time - start_time).count();
|
|
||||||
|
|
||||||
Send(Direction::Host, Message::DecodeInterleavedForMultiStreamOK);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
LOG_ERROR(Service_Audio, "Invalid OpusDecoder command {}", msg);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace AudioCore::ADSP::OpusDecoder
|
} // namespace AudioCore::ADSP::OpusDecoder
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 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-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -69,10 +72,6 @@ private:
|
|||||||
* Initializing thread, launched at audio_core boot to avoid blocking the main emu boot thread.
|
* Initializing thread, launched at audio_core boot to avoid blocking the main emu boot thread.
|
||||||
*/
|
*/
|
||||||
void Init(std::stop_token stop_token);
|
void Init(std::stop_token stop_token);
|
||||||
/**
|
|
||||||
* Main OpusDecoder thread, responsible for processing the incoming Opus packets.
|
|
||||||
*/
|
|
||||||
void Main(std::stop_token stop_token);
|
|
||||||
|
|
||||||
/// Core system
|
/// Core system
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 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
|
||||||
|
|
||||||
@@ -60,7 +63,7 @@ public:
|
|||||||
template <typename Func>
|
template <typename Func>
|
||||||
void ForEachItemBelow(TickType tick, Func&& func) {
|
void ForEachItemBelow(TickType tick, Func&& func) {
|
||||||
static constexpr bool RETURNS_BOOL =
|
static constexpr bool RETURNS_BOOL =
|
||||||
std::is_same_v<std::invoke_result<Func, ObjectType>, bool>;
|
std::is_same_v<std::invoke_result_t<Func, ObjectType>, bool>;
|
||||||
Item* iterator = first_item;
|
Item* iterator = first_item;
|
||||||
while (iterator) {
|
while (iterator) {
|
||||||
if (static_cast<s64>(tick) - static_cast<s64>(iterator->tick) < 0) {
|
if (static_cast<s64>(tick) - static_cast<s64>(iterator->tick) < 0) {
|
||||||
|
|||||||
@@ -435,4 +435,16 @@ void ToggleSlowMode() {
|
|||||||
SetSpeedMode(SpeedMode::Standard);
|
SetSpeedMode(SpeedMode::Standard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsOpenGL() {
|
||||||
|
const auto backend = Settings::values.renderer_backend.GetValue();
|
||||||
|
switch (backend) {
|
||||||
|
case RendererBackend::OpenGL_GLSL:
|
||||||
|
case RendererBackend::OpenGL_GLASM:
|
||||||
|
case RendererBackend::OpenGL_SPIRV:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|||||||
@@ -545,6 +545,13 @@ struct Values {
|
|||||||
Specialization::Default,
|
Specialization::Default,
|
||||||
true,
|
true,
|
||||||
true};
|
true};
|
||||||
|
SwitchableSetting<bool> antiflicker{linkage,
|
||||||
|
false,
|
||||||
|
"antiflicker",
|
||||||
|
Category::RendererHacks,
|
||||||
|
Specialization::Default,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
SwitchableSetting<bool> async_presentation{linkage,
|
SwitchableSetting<bool> async_presentation{linkage,
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
false,
|
false,
|
||||||
@@ -863,6 +870,8 @@ bool IsFastmemEnabled();
|
|||||||
void SetNceEnabled(bool is_64bit);
|
void SetNceEnabled(bool is_64bit);
|
||||||
bool IsNceEnabled();
|
bool IsNceEnabled();
|
||||||
|
|
||||||
|
bool IsOpenGL();
|
||||||
|
|
||||||
bool IsDockedMode();
|
bool IsDockedMode();
|
||||||
|
|
||||||
float Volume();
|
float Volume();
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ 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, Res5_4X, 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, Gaussian, Lanczos, ScaleForce, Fsr, Area, ZeroTangent, BSpline, Mitchell, Spline1, Mmpx, Sgsr, SgsrEdge, 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,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 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
|
||||||
|
|
||||||
@@ -28,9 +31,118 @@ enum class Type {
|
|||||||
/// Protocol values for sockets
|
/// Protocol values for sockets
|
||||||
enum class Protocol : u8 {
|
enum class Protocol : u8 {
|
||||||
Unspecified, ///< Represents 0, usable in various places
|
Unspecified, ///< Represents 0, usable in various places
|
||||||
|
IP,
|
||||||
ICMP,
|
ICMP,
|
||||||
TCP,
|
TCP,
|
||||||
UDP,
|
UDP,
|
||||||
|
IPV6,
|
||||||
|
RAW,
|
||||||
|
IGMP,
|
||||||
|
GGP,
|
||||||
|
IPV4,
|
||||||
|
ST,
|
||||||
|
EGP,
|
||||||
|
PIGP,
|
||||||
|
RCCMON,
|
||||||
|
NVPII,
|
||||||
|
PUP,
|
||||||
|
ARGUS,
|
||||||
|
EMCON,
|
||||||
|
XNET,
|
||||||
|
CHAOS,
|
||||||
|
MUX,
|
||||||
|
MEAS,
|
||||||
|
HMP,
|
||||||
|
PRM,
|
||||||
|
IDP,
|
||||||
|
TRUNK1,
|
||||||
|
TRUNK2,
|
||||||
|
LEAF1,
|
||||||
|
LEAF2,
|
||||||
|
RDP,
|
||||||
|
IRTP,
|
||||||
|
TP,
|
||||||
|
BLT,
|
||||||
|
NSP,
|
||||||
|
INP,
|
||||||
|
DCCP,
|
||||||
|
//TODO: 3PC,
|
||||||
|
IDPR,
|
||||||
|
XTP,
|
||||||
|
DDP,
|
||||||
|
CMTP,
|
||||||
|
TPXX,
|
||||||
|
IL,
|
||||||
|
SDRP,
|
||||||
|
ROUTING,
|
||||||
|
FRAGMENT,
|
||||||
|
IDRP,
|
||||||
|
RSVP,
|
||||||
|
GRE,
|
||||||
|
MHRP,
|
||||||
|
BHA,
|
||||||
|
ESP,
|
||||||
|
AH,
|
||||||
|
INLSP,
|
||||||
|
SWIPE,
|
||||||
|
NHRP,
|
||||||
|
MOBILE,
|
||||||
|
TLSP,
|
||||||
|
SKIP,
|
||||||
|
ICMPV6,
|
||||||
|
NONE,
|
||||||
|
DSTOPTS,
|
||||||
|
AHIP,
|
||||||
|
CFTP,
|
||||||
|
HELLO,
|
||||||
|
SATEXPAK,
|
||||||
|
KRYPTOLAN,
|
||||||
|
RVD,
|
||||||
|
IPPC,
|
||||||
|
ADFS,
|
||||||
|
SATMON,
|
||||||
|
VISA,
|
||||||
|
IPCV,
|
||||||
|
CPNX,
|
||||||
|
CPHB,
|
||||||
|
WSN,
|
||||||
|
PVP,
|
||||||
|
BRSATMON,
|
||||||
|
ND,
|
||||||
|
WBMON,
|
||||||
|
WBEXPAK,
|
||||||
|
EON,
|
||||||
|
VMTP,
|
||||||
|
SVMTP,
|
||||||
|
VINES,
|
||||||
|
TTP,
|
||||||
|
IGP,
|
||||||
|
DGP,
|
||||||
|
TCF,
|
||||||
|
IGRP,
|
||||||
|
OSPFIGP,
|
||||||
|
SRPC,
|
||||||
|
LARP,
|
||||||
|
MTP,
|
||||||
|
AX25,
|
||||||
|
IPEIP,
|
||||||
|
MICP,
|
||||||
|
SCCSP,
|
||||||
|
ETHERIP,
|
||||||
|
ENCAP,
|
||||||
|
APES,
|
||||||
|
GMTP,
|
||||||
|
IPCOMP,
|
||||||
|
SCTP,
|
||||||
|
MH,
|
||||||
|
UDPLITE,
|
||||||
|
HIP,
|
||||||
|
SHIM6,
|
||||||
|
PIM,
|
||||||
|
CARP,
|
||||||
|
PGM,
|
||||||
|
MPLS,
|
||||||
|
PFSYNC
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Shutdown mode
|
/// Shutdown mode
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ public:
|
|||||||
VirtualBuffer& operator=(const VirtualBuffer&) = delete;
|
VirtualBuffer& operator=(const VirtualBuffer&) = delete;
|
||||||
|
|
||||||
VirtualBuffer(VirtualBuffer&& other) noexcept
|
VirtualBuffer(VirtualBuffer&& other) noexcept
|
||||||
: alloc_size{std::exchange(other.alloc_size, 0)}, base_ptr{std::exchange(other.base_ptr), nullptr}
|
: alloc_size{std::exchange(other.alloc_size, 0)}
|
||||||
|
, base_ptr{std::exchange(other.base_ptr, nullptr)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
VirtualBuffer& operator=(VirtualBuffer&& other) noexcept {
|
VirtualBuffer& operator=(VirtualBuffer&& other) noexcept {
|
||||||
|
|||||||
@@ -106,8 +106,6 @@ static CPUCaps Detect() {
|
|||||||
// Detect family and other miscellaneous features
|
// Detect family and other miscellaneous features
|
||||||
if (max_std_fn >= 1) {
|
if (max_std_fn >= 1) {
|
||||||
__cpuid(cpu_id, 0x00000001);
|
__cpuid(cpu_id, 0x00000001);
|
||||||
caps.sse = Common::Bit<25>(cpu_id[3]);
|
|
||||||
caps.sse2 = Common::Bit<26>(cpu_id[3]);
|
|
||||||
caps.sse3 = Common::Bit<0>(cpu_id[2]);
|
caps.sse3 = Common::Bit<0>(cpu_id[2]);
|
||||||
caps.pclmulqdq = Common::Bit<1>(cpu_id[2]);
|
caps.pclmulqdq = Common::Bit<1>(cpu_id[2]);
|
||||||
caps.ssse3 = Common::Bit<9>(cpu_id[2]);
|
caps.ssse3 = Common::Bit<9>(cpu_id[2]);
|
||||||
@@ -150,9 +148,6 @@ static CPUCaps Detect() {
|
|||||||
|
|
||||||
caps.waitpkg = Common::Bit<5>(cpu_id[2]);
|
caps.waitpkg = Common::Bit<5>(cpu_id[2]);
|
||||||
caps.gfni = Common::Bit<8>(cpu_id[2]);
|
caps.gfni = Common::Bit<8>(cpu_id[2]);
|
||||||
|
|
||||||
__cpuidex(cpu_id, 0x00000007, 0x00000001);
|
|
||||||
caps.avx_vnni = caps.avx && Common::Bit<4>(cpu_id[0]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +165,6 @@ static CPUCaps Detect() {
|
|||||||
// Check for more features
|
// Check for more features
|
||||||
__cpuid(cpu_id, 0x80000001);
|
__cpuid(cpu_id, 0x80000001);
|
||||||
caps.lzcnt = Common::Bit<5>(cpu_id[2]);
|
caps.lzcnt = Common::Bit<5>(cpu_id[2]);
|
||||||
caps.fma4 = Common::Bit<16>(cpu_id[2]);
|
|
||||||
caps.monitorx = Common::Bit<29>(cpu_id[2]);
|
caps.monitorx = Common::Bit<29>(cpu_id[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 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-FileCopyrightText: Copyright 2013 Dolphin Emulator Project / 2015 Citra Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2013 Dolphin Emulator Project / 2015 Citra Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
@@ -36,15 +39,12 @@ struct CPUCaps {
|
|||||||
u32 crystal_frequency;
|
u32 crystal_frequency;
|
||||||
u64 tsc_frequency; // Derived from the above three values
|
u64 tsc_frequency; // Derived from the above three values
|
||||||
|
|
||||||
bool sse : 1;
|
|
||||||
bool sse2 : 1;
|
|
||||||
bool sse3 : 1;
|
bool sse3 : 1;
|
||||||
bool ssse3 : 1;
|
bool ssse3 : 1;
|
||||||
bool sse4_1 : 1;
|
bool sse4_1 : 1;
|
||||||
bool sse4_2 : 1;
|
bool sse4_2 : 1;
|
||||||
|
|
||||||
bool avx : 1;
|
bool avx : 1;
|
||||||
bool avx_vnni : 1;
|
|
||||||
bool avx2 : 1;
|
bool avx2 : 1;
|
||||||
bool avx512f : 1;
|
bool avx512f : 1;
|
||||||
bool avx512dq : 1;
|
bool avx512dq : 1;
|
||||||
@@ -59,7 +59,6 @@ struct CPUCaps {
|
|||||||
bool bmi2 : 1;
|
bool bmi2 : 1;
|
||||||
bool f16c : 1;
|
bool f16c : 1;
|
||||||
bool fma : 1;
|
bool fma : 1;
|
||||||
bool fma4 : 1;
|
|
||||||
bool gfni : 1;
|
bool gfni : 1;
|
||||||
bool invariant_tsc : 1;
|
bool invariant_tsc : 1;
|
||||||
bool lzcnt : 1;
|
bool lzcnt : 1;
|
||||||
|
|||||||
@@ -1089,6 +1089,8 @@ add_library(core STATIC
|
|||||||
hle/service/ssl/ssl.h
|
hle/service/ssl/ssl.h
|
||||||
hle/service/ssl/ssl_backend.h
|
hle/service/ssl/ssl_backend.h
|
||||||
hle/service/ssl/ssl_types.h
|
hle/service/ssl/ssl_types.h
|
||||||
|
hle/service/ulsf/ulsf.cpp
|
||||||
|
hle/service/ulsf/ulsf.h
|
||||||
hle/service/usb/usb.cpp
|
hle/service/usb/usb.cpp
|
||||||
hle/service/usb/usb.h
|
hle/service/usb/usb.h
|
||||||
hle/service/vi/application_display_service.cpp
|
hle/service/vi/application_display_service.cpp
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ void ArmNce::SignalInterrupt(Kernel::KThread* thread) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::size_t CACHE_PAGE_SIZE = 4096;
|
[[maybe_unused]] const std::size_t CACHE_PAGE_SIZE = 4096;
|
||||||
|
|
||||||
void ArmNce::ClearInstructionCache() {
|
void ArmNce::ClearInstructionCache() {
|
||||||
#ifdef __aarch64__
|
#ifdef __aarch64__
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ namespace Core {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Prefetch tuning parameters
|
// Prefetch tuning parameters
|
||||||
constexpr size_t CACHE_LINE_SIZE = 64;
|
[[maybe_unused]] constexpr size_t CACHE_LINE_SIZE = 64;
|
||||||
constexpr size_t PREFETCH_STRIDE = 128; // 2 cache lines ahead
|
[[maybe_unused]] constexpr size_t PREFETCH_STRIDE = 128; // 2 cache lines ahead
|
||||||
constexpr size_t SIMD_PREFETCH_THRESHOLD = 32; // Bytes
|
[[maybe_unused]] constexpr size_t SIMD_PREFETCH_THRESHOLD = 32; // Bytes
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
template <u32 BitSize>
|
template <u32 BitSize>
|
||||||
|
|||||||
@@ -14,17 +14,12 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/range_mutex.h"
|
#include "common/range_mutex.h"
|
||||||
#include "common/scratch_buffer.h"
|
#include "common/scratch_buffer.h"
|
||||||
#include "common/virtual_buffer.h"
|
#include "common/virtual_buffer.h"
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
constexpr size_t DEVICE_PAGEBITS = 12ULL;
|
constexpr size_t DEVICE_PAGEBITS = 12ULL;
|
||||||
@@ -50,74 +45,6 @@ class DeviceMemoryManager {
|
|||||||
using DeviceMethods = typename Traits::DeviceMethods;
|
using DeviceMethods = typename Traits::DeviceMethods;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class MirrorMapping {
|
|
||||||
public:
|
|
||||||
MirrorMapping() = default;
|
|
||||||
MirrorMapping(u8* mapped_base_, size_t mapped_size_, size_t data_offset_)
|
|
||||||
: mapped_base{mapped_base_}, mapped_size{mapped_size_}, data_offset{data_offset_} {}
|
|
||||||
|
|
||||||
MirrorMapping(const MirrorMapping&) = delete;
|
|
||||||
MirrorMapping& operator=(const MirrorMapping&) = delete;
|
|
||||||
|
|
||||||
MirrorMapping(MirrorMapping&& other) noexcept {
|
|
||||||
MoveFrom(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
MirrorMapping& operator=(MirrorMapping&& other) noexcept {
|
|
||||||
if (this != &other) {
|
|
||||||
Release();
|
|
||||||
MoveFrom(other);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~MirrorMapping() {
|
|
||||||
Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool IsValid() const noexcept {
|
|
||||||
return mapped_base != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] explicit operator bool() const noexcept {
|
|
||||||
return IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] u8* Data() noexcept {
|
|
||||||
return mapped_base ? mapped_base + data_offset : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const u8* Data() const noexcept {
|
|
||||||
return mapped_base ? mapped_base + data_offset : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] size_t Size() const noexcept {
|
|
||||||
return mapped_size >= data_offset ? mapped_size - data_offset : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void MoveFrom(MirrorMapping& other) noexcept {
|
|
||||||
mapped_base = std::exchange(other.mapped_base, nullptr);
|
|
||||||
mapped_size = std::exchange(other.mapped_size, 0);
|
|
||||||
data_offset = std::exchange(other.data_offset, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Release() noexcept {
|
|
||||||
#if defined(__linux__)
|
|
||||||
if (mapped_base) {
|
|
||||||
munmap(mapped_base, mapped_size);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
mapped_base = nullptr;
|
|
||||||
mapped_size = 0;
|
|
||||||
data_offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8* mapped_base{};
|
|
||||||
size_t mapped_size{};
|
|
||||||
size_t data_offset{};
|
|
||||||
};
|
|
||||||
|
|
||||||
DeviceMemoryManager(const DeviceMemory& device_memory);
|
DeviceMemoryManager(const DeviceMemory& device_memory);
|
||||||
~DeviceMemoryManager();
|
~DeviceMemoryManager();
|
||||||
|
|
||||||
@@ -191,11 +118,6 @@ public:
|
|||||||
void WriteBlock(DAddr address, const void* src_pointer, size_t size);
|
void WriteBlock(DAddr address, const void* src_pointer, size_t size);
|
||||||
void WriteBlockUnsafe(DAddr address, const void* src_pointer, size_t size);
|
void WriteBlockUnsafe(DAddr address, const void* src_pointer, size_t size);
|
||||||
|
|
||||||
[[nodiscard]] MirrorMapping CreateMirrorMapping(DAddr address, size_t size) const;
|
|
||||||
[[nodiscard]] u64 GetMappingVersion() const noexcept {
|
|
||||||
return mapping_version.load(std::memory_order_acquire);
|
|
||||||
}
|
|
||||||
|
|
||||||
Asid RegisterProcess(Memory::Memory* memory);
|
Asid RegisterProcess(Memory::Memory* memory);
|
||||||
void UnregisterProcess(Asid id);
|
void UnregisterProcess(Asid id);
|
||||||
|
|
||||||
@@ -314,7 +236,6 @@ private:
|
|||||||
std::unique_ptr<CachedPages> cached_pages;
|
std::unique_ptr<CachedPages> cached_pages;
|
||||||
Common::RangeMutex counter_guard;
|
Common::RangeMutex counter_guard;
|
||||||
std::mutex mapping_guard;
|
std::mutex mapping_guard;
|
||||||
std::atomic<u64> mapping_version{1};
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,10 +4,6 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#if defined(__linux__) && !defined(_GNU_SOURCE)
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -15,17 +11,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#ifndef MREMAP_MAYMOVE
|
|
||||||
#define MREMAP_MAYMOVE 1
|
|
||||||
#endif
|
|
||||||
#ifndef MREMAP_FIXED
|
|
||||||
#define MREMAP_FIXED 2
|
|
||||||
#endif
|
|
||||||
extern "C" void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "common/address_space.h"
|
#include "common/address_space.h"
|
||||||
#include "common/address_space.inc"
|
#include "common/address_space.inc"
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
@@ -255,7 +240,6 @@ void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size
|
|||||||
impl->multi_dev_address.Register(new_dev, start_id);
|
impl->multi_dev_address.Register(new_dev, start_id);
|
||||||
}
|
}
|
||||||
t_slot = {};
|
t_slot = {};
|
||||||
mapping_version.fetch_add(1, std::memory_order_release);
|
|
||||||
if (track) {
|
if (track) {
|
||||||
TrackContinuityImpl(address, virtual_address, size, asid);
|
TrackContinuityImpl(address, virtual_address, size, asid);
|
||||||
}
|
}
|
||||||
@@ -288,7 +272,6 @@ void DeviceMemoryManager<Traits>::Unmap(DAddr address, size_t size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
t_slot = {};
|
t_slot = {};
|
||||||
mapping_version.fetch_add(1, std::memory_order_release);
|
|
||||||
}
|
}
|
||||||
template <typename Traits>
|
template <typename Traits>
|
||||||
void DeviceMemoryManager<Traits>::TrackContinuityImpl(DAddr address, VAddr virtual_address,
|
void DeviceMemoryManager<Traits>::TrackContinuityImpl(DAddr address, VAddr virtual_address,
|
||||||
@@ -332,78 +315,6 @@ const u8* DeviceMemoryManager<Traits>::GetSpan(const DAddr src_addr, const std::
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Traits>
|
|
||||||
typename DeviceMemoryManager<Traits>::MirrorMapping DeviceMemoryManager<Traits>::CreateMirrorMapping(
|
|
||||||
DAddr address, size_t size) const {
|
|
||||||
#if !defined(__linux__)
|
|
||||||
return {};
|
|
||||||
#else
|
|
||||||
if (size == 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const DAddr aligned_address = Common::AlignDown(address, DAddr{page_size});
|
|
||||||
const size_t data_offset = static_cast<size_t>(address - aligned_address);
|
|
||||||
const size_t mapped_size = Common::AlignUp(size + data_offset, page_size);
|
|
||||||
|
|
||||||
struct Segment {
|
|
||||||
const u8* source;
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<Segment> segments;
|
|
||||||
segments.reserve(Common::DivCeil(mapped_size, page_size));
|
|
||||||
|
|
||||||
size_t remaining_size = mapped_size;
|
|
||||||
size_t page_index = aligned_address >> page_bits;
|
|
||||||
while (remaining_size > 0) {
|
|
||||||
const size_t next_pages = std::size_t(tracked_entries[page_index].continuity_tracker);
|
|
||||||
const size_t copy_amount = (std::min)(next_pages << page_bits, remaining_size);
|
|
||||||
|
|
||||||
const auto phys_addr = tracked_entries[page_index].compressed_physical_ptr;
|
|
||||||
if (phys_addr == 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto* source =
|
|
||||||
GetPointerFromRaw<u8>(PAddr(phys_addr - 1U) << Memory::YUZU_PAGEBITS);
|
|
||||||
|
|
||||||
if (!segments.empty() && segments.back().source + segments.back().size == source) {
|
|
||||||
segments.back().size += copy_amount;
|
|
||||||
} else {
|
|
||||||
segments.push_back({source, copy_amount});
|
|
||||||
}
|
|
||||||
|
|
||||||
page_index += next_pages;
|
|
||||||
remaining_size -= copy_amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* const mirror_base =
|
|
||||||
mmap(nullptr, mapped_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
||||||
if (mirror_base == MAP_FAILED) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t mirror_offset = 0;
|
|
||||||
for (const auto& segment : segments) {
|
|
||||||
void* const target = static_cast<u8*>(mirror_base) + mirror_offset;
|
|
||||||
void* const result = mremap(const_cast<u8*>(segment.source), 0, segment.size,
|
|
||||||
MREMAP_MAYMOVE | MREMAP_FIXED, target);
|
|
||||||
if (result == MAP_FAILED) {
|
|
||||||
munmap(mirror_base, mapped_size);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (mprotect(result, segment.size, PROT_READ | PROT_WRITE) != 0) {
|
|
||||||
munmap(mirror_base, mapped_size);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
mirror_offset += segment.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MirrorMapping{static_cast<u8*>(mirror_base), mapped_size, data_offset};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Traits>
|
template <typename Traits>
|
||||||
void DeviceMemoryManager<Traits>::InnerGatherDeviceAddresses(Common::ScratchBuffer<u32>& buffer,
|
void DeviceMemoryManager<Traits>::InnerGatherDeviceAddresses(Common::ScratchBuffer<u32>& buffer,
|
||||||
PAddr address) {
|
PAddr address) {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 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
|
||||||
|
|
||||||
@@ -16,6 +19,12 @@
|
|||||||
#include "core/file_sys/fs_filesystem.h"
|
#include "core/file_sys/fs_filesystem.h"
|
||||||
#include "core/file_sys/vfs/vfs_types.h"
|
#include "core/file_sys/vfs/vfs_types.h"
|
||||||
|
|
||||||
|
#undef CreateFile
|
||||||
|
#undef CopyFile
|
||||||
|
#undef MoveFile
|
||||||
|
#undef DeleteFile
|
||||||
|
#undef CreateDirectory
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
// An enumeration representing what can be at the end of a path in a VfsFilesystem
|
// An enumeration representing what can be at the end of a path in a VfsFilesystem
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ constexpr size_t SlabCountKDeviceAddressSpace = 300;
|
|||||||
constexpr size_t SlabCountKSession = 1133;
|
constexpr size_t SlabCountKSession = 1133;
|
||||||
constexpr size_t SlabCountKLightSession = 100;
|
constexpr size_t SlabCountKLightSession = 100;
|
||||||
constexpr size_t SlabCountKObjectName = 7;
|
constexpr size_t SlabCountKObjectName = 7;
|
||||||
constexpr size_t SlabCountKResourceLimit = 5;
|
// TODO(lizzie): divergence that allows ulauncher to work
|
||||||
|
constexpr size_t SlabCountKResourceLimit = 5 + 1;
|
||||||
constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES;
|
constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES;
|
||||||
constexpr size_t SlabCountKIoPool = 1;
|
constexpr size_t SlabCountKIoPool = 1;
|
||||||
constexpr size_t SlabCountKIoRegion = 6;
|
constexpr size_t SlabCountKIoRegion = 6;
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 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-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -268,7 +271,8 @@ Result KCapabilities::SetHandleTableCapability(const u32 cap) {
|
|||||||
Result KCapabilities::SetDebugFlagsCapability(const u32 cap) {
|
Result KCapabilities::SetDebugFlagsCapability(const u32 cap) {
|
||||||
// Validate.
|
// Validate.
|
||||||
const DebugFlags pack{cap};
|
const DebugFlags pack{cap};
|
||||||
R_UNLESS(pack.reserved == 0, ResultReservedUsed);
|
// TODO: Enabling this breaks compatibility with HBloader and such
|
||||||
|
//R_UNLESS(pack.reserved == 0, ResultReservedUsed);
|
||||||
|
|
||||||
DebugFlags debug_capabilities{m_debug_capabilities};
|
DebugFlags debug_capabilities{m_debug_capabilities};
|
||||||
debug_capabilities.allow_debug.Assign(pack.allow_debug);
|
debug_capabilities.allow_debug.Assign(pack.allow_debug);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
@@ -94,7 +94,9 @@ enum class AppletId : u32 {
|
|||||||
LoginShare = 0x18,
|
LoginShare = 0x18,
|
||||||
WebAuth = 0x19,
|
WebAuth = 0x19,
|
||||||
MyPage = 0x1A,
|
MyPage = 0x1A,
|
||||||
Lhub = 0x35
|
Lhub = 0x35,
|
||||||
|
// Homebrew -- uses same ProgramId as qlaunch
|
||||||
|
UlauncherUmenu = 0xF000'0000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class AppletProgramId : u64 {
|
enum class AppletProgramId : u64 {
|
||||||
|
|||||||
@@ -24,6 +24,20 @@ namespace Service::AM {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr size_t NroPathSize = 512;
|
||||||
|
constexpr size_t NroArgvSize = 2048;
|
||||||
|
constexpr size_t MenuCaptionSize = 1024;
|
||||||
|
struct UloaderTargetInput {
|
||||||
|
u32 magic;
|
||||||
|
bool target_once;
|
||||||
|
bool is_auto_game_recording;
|
||||||
|
std::array<u8, 2> unused;
|
||||||
|
std::array<char, NroPathSize> nro_path;
|
||||||
|
std::array<char, NroArgvSize> nro_argv;
|
||||||
|
std::array<char, MenuCaptionSize> menu_caption;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(UloaderTargetInput) == 3592);
|
||||||
|
|
||||||
constexpr u32 LaunchParameterAccountPreselectedUserMagic = 0xC79497CA;
|
constexpr u32 LaunchParameterAccountPreselectedUserMagic = 0xC79497CA;
|
||||||
|
|
||||||
struct LaunchParameterAccountPreselectedUser {
|
struct LaunchParameterAccountPreselectedUser {
|
||||||
@@ -121,6 +135,44 @@ void PushInShowController(Core::System& system, AppletStorageChannel& channel) {
|
|||||||
channel.Push(std::make_shared<IStorage>(system, std::move(user_args_data)));
|
channel.Push(std::make_shared<IStorage>(system, std::move(user_args_data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PushInShowUlauncherUmenu(Core::System& system, AppletStorageChannel& channel) {
|
||||||
|
typedef std::array<u64, 2> AccountUid;
|
||||||
|
const CommonArguments common_args = {
|
||||||
|
.arguments_version = CommonArgumentVersion::Version3,
|
||||||
|
.size = CommonArgumentSize::Version3,
|
||||||
|
.library_version = 2,
|
||||||
|
.theme_color = ThemeColor::BasicBlack,
|
||||||
|
.play_startup_sound = true,
|
||||||
|
.system_tick = system.CoreTiming().GetClockTicks(),
|
||||||
|
};
|
||||||
|
struct UmenuInput {
|
||||||
|
AccountUid selected_user;
|
||||||
|
UloaderTargetInput suspended_hb_target_ipt; // Set if homebrew (launched as an application) is currently suspended
|
||||||
|
u64 suspended_app_id; // Set if any normal application is suspended
|
||||||
|
std::array<char, 0x301> last_menu_fs_path; //FS_MAX_PATH
|
||||||
|
std::array<char, 0x301> last_menu_path;
|
||||||
|
u32 last_menu_index;
|
||||||
|
bool reload_theme_cache;
|
||||||
|
bool warned_about_outdated_theme;
|
||||||
|
u32 last_added_app_count;
|
||||||
|
u32 last_deleted_app_count;
|
||||||
|
u32 in_verify_app_count;
|
||||||
|
} user_args = {};
|
||||||
|
static_assert(sizeof(UmenuInput) == 5176);
|
||||||
|
|
||||||
|
auto const user = system.GetProfileManager().GetUser(0);
|
||||||
|
user_args.selected_user[0] = user->uuid[0];
|
||||||
|
user_args.selected_user[1] = user->uuid[1];
|
||||||
|
user_args.warned_about_outdated_theme = true;
|
||||||
|
|
||||||
|
std::vector<u8> common_args_data(sizeof(common_args));
|
||||||
|
std::vector<u8> user_args_data(sizeof(user_args));
|
||||||
|
std::memcpy(common_args_data.data(), std::addressof(common_args), sizeof(common_args));
|
||||||
|
std::memcpy(user_args_data.data(), std::addressof(user_args), sizeof(user_args));
|
||||||
|
channel.Push(std::make_shared<IStorage>(system, std::move(common_args_data)));
|
||||||
|
channel.Push(std::make_shared<IStorage>(system, std::move(user_args_data)));
|
||||||
|
}
|
||||||
|
|
||||||
void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) {
|
void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) {
|
||||||
const CommonArguments arguments{
|
const CommonArguments arguments{
|
||||||
.arguments_version = CommonArgumentVersion::Version3,
|
.arguments_version = CommonArgumentVersion::Version3,
|
||||||
@@ -292,8 +344,18 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
|||||||
applet->previous_program_index = params.previous_program_index;
|
applet->previous_program_index = params.previous_program_index;
|
||||||
|
|
||||||
// Push UserChannel data from previous application
|
// Push UserChannel data from previous application
|
||||||
|
// Or ulaunch initialization where we push parameters willingly!
|
||||||
if (params.launch_type == LaunchType::ApplicationInitiated) {
|
if (params.launch_type == LaunchType::ApplicationInitiated) {
|
||||||
applet->user_channel_launch_parameter.swap(m_system.GetUserChannel());
|
applet->user_channel_launch_parameter.swap(m_system.GetUserChannel());
|
||||||
|
} else if (params.launch_type == LaunchType::FrontendUlaunchInitiated) {
|
||||||
|
UloaderTargetInput target_ipt = {};
|
||||||
|
target_ipt.magic = 0x49444C55; // "ULDI"
|
||||||
|
target_ipt.nro_path = {"sdmc:/hbmenu.nro"};
|
||||||
|
target_ipt.menu_caption = {"Loaded by uLoader v1.2.4 - uLaunch's custom hbloader replacement ;)"};
|
||||||
|
std::vector<u8> v(sizeof(target_ipt));
|
||||||
|
std::memcpy(v.data(), std::addressof(target_ipt), sizeof(target_ipt));
|
||||||
|
applet->user_channel_launch_parameter.clear();
|
||||||
|
applet->user_channel_launch_parameter.push_back(std::move(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Read whether we need a preselected user from NACP?
|
// TODO: Read whether we need a preselected user from NACP?
|
||||||
@@ -335,6 +397,9 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
|||||||
case AppletId::Controller:
|
case AppletId::Controller:
|
||||||
PushInShowController(m_system, InitializeFakeCallerApplet(m_system, applet));
|
PushInShowController(m_system, InitializeFakeCallerApplet(m_system, applet));
|
||||||
break;
|
break;
|
||||||
|
case AppletId::UlauncherUmenu:
|
||||||
|
PushInShowUlauncherUmenu(m_system, InitializeFakeCallerApplet(m_system, applet));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -342,7 +407,7 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
|||||||
// Applet was started by frontend, so it is foreground.
|
// Applet was started by frontend, so it is foreground.
|
||||||
applet->lifecycle_manager.SetFocusState(FocusState::InFocus);
|
applet->lifecycle_manager.SetFocusState(FocusState::InFocus);
|
||||||
|
|
||||||
if (applet->applet_id == AppletId::QLaunch) {
|
if (applet->applet_id == AppletId::QLaunch || applet->applet_id == AppletId::UlauncherUmenu) {
|
||||||
applet->lifecycle_manager.SetFocusHandlingMode(false);
|
applet->lifecycle_manager.SetFocusHandlingMode(false);
|
||||||
applet->lifecycle_manager.SetOutOfFocusSuspendingEnabled(false);
|
applet->lifecycle_manager.SetOutOfFocusSuspendingEnabled(false);
|
||||||
m_window_system->TrackApplet(applet, false);
|
m_window_system->TrackApplet(applet, false);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
@@ -26,6 +26,9 @@ class WindowSystem;
|
|||||||
enum class LaunchType {
|
enum class LaunchType {
|
||||||
FrontendInitiated,
|
FrontendInitiated,
|
||||||
ApplicationInitiated,
|
ApplicationInitiated,
|
||||||
|
// Special masquerade for AMS + uLaunch CFW
|
||||||
|
FrontendUlaunchInitiated = 0x800,
|
||||||
|
FrontendUmenuInitiated,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FrontendAppletParameters {
|
struct FrontendAppletParameters {
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
|
|||||||
case AppletId::OverlayDisplay:
|
case AppletId::OverlayDisplay:
|
||||||
return AppletProgramId::OverlayDisplay;
|
return AppletProgramId::OverlayDisplay;
|
||||||
case AppletId::QLaunch:
|
case AppletId::QLaunch:
|
||||||
|
case AppletId::UlauncherUmenu: //reuses same id as Qlaunch
|
||||||
return AppletProgramId::QLaunch;
|
return AppletProgramId::QLaunch;
|
||||||
case AppletId::Starter:
|
case AppletId::Starter:
|
||||||
return AppletProgramId::Starter;
|
return AppletProgramId::Starter;
|
||||||
|
|||||||
@@ -8,18 +8,23 @@
|
|||||||
#include "core/file_sys/control_metadata.h"
|
#include "core/file_sys/control_metadata.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
#include "core/hle/service/am/applet_data_broker.h"
|
#include "core/hle/service/am/applet_data_broker.h"
|
||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/am/frontend/applets.h"
|
#include "core/hle/service/am/frontend/applets.h"
|
||||||
|
#include "core/hle/service/am/process_creation.h"
|
||||||
#include "core/hle/service/am/service/library_applet_self_accessor.h"
|
#include "core/hle/service/am/service/library_applet_self_accessor.h"
|
||||||
#include "core/hle/service/am/service/storage.h"
|
#include "core/hle/service/am/service/storage.h"
|
||||||
|
#include "core/hle/service/am/window_system.h"
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/hle/service/glue/glue_manager.h"
|
#include "core/hle/service/glue/glue_manager.h"
|
||||||
#include "core/hle/service/ns/application_manager_interface.h"
|
#include "core/hle/service/ns/application_manager_interface.h"
|
||||||
#include "core/hle/service/ns/service_getter_interface.h"
|
#include "core/hle/service/ns/service_getter_interface.h"
|
||||||
|
#include "core/hle/service/server_manager.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
@@ -44,8 +49,9 @@ AppletIdentityInfo GetCallerIdentity(Applet& applet) {
|
|||||||
|
|
||||||
ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
|
ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
|
||||||
std::shared_ptr<Applet> applet)
|
std::shared_ptr<Applet> applet)
|
||||||
: ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, m_applet{std::move(applet)},
|
: ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, m_applet{std::move(applet)}
|
||||||
m_broker{m_applet->caller_applet_broker} {
|
, m_broker{m_applet->caller_applet_broker}
|
||||||
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&ILibraryAppletSelfAccessor::PopInData>, "PopInData"},
|
{0, D<&ILibraryAppletSelfAccessor::PopInData>, "PopInData"},
|
||||||
@@ -96,9 +102,130 @@ Result ILibraryAppletSelfAccessor::PopInData(Out<SharedPointer<IStorage>> out_st
|
|||||||
R_RETURN(m_broker->GetInData().Pop(out_storage));
|
R_RETURN(m_broker->GetInData().Pop(out_storage));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// uLauncher emulation
|
||||||
|
static Result UloaderCreateApplication(Core::System& system, u64 program_id, std::shared_ptr<Applet> caller_applet) {
|
||||||
|
// Get the program NCA from storage.
|
||||||
|
auto& storage = system.GetContentProviderUnion();
|
||||||
|
FileSys::VirtualFile nca_raw = storage.GetEntryRaw(program_id, FileSys::ContentRecordType::Program);
|
||||||
|
// Ensure we retrieved a program NCA.
|
||||||
|
R_UNLESS(nca_raw != nullptr, ResultUnknown);
|
||||||
|
std::vector<u8> control;
|
||||||
|
std::unique_ptr<Loader::AppLoader> loader;
|
||||||
|
Loader::ResultStatus result;
|
||||||
|
auto process = CreateApplicationProcess(control, loader, result, system, nca_raw, program_id, 0);
|
||||||
|
R_UNLESS(process != nullptr, ResultUnknown);
|
||||||
|
const auto applet = std::make_shared<Applet>(system, std::move(process), true);
|
||||||
|
applet->program_id = program_id;
|
||||||
|
applet->applet_id = AppletId::Application;
|
||||||
|
applet->type = AppletType::Application;
|
||||||
|
applet->library_applet_mode = LibraryAppletMode::AllForeground;
|
||||||
|
|
||||||
|
applet->caller_applet = caller_applet;
|
||||||
|
applet->caller_applet_broker = std::make_shared<AppletDataBroker>(system);
|
||||||
|
applet->frontend = caller_applet->frontend;
|
||||||
|
caller_applet->child_applets.push_back(applet);
|
||||||
|
|
||||||
|
system.GetAppletManager().GetWindowSystem()->TrackApplet(applet, true);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
Result ILibraryAppletSelfAccessor::PushOutData(SharedPointer<IStorage> storage) {
|
Result ILibraryAppletSelfAccessor::PushOutData(SharedPointer<IStorage> storage) {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_INFO(Service_AM, "called");
|
||||||
m_broker->GetOutData().Push(storage);
|
m_broker->GetOutData().Push(storage);
|
||||||
|
|
||||||
|
if (m_applet->applet_id == AppletId::UlauncherUmenu) {
|
||||||
|
enum class SystemMessage : u32 {
|
||||||
|
Invalid,
|
||||||
|
SetSelectedUser,
|
||||||
|
LaunchApplication,
|
||||||
|
ResumeApplication,
|
||||||
|
TerminateApplication,
|
||||||
|
LaunchHomebrewLibraryApplet,
|
||||||
|
LaunchHomebrewApplication,
|
||||||
|
ChooseHomebrew,
|
||||||
|
OpenWebPage,
|
||||||
|
OpenAlbum,
|
||||||
|
RestartMenu,
|
||||||
|
ReloadConfig,
|
||||||
|
UpdateMenuPaths,
|
||||||
|
UpdateMenuIndex,
|
||||||
|
OpenUserPage,
|
||||||
|
OpenMiiEdit,
|
||||||
|
OpenAddUser,
|
||||||
|
OpenNetConnect,
|
||||||
|
ListAddedApplications,
|
||||||
|
ListDeletedApplications,
|
||||||
|
OpenCabinet,
|
||||||
|
StartVerifyApplication,
|
||||||
|
ListInVerifyApplications,
|
||||||
|
NotifyWarnedAboutOutdatedTheme,
|
||||||
|
TerminateMenu,
|
||||||
|
OpenControllerKeyRemapping
|
||||||
|
};
|
||||||
|
struct CommandCommonHeader {
|
||||||
|
u32 magic;
|
||||||
|
u32 val;
|
||||||
|
};
|
||||||
|
std::shared_ptr<IStorage> req_storage;
|
||||||
|
m_broker->GetOutData().Pop(&req_storage);
|
||||||
|
auto req_data = req_storage->GetData();
|
||||||
|
CommandCommonHeader req_cmd{};
|
||||||
|
std::memcpy(&req_cmd, req_data.data(), sizeof(req_cmd));
|
||||||
|
|
||||||
|
LOG_WARNING(Service_AM, "uLauncher:IPC {}, {}", req_cmd.magic, req_cmd.val);
|
||||||
|
switch (SystemMessage(req_cmd.val)) {
|
||||||
|
case SystemMessage::SetSelectedUser:
|
||||||
|
break;
|
||||||
|
case SystemMessage::LaunchApplication: {
|
||||||
|
// all applet proxies OpenSystemAppletProxy
|
||||||
|
// applet proxy GetApplicationCreator
|
||||||
|
// application creator CreateApplication
|
||||||
|
u64 args_value{};
|
||||||
|
std::memcpy(std::addressof(args_value), req_data.data() + sizeof(req_cmd), sizeof(args_value));
|
||||||
|
LOG_WARNING(Service_AM, "program_id={:016x}", args_value);
|
||||||
|
UloaderCreateApplication(system, args_value, m_applet);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SystemMessage::ResumeApplication:
|
||||||
|
case SystemMessage::TerminateApplication:
|
||||||
|
case SystemMessage::LaunchHomebrewLibraryApplet:
|
||||||
|
case SystemMessage::LaunchHomebrewApplication:
|
||||||
|
case SystemMessage::ChooseHomebrew:
|
||||||
|
case SystemMessage::OpenWebPage:
|
||||||
|
case SystemMessage::OpenAlbum:
|
||||||
|
case SystemMessage::RestartMenu:
|
||||||
|
case SystemMessage::ReloadConfig:
|
||||||
|
case SystemMessage::UpdateMenuPaths:
|
||||||
|
case SystemMessage::UpdateMenuIndex:
|
||||||
|
case SystemMessage::OpenUserPage:
|
||||||
|
case SystemMessage::OpenMiiEdit:
|
||||||
|
case SystemMessage::OpenAddUser:
|
||||||
|
case SystemMessage::OpenNetConnect:
|
||||||
|
case SystemMessage::ListAddedApplications:
|
||||||
|
case SystemMessage::ListDeletedApplications:
|
||||||
|
case SystemMessage::OpenCabinet:
|
||||||
|
case SystemMessage::StartVerifyApplication:
|
||||||
|
case SystemMessage::ListInVerifyApplications:
|
||||||
|
case SystemMessage::NotifyWarnedAboutOutdatedTheme:
|
||||||
|
break;
|
||||||
|
case SystemMessage::TerminateMenu:
|
||||||
|
system.GetUserChannel() = m_applet->user_channel_launch_parameter;
|
||||||
|
system.ExecuteProgram(0);
|
||||||
|
break;
|
||||||
|
case SystemMessage::OpenControllerKeyRemapping:
|
||||||
|
break;
|
||||||
|
case SystemMessage::Invalid:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandCommonHeader res_cmd{};
|
||||||
|
std::vector<u8> res_data(0x8000);
|
||||||
|
res_cmd.magic = 0x21494D53;
|
||||||
|
res_cmd.val = u32(ResultSuccess.raw);
|
||||||
|
std::memcpy(res_data.data(), &res_cmd, sizeof(res_cmd));
|
||||||
|
m_broker->GetInData().Push(std::make_shared<IStorage>(system, std::move(res_data)));
|
||||||
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void WindowSystem::Update() {
|
|||||||
void WindowSystem::TrackApplet(std::shared_ptr<Applet> applet, bool is_application) {
|
void WindowSystem::TrackApplet(std::shared_ptr<Applet> applet, bool is_application) {
|
||||||
std::scoped_lock lk{m_lock};
|
std::scoped_lock lk{m_lock};
|
||||||
|
|
||||||
if (applet->applet_id == AppletId::QLaunch) {
|
if (applet->applet_id == AppletId::QLaunch || applet->applet_id == AppletId::UlauncherUmenu) {
|
||||||
ASSERT(m_home_menu == nullptr);
|
ASSERT(m_home_menu == nullptr);
|
||||||
m_home_menu = applet.get();
|
m_home_menu = applet.get();
|
||||||
} else if (applet->applet_id == AppletId::OverlayDisplay) {
|
} else if (applet->applet_id == AppletId::OverlayDisplay) {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 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
|
||||||
|
|
||||||
@@ -15,12 +18,11 @@ void LoopProcess(Core::System& system) {
|
|||||||
auto module = std::make_shared<Module>();
|
auto module = std::make_shared<Module>();
|
||||||
auto server_manager = std::make_unique<ServerManager>(system);
|
auto server_manager = std::make_unique<ServerManager>(system);
|
||||||
|
|
||||||
server_manager->RegisterNamedService(
|
server_manager->RegisterNamedService("apm", std::make_shared<APM>(system, module, system.GetAPMController(), "apm"));
|
||||||
"apm", std::make_shared<APM>(system, module, system.GetAPMController(), "apm"));
|
server_manager->RegisterNamedService("apm:am", std::make_shared<APM>(system, module, system.GetAPMController(), "apm:am"));
|
||||||
server_manager->RegisterNamedService(
|
// Removed on [+8.0.0] but kept for compatibility
|
||||||
"apm:am", std::make_shared<APM>(system, module, system.GetAPMController(), "apm:am"));
|
server_manager->RegisterNamedService("apm:p", std::make_shared<APM>(system, module, system.GetAPMController(), "apm:p"));
|
||||||
server_manager->RegisterNamedService(
|
server_manager->RegisterNamedService("apm:sys", std::make_shared<APM_Sys>(system, system.GetAPMController()));
|
||||||
"apm:sys", std::make_shared<APM_Sys>(system, system.GetAPMController()));
|
|
||||||
ServerManager::RunServer(std::move(server_manager));
|
ServerManager::RunServer(std::move(server_manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ IBtmSystemCore::IBtmSystemCore(Core::System& system_)
|
|||||||
{10, nullptr, "StartAudioDeviceDiscovery"},
|
{10, nullptr, "StartAudioDeviceDiscovery"},
|
||||||
{11, nullptr, "StopAudioDeviceDiscovery"},
|
{11, nullptr, "StopAudioDeviceDiscovery"},
|
||||||
{12, nullptr, "IsDiscoveryingAudioDevice"},
|
{12, nullptr, "IsDiscoveryingAudioDevice"},
|
||||||
{13, nullptr, "GetDiscoveredAudioDevice"},
|
{13, C<&IBtmSystemCore::GetDiscoveredAudioDevice>, "GetDiscoveredAudioDevice"},
|
||||||
{14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"},
|
{14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"},
|
||||||
{15, nullptr, "ConnectAudioDevice"},
|
{15, nullptr, "ConnectAudioDevice"},
|
||||||
{16, nullptr, "IsConnectingAudioDevice"},
|
{16, nullptr, "IsConnectingAudioDevice"},
|
||||||
@@ -93,6 +93,11 @@ Result IBtmSystemCore::AcquireRadioEvent(Out<bool> out_is_valid,
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result IBtmSystemCore::GetDiscoveredAudioDevice(OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices, s32 count, Out<s32> out_total) {
|
||||||
|
LOG_WARNING(Service_BTM, "(STUBBED) called");
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent(
|
Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent(
|
||||||
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
LOG_WARNING(Service_BTM, "(STUBBED) called");
|
LOG_WARNING(Service_BTM, "(STUBBED) called");
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 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-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
@@ -34,9 +37,8 @@ private:
|
|||||||
Result DisableRadio();
|
Result DisableRadio();
|
||||||
Result IsRadioEnabled(Out<bool> out_is_enabled);
|
Result IsRadioEnabled(Out<bool> out_is_enabled);
|
||||||
|
|
||||||
Result AcquireRadioEvent(Out<bool> out_is_valid,
|
Result AcquireRadioEvent(Out<bool> out_is_valid, OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||||
OutCopyHandle<Kernel::KReadableEvent> out_event);
|
Result GetDiscoveredAudioDevice(OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices, s32 count, Out<s32> out_total);
|
||||||
|
|
||||||
Result AcquireAudioDeviceConnectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
Result AcquireAudioDeviceConnectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||||
|
|
||||||
Result GetConnectedAudioDevices(
|
Result GetConnectedAudioDevices(
|
||||||
|
|||||||
@@ -277,7 +277,17 @@ private:
|
|||||||
state.store(State::Processing);
|
state.store(State::Processing);
|
||||||
evt_processing->Signal();
|
evt_processing->Signal();
|
||||||
|
|
||||||
worker = std::thread(&IScanRequest::WorkerThread, this);
|
worker = std::thread([this]() {
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
scan_results = Network::ScanWifiNetworks(3s);
|
||||||
|
{
|
||||||
|
std::scoped_lock lk{g_scan_mtx};
|
||||||
|
g_last_scan_results = scan_results;
|
||||||
|
}
|
||||||
|
// choose result code
|
||||||
|
const bool ok = !scan_results.empty();
|
||||||
|
Finish(ok ? ResultSuccess : ResultPendingConnection);
|
||||||
|
});
|
||||||
IPC::ResponseBuilder{ctx, 2}.Push(ResultSuccess);
|
IPC::ResponseBuilder{ctx, 2}.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,21 +318,6 @@ private:
|
|||||||
|
|
||||||
enum class State { Idle, Processing, Finished };
|
enum class State { Idle, Processing, Finished };
|
||||||
|
|
||||||
void WorkerThread() {
|
|
||||||
using namespace std::chrono_literals;
|
|
||||||
|
|
||||||
scan_results = Network::ScanWifiNetworks(3s);
|
|
||||||
|
|
||||||
{
|
|
||||||
std::scoped_lock lk{g_scan_mtx};
|
|
||||||
g_last_scan_results = scan_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
// choose result code
|
|
||||||
const bool ok = !scan_results.empty();
|
|
||||||
Finish(ok ? ResultSuccess : ResultPendingConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Finish(Result rc) {
|
void Finish(Result rc) {
|
||||||
worker_result.store(rc);
|
worker_result.store(rc);
|
||||||
state.store(State::Finished);
|
state.store(State::Finished);
|
||||||
|
|||||||
@@ -79,7 +79,9 @@ void nvdisp_disp0::Composite(std::span<const Nvnflinger::HwcLayer> sorted_layers
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (size_t i = 0; i < layer.acquire_fence.num_fences; i++) {
|
for (size_t i = 0; i < layer.acquire_fence.num_fences; i++) {
|
||||||
output_fences.push_back(layer.acquire_fence.fences[i]);
|
if (layer.acquire_fence.fences[i].id >= 0) {
|
||||||
|
output_fences.push_back(layer.acquire_fence.fences[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -615,6 +615,9 @@ Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) {
|
|||||||
case NativeWindow::ConsumerUsageBits:
|
case NativeWindow::ConsumerUsageBits:
|
||||||
value = core->consumer_usage_bit;
|
value = core->consumer_usage_bit;
|
||||||
break;
|
break;
|
||||||
|
case NativeWindow::DefaultDataSpace:
|
||||||
|
value = core->GetMaxBufferCountLocked(false);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return Status::BadValue;
|
return Status::BadValue;
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 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-FileCopyrightText: Copyright 2012 The Android Open Source Project
|
// SPDX-FileCopyrightText: Copyright 2012 The Android Open Source Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
@@ -15,10 +18,8 @@ namespace Service::android {
|
|||||||
|
|
||||||
class Fence {
|
class Fence {
|
||||||
public:
|
public:
|
||||||
constexpr Fence() = default;
|
|
||||||
|
|
||||||
static constexpr Fence NoFence() {
|
static constexpr Fence NoFence() {
|
||||||
Fence fence;
|
Fence fence{};
|
||||||
fence.fences[0].id = -1;
|
fence.fences[0].id = -1;
|
||||||
fence.fences[1].id = -1;
|
fence.fences[1].id = -1;
|
||||||
fence.fences[2].id = -1;
|
fence.fences[2].id = -1;
|
||||||
@@ -26,7 +27,6 @@ public:
|
|||||||
return fence;
|
return fence;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
u32 num_fences{};
|
u32 num_fences{};
|
||||||
std::array<Service::Nvidia::NvFence, 4> fences{};
|
std::array<Service::Nvidia::NvFence, 4> fences{};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
#include "core/hle/service/sockets/sockets.h"
|
#include "core/hle/service/sockets/sockets.h"
|
||||||
#include "core/hle/service/spl/spl_module.h"
|
#include "core/hle/service/spl/spl_module.h"
|
||||||
#include "core/hle/service/ssl/ssl.h"
|
#include "core/hle/service/ssl/ssl.h"
|
||||||
|
#include "core/hle/service/ulsf/ulsf.h"
|
||||||
#include "core/hle/service/usb/usb.h"
|
#include "core/hle/service/usb/usb.h"
|
||||||
#include "core/hle/service/vi/vi.h"
|
#include "core/hle/service/vi/vi.h"
|
||||||
|
|
||||||
@@ -144,7 +145,8 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
|
|||||||
{"ro", &RO::LoopProcess},
|
{"ro", &RO::LoopProcess},
|
||||||
{"spl", &SPL::LoopProcess},
|
{"spl", &SPL::LoopProcess},
|
||||||
{"ssl", &SSL::LoopProcess},
|
{"ssl", &SSL::LoopProcess},
|
||||||
{"usb", &USB::LoopProcess}
|
{"usb", &USB::LoopProcess},
|
||||||
|
{"ulsf", &ULSF::LoopProcess},
|
||||||
})
|
})
|
||||||
kernel.RunOnGuestCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); });
|
kernel.RunOnGuestCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); });
|
||||||
}
|
}
|
||||||
|
|||||||