Compare commits
37 Commits
1.2.80
...
fa4f80ebdf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa4f80ebdf | ||
|
|
c06f16c5e6 | ||
|
|
7829fd8ee7 | ||
|
|
33079422fe | ||
|
|
f81cb093fc | ||
|
|
dc0c7a2912 | ||
|
|
1fbee5a584 | ||
|
|
c140e9b23c | ||
|
|
9c8055440e | ||
|
|
c03cd50fa3 | ||
|
|
069f630776 | ||
|
|
1fb1530ea3 | ||
|
|
13d411e4de | ||
|
|
9f53b07491 | ||
|
|
cd8113dadf | ||
|
|
9089c4ffe5 | ||
|
|
fe9d8d05bd | ||
|
|
880a8ae748 | ||
|
|
11531dacb6 | ||
|
|
3974739ed3 | ||
|
|
440a3447fb | ||
|
|
65374ed6cb | ||
|
|
789d6ab959 | ||
|
|
182db31343 | ||
|
|
ea296b134d | ||
|
|
bf584442b2 | ||
|
|
cb7c294dbf | ||
|
|
eaf1e7efd2 | ||
|
|
471e7ed2e4 | ||
|
|
ad3e80b383 | ||
|
|
ed64a63094 | ||
|
|
8df7ba2d56 | ||
|
|
e743d78115 | ||
|
|
04ba762710 | ||
|
|
f42b2ed59d | ||
|
|
d135385cab | ||
|
|
b360f4e721 |
4
.github/labeler.yml
vendored
4
.github/labeler.yml
vendored
@@ -18,6 +18,10 @@ gpu:
|
|||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**']
|
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**']
|
||||||
|
|
||||||
|
'graphics-backend:metal':
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Metal/**', 'src/Ryujinx.Graphics.Metal.SharpMetalExtensions/**']
|
||||||
|
|
||||||
gui:
|
gui:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**']
|
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**']
|
||||||
|
|||||||
2
.github/workflows/canary.yml
vendored
2
.github/workflows/canary.yml
vendored
@@ -202,7 +202,7 @@ jobs:
|
|||||||
|
|
||||||
macos_release:
|
macos_release:
|
||||||
name: Release MacOS universal
|
name: Release MacOS universal
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -183,7 +183,7 @@ jobs:
|
|||||||
|
|
||||||
macos_release:
|
macos_release:
|
||||||
name: Release MacOS universal
|
name: Release MacOS universal
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
|||||||
@@ -54,12 +54,13 @@ failing to meet this requirement may result in a poor gameplay experience or une
|
|||||||
|
|
||||||
## Latest build
|
## Latest build
|
||||||
|
|
||||||
Stable builds are made every so often onto a separate "release" branch that then gets put into the releases you know and love.
|
Stable builds are made every so often, based on the `master` branch, that then gets put into the releases you know and love.
|
||||||
These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
|
These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
|
||||||
|
They are released every month or so, to ensure consistent updates, while not being an annoying amount of individual updates to download over the course of that month.
|
||||||
|
|
||||||
You can find the latest stable release [here](https://github.com/GreemDev/Ryujinx/releases/latest).
|
You can find the latest stable release [here](https://github.com/GreemDev/Ryujinx/releases/latest).
|
||||||
|
|
||||||
Canary builds are compiled automatically for each commit on the master branch.
|
Canary builds are compiled automatically for each commit on the `master` branch.
|
||||||
While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**.
|
While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**.
|
||||||
These canary builds are only recommended for experienced users.
|
These canary builds are only recommended for experienced users.
|
||||||
|
|
||||||
@@ -109,7 +110,7 @@ If you are planning to contribute or just want to learn more about this project
|
|||||||
- **Configuration**
|
- **Configuration**
|
||||||
|
|
||||||
The emulator has settings for enabling or disabling some logging, remapping controllers, and more.
|
The emulator has settings for enabling or disabling some logging, remapping controllers, and more.
|
||||||
You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the user folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
|
You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the Ryujinx data folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -1070,6 +1070,7 @@
|
|||||||
010017B0102A8000,"Emma: Lost in Memories",nvdec,playable,2021-01-28 16:19:10
|
010017B0102A8000,"Emma: Lost in Memories",nvdec,playable,2021-01-28 16:19:10
|
||||||
010068300E08E000,"Enchanted in the Moonlight - Kiryu, Chikage & Yukinojo -",gpu;nvdec,ingame,2022-11-20 16:18:45
|
010068300E08E000,"Enchanted in the Moonlight - Kiryu, Chikage & Yukinojo -",gpu;nvdec,ingame,2022-11-20 16:18:45
|
||||||
01007A4008486000,"Enchanting Mahjong Match",gpu,ingame,2020-04-17 22:01:31
|
01007A4008486000,"Enchanting Mahjong Match",gpu,ingame,2020-04-17 22:01:31
|
||||||
|
0100EF901E552000,"ENDER MAGNOLIA: Bloom in the Mist",deadlock,boots,2025-01-22 17:59:00
|
||||||
01004F3011F92000,"Endless Fables: Dark Moor",gpu;nvdec,ingame,2021-03-07 15:31:03
|
01004F3011F92000,"Endless Fables: Dark Moor",gpu;nvdec,ingame,2021-03-07 15:31:03
|
||||||
010067B017588000,"Endless Ocean™ Luminous",services-horizon;crash,ingame,2024-05-30 02:05:57
|
010067B017588000,"Endless Ocean™ Luminous",services-horizon;crash,ingame,2024-05-30 02:05:57
|
||||||
0100B8700BD14000,"Energy Cycle Edge",services,ingame,2021-11-30 05:02:31
|
0100B8700BD14000,"Energy Cycle Edge",services,ingame,2021-11-30 05:02:31
|
||||||
@@ -2681,7 +2682,7 @@
|
|||||||
01005EA01C0FC000,"SONIC X SHADOW GENERATIONS",crash,ingame,2025-01-07 04:20:45
|
01005EA01C0FC000,"SONIC X SHADOW GENERATIONS",crash,ingame,2025-01-07 04:20:45
|
||||||
010064F00C212000,"Soul Axiom Rebooted",nvdec;slow,ingame,2020-09-04 12:41:01
|
010064F00C212000,"Soul Axiom Rebooted",nvdec;slow,ingame,2020-09-04 12:41:01
|
||||||
0100F2100F0B2000,"Soul Searching",,playable,2020-07-09 18:39:07
|
0100F2100F0B2000,"Soul Searching",,playable,2020-07-09 18:39:07
|
||||||
01008F2005154000,"South Park™: The Fractured but Whole™ - Standard Edition",slow;online-broken,playable,2024-07-08 17:47:28
|
01008F2005154000,"South Park™: The Fractured but Whole™ - Standard Edition",slow;online-broken;vulkan-backend-bug;gpu,ingame,2025-01-21 17:35:10
|
||||||
0100B9F00C162000,"Space Blaze",,playable,2020-08-30 16:18:05
|
0100B9F00C162000,"Space Blaze",,playable,2020-08-30 16:18:05
|
||||||
010005500E81E000,"Space Cows",UE4;crash,menus,2020-06-15 11:33:20
|
010005500E81E000,"Space Cows",UE4;crash,menus,2020-06-15 11:33:20
|
||||||
0100707011722000,"Space Elite Force",,playable,2020-11-27 15:21:05
|
0100707011722000,"Space Elite Force",,playable,2020-11-27 15:21:05
|
||||||
|
|||||||
|
@@ -78,5 +78,10 @@ namespace Ryujinx.Common.Configuration.Hid.Controller
|
|||||||
/// Controller Rumble Settings
|
/// Controller Rumble Settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RumbleConfigController Rumble { get; set; }
|
public RumbleConfigController Rumble { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controller LED Settings
|
||||||
|
/// </summary>
|
||||||
|
public LedConfigController Led { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||||
|
{
|
||||||
|
public class LedConfigController
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Packed RGB int of the color
|
||||||
|
/// </summary>
|
||||||
|
public uint LedColor { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable LED color changing by the emulator
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableLed { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/Ryujinx.Common/Helpers/RunningPlatform.cs
Normal file
23
src/Ryujinx.Common/Helpers/RunningPlatform.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
// ReSharper disable MemberCanBePrivate.Global
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Helper
|
||||||
|
{
|
||||||
|
public static class RunningPlatform
|
||||||
|
{
|
||||||
|
public static bool IsMacOS => OperatingSystem.IsMacOS();
|
||||||
|
public static bool IsWindows => OperatingSystem.IsWindows();
|
||||||
|
public static bool IsLinux => OperatingSystem.IsLinux();
|
||||||
|
|
||||||
|
public static bool IsIntelMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.X64;
|
||||||
|
public static bool IsArmMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.Arm64;
|
||||||
|
|
||||||
|
public static bool IsX64Windows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.X64);
|
||||||
|
public static bool IsArmWindows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
|
||||||
|
|
||||||
|
public static bool IsX64Linux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.X64);
|
||||||
|
public static bool IsArmLinux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@@ -8,19 +9,20 @@ namespace Ryujinx.Common
|
|||||||
{
|
{
|
||||||
public static class TitleIDs
|
public static class TitleIDs
|
||||||
{
|
{
|
||||||
public static ReactiveObject<Optional<string>> CurrentApplication { get; set; } = new();
|
public static ReactiveObject<Optional<string>> CurrentApplication { get; } = new();
|
||||||
|
|
||||||
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
|
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
|
||||||
{
|
{
|
||||||
switch (currentBackend)
|
switch (currentBackend)
|
||||||
{
|
{
|
||||||
|
case GraphicsBackend.Metal when !OperatingSystem.IsMacOS():
|
||||||
case GraphicsBackend.OpenGl when OperatingSystem.IsMacOS():
|
case GraphicsBackend.OpenGl when OperatingSystem.IsMacOS():
|
||||||
return GraphicsBackend.Vulkan;
|
return GraphicsBackend.Vulkan;
|
||||||
case GraphicsBackend.Vulkan or GraphicsBackend.OpenGl or GraphicsBackend.Metal:
|
case GraphicsBackend.Vulkan or GraphicsBackend.OpenGl or GraphicsBackend.Metal:
|
||||||
return currentBackend;
|
return currentBackend;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture is Architecture.Arm64))
|
if (!RunningPlatform.IsArmMac)
|
||||||
return GraphicsBackend.Vulkan;
|
return GraphicsBackend.Vulkan;
|
||||||
|
|
||||||
return GreatMetalTitles.ContainsIgnoreCase(titleId) ? GraphicsBackend.Metal : GraphicsBackend.Vulkan;
|
return GreatMetalTitles.ContainsIgnoreCase(titleId) ? GraphicsBackend.Metal : GraphicsBackend.Vulkan;
|
||||||
@@ -28,18 +30,28 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
public static readonly string[] GreatMetalTitles =
|
public static readonly string[] GreatMetalTitles =
|
||||||
[
|
[
|
||||||
"01006f8002326000", // Animal Crossings: New Horizons
|
"010076f0049a2000", // Bayonetta
|
||||||
"01009bf0072d4000", // Captain Toad: Treasure Tracker
|
|
||||||
"0100a5c00d162000", // Cuphead
|
"0100a5c00d162000", // Cuphead
|
||||||
"010023800d64a000", // Deltarune
|
"010023800d64a000", // Deltarune
|
||||||
|
"01003a30012c0000", // LEGO City Undercover
|
||||||
"010028600EBDA000", // Mario 3D World
|
"010028600EBDA000", // Mario 3D World
|
||||||
"0100152000022000", // Mario Kart 8 Deluxe
|
"0100152000022000", // Mario Kart 8 Deluxe
|
||||||
"01005CA01580E000", // Persona 5
|
"010075a016a3a000", // Persona 4 Arena Ultimax
|
||||||
"0100187003A36000", // Pokémon: Let's Go, Evoli!
|
"0100187003A36000", // Pokémon: Let's Go, Eevee!
|
||||||
"010003f003a34000", // Pokémon: Let's Go, Pikachu!
|
"010003f003a34000", // Pokémon: Let's Go, Pikachu!
|
||||||
"01008C0016544000", // Sea of Stars
|
"01008C0016544000", // Sea of Stars
|
||||||
"01006A800016E000", // Smash Ultimate
|
"01006A800016E000", // Smash Ultimate
|
||||||
"0100000000010000", // Super Mario Odyessy
|
"01006bb00c6f0000", // The Legend of Zelda: Link's Awakening
|
||||||
|
|
||||||
|
// These ones have small issues, but those happen on Vulkan as well:
|
||||||
|
"01006f8002326000", // Animal Crossings: New Horizons
|
||||||
|
"01009bf0072d4000", // Captain Toad: Treasure Tracker
|
||||||
|
"01009510001ca000", // Fast RMX
|
||||||
|
"01005CA01580E000", // Persona 5 Royale
|
||||||
|
"0100000000010000", // Super Mario Odyssey
|
||||||
|
|
||||||
|
//Isaac claims it has a issue in level 2, but I am not able to replicate it on my M3. More testing would be appreciated:
|
||||||
|
"010015100b514000", // Super Mario Bros. Wonder
|
||||||
];
|
];
|
||||||
|
|
||||||
public static string GetDiscordGameAsset(string titleId)
|
public static string GetDiscordGameAsset(string titleId)
|
||||||
@@ -47,72 +59,87 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
public static readonly string[] DiscordGameAssetKeys =
|
public static readonly string[] DiscordGameAssetKeys =
|
||||||
[
|
[
|
||||||
|
//All games are in Alphabetical order by Game name.
|
||||||
|
|
||||||
|
//Dragon Quest Franchise
|
||||||
"010008900705c000", // Dragon Quest Builders
|
"010008900705c000", // Dragon Quest Builders
|
||||||
"010042000a986000", // Dragon Quest Builders 2
|
"010042000a986000", // Dragon Quest Builders 2
|
||||||
|
|
||||||
"010055d009f78000", // Fire Emblem: Three Houses
|
//Fire Emblem Franchise
|
||||||
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
|
||||||
"0100a6301214e000", // Fire Emblem Engage
|
"0100a6301214e000", // Fire Emblem Engage
|
||||||
|
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
||||||
|
"010055d009f78000", // Fire Emblem: Three Houses
|
||||||
"0100f15003e64000", // Fire Emblem Warriors
|
"0100f15003e64000", // Fire Emblem Warriors
|
||||||
"010071f0143ea000", // Fire Emblem Warriors: Three Hopes
|
"010071f0143ea000", // Fire Emblem Warriors: Three Hopes
|
||||||
|
|
||||||
"01007e3006dda000", // Kirby Star Allies
|
//Kirby Franchise
|
||||||
"01004d300c5ae000", // Kirby and the Forgotten Land
|
"01004d300c5ae000", // Kirby and the Forgotten Land
|
||||||
"01006b601380e000", // Kirby's Return to Dream Land Deluxe
|
|
||||||
"01003fb00c5a8000", // Super Kirby Clash
|
|
||||||
"0100227010460000", // Kirby Fighters 2
|
|
||||||
"0100a8e016236000", // Kirby's Dream Buffet
|
"0100a8e016236000", // Kirby's Dream Buffet
|
||||||
|
"0100227010460000", // Kirby Fighters 2
|
||||||
|
"01006b601380e000", // Kirby's Return to Dream Land Deluxe
|
||||||
|
"01007e3006dda000", // Kirby Star Allies
|
||||||
|
"01003fb00c5a8000", // Super Kirby Clash
|
||||||
|
|
||||||
|
|
||||||
|
//The Zelda Franchise
|
||||||
|
"01000b900d8b0000", // Cadence of Hyrule
|
||||||
|
"0100ae00096ea000", // Hyrule Warriors: Definitive Edition
|
||||||
|
"01002b00111a2000", // Hyrule Warriors: Age of Calamity
|
||||||
"01007ef00011e000", // The Legend of Zelda: Breath of the Wild
|
"01007ef00011e000", // The Legend of Zelda: Breath of the Wild
|
||||||
"01006bb00c6f0000", // The Legend of Zelda: Link's Awakening
|
"01006bb00c6f0000", // The Legend of Zelda: Link's Awakening
|
||||||
"01002da013484000", // The Legend of Zelda: Skyward Sword HD
|
"01002da013484000", // The Legend of Zelda: Skyward Sword HD
|
||||||
"0100f2c0115b6000", // The Legend of Zelda: Tears of the Kingdom
|
"0100f2c0115b6000", // The Legend of Zelda: Tears of the Kingdom
|
||||||
"01008cf01baac000", // The Legend of Zelda: Echoes of Wisdom
|
"01008cf01baac000", // The Legend of Zelda: Echoes of Wisdom
|
||||||
"01000b900d8b0000", // Cadence of Hyrule
|
|
||||||
"0100ae00096ea000", // Hyrule Warriors: Definitive Edition
|
|
||||||
"01002b00111a2000", // Hyrule Warriors: Age of Calamity
|
|
||||||
|
|
||||||
|
//Luigi Franchise
|
||||||
"010048701995e000", // Luigi's Mansion 2 HD
|
"010048701995e000", // Luigi's Mansion 2 HD
|
||||||
"0100dca0064a6000", // Luigi's Mansion 3
|
"0100dca0064a6000", // Luigi's Mansion 3
|
||||||
|
|
||||||
|
//Metroid Franchise
|
||||||
"010093801237c000", // Metroid Dread
|
"010093801237c000", // Metroid Dread
|
||||||
"010012101468c000", // Metroid Prime Remastered
|
"010012101468c000", // Metroid Prime Remastered
|
||||||
|
|
||||||
"0100000000010000", // SUPER MARIO ODYSSEY
|
//Monster Hunter Franchise
|
||||||
"0100ea80032ea000", // Super Mario Bros. U Deluxe
|
"0100770008dd8000", // Monster Hunter Generations Ultimate
|
||||||
"01009b90006dc000", // Super Mario Maker 2
|
"0100b04011742000", // Monster Hunter Rise
|
||||||
"010049900f546000", // Super Mario 3D All-Stars
|
|
||||||
"010049900F546001", // ^ 64
|
//Mario Franchise
|
||||||
"010049900F546002", // ^ Sunshine
|
|
||||||
"010049900F546003", // ^ Galaxy
|
|
||||||
"010028600ebda000", // Super Mario 3D World + Bowser's Fury
|
|
||||||
"010015100b514000", // Super Mario Bros. Wonder
|
|
||||||
"0100152000022000", // Mario Kart 8 Deluxe
|
|
||||||
"010036b0034e4000", // Super Mario Party
|
|
||||||
"01006fe013472000", // Mario Party Superstars
|
|
||||||
"0100965017338000", // Super Mario Party Jamboree
|
|
||||||
"01006d0017f7a000", // Mario & Luigi: Brothership
|
"01006d0017f7a000", // Mario & Luigi: Brothership
|
||||||
|
"010003000e146000", // Mario & Sonic at the Olympic Games Tokyo 2020
|
||||||
"010067300059a000", // Mario + Rabbids: Kingdom Battle
|
"010067300059a000", // Mario + Rabbids: Kingdom Battle
|
||||||
"0100317013770000", // Mario + Rabbids: Sparks of Hope
|
"0100317013770000", // Mario + Rabbids: Sparks of Hope
|
||||||
|
"0100c9c00e25c000", // Mario Golf: Super Rush
|
||||||
|
"0100152000022000", // Mario Kart 8 Deluxe
|
||||||
|
"01006fe013472000", // Mario Party Superstars
|
||||||
|
"010019401051c000", // Mario Strikers: Battle League
|
||||||
|
"0100bde00862a000", // Mario Tennis Aces
|
||||||
|
"0100b99019412000", // Mario vs. Donkey Kong
|
||||||
|
"010049900f546000", // Super Mario 3D All-Stars
|
||||||
|
"010028600ebda000", // Super Mario 3D World + Bowser's Fury
|
||||||
|
"010049900F546001", // Super Mario 64
|
||||||
|
"0100ea80032ea000", // Super Mario Bros. U Deluxe
|
||||||
|
"010015100b514000", // Super Mario Bros. Wonder
|
||||||
|
"010049900F546003", // Super Mario Galaxy
|
||||||
|
"01009b90006dc000", // Super Mario Maker 2
|
||||||
|
"0100000000010000", // SUPER MARIO ODYSSEY
|
||||||
|
"010036b0034e4000", // Super Mario Party
|
||||||
|
"0100965017338000", // Super Mario Party Jamboree
|
||||||
|
"0100bc0018138000", // Super Mario RPG
|
||||||
|
"010049900F546002", // Super Mario Sunshine
|
||||||
"0100a3900c3e2000", // Paper Mario: The Origami King
|
"0100a3900c3e2000", // Paper Mario: The Origami King
|
||||||
"0100ecd018ebe000", // Paper Mario: The Thousand-Year Door
|
"0100ecd018ebe000", // Paper Mario: The Thousand-Year Door
|
||||||
"0100bc0018138000", // Super Mario RPG
|
|
||||||
"0100bde00862a000", // Mario Tennis Aces
|
|
||||||
"0100c9c00e25c000", // Mario Golf: Super Rush
|
|
||||||
"010019401051c000", // Mario Strikers: Battle League
|
|
||||||
"010003000e146000", // Mario & Sonic at the Olympic Games Tokyo 2020
|
|
||||||
"0100b99019412000", // Mario vs. Donkey Kong
|
|
||||||
|
|
||||||
|
//Pikmin Franchise
|
||||||
"0100aa80194b0000", // Pikmin 1
|
"0100aa80194b0000", // Pikmin 1
|
||||||
"0100d680194b2000", // Pikmin 2
|
"0100d680194b2000", // Pikmin 2
|
||||||
"0100f4c009322000", // Pikmin 3 Deluxe
|
"0100f4c009322000", // Pikmin 3 Deluxe
|
||||||
"0100b7c00933a000", // Pikmin 4
|
"0100b7c00933a000", // Pikmin 4
|
||||||
|
|
||||||
|
//The Pokémon Franchise
|
||||||
"0100f4300bf2c000", // New Pokémon Snap
|
"0100f4300bf2c000", // New Pokémon Snap
|
||||||
"0100000011d90000", // Pokémon Brilliant Diamond
|
"0100000011d90000", // Pokémon Brilliant Diamond
|
||||||
"01001f5010dfa000", // Pokémon Legends: Arceus
|
"01001f5010dfa000", // Pokémon Legends: Arceus
|
||||||
"010003f003a34000", // Pokémon: Let's Go Pikachu!
|
|
||||||
"0100187003a36000", // Pokémon: Let's Go Eevee!
|
|
||||||
"01003d200baa2000", // Pokémon Mystery Dungeon - Rescue Team DX
|
"01003d200baa2000", // Pokémon Mystery Dungeon - Rescue Team DX
|
||||||
"0100a3d008c5c000", // Pokémon Scarlet
|
"0100a3d008c5c000", // Pokémon Scarlet
|
||||||
"01008db008c2c000", // Pokémon Shield
|
"01008db008c2c000", // Pokémon Shield
|
||||||
@@ -120,24 +147,29 @@ namespace Ryujinx.Common
|
|||||||
"0100abf008968000", // Pokémon Sword
|
"0100abf008968000", // Pokémon Sword
|
||||||
"01008f6008c5e000", // Pokémon Violet
|
"01008f6008c5e000", // Pokémon Violet
|
||||||
"0100b3f000be2000", // Pokkén Tournament DX
|
"0100b3f000be2000", // Pokkén Tournament DX
|
||||||
|
"0100187003a36000", // Pokémon: Let's Go Eevee!
|
||||||
|
"010003f003a34000", // Pokémon: Let's Go Pikachu!
|
||||||
|
|
||||||
"01003bc0000a0000", // Splatoon 2 (US)
|
//Splatoon Franchise
|
||||||
"0100f8f0000a2000", // Splatoon 2 (EU)
|
"0100f8f0000a2000", // Splatoon 2 (EU)
|
||||||
"01003c700009c000", // Splatoon 2 (JP)
|
"01003c700009c000", // Splatoon 2 (JP)
|
||||||
|
"01003bc0000a0000", // Splatoon 2 (US)
|
||||||
"0100c2500fc20000", // Splatoon 3
|
"0100c2500fc20000", // Splatoon 3
|
||||||
"0100ba0018500000", // Splatoon 3: Splatfest World Premiere
|
"0100ba0018500000", // Splatoon 3: Splatfest World Premiere
|
||||||
|
|
||||||
"010040600c5ce000", // Tetris 99
|
//NSO Membership games
|
||||||
"0100277011f1a000", // Super Mario Bros. 35
|
|
||||||
"0100ad9012510000", // PAC-MAN 99
|
|
||||||
"0100ccf019c8c000", // F-ZERO 99
|
"0100ccf019c8c000", // F-ZERO 99
|
||||||
"0100d870045b6000", // NES - Nintendo Switch Online
|
|
||||||
"01008d300c50c000", // SNES - Nintendo Switch Online
|
|
||||||
"0100c9a00ece6000", // N64 - Nintendo Switch Online
|
|
||||||
"0100e0601c632000", // N64 - Nintendo Switch Online 18+
|
|
||||||
"0100c62011050000", // GB - Nintendo Switch Online
|
"0100c62011050000", // GB - Nintendo Switch Online
|
||||||
"010012f017576000", // GBA - Nintendo Switch Online
|
"010012f017576000", // GBA - Nintendo Switch Online
|
||||||
|
"0100c9a00ece6000", // N64 - Nintendo Switch Online
|
||||||
|
"0100e0601c632000", // N64 - Nintendo Switch Online 18+
|
||||||
|
"0100d870045b6000", // NES - Nintendo Switch Online
|
||||||
|
"0100ad9012510000", // PAC-MAN 99
|
||||||
|
"010040600c5ce000", // Tetris 99
|
||||||
|
"01008d300c50c000", // SNES - Nintendo Switch Online
|
||||||
|
"0100277011f1a000", // Super Mario Bros. 35
|
||||||
|
|
||||||
|
//Misc Nintendo 1st party games
|
||||||
"01000320000cc000", // 1-2 Switch
|
"01000320000cc000", // 1-2 Switch
|
||||||
"0100300012f2a000", // Advance Wars 1+2: Re-Boot Camp
|
"0100300012f2a000", // Advance Wars 1+2: Re-Boot Camp
|
||||||
"01006f8002326000", // Animal Crossing: New Horizons
|
"01006f8002326000", // Animal Crossing: New Horizons
|
||||||
@@ -152,27 +184,32 @@ namespace Ryujinx.Common
|
|||||||
"01006a800016e000", // Super Smash Bros. Ultimate
|
"01006a800016e000", // Super Smash Bros. Ultimate
|
||||||
"0100a9400c9c2000", // Tokyo Mirage Sessions #FE Encore
|
"0100a9400c9c2000", // Tokyo Mirage Sessions #FE Encore
|
||||||
|
|
||||||
|
//Bayonetta Franchise
|
||||||
"010076f0049a2000", // Bayonetta
|
"010076f0049a2000", // Bayonetta
|
||||||
"01007960049a0000", // Bayonetta 2
|
"01007960049a0000", // Bayonetta 2
|
||||||
"01004a4010fea000", // Bayonetta 3
|
"01004a4010fea000", // Bayonetta 3
|
||||||
"0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon
|
"0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon
|
||||||
|
|
||||||
|
//Persona Franchise
|
||||||
"0100dcd01525a000", // Persona 3 Portable
|
"0100dcd01525a000", // Persona 3 Portable
|
||||||
"010062b01525c000", // Persona 4 Golden
|
|
||||||
"010075a016a3a000", // Persona 4 Arena Ultimax
|
"010075a016a3a000", // Persona 4 Arena Ultimax
|
||||||
|
"010062b01525c000", // Persona 4 Golden
|
||||||
"01005ca01580e000", // Persona 5 Royal
|
"01005ca01580e000", // Persona 5 Royal
|
||||||
"0100801011c3e000", // Persona 5 Strikers
|
"0100801011c3e000", // Persona 5 Strikers
|
||||||
"010087701b092000", // Persona 5 Tactica
|
"010087701b092000", // Persona 5 Tactica
|
||||||
|
|
||||||
"01009aa000faa000", // Sonic Mania
|
//Sonic Franchise
|
||||||
"01004ad014bf0000", // Sonic Frontiers
|
"01004ad014bf0000", // Sonic Frontiers
|
||||||
|
"01009aa000faa000", // Sonic Mania
|
||||||
"01005ea01c0fc000", // SONIC X SHADOW GENERATIONS
|
"01005ea01c0fc000", // SONIC X SHADOW GENERATIONS
|
||||||
"01005ea01c0fc001", // ^
|
"01005ea01c0fc001", // ^
|
||||||
|
|
||||||
|
//Xenoblade Franchise
|
||||||
"0100ff500e34a000", // Xenoblade Chronicles - Definitive Edition
|
"0100ff500e34a000", // Xenoblade Chronicles - Definitive Edition
|
||||||
"0100e95004038000", // Xenoblade Chronicles 2
|
"0100e95004038000", // Xenoblade Chronicles 2
|
||||||
"010074f013262000", // Xenoblade Chronicles 3
|
"010074f013262000", // Xenoblade Chronicles 3
|
||||||
|
|
||||||
|
//Misc Games
|
||||||
"010056e00853a000", // A Hat in Time
|
"010056e00853a000", // A Hat in Time
|
||||||
"0100fd1014726000", // Baldurs Gate: Dark Alliance
|
"0100fd1014726000", // Baldurs Gate: Dark Alliance
|
||||||
"0100dbf01000a000", // Burnout Paradise Remastered
|
"0100dbf01000a000", // Burnout Paradise Remastered
|
||||||
@@ -185,8 +222,6 @@ namespace Ryujinx.Common
|
|||||||
"01003620068ea000", // Hand of Fate 2
|
"01003620068ea000", // Hand of Fate 2
|
||||||
"010085500130a000", // Lego City: Undercover
|
"010085500130a000", // Lego City: Undercover
|
||||||
"010073c01af34000", // LEGO Horizon Adventures
|
"010073c01af34000", // LEGO Horizon Adventures
|
||||||
"0100770008dd8000", // Monster Hunter Generations Ultimate
|
|
||||||
"0100b04011742000", // Monster Hunter Rise
|
|
||||||
"0100853015e86000", // No Man's Sky
|
"0100853015e86000", // No Man's Sky
|
||||||
"01007bb017812000", // Portal
|
"01007bb017812000", // Portal
|
||||||
"0100abd01785c000", // Portal 2
|
"0100abd01785c000", // Portal 2
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
private static string GetDiskCachePath()
|
private static string GetDiskCachePath()
|
||||||
{
|
{
|
||||||
return GraphicsConfig.EnableShaderCache && GraphicsConfig.TitleId != null
|
return GraphicsConfig.EnableShaderCache && GraphicsConfig.TitleId != null
|
||||||
? Path.Combine(AppDataManager.GamesDirPath, GraphicsConfig.TitleId, "cache", "shader")
|
? Path.Combine(AppDataManager.GamesDirPath, GraphicsConfig.TitleId.ToLower(), "cache", "shader")
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -710,9 +710,8 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
{
|
{
|
||||||
updateNcasItem.Add((nca.Header.ContentType, entry.FullName));
|
updateNcasItem.Add((nca.Header.ContentType, entry.FullName));
|
||||||
}
|
}
|
||||||
else
|
else if (updateNcas.TryAdd(nca.Header.TitleId, new List<(NcaContentType, string)>()))
|
||||||
{
|
{
|
||||||
updateNcas.Add(nca.Header.TitleId, new List<(NcaContentType, string)>());
|
|
||||||
updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullName));
|
updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -898,9 +897,8 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
{
|
{
|
||||||
updateNcasItem.Add((nca.Header.ContentType, entry.FullPath));
|
updateNcasItem.Add((nca.Header.ContentType, entry.FullPath));
|
||||||
}
|
}
|
||||||
else
|
else if (updateNcas.TryAdd(nca.Header.TitleId, new List<(NcaContentType, string)>()))
|
||||||
{
|
{
|
||||||
updateNcas.Add(nca.Header.TitleId, new List<(NcaContentType, string)>());
|
|
||||||
updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullPath));
|
updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||||||
ProfilesJson profilesJson = JsonHelper.DeserializeFromFile(_profilesJsonPath, _serializerContext.ProfilesJson);
|
ProfilesJson profilesJson = JsonHelper.DeserializeFromFile(_profilesJsonPath, _serializerContext.ProfilesJson);
|
||||||
|
|
||||||
return profilesJson.Profiles
|
return profilesJson.Profiles
|
||||||
.FindFirst(profile => profile.AccountState == AccountState.Open)
|
.FindFirst(profile => profile.UserId == profilesJson.LastOpened)
|
||||||
.Convert(profileJson => new UserProfile(new UserId(profileJson.UserId), profileJson.Name,
|
.Convert(profileJson => new UserProfile(new UserId(profileJson.UserId), profileJson.Name,
|
||||||
profileJson.Image, profileJson.LastModifiedTimestamp));
|
profileJson.Image, profileJson.LastModifiedTimestamp));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -659,7 +659,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
|||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(filePath))
|
if (string.IsNullOrWhiteSpace(filePath))
|
||||||
{
|
{
|
||||||
throw new InvalidSystemResourceException("JIT (010000000000003B) system title not found! The JIT will not work, provide the system archive to fix this error. (See https://github.com/GreemDev/Ryujinx#requirements for more information)");
|
throw new InvalidSystemResourceException("JIT (010000000000003B) system title not found! The JIT will not work, provide the system archive to fix this error. (See https://github.com/Ryubing/Ryujinx#requirements for more information)");
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Device.LoadNca(filePath);
|
context.Device.LoadNca(filePath);
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
|
|||||||
titleName = "Unknown";
|
titleName = "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new InvalidSystemResourceException($"{titleName} ({fontTitle:x8}) system title not found! This font will not work, provide the system archive to fix this error. (See https://github.com/GreemDev/Ryujinx#requirements for more information)");
|
throw new InvalidSystemResourceException($"{titleName} ({fontTitle:x8}) system title not found! This font will not work, provide the system archive to fix this error. (See https://github.com/Ryubing/Ryujinx#requirements for more information)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -244,6 +244,15 @@ namespace Ryujinx.HLE.HOS.Services.Settings
|
|||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CommandCmif(68)]
|
||||||
|
// GetSerialNumber() -> buffer<nn::settings::system::SerialNumber, 0x16>
|
||||||
|
public ResultCode GetSerialNumber(ServiceCtx context)
|
||||||
|
{
|
||||||
|
context.ResponseData.Write(Encoding.ASCII.GetBytes("RYU00000000000"));
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
[CommandCmif(77)]
|
[CommandCmif(77)]
|
||||||
// GetDeviceNickName() -> buffer<nn::settings::system::DeviceNickName, 0x16>
|
// GetDeviceNickName() -> buffer<nn::settings::system::DeviceNickName, 0x16>
|
||||||
public ResultCode GetDeviceNickName(ServiceCtx context)
|
public ResultCode GetDeviceNickName(ServiceCtx context)
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ namespace Ryujinx.HLE.HOS.Services.Spl
|
|||||||
|
|
||||||
context.ResponseData.Write(configValue);
|
context.ResponseData.Write(configValue);
|
||||||
|
|
||||||
|
if (result == SmcResult.Success)
|
||||||
|
return ResultCode.Success;
|
||||||
|
|
||||||
return (ResultCode)((int)result << 9) | ResultCode.ModuleId;
|
return (ResultCode)((int)result << 9) | ResultCode.ModuleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,5 +161,20 @@ namespace Ryujinx.HLE
|
|||||||
{
|
{
|
||||||
return 1000 / _frameRate[FrameTypeGame];
|
return 1000 / _frameRate[FrameTypeGame];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string FormatGameFrameRate()
|
||||||
|
{
|
||||||
|
double frameRate = GetGameFrameRate();
|
||||||
|
double frameTime = GetGameFrameTime();
|
||||||
|
|
||||||
|
return $"{frameRate:00.00} FPS ({frameTime:00.00}ms)";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FormatFifoPercent()
|
||||||
|
{
|
||||||
|
double fifoPercent = GetFifoPercent();
|
||||||
|
|
||||||
|
return $"FIFO: {fifoPercent:00.00}%";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ namespace Ryujinx.HLE
|
|||||||
|
|
||||||
public int CpuCoresCount = 4; //Switch 1 has 4 cores
|
public int CpuCoresCount = 4; //Switch 1 has 4 cores
|
||||||
|
|
||||||
public VSyncMode VSyncMode { get; set; } = VSyncMode.Switch;
|
public VSyncMode VSyncMode { get; set; }
|
||||||
public bool CustomVSyncIntervalEnabled { get; set; } = false;
|
public bool CustomVSyncIntervalEnabled { get; set; }
|
||||||
public int CustomVSyncInterval { get; set; }
|
public int CustomVSyncInterval { get; set; }
|
||||||
|
|
||||||
public long TargetVSyncInterval { get; set; } = 60;
|
public long TargetVSyncInterval { get; set; } = 60;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using SDL2;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
@@ -118,6 +119,11 @@ namespace Ryujinx.Input.SDL2
|
|||||||
result |= GamepadFeaturesFlag.Rumble;
|
result |= GamepadFeaturesFlag.Rumble;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SDL_GameControllerHasLED(_gamepadHandle) == SDL_bool.SDL_TRUE)
|
||||||
|
{
|
||||||
|
result |= GamepadFeaturesFlag.Led;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,5 +24,10 @@ namespace Ryujinx.Input
|
|||||||
/// <remarks>Also named sixaxis</remarks>
|
/// <remarks>Also named sixaxis</remarks>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Motion,
|
Motion,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The LED on the back of modern PlayStation controllers (DualSense & DualShock 4).
|
||||||
|
/// </summary>
|
||||||
|
Led,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -674,7 +674,7 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
public async Task<bool> LoadGuestApplication(BlitStruct<ApplicationControlProperty>? customNacpData = null)
|
public async Task<bool> LoadGuestApplication(BlitStruct<ApplicationControlProperty>? customNacpData = null)
|
||||||
{
|
{
|
||||||
InitializeSwitchInstance();
|
InitEmulatedSwitch();
|
||||||
MainWindow.UpdateGraphicsConfig();
|
MainWindow.UpdateGraphicsConfig();
|
||||||
|
|
||||||
SystemVersion firmwareVersion = ContentManager.GetCurrentFirmwareVersion();
|
SystemVersion firmwareVersion = ContentManager.GetCurrentFirmwareVersion();
|
||||||
@@ -757,6 +757,8 @@ namespace Ryujinx.Ava
|
|||||||
{
|
{
|
||||||
romFsFiles = Directory.GetFiles(ApplicationPath, "*.romfs");
|
romFsFiles = Directory.GetFiles(ApplicationPath, "*.romfs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.Notice.Print(LogClass.Application, $"Loading unpacked content archive from '{ApplicationPath}'.");
|
||||||
|
|
||||||
if (romFsFiles.Length > 0)
|
if (romFsFiles.Length > 0)
|
||||||
{
|
{
|
||||||
@@ -783,6 +785,8 @@ namespace Ryujinx.Ava
|
|||||||
}
|
}
|
||||||
else if (File.Exists(ApplicationPath))
|
else if (File.Exists(ApplicationPath))
|
||||||
{
|
{
|
||||||
|
Logger.Notice.Print(LogClass.Application, $"Loading content archive from '{ApplicationPath}'.");
|
||||||
|
|
||||||
switch (Path.GetExtension(ApplicationPath).ToLowerInvariant())
|
switch (Path.GetExtension(ApplicationPath).ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case ".xci":
|
case ".xci":
|
||||||
@@ -885,7 +889,7 @@ namespace Ryujinx.Ava
|
|||||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused");
|
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeSwitchInstance()
|
private void InitEmulatedSwitch()
|
||||||
{
|
{
|
||||||
// Initialize KeySet.
|
// Initialize KeySet.
|
||||||
VirtualFileSystem.ReloadKeySet();
|
VirtualFileSystem.ReloadKeySet();
|
||||||
@@ -1040,7 +1044,7 @@ namespace Ryujinx.Ava
|
|||||||
_viewModel.WindowState = WindowState.FullScreen;
|
_viewModel.WindowState = WindowState.FullScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_viewModel.WindowState is WindowState.FullScreen)
|
if (_viewModel.WindowState is WindowState.FullScreen || _viewModel.StartGamesWithoutUI)
|
||||||
{
|
{
|
||||||
_viewModel.ShowMenuAndStatusBar = false;
|
_viewModel.ShowMenuAndStatusBar = false;
|
||||||
}
|
}
|
||||||
@@ -1147,8 +1151,8 @@ namespace Ryujinx.Ava
|
|||||||
LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%",
|
LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%",
|
||||||
dockedMode,
|
dockedMode,
|
||||||
ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(),
|
ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(),
|
||||||
$"{Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)",
|
Device.Statistics.FormatGameFrameRate(),
|
||||||
$"FIFO: {Device.Statistics.GetFifoPercent():00.00} %",
|
Device.Statistics.FormatFifoPercent(),
|
||||||
_displayCount));
|
_displayCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
src/Ryujinx/Assets/Styles/CheckboxMenuItemStyle.axaml
Normal file
13
src/Ryujinx/Assets/Styles/CheckboxMenuItemStyle.axaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<Styles xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Style Selector="MenuItem.withCheckbox Viewbox#PART_IconPresenter">
|
||||||
|
<Setter Property="MaxHeight" Value="36" />
|
||||||
|
<Setter Property="MinHeight" Value="36" />
|
||||||
|
<Setter Property="MaxWidth" Value="36" />
|
||||||
|
<Setter Property="MinWidth" Value="36" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="MenuItem.withCheckbox ContentPresenter#PART_HeaderPresenter">
|
||||||
|
<Setter Property="Padding" Value="-10,0,0,0" />
|
||||||
|
</Style>
|
||||||
|
</Styles>
|
||||||
|
|
||||||
@@ -393,7 +393,7 @@
|
|||||||
"th_TH": "โหลด DLC จากโฟลเดอร์",
|
"th_TH": "โหลด DLC จากโฟลเดอร์",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Завантажити DLC з теки",
|
"uk_UA": "Завантажити DLC з теки",
|
||||||
"zh_CN": "从文件夹加载DLC",
|
"zh_CN": "从文件夹加载 DLC",
|
||||||
"zh_TW": "從資料夾中載入 DLC"
|
"zh_TW": "從資料夾中載入 DLC"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -572,6 +572,31 @@
|
|||||||
"zh_TW": "使用全螢幕模式啟動遊戲"
|
"zh_TW": "使用全螢幕模式啟動遊戲"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "MenuBarOptionsStartGamesWithoutUI",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Start Games with UI Hidden",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarOptionsStopEmulation",
|
"ID": "MenuBarOptionsStopEmulation",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
@@ -743,37 +768,12 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Сканувати Amiibo (з теки Bin)",
|
"uk_UA": "Сканувати Amiibo (з теки Bin)",
|
||||||
"zh_CN": "从bin文件扫描 Amiibo",
|
"zh_CN": "扫描 Amiibo (从 bin 文件)",
|
||||||
"zh_TW": "掃瞄 Amiibo (從 Bin 檔案)"
|
"zh_TW": "掃瞄 Amiibo (從 Bin 檔案)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarTools",
|
"ID": "MenuBarActionsInstallFirmware",
|
||||||
"Translations": {
|
|
||||||
"ar_SA": "_الأدوات",
|
|
||||||
"de_DE": "",
|
|
||||||
"el_GR": "_Εργαλεία",
|
|
||||||
"en_US": "_Tools",
|
|
||||||
"es_ES": "_Herramientas",
|
|
||||||
"fr_FR": "_Outils",
|
|
||||||
"he_IL": "_כלים",
|
|
||||||
"it_IT": "_Strumenti",
|
|
||||||
"ja_JP": "ツール(_T)",
|
|
||||||
"ko_KR": "도구(_T)",
|
|
||||||
"no_NO": "_Verktøy",
|
|
||||||
"pl_PL": "_Narzędzia",
|
|
||||||
"pt_BR": "_Ferramentas",
|
|
||||||
"ru_RU": "_Инструменты",
|
|
||||||
"sv_SE": "V_erktyg",
|
|
||||||
"th_TH": "_เครื่องมือ",
|
|
||||||
"tr_TR": "_Araçlar",
|
|
||||||
"uk_UA": "_Інструменти",
|
|
||||||
"zh_CN": "工具(_T)",
|
|
||||||
"zh_TW": "工具(_T)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ID": "MenuBarToolsInstallFirmware",
|
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "تثبيت البرنامج الثابت",
|
"ar_SA": "تثبيت البرنامج الثابت",
|
||||||
"de_DE": "Firmware installieren",
|
"de_DE": "Firmware installieren",
|
||||||
@@ -798,7 +798,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarFileToolsInstallFirmwareFromFile",
|
"ID": "MenuBarActionsInstallFirmwareFromFile",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "تثبيت برنامج ثابت من XCI أو ZIP",
|
"ar_SA": "تثبيت برنامج ثابت من XCI أو ZIP",
|
||||||
"de_DE": "Firmware von einer XCI- oder einer ZIP-Datei installieren",
|
"de_DE": "Firmware von einer XCI- oder einer ZIP-Datei installieren",
|
||||||
@@ -818,12 +818,12 @@
|
|||||||
"th_TH": "ติดตั้งเฟิร์มแวร์จาก ไฟล์ XCI หรือ ไฟล์ ZIP",
|
"th_TH": "ติดตั้งเฟิร์มแวร์จาก ไฟล์ XCI หรือ ไฟล์ ZIP",
|
||||||
"tr_TR": "XCI veya ZIP'ten Yazılım Yükle",
|
"tr_TR": "XCI veya ZIP'ten Yazılım Yükle",
|
||||||
"uk_UA": "Встановити прошивку з XCI або ZIP",
|
"uk_UA": "Встановити прошивку з XCI або ZIP",
|
||||||
"zh_CN": "从 XCI 或 ZIP 文件中安装系统固件",
|
"zh_CN": "从 XCI 或 ZIP 文件安装系统固件",
|
||||||
"zh_TW": "從 XCI 或 ZIP 安裝韌體"
|
"zh_TW": "從 XCI 或 ZIP 安裝韌體"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarFileToolsInstallFirmwareFromDirectory",
|
"ID": "MenuBarActionsInstallFirmwareFromDirectory",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "تثبيت برنامج ثابت من مجلد",
|
"ar_SA": "تثبيت برنامج ثابت من مجلد",
|
||||||
"de_DE": "Firmware aus einem Verzeichnis installieren",
|
"de_DE": "Firmware aus einem Verzeichnis installieren",
|
||||||
@@ -843,12 +843,12 @@
|
|||||||
"th_TH": "ติดตั้งเฟิร์มแวร์จากไดเร็กทอรี",
|
"th_TH": "ติดตั้งเฟิร์มแวร์จากไดเร็กทอรี",
|
||||||
"tr_TR": "Bir Dizin Üzerinden Yazılım Yükle",
|
"tr_TR": "Bir Dizin Üzerinden Yazılım Yükle",
|
||||||
"uk_UA": "Встановити прошивку з теки",
|
"uk_UA": "Встановити прошивку з теки",
|
||||||
"zh_CN": "从文件夹中安装系统固件",
|
"zh_CN": "从文件夹安装系统固件",
|
||||||
"zh_TW": "從資料夾安裝韌體"
|
"zh_TW": "從資料夾安裝韌體"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarToolsInstallKeys",
|
"ID": "MenuBarActionsInstallKeys",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "",
|
"ar_SA": "",
|
||||||
"de_DE": "",
|
"de_DE": "",
|
||||||
@@ -873,7 +873,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarFileToolsInstallKeysFromFile",
|
"ID": "MenuBarFileActionsInstallKeysFromFile",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "",
|
"ar_SA": "",
|
||||||
"de_DE": "",
|
"de_DE": "",
|
||||||
@@ -893,12 +893,12 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Встановити ключі з файлу .KEYS або .ZIP",
|
"uk_UA": "Встановити ключі з файлу .KEYS або .ZIP",
|
||||||
"zh_CN": "从.KEYS文件或ZIP压缩包安装密匙",
|
"zh_CN": "从 .KEYS 文件或 .ZIP 压缩包安装密匙",
|
||||||
"zh_TW": "從 .KEYS 或 .ZIP 安裝金鑰"
|
"zh_TW": "從 .KEYS 或 .ZIP 安裝金鑰"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarFileToolsInstallKeysFromFolder",
|
"ID": "MenuBarFileActionsInstallKeysFromFolder",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "",
|
"ar_SA": "",
|
||||||
"de_DE": "",
|
"de_DE": "",
|
||||||
@@ -923,7 +923,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarToolsManageFileTypes",
|
"ID": "MenuBarActionsManageFileTypes",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "إدارة أنواع الملفات",
|
"ar_SA": "إدارة أنواع الملفات",
|
||||||
"de_DE": "Dateitypen verwalten",
|
"de_DE": "Dateitypen verwalten",
|
||||||
@@ -948,7 +948,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarToolsInstallFileTypes",
|
"ID": "MenuBarActionsInstallFileTypes",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "تثبيت أنواع الملفات",
|
"ar_SA": "تثبيت أنواع الملفات",
|
||||||
"de_DE": "Dateitypen installieren",
|
"de_DE": "Dateitypen installieren",
|
||||||
@@ -973,7 +973,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarToolsUninstallFileTypes",
|
"ID": "MenuBarActionsUninstallFileTypes",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "إزالة أنواع الملفات",
|
"ar_SA": "إزالة أنواع الملفات",
|
||||||
"de_DE": "Dateitypen deinstallieren",
|
"de_DE": "Dateitypen deinstallieren",
|
||||||
@@ -998,7 +998,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarToolsXCITrimmer",
|
"ID": "MenuBarActionsXCITrimmer",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "",
|
"ar_SA": "",
|
||||||
"de_DE": "",
|
"de_DE": "",
|
||||||
@@ -1018,7 +1018,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізати XCI файли",
|
"uk_UA": "Обрізати XCI файли",
|
||||||
"zh_CN": "XCI文件瘦身",
|
"zh_CN": "瘦身 XCI 文件",
|
||||||
"zh_TW": "修剪 XCI 檔案"
|
"zh_TW": "修剪 XCI 檔案"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1293,7 +1293,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Відкриває сторінку з Посібником по усуненню помилок та несправностей на офіційній вікі-сторінці Ryujinx (англійською)",
|
"uk_UA": "Відкриває сторінку з Посібником по усуненню помилок та несправностей на офіційній вікі-сторінці Ryujinx (англійською)",
|
||||||
"zh_CN": "打开Ryujinx官方wiki的常见问题和问题排除页面",
|
"zh_CN": "打开 Ryujinx 官方 Wiki 的常见问题和问题排除页面",
|
||||||
"zh_TW": "開啟官方 Ryujinx Wiki 常見問題 (FAQ) 和疑難排解頁面"
|
"zh_TW": "開啟官方 Ryujinx Wiki 常見問題 (FAQ) 和疑難排解頁面"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1343,7 +1343,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Відкриває посібник з Налаштування та конфігурації на офіційній вікі-сторінці Ryujinx (англійською)",
|
"uk_UA": "Відкриває посібник з Налаштування та конфігурації на офіційній вікі-сторінці Ryujinx (англійською)",
|
||||||
"zh_CN": "打开Ryujinx官方wiki的安装与配置指南",
|
"zh_CN": "打开 Ryujinx 官方 Wiki 的安装与配置指南",
|
||||||
"zh_TW": "開啟官方 Ryujinx Wiki 設定和配置指南"
|
"zh_TW": "開啟官方 Ryujinx Wiki 設定和配置指南"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1393,7 +1393,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Відкриває посібник з налаштування Мультиплеєру на офіційній вікі-сторінці Ryujinx (англійською)",
|
"uk_UA": "Відкриває посібник з налаштування Мультиплеєру на офіційній вікі-сторінці Ryujinx (англійською)",
|
||||||
"zh_CN": "打开Ryujinx官方wiki的多人游戏指南",
|
"zh_CN": "打开 Ryujinx 官方 Wiki 的多人游戏指南",
|
||||||
"zh_TW": "開啟官方 Ryujinx Wiki 多人遊戲 (LDN/LAN) 指南"
|
"zh_TW": "開啟官方 Ryujinx Wiki 多人遊戲 (LDN/LAN) 指南"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1443,7 +1443,7 @@
|
|||||||
"th_TH": "กำลังค้นหา...",
|
"th_TH": "กำลังค้นหา...",
|
||||||
"tr_TR": "Ara...",
|
"tr_TR": "Ara...",
|
||||||
"uk_UA": "Пошук...",
|
"uk_UA": "Пошук...",
|
||||||
"zh_CN": "搜索…",
|
"zh_CN": "搜索...",
|
||||||
"zh_TW": "搜尋..."
|
"zh_TW": "搜尋..."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2297,6 +2297,56 @@
|
|||||||
"zh_TW": "從應用程式的目前配置中提取 RomFS 分區 (包含更新)"
|
"zh_TW": "從應用程式的目前配置中提取 RomFS 分區 (包含更新)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListContextMenuExtractDataAocRomFS",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "DLC RomFS",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "RomFS de DLC",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListContextMenuExtractDataAocRomFSToolTip",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Extract the RomFS from a selected DLC file",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "Extraire les RomFS d'un fichier DLC choisi",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "Pakk ut RomFS filene fra valgt DLC fil",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "GameListContextMenuExtractDataLogo",
|
"ID": "GameListContextMenuExtractDataLogo",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
@@ -2543,7 +2593,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перевірка та нарізка XCI Файлу",
|
"uk_UA": "Перевірка та нарізка XCI Файлу",
|
||||||
"zh_CN": "检查并瘦身XCI文件",
|
"zh_CN": "检查并瘦身 XCI 文件",
|
||||||
"zh_TW": "檢查及修剪 XCI 檔案"
|
"zh_TW": "檢查及修剪 XCI 檔案"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2568,7 +2618,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перевірити та обрізати XCI Файл задля збереження місця на диску",
|
"uk_UA": "Перевірити та обрізати XCI Файл задля збереження місця на диску",
|
||||||
"zh_CN": "检查并瘦身XCI文件以节约磁盘空间",
|
"zh_CN": "检查并瘦身 XCI 文件以节约磁盘空间",
|
||||||
"zh_TW": "檢查及修剪 XCI 檔案以節省儲存空間"
|
"zh_TW": "檢查及修剪 XCI 檔案以節省儲存空間"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2643,7 +2693,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізається XCI Файлів '{0}'",
|
"uk_UA": "Обрізається XCI Файлів '{0}'",
|
||||||
"zh_CN": "XCI文件瘦身中'{0}'",
|
"zh_CN": "正在瘦身 XCI 文件 '{0}'",
|
||||||
"zh_TW": "正在修剪 XCI 檔案 '{0}'"
|
"zh_TW": "正在修剪 XCI 檔案 '{0}'"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3168,7 +3218,7 @@
|
|||||||
"th_TH": "โหลดไดเรกทอรี DLC/ไฟล์อัปเดต อัตโนมัติ",
|
"th_TH": "โหลดไดเรกทอรี DLC/ไฟล์อัปเดต อัตโนมัติ",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Автозавантаження теки DLC/Оновлень",
|
"uk_UA": "Автозавантаження теки DLC/Оновлень",
|
||||||
"zh_CN": "自动加载DLC/游戏更新目录",
|
"zh_CN": "自动加载 DLC 及 游戏更新 的目录",
|
||||||
"zh_TW": "自動載入 DLC/遊戲更新資料夾"
|
"zh_TW": "自動載入 DLC/遊戲更新資料夾"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3193,7 +3243,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "DLC та Оновлення, які посилаються на відсутні файли, будуть автоматично вимкнуті.",
|
"uk_UA": "DLC та Оновлення, які посилаються на відсутні файли, будуть автоматично вимкнуті.",
|
||||||
"zh_CN": "DLC/游戏更新可自动加载和卸载",
|
"zh_CN": "DLC 及 游戏更新 可自动加载和卸载",
|
||||||
"zh_TW": "遺失的 DLC 及遊戲更新檔案將會在自動載入中移除"
|
"zh_TW": "遺失的 DLC 及遊戲更新檔案將會在自動載入中移除"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -7572,6 +7622,31 @@
|
|||||||
"zh_TW": "陀螺儀無感帶:"
|
"zh_TW": "陀螺儀無感帶:"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "ControllerSettingsLedColor",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Custom LED",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "ControllerSettingsSave",
|
"ID": "ControllerSettingsSave",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
@@ -11218,7 +11293,7 @@
|
|||||||
"th_TH": "ไม่มีข้อมูลบันทึกไว้สำหรับ {0} [{1:x16}]",
|
"th_TH": "ไม่มีข้อมูลบันทึกไว้สำหรับ {0} [{1:x16}]",
|
||||||
"tr_TR": "{0} [{1:x16}] için kayıt verisi bulunamadı",
|
"tr_TR": "{0} [{1:x16}] için kayıt verisi bulunamadı",
|
||||||
"uk_UA": "Немає збережених даних для {0} [{1:x16}]",
|
"uk_UA": "Немає збережених даних для {0} [{1:x16}]",
|
||||||
"zh_CN": "没有{0} [{1:x16}]的游戏存档",
|
"zh_CN": "没有 {0} [{1:x16}] 的游戏存档",
|
||||||
"zh_TW": "沒有 {0} [{1:x16}] 的存檔"
|
"zh_TW": "沒有 {0} [{1:x16}] 的存檔"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -12368,7 +12443,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вікно XCI Тримера",
|
"uk_UA": "Вікно XCI Тримера",
|
||||||
"zh_CN": "XCI文件瘦身窗口",
|
"zh_CN": "XCI 文件瘦身窗口",
|
||||||
"zh_TW": "XCI 修剪器視窗"
|
"zh_TW": "XCI 修剪器視窗"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -13093,7 +13168,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "在{0}发现了一个无效的密匙文件",
|
"zh_CN": "在 {0} 发现了一个无效的密匙文件",
|
||||||
"zh_TW": "找到無效的金鑰檔案 {0}"
|
"zh_TW": "找到無效的金鑰檔案 {0}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -14443,7 +14518,7 @@
|
|||||||
"th_TH": "แฮ็ค: สุ่มแท็ก Uuid",
|
"th_TH": "แฮ็ค: สุ่มแท็ก Uuid",
|
||||||
"tr_TR": "Hack: Rastgele bir Uuid kullan",
|
"tr_TR": "Hack: Rastgele bir Uuid kullan",
|
||||||
"uk_UA": "Хитрість: Використовувати випадковий тег Uuid",
|
"uk_UA": "Хитрість: Використовувати випадковий тег Uuid",
|
||||||
"zh_CN": "修改:使用随机生成的Amiibo ID",
|
"zh_CN": "修改:使用随机生成的 Amiibo ID",
|
||||||
"zh_TW": "補釘修正:使用隨機標記的 Uuid"
|
"zh_TW": "補釘修正:使用隨機標記的 Uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -15393,7 +15468,7 @@
|
|||||||
"th_TH": "โหลด PPTC โดยใช้หนึ่งในสามของจำนวนคอร์",
|
"th_TH": "โหลด PPTC โดยใช้หนึ่งในสามของจำนวนคอร์",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Завантажувати PPTC використовуючи третину від кількості ядер.",
|
"uk_UA": "Завантажувати PPTC використовуючи третину від кількості ядер.",
|
||||||
"zh_CN": "使用三分之一的核心数加载PPTC.",
|
"zh_CN": "使用三分之一的核心数加载 PPTC.",
|
||||||
"zh_TW": "使用 CPU 核心數量的三分之一載入 PPTC。"
|
"zh_TW": "使用 CPU 核心數量的三分之一載入 PPTC。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16218,7 +16293,7 @@
|
|||||||
"th_TH": "เปิดตัวสำรวจไฟล์เพื่อเลือกหนึ่งโฟลเดอร์ขึ้นไปเพื่อโหลด DLC จำนวนมาก",
|
"th_TH": "เปิดตัวสำรวจไฟล์เพื่อเลือกหนึ่งโฟลเดอร์ขึ้นไปเพื่อโหลด DLC จำนวนมาก",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Відкриває Файловий провідник для обрання однієї або декількох тек для масового завантаження DLC",
|
"uk_UA": "Відкриває Файловий провідник для обрання однієї або декількох тек для масового завантаження DLC",
|
||||||
"zh_CN": "打开文件资源管理器以选择一个或多个文件夹来批量加载DLC。",
|
"zh_CN": "打开文件资源管理器以选择一个或多个文件夹来批量加载 DLC。",
|
||||||
"zh_TW": "開啟檔案總管,選擇一個或多個資料夾來大量載入 DLC"
|
"zh_TW": "開啟檔案總管,選擇一個或多個資料夾來大量載入 DLC"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19043,7 +19118,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перевірити та Обрізати XCI файл",
|
"uk_UA": "Перевірити та Обрізати XCI файл",
|
||||||
"zh_CN": "检查并瘦身XCI文件",
|
"zh_CN": "检查并瘦身 XCI 文件",
|
||||||
"zh_TW": "檢查及修剪 XCI 檔案"
|
"zh_TW": "檢查及修剪 XCI 檔案"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19068,7 +19143,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Ця функція спочатку перевірить наявність порожнього місця, після чого обріже файл XCI для економії місця на диску.",
|
"uk_UA": "Ця функція спочатку перевірить наявність порожнього місця, після чого обріже файл XCI для економії місця на диску.",
|
||||||
"zh_CN": "这个功能将会先检查XCI文件,再对其执行瘦身操作以节约磁盘空间。",
|
"zh_CN": "这个功能将会先检查 XCI 文件,再对其执行瘦身操作以节约磁盘空间。",
|
||||||
"zh_TW": "此功能首先檢查 XCI 檔案是否有可修剪的字元,然後修剪檔案以節省儲存空間。"
|
"zh_TW": "此功能首先檢查 XCI 檔案是否有可修剪的字元,然後修剪檔案以節省儲存空間。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19118,7 +19193,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI файл не потребує обрізання. Перевірте журнали (logs) для отримання додаткової інформації",
|
"uk_UA": "XCI файл не потребує обрізання. Перевірте журнали (logs) для отримання додаткової інформації",
|
||||||
"zh_CN": "XCI文件不需要被瘦身。查看日志以获得更多细节。",
|
"zh_CN": "XCI 文件不需要被瘦身。查看日志以获得更多细节。",
|
||||||
"zh_TW": "XCI 檔案不需要修剪。檢查日誌以取得更多資訊"
|
"zh_TW": "XCI 檔案不需要修剪。檢查日誌以取得更多資訊"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19143,7 +19218,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI файл не може бути обрізаний. Перевірте журнали (logs) для отримання додаткової інформації",
|
"uk_UA": "XCI файл не може бути обрізаний. Перевірте журнали (logs) для отримання додаткової інформації",
|
||||||
"zh_CN": "XCI文件不能被瘦身。查看日志以获得更多细节。",
|
"zh_CN": "XCI 文件不能被瘦身。查看日志以获得更多细节。",
|
||||||
"zh_TW": "XCI 檔案不能被修剪。檢查日誌以取得更多資訊"
|
"zh_TW": "XCI 檔案不能被修剪。檢查日誌以取得更多資訊"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19168,7 +19243,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали (logs) для отримання додаткової інформації",
|
"uk_UA": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали (logs) для отримання додаткової інформації",
|
||||||
"zh_CN": "XCI文件是只读的,且不可以被标记为可读取的。查看日志以获得更多细节。",
|
"zh_CN": "XCI 文件是只读的,且不可以被标记为可读取的。查看日志以获得更多细节。",
|
||||||
"zh_TW": "XCI 檔案是唯讀,並且無法改成可寫入。檢查日誌以取得更多資訊"
|
"zh_TW": "XCI 檔案是唯讀,並且無法改成可寫入。檢查日誌以取得更多資訊"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19193,7 +19268,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Розмір файлу XCI змінився з моменту сканування. Перевірте, чи не записується файл, та спробуйте знову",
|
"uk_UA": "Розмір файлу XCI змінився з моменту сканування. Перевірте, чи не записується файл, та спробуйте знову",
|
||||||
"zh_CN": "XCI文件在扫描后大小发生了变化。请检查文件是否未被写入,然后重试。",
|
"zh_CN": "XCI 文件在扫描后大小发生了变化。请检查文件是否未被写入,然后重试。",
|
||||||
"zh_TW": "XCI 檔案大小比較上次的掃瞄已經改變。請檢查檔案是否未被寫入,然後再嘗試。"
|
"zh_TW": "XCI 檔案大小比較上次的掃瞄已經改變。請檢查檔案是否未被寫入,然後再嘗試。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19218,7 +19293,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Файл XCI містить дані в зоні вільного простору, тому обрізка небезпечна",
|
"uk_UA": "Файл XCI містить дані в зоні вільного простору, тому обрізка небезпечна",
|
||||||
"zh_CN": "XCI文件的空闲区域内有数据,不能安全瘦身。",
|
"zh_CN": "XCI 文件的空闲区域内有数据,不能安全瘦身。",
|
||||||
"zh_TW": "XCI 檔案有數據儲存於可節省儲存空間的區域,所以試圖修剪並不安全"
|
"zh_TW": "XCI 檔案有數據儲存於可節省儲存空間的區域,所以試圖修剪並不安全"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19243,7 +19318,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI Файл містить недійсні дані. Перевірте журнали (logs) для отримання додаткової інформації",
|
"uk_UA": "XCI Файл містить недійсні дані. Перевірте журнали (logs) для отримання додаткової інформації",
|
||||||
"zh_CN": "XCI文件含有无效数据。查看日志以获得更多细节。",
|
"zh_CN": "XCI 文件含有无效数据。查看日志以获得更多细节。",
|
||||||
"zh_TW": "XCI 檔案帶有無效的數據。檢查日誌以取得更多資訊"
|
"zh_TW": "XCI 檔案帶有無效的數據。檢查日誌以取得更多資訊"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19268,7 +19343,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI Файл файл не вдалося відкрити для запису. Перевірте журнали для додаткової інформації",
|
"uk_UA": "XCI Файл файл не вдалося відкрити для запису. Перевірте журнали для додаткової інформації",
|
||||||
"zh_CN": "XCI文件不能被读写。查看日志以获得更多细节。",
|
"zh_CN": "XCI 文件不能被读写。查看日志以获得更多细节。",
|
||||||
"zh_TW": "XCI 檔案不能被寫入。檢查日誌以取得更多資訊"
|
"zh_TW": "XCI 檔案不能被寫入。檢查日誌以取得更多資訊"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19293,7 +19368,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Не вдалося обрізати файл XCI",
|
"uk_UA": "Не вдалося обрізати файл XCI",
|
||||||
"zh_CN": "XCI文件瘦身失败",
|
"zh_CN": "XCI 文件瘦身失败",
|
||||||
"zh_TW": "修剪 XCI 檔案失敗"
|
"zh_TW": "修剪 XCI 檔案失敗"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19493,7 +19568,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізка XCI Файлів",
|
"uk_UA": "Обрізка XCI Файлів",
|
||||||
"zh_CN": "XCI文件瘦身器",
|
"zh_CN": "XCI 文件瘦身器",
|
||||||
"zh_TW": "XCI 檔案修剪器"
|
"zh_TW": "XCI 檔案修剪器"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19968,7 +20043,7 @@
|
|||||||
"th_TH": "แพ็ค DLC ไม่สามารถลบทิ้งได้ สามารถปิดใช้งานได้เท่านั้น",
|
"th_TH": "แพ็ค DLC ไม่สามารถลบทิ้งได้ สามารถปิดใช้งานได้เท่านั้น",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Комплектні DLC (бандли) не можуть бути видаленими, лише вимкненими.",
|
"uk_UA": "Комплектні DLC (бандли) не можуть бути видаленими, лише вимкненими.",
|
||||||
"zh_CN": "游戏整合的DLC无法移除,可尝试禁用。",
|
"zh_CN": "游戏整合的 DLC 无法移除,可尝试禁用。",
|
||||||
"zh_TW": "附帶的 DLC 只能被停用而無法被刪除。"
|
"zh_TW": "附帶的 DLC 只能被停用而無法被刪除。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -20018,7 +20093,7 @@
|
|||||||
"th_TH": "{0} DLC ใหม่ที่เพิ่มเข้ามา",
|
"th_TH": "{0} DLC ใหม่ที่เพิ่มเข้ามา",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "{0} нового завантажувального вмісту додано",
|
"uk_UA": "{0} нового завантажувального вмісту додано",
|
||||||
"zh_CN": "{0} 个DLC被添加",
|
"zh_CN": "{0} 个 DLC 被添加",
|
||||||
"zh_TW": "已加入 {0} 個 DLC"
|
"zh_TW": "已加入 {0} 個 DLC"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -20043,7 +20118,7 @@
|
|||||||
"th_TH": "{0} ใหม่ที่เพิ่มเข้ามา",
|
"th_TH": "{0} ใหม่ที่เพิ่มเข้ามา",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "{0} нового завантажувального вмісту додано",
|
"uk_UA": "{0} нового завантажувального вмісту додано",
|
||||||
"zh_CN": "{0} 个DLC被添加",
|
"zh_CN": "{0} 个 DLC 被添加",
|
||||||
"zh_TW": "已加入 {0} 個 DLC"
|
"zh_TW": "已加入 {0} 個 DLC"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -20068,7 +20143,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "{0} відсутнього завантажувального вмісту видалено",
|
"uk_UA": "{0} відсутнього завантажувального вмісту видалено",
|
||||||
"zh_CN": "{0} 个失效的DLC已移除",
|
"zh_CN": "{0} 个失效的 DLC 已移除",
|
||||||
"zh_TW": "已刪除 {0} 個遺失的 DLC"
|
"zh_TW": "已刪除 {0} 個遺失的 DLC"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -20593,7 +20668,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "使用Vulkan。\n在ARM Mac上,当玩在其下运行良好的游戏时,使用Metal后端。",
|
"zh_CN": "使用 Vulkan。\n在 ARM Mac 上,当玩在其下运行良好的游戏时,使用 Metal 后端。",
|
||||||
"zh_TW": "使用Vulkan。\n在 ARM Mac 上,如果遊戲執行性能良好時,則將使用 Metal 後端。"
|
"zh_TW": "使用Vulkan。\n在 ARM Mac 上,如果遊戲執行性能良好時,則將使用 Metal 後端。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21993,7 +22068,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вимкнути хостинг P2P мережі (може збільшити затримку)",
|
"uk_UA": "Вимкнути хостинг P2P мережі (може збільшити затримку)",
|
||||||
"zh_CN": "禁用P2P网络连接 (也许会增加延迟)",
|
"zh_CN": "禁用 P2P 网络连接 (也许会增加延迟)",
|
||||||
"zh_TW": "停用對等網路代管 (P2P Network Hosting) (可能增加網路延遲)"
|
"zh_TW": "停用對等網路代管 (P2P Network Hosting) (可能增加網路延遲)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22018,7 +22093,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вимкнути хостинг P2P мережі, піри будуть підключатися через майстер-сервер замість прямого з'єднання з вами.",
|
"uk_UA": "Вимкнути хостинг P2P мережі, піри будуть підключатися через майстер-сервер замість прямого з'єднання з вами.",
|
||||||
"zh_CN": "禁用P2P网络连接,对方将通过主服务器进行连接,而不是直接连接到您。",
|
"zh_CN": "禁用 P2P 网络连接,对方将通过主服务器进行连接,而不是直接连接到您。",
|
||||||
"zh_TW": "停用對等網路代管 (P2P Network Hosting), 用戶群會經過代理何服器而非直接連線至你的主機。"
|
"zh_TW": "停用對等網路代管 (P2P Network Hosting), 用戶群會經過代理何服器而非直接連線至你的主機。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22093,7 +22168,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Введіть пароль у форматі Ryujinx-<8 символів>. Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
"uk_UA": "Введіть пароль у форматі Ryujinx-<8 символів>. Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
||||||
"zh_CN": "以Ryujinx-<8个十六进制字符>的格式输入密码。您只能看到与您使用相同密码的游戏房间。",
|
"zh_CN": "以 Ryujinx-<8个十六进制字符> 的格式输入密码。您只能看到与您使用相同密码的游戏房间。",
|
||||||
"zh_TW": "以「Ryujinx-<8 個十六進制數字>」的格式輸入密碼片語 (passphrase)。你只會看到與你的密碼片語 (passphrase) 相同的遊戲房間。"
|
"zh_TW": "以「Ryujinx-<8 個十六進制數字>」的格式輸入密碼片語 (passphrase)。你只會看到與你的密碼片語 (passphrase) 相同的遊戲房間。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22393,7 +22468,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Емульована вертикальна синхронізація кадрів. 'Switch' емулює частоту оновлення консолі Nintendo Switch (60 Гц). 'Необмежена' — частота оновлення не матиме обмежень.",
|
"uk_UA": "Емульована вертикальна синхронізація кадрів. 'Switch' емулює частоту оновлення консолі Nintendo Switch (60 Гц). 'Необмежена' — частота оновлення не матиме обмежень.",
|
||||||
"zh_CN": "模拟垂直同步。“Switch”模拟了Switch的60Hz刷新率。“无限制”没有刷新率限制。",
|
"zh_CN": "模拟垂直同步。“Switch”模拟了 Switch 的 60Hz 刷新率。“无限制”没有刷新率限制。",
|
||||||
"zh_TW": "模擬垂直同步。「Switch」 模擬 Nintendo Switch 的 60Hz 重新整理頻率。「沒有限制」是沒有限制的重新整理頻率。"
|
"zh_TW": "模擬垂直同步。「Switch」 模擬 Nintendo Switch 的 60Hz 重新整理頻率。「沒有限制」是沒有限制的重新整理頻率。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22418,7 +22493,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Емульована вертикальна синхронізація кадрів. 'Switch' емулює частоту оновлення консолі Nintendo Switch (60 Гц). 'Необмежена' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.",
|
"uk_UA": "Емульована вертикальна синхронізація кадрів. 'Switch' емулює частоту оновлення консолі Nintendo Switch (60 Гц). 'Необмежена' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.",
|
||||||
"zh_CN": "模拟垂直同步。“Switch”模拟了Switch的60Hz刷新率。“无限制”没有刷新率限制。“自定义刷新率”模拟指定的自定义刷新率。",
|
"zh_CN": "模拟垂直同步。“Switch”模拟了 Switch 的 60Hz 刷新率。“无限制”没有刷新率限制。“自定义刷新率”模拟指定的自定义刷新率。",
|
||||||
"zh_TW": "模擬垂直同步。「Switch」 模擬 Nintendo Switch 的 60Hz 重新整理頻率。「沒有限制」是沒有限制的重新整理頻率。「自訂的重新整理頻率」模擬所自訂的重新整理頻率。"
|
"zh_TW": "模擬垂直同步。「Switch」 模擬 Nintendo Switch 的 60Hz 重新整理頻率。「沒有限制」是沒有限制的重新整理頻率。「自訂的重新整理頻率」模擬所自訂的重新整理頻率。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22443,7 +22518,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. Натомість в інших іграх ця функція може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як вона вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.",
|
"uk_UA": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. Натомість в інших іграх ця функція може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як вона вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.",
|
||||||
"zh_CN": "允许用户指定模拟刷新率。在某些游戏中,这可能会加快或减慢游戏逻辑的速度。在其他游戏中,它可能允许将FPS限制在刷新率的某个倍数,或者导致不可预测的行为。这是一个实验性功能,无法保证游戏会受到怎样的影响。\n\n如果不确定,请关闭。",
|
"zh_CN": "允许用户指定模拟刷新率。在某些游戏中,这可能会加快或减慢游戏逻辑的速度。在其他游戏中,它可能允许将 FPS 限制在刷新率的某个倍数,或者导致不可预测的行为。这是一个实验性功能,无法保证游戏会受到怎样的影响。\n\n如果不确定,请关闭。",
|
||||||
"zh_TW": "容許使用者自訂模擬的重新整理頻率。你可能會在某些遊戲裡感受到加快或減慢的遊戲速度;其他遊戲裡則可能會容許限制最高的 FPS 至重新整理頻率的倍數,或引起未知遊戲行為。這是實驗性功能,且沒有保證遊戲會穩定執行。\n\n如果不確定,請保持關閉狀態。"
|
"zh_TW": "容許使用者自訂模擬的重新整理頻率。你可能會在某些遊戲裡感受到加快或減慢的遊戲速度;其他遊戲裡則可能會容許限制最高的 FPS 至重新整理頻率的倍數,或引起未知遊戲行為。這是實驗性功能,且沒有保證遊戲會穩定執行。\n\n如果不確定,請保持關閉狀態。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22896,6 +22971,31 @@
|
|||||||
"zh_CN": "什么都没有",
|
"zh_CN": "什么都没有",
|
||||||
"zh_TW": "無法啟動 (Nothing)"
|
"zh_TW": "無法啟動 (Nothing)"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "ExtractAocListHeader",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Select a DLC to Extract",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "Choisissez un DLC à extraire",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "Velg en DLC og hente ut",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using Avalonia.Controls.Notifications;
|
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using Gommon;
|
||||||
using LibHac;
|
using LibHac;
|
||||||
using LibHac.Account;
|
using LibHac.Account;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
@@ -15,6 +15,7 @@ using LibHac.Tools.FsSystem.NcaUtils;
|
|||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Controls;
|
using Ryujinx.Ava.UI.Controls;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
@@ -295,22 +296,150 @@ namespace Ryujinx.Ava.Common
|
|||||||
};
|
};
|
||||||
extractorThread.Start();
|
extractorThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ExtractAoc(string destination, string updateFilePath, string updateName)
|
||||||
|
{
|
||||||
|
var cancellationToken = new CancellationTokenSource();
|
||||||
|
|
||||||
|
UpdateWaitWindow waitingDialog = new(
|
||||||
|
RyujinxApp.FormatTitle(LocaleKeys.DialogNcaExtractionTitle),
|
||||||
|
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogNcaExtractionMessage, NcaSectionType.Data, Path.GetFileName(updateFilePath)),
|
||||||
|
cancellationToken);
|
||||||
|
|
||||||
|
Thread extractorThread = new(() =>
|
||||||
|
{
|
||||||
|
Dispatcher.UIThread.Post(waitingDialog.Show);
|
||||||
|
|
||||||
|
using FileStream file = new(updateFilePath, FileMode.Open, FileAccess.Read);
|
||||||
|
|
||||||
|
Nca publicDataNca = null;
|
||||||
|
|
||||||
|
string extension = Path.GetExtension(updateFilePath).ToLower();
|
||||||
|
if (extension is ".nsp")
|
||||||
|
{
|
||||||
|
var pfsTemp = new PartitionFileSystem();
|
||||||
|
pfsTemp.Initialize(file.AsStorage()).ThrowIfFailure();
|
||||||
|
IFileSystem pfs = pfsTemp;
|
||||||
|
|
||||||
|
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
|
||||||
|
{
|
||||||
|
using var ncaFile = new UniqueRef<IFile>();
|
||||||
|
|
||||||
|
pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||||
|
|
||||||
|
Nca nca = new(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage());
|
||||||
|
if (nca.Header.ContentType is NcaContentType.PublicData && nca.SectionExists(NcaSectionType.Data))
|
||||||
|
{
|
||||||
|
publicDataNca = nca;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (publicDataNca is null)
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, "Extraction failure. The NCA was not present in the selected file");
|
||||||
|
|
||||||
|
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||||
|
{
|
||||||
|
waitingDialog.Close();
|
||||||
|
|
||||||
|
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogNcaExtractionMainNcaNotFoundErrorMessage]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
|
||||||
|
? IntegrityCheckLevel.ErrorOnInvalid
|
||||||
|
: IntegrityCheckLevel.None;
|
||||||
|
|
||||||
|
int index = Nca.GetSectionIndexFromType(NcaSectionType.Data, publicDataNca.Header.ContentType);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IFileSystem ncaFileSystem = publicDataNca.OpenFileSystem(index, IntegrityCheckLevel.ErrorOnInvalid);
|
||||||
|
|
||||||
|
FileSystemClient fsClient = _horizonClient.Fs;
|
||||||
|
|
||||||
|
string source = DateTime.Now.ToFileTime().ToString()[10..];
|
||||||
|
string output = DateTime.Now.ToFileTime().ToString()[10..];
|
||||||
|
|
||||||
|
using var uniqueSourceFs = new UniqueRef<IFileSystem>(ncaFileSystem);
|
||||||
|
using var uniqueOutputFs = new UniqueRef<IFileSystem>(new LocalFileSystem(destination));
|
||||||
|
|
||||||
|
fsClient.Register(source.ToU8Span(), ref uniqueSourceFs.Ref);
|
||||||
|
fsClient.Register(output.ToU8Span(), ref uniqueOutputFs.Ref);
|
||||||
|
|
||||||
|
(Result? resultCode, bool canceled) = CopyDirectory(fsClient, $"{source}:/", $"{output}:/", cancellationToken.Token);
|
||||||
|
|
||||||
|
if (!canceled)
|
||||||
|
{
|
||||||
|
if (resultCode.Value.IsFailure())
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, $"LibHac returned error code: {resultCode.Value.ErrorCode}");
|
||||||
|
|
||||||
|
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||||
|
{
|
||||||
|
waitingDialog.Close();
|
||||||
|
|
||||||
|
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogNcaExtractionCheckLogErrorMessage]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (resultCode.Value.IsSuccess())
|
||||||
|
{
|
||||||
|
Dispatcher.UIThread.Post(waitingDialog.Close);
|
||||||
|
|
||||||
|
NotificationHelper.ShowInformation(
|
||||||
|
RyujinxApp.FormatTitle(LocaleKeys.DialogNcaExtractionTitle),
|
||||||
|
$"{updateName}\n\n{LocaleManager.Instance[LocaleKeys.DialogNcaExtractionSuccessMessage]}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fsClient.Unmount(source.ToU8Span());
|
||||||
|
fsClient.Unmount(output.ToU8Span());
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, $"{ex.Message}");
|
||||||
|
|
||||||
|
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||||
|
{
|
||||||
|
waitingDialog.Close();
|
||||||
|
|
||||||
|
await ContentDialogHelper.CreateErrorDialog(ex.Message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
{
|
||||||
|
Name = "GUI.AocExtractorThread",
|
||||||
|
IsBackground = true,
|
||||||
|
};
|
||||||
|
extractorThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task ExtractAoc(IStorageProvider storageProvider, string updateFilePath, string updateName)
|
||||||
|
{
|
||||||
|
Optional<IStorageFolder> result = await storageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
|
||||||
|
{
|
||||||
|
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.HasValue) return;
|
||||||
|
|
||||||
|
ExtractAoc(result.Value.Path.LocalPath, updateFilePath, updateName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static async Task ExtractSection(IStorageProvider storageProvider, NcaSectionType ncaSectionType, string titleFilePath, string titleName, int programIndex = 0)
|
public static async Task ExtractSection(IStorageProvider storageProvider, NcaSectionType ncaSectionType, string titleFilePath, string titleName, int programIndex = 0)
|
||||||
{
|
{
|
||||||
var result = await storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
Optional<IStorageFolder> result = await storageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
|
||||||
{
|
{
|
||||||
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle],
|
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle]
|
||||||
AllowMultiple = false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.Count == 0)
|
if (!result.HasValue) return;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExtractSection(result[0].Path.LocalPath, ncaSectionType, titleFilePath, titleName, programIndex);
|
ExtractSection(result.Value.Path.LocalPath, ncaSectionType, titleFilePath, titleName, programIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (Result? result, bool canceled) CopyDirectory(FileSystemClient fs, string sourcePath, string destPath, CancellationToken token)
|
public static (Result? result, bool canceled) CopyDirectory(FileSystemClient fs, string sourcePath, string destPath, CancellationToken token)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Ryujinx.Ava.Common.Models
|
|||||||
public bool IsBundled { get; } = System.IO.Path.GetExtension(ContainerPath)?.ToLower() == ".xci";
|
public bool IsBundled { get; } = System.IO.Path.GetExtension(ContainerPath)?.ToLower() == ".xci";
|
||||||
|
|
||||||
public string FileName => System.IO.Path.GetFileName(ContainerPath);
|
public string FileName => System.IO.Path.GetFileName(ContainerPath);
|
||||||
public string TitleIdStr => TitleId.ToString("x16");
|
public string TitleIdStr => TitleId.ToString("x16").ToUpper();
|
||||||
public ulong TitleIdBase => TitleId & ~0x1FFFUL;
|
public ulong TitleIdBase => TitleId & ~0x1FFFUL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ namespace Ryujinx.Headless
|
|||||||
IgnoreMissingServices = configurationState.System.IgnoreMissingServices;
|
IgnoreMissingServices = configurationState.System.IgnoreMissingServices;
|
||||||
|
|
||||||
if (NeedsOverride(nameof(IgnoreControllerApplet)))
|
if (NeedsOverride(nameof(IgnoreControllerApplet)))
|
||||||
IgnoreControllerApplet = configurationState.IgnoreApplet;
|
IgnoreControllerApplet = configurationState.System.IgnoreApplet;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ namespace Ryujinx.Ava
|
|||||||
{
|
{
|
||||||
Version = ReleaseInformation.Version;
|
Version = ReleaseInformation.Version;
|
||||||
|
|
||||||
if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134))
|
if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041))
|
||||||
{
|
{
|
||||||
_ = MessageBoxA(nint.Zero, "You are running an outdated version of Windows.\n\nRyujinx supports Windows 10 version 1803 and newer.\n", $"Ryujinx {Version}", MbIconwarning);
|
_ = MessageBoxA(nint.Zero, "You are running an outdated version of Windows.\n\nRyujinx supports Windows 10 version 20H1 and newer.\n", $"Ryujinx {Version}", MbIconwarning);
|
||||||
}
|
}
|
||||||
|
|
||||||
PreviewerDetached = true;
|
PreviewerDetached = true;
|
||||||
@@ -230,13 +230,16 @@ namespace Ryujinx.Ava
|
|||||||
internal static void PrintSystemInfo()
|
internal static void PrintSystemInfo()
|
||||||
{
|
{
|
||||||
Logger.Notice.Print(LogClass.Application, $"{RyujinxApp.FullAppName} Version: {Version}");
|
Logger.Notice.Print(LogClass.Application, $"{RyujinxApp.FullAppName} Version: {Version}");
|
||||||
|
Logger.Notice.Print(LogClass.Application, $".NET Runtime: {RuntimeInformation.FrameworkDescription}");
|
||||||
SystemInfo.Gather().Print();
|
SystemInfo.Gather().Print();
|
||||||
|
|
||||||
var enabledLogLevels = Logger.GetEnabledLevels().ToArray();
|
Logger.Notice.Print(LogClass.Application, $"Logs Enabled: {
|
||||||
|
Logger.GetEnabledLevels()
|
||||||
Logger.Notice.Print(LogClass.Application, $"Logs Enabled: {(enabledLogLevels.Length is 0
|
.FormatCollection(
|
||||||
? "<None>"
|
x => x.ToString(),
|
||||||
: enabledLogLevels.JoinToString(", "))}");
|
separator: ", ",
|
||||||
|
emptyCollectionFallback: "<None>")
|
||||||
|
}");
|
||||||
|
|
||||||
Logger.Notice.Print(LogClass.Application,
|
Logger.Notice.Print(LogClass.Application,
|
||||||
AppDataManager.Mode == AppDataManager.LaunchMode.Custom
|
AppDataManager.Mode == AppDataManager.LaunchMode.Custom
|
||||||
|
|||||||
@@ -123,12 +123,13 @@
|
|||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</AvaloniaResource>
|
</AvaloniaResource>
|
||||||
<AvaloniaResource Include="Assets\Styles\Styles.xaml" />
|
<AvaloniaResource Include="Assets\Styles\Styles.xaml" />
|
||||||
|
<AvaloniaResource Include="Assets\Styles\CheckboxMenuItemStyle.axaml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Assets\locales.json" />
|
<None Remove="Assets\locales.json" />
|
||||||
<None Remove="Assets\Styles\Styles.xaml" />
|
|
||||||
<None Remove="Assets\Styles\Themes.xaml" />
|
<None Remove="Assets\Styles\Themes.xaml" />
|
||||||
|
<None Remove="Assets\Styles\CheckboxMenuItemStyle.xaml" />
|
||||||
<None Remove="Assets\Icons\Controller_JoyConLeft.svg" />
|
<None Remove="Assets\Icons\Controller_JoyConLeft.svg" />
|
||||||
<None Remove="Assets\Icons\Controller_JoyConPair.svg" />
|
<None Remove="Assets\Icons\Controller_JoyConPair.svg" />
|
||||||
<None Remove="Assets\Icons\Controller_JoyConRight.svg" />
|
<None Remove="Assets\Icons\Controller_JoyConRight.svg" />
|
||||||
@@ -150,6 +151,7 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Assets\locales.json" />
|
<EmbeddedResource Include="Assets\locales.json" />
|
||||||
<EmbeddedResource Include="Assets\Styles\Styles.xaml" />
|
<EmbeddedResource Include="Assets\Styles\Styles.xaml" />
|
||||||
|
<EmbeddedResource Include="Assets\Styles\CheckboxMenuItemStyle.axaml" />
|
||||||
<EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />
|
<EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />
|
||||||
<EmbeddedResource Include="Assets\Icons\Controller_JoyConPair.svg" />
|
<EmbeddedResource Include="Assets\Icons\Controller_JoyConPair.svg" />
|
||||||
<EmbeddedResource Include="Assets\Icons\Controller_JoyConRight.svg" />
|
<EmbeddedResource Include="Assets\Icons\Controller_JoyConRight.svg" />
|
||||||
@@ -173,10 +175,5 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Assets\Fonts\Mono\" />
|
<Folder Include="Assets\Fonts\Mono\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Compile Update="UI\Applet\UserSelectorDialog.axaml.cs">
|
|
||||||
<DependentUpon>UserSelectorDialog.axaml</DependentUpon>
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -16,5 +16,6 @@
|
|||||||
<Application.Styles>
|
<Application.Styles>
|
||||||
<sty:FluentAvaloniaTheme PreferUserAccentColor="True" PreferSystemTheme="False" />
|
<sty:FluentAvaloniaTheme PreferUserAccentColor="True" PreferSystemTheme="False" />
|
||||||
<StyleInclude Source="/Assets/Styles/Styles.xaml" />
|
<StyleInclude Source="/Assets/Styles/Styles.xaml" />
|
||||||
|
<StyleInclude Source="/Assets/Styles/CheckboxMenuItemStyle.axaml"/>
|
||||||
</Application.Styles>
|
</Application.Styles>
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using Ryujinx.Ava.Common.Locale;
|
|||||||
using Ryujinx.Ava.UI.Controls;
|
using Ryujinx.Ava.UI.Controls;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
@@ -42,7 +41,7 @@ namespace Ryujinx.Ava.UI.Applet
|
|||||||
|
|
||||||
bool okPressed = false;
|
bool okPressed = false;
|
||||||
|
|
||||||
if (ConfigurationState.Instance.IgnoreApplet)
|
if (ConfigurationState.Instance.System.IgnoreApplet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||||
|
|||||||
@@ -106,6 +106,10 @@
|
|||||||
Click="ExtractApplicationRomFs_Click"
|
Click="ExtractApplicationRomFs_Click"
|
||||||
Header="{ext:Locale GameListContextMenuExtractDataRomFS}"
|
Header="{ext:Locale GameListContextMenuExtractDataRomFS}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuExtractDataRomFSToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuExtractDataRomFSToolTip}" />
|
||||||
|
<MenuItem
|
||||||
|
Click="ExtractAocRomFs_Click"
|
||||||
|
Header="{ext:Locale GameListContextMenuExtractDataAocRomFS}"
|
||||||
|
ToolTip.Tip="{ext:Locale GameListContextMenuExtractDataAocRomFSToolTip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="ExtractApplicationLogo_Click"
|
Click="ExtractApplicationLogo_Click"
|
||||||
Header="{ext:Locale GameListContextMenuExtractDataLogo}"
|
Header="{ext:Locale GameListContextMenuExtractDataLogo}"
|
||||||
|
|||||||
@@ -3,10 +3,13 @@ using Avalonia.Interactivity;
|
|||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using FluentAvalonia.UI.Controls;
|
||||||
|
using LibHac;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
using Ryujinx.Ava.Common;
|
using Ryujinx.Ava.Common;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using Ryujinx.Ava.Common.Models;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
@@ -14,6 +17,7 @@ using Ryujinx.Ava.Utilities;
|
|||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using System;
|
using System;
|
||||||
@@ -247,7 +251,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
{
|
{
|
||||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
{
|
{
|
||||||
string shaderCacheDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "shader");
|
string shaderCacheDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString.ToLower(), "cache", "shader");
|
||||||
|
|
||||||
if (!Directory.Exists(shaderCacheDir))
|
if (!Directory.Exists(shaderCacheDir))
|
||||||
{
|
{
|
||||||
@@ -279,6 +283,22 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
viewModel.SelectedApplication.Path,
|
viewModel.SelectedApplication.Path,
|
||||||
viewModel.SelectedApplication.Name);
|
viewModel.SelectedApplication.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async void ExtractAocRomFs_Click(object sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
if (sender is not MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
|
return;
|
||||||
|
|
||||||
|
DownloadableContentModel selectedDlc = await DlcSelectView.Show(viewModel.SelectedApplication.IdBase, viewModel.ApplicationLibrary);
|
||||||
|
|
||||||
|
if (selectedDlc is not null)
|
||||||
|
{
|
||||||
|
await ApplicationHelper.ExtractAoc(
|
||||||
|
viewModel.StorageProvider,
|
||||||
|
selectedDlc.ContainerPath,
|
||||||
|
selectedDlc.FileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async void ExtractApplicationLogo_Click(object sender, RoutedEventArgs args)
|
public async void ExtractApplicationLogo_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,11 +2,10 @@
|
|||||||
x:Class="Ryujinx.Ava.UI.Controls.ApplicationListView"
|
x:Class="Ryujinx.Ava.UI.Controls.ApplicationListView"
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
Focusable="True"
|
Focusable="True"
|
||||||
|
|||||||
67
src/Ryujinx/UI/Controls/DlcSelectView.axaml
Normal file
67
src/Ryujinx/UI/Controls/DlcSelectView.axaml
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:helpers="using:Ryujinx.Ava.UI.Helpers"
|
||||||
|
xmlns:ext="using:Ryujinx.Ava.Common.Markup"
|
||||||
|
xmlns:models="using:Ryujinx.Ava.Common.Models"
|
||||||
|
xmlns:viewModels="using:Ryujinx.Ava.UI.ViewModels"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Ryujinx.Ava.UI.Controls.DlcSelectView"
|
||||||
|
x:DataType="viewModels:DlcSelectViewModel">
|
||||||
|
<Grid RowDefinitions="*,Auto,*">
|
||||||
|
<TextBlock
|
||||||
|
Classes="h1"
|
||||||
|
Margin="5, -5, 0, 15"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Text="{ext:Locale ExtractAocListHeader}" />
|
||||||
|
<ScrollViewer Grid.Row="2">
|
||||||
|
<ListBox
|
||||||
|
AutoScrollToSelectedItem="False"
|
||||||
|
SelectionMode="Single"
|
||||||
|
Background="Transparent"
|
||||||
|
SelectedItem="{Binding SelectedDlc}"
|
||||||
|
ItemsSource="{Binding Dlcs}">
|
||||||
|
<ListBox.DataTemplates>
|
||||||
|
<DataTemplate
|
||||||
|
DataType="models:DownloadableContentModel">
|
||||||
|
<Panel Margin="10" Background="Transparent">
|
||||||
|
<Grid ColumnDefinitions="*,Auto">
|
||||||
|
<Grid
|
||||||
|
Grid.Column="0" ColumnDefinitions="*,Auto">
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
MaxLines="2"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
TextTrimming="CharacterEllipsis">
|
||||||
|
<TextBlock.Text>
|
||||||
|
<MultiBinding Converter="{x:Static helpers:DownloadableContentLabelConverter.Instance}">
|
||||||
|
<Binding Path="FileName" />
|
||||||
|
<Binding Path="IsBundled" />
|
||||||
|
</MultiBinding>
|
||||||
|
</TextBlock.Text>
|
||||||
|
</TextBlock>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="10, 0, 0, 0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{Binding TitleIdStr}" />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Panel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.DataTemplates>
|
||||||
|
<ListBox.Styles>
|
||||||
|
<Style Selector="ListBoxItem">
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
</Style>
|
||||||
|
</ListBox.Styles>
|
||||||
|
</ListBox>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
51
src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs
Normal file
51
src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.Styling;
|
||||||
|
using FluentAvalonia.UI.Controls;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using Ryujinx.Ava.Common.Models;
|
||||||
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
|
{
|
||||||
|
public partial class DlcSelectView : UserControl
|
||||||
|
{
|
||||||
|
public DlcSelectView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
public static async Task<DownloadableContentModel?> Show(ulong selectedTitleId, ApplicationLibrary appLibrary)
|
||||||
|
#nullable disable
|
||||||
|
{
|
||||||
|
DlcSelectViewModel viewModel = new(selectedTitleId, appLibrary);
|
||||||
|
|
||||||
|
ContentDialog contentDialog = new()
|
||||||
|
{
|
||||||
|
PrimaryButtonText = LocaleManager.Instance[LocaleKeys.Continue],
|
||||||
|
SecondaryButtonText = string.Empty,
|
||||||
|
CloseButtonText = string.Empty,
|
||||||
|
Content = new DlcSelectView { DataContext = viewModel }
|
||||||
|
};
|
||||||
|
|
||||||
|
Style closeButton = new(x => x.Name("CloseButton"));
|
||||||
|
closeButton.Setters.Add(new Setter(WidthProperty, 80d));
|
||||||
|
|
||||||
|
Style closeButtonParent = new(x => x.Name("CommandSpace"));
|
||||||
|
closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty,
|
||||||
|
Avalonia.Layout.HorizontalAlignment.Right));
|
||||||
|
|
||||||
|
contentDialog.Styles.Add(closeButton);
|
||||||
|
contentDialog.Styles.Add(closeButtonParent);
|
||||||
|
|
||||||
|
await ContentDialogHelper.ShowAsync(contentDialog);
|
||||||
|
|
||||||
|
return viewModel.SelectedDlc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -69,7 +69,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
VirtualFileSystem ownerVirtualFileSystem,
|
VirtualFileSystem ownerVirtualFileSystem,
|
||||||
HorizonClient ownerHorizonClient)
|
HorizonClient ownerHorizonClient)
|
||||||
{
|
{
|
||||||
var content = new NavigationDialogHost(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem, ownerHorizonClient);
|
NavigationDialogHost content = new(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem, ownerHorizonClient);
|
||||||
ContentDialog contentDialog = new()
|
ContentDialog contentDialog = new()
|
||||||
{
|
{
|
||||||
Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle],
|
Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle],
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
public static RelayCommand CreateConditional(Action action, Func<bool> canExecute)
|
public static RelayCommand CreateConditional(Action action, Func<bool> canExecute)
|
||||||
=> new(action, canExecute);
|
=> new(action, canExecute);
|
||||||
|
|
||||||
public static RelayCommand<T> CreateWithArg<T>(Action<T?> action)
|
public static RelayCommand<T> Create<T>(Action<T?> action)
|
||||||
=> new(action);
|
=> new(action);
|
||||||
public static RelayCommand<T> CreateConditionalWithArg<T>(Action<T?> action, Predicate<T?> canExecute)
|
public static RelayCommand<T> CreateConditional<T>(Action<T?> action, Predicate<T?> canExecute)
|
||||||
=> new(action, canExecute);
|
=> new(action, canExecute);
|
||||||
|
|
||||||
public static AsyncRelayCommand Create(Func<Task> action)
|
public static AsyncRelayCommand Create(Func<Task> action)
|
||||||
@@ -24,11 +24,11 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
public static AsyncRelayCommand CreateSilentFail(Func<Task> action)
|
public static AsyncRelayCommand CreateSilentFail(Func<Task> action)
|
||||||
=> new(action, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
=> new(action, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
||||||
|
|
||||||
public static AsyncRelayCommand<T> CreateWithArg<T>(Func<T?, Task> action)
|
public static AsyncRelayCommand<T> Create<T>(Func<T?, Task> action)
|
||||||
=> new(action, AsyncRelayCommandOptions.None);
|
=> new(action, AsyncRelayCommandOptions.None);
|
||||||
public static AsyncRelayCommand<T> CreateConcurrentWithArg<T>(Func<T?, Task> action)
|
public static AsyncRelayCommand<T> CreateConcurrent<T>(Func<T?, Task> action)
|
||||||
=> new(action, AsyncRelayCommandOptions.AllowConcurrentExecutions);
|
=> new(action, AsyncRelayCommandOptions.AllowConcurrentExecutions);
|
||||||
public static AsyncRelayCommand<T> CreateSilentFailWithArg<T>(Func<T?, Task> action)
|
public static AsyncRelayCommand<T> CreateSilentFail<T>(Func<T?, Task> action)
|
||||||
=> new(action, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
=> new(action, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
||||||
|
|
||||||
public static AsyncRelayCommand CreateConditional(Func<Task> action, Func<bool> canExecute)
|
public static AsyncRelayCommand CreateConditional(Func<Task> action, Func<bool> canExecute)
|
||||||
@@ -38,11 +38,11 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
public static AsyncRelayCommand CreateSilentFailConditional(Func<Task> action, Func<bool> canExecute)
|
public static AsyncRelayCommand CreateSilentFailConditional(Func<Task> action, Func<bool> canExecute)
|
||||||
=> new(action, canExecute, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
=> new(action, canExecute, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
||||||
|
|
||||||
public static AsyncRelayCommand<T> CreateConditionalWithArg<T>(Func<T?, Task> action, Predicate<T?> canExecute)
|
public static AsyncRelayCommand<T> CreateConditional<T>(Func<T?, Task> action, Predicate<T?> canExecute)
|
||||||
=> new(action, canExecute, AsyncRelayCommandOptions.None);
|
=> new(action, canExecute, AsyncRelayCommandOptions.None);
|
||||||
public static AsyncRelayCommand<T> CreateConcurrentConditionalWithArg<T>(Func<T?, Task> action, Predicate<T?> canExecute)
|
public static AsyncRelayCommand<T> CreateConcurrentConditional<T>(Func<T?, Task> action, Predicate<T?> canExecute)
|
||||||
=> new(action, canExecute, AsyncRelayCommandOptions.AllowConcurrentExecutions);
|
=> new(action, canExecute, AsyncRelayCommandOptions.AllowConcurrentExecutions);
|
||||||
public static AsyncRelayCommand<T> CreateSilentFailConditionalWithArg<T>(Func<T?, Task> action, Predicate<T?> canExecute)
|
public static AsyncRelayCommand<T> CreateSilentFailConditional<T>(Func<T?, Task> action, Predicate<T?> canExecute)
|
||||||
=> new(action, canExecute, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
=> new(action, canExecute, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Avalonia.Media;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
@@ -387,6 +388,30 @@ namespace Ryujinx.Ava.UI.Models.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _enableLedChanging;
|
||||||
|
|
||||||
|
public bool EnableLedChanging
|
||||||
|
{
|
||||||
|
get => _enableLedChanging;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_enableLedChanging = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color _ledColor;
|
||||||
|
|
||||||
|
public Color LedColor
|
||||||
|
{
|
||||||
|
get => _ledColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_ledColor = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool _enableMotion;
|
private bool _enableMotion;
|
||||||
public bool EnableMotion
|
public bool EnableMotion
|
||||||
{
|
{
|
||||||
@@ -483,12 +508,23 @@ namespace Ryujinx.Ava.UI.Models.Input
|
|||||||
WeakRumble = controllerInput.Rumble.WeakRumble;
|
WeakRumble = controllerInput.Rumble.WeakRumble;
|
||||||
StrongRumble = controllerInput.Rumble.StrongRumble;
|
StrongRumble = controllerInput.Rumble.StrongRumble;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (controllerInput.Led != null)
|
||||||
|
{
|
||||||
|
EnableLedChanging = controllerInput.Led.EnableLed;
|
||||||
|
uint rawColor = controllerInput.Led.LedColor;
|
||||||
|
byte alpha = (byte)(rawColor >> 24);
|
||||||
|
byte red = (byte)(rawColor >> 16);
|
||||||
|
byte green = (byte)(rawColor >> 8);
|
||||||
|
byte blue = (byte)(rawColor % 256);
|
||||||
|
LedColor = new Color(alpha, red, green, blue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputConfig GetConfig()
|
public InputConfig GetConfig()
|
||||||
{
|
{
|
||||||
var config = new StandardControllerInputConfig
|
StandardControllerInputConfig config = new()
|
||||||
{
|
{
|
||||||
Id = Id,
|
Id = Id,
|
||||||
Backend = InputBackendType.GamepadSDL2,
|
Backend = InputBackendType.GamepadSDL2,
|
||||||
@@ -540,6 +576,11 @@ namespace Ryujinx.Ava.UI.Models.Input
|
|||||||
WeakRumble = WeakRumble,
|
WeakRumble = WeakRumble,
|
||||||
StrongRumble = StrongRumble,
|
StrongRumble = StrongRumble,
|
||||||
},
|
},
|
||||||
|
Led = new LedConfigController
|
||||||
|
{
|
||||||
|
EnableLed = EnableLedChanging,
|
||||||
|
LedColor = LedColor.ToUInt32()
|
||||||
|
},
|
||||||
Version = InputConfig.CurrentVersion,
|
Version = InputConfig.CurrentVersion,
|
||||||
DeadzoneLeft = DeadzoneLeft,
|
DeadzoneLeft = DeadzoneLeft,
|
||||||
DeadzoneRight = DeadzoneRight,
|
DeadzoneRight = DeadzoneRight,
|
||||||
|
|||||||
@@ -432,7 +432,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://raw.githubusercontent.com/GreemDev/Ryujinx/refs/heads/master/assets/amiibo/Amiibo.json"));
|
HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://raw.githubusercontent.com/Ryubing/Ryujinx/refs/heads/master/assets/amiibo/Amiibo.json"));
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
@@ -451,7 +451,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpResponseMessage response = await _httpClient.GetAsync($"https://raw.githubusercontent.com/GreemDev/Ryujinx/refs/heads/master/assets/amiibo/Amiibo.json");
|
HttpResponseMessage response = await _httpClient.GetAsync($"https://raw.githubusercontent.com/Ryubing/Ryujinx/refs/heads/master/assets/amiibo/Amiibo.json");
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
|
|||||||
25
src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs
Normal file
25
src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Ryujinx.Ava.Common.Models;
|
||||||
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
{
|
||||||
|
public partial class DlcSelectViewModel : BaseModel
|
||||||
|
{
|
||||||
|
[ObservableProperty] private DownloadableContentModel[] _dlcs;
|
||||||
|
#nullable enable
|
||||||
|
[ObservableProperty] private DownloadableContentModel? _selectedDlc;
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
public DlcSelectViewModel(ulong titleId, ApplicationLibrary appLibrary)
|
||||||
|
{
|
||||||
|
_dlcs = appLibrary.DownloadableContents.Items
|
||||||
|
.Where(x => x.Dlc.TitleIdBase == titleId)
|
||||||
|
.Select(x => x.Dlc)
|
||||||
|
.OrderBy(it => it.IsBundled ? 0 : 1)
|
||||||
|
.ThenBy(it => it.TitleId)
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,7 +37,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
|
|
||||||
[ObservableProperty] private SvgImage _image;
|
[ObservableProperty] private SvgImage _image;
|
||||||
|
|
||||||
public readonly InputViewModel ParentModel;
|
public InputViewModel ParentModel { get; }
|
||||||
|
|
||||||
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
|
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -69,6 +69,9 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
public bool IsRight { get; set; }
|
public bool IsRight { get; set; }
|
||||||
public bool IsLeft { get; set; }
|
public bool IsLeft { get; set; }
|
||||||
|
|
||||||
|
public bool HasLed => false; //temporary
|
||||||
|
//SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led);
|
||||||
|
|
||||||
public bool IsModified { get; set; }
|
public bool IsModified { get; set; }
|
||||||
public event Action NotifyChangesEvent;
|
public event Action NotifyChangesEvent;
|
||||||
|
|
||||||
|
|||||||
@@ -488,6 +488,19 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool StartGamesWithoutUI
|
||||||
|
{
|
||||||
|
get => ConfigurationState.Instance.UI.StartNoUI;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ConfigurationState.Instance.UI.StartNoUI.Value = value;
|
||||||
|
|
||||||
|
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool ShowConsole
|
public bool ShowConsole
|
||||||
{
|
{
|
||||||
get => ConfigurationState.Instance.UI.ShowConsole;
|
get => ConfigurationState.Instance.UI.ShowConsole;
|
||||||
@@ -624,6 +637,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
ApplicationSort.FileSize => LocaleManager.Instance[LocaleKeys.GameListHeaderFileSize],
|
ApplicationSort.FileSize => LocaleManager.Instance[LocaleKeys.GameListHeaderFileSize],
|
||||||
ApplicationSort.Path => LocaleManager.Instance[LocaleKeys.GameListHeaderPath],
|
ApplicationSort.Path => LocaleManager.Instance[LocaleKeys.GameListHeaderPath],
|
||||||
ApplicationSort.Favorite => LocaleManager.Instance[LocaleKeys.CommonFavorite],
|
ApplicationSort.Favorite => LocaleManager.Instance[LocaleKeys.CommonFavorite],
|
||||||
|
ApplicationSort.TitleId => LocaleManager.Instance[LocaleKeys.DlcManagerTableHeadingTitleIdLabel],
|
||||||
_ => string.Empty,
|
_ => string.Empty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -694,6 +708,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
public IHostUIHandler UiHandler { get; internal set; }
|
public IHostUIHandler UiHandler { get; internal set; }
|
||||||
public bool IsSortedByFavorite => SortMode == ApplicationSort.Favorite;
|
public bool IsSortedByFavorite => SortMode == ApplicationSort.Favorite;
|
||||||
public bool IsSortedByTitle => SortMode == ApplicationSort.Title;
|
public bool IsSortedByTitle => SortMode == ApplicationSort.Title;
|
||||||
|
public bool IsSortedByTitleId => SortMode == ApplicationSort.TitleId;
|
||||||
public bool IsSortedByDeveloper => SortMode == ApplicationSort.Developer;
|
public bool IsSortedByDeveloper => SortMode == ApplicationSort.Developer;
|
||||||
public bool IsSortedByLastPlayed => SortMode == ApplicationSort.LastPlayed;
|
public bool IsSortedByLastPlayed => SortMode == ApplicationSort.LastPlayed;
|
||||||
public bool IsSortedByTimePlayed => SortMode == ApplicationSort.TotalTimePlayed;
|
public bool IsSortedByTimePlayed => SortMode == ApplicationSort.TotalTimePlayed;
|
||||||
@@ -726,6 +741,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
ApplicationSort.FileSize => CreateComparer(IsAscending, app => app.FileSize),
|
ApplicationSort.FileSize => CreateComparer(IsAscending, app => app.FileSize),
|
||||||
ApplicationSort.Path => CreateComparer(IsAscending, app => app.Path),
|
ApplicationSort.Path => CreateComparer(IsAscending, app => app.Path),
|
||||||
ApplicationSort.Favorite => CreateComparer(IsAscending, app => new AppListFavoriteComparable(app)),
|
ApplicationSort.Favorite => CreateComparer(IsAscending, app => new AppListFavoriteComparable(app)),
|
||||||
|
ApplicationSort.TitleId => CreateComparer(IsAscending, app => app.Id),
|
||||||
_ => null,
|
_ => null,
|
||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
};
|
};
|
||||||
@@ -1195,6 +1211,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
StartGamesInFullscreen = !StartGamesInFullscreen;
|
StartGamesInFullscreen = !StartGamesInFullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ToggleStartGamesWithoutUI()
|
||||||
|
{
|
||||||
|
StartGamesWithoutUI = !StartGamesWithoutUI;
|
||||||
|
}
|
||||||
|
|
||||||
public void ToggleShowConsole()
|
public void ToggleShowConsole()
|
||||||
{
|
{
|
||||||
ShowConsole = !ShowConsole;
|
ShowConsole = !ShowConsole;
|
||||||
@@ -1641,10 +1662,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public async Task OpenAmiiboWindow()
|
public async Task OpenAmiiboWindow()
|
||||||
{
|
{
|
||||||
if (!IsAmiiboRequested)
|
if (AppHost.Device.System.SearchingForAmiibo(out int deviceId) && IsGameRunning)
|
||||||
return;
|
|
||||||
|
|
||||||
if (AppHost.Device.System.SearchingForAmiibo(out int deviceId))
|
|
||||||
{
|
{
|
||||||
string titleId = AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper();
|
string titleId = AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper();
|
||||||
AmiiboWindow window = new(ShowAll, LastScannedAmiiboId, titleId);
|
AmiiboWindow window = new(ShowAll, LastScannedAmiiboId, titleId);
|
||||||
@@ -1662,10 +1680,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
public async Task OpenBinFile()
|
public async Task OpenBinFile()
|
||||||
{
|
{
|
||||||
if (!IsAmiiboRequested)
|
if (AppHost.Device.System.SearchingForAmiibo(out _) && IsGameRunning)
|
||||||
return;
|
|
||||||
|
|
||||||
if (AppHost.Device.System.SearchingForAmiibo(out int deviceId))
|
|
||||||
{
|
{
|
||||||
var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -488,7 +488,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
EnableDiscordIntegration = config.EnableDiscordIntegration;
|
EnableDiscordIntegration = config.EnableDiscordIntegration;
|
||||||
CheckUpdatesOnStart = config.CheckUpdatesOnStart;
|
CheckUpdatesOnStart = config.CheckUpdatesOnStart;
|
||||||
ShowConfirmExit = config.ShowConfirmExit;
|
ShowConfirmExit = config.ShowConfirmExit;
|
||||||
IgnoreApplet = config.IgnoreApplet;
|
|
||||||
RememberWindowState = config.RememberWindowState;
|
RememberWindowState = config.RememberWindowState;
|
||||||
ShowTitleBar = config.ShowTitleBar;
|
ShowTitleBar = config.ShowTitleBar;
|
||||||
HideCursor = (int)config.HideCursor.Value;
|
HideCursor = (int)config.HideCursor.Value;
|
||||||
@@ -532,6 +531,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
|
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
|
||||||
DramSize = config.System.DramSize;
|
DramSize = config.System.DramSize;
|
||||||
IgnoreMissingServices = config.System.IgnoreMissingServices;
|
IgnoreMissingServices = config.System.IgnoreMissingServices;
|
||||||
|
IgnoreApplet = config.System.IgnoreApplet;
|
||||||
|
|
||||||
// CPU
|
// CPU
|
||||||
EnablePptc = config.System.EnablePtc;
|
EnablePptc = config.System.EnablePtc;
|
||||||
@@ -591,7 +591,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
|
config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
|
||||||
config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
|
config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
|
||||||
config.ShowConfirmExit.Value = ShowConfirmExit;
|
config.ShowConfirmExit.Value = ShowConfirmExit;
|
||||||
config.IgnoreApplet.Value = IgnoreApplet;
|
|
||||||
config.RememberWindowState.Value = RememberWindowState;
|
config.RememberWindowState.Value = RememberWindowState;
|
||||||
config.ShowTitleBar.Value = ShowTitleBar;
|
config.ShowTitleBar.Value = ShowTitleBar;
|
||||||
config.HideCursor.Value = (HideCursorMode)HideCursor;
|
config.HideCursor.Value = (HideCursorMode)HideCursor;
|
||||||
@@ -632,12 +631,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds());
|
config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds());
|
||||||
config.Graphics.VSyncMode.Value = VSyncMode;
|
|
||||||
config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval;
|
|
||||||
config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval;
|
|
||||||
config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
|
config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
|
||||||
config.System.DramSize.Value = DramSize;
|
config.System.DramSize.Value = DramSize;
|
||||||
config.System.IgnoreMissingServices.Value = IgnoreMissingServices;
|
config.System.IgnoreMissingServices.Value = IgnoreMissingServices;
|
||||||
|
config.System.IgnoreApplet.Value = IgnoreApplet;
|
||||||
|
|
||||||
// CPU
|
// CPU
|
||||||
config.System.EnablePtc.Value = EnablePptc;
|
config.System.EnablePtc.Value = EnablePptc;
|
||||||
@@ -646,6 +643,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
config.System.UseHypervisor.Value = UseHypervisor;
|
config.System.UseHypervisor.Value = UseHypervisor;
|
||||||
|
|
||||||
// Graphics
|
// Graphics
|
||||||
|
config.Graphics.VSyncMode.Value = VSyncMode;
|
||||||
|
config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval;
|
||||||
|
config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval;
|
||||||
config.Graphics.GraphicsBackend.Value = (GraphicsBackend)GraphicsBackendIndex;
|
config.Graphics.GraphicsBackend.Value = (GraphicsBackend)GraphicsBackendIndex;
|
||||||
config.Graphics.PreferredGpu.Value = _gpuIds.ElementAtOrDefault(PreferredGpuIndex);
|
config.Graphics.PreferredGpu.Value = _gpuIds.ElementAtOrDefault(PreferredGpuIndex);
|
||||||
config.Graphics.EnableShaderCache.Value = EnableShaderCache;
|
config.Graphics.EnableShaderCache.Value = EnableShaderCache;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
||||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
|
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
|
||||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||||
@@ -486,6 +487,37 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="5"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Margin="0,-1,0,0">
|
||||||
|
<Grid IsVisible="{Binding ParentModel.HasLed}">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<CheckBox
|
||||||
|
Margin="10"
|
||||||
|
MinWidth="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
IsChecked="{Binding Config.EnableLedChanging, Mode=TwoWay}">
|
||||||
|
<TextBlock Text="{ext:Locale ControllerSettingsLedColor}" />
|
||||||
|
</CheckBox>
|
||||||
|
<ui:ColorPickerButton
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="10"
|
||||||
|
IsMoreButtonVisible="False"
|
||||||
|
UseColorPalette="False"
|
||||||
|
UseColorTriangle="False"
|
||||||
|
UseColorWheel="False"
|
||||||
|
ShowAcceptDismissButtons="False"
|
||||||
|
IsAlphaEnabled="False"
|
||||||
|
Color="{Binding Config.LedColor, Mode=TwoWay}">
|
||||||
|
</ui:ColorPickerButton>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<!-- Right Controls -->
|
<!-- Right Controls -->
|
||||||
|
|||||||
@@ -4,14 +4,11 @@ using Avalonia.Controls.Primitives;
|
|||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.LogicalTree;
|
using Avalonia.LogicalTree;
|
||||||
using DiscordRPC;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
using Ryujinx.Common.Logging;
|
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Input.Assigner;
|
using Ryujinx.Input.Assigner;
|
||||||
using System;
|
|
||||||
using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Views.Input
|
namespace Ryujinx.Ava.UI.Views.Input
|
||||||
|
|||||||
@@ -81,25 +81,16 @@
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding ToggleFullscreen}"
|
Command="{Binding ToggleFullscreen}"
|
||||||
Header="{ext:Locale MenuBarOptionsToggleFullscreen}"
|
Header="{ext:Locale MenuBarOptionsToggleFullscreen}"
|
||||||
|
Classes="withCheckbox"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
Icon="{ext:Icon fa-solid fa-expand}"
|
Icon="{ext:Icon fa-solid fa-expand}"
|
||||||
InputGesture="F11">
|
InputGesture="F11">
|
||||||
<MenuItem.Styles>
|
|
||||||
<Style Selector="Viewbox#PART_IconPresenter">
|
|
||||||
<Setter Property="MaxHeight" Value="36" />
|
|
||||||
<Setter Property="MinHeight" Value="36" />
|
|
||||||
<Setter Property="MaxWidth" Value="36" />
|
|
||||||
<Setter Property="MinWidth" Value="36" />
|
|
||||||
</Style>
|
|
||||||
<Style Selector="ContentPresenter#PART_HeaderPresenter">
|
|
||||||
<Setter Property="Padding" Value="-10,0,0,0" />
|
|
||||||
</Style>
|
|
||||||
</MenuItem.Styles>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Padding="0"
|
Padding="0"
|
||||||
Command="{Binding ToggleStartGamesInFullscreen}"
|
Command="{Binding ToggleStartGamesInFullscreen}"
|
||||||
Header="{ext:Locale MenuBarOptionsStartGamesInFullscreen}">
|
Header="{ext:Locale MenuBarOptionsStartGamesInFullscreen}"
|
||||||
|
Classes="withCheckbox">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<CheckBox
|
<CheckBox
|
||||||
MinWidth="{DynamicResource CheckBoxSize}"
|
MinWidth="{DynamicResource CheckBoxSize}"
|
||||||
@@ -107,23 +98,26 @@
|
|||||||
IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}"
|
IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}"
|
||||||
Padding="0" />
|
Padding="0" />
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
<MenuItem.Styles>
|
</MenuItem>
|
||||||
<Style Selector="Viewbox#PART_IconPresenter">
|
<MenuItem
|
||||||
<Setter Property="MaxHeight" Value="36" />
|
Padding="0"
|
||||||
<Setter Property="MinHeight" Value="36" />
|
Command="{Binding ToggleStartGamesWithoutUI}"
|
||||||
<Setter Property="MaxWidth" Value="36" />
|
Header="{ext:Locale MenuBarOptionsStartGamesWithoutUI}"
|
||||||
<Setter Property="MinWidth" Value="36" />
|
Classes="withCheckbox">
|
||||||
</Style>
|
<MenuItem.Icon>
|
||||||
<Style Selector="ContentPresenter#PART_HeaderPresenter">
|
<CheckBox
|
||||||
<Setter Property="Padding" Value="-10,0,0,0" />
|
MinWidth="{DynamicResource CheckBoxSize}"
|
||||||
</Style>
|
MinHeight="{DynamicResource CheckBoxSize}"
|
||||||
</MenuItem.Styles>
|
IsChecked="{Binding StartGamesWithoutUI, Mode=TwoWay}"
|
||||||
|
Padding="0" />
|
||||||
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Padding="0"
|
Padding="0"
|
||||||
IsVisible="{Binding ShowConsoleVisible}"
|
IsVisible="{Binding ShowConsoleVisible}"
|
||||||
Command="{Binding ToggleShowConsole}"
|
Command="{Binding ToggleShowConsole}"
|
||||||
Header="{ext:Locale MenuBarOptionsShowConsole}">
|
Header="{ext:Locale MenuBarOptionsShowConsole}"
|
||||||
|
Classes="withCheckbox">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<CheckBox
|
<CheckBox
|
||||||
MinWidth="{DynamicResource CheckBoxSize}"
|
MinWidth="{DynamicResource CheckBoxSize}"
|
||||||
@@ -131,35 +125,14 @@
|
|||||||
IsChecked="{Binding ShowConsole, Mode=TwoWay}"
|
IsChecked="{Binding ShowConsole, Mode=TwoWay}"
|
||||||
Padding="0" />
|
Padding="0" />
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
<MenuItem.Styles>
|
|
||||||
<Style Selector="Viewbox#PART_IconPresenter">
|
|
||||||
<Setter Property="MaxHeight" Value="36" />
|
|
||||||
<Setter Property="MinHeight" Value="36" />
|
|
||||||
<Setter Property="MaxWidth" Value="36" />
|
|
||||||
<Setter Property="MinWidth" Value="36" />
|
|
||||||
</Style>
|
|
||||||
<Style Selector="ContentPresenter#PART_HeaderPresenter">
|
|
||||||
<Setter Property="Padding" Value="-10,0,0,0" />
|
|
||||||
</Style>
|
|
||||||
</MenuItem.Styles>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Separator/>
|
<Separator/>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="ChangeLanguageMenuItem"
|
Name="ChangeLanguageMenuItem"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
Header="{ext:Locale MenuBarOptionsChangeLanguage}"
|
Header="{ext:Locale MenuBarOptionsChangeLanguage}"
|
||||||
Icon="{ext:Icon fa-solid fa-language}">
|
Icon="{ext:Icon fa-solid fa-language}"
|
||||||
<MenuItem.Styles>
|
Classes="withCheckbox">
|
||||||
<Style Selector="Viewbox#PART_IconPresenter">
|
|
||||||
<Setter Property="MaxHeight" Value="36" />
|
|
||||||
<Setter Property="MinHeight" Value="36" />
|
|
||||||
<Setter Property="MaxWidth" Value="36" />
|
|
||||||
<Setter Property="MinWidth" Value="36" />
|
|
||||||
</Style>
|
|
||||||
<Style Selector="ContentPresenter#PART_HeaderPresenter">
|
|
||||||
<Setter Property="Padding" Value="-10,0,0,0" />
|
|
||||||
</Style>
|
|
||||||
</MenuItem.Styles>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="ToggleFileTypesMenuItem"
|
Name="ToggleFileTypesMenuItem"
|
||||||
@@ -171,18 +144,8 @@
|
|||||||
Padding="0"
|
Padding="0"
|
||||||
Header="{ext:Locale MenuBarOptionsSettings}"
|
Header="{ext:Locale MenuBarOptionsSettings}"
|
||||||
Icon="{ext:Icon fa-solid fa-gear}"
|
Icon="{ext:Icon fa-solid fa-gear}"
|
||||||
ToolTip.Tip="{ext:Locale OpenSettingsTooltip}">
|
ToolTip.Tip="{ext:Locale OpenSettingsTooltip}"
|
||||||
<MenuItem.Styles>
|
Classes="withCheckbox">
|
||||||
<Style Selector="Viewbox#PART_IconPresenter">
|
|
||||||
<Setter Property="MaxHeight" Value="36" />
|
|
||||||
<Setter Property="MinHeight" Value="36" />
|
|
||||||
<Setter Property="MaxWidth" Value="36" />
|
|
||||||
<Setter Property="MinWidth" Value="36" />
|
|
||||||
</Style>
|
|
||||||
<Style Selector="ContentPresenter#PART_HeaderPresenter">
|
|
||||||
<Setter Property="Padding" Value="-10,0,0,0" />
|
|
||||||
</Style>
|
|
||||||
</MenuItem.Styles>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding ManageProfiles}"
|
Command="{Binding ManageProfiles}"
|
||||||
@@ -190,25 +153,15 @@
|
|||||||
Header="{ext:Locale MenuBarOptionsManageUserProfiles}"
|
Header="{ext:Locale MenuBarOptionsManageUserProfiles}"
|
||||||
Icon="{ext:Icon mdi-account}"
|
Icon="{ext:Icon mdi-account}"
|
||||||
IsEnabled="{Binding EnableNonGameRunningControls}"
|
IsEnabled="{Binding EnableNonGameRunningControls}"
|
||||||
ToolTip.Tip="{ext:Locale OpenProfileManagerTooltip}">
|
ToolTip.Tip="{ext:Locale OpenProfileManagerTooltip}"
|
||||||
<MenuItem.Styles>
|
Classes="withCheckbox">
|
||||||
<Style Selector="Viewbox#PART_IconPresenter">
|
|
||||||
<Setter Property="MaxHeight" Value="36" />
|
|
||||||
<Setter Property="MinHeight" Value="36" />
|
|
||||||
<Setter Property="MaxWidth" Value="36" />
|
|
||||||
<Setter Property="MinWidth" Value="36" />
|
|
||||||
</Style>
|
|
||||||
<Style Selector="ContentPresenter#PART_HeaderPresenter">
|
|
||||||
<Setter Property="Padding" Value="-10,0,0,0" />
|
|
||||||
</Style>
|
|
||||||
</MenuItem.Styles>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="ActionsMenuItem"
|
Name="ActionsMenuItem"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Header="{ext:Locale MenuBarActions}"
|
Header="{ext:Locale MenuBarActions}"
|
||||||
IsEnabled="{Binding IsGameRunning}">
|
IsVisible="{Binding !EnableNonGameRunningControls}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="PauseEmulationMenuItem"
|
Name="PauseEmulationMenuItem"
|
||||||
Header="{ext:Locale MenuBarOptionsPauseEmulation}"
|
Header="{ext:Locale MenuBarOptionsPauseEmulation}"
|
||||||
@@ -265,21 +218,21 @@
|
|||||||
Icon="{ext:Icon fa-solid fa-code}"
|
Icon="{ext:Icon fa-solid fa-code}"
|
||||||
IsEnabled="{Binding IsGameRunning}" />
|
IsEnabled="{Binding IsGameRunning}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarTools}">
|
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarActions}" IsVisible="{Binding EnableNonGameRunningControls}">
|
||||||
<MenuItem Header="{ext:Locale MenuBarToolsInstallKeys}" Icon="{ext:Icon fa-solid fa-key}" IsEnabled="{Binding EnableNonGameRunningControls}">
|
<MenuItem Header="{ext:Locale MenuBarActionsInstallKeys}" Icon="{ext:Icon fa-solid fa-key}">
|
||||||
<MenuItem Command="{Binding InstallKeysFromFile}" Header="{ext:Locale MenuBarFileToolsInstallKeysFromFile}" Icon="{ext:Icon mdi-file-cog}" />
|
<MenuItem Command="{Binding InstallKeysFromFile}" Header="{ext:Locale MenuBarFileActionsInstallKeysFromFile}" Icon="{ext:Icon mdi-file-cog}" />
|
||||||
<MenuItem Command="{Binding InstallKeysFromFolder}" Header="{ext:Locale MenuBarFileToolsInstallKeysFromFolder}" Icon="{ext:Icon mdi-folder-cog}" />
|
<MenuItem Command="{Binding InstallKeysFromFolder}" Header="{ext:Locale MenuBarFileActionsInstallKeysFromFolder}" Icon="{ext:Icon mdi-folder-cog}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="{ext:Locale MenuBarToolsInstallFirmware}" Icon="{ext:Icon fa-solid fa-download}" IsEnabled="{Binding EnableNonGameRunningControls}">
|
<MenuItem Header="{ext:Locale MenuBarActionsInstallFirmware}" Icon="{ext:Icon fa-solid fa-download}">
|
||||||
<MenuItem Command="{Binding InstallFirmwareFromFile}" Header="{ext:Locale MenuBarFileToolsInstallFirmwareFromFile}" Icon="{ext:Icon mdi-file-cog}" />
|
<MenuItem Command="{Binding InstallFirmwareFromFile}" Header="{ext:Locale MenuBarActionsInstallFirmwareFromFile}" Icon="{ext:Icon mdi-file-cog}" />
|
||||||
<MenuItem Command="{Binding InstallFirmwareFromFolder}" Header="{ext:Locale MenuBarFileToolsInstallFirmwareFromDirectory}" Icon="{ext:Icon mdi-folder-cog}" />
|
<MenuItem Command="{Binding InstallFirmwareFromFolder}" Header="{ext:Locale MenuBarActionsInstallFirmwareFromDirectory}" Icon="{ext:Icon mdi-folder-cog}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="{ext:Locale MenuBarToolsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}">
|
<MenuItem Header="{ext:Locale MenuBarActionsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}">
|
||||||
<MenuItem Name="InstallFileTypesMenuItem" Header="{ext:Locale MenuBarToolsInstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered, Converter={x:Static BoolConverters.Not}}" />
|
<MenuItem Name="InstallFileTypesMenuItem" Header="{ext:Locale MenuBarActionsInstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered, Converter={x:Static BoolConverters.Not}}" />
|
||||||
<MenuItem Name="UninstallFileTypesMenuItem" Header="{ext:Locale MenuBarToolsUninstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered}" />
|
<MenuItem Name="UninstallFileTypesMenuItem" Header="{ext:Locale MenuBarActionsUninstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem Name="XciTrimmerMenuItem" Header="{ext:Locale MenuBarToolsXCITrimmer}" IsEnabled="{Binding EnableNonGameRunningControls}" Icon="{ext:Icon fa-solid fa-scissors}" />
|
<MenuItem Name="XciTrimmerMenuItem" Header="{ext:Locale MenuBarActionsXCITrimmer}" Icon="{ext:Icon fa-solid fa-scissors}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarView}">
|
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarView}">
|
||||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarViewWindow}">
|
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarViewWindow}">
|
||||||
@@ -311,19 +264,19 @@
|
|||||||
Name="FaqMenuItem"
|
Name="FaqMenuItem"
|
||||||
Header="{ext:Locale MenuBarHelpFaq}"
|
Header="{ext:Locale MenuBarHelpFaq}"
|
||||||
Icon="{ext:Icon fa-github}"
|
Icon="{ext:Icon fa-github}"
|
||||||
CommandParameter="https://github.com/GreemDev/Ryujinx/wiki/FAQ-and-Troubleshooting"
|
CommandParameter="https://github.com/Ryubing/Ryujinx/wiki/FAQ-and-Troubleshooting"
|
||||||
ToolTip.Tip="{ext:Locale MenuBarHelpFaqTooltip}" />
|
ToolTip.Tip="{ext:Locale MenuBarHelpFaqTooltip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="SetupGuideMenuItem"
|
Name="SetupGuideMenuItem"
|
||||||
Header="{ext:Locale MenuBarHelpSetup}"
|
Header="{ext:Locale MenuBarHelpSetup}"
|
||||||
Icon="{ext:Icon fa-github}"
|
Icon="{ext:Icon fa-github}"
|
||||||
CommandParameter="https://github.com/GreemDev/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide"
|
CommandParameter="https://github.com/Ryubing/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide"
|
||||||
ToolTip.Tip="{ext:Locale MenuBarHelpSetupTooltip}" />
|
ToolTip.Tip="{ext:Locale MenuBarHelpSetupTooltip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="LdnGuideMenuItem"
|
Name="LdnGuideMenuItem"
|
||||||
Header="{ext:Locale MenuBarHelpMultiplayer}"
|
Header="{ext:Locale MenuBarHelpMultiplayer}"
|
||||||
Icon="{ext:Icon fa-github}"
|
Icon="{ext:Icon fa-github}"
|
||||||
CommandParameter="https://github.com/GreemDev/Ryujinx/wiki/Multiplayer%E2%80%90(LDN%E2%80%90Local%E2%80%90Wireless)%E2%80%90Guide"
|
CommandParameter="https://github.com/Ryubing/Ryujinx/wiki/Multiplayer%E2%80%90(LDN%E2%80%90Local%E2%80%90Wireless)%E2%80%90Guide"
|
||||||
ToolTip.Tip="{ext:Locale MenuBarHelpMultiplayerTooltip}" />
|
ToolTip.Tip="{ext:Locale MenuBarHelpMultiplayerTooltip}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|||||||
@@ -37,26 +37,20 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
ToggleFileTypesMenuItem.ItemsSource = GenerateToggleFileTypeItems();
|
ToggleFileTypesMenuItem.ItemsSource = GenerateToggleFileTypeItems();
|
||||||
ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems();
|
ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems();
|
||||||
|
|
||||||
MiiAppletMenuItem.Command = new AsyncRelayCommand(OpenMiiApplet);
|
MiiAppletMenuItem.Command = Commands.Create(OpenMiiApplet);
|
||||||
CloseRyujinxMenuItem.Command = new RelayCommand(CloseWindow);
|
CloseRyujinxMenuItem.Command = Commands.Create(CloseWindow);
|
||||||
OpenSettingsMenuItem.Command = new AsyncRelayCommand(OpenSettings);
|
OpenSettingsMenuItem.Command = Commands.Create(OpenSettings);
|
||||||
PauseEmulationMenuItem.Command = new RelayCommand(() => ViewModel.AppHost?.Pause());
|
PauseEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.Pause());
|
||||||
ResumeEmulationMenuItem.Command = new RelayCommand(() => ViewModel.AppHost?.Resume());
|
ResumeEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.Resume());
|
||||||
StopEmulationMenuItem.Command = new AsyncRelayCommand(() => ViewModel.AppHost?.ShowExitPrompt().OrCompleted());
|
StopEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.ShowExitPrompt().OrCompleted());
|
||||||
CheatManagerMenuItem.Command = new AsyncRelayCommand(async () =>
|
CheatManagerMenuItem.Command = Commands.CreateSilentFail(OpenCheatManagerForCurrentApp);
|
||||||
{
|
InstallFileTypesMenuItem.Command = Commands.Create(InstallFileTypes);
|
||||||
try
|
UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes);
|
||||||
{
|
XciTrimmerMenuItem.Command = Commands.Create(XCITrimmerWindow.Show);
|
||||||
await OpenCheatManagerForCurrentApp();
|
AboutWindowMenuItem.Command = Commands.Create(AboutWindow.Show);
|
||||||
} catch {}
|
CompatibilityListMenuItem.Command = Commands.Create(CompatibilityList.Show);
|
||||||
});
|
|
||||||
InstallFileTypesMenuItem.Command = new AsyncRelayCommand(InstallFileTypes);
|
|
||||||
UninstallFileTypesMenuItem.Command = new AsyncRelayCommand(UninstallFileTypes);
|
|
||||||
XciTrimmerMenuItem.Command = new AsyncRelayCommand(() => XCITrimmerWindow.Show(ViewModel));
|
|
||||||
AboutWindowMenuItem.Command = new AsyncRelayCommand(AboutWindow.Show);
|
|
||||||
CompatibilityListMenuItem.Command = new AsyncRelayCommand(CompatibilityList.Show);
|
|
||||||
|
|
||||||
UpdateMenuItem.Command = new AsyncRelayCommand(async () =>
|
UpdateMenuItem.Command = Commands.Create(async () =>
|
||||||
{
|
{
|
||||||
if (Updater.CanUpdate(true))
|
if (Updater.CanUpdate(true))
|
||||||
await Updater.BeginUpdateAsync(true);
|
await Updater.BeginUpdateAsync(true);
|
||||||
@@ -64,12 +58,12 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
|
|
||||||
FaqMenuItem.Command =
|
FaqMenuItem.Command =
|
||||||
SetupGuideMenuItem.Command =
|
SetupGuideMenuItem.Command =
|
||||||
LdnGuideMenuItem.Command = new RelayCommand<string>(OpenHelper.OpenUrl);
|
LdnGuideMenuItem.Command = Commands.Create<string>(OpenHelper.OpenUrl);
|
||||||
|
|
||||||
WindowSize720PMenuItem.Command =
|
WindowSize720PMenuItem.Command =
|
||||||
WindowSize1080PMenuItem.Command =
|
WindowSize1080PMenuItem.Command =
|
||||||
WindowSize1440PMenuItem.Command =
|
WindowSize1440PMenuItem.Command =
|
||||||
WindowSize2160PMenuItem.Command = new RelayCommand<string>(ChangeWindowSize);
|
WindowSize2160PMenuItem.Command = Commands.Create<string>(ChangeWindowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<CheckBox> GenerateToggleFileTypeItems() =>
|
private IEnumerable<CheckBox> GenerateToggleFileTypeItems() =>
|
||||||
|
|||||||
@@ -105,6 +105,12 @@
|
|||||||
GroupName="Sort"
|
GroupName="Sort"
|
||||||
IsChecked="{Binding IsSortedByTitle, Mode=OneTime}"
|
IsChecked="{Binding IsSortedByTitle, Mode=OneTime}"
|
||||||
Tag="Title" />
|
Tag="Title" />
|
||||||
|
<RadioButton
|
||||||
|
Checked="Sort_Checked"
|
||||||
|
Content="{ext:Locale DlcManagerTableHeadingTitleIdLabel}"
|
||||||
|
GroupName="Sort"
|
||||||
|
IsChecked="{Binding IsSortedByTitleId, Mode=OneTime}"
|
||||||
|
Tag="TitleId" />
|
||||||
<RadioButton
|
<RadioButton
|
||||||
Checked="Sort_Checked"
|
Checked="Sort_Checked"
|
||||||
Content="{ext:Locale GameListHeaderDeveloper}"
|
Content="{ext:Locale GameListHeaderDeveloper}"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<TextBlock
|
<TextBlock
|
||||||
Foreground="{DynamicResource SecondaryTextColor}"
|
Foreground="{DynamicResource SecondaryTextColor}"
|
||||||
TextDecorations="Underline"
|
TextDecorations="Underline"
|
||||||
Text="Game-specific hacks & tricks to alleviate performance issues or crashing. Will cause issues." />
|
Text="Highly specific hacks & tricks to alleviate performance issues, crashing, or freezing. Will cause issues." />
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Margin="0,10,0,0"
|
Margin="0,10,0,0"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
|
|||||||
@@ -114,8 +114,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
MinWidth="90"
|
MinWidth="90"
|
||||||
Margin="10,0,0,0"
|
Margin="10,0,0,0"
|
||||||
ToolTip.Tip="{ext:Locale AddGameDirTooltip}"
|
ToolTip.Tip="{ext:Locale AddGameDirTooltip}">
|
||||||
Click="AddGameDirButton_OnClick">
|
|
||||||
<TextBlock HorizontalAlignment="Center"
|
<TextBlock HorizontalAlignment="Center"
|
||||||
Text="{ext:Locale SettingsTabGeneralAdd}" />
|
Text="{ext:Locale SettingsTabGeneralAdd}" />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -168,8 +167,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
MinWidth="90"
|
MinWidth="90"
|
||||||
Margin="10,0,0,0"
|
Margin="10,0,0,0"
|
||||||
ToolTip.Tip="{ext:Locale AddAutoloadDirTooltip}"
|
ToolTip.Tip="{ext:Locale AddAutoloadDirTooltip}">
|
||||||
Click="AddAutoloadDirButton_OnClick">
|
|
||||||
<TextBlock HorizontalAlignment="Center"
|
<TextBlock HorizontalAlignment="Center"
|
||||||
Text="{ext:Locale SettingsTabGeneralAdd}" />
|
Text="{ext:Locale SettingsTabGeneralAdd}" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
|
using Avalonia.Collections;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using Avalonia.VisualTree;
|
using Avalonia.VisualTree;
|
||||||
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using Ryujinx.Ava.Utilities;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Views.Settings
|
namespace Ryujinx.Ava.UI.Views.Settings
|
||||||
{
|
{
|
||||||
@@ -18,31 +23,39 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
ShowTitleBarBox.IsVisible = OperatingSystem.IsWindows();
|
ShowTitleBarBox.IsVisible = OperatingSystem.IsWindows();
|
||||||
|
AddGameDirButton.Command =
|
||||||
|
Commands.Create(() => AddDirButton(GameDirPathBox, ViewModel.GameDirectories, true));
|
||||||
|
AddAutoloadDirButton.Command =
|
||||||
|
Commands.Create(() => AddDirButton(AutoloadDirPathBox, ViewModel.AutoloadDirectories, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void AddGameDirButton_OnClick(object sender, RoutedEventArgs e)
|
private async Task AddDirButton(TextBox addDirBox, AvaloniaList<string> directories, bool isGameList)
|
||||||
{
|
{
|
||||||
string path = GameDirPathBox.Text;
|
string path = addDirBox.Text;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path))
|
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !directories.Contains(path))
|
||||||
{
|
{
|
||||||
ViewModel.GameDirectories.Add(path);
|
directories.Add(path);
|
||||||
ViewModel.GameDirectoryChanged = true;
|
|
||||||
|
addDirBox.Clear();
|
||||||
|
|
||||||
|
if (isGameList)
|
||||||
|
ViewModel.GameDirectoryChanged = true;
|
||||||
|
else
|
||||||
|
ViewModel.AutoloadDirectoryChanged = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this.GetVisualRoot() is Window window)
|
Optional<IStorageFolder> folder = await RyujinxApp.MainWindow.ViewModel.StorageProvider.OpenSingleFolderPickerAsync();
|
||||||
{
|
|
||||||
var result = await window.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
|
||||||
{
|
|
||||||
AllowMultiple = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result.Count > 0)
|
if (folder.HasValue)
|
||||||
{
|
{
|
||||||
ViewModel.GameDirectories.Add(result[0].Path.LocalPath);
|
directories.Add(folder.Value.Path.LocalPath);
|
||||||
|
|
||||||
|
if (isGameList)
|
||||||
ViewModel.GameDirectoryChanged = true;
|
ViewModel.GameDirectoryChanged = true;
|
||||||
}
|
else
|
||||||
|
ViewModel.AutoloadDirectoryChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,33 +76,6 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void AddAutoloadDirButton_OnClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
string path = AutoloadDirPathBox.Text;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.AutoloadDirectories.Contains(path))
|
|
||||||
{
|
|
||||||
ViewModel.AutoloadDirectories.Add(path);
|
|
||||||
ViewModel.AutoloadDirectoryChanged = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (this.GetVisualRoot() is Window window)
|
|
||||||
{
|
|
||||||
var result = await window.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
|
||||||
{
|
|
||||||
AllowMultiple = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result.Count > 0)
|
|
||||||
{
|
|
||||||
ViewModel.AutoloadDirectories.Add(result[0].Path.LocalPath);
|
|
||||||
ViewModel.AutoloadDirectoryChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveAutoloadDirButton_OnClick(object sender, RoutedEventArgs e)
|
private void RemoveAutoloadDirButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
int oldIndex = AutoloadDirsList.SelectedIndex;
|
int oldIndex = AutoloadDirsList.SelectedIndex;
|
||||||
|
|||||||
@@ -182,7 +182,7 @@
|
|||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
Click="Button_OnClick"
|
Click="Button_OnClick"
|
||||||
Tag="https://github.com/GreemDev/Ryujinx/graphs/contributors?type=a">
|
Tag="https://github.com/Ryubing/Ryujinx/graphs/contributors?type=a">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
FontSize="10"
|
FontSize="10"
|
||||||
Text="{ext:Locale AboutRyujinxContributorsButtonHeader}"
|
Text="{ext:Locale AboutRyujinxContributorsButtonHeader}"
|
||||||
|
|||||||
@@ -14,9 +14,6 @@
|
|||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
x:DataType="viewModels:DownloadableContentManagerViewModel"
|
x:DataType="viewModels:DownloadableContentManagerViewModel"
|
||||||
Focusable="True">
|
Focusable="True">
|
||||||
<UserControl.Resources>
|
|
||||||
<helpers:DownloadableContentLabelConverter x:Key="DownloadableContentLabel" />
|
|
||||||
</UserControl.Resources>
|
|
||||||
<Grid RowDefinitions="Auto,Auto,*,Auto">
|
<Grid RowDefinitions="Auto,Auto,*,Auto">
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
@@ -89,7 +86,7 @@
|
|||||||
<ListBox.DataTemplates>
|
<ListBox.DataTemplates>
|
||||||
<DataTemplate
|
<DataTemplate
|
||||||
DataType="models:DownloadableContentModel">
|
DataType="models:DownloadableContentModel">
|
||||||
<Panel Margin="10">
|
<Panel Margin="10" Background="Transparent">
|
||||||
<Grid ColumnDefinitions="*,Auto">
|
<Grid ColumnDefinitions="*,Auto">
|
||||||
<Grid
|
<Grid
|
||||||
Grid.Column="0" ColumnDefinitions="*,Auto">
|
Grid.Column="0" ColumnDefinitions="*,Auto">
|
||||||
@@ -101,7 +98,7 @@
|
|||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
TextTrimming="CharacterEllipsis">
|
TextTrimming="CharacterEllipsis">
|
||||||
<TextBlock.Text>
|
<TextBlock.Text>
|
||||||
<MultiBinding Converter="{StaticResource DownloadableContentLabel}">
|
<MultiBinding Converter="{x:Static helpers:DownloadableContentLabelConverter.Instance}">
|
||||||
<Binding Path="FileName" />
|
<Binding Path="FileName" />
|
||||||
<Binding Path="IsBundled" />
|
<Binding Path="IsBundled" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
@@ -112,7 +109,7 @@
|
|||||||
Margin="10 0"
|
Margin="10 0"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{Binding TitleId}" />
|
Text="{Binding TitleIdStr}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
|
using Ryujinx.Ava.Common;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Common.Models;
|
using Ryujinx.Ava.Common.Models;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
|||||||
@@ -691,6 +691,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
ApplicationLibrary.LoadApplications(ConfigurationState.Instance.UI.GameDirs);
|
ApplicationLibrary.LoadApplications(ConfigurationState.Instance.UI.GameDirs);
|
||||||
|
|
||||||
var autoloadDirs = ConfigurationState.Instance.UI.AutoloadDirs.Value;
|
var autoloadDirs = ConfigurationState.Instance.UI.AutoloadDirs.Value;
|
||||||
|
autoloadDirs.ForEach(dir => Logger.Info?.Print(LogClass.Application, $"Auto loading DLC & updates from: {dir}"));
|
||||||
if (autoloadDirs.Count > 0)
|
if (autoloadDirs.Count > 0)
|
||||||
{
|
{
|
||||||
var updatesLoaded = ApplicationLibrary.AutoLoadTitleUpdates(autoloadDirs, out int updatesRemoved);
|
var updatesLoaded = ApplicationLibrary.AutoLoadTitleUpdates(autoloadDirs, out int updatesRemoved);
|
||||||
@@ -735,9 +736,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool _intelMacWarningShown = !(OperatingSystem.IsMacOS() &&
|
private static bool _intelMacWarningShown = !RunningPlatform.IsIntelMac;
|
||||||
(RuntimeInformation.OSArchitecture == Architecture.X64 ||
|
|
||||||
RuntimeInformation.OSArchitecture == Architecture.X86));
|
|
||||||
|
|
||||||
public static async Task ShowIntelMacWarningAsync()
|
public static async Task ShowIntelMacWarningAsync()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,15 +28,15 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task Show(MainWindowViewModel mainWindowViewModel)
|
public static async Task Show()
|
||||||
{
|
{
|
||||||
ContentDialog contentDialog = new()
|
ContentDialog contentDialog = new()
|
||||||
{
|
{
|
||||||
PrimaryButtonText = string.Empty,
|
PrimaryButtonText = string.Empty,
|
||||||
SecondaryButtonText = string.Empty,
|
SecondaryButtonText = string.Empty,
|
||||||
CloseButtonText = string.Empty,
|
CloseButtonText = string.Empty,
|
||||||
Content = new XCITrimmerWindow(mainWindowViewModel),
|
Content = new XCITrimmerWindow(RyujinxApp.MainWindow.ViewModel),
|
||||||
Title = string.Format(LocaleManager.Instance[LocaleKeys.XCITrimmerWindowTitle]),
|
Title = LocaleManager.Instance[LocaleKeys.XCITrimmerWindowTitle]
|
||||||
};
|
};
|
||||||
|
|
||||||
Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
|
Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.Info?.Print(LogClass.Application, "Checking for updates.");
|
||||||
|
|
||||||
// Get latest version number from GitHub API
|
// Get latest version number from GitHub API
|
||||||
try
|
try
|
||||||
@@ -140,6 +142,8 @@ namespace Ryujinx.Ava
|
|||||||
OpenHelper.OpenUrl(ReleaseInformation.GetChangelogForVersion(currentVersion));
|
OpenHelper.OpenUrl(ReleaseInformation.GetChangelogForVersion(currentVersion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.Info?.Print(LogClass.Application, "Up to date.");
|
||||||
|
|
||||||
_running = false;
|
_running = false;
|
||||||
|
|
||||||
@@ -214,6 +218,8 @@ namespace Ryujinx.Ava
|
|||||||
? $"Canary {currentVersion} -> Canary {newVersion}"
|
? $"Canary {currentVersion} -> Canary {newVersion}"
|
||||||
: $"{currentVersion} -> {newVersion}";
|
: $"{currentVersion} -> {newVersion}";
|
||||||
|
|
||||||
|
Logger.Info?.Print(LogClass.Application, $"Version found: {newVersionString}");
|
||||||
|
|
||||||
RequestUserToUpdate:
|
RequestUserToUpdate:
|
||||||
// Show a message asking the user if they want to update
|
// Show a message asking the user if they want to update
|
||||||
UserResult shouldUpdate = await ContentDialogHelper.CreateUpdaterChoiceDialog(
|
UserResult shouldUpdate = await ContentDialogHelper.CreateUpdaterChoiceDialog(
|
||||||
|
|||||||
@@ -840,7 +840,6 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Remove any downloadable content which can no longer be located on disk
|
// Remove any downloadable content which can no longer be located on disk
|
||||||
Logger.Notice.Print(LogClass.Application, $"Removing non-existing Title DLCs");
|
|
||||||
var dlcToRemove = _downloadableContents.Items
|
var dlcToRemove = _downloadableContents.Items
|
||||||
.Where(dlc => !File.Exists(dlc.Dlc.ContainerPath))
|
.Where(dlc => !File.Exists(dlc.Dlc.ContainerPath))
|
||||||
.ToList();
|
.ToList();
|
||||||
@@ -852,8 +851,6 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
|
|
||||||
foreach (string appDir in appDirs)
|
foreach (string appDir in appDirs)
|
||||||
{
|
{
|
||||||
Logger.Notice.Print(LogClass.Application, $"Auto loading DLC from: {appDir}");
|
|
||||||
|
|
||||||
if (_cancellationToken.Token.IsCancellationRequested)
|
if (_cancellationToken.Token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
return newDlcLoaded;
|
return newDlcLoaded;
|
||||||
@@ -956,7 +953,6 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
var titleIdsToRefresh = new HashSet<ulong>();
|
var titleIdsToRefresh = new HashSet<ulong>();
|
||||||
|
|
||||||
// Remove any updates which can no longer be located on disk
|
// Remove any updates which can no longer be located on disk
|
||||||
Logger.Notice.Print(LogClass.Application, $"Removing non-existing Title Updates");
|
|
||||||
var updatesToRemove = _titleUpdates.Items
|
var updatesToRemove = _titleUpdates.Items
|
||||||
.Where(it => !File.Exists(it.TitleUpdate.Path))
|
.Where(it => !File.Exists(it.TitleUpdate.Path))
|
||||||
.ToList();
|
.ToList();
|
||||||
@@ -971,8 +967,6 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
|
|
||||||
foreach (string appDir in appDirs)
|
foreach (string appDir in appDirs)
|
||||||
{
|
{
|
||||||
Logger.Notice.Print(LogClass.Application, $"Auto loading updates from: {appDir}");
|
|
||||||
|
|
||||||
if (_cancellationToken.Token.IsCancellationRequested)
|
if (_cancellationToken.Token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
return numUpdatesLoaded;
|
return numUpdatesLoaded;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current version of the file format
|
/// The current version of the file format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CurrentVersion = 59;
|
public const int CurrentVersion = 61;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the configuration file format
|
/// Version of the configuration file format
|
||||||
@@ -351,6 +351,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool StartFullscreen { get; set; }
|
public bool StartFullscreen { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start games with UI hidden
|
||||||
|
/// </summary>
|
||||||
|
public bool StartNoUI { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Show console window
|
/// Show console window
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
EnableDiscordIntegration.Value = cff.EnableDiscordIntegration;
|
EnableDiscordIntegration.Value = cff.EnableDiscordIntegration;
|
||||||
CheckUpdatesOnStart.Value = cff.CheckUpdatesOnStart;
|
CheckUpdatesOnStart.Value = cff.CheckUpdatesOnStart;
|
||||||
ShowConfirmExit.Value = cff.ShowConfirmExit;
|
ShowConfirmExit.Value = cff.ShowConfirmExit;
|
||||||
IgnoreApplet.Value = cff.IgnoreApplet;
|
|
||||||
RememberWindowState.Value = cff.RememberWindowState;
|
RememberWindowState.Value = cff.RememberWindowState;
|
||||||
ShowTitleBar.Value = cff.ShowTitleBar;
|
ShowTitleBar.Value = cff.ShowTitleBar;
|
||||||
EnableHardwareAcceleration.Value = cff.EnableHardwareAcceleration;
|
EnableHardwareAcceleration.Value = cff.EnableHardwareAcceleration;
|
||||||
@@ -97,6 +96,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
System.MemoryManagerMode.Value = cff.MemoryManagerMode;
|
System.MemoryManagerMode.Value = cff.MemoryManagerMode;
|
||||||
System.DramSize.Value = cff.DramSize;
|
System.DramSize.Value = cff.DramSize;
|
||||||
System.IgnoreMissingServices.Value = cff.IgnoreMissingServices;
|
System.IgnoreMissingServices.Value = cff.IgnoreMissingServices;
|
||||||
|
System.IgnoreApplet.Value = cff.IgnoreApplet;
|
||||||
System.UseHypervisor.Value = cff.UseHypervisor;
|
System.UseHypervisor.Value = cff.UseHypervisor;
|
||||||
|
|
||||||
UI.GuiColumns.FavColumn.Value = cff.GuiColumns.FavColumn;
|
UI.GuiColumns.FavColumn.Value = cff.GuiColumns.FavColumn;
|
||||||
@@ -127,6 +127,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
UI.GridSize.Value = cff.GridSize;
|
UI.GridSize.Value = cff.GridSize;
|
||||||
UI.ApplicationSort.Value = cff.ApplicationSort;
|
UI.ApplicationSort.Value = cff.ApplicationSort;
|
||||||
UI.StartFullscreen.Value = cff.StartFullscreen;
|
UI.StartFullscreen.Value = cff.StartFullscreen;
|
||||||
|
UI.StartNoUI.Value = cff.StartNoUI;
|
||||||
UI.ShowConsole.Value = cff.ShowConsole;
|
UI.ShowConsole.Value = cff.ShowConsole;
|
||||||
UI.WindowStartup.WindowSizeWidth.Value = cff.WindowStartup.WindowSizeWidth;
|
UI.WindowStartup.WindowSizeWidth.Value = cff.WindowStartup.WindowSizeWidth;
|
||||||
UI.WindowStartup.WindowSizeHeight.Value = cff.WindowStartup.WindowSizeHeight;
|
UI.WindowStartup.WindowSizeHeight.Value = cff.WindowStartup.WindowSizeHeight;
|
||||||
@@ -262,15 +263,12 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
}),
|
}),
|
||||||
(30, static cff =>
|
(30, static cff =>
|
||||||
{
|
{
|
||||||
foreach (InputConfig config in cff.InputConfig)
|
foreach (StandardControllerInputConfig config in cff.InputConfig.OfType<StandardControllerInputConfig>())
|
||||||
{
|
{
|
||||||
if (config is StandardControllerInputConfig controllerConfig)
|
config.Rumble = new RumbleConfigController
|
||||||
{
|
{
|
||||||
controllerConfig.Rumble = new RumbleConfigController
|
EnableRumble = false, StrongRumble = 1f, WeakRumble = 1f,
|
||||||
{
|
};
|
||||||
EnableRumble = false, StrongRumble = 1f, WeakRumble = 1f,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
(31, static cff => cff.BackendThreading = BackendThreading.Auto),
|
(31, static cff => cff.BackendThreading = BackendThreading.Auto),
|
||||||
@@ -414,6 +412,18 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
// This was accidentally enabled by default when it was PRed. That is not what we want,
|
// This was accidentally enabled by default when it was PRed. That is not what we want,
|
||||||
// so as a compromise users who want to use it will simply need to re-enable it once after updating.
|
// so as a compromise users who want to use it will simply need to re-enable it once after updating.
|
||||||
cff.IgnoreApplet = false;
|
cff.IgnoreApplet = false;
|
||||||
|
}),
|
||||||
|
(60, static cff => cff.StartNoUI = false),
|
||||||
|
(61, static cff =>
|
||||||
|
{
|
||||||
|
foreach (StandardControllerInputConfig config in cff.InputConfig.OfType<StandardControllerInputConfig>())
|
||||||
|
{
|
||||||
|
config.Led = new LedConfigController
|
||||||
|
{
|
||||||
|
EnableLed = false,
|
||||||
|
LedColor = 328189
|
||||||
|
};
|
||||||
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> StartFullscreen { get; private set; }
|
public ReactiveObject<bool> StartFullscreen { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start games with UI hidden
|
||||||
|
/// </summary>
|
||||||
|
public ReactiveObject<bool> StartNoUI { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hide / Show Console Window
|
/// Hide / Show Console Window
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -192,6 +197,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
WindowStartup = new WindowStartupSettings();
|
WindowStartup = new WindowStartupSettings();
|
||||||
BaseStyle = new ReactiveObject<string>();
|
BaseStyle = new ReactiveObject<string>();
|
||||||
StartFullscreen = new ReactiveObject<bool>();
|
StartFullscreen = new ReactiveObject<bool>();
|
||||||
|
StartNoUI = new ReactiveObject<bool>();
|
||||||
GameListViewMode = new ReactiveObject<int>();
|
GameListViewMode = new ReactiveObject<int>();
|
||||||
ShowNames = new ReactiveObject<bool>();
|
ShowNames = new ReactiveObject<bool>();
|
||||||
GridSize = new ReactiveObject<int>();
|
GridSize = new ReactiveObject<int>();
|
||||||
@@ -360,6 +366,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// Enable or disable ignoring missing services
|
/// Enable or disable ignoring missing services
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> IgnoreMissingServices { get; private set; }
|
public ReactiveObject<bool> IgnoreMissingServices { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ignore Controller Applet
|
||||||
|
/// </summary>
|
||||||
|
public ReactiveObject<bool> IgnoreApplet { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Uses Hypervisor over JIT if available
|
/// Uses Hypervisor over JIT if available
|
||||||
@@ -398,6 +409,8 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
DramSize.LogChangesToValue(nameof(DramSize));
|
DramSize.LogChangesToValue(nameof(DramSize));
|
||||||
IgnoreMissingServices = new ReactiveObject<bool>();
|
IgnoreMissingServices = new ReactiveObject<bool>();
|
||||||
IgnoreMissingServices.LogChangesToValue(nameof(IgnoreMissingServices));
|
IgnoreMissingServices.LogChangesToValue(nameof(IgnoreMissingServices));
|
||||||
|
IgnoreApplet = new ReactiveObject<bool>();
|
||||||
|
IgnoreApplet.LogChangesToValue(nameof(IgnoreApplet));
|
||||||
AudioVolume = new ReactiveObject<float>();
|
AudioVolume = new ReactiveObject<float>();
|
||||||
AudioVolume.LogChangesToValue(nameof(AudioVolume));
|
AudioVolume.LogChangesToValue(nameof(AudioVolume));
|
||||||
UseHypervisor = new ReactiveObject<bool>();
|
UseHypervisor = new ReactiveObject<bool>();
|
||||||
@@ -739,11 +752,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> ShowConfirmExit { get; private set; }
|
public ReactiveObject<bool> ShowConfirmExit { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ignore Applet
|
|
||||||
/// </summary>
|
|
||||||
public ReactiveObject<bool> IgnoreApplet { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables or disables save window size, position and state on close.
|
/// Enables or disables save window size, position and state on close.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -776,8 +784,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
EnableDiscordIntegration = new ReactiveObject<bool>();
|
EnableDiscordIntegration = new ReactiveObject<bool>();
|
||||||
CheckUpdatesOnStart = new ReactiveObject<bool>();
|
CheckUpdatesOnStart = new ReactiveObject<bool>();
|
||||||
ShowConfirmExit = new ReactiveObject<bool>();
|
ShowConfirmExit = new ReactiveObject<bool>();
|
||||||
IgnoreApplet = new ReactiveObject<bool>();
|
|
||||||
IgnoreApplet.LogChangesToValue(nameof(IgnoreApplet));
|
|
||||||
RememberWindowState = new ReactiveObject<bool>();
|
RememberWindowState = new ReactiveObject<bool>();
|
||||||
ShowTitleBar = new ReactiveObject<bool>();
|
ShowTitleBar = new ReactiveObject<bool>();
|
||||||
EnableHardwareAcceleration = new ReactiveObject<bool>();
|
EnableHardwareAcceleration = new ReactiveObject<bool>();
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
EnableDiscordIntegration = EnableDiscordIntegration,
|
EnableDiscordIntegration = EnableDiscordIntegration,
|
||||||
CheckUpdatesOnStart = CheckUpdatesOnStart,
|
CheckUpdatesOnStart = CheckUpdatesOnStart,
|
||||||
ShowConfirmExit = ShowConfirmExit,
|
ShowConfirmExit = ShowConfirmExit,
|
||||||
IgnoreApplet = IgnoreApplet,
|
|
||||||
RememberWindowState = RememberWindowState,
|
RememberWindowState = RememberWindowState,
|
||||||
ShowTitleBar = ShowTitleBar,
|
ShowTitleBar = ShowTitleBar,
|
||||||
EnableHardwareAcceleration = EnableHardwareAcceleration,
|
EnableHardwareAcceleration = EnableHardwareAcceleration,
|
||||||
@@ -78,6 +77,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
MemoryManagerMode = System.MemoryManagerMode,
|
MemoryManagerMode = System.MemoryManagerMode,
|
||||||
DramSize = System.DramSize,
|
DramSize = System.DramSize,
|
||||||
IgnoreMissingServices = System.IgnoreMissingServices,
|
IgnoreMissingServices = System.IgnoreMissingServices,
|
||||||
|
IgnoreApplet = System.IgnoreApplet,
|
||||||
UseHypervisor = System.UseHypervisor,
|
UseHypervisor = System.UseHypervisor,
|
||||||
GuiColumns = new GuiColumns
|
GuiColumns = new GuiColumns
|
||||||
{
|
{
|
||||||
@@ -125,6 +125,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
ApplicationSort = UI.ApplicationSort,
|
ApplicationSort = UI.ApplicationSort,
|
||||||
IsAscendingOrder = UI.IsAscendingOrder,
|
IsAscendingOrder = UI.IsAscendingOrder,
|
||||||
StartFullscreen = UI.StartFullscreen,
|
StartFullscreen = UI.StartFullscreen,
|
||||||
|
StartNoUI = UI.StartNoUI,
|
||||||
ShowConsole = UI.ShowConsole,
|
ShowConsole = UI.ShowConsole,
|
||||||
EnableKeyboard = Hid.EnableKeyboard,
|
EnableKeyboard = Hid.EnableKeyboard,
|
||||||
EnableMouse = Hid.EnableMouse,
|
EnableMouse = Hid.EnableMouse,
|
||||||
@@ -175,7 +176,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
EnableDiscordIntegration.Value = true;
|
EnableDiscordIntegration.Value = true;
|
||||||
CheckUpdatesOnStart.Value = true;
|
CheckUpdatesOnStart.Value = true;
|
||||||
ShowConfirmExit.Value = true;
|
ShowConfirmExit.Value = true;
|
||||||
IgnoreApplet.Value = false;
|
|
||||||
RememberWindowState.Value = true;
|
RememberWindowState.Value = true;
|
||||||
ShowTitleBar.Value = !OperatingSystem.IsWindows();
|
ShowTitleBar.Value = !OperatingSystem.IsWindows();
|
||||||
EnableHardwareAcceleration.Value = true;
|
EnableHardwareAcceleration.Value = true;
|
||||||
@@ -199,6 +199,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
System.MemoryManagerMode.Value = MemoryManagerMode.HostMappedUnsafe;
|
System.MemoryManagerMode.Value = MemoryManagerMode.HostMappedUnsafe;
|
||||||
System.DramSize.Value = MemoryConfiguration.MemoryConfiguration4GiB;
|
System.DramSize.Value = MemoryConfiguration.MemoryConfiguration4GiB;
|
||||||
System.IgnoreMissingServices.Value = false;
|
System.IgnoreMissingServices.Value = false;
|
||||||
|
System.IgnoreApplet.Value = false;
|
||||||
System.UseHypervisor.Value = true;
|
System.UseHypervisor.Value = true;
|
||||||
Multiplayer.LanInterfaceId.Value = "0";
|
Multiplayer.LanInterfaceId.Value = "0";
|
||||||
Multiplayer.Mode.Value = MultiplayerMode.Disabled;
|
Multiplayer.Mode.Value = MultiplayerMode.Disabled;
|
||||||
@@ -233,6 +234,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
UI.ApplicationSort.Value = 0;
|
UI.ApplicationSort.Value = 0;
|
||||||
UI.IsAscendingOrder.Value = true;
|
UI.IsAscendingOrder.Value = true;
|
||||||
UI.StartFullscreen.Value = false;
|
UI.StartFullscreen.Value = false;
|
||||||
|
UI.StartNoUI.Value = false;
|
||||||
UI.ShowConsole.Value = true;
|
UI.ShowConsole.Value = true;
|
||||||
UI.WindowStartup.WindowSizeWidth.Value = 1280;
|
UI.WindowStartup.WindowSizeWidth.Value = 1280;
|
||||||
UI.WindowStartup.WindowSizeHeight.Value = 760;
|
UI.WindowStartup.WindowSizeHeight.Value = 760;
|
||||||
|
|||||||
47
src/Ryujinx/Utilities/StorageProviderExtensions.cs
Normal file
47
src/Ryujinx/Utilities/StorageProviderExtensions.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using Avalonia.Platform.Storage;
|
||||||
|
using Gommon;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.Utilities
|
||||||
|
{
|
||||||
|
public static class StorageProviderExtensions
|
||||||
|
{
|
||||||
|
public static async Task<Optional<IStorageFolder>> OpenSingleFolderPickerAsync(this IStorageProvider storageProvider, FolderPickerOpenOptions openOptions = null) =>
|
||||||
|
await storageProvider.OpenFolderPickerAsync(FixOpenOptions(openOptions, false))
|
||||||
|
.Then(folders => folders.FindFirst());
|
||||||
|
|
||||||
|
public static async Task<Optional<IStorageFile>> OpenSingleFilePickerAsync(this IStorageProvider storageProvider, FilePickerOpenOptions openOptions = null) =>
|
||||||
|
await storageProvider.OpenFilePickerAsync(FixOpenOptions(openOptions, false))
|
||||||
|
.Then(files => files.FindFirst());
|
||||||
|
|
||||||
|
public static async Task<Optional<IReadOnlyList<IStorageFolder>>> OpenMultiFolderPickerAsync(this IStorageProvider storageProvider, FolderPickerOpenOptions openOptions = null) =>
|
||||||
|
await storageProvider.OpenFolderPickerAsync(FixOpenOptions(openOptions, true))
|
||||||
|
.Then(folders => folders.Count > 0 ? Optional.Of(folders) : default);
|
||||||
|
|
||||||
|
public static async Task<Optional<IReadOnlyList<IStorageFile>>> OpenMultiFilePickerAsync(this IStorageProvider storageProvider, FilePickerOpenOptions openOptions = null) =>
|
||||||
|
await storageProvider.OpenFilePickerAsync(FixOpenOptions(openOptions, true))
|
||||||
|
.Then(files => files.Count > 0 ? Optional.Of(files) : default);
|
||||||
|
|
||||||
|
private static FilePickerOpenOptions FixOpenOptions(this FilePickerOpenOptions openOptions, bool allowMultiple)
|
||||||
|
{
|
||||||
|
if (openOptions is null)
|
||||||
|
return new FilePickerOpenOptions { AllowMultiple = allowMultiple };
|
||||||
|
|
||||||
|
openOptions.AllowMultiple = allowMultiple;
|
||||||
|
|
||||||
|
return openOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FolderPickerOpenOptions FixOpenOptions(this FolderPickerOpenOptions openOptions, bool allowMultiple)
|
||||||
|
{
|
||||||
|
if (openOptions is null)
|
||||||
|
return new FolderPickerOpenOptions { AllowMultiple = allowMultiple };
|
||||||
|
|
||||||
|
openOptions.AllowMultiple = allowMultiple;
|
||||||
|
|
||||||
|
return openOptions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user