Compare commits
6 Commits
38c5211f99
...
Canary-1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec06a86899 | ||
|
|
2e4de17472 | ||
|
|
9227cbe5a7 | ||
|
|
332bcdfaf1 | ||
|
|
1c8276197f | ||
|
|
a3596ba858 |
@@ -24,7 +24,7 @@ namespace ARMeilleure.Translation.Cache
|
||||
|
||||
private static JitCacheInvalidation _jitCacheInvalidator;
|
||||
|
||||
private static CacheMemoryAllocator _cacheAllocator;
|
||||
private static List<CacheMemoryAllocator> _cacheAllocators = [];
|
||||
|
||||
private static readonly List<CacheEntry> _cacheEntries = [];
|
||||
|
||||
@@ -40,37 +40,48 @@ namespace ARMeilleure.Translation.Cache
|
||||
|
||||
public static void Initialize(IJitMemoryAllocator allocator)
|
||||
{
|
||||
if (_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
if (_initialized)
|
||||
{
|
||||
return;
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
JitUnwindWindows.RemoveFunctionTableHandler(
|
||||
_jitRegions[0].Pointer);
|
||||
}
|
||||
|
||||
for (int i = 0; i < _jitRegions.Count; i++)
|
||||
{
|
||||
_jitRegions[i].Dispose();
|
||||
}
|
||||
|
||||
_jitRegions.Clear();
|
||||
_cacheAllocators.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
_activeRegionIndex = 0;
|
||||
|
||||
ReservedRegion firstRegion = new(allocator, CacheSize);
|
||||
_jitRegions.Add(firstRegion);
|
||||
_activeRegionIndex = 0;
|
||||
|
||||
CacheMemoryAllocator firstCacheAllocator = new(CacheSize);
|
||||
_cacheAllocators.Add(firstCacheAllocator);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +147,7 @@ namespace ARMeilleure.Translation.Cache
|
||||
|
||||
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
|
||||
{
|
||||
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
|
||||
_cacheAllocators[_activeRegionIndex].Free(funcOffset, AlignCodeSize(entry.Size));
|
||||
_cacheEntries.RemoveAt(entryIndex);
|
||||
}
|
||||
|
||||
@@ -167,30 +178,24 @@ namespace ARMeilleure.Translation.Cache
|
||||
{
|
||||
codeSize = AlignCodeSize(codeSize);
|
||||
|
||||
for (int i = _activeRegionIndex; i < _jitRegions.Count; i++)
|
||||
int allocOffset = _cacheAllocators[_activeRegionIndex].Allocate(codeSize);
|
||||
|
||||
if (allocOffset >= 0)
|
||||
{
|
||||
int allocOffset = _cacheAllocator.Allocate(codeSize);
|
||||
|
||||
if (allocOffset >= 0)
|
||||
{
|
||||
_jitRegions[i].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
||||
_activeRegionIndex = i;
|
||||
return allocOffset;
|
||||
}
|
||||
_jitRegions[_activeRegionIndex].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
||||
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 {newRegionNumber} ({((long)(newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation).");
|
||||
|
||||
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
|
||||
Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {_activeRegionIndex} ({((long)(_activeRegionIndex + 1) * CacheSize).Bytes()} Total Allocation).");
|
||||
|
||||
int allocOffsetNew = _cacheAllocator.Allocate(codeSize);
|
||||
_cacheAllocators.Add(new CacheMemoryAllocator(CacheSize));
|
||||
|
||||
int allocOffsetNew = _cacheAllocators[_activeRegionIndex].Allocate(codeSize);
|
||||
if (allocOffsetNew < 0)
|
||||
{
|
||||
throw new OutOfMemoryException("Failed to allocate in new Cache Region!");
|
||||
|
||||
@@ -52,6 +52,11 @@ 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;
|
||||
@@ -91,6 +96,23 @@ 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,15 +5,34 @@ 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 => RuntimeInformation.OSArchitecture is Architecture.Arm64;
|
||||
public static bool IsArm => Architecture is Architecture.Arm64;
|
||||
|
||||
public static bool IsX64 => RuntimeInformation.OSArchitecture is Architecture.X64;
|
||||
public static bool IsX64 => Architecture is Architecture.X64;
|
||||
|
||||
public static bool IsIntelMac => IsMacOS && IsX64;
|
||||
public static bool IsArmMac => IsMacOS && IsArm;
|
||||
|
||||
@@ -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="(Global)"/>
|
||||
<Setter Property="Text" Value="{ext:Locale GameSpecificConfigurationGlobal}"/>
|
||||
</Style>
|
||||
<Style Selector="StackPanel.globalConfigMarker">
|
||||
</Style>
|
||||
|
||||
@@ -2748,28 +2748,53 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "GameListContextMenuEditGameConfiguration",
|
||||
"ID": "GameListContextMenuCreateCustomConfiguration",
|
||||
"Translations": {
|
||||
"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": "編輯遊戲設定"
|
||||
"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": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -2798,12 +2823,12 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "EditGameConfigurationToolTip",
|
||||
"ID": "CreateCustomConfigurationToolTip",
|
||||
"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 current game",
|
||||
"en_US": "Creates an independent configuration for the selected 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": "יוצר תצורה עצמאית למשחק הנוכחי",
|
||||
@@ -2822,6 +2847,31 @@
|
||||
"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": {
|
||||
@@ -24123,12 +24173,37 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "UserConfigurationHeader",
|
||||
"ID": "GameSpecificConfigurationHeader",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "User Config",
|
||||
"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)",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
|
||||
@@ -42,52 +42,33 @@ namespace Ryujinx.Ava
|
||||
List<string> arguments = CommandLineState.Arguments.ToList();
|
||||
string executableDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
|
||||
// On macOS we perform the update at relaunch.
|
||||
if (OperatingSystem.IsMacOS())
|
||||
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)))
|
||||
{
|
||||
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);
|
||||
ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
|
||||
}
|
||||
else
|
||||
|
||||
ProcessStartInfo processStart = new(ryuName)
|
||||
{
|
||||
var dialogTask = taskDialog.ShowAsync(true);
|
||||
await Task.Delay(500);
|
||||
UseShellExecute = true,
|
||||
WorkingDirectory = executableDirectory,
|
||||
};
|
||||
|
||||
// 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);
|
||||
foreach (var arg in args)
|
||||
{
|
||||
processStart.ArgumentList.Add(arg);
|
||||
}
|
||||
|
||||
processStart.ArgumentList.Add(gamePath);
|
||||
|
||||
Process.Start(processStart);
|
||||
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,18 @@
|
||||
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"
|
||||
Header="{ext:Locale GameListContextMenuEditGameConfiguration}"
|
||||
IsVisible="{Binding !SelectedApplication.HasIndependentConfiguration}"
|
||||
Header="{ext:Locale GameListContextMenuCreateCustomConfiguration}"
|
||||
Icon="{ext:Icon fa-solid fa-gear}"
|
||||
ToolTip.Tip="{ext:Locale EditGameConfigurationToolTip}" />
|
||||
ToolTip.Tip="{ext:Locale CreateCustomConfigurationToolTip}" />
|
||||
<MenuItem
|
||||
IsVisible="{Binding HasCompatibilityEntry}"
|
||||
Click="OpenApplicationCompatibility_Click"
|
||||
|
||||
@@ -200,7 +200,7 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
if (backupDir.Exists)
|
||||
{
|
||||
cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
|
||||
cacheFiles.AddRange(mainDir.EnumerateFiles("*.info"));
|
||||
cacheFiles.AddRange(backupDir.EnumerateFiles("*.info"));
|
||||
}
|
||||
|
||||
if (cacheFiles.Count > 0)
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
IsVisible="{Binding HasIndependentConfiguration}"
|
||||
Text="{ext:Locale UserConfigurationHeader}"
|
||||
Text="{ext:Locale GameSpecificConfigurationHeader}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource Warning}" />
|
||||
@@ -110,7 +110,7 @@
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="{ext:Locale UserConfigurationHeader}"
|
||||
Text="{ext:Locale GameSpecificConfigurationHeader}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
</Border>
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
<TextBlock
|
||||
HorizontalAlignment="Stretch"
|
||||
IsVisible="{Binding HasIndependentConfiguration}"
|
||||
Text="{ext:Locale UserConfigurationHeader}"
|
||||
Text="{ext:Locale GameSpecificConfigurationHeader}"
|
||||
TextAlignment="Start"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource Warning}" />
|
||||
|
||||
@@ -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="768"
|
||||
Height="910"
|
||||
MinWidth="800"
|
||||
MinHeight="480"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
|
||||
@@ -65,7 +65,6 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
Pages.Children.Clear();
|
||||
NavPanel.SelectionChanged += NavPanelOnSelectionChanged;
|
||||
NavPanel.SelectedItem = NavPanel.MenuItems.ElementAt(0);
|
||||
|
||||
}
|
||||
|
||||
private void NavPanelOnSelectionChanged(object sender, NavigationViewSelectionChangedEventArgs e)
|
||||
|
||||
@@ -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="768"
|
||||
Height="918"
|
||||
MinWidth="800"
|
||||
MinHeight="480"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
|
||||
@@ -43,17 +43,9 @@ namespace Ryujinx.Ava
|
||||
private const int ConnectionCount = 4;
|
||||
|
||||
private static string _buildVer;
|
||||
|
||||
|
||||
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 readonly string _platformExt = BuildPlatformExtension();
|
||||
|
||||
private static string _buildUrl;
|
||||
private static long _buildSize;
|
||||
@@ -780,5 +772,34 @@ 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,12 +59,13 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||
"Race" => "Racing",
|
||||
_ => FormattedValue.ForceReset
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
{
|
||||
// Base Game Locations
|
||||
"a_w01" => "South Area One",
|
||||
@@ -92,10 +93,13 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||
"a_w24" => "South Paldean Sea",
|
||||
"a_w25" => "West Paldean Sea",
|
||||
"a_w26" => "East Paldean Sea",
|
||||
"a_w27" => "Nouth Paldean Sea",
|
||||
"a_w27" => "North Paldean Sea",
|
||||
//TODO DLC Locations
|
||||
_ => FormattedValue.ForceReset
|
||||
};
|
||||
|
||||
return$"{playStatus} in {locations}";
|
||||
}
|
||||
|
||||
private static FormattedValue SuperSmashBrosUltimate_Mode(SparseMultiValue values)
|
||||
{
|
||||
@@ -115,6 +119,11 @@ 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,9 +59,8 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||
.AddSpec(
|
||||
["0100a3d008c5c000", "01008f6008c5e000"],
|
||||
spec => spec
|
||||
.WithDescription("based on what area of Paldea you're exploring.")
|
||||
.AddValueFormatter("area_no", PokemonSVArea)
|
||||
.AddValueFormatter("team_circle", PokemonSVUnionCircle)
|
||||
.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)
|
||||
)
|
||||
.AddSpec(
|
||||
"01006a800016e000",
|
||||
@@ -71,7 +70,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",
|
||||
"adv_slot", "is_created",
|
||||
// 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