Compare commits
36 Commits
v0.0.4.tes
...
discfix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed577ebf12 | ||
|
|
d498db1106 | ||
|
|
e93159b047 | ||
|
|
d989166044 | ||
|
|
c96defb80d | ||
|
|
06275885f1 | ||
|
|
206e7af162 | ||
|
|
cdf4ce07bc | ||
|
|
2f591d33d3 | ||
|
|
e4b0c03a22 | ||
|
|
9582dfffee | ||
|
|
cf9f78636a | ||
|
|
ae46778cc3 | ||
|
|
c31761ab75 | ||
|
|
b50f8c620b | ||
|
|
fa718acfbe | ||
|
|
ce0a299bdb | ||
|
|
d3dbabcfc7 | ||
|
|
effe8109a7 | ||
|
|
2924297790 | ||
|
|
5c6aaa7eb1 | ||
|
|
83c162d80d | ||
|
|
1a2d1821b5 | ||
|
|
a9b87077f8 | ||
|
|
2e092d5f5d | ||
|
|
a5996c7511 | ||
|
|
1c57172524 | ||
|
|
d34b44ce39 | ||
|
|
ecf7af0cde | ||
|
|
6b01c13975 | ||
|
|
15becaa5a3 | ||
|
|
3d4bb08cfc | ||
|
|
b2ac18173f | ||
|
|
39f226a853 | ||
|
|
61ab1be0e7 | ||
|
|
3ba9769d7a |
@@ -4,7 +4,7 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# specify full path if dupes may exist
|
||||
EXCLUDE_FILES="CPM.cmake CPMUtil.cmake GetSCMRev.cmake sse2neon.h renderdoc_app.h tools/cpm tools/shellcheck.sh tools/update-cpm.sh externals/stb externals/glad externals/getopt externals/gamemode externals/FidelityFX-FSR externals/demangle externals/bc_decoder"
|
||||
EXCLUDE_FILES="CPM.cmake CPMUtil.cmake GetSCMRev.cmake renderdoc_app.h tools/cpm tools/shellcheck.sh tools/update-cpm.sh externals/stb externals/glad externals/getopt externals/gamemode externals/FidelityFX-FSR externals/demangle externals/bc_decoder"
|
||||
|
||||
# license header constants, please change when needed :))))
|
||||
YEAR=2025
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,6 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: yuzu Discord
|
||||
url: https://discord.com/invite/u77vRWY
|
||||
about: If you are experiencing an issue with yuzu, and you need tech support, or if you have a general question, try asking in the official yuzu Discord linked here. Piracy is not allowed.
|
||||
- name: Community forums
|
||||
url: https://community.citra-emu.org
|
||||
about: This is an alternative place for tech support, however helpers there are not as active.
|
||||
- name: Eden Discord
|
||||
url: https://discord.gg/kXAmGCXBGD
|
||||
- name: Eden Revolt
|
||||
url: https://rvlt.gg/qKgFEAbH
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
From d765ebed3598ddfd7167fc546474626ac5ef9498 Mon Sep 17 00:00:00 2001
|
||||
From: Anthony Roberts <anthony.roberts@linaro.org>
|
||||
Date: Fri, 2 Aug 2024 16:55:57 +0100
|
||||
Subject: [PATCH] Add support for clang-cl on Windows (#633)
|
||||
|
||||
This commit adds support for clang-cl (clang, pretending to be MSVC) to
|
||||
SSE2NEON on Windows ARM64 platforms. This change is part of some Blender
|
||||
work, as using clang-cl provides a ~20-40% speedup compared to MSVC.
|
||||
|
||||
Compiled with the following command line (via a VS2022 Native ARM64 Tools
|
||||
CMD window):
|
||||
msbuild sse2neon.vcxproj /p:Configuration=Release /p:CLToolExe=clang-cl.exe
|
||||
/p:CLToolPath="C:\Program Files\LLVM\bin\"
|
||||
|
||||
Known failures in test suite:
|
||||
Test mm_cvttpd_epi32
|
||||
Test rdtsc
|
||||
|
||||
Co-authored-by: Anthony Roberts <anthony.roberts@linaro.org>
|
||||
---
|
||||
sse2neon.h | 22 +++++++++++-----------
|
||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/sse2neon.h b/sse2neon.h
|
||||
index 56254b5..76cf8e3 100644
|
||||
--- a/sse2neon.h
|
||||
+++ b/sse2neon.h
|
||||
@@ -180,7 +180,7 @@
|
||||
}
|
||||
|
||||
/* Compiler barrier */
|
||||
-#if defined(_MSC_VER)
|
||||
+#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define SSE2NEON_BARRIER() _ReadWriteBarrier()
|
||||
#else
|
||||
#define SSE2NEON_BARRIER() \
|
||||
@@ -856,7 +856,7 @@ FORCE_INLINE uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b)
|
||||
{
|
||||
poly64_t a = vget_lane_p64(vreinterpret_p64_u64(_a), 0);
|
||||
poly64_t b = vget_lane_p64(vreinterpret_p64_u64(_b), 0);
|
||||
-#if defined(_MSC_VER)
|
||||
+#if defined(_MSC_VER) && !defined(__clang__)
|
||||
__n64 a1 = {a}, b1 = {b};
|
||||
return vreinterpretq_u64_p128(vmull_p64(a1, b1));
|
||||
#else
|
||||
@@ -1767,7 +1767,7 @@ FORCE_INLINE void _mm_free(void *addr)
|
||||
FORCE_INLINE uint64_t _sse2neon_get_fpcr(void)
|
||||
{
|
||||
uint64_t value;
|
||||
-#if defined(_MSC_VER)
|
||||
+#if defined(_MSC_VER) && !defined(__clang__)
|
||||
value = _ReadStatusReg(ARM64_FPCR);
|
||||
#else
|
||||
__asm__ __volatile__("mrs %0, FPCR" : "=r"(value)); /* read */
|
||||
@@ -1777,7 +1777,7 @@ FORCE_INLINE uint64_t _sse2neon_get_fpcr(void)
|
||||
|
||||
FORCE_INLINE void _sse2neon_set_fpcr(uint64_t value)
|
||||
{
|
||||
-#if defined(_MSC_VER)
|
||||
+#if defined(_MSC_VER) && !defined(__clang__)
|
||||
_WriteStatusReg(ARM64_FPCR, value);
|
||||
#else
|
||||
__asm__ __volatile__("msr FPCR, %0" ::"r"(value)); /* write */
|
||||
@@ -2246,7 +2246,7 @@ FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b)
|
||||
FORCE_INLINE void _mm_prefetch(char const *p, int i)
|
||||
{
|
||||
(void) i;
|
||||
-#if defined(_MSC_VER)
|
||||
+#if defined(_MSC_VER) && !defined(__clang__)
|
||||
switch (i) {
|
||||
case _MM_HINT_NTA:
|
||||
__prefetch2(p, 1);
|
||||
@@ -4817,7 +4817,7 @@ FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b)
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_pause
|
||||
FORCE_INLINE void _mm_pause(void)
|
||||
{
|
||||
-#if defined(_MSC_VER)
|
||||
+#if defined(_MSC_VER) && !defined(__clang__)
|
||||
__isb(_ARM64_BARRIER_SY);
|
||||
#else
|
||||
__asm__ __volatile__("isb\n");
|
||||
@@ -5713,7 +5713,7 @@ FORCE_INLINE __m128d _mm_undefined_pd(void)
|
||||
#pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
__m128d a;
|
||||
-#if defined(_MSC_VER)
|
||||
+#if defined(_MSC_VER) && !defined(__clang__)
|
||||
a = _mm_setzero_pd();
|
||||
#endif
|
||||
return a;
|
||||
@@ -8127,7 +8127,7 @@ FORCE_INLINE int _sse2neon_sido_negative(int res, int lb, int imm8, int bound)
|
||||
|
||||
FORCE_INLINE int _sse2neon_clz(unsigned int x)
|
||||
{
|
||||
-#ifdef _MSC_VER
|
||||
+#if defined(_MSC_VER) && !defined(__clang__)
|
||||
unsigned long cnt = 0;
|
||||
if (_BitScanReverse(&cnt, x))
|
||||
return 31 - cnt;
|
||||
@@ -8139,7 +8139,7 @@ FORCE_INLINE int _sse2neon_clz(unsigned int x)
|
||||
|
||||
FORCE_INLINE int _sse2neon_ctz(unsigned int x)
|
||||
{
|
||||
-#ifdef _MSC_VER
|
||||
+#if defined(_MSC_VER) && !defined(__clang__)
|
||||
unsigned long cnt = 0;
|
||||
if (_BitScanForward(&cnt, x))
|
||||
return cnt;
|
||||
@@ -9055,7 +9055,7 @@ FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i a, const int rcon)
|
||||
// AESE does ShiftRows and SubBytes on A
|
||||
uint8x16_t u8 = vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0));
|
||||
|
||||
-#ifndef _MSC_VER
|
||||
+#if !defined(_MSC_VER) || defined(__clang__)
|
||||
uint8x16_t dest = {
|
||||
// Undo ShiftRows step from AESE and extract X1 and X3
|
||||
u8[0x4], u8[0x1], u8[0xE], u8[0xB], // SubBytes(X1)
|
||||
@@ -9242,7 +9242,7 @@ FORCE_INLINE uint64_t _rdtsc(void)
|
||||
* bits wide and it is attributed with the flag 'cap_user_time_short'
|
||||
* is true.
|
||||
*/
|
||||
-#if defined(_MSC_VER)
|
||||
+#if defined(_MSC_VER) && !defined(__clang__)
|
||||
val = _ReadStatusReg(ARM64_SYSREG(3, 3, 14, 0, 2));
|
||||
#else
|
||||
__asm__ __volatile__("mrs %0, cntvct_el0" : "=r"(val));
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -231,7 +231,7 @@ if(USE_CCACHE)
|
||||
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_BINARY})
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_BINARY})
|
||||
else()
|
||||
message(WARNING "USE_CCACHE enabled, but no executable found at: ${CCACHE_PATH}")
|
||||
message(FATAL_ERROR "USE_CCACHE enabled, but no executable found at: ${CCACHE_PATH}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -344,10 +344,6 @@ if (NOT EXISTS ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json "")
|
||||
endif()
|
||||
|
||||
if (UNIX)
|
||||
add_compile_definitions(YUZU_UNIX=1)
|
||||
endif()
|
||||
|
||||
if (YUZU_LEGACY)
|
||||
message(WARNING "Making legacy build. Performance may suffer.")
|
||||
add_compile_definitions(YUZU_LEGACY)
|
||||
@@ -377,6 +373,8 @@ endif()
|
||||
# Build/optimization presets
|
||||
if (PLATFORM_LINUX OR CXX_CLANG)
|
||||
if (ARCHITECTURE_x86_64)
|
||||
# See https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
|
||||
# Generic supports Pentium Pro instruction set and above
|
||||
set(YUZU_BUILD_PRESET "custom" CACHE STRING "Build preset to use. One of: custom, generic, v3, zen2, zen4, native")
|
||||
if (${YUZU_BUILD_PRESET} STREQUAL "generic")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=x86-64 -mtune=generic")
|
||||
@@ -395,13 +393,17 @@ if (PLATFORM_LINUX OR CXX_CLANG)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mtune=native")
|
||||
endif()
|
||||
elseif(ARCHITECTURE_arm64)
|
||||
set(YUZU_BUILD_PRESET "custom" CACHE STRING "Build preset to use. One of: custom, generic, armv9")
|
||||
# See https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html
|
||||
set(YUZU_BUILD_PRESET "custom" CACHE STRING "Build preset to use. One of: custom, generic, armv9, native")
|
||||
if (${YUZU_BUILD_PRESET} STREQUAL "generic")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a -mtune=generic")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a -mtune=generic")
|
||||
elseif (${YUZU_BUILD_PRESET} STREQUAL "armv9")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv9-a -mtune=generic")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv9-a -mtune=generic")
|
||||
elseif (${YUZU_BUILD_PRESET} STREQUAL "native")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mtune=native")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mtune=native")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -611,9 +613,6 @@ find_package(VulkanUtilityLibraries)
|
||||
find_package(SimpleIni)
|
||||
find_package(SPIRV-Tools)
|
||||
find_package(sirit)
|
||||
if (ARCHITECTURE_arm64)
|
||||
find_package(sse2neon)
|
||||
endif()
|
||||
|
||||
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
|
||||
find_package(xbyak)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
-->
|
||||
# Contributing
|
||||
|
||||
**The Contributor's Guide has moved to [the yuzu wiki](https://github.com/yuzu-emu/yuzu/wiki/Contributing).**
|
||||
Want to contribute to Eden? That's awesome!
|
||||
|
||||
- [Get started by building the emulator](./docs/Build.md)
|
||||
- [Make an account on the git](./docs/SIGNUP.md)
|
||||
- [Read the documentation](./docs/README.md)
|
||||
|
||||
@@ -82,7 +82,7 @@ Any donations received will go towards things such as:
|
||||
* Additional hardware (e.g. GPUs as needed to improve rendering support, other peripherals to add support for, etc.)
|
||||
* CI Infrastructure
|
||||
|
||||
If you would prefer to support us in a different way, please join our [Discord](https://discord.gg/edenemu) and talk to Camille or any of our other developers.
|
||||
If you would prefer to support us in a different way, please join our [Discord](https://discord.gg/kXAmGCXBGD) and talk to Camille or any of our other developers.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
107
dist/dev.eden_emu.eden.svg
vendored
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 13 KiB |
BIN
dist/eden.ico
vendored
|
Before Width: | Height: | Size: 316 KiB After Width: | Height: | Size: 403 KiB |
BIN
dist/eden_named.ico
vendored
|
Before Width: | Height: | Size: 54 KiB |
117
dist/eden_named.svg
vendored
|
Before Width: | Height: | Size: 4.9 MiB After Width: | Height: | Size: 39 KiB |
1
dist/icon_variations/base.svg
vendored
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
81
dist/icon_variations/base_named.svg
vendored
Normal file
|
After Width: | Height: | Size: 37 KiB |
106
dist/icon_variations/halloween2025.svg
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?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="dev.eden_emu.eden.svg"
|
||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs7" />
|
||||
<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.25"
|
||||
inkscape:cx="186.8"
|
||||
inkscape:cy="210.4"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="849"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg7" />
|
||||
<path
|
||||
fill="#bf42f6"
|
||||
d="M346.71 255.306c.788.006 1.577.013 3.124.059 4.006.027 7.253.015 10.501.003 33.391.022 66.783.028 100.175.078 8.174.013 16.349.279 24.522.209 3.084-.026 4.596.75 4.356 4.156-.293 4.157-.31 8.343-.259 12.513.049 3.964-1.248 5.539-5.679 5.524-48.85-.158-97.701-.071-146.552-.056-22.107.007-44.214 0-66.321 0h-5.43v7.117h223.011c-1.553 8.254-2.894 15.76-4.475 23.215-.17.802-1.666 1.617-2.685 1.87-1.312.327-2.763.099-4.155.099H265.099v6.701h216.666c-1.609 5.425-2.887 10.074-4.367 14.658-2.758 8.54-2.807 8.524-11.564 8.524-64.929 0-129.859.014-194.788-.04-3.401-.003-6.19.251-4.758 4.652.349 1.075 1.875 2.026 3.071 2.491 1.075.418 2.439.092 3.676.092l191.542.001h7.17c-3.533 7.29-6.399 13.72-9.834 19.83-.651 1.157-3.562 1.448-5.432 1.454-27.981.088-55.963.061-83.944.061-31.692 0-63.384.005-95.075-.008-2.61-.002-5.219-.124-8.53-.021-3.11.173-5.518.177-7.926.181-.849-7.032-2.289-14.051-2.44-21.098-.547-25.616-.773-51.242-.844-76.864-.014-4.88 1.228-9.763 2.52-14.927 2.88-.296 5.132-.31 7.81-.259 22.492.021 44.557-.024 67.034-.066 4.149-.049 7.886-.099 11.624-.149"
|
||||
id="path1"
|
||||
style="fill:#fea265;fill-opacity:1" />
|
||||
<path
|
||||
fill="#ff44c4"
|
||||
d="M168.124 257.114v-9.301c-2.407 0-4.67-.001-6.933.001-44.522.025-89.044.01-133.566.146-3.858.012-5.358-1.03-4.744-5 .683-4.418 1.254-8.885 1.393-13.346.106-3.386 1.603-4.005 4.608-4.012 45.9-.11 91.801-.344 137.702-.452 3.865-.009 6.842-.344 6.032-5.831H25.546c1.39-6.599 2.354-12.681 4.138-18.513.413-1.35 3.628-2.615 5.555-2.618 47.458-.084 94.917-.01 142.375.109 3.275.008 5.855-.38 6.138-5.045H31.147c3.43-9.311 6.348-17.71 9.74-25.913.483-1.166 3.265-1.942 4.987-1.95 24.582-.124 49.165-.21 73.745.014 5.283.048 8.073-2.583 11.128-7.248h-86.45c4.35-7.835 8.002-14.753 12.077-21.412.67-1.096 3.197-1.473 4.868-1.478 30.611-.083 61.226-.291 91.832.113 7.185.094 12.719-2.619 18.321-6.774H61.385c2.592-3.805 4.355-6.546 6.268-9.178 8.88-12.216 8.896-12.209 24.069-12.21q60.991-.002 121.982-.001h5.885c-3.968-4.128-7.007-6.966-12.321-6.944-38.959.165-77.92.09-116.88.09H85.03l-.741-1.31c3.832-3.852 7.564-7.81 11.514-11.537 11.456-10.807 11.495-10.996 27.246-10.717 23.209.411 45.103 6.8 66.234 15.885 5.657 2.432 10.56 3.715 16.604.944 4.726-2.166 10.217-2.664 16.034-3.521-4.411 8.139.887 12.041 5.52 16.414 5.73 5.408 11.223 11.07 16.751 16.688 1.165 1.185 2.035 2.659 3.685 4.857-2.256.128-3.665.274-5.075.275-9.739.008-19.489.286-29.214-.085-28.045-1.07-51.592 9.244-71.602 28.209-7.152 6.778-13.525 14.379-20.212 21.643-.683.742-1.079 1.748-2.209 3.632 33.94-11.926 65.876-27.377 101.589-28.637l.859 1.395c-4.228 4.943-8.188 10.148-12.73 14.783-18.091 18.461-28.905 40.673-33.892 65.773-1.402 7.057-1.306 14.412-2.504 21.941-1.992.248-3.377.184-4.762.121m19.995-91.726c3.865.004 7.763-.315 11.585.09 5.562.589 8.92-2.178 12.525-7.52-9.134 2.152-17.144 4.039-25.139 5.988-.008.002.209.928 1.029 1.442"
|
||||
id="path2"
|
||||
style="fill:#ff7f2a;fill-opacity:1" />
|
||||
<path
|
||||
fill="#bf43f5"
|
||||
d="M167.719 257.136c1.79.041 3.175.105 4.979.185.569 3.091.719 6.166.87 9.24l1.623.577c2.3-3.392 4.599-6.785 7.467-10.458 2.456-.382 4.343-.483 6.573-.598 1.405-.133 2.466-.342 3.53-.356 12.08-.162 24.16-.295 36.693-.368 3.463.111 6.473.155 9.484.2-1.12 6.677-2.306 13.345-3.347 20.035-4.715 30.285-5.404 60.697-3.186 91.651-2.469.746-4.517 1.048-6.565 1.35-56.117-.025-112.236-.135-168.353.061-5.334.018-8.298-1.559-10.185-6.415-1.874-4.824-4.295-9.436-6.907-15.069h17.147c53.955 0 107.909.013 161.863-.044 2.026-.002 4.864 1.218 5.327-2.599.469-3.862-1.271-4.625-4.781-4.616-38.803.103-77.607.061-116.411.068-20.405.003-40.811-.065-61.215.125-3.545.033-5.36-1.044-6.324-4.419-1.642-5.75-3.577-11.416-5.879-18.659 65.363-.259 129.677-.027 194.424-.144l.372-6.533c-1.901-.099-3.398-.244-4.896-.245-58.283-.032-116.565-.056-174.848-.06-4.48 0-8.964.279-13.439.163-1.138-.029-3.078-.897-3.247-1.681-1.676-7.766-3.056-15.595-4.624-23.961 8.433 0 15.808-.031 23.182.02 1.998.014 3.995.4 5.992.401 55.964.023 111.928.02 167.892.017 6.075 0 6.307-.256 6.266-7.198H23.431c-.284-6.643-.72-12.739-.592-18.823.016-.786 2.94-2.144 4.53-2.165 15.149-.197 30.3-.177 45.45-.191 17.623-.016 35.248-.072 52.871.018 13.876.07 27.75.335 42.029.491"
|
||||
id="path3"
|
||||
style="fill:#fea265;fill-opacity:1" />
|
||||
<path
|
||||
fill="#985ded"
|
||||
d="M225.868 369.021c2.02-.729 4.068-1.031 6.551-1.351 2.672 17.851 4.169 35.853 7.334 53.556 4.047 22.64 9.785 44.94 18.63 66.298.29.699.498 1.433.742 2.142-25.39 10.452-124.622-22.609-146.929-49.453h122.669c.302-4.81-.85-6.915-5.85-6.891-39.883.193-79.768.055-119.652.182-4.441.014-8.036-.845-11.208-4.17-6.87-7.203-13.99-14.166-21.008-21.228l.69-1.319H229.63l-1.24-7.289h-5.726c-42.821 0-85.642.011-128.464-.013-6.18-.003-12.371-.428-18.537-.173-3.704.154-6.14-1.066-8.104-4.073-4.111-6.292-8.367-12.489-13.256-19.755h171.593c0-2.433 0-4.234-.027-6.463m35.103.062c2.442-.418 4.85-.422 7.641-.431.482 1.987.581 3.979.706 6.499H457.62c-3.126 4.951-5.544 8.946-8.123 12.835-7.64 11.521-7.665 11.508-21.226 11.509l-147.5.003h-5.407c-.602 6.688-.15 7.214 5.824 7.214q73.75.004 147.5.004h6.891c-4.048 4.533-7.454 7.812-10.233 11.556-9.047 12.19-20.575 16.124-35.967 15.542-33.039-1.25-66.159-.384-99.246-.384h-5.45c-.275 5.77.583 6.774 5.594 6.776 34.478.012 68.957.006 103.435.007h5.302l.443 1.274c-3.495 2.62-6.91 5.358-10.5 7.842-23.505 16.265-49.192 27.744-76.893 34.696-3.263.819-6.763 1.374-10.069 1.085-1.874-.164-4.144-1.915-5.266-3.597-9.503-14.258-15.474-30.133-21.055-46.227-7.418-21.394-11.59-43.465-14.702-66.203"
|
||||
id="path4"
|
||||
style="fill:#fe8463;fill-opacity:1" />
|
||||
<path
|
||||
fill="#ff43c4"
|
||||
d="M360.319 254.985c-3.232.395-6.479.407-10.189.359 2.612-14.328 2.295-28.523-1.162-42.703-4.74-19.439-15.808-34.254-32.502-45.039-.639-.413-1.27-.839-1.852-2.137h52.547l.213-1.506c-7.026-2.665-13.978-5.752-21.733-5.819-15.455-.136-30.914.047-46.369-.12-3.092-.034-6.173-1.044-9.202-2.411 18.374-7.385 37.172-6.583 56.061-3.6 19.128 3.021 35.771 12.957 54.614 20.622l-3.662-6.95c1.846-.148 3.252-.359 4.658-.36 21.485-.021 42.97.048 64.454-.082 3.262-.019 5.062.848 6.121 4.101 2.319 7.128 5.012 14.134 7.891 22.129h-127.22c.144 4.537 2.105 5.796 5.897 5.783q43.588-.154 87.175-.028c10.803.031 21.607.309 32.402.688 1.327.047 3.486 1.183 3.763 2.215 1.549 5.774 2.638 11.671 4.021 18.169H361.127c-.548 6.29-.254 6.61 5.207 6.619 38.949.061 77.898.158 116.847.146 2.863-.001 4.211.672 4.397 3.772.304 5.076.956 10.136 1.609 15.183.414 3.199-.637 4.443-4.005 4.328-6.635-.228-13.283-.105-19.926-.106q-49.152-.005-98.304.001c-6.266.001-6.266.007-6.633 6.746"
|
||||
id="path5"
|
||||
style="fill:#ff7f2a;fill-opacity:1" />
|
||||
<path
|
||||
fill="#ff42c3"
|
||||
d="M214.837 27.347c41.832-7.02 81.069-2.12 103 5.453-3.084 7.222-6.153 14.42-9.231 21.612-1.64 3.833-3.549 7.574-4.869 11.513-1.091 3.256-2.992 4.06-6.217 4.042-22.092-.119-44.185-.062-67.454-.062 3.94 4.046 6.873 7.296 12.308 7.245 16.689-.157 33.381-.056 50.072-.055h6.745c-3.661 6.1-6.056 11.84-9.975 16.217-6.139 6.856-13.44 12.659-19.972 19.184-2.516 2.514-3.687 2.416-6.101-.229-9.873-10.813-19.809-21.593-30.196-31.908-11.454-11.376-25.983-16.088-41.742-17.908-14.011-1.618-27.312.965-40.451 5.507a34.7 34.7 0 0 1-9.886 1.86c-7.248.275-14.513.085-21.995-.508 28.501-21.58 60.452-35.31 95.964-41.963m53.746 77.311 3.605-4.283h-11.056c1.525 2.155 2.339 3.846 3.653 4.931.643.531 2.216-.065 3.798-.648"
|
||||
id="path6"
|
||||
style="fill:#63915a;fill-opacity:1" />
|
||||
<path
|
||||
fill="#ff44c4"
|
||||
d="M377.152 144.943c-12.092-9.869-26.287-13.386-40.919-15.513-16.956-2.465-33.583-1.51-50.074 5.653.952-1.742 1.722-3.617 2.884-5.206 15.646-21.395 34.923-38.76 58.357-51.192 3.545-1.881 8.365-1.78 12.607-1.849 13.445-.22 26.898-.165 40.345-.002 2.017.024 4.514.652 5.947 1.938 7.01 6.292 13.741 12.894 20.545 19.414.386.37.542.98 1.172 2.175h-5.468c-30.918 0-61.837.116-92.753-.114-5.213-.039-8.095 2.606-11.98 6.969h6.295c35.092-.001 70.184.065 105.275-.091 4.005-.018 6.738 1.186 8.994 4.365 3.728 5.252 7.642 10.372 12.234 16.566h-90.207l-.153 1.134c6.582 2.444 12.387 6.339 20.175 6.183 23.179-.463 46.374-.087 69.561-.245 3.754-.026 6.054 1.177 7.725 4.48 2.979 5.887 6.211 11.646 9.711 18.154-2.304.15-3.753.325-5.203.326-22.415.017-44.831-.042-67.246.074-3.19.016-5.54-.802-7.705-3.211-3.093-3.441-6.561-6.545-10.119-10.008M267.626 255.455a972 972 0 0 1-7.18.028c2.056-26.604 4.319-53.217 12.215-78.952 1.17-3.813 2.458-5.484 6.241-2.773 3.757 2.69 8.105 4.741 11.346 7.934 22.076 21.743 42.878 44.52 56.347 73.308-3.623.356-7.36.406-11.542.092-1.222-4.579-3.365-6.359-8.021-6.284-17.697.286-35.402.122-53.104.126h-6.302zm2.176-30.951h44.834l.519-1.678c-1.826-.906-3.637-2.562-5.479-2.597-12.466-.234-24.937-.104-37.407-.144-2.831-.009-4.108.992-2.467 4.419m10.378-31.312c-3.285-.223-6.209-.007-5.651 4.577h16.788c-2.211-5.078-6.298-4.716-11.137-4.577m-41.043 62.082c-3.21.24-6.22.195-9.566-.301-.214-2.054-.093-3.657.08-5.95-11.47 0-22.329-.006-33.188.003-5.917.004-6.716.761-7.574 7.07-1.888.101-3.775.202-6.063.302 4.551-9.736 8.81-19.906 14.604-29.11 10.304-16.372 21.983-31.76 37.616-43.656 7.217-5.492 15.096-9.592 23.847-11.977 1.13-.308 2.333-.345 4.833-.691-10.43 27.968-18.906 55.583-24.589 84.31m-25.72-36.778c-4.442-.439-5.459 2.888-7.32 6.624 9.882 0 19.096-.135 28.302.061 4.188.089 5.338-1.767 4.777-6.598-8.393 0-16.684 0-25.759-.087m33.855-22.914c-1.112-.66-2.178-1.777-3.343-1.89-2.903-.28-5.86.032-8.779-.147-3.761-.229-5.839 1.749-7.932 5.507 6.203 0 11.685.126 17.15-.12.95-.043 1.829-1.662 2.904-3.35m96.491-154.518c17.922 7.326 34.473 16.35 49.706 28.527-30.671-2.027-59.888 3.402-88.579 15.8.855-4.673 2.395-7.566 6.408-8.806 5.86-1.811 11.674-3.77 17.472-6.488h-16.478c5.867-11.505 11.161-22.041 16.71-32.442.395-.74 2.807-.966 4.029-.597 3.534 1.07 6.939 2.564 10.732 4.006"
|
||||
id="path7"
|
||||
style="fill:#ff7f2a;fill-opacity:1" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="m 130,278.4 c 69.2,16 30.4,65.6 30.4,65.6 0,0 -14.8,-92.4 28.8,-46.4 43.6,46 -59.2,-19.2 -59.2,-19.2 z"
|
||||
id="path8" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="m 76.08469,213.54625 c 17.819091,7.91959 0.282842,24.32447 22.061731,7.91959 21.778889,-16.40487 53.174429,-48.3661 21.778889,-16.40487 -31.395541,31.96122 -43.84062,8.48528 -43.84062,8.48528 z"
|
||||
id="path9" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="m 310.4,292.8 c 36,20.8 16,50.4 40,18.8 24,-31.6 46.8,-57.2 14.8,-33.6 -32,23.6 -54.8,14.8 -54.8,14.8 z"
|
||||
id="path10" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="m 380.8,197.2 c 41.6,30.4 18.4,62.8 42,30.4 23.6,-32.4 10,-68.8 23.6,-32.4 13.6,36.4 58,64.4 13.6,36.4 -44.4,-28 -79.2,-34.4 -79.2,-34.4 z"
|
||||
id="path11" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="M 99.6,145.2 C 146,120.4 170.4,80.8 146,120.4 121.6,160 121.2,187.6 120.4,159.6 119.6,131.6 99.6,145.2 99.6,145.2 Z"
|
||||
id="path12" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="m 166.4,395.2 c 36.4,-34.4 26.8,-68.4 35.2,-32.8 8.4,35.6 -36,4.8 -36,4.8 z"
|
||||
id="path13" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="M 325.6,419.2 C 390,378.4 402,310 388.8,379.6 c -13.2,69.6 7.6,39.6 -15.6,67.6 -23.2,28 81.6,-113.2 50,-90.8 -31.6,22.4 -97.6,62.8 -97.6,62.8 z"
|
||||
id="path14" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="m 298.11622,232.77955 c 9.33381,30.82986 27.43574,16.68772 9.05097,29.41564 -18.38478,12.72793 -23.19311,44.12347 -17.53625,11.59656 5.65685,-32.52692 8.48528,-41.0122 8.48528,-41.0122 z"
|
||||
id="path15" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="M 54.305801,291.32799 C 110.5915,257.10403 141.42136,225.1428 108.89444,258.51824 76.367532,291.89368 96.166522,307.73287 78.913117,291.04515 61.659711,274.35743 54.022958,289.06525 54.022958,289.06525 l 53.174432,-31.1127 z"
|
||||
id="path16" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
110
dist/icon_variations/halloween2025_named.svg
vendored
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
dist/qt_themes/default/icons/256x256/eden.png
vendored
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 27 KiB |
BIN
dist/qt_themes/default/icons/256x256/eden_named.png
vendored
|
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 38 KiB |
BIN
dist/yuzu.bmp
vendored
|
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 256 KiB |
@@ -1,5 +1,23 @@
|
||||
# Debug Guidelines
|
||||
|
||||
## Issue reports
|
||||
|
||||
When reporting issues or finding bugs, we often need backtraces, debug logs, or both in order to track down the issue.
|
||||
|
||||
### Graphics Debugging
|
||||
|
||||
If your bug is related to a graphical issue--e.g. mismatched colors, vertex explosions, flickering, etc.--then you are required to include graphical debugging logs in your issue reports.
|
||||
|
||||
Graphics Debugging is found in General -> Debug on desktop, and Advanced Settings -> Debug on Android. Android users are all set; however, desktop users may need to install the Vulkan Validation Layers:
|
||||
- Windows: Install the [Vulkan SDK](https://vulkan.lunarg.com/sdk/home)
|
||||
- Linux, BSD, etc: Install `vulkan-validation-layers`, `vulkan-layers`, or similar from your package manager. It should be located in e.g. `/usr/lib64/libVkLayer_khronos_validation.so`
|
||||
|
||||
Once Graphics Debugging is enabled, run the problematic game again and continue. Note that the game may run extremely slow on weak hardware.
|
||||
|
||||
### Debug Logs
|
||||
|
||||
Debug logs can be found in General -> Debug -> Open Log Location on desktop, and Share Debug Logs on Android. This MUST be included in all bug reports, except for certain UI bugs--but we still highly recommend them even for UI bugs.
|
||||
|
||||
## Debugging (host code)
|
||||
|
||||
Ignoring SIGSEGV when debugging in host:
|
||||
@@ -47,10 +65,10 @@ Renderdoc is a free, cross platform, multi-graphics API debugger. It is an inval
|
||||
|
||||
Before using renderdoc to diagnose issues, it is always good to make sure there are no validation errors. Any errors means the behavior of the application is undefined. That said, renderdoc can help debug validation errors if you do have them.
|
||||
|
||||
When debugging a black screen, there are many ways the application could have setup Vulkan wrong.
|
||||
When debugging a black screen, there are many ways the application could have setup Vulkan wrong.
|
||||
Here is a short checklist of items to look at to make sure are appropriate:
|
||||
* Draw call counts are correct (aka not zero, or if rendering many triangles, not 3)
|
||||
* Vertex buffers are bound
|
||||
* Vertex buffers are bound
|
||||
* vertex attributes are correct - Make sure the size & offset of each attribute matches what should it should be
|
||||
* Any bound push constants and descriptors have the right data - including:
|
||||
* Matrices have correct values - double check the model, view, & projection matrices are uploaded correctly
|
||||
@@ -63,6 +81,6 @@ Here is a short checklist of items to look at to make sure are appropriate:
|
||||
* Blend state is correct
|
||||
* Depth state is correct - typically enabled with Function set to Less than or Equal
|
||||
* Swapchain images are bound when rendering to the swapchain
|
||||
* Image being rendered to is the same as the one being presented when rendering to the swapchain
|
||||
* Image being rendered to is the same as the one being presented when rendering to the swapchain
|
||||
|
||||
Alternatively, a [RenderDoc Extension](https://github.com/baldurk/renderdoc-contrib/tree/main/baldurk/whereismydraw) ([Archive](https://web.archive.org/web/20250000000000*/https://github.com/baldurk/renderdoc-contrib/tree/main/baldurk/whereismydraw)) exists which automates doing a lot of these manual steps.
|
||||
|
||||
13
docs/Deps.md
@@ -72,9 +72,6 @@ Certain other dependencies will be fetched by CPM regardless. System packages *c
|
||||
|
||||
On amd64:
|
||||
* [xbyak](https://github.com/herumi/xbyak) - 7.22 or earlier is recommended
|
||||
* [zycore](https://github.com/zyantific/zycore-c)
|
||||
* [zydis](https://github.com/zyantific/zydis) 4+
|
||||
* Note: zydis and zycore-c MUST match. Using one as a system dependency and the other as a bundled dependency WILL break things
|
||||
|
||||
On aarch64 OR if `DYNARMIC_TESTS` is on:
|
||||
* [oaknut](https://github.com/merryhime/oaknut) 2.0.1+
|
||||
@@ -94,7 +91,7 @@ Click on the arrows to expand.
|
||||
<summary>Arch Linux</summary>
|
||||
|
||||
```sh
|
||||
sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip zydis zycore vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers
|
||||
sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers
|
||||
```
|
||||
|
||||
* Building with QT Web Engine requires `qt6-webengine` as well.
|
||||
@@ -106,7 +103,7 @@ sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glsl
|
||||
<summary>Ubuntu, Debian, Mint Linux</summary>
|
||||
|
||||
```sh
|
||||
sudo apt-get install autoconf cmake g++ gcc git glslang-tools libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev libvulkan-dev spirv-tools spirv-headers libusb-1.0-0-dev libxbyak-dev libboost-dev libboost-fiber-dev libboost-context-dev libsdl2-dev libopus-dev libasound2t64 vulkan-utility-libraries-dev
|
||||
sudo apt-get install autoconf cmake g++ gcc git glslang-tools libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libvulkan-dev spirv-tools spirv-headers libusb-1.0-0-dev libxbyak-dev libboost-dev libboost-fiber-dev libboost-context-dev libsdl2-dev libopus-dev libasound2t64 vulkan-utility-libraries-dev
|
||||
```
|
||||
|
||||
* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required.
|
||||
@@ -189,7 +186,7 @@ brew install molten-vk vulkan-loader
|
||||
<details>
|
||||
<summary>FreeBSD</summary>
|
||||
|
||||
As root run: `pkg install devel/cmake devel/sdl20 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib devel/jwt-cpp devel/unordered-dense devel/zydis`
|
||||
As root run: `pkg install devel/cmake devel/sdl20 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib devel/jwt-cpp devel/unordered-dense`
|
||||
|
||||
If using FreeBSD 12 or prior, use `devel/pkg-config` instead.
|
||||
|
||||
@@ -237,7 +234,7 @@ Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/l
|
||||
* Download and install all dependencies:
|
||||
```
|
||||
BASE="git make autoconf libtool automake-wrapper jq patch"
|
||||
MINGW="SDL2 cmake python-pip qt6-base toolchain ffmpeg boost catch fmt lz4 nlohmann-json openssl zlib zstd enet opus mbedtls vulkan-devel libusb vulkan-memory-allocator unordered_dense zydis clang ccache"
|
||||
MINGW="SDL2 cmake python-pip qt6-base toolchain ffmpeg boost catch fmt lz4 nlohmann-json openssl zlib zstd enet opus mbedtls vulkan-devel libusb vulkan-memory-allocator unordered_dense clang ccache"
|
||||
|
||||
packages="$BASE"
|
||||
for pkg in $MINGW; do
|
||||
@@ -260,7 +257,7 @@ pacman -Syu --needed --noconfirm $packages
|
||||
<summary>HaikuOS</summary>
|
||||
|
||||
```sh
|
||||
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.89_devel vulkan_devel qt6_base_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt6_devel qt6_5compat_devel zydis_devel libusb1_devel libz_devel glslang mbedtls3
|
||||
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.89_devel vulkan_devel qt6_base_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt6_devel qt6_5compat_devel libusb1_devel libz_devel glslang mbedtls3
|
||||
```
|
||||
|
||||
[Caveats](./Caveats.md#haikuos).
|
||||
|
||||
@@ -10,4 +10,4 @@ This contains documentation created by developers. This contains build instructi
|
||||
- **[Debug Guidelines](./Debug.md)**
|
||||
- **[CPM - CMake Package Manager](CPMUtil.md)**
|
||||
- **[Platform-Specific Caveats](Caveats.md)**
|
||||
- **[User Handbook](User.md)**
|
||||
- **[User Handbook](./user)**
|
||||
|
||||
12
docs/User.md
@@ -1,12 +0,0 @@
|
||||
# User Handbook
|
||||
|
||||
The "FAQ".
|
||||
|
||||
This handbook is primarily aimed at the end-user - baking useful knowledge for enhancing their emulation experience.
|
||||
|
||||
- **[The Basics](user/Basics.md)**
|
||||
- **[Audio](user/Audio.md)**
|
||||
- **[Graphics](user/Graphics.md)**
|
||||
- **[Platforms and Architectures](user/Architectures.md)**
|
||||
- **[Testing](user/Testing.md)**
|
||||
- **[Data, savefiles and storage](user/Storage.md)**
|
||||
@@ -47,6 +47,26 @@ Various graphical filters exist - each of them aimed at a specific target/image
|
||||
|
||||
While stock shaders offer a basic subset of options for most users, programs such as [ReShade](https://github.com/crosire/reshade) offer a more flexible experience. In addition to that users can also seek out modifications (mods) for enhancing visual experience (60 FPS mods, HDR, etc).
|
||||
|
||||
**Installing ReShade (Windows)**
|
||||
1. [Download ReShade](https://reshade.me/#download) with add-on support.
|
||||
- [ReShade Setup 6.6.2 (Windows 64-bit) with add-on support](https://reshade.me/downloads/ReShade_Setup_6.6.2_Addon.exe)
|
||||
- SHA512 checksum: `1f09a73afa160480c13ffdd73cc04b1dc82943dddea58ad3bb9375f26b48c2787d0a85197e46b6fce32a4fd3472465520a3355ed3436241e17fba7ebaff7ffec`.
|
||||
2. Open ReShade and hit browse, then the folder where `eden.exe` is at, hit open, then hit next.
|
||||
3. Select Vulkan as the rendering API, hit next.
|
||||
4. In "Select effects to install" screen: hit next don't change anything.
|
||||
5. In "Select add on" screen: click the box for `Shader Toggler by Otis` ([GitHub](https://github.com/FransBouma/ShaderToggler)) and hit next.
|
||||
|
||||
**Using the Shader Toggler**
|
||||
1. Launch a game, you must see a ReShade pop up afterwards.
|
||||
2. Progress to a point with a flickering shader.
|
||||
3. Hit the Home key on keyboard (or change binds if you don't have one).
|
||||
4. Navigate to the add on tab at the top of the ReShade menu.
|
||||
5. At the bottom where Shader Toggler is at open the drop down and max out the slider that says "# of fames collected" then select change shaders while staring at the flickering shader.
|
||||
6. When the Shader Toggler finishes collecting frames in the top left hit Numpad 2 till it turns off the flickering lines.
|
||||
7. Hit Numpad 3 to add it the group of shaders to turn off and hit done and save all toggle groups.
|
||||
8. Hit the edit button and select "active at startup" for the shader to be turned off on every game launch.
|
||||
9. Caps lock to manually turn on and off the shader (default key you can change it with the previous edit button)
|
||||
|
||||
## Driver specifics
|
||||
|
||||
### Mesa environment variable hacks
|
||||
|
||||
31
docs/user/Orphaned.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Orphaned Profiles
|
||||
|
||||
A bug present in earlier versions of Eden and Yuzu caused some profiles to be read from the incorrect location if your NAND directory was set to anything other than the default. This bug was fixed in Eden v0.0.4-rc1, but it can be destructive if you're not careful.
|
||||
|
||||
## What are they?
|
||||
|
||||
Orphaned profiles refer to emulated user profiles that may or may not contain valid save data, but are not referenced by the internal profile map. This means the save data is effectively inaccessible, and should be fixed in order to access your save data.
|
||||
|
||||
## How do I fix it?
|
||||
|
||||
There are lots of different cases of varying complexity.
|
||||
|
||||
Remember to ALWAYS back up your saves!
|
||||
|
||||
### Simple Copy
|
||||
|
||||
Sometimes, a simple copying is all you need. For example, if the orphaned profile folder contains game saves, BUT the good profile is completely empty, then you can simply remove the empty folder and rename the orphaned profile to the same name as the good one.
|
||||
|
||||
### Combination
|
||||
|
||||
In more extreme cases, game saves can be strewn all throughout different profiles. In this case, you must look at each profile individually.
|
||||
|
||||
Typically, one folder will clearly have more recent/numerous save data, in which case you can remove all the other profile folders and follow the same procedure as the simple copy.
|
||||
|
||||
If multiple profile folders contain valid data, the recommended approach is to copy the contents of one folder into the other. There are likely to be file conflicts, the resolution of which is up to you.
|
||||
|
||||
An alternate method for dealing with multiple valid profiles is to go into System -> Profiles, and create a new profile. From there, you can copy the contents of each previously-orphaned profile into a new profile.
|
||||
|
||||
### Edge Cases
|
||||
|
||||
There are way too many edge cases to cover here, but in general, make backups! You can never go wrong if you always have a backup of your saves.
|
||||
13
docs/user/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# User Handbook
|
||||
|
||||
The "FAQ".
|
||||
|
||||
This handbook is primarily aimed at the end-user - baking useful knowledge for enhancing their emulation experience.
|
||||
|
||||
- **[The Basics](Basics.md)**
|
||||
- **[Audio](Audio.md)**
|
||||
- **[Graphics](Graphics.md)**
|
||||
- **[Platforms and Architectures](Architectures.md)**
|
||||
- **[Testing](Testing.md)**
|
||||
- **[Data, savefiles and storage](Storage.md)**
|
||||
- **[Orphaned Profiles](Orphaned.md)**
|
||||
@@ -27,6 +27,8 @@ When you report your results:
|
||||
2. "Tested on based master — issue already present. Good result for PR, not a regression."
|
||||
```
|
||||
|
||||
This approach helps maintain clarity and accountability in the testing process and ensures regressions are caught and addressed efficiently. If the behavior seems normal for a certain game/feature then it may not be always required to check against the based master.
|
||||
This approach helps maintain clarity and accountability in the testing process and ensures regressions are caught and addressed efficiently. If the behavior seems normal for a certain game/feature then it may not be always required to check against the based master.
|
||||
|
||||
If a master build for the PR' based master does not exist. It will be helpful to just test past and future builds nearby. That would help with gathering more information about the problem.
|
||||
|
||||
**Always include [debugging info](../Debug.md) as needed**.
|
||||
9
externals/CMakeLists.txt
vendored
@@ -219,7 +219,7 @@ if (ENABLE_WEB_SERVICE OR ENABLE_UPDATE_CHECKER)
|
||||
endif()
|
||||
|
||||
# cpp-jwt
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
if (ENABLE_WEB_SERVICE OR ENABLE_UPDATE_CHECKER)
|
||||
AddJsonPackage(cpp-jwt)
|
||||
endif()
|
||||
|
||||
@@ -399,10 +399,3 @@ if (ANDROID)
|
||||
|
||||
add_library(oboe::oboe ALIAS oboe)
|
||||
endif()
|
||||
|
||||
# sse2neon
|
||||
if (ARCHITECTURE_arm64 AND NOT TARGET sse2neon)
|
||||
AddJsonPackage(sse2neon)
|
||||
add_library(sse2neon INTERFACE)
|
||||
target_include_directories(sse2neon INTERFACE ${sse2neon_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
9
externals/cpmfile.json
vendored
@@ -213,14 +213,5 @@
|
||||
"key": "steamdeck",
|
||||
"bundled": true,
|
||||
"skip_updates": "true"
|
||||
},
|
||||
"sse2neon": {
|
||||
"repo": "DLTcollab/sse2neon",
|
||||
"sha": "66267b52fd",
|
||||
"hash": "3aed8676e1b8c428acb076464663e3968a721457b08710a7c5f8df2fbdaa5601053c1606169a55e987e7a58dd17e3cc3b7fbf953aa891c5ac5f8ce2941862e4b",
|
||||
"download_only": "true",
|
||||
"patches": [
|
||||
"0001-Add-support-for-clang-cl-on-Windows-633.patch"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ pkgs.mkShellNoCC {
|
||||
openssl boost fmt nlohmann_json lz4 zlib zstd
|
||||
enet libopus vulkan-headers vulkan-utility-libraries
|
||||
spirv-tools spirv-headers simpleini vulkan-memory-allocator
|
||||
vulkan-loader unzip mbedtls zydis glslang python3 httplib
|
||||
vulkan-loader unzip mbedtls glslang python3 httplib
|
||||
cpp-jwt ffmpeg-headless libusb1 cubeb
|
||||
qt6.full # eden
|
||||
SDL2 # eden-cli
|
||||
|
||||
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 74 KiB |
@@ -374,9 +374,6 @@
|
||||
<string name="firmware_uninstalling">إلغاء تثبيت الفريموير</string>
|
||||
<string name="firmware_uninstalled_success">تم إزالة الفريموير بنجاح</string>
|
||||
|
||||
<string name="error_firmware_missing">الفريموير مطلوب لتشغيل بعض الألعاب واستخدام التطبيقات. يعمل عدن فقط مع الفريموير 19.0.1 أو الأقدم.</string>
|
||||
<string name="error_firmware_corrupted">الفريموير موجود ولكن لا يمكن قراءته. تحقق من مفاتيح التشفير وأعد نسخ الفريموير إذا لزم الأمر.</string>
|
||||
<string name="error_firmware_too_new">الفريموير جديد جداً أو لا يمكن قراءته. يعمل عدن فقط مع الفريموير 19.0.1 أو الأقدم.</string>
|
||||
|
||||
<string name="keys_failed">فشل تثبيت المفاتيح</string>
|
||||
<string name="keys_install_success">تم تثبيت المفاتيح بنجاح</string>
|
||||
|
||||
@@ -322,9 +322,6 @@
|
||||
<string name="firmware_uninstalling">جاري إزالة البرنامج الثابت</string>
|
||||
<string name="firmware_uninstalled_success">تم إزالة البرنامج الثابت بنجاح</string>
|
||||
|
||||
<string name="error_firmware_missing">فریموێر پێویستە بۆ کارپێکردنی هەندێک یاری و بەکارهێنانی بەرنامەکان. ئێدین تەنها لەگەڵ فریموێری 19.0.1 یان کۆنتر کار دەکات.</string>
|
||||
<string name="error_firmware_corrupted">فریموێر هەیە بەڵام ناتوانرێت بخوێنرێتەوە. پشکنین بکە بۆ کلیلی شیکردنەوە و دووبارە فریموێرەکە دامپ بکە ئەگەر پێویست بوو.</string>
|
||||
<string name="error_firmware_too_new">فریموێر زۆر نوێ یان ناتوانرێت بخوێنرێتەوە. ئێدین تەنها لەگەڵ فریموێری 19.0.1 یان کۆنتر کار دەکات.</string>
|
||||
|
||||
<string name="keys_failed">سەرکەوتوو نەبوو لە ناساندنی کلیلی</string>
|
||||
<string name="keys_install_success">کلیلەکان بە سەرکەوتوویی ناسێندران</string>
|
||||
|
||||
@@ -301,9 +301,6 @@
|
||||
<string name="firmware_uninstalling">Odstraňování firmwaru</string>
|
||||
<string name="firmware_uninstalled_success">Firmware byl úspěšně odinstalován</string>
|
||||
|
||||
<string name="error_firmware_missing">Firmware je vyžadován pro spuštění některých her a aplikací. Eden funguje pouze s firmwarem 19.0.1 nebo starším.</string>
|
||||
<string name="error_firmware_corrupted">Firmware byl nahlášen jako přítomný, ale nelze jej přečíst. Zkontrolujte šifrovací klíče a v případě potřeby firmware převezměte znovu.</string>
|
||||
<string name="error_firmware_too_new">Firmware je příliš nový nebo nelze přečíst. Eden funguje pouze s firmwarem 19.0.1 nebo starším.</string>
|
||||
|
||||
<string name="keys_failed">Selhání instalace klíčů</string>
|
||||
<string name="keys_install_success">Klíče úspěšně nainstalovány</string>
|
||||
|
||||
@@ -353,9 +353,6 @@ Wirklich fortfahren?</string>
|
||||
<string name="firmware_uninstalling">Firmware wird deinstalliert...</string>
|
||||
<string name="firmware_uninstalled_success">Firmware erfolgreich deinstalliert</string>
|
||||
|
||||
<string name="error_firmware_missing">Firmware wird benötigt, um bestimmte Spiele und Applikationen zu nutzen. Eden funktioniert nur mit Firmware 19.0.1 oder älter.</string>
|
||||
<string name="error_firmware_corrupted">Firmware wurde als vorhanden gemeldet, konnte aber nicht gelesen werden. Überprüfen Sie die Entschlüsselungsschlüssel und dumpen Sie die Firmware bei Bedarf neu.</string>
|
||||
<string name="error_firmware_too_new">Firmware ist zu neu oder konnte nicht gelesen werden. Eden funktioniert nur mit Firmware 19.0.1 oder älter.</string>
|
||||
|
||||
<string name="keys_failed">Schlüsselinstallation fehlgeschlagen</string>
|
||||
<string name="keys_install_success">Schlüssel erfolgreich installiert</string>
|
||||
|
||||
@@ -368,9 +368,6 @@
|
||||
<string name="firmware_uninstalling">Desinstalando firmware...</string>
|
||||
<string name="firmware_uninstalled_success">Firmware desinstalado correctamente</string>
|
||||
|
||||
<string name="error_firmware_missing">Se requiere firmware para ejecutar ciertos juegos y aplicaciones. Eden solo funciona con firmware 19.0.1 o anterior.</string>
|
||||
<string name="error_firmware_corrupted">El firmware está presente pero no se pudo leer. Verifique las claves de descifrado y vuelva a volcar el firmware si es necesario.</string>
|
||||
<string name="error_firmware_too_new">El firmware es demasiado nuevo o no se pudo leer. Eden solo funciona con firmware 19.0.1 o anterior.</string>
|
||||
|
||||
<string name="keys_failed">Error al instalar claves</string>
|
||||
<string name="keys_install_success">Claves instaladas correctamente</string>
|
||||
|
||||
@@ -387,9 +387,6 @@
|
||||
<string name="verify_installed_content_description">تمام محتوای نصب شده را از نظر خرابی بررسی میکند</string>
|
||||
<string name="keys_missing">کلیدهای رمزگذاری وجود ندارند</string>
|
||||
<string name="keys_missing_description">ثابتافزار و بازیهای فروشگاهی قابل رمزگشایی نیستند</string>
|
||||
<string name="error_firmware_missing">برای اجرای برخی بازیها و برنامهها نیاز به فیرمور است. ادن فقط با فیرمور 19.0.1 یا قدیمیتر کار میکند.</string>
|
||||
<string name="error_firmware_corrupted">فیرمور موجود است اما قابل خواندن نیست. کلیدهای رمزگشایی را بررسی کنید و در صورت نیاز فیرمور را دوباره دامپ کنید.</string>
|
||||
<string name="error_firmware_too_new">فیرمور خیلی جدید است یا قابل خواندن نیست. ادن فقط با فیرمور 19.0.1 یا قدیمیتر کار میکند.</string>
|
||||
<string name="keys_failed">خطا در نصب کلیدها</string>
|
||||
<string name="keys_install_success">کلیدها با موفقیت نصب شدند</string>
|
||||
<string name="error_keys_copy_failed">یک یا چند کلید با خطا در کپی مواجه شد.</string>
|
||||
|
||||
@@ -368,9 +368,6 @@
|
||||
<string name="firmware_uninstalling">Désinstallation du firmware...</string>
|
||||
<string name="firmware_uninstalled_success">Firmware désinstallé avec succès</string>
|
||||
|
||||
<string name="error_firmware_missing">Le firmware est requis pour exécuter certains jeux et applications. Eden ne fonctionne qu\'avec le firmware 19.0.1 ou antérieur.</string>
|
||||
<string name="error_firmware_corrupted">Firmware présent mais illisible. Vérifiez les clés de décryptage et redumpz le firmware si nécessaire.</string>
|
||||
<string name="error_firmware_too_new">Firmware trop récent ou illisible. Eden ne supporte que le firmware 19.0.1 ou antérieur.</string>
|
||||
|
||||
<string name="keys_failed">Échec de l\'installation des clés</string>
|
||||
<string name="keys_install_success">Clés installées avec succès</string>
|
||||
|
||||
@@ -334,9 +334,6 @@
|
||||
<string name="firmware_uninstalling">מסיר קושחה...</string>
|
||||
<string name="firmware_uninstalled_success">הקושחה הוסרה בהצלחה</string>
|
||||
|
||||
<string name="error_firmware_missing">נדרש קושחה להפעלת משחקים ויישומים מסוימים. עדן עובד רק עם קושחה 19.0.1 או ישנה יותר.</string>
|
||||
<string name="error_firmware_corrupted">קושחה קיימת אך לא ניתנת לקריאה. בדוק מפתחות פענוח ושמור קושחה מחדש אם needed.</string>
|
||||
<string name="error_firmware_too_new">קושחה חדשה מדי או לא ניתנת לקריאה. עדן תומך רק בקושחה 19.0.1 או ישנה יותר.</string>
|
||||
|
||||
<string name="keys_failed">התקנת מפתחות נכשלה</string>
|
||||
<string name="keys_install_success">מפתחות הותקנו בהצלחה</string>
|
||||
|
||||
@@ -331,9 +331,6 @@
|
||||
<string name="firmware_uninstalling">Firmware eltávolítása...</string>
|
||||
<string name="firmware_uninstalled_success">A firmware sikeresen eltávolítva</string>
|
||||
|
||||
<string name="error_firmware_missing">A firmware szükséges egyes játékok és alkalmazások futtatásához. Az Eden csak 19.0.1 vagy régebbi firmware-ekkel működik.</string>
|
||||
<string name="error_firmware_corrupted">A firmware jelen van, de nem olvasható. Ellenőrizze a visszafejtési kulcsokat és szükség esetén dumpolja újra a firmware-t.</string>
|
||||
<string name="error_firmware_too_new">A firmware túl új vagy nem olvasható. Az Eden csak a 19.0.1 vagy régebbi firmware-ekkel működik.</string>
|
||||
|
||||
<string name="keys_failed">A kulcsok telepítése sikertelen</string>
|
||||
<string name="keys_install_success">A kulcsok sikeresen telepítve</string>
|
||||
|
||||
@@ -364,9 +364,6 @@
|
||||
<string name="firmware_uninstalling">Mencopot firmware...</string>
|
||||
<string name="firmware_uninstalled_success">Firmware berhasil dicopot</string>
|
||||
|
||||
<string name="error_firmware_missing">Firmware diperlukan untuk menjalankan game dan aplikasi tertentu. Eden hanya bekerja dengan firmware 19.0.1 atau lebih lama.</string>
|
||||
<string name="error_firmware_corrupted">Firmware dilaporkan ada tetapi tidak dapat dibaca. Periksa kunci dekripsi dan dump ulang firmware jika diperlukan.</string>
|
||||
<string name="error_firmware_too_new">Firmware terlalu baru atau tidak dapat dibaca. Eden hanya bekerja dengan firmware 19.0.1 atau lebih lama.</string>
|
||||
|
||||
<string name="keys_failed">Gagal menginstal kunci</string>
|
||||
<string name="keys_install_success">Kunci berhasil diinstal</string>
|
||||
|
||||
@@ -360,9 +360,6 @@
|
||||
<string name="firmware_uninstalling">Disinstallazione firmware...</string>
|
||||
<string name="firmware_uninstalled_success">Firmware disinstallato con successo</string>
|
||||
|
||||
<string name="error_firmware_missing">Il firmware è richiesto per eseguire alcuni giochi e applicazioni. Eden funziona solo con firmware 19.0.1 o precedente.</string>
|
||||
<string name="error_firmware_corrupted">Il firmware è presente ma non può essere letto. Controlla le chiavi di decrittazione e ridumpa il firmware se necessario.</string>
|
||||
<string name="error_firmware_too_new">Il firmware è troppo recente o illeggibile. Eden supporta solo firmware 19.0.1 o precedenti.</string>
|
||||
|
||||
<string name="keys_failed">Installazione chiavi fallita</string>
|
||||
<string name="keys_install_success">Chiavi installate con successo</string>
|
||||
|
||||
@@ -333,9 +333,6 @@
|
||||
<string name="firmware_uninstalling">ファームウェアをアンインストール中...</string>
|
||||
<string name="firmware_uninstalled_success">ファームウェアのアンインストールが成功しました</string>
|
||||
|
||||
<string name="error_firmware_missing">一部のゲームとアプリケーションを実行するにはファームウェアが必要です。Edenは19.0.1以前のファームウェアでのみ動作します。</string>
|
||||
<string name="error_firmware_corrupted">ファームウェアは存在しますが読み取れません。復号キーを確認し、必要に応じてファームウェアを再ダンプしてください。</string>
|
||||
<string name="error_firmware_too_new">ファームウェアが新しすぎるか読み取れません。Edenは19.0.1以前のファームウェアのみに対応しています。</string>
|
||||
|
||||
<string name="keys_failed">キーのインストールに失敗</string>
|
||||
<string name="keys_install_success">キーが正常にインストールされました</string>
|
||||
|
||||
@@ -330,9 +330,6 @@
|
||||
<string name="firmware_uninstalling">펌웨어 제거 중...</string>
|
||||
<string name="firmware_uninstalled_success">펌웨어가 성공적으로 제거되었습니다</string>
|
||||
|
||||
<string name="error_firmware_missing">일부 게임 및 애플리케이션 실행을 위해 펌웨어가 필요합니다. Eden은 19.0.1 이하 버전의 펌웨어에서만 작동합니다.</string>
|
||||
<string name="error_firmware_corrupted">펌웨어가 존재하지만 읽을 수 없습니다. 복호화 키를 확인하고 필요한 경우 펌웨어를 다시 덤프하세요.</string>
|
||||
<string name="error_firmware_too_new">펌웨어가 너무 최신이거나 읽을 수 없습니다. Eden은 19.0.1 이전 버전의 펌웨어에서만 작동합니다.</string>
|
||||
|
||||
<string name="keys_failed">키 설치 실패</string>
|
||||
<string name="keys_install_success">키가 성공적으로 설치됨</string>
|
||||
|
||||
@@ -322,9 +322,6 @@
|
||||
<string name="firmware_uninstalling">Avinstallerer firmware...</string>
|
||||
<string name="firmware_uninstalled_success">Firmware avinstallert</string>
|
||||
|
||||
<string name="error_firmware_missing">Fastvare kreves for å kjøre enkelte spill og applikasjoner. Eden fungerer bare med fastvare 19.0.1 eller eldre.</string>
|
||||
<string name="error_firmware_corrupted">Fastvare er til stede, men kan ikke leses. Sjekk dekrypteringsnøklene og dump fastvaren på nytt om nødvendig.</string>
|
||||
<string name="error_firmware_too_new">Fastvaren er for ny eller kan ikke leses. Eden fungerer bare med fastvare 19.0.1 eller eldre.</string>
|
||||
|
||||
<string name="keys_failed">Kunne ikke installere nøkler</string>
|
||||
<string name="keys_install_success">Nøklene ble installert</string>
|
||||
|
||||
@@ -370,9 +370,6 @@
|
||||
<string name="firmware_uninstalling">Odinstalowywanie firmware...</string>
|
||||
<string name="firmware_uninstalled_success">Firmware odinstalowany pomyślnie</string>
|
||||
|
||||
<string name="error_firmware_missing">Firmware jest wymagany do uruchamiania niektórych gier i aplikacji. Eden działa tylko z firmwarem 19.0.1 lub starszym.</string>
|
||||
<string name="error_firmware_corrupted">Oprogramowanie sprzętowe jest obecne, ale nie można go odczytać. Sprawdź klucze deszyfrujące i w razie potrzeby zrzuć oprogramowanie ponownie.</string>
|
||||
<string name="error_firmware_too_new">Oprogramowanie sprzętowe jest zbyt nowe lub nie można go odczytać. Eden działa tylko z oprogramowaniem sprzętowym w wersji 19.0.1 lub starszej.</string>
|
||||
|
||||
<string name="keys_failed">Nie udało się zainstalować kluczy</string>
|
||||
<string name="keys_install_success">Pomyślnie zainstalowano klucze</string>
|
||||
|
||||
@@ -368,9 +368,6 @@
|
||||
<string name="firmware_uninstalling">Desinstalando firmware</string>
|
||||
<string name="firmware_uninstalled_success">Firmware desinstalado com sucesso</string>
|
||||
|
||||
<string name="error_firmware_missing">Firmware é necessário para executar certos jogos e aplicativos. Eden só funciona com firmware 19.0.1 ou anterior.</string>
|
||||
<string name="error_firmware_corrupted">Firmware está presente mas não pode ser lido. Verifique as chaves de descriptografia e refaça o dump do firmware se necessário.</string>
|
||||
<string name="error_firmware_too_new">Firmware é muito novo ou não pode ser lido. Eden só funciona com firmware 19.0.1 ou anterior.</string>
|
||||
|
||||
<string name="keys_failed">Falha ao instalar chaves (keys)</string>
|
||||
<string name="keys_install_success">Chaves (keys) instaladas com sucesso</string>
|
||||
|
||||
@@ -334,9 +334,6 @@
|
||||
<string name="firmware_uninstalling">A desinstalar firmware...</string>
|
||||
<string name="firmware_uninstalled_success">Firmware desinstalado com sucesso</string>
|
||||
|
||||
<string name="error_firmware_missing">É necessário firmware para executar alguns jogos e aplicações. O Eden só funciona com firmware 19.0.1 ou anterior.</string>
|
||||
<string name="error_firmware_corrupted">Firmware está presente mas não pode ser lido. Verifique chaves de descriptografia e volte a fazer dump do firmware se necessário.</string>
|
||||
<string name="error_firmware_too_new">Firmware é demasiado recente ou ilegível. O Eden só funciona com firmware 19.0.1 ou anterior.</string>
|
||||
|
||||
<string name="keys_failed">Falha ao instalar chaves</string>
|
||||
<string name="keys_install_success">Chaves instaladas com sucesso</string>
|
||||
|
||||
@@ -370,9 +370,6 @@
|
||||
<string name="firmware_uninstalling">Удаление прошивки...</string>
|
||||
<string name="firmware_uninstalled_success">Прошивка успешно удалена</string>
|
||||
|
||||
<string name="error_firmware_missing">Для запуска некоторых игр и системных апплетов требуется прошивка. Eden работает только с прошивкой версии 19.0.1 и ниже.</string>
|
||||
<string name="error_firmware_corrupted">Прошивка обнаружена, но не может быть прочитана. Проверьте наличие ключей дешифрования и при необходимости пересохраните прошивку.</string>
|
||||
<string name="error_firmware_too_new">Прошивка слишком новая или не может быть прочитана. Eden работает только с прошивкой версии 19.0.1 и ниже.</string>
|
||||
|
||||
<string name="keys_failed">Ошибка установки ключей</string>
|
||||
<string name="keys_install_success">Ключи успешно установлены</string>
|
||||
|
||||
@@ -334,9 +334,6 @@
|
||||
<string name="firmware_uninstalling">Деинсталирање фирмвера</string>
|
||||
<string name="firmware_uninstalled_success">Фирмваре је успешно деинсталирано</string>
|
||||
|
||||
<string name="error_firmware_missing">Firmware је потребан за покретање одређених игара и апликација. Eden ради само са firmware-ом 19.0.1 или старијим.</string>
|
||||
<string name="error_firmware_corrupted">Firmware је присутан али се не може прочитати. Проверите кључеве за дешифровање и поново направите firmware дамп ако је потребно.</string>
|
||||
<string name="error_firmware_too_new">Firmware је превише нов или се не може прочитати. Eden ради само са firmware-ом 19.0.1 или старијим.</string>
|
||||
|
||||
<string name="keys_failed">Неуспела инсталација кључева</string>
|
||||
<string name="keys_install_success">Кључеви успешно инсталирани</string>
|
||||
|
||||
@@ -370,9 +370,6 @@
|
||||
<string name="firmware_uninstalling">Видалення прошивки...</string>
|
||||
<string name="firmware_uninstalled_success">Прошивку успішно видалено</string>
|
||||
|
||||
<string name="error_firmware_missing">Для запуску деяких ігор та системних аплетів потрібна прошивка. Eden працює лише з прошивкою 19.0.1 або старішою.</string>
|
||||
<string name="error_firmware_corrupted">Прошивка є, але не може бути прочитана. Перевірте ключі дешифрування та повторно зробіть дамп прошивки за необхідності.</string>
|
||||
<string name="error_firmware_too_new">Прошивка занадто нова або нечитабельна. Eden працює лише з прошивкою 19.0.1 або старішою.</string>
|
||||
|
||||
<string name="keys_failed">Не вдалося встановити ключі</string>
|
||||
<string name="keys_install_success">Ключі успішно встановлено</string>
|
||||
|
||||
@@ -320,9 +320,6 @@
|
||||
<string name="firmware_uninstalling">Đang gỡ cài đặt firmware...</string>
|
||||
<string name="firmware_uninstalled_success">Gỡ cài đặt firmware thành công</string>
|
||||
|
||||
<string name="error_firmware_missing">Firmware là cần thiết để chạy một số trò chơi và ứng dụng. Eden chỉ hoạt động với firmware 19.0.1 trở về trước.</string>
|
||||
<string name="error_firmware_corrupted">Firmware được báo cáo là có nhưng không thể đọc được. Kiểm tra khóa giải mã và dump lại firmware nếu cần.</string>
|
||||
<string name="error_firmware_too_new">Firmware quá mới hoặc không thể đọc. Eden chỉ hoạt động với firmware 19.0.1 trở về trước.</string>
|
||||
|
||||
<string name="keys_failed">Không thể cài đặt khóa</string>
|
||||
<string name="keys_install_success">Đã cài đặt khóa thành công</string>
|
||||
|
||||
@@ -335,9 +335,6 @@
|
||||
<string name="firmware_uninstalling">正在卸载固件...</string>
|
||||
<string name="firmware_uninstalled_success">固件卸载成功</string>
|
||||
|
||||
<string name="error_firmware_missing">运行某些游戏和系统应用需要固件。Eden仅支持19.0.1及更早版本的固件。</string>
|
||||
<string name="error_firmware_corrupted">检测到固件存在但无法读取。请检查解密密钥并在必要时重新转储固件。</string>
|
||||
<string name="error_firmware_too_new">固件过新或无法读取。Eden仅支持19.0.1及更早版本的固件。</string>
|
||||
|
||||
<string name="keys_failed">密钥安装失败</string>
|
||||
<string name="keys_install_success">密钥安装成功</string>
|
||||
|
||||
@@ -364,9 +364,6 @@
|
||||
<string name="firmware_uninstalling">正在解除安裝韌體...</string>
|
||||
<string name="firmware_uninstalled_success">韌體解除安裝成功</string>
|
||||
|
||||
<string name="error_firmware_missing">執行某些遊戲和系統應用程式需要韌體。Eden僅支援19.0.1及更早版本的韌體。</string>
|
||||
<string name="error_firmware_corrupted">檢測到韌體存在但無法讀取。請檢查解密金鑰並在必要時重新轉儲韌體。</string>
|
||||
<string name="error_firmware_too_new">韌體過新或無法讀取。Eden僅支援19.0.1及更早版本的韌體。</string>
|
||||
|
||||
<string name="keys_failed">金鑰安裝失敗</string>
|
||||
<string name="keys_install_success">金鑰安裝成功</string>
|
||||
|
||||
@@ -376,9 +376,6 @@
|
||||
<string name="firmware_uninstalling">Uninstalling firmware</string>
|
||||
<string name="firmware_uninstalled_success">Firmware uninstalled successfully</string>
|
||||
|
||||
<string name="error_firmware_missing">Firmware is required to run certain games and use system applications. Eden only works with firmware 19.0.1 and earlier.</string>
|
||||
<string name="error_firmware_corrupted">Firmware reported as present, but was unable to be read. Check for decryption keys and redump firmware if necessary.</string>
|
||||
<string name="error_firmware_too_new">Firmware is too new or could not be read. Eden only works with firmware 19.0.1 and earlier.</string>
|
||||
|
||||
<string name="keys_failed">Failed to Install Keys</string>
|
||||
<string name="keys_install_success">Keys successfully installed</string>
|
||||
|
||||
@@ -188,7 +188,7 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
|
||||
}
|
||||
// Successfully dequeued a new buffer.
|
||||
{
|
||||
std::unique_lock lk{release_mutex};\
|
||||
std::unique_lock lk{release_mutex};
|
||||
queued_buffers--;
|
||||
}
|
||||
release_cv.notify_one();
|
||||
@@ -237,9 +237,15 @@ u64 SinkStream::GetExpectedPlayedSampleCount() {
|
||||
|
||||
void SinkStream::WaitFreeSpace(std::stop_token stop_token) {
|
||||
std::unique_lock lk{release_mutex};
|
||||
release_cv.wait_for(lk, std::chrono::milliseconds(5), [this]() { return paused || queued_buffers < max_queue_size; });
|
||||
if (queued_buffers > max_queue_size + 3) {
|
||||
release_cv.wait(lk, stop_token, [this] { return paused || queued_buffers < max_queue_size; });
|
||||
|
||||
const auto has_space = [this]() {
|
||||
const u32 current_size = queued_buffers.load(std::memory_order_relaxed);
|
||||
return paused || max_queue_size == 0 || current_size < max_queue_size;
|
||||
};
|
||||
|
||||
if (!has_space()) {
|
||||
// Wait until the queue falls below the configured limit or the stream is paused/stopped.
|
||||
release_cv.wait(lk, stop_token, has_space);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ private:
|
||||
/// Ring buffer of the samples waiting to be played or consumed
|
||||
Common::RingBuffer<s16, 0x10000> samples_buffer;
|
||||
/// Audio buffers queued and waiting to play
|
||||
Common::SPSCQueue<SinkBuffer, 0x40000> queue;
|
||||
Common::SPSCQueue<SinkBuffer, 0x10000> queue;
|
||||
/// The currently-playing audio buffer
|
||||
SinkBuffer playing_buffer{};
|
||||
/// The last played (or received) frame of audio, used when the callback underruns
|
||||
|
||||
@@ -153,6 +153,8 @@ add_library(
|
||||
wall_clock.h
|
||||
zstd_compression.cpp
|
||||
zstd_compression.h
|
||||
fs/ryujinx_compat.h fs/ryujinx_compat.cpp
|
||||
fs/symlink.h fs/symlink.cpp
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#define SUDACHI_DIR "sudachi"
|
||||
#define YUZU_DIR "yuzu"
|
||||
#define SUYU_DIR "suyu"
|
||||
#define RYUJINX_DIR "Ryujinx"
|
||||
|
||||
// yuzu-specific files
|
||||
#define LOG_FILE "eden_log.txt"
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
return eden_paths.at(eden_path);
|
||||
}
|
||||
|
||||
[[nodiscard]] const fs::path& GetLegacyPathImpl(LegacyPath legacy_path) {
|
||||
[[nodiscard]] const fs::path& GetLegacyPathImpl(EmuPath legacy_path) {
|
||||
return legacy_paths.at(legacy_path);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
eden_paths.insert_or_assign(eden_path, new_path);
|
||||
}
|
||||
|
||||
void SetLegacyPathImpl(LegacyPath legacy_path, const fs::path& new_path) {
|
||||
void SetLegacyPathImpl(EmuPath legacy_path, const fs::path& new_path) {
|
||||
legacy_paths.insert_or_assign(legacy_path, new_path);
|
||||
}
|
||||
|
||||
@@ -118,9 +118,9 @@ public:
|
||||
}
|
||||
eden_path_cache = eden_path / CACHE_DIR;
|
||||
eden_path_config = eden_path / CONFIG_DIR;
|
||||
#define LEGACY_PATH(titleName, upperName) GenerateLegacyPath(LegacyPath::titleName##Dir, GetAppDataRoamingDirectory() / upperName##_DIR); \
|
||||
GenerateLegacyPath(LegacyPath::titleName##ConfigDir, GetAppDataRoamingDirectory() / upperName##_DIR / CONFIG_DIR); \
|
||||
GenerateLegacyPath(LegacyPath::titleName##CacheDir, GetAppDataRoamingDirectory() / upperName##_DIR / CACHE_DIR);
|
||||
#define LEGACY_PATH(titleName, upperName) GenerateLegacyPath(EmuPath::titleName##Dir, GetAppDataRoamingDirectory() / upperName##_DIR); \
|
||||
GenerateLegacyPath(EmuPath::titleName##ConfigDir, GetAppDataRoamingDirectory() / upperName##_DIR / CONFIG_DIR); \
|
||||
GenerateLegacyPath(EmuPath::titleName##CacheDir, GetAppDataRoamingDirectory() / upperName##_DIR / CACHE_DIR);
|
||||
LEGACY_PATH(Citron, CITRON)
|
||||
LEGACY_PATH(Sudachi, SUDACHI)
|
||||
LEGACY_PATH(Yuzu, YUZU)
|
||||
@@ -140,9 +140,9 @@ public:
|
||||
eden_path_cache = eden_path / CACHE_DIR;
|
||||
eden_path_config = eden_path / CONFIG_DIR;
|
||||
}
|
||||
#define LEGACY_PATH(titleName, upperName) GenerateLegacyPath(LegacyPath::titleName##Dir, GetDataDirectory("XDG_DATA_HOME") / upperName##_DIR); \
|
||||
GenerateLegacyPath(LegacyPath::titleName##ConfigDir, GetDataDirectory("XDG_CONFIG_HOME") / upperName##_DIR); \
|
||||
GenerateLegacyPath(LegacyPath::titleName##CacheDir, GetDataDirectory("XDG_CACHE_HOME") / upperName##_DIR);
|
||||
#define LEGACY_PATH(titleName, upperName) GenerateLegacyPath(EmuPath::titleName##Dir, GetDataDirectory("XDG_DATA_HOME") / upperName##_DIR); \
|
||||
GenerateLegacyPath(EmuPath::titleName##ConfigDir, GetDataDirectory("XDG_CONFIG_HOME") / upperName##_DIR); \
|
||||
GenerateLegacyPath(EmuPath::titleName##CacheDir, GetDataDirectory("XDG_CACHE_HOME") / upperName##_DIR);
|
||||
LEGACY_PATH(Citron, CITRON)
|
||||
LEGACY_PATH(Sudachi, SUDACHI)
|
||||
LEGACY_PATH(Yuzu, YUZU)
|
||||
@@ -165,6 +165,15 @@ public:
|
||||
GenerateEdenPath(EdenPath::ShaderDir, eden_path / SHADER_DIR);
|
||||
GenerateEdenPath(EdenPath::TASDir, eden_path / TAS_DIR);
|
||||
GenerateEdenPath(EdenPath::IconsDir, eden_path / ICONS_DIR);
|
||||
|
||||
#ifdef _WIN32
|
||||
GenerateLegacyPath(EmuPath::RyujinxDir, GetAppDataRoamingDirectory() / RYUJINX_DIR);
|
||||
#else
|
||||
// In Ryujinx's infinite wisdom, it places EVERYTHING in the config directory on UNIX
|
||||
// This is incredibly stupid and violates a million XDG standards, but whatever
|
||||
GenerateLegacyPath(EmuPath::RyujinxDir, GetDataDirectory("XDG_CONFIG_HOME") / RYUJINX_DIR);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -179,12 +188,12 @@ private:
|
||||
SetEdenPathImpl(eden_path, new_path);
|
||||
}
|
||||
|
||||
void GenerateLegacyPath(LegacyPath legacy_path, const fs::path& new_path) {
|
||||
void GenerateLegacyPath(EmuPath legacy_path, const fs::path& new_path) {
|
||||
SetLegacyPathImpl(legacy_path, new_path);
|
||||
}
|
||||
|
||||
std::unordered_map<EdenPath, fs::path> eden_paths;
|
||||
std::unordered_map<LegacyPath, fs::path> legacy_paths;
|
||||
std::unordered_map<EmuPath, fs::path> legacy_paths;
|
||||
};
|
||||
|
||||
bool ValidatePath(const fs::path& path) {
|
||||
@@ -272,7 +281,7 @@ const fs::path& GetEdenPath(EdenPath eden_path) {
|
||||
return PathManagerImpl::GetInstance().GetEdenPathImpl(eden_path);
|
||||
}
|
||||
|
||||
const std::filesystem::path& GetLegacyPath(LegacyPath legacy_path) {
|
||||
const std::filesystem::path& GetLegacyPath(EmuPath legacy_path) {
|
||||
return PathManagerImpl::GetInstance().GetLegacyPathImpl(legacy_path);
|
||||
}
|
||||
|
||||
@@ -280,7 +289,7 @@ std::string GetEdenPathString(EdenPath eden_path) {
|
||||
return PathToUTF8String(GetEdenPath(eden_path));
|
||||
}
|
||||
|
||||
std::string GetLegacyPathString(LegacyPath legacy_path) {
|
||||
std::string GetLegacyPathString(EmuPath legacy_path) {
|
||||
return PathToUTF8String(GetLegacyPath(legacy_path));
|
||||
}
|
||||
|
||||
|
||||
@@ -32,22 +32,26 @@ enum class EdenPath {
|
||||
IconsDir, // Where Icons for Windows shortcuts are stored.
|
||||
};
|
||||
|
||||
enum LegacyPath {
|
||||
CitronDir, // Citron Directories for migration
|
||||
// migration/compat dirs
|
||||
enum EmuPath {
|
||||
CitronDir,
|
||||
CitronConfigDir,
|
||||
CitronCacheDir,
|
||||
|
||||
SudachiDir, // Sudachi Directories for migration
|
||||
SudachiDir,
|
||||
SudachiConfigDir,
|
||||
SudachiCacheDir,
|
||||
|
||||
YuzuDir, // Yuzu Directories for migration
|
||||
YuzuDir,
|
||||
YuzuConfigDir,
|
||||
YuzuCacheDir,
|
||||
|
||||
SuyuDir, // Suyu Directories for migration
|
||||
SuyuDir,
|
||||
SuyuConfigDir,
|
||||
SuyuCacheDir,
|
||||
|
||||
// used exclusively for save data linking
|
||||
RyujinxDir,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -229,7 +233,7 @@ void SetAppDirectory(const std::string& app_directory);
|
||||
*
|
||||
* @returns The filesystem path associated with the LegacyPath enum.
|
||||
*/
|
||||
[[nodiscard]] const std::filesystem::path& GetLegacyPath(LegacyPath legacy_path);
|
||||
[[nodiscard]] const std::filesystem::path& GetLegacyPath(EmuPath legacy_path);
|
||||
|
||||
/**
|
||||
* Gets the filesystem path associated with the EdenPath enum as a UTF-8 encoded std::string.
|
||||
@@ -247,7 +251,7 @@ void SetAppDirectory(const std::string& app_directory);
|
||||
*
|
||||
* @returns The filesystem path associated with the LegacyPath enum as a UTF-8 encoded std::string.
|
||||
*/
|
||||
[[nodiscard]] std::string GetLegacyPathString(LegacyPath legacy_path);
|
||||
[[nodiscard]] std::string GetLegacyPathString(EmuPath legacy_path);
|
||||
|
||||
/**
|
||||
* Sets a new filesystem path associated with the EdenPath enum.
|
||||
|
||||
93
src/common/fs/ryujinx_compat.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "ryujinx_compat.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <fmt/ranges.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace Common::FS {
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
fs::path GetKvdbPath()
|
||||
{
|
||||
return GetLegacyPath(EmuPath::RyujinxDir) / "bis" / "system" / "save" / "8000000000000000" / "0"
|
||||
/ "imkvdb.arc";
|
||||
}
|
||||
|
||||
fs::path GetRyuSavePath(const u64 &save_id)
|
||||
{
|
||||
std::string hex = fmt::format("{:016x}", save_id);
|
||||
|
||||
// TODO: what's the difference between 0 and 1?
|
||||
return GetLegacyPath(EmuPath::RyujinxDir) / "bis" / "user" / "save" / hex / "0";
|
||||
}
|
||||
|
||||
IMENReadResult ReadKvdb(const fs::path &path, std::vector<IMEN> &imens)
|
||||
{
|
||||
std::ifstream kvdb{path, std::ios::binary | std::ios::ate};
|
||||
|
||||
if (!kvdb) {
|
||||
return IMENReadResult::Nonexistent;
|
||||
}
|
||||
|
||||
size_t file_size = kvdb.tellg();
|
||||
|
||||
// IMKV header + 8 bytes
|
||||
if (file_size < 0xB) {
|
||||
return IMENReadResult::NoHeader;
|
||||
}
|
||||
|
||||
// magic (not the wizard kind)
|
||||
kvdb.seekg(0, std::ios::beg);
|
||||
char header[12];
|
||||
kvdb.read(header, 12);
|
||||
|
||||
if (std::memcmp(header, IMKV_MAGIC, 4) != 0) {
|
||||
return IMENReadResult::InvalidMagic;
|
||||
}
|
||||
|
||||
// calculate num. of imens left
|
||||
std::size_t remaining = (file_size - 12);
|
||||
std::size_t num_imens = remaining / IMEN_SIZE;
|
||||
|
||||
// File is misaligned and probably corrupt (rip)
|
||||
if (remaining % IMEN_SIZE != 0) {
|
||||
return IMENReadResult::Misaligned;
|
||||
}
|
||||
|
||||
// if there aren't any IMENs, it's empty and we can safely no-op out of here
|
||||
if (num_imens == 0) {
|
||||
return IMENReadResult::NoImens;
|
||||
}
|
||||
|
||||
imens.reserve(num_imens);
|
||||
|
||||
// initially I wanted to do a struct, but imkvdb is 140 bytes
|
||||
// while the compiler will murder you if you try to align u64 to 4 bytes
|
||||
for (std::size_t i = 0; i < num_imens; ++i) {
|
||||
char magic[4];
|
||||
u64 title_id = 0;
|
||||
u64 save_id = 0;
|
||||
|
||||
kvdb.read(magic, 4);
|
||||
if (std::memcmp(magic, IMEN_MAGIC, 4) != 0) {
|
||||
return IMENReadResult::InvalidMagic;
|
||||
}
|
||||
|
||||
kvdb.ignore(0x8);
|
||||
kvdb.read(reinterpret_cast<char *>(&title_id), 8);
|
||||
kvdb.ignore(0x38);
|
||||
kvdb.read(reinterpret_cast<char *>(&save_id), 8);
|
||||
kvdb.ignore(0x38);
|
||||
|
||||
imens.emplace_back(IMEN{title_id, save_id});
|
||||
}
|
||||
|
||||
return IMENReadResult::Success;
|
||||
}
|
||||
|
||||
} // namespace Common::FS
|
||||
40
src/common/fs/ryujinx_compat.h
Normal file
@@ -0,0 +1,40 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace Common::FS {
|
||||
|
||||
constexpr const char IMEN_MAGIC[4] = {0x49, 0x4d, 0x45, 0x4e};
|
||||
constexpr const char IMKV_MAGIC[4] = {0x49, 0x4d, 0x4b, 0x56};
|
||||
constexpr const u8 IMEN_SIZE = 0x8c;
|
||||
|
||||
fs::path GetKvdbPath();
|
||||
fs::path GetRyuSavePath(const u64 &program_id);
|
||||
|
||||
enum class IMENReadResult {
|
||||
Nonexistent, // ryujinx not found
|
||||
NoHeader, // file isn't big enough for header
|
||||
InvalidMagic, // no IMKV or IMEN header
|
||||
Misaligned, // file isn't aligned to expected IMEN boundaries
|
||||
NoImens, // no-op, there are no IMENs
|
||||
Success, // :)
|
||||
};
|
||||
|
||||
struct IMEN
|
||||
{
|
||||
u64 title_id;
|
||||
u64 save_id;
|
||||
};
|
||||
|
||||
static_assert(sizeof(IMEN) == 0x10, "IMEN has incorrect size.");
|
||||
|
||||
IMENReadResult ReadKvdb(const fs::path &path, std::vector<IMEN> &imens);
|
||||
|
||||
} // namespace Common::FS
|
||||
43
src/common/fs/symlink.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "symlink.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <fmt/format.h>
|
||||
#endif
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// The sole purpose of this file is to treat symlinks like symlinks on POSIX,
|
||||
// or treat them as directory junctions on Windows.
|
||||
// This is because, for some inexplicable reason, Microsoft has locked symbolic
|
||||
// links behind a "security policy", whereas directory junctions--functionally identical
|
||||
// for directories, by the way--are not. Why? I don't know.
|
||||
|
||||
namespace Common::FS {
|
||||
|
||||
bool CreateSymlink(const fs::path &from, const fs::path &to)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const std::string command = fmt::format("mklink /J {} {}", to.string(), from.string());
|
||||
return system(command.c_str()) == 0;
|
||||
#else
|
||||
std::error_code ec;
|
||||
fs::create_directory_symlink(from, to, ec);
|
||||
return !ec;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsSymlink(const fs::path &path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
auto attributes = GetFileAttributesW(path.wstring().c_str());
|
||||
return attributes & FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
#else
|
||||
return fs::is_symlink(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Common::FS
|
||||
12
src/common/fs/symlink.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
namespace Common::FS {
|
||||
|
||||
bool CreateSymlink(const std::filesystem::path &from, const std::filesystem::path &to);
|
||||
bool IsSymlink(const std::filesystem::path &path);
|
||||
|
||||
} // namespace Common::FS
|
||||
@@ -622,6 +622,10 @@ struct Values {
|
||||
|
||||
// Linux
|
||||
SwitchableSetting<bool> enable_gamemode{linkage, true, "enable_gamemode", Category::Linux};
|
||||
#ifdef __unix__
|
||||
SwitchableSetting<bool> gui_force_x11{linkage, false, "gui_force_x11", Category::Linux};
|
||||
Setting<bool> gui_hide_backend_warning{linkage, false, "gui_hide_backend_warning", Category::Linux};
|
||||
#endif
|
||||
|
||||
// Controls
|
||||
InputSetting<std::array<PlayerInput, 10>> players;
|
||||
|
||||
@@ -210,12 +210,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ArmDynarmic32::MakeJit(Common::PageTable* pa
|
||||
config.wall_clock_cntpct = m_uses_wall_clock;
|
||||
config.enable_cycle_counting = !m_uses_wall_clock;
|
||||
|
||||
// Code cache size
|
||||
#ifdef ARCHITECTURE_arm64
|
||||
// Code cache size - max in ARM is 128MiB, max in x86_64 is 2GiB
|
||||
// Solaris doesn't support kPageSize >= 512MiB
|
||||
config.code_cache_size = std::uint32_t(128_MiB);
|
||||
#else
|
||||
config.code_cache_size = std::uint32_t(512_MiB);
|
||||
#endif
|
||||
|
||||
// Allow memory fault handling to work
|
||||
if (m_system.DebuggerEnabled()) {
|
||||
|
||||
@@ -269,12 +269,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa
|
||||
config.wall_clock_cntpct = m_uses_wall_clock;
|
||||
config.enable_cycle_counting = !m_uses_wall_clock;
|
||||
|
||||
// Code cache size
|
||||
#ifdef ARCHITECTURE_arm64
|
||||
// Code cache size - max in ARM is 128MiB, max in x86_64 is 2GiB
|
||||
// Solaris doesn't support kPageSize >= 512MiB
|
||||
config.code_cache_size = std::uint32_t(128_MiB);
|
||||
#else
|
||||
config.code_cache_size = std::uint32_t(512_MiB);
|
||||
#endif
|
||||
|
||||
// Allow memory fault handling to work
|
||||
if (m_system.DebuggerEnabled()) {
|
||||
|
||||
@@ -10,16 +10,19 @@
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/algorithm/string/find.hpp>
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
#include "common/fs/file.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/fs_types.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include <ranges>
|
||||
#include "common/settings.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/file_sys/savedata_factory.h"
|
||||
#include "core/hle/service/acc/profile_manager.h"
|
||||
#include <ranges>
|
||||
|
||||
namespace Service::Account {
|
||||
|
||||
@@ -39,6 +42,7 @@ struct ProfileDataRaw {
|
||||
INSERT_PADDING_BYTES(0x10);
|
||||
std::array<UserRaw, MAX_USERS> users{};
|
||||
};
|
||||
|
||||
static_assert(sizeof(ProfileDataRaw) == 0x650, "ProfileDataRaw has incorrect size.");
|
||||
|
||||
// TODO(ogniK): Get actual error codes
|
||||
@@ -490,8 +494,22 @@ void ProfileManager::ResetUserSaveFile()
|
||||
|
||||
std::vector<std::string> ProfileManager::FindGoodProfiles()
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::vector<std::string> good_uuids;
|
||||
|
||||
const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir)
|
||||
/ "user/save/0000000000000000";
|
||||
|
||||
// some exceptions because certain games just LOVE TO CAUSE ISSUES
|
||||
static constexpr const std::array<const char* const, 2> EXCEPTION_UUIDS
|
||||
= {"5755CC2A545A87128500000000000000", "00000000000000000000000000000000"};
|
||||
|
||||
for (const char *const uuid : EXCEPTION_UUIDS) {
|
||||
if (fs::exists(path / uuid))
|
||||
good_uuids.emplace_back(uuid);
|
||||
}
|
||||
|
||||
for (const ProfileInfo& p : profiles) {
|
||||
std::string uuid_string = [p]() -> std::string {
|
||||
auto uuid = p.user_uuid;
|
||||
@@ -506,12 +524,9 @@ std::vector<std::string> ProfileManager::FindGoodProfiles()
|
||||
return fmt::format("{:016X}{:016X}", user_id[1], user_id[0]);
|
||||
}();
|
||||
|
||||
good_uuids.emplace_back(uuid_string);
|
||||
if (uuid_string != "0") good_uuids.emplace_back(uuid_string);
|
||||
}
|
||||
|
||||
// used for acnh, etc
|
||||
good_uuids.emplace_back("00000000000000000000000000000000");
|
||||
|
||||
return good_uuids;
|
||||
}
|
||||
|
||||
@@ -519,6 +534,8 @@ std::vector<std::string> ProfileManager::FindOrphanedProfiles()
|
||||
{
|
||||
std::vector<std::string> good_uuids = FindGoodProfiles();
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// TODO: fetch save_id programmatically
|
||||
const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir)
|
||||
/ "user/save/0000000000000000";
|
||||
@@ -530,32 +547,47 @@ std::vector<std::string> ProfileManager::FindOrphanedProfiles()
|
||||
[&good_uuids, &orphaned_profiles](const std::filesystem::directory_entry& entry) -> bool {
|
||||
const std::string uuid = entry.path().stem().string();
|
||||
|
||||
bool override = false;
|
||||
|
||||
// first off, we should always clear empty profiles
|
||||
// 99% of the time these are useless. If not, they are recreated anyways...
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const auto is_empty = [&entry]() -> bool {
|
||||
const auto is_empty = [&entry, &override]() -> bool {
|
||||
try {
|
||||
for (const auto& file : fs::recursive_directory_iterator(entry.path())) {
|
||||
if (file.is_regular_file()) {
|
||||
return true;
|
||||
}
|
||||
// TODO: .yuzu_save_size is a weird file that gets created by certain games
|
||||
// I have no idea what its purpose is, but TEMPORARY SOLUTION: just mark the profile as valid if
|
||||
// this file exists (???) e.g. for SSBU
|
||||
// In short: if .yuzu_save_size is the ONLY file in a profile it's probably fine to keep
|
||||
if (file.path().filename().string() == FileSys::GetSaveDataSizeFileName())
|
||||
override = true;
|
||||
|
||||
// if there are any regular files (NOT directories) there, do NOT delete it :p
|
||||
if (file.is_regular_file())
|
||||
return false;
|
||||
}
|
||||
} catch (const fs::filesystem_error& e) {
|
||||
// if we get an error--no worries, just pretend it's not empty
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}();
|
||||
|
||||
if (!is_empty) {
|
||||
if (is_empty) {
|
||||
fs::remove_all(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
// edge-case: some filesystems forcefully change filenames to lowercase
|
||||
// so we can just ignore any differences
|
||||
// looking at you microsoft... ;)
|
||||
std::string upper_uuid = uuid;
|
||||
boost::to_upper(upper_uuid);
|
||||
|
||||
// if profiles.dat contains the UUID--all good
|
||||
// if not--it's an orphaned profile and should be resolved by the user
|
||||
if (std::find(good_uuids.begin(), good_uuids.end(), uuid) == good_uuids.end()) {
|
||||
if (!override
|
||||
&& std::find(good_uuids.begin(), good_uuids.end(), upper_uuid) == good_uuids.end()) {
|
||||
orphaned_profiles.emplace_back(uuid);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -69,7 +69,7 @@ enum class FatalType : u32 {
|
||||
static void GenerateErrorReport(Core::System& system, Result error_code, const FatalInfo& info) {
|
||||
const auto title_id = system.GetApplicationProcessProgramID();
|
||||
std::string crash_report = fmt::format(
|
||||
"Yuzu {}-{} crash report\n"
|
||||
"Eden {}-{} crash report\n"
|
||||
"Title ID: {:016x}\n"
|
||||
"Result: {:#X} ({:04}-{:04d})\n"
|
||||
"Set flags: 0x{:16X}\n"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -70,67 +73,80 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
|
||||
|
||||
system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false);
|
||||
|
||||
// clang-format off
|
||||
kernel.RunOnHostCoreProcess("audio", [&] { Audio::LoopProcess(system); }).detach();
|
||||
kernel.RunOnHostCoreProcess("FS", [&] { FileSystem::LoopProcess(system); }).detach();
|
||||
kernel.RunOnHostCoreProcess("jit", [&] { JIT::LoopProcess(system); }).detach();
|
||||
kernel.RunOnHostCoreProcess("ldn", [&] { LDN::LoopProcess(system); }).detach();
|
||||
kernel.RunOnHostCoreProcess("Loader", [&] { LDR::LoopProcess(system); }).detach();
|
||||
kernel.RunOnHostCoreProcess("nvservices", [&] { Nvidia::LoopProcess(system); }).detach();
|
||||
kernel.RunOnHostCoreProcess("bsdsocket", [&] { Sockets::LoopProcess(system); }).detach();
|
||||
kernel.RunOnHostCoreProcess("vi", [&, token] { VI::LoopProcess(system, token); }).detach();
|
||||
// Just a quick C++ lesson
|
||||
// Capturing lambdas will silently create new variables for the objects referenced via <ident> = <expr>
|
||||
// and create a `auto&` sorts of for `&`; with all your usual reference shenanigans.
|
||||
// Do not be confused, `std::function<>` will allocate into the heap and will do so most of the time
|
||||
// The heap is where we'd expect our "stored" values to be placed at.
|
||||
//
|
||||
// Eventually we'd need a "heapless" solution so the overhead is nil - but again a good starting point
|
||||
// is removing all the cold clones ;)
|
||||
|
||||
kernel.RunOnGuestCoreProcess("sm", [&] { SM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("account", [&] { Account::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("am", [&] { AM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("aoc", [&] { AOC::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("apm", [&] { APM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("bcat", [&] { BCAT::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("bpc", [&] { BPC::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("btdrv", [&] { BtDrv::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("btm", [&] { BTM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("capsrv", [&] { Capture::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("erpt", [&] { ERPT::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("es", [&] { ES::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("eupld", [&] { EUPLD::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("fatal", [&] { Fatal::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("fgm", [&] { FGM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("friends", [&] { Friend::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("settings", [&] { Set::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("psc", [&] { PSC::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("glue", [&] { Glue::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("grc", [&] { GRC::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("hid", [&] { HID::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("lbl", [&] { LBL::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("LogManager.Prod", [&] { LM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("mig", [&] { Migration::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("mii", [&] { Mii::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("mm", [&] { MM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("mnpp", [&] { MNPP::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("nvnflinger", [&] { Nvnflinger::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("NCM", [&] { NCM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("nfc", [&] { NFC::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("nfp", [&] { NFP::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("ngc", [&] { NGC::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("nifm", [&] { NIFM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("nim", [&] { NIM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("npns", [&] { NPNS::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("ns", [&] { NS::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("olsc", [&] { OLSC::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("omm", [&] { OMM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("pcie", [&] { PCIe::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("pctl", [&] { PCTL::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("pcv", [&] { PCV::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("prepo", [&] { PlayReport::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("ProcessManager", [&] { PM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("ptm", [&] { PTM::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("ro", [&] { RO::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("spl", [&] { SPL::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("ssl", [&] { SSL::LoopProcess(system); });
|
||||
kernel.RunOnGuestCoreProcess("usb", [&] { USB::LoopProcess(system); });
|
||||
// clang-format on
|
||||
// BEGONE cold clones of lambdas, for I have merged you all into a SINGLE lambda instead of
|
||||
// spamming lambdas like it's some kind of lambda calculus class
|
||||
for (auto const& e : std::vector<std::pair<std::string_view, void (*)(Core::System&)>>{
|
||||
{"audio", &Audio::LoopProcess},
|
||||
{"FS", &FileSystem::LoopProcess},
|
||||
{"jit", &JIT::LoopProcess},
|
||||
{"ldn", &LDN::LoopProcess},
|
||||
{"Loader", &LDR::LoopProcess},
|
||||
{"nvservices", &Nvidia::LoopProcess},
|
||||
{"bsdsocket", &Sockets::LoopProcess},
|
||||
})
|
||||
kernel.RunOnHostCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); }).detach();
|
||||
kernel.RunOnHostCoreProcess("vi", [&, token] { VI::LoopProcess(system, token); }).detach();
|
||||
// Avoid cold clones of lambdas -- succintly
|
||||
for (auto const& e : std::vector<std::pair<std::string_view, void (*)(Core::System&)>>{
|
||||
{"sm", &SM::LoopProcess},
|
||||
{"account", &Account::LoopProcess},
|
||||
{"am", &AM::LoopProcess},
|
||||
{"aoc", &AOC::LoopProcess},
|
||||
{"apm", &APM::LoopProcess},
|
||||
{"bcat", &BCAT::LoopProcess},
|
||||
{"bpc", &BPC::LoopProcess},
|
||||
{"btdrv", &BtDrv::LoopProcess},
|
||||
{"btm", &BTM::LoopProcess},
|
||||
{"capsrv", &Capture::LoopProcess},
|
||||
{"erpt", &ERPT::LoopProcess},
|
||||
{"es", &ES::LoopProcess},
|
||||
{"eupld", &EUPLD::LoopProcess},
|
||||
{"fatal", &Fatal::LoopProcess},
|
||||
{"fgm", &FGM::LoopProcess},
|
||||
{"friends", &Friend::LoopProcess},
|
||||
{"settings", &Set::LoopProcess},
|
||||
{"psc", &PSC::LoopProcess},
|
||||
{"glue", &Glue::LoopProcess},
|
||||
{"grc", &GRC::LoopProcess},
|
||||
{"hid", &HID::LoopProcess},
|
||||
{"lbl", &LBL::LoopProcess},
|
||||
{"LogManager.Prod", &LM::LoopProcess},
|
||||
{"mig", &Migration::LoopProcess},
|
||||
{"mii", &Mii::LoopProcess},
|
||||
{"mm", &MM::LoopProcess},
|
||||
{"mnpp", &MNPP::LoopProcess},
|
||||
{"nvnflinger", &Nvnflinger::LoopProcess},
|
||||
{"NCM", &NCM::LoopProcess},
|
||||
{"nfc", &NFC::LoopProcess},
|
||||
{"nfp", &NFP::LoopProcess},
|
||||
{"ngc", &NGC::LoopProcess},
|
||||
{"nifm", &NIFM::LoopProcess},
|
||||
{"nim", &NIM::LoopProcess},
|
||||
{"npns", &NPNS::LoopProcess},
|
||||
{"ns", &NS::LoopProcess},
|
||||
{"olsc", &OLSC::LoopProcess},
|
||||
{"omm", &OMM::LoopProcess},
|
||||
{"pcie", &PCIe::LoopProcess},
|
||||
{"pctl", &PCTL::LoopProcess},
|
||||
{"pcv", &PCV::LoopProcess},
|
||||
{"prepo", &PlayReport::LoopProcess},
|
||||
{"ProcessManager", &PM::LoopProcess},
|
||||
{"ptm", &PTM::LoopProcess},
|
||||
{"ro", &RO::LoopProcess},
|
||||
{"spl", &SPL::LoopProcess},
|
||||
{"ssl", &SSL::LoopProcess},
|
||||
{"usb", &USB::LoopProcess}
|
||||
})
|
||||
kernel.RunOnGuestCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); });
|
||||
}
|
||||
|
||||
Services::~Services() = default;
|
||||
|
||||
} // namespace Service
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -8,15 +11,13 @@
|
||||
|
||||
namespace Service {
|
||||
|
||||
/**
|
||||
* The purpose of this class is to own any objects that need to be shared across the other service
|
||||
* implementations. Will be torn down when the global system instance is shutdown.
|
||||
*/
|
||||
/// @brief The purpose of this class is to own any objects that need to be shared across the other service
|
||||
/// implementations. Will be torn down when the global system instance is shutdown.
|
||||
class Services final {
|
||||
public:
|
||||
explicit Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
|
||||
std::stop_token token);
|
||||
~Services();
|
||||
~Services() = default;
|
||||
};
|
||||
|
||||
} // namespace Service
|
||||
|
||||
@@ -137,8 +137,6 @@ endif()
|
||||
|
||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
||||
find_package(xbyak 7 CONFIG)
|
||||
find_package(zycore REQUIRED)
|
||||
find_package(zydis 4 REQUIRED)
|
||||
endif()
|
||||
|
||||
if (DYNARMIC_USE_LLVM)
|
||||
|
||||
@@ -20,7 +20,6 @@ if (NOT @BUILD_SHARED_LIBS@)
|
||||
|
||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
||||
find_dependency(xbyak 7)
|
||||
find_dependency(Zydis 4)
|
||||
endif()
|
||||
|
||||
if (@DYNARMIC_USE_LLVM@)
|
||||
|
||||
@@ -389,30 +389,3 @@ THE POSSIBILITY OF SUCH DAMAGE.
|
||||
損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害について、
|
||||
一切責任を負わないものとします。
|
||||
```
|
||||
|
||||
### zydis
|
||||
|
||||
```
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2020 Florian Bernd
|
||||
Copyright (c) 2014-2020 Joel Höner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
```
|
||||
|
||||
14
src/dynarmic/externals/CMakeLists.txt
vendored
@@ -32,17 +32,3 @@ AddJsonPackage(
|
||||
NAME mcl
|
||||
BUNDLED_PACKAGE ${DYNARMIC_USE_BUNDLED_EXTERNALS}
|
||||
)
|
||||
|
||||
# TODO(crueter): maybe it's just Gentoo but zydis system package really sucks
|
||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
||||
set(CMAKE_DISABLE_FIND_PACKAGE_Doxygen ON)
|
||||
AddJsonPackage(
|
||||
NAME zycore
|
||||
BUNDLED_PACKAGE ${DYNARMIC_USE_BUNDLED_EXTERNALS}
|
||||
)
|
||||
|
||||
AddJsonPackage(
|
||||
NAME zydis
|
||||
BUNDLED_PACKAGE ${DYNARMIC_USE_BUNDLED_EXTERNALS}
|
||||
)
|
||||
endif()
|
||||
|
||||
19
src/dynarmic/externals/cpmfile.json
vendored
@@ -17,24 +17,5 @@
|
||||
"patches": [
|
||||
"0001-assert-macro.patch"
|
||||
]
|
||||
},
|
||||
"zycore": {
|
||||
"package": "zycore",
|
||||
"repo": "zyantific/zycore-c",
|
||||
"sha": "75a36c45ae",
|
||||
"hash": "e1cf9bdd3163b6429eba94d0f9f82e343de33b77a838748f598c719913c9f91c502b818e37b716e174b55a3a26cdf39d665c4b50a548255973ac287c0e554fb6"
|
||||
},
|
||||
"zydis": {
|
||||
"package": "zydis",
|
||||
"version": "4",
|
||||
"repo": "zyantific/zydis",
|
||||
"sha": "c2d2bab025",
|
||||
"hash": "3808773593536f78d3ddaf4cf712101d3fb6d981c6cc55555ad686a9adbe3397a727f62f561e8d8755bdcd88a763777da30281cc2924fc160b0386c3f99f5bd9",
|
||||
"options": [
|
||||
"ZYDIS_BUILD_TOOLS OFF",
|
||||
"ZYDIS_BUILD_EXAMPLES OFF",
|
||||
"ZYDIS_BUILD_DOXYGEN OFF",
|
||||
"ZYAN_SYSTEM_ZYCORE ON"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,14 +58,11 @@ add_library(dynarmic STATIC
|
||||
common/lut_from_list.h
|
||||
common/math_util.cpp
|
||||
common/math_util.h
|
||||
common/memory_pool.cpp
|
||||
common/memory_pool.h
|
||||
common/safe_ops.h
|
||||
common/spin_lock.h
|
||||
common/string_util.h
|
||||
common/u128.cpp
|
||||
common/u128.h
|
||||
common/variant_util.h
|
||||
frontend/A32/a32_types.cpp
|
||||
frontend/A32/a32_types.h
|
||||
frontend/A64/a64_types.cpp
|
||||
@@ -80,7 +77,6 @@ add_library(dynarmic STATIC
|
||||
ir/basic_block.cpp
|
||||
ir/basic_block.h
|
||||
ir/cond.h
|
||||
ir/ir_emitter.cpp
|
||||
ir/ir_emitter.h
|
||||
ir/location_descriptor.cpp
|
||||
ir/location_descriptor.h
|
||||
@@ -148,11 +144,7 @@ if ("x86_64" IN_LIST ARCHITECTURE)
|
||||
target_compile_definitions(dynarmic PRIVATE XBYAK_STRICT_CHECK_MEM_REG_SIZE=0)
|
||||
|
||||
target_compile_definitions(dynarmic PRIVATE XBYAK_OLD_DISP_CHECK=1)
|
||||
target_link_libraries(dynarmic
|
||||
PRIVATE
|
||||
xbyak::xbyak
|
||||
Zydis::Zydis
|
||||
)
|
||||
target_link_libraries(dynarmic PRIVATE xbyak::xbyak)
|
||||
|
||||
target_architecture_specific_sources(dynarmic "x86_64"
|
||||
backend/x64/abi.cpp
|
||||
@@ -196,8 +188,6 @@ if ("x86_64" IN_LIST ARCHITECTURE)
|
||||
backend/x64/verbose_debugging_output.h
|
||||
common/spin_lock_x64.cpp
|
||||
common/spin_lock_x64.h
|
||||
common/x64_disassemble.cpp
|
||||
common/x64_disassemble.h
|
||||
# A32
|
||||
backend/x64/a32_emit_x64.cpp
|
||||
backend/x64/a32_emit_x64.h
|
||||
|
||||
@@ -93,9 +93,9 @@ static void* EmitExclusiveReadCallTrampoline(oaknut::CodeGenerator& code, const
|
||||
|
||||
code.align(8);
|
||||
code.l(l_this);
|
||||
code.dx(mcl::bit_cast<u64>(&conf));
|
||||
code.dx(std::bit_cast<u64>(&conf));
|
||||
code.l(l_addr);
|
||||
code.dx(mcl::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
code.dx(std::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
|
||||
return target;
|
||||
}
|
||||
@@ -151,9 +151,9 @@ static void* EmitExclusiveWriteCallTrampoline(oaknut::CodeGenerator& code, const
|
||||
|
||||
code.align(8);
|
||||
code.l(l_this);
|
||||
code.dx(mcl::bit_cast<u64>(&conf));
|
||||
code.dx(std::bit_cast<u64>(&conf));
|
||||
code.l(l_addr);
|
||||
code.dx(mcl::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
code.dx(std::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
|
||||
return target;
|
||||
}
|
||||
@@ -219,7 +219,7 @@ void A32AddressSpace::EmitPrelude() {
|
||||
code.MOV(Xstate, X1);
|
||||
code.MOV(Xhalt, X2);
|
||||
if (conf.page_table) {
|
||||
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
||||
code.MOV(Xpagetable, std::bit_cast<u64>(conf.page_table));
|
||||
}
|
||||
if (conf.fastmem_pointer) {
|
||||
code.MOV(Xfastmem, *conf.fastmem_pointer);
|
||||
@@ -258,7 +258,7 @@ void A32AddressSpace::EmitPrelude() {
|
||||
code.MOV(Xstate, X1);
|
||||
code.MOV(Xhalt, X2);
|
||||
if (conf.page_table) {
|
||||
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
||||
code.MOV(Xpagetable, std::bit_cast<u64>(conf.page_table));
|
||||
}
|
||||
if (conf.fastmem_pointer) {
|
||||
code.MOV(Xfastmem, *conf.fastmem_pointer);
|
||||
@@ -317,9 +317,9 @@ void A32AddressSpace::EmitPrelude() {
|
||||
|
||||
code.align(8);
|
||||
code.l(l_this);
|
||||
code.dx(mcl::bit_cast<u64>(this));
|
||||
code.dx(std::bit_cast<u64>(this));
|
||||
code.l(l_addr);
|
||||
code.dx(mcl::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
code.dx(std::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
}
|
||||
|
||||
prelude_info.return_from_run_code = code.xptr<void*>();
|
||||
@@ -347,7 +347,7 @@ void A32AddressSpace::EmitPrelude() {
|
||||
|
||||
code.align(8);
|
||||
code.l(l_return_to_dispatcher);
|
||||
code.dx(mcl::bit_cast<u64>(prelude_info.return_to_dispatcher));
|
||||
code.dx(std::bit_cast<u64>(prelude_info.return_to_dispatcher));
|
||||
|
||||
prelude_info.end_of_prelude = code.offset();
|
||||
|
||||
@@ -369,7 +369,7 @@ EmitConfig A32AddressSpace::GetEmitConfig() {
|
||||
|
||||
.check_halt_on_memory_access = conf.check_halt_on_memory_access,
|
||||
|
||||
.page_table_pointer = mcl::bit_cast<u64>(conf.page_table),
|
||||
.page_table_pointer = std::bit_cast<u64>(conf.page_table),
|
||||
.page_table_address_space_bits = 32,
|
||||
.page_table_pointer_mask_bits = conf.page_table_pointer_mask_bits,
|
||||
.silently_mirror_page_table = true,
|
||||
|
||||
@@ -125,10 +125,6 @@ struct Jit::Impl final {
|
||||
current_state.exclusive_state = false;
|
||||
}
|
||||
|
||||
void DumpDisassembly() const {
|
||||
ASSERT_FALSE("Unimplemented");
|
||||
}
|
||||
|
||||
private:
|
||||
void PerformRequestedCacheInvalidation(HaltReason hr) {
|
||||
if (Has(hr, HaltReason::CacheInvalidation)) {
|
||||
@@ -235,8 +231,4 @@ void Jit::ClearExclusiveState() {
|
||||
impl->ClearExclusiveState();
|
||||
}
|
||||
|
||||
void Jit::DumpDisassembly() const {
|
||||
impl->DumpDisassembly();
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
||||
|
||||
@@ -92,9 +92,9 @@ static void* EmitExclusiveReadCallTrampoline(oaknut::CodeGenerator& code, const
|
||||
|
||||
code.align(8);
|
||||
code.l(l_this);
|
||||
code.dx(mcl::bit_cast<u64>(&conf));
|
||||
code.dx(std::bit_cast<u64>(&conf));
|
||||
code.l(l_addr);
|
||||
code.dx(mcl::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
code.dx(std::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
|
||||
return target;
|
||||
}
|
||||
@@ -150,9 +150,9 @@ static void* EmitExclusiveWriteCallTrampoline(oaknut::CodeGenerator& code, const
|
||||
|
||||
code.align(8);
|
||||
code.l(l_this);
|
||||
code.dx(mcl::bit_cast<u64>(&conf));
|
||||
code.dx(std::bit_cast<u64>(&conf));
|
||||
code.l(l_addr);
|
||||
code.dx(mcl::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
code.dx(std::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
|
||||
return target;
|
||||
}
|
||||
@@ -235,9 +235,9 @@ static void* EmitExclusiveRead128CallTrampoline(oaknut::CodeGenerator& code, con
|
||||
|
||||
code.align(8);
|
||||
code.l(l_this);
|
||||
code.dx(mcl::bit_cast<u64>(&conf));
|
||||
code.dx(std::bit_cast<u64>(&conf));
|
||||
code.l(l_addr);
|
||||
code.dx(mcl::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
code.dx(std::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
|
||||
return target;
|
||||
}
|
||||
@@ -317,9 +317,9 @@ static void* EmitExclusiveWrite128CallTrampoline(oaknut::CodeGenerator& code, co
|
||||
|
||||
code.align(8);
|
||||
code.l(l_this);
|
||||
code.dx(mcl::bit_cast<u64>(&conf));
|
||||
code.dx(std::bit_cast<u64>(&conf));
|
||||
code.l(l_addr);
|
||||
code.dx(mcl::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
code.dx(std::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
|
||||
return target;
|
||||
}
|
||||
@@ -396,7 +396,7 @@ void A64AddressSpace::EmitPrelude() {
|
||||
code.MOV(Xstate, X1);
|
||||
code.MOV(Xhalt, X2);
|
||||
if (conf.page_table) {
|
||||
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
||||
code.MOV(Xpagetable, std::bit_cast<u64>(conf.page_table));
|
||||
}
|
||||
if (conf.fastmem_pointer) {
|
||||
code.MOV(Xfastmem, *conf.fastmem_pointer);
|
||||
@@ -434,7 +434,7 @@ void A64AddressSpace::EmitPrelude() {
|
||||
code.MOV(Xstate, X1);
|
||||
code.MOV(Xhalt, X2);
|
||||
if (conf.page_table) {
|
||||
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
||||
code.MOV(Xpagetable, std::bit_cast<u64>(conf.page_table));
|
||||
}
|
||||
if (conf.fastmem_pointer) {
|
||||
code.MOV(Xfastmem, *conf.fastmem_pointer);
|
||||
@@ -492,9 +492,9 @@ void A64AddressSpace::EmitPrelude() {
|
||||
|
||||
code.align(8);
|
||||
code.l(l_this);
|
||||
code.dx(mcl::bit_cast<u64>(this));
|
||||
code.dx(std::bit_cast<u64>(this));
|
||||
code.l(l_addr);
|
||||
code.dx(mcl::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
code.dx(std::bit_cast<u64>(Common::FptrCast(fn)));
|
||||
}
|
||||
|
||||
prelude_info.return_from_run_code = code.xptr<void*>();
|
||||
@@ -522,7 +522,7 @@ void A64AddressSpace::EmitPrelude() {
|
||||
|
||||
code.align(8);
|
||||
code.l(l_return_to_dispatcher);
|
||||
code.dx(mcl::bit_cast<u64>(prelude_info.return_to_dispatcher));
|
||||
code.dx(std::bit_cast<u64>(prelude_info.return_to_dispatcher));
|
||||
|
||||
prelude_info.end_of_prelude = code.offset();
|
||||
|
||||
@@ -544,7 +544,7 @@ EmitConfig A64AddressSpace::GetEmitConfig() {
|
||||
|
||||
.check_halt_on_memory_access = conf.check_halt_on_memory_access,
|
||||
|
||||
.page_table_pointer = mcl::bit_cast<u64>(conf.page_table),
|
||||
.page_table_pointer = std::bit_cast<u64>(conf.page_table),
|
||||
.page_table_address_space_bits = conf.page_table_address_space_bits,
|
||||
.page_table_pointer_mask_bits = conf.page_table_pointer_mask_bits,
|
||||
.silently_mirror_page_table = conf.silently_mirror_page_table,
|
||||
|
||||
@@ -151,12 +151,8 @@ struct Jit::Impl final {
|
||||
return is_executing;
|
||||
}
|
||||
|
||||
void DumpDisassembly() const {
|
||||
current_address_space.DumpDisassembly();
|
||||
}
|
||||
|
||||
std::vector<std::string> Disassemble() const {
|
||||
ASSERT_FALSE("Unimplemented");
|
||||
std::string Disassemble() const {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -315,11 +311,7 @@ bool Jit::IsExecuting() const {
|
||||
return impl->IsExecuting();
|
||||
}
|
||||
|
||||
void Jit::DumpDisassembly() const {
|
||||
impl->DumpDisassembly();
|
||||
}
|
||||
|
||||
std::vector<std::string> Jit::Disassemble() const {
|
||||
std::string Jit::Disassemble() const {
|
||||
return impl->Disassemble();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2022 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
@@ -5,7 +8,7 @@
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include <bit>
|
||||
|
||||
#include "dynarmic/backend/arm64/a64_address_space.h"
|
||||
#include "dynarmic/backend/arm64/a64_jitstate.h"
|
||||
@@ -97,12 +100,6 @@ void AddressSpace::ClearCache() {
|
||||
code.set_offset(prelude_info.end_of_prelude);
|
||||
}
|
||||
|
||||
void AddressSpace::DumpDisassembly() const {
|
||||
for (u32* ptr = mem.ptr(); ptr < code.xptr<u32*>(); ptr++) {
|
||||
std::printf("%s", Common::DisassembleAArch64(*ptr, mcl::bit_cast<u64>(ptr)).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
size_t AddressSpace::GetRemainingSize() {
|
||||
return code_cache_size - static_cast<size_t>(code.offset());
|
||||
}
|
||||
@@ -316,7 +313,7 @@ void AddressSpace::RelinkForDescriptor(IR::LocationDescriptor target_descriptor,
|
||||
|
||||
FakeCall AddressSpace::FastmemCallback(u64 host_pc) {
|
||||
{
|
||||
const auto host_ptr = mcl::bit_cast<CodePtr>(host_pc);
|
||||
const auto host_ptr = std::bit_cast<CodePtr>(host_pc);
|
||||
|
||||
const auto entry_point = ReverseGetEntryPoint(host_ptr);
|
||||
if (!entry_point) {
|
||||
|
||||
@@ -44,9 +44,6 @@ public:
|
||||
void InvalidateBasicBlocks(const ankerl::unordered_dense::set<IR::LocationDescriptor>& descriptors);
|
||||
|
||||
void ClearCache();
|
||||
|
||||
void DumpDisassembly() const;
|
||||
|
||||
protected:
|
||||
virtual EmitConfig GetEmitConfig() = 0;
|
||||
virtual void RegisterNewBasicBlock(const IR::Block& block, const EmittedBlockInfo& block_info) = 0;
|
||||
|
||||
@@ -8,12 +8,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include <bit>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <mcl/type_traits/function_info.hpp>
|
||||
|
||||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
||||
namespace impl {
|
||||
template<typename T, typename P> inline T bit_cast_pointee(const P source_ptr) noexcept {
|
||||
std::aligned_storage_t<sizeof(T), alignof(T)> dest;
|
||||
std::memcpy(&dest, std::bit_cast<void*>(source_ptr), sizeof(T));
|
||||
return reinterpret_cast<T&>(dest);
|
||||
}
|
||||
};
|
||||
|
||||
struct DevirtualizedCall {
|
||||
u64 fn_ptr;
|
||||
u64 this_ptr;
|
||||
@@ -23,7 +31,7 @@ struct DevirtualizedCall {
|
||||
template<auto mfp>
|
||||
DevirtualizedCall DevirtualizeWindows(mcl::class_type<decltype(mfp)>* this_) {
|
||||
static_assert(sizeof(mfp) == 8);
|
||||
return DevirtualizedCall{mcl::bit_cast<u64>(mfp), reinterpret_cast<u64>(this_)};
|
||||
return DevirtualizedCall{std::bit_cast<u64>(mfp), reinterpret_cast<u64>(this_)};
|
||||
}
|
||||
|
||||
// https://github.com/ARM-software/abi-aa/blob/main/cppabi64/cppabi64.rst#representation-of-pointer-to-member-function
|
||||
@@ -34,16 +42,16 @@ DevirtualizedCall DevirtualizeDefault(mcl::class_type<decltype(mfp)>* this_) {
|
||||
u64 ptr;
|
||||
// LSB is discriminator for if function is virtual. Other bits are this adjustment.
|
||||
u64 adj;
|
||||
} mfp_struct = mcl::bit_cast<MemberFunctionPointer>(mfp);
|
||||
} mfp_struct = std::bit_cast<MemberFunctionPointer>(mfp);
|
||||
|
||||
static_assert(sizeof(MemberFunctionPointer) == 16);
|
||||
static_assert(sizeof(MemberFunctionPointer) == sizeof(mfp));
|
||||
|
||||
u64 fn_ptr = mfp_struct.ptr;
|
||||
u64 this_ptr = mcl::bit_cast<u64>(this_) + (mfp_struct.adj >> 1);
|
||||
u64 this_ptr = std::bit_cast<u64>(this_) + (mfp_struct.adj >> 1);
|
||||
if (mfp_struct.adj & 1) {
|
||||
u64 vtable = mcl::bit_cast_pointee<u64>(this_ptr);
|
||||
fn_ptr = mcl::bit_cast_pointee<u64>(vtable + fn_ptr);
|
||||
u64 vtable = impl::bit_cast_pointee<u64>(this_ptr);
|
||||
fn_ptr = impl::bit_cast_pointee<u64>(vtable + fn_ptr);
|
||||
}
|
||||
return DevirtualizedCall{fn_ptr, this_ptr};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2022 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include <bit>
|
||||
#include <oaknut/oaknut.hpp>
|
||||
|
||||
#include "dynarmic/backend/arm64/a64_jitstate.h"
|
||||
@@ -495,7 +498,7 @@ template<>
|
||||
void EmitIR<IR::Opcode::A64GetTPIDR>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto Xvalue = ctx.reg_alloc.WriteX(inst);
|
||||
RegAlloc::Realize(Xvalue);
|
||||
code.MOV(Xscratch0, mcl::bit_cast<u64>(ctx.conf.tpidr_el0));
|
||||
code.MOV(Xscratch0, std::bit_cast<u64>(ctx.conf.tpidr_el0));
|
||||
code.LDR(Xvalue, Xscratch0);
|
||||
}
|
||||
|
||||
@@ -503,7 +506,7 @@ template<>
|
||||
void EmitIR<IR::Opcode::A64GetTPIDRRO>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto Xvalue = ctx.reg_alloc.WriteX(inst);
|
||||
RegAlloc::Realize(Xvalue);
|
||||
code.MOV(Xscratch0, mcl::bit_cast<u64>(ctx.conf.tpidrro_el0));
|
||||
code.MOV(Xscratch0, std::bit_cast<u64>(ctx.conf.tpidrro_el0));
|
||||
code.LDR(Xvalue, Xscratch0);
|
||||
}
|
||||
|
||||
@@ -512,7 +515,7 @@ void EmitIR<IR::Opcode::A64SetTPIDR>(oaknut::CodeGenerator& code, EmitContext& c
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Xvalue = ctx.reg_alloc.ReadX(args[0]);
|
||||
RegAlloc::Realize(Xvalue);
|
||||
code.MOV(Xscratch0, mcl::bit_cast<u64>(ctx.conf.tpidr_el0));
|
||||
code.MOV(Xscratch0, std::bit_cast<u64>(ctx.conf.tpidr_el0));
|
||||
code.STR(Xvalue, Xscratch0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2022 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
@@ -8,7 +11,7 @@
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include <bit>
|
||||
#include <oaknut/oaknut.hpp>
|
||||
|
||||
#include "dynarmic/backend/arm64/abi.h"
|
||||
@@ -548,7 +551,7 @@ void FastmemEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::In
|
||||
FastmemPatchInfo{
|
||||
.marker = marker,
|
||||
.fc = FakeCall{
|
||||
.call_pc = mcl::bit_cast<u64>(code.xptr<void*>()),
|
||||
.call_pc = std::bit_cast<u64>(code.xptr<void*>()),
|
||||
},
|
||||
.recompile = ctx.conf.recompile_on_fastmem_failure,
|
||||
});
|
||||
@@ -598,7 +601,7 @@ void FastmemEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::I
|
||||
FastmemPatchInfo{
|
||||
.marker = marker,
|
||||
.fc = FakeCall{
|
||||
.call_pc = mcl::bit_cast<u64>(code.xptr<void*>()),
|
||||
.call_pc = std::bit_cast<u64>(code.xptr<void*>()),
|
||||
},
|
||||
.recompile = ctx.conf.recompile_on_fastmem_failure,
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include <bit>
|
||||
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||
#include <mcl/mp/typelist/cartesian_product.hpp>
|
||||
#include <mcl/mp/typelist/get.hpp>
|
||||
@@ -271,7 +271,7 @@ static void EmitTwoOpFallbackWithoutRegAlloc(oaknut::CodeGenerator& code, EmitCo
|
||||
|
||||
ABI_PushRegisters(code, ABI_CALLER_SAVE & ~(1ull << Qresult.index()), stack_size);
|
||||
|
||||
code.MOV(Xscratch0, mcl::bit_cast<u64>(fn));
|
||||
code.MOV(Xscratch0, std::bit_cast<u64>(fn));
|
||||
code.ADD(X0, SP, 0 * 16);
|
||||
code.ADD(X1, SP, 1 * 16);
|
||||
code.MOV(X2, fpcr);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <mcl/bit/bit_field.hpp>
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include <bit>
|
||||
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
|
||||
@@ -246,7 +246,7 @@ void RegAlloc::AssertNoMoreUses() const {
|
||||
}
|
||||
|
||||
void RegAlloc::EmitVerboseDebuggingOutput() {
|
||||
code.MOV(X19, mcl::bit_cast<u64>(&PrintVerboseDebuggingOutputLine)); // Non-volatile register
|
||||
code.MOV(X19, std::bit_cast<u64>(&PrintVerboseDebuggingOutputLine)); // Non-volatile register
|
||||
|
||||
const auto do_location = [&](HostLocInfo& info, HostLocType type, size_t index) {
|
||||
using namespace oaknut::util;
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
#include <mcl/macro/architecture.hpp>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
|
||||
#if defined(MCL_ARCHITECTURE_X86_64)
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
class BlockOfCode;
|
||||
} // namespace Dynarmic::Backend::X64
|
||||
#elif defined(MCL_ARCHITECTURE_ARM64)
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
namespace oaknut {
|
||||
class CodeBlock;
|
||||
} // namespace oaknut
|
||||
#elif defined(MCL_ARCHITECTURE_RISCV)
|
||||
#elif defined(ARCHITECTURE_riscv64)
|
||||
namespace Dynarmic::Backend::RV64 {
|
||||
class CodeBlock;
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
@@ -33,16 +33,16 @@ class CodeBlock;
|
||||
|
||||
namespace Dynarmic::Backend {
|
||||
|
||||
#if defined(MCL_ARCHITECTURE_X86_64)
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
struct FakeCall {
|
||||
u64 call_rip;
|
||||
u64 ret_rip;
|
||||
};
|
||||
#elif defined(MCL_ARCHITECTURE_ARM64)
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
struct FakeCall {
|
||||
u64 call_pc;
|
||||
};
|
||||
#elif defined(MCL_ARCHITECTURE_RISCV)
|
||||
#elif defined(ARCHITECTURE_riscv64)
|
||||
struct FakeCall {
|
||||
};
|
||||
#else
|
||||
@@ -54,11 +54,11 @@ public:
|
||||
ExceptionHandler();
|
||||
~ExceptionHandler();
|
||||
|
||||
#if defined(MCL_ARCHITECTURE_X86_64)
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
void Register(X64::BlockOfCode& code);
|
||||
#elif defined(MCL_ARCHITECTURE_ARM64)
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
void Register(oaknut::CodeBlock& mem, std::size_t mem_size);
|
||||
#elif defined(MCL_ARCHITECTURE_RISCV)
|
||||
#elif defined(ARCHITECTURE_riscv64)
|
||||
void Register(RV64::CodeBlock& mem, std::size_t mem_size);
|
||||
#else
|
||||
# error "Invalid architecture"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include <bit>
|
||||
#include <mcl/macro/architecture.hpp>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
|
||||
@@ -146,7 +146,7 @@ kern_return_t MachHandler::HandleRequest(x86_thread_state64_t* ts) {
|
||||
FakeCall fc = iter->cb(ts->__rip);
|
||||
|
||||
ts->__rsp -= sizeof(u64);
|
||||
*mcl::bit_cast<u64*>(ts->__rsp) = fc.ret_rip;
|
||||
*std::bit_cast<u64*>(ts->__rsp) = fc.ret_rip;
|
||||
ts->__rip = fc.call_rip;
|
||||
|
||||
return KERN_SUCCESS;
|
||||
@@ -271,13 +271,13 @@ ExceptionHandler::~ExceptionHandler() = default;
|
||||
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
void ExceptionHandler::Register(X64::BlockOfCode& code) {
|
||||
const u64 code_begin = mcl::bit_cast<u64>(code.getCode());
|
||||
const u64 code_begin = std::bit_cast<u64>(code.getCode());
|
||||
const u64 code_end = code_begin + code.GetTotalCodeSize();
|
||||
impl = std::make_unique<Impl>(code_begin, code_end);
|
||||
}
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) {
|
||||
const u64 code_begin = mcl::bit_cast<u64>(mem.ptr());
|
||||
const u64 code_begin = std::bit_cast<u64>(mem.ptr());
|
||||
const u64 code_end = code_begin + size;
|
||||
impl = std::make_unique<Impl>(code_begin, code_end);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#else
|
||||
# error "Invalid architecture"
|
||||
#endif
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include <bit>
|
||||
|
||||
namespace Dynarmic::Backend {
|
||||
|
||||
@@ -122,7 +122,7 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
|
||||
if (auto const iter = sig_handler->FindCodeBlockInfo(CTX_RIP); iter != sig_handler->code_block_infos.end()) {
|
||||
FakeCall fc = iter->second.cb(CTX_RIP);
|
||||
CTX_RSP -= sizeof(u64);
|
||||
*mcl::bit_cast<u64*>(CTX_RSP) = fc.ret_rip;
|
||||
*std::bit_cast<u64*>(CTX_RSP) = fc.ret_rip;
|
||||
CTX_RIP = fc.call_rip;
|
||||
return;
|
||||
}
|
||||
@@ -189,15 +189,15 @@ ExceptionHandler::~ExceptionHandler() = default;
|
||||
|
||||
#if defined(MCL_ARCHITECTURE_X86_64)
|
||||
void ExceptionHandler::Register(X64::BlockOfCode& code) {
|
||||
impl = std::make_unique<Impl>(mcl::bit_cast<u64>(code.getCode()), code.GetTotalCodeSize());
|
||||
impl = std::make_unique<Impl>(std::bit_cast<u64>(code.getCode()), code.GetTotalCodeSize());
|
||||
}
|
||||
#elif defined(MCL_ARCHITECTURE_ARM64)
|
||||
void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) {
|
||||
impl = std::make_unique<Impl>(mcl::bit_cast<u64>(mem.ptr()), size);
|
||||
impl = std::make_unique<Impl>(std::bit_cast<u64>(mem.ptr()), size);
|
||||
}
|
||||
#elif defined(MCL_ARCHITECTURE_RISCV)
|
||||
void ExceptionHandler::Register(RV64::CodeBlock& mem, std::size_t size) {
|
||||
impl = std::make_unique<Impl>(mcl::bit_cast<u64>(mem.ptr<u64>()), size);
|
||||
impl = std::make_unique<Impl>(std::bit_cast<u64>(mem.ptr<u64>()), size);
|
||||
}
|
||||
#else
|
||||
# error "Invalid architecture"
|
||||
|
||||
@@ -28,19 +28,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf)
|
||||
|
||||
IR::Block A32AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const {
|
||||
IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||
|
||||
Optimization::PolyfillPass(ir_block, {});
|
||||
if (conf.HasOptimization(OptimizationFlag::GetSetElimination)) {
|
||||
Optimization::A32GetSetElimination(ir_block, {.convert_nzc_to_nz = true});
|
||||
Optimization::DeadCodeElimination(ir_block);
|
||||
}
|
||||
if (conf.HasOptimization(OptimizationFlag::ConstProp)) {
|
||||
Optimization::A32ConstantMemoryReads(ir_block, conf.callbacks);
|
||||
Optimization::ConstantPropagation(ir_block);
|
||||
Optimization::DeadCodeElimination(ir_block);
|
||||
}
|
||||
Optimization::VerificationPass(ir_block);
|
||||
|
||||
Optimization::Optimize(ir_block, conf, {});
|
||||
return ir_block;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,10 +119,6 @@ struct Jit::Impl final {
|
||||
current_state.exclusive_state = false;
|
||||
}
|
||||
|
||||
void DumpDisassembly() const {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
private:
|
||||
void RequestCacheInvalidation() {
|
||||
// ASSERT_FALSE("Unimplemented");
|
||||
@@ -213,8 +209,4 @@ void Jit::ClearExclusiveState() {
|
||||
impl->ClearExclusiveState();
|
||||
}
|
||||
|
||||
void Jit::DumpDisassembly() const {
|
||||
impl->DumpDisassembly();
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "dynarmic/backend/x64/nzcv_util.h"
|
||||
#include "dynarmic/backend/x64/perf_map.h"
|
||||
#include "dynarmic/backend/x64/stack_layout.h"
|
||||
#include "dynarmic/common/variant_util.h"
|
||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||
#include "dynarmic/frontend/A32/a32_types.h"
|
||||
#include "dynarmic/interface/A32/coprocessor.h"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2022 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
@@ -19,7 +22,6 @@
|
||||
#include "dynarmic/backend/x64/emit_x64_memory.h"
|
||||
#include "dynarmic/backend/x64/exclusive_monitor_friend.h"
|
||||
#include "dynarmic/backend/x64/perf_map.h"
|
||||
#include "dynarmic/common/x64_disassemble.h"
|
||||
#include "dynarmic/interface/exclusive_monitor.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include <bit>
|
||||
#include <mcl/scope_exit.hpp>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "dynarmic/common/llvm_disassemble.h"
|
||||
|
||||
#include "dynarmic/backend/x64/a32_emit_x64.h"
|
||||
#include "dynarmic/backend/x64/a32_jitstate.h"
|
||||
@@ -24,7 +25,6 @@
|
||||
#include "dynarmic/backend/x64/devirtualize.h"
|
||||
#include "dynarmic/backend/x64/jitstate_info.h"
|
||||
#include "dynarmic/common/atomic.h"
|
||||
#include "dynarmic/common/x64_disassemble.h"
|
||||
#include "dynarmic/frontend/A32/translate/a32_translate.h"
|
||||
#include "dynarmic/interface/A32/a32.h"
|
||||
#include "dynarmic/ir/basic_block.h"
|
||||
@@ -47,7 +47,7 @@ static RunCodeCallbacks GenRunCodeCallbacks(A32::UserCallbacks* cb, CodePtr (*Lo
|
||||
static std::function<void(BlockOfCode&)> GenRCP(const A32::UserConfig& conf) {
|
||||
return [conf](BlockOfCode& code) {
|
||||
if (conf.page_table) {
|
||||
code.mov(code.r14, mcl::bit_cast<u64>(conf.page_table));
|
||||
code.mov(code.r14, std::bit_cast<u64>(conf.page_table));
|
||||
}
|
||||
if (conf.fastmem_pointer) {
|
||||
code.mov(code.r13, *conf.fastmem_pointer);
|
||||
@@ -176,14 +176,10 @@ struct Jit::Impl {
|
||||
return jit_state.SetFpscr(value);
|
||||
}
|
||||
|
||||
void DumpDisassembly() const {
|
||||
std::string Disassemble() const {
|
||||
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
|
||||
Common::DumpDisassembledX64(block_of_code.GetCodeBegin(), size);
|
||||
}
|
||||
|
||||
std::vector<std::string> Disassemble() const {
|
||||
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
|
||||
return Common::DisassembleX64(block_of_code.GetCodeBegin(), size);
|
||||
auto const* p = reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
|
||||
return Common::DisassembleX64(p, p + size);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -327,8 +323,4 @@ void Jit::ClearExclusiveState() {
|
||||
impl->ClearExclusiveState();
|
||||
}
|
||||
|
||||
void Jit::DumpDisassembly() const {
|
||||
impl->DumpDisassembly();
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
||||
|
||||
@@ -122,9 +122,9 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) noexcept {
|
||||
auto const opcode = inst.GetOpcode();
|
||||
// Call the relevant Emit* member function.
|
||||
switch (opcode) {
|
||||
#define OPCODE(name, type, ...) [[likely]] case IR::Opcode::name: goto opcode_branch;
|
||||
#define OPCODE(name, type, ...) case IR::Opcode::name: goto opcode_branch;
|
||||
#define A32OPC(name, type, ...)
|
||||
#define A64OPC(name, type, ...) [[likely]] case IR::Opcode::A64##name: goto a64_branch;
|
||||
#define A64OPC(name, type, ...) case IR::Opcode::A64##name: goto a64_branch;
|
||||
#include "dynarmic/ir/opcodes.inc"
|
||||
#undef OPCODE
|
||||
#undef A32OPC
|
||||
@@ -764,7 +764,7 @@ void A64EmitX64::EmitPatchMovRcx(CodePtr target_code_ptr) {
|
||||
target_code_ptr = code.GetReturnFromRunCodeAddress();
|
||||
}
|
||||
const CodePtr patch_location = code.getCurr();
|
||||
code.mov(code.rcx, reinterpret_cast<u64>(target_code_ptr));
|
||||
code.mov(code.rcx, u64(target_code_ptr));
|
||||
code.EnsurePatchLocationSize(patch_location, 10);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2022 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
@@ -20,7 +23,6 @@
|
||||
#include "dynarmic/backend/x64/exclusive_monitor_friend.h"
|
||||
#include "dynarmic/backend/x64/perf_map.h"
|
||||
#include "dynarmic/common/spin_lock_x64.h"
|
||||
#include "dynarmic/common/x64_disassemble.h"
|
||||
#include "dynarmic/interface/exclusive_monitor.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include "dynarmic/common/llvm_disassemble.h"
|
||||
#include <bit>
|
||||
#include <mcl/scope_exit.hpp>
|
||||
|
||||
#include "dynarmic/backend/x64/a64_emit_x64.h"
|
||||
@@ -21,7 +22,6 @@
|
||||
#include "dynarmic/backend/x64/devirtualize.h"
|
||||
#include "dynarmic/backend/x64/jitstate_info.h"
|
||||
#include "dynarmic/common/atomic.h"
|
||||
#include "dynarmic/common/x64_disassemble.h"
|
||||
#include "dynarmic/frontend/A64/translate/a64_translate.h"
|
||||
#include "dynarmic/interface/A64/a64.h"
|
||||
#include "dynarmic/ir/basic_block.h"
|
||||
@@ -43,7 +43,7 @@ static RunCodeCallbacks GenRunCodeCallbacks(A64::UserCallbacks* cb, CodePtr (*Lo
|
||||
static std::function<void(BlockOfCode&)> GenRCP(const A64::UserConfig& conf) {
|
||||
return [conf](BlockOfCode& code) {
|
||||
if (conf.page_table) {
|
||||
code.mov(code.r14, mcl::bit_cast<u64>(conf.page_table));
|
||||
code.mov(code.r14, std::bit_cast<u64>(conf.page_table));
|
||||
}
|
||||
if (conf.fastmem_pointer) {
|
||||
code.mov(code.r13, *conf.fastmem_pointer);
|
||||
@@ -80,16 +80,16 @@ public:
|
||||
};
|
||||
|
||||
// TODO: Check code alignment
|
||||
|
||||
const CodePtr current_code_ptr = [this] {
|
||||
const CodePtr aligned_code_ptr = CodePtr((uintptr_t(GetCurrentBlock()) + 15) & ~uintptr_t(15));
|
||||
const CodePtr current_code_ptr = [this, aligned_code_ptr] {
|
||||
// RSB optimization
|
||||
const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A64JitState::RSBPtrMask;
|
||||
if (jit_state.GetUniqueHash() == jit_state.rsb_location_descriptors[new_rsb_ptr]) {
|
||||
jit_state.rsb_ptr = new_rsb_ptr;
|
||||
return reinterpret_cast<CodePtr>(jit_state.rsb_codeptrs[new_rsb_ptr]);
|
||||
return CodePtr(jit_state.rsb_codeptrs[new_rsb_ptr]);
|
||||
}
|
||||
|
||||
return GetCurrentBlock();
|
||||
return aligned_code_ptr;
|
||||
//return GetCurrentBlock();
|
||||
}();
|
||||
|
||||
const HaltReason hr = block_of_code.RunCode(&jit_state, current_code_ptr);
|
||||
@@ -231,14 +231,10 @@ public:
|
||||
return is_executing;
|
||||
}
|
||||
|
||||
void DumpDisassembly() const {
|
||||
std::string Disassemble() const {
|
||||
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
|
||||
Common::DumpDisassembledX64(block_of_code.GetCodeBegin(), size);
|
||||
}
|
||||
|
||||
std::vector<std::string> Disassemble() const {
|
||||
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
|
||||
return Common::DisassembleX64(block_of_code.GetCodeBegin(), size);
|
||||
auto const* p = reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
|
||||
return Common::DisassembleX64(p, p + size);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -427,11 +423,7 @@ bool Jit::IsExecuting() const {
|
||||
return impl->IsExecuting();
|
||||
}
|
||||
|
||||
void Jit::DumpDisassembly() const {
|
||||
return impl->DumpDisassembly();
|
||||
}
|
||||
|
||||
std::vector<std::string> Jit::Disassemble() const {
|
||||
std::string Jit::Disassemble() const {
|
||||
return impl->Disassemble();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <mcl/iterator/reverse.hpp>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <xbyak/xbyak.h>
|
||||
|
||||
@@ -76,7 +75,8 @@ void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size,
|
||||
const FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size);
|
||||
|
||||
size_t xmm_offset = frame_info.xmm_offset + (num_xmms * XMM_SIZE);
|
||||
for (auto const xmm : mcl::iterator::reverse(regs)) {
|
||||
for (auto it = regs.rbegin(); it != regs.rend(); ++it) {
|
||||
auto const xmm = *it;
|
||||
if (HostLocIsXMM(xmm)) {
|
||||
xmm_offset -= XMM_SIZE;
|
||||
if (code.HasHostFeature(HostFeature::AVX)) {
|
||||
@@ -88,9 +88,11 @@ void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size,
|
||||
}
|
||||
if (frame_info.stack_subtraction != 0)
|
||||
code.add(rsp, u32(frame_info.stack_subtraction));
|
||||
for (auto const gpr : mcl::iterator::reverse(regs))
|
||||
for (auto it = regs.rbegin(); it != regs.rend(); ++it) {
|
||||
auto const gpr = *it;
|
||||
if (HostLocIsGPR(gpr))
|
||||
code.pop(HostLocToReg64(gpr));
|
||||
}
|
||||
}
|
||||
|
||||
void ABI_PushCalleeSaveRegistersAndAdjustStack(BlockOfCode& code, const std::size_t frame_size) {
|
||||
|
||||