Compare commits

..

52 commits

Author SHA1 Message Date
d56e5dd74f [network] use jthread and use std::vector for packet list instead of std::list
All checks were successful
eden-license / license-header (pull_request) Successful in 27s
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-08-30 00:50:32 +02:00
57fbdd516e
[host_memory] Fix a bunch of memory errors on Windows (#303)
This fixes a bunch of memory errors that could happen on Windows. Possibly regression introduced on PR 187.

Reviewed-on: #303
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-29 14:20:22 +02:00
f07309afd2
[ffmpeg] proper drm inclusion (#328)
* this fixes build on ubuntu 25.04

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

Reviewed-on: #328
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-committed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-08-29 01:49:20 +02:00
cf689a7a49
[cmake] properly invalidate tzdb cache; require matching version (#346)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #346
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2025-08-29 01:35:01 +02:00
702a2beb7c
[cmake] refactor: cpmfile, deps prefetch, force system and more (#322)
CPM Dependencies are now managed in a singular json file, where each can be properly prefetched at-will via `tools/cpm-fetch.sh <packages...>`, or all at once via `tools/cpm-fetch-all.sh`.

Adds docs for CPMUtil as well.

Also adds `<package>_FORCE_{BUNDLED,SYSTEM}` overrides

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #322
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2025-08-29 00:18:02 +02:00
d709771d67
[core] Unsafe toggles cannot be changed at runtime (#344)
Some checks failed
eden-license / license-header (pull_request) Failing after 27s
Reviewed-on: #344
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-29 00:07:21 +02:00
428249cb01
[debug] Rename remaining names in accordance with PR 341 (#343)
This renames the remaining names in accordance with PR 341.

Reviewed-on: #343
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-28 16:46:24 +02:00
8ed05425dd
[Vulkan][TextureCache] Always use identity-swizzled views for storage images (#321)
Validation flagged writes to a VK_DESCRIPTOR_TYPE_STORAGE_IMAGE descriptor because the bound VkImageView had a non-identity component mapping  and hence the vuid-00336 error, this fixes the said error.

------

This commit helps to fix some graphical issues on games like Trident's Tale, where game didn't render anything than just plain terrain, helps to stabilize Nier Automata graphical issues, meanwhile the most annoying glitches are gone, there's still remain other issues.

Reviewed-on: #321
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: wildcard <nubieluv@gmail.com>
Co-committed-by: wildcard <nubieluv@gmail.com>
2025-08-28 05:21:05 +02:00
26b5286250
[veil] fix flush log option not being available (#341)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #341
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-28 05:14:24 +02:00
529f78b95f
[audio] fix ringbuffer datarace (#205)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #205
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-28 01:55:27 +02:00
434bd42a5e
[desktop] fix controls dialog text clipping (#336)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #336
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2025-08-28 01:34:41 +02:00
8407510f76
[video_core] fix nixOS flake build patch (#339)
See https://github.com/NixOS/nixpkgs/pull/406630/files

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

Reviewed-on: #339
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-28 01:32:37 +02:00
7f482d0730
[core] Add option to control Host MMU Emulation (#324)
This adds an option to enable or disable Host MMU Emulation [Android/PC], brings better config per-game handling with Disable Buffer Reorder, disables Flush Debug Lines by Log, option which was enabled by default on Android/PC taxing performance and translates to all supported languages the recent changes.

Leaves room for NCE improvements in the foreseable future.

Co-authored-by: crueter <crueter@eden-emu.dev>
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Reviewed-on: #324
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-27 23:02:46 +02:00
9d53933a95
[fmt] use {:#X} for format instead of 0x{:X} (#309)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #309
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-27 22:39:11 +02:00
7950c5cca0
[common/host_memory] use assert instead of throw on Impl() ctor; abort on error (#316)
Rationale: Throwing when running out of memory just creates sad paths for no reason (and at that point, just abort immediately). We are using MAP_NORESERVE, if there isn't enough memory a crash will follow anyways.

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

Reviewed-on: #316
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-27 22:26:08 +02:00
09e77fa146
[common, fs] Use std::string_view instead of std::string&; inline functions that are used rarely (#330)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #330
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-27 22:21:04 +02:00
dae0d7bec6
[VK] Very conservative and spec-compliant alignment (#335)
spec-compliant alignment: Implement spec-compliant alignment for non-coherent memory and buffer-image granularity
revert oom handling

Reviewed-on: #335
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: wildcard <wildcard@eden-emu.dev>
Co-committed-by: wildcard <wildcard@eden-emu.dev>
2025-08-27 22:20:02 +02:00
37375220e8
[VK] Refine VRAM allocation strategy for improved stability and performance (#334)
These adjustments enhance memory management,
While increasing shader performance across all GPU types, including iGPUs.
This commit fixes a bug in Super Mario Odyssey where loading into a new area or pausing the game
Would cause the whole game to slow down (Most noticeable on RDNA 2 GPUs like the Steam Deck)

Thank you to all of our testers for helping eliminate this bug,
And thank you to Camille for the instructions/commit and to Zephyron for addressing this in Citron.

Co-authored-by: JPikachu <jpikachu.eden@gmail.com>
Reviewed-on: #334
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: JPikachu <jpikachu@eden-emu.dev>
Co-committed-by: JPikachu <jpikachu@eden-emu.dev>
2025-08-27 22:19:17 +02:00
9fae048a5a
revert [jit] Increase x86_64 default code size to full 2GiB hugepage (#318) (#337)
revert [jit] Increase x86_64 default code size to full 2GiB hugepage (#318)

Abuses the existence of transparent huge pages on Unix. 4*2 = 8GiB virtual memory used total by JIT. May reduce native host TLB trees.

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

WIP: Wasn't meant to be merged, it's going to be refined to be added later when more data/ testing have been made about this approach.
Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #318
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #337
Co-authored-by: CamilleLaVey <camillelavey99@gmail.com>
Co-committed-by: CamilleLaVey <camillelavey99@gmail.com>
2025-08-27 21:28:23 +02:00
eb80a30c42
revert 22847ec78a (#331)
revert [jit] Disable fastmem (by default) on FreeBSD, Solaris and OpenBSD due to subpar timings of SIGSEGV (#319)
According to MaranBR, this should have never been merged and should have been closed instead as they iterated on it in 324.

Reviewed-on: #319
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #331
Co-authored-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-committed-by: Shinmegumi <shinmegumi@eden-emu.dev>
2025-08-27 15:12:16 +02:00
22847ec78a
[jit] Disable fastmem (by default) on FreeBSD, Solaris and OpenBSD due to subpar timings of SIGSEGV (#319)
Reviewed-on: #319
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-27 12:12:32 +02:00
3cb8e6111a
[jit] Increase x86_64 default code size to full 2GiB hugepage (#318)
Abuses the existence of transparent huge pages on Unix. 4*2 = 8GiB virtual memory used total by JIT. May reduce native host TLB trees.

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

Reviewed-on: #318
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-27 12:10:53 +02:00
21cd44ec04
[dynarmic] jit fix branch v2 (#203)
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #203
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
2025-08-27 06:49:50 +02:00
c9a3baab5d
[heap_tracker] Use ankerl map instead of rb tree (#249)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #249
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-27 05:00:38 +02:00
380cfcaeed
[VK] Hybrid memory allocation with robust alignment (#325)
Combines robust OOM handling with progressive size reduction and spec-compliant alignment:

This hybrid approach maximizes allocation success rates through multiple recovery tries.

Reviewed-on: #325
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>

Credits to Wildcard
Co-authored-by: wildcard <wildcard@eden-emu.dev>
Co-committed-by: wildcard <wildcard@eden-emu.dev>
2025-08-27 04:45:50 +02:00
44d658bbc5
[core] Fix Diablo 3 (#314)
This fixes Diablo 3. Regression introduced on PR 311.

Reviewed-on: #314
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-25 21:04:44 +02:00
a1c5b5c911
[core] Fix a specific condition where the controller applet would still freeze in MK8D (#311)
This fixes a specific condition where the controller applet would still freeze on the MK8D under certain circumstances.

Reviewed-on: #311
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-25 18:23:38 +02:00
302509d84d
[compat] fix clang std::terminate error (#307)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #307
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-25 14:43:50 +02:00
4ea9664ff4
[video_core] Fix EDS defaults by platform (#305)
Reviewed-on: #305
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-24 02:05:38 +02:00
e59065b542
[VK] change bind point from Graphics to Compute since its a compute pipeline (#293)
Title is sufficient

Reviewed-on: #293
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: wildcard <wildcard@eden-emu.dev>
Co-committed-by: wildcard <wildcard@eden-emu.dev>
2025-08-24 01:16:06 +02:00
eb72a358e3
[vk] Fix dynamic vertex input state handling (#295)
only applies vertex input state if the pipeline was created with it

Reviewed-on: #295
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-committed-by: Shinmegumi <shinmegumi@eden-emu.dev>
2025-08-23 20:34:05 +02:00
4eb6d10d62
[Vk] Improve Stencil Handling and Fix Read-After-Write Hazard (#235)
1. Improves stencil handling:
   - Adds surface type detection to distinguish between color, depth, stencil, and depth-stencil formats
   - Only enables stencil load/store operations for surfaces that actually contain stencil data
   - Avoids unnecessary stencil operations for non-stencil formats (DONT_CARE)

2. Fixes read-after-write (RAW) synchronization hazards:
   - Adds a subpass self-dependency (subpass 0 → subpass 0)
   - Synchronizes color/depth writes with subsequent shader reads
   - Uses VK_DEPENDENCY_BY_REGION_BIT for efficient synchronization
   - Covers all possible relevant stages,
     • src: Color output + Early/Late fragment tests
     • dst: Fragment shader
     • Access: Write → Read transitions
here is what hazard looks like [1147.550616] Render.Vulkan <Critical> video_core/vulkan_common/vulkan_debug_callback.cpp:DebugUtilCallback:55: Validation Error: [ SYNC-HAZARD-READ-AFTER-WRITE ] Object 0: handle = 0x7409630000000192, type = VK_OBJECT_TYPE_IMAGE_VIEW; | MessageID = 0xe4d96472 | vkCmdDrawIndexed: Hazard READ_AFTER_WRITE for VkImageView 0x7409630000000192[], in VkCommandBuffer 0xb400007cb003ea70[], and VkPipeline 0x44d3470000000213[], VkDescriptorSet 0x0[], type: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageLayout: VK_IMAGE_LAYOUT_GENERAL, binding #2, index 0. Access info (usage: SYNC_FRAGMENT_SHADER_SHADER_SAMPLED_READ, prior_usage: SYNC_IMAGE_LAYOUT_TRANSITION, write_barriers: SYNC_FRAGMENT_SHADER_COLOR_ATTACHMENT_READ|SYNC_FRAGMENT_SHADER_DEPTH_STENCIL_ATTACHMENT_READ|SYNC_FRAGMENT_SHADER_INPUT_ATTACHMENT_READ|SYNC_EARLY_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_READ|SYNC_EARLY_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE|SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_READ|SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE|SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_READ|SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE|SYNC_SUBPASS_SHADER_HUAWEI_INPUT_ATTACHMENT_READ, command: vkCmdPipelineBarrier, seq_no: 45, reset_no: 129).

Reviewed-on: #235
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: wildcard <nubieluv@gmail.com>
Co-committed-by: wildcard <nubieluv@gmail.com>
2025-08-23 20:04:48 +02:00
949f72222b
[VK] spec-clean MasterSemaphore submits (#285)
fixes this error [  18.505526] Render.Vulkan <Info> video_core/vulkan_common/vulkan_debug_callback.cpp:DebugUtilCallback:59: Validation Information: [ UNASSIGNED-BestPractices-SemaphoreCount ] | MessageID = 0x6cfe18a5 | pSubmits[0].pWaitSemaphores is set, but pSubmits[0].waitSemaphoreCount is 0.
This patch is only corrective in nature and is trivial and should not fix or break anything just one of the best practices in vulkan. It nulls pWaitSemaphores / pWaitDstStageMask / pSignalSemaphores when the corresponding counts are zero.

Reviewed-on: #285
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: wildcard <wildcard@eden-emu.dev>
Co-committed-by: wildcard <wildcard@eden-emu.dev>
2025-08-23 20:00:58 +02:00
c228f9b746
updated the translation (#288)
Reviewed-on: #288
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Co-committed-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
2025-08-23 19:53:16 +02:00
94bcd64153
[cmake] refactor: SDL2 CI and CPMUtil::AddCIPackage (#284)
Replaces bundled SDL2 with my SDL2 CI, and updates external SDL2

Additionally, reduces all that boilerplate with a common AddCIPackage in
CPMUtil.cmake, currently used by OpenSSL and SDL2. To be used with ffmpeg in the future

Signed-off-by: crueter <crueter@crueter.xyz>
Reviewed-on: #284
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
2025-08-23 19:42:49 +02:00
5b864d406d
[video_core] Add option to control the DMA precision level at runtime (#304)
This adds an option to control the DMA precision level at runtime.

Co-authored-by: crueter <crueter@eden-emu.dev>
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Reviewed-on: #304
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-23 19:42:10 +02:00
a51953e4f9
[video_core] Add hability to change Sync Memory Operations at runtime (#300)
This adds the hability to change Sync Memory Operations at runtime.

Reviewed-on: #300
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-22 16:23:34 +02:00
35ec256c74
[translation] EDS Description (#297)
Reviewed-on: #297
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Co-committed-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
2025-08-21 23:57:32 +02:00
e75ceb676b
[core] Finalize AliasRegionExtraSize (#291)
The previous implementation was based on assumptions for the baseline.
The new implementation is based on calculations, and should be more robust for DRAM values beyond 8GB as well.

Reviewed-on: #291
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: SDK-Chan <sdkchan@eden-emu.dev>
Co-committed-by: SDK-Chan <sdkchan@eden-emu.dev>
2025-08-21 21:08:43 +02:00
de5c761aa7
[video_core] Update Vulkan Extended Dynamic State settings (#292)
This updates the Vulkan Extended Dynamic State settings and descriptions to improve and make it more clear how it works.

Reviewed-on: #292
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-21 19:27:39 +02:00
0e7203df34
feat(android): add automatic GPU driver download for intent launches (#279)
Reviewed-on: #279
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Producdevity <y.gherbi.dev@gmail.com>
Co-committed-by: Producdevity <y.gherbi.dev@gmail.com>
2025-08-20 19:48:07 +02:00
7ce051cfb3
[core] Unstub AliasRegionExtraSize (#260)
This implementation is basically usable for up to 8GB of DRAM which you can set in the emulator.
It should ensure that the alias or map region for the virtual address space is bigger when requested.
8GB DRAM is the size of Nintendos DRAM sticks in the developers kit.
Going above 8GB DRAM while emulating a game is not recommended.
That is why this implementation.

Reviewed-on: #260
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: SDK-Chan <sdkchan@eden-emu.dev>
Co-committed-by: SDK-Chan <sdkchan@eden-emu.dev>
2025-08-20 17:16:13 +02:00
7bfa2404a6
[video_core] Improve DMA logic and add an option to sync memory operations (#276)
This improves DMA logic and add an option to sync memory operations.

Thanks to Higgs for the new DMA logic.

Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #276
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-20 00:21:25 +02:00
bf7f3e25fc
[compat] fix solaris build and update instructions for CPM on solaris (#270)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #270
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-20 00:21:16 +02:00
5180031313
[ci, cmake] openssl updates, fix drpc and ci scripts (#283)
- Add bundled OpenSSL libs for Solaris, FreeBSD, Linux
- Fix CPMUtil default on msvc
- Update CI scripts (thanks dravee)
- PLATFORM_<OS> helpers for non-ANDROID UNIX

Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Signed-off-by: crueter <crueter@eden-emu.dev>

Reviewed-on: #283
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: crueter <crueter@crueter.xyz>
Co-committed-by: crueter <crueter@crueter.xyz>
2025-08-19 21:29:36 +02:00
1307f3510d
[externals] Fix usage of USE_CCACHE for Sirit (#282)
This Fixes usage of USE_CCACHE for Sirit.

Credit: DraVee

Reviewed-on: #282
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-19 17:39:28 +02:00
12f5a96f01
[Textures] Normalize 1D TICs that use layers to 1DArray; (#274)
Some TIC entries are tagged Texture1D but actually use array layers so previously it was marked as simple 1D and hence the assert, this fixes the said issue(Depth > 1 or baseLayer != 0).
Games fixed- God Eater 3

Reviewed-on: #274
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: wildcard <wildcard@eden-emu.dev>
Co-committed-by: wildcard <wildcard@eden-emu.dev>
2025-08-19 02:28:17 +02:00
77b3f159af
updated the translation (#275)
Reviewed-on: #275
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Co-committed-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
2025-08-18 20:58:40 +02:00
c97d0c8b53
[desktop] Fix VRAM Usage Mode description (#277)
Reviewed-on: #277
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-08-18 20:10:34 +02:00
Bix
4cc4d315f0
[Frontend] add X links to About and Help (#272)
Based off the recent addition of revolt links.
Authored-by: Bix bix@bixed.xyz
Signed-off-by: Bix bix@bixed.xyz

Reviewed-on: #272
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Bix <bix@bixed.xyz>
Co-committed-by: Bix <bix@bixed.xyz>
2025-08-16 17:32:18 +02:00
d96da5104b
[cmake] final CPM fixes (#267)
- remove vcpkg references in docs
- move externals around
- fix non-cpm stuff
- remove redundant simpleini call/dir

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

Reviewed-on: #267
Reviewed-by: Maufeat <sahyno1996@gmail.com>
2025-08-16 03:19:02 +02:00
1f5f9d34d1
[desktop] update sample shading fraction tooltip (#266)
more clear on what the slider doessssssssss

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

Reviewed-on: #266
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
2025-08-16 00:42:54 +02:00
279 changed files with 5906 additions and 14188 deletions

View file

@ -96,7 +96,6 @@ cmake .. -G Ninja \
-DUSE_DISCORD_PRESENCE=ON \
-DCMAKE_CXX_FLAGS="$ARCH_FLAGS" \
-DCMAKE_C_FLAGS="$ARCH_FLAGS" \
-DYUZU_USE_BUNDLED_VCPKG=OFF \
-DYUZU_USE_BUNDLED_QT=OFF \
-DYUZU_USE_BUNDLED_SDL2=OFF \
-DYUZU_USE_EXTERNAL_SDL2=ON \

View file

@ -4,7 +4,7 @@
$ErrorActionPreference = "Stop"
$VulkanSDKVer = "1.4.321.1"
$ExeFile = "VulkanSDK-$VulkanSDKVer-Installer.exe"
$ExeFile = "vulkansdk-windows-X64-$VulkanSDKVer.exe"
$Uri = "https://sdk.lunarg.com/sdk/download/$VulkanSDKVer/windows/$ExeFile"
$Destination = "./$ExeFile"
@ -30,4 +30,4 @@ echo "Finished installing Vulkan SDK $VulkanSDKVer"
if ("$env:GITHUB_ACTIONS" -eq "true") {
echo "VULKAN_SDK=$VULKAN_SDK" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "$VULKAN_SDK/Bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
}
}

View file

@ -3,11 +3,16 @@ GITREV=$(git show -s --format='%h')
ZIP_NAME="Eden-Windows-${ARCH}-${GITDATE}-${GITREV}.zip"
mkdir -p artifacts
mkdir -p pack
ARTIFACTS_DIR="artifacts"
PKG_DIR="build/pkg"
cp -r build/pkg/* pack
mkdir -p "$ARTIFACTS_DIR"
cp LICENSE* README* pack/
TMP_DIR=$(mktemp -d)
7z a -tzip artifacts/$ZIP_NAME pack/*
cp -r "$PKG_DIR"/* "$TMP_DIR"/
cp LICENSE* README* "$TMP_DIR"/
7z a -tzip "$ARTIFACTS_DIR/$ZIP_NAME" "$TMP_DIR"/*
rm -rf "$TMP_DIR"

1
.gitignore vendored
View file

@ -52,3 +52,4 @@ Thumbs.db
eden-windows-msvc
artifacts
*.AppImage*
/install*

View file

@ -128,10 +128,6 @@ Copyright: 2020-2021 Its-Rei <kupfel@gmail.com>
2020-2021 yuzu Emulator Project
License: GPL-2.0-or-later
Files: vcpkg.json
Copyright: 2022 yuzu Emulator Project
License: GPL-3.0-or-later
Files: .github/ISSUE_TEMPLATE/*
Copyright: 2022 yuzu Emulator Project
License: GPL-2.0-or-later

View file

@ -1,57 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
"name": "yuzu",
"builtin-baseline": "ea2a964f9303270322cf3f2d51c265ba146c422d",
"version": "1.0",
"dependencies": [
"boost-algorithm",
"boost-asio",
"boost-bind",
"boost-config",
"boost-container",
"boost-context",
"boost-crc",
"boost-functional",
"boost-heap",
"boost-icl",
"boost-intrusive",
"boost-mpl",
"boost-range",
"boost-spirit",
"boost-process",
"boost-test",
"boost-timer",
"boost-variant",
"fmt",
"lz4",
"nlohmann-json",
"zlib",
"zstd",
"sdl2"
],
"features": {
"yuzu-tests": {
"description": "Compile tests",
"dependencies": [ "catch2" ]
},
"web-service": {
"description": "Enable web services (telemetry, etc.)",
"dependencies": [
{
"name": "openssl"
}
]
}
},
"overrides": [
{
"name": "catch2",
"version": "3.3.1"
},
{
"name": "boost-process",
"version": "1.81.0"
}
]
}

View file

@ -5,12 +5,28 @@ cmake_minimum_required(VERSION 3.22)
project(yuzu)
if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
set(PLATFORM_SUN ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
set(PLATFORM_FREEBSD ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
set(PLATFORM_OPENBSD ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(PLATFORM_LINUX ON)
endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
if (PLATFORM_SUN)
# Terrific Solaris pkg shenanigans
list(APPEND CMAKE_PREFIX_PATH "/usr/lib/qt/6.6/lib/amd64/cmake")
list(APPEND CMAKE_MODULE_PATH "/usr/lib/qt/6.6/lib/amd64/cmake")
# For some mighty reason, doing a normal release build sometimes may not trigger
# the proper -O3 switch to materialize
if (CMAKE_BUILD_TYPE MATCHES "Release")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
endif()
endif()
set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm)
@ -24,28 +40,22 @@ if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX-")
endif()
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
if (PLATFORM_FREEBSD)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
endif()
# Check if SDL2::SDL2 target exists; if not, create an alias
if (TARGET SDL2::SDL2-static)
add_library(SDL2::SDL2 ALIAS SDL2::SDL2-static)
elseif (TARGET SDL2::SDL2-shared)
add_library(SDL2::SDL2 ALIAS SDL2::SDL2-shared)
endif()
# Set bundled sdl2/qt as dependent options.
# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
CMAKE_DEPENDENT_OPTION(ENABLE_SDL2 "Enable the SDL2 frontend" ON "NOT ANDROID" OFF)
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
CMAKE_DEPENDENT_OPTION(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" OFF "ENABLE_SDL2;NOT MSVC" OFF)
else()
CMAKE_DEPENDENT_OPTION(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" ON "ENABLE_SDL2;NOT MSVC" OFF)
set(EXT_DEFAULT ON)
if (PLATFORM_FREEBSD)
set(EXT_DEFAULT OFF)
endif()
CMAKE_DEPENDENT_OPTION(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" ${EXT_DEFAULT} "ENABLE_SDL2;NOT MSVC" OFF)
cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "NOT ANDROID" OFF)
option(ENABLE_OPENGL "Enable OpenGL" ON)
@ -57,41 +67,15 @@ option(ENABLE_QT_UPDATE_CHECKER "Enable update checker for the Qt frontend" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF)
# TODO(crueter): maybe this should default on everywhere...?
if (MSVC OR ANDROID)
set(CPM_DEFAULT ON)
else()
set(CPM_DEFAULT OFF)
endif()
option(YUZU_USE_CPM "Use CPM for Eden dependencies" "${CPM_DEFAULT}")
option(YUZU_USE_CPM "Use CPM to fetch Eden dependencies if needed" ON)
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
option(ENABLE_WIFI_SCAN "Enable WiFi scanning" OFF)
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" OFF)
else()
option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" ON)
endif()
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" OFF)
else()
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON)
endif()
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan-Utility-Libraries from externals" OFF)
else()
option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan-Utility-Libraries from externals" ON)
endif()
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
option(YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS "Use SPIRV-Tools from externals" OFF)
else()
option(YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS "Use SPIRV-Tools from externals" ON)
endif()
option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" ${EXT_DEFAULT})
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ${EXT_DEFAULT})
option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan-Utility-Libraries from externals" ${EXT_DEFAULT})
option(YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS "Use SPIRV-Tools from externals" ${EXT_DEFAULT})
option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
@ -101,22 +85,22 @@ set(YUZU_QT_MIRROR "" CACHE STRING "What mirror to use for downloading the bundl
option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
CMAKE_DEPENDENT_OPTION(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF "ENABLE_QT" OFF)
option(ENABLE_MICROPROFILE "Enables microprofile capabilities" OFF)
option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}")
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF)
else()
option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
endif()
option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ${EXT_DEFAULT})
option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON)
option(FORCE_DOWNLOAD_WIN_BUNDLES "Forcefully download bundled Windows dependencies (useful for CI)" OFF)
if (YUZU_USE_CPM AND ENABLE_SDL2)
option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}")
endif()
CMAKE_DEPENDENT_OPTION(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF)
@ -125,11 +109,7 @@ CMAKE_DEPENDENT_OPTION(YUZU_CMD "Compile the eden-cli executable" ON "NOT ANDROI
CMAKE_DEPENDENT_OPTION(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR LINUX" OFF)
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
option(YUZU_CHECK_SUBMODULES "Check if submodules are present" OFF)
else()
option(YUZU_CHECK_SUBMODULES "Check if submodules are present" ON)
endif()
option(YUZU_CHECK_SUBMODULES "Check if submodules are present" ${EXT_DEFAULT})
option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF)
@ -142,7 +122,7 @@ CMAKE_DEPENDENT_OPTION(YUZU_USE_FASTER_LD "Check if a faster linker is available
CMAKE_DEPENDENT_OPTION(USE_SYSTEM_MOLTENVK "Use the system MoltenVK lib (instead of the bundled one)" OFF "APPLE" OFF)
set(DEFAULT_ENABLE_OPENSSL ON)
if (ANDROID OR WIN32 OR APPLE OR ${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
if (ANDROID OR WIN32 OR APPLE OR PLATFORM_SUN)
# - Windows defaults to the Schannel backend.
# - macOS defaults to the SecureTransport backend.
# - Android currently has no SSL backend as the NDK doesn't include any SSL
@ -158,6 +138,10 @@ endif()
option(ENABLE_OPENSSL "Enable OpenSSL backend for ISslConnection" ${DEFAULT_ENABLE_OPENSSL})
if (ENABLE_OPENSSL)
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_OPENSSL "Download bundled OpenSSL build" "${MSVC}" "NOT ANDROID" ON)
endif()
if (ANDROID AND YUZU_DOWNLOAD_ANDROID_VVL)
set(vvl_version "sdk-1.3.261.1")
set(vvl_zip_file "${CMAKE_BINARY_DIR}/externals/vvl-android.zip")
@ -190,12 +174,12 @@ if (YUZU_USE_PRECOMPILED_HEADERS)
set(YUZU_USE_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE)
endif()
endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
message(STATUS "Using Precompiled Headers.")
set(CMAKE_PCH_INSTANTIATE_TEMPLATES ON)
endif()
# Default to a Release build
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE)
@ -256,20 +240,24 @@ endfunction()
if(EXISTS ${PROJECT_SOURCE_DIR}/.gitmodules AND YUZU_CHECK_SUBMODULES)
check_submodules_present()
endif()
configure_file(${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.qrc
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
COPYONLY)
if (EXISTS ${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.json)
configure_file("${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.json"
"${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json"
COPYONLY)
endif()
if (ENABLE_COMPATIBILITY_LIST_DOWNLOAD AND NOT EXISTS ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
message(STATUS "Downloading compatibility list for yuzu...")
file(DOWNLOAD
https://api.yuzu-emu.org/gamedb/
"${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json" SHOW_PROGRESS)
endif()
if (NOT EXISTS ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
file(WRITE ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json "")
endif()
@ -313,13 +301,20 @@ if (NOT DEFINED ARCHITECTURE)
set(ARCHITECTURE_GENERIC 1)
add_definitions(-DARCHITECTURE_GENERIC=1)
endif()
message(STATUS "Target architecture: ${ARCHITECTURE}")
if (MSVC AND ARCHITECTURE_x86)
message(FATAL_ERROR "Attempting to build with the x86 environment is not supported. \
This can typically happen if you used the Developer Command Prompt from the start menu;\
instead, run vcvars64.bat directly, located at C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat")
endif()
if (UNIX)
add_definitions(-DYUZU_UNIX=1)
endif()
if (ARCHITECTURE_arm64 AND (ANDROID OR APPLE OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux"))
if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX))
set(HAS_NCE 1)
add_definitions(-DHAS_NCE=1)
endif()
@ -329,7 +324,7 @@ if (YUZU_ROOM)
endif()
# Build/optimization presets
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
if (PLATFORM_LINUX)
if (ARCHITECTURE_x86_64)
set(YUZU_BUILD_PRESET "custom" CACHE STRING "Build preset to use. One of: custom, generic, v3, zen2, zen4, native")
if (${YUZU_BUILD_PRESET} STREQUAL "generic")
@ -375,8 +370,18 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
# System imported libraries
# =======================================================================
include(CPMUtil)
# openssl funniness
if (ENABLE_OPENSSL)
if (YUZU_USE_BUNDLED_OPENSSL)
AddJsonPackage(openssl)
endif()
find_package(OpenSSL 1.1.1 REQUIRED)
endif()
if (YUZU_USE_CPM)
include(CPMUtil)
message(STATUS "Fetching needed dependencies with CPM")
set(BUILD_SHARED_LIBS OFF)
@ -384,55 +389,12 @@ if (YUZU_USE_CPM)
# TODO(crueter): renderdoc?
# openssl funniness
if (ENABLE_OPENSSL)
if (MSVC)
set(BUILD_SHARED_LIBS OFF)
AddPackage(
NAME OpenSSL
REPO crueter/OpenSSL-CI
TAG v3.5.2
VERSION 3.5.2
ARTIFACT openssl-windows-3.5.2.tar.zst
KEY windows
HASH_SUFFIX sha512sum
BUNDLED_PACKAGE ON
)
include(${OpenSSL_SOURCE_DIR}/openssl.cmake)
endif()
if (ANDROID)
set(BUILD_SHARED_LIBS OFF)
AddPackage(
NAME OpenSSL
REPO crueter/OpenSSL-CI
TAG v3.5.2
VERSION 3.5.2
ARTIFACT openssl-android-3.5.2.tar.zst
KEY android
HASH_SUFFIX sha512sum
BUNDLED_PACKAGE ON
)
include(${OpenSSL_SOURCE_DIR}/openssl.cmake)
endif()
endif()
AddPackage(
NAME Boost
REPO boostorg/boost
TAG boost-1.88.0
ARTIFACT boost-1.88.0-cmake.7z
HASH e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01
GIT_VERSION 1.88.0
VERSION 1.57
)
# boost
set(BOOST_INCLUDE_LIBRARIES algorithm icl pool container heap asio headers process filesystem crc variant)
AddJsonPackage(boost)
# really annoying thing where boost::headers doesn't work with cpm
# TODO(crueter) investigate
set(BOOST_NO_HEADERS ${Boost_ADDED})
if (Boost_ADDED)
@ -444,86 +406,57 @@ if (YUZU_USE_CPM)
if (NOT MSVC)
# boost sucks
if (NOT PLATFORM_LINUX AND NOT ANDROID)
target_compile_definitions(boost_container INTERFACE BOOST_HAS_PTHREADS)
endif()
target_compile_options(boost_heap INTERFACE -Wno-shadow)
target_compile_options(boost_icl INTERFACE -Wno-shadow)
target_compile_options(boost_asio INTERFACE -Wno-conversion -Wno-implicit-fallthrough)
endif()
endif()
AddPackage(
NAME fmt
REPO fmtlib/fmt
SHA 40626af88b
HASH d59f06c24339f223de4ec2afeba1c67b5835a0f350a1ffa86242a72fc3e616a6b8b21798355428d4200c75287308b66634619ffa0b52ba5bd74cc01772ea1a8a
VERSION 8
OPTIONS
"FMT_INSTALL OFF"
)
# fmt
AddJsonPackage(fmt)
AddPackage(
NAME lz4
REPO lz4/lz4
SHA ebb370ca83
HASH 43600e87b35256005c0f2498fa56a77de6783937ba4cfce38c099f27c03188d097863e8a50c5779ca0a7c63c29c4f7ed0ae526ec798c1fd2e3736861b62e0a37
SOURCE_SUBDIR build/cmake
)
# lz4
AddJsonPackage(lz4)
if (lz4_ADDED)
add_library(lz4::lz4 ALIAS lz4_static)
endif()
AddPackage(
NAME nlohmann_json
REPO nlohmann/json
SHA 55f93686c0
HASH b739749b066800e21154506ea150d2c5cbce8a45344177f46f884547a1399d26753166fd0df8135269ce28cf223552b1b65cd625b88c844d54753f2434900486
VERSION 3.8
)
# nlohmann
AddJsonPackage(nlohmann)
AddPackage(
NAME SimpleIni
REPO brofield/simpleini
SHA 09c21bda1d
HASH 99779ca9b6e040d36558cadf484f9ffdab5b47bcc8fc72e4d33639d1d60c0ceb4410d335ba445d72a4324e455167fd6769d99b459943aa135bec085dff2d4b7c
EXCLUDE_FROM_ALL ON
)
AddPackage(
NAME ZLIB
REPO madler/zlib
SHA 51b7f2abda
HASH 16eaf1f3752489d12fd9ce30f7b5f7cbd5cb8ff53d617005a9847ae72d937f65e01e68be747f62d7ac19fd0c9aeba9956e60f16d6b465c5fdc2f3d08b4db2e6c
VERSION 1.2
OPTIONS
"ZLIB_BUILD_SHARED OFF"
"ZLIB_INSTALL OFF"
EXCLUDE_FROM_ALL ON
)
# zlib
AddJsonPackage(zlib)
if (ZLIB_ADDED)
add_library(ZLIB::ZLIB ALIAS zlibstatic)
endif()
set(ZSTD_BUILD_SHARED OFF)
AddPackage(
NAME zstd
REPO facebook/zstd
SHA f8745da6ff
HASH 3037007f990040fe32573b46f9bef8762fd5dbeeb07ffffcbfeba51ec98167edae39bb9c87f9299efcd61c4e467c5e84f7c19f0df7799bc1fc04864a278792ee
VERSION 1.5
SOURCE_SUBDIR build/cmake
EXCLUDE_FROM_ALL ON
)
# zstd
AddJsonPackage(zstd)
if (YUZU_TESTS OR DYNARMIC_TESTS)
AddPackage(
NAME Catch2
REPO catchorg/Catch2
SHA 644821ce28
HASH f8795f98acf2c02c0db8e734cc866d5caebab4b4a306e93598b97cb3c0c728dafe8283dce27ffe8d42460e5ae7302f3f32e7e274a7f991b73511ac88eef21b1f
VERSION 3.0.1
)
if (zstd_ADDED)
add_library(zstd::zstd ALIAS libzstd_static)
endif()
# Catch2
if (YUZU_TESTS OR DYNARMIC_TESTS)
AddJsonPackage(catch2)
endif()
# ENet
AddJsonPackage(enet)
if (enet_ADDED)
target_include_directories(enet INTERFACE ${enet_SOURCE_DIR}/include)
endif()
# Opus
AddJsonPackage(opus)
else()
# Enforce the search mode of non-required packages for better and shorter failure messages
find_package(fmt 8 REQUIRED)
@ -531,10 +464,11 @@ else()
find_package(nlohmann_json 3.8 REQUIRED)
find_package(lz4 REQUIRED)
find_package(RenderDoc MODULE)
find_package(SimpleIni MODULE)
find_package(stb MODULE)
find_package(enet 1.3 MODULE REQUIRED)
find_package(Opus 1.3 MODULE REQUIRED)
find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED)
find_package(zstd 1.5 REQUIRED MODULE)
if (YUZU_TESTS)
find_package(Catch2 3.0.1 REQUIRED)
@ -549,48 +483,92 @@ else()
endif()
endif()
if(NOT TARGET Boost::headers)
AddJsonPackage(boost_headers)
endif()
if (ENABLE_LIBUSB)
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
if (PLATFORM_FREEBSD)
find_package(libusb MODULE)
else()
find_package(libusb 1.0.24 MODULE)
endif()
endif()
# TODO(crueter): Work around this
if (NOT YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS)
find_package(PkgConfig REQUIRED)
pkg_check_modules(SPIRV-Tools REQUIRED SPIRV-Tools)
# DiscordRPC
if (USE_DISCORD_PRESENCE)
AddJsonPackage(discord-rpc)
target_include_directories(discord-rpc INTERFACE ${discord-rpc_SOURCE_DIR}/include)
add_library(DiscordRPC::discord-rpc ALIAS discord-rpc)
endif()
# SimpleIni
AddJsonPackage(simpleini)
# Most linux distros don't package cubeb, so enable regardless of cpm settings
if(ENABLE_CUBEB)
AddJsonPackage(cubeb)
if (cubeb_ADDED)
if (NOT MSVC)
if (TARGET speex)
target_compile_options(speex PRIVATE -Wno-sign-compare)
endif()
set_target_properties(cubeb PROPERTIES COMPILE_OPTIONS "")
target_compile_options(cubeb INTERFACE
-Wno-implicit-const-int-float-conversion
-Wno-shadow
-Wno-missing-declarations
-Wno-return-type
-Wno-uninitialized
)
else()
target_compile_options(cubeb PRIVATE
/wd4456
/wd4458
)
endif()
endif()
endif()
# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the YUZU_find_package
# TODO(crueter): combine this all with CPM.
if (ENABLE_SDL2)
if (YUZU_USE_BUNDLED_SDL2)
# Detect toolchain and platform
if ((MSVC_VERSION GREATER_EQUAL 1920) AND ARCHITECTURE_x86_64)
set(SDL2_VER "SDL2-2.32.8")
else()
message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.")
endif()
if (DEFINED SDL2_VER)
download_bundled_external("sdl2/" ${SDL2_VER} "sdl2-bundled" SDL2_PREFIX 2.32.8)
endif()
set(SDL2_FOUND YES)
set(SDL2_INCLUDE_DIR "${SDL2_PREFIX}/include" CACHE PATH "Path to SDL2 headers")
set(SDL2_LIBRARY "${SDL2_PREFIX}/lib/x64/SDL2.lib" CACHE PATH "Path to SDL2 library")
set(SDL2_DLL_DIR "${SDL2_PREFIX}/lib/x64/" CACHE PATH "Path to SDL2.dll")
add_library(SDL2::SDL2 INTERFACE IMPORTED)
target_link_libraries(SDL2::SDL2 INTERFACE "${SDL2_LIBRARY}")
target_include_directories(SDL2::SDL2 INTERFACE "${SDL2_INCLUDE_DIR}")
elseif (YUZU_USE_EXTERNAL_SDL2)
if (YUZU_USE_EXTERNAL_SDL2)
message(STATUS "Using SDL2 from externals.")
else()
find_package(SDL2 2.26.4 REQUIRED)
if (NOT WIN32)
# Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers
# Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095)
# Yuzu-cmd also needs: Video (depends on Loadso/Dlopen)
# CPUinfo also required for SDL Audio, at least until 2.28.0 (see https://github.com/libsdl-org/SDL/issues/7809)
set(SDL_UNUSED_SUBSYSTEMS
File Filesystem
Locale Power Render)
foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT)
set(SDL_${_OPT} OFF)
endforeach()
set(HIDAPI ON)
endif()
if (APPLE)
set(SDL_FILE ON)
endif()
if ("${YUZU_SYSTEM_PROFILE}" STREQUAL "steamdeck")
set(SDL_PIPEWIRE OFF) # build errors out with this on
AddJsonPackage("sdl2_steamdeck")
else()
AddJsonPackage("sdl2_generic")
endif()
elseif (YUZU_USE_BUNDLED_SDL2)
message(STATUS "Using bundled SDL2")
AddJsonPackage(sdl2)
endif()
find_package(SDL2 2.26.4 REQUIRED)
endif()
# List of all FFmpeg components required
@ -624,6 +602,7 @@ add_subdirectory(externals)
find_package(VulkanHeaders)
find_package(VulkanUtilityLibraries)
find_package(VulkanMemoryAllocator)
find_package(SPIRV-Tools)
if (ENABLE_WEB_SERVICE)
find_package(httplib)
@ -633,8 +612,8 @@ if (ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER)
find_package(cpp-jwt)
endif()
if (NOT YUZU_USE_BUNDLED_SDL2)
find_package(SDL2 REQUIRED)
if (ENABLE_SDL2)
find_package(SDL2)
endif()
if (ENABLE_QT)
@ -655,7 +634,7 @@ if (ENABLE_QT)
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_package(Qt6 REQUIRED COMPONENTS DBus GuiPrivate)
find_package(Qt6 REQUIRED COMPONENTS DBus OPTIONAL_COMPONENTS GuiPrivate)
elseif (UNIX AND NOT APPLE)
find_package(Qt6 REQUIRED COMPONENTS DBus Gui)
endif()
@ -686,7 +665,7 @@ endif()
function(set_yuzu_qt_components)
# Best practice is to ask for all components at once, so they are from the same version
set(YUZU_QT_COMPONENTS2 Core Widgets Concurrent)
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
if (PLATFORM_LINUX)
list(APPEND YUZU_QT_COMPONENTS2 DBus)
endif()
if (YUZU_USE_QT_MULTIMEDIA)

View file

@ -1,22 +1,222 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
# Created-By: crueter
# Docs will come at a later date, mostly this is to just reduce boilerplate
# and some cmake magic to allow for runtime viewing of dependency versions
include(CMakeDependentOption)
CMAKE_DEPENDENT_OPTION(CPMUTIL_DEFAULT_SYSTEM
"Allow usage of system packages for CPM dependencies" ON
"NOT ANDROID" OFF)
# Future crueter: Wow this was a lie and a half, at this point I might as well make my own CPN
# haha just kidding... unless?
if (MSVC OR ANDROID)
set(BUNDLED_DEFAULT OFF)
else()
set(BUNDLED_DEFAULT ON)
endif()
option(CPMUTIL_FORCE_BUNDLED
"Force bundled packages for all CPM depdendencies" ${BUNDLED_DEFAULT})
option(CPMUTIL_FORCE_SYSTEM
"Force system packages for all CPM dependencies (NOT RECOMMENDED)" OFF)
cmake_minimum_required(VERSION 3.22)
include(CPM)
# TODO(crueter): Better solution for separate cpmfiles e.g. per-directory
set(CPMUTIL_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json" CACHE STRING "Location of cpmfile.json")
if (EXISTS ${CPMUTIL_JSON_FILE})
file(READ ${CPMUTIL_JSON_FILE} CPMFILE_CONTENT)
else()
message(WARNING "[CPMUtil] cpmfile ${CPMUTIL_JSON_FILE} does not exist, AddJsonPackage will be a no-op")
endif()
# utility
function(cpm_utils_message level name message)
message(${level} "[CPMUtil] ${name}: ${message}")
endfunction()
# utility
function(array_to_list array length out)
math(EXPR range "${length} - 1")
foreach(IDX RANGE ${range})
string(JSON _element GET "${array}" "${IDX}")
list(APPEND NEW_LIST ${_element})
endforeach()
set("${out}" "${NEW_LIST}" PARENT_SCOPE)
endfunction()
# utility
function(get_json_element object out member default)
string(JSON out_type ERROR_VARIABLE err TYPE "${object}" ${member})
if (err)
set("${out}" "${default}" PARENT_SCOPE)
return()
endif()
string(JSON outvar GET "${object}" ${member})
if (out_type STREQUAL "ARRAY")
string(JSON _len LENGTH "${object}" ${member})
# array_to_list("${outvar}" ${_len} outvar)
set("${out}_LENGTH" "${_len}" PARENT_SCOPE)
endif()
set("${out}" "${outvar}" PARENT_SCOPE)
endfunction()
# Kinda cancerous but whatever
function(AddJsonPackage)
set(oneValueArgs
NAME
# these are overrides that can be generated at runtime, so can be defined separately from the json
DOWNLOAD_ONLY
SYSTEM_PACKAGE
BUNDLED_PACKAGE
)
set(multiValueArgs OPTIONS)
cmake_parse_arguments(JSON "" "${oneValueArgs}" "${multiValueArgs}"
"${ARGN}")
list(LENGTH ARGN argnLength)
# single name argument
if(argnLength EQUAL 1)
set(JSON_NAME "${ARGV0}")
endif()
if (NOT DEFINED CPMFILE_CONTENT)
cpm_utils_message(WARNING ${name} "No cpmfile, AddJsonPackage is a no-op")
return()
endif()
if (NOT DEFINED JSON_NAME)
cpm_utils_message(FATAL_ERROR "json package" "No name specified")
endif()
string(JSON object ERROR_VARIABLE err GET "${CPMFILE_CONTENT}" "${JSON_NAME}")
if (err)
cpm_utils_message(FATAL_ERROR ${JSON_NAME} "Not found in cpmfile")
endif()
get_json_element("${object}" package package ${JSON_NAME})
get_json_element("${object}" repo repo "")
get_json_element("${object}" ci ci OFF)
get_json_element("${object}" version version "")
if (ci)
get_json_element("${object}" name name "${JSON_NAME}")
get_json_element("${object}" extension extension "tar.zst")
get_json_element("${object}" min_version min_version "")
get_json_element("${object}" cmake_filename cmake_filename "")
get_json_element("${object}" raw_disabled disabled_platforms "")
if (raw_disabled)
array_to_list("${raw_disabled}" ${raw_disabled_LENGTH} disabled_platforms)
else()
set(disabled_platforms "")
endif()
AddCIPackage(
VERSION ${version}
NAME ${name}
REPO ${repo}
PACKAGE ${package}
EXTENSION ${extension}
MIN_VERSION ${min_version}
DISABLED_PLATFORMS ${disabled_platforms}
CMAKE_FILENAME ${cmake_filename}
)
return()
endif()
get_json_element("${object}" hash hash "")
get_json_element("${object}" sha sha "")
get_json_element("${object}" url url "")
get_json_element("${object}" key key "")
get_json_element("${object}" tag tag "")
get_json_element("${object}" artifact artifact "")
get_json_element("${object}" git_version git_version "")
get_json_element("${object}" source_subdir source_subdir "")
get_json_element("${object}" bundled bundled "unset")
get_json_element("${object}" find_args find_args "")
get_json_element("${object}" raw_patches patches "")
# format patchdir
if (raw_patches)
math(EXPR range "${raw_patches_LENGTH} - 1")
foreach(IDX RANGE ${range})
string(JSON _patch GET "${raw_patches}" "${IDX}")
set(full_patch "${CMAKE_SOURCE_DIR}/.patch/${JSON_NAME}/${_patch}")
if (NOT EXISTS ${full_patch})
cpm_utils_message(FATAL_ERROR ${JSON_NAME} "specifies patch ${full_patch} which does not exist")
endif()
list(APPEND patches "${full_patch}")
endforeach()
endif()
# end format patchdir
# options
get_json_element("${object}" raw_options options "")
if (raw_options)
array_to_list("${raw_options}" ${raw_options_LENGTH} options)
endif()
set(options ${options} ${JSON_OPTIONS})
# end options
# system/bundled
if (bundled STREQUAL "unset" AND DEFINED JSON_BUNDLED_PACKAGE)
set(bundled ${JSON_BUNDLED_PACKAGE})
else()
set(bundled ON)
endif()
AddPackage(
NAME "${package}"
VERSION "${version}"
URL "${url}"
HASH "${hash}"
SHA "${sha}"
REPO "${repo}"
KEY "${key}"
PATCHES "${patches}"
OPTIONS "${options}"
FIND_PACKAGE_ARGUMENTS "${find_args}"
BUNDLED_PACKAGE "${bundled}"
SOURCE_SUBDIR "${source_subdir}"
GIT_VERSION ${git_version}
ARTIFACT ${artifact}
TAG ${tag}
)
# pass stuff to parent scope
set(${package}_ADDED "${${package}_ADDED}"
PARENT_SCOPE)
set(${package}_SOURCE_DIR "${${package}_SOURCE_DIR}"
PARENT_SCOPE)
set(${package}_BINARY_DIR "${${package}_BINARY_DIR}"
PARENT_SCOPE)
endfunction()
function(AddPackage)
cpm_set_policies()
@ -58,9 +258,6 @@ function(AddPackage)
GIT_URL
KEY
DOWNLOAD_ONLY
FIND_PACKAGE_ARGUMENTS
SYSTEM_PACKAGE
BUNDLED_PACKAGE
)
@ -73,6 +270,9 @@ function(AddPackage)
cpm_utils_message(FATAL_ERROR "package" "No package name defined")
endif()
option(${PKG_ARGS_NAME}_FORCE_SYSTEM "Force the system package for ${PKG_ARGS_NAME}")
option(${PKG_ARGS_NAME}_FORCE_BUNDLED "Force the bundled package for ${PKG_ARGS_NAME}")
if (DEFINED PKG_ARGS_URL)
set(pkg_url ${PKG_ARGS_URL})
@ -118,9 +318,9 @@ function(AddPackage)
cpm_utils_message(STATUS ${PKG_ARGS_NAME} "Download URL is ${pkg_url}")
if (DEFINED PKG_ARGS_GIT_VERSION)
set(git_version ${PKG_ARGS_VERSION})
elseif(DEFINED PKG_ARGS_VERSION)
set(git_version ${PKG_ARGS_GIT_VERSION})
elseif(DEFINED PKG_ARGS_VERSION)
set(git_version ${PKG_ARGS_VERSION})
endif()
if (NOT DEFINED PKG_ARGS_KEY)
@ -172,25 +372,55 @@ function(AddPackage)
if (DEFINED hash_url)
set(outfile ${CMAKE_CURRENT_BINARY_DIR}/${PKG_ARGS_NAME}.hash)
file(DOWNLOAD ${hash_url} ${outfile})
file(READ ${outfile} pkg_hash_tmp)
file(REMOVE ${outfile})
# TODO(crueter): This is kind of a bad solution
# because "technically" the hash is invalidated each week
# but it works for now kjsdnfkjdnfjksdn
string(TOLOWER ${PKG_ARGS_NAME} lowername)
if (NOT EXISTS ${outfile} AND NOT EXISTS ${CPM_SOURCE_CACHE}/${lowername}/${pkg_key})
file(DOWNLOAD ${hash_url} ${outfile})
endif()
set(pkg_hash "${hash_algo}=${pkg_hash_tmp}")
if (EXISTS ${outfile})
file(READ ${outfile} pkg_hash_tmp)
endif()
if (DEFINED ${pkg_hash_tmp})
set(pkg_hash "${hash_algo}=${pkg_hash_tmp}")
endif()
endif()
if (NOT CPMUTIL_DEFAULT_SYSTEM)
set(CPM_USE_LOCAL_PACKAGES OFF)
elseif (DEFINED PKG_ARGS_SYSTEM_PACKAGE)
set(CPM_USE_LOCAL_PACKAGES ${PKG_ARGS_SYSTEM_PACKAGE})
macro(set_precedence local force)
set(CPM_USE_LOCAL_PACKAGES ${local})
set(CPM_LOCAL_PACKAGES_ONLY ${force})
endmacro()
#[[
Precedence:
- package_FORCE_SYSTEM
- package_FORCE_BUNDLED
- CPMUTIL_FORCE_SYSTEM
- CPMUTIL_FORCE_BUNDLED
- BUNDLED_PACKAGE
- default to allow local
]]#
if (${PKG_ARGS_NAME}_FORCE_SYSTEM)
set_precedence(ON ON)
elseif (${PKG_ARGS_NAME}_FORCE_BUNDLED)
set_precedence(OFF OFF)
elseif (CPMUTIL_FORCE_SYSTEM)
set_precedence(ON ON)
elseif(NOT CPMUTIL_FORCE_BUNDLED)
set_precedence(OFF OFF)
elseif (DEFINED PKG_ARGS_BUNDLED_PACKAGE)
if (PKG_ARGS_BUNDLED_PACKAGE)
set(CPM_USE_LOCAL_PACKAGES OFF)
set(local OFF)
else()
set(CPM_USE_LOCAL_PACKAGES ON)
set(local ON)
endif()
set_precedence(${local} OFF)
else()
set(CPM_USE_LOCAL_PACKAGES ON)
set_precedence(ON OFF)
endif()
CPMAddPackage(
@ -204,6 +434,7 @@ function(AddPackage)
OPTIONS ${PKG_ARGS_OPTIONS}
PATCHES ${PKG_ARGS_PATCHES}
EXCLUDE_FROM_ALL ON
${PKG_ARGS_UNPARSED_ARGUMENTS}
)
@ -246,3 +477,116 @@ function(AddPackage)
PARENT_SCOPE)
endfunction()
function(add_ci_package key)
set(ARTIFACT ${ARTIFACT_NAME}-${key}-${ARTIFACT_VERSION}.${ARTIFACT_EXT})
AddPackage(
NAME ${ARTIFACT_PACKAGE}
REPO ${ARTIFACT_REPO}
TAG v${ARTIFACT_VERSION}
VERSION ${ARTIFACT_VERSION}
ARTIFACT ${ARTIFACT}
KEY ${key}
HASH_SUFFIX sha512sum
BUNDLED_PACKAGE ON
)
set(ARTIFACT_DIR ${${ARTIFACT_PACKAGE}_SOURCE_DIR} PARENT_SCOPE)
endfunction()
# name is the artifact name, package is for find_package override
function(AddCIPackage)
set(oneValueArgs
VERSION
NAME
REPO
PACKAGE
EXTENSION
MIN_VERSION
DISABLED_PLATFORMS
CMAKE_FILENAME
)
cmake_parse_arguments(PKG_ARGS "" "${oneValueArgs}" "" ${ARGN})
if(NOT DEFINED PKG_ARGS_VERSION)
message(FATAL_ERROR "[CPMUtil] VERSION is required")
endif()
if(NOT DEFINED PKG_ARGS_NAME)
message(FATAL_ERROR "[CPMUtil] NAME is required")
endif()
if(NOT DEFINED PKG_ARGS_REPO)
message(FATAL_ERROR "[CPMUtil] REPO is required")
endif()
if(NOT DEFINED PKG_ARGS_PACKAGE)
message(FATAL_ERROR "[CPMUtil] PACKAGE is required")
endif()
if (NOT DEFINED PKG_ARGS_CMAKE_FILENAME)
set(ARTIFACT_CMAKE ${PKG_ARGS_NAME})
else()
set(ARTIFACT_CMAKE ${PKG_ARGS_CMAKE_FILENAME})
endif()
if(NOT DEFINED PKG_ARGS_EXTENSION)
set(ARTIFACT_EXT "tar.zst")
else()
set(ARTIFACT_EXT ${PKG_ARGS_EXTENSION})
endif()
if (DEFINED PKG_ARGS_MIN_VERSION)
set(ARTIFACT_MIN_VERSION ${PKG_ARGS_MIN_VERSION})
endif()
if (DEFINED PKG_ARGS_DISABLED_PLATFORMS)
set(DISABLED_PLATFORMS ${PKG_ARGS_DISABLED_PLATFORMS})
endif()
# this is mildly annoying
set(ARTIFACT_VERSION ${PKG_ARGS_VERSION})
set(ARTIFACT_NAME ${PKG_ARGS_NAME})
set(ARTIFACT_REPO ${PKG_ARGS_REPO})
set(ARTIFACT_PACKAGE ${PKG_ARGS_PACKAGE})
if ((MSVC AND ARCHITECTURE_x86_64) AND NOT "windows-amd64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(windows-amd64)
endif()
if ((MSVC AND ARCHITECTURE_arm64) AND NOT "windows-arm64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(windows-arm64)
endif()
if (ANDROID AND NOT "android" IN_LIST DISABLED_PLATFORMS)
add_ci_package(android)
endif()
if(PLATFORM_SUN AND NOT "solaris" IN_LIST DISABLED_PLATFORMS)
add_ci_package(solaris)
endif()
if(PLATFORM_FREEBSD AND NOT "freebsd" IN_LIST DISABLED_PLATFORMS)
add_ci_package(freebsd)
endif()
if((PLATFORM_LINUX AND ARCHITECTURE_x86_64) AND NOT "linux" IN_LIST DISABLED_PLATFORMS)
add_ci_package(linux)
endif()
if((PLATFORM_LINUX AND ARCHITECTURE_arm64) AND NOT "linux-aarch64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(linux-aarch64)
endif()
if (DEFINED ARTIFACT_DIR)
include(${ARTIFACT_DIR}/${ARTIFACT_CMAKE}.cmake)
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_NAMES ${ARTIFACT_NAME})
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_URLS "https://github.com/${ARTIFACT_REPO}") # TODO(crueter) other hosts?
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_SHAS ${ARTIFACT_VERSION})
set(${ARTIFACT_PACKAGE}_ADDED TRUE PARENT_SCOPE)
else()
find_package(${ARTIFACT_PACKAGE} ${ARTIFACT_MIN_VERSION} REQUIRED)
endif()
endfunction()

View file

@ -29,6 +29,7 @@ function(download_bundled_external remote_path lib_name cpm_key prefix_var versi
set(package_url "${package_base_url}${package_repo}")
set(full_url ${package_url}${remote_path}${lib_name}${package_extension})
# TODO(crueter): DELETE THIS ENTIRELY, GLORY BE TO THE CI!
AddPackage(
NAME ${cpm_key}
VERSION ${version}
@ -49,9 +50,6 @@ function(download_win_archives)
download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "ffmpeg-bundled" "" 7.1.1)
# TODO(crueter): separate handling for arm64
set(SDL2_VER "SDL2-2.32.8")
download_bundled_external("sdl2/" ${SDL2_VER} "sdl2-bundled" "" 2.32.8)
set(FORCE_WIN_ARCHIVES OFF)
endfunction()

View file

@ -0,0 +1,19 @@
# 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 (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()

View file

@ -3,17 +3,12 @@
include(FindPackageHandleStandardArgs)
find_package(zstd QUIET CONFIG)
if (zstd_CONSIDERED_CONFIGS)
find_package_handle_standard_args(zstd CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
pkg_search_module(ZSTD QUIET IMPORTED_TARGET libzstd)
find_package_handle_standard_args(zstd
REQUIRED_VARS ZSTD_LINK_LIBRARIES
VERSION_VAR ZSTD_VERSION
)
endif()
find_package(PkgConfig QUIET)
pkg_search_module(ZSTD QUIET IMPORTED_TARGET libzstd)
find_package_handle_standard_args(zstd
REQUIRED_VARS ZSTD_LINK_LIBRARIES
VERSION_VAR ZSTD_VERSION
)
if (zstd_FOUND AND NOT TARGET zstd::zstd)
if (TARGET zstd::libzstd_shared)

View file

@ -51,6 +51,7 @@ Check out our [website](https://eden-emu.dev) for the latest news on exciting fe
## Development
Most of the development happens on our Git server. It is also where [our central repository](https://git.eden-emu.dev/eden-emu/eden) is hosted. For development discussions, please join us on [Discord](https://discord.gg/kXAmGCXBGD) or [Revolt](https://rvlt.gg/qKgFEAbH).
You can also follow us on [X (Twitter)](https://x.com/edenemuofficial) for updates and announcements.
If you would like to contribute, we are open to new developers and pull requests. Please ensure that your work is of a high standard and properly documented. You can also contact any of the developers on Discord or Revolt to learn more about the current state of the emulator.

147
cpmfile.json Normal file
View file

@ -0,0 +1,147 @@
{
"openssl": {
"ci": true,
"package": "OpenSSL",
"name": "openssl",
"repo": "crueter-ci/OpenSSL",
"version": "3.5.2",
"min_version": "1.1.1"
},
"boost": {
"package": "Boost",
"repo": "boostorg/boost",
"tag": "boost-1.88.0",
"artifact": "boost-1.88.0-cmake.7z",
"hash": "e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01",
"git_version": "1.88.0",
"version": "1.57"
},
"fmt": {
"repo": "fmtlib/fmt",
"sha": "40626af88b",
"hash": "d59f06c24339f223de4ec2afeba1c67b5835a0f350a1ffa86242a72fc3e616a6b8b21798355428d4200c75287308b66634619ffa0b52ba5bd74cc01772ea1a8a",
"version": "8",
"options": [
"FMT_INSTALL OFF"
]
},
"lz4": {
"name": "lz4",
"repo": "lz4/lz4",
"sha": "ebb370ca83",
"hash": "43600e87b35256005c0f2498fa56a77de6783937ba4cfce38c099f27c03188d097863e8a50c5779ca0a7c63c29c4f7ed0ae526ec798c1fd2e3736861b62e0a37",
"source_subdir": "build/cmake"
},
"nlohmann": {
"package": "nlohmann_json",
"repo": "nlohmann/json",
"sha": "55f93686c0",
"hash": "b739749b066800e21154506ea150d2c5cbce8a45344177f46f884547a1399d26753166fd0df8135269ce28cf223552b1b65cd625b88c844d54753f2434900486",
"version": "3.8"
},
"zlib": {
"package": "ZLIB",
"repo": "madler/zlib",
"sha": "51b7f2abda",
"hash": "16eaf1f3752489d12fd9ce30f7b5f7cbd5cb8ff53d617005a9847ae72d937f65e01e68be747f62d7ac19fd0c9aeba9956e60f16d6b465c5fdc2f3d08b4db2e6c",
"version": "1.2",
"options": [
"ZLIB_BUILD_SHARED OFF",
"ZLIB_INSTALL OFF"
]
},
"zstd": {
"repo": "facebook/zstd",
"sha": "f8745da6ff",
"hash": "3037007f990040fe32573b46f9bef8762fd5dbeeb07ffffcbfeba51ec98167edae39bb9c87f9299efcd61c4e467c5e84f7c19f0df7799bc1fc04864a278792ee",
"version": "1.5",
"source_subdir": "build/cmake",
"find_args": "MODULE",
"options": [
"ZSTD_BUILD_SHARED OFF"
]
},
"catch2": {
"package": "Catch2",
"repo": "catchorg/Catch2",
"sha": "644821ce28",
"hash": "f8795f98acf2c02c0db8e734cc866d5caebab4b4a306e93598b97cb3c0c728dafe8283dce27ffe8d42460e5ae7302f3f32e7e274a7f991b73511ac88eef21b1f",
"version": "3.0.1"
},
"enet": {
"repo": "lsalzman/enet",
"sha": "2662c0de09",
"hash": "3de1beb4fa3d6b1e03eda8dd1e7580694f854af3ed3975dcdabfdcdf76b97f322b9734d35ea7f185855bb490d957842b938b26da4dd2dfded509390f8d2794dd",
"version": "1.3",
"find_args": "MODULE"
},
"opus": {
"package": "Opus",
"repo": "xiph/opus",
"sha": "5ded705cf4",
"hash": "0dc89e58ddda1f3bc6a7037963994770c5806c10e66f5cc55c59286fc76d0544fe4eca7626772b888fd719f434bc8a92f792bdb350c807968b2ac14cfc04b203",
"version": "1.3",
"find_args": "MODULE",
"options": [
"OPUS_BUILD_TESTING OFF",
"OPUS_BUILD_PROGRAMS OFF",
"OPUS_INSTALL_PKG_CONFIG_MODULE OFF",
"OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF"
]
},
"cubeb": {
"repo": "mozilla/cubeb",
"sha": "fa02160712",
"hash": "82d808356752e4064de48c8fecbe7856715ade1e76b53937116bf07129fc1cc5b3de5e4b408de3cd000187ba8dc32ca4109661cb7e0355a52e54bd81b9be1c61",
"find_args": "CONFIG",
"options": [
"USE_SANITIZERS OFF",
"BUILD_TESTS OFF",
"BUILD_TOOLS OFF",
"BUNDLE_SPEEX ON"
]
},
"boost_headers": {
"repo": "boostorg/headers",
"sha": "0456900fad",
"hash": "50cd75dcdfc5f082225cdace058f47b4fb114a47585f7aee1d22236a910a80b667186254c214fa2fcebac67ae6d37ba4b6e695e1faea8affd6fd42a03cf996e3",
"bundled": true
},
"discord-rpc": {
"repo": "eden-emulator/discord-rpc",
"sha": "1cf7772bb6",
"hash": "e9b35e6f2c075823257bcd59f06fe7bb2ccce1976f44818d2e28810435ef79c712a3c4f20f40da41f691342a4058cf86b078eb7f9d9e4dae83c0547c21ec4f97"
},
"simpleini": {
"package": "SimpleIni",
"repo": "brofield/simpleini",
"sha": "09c21bda1d",
"hash": "99779ca9b6e040d36558cadf484f9ffdab5b47bcc8fc72e4d33639d1d60c0ceb4410d335ba445d72a4324e455167fd6769d99b459943aa135bec085dff2d4b7c",
"find_args": "MODULE"
},
"sdl2_generic": {
"package": "SDL2",
"repo": "libsdl-org/SDL",
"sha": "54772f345a",
"hash": "2a68a0e01c390043aa9d9df63d8a20a52076c88bb460ac4e0f33194ca7d9bc8fadbbcc04e7506872ac4b6354a73fbc267c036f82200da59465789b87c7d9e3a4",
"key": "generic",
"bundled": true
},
"sdl2_steamdeck": {
"package": "SDL2",
"repo": "libsdl-org/SDL",
"sha": "cc016b0046",
"hash": "34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b",
"key": "steamdeck",
"bundled": true
},
"sdl2": {
"ci": true,
"package": "SDL2",
"name": "SDL2",
"repo": "crueter-ci/SDL2",
"version": "2.32.8",
"min_version": "2.26.4",
"cmake_filename": "sdl2"
}
}

View file

@ -95,6 +95,60 @@ QPushButton#button_reset_defaults {
padding: 4px 8px;
}
/* QGroupBox --------------------------------------------------------------
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox
--------------------------------------------------------------------------- */
QGroupBox {
border: 1px solid #32414B;
border-radius: 4px;
margin-top: 20px;
padding: 2px;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top left;
padding-left: 3px;
padding-right: 5px;
padding-top: 2px;
}
QGroupBox::indicator {
margin-left: 2px;
height: 16px;
width: 16px;
}
QGroupBox::indicator:unchecked {
border: none;
image: url(":/qss_icons/rc/checkbox_unchecked.png");
}
QGroupBox::indicator:unchecked:hover, QGroupBox::indicator:unchecked:focus, QGroupBox::indicator:unchecked:pressed {
border: none;
image: url(":/qss_icons/rc/checkbox_unchecked_focus.png");
}
QGroupBox::indicator:unchecked:disabled {
image: url(":/qss_icons/rc/checkbox_unchecked_disabled.png");
}
QGroupBox::indicator:checked {
border: none;
image: url(":/qss_icons/rc/checkbox_checked.png");
}
QGroupBox::indicator:checked:hover, QGroupBox::indicator:checked:focus, QGroupBox::indicator:checked:pressed {
border: none;
image: url(":/qss_icons/rc/checkbox_checked_focus.png");
}
QGroupBox::indicator:checked:disabled {
image: url(":/qss_icons/rc/checkbox_checked_disabled.png");
}
QWidget#bottomPerGameInput,
QWidget#topControllerApplet,
QWidget#bottomControllerApplet,

View file

@ -697,3 +697,29 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
image: url(:/overlay/osk_button_Y_disabled.png);
}
/* QGroupBox --------------------------------------------------------------
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox
--------------------------------------------------------------------------- */
QGroupBox {
border: 1px solid #32414B;
border-radius: 4px;
margin-top: 22px;
padding: 2px;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top left;
padding-left: 10px;
padding-right: 10px;
padding-top: 2px;
}
QGroupBox::indicator {
margin-left: 2px;
height: 16px;
width: 16px;
}

View file

@ -307,7 +307,7 @@ QAbstractItemView QLineEdit {
QGroupBox {
border: 1px solid #54575B;
border-radius: 2px;
margin-top: 12px;
margin-top: 20px;
padding-top: 2px;
}

View file

@ -235,10 +235,9 @@ https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox
--------------------------------------------------------------------------- */
QGroupBox {
font-weight: bold;
border: 1px solid #32414B;
border-radius: 4px;
margin-top: 12px;
margin-top: 20px;
padding: 2px;
}

252
docs/CPM.md Normal file
View file

@ -0,0 +1,252 @@
# CPM
CPM (CMake Package Manager) is the preferred method of managing dependencies within Eden.
Global Options:
- `YUZU_USE_CPM` is set by default on MSVC and Android. Other platforms should use this if certain "required" system dependencies (e.g. OpenSSL) are broken or missing
* If this is `OFF`, required system dependencies will be searched via `find_package`, although certain externals use CPM regardless.
- `CPMUTIL_FORCE_SYSTEM` (default `OFF`): Require all CPM dependencies to use system packages. NOT RECOMMENDED!
* Many packages, e.g. mcl, sirit, xbyak, discord-rpc, are not generally available as a system package.
* You may optionally override these (see CPMUtil section)
- `CPMUTIL_FORCE_BUNDLED` (default `ON` on MSVC and Android, `OFF` elsewhere): Require all CPM dependencies to use bundled packages.
## CPMUtil
CPMUtil is a wrapper around CPM that aims to reduce boilerplate and add useful utility functions to make dependency management a piece of cake.
### AddPackage
`AddPackage` is the core of the CPMUtil wrapper, and is generally the lowest level you will need to go when dealing with dependencies.
**Identification/Fetching**
- `NAME` (required): The package name (must be the same as the `find_package` name if applicable)
- `VERSION`: The minimum version of this package that can be used on the system
- `GIT_VERSION`: The version found within git, only used for identification
- `URL`: The URL to fetch.
- `REPO`: The GitHub repo to use (`owner/repo`).
* Only GitHub is supported for now, though other platforms will see support at some point
- `TAG`: The tag to fetch, if applicable.
- `ARTIFACT`: The name of the artifact, if applicable.
- `SHA`: Commit sha to fetch, if applicable.
- `BRANCH`: Branch to fetch, if applicable.
The following configurations are supported, in descending order of precedence:
- `URL`: Bare URL download, useful for custom artifacts
* If this is set, `GIT_URL` or `REPO` should be set to allow the dependency viewer to link to the project's Git repository.
* If this is NOT set, `REPO` must be defined.
- `REPO + TAG + ARTIFACT`: GitHub release artifact
* The final download URL will be `https://github.com/${REPO}/releases/download/${TAG}/${ARTIFACT}`
* Useful for prebuilt libraries and prefetched archives
- `REPO + TAG`: GitHub tag archive
* The final download URL will be `https://github.com/${REPO}/archive/refs/tags/${TAG}.tar.gz`
* Useful for pinning to a specific tag, better for build identification
- `REPO + SHA`: GitHub commit archive
* The final download URL will be `https://github.com/${REPO}/archive/${SHA}.zip`
* Useful for pinning to a specific commit
- `REPO + BRANCH`: GitHub branch archive
* The final download URL will be `https://github.com/${REPO}/archive/refs/heads/${BRANCH}.zip`
* Generally not recommended unless the branch is frozen
- `REPO`: GitHub master archive
* The final download URL will be `https://github.com/${REPO}/archive/refs/heads/master.zip`
* Generally not recommended unless the project is dead
**Hashing**
Hashing is used for verifying downloads. It's highly recommended to use these.
- `HASH_ALGO` (default `SHA512`): Hash algorithm to use
Hashing strategies, descending order of precedence:
- `HASH`: Bare hash verification, useful for static downloads e.g. commit archives
- `HASH_SUFFIX`: Download the hash as `${DOWNLOAD_URL}.${HASH_SUFFIX}`
* The downloaded hash *must* match the hash algorithm and contain nothing but the hash; no filenames or extra content.
- `HASH_URL`: Download the hash from a separate URL
**Additional Options**
- `KEY`: Custom cache key to use (stored as `.cache/cpm/${packagename_lower}/${key}`)
* Default is based on, in descending order of precedence:
- First 4 characters of the sha
- `GIT_VERSION`, or `VERSION` if not specified
- Tag
- Otherwise, CPM defaults will be used. This is not recommended as it doesn't produce reproducible caches
- `DOWNLOAD_ONLY`: Whether or not to configure the downloaded package via CMake
* Useful to turn `OFF` if the project doesn't use CMake
- `SOURCE_SUBDIR`: Subdirectory of the project containing a CMakeLists.txt file
- `FIND_PACKAGE_ARGUMENTS`: Arguments to pass to the `find_package` call
- `BUNDLED_PACKAGE`: Set to `ON` to force the usage of a bundled package
- `OPTIONS`: Options to pass to the configuration of the package
- `PATCHES`: Patches to apply to the package, stored in `.patch/${packagename_lower}/0001-patch-name.patch` and so on
- Other arguments can be passed to CPM as well
**Extra Variables**
For each added package, users may additionally force usage of the system/bundled package.
- `${package}_FORCE_SYSTEM`: Require the package to be installed on the system
- `${package}_FORCE_BUNDLED`: Force the package to be fetched and use the bundled version
**Bundled/System Switching**
Descending order of precedence:
- If `${package}_FORCE_SYSTEM` is true, requires the package to be on the system
- If `${package}_FORCE_BUNDLED` is true, forcefully uses the bundled package
- If `CPMUTIL_FORCE_SYSTEM` is true, requires the package to be on the system
- If `CPMUTIL_FORCE_BUNDLED` is true, forcefully uses the bundled package
- If the `BUNDLED_PACKAGE` argument is true, forcefully uses the bundled package
- Otherwise, CPM will search for the package first, and if not found, will use the bundled package
**Identification**
All dependencies must be identifiable in some way for usage in the dependency viewer. Lists are provided in descending order of precedence.
URLs:
- `GIT_URL`
- `REPO` as a GitHub repository
- `URL`
Versions (bundled):
- `SHA`
- `GIT_VERSION`
- `VERSION`
- `TAG`
- "unknown"
If the package is a system package, AddPackage will attempt to determine the package version and append ` (system)` to the identifier. Otherwise, it will be marked as `unknown (system)`
### AddCIPackage
Adds a package that follows crueter's CI repository spec.
- `VERSION` (required): The version to get (the tag will be `v${VERSION}`)
- `NAME` (required): Name used within the artifacts
- `REPO` (required): CI repository, e.g. `crueter-ci/OpenSSL`
- `PACKAGE` (required): `find_package` package name
- `EXTENSION`: Artifact extension (default `tar.zst`)
- `MIN_VERSION`: Minimum version for `find_package`. Only used if platform does not support this package as a bundled artifact
- `DISABLED_PLATFORMS`: List of platforms that lack artifacts for this package. One of:
* `windows-amd64`
* `windows-arm64`
* `android`
* `solaris`
* `freebsd`
* `linux`
* `linux-aarch64`
- `CMAKE_FILENAME`: Custom CMake filename, relative to the package root (default `${PACKAGE_ROOT}/${NAME}.cmake`)
### AddJsonPackage
This is the recommended method of usage for CPMUtil. In each directory that utilizes `CPMUtil`, there must be a `cpmfile.json` that defines dependencies in a similar manner to the individual calls.
The cpmfile is an object of objects, with each sub-object being named according to the package's identifier, e.g. `openssl`, which can then be fetched with `AddJsonPackage(<identifier>)`. Options are designed to map closely to the argument names, and are always strings unless otherwise specified.
- `package` -> `NAME` (`PACKAGE` for CI), defaults to the object key
- `repo` -> `REPO`
- `version` -> `VERSION`
- `ci` (bool)
If `ci` is `false`:
- `hash` -> `HASH`
- `sha` -> `SHA`
- `tag` -> `TAG`
- `artifact` -> `ARTIFACT`
- `git_version` -> `GIT_VERSION`
- `source_subdir` -> `SOURCE_SUBDIR`
- `bundled` -> `BUNDLED_PACKAGE`
- `find_args` -> `FIND_PACKAGE_ARGUMENTS`
- `patches` -> `PATCHES` (array)
- `options` -> `OPTIONS` (array)
Other arguments aren't currently supported. If you wish to add them, see the `AddJsonPackage` function in `CMakeModules/CPMUtil.cmake`.
If `ci` is `true`:
- `name` -> `NAME`, defaults to the object key
- `extension` -> `EXTENSION`, defaults to `tar.zst`
- `min_version` -> `MIN_VERSION`
- `cmake_filename` -> `CMAKE_FILENAME`
- `extension` -> `EXTENSION`
### Examples
In order: OpenSSL CI, Boost (tag + artifact), discord-rpc (sha + options + patches), Opus (options + find_args)
```json
{
"openssl": {
"ci": true,
"package": "OpenSSL",
"name": "openssl",
"repo": "crueter-ci/OpenSSL",
"version": "3.5.2",
"min_version": "1.1.1"
},
"boost": {
"package": "Boost",
"repo": "boostorg/boost",
"tag": "boost-1.88.0",
"artifact": "boost-1.88.0-cmake.7z",
"hash": "e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01",
"git_version": "1.88.0",
"version": "1.57"
},
"opus": {
"package": "Opus",
"repo": "xiph/opus",
"sha": "5ded705cf4",
"hash": "0dc89e58ddda1f3bc6a7037963994770c5806c10e66f5cc55c59286fc76d0544fe4eca7626772b888fd719f434bc8a92f792bdb350c807968b2ac14cfc04b203",
"version": "1.3",
"find_args": "MODULE",
"options": [
"OPUS_BUILD_TESTING OFF",
"OPUS_BUILD_PROGRAMS OFF",
"OPUS_INSTALL_PKG_CONFIG_MODULE OFF",
"OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF"
]
},
"discord-rpc": {
"repo": "discord/discord-rpc",
"sha": "963aa9f3e5",
"hash": "386e1344e9a666d730f2d335ee3aef1fd05b1039febefd51aa751b705009cc764411397f3ca08dffd46205c72f75b235c870c737b2091a4ed0c3b061f5919bde",
"options": [
"BUILD_EXAMPLES OFF"
],
"patches": [
"0001-cmake-version.patch",
"0002-no-clang-format.patch",
"0003-fix-cpp17.patch"
]
},
}
```
### Inclusion
To include CPMUtil:
```cmake
set(CPMUTIL_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json)
include(CPMUtil)
```
You may omit the first line if you are not utilizing cpmfile.
## Prefetching
- To prefetch a CPM dependency (requires cpmfile):
* `tools/cpm-fetch.sh <packages>`
- To prefetch all CPM dependencies:
* `tools/cpm-fetch-all.sh`
Currently, `cpm-fetch.sh` defines the following directories for cpmfiles:
`externals src/yuzu/externals externals/ffmpeg src/dynarmic/externals externals/nx_tzdb`
Whenever you add a new cpmfile, update the script accordingly

View file

@ -1,12 +1,22 @@
# Development
* **Windows**: [Windows Building Guide](./docs/build/Windows.md)
* **Linux**: [Linux Building Guide](./docs/build/Linux.md)
* **Android**: [Android Building Guide](./docs/build/Android.md)
* **Solaris**: [Solaris Building Guide](./docs/build/Solaris.md)
* **FreeBSD**: [FreeBSD Building Guide](./docs/build/FreeBSD.md)
* **macOS**: [macOS Building Guide](./docs/build/macOS.md)
* **Windows**: [Windows Building Guide](./build/Windows.md)
* **Linux**: [Linux Building Guide](./build/Linux.md)
* **Android**: [Android Building Guide](./build/Android.md)
* **Solaris**: [Solaris Building Guide](./build/Solaris.md)
* **FreeBSD**: [FreeBSD Building Guide](./build/FreeBSD.md)
* **macOS**: [macOS Building Guide](./build/macOS.md)
# CPM
CPM (CMake Package Manager) is the preferred method of managing dependencies within Eden. Documentation on adding dependencies/using CPMUtil is in the works.
Notes:
- `YUZU_USE_CPM` is set by default on MSVC and Android. Other platforms should use this if certain "required" system dependencies (e.g. OpenSSL) are broken or missing
- `CPMUTIL_DEFAULT_SYSTEM` can be set to `OFF` to force the usage of bundled dependencies. This can marginally decrease the final package size.
- When adding new prebuilt dependencies a la OpenSSL, SDL2, or FFmpeg, there *must* be a CMake option made available to forcefully download this bundle. See the OpenSSL implementation in the root CMakeLists for an example.
* This is necessary to allow for creation of fully-qualified source packs that allow for offline builds after download (some package managers and distros enforce this)
# Guidelines
## License Headers
@ -76,9 +86,16 @@ cmake --build /tmp/ramdisk -- -j32
sudo umount /tmp/ramdisk
```
# How to test JIT
## Debugging (host code)
## gdb
Ignoring SIGSEGV when debugging in host:
- **gdb**: `handle all nostop pass`.
- **lldb**: `pro hand -p true -s false -n false SIGSEGV`.
## Debugging (guest code)
### gdb
Run `./build/bin/eden-cli -c <path to your config file (see logs where you run eden normally to see where it is)> -d -g <path to game>`
@ -87,7 +104,7 @@ Then type `target remote localhost:1234` and type `c` (for continue) - and then
### gdb cheatsheet
- `mo <cmd>`: Monitor commands, `get info`, `get fastmem` and `get mappings` are available.
- `mo <cmd>`: Monitor commands, `get info`, `get fastmem` and `get mappings` are available. Type `mo help` for more info.
- `detach`: Detach from remote (i.e restarting the emulator).
- `c`: Continue
- `p <expr>`: Print variable, `p/x <expr>` for hexadecimal.
@ -110,7 +127,7 @@ Expressions can be `variable_names` or `1234` (numbers) or `*var` (dereference o
For more information type `info gdb` and read [the man page](https://man7.org/linux/man-pages/man1/gdb.1.html).
## Bisecting older commits
# Bisecting older commits
Since going into the past can be tricky (especially due to the dependencies from the project being lost thru time). This should "restore" the URLs for the respective submodules.

14
docs/build/FreeBSD.md vendored
View file

@ -1,12 +1,13 @@
## One word of caution before proceeding.
This is not the usual or preferred way to build programs on FreeBSD.
As of writing there is no official fresh port available for eden-emu, but it is in the works.
After it is available you can find a link to the eden-emu fresh port here and on Escarys github repo.
See this build as an App Image alternative for FreeBSD.
As of writing there is no official fresh port available for Eden, but it is in the works.
After it is available you can find a link to the eden-emu fresh port here and on Escary's github repo.
See this build as an AppImage alternative for FreeBSD.
## Dependencies.
Before we start we need some dependencies.
These dependencies are generally needed to build eden-emu on FreeBSD.
These dependencies are generally needed to build Eden on FreeBSD.
```
devel/cmake
@ -56,8 +57,6 @@ Change into that build directory:
cd build
```
Now choose one option either 1 or 2, but not both as one option overwrites the other.
#### 1. Building in Release Mode (usually preferred and the most performant choice):
```sh
cmake .. -GNinja -DYUZU_TESTS=OFF
@ -81,3 +80,6 @@ OR
```sh
doas -- ninja install
```
## OpenSSL
The available OpenSSL port (3.0.17) is out-of-date, and using a bundled static library instead is recommended; to do so, add `-DYUZU_USE_CPM=ON` to your CMake configure command.

15
docs/build/Linux.md vendored
View file

@ -10,31 +10,34 @@ The following are handled by Eden's externals:
* [FFmpeg](https://ffmpeg.org/)
* [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+
* [opus](https://opus-codec.org/downloads/)
* [opus](https://opus-codec.org/downloads/) 1.3+
All other dependencies will be downloaded by [vcpkg](https://vcpkg.io/) if needed:
All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available:
* [Boost](https://www.boost.org/users/download/) 1.79.0+
* [Catch2](https://github.com/catchorg/Catch2) 2.13.7 - 2.13.9
* [fmt](https://fmt.dev/) 8.0.1+
* [lz4](http://www.lz4.org) 1.8+
* [nlohmann_json](https://github.com/nlohmann/json) 3.8+
* [OpenSSL](https://www.openssl.org/source/)
* [OpenSSL](https://www.openssl.org/source/) 1.1.1+
* [ZLIB](https://www.zlib.net/) 1.2+
* [zstd](https://facebook.github.io/zstd/) 1.5+
* [enet](http://enet.bespin.org/) 1.3+
* [cubeb](https://github.com/mozilla/cubeb)
* [SimpleIni](https://github.com/brofield/simpleini)
If an ARM64 build is intended, export `VCPKG_FORCE_SYSTEM_BINARIES=1`.
Certain other dependencies (httplib, jwt, sirit, etc.) will be fetched by CPM regardless. System packages *can* be used for these libraries but this is generally not recommended.
Dependencies are listed here as commands that can be copied/pasted. Of course, they should be inspected before being run.
- Arch / Manjaro:
- `sudo pacman -Syu --needed base-devel boost catch2 cmake ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip`
- `sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip`
- Building with QT Web Engine requires `qt6-webengine` as well.
- Proper wayland support requires `qt6-wayland`
- GCC 11 or later is required.
- Ubuntu / Linux Mint / Debian:
- `sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev`
- `sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev`
- Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required.
- Users need to manually specify building with QT Web Engine enabled. This is done using the parameter `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake.
- Users need to manually disable building SDL2 from externals if they intend to use the version provided by their system by adding the parameters `-DYUZU_USE_EXTERNAL_SDL2=OFF`

76
docs/build/Solaris.md vendored
View file

@ -8,73 +8,12 @@ Run the usual update + install of essential toolings: `sudo pkg update && sudo p
- **gcc**: `sudo pkg install developer/gcc-14`.
- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`.
Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm`.
fmtlib is not available on repositories and has to be manually built:
```sh
git clone --recurisve --depth=1 https://github.com/fmtlib/fmt.git
cd fmt
cmake -DCMAKE_BUILD_TYPE=Release -B build
cmake --build build
sudo cmake --install build
```
pkg lz4 doesn't provide a proper CMakeFile to find the library, has to also be manually built:
```sh
git clone --depth=1 https://github.com/lz4/lz4.git
cd lz4
gmake
sudo gmake install
```
Same goes for zstd:
```sh
git clone --depth=1 https://github.com/facebook/zstd.git
cd zstd
cmake -DCMAKE_BUILD_TYPE=Release -B build0 -S build/cmake
cmake --build build0
cd build0
sudo gmake install
```
pkg SDL2 is also not nice to work with on CMake, save yourself some pain and compile it yourself:
```sh
git clone --depth=1 --branch=release-2.32.8 https://github.com/libsdl-org/SDL
cmake -DCMAKE_BUILD_TYPE=Release -B build
cmake --build build
sudo cmake --install build
```
Audio is broken in OpenIndiana [see this issue](https://github.com/libsdl-org/SDL/issues/13405), go into `SDL/CMakeLists.txt` and comment out lines 1468:
```diff
+# set(SDL_AUDIO_DRIVER_SUNAUDIO 1)
+# file(GLOB SUN_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/sun/*.c)
+# list(APPEND SOURCE_FILES ${SUN_AUDIO_SOURCES})
+# set(HAVE_SDL_AUDIO TRUE)
```
For Solaris this issue does not exist - however PulseAudio crashes on Solaris - so use a different backend.
---
### Build preparations:
Run the following command to clone eden with git:
```sh
git clone --recursive https://git.eden-emu.dev/eden-emu/eden
```
You usually want to add the `--recursive` parameter as it also takes care of the external dependencies for you.
Now change into the eden directory and create a build directory there:
```sh
cd eden
mkdir build
```
Change into that build directory: `cd build`
Now choose one option either 1 or 2, but not both as one option overwrites the other.
Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`.
### Building
Clone eden with git `git clone --recursive https://git.eden-emu.dev/eden-emu/eden`
```sh
# Needed for some dependencies that call cc directly (tz)
echo '#!/bin/sh' >cc
@ -83,7 +22,12 @@ chmod +x cc
export PATH="$PATH:$PWD"
```
- **Configure**: `cmake -B build -DYUZU_TESTS=OFF -DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF -DYUZU_USE_LLVM_DEMANGLE=OFF -DYUZU_USE_QT_MULTIMEDIA=OFF -DYUZU_USE_QT_WEB_ENGINE=OFF -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_USE_BUNDLED_QT=OFF -DENABLE_QT=OFF -DSDL_AUDIO=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_QT_UPDATE_CHECKER=OFF`.
Patch for FFmpeg:
```sh
sed -i 's/ make / gmake /' externals/ffmpeg/CMakeFiles/ffmpeg-build.dir/build.make
```
- **Configure**: `cmake -B build -DYUZU_USE_CPM=ON -DCMAKE_CXX_FLAGS="-I/usr/include/SDL2" -DCMAKE_C_FLAGS="-I/usr/include/SDL2"`.
- **Build**: `cmake --build build`.
- **Installing**: `sudo cmake --install build`.
@ -104,4 +48,4 @@ export LIBGL_ALWAYS_SOFTWARE=1
- Modify the generated ffmpeg.make (in build dir) if using multiple threads (base system `make` doesn't use `-j4`, so change for `gmake`).
- If using OpenIndiana, due to a bug in SDL2 cmake configuration; Audio driver defaults to SunOS `<sys/audioio.h>`, which does not exist on OpenIndiana.
- Enabling OpenSSL requires compiling OpenSSL manually instead of using the provided one from repositores.
- System OpenSSL generally does not work. Instead, use `-DYUZU_USE_CPM=ON` to use a bundled static OpenSSL, or build a system dependency from source.

View file

@ -10,7 +10,6 @@ On Windows, all library dependencies are automatically included within the `exte
* **[CMake](https://cmake.org/download/)** - Used to generate Visual Studio project files. Does not matter if either 32-bit or 64-bit version is installed.
* **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** - **Make sure to select Latest SDK.**
- A convenience script to install the latest SDK is provided in `.ci\windows\install-vulkan-sdk.ps1`.
* **[OpenSSL](https://slproweb.com/products/Win32OpenSSL.html)** - You are recommended to keep the default install location, otherwise you will have to specify a custom OpenSSL root.
![2](https://i.imgur.com/giDwuTm.png)
@ -48,8 +47,6 @@ On Windows, all library dependencies are automatically included within the `exte
* *(Note: If you used GitHub's own app to clone, run `git submodule update --init --recursive` to get the remaining dependencies)*
* If you get an error about missing packages, enable `YUZU_USE_BUNDLED_VCPKG`, and then click Configure again.
* *(You may also want to disable `YUZU_TESTS` in this case since Catch2 is not yet supported with this.)*
![13](https://user-images.githubusercontent.com/22451773/180585999-07316d6e-9751-4d11-b957-1cf57cd7cd58.png)
@ -100,7 +97,7 @@ On Windows, all library dependencies are automatically included within the `exte
```bash
mkdir build && cd build
cmake -G "MSYS Makefiles" -DYUZU_USE_BUNDLED_VCPKG=ON -DYUZU_TESTS=OFF ..
cmake -G "MSYS Makefiles" -DYUZU_TESTS=OFF ..
make -j$(nproc)
# test eden out with
./bin/eden.exe

View file

@ -7,7 +7,8 @@
# TODO(crueter): A lot of this should be moved to the root.
# otherwise we have to do weird shenanigans with library linking and stuff
# cpm
# Explicitly include CPMUtil here since we have a separate cpmfile for externals
set(CPMUTIL_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json)
include(CPMUtil)
# Explicitly declare this option here to propagate to the oaknut CPM call
@ -32,34 +33,17 @@ endif()
# Xbyak (also used by Dynarmic, so needs to be added first)
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
# Fix regset.h collisions
set(XBYAK_HASH 51f507b0b3)
set(XBYAK_SHA512SUM 4a29a3c2f97f7d5adf667a21a008be03c951fb6696b0d7ba27e7e4afa037bc76eb5e059bb84860e01baf741d4d3ac851b840cd54c99d038812fbe0f1fa6d38a4)
if (PLATFORM_SUN)
AddJsonPackage(xbyak_sun)
else()
set(XBYAK_HASH 4e44f4614d)
set(XBYAK_SHA512SUM 5824e92159e07fa36a774aedd3b3ef3541d0241371d522cffa4ab3e1f215fa5097b1b77865b47b2481376c704fa079875557ea463ca63d0a7fd6a8a20a589e70)
AddJsonPackage(xbyak)
endif()
AddPackage(
NAME xbyak
REPO "Lizzie841/xbyak"
SHA ${XBYAK_HASH}
HASH ${XBYAK_SHA512SUM}
BUNDLED_PACKAGE ON
)
endif()
# Oaknut (also used by Dynarmic, so needs to be added first)
if (ARCHITECTURE_arm64 OR DYNARMIC_TESTS)
AddPackage(
NAME oaknut
VERSION 2.0.1
REPO "merryhime/oaknut"
SHA 94c726ce03
HASH d8d082242fa1881abce3c82f8dafa002c4e561e66a69e7fc038af67faa5eff2630f082d3d19579c88c4c9f9488e54552accc8cb90e7ce743efe043b6230c08ac
)
endif()
AddJsonPackage(oaknut)
endif()
# getopt
if (MSVC)
@ -70,15 +54,7 @@ endif()
add_subdirectory(glad)
# mbedtls
# TODO(crueter): test local mbedtls
AddPackage(
NAME mbedtls
REPO "Mbed-TLS/mbedtls"
SHA "8c88150ca1"
HASH 769ad1e94c570671071e1f2a5c0f1027e0bf6bcdd1a80ea8ac970f2c86bc45ce4e31aa88d6d8110fc1bed1de81c48bc624df1b38a26f8b340a44e109d784a966
PATCHES
${CMAKE_SOURCE_DIR}/.patch/mbedtls/0001-cmake-version.patch
)
AddJsonPackage(mbedtls)
if (mbedtls_ADDED)
target_include_directories(mbedtls PUBLIC ${mbedtls_SOURCE_DIR}/include)
@ -95,179 +71,39 @@ if (ENABLE_LIBUSB AND NOT TARGET libusb::usb)
add_subdirectory(libusb)
endif()
# SDL2
if (NOT YUZU_USE_BUNDLED_SDL2)
if (NOT WIN32)
# Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers
# Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095)
# Yuzu-cmd also needs: Video (depends on Loadso/Dlopen)
# CPUinfo also required for SDL Audio, at least until 2.28.0 (see https://github.com/libsdl-org/SDL/issues/7809)
set(SDL_UNUSED_SUBSYSTEMS
File Filesystem
Locale Power Render)
foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT)
set(SDL_${_OPT} OFF)
endforeach()
set(HIDAPI ON)
endif()
if (APPLE)
set(SDL_FILE ON)
endif()
if ("${YUZU_SYSTEM_PROFILE}" STREQUAL "steamdeck")
set(SDL_HASH cc016b0046)
set(SDL_PIPEWIRE OFF) # build errors out with this on
set(SDL_SHA512SUM 34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b)
elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
set(SDL_HASH d310b5679f)
set(SDL_SHA512SUM cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e)
else()
set(SDL_HASH 2e4c12cd2c)
set(SDL_SHA512SUM d95af47f469a312876f8ab361074a1e7b8083db19935a102d9c6e5887ace6008e64475a8c54b00164b40cad86492bb1b2366084efdd0b2555e5fea6d9c5da80e)
endif()
AddPackage(
NAME SDL2
REPO "libsdl-org/SDL"
SHA ${SDL_HASH}
HASH ${SDL_SHA512SUM}
KEY ${YUZU_SYSTEM_PROFILE}
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_SDL2}
)
endif()
# ENet
AddPackage(
NAME enet
REPO lsalzman/enet
SHA 2662c0de09
VERSION 1.3
HASH 3de1beb4fa3d6b1e03eda8dd1e7580694f854af3ed3975dcdabfdcdf76b97f322b9734d35ea7f185855bb490d957842b938b26da4dd2dfded509390f8d2794dd
FIND_PACKAGE_ARGUMENTS "MODULE"
)
if (enet_ADDED)
target_include_directories(enet INTERFACE ${enet_SOURCE_DIR}/include)
endif()
AddPackage(
NAME cubeb
REPO "mozilla/cubeb"
SHA fa02160712
HASH 82d808356752e4064de48c8fecbe7856715ade1e76b53937116bf07129fc1cc5b3de5e4b408de3cd000187ba8dc32ca4109661cb7e0355a52e54bd81b9be1c61
FIND_PACKAGE_ARGUMENTS "CONFIG" # not sure this works outside of gentoo
OPTIONS
"USE_SANITIZERS OFF"
"BUILD_TESTS OFF"
"BUILD_TOOLS OFF"
"BUNDLE_SPEEX ON"
)
if (cubeb_ADDED)
if (NOT MSVC)
if (TARGET speex)
target_compile_options(speex PRIVATE -Wno-sign-compare)
endif()
set_target_properties(cubeb PROPERTIES COMPILE_OPTIONS "")
target_compile_options(cubeb INTERFACE
-Wno-implicit-const-int-float-conversion
-Wno-shadow
-Wno-missing-declarations
-Wno-return-type
-Wno-uninitialized
)
else()
target_compile_options(cubeb PRIVATE
/wd4456
/wd4458
)
endif()
endif()
# DiscordRPC
if (USE_DISCORD_PRESENCE)
AddPackage(
NAME discord-rpc
REPO "discord/discord-rpc"
SHA 963aa9f3e5
HASH 386e1344e9a666d730f2d335ee3aef1fd05b1039febefd51aa751b705009cc764411397f3ca08dffd46205c72f75b235c870c737b2091a4ed0c3b061f5919bde
OPTIONS
"BUILD_EXAMPLES OFF"
PATCHES
${CMAKE_SOURCE_DIR}/.patch/discord-rpc/0001-cmake-version.patch
${CMAKE_SOURCE_DIR}/.patch/discord-rpc/0002-no-clang-format.patch
${CMAKE_SOURCE_DIR}/.patch/discord-rpc/0003-fix-cpp17.patch
)
target_include_directories(discord-rpc INTERFACE ${discord-rpc_SOURCE_DIR}/include)
add_library(DiscordRPC::discord-rpc ALIAS discord-rpc)
endif()
# Sirit
# TODO(crueter): spirv-tools doesn't work w/ system
AddPackage(
NAME SPIRV-Headers
REPO "KhronosGroup/SPIRV-Headers"
SHA 4e209d3d7e
HASH f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4
)
set(SPIRV_WERROR OFF)
AddJsonPackage(spirv-headers)
AddPackage(
NAME sirit
REPO "eden-emulator/sirit"
SHA db1f1e8ab5
HASH 73eb3a042848c63a10656545797e85f40d142009dfb7827384548a385e1e28e1ac72f42b25924ce530d58275f8638554281e884d72f9c7aaf4ed08690a414b05
OPTIONS
"SIRIT_USE_SYSTEM_SPIRV_HEADERS ON"
)
AddJsonPackage(sirit)
if(MSVC AND USE_CCACHE AND sirit_ADDED)
get_target_property(_opts sirit COMPILE_OPTIONS)
list(FILTER _opts EXCLUDE REGEX "/Zi")
list(APPEND _opts "/Z7")
set_target_properties(sirit PROPERTIES COMPILE_OPTIONS "${_opts}")
endif()
# httplib
if ((ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER))
AddPackage(
NAME httplib
REPO "yhirose/cpp-httplib"
SHA a609330e4c
HASH dd3fd0572f8367d8549e1319fd98368b3e75801a293b0c3ac9b4adb806473a4506a484b3d389dc5bee5acc460cb90af7a20e5df705a1696b56496b30b9ce7ed2
OPTIONS
"HTTPLIB_REQUIRE_OPENSSL ${ENABLE_OPENSSL}"
)
if (ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER)
AddJsonPackage(httplib)
endif()
# cpp-jwt
if (ENABLE_WEB_SERVICE)
AddPackage(
NAME cpp-jwt
VERSION 1.4
REPO "arun11299/cpp-jwt"
SHA a54fa08a3b
HASH a90f7e594ada0c7e49d5ff9211c71097534e7742a8e44bf0851b0362642a7271d53f5d83d04eeaae2bad17ef3f35e09e6818434d8eaefa038f3d1f7359d0969a
FIND_PACKAGE_ARGUMENTS "CONFIG"
OPTIONS
"CPP_JWT_BUILD_EXAMPLES OFF"
"CPP_JWT_BUILD_TESTS OFF"
"CPP_JWT_USE_VENDORED_NLOHMANN_JSON OFF"
PATCHES
${CMAKE_SOURCE_DIR}/.patch/cpp-jwt/0001-no-install.patch
${CMAKE_SOURCE_DIR}/.patch/cpp-jwt/0002-missing-decl.patch
)
AddJsonPackage(cpp-jwt)
endif()
# Opus
# unordered_dense
AddPackage(
NAME Opus
VERSION 1.3
REPO "xiph/opus"
SHA 5ded705cf4
HASH 0dc89e58ddda1f3bc6a7037963994770c5806c10e66f5cc55c59286fc76d0544fe4eca7626772b888fd719f434bc8a92f792bdb350c807968b2ac14cfc04b203
FIND_PACKAGE_ARGUMENTS "MODULE"
NAME unordered_dense
REPO "Lizzie841/unordered_dense"
SHA e59d30b7b1
HASH 71eff7bd9ba4b9226967bacd56a8ff000946f8813167cb5664bb01e96fb79e4e220684d824fe9c59c4d1cc98c606f13aff05b7940a1ed8ab3c95d6974ee34fa0
FIND_PACKAGE_ARGUMENTS "CONFIG"
OPTIONS
"OPUS_BUILD_TESTING OFF"
"OPUS_BUILD_PROGRAMS OFF"
"OPUS_INSTALL_PKG_CONFIG_MODULE OFF"
"OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF"
"UNORDERED_DENSE_INSTALL OFF"
)
# FFMpeg
@ -283,63 +119,33 @@ endif()
# TODO(crueter): Vk1.4 impl
AddPackage(
NAME VulkanHeaders
VERSION 1.3.274
REPO "KhronosGroup/Vulkan-Headers"
SHA 89268a6d17
HASH 3ab349f74298ba72cafb8561015690c0674d428a09fb91ccd3cd3daca83650d190d46d33fd97b0a8fd4223fe6df2bcabae89136fbbf7c0bfeb8776f9448304c8
AddJsonPackage(
NAME vulkan-headers
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_HEADERS}
)
# CMake's interface generator sucks
# if (VulkanHeaders_ADDED)
# target_include_directories(Vulkan-Headers INTERFACE ${VulkanHeaders_SOURCE_DIR}/include)
# endif()
# Vulkan-Utility-Libraries
AddPackage(
NAME VulkanUtilityLibraries
REPO "KhronosGroup/Vulkan-Utility-Libraries"
SHA df2e358152
HASH 3e468c3d9ff93f6d418d71e5527abe0a12c8c7ab5b0b52278bbbee4d02bb87e99073906729b727e0147242b7e3fd5dedf68b803f1878cb4c0e4f730bc2238d79
AddJsonPackage(
NAME vulkan-utility-libraries
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES}
)
# SPIRV-Tools
if (YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS)
AddPackage(
NAME SPIRV-Tools
REPO "KhronosGroup/SPIRV-Tools"
SHA 40eb301f32
HASH 58d0fb1047d69373cf24c73e6f78c73a72a6cca3b4df1d9f083b9dcc0962745ef154abf3dbe9b3623b835be20c6ec769431cf11733349f45e7568b3525f707aa
OPTIONS
"SPIRV_SKIP_EXECUTABLES ON"
)
endif()
# SPIRV Tools
AddJsonPackage(
NAME spirv-tools
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS}
)
# Boost headers
if (NOT Boost_ADDED AND NOT TARGET Boost::headers)
AddPackage(
NAME boost_headers
REPO "boostorg/headers"
SHA 0456900fad
HASH 50cd75dcdfc5f082225cdace058f47b4fb114a47585f7aee1d22236a910a80b667186254c214fa2fcebac67ae6d37ba4b6e695e1faea8affd6fd42a03cf996e3
BUNDLED_PACKAGE ON
)
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()
# TZDB (Time Zone Database)
add_subdirectory(nx_tzdb)
# VMA
AddPackage(
NAME VulkanMemoryAllocator
REPO "GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator"
SHA 1076b348ab
HASH a46b44e4286d08cffda058e856c47f44c7fed3da55fe9555976eb3907fdcc20ead0b1860b0c38319cda01dbf9b1aa5d4b4038c7f1f8fbd97283d837fa9af9772
FIND_PACKAGE_ARGUMENTS "CONFIG"
)
AddJsonPackage(vulkan-memory-allocator)
if (NOT TARGET LLVM::Demangle)
add_library(demangle demangle/ItaniumDemangle.cpp)
@ -369,17 +175,8 @@ if (NOT TARGET RenderDoc::API)
add_library(RenderDoc::API ALIAS renderdoc)
endif()
if (ANDROID)
if (ARCHITECTURE_arm64)
AddPackage(
NAME libadrenotools
REPO "bylaws/libadrenotools"
SHA 8fae8ce254
HASH c74fa855f0edebbf25c9bce40b00966daa2447bfc5e15f0cf1a95f86cbf70fc6b02590707edbde16328a0a2a4fb9a1fc419d2dfc22a4a4150971be91892d4edb
PATCHES
${CMAKE_SOURCE_DIR}/.patch/libadrenotools/0001-linkerns-cpm.patch
)
endif()
if (ANDROID AND ARCHITECTURE_arm64)
AddJsonPackage(libadrenotools)
endif()
if (UNIX AND NOT APPLE AND NOT TARGET gamemode::headers)
@ -402,6 +199,7 @@ if (YUZU_CRASH_DUMPS AND NOT TARGET libbreakpad_client)
_CRT_NONSTDC_NO_DEPRECATE
)
# TODO
AddPackage(
NAME breakpad
URL "google/breakpad"
@ -500,19 +298,9 @@ if (YUZU_CRASH_DUMPS AND NOT TARGET libbreakpad_client)
endif()
endif()
# SimpleIni
if (NOT TARGET SimpleIni::SimpleIni)
add_subdirectory(simpleini)
endif()
# oboe
if (ANDROID)
AddPackage(
NAME oboe
REPO "google/oboe"
SHA 2bc873e53c
HASH 02329058a7f9cf7d5039afaae5ab170d9f42f60f4c01e21eaf4f46073886922b057a9ae30eeac040b3ac182f51b9c1bfe9fe1050a2c9f6ce567a1a9a0ec2c768
)
AddJsonPackage(oboe)
add_library(oboe::oboe ALIAS oboe)
endif()

109
externals/cpmfile.json vendored Normal file
View file

@ -0,0 +1,109 @@
{
"mbedtls": {
"repo": "Mbed-TLS/mbedtls",
"sha": "8c88150ca1",
"hash": "769ad1e94c570671071e1f2a5c0f1027e0bf6bcdd1a80ea8ac970f2c86bc45ce4e31aa88d6d8110fc1bed1de81c48bc624df1b38a26f8b340a44e109d784a966",
"patches": [
"0001-cmake-version.patch"
]
},
"spirv-headers": {
"package": "SPIRV-Headers",
"repo": "KhronosGroup/SPIRV-Headers",
"sha": "4e209d3d7e",
"hash": "f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4"
},
"sirit": {
"repo": "eden-emulator/sirit",
"sha": "db1f1e8ab5",
"hash": "73eb3a042848c63a10656545797e85f40d142009dfb7827384548a385e1e28e1ac72f42b25924ce530d58275f8638554281e884d72f9c7aaf4ed08690a414b05",
"options": [
"SIRIT_USE_SYSTEM_SPIRV_HEADERS ON"
]
},
"httplib": {
"repo": "yhirose/cpp-httplib",
"sha": "a609330e4c",
"hash": "dd3fd0572f8367d8549e1319fd98368b3e75801a293b0c3ac9b4adb806473a4506a484b3d389dc5bee5acc460cb90af7a20e5df705a1696b56496b30b9ce7ed2"
},
"cpp-jwt": {
"version": "1.4",
"repo": "arun11299/cpp-jwt",
"sha": "a54fa08a3b",
"hash": "a90f7e594ada0c7e49d5ff9211c71097534e7742a8e44bf0851b0362642a7271d53f5d83d04eeaae2bad17ef3f35e09e6818434d8eaefa038f3d1f7359d0969a",
"find_args": "CONFIG",
"options": [
"CPP_JWT_BUILD_EXAMPLES OFF",
"CPP_JWT_BUILD_TESTS OFF",
"CPP_JWT_USE_VENDORED_NLOHMANN_JSON OFF"
],
"patches": [
"0001-no-install.patch",
"0002-missing-decl.patch"
]
},
"vulkan-headers": {
"package": "VulkanHeaders",
"version": "1.3.274",
"repo": "KhronosGroup/Vulkan-Headers",
"sha": "89268a6d17",
"hash": "3ab349f74298ba72cafb8561015690c0674d428a09fb91ccd3cd3daca83650d190d46d33fd97b0a8fd4223fe6df2bcabae89136fbbf7c0bfeb8776f9448304c8"
},
"vulkan-utility-libraries": {
"package": "VulkanUtilityLibraries",
"repo": "KhronosGroup/Vulkan-Utility-Libraries",
"sha": "df2e358152",
"hash": "3e468c3d9ff93f6d418d71e5527abe0a12c8c7ab5b0b52278bbbee4d02bb87e99073906729b727e0147242b7e3fd5dedf68b803f1878cb4c0e4f730bc2238d79"
},
"vulkan-memory-allocator": {
"package": "VulkanMemoryAllocator",
"repo": "GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator",
"sha": "1076b348ab",
"hash": "a46b44e4286d08cffda058e856c47f44c7fed3da55fe9555976eb3907fdcc20ead0b1860b0c38319cda01dbf9b1aa5d4b4038c7f1f8fbd97283d837fa9af9772",
"find_args": "CONFIG"
},
"spirv-tools": {
"package": "SPIRV-Tools",
"repo": "KhronosGroup/SPIRV-Tools",
"sha": "40eb301f32",
"hash": "58d0fb1047d69373cf24c73e6f78c73a72a6cca3b4df1d9f083b9dcc0962745ef154abf3dbe9b3623b835be20c6ec769431cf11733349f45e7568b3525f707aa",
"find_args": "MODULE",
"options": [
"SPIRV_SKIP_EXECUTABLES ON"
]
},
"xbyak_sun": {
"package": "xbyak",
"repo": "Lizzie841/xbyak",
"sha": "51f507b0b3",
"hash": "4a29a3c2f97f7d5adf667a21a008be03c951fb6696b0d7ba27e7e4afa037bc76eb5e059bb84860e01baf741d4d3ac851b840cd54c99d038812fbe0f1fa6d38a4",
"bundled": true
},
"xbyak": {
"package": "xbyak",
"repo": "Lizzie841/xbyak",
"sha": "4e44f4614d",
"hash": "5824e92159e07fa36a774aedd3b3ef3541d0241371d522cffa4ab3e1f215fa5097b1b77865b47b2481376c704fa079875557ea463ca63d0a7fd6a8a20a589e70",
"bundled": true
},
"oaknut": {
"version": "2.0.1",
"repo": "merryhime/oaknut",
"sha": "94c726ce03",
"hash": "d8d082242fa1881abce3c82f8dafa002c4e561e66a69e7fc038af67faa5eff2630f082d3d19579c88c4c9f9488e54552accc8cb90e7ce743efe043b6230c08ac"
},
"libadrenotools": {
"repo": "bylaws/libadrenotools",
"sha": "8fae8ce254",
"hash": "c74fa855f0edebbf25c9bce40b00966daa2447bfc5e15f0cf1a95f86cbf70fc6b02590707edbde16328a0a2a4fb9a1fc419d2dfc22a4a4150971be91892d4edb",
"patches": [
"0001-linkerns-cpm.patch"
]
},
"oboe": {
"repo": "google/oboe",
"sha": "2bc873e53c",
"hash": "02329058a7f9cf7d5039afaae5ab170d9f42f60f4c01e21eaf4f46073886922b057a9ae30eeac040b3ac182f51b9c1bfe9fe1050a2c9f6ce567a1a9a0ec2c768",
"bundled": true
}
}

View file

@ -1,6 +1,10 @@
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
# Explicitly include CPMUtil here since we have a separate cpmfile for ffmpeg
set(CPMUTIL_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json)
include(CPMUtil)
if (NOT WIN32 AND NOT ANDROID)
# Build FFmpeg from externals
message(STATUS "Using FFmpeg from externals")
@ -19,13 +23,7 @@ if (NOT WIN32 AND NOT ANDROID)
message(FATAL_ERROR "Required program `autoconf` not found.")
endif()
AddPackage(
NAME ffmpeg
REPO "FFmpeg/FFmpeg"
SHA c2184b65d2
HASH 2a89d664119debbb3c006ab1c48d5d7f26e889f4a65ad2e25c8b0503308295123d5a9c5c78bf683aef5ff09acef8c3fc2837f22d3e8c611528b933bf03bcdd97
SYSTEM_PACKAGE OFF
)
AddJsonPackage(ffmpeg)
set(FFmpeg_PREFIX ${ffmpeg_SOURCE_DIR})
set(FFmpeg_BUILD_DIR ${ffmpeg_BINARY_DIR})
@ -65,32 +63,44 @@ if (NOT WIN32 AND NOT ANDROID)
set(FFmpeg_HWACCEL_INCLUDE_DIRS)
set(FFmpeg_HWACCEL_LDFLAGS)
if(LIBVA_FOUND)
# In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so
if(PLATFORM_SUN)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
X11
"/usr/lib/xorg/amd64/libdrm.so")
else()
pkg_check_modules(LIBDRM libdrm REQUIRED)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
${LIBDRM_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${LIBDRM_INCLUDE_DIRS})
endif()
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-libdrm)
if(LIBVA_FOUND)
find_package(X11 REQUIRED)
pkg_check_modules(LIBVA-DRM libva-drm REQUIRED)
pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
${LIBDRM_LIBRARIES}
${X11_LIBRARIES}
${LIBVA-DRM_LIBRARIES}
${LIBVA-X11_LIBRARIES}
${LIBVA_LIBRARIES})
set(FFmpeg_HWACCEL_FLAGS
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-hwaccel=h264_vaapi
--enable-hwaccel=vp8_vaapi
--enable-hwaccel=vp9_vaapi
--enable-libdrm)
--enable-hwaccel=vp9_vaapi)
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${LIBDRM_INCLUDE_DIRS}
${X11_INCLUDE_DIRS}
${LIBVA-DRM_INCLUDE_DIRS}
${LIBVA-X11_INCLUDE_DIRS}
${LIBVA_INCLUDE_DIRS}
)
message(STATUS "VA-API found")
message(STATUS "ffmpeg: va-api libraries version ${LIBVA_VERSION} found")
else()
set(FFmpeg_HWACCEL_FLAGS --disable-vaapi)
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi)
message(WARNING "ffmpeg: libva-dev not found, disabling Video Aceleraion API (VA-API)...")
endif()
if (FFNVCODEC_FOUND)
@ -105,7 +115,7 @@ if (NOT WIN32 AND NOT ANDROID)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${FFNVCODEC_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${FFNVCODEC_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${FFNVCODEC_LDFLAGS})
message(STATUS "ffnvcodec libraries version ${FFNVCODEC_VERSION} found")
message(STATUS "ffmpeg: ffnvcodec libraries version ${FFNVCODEC_VERSION} found")
# ffnvenc could load CUDA libraries at the runtime using dlopen/dlsym or LoadLibrary/GetProcAddress
# here we handle the hard-linking senario where CUDA is linked during compilation
if (CUDA_FOUND)
@ -114,7 +124,7 @@ if (NOT WIN32 AND NOT ANDROID)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${CUDA_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${CUDA_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${CUDA_LDFLAGS})
message(STATUS "CUDA libraries found, hard-linking will be performed")
message(STATUS "ffmpeg: CUDA libraries found, hard-linking will be performed")
endif(CUDA_FOUND)
endif()
@ -127,9 +137,10 @@ if (NOT WIN32 AND NOT ANDROID)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${VDPAU_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${VDPAU_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${VDPAU_LDFLAGS})
message(STATUS "vdpau libraries version ${VDPAU_VERSION} found")
message(STATUS "ffmpeg: vdpau libraries version ${VDPAU_VERSION} found")
else()
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau)
message(WARNING "ffmpeg: libvdpau-dev not found, disabling Video Decode and Presentation API for Unix (VDPAU)...")
endif()
find_program(BASH_PROGRAM bash REQUIRED)

8
externals/ffmpeg/cpmfile.json vendored Normal file
View file

@ -0,0 +1,8 @@
{
"ffmpeg": {
"repo": "FFmpeg/FFmpeg",
"sha": "c2184b65d2",
"hash": "2a89d664119debbb3c006ab1c48d5d7f26e889f4a65ad2e25c8b0503308295123d5a9c5c78bf683aef5ff09acef8c3fc2837f22d3e8c611528b933bf03bcdd97",
"bundled": true
}
}

View file

@ -1,6 +1,10 @@
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
# Explicitly include CPMUtil here since we have a separate cpmfile for nx_tzdb
set(CPMUTIL_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json)
include(CPMUtil)
set(NX_TZDB_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include")
add_library(nx_tzdb INTERFACE)
@ -28,28 +32,14 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR ANDROID)
endif()
set(NX_TZDB_VERSION "250725")
set(NX_TZDB_ARCHIVE "${CPM_SOURCE_CACHE}/nx_tzdb/${NX_TZDB_VERSION}.zip")
set(NX_TZDB_ROMFS_DIR "${CPM_SOURCE_CACHE}/nx_tzdb")
set(NX_TZDB_ROMFS_DIR "${CPM_SOURCE_CACHE}/nx_tzdb/tz")
if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ROMFS_DIR})
set(NX_TZDB_DOWNLOAD_URL "https://github.com/crueter/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip")
message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...")
file(DOWNLOAD ${NX_TZDB_DOWNLOAD_URL} ${NX_TZDB_ARCHIVE}
STATUS NX_TZDB_DOWNLOAD_STATUS)
list(GET NX_TZDB_DOWNLOAD_STATUS 0 NX_TZDB_DOWNLOAD_STATUS_CODE)
if (NOT NX_TZDB_DOWNLOAD_STATUS_CODE EQUAL 0)
message(FATAL_ERROR "Time zone data download failed (status code ${NX_TZDB_DOWNLOAD_STATUS_CODE})")
endif()
file(ARCHIVE_EXTRACT
INPUT
${NX_TZDB_ARCHIVE}
DESTINATION
${NX_TZDB_ROMFS_DIR})
if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION})
message(STATUS "Downloading time zone data...")
AddJsonPackage(tzdb)
elseif (CAN_BUILD_NX_TZDB AND NOT YUZU_DOWNLOAD_TIME_ZONE_DATA)
# TODO(crueter): this sucked to do with cpm, see if i can get it to work again
message(FATAL_ERROR "Building tzdb is currently unsupported. Check back later.")
add_subdirectory(tzdb_to_nx)
add_dependencies(nx_tzdb x80e)
@ -79,24 +69,24 @@ function(CreateHeader ZONE_PATH HEADER_NAME)
endfunction()
CreateHeader(${NX_TZDB_ROMFS_DIR} base)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo zoneinfo)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Africa africa)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America america)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Argentina america_argentina)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Indiana america_indiana)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Kentucky america_kentucky)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/North_Dakota america_north_dakota)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Antarctica antarctica)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Arctic arctic)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Asia asia)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Atlantic atlantic)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Australia australia)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Brazil brazil)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Canada canada)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Chile chile)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Etc etc)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Europe europe)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Indian indian)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Mexico mexico)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Pacific pacific)
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/US us)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION} zoneinfo)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Africa africa)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/America america)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/America/Argentina america_argentina)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/America/Indiana america_indiana)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/America/Kentucky america_kentucky)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/America/North_Dakota america_north_dakota)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Antarctica antarctica)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Arctic arctic)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Asia asia)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Atlantic atlantic)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Australia australia)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Brazil brazil)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Canada canada)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Chile chile)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Etc etc)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Europe europe)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Indian indian)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Mexico mexico)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/Pacific pacific)
CreateHeader(${NX_TZDB_ROMFS_DIR}/${NX_TZDB_VERSION}/US us)

8
externals/nx_tzdb/cpmfile.json vendored Normal file
View file

@ -0,0 +1,8 @@
{
"tzdb": {
"package": "nx_tzdb",
"url": "https://github.com/crueter/tzdb_to_nx/releases/download/250725/250725.zip",
"hash": "8f60b4b29f285e39c0443f3d5572a73780f3dbfcfd5b35004451fadad77f3a215b2e2aa8d0fffe7e348e2a7b0660882b35228b6178dda8804a14ce44509fd2ca",
"version": "250725"
}
}

View file

@ -1,61 +0,0 @@
name: Build and Test
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
Windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: microsoft/setup-msbuild@v2
- name: Build
run: |
nuget restore vcproj\SimpleIni.sln
msbuild vcproj\SimpleIni.sln /p:Configuration=Release
- name: Run tests
run: |
cd tests
..\vcproj\x64\Release\tests.exe
Ubuntu:
runs-on: ubuntu-latest
steps:
- name: Install requirements
run: sudo apt install libgtest-dev cmake
- uses: actions/checkout@v3
- run: make all && make test
- name: test with CMake (-DSIMPLEINI_USE_SYSTEM_GTEST=OFF)
run: |
cmake . -B build -DSIMPLEINI_USE_SYSTEM_GTEST=OFF
cmake --build build
ctest --verbose --test-dir build
- name: test with CMake (-DSIMPLEINI_USE_SYSTEM_GTEST=ON)
run: |
cmake . -B build-system-gtest -DSIMPLEINI_USE_SYSTEM_GTEST=ON
cmake --build build-system-gtest
ctest --verbose --test-dir build-system-gtest
MacOS:
runs-on: macos-latest
steps:
- name: Install requirements
run: brew install googletest cmake
- uses: actions/checkout@v3
- run: make all && make test
- name: test with CMake (-DSIMPLEINI_USE_SYSTEM_GTEST=OFF)
run: |
cmake . -B build -DSIMPLEINI_USE_SYSTEM_GTEST=OFF
cmake --build build
ctest --verbose --test-dir build
- name: test with CMake (-DSIMPLEINI_USE_SYSTEM_GTEST=ON)
run: |
cmake . -B build-system-gtest -DSIMPLEINI_USE_SYSTEM_GTEST=ON
cmake --build build-system-gtest
ctest --verbose --test-dir build-system-gtest

View file

@ -1,24 +0,0 @@
name: Build Doxygen Docs
on:
workflow_run:
workflows: ["Build and Test"]
types:
- completed
jobs:
deploy:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install Doxygen
run: sudo apt-get update && sudo apt-get install -y doxygen graphviz
- name: Generate Doxygen Documentation
run: doxygen Doxyfile
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/html

View file

@ -1,37 +0,0 @@
name: "CodeQL"
on: workflow_dispatch
#on:
# push:
# branches: [ "master" ]
# pull_request:
# branches: [ "master" ]
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

View file

@ -1,365 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
docs
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
build/
build-system-gtest/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*[.json, .xml, .info]
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd

View file

@ -1,66 +0,0 @@
cmake_minimum_required(VERSION 3.14)
project(
SimpleIni
VERSION 4.22
DESCRIPTION "Cross-platform C++ library providing a simple API to read and write INI-style configuration files"
LANGUAGES CXX
)
option(SIMPLEINI_USE_SYSTEM_GTEST "Use system GoogleTest dependency" OFF)
# disable in-source builds
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "In-source builds are not allowed, use cmake -S . -B build.")
endif()
# Define library paths and include directories
set(EXPORT_NAMESPACE "${PROJECT_NAME}::")
set(HEADERS SimpleIni.h)
add_library(${PROJECT_NAME} INTERFACE)
add_library(${EXPORT_NAMESPACE}${PROJECT_NAME} ALIAS ${PROJECT_NAME})
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
configure_package_config_file(${PROJECT_NAME}Config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}
)
install(FILES SimpleIni.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}
)
install(EXPORT ${PROJECT_NAME}Targets
DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}
NAMESPACE ${EXPORT_NAMESPACE}
)
target_include_directories(${PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
# only build tests when top level and testing enabled
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest)
if(BUILD_TESTING)
add_subdirectory(tests)
endif()
endif()

View file

@ -1,578 +0,0 @@
/*
* https://web.archive.org/web/20090529064329/http://www.unicode.org:80/Public/PROGRAMS/CVTUTF/
*
* Copyright 2001-2004 Unicode, Inc.
*
* Disclaimer
*
* This source code is provided as is by Unicode, Inc. No claims are
* made as to fitness for any particular purpose. No warranties of any
* kind are expressed or implied. The recipient agrees to determine
* applicability of information provided. If this file has been
* purchased on magnetic or optical media from Unicode, Inc., the
* sole remedy for any claim will be exchange of defective media
* within 90 days of receipt.
*
* Limitations on Rights to Redistribute This Code
*
* Unicode, Inc. hereby grants the right to freely use the information
* supplied in this file in the creation of products supporting the
* Unicode Standard, and to make copies of this file in any form
* for internal or external distribution as long as this notice
* remains attached.
*/
/* ---------------------------------------------------------------------
Conversions between UTF32, UTF-16, and UTF-8. Source code file.
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
Sept 2001: fixed const & error conditions per
mods suggested by S. Parent & A. Lillich.
June 2002: Tim Dodd added detection and handling of incomplete
source sequences, enhanced error detection, added casts
to eliminate compiler warnings.
July 2003: slight mods to back out aggressive FFFE detection.
Jan 2004: updated switches in from-UTF8 conversions.
Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
See the header file "ConvertUTF.h" for complete documentation.
------------------------------------------------------------------------ */
#include "ConvertUTF.h"
#ifdef CVTUTF_DEBUG
#include <stdio.h>
#endif
static const int halfShift = 10; /* used for shifting by 10 bits */
static const UTF32 halfBase = 0x0010000UL;
static const UTF32 halfMask = 0x3FFUL;
#define UNI_SUR_HIGH_START (UTF32)0xD800
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
#define UNI_SUR_LOW_START (UTF32)0xDC00
#define UNI_SUR_LOW_END (UTF32)0xDFFF
#define false 0
#define true 1
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF16(
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
UTF16* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
if (target >= targetEnd) {
result = targetExhausted; break;
}
ch = *source++;
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
/* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
else {
*target++ = UNI_REPLACEMENT_CHAR;
}
}
else {
*target++ = (UTF16)ch; /* normal case */
}
}
else if (ch > UNI_MAX_LEGAL_UTF32) {
if (flags == strictConversion) {
result = sourceIllegal;
}
else {
*target++ = UNI_REPLACEMENT_CHAR;
}
}
else {
/* target is a character in range 0xFFFF - 0x10FFFF. */
if (target + 1 >= targetEnd) {
--source; /* Back up source pointer! */
result = targetExhausted; break;
}
ch -= halfBase;
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF32(
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
UTF32* target = *targetStart;
UTF32 ch, ch2;
while (source < sourceEnd) {
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
/* If the 16 bits following the high surrogate are in the source buffer... */
if (source < sourceEnd) {
ch2 = *source;
/* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
}
else if (flags == strictConversion) { /* it's an unpaired high surrogate */
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
else { /* We don't have the 16 bits following the high surrogate. */
--source; /* return to the high surrogate */
result = sourceExhausted;
break;
}
}
else if (flags == strictConversion) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
if (target >= targetEnd) {
source = oldSource; /* Back up source pointer! */
result = targetExhausted; break;
}
*target++ = ch;
}
*sourceStart = source;
*targetStart = target;
#ifdef CVTUTF_DEBUG
if (result == sourceIllegal) {
fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
fflush(stderr);
}
#endif
return result;
}
/* --------------------------------------------------------------------- */
/*
* Index into the table below with the first byte of a UTF-8 sequence to
* get the number of trailing bytes that are supposed to follow it.
* Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
* left as-is for anyone who may want to do such conversion, which was
* allowed in earlier algorithms.
*/
static const char trailingBytesForUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
/*
* Magic values subtracted from a buffer value during UTF8 conversion.
* This table contains as many values as there might be trailing bytes
* in a UTF-8 sequence.
*/
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
/*
* Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
* into the first byte, depending on how many bytes follow. There are
* as many entries in this table as there are UTF-8 sequence types.
* (I.e., one byte sequence, two byte... etc.). Remember that sequencs
* for *legal* UTF-8 will be 4 or fewer bytes total.
*/
static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
/* --------------------------------------------------------------------- */
/* The interface converts a whole buffer to avoid function-call overhead.
* Constants have been gathered. Loops & conditionals have been removed as
* much as possible for efficiency, in favor of drop-through switches.
* (See "Note A" at the bottom of the file for equivalent code.)
* If your compiler supports it, the "isLegalUTF8" call can be turned
* into an inline function.
*/
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF8(
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
UTF8* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
unsigned short bytesToWrite = 0;
const UTF32 byteMask = 0xBF;
const UTF32 byteMark = 0x80;
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
/* If the 16 bits following the high surrogate are in the source buffer... */
if (source < sourceEnd) {
UTF32 ch2 = *source;
/* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
}
else if (flags == strictConversion) { /* it's an unpaired high surrogate */
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
else { /* We don't have the 16 bits following the high surrogate. */
--source; /* return to the high surrogate */
result = sourceExhausted;
break;
}
}
else if (flags == strictConversion) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
/* Figure out how many bytes the result will require */
if (ch < (UTF32)0x80) {
bytesToWrite = 1;
}
else if (ch < (UTF32)0x800) {
bytesToWrite = 2;
}
else if (ch < (UTF32)0x10000) {
bytesToWrite = 3;
}
else if (ch < (UTF32)0x110000) {
bytesToWrite = 4;
}
else {
bytesToWrite = 3;
ch = UNI_REPLACEMENT_CHAR;
}
target += bytesToWrite;
if (target > targetEnd) {
source = oldSource; /* Back up source pointer! */
target -= bytesToWrite; result = targetExhausted; break;
}
switch (bytesToWrite) { /* note: everything falls through. */
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
}
target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
/*
* Utility routine to tell whether a sequence of bytes is legal UTF-8.
* This must be called with the length pre-determined by the first byte.
* If not calling this from ConvertUTF8to*, then the length can be set by:
* length = trailingBytesForUTF8[*source]+1;
* and the sequence is illegal right away if there aren't that many bytes
* available.
* If presented with a length > 4, this returns false. The Unicode
* definition of UTF-8 goes up to 4-byte sequences.
*/
static Boolean isLegalUTF8(const UTF8* source, int length) {
UTF8 a;
const UTF8* srcptr = source + length;
switch (length) {
default: return false;
/* Everything else falls through when "true"... */
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 2: if ((a = (*--srcptr)) > 0xBF) return false;
switch (*source) {
/* no fall-through in this inner switch */
case 0xE0: if (a < 0xA0) return false; break;
case 0xED: if (a > 0x9F) return false; break;
case 0xF0: if (a < 0x90) return false; break;
case 0xF4: if (a > 0x8F) return false; break;
default: if (a < 0x80) return false;
}
case 1: if (*source >= 0x80 && *source < 0xC2) return false;
}
if (*source > 0xF4) return false;
return true;
}
/* --------------------------------------------------------------------- */
/*
* Exported function to return whether a UTF-8 sequence is legal or not.
* This is not used here; it's just exported.
*/
Boolean isLegalUTF8Sequence(const UTF8* source, const UTF8* sourceEnd) {
int length = trailingBytesForUTF8[*source] + 1;
if (source + length > sourceEnd) {
return false;
}
return isLegalUTF8(source, length);
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF16(
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
UTF16* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (source + extraBytesToRead >= sourceEnd) {
result = sourceExhausted; break;
}
/* Do this check whether lenient or strict */
if (!isLegalUTF8(source, extraBytesToRead + 1)) {
result = sourceIllegal;
break;
}
/*
* The cases all fall through. See "Note A" below.
*/
switch (extraBytesToRead) {
case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
case 3: ch += *source++; ch <<= 6;
case 2: ch += *source++; ch <<= 6;
case 1: ch += *source++; ch <<= 6;
case 0: ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
if (target >= targetEnd) {
source -= (extraBytesToRead + 1); /* Back up source pointer! */
result = targetExhausted; break;
}
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
source -= (extraBytesToRead + 1); /* return to the illegal value itself */
result = sourceIllegal;
break;
}
else {
*target++ = UNI_REPLACEMENT_CHAR;
}
}
else {
*target++ = (UTF16)ch; /* normal case */
}
}
else if (ch > UNI_MAX_UTF16) {
if (flags == strictConversion) {
result = sourceIllegal;
source -= (extraBytesToRead + 1); /* return to the start */
break; /* Bail out; shouldn't continue */
}
else {
*target++ = UNI_REPLACEMENT_CHAR;
}
}
else {
/* target is a character in range 0xFFFF - 0x10FFFF. */
if (target + 1 >= targetEnd) {
source -= (extraBytesToRead + 1); /* Back up source pointer! */
result = targetExhausted; break;
}
ch -= halfBase;
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF8(
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
UTF8* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
unsigned short bytesToWrite = 0;
const UTF32 byteMask = 0xBF;
const UTF32 byteMark = 0x80;
ch = *source++;
if (flags == strictConversion) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
/*
* Figure out how many bytes the result will require. Turn any
* illegally large UTF32 things (> Plane 17) into replacement chars.
*/
if (ch < (UTF32)0x80) {
bytesToWrite = 1;
}
else if (ch < (UTF32)0x800) {
bytesToWrite = 2;
}
else if (ch < (UTF32)0x10000) {
bytesToWrite = 3;
}
else if (ch <= UNI_MAX_LEGAL_UTF32) {
bytesToWrite = 4;
}
else {
bytesToWrite = 3;
ch = UNI_REPLACEMENT_CHAR;
result = sourceIllegal;
}
target += bytesToWrite;
if (target > targetEnd) {
--source; /* Back up source pointer! */
target -= bytesToWrite; result = targetExhausted; break;
}
switch (bytesToWrite) { /* note: everything falls through. */
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
}
target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF32(
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
UTF32* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (source + extraBytesToRead >= sourceEnd) {
result = sourceExhausted; break;
}
/* Do this check whether lenient or strict */
if (!isLegalUTF8(source, extraBytesToRead + 1)) {
result = sourceIllegal;
break;
}
/*
* The cases all fall through. See "Note A" below.
*/
switch (extraBytesToRead) {
case 5: ch += *source++; ch <<= 6;
case 4: ch += *source++; ch <<= 6;
case 3: ch += *source++; ch <<= 6;
case 2: ch += *source++; ch <<= 6;
case 1: ch += *source++; ch <<= 6;
case 0: ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
if (target >= targetEnd) {
source -= (extraBytesToRead + 1); /* Back up the source pointer! */
result = targetExhausted; break;
}
if (ch <= UNI_MAX_LEGAL_UTF32) {
/*
* UTF-16 surrogate values are illegal in UTF-32, and anything
* over Plane 17 (> 0x10FFFF) is illegal.
*/
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
source -= (extraBytesToRead + 1); /* return to the illegal value itself */
result = sourceIllegal;
break;
}
else {
*target++ = UNI_REPLACEMENT_CHAR;
}
}
else {
*target++ = ch;
}
}
else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
result = sourceIllegal;
*target++ = UNI_REPLACEMENT_CHAR;
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* ---------------------------------------------------------------------
Note A.
The fall-through switches in UTF-8 reading code save a
temp variable, some decrements & conditionals. The switches
are equivalent to the following loop:
{
int tmpBytesToRead = extraBytesToRead+1;
do {
ch += *source++;
--tmpBytesToRead;
if (tmpBytesToRead) ch <<= 6;
} while (tmpBytesToRead > 0);
}
In UTF-8 writing code, the switches on "bytesToWrite" are
similarly unrolled loops.
--------------------------------------------------------------------- */

View file

@ -1,151 +0,0 @@
/*
* https://web.archive.org/web/20090529064329/http://www.unicode.org:80/Public/PROGRAMS/CVTUTF/
*
* Copyright 2001-2004 Unicode, Inc.
*
* Disclaimer
*
* This source code is provided as is by Unicode, Inc. No claims are
* made as to fitness for any particular purpose. No warranties of any
* kind are expressed or implied. The recipient agrees to determine
* applicability of information provided. If this file has been
* purchased on magnetic or optical media from Unicode, Inc., the
* sole remedy for any claim will be exchange of defective media
* within 90 days of receipt.
*
* Limitations on Rights to Redistribute This Code
*
* Unicode, Inc. hereby grants the right to freely use the information
* supplied in this file in the creation of products supporting the
* Unicode Standard, and to make copies of this file in any form
* for internal or external distribution as long as this notice
* remains attached.
*/
/* ---------------------------------------------------------------------
Conversions between UTF32, UTF-16, and UTF-8. Header file.
Several funtions are included here, forming a complete set of
conversions between the three formats. UTF-7 is not included
here, but is handled in a separate source file.
Each of these routines takes pointers to input buffers and output
buffers. The input buffers are const.
Each routine converts the text between *sourceStart and sourceEnd,
putting the result into the buffer between *targetStart and
targetEnd. Note: the end pointers are *after* the last item: e.g.
*(sourceEnd - 1) is the last item.
The return result indicates whether the conversion was successful,
and if not, whether the problem was in the source or target buffers.
(Only the first encountered problem is indicated.)
After the conversion, *sourceStart and *targetStart are both
updated to point to the end of last text successfully converted in
the respective buffers.
Input parameters:
sourceStart - pointer to a pointer to the source buffer.
The contents of this are modified on return so that
it points at the next thing to be converted.
targetStart - similarly, pointer to pointer to the target buffer.
sourceEnd, targetEnd - respectively pointers to the ends of the
two buffers, for overflow checking only.
These conversion functions take a ConversionFlags argument. When this
flag is set to strict, both irregular sequences and isolated surrogates
will cause an error. When the flag is set to lenient, both irregular
sequences and isolated surrogates are converted.
Whether the flag is strict or lenient, all illegal sequences will cause
an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
must check for illegal sequences.
When the flag is set to lenient, characters over 0x10FFFF are converted
to the replacement character; otherwise (when the flag is set to strict)
they constitute an error.
Output parameters:
The value "sourceIllegal" is returned from some routines if the input
sequence is malformed. When "sourceIllegal" is returned, the source
value will point to the illegal value that caused the problem. E.g.,
in UTF-8 when a sequence is malformed, it points to the start of the
malformed sequence.
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
Fixes & updates, Sept 2001.
------------------------------------------------------------------------ */
/* ---------------------------------------------------------------------
The following 4 definitions are compiler-specific.
The C standard does not guarantee that wchar_t has at least
16 bits, so wchar_t is no less portable than unsigned short!
All should be unsigned values to avoid sign extension during
bit mask & shift operations.
------------------------------------------------------------------------ */
typedef unsigned long UTF32; /* at least 32 bits */
typedef unsigned short UTF16; /* at least 16 bits */
typedef unsigned char UTF8; /* typically 8 bits */
typedef unsigned char Boolean; /* 0 or 1 */
/* Some fundamental constants */
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
#define UNI_MAX_BMP (UTF32)0x0000FFFF
#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
typedef enum {
conversionOK, /* conversion successful */
sourceExhausted, /* partial character in source, but hit end */
targetExhausted, /* insuff. room in target for conversion */
sourceIllegal /* source sequence is illegal/malformed */
} ConversionResult;
typedef enum {
strictConversion = 0,
lenientConversion
} ConversionFlags;
/* This is for C++ and does no harm in C */
#ifdef __cplusplus
extern "C" {
#endif
ConversionResult ConvertUTF8toUTF16(
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF16toUTF8(
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF8toUTF32(
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF8(
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF16toUTF32(
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF16(
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
Boolean isLegalUTF8Sequence(const UTF8* source, const UTF8* sourceEnd);
#ifdef __cplusplus
}
#endif
/* --------------------------------------------------------------------- */

View file

@ -1,43 +0,0 @@
https://web.archive.org/web/20090529064329/http://www.unicode.org:80/Public/PROGRAMS/CVTUTF/
The accompanying C source code file "ConvertUTF.c" and the associated header
file "ConvertUTF.h" provide for conversion between various transformation
formats of Unicode characters. The following conversions are supported:
UTF-32 to UTF-16
UTF-32 to UTF-8
UTF-16 to UTF-32
UTF-16 to UTF-8
UTF-8 to UTF-16
UTF-8 to UTF-32
In addition, there is a test harness which runs various tests.
The files "CVTUTF7.C" and "CVTUTF7.H" are for archival and historical purposes
only. They have not been updated to Unicode 3.0 or later and should be
considered obsolescent. "CVTUTF7.C" contains two functions that can convert
between UCS2 (i.e., the BMP characters only) and UTF-7. Surrogates are
not supported, the code has not been tested, and should be considered
unsuitable for general purpose use.
Please submit any bug reports about these programs here:
http://www.unicode.org/unicode/reporting.html
Version 1.0: initial version.
Version 1.1: corrected some minor problems; added stricter checks.
Version 1.2: corrected switch statements associated with "extraBytesToRead"
in 4 & 5 byte cases, in functions for conversion from UTF8.
Note: formally, the 4 & 5 byte cases are illegal in the latest
UTF8, but the table and this code has always catered for those,
cases since at one time they were legal.
Version 1.3: Updated UTF-8 legality check;
updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions
Updated UTF-8 legality tests in harness.c
Last update: October 19, 2004

File diff suppressed because it is too large Load diff

View file

@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2006-2024 Brodie Thiesfield
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -1,18 +0,0 @@
# This makefile is just to build the automatic test harness
# To use SimpleIni, just include SimpleIni.h header file
PREFIX?= /usr/local
TOPTARGETS := all clean test
SUBDIRS := tests
$(TOPTARGETS): $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)
.PHONY: $(TOPTARGETS) $(SUBDIRS)
install:
mkdir -p $(DESTDIR)$(PREFIX)/include/
install -C -m 644 SimpleIni.h $(DESTDIR)$(PREFIX)/include/

View file

@ -1,199 +0,0 @@
simpleini
=========
![Latest Test Results](https://github.com/brofield/simpleini/actions/workflows/build-and-test.yml/badge.svg)
A cross-platform library that provides a simple API to read and write INI-style configuration files. It supports data files in ASCII, MBCS and Unicode. It is designed explicitly to be portable to any platform and has been tested on Windows, WinCE and Linux. Released as open-source and free using the MIT licence.
[Full documentation](https://brofield.github.io/simpleini/)
# Feature Summary
- MIT Licence allows free use in all software (including GPL and commercial)
- multi-platform: Windows (from 95 to 11, CE), Linux, MacOS
- loading and saving of INI-style configuration files
- configuration files can have any newline format on all platforms
- liberal acceptance of file format
* key/values with no section, keys with no value
* removal of whitespace around sections, keys and values
- support for multi-line values (values with embedded newline characters)
- optional support for multiple keys with the same name
- optional case-insensitive sections and keys (for ASCII characters only)
- saves files with sections and keys in the same order as they were loaded
- preserves comments on the file, section and keys where possible
- supports both char or wchar_t programming interfaces
- supports both MBCS (system locale) and UTF-8 file encodings
- supports ICU as conversion library on all platforms
- system locale does not need to be UTF-8 on Linux/Unix to load UTF-8 file
- support for non-ASCII characters in section, keys, values and comments
- support for non-standard character types or file encodings via user-written converter classes
- support for adding/modifying values programmatically
- should compile with no warnings in most compilers
# Documentation
Full documentation of the interface is available in doxygen format. See [latest documentation here](https://brofield.github.io/simpleini/).
# Examples
These snippets are included with the distribution in the automatic tests as ts-snippets.cpp.
### SIMPLE USAGE
```c++
// simple demonstration
CSimpleIniA ini;
ini.SetUnicode();
SI_Error rc = ini.LoadFile("example.ini");
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_OK);
const char* pv;
pv = ini.GetValue("section", "key", "default");
ASSERT_STREQ(pv, "value");
ini.SetValue("section", "key", "newvalue");
pv = ini.GetValue("section", "key", "default");
ASSERT_STREQ(pv, "newvalue");
```
### LOADING DATA
```c++
// load from a data file
CSimpleIniA ini;
SI_Error rc = ini.LoadFile("example.ini");
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_OK);
// load from a string
const std::string example = "[section]\nkey = value\n";
CSimpleIniA ini;
SI_Error rc = ini.LoadData(example);
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_OK);
```
### GETTING SECTIONS AND KEYS
```c++
// get all sections
CSimpleIniA::TNamesDepend sections;
ini.GetAllSections(sections);
// get all keys in a section
CSimpleIniA::TNamesDepend keys;
ini.GetAllKeys("section1", keys);
```
### GETTING VALUES
```c++
// get the value of a key that doesn't exist
const char* pv;
pv = ini.GetValue("section1", "key99");
ASSERT_EQ(pv, nullptr);
// get the value of a key that does exist
pv = ini.GetValue("section1", "key1");
ASSERT_STREQ(pv, "value1");
// get the value of a key which may have multiple
// values. If hasMultiple is true, then there are
// multiple values and just one value has been returned
bool hasMulti;
pv = ini.GetValue("section1", "key1", nullptr, &hasMulti);
ASSERT_STREQ(pv, "value1");
ASSERT_EQ(hasMulti, false);
pv = ini.GetValue("section1", "key2", nullptr, &hasMulti);
ASSERT_STREQ(pv, "value2.1");
ASSERT_EQ(hasMulti, true);
// get all values of a key with multiple values
CSimpleIniA::TNamesDepend values;
ini.GetAllValues("section1", "key2", values);
// sort the values into a known order, in this case we want
// the original load order
values.sort(CSimpleIniA::Entry::LoadOrder());
// output all of the items
CSimpleIniA::TNamesDepend::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) {
printf("value = '%s'\n", it->pItem);
}
```
### MODIFYING DATA
```c++
// add a new section
rc = ini.SetValue("section1", nullptr, nullptr);
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_INSERTED);
// not an error to add one that already exists
rc = ini.SetValue("section1", nullptr, nullptr);
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_UPDATED);
// get the value of a key that doesn't exist
const char* pv;
pv = ini.GetValue("section2", "key1", "default-value");
ASSERT_STREQ(pv, "default-value");
// adding a key (the section will be added if needed)
rc = ini.SetValue("section2", "key1", "value1");
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_INSERTED);
// ensure it is set to expected value
pv = ini.GetValue("section2", "key1", nullptr);
ASSERT_STREQ(pv, "value1");
// change the value of a key
rc = ini.SetValue("section2", "key1", "value2");
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_UPDATED);
// ensure it is set to expected value
pv = ini.GetValue("section2", "key1", nullptr);
ASSERT_STREQ(pv, "value2");
```
### DELETING DATA
```c++
// deleting a key from a section. Optionally the entire
// section may be deleted if it is now empty.
bool done, deleteSectionIfEmpty = true;
done = ini.Delete("section1", "key1", deleteSectionIfEmpty);
ASSERT_EQ(done, true);
done = ini.Delete("section1", "key1");
ASSERT_EQ(done, false);
// deleting an entire section and all keys in it
done = ini.Delete("section2", nullptr);
ASSERT_EQ(done, true);
done = ini.Delete("section2", nullptr);
ASSERT_EQ(done, false);
```
### SAVING DATA
```c++
// save the data to a string
std::string data;
rc = ini.Save(data);
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_OK);
// save the data back to the file
rc = ini.SaveFile("example2.ini");
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_OK);
```

File diff suppressed because it is too large Load diff

View file

@ -1,8 +0,0 @@
@PACKAGE_INIT@
# prevent repeatedly including the targets
if(NOT TARGET @PROJECT_NAME@::@PROJECT_NAME@)
include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake)
endif()
message(STATUS "Found @PROJECT_NAME@, version: ${@PROJECT_NAME@_VERSION}")

View file

@ -1,26 +0,0 @@
set VERSION=4.15
set SEVENZIP="C:\Program Files\7-Zip\7z.exe"
FOR /F "tokens=*" %%G IN ('DIR /AD /B /S Debug*') DO (
DEL /S /Q "%%G"
RD "%%G"
)
FOR /F "tokens=*" %%G IN ('DIR /AD /B /S Release*') DO (
DEL /S /Q "%%G"
RD "%%G"
)
DEL /Q "SimpleIni.ncb"
ATTRIB -H "SimpleIni.suo"
DEL /Q "SimpleIni.suo"
DEL /Q "SimpleIni.opt"
DEL /Q testsi-out*.ini
DEL /Q test1-blah.ini
DEL /Q test1-output.ini
START "Generate documentation" /WAIT "C:\Program Files (x86)\doxygen\bin\doxygen.exe" SimpleIni.doxy
cd ..
del simpleini-%VERSION%.zip
%SEVENZIP% a -tzip -r- -x!simpleini\.svn simpleini-%VERSION%.zip simpleini\*
del simpleini-doc.zip
%SEVENZIP% a -tzip -r simpleini-doc.zip simpleini-doc\*
cd simpleini

File diff suppressed because it is too large Load diff

View file

@ -1,6 +0,0 @@
Making a release:
* update version number in SimpleIni.h
* update version number in CMakeLists.txt
* check-in all files
* make a release "v4.22" etc creating a matching tag

View file

@ -1,5 +0,0 @@
example2.ini
tests
*.o

View file

@ -1,30 +0,0 @@
if(SIMPLEINI_USE_SYSTEM_GTEST)
find_package(GTest REQUIRED)
else()
include(FetchContent)
FetchContent_Declare(
googletest
DOWNLOAD_EXTRACT_TIMESTAMP ON
URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
URL_HASH SHA1=0ac421f2ec11af38b0fff0f1992184032731a8bc
)
FetchContent_MakeAvailable(googletest)
endif()
add_executable(tests
ts-bugfix.cpp
ts-noconvert.cpp
ts-quotes.cpp
ts-roundtrip.cpp
ts-snippets.cpp
ts-utf8.cpp)
add_test(NAME tests COMMAND tests)
target_link_libraries(tests PRIVATE ${PROJECT_NAME} GTest::gtest_main)
add_custom_command(
TARGET tests POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/example.ini
${CMAKE_CURRENT_SOURCE_DIR}/tests.ini
${CMAKE_CURRENT_BINARY_DIR})

View file

@ -1,21 +0,0 @@
CXX?=g++
CXXFLAGS+=-Wall -std=c++14 `pkg-config --cflags gtest_main`
LDFLAGS+=`pkg-config --libs gtest_main`
OBJS=ts-roundtrip.o ts-snippets.o ts-utf8.o ts-bugfix.o ts-quotes.o ts-noconvert.o
BIN=./tests
all: $(BIN)
$(BIN): $(OBJS)
$(CXX) -o $(BIN) $(OBJS) $(LDFLAGS)
clean:
rm -f core $(OBJS) $(BIN)
test: $(BIN)
$(BIN)
$(OBJS): ../SimpleIni.h

View file

@ -1,2 +0,0 @@
[section]
key = value

View file

@ -1,24 +0,0 @@
@echo off
Debug\testsi.exe -u -m -l test1-input.ini > test1-blah.ini
fc test1-expected.ini test1-output.ini
if errorlevel 1 goto error
"Debug Unicode\testsi.exe" -u -m -l test1-input.ini > test1-blah.ini
fc test1-expected.ini test1-output.ini
if errorlevel 1 goto error
Release\testsi.exe -u -m -l test1-input.ini > test1-blah.ini
fc test1-expected.ini test1-output.ini
if errorlevel 1 goto error
"Release Unicode\testsi.exe" -u -m -l test1-input.ini > test1-blah.ini
fc test1-expected.ini test1-output.ini
if errorlevel 1 goto error
exit /b 0
:error
echo Failed during test run. Output file doesn't match expected file.
pause
exit /b 1

View file

@ -1,85 +0,0 @@
; testsi-UTF8-std.ini : standard UTF-8 test file for SimpleIni automated testing
;
; The number after a section or key is the order that it is defined in this file
; to make it easier to see if it has been written out correctly. This file should
; be loaded with Unicode / MultiKey / MultiLine turned on.
; This comment should be joined on to the one below it about the key
; with no section.
; Key with no section
lonely-key = nosection
another = nosection either
; This key has no value
empty =
; This should be joined with the comment below about japanese.
; Another line which will be un-indented.
; This is a section of keys showing the word Japanese in different syllabies.
[ordered-1]
a-1 = blah
; this is in kanji
japanese-2 = 日本語
; this is in hiragana
japanese-3 = にほんご
; this is in katakana
japanese-4 = ニホンゴ
; this is in romaji
japanese-5 = nihongo
; kanji as the key
日本語-6 = japanese
[multi-2]
; value a
test = a
; value b
test = b
; value c
test = c
; value d
test = d
[multiline-3]
; This is obviously a multi-line entry
multiline-1 = <<<END_OF_TEXT
This is a multi-line comment. It
will continue until we have the word MULTI
on a line by itself.
日本語も。
END_OF_TEXT
; This looks like multi-line, but because the newline following the last
; line is discarded, it will be converted into a single line entry.
another-2 = This is not a multiline entry.
; If you wanted a multiline entry with a single line, you need to add
; an extra line to it.
another-3 = <<<END_OF_TEXT
This is a multiline entry.
END_OF_TEXT
[integer]
dec = 42
hex = 0x2a

View file

@ -1,76 +0,0 @@
; testsi-UTF8-std.ini : standard UTF-8 test file for SimpleIni automated testing
;
; The number after a section or key is the order that it is defined in this file
; to make it easier to see if it has been written out correctly. This file should
; be loaded with Unicode / MultiKey / MultiLine turned on.
; This comment should be joined on to the one below it about the key
; with no section.
; Key with no section
lonely-key = nosection
another = nosection either
; This key has no value
empty =
; This should be joined with the comment below about japanese.
; Another line which will be un-indented.
; This is a section of keys showing the word Japanese in different syllabies.
[ordered-1]
a-1 = blah
; this is in kanji
japanese-2 = 日本語
; this is in hiragana
japanese-3 = にほんご
; this is in katakana
japanese-4 = ニホンゴ
; this is in romaji
japanese-5 = nihongo
; kanji as the key
日本語-6 = japanese
[multi-2]
; value a
test = a
; value b
test = b
; value c
test = c
; value d
test = d
[multiline-3]
; This is obviously a multi-line entry
multiline-1 = <<<MULTI
This is a multi-line comment. It
will continue until we have the word MULTI
on a line by itself.
日本語も。
MULTI
; This looks like multi-line, but because the newline following the last
; line is discarded, it will be converted into a single line entry.
another-2 = <<<MULTI
This is not a multiline entry.
MULTI
; If you wanted a multiline entry with a single line, you need to add
; an extra line to it.
another-3 = <<<MULTI
This is a multiline entry.
MULTI
[integer]
dec = 42
hex = 0x2a

View file

@ -1,166 +0,0 @@
// File: test1.cpp
// Library: SimpleIni
// Author: Brodie Thiesfield <code@jellycan.com>
// Source: http://code.jellycan.com/simpleini/
//
// Automated testing for SimpleIni streams
#ifdef _WIN32
# pragma warning(disable: 4786)
#endif
#ifdef _WIN32
# include <windows.h>
# define DELETE_FILE DeleteFileA
#else
# include <unistd.h>
# define DELETE_FILE unlink
#endif
#include <fstream>
#define SI_SUPPORT_IOSTREAMS
#include "SimpleIni.h"
class Test
{
std::string m_strTest;
public:
Test(const char * a_pszName)
: m_strTest(a_pszName)
{
printf("%s: test starting\n", m_strTest.c_str());
}
bool Success()
{
printf("%s: test succeeded\n", m_strTest.c_str());
return false;
}
bool Failure(const char * pszReason)
{
printf("%s: test FAILED (%s)\n", m_strTest.c_str(), pszReason);
return false;
}
};
bool FileComparisonTest(const char * a_pszFile1, const char * a_pszFile2) {
// ensure that the two files are the same
try {
std::string strFile1, strFile2;
char szBuf[1024];
FILE * fp = NULL;
#if __STDC_WANT_SECURE_LIB__
fopen_s(&fp, a_pszFile1, "rb");
#else
fp = fopen(a_pszFile1, "rb");
#endif
if (!fp) throw false;
while (!feof(fp)) {
size_t n = fread(szBuf, 1, sizeof(szBuf), fp);
strFile1.append(szBuf, n);
}
fclose(fp);
fp = NULL;
#if __STDC_WANT_SECURE_LIB__
fopen_s(&fp, a_pszFile2, "rb");
#else
fp = fopen(a_pszFile2, "rb");
#endif
if (!fp) throw false;
while (!feof(fp)) {
size_t n = fread(szBuf, 1, sizeof(szBuf), fp);
strFile2.append(szBuf, n);
}
fclose(fp);
if (strFile1 != strFile2) throw false;
}
catch (...) {
return false;
}
return true;
}
bool FileLoadTest(const char * a_pszFile1, const char * a_pszFile2) {
// ensure that the two files load into simpleini the same
CSimpleIniA ini(true, true, true);
bool b;
try {
ini.Reset();
if (ini.LoadFile(a_pszFile1) < 0) throw "Load failed for file 1";
if (ini.SaveFile("test1.ini") < 0) throw "Save failed for file 1";
ini.Reset();
if (ini.LoadFile(a_pszFile2) < 0) throw "Load failed for file 2";
if (ini.SaveFile("test2.ini") < 0) throw "Save failed for file 2";
b = FileComparisonTest("test1.ini", "test2.ini");
DELETE_FILE("test1.ini");
DELETE_FILE("test2.ini");
if (!b) throw "File comparison failed in FileLoadTest";
}
catch (...) {
return false;
}
return true;
}
bool TestStreams()
{
const char * rgszTestFile[3] = {
"test1-input.ini",
"test1-output.ini",
"test1-expected.ini"
};
Test oTest("TestStreams");
CSimpleIniW ini;
ini.SetUnicode(true);
ini.SetMultiKey(true);
ini.SetMultiLine(true);
// load the file
try {
std::ifstream instream;
instream.open(rgszTestFile[0], std::ifstream::in | std::ifstream::binary);
if (ini.LoadData(instream) < 0) throw false;
instream.close();
}
catch (...) {
return oTest.Failure("Failed to load file");
}
// standard contents test
//if (!StandardContentsTest(ini, oTest)) {
// return false;
//}
// save the file
try {
std::ofstream outfile;
outfile.open(rgszTestFile[1], std::ofstream::out | std::ofstream::binary);
if (ini.Save(outfile, true) < 0) throw false;
outfile.close();
}
catch (...) {
return oTest.Failure("Failed to save file");
}
// file comparison test
if (!FileComparisonTest(rgszTestFile[1], rgszTestFile[2])) {
return oTest.Failure("Failed file comparison");
}
if (!FileLoadTest(rgszTestFile[1], rgszTestFile[2])) {
return oTest.Failure("Failed file load comparison");
}
return oTest.Success();
}

View file

@ -1,52 +0,0 @@
; test file for SimpleIni
nosection=ok
NOSECTION=still ok
whitespace = ok
[standard]
foo=foo1
standard-1=foo
日本語=ok1
[Standard]
Foo=foo2
standard-2=foo
日本語=ok2
[ Whitespace ]
a=
[ whitespace in section name ]
whitespace in key name = whitespace in value name
; comments
; more comments
invalid
=invalid
====invalid
[Japanese]
nihongo = 日本語
日本語 = 日本語
[日本語]
nihongo = 日本語
日本語 = 日本語
[]
more=no section name
[MultiLine]
single = This is a single line.
multi = <<<MULTI
This is a multi-line value. It continues until the MULTI tag is found
on a line by itself with no whitespace before or after it. This value
will be returned to the user with all newlines and whitespace.
MULTI

View file

@ -1,51 +0,0 @@
; test file for SimpleIni
nosection=ok
NOSECTION=still ok
whitespace = ok
[standard]
foo=foo1
standard-1=foo
日本語=ok1
[Standard]
Foo=foo2
standard-2=foo
日本語=ok2
[ Whitespace ]
a=
[ whitespace in section name ]
whitespace in key name = whitespace in value name
; comments
; more comments
invalid
=invalid
====invalid
[Japanese]
nihongo = 日本語
日本語 = 日本語
[日本語]
nihongo = 日本語
日本語 = 日本語
[]
more=no section name
[MultiLine]
single = This is a single line.
multi = <<<MULTI
This is a multi-line value. It continues until the MULTI tag is found
on a line by itself with no whitespace before or after it. This value
will be returned to the user with all newlines and whitespace.
MULTI

View file

@ -1,50 +0,0 @@
; test file for SimpleIni
whitespace = ok
nosection=ok
NOSECTION=still ok
[standard]
foo=foo1
standard-1=foo
日本語=ok1
[Standard]
Foo=foo2
standard-2=foo
日本語=ok2
[ Whitespace ]
a=
[ whitespace in section name ]
whitespace in key name = whitespace in value name
; comments
; more comments
invalid
=invalid
====invalid
[Japanese]
nihongo = 日本語
日本語 = 日本語
[日本語]
nihongo = 日本語
日本語 = 日本語
[]
more=no section name
[MultiLine]
single = This is a single line.
multi = <<<MULTI
This is a multi-line value. It continues until the MULTI tag is found
on a line by itself with no whitespace before or after it. This value
will be returned to the user with all newlines and whitespace.
MULTI

View file

@ -1,315 +0,0 @@
// File: testsi.cpp
// Library: SimpleIni
// Author: Brodie Thiesfield <code@jellycan.com>
// Source: http://code.jellycan.com/simpleini/
//
// Demo of usage
#ifdef _WIN32
# pragma warning(disable: 4786)
#endif
#include <locale.h>
#include <stdio.h>
#include <cassert>
#define SI_SUPPORT_IOSTREAMS
#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
# include <fstream>
#endif
//#define SI_CONVERT_GENERIC
//#define SI_CONVERT_ICU
//#define SI_CONVERT_WIN32
#include "../SimpleIni.h"
#ifdef SI_CONVERT_ICU
// if converting using ICU then we need the ICU library
# pragma comment(lib, "icuuc.lib")
#endif
#ifdef _WIN32
# include <tchar.h>
#else // !_WIN32
# define TCHAR char
# define _T(x) x
# define _tprintf printf
# define _tmain main
#endif // _WIN32
static void
Test(
CSimpleIni & ini
)
{
const TCHAR *pszSection = 0;
const TCHAR *pItem = 0;
const TCHAR *pszVal = 0;
// get the value of the key "foo" in section "standard"
bool bHasMulti;
pszVal = ini.GetValue(_T("standard"), _T("foo"), 0, &bHasMulti);
_tprintf(_T("\n-- Value of standard::foo is '%s' (hasMulti = %d)\n"),
pszVal ? pszVal : _T("(null)"), bHasMulti);
// set the value of the key "foo" in section "standard"
ini.SetValue(_T("standard"), _T("foo"), _T("wibble"));
pszVal = ini.GetValue(_T("standard"), _T("foo"), 0, &bHasMulti);
_tprintf(_T("\n-- Value of standard::foo is '%s' (hasMulti = %d)\n"),
pszVal ? pszVal : _T("(null)"), bHasMulti);
// get all values of the key "foo" in section "standard"
CSimpleIni::TNamesDepend values;
if (ini.GetAllValues(_T("standard"), _T("foo"), values)) {
_tprintf(_T("\n-- Values of standard::foo are:\n"));
CSimpleIni::TNamesDepend::const_iterator i = values.begin();
for (; i != values.end(); ++i) {
pszVal = i->pItem;
_tprintf(_T(" -> '%s'\n"), pszVal);
}
}
// get the size of the section [standard]
_tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
ini.GetSectionSize(_T("standard")));
// delete the key "foo" in section "standard", if it has value "bar"
ini.DeleteValue(_T("standard"), _T("foo"), _T("bar"));
pszVal = ini.GetValue(_T("standard"), _T("foo"), 0);
_tprintf(_T("\n-- Value of standard::foo is now '%s'\n"),
pszVal ? pszVal : _T("(null)"));
// delete the key "foo" in section "standard"
ini.Delete(_T("standard"), _T("foo"));
pszVal = ini.GetValue(_T("standard"), _T("foo"), 0);
_tprintf(_T("\n-- Value of standard::foo is now '%s'\n"),
pszVal ? pszVal : _T("(null)"));
// get the size of the section [standard]
_tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
ini.GetSectionSize(_T("standard")));
// get the list of all key names for the section "standard"
_tprintf(_T("\n-- Dumping keys of section: [standard]\n"));
CSimpleIni::TNamesDepend keys;
ini.GetAllKeys(_T("standard"), keys);
// dump all of the key names
CSimpleIni::TNamesDepend::const_iterator iKey = keys.begin();
for ( ; iKey != keys.end(); ++iKey ) {
pItem = iKey->pItem;
_tprintf(_T("Key: %s\n"), pItem);
}
// add a decimal value
ini.SetLongValue(_T("integer"), _T("dec"), 42, NULL, false);
ini.SetLongValue(_T("integer"), _T("hex"), 42, NULL, true);
// add some bool values
ini.SetBoolValue(_T("bool"), _T("t"), true);
ini.SetBoolValue(_T("bool"), _T("f"), false);
// get the values back
assert(42 == ini.GetLongValue(_T("integer"), _T("dec")));
assert(42 == ini.GetLongValue(_T("integer"), _T("hex")));
assert(true == ini.GetBoolValue(_T("bool"), _T("t")));
assert(false == ini.GetBoolValue(_T("bool"), _T("f")));
// delete the section "standard"
ini.Delete(_T("standard"), NULL);
_tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
ini.GetSectionSize(_T("standard")));
// iterate through every section in the file
_tprintf(_T("\n-- Dumping all sections\n"));
CSimpleIni::TNamesDepend sections;
ini.GetAllSections(sections);
CSimpleIni::TNamesDepend::const_iterator iSection = sections.begin();
for ( ; iSection != sections.end(); ++iSection ) {
pszSection = iSection->pItem;
// print the section name
printf("\n");
if (*pszSection) {
_tprintf(_T("[%s]\n"), pszSection);
}
// if there are keys and values...
const CSimpleIni::TKeyVal * pSectionData = ini.GetSection(pszSection);
if (pSectionData) {
// iterate over all keys and dump the key name and value
CSimpleIni::TKeyVal::const_iterator iKeyVal = pSectionData->begin();
for ( ;iKeyVal != pSectionData->end(); ++iKeyVal) {
pItem = iKeyVal->first.pItem;
pszVal = iKeyVal->second;
_tprintf(_T("%s=%s\n"), pItem, pszVal);
}
}
}
}
#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
static bool
TestStreams(
const TCHAR * a_pszFile,
bool a_bIsUtf8,
bool a_bUseMultiKey,
bool a_bUseMultiLine
)
{
// load the file
CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine);
_tprintf(_T("Loading file: %s\n"), a_pszFile);
std::ifstream instream;
instream.open(a_pszFile, std::ifstream::in | std::ifstream::binary);
SI_Error rc = ini.LoadData(instream);
instream.close();
if (rc < 0) {
printf("Failed to open file.\n");
return false;
}
Test(ini);
// save the file (simple)
_tprintf(_T("\n-- Saving file to: testsi-out-streams.ini\n"));
std::ofstream outstream;
outstream.open("testsi-out-streams.ini", std::ofstream::out | std::ofstream::binary);
ini.Save(outstream);
outstream.close();
return true;
}
#endif // SI_SUPPORT_IOSTREAMS
static bool
TestFile(
const TCHAR * a_pszFile,
bool a_bIsUtf8,
bool a_bUseMultiKey,
bool a_bUseMultiLine
)
{
// load the file
CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine);
_tprintf(_T("Loading file: %s\n"), a_pszFile);
SI_Error rc = ini.LoadFile(a_pszFile);
if (rc < 0) {
printf("Failed to open file.\n");
return false;
}
// run the tests
Test(ini);
// save the file (simple)
_tprintf(_T("\n-- Saving file to: testsi-out.ini\n"));
ini.SaveFile("testsi-out.ini");
// save the file (with comments)
// Note: to save the file and add a comment to the beginning, use
// code such as the following.
_tprintf(_T("\n-- Saving file to: testsi-out-comment.ini\n"));
FILE * fp = NULL;
#if __STDC_WANT_SECURE_LIB__
fopen_s(&fp, "testsi-out-comment.ini", "wb");
#else
fp = fopen("testsi-out-comment.ini", "wb");
#endif
if (fp) {
CSimpleIni::FileWriter writer(fp);
if (a_bIsUtf8) {
writer.Write(SI_UTF8_SIGNATURE);
}
// add a string to the file in the correct text format
CSimpleIni::Converter convert = ini.GetConverter();
convert.ConvertToStore(_T("; output from testsi.cpp test program")
SI_NEWLINE SI_NEWLINE);
writer.Write(convert.Data());
ini.Save(writer, false);
fclose(fp);
}
return true;
}
static bool
ParseCommandLine(
int argc,
TCHAR * argv[],
const TCHAR * & a_pszFile,
bool & a_bIsUtf8,
bool & a_bUseMultiKey,
bool & a_bUseMultiLine
)
{
a_pszFile = 0;
a_bIsUtf8 = false;
a_bUseMultiKey = false;
a_bUseMultiLine = false;
for (--argc; argc > 0; --argc) {
if (argv[argc][0] == '-') {
switch (argv[argc][1]) {
case TCHAR('u'):
a_bIsUtf8 = true;
break;
case TCHAR('m'):
a_bUseMultiKey = true;
break;
case TCHAR('l'):
a_bUseMultiLine = true;
break;
}
}
else {
a_pszFile = argv[argc];
}
}
if (!a_pszFile) {
_tprintf(
_T("Usage: testsi [-u] [-m] [-l] iniFile\n")
_T(" -u Load file as UTF-8 (Default is to use system locale)\n")
_T(" -m Enable multiple keys\n")
_T(" -l Enable multiple line values\n")
);
return false;
}
return true;
}
extern bool TestStreams();
int
_tmain(
int argc,
TCHAR * argv[]
)
{
setlocale(LC_ALL, "");
// start of automated testing...
TestStreams();
// parse the command line
const TCHAR * pszFile;
bool bIsUtf8, bUseMultiKey, bUseMultiLine;
if (!ParseCommandLine(argc, argv, pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
return 1;
}
// run the test
if (!TestFile(pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
return 1;
}
#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
if (!TestStreams(pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
return 1;
}
#endif
return 0;
}

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn" version="1.8.1.7" targetFramework="native" />
</packages>

View file

@ -1,6 +0,0 @@
//
// pch.cpp
// Include the standard header and generate the precompiled header.
//
#include "pch.h"

View file

@ -1,8 +0,0 @@
//
// pch.h
// Header for standard system include files.
//
#pragma once
#include "gtest/gtest.h"

View file

@ -1,13 +0,0 @@
[section1]
key1=value1
[section2]
test2=テスト2
テスト=test
テスト2=テスト二
[検査]
key2=value2
test2=テスト2
テスト=test
テスト2=テスト二

View file

@ -1,92 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8f30a5dc-b942-4c9a-ba75-91c906ff85fa}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<ProjectName>tests</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="Shared" />
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<ItemGroup>
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ts-bugfix.cpp" />
<ClCompile Include="ts-noconvert.cpp" />
<ClCompile Include="ts-quotes.cpp" />
<ClCompile Include="ts-roundtrip.cpp" />
<ClCompile Include="ts-snippets.cpp" />
<ClCompile Include="ts-utf8.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="ts-wchar.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="example.ini" />
<None Include="Makefile" />
<None Include="packages.config" />
<None Include="tests.ini" />
</ItemGroup>
<ItemDefinitionGroup />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\vcproj\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.7\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets" Condition="Exists('..\vcproj\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.7\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')" />
</ImportGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\vcproj\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.7\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\vcproj\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.7\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets'))" />
</Target>
</Project>

View file

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="ts-bugfix.cpp">
<Filter>Test Cases</Filter>
</ClCompile>
<ClCompile Include="ts-noconvert.cpp">
<Filter>Test Cases</Filter>
</ClCompile>
<ClCompile Include="ts-quotes.cpp">
<Filter>Test Cases</Filter>
</ClCompile>
<ClCompile Include="ts-roundtrip.cpp">
<Filter>Test Cases</Filter>
</ClCompile>
<ClCompile Include="ts-snippets.cpp">
<Filter>Test Cases</Filter>
</ClCompile>
<ClCompile Include="ts-utf8.cpp">
<Filter>Test Cases</Filter>
</ClCompile>
<ClCompile Include="ts-wchar.cpp">
<Filter>Test Cases</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Other Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="example.ini">
<Filter>Other Files</Filter>
</None>
<None Include="tests.ini">
<Filter>Test Cases</Filter>
</None>
<None Include="Makefile">
<Filter>Other Files</Filter>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Filter Include="Test Cases">
<UniqueIdentifier>{8b76c482-decd-405d-abd8-98726f5c0b03}</UniqueIdentifier>
<Extensions>ts-*.cpp</Extensions>
</Filter>
<Filter Include="Other Files">
<UniqueIdentifier>{8f23fd84-666d-4e92-83de-ed431f244af0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Other Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View file

@ -1,137 +0,0 @@
#include "pch.h"
#include "../SimpleIni.h"
TEST(TestBugFix, TestEmptySection) {
CSimpleIniA ini;
ini.SetValue("foo", "skey", "sval");
ini.SetValue("", "rkey", "rval");
ini.SetValue("bar", "skey", "sval");
std::string output;
ini.Save(output);
std::string expected =
"rkey = rval\n"
"\n"
"\n"
"[foo]\n"
"skey = sval\n"
"\n"
"\n"
"[bar]\n"
"skey = sval\n";
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(expected.c_str(), output.c_str());
}
TEST(TestBugFix, TestMultiLineIgnoreTrailSpace0) {
std::string input =
"; multiline values\n"
"key = <<<EOS\n"
"This is a\n"
"multiline value\n"
"and it ends.\n"
"EOS\n"
"\n"
"[section]\n";
bool multiline = true;
CSimpleIniA ini(true, false, multiline);
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
std::string output;
ini.Save(output);
std::string expected =
"; multiline values\n"
"\n"
"\n"
"key = <<<END_OF_TEXT\n"
"This is a\n"
"multiline value\n"
"and it ends.\n"
"END_OF_TEXT\n"
"\n"
"\n"
"[section]\n";
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(expected.c_str(), output.c_str());
}
TEST(TestBugFix, TestMultiLineIgnoreTrailSpace1) {
std::string input =
"; multiline values\n"
"key = <<<EOS\n"
"This is a\n"
"multiline value\n"
"and it ends.\n"
"EOS \n"
"\n"
"[section]\n";
bool multiline = true;
CSimpleIniA ini(true, false, multiline);
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
std::string output;
ini.Save(output);
std::string expected =
"; multiline values\n"
"\n"
"\n"
"key = <<<END_OF_TEXT\n"
"This is a\n"
"multiline value\n"
"and it ends.\n"
"END_OF_TEXT\n"
"\n"
"\n"
"[section]\n";
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(expected.c_str(), output.c_str());
}
TEST(TestBugFix, TestMultiLineIgnoreTrailSpace2) {
std::string input =
"; multiline values\n"
"key = <<<EOS\n"
"This is a\n"
"multiline value\n"
"and it ends.\n"
"EOS \n"
"\n"
"[section]\n";
bool multiline = true;
CSimpleIniA ini(true, false, multiline);
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
std::string output;
ini.Save(output);
std::string expected =
"; multiline values\n"
"\n"
"\n"
"key = <<<END_OF_TEXT\n"
"This is a\n"
"multiline value\n"
"and it ends.\n"
"END_OF_TEXT\n"
"\n"
"\n"
"[section]\n";
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(expected.c_str(), output.c_str());
}

View file

@ -1,69 +0,0 @@
#include "pch.h"
#define SI_NO_CONVERSION
#include "../SimpleIni.h"
class TestNoConvert : public ::testing::Test {
protected:
void SetUp() override;
protected:
CSimpleIniA ini;
};
void TestNoConvert::SetUp() {
ini.SetUnicode();
SI_Error err = ini.LoadFile("tests.ini");
ASSERT_EQ(err, SI_OK);
}
TEST_F(TestNoConvert, TestSectionAKeyAValA) {
const char* result = ini.GetValue("section1", "key1");
ASSERT_STREQ(result, "value1");
}
TEST_F(TestNoConvert, TestSectionAKeyAValU) {
const char tesuto2[] = u8"テスト2";
const char* result = ini.GetValue("section2", "test2");
ASSERT_STREQ(result, tesuto2);
}
TEST_F(TestNoConvert, TestSectionAKeyUValA) {
const char tesuto[] = u8"テスト";
const char* result = ini.GetValue("section2", tesuto);
ASSERT_STREQ(result, "test");
}
TEST_F(TestNoConvert, TestSectionAKeyUValU) {
const char tesuto2[] = u8"テスト2";
const char tesutoni[] = u8"テスト二";
const char* result = ini.GetValue("section2", tesuto2);
ASSERT_STREQ(result, tesutoni);
}
TEST_F(TestNoConvert, TestSectionUKeyAValA) {
const char kensa[] = u8"検査";
const char* result = ini.GetValue(kensa, "key2");
ASSERT_STREQ(result, "value2");
}
TEST_F(TestNoConvert, TestSectionUKeyAValU) {
const char kensa[] = u8"検査";
const char tesuto2[] = u8"テスト2";
const char* result = ini.GetValue(kensa, "test2");
ASSERT_STREQ(result, tesuto2);
}
TEST_F(TestNoConvert, TestSectionUKeyUValA) {
const char kensa[] = u8"検査";
const char tesuto[] = u8"テスト";
const char* result = ini.GetValue(kensa, tesuto);
ASSERT_STREQ(result, "test");
}
TEST_F(TestNoConvert, TestSectionUKeyUValU) {
const char kensa[] = u8"検査";
const char tesuto2[] = u8"テスト2";
const char tesutoni[] = u8"テスト二";
const char* result = ini.GetValue(kensa, tesuto2);
ASSERT_STREQ(result, tesutoni);
}

View file

@ -1,202 +0,0 @@
#include "pch.h"
#include <algorithm>
#include "../SimpleIni.h"
class TestQuotes : public ::testing::Test {
protected:
void SetUp() override;
protected:
CSimpleIniA ini;
std::string input;
std::string expect;
std::string output;
};
void TestQuotes::SetUp() {
ini.SetUnicode();
}
TEST_F(TestQuotes, TestEmpty) {
ini.SetQuotes(true);
input =
"[section]\n"
"key1 = \"\"\n"
"key2 = \n"
;
// no need to preserve quotes for empty data
expect =
"[section]\n"
"key1 = \n"
"key2 = \n"
;
const char* result;
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
result = ini.GetValue("section", "key1");
ASSERT_STREQ(result, "");
result = ini.GetValue("section", "key2");
ASSERT_STREQ(result, "");
rc = ini.Save(output);
ASSERT_EQ(rc, SI_OK);
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(expect.c_str(), output.c_str());
}
TEST_F(TestQuotes, TestEmptyDisabled) {
ini.SetQuotes(false);
input =
"[section]\n"
"key1 = \"\"\n"
"key2 = \n"
;
const char* result;
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
result = ini.GetValue("section", "key1");
ASSERT_STREQ(result, "\"\"");
result = ini.GetValue("section", "key2");
ASSERT_STREQ(result, "");
rc = ini.Save(output);
ASSERT_EQ(rc, SI_OK);
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(input.c_str(), output.c_str());
}
TEST_F(TestQuotes, TestGeneral) {
ini.SetQuotes(true);
input =
"[section]\n"
"key1 = foo\n"
"key2 = \"foo\"\n"
"key3 = foo \n"
"key4 = \" foo \"\n"
"key5 = \"foo\n"
"key6 = foo\"\n"
"key7 = foo \" foo \n"
"key8 = \" foo \" foo \" \n"
;
expect =
"[section]\n"
"key1 = foo\n"
"key2 = foo\n"
"key3 = foo\n"
"key4 = \" foo \"\n"
"key5 = \"foo\n"
"key6 = foo\"\n"
"key7 = foo \" foo\n"
"key8 = \" foo \" foo \"\n"
;
const char* result;
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
result = ini.GetValue("section", "key1");
ASSERT_STREQ(result, "foo");
result = ini.GetValue("section", "key2");
ASSERT_STREQ(result, "foo");
result = ini.GetValue("section", "key3");
ASSERT_STREQ(result, "foo");
result = ini.GetValue("section", "key4");
ASSERT_STREQ(result, " foo ");
result = ini.GetValue("section", "key5");
ASSERT_STREQ(result, "\"foo");
result = ini.GetValue("section", "key6");
ASSERT_STREQ(result, "foo\"");
result = ini.GetValue("section", "key7");
ASSERT_STREQ(result, "foo \" foo");
result = ini.GetValue("section", "key8");
ASSERT_STREQ(result, " foo \" foo ");
rc = ini.Save(output);
ASSERT_EQ(rc, SI_OK);
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(expect.c_str(), output.c_str());
}
TEST_F(TestQuotes, TestGeneralDisabled) {
ini.SetQuotes(false);
input =
"[section]\n"
"key1 = foo\n"
"key2 = \"foo\"\n"
"key3 = foo \n"
"key4 = \" foo \"\n"
"key5 = \"foo\n"
"key6 = foo\"\n"
"key7 = foo \" foo \n"
"key8 = \" foo \" foo \" \n"
;
expect =
"[section]\n"
"key1 = foo\n"
"key2 = \"foo\"\n"
"key3 = foo\n"
"key4 = \" foo \"\n"
"key5 = \"foo\n"
"key6 = foo\"\n"
"key7 = foo \" foo\n"
"key8 = \" foo \" foo \"\n"
;
const char* result;
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
rc = ini.Save(output);
ASSERT_EQ(rc, SI_OK);
result = ini.GetValue("section", "key1");
ASSERT_STREQ(result, "foo");
result = ini.GetValue("section", "key2");
ASSERT_STREQ(result, "\"foo\"");
result = ini.GetValue("section", "key3");
ASSERT_STREQ(result, "foo");
result = ini.GetValue("section", "key4");
ASSERT_STREQ(result, "\" foo \"");
result = ini.GetValue("section", "key5");
ASSERT_STREQ(result, "\"foo");
result = ini.GetValue("section", "key6");
ASSERT_STREQ(result, "foo\"");
result = ini.GetValue("section", "key7");
ASSERT_STREQ(result, "foo \" foo");
result = ini.GetValue("section", "key8");
ASSERT_STREQ(result, "\" foo \" foo \"");
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(expect.c_str(), output.c_str());
}

View file

@ -1,246 +0,0 @@
#include "pch.h"
#include <algorithm>
#include "../SimpleIni.h"
class TestRoundTrip : public ::testing::Test {
protected:
void SetUp() override;
void TestMulti();
void TestBOM(bool useBOM);
protected:
CSimpleIniA ini;
std::string input;
std::string output;
};
void TestRoundTrip::SetUp() {
ini.SetUnicode();
}
TEST_F(TestRoundTrip, TestStandard) {
input =
"; File comment\n"
"\n"
"\n"
"; Section 1 comment\n"
"[section1]\n"
"\n"
"\n"
"; Section 2 comment\n"
"[section2]\n"
"\n"
"; key1 comment\n"
"key1 = string\n"
"\n"
"; key 2 comment\n"
"key2 = true\n"
"key3 = 3.1415\n"
;
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
const char* result = ini.GetValue("section2", "key1");
ASSERT_STREQ(result, "string");
rc = ini.Save(output);
ASSERT_EQ(rc, SI_OK);
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(input.c_str(), output.c_str());
}
void TestRoundTrip::TestMulti() {
input =
"[section]\n"
"key = string1\n"
"key = string2\n"
;
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
rc = ini.Save(output);
ASSERT_EQ(rc, SI_OK);
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
}
TEST_F(TestRoundTrip, TestMultiGood) {
ini.SetMultiKey(true);
TestMulti();
ASSERT_STREQ(input.c_str(), output.c_str());
}
TEST_F(TestRoundTrip, TestMultiBad) {
std::string expected =
"[section]\n"
"key = string2\n";
ini.SetMultiKey(false);
TestMulti();
ASSERT_STRNE(input.c_str(), output.c_str());
ASSERT_STREQ(expected.c_str(), output.c_str());
}
TEST_F(TestRoundTrip, TestSpacesTrue) {
input =
"[section]\n"
"key = string1\n";
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
ini.SetSpaces(true);
rc = ini.Save(output);
ASSERT_EQ(rc, SI_OK);
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(input.c_str(), output.c_str());
}
TEST_F(TestRoundTrip, TestSpacesFalse) {
input =
"[section]\n"
"key = string1\n";
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
ini.SetSpaces(false);
rc = ini.Save(output);
ASSERT_EQ(rc, SI_OK);
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STRNE(input.c_str(), output.c_str());
std::string expected =
"[section]\n"
"key=string1\n";
ASSERT_STREQ(expected.c_str(), output.c_str());
}
void TestRoundTrip::TestBOM(bool useBOM) {
const char bom[] = "\xEF\xBB\xBF";
const char input8[] =
u8"[テスト1]\n"
u8"テスト2 = テスト3\n";
input = bom;
input += input8;
ini.Reset();
ini.SetUnicode(false);
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
const char tesuto1[] = u8"テスト1";
const char tesuto2[] = u8"テスト2";
const char tesuto3[] = u8"テスト3";
const char* result = ini.GetValue(tesuto1, tesuto2);
ASSERT_STREQ(result, tesuto3);
rc = ini.Save(output, useBOM);
ASSERT_EQ(rc, SI_OK);
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
}
TEST_F(TestRoundTrip, TestWithBOM) {
TestBOM(true);
ASSERT_STREQ(input.c_str(), output.c_str());
}
TEST_F(TestRoundTrip, TestWithoutBOM) {
TestBOM(false);
ASSERT_STRNE(input.c_str(), output.c_str());
std::string expected(input, 3);
ASSERT_STREQ(expected.c_str(), output.c_str());
}
TEST_F(TestRoundTrip, TestAllowKeyOnly1) {
ini.SetAllowKeyOnly(false);
input =
"[section1]\n"
"key1 = string\n"
"key2 = \n"
"key3= \n"
"key4=\n"
"key5\n"
"\n"
"Never going to give you up\n"
"Never going to let you down\n"
;
std::string expect =
"[section1]\n"
"key1 = string\n"
"key2 = \n"
"key3 = \n"
"key4 = \n"
;
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
rc = ini.Save(output);
ASSERT_EQ(rc, SI_OK);
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(expect.c_str(), output.c_str());
}
TEST_F(TestRoundTrip, TestAllowKeyOnly2) {
ini.SetAllowKeyOnly(true);
input =
"[section1]\n"
"key1\n"
"key2\n"
"[section2]\n"
"key1 = string\n"
"key2 = \n"
"key3= \n"
"key4=\n"
"\n"
"key5\n"
"\n"
"Never going to give you up\n"
"\n"
"Never going to let you down\n"
;
std::string expect =
"[section1]\n"
"key1\n"
"key2\n"
"\n\n"
"[section2]\n"
"key1 = string\n"
"key2\n"
"key3\n"
"key4\n"
"key5\n"
"Never going to give you up\n"
"Never going to let you down\n"
;
SI_Error rc = ini.LoadData(input);
ASSERT_EQ(rc, SI_OK);
rc = ini.Save(output);
ASSERT_EQ(rc, SI_OK);
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end());
ASSERT_STREQ(expect.c_str(), output.c_str());
}

View file

@ -1,303 +0,0 @@
#include "pch.h"
#include "../SimpleIni.h"
// ### SIMPLE USAGE
TEST(TestSnippets, TestSimple) {
// simple demonstration
CSimpleIniA ini;
ini.SetUnicode();
SI_Error rc = ini.LoadFile("example.ini");
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_OK);
const char* pv;
pv = ini.GetValue("section", "key", "default");
ASSERT_STREQ(pv, "value");
ini.SetValue("section", "key", "newvalue");
pv = ini.GetValue("section", "key", "default");
ASSERT_STREQ(pv, "newvalue");
}
// ### LOADING DATA
TEST(TestSnippets, TestLoadFile) {
// load from a data file
CSimpleIniA ini;
SI_Error rc = ini.LoadFile("example.ini");
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_OK);
}
TEST(TestSnippets, TestLoadString) {
// load from a string
const std::string example = "[section]\nkey = value\n";
CSimpleIniA ini;
SI_Error rc = ini.LoadData(example);
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_OK);
}
// ### GETTING SECTIONS AND KEYS
TEST(TestSnippets, TestSectionsAndKeys) {
const std::string example =
"[section1]\n"
"key1 = value1\n"
"key2 = value2\n"
"\n"
"[section2]\n"
"[section3]\n";
CSimpleIniA ini;
SI_Error rc = ini.LoadData(example);
ASSERT_EQ(rc, SI_OK);
// get all sections
CSimpleIniA::TNamesDepend sections;
ini.GetAllSections(sections);
// get all keys in a section
CSimpleIniA::TNamesDepend keys;
ini.GetAllKeys("section1", keys);
const char* expectedSections[] = { "section1", "section2", "section3", nullptr };
const char* expectedKeys[] = { "key1", "key2", nullptr };
CSimpleIniA::TNamesDepend::const_iterator it;
int i;
for (i = 0, it = sections.begin(); it != sections.end(); ++i, ++it) {
ASSERT_NE(expectedSections[i], nullptr);
ASSERT_STREQ(expectedSections[i], it->pItem);
}
ASSERT_EQ(expectedSections[i], nullptr);
for (i = 0, it = keys.begin(); it != keys.end(); ++i, ++it) {
ASSERT_NE(expectedKeys[i], nullptr);
ASSERT_STREQ(expectedKeys[i], it->pItem);
}
ASSERT_EQ(expectedKeys[i], nullptr);
}
// ### GETTING VALUES
TEST(TestSnippets, TestGettingValues) {
const std::string example =
"[section1]\n"
"key1 = value1\n"
"key2 = value2.1\n"
"key2 = value2.2\n"
"\n"
"[section2]\n"
"[section3]\n";
bool utf8 = true;
bool multiKey = true;
CSimpleIniA ini(utf8, multiKey);
SI_Error rc = ini.LoadData(example);
ASSERT_EQ(rc, SI_OK);
// get the value of a key that doesn't exist
const char* pv;
pv = ini.GetValue("section1", "key99");
ASSERT_EQ(pv, nullptr);
// get the value of a key that does exist
pv = ini.GetValue("section1", "key1");
ASSERT_STREQ(pv, "value1");
// get the value of a key which may have multiple
// values. If hasMultiple is true, then there are
// multiple values and just one value has been returned
bool hasMulti;
pv = ini.GetValue("section1", "key1", nullptr, &hasMulti);
ASSERT_STREQ(pv, "value1");
ASSERT_EQ(hasMulti, false);
pv = ini.GetValue("section1", "key2", nullptr, &hasMulti);
ASSERT_STREQ(pv, "value2.1");
ASSERT_EQ(hasMulti, true);
// get all values of a key with multiple values
CSimpleIniA::TNamesDepend values;
ini.GetAllValues("section1", "key2", values);
// sort the values into a known order, in this case we want
// the original load order
values.sort(CSimpleIniA::Entry::LoadOrder());
// output all of the items
CSimpleIniA::TNamesDepend::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) {
//printf("value = '%s'\n", it->pItem);
}
int i;
const char* expectedValues[] = { "value2.1", "value2.2", nullptr };
for (i = 0, it = values.begin(); it != values.end(); ++it, ++i) {
ASSERT_NE(expectedValues[i], nullptr);
ASSERT_STREQ(expectedValues[i], it->pItem);
}
ASSERT_EQ(expectedValues[i], nullptr);
}
// ### VALUE EXISTS
TEST(TestSnippets, TestExists)
{
const std::string example =
"[section1]\n"
"key1 = value1\n"
"key2 = value2.1\n"
"key2 = value2.2\n"
"\n"
"[section2]\n"
"key1\n"
"key2\n"
"[section3]\n";
CSimpleIniA ini;
ini.SetUnicode();
ini.SetMultiKey();
ini.SetAllowKeyOnly();
SI_Error rc = ini.LoadData(example);
ASSERT_EQ(rc, SI_OK);
// check for section doesn't exist
EXPECT_FALSE(ini.SectionExists(""));
EXPECT_FALSE(ini.SectionExists("section4"));
// check for section does exist
EXPECT_TRUE(ini.SectionExists("section1"));
EXPECT_TRUE(ini.SectionExists("section2"));
EXPECT_TRUE(ini.SectionExists("section3"));
// check for key doesn't exist
EXPECT_FALSE(ini.KeyExists("", "key"));
EXPECT_FALSE(ini.KeyExists("section1", "key"));
EXPECT_FALSE(ini.KeyExists("section2", "key"));
// check for key does exist
EXPECT_TRUE(ini.KeyExists("section1", "key1"));
EXPECT_TRUE(ini.KeyExists("section1", "key2"));
EXPECT_TRUE(ini.KeyExists("section2", "key1"));
EXPECT_TRUE(ini.KeyExists("section2", "key2"));
}
// ### MODIFYING DATA
TEST(TestSnippets, TestModifyingData) {
bool utf8 = true;
bool multiKey = false;
CSimpleIniA ini(utf8, multiKey);
SI_Error rc;
// add a new section
rc = ini.SetValue("section1", nullptr, nullptr);
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_INSERTED);
// not an error to add one that already exists
rc = ini.SetValue("section1", nullptr, nullptr);
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_UPDATED);
// get the value of a key that doesn't exist
const char* pv;
pv = ini.GetValue("section2", "key1", "default-value");
ASSERT_STREQ(pv, "default-value");
// adding a key (the section will be added if needed)
rc = ini.SetValue("section2", "key1", "value1");
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_INSERTED);
// ensure it is set to expected value
pv = ini.GetValue("section2", "key1", nullptr);
ASSERT_STREQ(pv, "value1");
// change the value of a key
rc = ini.SetValue("section2", "key1", "value2");
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_UPDATED);
// ensure it is set to expected value
pv = ini.GetValue("section2", "key1", nullptr);
ASSERT_STREQ(pv, "value2");
}
// ### DELETING DATA
TEST(TestSnippets, TestDeletingData) {
const std::string example =
"[section1]\n"
"key1 = value1\n"
"key2 = value2\n"
"\n"
"[section2]\n"
"key1 = value1\n"
"key2 = value2\n"
"\n"
"[section3]\n";
bool utf8 = true;
CSimpleIniA ini(utf8);
SI_Error rc = ini.LoadData(example);
ASSERT_EQ(rc, SI_OK);
// deleting a key from a section. Optionally the entire
// section may be deleted if it is now empty.
bool done, deleteSectionIfEmpty = true;
done = ini.Delete("section1", "key1", deleteSectionIfEmpty);
ASSERT_EQ(done, true);
done = ini.Delete("section1", "key1");
ASSERT_EQ(done, false);
// deleting an entire section and all keys in it
done = ini.Delete("section2", nullptr);
ASSERT_EQ(done, true);
done = ini.Delete("section2", nullptr);
ASSERT_EQ(done, false);
}
// ### SAVING DATA
TEST(TestSnippets, TestSavingData) {
bool utf8 = true;
CSimpleIniA ini(utf8);
SI_Error rc;
// save the data to a string
std::string data;
rc = ini.Save(data);
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_OK);
// save the data back to the file
rc = ini.SaveFile("example2.ini");
if (rc < 0) { /* handle error */ };
ASSERT_EQ(rc, SI_OK);
}

View file

@ -1,67 +0,0 @@
#include "pch.h"
#include "../SimpleIni.h"
class TestUTF8 : public ::testing::Test {
protected:
void SetUp() override;
protected:
CSimpleIniA ini;
};
void TestUTF8::SetUp() {
ini.SetUnicode();
SI_Error err = ini.LoadFile("tests.ini");
ASSERT_EQ(err, SI_OK);
}
TEST_F(TestUTF8, TestSectionAKeyAValA) {
const char* result = ini.GetValue("section1", "key1");
ASSERT_STREQ(result, "value1");
}
TEST_F(TestUTF8, TestSectionAKeyAValU) {
const char tesuto2[] = u8"テスト2";
const char* result = ini.GetValue("section2", "test2");
ASSERT_STREQ(result, tesuto2);
}
TEST_F(TestUTF8, TestSectionAKeyUValA) {
const char tesuto[] = u8"テスト";
const char* result = ini.GetValue("section2", tesuto);
ASSERT_STREQ(result, "test");
}
TEST_F(TestUTF8, TestSectionAKeyUValU) {
const char tesuto2[] = u8"テスト2";
const char tesutoni[] = u8"テスト二";
const char* result = ini.GetValue("section2", tesuto2);
ASSERT_STREQ(result, tesutoni);
}
TEST_F(TestUTF8, TestSectionUKeyAValA) {
const char kensa[] = u8"検査";
const char* result = ini.GetValue(kensa, "key2");
ASSERT_STREQ(result, "value2");
}
TEST_F(TestUTF8, TestSectionUKeyAValU) {
const char kensa[] = u8"検査";
const char tesuto2[] = u8"テスト2";
const char* result = ini.GetValue(kensa, "test2");
ASSERT_STREQ(result, tesuto2);
}
TEST_F(TestUTF8, TestSectionUKeyUValA) {
const char kensa[] = u8"検査";
const char tesuto[] = u8"テスト";
const char* result = ini.GetValue(kensa, tesuto);
ASSERT_STREQ(result, "test");
}
TEST_F(TestUTF8, TestSectionUKeyUValU) {
const char kensa[] = u8"検査";
const char tesuto2[] = u8"テスト2";
const char tesutoni[] = u8"テスト二";
const char* result = ini.GetValue(kensa, tesuto2);
ASSERT_STREQ(result, tesutoni);
}

View file

@ -1,67 +0,0 @@
#include "pch.h"
#include "../SimpleIni.h"
class TestWide : public ::testing::Test {
protected:
void TestWide::SetUp() override;
protected:
CSimpleIniW ini;
};
void TestWide::SetUp() {
ini.SetUnicode();
SI_Error err = ini.LoadFile(L"tests.ini");
ASSERT_EQ(err, SI_OK);
}
TEST_F(TestWide, TestSectionAKeyAValA) {
const wchar_t* result = ini.GetValue(L"section1", L"key1");
ASSERT_STREQ(result, L"value1");
}
TEST_F(TestWide, TestSectionAKeyAValU) {
const wchar_t tesuto2[] = L"テスト2";
const wchar_t* result = ini.GetValue(L"section2", L"test2");
ASSERT_STREQ(result, tesuto2);
}
TEST_F(TestWide, TestSectionAKeyUValA) {
const wchar_t tesuto[] = L"テスト";
const wchar_t* result = ini.GetValue(L"section2", tesuto);
ASSERT_STREQ(result, L"test");
}
TEST_F(TestWide, TestSectionAKeyUValU) {
const wchar_t tesuto2[] = L"テスト2";
const wchar_t tesutoni[] = L"テスト二";
const wchar_t* result = ini.GetValue(L"section2", tesuto2);
ASSERT_STREQ(result, tesutoni);
}
TEST_F(TestWide, TestSectionUKeyAValA) {
const wchar_t kensa[] = L"検査";
const wchar_t* result = ini.GetValue(kensa, L"key2");
ASSERT_STREQ(result, L"value2");
}
TEST_F(TestWide, TestSectionUKeyAValU) {
const wchar_t kensa[] = L"検査";
const wchar_t tesuto2[] = L"テスト2";
const wchar_t* result = ini.GetValue(kensa, L"test2");
ASSERT_STREQ(result, tesuto2);
}
TEST_F(TestWide, TestSectionUKeyUValA) {
const wchar_t kensa[] = L"検査";
const wchar_t tesuto[] = L"テスト";
const wchar_t* result = ini.GetValue(kensa, tesuto);
ASSERT_STREQ(result, L"test");
}
TEST_F(TestWide, TestSectionUKeyUValU) {
const wchar_t kensa[] = L"検査";
const wchar_t tesuto2[] = L"テスト2";
const wchar_t tesutoni[] = L"テスト二";
const wchar_t* result = ini.GetValue(kensa, tesuto2);
ASSERT_STREQ(result, tesutoni);
}

View file

@ -1,46 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32804.467
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Library Files", "Library Files", "{C1F8A145-78E7-42C6-95D5-23C746C2BC56}"
ProjectSection(SolutionItems) = preProject
..\ConvertUTF.c = ..\ConvertUTF.c
..\ConvertUTF.h = ..\ConvertUTF.h
..\ConvertUTF_readme.txt = ..\ConvertUTF_readme.txt
..\SimpleIni.h = ..\SimpleIni.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Information Files", "Information Files", "{E40DD170-6D17-49D2-9BB2-8546658F0A37}"
ProjectSection(SolutionItems) = preProject
..\LICENCE.txt = ..\LICENCE.txt
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Other Files", "Other Files", "{560B512C-6D1C-4E65-83C1-049110E5DEF6}"
ProjectSection(SolutionItems) = preProject
..\Makefile = ..\Makefile
..\other\package.cmd = ..\other\package.cmd
..\other\simpleini.doxy = ..\other\simpleini.doxy
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "..\tests\tests.vcxproj", "{8F30A5DC-B942-4C9A-BA75-91C906FF85FA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8F30A5DC-B942-4C9A-BA75-91C906FF85FA}.Debug|x64.ActiveCfg = Debug|x64
{8F30A5DC-B942-4C9A-BA75-91C906FF85FA}.Debug|x64.Build.0 = Debug|x64
{8F30A5DC-B942-4C9A-BA75-91C906FF85FA}.Release|x64.ActiveCfg = Release|x64
{8F30A5DC-B942-4C9A-BA75-91C906FF85FA}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {ABD2CECE-EA8B-455B-8AE7-00E499634EC2}
EndGlobalSection
EndGlobal

View file

@ -1,148 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{9a59fc4f-ad32-4bd3-b6b5-9bb0ddc6138d}</ProjectGuid>
<RootNamespace>SimpleIni</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\tests\snippets.cpp" />
<ClCompile Include="..\tests\testsi.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Tests">
<UniqueIdentifier>{353054bc-f2a3-46d2-a9cb-df767fe52289}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\tests\snippets.cpp">
<Filter>Tests</Filter>
</ClCompile>
<ClCompile Include="..\tests\testsi.cpp">
<Filter>Tests</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -151,7 +151,7 @@ android {
create("genshinSpoof") {
dimension = "version"
resValue("string", "app_name_suffixed", "Eden Optimised")
applicationId = "com.miHoYo.Yuanshen"
applicationId = "com.miHoYo.Yuanshen"
}
}
}
@ -175,7 +175,10 @@ android {
"-DYUZU_USE_CPM=ON",
"-DYUZU_USE_BUNDLED_FFMPEG=ON",
"-DYUZU_ENABLE_LTO=ON",
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
"-DBUILD_TESTING=OFF",
"-DYUZU_TESTS=OFF",
"-DDYNARMIC_TESTS=OFF"
)
abiFilters("arm64-v8a")

View file

@ -18,6 +18,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
USE_FAST_CPU_TIME("use_fast_cpu_time"),
USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
USE_DOCKED_MODE("use_docked_mode"),
USE_AUTO_STUB("use_auto_stub"),
RENDERER_USE_DISK_SHADER_CACHE("use_disk_shader_cache"),
@ -26,6 +27,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
RENDERER_FAST_GPU("use_fast_gpu_time"),
RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"),
RENDERER_EARLY_RELEASE_FENCES("early_release_fences"),
SYNC_MEMORY_OPERATIONS("sync_memory_operations"),
BUFFER_REORDER_DISABLE("disable_buffer_reorder"),
RENDERER_DEBUG("debug"),
RENDERER_PROVOKING_VERTEX("provoking_vertex"),
@ -64,10 +66,11 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
SHOW_POWER_INFO("show_power_info"),
SHOW_SHADERS_BUILDING("show_shaders_building"),
DEBUG_FLUSH_BY_LINE("flush_lines"),
DEBUG_FLUSH_BY_LINE("flush_line"),
USE_LRU_CACHE("use_lru_cache");
external fun isRaiiEnabled(): Boolean
// external fun isFrameSkippingEnabled(): Boolean
external fun isFrameInterpolationEnabled(): Boolean

View file

@ -27,6 +27,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
RENDERER_SCREEN_LAYOUT("screen_layout"),
RENDERER_ASPECT_RATIO("aspect_ratio"),
RENDERER_OPTIMIZE_SPIRV_OUTPUT("optimize_spirv_output"),
DMA_ACCURACY("dma_accuracy"),
AUDIO_OUTPUT_ENGINE("output_engine"),
MAX_ANISOTROPY("max_anisotropy"),
THEME("theme"),
@ -58,7 +59,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
OFFLINE_WEB_APPLET("offline_web_applet_mode"),
LOGIN_SHARE_APPLET("login_share_applet_mode"),
WIFI_WEB_AUTH_APPLET("wifi_web_auth_applet_mode"),
MY_PAGE_APPLET("my_page_applet_mode"),
MY_PAGE_APPLET("my_page_applet_mode")
;
override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal)

View file

@ -274,7 +274,6 @@ abstract class SettingsItem(
descriptionId = R.string.use_sync_core_description
)
)
put(
SingleChoiceSetting(
IntSetting.REGION_INDEX,
@ -603,6 +602,15 @@ abstract class SettingsItem(
valuesId = R.array.optimizeSpirvOutputValues
)
)
put(
SingleChoiceSetting(
IntSetting.DMA_ACCURACY,
titleId = R.string.dma_accuracy,
descriptionId = R.string.dma_accuracy_description,
choicesId = R.array.dmaAccuracyNames,
valuesId = R.array.dmaAccuracyValues
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS,
@ -665,6 +673,13 @@ abstract class SettingsItem(
descriptionId = R.string.skip_cpu_inner_invalidation_description
)
)
put(
SwitchSetting(
BooleanSetting.CPUOPT_UNSAFE_HOST_MMU,
titleId = R.string.cpuopt_unsafe_host_mmu,
descriptionId = R.string.cpuopt_unsafe_host_mmu_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_REACTIVE_FLUSHING,
@ -679,6 +694,13 @@ abstract class SettingsItem(
descriptionId = R.string.renderer_early_release_fences_description
)
)
put(
SwitchSetting(
BooleanSetting.SYNC_MEMORY_OPERATIONS,
titleId = R.string.sync_memory_operations,
descriptionId = R.string.sync_memory_operations_description
)
)
put(
SwitchSetting(
BooleanSetting.BUFFER_REORDER_DISABLE,

View file

@ -448,6 +448,7 @@ class SettingsFragmentPresenter(
add(HeaderSetting(R.string.veil_renderer))
add(BooleanSetting.ENABLE_RAII.key)
add(BooleanSetting.RENDERER_EARLY_RELEASE_FENCES.key)
add(IntSetting.DMA_ACCURACY.key)
add(BooleanSetting.BUFFER_REORDER_DISABLE.key)
add(BooleanSetting.FRAME_INTERPOLATION.key)
add(BooleanSetting.RENDERER_FAST_GPU.key)
@ -465,8 +466,10 @@ class SettingsFragmentPresenter(
add(BooleanSetting.USE_CUSTOM_CPU_TICKS.key)
add(IntSetting.CPU_TICKS.key)
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
add(BooleanSetting.CPUOPT_UNSAFE_HOST_MMU.key)
add(BooleanSetting.USE_LRU_CACHE.key)
add(BooleanSetting.CORE_SYNC_CORE_SPEED.key)
add(BooleanSetting.SYNC_MEMORY_OPERATIONS.key)
add(IntSetting.MEMORY_LAYOUT.key)
}
}

View file

@ -96,6 +96,7 @@ class AboutFragment : Fragment() {
binding.buttonDiscord.setOnClickListener { openLink(getString(R.string.discord_link)) }
binding.buttonRevolt.setOnClickListener { openLink(getString(R.string.revolt_link)) }
binding.buttonX.setOnClickListener { openLink(getString(R.string.x_link)) }
binding.buttonWebsite.setOnClickListener { openLink(getString(R.string.website_link)) }
binding.buttonGithub.setOnClickListener { openLink(getString(R.string.github_link)) }

View file

@ -174,7 +174,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
game = gameToUse
} catch (e: Exception) {
Log.error("[EmulationFragment] Error during game setup: ${e.message}")
Toast.makeText(
@ -193,10 +192,14 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
game?.let { gameInstance ->
val customConfigFile = SettingsFile.getCustomSettingsFile(gameInstance)
if (customConfigFile.exists()) {
Log.info("[EmulationFragment] Found existing custom settings for ${gameInstance.title}, loading them")
Log.info(
"[EmulationFragment] Found existing custom settings for ${gameInstance.title}, loading them"
)
SettingsFile.loadCustomConfig(gameInstance)
} else {
Log.info("[EmulationFragment] No custom settings found for ${gameInstance.title}, using global settings")
Log.info(
"[EmulationFragment] No custom settings found for ${gameInstance.title}, using global settings"
)
NativeConfig.reloadGlobalConfig()
}
} ?: run {
@ -225,7 +228,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
try {
NativeConfig.reloadGlobalConfig()
} catch (fallbackException: Exception) {
Log.error("[EmulationFragment] Critical error: could not load global config: ${fallbackException.message}")
Log.error(
"[EmulationFragment] Critical error: could not load global config: ${fallbackException.message}"
)
throw fallbackException
}
}
@ -233,7 +238,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
emulationState = EmulationState(game!!.path) {
return@EmulationState driverViewModel.isInteractionAllowed.value
}
}
/**
@ -333,10 +337,14 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
val customConfigFile = SettingsFile.getCustomSettingsFile(foundGame)
if (customConfigFile.exists()) {
Log.info("[EmulationFragment] Found existing custom settings for ${foundGame.title}, loading them")
Log.info(
"[EmulationFragment] Found existing custom settings for ${foundGame.title}, loading them"
)
SettingsFile.loadCustomConfig(foundGame)
} else {
Log.info("[EmulationFragment] No custom settings found for ${foundGame.title}, using global settings")
Log.info(
"[EmulationFragment] No custom settings found for ${foundGame.title}, using global settings"
)
}
Toast.makeText(
@ -352,7 +360,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
withContext(Dispatchers.Main) {
try {
finishGameSetup()
Log.info("[EmulationFragment] Game setup complete for intent launch")
Log.info(
"[EmulationFragment] Game setup complete for intent launch"
)
if (_binding != null) {
// Hide loading indicator immediately for intent launches
@ -365,12 +375,16 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
binding.root.post {
if (binding.surfaceEmulation.holder.surface?.isValid == true && !emulationStarted) {
emulationStarted = true
emulationState.newSurface(binding.surfaceEmulation.holder.surface)
emulationState.newSurface(
binding.surfaceEmulation.holder.surface
)
}
}
}
} catch (e: Exception) {
Log.error("[EmulationFragment] Error in finishGameSetup: ${e.message}")
Log.error(
"[EmulationFragment] Error in finishGameSetup: ${e.message}"
)
requireActivity().finish()
return@withContext
}
@ -477,7 +491,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
if (game == null) {
Log.warning("[EmulationFragment] Game not yet initialized in onViewCreated - will be set up by async intent handler")
Log.warning(
"[EmulationFragment] Game not yet initialized in onViewCreated - will be set up by async intent handler"
)
return
}

View file

@ -18,6 +18,13 @@ import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import android.net.Uri
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.yuzu.yuzu_emu.databinding.DialogProgressBinding
import android.view.LayoutInflater
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import kotlinx.coroutines.CoroutineScope
object CustomSettingsHandler {
const val CUSTOM_CONFIG_ACTION = "dev.eden.eden_emulator.LAUNCH_WITH_CUSTOM_CONFIG"
@ -44,7 +51,9 @@ object CustomSettingsHandler {
// Check if config already exists - this should be handled by the caller
val configFile = getConfigFile(game)
if (configFile.exists()) {
Log.warning("[CustomSettingsHandler] Config file already exists for game: ${game.title}")
Log.warning(
"[CustomSettingsHandler] Config file already exists for game: ${game.title}"
)
}
// Write the config file
@ -121,37 +130,158 @@ object CustomSettingsHandler {
// Check if driver exists in the driver storage
val driverFile = File(driverPath)
if (!driverFile.exists()) {
Log.error("[CustomSettingsHandler] Required driver not found: $driverPath")
Toast.makeText(
activity,
activity.getString(
R.string.custom_settings_failed_message,
game.title,
activity.getString(R.string.driver_not_found, driverFile.name)
),
Toast.LENGTH_LONG
).show()
// Don't write config if driver is missing
return null
}
Log.info("[CustomSettingsHandler] Driver not found locally: ${driverFile.name}")
// Verify it's a valid driver
val metadata = GpuDriverHelper.getMetadataFromZip(driverFile)
if (metadata.name == null) {
Log.error("[CustomSettingsHandler] Invalid driver file: $driverPath")
Toast.makeText(
activity,
activity.getString(
R.string.custom_settings_failed_message,
game.title,
activity.getString(R.string.invalid_driver_file, driverFile.name)
),
Toast.LENGTH_LONG
).show()
return null
}
// Ask user if they want to download the missing driver
val shouldDownload = askUserToDownloadDriver(activity, driverFile.name)
if (!shouldDownload) {
Log.info("[CustomSettingsHandler] User declined to download driver")
Toast.makeText(
activity,
activity.getString(R.string.driver_download_cancelled),
Toast.LENGTH_SHORT
).show()
return null
}
Log.info("[CustomSettingsHandler] Driver verified: ${metadata.name}")
// Check network connectivity after user consent
if (!DriverResolver.isNetworkAvailable(activity)) {
Log.error("[CustomSettingsHandler] No network connection available")
Toast.makeText(
activity,
activity.getString(R.string.network_unavailable),
Toast.LENGTH_LONG
).show()
return null
}
Log.info("[CustomSettingsHandler] User approved, downloading driver")
// Show progress dialog for driver download
val dialogBinding = DialogProgressBinding.inflate(LayoutInflater.from(activity))
dialogBinding.progressBar.isIndeterminate = false
dialogBinding.title.text = activity.getString(R.string.installing_driver)
dialogBinding.status.text = activity.getString(R.string.downloading)
val progressDialog = MaterialAlertDialogBuilder(activity)
.setView(dialogBinding.root)
.setCancelable(false)
.create()
withContext(Dispatchers.Main) {
progressDialog.show()
}
try {
// Set up progress channel for thread-safe UI updates
val progressChannel = Channel<Int>(Channel.CONFLATED)
val progressJob = CoroutineScope(Dispatchers.Main).launch {
for (progress in progressChannel) {
dialogBinding.progressBar.progress = progress
}
}
// Attempt to download and install the driver
val driverUri = DriverResolver.ensureDriverAvailable(driverPath, activity) { progress ->
progressChannel.trySend(progress.toInt())
}
progressChannel.close()
progressJob.cancel()
withContext(Dispatchers.Main) {
progressDialog.dismiss()
}
if (driverUri == null) {
Log.error(
"[CustomSettingsHandler] Failed to download driver: ${driverFile.name}"
)
Toast.makeText(
activity,
activity.getString(
R.string.custom_settings_failed_message,
game.title,
activity.getString(R.string.driver_not_found, driverFile.name)
),
Toast.LENGTH_LONG
).show()
return null
}
// Verify the downloaded driver
val installedFile = File(driverPath)
val metadata = GpuDriverHelper.getMetadataFromZip(installedFile)
if (metadata.name == null) {
Log.error(
"[CustomSettingsHandler] Downloaded driver is invalid: $driverPath"
)
Toast.makeText(
activity,
activity.getString(
R.string.custom_settings_failed_message,
game.title,
activity.getString(
R.string.invalid_driver_file,
driverFile.name
)
),
Toast.LENGTH_LONG
).show()
return null
}
// Add to driver list
driverViewModel.onDriverAdded(Pair(driverPath, metadata))
Log.info(
"[CustomSettingsHandler] Successfully downloaded and installed driver: ${metadata.name}"
)
Toast.makeText(
activity,
activity.getString(
R.string.successfully_installed,
metadata.name ?: driverFile.name
),
Toast.LENGTH_SHORT
).show()
} catch (e: Exception) {
withContext(Dispatchers.Main) {
progressDialog.dismiss()
}
Log.error("[CustomSettingsHandler] Error downloading driver: ${e.message}")
Toast.makeText(
activity,
activity.getString(
R.string.custom_settings_failed_message,
game.title,
e.message ?: activity.getString(
R.string.driver_not_found,
driverFile.name
)
),
Toast.LENGTH_LONG
).show()
return null
}
} else {
// Driver exists, verify it's valid
val metadata = GpuDriverHelper.getMetadataFromZip(driverFile)
if (metadata.name == null) {
Log.error("[CustomSettingsHandler] Invalid driver file: $driverPath")
Toast.makeText(
activity,
activity.getString(
R.string.custom_settings_failed_message,
game.title,
activity.getString(R.string.invalid_driver_file, driverFile.name)
),
Toast.LENGTH_LONG
).show()
return null
}
Log.info("[CustomSettingsHandler] Driver verified: ${metadata.name}")
}
}
}
@ -290,6 +420,29 @@ object CustomSettingsHandler {
}
}
/**
* Ask user if they want to download a missing driver
*/
private suspend fun askUserToDownloadDriver(activity: FragmentActivity, driverName: String): Boolean {
return suspendCoroutine { continuation ->
activity.runOnUiThread {
MaterialAlertDialogBuilder(activity)
.setTitle(activity.getString(R.string.driver_missing_title))
.setMessage(
activity.getString(R.string.driver_missing_message, driverName)
)
.setPositiveButton(activity.getString(R.string.download)) { _, _ ->
continuation.resume(true)
}
.setNegativeButton(activity.getString(R.string.cancel)) { _, _ ->
continuation.resume(false)
}
.setCancelable(false)
.show()
}
}
}
/**
* Extract driver path from custom settings INI content
*/

View file

@ -0,0 +1,371 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.utils
import android.content.Context
import android.net.Uri
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import org.yuzu.yuzu_emu.fragments.DriverFetcherFragment
import java.io.File
import java.io.IOException
import java.util.concurrent.TimeUnit
import java.util.concurrent.ConcurrentHashMap
import okhttp3.ConnectionPool
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import kotlinx.coroutines.delay
import kotlin.math.pow
/**
* Resolves driver download URLs from filenames by searching GitHub repositories
*/
object DriverResolver {
private const val CONNECTION_TIMEOUT_SECONDS = 30L
private const val CACHE_DURATION_MS = 3600000L // 1 hour
private const val BUFFER_SIZE = 8192
private const val MIN_API_CALL_INTERVAL = 2000L // 2 seconds between API calls
private const val MAX_RETRY_COUNT = 3
@Volatile
private var client: OkHttpClient? = null
private fun getClient(): OkHttpClient {
return client ?: synchronized(this) {
client ?: OkHttpClient.Builder()
.connectTimeout(CONNECTION_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.readTimeout(CONNECTION_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.writeTimeout(CONNECTION_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.followRedirects(true)
.followSslRedirects(true)
.connectionPool(ConnectionPool(5, 1, TimeUnit.MINUTES))
.build().also { client = it }
}
}
// Driver repository paths - (from DriverFetcherFragment) might extract these to a config file later
private val repositories = listOf(
"MrPurple666/purple-turnip",
"crueter/GameHub-8Elite-Drivers",
"K11MCH1/AdrenoToolsDrivers",
"Weab-chan/freedreno_turnip-CI"
)
private val urlCache = ConcurrentHashMap<String, ResolvedDriver>()
private val releaseCache = ConcurrentHashMap<String, List<DriverFetcherFragment.Release>>()
private var lastCacheTime = 0L
private var lastApiCallTime = 0L
data class ResolvedDriver(
val downloadUrl: String,
val repoPath: String,
val releaseTag: String,
val filename: String
)
/**
* Resolve a driver download URL from its filename
* @param filename The driver filename (e.g., "turnip_mrpurple-T19-toasted.adpkg.zip")
* @return ResolvedDriver with download URL and metadata, or null if not found
*/
suspend fun resolveDriverUrl(filename: String): ResolvedDriver? {
// Validate input
require(filename.isNotBlank()) { "Filename cannot be blank" }
require(!filename.contains("..")) { "Invalid filename: path traversal detected" }
// Check cache first
urlCache[filename]?.let {
Log.info("[DriverResolver] Found cached URL for $filename")
return it
}
Log.info("[DriverResolver] Resolving download URL for: $filename")
// Clear cache if expired
if (System.currentTimeMillis() - lastCacheTime > CACHE_DURATION_MS) {
releaseCache.clear()
lastCacheTime = System.currentTimeMillis()
}
return coroutineScope {
// Search all repositories in parallel
repositories.map { repoPath ->
async {
searchRepository(repoPath, filename)
}
}.mapNotNull { it.await() }.firstOrNull().also { resolved ->
// Cache the result if found
resolved?.let {
urlCache[filename] = it
Log.info("[DriverResolver] Cached resolution for $filename from ${it.repoPath}")
}
}
}
}
/**
* Search a specific repository for a driver file
*/
private suspend fun searchRepository(repoPath: String, filename: String): ResolvedDriver? {
return withContext(Dispatchers.IO) {
try {
// Get releases from cache or fetch
val releases = releaseCache[repoPath] ?: fetchReleases(repoPath).also {
releaseCache[repoPath] = it
}
// Search through all releases and artifacts
for (release in releases) {
for (artifact in release.artifacts) {
if (artifact.name == filename) {
Log.info(
"[DriverResolver] Found $filename in $repoPath/${release.tagName}"
)
return@withContext ResolvedDriver(
downloadUrl = artifact.url.toString(),
repoPath = repoPath,
releaseTag = release.tagName,
filename = filename
)
}
}
}
null
} catch (e: Exception) {
Log.error("[DriverResolver] Failed to search $repoPath: ${e.message}")
null
}
}
}
/**
* Fetch releases from a GitHub repository
*/
private suspend fun fetchReleases(repoPath: String): List<DriverFetcherFragment.Release> = withContext(
Dispatchers.IO
) {
// Rate limiting
val timeSinceLastCall = System.currentTimeMillis() - lastApiCallTime
if (timeSinceLastCall < MIN_API_CALL_INTERVAL) {
delay(MIN_API_CALL_INTERVAL - timeSinceLastCall)
}
lastApiCallTime = System.currentTimeMillis()
// Retry logic with exponential backoff
var retryCount = 0
var lastException: Exception? = null
while (retryCount < MAX_RETRY_COUNT) {
try {
val request = Request.Builder()
.url("https://api.github.com/repos/$repoPath/releases")
.header("Accept", "application/vnd.github.v3+json")
.build()
return@withContext getClient().newCall(request).execute().use { response ->
when {
response.code == 404 -> throw IOException("Repository not found: $repoPath")
response.code == 403 -> {
val resetTime = response.header("X-RateLimit-Reset")?.toLongOrNull() ?: 0
throw IOException(
"API rate limit exceeded. Resets at ${java.util.Date(
resetTime * 1000
)}"
)
}
!response.isSuccessful -> throw IOException(
"HTTP ${response.code}: ${response.message}"
)
}
val body = response.body?.string()
?: throw IOException("Empty response from $repoPath")
// Determine if this repo uses tag names (from DriverFetcherFragment logic)
val useTagName = repoPath.contains("K11MCH1")
val sortMode = if (useTagName) {
DriverFetcherFragment.SortMode.PublishTime
} else {
DriverFetcherFragment.SortMode.Default
}
DriverFetcherFragment.Release.fromJsonArray(body, useTagName, sortMode)
}
} catch (e: IOException) {
lastException = e
if (retryCount == MAX_RETRY_COUNT - 1) throw e
delay((2.0.pow(retryCount) * 1000).toLong())
retryCount++
}
}
throw lastException ?: IOException(
"Failed to fetch releases after $MAX_RETRY_COUNT attempts"
)
}
/**
* Download a driver file to the cache directory
* @param resolvedDriver The resolved driver information
* @param context Android context for cache directory
* @return The downloaded file, or null if download failed
*/
suspend fun downloadDriver(
resolvedDriver: ResolvedDriver,
context: Context,
onProgress: ((Float) -> Unit)? = null
): File? {
return withContext(Dispatchers.IO) {
try {
Log.info(
"[DriverResolver] Downloading ${resolvedDriver.filename} from ${resolvedDriver.repoPath}"
)
val cacheDir = context.externalCacheDir ?: throw IOException("Failed to access cache directory")
cacheDir.mkdirs()
val file = File(cacheDir, resolvedDriver.filename)
// If file already exists in cache and has content, return it
if (file.exists() && file.length() > 0) {
Log.info("[DriverResolver] Using cached file: ${file.absolutePath}")
return@withContext file
}
val request = Request.Builder()
.url(resolvedDriver.downloadUrl)
.header("Accept", "application/octet-stream")
.build()
getClient().newCall(request).execute().use { response ->
if (!response.isSuccessful) {
throw IOException("Download failed: ${response.code}")
}
response.body?.use { body ->
val contentLength = body.contentLength()
body.byteStream().use { input ->
file.outputStream().use { output ->
val buffer = ByteArray(BUFFER_SIZE)
var totalBytesRead = 0L
var bytesRead: Int
while (input.read(buffer).also { bytesRead = it } != -1) {
output.write(buffer, 0, bytesRead)
totalBytesRead += bytesRead
if (contentLength > 0) {
val progress = (totalBytesRead.toFloat() / contentLength) * 100f
onProgress?.invoke(progress)
}
}
}
}
} ?: throw IOException("Empty response body")
}
if (file.length() == 0L) {
file.delete()
throw IOException("Downloaded file is empty")
}
Log.info(
"[DriverResolver] Successfully downloaded ${file.length()} bytes to ${file.absolutePath}"
)
file
} catch (e: Exception) {
Log.error("[DriverResolver] Download failed: ${e.message}")
null
}
}
}
/**
* Download and install a driver if not already present
* @param driverPath The driver filename or full path
* @param context Android context
* @param onProgress Optional progress callback (0-100)
* @return Uri of the installed driver, or null if failed
*/
suspend fun ensureDriverAvailable(
driverPath: String,
context: Context,
onProgress: ((Float) -> Unit)? = null
): Uri? {
// Extract filename from path
val filename = driverPath.substringAfterLast('/')
// Check if driver already exists locally
val localPath = "${GpuDriverHelper.driverStoragePath}$filename"
val localFile = File(localPath)
if (localFile.exists() && localFile.length() > 0) {
Log.info("[DriverResolver] Driver already exists locally: $localPath")
return Uri.fromFile(localFile)
}
Log.info("[DriverResolver] Driver not found locally, attempting to download: $filename")
// Resolve download URL
val resolvedDriver = resolveDriverUrl(filename)
if (resolvedDriver == null) {
Log.error("[DriverResolver] Failed to resolve download URL for $filename")
return null
}
// Download the driver with progress callback
val downloadedFile = downloadDriver(resolvedDriver, context, onProgress)
if (downloadedFile == null) {
Log.error("[DriverResolver] Failed to download driver $filename")
return null
}
// Install the driver to internal storage
val downloadedUri = Uri.fromFile(downloadedFile)
if (GpuDriverHelper.copyDriverToInternalStorage(downloadedUri)) {
Log.info("[DriverResolver] Successfully installed driver to internal storage")
// Clean up cache file
downloadedFile.delete()
return Uri.fromFile(File(localPath))
} else {
Log.error("[DriverResolver] Failed to copy driver to internal storage")
downloadedFile.delete()
return null
}
}
/**
* Check network connectivity
*/
fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
?: return false
val network = connectivityManager.activeNetwork ?: return false
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
}
/**
* Clear all caches
*/
fun clearCache() {
urlCache.clear()
releaseCache.clear()
lastCacheTime = 0L
lastApiCallTime = 0L
}
/**
* Clean up resources
*/
fun cleanup() {
client?.dispatcher?.executorService?.shutdown()
client?.connectionPool?.evictAll()
client = null
clearCache()
}
}

View file

@ -52,8 +52,10 @@ class GradientBorderCardView @JvmOverloads constructor(
if (isEdenTheme) {
// Gradient for Eden theme
borderPaint.shader = LinearGradient(
0f, 0f,
w.toFloat(), h.toFloat(),
0f,
0f,
w.toFloat(),
h.toFloat(),
context.getColor(R.color.eden_border_gradient_start),
context.getColor(R.color.eden_border_gradient_end),
Shader.TileMode.CLAMP
@ -62,7 +64,11 @@ class GradientBorderCardView @JvmOverloads constructor(
// Solid color for other themes
borderPaint.shader = null
val typedValue = android.util.TypedValue()
context.theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValue, true)
context.theme.resolveAttribute(
com.google.android.material.R.attr.colorPrimary,
typedValue,
true
)
borderPaint.color = typedValue.data
}

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="120"
android:viewportHeight="120">
<path
android:fillColor="#000000"
android:pathData="M95.26,0H113L72.12,51.27L120,120H82.83L53.89,78.31L20.57,120H2.7L45.74,65.01L0,0H38.18L65.22,38.9Z" />
</vector>

View file

@ -230,6 +230,17 @@
app:iconSize="24dp"
app:iconPadding="0dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_x"
style="@style/EdenButton.Secondary"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginEnd="12dp"
app:icon="@drawable/ic_x"
app:iconGravity="textStart"
app:iconSize="24dp"
app:iconPadding="0dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_website"
style="@style/EdenButton.Secondary"

View file

@ -225,6 +225,18 @@
app:iconGravity="textStart"
app:iconPadding="0dp" />
<com.google.android.material.button.MaterialButton
style="@style/EdenButton.Secondary"
android:id="@+id/button_x"
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_weight="1"
android:layout_marginEnd="8dp"
app:icon="@drawable/ic_x"
app:iconSize="24dp"
app:iconGravity="textStart"
app:iconPadding="0dp" />
<com.google.android.material.button.MaterialButton
style="@style/EdenButton.Secondary"
android:id="@+id/button_website"

View file

@ -77,12 +77,14 @@
<string name="frame_interpolation_description">يضمن تسليمًا سلسًا ومتناسقًا للإطارات من خلال مزامنة التوقيت بينها، مما يقلل من التقطيع وعدم انتظام الحركة. مثالي للألعاب التي تعاني من عدم استقرار في توقيت الإطارات أو تقطع دقيق أثناء اللعب.</string>
<string name="renderer_early_release_fences">إطلاق الأسوار مبكرًا</string>
<string name="renderer_early_release_fences_description">يساعد في إصلاح مشكلة 0 إطار في الثانية في ألعاب مثل DKCR:HD وSubnautica Below Zero وOri 2، ولكن قد يتسبب في تعطيل التحميل أو الأداء في ألعاب Unreal Engine.</string>
<string name="sync_memory_operations">مزامنة عمليات الذاكرة</string>
<string name="sync_memory_operations_description">يضمن اتساق البيانات بين عمليات الحوسبة والذاكرة. هذا الخيار قد يحل المشكلات في بعض الألعاب، ولكن قد يقلل الأداء في بعض الحالات. يبدو أن الألعاب التي تستخدم Unreal Engine 4 هي الأكثر تأثرًا.</string>
<string name="buffer_reorder_disable">تعطيل إعادة ترتيب المخزن المؤقت</string>
<string name="buffer_reorder_disable_description">عند التحديد، يتم تعطيل إعادة ترتيب تحميل الذاكرة المعينة مما يسمح بربط التحميلات برسومات محددة. قد يقلل الأداء في بعض الحالات.</string>
<string name="use_lru_cache">تمكين ذاكرة التخزين المؤقت LRU</string>
<string name="use_lru_cache_description">تمكين أو تعطيل ذاكرة التخزين المؤقت الأقل استخداماً مؤخراً (LRU) لتحسين الأداء عن طريق تقليل استخدام وحدة المعالجة المركزية. بعض الألعاب قد تواجه مشاكل معه، خاصةً TotK 1.2.1، لذا قم بتعطيله إذا لم تعمل اللعبة أو انهارت عشوائياً.</string>
<string name="dyna_state">الحالة الديناميكية الممتدة</string>
<string name="dyna_state_description">تمكين ميزات فولكان لتحسين الأداء، العرض، وتوفير الموارد أثناء إنشاء خطوط المعالجة مع الحفاظ على استهلاك منخفض لوحدة المعالجة المركزية/وحدة معالجة الرسومات. هذه الامتدادات قد تزيد من حرارة الجهاز، ووحدات معالجة الرسومات من سلسلة A6XX القديمة قد لا تعمل بشكل صحيح. قم بتعطيله لمحاكاة الصيغ المضبوطة.</string>
<string name="dyna_state_description">يتحكم في عدد الميزات التي يمكن استخدامها في الحالة الديناميكية الممتدة. الأرقام الأعلى تسمح بالمزيد من Мيزات ويمكن أن تزيد الأداء، ولكن قد تسبب مشاكل مع بعض برامج التشغيل والبائعين. قد تختلف القيمة الافتراضية اعتمادًا على نظامك وقدرات硬件. يمكن تغيير هذه القيمة حتى يتم تحقيق الاستقرار وجودة بصرية أفضل.</string>
<string name="disabled">معطل</string>
<string name="use_sync_core">مزامنة سرعة النواة</string>
<string name="use_sync_core_description">مزامنة سرعة النواة مع النسبة القصوى للسرعة لتحسين الأداء دون تغيير السرعة الفعلية للعبة.</string>
@ -108,11 +110,17 @@
<string name="memory_layout_description">(تجريبي) تغيير تخطيط الذاكرة المحاكاة. هذا الإعداد لن يزيد الأداء، ولكن قد يساعد في الألعاب التي تستخدم دقة عالية عبر التعديلات. لا تستخدم على الهواتف التي تحتوي على 8 جيجابايت من الذاكرة العشوائية أو أقل.</string>
<string name="sample_shading">تظليل العينة</string>
<string name="sample_shading_description">يسمح لمُظلل الأجزاء بالتنفيذ لكل عينة في جزء متعدد العينات بدلاً من مرة واحدة لكل جزء. يحسن جودة الرسومات على حساب بعض الأداء. تدعم فقط أجهزة Vulkan 1.1+ هذا الامتداد.</string>
<string name="sample_shading_fraction">كسر التظليل العيني</string>
<string name="sample_shading_fraction_description">شدة تمرير التظليل العيني. القيم الأعلى تحسن الجودة أكثر ولكنها تقلل الأداء بدرجة أكبر.</string>
<string name="custom_cpu_ticks">تخصيص دورات المعالج</string>
<string name="custom_cpu_ticks_description">تعيين قيمة مخصصة لدورات المعالج. القيم الأعلى قد تزيد الأداء، ولكن قد تتسبب أيضًا في تجمد اللعبة. يوصى بنطاق 77-21000.</string>
<string name="cpu_ticks">دورات</string>
<string name="skip_cpu_inner_invalidation">تخطي إبطال ذاكرة التخزين المؤقت الداخلية للوحدة المركزية</string>
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقت أثناء تحديثات الذاكرة، مما يقلل استخدام المعالج ويحسن أدائه. قد يسبب هذا أعطالاً أو تعطلًا في بعض الألعاب.</string>
<string name="cpuopt_unsafe_host_mmu">تمكين محاكاة MMU المضيف</string>
<string name="cpuopt_unsafe_host_mmu_description">يعمل هذا التحسين على تسريع وصول الذاكرة بواسطة البرنامج الضيف. يؤدي تمكينه إلى إجراء عمليات قراءة/كتابة ذاكرة الضيف مباشرة في الذاكرة والاستفادة من MMU المضيف. يؤدي تعطيل هذا إلى إجبار جميع عمليات الوصول إلى الذاكرة على استخدام محاكاة MMU البرمجية.</string>
<string name="dma_accuracy">مستوى DMA</string>
<string name="dma_accuracy_description">يتحكم في دقة تحديد مستوى DMA. الدقة الأعلى يمكنها إصلاح بعض المشاكل في بعض الألعاب، ولكنها قد تؤثر أيضًا على الأداء في بعض الحالات. إذا كنت غير متأكد، اتركه على الوضع الافتراضي.</string>
<!-- Memory Layouts -->
<string name="memory_4gb">4 جيجابايت (موصى به)</string>
@ -673,6 +681,50 @@
<string name="loader_requires_firmware">اللعبة تتطلب برنامجاً ثابتاً</string>
<string name="loader_requires_firmware_description"><![CDATA[اللعبة التي تحاول تشغيلها تتطلب برنامجاً ثابتاً للتمهيد أو لتجاوز القائمة الافتتاحية. يرجى <a href="https://yuzu-mirror.github.io/help/quickstart">نسخ وتثبيت البرنامج الثابت</a>، أو اضغط "موافق" للمتابعة على أي حال.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">جاري البحث عن اللعبة...</string>
<string name="game_not_found_for_title_id">لم يتم العثور على اللعبة لمعرف العنوان: %1$s</string>
<string name="custom_settings_failed_title">فشل الإعدادات المخصصة</string>
<string name="custom_settings_failed_message">فشل تطبيق الإعدادات المخصصة لـ %1$s: %2$s</string>
<string name="launch_with_default_settings">بدء التشغيل بالإعدادات الافتراضية</string>
<string name="launch_cancelled">تم إلغاء البدء</string>
<string name="custom_settings_failure_reasons">غير قادر على تطبيق الإعدادات المطلوبة. قد يكون هذا بسبب отсут برامج تشغيل GPU أو مشاكل في التهيئة.</string>
<string name="custom_settings_applied">تم تطبيق الإعدادات المخصصة</string>
<string name="launching_game">جاري تشغيل %1$s...</string>
<string name="failed_to_initialize_game">فشل تهيئة اللعبة</string>
<string name="custom_intent_launch_message_with_settings">هل تريد تشغيل %1$s بالإعدادات المخصصة؟</string>
<string name="custom_intent_launch_message">هل تريد تشغيل %1$s؟</string>
<string name="custom_intent_launch_title">تشغيل اللعبة</string>
<string name="launch">تشغيل</string>
<!-- Custom Config strings -->
<string name="config_write_failed">فشل كتابة ملف التهيئة</string>
<string name="config_apply_failed">فشل تطبيق التهيئة</string>
<string name="config_already_exists_title">التهيئة موجودة بالفعل</string>
<string name="config_already_exists_message">توجد إعدادات مخصصة بالفعل لـ %1$s.\n\nهل تريد الكتابة فوق التهيئة الموجودة؟\n\nلا يمكن التراجع عن هذا الإجراء.</string>
<string name="config_exists_prompt">جاري التحقق من وجود تهيئة حالية...</string>
<string name="overwrite_cancelled">تم إلغاء الكتابة فوق</string>
<string name="checking_driver">جاري التحقق من وجود برنامج تشغيل مخصص: %1$s</string>
<string name="driver_unavailable">برنامج التشغيل المخصص غير متاح لهذا الجهاز</string>
<string name="overwrite">الكتابة فوق</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">برنامج تشغيل GPU مفقود</string>
<string name="missing_gpu_driver_message">برنامج التشغيل المخصص المحدد \"%s\" غير مثبت. هل تريد تنزيله وتثبيته الآن؟</string>
<string name="downloading_driver">جاري تنزيل برنامج التشغيل...</string>
<string name="driver_installed">تم تثبيت برنامج التشغيل بنجاح</string>
<string name="driver_installation_failed_title">فشل تثبيت برنامج التشغيل</string>
<string name="driver_installation_failed_message">فشل تثبيت برنامج تشغيل GPU: %s</string>
<string name="driver_not_available_title">برنامج التشغيل غير متاح</string>
<string name="driver_not_available_message">برنامج التشغيل المحدد غير متاح للتنزيل.</string>
<string name="driver_not_found">برنامج التشغيل المطلوب غير مثبت: %s</string>
<string name="invalid_driver_file">ملف برنامج تشغيل غير صالح: %s</string>
<string name="network_unavailable">لا يوجد اتصال بالشبكة. يرجى التحقق من اتصال الإنترنت والمحاولة مرة أخرى.</string>
<string name="driver_missing_title">مطلوب برنامج تشغيل GPU</string>
<string name="driver_missing_message">تكوين اللعبة يتطلب برنامج تشغيل GPU \"%s\" غير المثبت على جهازك.\n\nهل تريد تنزيله وتثبيته الآن?</string>
<string name="driver_download_cancelled">تم إلغاء تنزيل برنامج التشغيل. لا يمكن تشغيل اللعبة بدون برنامج التشغيل المطلوب.</string>
<string name="download">تنزيل</string>
<!-- Emulation Menu -->
<string name="emulation_exit">الخروج من المحاكاة</string>
<string name="emulation_done">إنهاء</string>
@ -737,6 +789,12 @@
<string name="renderer_accuracy_high">عالي</string>
<string name="renderer_accuracy_extreme">Extreme (بطيء)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">افتراضي</string>
<string name="dma_accuracy_normal">عادي</string>
<string name="dma_accuracy_high">عالي</string>
<string name="dma_accuracy_extreme">مفرط</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">يضمن تسليمًا سلسًا ومتناسقًا للإطارات من خلال مزامنة التوقيت بينها، مما يقلل من التقطيع وعدم انتظام الحركة. مثالي للألعاب التي تعاني من عدم استقرار في توقيت الإطارات أو تقطع دقيق أثناء اللعب.</string>
<string name="renderer_early_release_fences">زێدەکردنی پەرستارەکان زووتر</string>
<string name="renderer_early_release_fences_description">یارمەتی دەدات لە چارەسەری 0 FPS لە یارییەکانی وەک DKCR:HD، Subnautica Below Zero و Ori 2، بەڵام ڕەنگە بارکردن یان کارایی لە یارییەکانی Unreal Engine تێکبدات.</string>
<string name="sync_memory_operations">هاوبەشیی کردارەکانی بیرگە</string>
<string name="sync_memory_operations_description">دڵنیایی داتا لە نێوان کردارەکانی کۆمپیوتەر و بیرگە. ئەم هەڵبژاردە کێشەکان لە هەندێک یاری چارەسەر دەکات، بەڵام لە هەندێک حاڵەت کارایی کەم دەکاتەوە. وا دیارە یارییەکانی Unreal Engine 4 زۆرترین کاریگەریان هەیە.</string>
<string name="buffer_reorder_disable">ڕێکخستنەوەی بافر ناچالاک بکە</string>
<string name="buffer_reorder_disable_description">کە دیاریکرا، ڕێکخستنەوەی بارکردنی بیرگەی نەخشەکراو ناچالاک دەکات کە ڕێگەدەدات بارکردنەکان بە ڕەسمی دیاریکراو ببەسترێت. لە هەندێک حاڵەتدا کاراییمان دەکاتەوە.</string>
<string name="use_lru_cache">تمكين ذاكرة التخزين المؤقت LRU</string>
<string name="use_lru_cache_description">چالاک یان ناچالاککردنی کاشەی LRU، کارایی باشتر دەکات بە هەڵگرتنی بەکارهێنانی پرۆسەی CPU. هەندێک یاری کێشەی لەگەڵ هەیە، بەتایبەتی TotK 1.2.1، بۆیە بیخەوێنە ئەگەر یاریەکە نەگەڕێت یان بە هەڕەمەکی بشکێت.</string>
<string name="dyna_state">الحالة الديناميكية الممتدة</string>
<string name="dyna_state_description">کاریگەرییەکانی ڤولکان چالاک بکە بۆ باشترکردنی کارایی، رێندرکردن، و هەڵگرتنی سەرچاوەکان لە دروستکردنی پایپلاین بە هەمان کات کەمترین بەکارهێنانی CPU/GPU بەکاربهێنرێت. ئەم زیادکراوانە ڕەنگە پلەی گەرمی ئامێر زیاد بکەن، و GPU-کانی هێڵی کۆنی A6XX ڕەنگە بە شێوەیەکی گونجاو کارنەکەن. بیخەوێنە بۆ نەخشەکێشانی فۆرماتە پێوانەکراوەکان.</string>
<string name="dyna_state_description">کۆntrolی ژمارەی تایبەتمەندییەکان دەکات کە دەتوانرێت لە دۆخی هایپرDynamic بەکاربهێنرێت. ژمارەی زیاتر ڕێگە بە تایبەتمەندییەکی زیاتر دەدات و دەتوانێت کارایی باشتر بکات، بەڵام لەوانەیە کێشە دروست بکات لەگەڵ هەندێک لە درایڤەرەکان و فرۆشەکان. نرخی گریمانەیی دەگۆڕێت بەپێی سیستەم و تواناکانی hardwareی تۆ. دەتوانیت ئەم نرخە بگۆڕیت تا جێگیری و جێیەکی بینینی باشتر دەستبکەوێت.</string>
<string name="disabled">ناچالاک</string>
<string name="use_sync_core">مزامنة سرعة النواة</string>
<string name="use_sync_core_description">خێرایی تیکەکانی ناوک ڕێکبخە لەگەڵ ڕێژەی خێرایی بەرزترین بۆ باشترکردنی کارایی بەبێ گۆڕینی خێرایی ڕاستەقینەی یارییەکە.</string>
@ -117,11 +119,17 @@
<string name="memory_layout_description">(تاقیکاری) گۆڕینی ڕێکخستنی بیرگەی شبیهسازیکراو. ئەم ڕێکخستنە کارایی زیاد ناکات، بەڵام لەوانەیە یارمەتی یارییەکان بدات کە بەرزی ڕێزۆلۆشن بەکاردهێنن بە هۆی مۆدەکان. لەسەر مۆبایلەکانی کە 8GB یان کەمتر RAMیان هەیە بەکارمەهێنە.</string>
<string name="sample_shading">سێبەندی نمونە</string>
<string name="sample_shading_description">ڕێگە بە شێدەری پارچە دەدات کە بۆ هەر نمونەیەک لە پارچەی فرە نمونەیدا جێبەجێ بکات لە جیاتی جێبەجێکردنی بۆ هەر پارچەیەک. جۆرایی گرافیک باشتر دەکات بە بەهای هەندێک لە کارایی. تەنها ئامێرەکانی Vulkan 1.1+ پشتگیری ئەم درێژکراوە دەکەن.</string>
<string name="sample_shading_fraction">پێکهاتەی سێبەرکردنی نموونە</string>
<string name="sample_shading_fraction_description">چڕی تێپەڕاندنی سێبەرکردنی نموونە. بەهای زیاتر کوالێتی باشتر دەکات بەڵام کارایی زیاتر کەم دەکاتەوە.</string>
<string name="custom_cpu_ticks">تیکی CPU هەڵبژێردراو</string>
<string name="custom_cpu_ticks_description">بەهای هەڵبژێردراوی تیکی CPU دابنێ. بەهای زیاتر دەتوانن کارایی زیاد بکەن، بەڵام لەوانەیە بووەستانی یاریش دروست بکەن. ئامۆژگاری بە نێوان 77-21000 دەکرێت.</string>
<string name="cpu_ticks">تیک</string>
<string name="skip_cpu_inner_invalidation">بازنەکردنی ناوەکی CPU</string>
<string name="skip_cpu_inner_invalidation_description">هەندێک لە بازنەکردنەکانی هەڵگر لە کاتی نوێکردنەوەی بیرگە دەنێرێت، کەمکردنەوەی بەکارهێنانی CPU و باشترکردنی کارایی. لەوانەیە لە هەندێک یاری کێشە درووست بکات.</string>
<string name="cpuopt_unsafe_host_mmu">چالاککردنی میمیکردنی MMU میواندە</string>
<string name="cpuopt_unsafe_host_mmu_description">ئەم باشکردنە خێرایی دەستکەوتنی بیرگە لەلایەن پرۆگرامی میوانەکە زیاد دەکات. چالاککردنی وای لێدەکات کە خوێندنەوە/نووسینەکانی بیرگەی میوانەکە ڕاستەوخۆ لە بیرگە ئەنجام بدرێت و میمیکردنی MMU میواندە بەکاربهێنێت. ناچالاککردنی ئەمە هەموو دەستکەوتنەکانی بیرگە ڕەت دەکاتەوە لە بەکارهێنانی میمیکردنی MMU نەرمەکاڵا.</string>
<string name="dma_accuracy">ئاستی DMA</string>
<string name="dma_accuracy_description">کۆنتڕۆڵی وردی ڕێکخستنی DMA دەکات. وردی زیاتر دەتوانێ هەندێک کێشە لە هەندێک یاری چارەسەر بکات، بەڵام لە هەندێک حاڵەتدا کاریگەری لەسەر کارایی هەیە. ئەگەر دڵنیا نیت، بە ڕێکخستنی بنەڕەتی بێڵە.</string>
<string name="memory_4gb">4GB (پێشنیارکراو)</string>
<string name="memory_6gb">6GB (نائاسایش)</string>
@ -650,6 +658,50 @@
<string name="loader_requires_firmware">یارییەکە فریموێر پێویستە</string>
<string name="loader_requires_firmware_description"><![CDATA[یارییەکە کە تۆ هەوڵ دەدەیت بیخەیتە کار فریموێر پێویستە بۆ کردنەوە یان تێپەڕاندنی مێنیوی کردنەوە. تکایە <a href="https://yuzu-mirror.github.io/help/quickstart"> فریموێر دامپ بکە و دابنێ</a>, یان پەنجە بنێ سەر "باشە" بۆ بەردەوامبوون هەرچۆنێک بێت.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">گەڕان بە دوای یارییە...</string>
<string name="game_not_found_for_title_id">یاری نەدۆزرایەوە بۆ ناسنامەی ناونیشان: %1$s</string>
<string name="custom_settings_failed_title">ڕێکخستنە هەڵبژێردراوەکان سەرکەوتوو نەبوو</string>
<string name="custom_settings_failed_message">سەرکەوتوو نەبوو لە جێبەجێکردنی ڕێکخستنە هەڵبژێردراوەکان بۆ %1$s: %2$s</string>
<string name="launch_with_default_settings">دەستپێکردن بە ڕێکخستنە بنەڕەتییەکان</string>
<string name="launch_cancelled">دەستپێکردن هەڵوەشیندراوە</string>
<string name="custom_settings_failure_reasons">ناتوانێت ڕێکخستنە داواکراوەکان جێبەجێ بکات. لەوانەیە ئەمە بەهۆی ونبوونی ڕاهێنەری GPU یان کێشەکانی ڕێکخستنەوە بێت.</string>
<string name="custom_settings_applied">ڕێکخستنە هەڵبژێردراوەکان جێبەجێ کرا</string>
<string name="launching_game">دەستپێکردنی %1$s...</string>
<string name="failed_to_initialize_game">سەرکەوتوو نەبوو لە دەستپێکردنی یارییەکە</string>
<string name="custom_intent_launch_message_with_settings">ئایا دەتەوێت %1$s بە ڕێکخستنە هەڵبژێردراوەکان دەستپێبکەیت؟</string>
<string name="custom_intent_launch_message">ئایا دەتەوێت %1$s دەستپێبکەیت?</string>
<string name="custom_intent_launch_title">دەستپێکردنی یاری</string>
<string name="launch">دەستپێکردن</string>
<!-- Custom Config strings -->
<string name="config_write_failed">سەرکەوتوو نەبوو لە نووسینی پەڕگەی ڕێکخستن</string>
<string name="config_apply_failed">سەرکەوتوو نەبوو لە جێبەجێکردنی ڕێکخستن</string>
<string name="config_already_exists_title">ڕێکخستن هەبووی تری هەیە</string>
<string name="config_already_exists_message">ڕێکخستنە هەڵبژێردراوەکان هەڵە بۆ %1$s.\n\nئایا دەتەوێت ڕێکخستنە هەبووەکە بسڕیتەوە؟\n\nناتوانیت ئەم کردارە بگەڕێنیتەوە.</string>
<string name="config_exists_prompt">پشکنین بۆ ڕێکخستنی ئێستا...</string>
<string name="overwrite_cancelled">سڕینەوە هەڵوەشیندراوە</string>
<string name="checking_driver">پشکنین بۆ ڕاهێنەری هەڵبژێردراو: %1$s</string>
<string name="driver_unavailable">ڕاهێنەری هەڵبژێردراو بۆ ئەم ئامێرە بەردەست نییە</string>
<string name="overwrite">سڕینەوە</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">ڕاهێنەری GPU ونبووە</string>
<string name="missing_gpu_driver_message">ڕاهێنەری هەڵبژێردراوی دیاریکراو \"%s\" دامەزراو نییە. ئایا دەتەوێت ئێستا دایببزێنیت و دامەزرێنیت?</string>
<string name="downloading_driver">داگرتنی ڕاهێنەر...</string>
<string name="driver_installed">ڕاهێنەر بە سەرکەوتوویی دامەزرا</string>
<string name="driver_installation_failed_title">دامەزرانی ڕاهێنەر سەرکەوتوو نەبوو</string>
<string name="driver_installation_failed_message">سەرکەوتوو نەبوو لە دامەزراندنی ڕاهێنەری GPU: %s</string>
<string name="driver_not_available_title">ڕاهێنەر بەردەست نییە</string>
<string name="driver_not_available_message">ڕاهێنەری دیاریکراو بۆ داگرتن بەردەست نییە.</string>
<string name="driver_not_found">ڕاهێنەری پێویست دامەزراو نییە: %s</string>
<string name="invalid_driver_file">پەڕگەی ڕاهێنەری نادروست: %s</string>
<string name="network_unavailable">هیچ پەیوەندییەکی تۆڕ بەردەست نییە. تکایە پەیوەندیی ئینتەرنێتەکەت بپشکنە و دووبارە هەوڵبدە.</string>
<string name="driver_missing_title">ڕاهێنەری GPU پێویستە</string>
<string name="driver_missing_message">ڕێکخستنی یارییەکە پێویستی بە ڕاهێنەری GPU \"%s\" هەیە کە لەسەر ئامێرەکەت دامەزراو نییە.\n\nئایا دەتەوێت ئێستا دایببزێنیت و دامەزرێنیت?</string>
<string name="driver_download_cancelled">داگرتنی ڕاهێنەر هەڵوەشیندراوە. ناتوانیت یارییەکە دەستپێبکەیت بەبێ ڕاهێنەری پێویست.</string>
<string name="download">داگرتن</string>
<!-- Emulation Menu -->
<string name="emulation_exit">دەرچوون لە ئیمولەیشن</string>
<string name="emulation_done">تەواو</string>
@ -684,6 +736,7 @@
<string name="fatal_error">هەڵەی کوشندە</string>
<string name="fatal_error_message">هەڵەیەکی کوشندە ڕوویدا. بۆ وردەکارییەکان لۆگەکە بپشکنە.\nبەردەوامی ئیمولەیشن لەوانەیە ببێتە هۆی تێکچوون و فڕێدانەدەرەوە.</string>
<string name="performance_warning">کوژاندنەوەی ئەم ڕێکخستنە دەبێتە هۆی کەمکردنەوەی کارایی ئیمولەیشن! بۆ باشترین ئەزموون، باشترە ئەم ڕێکخستنە چالاک بهێڵیتەوە.</string>
<!-- Region Names -->
<string name="region_japan">ژاپۆن</string>
<string name="region_usa">ئەمریکا</string>
@ -695,6 +748,7 @@
<string name="memory_byte_shorthand">B</string>
<string name="memory_gigabyte">GB</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">ڤوڵکان</string>
<string name="renderer_none">هیچ</string>
@ -704,6 +758,12 @@
<string name="renderer_accuracy_high">بەرز</string>
<string name="renderer_accuracy_extreme">ئەوپەڕ (خاو)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">بنەڕەتی</string>
<string name="dma_accuracy_normal">ئاسایی</string>
<string name="dma_accuracy_high">بەرز</string>
<string name="dma_accuracy_extreme">زۆر بەرز</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -77,12 +77,14 @@
<string name="frame_interpolation_description">Zajišťuje plynulé a konzistentní zobrazování snímků synchronizací jejich časování, čímž snižuje trhání a nerovnoměrné animace. Ideální pro hry, které trpí nestabilitou časování snímků nebo mikrotrháním během hraní.</string>
<string name="renderer_early_release_fences">Uvolnit ploty brzy</string>
<string name="renderer_early_release_fences_description">Pomáhá opravit 0 FPS v hrách jako DKCR:HD, Subnautica Below Zero a Ori 2, ale může narušit načítání nebo výkon v hrách na Unreal Engine.</string>
<string name="sync_memory_operations">Synchronizace paměťových operací</string>
<string name="sync_memory_operations_description">Zajišťuje konzistenci dat mezi výpočetními a paměťovými operacemi. Tato volba by měla opravit problémy v některých hrách, ale může v některých případech snížit výkon. Nejvíce postižené se zdají být hry s Unreal Engine 4.</string>
<string name="buffer_reorder_disable">Zakázat přeřazování vyrovnávací paměti</string>
<string name="buffer_reorder_disable_description">Při zaškrtnutí zakáže přeřazování nahrání mapované paměti, což umožňuje spojit nahrání s konkrétními vykresleními. V některých případech může snížit výkon.</string>
<string name="use_lru_cache">Povolit LRU mezipaměť</string>
<string name="use_lru_cache_description">Povolte nebo zakažte mezipaměť LRU, čímž zvýšíte výkon snížením využití procesoru CPU. Některé hry s ní mají problémy, zejména TotK 1.2.1, takže ji deaktivujte, pokud hra neběží nebo náhodně padá.</string>
<string name="dyna_state">Rozšířený dynamický stav</string>
<string name="dyna_state_description">Umožňuje funkce Vulkan pro zlepšení výkonu, vykreslování a úsporu zdrojů při vytváření pipeline při zachování nižšího využití CPU/GPU. Tato rozšíření mohou zvýšit teplotu zařízení a starší GPU řady A6XX nemusí správně reagovat. Vypněte pro emulaci měřítkových formátů.</string>
<string name="dyna_state_description">Ovládá počet funkcí, které lze použít v rozšířeném dynamickém stavu. Vyšší hodnoty umožňují více funkcí a mohou zvýšit výkon, ale mohou způsobit problémy s některými ovladači a výrobci. Výchozí hodnota se může lišit v závislosti na vašem systému a hardwarových schopnostech. Tuto hodnotu lze měnit, dokud nedosáhnete stability a lepší vizuální kvality.</string>
<string name="disabled">Vypnuto</string>
<string name="use_sync_core">Synchronizovat rychlost jádra</string>
<string name="use_sync_core_description">Synchronizuje rychlost jádra s maximálním procentem rychlosti, aby se zlepšil výkon bez změny skutečné rychlosti hry.</string>
@ -116,11 +118,17 @@
<string name="memory_layout_description">(EXPERIMENTÁLNÍ) Změna emulovaného rozložení paměti. Toto nastavení nezvyšuje výkon, ale může pomoci hrám využívajícím vysoké rozlišení pomocí modů. Nepoužívejte na telefonech s 8GB RAM nebo méně.</string>
<string name="sample_shading">Vzorkovací stínování</string>
<string name="sample_shading_description">Umožňuje fragment shaderu provádět výpočty pro každý vzorek ve fragmentu s více vzorky namísto jednou pro fragment. Zlepšuje kvalitu grafiky na úkor výkonu. Tuto funkci podporují pouze zařízení s Vulkan 1.1+.</string>
<string name="sample_shading_fraction">Podíl stínování vzorku</string>
<string name="sample_shading_fraction_description">Intenzita průchodu stínování vzorku. Vyšší hodnoty zlepšují kvalitu, ale také výrazněji snižují výkon.</string>
<string name="custom_cpu_ticks">Vlastní CPU takty</string>
<string name="custom_cpu_ticks_description">Nastavte vlastní hodnotu CPU taktů. Vyšší hodnoty mohou zvýšit výkon, ale mohou také způsobit zamrznutí hry. Doporučuje se rozsah 7721000.</string>
<string name="cpu_ticks">Takty</string>
<string name="skip_cpu_inner_invalidation">Přeskočit vnitřní invalidaci CPU</string>
<string name="skip_cpu_inner_invalidation_description">Přeskočí některé invalidace mezipaměti na straně CPU během aktualizací paměti, čímž sníží zatížení CPU a zlepší jeho výkon. Může způsobit chyby nebo pády v některých hrách.</string>
<string name="cpuopt_unsafe_host_mmu">Povolit emulaci hostitelské MMU</string>
<string name="cpuopt_unsafe_host_mmu_description">Tato optimalizace zrychluje přístup do paměti hostovaného programu. Její povolení způsobí, že čtení a zápisy do paměti hosta se provádějí přímo v paměti a využívají hostitelskou MMU. Zakázání této funkce vynutí použití softwarové emulace MMU pro všechny přístupy do paměti.</string>
<string name="dma_accuracy">Úroveň DMA</string>
<string name="dma_accuracy_description">Ovládá přesnost DMA. Vyšší přesnost může opravit problémy v některých hrách, ale může také ovlivnit výkon. Pokud si nejste jisti, ponechejte výchozí nastavení.</string>
<string name="memory_4gb">4GB (Doporučeno)</string>
<string name="memory_6gb">6GB (Nebezpečné)</string>
@ -630,6 +638,50 @@
<string name="loader_requires_firmware">Hra vyžaduje firmware</string>
<string name="loader_requires_firmware_description"><![CDATA[Hra, kterou se pokoušíte spustit, vyžaduje firmware pro spuštění nebo pro překročení úvodní nabídky. Prosím <a href="https://yuzu-mirror.github.io/help/quickstart"> převezměte a nainstalujte firmware</a>, nebo stiskněte "OK" pro pokračování v každém případě.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">Hledání hry...</string>
<string name="game_not_found_for_title_id">Hra nebyla nalezena pro ID titulu: %1$s</string>
<string name="custom_settings_failed_title">Vlastní nastavení selhalo</string>
<string name="custom_settings_failed_message">Nepodařilo se použít vlastní nastavení pro %1$s: %2$s</string>
<string name="launch_with_default_settings">Spustit s výchozím nastavením</string>
<string name="launch_cancelled">Spuštění zrušeno</string>
<string name="custom_settings_failure_reasons">Nelze použít požadovaná nastavení. Důvodem může být chybějící ovladač GPU nebo problémy s konfigurací.</string>
<string name="custom_settings_applied">Vlastní nastavení použito</string>
<string name="launching_game">Spouštím %1$s...</string>
<string name="failed_to_initialize_game">Nepodařilo se inicializovat hru</string>
<string name="custom_intent_launch_message_with_settings">Chcete spustit %1$s s vlastním nastavením?</string>
<string name="custom_intent_launch_message">Chcete spustit %1$s?</string>
<string name="custom_intent_launch_title">Spustit hru</string>
<string name="launch">Spustit</string>
<!-- Custom Config strings -->
<string name="config_write_failed">Nepodařilo se zapsat konfigurační soubor</string>
<string name="config_apply_failed">Nepodařilo se použít konfiguraci</string>
<string name="config_already_exists_title">Konfigurace již existuje</string>
<string name="config_already_exists_message">Vlastní nastavení již existuje pro %1$s.\n\nChcete přepsat stávající konfiguraci?\n\nTuto akci nelze vrátit zpět.</string>
<string name="config_exists_prompt">Kontrola existující konfigurace...</string>
<string name="overwrite_cancelled">Přepsání zrušeno</string>
<string name="checking_driver">Kontrola vlastního ovladače: %1$s</string>
<string name="driver_unavailable">Vlastní ovladač není pro toto zařízení k dispozici</string>
<string name="overwrite">Přepsat</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">Chybí ovladač GPU</string>
<string name="missing_gpu_driver_message">Vybraný vlastní ovladač \"%s\" není nainstalován. Chcete jej nyní stáhnout и nainstalovat?</string>
<string name="downloading_driver">Stahování ovladače...</string>
<string name="driver_installed">Ovladač byl úspěšně nainstalován</string>
<string name="driver_installation_failed_title">Instalace ovladače selhala</string>
<string name="driver_installation_failed_message">Nepodařilo se nainstalovat ovladač GPU: %s</string>
<string name="driver_not_available_title">Ovladač není k dispozici</string>
<string name="driver_not_available_message">Vybraný ovladač není k dispozici ke stažení.</string>
<string name="driver_not_found">Požadovaný ovladač není nainstalován: %s</string>
<string name="invalid_driver_file">Neplatný soubor ovladače: %s</string>
<string name="network_unavailable">Není dostupné síťové připojení. Zkontrolujte prosím připojení k internetu a zkuste to znovu.</string>
<string name="driver_missing_title">Vyžadován ovladač GPU</string>
<string name="driver_missing_message">Konfigurace hry vyžaduje ovladač GPU \"%s\", který není na vašem zařízení nainstalován.\n\nChcete jej nyní stáhnout a nainstalovat?</string>
<string name="driver_download_cancelled">Stahování ovladače bylo zrušeno. Hru nelze spustit bez požadovaného ovladače.</string>
<string name="download">Stáhnout</string>
<!-- Emulation Menu -->
<string name="emulation_exit">Ukončit emulaci</string>
<string name="emulation_done">Hotovo</string>
@ -680,6 +732,12 @@
<string name="renderer_accuracy_high">Vysoká</string>
<string name="renderer_accuracy_extreme">Extrémní (Pomalé)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Výchozí</string>
<string name="dma_accuracy_normal">Normální</string>
<string name="dma_accuracy_high">Vysoká</string>
<string name="dma_accuracy_extreme">Extrémní</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">Sorgt für eine gleichmäßige und konsistente Frame-Wiedergabe durch Synchronisierung der Frame-Zeiten, was Ruckeln und ungleichmäßige Animationen reduziert. Ideal für Spiele, die unter instabilen Frame-Zeiten oder Mikrorucklern leiden.</string>
<string name="renderer_early_release_fences">Zäune früher freigeben</string>
<string name="renderer_early_release_fences_description">Behebt 0 FPS in Spielen wie DKCR:HD, Subnautica Below Zero und Ori 2, kann aber Ladezeiten oder Performance in Unreal Engine-Spielen beeinträchtigen.</string>
<string name="sync_memory_operations">Speicheroperationen synchronisieren</string>
<string name="sync_memory_operations_description">Stellt die Datenkonsistenz zwischen Compute- und Speicheroperationen sicher. Diese Option sollte Probleme in einigen Spielen beheben, kann aber in einigen Fällen die Leistung verringern. Spiele mit Unreal Engine 4 scheinen am stärksten betroffen zu sein.</string>
<string name="buffer_reorder_disable">Puffer-Neuanordnung deaktivieren</string>
<string name="buffer_reorder_disable_description">Wenn aktiviert, wird die Neuanordnung von gemappten Speicher-Uploads deaktiviert, was die Zuordnung von Uploads zu bestimmten Zeichenvorgängen ermöglicht. Kann in einigen Fällen die Leistung verringern.</string>
<string name="use_lru_cache">LRU-Cache aktivieren</string>
<string name="use_lru_cache_description">Aktivieren oder deaktivieren Sie den LRU-Cache, um die Leistung durch Einsparung von CPU-Prozessorauslastung zu verbessern. Einige Spiele haben Probleme damit, insbesondere TotK 1.2.1, deaktivieren Sie es also, wenn das Spiel nicht startet oder zufällig abstürzt.</string>
<string name="dyna_state">Erweiterter dynamischer Status</string>
<string name="dyna_state_description">Aktiviert Vulkan-Funktionen zur Verbesserung der Leistung, des Renderings und zur Einsparung von Ressourcen bei der Pipeline-Erstellung bei gleichzeitig geringer CPU/GPU-Auslastung. Diese Erweiterungen können die Gerätetemperatur erhöhen, und ältere GPUs der A6XX-Serie reagieren möglicherweise nicht richtig. Deaktivieren Sie dies, um skalierte Formate zu emulieren.</string>
<string name="dyna_state_description">Steuert die Anzahl der Funktionen, die im Erweiterten Dynamischen Zustand verwendet werden können. Höhere Werte ermöglichen mehr Funktionen und können die Leistung steigern, können jedoch bei einigen Treibern und Herstellern zu Problemen führen. Der Standardwert kann je nach System und Hardwarefähigkeiten variieren. Dieser Wert kann geändert werden, bis Stabilität und eine bessere visuelle Qualität erreicht sind.</string>
<string name="disabled">Deaktiviert</string>
<string name="use_sync_core">Kern-Geschwindigkeit synchronisieren</string>
<string name="use_sync_core_description">Synchronisiert die Taktrate des Kerns mit der maximalen Geschwindigkeit, um die Leistung zu verbessern, ohne die tatsächliche Spielgeschwindigkeit zu verändern.</string>
@ -117,11 +119,17 @@
<string name="memory_layout_description">(EXPERIMENTELL) Ändert das emulierte Speicherlayout. Diese Einstellung erhöht nicht die Leistung, kann aber bei Spielen helfen, die hohe Auflösungen über Mods nutzen. Nicht auf Telefonen mit 8 GB RAM oder weniger verwenden.</string>
<string name="sample_shading">Sample Shading</string>
<string name="sample_shading_description">Ermöglicht dem Fragment-Shader, pro Sample in einem mehrfach gesampleten Fragment ausgeführt zu werden, anstatt einmal pro Fragment. Verbessert die Grafikqualität auf Kosten der Leistung. Nur Vulkan 1.1+-Geräte unterstützen diese Erweiterung.</string>
<string name="sample_shading_fraction">Sample-Shading-Anteil</string>
<string name="sample_shading_fraction_description">Die Intensität des Sample-Shading-Durchgangs. Höhere Werte verbessern die Qualität stärker, beeinträchtigen aber auch die Leistung stärker.</string>
<string name="custom_cpu_ticks">Benutzerdefinierte CPU-Ticks</string>
<string name="custom_cpu_ticks_description">Legen Sie einen benutzerdefinierten Wert für CPU-Ticks fest. Höhere Werte können die Leistung steigern, aber auch zum Einfrieren des Spiels führen. Ein Bereich von 7721000 wird empfohlen.</string>
<string name="cpu_ticks">Ticks</string>
<string name="skip_cpu_inner_invalidation">CPU-interne Invalidierung überspringen</string>
<string name="skip_cpu_inner_invalidation_description">Überspringt bestimmte Cache-Invalidierungen auf CPU-Seite während Speicherupdates, reduziert die CPU-Auslastung und verbessert die Leistung. Kann in einigen Spielen zu Fehlern oder Abstürzen führen.</string>
<string name="cpuopt_unsafe_host_mmu">Host-MMU-Emulation aktivieren</string>
<string name="cpuopt_unsafe_host_mmu_description">Diese Optimierung beschleunigt Speicherzugriffe durch das Gastprogramm. Wenn aktiviert, erfolgen Speicherlese- und -schreibvorgänge des Gastes direkt im Speicher und nutzen die MMU des Hosts. Das Deaktivieren erzwingt die Verwendung der Software-MMU-Emulation für alle Speicherzugriffe.</string>
<string name="dma_accuracy">DMA-Level</string>
<string name="dma_accuracy_description">Steuert die DMA-Präzisionsgenauigkeit. Eine höhere Präzision kann Probleme in einigen Spielen beheben, kann aber in einigen Fällen auch die Leistung beeinträchtigen. Im Zweifel auf „Standard“ belassen.</string>
<string name="memory_4gb">4 GB (Empfohlen)</string>
<string name="memory_6gb">6 GB (Unsicher)</string>
@ -706,6 +714,50 @@ Wirklich fortfahren?</string>
<string name="loader_requires_firmware">Spiel erfordert Firmware</string>
<string name="loader_requires_firmware_description"><![CDATA[Das Spiel, das Sie starten möchten, benötigt Firmware zum Booten oder zum Überspringen des Startmenüs. Bitte <a href="https://yuzu-mirror.github.io/help/quickstart"> dumpen und installieren Sie Firmware</a>, oder drücken Sie "OK", um trotzdem zu starten.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">Suche nach Spiel...</string>
<string name="game_not_found_for_title_id">Spiel nicht gefunden für Titel-ID: %1$s</string>
<string name="custom_settings_failed_title">Benutzerdefinierte Einstellungen fehlgeschlagen</string>
<string name="custom_settings_failed_message">Fehler beim Anwenden der benutzerdefinierten Einstellungen für %1$s: %2$s</string>
<string name="launch_with_default_settings">Mit Standardeinstellungen starten</string>
<string name="launch_cancelled">Start abgebrochen</string>
<string name="custom_settings_failure_reasons">Die angeforderten Einstellungen konnten nicht angewendet werden. Dies kann an fehlenden GPU-Treibern oder Konfigurationsproblemen liegen.</string>
<string name="custom_settings_applied">Benutzerdefinierte Einstellungen übernommen</string>
<string name="launching_game">Starte %1$s...</string>
<string name="failed_to_initialize_game">Spielinitialisierung fehlgeschlagen</string>
<string name="custom_intent_launch_message_with_settings">Möchten Sie %1$s mit benutzerdefinierten Einstellungen starten?</string>
<string name="custom_intent_launch_message">Möchten Sie %1$s starten?</string>
<string name="custom_intent_launch_title">Spiel starten</string>
<string name="launch">Starten</string>
<!-- Custom Config strings -->
<string name="config_write_failed">Konfigurationsdatei konnte nicht geschrieben werden</string>
<string name="config_apply_failed">Konfiguration konnte nicht angewendet werden</string>
<string name="config_already_exists_title">Konfiguration existiert bereits</string>
<string name="config_already_exists_message">Benutzerdefinierte Einstellungen existieren bereits für %1$s.\n\nMöchten Sie die bestehende Konfiguration überschreiben?\n\nDiese Aktion kann nicht rückgängig gemacht werden.</string>
<string name="config_exists_prompt">Überprüfe auf vorhandene Konfiguration...</string>
<string name="overwrite_cancelled">Überschreiben abgebrochen</string>
<string name="checking_driver">Üoverprüfe benutzerdefinierten Treiber: %1$s</string>
<string name="driver_unavailable">Benutzerdefinierter Treiber für dieses Gerät nicht verfügbar</string>
<string name="overwrite">Überschreiben</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">GPU-Treiber fehlt</string>
<string name="missing_gpu_driver_message">Der ausgewählte benutzerdefinierte Treiber \"%s\" ist nicht installiert. Möchten Sie ihn jetzt herunterladen und installieren?</string>
<string name="downloading_driver">Treiber wird heruntergeladen...</string>
<string name="driver_installed">Treiber erfolgreich installiert</string>
<string name="driver_installation_failed_title">Treiberinstallation fehlgeschlagen</string>
<string name="driver_installation_failed_message">Fehler beim Installieren des GPU-Treibers: %s</string>
<string name="driver_not_available_title">Treiber nicht verfügbar</string>
<string name="driver_not_available_message">Der ausgewählte Treiber ist nicht zum Download verfügbar.</string>
<string name="driver_not_found">Erforderlicher Treiber nicht installiert: %s</string>
<string name="invalid_driver_file">Ungültige Treiberdatei: %s</string>
<string name="network_unavailable">Keine Netzwerkverbindung verfügbar. Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut.</string>
<string name="driver_missing_title">GPU-Treiber erforderlich</string>
<string name="driver_missing_message">Die Spielkonfiguration erfordert den GPU-Treiber \"%s\", der auf Ihrem Gerät nicht installiert ist.\n\nMöchten Sie ihn jetzt herunterladen и installieren?</string>
<string name="driver_download_cancelled">Treiberdownload abgebrochen. Das Spiel kann ohne den erforderlichen Treiber nicht gestartet werden.</string>
<string name="download">Herunterladen</string>
<!-- Emulation Menu -->
<string name="emulation_exit">Emulation beenden</string>
<string name="emulation_done">Fertig</string>
@ -766,6 +818,12 @@ Wirklich fortfahren?</string>
<string name="renderer_accuracy_high">Hoch</string>
<string name="renderer_accuracy_extreme">Extrem (Langsam)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Standard</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Hoch</string>
<string name="dma_accuracy_extreme">Extrem</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">Garantiza una reproducción suave y consistente de fotogramas sincronizando sus tiempos, reduciendo el tartamudeo y animaciones irregulares. Ideal para juegos con problemas de sincronización de fotogramas o microtartamudeos.</string>
<string name="renderer_early_release_fences">Liberar vallas antes</string>
<string name="renderer_early_release_fences_description">Ayuda a solucionar 0 FPS en juegos como DKCR:HD, Subnautica Below Zero y Ori 2, pero puede afectar la carga o rendimiento en juegos de Unreal Engine.</string>
<string name="sync_memory_operations">Sincronizar operaciones de memoria</string>
<string name="sync_memory_operations_description">Garantiza la consistencia de datos entre operaciones de computación y memoria. Esta opción debería solucionar problemas en algunos juegos, pero puede reducir el rendimiento en algunos casos. Los juegos con Unreal Engine 4 parecen ser los más afectados.</string>
<string name="buffer_reorder_disable">Desactivar reordenamiento de búfer</string>
<string name="buffer_reorder_disable_description">Cuando está marcado, desactiva el reordenamiento de cargas de memoria mapeada, lo que permite asociar cargas con dibujos específicos. Puede reducir el rendimiento en algunos casos.</string>
<string name="use_lru_cache">Habilitar caché LRU</string>
<string name="use_lru_cache_description">Activa o desactiva la caché LRU, mejorando el rendimiento al ahorrar uso del proceso de la CPU. Algunos juegos tienen problemas con ella, notablemente TotK 1.2.1, así que desactívala si el juego no inicia o se cierra aleatoriamente.</string>
<string name="dyna_state">Estado dinámico extendido</string>
<string name="dyna_state_description">Habilita funciones de Vulkan para mejorar el rendimiento, el renderizado y ahorrar recursos en la creación de pipelines manteniendo un uso bajo de CPU/GPU. Estas extensiones pueden aumentar la temperatura del dispositivo, y las GPU de la antigua línea A6XX pueden no reaccionar correctamente. Desactívalo para emular formatos escalados.</string>
<string name="dyna_state_description">Controla la cantidad de funciones que se pueden usar en el Estado Dinámico Extendido. Los valores más altos permiten más funciones y pueden aumentar el rendimiento, pero pueden causar problemas con algunos controladores y fabricantes. El valor predeterminado puede variar según su sistema y las capacidades de su hardware. Este valor se puede cambiar hasta lograr estabilidad y una mejor calidad visual.</string>
<string name="disabled">Desactivado</string>
<string name="use_sync_core">Sincronizar velocidad del núcleo</string>
<string name="use_sync_core_description">Sincroniza la velocidad del núcleo con el porcentaje máximo de velocidad para mejorar el rendimiento sin alterar la velocidad real del juego.</string>
@ -117,11 +119,17 @@
<string name="memory_layout_description">(EXPERIMENTAL) Cambia la distribución de memoria emulada. Esta configuración no aumenta el rendimiento, pero puede ayudar en juegos que utilizan altas resoluciones mediante mods. No usar en teléfonos con 8GB de RAM o menos.</string>
<string name="sample_shading">Muestreo de sombreado</string>
<string name="sample_shading_description">Permite que el fragment shader se ejecute por muestra en un fragmento multisample en lugar de una vez por fragmento. Mejora la calidad gráfica a costa de algo de rendimiento. Solo los dispositivos Vulkan 1.1+ admiten esta extensión.</string>
<string name="sample_shading_fraction">Fracción de sombreado de muestra</string>
<string name="sample_shading_fraction_description">La intensidad del paso de sombreado de muestra. Valores más altos mejoran más la calidad pero también reducen en mayor medida el rendimiento.</string>
<string name="custom_cpu_ticks">Ticks de CPU personalizados</string>
<string name="custom_cpu_ticks_description">Establece un valor personalizado de ticks de CPU. Valores más altos pueden aumentar el rendimiento, pero también pueden hacer que el juego se congele. Se recomienda un rango de 7721000.</string>
<string name="cpu_ticks">Ticks</string>
<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é durante actualizaciones de memoria, reduciendo el uso de CPU y mejorando su rendimiento. Puede causar fallos en algunos juegos.</string>
<string name="cpuopt_unsafe_host_mmu">Habilitar emulación de MMU del host</string>
<string name="cpuopt_unsafe_host_mmu_description">Esta optimización acelera los accesos a la memoria por parte del programa invitado. Al habilitarla, las lecturas/escrituras de memoria del invitado se realizan directamente en la memoria y utilizan la MMU del host. Deshabilitar esto obliga a que todos los accesos a la memoria utilicen la emulación de MMU por software.</string>
<string name="dma_accuracy">Nivel de DMA</string>
<string name="dma_accuracy_description">Controla la precisión del DMA. Una mayor precisión puede solucionar problemas en algunos juegos, pero también puede afectar el rendimiento en algunos casos. Si no está seguro, déjelo en Predeterminado.</string>
<string name="memory_4gb">4GB (Recomendado)</string>
<string name="memory_6gb">6GB (Inseguro)</string>
@ -745,6 +753,50 @@
<string name="loader_requires_firmware">El juego requiere firmware</string>
<string name="loader_requires_firmware_description"><![CDATA[El juego que intentas iniciar requiere firmware para arrancar o pasar el menú de inicio. Por favor <a href="https://yuzu-mirror.github.io/help/quickstart"> vuelca e instala el firmware</a>, o pulsa "Aceptar" para continuar de todos modos.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">Buscando juego...</string>
<string name="game_not_found_for_title_id">Juego no encontrado para el ID de título: %1$s</string>
<string name="custom_settings_failed_title">Configuración personalizada fallida</string>
<string name="custom_settings_failed_message">Error al aplicar la configuración personalizada para %1$s: %2$s</string>
<string name="launch_with_default_settings">Iniciar con configuración predeterminada</string>
<string name="launch_cancelled">Inicio cancelado</string>
<string name="custom_settings_failure_reasons">No se pueden aplicar los ajustes solicitados. Esto puede deberse a controladores GPU faltantes o problemas de configuración.</string>
<string name="custom_settings_applied">Configuración personalizada aplicada</string>
<string name="launching_game">Iniciando %1$s...</string>
<string name="failed_to_initialize_game">Error al inicializar el juego</string>
<string name="custom_intent_launch_message_with_settings">¿Quieres iniciar %1$s con configuración personalizada?</string>
<string name="custom_intent_launch_message">¿Quieres iniciar %1$s?</string>
<string name="custom_intent_launch_title">Iniciar juego</string>
<string name="launch">Iniciar</string>
<!-- Custom Config strings -->
<string name="config_write_failed">Error al escribir el archivo de configuración</string>
<string name="config_apply_failed">Error al aplicar la configuración</string>
<string name="config_already_exists_title">La configuración ya existe</string>
<string name="config_already_exists_message">Ya existe una configuración personalizada para %1$s.\n\n¿Quieres sobrescribir la configuración existente?\n\nEsta acción no se puede deshacer.</string>
<string name="config_exists_prompt">Comprobando la configuración existente...</string>
<string name="overwrite_cancelled">Sobrescritura cancelada</string>
<string name="checking_driver">Comprobando controlador personalizado: %1$s</string>
<string name="driver_unavailable">Controlador personalizado no disponible para este dispositivo</string>
<string name="overwrite">Sobrescribir</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">Falta controlador de GPU</string>
<string name="missing_gpu_driver_message">El controlador personalizado seleccionado \"%s\" no está instalado. ¿Quieres descargarlo e instalarlo ahora?</string>
<string name="downloading_driver">Descargando controlador...</string>
<string name="driver_installed">Controlador instalado correctamente</string>
<string name="driver_installation_failed_title">Error en la instalación del controlador</string>
<string name="driver_installation_failed_message">Error al instalar el controlador de GPU: %s</string>
<string name="driver_not_available_title">Controlador no disponible</string>
<string name="driver_not_available_message">El controlador seleccionado no está disponible para descargar.</string>
<string name="driver_not_found">Controlador requerido no instalado: %s</string>
<string name="invalid_driver_file">Archivo de controlador no válido: %s</string>
<string name="network_unavailable">No hay conexión de red disponible. Por favor, compruebe su conexión a Internet e inténtelo de nuevo.</string>
<string name="driver_missing_title">Se requiere controlador de GPU</string>
<string name="driver_missing_message">La configuración del juego requiere el controlador de GPU \"%s\" que no está instalado en su dispositivo.\n\n¿Quieres descargarlo e instalarlo ahora?</string>
<string name="driver_download_cancelled">Descarga del controlador cancelada. El juego no se puede iniciar sin el controlador requerido.</string>
<string name="download">Descargar</string>
<!-- Emulation Menu -->
<string name="emulation_exit">Salir de la emulación</string>
<string name="emulation_done">Hecho</string>
@ -815,6 +867,12 @@
<string name="renderer_accuracy_high">Alto</string>
<string name="renderer_accuracy_extreme">Extremo (Lento)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Predeterminado</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Alto</string>
<string name="dma_accuracy_extreme">Extremo</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">ارسال یکنواخت و پایدار فریم‌ها را با همگام‌سازی زمان بین آن‌ها تضمین می‌کند، که منجر به کاهش لرزش و انیمیشن‌های ناهموار می‌شود. برای بازی‌هایی که ناپایداری در زمان‌بندی فریم‌ها یا میکرو لرزش در حین بازی دارند ایده‌آل است</string>
<string name="renderer_early_release_fences">رهاسازی حصارها زودتر</string>
<string name="renderer_early_release_fences_description">به رفع مشکل 0 فریم بر ثانیه در بازی‌هایی مانند DKCR:HD، Subnautica Below Zero و Ori 2 کمک می‌کند، اما ممکن است بارگذاری یا عملکرد بازی‌های Unreal Engine را مختل کند.</string>
<string name="sync_memory_operations">همگام‌سازی عملیات حافظه</string>
<string name="sync_memory_operations_description">اطمینان از سازگاری داده‌ها بین عملیات محاسباتی و حافظه. این گزینه ممکن است مشکلات برخی بازی‌ها را رفع کند، اما در برخی موارد ممکن است عملکرد را کاهش دهد. به نظر می‌رسد بازی‌های با Unreal Engine 4 بیشترین تأثیر را داشته باشند.</string>
<string name="buffer_reorder_disable">غیرفعال کردن مرتب‌سازی مجدد بافر</string>
<string name="buffer_reorder_disable_description">در صورت انتخاب، مرتب‌سازی مجدد آپلودهای حافظه نگاشت‌شده غیرفعال می‌شود که امکان ارتباط آپلودها با ترسیمات خاص را فراهم می‌کند. ممکن است در برخی موارد عملکرد را کاهش دهد.</string>
<string name="use_lru_cache">فعال‌سازی حافظه نهان LRU</string>
<string name="use_lru_cache_description">حافظه پنهان LRU را فعال یا غیرفعال کنید تا با کاهش استفاده از پردازنده، عملکرد بهبود یابد. برخی بازی‌ها مانند TotK 1.2.1 با این ویژگی مشکل دارند، در صورت عدم راه‌اندازی یا قطعی تصادفی بازی، آن را غیرفعال کنید.</string>
<string name="dyna_state">حالت پویای گسترده</string>
<string name="dyna_state_description">قابلیت‌های ولکان را برای بهبود عملکرد، رندرینگ و صرفه‌جویی در منابع هنگام ایجاد خط لوله فعال می‌کند، در حالی که استفاده کمتری از CPU/GPU دارد. این پسوندها ممکن است دمای دستگاه را افزایش دهند و GPUهای قدیمی خط A6XX ممکن است به درستی واکنش نشان ندهند. برای شبیه‌سازی فرمت‌های مقیاس‌شده غیرفعال کنید.</string>
<string name="dyna_state_description">تعداد قابلیت‌هایی که می‌توان در حالت Extended Dynamic State استفاده کرد را کنترل می‌کند. اعداد بالاتر قابلیت‌های بیشتری را فعال کرده و می‌توانند عملکرد را افزایش دهند، اما ممکن است با برخی درایورها و فروشندگان مشکلاتی ایجاد کنند. مقدار پیش‌فرض بسته به سیستم و قابلیت‌های سخت‌افزاری شما ممکن است متفاوت باشد. این مقدار را می‌توان تغییر داد تا زمانی که پایداری و کیفیت بصری بهتری حاصل شود.</string>
<string name="disabled">غیرفعال</string>
<string name="use_sync_core">همگام‌سازی سرعت هسته</string>
<string name="use_sync_core_description">همگام‌سازی سرعت هسته با حداکثر درصد سرعت برای بهبود عملکرد بدون تغییر سرعت واقعی بازی.</string>
@ -117,11 +119,17 @@
<string name="memory_layout_description">(آزمایشی) چیدمان حافظه شبیه‌سازی شده را تغییر می‌دهد. این تنظیم عملکرد را افزایش نمی‌دهد، اما ممکن است به بازی‌هایی که از رزولوشن بالا با استفاده از مادها استفاده می‌کنند کمک کند. در تلفن‌های با 8 گیگابایت رم یا کمتر استفاده نشود.</string>
<string name="sample_shading">سایه‌زنی نمونه</string>
<string name="sample_shading_description">اجازه می‌دهد شیدر قطعه در هر نمونه از یک قطعه چندنمونه‌ای اجرا شود به جای یک بار برای هر قطعه. کیفیت گرافیک را به بهای کاهش عملکرد بهبود می‌بخشد. فقط دستگاه‌های Vulkan 1.1+ از این افزونه پشتیبانی می‌کنند.</string>
<string name="sample_shading_fraction">کسر سایه‌زنی نمونه</string>
<string name="sample_shading_fraction_description">شدت مرحله سایه‌زنی نمونه. مقادیر بالاتر کیفیت را بیشتر بهبود می‌بخشد اما عملکرد را نیز به میزان بیشتری کاهش می‌دهد.</string>
<string name="custom_cpu_ticks">تیک‌های CPU سفارشی</string>
<string name="custom_cpu_ticks_description">مقدار سفارشی برای تیک‌های CPU تنظیم کنید. مقادیر بالاتر ممکن است عملکرد را افزایش دهند، اما ممکن است باعث یخ زدن بازی شوند. محدوده 77-21000 توصیه می‌شود.</string>
<string name="cpu_ticks">تیک‌ها</string>
<string name="skip_cpu_inner_invalidation">رد کردن ابطال داخلی CPU</string>
<string name="skip_cpu_inner_invalidation_description">بعضی ابطال‌های حافظه نهان در هنگام به‌روزرسانی‌های حافظه را رد می‌کند، استفاده از CPU را کاهش داده و عملکرد آن را بهبود می‌بخشد. ممکن است در برخی بازی‌ها باعث مشکلات یا خرابی شود.</string>
<string name="cpuopt_unsafe_host_mmu">فعال‌سازی شبیه‌سازی MMU میزبان</string>
<string name="cpuopt_unsafe_host_mmu_description">این بهینه‌سازی دسترسی‌های حافظه توسط برنامه میهمان را تسریع می‌کند. فعال‌سازی آن باعث می‌شود خواندن/نوشتن حافظه میهمان مستقیماً در حافظه انجام شود و از MMU میزبان استفاده کند. غیرفعال کردن این قابلیت، همه دسترسی‌های حافظه را مجبور به استفاده از شبیه‌سازی نرم‌افزاری MMU می‌کند.</string>
<string name="dma_accuracy">سطح DMA</string>
<string name="dma_accuracy_description">دقت صحت DMA را کنترل می کند. دقت بالاتر می تواند مشکلات برخی بازی ها را برطرف کند، اما در برخی موارد نیز می تواند بر عملکرد تأثیر بگذارد. اگر مطمئن نیستید، آن را روی پیش فرض بگذارید.</string>
<string name="memory_4gb">4 گیگابایت (توصیه شده)</string>
<string name="memory_6gb">6 گیگابایت (ناامن)</string>
@ -744,6 +752,50 @@
<string name="loader_requires_firmware">بازی نیاز به فیرمور دارد</string>
<string name="loader_requires_firmware_description"><![CDATA[بازی که می‌خواهید اجرا کنید برای بوت شدن یا عبور از منوی شروع نیاز به فیرمور دارد. لطفا <a href="https://yuzu-mirror.github.io/help/quickstart"> فیرمور را دامپ و نصب کنید</a> یا برای ادامه کار "تایید" را فشار دهید.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">در حال جستجوی بازی...</string>
<string name="game_not_found_for_title_id">بازی برای شناسه عنوان یافت نشد: %1$s</string>
<string name="custom_settings_failed_title">تنظیمات سفارشی ناموفق بود</string>
<string name="custom_settings_failed_message">اعمال تنظیمات سفارشی برای %1$s ناموفق بود: %2$s</string>
<string name="launch_with_default_settings">اجرا با تنظیمات پیش‌فرض</string>
<string name="launch_cancelled">اجرا لغو شد</string>
<string name="custom_settings_failure_reasons">قادر به اعمال تنظیمات درخواستی نیست. این ممکن است به دلیل عدم وجود درایورهای GPU یا مشکلات پیکربندی باشد.</string>
<string name="custom_settings_applied">تنظیمات سفارشی اعمال شد</string>
<string name="launching_game">در حال اجرای %1$s...</string>
<string name="failed_to_initialize_game">مشکل در مقداردهی اولیه بازی</string>
<string name="custom_intent_launch_message_with_settings">آیا می‌خواهید %1$s را با تنظیمات سفارشی اجرا کنید؟</string>
<string name="custom_intent_launch_message">آیا می‌خواهید %1$s را اجرا کنید؟</string>
<string name="custom_intent_launch_title">اجرای بازی</string>
<string name="launch">اجرا</string>
<!-- Custom Config strings -->
<string name="config_write_failed">نوشتن فایل پیکربندی ناموفق بود</string>
<string name="config_apply_failed">اعمال پیکربندی ناموفق بود</string>
<string name="config_already_exists_title">پیکربندی از قبل وجود دارد</string>
<string name="config_already_exists_message">تنظیمات سفارشی از قبل برای %1$s وجود دارد.\n\nآیا می‌خواهید پیکربندی موجود را بازنویسی کنید؟\n\nاین عمل قابل بازگشت نیست.</string>
<string name="config_exists_prompt">در حال بررسی پیکربندی موجود...</string>
<string name="overwrite_cancelled">بازنویسی لغو شد</string>
<string name="checking_driver">در حال بررسی درایور سفارشی: %1$s</string>
<string name="driver_unavailable">درایور سفارشی برای این دستگاه در دسترس نیست</string>
<string name="overwrite">بازنویسی</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">درایور GPU یافت نشد</string>
<string name="missing_gpu_driver_message">درایور سفارشی انتخاب شده \"%s\" نصب نشده است. آیا می‌خواهید هم اکنون آن را دانلود و نصب کنید؟</string>
<string name="downloading_driver">در حال دانلود درایور...</string>
<string name="driver_installed">درایور با موفقیت نصب شد</string>
<string name="driver_installation_failed_title">نصب درایور ناموفق بود</string>
<string name="driver_installation_failed_message">نصب درایور GPU ناموفق بود: %s</string>
<string name="driver_not_available_title">درایور در دسترس نیست</string>
<string name="driver_not_available_message">درایور انتخاب شده برای دانلود در دسترس نیست.</string>
<string name="driver_not_found">درایور مورد نیاز نصب نشده است: %s</string>
<string name="invalid_driver_file">فایل درایور نامعتبر: %s</string>
<string name="network_unavailable">اتصال شبکه در دسترس نیست. لطفاً اتصال اینترنت خود را بررسی کرده و مجدداً تلاش کنید.</string>
<string name="driver_missing_title">درایور GPU مورد نیاز است</string>
<string name="driver_missing_message">پیکربندی بازی به درایور GPU \"%s\" نیاز دارد که روی دستگاه شما نصب نیست.\n\nآیا می‌خواهید هم اکنون آن را دانلود و نصب کنید?</string>
<string name="driver_download_cancelled">دانلود درایور لغو شد. بازی بدون درایور مورد نیاز قابل اجرا نیست.</string>
<string name="download">دانلود</string>
<!-- Emulation Menu -->
<string name="emulation_exit">خروج از شبیه‌سازی</string>
<string name="emulation_done">انجام شد</string>
@ -814,6 +866,12 @@
<string name="renderer_accuracy_high">زیاد</string>
<string name="renderer_accuracy_extreme">افراطی (کند)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">پیش فرض</string>
<string name="dma_accuracy_normal">معمولی</string>
<string name="dma_accuracy_high">بالا</string>
<string name="dma_accuracy_extreme">فوق العاده</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">Assure une diffusion fluide et régulière des frames en synchronisant leur timing, réduisant ainsi les saccades et les animations irrégulières. Idéal pour les jeux souffrant d`instabilité de timing des frames ou de micro-saccades pendant le jeu.</string>
<string name="renderer_early_release_fences">Libérer les barrières plus tôt</string>
<string name="renderer_early_release_fences_description">Résout les problèmes de 0 FPS dans des jeux comme DKCR:HD, Subnautica Below Zero et Ori 2, mais peut perturber le chargement ou les performances des jeux Unreal Engine.</string>
<string name="sync_memory_operations">Synchroniser les opérations mémoire</string>
<string name="sync_memory_operations_description">Garantit la cohérence des données entre les opérations de calcul et de mémoire. Cette option devrait résoudre les problèmes dans certains jeux, mais peut réduire les performances dans certains cas. Les jeux utilisant Unreal Engine 4 semblent être les plus affectés.</string>
<string name="buffer_reorder_disable">Désactiver le réordonnancement du tampon</string>
<string name="buffer_reorder_disable_description">Lorsqu\'il est coché, désactive le réordonnancement des téléchargements de mémoire mappée, permettant d\'associer les téléchargements à des dessins spécifiques. Peut réduire les performances dans certains cas.</string>
<string name="use_lru_cache">Activer le cache LRU</string>
<string name="use_lru_cache_description">Active ou désactive le cache LRU pour améliorer les performances en réduisant l\'utilisation du processeur. Certains jeux comme TotK 1.2.1 ont des problèmes - désactivez-le si le jeu ne démarre pas ou plante aléatoirement.</string>
<string name="dyna_state">État dynamique étendu</string>
<string name="dyna_state_description">Active les fonctionnalités Vulkan pour améliorer les performances, le rendu et économiser les ressources lors de la création des pipelines tout en maintenant une utilisation réduite du CPU/GPU. Ces extensions peuvent augmenter la température de l\'appareil et les GPU anciens de la série A6XX peuvent mal réagir. Désactivez pour émuler les formats mis à l\'échelle.</string>
<string name="dyna_state_description">Contrôle le nombre de fonctionnalités utilisables dans l\'état dynamique étendu. Des valeurs plus élevées permettent plus de fonctionnalités et peuvent augmenter les performances, mais peuvent causer des problèmes avec certains pilotes et fabricants. La valeur par défaut peut varier selon votre système et vos capacités matérielles. Cette valeur peut être modifiée jusqu\'à obtenir une stabilité et une meilleure qualité visuelle.</string>
<string name="disabled">Désactivé</string>
<string name="use_sync_core">Synchroniser la vitesse du cœur</string>
<string name="use_sync_core_description">Synchronise la vitesse du cœur avec le pourcentage de vitesse maximal pour améliorer les performances sans modifier la vitesse réelle du jeu.</string>
@ -117,11 +119,17 @@
<string name="memory_layout_description">(EXPÉRIMENTAL) Change la disposition de la mémoire émulée. Ce paramètre n\'augmente pas les performances, mais peut aider les jeux utilisant des résolutions élevées via des mods. Ne pas utiliser sur les téléphones avec 8 Go de RAM ou moins.</string>
<string name="sample_shading">Échantillonnage de shading</string>
<string name="sample_shading_description">Permet au fragment shader de s\'exécuter par échantillon dans un fragment multi-échantillonné au lieu d\'une fois par fragment. Améliore la qualité graphique au détriment des performances. Seuls les appareils Vulkan 1.1+ prennent en charge cette extension.</string>
<string name="sample_shading_fraction">Fraction d\'ombrage d\'échantillon</string>
<string name="sample_shading_fraction_description">L\'intensité de la passe d\'ombrage d\'échantillon. Des valeurs plus élevées améliorent davantage la qualité mais réduisent aussi plus fortement les performances.</string>
<string name="custom_cpu_ticks">Ticks CPU personnalisés</string>
<string name="custom_cpu_ticks_description">Définissez une valeur personnalisée de ticks CPU. Des valeurs plus élevées peuvent améliorer les performances, mais peuvent aussi provoquer des gels du jeu. Une plage de 77 à 21000 est recommandée.</string>
<string name="cpu_ticks">Ticks</string>
<string name="skip_cpu_inner_invalidation">Ignorer l\'invalidation interne du CPU</string>
<string name="skip_cpu_inner_invalidation_description">Ignore certaines invalidations de cache côté CPU lors des mises à jour mémoire, réduisant l\'utilisation du CPU et améliorant ses performances. Peut causer des bugs ou plantages sur certains jeux.</string>
<string name="cpuopt_unsafe_host_mmu">Activer l\'émulation de la MMU hôte</string>
<string name="cpuopt_unsafe_host_mmu_description">Cette optimisation accélère les accès mémoire par le programme invité. L\'activer entraîne que les lectures/écritures mémoire de l\'invité sont effectuées directement en mémoire et utilisent la MMU de l\'hôte. Désactiver cela force tous les accès mémoire à utiliser l\'émulation logicielle de la MMU.</string>
<string name="dma_accuracy">Niveau DMA</string>
<string name="dma_accuracy_description">Contrôle la précision du DMA. Une précision plus élevée peut résoudre les problèmes dans certains jeux, mais peut aussi affecter les performances dans certains cas. Si vous n\'êtes pas sûr, laissez-la sur Défaut.</string>
<string name="memory_4gb">4 Go (Recommandé)</string>
<string name="memory_6gb">6 Go (Dangereux)</string>
@ -793,6 +801,50 @@
<string name="loader_requires_firmware">Jeu nécessite un firmware</string>
<string name="loader_requires_firmware_description"><![CDATA[Ce jeu nécessite un firmware pour démarrer ou passer le menu d\'accueil. Veuillez <a href="https://yuzu-mirror.github.io/help/quickstart">dumper et installer le firmware</a> ou appuyez sur "OK" pour continuer quand même.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">Recherche du jeu...</string>
<string name="game_not_found_for_title_id">Jeu non trouvé pour l\'ID de titre : %1$s</string>
<string name="custom_settings_failed_title">Échec des paramètres personnalisés</string>
<string name="custom_settings_failed_message">Échec de l\'application des paramètres personnalisés pour %1$s : %2$s</string>
<string name="launch_with_default_settings">Lancer avec les paramètres par défaut</string>
<string name="launch_cancelled">Lancement annulé</string>
<string name="custom_settings_failure_reasons">Impossible d\'appliquer les paramètres demandés. Cela peut être dû à des pilotes GPU manquants ou à des problèmes de configuration.</string>
<string name="custom_settings_applied">Paramètres personnalisés appliqués</string>
<string name="launching_game">Lancement de %1$s...</string>
<string name="failed_to_initialize_game">Échec de l\'initialisation du jeu</string>
<string name="custom_intent_launch_message_with_settings">Voulez-vous lancer %1$s avec des paramètres personnalisés ?</string>
<string name="custom_intent_launch_message">Voulez-vous lancer %1$s ?</string>
<string name="custom_intent_launch_title">Lancer le jeu</string>
<string name="launch">Lancer</string>
<!-- Custom Config strings -->
<string name="config_write_failed">Échec de l\'écriture du fichier de configuration</string>
<string name="config_apply_failed">Échec de l\'application de la configuration</string>
<string name="config_already_exists_title">Configuration déjà existante</string>
<string name="config_already_exists_message">Des paramètres personnalisés existent déjà pour %1$s.\n\nVoulez-vous écraser la configuration existante ?\n\nCette action ne peut pas être annulée.</string>
<string name="config_exists_prompt">Vérification de la configuration existante...</string>
<string name="overwrite_cancelled">Écrasement annulé</string>
<string name="checking_driver">Vérification du pilote personnalisé : %1$s</string>
<string name="driver_unavailable">Pilote personnalisé non disponible pour cet appareil</string>
<string name="overwrite">Écraser</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">Pilote GPU manquant</string>
<string name="missing_gpu_driver_message">Le pilote personnalisé sélectionné \"%s\" n\'est pas installé. Voulez-vous le télécharger et l\'installer maintenant ?</string>
<string name="downloading_driver">Téléchargement du pilote...</string>
<string name="driver_installed">Pilote installé avec succès</string>
<string name="driver_installation_failed_title">Échec de l\'installation du pilote</string>
<string name="driver_installation_failed_message">Échec de l\'installation du pilote GPU : %s</string>
<string name="driver_not_available_title">Pilote non disponible</string>
<string name="driver_not_available_message">Le pilote sélectionné n\'est pas disponible au téléchargement.</string>
<string name="driver_not_found">Pilote requis non installé : %s</string>
<string name="invalid_driver_file">Fichier de pilote invalide : %s</string>
<string name="network_unavailable">Aucune connexion réseau disponible. Veuillez vérifier votre connexion Internet et réessayer.</string>
<string name="driver_missing_title">Pilote GPU requis</string>
<string name="driver_missing_message">La configuration du jeu nécessite le pilote GPU \"%s\" qui n\'est pas installé sur votre appareil.\n\nVoulez-vous le télécharger et l\'installer maintenant ?</string>
<string name="driver_download_cancelled">Téléchargement du pilote annulé. Le jeu ne peut pas être lancé sans le pilote requis.</string>
<string name="download">Télécharger</string>
<!-- Emulation Menu -->
<string name="emulation_exit">Quitter l\'émulation</string>
<string name="emulation_done">Terminé</string>
@ -863,6 +915,12 @@
<string name="renderer_accuracy_high">Haut</string>
<string name="renderer_accuracy_extreme">Extrême (Lent)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Défaut</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Élevé</string>
<string name="dma_accuracy_extreme">Extrême</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">מבטיח אספקה חלקה ועקבית של פריימים על ידי סנכרון התזמון ביניהם, מפחית קפיצות ואנימציה לא אחידה. אידיאלי למשחקים עם בעיות בתזמון פריימים או מיקרו-קפיצות במהלך המשחק.</string>
<string name="renderer_early_release_fences">שחרר גדרות מוקדם</string>
<string name="renderer_early_release_fences_description">עוזר לתקן 0 FPS במשחקים כמו DKCR:HD, Subnautica Below Zero ו-Ori 2, אך עלול לפגוע בטעינה או בביצועים במשחקי Unreal Engine.</string>
<string name="sync_memory_operations">סנכרון פעולות זיכרון</string>
<string name="sync_memory_operations_description">מבטיח עקביות נתונים בין פעולות חישוב וזיכרון. אפשרות זו אמורה לתקן בעיות במשחקים מסוימים, אך עלולה להפחית ביצועים במקרים מסוימים. נראה שהמשחקים עם Unreal Engine 4 הם המושפעים ביותר.</string>
<string name="buffer_reorder_disable">השבת סידור מחדש של חוצץ</string>
<string name="buffer_reorder_disable_description">כאשר מסומן, מבטל את סידור מחדש של העלאות זיכרון ממופה המאפשר לשייך העלאות עם ציורים ספציפיים. עלול להפחית ביצועים במקרים מסוימים.</string>
<string name="use_lru_cache">הפעלת מטמון LRU</string>
<string name="use_lru_cache_description">הפעל או השבת מטמון LRU לשיפור ביצועים על ידי חיסכון בשימוש במעבד. לחלק מהמשחקים כמו TotK 1.2.1 יש בעיות - השבת אם המשחק לא עולה או קורס באקראי.</string>
<string name="dyna_state">מצב דינמי מורחב</string>
<string name="dyna_state_description">מאפשר תכונות Vulkan לשיפור ביצועים, רינדור וחיסכון במשאבים בעת יצירת צינורות עיבוד תוך שמירה על שימוש נמוך במעבד/מעבד גרפי. הרחבות אלו עלולות להעלות את טמפרטורת המכשיר, ומעבדים גרפיים מקו A6XX הישן עשויים לא להגיב כראוי. השבת כדי לדמות פורמטים מוקטנים.</string>
<string name="dyna_state_description">שולט במספר התכונות שניתן להשתמש בהן במצב דינמי מורחב. מספרים גבוהים יותר מאפשרים יותר תכונות ויכולים לשפר את הביצועים, אך עלולים לגרום לבעיות עם כמה מנהלי התקנים וספקים. הערך המוגדר כברירת מחדל עשוי להשתנות בהתאם למערכת שלך ויכולות החומרה. ניתן לשנות ערך זה עד להשגת יציבות ואיכות ויזואלית טובה יותר.</string>
<string name="disabled">מושבת</string>
<string name="use_sync_core">סנכרון מהירות ליבה</string>
<string name="use_sync_core_description">סנכרן את מהירות הליבה לאחוז המהירות המרבי כדי לשפר ביצועים מבלי לשנות את מהירות המשחק בפועל.</string>
@ -118,11 +120,17 @@
<string name="memory_layout_description">(ניסיוני) שנה את מבנה הזיכרון המדומה. הגדרה זו לא תגדיל את הביצועים, אך עשויה לעזור במשחקים המשתמשים ברזולוציות גבוהות באמצעות מודים. אל תשתמש בטלפונים עם 8GB זיכרון RAM או פחות.</string>
<string name="sample_shading">דגימת צל</string>
<string name="sample_shading_description">מאפשר לשברי הצללה לרוץ לכל דגימה בקטע רב-דגימות במקום פעם אחת לקטע. משפר את איכות הגרפיקה במחיר של ביצועים. רק מכשירי Vulkan 1.1+ תומכים בהרחבה זו.</string>
<string name="sample_shading_fraction">שבר הצללה לדוגמה</string>
<string name="sample_shading_fraction_description">עוצמת מעבר ההצללה לדוגמה. ערכים גבוהים יותר משפרים את האיכות יותר אך גם מפחיתים את הביצועים במידה רבה יותר.</string>
<string name="custom_cpu_ticks">טיקי CPU מותאמים</string>
<string name="custom_cpu_ticks_description">הגדר ערך מותאם לטיקי CPU. ערכים גבוהים יותר עשויים לשפר ביצועים, אך גם עלולים לגרום להקפאת המשחק. מומלץ טווח של 77-21000.</string>
<string name="cpu_ticks">טיקים</string>
<string name="skip_cpu_inner_invalidation">דלג על איפוס מטמון פנימי של המעבד</string>
<string name="skip_cpu_inner_invalidation_description">מדלג על איפוסי מטמון מסוימים במהלך עדכוני זיכרון, מפחית שימוש במעבד ומשפר ביצועים. עלול לגרום לתקלות או קריסות בחלק מהמשחקים.</string>
<string name="cpuopt_unsafe_host_mmu">הפעל אמולציית MMU מארח</string>
<string name="cpuopt_unsafe_host_mmu_description">אופטימיזציה זו מאיצה את גישת הזיכרון על ידי התוכנית האורחת. הפעלתה גורמת לכך שפעולות קריאה/כתיבה לזיכרון האורח מתבצעות ישירות לזיכרון ומשתמשות ב-MMU של המארח. השבתת זאת מאלצת את כל גישות הזיכרון להשתמש באמולציית MMU תוכנתית.</string>
<string name="dma_accuracy">רמת DMA</string>
<string name="dma_accuracy_description">שולטת בדיוק הדיוק של DMA. דיוק גבוה יותר יכול לתקן בעיות בחלק מהמשחקים, אך הוא עלול גם להשפיע על הביצועים במקרים מסוימים. אם אינך בטוח, השאר ברירת מחדל.</string>
<string name="memory_4gb">4GB (מומלץ)</string>
<string name="memory_6gb">6GB (לא בטוח)</string>
@ -679,6 +687,50 @@
<string name="loader_requires_firmware">המשחק דורש קושחה</string>
<string name="loader_requires_firmware_description"><![CDATA[המשחק שאתה מנסה להפעיל דורש קושחה לאתחול או למעבר מתפריט הפתיחה. אנא <a href="https://yuzu-mirror.github.io/help/quickstart">שמור והתקן קושחה</a> או לחץ "אישור" כדי להמשיך בכל מקרה.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">מחפש משחק...</string>
<string name="game_not_found_for_title_id">משחק לא נמצא למזהה כותרת: %1$s</string>
<string name="custom_settings_failed_title">הגדרות מותאמות אישית נכשלו</string>
<string name="custom_settings_failed_message">נכשל בהחלת הגדרות מותאמות אישית עבור %1$s: %2$s</string>
<string name="launch_with_default_settings">הפעל עם הגדרות ברירת מחדל</string>
<string name="launch_cancelled">ההפעלה בוטלה</string>
<string name="custom_settings_failure_reasons">לא ניתן להחיל את ההגדרות המבוקשות. זה עשוי להיות עקב חסרון מנהלי התקן של GPU או בעיות תצורה.</string>
<string name="custom_settings_applied">הגדרות מותאמות אישית הוחלו</string>
<string name="launching_game">מפעיל את %1$s...</string>
<string name="failed_to_initialize_game">נכשל באתחול המשחק</string>
<string name="custom_intent_launch_message_with_settings">האם ברצונך להפעיל את %1$s עם הגדרות מותאמות אישית?</string>
<string name="custom_intent_launch_message">האם ברצונך להפעיל את %1$s?</string>
<string name="custom_intent_launch_title">הפעל משחק</string>
<string name="launch">הפעל</string>
<!-- Custom Config strings -->
<string name="config_write_failed">נכשל בכתיבת קובץ התצורה</string>
<string name="config_apply_failed">נכשל בהחלת התצורה</string>
<string name="config_already_exists_title">תצורה כבר קיימת</string>
<string name="config_already_exists_message">הגדרות מותאמות אישית כבר קיימות עבור %1$s.\n\nהאם ברצונך לדרוס את התצורה הקיימת?\n\nפעולה זו לא ניתנת לביטול.</string>
<string name="config_exists_prompt">בודק אם קיימת תצורה...</string>
<string name="overwrite_cancelled">דריסה בוטלה</string>
<string name="checking_driver">בודק מנהל התקן מותאם אישית: %1$s</string>
<string name="driver_unavailable">מנהל התקן מותאם אישית לא זמין למכשיר זה</string>
<string name="overwrite">דרוס</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">מנהל התקן GPU חסר</string>
<string name="missing_gpu_driver_message">מנהל ההתקן המותאם אישית הנבחר \"%s\" אינו מותקן. האם ברצונך להוריד ולהתקין אותו כעת?</string>
<string name="downloading_driver">מוריד מנהל התקן...</string>
<string name="driver_installed">מנהל ההתקן הותקן בהצלחה</string>
<string name="driver_installation_failed_title">התקנת מנהל ההתקן נכשלה</string>
<string name="driver_installation_failed_message">נכשלה התקנת מנהל ההתקן של GPU: %s</string>
<string name="driver_not_available_title">מנהל התקן לא זמין</string>
<string name="driver_not_available_message">מנהל ההתקן הנבחר אינו זמין להורדה.</string>
<string name="driver_not_found">מנהל התקן נדרש לא מותקן: %s</string>
<string name="invalid_driver_file">קובץ מנהל התקן לא חוקי: %s</string>
<string name="network_unavailable">אין חיבור אינטרנט זמין. אנא בדוק את חיבור האינטרנט שלך ונסה שוב.</string>
<string name="driver_missing_title">נדרש מנהל התקן GPU</string>
<string name="driver_missing_message">תצורת המשחק דורשת מנהל התקן GPU \"%s\" אשר אינו מותקן במכשירך.\n\nהאם ברצונך להוריד ולהתקין אותו כעת?</string>
<string name="driver_download_cancelled">הורדת מנהל ההתקן בוטלה. לא ניתן להפעיל את המשחק ללא מנהל ההתקן הנדרש.</string>
<string name="download">הורד</string>
<!-- Emulation Menu -->
<string name="emulation_exit">צא מהאמולציה</string>
<string name="emulation_done">סיום</string>
@ -745,6 +797,12 @@
<string name="renderer_accuracy_high">גבוה</string>
<string name="renderer_accuracy_extreme">אקסטרים (איטי)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">ברירת מחדל</string>
<string name="dma_accuracy_normal">רגיל</string>
<string name="dma_accuracy_high">גבוה</string>
<string name="dma_accuracy_extreme">קיצוני</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">Biztosítja a képkockák sima és egyenletes kézbesítését azok időzítésének szinkronizálásával, csökkentve a megakadásokat és egyenetlen animációkat. Ideális azokhoz a játékokhoz, amelyek képkocka-időzítési instabilitást vagy mikro-reccsenést tapasztalnak játék közben.</string>
<string name="renderer_early_release_fences">Korai kerítés-felszabadítás</string>
<string name="renderer_early_release_fences_description">Segít javítani a 0 FPS-t olyan játékokban, mint a DKCR:HD, Subnautica Below Zero és az Ori 2, de ronthatja az Unreal Engine játékok betöltését vagy teljesítményét.</string>
<string name="sync_memory_operations">Memória-műveletek szinkronizálása</string>
<string name="sync_memory_operations_description">Biztosítja az adatok konzisztenciáját a számítási és memória-műveletek között. Ez az opciónak javítania kell néhány játékban előforduló problémát, de bizonyos esetekben csökkentheti a teljesítményt. Az Unreal Engine 4-et használó játékok látszanak a legérintettebbek.</string>
<string name="buffer_reorder_disable">Puffer újrarendezés letiltása</string>
<string name="buffer_reorder_disable_description">Ha be van jelölve, letiltja a leképezett memória feltöltéseinek újrarendezését, lehetővé téve a feltöltések összerendelését konkrét rajzolásokkal. Bizonyos esetekben csökkentheti a teljesítményt.</string>
<string name="use_lru_cache">LRU gyorsítótár engedélyezése</string>
<string name="use_lru_cache_description">Engedélyezi vagy letiltja az LRU gyorsítótárat, növelve a teljesítményt a CPU használat csökkentésével. Néhány játéknak (különösen a TotK 1.2.1-nek) problémája lehet vele - tiltsa le, ha a játék nem indul el vagy véletlenszerűen összeomlik.</string>
<string name="dyna_state">Kiterjesztett Dinamikus Állapot</string>
<string name="dyna_state_description">Engedélyezi a Vulkan funkciókat a teljesítmény, renderelés javítására és erőforrások spórolására a pipeline létrehozásánál, miközben alacsony CPU/GPU használatot tart fenn. Ezek a kiterjesztések növelhetik az eszköz hőmérsékletét, és a régebbi A6XX sorozatú GPU-k nem feltétlenül működnek megfelelően. Tiltsa le a skálázott formátumok emulálásához.</string>
<string name="dyna_state_description">Szabályozza a Kiterjesztett Dynamikus Állapotban használható funkciók számát. A magasabb értékek több funkciót tesznek lehetővé és növelhetik a teljesítményt, de problémákat okozhatnak egyes meghajtókkal és gyártókkal. Az alapértelmezett érték eltérő lehet a rendszertől és a hardverképességektől függően. Ez az érték módosítható, amíg el nem éri a stabilitást és a jobb vizuális minőséget.</string>
<string name="disabled">Letiltva</string>
<string name="use_sync_core">Magsebesség szinkronizálása</string>
<string name="use_sync_core_description">A mag sebességének szinkronizálása a maximális sebesség százalékával a teljesítmény javítása érdekében a játék tényleges sebességének megváltoztatása nélkül.</string>
@ -117,11 +119,17 @@
<string name="memory_layout_description">(KÍSÉRLETI) Megváltoztatja az emulált memórialayoutot. Ez a beállítás nem növeli a teljesítményt, de segíthet a magas felbontást használó játékokban modok segítségével. Ne használd 8GB RAM vagy kevesebb rendelkező telefonokon.</string>
<string name="sample_shading">Mintavételezés árnyékolás</string>
<string name="sample_shading_description">Lehetővé teszi, hogy a fragment shader mintánként fusson egy többmintás fragmentben a fragmentenkénti futtatás helyett. Javítja a grafikai minőséget a teljesítmény rovására. Csak Vulkan 1.1+ eszközök támogatják ezt a kiterjesztést.</string>
<string name="sample_shading_fraction">Mintavételezés árnyékolási hányad</string>
<string name="sample_shading_fraction_description">A mintavételezés árnyékolási lépés intenzitása. A magasabb értékek jobb minőséget eredményeznek, de nagyobb mértékben csökkentik a teljesítményt.</string>
<string name="custom_cpu_ticks">Egyéni CPU tick-ek</string>
<string name="custom_cpu_ticks_description">Egyéni CPU tick érték beállítása. A magasabb értékek növelhetik a teljesítményt, de a játék befagyását is okozhatják. 7721000 közötti tartomány ajánlott.</string>
<string name="cpu_ticks">Tick-ek</string>
<string name="skip_cpu_inner_invalidation">CPU belső érvénytelenítés kihagyása</string>
<string name="skip_cpu_inner_invalidation_description">Kihagy néhány CPU-oldali gyorsítótár-érvénytelenítést memóriafrissítések közben, csökkentve a CPU használatát és javítva a teljesítményt. Néhány játékban hibákat vagy összeomlást okozhat.</string>
<string name="cpuopt_unsafe_host_mmu">Gazda MMU emuláció engedélyezése</string>
<string name="cpuopt_unsafe_host_mmu_description">Ez az optimalizáció gyorsítja a vendégprogram memória-hozzáférését. Engedélyezése esetén a vendég memóriaolvasási/írási műveletei közvetlenül a memóriában történnek, és kihasználják a gazda MMU-ját. Letiltás esetén minden memória-hozzáférés a szoftveres MMU emulációt használja.</string>
<string name="dma_accuracy">DMA szint</string>
<string name="dma_accuracy_description">Szabályozza a DMA pontosságát. A magasabb pontosság megoldhat néhány játék problémáit, de bizonyos esetekben befolyásolhatja a teljesítményt. Ha bizonytalan, hagyja Alapértelmezett beállításnál.</string>
<string name="memory_4gb">4GB (Ajánlott)</string>
<string name="memory_6gb">6GB (Nem biztonságos)</string>
@ -783,6 +791,50 @@
<string name="loader_requires_firmware">A játék firmware-t igényel</string>
<string name="loader_requires_firmware_description"><![CDATA[A játék, amelyet el szeretne indítani, firmware-t igényel a bootoláshoz vagy a kezdőmenü átlépéséhez. Kérjük, <a href="https://yuzu-mirror.github.io/help/quickstart"> dumpolja és telepítse a firmware-t</a>, vagy nyomja meg az "OK" gombot a folytatáshoz.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">Játék keresése...</string>
<string name="game_not_found_for_title_id">A játék nem található a következő címazonosítóhoz: %1$s</string>
<string name="custom_settings_failed_title">Egyéni beállítások sikertelenek</string>
<string name="custom_settings_failed_message">Nem sikerült alkalmazni az egyéni beállításokat ehhez: %1$s: %2$s</string>
<string name="launch_with_default_settings">Indítás alapértelmezett beállításokkal</string>
<string name="launch_cancelled">Indítás megszakítva</string>
<string name="custom_settings_failure_reasons">Nem sikerült alkalmazni a kért beállításokat. Ennek oka hiányzó GPU illesztőprogramok vagy konfigurációs problémák lehetnek.</string>
<string name="custom_settings_applied">Egyéni beállítások alkalmazva</string>
<string name="launching_game">%1$s indítása...</string>
<string name="failed_to_initialize_game">A játék inicializálása sikertelen</string>
<string name="custom_intent_launch_message_with_settings">Szeretné elindítani a(z) %1$s-t egyéni beállításokkal?</string>
<string name="custom_intent_launch_message">Szeretné elindítani a(z) %1$s-t?</string>
<string name="custom_intent_launch_title">Játék indítása</string>
<string name="launch">Indítás</string>
<!-- Custom Config strings -->
<string name="config_write_failed">A konfigurációs fájl írása sikertelen</string>
<string name="config_apply_failed">A konfiguráció alkalmazása sikertelen</string>
<string name="config_already_exists_title">A konfiguráció már létezik</string>
<string name="config_already_exists_message">Már léteznek egyéni beállítások a(z) %1$s számára.\n\nSzeretné felülírni a meglévő konfigurációt?\n\nEzt a műveletet nem lehet visszavonni.</string>
<string name="config_exists_prompt">Létező konfiguráció keresése...</string>
<string name="overwrite_cancelled">A felülírás megszakítva</string>
<string name="checking_driver">Egyéni illesztőprogram ellenőrzése: %1$s</string>
<string name="driver_unavailable">Egyéni illesztőprogram nem elérhető ehhez az eszközhöz</string>
<string name="overwrite">Felülírás</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">GPU illesztőprogram hiányzik</string>
<string name="missing_gpu_driver_message">A kiválasztott egyéni illesztőprogram \"%s\" nincs telepítve. Szeretné most letölteni és telepíteni?</string>
<string name="downloading_driver">Illesztőprogram letöltése...</string>
<string name="driver_installed">Az illesztőprogram sikeresen telepítve</string>
<string name="driver_installation_failed_title">Az illesztőprogram telepítése sikertelen</string>
<string name="driver_installation_failed_message">Nem sikerült telepíteni a GPU illesztőprogramot: %s</string>
<string name="driver_not_available_title">Az illesztőprogram nem elérhető</string>
<string name="driver_not_available_message">A kiválasztott illesztőprogram nem érhető el letöltésre.</string>
<string name="driver_not_found">A szükséges illesztőprogram nincs telepítve: %s</string>
<string name="invalid_driver_file">Érvénytelen illesztőprogramfájl: %s</string>
<string name="network_unavailable">Nincs hálózati kapcsolat. Kérjük, ellenőrizze az internetkapcsolatát, és próbálja újra.</string>
<string name="driver_missing_title">GPU illesztőprogram szükséges</string>
<string name="driver_missing_message">A játék konfigurációja \"%s\" GPU illesztőprogramot igényel, amely nincs telepítve az eszközén.\n\nSzeretné most letölteni és telepíteni?</string>
<string name="driver_download_cancelled">Az illesztőprogram letöltése megszakítva. A játék nem indítható el a szükséges illesztőprogram nélkül.</string>
<string name="download">Letöltés</string>
<!-- Emulation Menu -->
<string name="emulation_exit">Emuláció bezárása</string>
<string name="emulation_done">Kész</string>
@ -852,6 +904,12 @@
<string name="renderer_accuracy_high">Magas</string>
<string name="renderer_accuracy_extreme">Extrém (Lassú)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Alapértelmezett</string>
<string name="dma_accuracy_normal">Normál</string>
<string name="dma_accuracy_high">Magas</string>
<string name="dma_accuracy_extreme">Extrém</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">Memastikan pengiriman frame yang halus dan konsisten dengan menyinkronkan waktu antar frame, mengurangi stuttering dan animasi tidak rata. Ideal untuk game yang mengalami ketidakstabilan waktu frame atau micro-stutter selama gameplay.</string>
<string name="renderer_early_release_fences">Lepas Pagar Lebih Awal</string>
<string name="renderer_early_release_fences_description">Membantu memperbaiki 0 FPS di game seperti DKCR:HD, Subnautica Below Zero dan Ori 2, tapi mungkin mengganggu loading atau performa di game Unreal Engine.</string>
<string name="sync_memory_operations">Sinkronisasi Operasi Memori</string>
<string name="sync_memory_operations_description">Memastikan konsistensi data antara operasi komputasi dan memori. Opsi ini seharusnya memperbaiki masalah di beberapa game, tetapi mungkin mengurangi performa dalam beberapa kasus. Game dengan Unreal Engine 4 tampaknya yang paling terpengaruh.</string>
<string name="buffer_reorder_disable">Nonaktifkan Penyusunan Ulang Buffer</string>
<string name="buffer_reorder_disable_description">Ketika dicentang, menonaktifkan penyusunan ulang unggahan memori yang dipetakan yang memungkinkan mengaitkan unggahan dengan gambar tertentu. Dapat mengurangi kinerja dalam beberapa kasus.</string>
<string name="use_lru_cache">Aktifkan LRU Cache</string>
<string name="use_lru_cache_description">Aktifkan atau nonaktifkan cache LRU untuk meningkatkan performa dengan mengurangi penggunaan proses CPU. Beberapa game seperti TotK 1.2.1 memiliki masalah - nonaktifkan jika game tidak mau berjalan atau crash acak.</string>
<string name="dyna_state">Status Dinamis Ekstensi</string>
<string name="dyna_state_description">Aktifkan fitur Vulkan untuk meningkatkan performa, rendering dan menghemat sumber daya saat pembuatan pipeline sambil mempertahankan penggunaan CPU/GPU yang rendah. Ekstensi ini dapat meningkatkan suhu perangkat, dan GPU seri A6XX lama mungkin tidak merespons dengan benar. Nonaktifkan untuk emulasi format skala.</string>
<string name="dyna_state_description">Mengontrol jumlah fitur yang dapat digunakan dalam Extended Dynamic State. Angka yang lebih tinggi memungkinkan lebih banyak fitur dan dapat meningkatkan performa, tetapi dapat menyebabkan masalah dengan beberapa driver dan vendor. Nilai default dapat bervariasi tergantung pada sistem dan kemampuan hardware Anda. Nilai ini dapat diubah hingga stabilitas dan kualitas visual yang lebih baik tercapai.</string>
<string name="disabled">Dinonaktifkan</string>
<string name="use_sync_core">Sinkronisasi Kecepatan Inti</string>
<string name="use_sync_core_description">Sinkronkan kecepatan inti dengan persentase kecepatan maksimum untuk meningkatkan performa tanpa mengubah kecepatan sebenarnya dari permainan.</string>
@ -117,11 +119,17 @@
<string name="memory_layout_description">(EKSPERIMENTAL) Ubah tata letak memori emulasi. Pengaturan ini tidak meningkatkan kinerja, tetapi dapat membantu game yang menggunakan resolusi tinggi melalui mod. Jangan gunakan pada ponsel dengan RAM 8GB atau kurang.</string>
<string name="sample_shading">Pencahayaan Sampel</string>
<string name="sample_shading_description">Memungkinkan fragment shader dieksekusi per sampel dalam fragmen multisampel alih-alih sekali per fragmen. Meningkatkan kualitas grafis dengan mengorbankan kinerja. Hanya perangkat Vulkan 1.1+ yang mendukung ekstensi ini.</string>
<string name="sample_shading_fraction">Fraksi Pencahayaan Sampel</string>
<string name="sample_shading_fraction_description">Intensitas proses pencahayaan sampel. Nilai lebih tinggi meningkatkan kualitas lebih baik tetapi juga mengurangi performa lebih besar.</string>
<string name="custom_cpu_ticks">Ticks CPU Kustom</string>
<string name="custom_cpu_ticks_description">Atur nilai ticks CPU kustom. Nilai yang lebih tinggi dapat meningkatkan kinerja, tetapi juga dapat menyebabkan game membeku. Kisaran 7721000 direkomendasikan.</string>
<string name="cpu_ticks">Ticks</string>
<string name="skip_cpu_inner_invalidation">Lewati Pembatalan Internal CPU</string>
<string name="skip_cpu_inner_invalidation_description">Melewati beberapa pembatalan cache sisi CPU selama pembaruan memori, mengurangi penggunaan CPU dan meningkatkan kinerjanya. Mungkin menyebabkan gangguan atau crash pada beberapa game.</string>
<string name="cpuopt_unsafe_host_mmu">Aktifkan Emulasi MMU Host</string>
<string name="cpuopt_unsafe_host_mmu_description">Optimasi ini mempercepat akses memori oleh program tamu. Mengaktifkannya menyebabkan pembacaan/penulisan memori tamu dilakukan langsung ke memori dan memanfaatkan MMU Host. Menonaktifkan ini memaksa semua akses memori menggunakan Emulasi MMU Perangkat Lunak.</string>
<string name="dma_accuracy">Level DMA</string>
<string name="dma_accuracy_description">Mengontrol akurasi presisi DMA. Presisi yang lebih tinggi dapat memperbaiki masalah di beberapa game, tetapi juga dapat memengaruhi performa dalam beberapa kasus. Jika tidak yakin, biarkan di Bawaan.</string>
<string name="memory_4gb">4GB (Direkomendasikan)</string>
<string name="memory_6gb">6GB (Tidak Aman)</string>
@ -737,6 +745,50 @@
<string name="loader_requires_firmware">Game memerlukan firmware</string>
<string name="loader_requires_firmware_description"><![CDATA[Game yang ingin Anda jalankan memerlukan firmware untuk boot atau melewati menu pembuka. Silakan <a href="https://yuzu-mirror.github.io/help/quickstart"> dump dan instal firmware</a>, atau tekan "OK" untuk melanjutkan.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">Mencari game...</string>
<string name="game_not_found_for_title_id">Game tidak ditemukan untuk ID Judul: %1$s</string>
<string name="custom_settings_failed_title">Pengaturan Kustom Gagal</string>
<string name="custom_settings_failed_message">Gagal menerapkan pengaturan kustom untuk %1$s: %2$s</string>
<string name="launch_with_default_settings">Luncurkan dengan Pengaturan Default</string>
<string name="launch_cancelled">Peluncuran dibatalkan</string>
<string name="custom_settings_failure_reasons">Tidak dapat menerapkan pengaturan yang diminta. Ini mungkin karena driver GPU yang hilang atau masalah konfigurasi.</string>
<string name="custom_settings_applied">Pengaturan kustom diterapkan</string>
<string name="launching_game">Meluncurkan %1$s...</string>
<string name="failed_to_initialize_game">Gagal menginisialisasi game</string>
<string name="custom_intent_launch_message_with_settings">Apakah Anda ingin meluncurkan %1$s dengan pengaturan kustom?</string>
<string name="custom_intent_launch_message">Apakah Anda ingin meluncurkan %1$s?</string>
<string name="custom_intent_launch_title">Luncurkan Game</string>
<string name="launch">Luncurkan</string>
<!-- Custom Config strings -->
<string name="config_write_failed">Gagal menulis file konfigurasi</string>
<string name="config_apply_failed">Gagal menerapkan konfigurasi</string>
<string name="config_already_exists_title">Konfigurasi Sudah Ada</string>
<string name="config_already_exists_message">Pengaturan kustom sudah ada untuk %1$s.\n\nApakah Anda ingin menimpa konfigurasi yang ada?\n\nTindakan ini tidak dapat dibatalkan.</string>
<string name="config_exists_prompt">Memeriksa konfigurasi yang ada...</string>
<string name="overwrite_cancelled">Penimpaan dibatalkan</string>
<string name="checking_driver">Memeriksa driver kustom: %1$s</string>
<string name="driver_unavailable">Driver kustom tidak tersedia untuk perangkat ini</string>
<string name="overwrite">Timpa</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">Driver GPU Hilang</string>
<string name="missing_gpu_driver_message">Driver kustom yang dipilih \"%s\" tidak terinstal. Apakah Anda ingin mengunduh dan menginstalnya sekarang?</string>
<string name="downloading_driver">Mengunduh driver...</string>
<string name="driver_installed">Driver berhasil diinstal</string>
<string name="driver_installation_failed_title">Instalasi Driver Gagal</string>
<string name="driver_installation_failed_message">Gagal menginstal driver GPU: %s</string>
<string name="driver_not_available_title">Driver Tidak Tersedia</string>
<string name="driver_not_available_message">Driver yang dipilih tidak tersedia untuk diunduh.</string>
<string name="driver_not_found">Driver yang diperlukan tidak terinstal: %s</string>
<string name="invalid_driver_file">File driver tidak valid: %s</string>
<string name="network_unavailable">Tidak ada koneksi jaringan yang tersedia. Silakan periksa koneksi internet Anda dan coba lagi.</string>
<string name="driver_missing_title">Driver GPU Diperlukan</string>
<string name="driver_missing_message">Konfigurasi game memerlukan driver GPU \"%s\" yang tidak terinstal di perangkat Anda.\n\nApakah Anda ingin mengunduh dan menginstalnya sekarang?</string>
<string name="driver_download_cancelled">Pengunduhan driver dibatalkan. Game tidak dapat diluncurkan tanpa driver yang diperlukan.</string>
<string name="download">Unduh</string>
<!-- Emulation Menu -->
<string name="emulation_exit">Keluar</string>
<string name="emulation_done">Selesai</string>
@ -807,6 +859,12 @@
<string name="renderer_accuracy_high">Tinggi</string>
<string name="renderer_accuracy_extreme">Ekstrim (Lambat)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Bawaan</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Tinggi</string>
<string name="dma_accuracy_extreme">Ekstrem</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">Garantisce una consegna fluida e costante dei fotogrammi sincronizzandone i tempi, riducendo scatti e animazioni irregolari. Ideale per giochi che presentano instabilità nei tempi dei fotogrammi o micro-scatti durante il gameplay.</string>
<string name="renderer_early_release_fences">Rilascia le barriere prima</string>
<string name="renderer_early_release_fences_description">Risolve problemi di 0 FPS in giochi come DKCR:HD, Subnautica Below Zero e Ori 2, ma potrebbe compromettere caricamento o prestazioni in giochi Unreal Engine.</string>
<string name="sync_memory_operations">Sincronizza operazioni di memoria</string>
<string name="sync_memory_operations_description">Garantisce la coerenza dei dati tra le operazioni di calcolo e memoria. Questa opzione dovrebbe risolvere problemi in alcuni giochi, ma potrebbe ridurre le prestazioni in alcuni casi. I giochi con Unreal Engine 4 sembrano essere i più colpiti.</string>
<string name="buffer_reorder_disable">Disabilita riordino buffer</string>
<string name="buffer_reorder_disable_description">Se selezionato, disabilita il riordino dei caricamenti di memoria mappata consentendo di associare i caricamenti a disegni specifici. Potrebbe ridurre le prestazioni in alcuni casi.</string>
<string name="use_lru_cache">Abilita cache LRU</string>
<string name="use_lru_cache_description">Abilita o disabilita la cache LRU per migliorare le prestazioni riducendo l\'uso della CPU. Alcuni giochi come TotK 1.2.1 hanno problemi - disabilitalo se il gioco non si avvia o crasha casualmente.</string>
<string name="dyna_state">Stato dinamico esteso</string>
<string name="dyna_state_description">Abilita le funzionalità Vulkan per migliorare prestazioni, rendering e risparmiare risorse durante la creazione della pipeline mantenendo un basso utilizzo di CPU/GPU. Queste estensioni possono aumentare la temperatura del dispositivo e le GPU della vecchia serie A6XX potrebbero non rispondere correttamente. Disabilita per emulare formati scalati.</string>
<string name="dyna_state_description">Controlla il numero di funzioni utilizzabili nello Stato Dinamico Esteso. Valori più alti consentono più funzioni e possono aumentare le prestazioni, ma potrebbero causare problemi con alcuni driver e vendor. Il valore predefinito può variare in base al sistema e alle capacità hardware. Questo valore può essere modificato finché non si raggiunge la stabilità e una migliore qualità visiva.</string>
<string name="disabled">Disabilitato</string>
<string name="use_sync_core">Sincronizza velocità core</string>
<string name="use_sync_core_description">Sincronizza la velocità del core con la percentuale massima di velocità per migliorare le prestazioni senza alterare la velocità effettiva del gioco.</string>
@ -117,11 +119,17 @@
<string name="memory_layout_description">(SPERIMENTALE) Cambia il layout della memoria emulata. Questa impostazione non aumenta le prestazioni, ma può aiutare nei giochi che utilizzano alte risoluzioni tramite mod. Non usare su telefoni con 8GB di RAM o meno.</string>
<string name="sample_shading">Shading campione</string>
<string name="sample_shading_description">Permette al fragment shader di eseguire per campione in un frammento multi-campione invece che una volta per frammento. Migliora la qualità grafica a scapito delle prestazioni. Solo i dispositivi Vulkan 1.1+ supportano questa estensione.</string>
<string name="sample_shading_fraction">Frazione di ombreggiatura campione</string>
<string name="sample_shading_fraction_description">L\'intensità della passata di ombreggiatura campione. Valori più alti migliorano la qualità ma riducono maggiormente le prestazioni.</string>
<string name="custom_cpu_ticks">Tick CPU personalizzati</string>
<string name="custom_cpu_ticks_description">Imposta un valore personalizzato per i tick della CPU. Valori più alti possono aumentare le prestazioni, ma possono anche causare il blocco del gioco. Si consiglia un intervallo di 7721000.</string>
<string name="cpu_ticks">Tick</string>
<string name="skip_cpu_inner_invalidation">Salta invalidamento interno CPU</string>
<string name="skip_cpu_inner_invalidation_description">Salta alcuni invalidamenti della cache lato CPU durante gli aggiornamenti di memoria, riducendo l\'uso della CPU e migliorandone le prestazioni. Potrebbe causare glitch o crash in alcuni giochi.</string>
<string name="cpuopt_unsafe_host_mmu">Abilita emulazione MMU host</string>
<string name="cpuopt_unsafe_host_mmu_description">Questa ottimizzazione accelera gli accessi alla memoria da parte del programma guest. Abilitandola, le letture/scritture della memoria guest vengono eseguite direttamente in memoria e sfruttano la MMU host. Disabilitandola, tutti gli accessi alla memoria sono costretti a utilizzare l\'emulazione software della MMU.</string>
<string name="dma_accuracy">Livello DMA</string>
<string name="dma_accuracy_description">Controlla la precisione del DMA. Una precisione più alta può risolvere problemi in alcuni giochi, ma in alcuni casi può influire sulle prestazioni. Se non sei sicuro, lascia su Predefinito.</string>
<string name="memory_4gb">4GB (Consigliato)</string>
<string name="memory_6gb">6GB (Non sicuro)</string>
@ -710,6 +718,50 @@
<string name="loader_requires_firmware">Il gioco richiede firmware</string>
<string name="loader_requires_firmware_description"><![CDATA[Il gioco che stai cercando di avviare richiede firmware per l\'avvio o per superare il menu iniziale. Per favore <a href="https://yuzu-mirror.github.io/help/quickstart"> dumpa e installa il firmware</a>, o premi "OK" per continuare comunque.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">Ricerca del gioco in corso...</string>
<string name="game_not_found_for_title_id">Gioco non trovato per l\'ID titolo: %1$s</string>
<string name="custom_settings_failed_title">Impostazioni personalizzate non riuscite</string>
<string name="custom_settings_failed_message">Impossibile applicare le impostazioni personalizzate per %1$s: %2$s</string>
<string name="launch_with_default_settings">Avvia con impostazioni predefinite</string>
<string name="launch_cancelled">Avvio annullato</string>
<string name="custom_settings_failure_reasons">Impossibile applicare le impostazioni richieste. Ciò potrebbe essere dovuto a driver GPU mancanti o problemi di configurazione.</string>
<string name="custom_settings_applied">Impostazioni personalizzate applicate</string>
<string name="launching_game">Avvio di %1$s...</string>
<string name="failed_to_initialize_game">Impossibile inizializzare il gioco</string>
<string name="custom_intent_launch_message_with_settings">Vuoi avviare %1$s con impostazioni personalizzate?</string>
<string name="custom_intent_launch_message">Vuoi avviare %1$s?</string>
<string name="custom_intent_launch_title">Avvia gioco</string>
<string name="launch">Avvia</string>
<!-- Custom Config strings -->
<string name="config_write_failed">Impossibile scrivere il file di configurazione</string>
<string name="config_apply_failed">Impossibile applicare la configurazione</string>
<string name="config_already_exists_title">Configurazione già esistente</string>
<string name="config_already_exists_message">Impostazioni personalizzate già esistenti per %1$s.\n\nVuoi sovrascrivere la configurazione esistente?\n\nQuesta azione non può essere annullata.</string>
<string name="config_exists_prompt">Verifica della configurazione esistente...</string>
<string name="overwrite_cancelled">Sovrascrittura annullata</string>
<string name="checking_driver">Verifica del driver personalizzato: %1$s</string>
<string name="driver_unavailable">Driver personalizzato non disponibile per questo dispositivo</string>
<string name="overwrite">Sovrascrivi</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">Driver GPU mancante</string>
<string name="missing_gpu_driver_message">Il driver personalizzato selezionato \"%s\" non è installato. Vuoi scaricarlo e installarlo ora?</string>
<string name="downloading_driver">Download del driver in corso...</string>
<string name="driver_installed">Driver installato correttamente</string>
<string name="driver_installation_failed_title">Installazione del driver non riuscita</string>
<string name="driver_installation_failed_message">Impossibile installare il driver GPU: %s</string>
<string name="driver_not_available_title">Driver non disponibile</string>
<string name="driver_not_available_message">Il driver selezionato non è disponibile per il download.</string>
<string name="driver_not_found">Driver richiesto non installato: %s</string>
<string name="invalid_driver_file">File driver non valido: %s</string>
<string name="network_unavailable">Nessuna connessione di rete disponibile. Controlla la connessione Internet e riprova.</string>
<string name="driver_missing_title">Driver GPU richiesto</string>
<string name="driver_missing_message">La configurazione del gioco richiede il driver GPU \"%s\" che non è installato sul tuo dispositivo.\n\nVuoi scaricarlo e installarlo ora?</string>
<string name="driver_download_cancelled">Download del driver annullato. Il gioco non può essere avviato senza il driver richiesto.</string>
<string name="download">Scarica</string>
<!-- Emulation Menu -->
<string name="emulation_exit">Arresta emulazione</string>
<string name="emulation_done">Fatto</string>
@ -776,6 +828,12 @@
<string name="renderer_accuracy_high">Alta</string>
<string name="renderer_accuracy_extreme">Estrema (Lenta)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Predefinito</string>
<string name="dma_accuracy_normal">Normale</string>
<string name="dma_accuracy_high">Alto</string>
<string name="dma_accuracy_extreme">Estremo</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">フレーム間のタイミングを同期させることで、スムーズで一貫したフレーム配信を確保し、カクつきや不均一なアニメーションを軽減します。フレームタイミングの不安定さやマイクロスタッターが発生するゲームに最適です。</string>
<string name="renderer_early_release_fences">フェンスを早期に解放</string>
<string name="renderer_early_release_fences_description">DKCR:HD、Subnautica Below Zero、Ori 2などのゲームで0 FPSを修正しますが、Unreal Engineゲームの読み込みやパフォーマンスに影響する可能性があります。</string>
<string name="sync_memory_operations">メモリ操作の同期</string>
<string name="sync_memory_operations_description">計算処理とメモリ操作間のデータ一貫性を保証します。 このオプションは一部のゲームの問題を修正しますが、場合によってはパフォーマンスが低下する可能性があります。 Unreal Engine 4のゲームが最も影響を受けるようです。</string>
<string name="buffer_reorder_disable">バッファの再並べ替えを無効化</string>
<string name="buffer_reorder_disable_description">チェック時、マップされたメモリのアップロードの再並べ替えを無効化し、特定の描画に関連付けることができます。場合によってはパフォーマンスが低下する可能性があります。</string>
<string name="use_lru_cache">LRUキャッシュを有効化</string>
<string name="use_lru_cache_description">LRUキャッシュを有効/無効にし、CPUプロセスの使用を節約してパフォーマンスを向上させます。TotK 1.2.1など一部のゲームで問題が発生する可能性があるため、ゲームが起動しない場合やランダムにクラッシュする場合は無効にしてください。</string>
<string name="dyna_state">拡張ダイナミックステート</string>
<string name="dyna_state_description">Vulkan機能を有効にし、パイプライン作成時のCPU/GPU使用率を低く保ちながら、パフォーマンス、レンダリング、リソース節約を改善します。これらの拡張機能はデバイスの温度を上昇させる可能性があり、旧A6XXシリーズのGPUは正しく反応しない場合があります。スケールフォーマットをエミュレートするには無効にしてください</string>
<string name="dyna_state_description">拡張ダイナミックステートで使用できる機能の数を制御します。数値が高いほどより多くの機能が使用可能になり、パフォーマンスが向上する可能性がありますが、一部のドライバーやベンダーで問題が発生する可能性があります。デフォルト値は、お使いのシステムとハードウェアの機能によって異なります。安定性とより良い画質が得られるまでこの値を変更できます</string>
<string name="disabled">無効</string>
<string name="use_sync_core">コア速度の同期</string>
<string name="use_sync_core_description">コアの速度を最大速度パーセンテージに同期させ、ゲームの実際の速度を変えずにパフォーマンスを向上させます。</string>
@ -117,11 +119,17 @@
<string name="memory_layout_description">(実験的) エミュレートされたメモリレイアウトを変更します。この設定はパフォーマンスを向上させませんが、modを介して高解像度を利用するゲームに役立つ場合があります。8GB以下のRAMを搭載した電話では使用しないでください。</string>
<string name="sample_shading">サンプルシェーディング</string>
<string name="sample_shading_description">マルチサンプルフラグメントでフラグメントシェーダーをフラグメントごとではなくサンプルごとに実行できるようにします。パフォーマンスを犠牲にしてグラフィック品質を向上させます。Vulkan 1.1+デバイスのみがこの拡張機能をサポートしています。</string>
<string name="sample_shading_fraction">サンプルシェーディング率</string>
<string name="sample_shading_fraction_description">サンプルシェーディング処理の強度。高い値ほど品質は向上しますが、パフォーマンスも大きく低下します。</string>
<string name="custom_cpu_ticks">カスタムCPUティック</string>
<string name="custom_cpu_ticks_description">CPUティックのカスタム値を設定します。高い値はパフォーマンスを向上させる可能性がありますが、ゲームがフリーズする可能性もあります。77〜21000の範囲が推奨されます。</string>
<string name="cpu_ticks">ティック</string>
<string name="skip_cpu_inner_invalidation">CPU内部無効化をスキップ</string>
<string name="skip_cpu_inner_invalidation_description">メモリ更新時のCPU側キャッシュ無効化をスキップし、CPU使用率を減らして性能を向上させます。一部のゲームで不具合やクラッシュが発生する可能性があります。</string>
<string name="cpuopt_unsafe_host_mmu">ホストMMUエミュレーションを有効化</string>
<string name="cpuopt_unsafe_host_mmu_description">この最適化により、ゲストプログラムによるメモリアクセスが高速化されます。有効にすると、ゲストのメモリ読み書きが直接メモリ内で実行され、ホストのMMUを利用します。無効にすると、すべてのメモリアクセスでソフトウェアMMUエミュレーションが使用されます。</string>
<string name="dma_accuracy">DMAレベル</string>
<string name="dma_accuracy_description">DMAの精度を制御します。精度を高くすると一部のゲームの問題が修正される場合がありますが、場合によってはパフォーマンスに影響を与える可能性もあります。不明な場合は、デフォルトのままにしてください。</string>
<string name="memory_4gb">4GB (推奨)</string>
<string name="memory_6gb">6GB (安全でない)</string>
@ -669,6 +677,50 @@
<string name="loader_requires_firmware">ゲームにはファームウェアが必要です</string>
<string name="loader_requires_firmware_description"><![CDATA[起動しようとしているゲームは、起動または開始メニューを通過するためにファームウェアが必要です。<a href="https://yuzu-mirror.github.io/help/quickstart"> ファームウェアをダンプしてインストール</a>するか、"OK"を押して続行してください。]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">ゲームを検索中...</string>
<string name="game_not_found_for_title_id">タイトルID: %1$s のゲームが見つかりません</string>
<string name="custom_settings_failed_title">カスタム設定の失敗</string>
<string name="custom_settings_failed_message">%1$s のカスタム設定の適用に失敗しました: %2$s</string>
<string name="launch_with_default_settings">デフォルト設定で起動</string>
<string name="launch_cancelled">起動がキャンセルされました</string>
<string name="custom_settings_failure_reasons">要求された設定を適用できません。GPUドライバーの不足または設定の問題が原因である可能性があります。</string>
<string name="custom_settings_applied">カスタム設定が適用されました</string>
<string name="launching_game">%1$s を起動中...</string>
<string name="failed_to_initialize_game">ゲームの初期化に失敗しました</string>
<string name="custom_intent_launch_message_with_settings">%1$s をカスタム設定で起動しますか?</string>
<string name="custom_intent_launch_message">%1$s を起動しますか?</string>
<string name="custom_intent_launch_title">ゲームを起動</string>
<string name="launch">起動</string>
<!-- Custom Config strings -->
<string name="config_write_failed">設定ファイルの書き込みに失敗しました</string>
<string name="config_apply_failed">設定の適用に失敗しました</string>
<string name="config_already_exists_title">設定が既に存在します</string>
<string name="config_already_exists_message">%1$s のカスタム設定は既に存在します。\n\n既存の設定を上書きしますか\n\nこの操作は元に戻せません。</string>
<string name="config_exists_prompt">既存の設定を確認中...</string>
<string name="overwrite_cancelled">上書きがキャンセルされました</string>
<string name="checking_driver">カスタムドライバーを確認中: %1$s</string>
<string name="driver_unavailable">このデバイスではカスタムドライバーは利用できません</string>
<string name="overwrite">上書き</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">GPUドライバーが見つかりません</string>
<string name="missing_gpu_driver_message">選択したカスタムドライバー \"%s\" がインストールされていません。今すぐダウンロードしてインストールしますか?</string>
<string name="downloading_driver">ドライバーをダウンロード中...</string>
<string name="driver_installed">ドライバーが正常にインストールされました</string>
<string name="driver_installation_failed_title">ドライバーのインストールに失敗しました</string>
<string name="driver_installation_failed_message">GPUドライバーのインストールに失敗しました: %s</string>
<string name="driver_not_available_title">ドライバーが利用できません</string>
<string name="driver_not_available_message">選択したドライバーはダウンロードできません。</string>
<string name="driver_not_found">必要なドライバーがインストールされていません: %s</string>
<string name="invalid_driver_file">無効なドライバーファイル: %s</string>
<string name="network_unavailable">ネットワーク接続が利用できません。インターネット接続を確認してからもう一度お試しください。</string>
<string name="driver_missing_title">GPUドライバーが必要です</string>
<string name="driver_missing_message">ゲーム設定にはGPUドライバー \"%s\" が必要ですが、お使いのデバイスにインストールされていません。\n\n今すぐダウンロードしてインストールしますか</string>
<string name="driver_download_cancelled">ドライバーのダウンロードがキャンセルされました。必要なドライバーがないとゲームを起動できません。</string>
<string name="download">ダウンロード</string>
<!-- Emulation Menu -->
<string name="emulation_exit">終了</string>
<string name="emulation_done">完了</string>
@ -735,6 +787,12 @@
<string name="renderer_accuracy_high"></string>
<string name="renderer_accuracy_extreme">最高 (低速)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">デフォルト</string>
<string name="dma_accuracy_normal">標準</string>
<string name="dma_accuracy_high"></string>
<string name="dma_accuracy_extreme">最高</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

View file

@ -78,12 +78,14 @@
<string name="frame_interpolation_description">프레임 간 타이밍을 동기화하여 부드럽고 일관된 프레임 전달을 보장하며, 끊김과 불균일한 애니메이션을 줄입니다. 프레임 타이밍 불안정이나 게임 플레이 중 미세 끊김이 발생하는 게임에 이상적입니다.</string>
<string name="renderer_early_release_fences">펜스 조기 해제</string>
<string name="renderer_early_release_fences_description">DKCR:HD, Subnautica Below Zero, Ori 2 등의 게임에서 0 FPS 현상을 해결하지만, Unreal Engine 게임의 로딩이나 성능에 문제를 일으킬 수 있습니다.</string>
<string name="sync_memory_operations">메모리 작업 동기화</string>
<string name="sync_memory_operations_description">컴퓨팅 및 메모리 작업 간 데이터 일관성을 보장합니다. 이 옵션은 일부 게임의 문제를 해결할 수 있지만 경우에 따라 성능이 저하될 수 있습니다. Unreal Engine 4 게임이 가장 큰 영향을 받는 것으로 보입니다.</string>
<string name="buffer_reorder_disable">버퍼 재정렬 비활성화</string>
<string name="buffer_reorder_disable_description">체크 시, 매핑된 메모리 업로드의 재정렬을 비활성화하여 특정 그리기와 업로드를 연결할 수 있습니다. 경우에 따라 성능이 저하될 수 있습니다.</string>
<string name="use_lru_cache">LRU 캐시 사용</string>
<string name="use_lru_cache_description">LRU 캐시를 활성화 또는 비활성화하여 CPU 프로세스 사용을 절약하고 성능을 향상시킵니다. TotK 1.2.1을 포함한 일부 게임에서 문제가 발생할 수 있으므로 게임이 부팅되지 않거나 무작위로 충돌하는 경우 비활성화하세요.</string>
<string name="dyna_state">확장 동적 상태</string>
<string name="dyna_state_description">파이프라인 생성 시 CPU/GPU 사용량을 낮게 유지하면서 성능, 렌더링 및 리소스 절약을 개선하기 위해 Vulkan 기능을 활성화합니다. 이 확장 기능은 장치 온도를 높일 수 있으며 이전 A6XX 라인에 속하는 GPU가 제대로 반응하지 않을 수 있습니다. 스케일된 형식을 에뮬레이트하려면 비활성화하세요.</string>
<string name="dyna_state_description">확장 동적 상태에서 사용할 수 있는 기능의 수를 제어합니다. 높은 값은 더 많은 기능을 허용하고 성능을 높일 수 있지만, 일부 드라이버 및 벤더에서 문제를 일으킬 수 있습니다. 기본값은 시스템 및 하드웨어 기능에 따라 다를 수 있습니다. 안정성과 더 나은 시각적 품질이 달성될 때까지 이 값을 변경할 수 있습니다.</string>
<string name="disabled">비활성화됨</string>
<string name="use_sync_core">코어 속도 동기화</string>
<string name="use_sync_core_description">코어 틱 속도를 최대 속도 백분율과 동기화하여 게임의 실제 속도를 변경하지 않고 성능을 향상시킵니다.</string>
@ -117,11 +119,17 @@
<string name="memory_layout_description">(실험적) 에뮬레이트된 메모리 레이아웃을 변경합니다. 이 설정은 성능을 높이지 않지만 모드를 통해 고해상도를 사용하는 게임에 도움이 될 수 있습니다. 8GB 이하 RAM의 휴대폰에서는 사용하지 마십시오.</string>
<string name="sample_shading">샘플 쉐이딩</string>
<string name="sample_shading_description">멀티샘플 프래그먼트에서 프래그먼트 쉐이더가 프래그먼트당 한 번이 아니라 샘플당 실행되도록 합니다. 성능을 희생하여 그래픽 품질을 향상시킵니다. Vulkan 1.1+ 장치만 이 확장을 지원합니다.</string>
<string name="sample_shading_fraction">샘플 쉐이딩 비율</string>
<string name="sample_shading_fraction_description">샘플 쉐이딩 패스의 강도. 값이 높을수록 품질이 더 향상되지만 성능도 더 크게 저하됩니다.</string>
<string name="custom_cpu_ticks">사용자 정의 CPU 틱</string>
<string name="custom_cpu_ticks_description">CPU 틱의 사용자 정의 값을 설정합니다. 높은 값은 성능을 향상시킬 수 있지만 게임이 멈출 수도 있습니다. 77~21000 범위를 권장합니다.</string>
<string name="cpu_ticks"></string>
<string name="skip_cpu_inner_invalidation">CPU 내부 무효화 건너뛰기</string>
<string name="skip_cpu_inner_invalidation_description">메모리 업데이트 시 일부 CPU 측 캐시 무효화를 건너뛰어 CPU 사용량을 줄이고 성능을 향상시킵니다. 일부 게임에서 오류 또는 충돌을 일으킬 수 있습니다.</string>
<string name="cpuopt_unsafe_host_mmu">호스트 MMU 에뮬레이션 사용</string>
<string name="cpuopt_unsafe_host_mmu_description">이 최적화는 게스트 프로그램의 메모리 접근 속도를 높입니다. 활성화하면 게스트의 메모리 읽기/쓰기가 메모리에서 직접 수행되고 호스트의 MMU를 활용합니다. 비활성화하면 모든 메모리 접근에 소프트웨어 MMU 에뮬레이션을 사용하게 됩니다.</string>
<string name="dma_accuracy">DMA 수준</string>
<string name="dma_accuracy_description">DMA 정밀도를 제어합니다. 높은 정밀도는 일부 게임의 문제를 해결할 수 있지만 경우에 따라 성능에 영향을 미칠 수도 있습니다. 확실하지 않다면 기본값으로 두세요.</string>
<string name="memory_4gb">4GB (권장)</string>
<string name="memory_6gb">6GB (안전하지 않음)</string>
@ -737,6 +745,50 @@
<string name="loader_requires_firmware">게임에 펌웨어가 필요합니다</string>
<string name="loader_requires_firmware_description"><![CDATA[실행하려는 게임은 부팅하거나 시작 메뉴를 통과하기 위해 펌웨어가 필요합니다. <a href="https://yuzu-mirror.github.io/help/quickstart">펌웨어를 덤프하여 설치</a>하거나 "확인"을 눌러 계속 진행하세요.]]></string>
<!-- Intent Launch strings -->
<string name="searching_for_game">게임 검색 중...</string>
<string name="game_not_found_for_title_id">타이틀 ID에 대한 게임을 찾을 수 없음: %1$s</string>
<string name="custom_settings_failed_title">사용자 지정 설정 실패</string>
<string name="custom_settings_failed_message">%1$s에 대한 사용자 지정 설정 적용 실패: %2$s</string>
<string name="launch_with_default_settings">기본 설정으로 실행</string>
<string name="launch_cancelled">실행 취소됨</string>
<string name="custom_settings_failure_reasons">요청한 설정을 적용할 수 없습니다. GPU 드라이버 누락 또는 구성 문제 때문일 수 있습니다.</string>
<string name="custom_settings_applied">사용자 지정 설정이 적용됨</string>
<string name="launching_game">%1$s 실행 중...</string>
<string name="failed_to_initialize_game">게임 초기화 실패</string>
<string name="custom_intent_launch_message_with_settings">%1$s을(를) 사용자 지정 설정으로 실행하시겠습니까?</string>
<string name="custom_intent_launch_message">%1$s을(를) 실행하시겠습니까?</string>
<string name="custom_intent_launch_title">게임 실행</string>
<string name="launch">실행</string>
<!-- Custom Config strings -->
<string name="config_write_failed">구성 파일 작성 실패</string>
<string name="config_apply_failed">구성 적용 실패</string>
<string name="config_already_exists_title">구성이 이미 존재함</string>
<string name="config_already_exists_message">%1$s에 대한 사용자 지정 설정이 이미 존재합니다.\n\n기존 구성을 덮어쓰시겠습니까?\n\n이 작업은 취소할 수 없습니다.</string>
<string name="config_exists_prompt">기존 구성 확인 중...</string>
<string name="overwrite_cancelled">덮어쓰기 취소됨</string>
<string name="checking_driver">사용자 지정 드라이버 확인 중: %1$s</string>
<string name="driver_unavailable">이 기기에서는 사용자 지정 드라이버를 사용할 수 없음</string>
<string name="overwrite">덮어쓰기</string>
<!-- Driver strings -->
<string name="missing_gpu_driver_title">GPU 드라이버 누락</string>
<string name="missing_gpu_driver_message">선택한 사용자 지정 드라이버 \"%s\"이(가) 설치되지 않았습니다. 지금 다운로드하여 설치하시겠습니까?</string>
<string name="downloading_driver">드라이버 다운로드 중...</string>
<string name="driver_installed">드라이버가 성공적으로 설치됨</string>
<string name="driver_installation_failed_title">드라이버 설치 실패</string>
<string name="driver_installation_failed_message">GPU 드라이버 설치 실패: %s</string>
<string name="driver_not_available_title">드라이버를 사용할 수 없음</string>
<string name="driver_not_available_message">선택한 드라이버를 다운로드할 수 없습니다.</string>
<string name="driver_not_found">필요한 드라이버가 설치되지 않았습니다: %s</string>
<string name="invalid_driver_file">잘못된 드라이버 파일: %s</string>
<string name="network_unavailable">사용 가능한 네트워크 연결이 없습니다. 인터넷 연결을 확인하고 다시 시도하십시오.</string>
<string name="driver_missing_title">GPU 드라이버 필요</string>
<string name="driver_missing_message">게임 구성에 GPU 드라이버 \"%s\"이(가) 필요하지만 기기에 설치되어 있지 않습니다.\n\n지금 다운로드하여 설치하시겠습니까?</string>
<string name="driver_download_cancelled">드라이버 다운로드가 취소되었습니다. 필요한 드라이버 없이는 게임을 실행할 수 없습니다.</string>
<string name="download">다운로드</string>
<!-- Emulation Menu -->
<string name="emulation_exit">에뮬레이션 종료</string>
<string name="emulation_done">완료</string>
@ -806,6 +858,12 @@
<string name="renderer_accuracy_high">높음</string>
<string name="renderer_accuracy_extreme">극한 (느림)</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">기본값</string>
<string name="dma_accuracy_normal">보통</string>
<string name="dma_accuracy_high">높음</string>
<string name="dma_accuracy_extreme">극단적</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
<string name="resolution_half">0.5X (360p/540p)</string>

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