Compare commits

..

53 Commits

Author SHA1 Message Date
PavelBARABANOV 7d9fcb0533 add other functions 2026-05-06 17:58:56 +03:00
PavelBARABANOV a88d8e3ebb [hle] GetFriendListForViewerV2 stub 2026-05-06 06:44:19 +03:00
PavelBARABANOV 86eae5cc41 [core] Fix qlaunch crash on second launch (#3930)
partial revert [08232ce642](https://git.eden-emu.dev/eden-emu/eden/commit/08232ce64275eaf388eba7005f4dae28fc18a0b7)

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3930
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-05-06 04:20:55 +02:00
crueter 8b9a841d99 [desktop] Fix QtCommon missing header in bootmanager.cpp (#3931)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3931
2026-05-06 03:27:51 +02:00
lizzie ca1fcaca3b [opengl] remove GLAD symbols from builds w/o OpenGL (#3922)
removes unused symbols from non-OpenGL builds, notably mac

I REMEMBER MAKING THIS PR A WHILE AGO but I have no record of it here, so hell lets redo it

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3922
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-05-06 03:23:27 +02:00
Eden CI 8f4e8c6d6a [dist, android] Update translations from Transifex for May 05 (#3929)
Automatic translation update for May 05

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3929
2026-05-05 21:48:58 +02:00
lizzie 4f4c298a39 [hle, service] fix errors related to race conditions triggering under SMG1 and SMG2 (#3927)
- service manager may add a service while someone else is finding it, so properly lock
- nvhost doesn't properly account for the fact that iterators GET FUCKING INVALIDATED
- use proper exit routine for mapping locked that failed (try/catch hell)

the last two were introduced by #3858, but the first one has been present since ???

either way, remember that ankerl map has invalidated iterators upon erase/insert, so i accounted for that and SMG1 (and probably smg2) boot fine now

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3927
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-05-05 07:31:08 +02:00
maufeat fee603f0b9 [kernel, hle] Initial 22.0.0 kernel changes and cmd stubs (#3761)
- KProcess::Run() and CreateThread() SVC now write the current thread handle to TLS+0x110
- KPageTableBase::LockForMapDeviceAddressSpace now checks for a new KPageTableBase boolean, m_allowed_exec_device_mapping
- Stub `am` + `acc` + `settings` cmd module that needs to work for qlaunch

Thanks to: @alula and @yellows8
Source for changes: https://github.com/Atmosphere-NX/Atmosphere/pull/2744, https://switchbrew.org/, https://yls8.mtheall.com/

Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3761
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-05-05 01:29:46 +02:00
MaranBr fc5fa7f1b2 [video_core] Reapply "Simplify TextureCache GC and remove redundant code" (#3723)
This enhances the garbage collection in TextureCache to make it more responsive and reliable during long gameplay sessions.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3723
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-05-04 21:28:43 +02:00
crueter 17c341ff6c [video_core] index rescaling metadata by descriptor (#3899) (#3924)
#3898 fix was good but exposed a rescaling metadata mismatch that can cause scaled texture descriptors to read the wrong state so this patch tries to keep them aligned with shader lookup

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3899
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>

Co-authored-by: ryana <ryanamayque@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3924
2026-05-04 20:27:53 +02:00
PavelBARABANOV 2deee80f29 [android] move GENSHIN_SPOOF flag to genshinSpoof flavor (#3923)
The standard build was downloading the optimized APK and vice versa due to GENSHIN_SPOOF being incorrectly defined in the mainline flavor. This should resolve the issue.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3923
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-05-04 19:54:26 +02:00
ryana 27e5cb0f12 [spirv] mark sampled image descriptor indices non-uniform (#3900)
fixes incorrect texture selection on vk when shaders use per-pixel descriptor indices, in line with #3898 so dynamic descs are no longer treated as uniform

also fixes TD;LTD spotty grass issue on SD not addressed by above pr

you can test out all the fixes here: https://git.eden-emu.dev/may/eden/src/branch/may/integrate-texture-descriptor-fixes

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3900
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-05-04 18:16:11 +02:00
ryana a76c76d122 [shader_recompiler] handle dynamic texture descriptor strides (#3898)
this fixes dynamic texture descriptors that are not laid out as simple 8-byte entries

tested on steam deck/amd

notes
- DynamicDescriptorSizeShift called twice because i moved it away from the struct but doing it this way keeps the patch just in this single file than adding a new derived field in the shared struct (i also think its just a cheap recomputation anyways)
- removed cbuf scanning because i figured out how to do a bounds check statically

credits:
- Mythrax <mythrax@mytrax-rs.org> (identified the 1024 descriptor cap fix in #3897)

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3898
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-05-04 18:15:55 +02:00
rayman30 44fa2805d6 [macos, dynarmic] Implement VectorMin/Max{S,U}64 emitters (Apple Silicon fix) (#3421)
[macos] dynarmic: Implement VectorMin/Max{S,U}64 emitters (Apple Silicon fix)

Implements the missing A64 backend emitters for VectorMinS64, VectorMinU64, VectorMaxS64, and VectorMaxU64.

These IR opcodes are generated by the optimizer but lack direct hardware instruction support for 64-bit elements in the base NEON set (e.g., UMIN.2D does not exist). They are implemented using a compare (CMGT/CMHI) followed by a bitwise select (BSL). This correctly selects between the two source registers, whereas using BIT would incorrectly zero out elements.

This implementation is guarded by #ifdef __APPLE__ to ensure no impact on other platforms.

Unit tests could not be added to a64.cpp because UMIN.2D is not a valid A64 instruction, causing the assembler (Oaknut) to reject it. The fix was verified by running Team Sonic Racing, which previously crashed on this synthetic opcode.

Fixes crash in Team Sonic Racing on macOS.

Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3421
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-05-03 04:29:49 +02:00
Eden CI 7d0e79335e [dist, android] Update translations from Transifex for May 02 (#3918)
Automatic translation update for May 02

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3918
2026-05-02 19:31:02 +02:00
lizzie d17ecb01af [file_sys] fix compilation on GCC 16 (#3917)
Signed-off-by: lizzie lizzie@eden-emu.dev
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3917
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-05-02 01:12:24 +02:00
crueter b537e83bed [android] Fix update checker crash on release mode (#3909)
R8 minifies the UpdateResult's data class to remove the `Set...`
methods, as it's technically not used in Kotlin/Java land.

Just force the minifier to keep it

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3909
2026-04-30 20:32:19 +02:00
lizzie 8765b49512 [video_core] fix H264 and jthread() causing spurious errors (#3907)
fixes regression by #3878

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3907
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-29 19:23:20 +02:00
lizzie a587b7dc3a [hle/nvdrv] drop redundant shared_ptr<> in internal nvhost_as_gpu mappings (#3858)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3858
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-04-29 16:44:28 +02:00
lizzie 90515bc6a2 [host1x] fix ffmpeg not having va-api on freebsd, inline nvenc (#3878)
- fix va-api not being used on freebsd

small thingies dont affect a lot:
- removes some pointer indirection (why save pointer to GMMU if its accesible via host1x)
- use std::variant<> for decoder
- miscelly vp9/v8/h264 opts
Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3878
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-29 16:41:25 +02:00
crueter 676b1aabfc [frontend] Built-in auto updater (#3845)
Checks latest release and opens a dialog containing the changelog, and
allow the user to select a specific build to download. After
downloading, it prompts the user to open it.

On Windows, this just opens up the zip in File Explorer. In the future setup files will be available. On macOS this opens up the DMG in Finder so the user can drag it to the Applications folder. Android retains the auto-update functionality from before, but updated to the new scheme. Body/View on Forgejo are not implemented, that should be in a future PR.

Additionally, moved some common httplib incantations to `Common::Net`. This will serve as the common network accessor and JSON parser from here on out.

TODO:
- [x] android :(
- [x] Search for builds based on keywords, with weights towards certain builds (e.g. macOS will search for dmg then tar.gz, windows msvc then mingw/exe then zip, etc.)
- [x] remove linux leftovers
- [x] don't allow asset selection on platforms w/o assets
- [x] nightly changelog should be in the real

FUTURE IMPLEMENTATION:
- [ ] Body/View on Forgejo for Android
- [ ] Setup files for Windows (Eden/nightly are separate) -- maybe portable/setup selector?
- [ ] Something else I'm forgetting

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3845
2026-04-28 20:42:23 +02:00
lizzie 77decca678 [video_core/engines/maxwell3d] memory inline DrawState to reduce indirection on hot paths (#3758)
usual indirection removal
helps very slightly to codegen

the idea is basically to reduce the amount of pointer deference overall in the code, and use idiomatic std::variant<>-isms to not rely on vtables/unique_ptr overhead
this should allow the compiler to emit better code
of course it's a tiny optimisation and only CPU side, but allows us to reduce indirection which is almost always a good thing

"but youre passing more parameters to the function!!!" its literally memoized into a register my friend

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3758
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-28 17:44:51 +02:00
Eden CI ed225f8a8b [dist, android] Update translations from Transifex for Apr 28 (#3902)
Automatic translation update for Apr 28

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3902
2026-04-28 16:11:44 +02:00
lizzie d69bd86183 [memory] coalesce redundant remappings of MultiPageLevel (#3857)
there is no need to call mmap() over the mapped region as the OS will automatically map it via lazy paging

basically the mmap() and virtualAlloc on a region already allocated is a no-op (FOR THIS SPECIFIC USECASE)

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3857
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-04-28 01:17:56 +02:00
lizzie c172abfb53 [hle] reuse previous pagetable when initializing new processes on the same KProcessPageTable (#3891)
VirtualBuffer<> would be recreated each time due to the `operator=()` from the unique_ptr<> when initializing a new process, this change makes it so said thing doesn't happen (instead it resizes the existing buffer)

this means that consecutive launches of the same process that happen to have the same process page table (or reuse it) will no longer incur a ctor/dtor path for VirtualBuffer and instead just resize the existing one

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3891
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-04-28 01:15:21 +02:00
lizzie d33dc16820 [dynarmic] set BL terminal as FastLinkBlock (#3811)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3811
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-04-28 01:12:35 +02:00
lizzie 8cdaf19a83 [video_core] simplify InvalidationAccumulator (#3890)
various redundant fields aren't required, so just redo it for good measure

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3890
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-04-28 00:24:54 +02:00
lizzie f088f5bd45 [loader] change ASLR algo to be more uniform (#3869)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3869
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-27 05:09:55 +02:00
lizzie cbeea5b954 [hle] handle NPad shared_memory being null on certain updates and cases (#3860)
Does NOT fix root issue with shared_memory of NPad yet, that is something probably separate
I'd like to suspect it's because every NPad by default it's expected to have shared memory, even when not explicitly initialized, but seems unlikely

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3860
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-04-27 04:01:49 +02:00
Duncan Ogilvie 1590e7c061 [core] GDB improvements (#3848)
The commands to reproduce the issues are in the commit messages. I tested on Super Mario Odyssey using [nx2elf](https://github.com/shuffle2/nx2elf) converted binaries and gdb-multiarch:

```
(gdb) monitor info
Process:     0x51 (Application)
Program Id:  0x0100000000010000
Layout:
  Alias: 0x1103400000 - 0x21033fffff
  Heap:  0x2103400000 - 0x23033fffff
  Aslr:  0x0008000000 - 0x7fffffffff
  Stack: 0x1083400000 - 0x11033fffff
Modules:
  0x0080b3d000 - 0x0080b40fff nnrtld
  0x0080b41000 - 0x0081ff1fff RedStar.nss
  0x0081ff2000 - 0x008270efff multimedia
  0x008270f000 - 0x00833e2fff nnSdk
(gdb) monitor mappings
Mappings:
  0x0000000000 - 0x0080b3cfff     Free ----- [0, 0]
  0x0080b3d000 - 0x0080b3efff r-x Code ----- [0, 0]
  0x0080b3f000 - 0x0080b3ffff r-- Code ----- [0, 0]
  0x0080b40000 - 0x0080b40fff rw- CodeData ----- [0, 0]
  0x0080b41000 - 0x008156bfff r-x Code ----- [0, 0]
  0x008156c000 - 0x0081cdafff r-- Code ----- [0, 0]
  0x0081cdb000 - 0x0081ff1fff rw- CodeData ----- [0, 0]
  0x0081ff2000 - 0x0082365fff r-x Code ----- [0, 0]
  0x0082366000 - 0x00825c0fff r-- Code ----- [0, 0]
  0x00825c1000 - 0x008270efff rw- CodeData ----- [0, 0]
  0x008270f000 - 0x0082c3cfff r-x Code ----- [0, 0]
  0x0082c3d000 - 0x00832bffff r-- Code ----- [0, 0]
  0x00832c0000 - 0x00833e2fff rw- CodeData ----- [0, 0]
  0x00833e3000 - 0x0083403fff     Free ----- [0, 0]
  0x0083404000 - 0x0083404fff rw- ThreadLocal ----- [0, 0]
  0x0083405000 - 0x1083403fff     Free ----- [0, 0]
  0x1083404000 - 0x1083503fff rw- Stack ----- [0, 0]
  0x1083504000 - 0x7fffffffff     Free ----- [0, 0]
(gdb) set sysroot
(gdb) set solib-search-path /Users/duncan/Downloads/smo-program
Reading symbols from /Users/duncan/Downloads/smo-program/rtld.elf...
(No debugging symbols found in /Users/duncan/Downloads/smo-program/rtld.elf)
Reading symbols from /Users/duncan/Downloads/smo-program/main.elf...
(No debugging symbols found in /Users/duncan/Downloads/smo-program/main.elf)
Reading symbols from /Users/duncan/Downloads/smo-program/subsdk0.elf...
(No debugging symbols found in /Users/duncan/Downloads/smo-program/subsdk0.elf)
Reading symbols from /Users/duncan/Downloads/smo-program/sdk.elf...
(No debugging symbols found in /Users/duncan/Downloads/smo-program/sdk.elf)
(gdb) info shared
From                To                  Syms Read   Shared Object Library
0x0000000080b3d000  0x0000000080b41000  Yes (*)     /Users/duncan/Downloads/smo-program/rtld.elf
0x0000000080b41000  0x0000000081ff2000  Yes (*)     /Users/duncan/Downloads/smo-program/main.elf
0x0000000081ff2000  0x000000008270f000  Yes (*)     /Users/duncan/Downloads/smo-program/subsdk0.elf
0x000000008270f000  0x00000000833e3000  Yes (*)     /Users/duncan/Downloads/smo-program/sdk.elf
(*): Shared library is missing debugging information.
(gdb) info functions nnMain
All functions matching regular expression "nnMain":

Non-debugging symbols:
0x0000000081024250  nnMain
0x0000000082c2de40  nnMain@plt
(gdb) b *nnMain
Breakpoint 1 at 0x81024250
(gdb) c
Continuing.

Breakpoint 1, 0x0000000081024250 in nnMain () from /Users/duncan/Downloads/smo-program/main.elf
(gdb) x/10i $pc
=> 0x81024250 <nnMain>:	stp	x22, x21, [sp, #-48]!
   0x81024254 <nnMain+4>:	stp	x20, x19, [sp, #16]
   0x81024258 <nnMain+8>:	stp	x29, x30, [sp, #32]
   0x8102425c <nnMain+12>:	add	x29, sp, #0x20
   0x81024260 <nnMain+16>:	bl	0x81569aa0
   0x81024264 <nnMain+20>:	mov	w19, w0
   0x81024268 <nnMain+24>:	bl	0x81569ab0
   0x8102426c <nnMain+28>:	mov	x20, x0
   0x81024270 <nnMain+32>:	mov	w0, w19
   0x81024274 <nnMain+36>:	mov	x1, x20
```

Symlinked like this:

```
ls -l /Users/duncan/Downloads/smo-program
total 687472
-rw-r--r--@ 1 duncan  staff   20385356 Apr  9 18:12 main.elf
lrwxr-xr-x@ 1 duncan  staff         11 Apr  9 15:26 multimedia -> subsdk0.elf
lrwxr-xr-x@ 1 duncan  staff          8 Apr  9 15:28 nnrtld -> rtld.elf
lrwxr-xr-x@ 1 duncan  staff          7 Apr  9 15:26 nnSdk -> sdk.elf
lrwxr-xr-x@ 1 duncan  staff          8 Apr  9 15:26 RedStar.nss -> main.elf
-rw-r--r--@ 1 duncan  staff      12440 Apr  9 18:12 rtld.elf
-rw-r--r--@ 1 duncan  staff   12662960 Apr  9 18:12 sdk.elf
-rw-r--r--@ 1 duncan  staff    6294336 Apr  9 18:12 subsdk0.elf
```

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3848
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-04-27 03:39:34 +02:00
lizzie c95f8df8a5 [docs] update deps for illumos, instructions for OmniOS (#3892)
omniOS is different enough from openIndiana that they warrant their own section

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3892
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-04-26 21:17:40 +02:00
crueter e81f5111de [android] Fix auto updater by using https scheme (#3895)
Seems like some phone vendors require https for URLs? Weird behavior,
works on some phones but not others

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3895
2026-04-26 21:15:07 +02:00
crueter 91058d7383 [desktop] Fix 2 mod manager bugs (#3884)
- Multi-import would show duplicates of a mod if it had both exefs and
  romfs
- Import from folder would crash on some single mods

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3884
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-26 03:26:04 +02:00
crueter 048d02e5b4 [android] Remove unused SPIRV strings and make strings check run on PRs (#3885)
I reorganized my runners so it shouldn't be an issue anymore

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3885
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-04-25 23:32:20 +02:00
lizzie 17e2be173c [spirv] nuke spirv-opt (#3877)
lots of AGILEism in spirv-opt
theres BETTER alternatives like https://github.com/renderbag/re-spirv (im not gonna bother for now, it probably has shitty build system)
it sucks

the IR already resolves most of the shader code to just constant load/stores
Spirv-opt passes do not seem to make such a big difference
only introduce extra latency
like for example cbuf pass in IR already removes a lot of code, that spirv_opt would otherwise miss due to the fact it doesn't have cbuf information

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

Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3877
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-04-25 21:54:27 +02:00
crueter bd6dd7ecec [maxwell] Fix Flow::Block comp error (#3882)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3882
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-25 20:50:11 +02:00
crueter 72ae613176 [dist, android] Update translations from Transifex (#3881)
Signed-off-by: Eden CI <ci@eden-emu.dev>
Co-authored-by: Eden CI <ci@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3881
2026-04-25 18:07:47 +02:00
crueter 26ce96297c [frontend] Change update checker to use new endpoints (#3879)
Related: [RFC3870](https://git.eden-emu.dev/eden-emu/eden/issues/3870)

Nightly and stable releases are now served through
`nightly.eden-emu.dev` and `stable.eden-emu.dev`, respectively. These
are stored using Backblaze, and served and cached through the Cloudflare
CDN. Ideally this will reduce costs, though I'll have to wait for my
first invoice to be certain.

These will serve as the new download locations going forward. Since we
have full control over this API, we can make any adjustments we want as
needed. For now, all it does is provide `tag_name`, `name`, and `body`,
the latter of which will be used for the upcoming updater PR.

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3879
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-24 18:40:49 +02:00
CamilleLaVey b3cc8723c1 [vulkan] 2nd Vulkan Global Maintenance (#3853)
This pr is a sequel to the one merged some days ago (#3839); which aims to improve stability, graphical accuracy and better Vulkan implementation and coherency among all platforms, contains the next changes:

-> Removal of VK_EXT_unified_image_layouts: The removal of this ext was for cleaning purposes since the only part of this extension implemented was the activator; meanwhile a proper structure of use for this extension was not implemented, currently it's not viable to keep following an idea of a proper implementation due to complexity of this feature and the state of buffer cache and texture cache, which it's task that we must do near in the future, when this happens a better oportunity will arise to properly set layouts along a proper implementation of VK_EXT_descriptors_indexing, practically this feature was dead code.

-> Adjustment of VK_EXT_custom_border_color: The implementation of this feature was handled poorly and worsened during the first tries of making ExtendedDynamicState stable, by gating it's use to the slider of EDS (dyna_state) if the counter was at least in 1, even tho this entered in a bug with the RemoveUnsuitableExtension, when is not a requirement for enabling in Vulkan's documentation and was my mistake, some time later in ExtendedDynamicState refactor (#3074) I tried to make the implementation more robust in comparison the Yuzu's implementation which had bans on vendor drivers, the new handling was requesting if extension was available and what kind of support feature it had, enabling what it was available and wiring an adequate path for said available feature; which leads us to today's change, after reading carefully how certain paths weren't triggered or caused mostly issues on how extension should work I did the next changes:

    - I removed the forced disabling with ExtendedDynamicState setting
    - Resolved the bug with RemoveUnsuitableExtension + dyna_state
    - Removed comments of explanation + log_debug warning
    - Set extension to be disabled if customBorderColorWithoutFormat is not available
    - Helps to solidify the removal of bans in vendor drivers

This changes fixes the VUID 04015 for the handling with undefined format and made the usage of the extension more near to what Vulkan specification expects, yet there is still cases where we can't emulate properly samplers and some translucid black boxes will still appear, yet, now alleviated by allowing extension choose the proper custom available in Vulkan or degrade into a fallaback of solid colors.

-> Adjustment of VK_EXT/KHR_robustness2: This feature was introduced in ExtendedDynamicState refactor (#3074), as safety measure for descriptors during the Write of buffers, providing robustness with an upgraded access to image, buffers and proper discard of null data in descriptors, however, despite the configuration the logs during debug sessions never stopped to bring the next VUID-VkWriteDescriptorSet-descriptorType-00324 and VUID-VkWriteDescriptorSet-descriptorType-00325, being the first one, the most constant issue plaguing logs; the approach was not only ensuring device can access between each of the version of this feature, whether is an EXT or KHR (drivers can report one of them or both, yet, if we call the one of them and it's not the version supported, driver would not load the feature, there's a priority to the KHR version) with a simplified configuration of the extension to use only nullDescritor to deflect properly buffers and other trash data outside of descriptors bound; ensuring to wire the path when it's and not available and also with BindVertexBuffers2EXT when it's or not available; fixing both VUID's. This changes helps to save some CPU resources and memory on binding routes.

      - Fixes VUID-VkWriteDescriptorSet-descriptorType-00324
      - Fixes VUID-VkWriteDescriptorSet-descriptorType-00325
      - Fixes VUID-vkCmdBindVertexBuffers-pBuffers-00621 (alongisde a latter adjustment for pStrides)

-> Adjustment VK_EXT_image_robustness: As other features, this was implemented during the ExtendedDynamicState refactor (#3074), currently this change it's just to ensure more drivers are accessing this feature by changing the modality from extension to an explicit feature, some other redundant code was cleaned within this change.

-> Restored gating flush operation on removed gpu accuracy: An issue report from an user called CaptFaraday in https://github.com/eden-emulator/Issue-Reports/issues/425, posted a behavior appearing after the rework of gpu accuracy levels (#3129), which broke the rendering in Paper Mario - The-Thousand-Year Door where some graphical issues such as black flash and missing rendering from many animations through the game thanks to the removal of the flush inside FlushAndInvalidateRegion gated with IsGPULevelExtreme and suggested a possible fix with resting the missing gating and flush; which I did and properly restoring the complete behavior of this functionality + wiring to the new IsGPULevelHigh for a better semantic correctness, the change was tested and didn't affected Yoshi's Crafted World graphical problems and main reason behind the deletion of this function, fixed in fcfcee7247.

      - Solves https://github.com/eden-emulator/Issue-Reports/issues/266
      - Solves https://github.com/eden-emulator/Issue-Reports/issues/425
      - Fixes Paper Mario - The-Thousand-Year Door
      - Keeps Yoshi's Crafted World issue still fixed

-> Adjustment VK_EXT_conditional_rendering: Yuzu inherited us in their Vulkan backend multiple flaws which got worsened with the time as game and drivers changed, aside that, with the time studying this source code and especially the Vulkan-side of Eden, I started to learn and recognize some extensions that required a wide and robust modification to ensure the logic of the extension works as intended; currently ConditionalRendering had a lot of minimal modification:

    - Reordering the functions from "_NotifySegment_" to avoid a masive ram leak coming from query_cache (@weakboson) (#131)
    - Removing a function "_NotifySegment_" from rasterizer to ensure Metroid Prime 4 stopped crashing due to serious ram leaks in query_cache (@Maufeat) (#3142)

And other intents to make ConditionalRendering fully working, such as happened in ExtendedDynamicState refactor (#3074) but only patched an horrible situation with how the extension was truly working, after spending more than 3 months studying how this and other sub-sequential and essential extensions touched in this PR worked in Vulkan, I dived once again to make it work properly; one of the first changes was to fix an invalid reference lookup of queries, which fixed the removal of "NotifySegment" inside rasterizer and start to adjusting other parts of the implementation of ConditionalRendering minimally and switching with heavy tests to ensure not a single game gets broken among the changes; yet the initial benefits from fixing the indirection in the lookups to query cache, was to reduce the amount of time of GPU was spending in the constant state of queries, which proved to reduce flickering in Pokémon ZA among others, with also an small increase of performance but more noticeable stability, starting to reduce stutering bit by bit.

This advances allowed me to fix one of the the functions of IsGPULevelHigh, where existed a bypass to accelerate conditional rendering without the proper checks if the extension was truly supported, freeing QCOM from the flag of a fixated presync workaround; which also improved the usage of QCOM driver for 8 Elite devices and Unreal Engine 4 - 5 games, such as Dragon Ball Z - Sparking Zero; but that's not the only benefit from the current tries to make ConditionalRendering implementation more robust and accurate to specifications, but also started to show key points of where VK_EXT_transform_feedback was also failing to work properly.

-> Adjustment VK_EXT_transform_feedback: Like many other features in this PR, this one was also adjusted minimally in ExtendedDynamicState refactor (#3074), with the ConditionalRendering refactor going on, the solutions for the usage of this extensions started by ensuring each key function is properly gated by a getter which would only be enabled if the extension was already being loaded in the virtual device, if wasn't the case I was making sure to wire the fallback correctly, which wasn't in place and didn't had a robust handling since ever, this way games started to not only improve graphical accuracy, like some games such as Zelda - Echoes Of Wisdom where the lightning and dark border moves/ reacts dynamically.

Besides that, this change brought the possibility to finally get rid of the indirection of the buffers synchronization which often take a non-synchornization path to ensure a faster reply but with higher possibilities to cause graphical issues in among several games; aside that, also helped to ensure "_query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount, false)_;" function is properly allocated and reset in a different place than where this was placed.

   - Maintain Metroid Prime 4 fixes even after returning the lines that caused the game to be unplayable, whether was an instant crash
     or crash after some minutes of gameplay, fixes that were introduced in other work (#3142).

Within the first step in the refactor of this extension, this work was reviewed by @wildcard which made me notice of an issue of handling inside buffers, there existed a mismatch on the tracking of feedback buffers and since we're treating them as buffer_slot, counterstream was still tracking and consuming stream_buffers and not where data was really passing through; derivating the counter selection of counterBufferCount by stream indexes and not by slot, which could cause cases of _Stream =! slot_, a solution proposed for me was to add stream mapper function where the stream slot were located + updating UpdateBuffers() to calculate buffer counts per slot and not stream, allowing to fully map the map funtion of stream mapper; along other changes on the WriteBuffers + ProduceBufferCounter to avoid any misaligment.

-> Other minimal adjustments: Alongside these important adjustment, others were also made to ensure logical coherency to this recent changes, such as ensuring FullSynchronization of buffers path, since GPU has mostly a syncing issue with certain type of textures and vertex calculations, the original behavior of jumping into a non-synchronize path of buffers let GPU ran without proper awareness of the textures being loaded, ensuring more performance if all the textures reached properly inside GPU, but with no safety provided for buffers, even we added a cases were dummies and mostly buffer trash data gets discarded by nullDescriptors, this won't ensure graphical artifacts or a bad calculation on the range of lightning/ gfx could appear. I dare to think this was thought to be implemented due to the original heavy costs on Yuzu's time, this along the removal of QCOM's drivers from Query's Presync funtions.

A small adjustment to the mutable functions inside the CreateImageView structure to add the extended usage:

"Because Switch's GPU creates incompatible views (sRGB and UNORM) on the same image. A sRGB image can't be used as storage but it is in a UNORM view. Which is exactly the use case of these flags." - @weakboson

During all of this changes inside queries, we started to get in some devices "Device Loss" warning from Vulkan along 2 specific warnings:

    - [ 102.384895] Render.Vulkan <Critical> video_core/vulkan_common/vulkan_debug_callback.cpp:69:DebugUtilCallback: vkDeviceWaitIdle(): THREADING ERROR : object of type VkQueue is simultaneously used in current thread 517024609280 and thread 517864567808
    - [ 114.003530] Render.Vulkan <Critical> video_core/vulkan_common/vulkan_debug_callback.cpp:69:DebugUtilCallback: vkCmdBeginQuery(): VkQueryPool 0x15e400000015e4 and query 172: query not reset. After query pool creation, each query must be reset (with vkCmdResetQueryPool or vkResetQueryPool) before it is used. Queries must also be reset between uses.

Since before all of this adjustments, original GPU thread often take it's time to stop and look for a moment to synchronize with CPU (non-TimelineSemaphore), the whole flow data was improved that we were producing more data stale than we could really take due to the lack of a Reset to avoid pools being filled with old data, in order to get rid of this, another try to implement ResetQueryPool's appeared which was intented to be implemented some months ago and got removed in #3270, this time aligning the vkDeviceWaitIdle + ResetQueryPool was proved to be effective than first implementation and didn't caused major issues, now GPU can Vulkan can reset staling data, which can catalogued as old once they were used and displayed in frame, keeping a more fluid exchance and discard of data.

    - Fixes VUID-vkCmdBeginQuery-None-00807
    - Fixes multithreading error with vkDeviceWaitIdle and data allocation

We have some other changes to the coherency of ExtendedDynamicState2 and the feature of restart primitives, which now patches topologies once are processed if they pass through ExtendedDynamicState2 enabled and get reset before every draw to prevent another topology VUID; also I ensured refresh, reset, clamp and overall improve the math inside the Viewport/ Scissor feature operations inside DynamicState and later upgrades.

---------------------------
UPDATE (23/04/2026): After passing a heavy testing phase, an issue was encountered with AMD drivers on Windows which based on the commit:  c07dfa6fb4, Super Mario Odissey started to show vertex glitches on the the waterfall + water fog being rendered incorrectly, if VertexInputDynamicState was disabled caused black screen on ExtendedDynamicState (1 - 3) and hard crash if ExtendedDynamicState it was disabled; this situation was caused to the vertex input dynamic tied to ExtendedDynamicState1, AMD driver didn't allowed fast access to BindVertexBuffers2EXT without binding strides first, which caused a syncing problem between the binded vertex and the missing buffer in the same chain, this got fixed by removing the conditions for vertex input dynamic.

Aside that; another pair of issues were addressed in the meantime of refining this PR, one of them was to solve the failing BGR565 formats to swizzle into RGBA5 which allows to swap between red and blue; solving the inverse situation of blue icons on Mario Kart 8 Deluxe for older QCOM drivers and SoC's, such as Snapdragon 855 - 870; which will also help some Exynos processors to render properly. This solution was converted into a toggle/hack because it's use it's very conditional on older hardware; newer SoC's such as 8 Elite won't longer require this handling to convert properly BGR565 texture even if the support for the format is not available.

---------------------------

Here an small preview of what this pr has been fixed so far, but our testing range may be more limited than what this can actually do:

- Allow to display new effect on games

1. Jump Force: New particle on stages and main menu.
2. The Legend Of Zelda - Echoes of Wisdom: darkness post processing effect on screen filter such as game intro and smokes on houses (8 Elite).
3. Reduce texture flickering on games such as EoW, Monster Hunter Rise.
4. Improved performance stability on various games with Android.
5. Improved Xenoblade games rendering with QCOM stock drivers by improve viewpoint handling (8 Elite).
6. Fixes vertex explosion on Xenoblade 3 with AMD GPU with extended dynamic state enabled.
7. Fixed Mario Kart 8 Deluxe rendering with VK_EXT_vertex_input_dynamic_state enabled.
8. Fixes certain angle of Pokemon Legend Z-A would look mono color with vertex input dynamic state.
9. Fixed graphical issue with VK_EXT_vertex_input_dynamic_state on mobile drivers.
10. Fixed vertex explosion with Turnip (8 Elite) on The Legend Of Zelda- Breath Of The Wild during loading screen.
11. Fixed issue of vertex on Pokémon Legends ZA with VK_EXT_vertex_input_dynamic_state enabled.
12. Improved rendering and stability of Inmortal Fenyx Rising, including QCOM drivers being able to reach into gameplay.
13. Fixes Paper Mario - The-Thousand-Year Door missing rendering on animations through the whole game.
14. Fixed Mario Kart 8 Deluxe blue tint icon on Snapdragon 855 - 870 (by enabling Emulated BGR565 hack toggle).
15. Fixed Naruto Ultimate Ninja Storm issue rendering on characters like Naruto being blue on older QCOM SoC's and Exynos (by enabling Emulated BGR565 hack toggle)
16. Fixed Dangaronpa Killing Harmony v3 issue rendering on characters with blue tint on older QCOM SoC's.
---------------------------

_**Special Thanks - Credits**_

-> @Gidoly for being able to keep track of the intensive testing phase this pr required and the will to keep helping in development, you're a good friend and very useful.
-> @CaptFaraday for the suggestion of the fix for Paper Mario.
-> @wildcard for the review during the refactor of VK_EXT_transform_feedback, without this comment I would probably ran into many untrackable issues.
-> @weakboson for the suggestion into the solution for sRGB's and UNORM's in the incompatible views.

Co-authored-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3853
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-04-24 16:37:18 +02:00
lizzie 417ed904f0 [dynarmic] fix MWAIT push/pop not being handled properly on xbyak (#3875)
push %edx is not what i wanted, nor what anybody wants, xbyak silently accepting this before was not intended
now that xbyak is updated this is an issue

the issue was simply:
a) ptr being overwritten (if it happened to be EDX/EBX/EAX) due to changed WAITPKG logic (oops)
b) xbyak not reporting wrong r32 pop/push on older versions thus missing it and now it throws an exception

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3875
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-04-23 05:06:33 +02:00
wildcard 838cc926f6 keyboard fixes (#3865)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3865
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-04-23 03:43:54 +02:00
coolone 860acb4faf [android] Fix crash on start any games for many handhelds (Ayaneo, Retroid etc) (#3647)
## Summary
This change hardens Android Picture-in-Picture handling to avoid runtime crashes on devices/ROMs where PiP APIs are unavailable or behave inconsistently.

## What changed
- Added a feature gate for PiP support using `FEATURE_PICTURE_IN_PICTURE`.
- Early-returned from PiP flows when unsupported.
- Wrapped PiP API calls (`enterPictureInPictureMode`, `setPictureInPictureParams`) in guarded handlers that catch `IllegalStateException` and `UnsupportedOperationException`.
- Logged one warning per failed PiP action to avoid log spam.

## Why
On some Android devices, calling PiP APIs can throw at runtime even when the app is otherwise functioning normally. This patch prevents those calls from crashing/interrupting emulation and keeps behavior unchanged on supported devices.

## Notes
- No behavior changes for fully PiP-capable devices.
- Safe no-op on unsupported devices.

Co-authored-by: Nikolai Trukhin <coolone.official@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3647
Reviewed-by: DraVee <chimera@dravee.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-22 05:32:52 +02:00
Eden CI a0bb6324c0 [dist, android] Update translations from Transifex for Apr 21 (#3871)
Automatic translation update for Apr 21

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3871
2026-04-21 16:02:40 +02:00
MaranBr 3a823de605 [dynarmic] Remove Ignore Global Monitor from CPU Accuracy Auto (#3846)
This fixes a flickering issue in some games, such as The Legend of Zelda: Echoes of Wisdom.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3846
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
2026-04-21 05:03:43 +02:00
crueter 0257a8d491 [desktop] Change data manager to use tabs instead of a list (#3856)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3856
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
2026-04-21 04:01:39 +02:00
PavelBARABANOV 6c76908ddb [android] Allow manual overlay toggle even with controller connected + move async GPU options to hacks (#3862)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3862
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Co-committed-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
2026-04-17 20:29:45 +02:00
omardotdev e6ad51e3d5 [settings] remove duplicate settings (#3847)
this removes the duplicate serial knob, battery/unit serial shown on the settings tab and uses the debugging tab instead
(this used to be a pr to fix breeze compatibility issues where the text/input fields would look wrong when the theme was set to breeze but since the settings was moved its not really needed to change the window size)

Co-authored-by: Omar <180954465+omardotdev@users.noreply.github.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3847
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: omardotdev <omardotdev@eden-emu.dev>
Co-committed-by: omardotdev <omardotdev@eden-emu.dev>
2026-04-17 06:58:40 +02:00
Eden CI f11b69d6b7 [dist, android] Update translations from Transifex for Apr 14 (#3859)
Automatic translation update for Apr 14

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3859
Co-authored-by: Eden CI <ci@eden-emu.dev>
Co-committed-by: Eden CI <ci@eden-emu.dev>
2026-04-14 18:14:01 +02:00
xbzk 27cadb24f3 [android, intent] Run restoreContentForGame for shortcut launching + Improve custom settings context for shortcut launching (based on normal launch) (#3854)
intended to fix two bugs identified by Pavel upon android shortcut launching (and prolly all FEs since the rely on intent launching too):
1. external content not loading: fixed by running restoreContentForGame  for per game mount in content path.
2. custom settings no loading: that was proven to be user side, but adjustments were made to match normal launch.
should be harmless for normal usage. once validated can be merged.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3854
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: xbzk <xbzk@eden-emu.dev>
Co-committed-by: xbzk <xbzk@eden-emu.dev>
2026-04-14 00:21:51 +02:00
John a7ef19e028 [settings] Exposes the Hidden GPU Async Setting on other Platforms (#3833)
Disabling it may:
- Alleviates and Fixes flickering in Pokemon LZA, Kirby, Jamboree, XCDE, etc.
- Audio improvements in Metroid Prime 4

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3833
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: John <john@eden-emu.dev>
Co-committed-by: John <john@eden-emu.dev>
2026-04-13 00:28:12 +02:00
Eden CI 2c1eff2e60 [dist, android] Update translations from Transifex for Apr 11 (#3850)
Automatic translation update for Apr 11

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3850
Co-authored-by: Eden CI <ci@eden-emu.dev>
Co-committed-by: Eden CI <ci@eden-emu.dev>
2026-04-11 18:37:13 +02:00
xbzk abb616c357 [vk,swapchain] vsync: Changed Immediate fallback from (FIFO) to (Mailbox, then FIFO) (#3746)
Just discovered that stock adreno drivers on a730 had no Immediate VSync mode available, and it was falling back to FIFO, which causes a lot of response delay in Unity games.

But if someone chose Immediate, it prefers low latency above buffering, so Mailbox is his friend, and FIFO is his nemesis.

So i just changed Immediate to fall back to Mailbox first, and only if Mailbox is not available either it falls back to FIFO:

Immediate -> Mailbox -> FIFO;
Mailbox -> FIFO;
FIFO Relaxed -> FIFO.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3746
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: xbzk <xbzk@eden-emu.dev>
Co-committed-by: xbzk <xbzk@eden-emu.dev>
2026-04-11 02:49:55 +02:00
lizzie c95cb8f8ec [hle] improved flusher that uses jthread (#3837)
not happy with this impl, but I made this a bit quickly to demostrate it can be done better :)

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3837
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>
2026-04-09 23:46:38 +02:00
243 changed files with 20074 additions and 17813 deletions
+3 -1
View File
@@ -3,6 +3,8 @@ name: Check Strings
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
check-strings:
@@ -10,7 +12,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-depth: 1
- name: Find Unused Strings
run: ./tools/unused-strings.sh
-14
View File
@@ -1,14 +0,0 @@
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
index eb4e69e..3155805 100644
--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
@@ -72,7 +72,8 @@ if (SPIRV_TOOLS_USE_MIMALLOC)
pop_variable(MI_BUILD_TESTS)
endif()
-if (DEFINED SPIRV-Headers_SOURCE_DIR)
+# NetBSD doesn't have SPIRV-Headers readily available on system
+if (DEFINED SPIRV-Headers_SOURCE_DIR AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "NetBSD")
# This allows flexible position of the SPIRV-Headers repo.
set(SPIRV_HEADER_DIR ${SPIRV-Headers_SOURCE_DIR})
else()
@@ -1,287 +0,0 @@
From 67bf3d1381b1faf59e87001d6156ba4e21cada14 Mon Sep 17 00:00:00 2001
From: crueter <crueter@eden-emu.dev>
Date: Mon, 29 Dec 2025 21:22:36 -0500
Subject: [PATCH] [cmake] refactor: shared/static handling
This significantly redoes the way shared and static libraries are
handled. Now, it's controlled by two options: `SPIRV_TOOLS_BUILD_STATIC`
and `SPIRV_TOOLS_BUILD_SHARED`.
The default configuration (no `BUILD_SHARED_LIBS` set, options left at
default) is to build shared ONLY if this is the master project, or
static ONLY if this is a subproject (e.g. FetchContent, CPM.cmake). Also
I should note that static-only (i.e. no shared) is now a supported
target, this is done because projects including it as a submodule e.g.
on Android or Windows may prefer this.
Now the shared/static handling:
- static ON, shared OFF: Only generates `.a` libraries.
- static ON, shared ON: Generates `.a` libraries, but also
`libSPIRV-Tools.so`
- static OFF, shared ON: Only generates `.so` libraries.
Notable TODOs:
- SPIRV-Tools-shared.pc seems redundant--how should we handle which one
to use in the case of distributions that distribute both types (MSYS2
for instance)?
* *Note: pkgconfig sucks at this and usually just leaves it up to the
user, so the optimal solution may indeed be doing absolutely
nothing.* CMake is unaffected :)
- use namespaces in the CMake config files pleaaaaase
This is going to change things a good bit for package maintainers, but
cest la vie. It's for the greater good, I promise.
Signed-off-by: crueter <crueter@eden-emu.dev>
---
CMakeLists.txt | 108 +++++++++++++++++++++++++-----------------
source/CMakeLists.txt | 62 ++++++++++++------------
2 files changed, 94 insertions(+), 76 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4d843b4d2f..07201f690f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,6 +14,15 @@
cmake_minimum_required(VERSION 3.22.1)
+# master project detection--useful for FetchContent/submodule inclusion
+set(master_project OFF)
+set(subproject ON)
+
+if (NOT DEFINED PROJECT_NAME)
+ set(master_project ON)
+ set(subproject OFF)
+endif()
+
project(spirv-tools)
# Avoid a bug in CMake 3.22.1. By default it will set -std=c++11 for
@@ -135,46 +144,49 @@ if (DEFINED SPIRV_TOOLS_EXTRA_DEFINITIONS)
add_definitions(${SPIRV_TOOLS_EXTRA_DEFINITIONS})
endif()
-# Library build setting definitions:
-#
-# * SPIRV_TOOLS_BUILD_STATIC - ON or OFF - Defaults to ON.
-# If enabled the following targets will be created:
-# ${SPIRV_TOOLS}-static - STATIC library.
-# Has full public symbol visibility.
-# ${SPIRV_TOOLS}-shared - SHARED library.
-# Has default-hidden symbol visibility.
-# ${SPIRV_TOOLS} - will alias to one of above, based on BUILD_SHARED_LIBS.
-# If disabled the following targets will be created:
-# ${SPIRV_TOOLS} - either STATIC or SHARED based on SPIRV_TOOLS_LIBRARY_TYPE.
-# Has full public symbol visibility.
-# ${SPIRV_TOOLS}-shared - SHARED library.
-# Has default-hidden symbol visibility.
-#
-# * SPIRV_TOOLS_LIBRARY_TYPE - SHARED or STATIC.
-# Specifies the library type used for building SPIRV-Tools libraries.
-# Defaults to SHARED when BUILD_SHARED_LIBS=1, otherwise STATIC.
-#
-# * SPIRV_TOOLS_FULL_VISIBILITY - "${SPIRV_TOOLS}-static" or "${SPIRV_TOOLS}"
-# Evaluates to the SPIRV_TOOLS target library name that has no hidden symbols.
-# This is used by internal targets for accessing symbols that are non-public.
-# Note this target provides no API stability guarantees.
-#
-# Ideally, all of these will go away - see https://github.com/KhronosGroup/SPIRV-Tools/issues/3909.
-option(ENABLE_EXCEPTIONS_ON_MSVC "Build SPIRV-TOOLS with c++ exceptions enabled in MSVC" ON)
-option(SPIRV_TOOLS_BUILD_STATIC "Build ${SPIRV_TOOLS}-static target. ${SPIRV_TOOLS} will alias to ${SPIRV_TOOLS}-static or ${SPIRV_TOOLS}-shared based on BUILD_SHARED_LIBS" ON)
-if(SPIRV_TOOLS_BUILD_STATIC)
- set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS}-static)
+# If BUILD_SHARED_LIBS is undefined, set it based on whether we are
+# the master project or a subproject
+if (NOT DEFINED BUILD_SHARED_LIBS)
+ set(BUILD_SHARED_LIBS ${master_project})
+endif()
+
+if (BUILD_SHARED_LIBS)
+ set(static_default OFF)
+else()
+ set(static_default ON)
+endif()
+
+option(SPIRV_TOOLS_BUILD_SHARED "Build ${SPIRV_TOOLS} as a shared library"
+ ${BUILD_SHARED_LIBS})
+option(SPIRV_TOOLS_BUILD_STATIC "Build ${SPIRV_TOOLS} as a static library"
+ ${static_default})
+
+# Avoid conflict between the dll import library and
+# the static library (thanks microsoft)
+if(CMAKE_STATIC_LIBRARY_PREFIX STREQUAL "" AND
+ CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL ".lib")
+ set(SPIRV_TOOLS_STATIC_LIBNAME "${SPIRV_TOOLS}-static")
+else()
+ set(SPIRV_TOOLS_STATIC_LIBNAME "${SPIRV_TOOLS}")
+endif()
+
+if (SPIRV_TOOLS_BUILD_STATIC)
+ # If building a static library at all, always build other libraries as static,
+ # and link to the static SPIRV-Tools library.
set(SPIRV_TOOLS_LIBRARY_TYPE "STATIC")
-else(SPIRV_TOOLS_BUILD_STATIC)
- set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS})
- if (NOT DEFINED SPIRV_TOOLS_LIBRARY_TYPE)
- if(BUILD_SHARED_LIBS)
- set(SPIRV_TOOLS_LIBRARY_TYPE "SHARED")
- else()
- set(SPIRV_TOOLS_LIBRARY_TYPE "STATIC")
- endif()
- endif()
-endif(SPIRV_TOOLS_BUILD_STATIC)
+ set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS}-static)
+elseif (SPIRV_TOOLS_BUILD_SHARED)
+ # If only building a shared library, link other libraries to the
+ # shared library. Also, other libraries should be shared
+ set(SPIRV_TOOLS_LIBRARY_TYPE "SHARED")
+ set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS}-shared)
+else()
+ message(FATAL_ERROR "You must set one of "
+ "SPIRV_TOOLS_BUILD_STATIC or SPIRV_TOOLS_BUILD_SHARED!")
+endif()
+
+option(ENABLE_EXCEPTIONS_ON_MSVC
+ "Build SPIRV-TOOLS with C++ exceptions enabled in MSVC" ON)
function(spvtools_default_compile_options TARGET)
target_compile_options(${TARGET} PRIVATE ${SPIRV_WARNINGS})
@@ -372,7 +384,7 @@ if (NOT "${SPIRV_SKIP_TESTS}")
endif()
set(SPIRV_LIBRARIES "-lSPIRV-Tools-opt -lSPIRV-Tools -lSPIRV-Tools-link")
-set(SPIRV_SHARED_LIBRARIES "-lSPIRV-Tools-shared")
+set(SPIRV_SHARED_LIBRARIES "-lSPIRV-Tools")
# Build pkg-config file
# Use a first-class target so it's regenerated when relevant files are updated.
@@ -388,7 +400,12 @@ add_custom_command(
-DSPIRV_LIBRARIES=${SPIRV_LIBRARIES}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
-add_custom_command(
+
+set(pc_files ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc)
+
+# TODO(crueter): remove?
+if (SPIRV_TOOLS_BUILD_SHARED)
+ add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc
COMMAND ${CMAKE_COMMAND}
-DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
@@ -400,9 +417,12 @@ add_custom_command(
-DSPIRV_SHARED_LIBRARIES=${SPIRV_SHARED_LIBRARIES}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools-shared.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
-add_custom_target(spirv-tools-pkg-config
- ALL
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc)
+ set(pc_files ${pc_files} ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc)
+endif()
+
+add_custom_target(spirv-tools-pkg-config
+ ALL
+ DEPENDS ${pc_files})
# Install pkg-config file
if (ENABLE_SPIRV_TOOLS_INSTALL)
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index bfa1e661bc..fd3712c70c 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -337,49 +337,44 @@ function(spirv_tools_default_target_options target)
)
set_property(TARGET ${target} PROPERTY FOLDER "SPIRV-Tools libraries")
spvtools_check_symbol_exports(${target})
- add_dependencies(${target} spirv-tools-build-version core_tables extinst_tables)
+ add_dependencies(${target}
+ spirv-tools-build-version core_tables extinst_tables)
endfunction()
-# Always build ${SPIRV_TOOLS}-shared. This is expected distro packages, and
-# unlike the other SPIRV_TOOLS target, defaults to hidden symbol visibility.
-add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES})
-if (SPIRV_TOOLS_USE_MIMALLOC)
- target_link_libraries(${SPIRV_TOOLS}-shared PRIVATE mimalloc-static)
+if (SPIRV_TOOLS_BUILD_SHARED)
+ add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES})
+ if (SPIRV_TOOLS_USE_MIMALLOC)
+ target_link_libraries(${SPIRV_TOOLS}-shared PRIVATE mimalloc-static)
+ endif()
+
+ set_target_properties(${SPIRV_TOOLS}-shared PROPERTIES
+ OUTPUT_NAME "${SPIRV_TOOLS}")
+ spirv_tools_default_target_options(${SPIRV_TOOLS}-shared)
+
+ target_compile_definitions(${SPIRV_TOOLS}-shared
+ PRIVATE SPIRV_TOOLS_IMPLEMENTATION
+ PUBLIC SPIRV_TOOLS_SHAREDLIB)
+
+ list(APPEND SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-shared)
endif()
-spirv_tools_default_target_options(${SPIRV_TOOLS}-shared)
-set_target_properties(${SPIRV_TOOLS}-shared PROPERTIES CXX_VISIBILITY_PRESET hidden)
-target_compile_definitions(${SPIRV_TOOLS}-shared
- PRIVATE SPIRV_TOOLS_IMPLEMENTATION
- PUBLIC SPIRV_TOOLS_SHAREDLIB
-)
if(SPIRV_TOOLS_BUILD_STATIC)
add_library(${SPIRV_TOOLS}-static STATIC ${SPIRV_SOURCES})
if (SPIRV_TOOLS_USE_MIMALLOC AND SPIRV_TOOLS_USE_MIMALLOC_IN_STATIC_BUILD)
target_link_libraries(${SPIRV_TOOLS}-shared PRIVATE mimalloc-static)
endif()
+
spirv_tools_default_target_options(${SPIRV_TOOLS}-static)
- # The static target does not have the '-static' suffix.
- set_target_properties(${SPIRV_TOOLS}-static PROPERTIES OUTPUT_NAME "${SPIRV_TOOLS}")
-
- # Create the "${SPIRV_TOOLS}" target as an alias to either "${SPIRV_TOOLS}-static"
- # or "${SPIRV_TOOLS}-shared" depending on the value of BUILD_SHARED_LIBS.
- if(BUILD_SHARED_LIBS)
- add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-shared)
- else()
- add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-static)
- endif()
+ set_target_properties(${SPIRV_TOOLS}-static PROPERTIES
+ OUTPUT_NAME "${SPIRV_TOOLS_STATIC_LIBNAME}")
- set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-static ${SPIRV_TOOLS}-shared)
-else()
- add_library(${SPIRV_TOOLS} ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_SOURCES})
- if (SPIRV_TOOLS_USE_MIMALLOC)
- target_link_libraries(${SPIRV_TOOLS} PRIVATE mimalloc-static)
- endif()
- spirv_tools_default_target_options(${SPIRV_TOOLS})
- set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS} ${SPIRV_TOOLS}-shared)
+ list(APPEND SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-static)
endif()
+# Create the "SPIRV-Tools" target as an alias to either "SPIRV-Tools-static"
+# or "SPIRV-Tools-shared" depending on the value of SPIRV_TOOLS_BUILD_SHARED.
+add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS_FULL_VISIBILITY})
+
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
find_library(LIBRT rt)
if(LIBRT)
@@ -390,14 +385,17 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
endif()
if(ENABLE_SPIRV_TOOLS_INSTALL)
- if (SPIRV_TOOLS_USE_MIMALLOC AND (NOT SPIRV_TOOLS_BUILD_STATIC OR SPIRV_TOOLS_USE_MIMALLOC_IN_STATIC_BUILD))
+ if (SPIRV_TOOLS_USE_MIMALLOC AND
+ (NOT SPIRV_TOOLS_BUILD_STATIC OR SPIRV_TOOLS_USE_MIMALLOC_IN_STATIC_BUILD))
list(APPEND SPIRV_TOOLS_TARGETS mimalloc-static)
endif()
install(TARGETS ${SPIRV_TOOLS_TARGETS} EXPORT ${SPIRV_TOOLS}Targets)
export(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake)
spvtools_config_package_dir(${SPIRV_TOOLS} PACKAGE_DIR)
- install(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake DESTINATION ${PACKAGE_DIR})
+ install(EXPORT ${SPIRV_TOOLS}Targets
+ FILE ${SPIRV_TOOLS}Target.cmake
+ DESTINATION ${PACKAGE_DIR})
# Special config file for root library compared to other libs.
file(WRITE ${CMAKE_BINARY_DIR}/${SPIRV_TOOLS}Config.cmake
+4 -11
View File
@@ -130,7 +130,6 @@ if (YUZU_STATIC_BUILD)
# these libs do not properly provide static libs/let you do it with cmake
set(fmt_FORCE_BUNDLED ON)
set(SPIRV-Tools_FORCE_BUNDLED ON)
set(SPIRV-Headers_FORCE_BUNDLED ON)
set(zstd_FORCE_BUNDLED ON)
endif()
@@ -269,11 +268,6 @@ if (NOT EXISTS ${PROJECT_BINARY_DIR}/${compat_json})
file(WRITE ${PROJECT_BINARY_DIR}/${compat_json} "")
endif()
if (YUZU_LEGACY)
message(WARNING "Making legacy build. Performance may suffer.")
add_compile_definitions(YUZU_LEGACY)
endif()
if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX))
set(HAS_NCE 1)
add_compile_definitions(HAS_NCE=1)
@@ -425,10 +419,10 @@ if (zstd_ADDED)
add_library(zstd::libzstd ALIAS libzstd_static)
endif()
if (NOT YUZU_STATIC_ROOM)
# nlohmann
AddJsonPackage(nlohmann)
# nlohmann
AddJsonPackage(nlohmann)
if (NOT YUZU_STATIC_ROOM)
# zlib
AddJsonPackage(zlib)
@@ -486,7 +480,7 @@ endfunction()
# =============================================
if (APPLE)
foreach(fw Carbon Metal Cocoa IOKit CoreVideo CoreMedia)
foreach(fw Carbon Metal Cocoa IOKit CoreVideo CoreMedia Security)
find_library(${fw}_LIBRARY ${fw} REQUIRED)
list(APPEND PLATFORM_LIBRARIES ${${fw}_LIBRARY})
endforeach()
@@ -523,7 +517,6 @@ if (NOT YUZU_STATIC_ROOM)
find_package(VulkanMemoryAllocator)
find_package(VulkanUtilityLibraries)
find_package(SimpleIni)
find_package(SPIRV-Tools)
find_package(sirit)
find_package(gamemode)
find_package(frozen)
-26
View File
@@ -1,26 +0,0 @@
# 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
include(FindPackageHandleStandardArgs)
find_package(PkgConfig QUIET)
pkg_search_module(SPIRV-Tools QUIET IMPORTED_TARGET SPIRV-Tools)
find_package_handle_standard_args(SPIRV-Tools
REQUIRED_VARS SPIRV-Tools_LINK_LIBRARIES
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)
else()
add_library(SPIRV-Tools::SPIRV-Tools ALIAS PkgConfig::SPIRV-Tools)
endif()
endif()
+8 -6
View File
@@ -33,19 +33,21 @@ endif()
set(GIT_DESC ${BUILD_VERSION})
# Generate cpp with Git revision from template
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
# Auto-updater metadata! Must somewhat mirror GitHub API endpoint
# TODO(crueter): Stable releases feed.
set(BUILD_AUTO_UPDATE_STABLE_REPO "eden-emu/eden")
set(BUILD_AUTO_UPDATE_STABLE_API "git.eden-emu.dev")
set(BUILD_AUTO_UPDATE_STABLE_API_PATH "/api/v1/repos/")
set(BUILD_AUTO_UPDATE_API_PATH "/latest/release.json")
if (NIGHTLY_BUILD)
set(BUILD_AUTO_UPDATE_WEBSITE "https://git.eden-emu.dev")
set(BUILD_AUTO_UPDATE_API "git.eden-emu.dev")
set(BUILD_AUTO_UPDATE_API_PATH "/api/v1/repos/")
set(BUILD_AUTO_UPDATE_API "nightly.eden-emu.dev")
set(BUILD_AUTO_UPDATE_REPO "eden-ci/nightly")
set(REPO_NAME "Eden Nightly")
else()
set(BUILD_AUTO_UPDATE_WEBSITE "https://git.eden-emu.dev")
set(BUILD_AUTO_UPDATE_API "git.eden-emu.dev")
set(BUILD_AUTO_UPDATE_API_PATH "/api/v1/repos/")
set(BUILD_AUTO_UPDATE_API "stable.eden-emu.dev")
set(BUILD_AUTO_UPDATE_REPO "eden-emu/eden")
set(REPO_NAME "Eden")
endif()
+606 -541
View File
File diff suppressed because it is too large Load Diff
+576 -510
View File
File diff suppressed because it is too large Load Diff
+572 -506
View File
File diff suppressed because it is too large Load Diff
+572 -506
View File
File diff suppressed because it is too large Load Diff
+576 -510
View File
File diff suppressed because it is too large Load Diff
+572 -506
View File
File diff suppressed because it is too large Load Diff
+608 -543
View File
File diff suppressed because it is too large Load Diff
+645 -577
View File
File diff suppressed because it is too large Load Diff
+576 -513
View File
File diff suppressed because it is too large Load Diff
+572 -506
View File
File diff suppressed because it is too large Load Diff
+635 -571
View File
File diff suppressed because it is too large Load Diff
+576 -512
View File
File diff suppressed because it is too large Load Diff
+572 -506
View File
File diff suppressed because it is too large Load Diff
+572 -506
View File
File diff suppressed because it is too large Load Diff
+577 -511
View File
File diff suppressed because it is too large Load Diff
+572 -506
View File
File diff suppressed because it is too large Load Diff
+574 -511
View File
File diff suppressed because it is too large Load Diff
+764 -673
View File
File diff suppressed because it is too large Load Diff
+572 -506
View File
File diff suppressed because it is too large Load Diff
+1257 -1185
View File
File diff suppressed because it is too large Load Diff
+576 -512
View File
File diff suppressed because it is too large Load Diff
+576 -510
View File
File diff suppressed because it is too large Load Diff
+577 -512
View File
File diff suppressed because it is too large Load Diff
+572 -506
View File
File diff suppressed because it is too large Load Diff
+572 -506
View File
File diff suppressed because it is too large Load Diff
+578 -511
View File
File diff suppressed because it is too large Load Diff
+573 -509
View File
File diff suppressed because it is too large Load Diff
+30 -4
View File
@@ -4,7 +4,8 @@
- [Arch Linux](#arch-linux)
- [Gentoo Linux](#gentoo-linux)
- [macOS](#macos)
- [Solaris](#solaris)
- [OpenIndiana](#openindiana)
- [OmniOS](#omnios)
- [HaikuOS](#haikuos)
- [OpenBSD](#openbsd)
- [FreeBSD](#freebsd)
@@ -31,14 +32,14 @@ If you're having issues with building, always consult that ebuild.
macOS is largely untested. Expect crashes, significant Vulkan issues, and other fun stuff.
## Solaris
## OpenIndiana
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`.
- **gcc**: Install either `developer/gcc-14`.
- **clang**: Version 20 is broken, 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!
@@ -67,6 +68,31 @@ export LIBGL_ALWAYS_SOFTWARE=1
- If using OpenIndiana, due to a bug in SDL2's CMake configuration, audio driver defaults to SunOS `<sys/audioio.h>`, which does not exist on OpenIndiana. Using external or bundled SDL2 may solve this.
- System OpenSSL generally does not work. Instead, use `-DYUZU_USE_BUNDLED_OPENSSL=ON` to use a bundled static OpenSSL, or build a system dependency from source.
## OmniOS
Install `developer/gcc14` on OmniOS using pkgsrc.
Since so many dependencies are missing on `OmniOS`, you may wish to use `-DCPMUTIL_FORCE_BUNDLED=ON -DYUZU_USE_EXTERNAL_SDL2=ON`
For OmniOS you are required to build glslang yourself:
```sh
sudo pkg install python-313
git clone --depth=1 https://github.com/KhronosGroup/glslang.git
cd glslang
python3.13 ./update_glslang_sources.py
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -- -j `nproc`
cmake --install build
```
It may be tempting to specify `-t glslang`, but this will cause installation to fail. So don't.
Using `--parallel` on CMake incorrectly passes `dmake ... -jn` instead of `dmake ... -j n`, this is a bug with OmniOS's CMake, and as such it's recommended to not use this option until it's fixed.
You may also need to install `gmake` in order to properly build FFmpeg, this is provided by the `build-essential` package.
If it wasn't obvious already, you require a X11 server to properly run the emulator within OmniOS, [this guide](https://web.archive.org/web/20260424200928/https://geekblood.wordpress.com/2017/10/26/installing-x11-and-a-desktop-environment-on-omnios/) is a great starting point for that, the links to pkgsrc are outdated so follow [this exemplar](https://pkgsrc.smartos.org/install-on-illumos/) as well:
## HaikuOS
It's recommended to do a `pkgman full-sync` before installing. See [HaikuOS: Installing applications](https://www.haiku-os.org/guides/daily-tasks/install-applications/). Sometimes the process may be interrupted by an error like "Interrupted syscall". Simply firing the command again fixes the issue. By default `g++` is included on the default installation.
+13 -3
View File
@@ -291,13 +291,23 @@ pkg install gcc14 git cmake unzip nasm autoconf bash pkgconf ffmpeg glslang gmak
</details>
<details>
<summary>Solaris / OpenIndiana</summary>
<summary>OpenIndiana</summary>
```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
sudo pkg install git cmake 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).
[Caveats](./Caveats.md#openindiana).
</details>
<details>
<summary>OmniOS</summary>
```sh
sudo pkgin install git cmake autoconf build-essential libusb-1 nasm gcc13
```
[Caveats](./Caveats.md#omnios).
</details>
<details>
-8
View File
@@ -192,14 +192,6 @@ else()
endif()
endif()
# SPIRV Tools
AddJsonPackage(spirv-tools)
if (SPIRV-Tools_ADDED)
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools-static)
target_link_libraries(SPIRV-Tools-static PRIVATE SPIRV-Tools-opt SPIRV-Tools-link)
endif()
# Catch2
if (YUZU_TESTS OR DYNARMIC_TESTS)
AddJsonPackage(catch2)
-14
View File
@@ -102,20 +102,6 @@
"git_version": "1.3.18",
"find_args": "MODULE"
},
"spirv-tools": {
"package": "SPIRV-Tools",
"repo": "KhronosGroup/SPIRV-Tools",
"sha": "0a7e28689a",
"hash": "eadfcceb82f4b414528d99962335e4f806101168474028f3cf7691ac40c37f323decf2a42c525e2d5bfa6f14ff132d6c5cf9b87c151490efad01f5e13ade1520",
"git_version": "2025.4",
"options": [
"SPIRV_SKIP_EXECUTABLES ON"
],
"patches": [
"0001-netbsd-fix.patch",
"0002-allow-static-only.patch"
]
},
"spirv-headers": {
"package": "SPIRV-Headers",
"repo": "KhronosGroup/SPIRV-Headers",
+2 -2
View File
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
@@ -254,7 +254,7 @@ else()
OUTPUT
${FFmpeg_BUILD_LIBRARIES}
COMMAND
make ${FFmpeg_MAKE_ARGS}
gmake ${FFmpeg_MAKE_ARGS}
WORKING_DIRECTORY
${FFmpeg_BUILD_DIR}
)
+10
View File
@@ -25,6 +25,16 @@ if (NIGHTLY_BUILD)
add_compile_definitions(NIGHTLY_BUILD)
endif()
if (YUZU_LEGACY)
message(WARNING "Making legacy build. Performance may suffer.")
add_compile_definitions(YUZU_LEGACY)
endif()
if (GENSHIN_SPOOF)
message(WARNING "Making Genshin spoof build")
add_compile_definitions(GENSHIN_SPOOF)
endif()
# Set compilation flags
if (MSVC AND NOT CXX_CLANG)
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
+6
View File
@@ -203,6 +203,12 @@ android {
resValue("string", "app_name_suffixed", "Eden Optimized")
applicationId = "com.miHoYo.Yuanshen"
externalNativeBuild {
cmake {
arguments.add("-DGENSHIN_SPOOF=ON")
}
}
ndk {
abiFilters += listOf("arm64-v8a")
}
@@ -33,6 +33,19 @@ import org.yuzu.yuzu_emu.applets.web.WebBrowser
* with the native side of the Yuzu code.
*/
object NativeLibrary {
@Keep
data class UpdateResult(
var tag: String = "",
var title: String = "",
var body: String = "",
var url: String = "",
var assets: MutableList<String> = mutableListOf()
) {
fun addAsset(asset: String) {
assets.add(asset)
}
}
@JvmField
var sEmulationActivity = WeakReference<EmulationActivity?>(null)
@@ -240,17 +253,7 @@ object NativeLibrary {
/**
* Checks for available updates.
*/
external fun checkForUpdate(): Array<String>?
/**
* Return the URL to the release page
*/
external fun getUpdateUrl(version: String): String
/**
* Return the URL to download the APK for the given version
*/
external fun getUpdateApkUrl(tag: String, artifact: String, packageId: String): String
external fun checkForUpdate(): UpdateResult?
/**
* Returns whether the update checker is enabled through CMAKE options.
@@ -15,6 +15,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Rect
import android.graphics.drawable.Icon
@@ -100,6 +101,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
private var romSwapGeneration = 0
private var hasEmulationSession = processHasEmulationSession
private val romSwapStopTimeoutRunnable = Runnable { onRomSwapStopTimeout() }
private val pictureInPictureFailureActions: MutableSet<String> = mutableSetOf()
private fun onRomSwapStopTimeout() {
if (!isWaitingForRomSwapStop) {
@@ -266,12 +268,18 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
}
override fun onUserLeaveHint() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
if (BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && !isInPictureInPictureMode) {
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
enterPictureInPictureMode(pictureInPictureParamsBuilder.build())
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ||
!isPictureInPictureSupported() ||
!BooleanSetting.PICTURE_IN_PICTURE.getBoolean() ||
isInPictureInPictureMode
) {
return
}
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
runPictureInPictureAction("enter picture-in-picture mode") {
enterPictureInPictureMode(pictureInPictureParamsBuilder.build())
}
}
@@ -651,7 +659,29 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
return this.apply { setActions(pictureInPictureActions) }
}
private fun isPictureInPictureSupported() =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
private fun runPictureInPictureAction(actionName: String, action: () -> Unit) {
try {
action()
} catch (e: IllegalStateException) {
if (pictureInPictureFailureActions.add(actionName)) {
Log.warning("[PiP] Failed to $actionName: ${e.message}")
}
} catch (e: UnsupportedOperationException) {
if (pictureInPictureFailureActions.add(actionName)) {
Log.warning("[PiP] Failed to $actionName: ${e.message}")
}
}
}
fun buildPictureInPictureParams() {
if (!isPictureInPictureSupported()) {
return
}
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
@@ -661,7 +691,9 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && isEmulationActive
)
}
setPictureInPictureParams(pictureInPictureParamsBuilder.build())
runPictureInPictureAction("set picture-in-picture params") {
setPictureInPictureParams(pictureInPictureParamsBuilder.build())
}
}
fun displayMultiplayerDialog() {
@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -33,8 +37,10 @@ object SoftwareKeyboard {
val emulationActivity = NativeLibrary.sEmulationActivity.get()
val overlayView = emulationActivity!!.findViewById<View>(R.id.surface_input_overlay)
overlayView.requestFocus()
val im =
overlayView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
im.restartInput(overlayView)
im.showSoftInput(overlayView, InputMethodManager.SHOW_FORCED)
// There isn't a good way to know that the IMM is dismissed, so poll every 500ms to submit inline keyboard result.
@@ -17,6 +17,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
FIX_BLOOM_EFFECTS("fix_bloom_effects"),
EMULATE_BGR565("emulate_bgr565"),
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
USE_DOCKED_MODE("use_docked_mode"),
USE_AUTO_STUB("use_auto_stub"),
@@ -24,7 +24,6 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
RENDERER_ANTI_ALIASING("anti_aliasing"),
RENDERER_SCREEN_LAYOUT("screen_layout"),
RENDERER_ASPECT_RATIO("aspect_ratio"),
RENDERER_OPTIMIZE_SPIRV_OUTPUT("optimize_spirv_output"),
RENDERER_DYNA_STATE("dyna_state"),
DMA_ACCURACY("dma_accuracy"),
@@ -643,15 +643,6 @@ abstract class SettingsItem(
descriptionId = R.string.renderer_async_presentation_description
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT,
titleId = R.string.renderer_optimize_spirv_output,
descriptionId = R.string.renderer_optimize_spirv_output_description,
choicesId = R.array.optimizeSpirvOutputEntries,
valuesId = R.array.optimizeSpirvOutputValues
)
)
put(
SingleChoiceSetting(
IntSetting.DMA_ACCURACY,
@@ -756,6 +747,13 @@ abstract class SettingsItem(
descriptionId = R.string.fix_bloom_effects_description
)
)
put(
SwitchSetting(
BooleanSetting.EMULATE_BGR565,
titleId = R.string.emulate_bgr565,
descriptionId = R.string.emulate_bgr565_description
)
)
put(
SwitchSetting(
BooleanSetting.CPUOPT_UNSAFE_HOST_MMU,
@@ -271,7 +271,6 @@ class SettingsFragmentPresenter(
add(IntSetting.FSR_SHARPENING_SLIDER.key)
}
add(IntSetting.RENDERER_ANTI_ALIASING.key)
add(IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT.key)
add(HeaderSetting(R.string.advanced))
@@ -284,8 +283,6 @@ class SettingsFragmentPresenter(
add(BooleanSetting.SYNC_MEMORY_OPERATIONS.key)
add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key)
add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key)
add(BooleanSetting.RENDERER_ASYNC_PRESENTATION.key)
add(BooleanSetting.RENDERER_REACTIVE_FLUSHING.key)
add(BooleanSetting.ENABLE_BUFFER_HISTORY.key)
add(BooleanSetting.USE_OPTIMIZED_VERTEX_BUFFERS.key)
@@ -295,7 +292,10 @@ class SettingsFragmentPresenter(
add(IntSetting.FAST_GPU_TIME.key)
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
add(BooleanSetting.EMULATE_BGR565.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key)
add(BooleanSetting.RENDERER_ASYNC_PRESENTATION.key)
add(SettingsItem.GPU_UNSWIZZLE_COMBINED)
add(HeaderSetting(R.string.extensions))
@@ -291,13 +291,23 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
// Game launched via intent (check for existing custom config)
intentGame != null -> {
game?.let { gameInstance ->
runCatching { GameHelper.restoreContentForGame(gameInstance) }
.onFailure {
Log.warning(
"[EmulationFragment] Failed to restore content for intent launch: ${it.message}"
)
}
val customConfigFile = SettingsFile.getCustomSettingsFile(gameInstance)
if (customConfigFile.exists()) {
shouldUseCustom = true
Log.info(
"[EmulationFragment] Found existing custom settings for ${gameInstance.title}, loading them"
)
SettingsFile.loadCustomConfig(gameInstance)
NativeConfig.unloadPerGameConfig()
} else {
shouldUseCustom = false
Log.info(
"[EmulationFragment] No custom settings found for ${gameInstance.title}, using global settings"
)
@@ -871,7 +881,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
if (drawerView == binding.quickSettingsSheet) {
isQuickSettingsMenuOpen = true
if (shouldUseCustom) {
SettingsFile.loadCustomConfig(args.game!!)
SettingsFile.loadCustomConfig(game!!)
}
}
}
@@ -2499,7 +2509,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
fun toggleOverlay(enable: Boolean) {
if (!isAdded || _binding == null) return
if (enable && hasPhysicalControllerConnected && !args.overlayGamelessEditMode) return
if (enable == !BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean()) {
// Reset controller input flag so controller can hide overlay again
if (!enable) {
@@ -2537,7 +2546,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
if (binding.surfaceInputOverlay.isGamelessMode()) return
if (hasConnectedControllers) {
if (BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean()) {
if (BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean() &&
BooleanSetting.HIDE_OVERLAY_ON_CONTROLLER_INPUT.getBoolean()) {
overlayHiddenByPhysicalController = true
toggleOverlay(false)
}
@@ -17,16 +17,23 @@ import android.graphics.drawable.VectorDrawable
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.text.Editable
import android.text.InputType
import android.util.AttributeSet
import android.view.HapticFeedbackConstants
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.View.OnTouchListener
import android.view.WindowInsets
import android.view.inputmethod.BaseInputConnection
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
import androidx.core.content.ContextCompat
import androidx.window.layout.WindowMetricsCalculator
import kotlin.math.max
import kotlin.math.min
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.features.input.model.NativeAnalog
@@ -49,6 +56,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
private val overlayButtons: MutableSet<InputOverlayDrawableButton> = HashSet()
private val overlayDpads: MutableSet<InputOverlayDrawableDpad> = HashSet()
private val overlayJoysticks: MutableSet<InputOverlayDrawableJoystick> = HashSet()
private val imeEditable = Editable.Factory.getInstance().newEditable("")
private var inEditMode = false
private var gamelessMode = false
@@ -75,6 +83,63 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
// External listener for EmulationFragment joypad overlay auto-hide
var touchEventListener: ((MotionEvent) -> Unit)? = null
override fun onCheckIsTextEditor(): Boolean = true
override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection {
imeEditable.clear()
outAttrs.inputType =
InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS or
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI or EditorInfo.IME_ACTION_DONE
outAttrs.initialSelStart = 0
outAttrs.initialSelEnd = 0
return object : BaseInputConnection(this, true) {
override fun getEditable(): Editable = imeEditable
override fun commitText(text: CharSequence?, newCursorPosition: Int): Boolean {
if (!text.isNullOrEmpty()) {
forwardCommittedText(text)
}
return super.commitText(text, newCursorPosition)
}
override fun deleteSurroundingText(beforeLength: Int, afterLength: Int): Boolean {
repeat(beforeLength.coerceAtLeast(0)) {
NativeLibrary.submitInlineKeyboardInput(KeyEvent.KEYCODE_DEL)
}
return super.deleteSurroundingText(beforeLength, afterLength)
}
override fun sendKeyEvent(event: KeyEvent): Boolean {
if (event.action != KeyEvent.ACTION_DOWN) {
return true
}
when (event.keyCode) {
KeyEvent.KEYCODE_BACK,
KeyEvent.KEYCODE_DEL,
KeyEvent.KEYCODE_ENTER -> {
NativeLibrary.submitInlineKeyboardInput(event.keyCode)
}
else -> {
val textChar = event.unicodeChar
if (textChar != 0) {
NativeLibrary.submitInlineKeyboardText(textChar.toChar().toString())
}
}
}
return true
}
override fun performEditorAction(actionCode: Int): Boolean {
NativeLibrary.submitInlineKeyboardInput(KeyEvent.KEYCODE_ENTER)
return true
}
}
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
@@ -119,6 +184,25 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
}
}
private fun forwardCommittedText(text: CharSequence) {
val builder = StringBuilder()
text.forEach { character ->
when (character) {
'\n' -> {
if (builder.isNotEmpty()) {
NativeLibrary.submitInlineKeyboardText(builder.toString())
builder.clear()
}
NativeLibrary.submitInlineKeyboardInput(KeyEvent.KEYCODE_ENTER)
}
else -> builder.append(character)
}
}
if (builder.isNotEmpty()) {
NativeLibrary.submitInlineKeyboardText(builder.toString())
}
}
private fun drawGrid(canvas: Canvas) {
val gridSize = IntSetting.OVERLAY_GRID_SIZE.getInt()
val width = canvas.width
@@ -175,25 +175,25 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
val latestVersion = NativeLibrary.checkForUpdate()
if (latestVersion != null) {
runOnUiThread {
val tag: String = latestVersion[0]
val name: String = latestVersion[1]
showUpdateDialog(tag, name)
showUpdateDialog(latestVersion)
}
}
}.start()
}
private fun showUpdateDialog(tag: String, name: String) {
// TODO(crueter): body, "View on Forgejo" button
private fun showUpdateDialog(release: NativeLibrary.UpdateResult) {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.update_available)
.setMessage(getString(R.string.update_available_description, name))
.setMessage(getString(R.string.update_available_description, release.title))
.setPositiveButton(android.R.string.ok) { _, _ ->
var artifact = tag
// Nightly builds have a slightly different format
if (NativeLibrary.isNightlyBuild()) {
artifact = tag.substringAfter('.', tag)
val assets = release.assets
if (assets.isEmpty()) {
openLink(release.url)
} else {
downloadAndInstallUpdate(release)
}
downloadAndInstallUpdate(tag, artifact)
}
.setNeutralButton(R.string.cancel) { dialog, _ ->
dialog.dismiss()
@@ -206,17 +206,23 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
.show()
}
private fun downloadAndInstallUpdate(version: String, artifact: String) {
private fun openLink(link: String) {
val intent = Intent(Intent.ACTION_VIEW, link.toUri())
startActivity(intent)
}
private fun downloadAndInstallUpdate(release: NativeLibrary.UpdateResult) {
CoroutineScope(Dispatchers.IO).launch {
val packageId = applicationContext.packageName
val apkUrl = NativeLibrary.getUpdateApkUrl(version, artifact, packageId)
val asset = release.assets[0]
val artifact = asset.split("/").last()
val apkFile = File(cacheDir, "update-$artifact.apk")
withContext(Dispatchers.Main) {
showDownloadProgressDialog()
}
val downloader = APKDownloader(apkUrl, apkFile)
val downloader = APKDownloader(asset, apkFile)
downloader.download(
onProgress = { progress ->
runOnUiThread {
@@ -248,7 +254,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
} else {
Toast.makeText(
this@MainActivity,
getString(R.string.update_download_failed) + "\n\nURL: $apkUrl",
getString(R.string.update_download_failed) + "\n\nURL: $asset",
Toast.LENGTH_LONG
).show()
}
@@ -277,7 +283,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
private fun updateDownloadProgress(progress: Int) {
progressBar?.progress = progress
progressMessage?.text = "$progress%"
progressMessage?.text = getString(R.string.percent, progress)
}
private fun dismissDownloadProgressDialog() {
@@ -95,7 +95,7 @@ namespace AndroidSettings {
Settings::Setting<u32> input_overlay_auto_hide{linkage, 5, "input_overlay_auto_hide",
Settings::Category::Overlay,
Settings::Specialization::Default, true, true, &enable_input_overlay_auto_hide};
Settings::Setting<bool> hide_overlay_on_controller_input{linkage, false,
Settings::Setting<bool> hide_overlay_on_controller_input{linkage, true,
"hide_overlay_on_controller_input",
Settings::Category::Overlay,
Settings::Specialization::Default, true,
+59 -61
View File
@@ -1699,78 +1699,76 @@ JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_isNightlyBuild(
#ifdef ENABLE_UPDATE_CHECKER
JNIEXPORT jobjectArray JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_checkForUpdate(
JNIEXPORT jobject JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_checkForUpdate(
JNIEnv* env,
jobject obj) {
std::optional<UpdateChecker::Update> release = UpdateChecker::GetUpdate();
std::optional<Common::Net::Release> release = UpdateChecker::GetUpdate();
if (!release) return nullptr;
const std::string tag = release->tag;
const std::string name = release->name;
const std::string title = release->title;
const std::string body = release->body;
const std::string url = release->html_url;
jobjectArray result = env->NewObjectArray(2, env->FindClass("java/lang/String"), nullptr);
// Android *should* only ever define a single asset.
// If not, something has gone wrong, but the Kotlin side can handle it.
const auto assets = release->GetPlatformAssets();
const jstring jtag = env->NewStringUTF(tag.c_str());
const jstring jname = env->NewStringUTF(name.c_str());
env->SetObjectArrayElement(result, 0, jtag);
env->SetObjectArrayElement(result, 1, jname);
env->DeleteLocalRef(jtag);
env->DeleteLocalRef(jname);
return result;
}
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateUrl(
JNIEnv* env,
jobject obj,
jstring version) {
const char* version_str = env->GetStringUTFChars(version, nullptr);
const std::string url = fmt::format("{}/{}/releases/tag/{}",
std::string{Common::g_build_auto_update_website},
std::string{Common::g_build_auto_update_repo},
version_str);
env->ReleaseStringUTFChars(version, version_str);
return env->NewStringUTF(url.c_str());
}
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateApkUrl(
JNIEnv* env,
jobject obj,
jstring tag,
jstring artifact,
jstring packageId) {
const char* version_str = env->GetStringUTFChars(tag, nullptr);
const char* artifact_str = env->GetStringUTFChars(artifact, nullptr);
const char* package_id_str = env->GetStringUTFChars(packageId, nullptr);
std::string variant;
std::string package_id(package_id_str);
if (package_id.find("dev.legacy.eden_emulator") != std::string::npos) {
variant = "legacy";
} else if (package_id.find("com.miHoYo.Yuanshen") != std::string::npos) {
variant = "optimized";
} else {
#ifdef ARCHITECTURE_arm64
variant = "standard";
#else
variant = "chromeos";
#endif
jclass updateResultClass = env->FindClass("org/yuzu/yuzu_emu/NativeLibrary$UpdateResult");
if (!updateResultClass) {
LOG_ERROR(Frontend, "Could not find UpdateResult class");
return nullptr;
}
const std::string apk_filename = fmt::format("Eden-Android-{}-{}.apk", artifact_str, variant);
const std::string url = fmt::format("{}/{}/releases/download/{}/{}",
std::string{Common::g_build_auto_update_website},
std::string{Common::g_build_auto_update_repo},
version_str,
apk_filename);
jmethodID updateResultCtor = env->GetMethodID(updateResultClass, "<init>", "()V");
env->ReleaseStringUTFChars(tag, version_str);
env->ReleaseStringUTFChars(artifact, artifact_str);
env->ReleaseStringUTFChars(packageId, package_id_str);
return env->NewStringUTF(url.c_str());
if (!updateResultCtor) {
LOG_ERROR(Frontend, "Could not find UpdateResult ctor");
env->DeleteLocalRef(updateResultClass);
return nullptr;
}
jmethodID setTag = env->GetMethodID(updateResultClass, "setTag", "(Ljava/lang/String;)V");
jmethodID setTitle = env->GetMethodID(updateResultClass, "setTitle", "(Ljava/lang/String;)V");
jmethodID setBody = env->GetMethodID(updateResultClass, "setBody", "(Ljava/lang/String;)V");
jmethodID setUrl = env->GetMethodID(updateResultClass, "setUrl", "(Ljava/lang/String;)V");
jmethodID addAsset = env->GetMethodID(updateResultClass, "addAsset", "(Ljava/lang/String;)V");
jobject updateResult = env->NewObject(updateResultClass, updateResultCtor);
LOG_DEBUG(Frontend, "Tag: {}", tag);
LOG_DEBUG(Frontend, "Title: {}", title);
LOG_DEBUG(Frontend, "Body: {}", body);
LOG_DEBUG(Frontend, "Url: {}", url);
const auto jtag = env->NewStringUTF(tag.c_str());
const auto jtitle = env->NewStringUTF(title.c_str());
const auto jbody = env->NewStringUTF(body.c_str());
const auto jurl = env->NewStringUTF(url.c_str());
env->CallVoidMethod(updateResult, setTag, jtag);
env->CallVoidMethod(updateResult, setTitle, jtitle);
env->CallVoidMethod(updateResult, setBody, jbody);
env->CallVoidMethod(updateResult, setUrl, jurl);
// TODO(crueter): Handling for multiple assets?
// Maybe another data class x(
for (const Common::Net::Asset &a : assets) {
const auto jaurl = env->NewStringUTF(a.path.c_str());
env->CallVoidMethod(updateResult, addAsset, jaurl);
env->DeleteLocalRef(jaurl);
}
env->DeleteLocalRef(jtag);
env->DeleteLocalRef(jtitle);
env->DeleteLocalRef(jbody);
env->DeleteLocalRef(jurl);
env->DeleteLocalRef(updateResultClass);
return updateResult;
}
#endif
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getBuildVersion(
@@ -32,7 +32,7 @@
<string name="hide_overlay_on_controller_input">إخفاء الطبقة عند إدخال ذراع التحكم</string>
<string name="hide_overlay_on_controller_input_description">إخفاء تلقائي لطبقة عناصر التحكم باللمس عند استخدام ذراع تحكم فعلية. تظهر الطبقة مرة أخرى عند فصل ذراع التحكم.</string>
<string name="invert_confirm_back_controller_buttons">عكس أزرار التأكيد/الرجوع في وحدة التحكم</string>
<string name="invert_confirm_back_controller_buttons_description">قم بتبديل طريقة عمل زري التأكيد والرجوع في نظام Android لتتوافق مع أنماط Switch و Xbox أثناء استخدام واجهة المستخدم الخاصة بالتطبيق.</string>
<string name="invert_confirm_back_controller_buttons_description">تبديل طريقة التعامل مع زري «تأكيد» و«رجوع» في نظام Android لتتوافق مع أنماط أجهزة Switch وXbox أثناء استخدام واجهة المستخدم الخاصة بالتطبيق.</string>
<string name="input_overlay_options">طبقة الإدخال</string>
<string name="input_overlay_options_description">ضبط ذراع التحكم على الشاشة</string>
@@ -268,7 +268,7 @@
<string name="product">المنتج</string>
<string name="android_version">إصدار Android</string>
<string name="android_security_patch">تصحيح الأمان</string>
<string name="build_id">معرف البناء</string>
<string name="build_id">معرف الإصدار</string>
<string name="general_information">معلومات عامة</string>
<string name="hardware">الأجهزة</string>
<string name="supported_abis">واجهات برمجة التطبيقات المدعومة</string>
@@ -287,7 +287,7 @@
<string name="install_amiibo_keys">تثبيت مفاتيح أميبو</string>
<string name="install_amiibo_keys_description">مطلوب لاستخدام أميبو في اللعبة</string>
<string name="gpu_driver_fetcher">أداة جلب برامج تشغيل وحدة المعالجة الرسومية</string>
<string name="gpu_driver_manager">مدير برامج تشغيل وحدة معالجة الرسومات</string>
<string name="gpu_driver_manager">إدارة برامج تشغيل وحدة معالجة الرسومات</string>
<string name="install_gpu_driver_description">تثبيت برامج تشغيل بديلة لأداء أو دقة أفضل</string>
<string name="advanced_settings">الإعدادات المتقدمة</string>
<string name="settings_description">ضبط إعدادات المحاكي</string>
@@ -403,7 +403,7 @@
<string name="contributors">المساهمين</string>
<string name="contributors_description">الأشخاص الذين جعلوا تطبيق Eden لنظام Android ممكنًا</string>
<string name="licenses_description">المشاريع التي تجعل Eden لأجهزة Android ممكنة</string>
<string name="build">البناء</string>
<string name="build">الإصدار</string>
<string name="user_data">بيانات المستخدم</string>
<string name="user_data_description">استيراد/تصدير جميع بيانات التطبيق.\nعند استيراد بيانات المستخدم، سيتم حذف جميع بيانات المستخدم الموجودة!\nقد يُسبب استيراد البيانات من Citron بعض المشاكل. يُنصح باستيراد جميع البيانات المطلوبة يدويًا.</string>
<string name="exporting_user_data">جارٍ تصدير بيانات المستخدم...</string>
@@ -463,8 +463,6 @@
<string name="fsr_sharpness">حدة FSR</string>
<string name="fsr_sharpness_description">يحدد مدى وضوح الصورة عند استخدام التباين الديناميكي لـ FSR</string>
<string name="renderer_anti_aliasing">طريقة مضاد التعرج</string>
<string name="renderer_optimize_spirv_output">تحسين مخرجات SPIRV</string>
<string name="renderer_optimize_spirv_output_description">يعمل على تحسين أداء برامج التظليل المجمعة لتحسين كفاءة وحدة معالجة الرسومات، ولكنه قد يؤدي إلى زيادة وقت التحميل وإبطاء السرعة في البداية.</string>
<string name="advanced">متقدم</string>
@@ -486,12 +484,16 @@
<string name="use_disk_shader_cache_description">يقلل من التأتأة عن طريق تخزين وتحميل التظليلات التي تم إنشاؤها محليًا.</string>
<string name="renderer_force_max_clock">إجبار السرعة القصوى (لأجهزة Adreno فقط)</string>
<string name="renderer_force_max_clock_description">يجبر وحدة معالجة الرسومات على العمل بأقصى سرعة ممكنة (سيظل يتم تطبيق القيود الحرارية).</string>
<string name="renderer_asynchronous_gpu_emulation">محاكاة غير متزامنة لوحدة معالجة الرسومات</string>
<string name="renderer_asynchronous_gpu_emulation_description">يُشغّل هذا الخيار محاكاة وحدة معالجة الرسومات بشكل غير متزامن لتقليل توقف وحدة المعالجة المركزية وتحسين الإنتاجية. عطّل هذا الخيار فقط في حال واجهت مشاكل متعلقة بالتوقيت.</string>
<string name="renderer_async_presentation">عرض غير متزامن</string>
<string name="renderer_async_presentation_description">يحسّن الأداء بشكل طفيف عن طريق نقل عملية العرض إلى خيط معالجة منفصل لوحدة المعالجة المركزية.</string>
<string name="renderer_reactive_flushing">استخدم التنظيف التفاعلي</string>
<string name="renderer_reactive_flushing_description">يحسن دقة العرض في بعض الألعاب على حساب الأداء.</string>
<string name="enable_buffer_history">تمكين سجل التخزين المؤقت</string>
<string name="enable_buffer_history_description">يُتيح هذا الخيار الوصول إلى حالات التخزين المؤقت السابقة. وقد يُحسّن جودة العرض وثبات الأداء في بعض الألعاب.</string>
<string name="use_optimized_vertex_buffers">مخازن الرؤوس المُحسّنة</string>
<string name="use_optimized_vertex_buffers_description">يُتيح ربطًا مُحسَّنًا لمخازن الرؤوس لتحسين الأداء. يتطلب برامج تشغيل Turnip من Mesa 26.0 أو أحدث. قد يتعطل على برامج التشغيل الأقدم.</string>
<string name="use_optimized_vertex_buffers_description">يتيح ربط مخزن الرؤوس المُحسّن لتحسين الأداء. يتطلب برامج تشغيل Turnip/QCOM من إصدار Mesa 26.0 أو أحدث. سيؤدي إلى تعطل النظام عند استخدام برامج تشغيل Turnip الأقدم.</string>
<string name="hacks">اختراقات</string>
@@ -500,7 +502,9 @@
<string name="skip_cpu_inner_invalidation">تخطي إبطال صلاحية وحدة المعالجة المركزية الداخلية</string>
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقتة من جانب وحدة المعالجة المركزية أثناء تحديثات الذاكرة، مما يقلل من استخدام وحدة المعالجة المركزية ويحسن أداءها. قد يتسبب ذلك في حدوث أعطال أو تعطل في بعض الألعاب.</string>
<string name="fix_bloom_effects">إصلاح تأثيرات التوهج</string>
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno 700)، ويزيل التوهج في Burnout. تحذير: قد يسبب ظهور خلل رسومي في ألعاب أخرى.</string>
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno A6XX - A7XX/ Turnip)، ويزيل التوهج في Burnout. تحذير: قد يسبب تشوهات رسومية في ألعاب أخرى.</string>
<string name="emulate_bgr565">محاكاة BGR565</string>
<string name="emulate_bgr565_description">يُصلح مشاكل انعكاس الألوان في الألعاب أو ظهور تشوهات غريبة أو ظلال غريبة.</string>
<string name="renderer_asynchronous_shaders">استخدم تظليل غير متزامن</string>
<string name="renderer_asynchronous_shaders_description">يقوم بتجميع التظليل بشكل غير متزامن. قد يقلل ذلك من التقطعات ولكنه قد يؤدي أيضًا إلى حدوث أخطاء.</string>
<string name="gpu_unswizzle_settings">إعدادات إلغاء ترتيب بيانات وحدة معالجة الرسومات</string>
@@ -627,10 +631,10 @@
<string name="gamecube_controller">ذراع تحكم GameCube</string>
<string name="invert_axis">عكس المحور</string>
<string name="invert_button">عكس الزر</string>
<string name="toggle_button">زر التبديل</string>
<string name="toggle_button">زر تشغيل/إيقاف</string>
<string name="turbo_button">زر التوربو</string>
<string name="set_threshold">تعيين الحد الفاصل</string>
<string name="toggle_axis">تبديل المحور</string>
<string name="toggle_axis">تشغيل/إيقاف المحور</string>
<string name="connected">متصل</string>
<string name="use_system_vibrator">استخدم هزاز النظام</string>
<string name="input_overlay">طبقة الإدخال</string>
@@ -656,7 +660,7 @@
<!-- Miscellaneous -->
<string name="slider_default">افتراضي</string>
<string name="default_string">الافتراضي</string>
<string name="default_string">افتراضي</string>
<string name="loading">جارٍ التحميل…</string>
<string name="shutting_down">جارٍ إيقاف التشغيل...</string>
<string name="reset_setting_confirmation">هل تريد إعادة تعيين هذا الإعداد إلى قيمته الافتراضية؟</string>
@@ -682,8 +686,8 @@
<string name="import_success">تم الاستيراد بنجاح</string>
<string name="export_success">تم التصدير بنجاح</string>
<string name="start">بدء</string>
<string name="global">المتغيرات العامة</string>
<string name="custom">مخصص</string>
<string name="global">الإعدادات العامة</string>
<string name="custom">الإعدادات المخصصة للعبة</string>
<string name="import_complete">اكتمل الاستيراد</string>
<string name="use_global_setting">استخدام الإعداد العام</string>
<string name="operation_completed_successfully">اكتملت العملية بنجاح</string>
@@ -762,7 +766,7 @@
<string name="info_description">معرف العنوان، المطور، الإصدار</string>
<string name="per_game_settings">الإعدادات الخاصة للعبة</string>
<string name="per_game_settings_description">تعديل الإعدادات الخاصة بهذه اللعبة</string>
<string name="launch_options">تشغيل الإعدادات</string>
<string name="launch_options">إعدادات التشغيل</string>
<string name="path">المسار</string>
<string name="program_id">معرف العنوان</string>
<string name="developer">المطور</string>
@@ -874,13 +878,13 @@
<!-- Emulation Menu -->
<string name="emulation_exit">خروج من المحاكاة</string>
<string name="emulation_done">إنهاء</string>
<string name="emulation_toggle_controls">تبديل أزرار التحكم</string>
<string name="emulation_toggle_controls">تشغيل/إيقاف أزرار التحكم</string>
<string name="emulation_rel_stick_center">مركز العصا النسبي</string>
<string name="emulation_dpad_slide">انزلاق الأسهم</string>
<string name="emulation_haptics">الاهتزازات الديناميكية</string>
<string name="emulation_show_overlay">عرض ذراع التحكم</string>
<string name="emulation_hide_overlay">إخفاء ذراع التحكم</string>
<string name="emulation_toggle_all">تبديل الكل</string>
<string name="emulation_toggle_all">تشغيل/إيقاف الكل</string>
<string name="emulation_control_adjust">ضبط الطبقة</string>
<string name="emulation_control_scale">الحجم</string>
<string name="emulation_control_opacity">الشفافية</string>
@@ -1122,7 +1126,7 @@
<string name="enable_overlay_description">تمكين التطبيق الصغير المدمج في Horizon. اضغط مع الاستمرار على زر الشاشة الرئيسية لمدة 1 ثانية لإظهاره.</string>
<!-- Profile Management -->
<string name="profile_manager">مدير الملف الشخصي</string>
<string name="profile_manager">إدارة ملف التعريف</string>
<string name="profile_manager_description">إدارة ملفات تعريف المستخدمين</string>
<string name="profile_add_user">إضافة مستخدم</string>
<string name="profile_new_user">مستخدم جديد</string>
@@ -1155,5 +1159,6 @@
<string name="license_fidelityfx_fsr_description">تحسين الجودة بدرجة عالية من AMD</string>
<string name="external_content">محتوى خارجي</string>
<string name="add_folders">إضافة مجلد</string>
<string name="percent">%1$d%%</string>
</resources>
@@ -332,7 +332,6 @@
<string name="fsr_sharpness">تیژی FSR</string>
<string name="fsr_sharpness_description">دیاریکردنی تیژی وێنە لە کاتی بەکارهێنانی FSR</string>
<string name="renderer_anti_aliasing">شێوازی دژە-خاوڕۆیی</string>
<string name="renderer_optimize_spirv_output_description">شێیدەرە کۆمپایلکراوەکان باش دەکات بۆ باشترکردنی کارایی GPU.</string>
<string name="dma_accuracy">وردیی DMA</string>
@@ -442,8 +442,6 @@
<string name="fsr_sharpness">Ostrost FSR</string>
<string name="fsr_sharpness_description">Určuje jak ostře bude obraz vypadat při použití dynamického kontrastu FSR.</string>
<string name="renderer_anti_aliasing">Metoda anti-aliasingu</string>
<string name="renderer_optimize_spirv_output">Optimalizovat výstup SPIRV</string>
<string name="renderer_optimize_spirv_output_description">Optimalizuje kompilované shadery pro zlepšení efektivity GPU, ale mohou se objevit delší nahrávací časy a zpomalení v úvodu.</string>
<string name="advanced">Pokročilé</string>
@@ -442,8 +442,6 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
<string name="fsr_sharpness">FSR-Schärfe</string>
<string name="fsr_sharpness_description">Bestimmt die Schärfe bei FSR-Nutzung.</string>
<string name="renderer_anti_aliasing">Kantenglättung</string>
<string name="renderer_optimize_spirv_output">Optimiere SPIRV-Ausgabe</string>
<string name="renderer_optimize_spirv_output_description">Optimiert den kompilierten Shader, um die GPU-Effizienz zu verbessern.</string>
<string name="advanced">Erweitert</string>
@@ -351,7 +351,7 @@
<item quantity="other">%d archivos de guardado importados con éxito.</item>
</plurals>
<string name="no_save_data_found">No se encontraron datos de guardado</string>
<string name="verify_installed_content">Verificar contenido instalado</string>
<string name="verify_installed_content">Verificar los contenidos instalados</string>
<string name="verify_installed_content_description">Comprueba todo el contenido instalado por si hubiese alguno corrupto</string>
<string name="keys_missing">Faltan las claves de encriptación</string>
@@ -457,8 +457,6 @@
<string name="fsr_sharpness">Nitidez FSR</string>
<string name="fsr_sharpness_description">Ajusta la intensidad del filtro de enfoque al usar el contraste dinámico de FSR.</string>
<string name="renderer_anti_aliasing">Método de suavizado de bordes</string>
<string name="renderer_optimize_spirv_output">Optimizar la salida de SPIRV</string>
<string name="renderer_optimize_spirv_output_description">Optimiza los sombreadores compilados para mejorar la eficiencia de la GPU.</string>
<string name="advanced">Avanzado</string>
@@ -480,12 +478,16 @@
<string name="use_disk_shader_cache_description">Reduce los tirones almacenando y cargando los sombreadores generados.</string>
<string name="renderer_force_max_clock">Forzar velocidad al máximo (solo Adreno)</string>
<string name="renderer_force_max_clock_description">Fuerza a la GPU a ejecutarse a la velocidad máxima de reloj posible (se seguirán aplicando restricciones térmicas).</string>
<string name="renderer_asynchronous_gpu_emulation">Emulación de GPU asíncrona</string>
<string name="renderer_asynchronous_gpu_emulation_description">Ejecuta la emulación de la GPU de forma asíncrona para reducir los bloqueos de la CPU y mejorar el rendimiento. Desactiva esta opción solo si experimentas problemas de sincronización.</string>
<string name="renderer_async_presentation">Presentación asíncrona</string>
<string name="renderer_async_presentation_description">Mejora ligeramente el rendimiento al mover la presentación a un hilo independiente de la CPU.</string>
<string name="renderer_reactive_flushing">Usar limpieza reactiva</string>
<string name="renderer_reactive_flushing_description">Mejora la precisión de renderizado en algunos juegos, pero reduce el rendimiento.</string>
<string name="enable_buffer_history">Activar el historial del búfer</string>
<string name="enable_buffer_history_description">Permite el acceso al estado del búfer anterior. Esta opción puede mejorar la calidad de renderizado y la consistencia en el rendimiento de algunos juegos.</string>
<string name="use_optimized_vertex_buffers">Búferes de vértices optimizados</string>
<string name="use_optimized_vertex_buffers_description">Permite la vinculación optimizada del búfer de vértices para un mejor rendimiento. Requiere controladores de Mesa 26.0+ Turnip. Se producin fallos en controladores más antiguos.</string>
<string name="use_optimized_vertex_buffers_description">Permite la optimización del enlace del búfer de vértices para un mejor rendimiento. Requiere controladores Mesa 26.0+ Turnip/ controladores QCOM. Causará fallos con controladores Turnip más antiguos.</string>
<string name="hacks">Hacks</string>
@@ -494,7 +496,9 @@
<string name="skip_cpu_inner_invalidation">Omitir invalidación interna de la CPU</string>
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché de la CPU durante las actualizaciones de memoria, lo que reduce el uso de la CPU y mejora su rendimiento. Esto puede causar fallos o bloqueos en algunos juegos.</string>
<string name="fix_bloom_effects">Arreglar los efectos de resplandor</string>
<string name="fix_bloom_effects_description">Reduce el efecto de resplandor en LA/EOW (Adreno 700), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos.</string>
<string name="fix_bloom_effects_description">Reduce el efecto de resplandor en LA/EOW (Adreno A6XX - A7XX/ Turnip), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos.</string>
<string name="emulate_bgr565">Emular BGR565</string>
<string name="emulate_bgr565_description">Soluciona problemas con colores invertidos en juegos, artefactos o sombras extrañas.</string>
<string name="renderer_asynchronous_shaders">Usar sombreadores asíncronos</string>
<string name="renderer_asynchronous_shaders_description">Compila los sombreadores de forma asíncrona. Esto puede reducir los tirones, pero también puede introducir errores gráficos.</string>
<string name="gpu_unswizzle_settings">Ajustes de desentrelazado de la GPU</string>
@@ -763,7 +767,7 @@
<string name="version">Versión</string>
<string name="copy_details">Copiar detalles</string>
<string name="add_ons">Complementos</string>
<string name="add_ons_description">Activa/desactiva mods, actualizaciones y contenidos descargables</string>
<string name="add_ons_description">Alternar mods, actualizaciones y contenido descargable</string>
<string name="playtime">Tiempo jugado:</string>
<string name="reset_playtime">Borrar tiempo de juego</string>
<string name="reset_playtime_description">Restablecer el tiempo de juego actual a 0 segundos</string>
@@ -1149,5 +1153,6 @@
<string name="license_fidelityfx_fsr_description">Upscaling de alta calidad de AMD</string>
<string name="external_content">Contenido externo</string>
<string name="add_folders">Añadir carpeta</string>
<string name="percent">%1$d%%</string>
</resources>
@@ -125,8 +125,6 @@
<string name="nvdec_emulation_none">هیچ‌کدام</string>
<!-- Optimize Spir-V output -->
<string name="renderer_optimize_spirv_output">بهینه‌سازی خروجی Spir-V</string>
<string name="renderer_optimize_spirv_output_description">شیدر کامپایل شده را برای بهبود کارایی GPU بهینه‌سازی می‌کند.</string>
<string name="never">هرگز</string>
<string name="on_load">در هنگام بارگذاری</string>
<string name="always">همیشه</string>
@@ -413,7 +413,9 @@
<string name="frame_limit_slider">Limiter le pourcentage de vitesse</string>
<string name="frame_limit_slider_description">Spécifier le pourcentage pour limiter la vitesse d\'émulation. 100% correspond à la vitesse normale. Des valeurs plus élevées ou plus basses augmenteront ou diminueront la limite de vitesse.</string>
<string name="turbo_speed_limit">Vitesse turbo</string>
<string name="turbo_speed_limit_description">Lorsque le mode Turbo est activé, l\'émulation s\'exécute à cette vitesse.</string>
<string name="slow_speed_limit">Vitesse lente</string>
<string name="slow_speed_limit_description">Lorsque le mode Lent est activé, l\'émulation s\'exécute à cette vitesse.</string>
<string name="cpu_backend">Backend du CPU</string>
<string name="cpu_accuracy">Précision du CPU</string>
<string name="value_with_units">%1$s%2$s</string>
@@ -455,7 +457,6 @@
<string name="fsr_sharpness">Netteté FSR</string>
<string name="fsr_sharpness_description">Détermine à quel point l\'image sera affinée lors de l\'utilisation du contraste dynamique FSR.</string>
<string name="renderer_anti_aliasing">Méthode d\'anticrénelage</string>
<string name="renderer_optimize_spirv_output_description">Optimise le shader compilé pour améliorer l\'efficacité du GPU.</string>
<string name="dma_accuracy">Précision DMA</string>
@@ -362,7 +362,6 @@
<string name="fsr_sharpness">חדות FSR</string>
<string name="fsr_sharpness_description">קובע את מידת החדות בעת שימוש ב-FSR.</string>
<string name="renderer_anti_aliasing">שיטת Anti-aliasing</string>
<string name="renderer_optimize_spirv_output_description">משפר את השאדר המהודר כדי להגביר את יעילות ה-GPU.</string>
<string name="dma_accuracy">דיוק DMA</string>
@@ -351,7 +351,6 @@
<string name="fsr_sharpness">FSR élesség</string>
<string name="fsr_sharpness_description">Meghatározza, milyen éles lesz a kép az FSR dinamikus kontraszt használata közben.</string>
<string name="renderer_anti_aliasing">Élsimítási módszer</string>
<string name="renderer_optimize_spirv_output_description">Optimalizálja a lefordított shadert a GPU hatékonyságának javításáért.</string>
<string name="dma_accuracy">DMA pontosság</string>
@@ -383,7 +383,6 @@
<string name="fsr_sharpness">Ketajaman FSR</string>
<string name="fsr_sharpness_description">Menentukan seberapa tajam gambar akan terlihat saat menggunakan kontras dinamis FSR</string>
<string name="renderer_anti_aliasing">Metode anti-aliasing</string>
<string name="renderer_optimize_spirv_output_description">Mengoptimalkan shader yang dikompilasi untuk meningkatkan efisiensi GPU.</string>
<string name="dma_accuracy">Akurasi DMA</string>
@@ -390,7 +390,6 @@
<string name="fsr_sharpness">Nitidezza FSR</string>
<string name="fsr_sharpness_description">Determina quanto sarà nitida l\'immagine utilizzando il contrasto dinamico di FSR</string>
<string name="renderer_anti_aliasing">Metodo di anti-aliasing</string>
<string name="renderer_optimize_spirv_output_description">Ottimizza lo shader compilato per migliorare l\'efficienza della GPU.</string>
<string name="dma_accuracy">Precisione DMA</string>
@@ -349,7 +349,6 @@
<string name="renderer_vsync">垂直同期モード</string>
<string name="renderer_scaling_filter">ウィンドウ適応フィルター</string>
<string name="renderer_anti_aliasing">アンチエイリアス方式</string>
<string name="renderer_optimize_spirv_output_description">コンパイル済みシェーダーを最適化し、GPUの効率を向上させます。</string>
<string name="dma_accuracy">DMA精度</string>
@@ -349,7 +349,6 @@
<string name="renderer_vsync">수직동기화 모드</string>
<string name="renderer_scaling_filter">윈도우 적응 필터</string>
<string name="renderer_anti_aliasing">안티에일리어싱 방법</string>
<string name="renderer_optimize_spirv_output_description">컴파일된 셰이더를 최적화하여 GPU 효율성을 향상시킵니다.</string>
<string name="dma_accuracy">DMA 정확도</string>
@@ -332,7 +332,6 @@
<string name="fsr_sharpness">FSR-skarphet</string>
<string name="fsr_sharpness_description">Bestemmer bildekvalitet med FSR</string>
<string name="renderer_anti_aliasing">Anti-aliasing-metode</string>
<string name="renderer_optimize_spirv_output_description">Optimaliserer den kompilerte shaderen for å forbedre GPU-effektiviteten.</string>
<string name="dma_accuracy">DMA-nøyaktighet</string>
@@ -442,8 +442,6 @@
<string name="fsr_sharpness">Ostrość FSR</string>
<string name="fsr_sharpness_description">Kontroluje ostrość obrazu w FSR.</string>
<string name="renderer_anti_aliasing">Metoda wygładzania krawędzi</string>
<string name="renderer_optimize_spirv_output">Optymalizuj wyjście SPIRV</string>
<string name="renderer_optimize_spirv_output_description">Optymalizuje skompilowany shader w celu poprawy wydajności GPU.</string>
<string name="advanced">Zaawansowane</string>
@@ -433,7 +433,6 @@
<string name="fsr_sharpness">Nitidez do FSR</string>
<string name="fsr_sharpness_description">Determina a nitidez da imagem ao utilizar o contraste dinâmico do FSR</string>
<string name="renderer_anti_aliasing">Método de Anti-aliasing</string>
<string name="renderer_optimize_spirv_output_description">Otimiza o shader compilado para melhorar a eficiência da GPU.</string>
<string name="advanced">Avançado</string>
@@ -355,7 +355,6 @@
<string name="fsr_sharpness">Nitidez do FSR</string>
<string name="fsr_sharpness_description">Determina a nitidez da imagem ao usar contraste dinâmico do FSR</string>
<string name="renderer_anti_aliasing">Método de Anti-Serrilhado</string>
<string name="renderer_optimize_spirv_output_description">Otimiza o shader compilado para melhorar a eficiência da GPU.</string>
<string name="dma_accuracy">Precisão da DMA</string>
@@ -459,8 +459,6 @@
<string name="fsr_sharpness">Резкость FSR</string>
<string name="fsr_sharpness_description">Определяет, насколько чётким будет изображение при использовании динамического контраста FSR.</string>
<string name="renderer_anti_aliasing">Метод сглаживания</string>
<string name="renderer_optimize_spirv_output">Оптимизация вывода SPIRV</string>
<string name="renderer_optimize_spirv_output_description">Оптимизирует скомпилированный шейдер для повышения эффективности ГПУ.</string>
<string name="advanced">Расширенные</string>
@@ -482,12 +480,16 @@
<string name="use_disk_shader_cache_description">Уменьшение зависаний за счет хранения и загрузки сгенерированных шейдеров.</string>
<string name="renderer_force_max_clock">Принудительная максимальная тактовая частота (только для Adreno)</string>
<string name="renderer_force_max_clock_description">Заставляет ГПУ работать на максимально возможных тактовых частотах (тепловые ограничения все равно будут применяться).</string>
<string name="renderer_asynchronous_gpu_emulation">Асинхронная эмуляция ГПУ</string>
<string name="renderer_asynchronous_gpu_emulation_description">Выполняет эмуляцию ГПУ асинхронно для снижения задержек ЦП и увеличения производительности. Отключайте только при возникновении проблем с таймингами.</string>
<string name="renderer_async_presentation">Асинхронная презентация</string>
<string name="renderer_async_presentation_description">Немного улучшает производительность, перемещая презентацию в отдельный поток ЦП.</string>
<string name="renderer_reactive_flushing">Реактивная очистка</string>
<string name="renderer_reactive_flushing_description">Повышение точности рендеринга в некоторых играх за счет снижения производительности.</string>
<string name="enable_buffer_history">Включить историю буфера</string>
<string name="enable_buffer_history_description">Позволяет обращаться к предыдущим состояниям буфера. Эта опция может повысить качество рендеринга и стабильность производительности в некоторых играх.</string>
<string name="use_optimized_vertex_buffers">Оптимизированные вершинные буферы</string>
<string name="use_optimized_vertex_buffers_description">Активирует оптимизированную привязку вершинных буферов для улучшения производительности. Требуются Mesa Turnip драйвера версией не ниже 26.0, на более старых драйверах будут происходить сбои и краши</string>
<string name="use_optimized_vertex_buffers_description">Включает оптимизированную привязку вершинного буфера для повышения производительности. Требует Mesa Turnip 26.0+ / QCOM драйверы. Приводит к вылету на старых версиях Turnip.</string>
<string name="hacks">Хаки</string>
@@ -496,7 +498,9 @@
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
<string name="fix_bloom_effects">Исправить эффекты размытия</string>
<string name="fix_bloom_effects_description">Частично убирает размытие в LA/EOW (Adreno 700), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх.</string>
<string name="fix_bloom_effects_description">Частично убирает размытие в LA/EOW (Adreno A6XX - A7XX/ Turnip), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх.</string>
<string name="emulate_bgr565">Эмулировать BGR565</string>
<string name="emulate_bgr565_description">Исправляет проблемы с инвертированными цветами в играх, а также со странными артефактами или некорректными тенями.</string>
<string name="renderer_asynchronous_shaders">Использовать асинхронные шейдеры</string>
<string name="renderer_asynchronous_shaders_description">Компилирует шейдеры асинхронно. Это может уменьшить подтормаживания, но также может вызвать графические артефакты.</string>
<string name="gpu_unswizzle_settings">Настройки распаковки текстур (Unswizzle)</string>
@@ -1080,6 +1084,7 @@
<string name="app_language_system">Следовать системе</string>
<!-- Static Themes -->
<string name="static_theme_color">Цвет темы</string>
<string name="eden_theme">Eden</string>
<string name="violet">Фиолетовый </string>
<string name="blue">Синий</string>
<string name="cyan">Циановый</string>
@@ -1150,5 +1155,4 @@
<string name="license_fidelityfx_fsr_description">Высококачественное масштабирование от AMD</string>
<string name="external_content">Дополнительный контент</string>
<string name="add_folders">Добавить папку</string>
</resources>
</resources>
@@ -354,7 +354,6 @@
<string name="fsr_sharpness">ФСР оштрина</string>
<string name="fsr_sharpness_description">Одређује колико ће се слика наоштрен трајати док користи \"ФСР\" динамички контраст</string>
<string name="renderer_anti_aliasing">Метода против алиасирања</string>
<string name="renderer_optimize_spirv_output_description">Оптимизира састављена схадер за побољшање ефикасности ГПУ-а.</string>
<string name="dma_accuracy">DMA тачност</string>
@@ -459,8 +459,6 @@
<string name="fsr_sharpness">Різкість FSR</string>
<string name="fsr_sharpness_description">Визначає різкість зображення при використанні FSR.</string>
<string name="renderer_anti_aliasing">Згладжування</string>
<string name="renderer_optimize_spirv_output">Оптимізовувати виведення SPIRV</string>
<string name="renderer_optimize_spirv_output_description">Оптимізує скомпільований шейдер для покращення ефективності GPU.</string>
<string name="advanced">Додаткові</string>
@@ -482,12 +480,16 @@
<string name="use_disk_shader_cache_description">Зменшує затримки шляхом збереження шейдерів.</string>
<string name="renderer_force_max_clock">Максимальна тактова частота (тільки Adreno)</string>
<string name="renderer_force_max_clock_description">Змушує GPU працювати на максимальній тактовій частоті.</string>
<string name="renderer_asynchronous_gpu_emulation">Асинхронна емуляція ГП</string>
<string name="renderer_asynchronous_gpu_emulation_description">Емуляція ГП виконується асинхронно для зменшення затримок ЦП й покращення пропускної здатності. Вимкніть лише у випадку виникнення проблем із таймінгами.</string>
<string name="renderer_async_presentation">Асинхронне подання</string>
<string name="renderer_async_presentation_description">Трохи покращує продуктивність завдяки переміщенню подання на окремий потік ЦП.</string>
<string name="renderer_reactive_flushing">Реактивне очищення</string>
<string name="renderer_reactive_flushing_description">Покращує точність рендерингу в деяких іграх.</string>
<string name="enable_buffer_history">Увімкнути історію буфера</string>
<string name="enable_buffer_history_description">Вмикає доступ до попередніх станів буфера. Цей параметр може покращити якість візуалізації та стабільну продуктивність у деяких іграх.</string>
<string name="use_optimized_vertex_buffers">Оптимізовані буфери вершин</string>
<string name="use_optimized_vertex_buffers_description">Застосовує оптимізований буфер вершин, щоб покращити продуктивність. Потребує драйверів Mesa 26.0+ Turnip. На старіших драйверах виникатиме збій.</string>
<string name="use_optimized_vertex_buffers_description">Застосовує оптимізований буфер вершин, щоб покращити продуктивність. Потребує драйверів Mesa 26.0+ Turnip / QCOM. На старіших драйверах Turnip виникатиме збій.</string>
<string name="hacks">Обхідні рішення</string>
@@ -496,7 +498,9 @@
<string name="skip_cpu_inner_invalidation">Пропустити внутрішнє інвалідування CPU</string>
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
<string name="fix_bloom_effects">Виправити ефекти світіння</string>
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno 700), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno A6XXA7XX / Turnip), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
<string name="emulate_bgr565">Емулювати BGR565</string>
<string name="emulate_bgr565_description">Виправляє проблеми з інвертованими кольорами в іграх або дивними артефактами чи тінями.</string>
<string name="renderer_asynchronous_shaders">Асинхронні шейдери</string>
<string name="renderer_asynchronous_shaders_description">Компілює шейдери асинхронно. Це може зменшити затримки, але також може спричинити графічні баги.</string>
<string name="gpu_unswizzle_settings">Налаштування розпакування за допомогою ГП</string>
@@ -1151,5 +1155,6 @@
<string name="license_fidelityfx_fsr_description">Високоякісне масштабування від AMD</string>
<string name="external_content">Зовнішній вміст</string>
<string name="add_folders">Додати теку</string>
<string name="percent">%1$d%%</string>
</resources>
@@ -330,7 +330,6 @@
<string name="fsr_sharpness">Độ sắc nét FSR</string>
<string name="fsr_sharpness_description">Độ sắc nét khi dùng FSR</string>
<string name="renderer_anti_aliasing">Phương pháp khử răng cưa</string>
<string name="renderer_optimize_spirv_output_description">Tối ưu hóa shader đã biên dịch để cải thiện hiệu suất GPU.</string>
<string name="dma_accuracy">Độ chính xác DMA</string>
@@ -55,7 +55,7 @@
<string name="stats_overlay_options_description">配置性能统计叠加层中显示的信息</string>
<string name="show_fps">显示帧率</string>
<string name="show_fps_description">显示当前帧率</string>
<string name="show_frametime">显示帧时间</string>
<string name="show_frametime">显示 Frametime</string>
<string name="show_app_ram_usage">显示应用内存使用情况</string>
<string name="show_app_ram_usage_description">显示模拟器内存用量</string>
<string name="show_system_ram_usage">显示系统内存使用情况</string>
@@ -453,8 +453,6 @@
<string name="fsr_sharpness">FSR 锐化度</string>
<string name="fsr_sharpness_description">指定使用 FSR 时图像的锐化程度</string>
<string name="renderer_anti_aliasing">抗锯齿方式</string>
<string name="renderer_optimize_spirv_output">优化 SPIRV 输出</string>
<string name="renderer_optimize_spirv_output_description">优化编译后的着色器以提高GPU效率。</string>
<string name="advanced">高级</string>
@@ -476,21 +474,27 @@
<string name="use_disk_shader_cache_description">将生成的着色器缓存于磁盘中并进行读取,以减少卡顿。</string>
<string name="renderer_force_max_clock">强制最大时钟 (仅限 Adreno)</string>
<string name="renderer_force_max_clock_description">强制 GPU 以最大时钟运行 (仍被温控限制)。</string>
<string name="renderer_asynchronous_gpu_emulation">GPU 异步模拟</string>
<string name="renderer_asynchronous_gpu_emulation_description">异步运行 GPU 模拟,以减少 CPU 停顿并提高吞吐量。仅当遇到与时序相关的问题时才应禁用此功能。</string>
<string name="renderer_async_presentation">异步呈现</string>
<string name="renderer_async_presentation_description">通过将呈现操作移至单独的 CPU 线程来略微提升性能。</string>
<string name="renderer_reactive_flushing">启用反应性刷新</string>
<string name="renderer_reactive_flushing_description">牺牲性能提高某些游戏的渲染精度。</string>
<string name="renderer_reactive_flushing_description">通过牺牲性能提高某些游戏的渲染精度。</string>
<string name="enable_buffer_history">启用缓冲区历史</string>
<string name="enable_buffer_history_description">允许访问之前的缓冲状态。\n这个选项可能会提升某些游戏渲染质量性能一致性。</string>
<string name="enable_buffer_history_description">启用对先前缓冲状态的访问。此选项可在某些游戏中提升渲染质量并保持性能一致性。</string>
<string name="use_optimized_vertex_buffers">优化顶点缓冲区</string>
<string name="use_optimized_vertex_buffers_description">实现优化顶点缓冲区绑定以提升性能。需要 Mesa 26.0+ Turnip 驱动。老驱动会崩溃。</string>
<string name="use_optimized_vertex_buffers_description">启用经过优化顶点缓冲区绑定以提升性能。需要 Mesa 26.0 及以上版本的 Turnip 或 QCOM 驱动程序。若使用较旧版本的 Turnip 驱动则会导致崩溃。</string>
<string name="hacks">Hacks</string>
<string name="fast_gpu_time">GPU 超频频率</string>
<string name="fast_gpu_time_description">强制大多数游戏以其最高原生分辨率运行。使用 256 获得最性能,使用 512 获得最大图形保真度。</string>
<string name="fast_gpu_time_description">强制大多数游戏以其最高原生分辨率运行。设置为 256 获得最性能,设置为 512 获得最佳画面保真度。</string>
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
<string name="skip_cpu_inner_invalidation_description">在内存更新期间跳过某些CPU端缓存无效化,减少CPU使用率并提高其性能。可能会导致某些游戏出现故障或崩溃。</string>
<string name="fix_bloom_effects">修复泛光效果</string>
<string name="fix_bloom_effects_description">减少《塞尔达传说:智慧的再现》(LA/EOW) 在 Adreno 700 系列 GPU 上的模糊,并移除《横冲直撞》(Burnout) 中的模糊特效。警告:可能会导致其他游戏出现画面花屏或异常。</string>
<string name="fix_bloom_effects">修复 Bloom 效果</string>
<string name="fix_bloom_effects_description">减少《塞尔达传说:智慧的再现》Adreno A6XX - A7XX/ Turnip)中的 bloom 模糊,并移除《Burnout》中的 bloom 效果。警告:可能会导致其他游戏出现图形异常。</string>
<string name="emulate_bgr565">模拟 BGR565</string>
<string name="emulate_bgr565_description">修复了游戏中的颜色反转以及出现的异常画面瑕疵或奇怪阴影问题</string>
<string name="renderer_asynchronous_shaders">使用异步着色器</string>
<string name="renderer_asynchronous_shaders_description">异步编译着色器。这可能会减少卡顿,但也可能会导致图形错误。</string>
<string name="gpu_unswizzle_settings">GPU 还原设置</string>
@@ -1145,5 +1149,6 @@
<string name="license_fidelityfx_fsr_description">AMD 的高品质画面增强技术</string>
<string name="external_content">外部内容</string>
<string name="add_folders">添加文件夹</string>
<string name="percent">%1$d%%</string>
</resources>
@@ -440,7 +440,6 @@
<string name="fsr_sharpness">FSR 銳化度</string>
<string name="fsr_sharpness_description">使用 FSR 時圖片的銳化程度</string>
<string name="renderer_anti_aliasing">抗鋸齒</string>
<string name="renderer_optimize_spirv_output_description">最佳化編譯後的著色器以提高GPU效率。</string>
<string name="dma_accuracy">DMA 準確度</string>
@@ -469,8 +469,6 @@
<string name="fsr_sharpness">FSR sharpness</string>
<string name="fsr_sharpness_description">Determines how sharpened the image will look while using FSR\'s dynamic contrast</string>
<string name="renderer_anti_aliasing">Anti-aliasing method</string>
<string name="renderer_optimize_spirv_output">Optimize SPIRV output</string>
<string name="renderer_optimize_spirv_output_description">Optimizes compiled shaders to improve GPU efficiency, but may introduce longer loading times and initial slowdowns.</string>
<string name="advanced">Advanced</string>
@@ -501,7 +499,7 @@
<string name="enable_buffer_history">Enable buffer history</string>
<string name="enable_buffer_history_description">Enables access to previous buffer states. This option may improve rendering quality and performance consistency in some games.</string>
<string name="use_optimized_vertex_buffers">Optimized Vertex Buffers</string>
<string name="use_optimized_vertex_buffers_description">Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers. Will crash on older drivers.</string>
<string name="use_optimized_vertex_buffers_description">Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers/ QCOM drivers. Will crash on older Turnip drivers.</string>
<string name="hacks">Hacks</string>
@@ -510,7 +508,9 @@
<string name="skip_cpu_inner_invalidation">Skip CPU Inner Invalidation</string>
<string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string>
<string name="fix_bloom_effects">Fix Bloom Effects</string>
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno 700), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno A6XX - A7XX/ Turnip), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
<string name="emulate_bgr565">Emulate BGR565</string>
<string name="emulate_bgr565_description">Fixes problems with inverted colors in games or strange artifacts or strange shadows.</string>
<string name="renderer_asynchronous_shaders">Use asynchronous shaders</string>
<string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches.</string>
<string name="gpu_unswizzle_settings">GPU Unswizzle Settings</string>
@@ -1783,5 +1783,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<string name="external_content">External Content</string>
<string name="add_folders">Add Folder</string>
<string name="percent">%1$d%%</string>
</resources>
+3 -2
View File
@@ -147,7 +147,8 @@ add_library(
zstd_compression.h
fs/ryujinx_compat.h fs/ryujinx_compat.cpp
fs/symlink.h fs/symlink.cpp
httplib.h)
httplib.h
net/net.h net/net.cpp)
if(WIN32)
target_sources(common PRIVATE windows/timer_resolution.cpp
@@ -245,7 +246,7 @@ else()
target_link_libraries(common PUBLIC Boost::headers)
endif()
target_link_libraries(common PUBLIC Boost::filesystem Boost::context httplib::httplib)
target_link_libraries(common PUBLIC Boost::filesystem Boost::context httplib::httplib nlohmann_json::nlohmann_json)
if (lz4_ADDED)
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
@@ -243,6 +243,9 @@ void AndroidKeyboard::SubmitInlineKeyboardInput(int key_code) {
static_cast<s32>(m_current_text.size()));
break;
case KEYCODE_DEL:
if (m_current_text.empty()) {
return;
}
m_current_text.pop_back();
submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString, m_current_text,
static_cast<int>(m_current_text.size()));
+139
View File
@@ -0,0 +1,139 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <deque>
#include <memory>
#include <type_traits>
#include "common/common_types.h"
namespace Common {
template <class Traits>
class LeastRecentlyUsedCache {
using ObjectType = typename Traits::ObjectType;
using TickType = typename Traits::TickType;
struct Item {
ObjectType obj;
TickType tick;
Item* next{};
Item* prev{};
};
public:
LeastRecentlyUsedCache() : first_item{}, last_item{} {}
~LeastRecentlyUsedCache() = default;
size_t Insert(ObjectType obj, TickType tick) {
const auto new_id = Build();
auto& item = item_pool[new_id];
item.obj = obj;
item.tick = tick;
Attach(item);
return new_id;
}
void Touch(size_t id, TickType tick) {
auto& item = item_pool[id];
if (item.tick >= tick) {
return;
}
item.tick = tick;
if (&item == last_item) {
return;
}
Detach(item);
Attach(item);
}
void Free(size_t id) {
auto& item = item_pool[id];
Detach(item);
item.prev = nullptr;
item.next = nullptr;
free_items.push_back(id);
}
template <typename Func>
void ForEachItemBelow(TickType tick, Func&& func) {
static constexpr bool RETURNS_BOOL =
std::is_same_v<std::invoke_result<Func, ObjectType>, bool>;
Item* iterator = first_item;
while (iterator) {
if (static_cast<s64>(tick) - static_cast<s64>(iterator->tick) < 0) {
return;
}
Item* next = iterator->next;
if constexpr (RETURNS_BOOL) {
if (func(iterator->obj)) {
return;
}
} else {
func(iterator->obj);
}
iterator = next;
}
}
private:
size_t Build() {
if (free_items.empty()) {
const size_t item_id = item_pool.size();
auto& item = item_pool.emplace_back();
item.next = nullptr;
item.prev = nullptr;
return item_id;
}
const size_t item_id = free_items.front();
free_items.pop_front();
auto& item = item_pool[item_id];
item.next = nullptr;
item.prev = nullptr;
return item_id;
}
void Attach(Item& item) {
if (!first_item) {
first_item = &item;
}
if (!last_item) {
last_item = &item;
} else {
item.prev = last_item;
last_item->next = &item;
item.next = nullptr;
last_item = &item;
}
}
void Detach(Item& item) {
if (item.prev) {
item.prev->next = item.next;
}
if (item.next) {
item.next->prev = item.prev;
}
if (&item == first_item) {
first_item = item.next;
if (first_item) {
first_item->prev = nullptr;
}
}
if (&item == last_item) {
last_item = item.prev;
if (last_item) {
last_item->next = nullptr;
}
}
}
std::deque<Item> item_pool;
std::deque<size_t> free_items;
Item* first_item{};
Item* last_item{};
};
} // namespace Common
+16 -27
View File
@@ -13,13 +13,13 @@
namespace Common {
template <typename BaseAddr>
MultiLevelPageTable<BaseAddr>::MultiLevelPageTable(std::size_t address_space_bits_,
std::size_t first_level_bits_,
std::size_t page_bits_)
: address_space_bits{address_space_bits_},
first_level_bits{first_level_bits_}, page_bits{page_bits_} {
MultiLevelPageTable<BaseAddr>::MultiLevelPageTable(std::size_t address_space_bits_, std::size_t first_level_bits_, std::size_t page_bits_)
: address_space_bits{address_space_bits_}
, first_level_bits{first_level_bits_}
, page_bits{page_bits_}
{
if (page_bits == 0) {
return;
return;
}
first_level_shift = address_space_bits - first_level_bits;
first_level_chunk_size = (1ULL << (first_level_shift - page_bits)) * sizeof(BaseAddr);
@@ -30,12 +30,9 @@ MultiLevelPageTable<BaseAddr>::MultiLevelPageTable(std::size_t address_space_bit
void* base{VirtualAlloc(nullptr, alloc_size, MEM_RESERVE, PAGE_READWRITE)};
#else
void* base{mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)};
if (base == MAP_FAILED) {
if (base == MAP_FAILED)
base = nullptr;
}
#endif
ASSERT(base);
base_ptr = reinterpret_cast<BaseAddr*>(base);
}
@@ -56,29 +53,21 @@ template <typename BaseAddr>
void MultiLevelPageTable<BaseAddr>::ReserveRange(u64 start, std::size_t size) {
const u64 new_start = start >> first_level_shift;
const u64 new_end = (start + size) >> first_level_shift;
for (u64 i = new_start; i <= new_end; i++) {
if (!first_level_map[i]) {
for (u64 i = new_start; i <= new_end; i++)
if (!first_level_map[i])
AllocateLevel(i);
}
}
}
template <typename BaseAddr>
void MultiLevelPageTable<BaseAddr>::AllocateLevel(u64 level) {
void* ptr = reinterpret_cast<char *>(base_ptr) + level * first_level_chunk_size;
void MultiLevelPageTable<BaseAddr>::AllocateLevel(u64 index) {
void* ptr = reinterpret_cast<char *>(base_ptr) + index * first_level_chunk_size;
#ifdef _WIN32
void* base{VirtualAlloc(ptr, first_level_chunk_size, MEM_COMMIT, PAGE_READWRITE)};
#else
void* base{mmap(ptr, first_level_chunk_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)};
if (base == MAP_FAILED) {
base = nullptr;
}
#endif
void* base = VirtualAlloc(ptr, first_level_chunk_size, MEM_COMMIT, PAGE_READWRITE);
ASSERT(base);
first_level_map[level] = base;
#else
void* base = ptr;
#endif
first_level_map[index] = base;
}
} // namespace Common
+287
View File
@@ -0,0 +1,287 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <optional>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <fmt/format.h>
#include "common/scm_rev.h"
#include "net.h"
#include "common/logging.h"
#include "common/httplib.h"
#ifdef YUZU_BUNDLED_OPENSSL
#include <openssl/cert.h>
#endif
#define QT_TR_NOOP(x) x
namespace Common::Net {
std::vector<Asset> Release::GetPlatformAssets() const {
// TODO(crueter): Need better handling for this as a whole.
#ifdef NIGHTLY_BUILD
std::vector<std::string> result;
boost::algorithm::split(result, tag, boost::is_any_of("."));
if (result.size() != 2)
return {};
const auto ref = result.at(1);
#else
const auto ref = tag;
#endif
std::vector<Asset> found_assets;
// FIXME: This is mildly inefficient.
// Finds assets based on a hierarchy of regex search strings.
const auto find_asset = [&found_assets, ref, this](const std::string& name,
const std::vector<std::string>& suffixes) {
for (const std::string& asset : assets) {
for (const auto& suffix : suffixes) {
if (asset.ends_with(suffix)) {
const std::string_view asset_sv = asset;
const size_t pos = asset_sv.find_last_of('/');
const std::string_view filename =
(pos != std::string_view::npos) ? asset_sv.substr(pos + 1) : asset_sv;
found_assets.emplace_back(Asset{
.name = name,
.url = host,
.path = asset,
.filename = std::string{filename},
});
return;
}
}
}
};
#ifdef _WIN32
#ifdef ARCHITECTURE_x86_64
find_asset("Standard", {"amd64-msvc-standard.exe", "amd64-msvc-standard.zip", "mingw-amd64-gcc-standard.exe", "mingw-amd64-gcc-standard.zip"});
find_asset("PGO", {"mingw-amd64-clang-pgo.exe", "mingw-amd64-clang-pgo.zip"});
#elif defined(ARCHITECTURE_arm64)
find_asset("Standard", {"mingw-arm64-clang-standard.exe", "mingw-arm64-clang-standard.zip"});
find_asset("PGO", {"mingw-arm64-clang-pgo.exe", "mingw-arm64-clang-pgo.zip"});
#endif
#elif defined(__APPLE__)
#ifdef ARCHITECTURE_arm64
find_asset("Standard", {".dmg", ".tar.gz"});
#endif
#elif defined(__ANDROID__)
#ifdef ARCHITECTURE_x86_64
find_asset("Standard", {"chromeos.apk"});
#elif defined(ARCHITECTURE_arm64)
#ifdef YUZU_LEGACY
find_asset("Standard", {"legacy.apk"});
#elif defined(GENSHIN_SPOOF)
find_asset("Standard", {"optimized.apk"});
#else
find_asset("Standard", {"standard.apk"});
#endif
#endif
#endif
return found_assets;
}
static inline u64 ParseIsoTimestamp(const std::string& iso) {
if (iso.empty())
return 0;
std::string buf = iso;
if (buf.back() == 'Z')
buf.pop_back();
std::tm tm{};
std::istringstream ss(buf);
ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S");
if (ss.fail())
return 0;
#ifdef _WIN32
return static_cast<u64>(_mkgmtime(&tm));
#else
return static_cast<u64>(timegm(&tm));
#endif
}
std::optional<Release> Release::FromJson(const nlohmann::json& json, const std::string& host,
const std::string& repo) {
Release rel;
if (!json.is_object())
return std::nullopt;
rel.tag = json.value("tag_name", std::string{});
if (rel.tag.empty())
return std::nullopt;
rel.title = json.value("name", rel.tag);
rel.id = json.value("id", std::hash<std::string>{}(rel.title));
rel.published = ParseIsoTimestamp(json.value("published_at", std::string{}));
rel.prerelease = json.value("prerelease", false);
auto body = json.value("body", rel.title);
boost::replace_all(body, "\\r", "");
boost::replace_all(body, "\\n", "\n");
rel.body = body;
rel.host = host;
const auto release_base =
fmt::format("{}/{}/releases", Common::g_build_auto_update_website, repo);
const auto fallback_html = fmt::format("{}/tag/{}", release_base, rel.tag);
rel.html_url = json.value("html_url", fallback_html);
// This is our own "fake" API.
if (json.contains("base")) {
const auto base = json.value("base", fmt::format("https://{}", Common::g_build_auto_update_api));
rel.base_download_url = fmt::format("{}/{}", base, rel.tag);
// Assets are easy :)
rel.assets = json.value("assets", std::vector<std::string>{});
} else {
const auto base_download_url = fmt::format("/{}/releases/download/{}", repo, rel.tag);
rel.base_download_url = base_download_url;
// assets are a bit more complex here. :(
std::vector<std::string> assets;
const nlohmann::json& arr = json["assets"];
for (const auto &obj : arr) {
const auto url = obj.value("browser_download_url", std::string{});
assets.emplace_back(url);
}
rel.assets = assets;
}
return rel;
}
std::optional<Release> Release::FromJson(const std::string_view& json, const std::string& host,
const std::string& repo) {
try {
return FromJson(nlohmann::json::parse(json), host, repo);
} catch (std::exception& e) {
LOG_WARNING(Common, "Failed to parse JSON: {}", e.what());
}
return {};
}
std::vector<Release> Release::ListFromJson(const nlohmann::json& json, const std::string& host,
const std::string& repo) {
if (!json.is_array())
return {};
std::vector<Release> releases;
for (const auto& obj : json) {
auto rel = Release::FromJson(obj, host, repo);
if (rel)
releases.emplace_back(rel.value());
}
return releases;
}
std::vector<Release> Release::ListFromJson(const std::string_view& json, const std::string& host,
const std::string& repo) {
try {
return ListFromJson(nlohmann::json::parse(json), host, repo);
} catch (std::exception& e) {
LOG_WARNING(Common, "Failed to parse JSON: {}", e.what());
}
return {};
}
std::optional<std::string> MakeRequest(const std::string& url, const std::string& path) {
try {
constexpr std::size_t timeout_seconds = 15;
std::unique_ptr<httplib::Client> client = std::make_unique<httplib::Client>(url);
client->set_connection_timeout(timeout_seconds);
client->set_read_timeout(timeout_seconds);
client->set_write_timeout(timeout_seconds);
#ifdef YUZU_BUNDLED_OPENSSL
client->load_ca_cert_store(kCert, sizeof(kCert));
#endif
if (client == nullptr) {
LOG_ERROR(Common, "Invalid URL {}{}", url, path);
return {};
}
httplib::Request request{
.method = "GET",
.path = path,
};
client->set_follow_location(true);
httplib::Result result = client->send(request);
if (!result) {
LOG_ERROR(Common, "GET to {}{} returned null", url, path);
return {};
}
const auto& response = result.value();
if (response.status >= 400) {
LOG_ERROR(Common, "GET to {}{} returned error status code: {}", url, path,
response.status);
return {};
}
if (!response.headers.contains("content-type")) {
LOG_ERROR(Common, "GET to {}{} returned no content", url, path);
return {};
}
return response.body;
} catch (std::exception& e) {
LOG_ERROR(Common, "GET to {}{} failed during update check: {}", url, path, e.what());
return std::nullopt;
}
}
std::vector<Release> GetReleases() {
const auto body = GetReleasesBody();
if (!body) {
LOG_WARNING(Common, "Failed to get stable releases");
return {};
}
const std::string_view body_str = body.value();
const auto url = fmt::format("https://{}", Common::g_build_auto_update_stable_api);
return Release::ListFromJson(body_str, url, Common::g_build_auto_update_stable_repo);
}
std::optional<Release> GetLatestRelease() {
const auto releases_path = Common::g_build_auto_update_api_path;
const auto url = fmt::format("https://{}", Common::g_build_auto_update_api);
const auto body = MakeRequest(url, releases_path);
if (!body) {
LOG_WARNING(Common, "Failed to get latest release");
return std::nullopt;
}
const std::string_view body_str = body.value();
return Release::FromJson(body_str, url, Common::g_build_auto_update_repo);
}
std::optional<std::string> GetReleasesBody() {
const auto releases_path =
fmt::format("/{}/{}/releases", Common::g_build_auto_update_stable_api_path,
Common::g_build_auto_update_stable_repo);
const auto url = fmt::format("https://{}", Common::g_build_auto_update_stable_api);
return MakeRequest(url, releases_path);
}
} // namespace Common::Net
+56
View File
@@ -0,0 +1,56 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <optional>
#include <string>
#include <vector>
#include <nlohmann/json.hpp>
#include "common/common_types.h"
namespace Common::Net {
typedef struct {
std::string name;
std::string url;
std::string path;
std::string filename;
} Asset;
typedef struct Release {
std::string title;
std::string body;
std::string tag;
std::string base_download_url;
std::string html_url;
std::string host;
std::vector<std::string> assets;
u64 id;
u64 published;
bool prerelease;
// Get the relevant list of assets for the current platform.
std::vector<Asset> GetPlatformAssets() const;
static std::optional<Release> FromJson(const nlohmann::json& json, const std::string &host, const std::string& repo);
static std::optional<Release> FromJson(const std::string_view& json, const std::string &host, const std::string& repo);
static std::vector<Release> ListFromJson(const nlohmann::json &json, const std::string &host, const std::string &repo);
static std::vector<Release> ListFromJson(const std::string_view &json, const std::string &host, const std::string &repo);
} Release;
// Make a request via httplib, and return the response body if applicable.
std::optional<std::string> MakeRequest(const std::string &url, const std::string &path);
// Get all of the latest stable releases.
std::vector<Release> GetReleases();
// Get all of the latest stable releases as text.
std::optional<std::string> GetReleasesBody();
// Get the latest release of the current channel.
std::optional<Release> GetLatestRelease();
}
+2 -4
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
@@ -142,10 +142,8 @@ struct PageTable {
VirtualBuffer<PageEntryData> entries;
static_assert(sizeof(PageEntryData) == 32);
std::size_t current_address_space_width_in_bits{};
u8* fastmem_arena{};
std::size_t current_address_space_width_in_bits{};
std::size_t page_size{};
};
+6
View File
@@ -22,6 +22,9 @@
#define BUILD_AUTO_UPDATE_API "@BUILD_AUTO_UPDATE_API@"
#define BUILD_AUTO_UPDATE_API_PATH "@BUILD_AUTO_UPDATE_API_PATH@"
#define BUILD_AUTO_UPDATE_REPO "@BUILD_AUTO_UPDATE_REPO@"
#define BUILD_AUTO_UPDATE_STABLE_API "@BUILD_AUTO_UPDATE_STABLE_API@"
#define BUILD_AUTO_UPDATE_STABLE_API_PATH "@BUILD_AUTO_UPDATE_STABLE_API_PATH@"
#define BUILD_AUTO_UPDATE_STABLE_REPO "@BUILD_AUTO_UPDATE_STABLE_REPO@"
#define IS_NIGHTLY_BUILD @IS_NIGHTLY_BUILD@
namespace Common {
@@ -45,5 +48,8 @@ constexpr const char g_build_auto_update_website[] = BUILD_AUTO_UPDATE_WEBSITE;
constexpr const char g_build_auto_update_api[] = BUILD_AUTO_UPDATE_API;
constexpr const char g_build_auto_update_api_path[] = BUILD_AUTO_UPDATE_API_PATH;
constexpr const char g_build_auto_update_repo[] = BUILD_AUTO_UPDATE_REPO;
constexpr const char g_build_auto_update_stable_api[] = BUILD_AUTO_UPDATE_STABLE_API;
constexpr const char g_build_auto_update_stable_api_path[] = BUILD_AUTO_UPDATE_STABLE_API_PATH;
constexpr const char g_build_auto_update_stable_repo[] = BUILD_AUTO_UPDATE_STABLE_REPO;
} // namespace Common
+3
View File
@@ -28,5 +28,8 @@ extern const char g_build_auto_update_website[];
extern const char g_build_auto_update_api[];
extern const char g_build_auto_update_api_path[];
extern const char g_build_auto_update_repo[];
extern const char g_build_auto_update_stable_api[];
extern const char g_build_auto_update_stable_api_path[];
extern const char g_build_auto_update_stable_repo[];
} // namespace Common
+7 -8
View File
@@ -388,10 +388,6 @@ struct Values {
true,
true};
SwitchableSetting<SpirvOptimizeMode, true> optimize_spirv_output{linkage,
SpirvOptimizeMode::Never,
"optimize_spirv_output",
Category::Renderer};
SwitchableSetting<bool> use_asynchronous_gpu_emulation{
linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer};
// *nix platforms may have issues with the borderless windowed fullscreen mode.
@@ -555,6 +551,9 @@ struct Values {
SwitchableSetting<bool> fix_bloom_effects{linkage, false, "fix_bloom_effects",
Category::RendererHacks};
SwitchableSetting<bool> emulate_bgr565{linkage, false, "emulate_bgr565",
Category::RendererHacks};
SwitchableSetting<bool> rescale_hack{linkage, false, "rescale_hack",
Category::RendererHacks};
@@ -584,7 +583,7 @@ struct Values {
SwitchableSetting<ExtendedDynamicState> dyna_state{linkage,
#if defined(ANDROID)
ExtendedDynamicState::EDS1,
ExtendedDynamicState::Disabled,
#elif defined(__APPLE__)
ExtendedDynamicState::Disabled,
#else
@@ -636,8 +635,8 @@ struct Values {
Category::System};
SwitchableSetting<Region, true> region_index{linkage, Region::Usa, "region_index", Category::System};
SwitchableSetting<TimeZone, true> time_zone_index{linkage, TimeZone::Auto, "time_zone_index", Category::System};
Setting<u32> serial_battery{linkage, 0, "serial_battery", Category::System};
Setting<u32> serial_unit{linkage, 0, "serial_unit", Category::System};
Setting<u32> serial_battery{linkage, 0, "serial_battery", Category::Debugging};
Setting<u32> serial_unit{linkage, 0, "serial_unit", Category::Debugging};
// Measured in seconds since epoch
SwitchableSetting<bool> custom_rtc_enabled{linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true};
SwitchableSetting<s64> custom_rtc{
@@ -807,7 +806,7 @@ struct Values {
0,
65535,
"debug_knobs",
Category::Core,
Category::Debugging,
Specialization::Countable,
true,
true};
+18 -17
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 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
@@ -21,7 +24,9 @@ public:
// "with the current allocator");
constexpr VirtualBuffer() = default;
explicit VirtualBuffer(std::size_t count) : alloc_size{count * sizeof(T)} {
explicit VirtualBuffer(std::size_t count) noexcept
: alloc_size{count * sizeof(T)}
{
base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
}
@@ -33,8 +38,8 @@ public:
VirtualBuffer& operator=(const VirtualBuffer&) = delete;
VirtualBuffer(VirtualBuffer&& other) noexcept
: alloc_size{std::exchange(other.alloc_size, 0)}, base_ptr{std::exchange(other.base_ptr),
nullptr} {}
: alloc_size{std::exchange(other.alloc_size, 0)}, base_ptr{std::exchange(other.base_ptr), nullptr}
{}
VirtualBuffer& operator=(VirtualBuffer&& other) noexcept {
alloc_size = std::exchange(other.alloc_size, 0);
@@ -42,35 +47,31 @@ public:
return *this;
}
void resize(std::size_t count) {
const auto new_size = count * sizeof(T);
if (new_size == alloc_size) {
return;
void resize(std::size_t count) noexcept {
if (auto const new_size = count * sizeof(T); new_size != alloc_size) {
FreeMemoryPages(base_ptr, alloc_size);
alloc_size = new_size;
base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
}
FreeMemoryPages(base_ptr, alloc_size);
alloc_size = new_size;
base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
}
[[nodiscard]] constexpr const T& operator[](std::size_t index) const {
[[nodiscard]] constexpr const T& operator[](std::size_t index) const noexcept {
return base_ptr[index];
}
[[nodiscard]] constexpr T& operator[](std::size_t index) {
[[nodiscard]] constexpr T& operator[](std::size_t index) noexcept {
return base_ptr[index];
}
[[nodiscard]] constexpr T* data() {
[[nodiscard]] constexpr T* data() noexcept {
return base_ptr;
}
[[nodiscard]] constexpr const T* data() const {
[[nodiscard]] constexpr const T* data() const noexcept {
return base_ptr;
}
[[nodiscard]] constexpr std::size_t size() const {
[[nodiscard]] constexpr std::size_t size() const noexcept {
return alloc_size / sizeof(T);
}
@@ -289,7 +289,6 @@ void ArmDynarmic32::MakeJit(Common::PageTable* page_table) {
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
break;
// Paranoia mode for debugging optimizations
case Settings::CpuAccuracy::Paranoid:
@@ -340,7 +340,6 @@ void ArmDynarmic64::MakeJit(Common::PageTable* page_table, std::size_t address_s
config.unsafe_optimizations = true;
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
config.fastmem_address_space_bits = 64;
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
break;
// Paranoia mode for debugging optimizations
case Settings::CpuAccuracy::Paranoid:
-1
View File
@@ -415,7 +415,6 @@ struct System::Impl {
cpu_manager.Shutdown();
debugger.reset();
kernel.Shutdown();
device_memory.reset();
stop_event = {};
Network::RestartSocketOperations();
+2 -2
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
@@ -283,7 +283,7 @@ std::string_view GDBStubA32::GetTargetXML() const {
<reg name="r11" bitsize="32" type="uint32"/>
<reg name="r12" bitsize="32" type="uint32"/>
<reg name="sp" bitsize="32" type="data_ptr"/>
<reg name="lr" bitsize="32" type="code_ptr"/>
<reg name="lr" bitsize="32"/>
<reg name="pc" bitsize="32" type="code_ptr"/>
<!-- The CPSR is register 25, rather than register 16, because
the FPA registers historically were placed between the PC
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@@ -109,7 +109,7 @@ Result AesCtrCounterExtendedStorage::GetEntryList(Entry* out_entries, s32* out_e
R_UNLESS(out_entries != nullptr || entry_count == 0, ResultNullptrArgument);
// Check that our range is valid.
BucketTree::Offsets table_offsets;
BucketTree::Offsets table_offsets{};
R_TRY(m_table.GetOffsets(std::addressof(table_offsets)));
R_UNLESS(table_offsets.IsInclude(offset, size), ResultOutOfRange);
@@ -167,7 +167,7 @@ size_t AesCtrCounterExtendedStorage::Read(u8* buffer, size_t size, size_t offset
ASSERT(Common::IsAligned(offset, BlockSize));
ASSERT(Common::IsAligned(size, BlockSize));
BucketTree::Offsets table_offsets;
BucketTree::Offsets table_offsets{};
ASSERT(R_SUCCEEDED(m_table.GetOffsets(std::addressof(table_offsets))));
ASSERT(table_offsets.IsInclude(offset, size));
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -89,7 +92,7 @@ public:
virtual size_t Read(u8* buffer, size_t size, size_t offset) const override;
virtual size_t GetSize() const override {
BucketTree::Offsets offsets;
BucketTree::Offsets offsets{};
ASSERT(R_SUCCEEDED(m_table.GetOffsets(std::addressof(offsets))));
return offsets.end_offset;
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@@ -270,7 +270,7 @@ Result BucketTree::Find(Visitor* visitor, s64 virtual_address) {
R_UNLESS(virtual_address >= 0, ResultInvalidOffset);
R_UNLESS(!this->IsEmpty(), ResultOutOfRange);
BucketTree::Offsets offsets;
BucketTree::Offsets offsets{};
R_TRY(this->GetOffsets(std::addressof(offsets)));
R_TRY(visitor->Initialize(this, offsets));
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@@ -125,7 +125,7 @@ private:
}
// Get the table offsets.
BucketTree::Offsets table_offsets;
BucketTree::Offsets table_offsets{};
R_TRY(m_table.GetOffsets(std::addressof(table_offsets)));
// Validate arguments.
@@ -177,7 +177,7 @@ private:
ASSERT(out != nullptr);
// Get our table offsets.
BucketTree::Offsets offsets;
BucketTree::Offsets offsets{};
R_TRY(m_table.GetOffsets(std::addressof(offsets)));
// Set the output.
@@ -195,7 +195,7 @@ private:
R_SUCCEED_IF(size == 0);
// Get the table offsets.
BucketTree::Offsets table_offsets;
BucketTree::Offsets table_offsets{};
R_TRY(m_table.GetOffsets(std::addressof(table_offsets)));
// Validate arguments.
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -52,7 +55,7 @@ Result IndirectStorage::GetEntryList(Entry* out_entries, s32* out_entry_count, s
R_UNLESS(out_entries != nullptr || entry_count == 0, ResultNullptrArgument);
// Check that our range is valid.
BucketTree::Offsets table_offsets;
BucketTree::Offsets table_offsets{};
R_TRY(m_table.GetOffsets(std::addressof(table_offsets)));
R_UNLESS(table_offsets.IsInclude(offset, size), ResultOutOfRange);
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -164,7 +167,7 @@ Result IndirectStorage::OperatePerEntry(s64 offset, s64 size, F func) {
R_SUCCEED_IF(size == 0);
// Get the table offsets.
BucketTree::Offsets table_offsets;
BucketTree::Offsets table_offsets{};
R_TRY(m_table.GetOffsets(std::addressof(table_offsets)));
// Validate arguments.
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -18,7 +21,7 @@ size_t SparseStorage::Read(u8* buffer, size_t size, size_t offset) const {
SparseStorage* self = const_cast<SparseStorage*>(this);
if (self->GetEntryTable().IsEmpty()) {
BucketTree::Offsets table_offsets;
BucketTree::Offsets table_offsets{};
ASSERT(R_SUCCEEDED(self->GetEntryTable().GetOffsets(std::addressof(table_offsets))));
ASSERT(table_offsets.IsInclude(offset, size));
+17 -32
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@@ -191,8 +191,7 @@ Result KPageTableBase::InitializeForKernel(bool is_64_bit, KVirtualAddress start
m_cached_physical_heap_region = nullptr;
// Initialize our implementation.
m_impl = std::make_unique<Common::PageTable>();
m_impl->Resize(m_address_space_width, PageBits);
m_impl.Resize(m_address_space_width, PageBits);
// Set the tracking memory.
m_memory = std::addressof(memory);
@@ -202,13 +201,7 @@ Result KPageTableBase::InitializeForKernel(bool is_64_bit, KVirtualAddress start
m_memory_block_slab_manager));
}
Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool enable_aslr,
bool enable_das_merge, bool from_back,
KMemoryManager::Pool pool, KProcessAddress code_address,
size_t code_size, KSystemResource* system_resource,
KResourceLimit* resource_limit,
Core::Memory::Memory& memory,
KProcessAddress aslr_space_start) {
Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource* system_resource, KResourceLimit* resource_limit, Core::Memory::Memory& memory, KProcessAddress aslr_space_start) {
// Calculate region extents.
const size_t as_width = GetAddressSpaceWidth(as_type);
const KProcessAddress start = 0;
@@ -275,6 +268,7 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool
// Set other basic fields.
m_enable_aslr = enable_aslr;
m_enable_device_address_space_merge = enable_das_merge;
m_allowed_exec_device_mapping = false;
m_address_space_start = start;
m_address_space_end = end;
m_is_kernel = false;
@@ -319,14 +313,10 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool
// Determine random placements for each region.
size_t alias_rnd = 0, heap_rnd = 0, stack_rnd = 0, kmap_rnd = 0;
if (enable_aslr) {
alias_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
RegionAlignment;
heap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
RegionAlignment;
stack_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
RegionAlignment;
kmap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
RegionAlignment;
alias_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment;
heap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment;
stack_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment;
kmap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment;
}
// Setup heap and alias regions.
@@ -445,15 +435,13 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool
ASSERT(heap_last < kmap_start || kmap_last < heap_start);
// Initialize our implementation.
m_impl = std::make_unique<Common::PageTable>();
m_impl->Resize(m_address_space_width, PageBits);
m_impl.Resize(m_address_space_width, PageBits);
// Set the tracking memory.
m_memory = std::addressof(memory);
// Initialize our memory block manager.
R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end,
m_memory_block_slab_manager));
R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end, m_memory_block_slab_manager));
}
Result KPageTableBase::FinalizeProcess() {
@@ -476,7 +464,7 @@ void KPageTableBase::Finalize() {
this->FinalizeProcess();
auto BlockCallback = [&](KProcessAddress addr, u64 size) {
if (m_impl->fastmem_arena) {
if (m_impl.fastmem_arena) {
m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size, false);
}
@@ -514,9 +502,6 @@ void KPageTableBase::Finalize() {
m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax,
m_mapped_ipc_server_memory);
}
// Close the backing page table, as the destructor is not called for guest objects.
m_impl.reset();
}
KProcessAddress KPageTableBase::GetRegionAddress(Svc::MemoryState state) const {
@@ -2349,7 +2334,7 @@ Result KPageTableBase::QueryPhysicalAddress(Svc::lp64::PhysicalMemoryInfo* out,
TraversalContext context;
TraversalEntry next_entry;
bool traverse_valid =
m_impl->BeginTraversal(std::addressof(next_entry), std::addressof(context), virt_addr);
m_impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), virt_addr);
R_UNLESS(traverse_valid, ResultInvalidCurrentMemory);
// Set tracking variables.
@@ -2360,7 +2345,7 @@ Result KPageTableBase::QueryPhysicalAddress(Svc::lp64::PhysicalMemoryInfo* out,
while (true) {
// Continue the traversal.
traverse_valid =
m_impl->ContinueTraversal(std::addressof(next_entry), std::addressof(context));
m_impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
if (!traverse_valid) {
break;
}
@@ -5730,14 +5715,14 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
this->MakePageGroup(pages_to_close, virt_addr, num_pages);
// Unmap.
m_memory->UnmapRegion(*m_impl, virt_addr, num_pages * PageSize, separate_heap);
m_memory->UnmapRegion(m_impl, virt_addr, num_pages * PageSize, separate_heap);
R_SUCCEED();
}
case OperationType::Map: {
ASSERT(virt_addr != 0);
ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize));
m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr,
m_memory->MapMemoryRegion(m_impl, virt_addr, num_pages * PageSize, phys_addr,
ConvertToMemoryPermission(properties.perm), false);
// Open references to pages, if we should.
@@ -5754,7 +5739,7 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
case OperationType::ChangePermissions:
case OperationType::ChangePermissionsAndRefresh:
case OperationType::ChangePermissionsAndRefreshAndFlush: {
m_memory->ProtectRegion(*m_impl, virt_addr, num_pages * PageSize,
m_memory->ProtectRegion(m_impl, virt_addr, num_pages * PageSize,
ConvertToMemoryPermission(properties.perm));
R_SUCCEED();
}
@@ -5788,7 +5773,7 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
const size_t size{node.GetNumPages() * PageSize};
// Map the pages.
m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress(),
m_memory->MapMemoryRegion(m_impl, virt_addr, size, node.GetAddress(),
ConvertToMemoryPermission(properties.perm), separate_heap);
virt_addr += size;
+12 -22
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@@ -215,7 +215,7 @@ private:
mutable KLightLock m_general_lock;
mutable KLightLock m_map_physical_memory_lock;
KLightLock m_device_map_lock;
std::unique_ptr<Common::PageTable> m_impl{};
Common::PageTable m_impl{};
Core::Memory::Memory* m_memory{};
KMemoryBlockManager m_memory_block_manager{};
u32 m_allocate_option{};
@@ -223,6 +223,7 @@ private:
bool m_is_kernel{};
bool m_enable_aslr{};
bool m_enable_device_address_space_merge{};
bool m_allowed_exec_device_mapping{};
KMemoryBlockSlabManager* m_memory_block_slab_manager{};
KBlockInfoManager* m_block_info_manager{};
KResourceLimit* m_resource_limit{};
@@ -255,6 +256,10 @@ public:
return m_enable_aslr;
}
void AllowDeviceMappingOfExecPages() {
m_allowed_exec_device_mapping = true;
}
bool Contains(KProcessAddress addr) const {
return m_address_space_start <= addr && addr <= m_address_space_end - 1;
}
@@ -300,26 +305,11 @@ public:
}
public:
Core::Memory::Memory& GetMemory() {
return *m_memory;
}
Core::Memory::Memory& GetMemory() const {
return *m_memory;
}
Common::PageTable& GetImpl() {
return *m_impl;
}
Common::PageTable& GetImpl() const {
return *m_impl;
}
size_t GetNumGuardPages() const {
return this->IsKernel() ? 1 : 4;
}
[[nodiscard]] Core::Memory::Memory& GetMemory() noexcept { return *m_memory; }
[[nodiscard]] Core::Memory::Memory const& GetMemory() const noexcept { return *m_memory; }
[[nodiscard]] Common::PageTable& GetImpl() noexcept { return m_impl; }
[[nodiscard]] Common::PageTable const& GetImpl() const noexcept { return m_impl; }
[[nodiscard]] size_t GetNumGuardPages() const noexcept { return this->IsKernel() ? 1 : 4; }
protected:
// NOTE: These three functions (Operate, Operate, FinalizeUpdate) are virtual functions
// in Nintendo's kernel. We devirtualize them, since KPageTable is the only derived

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