Compare commits

...

8 Commits

16 changed files with 122 additions and 62 deletions

View File

@@ -8,7 +8,20 @@ namespace Ryujinx.Common
{ {
public static class TitleIDs public static class TitleIDs
{ {
public static Optional<string> CurrentApplication; private static string _currentApplication;
public static Optional<string> CurrentApplication
{
get => _currentApplication;
set
{
_currentApplication = value.OrElse(null);
CurrentApplicationChanged?.Invoke(_currentApplication);
}
}
public static event Action<Optional<string>> CurrentApplicationChanged;
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend) public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
{ {
@@ -35,6 +48,7 @@ namespace Ryujinx.Common
"010028600EBDA000", // Mario 3D World "010028600EBDA000", // Mario 3D World
"0100152000022000", // Mario Kart 8 Deluxe "0100152000022000", // Mario Kart 8 Deluxe
"01005CA01580E000", // Persona 5 "01005CA01580E000", // Persona 5
"01001f5010dfa000", // Pokemon Legends Arceus
"01008C0016544000", // Sea of Stars "01008C0016544000", // Sea of Stars
"01006A800016E000", // Smash Ultimate "01006A800016E000", // Smash Ultimate
"0100000000010000", // Super Mario Odyessy "0100000000010000", // Super Mario Odyessy

View File

@@ -47,6 +47,12 @@ namespace Ryujinx.Graphics.Gpu
/// </summary> /// </summary>
public static bool EnableMacroHLE = true; public static bool EnableMacroHLE = true;
/// <summary>
/// Title id of the current running game.
/// Used by the shader cache.
/// </summary>
public static string TitleId;
/// <summary> /// <summary>
/// Enables or disables the shader cache. /// Enables or disables the shader cache.
/// </summary> /// </summary>

View File

@@ -117,8 +117,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// </summary> /// </summary>
private static string GetDiskCachePath() private static string GetDiskCachePath()
{ {
return GraphicsConfig.EnableShaderCache && TitleIDs.CurrentApplication.HasValue return GraphicsConfig.EnableShaderCache && GraphicsConfig.TitleId != null
? Path.Combine(AppDataManager.GamesDirPath, TitleIDs.CurrentApplication, "cache", "shader") ? Path.Combine(AppDataManager.GamesDirPath, GraphicsConfig.TitleId, "cache", "shader")
: null; : null;
} }

View File

@@ -23,12 +23,14 @@ namespace Ryujinx.Graphics.Metal
private int _requestedWidth; private int _requestedWidth;
private int _requestedHeight; private int _requestedHeight;
// private bool _vsyncEnabled;
private AntiAliasing _currentAntiAliasing; private AntiAliasing _currentAntiAliasing;
private bool _updateEffect; private bool _updateEffect;
private IPostProcessingEffect _effect; private IPostProcessingEffect _effect;
private IScalingFilter _scalingFilter; private IScalingFilter _scalingFilter;
private bool _isLinear; private bool _isLinear;
public bool IsVSyncEnabled => _metalLayer.DisplaySyncEnabled;
// private float _scalingFilterLevel; // private float _scalingFilterLevel;
private bool _updateScalingFilter; private bool _updateScalingFilter;
private ScalingFilter _currentScalingFilter; private ScalingFilter _currentScalingFilter;
@@ -40,7 +42,7 @@ namespace Ryujinx.Graphics.Metal
_metalLayer = metalLayer; _metalLayer = metalLayer;
} }
private unsafe void ResizeIfNeeded() private void ResizeIfNeeded()
{ {
if (_requestedWidth != 0 && _requestedHeight != 0) if (_requestedWidth != 0 && _requestedHeight != 0)
{ {
@@ -54,7 +56,7 @@ namespace Ryujinx.Graphics.Metal
} }
} }
public unsafe void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback) public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
{ {
if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex) if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex)
{ {
@@ -141,15 +143,7 @@ namespace Ryujinx.Graphics.Metal
public void ChangeVSyncMode(VSyncMode vSyncMode) public void ChangeVSyncMode(VSyncMode vSyncMode)
{ {
switch (vSyncMode) _metalLayer.DisplaySyncEnabled = vSyncMode is VSyncMode.Switch;
{
case VSyncMode.Unbounded:
_metalLayer.DisplaySyncEnabled = false;
break;
case VSyncMode.Switch:
_metalLayer.DisplaySyncEnabled = true;
break;
}
} }
public void SetAntiAliasing(AntiAliasing effect) public void SetAntiAliasing(AntiAliasing effect)

View File

@@ -2,8 +2,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
{ {
internal enum BitDepth internal enum BitDepth
{ {
Bits8 = 8, /**< 8 bits */ Bits8 = 8, // < 8 bits
Bits10 = 10, /**< 10 bits */ Bits10 = 10, // < 10 bits
Bits12 = 12, /**< 12 bits */ Bits12 = 12, // < 12 bits
} }
} }

View File

@@ -1,3 +1,4 @@
using Gommon;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
@@ -890,7 +891,12 @@ namespace Ryujinx.Graphics.Vulkan
private void PrintGpuInformation() private void PrintGpuInformation()
{ {
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})"); string gpuInfoMessage = $"{GpuRenderer} ({GpuVersion})";
if (!GpuRenderer.StartsWithIgnoreCase(GpuVendor))
gpuInfoMessage = gpuInfoMessage.Prepend(GpuVendor);
Logger.Notice.Print(LogClass.Gpu, gpuInfoMessage);
Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB"); Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB");
} }

View File

@@ -189,9 +189,9 @@ namespace Ryujinx.HLE
/// </summary> /// </summary>
public Action RefreshInputConfig { internal get; set; } public Action RefreshInputConfig { internal get; set; }
/** /// <summary>
* The desired hacky workarounds. /// The desired hacky workarounds.
*/ /// </summary>
public DirtyHacks Hacks { internal get; set; } public DirtyHacks Hacks { internal get; set; }
public HLEConfiguration(VirtualFileSystem virtualFileSystem, public HLEConfiguration(VirtualFileSystem virtualFileSystem,

View File

@@ -7,6 +7,7 @@ using LibHac.Tools.FsSystem;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.Loaders.Executables; using Ryujinx.HLE.Loaders.Executables;
using Ryujinx.Memory; using Ryujinx.Memory;
using System; using System;
@@ -103,7 +104,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
} }
// Initialize GPU. // Initialize GPU.
TitleIDs.CurrentApplication = programId.ToString("X16"); GraphicsConfig.TitleId = programId.ToString("X16");
device.Gpu.HostInitalized.Set(); device.Gpu.HostInitalized.Set();
if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible)) if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible))

View File

@@ -8,6 +8,7 @@ using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils; using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.Loaders.Executables; using Ryujinx.HLE.Loaders.Executables;
using Ryujinx.HLE.Loaders.Processes.Extensions; using Ryujinx.HLE.Loaders.Processes.Extensions;
using System; using System;
@@ -60,6 +61,8 @@ namespace Ryujinx.HLE.Loaders.Processes
{ {
_latestPid = processResult.ProcessId; _latestPid = processResult.ProcessId;
TitleIDs.CurrentApplication = processResult.ProgramIdText;
return true; return true;
} }
} }
@@ -87,6 +90,8 @@ namespace Ryujinx.HLE.Loaders.Processes
{ {
_latestPid = processResult.ProcessId; _latestPid = processResult.ProcessId;
TitleIDs.CurrentApplication = processResult.ProgramIdText;
return true; return true;
} }
} }
@@ -114,6 +119,8 @@ namespace Ryujinx.HLE.Loaders.Processes
if (processResult.ProgramId > 0x01000000000007FF) if (processResult.ProgramId > 0x01000000000007FF)
{ {
_latestPid = processResult.ProcessId; _latestPid = processResult.ProcessId;
TitleIDs.CurrentApplication = processResult.ProgramIdText;
} }
return true; return true;
@@ -133,6 +140,8 @@ namespace Ryujinx.HLE.Loaders.Processes
{ {
_latestPid = processResult.ProcessId; _latestPid = processResult.ProcessId;
TitleIDs.CurrentApplication = processResult.ProgramIdText;
return true; return true;
} }
} }
@@ -184,14 +193,17 @@ namespace Ryujinx.HLE.Loaders.Processes
if (nacpData.Value.PresenceGroupId != 0) if (nacpData.Value.PresenceGroupId != 0)
{ {
programId = nacpData.Value.PresenceGroupId; programId = nacpData.Value.PresenceGroupId;
TitleIDs.CurrentApplication = programId.ToString("X16");
} }
else if (nacpData.Value.SaveDataOwnerId != 0) else if (nacpData.Value.SaveDataOwnerId != 0)
{ {
programId = nacpData.Value.SaveDataOwnerId; programId = nacpData.Value.SaveDataOwnerId;
TitleIDs.CurrentApplication = programId.ToString("X16");
} }
else if (nacpData.Value.AddOnContentBaseId != 0) else if (nacpData.Value.AddOnContentBaseId != 0)
{ {
programId = nacpData.Value.AddOnContentBaseId - 0x1000; programId = nacpData.Value.AddOnContentBaseId - 0x1000;
TitleIDs.CurrentApplication = programId.ToString("X16");
} }
} }
@@ -205,7 +217,7 @@ namespace Ryujinx.HLE.Loaders.Processes
} }
// Explicitly null TitleId to disable the shader cache. // Explicitly null TitleId to disable the shader cache.
TitleIDs.CurrentApplication = default; GraphicsConfig.TitleId = null;
_device.Gpu.HostInitalized.Set(); _device.Gpu.HostInitalized.Set();
ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device, ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device,

View File

@@ -2,6 +2,7 @@ using LibHac.Common;
using LibHac.Ns; using LibHac.Ns;
using Ryujinx.Audio.Backends.CompatLayer; using Ryujinx.Audio.Backends.CompatLayer;
using Ryujinx.Audio.Integration; using Ryujinx.Audio.Integration;
using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
@@ -17,6 +18,8 @@ namespace Ryujinx.HLE
{ {
public class Switch : IDisposable public class Switch : IDisposable
{ {
public static Switch Shared { get; private set; }
public HLEConfiguration Configuration { get; } public HLEConfiguration Configuration { get; }
public IHardwareDeviceDriver AudioDeviceDriver { get; } public IHardwareDeviceDriver AudioDeviceDriver { get; }
public MemoryBlock Memory { get; } public MemoryBlock Memory { get; }
@@ -77,6 +80,8 @@ namespace Ryujinx.HLE
DirtyHacks = Configuration.Hacks; DirtyHacks = Configuration.Hacks;
UpdateVSyncInterval(); UpdateVSyncInterval();
#pragma warning restore IDE0055 #pragma warning restore IDE0055
Shared = this;
} }
public void ProcessFrame() public void ProcessFrame()
@@ -145,6 +150,9 @@ namespace Ryujinx.HLE
AudioDeviceDriver.Dispose(); AudioDeviceDriver.Dispose();
FileSystem.Dispose(); FileSystem.Dispose();
Memory.Dispose(); Memory.Dispose();
TitleIDs.CurrentApplication = null;
Shared = null;
} }
} }
} }

View File

@@ -430,14 +430,14 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary> /// </summary>
public bool UseHypervisor { get; set; } public bool UseHypervisor { get; set; }
/** /// <summary>
* Show toggles for dirty hacks in the UI. /// Show toggles for dirty hacks in the UI.
*/ /// </summary>
public bool ShowDirtyHacks { get; set; } public bool ShowDirtyHacks { get; set; }
/** /// <summary>
* The packed value of the enabled dirty hacks. /// The packed value of the enabled dirty hacks.
*/ /// </summary>
public int EnabledDirtyHacks { get; set; } public int EnabledDirtyHacks { get; set; }
/// <summary> /// <summary>

View File

@@ -696,9 +696,9 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary> /// </summary>
public MultiplayerSection Multiplayer { get; private set; } public MultiplayerSection Multiplayer { get; private set; }
/** /// <summary>
* The Dirty Hacks section /// The Dirty Hacks section
*/ /// </summary>
public HacksSection Hacks { get; private set; } public HacksSection Hacks { get; private set; }
/// <summary> /// <summary>

View File

@@ -2,6 +2,7 @@ using DiscordRPC;
using Humanizer; using Humanizer;
using Humanizer.Localisation; using Humanizer.Localisation;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.HLE;
using Ryujinx.HLE.Loaders.Processes; using Ryujinx.HLE.Loaders.Processes;
using Ryujinx.UI.App.Common; using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common.Configuration; using Ryujinx.UI.Common.Configuration;
@@ -44,6 +45,16 @@ namespace Ryujinx.UI.Common
}; };
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update; ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
TitleIDs.CurrentApplicationChanged += titleId =>
{
if (titleId)
SwitchToPlayingState(
ApplicationLibrary.LoadAndSaveMetaData(titleId),
Switch.Shared.Processes.ActiveApplication
);
else
SwitchToMainState();
};
} }
private static void Update(object sender, ReactiveEventArgs<bool> evnt) private static void Update(object sender, ReactiveEventArgs<bool> evnt)
@@ -69,7 +80,7 @@ namespace Ryujinx.UI.Common
} }
} }
public static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResult procRes) private static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResult procRes)
{ {
_discordClient?.SetPresence(new RichPresence _discordClient?.SetPresence(new RichPresence
{ {
@@ -88,7 +99,7 @@ namespace Ryujinx.UI.Common
}); });
} }
public static void SwitchToMainState() => _discordClient?.SetPresence(_discordPresenceMain); private static void SwitchToMainState() => _discordClient?.SetPresence(_discordPresenceMain);
private static string TruncateToByteLength(string input) private static string TruncateToByteLength(string input)
{ {

View File

@@ -578,7 +578,6 @@ namespace Ryujinx.Ava
public void Stop() public void Stop()
{ {
_isActive = false; _isActive = false;
DiscordIntegrationModule.SwitchToMainState();
} }
private void Exit() private void Exit()
@@ -863,12 +862,10 @@ namespace Ryujinx.Ava
return false; return false;
} }
ApplicationMetadata appMeta = ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText,
appMetadata => appMetadata.UpdatePreGame() appMetadata => appMetadata.UpdatePreGame()
); );
DiscordIntegrationModule.SwitchToPlayingState(appMeta, Device.Processes.ActiveApplication);
return true; return true;
} }

View File

@@ -17426,25 +17426,25 @@
"ID": "TitleUpdateVersionLabel", "ID": "TitleUpdateVersionLabel",
"Translations": { "Translations": {
"ar_SA": "الإصدار: {0}", "ar_SA": "الإصدار: {0}",
"de_DE": "Version {0} - {1}", "de_DE": "",
"el_GR": "Version {0} - {1}", "el_GR": "",
"en_US": "Version {0} - {1}", "en_US": "Version {0}",
"es_ES": "Versión {0} - {1}", "es_ES": "Versión {0}",
"fr_FR": "", "fr_FR": "",
"he_IL": "גרסה {0} - {1}", "he_IL": "גרסה: {0}",
"it_IT": "Versione {0} - {1}", "it_IT": "Versione {0}",
"ja_JP": "バージョン {0} - {1}", "ja_JP": "バージョン {0}",
"ko_KR": "버전 {0} - {1}", "ko_KR": "버전 {0}",
"no_NO": "Versjon {0} - {1}", "no_NO": "Versjon {0}",
"pl_PL": "Wersja {0} - {1}", "pl_PL": "Wersja {0}",
"pt_BR": "Versão {0} - {1}", "pt_BR": "Versão {0}",
"ru_RU": "Версия {0} - {1}", "ru_RU": "Версия {0}",
"sv_SE": "Version {0} - {1}", "sv_SE": "Version {0}",
"th_TH": "เวอร์ชั่น {0} - {1}", "th_TH": "เวอร์ชั่น {0}",
"tr_TR": "Sürüm {0} - {1}", "tr_TR": "Sürüm {0}",
"uk_UA": "Версія {0} - {1}", "uk_UA": "Версія {0}",
"zh_CN": "游戏更新的版本 {0} - {1}", "zh_CN": "游戏更新的版本 {0}",
"zh_TW": "版本 {0} - {1}" "zh_TW": "版本 {0}"
} }
}, },
{ {

View File

@@ -1,6 +1,7 @@
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Threading; using Avalonia.Threading;
using Gommon;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.OpenAL; using Ryujinx.Audio.Backends.OpenAL;
using Ryujinx.Audio.Backends.SDL2; using Ryujinx.Audio.Backends.SDL2;
@@ -796,7 +797,17 @@ namespace Ryujinx.Ava.UI.ViewModels
CloseWindow?.Invoke(); CloseWindow?.Invoke();
} }
public static string Xc2MenuFixTooltip => public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb =>
"From the issue on GitHub:\n\nWhen clicking very fast from game main menu to 2nd submenu, there is a low chance that the game will softlock, the submenu won't show up, while background music is still there."; {
sb.AppendLine(
"This fix applies a 2ms delay (via 'Thread.Sleep(2)') every time the game tries to read data from the emulated Switch filesystem.")
.AppendLine();
sb.AppendLine("From the issue on GitHub:").AppendLine();
sb.Append(
"When clicking very fast from game main menu to 2nd submenu, " +
"there is a low chance that the game will softlock, " +
"the submenu won't show up, while background music is still there.");
});
} }
} }