Compare commits

..

8 Commits

Author SHA1 Message Date
Evan Husted
3abee2a0be Merge branch 'master' into feature/turbo-mode 2025-03-04 02:57:30 -06:00
Evan Husted
94f34a9ed1 properly merge + move hleconfig tick scalar parameter 2025-03-04 01:19:18 -06:00
Evan Husted
776c0cb5cf merge 2025-03-04 01:08:39 -06:00
Evan Husted
ef1529a2d9 localize Turbo Mode for French 2025-03-03 13:38:52 -06:00
Evan Husted
768406cb67 Improve description of Turbo Mode in the UI and localize FPS/Turbo indicator on status bar 2025-03-03 12:42:00 -06:00
Evan Husted
ed5cb82aa8 feature: Turbo Mode
Adds an elapsed tick multiplier feature which speeds up games which are built upon delta time.
More information: https://web.archive.org/web/20240713135029/https://github.com/Ryujinx/Ryujinx/pull/6456
2025-03-03 02:33:28 -06:00
Evan Husted
c48a2e6ba0 join assignment and declaration for this local variable in ipc service 2025-03-03 02:30:26 -06:00
Evan Husted
90f2b089eb fix nullref when switching vsync mode with turbo mode 2025-03-02 23:51:56 -06:00
105 changed files with 785 additions and 424 deletions

View File

@@ -13,5 +13,7 @@ namespace Ryujinx.Common.Configuration.Hid
public Key VolumeDown { get; set; }
public Key CustomVSyncIntervalIncrement { get; set; }
public Key CustomVSyncIntervalDecrement { get; set; }
public Key TurboMode { get; set; }
public bool TurboModeWhileHeld { get; set; }
}
}

View File

@@ -8,10 +8,17 @@ namespace Ryujinx.Cpu
/// </summary>
public interface ITickSource : ICounter
{
public const long RealityTickScalar = 100;
/// <summary>
/// Time elapsed since the counter was created.
/// </summary>
TimeSpan ElapsedTime { get; }
/// <summary>
/// Clock tick scalar, in percent points (100 = 1.0).
/// </summary>
long TickScalar { get; set; }
/// <summary>
/// Time elapsed since the counter was created, in seconds.

View File

@@ -14,12 +14,37 @@ namespace Ryujinx.Cpu
/// <inheritdoc/>
public ulong Counter => (ulong)(ElapsedSeconds * Frequency);
public long TickScalar { get; set; }
private static long _acumElapsedTicks;
private static long _lastElapsedTicks;
private long ElapsedTicks
{
get
{
long elapsedTicks = _tickCounter.ElapsedTicks;
_acumElapsedTicks += (elapsedTicks - _lastElapsedTicks) * TickScalar / 100;
_lastElapsedTicks = elapsedTicks;
return _acumElapsedTicks;
}
}
/// <inheritdoc/>
public TimeSpan ElapsedTime => _tickCounter.Elapsed;
public TimeSpan ElapsedTime => Stopwatch.GetElapsedTime(0, ElapsedTicks);
/// <inheritdoc/>
public double ElapsedSeconds => _tickCounter.ElapsedTicks * _hostTickFreq;
public double ElapsedSeconds => ElapsedTicks * _hostTickFreq;
public TickSource(ulong frequency)
{

View File

@@ -1065,7 +1065,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// </summary>
private void UpdateIndexBufferState()
{
IndexBufferState indexBuffer = _state.State.IndexBufferState;
IndexBufferState? indexBufferNullable = _state?.State.IndexBufferState;
if (!indexBufferNullable.HasValue)
{
return;
}
IndexBufferState indexBuffer = indexBufferNullable.Value;
if (_drawState.IndexCount == 0)
{

View File

@@ -127,10 +127,7 @@ namespace Ryujinx.HLE.HOS.Services
}
else
{
string serviceName;
serviceName = (service is not DummyService dummyService) ? service.GetType().FullName : dummyService.ServiceName;
string serviceName = (service is not DummyService dummyService) ? service.GetType().FullName : dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored");
}

View File

@@ -2,6 +2,7 @@ using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.PreciseSleep;
using Ryujinx.Cpu;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
@@ -89,7 +90,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
else
{
_ticksPerFrame = Stopwatch.Frequency / _device.TargetVSyncInterval;
_ticksPerFrame = ((Stopwatch.Frequency / _device.TargetVSyncInterval) * 100) / _device.TickScalar;
_targetVSyncInterval = _device.TargetVSyncInterval;
}
}

View File

@@ -102,6 +102,11 @@ namespace Ryujinx.HLE
/// Control if the Profiled Translation Cache (PTC) should be used.
/// </summary>
internal readonly bool EnablePtc;
/// <summary>
/// Control the arbitrary scalar applied to emulated CPU tick timing.
/// </summary>
public long TickScalar { get; set; }
/// <summary>
/// Control if the guest application should be told that there is a Internet connection available.
@@ -201,6 +206,7 @@ namespace Ryujinx.HLE
VSyncMode vSyncMode,
bool enableDockedMode,
bool enablePtc,
long tickScalar,
bool enableInternetAccess,
IntegrityCheckLevel fsIntegrityCheckLevel,
int fsGlobalAccessLogMode,
@@ -226,6 +232,7 @@ namespace Ryujinx.HLE
CustomVSyncInterval = customVSyncInterval;
EnableDockedMode = enableDockedMode;
EnablePtc = enablePtc;
TickScalar = tickScalar;
EnableInternetAccess = enableInternetAccess;
FsIntegrityCheckLevel = fsIntegrityCheckLevel;
FsGlobalAccessLogMode = fsGlobalAccessLogMode;

View File

@@ -6,6 +6,8 @@ namespace Ryujinx.HLE
{
public class PerformanceStatistics
{
private readonly Switch _device;
private const int FrameTypeGame = 0;
private const int PercentTypeFifo = 0;
@@ -28,8 +30,10 @@ namespace Ryujinx.HLE
private readonly System.Timers.Timer _resetTimer;
public PerformanceStatistics()
public PerformanceStatistics(Switch device)
{
_device = device;
_frameRate = new double[1];
_accumulatedFrameTime = new double[1];
_previousFrameTime = new double[1];
@@ -162,14 +166,6 @@ namespace Ryujinx.HLE
return 1000 / _frameRate[FrameTypeGame];
}
public string FormatGameFrameRate()
{
double frameRate = GetGameFrameRate();
double frameTime = GetGameFrameTime();
return $"{frameRate:00.00} FPS ({frameTime:00.00}ms)";
}
public string FormatFifoPercent()
{
double fifoPercent = GetFifoPercent();

View File

@@ -4,6 +4,7 @@ using Ryujinx.Audio.Backends.CompatLayer;
using Ryujinx.Audio.Integration;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Cpu;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
@@ -26,18 +27,26 @@ namespace Ryujinx.HLE
public GpuContext Gpu { get; }
public VirtualFileSystem FileSystem { get; }
public HOS.Horizon System { get; }
public bool TurboMode = false;
public long TickScalar
{
get => System?.TickSource?.TickScalar ?? ITickSource.RealityTickScalar;
set => System.TickSource.TickScalar = value;
}
public ProcessLoader Processes { get; }
public PerformanceStatistics Statistics { get; }
public Hid Hid { get; }
public TamperMachine TamperMachine { get; }
public IHostUIHandler UIHandler { get; }
public int CpuCoresCount = 4; //Switch 1 has 4 cores
public int CpuCoresCount = 4; // Switch has a quad-core Tegra X1 SoC
public VSyncMode VSyncMode { get; set; }
public bool CustomVSyncIntervalEnabled { get; set; }
public int CustomVSyncInterval { get; set; }
public long TargetVSyncInterval { get; set; } = 60;
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
@@ -64,7 +73,7 @@ namespace Ryujinx.HLE
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks);
System = new HOS.Horizon(this);
Statistics = new PerformanceStatistics();
Statistics = new PerformanceStatistics(this);
Hid = new Hid(this, System.HidStorage);
Processes = new ProcessLoader(this);
TamperMachine = new TamperMachine();
@@ -75,6 +84,7 @@ namespace Ryujinx.HLE
VSyncMode = Configuration.VSyncMode;
CustomVSyncInterval = Configuration.CustomVSyncInterval;
TickScalar = TurboMode ? Configuration.TickScalar : ITickSource.RealityTickScalar;
System.State.DockedMode = Configuration.EnableDockedMode;
System.PerformanceState.PerformanceMode = System.State.DockedMode ? PerformanceMode.Boost : PerformanceMode.Default;
System.EnablePtc = Configuration.EnablePtc;
@@ -126,6 +136,12 @@ namespace Ryujinx.HLE
}
}
public void ToggleTurbo()
{
TurboMode = !TurboMode;
TickScalar = TurboMode ? Configuration.TickScalar : ITickSource.RealityTickScalar;
}
public bool LoadCart(string exeFsDir, string romFsFile = null) => Processes.LoadUnpackedNca(exeFsDir, romFsFile);
public bool LoadXci(string xciFile, ulong applicationId = 0) => Processes.LoadXci(xciFile, applicationId);
public bool LoadNca(string ncaFile, BlitStruct<ApplicationControlProperty>? customNacpData = null) => Processes.LoadNca(ncaFile, customNacpData);

View File

@@ -4,9 +4,9 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input;
using Avalonia.Threading;
using DiscordRPC;
using Gommon;
using LibHac.Common;
using LibHac.Ns;
using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.Dummy;
using Ryujinx.Audio.Backends.OpenAL;
using Ryujinx.Audio.Backends.SDL2;
@@ -21,8 +21,8 @@ using Ryujinx.Ava.UI.Renderer;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer;
@@ -35,11 +35,9 @@ using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Graphics.Gpu;
using Ryujinx.Graphics.OpenGL;
using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Input;
using Ryujinx.Input.HLE;
using SkiaSharp;
@@ -1118,11 +1116,23 @@ namespace Ryujinx.Ava
LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%",
dockedMode,
ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(),
Device.Statistics.FormatGameFrameRate(),
FormatGameFrameRate(),
Device.Statistics.FormatFifoPercent(),
_displayCount));
}
private string FormatGameFrameRate()
{
string frameRate = Device.Statistics.GetGameFrameRate().ToString("00.00");
string frameTime = Device.Statistics.GetGameFrameTime().ToString("00.00");
return Device.TurboMode
? LocaleManager.GetUnformatted(LocaleKeys.FpsTurboStatusBarText)
.Format(frameRate, frameTime, Device.TickScalar)
: LocaleManager.GetUnformatted(LocaleKeys.FpsStatusBarText)
.Format(frameRate, frameTime);
}
public async Task ShowExitPrompt()
{
bool shouldExit = !ConfigurationState.Instance.ShowConfirmExit;
@@ -1218,6 +1228,12 @@ namespace Ryujinx.Ava
if (currentHotkeyState != _prevHotkeyState)
{
if (ConfigurationState.Instance.Hid.Hotkeys.Value.TurboModeWhileHeld &&
_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.TurboMode) != Device.TurboMode)
{
Device.ToggleTurbo();
}
switch (currentHotkeyState)
{
case KeyboardHotkeyState.ToggleVSyncMode:
@@ -1229,6 +1245,12 @@ namespace Ryujinx.Ava
case KeyboardHotkeyState.CustomVSyncIntervalIncrement:
_viewModel.CustomVSyncInterval = Device.IncrementCustomVSyncInterval();
break;
case KeyboardHotkeyState.TurboMode:
if (!ConfigurationState.Instance.Hid.Hotkeys.Value.TurboModeWhileHeld)
{
Device.ToggleTurbo();
}
break;
case KeyboardHotkeyState.Screenshot:
ScreenshotRequested = true;
break;
@@ -1358,6 +1380,10 @@ namespace Ryujinx.Ava
{
state = KeyboardHotkeyState.CustomVSyncIntervalDecrement;
}
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.TurboMode))
{
state = KeyboardHotkeyState.TurboMode;
}
return state;
}

View File

@@ -440,7 +440,7 @@
<x:Double x:Key="ControlContentThemeFontSize">13</x:Double>
<x:Double x:Key="MenuItemHeight">26</x:Double>
<x:Double x:Key="TabItemMinHeight">28</x:Double>
<x:Double x:Key="ContentDialogMaxWidth">700</x:Double>
<x:Double x:Key="ContentDialogMaxWidth">900</x:Double>
<x:Double x:Key="ContentDialogMaxHeight">756</x:Double>
</Styles.Resources>
</Styles>

View File

@@ -4897,6 +4897,81 @@
"zh_TW": "低功耗 PPTC"
}
},
{
"ID": "SettingsTabSystemTurboMultiplier",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Turbo Mode multiplier:",
"es_ES": "",
"fr_FR": "Multiplicateur du Mode Turbo :",
"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": "SettingsTabSystemTurboMultiplierValueToolTip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "The Turbo mode multiplier target value.\n\nLeave at 200 if unsure.",
"es_ES": "",
"fr_FR": "La valeur souhaitée du multiplicateur du Mode Turbo.\n\nGarder à 200 si incertain.",
"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": "SettingsTabSystemTurboMultiplierToolTip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Turbo mode is an emulator feature which effectively causes speed up or slow down when a game is not frame-rate sensitive.\nYou can toggle this feature in-game with a hotkey, configurable in Ryujinx Keyboard Hotkeys settings.\n\nLeave at 200 if unsure.",
"es_ES": "",
"fr_FR": "Le Mode Turbo est une fonctionnalité de l'émulateur qui accélère ou ralentit le jeu lorsque ce dernier n'est pas sensible au framerate.\nVous pouvez changer cette option en jeu avec un raccourci clavier, configurable dans les paramètres de Raccourcis clavier de Ryujinx.\n\nGarder à 200 si incertain.",
"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": "SettingsTabSystemEnableFsIntegrityChecks",
"Translations": {
@@ -10480,7 +10555,7 @@
"el_GR": "",
"en_US": "Unbound",
"es_ES": "",
"fr_FR": "Pas Attribuée",
"fr_FR": "Non Attribuée",
"he_IL": "",
"it_IT": "Non assegnato",
"ja_JP": "",
@@ -18072,6 +18147,56 @@
"zh_TW": "更新已停用!"
}
},
{
"ID": "FpsStatusBarText",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "{0} FPS ({1}ms)",
"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": "FpsTurboStatusBarText",
"Translations": {
"ar_SA": "{0} FPS ({1}ms), التوربو %{2}",
"de_DE": "",
"el_GR": "",
"en_US": "{0} FPS ({1}ms), Turbo ({2}%)",
"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": "UpdaterBackgroundStatusBarButtonText",
"Translations": {
@@ -23797,6 +23922,81 @@
"zh_TW": "降低自訂的重新整理頻率"
}
},
{
"ID": "SettingsTabHotkeysTurboMode",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Turbo mode:",
"es_ES": "",
"fr_FR": "Mode Turbo :",
"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": "SettingsTabHotkeysTurboModeToolTip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "The Turbo mode hotkey.\nConfigure the behavior of Turbo mode in Ryujinx CPU settings.\n\nLeave Unbound if unsure.",
"es_ES": "",
"fr_FR": "Le raccourci clavier Mode Turbo.\nConfigurez le comportement du Mode Turbo dans les paramètres de CPU de Ryujinx.\n\nLaisser Non Attribuée si incertain.",
"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": "SettingsTabHotkeysOnlyWhilePressed",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Only while pressed",
"es_ES": "",
"fr_FR": "Seulement quand le raccourci est maintenu",
"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": "CompatibilityListLastUpdated",
"Translations": {
@@ -23822,31 +24022,6 @@
"zh_TW": "上次更新時間: {0}"
}
},
{
"ID": "CompatibilityListTitle",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Compatibility List - {0} entries",
"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": "CompatibilityListWarning",
"Translations": {
@@ -23897,31 +24072,6 @@
"zh_TW": "搜尋相容性列表紀錄..."
}
},
{
"ID": "CompatibilityListSearchBoxWatermarkWithCount",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Search {0} compatibility entries...",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "Søk i {0} kompatibilitetsoppføringer...",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "CompatibilityListOpen",
"Translations": {

View File

@@ -16,7 +16,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Helper;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
@@ -216,7 +216,11 @@ namespace Ryujinx.Ava.Common
return;
}
(Nca updatePatchNca, _) = mainNca.GetUpdateData(_virtualFileSystem, ConfigurationState.Instance.System.IntegrityCheckLevel, programIndex, out _);
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
(Nca updatePatchNca, _) = mainNca.GetUpdateData(_virtualFileSystem, checkLevel, programIndex, out _);
if (updatePatchNca is not null)
{
patchNca = updatePatchNca;

View File

@@ -14,5 +14,6 @@ namespace Ryujinx.Ava.Common
VolumeDown,
CustomVSyncIntervalIncrement,
CustomVSyncIntervalDecrement,
TurboMode,
}
}

View File

@@ -1,7 +1,6 @@
using Gommon;
using Ryujinx.Ava.Systems;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common;
using Ryujinx.Common.Utilities;
using System;
@@ -56,10 +55,15 @@ namespace Ryujinx.Ava.Common.Locale
SetDynamicValues(LocaleKeys.RyujinxConfirm, RyujinxApp.FullAppName);
SetDynamicValues(LocaleKeys.RyujinxUpdater, RyujinxApp.FullAppName);
SetDynamicValues(LocaleKeys.RyujinxRebooter, RyujinxApp.FullAppName);
SetDynamicValues(LocaleKeys.CompatibilityListSearchBoxWatermarkWithCount, CompatibilityCsv.Entries.Length);
SetDynamicValues(LocaleKeys.CompatibilityListTitle, CompatibilityCsv.Entries.Length);
}
public static string GetUnformatted(LocaleKeys key) => Instance.Get(key);
public string Get(LocaleKeys key) =>
_localeStrings.TryGetValue(key, out string value)
? value
: key.ToString();
public string this[LocaleKeys key]
{
get

View File

@@ -1,4 +1,4 @@
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;

View File

@@ -1,9 +1,9 @@
using DiscordRPC;
using Gommon;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Systems.PlayReport;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Utilities.PlayReport;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.HLE;

View File

@@ -2,7 +2,7 @@ using DiscordRPC;
using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.SDL2;
using Ryujinx.Ava;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
@@ -10,6 +10,7 @@ using Ryujinx.Common.Configuration.Hid.Controller.Motion;
using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
using Ryujinx.Cpu;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Graphics.OpenGL;
@@ -311,7 +312,7 @@ namespace Ryujinx.Headless
return new OpenGLRenderer();
}
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) =>
new(
new HleConfiguration(
@@ -321,6 +322,7 @@ namespace Ryujinx.Headless
options.VSyncMode,
!options.DisableDockedMode,
!options.DisablePTC,
ITickSource.RealityTickScalar,
options.EnableInternetAccess,
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
options.FsGlobalAccessLogMode,

View File

@@ -1,7 +1,7 @@
using CommandLine;
using Gommon;
using Ryujinx.Ava;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;

View File

@@ -1,7 +1,6 @@
using CommandLine;
using Gommon;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.HLE;
@@ -38,7 +37,7 @@ namespace Ryujinx.Headless
EnableInternetAccess = configurationState.System.EnableInternetAccess;
if (NeedsOverride(nameof(DisableFsIntegrityChecks)))
DisableFsIntegrityChecks = !configurationState.System.EnableFsIntegrityChecks;
DisableFsIntegrityChecks = configurationState.System.EnableFsIntegrityChecks;
if (NeedsOverride(nameof(FsGlobalAccessLogMode)))
FsGlobalAccessLogMode = configurationState.System.FsGlobalAccessLogMode;
@@ -59,10 +58,10 @@ namespace Ryujinx.Headless
DisableDockedMode = !configurationState.System.EnableDockedMode;
if (NeedsOverride(nameof(SystemLanguage)))
SystemLanguage = configurationState.System.Language.Value.ToHLE();
SystemLanguage = (SystemLanguage)(int)configurationState.System.Language.Value;
if (NeedsOverride(nameof(SystemRegion)))
SystemRegion = configurationState.System.Region.Value.ToHLE();
SystemRegion = (RegionCode)(int)configurationState.System.Region.Value;
if (NeedsOverride(nameof(SystemTimeZone)))
SystemTimeZone = configurationState.System.TimeZone;

View File

@@ -8,8 +8,7 @@ using Projektanker.Icons.Avalonia.MaterialDesign;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Utilities.SystemInfo;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
@@ -283,16 +282,16 @@ namespace Ryujinx.Ava
// Check if region was overridden.
if (CommandLineState.OverrideSystemRegion is not null)
if (Enum.TryParse(CommandLineState.OverrideSystemRegion, true, out HLE.HOS.SystemState.RegionCode result))
if (Enum.TryParse(CommandLineState.OverrideSystemRegion, true, out Ryujinx.HLE.HOS.SystemState.RegionCode result))
{
ConfigurationState.Instance.System.Region.Value = result.ToUI();
ConfigurationState.Instance.System.Region.Value = (Utilities.Configuration.System.Region)result;
}
//Check if language was overridden.
if (CommandLineState.OverrideSystemLanguage is not null)
if (Enum.TryParse(CommandLineState.OverrideSystemLanguage, true, out HLE.HOS.SystemState.SystemLanguage result))
if (Enum.TryParse(CommandLineState.OverrideSystemLanguage, true, out Ryujinx.HLE.HOS.SystemState.SystemLanguage result))
{
ConfigurationState.Instance.System.Language.Value = result.ToUI();
ConfigurationState.Instance.System.Language.Value = (Utilities.Configuration.System.Language)result;
}
// Check if hardware-acceleration was overridden.

View File

@@ -17,9 +17,4 @@
<sty:FluentAvaloniaTheme PreferUserAccentColor="True" PreferSystemTheme="False" />
<StyleInclude Source="/Assets/Styles/Styles.xaml" />
</Application.Styles>
<NativeMenu.Menu>
<NativeMenu>
<NativeMenuItem Header="About Ryujinx" Click="AboutRyujinx_OnClick" />
</NativeMenu>
</NativeMenu.Menu>
</Application>

View File

@@ -12,7 +12,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using System;
@@ -147,10 +147,5 @@ namespace Ryujinx.Ava
Current is RyujinxApp { PlatformSettings: not null } app
? ConvertThemeVariant(app.PlatformSettings.GetColorValues().ThemeVariant)
: ThemeVariant.Default;
private async void AboutRyujinx_OnClick(object sender, EventArgs e)
{
await AboutWindow.Show();
}
}
}

View File

@@ -1,26 +0,0 @@
using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration.System
{
[JsonConverter(typeof(TypedStringEnumConverter<Region>))]
public enum Region
{
Japan,
USA,
Europe,
Australia,
China,
Korea,
Taiwan,
}
public static class RegionEnumHelper
{
public static Region ToUI(this HLE.HOS.SystemState.RegionCode hleRegion)
=> (Region)hleRegion;
public static HLE.HOS.SystemState.RegionCode ToHLE(this Region uiRegion)
=> (HLE.HOS.SystemState.RegionCode)uiRegion;
}
}

View File

@@ -7,7 +7,7 @@ using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common;
using Ryujinx.HLE;
using Ryujinx.HLE.HOS.Applets;

View File

@@ -12,7 +12,8 @@ using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Views.Misc;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Compat;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Helper;
using Ryujinx.HLE.HOS;
@@ -407,7 +408,7 @@ namespace Ryujinx.Ava.UI.Controls
public async void OpenApplicationCompatibility_Click(object sender, RoutedEventArgs args)
{
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
await CompatibilityListWindow.Show(viewModel.SelectedApplication.IdString);
await CompatibilityList.Show(viewModel.SelectedApplication.IdString);
}
public async void OpenApplicationData_Click(object sender, RoutedEventArgs args)

View File

@@ -1,5 +1,5 @@
using Avalonia.Interactivity;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
namespace Ryujinx.Ava.UI.Helpers
{

View File

@@ -2,7 +2,7 @@ using Avalonia.Data.Converters;
using Avalonia.Markup.Xaml;
using Gommon;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using System;
using System.Globalization;
using System.Text;

View File

@@ -1,7 +1,7 @@
using Avalonia.Logging;
using Avalonia.Utilities;
using Gommon;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Logging;
using System;
using System.Text;

View File

@@ -1,4 +1,4 @@
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using System;
using System.Collections.Generic;

View File

@@ -1,4 +1,4 @@
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using System;
using System.Collections.Generic;

View File

@@ -28,6 +28,10 @@ namespace Ryujinx.Ava.UI.Models.Input
[ObservableProperty] private Key _customVSyncIntervalDecrement;
[ObservableProperty] private Key _turboMode;
[ObservableProperty] private bool _turboModeWhileHeld;
public HotkeyConfig(KeyboardHotkeys config)
{
if (config == null)
@@ -44,6 +48,8 @@ namespace Ryujinx.Ava.UI.Models.Input
VolumeDown = config.VolumeDown;
CustomVSyncIntervalIncrement = config.CustomVSyncIntervalIncrement;
CustomVSyncIntervalDecrement = config.CustomVSyncIntervalDecrement;
TurboMode = config.TurboMode;
TurboModeWhileHeld = config.TurboModeWhileHeld;
}
public KeyboardHotkeys GetConfig() =>
@@ -60,6 +66,8 @@ namespace Ryujinx.Ava.UI.Models.Input
VolumeDown = VolumeDown,
CustomVSyncIntervalIncrement = CustomVSyncIntervalIncrement,
CustomVSyncIntervalDecrement = CustomVSyncIntervalDecrement,
TurboMode = TurboMode,
TurboModeWhileHeld = TurboModeWhileHeld
};
}
}

View File

@@ -3,7 +3,7 @@ using LibHac.Fs;
using LibHac.Ncm;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.HLE.FileSystem;
using System.IO;
using System.Linq;

View File

@@ -1,7 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Platform;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Helper;
using SPB.Graphics;

View File

@@ -1,5 +1,5 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;

View File

@@ -1,7 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration;
using System;

View File

@@ -5,7 +5,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using Gommon;
using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using System;
namespace Ryujinx.Ava.UI.ViewModels

View File

@@ -1,4 +1,4 @@
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using System;
namespace Ryujinx.Ava.UI.ViewModels

View File

@@ -1,7 +1,7 @@
using Gommon;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Systems.PlayReport;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.PlayReport;
namespace Ryujinx.Ava.UI.ViewModels
{

View File

@@ -1,6 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using System.Linq;
namespace Ryujinx.Ava.UI.ViewModels

View File

@@ -7,7 +7,7 @@ using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;

View File

@@ -10,7 +10,7 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;

View File

@@ -3,7 +3,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Humanizer;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using System.Globalization;
namespace Ryujinx.Ava.UI.ViewModels.Input

View File

@@ -23,8 +23,8 @@ using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.Models.Generic;
using Ryujinx.Ava.UI.Renderer;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Helper;

View File

@@ -7,7 +7,7 @@ using Gommon;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;

View File

@@ -1,6 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Gommon;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
namespace Ryujinx.Ava.UI.ViewModels
{

View File

@@ -12,9 +12,9 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.GraphicsDriver;
@@ -60,6 +60,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private bool _enableCustomVSyncInterval;
private int _customVSyncIntervalPercentageProxy;
private VSyncMode _vSyncMode;
private long _turboModeMultiplier;
public event Action CloseWindow;
public event Action SaveSettingsEvent;
@@ -207,6 +208,25 @@ namespace Ryujinx.Ava.UI.ViewModels
}
public bool EnablePptc { get; set; }
public bool EnableLowPowerPptc { get; set; }
public long TurboMultiplier
{
get => _turboModeMultiplier;
set
{
if (_turboModeMultiplier != value)
{
_turboModeMultiplier = value;
OnPropertyChanged();
OnPropertyChanged((nameof(TurboMultiplierPercentageText)));
}
}
}
public string TurboMultiplierPercentageText => $"{TurboMultiplier}%";
public bool EnableInternetAccess { get; set; }
public bool EnableFsIntegrityChecks { get; set; }
public bool IgnoreMissingServices { get; set; }
@@ -594,6 +614,7 @@ namespace Ryujinx.Ava.UI.ViewModels
EnableLowPowerPptc = config.System.EnableLowPowerPtc;
MemoryMode = (int)config.System.MemoryManagerMode.Value;
UseHypervisor = config.System.UseHypervisor;
TurboMultiplier = config.System.TickScalar;
// Graphics
GraphicsBackendIndex = (int)config.Graphics.GraphicsBackend.Value;
@@ -697,6 +718,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.System.EnableLowPowerPtc.Value = EnableLowPowerPptc;
config.System.MemoryManagerMode.Value = (MemoryManagerMode)MemoryMode;
config.System.UseHypervisor.Value = UseHypervisor;
config.System.TickScalar.Value = TurboMultiplier;
// Graphics
config.Graphics.VSyncMode.Value = VSyncMode;

View File

@@ -6,7 +6,7 @@ using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using System.Collections.Generic;
using System.IO;
using System.Linq;

View File

@@ -6,7 +6,7 @@ using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Utilities;
using System.Collections.Generic;
using System.Collections.ObjectModel;

View File

@@ -11,9 +11,9 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.Views.Misc;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Compat;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common;
using Ryujinx.Common.Helper;
using Ryujinx.Common.Utilities;
@@ -51,7 +51,7 @@ namespace Ryujinx.Ava.UI.Views.Main
UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes);
XciTrimmerMenuItem.Command = Commands.Create(XCITrimmerWindow.Show);
AboutWindowMenuItem.Command = Commands.Create(AboutWindow.Show);
CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityListWindow.Show());
CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityList.Show());
UpdateMenuItem.Command = MainWindowViewModel.UpdateCommand;

View File

@@ -7,7 +7,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;

View File

@@ -2,13 +2,15 @@
using Avalonia.Input.Platform;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Styling;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Compat;
using System.Linq;
using System.Threading.Tasks;
@@ -44,18 +46,21 @@ namespace Ryujinx.Ava.UI.Views.Misc
if (RyujinxApp.AppLifetime.Windows.TryGetFirst(x => x is ContentDialogOverlayWindow, out Window window))
window.Close(ContentDialogResult.None);
await CompatibilityListWindow.Show((string)playabilityLabel.Tag);
await CompatibilityList.Show((string)playabilityLabel.Tag);
}
private async void IdString_OnClick(object sender, RoutedEventArgs e)
{
if (DataContext is not MainWindowViewModel mwvm)
return;
if (sender is not Button { Content: TextBlock idText })
return;
if (!RyujinxApp.IsClipboardAvailable(out IClipboard clipboard))
return;
ApplicationData appData = RyujinxApp.MainWindow.ViewModel.Applications.FirstOrDefault(it => it.IdString == idText.Text);
ApplicationData appData = mwvm.Applications.FirstOrDefault(it => it.IdString == idText.Text);
if (appData is null)
return;

View File

@@ -4,7 +4,7 @@ using Avalonia.Interactivity;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using System;
namespace Ryujinx.Ava.UI.Views.Misc

View File

@@ -5,8 +5,8 @@ using Avalonia.Interactivity;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Compat;
using System;
using System.Linq;
@@ -36,7 +36,7 @@ namespace Ryujinx.Ava.UI.Views.Misc
if (sender is not Button { Content: TextBlock playabilityLabel })
return;
await CompatibilityListWindow.Show((string)playabilityLabel.Tag);
await CompatibilityList.Show((string)playabilityLabel.Tag);
}
private async void IdString_OnClick(object sender, RoutedEventArgs e)

View File

@@ -6,7 +6,7 @@ using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Views.Misc

View File

@@ -7,6 +7,7 @@
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
mc:Ignorable="d"
x:DataType="viewModels:SettingsViewModel">
<Design.DataContext>
@@ -76,6 +77,57 @@
ToolTip.Tip="{ext:Locale UseHypervisorTooltip}" />
</CheckBox>
</StackPanel>
<Separator Height="1" />
<StackPanel
Orientation="Vertical"
Spacing="5">
<TextBlock
Classes="h1"
Text="{ext:Locale SettingsTabSystemHacks}" />
<TextBlock
Foreground="{DynamicResource SecondaryTextColor}"
TextDecorations="Underline"
Text="{ext:Locale SettingsTabSystemHacksNote}" />
</StackPanel>
<StackPanel
Margin="10,0,0,0"
HorizontalAlignment="Stretch"
Orientation="Vertical">
<StackPanel Margin="0,0,0,10"
Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
Background="Transparent"
Text="{ext:Locale SettingsTabSystemTurboMultiplier}"
ToolTip.Tip="{ext:Locale SettingsTabSystemTurboMultiplierToolTip}"
Width="250" />
<ui:NumberBox ToolTip.Tip="{ext:Locale SettingsTabSystemTurboMultiplierValueToolTip}"
Value="{Binding TurboMultiplier}"
Width="165"
SmallChange="1.0"
LargeChange="10"
SimpleNumberFormat="F0"
SpinButtonPlacementMode="Hidden"
Minimum="50"
Maximum="500" />
<Slider Value="{Binding TurboMultiplier}"
ToolTip.Tip="{ext:Locale SettingsTabSystemTurboMultiplierValueToolTip}"
MinWidth="175"
Margin="10,-3,0,0"
Height="32"
Padding="0,-5"
TickFrequency="1"
IsSnapToTickEnabled="True"
LargeChange="10"
SmallChange="1"
VerticalAlignment="Center"
Minimum="50"
Maximum="500" />
<TextBlock Margin="5,0"
Width="40"
Text="{Binding TurboMultiplierPercentageText}"/>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
</ScrollViewer>

View File

@@ -19,7 +19,7 @@
<Setter Property="Margin" Value="10, 0, 0, 0" />
<Setter Property="Orientation" Value="Horizontal" />
</Style>
<Style Selector="StackPanel > StackPanel > TextBlock">
<Style Selector="StackPanel > StackPanel > TextBlock.settingHeader">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Width" Value="230" />
</Style>
@@ -47,71 +47,79 @@
Classes="h1"
Text="{ext:Locale SettingsTabHotkeysHotkeys}" />
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleVSyncModeHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleVSyncModeHotkey}" Classes="settingHeader" />
<ToggleButton Name="ToggleVSyncMode">
<TextBlock Text="{Binding KeyboardHotkey.ToggleVSyncMode, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysScreenshotHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysScreenshotHotkey}" Classes="settingHeader" />
<ToggleButton Name="Screenshot">
<TextBlock Text="{Binding KeyboardHotkey.Screenshot, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysShowUiHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysShowUiHotkey}" Classes="settingHeader" />
<ToggleButton Name="ShowUI">
<TextBlock Text="{Binding KeyboardHotkey.ShowUI, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysPauseHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysPauseHotkey}" Classes="settingHeader" />
<ToggleButton Name="Pause">
<TextBlock Text="{Binding KeyboardHotkey.Pause, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleMuteHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleMuteHotkey}" Classes="settingHeader" />
<ToggleButton Name="ToggleMute">
<TextBlock Text="{Binding KeyboardHotkey.ToggleMute, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleUpHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleUpHotkey}" Classes="settingHeader" />
<ToggleButton Name="ResScaleUp">
<TextBlock Text="{Binding KeyboardHotkey.ResScaleUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleDownHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleDownHotkey}" Classes="settingHeader" />
<ToggleButton Name="ResScaleDown">
<TextBlock Text="{Binding KeyboardHotkey.ResScaleDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeUpHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeUpHotkey}" Classes="settingHeader" />
<ToggleButton Name="VolumeUp">
<TextBlock Text="{Binding KeyboardHotkey.VolumeUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeDownHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeDownHotkey}" Classes="settingHeader" />
<ToggleButton Name="VolumeDown">
<TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey}" Classes="settingHeader" />
<ToggleButton Name="CustomVSyncIntervalIncrement">
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalIncrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey}" />
<TextBlock Text="{ext:Locale SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey}" Classes="settingHeader" />
<ToggleButton Name="CustomVSyncIntervalDecrement">
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalDecrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabHotkeysTurboMode}" Classes="settingHeader" ToolTip.Tip="{ext:Locale SettingsTabHotkeysTurboModeToolTip}" Background="Transparent" />
<ToggleButton Name="TurboMode">
<TextBlock Text="{Binding KeyboardHotkey.TurboMode, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
<TextBlock Text="{ext:Locale SettingsTabHotkeysOnlyWhilePressed}" Margin="10,0" />
<CheckBox IsChecked="{Binding KeyboardHotkey.TurboModeWhileHeld}" />
</StackPanel>
</StackPanel>
</Border>
</ScrollViewer>

View File

@@ -116,6 +116,9 @@ namespace Ryujinx.Ava.UI.Views.Settings
case "CustomVSyncIntervalDecrement":
viewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = buttonValue.AsHidType<Key>();
break;
case "TurboMode":
viewModel.KeyboardHotkey.TurboMode = buttonValue.AsHidType<Key>();
break;
}
}
};

View File

@@ -2,8 +2,8 @@ using Avalonia.Collections;
using LibHac.Tools.FsSystem;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using System.Collections.Generic;
@@ -38,9 +38,12 @@ namespace Ryujinx.Ava.UI.Windows
MinHeight = 650;
LoadedCheats = [];
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
Heading = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.CheatWindowHeading, titleName, titleId.ToUpper());
BuildId = ApplicationData.GetBuildId(virtualFileSystem, ConfigurationState.Instance.System.IntegrityCheckLevel, titlePath);
BuildId = ApplicationData.GetBuildId(virtualFileSystem, checkLevel, titlePath);
InitializeComponent();

View File

@@ -1,82 +0,0 @@
<window:StyleableAppWindow xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:helpers="using:Ryujinx.Ava.UI.Helpers"
xmlns:ext="using:Ryujinx.Ava.Common.Markup"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:systems="clr-namespace:Ryujinx.Ava.Systems"
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
CanResize="False"
mc:Ignorable="d"
MinWidth="800"
MinHeight="745"
x:Class="Ryujinx.Ava.UI.Windows.CompatibilityListWindow"
x:DataType="viewModels:CompatibilityViewModel">
<window:StyleableAppWindow.DataContext>
<viewModels:CompatibilityViewModel />
</window:StyleableAppWindow.DataContext>
<Grid RowDefinitions="Auto,*">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto" Name="FlushControls">
<Image
Name="RyuLogo"
Margin="15, 0, 7, 0"
Height="25"
Width="25" />
<TextBox Name="SearchBoxFlush" Grid.Column="1" Margin="0, 5, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermarkWithCount}" TextChanged="TextBox_OnTextChanged" />
<CheckBox Grid.Column="2" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
<TextBlock Grid.Column="3" Padding="0, 0, 138, 0" Margin="-10, 0, 18, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
</Grid>
<Grid Grid.Row="0" ColumnDefinitions="*,Auto,Auto" Name="NormalControls">
<TextBox Name="SearchBoxNormal" Grid.Column="0" Margin="15, 0, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermark}" TextChanged="TextBox_OnTextChanged" />
<CheckBox Grid.Column="1" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
<TextBlock Grid.Column="2" Padding="0, 0, 1, 0" Margin="-10, 0, 18, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
</Grid>
<ScrollViewer Grid.Row="1">
<ListBox Margin="12, 0, 13, 0"
Background="Transparent"
ItemsSource="{Binding CurrentEntries}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type systems:CompatibilityEntry}">
<Grid MinWidth="800"
Margin="10"
ColumnDefinitions="*,Auto,Auto,*"
Background="Transparent"
ToolTip.Tip="{Binding LocalizedLastUpdated}">
<TextBlock Grid.Column="0"
Text="{Binding GameName}"
Width="525"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" />
<TextBlock Grid.Column="1"
Width="135"
Padding="7, 0, 0, 0"
FontFamily="{StaticResource JetBrainsMono}"
Text="{Binding FormattedTitleId}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" />
<TextBlock Grid.Column="2"
Padding="7, 0"
Text="{Binding LocalizedStatus}"
Width="90"
Background="Transparent"
ToolTip.Tip="{Binding LocalizedStatusDescription}"
Foreground="{Binding Status, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="NoWrap" />
<TextBlock Grid.Column="3"
Text="{Binding FormattedIssueLabels}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
TextWrapping="WrapWithOverflow" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
<Grid></Grid>
</Grid>
</window:StyleableAppWindow>

View File

@@ -1,50 +0,0 @@
using Avalonia.Controls;
using Avalonia.Styling;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Windowing;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows
{
public partial class CompatibilityListWindow : StyleableAppWindow
{
public static Task Show(string titleId = null) =>
ShowAsync(new CompatibilityListWindow
{
DataContext = new CompatibilityViewModel(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary),
SearchBoxFlush = { Text = titleId ?? string.Empty },
SearchBoxNormal = { Text = titleId ?? string.Empty }
});
public CompatibilityListWindow() : base(useCustomTitleBar: true)
{
Title = RyujinxApp.FormatTitle(LocaleKeys.CompatibilityListTitle);
TitleBar.Height = 37;
InitializeComponent();
RyuLogo.Source = MainWindowViewModel.IconBitmap;
FlushControls.IsVisible = !ConfigurationState.Instance.ShowTitleBar;
NormalControls.IsVisible = ConfigurationState.Instance.ShowTitleBar;
}
// ReSharper disable once UnusedMember.Local
// its referenced in the axaml but rider keeps yelling at me that its unused so
private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
if (DataContext is not CompatibilityViewModel cvm)
return;
if (sender is not TextBox searchBox)
return;
cvm.Search(searchBox.Text);
}
}
}

View File

@@ -5,7 +5,7 @@ using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Helper;
using System.Threading.Tasks;

View File

@@ -11,7 +11,7 @@ using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.SystemState;

View File

@@ -18,9 +18,9 @@ using Ryujinx.Ava.UI.Applet;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Systems.Configuration.UI;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common;
using Ryujinx.Common.Helper;
using Ryujinx.Common.Logging;
@@ -76,7 +76,7 @@ namespace Ryujinx.Ava.UI.Windows
public readonly double StatusBarHeight;
public readonly double MenuBarHeight;
public MainWindow() : base(useCustomTitleBar: true)
public MainWindow()
{
DataContext = ViewModel = new MainWindowViewModel
{
@@ -90,6 +90,9 @@ namespace Ryujinx.Ava.UI.Windows
ViewModel.Title = RyujinxApp.FormatTitle();
TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar;
TitleBar.TitleBarHitTestType = (ConfigurationState.Instance.ShowTitleBar) ? TitleBarHitTestType.Simple : TitleBarHitTestType.Complex;
// NOTE: Height of MenuBar and StatusBar is not usable here, since it would still be 0 at this point.
StatusBarHeight = StatusBarView.StatusBar.MinHeight;
MenuBarHeight = MenuBar.MinHeight;
@@ -270,7 +273,11 @@ namespace Ryujinx.Ava.UI.Windows
LibHacHorizonManager.InitializeBcatServer();
LibHacHorizonManager.InitializeSystemClients();
ApplicationLibrary = new ApplicationLibrary(VirtualFileSystem, ConfigurationState.Instance.System.IntegrityCheckLevel)
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
ApplicationLibrary = new ApplicationLibrary(VirtualFileSystem, checkLevel)
{
DesiredLanguage = ConfigurationState.Instance.System.Language,
};

View File

@@ -6,7 +6,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Helper;
using System.Threading.Tasks;
using Button = Avalonia.Controls.Button;

View File

@@ -6,7 +6,6 @@ using Avalonia.Media;
using Avalonia.Platform;
using FluentAvalonia.UI.Windowing;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.ViewModels;
using System.Threading.Tasks;
@@ -22,7 +21,7 @@ namespace Ryujinx.Ava.UI.Windows
await appWindow.ShowDialog(owner ?? RyujinxApp.MainWindow);
}
protected StyleableAppWindow(bool useCustomTitleBar = false)
protected StyleableAppWindow()
{
WindowStartupLocation = WindowStartupLocation.CenterOwner;
TransparencyLevelHint = [WindowTransparencyLevel.None];
@@ -30,12 +29,6 @@ namespace Ryujinx.Ava.UI.Windows
LocaleManager.Instance.LocaleChanged += LocaleChanged;
LocaleChanged();
if (useCustomTitleBar)
{
TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar;
TitleBar.TitleBarHitTestType = ConfigurationState.Instance.ShowTitleBar ? TitleBarHitTestType.Simple : TitleBarHitTestType.Complex;
}
Icon = MainWindowViewModel.IconBitmap;
}

View File

@@ -5,7 +5,7 @@ using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Helper;
using System.Threading.Tasks;

View File

@@ -1,6 +1,6 @@
using System;
namespace Ryujinx.Ava.Systems.AppLibrary
namespace Ryujinx.Ava.Utilities.AppLibrary
{
public class ApplicationCountUpdatedEventArgs : EventArgs
{

View File

@@ -9,8 +9,8 @@ using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.PlayReport;
using Ryujinx.Ava.Utilities.Compat;
using Ryujinx.Ava.Utilities.PlayReport;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.Loaders.Processes.Extensions;
@@ -18,7 +18,7 @@ using System;
using System.IO;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.AppLibrary
namespace Ryujinx.Ava.Utilities.AppLibrary
{
public class ApplicationData
{

View File

@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.AppLibrary
namespace Ryujinx.Ava.Utilities.AppLibrary
{
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ApplicationMetadata))]

View File

@@ -12,9 +12,8 @@ using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer;
@@ -39,7 +38,7 @@ using MissingKeyException = LibHac.Common.Keys.MissingKeyException;
using Path = System.IO.Path;
using TimeSpan = System.TimeSpan;
namespace Ryujinx.Ava.Systems.AppLibrary
namespace Ryujinx.Ava.Utilities.AppLibrary
{
public class ApplicationLibrary
{
@@ -618,11 +617,15 @@ namespace Ryujinx.Ava.Systems.AppLibrary
case ".xci":
case ".nsp":
{
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
using IFileSystem pfs =
PartitionFileSystemUtils.OpenApplicationFileSystem(filePath, _virtualFileSystem);
Dictionary<ulong, ContentMetaData> updates =
pfs.GetContentData(ContentMetaType.Patch, _virtualFileSystem, ConfigurationState.Instance.System.IntegrityCheckLevel);
pfs.GetContentData(ContentMetaType.Patch, _virtualFileSystem, checkLevel);
if (updates.Count == 0)
{

View File

@@ -1,7 +1,7 @@
using System;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.AppLibrary
namespace Ryujinx.Ava.Utilities.AppLibrary
{
public class ApplicationMetadata
{

View File

@@ -4,7 +4,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
namespace Ryujinx.Ava.Systems.AppLibrary
namespace Ryujinx.Ava.Utilities.AppLibrary
{
public struct LdnGameData
{

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
namespace Ryujinx.Ava.Systems.AppLibrary
namespace Ryujinx.Ava.Utilities.AppLibrary
{
public class LdnGameDataReceivedEventArgs : EventArgs
{

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.AppLibrary
namespace Ryujinx.Ava.Utilities.AppLibrary
{
[JsonSerializable(typeof(IEnumerable<LdnGameData>))]
internal partial class LdnGameDataSerializerContext : JsonSerializerContext;

View File

@@ -2,7 +2,7 @@
using LibHac.Ncm;
using LibHac.Ns;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.HLE;
using Ryujinx.HLE.FileSystem;

View File

@@ -9,7 +9,7 @@ using System.Linq;
using System.Reflection;
using System.Text;
namespace Ryujinx.Ava.Systems
namespace Ryujinx.Ava.Utilities.Compat
{
public struct ColumnIndices(Func<ReadOnlySpan<char>, int> getIndex)
{

View File

@@ -0,0 +1,81 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Ryujinx.Ava.Utilities.Compat"
xmlns:helpers="using:Ryujinx.Ava.UI.Helpers"
xmlns:ext="using:Ryujinx.Ava.Common.Markup"
xmlns:ui="using:FluentAvalonia.UI.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.Utilities.Compat.CompatibilityList"
x:DataType="local:CompatibilityViewModel">
<UserControl.DataContext>
<local:CompatibilityViewModel />
</UserControl.DataContext>
<Grid RowDefinitions="*,Auto,*">
<Grid
Grid.Row="0"
HorizontalAlignment="Center"
ColumnDefinitions="Auto,*"
Margin="0 0 0 10">
<ui:FontIcon
Grid.Column="0"
Margin="0"
HorizontalAlignment="Stretch"
FontFamily="avares://FluentAvalonia/Fonts#Symbols"
Glyph="{helpers:GlyphValueConverter Important}" />
<!-- NOTE: aligning to bottom for better visual alignment with glyph -->
<TextBlock
Grid.Column="1"
Margin="5, 0, 0, 0"
FontStyle="Italic"
VerticalAlignment="Center"
TextWrapping="Wrap"
Text="{ext:Locale CompatibilityListWarning}" />
</Grid>
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto">
<TextBox Name="SearchBox" Grid.Column="0" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermark}" TextChanged="TextBox_OnTextChanged" />
<CheckBox Grid.Column="1" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
<TextBlock Grid.Column="2" Margin="-10, 0, 0, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
</Grid>
<ScrollViewer Grid.Row="2">
<ListBox Margin="0,5, 0, 0"
Background="Transparent"
ItemsSource="{Binding CurrentEntries}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:CompatibilityEntry}">
<Grid Width="750"
Margin="5"
ColumnDefinitions="Auto,Auto,Auto,*"
Background="Transparent"
ToolTip.Tip="{Binding LocalizedLastUpdated}">
<TextBlock Grid.Column="0"
Text="{Binding GameName}"
Width="320"
TextWrapping="Wrap" />
<TextBlock Grid.Column="1"
Width="135"
Padding="7, 0, 0, 0"
FontFamily="{StaticResource JetBrainsMono}"
Text="{Binding FormattedTitleId}"
TextWrapping="Wrap" />
<TextBlock Grid.Column="2"
Padding="7, 0"
VerticalAlignment="Center"
Text="{Binding LocalizedStatus}"
Width="85"
Background="Transparent"
ToolTip.Tip="{Binding LocalizedStatusDescription}"
Foreground="{Binding Status, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
TextWrapping="NoWrap" />
<TextBlock Grid.Column="3"
VerticalAlignment="Center"
Text="{Binding FormattedIssueLabels}"
TextWrapping="WrapWithOverflow" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -0,0 +1,47 @@
using Avalonia.Controls;
using Avalonia.Styling;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Utilities.Compat
{
public partial class CompatibilityList : UserControl
{
public static async Task Show(string titleId = null)
{
ContentDialog contentDialog = new()
{
PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty,
CloseButtonText = LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
Content = new CompatibilityList
{
DataContext = new CompatibilityViewModel(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary),
SearchBox = {
Text = titleId ?? ""
}
}
};
await ContentDialogHelper.ShowAsync(contentDialog.ApplyStyles());
}
public CompatibilityList()
{
InitializeComponent();
}
private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
if (DataContext is not CompatibilityViewModel cvm)
return;
if (sender is not TextBox searchBox)
return;
cvm.Search(searchBox.Text);
}
}
}

View File

@@ -1,11 +1,10 @@
using Gommon;
using Ryujinx.Ava.Systems;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities.AppLibrary;
using System.Collections.Generic;
using System.Linq;
namespace Ryujinx.Ava.UI.ViewModels
namespace Ryujinx.Ava.Utilities.Compat
{
public class CompatibilityViewModel : BaseModel
{

View File

@@ -1,7 +1,7 @@
using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration
namespace Ryujinx.Ava.Utilities.Configuration
{
[JsonConverter(typeof(TypedStringEnumConverter<AudioBackend>))]
public enum AudioBackend

View File

@@ -1,5 +1,5 @@
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI;
using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Multiplayer;
@@ -8,14 +8,14 @@ using Ryujinx.Common.Utilities;
using Ryujinx.HLE;
using System.Collections.Generic;
namespace Ryujinx.Ava.Systems.Configuration
namespace Ryujinx.Ava.Utilities.Configuration
{
public class ConfigurationFileFormat
{
/// <summary>
/// The current version of the file format
/// </summary>
public const int CurrentVersion = 67;
public const int CurrentVersion = 68;
/// <summary>
/// Version of the configuration file format
@@ -258,6 +258,11 @@ namespace Ryujinx.Ava.Systems.Configuration
/// Enables or disables low-power profiled translation cache persistency loading
/// </summary>
public bool EnableLowPowerPtc { get; set; }
/// <summary>
/// Clock tick scalar, in percent points (100 = 1.0).
/// </summary>
public long TickScalar { get; set; }
/// <summary>
/// Enables or disables guest Internet access

View File

@@ -1,6 +1,6 @@
using Ryujinx.Common.Utilities;
namespace Ryujinx.Ava.Systems.Configuration
namespace Ryujinx.Ava.Utilities.Configuration
{
internal static class ConfigurationFileFormatSettings
{

View File

@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration
namespace Ryujinx.Ava.Utilities.Configuration
{
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ConfigurationFileFormat))]

View File

@@ -1,7 +1,7 @@
using Avalonia.Media;
using Gommon;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI;
using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
@@ -14,7 +14,7 @@ using System.Collections.Generic;
using System.Linq;
using RyuLogger = Ryujinx.Common.Logging.Logger;
namespace Ryujinx.Ava.Systems.Configuration
namespace Ryujinx.Ava.Utilities.Configuration
{
public partial class ConfigurationState
{
@@ -94,6 +94,7 @@ namespace Ryujinx.Ava.Systems.Configuration
System.EnableDockedMode.Value = cff.DockedMode;
System.EnablePtc.Value = cff.EnablePtc;
System.EnableLowPowerPtc.Value = cff.EnableLowPowerPtc;
System.TickScalar.Value = cff.TickScalar;
System.EnableInternetAccess.Value = cff.EnableInternetAccess;
System.EnableFsIntegrityChecks.Value = cff.EnableFsIntegrityChecks;
System.FsGlobalAccessLogMode.Value = cff.FsGlobalAccessLogMode;
@@ -441,7 +442,27 @@ namespace Ryujinx.Ava.Systems.Configuration
(64, static cff => cff.LoggingEnableAvalonia = false),
(65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off),
(66, static cff => cff.DisableInputWhenOutOfFocus = false),
(67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing)
(67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing),
(68, static cff =>
{
cff.TickScalar = 200;
cff.Hotkeys = new KeyboardHotkeys
{
ToggleVSyncMode = cff.Hotkeys.ToggleVSyncMode,
Screenshot = cff.Hotkeys.Screenshot,
ShowUI = cff.Hotkeys.ShowUI,
Pause = cff.Hotkeys.Pause,
ToggleMute = cff.Hotkeys.ToggleMute,
ResScaleUp = cff.Hotkeys.ResScaleUp,
ResScaleDown = cff.Hotkeys.ResScaleDown,
VolumeUp = cff.Hotkeys.VolumeUp,
VolumeDown = cff.Hotkeys.VolumeDown,
CustomVSyncIntervalIncrement = cff.Hotkeys.CustomVSyncIntervalIncrement,
CustomVSyncIntervalDecrement = cff.Hotkeys.CustomVSyncIntervalDecrement,
TurboMode = Key.Unbound,
TurboModeWhileHeld = false
};
})
);
}
}

View File

@@ -1,8 +1,8 @@
using ARMeilleure;
using Gommon;
using LibHac.Tools.FsSystem;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI;
using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
@@ -16,7 +16,7 @@ using System.Collections.Generic;
using System.Linq;
using RyuLogger = Ryujinx.Common.Logging.Logger;
namespace Ryujinx.Ava.Systems.Configuration
namespace Ryujinx.Ava.Utilities.Configuration
{
public partial class ConfigurationState
{
@@ -336,6 +336,11 @@ namespace Ryujinx.Ava.Systems.Configuration
/// Enables or disables persistent profiled translation cache
/// </summary>
public ReactiveObject<bool> EnablePtc { get; private set; }
/// <summary>
/// Clock tick scalar, in percent points (100 = 1.0).
/// </summary>
public ReactiveObject<long> TickScalar { get; set; }
/// <summary>
/// Enables or disables low-power persistent profiled translation cache loading
@@ -352,10 +357,6 @@ namespace Ryujinx.Ava.Systems.Configuration
/// </summary>
public ReactiveObject<bool> EnableFsIntegrityChecks { get; private set; }
public IntegrityCheckLevel IntegrityCheckLevel => EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
/// <summary>
/// Enables FS access log output to the console. Possible modes are 0-3
/// </summary>
@@ -416,6 +417,15 @@ namespace Ryujinx.Ava.Systems.Configuration
EnableLowPowerPtc.LogChangesToValue(nameof(EnableLowPowerPtc));
EnableLowPowerPtc.Event += (_, evnt)
=> Optimizations.LowPower = evnt.NewValue;
TickScalar = new ReactiveObject<long>();
TickScalar.LogChangesToValue(nameof(TickScalar));
TickScalar.Event += (_, evnt) =>
{
if (Switch.Shared is null)
return;
Switch.Shared.Configuration.TickScalar = evnt.NewValue;
};
EnableInternetAccess = new ReactiveObject<bool>();
EnableInternetAccess.LogChangesToValue(nameof(EnableInternetAccess));
EnableFsIntegrityChecks = new ReactiveObject<bool>();
@@ -847,11 +857,12 @@ namespace Ryujinx.Ava.Systems.Configuration
public HleConfiguration CreateHleConfiguration() =>
new(
System.DramSize,
System.Language.Value.ToHLE(),
System.Region.Value.ToHLE(),
(SystemLanguage)System.Language.Value,
(RegionCode)System.Region.Value,
Graphics.VSyncMode,
System.EnableDockedMode,
System.EnablePtc,
System.TickScalar,
System.EnableInternetAccess,
System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
@@ -870,8 +881,8 @@ namespace Ryujinx.Ava.Systems.Configuration
Multiplayer.Mode,
Multiplayer.DisableP2p,
Multiplayer.LdnPassphrase,
Instance.Multiplayer.GetLdnServer(),
Instance.Graphics.CustomVSyncInterval,
Instance.Hacks.ShowDirtyHacks ? Instance.Hacks.EnabledHacks : null);
Multiplayer.GetLdnServer(),
Graphics.CustomVSyncInterval,
Hacks.ShowDirtyHacks ? Hacks.EnabledHacks : null);
}
}

View File

@@ -1,5 +1,5 @@
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI;
using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Keyboard;
@@ -9,7 +9,7 @@ using Ryujinx.HLE;
using System;
using System.Linq;
namespace Ryujinx.Ava.Systems.Configuration
namespace Ryujinx.Ava.Utilities.Configuration
{
public partial class ConfigurationState
{
@@ -73,6 +73,7 @@ namespace Ryujinx.Ava.Systems.Configuration
EnableColorSpacePassthrough = Graphics.EnableColorSpacePassthrough,
EnablePtc = System.EnablePtc,
EnableLowPowerPtc = System.EnableLowPowerPtc,
TickScalar = System.TickScalar,
EnableInternetAccess = System.EnableInternetAccess,
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
@@ -261,6 +262,10 @@ namespace Ryujinx.Ava.Systems.Configuration
ResScaleDown = Key.Unbound,
VolumeUp = Key.Unbound,
VolumeDown = Key.Unbound,
CustomVSyncIntervalIncrement = Key.Unbound,
CustomVSyncIntervalDecrement = Key.Unbound,
TurboMode = Key.Unbound,
TurboModeWhileHeld = false
};
Hid.RainbowSpeed.Value = 1f;
Hid.InputConfig.Value =

View File

@@ -1,8 +1,8 @@
using System;
using static Ryujinx.Ava.Systems.Configuration.ConfigurationState.UISection;
using static Ryujinx.Ava.Utilities.Configuration.ConfigurationState.UISection;
namespace Ryujinx.Ava.Systems.Configuration
namespace Ryujinx.Ava.Utilities.Configuration
{
public enum FileTypes
{

View File

@@ -4,7 +4,7 @@ using Ryujinx.Common.Logging.Targets;
using System;
using System.IO;
namespace Ryujinx.Ava.Systems.Configuration
namespace Ryujinx.Ava.Utilities.Configuration
{
public static class LoggerModule
{

View File

@@ -1,7 +1,7 @@
using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration.System
namespace Ryujinx.Ava.Utilities.Configuration.System
{
[JsonConverter(typeof(TypedStringEnumConverter<Language>))]
public enum Language
@@ -25,13 +25,4 @@ namespace Ryujinx.Ava.Systems.Configuration.System
TraditionalChinese,
BrazilianPortuguese,
}
public static class LanguageEnumHelper
{
public static Language ToUI(this HLE.HOS.SystemState.SystemLanguage hleLanguage)
=> (Language)hleLanguage;
public static HLE.HOS.SystemState.SystemLanguage ToHLE(this Language uiLanguage)
=> (HLE.HOS.SystemState.SystemLanguage)uiLanguage;
}
}

View File

@@ -0,0 +1,17 @@
using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.Configuration.System
{
[JsonConverter(typeof(TypedStringEnumConverter<Region>))]
public enum Region
{
Japan,
USA,
Europe,
Australia,
China,
Korea,
Taiwan,
}
}

View File

@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Systems.Configuration.UI
namespace Ryujinx.Ava.Utilities.Configuration.UI
{
public struct ColumnSort
{

View File

@@ -1,7 +1,7 @@
using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration.UI
namespace Ryujinx.Ava.Utilities.Configuration.UI
{
[JsonConverter(typeof(TypedStringEnumConverter<FocusLostType>))]
public enum FocusLostType

View File

@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Systems.Configuration.UI
namespace Ryujinx.Ava.Utilities.Configuration.UI
{
public struct GuiColumns
{

View File

@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Systems.Configuration.UI
namespace Ryujinx.Ava.Utilities.Configuration.UI
{
public struct ShownFileTypes
{

View File

@@ -1,7 +1,7 @@
using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration.UI
namespace Ryujinx.Ava.Utilities.Configuration.UI
{
[JsonConverter(typeof(TypedStringEnumConverter<UpdaterType>))]
public enum UpdaterType

View File

@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Systems.Configuration.UI
namespace Ryujinx.Ava.Utilities.Configuration.UI
{
public struct WindowStartup
{

View File

@@ -1,5 +1,5 @@
using Gommon;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
@@ -7,7 +7,7 @@ using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
namespace Ryujinx.Ava.Systems.PlayReport
namespace Ryujinx.Ava.Utilities.PlayReport
{
/// <summary>
/// The entrypoint for the Play Report analysis system.

View File

@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Systems.PlayReport
namespace Ryujinx.Ava.Utilities.PlayReport
{
/// <summary>
/// The delegate type that powers single value formatters.<br/>

View File

@@ -1,8 +1,8 @@
using MsgPack;
using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Utilities.AppLibrary;
using System.Collections.Generic;
namespace Ryujinx.Ava.Systems.PlayReport
namespace Ryujinx.Ava.Utilities.PlayReport
{
public abstract class MatchedValue<T>
{

Some files were not shown because too many files have changed in this diff Show More