Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 84b1a6ebf0 | |||
| 152c9f7a7b | |||
| f8c02e20f6 | |||
| 6ea6198ba7 | |||
| 7b50ca91d9 |
@@ -1,22 +0,0 @@
|
|||||||
#!/bin/sh -e
|
|
||||||
|
|
||||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
# SPDX-FileCopyrightText: Copyright 2026 crueter
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
_svg=dev.eden_emu.eden.svg
|
|
||||||
_icon=dist/eden.icon
|
|
||||||
_composed="$_icon/Assets/$_svg"
|
|
||||||
_svg="dist/$_svg"
|
|
||||||
|
|
||||||
rm "$_composed"
|
|
||||||
cp "$_svg" "$_composed"
|
|
||||||
|
|
||||||
xcrun actool "$_icon" \
|
|
||||||
--compile dist \
|
|
||||||
--platform macosx \
|
|
||||||
--minimum-deployment-target 11.0 \
|
|
||||||
--app-icon eden \
|
|
||||||
--output-partial-info-plist /dev/null
|
|
||||||
@@ -3,7 +3,8 @@ name: tx-pull
|
|||||||
on:
|
on:
|
||||||
# monday, wednesday, saturday at 2pm
|
# monday, wednesday, saturday at 2pm
|
||||||
schedule:
|
schedule:
|
||||||
cron: '0 14 * * 1,3,6'
|
cron:
|
||||||
|
- '0 14 * * 1,3,6'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -58,3 +59,4 @@ jobs:
|
|||||||
-H 'Authorization: Bearer ${{ secrets.CI_FJ_TOKEN }}' \
|
-H 'Authorization: Bearer ${{ secrets.CI_FJ_TOKEN }}' \
|
||||||
-H 'Content-Type: application/json' \
|
-H 'Content-Type: application/json' \
|
||||||
-d "@data.json" --fail
|
-d "@data.json" --fail
|
||||||
|
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
diff --git a/include/mcl/assert.hpp b/include/mcl/assert.hpp
|
||||||
|
index f77dbe7..9ec0b9c 100644
|
||||||
|
--- a/include/mcl/assert.hpp
|
||||||
|
+++ b/include/mcl/assert.hpp
|
||||||
|
@@ -23,8 +23,11 @@ template<typename... Ts>
|
||||||
|
|
||||||
|
} // namespace mcl::detail
|
||||||
|
|
||||||
|
+#ifndef UNREACHABLE
|
||||||
|
#define UNREACHABLE() ASSERT_FALSE("Unreachable code!")
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
+#ifndef ASSERT
|
||||||
|
#define ASSERT(expr) \
|
||||||
|
[&] { \
|
||||||
|
if (std::is_constant_evaluated()) { \
|
||||||
|
@@ -37,7 +40,9 @@ template<typename... Ts>
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}()
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
+#ifndef ASSERT_MSG
|
||||||
|
#define ASSERT_MSG(expr, ...) \
|
||||||
|
[&] { \
|
||||||
|
if (std::is_constant_evaluated()) { \
|
||||||
|
@@ -50,13 +55,24 @@ template<typename... Ts>
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}()
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
+#ifndef ASSERT_FALSE
|
||||||
|
#define ASSERT_FALSE(...) ::mcl::detail::assert_terminate("false", __VA_ARGS__)
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#if defined(NDEBUG) || defined(MCL_IGNORE_ASSERTS)
|
||||||
|
-# define DEBUG_ASSERT(expr) ASSUME(expr)
|
||||||
|
-# define DEBUG_ASSERT_MSG(expr, ...) ASSUME(expr)
|
||||||
|
+# ifndef DEBUG_ASSERT
|
||||||
|
+# define DEBUG_ASSERT(expr) ASSUME(expr)
|
||||||
|
+# endif
|
||||||
|
+# ifndef DEBUG_ASSERT_MSG
|
||||||
|
+# define DEBUG_ASSERT_MSG(expr, ...) ASSUME(expr)
|
||||||
|
+# endif
|
||||||
|
#else
|
||||||
|
-# define DEBUG_ASSERT(expr) ASSERT(expr)
|
||||||
|
-# define DEBUG_ASSERT_MSG(expr, ...) ASSERT_MSG(expr, __VA_ARGS__)
|
||||||
|
+# ifndef DEBUG_ASSERT
|
||||||
|
+# define DEBUG_ASSERT(expr) ASSERT(expr)
|
||||||
|
+# endif
|
||||||
|
+# ifndef DEBUG_ASSERT_MSG
|
||||||
|
+# define DEBUG_ASSERT_MSG(expr, ...) ASSERT_MSG(expr, __VA_ARGS__)
|
||||||
|
+# endif
|
||||||
|
#endif
|
||||||
@@ -158,8 +158,7 @@ if (CXX_CLANG_CL)
|
|||||||
if (ARCHITECTURE_x86_64)
|
if (ARCHITECTURE_x86_64)
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-msse4.1>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-msse4.1>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-mcx16>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-mcx16>)
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -402,8 +401,7 @@ if (Boost_ADDED)
|
|||||||
target_compile_options(boost_icl INTERFACE $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-shadow>)
|
target_compile_options(boost_icl INTERFACE $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-shadow>)
|
||||||
target_compile_options(boost_asio INTERFACE
|
target_compile_options(boost_asio INTERFACE
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-conversion>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-conversion>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-fallthrough>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-fallthrough>)
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -441,9 +439,7 @@ if (NOT YUZU_STATIC_ROOM)
|
|||||||
|
|
||||||
if (Opus_ADDED)
|
if (Opus_ADDED)
|
||||||
if (MSVC AND CXX_CLANG)
|
if (MSVC AND CXX_CLANG)
|
||||||
target_compile_options(opus PRIVATE
|
target_compile_options(opus PRIVATE $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-function-declaration>)
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-function-declaration>
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -486,10 +482,10 @@ endfunction()
|
|||||||
# =============================================
|
# =============================================
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
foreach(fw Carbon Metal Cocoa IOKit CoreVideo CoreMedia)
|
# Umbrella framework for everything GUI-related
|
||||||
find_library(${fw}_LIBRARY ${fw} REQUIRED)
|
find_library(COCOA_LIBRARY Cocoa REQUIRED)
|
||||||
list(APPEND PLATFORM_LIBRARIES ${${fw}_LIBRARY})
|
find_library(IOKIT_LIBRARY IOKit REQUIRED)
|
||||||
endforeach()
|
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
# Target Windows 10
|
# Target Windows 10
|
||||||
add_compile_definitions(_WIN32_WINNT=0x0A00 WINVER=0x0A00)
|
add_compile_definitions(_WIN32_WINNT=0x0A00 WINVER=0x0A00)
|
||||||
@@ -526,6 +522,7 @@ if (NOT YUZU_STATIC_ROOM)
|
|||||||
find_package(SPIRV-Tools)
|
find_package(SPIRV-Tools)
|
||||||
find_package(sirit)
|
find_package(sirit)
|
||||||
find_package(gamemode)
|
find_package(gamemode)
|
||||||
|
find_package(mcl)
|
||||||
find_package(frozen)
|
find_package(frozen)
|
||||||
|
|
||||||
if (ARCHITECTURE_riscv64)
|
if (ARCHITECTURE_riscv64)
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ set(GIT_DESC ${BUILD_VERSION})
|
|||||||
|
|
||||||
# Auto-updater metadata! Must somewhat mirror GitHub API endpoint
|
# Auto-updater metadata! Must somewhat mirror GitHub API endpoint
|
||||||
if (NIGHTLY_BUILD)
|
if (NIGHTLY_BUILD)
|
||||||
set(BUILD_AUTO_UPDATE_WEBSITE "https://git.eden-emu.dev")
|
set(BUILD_AUTO_UPDATE_WEBSITE "https://github.com")
|
||||||
set(BUILD_AUTO_UPDATE_API "git.eden-emu.dev")
|
set(BUILD_AUTO_UPDATE_API "api.github.com")
|
||||||
set(BUILD_AUTO_UPDATE_API_PATH "/api/v1/repos/")
|
set(BUILD_AUTO_UPDATE_API_PATH "/repos/")
|
||||||
set(BUILD_AUTO_UPDATE_REPO "eden-ci/nightly")
|
set(BUILD_AUTO_UPDATE_REPO "Eden-CI/Nightly")
|
||||||
set(REPO_NAME "Eden Nightly")
|
set(REPO_NAME "Eden Nightly")
|
||||||
else()
|
else()
|
||||||
set(BUILD_AUTO_UPDATE_WEBSITE "https://git.eden-emu.dev")
|
set(BUILD_AUTO_UPDATE_WEBSITE "https://git.eden-emu.dev")
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 256 KiB |
|
Before Width: | Height: | Size: 317 KiB After Width: | Height: | Size: 335 KiB |
@@ -1,230 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
width="512"
|
|
||||||
height="512"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
version="1.1"
|
|
||||||
id="svg7"
|
|
||||||
sodipodi:docname="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"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<defs
|
|
||||||
id="defs7">
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient1"
|
|
||||||
inkscape:collect="always">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#ff2e88;stop-opacity:0.5;"
|
|
||||||
offset="0"
|
|
||||||
id="stop3" />
|
|
||||||
<stop
|
|
||||||
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>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient138"
|
|
||||||
inkscape:collect="always">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#ff2e88;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop152" />
|
|
||||||
<stop
|
|
||||||
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"
|
|
||||||
inkscape:swatch="solid">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#ffffff;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop37" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="swatch28"
|
|
||||||
inkscape:swatch="solid">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#252525;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop28" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="swatch27"
|
|
||||||
inkscape:swatch="solid">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#000000;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop27" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="swatch15"
|
|
||||||
inkscape:swatch="solid">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#ffffff;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop16" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient14"
|
|
||||||
inkscape:swatch="gradient">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#ffffff;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop14" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#ffffff;stop-opacity:0;"
|
|
||||||
offset="1"
|
|
||||||
id="stop15" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="swatch9"
|
|
||||||
inkscape:swatch="solid">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#ffffff;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop10" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="swatch8"
|
|
||||||
inkscape:swatch="solid">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#ffffff;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop9" />
|
|
||||||
</linearGradient>
|
|
||||||
<rect
|
|
||||||
x="22.627417"
|
|
||||||
y="402.76802"
|
|
||||||
width="521.34025"
|
|
||||||
height="248.94868"
|
|
||||||
id="rect24" />
|
|
||||||
<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">
|
|
||||||
<circle
|
|
||||||
style="opacity:1;mix-blend-mode:normal;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.8382;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
|
||||||
id="circle18"
|
|
||||||
cx="-246.8315"
|
|
||||||
cy="246.8338"
|
|
||||||
inkscape:label="Circle"
|
|
||||||
r="191.89999" />
|
|
||||||
</clipPath>
|
|
||||||
<clipPath
|
|
||||||
clipPathUnits="userSpaceOnUse"
|
|
||||||
id="clipPath22">
|
|
||||||
<circle
|
|
||||||
style="opacity:1;mix-blend-mode:normal;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.8382;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
|
||||||
id="circle22"
|
|
||||||
cx="256"
|
|
||||||
cy="256"
|
|
||||||
inkscape:label="Circle"
|
|
||||||
r="191.89999" />
|
|
||||||
</clipPath>
|
|
||||||
<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">
|
|
||||||
<circle
|
|
||||||
style="fill:none;fill-opacity:1;stroke:#03ffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
id="circle128"
|
|
||||||
cx="256"
|
|
||||||
cy="256"
|
|
||||||
r="192" />
|
|
||||||
</clipPath>
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient1"
|
|
||||||
id="linearGradient2"
|
|
||||||
x1="256"
|
|
||||||
y1="64"
|
|
||||||
x2="256"
|
|
||||||
y2="448"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(1.3229974,0,0,1.3214002,-82.687336,-82.290326)" />
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview7"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="1.4142136"
|
|
||||||
inkscape:cx="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" />
|
|
||||||
<path
|
|
||||||
id="path8-7"
|
|
||||||
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: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"
|
|
||||||
clip-path="url(#clipPath128)"
|
|
||||||
transform="matrix(1.3229974,0,0,1.3214002,-82.687282,-82.278451)" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,37 +0,0 @@
|
|||||||
{
|
|
||||||
"fill" : {
|
|
||||||
"automatic-gradient" : "srgb:0.00000,0.00000,0.00000,1.00000"
|
|
||||||
},
|
|
||||||
"groups" : [
|
|
||||||
{
|
|
||||||
"layers" : [
|
|
||||||
{
|
|
||||||
"fill" : "none",
|
|
||||||
"image-name" : "dev.eden_emu.eden.svg",
|
|
||||||
"name" : "dev.eden_emu.eden",
|
|
||||||
"position" : {
|
|
||||||
"scale" : 1.8,
|
|
||||||
"translation-in-points" : [
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"shadow" : {
|
|
||||||
"kind" : "neutral",
|
|
||||||
"opacity" : 0.5
|
|
||||||
},
|
|
||||||
"translucency" : {
|
|
||||||
"enabled" : true,
|
|
||||||
"value" : 0.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"supported-platforms" : {
|
|
||||||
"circles" : [
|
|
||||||
"watchOS"
|
|
||||||
],
|
|
||||||
"squares" : "shared"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 19 KiB |
@@ -1 +0,0 @@
|
|||||||
#43fcfcff
|
|
||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 35 KiB |
@@ -76,6 +76,7 @@ Certain other dependencies will be fetched by CPM regardless. System packages *c
|
|||||||
* This package is known to be broken on the AUR.
|
* This package is known to be broken on the AUR.
|
||||||
* [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on
|
* [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on
|
||||||
* [unordered-dense](https://github.com/martinus/unordered_dense)
|
* [unordered-dense](https://github.com/martinus/unordered_dense)
|
||||||
|
* [mcl](https://github.com/azahar-emu/mcl) - subject to removal
|
||||||
|
|
||||||
On amd64:
|
On amd64:
|
||||||
|
|
||||||
@@ -334,7 +335,7 @@ pacman -Syuu --needed --noconfirm $packages
|
|||||||
<summary>HaikuOS</summary>
|
<summary>HaikuOS</summary>
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.90_devel vulkan_devel qt6_base_devel qt6_declarative_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt5_devel qt6_5compat_devel glslang qt6_devel qt6_charts_devel
|
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.89_devel vulkan_devel qt6_base_devel qt6_declarative_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt5_devel qt6_5compat_devel glslang qt6_devel qt6_charts_devel
|
||||||
```
|
```
|
||||||
|
|
||||||
[Caveats](./Caveats.md#haikuos).
|
[Caveats](./Caveats.md#haikuos).
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ Use this when you need to connect to a multiplayer room for LDN functionality in
|
|||||||
- Multiplayer Options Configured in Eden Settings
|
- Multiplayer Options Configured in Eden Settings
|
||||||
- Network Access
|
- Network Access
|
||||||
|
|
||||||
### Steps
|
## Steps
|
||||||
There are 2 primary methods that you can use to connect to an existing room, depending on how the room is hosted.
|
There are 2 primary methods that you can use to connect to an existing room, depending on how the room is hosted.
|
||||||
|
|
||||||
- Joining a Public Lobby
|
- Joining a Public Lobby
|
||||||
@@ -70,7 +70,7 @@ There are 2 primary methods that you can use to connect to an existing room, dep
|
|||||||
|
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
## Joining a Public Lobby
|
### Joining a Public Lobby
|
||||||
1. Open Eden and navigate to *Multiplayer → Browse Public Game Lobby*.
|
1. Open Eden and navigate to *Multiplayer → Browse Public Game Lobby*.
|
||||||
2. The **Public Room Browser** will now open and display a list of publicly accessible rooms. Find one you want to connect to and double click it.
|
2. The **Public Room Browser** will now open and display a list of publicly accessible rooms. Find one you want to connect to and double click it.
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ If the hoster has not made the lobby public, or you don't want to find it in the
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Hosting a Multiplayer Room
|
# Hosting a Multiplayer Room
|
||||||
Use this guide for when you want to host a multiplayer lobby to play with others in Eden. In order to have someone access the room from outside your local network, see the *Access Your Multiplayer Room Externally* section for next steps.
|
Use this guide for when you want to host a multiplayer lobby to play with others in Eden. In order to have someone access the room from outside your local network, see the *Access Your Multiplayer Room Externally* section for next steps.
|
||||||
|
|
||||||
**Click [Here](https://evilperson1337.notion.site/Hosting-a-Multiplayer-Room-2c357c2edaf6819481dbe8a99926cea2) for a version of this guide with images & visual elements.**
|
**Click [Here](https://evilperson1337.notion.site/Hosting-a-Multiplayer-Room-2c357c2edaf6819481dbe8a99926cea2) for a version of this guide with images & visual elements.**
|
||||||
@@ -100,7 +100,7 @@ Use this guide for when you want to host a multiplayer lobby to play with others
|
|||||||
- Network Access
|
- Network Access
|
||||||
- Ability to allow programs through the firewall on your device.
|
- Ability to allow programs through the firewall on your device.
|
||||||
|
|
||||||
### Steps
|
## Steps
|
||||||
1. Open Eden and navigate to *Emulation → Multiplayer → Create Room.*
|
1. Open Eden and navigate to *Emulation → Multiplayer → Create Room.*
|
||||||
2. Fill out the following information in the popup dialog box.
|
2. Fill out the following information in the popup dialog box.
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ Use this guide for when you want to host a multiplayer lobby to play with others
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Access Your Multiplayer Room Externally
|
# Access Your Multiplayer Room Externally
|
||||||
Quite often the person with whom you want to play is located off of your internal network (LAN). If you want to host a room and play with them you will need to get your devices to communicate with each other. This guide will go over your options on how to do this so that you can play together.
|
Quite often the person with whom you want to play is located off of your internal network (LAN). If you want to host a room and play with them you will need to get your devices to communicate with each other. This guide will go over your options on how to do this so that you can play together.
|
||||||
|
|
||||||
**Click [Here](https://evilperson1337.notion.site/Access-Your-Multiplayer-Room-Externally-2c357c2edaf681c0ab2ce2ee624d809d) for a version of this guide with images & visual elements.**
|
**Click [Here](https://evilperson1337.notion.site/Access-Your-Multiplayer-Room-Externally-2c357c2edaf681c0ab2ce2ee624d809d) for a version of this guide with images & visual elements.**
|
||||||
@@ -129,9 +129,9 @@ Quite often the person with whom you want to play is located off of your interna
|
|||||||
- Eden set up and Functioning
|
- Eden set up and Functioning
|
||||||
- Network Access
|
- Network Access
|
||||||
|
|
||||||
### Options
|
## Options
|
||||||
|
|
||||||
#### Port Forwarding
|
### Port Forwarding
|
||||||
|
|
||||||
- **Difficulty Level**: High
|
- **Difficulty Level**: High
|
||||||
|
|
||||||
@@ -148,9 +148,8 @@ The process works by creating a static mapping—often called a “port-forward
|
|||||||
|
|
||||||
For our purposes we would pick the port we want to expose (*e.g. 24872*) and we would access our router's configuration and create a port-forward rule to send the traffic from an external connection to your local machine over our specified port (*24872)*. The exact way to do so, varies greatly by router manufacturer - and sometimes require contacting your ISP to do so depending on your agreement. You can look up your router on [*portforward.com*](https://portforward.com/router.htm) which may have instructions on how to do so for your specific equipment. If it is not there, you will have to use Google/ChatGPT to determine the steps for your equipment.
|
For our purposes we would pick the port we want to expose (*e.g. 24872*) and we would access our router's configuration and create a port-forward rule to send the traffic from an external connection to your local machine over our specified port (*24872)*. The exact way to do so, varies greatly by router manufacturer - and sometimes require contacting your ISP to do so depending on your agreement. You can look up your router on [*portforward.com*](https://portforward.com/router.htm) which may have instructions on how to do so for your specific equipment. If it is not there, you will have to use Google/ChatGPT to determine the steps for your equipment.
|
||||||
|
|
||||||
Remember you can't have one port open for multiple devices at the same time - you must only host from one device (or do more convoluted networking which we will not cover here).
|
|
||||||
|
|
||||||
#### Use a Tunnelling Service
|
### Use a Tunnelling Service
|
||||||
- **Difficulty Level**: Easy
|
- **Difficulty Level**: Easy
|
||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
@@ -168,7 +167,7 @@ For our purposes we would spawn the listener for the port that way chose when ho
|
|||||||
- [*Playit.GG*](https://playit.gg/)
|
- [*Playit.GG*](https://playit.gg/)
|
||||||
|
|
||||||
|
|
||||||
#### Use a VPN Service
|
### Use a VPN Service
|
||||||
|
|
||||||
- **Difficulty**: Easy
|
- **Difficulty**: Easy
|
||||||
|
|
||||||
@@ -190,7 +189,7 @@ The VPN solution is a good compromise between the tunnelling solution and port f
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Finding the Server Information for a Multiplayer Room
|
# Finding the Server Information for a Multiplayer Room
|
||||||
Use this guide when you need to determine the connection information for the Public Multiplayer Lobby you are connected to.
|
Use this guide when you need to determine the connection information for the Public Multiplayer Lobby you are connected to.
|
||||||
|
|
||||||
**Click [Here](https://evilperson1337.notion.site/Finding-the-Server-Information-for-a-Multiplayer-Room-2c557c2edaf6809e94e8ed3429b9eb26) for a version of this guide with images & visual elements.**
|
**Click [Here](https://evilperson1337.notion.site/Finding-the-Server-Information-for-a-Multiplayer-Room-2c557c2edaf6809e94e8ed3429b9eb26) for a version of this guide with images & visual elements.**
|
||||||
@@ -199,7 +198,7 @@ Use this guide when you need to determine the connection information for the Pub
|
|||||||
- Eden set up and configured
|
- Eden set up and configured
|
||||||
- Internet Access
|
- Internet Access
|
||||||
|
|
||||||
### Steps
|
## Steps
|
||||||
|
|
||||||
### Method 1: Grabbing the Address from the Log File
|
### Method 1: Grabbing the Address from the Log File
|
||||||
1. Open Eden and Connect to the room you want to identify.
|
1. Open Eden and Connect to the room you want to identify.
|
||||||
@@ -223,7 +222,7 @@ Use this guide when you need to determine the connection information for the Pub
|
|||||||
2. Open the terminal supported by your operating system.
|
2. Open the terminal supported by your operating system.
|
||||||
3. Run one of the following commands, replacing *<Name>* with the name of the server from step 1.
|
3. Run one of the following commands, replacing *<Name>* with the name of the server from step 1.
|
||||||
|
|
||||||
#### PowerShell Command [Windows Users]
|
### PowerShell Command [Windows Users]
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Calls the API to get the address and port information
|
# Calls the API to get the address and port information
|
||||||
@@ -236,7 +235,7 @@ Use this guide when you need to determine the connection information for the Pub
|
|||||||
#}
|
#}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### CURL Command [MacOS/Linux Users] **Requires jq*
|
### CURL Command [MacOS/Linux Users] **Requires jq*
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Calls the API to get the address and port information
|
# Calls the API to get the address and port information
|
||||||
@@ -253,7 +252,7 @@ Use this guide when you need to determine the connection information for the Pub
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Multiplayer for Local Co-Op Games
|
# Multiplayer for Local Co-Op Games
|
||||||
Use this guide when you want to play with a friend on a different system for games that only support local co-op.
|
Use this guide when you want to play with a friend on a different system for games that only support local co-op.
|
||||||
|
|
||||||
**Click [Here](https://evilperson1337.notion.site/Multiplayer-for-Local-Co-Op-Games-2c657c2edaf680c59975ec6b52022a2d) for a version of this guide with images & visual elements.**
|
**Click [Here](https://evilperson1337.notion.site/Multiplayer-for-Local-Co-Op-Games-2c657c2edaf680c59975ec6b52022a2d) for a version of this guide with images & visual elements.**
|
||||||
@@ -272,7 +271,7 @@ In either situation at its core, we are emulating an input device on the host ma
|
|||||||
- Parsec is free to use for personal, non-commercial use. For instructions on how to set up an account and install the client you should refer to the Parsec documentation on it's site.
|
- Parsec is free to use for personal, non-commercial use. For instructions on how to set up an account and install the client you should refer to the Parsec documentation on it's site.
|
||||||
- Parsec client installed on your machine and remote (friend's) machine
|
- Parsec client installed on your machine and remote (friend's) machine
|
||||||
|
|
||||||
### Steps
|
## Steps
|
||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
|
|
||||||
@@ -295,22 +294,3 @@ This guide will assume you are the one hosting the game and go over things *Pars
|
|||||||
10. Set up the remote player's controller.
|
10. Set up the remote player's controller.
|
||||||
11. Hit **OK** to apply the changes.
|
11. Hit **OK** to apply the changes.
|
||||||
12. Launch the game you want to play and enter the co-op mode. How this works depends on the game, so you will have to look in the menus or online to find out.
|
12. Launch the game you want to play and enter the co-op mode. How this works depends on the game, so you will have to look in the menus or online to find out.
|
||||||
|
|
||||||
## Metaserver troubleshooting
|
|
||||||
|
|
||||||
If you can't connect to the metaserver, it's likely your ISP is blocking the requests.
|
|
||||||
|
|
||||||
### Linux and Steamdeck
|
|
||||||
|
|
||||||
Most Linux systems and Steamdeck should allow to modify the base `/etc/hosts` file, this should fix the DNS lookup issue; hence add the following to said file:
|
|
||||||
```
|
|
||||||
28.165.181.135 api.ynet-fun.xyz api.ynet-fun.xyz
|
|
||||||
```
|
|
||||||
|
|
||||||
### Zapret
|
|
||||||
|
|
||||||
In `lists/list-general.txt` add the following:
|
|
||||||
```
|
|
||||||
api.ynet-fun.xyz
|
|
||||||
ynet-fun.xyz
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ if (ARCHITECTURE_riscv64)
|
|||||||
AddJsonPackage(biscuit)
|
AddJsonPackage(biscuit)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# mcl
|
||||||
|
AddJsonPackage(mcl)
|
||||||
|
|
||||||
# Vulkan stuff
|
# Vulkan stuff
|
||||||
AddDependentPackages(vulkan-headers vulkan-utility-libraries)
|
AddDependentPackages(vulkan-headers vulkan-utility-libraries)
|
||||||
|
|
||||||
|
|||||||
@@ -208,6 +208,18 @@
|
|||||||
"version": "0.9.1",
|
"version": "0.9.1",
|
||||||
"git_version": "0.19.0"
|
"git_version": "0.19.0"
|
||||||
},
|
},
|
||||||
|
"mcl": {
|
||||||
|
"version": "0.1.12",
|
||||||
|
"repo": "azahar-emu/mcl",
|
||||||
|
"sha": "7b08d83418",
|
||||||
|
"hash": "9c6ba624cb22ef622f78046a82abb99bf5026284ba17dfacaf46ac842cbd3b0f515f5ba45a1598c7671318a78a2e648db72ce8d10e7537f34e39800bdcb57694",
|
||||||
|
"options": [
|
||||||
|
"MCL_INSTALL OFF"
|
||||||
|
],
|
||||||
|
"patches": [
|
||||||
|
"0001-assert-macro.patch"
|
||||||
|
]
|
||||||
|
},
|
||||||
"libusb": {
|
"libusb": {
|
||||||
"repo": "libusb/libusb",
|
"repo": "libusb/libusb",
|
||||||
"tag": "v%VERSION%",
|
"tag": "v%VERSION%",
|
||||||
|
|||||||
@@ -25,11 +25,6 @@ import android.hardware.SensorEventListener
|
|||||||
import android.hardware.SensorManager
|
import android.hardware.SensorManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import androidx.navigation.NavOptions
|
|
||||||
import org.yuzu.yuzu_emu.fragments.EmulationFragment
|
|
||||||
import org.yuzu.yuzu_emu.utils.CustomSettingsHandler
|
|
||||||
import android.util.Rational
|
import android.util.Rational
|
||||||
import android.view.InputDevice
|
import android.view.InputDevice
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
@@ -92,28 +87,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||||||
private val emulationViewModel: EmulationViewModel by viewModels()
|
private val emulationViewModel: EmulationViewModel by viewModels()
|
||||||
|
|
||||||
private var foregroundService: Intent? = null
|
private var foregroundService: Intent? = null
|
||||||
private val mainHandler = Handler(Looper.getMainLooper())
|
|
||||||
private var pendingRomSwapIntent: Intent? = null
|
|
||||||
private var isWaitingForRomSwapStop = false
|
|
||||||
private var romSwapNativeStopped = false
|
|
||||||
private var romSwapThreadStopped = false
|
|
||||||
private var romSwapGeneration = 0
|
|
||||||
private var hasEmulationSession = processHasEmulationSession
|
|
||||||
private val romSwapStopTimeoutRunnable = Runnable { onRomSwapStopTimeout() }
|
|
||||||
|
|
||||||
private fun onRomSwapStopTimeout() {
|
|
||||||
if (!isWaitingForRomSwapStop) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Log.warning("[EmulationActivity] ROM swap stop timed out; retrying native stop and continuing to wait")
|
|
||||||
NativeLibrary.stopEmulation()
|
|
||||||
scheduleRomSwapStopTimeout()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun scheduleRomSwapStopTimeout() {
|
|
||||||
mainHandler.removeCallbacks(romSwapStopTimeoutRunnable)
|
|
||||||
mainHandler.postDelayed(romSwapStopTimeoutRunnable, ROM_SWAP_STOP_TIMEOUT_MS)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun attachBaseContext(base: Context) {
|
override fun attachBaseContext(base: Context) {
|
||||||
super.attachBaseContext(YuzuApplication.applyLanguage(base))
|
super.attachBaseContext(YuzuApplication.applyLanguage(base))
|
||||||
@@ -155,29 +128,9 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||||||
binding = ActivityEmulationBinding.inflate(layoutInflater)
|
binding = ActivityEmulationBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
val launchIntent = Intent(intent)
|
|
||||||
val shouldDeferLaunchForSwap = hasEmulationSession && isSwapIntent(launchIntent)
|
|
||||||
if (shouldDeferLaunchForSwap) {
|
|
||||||
Log.info("[EmulationActivity] onCreate detected existing session; deferring new game setup for swap")
|
|
||||||
emulationViewModel.setIsEmulationStopping(true)
|
|
||||||
emulationViewModel.setEmulationStopped(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
val navHostFragment =
|
val navHostFragment =
|
||||||
supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
|
supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
|
||||||
val initialArgs = if (shouldDeferLaunchForSwap) {
|
navHostFragment.navController.setGraph(R.navigation.emulation_navigation, intent.extras)
|
||||||
Bundle(intent.extras ?: Bundle()).apply {
|
|
||||||
processSessionGame?.let { putParcelable("game", it) }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
intent.extras
|
|
||||||
}
|
|
||||||
navHostFragment.navController.setGraph(R.navigation.emulation_navigation, initialArgs)
|
|
||||||
if (shouldDeferLaunchForSwap) {
|
|
||||||
mainHandler.post {
|
|
||||||
handleSwapIntent(launchIntent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isActivityRecreated = savedInstanceState != null
|
isActivityRecreated = savedInstanceState != null
|
||||||
|
|
||||||
@@ -257,7 +210,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
mainHandler.removeCallbacks(romSwapStopTimeoutRunnable)
|
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
inputManager.unregisterInputDeviceListener(this)
|
inputManager.unregisterInputDeviceListener(this)
|
||||||
stopForegroundService(this)
|
stopForegroundService(this)
|
||||||
@@ -276,121 +228,15 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||||||
|
|
||||||
override fun onNewIntent(intent: Intent) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
super.onNewIntent(intent)
|
super.onNewIntent(intent)
|
||||||
handleSwapIntent(intent)
|
setIntent(intent)
|
||||||
nfcReader.onNewIntent(intent)
|
|
||||||
InputHandler.updateControllerData()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isSwapIntent(intent: Intent): Boolean {
|
// Reset navigation graph with new intent data to recreate EmulationFragment
|
||||||
return when {
|
|
||||||
intent.getBooleanExtra(EXTRA_OVERLAY_GAMELESS_EDIT_MODE, false) -> false
|
|
||||||
intent.action == CustomSettingsHandler.CUSTOM_CONFIG_ACTION -> true
|
|
||||||
intent.data != null -> true
|
|
||||||
else -> {
|
|
||||||
val extras = intent.extras
|
|
||||||
extras != null &&
|
|
||||||
BundleCompat.getParcelable(extras, EXTRA_SELECTED_GAME, Game::class.java) != null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleSwapIntent(intent: Intent) {
|
|
||||||
if (!isSwapIntent(intent)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
pendingRomSwapIntent = Intent(intent)
|
|
||||||
|
|
||||||
if (!isWaitingForRomSwapStop) {
|
|
||||||
Log.info("[EmulationActivity] Begin ROM swap: data=${intent.data}")
|
|
||||||
isWaitingForRomSwapStop = true
|
|
||||||
romSwapNativeStopped = false
|
|
||||||
romSwapThreadStopped = false
|
|
||||||
romSwapGeneration += 1
|
|
||||||
val thisSwapGeneration = romSwapGeneration
|
|
||||||
emulationViewModel.setIsEmulationStopping(true)
|
|
||||||
emulationViewModel.setEmulationStopped(false)
|
|
||||||
val navHostFragment =
|
|
||||||
supportFragmentManager.findFragmentById(R.id.fragment_container) as? NavHostFragment
|
|
||||||
val childFragmentManager = navHostFragment?.childFragmentManager
|
|
||||||
val stoppingFragmentForSwap =
|
|
||||||
(childFragmentManager?.primaryNavigationFragment as? EmulationFragment) ?:
|
|
||||||
childFragmentManager
|
|
||||||
?.fragments
|
|
||||||
?.asReversed()
|
|
||||||
?.firstOrNull {
|
|
||||||
it is EmulationFragment &&
|
|
||||||
it.isAdded &&
|
|
||||||
it.view != null &&
|
|
||||||
!it.isRemoving
|
|
||||||
} as? EmulationFragment
|
|
||||||
|
|
||||||
val hasSessionForSwap = hasEmulationSession || stoppingFragmentForSwap != null
|
|
||||||
|
|
||||||
if (!hasSessionForSwap) {
|
|
||||||
romSwapNativeStopped = true
|
|
||||||
romSwapThreadStopped = true
|
|
||||||
} else {
|
|
||||||
if (stoppingFragmentForSwap != null) {
|
|
||||||
stoppingFragmentForSwap.stopForRomSwap()
|
|
||||||
stoppingFragmentForSwap.notifyWhenEmulationThreadStops {
|
|
||||||
if (!isWaitingForRomSwapStop || romSwapGeneration != thisSwapGeneration) {
|
|
||||||
return@notifyWhenEmulationThreadStops
|
|
||||||
}
|
|
||||||
romSwapThreadStopped = true
|
|
||||||
Log.info("[EmulationActivity] ROM swap thread stop acknowledged")
|
|
||||||
launchPendingRomSwap(force = false)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.warning("[EmulationActivity] ROM swap stop target fragment not found; requesting native stop")
|
|
||||||
romSwapThreadStopped = true
|
|
||||||
NativeLibrary.stopEmulation()
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduleRomSwapStopTimeout()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
launchPendingRomSwap(force = false)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun launchPendingRomSwap(force: Boolean) {
|
|
||||||
if (!isWaitingForRomSwapStop) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!force && (!romSwapNativeStopped || !romSwapThreadStopped)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val swapIntent = pendingRomSwapIntent ?: return
|
|
||||||
Log.info("[EmulationActivity] Launching pending ROM swap: data=${swapIntent.data}")
|
|
||||||
pendingRomSwapIntent = null
|
|
||||||
isWaitingForRomSwapStop = false
|
|
||||||
romSwapNativeStopped = false
|
|
||||||
romSwapThreadStopped = false
|
|
||||||
mainHandler.removeCallbacks(romSwapStopTimeoutRunnable)
|
|
||||||
applyGameLaunchIntent(swapIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applyGameLaunchIntent(intent: Intent) {
|
|
||||||
hasEmulationSession = true
|
|
||||||
processHasEmulationSession = true
|
|
||||||
emulationViewModel.setIsEmulationStopping(false)
|
|
||||||
emulationViewModel.setEmulationStopped(false)
|
|
||||||
setIntent(Intent(intent))
|
|
||||||
val navHostFragment =
|
val navHostFragment =
|
||||||
supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
|
supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
|
||||||
val navController = navHostFragment.navController
|
navHostFragment.navController.setGraph(R.navigation.emulation_navigation, intent.extras)
|
||||||
val startArgs = intent.extras?.let { Bundle(it) } ?: Bundle()
|
|
||||||
val navOptions = NavOptions.Builder()
|
|
||||||
.setPopUpTo(R.id.emulationFragment, true)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
runCatching {
|
nfcReader.onNewIntent(intent)
|
||||||
navController.navigate(R.id.emulationFragment, startArgs, navOptions)
|
InputHandler.updateControllerData()
|
||||||
}.onFailure {
|
|
||||||
Log.warning("[EmulationActivity] ROM swap navigate fallback to setGraph: ${it.message}")
|
|
||||||
navController.setGraph(R.navigation.emulation_navigation, startArgs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||||
@@ -762,48 +608,19 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onEmulationStarted() {
|
fun onEmulationStarted() {
|
||||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
|
||||||
mainHandler.post { onEmulationStarted() }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
hasEmulationSession = true
|
|
||||||
processHasEmulationSession = true
|
|
||||||
emulationViewModel.setEmulationStarted(true)
|
emulationViewModel.setEmulationStarted(true)
|
||||||
emulationViewModel.setIsEmulationStopping(false)
|
|
||||||
emulationViewModel.setEmulationStopped(false)
|
|
||||||
NativeLibrary.playTimeManagerStart()
|
NativeLibrary.playTimeManagerStart()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onEmulationStopped(status: Int) {
|
fun onEmulationStopped(status: Int) {
|
||||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
if (status == 0 && emulationViewModel.programChanged.value == -1) {
|
||||||
mainHandler.post { onEmulationStopped(status) }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
hasEmulationSession = false
|
|
||||||
processHasEmulationSession = false
|
|
||||||
if (isWaitingForRomSwapStop) {
|
|
||||||
romSwapNativeStopped = true
|
|
||||||
Log.info("[EmulationActivity] ROM swap native stop acknowledged")
|
|
||||||
launchPendingRomSwap(force = false)
|
|
||||||
} else if (status == 0 && emulationViewModel.programChanged.value == -1) {
|
|
||||||
processSessionGame = null
|
|
||||||
finish()
|
finish()
|
||||||
} else if (!isWaitingForRomSwapStop) {
|
|
||||||
processSessionGame = null
|
|
||||||
}
|
}
|
||||||
emulationViewModel.setEmulationStopped(true)
|
emulationViewModel.setEmulationStopped(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateSessionGame(game: Game?) {
|
|
||||||
processSessionGame = game
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onProgramChanged(programIndex: Int) {
|
fun onProgramChanged(programIndex: Int) {
|
||||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
|
||||||
mainHandler.post { onProgramChanged(programIndex) }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
emulationViewModel.setProgramChanged(programIndex)
|
emulationViewModel.setProgramChanged(programIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,11 +644,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||||||
companion object {
|
companion object {
|
||||||
const val EXTRA_SELECTED_GAME = "SelectedGame"
|
const val EXTRA_SELECTED_GAME = "SelectedGame"
|
||||||
const val EXTRA_OVERLAY_GAMELESS_EDIT_MODE = "overlayGamelessEditMode"
|
const val EXTRA_OVERLAY_GAMELESS_EDIT_MODE = "overlayGamelessEditMode"
|
||||||
private const val ROM_SWAP_STOP_TIMEOUT_MS = 5000L
|
|
||||||
@Volatile
|
|
||||||
private var processHasEmulationSession = false
|
|
||||||
@Volatile
|
|
||||||
private var processSessionGame: Game? = null
|
|
||||||
|
|
||||||
fun stopForegroundService(activity: Activity) {
|
fun stopForegroundService(activity: Activity) {
|
||||||
val startIntent = Intent(activity, ForegroundService::class.java)
|
val startIntent = Intent(activity, ForegroundService::class.java)
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import androidx.window.layout.FoldingFeature
|
import androidx.window.layout.FoldingFeature
|
||||||
import androidx.window.layout.WindowInfoTracker
|
import androidx.window.layout.WindowInfoTracker
|
||||||
@@ -136,8 +135,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
|
|
||||||
private var intentGame: Game? = null
|
private var intentGame: Game? = null
|
||||||
private var isCustomSettingsIntent = false
|
private var isCustomSettingsIntent = false
|
||||||
private var isStoppingForRomSwap = false
|
|
||||||
private var deferGameSetupUntilStopCompletes = false
|
|
||||||
|
|
||||||
private var perfStatsRunnable: Runnable? = null
|
private var perfStatsRunnable: Runnable? = null
|
||||||
private var socRunnable: Runnable? = null
|
private var socRunnable: Runnable? = null
|
||||||
@@ -241,14 +238,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emulationViewModel.isEmulationStopping.value) {
|
|
||||||
deferGameSetupUntilStopCompletes = true
|
|
||||||
if (game == null) {
|
|
||||||
game = args.game ?: intentGame
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
finishGameSetup()
|
finishGameSetup()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +260,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
game = gameToUse
|
game = gameToUse
|
||||||
emulationActivity?.updateSessionGame(gameToUse)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.error("[EmulationFragment] Error during game setup: ${e.message}")
|
Log.error("[EmulationFragment] Error during game setup: ${e.message}")
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
@@ -346,8 +334,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
emulationState = EmulationState(game!!.path) {
|
emulationState = EmulationState(game!!.path) {
|
||||||
return@EmulationState driverViewModel.isInteractionAllowed.value &&
|
return@EmulationState driverViewModel.isInteractionAllowed.value
|
||||||
!isStoppingForRomSwap
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -903,12 +890,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
game?.let {
|
GameIconUtils.loadGameIcon(game!!, binding.loadingImage)
|
||||||
GameIconUtils.loadGameIcon(it, binding.loadingImage)
|
binding.loadingTitle.text = game!!.title
|
||||||
binding.loadingTitle.text = it.title
|
|
||||||
} ?: run {
|
|
||||||
binding.loadingTitle.text = ""
|
|
||||||
}
|
|
||||||
binding.loadingTitle.isSelected = true
|
binding.loadingTitle.isSelected = true
|
||||||
binding.loadingText.isSelected = true
|
binding.loadingText.isSelected = true
|
||||||
|
|
||||||
@@ -976,12 +959,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
ViewUtils.showView(binding.loadingIndicator)
|
ViewUtils.showView(binding.loadingIndicator)
|
||||||
ViewUtils.hideView(binding.inputContainer)
|
ViewUtils.hideView(binding.inputContainer)
|
||||||
ViewUtils.hideView(binding.showStatsOverlayText)
|
ViewUtils.hideView(binding.showStatsOverlayText)
|
||||||
} else if (deferGameSetupUntilStopCompletes) {
|
|
||||||
if (!isAdded) {
|
|
||||||
return@collect
|
|
||||||
}
|
|
||||||
deferGameSetupUntilStopCompletes = false
|
|
||||||
finishGameSetup()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emulationViewModel.drawerOpen.collect(viewLifecycleOwner) {
|
emulationViewModel.drawerOpen.collect(viewLifecycleOwner) {
|
||||||
@@ -1018,24 +995,26 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
driverViewModel.isInteractionAllowed.collect(viewLifecycleOwner) {
|
driverViewModel.isInteractionAllowed.collect(viewLifecycleOwner) {
|
||||||
if (it &&
|
if (it && !NativeLibrary.isRunning() && !NativeLibrary.isPaused()) {
|
||||||
!isStoppingForRomSwap &&
|
startEmulation()
|
||||||
!NativeLibrary.isRunning() &&
|
|
||||||
!NativeLibrary.isPaused()
|
|
||||||
) {
|
|
||||||
if (!DirectoryInitialization.areDirectoriesReady) {
|
|
||||||
DirectoryInitialization.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
updateScreenLayout()
|
|
||||||
|
|
||||||
emulationState.run(emulationActivity!!.isActivityRecreated)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
driverViewModel.onLaunchGame()
|
driverViewModel.onLaunchGame()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun startEmulation(programIndex: Int = 0) {
|
||||||
|
if (!NativeLibrary.isRunning() && !NativeLibrary.isPaused()) {
|
||||||
|
if (!DirectoryInitialization.areDirectoriesReady) {
|
||||||
|
DirectoryInitialization.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
updateScreenLayout()
|
||||||
|
|
||||||
|
emulationState.run(emulationActivity!!.isActivityRecreated, programIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
super.onConfigurationChanged(newConfig)
|
super.onConfigurationChanged(newConfig)
|
||||||
val b = _binding ?: return
|
val b = _binding ?: return
|
||||||
@@ -1396,9 +1375,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
amiiboLoadJob?.cancel()
|
amiiboLoadJob?.cancel()
|
||||||
amiiboLoadJob = null
|
amiiboLoadJob = null
|
||||||
perfStatsRunnable?.let { perfStatsUpdateHandler.removeCallbacks(it) }
|
|
||||||
socRunnable?.let { socUpdateHandler.removeCallbacks(it) }
|
|
||||||
handler.removeCallbacksAndMessages(null)
|
|
||||||
clearPausedFrame()
|
clearPausedFrame()
|
||||||
_binding?.surfaceInputOverlay?.touchEventListener = null
|
_binding?.surfaceInputOverlay?.touchEventListener = null
|
||||||
_binding = null
|
_binding = null
|
||||||
@@ -1406,9 +1382,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDetach() {
|
override fun onDetach() {
|
||||||
if (!hasNewerEmulationFragment()) {
|
NativeLibrary.clearEmulationActivity()
|
||||||
NativeLibrary.clearEmulationActivity()
|
|
||||||
}
|
|
||||||
super.onDetach()
|
super.onDetach()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1866,74 +1840,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
||||||
if (this::emulationState.isInitialized && !hasNewerEmulationFragment()) {
|
emulationState.clearSurface()
|
||||||
emulationState.clearSurface()
|
|
||||||
}
|
|
||||||
emulationStarted = false
|
emulationStarted = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hasNewerEmulationFragment(): Boolean {
|
|
||||||
val activity = emulationActivity ?: return false
|
|
||||||
return try {
|
|
||||||
val navHostFragment =
|
|
||||||
activity.supportFragmentManager.findFragmentById(R.id.fragment_container) as? NavHostFragment
|
|
||||||
?: return false
|
|
||||||
val currentFragment = navHostFragment.childFragmentManager.fragments
|
|
||||||
.filterIsInstance<EmulationFragment>()
|
|
||||||
.firstOrNull()
|
|
||||||
currentFragment != null && currentFragment !== this
|
|
||||||
} catch (_: Exception) {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// xbzk: called from EmulationActivity when a new game is loaded while this fragment is still active,
|
|
||||||
// to wait for the emulation thread to stop before allowing the ROM swap to proceed
|
|
||||||
fun notifyWhenEmulationThreadStops(onStopped: () -> Unit) {
|
|
||||||
if (!this::emulationState.isInitialized) {
|
|
||||||
onStopped()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val emuThread = runCatching { emulationState.emulationThread }.getOrNull()
|
|
||||||
if (emuThread == null || !emuThread.isAlive) {
|
|
||||||
onStopped()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Thread({
|
|
||||||
runCatching { emuThread.join() }
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
|
||||||
onStopped()
|
|
||||||
}
|
|
||||||
}, "RomSwapWait").start()
|
|
||||||
}
|
|
||||||
|
|
||||||
// xbzk: called from EmulationActivity when a new game is loaded while this
|
|
||||||
// fragment is still active, to stop the current emulation before swapping the ROM
|
|
||||||
fun stopForRomSwap() {
|
|
||||||
if (isStoppingForRomSwap) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
isStoppingForRomSwap = true
|
|
||||||
clearPausedFrame()
|
|
||||||
emulationViewModel.setIsEmulationStopping(true)
|
|
||||||
_binding?.let {
|
|
||||||
binding.loadingText.setText(R.string.shutting_down)
|
|
||||||
ViewUtils.showView(binding.loadingIndicator)
|
|
||||||
ViewUtils.hideView(binding.inputContainer)
|
|
||||||
ViewUtils.hideView(binding.showStatsOverlayText)
|
|
||||||
}
|
|
||||||
if (this::emulationState.isInitialized) {
|
|
||||||
emulationState.stop()
|
|
||||||
if (NativeLibrary.isRunning() || NativeLibrary.isPaused()) {
|
|
||||||
Log.warning("[EmulationFragment] ROM swap stop fallback: forcing native stop request.")
|
|
||||||
NativeLibrary.stopEmulation()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
NativeLibrary.stopEmulation()
|
|
||||||
}
|
|
||||||
NativeConfig.reloadGlobalConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showOverlayOptions() {
|
private fun showOverlayOptions() {
|
||||||
val anchor = binding.inGameMenu.findViewById<View>(R.id.menu_overlay_controls)
|
val anchor = binding.inGameMenu.findViewById<View>(R.id.menu_overlay_controls)
|
||||||
val popup = PopupMenu(requireContext(), anchor)
|
val popup = PopupMenu(requireContext(), anchor)
|
||||||
@@ -2224,7 +2134,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
state = State.STOPPED
|
state = State.STOPPED
|
||||||
} else {
|
} else {
|
||||||
Log.warning("[EmulationFragment] Stop called while already stopped.")
|
Log.warning("[EmulationFragment] Stop called while already stopped.")
|
||||||
NativeLibrary.stopEmulation()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import org.yuzu.yuzu_emu.databinding.FragmentGamePropertiesBinding
|
|||||||
import org.yuzu.yuzu_emu.features.DocumentProvider
|
import org.yuzu.yuzu_emu.features.DocumentProvider
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsSubscreen
|
import org.yuzu.yuzu_emu.features.settings.ui.SettingsSubscreen
|
||||||
import org.yuzu.yuzu_emu.model.AddonViewModel
|
|
||||||
import org.yuzu.yuzu_emu.model.DriverViewModel
|
import org.yuzu.yuzu_emu.model.DriverViewModel
|
||||||
import org.yuzu.yuzu_emu.model.GameProperty
|
import org.yuzu.yuzu_emu.model.GameProperty
|
||||||
import org.yuzu.yuzu_emu.model.GamesViewModel
|
import org.yuzu.yuzu_emu.model.GamesViewModel
|
||||||
@@ -47,7 +46,6 @@ import org.yuzu.yuzu_emu.model.SubmenuProperty
|
|||||||
import org.yuzu.yuzu_emu.model.TaskState
|
import org.yuzu.yuzu_emu.model.TaskState
|
||||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
||||||
import org.yuzu.yuzu_emu.utils.FileUtil
|
import org.yuzu.yuzu_emu.utils.FileUtil
|
||||||
import org.yuzu.yuzu_emu.utils.GameHelper
|
|
||||||
import org.yuzu.yuzu_emu.utils.GameIconUtils
|
import org.yuzu.yuzu_emu.utils.GameIconUtils
|
||||||
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
||||||
import org.yuzu.yuzu_emu.utils.MemoryUtil
|
import org.yuzu.yuzu_emu.utils.MemoryUtil
|
||||||
@@ -63,7 +61,6 @@ class GamePropertiesFragment : Fragment() {
|
|||||||
|
|
||||||
private val homeViewModel: HomeViewModel by activityViewModels()
|
private val homeViewModel: HomeViewModel by activityViewModels()
|
||||||
private val gamesViewModel: GamesViewModel by activityViewModels()
|
private val gamesViewModel: GamesViewModel by activityViewModels()
|
||||||
private val addonViewModel: AddonViewModel by activityViewModels()
|
|
||||||
private val driverViewModel: DriverViewModel by activityViewModels()
|
private val driverViewModel: DriverViewModel by activityViewModels()
|
||||||
|
|
||||||
private val args by navArgs<GamePropertiesFragmentArgs>()
|
private val args by navArgs<GamePropertiesFragmentArgs>()
|
||||||
@@ -121,20 +118,6 @@ class GamePropertiesFragment : Fragment() {
|
|||||||
.show(childFragmentManager, LaunchGameDialogFragment.TAG)
|
.show(childFragmentManager, LaunchGameDialogFragment.TAG)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameHelper.cachedGameList.isEmpty()) {
|
|
||||||
binding.buttonStart.isEnabled = false
|
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
GameHelper.restoreContentForGame(args.game)
|
|
||||||
}
|
|
||||||
if (_binding == null) {
|
|
||||||
return@launch
|
|
||||||
}
|
|
||||||
addonViewModel.onAddonsViewStarted(args.game)
|
|
||||||
binding.buttonStart.isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reloadList()
|
reloadList()
|
||||||
|
|
||||||
homeViewModel.openImportSaves.collect(
|
homeViewModel.openImportSaves.collect(
|
||||||
@@ -150,11 +133,8 @@ class GamePropertiesFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
val isChangingConfigurations = activity?.isChangingConfigurations == true
|
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
if (!isChangingConfigurations) {
|
gamesViewModel.reloadGames(true)
|
||||||
gamesViewModel.reloadGames(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPlayTime() {
|
private fun getPlayTime() {
|
||||||
|
|||||||
@@ -100,45 +100,42 @@ class GamesViewModel : ViewModel() {
|
|||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
if (firstStartup) {
|
||||||
if (firstStartup) {
|
// Retrieve list of cached games
|
||||||
// Retrieve list of cached games
|
val storedGames =
|
||||||
val storedGames =
|
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||||
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
.getStringSet(GameHelper.KEY_GAMES, emptySet())
|
||||||
.getStringSet(GameHelper.KEY_GAMES, emptySet())
|
if (storedGames!!.isNotEmpty()) {
|
||||||
if (storedGames!!.isNotEmpty()) {
|
val deserializedGames = mutableSetOf<Game>()
|
||||||
val deserializedGames = mutableSetOf<Game>()
|
storedGames.forEach {
|
||||||
storedGames.forEach {
|
val game: Game
|
||||||
val game: Game
|
try {
|
||||||
try {
|
game = Json.decodeFromString(it)
|
||||||
game = Json.decodeFromString(it)
|
} catch (e: Exception) {
|
||||||
} catch (e: Exception) {
|
// We don't care about any errors related to parsing the game cache
|
||||||
// We don't care about any errors related to parsing the game cache
|
return@forEach
|
||||||
return@forEach
|
}
|
||||||
}
|
|
||||||
|
val gameExists =
|
||||||
val gameExists =
|
DocumentFile.fromSingleUri(
|
||||||
DocumentFile.fromSingleUri(
|
YuzuApplication.appContext,
|
||||||
YuzuApplication.appContext,
|
Uri.parse(game.path)
|
||||||
Uri.parse(game.path)
|
)?.exists()
|
||||||
)?.exists()
|
if (gameExists == true) {
|
||||||
if (gameExists == true) {
|
deserializedGames.add(game)
|
||||||
deserializedGames.add(game)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setGames(deserializedGames.toList())
|
|
||||||
}
|
}
|
||||||
|
setGames(deserializedGames.toList())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setGames(GameHelper.getGames())
|
setGames(GameHelper.getGames())
|
||||||
_shouldScrollAfterReload.value = true
|
reloading.set(false)
|
||||||
|
_isReloading.value = false
|
||||||
|
_shouldScrollAfterReload.value = true
|
||||||
|
|
||||||
if (directoriesChanged) {
|
if (directoriesChanged) {
|
||||||
setShouldSwapData(true)
|
setShouldSwapData(true)
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
reloading.set(false)
|
|
||||||
_isReloading.value = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ object DirectoryInitialization {
|
|||||||
fun start() {
|
fun start() {
|
||||||
if (!areDirectoriesReady) {
|
if (!areDirectoriesReady) {
|
||||||
initializeInternalStorage()
|
initializeInternalStorage()
|
||||||
NativeConfig.initializeGlobalConfig()
|
|
||||||
NativeLibrary.initializeSystem(false)
|
NativeLibrary.initializeSystem(false)
|
||||||
|
NativeConfig.initializeGlobalConfig()
|
||||||
NativeLibrary.reloadProfiles()
|
NativeLibrary.reloadProfiles()
|
||||||
migrateSettings()
|
migrateSettings()
|
||||||
areDirectoriesReady = true
|
areDirectoriesReady = true
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ package org.yuzu.yuzu_emu.utils
|
|||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.DocumentsContract
|
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import java.io.File
|
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
import org.yuzu.yuzu_emu.model.Game
|
import org.yuzu.yuzu_emu.model.Game
|
||||||
@@ -51,8 +49,29 @@ object GameHelper {
|
|||||||
// Remove previous filesystem provider information so we can get up to date version info
|
// Remove previous filesystem provider information so we can get up to date version info
|
||||||
NativeLibrary.clearFilesystemProvider()
|
NativeLibrary.clearFilesystemProvider()
|
||||||
|
|
||||||
|
// Scan External Content directories and register all NSP/XCI files
|
||||||
|
val externalContentDirs = NativeConfig.getExternalContentDirs()
|
||||||
|
val uniqueExternalContentDirs = linkedSetOf<String>()
|
||||||
|
externalContentDirs.forEach { externalDir ->
|
||||||
|
if (externalDir.isNotEmpty()) {
|
||||||
|
uniqueExternalContentDirs.add(externalDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val mountedContainerUris = mutableSetOf<String>()
|
val mountedContainerUris = mutableSetOf<String>()
|
||||||
mountExternalContentDirectories(mountedContainerUris)
|
for (externalDir in uniqueExternalContentDirs) {
|
||||||
|
if (externalDir.isNotEmpty()) {
|
||||||
|
val externalDirUri = externalDir.toUri()
|
||||||
|
if (FileUtil.isTreeUriValid(externalDirUri)) {
|
||||||
|
scanContentContainersRecursive(FileUtil.listFiles(externalDirUri), 3) {
|
||||||
|
val containerUri = it.uri.toString()
|
||||||
|
if (mountedContainerUris.add(containerUri)) {
|
||||||
|
NativeLibrary.addFileToFilesystemProvider(containerUri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val badDirs = mutableListOf<Int>()
|
val badDirs = mutableListOf<Int>()
|
||||||
gameDirs.forEachIndexed { index: Int, gameDir: GameDir ->
|
gameDirs.forEachIndexed { index: Int, gameDir: GameDir ->
|
||||||
@@ -96,15 +115,6 @@ object GameHelper {
|
|||||||
return games.toList()
|
return games.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun restoreContentForGame(game: Game) {
|
|
||||||
NativeLibrary.reloadKeys()
|
|
||||||
|
|
||||||
val mountedContainerUris = mutableSetOf<String>()
|
|
||||||
mountExternalContentDirectories(mountedContainerUris)
|
|
||||||
mountGameFolderContent(Uri.parse(game.path), mountedContainerUris)
|
|
||||||
NativeLibrary.addFileToFilesystemProvider(game.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// File extensions considered as external content, buuut should
|
// File extensions considered as external content, buuut should
|
||||||
// be done better imo.
|
// be done better imo.
|
||||||
private val externalContentExtensions = setOf("nsp", "xci")
|
private val externalContentExtensions = setOf("nsp", "xci")
|
||||||
@@ -171,71 +181,6 @@ object GameHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mountExternalContentDirectories(mountedContainerUris: MutableSet<String>) {
|
|
||||||
val uniqueExternalContentDirs = linkedSetOf<String>()
|
|
||||||
NativeConfig.getExternalContentDirs().forEach { externalDir ->
|
|
||||||
if (externalDir.isNotEmpty()) {
|
|
||||||
uniqueExternalContentDirs.add(externalDir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (externalDir in uniqueExternalContentDirs) {
|
|
||||||
val externalDirUri = externalDir.toUri()
|
|
||||||
if (FileUtil.isTreeUriValid(externalDirUri)) {
|
|
||||||
scanContentContainersRecursive(FileUtil.listFiles(externalDirUri), 3) {
|
|
||||||
val containerUri = it.uri.toString()
|
|
||||||
if (mountedContainerUris.add(containerUri)) {
|
|
||||||
NativeLibrary.addFileToFilesystemProvider(containerUri)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun mountGameFolderContent(gameUri: Uri, mountedContainerUris: MutableSet<String>) {
|
|
||||||
if (gameUri.scheme == "content") {
|
|
||||||
val parentUri = getParentDocumentUri(gameUri) ?: return
|
|
||||||
scanContentContainersRecursive(FileUtil.listFiles(parentUri), 1) {
|
|
||||||
val containerUri = it.uri.toString()
|
|
||||||
if (mountedContainerUris.add(containerUri)) {
|
|
||||||
NativeLibrary.addGameFolderFileToFilesystemProvider(containerUri)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val gameFile = File(gameUri.path ?: gameUri.toString())
|
|
||||||
val parentDir = gameFile.parentFile ?: return
|
|
||||||
parentDir.listFiles()?.forEach { sibling ->
|
|
||||||
if (!sibling.isFile) {
|
|
||||||
return@forEach
|
|
||||||
}
|
|
||||||
|
|
||||||
val extension = sibling.extension.lowercase()
|
|
||||||
if (externalContentExtensions.contains(extension)) {
|
|
||||||
val containerUri = Uri.fromFile(sibling).toString()
|
|
||||||
if (mountedContainerUris.add(containerUri)) {
|
|
||||||
NativeLibrary.addGameFolderFileToFilesystemProvider(containerUri)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getParentDocumentUri(uri: Uri): Uri? {
|
|
||||||
return try {
|
|
||||||
val documentId = DocumentsContract.getDocumentId(uri)
|
|
||||||
val separatorIndex = documentId.lastIndexOf('/')
|
|
||||||
if (separatorIndex == -1) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
val parentDocumentId = documentId.substring(0, separatorIndex)
|
|
||||||
DocumentsContract.buildDocumentUriUsingTree(uri, parentDocumentId)
|
|
||||||
}
|
|
||||||
} catch (_: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getGame(
|
fun getGame(
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
addedToLibrary: Boolean,
|
addedToLibrary: Boolean,
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 67 KiB |
@@ -473,6 +473,8 @@
|
|||||||
<string name="renderer_accuracy_description">يتحكم في وضع محاكاة وحدة معالجة الرسومات. تعمل معظم الألعاب بشكل جيد مع وضعي سريع أو متوازن، لكن الوضع الدقيق لا يزال مطلوبًا لبعض الألعاب. تميل الجسيمات إلى العرض بشكل صحيح فقط عند استخدام الوضع الدقيق.</string>
|
<string name="renderer_accuracy_description">يتحكم في وضع محاكاة وحدة معالجة الرسومات. تعمل معظم الألعاب بشكل جيد مع وضعي سريع أو متوازن، لكن الوضع الدقيق لا يزال مطلوبًا لبعض الألعاب. تميل الجسيمات إلى العرض بشكل صحيح فقط عند استخدام الوضع الدقيق.</string>
|
||||||
<string name="dma_accuracy">دقة DMA</string>
|
<string name="dma_accuracy">دقة DMA</string>
|
||||||
<string name="dma_accuracy_description">يتحكم في دقة DMA. يمكن أن تؤدي الدقة الآمنة إلى حل المشكلات في بعض الألعاب، ولكنها قد تؤثر أيضًا على الأداء في بعض الحالات. إذا لم تكن متأكدًا، فاترك هذا الخيار على الإعداد الافتراضي.</string>
|
<string name="dma_accuracy_description">يتحكم في دقة DMA. يمكن أن تؤدي الدقة الآمنة إلى حل المشكلات في بعض الألعاب، ولكنها قد تؤثر أيضًا على الأداء في بعض الحالات. إذا لم تكن متأكدًا، فاترك هذا الخيار على الإعداد الافتراضي.</string>
|
||||||
|
<string name="frame_pacing_mode">وضع توقيت الإطارات</string>
|
||||||
|
<string name="frame_pacing_mode_description">يتحكم في كيفية إدارة المحاكي لسرعة الإطارات لتقليل التقطع وجعل معدل الإطارات أكثر سلاسة واتساقًا.</string>
|
||||||
<string name="anisotropic_filtering">تصفية متباينة الخواص</string>
|
<string name="anisotropic_filtering">تصفية متباينة الخواص</string>
|
||||||
<string name="anisotropic_filtering_description">يحسن جودة الأنسجة عند عرضها بزوايا مائلة</string>
|
<string name="anisotropic_filtering_description">يحسن جودة الأنسجة عند عرضها بزوايا مائلة</string>
|
||||||
<string name="vram_usage_mode">وضع استخدام ذاكرة VRAM</string>
|
<string name="vram_usage_mode">وضع استخدام ذاكرة VRAM</string>
|
||||||
@@ -997,6 +999,13 @@
|
|||||||
<string name="dma_accuracy_unsafe">غير آمن</string>
|
<string name="dma_accuracy_unsafe">غير آمن</string>
|
||||||
<string name="dma_accuracy_safe">آمن</string>
|
<string name="dma_accuracy_safe">آمن</string>
|
||||||
|
|
||||||
|
<!-- Frame Pacing Mode -->
|
||||||
|
<string name="frame_pacing_mode_target_Auto">تلقائي</string>
|
||||||
|
<string name="frame_pacing_mode_target_30">30 إطارًا في الثانية</string>
|
||||||
|
<string name="frame_pacing_mode_target_60">60 إطارًا في الثانية</string>
|
||||||
|
<string name="frame_pacing_mode_target_90">90 إطارًا في الثانية</string>
|
||||||
|
<string name="frame_pacing_mode_target_120">120 إطارًا في الثانية</string>
|
||||||
|
|
||||||
<!-- ASTC Recompression Method Choices -->
|
<!-- ASTC Recompression Method Choices -->
|
||||||
<string name="astc_recompression_uncompressed">غير مضغوط</string>
|
<string name="astc_recompression_uncompressed">غير مضغوط</string>
|
||||||
<!-- ASTC Recompression Method Choices -->
|
<!-- ASTC Recompression Method Choices -->
|
||||||
|
|||||||
@@ -452,6 +452,8 @@
|
|||||||
<string name="renderer_accuracy_description">Určuje režim emulovaného GPU. Většina her běží bez problémů v rychlém, nebo vyváženém režimu, ale některé stále vyžadují přesný režim. Částicové efekty se většinou zobrazují korektně pouze v přesném režimu. </string>
|
<string name="renderer_accuracy_description">Určuje režim emulovaného GPU. Většina her běží bez problémů v rychlém, nebo vyváženém režimu, ale některé stále vyžadují přesný režim. Částicové efekty se většinou zobrazují korektně pouze v přesném režimu. </string>
|
||||||
<string name="dma_accuracy">Přesnost DMA</string>
|
<string name="dma_accuracy">Přesnost DMA</string>
|
||||||
<string name="dma_accuracy_description">Ovládá přesnost DMA. Bezpečná přesnost může vyřešit problémy v některých hrách, ale v některých případech může také ovlivnit výkon. Pokud si nejste jisti, použijte výchozí nastavení.</string>
|
<string name="dma_accuracy_description">Ovládá přesnost DMA. Bezpečná přesnost může vyřešit problémy v některých hrách, ale v některých případech může také ovlivnit výkon. Pokud si nejste jisti, použijte výchozí nastavení.</string>
|
||||||
|
<string name="frame_pacing_mode">Režim Framepacingu</string>
|
||||||
|
<string name="frame_pacing_mode_description">Řídí způsob jakým emulátor spravuje časování snímku aby snížil trhání a zlepšení plynulost a stabilitu snímkové frekvence.</string>
|
||||||
<string name="anisotropic_filtering">Anizotropní filtrování</string>
|
<string name="anisotropic_filtering">Anizotropní filtrování</string>
|
||||||
<string name="anisotropic_filtering_description">Zlepšuje kvalitu textur při pohledu pod úhlem</string>
|
<string name="anisotropic_filtering_description">Zlepšuje kvalitu textur při pohledu pod úhlem</string>
|
||||||
<string name="vram_usage_mode">Režim využití VRAM</string>
|
<string name="vram_usage_mode">Režim využití VRAM</string>
|
||||||
|
|||||||
@@ -467,6 +467,8 @@
|
|||||||
<string name="renderer_accuracy_description">Controla el modo de la emulación de la GPU. La mayoría de los juegos se renderizan correctamente en los modos Rápido o Equilibrado, pero algunos requieren Preciso. Las partículas tienden a renderizarse correctamente solo con el modo Preciso.</string>
|
<string name="renderer_accuracy_description">Controla el modo de la emulación de la GPU. La mayoría de los juegos se renderizan correctamente en los modos Rápido o Equilibrado, pero algunos requieren Preciso. Las partículas tienden a renderizarse correctamente solo con el modo Preciso.</string>
|
||||||
<string name="dma_accuracy">Precisión de DMA</string>
|
<string name="dma_accuracy">Precisión de DMA</string>
|
||||||
<string name="dma_accuracy_description">Controla la precisión de DMA. La precisión segura puede solucionar problemas en algunos juegos, pero también puede afectar al rendimiento en algunos casos. Si no está seguro, déjelo en Predeterminado.</string>
|
<string name="dma_accuracy_description">Controla la precisión de DMA. La precisión segura puede solucionar problemas en algunos juegos, pero también puede afectar al rendimiento en algunos casos. Si no está seguro, déjelo en Predeterminado.</string>
|
||||||
|
<string name="frame_pacing_mode">Modo de ritmo de fotogramas</string>
|
||||||
|
<string name="frame_pacing_mode_description">Controla cómo el emulador gestiona el ritmo de los fotogramas para reducir los tirones y hacer que la velocidad de los fotogramas sea más suave y consistente.</string>
|
||||||
<string name="anisotropic_filtering">Filtrado anisotrópico</string>
|
<string name="anisotropic_filtering">Filtrado anisotrópico</string>
|
||||||
<string name="anisotropic_filtering_description">Mejora la calidad de las texturas al ser observadas desde ángulos oblicuos</string>
|
<string name="anisotropic_filtering_description">Mejora la calidad de las texturas al ser observadas desde ángulos oblicuos</string>
|
||||||
<string name="vram_usage_mode">Modo de uso de VRAM</string>
|
<string name="vram_usage_mode">Modo de uso de VRAM</string>
|
||||||
@@ -991,6 +993,13 @@
|
|||||||
<string name="dma_accuracy_unsafe">Inseguro</string>
|
<string name="dma_accuracy_unsafe">Inseguro</string>
|
||||||
<string name="dma_accuracy_safe">Seguro</string>
|
<string name="dma_accuracy_safe">Seguro</string>
|
||||||
|
|
||||||
|
<!-- Frame Pacing Mode -->
|
||||||
|
<string name="frame_pacing_mode_target_Auto">Automático</string>
|
||||||
|
<string name="frame_pacing_mode_target_30">30 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_60">60 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_90">90 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_120">120 FPS</string>
|
||||||
|
|
||||||
<!-- ASTC Recompression Method Choices -->
|
<!-- ASTC Recompression Method Choices -->
|
||||||
<string name="astc_recompression_uncompressed">Sin compresión</string>
|
<string name="astc_recompression_uncompressed">Sin compresión</string>
|
||||||
<!-- ASTC Recompression Method Choices -->
|
<!-- ASTC Recompression Method Choices -->
|
||||||
|
|||||||
@@ -468,6 +468,8 @@
|
|||||||
<string name="renderer_accuracy_description">Управляет режимом эмуляции графического процессора. Большинство игр нормально отображаются в режимах «Быстрый» или «Сбалансированный», но для некоторых требуется режим «Точный». Частицы обычно корректно отображаются только в режиме «Точный».</string>
|
<string name="renderer_accuracy_description">Управляет режимом эмуляции графического процессора. Большинство игр нормально отображаются в режимах «Быстрый» или «Сбалансированный», но для некоторых требуется режим «Точный». Частицы обычно корректно отображаются только в режиме «Точный».</string>
|
||||||
<string name="dma_accuracy">Точность DMA</string>
|
<string name="dma_accuracy">Точность DMA</string>
|
||||||
<string name="dma_accuracy_description">Управляет точностью DMA. Безопасная точность может исправить проблемы в некоторых играх, но в некоторых случаях также может повлиять на производительность. Если не уверены, оставьте значение По умолчанию.</string>
|
<string name="dma_accuracy_description">Управляет точностью DMA. Безопасная точность может исправить проблемы в некоторых играх, но в некоторых случаях также может повлиять на производительность. Если не уверены, оставьте значение По умолчанию.</string>
|
||||||
|
<string name="frame_pacing_mode">Режим синхронизации кадров</string>
|
||||||
|
<string name="frame_pacing_mode_description">Управляет синхронизацией кадров в эмуляторе для уменьшения рывков и обеспечения более плавной и стабильной частоты кадров.</string>
|
||||||
<string name="anisotropic_filtering">Анизотропная фильтрация</string>
|
<string name="anisotropic_filtering">Анизотропная фильтрация</string>
|
||||||
<string name="anisotropic_filtering_description">Улучшает качество текстур под углом</string>
|
<string name="anisotropic_filtering_description">Улучшает качество текстур под углом</string>
|
||||||
<string name="vram_usage_mode">Режим VRAM</string>
|
<string name="vram_usage_mode">Режим VRAM</string>
|
||||||
@@ -992,6 +994,13 @@
|
|||||||
<string name="dma_accuracy_unsafe">Небезопасно</string>
|
<string name="dma_accuracy_unsafe">Небезопасно</string>
|
||||||
<string name="dma_accuracy_safe">Безопасный</string>
|
<string name="dma_accuracy_safe">Безопасный</string>
|
||||||
|
|
||||||
|
<!-- Frame Pacing Mode -->
|
||||||
|
<string name="frame_pacing_mode_target_Auto">Авто</string>
|
||||||
|
<string name="frame_pacing_mode_target_30">30 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_60">60 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_90">90 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_120">120 FPS</string>
|
||||||
|
|
||||||
<!-- ASTC Recompression Method Choices -->
|
<!-- ASTC Recompression Method Choices -->
|
||||||
<string name="astc_recompression_uncompressed">Без сжатия</string>
|
<string name="astc_recompression_uncompressed">Без сжатия</string>
|
||||||
<!-- ASTC Recompression Method Choices -->
|
<!-- ASTC Recompression Method Choices -->
|
||||||
|
|||||||
@@ -469,6 +469,8 @@
|
|||||||
<string name="renderer_accuracy_description">Керує режимом емуляції ГП. Більшість ігор добре візуалізуються з режимами «Швидко» або «Збалансовано», але деякі ігри можуть потребувати режиму «Точно». Частинки зазвичай правильно візуалізуються лише з режимом «Точно».</string>
|
<string name="renderer_accuracy_description">Керує режимом емуляції ГП. Більшість ігор добре візуалізуються з режимами «Швидко» або «Збалансовано», але деякі ігри можуть потребувати режиму «Точно». Частинки зазвичай правильно візуалізуються лише з режимом «Точно».</string>
|
||||||
<string name="dma_accuracy">Точність DMA</string>
|
<string name="dma_accuracy">Точність DMA</string>
|
||||||
<string name="dma_accuracy_description">Керує точністю DMA. Безпечна точність може виправити проблеми в деяких іграх, але в деяких випадках також може вплинути на продуктивність. Якщо не впевнені, залиште це значення за замовчуванням.</string>
|
<string name="dma_accuracy_description">Керує точністю DMA. Безпечна точність може виправити проблеми в деяких іграх, але в деяких випадках також може вплинути на продуктивність. Якщо не впевнені, залиште це значення за замовчуванням.</string>
|
||||||
|
<string name="frame_pacing_mode">Режим виведення кадрів</string>
|
||||||
|
<string name="frame_pacing_mode_description">Керує тим, як емулятор виконує виведення кадрів, щоб зменшити затримки й забезпечити плавнішу й стабільнішу частоту кадрів.</string>
|
||||||
<string name="anisotropic_filtering">Анізотропне фільтрування</string>
|
<string name="anisotropic_filtering">Анізотропне фільтрування</string>
|
||||||
<string name="anisotropic_filtering_description">Покращує якість текстур під кутом.</string>
|
<string name="anisotropic_filtering_description">Покращує якість текстур під кутом.</string>
|
||||||
<string name="vram_usage_mode">Режим використання VRAM</string>
|
<string name="vram_usage_mode">Режим використання VRAM</string>
|
||||||
@@ -993,6 +995,13 @@
|
|||||||
<string name="dma_accuracy_unsafe">Небезпечно</string>
|
<string name="dma_accuracy_unsafe">Небезпечно</string>
|
||||||
<string name="dma_accuracy_safe">Безпечно</string>
|
<string name="dma_accuracy_safe">Безпечно</string>
|
||||||
|
|
||||||
|
<!-- Frame Pacing Mode -->
|
||||||
|
<string name="frame_pacing_mode_target_Auto">Автоматично</string>
|
||||||
|
<string name="frame_pacing_mode_target_30">30 к/с</string>
|
||||||
|
<string name="frame_pacing_mode_target_60">60 к/с</string>
|
||||||
|
<string name="frame_pacing_mode_target_90">90 к/с</string>
|
||||||
|
<string name="frame_pacing_mode_target_120">120 к/с</string>
|
||||||
|
|
||||||
<!-- ASTC Recompression Method Choices -->
|
<!-- ASTC Recompression Method Choices -->
|
||||||
<string name="astc_recompression_uncompressed">Без стиснення</string>
|
<string name="astc_recompression_uncompressed">Без стиснення</string>
|
||||||
<!-- ASTC Recompression Method Choices -->
|
<!-- ASTC Recompression Method Choices -->
|
||||||
|
|||||||
@@ -462,6 +462,8 @@
|
|||||||
<string name="renderer_accuracy_description">控制 GPU 模拟的精确度。大部分游戏在性能或平衡模式下可以正常渲染,但部分游戏需要设置为精确。粒子效果通常只有在精确模式下才能正确显示。</string>
|
<string name="renderer_accuracy_description">控制 GPU 模拟的精确度。大部分游戏在性能或平衡模式下可以正常渲染,但部分游戏需要设置为精确。粒子效果通常只有在精确模式下才能正确显示。</string>
|
||||||
<string name="dma_accuracy">DMA 精度</string>
|
<string name="dma_accuracy">DMA 精度</string>
|
||||||
<string name="dma_accuracy_description">控制 DMA 精度。安全精度可以修复某些游戏中的问题,但在某些情况下也可能影响性能。如果不确定,请保留为“默认”。</string>
|
<string name="dma_accuracy_description">控制 DMA 精度。安全精度可以修复某些游戏中的问题,但在某些情况下也可能影响性能。如果不确定,请保留为“默认”。</string>
|
||||||
|
<string name="frame_pacing_mode">帧同步模式</string>
|
||||||
|
<string name="frame_pacing_mode_description">控制模拟器如何管理帧同步,以减少卡顿,使帧率表现更加平稳顺滑。</string>
|
||||||
<string name="anisotropic_filtering">各向异性过滤</string>
|
<string name="anisotropic_filtering">各向异性过滤</string>
|
||||||
<string name="anisotropic_filtering_description">提高斜角的纹理质量</string>
|
<string name="anisotropic_filtering_description">提高斜角的纹理质量</string>
|
||||||
<string name="vram_usage_mode">显存使用模式</string>
|
<string name="vram_usage_mode">显存使用模式</string>
|
||||||
@@ -986,6 +988,13 @@
|
|||||||
<string name="dma_accuracy_unsafe">不安全</string>
|
<string name="dma_accuracy_unsafe">不安全</string>
|
||||||
<string name="dma_accuracy_safe">安全</string>
|
<string name="dma_accuracy_safe">安全</string>
|
||||||
|
|
||||||
|
<!-- Frame Pacing Mode -->
|
||||||
|
<string name="frame_pacing_mode_target_Auto">自动</string>
|
||||||
|
<string name="frame_pacing_mode_target_30">30 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_60">60 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_90">90 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_120">120 FPS</string>
|
||||||
|
|
||||||
<!-- ASTC Recompression Method Choices -->
|
<!-- ASTC Recompression Method Choices -->
|
||||||
<string name="astc_recompression_uncompressed">不压缩</string>
|
<string name="astc_recompression_uncompressed">不压缩</string>
|
||||||
<!-- ASTC Recompression Method Choices -->
|
<!-- ASTC Recompression Method Choices -->
|
||||||
|
|||||||
@@ -533,6 +533,20 @@
|
|||||||
<item>2</item>
|
<item>2</item>
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
|
<string-array name="framePacingModeNames">
|
||||||
|
<item>@string/frame_pacing_mode_target_Auto</item>
|
||||||
|
<item>@string/frame_pacing_mode_target_30</item>
|
||||||
|
<item>@string/frame_pacing_mode_target_60</item>
|
||||||
|
<item>@string/frame_pacing_mode_target_90</item>
|
||||||
|
<item>@string/frame_pacing_mode_target_120</item>
|
||||||
|
</string-array>
|
||||||
|
<integer-array name="framePacingModeValues">
|
||||||
|
<item>0</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
<item>3</item>
|
||||||
|
<item>4</item>
|
||||||
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="appletEntries">
|
<string-array name="appletEntries">
|
||||||
<item>@string/applet_hle</item>
|
<item>@string/applet_hle</item>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?><resources><color name='ic_launcher_background'>#43fcfcff</color></resources>
|
<?xml version='1.0' encoding='utf-8'?><resources><color name='ic_launcher_background'>#1F143C</color></resources>
|
||||||
|
|||||||
@@ -479,6 +479,8 @@
|
|||||||
<string name="renderer_accuracy_description">Controls the GPU emulation mode. Most games render fine with Fast or Balanced modes, but Accurate is still required for some. Particles tend to only render correctly with Accurate mode.</string>
|
<string name="renderer_accuracy_description">Controls the GPU emulation mode. Most games render fine with Fast or Balanced modes, but Accurate is still required for some. Particles tend to only render correctly with Accurate mode.</string>
|
||||||
<string name="dma_accuracy">DMA Accuracy</string>
|
<string name="dma_accuracy">DMA Accuracy</string>
|
||||||
<string name="dma_accuracy_description">Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave this on Default.</string>
|
<string name="dma_accuracy_description">Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave this on Default.</string>
|
||||||
|
<string name="frame_pacing_mode">Frame Pacing Mode</string>
|
||||||
|
<string name="frame_pacing_mode_description">Controls how the emulator manages frame pacing to reduce stuttering and make the frame rate smoother and more consistent.</string>
|
||||||
<string name="anisotropic_filtering">Anisotropic filtering</string>
|
<string name="anisotropic_filtering">Anisotropic filtering</string>
|
||||||
<string name="anisotropic_filtering_description">Improves the quality of textures when viewed at oblique angles</string>
|
<string name="anisotropic_filtering_description">Improves the quality of textures when viewed at oblique angles</string>
|
||||||
<string name="vram_usage_mode">VRAM Usage Mode</string>
|
<string name="vram_usage_mode">VRAM Usage Mode</string>
|
||||||
@@ -1036,6 +1038,13 @@
|
|||||||
<string name="dma_accuracy_unsafe">Unsafe</string>
|
<string name="dma_accuracy_unsafe">Unsafe</string>
|
||||||
<string name="dma_accuracy_safe">Safe</string>
|
<string name="dma_accuracy_safe">Safe</string>
|
||||||
|
|
||||||
|
<!-- Frame Pacing Mode -->
|
||||||
|
<string name="frame_pacing_mode_target_Auto">Auto</string>
|
||||||
|
<string name="frame_pacing_mode_target_30">30 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_60">60 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_90">90 FPS</string>
|
||||||
|
<string name="frame_pacing_mode_target_120">120 FPS</string>
|
||||||
|
|
||||||
<!-- ASTC Decoding Method Choices -->
|
<!-- ASTC Decoding Method Choices -->
|
||||||
<string name="accelerate_astc_cpu" translatable="false">CPU</string>
|
<string name="accelerate_astc_cpu" translatable="false">CPU</string>
|
||||||
<string name="accelerate_astc_gpu" translatable="false">GPU</string>
|
<string name="accelerate_astc_gpu" translatable="false">GPU</string>
|
||||||
|
|||||||
@@ -134,8 +134,6 @@ add_library(
|
|||||||
typed_address.h
|
typed_address.h
|
||||||
uint128.h
|
uint128.h
|
||||||
unique_function.h
|
unique_function.h
|
||||||
random.cpp
|
|
||||||
random.h
|
|
||||||
uuid.cpp
|
uuid.cpp
|
||||||
uuid.h
|
uuid.h
|
||||||
vector_math.h
|
vector_math.h
|
||||||
|
|||||||
@@ -30,8 +30,6 @@
|
|||||||
#include <sys/random.h>
|
#include <sys/random.h>
|
||||||
#include <mach/vm_map.h>
|
#include <mach/vm_map.h>
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
#elif defined(__FreeBSD__)
|
|
||||||
#include <sys/shm.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FreeBSD
|
// FreeBSD
|
||||||
@@ -505,7 +503,8 @@ public:
|
|||||||
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__)
|
||||||
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__) && __FreeBSD__ < 13
|
||||||
|
// XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30
|
||||||
fd = shm_open(SHM_ANON, O_RDWR, 0600);
|
fd = shm_open(SHM_ANON, O_RDWR, 0600);
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
// macOS doesn't have memfd_create, use anonymous temporary file
|
// macOS doesn't have memfd_create, use anonymous temporary file
|
||||||
@@ -572,9 +571,9 @@ public:
|
|||||||
if (True(perms & MemoryPermission::Execute))
|
if (True(perms & MemoryPermission::Execute))
|
||||||
prot_flags |= PROT_EXEC;
|
prot_flags |= PROT_EXEC;
|
||||||
#endif
|
#endif
|
||||||
int flags = (fd >= 0 ? MAP_SHARED : MAP_PRIVATE) | MAP_FIXED;
|
int flags = (fd > 0 ? MAP_SHARED : MAP_PRIVATE) | MAP_FIXED;
|
||||||
void* ret = mmap(virtual_base + virtual_offset, length, prot_flags, flags, fd, host_offset);
|
void* ret = mmap(virtual_base + virtual_offset, length, prot_flags, flags, fd, host_offset);
|
||||||
ASSERT_MSG(ret != MAP_FAILED, "mmap: {} {}", strerror(errno), fd);
|
ASSERT_MSG(ret != MAP_FAILED, "mmap: {}", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unmap(size_t virtual_offset, size_t length) {
|
void Unmap(size_t virtual_offset, size_t length) {
|
||||||
@@ -588,8 +587,9 @@ public:
|
|||||||
auto [merged_pointer, merged_size] =
|
auto [merged_pointer, merged_size] =
|
||||||
free_manager.FreeBlock(virtual_base + virtual_offset, length);
|
free_manager.FreeBlock(virtual_base + virtual_offset, length);
|
||||||
|
|
||||||
void* ret = mmap(merged_pointer, merged_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
|
void* ret = mmap(merged_pointer, merged_size, PROT_NONE,
|
||||||
ASSERT_MSG(ret != MAP_FAILED, "mmap: {}", strerror(errno));
|
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
|
||||||
|
ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute) {
|
void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute) {
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#include <random>
|
|
||||||
#include "common/random.h"
|
|
||||||
|
|
||||||
namespace Common::Random {
|
|
||||||
[[nodiscard]] static std::random_device& GetGlobalRandomDevice() noexcept {
|
|
||||||
static std::random_device g_random_device{};
|
|
||||||
return g_random_device;
|
|
||||||
}
|
|
||||||
[[nodiscard]] u32 Random32(u32 seed) noexcept {
|
|
||||||
return GetGlobalRandomDevice()();
|
|
||||||
}
|
|
||||||
[[nodiscard]] u64 Random64(u64 seed) noexcept {
|
|
||||||
return GetGlobalRandomDevice()();
|
|
||||||
}
|
|
||||||
[[nodiscard]] std::mt19937 GetMT19937() noexcept {
|
|
||||||
return std::mt19937(GetGlobalRandomDevice()());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <random>
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
namespace Common::Random {
|
|
||||||
[[nodiscard]] u32 Random32(u32 seed) noexcept;
|
|
||||||
[[nodiscard]] u64 Random64(u64 seed) noexcept;
|
|
||||||
[[nodiscard]] std::mt19937 GetMT19937() noexcept;
|
|
||||||
}
|
|
||||||
@@ -186,7 +186,7 @@ bool IsFastmemEnabled() {
|
|||||||
// Only 4kb systems support host MMU right now
|
// Only 4kb systems support host MMU right now
|
||||||
// TODO: Support this
|
// TODO: Support this
|
||||||
return getpagesize() == 4096;
|
return getpagesize() == 4096;
|
||||||
#elif !defined(__APPLE__) && !defined(__ANDROID__) && !defined(_WIN32) && !defined(__linux__) && !defined(__FreeBSD__)
|
#elif !defined(__APPLE__) && !defined(__ANDROID__) && !defined(_WIN32) && !defined(__linux__)
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
@@ -218,6 +218,12 @@ public:
|
|||||||
return t0;
|
return t0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 GenerateRandomU64() {
|
||||||
|
const u32 lo = this->GenerateRandomU32();
|
||||||
|
const u32 hi = this->GenerateRandomU32();
|
||||||
|
return (u64{hi} << 32) | u64{lo};
|
||||||
|
}
|
||||||
|
|
||||||
float GenerateRandomF32() {
|
float GenerateRandomF32() {
|
||||||
// Floats have 24 bits of mantissa.
|
// Floats have 24 bits of mantissa.
|
||||||
constexpr u32 MantissaBits = 24;
|
constexpr u32 MantissaBits = 24;
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -13,7 +10,6 @@
|
|||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/tiny_mt.h"
|
#include "common/tiny_mt.h"
|
||||||
#include "common/uuid.h"
|
#include "common/uuid.h"
|
||||||
#include "common/random.h"
|
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
@@ -179,16 +175,21 @@ u128 UUID::AsU128() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UUID UUID::MakeRandom() {
|
UUID UUID::MakeRandom() {
|
||||||
return MakeRandomWithSeed(Common::Random::Random32(0));
|
std::random_device device;
|
||||||
|
|
||||||
|
return MakeRandomWithSeed(device());
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID UUID::MakeRandomWithSeed(u32 seed) {
|
UUID UUID::MakeRandomWithSeed(u32 seed) {
|
||||||
// Create and initialize our RNG.
|
// Create and initialize our RNG.
|
||||||
TinyMT rng;
|
TinyMT rng;
|
||||||
rng.Initialize(seed);
|
rng.Initialize(seed);
|
||||||
|
|
||||||
UUID uuid;
|
UUID uuid;
|
||||||
|
|
||||||
// Populate the UUID with random bytes.
|
// Populate the UUID with random bytes.
|
||||||
rng.GenerateRandomBytes(uuid.uuid.data(), sizeof(UUID));
|
rng.GenerateRandomBytes(uuid.uuid.data(), sizeof(UUID));
|
||||||
|
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ void ArmDynarmic32::MakeJit(Common::PageTable* page_table) {
|
|||||||
config.only_detect_misalignment_via_page_table_on_page_boundary = true;
|
config.only_detect_misalignment_via_page_table_on_page_boundary = true;
|
||||||
|
|
||||||
config.fastmem_pointer = page_table->fastmem_arena ?
|
config.fastmem_pointer = page_table->fastmem_arena ?
|
||||||
std::optional<uintptr_t>{uintptr_t(page_table->fastmem_arena)} :
|
std::optional<uintptr_t>{reinterpret_cast<uintptr_t>(page_table->fastmem_arena)} :
|
||||||
std::nullopt;
|
std::nullopt;
|
||||||
|
|
||||||
config.fastmem_exclusive_access = config.fastmem_pointer != std::nullopt;
|
config.fastmem_exclusive_access = config.fastmem_pointer != std::nullopt;
|
||||||
@@ -286,6 +286,10 @@ void ArmDynarmic32::MakeJit(Common::PageTable* page_table) {
|
|||||||
// Curated optimizations
|
// Curated optimizations
|
||||||
case Settings::CpuAccuracy::Auto:
|
case Settings::CpuAccuracy::Auto:
|
||||||
config.unsafe_optimizations = true;
|
config.unsafe_optimizations = true;
|
||||||
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) || defined(__DragonFly__) || defined(__NetBSD__)
|
||||||
|
config.fastmem_pointer = std::nullopt;
|
||||||
|
config.fastmem_exclusive_access = false;
|
||||||
|
#endif
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
|
||||||
@@ -300,10 +304,6 @@ void ArmDynarmic32::MakeJit(Common::PageTable* page_table) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!Settings::IsFastmemEnabled()) {
|
|
||||||
config.fastmem_pointer = std::nullopt;
|
|
||||||
config.fastmem_exclusive_access = false;
|
|
||||||
}
|
|
||||||
m_jit.emplace(config);
|
m_jit.emplace(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -338,6 +338,10 @@ void ArmDynarmic64::MakeJit(Common::PageTable* page_table, std::size_t address_s
|
|||||||
// Safe optimisations
|
// Safe optimisations
|
||||||
case Settings::CpuAccuracy::Auto:
|
case Settings::CpuAccuracy::Auto:
|
||||||
config.unsafe_optimizations = true;
|
config.unsafe_optimizations = true;
|
||||||
|
#if !defined(__APPLE__) && !defined(__linux__) && !defined(__ANDROID__) && !defined(_WIN32)
|
||||||
|
config.fastmem_pointer = std::nullopt;
|
||||||
|
config.fastmem_exclusive_access = false;
|
||||||
|
#endif
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||||
config.fastmem_address_space_bits = 64;
|
config.fastmem_address_space_bits = 64;
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
|
||||||
@@ -351,10 +355,6 @@ void ArmDynarmic64::MakeJit(Common::PageTable* page_table, std::size_t address_s
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!Settings::IsFastmemEnabled()) {
|
|
||||||
config.fastmem_pointer = std::nullopt;
|
|
||||||
config.fastmem_exclusive_access = false;
|
|
||||||
}
|
|
||||||
m_jit.emplace(config);
|
m_jit.emplace(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -773,11 +773,7 @@ std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, m
|
|||||||
bool was_executed = false;
|
bool was_executed = false;
|
||||||
|
|
||||||
auto decoder = Dynarmic::A64::Decode<VisitorBase>(instruction);
|
auto decoder = Dynarmic::A64::Decode<VisitorBase>(instruction);
|
||||||
if (decoder) {
|
was_executed = decoder.get().call(visitor, instruction);
|
||||||
was_executed = decoder->get().call(visitor, instruction);
|
|
||||||
} else {
|
|
||||||
was_executed = false;
|
|
||||||
}
|
|
||||||
return was_executed ? std::optional<u64>(pc + 4) : std::nullopt;
|
return was_executed ? std::optional<u64>(pc + 4) : std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
#include "common/hex_util.h"
|
#include "common/hex_util.h"
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/random.h"
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/crypto/key_manager.h"
|
#include "core/crypto/key_manager.h"
|
||||||
#include "core/file_sys/card_image.h"
|
#include "core/file_sys/card_image.h"
|
||||||
@@ -491,13 +490,17 @@ std::vector<NcaID> PlaceholderCache::List() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NcaID PlaceholderCache::Generate() {
|
NcaID PlaceholderCache::Generate() {
|
||||||
auto gen = Common::Random::GetMT19937();
|
std::random_device device;
|
||||||
|
std::mt19937 gen(device());
|
||||||
std::uniform_int_distribution<u64> distribution(1, (std::numeric_limits<u64>::max)());
|
std::uniform_int_distribution<u64> distribution(1, (std::numeric_limits<u64>::max)());
|
||||||
|
|
||||||
NcaID out{};
|
NcaID out{};
|
||||||
|
|
||||||
const auto v1 = distribution(gen);
|
const auto v1 = distribution(gen);
|
||||||
const auto v2 = distribution(gen);
|
const auto v2 = distribution(gen);
|
||||||
std::memcpy(out.data(), &v1, sizeof(u64));
|
std::memcpy(out.data(), &v1, sizeof(u64));
|
||||||
std::memcpy(out.data() + sizeof(u64), &v2, sizeof(u64));
|
std::memcpy(out.data() + sizeof(u64), &v2, sizeof(u64));
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
@@ -7,7 +7,6 @@
|
|||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
#include "common/literals.h"
|
#include "common/literals.h"
|
||||||
#include "common/random.h"
|
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
|
||||||
#include "core/hle/kernel/board/nintendo/nx/k_system_control.h"
|
#include "core/hle/kernel/board/nintendo/nx/k_system_control.h"
|
||||||
@@ -202,8 +201,15 @@ u64 GenerateUniformRange(u64 min, u64 max, F f) {
|
|||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
|
u64 KSystemControl::GenerateRandomU64() {
|
||||||
|
std::random_device device;
|
||||||
|
std::mt19937 gen(device());
|
||||||
|
std::uniform_int_distribution<u64> distribution(1, (std::numeric_limits<u64>::max)());
|
||||||
|
return distribution(gen);
|
||||||
|
}
|
||||||
|
|
||||||
u64 KSystemControl::GenerateRandomRange(u64 min, u64 max) {
|
u64 KSystemControl::GenerateRandomRange(u64 min, u64 max) {
|
||||||
return GenerateUniformRange(min, max, Common::Random::GetMT19937());
|
return GenerateUniformRange(min, max, GenerateRandomU64);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t KSystemControl::CalculateRequiredSecureMemorySize(size_t size, u32 pool) {
|
size_t KSystemControl::CalculateRequiredSecureMemorySize(size_t size, u32 pool) {
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -36,6 +33,7 @@ public:
|
|||||||
|
|
||||||
// Randomness.
|
// Randomness.
|
||||||
static u64 GenerateRandomRange(u64 min, u64 max);
|
static u64 GenerateRandomRange(u64 min, u64 max);
|
||||||
|
static u64 GenerateRandomU64();
|
||||||
|
|
||||||
// Secure Memory.
|
// Secure Memory.
|
||||||
static size_t CalculateRequiredSecureMemorySize(size_t size, u32 pool);
|
static size_t CalculateRequiredSecureMemorySize(size_t size, u32 pool);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
#include "common/bit_util.h"
|
#include "common/bit_util.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/tiny_mt.h"
|
#include "common/tiny_mt.h"
|
||||||
#include "common/random.h"
|
|
||||||
#include "core/hle/kernel/k_system_control.h"
|
#include "core/hle/kernel/k_system_control.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
@@ -24,7 +23,7 @@ public:
|
|||||||
class RandomBitGenerator {
|
class RandomBitGenerator {
|
||||||
public:
|
public:
|
||||||
RandomBitGenerator() {
|
RandomBitGenerator() {
|
||||||
m_rng.Initialize(u32(Common::Random::Random64(0)));
|
m_rng.Initialize(static_cast<u32>(KSystemControl::GenerateRandomU64()));
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 SelectRandomBit(u64 bitmap) {
|
u64 SelectRandomBit(u64 bitmap) {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
#include "common/fiber.h"
|
#include "common/fiber.h"
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/random.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/cpu_manager.h"
|
#include "core/cpu_manager.h"
|
||||||
#include "core/hardware_properties.h"
|
#include "core/hardware_properties.h"
|
||||||
@@ -46,7 +45,8 @@ namespace {
|
|||||||
|
|
||||||
constexpr inline s32 TerminatingThreadPriority = Kernel::Svc::SystemThreadPriorityHighest - 1;
|
constexpr inline s32 TerminatingThreadPriority = Kernel::Svc::SystemThreadPriorityHighest - 1;
|
||||||
|
|
||||||
static void ResetThreadContext32(Kernel::Svc::ThreadContext& ctx, u64 stack_top, u64 entry_point, u64 arg) {
|
static void ResetThreadContext32(Kernel::Svc::ThreadContext& ctx, u64 stack_top, u64 entry_point,
|
||||||
|
u64 arg) {
|
||||||
ctx = {};
|
ctx = {};
|
||||||
ctx.r[0] = arg;
|
ctx.r[0] = arg;
|
||||||
ctx.r[15] = entry_point;
|
ctx.r[15] = entry_point;
|
||||||
@@ -55,10 +55,11 @@ static void ResetThreadContext32(Kernel::Svc::ThreadContext& ctx, u64 stack_top,
|
|||||||
ctx.fpsr = 0;
|
ctx.fpsr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ResetThreadContext64(Kernel::Svc::ThreadContext& ctx, u64 stack_top, u64 entry_point, u64 arg) {
|
static void ResetThreadContext64(Kernel::Svc::ThreadContext& ctx, u64 stack_top, u64 entry_point,
|
||||||
|
u64 arg) {
|
||||||
ctx = {};
|
ctx = {};
|
||||||
ctx.r[0] = arg;
|
ctx.r[0] = arg;
|
||||||
ctx.r[18] = Common::Random::Random64(0) | 1;
|
ctx.r[18] = Kernel::KSystemControl::GenerateRandomU64() | 1;
|
||||||
ctx.pc = entry_point;
|
ctx.pc = entry_point;
|
||||||
ctx.sp = stack_top;
|
ctx.sp = stack_top;
|
||||||
ctx.fpcr = 0;
|
ctx.fpcr = 0;
|
||||||
|
|||||||
@@ -438,20 +438,20 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ
|
|||||||
|
|
||||||
template <bool Domain, typename T, typename... A>
|
template <bool Domain, typename T, typename... A>
|
||||||
void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) {
|
void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) {
|
||||||
const auto mgr = ctx.GetManager().get();
|
|
||||||
// Verify domain state.
|
// Verify domain state.
|
||||||
if constexpr (!Domain) {
|
if constexpr (!Domain) {
|
||||||
const bool is_domain = mgr ? mgr->IsDomain() : false;
|
const auto _mgr = ctx.GetManager();
|
||||||
ASSERT_MSG(!is_domain,
|
const bool _is_domain = _mgr ? _mgr->IsDomain() : false;
|
||||||
"Non-domain reply used on domain session\n"
|
ASSERT_MSG(!_is_domain,
|
||||||
"Service={} (TIPC={} CmdType={} Cmd=0x{:08X}\n"
|
"Non-domain reply used on domain session\n"
|
||||||
"HasDomainHeader={} DomainHandlers={}\nDesc={}",
|
"Service={} (TIPC={} CmdType={} Cmd=0x{:08X}\n"
|
||||||
t.GetServiceName(), ctx.IsTipc(),
|
"HasDomainHeader={} DomainHandlers={}\nDesc={}",
|
||||||
u32(ctx.GetCommandType()), u32(ctx.GetCommand()),
|
t.GetServiceName(), ctx.IsTipc(),
|
||||||
ctx.HasDomainMessageHeader(), mgr ? u32(mgr->DomainHandlerCount()) : 0u,
|
static_cast<u32>(ctx.GetCommandType()), static_cast<u32>(ctx.GetCommand()),
|
||||||
ctx.Description());
|
ctx.HasDomainMessageHeader(), _mgr ? static_cast<u32>(_mgr->DomainHandlerCount()) : 0u,
|
||||||
|
ctx.Description());
|
||||||
}
|
}
|
||||||
const bool is_domain = Domain ? mgr->IsDomain() : false;
|
const bool is_domain = Domain ? ctx.GetManager()->IsDomain() : false;
|
||||||
|
|
||||||
static_assert(ConstIfReference<A...>(), "Arguments taken by reference must be const");
|
static_assert(ConstIfReference<A...>(), "Arguments taken by reference must be const");
|
||||||
using MethodArguments = std::tuple<std::remove_cvref_t<A>...>;
|
using MethodArguments = std::tuple<std::remove_cvref_t<A>...>;
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -81,29 +78,32 @@ public:
|
|||||||
memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH);
|
memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH);
|
||||||
|
|
||||||
IPC::CommandHeader header{};
|
IPC::CommandHeader header{};
|
||||||
auto const mgr = ctx.GetManager().get();
|
|
||||||
|
|
||||||
// The entire size of the raw data section in u32 units, including the 16 bytes of mandatory
|
// The entire size of the raw data section in u32 units, including the 16 bytes of mandatory
|
||||||
// padding.
|
// padding.
|
||||||
u32 raw_data_size = ctx.write_size = ctx.IsTipc() ? normal_params_size - 1 : normal_params_size;
|
u32 raw_data_size = ctx.write_size =
|
||||||
|
ctx.IsTipc() ? normal_params_size - 1 : normal_params_size;
|
||||||
u32 num_handles_to_move{};
|
u32 num_handles_to_move{};
|
||||||
u32 num_domain_objects{};
|
u32 num_domain_objects{};
|
||||||
const bool always_move_handles = (u32(flags) & u32(Flags::AlwaysMoveHandles)) != 0;
|
const bool always_move_handles{
|
||||||
if (!mgr->IsDomain() || always_move_handles) {
|
(static_cast<u32>(flags) & static_cast<u32>(Flags::AlwaysMoveHandles)) != 0};
|
||||||
|
if (!ctx.GetManager()->IsDomain() || always_move_handles) {
|
||||||
num_handles_to_move = num_objects_to_move;
|
num_handles_to_move = num_objects_to_move;
|
||||||
} else {
|
} else {
|
||||||
num_domain_objects = num_objects_to_move;
|
num_domain_objects = num_objects_to_move;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mgr->IsDomain()) {
|
if (ctx.GetManager()->IsDomain()) {
|
||||||
raw_data_size += u32(sizeof(DomainMessageHeader) / sizeof(u32) + num_domain_objects);
|
raw_data_size +=
|
||||||
|
static_cast<u32>(sizeof(DomainMessageHeader) / sizeof(u32) + num_domain_objects);
|
||||||
ctx.write_size += num_domain_objects;
|
ctx.write_size += num_domain_objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.IsTipc()) {
|
if (ctx.IsTipc()) {
|
||||||
header.type.Assign(ctx.GetCommandType());
|
header.type.Assign(ctx.GetCommandType());
|
||||||
} else {
|
} else {
|
||||||
raw_data_size += u32(sizeof(IPC::DataPayloadHeader) / sizeof(u32) + 4 + normal_params_size);
|
raw_data_size += static_cast<u32>(sizeof(IPC::DataPayloadHeader) / sizeof(u32) + 4 +
|
||||||
|
normal_params_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
header.data_size.Assign(raw_data_size);
|
header.data_size.Assign(raw_data_size);
|
||||||
@@ -126,7 +126,7 @@ public:
|
|||||||
if (!ctx.IsTipc()) {
|
if (!ctx.IsTipc()) {
|
||||||
AlignWithPadding();
|
AlignWithPadding();
|
||||||
|
|
||||||
if (mgr->IsDomain() && ctx.HasDomainMessageHeader()) {
|
if (ctx.GetManager()->IsDomain() && ctx.HasDomainMessageHeader()) {
|
||||||
IPC::DomainMessageHeader domain_header{};
|
IPC::DomainMessageHeader domain_header{};
|
||||||
domain_header.num_objects = num_domain_objects;
|
domain_header.num_objects = num_domain_objects;
|
||||||
PushRaw(domain_header);
|
PushRaw(domain_header);
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -10,7 +7,6 @@
|
|||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/random.h"
|
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "common/uuid.h"
|
#include "common/uuid.h"
|
||||||
#include "core/hle/service/mii/mii_types.h"
|
#include "core/hle/service/mii/mii_types.h"
|
||||||
@@ -69,9 +65,11 @@ public:
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static T GetRandomValue(T min, T max) {
|
static T GetRandomValue(T min, T max) {
|
||||||
std::uniform_int_distribution<u64> distribution{u64(min), u64(max)};
|
std::random_device device;
|
||||||
auto gen = Common::Random::GetMT19937();
|
std::mt19937 gen(device());
|
||||||
return T(distribution(gen));
|
std::uniform_int_distribution<u64> distribution(static_cast<u64>(min),
|
||||||
|
static_cast<u64>(max));
|
||||||
|
return static_cast<T>(distribution(gen));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
@@ -373,8 +373,6 @@ Result SharedBufferManager::PresentSharedFrameBuffer(android::Fence fence,
|
|||||||
android::Status::NoError,
|
android::Status::NoError,
|
||||||
VI::ResultOperationFailed);
|
VI::ResultOperationFailed);
|
||||||
|
|
||||||
(void)m_container.SetLayerZIndex(layer_id, 100000);
|
|
||||||
|
|
||||||
// We succeeded.
|
// We succeeded.
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/random.h"
|
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/file_sys/content_archive.h"
|
#include "core/file_sys/content_archive.h"
|
||||||
@@ -230,7 +229,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
|||||||
// TODO: this is bad form of ASLR, it sucks
|
// TODO: this is bad form of ASLR, it sucks
|
||||||
size_t aslr_offset = ((::Settings::values.rng_seed_enabled.GetValue()
|
size_t aslr_offset = ((::Settings::values.rng_seed_enabled.GetValue()
|
||||||
? ::Settings::values.rng_seed.GetValue()
|
? ::Settings::values.rng_seed.GetValue()
|
||||||
: Common::Random::Random64(0)) * 0x734287f27) & 0xfff000;
|
: std::rand()) * 0x734287f27) & 0xfff000;
|
||||||
|
|
||||||
// Setup the process code layout
|
// Setup the process code layout
|
||||||
if (process.LoadFromMetadata(metadata, code_size, fastmem_base, aslr_offset, is_hbl).IsError()) {
|
if (process.LoadFromMetadata(metadata, code_size, fastmem_base, aslr_offset, is_hbl).IsError()) {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/random.h"
|
|
||||||
#include "core/file_sys/kernel_executable.h"
|
#include "core/file_sys/kernel_executable.h"
|
||||||
#include "core/file_sys/program_metadata.h"
|
#include "core/file_sys/program_metadata.h"
|
||||||
#include "core/hle/kernel/code_set.h"
|
#include "core/hle/kernel/code_set.h"
|
||||||
@@ -91,7 +90,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
|
|||||||
// TODO: this is bad form of ASLR, it sucks
|
// TODO: this is bad form of ASLR, it sucks
|
||||||
size_t aslr_offset = ((::Settings::values.rng_seed_enabled.GetValue()
|
size_t aslr_offset = ((::Settings::values.rng_seed_enabled.GetValue()
|
||||||
? ::Settings::values.rng_seed.GetValue()
|
? ::Settings::values.rng_seed.GetValue()
|
||||||
: Common::Random::Random64(0)) * 0x734287f27) & 0xfff000;
|
: std::rand()) * 0x734287f27) & 0xfff000;
|
||||||
|
|
||||||
// Setup the process code layout
|
// Setup the process code layout
|
||||||
if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), codeset.memory.size(), 0, aslr_offset, false).IsError()) {
|
if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), codeset.memory.size(), 0, aslr_offset, false).IsError()) {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/random.h"
|
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/file_sys/control_metadata.h"
|
#include "core/file_sys/control_metadata.h"
|
||||||
@@ -244,7 +243,7 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process,
|
|||||||
// TODO: this is bad form of ASLR, it sucks
|
// TODO: this is bad form of ASLR, it sucks
|
||||||
size_t aslr_offset = ((::Settings::values.rng_seed_enabled.GetValue()
|
size_t aslr_offset = ((::Settings::values.rng_seed_enabled.GetValue()
|
||||||
? ::Settings::values.rng_seed.GetValue()
|
? ::Settings::values.rng_seed.GetValue()
|
||||||
: Common::Random::Random64(0)) * 0x734287f27) & 0xfff000;
|
: std::rand()) * 0x734287f27) & 0xfff000;
|
||||||
|
|
||||||
// Setup the process code layout
|
// Setup the process code layout
|
||||||
if (process
|
if (process
|
||||||
|
|||||||
@@ -45,7 +45,11 @@ static inline bool AddressSpaceContains(const Common::PageTable& table, const Co
|
|||||||
// from outside classes. This also allows modification to the internals of the memory
|
// from outside classes. This also allows modification to the internals of the memory
|
||||||
// subsystem without needing to rebuild all files that make use of the memory interface.
|
// subsystem without needing to rebuild all files that make use of the memory interface.
|
||||||
struct Memory::Impl {
|
struct Memory::Impl {
|
||||||
explicit Impl(Core::System& system_) : system{system_} {}
|
explicit Impl(Core::System& system_) : system{system_} {
|
||||||
|
// Initialize thread count based on available cores for parallel memory operations
|
||||||
|
const unsigned int hw_concurrency = std::thread::hardware_concurrency();
|
||||||
|
thread_count = (std::max)(2u, (std::min)(hw_concurrency, 8u)); // Limit to 8 threads max
|
||||||
|
}
|
||||||
|
|
||||||
void SetCurrentPageTable(Kernel::KProcess& process) {
|
void SetCurrentPageTable(Kernel::KProcess& process) {
|
||||||
current_page_table = &process.GetPageTable().GetImpl();
|
current_page_table = &process.GetPageTable().GetImpl();
|
||||||
@@ -852,7 +856,13 @@ struct Memory::Impl {
|
|||||||
Tegra::MaxwellDeviceMemoryManager* gpu_device_memory{};
|
Tegra::MaxwellDeviceMemoryManager* gpu_device_memory{};
|
||||||
Common::PageTable* current_page_table = nullptr;
|
Common::PageTable* current_page_table = nullptr;
|
||||||
|
|
||||||
std::array<VideoCore::RasterizerDownloadArea, Core::Hardware::NUM_CPU_CORES> rasterizer_read_areas{};
|
// Number of threads to use for parallel memory operations
|
||||||
|
unsigned int thread_count = 2;
|
||||||
|
|
||||||
|
// Minimum size in bytes for which parallel processing is beneficial
|
||||||
|
//size_t PARALLEL_THRESHOLD = (L3 CACHE * NUM PHYSICAL CORES); // 64 KB
|
||||||
|
std::array<VideoCore::RasterizerDownloadArea, Core::Hardware::NUM_CPU_CORES>
|
||||||
|
rasterizer_read_areas{};
|
||||||
std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
|
std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
|
||||||
std::array<Common::ScratchBuffer<u32>, Core::Hardware::NUM_CPU_CORES> scratch_buffers{};
|
std::array<Common::ScratchBuffer<u32>, Core::Hardware::NUM_CPU_CORES> scratch_buffers{};
|
||||||
std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
|
std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
@@ -51,12 +51,10 @@ void RenderdocAPI::ToggleCapture() {
|
|||||||
if (!rdoc_api) [[unlikely]] {
|
if (!rdoc_api) [[unlikely]] {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* api = static_cast<RENDERDOC_API_1_6_0*>(rdoc_api);
|
|
||||||
if (!is_capturing) {
|
if (!is_capturing) {
|
||||||
api->StartFrameCapture(NULL, NULL);
|
rdoc_api->StartFrameCapture(NULL, NULL);
|
||||||
} else {
|
} else {
|
||||||
api->EndFrameCapture(NULL, NULL);
|
rdoc_api->EndFrameCapture(NULL, NULL);
|
||||||
}
|
}
|
||||||
is_capturing = !is_capturing;
|
is_capturing = !is_capturing;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
struct RENDERDOC_API_1_7_0;
|
||||||
|
|
||||||
namespace Tools {
|
namespace Tools {
|
||||||
|
|
||||||
class RenderdocAPI {
|
class RenderdocAPI {
|
||||||
@@ -16,7 +18,7 @@ public:
|
|||||||
void ToggleCapture();
|
void ToggleCapture();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void* rdoc_api{};
|
RENDERDOC_API_1_7_0* rdoc_api{};
|
||||||
bool is_capturing{false};
|
bool is_capturing{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -78,9 +78,7 @@ if (MSVC)
|
|||||||
/Zc:throwingNew # Assumes new (without std::nothrow) never returns null.
|
/Zc:throwingNew # Assumes new (without std::nothrow) never returns null.
|
||||||
/volatile:iso # Use strict standard-abiding volatile semantics
|
/volatile:iso # Use strict standard-abiding volatile semantics
|
||||||
/bigobj # Increase number of sections in .obj files
|
/bigobj # Increase number of sections in .obj files
|
||||||
/DNOMINMAX
|
/DNOMINMAX)
|
||||||
/GR-
|
|
||||||
)
|
|
||||||
|
|
||||||
if (CXX_CLANG)
|
if (CXX_CLANG)
|
||||||
list(APPEND DYNARMIC_CXX_FLAGS
|
list(APPEND DYNARMIC_CXX_FLAGS
|
||||||
@@ -93,10 +91,8 @@ else()
|
|||||||
-Wextra
|
-Wextra
|
||||||
-Wcast-qual
|
-Wcast-qual
|
||||||
-pedantic
|
-pedantic
|
||||||
-Wno-missing-braces
|
-Wno-missing-braces)
|
||||||
-fno-rtti
|
|
||||||
#-fno-exceptions
|
|
||||||
)
|
|
||||||
if (CXX_GCC)
|
if (CXX_GCC)
|
||||||
# GCC produces bogus -Warray-bounds warnings from xbyak headers for code paths that are not
|
# GCC produces bogus -Warray-bounds warnings from xbyak headers for code paths that are not
|
||||||
# actually reachable. Specifically, it happens in cases where some code casts an Operand&
|
# actually reachable. Specifically, it happens in cases where some code casts an Operand&
|
||||||
@@ -106,6 +102,7 @@ else()
|
|||||||
list(APPEND DYNARMIC_CXX_FLAGS -Wno-array-bounds)
|
list(APPEND DYNARMIC_CXX_FLAGS -Wno-array-bounds)
|
||||||
list(APPEND DYNARMIC_CXX_FLAGS -Wstack-usage=4096)
|
list(APPEND DYNARMIC_CXX_FLAGS -Wstack-usage=4096)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CXX_CLANG)
|
if (CXX_CLANG)
|
||||||
# Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6.
|
# Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6.
|
||||||
# And this in turns limits the size of a std::array.
|
# And this in turns limits the size of a std::array.
|
||||||
@@ -120,6 +117,7 @@ if (NOT Boost_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(fmt 8 CONFIG)
|
find_package(fmt 8 CONFIG)
|
||||||
|
find_package(mcl 0.1.12 REQUIRED)
|
||||||
find_package(unordered_dense REQUIRED)
|
find_package(unordered_dense REQUIRED)
|
||||||
|
|
||||||
if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS)
|
if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS)
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
string(TOUPPER "${arch}" arch)
|
string(TOUPPER "${arch}" arch)
|
||||||
file(READ "${input_file}" f_contents)
|
file(READ "${input_file}" f_contents)
|
||||||
file(WRITE "${output_file}" "#if defined(ARCHITECTURE_${arch})\n${f_contents}\n#endif\n")
|
file(WRITE "${output_file}" "#include <mcl/macro/architecture.hpp>\n#if defined(MCL_ARCHITECTURE_${arch})\n${f_contents}\n#endif\n")
|
||||||
|
|||||||
@@ -3,12 +3,6 @@
|
|||||||
include(TargetArchitectureSpecificSources)
|
include(TargetArchitectureSpecificSources)
|
||||||
|
|
||||||
add_library(dynarmic STATIC
|
add_library(dynarmic STATIC
|
||||||
mcl/bit.hpp
|
|
||||||
mcl/function_info.hpp
|
|
||||||
mcl/integer_of_size.hpp
|
|
||||||
mcl/intrusive_list.hpp
|
|
||||||
mcl/is_instance_of_template.hpp
|
|
||||||
|
|
||||||
backend/block_range_information.cpp
|
backend/block_range_information.cpp
|
||||||
backend/block_range_information.h
|
backend/block_range_information.h
|
||||||
backend/exception_handler.h
|
backend/exception_handler.h
|
||||||
@@ -359,7 +353,7 @@ set_target_properties(dynarmic PROPERTIES
|
|||||||
target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS})
|
target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS})
|
||||||
|
|
||||||
target_link_libraries(dynarmic PRIVATE unordered_dense::unordered_dense)
|
target_link_libraries(dynarmic PRIVATE unordered_dense::unordered_dense)
|
||||||
target_link_libraries(dynarmic PUBLIC fmt::fmt)
|
target_link_libraries(dynarmic PUBLIC fmt::fmt merry::mcl)
|
||||||
|
|
||||||
if (BOOST_NO_HEADERS)
|
if (BOOST_NO_HEADERS)
|
||||||
target_link_libraries(dynarmic PRIVATE Boost::variant Boost::icl Boost::pool)
|
target_link_libraries(dynarmic PRIVATE Boost::variant Boost::icl Boost::pool)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "dynarmic/common/assert.h"
|
||||||
|
#include <mcl/scope_exit.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/a32_address_space.h"
|
#include "dynarmic/backend/arm64/a32_address_space.h"
|
||||||
@@ -35,9 +36,14 @@ struct Jit::Impl final {
|
|||||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
||||||
|
|
||||||
jit_interface->is_executing = true;
|
jit_interface->is_executing = true;
|
||||||
|
SCOPE_EXIT {
|
||||||
|
jit_interface->is_executing = false;
|
||||||
|
};
|
||||||
|
|
||||||
HaltReason hr = core.Run(current_address_space, current_state, &halt_reason);
|
HaltReason hr = core.Run(current_address_space, current_state, &halt_reason);
|
||||||
|
|
||||||
PerformRequestedCacheInvalidation(hr);
|
PerformRequestedCacheInvalidation(hr);
|
||||||
jit_interface->is_executing = false;
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,9 +52,14 @@ struct Jit::Impl final {
|
|||||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
||||||
|
|
||||||
jit_interface->is_executing = true;
|
jit_interface->is_executing = true;
|
||||||
|
SCOPE_EXIT {
|
||||||
|
jit_interface->is_executing = false;
|
||||||
|
};
|
||||||
|
|
||||||
HaltReason hr = core.Step(current_address_space, current_state, &halt_reason);
|
HaltReason hr = core.Step(current_address_space, current_state, &halt_reason);
|
||||||
|
|
||||||
PerformRequestedCacheInvalidation(hr);
|
PerformRequestedCacheInvalidation(hr);
|
||||||
jit_interface->is_executing = false;
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
||||||
|
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include <mcl/bit/bit_field.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "dynarmic/common/assert.h"
|
||||||
|
#include <mcl/scope_exit.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/a64_address_space.h"
|
#include "dynarmic/backend/arm64/a64_address_space.h"
|
||||||
@@ -33,20 +34,32 @@ struct Jit::Impl final {
|
|||||||
HaltReason Run() {
|
HaltReason Run() {
|
||||||
ASSERT(!is_executing);
|
ASSERT(!is_executing);
|
||||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
||||||
|
|
||||||
is_executing = true;
|
is_executing = true;
|
||||||
|
SCOPE_EXIT {
|
||||||
|
is_executing = false;
|
||||||
|
};
|
||||||
|
|
||||||
HaltReason hr = core.Run(current_address_space, current_state, &halt_reason);
|
HaltReason hr = core.Run(current_address_space, current_state, &halt_reason);
|
||||||
|
|
||||||
PerformRequestedCacheInvalidation(hr);
|
PerformRequestedCacheInvalidation(hr);
|
||||||
is_executing = false;
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HaltReason Step() {
|
HaltReason Step() {
|
||||||
ASSERT(!is_executing);
|
ASSERT(!is_executing);
|
||||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
||||||
|
|
||||||
is_executing = true;
|
is_executing = true;
|
||||||
|
SCOPE_EXIT {
|
||||||
|
is_executing = false;
|
||||||
|
};
|
||||||
|
|
||||||
HaltReason hr = core.Step(current_address_space, current_state, &halt_reason);
|
HaltReason hr = core.Step(current_address_space, current_state, &halt_reason);
|
||||||
|
|
||||||
PerformRequestedCacheInvalidation(hr);
|
PerformRequestedCacheInvalidation(hr);
|
||||||
is_executing = false;
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include <mcl/bit/bit_field.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
#include "dynarmic/common/assert.h"
|
#include "dynarmic/common/assert.h"
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
@@ -36,7 +37,7 @@ constexpr auto Rscratch0() {
|
|||||||
} else if constexpr (bitsize == 64) {
|
} else if constexpr (bitsize == 64) {
|
||||||
return Xscratch0;
|
return Xscratch0;
|
||||||
} else {
|
} else {
|
||||||
return Xscratch0; //UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<bitsize>>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ constexpr auto Rscratch1() {
|
|||||||
} else if constexpr (bitsize == 64) {
|
} else if constexpr (bitsize == 64) {
|
||||||
return Xscratch1;
|
return Xscratch1;
|
||||||
} else {
|
} else {
|
||||||
return Xscratch1; //UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<bitsize>>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
#include "dynarmic/mcl/function_info.hpp"
|
#include <mcl/type_traits/function_info.hpp>
|
||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include <mcl/bit/bit_field.hpp>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -642,7 +642,7 @@ void EmitIR<IR::Opcode::ArithmeticShiftRight64>(oaknut::CodeGenerator& code, Emi
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::BitRotateRight32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::RotateRight32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
@@ -708,7 +708,7 @@ void EmitIR<IR::Opcode::BitRotateRight32>(oaknut::CodeGenerator& code, EmitConte
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::BitRotateRight64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::RotateRight64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
auto& shift_arg = args[1];
|
auto& shift_arg = args[1];
|
||||||
|
|||||||
@@ -209,9 +209,9 @@ void CallbackOnlyEmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitConte
|
|||||||
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr size_t page_table_const_bits = 12;
|
constexpr size_t page_bits = 12;
|
||||||
constexpr size_t page_table_const_size = 1 << page_table_const_bits;
|
constexpr size_t page_size = 1 << page_bits;
|
||||||
constexpr size_t page_table_const_mask = (1 << page_table_const_bits) - 1;
|
constexpr size_t page_mask = (1 << page_bits) - 1;
|
||||||
|
|
||||||
// This function may use Xscratch0 as a scratch register
|
// This function may use Xscratch0 as a scratch register
|
||||||
// Trashes NZCV
|
// Trashes NZCV
|
||||||
@@ -242,28 +242,28 @@ void EmitDetectMisalignedVAddr(oaknut::CodeGenerator& code, EmitContext& ctx, oa
|
|||||||
code.TST(Xaddr, align_mask);
|
code.TST(Xaddr, align_mask);
|
||||||
code.B(NE, *fallback);
|
code.B(NE, *fallback);
|
||||||
} else {
|
} else {
|
||||||
// If (addr & page_table_const_mask) > page_table_const_size - byte_size, use fallback.
|
// If (addr & page_mask) > page_size - byte_size, use fallback.
|
||||||
code.AND(Xscratch0, Xaddr, page_table_const_mask);
|
code.AND(Xscratch0, Xaddr, page_mask);
|
||||||
code.CMP(Xscratch0, page_table_const_size - bitsize / 8);
|
code.CMP(Xscratch0, page_size - bitsize / 8);
|
||||||
code.B(HI, *fallback);
|
code.B(HI, *fallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outputs Xscratch0 = page_table[addr >> page_table_const_bits]
|
// Outputs Xscratch0 = page_table[addr >> page_bits]
|
||||||
// May use Xscratch1 as scratch register
|
// May use Xscratch1 as scratch register
|
||||||
// Address to read/write = [ret0 + ret1], ret0 is always Xscratch0 and ret1 is either Xaddr or Xscratch1
|
// Address to read/write = [ret0 + ret1], ret0 is always Xscratch0 and ret1 is either Xaddr or Xscratch1
|
||||||
// Trashes NZCV
|
// Trashes NZCV
|
||||||
template<size_t bitsize>
|
template<size_t bitsize>
|
||||||
std::pair<oaknut::XReg, oaknut::XReg> InlinePageTableEmitVAddrLookup(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
std::pair<oaknut::XReg, oaknut::XReg> InlinePageTableEmitVAddrLookup(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
||||||
const size_t valid_page_index_bits = ctx.conf.page_table_address_space_bits - page_table_const_bits;
|
const size_t valid_page_index_bits = ctx.conf.page_table_address_space_bits - page_bits;
|
||||||
const size_t unused_top_bits = 64 - ctx.conf.page_table_address_space_bits;
|
const size_t unused_top_bits = 64 - ctx.conf.page_table_address_space_bits;
|
||||||
|
|
||||||
EmitDetectMisalignedVAddr<bitsize>(code, ctx, Xaddr, fallback);
|
EmitDetectMisalignedVAddr<bitsize>(code, ctx, Xaddr, fallback);
|
||||||
|
|
||||||
if (ctx.conf.silently_mirror_page_table || unused_top_bits == 0) {
|
if (ctx.conf.silently_mirror_page_table || unused_top_bits == 0) {
|
||||||
code.UBFX(Xscratch0, Xaddr, page_table_const_bits, valid_page_index_bits);
|
code.UBFX(Xscratch0, Xaddr, page_bits, valid_page_index_bits);
|
||||||
} else {
|
} else {
|
||||||
code.LSR(Xscratch0, Xaddr, page_table_const_bits);
|
code.LSR(Xscratch0, Xaddr, page_bits);
|
||||||
code.TST(Xscratch0, u64(~u64(0)) << valid_page_index_bits);
|
code.TST(Xscratch0, u64(~u64(0)) << valid_page_index_bits);
|
||||||
code.B(NE, *fallback);
|
code.B(NE, *fallback);
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ std::pair<oaknut::XReg, oaknut::XReg> InlinePageTableEmitVAddrLookup(oaknut::Cod
|
|||||||
if (ctx.conf.absolute_offset_page_table) {
|
if (ctx.conf.absolute_offset_page_table) {
|
||||||
return std::make_pair(Xscratch0, Xaddr);
|
return std::make_pair(Xscratch0, Xaddr);
|
||||||
}
|
}
|
||||||
code.AND(Xscratch1, Xaddr, page_table_const_mask);
|
code.AND(Xscratch1, Xaddr, page_mask);
|
||||||
return std::make_pair(Xscratch0, Xscratch1);
|
return std::make_pair(Xscratch0, Xscratch1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
||||||
@@ -45,7 +46,7 @@ static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR:
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qresult->D2(), Qoperand->D2());
|
emit(Qresult->D2(), Qoperand->D2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -68,7 +69,7 @@ static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx
|
|||||||
} else if constexpr (size == 32) {
|
} else if constexpr (size == 32) {
|
||||||
emit(Qresult->D2(), Qoperand->toD().S2());
|
emit(Qresult->D2(), Qoperand->toD().S2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -83,7 +84,7 @@ static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ct
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qresult->toD().S2(), Qoperand->D2());
|
emit(Qresult->toD().S2(), Qoperand->D2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -106,7 +107,7 @@ static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext&
|
|||||||
} else if constexpr (size == 32) {
|
} else if constexpr (size == 32) {
|
||||||
emit(Qresult->D2(), Qoperand->S4());
|
emit(Qresult->D2(), Qoperand->S4());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -121,7 +122,7 @@ static void EmitTwoOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx
|
|||||||
} else if constexpr (size == 32) {
|
} else if constexpr (size == 32) {
|
||||||
emit(Qresult->toD().S2(), Qoperand->toD().S2());
|
emit(Qresult->toD().S2(), Qoperand->toD().S2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -149,7 +150,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qresult->D2(), Qa->D2(), Qb->D2());
|
emit(Qresult->D2(), Qa->D2(), Qb->D2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -174,7 +175,7 @@ static void EmitThreeOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& c
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qresult->Q1(), Qa->toD().D1(), Qb->toD().D1());
|
emit(Qresult->Q1(), Qa->toD().D1(), Qb->toD().D1());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -197,7 +198,7 @@ static void EmitThreeOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& c
|
|||||||
} else if constexpr (size == 32) {
|
} else if constexpr (size == 32) {
|
||||||
emit(Qresult->toD().S2(), Qa->toD().S2(), Qb->toD().S2());
|
emit(Qresult->toD().S2(), Qa->toD().S2(), Qb->toD().S2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -219,7 +220,7 @@ static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qaccumulator->D2(), Qoperand->D2());
|
emit(Qaccumulator->D2(), Qoperand->D2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +241,7 @@ static void EmitImmShift(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* ins
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qresult->D2(), Qoperand->D2(), shift_amount);
|
emit(Qresult->D2(), Qoperand->D2(), shift_amount);
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +269,7 @@ static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Vresult, Qoperand->D2());
|
emit(Vresult, Qoperand->D2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include "dynarmic/mcl/function_info.hpp"
|
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||||
#include "dynarmic/mcl/integer_of_size.hpp"
|
#include <mcl/mp/typelist/cartesian_product.hpp>
|
||||||
|
#include <mcl/mp/typelist/get.hpp>
|
||||||
|
#include <mcl/mp/typelist/lift_sequence.hpp>
|
||||||
|
#include <mcl/mp/typelist/list.hpp>
|
||||||
|
#include <mcl/mp/typelist/lower_to_tuple.hpp>
|
||||||
|
#include <mcl/type_traits/function_info.hpp>
|
||||||
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
||||||
@@ -32,6 +38,8 @@
|
|||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
namespace mp = mcl::mp;
|
||||||
|
|
||||||
using A64FullVectorWidth = std::integral_constant<size_t, 128>;
|
using A64FullVectorWidth = std::integral_constant<size_t, 128>;
|
||||||
|
|
||||||
// Array alias that always sizes itself according to the given type T
|
// Array alias that always sizes itself according to the given type T
|
||||||
@@ -75,7 +83,7 @@ static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR:
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qresult->D2(), Qa->D2());
|
emit(Qresult->D2(), Qa->D2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -103,7 +111,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qresult->D2(), Qa->D2(), Qb->D2());
|
emit(Qresult->D2(), Qa->D2(), Qb->D2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -126,7 +134,7 @@ static void EmitFMA(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* ins
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qresult->D2(), Qm->D2(), Qn->D2());
|
emit(Qresult->D2(), Qm->D2(), Qn->D2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -148,7 +156,7 @@ static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Ins
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qto->D2(), Qfrom->D2(), fbits);
|
emit(Qto->D2(), Qfrom->D2(), fbits);
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -170,7 +178,7 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst)
|
|||||||
} else if constexpr (fsize == 64) {
|
} else if constexpr (fsize == 64) {
|
||||||
return Qto->D2();
|
return Qto->D2();
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<fsize>>);
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
auto Vfrom = [&] {
|
auto Vfrom = [&] {
|
||||||
@@ -179,7 +187,7 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst)
|
|||||||
} else if constexpr (fsize == 64) {
|
} else if constexpr (fsize == 64) {
|
||||||
return Qfrom->D2();
|
return Qfrom->D2();
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<fsize>>);
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2022 MerryMage
|
* Copyright (c) 2022 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
||||||
@@ -41,7 +39,7 @@ static void Emit(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitF
|
|||||||
} else if constexpr (size == 64) {
|
} else if constexpr (size == 64) {
|
||||||
emit(Qresult->D2(), Qa->D2(), Qb->D2());
|
emit(Qresult->D2(), Qa->D2(), Qb->D2());
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<size>>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -10,10 +10,11 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
#include <mcl/hash/xmrx.hpp>
|
||||||
|
#include "dynarmic/common/common_types.h"
|
||||||
#include <ankerl/unordered_dense.h>
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/backend/exception_handler.h"
|
#include "dynarmic/backend/exception_handler.h"
|
||||||
#include "dynarmic/ir/location_descriptor.h"
|
#include "dynarmic/ir/location_descriptor.h"
|
||||||
|
|
||||||
@@ -21,16 +22,9 @@ namespace Dynarmic::Backend::Arm64 {
|
|||||||
|
|
||||||
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
|
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
|
||||||
|
|
||||||
constexpr size_t xmrx(size_t x) noexcept {
|
|
||||||
x ^= x >> 32;
|
|
||||||
x *= 0xff51afd7ed558ccd;
|
|
||||||
x ^= mcl::bit::rotate_right(x, 47) ^ mcl::bit::rotate_right(x, 23);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DoNotFastmemMarkerHash {
|
struct DoNotFastmemMarkerHash {
|
||||||
[[nodiscard]] size_t operator()(const DoNotFastmemMarker& value) const noexcept {
|
size_t operator()(const DoNotFastmemMarker& value) const {
|
||||||
return xmrx(std::get<0>(value).Value() ^ u64(std::get<1>(value)));
|
return mcl::hash::xmrx(std::get<0>(value).Value() ^ static_cast<u64>(std::get<1>(value)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,9 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
#include "dynarmic/common/assert.h"
|
#include "dynarmic/common/assert.h"
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include <mcl/bit/bit_field.hpp>
|
||||||
#include <bit>
|
#include <bit>
|
||||||
|
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/abi.h"
|
#include "dynarmic/backend/arm64/abi.h"
|
||||||
@@ -298,7 +299,7 @@ int RegAlloc::GenerateImmediate(const IR::Value& value) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<kind>>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,8 +317,8 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||||||
return current_location->index;
|
return current_location->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(!bool(ValueInfo(*current_location).realized));
|
ASSERT(!ValueInfo(*current_location).realized);
|
||||||
ASSERT(bool(ValueInfo(*current_location).locked));
|
ASSERT(ValueInfo(*current_location).locked);
|
||||||
|
|
||||||
if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
||||||
const int new_location_index = AllocateRegister(gprs, gpr_order);
|
const int new_location_index = AllocateRegister(gprs, gpr_order);
|
||||||
@@ -365,7 +366,7 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||||||
} else if constexpr (required_kind == HostLoc::Kind::Flags) {
|
} else if constexpr (required_kind == HostLoc::Kind::Flags) {
|
||||||
UNREACHABLE(); //A simple read from flags is likely a logic error
|
UNREACHABLE(); //A simple read from flags is likely a logic error
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<required_kind>>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,7 +390,7 @@ int RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
|
|||||||
flags.SetupLocation(value);
|
flags.SetupLocation(value);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<kind>>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,7 +410,7 @@ int RegAlloc::RealizeReadWriteImpl(const IR::Value& read_value, const IR::Inst*
|
|||||||
} else if constexpr (kind == HostLoc::Kind::Flags) {
|
} else if constexpr (kind == HostLoc::Kind::Flags) {
|
||||||
ASSERT(false && "Incorrect function for ReadWrite of flags");
|
ASSERT(false && "Incorrect function for ReadWrite of flags");
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
static_assert(Common::always_false_v<mcl::mp::lift_value<kind>>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include "dynarmic/common/assert.h"
|
#include "dynarmic/common/assert.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
#include "dynarmic/mcl/is_instance_of_template.hpp"
|
#include <mcl/type_traits/is_instance_of_template.hpp>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
#include <ankerl/unordered_dense.h>
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
#include <mcl/macro/architecture.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
|
|
||||||
#if defined(ARCHITECTURE_x86_64)
|
#if defined(ARCHITECTURE_x86_64)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -16,10 +16,11 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <bit>
|
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "dynarmic/common/assert.h"
|
||||||
|
#include <bit>
|
||||||
|
#include <mcl/macro/architecture.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/exception_handler.h"
|
#include "dynarmic/backend/exception_handler.h"
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <mcl/macro/architecture.hpp>
|
||||||
|
|
||||||
#if defined(ARCHITECTURE_x86_64)
|
#if defined(ARCHITECTURE_x86_64)
|
||||||
# include "dynarmic/backend/x64/mig/mach_exc_server.c"
|
# include "dynarmic/backend/x64/mig/mach_exc_server.c"
|
||||||
#elif defined(ARCHITECTURE_arm64)
|
#elif defined(ARCHITECTURE_arm64)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <mcl/macro/architecture.hpp>
|
||||||
|
|
||||||
#if defined(ARCHITECTURE_x86_64)
|
#if defined(ARCHITECTURE_x86_64)
|
||||||
# include "dynarmic/backend/x64/exception_handler_windows.cpp"
|
# include "dynarmic/backend/x64/exception_handler_windows.cpp"
|
||||||
#elif defined(ARCHITECTURE_arm64)
|
#elif defined(ARCHITECTURE_arm64)
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ void A32AddressSpace::SetCursorPtr(CodePtr ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t A32AddressSpace::GetRemainingSize() {
|
size_t A32AddressSpace::GetRemainingSize() {
|
||||||
return conf.code_cache_size - (GetCursorPtr<std::intptr_t>() - GetMemPtr<std::intptr_t>());
|
return conf.code_cache_size - (GetCursorPtr<sptr>() - GetMemPtr<sptr>());
|
||||||
}
|
}
|
||||||
|
|
||||||
EmittedBlockInfo A32AddressSpace::Emit(IR::Block block) {
|
EmittedBlockInfo A32AddressSpace::Emit(IR::Block block) {
|
||||||
|
|||||||
@@ -41,25 +41,25 @@ private:
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T GetMemPtr() {
|
T GetMemPtr() {
|
||||||
static_assert(std::is_pointer_v<T> || std::is_same_v<T, std::uintptr_t> || std::is_same_v<T, std::intptr_t>);
|
static_assert(std::is_pointer_v<T> || std::is_same_v<T, uptr> || std::is_same_v<T, sptr>);
|
||||||
return reinterpret_cast<T>(as.GetBufferPointer(0));
|
return reinterpret_cast<T>(as.GetBufferPointer(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T GetMemPtr() const {
|
T GetMemPtr() const {
|
||||||
static_assert(std::is_pointer_v<T> || std::is_same_v<T, std::uintptr_t> || std::is_same_v<T, std::intptr_t>);
|
static_assert(std::is_pointer_v<T> || std::is_same_v<T, uptr> || std::is_same_v<T, sptr>);
|
||||||
return reinterpret_cast<const T>(as.GetBufferPointer(0));
|
return reinterpret_cast<const T>(as.GetBufferPointer(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T GetCursorPtr() {
|
T GetCursorPtr() {
|
||||||
static_assert(std::is_pointer_v<T> || std::is_same_v<T, std::uintptr_t> || std::is_same_v<T, std::intptr_t>);
|
static_assert(std::is_pointer_v<T> || std::is_same_v<T, uptr> || std::is_same_v<T, sptr>);
|
||||||
return reinterpret_cast<T>(as.GetCursorPointer());
|
return reinterpret_cast<T>(as.GetCursorPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T GetCursorPtr() const {
|
T GetCursorPtr() const {
|
||||||
static_assert(std::is_pointer_v<T> || std::is_same_v<T, std::uintptr_t> || std::is_same_v<T, std::intptr_t>);
|
static_assert(std::is_pointer_v<T> || std::is_same_v<T, uptr> || std::is_same_v<T, sptr>);
|
||||||
return reinterpret_cast<const T>(as.GetCursorPointer());
|
return reinterpret_cast<const T>(as.GetCursorPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "dynarmic/common/assert.h"
|
||||||
|
#include <mcl/scope_exit.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/riscv64/a32_address_space.h"
|
#include "dynarmic/backend/riscv64/a32_address_space.h"
|
||||||
@@ -33,18 +34,28 @@ struct Jit::Impl final {
|
|||||||
HaltReason Run() {
|
HaltReason Run() {
|
||||||
ASSERT(!jit_interface->is_executing);
|
ASSERT(!jit_interface->is_executing);
|
||||||
jit_interface->is_executing = true;
|
jit_interface->is_executing = true;
|
||||||
|
SCOPE_EXIT {
|
||||||
|
jit_interface->is_executing = false;
|
||||||
|
};
|
||||||
|
|
||||||
HaltReason hr = core.Run(current_address_space, current_state, &halt_reason);
|
HaltReason hr = core.Run(current_address_space, current_state, &halt_reason);
|
||||||
|
|
||||||
RequestCacheInvalidation();
|
RequestCacheInvalidation();
|
||||||
jit_interface->is_executing = false;
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HaltReason Step() {
|
HaltReason Step() {
|
||||||
ASSERT(!jit_interface->is_executing);
|
ASSERT(!jit_interface->is_executing);
|
||||||
jit_interface->is_executing = true;
|
jit_interface->is_executing = true;
|
||||||
|
SCOPE_EXIT {
|
||||||
|
jit_interface->is_executing = false;
|
||||||
|
};
|
||||||
|
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
|
||||||
RequestCacheInvalidation();
|
RequestCacheInvalidation();
|
||||||
jit_interface->is_executing = false;
|
|
||||||
return HaltReason{};
|
return HaltReason{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "dynarmic/backend/riscv64/a32_jitstate.h"
|
#include "dynarmic/backend/riscv64/a32_jitstate.h"
|
||||||
|
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include <mcl/bit/bit_field.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "dynarmic/common/common_types.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::RV64 {
|
namespace Dynarmic::Backend::RV64 {
|
||||||
|
|||||||