Compare commits
33 commits
6b94984041
...
726f4621ea
| 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 |
|
|
@ -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"
|
||||
|
||||
# license header constants, please change when needed :))))
|
||||
YEAR=2026
|
||||
YEAR=$(date "+%Y")
|
||||
HOLDER="Eden Emulator Project"
|
||||
LICENSE="GPL-3.0-or-later"
|
||||
|
||||
|
|
@ -112,10 +112,10 @@ for file in $FILES; do
|
|||
[ "$excluded" = "true" ] && continue
|
||||
|
||||
case "$file" in
|
||||
*.cmake|*.sh|*CMakeLists.txt)
|
||||
*.cmake|*.sh|*.ps1|*.py|*.rb|*.perl|*.pl|*.nix|*CMakeLists.txt)
|
||||
begin="#"
|
||||
;;
|
||||
*.kt*|*.cpp|*.h|*.qml)
|
||||
*.kt|*.kts|*.cpp|*.h|*.qml|*.c|*.hpp|*.hxx|*.cxx|*.h.in|*.inc)
|
||||
begin="//"
|
||||
;;
|
||||
*)
|
||||
|
|
@ -185,11 +185,12 @@ if [ "$UPDATE" = "true" ]; then
|
|||
|
||||
for file in $SRC_FILES $OTHER_FILES; do
|
||||
case $(basename -- "$file") in
|
||||
*.cmake|*CMakeLists.txt)
|
||||
# Windows Powershell wont use shebangs
|
||||
*.cmake|*.ps1|*CMakeLists.txt)
|
||||
begin="#"
|
||||
shell="false"
|
||||
;;
|
||||
*.sh)
|
||||
*.sh|*.py|*.rb|*.perl|*.pl|*.nix)
|
||||
begin="#"
|
||||
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")
|
||||
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
|
||||
if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX))
|
||||
set(YUZU_STATIC_BUILD ON)
|
||||
|
|
@ -701,6 +703,12 @@ endif()
|
|||
|
||||
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
|
||||
if(ENABLE_QT)
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT yuzu)
|
||||
|
|
|
|||
207
dist/dev.eden_emu.eden.svg
vendored
|
|
@ -6,8 +6,8 @@
|
|||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg7"
|
||||
sodipodi:docname="1stanni.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
sodipodi:docname="base.svg.2026_01_12_14_43_47.0.svg"
|
||||
inkscape:version="1.4.2 (ebf0e94, 2025-05-08)"
|
||||
inkscape:export-filename="base.svg.2026_01_12_14_43_47.0.svg"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
|
|
@ -19,34 +19,36 @@
|
|||
<defs
|
||||
id="defs7">
|
||||
<linearGradient
|
||||
id="linearGradient34"
|
||||
id="linearGradient1"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#ffd700;stop-opacity:1;"
|
||||
style="stop-color:#ff2e88;stop-opacity:0.5;"
|
||||
offset="0"
|
||||
id="stop34" />
|
||||
id="stop3" />
|
||||
<stop
|
||||
style="stop-color:#ffd700;stop-opacity:0.48031053;"
|
||||
offset="1"
|
||||
id="stop35" />
|
||||
style="stop-color:#bf42f6;stop-opacity:0.5;"
|
||||
offset="0.44631511"
|
||||
id="stop4" />
|
||||
<stop
|
||||
style="stop-color:#5da5ed;stop-opacity:0.5;"
|
||||
offset="0.90088946"
|
||||
id="stop2" />
|
||||
</linearGradient>
|
||||
<rect
|
||||
x="20.999999"
|
||||
y="287.30493"
|
||||
width="487.07235"
|
||||
height="134.69506"
|
||||
id="rect22" />
|
||||
<linearGradient
|
||||
id="linearGradient21"
|
||||
id="linearGradient138"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#3a0057;stop-opacity:1;"
|
||||
style="stop-color:#ff2e88;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop21" />
|
||||
id="stop152" />
|
||||
<stop
|
||||
style="stop-color:#830091;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop22" />
|
||||
style="stop-color:#bf42f6;stop-opacity:1;"
|
||||
offset="0.44971901"
|
||||
id="stop137" />
|
||||
<stop
|
||||
style="stop-color:#5da5ed;stop-opacity:1;"
|
||||
offset="0.89793283"
|
||||
id="stop138" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch37"
|
||||
|
|
@ -114,6 +116,33 @@
|
|||
width="521.34025"
|
||||
height="248.94868"
|
||||
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
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath18">
|
||||
|
|
@ -136,6 +165,16 @@
|
|||
inkscape:label="Circle"
|
||||
r="191.89999" />
|
||||
</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
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath128">
|
||||
|
|
@ -148,106 +187,14 @@
|
|||
</clipPath>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient21"
|
||||
id="linearGradient22"
|
||||
xlink:href="#linearGradient1"
|
||||
id="linearGradient2"
|
||||
x1="256"
|
||||
y1="0"
|
||||
y1="64"
|
||||
x2="256"
|
||||
y2="512"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
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>
|
||||
y2="448"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.3229974,0,0,1.3214002,-82.687336,-82.290326)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
|
|
@ -258,29 +205,23 @@
|
|||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="213.49999"
|
||||
inkscape:cy="248.99999"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="849"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="261.62951"
|
||||
inkscape:cy="230.87036"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1008"
|
||||
inkscape:window-x="1080"
|
||||
inkscape:window-y="351"
|
||||
inkscape:window-maximized="1"
|
||||
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
|
||||
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"
|
||||
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
|
||||
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"
|
||||
sodipodi:nodetypes="cscsccscscscsccccccscscccscscscscscsc"
|
||||
inkscape:label="MainOutline"
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
BIN
dist/eden.bmp
vendored
|
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 256 KiB |
BIN
dist/eden.ico
vendored
|
Before Width: | Height: | Size: 556 KiB After Width: | Height: | Size: 335 KiB |
1174
dist/languages/ar.ts
vendored
1174
dist/languages/ca.ts
vendored
1178
dist/languages/cs.ts
vendored
1178
dist/languages/da.ts
vendored
1174
dist/languages/de.ts
vendored
1178
dist/languages/el.ts
vendored
1174
dist/languages/es.ts
vendored
1178
dist/languages/fi.ts
vendored
1170
dist/languages/fr.ts
vendored
1174
dist/languages/hu.ts
vendored
1174
dist/languages/id.ts
vendored
1170
dist/languages/it.ts
vendored
1174
dist/languages/ja_JP.ts
vendored
2851
dist/languages/ko_KR.ts
vendored
1174
dist/languages/nb.ts
vendored
1178
dist/languages/nl.ts
vendored
1172
dist/languages/pl.ts
vendored
1297
dist/languages/pt_BR.ts
vendored
1174
dist/languages/pt_PT.ts
vendored
1174
dist/languages/ru_RU.ts
vendored
1172
dist/languages/sv.ts
vendored
1174
dist/languages/tr_TR.ts
vendored
1174
dist/languages/uk.ts
vendored
1178
dist/languages/vi.ts
vendored
1178
dist/languages/vi_VN.ts
vendored
1172
dist/languages/zh_CN.ts
vendored
1174
dist/languages/zh_TW.ts
vendored
BIN
dist/qt_themes/default/icons/256x256/eden.png
vendored
|
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):
|
||||
|
||||
```sh
|
||||
echo '#!/bin/sh' >cc
|
||||
echo '#!/bin/sh -e' >cc
|
||||
echo 'gcc $@' >>cc
|
||||
chmod +x cc
|
||||
export PATH="$PATH:$PWD"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
- **Pros**: Offers decent pixel-art upscaling.
|
||||
- **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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
#!/bin/sh -e
|
||||
emuName="eden" #parameterize me
|
||||
|
||||
. "$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://git.crueter.xyz/mirror/eden
|
||||
- https://codeberg.org/eden-emu/eden
|
||||
- https://collective.taymaerz.de/eden/eden
|
||||
|
||||
Other mirrors obviously exist on the internet, but we can't guarantee their reliability and/or availability.
|
||||
|
|
|
|||
3
externals/nx_tzdb/tzdb_template.h.in
vendored
|
|
@ -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-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-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 ! 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.
|
||||
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
|
||||
END
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 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
|
||||
cat<<END
|
||||
cat<<EOF
|
||||
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.
|
||||
END
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
4
shell.nix
Normal file → Executable file
|
|
@ -1,3 +1,7 @@
|
|||
#!/usr/bin/nix-shell
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
let
|
||||
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05";
|
||||
pkgs = import nixpkgs { config = {}; overlays = []; };
|
||||
|
|
|
|||
|
|
@ -127,6 +127,8 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
NativeConfig.reloadGlobalConfig()
|
||||
|
||||
InputHandler.updateControllerData()
|
||||
val players = NativeConfig.getInputSettings(true)
|
||||
var hasConfiguredControllers = false
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
|||
RENDERER_USE_SPEED_LIMIT("use_speed_limit"),
|
||||
USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
|
||||
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
|
||||
ANTIFLICKER("antiflicker"),
|
||||
FIX_BLOOM_EFFECTS("fix_bloom_effects"),
|
||||
EMULATE_BGR565("emulate_bgr565"),
|
||||
RESCALE_HACK("rescale_hack"),
|
||||
|
|
|
|||
|
|
@ -750,6 +750,13 @@ abstract class SettingsItem(
|
|||
descriptionId = R.string.skip_cpu_inner_invalidation_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.ANTIFLICKER,
|
||||
titleId = R.string.antiflicker,
|
||||
descriptionId = R.string.antiflicker_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.FIX_BLOOM_EFFECTS,
|
||||
|
|
|
|||
|
|
@ -76,18 +76,25 @@ class SettingsFragmentPresenter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun isFsrScalingFilterSelected(): Boolean {
|
||||
val fsrFilterValue = resolveFsrScalingFilterValue() ?: return false
|
||||
private fun isSharpnessScalingFilterSelected(): Boolean {
|
||||
val needsGlobal = getNeedsGlobalForKey(IntSetting.RENDERER_SCALING_FILTER.key)
|
||||
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 values = context.resources.getIntArray(R.array.rendererScalingFilterValues)
|
||||
val fsrIndex = names.indexOf(context.getString(R.string.scaling_filter_fsr))
|
||||
return if (fsrIndex in values.indices) values[fsrIndex] else null
|
||||
val sharpnessFilterNames = setOf(
|
||||
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
|
||||
|
|
@ -267,7 +274,7 @@ class SettingsFragmentPresenter(
|
|||
add(IntSetting.RENDERER_RESOLUTION.key)
|
||||
add(IntSetting.RENDERER_VSYNC.key)
|
||||
add(IntSetting.RENDERER_SCALING_FILTER.key)
|
||||
if (isFsrScalingFilterSelected()) {
|
||||
if (isSharpnessScalingFilterSelected()) {
|
||||
add(IntSetting.FSR_SHARPENING_SLIDER.key)
|
||||
}
|
||||
add(IntSetting.RENDERER_ANTI_ALIASING.key)
|
||||
|
|
@ -291,6 +298,7 @@ class SettingsFragmentPresenter(
|
|||
|
||||
add(IntSetting.FAST_GPU_TIME.key)
|
||||
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
|
||||
add(BooleanSetting.ANTIFLICKER.key)
|
||||
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
|
||||
add(BooleanSetting.EMULATE_BGR565.key)
|
||||
add(BooleanSetting.RESCALE_HACK.key)
|
||||
|
|
|
|||
|
|
@ -1090,7 +1090,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
private fun addQuickSettings() {
|
||||
binding.quickSettingsSheet.apply {
|
||||
val container = binding.quickSettingsSheet.findViewById<ViewGroup>(R.id.quick_settings_container)
|
||||
val isFsrSelected = isFsrScalingFilterSelected()
|
||||
val isSharpnessFilterSelected = isSharpnessScalingFilterSelected()
|
||||
|
||||
container.removeAllViews()
|
||||
|
||||
|
|
@ -1176,7 +1176,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
addQuickSettings()
|
||||
}
|
||||
|
||||
if (isFsrSelected) {
|
||||
if (isSharpnessFilterSelected) {
|
||||
quickSettings.addSliderSetting(
|
||||
R.string.fsr_sharpness,
|
||||
container,
|
||||
|
|
@ -1197,17 +1197,24 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
}
|
||||
}
|
||||
|
||||
private fun isFsrScalingFilterSelected(): Boolean {
|
||||
val fsrFilterValue = resolveFsrScalingFilterValue() ?: return false
|
||||
private fun isSharpnessScalingFilterSelected(): Boolean {
|
||||
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 values = resources.getIntArray(R.array.rendererScalingFilterValues)
|
||||
val fsrIndex = names.indexOf(getString(R.string.scaling_filter_fsr))
|
||||
return if (fsrIndex in values.indices) values[fsrIndex] else null
|
||||
val sharpnessFilterNames = setOf(
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ AndroidConfig::AndroidConfig(const std::string& config_name, ConfigType config_t
|
|||
}
|
||||
|
||||
void AndroidConfig::ReloadAllValues() {
|
||||
// Ensure the INI file is current before reloading values.
|
||||
SetUpIni();
|
||||
|
||||
Reload();
|
||||
ReadAndroidValues();
|
||||
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="advanced">Avancé</string>
|
||||
|
||||
<string name="renderer_accuracy">Mode GPU</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="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="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_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_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_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_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="disabled">Désactivé</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="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_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 -->
|
||||
<string name="audio_output_engine">Moteur de sortie</string>
|
||||
<string name="audio_volume">Volume</string>
|
||||
|
|
@ -590,6 +622,7 @@
|
|||
|
||||
<!-- Miscellaneous -->
|
||||
<string name="slider_default">Par défaut</string>
|
||||
<string name="default_string">Par défaut</string>
|
||||
<string name="loading">Chargement...</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>
|
||||
|
|
@ -628,6 +661,7 @@
|
|||
<string name="select_gpu_driver_default">Par défaut</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="installed_label">%1$s (Installé)</string>
|
||||
<string name="system_gpu_driver">Pilote du GPU du système</string>
|
||||
<string name="installing_driver">Installation du pilote...</string>
|
||||
|
||||
|
|
@ -647,6 +681,7 @@
|
|||
<string name="installing">Installation en cours…</string>
|
||||
<string name="latest">Dernière</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_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_graphics">Vidéo</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_description">Moteur de sortie, volume</string>
|
||||
<string name="preferences_controls">Contrôles</string>
|
||||
|
|
@ -663,6 +701,25 @@
|
|||
<string name="preferences_player">Joueur %d</string>
|
||||
<string name="preferences_debug">Débogage</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 -->
|
||||
<string name="info">Info</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="add_ons">Extensions</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_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>
|
||||
|
|
@ -683,6 +741,9 @@
|
|||
<string name="edit_playtime">Modifier le Temps de Jeu</string>
|
||||
<string name="hours">Heures</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="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>
|
||||
|
|
@ -714,6 +775,7 @@
|
|||
<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="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_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>
|
||||
|
|
@ -785,6 +847,7 @@
|
|||
<string name="emulation_control_opacity">Opacité</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_snap_to_grid">Aimanter à la grille</string>
|
||||
<string name="emulation_pause">Mettre en pause l\'émulation</string>
|
||||
<string name="emulation_unpause">Reprendre l\'émulation</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_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 -->
|
||||
<string name="temperature_celsius">Celsius</string>
|
||||
<string name="temperature_fahrenheit">Fahrenheit</string>
|
||||
|
|
@ -853,6 +942,11 @@
|
|||
|
||||
<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 -->
|
||||
<string name="dma_accuracy_default">Défaut</string>
|
||||
<string name="dma_accuracy_unsafe">Dangereux</string>
|
||||
|
|
@ -886,6 +980,26 @@
|
|||
<string name="cpu_accuracy_paranoid">Paranoïaque</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 -->
|
||||
<string name="gamepad_d_pad">Pavé directionnel</string>
|
||||
<string name="gamepad_left_stick">Stick gauche</string>
|
||||
|
|
@ -902,26 +1016,37 @@
|
|||
<string name="theme_material_you">Material You</string>
|
||||
<string name="app_settings">Paramètres de l’App</string>
|
||||
<string name="theme_and_color">Thème et Couleur</string>
|
||||
<string name="fullscreen_mode">Mode plein écran</string>
|
||||
<!-- Theme Modes -->
|
||||
<string name="change_theme_mode">Changer le mode de thème</string>
|
||||
<string name="theme_mode_follow_system">Automatique</string>
|
||||
<string name="theme_mode_light">Lumineux</string>
|
||||
<string name="theme_mode_dark">Sombre</string>
|
||||
|
||||
<string name="multiplier_none">Aucun</string>
|
||||
|
||||
<!-- Black backgrounds theme -->
|
||||
<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>
|
||||
|
||||
<!-- 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 -->
|
||||
<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_system">Suivre le système</string>
|
||||
<!-- Static Themes -->
|
||||
<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="blue">Bleu</string>
|
||||
<string name="cyan">Cyan</string>
|
||||
<string name="red">Rouge</string>
|
||||
<string name="green">Vert</string>
|
||||
<string name="yellow">Jaune</string>
|
||||
<string name="orange">Orange</string>
|
||||
<string name="pink">Rose</string>
|
||||
|
|
@ -940,6 +1065,8 @@
|
|||
|
||||
<!-- Applet Modes -->
|
||||
<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_lle">Applet réel</string>
|
||||
|
||||
|
|
@ -948,7 +1075,39 @@
|
|||
<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="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 -->
|
||||
<string name="licenses">Licences</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>
|
||||
<!-- Stats Overlay settings -->
|
||||
<string name="process_ram">프로세스 RAM: %1$d MB</string>
|
||||
<string name="shaders_prefix">셰이더</string>
|
||||
<string name="shaders_suffix">빌드 중</string>
|
||||
<string name="shaders_prefix">구축 중</string>
|
||||
<string name="shaders_suffix">개 셰이더</string>
|
||||
<string name="charging">(충전 중)</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="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="app_notification_channel_description">Сповіщення емулятора Switch Eden</string>
|
||||
<string name="app_notification_running">Eden працює</string>
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@
|
|||
|
||||
<!-- NVDEC Emulation -->
|
||||
<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>
|
||||
|
||||
<!-- Optimize SPIRV output -->
|
||||
|
|
@ -181,14 +181,14 @@
|
|||
<string name="multiplayer_hide_full_rooms">隐藏满员房间</string>
|
||||
<string name="multiplayer_hide_empty_rooms">隐藏空房间</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_lobby_type">大厅类型</string>
|
||||
<string name="multiplayer_lobby_type">游戏大厅类型</string>
|
||||
<string name="multiplayer_room_name_error">长度需为3-20个字符</string>
|
||||
<string name="multiplayer_required">必填</string>
|
||||
<string name="multiplayer_token_required">需要Web令牌,请前往高级设置 -> 系统 -> 网络</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_token_error">必须为48个字符,且仅包含小写字母a-z</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="cpu_ticks">时钟</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>
|
||||
|
||||
<!-- Network settings strings -->
|
||||
<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_description">多人游戏房间中显示的用户名。必须为4-20个字符(仅字母数字、连字符、点号、下划线和空格)。</string>
|
||||
<string name="web_username_description">在多人游戏大厅中显示的用户名。用户名必须为4至20个字符,且仅可包含字母、数字、连字符、点号、下划线和空格。</string>
|
||||
<string name="network">网络</string>
|
||||
|
||||
<!-- Graphics settings strings -->
|
||||
|
|
@ -453,7 +453,7 @@
|
|||
<string name="renderer_vsync">垂直同步模式</string>
|
||||
<string name="renderer_scaling_filter">窗口滤镜</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>
|
||||
|
||||
|
||||
|
|
@ -496,7 +496,7 @@
|
|||
<string name="fix_bloom_effects">修复 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_description">修复了游戏中的颜色反转以及出现的异常画面瑕疵或奇怪阴影问题</string>
|
||||
<string name="emulate_bgr565_description">修复游戏中的颜色反转或是异常的画面瑕疵或阴影问题</string>
|
||||
<string name="rescale_hack">启用旧版缩放处理</string>
|
||||
<string name="rescale_hack_description">启用通过使用快速缩放路径,来为游戏提供缩放配置处理的传统处理方式</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_description">设置基于 GPU 的纹理还原的最大尺寸(单位:MiB)。\n虽然 GPU 在处理中型和大型纹理时速度更快,但对于非常小的纹理,CPU 的效率可能更高。\n调整此设置,以便在 GPU 加速和 CPU 开销之间找到最佳平衡点。</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_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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -240,6 +240,8 @@
|
|||
<item>@string/scaling_filter_bspline</item>
|
||||
<item>@string/scaling_filter_mitchell</item>
|
||||
<item>@string/scaling_filter_spline1</item>
|
||||
<item>@string/scaling_filter_sgsr</item>
|
||||
<item>@string/scaling_filter_sgsr_edge</item>
|
||||
</string-array>
|
||||
|
||||
<integer-array name="rendererScalingFilterValues">
|
||||
|
|
@ -256,6 +258,8 @@
|
|||
<item>10</item>
|
||||
<item>11</item>
|
||||
<item>12</item>
|
||||
<item>13</item>
|
||||
<item>14</item>
|
||||
</integer-array>
|
||||
|
||||
<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_vsync">VSync mode</string>
|
||||
<string name="renderer_scaling_filter">Window adapting filter</string>
|
||||
<string name="fsr_sharpness">FSR 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">FSR/SGSR sharpness</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>
|
||||
|
||||
|
||||
|
|
@ -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="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="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_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>
|
||||
|
|
@ -1078,6 +1080,8 @@
|
|||
<string name="scaling_filter_bspline" translatable="false">B-Spline</string>
|
||||
<string name="scaling_filter_mitchell" translatable="false">Mitchell</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 -->
|
||||
<string name="anti_aliasing_none">None</string>
|
||||
|
|
|
|||
|
|
@ -29,8 +29,96 @@ void AudioRenderer::Start() {
|
|||
CreateSinkStreams();
|
||||
|
||||
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);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
|
|
@ -82,11 +82,6 @@ public:
|
|||
u64 GetRenderingStartTick(s32 session_id) const noexcept;
|
||||
|
||||
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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ bool IsValidMultiStreamStreamCounts(s32 total_stream_count, s32 stereo_stream_co
|
|||
} // namespace
|
||||
|
||||
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() {
|
||||
|
|
@ -64,206 +66,203 @@ u32 OpusDecoder::Receive(Direction dir, std::stop_token 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");
|
||||
|
||||
if (Receive(Direction::DSP, stop_token) != Message::Start) {
|
||||
LOG_ERROR(Service_Audio,
|
||||
"DSP OpusDecoder failed to receive Start message. Opus initialization failed.");
|
||||
if (Receive(Direction::DSP, rc_stop_token) != Message::Start) {
|
||||
LOG_ERROR(Service_Audio, "DSP OpusDecoder failed to receive Start message. Opus initialization failed.");
|
||||
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;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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-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.
|
||||
*/
|
||||
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& 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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -60,7 +63,7 @@ public:
|
|||
template <typename Func>
|
||||
void ForEachItemBelow(TickType tick, Func&& func) {
|
||||
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;
|
||||
while (iterator) {
|
||||
if (static_cast<s64>(tick) - static_cast<s64>(iterator->tick) < 0) {
|
||||
|
|
|
|||
|
|
@ -545,6 +545,13 @@ struct Values {
|
|||
Specialization::Default,
|
||||
true,
|
||||
true};
|
||||
SwitchableSetting<bool> antiflicker{linkage,
|
||||
false,
|
||||
"antiflicker",
|
||||
Category::RendererHacks,
|
||||
Specialization::Default,
|
||||
true,
|
||||
true};
|
||||
SwitchableSetting<bool> async_presentation{linkage,
|
||||
#ifdef ANDROID
|
||||
false,
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
|
|||
ENUM(FullscreenMode, Borderless, Exclusive);
|
||||
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(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(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
|
||||
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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -28,9 +31,118 @@ enum class Type {
|
|||
/// Protocol values for sockets
|
||||
enum class Protocol : u8 {
|
||||
Unspecified, ///< Represents 0, usable in various places
|
||||
IP,
|
||||
ICMP,
|
||||
TCP,
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1089,6 +1089,8 @@ add_library(core STATIC
|
|||
hle/service/ssl/ssl.h
|
||||
hle/service/ssl/ssl_backend.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.h
|
||||
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() {
|
||||
#ifdef __aarch64__
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ namespace Core {
|
|||
|
||||
namespace {
|
||||
// Prefetch tuning parameters
|
||||
constexpr size_t CACHE_LINE_SIZE = 64;
|
||||
constexpr size_t PREFETCH_STRIDE = 128; // 2 cache lines ahead
|
||||
constexpr size_t SIMD_PREFETCH_THRESHOLD = 32; // Bytes
|
||||
[[maybe_unused]] constexpr size_t CACHE_LINE_SIZE = 64;
|
||||
[[maybe_unused]] constexpr size_t PREFETCH_STRIDE = 128; // 2 cache lines ahead
|
||||
[[maybe_unused]] constexpr size_t SIMD_PREFETCH_THRESHOLD = 32; // Bytes
|
||||
} // namespace
|
||||
|
||||
template <u32 BitSize>
|
||||
|
|
|
|||
|
|
@ -83,7 +83,8 @@ constexpr size_t SlabCountKDeviceAddressSpace = 300;
|
|||
constexpr size_t SlabCountKSession = 1133;
|
||||
constexpr size_t SlabCountKLightSession = 100;
|
||||
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 SlabCountKIoPool = 1;
|
||||
constexpr size_t SlabCountKIoRegion = 6;
|
||||
|
|
|
|||
|
|
@ -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-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
|
|
@ -94,7 +94,9 @@ enum class AppletId : u32 {
|
|||
LoginShare = 0x18,
|
||||
WebAuth = 0x19,
|
||||
MyPage = 0x1A,
|
||||
Lhub = 0x35
|
||||
Lhub = 0x35,
|
||||
// Homebrew -- uses same ProgramId as qlaunch
|
||||
UlauncherUmenu = 0xF000'0000,
|
||||
};
|
||||
|
||||
enum class AppletProgramId : u64 {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,20 @@ namespace Service::AM {
|
|||
|
||||
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;
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
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) {
|
||||
const CommonArguments arguments{
|
||||
.arguments_version = CommonArgumentVersion::Version3,
|
||||
|
|
@ -292,8 +344,18 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
|||
applet->previous_program_index = params.previous_program_index;
|
||||
|
||||
// Push UserChannel data from previous application
|
||||
// Or ulaunch initialization where we push parameters willingly!
|
||||
if (params.launch_type == LaunchType::ApplicationInitiated) {
|
||||
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?
|
||||
|
|
@ -335,6 +397,9 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
|||
case AppletId::Controller:
|
||||
PushInShowController(m_system, InitializeFakeCallerApplet(m_system, applet));
|
||||
break;
|
||||
case AppletId::UlauncherUmenu:
|
||||
PushInShowUlauncherUmenu(m_system, InitializeFakeCallerApplet(m_system, applet));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -342,7 +407,7 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
|||
// Applet was started by frontend, so it is foreground.
|
||||
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.SetOutOfFocusSuspendingEnabled(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-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
|
|
@ -26,6 +26,9 @@ class WindowSystem;
|
|||
enum class LaunchType {
|
||||
FrontendInitiated,
|
||||
ApplicationInitiated,
|
||||
// Special masquerade for AMS + uLaunch CFW
|
||||
FrontendUlaunchInitiated = 0x800,
|
||||
FrontendUmenuInitiated,
|
||||
};
|
||||
|
||||
struct FrontendAppletParameters {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
|
|||
case AppletId::OverlayDisplay:
|
||||
return AppletProgramId::OverlayDisplay;
|
||||
case AppletId::QLaunch:
|
||||
case AppletId::UlauncherUmenu: //reuses same id as Qlaunch
|
||||
return AppletProgramId::QLaunch;
|
||||
case AppletId::Starter:
|
||||
return AppletProgramId::Starter;
|
||||
|
|
|
|||
|
|
@ -8,18 +8,23 @@
|
|||
#include "core/file_sys/control_metadata.h"
|
||||
#include "core/file_sys/patch_manager.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/am/applet_data_broker.h"
|
||||
#include "core/hle/service/am/applet_manager.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/storage.h"
|
||||
#include "core/hle/service/am/window_system.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/hle/service/glue/glue_manager.h"
|
||||
#include "core/hle/service/ns/application_manager_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/loader/loader.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
|
|
@ -44,8 +49,9 @@ AppletIdentityInfo GetCallerIdentity(Applet& applet) {
|
|||
|
||||
ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
|
||||
std::shared_ptr<Applet> applet)
|
||||
: ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, m_applet{std::move(applet)},
|
||||
m_broker{m_applet->caller_applet_broker} {
|
||||
: ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, m_applet{std::move(applet)}
|
||||
, m_broker{m_applet->caller_applet_broker}
|
||||
{
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{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));
|
||||
}
|
||||
|
||||
// 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) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ void WindowSystem::Update() {
|
|||
void WindowSystem::TrackApplet(std::shared_ptr<Applet> applet, bool is_application) {
|
||||
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);
|
||||
m_home_menu = applet.get();
|
||||
} 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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -15,12 +18,11 @@ void LoopProcess(Core::System& system) {
|
|||
auto module = std::make_shared<Module>();
|
||||
auto server_manager = std::make_unique<ServerManager>(system);
|
||||
|
||||
server_manager->RegisterNamedService(
|
||||
"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(
|
||||
"apm:sys", std::make_shared<APM_Sys>(system, system.GetAPMController()));
|
||||
server_manager->RegisterNamedService("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"));
|
||||
// Removed on [+8.0.0] but kept for compatibility
|
||||
server_manager->RegisterNamedService("apm:p", std::make_shared<APM>(system, module, system.GetAPMController(), "apm:p"));
|
||||
server_manager->RegisterNamedService("apm:sys", std::make_shared<APM_Sys>(system, system.GetAPMController()));
|
||||
ServerManager::RunServer(std::move(server_manager));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ IBtmSystemCore::IBtmSystemCore(Core::System& system_)
|
|||
{10, nullptr, "StartAudioDeviceDiscovery"},
|
||||
{11, nullptr, "StopAudioDeviceDiscovery"},
|
||||
{12, nullptr, "IsDiscoveryingAudioDevice"},
|
||||
{13, nullptr, "GetDiscoveredAudioDevice"},
|
||||
{13, C<&IBtmSystemCore::GetDiscoveredAudioDevice>, "GetDiscoveredAudioDevice"},
|
||||
{14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"},
|
||||
{15, nullptr, "ConnectAudioDevice"},
|
||||
{16, nullptr, "IsConnectingAudioDevice"},
|
||||
|
|
@ -93,6 +93,11 @@ Result IBtmSystemCore::AcquireRadioEvent(Out<bool> out_is_valid,
|
|||
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(
|
||||
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||
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-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
|
|
@ -34,9 +37,8 @@ private:
|
|||
Result DisableRadio();
|
||||
Result IsRadioEnabled(Out<bool> out_is_enabled);
|
||||
|
||||
Result AcquireRadioEvent(Out<bool> out_is_valid,
|
||||
OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||
|
||||
Result AcquireRadioEvent(Out<bool> out_is_valid, 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 GetConnectedAudioDevices(
|
||||
|
|
|
|||
|
|
@ -277,7 +277,17 @@ private:
|
|||
state.store(State::Processing);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -308,21 +318,6 @@ private:
|
|||
|
||||
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) {
|
||||
worker_result.store(rc);
|
||||
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++) {
|
||||
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:
|
||||
value = core->consumer_usage_bit;
|
||||
break;
|
||||
case NativeWindow::DefaultDataSpace:
|
||||
value = core->GetMaxBufferCountLocked(false);
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
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 2012 The Android Open Source Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
|
@ -15,10 +18,8 @@ namespace Service::android {
|
|||
|
||||
class Fence {
|
||||
public:
|
||||
constexpr Fence() = default;
|
||||
|
||||
static constexpr Fence NoFence() {
|
||||
Fence fence;
|
||||
Fence fence{};
|
||||
fence.fences[0].id = -1;
|
||||
fence.fences[1].id = -1;
|
||||
fence.fences[2].id = -1;
|
||||
|
|
@ -26,7 +27,6 @@ public:
|
|||
return fence;
|
||||
}
|
||||
|
||||
public:
|
||||
u32 num_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-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
|
|
@ -62,6 +62,7 @@
|
|||
#include "core/hle/service/sockets/sockets.h"
|
||||
#include "core/hle/service/spl/spl_module.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/vi/vi.h"
|
||||
|
||||
|
|
@ -144,7 +145,8 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
|
|||
{"ro", &RO::LoopProcess},
|
||||
{"spl", &SPL::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); });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,10 +142,10 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
|
|||
{22, C<&ISystemSettingsServer::SetEulaVersions>, "SetEulaVersions"},
|
||||
{23, C<&ISystemSettingsServer::GetColorSetId>, "GetColorSetId"},
|
||||
{24, C<&ISystemSettingsServer::SetColorSetId>, "SetColorSetId"},
|
||||
{25, nullptr, "GetConsoleInformationUploadFlag"},
|
||||
{26, nullptr, "SetConsoleInformationUploadFlag"},
|
||||
{27, nullptr, "GetAutomaticApplicationDownloadFlag"},
|
||||
{28, nullptr, "SetAutomaticApplicationDownloadFlag"},
|
||||
{25, C<&ISystemSettingsServer::GetConsoleInformationUploadFlag>, "GetConsoleInformationUploadFlag"},
|
||||
{26, C<&ISystemSettingsServer::SetConsoleInformationUploadFlag>, "SetConsoleInformationUploadFlag"},
|
||||
{27, C<&ISystemSettingsServer::GetAutomaticApplicationDownloadFlag>, "GetAutomaticApplicationDownloadFlag"},
|
||||
{28, C<&ISystemSettingsServer::SetAutomaticApplicationDownloadFlag>, "SetAutomaticApplicationDownloadFlag"},
|
||||
{29, C<&ISystemSettingsServer::GetNotificationSettings>, "GetNotificationSettings"},
|
||||
{30, C<&ISystemSettingsServer::SetNotificationSettings>, "SetNotificationSettings"},
|
||||
{31, C<&ISystemSettingsServer::GetAccountNotificationSettings>, "GetAccountNotificationSettings"},
|
||||
|
|
@ -160,8 +160,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
|
|||
{42, nullptr, "SetEdid"},
|
||||
{43, C<&ISystemSettingsServer::GetAudioOutputMode>, "GetAudioOutputMode"},
|
||||
{44, C<&ISystemSettingsServer::SetAudioOutputMode>, "SetAudioOutputMode"},
|
||||
{45, C<&ISystemSettingsServer::GetSpeakerAutoMuteFlag> , "GetSpeakerAutoMuteFlag"},
|
||||
{46, C<&ISystemSettingsServer::SetSpeakerAutoMuteFlag> , "SetSpeakerAutoMuteFlag"},
|
||||
{45, C<&ISystemSettingsServer::GetSpeakerAutoMuteFlag>, "GetSpeakerAutoMuteFlag"},
|
||||
{46, C<&ISystemSettingsServer::SetSpeakerAutoMuteFlag>, "SetSpeakerAutoMuteFlag"},
|
||||
{47, C<&ISystemSettingsServer::GetQuestFlag>, "GetQuestFlag"},
|
||||
{48, C<&ISystemSettingsServer::SetQuestFlag>, "SetQuestFlag"},
|
||||
{49, nullptr, "GetDataDeletionSettings"},
|
||||
|
|
@ -180,8 +180,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
|
|||
{62, C<&ISystemSettingsServer::GetDebugModeFlag>, "GetDebugModeFlag"},
|
||||
{63, C<&ISystemSettingsServer::GetPrimaryAlbumStorage>, "GetPrimaryAlbumStorage"},
|
||||
{64, C<&ISystemSettingsServer::SetPrimaryAlbumStorage>, "SetPrimaryAlbumStorage"},
|
||||
{65, nullptr, "GetUsb30EnableFlag"},
|
||||
{66, nullptr, "SetUsb30EnableFlag"},
|
||||
{65, C<&ISystemSettingsServer::GetUsb30EnableFlag>, "GetUsb30EnableFlag"},
|
||||
{66, C<&ISystemSettingsServer::SetUsb30EnableFlag>, "SetUsb30EnableFlag"},
|
||||
{67, C<&ISystemSettingsServer::GetBatteryLot>, "GetBatteryLot"},
|
||||
{68, C<&ISystemSettingsServer::GetSerialNumber>, "GetSerialNumber"},
|
||||
{69, C<&ISystemSettingsServer::GetNfcEnableFlag>, "GetNfcEnableFlag"},
|
||||
|
|
@ -1074,6 +1074,45 @@ Result ISystemSettingsServer::SetNfcEnableFlag(bool nfc_enable_flag) {
|
|||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemSettingsServer::GetConsoleInformationUploadFlag(Out<bool> out_flag) {
|
||||
LOG_INFO(Service_SET, "called {}", m_system_settings.console_information_upload_flag);
|
||||
*out_flag = m_system_settings.console_information_upload_flag;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemSettingsServer::SetConsoleInformationUploadFlag(bool flag) {
|
||||
LOG_INFO(Service_SET, "called {}", flag);
|
||||
m_system_settings.usb_30_enable_flag = flag;
|
||||
SetSaveNeeded();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemSettingsServer::GetAutomaticApplicationDownloadFlag(Out<bool> out_flag) {
|
||||
LOG_INFO(Service_SET, "called {}", m_system_settings.usb_30_enable_flag);
|
||||
*out_flag = m_system_settings.automatic_application_download_flag;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemSettingsServer::SetAutomaticApplicationDownloadFlag(bool flag) {
|
||||
LOG_INFO(Service_SET, "called {}", flag);
|
||||
m_system_settings.automatic_application_download_flag = flag;
|
||||
SetSaveNeeded();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemSettingsServer::GetUsb30EnableFlag(Out<bool> out_usb30_enable_flag) {
|
||||
LOG_INFO(Service_SET, "called, usb30_enable_flag={}", m_system_settings.usb_30_enable_flag);
|
||||
*out_usb30_enable_flag = m_system_settings.usb_30_enable_flag;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemSettingsServer::SetUsb30EnableFlag(bool usb30_enable_flag) {
|
||||
LOG_INFO(Service_SET, "called, usb30_enable_flag={}", usb30_enable_flag);
|
||||
m_system_settings.usb_30_enable_flag = usb30_enable_flag;
|
||||
SetSaveNeeded();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemSettingsServer::GetSleepSettings(Out<SleepSettings> out_sleep_settings) {
|
||||
LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}",
|
||||
m_system_settings.sleep_settings.flags.raw,
|
||||
|
|
|
|||
|
|
@ -109,6 +109,12 @@ public:
|
|||
Result SetPrimaryAlbumStorage(PrimaryAlbumStorage primary_album_storage);
|
||||
Result GetBatteryLot(Out<BatteryLot> out_battery_lot);
|
||||
Result GetSerialNumber(Out<SerialNumber> out_console_serial);
|
||||
Result GetConsoleInformationUploadFlag(Out<bool> out_flag);
|
||||
Result SetConsoleInformationUploadFlag(bool flag);
|
||||
Result GetAutomaticApplicationDownloadFlag(Out<bool> out_flag);
|
||||
Result SetAutomaticApplicationDownloadFlag(bool flag);
|
||||
Result GetUsb30EnableFlag(Out<bool> out_usb30_enable_flag);
|
||||
Result SetUsb30EnableFlag(bool usb30_enable_flag);
|
||||
Result GetNfcEnableFlag(Out<bool> out_nfc_enable_flag);
|
||||
Result SetNfcEnableFlag(bool nfc_enable_flag);
|
||||
Result GetSleepSettings(Out<SleepSettings> out_sleep_settings);
|
||||
|
|
|
|||
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -11,6 +14,7 @@
|
|||
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
||||
#include "core/hle/kernel/k_server_port.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/ipc_helpers.h"
|
||||
#include "core/hle/service/server_manager.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
|
@ -250,15 +254,37 @@ void SM::UnregisterService(HLERequestContext& ctx) {
|
|||
rb.Push(service_manager.UnregisterService(name));
|
||||
}
|
||||
|
||||
void SM::AtmosphereHasService(HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
std::string name(PopServiceName(rp));
|
||||
LOG_WARNING(Service_SM, "(stubbed) called with name={}", name);
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
Kernel::KClientPort* out_client_port = nullptr;
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<bool>(service_manager.GetServicePort(&out_client_port, name) == ResultSuccess);
|
||||
}
|
||||
|
||||
SM::SM(ServiceManager& service_manager_, Core::System& system_)
|
||||
: ServiceFramework{system_, "sm:", 4},
|
||||
service_manager{service_manager_}, kernel{system_.Kernel()} {
|
||||
: ServiceFramework{system_, "sm:", 4}
|
||||
, service_manager{service_manager_}
|
||||
, kernel{system_.Kernel()}
|
||||
{
|
||||
RegisterHandlers({
|
||||
{0, &SM::Initialize, "Initialize"},
|
||||
{1, &SM::GetServiceCmif, "GetService"},
|
||||
{2, &SM::RegisterServiceCmif, "RegisterService"},
|
||||
{3, &SM::UnregisterService, "UnregisterService"},
|
||||
{4, nullptr, "DetachClient"},
|
||||
// TODO: are these non-TIPC as well?
|
||||
{65000, nullptr, "AtmosphereInstallMitm"},
|
||||
{65001, nullptr, "AtmosphereUninstallMitm"},
|
||||
{65002, nullptr, "Deprecated_AtmosphereAssociatePidTidForMitm"},
|
||||
{65003, nullptr, "AtmosphereAcknowledgeMitmSession"},
|
||||
{65004, nullptr, "AtmosphereHasMitm"},
|
||||
{65005, nullptr, "AtmosphereWaitMitm"},
|
||||
{65006, nullptr, "AtmosphereDeclareFutureMitm"},
|
||||
{65100, &SM::AtmosphereHasService, "AtmosphereHasService"},
|
||||
{65101, nullptr, "AtmosphereWaitService"},
|
||||
});
|
||||
RegisterHandlersTipc({
|
||||
{0, &SM::Initialize, "Initialize"},
|
||||
|
|
@ -266,6 +292,15 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_)
|
|||
{2, &SM::RegisterServiceTipc, "RegisterService"},
|
||||
{3, &SM::UnregisterService, "UnregisterService"},
|
||||
{4, nullptr, "DetachClient"},
|
||||
{65000, nullptr, "AtmosphereInstallMitm"},
|
||||
{65001, nullptr, "AtmosphereUninstallMitm"},
|
||||
{65002, nullptr, "Deprecated_AtmosphereAssociatePidTidForMitm"},
|
||||
{65003, nullptr, "AtmosphereAcknowledgeMitmSession"},
|
||||
{65004, nullptr, "AtmosphereHasMitm"},
|
||||
{65005, nullptr, "AtmosphereWaitMitm"},
|
||||
{65006, nullptr, "AtmosphereDeclareFutureMitm"},
|
||||
{65100, &SM::AtmosphereHasService, "AtmosphereHasService"},
|
||||
{65101, nullptr, "AtmosphereWaitService"},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ private:
|
|||
void RegisterServiceCmif(HLERequestContext& ctx);
|
||||
void RegisterServiceTipc(HLERequestContext& ctx);
|
||||
void UnregisterService(HLERequestContext& ctx);
|
||||
void AtmosphereHasService(HLERequestContext& ctx);
|
||||
|
||||
Result GetServiceImpl(Kernel::KClientSession** out_client_session, HLERequestContext& ctx);
|
||||
void RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_session_count,
|
||||
|
|
|
|||
|
|
@ -55,11 +55,43 @@ enum class NetDbError : s32 {
|
|||
|
||||
static const constexpr std::array blockedDomains = {
|
||||
"srv.nintendo.net", //obvious
|
||||
"nintendo.es",
|
||||
"nintendowifi.net",
|
||||
"nintendo-europe.com",
|
||||
"nintendo.com.hk",
|
||||
"nintendo.com.au",
|
||||
"nintendo.co.kr",
|
||||
"nintendo.co.uk",
|
||||
"nintendo.co.jp",
|
||||
"nintendo.co.nz",
|
||||
"nintendo.co.za",
|
||||
"nintendo.com",
|
||||
"nintendo.jp",
|
||||
"nintendo.tw",
|
||||
"nintendo.at",
|
||||
"nintendo.be",
|
||||
"nintendo.dk",
|
||||
"nintendo.de",
|
||||
"nintendo.fi",
|
||||
"nintendo.fr",
|
||||
"nintendo.gr",
|
||||
"nintendo.hu",
|
||||
"nintendo.it",
|
||||
"nintendo.nl",
|
||||
"nintendo.no",
|
||||
"nintendo.pt",
|
||||
"nintendo.ru",
|
||||
"nintendo.ch",
|
||||
"nintendo.se",
|
||||
"nintendoswitch.com.cn",
|
||||
"nintendoswitch.com",
|
||||
"sun.hac.lp1.d4c.nintendo.net",
|
||||
"phoenix-api.wbagora.com", //hogwarts legacy
|
||||
"battle.net",
|
||||
"microsoft.com", //minecraft dungeons + other games
|
||||
"mojang.com",
|
||||
"xboxlive.com",
|
||||
"api.epicgames.dev", // marvel cosmic invasion +?
|
||||
"minecraftservices.com"
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -65,10 +65,121 @@ enum class Type : u32 {
|
|||
};
|
||||
|
||||
enum class Protocol : u32 {
|
||||
Unspecified = 0,
|
||||
IP = 0,
|
||||
ICMP = 1,
|
||||
TCP = 6,
|
||||
UDP = 17,
|
||||
//
|
||||
IPV6 = 41,
|
||||
RAW = 255,
|
||||
//
|
||||
HOPOPTS = 0,
|
||||
IGMP = 2,
|
||||
GGP = 3,
|
||||
IPV4 = 4,
|
||||
ST = 7,
|
||||
EGP = 8,
|
||||
PIGP = 9,
|
||||
RCCMON = 10,
|
||||
NVPII = 11,
|
||||
PUP = 12,
|
||||
ARGUS = 13,
|
||||
EMCON = 14,
|
||||
XNET = 15,
|
||||
CHAOS = 16,
|
||||
MUX = 18,
|
||||
MEAS = 19,
|
||||
HMP = 20,
|
||||
PRM = 21,
|
||||
IDP = 22,
|
||||
TRUNK1 = 23,
|
||||
TRUNK2 = 24,
|
||||
LEAF1 = 25,
|
||||
LEAF2 = 26,
|
||||
RDP = 27,
|
||||
IRTP = 28,
|
||||
TP = 29,
|
||||
BLT = 30,
|
||||
NSP = 31,
|
||||
INP = 32,
|
||||
DCCP = 33,
|
||||
//3PC = 34,
|
||||
IDPR = 35,
|
||||
XTP = 36,
|
||||
DDP = 37,
|
||||
CMTP = 38,
|
||||
TPXX = 39,
|
||||
IL = 40,
|
||||
SDRP = 42,
|
||||
ROUTING = 43,
|
||||
FRAGMENT = 44,
|
||||
IDRP = 45,
|
||||
RSVP = 46,
|
||||
GRE = 47,
|
||||
MHRP = 48,
|
||||
BHA = 49,
|
||||
ESP = 50,
|
||||
AH = 51,
|
||||
INLSP = 52,
|
||||
SWIPE = 53,
|
||||
NHRP = 54,
|
||||
MOBILE = 55,
|
||||
TLSP = 56,
|
||||
SKIP = 57,
|
||||
ICMPV6 = 58,
|
||||
NONE = 59,
|
||||
DSTOPTS = 60,
|
||||
AHIP = 61,
|
||||
CFTP = 62,
|
||||
HELLO = 63,
|
||||
SATEXPAK = 64,
|
||||
KRYPTOLAN = 65,
|
||||
RVD = 66,
|
||||
IPPC = 67,
|
||||
ADFS = 68,
|
||||
SATMON = 69,
|
||||
VISA = 70,
|
||||
IPCV = 71,
|
||||
CPNX = 72,
|
||||
CPHB = 73,
|
||||
WSN = 74,
|
||||
PVP = 75,
|
||||
BRSATMON = 76,
|
||||
ND = 77,
|
||||
WBMON = 78,
|
||||
WBEXPAK = 79,
|
||||
EON = 80,
|
||||
VMTP = 81,
|
||||
SVMTP = 82,
|
||||
VINES = 83,
|
||||
TTP = 84,
|
||||
IGP = 85,
|
||||
DGP = 86,
|
||||
TCF = 87,
|
||||
IGRP = 88,
|
||||
OSPFIGP = 89,
|
||||
SRPC = 90,
|
||||
LARP = 91,
|
||||
MTP = 92,
|
||||
AX25 = 93,
|
||||
IPEIP = 94,
|
||||
MICP = 95,
|
||||
SCCSP = 96,
|
||||
ETHERIP = 97,
|
||||
ENCAP = 98,
|
||||
APES = 99,
|
||||
GMTP = 100,
|
||||
IPCOMP = 108,
|
||||
SCTP = 132,
|
||||
MH = 135,
|
||||
UDPLITE = 136,
|
||||
HIP = 139,
|
||||
SHIM6 = 140,
|
||||
PIM = 103,
|
||||
CARP = 112,
|
||||
PGM = 113,
|
||||
MPLS = 137,
|
||||
PFSYNC = 240,
|
||||
};
|
||||
|
||||
enum class SocketLevel : u32 {
|
||||
|
|
|
|||
|
|
@ -175,49 +175,151 @@ Network::Type Translate(Type type) {
|
|||
|
||||
Type Translate(Network::Type type) {
|
||||
switch (type) {
|
||||
case Network::Type::Unspecified:
|
||||
return Type::Unspecified;
|
||||
case Network::Type::STREAM:
|
||||
return Type::STREAM;
|
||||
case Network::Type::DGRAM:
|
||||
return Type::DGRAM;
|
||||
case Network::Type::RAW:
|
||||
return Type::RAW;
|
||||
case Network::Type::SEQPACKET:
|
||||
return Type::SEQPACKET;
|
||||
case Network::Type::Unspecified: return Type::Unspecified;
|
||||
case Network::Type::STREAM: return Type::STREAM;
|
||||
case Network::Type::DGRAM: return Type::DGRAM;
|
||||
case Network::Type::RAW: return Type::RAW;
|
||||
case Network::Type::SEQPACKET: return Type::SEQPACKET;
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented type={}", type);
|
||||
return Type{};
|
||||
}
|
||||
}
|
||||
|
||||
Network::Protocol Translate(Protocol protocol) {
|
||||
#define NETWORK_PROTOCOL_TRANSLATE_LIST \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TCP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(UDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPV6) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RAW) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IGMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(GGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPV4) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ST) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(EGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PIGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RCCMON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(NVPII) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PUP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ARGUS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(EMCON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(XNET) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CHAOS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MUX) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MEAS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(HMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PRM) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TRUNK1) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TRUNK2) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(LEAF1) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(LEAF2) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IRTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(BLT) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(NSP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(INP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DCCP) \
|
||||
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(3PC)*/ \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IDPR) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(XTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CMTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TPXX) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IL) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SDRP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ROUTING) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(FRAGMENT) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IDRP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RSVP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(GRE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MHRP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(BHA) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ESP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(AH) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(INLSP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SWIPE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(NHRP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MOBILE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TLSP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SKIP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMPV6) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(NONE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DSTOPTS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(AHIP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CFTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(HELLO) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SATEXPAK) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(KRYPTOLAN) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RVD) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPPC) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ADFS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SATMON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(VISA) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPCV) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CPNX) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CPHB) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(WSN) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PVP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(BRSATMON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ND) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(WBMON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(WBEXPAK) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(EON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(VMTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SVMTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(VINES) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TCF) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IGRP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(OSPFIGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SRPC) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(LARP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(AX25) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPEIP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MICP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SCCSP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ETHERIP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ENCAP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(APES) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(GMTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPCOMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SCTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MH) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(UDPLITE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(HIP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SHIM6) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PIM) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CARP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PGM) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MPLS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PFSYNC)
|
||||
[[nodiscard]] Network::Protocol Translate(Protocol protocol) {
|
||||
switch (protocol) {
|
||||
case Protocol::Unspecified:
|
||||
return Network::Protocol::Unspecified;
|
||||
case Protocol::TCP:
|
||||
return Network::Protocol::TCP;
|
||||
case Protocol::UDP:
|
||||
return Network::Protocol::UDP;
|
||||
#define NETWORK_PROTOCOL_TRANSLATE_ELEM(name) case Protocol::name: return Network::Protocol::name;
|
||||
NETWORK_PROTOCOL_TRANSLATE_LIST
|
||||
#undef NETWORK_PROTOCOL_TRANSLATE_ELEM
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol);
|
||||
return Network::Protocol::Unspecified;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
Protocol Translate(Network::Protocol protocol) {
|
||||
[[nodiscard]] Protocol Translate(Network::Protocol protocol) {
|
||||
switch (protocol) {
|
||||
case Network::Protocol::Unspecified:
|
||||
return Protocol::Unspecified;
|
||||
case Network::Protocol::TCP:
|
||||
return Protocol::TCP;
|
||||
case Network::Protocol::UDP:
|
||||
return Protocol::UDP;
|
||||
#define NETWORK_PROTOCOL_TRANSLATE_ELEM(name) case Network::Protocol::name: return Protocol::name;
|
||||
NETWORK_PROTOCOL_TRANSLATE_LIST
|
||||
#undef NETWORK_PROTOCOL_TRANSLATE_ELEM
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol);
|
||||
return Protocol::Unspecified;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
#undef NETWORK_PROTOCOL_TRANSLATE_LIST
|
||||
|
||||
Network::PollEvents Translate(PollEvents flags) {
|
||||
Network::PollEvents result{};
|
||||
|
|
|
|||
137
src/core/hle/service/ulsf/ulsf.cpp
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <memory>
|
||||
#include "core/hle/result.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/ipc_helpers.h"
|
||||
#include "core/hle/service/ulsf/ulsf.h"
|
||||
#include "core/hle/service/server_manager.h"
|
||||
|
||||
namespace Service::ULSF {
|
||||
|
||||
ULSF_U::ULSF_U(Core::System& system_) : ServiceFramework{system_, "ulsf:u"} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ULSF_U::GetVersion, "GetVersion"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
ULSF_U::~ULSF_U() = default;
|
||||
|
||||
// Result ULSF_U::GetVersion(Out<ULauncherVersion> out_version) {
|
||||
// LOG_WARNING(Service_SM, "(stubbed)");
|
||||
// *out_version = {};
|
||||
// R_SUCCEED();
|
||||
// }
|
||||
|
||||
void ULSF_U::GetVersion(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_SM, "(stubbed)");
|
||||
ULauncherVersion version{1, 6, 7};
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw(version);
|
||||
}
|
||||
|
||||
enum class MenuMessage : u32 {
|
||||
Invalid,
|
||||
HomeRequest,
|
||||
SdCardEjected,
|
||||
GameCardMountFailure,
|
||||
PreviousLaunchFailure,
|
||||
ChosenHomebrew,
|
||||
FinishedSleep,
|
||||
ApplicationRecordsChanged,
|
||||
ApplicationVerifyProgress,
|
||||
ApplicationVerifyResult
|
||||
};
|
||||
struct MenuMessageContext {
|
||||
MenuMessage msg;
|
||||
union {
|
||||
struct {
|
||||
Result mount_rc;
|
||||
} gc_mount_failure;
|
||||
struct {
|
||||
char nro_path[0x301];
|
||||
} chosen_hb;
|
||||
struct {
|
||||
bool records_added_or_deleted;
|
||||
} app_records_changed;
|
||||
struct {
|
||||
u64 app_id;
|
||||
u64 done;
|
||||
u64 total;
|
||||
} app_verify_progress;
|
||||
struct {
|
||||
u64 app_id;
|
||||
Result rc;
|
||||
Result detail_rc;
|
||||
} app_verify_rc;
|
||||
};
|
||||
};
|
||||
|
||||
class ULSF_P final : public ServiceFramework<ULSF_P> {
|
||||
public:
|
||||
explicit ULSF_P(Core::System& system_) : ServiceFramework{system_, "ulsf:p"} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, C<&ULSF_P::Initialize>, "Initialize"},
|
||||
{1, C<&ULSF_P::TryPopMessageContext>, "TryPopMessageContext"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
~ULSF_P() = default;
|
||||
|
||||
Result Initialize(u64 pid) {
|
||||
LOG_WARNING(Service_SM, "(stubbed) pid={}", pid);
|
||||
R_SUCCEED();
|
||||
}
|
||||
Result TryPopMessageContext(OutLargeData<MenuMessageContext, BufferAttr_HipcMapAlias> out_menu_message) {
|
||||
//LOG_WARNING(Service_SM, "(stubbed)");
|
||||
// *out_menu_message = {};
|
||||
// R_SUCCEED();
|
||||
R_THROW(Kernel::ResultInvalidAddress);
|
||||
}
|
||||
};
|
||||
|
||||
class AVM final : public ServiceFramework<AVM> {
|
||||
public:
|
||||
explicit AVM(Core::System& system_): ServiceFramework{system_, "avm"} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &AVM::Cmd0, "Cmd0"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
~AVM() = default;
|
||||
void Cmd0(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_SM, "(stubbed)");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
};
|
||||
class WLAN final : public ServiceFramework<WLAN> {
|
||||
public:
|
||||
explicit WLAN(Core::System& system_): ServiceFramework{system_, "wlan"} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &WLAN::Cmd0, "Cmd0"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
~WLAN() = default;
|
||||
void Cmd0(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_SM, "(stubbed)");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
};
|
||||
|
||||
void LoopProcess(Core::System& system) {
|
||||
auto server_manager = std::make_unique<ServerManager>(system);
|
||||
server_manager->RegisterNamedService("ulsf:u", std::make_shared<ULSF_U>(system));
|
||||
server_manager->RegisterNamedService("ulsf:p", std::make_shared<ULSF_P>(system));
|
||||
|
||||
server_manager->RegisterNamedService("avm", std::make_shared<AVM>(system));
|
||||
server_manager->RegisterNamedService("wlan", std::make_shared<WLAN>(system));
|
||||
ServerManager::RunServer(std::move(server_manager));
|
||||
}
|
||||
|
||||
}
|
||||
28
src/core/hle/service/ulsf/ulsf.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::ULSF {
|
||||
|
||||
struct ULauncherVersion {
|
||||
u8 major;
|
||||
u8 minor;
|
||||
u8 micro;
|
||||
};
|
||||
|
||||
class ULSF_U final : public ServiceFramework<ULSF_U> {
|
||||
public:
|
||||
explicit ULSF_U(Core::System& system_);
|
||||
~ULSF_U();
|
||||
//Result GetVersion(Out<ULauncherVersion> out_version);
|
||||
void GetVersion(HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
void LoopProcess(Core::System& system);
|
||||
|
||||
}
|
||||
|
|
@ -326,52 +326,37 @@ Errno GetAndLogLastError(CallType call_type = CallType::Other) {
|
|||
|
||||
GetAddrInfoError TranslateGetAddrInfoErrorFromNative(int gai_err) {
|
||||
switch (gai_err) {
|
||||
case 0:
|
||||
return GetAddrInfoError::SUCCESS;
|
||||
case 0: return GetAddrInfoError::SUCCESS;
|
||||
case EAI_AGAIN: return GetAddrInfoError::AGAIN;
|
||||
case EAI_BADFLAGS: return GetAddrInfoError::BADFLAGS;
|
||||
case EAI_FAIL: return GetAddrInfoError::FAIL;
|
||||
case EAI_FAMILY: return GetAddrInfoError::FAMILY;
|
||||
case EAI_MEMORY: return GetAddrInfoError::MEMORY;
|
||||
case EAI_NONAME: return GetAddrInfoError::NONAME;
|
||||
case EAI_SERVICE: return GetAddrInfoError::SERVICE;
|
||||
case EAI_SOCKTYPE: return GetAddrInfoError::SOCKTYPE;
|
||||
// These codes may not be defined on all systems:
|
||||
#ifdef EAI_ADDRFAMILY
|
||||
case EAI_ADDRFAMILY:
|
||||
return GetAddrInfoError::ADDRFAMILY;
|
||||
case EAI_ADDRFAMILY: return GetAddrInfoError::ADDRFAMILY;
|
||||
#endif
|
||||
case EAI_AGAIN:
|
||||
return GetAddrInfoError::AGAIN;
|
||||
case EAI_BADFLAGS:
|
||||
return GetAddrInfoError::BADFLAGS;
|
||||
case EAI_FAIL:
|
||||
return GetAddrInfoError::FAIL;
|
||||
case EAI_FAMILY:
|
||||
return GetAddrInfoError::FAMILY;
|
||||
case EAI_MEMORY:
|
||||
return GetAddrInfoError::MEMORY;
|
||||
case EAI_NONAME:
|
||||
return GetAddrInfoError::NONAME;
|
||||
case EAI_SERVICE:
|
||||
return GetAddrInfoError::SERVICE;
|
||||
case EAI_SOCKTYPE:
|
||||
return GetAddrInfoError::SOCKTYPE;
|
||||
// These codes may not be defined on all systems:
|
||||
#ifdef EAI_SYSTEM
|
||||
case EAI_SYSTEM:
|
||||
return GetAddrInfoError::SYSTEM;
|
||||
case EAI_SYSTEM: return GetAddrInfoError::SYSTEM;
|
||||
#endif
|
||||
#ifdef EAI_BADHINTS
|
||||
case EAI_BADHINTS:
|
||||
return GetAddrInfoError::BADHINTS;
|
||||
case EAI_BADHINTS: return GetAddrInfoError::BADHINTS;
|
||||
#endif
|
||||
#ifdef EAI_PROTOCOL
|
||||
case EAI_PROTOCOL:
|
||||
return GetAddrInfoError::PROTOCOL;
|
||||
case EAI_PROTOCOL: return GetAddrInfoError::PROTOCOL;
|
||||
#endif
|
||||
#ifdef EAI_OVERFLOW
|
||||
case EAI_OVERFLOW:
|
||||
return GetAddrInfoError::OVERFLOW_;
|
||||
case EAI_OVERFLOW: return GetAddrInfoError::OVERFLOW_;
|
||||
#endif
|
||||
default:
|
||||
#ifdef EAI_NODATA
|
||||
// This can't be a case statement because it would create a duplicate
|
||||
// case on Windows where EAI_NODATA is an alias for EAI_NONAME.
|
||||
if (gai_err == EAI_NODATA) {
|
||||
if (gai_err == EAI_NODATA)
|
||||
return GetAddrInfoError::NODATA;
|
||||
}
|
||||
#endif
|
||||
return GetAddrInfoError::OTHER;
|
||||
}
|
||||
|
|
@ -405,14 +390,10 @@ Type TranslateTypeFromNative(int type) {
|
|||
switch (type) {
|
||||
case 0:
|
||||
return Type::Unspecified;
|
||||
case SOCK_STREAM:
|
||||
return Type::STREAM;
|
||||
case SOCK_DGRAM:
|
||||
return Type::DGRAM;
|
||||
case SOCK_RAW:
|
||||
return Type::RAW;
|
||||
case SOCK_SEQPACKET:
|
||||
return Type::SEQPACKET;
|
||||
case SOCK_STREAM: return Type::STREAM;
|
||||
case SOCK_DGRAM: return Type::DGRAM;
|
||||
case SOCK_RAW: return Type::RAW;
|
||||
case SOCK_SEQPACKET: return Type::SEQPACKET;
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented type={}", type);
|
||||
return Type::STREAM;
|
||||
|
|
@ -423,55 +404,227 @@ int TranslateTypeToNative(Type type) {
|
|||
switch (type) {
|
||||
case Type::Unspecified:
|
||||
return 0;
|
||||
case Type::STREAM:
|
||||
return SOCK_STREAM;
|
||||
case Type::DGRAM:
|
||||
return SOCK_DGRAM;
|
||||
case Type::RAW:
|
||||
return SOCK_RAW;
|
||||
case Type::STREAM: return SOCK_STREAM;
|
||||
case Type::DGRAM: return SOCK_DGRAM;
|
||||
case Type::RAW: return SOCK_RAW;
|
||||
case Type::SEQPACKET: return SOCK_SEQPACKET;
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented type={}", type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Protocol TranslateProtocolFromNative(int protocol) {
|
||||
// Some of those protocols may not be supported on some platforms
|
||||
// It doesn't really matter, except that some homebrew may not work correctly
|
||||
// Official software uses TCP & UDP mainly, SCTP is used by some homebrew as well
|
||||
#ifdef __FreeBSD__
|
||||
#define NETWORK_PROTOCOL_TRANSLATE_LIST \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TCP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(UDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPV6) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RAW) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IGMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(GGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPV4) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ST) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(EGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PIGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RCCMON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(NVPII) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PUP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ARGUS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(EMCON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(XNET) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CHAOS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MUX) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MEAS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(HMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PRM) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TRUNK1) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TRUNK2) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(LEAF1) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(LEAF2) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IRTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(BLT) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(NSP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(INP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DCCP) \
|
||||
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(3PC)*/ \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IDPR) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(XTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CMTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TPXX) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IL) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SDRP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ROUTING) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(FRAGMENT) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IDRP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RSVP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(GRE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MHRP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(BHA) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ESP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(AH) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(INLSP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SWIPE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(NHRP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MOBILE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TLSP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SKIP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMPV6) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(NONE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DSTOPTS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(AHIP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CFTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(HELLO) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SATEXPAK) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(KRYPTOLAN) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RVD) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPPC) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ADFS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SATMON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(VISA) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPCV) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CPNX) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CPHB) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(WSN) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PVP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(BRSATMON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ND) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(WBMON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(WBEXPAK) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(EON) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(VMTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SVMTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(VINES) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TCF) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IGRP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(OSPFIGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SRPC) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(LARP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(AX25) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPEIP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MICP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SCCSP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ETHERIP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ENCAP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(APES) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(GMTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPCOMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SCTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MH) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(UDPLITE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(HIP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SHIM6) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PIM) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(CARP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PGM) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MPLS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PFSYNC)
|
||||
#elif defined(__linux__)
|
||||
// Other platforms get fucked
|
||||
#define NETWORK_PROTOCOL_TRANSLATE_LIST \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IP) \
|
||||
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(HOPOPTS)*/ \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IGMP) \
|
||||
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(IPIP)*/ \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TCP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(EGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PUP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(UDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DCCP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPV6) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ROUTING) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(FRAGMENT) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RSVP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(GRE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ESP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(AH) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMPV6) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(NONE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DSTOPTS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ENCAP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PIM) \
|
||||
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(COMP)*/ \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SCTP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(UDPLITE)
|
||||
#elif defined(_WIN32)
|
||||
#define NETWORK_PROTOCOL_TRANSLATE_LIST \
|
||||
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(HOPOPTS)*/ \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IGMP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(GGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPV4) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ST) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TCP) \
|
||||
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(CBT)*/ \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(EGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IGP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PUP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(UDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(RDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPV6) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ROUTING) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(FRAGMENT) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ESP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(AH) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMPV6) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(NONE) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(DSTOPTS) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(ND) \
|
||||
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(ICLFXBM)*/ \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PIM) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PGM) \
|
||||
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(L2TP)*/ \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SCTP)
|
||||
#else
|
||||
#define NETWORK_PROTOCOL_TRANSLATE_LIST \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(TCP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(UDP) \
|
||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(SCTP)
|
||||
#endif
|
||||
[[nodiscard]] Protocol TranslateProtocolFromNative(u32 protocol) {
|
||||
switch (protocol) {
|
||||
case 0:
|
||||
return Protocol::Unspecified;
|
||||
case IPPROTO_TCP:
|
||||
return Protocol::TCP;
|
||||
case IPPROTO_UDP:
|
||||
return Protocol::UDP;
|
||||
#define NETWORK_PROTOCOL_TRANSLATE_ELEM(x) case IPPROTO_##x: return Protocol::x;
|
||||
NETWORK_PROTOCOL_TRANSLATE_LIST
|
||||
#undef NETWORK_PROTOCOL_TRANSLATE_ELEM
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol);
|
||||
return Protocol::Unspecified;
|
||||
return Protocol::IP;
|
||||
}
|
||||
}
|
||||
|
||||
int TranslateProtocolToNative(Protocol protocol) {
|
||||
[[nodiscard]] u32 TranslateProtocolToNative(Protocol protocol) {
|
||||
switch (protocol) {
|
||||
case Protocol::Unspecified:
|
||||
return 0;
|
||||
case Protocol::TCP:
|
||||
return IPPROTO_TCP;
|
||||
case Protocol::UDP:
|
||||
return IPPROTO_UDP;
|
||||
#define NETWORK_PROTOCOL_TRANSLATE_ELEM(x) case Protocol::x: return IPPROTO_##x;
|
||||
NETWORK_PROTOCOL_TRANSLATE_LIST
|
||||
#undef NETWORK_PROTOCOL_TRANSLATE_ELEM
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#undef NETWORK_PROTOCOL_TRANSLATE_LIST
|
||||
|
||||
SockAddrIn TranslateToSockAddrIn(sockaddr_in input, size_t input_len) {
|
||||
SockAddrIn result;
|
||||
|
||||
SockAddrIn result{};
|
||||
result.family = TranslateDomainFromNative(input.sin_family);
|
||||
|
||||
result.portno = ntohs(input.sin_port);
|
||||
|
||||
result.ip = TranslateIPv4(input.sin_addr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -685,8 +838,7 @@ Errno Socket::SetSockOpt(SOCKET fd_so, int option, T value) {
|
|||
}
|
||||
|
||||
Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
|
||||
fd = socket(TranslateDomainToNative(domain), TranslateTypeToNative(type),
|
||||
TranslateProtocolToNative(protocol));
|
||||
fd = socket(TranslateDomainToNative(domain), TranslateTypeToNative(type), TranslateProtocolToNative(protocol));
|
||||
if (fd != INVALID_SOCKET) {
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "core/file_sys/content_archive.h"
|
||||
#include "core/file_sys/control_metadata.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/program_metadata.h"
|
||||
#include "core/file_sys/romfs_factory.h"
|
||||
#include "core/hle/kernel/k_page_table.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
|
|
@ -204,7 +205,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
|||
|
||||
const bool should_pass_arguments = std::strcmp(module, "rtld") == 0;
|
||||
const auto tentative_next_load_addr = AppLoader_NSO::LoadModule(
|
||||
process, system, *module_file, code_size, should_pass_arguments, false, {},
|
||||
process, system, *module_file, code_size, should_pass_arguments, false, nullptr, metadata, {},
|
||||
patch_ctx.GetPatchers(), patch_ctx.GetLastIndex());
|
||||
if (!tentative_next_load_addr) {
|
||||
return {ResultStatus::ErrorLoadingNSO, {}};
|
||||
|
|
@ -251,8 +252,9 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
|||
|
||||
const VAddr load_addr{next_load_addr};
|
||||
const bool should_pass_arguments = std::strcmp(module, "rtld") == 0;
|
||||
FileSys::ProgramMetadata tmp_metadata{};
|
||||
const auto tentative_next_load_addr = AppLoader_NSO::LoadModule(
|
||||
process, system, *module_file, load_addr, should_pass_arguments, true, pm,
|
||||
process, system, *module_file, load_addr, should_pass_arguments, true, nullptr, metadata, pm,
|
||||
patch_ctx.GetPatchers(), patch_ctx.GetIndex(i));
|
||||
if (!tentative_next_load_addr) {
|
||||
return {ResultStatus::ErrorLoadingNSO, {}};
|
||||
|
|
|
|||
|
|
@ -17,10 +17,14 @@
|
|||
#include "common/swap.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/romfs_factory.h"
|
||||
#include "core/file_sys/vfs/vfs_types.h"
|
||||
#include "core/hle/kernel/code_set.h"
|
||||
#include "core/hle/kernel/k_page_table.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_thread.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/loader/nso.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
|
|
@ -66,7 +70,7 @@ FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& in_file) {
|
|||
return FileType::NSO;
|
||||
}
|
||||
|
||||
std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::System& system, const FileSys::VfsFile& nso_file, VAddr load_base, bool should_pass_arguments, bool load_into_process, std::optional<FileSys::PatchManager> pm, std::vector<Core::NCE::Patcher>* patches, s32 patch_index) {
|
||||
std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::System& system, const FileSys::VfsFile& nso_file, const VAddr load_base, const bool should_pass_arguments, const bool load_into_process, VAddr* out_load_base, FileSys::ProgramMetadata metadata, std::optional<FileSys::PatchManager> pm, std::vector<Core::NCE::Patcher>* patches, s32 patch_index) {
|
||||
if (nso_file.GetSize() < sizeof(NSOHeader))
|
||||
return std::nullopt;
|
||||
NSOHeader nso_header{};
|
||||
|
|
@ -216,9 +220,19 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
|
|||
}
|
||||
}
|
||||
|
||||
const bool is_hbl = true;
|
||||
if (process
|
||||
.LoadFromMetadata(metadata, image_size, 0, 0, is_hbl)
|
||||
.IsError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto const new_load_base = process.GetEntryPoint().GetValue();
|
||||
if (out_load_base)
|
||||
*out_load_base = new_load_base; // no change
|
||||
// Load codeset for current process
|
||||
process.LoadModule(std::move(codeset), load_base);
|
||||
return load_base + image_size;
|
||||
process.LoadModule(std::move(codeset), new_load_base);
|
||||
return new_load_base + image_size;
|
||||
}
|
||||
|
||||
AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::System& system) {
|
||||
|
|
@ -226,20 +240,34 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S
|
|||
return {ResultStatus::ErrorAlreadyLoaded, {}};
|
||||
}
|
||||
|
||||
modules.clear();
|
||||
FileSys::VirtualFile npdm_file{};
|
||||
metadata = FileSys::ProgramMetadata::GetDefault();
|
||||
if (auto const dir = file->GetContainingDirectory()) {
|
||||
npdm_file = dir->GetFile("main.npdm");
|
||||
if (npdm_file) {
|
||||
metadata.Load(npdm_file);
|
||||
}
|
||||
}
|
||||
|
||||
modules.clear();
|
||||
// Load module
|
||||
const VAddr base_address = GetInteger(process.GetEntryPoint());
|
||||
if (!LoadModule(process, system, *file, base_address, true, true)) {
|
||||
VAddr base_address = GetInteger(process.GetEntryPoint());
|
||||
if (!LoadModule(process, system, *file, base_address, true, true, &base_address, metadata)) {
|
||||
return {ResultStatus::ErrorLoadingNSO, {}};
|
||||
}
|
||||
|
||||
modules.insert_or_assign(base_address, file->GetName());
|
||||
LOG_DEBUG(Loader, "loaded module {} @ {:#X}", file->GetName(), base_address);
|
||||
|
||||
if (npdm_file) {
|
||||
LOG_WARNING(Loader, "creating associated rom-fs factories for likely standalone NSO");
|
||||
u64 program_id{};
|
||||
ReadProgramId(program_id);
|
||||
system.GetFileSystemController().RegisterProcess(process.GetProcessId(), program_id, std::make_unique<FileSys::RomFSFactory>(*this, system.GetContentProvider(), system.GetFileSystemController()));
|
||||
}
|
||||
|
||||
is_loaded = true;
|
||||
return {ResultStatus::Success, LoadParameters{Kernel::KThread::DefaultThreadPriority,
|
||||
Core::Memory::DEFAULT_STACK_SIZE}};
|
||||
return {ResultStatus::Success, LoadParameters{Kernel::KThread::DefaultThreadPriority, Core::Memory::DEFAULT_STACK_SIZE}};
|
||||
}
|
||||
|
||||
ResultStatus AppLoader_NSO::ReadNSOModules(Modules& out_modules) {
|
||||
|
|
@ -247,4 +275,18 @@ ResultStatus AppLoader_NSO::ReadNSOModules(Modules& out_modules) {
|
|||
return ResultStatus::Success;
|
||||
}
|
||||
|
||||
ResultStatus AppLoader_NSO::ReadProgramId(u64& out_program_id) {
|
||||
if (metadata.GetTitleID() == 0)
|
||||
return ResultStatus::ErrorNoControl;
|
||||
out_program_id = metadata.GetTitleID();
|
||||
return ResultStatus::Success;
|
||||
}
|
||||
|
||||
ResultStatus AppLoader_NSO::ReadTitle(std::string& out_title) {
|
||||
auto const raw_name = metadata.GetName();
|
||||
out_title.resize(raw_name.size());
|
||||
std::memcpy(out_title.data(), raw_name.data(), raw_name.size());
|
||||
return ResultStatus::Success;
|
||||
}
|
||||
|
||||
} // namespace Loader
|
||||
|
|
|
|||