Compare commits
18 Commits
feature/av
...
d1824c5cb6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1824c5cb6 | ||
|
|
17233d30da | ||
|
|
2bf48f57d2 | ||
|
|
412d4065b8 | ||
|
|
e6644626fc | ||
|
|
0bacdb8765 | ||
|
|
0ca4d6e921 | ||
|
|
f0aa7eedf6 | ||
|
|
41acc4b1f3 | ||
|
|
7aede70ba9 | ||
|
|
a0a4f78cff | ||
|
|
0502da96cd | ||
|
|
7df0fb587e | ||
|
|
50847f0687 | ||
|
|
125f6d2777 | ||
|
|
dfc4831828 | ||
|
|
45feeae9db | ||
|
|
e67df5219c |
@@ -1,4 +1,5 @@
|
|||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
|
using Humanizer;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
@@ -58,8 +59,8 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
{
|
{
|
||||||
_ptc = ptc;
|
_ptc = ptc;
|
||||||
|
|
||||||
_timer = new Timer(SaveInterval * 1000d);
|
_timer = new Timer(SaveInterval.Seconds());
|
||||||
_timer.Elapsed += PreSave;
|
_timer.Elapsed += TimerElapsed;
|
||||||
|
|
||||||
_outerHeaderMagic = BinaryPrimitives.ReadUInt64LittleEndian(EncodingCache.UTF8NoBOM.GetBytes(OuterHeaderMagicString).AsSpan());
|
_outerHeaderMagic = BinaryPrimitives.ReadUInt64LittleEndian(EncodingCache.UTF8NoBOM.GetBytes(OuterHeaderMagicString).AsSpan());
|
||||||
|
|
||||||
@@ -72,6 +73,9 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
Enabled = false;
|
Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TimerElapsed(object _, ElapsedEventArgs __)
|
||||||
|
=> new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start();
|
||||||
|
|
||||||
public void AddEntry(ulong address, ExecutionMode mode, bool highCq)
|
public void AddEntry(ulong address, ExecutionMode mode, bool highCq)
|
||||||
{
|
{
|
||||||
if (IsAddressInStaticCodeRange(address))
|
if (IsAddressInStaticCodeRange(address))
|
||||||
@@ -262,7 +266,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
compressedStream.SetLength(0L);
|
compressedStream.SetLength(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreSave(object source, ElapsedEventArgs e)
|
private void PreSave()
|
||||||
{
|
{
|
||||||
_waitEvent.Reset();
|
_waitEvent.Reset();
|
||||||
|
|
||||||
@@ -428,7 +432,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
{
|
{
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
|
|
||||||
_timer.Elapsed -= PreSave;
|
_timer.Elapsed -= TimerElapsed;
|
||||||
_timer.Dispose();
|
_timer.Dispose();
|
||||||
|
|
||||||
Wait();
|
Wait();
|
||||||
|
|||||||
190
src/Ryujinx.Common/TitleIDs.cs
Normal file
190
src/Ryujinx.Common/TitleIDs.cs
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
using Gommon;
|
||||||
|
using Ryujinx.Common.Configuration;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common
|
||||||
|
{
|
||||||
|
public static class TitleIDs
|
||||||
|
{
|
||||||
|
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
|
||||||
|
{
|
||||||
|
switch (currentBackend)
|
||||||
|
{
|
||||||
|
case GraphicsBackend.OpenGl when OperatingSystem.IsMacOS():
|
||||||
|
return GraphicsBackend.Vulkan;
|
||||||
|
case GraphicsBackend.Vulkan or GraphicsBackend.OpenGl or GraphicsBackend.Metal:
|
||||||
|
return currentBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture is Architecture.Arm64))
|
||||||
|
return GraphicsBackend.Vulkan;
|
||||||
|
|
||||||
|
return GreatMetalTitles.ContainsIgnoreCase(titleId) ? GraphicsBackend.Metal : GraphicsBackend.Vulkan;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly string[] GreatMetalTitles =
|
||||||
|
[
|
||||||
|
"01006f8002326000", // Animal Crossings: New Horizons
|
||||||
|
"01009bf0072d4000", // Captain Toad: Treasure Tracker
|
||||||
|
"0100a5c00d162000", // Cuphead
|
||||||
|
"010023800d64a000", // Deltarune
|
||||||
|
"010028600EBDA000", // Mario 3D World
|
||||||
|
"0100152000022000", // Mario Kart 8 Deluxe
|
||||||
|
"01005CA01580E000", // Persona 5
|
||||||
|
"01008C0016544000", // Sea of Stars
|
||||||
|
"01006A800016E000", // Smash Ultimate
|
||||||
|
"0100000000010000", // Super Mario Odyessy
|
||||||
|
];
|
||||||
|
|
||||||
|
public static string GetDiscordGameAsset(string titleId)
|
||||||
|
=> DiscordGameAssetKeys.Contains(titleId) ? titleId : "game";
|
||||||
|
|
||||||
|
public static readonly string[] DiscordGameAssetKeys =
|
||||||
|
[
|
||||||
|
"010055d009f78000", // Fire Emblem: Three Houses
|
||||||
|
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
||||||
|
"0100a6301214e000", // Fire Emblem Engage
|
||||||
|
"0100f15003e64000", // Fire Emblem Warriors
|
||||||
|
"010071f0143ea000", // Fire Emblem Warriors: Three Hopes
|
||||||
|
|
||||||
|
"01007e3006dda000", // Kirby Star Allies
|
||||||
|
"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
|
||||||
|
|
||||||
|
"01007ef00011e000", // The Legend of Zelda: Breath of the Wild
|
||||||
|
"01006bb00c6f0000", // The Legend of Zelda: Link's Awakening
|
||||||
|
"01002da013484000", // The Legend of Zelda: Skyward Sword HD
|
||||||
|
"0100f2c0115b6000", // The Legend of Zelda: Tears of the Kingdom
|
||||||
|
"01008cf01baac000", // The Legend of Zelda: Echoes of Wisdom
|
||||||
|
"01000b900d8b0000", // Cadence of Hyrule
|
||||||
|
"0100ae00096ea000", // Hyrule Warriors: Definitive Edition
|
||||||
|
"01002b00111a2000", // Hyrule Warriors: Age of Calamity
|
||||||
|
|
||||||
|
"010048701995e000", // Luigi's Mansion 2 HD
|
||||||
|
"0100dca0064a6000", // Luigi's Mansion 3
|
||||||
|
|
||||||
|
"010093801237c000", // Metroid Dread
|
||||||
|
"010012101468c000", // Metroid Prime Remastered
|
||||||
|
|
||||||
|
"0100000000010000", // SUPER MARIO ODYSSEY
|
||||||
|
"0100ea80032ea000", // Super Mario Bros. U Deluxe
|
||||||
|
"01009b90006dc000", // Super Mario Maker 2
|
||||||
|
"010049900f546000", // Super Mario 3D All-Stars
|
||||||
|
"010049900F546001", // ^ 64
|
||||||
|
"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
|
||||||
|
"010067300059a000", // Mario + Rabbids: Kingdom Battle
|
||||||
|
"0100317013770000", // Mario + Rabbids: Sparks of Hope
|
||||||
|
"0100a3900c3e2000", // Paper Mario: The Origami King
|
||||||
|
"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
|
||||||
|
|
||||||
|
"0100aa80194b0000", // Pikmin 1
|
||||||
|
"0100d680194b2000", // Pikmin 2
|
||||||
|
"0100f4c009322000", // Pikmin 3 Deluxe
|
||||||
|
"0100b7c00933a000", // Pikmin 4
|
||||||
|
|
||||||
|
"010003f003a34000", // Pokémon: Let's Go Pikachu!
|
||||||
|
"0100187003a36000", // Pokémon: Let's Go Eevee!
|
||||||
|
"0100abf008968000", // Pokémon Sword
|
||||||
|
"01008db008c2c000", // Pokémon Shield
|
||||||
|
"0100000011d90000", // Pokémon Brilliant Diamond
|
||||||
|
"010018e011d92000", // Pokémon Shining Pearl
|
||||||
|
"01001f5010dfa000", // Pokémon Legends: Arceus
|
||||||
|
"0100a3d008c5c000", // Pokémon Scarlet
|
||||||
|
"01008f6008c5e000", // Pokémon Violet
|
||||||
|
"0100b3f000be2000", // Pokkén Tournament DX
|
||||||
|
"0100f4300bf2c000", // New Pokémon Snap
|
||||||
|
|
||||||
|
"01003bc0000a0000", // Splatoon 2 (US)
|
||||||
|
"0100f8f0000a2000", // Splatoon 2 (EU)
|
||||||
|
"01003c700009c000", // Splatoon 2 (JP)
|
||||||
|
"0100c2500fc20000", // Splatoon 3
|
||||||
|
"0100ba0018500000", // Splatoon 3: Splatfest World Premiere
|
||||||
|
|
||||||
|
"010040600c5ce000", // Tetris 99
|
||||||
|
"0100277011f1a000", // Super Mario Bros. 35
|
||||||
|
"0100ad9012510000", // PAC-MAN 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
|
||||||
|
"010012f017576000", // GBA - Nintendo Switch Online
|
||||||
|
|
||||||
|
"01000320000cc000", // 1-2 Switch
|
||||||
|
"0100300012f2a000", // Advance Wars 1+2: Re-Boot Camp
|
||||||
|
"01006f8002326000", // Animal Crossing: New Horizons
|
||||||
|
"0100620012d6e000", // Big Brain Academy: Brain vs. Brain
|
||||||
|
"010018300d006000", // BOXBOY! + BOXGIRL!
|
||||||
|
"0100c1f0051b6000", // Donkey Kong Country: Tropical Freeze
|
||||||
|
"0100ed000d390000", // Dr. Kawashima's Brain Training
|
||||||
|
"010067b017588000", // Endless Ocean Luminous
|
||||||
|
"0100d2f00d5c0000", // Nintendo Switch Sports
|
||||||
|
"01006b5012b32000", // Part Time UFO
|
||||||
|
"0100704000B3A000", // Snipperclips
|
||||||
|
"01006a800016e000", // Super Smash Bros. Ultimate
|
||||||
|
"0100a9400c9c2000", // Tokyo Mirage Sessions #FE Encore
|
||||||
|
|
||||||
|
"010076f0049a2000", // Bayonetta
|
||||||
|
"01007960049a0000", // Bayonetta 2
|
||||||
|
"01004a4010fea000", // Bayonetta 3
|
||||||
|
"0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon
|
||||||
|
|
||||||
|
"0100dcd01525a000", // Persona 3 Portable
|
||||||
|
"010062b01525c000", // Persona 4 Golden
|
||||||
|
"010075a016a3a000", // Persona 4 Arena Ultimax
|
||||||
|
"01005ca01580e000", // Persona 5 Royal
|
||||||
|
"0100801011c3e000", // Persona 5 Strikers
|
||||||
|
"010087701b092000", // Persona 5 Tactica
|
||||||
|
|
||||||
|
"01009aa000faa000", // Sonic Mania
|
||||||
|
"01004ad014bf0000", // Sonic Frontiers
|
||||||
|
"01005ea01c0fc000", // SONIC X SHADOW GENERATIONS
|
||||||
|
"01005ea01c0fc001", // ^
|
||||||
|
|
||||||
|
"010056e00853a000", // A Hat in Time
|
||||||
|
"0100dbf01000a000", // Burnout Paradise Remastered
|
||||||
|
"0100744001588000", // Cars 3: Driven to Win
|
||||||
|
"0100b41013c82000", // Cruis'n Blast
|
||||||
|
"01001b300b9be000", // Diablo III: Eternal Collection
|
||||||
|
"01008c8012920000", // Dying Light Platinum Edition
|
||||||
|
"010073c01af34000", // LEGO Horizon Adventures
|
||||||
|
"0100770008dd8000", // Monster Hunter Generations Ultimate
|
||||||
|
"0100b04011742000", // Monster Hunter Rise
|
||||||
|
"0100853015e86000", // No Man's Sky
|
||||||
|
"01007bb017812000", // Portal
|
||||||
|
"0100abd01785c000", // Portal 2
|
||||||
|
"01008e200c5c2000", // Muse Dash
|
||||||
|
"01007820196a6000", // Red Dead Redemption
|
||||||
|
"01002f7013224000", // Rune Factory 5
|
||||||
|
"01008d100d43e000", // Saints Row IV
|
||||||
|
"0100de600beee000", // Saints Row: The Third - The Full Package
|
||||||
|
"01001180021fa000", // Shovel Knight: Specter of Torment
|
||||||
|
"0100d7a01b7a2000", // Star Wars: Bounty Hunter
|
||||||
|
"0100800015926000", // Suika Game
|
||||||
|
"0100e46006708000", // Terraria
|
||||||
|
"01000a10041ea000", // The Elder Scrolls V: Skyrim
|
||||||
|
"010057a01e4d4000", // TSUKIHIME -A piece of blue glass moon-
|
||||||
|
"010080b00ad66000", // Undertale
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||||||
|
|
||||||
_current = new CounterQueueEvent(this, glType, 0);
|
_current = new CounterQueueEvent(this, glType, 0);
|
||||||
|
|
||||||
_consumerThread = new Thread(EventConsumer);
|
_consumerThread = new Thread(EventConsumer) { Name = "CPU.CounterQueue." + (int)type };
|
||||||
_consumerThread.Start();
|
_consumerThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
|
|
||||||
_current = new CounterQueueEvent(this, type, 0);
|
_current = new CounterQueueEvent(this, type, 0);
|
||||||
|
|
||||||
_consumerThread = new Thread(EventConsumer);
|
_consumerThread = new Thread(EventConsumer) { Name = "CPU.CounterQueue." + (int)type };
|
||||||
_consumerThread.Start();
|
_consumerThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1034,16 +1034,16 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
switch (fileName)
|
switch (fileName)
|
||||||
{
|
{
|
||||||
case "prod.keys":
|
case "prod.keys":
|
||||||
verified = verifyKeys(lines, genericPattern);
|
verified = VerifyKeys(lines, genericPattern);
|
||||||
break;
|
break;
|
||||||
case "title.keys":
|
case "title.keys":
|
||||||
verified = verifyKeys(lines, titlePattern);
|
verified = VerifyKeys(lines, titlePattern);
|
||||||
break;
|
break;
|
||||||
case "console.keys":
|
case "console.keys":
|
||||||
verified = verifyKeys(lines, genericPattern);
|
verified = VerifyKeys(lines, genericPattern);
|
||||||
break;
|
break;
|
||||||
case "dev.keys":
|
case "dev.keys":
|
||||||
verified = verifyKeys(lines, genericPattern);
|
verified = VerifyKeys(lines, genericPattern);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new FormatException($"Keys file name \"{fileName}\" not supported. Only \"prod.keys\", \"title.keys\", \"console.keys\", \"dev.keys\" are supported.");
|
throw new FormatException($"Keys file name \"{fileName}\" not supported. Only \"prod.keys\", \"title.keys\", \"console.keys\", \"dev.keys\" are supported.");
|
||||||
@@ -1056,20 +1056,22 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
{
|
{
|
||||||
throw new FileNotFoundException($"Keys file not found at \"{filePath}\".");
|
throw new FileNotFoundException($"Keys file not found at \"{filePath}\".");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private bool verifyKeys(string[] lines, string regex)
|
return;
|
||||||
{
|
|
||||||
foreach (string line in lines)
|
bool VerifyKeys(string[] lines, string regex)
|
||||||
{
|
{
|
||||||
if (!Regex.IsMatch(line, regex))
|
foreach (string line in lines)
|
||||||
{
|
{
|
||||||
return false;
|
if (!Regex.IsMatch(line, regex))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AreKeysAlredyPresent(string pathToCheck)
|
public bool AreKeysAlredyPresent(string pathToCheck)
|
||||||
{
|
{
|
||||||
string[] fileNames = { "prod.keys", "title.keys", "console.keys", "dev.keys" };
|
string[] fileNames = { "prod.keys", "title.keys", "console.keys", "dev.keys" };
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
|||||||
is64Bits = true;
|
is64Bits = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
HostThread = new Thread(ThreadStart);
|
HostThread = new Thread(ThreadStart) { Name = "HLE.KThread" };
|
||||||
|
|
||||||
Context = owner?.CreateExecutionContext() ?? new ProcessExecutionContext();
|
Context = owner?.CreateExecutionContext() ?? new ProcessExecutionContext();
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace Ryujinx.UI.Common
|
|||||||
{
|
{
|
||||||
Assets = new Assets
|
Assets = new Assets
|
||||||
{
|
{
|
||||||
LargeImageKey = _discordGameAssetKeys.Contains(procRes.ProgramIdText) ? procRes.ProgramIdText : "game",
|
LargeImageKey = TitleIDs.GetDiscordGameAsset(procRes.ProgramIdText),
|
||||||
LargeImageText = TruncateToByteLength($"{appMeta.Title} (v{procRes.DisplayVersion})"),
|
LargeImageText = TruncateToByteLength($"{appMeta.Title} (v{procRes.DisplayVersion})"),
|
||||||
SmallImageKey = "ryujinx",
|
SmallImageKey = "ryujinx",
|
||||||
SmallImageText = TruncateToByteLength(_description)
|
SmallImageText = TruncateToByteLength(_description)
|
||||||
@@ -122,151 +122,5 @@ namespace Ryujinx.UI.Common
|
|||||||
{
|
{
|
||||||
_discordClient?.Dispose();
|
_discordClient?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly string[] _discordGameAssetKeys =
|
|
||||||
[
|
|
||||||
"010055d009f78000", // Fire Emblem: Three Houses
|
|
||||||
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
|
||||||
"0100a6301214e000", // Fire Emblem Engage
|
|
||||||
"0100f15003e64000", // Fire Emblem Warriors
|
|
||||||
"010071f0143ea000", // Fire Emblem Warriors: Three Hopes
|
|
||||||
|
|
||||||
"01007e3006dda000", // Kirby Star Allies
|
|
||||||
"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
|
|
||||||
|
|
||||||
"01007ef00011e000", // The Legend of Zelda: Breath of the Wild
|
|
||||||
"01006bb00c6f0000", // The Legend of Zelda: Link's Awakening
|
|
||||||
"01002da013484000", // The Legend of Zelda: Skyward Sword HD
|
|
||||||
"0100f2c0115b6000", // The Legend of Zelda: Tears of the Kingdom
|
|
||||||
"01008cf01baac000", // The Legend of Zelda: Echoes of Wisdom
|
|
||||||
"01000b900d8b0000", // Cadence of Hyrule
|
|
||||||
"0100ae00096ea000", // Hyrule Warriors: Definitive Edition
|
|
||||||
"01002b00111a2000", // Hyrule Warriors: Age of Calamity
|
|
||||||
|
|
||||||
"010048701995e000", // Luigi's Mansion 2 HD
|
|
||||||
"0100dca0064a6000", // Luigi's Mansion 3
|
|
||||||
|
|
||||||
"010093801237c000", // Metroid Dread
|
|
||||||
"010012101468c000", // Metroid Prime Remastered
|
|
||||||
|
|
||||||
"0100000000010000", // SUPER MARIO ODYSSEY
|
|
||||||
"0100ea80032ea000", // Super Mario Bros. U Deluxe
|
|
||||||
"01009b90006dc000", // Super Mario Maker 2
|
|
||||||
"010049900f546000", // Super Mario 3D All-Stars
|
|
||||||
"010049900F546001", // ^ 64
|
|
||||||
"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
|
|
||||||
"010067300059a000", // Mario + Rabbids: Kingdom Battle
|
|
||||||
"0100317013770000", // Mario + Rabbids: Sparks of Hope
|
|
||||||
"0100a3900c3e2000", // Paper Mario: The Origami King
|
|
||||||
"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
|
|
||||||
|
|
||||||
"0100aa80194b0000", // Pikmin 1
|
|
||||||
"0100d680194b2000", // Pikmin 2
|
|
||||||
"0100f4c009322000", // Pikmin 3 Deluxe
|
|
||||||
"0100b7c00933a000", // Pikmin 4
|
|
||||||
|
|
||||||
"010003f003a34000", // Pokémon: Let's Go Pikachu!
|
|
||||||
"0100187003a36000", // Pokémon: Let's Go Eevee!
|
|
||||||
"0100abf008968000", // Pokémon Sword
|
|
||||||
"01008db008c2c000", // Pokémon Shield
|
|
||||||
"0100000011d90000", // Pokémon Brilliant Diamond
|
|
||||||
"010018e011d92000", // Pokémon Shining Pearl
|
|
||||||
"01001f5010dfa000", // Pokémon Legends: Arceus
|
|
||||||
"0100a3d008c5c000", // Pokémon Scarlet
|
|
||||||
"01008f6008c5e000", // Pokémon Violet
|
|
||||||
"0100b3f000be2000", // Pokkén Tournament DX
|
|
||||||
"0100f4300bf2c000", // New Pokémon Snap
|
|
||||||
|
|
||||||
"01003bc0000a0000", // Splatoon 2 (US)
|
|
||||||
"0100f8f0000a2000", // Splatoon 2 (EU)
|
|
||||||
"01003c700009c000", // Splatoon 2 (JP)
|
|
||||||
"0100c2500fc20000", // Splatoon 3
|
|
||||||
"0100ba0018500000", // Splatoon 3: Splatfest World Premiere
|
|
||||||
|
|
||||||
"010040600c5ce000", // Tetris 99
|
|
||||||
"0100277011f1a000", // Super Mario Bros. 35
|
|
||||||
"0100ad9012510000", // PAC-MAN 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
|
|
||||||
"010012f017576000", // GBA - Nintendo Switch Online
|
|
||||||
|
|
||||||
"01000320000cc000", // 1-2 Switch
|
|
||||||
"0100300012f2a000", // Advance Wars 1+2: Re-Boot Camp
|
|
||||||
"01006f8002326000", // Animal Crossing: New Horizons
|
|
||||||
"0100620012d6e000", // Big Brain Academy: Brain vs. Brain
|
|
||||||
"010018300d006000", // BOXBOY! + BOXGIRL!
|
|
||||||
"0100c1f0051b6000", // Donkey Kong Country: Tropical Freeze
|
|
||||||
"0100ed000d390000", // Dr. Kawashima's Brain Training
|
|
||||||
"010067b017588000", // Endless Ocean Luminous
|
|
||||||
"0100d2f00d5c0000", // Nintendo Switch Sports
|
|
||||||
"01006b5012b32000", // Part Time UFO
|
|
||||||
"0100704000B3A000", // Snipperclips
|
|
||||||
"01006a800016e000", // Super Smash Bros. Ultimate
|
|
||||||
"0100a9400c9c2000", // Tokyo Mirage Sessions #FE Encore
|
|
||||||
|
|
||||||
"010076f0049a2000", // Bayonetta
|
|
||||||
"01007960049a0000", // Bayonetta 2
|
|
||||||
"01004a4010fea000", // Bayonetta 3
|
|
||||||
"0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon
|
|
||||||
|
|
||||||
"0100dcd01525a000", // Persona 3 Portable
|
|
||||||
"010062b01525c000", // Persona 4 Golden
|
|
||||||
"010075a016a3a000", // Persona 4 Arena Ultimax
|
|
||||||
"01005ca01580e000", // Persona 5 Royal
|
|
||||||
"0100801011c3e000", // Persona 5 Strikers
|
|
||||||
"010087701b092000", // Persona 5 Tactica
|
|
||||||
|
|
||||||
"01009aa000faa000", // Sonic Mania
|
|
||||||
"01004ad014bf0000", // Sonic Frontiers
|
|
||||||
"01005ea01c0fc000", // SONIC X SHADOW GENERATIONS
|
|
||||||
"01005ea01c0fc001", // ^
|
|
||||||
|
|
||||||
"010056e00853a000", // A Hat in Time
|
|
||||||
"0100dbf01000a000", // Burnout Paradise Remastered
|
|
||||||
"0100744001588000", // Cars 3: Driven to Win
|
|
||||||
"0100b41013c82000", // Cruis'n Blast
|
|
||||||
"01001b300b9be000", // Diablo III: Eternal Collection
|
|
||||||
"01008c8012920000", // Dying Light Platinum Edition
|
|
||||||
"010073c01af34000", // LEGO Horizon Adventures
|
|
||||||
"0100770008dd8000", // Monster Hunter Generations Ultimate
|
|
||||||
"0100b04011742000", // Monster Hunter Rise
|
|
||||||
"0100853015e86000", // No Man's Sky
|
|
||||||
"01007bb017812000", // Portal
|
|
||||||
"0100abd01785c000", // Portal 2
|
|
||||||
"01008e200c5c2000", // Muse Dash
|
|
||||||
"01007820196a6000", // Red Dead Redemption
|
|
||||||
"01002f7013224000", // Rune Factory 5
|
|
||||||
"01008d100d43e000", // Saints Row IV
|
|
||||||
"0100de600beee000", // Saints Row: The Third - The Full Package
|
|
||||||
"01001180021fa000", // Shovel Knight: Specter of Torment
|
|
||||||
"0100d7a01b7a2000", // Star Wars: Bounty Hunter
|
|
||||||
"0100800015926000", // Suika Game
|
|
||||||
"0100e46006708000", // Terraria
|
|
||||||
"01000a10041ea000", // The Elder Scrolls V: Skyrim
|
|
||||||
"010057a01e4d4000", // TSUKIHIME -A piece of blue glass moon-
|
|
||||||
"010080b00ad66000", // Undertale
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
64
src/Ryujinx.UI.Common/Helper/AppletMetadata.cs
Normal file
64
src/Ryujinx.UI.Common/Helper/AppletMetadata.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using LibHac.Common;
|
||||||
|
using LibHac.Ncm;
|
||||||
|
using LibHac.Ns;
|
||||||
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
|
using Ryujinx.HLE;
|
||||||
|
using Ryujinx.HLE.FileSystem;
|
||||||
|
using Ryujinx.UI.App.Common;
|
||||||
|
|
||||||
|
namespace Ryujinx.UI.Common.Helper
|
||||||
|
{
|
||||||
|
public readonly struct AppletMetadata
|
||||||
|
{
|
||||||
|
private readonly ContentManager _contentManager;
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
public ulong ProgramId { get; }
|
||||||
|
|
||||||
|
public string Version { get; }
|
||||||
|
|
||||||
|
public AppletMetadata(ContentManager contentManager, string name, ulong programId, string version = "1.0.0")
|
||||||
|
: this(name, programId, version)
|
||||||
|
{
|
||||||
|
_contentManager = contentManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AppletMetadata(string name, ulong programId, string version = "1.0.0")
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
ProgramId = programId;
|
||||||
|
Version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetContentPath(ContentManager contentManager)
|
||||||
|
=> (contentManager ?? _contentManager)
|
||||||
|
.GetInstalledContentPath(ProgramId, StorageId.BuiltInSystem, NcaContentType.Program);
|
||||||
|
|
||||||
|
public bool CanStart(ContentManager contentManager, out ApplicationData appData, out BlitStruct<ApplicationControlProperty> appControl)
|
||||||
|
{
|
||||||
|
contentManager ??= _contentManager;
|
||||||
|
if (contentManager == null)
|
||||||
|
{
|
||||||
|
appData = null;
|
||||||
|
appControl = new BlitStruct<ApplicationControlProperty>(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
appData = new()
|
||||||
|
{
|
||||||
|
Name = Name,
|
||||||
|
Id = ProgramId,
|
||||||
|
Path = GetContentPath(contentManager)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(appData.Path))
|
||||||
|
{
|
||||||
|
appControl = new BlitStruct<ApplicationControlProperty>(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
appControl = StructHelpers.CreateCustomNacpData(Name, Version);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
src/Ryujinx.UI.Common/Resources/Logo_Ryujinx_AntiAlias.png
Normal file
BIN
src/Ryujinx.UI.Common/Resources/Logo_Ryujinx_AntiAlias.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 609 KiB |
@@ -33,7 +33,7 @@
|
|||||||
<EmbeddedResource Include="Resources\Icon_XCI.png" />
|
<EmbeddedResource Include="Resources\Icon_XCI.png" />
|
||||||
<EmbeddedResource Include="Resources\Logo_Amiibo.png" />
|
<EmbeddedResource Include="Resources\Logo_Amiibo.png" />
|
||||||
<EmbeddedResource Include="Resources\Logo_Ryujinx.png" />
|
<EmbeddedResource Include="Resources\Logo_Ryujinx.png" />
|
||||||
<EmbeddedResource Include="Resources\Logo_Thiccjinx.png" />
|
<EmbeddedResource Include="Resources\Logo_Ryujinx_AntiAlias.png" />
|
||||||
<EmbeddedResource Include="Resources\Logo_Discord_Dark.png" />
|
<EmbeddedResource Include="Resources\Logo_Discord_Dark.png" />
|
||||||
<EmbeddedResource Include="Resources\Logo_Discord_Light.png" />
|
<EmbeddedResource Include="Resources\Logo_Discord_Light.png" />
|
||||||
<EmbeddedResource Include="Resources\Logo_GitHub_Dark.png" />
|
<EmbeddedResource Include="Resources\Logo_GitHub_Dark.png" />
|
||||||
|
|||||||
@@ -143,23 +143,6 @@ namespace Ryujinx.Ava
|
|||||||
public ulong ApplicationId { get; private set; }
|
public ulong ApplicationId { get; private set; }
|
||||||
public bool ScreenshotRequested { get; set; }
|
public bool ScreenshotRequested { get; set; }
|
||||||
|
|
||||||
public bool ShouldInitMetal
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64 &&
|
|
||||||
(
|
|
||||||
(
|
|
||||||
(
|
|
||||||
ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.Auto &&
|
|
||||||
RendererHost.KnownGreatMetalTitles.ContainsIgnoreCase(ApplicationId.ToString("X16"))
|
|
||||||
) ||
|
|
||||||
ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.Metal
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AppHost(
|
public AppHost(
|
||||||
RendererHost renderer,
|
RendererHost renderer,
|
||||||
InputManager inputManager,
|
InputManager inputManager,
|
||||||
@@ -912,27 +895,20 @@ namespace Ryujinx.Ava
|
|||||||
VirtualFileSystem.ReloadKeySet();
|
VirtualFileSystem.ReloadKeySet();
|
||||||
|
|
||||||
// Initialize Renderer.
|
// Initialize Renderer.
|
||||||
IRenderer renderer;
|
GraphicsBackend backend = TitleIDs.SelectGraphicsBackend(ApplicationId.ToString("X16"), ConfigurationState.Instance.Graphics.GraphicsBackend);
|
||||||
GraphicsBackend backend = ConfigurationState.Instance.Graphics.GraphicsBackend;
|
|
||||||
|
|
||||||
if (ShouldInitMetal)
|
IRenderer renderer = backend switch
|
||||||
{
|
{
|
||||||
#pragma warning disable CA1416 // This call site is reachable on all platforms
|
#pragma warning disable CA1416 // This call site is reachable on all platforms
|
||||||
// The condition does a check for Mac, on top of checking if it's an ARM Mac. This isn't a problem.
|
// SelectGraphicsBackend does a check for Mac, on top of checking if it's an ARM Mac. This isn't a problem.
|
||||||
renderer = new MetalRenderer((RendererHost.EmbeddedWindow as EmbeddedWindowMetal)!.CreateSurface);
|
GraphicsBackend.Metal => new MetalRenderer((RendererHost.EmbeddedWindow as EmbeddedWindowMetal)!.CreateSurface),
|
||||||
#pragma warning restore CA1416
|
#pragma warning restore CA1416
|
||||||
}
|
GraphicsBackend.Vulkan => VulkanRenderer.Create(
|
||||||
else if (backend == GraphicsBackend.Vulkan || (backend == GraphicsBackend.Auto && !ShouldInitMetal))
|
|
||||||
{
|
|
||||||
renderer = VulkanRenderer.Create(
|
|
||||||
ConfigurationState.Instance.Graphics.PreferredGpu,
|
ConfigurationState.Instance.Graphics.PreferredGpu,
|
||||||
(RendererHost.EmbeddedWindow as EmbeddedWindowVulkan)!.CreateSurface,
|
(RendererHost.EmbeddedWindow as EmbeddedWindowVulkan)!.CreateSurface,
|
||||||
VulkanHelper.GetRequiredInstanceExtensions);
|
VulkanHelper.GetRequiredInstanceExtensions),
|
||||||
}
|
_ => new OpenGLRenderer()
|
||||||
else
|
};
|
||||||
{
|
|
||||||
renderer = new OpenGLRenderer();
|
|
||||||
}
|
|
||||||
|
|
||||||
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
|
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Аплет для редагування Mii",
|
"uk_UA": "Аплет для редагування Mii",
|
||||||
"zh_CN": "",
|
"zh_CN": "Mii 小程序",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -713,7 +713,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "从bin文件扫描 Amiibo",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -833,7 +833,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "安装密匙",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -857,7 +857,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "从.KEYS文件或ZIP压缩包安装密匙",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -881,7 +881,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "从一个文件夹安装密匙",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -977,7 +977,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізати XCI файли",
|
"uk_UA": "Обрізати XCI файли",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件瘦身",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1217,7 +1217,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "常见问题和问题排除页面",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1241,7 +1241,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "打开Ryujinx官方wiki的常见问题和问题排除页面",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1265,7 +1265,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "安装与配置指南",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1289,7 +1289,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "打开Ryujinx官方wiki的安装与配置指南",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1313,7 +1313,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "多人游戏(LDN/LAN)指南",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1337,7 +1337,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "打开Ryujinx官方wiki的多人游戏指南",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2441,7 +2441,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перевірка та Нарізка XCI Файлів",
|
"uk_UA": "Перевірка та Нарізка XCI Файлів",
|
||||||
"zh_CN": "",
|
"zh_CN": "检查并瘦身XCI文件",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2465,7 +2465,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перевірка та Нарізка XCI Файлів для збереження місця на диску",
|
"uk_UA": "Перевірка та Нарізка XCI Файлів для збереження місця на диску",
|
||||||
"zh_CN": "",
|
"zh_CN": "检查并瘦身XCI文件以节约磁盘空间",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2537,7 +2537,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізано XCI Файлів '{0}'",
|
"uk_UA": "Обрізано XCI Файлів '{0}'",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件瘦身中'{0}'",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -10097,7 +10097,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Скасування",
|
"uk_UA": "Скасування",
|
||||||
"zh_CN": "",
|
"zh_CN": "正在取消",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -10121,7 +10121,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Закрити",
|
"uk_UA": "Закрити",
|
||||||
"zh_CN": "",
|
"zh_CN": "关闭",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -11369,7 +11369,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Показати список змін",
|
"uk_UA": "Показати список змін",
|
||||||
"zh_CN": "",
|
"zh_CN": "显示更新日志",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -11825,7 +11825,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件瘦身窗口",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -12521,7 +12521,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "在{0}发现了一个无效的密匙文件",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -12545,7 +12545,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Встановлення Ключів",
|
"uk_UA": "Встановлення Ключів",
|
||||||
"zh_CN": "",
|
"zh_CN": "安装密匙",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -12569,7 +12569,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Новий файл Ключів буде встановлено",
|
"uk_UA": "Новий файл Ключів буде встановлено",
|
||||||
"zh_CN": "",
|
"zh_CN": "将会安装新密匙文件",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -12593,7 +12593,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "\n\nЦе замінить собою поточні файли Ключів.",
|
"uk_UA": "\n\nЦе замінить собою поточні файли Ключів.",
|
||||||
"zh_CN": "",
|
"zh_CN": "\n\n这也许会替换掉一些当前已安装的密匙",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -12617,7 +12617,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "\n\nВи хочете продовжити?",
|
"uk_UA": "\n\nВи хочете продовжити?",
|
||||||
"zh_CN": "",
|
"zh_CN": "\n\n你想要继续吗?",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -12641,7 +12641,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Встановлення Ключів...",
|
"uk_UA": "Встановлення Ключів...",
|
||||||
"zh_CN": "",
|
"zh_CN": "安装密匙中。。。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -12665,7 +12665,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Нові ключі встановлено.",
|
"uk_UA": "Нові ключі встановлено.",
|
||||||
"zh_CN": "",
|
"zh_CN": "已成功安装新密匙文件",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -13673,7 +13673,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Минулі розробники:",
|
"uk_UA": "Минулі розробники:",
|
||||||
"zh_CN": "",
|
"zh_CN": "曾经的维护者:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -14657,7 +14657,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "重新同步系统时间以匹配您电脑的当前日期和时间。\n\n这个操作不会实时同步系统时间与电脑时间,时间仍然可能不同步;在这种情况下,只需再次单击此按钮即可。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16817,7 +16817,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Часткові",
|
"uk_UA": "Часткові",
|
||||||
"zh_CN": "",
|
"zh_CN": "分区",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16841,7 +16841,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Необрізані",
|
"uk_UA": "Необрізані",
|
||||||
"zh_CN": "",
|
"zh_CN": "没有瘦身的",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16865,7 +16865,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізані",
|
"uk_UA": "Обрізані",
|
||||||
"zh_CN": "",
|
"zh_CN": "经过瘦身的",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16889,7 +16889,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "(Невдача)",
|
"uk_UA": "(Невдача)",
|
||||||
"zh_CN": "",
|
"zh_CN": "(失败)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16913,7 +16913,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Зберегти {0:n0} Мб",
|
"uk_UA": "Зберегти {0:n0} Мб",
|
||||||
"zh_CN": "",
|
"zh_CN": "能节约 {0:n0} Mb",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16937,7 +16937,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Збережено {0:n0} Мб",
|
"uk_UA": "Збережено {0:n0} Мб",
|
||||||
"zh_CN": "",
|
"zh_CN": "节约了 {0:n0} Mb",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -17129,7 +17129,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вкажіть Ваше нове ім'я Amiibo",
|
"uk_UA": "Вкажіть Ваше нове ім'я Amiibo",
|
||||||
"zh_CN": "",
|
"zh_CN": "输入你的 Amiibo 的新名字",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -17153,7 +17153,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Будь ласка, проскануйте Ваш Amiibo.",
|
"uk_UA": "Будь ласка, проскануйте Ваш Amiibo.",
|
||||||
"zh_CN": "",
|
"zh_CN": "请现在扫描你的 Amiibo",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18233,7 +18233,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перевірити та Обрізати XCI файл",
|
"uk_UA": "Перевірити та Обрізати XCI файл",
|
||||||
"zh_CN": "",
|
"zh_CN": "检查并瘦身XCI文件",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18257,7 +18257,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Ця функція спочатку перевірить вільний простір, а потім обрізатиме файл XCI для економії місця на диску.",
|
"uk_UA": "Ця функція спочатку перевірить вільний простір, а потім обрізатиме файл XCI для економії місця на диску.",
|
||||||
"zh_CN": "",
|
"zh_CN": "这个功能将会先检查XCI文件,再对其执行瘦身操作以节约磁盘空间。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18281,7 +18281,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Поточний розмір файла: {0:n} MB\nРозмір файлів гри: {1:n} MB\nЕкономія місця: {2:n} MB",
|
"uk_UA": "Поточний розмір файла: {0:n} MB\nРозмір файлів гри: {1:n} MB\nЕкономія місця: {2:n} MB",
|
||||||
"zh_CN": "",
|
"zh_CN": "当前文件大小: {0:n} MB\n游戏数据大小: {1:n} MB\n节约的磁盘空间: {2:n} MB",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18305,7 +18305,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI файл не потребує обрізання. Перевірте журнали для додаткової інформації",
|
"uk_UA": "XCI файл не потребує обрізання. Перевірте журнали для додаткової інформації",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件不需要被瘦身。查看日志以获得更多细节。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18329,7 +18329,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI файл не може бути обрізаний. Перевірте журнали для додаткової інформації",
|
"uk_UA": "XCI файл не може бути обрізаний. Перевірте журнали для додаткової інформації",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件不能被瘦身。查看日志以获得更多细节。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18353,7 +18353,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали додаткової інформації",
|
"uk_UA": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали додаткової інформації",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件是只读的,且不可以被标记为可读取的。查看日志以获得更多细节。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18377,7 +18377,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Розмір файлу XCI змінився з моменту сканування. Перевірте, чи не записується файл, та спробуйте знову",
|
"uk_UA": "Розмір файлу XCI змінився з моменту сканування. Перевірте, чи не записується файл, та спробуйте знову",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件在扫描后大小发生了变化。请检查文件是否未被写入,然后重试。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18401,7 +18401,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Файл XCI містить дані в зоні вільного простору, тому обрізка небезпечна",
|
"uk_UA": "Файл XCI містить дані в зоні вільного простору, тому обрізка небезпечна",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件的空闲区域内有数据,不能安全瘦身。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18425,7 +18425,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI Файл містить недійсні дані. Перевірте журнали для додаткової інформації",
|
"uk_UA": "XCI Файл містить недійсні дані. Перевірте журнали для додаткової інформації",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件含有无效数据。查看日志以获得更多细节。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18449,7 +18449,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI Файл файл не вдалося відкрити для запису. Перевірте журнали для додаткової інформації",
|
"uk_UA": "XCI Файл файл не вдалося відкрити для запису. Перевірте журнали для додаткової інформації",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件不能被读写。查看日志以获得更多细节。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18473,7 +18473,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Не вдалося обрізати файл XCI",
|
"uk_UA": "Не вдалося обрізати файл XCI",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件瘦身失败",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18497,7 +18497,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Операція перервана",
|
"uk_UA": "Операція перервана",
|
||||||
"zh_CN": "",
|
"zh_CN": "操作已取消",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18521,7 +18521,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Операція не проводилася",
|
"uk_UA": "Операція не проводилася",
|
||||||
"zh_CN": "",
|
"zh_CN": "未执行操作",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18665,7 +18665,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізка XCI Файлів",
|
"uk_UA": "Обрізка XCI Файлів",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件瘦身器",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18689,7 +18689,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "{0} з {1} тайтл(ів) обрано",
|
"uk_UA": "{0} з {1} тайтл(ів) обрано",
|
||||||
"zh_CN": "",
|
"zh_CN": "在 {1} 中选中了 {0} 个游戏 ",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18713,7 +18713,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "{0} з {1} тайтл(ів) обрано ({2} відображається)",
|
"uk_UA": "{0} з {1} тайтл(ів) обрано ({2} відображається)",
|
||||||
"zh_CN": "",
|
"zh_CN": "在 {1} 中选中了 {0} 个游戏 (显示了 {2} 个)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18737,7 +18737,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізка {0} тайтл(ів)...",
|
"uk_UA": "Обрізка {0} тайтл(ів)...",
|
||||||
"zh_CN": "",
|
"zh_CN": "{0} 个游戏瘦身中。。。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18785,7 +18785,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Невдача",
|
"uk_UA": "Невдача",
|
||||||
"zh_CN": "",
|
"zh_CN": "失败",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18809,7 +18809,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Потенційна економія",
|
"uk_UA": "Потенційна економія",
|
||||||
"zh_CN": "",
|
"zh_CN": "潜在的储存空间节省",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18833,7 +18833,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Зекономлено",
|
"uk_UA": "Зекономлено",
|
||||||
"zh_CN": "",
|
"zh_CN": "实际的储存空间节省",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18881,7 +18881,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вибрати показане",
|
"uk_UA": "Вибрати показане",
|
||||||
"zh_CN": "",
|
"zh_CN": "选定显示的",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18905,7 +18905,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Скасувати вибір показаного",
|
"uk_UA": "Скасувати вибір показаного",
|
||||||
"zh_CN": "",
|
"zh_CN": "反选显示的",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -18977,7 +18977,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізка",
|
"uk_UA": "Обрізка",
|
||||||
"zh_CN": "",
|
"zh_CN": "瘦身",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19337,7 +19337,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Продовжити",
|
"uk_UA": "Продовжити",
|
||||||
"zh_CN": "",
|
"zh_CN": "继续",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19697,7 +19697,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "自动",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19721,7 +19721,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "使用Vulkan。\n在ARM Mac上,当玩在其下运行良好的游戏时,使用Metal后端。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21065,7 +21065,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вимкнути хостинг P2P мережі (може збільшити затримку)",
|
"uk_UA": "Вимкнути хостинг P2P мережі (може збільшити затримку)",
|
||||||
"zh_CN": "",
|
"zh_CN": "禁用P2P网络连接 (也许会增加延迟)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21089,7 +21089,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вимкнути хостинг P2P мережі, піри будуть підключатися через майстер-сервер замість прямого з'єднання з вами.",
|
"uk_UA": "Вимкнути хостинг P2P мережі, піри будуть підключатися через майстер-сервер замість прямого з'єднання з вами.",
|
||||||
"zh_CN": "",
|
"zh_CN": "禁用P2P网络连接,对方将通过主服务器进行连接,而不是直接连接到您。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21113,7 +21113,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Мережевий пароль:",
|
"uk_UA": "Мережевий пароль:",
|
||||||
"zh_CN": "",
|
"zh_CN": "网络密码:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21137,7 +21137,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
"uk_UA": "Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
||||||
"zh_CN": "",
|
"zh_CN": "您只能看到与您使用相同密码的游戏房间。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21161,7 +21161,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Введіть пароль у форматі Ryujinx-<8 символів>. Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
"uk_UA": "Введіть пароль у форматі Ryujinx-<8 символів>. Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
||||||
"zh_CN": "",
|
"zh_CN": "以Ryujinx-<8个十六进制字符>的格式输入密码。您只能看到与您使用相同密码的游戏房间。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21185,7 +21185,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "(публічний)",
|
"uk_UA": "(публічний)",
|
||||||
"zh_CN": "",
|
"zh_CN": "(公开的)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21209,7 +21209,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Згенерувати випадкову",
|
"uk_UA": "Згенерувати випадкову",
|
||||||
"zh_CN": "",
|
"zh_CN": "随机生成",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21233,7 +21233,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Генерує новий пароль, яким можна поділитися з іншими гравцями.",
|
"uk_UA": "Генерує новий пароль, яким можна поділитися з іншими гравцями.",
|
||||||
"zh_CN": "",
|
"zh_CN": "生成一个新的密码,可以与其他玩家共享。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21257,7 +21257,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Очистити",
|
"uk_UA": "Очистити",
|
||||||
"zh_CN": "",
|
"zh_CN": "清除",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21281,7 +21281,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Очищає поточну пароль, повертаючись до публічної мережі.",
|
"uk_UA": "Очищає поточну пароль, повертаючись до публічної мережі.",
|
||||||
"zh_CN": "",
|
"zh_CN": "清除当前密码,返回公共网络。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21305,7 +21305,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Невірний пароль! Має бути в форматі \"Ryujinx-<8 символів>\"",
|
"uk_UA": "Невірний пароль! Має бути в форматі \"Ryujinx-<8 символів>\"",
|
||||||
"zh_CN": "",
|
"zh_CN": "无效密码!密码的格式必须是\"Ryujinx-<8个十六进制字符>\"",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21329,7 +21329,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вертикальна синхронізація (VSync):",
|
"uk_UA": "Вертикальна синхронізація (VSync):",
|
||||||
"zh_CN": "",
|
"zh_CN": "垂直同步(VSync)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21353,7 +21353,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Увімкнути користувацьку частоту оновлення (Експериментально)",
|
"uk_UA": "Увімкнути користувацьку частоту оновлення (Експериментально)",
|
||||||
"zh_CN": "",
|
"zh_CN": "启动自定义刷新率(实验性功能)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21401,7 +21401,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Безмежна",
|
"uk_UA": "Безмежна",
|
||||||
"zh_CN": "",
|
"zh_CN": "无限制",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21425,7 +21425,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Користувацька",
|
"uk_UA": "Користувацька",
|
||||||
"zh_CN": "",
|
"zh_CN": "自定义刷新率",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21449,7 +21449,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень.",
|
"uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень.",
|
||||||
"zh_CN": "",
|
"zh_CN": "模拟垂直同步。“Switch”模拟了Switch的60Hz刷新率。“无限制”没有刷新率限制。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21473,7 +21473,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.",
|
"uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.",
|
||||||
"zh_CN": "",
|
"zh_CN": "模拟垂直同步。“Switch”模拟了Switch的60Hz刷新率。“无限制”没有刷新率限制。“自定义刷新率”模拟指定的自定义刷新率。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21497,7 +21497,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. У інших іграх це може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як це вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.",
|
"uk_UA": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. У інших іграх це може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як це вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.",
|
||||||
"zh_CN": "",
|
"zh_CN": "允许用户指定模拟刷新率。在某些游戏中,这可能会加快或减慢游戏逻辑的速度。在其他游戏中,它可能允许将FPS限制在刷新率的某个倍数,或者导致不可预测的行为。这是一个实验性功能,无法保证游戏会受到怎样的影响。\n\n如果不确定,请关闭。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21521,7 +21521,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Цільове значення користувацької частоти оновлення.",
|
"uk_UA": "Цільове значення користувацької частоти оновлення.",
|
||||||
"zh_CN": "",
|
"zh_CN": "目标自定义刷新率值。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21545,7 +21545,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Користувацька частота оновлення, як відсоток від стандартної частоти оновлення Switch.",
|
"uk_UA": "Користувацька частота оновлення, як відсоток від стандартної частоти оновлення Switch.",
|
||||||
"zh_CN": "",
|
"zh_CN": "自定义刷新率,占正常SWitch刷新率的百分比值。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21569,7 +21569,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Користувацька частота оновлення %:",
|
"uk_UA": "Користувацька частота оновлення %:",
|
||||||
"zh_CN": "",
|
"zh_CN": "自定义刷新率值 %:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21593,7 +21593,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Значення користувацька частота оновлення:",
|
"uk_UA": "Значення користувацька частота оновлення:",
|
||||||
"zh_CN": "",
|
"zh_CN": "自定义刷新率值:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21617,7 +21617,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "间隔",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21641,7 +21641,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перемкнути VSync режим:",
|
"uk_UA": "Перемкнути VSync режим:",
|
||||||
"zh_CN": "",
|
"zh_CN": "设置 VSync 模式:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21665,7 +21665,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Підвищити користувацьку частоту оновлення",
|
"uk_UA": "Підвищити користувацьку частоту оновлення",
|
||||||
"zh_CN": "",
|
"zh_CN": "提高自定义刷新率:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21689,7 +21689,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Понизити користувацьку частоту оновлення",
|
"uk_UA": "Понизити користувацьку частоту оновлення",
|
||||||
"zh_CN": "",
|
"zh_CN": "降低自定义刷新率:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.UI.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using System;
|
using System;
|
||||||
@@ -17,7 +16,6 @@ namespace Ryujinx.Ava.Common.Locale
|
|||||||
private const string DefaultLanguageCode = "en_US";
|
private const string DefaultLanguageCode = "en_US";
|
||||||
|
|
||||||
private readonly Dictionary<LocaleKeys, string> _localeStrings;
|
private readonly Dictionary<LocaleKeys, string> _localeStrings;
|
||||||
private Dictionary<LocaleKeys, string> _localeDefaultStrings;
|
|
||||||
private readonly ConcurrentDictionary<LocaleKeys, object[]> _dynamicValues;
|
private readonly ConcurrentDictionary<LocaleKeys, object[]> _dynamicValues;
|
||||||
private string _localeLanguageCode;
|
private string _localeLanguageCode;
|
||||||
|
|
||||||
@@ -27,7 +25,6 @@ namespace Ryujinx.Ava.Common.Locale
|
|||||||
public LocaleManager()
|
public LocaleManager()
|
||||||
{
|
{
|
||||||
_localeStrings = new Dictionary<LocaleKeys, string>();
|
_localeStrings = new Dictionary<LocaleKeys, string>();
|
||||||
_localeDefaultStrings = new Dictionary<LocaleKeys, string>();
|
|
||||||
_dynamicValues = new ConcurrentDictionary<LocaleKeys, object[]>();
|
_dynamicValues = new ConcurrentDictionary<LocaleKeys, object[]>();
|
||||||
|
|
||||||
Load();
|
Load();
|
||||||
@@ -37,9 +34,7 @@ namespace Ryujinx.Ava.Common.Locale
|
|||||||
{
|
{
|
||||||
var localeLanguageCode = !string.IsNullOrEmpty(ConfigurationState.Instance.UI.LanguageCode.Value) ?
|
var localeLanguageCode = !string.IsNullOrEmpty(ConfigurationState.Instance.UI.LanguageCode.Value) ?
|
||||||
ConfigurationState.Instance.UI.LanguageCode.Value : CultureInfo.CurrentCulture.Name.Replace('-', '_');
|
ConfigurationState.Instance.UI.LanguageCode.Value : CultureInfo.CurrentCulture.Name.Replace('-', '_');
|
||||||
|
|
||||||
// Load en_US as default, if the target language translation is missing or incomplete.
|
|
||||||
LoadDefaultLanguage();
|
|
||||||
LoadLanguage(localeLanguageCode);
|
LoadLanguage(localeLanguageCode);
|
||||||
|
|
||||||
// Save whatever we ended up with.
|
// Save whatever we ended up with.
|
||||||
@@ -66,26 +61,14 @@ namespace Ryujinx.Ava.Common.Locale
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// If formatting failed use the default text instead.
|
// If formatting the text failed,
|
||||||
if (_localeDefaultStrings.TryGetValue(key, out value))
|
// continue to the below line & return the text without formatting.
|
||||||
try
|
|
||||||
{
|
|
||||||
return string.Format(value, dynamicValue);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// If formatting the default text failed return the key.
|
|
||||||
return key.ToString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the locale doesn't contain the key return the default one.
|
return key.ToString(); // If the locale text doesn't exist return the key.
|
||||||
return _localeDefaultStrings.TryGetValue(key, out string defaultValue)
|
|
||||||
? defaultValue
|
|
||||||
: key.ToString(); // If the locale text doesn't exist return the key.
|
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
@@ -109,16 +92,11 @@ namespace Ryujinx.Ava.Common.Locale
|
|||||||
{
|
{
|
||||||
_dynamicValues[key] = values;
|
_dynamicValues[key] = values;
|
||||||
|
|
||||||
OnPropertyChanged("Item");
|
OnPropertyChanged("Translation");
|
||||||
|
|
||||||
return this[key];
|
return this[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadDefaultLanguage()
|
|
||||||
{
|
|
||||||
_localeDefaultStrings = LoadJsonLanguage(DefaultLanguageCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadLanguage(string languageCode)
|
public void LoadLanguage(string languageCode)
|
||||||
{
|
{
|
||||||
var locale = LoadJsonLanguage(languageCode);
|
var locale = LoadJsonLanguage(languageCode);
|
||||||
@@ -126,7 +104,7 @@ namespace Ryujinx.Ava.Common.Locale
|
|||||||
if (locale == null)
|
if (locale == null)
|
||||||
{
|
{
|
||||||
_localeLanguageCode = DefaultLanguageCode;
|
_localeLanguageCode = DefaultLanguageCode;
|
||||||
locale = _localeDefaultStrings;
|
locale = LoadJsonLanguage(_localeLanguageCode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -138,16 +116,12 @@ namespace Ryujinx.Ava.Common.Locale
|
|||||||
_localeStrings[key] = val;
|
_localeStrings[key] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
OnPropertyChanged("Item");
|
OnPropertyChanged("Translation");
|
||||||
|
|
||||||
LocaleChanged?.Invoke();
|
LocaleChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
private static LocalesJson? _localeData;
|
private static LocalesJson? _localeData;
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
private static Dictionary<LocaleKeys, string> LoadJsonLanguage(string languageCode)
|
private static Dictionary<LocaleKeys, string> LoadJsonLanguage(string languageCode)
|
||||||
{
|
{
|
||||||
@@ -158,18 +132,29 @@ namespace Ryujinx.Ava.Common.Locale
|
|||||||
|
|
||||||
foreach (LocalesEntry locale in _localeData.Value.Locales)
|
foreach (LocalesEntry locale in _localeData.Value.Locales)
|
||||||
{
|
{
|
||||||
if (locale.Translations.Count != _localeData.Value.Languages.Count)
|
if (locale.Translations.Count < _localeData.Value.Languages.Count)
|
||||||
{
|
{
|
||||||
throw new Exception($"Locale key {{{locale.ID}}} is missing languages! Has {locale.Translations.Count} translations, expected {_localeData.Value.Languages.Count}!");
|
throw new Exception($"Locale key {{{locale.ID}}} is missing languages! Has {locale.Translations.Count} translations, expected {_localeData.Value.Languages.Count}!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locale.Translations.Count > _localeData.Value.Languages.Count)
|
||||||
|
{
|
||||||
|
throw new Exception($"Locale key {{{locale.ID}}} has too many languages! Has {locale.Translations.Count} translations, expected {_localeData.Value.Languages.Count}!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Enum.TryParse<LocaleKeys>(locale.ID, out var localeKey))
|
if (!Enum.TryParse<LocaleKeys>(locale.ID, out var localeKey))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
localeStrings[localeKey] =
|
var str = locale.Translations.TryGetValue(languageCode, out string val) && !string.IsNullOrEmpty(val)
|
||||||
locale.Translations.TryGetValue(languageCode, out string val) && val != string.Empty
|
? val
|
||||||
? val
|
: locale.Translations[DefaultLanguageCode];
|
||||||
: locale.Translations[DefaultLanguageCode];
|
|
||||||
|
if (string.IsNullOrEmpty(str))
|
||||||
|
{
|
||||||
|
throw new Exception($"Locale key '{locale.ID}' has no valid translations for desired language {languageCode}! {DefaultLanguageCode} is an empty string or null");
|
||||||
|
}
|
||||||
|
|
||||||
|
localeStrings[localeKey] = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
return localeStrings;
|
return localeStrings;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Ryujinx.Ava.Common.Markup
|
|||||||
{
|
{
|
||||||
internal abstract class BasicMarkupExtension<T> : MarkupExtension
|
internal abstract class BasicMarkupExtension<T> : MarkupExtension
|
||||||
{
|
{
|
||||||
public virtual string Name => "Item";
|
public abstract string Name { get; }
|
||||||
public virtual Action<object, T?>? Setter => null;
|
public virtual Action<object, T?>? Setter => null;
|
||||||
|
|
||||||
protected abstract T? Value { get; }
|
protected abstract T? Value { get; }
|
||||||
|
|||||||
@@ -6,16 +6,19 @@ namespace Ryujinx.Ava.Common.Markup
|
|||||||
{
|
{
|
||||||
internal class IconExtension(string iconString) : BasicMarkupExtension<Icon>
|
internal class IconExtension(string iconString) : BasicMarkupExtension<Icon>
|
||||||
{
|
{
|
||||||
|
public override string Name => "Icon";
|
||||||
protected override Icon Value => new() { Value = iconString };
|
protected override Icon Value => new() { Value = iconString };
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class SpinningIconExtension(string iconString) : BasicMarkupExtension<Icon>
|
internal class SpinningIconExtension(string iconString) : BasicMarkupExtension<Icon>
|
||||||
{
|
{
|
||||||
|
public override string Name => "SIcon";
|
||||||
protected override Icon Value => new() { Value = iconString, Animation = IconAnimation.Spin };
|
protected override Icon Value => new() { Value = iconString, Animation = IconAnimation.Spin };
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LocaleExtension(LocaleKeys key) : BasicMarkupExtension<string>
|
internal class LocaleExtension(LocaleKeys key) : BasicMarkupExtension<string>
|
||||||
{
|
{
|
||||||
|
public override string Name => "Translation";
|
||||||
protected override string Value => LocaleManager.Instance[key];
|
protected override string Value => LocaleManager.Instance[key];
|
||||||
|
|
||||||
protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension)
|
protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension)
|
||||||
|
|||||||
19
src/Ryujinx/UI/Controls/StatusBarSeparator.cs
Normal file
19
src/Ryujinx/UI/Controls/StatusBarSeparator.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Media;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
|
{
|
||||||
|
public class MiniVerticalSeparator : Border
|
||||||
|
{
|
||||||
|
public MiniVerticalSeparator()
|
||||||
|
{
|
||||||
|
Width = 2;
|
||||||
|
Height = 12;
|
||||||
|
Margin = new Thickness();
|
||||||
|
BorderBrush = Brushes.Gray;
|
||||||
|
Background = Brushes.Gray;
|
||||||
|
BorderThickness = new Thickness(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Data;
|
using Avalonia.Data;
|
||||||
using Avalonia.Data.Converters;
|
using Avalonia.Data.Converters;
|
||||||
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.UI.Common.Models;
|
using Ryujinx.UI.Common.Models;
|
||||||
using System;
|
using System;
|
||||||
@@ -32,11 +33,11 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
|
|
||||||
if (app.CurrentSavingsB < app.PotentialSavingsB)
|
if (app.CurrentSavingsB < app.PotentialSavingsB)
|
||||||
{
|
{
|
||||||
return LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleXCICanSaveLabel, (app.PotentialSavingsB - app.CurrentSavingsB) / _bytesPerMB);
|
return LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleXCICanSaveLabel, ((app.PotentialSavingsB - app.CurrentSavingsB) / _bytesPerMB).CoerceAtLeast(0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleXCISavingLabel, app.CurrentSavingsB / _bytesPerMB);
|
return LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleXCISavingLabel, (app.CurrentSavingsB / _bytesPerMB).CoerceAtLeast(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.UI.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
@@ -31,15 +32,6 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly string[] KnownGreatMetalTitles =
|
|
||||||
[
|
|
||||||
"01006A800016E000", // Smash Ultimate
|
|
||||||
"0100000000010000", // Super Mario Odyessy
|
|
||||||
"01008C0016544000", // Sea of Stars
|
|
||||||
"01005CA01580E000", // Persona 5
|
|
||||||
"010028600EBDA000", // Mario 3D World
|
|
||||||
];
|
|
||||||
|
|
||||||
public GraphicsBackend Backend =>
|
public GraphicsBackend Backend =>
|
||||||
EmbeddedWindow switch
|
EmbeddedWindow switch
|
||||||
{
|
{
|
||||||
@@ -53,16 +45,8 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
switch (ConfigurationState.Instance.Graphics.GraphicsBackend.Value)
|
switch (TitleIDs.SelectGraphicsBackend(titleId, ConfigurationState.Instance.Graphics.GraphicsBackend))
|
||||||
{
|
{
|
||||||
case GraphicsBackend.Auto:
|
|
||||||
EmbeddedWindow =
|
|
||||||
OperatingSystem.IsMacOS() &&
|
|
||||||
RuntimeInformation.ProcessArchitecture == Architecture.Arm64 &&
|
|
||||||
KnownGreatMetalTitles.ContainsIgnoreCase(titleId)
|
|
||||||
? new EmbeddedWindowMetal()
|
|
||||||
: new EmbeddedWindowVulkan();
|
|
||||||
break;
|
|
||||||
case GraphicsBackend.OpenGl:
|
case GraphicsBackend.OpenGl:
|
||||||
EmbeddedWindow = new EmbeddedWindowOpenGL();
|
EmbeddedWindow = new EmbeddedWindowOpenGL();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
@@ -11,5 +12,13 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void OnPropertiesChanged(params ReadOnlySpan<string> propertyNames)
|
||||||
|
{
|
||||||
|
foreach (var propertyName in propertyNames)
|
||||||
|
{
|
||||||
|
OnPropertyChanged(propertyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
// For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left.
|
// For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left.
|
||||||
// The border gets reduced to colored pixels in the 4 corners.
|
// The border gets reduced to colored pixels in the 4 corners.
|
||||||
public static readonly Bitmap IconBitmap =
|
public static readonly Bitmap IconBitmap =
|
||||||
new(Assembly.GetAssembly(typeof(ConfigurationState))!.GetManifestResourceStream("Ryujinx.UI.Common.Resources.Logo_Thiccjinx.png")!);
|
new(Assembly.GetAssembly(typeof(ConfigurationState))!.GetManifestResourceStream("Ryujinx.UI.Common.Resources.Logo_Ryujinx_AntiAlias.png")!);
|
||||||
|
|
||||||
public MainWindow Window { get; init; }
|
public MainWindow Window { get; init; }
|
||||||
|
|
||||||
|
|||||||
@@ -71,8 +71,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
_resolutionScale = value;
|
_resolutionScale = value;
|
||||||
|
|
||||||
OnPropertyChanged(nameof(CustomResolutionScale));
|
OnPropertiesChanged(nameof(CustomResolutionScale), nameof(IsCustomResolutionScaleActive));
|
||||||
OnPropertyChanged(nameof(IsCustomResolutionScaleActive));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,8 +180,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
int newInterval = (int)((value / 100f) * 60);
|
int newInterval = (int)((value / 100f) * 60);
|
||||||
_customVSyncInterval = newInterval;
|
_customVSyncInterval = newInterval;
|
||||||
_customVSyncIntervalPercentageProxy = value;
|
_customVSyncIntervalPercentageProxy = value;
|
||||||
OnPropertyChanged((nameof(CustomVSyncInterval)));
|
OnPropertiesChanged(
|
||||||
OnPropertyChanged((nameof(CustomVSyncIntervalPercentageText)));
|
nameof(CustomVSyncInterval),
|
||||||
|
nameof(CustomVSyncIntervalPercentageText));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
string text = CustomVSyncIntervalPercentageProxy.ToString() + "%";
|
string text = CustomVSyncIntervalPercentageProxy + "%";
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,8 +221,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
_customVSyncInterval = value;
|
_customVSyncInterval = value;
|
||||||
int newPercent = (int)((value / 60f) * 100);
|
int newPercent = (int)((value / 60f) * 100);
|
||||||
_customVSyncIntervalPercentageProxy = newPercent;
|
_customVSyncIntervalPercentageProxy = newPercent;
|
||||||
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy));
|
OnPropertiesChanged(
|
||||||
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText));
|
nameof(CustomVSyncIntervalPercentageProxy),
|
||||||
|
nameof(CustomVSyncIntervalPercentageText));
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,39 +91,42 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
private void SortingChanged()
|
private void SortingChanged()
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(IsSortedByName));
|
OnPropertiesChanged(
|
||||||
OnPropertyChanged(nameof(IsSortedBySaved));
|
nameof(IsSortedByName),
|
||||||
OnPropertyChanged(nameof(SortingAscending));
|
nameof(IsSortedBySaved),
|
||||||
OnPropertyChanged(nameof(SortingField));
|
nameof(SortingAscending),
|
||||||
OnPropertyChanged(nameof(SortingFieldName));
|
nameof(SortingField),
|
||||||
|
nameof(SortingFieldName));
|
||||||
|
|
||||||
SortAndFilter();
|
SortAndFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisplayedChanged()
|
private void DisplayedChanged()
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(Status));
|
OnPropertiesChanged(nameof(Status), nameof(DisplayedXCIFiles), nameof(SelectedDisplayedXCIFiles));
|
||||||
OnPropertyChanged(nameof(DisplayedXCIFiles));
|
|
||||||
OnPropertyChanged(nameof(SelectedDisplayedXCIFiles));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplicationsChanged()
|
private void ApplicationsChanged()
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(AllXCIFiles));
|
OnPropertiesChanged(
|
||||||
OnPropertyChanged(nameof(Status));
|
nameof(AllXCIFiles),
|
||||||
OnPropertyChanged(nameof(PotentialSavings));
|
nameof(Status),
|
||||||
OnPropertyChanged(nameof(ActualSavings));
|
nameof(PotentialSavings),
|
||||||
OnPropertyChanged(nameof(CanTrim));
|
nameof(ActualSavings),
|
||||||
OnPropertyChanged(nameof(CanUntrim));
|
nameof(CanTrim),
|
||||||
|
nameof(CanUntrim));
|
||||||
|
|
||||||
DisplayedChanged();
|
DisplayedChanged();
|
||||||
SortAndFilter();
|
SortAndFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SelectionChanged(bool displayedChanged = true)
|
private void SelectionChanged(bool displayedChanged = true)
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(Status));
|
OnPropertiesChanged(
|
||||||
OnPropertyChanged(nameof(CanTrim));
|
nameof(Status),
|
||||||
OnPropertyChanged(nameof(CanUntrim));
|
nameof(CanTrim),
|
||||||
OnPropertyChanged(nameof(SelectedXCIFiles));
|
nameof(CanUntrim),
|
||||||
|
nameof(SelectedXCIFiles));
|
||||||
|
|
||||||
if (displayedChanged)
|
if (displayedChanged)
|
||||||
OnPropertyChanged(nameof(SelectedDisplayedXCIFiles));
|
OnPropertyChanged(nameof(SelectedDisplayedXCIFiles));
|
||||||
@@ -131,11 +134,12 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
private void ProcessingChanged()
|
private void ProcessingChanged()
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(Processing));
|
OnPropertiesChanged(
|
||||||
OnPropertyChanged(nameof(Cancel));
|
nameof(Processing),
|
||||||
OnPropertyChanged(nameof(Status));
|
nameof(Cancel),
|
||||||
OnPropertyChanged(nameof(CanTrim));
|
nameof(Status),
|
||||||
OnPropertyChanged(nameof(CanUntrim));
|
nameof(CanTrim),
|
||||||
|
nameof(CanUntrim));
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<XCITrimmerFileModel> GetSelectedDisplayedXCIFiles()
|
private IEnumerable<XCITrimmerFileModel> GetSelectedDisplayedXCIFiles()
|
||||||
@@ -360,7 +364,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
value = _processingApplication.Value with { PercentageProgress = null };
|
value = _processingApplication.Value with { PercentageProgress = null };
|
||||||
|
|
||||||
if (value.HasValue)
|
if (value.HasValue)
|
||||||
_displayedXCIFiles.ReplaceWith(value.Value);
|
_displayedXCIFiles.ReplaceWith(value);
|
||||||
|
|
||||||
_processingApplication = value;
|
_processingApplication = value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
Height="25"
|
Height="25"
|
||||||
Width="25"
|
Width="25"
|
||||||
ToolTip.Tip="{Binding Title}"
|
ToolTip.Tip="{Binding Title}"
|
||||||
Source="resm:Ryujinx.UI.Common.Resources.Logo_Thiccjinx.png?assembly=Ryujinx.UI.Common" />
|
Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx_AntiAlias.png?assembly=Ryujinx.UI.Common" />
|
||||||
<Menu
|
<Menu
|
||||||
Name="Menu"
|
Name="Menu"
|
||||||
Height="32"
|
Height="32"
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using LibHac.Ncm;
|
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
@@ -12,8 +10,6 @@ using Ryujinx.Ava.UI.Windows;
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
|
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
|
||||||
using Ryujinx.HLE;
|
|
||||||
using Ryujinx.UI.App.Common;
|
|
||||||
using Ryujinx.UI.Common;
|
using Ryujinx.UI.Common;
|
||||||
using Ryujinx.UI.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using Ryujinx.UI.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
@@ -124,26 +120,13 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
ViewModel.LoadConfigurableHotKeys();
|
ViewModel.LoadConfigurableHotKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly AppletMetadata MiiApplet = new("miiEdit", 0x0100000000001009);
|
||||||
|
|
||||||
public async void OpenMiiApplet(object sender, RoutedEventArgs e)
|
public async void OpenMiiApplet(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
const string AppletName = "miiEdit";
|
if (MiiApplet.CanStart(ViewModel.ContentManager, out var appData, out var nacpData))
|
||||||
const ulong AppletProgramId = 0x0100000000001009;
|
|
||||||
const string AppletVersion = "1.0.0";
|
|
||||||
|
|
||||||
string contentPath = ViewModel.ContentManager.GetInstalledContentPath(AppletProgramId, StorageId.BuiltInSystem, NcaContentType.Program);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(contentPath))
|
|
||||||
{
|
{
|
||||||
ApplicationData applicationData = new()
|
await ViewModel.LoadApplication(appData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData);
|
||||||
{
|
|
||||||
Name = AppletName,
|
|
||||||
Id = AppletProgramId,
|
|
||||||
Path = contentPath
|
|
||||||
};
|
|
||||||
|
|
||||||
var nacpData = StructHelpers.CreateCustomNacpData(AppletName, AppletVersion);
|
|
||||||
|
|
||||||
await ViewModel.LoadApplication(applicationData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||||
|
xmlns:local="clr-namespace:Ryujinx.Ava.UI.Views.Main"
|
||||||
xmlns:config="clr-namespace:Ryujinx.Common.Configuration;assembly=Ryujinx.Common"
|
xmlns:config="clr-namespace:Ryujinx.Common.Configuration;assembly=Ryujinx.Common"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="Ryujinx.Ava.UI.Views.Main.MainStatusBarView"
|
x:Class="Ryujinx.Ava.UI.Views.Main.MainStatusBarView"
|
||||||
@@ -132,14 +133,7 @@
|
|||||||
</Flyout>
|
</Flyout>
|
||||||
</Button.Flyout>
|
</Button.Flyout>
|
||||||
</Button>
|
</Button>
|
||||||
<Border
|
<controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
|
||||||
Width="2"
|
|
||||||
Height="12"
|
|
||||||
Margin="0"
|
|
||||||
BorderBrush="Gray"
|
|
||||||
Background="Gray"
|
|
||||||
BorderThickness="1"
|
|
||||||
IsVisible="{Binding !ShowLoadProgress}" />
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Name="DockedStatus"
|
Name="DockedStatus"
|
||||||
Margin="5,0,5,0"
|
Margin="5,0,5,0"
|
||||||
@@ -149,14 +143,7 @@
|
|||||||
PointerReleased="DockedStatus_PointerReleased"
|
PointerReleased="DockedStatus_PointerReleased"
|
||||||
Text="{Binding DockedStatusText}"
|
Text="{Binding DockedStatusText}"
|
||||||
TextAlignment="Start" />
|
TextAlignment="Start" />
|
||||||
<Border
|
<controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
|
||||||
Width="2"
|
|
||||||
Height="12"
|
|
||||||
Margin="0"
|
|
||||||
BorderBrush="Gray"
|
|
||||||
Background="Gray"
|
|
||||||
BorderThickness="1"
|
|
||||||
IsVisible="{Binding !ShowLoadProgress}" />
|
|
||||||
<SplitButton
|
<SplitButton
|
||||||
Name="AspectRatioStatus"
|
Name="AspectRatioStatus"
|
||||||
Padding="5,0,5,0"
|
Padding="5,0,5,0"
|
||||||
@@ -203,14 +190,7 @@
|
|||||||
</MenuFlyout>
|
</MenuFlyout>
|
||||||
</SplitButton.Flyout>
|
</SplitButton.Flyout>
|
||||||
</SplitButton>
|
</SplitButton>
|
||||||
<Border
|
<controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
|
||||||
Width="2"
|
|
||||||
Height="12"
|
|
||||||
Margin="0"
|
|
||||||
BorderBrush="Gray"
|
|
||||||
Background="Gray"
|
|
||||||
BorderThickness="1"
|
|
||||||
IsVisible="{Binding !ShowLoadProgress}" />
|
|
||||||
<ToggleSplitButton
|
<ToggleSplitButton
|
||||||
Name="VolumeStatus"
|
Name="VolumeStatus"
|
||||||
Padding="5,0,5,0"
|
Padding="5,0,5,0"
|
||||||
@@ -254,14 +234,7 @@
|
|||||||
</Flyout>
|
</Flyout>
|
||||||
</ToggleSplitButton.Flyout>
|
</ToggleSplitButton.Flyout>
|
||||||
</ToggleSplitButton>
|
</ToggleSplitButton>
|
||||||
<Border
|
<controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
|
||||||
Width="2"
|
|
||||||
Height="12"
|
|
||||||
Margin="0"
|
|
||||||
BorderBrush="Gray"
|
|
||||||
Background="Gray"
|
|
||||||
BorderThickness="1"
|
|
||||||
IsVisible="{Binding !ShowLoadProgress}" />
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="5,0,5,0"
|
Margin="5,0,5,0"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
@@ -269,14 +242,7 @@
|
|||||||
IsVisible="{Binding !ShowLoadProgress}"
|
IsVisible="{Binding !ShowLoadProgress}"
|
||||||
Text="{Binding GameStatusText}"
|
Text="{Binding GameStatusText}"
|
||||||
TextAlignment="Start" />
|
TextAlignment="Start" />
|
||||||
<Border
|
<controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
|
||||||
Width="2"
|
|
||||||
Height="12"
|
|
||||||
Margin="0"
|
|
||||||
BorderBrush="Gray"
|
|
||||||
Background="Gray"
|
|
||||||
BorderThickness="1"
|
|
||||||
IsVisible="{Binding !ShowLoadProgress}" />
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="5,0,5,0"
|
Margin="5,0,5,0"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
@@ -298,13 +264,7 @@
|
|||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
IsVisible="{Binding ShowShaderCompilationHint}"
|
IsVisible="{Binding ShowShaderCompilationHint}"
|
||||||
Text="{Binding ShaderCountText}" />
|
Text="{Binding ShaderCountText}" />
|
||||||
<Border
|
<controls:MiniVerticalSeparator IsVisible="{Binding ShowShaderCompilationHint}" />
|
||||||
Width="2"
|
|
||||||
Height="12"
|
|
||||||
Margin="0"
|
|
||||||
BorderBrush="Gray"
|
|
||||||
BorderThickness="1"
|
|
||||||
IsVisible="{Binding ShowShaderCompilationHint}" />
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="5,0,5,0"
|
Margin="5,0,5,0"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
@@ -312,14 +272,7 @@
|
|||||||
IsVisible="{Binding !ShowLoadProgress}"
|
IsVisible="{Binding !ShowLoadProgress}"
|
||||||
Text="{Binding BackendText}"
|
Text="{Binding BackendText}"
|
||||||
TextAlignment="Start" />
|
TextAlignment="Start" />
|
||||||
<Border
|
<controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
|
||||||
Width="2"
|
|
||||||
Height="12"
|
|
||||||
Margin="0"
|
|
||||||
BorderBrush="Gray"
|
|
||||||
Background="Gray"
|
|
||||||
BorderThickness="1"
|
|
||||||
IsVisible="{Binding !ShowLoadProgress}" />
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="5,0,0,0"
|
Margin="5,0,0,0"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
@@ -334,13 +287,7 @@
|
|||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
IsVisible="{Binding ShowFirmwareStatus}"
|
IsVisible="{Binding ShowFirmwareStatus}"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
<Border
|
<controls:MiniVerticalSeparator IsVisible="{Binding IsGameRunning}" />
|
||||||
Width="2"
|
|
||||||
Height="12"
|
|
||||||
Margin="0"
|
|
||||||
BorderBrush="Gray"
|
|
||||||
BorderThickness="1"
|
|
||||||
IsVisible="{Binding IsGameRunning}" />
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Name="FirmwareStatus"
|
Name="FirmwareStatus"
|
||||||
Margin="5, 0, 0, 0"
|
Margin="5, 0, 0, 0"
|
||||||
|
|||||||
@@ -62,12 +62,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
// Change the volume by 5% at a time
|
// Change the volume by 5% at a time
|
||||||
float newValue = Window.ViewModel.Volume + (float)e.Delta.Y * 0.05f;
|
float newValue = Window.ViewModel.Volume + (float)e.Delta.Y * 0.05f;
|
||||||
|
|
||||||
Window.ViewModel.Volume = newValue switch
|
Window.ViewModel.Volume = Math.Clamp(newValue, 0, 1);
|
||||||
{
|
|
||||||
< 0 => 0,
|
|
||||||
> 1 => 1,
|
|
||||||
_ => newValue,
|
|
||||||
};
|
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,12 +91,14 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar;
|
TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar;
|
||||||
TitleBar.TitleBarHitTestType = (ConfigurationState.Instance.ShowTitleBar) ? TitleBarHitTestType.Simple : TitleBarHitTestType.Complex;
|
TitleBar.TitleBarHitTestType = (ConfigurationState.Instance.ShowTitleBar) ? TitleBarHitTestType.Simple : TitleBarHitTestType.Complex;
|
||||||
|
|
||||||
// Correctly size window when 'TitleBar' is enabled (Nov. 14, 2024)
|
|
||||||
TitleBarHeight = (ConfigurationState.Instance.ShowTitleBar ? TitleBar.Height : 0);
|
|
||||||
|
|
||||||
// NOTE: Height of MenuBar and StatusBar is not usable here, since it would still be 0 at this point.
|
// NOTE: Height of MenuBar and StatusBar is not usable here, since it would still be 0 at this point.
|
||||||
StatusBarHeight = StatusBarView.StatusBar.MinHeight;
|
StatusBarHeight = StatusBarView.StatusBar.MinHeight;
|
||||||
MenuBarHeight = MenuBar.MinHeight;
|
MenuBarHeight = MenuBar.MinHeight;
|
||||||
|
|
||||||
|
TitleBar.Height = MenuBarHeight;
|
||||||
|
|
||||||
|
// Correctly size window when 'TitleBar' is enabled (Nov. 14, 2024)
|
||||||
|
TitleBarHeight = (ConfigurationState.Instance.ShowTitleBar ? TitleBar.Height : 0);
|
||||||
|
|
||||||
ApplicationList.DataContext = DataContext;
|
ApplicationList.DataContext = DataContext;
|
||||||
ApplicationGrid.DataContext = DataContext;
|
ApplicationGrid.DataContext = DataContext;
|
||||||
|
|||||||
Reference in New Issue
Block a user