mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-06-09 13:59:13 +00:00
Compare commits
1 Commits
08ab4979d7
...
Canary-1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac5f9857e2 |
@@ -1,4 +1,3 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
@@ -115,7 +114,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
cbs.AddDependant(this);
|
||||
|
||||
// We need to add a dependency on the command buffer to all objects this object
|
||||
// references as well.
|
||||
// references aswell.
|
||||
if (_referencedObjs != null)
|
||||
{
|
||||
for (int i = 0; i < _referencedObjs.Length; i++)
|
||||
@@ -177,8 +176,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
// This can somehow become -1.
|
||||
// Logger.Info?.PrintMsg(LogClass.Gpu, $"_referenceCount: {_referenceCount}");
|
||||
Debug.Assert(_referenceCount >= 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1059,7 +1059,7 @@ namespace Ryujinx.HLE.FileSystem
|
||||
}
|
||||
}
|
||||
|
||||
public static bool AreKeysAlreadyPresent(string pathToCheck)
|
||||
public static bool AreKeysAlredyPresent(string pathToCheck)
|
||||
{
|
||||
string[] fileNames = ["prod.keys", "title.keys", "console.keys", "dev.keys"];
|
||||
foreach (string file in fileNames)
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
_activeCount = 0;
|
||||
|
||||
JoyHold = NpadJoyHoldType.Vertical;
|
||||
SixAxisActive = false;
|
||||
}
|
||||
|
||||
internal ref KEvent GetStyleSetUpdateEvent(PlayerIndex player)
|
||||
@@ -580,6 +581,24 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
|
||||
return needUpdateRight;
|
||||
}
|
||||
|
||||
public bool isAtRest(int playerNumber)
|
||||
{
|
||||
|
||||
ref NpadInternalState currentNpad = ref _device.Hid.SharedMemory.Npads[playerNumber].InternalState;
|
||||
ref SixAxisSensorState storage = ref GetSixAxisSensorLifo(ref currentNpad, false).GetCurrentEntryRef();
|
||||
|
||||
float acceleration = Math.Abs(storage.Acceleration.X)
|
||||
+ Math.Abs(storage.Acceleration.Y)
|
||||
+ Math.Abs(storage.Acceleration.Z);
|
||||
|
||||
float angularVelocity = Math.Abs(storage.AngularVelocity.X)
|
||||
+ Math.Abs(storage.AngularVelocity.Y)
|
||||
+ Math.Abs(storage.AngularVelocity.Z);
|
||||
|
||||
// TODO: check against config deadzone and add sensitivity setting
|
||||
return ((acceleration <= 1.0F) && (angularVelocity <= 1.0F));
|
||||
}
|
||||
|
||||
private void UpdateDisconnectedInputSixAxis(PlayerIndex index)
|
||||
{
|
||||
|
||||
@@ -602,19 +602,33 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
}
|
||||
|
||||
[CommandCmif(82)]
|
||||
// IsSixAxisSensorAtRest(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsAsRest
|
||||
// IsSixAxisSensorAtRest(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsAtRest
|
||||
public ResultCode IsSixAxisSensorAtRest(ServiceCtx context)
|
||||
{
|
||||
int sixAxisSensorHandle = context.RequestData.ReadInt32();
|
||||
|
||||
// 4 byte struct w/ 4-byte alignment
|
||||
|
||||
// uint typeValue = (uint) sixAxisSensorHandle; // 0x0 0x4 TypeValue
|
||||
// uint npadStyleIndex = (uint) sixAxisSensorHandle & 0xff; // 0x0 0x1 NpadStyleIndex
|
||||
int playerNumber = (sixAxisSensorHandle << 8) & 0xff; // 0x1 0x1 PlayerNumber
|
||||
// uint deviceIdx= ((uint) sixAxisSensorHandle << 16) & 0xff; // 0x2 0x1 DeviceIdx
|
||||
// uint unknown = ((uint) sixAxisSensorHandle << 24) & 0xff;
|
||||
|
||||
// 32bit sign extension padding -> if = 0, + offset, else - offset
|
||||
|
||||
// npadStyleIndex = ((npadStyleIndex & 0x8000) == 0) ? npadStyleIndex | 0xFFFF0000 : npadStyleIndex & 0xFFFF0000;
|
||||
// playerNumber = ((playerNumber & 0x8000) == 0) ? playerNumber | 0xFFFF0000 : playerNumber & 0xFFFF0000;
|
||||
// deviceIdx = ((deviceIdx & 0x8000) == 0) ? deviceIdx | 0xFFFF0000 : deviceIdx & 0xFFFF0000;
|
||||
// unknown = ((unknown & 0x8000) == 0) ? unknown | 0xFFFF0000 : unknown & 0xFFFF0000;
|
||||
|
||||
context.RequestData.BaseStream.Position += 4; // Padding
|
||||
long appletResourceUserId = context.RequestData.ReadInt64();
|
||||
|
||||
bool isAtRest = true;
|
||||
|
||||
context.ResponseData.Write(isAtRest);
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, isAtRest });
|
||||
|
||||
|
||||
// TODO: link to context.Device.Hid.Npads.SixAxisActive when properly implemented
|
||||
// We currently do not support stopping or starting SixAxisTracking.
|
||||
|
||||
context.ResponseData.Write(context.Device.Hid.Npads.isAtRest(playerNumber));
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
@@ -629,7 +643,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
context.ResponseData.Write(_isFirmwareUpdateAvailableForSixAxisSensor);
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _isFirmwareUpdateAvailableForSixAxisSensor });
|
||||
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ using Ryujinx.HLE.Loaders.Executables;
|
||||
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Path = System.IO.Path;
|
||||
|
||||
@@ -28,15 +27,10 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
|
||||
private ulong _latestPid;
|
||||
|
||||
public ProcessResult? ActiveApplication
|
||||
public ProcessResult ActiveApplication
|
||||
{
|
||||
get
|
||||
{
|
||||
return _processesByPid.GetValueOrDefault(_latestPid);
|
||||
|
||||
// Using this if statement locks up the UI and prevents a new game from loading.
|
||||
// Haven't quite deduced why yet.
|
||||
|
||||
if (!_processesByPid.TryGetValue(_latestPid, out ProcessResult value))
|
||||
throw new RyujinxException(
|
||||
$"The HLE Process map did not have a process with ID {_latestPid}. Are you missing firmware?");
|
||||
@@ -150,7 +144,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
public bool LoadUnpackedNca(string exeFsDirPath, string romFsPath = null)
|
||||
{
|
||||
ProcessResult processResult = new LocalFileSystem(exeFsDirPath).Load(_device, romFsPath);
|
||||
|
||||
|
||||
if (processResult.ProcessId != 0 && _processesByPid.TryAdd(processResult.ProcessId, processResult))
|
||||
{
|
||||
if (processResult.Start(_device))
|
||||
|
||||
@@ -4,6 +4,7 @@ using LibHac.Ns;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Cpu;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
||||
using Ryujinx.Horizon.Common;
|
||||
|
||||
namespace Ryujinx.HLE.Loaders.Processes
|
||||
@@ -51,7 +52,6 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
|
||||
if (metaLoader is not null)
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Application,$"metaLoader: {metaLoader}");
|
||||
ulong programId = metaLoader.ProgramId;
|
||||
|
||||
Name = ApplicationControlProperties.Title[(int)titleLanguage].NameString.ToString();
|
||||
@@ -71,15 +71,8 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
ProgramId = programId;
|
||||
ProgramIdText = $"{programId:x16}";
|
||||
Is64Bit = metaLoader.IsProgram64Bit;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application,$"metaLoader is null !!!");
|
||||
ProcessId = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DiskCacheEnabled = diskCacheEnabled;
|
||||
AllowCodeMemoryForJit = allowCodeMemoryForJit;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
|
||||
|
||||
namespace Ryujinx.Ava.Systems
|
||||
{
|
||||
internal class AppHost : IDisposable
|
||||
internal class AppHost
|
||||
{
|
||||
private const int CursorHideIdleTime = 5; // Hide Cursor seconds.
|
||||
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
||||
@@ -438,7 +438,7 @@ namespace Ryujinx.Ava.Systems
|
||||
|
||||
SaveBitmapAsPng(bitmapToSave, path);
|
||||
|
||||
Logger.Notice.Print(LogClass.Application, $"Screenshot saved to '{path}'.", "Screenshot");
|
||||
Logger.Notice.Print(LogClass.Application, $"Screenshot saved to {path}", "Screenshot");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -611,40 +611,27 @@ namespace Ryujinx.Ava.Systems
|
||||
|
||||
_isActive = false;
|
||||
|
||||
// NOTE: The render loop is allowed to stay alive until the renderer itself is disposed, as it may handle resource dispose.
|
||||
// We only need to wait for all commands submitted during the main gpu loop to be processed.
|
||||
_gpuDoneEvent.WaitOne();
|
||||
_gpuDoneEvent.Dispose();
|
||||
|
||||
DisplaySleep.Restore();
|
||||
|
||||
NpadManager.Dispose();
|
||||
TouchScreenManager.Dispose();
|
||||
Device.Dispose();
|
||||
|
||||
// NOTE: The render loop is allowed to stay alive until the renderer itself is disposed, as it may handle resource dispose.
|
||||
// We only need to wait for all commands submitted during the main gpu loop to be processed.
|
||||
// If the GPU has no work and is cancelled, we need to handle that as well.
|
||||
|
||||
WaitHandle.WaitAny(new[] { _gpuDoneEvent, _gpuCancellationTokenSource.Token.WaitHandle });
|
||||
_gpuCancellationTokenSource.Dispose();
|
||||
|
||||
// Waiting for work to be finished before we dispose.
|
||||
if (_renderingStarted)
|
||||
{
|
||||
Device.Gpu.WaitUntilGpuReady();
|
||||
}
|
||||
|
||||
_gpuDoneEvent.Dispose();
|
||||
|
||||
DisposeGpu();
|
||||
|
||||
AppExit?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
// MUST be public to inherit from IDisposable
|
||||
public void Dispose()
|
||||
private void Dispose()
|
||||
{
|
||||
if (Device.Processes != null)
|
||||
{
|
||||
MainWindowViewModel.UpdateGameMetadata(Device.Processes.ActiveApplication?.ProgramIdText,
|
||||
_playTimer.Elapsed);
|
||||
}
|
||||
|
||||
MainWindowViewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText, _playTimer.Elapsed);
|
||||
|
||||
ConfigurationState.Instance.System.IgnoreMissingServices.Event -= UpdateIgnoreMissingServicesState;
|
||||
ConfigurationState.Instance.Graphics.AspectRatio.Event -= UpdateAspectRatioState;
|
||||
ConfigurationState.Instance.System.EnableDockedMode.Event -= UpdateDockedModeState;
|
||||
@@ -659,6 +646,7 @@ namespace Ryujinx.Ava.Systems
|
||||
_topLevel.PointerExited -= TopLevel_PointerExited;
|
||||
|
||||
_gpuCancellationTokenSource.Cancel();
|
||||
_gpuCancellationTokenSource.Dispose();
|
||||
|
||||
_chrono.Stop();
|
||||
_playTimer.Stop();
|
||||
@@ -684,12 +672,6 @@ namespace Ryujinx.Ava.Systems
|
||||
}
|
||||
else
|
||||
{
|
||||
// No use waiting on something that never started work
|
||||
if (_renderingStarted)
|
||||
{
|
||||
Device.Gpu.WaitUntilGpuReady();
|
||||
}
|
||||
|
||||
Device.DisposeGpu();
|
||||
}
|
||||
}
|
||||
@@ -704,7 +686,7 @@ namespace Ryujinx.Ava.Systems
|
||||
_cursorState = CursorStates.ForceChangeCursor;
|
||||
}
|
||||
|
||||
public async Task LoadGuestApplication(CancellationTokenSource cts, BlitStruct<ApplicationControlProperty>? customNacpData = null)
|
||||
public async Task<bool> LoadGuestApplication(BlitStruct<ApplicationControlProperty>? customNacpData = null)
|
||||
{
|
||||
DiscordIntegrationModule.GuestAppStartedAt = Timestamps.Now;
|
||||
|
||||
@@ -733,8 +715,7 @@ namespace Ryujinx.Ava.Systems
|
||||
await UserErrorDialog.ShowUserErrorDialog(userError);
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,11 +724,10 @@ namespace Ryujinx.Ava.Systems
|
||||
await UserErrorDialog.ShowUserErrorDialog(userError);
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Tell the user that we installed firmware for them.
|
||||
// Tell the user that we installed a firmware for them.
|
||||
if (userError is UserError.NoFirmware)
|
||||
{
|
||||
firmwareVersion = ContentManager.GetCurrentFirmwareVersion();
|
||||
@@ -767,8 +747,7 @@ namespace Ryujinx.Ava.Systems
|
||||
await UserErrorDialog.ShowUserErrorDialog(userError);
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -783,8 +762,7 @@ namespace Ryujinx.Ava.Systems
|
||||
{
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (Directory.Exists(ApplicationPath))
|
||||
@@ -804,24 +782,20 @@ namespace Ryujinx.Ava.Systems
|
||||
|
||||
if (!Device.LoadCart(ApplicationPath, romFsFiles[0]))
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(
|
||||
"Please specify an unpacked game directory with a valid exefs or NSO/NRO.");
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Application, "Loading as cart WITHOUT RomFS.");
|
||||
|
||||
if (!Device.LoadCart(ApplicationPath))
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(
|
||||
"Please specify an unpacked game directory with a valid exefs or NSO/NRO.");
|
||||
Device.Dispose();
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -839,8 +813,7 @@ namespace Ryujinx.Ava.Systems
|
||||
{
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -853,8 +826,7 @@ namespace Ryujinx.Ava.Systems
|
||||
{
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -868,8 +840,7 @@ namespace Ryujinx.Ava.Systems
|
||||
{
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -884,8 +855,7 @@ namespace Ryujinx.Ava.Systems
|
||||
{
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
@@ -894,8 +864,7 @@ namespace Ryujinx.Ava.Systems
|
||||
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -904,18 +873,19 @@ namespace Ryujinx.Ava.Systems
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Application, "Please specify a valid XCI/NCA/NSP/PFS0/NSO/NRO file.");
|
||||
Logger.Warning?.Print(LogClass.Application, "Please specify a valid XCI/NCA/NSP/PFS0/NRO file.");
|
||||
|
||||
Device.Dispose();
|
||||
|
||||
cts.Cancel();
|
||||
throw new OperationCanceledException(cts.Token);
|
||||
return false;
|
||||
}
|
||||
|
||||
ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText,
|
||||
appMetadata => appMetadata.UpdatePreGame()
|
||||
);
|
||||
_playTimer.Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void Resume()
|
||||
@@ -925,7 +895,7 @@ namespace Ryujinx.Ava.Systems
|
||||
_viewModel.IsPaused = false;
|
||||
_playTimer.Start();
|
||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI);
|
||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed.");
|
||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed");
|
||||
}
|
||||
|
||||
internal void Pause()
|
||||
@@ -935,7 +905,7 @@ namespace Ryujinx.Ava.Systems
|
||||
_viewModel.IsPaused = true;
|
||||
_playTimer.Stop();
|
||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI, LocaleManager.Instance[LocaleKeys.Paused]);
|
||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused.");
|
||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused");
|
||||
}
|
||||
|
||||
private void InitEmulatedSwitch()
|
||||
@@ -1134,9 +1104,7 @@ namespace Ryujinx.Ava.Systems
|
||||
// Make sure all commands in the run loop are fully executed before leaving the loop.
|
||||
if (Device.Gpu.Renderer is ThreadedRenderer threaded)
|
||||
{
|
||||
Logger.Info?.PrintMsg(LogClass.Gpu, "Flushing threaded commands...");
|
||||
threaded.FlushThreadedCommands();
|
||||
Logger.Info?.PrintMsg(LogClass.Gpu, "Flushed!");
|
||||
}
|
||||
|
||||
_gpuDoneEvent.Set();
|
||||
|
||||
@@ -849,8 +849,7 @@ namespace Ryujinx.Ava.Systems.AppLibrary
|
||||
|
||||
foreach (ApplicationData installedApplication in Applications.Items)
|
||||
{
|
||||
// this should always exist... should...
|
||||
temporary += LoadAndSaveMetaData(installedApplication.IdString).Value.TimePlayed;
|
||||
temporary += LoadAndSaveMetaData(installedApplication.IdString).TimePlayed;
|
||||
}
|
||||
|
||||
TotalTimePlayed = temporary;
|
||||
@@ -1160,22 +1159,15 @@ namespace Ryujinx.Ava.Systems.AppLibrary
|
||||
ApplicationCountUpdated?.Invoke(null, e);
|
||||
}
|
||||
|
||||
public static Gommon.Optional<ApplicationMetadata> LoadAndSaveMetaData(string titleId, Action<ApplicationMetadata> modifyFunction = null)
|
||||
public static ApplicationMetadata LoadAndSaveMetaData(string titleId, Action<ApplicationMetadata> modifyFunction = null)
|
||||
{
|
||||
if (titleId is null)
|
||||
{
|
||||
Logger.Warning?.PrintMsg(LogClass.Application, "Cannot save metadata because title ID is invalid.");
|
||||
return null;
|
||||
}
|
||||
|
||||
string metadataFolder = Path.Combine(AppDataManager.GamesDirPath, titleId, "gui");
|
||||
string metadataFile = Path.Combine(metadataFolder, "metadata.json");
|
||||
|
||||
ApplicationMetadata appMetadata;
|
||||
|
||||
|
||||
if (!File.Exists(metadataFile))
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Application, $"Metadata file does not exist. Creating metadata for {titleId}...");
|
||||
Directory.CreateDirectory(metadataFolder);
|
||||
|
||||
appMetadata = new ApplicationMetadata();
|
||||
@@ -1185,12 +1177,12 @@ namespace Ryujinx.Ava.Systems.AppLibrary
|
||||
|
||||
try
|
||||
{
|
||||
Logger.Debug?.Print(LogClass.Application, $"Deserializing metadata for {titleId}...");
|
||||
appMetadata = JsonHelper.DeserializeFromFile(metadataFile, _serializerContext.ApplicationMetadata);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Application, $"Failed to parse metadata json for {titleId}. Loading defaults.");
|
||||
|
||||
appMetadata = new ApplicationMetadata();
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace Ryujinx.Ava.Systems
|
||||
|
||||
public static void Use(Optional<string> titleId)
|
||||
{
|
||||
if (titleId.TryGet(out string tid) && Switch.Shared.Processes.ActiveApplication is not null)
|
||||
if (titleId.TryGet(out string tid))
|
||||
SwitchToPlayingState(
|
||||
ApplicationLibrary.LoadAndSaveMetaData(tid),
|
||||
Switch.Shared.Processes.ActiveApplication
|
||||
|
||||
@@ -57,15 +57,8 @@ namespace Ryujinx.Ava.UI.Models
|
||||
}
|
||||
else
|
||||
{
|
||||
Gommon.Optional<ApplicationMetadata> appMetadata = ApplicationLibrary.LoadAndSaveMetaData(TitleIdString);
|
||||
if (appMetadata != null)
|
||||
{
|
||||
Title = appMetadata.Value.Title ?? TitleIdString;
|
||||
}
|
||||
else
|
||||
{
|
||||
Title = "<INVALID>";
|
||||
}
|
||||
ApplicationMetadata appMetadata = ApplicationLibrary.LoadAndSaveMetaData(TitleIdString);
|
||||
Title = appMetadata.Title ?? TitleIdString;
|
||||
}
|
||||
|
||||
Task.Run(() =>
|
||||
|
||||
@@ -1062,7 +1062,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
string dialogMessage =
|
||||
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallMessage);
|
||||
|
||||
if (ContentManager.AreKeysAlreadyPresent(systemDirectory))
|
||||
if (ContentManager.AreKeysAlredyPresent(systemDirectory))
|
||||
{
|
||||
dialogMessage +=
|
||||
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys
|
||||
@@ -1736,6 +1736,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
Logger.RestartTime();
|
||||
|
||||
SelectedIcon ??= ApplicationLibrary.GetApplicationIcon(application.Path,
|
||||
ConfigurationState.Instance.System.Language, application.Id);
|
||||
|
||||
PrepareLoadScreen();
|
||||
|
||||
RendererHostControl = new RendererHost();
|
||||
|
||||
AppHost = new AppHost(
|
||||
@@ -1749,34 +1754,18 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
UserChannelPersistence,
|
||||
this,
|
||||
TopLevel);
|
||||
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
|
||||
try
|
||||
if (!await AppHost.LoadGuestApplication(customNacpData))
|
||||
{
|
||||
await AppHost.LoadGuestApplication(cts, customNacpData);
|
||||
}
|
||||
catch (OperationCanceledException exception)
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Application,
|
||||
"LoadGuestApplication was interrupted !!! " + exception.Message);
|
||||
AppHost.DisposeContext();
|
||||
AppHost = null;
|
||||
|
||||
return;
|
||||
}
|
||||
finally
|
||||
{
|
||||
cts.Dispose();
|
||||
}
|
||||
|
||||
|
||||
CanUpdate = false;
|
||||
|
||||
application.Name ??= AppHost.Device.Processes.ActiveApplication.Name;
|
||||
|
||||
SelectedIcon ??= ApplicationLibrary.GetApplicationIcon(application.Path,
|
||||
ConfigurationState.Instance.System.Language, application.Id);
|
||||
|
||||
PrepareLoadScreen();
|
||||
|
||||
LoadHeading = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.LoadingHeading, application.Name);
|
||||
|
||||
@@ -1798,9 +1787,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
RendererHostControl.Focus();
|
||||
});
|
||||
|
||||
public static void UpdateGameMetadata(string titleId, TimeSpan playTime)
|
||||
public static void UpdateGameMetadata(string titleId, TimeSpan playTime)
|
||||
=> ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata => appMetadata.UpdatePostGame(playTime));
|
||||
|
||||
|
||||
public void RefreshFirmwareStatus()
|
||||
{
|
||||
SystemVersion version = null;
|
||||
|
||||
Reference in New Issue
Block a user