Compare commits

...

10 Commits

Author SHA1 Message Date
pikminluvv
c698a10b23 Ryubing TR fixes (#143)
I've noticed some issues with the Turkish translation of Ryujinx. So I fixed and added certain translations.

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/143
2026-06-17 17:09:27 +00:00
Max
6d67a86efd 443 -libarmeillure-macos (#142)
Fixes [#443](https://github.com/Ryubing/Issues/issues/433)

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/142
2026-06-15 23:20:44 +00:00
LotP
e777e3f93b fix-tests (#140)
- downgrade unicorn to last working version
- update to new cp reg struct system
- remove nonexistent register (used to silently continue)
- fix partial unmap tests
    - InitializeSignalHandler() was moved out of the translator (almost 2.5 years ago), but the test code was never updated to manually call the function as it was changed to do in the real cpu context, so the tests just started failing.
    - by manually initializing the handler we no longer cause tests to fail.

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/140
2026-06-15 02:25:18 +00:00
KeatonTheBot
7b19e041cb Linux: Fix remaining file/folder picker issues (#24)
I fixed the remaining Linux file picker issues after testing on Steam Deck. User profile images, mod manager, title manager, and DLC directory were still using the old file picker methods and not the helper methods. I could only apply the helper method to user profiles, but I came up with a workaround for the others.

The reason for the draft PR: I'd ideally like to fix the other three at the helper level, so maybe @greem can help with that since since he wrote the initial implementation.

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/24
2026-06-15 01:44:24 +00:00
AllieNeedsSleep
e7a3c94b9c Discord RPC grammatical changes (#139)
Adjusted wording used in Discord RPC for clarity.

Co-authored-by: Allie <barstaxjolster@gmail.com>
Co-authored-by: sh0inx <randomgirlisweird@gmail.com>
Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/139
2026-06-14 22:13:59 +00:00
_Neo_
223f20868a UI: File Menu → General Improvements (#127)
Ayyyy, welcome to the UI: File Menu → General Improvements PR!

Wooo, we progressing smoothly!

This PR introduces small visual and "feature" improvements to the `File` menu.

### LOCALISATION:
* **Fractured:** More locales:
    * `Dialog_ContentLoading.json` - content loading dialogs (Updates/DLC)
    * `Dialog_FileTypeAssociations` - file association dialogs
    * `Dialog_FileMenu` - File menu dialog strings (complements `MenuBar_File.json`)
* **Added:** Additional entires to `Error.json`
* **Populated:** `MenuBar_File.json`

### FILE MENU:
* **Added:** Keyboard shortcuts to `Load Application` and `Load Unpacked Game`
    * Cmd + O/Ctrl + O and Cmd + Shift + O/Ctrl + Shift + O for macOS and other OS, respectively.
    * While many users rely on autoloaded game directories, manually opening content remains a common workflow (for those that don't rely on autoload directories).
* **Merged:** `Load Title Updates` and `Load DLC` → `Load Updates/DLC`
    * Both actions follow the same workflow: selecting one or more directories and allowing Ryujinx to load the content.
    * To reduce redundancy, they have been consolidated into a single menu item that loads both Updates and DLC simultaneously, mirroring the behavior of the existing autoload functionality.
    * As part of this change, Title Updates has been simplified to Updates for consistency with the rest of the UI. The remaining reference in the Game List context menu has also been updated from `Manage Title Updates` to `Manage Updates`.
* **Added/Updated:** File picker titles for content loading actions
    * `Load Application`: Select a Switch application file to load
    * `Load Unpacked Game`: Select a folder containing an unpacked Switch application to load
    * `Load Updates/DLC`: Select one or more folders to bulk load updates and DLC from
* **Improved:** `Associate File Types` and `Remove File Type Associations` (initially moved to the `File` menu in #42)
    * These options were previously nested under `Manage File Types` and exposed as `Install File Types` and `Uninstall File Types`. The submenu added unnecessary navigation, while the action names did not clearly communicate their purpose.
    * The two actions have been replaced with a single dynamic menu item, whose displayed and performed action updates based on the current association state. The respective icons have been added as well (imported namespace Projektanker.Icons to allow for dynamic switching):
        * Link → `Associate File Types`
        * Link-Slash →`Remove File Type Associations`
    * A tooltip has also been added to clarify the action being performed.
    * This option is only usable when a game is not running (why associate file types when running a game? Play the game!)
    * **Note:** These options are only available on Windows and Linux. macOS already provides robust per‑file “Open With” handling, so a custom association system isn’t necessary. Support can be added later if needed, but current macOS limitations in Ryujinx prevent certain behaviors; these will be addressed in future PRs.
* **Updated:** Menu Icons
    * Several icons have been updated to better reflect their associated actions and improve consistency throughout the menu:
        * `Load Updates/DLC...` now uses a single Inbox Tray icon instead of separate Update and DLC icons.
        * `Open Ryujinx Folder`, `Open Logs Folder`, and `Open Screenshots Folder` now share the same folder icon, as all three actions ultimately open a folder/directory.
        * `Exit` is now an Exit icon (arrow-right-from-bracket) instead of a Power button.

### OTHER:
* **Improved:** `Load Updates/DLC` dialog messages
    * Existing dialog messages were longer than necessary and included terms such as "missing" updates and "new" DLC.
    * These messages have been simplified and standardized:
        * Updates Added: {0} or Updates Removed: {0}
        * DLC Added: {0} or DLC Removed: {0}

_If there are any features or changes that you wish to be implemented, please comment down below and I'll be happy to accommodate!_

A GIGANTIC, ENORMOUSE HUUUUUUGEE thank you to @Babib3l for testing this and ensuring the commands work! WOOOOO!!!

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/127
2026-06-14 19:47:20 +00:00
_Neo_
8fe1a9c672 UI: Options Menu (Part 1 of 2) → General Improvements (#133)
Ayyyy, welcome to the UI: Options Menu → General Improvements PR!

We cruisin'!

This is the first PR of a small series aimed at improving the `Options` menu and related submenus.

This initial PR focuses on smaller visual and navigational improvements to the main `Options` menu. As this is part of a progressive series (two PRs _for now_), further bug fixes and refinements may be present in Part 2. Additionally, as the `View` menu is related to some of the changes presents in this PR, it has also received minor adjustments (see details below).

### LOCALISATION
* **Fractured:**
    * `MenuBar_Options.json` - `Options` menu locales
    * `MenuBar_View.json` - `View` menu locales
    * `Settings_Interface.json` - Interface `Settings` tab locales (UI-only)
* **Added:** Missing "e" in Italian translation of `User Profiles` (thank you BOBBIJDJ for pointing it out!)

**NOTE:** `MenuBar_View.json` and `Settings_Interface.json` were not populated in this PR.

### OPTIONS MENU
* **Moved:** `Toggle Fullscreen` to the `View` menu.
    * This option affects the current window/view state, so it belongs under `View` rather than `Options`.
* **Moved:** `Show Console` checkbox to the `View` menu.
    * Even though it was previously under `Options`, this is a real-time visibility toggle. It affects Ryujinx "immediately" (shows/hides the console window, and as immediately as you can get with our current implementation), so it fits better alongside other current view controls like `Toggle Fullscreen` and the `Window Size` presets.
* **Moved:** `Start Games in Fullscreen` and `Start Games Without UI` (renamed to "Hide UI on Game Start" for better flow) from the `Options` menu to the `Interface` tab in `Settings`.
    * These are persistent launch preferences rather than actions that can affect just the current session. Settings is the semantically correct location for them. They now sit alongside other launch-related options such as `Confirm Game Shutdown`.
    * Their respective locales were transferred to the newly created `Settings_Interface.json`.
* **Renamed:** `Change Language` → `Language`
    * Made consistent with the shorter style used by other items in this menu in previous cleanups.
* **Modified:** Menu item order (see images below).

### VIEW MENU
The `View` menu received only light adjustments in this PR (mainly padding/margins to better fit the newly added `Show Console` checkbox ). A dedicated _View Menu_ follow-up PR is planned to reorganise it further and add new options. Furthermore, _Options Menu (Part 2 of 2)_ will follow shortly as well.

_If there are any features or changes that you wish to be implemented, please comment down below and I'll be happy to accommodate!_

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/133
2026-06-14 19:21:25 +00:00
Renovate Bot
aad1a71f68 Update dependency Sep to 0.15.0 (#137)
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [Sep](https://github.com/nietras/Sep) | `0.14.1` → `0.15.0` | ![age](https://developer.mend.io/api/mc/badges/age/nuget/Sep/0.15.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/nuget/Sep/0.14.1/0.15.0?slim=true) |

---

### Release Notes

<details>
<summary>nietras/Sep (Sep)</summary>

### [`v0.15.0`](https://github.com/nietras/Sep/releases/tag/v0.15.0): 0.15.0

#### What's Changed

Minor breaking changes to API parameter names.

- Bump actions/setup-dotnet from 5.2.0 to 5.3.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;545](https://github.com/nietras/Sep/pull/545)
- Bump github/codeql-action from 4.35.3 to 4.36.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;544](https://github.com/nietras/Sep/pull/544)
- Bump codecov/codecov-action from 6.0.0 to 6.0.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;547](https://github.com/nietras/Sep/pull/547)
- Bump coverlet.collector from 10.0.0 to 10.0.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;549](https://github.com/nietras/Sep/pull/549)
- Bump actions/dependency-review-action from 4.9.0 to 5.0.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;548](https://github.com/nietras/Sep/pull/548)
- Bump step-security/harden-runner from 2.19.1 to 2.19.4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;546](https://github.com/nietras/Sep/pull/546)
- Bump MSTest from 4.2.2 to 4.2.3 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;550](https://github.com/nietras/Sep/pull/550)
- Fix typos: `degreeOfParallism` parameter name and missing quote in exception message by [@&#8203;Copilot](https://github.com/Copilot) in [#&#8203;551](https://github.com/nietras/Sep/pull/551)
- Remove unnessary `unsafe` usage by [@&#8203;nietras](https://github.com/nietras) in [#&#8203;552](https://github.com/nietras/Sep/pull/552)
- Address and remove TODOs by [@&#8203;nietras](https://github.com/nietras) in [#&#8203;554](https://github.com/nietras/Sep/pull/554)
- Fix Reader Spec forwarding, SepWriter dispose and README nits, expand tests by [@&#8203;nietras](https://github.com/nietras) in [#&#8203;555](https://github.com/nietras/Sep/pull/555)
- Bump github/codeql-action from 4.36.0 to 4.36.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;558](https://github.com/nietras/Sep/pull/558)
- Bump actions/checkout from 6.0.2 to 6.0.3 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;556](https://github.com/nietras/Sep/pull/556)
- Bump codecov/codecov-action from 6.0.1 to 7.0.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;557](https://github.com/nietras/Sep/pull/557)

**Full Changelog**: <https://github.com/nietras/Sep/compare/v0.14.1...v0.15.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzguMCIsInVwZGF0ZWRJblZlciI6IjQzLjE3OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/137
2026-06-14 18:59:33 +00:00
Renovate Bot
25120667f1 Update dependency Microsoft.IdentityModel.JsonWebTokens to 8.19.1 (#136)
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [Microsoft.IdentityModel.JsonWebTokens](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet) | `8.18.0` → `8.19.1` | ![age](https://developer.mend.io/api/mc/badges/age/nuget/Microsoft.IdentityModel.JsonWebTokens/8.19.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/nuget/Microsoft.IdentityModel.JsonWebTokens/8.18.0/8.19.1?slim=true) |

---

### Release Notes

<details>
<summary>AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet (Microsoft.IdentityModel.JsonWebTokens)</summary>

### [`v8.19.1`](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/HEAD/CHANGELOG.md#8191)

[Compare Source](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/compare/8.19.0...8.19.1)

\====

#### Bug Fixes

- Update `JwtSecurityTokenHandler` for `IssuerSigningKeyResolverUsingConfiguration` to take priority over `IssuerSigningKeyResolver`, matching the documented contract and the correct behavior already present in `JsonWebTokenHandler`. See [PR #&#8203;3519](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3519).

### [`v8.19.0`](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/HEAD/CHANGELOG.md#8190)

[Compare Source](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/compare/8.18.0...8.19.0)

\====

#### New Features

- Add ML-DSA (FIPS 204) post-quantum signature support. See [PR #&#8203;3479](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3479).
- Cache custom crypto providers in CryptoProviderFactory. See [PR #&#8203;3489](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3489).

#### Bug Fixes

- Disable automatic redirects on default HttpClient for JKU retrieval. See [PR #&#8203;3494](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3494).
- Adjust rented buffer handling in claim set parsing. See [PR #&#8203;3493](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3493).
- Tidy null handling in SAML conditions validation. See [PR #&#8203;3491](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3491).
- Improve validation of `jku` claim. See [PR #&#8203;3481](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3481).
- Limit telemetry algorithm dimension cardinality. See [PR #&#8203;3490](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3490).
- Add defensive copy of collections in ValidationParameters. See [PR #&#8203;3492](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3492).
- Update TokenValidationParameter copy constructor to make a deep copy. See [PR #&#8203;3488](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3488).
- Update to fail-closed when replay protection isn't configured and other DPoP hardening. See [PR #&#8203;3505](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3505).
- Apply RFC 3986 section 6.2.2 normalization to DPoP `htu` comparison. See [PR #&#8203;3509](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3509).

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzguMCIsInVwZGF0ZWRJblZlciI6IjQzLjE3OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/136
2026-06-14 18:53:00 +00:00
Renovate Bot
9061c3a2b3 Update dependency Ryujinx.Audio.OpenAL to 1.25.2 (#135)
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| Ryujinx.Audio.OpenAL | `1.25.1` → `1.25.2` | ![age](https://developer.mend.io/api/mc/badges/age/nuget/Ryujinx.Audio.OpenAL/1.25.2?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/nuget/Ryujinx.Audio.OpenAL/1.25.1/1.25.2?slim=true) |

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzguMCIsInVwZGF0ZWRJblZlciI6IjQzLjE3OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/135
2026-06-14 18:52:21 +00:00
36 changed files with 1244 additions and 996 deletions

View File

@@ -27,7 +27,7 @@
<PackageVersion Include="Humanizer" Version="2.14.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.18.0" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.19.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
@@ -43,7 +43,7 @@
<PackageVersion Include="Open.NAT.Core" Version="2.1.0.5" />
<!-- Ryujinx.Audio.OpenAL.Dependencies is from the original project, last updated 12/30/20 -->
<!--<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />-->
<PackageVersion Include="Ryujinx.Audio.OpenAL" Version="1.25.1" />
<PackageVersion Include="Ryujinx.Audio.OpenAL" Version="1.25.2" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.4-build6" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.MoltenVK" Version="1.4.2-ryujinx.3" />
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.133" />
@@ -51,7 +51,7 @@
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="2.0.6" />
<PackageVersion Include="Gommon" Version="2.8.1.2" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="Sep" Version="0.14.1" />
<PackageVersion Include="Sep" Version="0.15.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Shaderc" Version="2.23.0" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.23.0" />
@@ -63,6 +63,6 @@
<PackageVersion Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.9" />
<PackageVersion Include="SPB" Version="0.0.4-build32" />
<PackageVersion Include="System.IO.Hashing" Version="9.0.15" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.1.3" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.1.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,104 @@
{
"Locales": [
{
"ID": "UpdatesAddedMessage",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Updates Added: {0}",
"es_ES": "Actualizaciones Añadidas: {0}",
"fr_FR": "Mises à Jour Ajoutées : {0}",
"he_IL": "",
"it_IT": "Aggiornamenti aggiunti: {0}",
"ja_JP": "",
"ko_KR": "추가된 업데이트: {0}",
"no_NO": "Oppdateringer lagt til: {0}",
"pl_PL": "",
"pt_BR": "Atualizações adicionadas: {0}",
"ru_RU": "Добавлено обновлений: {0}",
"sv_SE": "Tillagda uppdateringar: {0}",
"th_TH": "การอัปเดตที่เพิ่มเข้ามา: {0}",
"tr_TR": "Eklenen güncelleştirmeler: {0}",
"uk_UA": "Додані оновлення: {0}",
"zh_CN": "已添加更新:{0}",
"zh_TW": "已新增更新:{0}"
}
},
{
"ID": "UpdatesRemovedMessage",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Updates Removed: {0}",
"es_ES": "Actualizaciones Eliminadas: {0}",
"fr_FR": "Mises à Jour Supprimées : {0}",
"he_IL": "",
"it_IT": "Aggiornamenti rimossi: {0}",
"ja_JP": "",
"ko_KR": "제거된 업데이트: {0}",
"no_NO": "Fjernede oppdateringer: {0}",
"pl_PL": "",
"pt_BR": "Atualizações removidas: {0}",
"ru_RU": "Удалено обновлений: {0}",
"sv_SE": "Borttagna uppdateringar: {0}",
"th_TH": "การอัปเดตที่ถูกลบ: {0}",
"tr_TR": "Silinen güncelleştirmeler: {0}",
"uk_UA": "Видалені оновлення: {0}",
"zh_CN": "已移除更新:{0}",
"zh_TW": "已移除更新:{0}"
}
},
{
"ID": "DLCAddedMessage",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "DLC Added: {0}",
"es_ES": "DLC Añadidos: {0}",
"fr_FR": "DLC Ajoutés : {0}",
"he_IL": "",
"it_IT": "DLC aggiunti: {0}",
"ja_JP": "",
"ko_KR": "추가된 DLC: {0}",
"no_NO": "DLC lagt til: {0}",
"pl_PL": "",
"pt_BR": "DLC adicionados: {0}",
"ru_RU": "Добавлено DLC: {0}",
"sv_SE": "Tillagda DLC: {0}",
"th_TH": "DLC ที่เพิ่มเข้ามา: {0}",
"tr_TR": "Eklenen DLC: {0}",
"uk_UA": "Додані DLC: {0}",
"zh_CN": "已添加 DLC{0}",
"zh_TW": "已新增 DLC{0}"
}
},
{
"ID": "DLCRemovedMessage",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "DLC Removed: {0}",
"es_ES": "DLC Eliminados: {0}",
"fr_FR": "DLC Supprimés : {0}",
"he_IL": "",
"it_IT": "DLC rimossi: {0}",
"ja_JP": "",
"ko_KR": "제거된 DLC: {0}",
"no_NO": "DLC fjernet: {0}",
"pl_PL": "",
"pt_BR": "DLC removidos: {0}",
"ru_RU": "Удалено DLC: {0}",
"sv_SE": "DLC borttaget: {0}",
"th_TH": "ลบ DLC: {0}",
"tr_TR": "Silinen DLC: {0}",
"uk_UA": "Видалено DLC: {0}",
"zh_CN": "已移除 DLC{0}",
"zh_TW": "已移除 DLC{0}"
}
}
]
}

View File

@@ -0,0 +1,79 @@
{
"Locales": [
{
"ID": "LoadApplicationFromFileFilePickerTitle",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Select a Switch application file to load",
"es_ES": "Selecciona un archivo de aplicación de Switch para cargar",
"fr_FR": "Sélectionnez un fichier dapplication Switch à charger",
"he_IL": "",
"it_IT": "Seleziona un file applicazione Switch da caricare",
"ja_JP": "",
"ko_KR": "로드할 Switch 애플리케이션 파일을 선택하세요",
"no_NO": "",
"pl_PL": "",
"pt_BR": "Selecione um arquivo de aplicativo Switch para carregar",
"ru_RU": "Выберите файл приложения Switch для загрузки",
"sv_SE": "Välj en Switch-applikationsfil att läsa in",
"th_TH": "",
"tr_TR": "Yüklenecek bir Switch oyun dosyası seçin",
"uk_UA": "Виберіть файл застосунку Switch для завантаження",
"zh_CN": "请选择要加载的 Switch 应用程序文件",
"zh_TW": "請選擇要載入的 Switch 應用程式檔案"
}
},
{
"ID": "LoadUnpackedApplicationFromFolderFilePickerTitle",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Select a folder containing an unpacked Switch application to load",
"es_ES": "Selecciona una carpeta que contenga una aplicación de Switch descomprimida para cargar",
"fr_FR": "Sélectionnez un dossier contenant une application Switch décompressée à charger",
"he_IL": "",
"it_IT": "Seleziona una cartella contenente unapplicazione Switch non compressa da caricare",
"ja_JP": "",
"ko_KR": "압축 해제된 Switch 애플리케이션이 포함된 폴더를 선택하여 로드하세요",
"no_NO": "",
"pl_PL": "",
"pt_BR": "Selecione uma pasta que contenha um aplicativo Switch descompactado para carregar",
"ru_RU": "Выберите папку, содержащую распакованное приложение Switch, для загрузки",
"sv_SE": "Välj en mapp som innehåller en uppackad Switch-applikation att läsa in",
"th_TH": "",
"tr_TR": "Yüklenecek çıkarılmış Switch dosyalarını barındıran bir dosya seçiniz",
"uk_UA": "Виберіть папку, що містить розпакований застосунок Switch, для завантаження",
"zh_CN": "请选择包含未打包 Switch 应用程序的文件夹以加载",
"zh_TW": "請選擇包含未解壓縮 Switch 應用程式的資料夾以載入"
}
},
{
"ID": "LoadUpdatesAndDLCFromFolderFilePickerTitle",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Select one or more folders to bulk load updates and DLC from",
"es_ES": "Selecciona una o más carpetas para cargar de forma masiva actualizaciones y DLC",
"fr_FR": "Sélectionnez un ou plusieurs dossiers pour charger en masse des mises à jour et des DLC",
"he_IL": "",
"it_IT": "Seleziona una o più cartelle da cui caricare in blocco aggiornamenti e DLC",
"ja_JP": "",
"ko_KR": "업데이트 및 DLC를 대량으로 로드할 폴더를 하나 이상 선택하세요",
"no_NO": "",
"pl_PL": "",
"pt_BR": "Selecione uma ou mais pastas para carregar em massa atualizações e DLC",
"ru_RU": "Выберите одну или несколько папок для массовой загрузки обновлений и DLC",
"sv_SE": "Välj en eller flera mappar för att massinläsa uppdateringar och DLC",
"th_TH": "",
"tr_TR": "Birden fazla güncelleştirme ve DLC yüklemek için bir ya da birden fazla dosya seçiniz",
"uk_UA": "Виберіть одну або кілька папок для масового завантаження оновлень і DLC",
"zh_CN": "请选择一个或多个文件夹以批量加载更新和 DLC",
"zh_TW": "請選擇一個或多個資料夾以批次載入更新與 DLC"
}
}
]
}

View File

@@ -0,0 +1,104 @@
{
"Locales": [
{
"ID": "AssociationSuccessMessage",
"Translations": {
"ar_SA": "تم ربط أنواع الملفات بنجاح.",
"de_DE": "Dateitypen erfolgreich zugeordnet.",
"el_GR": "Οι τύποι αρχείων συσχετίστηκαν με επιτυχία.",
"en_US": "Successfully associated file types.",
"es_ES": "¡Tipos de archivo asociados con éxito.",
"fr_FR": "Types de fichiers associés avec succès.",
"he_IL": "שיוך סוגי הקבצים בוצע בהצלחה.",
"it_IT": "Tipi di file associati con successo.",
"ja_JP": "ファイルの種類の関連付けに成功しました。",
"ko_KR": "파일 형식 연결에 성공했습니다.",
"no_NO": "Filtyper ble tilknyttet.",
"pl_PL": "Pomyślnie powiązano typy plików.",
"pt_BR": "Tipos de arquivo associados com sucesso.",
"ru_RU": "Типы файлов успешно связаны.",
"sv_SE": "Filtyper har kopplats.",
"th_TH": "เชื่อมโยงประเภทไฟล์สำเร็จแล้ว",
"tr_TR": "Dosya türleri başarıyla ilişkilendirildi.",
"uk_UA": "Типи файлів успішно пов’язані.",
"zh_CN": "文件类型关联成功。",
"zh_TW": "檔案類型關聯成功。"
}
},
{
"ID": "RemoveAssociationSuccessMessage",
"Translations": {
"ar_SA": "تمت إزالة ارتباطات أنواع الملفات بنجاح.",
"de_DE": "Dateitypzuordnungen erfolgreich entfernt.",
"el_GR": "Οι συσχετίσεις τύπων αρχείων αφαιρέθηκαν με επιτυχία.",
"en_US": "Successfully removed file type associations.",
"es_ES": "Asociaciones de tipos de archivo eliminadas con éxito.",
"fr_FR": "Associations de types de fichiers supprimées avec succès.",
"he_IL": "שיוכי סוגי הקבצים הוסרו בהצלחה.",
"it_IT": "Associazioni dei tipi di file rimosse con successo.",
"ja_JP": "ファイルの種類の関連付けの削除に成功しました。",
"ko_KR": "파일 형식 연결이 성공적으로 제거되었습니다.",
"no_NO": "Filtype-tilknytninger ble fjernet.",
"pl_PL": "Pomyślnie usunięto skojarzenia typów plików.",
"pt_BR": "Associações de tipos de arquivo removidas com sucesso.",
"ru_RU": "Связи типов файлов успешно удалены.",
"sv_SE": "Filtypsassociationer har tagits bort.",
"th_TH": "ลบการเชื่อมโยงประเภทไฟล์สำเร็จแล้ว",
"tr_TR": "Dosya türü ilişkilendirmeleri başarıyla kaldırıldı.",
"uk_UA": "Прив’язки типів файлів успішно видалено.",
"zh_CN": "文件类型关联已成功移除。",
"zh_TW": "檔案類型關聯已成功移除。"
}
},
{
"ID": "AssociationFailedMessage",
"Translations": {
"ar_SA": "فشل ربط أنواع الملفات.",
"de_DE": "Fehler beim Zuordnen der Dateitypen.",
"el_GR": "Απέτυχε η συσχέτιση των τύπων αρχείων.",
"en_US": "Failed to associate file types.",
"es_ES": "No se pudieron asociar los tipos de archivo.",
"fr_FR": "Échec de lassociation des types de fichiers.",
"he_IL": "שיוך סוגי הקבצים נכשל.",
"it_IT": "Associazione dei tipi di file non riuscita.",
"ja_JP": "ファイルの種類の関連付けに失敗しました。",
"ko_KR": "파일 형식 연결에 실패했습니다.",
"no_NO": "Klarte ikke å tilknytte filtyper.",
"pl_PL": "Nie udało się powiązać typów plików.",
"pt_BR": "Falha ao associar tipos de arquivo.",
"ru_RU": "Не удалось связать типы файлов.",
"sv_SE": "Det gick inte att koppla filtyper.",
"th_TH": "เชื่อมโยงประเภทไฟล์ไม่สำเร็จ",
"tr_TR": "Dosya türleri ilişkilendirilemedi.",
"uk_UA": "Не вдалося пов’язати типи файлів.",
"zh_CN": "文件类型关联失败。",
"zh_TW": "檔案類型關聯失敗。"
}
},
{
"ID": "RemoveAssociationFailedMessage",
"Translations": {
"ar_SA": "فشلت إزالة ارتباطات أنواع الملفات.",
"de_DE": "Das Entfernen der Dateitypzuordnungen ist fehlgeschlagen.",
"el_GR": "Η αφαίρεση των συσχετίσεων τύπων αρχείων απέτυχε.",
"en_US": "Failed to remove file type associations.",
"es_ES": "No se pudieron eliminar las asociaciones de tipos de archivo.",
"fr_FR": "Échec de la suppression des associations de types de fichiers.",
"he_IL": "הסרת שיוכי סוגי הקבצים נכשלה.",
"it_IT": "Rimozione delle associazioni dei tipi di file non riuscita.",
"ja_JP": "ファイルの種類の関連付けの削除に失敗しました。",
"ko_KR": "파일 형식 연결 제거에 실패했습니다.",
"no_NO": "Fjerning av filtype-tilknytninger mislyktes.",
"pl_PL": "Nie udało się usunąć skojarzeń typów plików.",
"pt_BR": "Falha ao remover associações de tipos de arquivo.",
"ru_RU": "Не удалось удалить связи типов файлов.",
"sv_SE": "Det gick inte att ta bort filtypsassociationer.",
"th_TH": "ไม่สามารถลบการเชื่อมโยงประเภทไฟล์ได้",
"tr_TR": "Dosya türü ilişkilendirmeleri kaldırılamadı.",
"uk_UA": "Не вдалося видалити прив’язки типів файлів.",
"zh_CN": "文件类型关联移除失败。",
"zh_TW": "無法移除檔案類型關聯。"
}
}
]
}

View File

@@ -194,7 +194,7 @@
"ru_RU": "В {0} найден некорректный файл ключей.",
"sv_SE": "En ogiltig nyckelfil hittades i {0}.",
"th_TH": "พบไฟล์ Keys ที่ไม่ถูกต้องใน {0}.",
"tr_TR": "",
"tr_TR": "Geçersiz bir KEYS dosyası {0} dosyası içinde bulundu.",
"uk_UA": "Виявлено неправильний файл ключів у теці {0}.",
"zh_CN": "在 {0} 发现了一个无效的密匙文件。",
"zh_TW": "找到無效的金鑰檔案 {0}。"

View File

@@ -1,5 +1,55 @@
{
"Locales": [
{
"ID": "NoApplicationFoundInFile",
"Translations": {
"ar_SA": "",
"de_DE": "Keine Anwendungen in ausgewählter Datei gefunden.",
"el_GR": "",
"en_US": "No applications found in selected file.",
"es_ES": "No se encontraron aplicaciones en el archivo seleccionado.",
"fr_FR": "Aucune application trouvée dans le fichier sélectionné.",
"he_IL": "",
"it_IT": "Nessuna applicazione trovata nel file selezionato.",
"ja_JP": "",
"ko_KR": "선택한 파일에서 앱을 찾을 수 없습니다.",
"no_NO": "Ingen apper ble funnet i valgt fil.",
"pl_PL": "",
"pt_BR": "Nenhum aplicativo encontrado no arquivo selecionado.",
"ru_RU": "Приложений в выбранном файле не найдены",
"sv_SE": "Inga applikationer hittades i vald fil.",
"th_TH": "ไม่พบแอปพลิเคชั่นจากไฟล์ที่เลือก",
"tr_TR": "Seçilen dosyada uygulama bulunamadı",
"uk_UA": "У вибраному файлі не знайдено жодних додатків.",
"zh_CN": "未发现应用",
"zh_TW": "未能從已選擇的檔案中找到應用程式。"
}
},
{
"ID": "NoUnpackedApplicationFoundInFolder",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Please select an unpacked application folder with a valid ExeFS or NSO/NRO.",
"es_ES": "",
"fr_FR": "Veuillez sélectionner un répertoire dapplication décompressée contenant un ExeFS valide ou NSO/NRO.",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "Пожалуйста, выберите папку распакованного приложения с корректным ExeFS или NSO/NRO",
"sv_SE": "",
"th_TH": "",
"tr_TR": "Lütfen geçerli bir ayıklanmış uygulama dosyası seçiniz. ExeFS ve ya NSO/NRO içermelidir.",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "NoKeysFound",
"Translations": {

View File

@@ -193,7 +193,7 @@
"pt_BR": "Ferramentas",
"ru_RU": "Инструменты",
"sv_SE": "Verktyg",
"th_TH": "",
"th_TH": "Araçlar",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "工具",
@@ -219,7 +219,7 @@
"ru_RU": "Редактор Mii",
"sv_SE": "Mii-redigerare",
"th_TH": "",
"tr_TR": "",
"tr_TR": "Mii editör",
"uk_UA": "Редактор Mii",
"zh_CN": "Mii 编辑器",
"zh_TW": "Mii 編輯器"
@@ -244,7 +244,7 @@
"ru_RU": "Обрезать XCI файлы",
"sv_SE": "Optimera XCI-filer",
"th_TH": "ตัดแต่งไฟล์ XCI",
"tr_TR": "",
"tr_TR": "XCI Dosyalarını Kırp",
"uk_UA": "Обрізати XCI файли",
"zh_CN": "瘦身 XCI 文件",
"zh_TW": "修剪 XCI 檔案"
@@ -344,7 +344,7 @@
"ru_RU": "Перезапустить эмуляцию",
"sv_SE": "Starta om emulering",
"th_TH": "",
"tr_TR": "",
"tr_TR": "Emülasyonu yeniden başlat",
"uk_UA": "",
"zh_CN": "重启模拟",
"zh_TW": "重新啟動模擬"
@@ -519,7 +519,7 @@
"ru_RU": "Запустить захват кадра RenderDoc",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"tr_TR": "RenderDoc Kare Yakalamayı Başlat",
"uk_UA": "",
"zh_CN": "启动 RenderDoc 帧捕获",
"zh_TW": ""
@@ -544,7 +544,7 @@
"ru_RU": "Завершить захват кадра RenderDoc",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"tr_TR": "RenderDoc Kare Yakalamayı Sonlandır",
"uk_UA": "",
"zh_CN": "结束 RenderDoc 帧捕获",
"zh_TW": ""
@@ -569,7 +569,7 @@
"ru_RU": "Отменить захват кадра RenderDoc",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"tr_TR": "RenderDoc Kare Yakalamasını At",
"uk_UA": "",
"zh_CN": "丢弃 RenderDoc 帧捕获",
"zh_TW": ""
@@ -594,7 +594,7 @@
"ru_RU": "Завершает текущий активный захват кадра RenderDoc и немедленно удаляет его результат.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"tr_TR": "Mevcut aktif RenderDoc Kare Yakalamasını sonlandırır ve sonucunu derhal atar.",
"uk_UA": "",
"zh_CN": "结束当前正在进行的 RenderDoc 帧捕获,并立即丢弃其结果。",
"zh_TW": ""

View File

@@ -1,78 +1,278 @@
{
"Locales": [
{
"ID": "ManageFileTypes",
"ID": "FileLabel",
"Translations": {
"ar_SA": "إدارة أنواع الملفات",
"de_DE": "Dateitypen verwalten",
"el_GR": "Διαχείριση τύπων αρχείων",
"en_US": "Manage File Types",
"es_ES": "Administrar Tipos de Archivo",
"fr_FR": "Gérer les Types de Fichiers",
"he_IL": "ניהול סוגי קבצים",
"it_IT": "Gestisci i tipi di file",
"ja_JP": "ファイル形式を管理",
"ko_KR": "파일 형식 관리",
"no_NO": "Behandle filtyper",
"pl_PL": "Zarządzaj rodzajami plików",
"pt_BR": "Gerenciar Tipos de Arquivos",
"ru_RU": "Управление типами файлов",
"sv_SE": "Hantera filtyper",
"th_TH": "จัดการประเภทไฟล์",
"tr_TR": "Dosya uzantılarını yönet",
"uk_UA": "Керувати типами файлів",
"zh_CN": "管理文件扩展名",
"zh_TW": "管理檔案類型"
"ar_SA": "_ملف",
"de_DE": "_Datei",
"el_GR": "_Αρχείο",
"en_US": "_File",
"es_ES": "_Archivo",
"fr_FR": "_Fichier",
"he_IL": "ובץ",
"it_IT": "_Archivio",
"ja_JP": "ファイル(_F)",
"ko_KR": "파일(_F)",
"no_NO": "_Fil",
"pl_PL": "_Plik",
"pt_BR": "_Arquivo",
"ru_RU": "айл",
"sv_SE": "_Arkiv",
"th_TH": "ไฟล์",
"tr_TR": "_Dosya",
"uk_UA": "айл",
"zh_CN": "文件(_F)",
"zh_TW": "檔案(_F)"
}
},
{
"ID": "InstallFileTypes",
"ID": "LoadApplicationFromFileButton",
"Translations": {
"ar_SA": "تثبيت أنواع الملفات",
"de_DE": "Dateitypen installieren",
"el_GR": "Εγκαταστήσετε τύπους αρχείων.",
"en_US": "Install File Types",
"es_ES": "Instalar Tipos de Archivo",
"fr_FR": "Installer des Types de Fichiers",
"he_IL": "סוגי קבצי התקנה",
"it_IT": "Installa i tipi di file",
"ja_JP": "ファイル形式をインストール",
"ko_KR": "파일 형식 설치",
"no_NO": "Installer filtyper",
"pl_PL": "Typy plików instalacyjnych",
"pt_BR": "Instalar tipos de arquivos",
"ru_RU": "Установить типы файлов",
"sv_SE": "Installera filtyper",
"th_TH": "ติดตั้งประเภทไฟล์",
"tr_TR": "Dosya uzantılarını yükle",
"uk_UA": "Встановити типи файлів",
"zh_CN": "关联文件扩展名",
"zh_TW": "安裝檔案類型"
"ar_SA": "_تحميل التطبيق...",
"de_DE": "_Anwendung laden...",
"el_GR": "_Φόρτωση εφαρμογής...",
"en_US": "_Load Application...",
"es_ES": "_Cargar Aplicación...",
"fr_FR": "_Charger lApplication...",
"he_IL": "_טען יישום...",
"it_IT": "_Carica applicazione...",
"ja_JP": "アプリケーションをロード(_L)...",
"ko_KR": "앱 불러오기(_L)...",
"no_NO": "_Last inn program...",
"pl_PL": "_Załaduj aplikację...",
"pt_BR": "_Carregar aplicativo...",
"ru_RU": "_Загрузить приложение...",
"sv_SE": "_Läs in applikation...",
"th_TH": "_โหลดแอปพลิเคชัน...",
"tr_TR": "_Uygulamayı yükle...",
"uk_UA": "_Завантажити застосунок...",
"zh_CN": "加载应用程序(_L)...",
"zh_TW": "載入應用程式(_L)..."
}
},
{
"ID": "UninstallFileTypes",
"ID": "LoadUnpackedGameFromFolderButton",
"Translations": {
"ar_SA": "إزالة أنواع الملفات",
"de_DE": "Dateitypen deinstallieren",
"el_GR": "Απεγκαταστήσετε τύπους αρχείων",
"en_US": "Uninstall File Types",
"es_ES": "Desinstalar Tipos de Archivo",
"fr_FR": "Désinstaller des Types de Fichiers",
"he_IL": "סוגי קבצי הסרה",
"it_IT": "Disinstalla i tipi di file",
"ja_JP": "ファイル形式をアンインストール",
"ko_KR": "파일 형식 제거",
"no_NO": "Avinstaller filtyper",
"pl_PL": "Typy plików dezinstalacyjnych",
"pt_BR": "Desinstalar tipos de arquivos",
"ru_RU": "Удалить типы файлов",
"sv_SE": "Avinstallera filtyper",
"th_TH": "ถอนการติดตั้งประเภทไฟล์",
"tr_TR": "Dosya uzantılarını kaldır",
"uk_UA": "Видалити типи файлів",
"zh_CN": "取消关联扩展名",
"zh_TW": "移除檔案類型"
"ar_SA": "تحميل لُعْبَة غير محزومة...",
"de_DE": "_Entpacktes Spiel laden...",
"el_GR": "_Φόρτωση Απακετάριστου Παιχνιδιού...",
"en_US": "Load _Unpacked Game...",
"es_ES": "Cargar Juego _Desempaquetado...",
"fr_FR": "Charger un Jeu Décompressé...",
"he_IL": "טען משחק _שאינו ארוז...",
"it_IT": "Carica gioco _estratto...",
"ja_JP": "_展開されたゲームをロード...",
"ko_KR": "압축 푼 게임 불러오기(_U)...",
"no_NO": "Last inn _upakket spill...",
"pl_PL": "Załaduj _rozpakowaną grę...",
"pt_BR": "Abrir Jogo _Extraído...",
"ru_RU": "Загрузить _распакованную игру...",
"sv_SE": "Läs in _uppackat spel...",
"th_TH": "โหลดเกมที่แตกไฟล์แล้ว...",
"tr_TR": "_Sıkıştırılmamış Oyun Yükle...",
"uk_UA": "Завантажити _розпаковану гру...",
"zh_CN": "加载解包后的游戏(_U)...",
"zh_TW": "載入未封裝的遊戲(_U)..."
}
},
{
"ID": "LoadTitleUpdatesAndDLCFromFolderButton",
"Translations": {
"ar_SA": "",
"de_DE": "Updates/DLC laden...",
"el_GR": "",
"en_US": "Load Updates/DLC...",
"es_ES": "Cargar Actualizaciones/DLC...",
"fr_FR": "Charger les Mises à Jour/DLC...",
"he_IL": "",
"it_IT": "Carica aggiornamenti/DLC...",
"ja_JP": "",
"ko_KR": "업데이트/DLC 불러오기...",
"no_NO": "Last inn oppdateringer/DLC...",
"pl_PL": "",
"pt_BR": "Carregar atualizações/DLC...",
"ru_RU": "Загрузить обновления/DLC...",
"sv_SE": "Läs in uppdateringar/DLC...",
"th_TH": "โหลดอัปเดต/DLC...",
"tr_TR": "Başlık Güncellemelerini Yükle/DLC yükle",
"uk_UA": "Завантажити оновлення/DLC...",
"zh_CN": "加载更新/DLC...",
"zh_TW": "載入更新/DLC..."
}
},
{
"ID": "OpenRyuijnxFolderButton",
"Translations": {
"ar_SA": "‫فتح مجلد Ryujinx",
"de_DE": "Ryujinx-Ordner öffnen",
"el_GR": "Άνοιγμα Φακέλου Ryujinx",
"en_US": "Open Ryujinx Folder",
"es_ES": "Abrir Carpeta de Ryujinx",
"fr_FR": "Ouvrir le Dossier Ryujinx",
"he_IL": "פתח את תיקיית ריוג'ינקס",
"it_IT": "Apri la cartella di Ryujinx",
"ja_JP": "Ryujinx フォルダを開く",
"ko_KR": "Ryujinx 폴더 열기",
"no_NO": "Åpne Ryujinx mappe",
"pl_PL": "Otwórz folder Ryujinx",
"pt_BR": "Abrir Pasta do Ryujinx",
"ru_RU": "Открыть папку Ryujinx",
"sv_SE": "Öppna Ryujinx-mapp",
"th_TH": "เปิดโฟลเดอร์ Ryujinx",
"tr_TR": "Ryujinx Klasörünü aç",
"uk_UA": "Відкрити теку Ryujinx",
"zh_CN": "打开 Ryujinx 系统目录",
"zh_TW": "開啟 Ryujinx 資料夾"
}
},
{
"ID": "OpenLogsFolderButton",
"Translations": {
"ar_SA": "فتح مجلد السجلات",
"de_DE": "Logs-Ordner öffnen",
"el_GR": "Άνοιγμα Φακέλου Καταγραφής",
"en_US": "Open Logs Folder",
"es_ES": "Abrir Carpeta de Registros",
"fr_FR": "Ouvrir le Dossier des Journaux",
"he_IL": "פתח את תיקיית קבצי הלוג",
"it_IT": "Apri la cartella dei log",
"ja_JP": "ログフォルダを開く",
"ko_KR": "로그 폴더 열기",
"no_NO": "Åpne Logg mappen",
"pl_PL": "Otwórz folder plików dziennika zdarzeń",
"pt_BR": "Abrir Pasta de _Logs",
"ru_RU": "Открыть папку журналов",
"sv_SE": "Öppna loggmapp",
"th_TH": "เปิดโฟลเดอร์ Logs",
"tr_TR": "Logs Klasörünü aç",
"uk_UA": "Відкрити теку журналів змін",
"zh_CN": "打开日志目录",
"zh_TW": "開啟日誌資料夾"
}
},
{
"ID": "OpenScreenshotsFolderButton",
"Translations": {
"ar_SA": "",
"de_DE": "Screenshots-Ordner öffnen",
"el_GR": "",
"en_US": "Open Screenshots Folder",
"es_ES": "Abrir Carpeta de Capturas de Pantalla",
"fr_FR": "Ouvrir le Dossier des Captures dÉcran",
"he_IL": "",
"it_IT": "Apri la cartella degli screenshots",
"ja_JP": "",
"ko_KR": "스크린샷 폴더 열기",
"no_NO": "Åpne Skjermbilde Mappen",
"pl_PL": "",
"pt_BR": "Abrir Pasta de Capturas de Tela",
"ru_RU": "Открыть папку снимков экрана",
"sv_SE": "Öppna skärmbildsmappen",
"th_TH": "เปิดโฟลเดอร์ที่เก็บภาพหน้าจอ",
"tr_TR": "Ekran yakalamaları klasörünü aç",
"uk_UA": "Відкрити теку скріншотів",
"zh_CN": "打开截图文件夹",
"zh_TW": "開啟螢幕擷取畫面資料夾"
}
},
{
"ID": "AssociateFileTypesButton",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Associate File Types",
"es_ES": "",
"fr_FR": "Associer Les Types de Fichiers",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "Связать файлы с приложением",
"sv_SE": "",
"th_TH": "",
"tr_TR": "Dosya Türlerini İlişkilendir",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "RemoveFileTypeAssociationsButton",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Remove File Type Associations",
"es_ES": "",
"fr_FR": "Dissocier Les Types de Fichiers",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "Удалить ассоциации файлов",
"sv_SE": "",
"th_TH": "",
"tr_TR": "Dosya Türü İlişkilendirmelerini Kaldır",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "FileTypeAssociationsToolTip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Associates supported file types (NSP, XCI, NCA, NRO, NSO) with Ryujinx so they open automatically when double-clicked in your file manager. Removing file type associations stops this behavior.",
"es_ES": "",
"fr_FR": "Associe les types de fichiers pris en charge (NSP, XCI, NCA, NRO, NSO) à Ryujinx afin quils souvrent automatiquement par double-clic dans votre gestionnaire de fichiers. Les dissocier désactive ce comportement",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "Связывает поддерживаемые типы файлов (NSP, XCI, NCA, NRO, NSO) с Ryujinx, чтобы они автоматически открывались при двойном щелчке в файловом менеджере. Удаление ассоциаций файлов отключает это поведение.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "Desteklenen dosya türlerini (NSP, XCI, NCA, NRO, NSO) Ryujinx ile ilişkilendirir; böylece dosya yöneticinizde çift tıklandıklarında otomatik olarak açılırlar.Dosya türü ilişkilendirmelerini kaldırmak bu davranışı durdurur.",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "ExitButton",
"Translations": {
"ar_SA": "_خروج",
"de_DE": "_Beenden",
"el_GR": "_Έξοδος",
"en_US": "_Exit",
"es_ES": "_Salir",
"fr_FR": "_Quitter",
"he_IL": "_יציאה",
"it_IT": "_Esci",
"ja_JP": "終了(_E)",
"ko_KR": "종료(_E)",
"no_NO": "_Avslutt",
"pl_PL": "_Wyjdź",
"pt_BR": "_Sair",
"ru_RU": "_Выйти",
"sv_SE": "_Avsluta",
"th_TH": "_ออก",
"tr_TR": "_Çıkış",
"uk_UA": "_Вихід",
"zh_CN": "退出(_E)",
"zh_TW": "結束(_E)"
}
}
]

View File

@@ -0,0 +1,104 @@
{
"Locales": [
{
"ID": "OptionsLabel",
"Translations": {
"ar_SA": "_خيارات",
"de_DE": "_Optionen",
"el_GR": "_Επιλογές",
"en_US": "_Options",
"es_ES": "_Opciones",
"fr_FR": null,
"he_IL": "_אפשרויות",
"it_IT": "_Opzioni",
"ja_JP": "オプション(_O)",
"ko_KR": "옵션(_O)",
"no_NO": "_Alternativer",
"pl_PL": "_Opcje",
"pt_BR": "_Opções",
"ru_RU": "_Настройки",
"sv_SE": "_Inställningar",
"th_TH": "_ตัวเลือก",
"tr_TR": "_Seçenekler",
"uk_UA": "_Параметри",
"zh_CN": "选项(_O)",
"zh_TW": "選項(_O)"
}
},
{
"ID": "LanguageButton",
"Translations": {
"ar_SA": "اللغة",
"de_DE": "Sprache",
"el_GR": "Γλώσσα",
"en_US": "Language",
"es_ES": "Idioma",
"fr_FR": "Langue",
"he_IL": "שפה",
"it_IT": "Lingua",
"ja_JP": "言語",
"ko_KR": "언어",
"no_NO": "Språk",
"pl_PL": "Język",
"pt_BR": "Idioma",
"ru_RU": "Язык",
"sv_SE": "Språk",
"th_TH": "ภาษา",
"tr_TR": "Dil",
"uk_UA": "Мова",
"zh_CN": "语言",
"zh_TW": "語言"
}
},
{
"ID": "UserProfilesButton",
"Translations": {
"ar_SA": "_ملفات المستخدمين",
"de_DE": "_Benutzerprofile",
"el_GR": "_Προφίλ Χρηστών",
"en_US": "_User Profiles",
"es_ES": "_Perfiles de Usuario",
"fr_FR": "_Profils d'Utilisateurs",
"he_IL": "_פרופילי משתמש",
"it_IT": "_Profili utente",
"ja_JP": "ユーザプロファイル(_M)",
"ko_KR": "사용자 프로필(_M)",
"no_NO": "_Brukerprofiler",
"pl_PL": "_Profile użytkowników",
"pt_BR": "_Perfis de usuário",
"ru_RU": "_Профили пользователей",
"sv_SE": "_Användarprofiler",
"th_TH": "_โปรไฟล์ผู้ใช้งาน",
"tr_TR": "_Kullanıcı Profilleri",
"uk_UA": "_Профілі користувачів",
"zh_CN": "用户配置文件(_M)",
"zh_TW": "使用者設定檔(_M)"
}
},
{
"ID": "SettingsButton",
"Translations": {
"ar_SA": "_الإعدادات",
"de_DE": "_Einstellungen",
"el_GR": "_Ρυθμίσεις",
"en_US": "_Settings",
"es_ES": "_Configuración",
"fr_FR": "_Paramètres",
"he_IL": "_הגדרות",
"it_IT": "_Impostazioni",
"ja_JP": "設定(_S)",
"ko_KR": "설정(_S)",
"no_NO": "_Innstillinger",
"pl_PL": "_Ustawienia",
"pt_BR": "_Configurações",
"ru_RU": "_Параметры",
"sv_SE": "_Inställningar",
"th_TH": "_ตั้งค่า",
"tr_TR": "_Seçenekler",
"uk_UA": "_Налаштування",
"zh_CN": "设置(_S)",
"zh_TW": "設定(_S)"
}
}
]
}

View File

@@ -0,0 +1,54 @@
{
"Locales": [
{
"ID": "ToggleFullscreenButton",
"Translations": {
"ar_SA": "التبديل إلى وضع ملء الشاشة",
"de_DE": "Vollbild",
"el_GR": "Λειτουργία Πλήρους Οθόνης",
"en_US": "Toggle Fullscreen",
"es_ES": "Cambiar a Pantalla Completa.",
"fr_FR": "Basculer en Plein Écran",
"he_IL": "שנה מצב- מסך מלא",
"it_IT": "Schermo intero",
"ja_JP": "全画面切り替え",
"ko_KR": "전체 화면 전환",
"no_NO": "Fullskjermsvisning av/på",
"pl_PL": "Przełącz na tryb pełnoekranowy",
"pt_BR": "Mudar para Tela Cheia",
"ru_RU": "Переключить полноэкранный режим",
"sv_SE": "Växla helskärm",
"th_TH": "สลับเป็นโหมดเต็มหน้าจอ",
"tr_TR": "Tam Ekran Modunu Aç",
"uk_UA": "На весь екран",
"zh_CN": "切换全屏",
"zh_TW": "切換全螢幕模式"
}
},
{
"ID": "ShowConsoleButton",
"Translations": {
"ar_SA": "عرض وحدة التحكم",
"de_DE": "Zeige Konsole",
"el_GR": "Εμφάνιση Κονσόλας",
"en_US": "Show Console",
"es_ES": "Mostrar Consola",
"fr_FR": "Afficher la Console",
"he_IL": "הצג שורת פקודות",
"it_IT": "Mostra console",
"ja_JP": "コンソールを表示",
"ko_KR": "콘솔 표시",
"no_NO": "Vis konsoll",
"pl_PL": "Pokaż Konsolę",
"pt_BR": "Exibir Console",
"ru_RU": "Показать консоль",
"sv_SE": "Visa konsoll",
"th_TH": "แสดง คอนโซล",
"tr_TR": "Konsol'u Göster",
"uk_UA": "Показати консоль",
"zh_CN": "显示控制台",
"zh_TW": "顯示控制台"
}
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
{
"Locales": [
{
"ID": "StartGamesInFullscreenCheckboxLabel",
"Translations": {
"ar_SA": "ابدأ الألعاب بملء الشاشة",
"de_DE": "Spiele im Vollbild starten",
"el_GR": "Εκκίνηση Παιχνιδιών σε Πλήρη Οθόνη",
"en_US": "Start Games in Fullscreen",
"es_ES": "Iniciar Juegos en Pantalla Completa",
"fr_FR": "Démarrer les Jeux en Plein Écran",
"he_IL": "התחל משחקים במסך מלא",
"it_IT": "Avvia i giochi a schermo intero",
"ja_JP": "全画面でゲームを開始",
"ko_KR": "전체 화면으로 게임 시작",
"no_NO": "Start spill i fullskjerm",
"pl_PL": "Uruchamiaj gry na pełnym ekranie",
"pt_BR": "Iniciar Jogos em Tela Cheia",
"ru_RU": "Запускать игры в полноэкранном режиме",
"sv_SE": "Starta spel i helskärm",
"th_TH": "เริ่มเกมแบบเต็มหน้าจอ",
"tr_TR": "Oyunları Tam Ekranda Başlat",
"uk_UA": "Запускати ігри в повноекранному режимі",
"zh_CN": "全屏启动游戏",
"zh_TW": "以全螢幕啟動遊戲"
}
},
{
"ID": "StartGamesWithoutUICheckboxLabel",
"Translations": {
"ar_SA": "",
"de_DE": "Benutzeroberfläche beim Spielstart ausblenden",
"el_GR": "",
"en_US": "Hide UI on Game Start",
"es_ES": "Ocultar la Interfaz al Iniciar el Juego",
"fr_FR": "Masquer lInterface au Lancement du Jeu",
"he_IL": "",
"it_IT": "Nascondi linterfaccia allavvio del gioco",
"ja_JP": "",
"ko_KR": "게임 시작 시 UI 숨기기",
"no_NO": "Skjul brukergrensesnitt ved spillstart",
"pl_PL": "",
"pt_BR": "Ocultar a interface ao iniciar o jogo",
"ru_RU": "Скрывать интерфейс при запуске игры",
"sv_SE": "Dölj användargränssnitt vid spelstart",
"th_TH": "ซ่อน UI เมื่อเริ่มเกม",
"tr_TR": "Oyun başlayınca arayüzü sakla",
"uk_UA": "Приховувати інтерфейс під час запуску гри",
"zh_CN": "启动游戏时隐藏界面",
"zh_TW": "啟動遊戲時隱藏介面"
}
},
{
"ID": "StartGamesWithoutUICheckboxLabelToolTip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Automatically hides Ryujinx's UI whenever a game launches. While in-game, press F4 to show the UI.",
"es_ES": "",
"fr_FR": "Masque automatiquement l'interface de Ryujinx au lancement d'un jeu. En jeu, appuyez sur F4 pour afficher l'interface.",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "Автоматически скрывает интерфейс Ryujinx при запуске игры. Во время игры нажмите F4, чтобы показать интерфейс.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "Bir oyun açılınca otomatik olarak Ryujinx'in arayüzünü saklar. Oyun içindeyken F4'e basarak arayüzü gösterebilirsin.",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
}
]
}

View File

@@ -19,7 +19,7 @@
"ru_RU": "Версия прошивки: {0}",
"sv_SE": "Firmware-version: {0}",
"th_TH": "เวอร์ชันเฟิร์มแวร์: {0}",
"tr_TR": "",
"tr_TR": "Yazılım Versiyonu: {0}",
"uk_UA": "Версія прошивки: {0}",
"zh_CN": "系统固件版本:{0}",
"zh_TW": "系統韌體版本: {0}"

View File

@@ -47,12 +47,14 @@ def get_new_name(
input_component = str(input_dylib_path).replace(str(input_directory), "")[1:]
return Path(os.path.join(output_directory, input_component))
def get_archs(dylib_path: Path) -> list[str]:
res = subprocess.check_output([LIPO, "-info", str(dylib_path)]).decode("utf-8")
if res.startswith("Non-fat file"):
return [res.split(":")[-1].strip()]
else:
return res.split("are:")[-1].strip().split()
def is_fat_file(dylib_path: Path) -> str:
res = subprocess.check_output([LIPO, "-info", str(dylib_path.absolute())]).decode(
"utf-8"
)
return not res.split("\n")[0].startswith("Non-fat file")
def construct_universal_dylib(
arm64_input_dylib_path: Path, x86_64_input_dylib_path: Path, output_dylib_path: Path
@@ -67,12 +69,11 @@ def construct_universal_dylib(
os.path.basename(arm64_input_dylib_path.resolve()), output_dylib_path
)
else:
arm64_archs = get_archs(arm64_input_dylib_path)
x86_64_archs = get_archs(x86_64_input_dylib_path) if x86_64_input_dylib_path.exists() else []
if "arm64" in arm64_archs and "x86_64" in arm64_archs:
shutil.copy2(arm64_input_dylib_path, output_dylib_path)
elif x86_64_archs:
if is_fat_file(arm64_input_dylib_path) or not x86_64_input_dylib_path.exists():
with open(output_dylib_path, "wb") as dst:
with open(arm64_input_dylib_path, "rb") as src:
dst.write(src.read())
else:
subprocess.check_call(
[
LIPO,

View File

@@ -24,6 +24,9 @@ namespace Ryujinx.Common.Helper
public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows());
// NOTE: On macOS, users have a more robust file association system (via Right-Click > Get Info > "Open with:" > Ryujinx > "Change All...)
// Custom file association isn't strictly necessary and will not provide any additional benefit to macOS users.
public static bool AreMimeTypesRegistered
{
get
@@ -38,8 +41,6 @@ namespace Ryujinx.Common.Helper
return AreMimeTypesRegisteredWindows();
}
// TODO: Add macOS support.
return false;
}
}
@@ -173,8 +174,6 @@ namespace Ryujinx.Common.Helper
return InstallWindowsMimeTypes();
}
// TODO: Add macOS support.
return false;
}
@@ -190,8 +189,6 @@ namespace Ryujinx.Common.Helper
return InstallWindowsMimeTypes(true);
}
// TODO: Add macOS support.
return false;
}
}

View File

@@ -53,7 +53,7 @@ namespace Ryujinx.Cpu.Signal
public SignalHandlerRangeArray Ranges;
}
static class NativeSignalHandler
public static class NativeSignalHandler
{
private static readonly nint _handlerConfig;
private static nint _signalHandlerPtr;

View File

@@ -16,15 +16,15 @@ namespace Ryujinx.Graphics.Vulkan
{
DescriptorSetLayout[] layouts = new DescriptorSetLayout[setDescriptors.Count];
bool[] updateAfterBindFlags = new bool[setDescriptors.Count];
bool isMoltenVk = gd.IsMoltenVk;
for (int setIndex = 0; setIndex < setDescriptors.Count; setIndex++)
{
ResourceDescriptorCollection rdc = setDescriptors[setIndex];
ResourceStages activeStages = ResourceStages.None;
if (isMoltenVk)
{
for (int descIndex = 0; descIndex < rdc.Descriptors.Count; descIndex++)
@@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.Vulkan
// causes invalid resource errors, allow the binding on all active stages as workaround.
// https://github.com/KhronosGroup/MoltenVK/issues/1870
stages = activeStages;
}
}
layoutBindings[descIndex] = new DescriptorSetLayoutBinding
{

View File

@@ -439,7 +439,7 @@ namespace Ryujinx.Graphics.Vulkan
features2.Features.MultiViewport && !(IsMoltenVk && Vendor == Vendor.Amd), // Workaround for AMD on MoltenVK issue
featuresRobustness2.NullDescriptor || IsMoltenVk,
supportsPushDescriptors,
IsMoltenVk ? 16 : propertiesPushDescriptor.MaxPushDescriptors, // In case an old version of MoltenVK is used, apply a limit to prevent vertex explosions.
IsMoltenVk ? 16 : propertiesPushDescriptor.MaxPushDescriptors, // Prevents vertex explosions on MoltenVK.
featuresPrimitiveTopologyListRestart.PrimitiveTopologyListRestart,
featuresPrimitiveTopologyListRestart.PrimitiveTopologyPatchListRestart,
supportsTransformFeedback,

View File

@@ -1,10 +1,23 @@
using System;
using System.Runtime.InteropServices;
using UnicornEngine.Const;
namespace Ryujinx.Tests.Unicorn
{
public class UnicornAArch32 : IDisposable
{
struct UcArmCpReg
{
public uint Cp;
public uint Is64;
public uint Sec;
public uint CRn;
public uint CRm;
public uint Opc1;
public uint Opc2;
public uint Val;
}
internal readonly UnicornEngine.Unicorn Uc;
private bool _isDisposed;
@@ -38,7 +51,7 @@ namespace Ryujinx.Tests.Unicorn
public int Fpscr
{
get => (int)GetRegister(Arm.UC_ARM_REG_FPSCR) | ((int)GetRegister(Arm.UC_ARM_REG_FPSCR_NZCV));
get => (int)GetRegister(Arm.UC_ARM_REG_FPSCR);
set => SetRegister(Arm.UC_ARM_REG_FPSCR, (uint)value);
}
@@ -85,8 +98,22 @@ namespace Ryujinx.Tests.Unicorn
public UnicornAArch32()
{
Uc = new UnicornEngine.Unicorn(Common.UC_ARCH_ARM, Common.UC_MODE_LITTLE_ENDIAN);
SetRegister(Arm.UC_ARM_REG_C1_C0_2, GetRegister(Arm.UC_ARM_REG_C1_C0_2) | 0xf00000);
UcArmCpReg reg = new()
{
Cp = 15,
Is64 = 0,
Sec = 0,
CRn = 13,
Opc1 = 0,
CRm = 0,
Opc2 = 2
};
GetRegister(Arm.UC_ARM_REG_CP_REG, ref reg);
reg.Val |= 0xf00000;
SetRegister(Arm.UC_ARM_REG_CP_REG, reg);
SetRegister(Arm.UC_ARM_REG_FPEXC, 0x40000000);
}
@@ -204,6 +231,17 @@ namespace Ryujinx.Tests.Unicorn
SetVector(Arm.UC_ARM_REG_D0 + index * 2, value);
}
public void GetRegister<T>(int register, ref T obj) where T : unmanaged
{
Span<T> span = new(ref obj);
Span<byte> dataSpan = MemoryMarshal.Cast<T, byte>(span);
byte[] data = dataSpan.ToArray();
Uc.RegRead(register, data);
data.AsSpan().CopyTo(dataSpan);
}
public uint GetRegister(int register)
{
byte[] data = new byte[4];
@@ -213,6 +251,13 @@ namespace Ryujinx.Tests.Unicorn
return BitConverter.ToUInt32(data, 0);
}
public void SetRegister<T>(int register, T obj) where T : unmanaged
{
byte[] data = MemoryMarshal.Cast<T, byte>(new Span<T>(ref obj)).ToArray();
Uc.RegWrite(register, data);
}
public void SetRegister(int register, uint value)
{
byte[] data = BitConverter.GetBytes(value);

View File

@@ -7,6 +7,7 @@ using Ryujinx.Common.Memory;
using Ryujinx.Common.Memory.PartialUnmaps;
using Ryujinx.Cpu;
using Ryujinx.Cpu.Jit;
using Ryujinx.Cpu.Signal;
using Ryujinx.Memory;
using Ryujinx.Memory.Tracking;
using System;
@@ -60,6 +61,8 @@ namespace Ryujinx.Tests.Memory
new JitMemoryAllocator(),
new MockMemoryManager(),
AddressTable<ulong>.CreateForArm(true, MemoryManagerType.SoftwarePageTable));
NativeSignalHandler.InitializeSignalHandler();
}
[Test]

View File

@@ -28,14 +28,14 @@
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
</PropertyGroup>
<!--
FluentAvalonia, used in the Avalonia UI, requires a workaround for the json serializer used internally when using .NET 8+ System.Text.Json.
See:
https://github.com/amwx/FluentAvalonia/issues/481
https://devblogs.microsoft.com/dotnet/system-text-json-in-dotnet-8/
-->
<PropertyGroup>
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
</PropertyGroup>
@@ -73,7 +73,7 @@
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
<PackageReference Include="SPB" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ryujinx.Graphics.RenderDocApi\Ryujinx.Graphics.RenderDocApi.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj" />

View File

@@ -818,8 +818,7 @@ namespace Ryujinx.Ava.Systems
if (!Device.LoadCart(ApplicationPath, romFsFiles[0]))
{
await ContentDialogHelper.CreateErrorDialog(
"Please specify an unpacked game directory with a valid exefs or NSO/NRO.");
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.Error_NoUnpackedApplicationFoundInFolder));
Device.Dispose();
cts.Cancel();
@@ -831,8 +830,7 @@ namespace Ryujinx.Ava.Systems
Logger.Info?.Print(LogClass.Application, "Loading as cart WITHOUT RomFS.");
if (!Device.LoadCart(ApplicationPath))
{
await ContentDialogHelper.CreateErrorDialog(
"Please specify an unpacked game directory with a valid exefs or NSO/NRO.");
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.Error_NoUnpackedApplicationFoundInFolder));
Device.Dispose();
cts.Cancel();
throw new OperationCanceledException(cts.Token);

View File

@@ -46,7 +46,7 @@ namespace Ryujinx.Ava.Systems
LargeImageText = TruncateToByteLength(_description)
},
Details = "Main Menu",
State = "Idling",
State = "Waiting",
Timestamps = EmulatorStartedAt
};

View File

@@ -1069,7 +1069,6 @@ namespace Ryujinx.Ava.Systems.PlayReport
_ => FormattedValue.ForceReset
};
private static FormattedValue TomodachiLifeLTD_Status(SingleValue value)
{
MessagePackObject messagePackObject = value.Matched.PackedValue;
@@ -1077,8 +1076,9 @@ namespace Ryujinx.Ava.Systems.PlayReport
int miiCount = messagePackObjectDictionary["MiiNum"].AsInt32();
int fountainLevel = messagePackObjectDictionary["FountainLevel"].AsInt32();
return $"Looking after {"Mii".ToQuantity(miiCount)}, with an island level of {fountainLevel}";
// Fountain Level should be kept consistent throughout code, so I basically made sure of it
return $"Looking after {"Mii".ToQuantity(miiCount)}, with a fountain level of {fountainLevel}";
}
private static FormattedValue AnimalCrossingNewHorizons_AppCommon(SingleValue value)

View File

@@ -13,6 +13,7 @@ using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using static Ryujinx.Ava.Utilities.StorageProviderExtensions;
namespace Ryujinx.Ava.UI.ViewModels
{
@@ -128,7 +129,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public async void Add()
{
IReadOnlyList<IStorageFile> result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
IReadOnlyList<IStorageFile> result = await CoreDumpable(() => _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = LocaleManager.Instance[LocaleKeys.SelectDlcDialogTitle],
AllowMultiple = true,
@@ -141,7 +142,7 @@ namespace Ryujinx.Ava.UI.ViewModels
MimeTypes = ["application/x-nx-nsp"],
},
},
});
}));
int totalDlcAdded = 0;
foreach (IStorageFile file in result)
@@ -250,7 +251,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private Task ShowNewDlcAddedDialog(int numAdded)
{
string msg = string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowDlcAddedMessage], numAdded);
string msg = string.Format(LocaleManager.Instance[LocaleKeys.Dialog_ContentLoading_DLCAddedMessage], numAdded);
return Dispatcher.UIThread.InvokeAsync(async () =>
{
await ContentDialogHelper.ShowTextDialog(

View File

@@ -136,9 +136,6 @@ namespace Ryujinx.Ava.UI.ViewModels
[ObservableProperty] public partial float VolumeBeforeMute { get; set; }
[ObservableProperty]
public partial bool AreMimeTypesRegistered { get; set; } = FileAssociationHelper.AreMimeTypesRegistered;
[ObservableProperty] public partial Cursor Cursor { get; set; }
[ObservableProperty] public partial string Title { get; set; }
@@ -219,6 +216,11 @@ namespace Ryujinx.Ava.UI.ViewModels
_rendererWaitEvent = new AutoResetEvent(false);
LocaleManager.Instance.PropertyChanged += (sender, args) =>
{
RefreshFileTypeAssociationToggle();
};
if (Program.PreviewerDetached)
{
LoadConfigurableHotKeys();
@@ -679,11 +681,6 @@ namespace Ryujinx.Ava.UI.ViewModels
get => ConsoleHelper.SetConsoleWindowStateSupported;
}
public bool ManageFileTypesVisible
{
get => FileAssociationHelper.IsTypeAssociationSupported;
}
public Glyph Glyph
{
get => (Glyph)ConfigurationState.Instance.UI.GameListViewMode.Value;
@@ -941,6 +938,71 @@ namespace Ryujinx.Ava.UI.ViewModels
return false;
}
public bool FileTypeAssociationsVisible
{
get => FileAssociationHelper.IsTypeAssociationSupported;
}
private void RefreshFileTypeAssociationToggle()
{
OnPropertyChanged(nameof(FileTypeAssociationsMenuHeader));
OnPropertyChanged(nameof(FileTypeAssociationsIcon));
}
private bool _areMimeTypesRegistered = FileAssociationHelper.AreMimeTypesRegistered;
public bool AreMimeTypesRegistered
{
get => _areMimeTypesRegistered;
set
{
if (_areMimeTypesRegistered != value)
{
_areMimeTypesRegistered = value;
RefreshFileTypeAssociationToggle();
}
}
}
public string FileTypeAssociationsMenuHeader =>
AreMimeTypesRegistered
? LocaleManager.Instance[LocaleKeys.MenuBar_File_RemoveFileTypeAssociationsButton]
: LocaleManager.Instance[LocaleKeys.MenuBar_File_AssociateFileTypesButton];
public string FileTypeAssociationsIcon =>
AreMimeTypesRegistered
? "fa-solid fa-link-slash"
: "fa-solid fa-link";
[RelayCommand]
private async Task ToggleFileTypeAssociations()
{
if (AreMimeTypesRegistered)
await RemoveFileTypeAssociations();
else
await AssociateFileTypes();
}
[RelayCommand]
private async Task AssociateFileTypes()
{
AreMimeTypesRegistered = FileAssociationHelper.Install();
if (AreMimeTypesRegistered)
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.Dialog_FileTypeAssociations_AssociationSuccessMessage], string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
else
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.Dialog_FileTypeAssociations_AssociationFailedMessage]);
}
[RelayCommand]
private async Task RemoveFileTypeAssociations()
{
AreMimeTypesRegistered = !FileAssociationHelper.Uninstall();
if (!AreMimeTypesRegistered)
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.Dialog_FileTypeAssociations_RemoveAssociationSuccessMessage], string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
else
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.Dialog_FileTypeAssociations_RemoveAssociationFailedMessage]);
}
public async Task HandleFirmwareInstallation(string filename)
{
try
@@ -1407,10 +1469,6 @@ namespace Ryujinx.Ava.UI.ViewModels
public void HideUi() => ShowMenuAndStatusBar = false;
public void ToggleStartGamesInFullscreen() => StartGamesInFullscreen = !StartGamesInFullscreen;
public void ToggleStartGamesWithoutUi() => StartGamesWithoutUi = !StartGamesWithoutUi;
public void ToggleShowConsole() => ShowConsole = !ShowConsole;
public void SetListMode() => Glyph = Glyph.List;
@@ -1601,11 +1659,14 @@ namespace Ryujinx.Ava.UI.ViewModels
AppHost.Device.System.SimulateWakeUpMessage();
}
public async Task OpenFile()
public KeyGesture LoadApplicationFromFileGesture => KeyGesture.Parse(OperatingSystem.IsMacOS() ? "Cmd+O" : "Ctrl+O");
public KeyGesture LoadUnpackedGameFromFolderFileGesture => KeyGesture.Parse(OperatingSystem.IsMacOS() ? "Cmd+Shift+O" : "Ctrl+Shift+O");
public async Task LoadApplicationFromFile()
{
Optional<IStorageFile> result = await StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
{
Title = LocaleManager.Instance[LocaleKeys.LoadApplicationFromFileDialogTitle],
Title = LocaleManager.Instance[LocaleKeys.Dialog_FileMenu_LoadApplicationFromFileFilePickerTitle],
FileTypeFilter = new List<FilePickerFileType>
{
new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
@@ -1671,35 +1732,17 @@ namespace Ryujinx.Ava.UI.ViewModels
else
{
await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance[LocaleKeys.MenuBarFileOpenFromFileError]);
LocaleManager.Instance[LocaleKeys.Error_NoApplicationFoundInFile]);
}
}
}
public async Task LoadDlcFromFolder()
{
await LoadContentFromFolder(
LocaleKeys.AutoloadDlcAddedMessage,
LocaleKeys.AutoloadDlcRemovedMessage,
ApplicationLibrary.AutoLoadDownloadableContents,
LocaleKeys.LoadDLCFromFolderDialogTitle);
}
public async Task LoadTitleUpdatesFromFolder()
{
await LoadContentFromFolder(
LocaleKeys.AutoloadUpdateAddedMessage,
LocaleKeys.AutoloadUpdateRemovedMessage,
ApplicationLibrary.AutoLoadTitleUpdates,
LocaleKeys.LoadTitleUpdatesFromFolderDialogTitle);
}
public async Task OpenFolder()
public async Task LoadUnpackedGameFromFolder()
{
Optional<IStorageFolder> result = await StorageProvider.OpenSingleFolderPickerAsync(
new FolderPickerOpenOptions
{
Title = LocaleManager.Instance[LocaleKeys.LoadUnpackedGameFromFolderDialogTitle]
Title = LocaleManager.Instance[LocaleKeys.Dialog_FileMenu_LoadUnpackedApplicationFromFolderFilePickerTitle]
});
if (result.TryGet(out IStorageFolder value))
@@ -1713,6 +1756,36 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
private async Task<IReadOnlyList<string>?> PickFolders(LocaleKeys titleKey)
{
return (await StorageProvider.OpenMultiFolderPickerAsync(new FolderPickerOpenOptions
{
Title = LocaleManager.Instance[titleKey]
})).TryGet(out IReadOnlyList<IStorageFolder> folders)
? folders.Select(f => f.Path.LocalPath).ToList()
: null;
}
public async Task LoadTitleUpdatesAndDLCFromFolder()
{
if (await PickFolders(LocaleKeys.Dialog_FileMenu_LoadUpdatesAndDLCFromFolderFilePickerTitle) is not { } dirs)
return;
int updAdded = ApplicationLibrary.AutoLoadTitleUpdates(dirs.ToList(), out _);
int dlcAdded = ApplicationLibrary.AutoLoadDownloadableContents(dirs.ToList(), out _);
await Dispatcher.UIThread.InvokeAsync(async () =>
{
await ContentDialogHelper.ShowTextDialog(
LocaleManager.Instance[LocaleKeys.RyujinxConfirm],
string.Format(LocaleManager.Instance[LocaleKeys.Dialog_ContentLoading_UpdatesAddedMessage], updAdded) + "\n\n" +
string.Format(LocaleManager.Instance[LocaleKeys.Dialog_ContentLoading_DLCAddedMessage], dlcAdded),
string.Empty, string.Empty, string.Empty,
LocaleManager.Instance[LocaleKeys.InputDialogOk],
(int)Symbol.Checkmark);
});
}
public static bool InitializeUserConfig(ApplicationData application)
{
// Code where conditions will be met before loading the user configuration (Global Config)

View File

@@ -17,6 +17,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using static Ryujinx.Ava.Utilities.StorageProviderExtensions;
namespace Ryujinx.Ava.UI.ViewModels
{
@@ -288,11 +289,11 @@ namespace Ryujinx.Ava.UI.ViewModels
public async void Add()
{
IReadOnlyList<IStorageFolder> result = await _storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
IReadOnlyList<IStorageFolder> result = await CoreDumpable(() => _storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = LocaleManager.Instance[LocaleKeys.SelectModDialogTitle],
AllowMultiple = true,
});
}));
foreach (IStorageFolder folder in result)
{

View File

@@ -109,6 +109,31 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
public bool StartGamesInFullscreen
{
get => ConfigurationState.Instance.UI.StartFullscreen;
set
{
if (ConfigurationState.Instance.UI.StartFullscreen.Value != value)
{
ConfigurationState.Instance.UI.StartFullscreen.Value = value;
OnPropertyChanged();
}
}
}
public bool StartGamesWithoutUi
{
get => ConfigurationState.Instance.UI.StartNoUI;
set
{
if (ConfigurationState.Instance.UI.StartNoUI.Value != value)
{
ConfigurationState.Instance.UI.StartNoUI.Value = value;
OnPropertyChanged();
}
}
}
public int GraphicsBackendMultithreadingIndex
{
get;
@@ -638,6 +663,8 @@ namespace Ryujinx.Ava.UI.ViewModels
HideCursor = (int)config.HideCursor.Value;
UpdateCheckerType = (int)config.UpdateCheckerType.Value;
FocusLostActionType = (int)config.FocusLostActionType.Value;
StartGamesInFullscreen = config.UI.StartFullscreen;
StartGamesWithoutUi = config.UI.StartNoUI;
GameDirectories.Clear();
GameDirectories.AddRange(config.UI.GameDirs.Value);
@@ -758,6 +785,8 @@ namespace Ryujinx.Ava.UI.ViewModels
config.FocusLostActionType.Value = (FocusLostType)FocusLostActionType;
config.UI.GameDirs.Value = [.. GameDirectories];
config.UI.AutoloadDirs.Value = [.. AutoloadDirectories];
config.UI.StartFullscreen.Value = StartGamesInFullscreen;
config.UI.StartNoUI.Value = StartGamesWithoutUi;
config.UI.BaseStyle.Value = BaseStyleIndex switch
{

View File

@@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using static Ryujinx.Ava.Utilities.StorageProviderExtensions;
namespace Ryujinx.Ava.UI.ViewModels
{
@@ -148,7 +149,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public async Task Add()
{
IReadOnlyList<IStorageFile> result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
IReadOnlyList<IStorageFile> result = await CoreDumpable(() => _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
AllowMultiple = true,
FileTypeFilter = new List<FilePickerFileType>
@@ -160,7 +161,7 @@ namespace Ryujinx.Ava.UI.ViewModels
MimeTypes = ["application/x-nx-nsp"],
},
},
});
}));
int totalUpdatesAdded = 0;
foreach (IStorageFile file in result)
@@ -187,7 +188,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private Task<UserResult> ShowNewUpdatesAddedDialog(int numAdded)
{
string msg = string.Format(LocaleManager.Instance[LocaleKeys.UpdateWindowUpdateAddedMessage], numAdded);
string msg = string.Format(LocaleManager.Instance[LocaleKeys.Dialog_ContentLoading_UpdatesAddedMessage], numAdded);
return Dispatcher.UIThread.InvokeAsync(async () =>
await ContentDialogHelper.ShowTextDialog(
LocaleManager.Instance[LocaleKeys.DialogConfirmationTitle],

View File

@@ -7,6 +7,7 @@
mc:Ignorable="d"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
xmlns:i="clr-namespace:Projektanker.Icons.Avalonia;assembly=Projektanker.Icons.Avalonia"
xmlns:common="clr-namespace:Ryujinx.Common;assembly=Ryujinx.Common"
xmlns:renderDocApi="clr-namespace:Ryujinx.Graphics.RenderDocApi;assembly=Ryujinx.Graphics.RenderDocApi"
x:DataType="viewModels:MainWindowViewModel"
@@ -29,122 +30,71 @@
<DockPanel Margin="0" HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarFile}">
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBar_File_FileLabel}">
<MenuItem
Command="{Binding OpenFile}"
Header="{ext:Locale MenuBarFileOpenFromFile}"
Command="{Binding LoadApplicationFromFile}"
Header="{ext:Locale MenuBar_File_LoadApplicationFromFileButton}"
Icon="{ext:Icon fa-solid fa-file}"
IsEnabled="{Binding EnableNonGameRunningControls}" />
IsEnabled="{Binding EnableNonGameRunningControls}"
InputGesture="{Binding LoadApplicationFromFileGesture}" />
<MenuItem
Command="{Binding OpenFolder}"
Header="{ext:Locale MenuBarFileOpenUnpacked}"
Command="{Binding LoadUnpackedGameFromFolder}"
Header="{ext:Locale MenuBar_File_LoadUnpackedGameFromFolderButton}"
Icon="{ext:Icon fa-solid fa-folder-open}"
IsEnabled="{Binding EnableNonGameRunningControls}" />
IsEnabled="{Binding EnableNonGameRunningControls}"
InputGesture="{Binding LoadUnpackedGameFromFolderFileGesture}" />
<MenuItem
Command="{Binding LoadTitleUpdatesFromFolder}"
Header="{ext:Locale MenuBarFileLoadTitleUpdatesFromFolder}"
Icon="{ext:Icon fa-solid fa-diagram-predecessor}"
IsEnabled="{Binding EnableNonGameRunningControls}" />
<MenuItem
Command="{Binding LoadDlcFromFolder}"
Header="{ext:Locale MenuBarFileLoadDlcFromFolder}"
Icon="{ext:Icon fa-solid fa-puzzle-piece}"
Command="{Binding LoadTitleUpdatesAndDLCFromFolder}"
Header="{ext:Locale MenuBar_File_LoadTitleUpdatesAndDLCFromFolderButton}"
Icon="{ext:Icon fa-solid fa-inbox}"
IsEnabled="{Binding EnableNonGameRunningControls}" />
<Separator />
<MenuItem
Command="{Binding OpenRyujinxFolder}"
Header="{ext:Locale MenuBarFileOpenEmuFolder}"
Header="{ext:Locale MenuBar_File_OpenRyuijnxFolderButton}"
Icon="{ext:Icon fa-solid fa-folder-closed}" />
<MenuItem
Command="{Binding OpenLogsFolder}"
Header="{ext:Locale MenuBarFileOpenLogsFolder}"
Icon="{ext:Icon fa-solid fa-terminal}" />
Header="{ext:Locale MenuBar_File_OpenLogsFolderButton}"
Icon="{ext:Icon fa-solid fa-folder-closed}" />
<MenuItem
Command="{Binding OpenScreenshotsFolder}"
Header="{ext:Locale MenuBarFileOpenScreenshotsFolder}"
Icon="{ext:Icon fa-solid fa-image}" />
<Separator IsVisible="{Binding ManageFileTypesVisible}" />
<MenuItem Header="{ext:Locale MenuBar_File_ManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}" Icon="{ext:Icon fa-solid fa-clipboard}">
<MenuItem Name="InstallFileTypesMenuItem" Header="{ext:Locale MenuBar_File_InstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered, Converter={x:Static BoolConverters.Not}}" Icon="{ext:Icon fa-solid fa-square-plus}" />
<MenuItem Name="UninstallFileTypesMenuItem" Header="{ext:Locale MenuBar_File_UninstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered}" Icon="{ext:Icon fa-solid fa-square-minus}" />
Header="{ext:Locale MenuBar_File_OpenScreenshotsFolderButton}"
Icon="{ext:Icon fa-solid fa-folder-closed}" />
<Separator IsVisible="{Binding FileTypeAssociationsVisible}" />
<MenuItem
Command="{Binding ToggleFileTypeAssociationsCommand}"
Header="{Binding FileTypeAssociationsMenuHeader}"
IsVisible="{Binding FileTypeAssociationsVisible}"
IsEnabled="{Binding EnableNonGameRunningControls}"
ToolTip.Tip="{ext:Locale MenuBar_File_FileTypeAssociationsToolTip}">
<MenuItem.Icon>
<i:Icon Value="{Binding FileTypeAssociationsIcon}" />
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem
Name="CloseRyujinxMenuItem"
Header="{ext:Locale MenuBarFileExit}"
Icon="{ext:Icon fa-solid fa-power-off}" />
Header="{ext:Locale MenuBar_File_ExitButton}"
Icon="{ext:Icon fa-solid fa-arrow-right-from-bracket}" />
</MenuItem>
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarOptions}">
<MenuItem
Command="{Binding ToggleFullscreen}"
Header="{ext:Locale MenuBarOptionsToggleFullscreen}"
Classes="withCheckbox"
Padding="0"
Icon="{ext:Icon fa-solid fa-expand}"
InputGesture="F11">
</MenuItem>
<MenuItem
Padding="0"
Command="{Binding ToggleStartGamesInFullscreen}"
Header="{ext:Locale MenuBarOptionsStartGamesInFullscreen}"
Classes="withCheckbox">
<MenuItem.Icon>
<CheckBox
MinWidth="{DynamicResource CheckBoxSize}"
MinHeight="{DynamicResource CheckBoxSize}"
IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}"
Padding="0" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Padding="0"
Command="{Binding ToggleStartGamesWithoutUi}"
Header="{ext:Locale MenuBarOptionsStartGamesWithoutUI}"
Classes="withCheckbox">
<MenuItem.Icon>
<CheckBox
MinWidth="{DynamicResource CheckBoxSize}"
MinHeight="{DynamicResource CheckBoxSize}"
IsChecked="{Binding StartGamesWithoutUi, Mode=TwoWay}"
Padding="0" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Padding="0"
IsVisible="{Binding ShowConsoleVisible}"
Command="{Binding ToggleShowConsole}"
Header="{ext:Locale MenuBarOptionsShowConsole}"
Classes="withCheckbox">
<MenuItem.Icon>
<CheckBox
MinWidth="{DynamicResource CheckBoxSize}"
MinHeight="{DynamicResource CheckBoxSize}"
IsChecked="{Binding ShowConsole, Mode=TwoWay}"
Padding="0" />
</MenuItem.Icon>
</MenuItem>
<Separator/>
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBar_Options_OptionsLabel}">
<MenuItem
Name="ChangeLanguageMenuItem"
Padding="0"
Header="{ext:Locale MenuBarOptionsChangeLanguage}"
Icon="{ext:Icon fa-solid fa-globe}"
Classes="withCheckbox">
</MenuItem>
<MenuItem
Name="OpenSettingsMenuItem"
Padding="0"
Header="{ext:Locale MenuBarOptionsSettings}"
Icon="{ext:Icon fa-solid fa-gear}"
Classes="withCheckbox">
Header="{ext:Locale MenuBar_Options_LanguageButton}"
Icon="{ext:Icon fa-solid fa-globe}">
</MenuItem>
<MenuItem
Command="{Binding ManageProfiles}"
Padding="0"
Header="{ext:Locale MenuBarOptionsManageUserProfiles}"
Header="{ext:Locale MenuBar_Options_UserProfilesButton}"
Icon="{ext:Icon fa-solid fa-user}"
IsEnabled="{Binding EnableNonGameRunningControls}"
Classes="withCheckbox">
IsEnabled="{Binding EnableNonGameRunningControls}">
</MenuItem>
<Separator/>
<MenuItem
Name="OpenSettingsMenuItem"
Header="{ext:Locale MenuBar_Options_SettingsButton}"
Icon="{ext:Icon fa-solid fa-gear}">
</MenuItem>
</MenuItem>
<MenuItem
@@ -270,13 +220,36 @@
</MenuItem>
</MenuItem>
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarView}">
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarViewWindow}" Icon="{ext:Icon fa-solid fa-window-restore}">
<MenuItem Name="WindowSize720PMenuItem" Header="{ext:Locale MenuBarViewWindow720}" CommandParameter="1280 720" />
<MenuItem Name="WindowSize1080PMenuItem" Header="{ext:Locale MenuBarViewWindow1080}" CommandParameter="1920 1080" />
<MenuItem Name="WindowSize1440PMenuItem" Header="{ext:Locale MenuBarViewWindow1440}" CommandParameter="2560 1440" />
<MenuItem Name="WindowSize2160PMenuItem" Header="{ext:Locale MenuBarViewWindow2160}" CommandParameter="3840 2160" />
<MenuItem
Command="{Binding ToggleShowConsole}"
IsVisible="{Binding ShowConsoleVisible}"
Header="{ext:Locale MenuBar_View_ShowConsoleButton}"
Classes="withCheckbox"
Padding="0">
<MenuItem.Icon>
<CheckBox
MinWidth="{DynamicResource CheckBoxSize}"
MinHeight="{DynamicResource CheckBoxSize}"
IsChecked="{Binding ShowConsole, Mode=TwoWay}"
Padding="0" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Name="ToggleFileTypesMenuItem" Header="{ext:Locale MenuBarShowFileTypes}" Icon="{ext:Icon fa-solid fa-tags}" />
<MenuItem
Command="{Binding ToggleFullscreen}"
Padding="0"
Header="{ext:Locale MenuBar_View_ToggleFullscreenButton}"
Icon="{ext:Icon fa-solid fa-expand}"
InputGesture="F11"
Classes="withCheckbox">
</MenuItem>
<MenuItem VerticalAlignment="Center" Padding="0" Header="{ext:Locale MenuBarViewWindow}" Icon="{ext:Icon fa-solid fa-window-restore}" Classes="withCheckbox">
<MenuItem Name="WindowSize720PMenuItem" Padding = "15,0,0,0" Header="{ext:Locale MenuBarViewWindow720}" CommandParameter="1280 720" />
<MenuItem Name="WindowSize1080PMenuItem" Padding = "15,0,0,0" Header="{ext:Locale MenuBarViewWindow1080}" CommandParameter="1920 1080" />
<MenuItem Name="WindowSize1440PMenuItem" Padding = "15,0,0,0" Header="{ext:Locale MenuBarViewWindow1440}" CommandParameter="2560 1440" />
<MenuItem Name="WindowSize2160PMenuItem" Padding = "15,0,0,0" Header="{ext:Locale MenuBarViewWindow2160}" CommandParameter="3840 2160" />
</MenuItem>
<Separator />
<MenuItem Name="ToggleFileTypesMenuItem" Padding="0" Header="{ext:Locale MenuBarShowFileTypes}" Icon="{ext:Icon fa-solid fa-tags}" Classes="withCheckbox" />
</MenuItem>
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarHelp}">
<MenuItem

View File

@@ -36,7 +36,6 @@ namespace Ryujinx.Ava.UI.Views.Main
ToggleFileTypesMenuItem.ItemsSource = GenerateToggleFileTypeItems();
ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems();
MiiAppletMenuItem.Command = Commands.Create(OpenMiiApplet);
CloseRyujinxMenuItem.Command = Commands.Create(() => Window?.Close());
OpenSettingsMenuItem.Command = Commands.Create(OpenSettings);
@@ -44,8 +43,6 @@ namespace Ryujinx.Ava.UI.Views.Main
ResumeEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.Resume());
StopEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.ShowExitPrompt().OrCompleted());
RestartEmulationMenuItem.Command = Commands.Create(() => ViewModel.RestartEmulation());
InstallFileTypesMenuItem.Command = Commands.Create(InstallFileTypes);
UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes);
XciTrimmerMenuItem.Command = Commands.Create(XciTrimmerView.Show);
AboutWindowMenuItem.Command = Commands.Create(AboutView.Show);
CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityListWindow.Show());
@@ -77,6 +74,7 @@ namespace Ryujinx.Ava.UI.Views.Main
.Select(it =>
new CheckBox
{
Margin = new Thickness(10, 0, 0, 0),
Content = $".{it.FileName}",
IsChecked = it.FileType.GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes),
Command = Commands.Create(() => Window.ToggleFileType(it.FileName))
@@ -98,8 +96,7 @@ namespace Ryujinx.Ava.UI.Views.Main
MenuItem menuItem = new()
{
Padding = new Thickness(15, 0, 0, 0),
Margin = new Thickness(3, 0, 3, 0),
Padding = new Thickness(10, 0, 0, 0),
HorizontalAlignment = HorizontalAlignment.Stretch,
Header = code == currentLanguageCode ? $"{languageName} ✔" : languageName,
Command = Commands.Create(() => MainWindowViewModel.ChangeLanguage(code))
@@ -189,24 +186,6 @@ namespace Ryujinx.Ava.UI.Views.Main
ViewModel.ShowSkylanderActions = string.Equals(ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper(), "0100CCC0002E6000");
}
private async Task InstallFileTypes()
{
ViewModel.AreMimeTypesRegistered = FileAssociationHelper.Install();
if (ViewModel.AreMimeTypesRegistered)
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesSuccessMessage], string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
else
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesErrorMessage]);
}
private async Task UninstallFileTypes()
{
ViewModel.AreMimeTypesRegistered = !FileAssociationHelper.Uninstall();
if (!ViewModel.AreMimeTypesRegistered)
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesSuccessMessage], string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
else
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesErrorMessage]);
}
private void ChangeWindowSize(string resolution)
{
(int resolutionWidth, int resolutionHeight) = resolution.Split(' ', 2)

View File

@@ -36,6 +36,25 @@
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
</StackPanel>
</CheckBox>
<CheckBox
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{ext:Locale Settings_Interface_StartGamesInFullscreenCheckboxLabel}" />
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
</StackPanel>
</CheckBox>
<CheckBox
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
IsChecked="{Binding StartGamesWithoutUi, Mode=TwoWay}"
ToolTip.Tip="{ext:Locale Settings_Interface_StartGamesWithoutUICheckboxLabelToolTip}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{ext:Locale Settings_Interface_StartGamesWithoutUICheckboxLabel}" />
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
</StackPanel>
</CheckBox>
<CheckBox
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"

View File

@@ -4,10 +4,12 @@ using Avalonia.Platform.Storage;
using Avalonia.VisualTree;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Navigation;
using Gommon;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities;
using Ryujinx.HLE.FileSystem;
using SkiaSharp;
using System.Collections.Generic;
@@ -62,7 +64,7 @@ namespace Ryujinx.Ava.UI.Views.User
private async void Import_OnClick(object sender, RoutedEventArgs e)
{
IReadOnlyList<IStorageFile> result = await ((Window)this.GetVisualRoot()!).StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
Optional<IStorageFile> result = await ((Window)this.GetVisualRoot()!).StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
{
AllowMultiple = false,
FileTypeFilter = new List<FilePickerFileType>
@@ -76,9 +78,9 @@ namespace Ryujinx.Ava.UI.Views.User
},
});
if (result.Count > 0)
if (result.HasValue)
{
_profile.Image = ProcessProfileImage(File.ReadAllBytes(result[0].Path.LocalPath));
_profile.Image = ProcessProfileImage(File.ReadAllBytes(result.Value.Path.LocalPath));
_parent.GoBack();
}
}

View File

@@ -45,6 +45,10 @@
<KeyBinding Gesture="Ctrl+Shift+R" Command="{Binding ReloadRenderDocApi}" />
<KeyBinding Gesture="Ctrl+Shift+C" Command="{Binding ToggleCapture}" />
<KeyBinding Gesture="Ctrl+M" Command="{Binding SimulateWakeUpMessage}" />
<KeyBinding Gesture="Cmd+O" Command="{Binding LoadApplicationFromFile}" />
<KeyBinding Gesture="Ctrl+O" Command="{Binding LoadApplicationFromFile}" />
<KeyBinding Gesture="Cmd+Shift+O" Command="{Binding LoadUnpackedGameFromFolder}" />
<KeyBinding Gesture="Ctrl+Shift+O" Command="{Binding LoadUnpackedGameFromFolder}" />
</Window.KeyBindings>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*">
<helpers:OffscreenTextBox IsEnabled="False" Opacity="0" Name="HiddenTextBox" IsHitTestVisible="False" IsTabStop="False" />

View File

@@ -741,10 +741,10 @@ namespace Ryujinx.Ava.UI.Windows
{
string[] messages =
[
numDlcRemoved > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.AutoloadDlcRemovedMessage], numDlcRemoved): null,
numDlcAdded > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.AutoloadDlcAddedMessage], numDlcAdded): null,
numUpdatesRemoved > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.AutoloadUpdateRemovedMessage], numUpdatesRemoved): null,
numUpdatesAdded > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.AutoloadUpdateAddedMessage], numUpdatesAdded) : null
numDlcRemoved > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.Dialog_ContentLoading_DLCRemovedMessage], numDlcRemoved): null,
numDlcAdded > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.Dialog_ContentLoading_DLCAddedMessage], numDlcAdded): null,
numUpdatesRemoved > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.Dialog_ContentLoading_UpdatesRemovedMessage], numUpdatesRemoved): null,
numUpdatesAdded > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.Dialog_ContentLoading_UpdatesAddedMessage], numUpdatesAdded) : null
];
string msg = String.Join("\r\n", messages);

View File

@@ -29,7 +29,7 @@ namespace Ryujinx.Ava.Utilities
.Then(files => files.Count > 0 ? Optional.Of(files) : default);
}
private static async Task<T> CoreDumpable<T>(Func<Task<T>> picker)
public static async Task<T> CoreDumpable<T>(Func<Task<T>> picker)
{
OsUtils.SetCoreDumpable(true);
try