mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-25 14:39:15 +00:00
Compare commits
3 Commits
Canary-1.3
...
Canary-1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18226decf1 | ||
|
|
b2310823c9 | ||
|
|
b62c58c2fe |
@@ -110,7 +110,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
Profiler.Wait();
|
||||
Profiler.ClearEntries();
|
||||
|
||||
Logger.Info?.Print(LogClass.Ptc, $"Initializing Profiled Persistent Translation Cache (enabled: {enabled}).");
|
||||
Logger.Info?.Print(LogClass.Ptc, $"Initializing Profiled Persistent Translation Cache v{InternalVersion}\n\t\t (title: {titleIdText}, version: '{displayVersion}', selector: '{cacheSelector}', enabled: {enabled}).");
|
||||
|
||||
if (!enabled || string.IsNullOrEmpty(titleIdText) || titleIdText == TitleIdTextDefault)
|
||||
{
|
||||
@@ -129,8 +129,6 @@ namespace ARMeilleure.Translation.PTC
|
||||
DisplayVersion = !string.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault;
|
||||
_memoryMode = memoryMode;
|
||||
|
||||
Logger.Info?.Print(LogClass.Ptc, $"PPTC (v{InternalVersion}) Profile: {DisplayVersion}-{cacheSelector}");
|
||||
|
||||
string workPathActual = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", ActualDir);
|
||||
string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", BackupDir);
|
||||
|
||||
|
||||
@@ -118,7 +118,9 @@ namespace Ryujinx.HLE.HOS
|
||||
}
|
||||
}
|
||||
|
||||
DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize, _diskCacheSelector ?? "default");
|
||||
string cacheSelector = _diskCacheSelector ?? "default";
|
||||
|
||||
DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize, cacheSelector);
|
||||
|
||||
return processContext;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace Ryujinx.HLE.HOS
|
||||
public IpcMessage Response { get; }
|
||||
public BinaryReader RequestData { get; }
|
||||
public BinaryWriter ResponseData { get; }
|
||||
public ulong ClientProcessId => Request.HandleDesc is { HasPId: true } ? Request.HandleDesc.PId : Process.Pid;
|
||||
|
||||
public ServiceCtx(
|
||||
Switch device,
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
||||
// TODO: Account actually calls nn::arp::detail::IReader::GetApplicationControlProperty() with the current Pid and store the result (NACP file) internally.
|
||||
// But since we use LibHac and we load one Application at a time, it's not necessary.
|
||||
|
||||
context.ResponseData.Write((byte)context.Device.Processes.ActiveApplication.ApplicationControlProperties.UserAccountSwitchLock);
|
||||
context.ResponseData.Write((byte)context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties.UserAccountSwitchLock);
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAcc);
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService
|
||||
// OpenLibraryAppletSelfAccessor() -> object<nn::am::service::ILibraryAppletSelfAccessor>
|
||||
public ResultCode OpenLibraryAppletSelfAccessor(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new ILibraryAppletSelfAccessor(context));
|
||||
MakeObject(context, new ILibraryAppletSelfAccessor(context, _pid));
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
|
||||
{
|
||||
private readonly AppletStandalone _appletStandalone = new();
|
||||
|
||||
public ILibraryAppletSelfAccessor(ServiceCtx context)
|
||||
public ILibraryAppletSelfAccessor(ServiceCtx context, ulong pid)
|
||||
{
|
||||
if (context.Device.Processes.ActiveApplication.ProgramId == 0x0100000000001009)
|
||||
ulong programId = context.Device.Processes.GetProcess(pid).ProgramId;
|
||||
|
||||
if (programId == 0x0100000000001009)
|
||||
{
|
||||
// Create MiiEdit data.
|
||||
_appletStandalone = new AppletStandalone()
|
||||
@@ -26,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException($"{context.Device.Processes.ActiveApplication.ProgramId} applet is not implemented.");
|
||||
throw new NotImplementedException($"{programId} applet is not implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,9 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
||||
private int _jitLoaded;
|
||||
|
||||
private readonly LibHac.HorizonClient _horizon;
|
||||
private readonly ulong _pid;
|
||||
|
||||
public IApplicationFunctions(Horizon system)
|
||||
public IApplicationFunctions(Horizon system, ulong pid)
|
||||
{
|
||||
// TODO: Find where they are signaled.
|
||||
_gpuErrorDetectedSystemEvent = new KEvent(system.KernelContext);
|
||||
@@ -55,6 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
||||
_unknownEvent = new KEvent(system.KernelContext);
|
||||
|
||||
_horizon = system.LibHacHorizonManager.AmClient;
|
||||
_pid = pid;
|
||||
}
|
||||
|
||||
[CommandCmif(1)]
|
||||
@@ -115,11 +117,12 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
||||
public ResultCode EnsureSaveData(ServiceCtx context)
|
||||
{
|
||||
Uid userId = context.RequestData.ReadStruct<AccountUid>().ToLibHacUid();
|
||||
var process = context.Device.Processes.GetProcess(_pid);
|
||||
|
||||
// Mask out the low nibble of the program ID to get the application ID
|
||||
ApplicationId applicationId = new(context.Device.Processes.ActiveApplication.ProgramId & ~0xFul);
|
||||
ApplicationId applicationId = new(process.Identity.ApplicationId);
|
||||
|
||||
ApplicationControlProperty nacp = context.Device.Processes.ActiveApplication.ApplicationControlProperties;
|
||||
ApplicationControlProperty nacp = process.ApplicationControlProperties;
|
||||
|
||||
LibHac.HorizonClient hos = context.Device.System.LibHacHorizonManager.AmClient;
|
||||
LibHac.Result result = hos.Fs.EnsureApplicationSaveData(out long requiredSize, applicationId, in nacp, in userId);
|
||||
@@ -139,7 +142,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
||||
// TODO: When above calls are implemented, switch to using ns:am
|
||||
|
||||
long desiredLanguageCode = context.Device.System.State.DesiredLanguageCode;
|
||||
int supportedLanguages = (int)context.Device.Processes.ActiveApplication.ApplicationControlProperties.SupportedLanguageFlag;
|
||||
int supportedLanguages = (int)context.Device.Processes.GetProcess(_pid).ApplicationControlProperties.SupportedLanguageFlag;
|
||||
int firstSupported = BitOperations.TrailingZeroCount(supportedLanguages);
|
||||
|
||||
if (firstSupported > (int)TitleLanguage.BrazilianPortuguese)
|
||||
@@ -182,7 +185,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
||||
public ResultCode GetDisplayVersion(ServiceCtx context)
|
||||
{
|
||||
// If an NACP isn't found, the buffer will be all '\0' which seems to be the correct implementation.
|
||||
context.ResponseData.Write(context.Device.Processes.ActiveApplication.ApplicationControlProperties.DisplayVersion);
|
||||
context.ResponseData.Write(context.Device.Processes.GetProcess(_pid).ApplicationControlProperties.DisplayVersion);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
@@ -235,11 +238,12 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
||||
ushort index = (ushort)context.RequestData.ReadUInt64();
|
||||
long saveSize = context.RequestData.ReadInt64();
|
||||
long journalSize = context.RequestData.ReadInt64();
|
||||
var process = context.Device.Processes.GetProcess(_pid);
|
||||
|
||||
// Mask out the low nibble of the program ID to get the application ID
|
||||
ApplicationId applicationId = new(context.Device.Processes.ActiveApplication.ProgramId & ~0xFul);
|
||||
ApplicationId applicationId = new(process.Identity.ApplicationId);
|
||||
|
||||
ApplicationControlProperty nacp = context.Device.Processes.ActiveApplication.ApplicationControlProperties;
|
||||
ApplicationControlProperty nacp = process.ApplicationControlProperties;
|
||||
|
||||
LibHac.Result result = _horizon.Fs.CreateApplicationCacheStorage(out long requiredSize,
|
||||
out CacheStorageTargetMedia storageTarget, applicationId, in nacp, index, saveSize, journalSize);
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService
|
||||
// GetApplicationFunctions() -> object<nn::am::service::IApplicationFunctions>
|
||||
public ResultCode GetApplicationFunctions(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new IApplicationFunctions(context.Device.System));
|
||||
MakeObject(context, new IApplicationFunctions(context.Device.System, _pid));
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
@@ -27,13 +27,18 @@ namespace Ryujinx.HLE.HOS.Services.Arp
|
||||
}
|
||||
|
||||
public static ApplicationLaunchProperty GetByPid(ServiceCtx context)
|
||||
{
|
||||
return GetByPid(context, context.ClientProcessId);
|
||||
}
|
||||
|
||||
public static ApplicationLaunchProperty GetByPid(ServiceCtx context, ulong pid)
|
||||
{
|
||||
// TODO: Handle ApplicationLaunchProperty as array when pid will be supported and return the right item.
|
||||
// For now we can hardcode values, and fix it after GetApplicationLaunchProperty is implemented.
|
||||
|
||||
return new ApplicationLaunchProperty
|
||||
{
|
||||
TitleId = context.Device.Processes.ActiveApplication.ProgramId,
|
||||
TitleId = context.Device.Processes.GetProcess(pid).ProgramId,
|
||||
Version = 0x00,
|
||||
BaseGameStorageId = (byte)StorageId.BuiltInSystem,
|
||||
UpdateGameStorageId = (byte)StorageId.None,
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Ryujinx.HLE.HOS.Services.Caps
|
||||
|
||||
byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray();
|
||||
|
||||
ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.ActiveApplication.ProgramId, out ApplicationAlbumEntry applicationAlbumEntry);
|
||||
ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.GetProcess(context.ClientProcessId).ProgramId, out ApplicationAlbumEntry applicationAlbumEntry);
|
||||
|
||||
context.ResponseData.WriteStruct(applicationAlbumEntry);
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace Ryujinx.HLE.HOS.Services.Caps
|
||||
|
||||
byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray();
|
||||
|
||||
ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.ActiveApplication.ProgramId, out ApplicationAlbumEntry applicationAlbumEntry);
|
||||
ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.GetProcess(context.ClientProcessId).ProgramId, out ApplicationAlbumEntry applicationAlbumEntry);
|
||||
|
||||
context.ResponseData.WriteStruct(applicationAlbumEntry);
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace Ryujinx.HLE.HOS.Services.Caps
|
||||
|
||||
byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray();
|
||||
|
||||
ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.ActiveApplication.ProgramId, out ApplicationAlbumEntry applicationAlbumEntry);
|
||||
ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.GetProcess(context.ClientProcessId).ProgramId, out ApplicationAlbumEntry applicationAlbumEntry);
|
||||
|
||||
context.ResponseData.WriteStruct(applicationAlbumEntry);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Services.Fatal.Types;
|
||||
using Ryujinx.HLE.Loaders.Processes;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
@@ -50,12 +51,13 @@ namespace Ryujinx.HLE.HOS.Services.Fatal
|
||||
|
||||
private ResultCode ThrowFatalWithCpuContextImpl(ServiceCtx context, ResultCode resultCode, ulong pid, FatalPolicy fatalPolicy, ReadOnlySpan<byte> cpuContext)
|
||||
{
|
||||
ProcessResult process = context.Device.Processes.GetProcess(pid);
|
||||
StringBuilder errorReport = new();
|
||||
|
||||
errorReport.AppendLine();
|
||||
errorReport.AppendLine("ErrorReport log:");
|
||||
|
||||
errorReport.AppendLine($"\tTitleId: {context.Device.Processes.ActiveApplication.ProgramIdText}");
|
||||
errorReport.AppendLine($"\tTitleId: {process.ProgramIdText}");
|
||||
errorReport.AppendLine($"\tPid: {pid}");
|
||||
errorReport.AppendLine($"\tResultCode: {((int)resultCode & 0x1FF) + 2000}-{((int)resultCode >> 9) & 0x3FFF:d4}");
|
||||
errorReport.AppendLine($"\tFatalPolicy: {fatalPolicy}");
|
||||
@@ -64,7 +66,7 @@ namespace Ryujinx.HLE.HOS.Services.Fatal
|
||||
{
|
||||
errorReport.AppendLine("CPU Context:");
|
||||
|
||||
if (context.Device.Processes.ActiveApplication.Is64Bit)
|
||||
if (process.Is64Bit)
|
||||
{
|
||||
CpuContext64 cpuContext64 = MemoryMarshal.Cast<byte, CpuContext64>(cpuContext)[0];
|
||||
|
||||
|
||||
@@ -885,7 +885,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
||||
{
|
||||
byte programIndex = context.RequestData.ReadByte();
|
||||
|
||||
if ((context.Device.Processes.ActiveApplication.ProgramId & 0xf) != programIndex)
|
||||
if (context.Device.Processes.GetProcess(_pid).Identity.ProgramIndex != programIndex)
|
||||
{
|
||||
throw new NotImplementedException($"Accessing storage from other programs is not supported (program index = {programIndex}).");
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
private bool CheckLocalCommunicationIdPermission(ServiceCtx context, ulong localCommunicationIdChecked)
|
||||
{
|
||||
// TODO: Call nn::arp::GetApplicationControlProperty here when implemented.
|
||||
ApplicationControlProperty controlProperty = context.Device.Processes.ActiveApplication.ApplicationControlProperties;
|
||||
ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties;
|
||||
|
||||
foreach (ulong localCommunicationId in controlProperty.LocalCommunicationId)
|
||||
{
|
||||
@@ -438,7 +438,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
if (scanFilter.NetworkId.IntentId.LocalCommunicationId == -1 && NetworkClient.NeedsRealId)
|
||||
{
|
||||
// TODO: Call nn::arp::GetApplicationControlProperty here when implemented.
|
||||
ApplicationControlProperty controlProperty = context.Device.Processes.ActiveApplication.ApplicationControlProperties;
|
||||
ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties;
|
||||
|
||||
scanFilter.NetworkId.IntentId.LocalCommunicationId = (long)controlProperty.LocalCommunicationId[0];
|
||||
}
|
||||
@@ -613,7 +613,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
if (networkConfig.IntentId.LocalCommunicationId == -1 && NetworkClient.NeedsRealId)
|
||||
{
|
||||
// TODO: Call nn::arp::GetApplicationControlProperty here when implemented.
|
||||
ApplicationControlProperty controlProperty = context.Device.Processes.ActiveApplication.ApplicationControlProperties;
|
||||
ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties;
|
||||
|
||||
networkConfig.IntentId.LocalCommunicationId = (long)controlProperty.LocalCommunicationId[0];
|
||||
}
|
||||
@@ -948,7 +948,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
if (networkInfo.NetworkId.IntentId.LocalCommunicationId == -1 && NetworkClient.NeedsRealId)
|
||||
{
|
||||
// TODO: Call nn::arp::GetApplicationControlProperty here when implemented.
|
||||
ApplicationControlProperty controlProperty = context.Device.Processes.ActiveApplication.ApplicationControlProperties;
|
||||
ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties;
|
||||
|
||||
networkInfo.NetworkId.IntentId.LocalCommunicationId = (long)controlProperty.LocalCommunicationId[0];
|
||||
}
|
||||
@@ -1208,7 +1208,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
}
|
||||
|
||||
// TODO: Call nn::arp::GetApplicationLaunchProperty here when implemented.
|
||||
NetworkClient.SetGameVersion(context.Device.Processes.ActiveApplication.ApplicationControlProperties.DisplayVersion);
|
||||
NetworkClient.SetGameVersion(context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties.DisplayVersion);
|
||||
|
||||
resultCode = ResultCode.Success;
|
||||
_nifmResultCode = resultCode;
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
|
||||
|
||||
// NOTE: Service call arp:r GetApplicationLaunchProperty to get TitleId using the PId.
|
||||
|
||||
return CountAddOnContentImpl(context, context.Device.Processes.ActiveApplication.ProgramId);
|
||||
return CountAddOnContentImpl(context, context.Device.Processes.GetProcess(pid).ProgramId);
|
||||
}
|
||||
|
||||
[CommandCmif(3)]
|
||||
@@ -63,7 +63,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
|
||||
|
||||
// NOTE: Service call arp:r GetApplicationLaunchProperty to get TitleId using the PId.
|
||||
|
||||
return ListAddContentImpl(context, context.Device.Processes.ActiveApplication.ProgramId);
|
||||
return ListAddContentImpl(context, context.Device.Processes.GetProcess(pid).ProgramId);
|
||||
}
|
||||
|
||||
[CommandCmif(4)] // 1.0.0-6.2.0
|
||||
@@ -85,7 +85,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
|
||||
|
||||
// NOTE: Service call arp:r GetApplicationLaunchProperty to get TitleId using the PId.
|
||||
|
||||
return GetAddOnContentBaseIdImpl(context, context.Device.Processes.ActiveApplication.ProgramId);
|
||||
return GetAddOnContentBaseIdImpl(context, context.Device.Processes.GetProcess(pid).ProgramId);
|
||||
}
|
||||
|
||||
[CommandCmif(6)] // 1.0.0-6.2.0
|
||||
@@ -107,7 +107,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
|
||||
|
||||
// NOTE: Service call arp:r GetApplicationLaunchProperty to get TitleId using the PId.
|
||||
|
||||
return PrepareAddOnContentImpl(context, context.Device.Processes.ActiveApplication.ProgramId);
|
||||
return PrepareAddOnContentImpl(context, context.Device.Processes.GetProcess(pid).ProgramId);
|
||||
}
|
||||
|
||||
[CommandCmif(8)] // 4.0.0+
|
||||
@@ -138,7 +138,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
|
||||
// NOTE: Service call arp:r GetApplicationLaunchProperty to get TitleId using the PId.
|
||||
|
||||
// TODO: Found where stored value is used.
|
||||
ResultCode resultCode = GetAddOnContentBaseIdFromTitleId(context, context.Device.Processes.ActiveApplication.ProgramId);
|
||||
ResultCode resultCode = GetAddOnContentBaseIdFromTitleId(context, context.Device.Processes.GetProcess(pid).ProgramId);
|
||||
|
||||
if (resultCode != ResultCode.Success)
|
||||
{
|
||||
@@ -310,7 +310,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
|
||||
// NOTE: Service calls arp:r GetApplicationControlProperty to get AddOnContentBaseId using TitleId,
|
||||
// If the call fails, it returns ResultCode.InvalidPid.
|
||||
|
||||
_addOnContentBaseId = context.Device.Processes.ActiveApplication.ApplicationControlProperties.AddOnContentBaseId;
|
||||
_addOnContentBaseId = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties.AddOnContentBaseId;
|
||||
|
||||
if (_addOnContentBaseId == 0)
|
||||
{
|
||||
@@ -324,7 +324,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
|
||||
{
|
||||
uint index = context.RequestData.ReadUInt32();
|
||||
|
||||
ResultCode resultCode = GetAddOnContentBaseIdFromTitleId(context, context.Device.Processes.ActiveApplication.ProgramId);
|
||||
ResultCode resultCode = GetAddOnContentBaseIdFromTitleId(context, titleId);
|
||||
|
||||
if (resultCode != ResultCode.Success)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns
|
||||
|
||||
ulong position = context.Request.ReceiveBuff[0].Position;
|
||||
|
||||
ApplicationControlProperty nacp = context.Device.Processes.ActiveApplication.ApplicationControlProperties;
|
||||
ApplicationControlProperty nacp = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties;
|
||||
|
||||
context.Memory.Write(position, SpanHelpers.AsByteSpan(ref nacp).ToArray());
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns
|
||||
|
||||
ulong position = context.Request.ReceiveBuff[0].Position;
|
||||
|
||||
ApplicationControlProperty nacp = context.Device.Processes.ActiveApplication.ApplicationControlProperties;
|
||||
ApplicationControlProperty nacp = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties;
|
||||
|
||||
context.Memory.Write(position, SpanHelpers.AsByteSpan(ref nacp).ToArray());
|
||||
|
||||
|
||||
@@ -48,21 +48,22 @@ namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory
|
||||
{
|
||||
if ((_permissionFlag & 0x40) == 0)
|
||||
{
|
||||
ulong titleId = ApplicationLaunchProperty.GetByPid(context).TitleId;
|
||||
ulong titleId = ApplicationLaunchProperty.GetByPid(context, _pid).TitleId;
|
||||
|
||||
if (titleId != 0)
|
||||
{
|
||||
_titleId = titleId;
|
||||
var process = context.Device.Processes.GetProcess(_pid);
|
||||
|
||||
// TODO: Call nn::arp::GetApplicationControlProperty here when implemented, if it return ResultCode.Success we assign fields.
|
||||
_ratingAge = new int[context.Device.Processes.ActiveApplication.ApplicationControlProperties.RatingAge.Length];
|
||||
_ratingAge = new int[process.ApplicationControlProperties.RatingAge.Length];
|
||||
|
||||
for (int i = 0; i < _ratingAge.Length; i++)
|
||||
{
|
||||
_ratingAge[i] = Convert.ToInt32(context.Device.Processes.ActiveApplication.ApplicationControlProperties.RatingAge[i]);
|
||||
_ratingAge[i] = Convert.ToInt32(process.ApplicationControlProperties.RatingAge[i]);
|
||||
}
|
||||
|
||||
_parentalControlFlag = context.Device.Processes.ActiveApplication.ApplicationControlProperties.ParentalControlFlag;
|
||||
_parentalControlFlag = process.ApplicationControlProperties.ParentalControlFlag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using Ryujinx.Common;
|
||||
using Ryujinx.Cpu;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService.Types;
|
||||
using Ryujinx.HLE.Loaders.Processes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -31,7 +32,8 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService
|
||||
}
|
||||
}
|
||||
|
||||
PlayLogQueryCapability queryCapability = (PlayLogQueryCapability)context.Device.Processes.ActiveApplication.ApplicationControlProperties.PlayLogQueryCapability;
|
||||
ProcessResult process = context.Device.Processes.GetProcess(context.ClientProcessId);
|
||||
PlayLogQueryCapability queryCapability = (PlayLogQueryCapability)process.ApplicationControlProperties.PlayLogQueryCapability;
|
||||
|
||||
List<ulong> titleIds = [];
|
||||
|
||||
@@ -45,7 +47,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService
|
||||
// Check if input title ids are in the whitelist.
|
||||
foreach (ulong titleId in titleIds)
|
||||
{
|
||||
if (!context.Device.Processes.ActiveApplication.ApplicationControlProperties.PlayLogQueryableApplicationId.AsReadOnlySpan().Contains(titleId))
|
||||
if (!process.ApplicationControlProperties.PlayLogQueryableApplicationId.AsReadOnlySpan().Contains(titleId))
|
||||
{
|
||||
return (ResultCode)Am.ResultCode.ObjectInvalid;
|
||||
}
|
||||
|
||||
34
src/Ryujinx.HLE/Loaders/Processes/ProcessIdentity.cs
Normal file
34
src/Ryujinx.HLE/Loaders/Processes/ProcessIdentity.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace Ryujinx.HLE.Loaders.Processes
|
||||
{
|
||||
public readonly struct ProcessIdentity
|
||||
{
|
||||
public ulong ProcessId { get; }
|
||||
public ulong ProgramId { get; }
|
||||
public ulong ApplicationId { get; }
|
||||
public byte ProgramIndex { get; }
|
||||
public string ProgramIdText { get; }
|
||||
public string DisplayVersion { get; }
|
||||
public ProcessKind Kind { get; }
|
||||
|
||||
public ProcessIdentity(
|
||||
ulong processId,
|
||||
ulong programId,
|
||||
byte programIndex,
|
||||
string displayVersion,
|
||||
ProcessKind kind)
|
||||
{
|
||||
ProcessId = processId;
|
||||
ProgramId = programId;
|
||||
ProgramIndex = programIndex;
|
||||
ApplicationId = programId & ~0xFul;
|
||||
ProgramIdText = $"{programId:x16}";
|
||||
DisplayVersion = displayVersion ?? string.Empty;
|
||||
Kind = kind;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Kind} pid={ProcessId} program={ProgramIdText} application={ApplicationId:x16} index={ProgramIndex} version={DisplayVersion}";
|
||||
}
|
||||
}
|
||||
}
|
||||
12
src/Ryujinx.HLE/Loaders/Processes/ProcessKind.cs
Normal file
12
src/Ryujinx.HLE/Loaders/Processes/ProcessKind.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Ryujinx.HLE.Loaders.Processes
|
||||
{
|
||||
public enum ProcessKind
|
||||
{
|
||||
Unknown,
|
||||
Application,
|
||||
SystemApplication,
|
||||
SystemApplet,
|
||||
LibraryApplet,
|
||||
Homebrew,
|
||||
}
|
||||
}
|
||||
@@ -93,6 +93,23 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
_processesByPid = new ConcurrentDictionary<ulong, ProcessResult>();
|
||||
}
|
||||
|
||||
public bool TryGetProcess(ulong pid, out ProcessResult process)
|
||||
{
|
||||
return _processesByPid.TryGetValue(pid, out process);
|
||||
}
|
||||
|
||||
public ProcessResult GetProcess(ulong pid)
|
||||
{
|
||||
if (_processesByPid.TryGetValue(pid, out ProcessResult process))
|
||||
{
|
||||
return process;
|
||||
}
|
||||
|
||||
Logger.Warning?.Print(LogClass.Loader, $"Process metadata for pid {pid} was not found. Falling back to active application metadata.");
|
||||
|
||||
return ActiveApplication;
|
||||
}
|
||||
|
||||
public bool LoadXci(string path, ulong applicationId)
|
||||
{
|
||||
FileStream stream = new(path, FileMode.Open, FileAccess.Read);
|
||||
|
||||
@@ -436,6 +436,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
allowCodeMemoryForJit,
|
||||
processContextFactory.DiskCacheLoadState,
|
||||
process.Pid,
|
||||
programIndex,
|
||||
meta.MainThreadPriority,
|
||||
meta.MainThreadStackSize,
|
||||
device.System.State.DesiredTitleLanguage);
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
{
|
||||
public class ProcessResult
|
||||
{
|
||||
public static ProcessResult Failed => new(null, new BlitStruct<ApplicationControlProperty>(1), false, false, null, 0, 0, 0, TitleLanguage.AmericanEnglish);
|
||||
public static ProcessResult Failed => new(null, new BlitStruct<ApplicationControlProperty>(1), false, false, null, 0, 0, 0, 0, TitleLanguage.AmericanEnglish);
|
||||
|
||||
private readonly byte _mainThreadPriority;
|
||||
private readonly uint _mainThreadStackSize;
|
||||
@@ -28,6 +28,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
public readonly bool Is64Bit;
|
||||
public readonly bool DiskCacheEnabled;
|
||||
public readonly bool AllowCodeMemoryForJit;
|
||||
public readonly ProcessIdentity Identity;
|
||||
|
||||
public ProcessResult(
|
||||
MetaLoader metaLoader,
|
||||
@@ -36,6 +37,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
bool allowCodeMemoryForJit,
|
||||
IDiskCacheLoadState diskCacheLoadState,
|
||||
ulong pid,
|
||||
byte programIndex,
|
||||
byte mainThreadPriority,
|
||||
uint mainThreadStackSize,
|
||||
TitleLanguage titleLanguage)
|
||||
@@ -71,6 +73,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
ProgramId = programId;
|
||||
ProgramIdText = $"{programId:x16}";
|
||||
Is64Bit = metaLoader.IsProgram64Bit;
|
||||
Identity = new ProcessIdentity(pid, programId, programIndex, DisplayVersion, GetProcessKind(programId));
|
||||
}
|
||||
|
||||
else
|
||||
@@ -84,6 +87,31 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
AllowCodeMemoryForJit = allowCodeMemoryForJit;
|
||||
}
|
||||
|
||||
private static ProcessKind GetProcessKind(ulong programId)
|
||||
{
|
||||
if (programId == 0)
|
||||
{
|
||||
return ProcessKind.Application;
|
||||
}
|
||||
|
||||
if (programId is >= 0x0100000000001000 and <= 0x0100000000001FFF)
|
||||
{
|
||||
return ProcessKind.SystemApplet;
|
||||
}
|
||||
|
||||
if (programId is >= 0x0100000000000800 and <= 0x0100000000000FFF)
|
||||
{
|
||||
return ProcessKind.LibraryApplet;
|
||||
}
|
||||
|
||||
if (programId <= 0x0100000000007FFF)
|
||||
{
|
||||
return ProcessKind.SystemApplication;
|
||||
}
|
||||
|
||||
return ProcessKind.Application;
|
||||
}
|
||||
|
||||
public bool Start(Switch device)
|
||||
{
|
||||
device.Configuration.ContentManager.LoadEntries(device);
|
||||
@@ -109,6 +137,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
: device.System.ContentManager.GetCurrentFirmwareVersion()?.VersionString ?? "?";
|
||||
|
||||
Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {name} v{version} [{ProgramIdText}] [{(Is64Bit ? "64-bit" : "32-bit")}]");
|
||||
Logger.Info?.Print(LogClass.Loader, $"Process identity: {Identity}");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,18 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NativeRect
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
|
||||
public int Width => Right - Left;
|
||||
public int Height => Bottom - Top;
|
||||
}
|
||||
|
||||
public static nint CreateEmptyCursor()
|
||||
{
|
||||
return CreateCursor(nint.Zero, 0, 0, 1, 1, [0xFF], [0x00]);
|
||||
@@ -119,6 +131,10 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
[LibraryImport("user32.dll", SetLastError = true)]
|
||||
public static partial nint SetWindowLongPtrW(nint hWnd, int nIndex, nint value);
|
||||
|
||||
[LibraryImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static partial bool GetWindowRect(nint hWnd, out NativeRect lpRect);
|
||||
|
||||
[LibraryImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static partial bool SetWindowPos(
|
||||
|
||||
@@ -2060,6 +2060,12 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
|
||||
private nint _savedWindowStyle;
|
||||
private WindowState _savedWindowState;
|
||||
private PixelPoint _savedWindowPosition;
|
||||
private double _savedWindowWidth;
|
||||
private double _savedWindowHeight;
|
||||
private Win32NativeInterop.NativeRect _savedWindowRect;
|
||||
private bool _savedWindowRectValid;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private void MakeWindowFullscreen()
|
||||
@@ -2067,19 +2073,36 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
nint hwnd = Window.TryGetPlatformHandle()?.Handle ?? nint.Zero;
|
||||
if (hwnd == nint.Zero) return;
|
||||
|
||||
PixelPoint windowCenter = new(
|
||||
Window.Position.X + (int)(Window.Bounds.Width / 2),
|
||||
Window.Position.Y + (int)(Window.Bounds.Height / 2));
|
||||
|
||||
Avalonia.Platform.Screen? screen =
|
||||
Window.Screens.ScreenFromVisual(Window) ??
|
||||
Window.Screens.ScreenFromPoint(windowCenter) ??
|
||||
Window.Screens.Primary;
|
||||
|
||||
if (screen == null)
|
||||
{
|
||||
return; // Can't determine screen size, don't attempt fullscreen
|
||||
}
|
||||
|
||||
// Save current style and placement
|
||||
_savedWindowStyle = Win32NativeInterop.GetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE);
|
||||
_savedWindowState = WindowState;
|
||||
_savedWindowPosition = Window.Position;
|
||||
_savedWindowWidth = Window.Width;
|
||||
_savedWindowHeight = Window.Height;
|
||||
_savedWindowRectValid = Win32NativeInterop.GetWindowRect(hwnd, out _savedWindowRect);
|
||||
|
||||
// Remove window chrome: WS_OVERLAPPEDWINDOW -> WS_POPUP | WS_VISIBLE
|
||||
Win32NativeInterop.SetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE,
|
||||
unchecked((nint)(Win32NativeInterop.WS_POPUP | Win32NativeInterop.WS_VISIBLE)));
|
||||
|
||||
// TODO: why is this nullable
|
||||
Avalonia.Platform.Screen? screen = Window.Screens.ScreenFromVisual(Window);
|
||||
int w = screen?.Bounds.Width ?? 0;
|
||||
int h = screen?.Bounds.Height ?? 0;
|
||||
|
||||
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, 0, 0, w, h,
|
||||
int w = screen.Bounds.Width;
|
||||
int h = screen.Bounds.Height;
|
||||
|
||||
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, screen.Bounds.X, screen.Bounds.Y, w, h,
|
||||
Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE | Win32NativeInterop.SWP_FRAMECHANGED);
|
||||
|
||||
WindowState = WindowState.FullScreen;
|
||||
@@ -2094,10 +2117,34 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
// Restore original window style
|
||||
Win32NativeInterop.SetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE, _savedWindowStyle);
|
||||
|
||||
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, 0, 0, 0, 0,
|
||||
Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE |
|
||||
Win32NativeInterop.SWP_FRAMECHANGED | Win32NativeInterop.SWP_NOMOVE | Win32NativeInterop.SWP_NOSIZE);
|
||||
if (_savedWindowState is WindowState.Maximized)
|
||||
{
|
||||
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, 0, 0, 0, 0,
|
||||
Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE |
|
||||
Win32NativeInterop.SWP_FRAMECHANGED | Win32NativeInterop.SWP_NOMOVE | Win32NativeInterop.SWP_NOSIZE);
|
||||
}
|
||||
else if (_savedWindowRectValid)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() => RestoreSavedWindowRect(hwnd), DispatcherPriority.Background);
|
||||
}
|
||||
else
|
||||
{
|
||||
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, 0, 0, 0, 0,
|
||||
Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE |
|
||||
Win32NativeInterop.SWP_FRAMECHANGED | Win32NativeInterop.SWP_NOMOVE | Win32NativeInterop.SWP_NOSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private void RestoreSavedWindowRect(nint hwnd)
|
||||
{
|
||||
Window.Position = _savedWindowPosition;
|
||||
Window.Width = _savedWindowWidth;
|
||||
Window.Height = _savedWindowHeight;
|
||||
|
||||
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, _savedWindowRect.Left, _savedWindowRect.Top,
|
||||
_savedWindowRect.Width, _savedWindowRect.Height,
|
||||
Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE | Win32NativeInterop.SWP_FRAMECHANGED);
|
||||
}
|
||||
|
||||
public static void SaveConfig()
|
||||
|
||||
@@ -48,6 +48,8 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
private bool _isLoading;
|
||||
private bool _applicationsLoadedOnce;
|
||||
private double _windowStartupWidthDelta;
|
||||
private double _windowStartupHeightDelta;
|
||||
|
||||
private UserChannelPersistence _userChannelPersistence;
|
||||
private static bool _deferLoad;
|
||||
@@ -477,8 +479,8 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
// Since scaling is being applied to the loaded settings from disk (see SetWindowSizePosition() above), scaling should be removed from width/height before saving out to disk
|
||||
// as well - otherwise anyone not using a 1.0 scale factor their window will increase in size with every subsequent launch of the program when scaling is applied (Nov. 14, 2024)
|
||||
ConfigurationState.Instance.UI.WindowStartup.WindowSizeHeight.Value = (int)(Height / Program.WindowScaleFactor);
|
||||
ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth.Value = (int)(Width / Program.WindowScaleFactor);
|
||||
ConfigurationState.Instance.UI.WindowStartup.WindowSizeHeight.Value = (int)((Height - _windowStartupHeightDelta) / Program.WindowScaleFactor);
|
||||
ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth.Value = (int)((Width - _windowStartupWidthDelta) / Program.WindowScaleFactor);
|
||||
|
||||
ConfigurationState.Instance.UI.WindowStartup.WindowPositionX.Value = Position.X;
|
||||
ConfigurationState.Instance.UI.WindowStartup.WindowPositionY.Value = Position.Y;
|
||||
@@ -493,6 +495,9 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
Initialize();
|
||||
|
||||
_windowStartupWidthDelta = Math.Max(0, Width - ViewModel.WindowWidth);
|
||||
_windowStartupHeightDelta = Math.Max(0, Height - ViewModel.WindowHeight);
|
||||
|
||||
PlatformSettings!.ColorValuesChanged += OnPlatformColorValuesChanged;
|
||||
|
||||
ViewModel.Initialize(
|
||||
|
||||
Reference in New Issue
Block a user