mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-28 16:09:15 +00:00
Compare commits
2 Commits
Canary-1.3
...
Canary-1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2310823c9 | ||
|
|
b62c58c2fe |
@@ -110,7 +110,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
Profiler.Wait();
|
Profiler.Wait();
|
||||||
Profiler.ClearEntries();
|
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)
|
if (!enabled || string.IsNullOrEmpty(titleIdText) || titleIdText == TitleIdTextDefault)
|
||||||
{
|
{
|
||||||
@@ -129,8 +129,6 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
DisplayVersion = !string.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault;
|
DisplayVersion = !string.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault;
|
||||||
_memoryMode = memoryMode;
|
_memoryMode = memoryMode;
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Ptc, $"PPTC (v{InternalVersion}) Profile: {DisplayVersion}-{cacheSelector}");
|
|
||||||
|
|
||||||
string workPathActual = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", ActualDir);
|
string workPathActual = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", ActualDir);
|
||||||
string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", BackupDir);
|
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;
|
return processContext;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
public IpcMessage Response { get; }
|
public IpcMessage Response { get; }
|
||||||
public BinaryReader RequestData { get; }
|
public BinaryReader RequestData { get; }
|
||||||
public BinaryWriter ResponseData { get; }
|
public BinaryWriter ResponseData { get; }
|
||||||
|
public ulong ClientProcessId => Request.HandleDesc.HasPId ? Request.HandleDesc.PId : Process.Pid;
|
||||||
|
|
||||||
public ServiceCtx(
|
public ServiceCtx(
|
||||||
Switch device,
|
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.
|
// 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.
|
// 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);
|
Logger.Stub?.PrintStub(LogClass.ServiceAcc);
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService
|
|||||||
// OpenLibraryAppletSelfAccessor() -> object<nn::am::service::ILibraryAppletSelfAccessor>
|
// OpenLibraryAppletSelfAccessor() -> object<nn::am::service::ILibraryAppletSelfAccessor>
|
||||||
public ResultCode OpenLibraryAppletSelfAccessor(ServiceCtx context)
|
public ResultCode OpenLibraryAppletSelfAccessor(ServiceCtx context)
|
||||||
{
|
{
|
||||||
MakeObject(context, new ILibraryAppletSelfAccessor(context));
|
MakeObject(context, new ILibraryAppletSelfAccessor(context, _pid));
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
|
|||||||
{
|
{
|
||||||
private readonly AppletStandalone _appletStandalone = new();
|
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.
|
// Create MiiEdit data.
|
||||||
_appletStandalone = new AppletStandalone()
|
_appletStandalone = new AppletStandalone()
|
||||||
@@ -26,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
|
|||||||
}
|
}
|
||||||
else
|
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 int _jitLoaded;
|
||||||
|
|
||||||
private readonly LibHac.HorizonClient _horizon;
|
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.
|
// TODO: Find where they are signaled.
|
||||||
_gpuErrorDetectedSystemEvent = new KEvent(system.KernelContext);
|
_gpuErrorDetectedSystemEvent = new KEvent(system.KernelContext);
|
||||||
@@ -55,6 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
|||||||
_unknownEvent = new KEvent(system.KernelContext);
|
_unknownEvent = new KEvent(system.KernelContext);
|
||||||
|
|
||||||
_horizon = system.LibHacHorizonManager.AmClient;
|
_horizon = system.LibHacHorizonManager.AmClient;
|
||||||
|
_pid = pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandCmif(1)]
|
[CommandCmif(1)]
|
||||||
@@ -115,11 +117,12 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
|||||||
public ResultCode EnsureSaveData(ServiceCtx context)
|
public ResultCode EnsureSaveData(ServiceCtx context)
|
||||||
{
|
{
|
||||||
Uid userId = context.RequestData.ReadStruct<AccountUid>().ToLibHacUid();
|
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
|
// 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.HorizonClient hos = context.Device.System.LibHacHorizonManager.AmClient;
|
||||||
LibHac.Result result = hos.Fs.EnsureApplicationSaveData(out long requiredSize, applicationId, in nacp, in userId);
|
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
|
// TODO: When above calls are implemented, switch to using ns:am
|
||||||
|
|
||||||
long desiredLanguageCode = context.Device.System.State.DesiredLanguageCode;
|
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);
|
int firstSupported = BitOperations.TrailingZeroCount(supportedLanguages);
|
||||||
|
|
||||||
if (firstSupported > (int)TitleLanguage.BrazilianPortuguese)
|
if (firstSupported > (int)TitleLanguage.BrazilianPortuguese)
|
||||||
@@ -182,7 +185,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
|||||||
public ResultCode GetDisplayVersion(ServiceCtx context)
|
public ResultCode GetDisplayVersion(ServiceCtx context)
|
||||||
{
|
{
|
||||||
// If an NACP isn't found, the buffer will be all '\0' which seems to be the correct implementation.
|
// 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;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
@@ -235,11 +238,12 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
|||||||
ushort index = (ushort)context.RequestData.ReadUInt64();
|
ushort index = (ushort)context.RequestData.ReadUInt64();
|
||||||
long saveSize = context.RequestData.ReadInt64();
|
long saveSize = context.RequestData.ReadInt64();
|
||||||
long journalSize = 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
|
// 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,
|
LibHac.Result result = _horizon.Fs.CreateApplicationCacheStorage(out long requiredSize,
|
||||||
out CacheStorageTargetMedia storageTarget, applicationId, in nacp, index, saveSize, journalSize);
|
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>
|
// GetApplicationFunctions() -> object<nn::am::service::IApplicationFunctions>
|
||||||
public ResultCode GetApplicationFunctions(ServiceCtx context)
|
public ResultCode GetApplicationFunctions(ServiceCtx context)
|
||||||
{
|
{
|
||||||
MakeObject(context, new IApplicationFunctions(context.Device.System));
|
MakeObject(context, new IApplicationFunctions(context.Device.System, _pid));
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,18 @@ namespace Ryujinx.HLE.HOS.Services.Arp
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ApplicationLaunchProperty GetByPid(ServiceCtx context)
|
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.
|
// 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.
|
// For now we can hardcode values, and fix it after GetApplicationLaunchProperty is implemented.
|
||||||
|
|
||||||
return new ApplicationLaunchProperty
|
return new ApplicationLaunchProperty
|
||||||
{
|
{
|
||||||
TitleId = context.Device.Processes.ActiveApplication.ProgramId,
|
TitleId = context.Device.Processes.GetProcess(pid).ProgramId,
|
||||||
Version = 0x00,
|
Version = 0x00,
|
||||||
BaseGameStorageId = (byte)StorageId.BuiltInSystem,
|
BaseGameStorageId = (byte)StorageId.BuiltInSystem,
|
||||||
UpdateGameStorageId = (byte)StorageId.None,
|
UpdateGameStorageId = (byte)StorageId.None,
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace Ryujinx.HLE.HOS.Services.Caps
|
|||||||
|
|
||||||
byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray();
|
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);
|
context.ResponseData.WriteStruct(applicationAlbumEntry);
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ namespace Ryujinx.HLE.HOS.Services.Caps
|
|||||||
|
|
||||||
byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray();
|
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);
|
context.ResponseData.WriteStruct(applicationAlbumEntry);
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ namespace Ryujinx.HLE.HOS.Services.Caps
|
|||||||
|
|
||||||
byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray();
|
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);
|
context.ResponseData.WriteStruct(applicationAlbumEntry);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.HOS.Services.Fatal.Types;
|
using Ryujinx.HLE.HOS.Services.Fatal.Types;
|
||||||
|
using Ryujinx.HLE.Loaders.Processes;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
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)
|
private ResultCode ThrowFatalWithCpuContextImpl(ServiceCtx context, ResultCode resultCode, ulong pid, FatalPolicy fatalPolicy, ReadOnlySpan<byte> cpuContext)
|
||||||
{
|
{
|
||||||
|
ProcessResult process = context.Device.Processes.GetProcess(pid);
|
||||||
StringBuilder errorReport = new();
|
StringBuilder errorReport = new();
|
||||||
|
|
||||||
errorReport.AppendLine();
|
errorReport.AppendLine();
|
||||||
errorReport.AppendLine("ErrorReport log:");
|
errorReport.AppendLine("ErrorReport log:");
|
||||||
|
|
||||||
errorReport.AppendLine($"\tTitleId: {context.Device.Processes.ActiveApplication.ProgramIdText}");
|
errorReport.AppendLine($"\tTitleId: {process.ProgramIdText}");
|
||||||
errorReport.AppendLine($"\tPid: {pid}");
|
errorReport.AppendLine($"\tPid: {pid}");
|
||||||
errorReport.AppendLine($"\tResultCode: {((int)resultCode & 0x1FF) + 2000}-{((int)resultCode >> 9) & 0x3FFF:d4}");
|
errorReport.AppendLine($"\tResultCode: {((int)resultCode & 0x1FF) + 2000}-{((int)resultCode >> 9) & 0x3FFF:d4}");
|
||||||
errorReport.AppendLine($"\tFatalPolicy: {fatalPolicy}");
|
errorReport.AppendLine($"\tFatalPolicy: {fatalPolicy}");
|
||||||
@@ -64,7 +66,7 @@ namespace Ryujinx.HLE.HOS.Services.Fatal
|
|||||||
{
|
{
|
||||||
errorReport.AppendLine("CPU Context:");
|
errorReport.AppendLine("CPU Context:");
|
||||||
|
|
||||||
if (context.Device.Processes.ActiveApplication.Is64Bit)
|
if (process.Is64Bit)
|
||||||
{
|
{
|
||||||
CpuContext64 cpuContext64 = MemoryMarshal.Cast<byte, CpuContext64>(cpuContext)[0];
|
CpuContext64 cpuContext64 = MemoryMarshal.Cast<byte, CpuContext64>(cpuContext)[0];
|
||||||
|
|
||||||
|
|||||||
@@ -885,7 +885,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||||||
{
|
{
|
||||||
byte programIndex = context.RequestData.ReadByte();
|
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}).");
|
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)
|
private bool CheckLocalCommunicationIdPermission(ServiceCtx context, ulong localCommunicationIdChecked)
|
||||||
{
|
{
|
||||||
// TODO: Call nn::arp::GetApplicationControlProperty here when implemented.
|
// 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)
|
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)
|
if (scanFilter.NetworkId.IntentId.LocalCommunicationId == -1 && NetworkClient.NeedsRealId)
|
||||||
{
|
{
|
||||||
// TODO: Call nn::arp::GetApplicationControlProperty here when implemented.
|
// 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];
|
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)
|
if (networkConfig.IntentId.LocalCommunicationId == -1 && NetworkClient.NeedsRealId)
|
||||||
{
|
{
|
||||||
// TODO: Call nn::arp::GetApplicationControlProperty here when implemented.
|
// 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];
|
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)
|
if (networkInfo.NetworkId.IntentId.LocalCommunicationId == -1 && NetworkClient.NeedsRealId)
|
||||||
{
|
{
|
||||||
// TODO: Call nn::arp::GetApplicationControlProperty here when implemented.
|
// 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];
|
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.
|
// 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;
|
resultCode = ResultCode.Success;
|
||||||
_nifmResultCode = resultCode;
|
_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.
|
// 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)]
|
[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.
|
// 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
|
[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.
|
// 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
|
[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.
|
// 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+
|
[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.
|
// NOTE: Service call arp:r GetApplicationLaunchProperty to get TitleId using the PId.
|
||||||
|
|
||||||
// TODO: Found where stored value is used.
|
// 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)
|
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,
|
// NOTE: Service calls arp:r GetApplicationControlProperty to get AddOnContentBaseId using TitleId,
|
||||||
// If the call fails, it returns ResultCode.InvalidPid.
|
// 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)
|
if (_addOnContentBaseId == 0)
|
||||||
{
|
{
|
||||||
@@ -324,7 +324,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
|
|||||||
{
|
{
|
||||||
uint index = context.RequestData.ReadUInt32();
|
uint index = context.RequestData.ReadUInt32();
|
||||||
|
|
||||||
ResultCode resultCode = GetAddOnContentBaseIdFromTitleId(context, context.Device.Processes.ActiveApplication.ProgramId);
|
ResultCode resultCode = GetAddOnContentBaseIdFromTitleId(context, titleId);
|
||||||
|
|
||||||
if (resultCode != ResultCode.Success)
|
if (resultCode != ResultCode.Success)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns
|
|||||||
|
|
||||||
ulong position = context.Request.ReceiveBuff[0].Position;
|
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());
|
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;
|
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());
|
context.Memory.Write(position, SpanHelpers.AsByteSpan(ref nacp).ToArray());
|
||||||
|
|
||||||
|
|||||||
@@ -48,21 +48,22 @@ namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory
|
|||||||
{
|
{
|
||||||
if ((_permissionFlag & 0x40) == 0)
|
if ((_permissionFlag & 0x40) == 0)
|
||||||
{
|
{
|
||||||
ulong titleId = ApplicationLaunchProperty.GetByPid(context).TitleId;
|
ulong titleId = ApplicationLaunchProperty.GetByPid(context, _pid).TitleId;
|
||||||
|
|
||||||
if (titleId != 0)
|
if (titleId != 0)
|
||||||
{
|
{
|
||||||
_titleId = titleId;
|
_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.
|
// 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++)
|
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.Cpu;
|
||||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||||
using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService.Types;
|
using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService.Types;
|
||||||
|
using Ryujinx.HLE.Loaders.Processes;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
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 = [];
|
List<ulong> titleIds = [];
|
||||||
|
|
||||||
@@ -45,7 +47,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService
|
|||||||
// Check if input title ids are in the whitelist.
|
// Check if input title ids are in the whitelist.
|
||||||
foreach (ulong titleId in titleIds)
|
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;
|
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>();
|
_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)
|
public bool LoadXci(string path, ulong applicationId)
|
||||||
{
|
{
|
||||||
FileStream stream = new(path, FileMode.Open, FileAccess.Read);
|
FileStream stream = new(path, FileMode.Open, FileAccess.Read);
|
||||||
|
|||||||
@@ -436,6 +436,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
allowCodeMemoryForJit,
|
allowCodeMemoryForJit,
|
||||||
processContextFactory.DiskCacheLoadState,
|
processContextFactory.DiskCacheLoadState,
|
||||||
process.Pid,
|
process.Pid,
|
||||||
|
programIndex,
|
||||||
meta.MainThreadPriority,
|
meta.MainThreadPriority,
|
||||||
meta.MainThreadStackSize,
|
meta.MainThreadStackSize,
|
||||||
device.System.State.DesiredTitleLanguage);
|
device.System.State.DesiredTitleLanguage);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
{
|
{
|
||||||
public class ProcessResult
|
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 byte _mainThreadPriority;
|
||||||
private readonly uint _mainThreadStackSize;
|
private readonly uint _mainThreadStackSize;
|
||||||
@@ -28,6 +28,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
public readonly bool Is64Bit;
|
public readonly bool Is64Bit;
|
||||||
public readonly bool DiskCacheEnabled;
|
public readonly bool DiskCacheEnabled;
|
||||||
public readonly bool AllowCodeMemoryForJit;
|
public readonly bool AllowCodeMemoryForJit;
|
||||||
|
public readonly ProcessIdentity Identity;
|
||||||
|
|
||||||
public ProcessResult(
|
public ProcessResult(
|
||||||
MetaLoader metaLoader,
|
MetaLoader metaLoader,
|
||||||
@@ -36,6 +37,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
bool allowCodeMemoryForJit,
|
bool allowCodeMemoryForJit,
|
||||||
IDiskCacheLoadState diskCacheLoadState,
|
IDiskCacheLoadState diskCacheLoadState,
|
||||||
ulong pid,
|
ulong pid,
|
||||||
|
byte programIndex,
|
||||||
byte mainThreadPriority,
|
byte mainThreadPriority,
|
||||||
uint mainThreadStackSize,
|
uint mainThreadStackSize,
|
||||||
TitleLanguage titleLanguage)
|
TitleLanguage titleLanguage)
|
||||||
@@ -71,6 +73,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
ProgramId = programId;
|
ProgramId = programId;
|
||||||
ProgramIdText = $"{programId:x16}";
|
ProgramIdText = $"{programId:x16}";
|
||||||
Is64Bit = metaLoader.IsProgram64Bit;
|
Is64Bit = metaLoader.IsProgram64Bit;
|
||||||
|
Identity = new ProcessIdentity(pid, programId, programIndex, DisplayVersion, GetProcessKind(programId));
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -84,6 +87,31 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
AllowCodeMemoryForJit = allowCodeMemoryForJit;
|
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)
|
public bool Start(Switch device)
|
||||||
{
|
{
|
||||||
device.Configuration.ContentManager.LoadEntries(device);
|
device.Configuration.ContentManager.LoadEntries(device);
|
||||||
@@ -109,6 +137,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
: device.System.ContentManager.GetCurrentFirmwareVersion()?.VersionString ?? "?";
|
: 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, $"Application Loaded: {name} v{version} [{ProgramIdText}] [{(Is64Bit ? "64-bit" : "32-bit")}]");
|
||||||
|
Logger.Info?.Print(LogClass.Loader, $"Process identity: {Identity}");
|
||||||
|
|
||||||
return true;
|
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()
|
public static nint CreateEmptyCursor()
|
||||||
{
|
{
|
||||||
return CreateCursor(nint.Zero, 0, 0, 1, 1, [0xFF], [0x00]);
|
return CreateCursor(nint.Zero, 0, 0, 1, 1, [0xFF], [0x00]);
|
||||||
@@ -119,6 +131,10 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
[LibraryImport("user32.dll", SetLastError = true)]
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
public static partial nint SetWindowLongPtrW(nint hWnd, int nIndex, nint value);
|
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)]
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
public static partial bool SetWindowPos(
|
public static partial bool SetWindowPos(
|
||||||
|
|||||||
@@ -2060,6 +2060,12 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
private nint _savedWindowStyle;
|
private nint _savedWindowStyle;
|
||||||
|
private WindowState _savedWindowState;
|
||||||
|
private PixelPoint _savedWindowPosition;
|
||||||
|
private double _savedWindowWidth;
|
||||||
|
private double _savedWindowHeight;
|
||||||
|
private Win32NativeInterop.NativeRect _savedWindowRect;
|
||||||
|
private bool _savedWindowRectValid;
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
private void MakeWindowFullscreen()
|
private void MakeWindowFullscreen()
|
||||||
@@ -2067,19 +2073,36 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
nint hwnd = Window.TryGetPlatformHandle()?.Handle ?? nint.Zero;
|
nint hwnd = Window.TryGetPlatformHandle()?.Handle ?? nint.Zero;
|
||||||
if (hwnd == nint.Zero) return;
|
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
|
// Save current style and placement
|
||||||
_savedWindowStyle = Win32NativeInterop.GetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE);
|
_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
|
// Remove window chrome: WS_OVERLAPPEDWINDOW -> WS_POPUP | WS_VISIBLE
|
||||||
Win32NativeInterop.SetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE,
|
Win32NativeInterop.SetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE,
|
||||||
unchecked((nint)(Win32NativeInterop.WS_POPUP | Win32NativeInterop.WS_VISIBLE)));
|
unchecked((nint)(Win32NativeInterop.WS_POPUP | Win32NativeInterop.WS_VISIBLE)));
|
||||||
|
|
||||||
// TODO: why is this nullable
|
int w = screen.Bounds.Width;
|
||||||
Avalonia.Platform.Screen? screen = Window.Screens.ScreenFromVisual(Window);
|
int h = screen.Bounds.Height;
|
||||||
int w = screen?.Bounds.Width ?? 0;
|
|
||||||
int h = screen?.Bounds.Height ?? 0;
|
|
||||||
|
|
||||||
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, 0, 0, w, h,
|
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, screen.Bounds.X, screen.Bounds.Y, w, h,
|
||||||
Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE | Win32NativeInterop.SWP_FRAMECHANGED);
|
Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE | Win32NativeInterop.SWP_FRAMECHANGED);
|
||||||
|
|
||||||
WindowState = WindowState.FullScreen;
|
WindowState = WindowState.FullScreen;
|
||||||
@@ -2094,10 +2117,34 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
// Restore original window style
|
// Restore original window style
|
||||||
Win32NativeInterop.SetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE, _savedWindowStyle);
|
Win32NativeInterop.SetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE, _savedWindowStyle);
|
||||||
|
|
||||||
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, 0, 0, 0, 0,
|
if (_savedWindowState is WindowState.Maximized)
|
||||||
Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE |
|
{
|
||||||
Win32NativeInterop.SWP_FRAMECHANGED | Win32NativeInterop.SWP_NOMOVE | Win32NativeInterop.SWP_NOSIZE);
|
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()
|
public static void SaveConfig()
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
|
|
||||||
private bool _isLoading;
|
private bool _isLoading;
|
||||||
private bool _applicationsLoadedOnce;
|
private bool _applicationsLoadedOnce;
|
||||||
|
private double _windowStartupWidthDelta;
|
||||||
|
private double _windowStartupHeightDelta;
|
||||||
|
|
||||||
private UserChannelPersistence _userChannelPersistence;
|
private UserChannelPersistence _userChannelPersistence;
|
||||||
private static bool _deferLoad;
|
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
|
// 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)
|
// 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.WindowSizeHeight.Value = (int)((Height - _windowStartupHeightDelta) / Program.WindowScaleFactor);
|
||||||
ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth.Value = (int)(Width / 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.WindowPositionX.Value = Position.X;
|
||||||
ConfigurationState.Instance.UI.WindowStartup.WindowPositionY.Value = Position.Y;
|
ConfigurationState.Instance.UI.WindowStartup.WindowPositionY.Value = Position.Y;
|
||||||
@@ -493,6 +495,9 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
|
_windowStartupWidthDelta = Math.Max(0, Width - ViewModel.WindowWidth);
|
||||||
|
_windowStartupHeightDelta = Math.Max(0, Height - ViewModel.WindowHeight);
|
||||||
|
|
||||||
PlatformSettings!.ColorValuesChanged += OnPlatformColorValuesChanged;
|
PlatformSettings!.ColorValuesChanged += OnPlatformColorValuesChanged;
|
||||||
|
|
||||||
ViewModel.Initialize(
|
ViewModel.Initialize(
|
||||||
|
|||||||
Reference in New Issue
Block a user