Compare commits

...

10 commits

Author SHA1 Message Date
WilliamWsyHK
da6fe2e574
Merge 36c061453b into cbd851d00e 2024-12-29 11:56:25 +00:00
WilliamWsyHK
36c061453b Address comment from GreemDev 2024-12-29 19:56:17 +08:00
WilliamWsyHK
f5dcf671e8 Skip processing application for LDN if it does not have control holder 2024-12-29 19:56:16 +08:00
Evan Husted
cbd851d00e misc: Forgot about ReactiveObject
Some checks are pending
Canary release job / Create tag (push) Waiting to run
Canary release job / Release for linux-arm64 (push) Waiting to run
Canary release job / Release for linux-x64 (push) Waiting to run
Canary release job / Release for win-x64 (push) Waiting to run
Canary release job / Release MacOS universal (push) Waiting to run
2024-12-29 04:16:08 -06:00
Evan Husted
f463ea1c5d misc: Refactor Discord integration to listen on TitleIDs.CurrentApplication changes instead of waiting to be directly told when to change states. 2024-12-29 03:27:05 -06:00
Evan Husted
1dd69912b1 Partial revert, decouple TitleIDs.CurrentApplication from shader cache stuff; as I want that to ALWAYS reflect the current app. 2024-12-29 03:02:56 -06:00
Evan Husted
1fbb0d8e7d metal: also disable vsync for custom refresh rates 2024-12-29 02:21:25 -06:00
Evan Husted
9ee3f1ff36 metal: add PKL Arceus to MetalGreatTitles 2024-12-29 00:28:18 -06:00
Evan Husted
d052d74ac4 misc: Remove duplicate prefix in GPU information line in log 2024-12-29 00:27:23 -06:00
Evan Husted
df91c4c57a UI: Fix Title updates being not formatted
Some checks are pending
Canary release job / Create tag (push) Waiting to run
Canary release job / Release for linux-arm64 (push) Waiting to run
Canary release job / Release for linux-x64 (push) Waiting to run
Canary release job / Release for win-x64 (push) Waiting to run
Canary release job / Release MacOS universal (push) Waiting to run
2024-12-29 00:08:20 -06:00
14 changed files with 85 additions and 49 deletions

View file

@ -8,10 +8,10 @@ namespace Ryujinx.Common
public static class StreamExtensions
{
/// <summary>
/// Writes a <see cref="ReadOnlySpan{int}" /> to this stream.
/// Writes an int span to this stream.
///
/// This default implementation converts each buffer value to a stack-allocated
/// byte array, then writes it to the Stream using <cref="System.Stream.Write(byte[])" />.
/// byte array, then writes it to the Stream using <see cref="Stream.Write(ReadOnlySpan{byte})" />.
/// </summary>
/// <param name="stream">The stream to be written to</param>
/// <param name="buffer">The buffer of values to be written</param>

View file

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

View file

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

View file

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

View file

@ -22,13 +22,15 @@ namespace Ryujinx.Graphics.Metal
private int _requestedWidth;
private int _requestedHeight;
// private bool _vsyncEnabled;
private AntiAliasing _currentAntiAliasing;
private bool _updateEffect;
private IPostProcessingEffect _effect;
private IScalingFilter _scalingFilter;
private bool _isLinear;
public bool IsVSyncEnabled => _metalLayer.DisplaySyncEnabled;
// private float _scalingFilterLevel;
private bool _updateScalingFilter;
private ScalingFilter _currentScalingFilter;
@ -40,7 +42,7 @@ namespace Ryujinx.Graphics.Metal
_metalLayer = metalLayer;
}
private unsafe void ResizeIfNeeded()
private void ResizeIfNeeded()
{
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)
{
@ -141,15 +143,7 @@ namespace Ryujinx.Graphics.Metal
public void ChangeVSyncMode(VSyncMode vSyncMode)
{
switch (vSyncMode)
{
case VSyncMode.Unbounded:
_metalLayer.DisplaySyncEnabled = false;
break;
case VSyncMode.Switch:
_metalLayer.DisplaySyncEnabled = true;
break;
}
_metalLayer.DisplaySyncEnabled = vSyncMode is VSyncMode.Switch;
}
public void SetAntiAliasing(AntiAliasing effect)

View file

@ -1,3 +1,4 @@
using Gommon;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
@ -890,7 +891,12 @@ namespace Ryujinx.Graphics.Vulkan
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");
}

View file

@ -39,7 +39,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
using var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true);
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
if (context.Device.DirtyHacks.HasFlag(DirtyHacks.Xc2MenuSoftlockFix) && TitleIDs.CurrentApplication == Xc2TitleId)
if (context.Device.DirtyHacks.HasFlag(DirtyHacks.Xc2MenuSoftlockFix) && TitleIDs.CurrentApplication.Value == Xc2TitleId)
{
// Add a load-bearing sleep to avoid XC2 softlock
// https://web.archive.org/web/20240728045136/https://github.com/Ryujinx/Ryujinx/issues/2357

View file

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

View file

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

View file

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

View file

@ -2,6 +2,7 @@ using DiscordRPC;
using Humanizer;
using Humanizer.Localisation;
using Ryujinx.Common;
using Ryujinx.HLE;
using Ryujinx.HLE.Loaders.Processes;
using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common.Configuration;
@ -44,6 +45,16 @@ namespace Ryujinx.UI.Common
};
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
TitleIDs.CurrentApplication.Event += (_, e) =>
{
if (e.NewValue)
SwitchToPlayingState(
ApplicationLibrary.LoadAndSaveMetaData(e.NewValue),
Switch.Shared.Processes.ActiveApplication
);
else
SwitchToMainState();
};
}
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
{
@ -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)
{

View file

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

View file

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

View file

@ -169,7 +169,7 @@ namespace Ryujinx.Ava.UI.Windows
{
var ldnGameDataArray = e.LdnData.ToList();
ViewModel.LdnData.Clear();
foreach (var application in ViewModel.Applications)
foreach (var application in ViewModel.Applications.Where(it => it.HasControlHolder))
{
ref var controlHolder = ref application.ControlHolder.Value;