Compare commits

...

137 Commits

Author SHA1 Message Date
Bix
d4cfe0b44e [vk] Reordering disabled broken DynamicState and ExtendedDynamicState 2025-11-22 19:05:10 +01:00
Bix
f3a50cfcf7 [vk] compiler baka baka 2025-11-22 19:04:43 +01:00
Bix
6cfdecbc7b [vk] Handling padding (compiler tomto) 2025-11-22 19:04:04 +01:00
Bix
d06ef6b83b Adding missing headers 2025-11-22 19:03:42 +01:00
Bix
963365716e [vk] Simplifying DynamicState and ExtendedState with Bitfield 2025-11-22 19:03:05 +01:00
Bix
587c601dfe [vk] Refactor to DynamicState and ExtendedState 2025-11-22 19:02:27 +01:00
CamilleLaVey
bba1904529 [vk] Refactor to DynamicState and ExtendedState 2025-11-17 21:53:34 -04:00
CamilleLaVey
e33d2541d2 [vk, texture_cache] Remove Force Identity in Component Swizzle 2025-11-17 20:55:47 -04:00
CamilleLaVey
3628654a98 [vk, android] Scaled Formats Emulation Only Available on Android 2025-11-17 20:47:49 -04:00
CamilleLaVey
1f5def5756 [vk, pipeline_cache] TEST: Refactor shader float controls handling for Qualcomm devices 2025-11-17 20:30:17 -04:00
CamilleLaVey
ca479883ec [vk, texture_cache, pipeline_cache] Removing handling for wrong vk formats 2025-11-17 02:13:39 -04:00
PavelBARABANOV
300c913883 comment 2025-11-16 20:11:56 +03:00
PavelBARABANOV
15b9a373cc [vk] Add Android-specific sRGB fallback format 2025-11-16 20:07:30 +03:00
CamilleLaVey
d19229b179 Fixing building issues again, dammed binding. 2025-11-16 02:20:00 -04:00
CamilleLaVey
0d999519a4 [spir-v] Include more cases for ColorArray1D 2025-11-16 02:03:46 -04:00
CamilleLaVey
92e9b82f6e [vk, spir-v] Refining the path for Array 1D emulation and R32 Uint handling consistency 2025-11-16 01:48:18 -04:00
CamilleLaVey
21575a7cc2 Fix building/ licensing issues 2025-11-15 23:18:39 -04:00
CamilleLaVey
7d8c5dad97 [vk, texture_cache, pipeline_cache] Refining handling of R32 2025-11-15 23:06:47 -04:00
CamilleLaVey
674f552ff1 [vk, texture_cache] Workaround for games with wrong usage of R32 with float samplers 2025-11-15 19:41:26 -04:00
CamilleLaVey
75d9236520 [vk, pipeline_cache, texture_cache, qcom] Resolving textures and pipeline usage for QCOM 2025-11-15 19:18:00 -04:00
CamilleLaVey
89926bce0b [vk, spir-v] Adding emulation of Array 1D with 2D for Android 2025-11-15 18:54:53 -04:00
CamilleLaVey
6c1fc4b4ed [vk] Handling threading missuse of VkQueue 2025-11-15 18:30:31 -04:00
CamilleLaVey
311f06047b [vk, Maxwell] Refining support for HDR Formats based on Specs 2025-11-15 18:24:14 -04:00
CamilleLaVey
46df717f7c [vk] Degrade HDR Format to LDR 2025-11-15 16:12:44 -04:00
CamilleLaVey
dcf9483b0b [vk, qcom] TEST: Adjustment to the MSAA and format resolve with native support 2025-11-15 15:06:43 -04:00
CamilleLaVey
2b828a9fee [vk] Re-adjusted HDR format handling based on physical specifications 2025-11-15 14:44:47 -04:00
CamilleLaVey
6fe1f86984 [vk, qcom] Revert Push Descriptors Threshold due to data corruption 2025-11-15 14:14:37 -04:00
CamilleLaVey
af073f13cf [vk, qcom] Including Tile Properties and Store Ops based on QCOM specifications 2025-11-15 03:02:08 -04:00
CamilleLaVey
aea945b671 [vk, host shaders, qcom] MSAA Handling by Native QCOM Shader Resolve 2025-11-15 01:47:28 -04:00
CamilleLaVey
c52fda760a Merge branch 'stuffmadeforfun' of https://git.eden-emu.dev/eden-emu/eden into stuffmadeforfun 2025-11-14 23:40:23 -04:00
lizzie
c168755c65 fix license 2025-11-15 03:38:33 +00:00
CamilleLaVey
8a83cf0271 [service, hle] Add defensive check in WriteBuffer 2025-11-15 03:37:57 +00:00
CamilleLaVey
3db41fbce6 [memory, vk] TEST: Tiled GPU optimization try #1 2025-11-15 03:37:56 +00:00
CamilleLaVey
5e7fb6eead Fix building issues 2025-11-15 03:37:56 +00:00
CamilleLaVey
bcc5390943 [texture_cache, gl, vk] Initial implementation for HDR + MSAA detection on QCOM drivers. 2025-11-15 03:37:44 +00:00
CamilleLaVey
a51d875d91 [shader_recompiler, spir-v] verifying int64 emulation path activation 2025-11-15 03:37:17 +00:00
PavelBARABANOV
6134a57367 Revert "TEST: Enabling TimelineSemaphores for QCOM and Turnip"
This reverts commit 3cd33fce44.
2025-11-15 03:37:01 +00:00
CamilleLaVey
c845b6086f Adding missing headers 2025-11-15 03:37:01 +00:00
CamilleLaVey
31c168efe1 [shader_recompiler, spir-v] Adding INT64 emulation path 2025-11-15 03:36:25 +00:00
CamilleLaVey
8bd87204f5 TEST: Enabling TimelineSemaphores for QCOM and Turnip 2025-11-15 03:36:09 +00:00
lizzie
e72a206aee fix 2025-11-15 03:36:08 +00:00
CamilleLaVey
6a62fa7ee3 Implement handling for texture cache flickering 2025-11-15 03:36:01 +00:00
crueter
52b630dfdc build
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-11-15 03:35:37 +00:00
CamilleLaVey
4860050358 attempt to fix building issues 2025-11-15 03:35:37 +00:00
CamilleLaVey
47f0563c1b Giving maintance to driver features and unused extensions 2025-11-15 03:35:35 +00:00
CamilleLaVey
b1208f03ee Fix building issues 2025-11-15 03:33:30 +00:00
CamilleLaVey
0fd603c094 [texture_cache, gl, vk] Initial implementation for HDR + MSAA detection on QCOM drivers. 2025-11-15 03:33:30 +00:00
CamilleLaVey
1ca19af7fb [shader_recompiler, spir-v] verifying int64 emulation path activation 2025-11-15 03:33:30 +00:00
PavelBARABANOV
ddd78c3b37 Revert "TEST: Enabling TimelineSemaphores for QCOM and Turnip"
This reverts commit 3cd33fce44.
2025-11-15 03:33:30 +00:00
CamilleLaVey
2e68f8795d Adding missing headers 2025-11-15 03:33:28 +00:00
CamilleLaVey
d3595fd2b1 [gl, vk, texture cache] Attempt to get correct MSAA image upload and download 2025-11-15 03:33:28 +00:00
CamilleLaVey
033531509b [shader_recompiler, spir-v] Adding INT64 emulation path 2025-11-15 03:33:28 +00:00
CamilleLaVey
b9954de1ca Fixing missing headers 2025-11-15 03:33:28 +00:00
CamilleLaVey
5f88deeebf [gl. vk] Extending impl for atomic floats operations 2025-11-15 03:33:28 +00:00
CamilleLaVey
d25da944ed Changing checks in HostMemor for virtual memory mapping 2025-11-15 03:33:27 +00:00
CamilleLaVey
ec274a855e TEST: Enabling TimelineSemaphores for QCOM and Turnip 2025-11-15 03:33:27 +00:00
CamilleLaVey
8133d4a8b4 Improved handling for Custom Border Color buggy impl on ARM/ QCOM and Turnip 2025-11-15 03:33:27 +00:00
lizzie
4f3e4bf9cb fix 2025-11-15 03:33:27 +00:00
CamilleLaVey
ec9e0f37ea Implement handling for texture cache flickering 2025-11-15 03:33:27 +00:00
crueter
b5f7735dba build
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-11-15 03:33:27 +00:00
CamilleLaVey
5f501d6ec0 attempt to fix building issues 2025-11-15 03:33:27 +00:00
CamilleLaVey
e820f304a5 Giving maintance to driver features and unused extensions 2025-11-15 03:33:26 +00:00
CamilleLaVey
3527a33430 [service, hle] Add defensive check in WriteBuffer 2025-11-14 20:31:14 -04:00
Shinmegumi
3f226678dd [vk] Fix fallback viewport/scissor origin handling (#294)
When viewport_scale_offset_enabled is disabled, the fallback path
previously assumed a top-left origin for both viewport and scissor.
This caused incorrect positioning or inverted geometry when the GPU
state expected a lower-left origin.

This change:
- Adjusts viewport setup: if window_origin is lower-left, shift Y and
  flip height negative to emulate lower-left in Vulkan’s top-left space.
- Updates scissor setup: recalculates Y for lower-left origin and
  ensures width/height fall back to 1 if zero, avoiding invalid extents.

This aligns Vulkan’s viewport/scissor behavior with Maxwell state,
fixing rendering issues in paths without scale/offset enabled.

Co-authored-by: MaranBr <maranbr@outlook.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/294
Co-authored-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-committed-by: Shinmegumi <shinmegumi@eden-emu.dev>
2025-11-14 15:13:29 +01:00
lizzie
e9d84d098d [dynarmic] attempt fix totk regression from #358 (#3013)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3013
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-14 15:07:13 +01:00
CamilleLaVey
ee5565077c [memory, vk] TEST: Tiled GPU optimization try #1 2025-11-14 01:32:02 -04:00
CamilleLaVey
9085ff1229 Merge branch 'stuffmadeforfun' of https://git.eden-emu.dev/eden-emu/eden into stuffmadeforfun 2025-11-13 23:10:40 -04:00
CamilleLaVey
6eff1779a2 Fix building issues 2025-11-14 03:03:28 +01:00
CamilleLaVey
3228cffd23 [texture_cache, gl, vk] Initial implementation for HDR + MSAA detection on QCOM drivers. 2025-11-14 03:03:28 +01:00
CamilleLaVey
9d9530efe0 [shader_recompiler, spir-v] verifying int64 emulation path activation 2025-11-14 03:03:28 +01:00
PavelBARABANOV
aaaa7c7601 Revert "TEST: Enabling TimelineSemaphores for QCOM and Turnip"
This reverts commit 3cd33fce44.
2025-11-14 03:03:28 +01:00
CamilleLaVey
7f8a507b79 Adding missing headers 2025-11-14 03:03:28 +01:00
CamilleLaVey
c28ae059e8 [gl, vk, texture cache] Attempt to get correct MSAA image upload and download 2025-11-14 03:03:28 +01:00
CamilleLaVey
7f1369f9a8 [shader_recompiler, spir-v] Adding INT64 emulation path 2025-11-14 03:03:28 +01:00
CamilleLaVey
6b05c164a1 Fixing missing headers 2025-11-14 03:03:28 +01:00
CamilleLaVey
a3f9d3b59c [gl. vk] Extending impl for atomic floats operations 2025-11-14 03:03:28 +01:00
CamilleLaVey
b066a6ffa0 Changing checks in HostMemor for virtual memory mapping 2025-11-14 03:03:28 +01:00
CamilleLaVey
a14cba7f11 TEST: Enabling TimelineSemaphores for QCOM and Turnip 2025-11-14 03:03:28 +01:00
CamilleLaVey
2d85b70373 Improved handling for Custom Border Color buggy impl on ARM/ QCOM and Turnip 2025-11-14 03:03:28 +01:00
lizzie
aa8cc4da38 fix 2025-11-14 03:03:28 +01:00
CamilleLaVey
baddaf0040 Implement handling for texture cache flickering 2025-11-14 03:03:28 +01:00
crueter
35b4e34e09 build
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-11-14 03:03:28 +01:00
CamilleLaVey
b574e9c334 attempt to fix building issues 2025-11-14 03:03:28 +01:00
CamilleLaVey
d6b5a3e181 Giving maintance to driver features and unused extensions 2025-11-14 03:03:28 +01:00
CamilleLaVey
a65a35432e Fix building issues 2025-11-13 21:30:19 -04:00
CamilleLaVey
6e575364eb [texture_cache, gl, vk] Initial implementation for HDR + MSAA detection on QCOM drivers. 2025-11-13 20:37:47 -04:00
CamilleLaVey
71a1442ab6 [shader_recompiler, spir-v] verifying int64 emulation path activation 2025-11-13 18:42:49 -04:00
xbzk
32db6c1877 [renderer] NG ragebound workaround via LoadOverrides + vk_rasterizer UpdateBlending TouchBlendequations Rework (#2934)
this pull should impact ninja gaiden ragebound only! it makes it playable past stage 4-1.
it contains a workaround for missing maxwell_3d's iterated_blend functionality, which fixes several graphics all over the game.
the issue causes transparency enabled blends (mostly lighting fx) to be wrongly blended into destination, turning textures into black frames.
in stage 4-1 there are lighthing layers in the foreground, causing sprites layer to become overlapped by these opaque black frames, including entire screen in a mid boss fight, making it unplayable* (players maneuvered by turning immortal option on and swinging sword all around until defeating it).
also only in stage 4-1 the fix has a short drawback: when you buff up next attack these problematique blends will be drawn back as black frames, but only for a split second, so no big deal.
this workaround was already discovered and available in PR 302,  but in an unconventional way for a game specific override, so we did forbidden it. now it uses classic game specific override solution exampled in core.cpp's System::Impl::LoadOverrides method, so now i guess it's worth to merge it and deliver this to players until we harness iterated_blend control.

additionally I've slightly reworked vk_rasterizer.cpp's RasterizerVulkan::UpdateBlending, if (state_tracker.TouchBlendEquations()) {...} session.
it was made in a way that for a single blend, it exhaustly calls 48 (6 x 8) MaxwellToVK redundant functions, and declared a lambda function inside a 8 laps loop.
reworked it so that instead of 48 calls it makes only the necessary 6 calls, and then merely safely copy the result for the other 7 times.

Co-authored-by: Allison Cunha <allisonbzk@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2934
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: xbzk <xbzk@eden-emu.dev>
Co-committed-by: xbzk <xbzk@eden-emu.dev>
2025-11-13 14:01:32 +01:00
lizzie
8eaa7c28ce [common] provide fallback for lack of atomic u128 support (#2999)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2999
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-13 13:27:32 +01:00
lizzie
3edfcabdea [dist] small low-fi version of the icon w/o antialias artifacts (#3006)
This version of the icon is mainly so the main one doesn't look like it has been compressed like a JPEG when shown on the taskbar :)
Signed-off-by: lizzie lizzie@eden-emu.dev

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3006
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-13 13:27:03 +01:00
lizzie
450c483de0 [cmake, externals/ffmpeg]: fix Solaris and BSD* builds with troubling makes (#3014)
Partial backport of https://github.com/pflyly/eden-nightly/blob/main/patches/solaris.patch

Signed-off-by: lizzie lizzie@eden-emu.dev

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3014
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-13 13:26:40 +01:00
lizzie
66db2613b5 [common] fix formatting of swapped u32_le/u64_le for BE targets (#2998)
Fixes a bunch of errors :)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2998
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-13 13:23:46 +01:00
lizzie
9a046190c7 [shader_recompiler] macro-ify flow_test and attribute (#2900)
Of course - macros my beloved :)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2900
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-13 13:22:02 +01:00
kleidis
cfbef5c487 [android] Setting to manually set app language (#2951)
It is on the app settings section

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2951
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: kleidis <kleidis1@protonmail.com>
Co-committed-by: kleidis <kleidis1@protonmail.com>
2025-11-13 03:45:58 +01:00
kleidis
f51d61e4a4 [android] Use spinbox setting type for CPU_TICKS (#2952)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2952
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: kleidis <kleidis1@protonmail.com>
Co-committed-by: kleidis <kleidis1@protonmail.com>
2025-11-13 03:45:41 +01:00
lizzie
ba9e03a612 [shared_recompiler/maxwell] fix SURED() wrong encodings (#2983)
SURED does NOT have a binding register and stuff, it is strictly just a binding-offset * 4

Signed-off-by: lizzie lizzie@eden-emu.dev

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2983
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-13 03:40:29 +01:00
crueter
7832afc5dd [externals] update nx-tzdb to 121125 (#3011)
real gzipped archive

Signed-off-by: crueter <crueter@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3011
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-11-13 03:25:55 +01:00
Caio Oliveira
028765867f externals: Fix Debug builds and remove PCH leftover (#3000)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3000
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-committed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-11-13 03:20:38 +01:00
MaranBr
d89df63a28 [video_core] Clean up the code and fix some inconsistences (#3015)
This cleans up the code and fixes some inconsistencies in the EDS settings.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3015
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-11-13 03:04:00 +01:00
crueter
87c4f658ce [ci] tx update ci (#3008)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3008
2025-11-12 05:21:49 +01:00
crueter
b7584cb2c3 [ci] push sources on every master push (#3007)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3007
2025-11-12 04:38:32 +01:00
crueter
f32f356c40 [desktop] always include common/detached_tasks.h (#3002)
Co-authored-by: Pabel Sobolev <contact@paveloom.dev>
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3002
2025-11-11 07:44:14 +01:00
crueter
7ca657d22f [cmake] allow static MinGW/macOS builds; fix clangarm64 (#2994)
Requires qt6-static, obviously... at least for eden. eden-cli also can
be built fully static
Notable challenges n such:
1. VkMemAlloc conflicts with Qt, since it embeds vk_mem_alloc.h in
   qrhivulkan; we can get around this by conditionally defining
   VMA_IMPLEMENTATION; that is, define it in the SDL2 frontend and undef
   it in the Qt frontend. It's not ideal, but I mean... it works, no?
2. find_library, pkgconfig, and some Config modules will always look for
   a .dll, so we have to tell CMake to look for .a
3. In spite of this, some will end up using .dll.a (implib) as their
   link targets; this is, well, bad, so we create a find_library hook
   that rejects dll.a
4. Some libraries have specific configs (boost lol)
5. Some libraries use _static targets (zstd, mbedtls)
6. Some extra libraries need to be linked, i.e. jbig, lzma, etc
7. QuaZip is sad

Needs testing on all platforms, and for both frontends on desktop, to
ensure Vulkan still works as expected.

(also: CI). Resulting executables are:
- 71MB for eden.exe
- 39MB for eden-cli.exe

Considering the entire libicudt is included (thanks Qt), that's a great size all things considered. No need to bundle all those plugins and translation files too.

Theoretically, this lays the groundwork towards fully static executables for other platforms too; though Linux doesn't have a huge benefit since AppImages are needed regardless. eden-room though maybe?

Fixes comp for clangarm64 because -msse4.1

Also allows macOS to build with qt6-static. macOS can't build static executables, but with these changes it ONLY relies on system libraries like libc and frameworks. So in theory we don't even need macdeployqt.

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2994
2025-11-11 06:22:33 +01:00
MaranBr
7764cdd57e [am] Improve some error messages (#2996)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2996
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-11-10 23:32:50 +01:00
PavelBARABANOV
4a17762ed7 Revert "TEST: Enabling TimelineSemaphores for QCOM and Turnip"
This reverts commit 3cd33fce44.
2025-11-10 18:52:31 +03:00
CamilleLaVey
447c4de73d Adding missing headers 2025-11-10 00:27:38 -04:00
CamilleLaVey
cd2c4d8caf [gl, vk, texture cache] Attempt to get correct MSAA image upload and download 2025-11-10 00:22:08 -04:00
CamilleLaVey
ee64c945fb [shader_recompiler, spir-v] Adding INT64 emulation path 2025-11-09 23:14:51 -04:00
CamilleLaVey
eec5d48220 Fixing missing headers 2025-11-09 20:03:19 -04:00
CamilleLaVey
75cc43a57a [gl. vk] Extending impl for atomic floats operations 2025-11-10 00:55:57 +01:00
CamilleLaVey
0078094b86 Changing checks in HostMemor for virtual memory mapping 2025-11-10 00:55:57 +01:00
CamilleLaVey
3cd33fce44 TEST: Enabling TimelineSemaphores for QCOM and Turnip 2025-11-10 00:55:57 +01:00
CamilleLaVey
ccafe0ed91 Improved handling for Custom Border Color buggy impl on ARM/ QCOM and Turnip 2025-11-10 00:55:57 +01:00
lizzie
94af9ff51f fix 2025-11-10 00:55:57 +01:00
CamilleLaVey
d229fdca32 Implement handling for texture cache flickering 2025-11-10 00:55:57 +01:00
crueter
e636e940ed build
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-11-10 00:55:57 +01:00
CamilleLaVey
2798174b00 attempt to fix building issues 2025-11-10 00:55:57 +01:00
CamilleLaVey
46f2084114 Giving maintance to driver features and unused extensions 2025-11-10 00:55:57 +01:00
PavelBARABANOV
42863027e2 Revert "[core/memory] Remove defered heap allocation on Linux." (#2974)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2974
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Co-committed-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
2025-11-09 22:42:09 +01:00
crueter
08f3639c80 [desktop, fs] main_window separation; fix Ryujinx save data link issues (#2929)
Some genius decided to put the entire MainWindow class into main.h and
main.cpp, which is not only horrific practice but also completely
destroys clangd beyond repair. Please, just don't do this.

(this will probably merge conflict to hell and back)

Also, fixes a bunch of issues with Ryujinx save data link:
- Paths with spaces would cause mklink to fail
- Add support for portable directories
- Symlink detection was incorrect sometimes(????)
- Some other stuff I'm forgetting

Furthermore, when selecting "From Eden" and attempting to save in Ryujinx, Ryujinx would destroy the link for... some reason? So to get around this we just copy the Eden data to Ryujinx then treat it like a "From Ryujinx" op

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2929
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2025-11-09 18:07:38 +01:00
Bix
e13c7ef3f8 [dist] Switch back to default Eden logo (#2990)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2990
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: Bix <bix@bixed.xyz>
Co-committed-by: Bix <bix@bixed.xyz>
2025-11-08 23:16:50 +01:00
unknown
89dd133a2f [frontend] Remove QDockWidget Wait Tree (#2949)
No one uses it and knows how to use it. So, remove it and replace it later with something more useful :)

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2949
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: unknown <sahyno1996@gmail.com>
Co-committed-by: unknown <sahyno1996@gmail.com>
2025-11-08 22:16:30 +01:00
John
86e9c32800 [desktop] Save option location in the Data Manager tool fix (#2986)
The first attempt missed a few files and did not move it properly.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2986
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: John <john@eden-emu.dev>
Co-committed-by: John <john@eden-emu.dev>
2025-11-08 19:41:35 +01:00
lizzie
f1cf30bc2a [dynarmic] fix build error for dynarmic_tests_generator on aarch64 (#2978)
Signed-off-by: lizzie lizzie@eden-emu.dev
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2978
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-08 18:47:55 +01:00
John
5af5214451 [desktop] Move save option location in the Data Manager tool. (#2985)
Move the save option further away from the shader option to help alleviate users accidents when deleting data.

(I slipped and I accidentally deleted all my saves instead of shaders when testing so many builds)

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2985
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: John <john@eden-emu.dev>
Co-committed-by: John <john@eden-emu.dev>
2025-11-08 18:46:30 +01:00
lizzie
312c1cc0f6 [shader_recompiler] Simplify translate loop and directly call (the now uniform functions); remove repetitive declarations on impl.h (#2972)
Function polymorphism where it wasn't needed? especially on tight code loops like translating code and whatnot?
You may think the compiler was fine with this but nah, it just made codegen for all those paths; I didn't check LTO but I'd assume it behaves the same (since the "black box" from most walkers suck) - basically bunch of code that isn't longer used
Also uniformly declaring all functions (i.e same args, return value) makes the entire switch statment way nicer

Signed-off-by: lizzie lizzie@eden-emu.dev

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2972
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-08 04:55:03 +01:00
MaranBr
576c4e5f77 [audio_core] Fix audio reverb effect acording to specs (#2976)
This fixes the audio reverb issue acording to specs. Known for affecting The Legend of Zelda: Echoes of Wisdom.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2976
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-11-08 03:50:51 +01:00
lizzie
84cf3e8c84 [nce] remove software prefetching instances (#2857)
May be a complete hit or miss on performance with NCE
Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2857
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-08 00:42:10 +01:00
lizzie
45a2008aa6 [common] replace Common::(DerivedFrom, IsArithmetic, Size, ConvertibleTo, IsIntegral) with libstdc++ equivalents (#290)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/290
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-07 17:03:01 +01:00
lizzie
8f6e0aa2cb [tools, hle/kernel] generate condensed version of svc.cpp; move svc_generator.py and generate_converters.py to tools (#2791)
Eventually we'd want cmake to do the build for us (as a build step) instead of having git be polluted with commits to update the autogenerated file...

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2791
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-07 17:00:53 +01:00
lizzie
ca0bc65531 [cmake] fix compilation for Intel Atom N455 (#2872)
Patience is key when building from source on an Intel Atom N455.

Of course, no SSE4.1 is in an atom... which is so unfortunate :(
We only get SSSE3 - but CI handles for building better codegen doesn't it?

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2872
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-07 16:58:41 +01:00
lizzie
a1930d1063 [dynarmic] remove MCL_ARCHITECTURE macros; fix unreachable macro builtin (#2889)
Eventually we shall use std::unreachable() ONCE all platforms support it :)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2889
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-07 16:50:14 +01:00
lizzie
48843306e2 [compat] Fix other DragonFlyBSD/NixOS issues (#2860)
Uh - the other pr that had "Fix dragonfly" got commits lost and I didn't notice... oops; cherry picked them back through :)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2860
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-07 16:50:03 +01:00
Caio Oliveira
159482a7a9 Revert "[vk] Clean up Extended Dynamic State code" (#2970)
* this PR need more work (as it break Eden on Windows+AMD)

Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>

---

Revert "[vk] Add back VIDS but disable on EDS0 (#2957)"

This reverts commit 1c4dae066b.

Revert "[vk] disable VK_EXT_vertex_input_dynamic_state again (#2954)"

This reverts commit 9406438d51.

Revert "[vk] Clean up Extended Dynamic State code (#2947)"

This reverts commit 612da00d1b.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2970
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-committed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-11-07 14:01:28 +01:00
MaranBr
0510f0bdbc [audio_core] Increase RingBuffer and SinkBuffer size a bit more (#2964)
This helps weaker CPUs maintain consistent audio playback while keeping latency low.

Complement to #2944.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2964
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-11-07 01:42:57 +01:00
MaranBr
569dbfe8c0 [video_core] Increase MAX_MIP_LEVELS to 16 according to specs (#2965)
This increases MAX_MIP_LEVELS from 14 to 16, according to specs.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2965
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-11-07 01:42:52 +01:00
lizzie
8412e64bb0 [dynarmic] fix qlaunch (#2967)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2967
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-11-06 22:37:52 +01:00
224 changed files with 10334 additions and 11514 deletions

19
.github/workflows/sources.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: tx-src
on:
push:
branches: [ master ]
jobs:
sources:
runs-on: source
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Push New Sources
run: |
export PATH=/usr/lib/qt6/bin:$PATH
./tools/translations/qt-source.sh
tx-cli push -s

61
.github/workflows/translations.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: tx-pull
on:
# monday, wednesday, saturday at 2pm
schedule:
cron:
- '0 14 * * 1,3,6'
jobs:
tx-update:
runs-on: source
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get New Translations
run: tx-cli pull -t -f
- name: Push branch
run: |
git config --local user.name "Eden CI"
git config --local user.email "ci@eden-emu.dev"
git config --local user.signingkey "D57652791BB25D2A"
git config --local push.autoSetupRemote true
git remote set-url origin ci:eden-emu/eden.git
TIMESTAMP=$(date +"%s")
echo "TIMESTAMP=$TIMESTAMP" >> "$GITHUB_ENV"
git switch -c update-translations-$TIMESTAMP
git add dist src/android/app/src/main/res
git commit -sS -m "[dist, android] Update translations from Transifex"
git push
- name: Create PR
run: |
DATE=$(date +"%b %d")
TITLE="[dist, android] Update translations from Transifex for $DATE"
BODY="Automatic translation update for $DATE"
BASE=master
HEAD=update-translations-$TIMESTAMP
cat << EOF > data.json
{
"base": "$BASE",
"body": "$BODY",
"head": "$HEAD",
"title": "$TITLE"
}
EOF
curl -X 'POST' \
'https://git.eden-emu.dev/api/v1/repos/eden-emu/eden/pulls' \
-H 'accept: application/json' \
-H 'Authorization: Bearer ${{ secrets.CI_FJ_TOKEN }}' \
-H 'Content-Type: application/json' \
-d "@data.json" --fail

View File

@@ -13,12 +13,19 @@ elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
set(PLATFORM_OPENBSD ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "NetBSD")
set(PLATFORM_NETBSD ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "DragonFly")
set(PLATFORM_DRAGONFLYBSD ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Haiku")
set(PLATFORM_HAIKU ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(PLATFORM_LINUX ON)
endif()
# dumb heuristic to detect msys2
if (CMAKE_COMMAND MATCHES "msys64")
set(PLATFORM_MSYS ON)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CXX_CLANG ON)
if (MSVC)
@@ -83,6 +90,89 @@ if (PLATFORM_NETBSD)
set(ENV{PKG_CONFIG_PATH} "${PKG_CONFIG_PATH}:${CMAKE_SYSROOT}/usr/pkg/lib/ffmpeg7/pkgconfig")
endif()
# MSYS2 utilities
if (PLATFORM_MSYS)
include(FixMsysPaths)
# really, really dumb heuristic to detect what environment we are in
macro(system var)
if (CMAKE_COMMAND MATCHES ${var})
set(MSYSTEM ${var})
endif()
endmacro()
system(mingw64)
system(clang64)
system(clangarm64)
system(ucrt64)
if (NOT DEFINED MSYSTEM)
set(MSYSTEM msys2)
endif()
# we (generally) want to prioritize environment-specific binaries if possible
# some, like autoconf, are not present on environments besides msys2 though
set(CMAKE_PROGRAM_PATH C:/msys64/${MSYSTEM}/bin C:/msys64/usr/bin)
set(ENV{PKG_CONFIG_PATH} C:/msys64/${MSYSTEM}/lib/pkgconfig)
endif()
# static stuff
option(YUZU_STATIC_BUILD "Use static libraries and executables if available" OFF)
if (YUZU_STATIC_BUILD)
# lol
set(Boost_USE_STATIC_LIBS ON)
set(BUILD_SHARED_LIBS OFF)
## find .a libs first (static, usually)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
## some libraries define a Library::Name_static alternative ##
set(YUZU_STATIC_SUFFIX _static)
## some libraries use CMAKE_IMPORT_LIBRARY_SUFFIX e.g. Harfbuzz ##
set(CMAKE_IMPORT_LIBRARY_SUFFIX ".a")
if (MINGW)
# simple hook to reject dynamic libs
function(find_library var)
# also skip previously-found libraries cuz... yaknow
if (${var})
return()
endif()
_find_library(${var} ${ARGN})
if (${var})
get_filename_component(lib_name "${${var}}" NAME)
if (lib_name MATCHES "dll\\.a$")
unset(${var} CACHE)
set(${var} "${var}-NOTFOUND" CACHE INTERNAL "" FORCE)
endif()
endif()
endfunction()
# msys2 quazip does not build a static lib
set(QuaZip-Qt6_FORCE_BUNDLED ON)
set(YUZU_USE_BUNDLED_FFMPEG ON)
set(YUZU_USE_BUNDLED_SDL2 ON)
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF)
elseif(APPLE)
# these libs do not properly provide static libs/let you do it with cmake
set(YUZU_USE_CPM ON)
# IMPORTED_IMPLIB not set for imported target
# TODO(crueter): wtf
set(YUZU_USE_BUNDLED_FFMPEG ON)
set(YUZU_USE_EXTERNAL_SDL2 ON)
set(fmt_FORCE_BUNDLED ON)
set(SPIRV-Tools_FORCE_BUNDLED ON)
set(SPIRV-Headers_FORCE_BUNDLED ON)
set(zstd_FORCE_BUNDLED ON)
endif()
endif()
# Detect current compilation architecture and create standard definitions
# =======================================================================
@@ -189,9 +279,9 @@ if (CXX_CLANG_CL)
$<$<COMPILE_LANGUAGE:C,CXX>:/EHsc> # thanks microsoft
)
# REQUIRED CPU features IN Windows-amd64
if (ARCHITECTURE_x86_64)
add_compile_options(
# Required CPU features for amd64
$<$<COMPILE_LANGUAGE:C,CXX>:-msse4.1>
$<$<COMPILE_LANGUAGE:C,CXX>:-mcx16>
)
@@ -209,20 +299,17 @@ if (MSVC AND NOT CXX_CLANG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX-")
endif()
if (PLATFORM_FREEBSD)
if (PLATFORM_FREEBSD OR PLATFORM_DRAGONFLYBSD)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/local/lib")
endif()
# Set bundled sdl2/qt as dependent options.
# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion
cmake_dependent_option(ENABLE_SDL2 "Enable the SDL2 frontend" ON "NOT ANDROID" OFF)
if (ENABLE_SDL2)
# TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system
cmake_dependent_option(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" OFF "NOT MSVC" OFF)
option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}")
endif()
# TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system
cmake_dependent_option(YUZU_USE_EXTERNAL_SDL2 "Build SDL2 from external source" OFF "ENABLE_SDL2;NOT MSVC" OFF)
cmake_dependent_option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}" "ENABLE_SDL2" OFF)
# qt stuff
option(ENABLE_QT "Enable the Qt frontend" ON)
@@ -243,10 +330,14 @@ option(YUZU_USE_CPM "Use CPM to fetch system dependencies (fmt, boost, etc) if n
# ffmpeg
option(YUZU_USE_BUNDLED_FFMPEG "Download bundled FFmpeg" ${EXT_DEFAULT})
cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from source" "${PLATFORM_SUN}" "NOT WIN32 AND NOT ANDROID" OFF)
cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from external source" "${PLATFORM_SUN}" "NOT WIN32 AND NOT ANDROID" OFF)
# sirit
option(YUZU_USE_BUNDLED_SIRIT "Download bundled sirit" ${EXT_DEFAULT})
set(BUNDLED_SIRIT_DEFAULT OFF)
if ((MSVC AND NOT (CMAKE_BUILD_TYPE MATCHES "Debug|RelWithDebInfo") OR ANDROID))
set(BUNDLED_SIRIT_DEFAULT ON)
endif()
option(YUZU_USE_BUNDLED_SIRIT "Download bundled sirit" ${BUNDLED_SIRIT_DEFAULT})
# Re-allow on FreeBSD once its on mainline ports
cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "WIN32 OR PLATFORM_LINUX OR APPLE" OFF)
@@ -283,6 +374,17 @@ if(USE_CCACHE)
else()
message(FATAL_ERROR "USE_CCACHE enabled, but no executable found at: ${CCACHE_PATH}")
endif()
# Follow SCCache recommendations:
# <https://github.com/mozilla/sccache/blob/main/README.md?plain=1#L144>
if(WIN32)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
endif()
endif()
endif()
# TODO(crueter): CI this?
@@ -354,13 +456,6 @@ if (ANDROID)
set(CMAKE_POLICY_VERSION_MINIMUM 3.5) # Workaround for Oboe
endif()
# We need to downgrade debug info (/Zi -> /Z7) to use an older but more cacheable format
# See https://github.com/nanoant/CMakePCHCompiler/issues/21
if(WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
endif()
# Default to a Release build
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE)
@@ -581,11 +676,12 @@ else()
find_package(stb MODULE)
find_package(Opus 1.3 MODULE REQUIRED)
find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED MODULE)
# wow
find_package(Boost 1.57.0 CONFIG REQUIRED OPTIONAL_COMPONENTS headers context system fiber)
find_package(Boost 1.57.0 CONFIG REQUIRED OPTIONAL_COMPONENTS headers context system fiber filesystem)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID)
find_package(gamemode 1.7 MODULE)
@@ -633,15 +729,15 @@ if (APPLE)
# Umbrella framework for everything GUI-related
find_library(COCOA_LIBRARY Cocoa)
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
find_library(ICONV_LIBRARY iconv REQUIRED)
list(APPEND PLATFORM_LIBRARIES ${ICONV_LIBRARY})
# find_library(ICONV_LIBRARY iconv REQUIRED)
# list(APPEND PLATFORM_LIBRARIES ${ICONV_LIBRARY})
elseif (WIN32)
# Target Windows 10
add_compile_definitions(_WIN32_WINNT=0x0A00 WINVER=0x0A00)
set(PLATFORM_LIBRARIES winmm ws2_32 iphlpapi)
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} winmm iphlpapi ws2_32 wlanapi)
if (MINGW)
# PSAPI is the Process Status API
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version)
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version crypt32 rpcrt4 gdi32 wldap32 mswsock)
endif()
elseif (PLATFORM_HAIKU)
# Haiku is so special :)
@@ -654,6 +750,8 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU|SunOS)$")
set(PLATFORM_LIBRARIES rt)
endif()
message(STATUS "Platform Libraries: ${PLATFORM_LIBRARIES}")
add_subdirectory(externals)
# pass targets from externals

View File

@@ -542,10 +542,11 @@ function(AddCIPackage)
PACKAGE
EXTENSION
MIN_VERSION
DISABLED_PLATFORMS
)
cmake_parse_arguments(PKG_ARGS "" "${oneValueArgs}" "" ${ARGN})
set(multiValueArgs DISABLED_PLATFORMS)
cmake_parse_arguments(PKG_ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT DEFINED PKG_ARGS_VERSION)
message(FATAL_ERROR "[CPMUtil] VERSION is required")

View File

@@ -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
@@ -10,6 +13,10 @@ find_package_handle_standard_args(Opus
VERSION_VAR OPUS_VERSION
)
if (PLATFORM_MSYS)
FixMsysPath(PkgConfig::OPUS)
endif()
if (Opus_FOUND AND NOT TARGET Opus::opus)
add_library(Opus::opus ALIAS PkgConfig::OPUS)
endif()

View File

@@ -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
@@ -10,6 +13,10 @@ find_package_handle_standard_args(SPIRV-Tools
VERSION_VAR SPIRV-Tools_VERSION
)
if (PLATFORM_MSYS)
FixMsysPath(PkgConfig::SPIRV-Tools)
endif()
if (SPIRV-Tools_FOUND AND NOT TARGET SPIRV-Tools::SPIRV-Tools)
if (TARGET SPIRV-Tools)
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools)

View File

@@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2022 Alexandre Bouvier <contact@amb.tf>
#
# SPDX-License-Identifier: GPL-3.0-or-later
@@ -11,6 +14,10 @@ find_package_handle_standard_args(enet
VERSION_VAR ENET_VERSION
)
if (PLATFORM_MSYS)
FixMsysPath(PkgConfig::ENET)
endif()
if (enet_FOUND AND NOT TARGET enet::enet)
add_library(enet::enet ALIAS PkgConfig::ENET)
endif()

View File

@@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2022 Alexandre Bouvier <contact@amb.tf>
#
# SPDX-License-Identifier: GPL-3.0-or-later
@@ -11,6 +14,10 @@ find_package_handle_standard_args(libusb
VERSION_VAR LIBUSB_VERSION
)
if (PLATFORM_MSYS)
FixMsysPath(PkgConfig::LIBUSB)
endif()
if (libusb_FOUND AND NOT TARGET libusb::usb)
add_library(libusb::usb ALIAS PkgConfig::LIBUSB)
endif()

View File

@@ -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
@@ -9,6 +12,11 @@ if (lz4_CONSIDERED_CONFIGS)
else()
find_package(PkgConfig QUIET)
pkg_search_module(LZ4 QUIET IMPORTED_TARGET liblz4)
if (PLATFORM_MSYS)
FixMsysPath(PkgConfig::LZ4)
endif()
find_package_handle_standard_args(lz4
REQUIRED_VARS LZ4_LINK_LIBRARIES
VERSION_VAR LZ4_VERSION

View File

@@ -6,22 +6,34 @@
include(FindPackageHandleStandardArgs)
find_package(PkgConfig QUIET)
pkg_search_module(ZSTD QUIET IMPORTED_TARGET libzstd)
find_package_handle_standard_args(zstd
REQUIRED_VARS ZSTD_LINK_LIBRARIES
VERSION_VAR ZSTD_VERSION
)
find_package(zstd QUIET CONFIG)
if (zstd_CONSIDERED_CONFIGS)
find_package_handle_standard_args(zstd CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
pkg_search_module(ZSTD QUIET IMPORTED_TARGET libzstd)
find_package_handle_standard_args(zstd
REQUIRED_VARS ZSTD_LINK_LIBRARIES
VERSION_VAR ZSTD_VERSION
)
endif()
if (zstd_FOUND AND NOT TARGET zstd::zstd)
if (TARGET zstd::libzstd_shared)
if (TARGET zstd::libzstd_shared AND NOT YUZU_STATIC_BUILD)
add_library(zstd::zstd ALIAS zstd::libzstd_shared)
add_library(zstd::libzstd ALIAS zstd::libzstd_shared)
elseif (TARGET zstd::libzstd_static)
add_library(zstd::zstd ALIAS zstd::libzstd_static)
add_library(zstd::libzstd ALIAS zstd::libzstd_static)
else()
add_library(zstd::zstd ALIAS PkgConfig::ZSTD)
add_library(zstd::libzstd ALIAS PkgConfig::ZSTD)
endif()
endif()
get_target_property(ZSTD_TARGET zstd::zstd ALIASED_TARGET)
if (NOT TARGET zstd::libzstd)
if (ZSTD_TARGET)
add_library(zstd::libzstd ALIAS ${ZSTD_TARGET})
else()
add_library(zstd::libzstd ALIAS zstd::zstd)
endif()
endif()

View File

@@ -0,0 +1,21 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
function(FixMsysPath target)
get_target_property(include_dir ${target} INTERFACE_INCLUDE_DIRECTORIES)
if (NOT (include_dir MATCHES "^/"))
return()
endif()
set(root_default $ENV{MSYS2_LOCATION})
if (root_default STREQUAL "")
set(root_default "C:/msys64")
endif()
set(MSYS_ROOT_PATH ${root_default} CACHE STRING "Location of the MSYS2 root")
set(include_dir "C:/msys64${include_dir}")
set_target_properties(${target} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${include_dir})
endfunction()

View File

@@ -1,58 +0,0 @@
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
set(MINGW_PREFIX /usr/x86_64-w64-mingw32/)
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(CMAKE_FIND_ROOT_PATH ${MINGW_PREFIX})
set(SDL2_PATH ${MINGW_PREFIX})
set(MINGW_TOOL_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32-)
# Specify the cross compiler
set(CMAKE_C_COMPILER ${MINGW_TOOL_PREFIX}clang)
set(CMAKE_CXX_COMPILER ${MINGW_TOOL_PREFIX}clang++)
set(CMAKE_RC_COMPILER ${MINGW_TOOL_PREFIX}windres)
set(CMAKE_C_COMPILER_AR ${MINGW_TOOL_PREFIX}ar)
set(CMAKE_CXX_COMPILER_AR ${MINGW_TOOL_PREFIX}ar)
set(CMAKE_C_COMPILER_RANLIB ${MINGW_TOOL_PREFIX}ranlib)
set(CMAKE_CXX_COMPILER_RANLIB ${MINGW_TOOL_PREFIX}ranlib)
# Mingw tools
set(STRIP ${MINGW_TOOL_PREFIX}strip)
set(WINDRES ${MINGW_TOOL_PREFIX}windres)
set(ENV{PKG_CONFIG} ${MINGW_TOOL_PREFIX}pkg-config)
# ccache wrapper
option(USE_CCACHE "Use ccache for compilation" OFF)
if(USE_CCACHE)
find_program(CCACHE ccache)
if(CCACHE)
message(STATUS "Using ccache found in PATH")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE})
else(CCACHE)
message(WARNING "USE_CCACHE enabled, but no ccache found")
endif(CCACHE)
endif(USE_CCACHE)
# Search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Echo modified cmake vars to screen for debugging purposes
if(NOT DEFINED ENV{MINGW_DEBUG_INFO})
message("")
message("Custom cmake vars: (blank = system default)")
message("-----------------------------------------")
message("* CMAKE_C_COMPILER : ${CMAKE_C_COMPILER}")
message("* CMAKE_CXX_COMPILER : ${CMAKE_CXX_COMPILER}")
message("* CMAKE_RC_COMPILER : ${CMAKE_RC_COMPILER}")
message("* WINDRES : ${WINDRES}")
message("* ENV{PKG_CONFIG} : $ENV{PKG_CONFIG}")
message("* STRIP : ${STRIP}")
message("* USE_CCACHE : ${USE_CCACHE}")
message("")
# So that the debug info only appears once
set(ENV{MINGW_DEBUG_INFO} SHOWN)
endif()

View File

@@ -1,57 +0,0 @@
# SPDX-FileCopyrightText: 2018 tech4me <guiwanglong@gmail.com>
# SPDX-License-Identifier: GPL-2.0-or-later
set(MINGW_PREFIX /usr/x86_64-w64-mingw32/)
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
# Actually a hack, w/o this will cause some strange errors
set(CMAKE_HOST_WIN32 TRUE)
set(CMAKE_FIND_ROOT_PATH ${MINGW_PREFIX})
set(SDL2_PATH ${MINGW_PREFIX})
set(MINGW_TOOL_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32-)
# Specify the cross compiler
set(CMAKE_C_COMPILER ${MINGW_TOOL_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${MINGW_TOOL_PREFIX}g++)
set(CMAKE_RC_COMPILER ${MINGW_TOOL_PREFIX}windres)
# Mingw tools
set(STRIP ${MINGW_TOOL_PREFIX}strip)
set(WINDRES ${MINGW_TOOL_PREFIX}windres)
set(ENV{PKG_CONFIG} ${MINGW_TOOL_PREFIX}pkg-config)
# ccache wrapper
option(USE_CCACHE "Use ccache for compilation" OFF)
if(USE_CCACHE)
find_program(CCACHE ccache)
if(CCACHE)
message(STATUS "Using ccache found in PATH")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE})
else(CCACHE)
message(WARNING "USE_CCACHE enabled, but no ccache found")
endif(CCACHE)
endif(USE_CCACHE)
# Search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Echo modified cmake vars to screen for debugging purposes
if(NOT DEFINED ENV{MINGW_DEBUG_INFO})
message("")
message("Custom cmake vars: (blank = system default)")
message("-----------------------------------------")
message("* CMAKE_C_COMPILER : ${CMAKE_C_COMPILER}")
message("* CMAKE_CXX_COMPILER : ${CMAKE_CXX_COMPILER}")
message("* CMAKE_RC_COMPILER : ${CMAKE_RC_COMPILER}")
message("* WINDRES : ${WINDRES}")
message("* ENV{PKG_CONFIG} : $ENV{PKG_CONFIG}")
message("* STRIP : ${STRIP}")
message("* USE_CCACHE : ${USE_CCACHE}")
message("")
# So that the debug info only appears once
set(ENV{MINGW_DEBUG_INFO} SHOWN)
endif()

View File

@@ -20,7 +20,7 @@
"hash": "4fb7f6fde92762305aad8754d7643cd918dd1f3f67e104e9ab385b18c73178d72a17321354eb203b790b6702f2cf6d725a5d6e2dfbc63b1e35f9eb59fb42ece9",
"git_version": "1.89.0",
"version": "1.57",
"find_args": "CONFIG",
"find_args": "CONFIG OPTIONAL_COMPONENTS headers context system fiber filesystem",
"patches": [
"0001-clang-cl.patch",
"0002-use-marmasm.patch",

0
dist/dev.eden_emu.eden.desktop vendored Normal file → Executable file
View File

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
dist/eden.icns vendored

Binary file not shown.

BIN
dist/eden.ico vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 KiB

After

Width:  |  Height:  |  Size: 386 KiB

83
dist/eden_named.svg vendored

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 37 KiB

9
dist/icon_variations/README.md vendored Normal file
View File

@@ -0,0 +1,9 @@
# Icon variations
These icons are licensed under GPLv3. Please see the [script for generating icons](../../tools/README.md) and appropriatedly redirect for seasonal icons.
- `base_named.svg` - Named variant.
- `base_small.svg`: Variant used for tiny icons (16x16, 64x64, etc).
- `base.svg`: Variant without branding/naming.
Try to keep the icons simple. And preferably automatically be able to be generated (to reduce maintanaince burden). Additionally keep the files small (use `svgo` and `optipng`) to not clutter the git.

80
dist/icon_variations/base_small.svg vendored Normal file
View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="512"
height="512"
fill="none"
viewBox="0 0 512 512"
version="1.1"
id="svg7"
sodipodi:docname="base_small.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:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs7">
<linearGradient
id="linearGradient10"
inkscape:collect="always">
<stop
style="stop-color:#f977d9;stop-opacity:1;"
offset="0"
id="stop10" />
<stop
style="stop-color:#a655d5;stop-opacity:1;"
offset="0.54051435"
id="stop13" />
<stop
style="stop-color:#984fd5;stop-opacity:1;"
offset="0.5714342"
id="stop12" />
<stop
style="stop-color:#8c4ad4;stop-opacity:1;"
offset="0.59666741"
id="stop14" />
<stop
style="stop-color:#3928d2;stop-opacity:1;"
offset="1"
id="stop11" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10"
id="linearGradient11"
x1="264.17508"
y1="28.385544"
x2="264.17508"
y2="488.65109"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.97815818,0,0,0.97880258,4.570042,5.8799159)" />
</defs>
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="0.88388348"
inkscape:cx="153.30075"
inkscape:cy="243.24473"
inkscape:window-width="1600"
inkscape:window-height="849"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg7"
showguides="false" />
<path
id="path9"
style="fill:url(#linearGradient11);fill-opacity:1;stroke:none;stroke-width:13.3314;stroke-opacity:1;paint-order:stroke fill markers"
d="M 262.97461 33.6875 A 218.44267 225.23091 0 0 0 138.83789 73.589844 L 141.13867 72.265625 L 161.2207 65.195312 L 181.01953 61.517578 L 204.35352 64.205078 L 228.96094 76.650391 L 265.80078 115 L 283 99.400391 L 304.59961 85.800781 L 331 76.400391 L 360.59961 69.599609 L 379.95508 69.208984 A 218.44267 225.23091 0 0 0 262.97461 33.6875 z M 380.07617 69.291016 L 350.19922 77.800781 L 329.19922 89.199219 L 307.40039 108 L 288.80078 129.80078 L 287.40039 135 L 302.40039 129.59961 L 319 127.80078 L 348.80078 131.80078 L 370.19922 141.40039 L 393 161.40039 L 399.59961 171.59961 L 374.80078 160.80078 L 338.40039 150.80078 L 309.19922 150 L 288.80078 154.40039 L 293.19922 155.19922 L 319.19922 168.80078 L 338 187.19922 L 350.80078 224 L 349.19922 260 L 326 222.80078 L 302.80078 194 L 277.59961 172.40039 L 269.19922 187.59961 L 256.80078 281.59961 L 258 364 L 278.40039 452.80078 L 297.19531 481.36914 A 218.44267 225.23091 0 0 0 481.41797 258.91797 A 218.44267 225.23091 0 0 0 380.07617 69.291016 z M 133.07422 77.839844 A 218.44267 225.23091 0 0 0 44.533203 258.91797 A 218.44267 225.23091 0 0 0 257.04102 484.06641 L 247.3457 458.62891 L 237.87109 418.18359 L 233.0625 380.42383 L 230.375 354.9668 L 229.95117 321.30859 L 232.35547 291.32812 L 237.44727 254.98242 L 254.55859 191.9082 L 261.62891 172.5332 L 255.54883 174.08984 L 240.98242 180.87695 L 229.59961 190.19922 L 210.59961 208.19922 L 197.40039 229.40039 L 186.40039 252.59961 L 173.40039 269 L 171.40039 253.19922 L 173.59961 229.40039 L 183 202.40039 L 199.40039 178 L 221.04102 153.44141 L 209.02148 155.70508 L 177.05859 162.77539 L 148.06836 171.40234 L 119.92578 183 L 120.63281 180.16992 L 129.82422 165.88672 L 151.17969 147.50195 L 172.95898 135.48242 L 190.07031 129.54102 L 209.02148 127.98633 L 227.6875 128.69336 L 247.76953 128.41016 L 246.49805 125.1582 L 226.69922 105.92383 L 219.62695 97.439453 L 221.4668 90.085938 L 206.75781 94.044922 L 195.86914 95.458984 L 179.46289 88.671875 L 156.12891 81.458984 L 133.07422 77.839844 z " />
<path
style="fill:#1b1b1b;fill-opacity:0.12492698;stroke:none;stroke-width:13.374;stroke-opacity:0.415999;paint-order:stroke fill markers"
d="m 259.36665,490.16617 39.03323,-6.96642 -20,-30.4 -20.4,-88.8 -1.2,-82.4 12.4,-94 8.4,-15.2 25.2,21.6 23.2,28.8 23.2,37.2 1.6,-36 -12.8,-36.8 -18.8,-18.4 -26,-13.6 -4.4,-0.8 20.4,-4.4 29.2,0.8 36.4,10 24.8,10.8 -6.6,-10.2 -22.8,-20 -21.4,-9.6 -29.8,-4 -16.6,1.8 -15,5.4 1.4,-5.2 18.6,-21.8 21.8,-18.800003 21,-11.4 30.2,-8.6 -19.8,0.4 -29.6,6.8 -26.4,9.4 -21.6,13.6 -17.2,15.600003 -36.83882,-38.349628 -24.60732,-12.445079 -23.33452,-2.687006 -19.79899,3.676955 -20.08184,7.071068 -9.33381,5.374012 24.32448,3.818376 23.33452,7.212489 16.40488,6.788226 10.88944,-1.414214 14.70782,-3.959798 -1.83847,7.353911 7.07106,8.485288 19.79899,19.2333 1.2728,3.25269 -20.08184,0.28284 -18.66762,-0.7071 -18.95046,1.55563 -17.11198,5.9397 -21.77889,12.02081 -21.35462,18.38478 -9.19239,14.28356 -0.70711,2.82843 28.14285,-11.59656 28.99138,-8.6267 31.96122,-7.07107 12.02082,-2.26274 -21.64158,24.55783 -16.4,24.4 -9.4,27 -2.2,23.8 2,15.8 13,-16.4 11,-23.2 13.2,-21.2 19,-18 11.38199,-9.32209 14.5664,-6.78822 6.08112,-1.55564 -7.07107,19.37473 -17.11198,63.07393 -5.09117,36.34528 -2.40416,29.98133 0.42426,33.65828 2.68701,25.45585 4.80832,37.7595 9.47523,40.44651 z"
id="path8-4" />
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -821,31 +821,6 @@ QTabBar QToolButton::left-arrow:disabled {
image: url(:/qss_icons/rc/left_arrow_disabled.png);
}
QDockWidget {
background: #31363b;
border: 1px solid #403F3F;
titlebar-close-icon: url(:/qss_icons/rc/close.png);
titlebar-normal-icon: url(:/qss_icons/rc/undock.png);
}
QDockWidget::close-button,
QDockWidget::float-button {
border: 1px solid transparent;
border-radius: 2px;
background: transparent;
}
QDockWidget::close-button:hover,
QDockWidget::float-button:hover {
background: rgba(255, 255, 255, 10);
}
QDockWidget::close-button:pressed,
QDockWidget::float-button:pressed {
padding: 1px -1px -1px 1px;
background: rgba(255, 255, 255, 10);
}
QTreeView,
QListView {
border: 1px solid #54575B;

View File

@@ -1685,54 +1685,6 @@ QTabBar QToolButton::right-arrow:disabled {
image: url(":/qss_icons/rc/arrow_right_disabled.png");
}
/* QDockWiget -------------------------------------------------------------
--------------------------------------------------------------------------- */
QDockWidget {
outline: 1px solid #32414B;
background-color: #19232D;
border: 1px solid #32414B;
border-radius: 4px;
titlebar-close-icon: url(":/qss_icons/rc/window_close.png");
titlebar-normal-icon: url(":/qss_icons/rc/window_undock.png");
}
QDockWidget::title {
/* Better size for title bar */
padding: 6px;
spacing: 4px;
border: none;
background-color: #32414B;
}
QDockWidget::close-button {
background-color: #32414B;
border-radius: 4px;
border: none;
}
QDockWidget::close-button:hover {
image: url(":/qss_icons/rc/window_close_focus.png");
}
QDockWidget::close-button:pressed {
image: url(":/qss_icons/rc/window_close_pressed.png");
}
QDockWidget::float-button {
background-color: #32414B;
border-radius: 4px;
border: none;
}
QDockWidget::float-button:hover {
image: url(":/qss_icons/rc/window_undock_focus.png");
}
QDockWidget::float-button:pressed {
image: url(":/qss_icons/rc/window_undock_pressed.png");
}
/* QTreeView QListView QTableView -----------------------------------------
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtreeview

BIN
dist/yuzu.bmp vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 256 KiB

BIN
dist/yuzu.icns vendored

Binary file not shown.

View File

@@ -30,6 +30,13 @@ macOS is largely untested. Expect crashes, significant Vulkan issues, and other
## Solaris
Always consult [the OpenIndiana package list](https://pkg.openindiana.org/hipster/en/index.shtml) to cross-verify availability.
Run the usual update + install of essential toolings: `sudo pkg update && sudo pkg install git cmake`.
- **gcc**: `sudo pkg install developer/gcc-14`.
- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`.
Qt Widgets appears to be broken. For now, add `-DENABLE_QT=OFF` to your configure command. In the meantime, a Qt Quick frontend is in the works--check back later!
This is needed for some dependencies that call cc directly (tz):
@@ -74,7 +81,7 @@ Still will not run flawlessly until `mesa-24` is available. Modify CMakeCache.tx
After configuration, you may need to modify `externals/ffmpeg/CMakeFiles/ffmpeg-build/build.make` to use `-j$(nproc)` instead of just `-j`.
`-lc++-experimental` doesn't exist in OpenBSD but the LLVM driver still tries to link against it, to solve just symlink `ln -s /usr/lib/libc++.a /usr/lib/libc++experimental.a`.
`-lc++-experimental` doesn't exist in OpenBSD but the LLVM driver still tries to link against it, to solve just symlink `ln -s /usr/lib/libc++.a /usr/lib/libc++experimental.a`. Builds are currently not working due to lack of `std::jthread` and such, either compile libc++ manually or wait for ports to catch up.
If clang has errors, try using `g++-11`.
@@ -107,6 +114,21 @@ cmake --build build -- -j`nproc`
cmake --install build
```
# DragonFlyBSD
If `libstdc++.so.6` is not found (`GLIBCXX_3.4.30`) then attempt:
```sh
rm /usr/local/lib/gcc11/libstdc++.so.6
ln -s /usr/local/lib/gcc14/libstdc++.so /usr/local/lib/gcc11/libstdc++.so.6
```
This may have unforeseen consequences of which we don't need to worry about for now.
Default `g++` (and the libstdc++) is too outdated - so install `gcc14` and redirect CMake to the new compiler toolchain `-DCMAKE_CXX_COMPILER=gcc14 -DCMAKE_C_COMPILER=g++14`.
There is also `llvm18` and use `-DCMAKE_CXX_COMPILER=clang++18 -DCMAKE_C_COMPILER=clang18` (note the `18` suffix at the end). NOTE: It doesn't have an updated libcxx so `<span>` will be missing, either build it manually or use gcc.
If build hangs, use `hammer2 bulkfree`.
## MSYS2
`qt6-static` isn't supported yet.
@@ -169,3 +191,9 @@ find ./*/ -name "*.dll" | while read -r dll; do deps "$dll"; done
DirectX 12 is not available - simply copy and paste a random DLL and name it `d3d12.dll`.
Install [Qt6 compatibility libraries](github.com/ANightly/qt6windows7) specifically Qt 6.9.5.
## RedoxOS
The package install may randomly hang at times, in which case it has to be restarted. ALWAYS do a `sudo pkg update` or the chances of it hanging will be close to 90%. If "multiple" installs fail at once, try installing 1 by 1 the packages.
When CMake invokes certain file syscalls - it may sometimes cause crashes or corruptions on the (kernel?) address space - so reboot the system if there is a "hang" in CMake.

View File

@@ -8,6 +8,8 @@ But for new developers you may find that following these guidelines will make ev
Simply put, types/classes are named as `PascalCase`, same for methods and functions like `AddElement`. Variables are named `like_this_snake_case` and constants are `IN_SCREAMING_CASE`.
Except for Qt MOC where `functionName` is preferred.
Template typenames prefer short names like `T`, `I`, `U`, if a longer name is required either `Iterator` or `perform_action` are fine as well.
Macros must always be in `SCREAMING_CASE`. Do not use short letter macros as systems like Solaris will conflict with them; a good rule of thumb is >5 characters per macro - i.e `THIS_MACRO_IS_GOOD`, `AND_ALSO_THIS_ONE`.

View File

@@ -196,7 +196,6 @@ apk add g++ git cmake make mbedtls-dev mbedtls-static mesa-dev qt6-qtbase-dev qt
`mbedtls-static` has to be specified otherwise `libeverest.a` and `libp256m.a` will fail to be found.
</details>
<details>
<summary>Void Linux</summary>
@@ -236,7 +235,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`
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 mbedtls3 vulkan-headers quazip-qt6`
If using FreeBSD 12 or prior, use `devel/pkg-config` instead.
@@ -261,18 +260,23 @@ pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gm
[Caveats](./Caveats.md#openbsd).
</details>
<details>
<summary>DragonFlyBSD</summary>
```sh
pkg install gcc14 git cmake unzip nasm autoconf bash pkgconf ffmpeg glslang gmake jq nlohmann-json enet spirv-tools sdl2 vulkan-utility-libraries vulkan-headers catch2 libfmt openssl liblz4 boost-libs cpp-httplib qt6-base quazip-qt6 unordered-dense libva-vdpau-driver libva-utils libva-intel-driver
```
[Caveats](./Caveats.md#dragonflybsd).
</details>
<details>
<summary>Solaris / OpenIndiana</summary>
Always consult [the OpenIndiana package list](https://pkg.openindiana.org/hipster/en/index.shtml) to cross-verify availability.
Run the usual update + install of essential toolings: `sudo pkg update && sudo pkg install git cmake`.
- **gcc**: `sudo pkg install developer/gcc-14`.
- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`.
Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/lz4 libusb-1 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`.
```sh
sudo pkg install qt6 boost glslang libzip library/lz4 libusb-1 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt
```
[Caveats](./Caveats.md#solaris).
@@ -316,16 +320,16 @@ pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel b
[Caveats](./Caveats.md#haikuos).
</details>
<details>
<summary>RedoxOS</summary>
TODO: Fix syscall crashes (heavy IO stalls and hangup due to net mutexes?)
```sh
sudo pkg update && sudo pkg install git cmake
sudo pkg install ffmpeg6 sdl2 zlib llvm18
sudo pkg update
sudo pkg install git cmake ffmpeg6 sdl2 zlib llvm18
```
[Caveats](./Caveats.md#redoxos).
</details>
## All Done

View File

@@ -160,13 +160,6 @@ if (YUZU_USE_BUNDLED_SIRIT)
AddJsonPackage(sirit-ci)
else()
AddJsonPackage(sirit)
# Change to old-but-more-cacheable debug info on Windows
if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
get_target_property(sirit_opts sirit COMPILE_OPTIONS)
list(FILTER sirit_opts EXCLUDE REGEX "/Zi")
list(APPEND sirit_opts "/Z7")
set_target_properties(sirit PROPERTIES COMPILE_OPTIONS "${sirit_opts}")
endif()
if(MSVC AND CXX_CLANG)
target_compile_options(siritobj PRIVATE -Wno-error=unused-command-line-argument)
endif()

View File

@@ -25,18 +25,26 @@ if (UNIX AND NOT ANDROID)
if (NOT APPLE)
# In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so
if(PLATFORM_SUN)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
X11
"/usr/lib/xorg/amd64/libdrm.so")
find_library(LIBDRM_LIB libdrm PATHS /usr/lib/64 /usr/lib/amd64 /usr/lib)
if(LIBDRM_LIB)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
X11
"${LIBDRM_LIB}")
message(STATUS "Found libdrm at: ${LIBDRM_LIB}")
else()
message(WARNING "libdrm not found, disabling libdrm support")
list(APPEND FFmpeg_HWACCEL_FLAGS
--disable-libdrm)
endif()
else()
pkg_check_modules(LIBDRM libdrm REQUIRED)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
${LIBDRM_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${LIBDRM_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-libdrm)
endif()
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-libdrm)
endif()
if(LIBVA_FOUND)
@@ -89,7 +97,7 @@ if (UNIX AND NOT ANDROID)
endif(CUDA_FOUND)
endif()
if (VDPAU_FOUND)
if (VDPAU_FOUND AND NOT APPLE)
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-vdpau
--enable-hwaccel=h264_vdpau
@@ -247,11 +255,19 @@ else()
SYSTEM_THREADS)
set(FFmpeg_BUILD_LIBRARIES ${FFmpeg_LIBRARIES})
# BSD make or Solaris make don't support ffmpeg make-j8
if (PLATFORM_LINUX OR ANDROID OR APPLE OR WIN32 OR PLATFORM_FREEBSD)
set(FFmpeg_MAKE_ARGS -j${SYSTEM_THREADS})
else()
set(FFmpeg_MAKE_ARGS "")
endif()
add_custom_command(
OUTPUT
${FFmpeg_BUILD_LIBRARIES}
COMMAND
make -j${SYSTEM_THREADS}
make ${FFmpeg_MAKE_ARGS}
WORKING_DIRECTORY
${FFmpeg_BUILD_DIR}
)

View File

@@ -15,8 +15,7 @@
"disabled_platforms": [
"freebsd-amd64",
"solaris-amd64",
"openbsd-amd64",
"macos-universal"
"openbsd-amd64"
]
}
}

View File

@@ -5,7 +5,7 @@
"git_host": "git.crueter.xyz",
"artifact": "%VERSION%.tar.gz",
"tag": "%VERSION%",
"hash": "87abb2aeca716d5d77b05317086dbc2f8acfc2f3f76ce4778345ee3df19973e6cd8ecbf16cfab5ad94c9636a6c44fd3588f9aadd3cba89403cfd56c8bec645c5",
"version": "091025"
"hash": "dc37a189a44ce8b5c988ca550582431a6c7eadfd3c6e709bee6277116ee803e714333e85c9e6cbb5c69346a14d6f2cc7ed96e8aa09cc5fb8a89f945059651db6",
"version": "121125"
}
}

View File

@@ -9,11 +9,15 @@ pkgs.mkShellNoCC {
# libraries
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 glslang python3 httplib
cpp-jwt ffmpeg-headless libusb1 cubeb
qt6.full # eden
SDL2 # eden-cli
discord-rpc gamemode # optional components
spirv-tools spirv-headers vulkan-loader unzip mbedtls
glslang python3 httplib cpp-jwt ffmpeg-headless
libusb1 cubeb
# eden
qt6.qtbase qt6.qtmultimedia qt6.qtwayland qt6.qttools
qt6.qtwebengine qt6.qt5compat
# eden-cli
SDL2
# optional components
discord-rpc gamemode
];
}

View File

@@ -35,7 +35,6 @@ if (MSVC AND NOT CXX_CLANG)
# /W4 - Level 4 warnings
# /MP - Multi-threaded compilation
# /Zi - Output debugging information
# /Zm - Specifies the precompiled header memory allocation limit
# /Zo - Enhanced debug info for optimized builds
# /permissive- - Enables stricter C++ standards conformance checks
@@ -98,11 +97,6 @@ if (MSVC AND NOT CXX_CLANG)
)
endif()
if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
endif()
if (ARCHITECTURE_x86_64)
add_compile_options(/QIntel-jcc-erratum)
endif()
@@ -127,7 +121,7 @@ else()
-Werror=unused
-Wno-attributes
-Wno-invalid-offsetof
$<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>
-Wno-unused-parameter
-Wno-missing-field-initializers
)
@@ -176,13 +170,27 @@ else()
add_compile_definitions(_FILE_OFFSET_BITS=64)
endif()
if (YUZU_STATIC_BUILD)
add_compile_definitions(QT_STATICPLUGIN)
# macos doesn't even let you make static executables... wtf?
if (NOT APPLE)
add_compile_options(-static)
if (YUZU_STATIC_BUILD)
# yuzu-cmd requires us to explicitly link libpthread, libgcc, and libstdc++ as static
# At a guess, it's probably because Qt handles the Qt executable for us, whereas this does not
add_link_options(-static -lpthread)
add_link_options(-static-libgcc -static-libstdc++)
endif()
endif()
endif()
if (MINGW)
add_compile_definitions(MINGW_HAS_SECURE_API)
add_compile_options("-msse4.1")
if (MINGW_STATIC_BUILD)
add_compile_definitions(QT_STATICPLUGIN)
add_compile_options("-static")
# Only windows has this requirement, thanks windows
if (WIN32 AND ARCHITECTURE_x86_64)
add_compile_options("-msse4.1")
endif()
endif()

View File

@@ -16,11 +16,15 @@ import java.io.FileOutputStream
import java.security.KeyStore
import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509TrustManager
import android.content.res.Configuration
import android.os.LocaleList
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
import org.yuzu.yuzu_emu.utils.DocumentsTree
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
import org.yuzu.yuzu_emu.utils.Log
import org.yuzu.yuzu_emu.utils.PowerStateUpdater
import java.util.Locale
fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir
@@ -73,5 +77,38 @@ class YuzuApplication : Application() {
val appContext: Context
get() = application.applicationContext
private val LANGUAGE_CODES = arrayOf(
"system", "en", "es", "fr", "de", "it", "pt", "pt-BR", "ru", "ja", "ko",
"zh-CN", "zh-TW", "pl", "cs", "nb", "hu", "uk", "vi", "id", "ar", "ckb", "fa", "he", "sr"
)
fun applyLanguage(context: Context): Context {
val languageIndex = IntSetting.APP_LANGUAGE.getInt()
val langCode = if (languageIndex in LANGUAGE_CODES.indices) {
LANGUAGE_CODES[languageIndex]
} else {
"system"
}
if (langCode == "system") {
return context
}
val locale = when {
langCode.contains("-") -> {
val parts = langCode.split("-")
Locale.Builder().setLanguage(parts[0]).setRegion(parts[1]).build()
}
else -> Locale.Builder().setLanguage(langCode).build()
}
Locale.setDefault(locale)
val config = Configuration(context.resources.configuration)
config.setLocales(LocaleList(locale))
return context.createConfigurationContext(config)
}
}
}

View File

@@ -86,6 +86,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
private var foregroundService: Intent? = null
override fun attachBaseContext(base: Context) {
super.attachBaseContext(YuzuApplication.applyLanguage(base))
}
override fun onCreate(savedInstanceState: Bundle?) {
Log.gameLaunched = true
ThemeHelper.setTheme(this)

View File

@@ -29,7 +29,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
SYNC_MEMORY_OPERATIONS("sync_memory_operations"),
BUFFER_REORDER_DISABLE("disable_buffer_reorder"),
RENDERER_DEBUG("debug"),
RENDERER_FORCE_UNSUPPORTED_EXTENSIONS("force_unsupported_extensions"),
RENDERER_PROVOKING_VERTEX("provoking_vertex"),
RENDERER_DESCRIPTOR_INDEXING("descriptor_indexing"),
RENDERER_SAMPLE_SHADING("sample_shading"),

View File

@@ -32,6 +32,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
MAX_ANISOTROPY("max_anisotropy"),
THEME("theme"),
THEME_MODE("theme_mode"),
APP_LANGUAGE("app_language"),
OVERLAY_SCALE("control_scale"),
OVERLAY_OPACITY("control_opacity"),
LOCK_DRAWER("lock_drawer"),

View File

@@ -139,13 +139,6 @@ abstract class SettingsItem(
valuesId = R.array.dynaStateValues
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_FORCE_UNSUPPORTED_EXTENSIONS,
titleId = R.string.force_unsupported_extensions,
descriptionId = R.string.force_unsupported_extensions_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_PROVOKING_VERTEX,
@@ -674,10 +667,11 @@ abstract class SettingsItem(
)
)
put(
SliderSetting(
SpinBoxSetting(
IntSetting.CPU_TICKS,
titleId = R.string.cpu_ticks,
descriptionId = 0,
valueHint = R.string.cpu_ticks,
min = 77,
max = 65535
)
@@ -763,6 +757,15 @@ abstract class SettingsItem(
titleId = R.string.enable_update_checks,
)
)
put(
SingleChoiceSetting(
IntSetting.APP_LANGUAGE,
titleId = R.string.app_language,
descriptionId = R.string.app_language_description,
choicesId = R.array.appLanguageNames,
valuesId = R.array.appLanguageValues
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_DEBUG,

View File

@@ -1,8 +1,13 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.ui
import android.content.Context
import org.yuzu.yuzu_emu.YuzuApplication
import android.os.Bundle
import android.view.View
import android.view.ViewGroup.MarginLayoutParams
@@ -24,6 +29,7 @@ import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
import org.yuzu.yuzu_emu.fragments.ResetSettingsDialogFragment
import org.yuzu.yuzu_emu.utils.*
import org.yuzu.yuzu_emu.utils.collect
class SettingsActivity : AppCompatActivity() {
private lateinit var binding: ActivitySettingsBinding
@@ -32,6 +38,10 @@ class SettingsActivity : AppCompatActivity() {
private val settingsViewModel: SettingsViewModel by viewModels()
override fun attachBaseContext(base: Context) {
super.attachBaseContext(YuzuApplication.applyLanguage(base))
}
override fun onCreate(savedInstanceState: Bundle?) {
ThemeHelper.setTheme(this)
@@ -125,6 +135,16 @@ class SettingsActivity : AppCompatActivity() {
NativeConfig.savePerGameConfig()
NativeConfig.unloadPerGameConfig()
}
if (settingsViewModel.shouldRecreateForLanguageChange.value) {
settingsViewModel.setShouldRecreateForLanguageChange(false)
val relaunchIntent = packageManager?.getLaunchIntentForPackage(packageName)
if (relaunchIntent != null) {
relaunchIntent.addFlags(android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK or android.content.Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(relaunchIntent)
android.os.Process.killProcess(android.os.Process.myPid())
}
}
}
}

View File

@@ -425,6 +425,14 @@ class SettingsAdapter(
position
).show(fragment.childFragmentManager, SettingsDialogFragment.TAG)
// reset language if detected
if (item.setting.key == "app_language") {
// recreate page apply language change instantly
fragment.requireActivity().recreate()
settingsViewModel.setShouldRecreateForLanguageChange(true)
}
return true
}

View File

@@ -14,6 +14,9 @@ import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.MotionEvent
import android.os.Handler
import android.os.Looper
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
@@ -197,6 +200,54 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
updateValidity(newValue)
}
fun attachRepeat(button: View, delta: Int) {
val handler = Handler(Looper.getMainLooper())
var runnable: Runnable? = null
val initialDelay = 400L
val minDelay = 40L
val accelerationFactor = 0.75f
button.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
val current = spinboxBinding.editValue.text.toString().toIntOrNull() ?: currentValue
val newValue = (current + delta)
spinboxBinding.editValue.setText(newValue.toString())
updateValidity(newValue)
var delay = initialDelay
runnable = object : Runnable {
override fun run() {
val curr = spinboxBinding.editValue.text.toString().toIntOrNull() ?: currentValue
val next = curr + delta
spinboxBinding.editValue.setText(next.toString())
updateValidity(next)
// accelerate
delay = (delay * accelerationFactor).toLong().coerceAtLeast(minDelay)
handler.postDelayed(this, delay)
}
}
handler.postDelayed(runnable!!, initialDelay)
true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
if (runnable != null) {
handler.removeCallbacks(runnable!!)
runnable = null
}
v.performClick()
true
}
else -> false
}
}
}
attachRepeat(spinboxBinding.buttonDecrement, -1)
attachRepeat(spinboxBinding.buttonIncrement, 1)
spinboxBinding.editValue.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
@@ -336,6 +387,12 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
.show()
}
scSetting.setSelectedValue(value)
if (scSetting.setting.key == "app_language") {
settingsViewModel.setShouldRecreateForLanguageChange(true)
// recreate page apply language change instantly
requireActivity().recreate()
}
}
is StringSingleChoiceSetting -> {

View File

@@ -453,7 +453,6 @@ class SettingsFragmentPresenter(
sl.apply {
add(HeaderSetting(R.string.veil_extensions))
add(ByteSetting.RENDERER_DYNA_STATE.key)
add(BooleanSetting.RENDERER_FORCE_UNSUPPORTED_EXTENSIONS.key)
add(BooleanSetting.RENDERER_PROVOKING_VERTEX.key)
add(BooleanSetting.RENDERER_DESCRIPTOR_INDEXING.key)
add(BooleanSetting.RENDERER_SAMPLE_SHADING.key)
@@ -1031,8 +1030,10 @@ class SettingsFragmentPresenter(
override fun reset() = IntSetting.THEME.setInt(defaultValue)
}
add(HeaderSetting(R.string.app_settings))
add(IntSetting.APP_LANGUAGE.key)
if (NativeLibrary.isUpdateCheckerEnabled()) {
add(HeaderSetting(R.string.app_settings))
add(BooleanSetting.ENABLE_UPDATE_CHECKS.key)
}

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -54,6 +57,8 @@ class SettingsViewModel : ViewModel() {
private val _shouldShowResetInputDialog = MutableStateFlow(false)
val shouldShowResetInputDialog = _shouldShowResetInputDialog.asStateFlow()
private val _shouldRecreateForLanguageChange = MutableStateFlow(false)
val shouldRecreateForLanguageChange = _shouldRecreateForLanguageChange.asStateFlow()
fun setShouldRecreate(value: Boolean) {
_shouldRecreate.value = value
}
@@ -103,6 +108,10 @@ class SettingsViewModel : ViewModel() {
_shouldShowResetInputDialog.value = value
}
fun setShouldRecreateForLanguageChange(value: Boolean) {
_shouldRecreateForLanguageChange.value = value
}
fun getCurrentDeviceParams(defaultParams: ParamPackage): ParamPackage =
try {
InputHandler.registeredControllers[currentDevice]

View File

@@ -4,6 +4,7 @@
package org.yuzu.yuzu_emu.ui.main
import android.content.Intent
import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.view.View
@@ -53,6 +54,7 @@ import org.yuzu.yuzu_emu.activities.EmulationActivity
import kotlin.text.compareTo
import androidx.core.net.toUri
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
import org.yuzu.yuzu_emu.YuzuApplication
class MainActivity : AppCompatActivity(), ThemeProvider {
private lateinit var binding: ActivityMainBinding
@@ -68,6 +70,10 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
private val CHECKED_DECRYPTION = "CheckedDecryption"
private var checkedDecryption = false
override fun attachBaseContext(base: Context) {
super.attachBaseContext(YuzuApplication.applyLanguage(base))
}
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }

View File

@@ -62,6 +62,7 @@ namespace AndroidSettings {
Settings::Setting<s32> theme_mode{linkage, -1, "theme_mode", Settings::Category::Android};
Settings::Setting<bool> black_backgrounds{linkage, false, "black_backgrounds",
Settings::Category::Android};
Settings::Setting<s32> app_language{linkage, 0, "app_language", Settings::Category::Android};
Settings::Setting<bool> enable_update_checks{linkage, true, "enable_update_checks",
Settings::Category::Android};

View File

@@ -4,6 +4,8 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#define VMA_IMPLEMENTATION
#include "video_core/vulkan_common/vma.h"
#include <codecvt>
#include <locale>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

@@ -391,6 +391,61 @@
<item>2</item>
</integer-array>
<string-array name="appLanguageNames">
<item>@string/app_language_system</item>
<item>@string/app_language_english</item>
<item>@string/app_language_spanish</item>
<item>@string/app_language_french</item>
<item>@string/app_language_german</item>
<item>@string/app_language_italian</item>
<item>@string/app_language_portuguese</item>
<item>@string/app_language_brazilian_portuguese</item>
<item>@string/app_language_russian</item>
<item>@string/app_language_japanese</item>
<item>@string/app_language_korean</item>
<item>@string/app_language_simplified_chinese</item>
<item>@string/app_language_traditional_chinese</item>
<item>@string/app_language_polish</item>
<item>@string/app_language_czech</item>
<item>@string/app_language_norwegian</item>
<item>@string/app_language_hungarian</item>
<item>@string/app_language_ukrainian</item>
<item>@string/app_language_vietnamese</item>
<item>@string/app_language_indonesian</item>
<item>@string/app_language_arabic</item>
<item>@string/app_language_central_kurdish</item>
<item>@string/app_language_persian</item>
<item>@string/app_language_hebrew</item>
<item>@string/app_language_serbian</item>
</string-array>
<integer-array name="appLanguageValues">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
<item>10</item>
<item>11</item>
<item>12</item>
<item>13</item>
<item>14</item>
<item>15</item>
<item>16</item>
<item>17</item>
<item>18</item>
<item>19</item>
<item>20</item>
<item>21</item>
<item>22</item>
<item>23</item>
<item>24</item>
</integer-array>
<string-array name="outputEngineEntries">
<item>@string/auto</item>
<item>@string/oboe</item>

View File

@@ -94,8 +94,6 @@
<string name="dyna_state">Extended Dynamic State</string>
<string name="dyna_state_description">Controls the number of features that can be used in Extended Dynamic State. Higher numbers allow for more features and can increase performance, but may cause issues with some drivers and vendors. The default value may vary depending on your system and hardware capabilities. This value can be changed until stability and a better visual quality are achieved.</string>
<string name="disabled">Disabled</string>
<string name="force_unsupported_extensions">Force Unsupported Extensions</string>
<string name="force_unsupported_extensions_description">Bypasses all driver workarounds and safety checks. May cause crashes, graphical glitches, or instability. Only enable for testing purposes.</string>
<string name="provoking_vertex">Provoking Vertex</string>
<string name="provoking_vertex_description">Improves lighting and vertex handling in certain games. Only supported on Vulkan 1.0+ GPUs.</string>
<string name="descriptor_indexing">Descriptor Indexing</string>
@@ -1030,6 +1028,35 @@
<string name="use_black_backgrounds">Black backgrounds</string>
<string name="use_black_backgrounds_description">When using the dark theme, apply black backgrounds.</string>
<!-- App Language -->
<string name="app_language">App Language</string>
<string name="app_language_description">Change the language of the app interface</string>
<string name="app_language_system">Follow System</string>
<string name="app_language_english">English</string>
<string name="app_language_spanish">Español</string>
<string name="app_language_french">Français</string>
<string name="app_language_german">Deutsch</string>
<string name="app_language_italian">Italiano</string>
<string name="app_language_portuguese">Português</string>
<string name="app_language_brazilian_portuguese">Português do Brasil</string>
<string name="app_language_russian">Русский</string>
<string name="app_language_japanese">日本語</string>
<string name="app_language_korean">한국어</string>
<string name="app_language_simplified_chinese">简体中文</string>
<string name="app_language_traditional_chinese">繁體中文</string>
<string name="app_language_polish">Polski</string>
<string name="app_language_czech">Čeština</string>
<string name="app_language_norwegian">Norsk bokmål</string>
<string name="app_language_hungarian">Magyar</string>
<string name="app_language_ukrainian">Українська</string>
<string name="app_language_vietnamese">Tiếng Việt</string>
<string name="app_language_indonesian">Bahasa Indonesia</string>
<string name="app_language_arabic">العربية</string>
<string name="app_language_central_kurdish">کوردیی ناوەندی</string>
<string name="app_language_persian">فارسی</string>
<string name="app_language_hebrew">עברית</string>
<string name="app_language_serbian">Српски</string>
<!-- Static Themes -->
<string name="static_theme_color">Theme Color</string>
<string name="eden_theme">Eden (Default)</string>

View File

@@ -84,6 +84,7 @@ static void UpdateReverbEffectParameter(const ReverbInfo::ParameterVersion2& par
const auto pow_10 = [](f32 val) -> f32 {
return (val >= 0.0f) ? 1.0f : (val <= -5.3f) ? 0.0f : std::pow(10.0f, val);
};
const auto cos = [](f32 degrees) -> f32 {
return std::cos(degrees * std::numbers::pi_v<f32> / 180.0f);
};
@@ -91,26 +92,39 @@ static void UpdateReverbEffectParameter(const ReverbInfo::ParameterVersion2& par
static bool unk_initialized{false};
static Common::FixedPoint<50, 14> unk_value{};
const auto sample_rate{Common::FixedPoint<50, 14>::from_base(params.sample_rate)};
const auto pre_delay_time{Common::FixedPoint<50, 14>::from_base(params.pre_delay)};
auto sample_rate = Common::FixedPoint<50, 14>::from_base(params.sample_rate);
if (sample_rate.to_float() < 1.0f) sample_rate = Common::FixedPoint<50, 14>(1.0f);
auto pre_delay_time = Common::FixedPoint<50, 14>::from_base(params.pre_delay);
if (pre_delay_time.to_float() < 0.0f) pre_delay_time = Common::FixedPoint<50, 14>(0.0f);
for (u32 i = 0; i < ReverbInfo::MaxDelayTaps; i++) {
auto early_delay{
((pre_delay_time + EarlyDelayTimes[params.early_mode][i]) * sample_rate).to_int()};
early_delay = (std::min)(early_delay, state.pre_delay_line.sample_count_max);
state.early_delay_times[i] = early_delay + 1;
state.early_gains[i] = Common::FixedPoint<50, 14>::from_base(params.early_gain) *
EarlyDelayGains[params.early_mode][i];
int target_delay = ((pre_delay_time + EarlyDelayTimes[params.early_mode][i]) * sample_rate).to_int();
if (target_delay < 0) target_delay = 0;
if (target_delay > state.pre_delay_line.sample_count_max) target_delay = state.pre_delay_line.sample_count_max;
int old_delay = state.early_delay_times[i] - 1;
int smooth_delay = old_delay + (target_delay - old_delay) / 4;
state.early_delay_times[i] = smooth_delay + 1;
auto target_gain = Common::FixedPoint<50, 14>::from_base(params.early_gain) * EarlyDelayGains[params.early_mode][i];
if (target_gain.to_float() < 0.0f) target_gain = Common::FixedPoint<50, 14>(0.0f);
if (target_gain.to_float() > 1.0f) target_gain = Common::FixedPoint<50, 14>(1.0f);
state.early_gains[i] = state.early_gains[i] + (target_gain - state.early_gains[i]) / 4;
}
if (params.channel_count == 2) {
state.early_gains[4] * 0.5f;
state.early_gains[5] * 0.5f;
state.early_gains[4] *= Common::FixedPoint<50, 14>(0.5f);
state.early_gains[5] *= Common::FixedPoint<50, 14>(0.5f);
}
auto pre_time{
((pre_delay_time + EarlyDelayTimes[params.early_mode][10]) * sample_rate).to_int()};
state.pre_delay_time = (std::min)(pre_time, state.pre_delay_line.sample_count_max);
int target_pre_time = ((pre_delay_time + EarlyDelayTimes[params.early_mode][10]) * sample_rate).to_int();
if (target_pre_time < 0) target_pre_time = 0;
if (target_pre_time > state.pre_delay_line.sample_count_max) target_pre_time = state.pre_delay_line.sample_count_max;
int old_pre_time = state.pre_delay_time;
state.pre_delay_time = old_pre_time + (target_pre_time - old_pre_time) / 4;
if (!unk_initialized) {
unk_value = cos((1280.0f / sample_rate).to_float());
@@ -118,45 +132,64 @@ static void UpdateReverbEffectParameter(const ReverbInfo::ParameterVersion2& par
}
for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
const auto fdn_delay{(FdnDelayTimes[params.late_mode][i] * sample_rate).to_int()};
state.fdn_delay_lines[i].sample_count =
(std::min)(fdn_delay, state.fdn_delay_lines[i].sample_count_max);
state.fdn_delay_lines[i].buffer_end =
&state.fdn_delay_lines[i].buffer[state.fdn_delay_lines[i].sample_count - 1];
int target_fdn_delay = (FdnDelayTimes[params.late_mode][i] * sample_rate).to_int();
if (target_fdn_delay < 0) target_fdn_delay = 0;
if (target_fdn_delay > state.fdn_delay_lines[i].sample_count_max) target_fdn_delay = state.fdn_delay_lines[i].sample_count_max;
const auto decay_delay{(DecayDelayTimes[params.late_mode][i] * sample_rate).to_int()};
state.decay_delay_lines[i].sample_count =
(std::min)(decay_delay, state.decay_delay_lines[i].sample_count_max);
state.decay_delay_lines[i].buffer_end =
&state.decay_delay_lines[i].buffer[state.decay_delay_lines[i].sample_count - 1];
int old_fdn = state.fdn_delay_lines[i].sample_count;
state.fdn_delay_lines[i].sample_count = old_fdn + (target_fdn_delay - old_fdn) / 4;
state.fdn_delay_lines[i].buffer_end = &state.fdn_delay_lines[i].buffer[state.fdn_delay_lines[i].sample_count - 1];
state.decay_delay_lines[i].decay =
0.5999755859375f * (1.0f - Common::FixedPoint<50, 14>::from_base(params.colouration));
int target_decay_delay = (DecayDelayTimes[params.late_mode][i] * sample_rate).to_int();
if (target_decay_delay < 0) target_decay_delay = 0;
if (target_decay_delay > state.decay_delay_lines[i].sample_count_max) target_decay_delay = state.decay_delay_lines[i].sample_count_max;
auto a{(Common::FixedPoint<50, 14>(state.fdn_delay_lines[i].sample_count_max) +
state.decay_delay_lines[i].sample_count_max) *
-3};
auto b{a / (Common::FixedPoint<50, 14>::from_base(params.decay_time) * sample_rate)};
Common::FixedPoint<50, 14> c{0.0f};
Common::FixedPoint<50, 14> d{0.0f};
auto hf_decay_ratio{Common::FixedPoint<50, 14>::from_base(params.high_freq_decay_ratio)};
int old_decay = state.decay_delay_lines[i].sample_count;
state.decay_delay_lines[i].sample_count = old_decay + (target_decay_delay - old_decay) / 4;
state.decay_delay_lines[i].buffer_end = &state.decay_delay_lines[i].buffer[state.decay_delay_lines[i].sample_count - 1];
if (hf_decay_ratio > 0.99493408203125f) {
auto colouration = Common::FixedPoint<50, 14>::from_base(params.colouration);
if (colouration.to_float() < 0.0f) colouration = Common::FixedPoint<50, 14>(0.0f);
if (colouration.to_float() > 1.0f) colouration = Common::FixedPoint<50, 14>(1.0f);
state.decay_delay_lines[i].decay = state.decay_delay_lines[i].decay + (0.5999755859375f * (1.0f - colouration) - state.decay_delay_lines[i].decay) / 4;
auto decay_time_fp = Common::FixedPoint<50, 14>::from_base(params.decay_time);
if (decay_time_fp.to_float() <= 0.0f) decay_time_fp = Common::FixedPoint<50, 14>(0.0001f);
auto a = (Common::FixedPoint<50, 14>(state.fdn_delay_lines[i].sample_count_max) + state.decay_delay_lines[i].sample_count_max) * -3;
auto b = a / (decay_time_fp * sample_rate);
auto hf_decay_ratio = Common::FixedPoint<50, 14>::from_base(params.high_freq_decay_ratio);
if (hf_decay_ratio.to_float() < 0.001f) hf_decay_ratio = Common::FixedPoint<50, 14>(0.001f);
if (hf_decay_ratio.to_float() > 0.999f) hf_decay_ratio = Common::FixedPoint<50, 14>(0.999f);
Common::FixedPoint<50, 14> c{0.0f}, d{0.0f};
if (hf_decay_ratio.to_float() > 0.9949f) {
c = 0.0f;
d = 1.0f;
} else {
const auto e{
pow_10(((((1.0f / hf_decay_ratio) - 1.0f) * 2) / 100 * (b / 10)).to_float())};
const auto f{1.0f - e};
const auto g{2.0f - (unk_value * e * 2)};
const auto h{std::sqrt(std::pow(g.to_float(), 2.0f) - (std::pow(f, 2.0f) * 4))};
auto e = pow_10(((((1.0f / hf_decay_ratio.to_float()) - 1.0f) * 2) / 100 * (b / 10)).to_float());
if (e < 0.0001f) e = 0.0001f;
if (e > 1.0f) e = 1.0f;
auto f = 1.0f - e;
if (f < 0.0001f) f = 0.0001f;
auto g = 2.0f - (unk_value.to_float() * e * 2);
auto h_sq = g * g - f * f * 4;
if (h_sq < 0.0f) h_sq = 0.0f;
auto h = std::sqrt(h_sq);
c = (g - h) / (f * 2.0f);
d = 1.0f - c;
}
state.hf_decay_prev_gain[i] = c;
state.hf_decay_gain[i] = pow_10((b / 1000).to_float()) * d * 0.70709228515625f;
state.hf_decay_prev_gain[i] = state.hf_decay_prev_gain[i] + (c - state.hf_decay_prev_gain[i]) / 4;
state.hf_decay_gain[i] = state.hf_decay_gain[i] + (pow_10((b / 1000).to_float()) * d * 0.70709228515625f - state.hf_decay_gain[i]) / 4;
state.prev_feedback_output[i] = 0;
}
}
@@ -191,6 +224,8 @@ static void InitializeReverbEffect(const ReverbInfo::ParameterVersion2& params,
const auto center_delay_time{(5 * delay).to_uint_floor()};
state.center_delay_line.Initialize(center_delay_time, 1.0f);
UpdateReverbEffectParameter(params, state);
for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
std::ranges::fill(state.fdn_delay_lines[i].buffer, 0);
std::ranges::fill(state.decay_delay_lines[i].buffer, 0);

View File

@@ -257,6 +257,8 @@ else()
target_link_libraries(common PUBLIC Boost::headers)
endif()
target_link_libraries(common PUBLIC Boost::filesystem)
if (lz4_ADDED)
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
endif()

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -103,46 +106,60 @@ template <>
#else
// Some architectures lack u128, there is no definitive way to check them all without even more macro magic
// so let's just... do this; add your favourite arches once they get u128 support :)
#if (defined(__clang__) || defined(__GNUC__)) && (defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64))
using RealU128 = unsigned __int128;
# define SYNC_VAL_COMPARE_AND_SWAP(p, e, v) __sync_val_compare_and_swap(p, e, v)
# define SYNC_BOOL_COMPARE_AND_SWAP(p, e, v) __sync_bool_compare_and_swap(p, e, v)
# define U128_ZERO_INIT 0
#else
using RealU128 = u128;
# define SYNC_VAL_COMPARE_AND_SWAP(p, e, v) ((*p == e) ? *p = v : *p)
# define SYNC_BOOL_COMPARE_AND_SWAP(p, e, v) ((*p == e) ? (void)(*p = v) : (void)0), true
# define U128_ZERO_INIT {}
#endif
template <typename T>
[[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected) {
return __sync_bool_compare_and_swap(pointer, expected, value);
return SYNC_BOOL_COMPARE_AND_SWAP(pointer, expected, value);
}
[[nodiscard]] inline bool AtomicCompareAndSwap(u64* pointer, u128 value, u128 expected) {
unsigned __int128 value_a;
unsigned __int128 expected_a;
RealU128 value_a;
RealU128 expected_a;
std::memcpy(&value_a, value.data(), sizeof(u128));
std::memcpy(&expected_a, expected.data(), sizeof(u128));
return __sync_bool_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a);
return SYNC_BOOL_COMPARE_AND_SWAP((RealU128*)pointer, expected_a, value_a);
}
template <typename T>
[[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected, T& actual) {
actual = __sync_val_compare_and_swap(pointer, expected, value);
actual = SYNC_VAL_COMPARE_AND_SWAP(pointer, expected, value);
return actual == expected;
}
[[nodiscard]] inline bool AtomicCompareAndSwap(u64* pointer, u128 value, u128 expected,
u128& actual) {
unsigned __int128 value_a;
unsigned __int128 expected_a;
unsigned __int128 actual_a;
[[nodiscard]] inline bool AtomicCompareAndSwap(u64* pointer, u128 value, u128 expected, u128& actual) {
RealU128 value_a;
RealU128 expected_a;
RealU128 actual_a;
std::memcpy(&value_a, value.data(), sizeof(u128));
std::memcpy(&expected_a, expected.data(), sizeof(u128));
actual_a = __sync_val_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a);
actual_a = SYNC_VAL_COMPARE_AND_SWAP((RealU128*)pointer, expected_a, value_a);
std::memcpy(actual.data(), &actual_a, sizeof(u128));
return actual_a == expected_a;
}
[[nodiscard]] inline u128 AtomicLoad128(u64* pointer) {
unsigned __int128 zeros_a = 0;
unsigned __int128 result_a =
__sync_val_compare_and_swap((unsigned __int128*)pointer, zeros_a, zeros_a);
RealU128 zeros_a = U128_ZERO_INIT;
RealU128 result_a = SYNC_VAL_COMPARE_AND_SWAP((RealU128*)pointer, zeros_a, zeros_a);
u128 result;
std::memcpy(result.data(), &result_a, sizeof(u128));
return result;
}
#undef U128_ZERO_INIT
#undef SYNC_VAL_COMPARE_AND_SWAP
#undef SYNC_BOOL_COMPARE_AND_SWAP
#endif

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -12,24 +15,4 @@ namespace Common {
template <typename T>
concept IsContiguousContainer = std::contiguous_iterator<typename T::iterator>;
// TODO: Replace with std::derived_from when the <concepts> header
// is available on all supported platforms.
template <typename Derived, typename Base>
concept DerivedFrom = requires {
std::is_base_of_v<Base, Derived>;
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
};
// TODO: Replace with std::convertible_to when libc++ implements it.
template <typename From, typename To>
concept ConvertibleTo = std::is_convertible_v<From, To>;
// No equivalents in the stdlib
template <typename T>
concept IsArithmetic = std::is_arithmetic_v<T>;
template <typename T>
concept IsIntegral = std::is_integral_v<T>;
} // namespace Common

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2015 Evan Teran
// SPDX-License-Identifier: MIT
@@ -16,6 +19,10 @@
namespace Common {
// No equivalent for "std::arithmetic" in the stdlib
template <typename T>
concept IsArithmetic = std::is_arithmetic_v<T>;
template <size_t I, size_t F>
class FixedPoint;
@@ -392,13 +399,13 @@ public: // binary math operators, effects underlying bit pattern since these
return *this;
}
template <IsIntegral Integer>
template <std::integral Integer>
constexpr FixedPoint& operator>>=(Integer n) {
data_ >>= n;
return *this;
}
template <IsIntegral Integer>
template <std::integral Integer>
constexpr FixedPoint& operator<<=(Integer n) {
data_ <<= n;
return *this;
@@ -587,12 +594,12 @@ constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
}
// shift operators
template <size_t I, size_t F, IsIntegral Integer>
template <size_t I, size_t F, std::integral Integer>
constexpr FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) {
lhs <<= rhs;
return lhs;
}
template <size_t I, size_t F, IsIntegral Integer>
template <size_t I, size_t F, std::integral Integer>
constexpr FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) {
lhs >>= rhs;
return lhs;

View File

@@ -14,16 +14,29 @@ namespace fs = std::filesystem;
fs::path GetKvdbPath()
{
return GetLegacyPath(EmuPath::RyujinxDir) / "bis" / "system" / "save" / "8000000000000000" / "0"
return GetKvdbPath(GetLegacyPath(EmuPath::RyujinxDir));
}
fs::path GetKvdbPath(const fs::path& path) {
return path / "bis" / "system" / "save" / "8000000000000000" / "0"
/ "imkvdb.arc";
}
fs::path GetRyuPathFromSavePath(const fs::path& path) {
// This is a horrible hack, but I cba to find something better
return path.parent_path().parent_path().parent_path().parent_path().parent_path();
}
fs::path GetRyuSavePath(const u64 &save_id)
{
return GetRyuSavePath(GetLegacyPath(EmuPath::RyujinxDir), save_id);
}
std::filesystem::path GetRyuSavePath(const std::filesystem::path& path, 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";
// TODO: what's the difference between 0 and 1?
return path / "bis" / "user" / "save" / hex / "0";
}
IMENReadResult ReadKvdb(const fs::path &path, std::vector<IMEN> &imens)

View File

@@ -7,16 +7,17 @@
#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);
std::filesystem::path GetKvdbPath();
std::filesystem::path GetKvdbPath(const std::filesystem::path &path);
std::filesystem::path GetRyuPathFromSavePath(const std::filesystem::path &path);
std::filesystem::path GetRyuSavePath(const u64 &save_id);
std::filesystem::path GetRyuSavePath(const std::filesystem::path &path, const u64 &save_id);
enum class IMENReadResult {
Nonexistent, // ryujinx not found
@@ -35,6 +36,6 @@ struct IMEN
static_assert(sizeof(IMEN) == 0x10, "IMEN has incorrect size.");
IMENReadResult ReadKvdb(const fs::path &path, std::vector<IMEN> &imens);
IMENReadResult ReadKvdb(const std::filesystem::path &path, std::vector<IMEN> &imens);
} // namespace Common::FS

View File

@@ -4,10 +4,12 @@
#include "symlink.h"
#ifdef _WIN32
#include <windows.h>
#include <fmt/format.h>
#include <windows.h>
#endif
#include <boost/filesystem.hpp>
namespace fs = std::filesystem;
// The sole purpose of this file is to treat symlinks like symlinks on POSIX,
@@ -15,29 +17,40 @@ namespace fs = std::filesystem;
// 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.
// And no, they do NOT provide a standard API for this (at least to my knowledge).
// CreateSymbolicLink, even when EXPLICITLY TOLD to create a junction, still fails
// because of their security policy.
// I don't know what kind of drugs the Windows developers have been on since NT started.
// Microsoft still has not implemented any of this in their std::filesystem implemenation,
// which ALSO means that it DOES NOT FOLLOW ANY DIRECTORY JUNCTIONS... AT ALL.
// Nor does any of their command line utilities or APIs. So you're quite literally
// on your own.
namespace Common::FS {
bool CreateSymlink(const fs::path &from, const fs::path &to)
bool CreateSymlink(fs::path from, fs::path to)
{
#ifdef _WIN32
const std::string command = fmt::format("mklink /J {} {}", to.string(), from.string());
return system(command.c_str()) == 0;
#else
from.make_preferred();
to.make_preferred();
std::error_code ec;
fs::create_directory_symlink(from, to, ec);
return !ec;
#ifdef _WIN32
if (ec) {
const std::string command = fmt::format("mklink /J \"{}\" \"{}\"",
to.string(),
from.string());
return system(command.c_str()) == 0;
}
#endif
return !ec;
}
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
return boost::filesystem::is_symlink(boost::filesystem::path{path});
}
} // namespace Common::FS

View File

@@ -6,7 +6,7 @@
#include <filesystem>
namespace Common::FS {
bool CreateSymlink(const std::filesystem::path &from, const std::filesystem::path &to);
bool CreateSymlink(std::filesystem::path from, std::filesystem::path to);
bool IsSymlink(const std::filesystem::path &path);
} // namespace Common::FS

View File

@@ -1,11 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <fstream>
#include <vector>
#include "common/heap_tracker.h"
#include "common/logging/log.h"
#include "common/assert.h"
@@ -37,8 +36,6 @@ HeapTracker::~HeapTracker() = default;
void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length,
MemoryPermission perm, bool is_separate_heap) {
bool rebuild_required = false;
// When mapping other memory, map pages immediately.
if (!is_separate_heap) {
m_buffer.Map(virtual_offset, host_offset, length, perm, false);
@@ -60,29 +57,11 @@ void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length,
// Insert into mappings.
m_map_count++;
const auto it = m_mappings.insert(*map);
// Update tick before possible rebuild.
it->tick = m_tick++;
// Check if we need to rebuild.
if (m_resident_map_count >= m_max_resident_map_count) {
rebuild_required = true;
}
// Map the area.
m_buffer.Map(it->vaddr, it->paddr, it->size, it->perm, false);
// This map is now resident.
it->is_resident = true;
m_resident_map_count++;
m_resident_mappings.insert(*it);
m_mappings.insert(*map);
}
if (rebuild_required) {
// A rebuild was required, so perform it now.
this->RebuildSeparateHeapAddressSpace();
}
// Finally, map.
this->DeferredMapSeparateHeap(virtual_offset);
}
void HeapTracker::Unmap(size_t virtual_offset, size_t size, bool is_separate_heap) {
@@ -169,7 +148,6 @@ void HeapTracker::Protect(size_t virtual_offset, size_t size, MemoryPermission p
// Clamp to end.
next = (std::min)(next, end);
// Reprotect, if we need to.
if (should_protect) {
m_buffer.Protect(cur, next - cur, perm);
@@ -180,6 +158,51 @@ void HeapTracker::Protect(size_t virtual_offset, size_t size, MemoryPermission p
}
}
bool HeapTracker::DeferredMapSeparateHeap(u8* fault_address) {
if (m_buffer.IsInVirtualRange(fault_address)) {
return this->DeferredMapSeparateHeap(fault_address - m_buffer.VirtualBasePointer());
}
return false;
}
bool HeapTracker::DeferredMapSeparateHeap(size_t virtual_offset) {
bool rebuild_required = false;
{
std::scoped_lock lk{m_lock};
// Check to ensure this was a non-resident separate heap mapping.
const auto it = this->GetNearestHeapMapLocked(virtual_offset);
if (it == m_mappings.end() || it->is_resident) {
return false;
}
// Update tick before possible rebuild.
it->tick = m_tick++;
// Check if we need to rebuild.
if (m_resident_map_count > m_max_resident_map_count) {
rebuild_required = true;
}
// Map the area.
m_buffer.Map(it->vaddr, it->paddr, it->size, it->perm, false);
// This map is now resident.
it->is_resident = true;
m_resident_map_count++;
m_resident_mappings.insert(*it);
}
if (rebuild_required) {
// A rebuild was required, so perform it now.
this->RebuildSeparateHeapAddressSpace();
}
return true;
}
void HeapTracker::RebuildSeparateHeapAddressSpace() {
std::scoped_lock lk{m_rebuild_lock, m_lock};
@@ -190,8 +213,8 @@ void HeapTracker::RebuildSeparateHeapAddressSpace() {
// Despite being worse in theory, this has proven to be better in practice than more
// regularly dumping a smaller amount, because it significantly reduces average case
// lock contention.
const size_t desired_count = (std::min)(m_resident_map_count, m_max_resident_map_count) / 2;
const size_t evict_count = m_resident_map_count - desired_count;
std::size_t const desired_count = (std::min)(m_resident_map_count, m_max_resident_map_count) / 2;
std::size_t const evict_count = m_resident_map_count - desired_count;
auto it = m_resident_mappings.begin();
for (size_t i = 0; i < evict_count && it != m_resident_mappings.end(); i++) {

View File

@@ -521,14 +521,29 @@ public:
#else
fd = memfd_create("HostMemory", 0);
#endif
ASSERT_MSG(fd >= 0, "memfd_create failed: {}", strerror(errno));
// Defined to extend the file with zeros
int ret = ftruncate(fd, backing_size);
ASSERT_MSG(ret == 0, "ftruncate failed with {}, are you out-of-memory?", strerror(errno));
backing_base = static_cast<u8*>(
mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
bool use_anon = false;
if (fd <= 0) {
LOG_WARNING(Common_Memory, "memfd_create: {}", strerror(errno));
use_anon = true;
}
if (!use_anon) {
// Defined to extend the file with zeros
int ret = ftruncate(fd, backing_size);
if (ret != 0) {
LOG_WARNING(Common_Memory, "ftruncate: {} (likely out-of-emory)", strerror(errno));
use_anon = true;
}
}
if (use_anon) {
LOG_WARNING(Common_Memory, "Using private mappings instead of shared ones");
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
if (fd > 0) {
fd = -1;
close(fd);
}
} else {
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
}
ASSERT_MSG(backing_base != MAP_FAILED, "mmap failed: {}", strerror(errno));
// Virtual memory initialization
@@ -552,22 +567,18 @@ public:
free_manager.AllocateBlock(virtual_base + virtual_offset, length);
// Deduce mapping protection flags.
int flags = PROT_NONE;
if (True(perms & MemoryPermission::Read)) {
flags |= PROT_READ;
}
if (True(perms & MemoryPermission::Write)) {
flags |= PROT_WRITE;
}
int prot_flags = PROT_NONE;
if (True(perms & MemoryPermission::Read))
prot_flags |= PROT_READ;
if (True(perms & MemoryPermission::Write))
prot_flags |= PROT_WRITE;
#ifdef ARCHITECTURE_arm64
if (True(perms & MemoryPermission::Execute)) {
flags |= PROT_EXEC;
}
if (True(perms & MemoryPermission::Execute))
prot_flags |= PROT_EXEC;
#endif
void* ret = mmap(virtual_base + virtual_offset, length, flags, MAP_SHARED | MAP_FIXED, fd,
host_offset);
ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
int flags = (fd > 0 ? MAP_SHARED : MAP_PRIVATE) | MAP_FIXED;
void* ret = mmap(virtual_base + virtual_offset, length, prot_flags, flags, fd, host_offset);
ASSERT_MSG(ret != MAP_FAILED, "mmap: {}", strerror(errno));
}
void Unmap(size_t virtual_offset, size_t length) {
@@ -719,7 +730,9 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
ASSERT(virtual_offset % PageAlignment == 0);
ASSERT(host_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size);
if (impl && virtual_base) {
ASSERT(virtual_offset + length <= virtual_size);
}
ASSERT(host_offset + length <= backing_size);
if (length == 0 || !virtual_base || !impl) {
return;
@@ -730,7 +743,9 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap) {
ASSERT(virtual_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size);
if (impl && virtual_base) {
ASSERT(virtual_offset + length <= virtual_size);
}
if (length == 0 || !virtual_base || !impl) {
return;
}
@@ -740,7 +755,9 @@ void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap)
void HostMemory::Protect(size_t virtual_offset, size_t length, MemoryPermission perm) {
ASSERT(virtual_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size);
if (impl && virtual_base) {
ASSERT(virtual_offset + length <= virtual_size);
}
if (length == 0 || !virtual_base || !impl) {
return;
}

View File

@@ -1,11 +1,14 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <type_traits>
#include <fmt/ranges.h>
#include "common/swap.h"
// adapted from https://github.com/fmtlib/fmt/issues/2704
// a generic formatter for enum classes
@@ -20,3 +23,14 @@ struct fmt::formatter<T, std::enable_if_t<std::is_enum_v<T>, char>>
}
};
#endif
template <typename T, typename U>
struct fmt::formatter<SwapStructT<T, U>> {
constexpr auto parse(format_parse_context& ctx) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const SwapStructT<T, U>& reg, FormatContext& ctx) const {
return fmt::format_to(ctx.out(), "{}", T(reg));
}
};

View File

@@ -169,7 +169,7 @@ bool IsFastmemEnabled() {
if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe) {
return bool(values.cpuopt_unsafe_host_mmu);
}
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__)
#if !defined(__APPLE__) && !defined(__linux__) && !defined(__ANDROID__) && !defined(_WIN32)
return false;
#else
return true;
@@ -359,6 +359,9 @@ void RestoreGlobalState(bool is_powered_on) {
for (const auto& reset : values.linkage.restore_functions) {
reset();
}
// Reset per-game flags
values.use_squashed_iterated_blend = false;
}
static bool configuring_global = true;

View File

@@ -296,7 +296,7 @@ struct Values {
Category::CpuDebug};
SwitchableSetting<bool> cpuopt_unsafe_host_mmu{linkage,
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__)
#if !defined(__APPLE__) && !defined(__linux__) && !defined(__ANDROID__) && !defined(_WIN32)
false,
#else
true,
@@ -546,7 +546,15 @@ struct Values {
Category::RendererExtensions,
Specialization::Scalar};
SwitchableSetting<bool> force_unsupported_extensions{linkage, false, "force_unsupported_extensions", Category::RendererExtensions};
SwitchableSetting<bool> vertex_input_dynamic_state{linkage,
#if defined (ANDROID)
false, // Disabled by default on Android (some drivers have issues)
#else
false, // Disabled by default on desktop (some drivers have issues)
#endif
"vertex_input_dynamic_state",
Category::RendererExtensions};
SwitchableSetting<bool> provoking_vertex{linkage, false, "provoking_vertex", Category::RendererExtensions};
SwitchableSetting<bool> descriptor_indexing{linkage, false, "descriptor_indexing", Category::RendererExtensions};
SwitchableSetting<bool> sample_shading{linkage, false, "sample_shading", Category::RendererExtensions, Specialization::Paired};
@@ -561,6 +569,60 @@ struct Values {
false,
&sample_shading};
#ifdef ANDROID
// Shader Float Controls (Android only) - Eden Veil / Extensions
// Force enable VK_KHR_shader_float_controls even if driver has known issues
// Allows fine-tuning float behavior to match Switch/Maxwell or optimize performance
SwitchableSetting<bool> shader_float_controls_force_enable{linkage,
false,
"shader_float_controls_force_enable",
Category::RendererExtensions,
Specialization::Paired};
// Individual float behavior controls (visible only when force_enable is true)
// Multiple can be active simultaneously EXCEPT FTZ and DenormPreserve (mutually exclusive)
//
// Recommended configurations:
// Switch-native: FTZ=ON, RTE=ON, SignedZero=ON (matches Maxwell behavior)
// Performance: FTZ=ON only (fastest)
// Accuracy: DenormPreserve=ON, RTE=ON, SignedZero=ON (slowest, highest precision)
SwitchableSetting<bool> shader_float_ftz{linkage,
false,
"shader_float_ftz",
Category::RendererExtensions,
Specialization::Default,
true,
false,
&shader_float_controls_force_enable};
SwitchableSetting<bool> shader_float_denorm_preserve{linkage,
false,
"shader_float_denorm_preserve",
Category::RendererExtensions,
Specialization::Default,
true,
false,
&shader_float_controls_force_enable};
SwitchableSetting<bool> shader_float_rte{linkage,
false,
"shader_float_rte",
Category::RendererExtensions,
Specialization::Default,
true,
false,
&shader_float_controls_force_enable};
SwitchableSetting<bool> shader_float_signed_zero_inf_nan{linkage,
false,
"shader_float_signed_zero_inf_nan",
Category::RendererExtensions,
Specialization::Default,
true,
false,
&shader_float_controls_force_enable};
#endif
Setting<bool> renderer_debug{linkage, false, "debug", Category::RendererDebug};
Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback",
Category::RendererDebug};
@@ -760,6 +822,9 @@ struct Values {
// Add-Ons
std::map<u64, std::vector<std::string>> disabled_addons;
// Per-game overrides
bool use_squashed_iterated_blend;
};
extern Values values;

View File

@@ -152,6 +152,16 @@ ENUM(SpirvOptimizeMode, Never, OnLoad, Always);
ENUM(GpuOverclock, Low, Medium, High)
ENUM(TemperatureUnits, Celsius, Fahrenheit)
// Shader Float Controls behavior modes
// These control how floating-point denormals and special values are handled in shaders
ENUM(ShaderFloatBehavior,
DriverDefault, // Let driver choose (safest, may not match Switch behavior)
SwitchNative, // Emulate Switch/Maxwell behavior (FTZ + RTE + SignedZero)
FlushToZero, // FTZ only - flush denorms to zero (fastest, some precision loss)
PreserveDenorms, // Preserve denorms (slowest, highest precision)
RoundToEven, // RTE rounding mode (IEEE 754 compliant)
SignedZeroInfNan); // Preserve signed zero, inf, nan (accuracy for edge cases)
template <typename Type>
inline std::string_view CanonicalizeEnum(Type id) {
const auto group = EnumMetadata<Type>::Canonicalizations();

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2012 PPSSPP Project
// SPDX-FileCopyrightText: 2012 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -17,7 +20,17 @@
namespace Common {
#ifdef _MSC_VER
#if defined(__Bitrig__) || defined(__OpenBSD__)
// We'll redefine swap16, swap32, swap64 as inline functions
// but OpenBSD is like "wow I bring my own stuff"
// It would be nice if we could use them without C++ namespace shenanigans
// But alas :)
#undef swap16
#undef swap32
#undef swap64
#endif
#if defined(_MSC_VER)
[[nodiscard]] inline u16 swap16(u16 data) noexcept {
return _byteswap_ushort(data);
}
@@ -28,12 +41,6 @@ namespace Common {
return _byteswap_uint64(data);
}
#elif defined(__clang__) || defined(__GNUC__)
#if defined(__Bitrig__) || defined(__OpenBSD__)
// redefine swap16, swap32, swap64 as inline functions
#undef swap16
#undef swap32
#undef swap64
#endif
[[nodiscard]] inline u16 swap16(u16 data) noexcept {
return __builtin_bswap16(data);
}
@@ -44,7 +51,9 @@ namespace Common {
return __builtin_bswap64(data);
}
#else
// Generic implementation.
// Generic implementation - compiler will optimise these into their respective
// __builtin_byteswapXX() and such; if not, the compiler is stupid and we probably
// have bigger problems to worry about :)
[[nodiscard]] inline u16 swap16(u16 data) noexcept {
return (data >> 8) | (data << 8);
}
@@ -62,33 +71,27 @@ namespace Common {
[[nodiscard]] inline float swapf(float f) noexcept {
static_assert(sizeof(u32) == sizeof(float), "float must be the same size as uint32_t.");
u32 value;
std::memcpy(&value, &f, sizeof(u32));
value = swap32(value);
std::memcpy(&f, &value, sizeof(u32));
return f;
}
[[nodiscard]] inline double swapd(double f) noexcept {
static_assert(sizeof(u64) == sizeof(double), "double must be the same size as uint64_t.");
u64 value;
std::memcpy(&value, &f, sizeof(u64));
value = swap64(value);
std::memcpy(&f, &value, sizeof(u64));
return f;
}
} // Namespace Common
template <typename T, typename F>
struct swap_struct_t {
using swapped_t = swap_struct_t;
struct SwapStructT {
using SwappedT = SwapStructT;
protected:
T value;
@@ -101,137 +104,137 @@ public:
T swap() const {
return swap(value);
}
swap_struct_t() = default;
swap_struct_t(const T& v) : value(swap(v)) {}
SwapStructT() = default;
SwapStructT(const T& v) : value(swap(v)) {}
template <typename S>
swapped_t& operator=(const S& source) {
value = swap(static_cast<T>(source));
SwappedT& operator=(const S& source) {
value = swap(T(source));
return *this;
}
operator s8() const {
return static_cast<s8>(swap());
return s8(swap());
}
operator u8() const {
return static_cast<u8>(swap());
return u8(swap());
}
operator s16() const {
return static_cast<s16>(swap());
return s16(swap());
}
operator u16() const {
return static_cast<u16>(swap());
return u16(swap());
}
operator s32() const {
return static_cast<s32>(swap());
return s32(swap());
}
operator u32() const {
return static_cast<u32>(swap());
return u32(swap());
}
operator s64() const {
return static_cast<s64>(swap());
return s64(swap());
}
operator u64() const {
return static_cast<u64>(swap());
return u64(swap());
}
operator float() const {
return static_cast<float>(swap());
return float(swap());
}
operator double() const {
return static_cast<double>(swap());
return double(swap());
}
// +v
swapped_t operator+() const {
SwappedT operator+() const {
return +swap();
}
// -v
swapped_t operator-() const {
SwappedT operator-() const {
return -swap();
}
// v / 5
swapped_t operator/(const swapped_t& i) const {
SwappedT operator/(const SwappedT& i) const {
return swap() / i.swap();
}
template <typename S>
swapped_t operator/(const S& i) const {
SwappedT operator/(const S& i) const {
return swap() / i;
}
// v * 5
swapped_t operator*(const swapped_t& i) const {
SwappedT operator*(const SwappedT& i) const {
return swap() * i.swap();
}
template <typename S>
swapped_t operator*(const S& i) const {
SwappedT operator*(const S& i) const {
return swap() * i;
}
// v + 5
swapped_t operator+(const swapped_t& i) const {
SwappedT operator+(const SwappedT& i) const {
return swap() + i.swap();
}
template <typename S>
swapped_t operator+(const S& i) const {
return swap() + static_cast<T>(i);
SwappedT operator+(const S& i) const {
return swap() + T(i);
}
// v - 5
swapped_t operator-(const swapped_t& i) const {
SwappedT operator-(const SwappedT& i) const {
return swap() - i.swap();
}
template <typename S>
swapped_t operator-(const S& i) const {
return swap() - static_cast<T>(i);
SwappedT operator-(const S& i) const {
return swap() - T(i);
}
// v += 5
swapped_t& operator+=(const swapped_t& i) {
SwappedT& operator+=(const SwappedT& i) {
value = swap(swap() + i.swap());
return *this;
}
template <typename S>
swapped_t& operator+=(const S& i) {
value = swap(swap() + static_cast<T>(i));
SwappedT& operator+=(const S& i) {
value = swap(swap() + T(i));
return *this;
}
// v -= 5
swapped_t& operator-=(const swapped_t& i) {
SwappedT& operator-=(const SwappedT& i) {
value = swap(swap() - i.swap());
return *this;
}
template <typename S>
swapped_t& operator-=(const S& i) {
value = swap(swap() - static_cast<T>(i));
SwappedT& operator-=(const S& i) {
value = swap(swap() - T(i));
return *this;
}
// ++v
swapped_t& operator++() {
SwappedT& operator++() {
value = swap(swap() + 1);
return *this;
}
// --v
swapped_t& operator--() {
SwappedT& operator--() {
value = swap(swap() - 1);
return *this;
}
// v++
swapped_t operator++(int) {
swapped_t old = *this;
SwappedT operator++(int) {
SwappedT old = *this;
value = swap(swap() + 1);
return old;
}
// v--
swapped_t operator--(int) {
swapped_t old = *this;
SwappedT operator--(int) {
SwappedT old = *this;
value = swap(swap() - 1);
return old;
}
// Comparison
// v == i
bool operator==(const swapped_t& i) const {
bool operator==(const SwappedT& i) const {
return swap() == i.swap();
}
template <typename S>
@@ -240,7 +243,7 @@ public:
}
// v != i
bool operator!=(const swapped_t& i) const {
bool operator!=(const SwappedT& i) const {
return swap() != i.swap();
}
template <typename S>
@@ -249,7 +252,7 @@ public:
}
// v > i
bool operator>(const swapped_t& i) const {
bool operator>(const SwappedT& i) const {
return swap() > i.swap();
}
template <typename S>
@@ -258,7 +261,7 @@ public:
}
// v < i
bool operator<(const swapped_t& i) const {
bool operator<(const SwappedT& i) const {
return swap() < i.swap();
}
template <typename S>
@@ -267,7 +270,7 @@ public:
}
// v >= i
bool operator>=(const swapped_t& i) const {
bool operator>=(const SwappedT& i) const {
return swap() >= i.swap();
}
template <typename S>
@@ -276,7 +279,7 @@ public:
}
// v <= i
bool operator<=(const swapped_t& i) const {
bool operator<=(const SwappedT& i) const {
return swap() <= i.swap();
}
template <typename S>
@@ -285,82 +288,82 @@ public:
}
// logical
swapped_t operator!() const {
SwappedT operator!() const {
return !swap();
}
// bitmath
swapped_t operator~() const {
SwappedT operator~() const {
return ~swap();
}
swapped_t operator&(const swapped_t& b) const {
SwappedT operator&(const SwappedT& b) const {
return swap() & b.swap();
}
template <typename S>
swapped_t operator&(const S& b) const {
SwappedT operator&(const S& b) const {
return swap() & b;
}
swapped_t& operator&=(const swapped_t& b) {
SwappedT& operator&=(const SwappedT& b) {
value = swap(swap() & b.swap());
return *this;
}
template <typename S>
swapped_t& operator&=(const S b) {
SwappedT& operator&=(const S b) {
value = swap(swap() & b);
return *this;
}
swapped_t operator|(const swapped_t& b) const {
SwappedT operator|(const SwappedT& b) const {
return swap() | b.swap();
}
template <typename S>
swapped_t operator|(const S& b) const {
SwappedT operator|(const S& b) const {
return swap() | b;
}
swapped_t& operator|=(const swapped_t& b) {
SwappedT& operator|=(const SwappedT& b) {
value = swap(swap() | b.swap());
return *this;
}
template <typename S>
swapped_t& operator|=(const S& b) {
SwappedT& operator|=(const S& b) {
value = swap(swap() | b);
return *this;
}
swapped_t operator^(const swapped_t& b) const {
SwappedT operator^(const SwappedT& b) const {
return swap() ^ b.swap();
}
template <typename S>
swapped_t operator^(const S& b) const {
SwappedT operator^(const S& b) const {
return swap() ^ b;
}
swapped_t& operator^=(const swapped_t& b) {
SwappedT& operator^=(const SwappedT& b) {
value = swap(swap() ^ b.swap());
return *this;
}
template <typename S>
swapped_t& operator^=(const S& b) {
SwappedT& operator^=(const S& b) {
value = swap(swap() ^ b);
return *this;
}
template <typename S>
swapped_t operator<<(const S& b) const {
SwappedT operator<<(const S& b) const {
return swap() << b;
}
template <typename S>
swapped_t& operator<<=(const S& b) const {
SwappedT& operator<<=(const S& b) const {
value = swap(swap() << b);
return *this;
}
template <typename S>
swapped_t operator>>(const S& b) const {
SwappedT operator>>(const S& b) const {
return swap() >> b;
}
template <typename S>
swapped_t& operator>>=(const S& b) const {
SwappedT& operator>>=(const S& b) const {
value = swap(swap() >> b);
return *this;
}
@@ -370,167 +373,167 @@ public:
// Arithmetic
template <typename S, typename T2, typename F2>
friend S operator+(const S& p, const swapped_t v);
friend S operator+(const S& p, const SwappedT v);
template <typename S, typename T2, typename F2>
friend S operator-(const S& p, const swapped_t v);
friend S operator-(const S& p, const SwappedT v);
template <typename S, typename T2, typename F2>
friend S operator/(const S& p, const swapped_t v);
friend S operator/(const S& p, const SwappedT v);
template <typename S, typename T2, typename F2>
friend S operator*(const S& p, const swapped_t v);
friend S operator*(const S& p, const SwappedT v);
template <typename S, typename T2, typename F2>
friend S operator%(const S& p, const swapped_t v);
friend S operator%(const S& p, const SwappedT v);
// Arithmetic + assignments
template <typename S, typename T2, typename F2>
friend S operator+=(const S& p, const swapped_t v);
friend S operator+=(const S& p, const SwappedT v);
template <typename S, typename T2, typename F2>
friend S operator-=(const S& p, const swapped_t v);
friend S operator-=(const S& p, const SwappedT v);
// Bitmath
template <typename S, typename T2, typename F2>
friend S operator&(const S& p, const swapped_t v);
friend S operator&(const S& p, const SwappedT v);
// Comparison
template <typename S, typename T2, typename F2>
friend bool operator<(const S& p, const swapped_t v);
friend bool operator<(const S& p, const SwappedT v);
template <typename S, typename T2, typename F2>
friend bool operator>(const S& p, const swapped_t v);
friend bool operator>(const S& p, const SwappedT v);
template <typename S, typename T2, typename F2>
friend bool operator<=(const S& p, const swapped_t v);
friend bool operator<=(const S& p, const SwappedT v);
template <typename S, typename T2, typename F2>
friend bool operator>=(const S& p, const swapped_t v);
friend bool operator>=(const S& p, const SwappedT v);
template <typename S, typename T2, typename F2>
friend bool operator!=(const S& p, const swapped_t v);
friend bool operator!=(const S& p, const SwappedT v);
template <typename S, typename T2, typename F2>
friend bool operator==(const S& p, const swapped_t v);
friend bool operator==(const S& p, const SwappedT v);
};
// Arithmetic
template <typename S, typename T, typename F>
S operator+(const S& i, const swap_struct_t<T, F> v) {
S operator+(const S& i, const SwapStructT<T, F> v) {
return i + v.swap();
}
template <typename S, typename T, typename F>
S operator-(const S& i, const swap_struct_t<T, F> v) {
S operator-(const S& i, const SwapStructT<T, F> v) {
return i - v.swap();
}
template <typename S, typename T, typename F>
S operator/(const S& i, const swap_struct_t<T, F> v) {
S operator/(const S& i, const SwapStructT<T, F> v) {
return i / v.swap();
}
template <typename S, typename T, typename F>
S operator*(const S& i, const swap_struct_t<T, F> v) {
S operator*(const S& i, const SwapStructT<T, F> v) {
return i * v.swap();
}
template <typename S, typename T, typename F>
S operator%(const S& i, const swap_struct_t<T, F> v) {
S operator%(const S& i, const SwapStructT<T, F> v) {
return i % v.swap();
}
// Arithmetic + assignments
template <typename S, typename T, typename F>
S& operator+=(S& i, const swap_struct_t<T, F> v) {
S& operator+=(S& i, const SwapStructT<T, F> v) {
i += v.swap();
return i;
}
template <typename S, typename T, typename F>
S& operator-=(S& i, const swap_struct_t<T, F> v) {
S& operator-=(S& i, const SwapStructT<T, F> v) {
i -= v.swap();
return i;
}
// Logical
template <typename S, typename T, typename F>
S operator&(const S& i, const swap_struct_t<T, F> v) {
S operator&(const S& i, const SwapStructT<T, F> v) {
return i & v.swap();
}
// Comparison
template <typename S, typename T, typename F>
bool operator<(const S& p, const swap_struct_t<T, F> v) {
bool operator<(const S& p, const SwapStructT<T, F> v) {
return p < v.swap();
}
template <typename S, typename T, typename F>
bool operator>(const S& p, const swap_struct_t<T, F> v) {
bool operator>(const S& p, const SwapStructT<T, F> v) {
return p > v.swap();
}
template <typename S, typename T, typename F>
bool operator<=(const S& p, const swap_struct_t<T, F> v) {
bool operator<=(const S& p, const SwapStructT<T, F> v) {
return p <= v.swap();
}
template <typename S, typename T, typename F>
bool operator>=(const S& p, const swap_struct_t<T, F> v) {
bool operator>=(const S& p, const SwapStructT<T, F> v) {
return p >= v.swap();
}
template <typename S, typename T, typename F>
bool operator!=(const S& p, const swap_struct_t<T, F> v) {
bool operator!=(const S& p, const SwapStructT<T, F> v) {
return p != v.swap();
}
template <typename S, typename T, typename F>
bool operator==(const S& p, const swap_struct_t<T, F> v) {
bool operator==(const S& p, const SwapStructT<T, F> v) {
return p == v.swap();
}
template <typename T>
struct swap_64_t {
struct Swap64T {
static T swap(T x) {
return static_cast<T>(Common::swap64(x));
return T(Common::swap64(x));
}
};
template <typename T>
struct swap_32_t {
struct Swap32T {
static T swap(T x) {
return static_cast<T>(Common::swap32(x));
return T(Common::swap32(x));
}
};
template <typename T>
struct swap_16_t {
struct Swap16T {
static T swap(T x) {
return static_cast<T>(Common::swap16(x));
return T(Common::swap16(x));
}
};
template <typename T>
struct swap_float_t {
struct SwapFloatT {
static T swap(T x) {
return static_cast<T>(Common::swapf(x));
return T(Common::swapf(x));
}
};
template <typename T>
struct swap_double_t {
struct SwapDoubleT {
static T swap(T x) {
return static_cast<T>(Common::swapd(x));
return T(Common::swapd(x));
}
};
template <typename T>
struct swap_enum_t {
struct SwapEnumT {
static_assert(std::is_enum_v<T>);
using base = std::underlying_type_t<T>;
public:
swap_enum_t() = default;
swap_enum_t(const T& v) : value(swap(v)) {}
SwapEnumT() = default;
SwapEnumT(const T& v) : value(swap(v)) {}
swap_enum_t& operator=(const T& v) {
SwapEnumT& operator=(const T& v) {
value = swap(v);
return *this;
}
@@ -540,22 +543,20 @@ public:
}
explicit operator base() const {
return static_cast<base>(swap(value));
return base(swap(value));
}
protected:
T value{};
// clang-format off
using swap_t = std::conditional_t<
std::is_same_v<base, u16>, swap_16_t<u16>, std::conditional_t<
std::is_same_v<base, s16>, swap_16_t<s16>, std::conditional_t<
std::is_same_v<base, u32>, swap_32_t<u32>, std::conditional_t<
std::is_same_v<base, s32>, swap_32_t<s32>, std::conditional_t<
std::is_same_v<base, u64>, swap_64_t<u64>, std::conditional_t<
std::is_same_v<base, s64>, swap_64_t<s64>, void>>>>>>;
// clang-format on
std::is_same_v<base, u16>, Swap16T<u16>, std::conditional_t<
std::is_same_v<base, s16>, Swap16T<s16>, std::conditional_t<
std::is_same_v<base, u32>, Swap32T<u32>, std::conditional_t<
std::is_same_v<base, s32>, Swap32T<s32>, std::conditional_t<
std::is_same_v<base, u64>, Swap64T<u64>, std::conditional_t<
std::is_same_v<base, s64>, Swap64T<s64>, void>>>>>>;
static T swap(T x) {
return static_cast<T>(swap_t::swap(static_cast<base>(x)));
return T(swap_t::swap(base(x)));
}
};
@@ -581,17 +582,17 @@ struct AddEndian<u8, SwapTag> {
template <>
struct AddEndian<u16, SwapTag> {
using type = swap_struct_t<u16, swap_16_t<u16>>;
using type = SwapStructT<u16, Swap16T<u16>>;
};
template <>
struct AddEndian<u32, SwapTag> {
using type = swap_struct_t<u32, swap_32_t<u32>>;
using type = SwapStructT<u32, Swap32T<u32>>;
};
template <>
struct AddEndian<u64, SwapTag> {
using type = swap_struct_t<u64, swap_64_t<u64>>;
using type = SwapStructT<u64, Swap64T<u64>>;
};
template <>
@@ -601,33 +602,33 @@ struct AddEndian<s8, SwapTag> {
template <>
struct AddEndian<s16, SwapTag> {
using type = swap_struct_t<s16, swap_16_t<s16>>;
using type = SwapStructT<s16, Swap16T<s16>>;
};
template <>
struct AddEndian<s32, SwapTag> {
using type = swap_struct_t<s32, swap_32_t<s32>>;
using type = SwapStructT<s32, Swap32T<s32>>;
};
template <>
struct AddEndian<s64, SwapTag> {
using type = swap_struct_t<s64, swap_64_t<s64>>;
using type = SwapStructT<s64, Swap64T<s64>>;
};
template <>
struct AddEndian<float, SwapTag> {
using type = swap_struct_t<float, swap_float_t<float>>;
using type = SwapStructT<float, SwapFloatT<float>>;
};
template <>
struct AddEndian<double, SwapTag> {
using type = swap_struct_t<double, swap_double_t<double>>;
using type = SwapStructT<double, SwapDoubleT<double>>;
};
template <typename T>
struct AddEndian<T, SwapTag> {
static_assert(std::is_enum_v<T>);
using type = swap_enum_t<T>;
using type = SwapEnumT<T>;
};
// Alias LETag/BETag as KeepTag/SwapTag depending on the system

View File

@@ -1199,10 +1199,10 @@ else()
target_link_libraries(core PUBLIC Boost::headers)
endif()
target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API MbedTLS::mbedcrypto MbedTLS::mbedtls)
if (MINGW)
target_link_libraries(core PRIVATE ws2_32 mswsock wlanapi)
endif()
target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API MbedTLS::mbedcrypto${YUZU_STATIC_SUFFIX} MbedTLS::mbedtls${YUZU_STATIC_SUFFIX})
# if (MINGW)
# target_link_libraries(core PRIVATE ws2_32 mswsock wlanapi)
# endif()
if (ENABLE_WEB_SERVICE)
target_compile_definitions(core PUBLIC ENABLE_WEB_SERVICE)
@@ -1231,6 +1231,7 @@ endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_sources(core PRIVATE
arm/dynarmic/arm_dynarmic.cpp
arm/dynarmic/arm_dynarmic.h
arm/dynarmic/arm_dynarmic_64.cpp
arm/dynarmic/arm_dynarmic_64.h

View File

@@ -0,0 +1,52 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#ifdef __linux__
#include "common/signal_chain.h"
#include "core/arm/dynarmic/arm_dynarmic.h"
#include "core/hle/kernel/k_process.h"
#include "core/memory.h"
namespace Core {
namespace {
thread_local Core::Memory::Memory* g_current_memory{};
std::once_flag g_registered{};
struct sigaction g_old_segv {};
void HandleSigSegv(int sig, siginfo_t* info, void* ctx) {
if (g_current_memory && g_current_memory->InvalidateSeparateHeap(info->si_addr)) {
return;
}
return g_old_segv.sa_sigaction(sig, info, ctx);
}
} // namespace
ScopedJitExecution::ScopedJitExecution(Kernel::KProcess* process) {
g_current_memory = std::addressof(process->GetMemory());
}
ScopedJitExecution::~ScopedJitExecution() {
g_current_memory = nullptr;
}
void ScopedJitExecution::RegisterHandler() {
std::call_once(g_registered, [] {
struct sigaction sa {};
sa.sa_sigaction = &HandleSigSegv;
sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
Common::SigAction(SIGSEGV, std::addressof(sa), std::addressof(g_old_segv));
});
}
} // namespace Core
#endif

View File

@@ -29,4 +29,24 @@ constexpr HaltReason TranslateHaltReason(Dynarmic::HaltReason hr) {
return static_cast<HaltReason>(hr);
}
#ifdef __linux__
class ScopedJitExecution {
public:
explicit ScopedJitExecution(Kernel::KProcess* process);
~ScopedJitExecution();
static void RegisterHandler();
};
#else
class ScopedJitExecution {
public:
explicit ScopedJitExecution(Kernel::KProcess* process) {}
~ScopedJitExecution() {}
static void RegisterHandler() {}
};
#endif
} // namespace Core

View File

@@ -210,9 +210,12 @@ 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 - max in ARM is 128MiB, max in x86_64 is 2GiB
// Solaris doesn't support kPageSize >= 512MiB
// Code cache size
#if defined(ARCHITECTURE_arm64) || defined(__sun__)
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()) {
@@ -292,7 +295,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ArmDynarmic32::MakeJit(Common::PageTable* pa
// Curated optimizations
case Settings::CpuAccuracy::Auto:
config.unsafe_optimizations = true;
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__)
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) || defined(__DragonFly__)
config.fastmem_pointer = std::nullopt;
config.fastmem_exclusive_access = false;
#endif
@@ -341,11 +344,15 @@ bool ArmDynarmic32::IsInThumbMode() const {
}
HaltReason ArmDynarmic32::RunThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Run());
}
HaltReason ArmDynarmic32::StepThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Step());
}
@@ -387,6 +394,7 @@ ArmDynarmic32::ArmDynarmic32(System& system, bool uses_wall_clock, Kernel::KProc
m_cp15(std::make_shared<DynarmicCP15>(*this)), m_core_index{core_index} {
auto& page_table_impl = process->GetPageTable().GetBasePageTable().GetImpl();
m_jit = MakeJit(&page_table_impl);
ScopedJitExecution::RegisterHandler();
}
ArmDynarmic32::~ArmDynarmic32() = default;

View File

@@ -269,9 +269,12 @@ 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 - max in ARM is 128MiB, max in x86_64 is 2GiB
// Solaris doesn't support kPageSize >= 512MiB
// Code cache size
#if defined(ARCHITECTURE_arm64) || defined(__sun__)
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()) {
@@ -351,7 +354,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa
// Safe optimisations
case Settings::CpuAccuracy::Auto:
config.unsafe_optimizations = true;
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__)
#if !defined(__APPLE__) && !defined(__linux__) && !defined(__ANDROID__) && !defined(_WIN32)
config.fastmem_pointer = std::nullopt;
config.fastmem_exclusive_access = false;
#endif
@@ -372,11 +375,15 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa
}
HaltReason ArmDynarmic64::RunThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Run());
}
HaltReason ArmDynarmic64::StepThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Step());
}
@@ -416,6 +423,7 @@ ArmDynarmic64::ArmDynarmic64(System& system, bool uses_wall_clock, Kernel::KProc
auto& page_table = process->GetPageTable().GetBasePageTable();
auto& page_table_impl = page_table.GetImpl();
m_jit = MakeJit(&page_table_impl, page_table.GetAddressSpaceWidth());
ScopedJitExecution::RegisterHandler();
}
ArmDynarmic64::~ArmDynarmic64() = default;

View File

@@ -388,14 +388,6 @@ void ArmNce::SignalInterrupt(Kernel::KThread* thread) {
const std::size_t CACHE_PAGE_SIZE = 4096;
void ArmNce::ClearInstructionCache() {
#if defined(__GNUC__) || defined(__clang__)
void* start = (void*)((uintptr_t)__builtin_return_address(0) & ~(CACHE_PAGE_SIZE - 1));
void* end =
(void*)((uintptr_t)start + CACHE_PAGE_SIZE * 2); // Clear two pages for better coverage
// Prefetch next likely pages
__builtin_prefetch((void*)((uintptr_t)end), 1, 3);
__builtin___clear_cache(static_cast<char*>(start), static_cast<char*>(end));
#endif
#ifdef __aarch64__
// Ensure all previous memory operations complete
asm volatile("dmb ish" ::: "memory");
@@ -405,20 +397,6 @@ void ArmNce::ClearInstructionCache() {
}
void ArmNce::InvalidateCacheRange(u64 addr, std::size_t size) {
#if defined(__GNUC__) || defined(__clang__)
// Align the start address to cache line boundary for better performance
const size_t CACHE_LINE_SIZE = 64;
addr &= ~(CACHE_LINE_SIZE - 1);
// Round up size to nearest cache line
size = (size + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1);
// Prefetch the range to be invalidated
for (size_t offset = 0; offset < size; offset += CACHE_LINE_SIZE) {
__builtin_prefetch((void*)(addr + offset), 1, 3);
}
#endif
this->ClearInstructionCache();
}

View File

@@ -181,14 +181,6 @@ bool InterpreterVisitor::Ordered(size_t size, bool L, bool o0, Reg Rn, Reg Rt) {
const size_t dbytes = datasize / 8;
u64 address = (Rn == Reg::SP) ? this->GetSp() : this->GetReg(Rn);
// Conservative prefetch for atomic ops
if (memop == MemOp::Load) {
__builtin_prefetch(reinterpret_cast<const void*>(address), 0, 1);
} else {
__builtin_prefetch(reinterpret_cast<const void*>(address), 1, 1);
}
switch (memop) {
case MemOp::Store: {
std::atomic_thread_fence(std::memory_order_seq_cst);
@@ -435,21 +427,6 @@ bool InterpreterVisitor::RegisterImmediate(bool wback, bool postindex, size_t sc
if (!postindex)
address += offset;
// Optimized prefetch for loads
if (memop == MemOp::Load) {
const size_t access_size = datasize / 8;
const bool is_aligned = (address % access_size) == 0;
if (is_aligned) {
__builtin_prefetch(reinterpret_cast<const void*>(address), 0, 3);
if (access_size >= 8 && access_size <= 32) {
__builtin_prefetch(reinterpret_cast<const void*>(address + PREFETCH_STRIDE), 0, 3);
}
} else {
__builtin_prefetch(reinterpret_cast<const void*>(address), 0, 1);
}
}
switch (memop) {
case MemOp::Store: {
u64 data = this->GetReg(Rt);
@@ -516,15 +493,6 @@ bool InterpreterVisitor::SIMDImmediate(bool wback, bool postindex, size_t scale,
if (!postindex)
address += offset;
// Aggressive prefetch for SIMD
if (memop == MemOp::Load) {
__builtin_prefetch(reinterpret_cast<const void*>(address), 0, 3);
__builtin_prefetch(reinterpret_cast<const void*>(address + CACHE_LINE_SIZE), 0, 3);
if (datasize >= SIMD_PREFETCH_THRESHOLD) {
__builtin_prefetch(reinterpret_cast<const void*>(address + PREFETCH_STRIDE), 0, 3);
}
}
switch (memop) {
case MemOp::Store: {
u128 data = VectorGetElement(this->GetVec(Vt), datasize);

View File

@@ -297,6 +297,9 @@ struct System::Impl {
std::string vendor = gpu_core->Renderer().GetDeviceVendor();
LOG_INFO(Core, "GPU Vendor: {}", vendor);
// Reset all per-game flags
Settings::values.use_squashed_iterated_blend = false;
// Insert PC overrides here
#ifdef ANDROID
@@ -322,6 +325,13 @@ struct System::Impl {
#endif
// Ninja Gaiden Ragebound
constexpr u64 ngr = 0x0100781020710000ULL;
if (programId == ngr) {
LOG_INFO(Core, "Enabling game specifc override: use_squashed_iterated_blend");
Settings::values.use_squashed_iterated_blend = true;
}
}
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
@@ -425,6 +435,9 @@ struct System::Impl {
void ShutdownMainProcess() {
SetShuttingDown(true);
// Reset per-game flags
Settings::values.use_squashed_iterated_blend = false;
is_powered_on = false;
exit_locked = false;
exit_requested = false;

View File

@@ -63,12 +63,10 @@ constexpr bool IsInvalidCharacter(char c) {
return impl::IsInvalidCharacterImpl<InvalidCharacters, std::size(InvalidCharacters)>(c);
}
constexpr bool IsInvalidCharacterForHostName(char c) {
return impl::IsInvalidCharacterImpl<InvalidCharactersForHostName,
std::size(InvalidCharactersForHostName)>(c);
return impl::IsInvalidCharacterImpl<InvalidCharactersForHostName, std::size(InvalidCharactersForHostName)>(c);
}
constexpr bool IsInvalidCharacterForMountName(char c) {
return impl::IsInvalidCharacterImpl<InvalidCharactersForMountName,
std::size(InvalidCharactersForMountName)>(c);
return impl::IsInvalidCharacterImpl<InvalidCharactersForMountName, std::size(InvalidCharactersForMountName)>(c);
}
} // namespace StringTraits

View File

@@ -15,7 +15,6 @@
#include "common/alignment.h"
#include "common/assert.h"
#include "common/common_types.h"
#include "common/concepts.h"
namespace Kernel {
@@ -24,7 +23,7 @@ class KThread;
template <typename T>
concept KPriorityQueueAffinityMask = !
std::is_reference_v<T>&& requires(T& t) {
{ t.GetAffinityMask() } -> Common::ConvertibleTo<u64>;
{ t.GetAffinityMask() } -> std::convertible_to<u64>;
{ t.SetAffinityMask(0) };
{ t.GetAffinity(0) } -> std::same_as<bool>;
@@ -50,9 +49,9 @@ std::is_reference_v<T>&& requires(T& t) {
std::remove_cvref_t<decltype(t.GetAffinityMask())>()
} -> KPriorityQueueAffinityMask;
{ t.GetActiveCore() } -> Common::ConvertibleTo<s32>;
{ t.GetPriority() } -> Common::ConvertibleTo<s32>;
{ t.IsDummyThread() } -> Common::ConvertibleTo<bool>;
{ t.GetActiveCore() } -> std::convertible_to<s32>;
{ t.GetPriority() } -> std::convertible_to<s32>;
{ t.IsDummyThread() } -> std::convertible_to<bool>;
};
template <typename Member, size_t NumCores_, int LowestPriority, int HighestPriority>

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-License-Identifier: GPL-2.0-or-late
// This file is automatically generated using svc_generator.py.
// DO NOT MODIFY IT MANUALLY
#pragma once
@@ -16,8 +19,6 @@ class System;
#include "core/hle/result.h"
namespace Kernel::Svc {
// clang-format off
Result SetHeapSize(Core::System& system, uint64_t* out_address, uint64_t size);
Result SetMemoryPermission(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
Result SetMemoryAttribute(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
@@ -506,8 +507,6 @@ enum class SvcId : u32 {
MapInsecureMemory = 0x90,
UnmapInsecureMemory = 0x91,
};
// clang-format on
// Custom ABI.
Result ReplyAndReceiveLight(Core::System& system, Handle handle, uint32_t* args);
Result ReplyAndReceiveLight64From32(Core::System& system, Handle handle, uint32_t* args);

View File

@@ -7,8 +7,6 @@
#include <algorithm>
#include <cstring>
#include <filesystem>
#include <iostream>
#include <random>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/find.hpp>
@@ -18,11 +16,11 @@
#include "common/fs/fs.h"
#include "common/fs/fs_types.h"
#include "common/fs/path_util.h"
#include "common/fs/symlink.h"
#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 {
@@ -492,6 +490,32 @@ void ProfileManager::ResetUserSaveFile()
ParseUserSaveFile();
}
std::vector<UUID> ProfileManager::FindExistingProfileUUIDs()
{
std::vector<UUID> uuids;
for (const ProfileInfo& p : profiles) {
auto uuid = p.user_uuid;
if (!uuid.IsInvalid()) {
uuids.emplace_back(uuid);
}
}
return uuids;
}
std::vector<std::string> ProfileManager::FindExistingProfileStrings()
{
std::vector<UUID> uuids = FindExistingProfileUUIDs();
std::vector<std::string> uuid_strings;
for (const UUID &uuid : uuids) {
auto user_id = uuid.AsU128();
uuid_strings.emplace_back(fmt::format("{:016X}{:016X}", user_id[1], user_id[0]));
}
return uuid_strings;
}
std::vector<std::string> ProfileManager::FindGoodProfiles()
{
namespace fs = std::filesystem;
@@ -501,31 +525,17 @@ std::vector<std::string> ProfileManager::FindGoodProfiles()
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"};
// some exceptions, e.g. the "system" profile
static constexpr const std::array<const char* const, 1> EXCEPTION_UUIDS
= {"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;
// "ignore" invalid uuids
if (uuid.IsInvalid()) {
return "0";
}
auto user_id = uuid.AsU128();
return fmt::format("{:016X}{:016X}", user_id[1], user_id[0]);
}();
if (uuid_string != "0") good_uuids.emplace_back(uuid_string);
}
auto existing = FindExistingProfileStrings();
good_uuids.insert(good_uuids.end(), existing.begin(), existing.end());
return good_uuids;
}
@@ -562,7 +572,8 @@ std::vector<std::string> ProfileManager::FindOrphanedProfiles()
override = true;
// if there are any regular files (NOT directories) there, do NOT delete it :p
if (file.is_regular_file())
// Also: check for symlinks
if (file.is_regular_file() || Common::FS::IsSymlink(file.path()))
return false;
}
} catch (const fs::filesystem_error& e) {

View File

@@ -105,6 +105,8 @@ public:
void ResetUserSaveFile();
std::vector<Common::UUID> FindExistingProfileUUIDs();
std::vector<std::string> FindExistingProfileStrings();
std::vector<std::string> FindGoodProfiles();
std::vector<std::string> FindOrphanedProfiles();

View File

@@ -237,7 +237,6 @@ WebBrowser::~WebBrowser() = default;
void WebBrowser::Initialize() {
if (Settings::values.disable_web_applet) {
LOG_INFO(Service_AM, "Web Browser Applet disabled, skipping.");
return;
}
@@ -305,6 +304,7 @@ void WebBrowser::ExecuteInteractive() {
void WebBrowser::Execute() {
if (Settings::values.disable_web_applet) {
LOG_WARNING(Service_AM, "(STUBBED) called, Web Browser Applet is disabled");
WebBrowserExit(WebExitReason::EndButtonPressed);
return;
}

View File

@@ -229,8 +229,7 @@ std::shared_ptr<FrontendApplet> FrontendAppletHolder::GetApplet(std::shared_ptr<
case AppletId::ProfileSelect:
return std::make_shared<ProfileSelect>(system, applet, mode, *frontend.profile_select);
case AppletId::SoftwareKeyboard:
return std::make_shared<SoftwareKeyboard>(system, applet, mode,
*frontend.software_keyboard);
return std::make_shared<SoftwareKeyboard>(system, applet, mode, *frontend.software_keyboard);
case AppletId::MiiEdit:
return std::make_shared<MiiEdit>(system, applet, mode, *frontend.mii_edit);
case AppletId::Web:
@@ -244,9 +243,7 @@ std::shared_ptr<FrontendApplet> FrontendAppletHolder::GetApplet(std::shared_ptr<
case AppletId::NetConnect:
return std::make_shared<NetConnect>(system, applet, mode, *frontend.net_connect);
default:
UNIMPLEMENTED_MSG(
"No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
static_cast<u8>(id));
LOG_ERROR(Service_AM, "No backend implementation exists for applet_id={:02X}. Falling back to stub applet", static_cast<u8>(id));
return std::make_shared<StubApplet>(system, applet, id, mode);
}
}

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -393,6 +396,24 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
const bool is_buffer_b{BufferDescriptorB().size() > buffer_index &&
BufferDescriptorB()[buffer_index].Size()};
const std::size_t buffer_size{GetWriteBufferSize(buffer_index)};
// Defensive check: if client didn't provide output buffer, log detailed error but don't crash
if (buffer_size == 0) {
LOG_ERROR(Core,
"WriteBuffer called but client provided NO output buffer! "
"Requested size: 0x{:X}, buffer_index: {}, is_buffer_b: {}, "
"BufferB count: {}, BufferC count: {}",
size, buffer_index, is_buffer_b, BufferDescriptorB().size(),
BufferDescriptorC().size());
// Log command context for debugging
LOG_ERROR(Core, "IPC Command: 0x{:X}, Type: {}", GetCommand(),
static_cast<u32>(GetCommandType()));
// Return 0 instead of crashing - let service handle error
return 0;
}
if (size > buffer_size) {
LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
buffer_size);

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -8,8 +11,8 @@
#include <mutex>
#include <string>
#include <unordered_map>
#include <concepts>
#include "common/concepts.h"
#include "core/hle/kernel/k_port.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/result.h"
@@ -63,7 +66,7 @@ public:
Result UnregisterService(const std::string& name);
Result GetServicePort(Kernel::KClientPort** out_client_port, const std::string& name);
template <Common::DerivedFrom<SessionRequestHandler> T>
template <std::derived_from<SessionRequestHandler> T>
std::shared_ptr<T> GetService(const std::string& service_name, bool block = false) const {
auto service = registered_services.find(service_name);
if (service == registered_services.end() && !block) {

View File

@@ -8,6 +8,7 @@
#include <optional>
#include <ostream>
#include <string>
#include <concepts>
#include "common/concepts.h"
#include "common/fs/path_util.h"
#include "common/logging/log.h"
@@ -27,7 +28,7 @@ namespace Loader {
namespace {
template <Common::DerivedFrom<AppLoader> T>
template <std::derived_from<AppLoader> T>
std::optional<FileType> IdentifyFileLoader(FileSys::VirtualFile file) {
const auto file_type = T::IdentifyType(file);
if (file_type != FileType::Error) {

View File

@@ -1230,7 +1230,22 @@ bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) {
if (rasterizer) {
impl->InvalidateGPUMemory(ptr, size);
}
#ifdef __linux__
if (!rasterizer && mapped) {
impl->buffer->DeferredMapSeparateHeap(GetInteger(vaddr));
}
#endif
return mapped && ptr != nullptr;
}
bool Memory::InvalidateSeparateHeap(void* fault_address) {
#ifdef __linux__
return impl->buffer->DeferredMapSeparateHeap(static_cast<u8*>(fault_address));
#else
return false;
#endif
}
} // namespace Core::Memory

View File

@@ -495,6 +495,8 @@ public:
bool InvalidateNCE(Common::ProcessAddress vaddr, size_t size);
bool InvalidateSeparateHeap(void* fault_address);
private:
Core::System& system;

View File

@@ -4,9 +4,6 @@
# SPDX-FileCopyrightText: 2017 Citra Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
add_library(yuzu-room STATIC EXCLUDE_FROM_ALL
yuzu_room.cpp
yuzu_room.h
@@ -19,7 +16,7 @@ if (ENABLE_WEB_SERVICE)
target_link_libraries(yuzu-room PRIVATE web_service)
endif()
target_link_libraries(yuzu-room PRIVATE MbedTLS::mbedcrypto MbedTLS::mbedtls)
target_link_libraries(yuzu-room PRIVATE MbedTLS::mbedcrypto${YUZU_STATIC_SUFFIX} MbedTLS::mbedtls${YUZU_STATIC_SUFFIX})
if (MSVC)
target_link_libraries(yuzu-room PRIVATE getopt)
endif()

View File

@@ -81,11 +81,6 @@ if (MSVC)
/bigobj # Increase number of sections in .obj files
/DNOMINMAX)
if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
endif()
if (CXX_CLANG)
list(APPEND DYNARMIC_CXX_FLAGS
-Qunused-arguments

View File

@@ -125,6 +125,10 @@ struct Jit::Impl final {
current_state.exclusive_state = false;
}
std::string Disassemble() const {
return {};
}
private:
void PerformRequestedCacheInvalidation(HaltReason hr) {
if (Has(hr, HaltReason::CacheInvalidation)) {
@@ -231,4 +235,8 @@ void Jit::ClearExclusiveState() {
impl->ClearExclusiveState();
}
std::string Jit::Disassemble() const {
return impl->Disassemble();
}
} // namespace Dynarmic::A32

View File

@@ -152,7 +152,7 @@ struct Jit::Impl final {
}
std::string Disassemble() const {
UNREACHABLE();
return {};
}
private:

View File

@@ -468,8 +468,9 @@ void EmitIR<IR::Opcode::FPRoundInt32>(oaknut::CodeGenerator& code, EmitContext&
case FP::RoundingMode::ToNearest_TieAwayFromZero:
code.FRINTA(Sresult, Soperand);
break;
default:
UNREACHABLE();
}
UNREACHABLE();
}
}

View File

@@ -1668,8 +1668,9 @@ void EmitIR<IR::Opcode::VectorTableLookup64>(oaknut::CodeGenerator& code, EmitCo
code.TBX(Dresult->B8(), oaknut::List{V0.B16(), V1.B16()}, Dindices->B8());
}
break;
default:
UNREACHABLE();
}
UNREACHABLE();
}
template<>
@@ -1731,8 +1732,9 @@ void EmitIR<IR::Opcode::VectorTableLookup128>(oaknut::CodeGenerator& code, EmitC
code.TBX(Qresult->B16(), oaknut::List{V0.B16(), V1.B16(), V2.B16(), V3.B16()}, Qindices->B16());
}
break;
default:
UNREACHABLE();
}
UNREACHABLE();
}
template<>

View File

@@ -645,8 +645,9 @@ void EmitIR<IR::Opcode::FPVectorRoundInt32>(oaknut::CodeGenerator& code, EmitCon
case FP::RoundingMode::ToNearest_TieAwayFromZero:
code.FRINTA(Qresult->S4(), Qoperand->S4());
break;
default:
UNREACHABLE();
}
UNREACHABLE();
}
});
}
@@ -684,8 +685,9 @@ void EmitIR<IR::Opcode::FPVectorRoundInt64>(oaknut::CodeGenerator& code, EmitCon
case FP::RoundingMode::ToNearest_TieAwayFromZero:
code.FRINTA(Qresult->D2(), Qoperand->D2());
break;
default:
UNREACHABLE();
}
UNREACHABLE();
}
});
}

View File

@@ -371,8 +371,9 @@ void RAReg<T>::Realize() {
case RWType::ReadWrite:
reg = T{reg_alloc.RealizeReadWriteImpl<kind>(read_value, write_value)};
break;
default:
UNREACHABLE();
}
UNREACHABLE();
}
} // namespace Dynarmic::Backend::Arm64

View File

@@ -188,15 +188,15 @@ private:
ExceptionHandler::ExceptionHandler() = default;
ExceptionHandler::~ExceptionHandler() = default;
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
void ExceptionHandler::Register(X64::BlockOfCode& code) {
impl = std::make_unique<Impl>(std::bit_cast<u64>(code.getCode()), code.GetTotalCodeSize());
}
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) {
impl = std::make_unique<Impl>(std::bit_cast<u64>(mem.ptr()), size);
}
#elif defined(MCL_ARCHITECTURE_RISCV)
#elif defined(ARCHITECTURE_riscv64)
void ExceptionHandler::Register(RV64::CodeBlock& mem, std::size_t size) {
impl = std::make_unique<Impl>(std::bit_cast<u64>(mem.ptr<u64>()), size);
}

View File

@@ -80,16 +80,15 @@ public:
};
// TODO: Check code alignment
const CodePtr aligned_code_ptr = CodePtr((uintptr_t(GetCurrentBlock()) + 15) & ~uintptr_t(15));
const CodePtr current_code_ptr = [this, aligned_code_ptr] {
const CodePtr current_code_ptr = [this] {
// 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 CodePtr(jit_state.rsb_codeptrs[new_rsb_ptr]);
}
return aligned_code_ptr;
//return GetCurrentBlock();
return CodePtr((uintptr_t(GetCurrentBlock()) + 15) & ~uintptr_t(15));
}();
const HaltReason hr = block_of_code.RunCode(&jit_state, current_code_ptr);

View File

@@ -36,22 +36,8 @@
#include "dynarmic/ir/basic_block.h"
#include "dynarmic/ir/microinstruction.h"
#define FCODE(NAME) \
[&code](auto... args) { \
if constexpr (fsize == 32) { \
code.NAME##s(args...); \
} else { \
code.NAME##d(args...); \
} \
}
#define ICODE(NAME) \
[&code](auto... args) { \
if constexpr (fsize == 32) { \
code.NAME##d(args...); \
} else { \
code.NAME##q(args...); \
} \
}
#define FCODE(NAME) [&](auto... args) { if (fsize == 32) code.NAME##s(args...); else code.NAME##d(args...); }
#define ICODE(NAME) [&](auto... args) { if (fsize == 32) code.NAME##d(args...); else code.NAME##q(args...); }
namespace Dynarmic::Backend::X64 {

Some files were not shown because too many files have changed in this diff Show More