Compare commits
72 Commits
xeyes
...
38c5211f99
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38c5211f99 | ||
|
|
88bf2f0941 | ||
|
|
d1efa27592 | ||
|
|
c4817b7588 | ||
|
|
7f08469dc5 | ||
|
|
ee886e54b5 | ||
|
|
313847eefe | ||
|
|
b61ca0640c | ||
|
|
43e5553113 | ||
|
|
01ef3872d3 | ||
|
|
65527cfb69 | ||
|
|
ced618d9a1 | ||
|
|
1ec039060e | ||
|
|
6b48836c62 | ||
|
|
5d4052f289 | ||
|
|
4461a7c471 | ||
|
|
edfd58bbe4 | ||
|
|
e7c991349e | ||
|
|
24867ec9b6 | ||
|
|
af00ca6ed8 | ||
|
|
931da5e1d2 | ||
|
|
451525e424 | ||
|
|
f73c9ac4de | ||
|
|
7f2dfac352 | ||
|
|
139e86915b | ||
|
|
ca8329d3da | ||
|
|
4f02b6a6de | ||
|
|
1dedf4c8d5 | ||
|
|
3f185f580c | ||
|
|
2dd787fb7b | ||
|
|
42bd99193f | ||
|
|
22299e69c6 | ||
|
|
acc06a8430 | ||
|
|
5d061a1871 | ||
|
|
c21e63eb02 | ||
|
|
32f9b3357a | ||
|
|
7f7055a037 | ||
|
|
af13f4bb3b | ||
|
|
03692e6072 | ||
|
|
6f4930d547 | ||
|
|
1ca5407c22 | ||
|
|
8efceb3c28 | ||
|
|
0399af0ff9 | ||
|
|
3e40532dee | ||
|
|
1d68546aa0 | ||
|
|
966860a464 | ||
|
|
b9982c02e3 | ||
|
|
a301a14074 | ||
|
|
7568dd4d7a | ||
|
|
4bbcec2076 | ||
|
|
57ac90a55b | ||
|
|
cdc4557d82 | ||
|
|
ae16360685 | ||
|
|
45b1794a45 | ||
|
|
39fbbb39e0 | ||
|
|
11a68a204f | ||
|
|
e4e38c4bdd | ||
|
|
5f5c76107c | ||
|
|
a92475b8fd | ||
|
|
4d5ae23b0b | ||
|
|
4cb2170ad1 | ||
|
|
fc01f7b58f | ||
|
|
fa463c51f8 | ||
|
|
3a8e6e3117 | ||
|
|
7f4a161ca5 | ||
|
|
df1c7613e8 | ||
|
|
6d37d79cc7 | ||
|
|
afdfcc1720 | ||
|
|
fe94224d01 | ||
|
|
fbe1a7d966 | ||
|
|
5dc7fb4495 | ||
|
|
2640f083b6 |
@@ -97,7 +97,7 @@ If you are planning to contribute or just want to learn more about this project
|
||||
|
||||
- **Input**
|
||||
|
||||
We currently have support for keyboard, mouse, touch input, Joy-Con input support, and nearly all controllers.
|
||||
We currently have support for keyboard, mouse, touch input, JoyCon input support, and nearly all controllers.
|
||||
Motion controls are natively supported in most cases; for dual-JoyCon motion support, DS4Windows or BetterJoy are currently required.
|
||||
In all scenarios, you can set up everything inside the input configuration menu.
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace ARMeilleure.Translation.Cache
|
||||
|
||||
private static JitCacheInvalidation _jitCacheInvalidator;
|
||||
|
||||
private static List<CacheMemoryAllocator> _cacheAllocators = [];
|
||||
private static CacheMemoryAllocator _cacheAllocator;
|
||||
|
||||
private static readonly List<CacheEntry> _cacheEntries = [];
|
||||
|
||||
@@ -40,48 +40,37 @@ namespace ARMeilleure.Translation.Cache
|
||||
|
||||
public static void Initialize(IJitMemoryAllocator allocator)
|
||||
{
|
||||
if (_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
if (_initialized)
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
JitUnwindWindows.RemoveFunctionTableHandler(
|
||||
_jitRegions[0].Pointer);
|
||||
}
|
||||
|
||||
for (int i = 0; i < _jitRegions.Count; i++)
|
||||
{
|
||||
_jitRegions[i].Dispose();
|
||||
}
|
||||
|
||||
_jitRegions.Clear();
|
||||
_cacheAllocators.Clear();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
_activeRegionIndex = 0;
|
||||
|
||||
ReservedRegion firstRegion = new(allocator, CacheSize);
|
||||
_jitRegions.Add(firstRegion);
|
||||
|
||||
CacheMemoryAllocator firstCacheAllocator = new(CacheSize);
|
||||
_cacheAllocators.Add(firstCacheAllocator);
|
||||
_activeRegionIndex = 0;
|
||||
|
||||
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
|
||||
{
|
||||
_jitCacheInvalidator = new JitCacheInvalidation(allocator);
|
||||
}
|
||||
|
||||
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
JitUnwindWindows.InstallFunctionTableHandler(
|
||||
firstRegion.Pointer, CacheSize, firstRegion.Pointer + Allocate(_pageSize)
|
||||
);
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +136,7 @@ namespace ARMeilleure.Translation.Cache
|
||||
|
||||
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
|
||||
{
|
||||
_cacheAllocators[_activeRegionIndex].Free(funcOffset, AlignCodeSize(entry.Size));
|
||||
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
|
||||
_cacheEntries.RemoveAt(entryIndex);
|
||||
}
|
||||
|
||||
@@ -178,24 +167,30 @@ namespace ARMeilleure.Translation.Cache
|
||||
{
|
||||
codeSize = AlignCodeSize(codeSize);
|
||||
|
||||
int allocOffset = _cacheAllocators[_activeRegionIndex].Allocate(codeSize);
|
||||
|
||||
if (allocOffset >= 0)
|
||||
for (int i = _activeRegionIndex; i < _jitRegions.Count; i++)
|
||||
{
|
||||
_jitRegions[_activeRegionIndex].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
||||
return allocOffset;
|
||||
int allocOffset = _cacheAllocator.Allocate(codeSize);
|
||||
|
||||
if (allocOffset >= 0)
|
||||
{
|
||||
_jitRegions[i].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
||||
_activeRegionIndex = i;
|
||||
return allocOffset;
|
||||
}
|
||||
}
|
||||
|
||||
int exhaustedRegion = _activeRegionIndex;
|
||||
ReservedRegion newRegion = new(_jitRegions[0].Allocator, CacheSize);
|
||||
_jitRegions.Add(newRegion);
|
||||
_activeRegionIndex = _jitRegions.Count - 1;
|
||||
|
||||
int newRegionNumber = _activeRegionIndex;
|
||||
|
||||
Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {_activeRegionIndex} ({((long)(_activeRegionIndex + 1) * CacheSize).Bytes()} Total Allocation).");
|
||||
Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((long)(newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation).");
|
||||
|
||||
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
|
||||
|
||||
_cacheAllocators.Add(new CacheMemoryAllocator(CacheSize));
|
||||
|
||||
int allocOffsetNew = _cacheAllocators[_activeRegionIndex].Allocate(codeSize);
|
||||
int allocOffsetNew = _cacheAllocator.Allocate(codeSize);
|
||||
if (allocOffsetNew < 0)
|
||||
{
|
||||
throw new OutOfMemoryException("Failed to allocate in new Cache Region!");
|
||||
|
||||
@@ -52,11 +52,6 @@ namespace ARMeilleure.Translation.Cache
|
||||
nint context,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string outOfProcessCallbackDll);
|
||||
|
||||
[LibraryImport("kernel32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static unsafe partial bool RtlDeleteFunctionTable(
|
||||
ulong tableIdentifier);
|
||||
|
||||
private static GetRuntimeFunctionCallback _getRuntimeFunctionCallback;
|
||||
|
||||
private static int _sizeOfRuntimeFunction;
|
||||
@@ -96,23 +91,6 @@ namespace ARMeilleure.Translation.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveFunctionTableHandler(nint codeCachePointer)
|
||||
{
|
||||
ulong codeCachePtr = (ulong)codeCachePointer.ToInt64();
|
||||
|
||||
bool result;
|
||||
|
||||
unsafe
|
||||
{
|
||||
result = RtlDeleteFunctionTable(codeCachePtr | 3);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
throw new InvalidOperationException("Failure removing function table callback.");
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe RuntimeFunction* FunctionTableHandler(ulong controlPc, nint context)
|
||||
{
|
||||
int offset = (int)((long)controlPc - context.ToInt64());
|
||||
|
||||
@@ -5,34 +5,15 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Common.Helper
|
||||
{
|
||||
public enum OperatingSystemType
|
||||
{
|
||||
MacOS,
|
||||
Linux,
|
||||
Windows
|
||||
}
|
||||
|
||||
public static class RunningPlatform
|
||||
{
|
||||
public static readonly OperatingSystemType CurrentOS
|
||||
= IsMacOS
|
||||
? OperatingSystemType.MacOS
|
||||
: IsWindows
|
||||
? OperatingSystemType.Windows
|
||||
: IsLinux
|
||||
? OperatingSystemType.Linux
|
||||
: throw new PlatformNotSupportedException();
|
||||
|
||||
public static Architecture Architecture => RuntimeInformation.OSArchitecture;
|
||||
public static Architecture CurrentProcessArchitecture => RuntimeInformation.ProcessArchitecture;
|
||||
|
||||
public static bool IsMacOS => OperatingSystem.IsMacOS();
|
||||
public static bool IsWindows => OperatingSystem.IsWindows();
|
||||
public static bool IsLinux => OperatingSystem.IsLinux();
|
||||
|
||||
public static bool IsArm => Architecture is Architecture.Arm64;
|
||||
public static bool IsArm => RuntimeInformation.OSArchitecture is Architecture.Arm64;
|
||||
|
||||
public static bool IsX64 => Architecture is Architecture.X64;
|
||||
public static bool IsX64 => RuntimeInformation.OSArchitecture is Architecture.X64;
|
||||
|
||||
public static bool IsIntelMac => IsMacOS && IsX64;
|
||||
public static bool IsArmMac => IsMacOS && IsArm;
|
||||
|
||||
@@ -71,24 +71,16 @@ namespace Ryujinx.HLE.Loaders.Mods
|
||||
int patchOffset = (int)offset;
|
||||
int patchSize = patch.Length;
|
||||
|
||||
if (patchOffset < protectedOffset)
|
||||
if (patchOffset < protectedOffset || patchOffset > memory.Length)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ModLoader, $"Attempted to patch protected memory ({patchOffset:x} is within protected boundary of {protectedOffset:x}).");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (patchOffset > memory.Length)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ModLoader, $"Attempted to patch out of bounds memory (offset {patchOffset} ({patchOffset:x}) exceeds memory buffer length {memory.Length}).");
|
||||
continue;
|
||||
continue; // Add warning?
|
||||
}
|
||||
|
||||
patchOffset -= protectedOffset;
|
||||
|
||||
if (patchOffset + patchSize > memory.Length)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ModLoader, $"Patch offset ({patchOffset:x}) + size ({patchSize}) is greater than the size of the memory buffer ({memory.Length}). Attempting to fix this...");
|
||||
patchSize = memory.Length - patchOffset;
|
||||
patchSize = memory.Length - patchOffset; // Add warning?
|
||||
}
|
||||
|
||||
Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}");
|
||||
|
||||
@@ -343,7 +343,7 @@
|
||||
<Setter Property="Foreground" Value="SeaGreen"/>
|
||||
<Setter Property="Margin" Value="5,0,0,0"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Text" Value="{ext:Locale GameSpecificConfigurationGlobal}"/>
|
||||
<Setter Property="Text" Value="(Global)"/>
|
||||
</Style>
|
||||
<Style Selector="StackPanel.globalConfigMarker">
|
||||
</Style>
|
||||
|
||||
@@ -464,7 +464,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Abrir Pasta de Capturas de Tela",
|
||||
"ru_RU": "Открыть папку со скриншотами",
|
||||
"sv_SE": "Öppna skärmbildsmappen",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Відкрити теку скріншотів",
|
||||
@@ -1564,7 +1564,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Desenvolvido por {0}",
|
||||
"ru_RU": "Разработана {0}",
|
||||
"sv_SE": "Utvecklat av {0}",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Розроблено: {0}",
|
||||
@@ -1864,7 +1864,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Compatibilidade:",
|
||||
"ru_RU": "Совместимость:",
|
||||
"sv_SE": "Kompatibilitet:",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Сумісність:",
|
||||
@@ -1889,7 +1889,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "ID do Título:",
|
||||
"ru_RU": "ID приложения",
|
||||
"sv_SE": "Titel-id:",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "ID гри:",
|
||||
@@ -1914,7 +1914,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Jogos Hospedados: {0}",
|
||||
"ru_RU": "Запущенно игр: {0}",
|
||||
"sv_SE": "Värdskap för spel: {0}",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Розміщені ігри: {0}",
|
||||
@@ -1939,7 +1939,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Jogadores Online: {0}",
|
||||
"ru_RU": "Игроков онлайн: {0}",
|
||||
"sv_SE": "Online-spelare: {0}",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Гравців онлайн: {0}",
|
||||
@@ -2289,7 +2289,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Limpar Cache PPTC",
|
||||
"ru_RU": "Очистить кэш PPTC",
|
||||
"sv_SE": "Rensa PPTC-cache",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Очистити кеш PPTC",
|
||||
@@ -2314,7 +2314,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Apaga os arquivos de cache PPTC do aplicativo",
|
||||
"ru_RU": "Удаляет все файлы кэша PPTC для приложения",
|
||||
"sv_SE": "Tar bort alla PPTC-cachefiler för applikationen",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Видаляє всі файли кешу PPTC для застосунку",
|
||||
@@ -2748,53 +2748,28 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "GameListContextMenuCreateCustomConfiguration",
|
||||
"ID": "GameListContextMenuEditGameConfiguration",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Create Custom Configuration",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "Создать пользовательскую конфигурацию",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "GameListContextMenuEditCustomConfiguration",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Edit Custom Configuration",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "Изменить пользовательскую конфигурацию",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
"ar_SA": "تعديل تكوين اللعبة",
|
||||
"de_DE": "Spielkonfiguration bearbeiten",
|
||||
"el_GR": "Επεξεργασία ρυθμίσεων παιχνιδιού",
|
||||
"en_US": "Edit Game Configuration",
|
||||
"es_ES": "Editar configuración del juego",
|
||||
"fr_FR": "Modifier la configuration du jeu",
|
||||
"he_IL": "ערוך את הגדרת המשחק",
|
||||
"it_IT": "Modifica configurazione gioco",
|
||||
"ja_JP": "ゲーム設定を編集",
|
||||
"ko_KR": "게임 설정 편집",
|
||||
"no_NO": "Rediger spillkonfig.",
|
||||
"pl_PL": "Edytuj konfigurację gry",
|
||||
"pt_BR": "Editar configuração do jogo",
|
||||
"ru_RU": "Редактировать конфигурацию игры",
|
||||
"sv_SE": "Redigera spelkonfiguration",
|
||||
"th_TH": "แก้ไขการตั้งค่าเกม",
|
||||
"tr_TR": "Oyunun yapılandırmasını düzenle",
|
||||
"uk_UA": "Редагувати конфігурацію гри",
|
||||
"zh_CN": "编辑游戏配置",
|
||||
"zh_TW": "編輯遊戲設定"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -2823,12 +2798,12 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "CreateCustomConfigurationToolTip",
|
||||
"ID": "EditGameConfigurationToolTip",
|
||||
"Translations": {
|
||||
"ar_SA": "ينشئ تكوينًا مستقلًا للعبة الحالية",
|
||||
"de_DE": "Erstellt eine unabhängige Konfiguration für das aktuelle Spiel",
|
||||
"el_GR": "Δημιουργεί μια ανεξάρτητη διαμόρφωση για το τρέχον παιχνίδι",
|
||||
"en_US": "Creates an independent configuration for the selected game",
|
||||
"en_US": "Creates an independent configuration for the current game",
|
||||
"es_ES": "Crea una configuración independiente para el juego actual",
|
||||
"fr_FR": "Crée une configuration indépendante pour le jeu en cours",
|
||||
"he_IL": "יוצר תצורה עצמאית למשחק הנוכחי",
|
||||
@@ -2847,31 +2822,6 @@
|
||||
"zh_TW": "為當前遊戲創建獨立的配置"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "EditCustomConfigurationToolTip",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Edit your existing independent configuration for the selected game",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "Отредактировать существующую независимую конфигурацию для выбранной игры.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "GameListContextMenuShowCompatEntry",
|
||||
"Translations": {
|
||||
@@ -2889,7 +2839,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Mostrar Dados de Compatibilidade",
|
||||
"ru_RU": "Показать записи о совместимости",
|
||||
"sv_SE": "Visa kompatibilitetspost",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Iнформація про сумісність",
|
||||
@@ -2914,7 +2864,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Exibe o jogo selecionado na Lista de Compatibilidade, que normalmente pode ser acessada pelo menu Ajuda.",
|
||||
"ru_RU": "Отобразить выбранную игру в списке совместимости, доступ к которому вы обычно можете получить через меню Справки.",
|
||||
"sv_SE": "Visa valt spel i kompatibilitetslistan som du normalt sett kan komma åt via hjälpmenyn.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Показати цю гру в Списку Сумісності. Список сумісності також можна зайти в меню Довідки.",
|
||||
@@ -2939,7 +2889,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Mostrar Informações do Jogo",
|
||||
"ru_RU": "Показать информацию об игре",
|
||||
"sv_SE": "Visa spelinformation",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Інформація про гру",
|
||||
@@ -2964,7 +2914,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Exibe estatísticas e detalhes sobre o jogo selecionado.",
|
||||
"ru_RU": "Показывать статистику и подробную информацию о выбранной игре.",
|
||||
"sv_SE": "Visa statistik och detaljer om det aktuella spelet.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Показати статистику та деталі обраної гри.",
|
||||
@@ -3514,7 +3464,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Verificar Atualizações:",
|
||||
"ru_RU": "Проверка наличия обновлений",
|
||||
"sv_SE": "Leta efter uppdateringar:",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Перевірка оновлень:",
|
||||
@@ -3539,7 +3489,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Desligado",
|
||||
"ru_RU": "Отключить",
|
||||
"sv_SE": "Av",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Вимкнути",
|
||||
@@ -3564,7 +3514,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Ao Abrir",
|
||||
"ru_RU": "При запуске",
|
||||
"sv_SE": "Fråga",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Запитувати щоразу",
|
||||
@@ -3589,7 +3539,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "2° Plano",
|
||||
"ru_RU": "В фоне",
|
||||
"sv_SE": "Bakgrund",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Оновлювати в фоні",
|
||||
@@ -3614,7 +3564,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Ao Perder o Foco:",
|
||||
"ru_RU": "При выходе эмулятора из фокуса",
|
||||
"sv_SE": "När emulatorn tappar fokus:",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "При втраті фокуса емулятором:",
|
||||
@@ -3639,7 +3589,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Não Fazer Nada",
|
||||
"ru_RU": "Ничего не делать",
|
||||
"sv_SE": "Gör ingenting",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Нічого не робити",
|
||||
@@ -3664,7 +3614,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Bloquear Controles",
|
||||
"ru_RU": "Блокировать управление",
|
||||
"sv_SE": "Blockera inmatning",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Блокувати введення",
|
||||
@@ -3689,7 +3639,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Ficar Mudo",
|
||||
"ru_RU": "Отключить звук",
|
||||
"sv_SE": "Stäng av ljudet",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Вимкнути звук",
|
||||
@@ -3714,7 +3664,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Bloquear Controles & Ficar Mudo",
|
||||
"ru_RU": "Блокировать управление и отключить звук",
|
||||
"sv_SE": "Blockera inmatningar och stäng av ljudet",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Блокувати введення та Вимкнути звук",
|
||||
@@ -3739,7 +3689,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Pausar a Emulação",
|
||||
"ru_RU": "Поставить паузу",
|
||||
"sv_SE": "Pausa emuleringen",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Поставити на паузу",
|
||||
@@ -3814,7 +3764,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Desativar Controles Quando Estiver Fora de Foco",
|
||||
"ru_RU": "Отключает управление при выходе из фокуса",
|
||||
"sv_SE": "Inaktivera inmatning när fokus tappas",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -4839,7 +4789,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Sincronizar com o Sistema PC",
|
||||
"ru_RU": "Соответствовать времени в системе",
|
||||
"sv_SE": "Matcha systemtid",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -5013,7 +4963,7 @@
|
||||
"no_NO": "Lyd Inn/Ut",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "Выход/Вход звука",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
@@ -5264,7 +5214,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Ignorar Applet do Controlador",
|
||||
"ru_RU": "Игнорировать апплет контроллера",
|
||||
"sv_SE": "Ignorera kontroller-applet",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Ігнорувати Аплет Контролера",
|
||||
@@ -6114,7 +6064,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Habilitar Logs da IU",
|
||||
"ru_RU": "Включить журнал интерфейса",
|
||||
"sv_SE": "Aktivera gränssnittsloggar",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Увімкнути журнали інтерфейсу",
|
||||
@@ -6514,7 +6464,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Redefinir Configurações",
|
||||
"ru_RU": "Сбросить настройки",
|
||||
"sv_SE": "Nollställ inställningar",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Скинути налаштування",
|
||||
@@ -6539,7 +6489,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Quero redefinir minhas configurações.",
|
||||
"ru_RU": "Я хочу сбросить свои настройки.",
|
||||
"sv_SE": "Jag vill nollställa mina inställningar.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Я хочу скинути налаштування.",
|
||||
@@ -6563,7 +6513,7 @@
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "Ок",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "Ok",
|
||||
"th_TH": "ตกลง",
|
||||
"tr_TR": "Tamam",
|
||||
@@ -7013,7 +6963,7 @@
|
||||
"no_NO": "",
|
||||
"pl_PL": "Pro Kontroler",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "Pro контроллер",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "โปรคอนโทรลเลอร์",
|
||||
"tr_TR": "Profesyonel Kumanda",
|
||||
@@ -8514,7 +8464,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Velocidade do Arco-íris",
|
||||
"ru_RU": "Скорость переливания",
|
||||
"sv_SE": "Regnbågshastighet",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -13814,7 +13764,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Você está prestes a limpar todos os dados PPTC de:\n\n{0}\n\nTem certeza de que deseja continuar?",
|
||||
"ru_RU": "Вы собираетесь удалить все данные PPTC из:\n\n{0}\n\nВы уверены, что хотите продолжить?",
|
||||
"sv_SE": "Du är på väg att ta bort allt PPTC-data från:\n\n{0}\n\nÄr du säker på att du vill fortsätta?",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Ви збираєтесь видалити всі дані PPTC з:\n\n{0}\n\nБажаєте продовжити цю операцію?",
|
||||
@@ -16664,7 +16614,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "A caixa de diálogo do Applet do controlador não aparecerá se o controle for desconectado enquanto um aplicativo estiver em execução.\n\nDeixe a opção DESLIGADO se não tiver certeza.",
|
||||
"ru_RU": "Диалоговое окно апплета контроллера не будет отображаться, если геймпад отключен во время работы приложения.\n\nОставьте выключенным, если не уверены.",
|
||||
"sv_SE": "Handkontroller-appleten kommer inte att visas om gamepaden är frånkopplad under tiden en applikation körs.\n\nLämna AV om du är osäker.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Діалогове вікно Аплету Контролера не з'явиться, якщо геймпад було відключено під час роботи програми.\n\nЗалиште вимкненим якщо не впевнені.",
|
||||
@@ -17139,7 +17089,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Imprime mensagens de log do Avalonia (UI) no console.",
|
||||
"ru_RU": "Выводит сообщения журнала Avalonia (интерфейс) в консоли.",
|
||||
"sv_SE": "Skriver ut loggmeddelanden från Avalonia (användargränssnittet) i konsollen.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Виводити повідомлення журналу Avalonia (UI) в консоль",
|
||||
@@ -17339,7 +17289,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Abre a pasta de capturas de tela do Ryujinx",
|
||||
"ru_RU": "Открывает папку скриншотов Ryujinx",
|
||||
"sv_SE": "Öppna Ryujinx skärmbildsmapp",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Відкрити теку куди зберігаються скріншоти Ryujinx",
|
||||
@@ -18089,7 +18039,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Atualização Disponível!",
|
||||
"ru_RU": "Доступно обновление!",
|
||||
"sv_SE": "Uppdatering finns tillgänglig!",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Доступне оновлення!",
|
||||
@@ -20013,7 +19963,7 @@
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "Амибо",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
@@ -24064,7 +24014,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Inicializa e roda sem travamentos ou bugs de GPU de qualquer tipo, e em uma velocidade rápida o suficiente para ser aproveitado em um PC comum.",
|
||||
"ru_RU": "Запускается и работает без любого рода сбоев или графисечких ошибок и на скорости, достаточной для работы на обычном ПК.",
|
||||
"sv_SE": "Startar upp och spelas utan några krascher eller GPU-fel av några slag och med en hastighet som är snabb nog för bra upplevelse på en genomsnittlig PC.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Запускається та оптимально працює (без збоїв або графічних багів) на середньостатистичному комп'ютері.",
|
||||
@@ -24089,7 +24039,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Inicializa e entra no jogo, mas sofre de um ou mais dos seguintes: travamentos, deadlocks, bugs de GPU, áudio ruim que distrai ou é simplesmente muito lento. O jogo ainda pode ser jogado até o fim, mas não da forma como foi criado para ser jogado.",
|
||||
"ru_RU": "Запускается и работает, но возникает одна или несколько из следующих проблем: сбои, взаимоблокировки, ошибки GPU, отвлекающие звуки или просто слишком медленная работа. Возможно, игру всё же удастся пройти до конца, но не так, как она задумана.",
|
||||
"sv_SE": "Startar och går in i spelet men lider av ett eller flera av följande: kraschar, deadlocks, GPU-buggar, distraherande dåligt ljud eller är helt enkelt för långsamt. Spelet kan fortfarande spelas hela vägen igenom, men inte så som spelet är avsett att spelas.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Запускається, але в грі на вас чекатимуть одна або декілька наступних проблем: збої, зависання, графічні баги, спотворений звук або ж гра загалом працюватиме надто повільно. Можливо, її все ще можна пройти, але досвід буде не найкращим.",
|
||||
@@ -24114,7 +24064,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Inicializa e passa da tela de título, mas não entra no jogo principal.",
|
||||
"ru_RU": "Загружается титульный экран и можно перейти дальше, но сама игра не работает.",
|
||||
"sv_SE": "Startar upp och går förbi titelskärmen men tar sig inte in i huvudspelet.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Запускається та проходить початковий екран, але пограти не вийде.",
|
||||
@@ -24139,7 +24089,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Inizializa, mas não passa da tela de título.",
|
||||
"ru_RU": "Загружается, но не проходит дальше титульного экрана.",
|
||||
"sv_SE": "Startar upp men tar sig inte förbi titelskärmen.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Запускається, але не відображає навіть початкового екрану.",
|
||||
@@ -24164,7 +24114,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Não inicializa ou não mostra sinais de atividade.",
|
||||
"ru_RU": "Не запускается или не подаёт признаков жизни.",
|
||||
"sv_SE": "Startar inte upp eller visar någon form av aktivitet.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Взагалі не запускається.",
|
||||
@@ -24173,37 +24123,12 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "GameSpecificConfigurationHeader",
|
||||
"ID": "UserConfigurationHeader",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Custom Config",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "GameSpecificConfigurationGlobal",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "(Global)",
|
||||
"en_US": "User Config",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
@@ -24264,7 +24189,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Imagem da Presença do Discord",
|
||||
"ru_RU": "Изображение для статуса активности",
|
||||
"sv_SE": "Bild för Rich Presence",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Зображення картки активності Discord",
|
||||
@@ -24289,7 +24214,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Presença Dinâmica do Discord",
|
||||
"ru_RU": "Динамический статус активности",
|
||||
"sv_SE": "Dynamisk Rich Presence",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Динамічна картка активності Discord",
|
||||
|
||||
@@ -158,6 +158,16 @@ namespace Ryujinx.Ava
|
||||
}
|
||||
}
|
||||
|
||||
public static bool FindGameConfig(string gameDir)
|
||||
{
|
||||
if (File.Exists(gameDir))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string GetDirGameUserConfig(string gameId, bool rememberGlobalDir = false, bool changeFolderForGame = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(gameId))
|
||||
|
||||
@@ -42,33 +42,52 @@ namespace Ryujinx.Ava
|
||||
List<string> arguments = CommandLineState.Arguments.ToList();
|
||||
string executableDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
|
||||
var dialogTask = taskDialog.ShowAsync(true);
|
||||
await Task.Delay(500);
|
||||
|
||||
// Find the process name.
|
||||
string ryuName = Path.GetFileName(Environment.ProcessPath) ?? string.Empty;
|
||||
|
||||
// Fallback if the executable could not be found.
|
||||
if (ryuName.Length == 0 || !Path.Exists(Path.Combine(executableDirectory, ryuName)))
|
||||
// On macOS we perform the update at relaunch.
|
||||
if (OperatingSystem.IsMacOS())
|
||||
{
|
||||
ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
|
||||
string baseBundlePath = Path.GetFullPath(Path.Combine(executableDirectory, "..", ".."));
|
||||
string newBundlePath = Path.Combine(_updateDir, "Ryujinx.app");
|
||||
string updaterScriptPath = Path.Combine(newBundlePath, "Contents", "Resources", "updater.sh");
|
||||
string currentPid = Environment.ProcessId.ToString();
|
||||
|
||||
arguments.InsertRange(0, new List<string> { updaterScriptPath, baseBundlePath, newBundlePath, currentPid });
|
||||
Process.Start("/bin/bash", arguments);
|
||||
}
|
||||
|
||||
ProcessStartInfo processStart = new(ryuName)
|
||||
else
|
||||
{
|
||||
UseShellExecute = true,
|
||||
WorkingDirectory = executableDirectory,
|
||||
};
|
||||
var dialogTask = taskDialog.ShowAsync(true);
|
||||
await Task.Delay(500);
|
||||
|
||||
foreach (var arg in args)
|
||||
{
|
||||
processStart.ArgumentList.Add(arg);
|
||||
// Find the process name.
|
||||
string ryuName = Path.GetFileName(Environment.ProcessPath) ?? string.Empty;
|
||||
|
||||
// Some operating systems can see the renamed executable, so strip off the .ryuold if found.
|
||||
if (ryuName.EndsWith(".ryuold"))
|
||||
{
|
||||
ryuName = ryuName[..^7];
|
||||
}
|
||||
|
||||
// Fallback if the executable could not be found.
|
||||
if (ryuName.Length == 0 || !Path.Exists(Path.Combine(executableDirectory, ryuName)))
|
||||
{
|
||||
ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
|
||||
}
|
||||
|
||||
ProcessStartInfo processStart = new(ryuName)
|
||||
{
|
||||
UseShellExecute = true,
|
||||
WorkingDirectory = executableDirectory,
|
||||
};
|
||||
|
||||
foreach (var arg in args)
|
||||
{
|
||||
processStart.ArgumentList.Add(arg);
|
||||
}
|
||||
|
||||
processStart.ArgumentList.Add(gamePath);
|
||||
|
||||
Process.Start(processStart);
|
||||
}
|
||||
|
||||
processStart.ArgumentList.Add(gamePath);
|
||||
|
||||
Process.Start(processStart);
|
||||
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Ryujinx.Ava.UI.Applet
|
||||
_parent.SettingsWindow =
|
||||
new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
|
||||
|
||||
await StyleableAppWindow.ShowAsync(_parent.SettingsWindow, window);
|
||||
await _parent.SettingsWindow.ShowDialog(window);
|
||||
|
||||
_parent.SettingsWindow = null;
|
||||
|
||||
|
||||
@@ -17,8 +17,12 @@
|
||||
<viewModels:ProfileSelectorDialogViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*,Auto">
|
||||
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border
|
||||
CornerRadius="5"
|
||||
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
|
||||
|
||||
@@ -19,18 +19,11 @@
|
||||
Header="{ext:Locale GameListContextMenuCreateShortcut}"
|
||||
Icon="{ext:Icon fa-solid fa-bookmark}"
|
||||
ToolTip.Tip="{OnPlatform Default={ext:Locale GameListContextMenuCreateShortcutToolTip}, macOS={ext:Locale GameListContextMenuCreateShortcutToolTipMacOS}}" />
|
||||
<MenuItem
|
||||
Click="EditGameConfiguration_Click"
|
||||
IsVisible="{Binding SelectedApplication.HasIndependentConfiguration}"
|
||||
Header="{ext:Locale GameListContextMenuEditCustomConfiguration}"
|
||||
Icon="{ext:Icon fa-solid fa-gear}"
|
||||
ToolTip.Tip="{ext:Locale EditCustomConfigurationToolTip}" />
|
||||
<MenuItem
|
||||
Click="EditGameConfiguration_Click"
|
||||
IsVisible="{Binding !SelectedApplication.HasIndependentConfiguration}"
|
||||
Header="{ext:Locale GameListContextMenuCreateCustomConfiguration}"
|
||||
Header="{ext:Locale GameListContextMenuEditGameConfiguration}"
|
||||
Icon="{ext:Icon fa-solid fa-gear}"
|
||||
ToolTip.Tip="{ext:Locale CreateCustomConfigurationToolTip}" />
|
||||
ToolTip.Tip="{ext:Locale EditGameConfigurationToolTip}" />
|
||||
<MenuItem
|
||||
IsVisible="{Binding HasCompatibilityEntry}"
|
||||
Click="OpenApplicationCompatibility_Click"
|
||||
|
||||
@@ -91,14 +91,11 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
public async void OpenCheatManager_Click(object sender, RoutedEventArgs args)
|
||||
{
|
||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||
await StyleableAppWindow.ShowAsync(
|
||||
new CheatWindow(
|
||||
viewModel.VirtualFileSystem,
|
||||
viewModel.SelectedApplication.IdString,
|
||||
viewModel.SelectedApplication.Name,
|
||||
viewModel.SelectedApplication.Path
|
||||
)
|
||||
);
|
||||
await new CheatWindow(
|
||||
viewModel.VirtualFileSystem,
|
||||
viewModel.SelectedApplication.IdString,
|
||||
viewModel.SelectedApplication.Name,
|
||||
viewModel.SelectedApplication.Path).ShowDialog((Window)viewModel.TopLevel);
|
||||
}
|
||||
|
||||
public void OpenModsDirectory_Click(object sender, RoutedEventArgs args)
|
||||
@@ -203,7 +200,7 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
if (backupDir.Exists)
|
||||
{
|
||||
cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
|
||||
cacheFiles.AddRange(backupDir.EnumerateFiles("*.info"));
|
||||
cacheFiles.AddRange(mainDir.EnumerateFiles("*.info"));
|
||||
}
|
||||
|
||||
if (cacheFiles.Count > 0)
|
||||
@@ -394,9 +391,9 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
{
|
||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||
{
|
||||
await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(viewModel));
|
||||
await new GameSpecificSettingsWindow(viewModel).ShowDialog((Window)viewModel.TopLevel);
|
||||
|
||||
// just checking for file presence
|
||||
//just checking for file presence
|
||||
viewModel.SelectedApplication.HasIndependentConfiguration = File.Exists(Program.GetDirGameUserConfig(viewModel.SelectedApplication.IdString,false,false));
|
||||
|
||||
viewModel.RefreshView();
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
mc:Ignorable="d"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||
x:DataType="viewModels:MainWindowViewModel">
|
||||
<Grid RowDefinitions="*">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox
|
||||
Grid.Row="0"
|
||||
Padding="8"
|
||||
@@ -54,7 +57,11 @@
|
||||
Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}"
|
||||
ClipToBounds="True"
|
||||
CornerRadius="4">
|
||||
<Grid RowDefinitions="Auto,Auto">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Grid.Row="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
@@ -74,7 +81,7 @@
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
IsVisible="{Binding HasIndependentConfiguration}"
|
||||
Text="{ext:Locale GameSpecificConfigurationHeader}"
|
||||
Text="{ext:Locale UserConfigurationHeader}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource Warning}" />
|
||||
@@ -103,7 +110,7 @@
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="{ext:Locale GameSpecificConfigurationHeader}"
|
||||
Text="{ext:Locale UserConfigurationHeader}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
</Border>
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
mc:Ignorable="d"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||
x:DataType="viewModels:MainWindowViewModel">
|
||||
<Grid RowDefinitions="*">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox
|
||||
Name="GameListBox"
|
||||
Grid.Row="0"
|
||||
@@ -157,7 +160,7 @@
|
||||
<TextBlock
|
||||
HorizontalAlignment="Stretch"
|
||||
IsVisible="{Binding HasIndependentConfiguration}"
|
||||
Text="{ext:Locale GameSpecificConfigurationHeader}"
|
||||
Text="{ext:Locale UserConfigurationHeader}"
|
||||
TextAlignment="Start"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource Warning}" />
|
||||
|
||||
@@ -13,7 +13,15 @@
|
||||
<Grid
|
||||
Margin="20"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch" ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto">
|
||||
VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image
|
||||
Grid.Row="1"
|
||||
Height="70"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
@@ -385,10 +384,6 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
Position = parent.PointToScreen(new Point()),
|
||||
ShowInTaskbar = false,
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
_contentDialogOverlayWindow.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control));
|
||||
#endif
|
||||
|
||||
parent.PositionChanged += OverlayOnPositionChanged;
|
||||
|
||||
|
||||
@@ -1,260 +0,0 @@
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using Ryujinx.Input;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Models.Input
|
||||
{
|
||||
public class StickVisualizer : BaseModel, IDisposable
|
||||
{
|
||||
public const int DrawStickPollRate = 50; // Milliseconds per poll.
|
||||
public const int DrawStickCircumference = 5;
|
||||
public const float DrawStickScaleFactor = DrawStickCanvasCenter;
|
||||
public const int DrawStickCanvasSize = 100;
|
||||
public const int DrawStickBorderSize = DrawStickCanvasSize + 5;
|
||||
public const float DrawStickCanvasCenter = (DrawStickCanvasSize - DrawStickCircumference) / 2;
|
||||
public const float MaxVectorLength = DrawStickCanvasSize / 2;
|
||||
|
||||
public CancellationTokenSource PollTokenSource;
|
||||
public CancellationToken PollToken;
|
||||
|
||||
private static float _vectorLength;
|
||||
private static float _vectorMultiplier;
|
||||
|
||||
private bool disposedValue;
|
||||
|
||||
private DeviceType _type;
|
||||
public DeviceType Type
|
||||
{
|
||||
get => _type;
|
||||
set
|
||||
{
|
||||
_type = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private GamepadInputConfig _gamepadConfig;
|
||||
public GamepadInputConfig GamepadConfig
|
||||
{
|
||||
get => _gamepadConfig;
|
||||
set
|
||||
{
|
||||
_gamepadConfig = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private KeyboardInputConfig _keyboardConfig;
|
||||
public KeyboardInputConfig KeyboardConfig
|
||||
{
|
||||
get => _keyboardConfig;
|
||||
set
|
||||
{
|
||||
_keyboardConfig = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private (float, float) _uiStickLeft;
|
||||
public (float, float) UiStickLeft
|
||||
{
|
||||
get => (_uiStickLeft.Item1 * DrawStickScaleFactor, _uiStickLeft.Item2 * DrawStickScaleFactor);
|
||||
set
|
||||
{
|
||||
_uiStickLeft = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(UiStickRightX));
|
||||
OnPropertyChanged(nameof(UiStickRightY));
|
||||
OnPropertyChanged(nameof(UiDeadzoneRight));
|
||||
}
|
||||
}
|
||||
|
||||
private (float, float) _uiStickRight;
|
||||
public (float, float) UiStickRight
|
||||
{
|
||||
get => (_uiStickRight.Item1 * DrawStickScaleFactor, _uiStickRight.Item2 * DrawStickScaleFactor);
|
||||
set
|
||||
{
|
||||
_uiStickRight = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(UiStickLeftX));
|
||||
OnPropertyChanged(nameof(UiStickLeftY));
|
||||
OnPropertyChanged(nameof(UiDeadzoneLeft));
|
||||
}
|
||||
}
|
||||
|
||||
public float UiStickLeftX => ClampVector(UiStickLeft).Item1;
|
||||
public float UiStickLeftY => ClampVector(UiStickLeft).Item2;
|
||||
public float UiStickRightX => ClampVector(UiStickRight).Item1;
|
||||
public float UiStickRightY => ClampVector(UiStickRight).Item2;
|
||||
|
||||
public int UiStickCircumference => DrawStickCircumference;
|
||||
public int UiCanvasSize => DrawStickCanvasSize;
|
||||
public int UiStickBorderSize => DrawStickBorderSize;
|
||||
|
||||
public float? UiDeadzoneLeft => _gamepadConfig?.DeadzoneLeft * DrawStickCanvasSize - DrawStickCircumference;
|
||||
public float? UiDeadzoneRight => _gamepadConfig?.DeadzoneRight * DrawStickCanvasSize - DrawStickCircumference;
|
||||
|
||||
private InputViewModel Parent;
|
||||
|
||||
public StickVisualizer(InputViewModel parent)
|
||||
{
|
||||
Parent = parent;
|
||||
|
||||
PollTokenSource = new CancellationTokenSource();
|
||||
PollToken = PollTokenSource.Token;
|
||||
|
||||
Task.Run(Initialize, PollToken);
|
||||
}
|
||||
|
||||
public void UpdateConfig(object config)
|
||||
{
|
||||
if (config is ControllerInputViewModel padConfig)
|
||||
{
|
||||
GamepadConfig = padConfig.Config;
|
||||
Type = DeviceType.Controller;
|
||||
|
||||
return;
|
||||
}
|
||||
else if (config is KeyboardInputViewModel keyConfig)
|
||||
{
|
||||
KeyboardConfig = keyConfig.Config;
|
||||
Type = DeviceType.Keyboard;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Type = DeviceType.None;
|
||||
}
|
||||
|
||||
public async Task Initialize()
|
||||
{
|
||||
(float, float) leftBuffer;
|
||||
(float, float) rightBuffer;
|
||||
|
||||
while (!PollToken.IsCancellationRequested)
|
||||
{
|
||||
leftBuffer = (0f, 0f);
|
||||
rightBuffer = (0f, 0f);
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case DeviceType.Keyboard:
|
||||
IKeyboard keyboard = (IKeyboard)Parent.AvaloniaKeyboardDriver.GetGamepad("0");
|
||||
|
||||
if (keyboard != null)
|
||||
{
|
||||
KeyboardStateSnapshot snapshot = keyboard.GetKeyboardStateSnapshot();
|
||||
|
||||
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickRight))
|
||||
{
|
||||
leftBuffer.Item1 += 1;
|
||||
}
|
||||
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickLeft))
|
||||
{
|
||||
leftBuffer.Item1 -= 1;
|
||||
}
|
||||
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickUp))
|
||||
{
|
||||
leftBuffer.Item2 += 1;
|
||||
}
|
||||
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickDown))
|
||||
{
|
||||
leftBuffer.Item2 -= 1;
|
||||
}
|
||||
|
||||
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickRight))
|
||||
{
|
||||
rightBuffer.Item1 += 1;
|
||||
}
|
||||
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickLeft))
|
||||
{
|
||||
rightBuffer.Item1 -= 1;
|
||||
}
|
||||
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickUp))
|
||||
{
|
||||
rightBuffer.Item2 += 1;
|
||||
}
|
||||
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickDown))
|
||||
{
|
||||
rightBuffer.Item2 -= 1;
|
||||
}
|
||||
|
||||
UiStickLeft = leftBuffer;
|
||||
UiStickRight = rightBuffer;
|
||||
}
|
||||
break;
|
||||
|
||||
case DeviceType.Controller:
|
||||
IGamepad controller = Parent.SelectedGamepad;
|
||||
|
||||
if (controller != null)
|
||||
{
|
||||
leftBuffer = controller.GetStick((StickInputId)GamepadConfig.LeftJoystick);
|
||||
rightBuffer = controller.GetStick((StickInputId)GamepadConfig.RightJoystick);
|
||||
}
|
||||
break;
|
||||
|
||||
case DeviceType.None:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException($"Unable to poll device type \"{Type}\"");
|
||||
}
|
||||
|
||||
UiStickLeft = leftBuffer;
|
||||
UiStickRight = rightBuffer;
|
||||
|
||||
await Task.Delay(DrawStickPollRate, PollToken);
|
||||
}
|
||||
|
||||
PollTokenSource.Dispose();
|
||||
}
|
||||
|
||||
public static (float, float) ClampVector((float, float) vect)
|
||||
{
|
||||
_vectorMultiplier = 1;
|
||||
_vectorLength = MathF.Sqrt((vect.Item1 * vect.Item1) + (vect.Item2 * vect.Item2));
|
||||
|
||||
if (_vectorLength > MaxVectorLength)
|
||||
{
|
||||
_vectorMultiplier = MaxVectorLength / _vectorLength;
|
||||
}
|
||||
|
||||
vect.Item1 = vect.Item1 * _vectorMultiplier + DrawStickCanvasCenter;
|
||||
vect.Item2 = vect.Item2 * _vectorMultiplier + DrawStickCanvasCenter;
|
||||
|
||||
return vect;
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
PollTokenSource.Cancel();
|
||||
}
|
||||
|
||||
KeyboardConfig = null;
|
||||
GamepadConfig = null;
|
||||
Parent = null;
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
using Avalonia.Svg.Skia;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Input;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.Models.Input;
|
||||
using Ryujinx.Ava.UI.Views.Input;
|
||||
using Ryujinx.Common.Utilities;
|
||||
@@ -14,30 +10,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
{
|
||||
public partial class ControllerInputViewModel : BaseModel
|
||||
{
|
||||
private GamepadInputConfig _config;
|
||||
public GamepadInputConfig Config
|
||||
{
|
||||
get => _config;
|
||||
set
|
||||
{
|
||||
_config = value;
|
||||
[ObservableProperty] private GamepadInputConfig _config;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private StickVisualizer _visualizer;
|
||||
public StickVisualizer Visualizer
|
||||
{
|
||||
get => _visualizer;
|
||||
set
|
||||
{
|
||||
_visualizer = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isLeft;
|
||||
public bool IsLeft
|
||||
{
|
||||
@@ -63,15 +37,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
}
|
||||
|
||||
public bool HasSides => IsLeft ^ IsRight;
|
||||
|
||||
|
||||
[ObservableProperty] private SvgImage _image;
|
||||
|
||||
|
||||
public InputViewModel ParentModel { get; }
|
||||
|
||||
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer)
|
||||
|
||||
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
|
||||
{
|
||||
ParentModel = model;
|
||||
Visualizer = visualizer;
|
||||
model.NotifyChangesEvent += OnParentModelChanged;
|
||||
OnParentModelChanged();
|
||||
config.PropertyChanged += (_, args) =>
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
private int _controller;
|
||||
private string _controllerImage;
|
||||
private int _device;
|
||||
private object _configViewModel;
|
||||
[ObservableProperty] private object _configViewModel;
|
||||
[ObservableProperty] private string _profileName;
|
||||
private bool _isLoaded;
|
||||
|
||||
@@ -74,7 +74,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
|
||||
}
|
||||
}
|
||||
public StickVisualizer VisualStick { get; private set; }
|
||||
|
||||
public ObservableCollection<PlayerModel> PlayerIndexes { get; set; }
|
||||
public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; }
|
||||
@@ -95,19 +94,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
public bool IsModified { get; set; }
|
||||
public event Action NotifyChangesEvent;
|
||||
|
||||
public object ConfigViewModel
|
||||
{
|
||||
get => _configViewModel;
|
||||
set
|
||||
{
|
||||
_configViewModel = value;
|
||||
|
||||
VisualStick.UpdateConfig(value);
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerIndex PlayerIdChoose
|
||||
{
|
||||
get => _playerIdChoose;
|
||||
@@ -283,7 +269,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
Devices = [];
|
||||
ProfilesList = [];
|
||||
DeviceList = [];
|
||||
VisualStick = new StickVisualizer(this);
|
||||
|
||||
ControllerImage = ProControllerResource;
|
||||
|
||||
@@ -304,12 +289,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
|
||||
if (Config is StandardKeyboardInputConfig keyboardInputConfig)
|
||||
{
|
||||
ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig), VisualStick);
|
||||
ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig));
|
||||
}
|
||||
|
||||
if (Config is StandardControllerInputConfig controllerInputConfig)
|
||||
{
|
||||
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick);
|
||||
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -908,8 +893,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
|
||||
_mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates();
|
||||
|
||||
VisualStick.Dispose();
|
||||
|
||||
SelectedGamepad?.Dispose();
|
||||
|
||||
AvaloniaKeyboardDriver.Dispose();
|
||||
|
||||
@@ -6,29 +6,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
{
|
||||
public partial class KeyboardInputViewModel : BaseModel
|
||||
{
|
||||
private KeyboardInputConfig _config;
|
||||
public KeyboardInputConfig Config
|
||||
{
|
||||
get => _config;
|
||||
set
|
||||
{
|
||||
_config = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private StickVisualizer _visualizer;
|
||||
public StickVisualizer Visualizer
|
||||
{
|
||||
get => _visualizer;
|
||||
set
|
||||
{
|
||||
_visualizer = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
[ObservableProperty] private KeyboardInputConfig _config;
|
||||
|
||||
private bool _isLeft;
|
||||
public bool IsLeft
|
||||
@@ -60,10 +38,9 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
|
||||
public readonly InputViewModel ParentModel;
|
||||
|
||||
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config, StickVisualizer visualizer)
|
||||
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config)
|
||||
{
|
||||
ParentModel = model;
|
||||
Visualizer = visualizer;
|
||||
model.NotifyChangesEvent += OnParentModelChanged;
|
||||
OnParentModelChanged();
|
||||
Config = config;
|
||||
|
||||
@@ -1747,7 +1747,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
string titleId = AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper();
|
||||
AmiiboWindow window = new(ShowAll, LastScannedAmiiboId, titleId);
|
||||
|
||||
await StyleableAppWindow.ShowAsync(window);
|
||||
await window.ShowDialog(Window);
|
||||
|
||||
if (window.IsScanned)
|
||||
{
|
||||
|
||||
@@ -34,7 +34,12 @@
|
||||
<!-- Button / JoyStick Settings -->
|
||||
<Grid
|
||||
Name="SettingButtons"
|
||||
MinHeight="450" ColumnDefinitions="Auto,*,Auto">
|
||||
MinHeight="450">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Left Controls -->
|
||||
<StackPanel
|
||||
Orientation="Vertical"
|
||||
@@ -49,7 +54,15 @@
|
||||
CornerRadius="5">
|
||||
<Grid
|
||||
Margin="10"
|
||||
HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
@@ -303,99 +316,17 @@
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<!-- Controller Picture -->
|
||||
<Image
|
||||
Margin="0,10"
|
||||
MaxHeight="300"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Source="{Binding Image}" />
|
||||
<Border
|
||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Margin="0,0, 0, 5"
|
||||
MinHeight="90">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Image
|
||||
Margin="5,10"
|
||||
MaxHeight="300"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Source="{Binding Image}" />
|
||||
<StackPanel
|
||||
Margin="10"
|
||||
Orientation="Horizontal"
|
||||
Spacing="20"
|
||||
HorizontalAlignment="Center">
|
||||
<Border
|
||||
BorderBrush="Transparent"
|
||||
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||
IsVisible="{Binding IsLeft}">
|
||||
<Canvas
|
||||
Background="{DynamicResource ThemeBackgroundColor}"
|
||||
Height="{Binding Visualizer.UiCanvasSize}"
|
||||
Width="{Binding Visualizer.UiCanvasSize}">
|
||||
<Grid
|
||||
Height="{Binding Visualizer.UiCanvasSize}"
|
||||
Width="{Binding Visualizer.UiCanvasSize}"
|
||||
Background="{DynamicResource ThemeBackgroundColor}">
|
||||
<Ellipse
|
||||
HorizontalAlignment="Center"
|
||||
Stroke="{DynamicResource ThemeControlBorderColor}"
|
||||
StrokeThickness="1"
|
||||
Width="{Binding Visualizer.UiCanvasSize}"
|
||||
Height="{Binding Visualizer.UiCanvasSize}" />
|
||||
<Ellipse
|
||||
HorizontalAlignment="Center"
|
||||
Fill="Black"
|
||||
Opacity="100"
|
||||
Height="{Binding Visualizer.UiDeadzoneLeft}"
|
||||
Width="{Binding Visualizer.UiDeadzoneLeft}" />
|
||||
</Grid>
|
||||
<Ellipse
|
||||
Fill="{DynamicResource Warning}"
|
||||
Width="{Binding Visualizer.UiStickCircumference}"
|
||||
Height="{Binding Visualizer.UiStickCircumference}"
|
||||
Canvas.Bottom="{Binding Visualizer.UiStickLeftY}"
|
||||
Canvas.Left="{Binding Visualizer.UiStickLeftX}" />
|
||||
</Canvas>
|
||||
</Border>
|
||||
<Border
|
||||
BorderBrush="Transparent"
|
||||
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||
IsVisible="{Binding IsRight}">
|
||||
<Canvas
|
||||
Background="{DynamicResource ThemeBackgroundColor}"
|
||||
Height="{Binding Visualizer.UiCanvasSize}"
|
||||
Width="{Binding Visualizer.UiCanvasSize}">
|
||||
<Grid
|
||||
Height="{Binding Visualizer.UiCanvasSize}"
|
||||
Width="{Binding Visualizer.UiCanvasSize}"
|
||||
Background="{DynamicResource ThemeBackgroundColor}">
|
||||
<Ellipse
|
||||
HorizontalAlignment="Center"
|
||||
Stroke="{DynamicResource ThemeControlBorderColor}"
|
||||
StrokeThickness="1"
|
||||
Width="{Binding Visualizer.UiCanvasSize}"
|
||||
Height="{Binding Visualizer.UiCanvasSize}" />
|
||||
<Ellipse
|
||||
HorizontalAlignment="Center"
|
||||
Fill="Black"
|
||||
Opacity="100"
|
||||
Height="{Binding Visualizer.UiDeadzoneRight}"
|
||||
Width="{Binding Visualizer.UiDeadzoneRight}" />
|
||||
</Grid>
|
||||
<Ellipse
|
||||
Fill="{DynamicResource Warning}"
|
||||
Width="{Binding Visualizer.UiStickCircumference}"
|
||||
Height="{Binding Visualizer.UiStickCircumference}"
|
||||
Canvas.Bottom="{Binding Visualizer.UiStickRightY}"
|
||||
Canvas.Left="{Binding Visualizer.UiStickRightX}" />
|
||||
</Canvas>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Border
|
||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5">
|
||||
<StackPanel
|
||||
Margin="8"
|
||||
Orientation="Vertical">
|
||||
@@ -414,8 +345,8 @@
|
||||
Minimum="0"
|
||||
Value="{Binding Config.TriggerThreshold, Mode=TwoWay}" />
|
||||
<TextBlock
|
||||
Width="25"
|
||||
Text="{Binding Config.TriggerThreshold, StringFormat=\{0:0.00\}}" />
|
||||
Width="25"
|
||||
Text="{Binding Config.TriggerThreshold, StringFormat=\{0:0.00\}}" />
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Orientation="Vertical"
|
||||
@@ -497,7 +428,7 @@
|
||||
</Border>
|
||||
<!-- Motion, Rumble, LED -->
|
||||
<StackPanel
|
||||
Margin="0,5,0,0"
|
||||
Margin="0,10,0,0"
|
||||
Spacing="5"
|
||||
Orientation="Vertical"
|
||||
VerticalAlignment="Bottom">
|
||||
@@ -507,7 +438,11 @@
|
||||
CornerRadius="5"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<CheckBox
|
||||
Margin="10"
|
||||
MinWidth="0"
|
||||
@@ -529,7 +464,11 @@
|
||||
CornerRadius="5"
|
||||
HorizontalAlignment="Stretch"
|
||||
Margin="0,-1,0,0">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<CheckBox
|
||||
Margin="10"
|
||||
MinWidth="0"
|
||||
@@ -551,7 +490,11 @@
|
||||
CornerRadius="5"
|
||||
HorizontalAlignment="Stretch"
|
||||
Margin="0,-1,0,0">
|
||||
<Grid IsVisible="{Binding ParentModel.HasLed}" ColumnDefinitions="*,Auto">
|
||||
<Grid IsVisible="{Binding ParentModel.HasLed}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<CheckBox
|
||||
Margin="10, 10, 5, 10"
|
||||
MinWidth="0"
|
||||
@@ -583,7 +526,15 @@
|
||||
CornerRadius="5">
|
||||
<Grid
|
||||
Margin="10"
|
||||
HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel
|
||||
Grid.Column="1"
|
||||
Grid.Row="0"
|
||||
|
||||
@@ -35,13 +35,22 @@
|
||||
Margin="0 0 0 5"
|
||||
Orientation="Vertical"
|
||||
Spacing="5">
|
||||
<Grid ColumnDefinitions="*,10,*">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Player Selection -->
|
||||
<Grid
|
||||
Grid.Column="0"
|
||||
Margin="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center" ColumnDefinitions="Auto,*">
|
||||
VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Margin="5,0,10,0"
|
||||
Width="90"
|
||||
@@ -68,7 +77,14 @@
|
||||
Grid.Column="2"
|
||||
Margin="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center" ColumnDefinitions="Auto,*,Auto,Auto,Auto">
|
||||
VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Margin="5,0,10,0"
|
||||
Width="90"
|
||||
@@ -123,12 +139,22 @@
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Separator />
|
||||
<Grid ColumnDefinitions="*,10,*">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Input Device -->
|
||||
<Grid
|
||||
Grid.Column="0"
|
||||
Margin="2"
|
||||
HorizontalAlignment="Stretch" ColumnDefinitions="Auto,*,Auto">
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Margin="5,0,10,0"
|
||||
@@ -160,7 +186,11 @@
|
||||
Grid.Column="2"
|
||||
Margin="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center" ColumnDefinitions="Auto,*">
|
||||
VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Margin="5,0,10,0"
|
||||
Width="90"
|
||||
|
||||
@@ -32,7 +32,12 @@
|
||||
<!-- Button / JoyStick Settings -->
|
||||
<Grid
|
||||
Name="SettingButtons"
|
||||
MinHeight="450" ColumnDefinitions="Auto,*,Auto">
|
||||
MinHeight="450">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Left Controls -->
|
||||
<StackPanel
|
||||
Orientation="Vertical"
|
||||
@@ -47,7 +52,15 @@
|
||||
CornerRadius="5">
|
||||
<Grid
|
||||
Margin="10"
|
||||
HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
@@ -296,79 +309,12 @@
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<!-- Controller Picture -->
|
||||
<Border
|
||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
<Image
|
||||
Margin="0,10"
|
||||
MinHeight="90">
|
||||
<StackPanel
|
||||
Margin="10"
|
||||
Orientation="Horizontal"
|
||||
Spacing="20"
|
||||
HorizontalAlignment="Center">
|
||||
<Border
|
||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||
IsVisible="{Binding IsLeft}">
|
||||
<Canvas
|
||||
Background="{DynamicResource ThemeBackgroundColor}"
|
||||
Height="{Binding Visualizer.UiCanvasSize}"
|
||||
Width="{Binding Visualizer.UiCanvasSize}">
|
||||
<Grid
|
||||
Height="{Binding Visualizer.UiCanvasSize}"
|
||||
Width="{Binding Visualizer.UiCanvasSize}"
|
||||
Background="{DynamicResource ThemeBackgroundColor}">
|
||||
<Ellipse
|
||||
HorizontalAlignment="Center"
|
||||
Stroke="Black"
|
||||
StrokeThickness="1"
|
||||
Width="{Binding Visualizer.UiCanvasSize}"
|
||||
Height="{Binding Visualizer.UiCanvasSize}"/>
|
||||
</Grid>
|
||||
<Ellipse
|
||||
Fill="Red"
|
||||
Width="{Binding Visualizer.UiStickCircumference}"
|
||||
Height="{Binding Visualizer.UiStickCircumference}"
|
||||
Canvas.Bottom="{Binding Visualizer.UiStickLeftY}"
|
||||
Canvas.Left="{Binding Visualizer.UiStickLeftX}" />
|
||||
</Canvas>
|
||||
</Border>
|
||||
<Border
|
||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||
IsVisible="{Binding IsRight}">
|
||||
<Canvas
|
||||
Background="{DynamicResource ThemeBackgroundColor}"
|
||||
Height="{Binding Visualizer.UiCanvasSize}"
|
||||
Width="{Binding Visualizer.UiCanvasSize}">
|
||||
<Grid
|
||||
Height="{Binding Visualizer.UiCanvasSize}"
|
||||
Width="{Binding Visualizer.UiCanvasSize}"
|
||||
Background="{DynamicResource ThemeBackgroundColor}">
|
||||
<Ellipse
|
||||
HorizontalAlignment="Center"
|
||||
Stroke="Black"
|
||||
StrokeThickness="1"
|
||||
Width="{Binding Visualizer.UiCanvasSize}"
|
||||
Height="{Binding Visualizer.UiCanvasSize}"/>
|
||||
</Grid>
|
||||
<Ellipse
|
||||
Fill="Red"
|
||||
Width="{Binding Visualizer.UiStickCircumference}"
|
||||
Height="{Binding Visualizer.UiStickCircumference}"
|
||||
Canvas.Bottom="{Binding Visualizer.UiStickRightY}"
|
||||
Canvas.Left="{Binding Visualizer.UiStickRightX}" />
|
||||
</Canvas>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
MaxHeight="300"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Source="{Binding Image}" />
|
||||
<Border
|
||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||
BorderThickness="1"
|
||||
@@ -467,7 +413,15 @@
|
||||
CornerRadius="5">
|
||||
<Grid
|
||||
Margin="10"
|
||||
HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel
|
||||
Grid.Column="1"
|
||||
Grid.Row="0"
|
||||
|
||||
@@ -11,7 +11,11 @@
|
||||
x:Class="Ryujinx.Ava.UI.Views.Input.MotionInputView"
|
||||
x:DataType="viewModels:MotionInputViewModel"
|
||||
Focusable="True">
|
||||
<Grid Margin="10" RowDefinitions="Auto,*">
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
@@ -76,7 +80,11 @@
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid VerticalAlignment="Top" RowDefinitions="Auto,*">
|
||||
<Grid VerticalAlignment="Top">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Center"
|
||||
@@ -110,7 +118,15 @@
|
||||
Text="{Binding DsuServerPort, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,*">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Margin="0,10,0,0"
|
||||
VerticalAlignment="Center"
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
x:Class="Ryujinx.Ava.UI.Views.Input.RumbleInputView"
|
||||
x:DataType="viewModels:RumbleInputViewModel"
|
||||
Focusable="True">
|
||||
<Grid Margin="10" RowDefinitions="Auto,*">
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock
|
||||
|
||||
@@ -19,7 +19,6 @@ using Ryujinx.Common.Utilities;
|
||||
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -134,20 +133,20 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
|
||||
if (ViewModel.SelectedApplication is null) // Checks if game data exists
|
||||
{
|
||||
await StyleableAppWindow.ShowAsync(Window.SettingsWindow);
|
||||
await Window.SettingsWindow.ShowDialog(Window);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool customConfigExists = File.Exists(Program.GetDirGameUserConfig(ViewModel.SelectedApplication.IdString));
|
||||
bool userConfigExist = Program.FindGameConfig(Program.GetDirGameUserConfig(ViewModel.SelectedApplication.IdString, false, false));
|
||||
|
||||
if (!ViewModel.IsGameRunning || !customConfigExists)
|
||||
if (!ViewModel.IsGameRunning || !userConfigExist)
|
||||
{
|
||||
await Window.SettingsWindow.ShowDialog(Window); // The game is not running, or if the user configuration does not exist
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there is a custom configuration in the folder
|
||||
await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(ViewModel, customConfigExists));
|
||||
await new GameSpecificSettingsWindow(ViewModel, userConfigExist).ShowDialog((Window)ViewModel.TopLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,13 +175,11 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
|
||||
string name = ViewModel.AppHost.Device.Processes.ActiveApplication.ApplicationControlProperties.Title[(int)ViewModel.AppHost.Device.System.State.DesiredTitleLanguage].NameString.ToString();
|
||||
|
||||
await StyleableAppWindow.ShowAsync(
|
||||
new CheatWindow(
|
||||
Window.VirtualFileSystem,
|
||||
ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText,
|
||||
name,
|
||||
ViewModel.SelectedApplication.Path)
|
||||
);
|
||||
await new CheatWindow(
|
||||
Window.VirtualFileSystem,
|
||||
ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText,
|
||||
name,
|
||||
ViewModel.SelectedApplication.Path).ShowDialog(Window);
|
||||
|
||||
ViewModel.AppHost.Device.EnableCheats();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,12 @@
|
||||
<Border Classes="settings">
|
||||
<Panel
|
||||
Margin="10">
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<views:InputView
|
||||
Grid.Row="0"
|
||||
Name="InputView" />
|
||||
|
||||
@@ -177,7 +177,12 @@
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
</ListBox>
|
||||
<Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto,Auto">
|
||||
<Grid HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox
|
||||
Name="GameDirPathBox"
|
||||
Margin="0"
|
||||
@@ -230,7 +235,12 @@
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
</ListBox>
|
||||
<Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto,Auto">
|
||||
<Grid HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox
|
||||
Name="AutoloadDirPathBox"
|
||||
Margin="0"
|
||||
|
||||
@@ -14,7 +14,15 @@
|
||||
mc:Ignorable="d"
|
||||
Focusable="True"
|
||||
x:DataType="models:TempProfile">
|
||||
<Grid Margin="0" ColumnDefinitions="Auto,*" RowDefinitions="*,Auto">
|
||||
<Grid Margin="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
|
||||
@@ -20,7 +20,13 @@
|
||||
<Grid
|
||||
Margin="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch" RowDefinitions="Auto,*,Auto,Auto">
|
||||
VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox
|
||||
Grid.Row="1"
|
||||
BorderThickness="0"
|
||||
|
||||
@@ -17,7 +17,12 @@
|
||||
</Design.DataContext>
|
||||
<Grid
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center" RowDefinitions="Auto,70,Auto">
|
||||
VerticalAlignment="Center">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="70" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
TextWrapping="Wrap"
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
<viewModels:UserProfileViewModel />
|
||||
</Design.DataContext>
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch" RowDefinitions="*,Auto">
|
||||
VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Border
|
||||
CornerRadius="5"
|
||||
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
|
||||
@@ -37,7 +41,11 @@
|
||||
VerticalAlignment="Stretch"
|
||||
ClipToBounds="True"
|
||||
CornerRadius="5">
|
||||
<Grid Margin="0" ColumnDefinitions="*,Auto">
|
||||
<Grid Margin="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Stretch"
|
||||
Text="{Binding UserId}"
|
||||
|
||||
@@ -19,10 +19,19 @@
|
||||
<Design.DataContext>
|
||||
<viewModels:UserSaveManagerViewModel />
|
||||
</Design.DataContext>
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid
|
||||
Grid.Row="0"
|
||||
HorizontalAlignment="Stretch" ColumnDefinitions="Auto,*">
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel
|
||||
Spacing="10"
|
||||
Orientation="Horizontal"
|
||||
@@ -71,7 +80,11 @@
|
||||
<Grid
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
Margin="10,0, 0, 0" ColumnDefinitions="Auto,*">
|
||||
Margin="10,0, 0, 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Content="{ext:Locale Search}" VerticalAlignment="Center" />
|
||||
<TextBox
|
||||
Margin="5,0,0,0"
|
||||
@@ -105,7 +118,11 @@
|
||||
</ListBox.Styles>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:SaveModel">
|
||||
<Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto">
|
||||
<Grid HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
Orientation="Horizontal"
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
<Design.DataContext>
|
||||
<viewModels:UserProfileViewModel />
|
||||
</Design.DataContext>
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*,Auto">
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Border
|
||||
CornerRadius="5"
|
||||
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
|
||||
Width="1100"
|
||||
Height="910"
|
||||
Height="768"
|
||||
MinWidth="800"
|
||||
MinHeight="480"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
@@ -53,12 +53,18 @@
|
||||
|
||||
<!-- For image -->
|
||||
<ui:NavigationView.PaneHeader>
|
||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" RowDefinitions="Auto,Auto,Auto,5">
|
||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="5"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{Binding GameId}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,10"
|
||||
TextAlignment="Center" Grid.Row="0" />
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,10"
|
||||
TextAlignment="Center" Grid.Row="0" />
|
||||
<Image Source="{Binding GameIcon}"
|
||||
Width="160"
|
||||
Height="160"
|
||||
|
||||
@@ -47,6 +47,11 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
InitializeComponent();
|
||||
Load();
|
||||
|
||||
#if DEBUG
|
||||
this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
public void SaveSettings()
|
||||
@@ -60,6 +65,7 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
Pages.Children.Clear();
|
||||
NavPanel.SelectionChanged += NavPanelOnSelectionChanged;
|
||||
NavPanel.SelectedItem = NavPanel.MenuItems.ElementAt(0);
|
||||
|
||||
}
|
||||
|
||||
private void NavPanelOnSelectionChanged(object sender, NavigationViewSelectionChangedEventArgs e)
|
||||
|
||||
@@ -70,7 +70,11 @@
|
||||
<DataTemplate
|
||||
DataType="models:ModModel">
|
||||
<Panel Margin="10">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
|
||||
Width="1100"
|
||||
Height="927"
|
||||
Height="768"
|
||||
MinWidth="800"
|
||||
MinHeight="480"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
@@ -6,6 +8,7 @@ using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.Input;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Key = Avalonia.Input.Key;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
@@ -24,6 +27,10 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
InitializeComponent();
|
||||
Load();
|
||||
|
||||
#if DEBUG
|
||||
this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt));
|
||||
#endif
|
||||
}
|
||||
|
||||
public SettingsWindow()
|
||||
|
||||
@@ -1,26 +1,15 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Platform;
|
||||
using FluentAvalonia.UI.Windowing;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
public abstract class StyleableAppWindow : AppWindow
|
||||
{
|
||||
public static async Task ShowAsync(StyleableAppWindow appWindow, Window owner = null)
|
||||
{
|
||||
#if DEBUG
|
||||
appWindow.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control));
|
||||
#endif
|
||||
await appWindow.ShowDialog(owner ?? RyujinxApp.MainWindow);
|
||||
}
|
||||
|
||||
protected StyleableAppWindow()
|
||||
{
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
@@ -47,14 +36,6 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
public abstract class StyleableWindow : Window
|
||||
{
|
||||
public static async Task ShowAsync(StyleableWindow window, Window owner = null)
|
||||
{
|
||||
#if DEBUG
|
||||
window.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control));
|
||||
#endif
|
||||
await window.ShowDialog(owner ?? RyujinxApp.MainWindow);
|
||||
}
|
||||
|
||||
protected StyleableWindow()
|
||||
{
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
|
||||
@@ -13,7 +13,14 @@
|
||||
x:DataType="viewModels:XCITrimmerViewModel"
|
||||
Focusable="True"
|
||||
mc:Ignorable="d">
|
||||
<Grid Margin="20 0 20 0" RowDefinitions="Auto,Auto,*,Auto,Auto">
|
||||
<Grid Margin="20 0 20 0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Panel
|
||||
Margin="10 10 10 10"
|
||||
Grid.Row="0">
|
||||
@@ -23,7 +30,12 @@
|
||||
Margin="0 0 10 10"
|
||||
IsVisible="{Binding !Processing}"
|
||||
Grid.Row="1">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
Orientation="Horizontal">
|
||||
@@ -133,7 +145,11 @@
|
||||
<DataTemplate
|
||||
DataType="models:XCITrimmerFileModel">
|
||||
<Panel Margin="10">
|
||||
<Grid ColumnDefinitions="65*,35*">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="65*" />
|
||||
<ColumnDefinition Width="35*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Margin="10 0 10 0"
|
||||
@@ -144,7 +160,11 @@
|
||||
TextTrimming="CharacterEllipsis"
|
||||
Text="{Binding Name}">
|
||||
</TextBlock>
|
||||
<Grid Grid.Column="1" ColumnDefinitions="45*,55*">
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="45*" />
|
||||
<ColumnDefinition Width="55*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ProgressBar
|
||||
Height="10"
|
||||
Margin="10 0 10 0"
|
||||
@@ -206,7 +226,15 @@
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Padding="2.5">
|
||||
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
@@ -246,7 +274,11 @@
|
||||
<Panel
|
||||
Grid.Row="4"
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
Orientation="Horizontal"
|
||||
|
||||
@@ -43,9 +43,17 @@ namespace Ryujinx.Ava
|
||||
private const int ConnectionCount = 4;
|
||||
|
||||
private static string _buildVer;
|
||||
|
||||
|
||||
private static readonly string _platformExt = BuildPlatformExtension();
|
||||
private static readonly string _platformExt =
|
||||
RunningPlatform.IsMacOS
|
||||
? "macos_universal.app.tar.gz"
|
||||
: RunningPlatform.IsWindows
|
||||
? "win_x64.zip"
|
||||
: RunningPlatform.IsX64Linux
|
||||
? "linux_x64.tar.gz"
|
||||
: RunningPlatform.IsArmLinux
|
||||
? "linux_arm64.tar.gz"
|
||||
: throw new PlatformNotSupportedException();
|
||||
|
||||
private static string _buildUrl;
|
||||
private static long _buildSize;
|
||||
@@ -772,34 +780,5 @@ namespace Ryujinx.Ava
|
||||
public static void CleanupUpdate() =>
|
||||
Directory.GetFiles(_homeDir, "*.ryuold", SearchOption.AllDirectories)
|
||||
.ForEach(File.Delete);
|
||||
|
||||
private static string BuildPlatformExtension()
|
||||
{
|
||||
if (RunningPlatform.IsMacOS)
|
||||
return "macos_universal.app.tar.gz";
|
||||
|
||||
#pragma warning disable CS8509 // It is exhaustive for any values this can contain.
|
||||
string osPrefix = RunningPlatform.CurrentOS switch
|
||||
{
|
||||
OperatingSystemType.Linux => "linux",
|
||||
OperatingSystemType.Windows => "win"
|
||||
};
|
||||
|
||||
string archSuffix = RunningPlatform.Architecture switch
|
||||
{
|
||||
Architecture.Arm64 => "arm64",
|
||||
Architecture.X64 => "x64",
|
||||
_ => throw new PlatformNotSupportedException($"Unknown architecture {Enum.GetName(RunningPlatform.Architecture)}."),
|
||||
};
|
||||
|
||||
string fileExtension = RunningPlatform.CurrentOS switch
|
||||
#pragma warning restore CS8509
|
||||
{
|
||||
OperatingSystemType.Linux => "tar.gz",
|
||||
OperatingSystemType.Windows => "zip"
|
||||
};
|
||||
|
||||
return $"{osPrefix}_{archSuffix}.{fileExtension}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,13 +59,12 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||
"Race" => "Racing",
|
||||
_ => FormattedValue.ForceReset
|
||||
};
|
||||
|
||||
private static FormattedValue PokemonSV(MultiValue values)
|
||||
{
|
||||
|
||||
string playStatus = values.Matched[0].BoxedValue is 0 ? "Playing Alone" : "Playing in a group";
|
||||
|
||||
FormattedValue locations = values.Matched[1].ToString() switch
|
||||
|
||||
private static FormattedValue PokemonSVUnionCircle(SingleValue value)
|
||||
=> value.Matched.BoxedValue is 0 ? "Playing Alone" : "Playing in a group";
|
||||
|
||||
private static FormattedValue PokemonSVArea(SingleValue value)
|
||||
=> value.Matched.StringValue switch
|
||||
{
|
||||
// Base Game Locations
|
||||
"a_w01" => "South Area One",
|
||||
@@ -93,13 +92,10 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||
"a_w24" => "South Paldean Sea",
|
||||
"a_w25" => "West Paldean Sea",
|
||||
"a_w26" => "East Paldean Sea",
|
||||
"a_w27" => "North Paldean Sea",
|
||||
"a_w27" => "Nouth Paldean Sea",
|
||||
//TODO DLC Locations
|
||||
_ => FormattedValue.ForceReset
|
||||
};
|
||||
|
||||
return$"{playStatus} in {locations}";
|
||||
}
|
||||
|
||||
private static FormattedValue SuperSmashBrosUltimate_Mode(SparseMultiValue values)
|
||||
{
|
||||
@@ -119,11 +115,6 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||
return $"Achievement Unlocked - ID: {anniversary}";
|
||||
}
|
||||
|
||||
if (values.Matched.ContainsKey("is_created"))
|
||||
{
|
||||
return "Edited a Custom Stage!";
|
||||
}
|
||||
|
||||
if (values.Matched.ContainsKey("adv_slot"))
|
||||
{
|
||||
return
|
||||
|
||||
@@ -59,8 +59,9 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||
.AddSpec(
|
||||
["0100a3d008c5c000", "01008f6008c5e000"],
|
||||
spec => spec
|
||||
.WithDescription("based on if you're playing alone or in a group and what area of Paldea you're exploring.")
|
||||
.AddMultiValueFormatter(["team_circle", "area_no"], PokemonSV)
|
||||
.WithDescription("based on what area of Paldea you're exploring.")
|
||||
.AddValueFormatter("area_no", PokemonSVArea)
|
||||
.AddValueFormatter("team_circle", PokemonSVUnionCircle)
|
||||
)
|
||||
.AddSpec(
|
||||
"01006a800016e000",
|
||||
@@ -70,7 +71,7 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||
[
|
||||
// Metadata to figure out what PlayReport we have.
|
||||
"match_mode", "match_submode", "anniversary", "fighter", "reason", "challenge_count",
|
||||
"adv_slot", "is_created",
|
||||
"adv_slot",
|
||||
// List of Fighters
|
||||
"player_1_fighter", "player_2_fighter", "player_3_fighter", "player_4_fighter",
|
||||
"player_5_fighter", "player_6_fighter", "player_7_fighter", "player_8_fighter",
|
||||
|
||||
Reference in New Issue
Block a user