Refactoring commands handling (#728)

* Refactoring commands handling

- Use Reflection to handle commands ID.
- Add all symbols (from SwIPC so not all time accurate).
- Re-sort some services commands methods.
- Some cleanup.
- Keep some empty constructor for consistency.

* Fix order in IProfile
This commit is contained in:
Ac_K 2019-07-12 03:13:43 +02:00 committed by gdkchan
parent f723f6f39a
commit 560ccbeb2d
99 changed files with 1035 additions and 1983 deletions

View file

@ -63,13 +63,13 @@ namespace Ryujinx.HLE.Exceptions
var ipcCommands = ipcService.Commands;
// Find the handler for the method called
var ipcHandler = ipcCommands.FirstOrDefault(x => x.Value.Method == callingMethod);
var ipcHandler = ipcCommands.FirstOrDefault(x => x.Value as MethodBase == callingMethod);
var ipcCommandId = ipcHandler.Key;
var ipcMethod = ipcHandler.Value;
if (ipcMethod != null)
{
sb.AppendLine($"Service Command: {ipcService.GetType().FullName}: {ipcCommandId} ({ipcMethod.Method.Name})");
sb.AppendLine($"Service Command: {ipcService.GetType().FullName}: {ipcCommandId} ({ipcMethod.Name})");
sb.AppendLine();
}
}

View file

@ -1,6 +1,5 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Services.Arp;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Utilities;
@ -19,40 +18,9 @@ namespace Ryujinx.HLE.HOS.Services.Acc
private ApplicationLaunchProperty _applicationLaunchProperty;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAccountService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetUserCount },
{ 1, GetUserExistence },
{ 2, ListAllUsers },
{ 3, ListOpenUsers },
{ 4, GetLastOpenedUser },
{ 5, GetProfile },
//{ 6, GetProfileDigest }, // 3.0.0+
{ 50, IsUserRegistrationRequestPermitted },
{ 51, TrySelectUserWithoutInteraction },
//{ 60, ListOpenContextStoredUsers }, // 5.0.0-5.1.0
//{ 99, DebugActivateOpenContextRetention }, // 6.0.0+
{ 100, InitializeApplicationInfo },
{ 101, GetBaasAccountManagerForApplication },
//{ 102, AuthenticateApplicationAsync },
//{ 103, CheckNetworkServiceAvailabilityAsync }, // 4.0.0+
{ 110, StoreSaveDataThumbnail },
{ 111, ClearSaveDataThumbnail },
//{ 120, CreateGuestLoginRequest },
//{ 130, LoadOpenContext }, // 6.0.0+
//{ 131, ListOpenContextStoredUsers }, // 6.0.0+
{ 140, InitializeApplicationInfo }, // 6.0.0+
//{ 141, ListQualifiedUsers }, // 6.0.0+
{ 150, IsUserAccountSwitchLocked }, // 6.0.0+
};
}
public IAccountService(ServiceCtx context) { }
[Command(0)]
// GetUserCount() -> i32
public long GetUserCount(ServiceCtx context)
{
@ -61,6 +29,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(1)]
// GetUserExistence(nn::account::Uid) -> bool
public long GetUserExistence(ServiceCtx context)
{
@ -76,12 +45,14 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(2)]
// ListAllUsers() -> array<nn::account::Uid, 0xa>
public long ListAllUsers(ServiceCtx context)
{
return WriteUserList(context, context.Device.System.State.Account.GetAllUsers());
}
[Command(3)]
// ListOpenUsers() -> array<nn::account::Uid, 0xa>
public long ListOpenUsers(ServiceCtx context)
{
@ -116,6 +87,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(4)]
// GetLastOpenedUser() -> nn::account::Uid
public long GetLastOpenedUser(ServiceCtx context)
{
@ -124,6 +96,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(5)]
// GetProfile(nn::account::Uid) -> object<nn::account::profile::IProfile>
public long GetProfile(ServiceCtx context)
{
@ -144,6 +117,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(50)]
// IsUserRegistrationRequestPermitted(u64, pid) -> bool
public long IsUserRegistrationRequestPermitted(ServiceCtx context)
{
@ -153,6 +127,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(51)]
// TrySelectUserWithoutInteraction(bool) -> nn::account::Uid
public long TrySelectUserWithoutInteraction(ServiceCtx context)
{
@ -180,6 +155,8 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(100)]
[Command(140)] // 6.0.0+
// InitializeApplicationInfo(u64, pid)
// Both calls (100, 140) use the same submethod, maybe there's something different further along when arp:r is called?
public long InitializeApplicationInfo(ServiceCtx context)
@ -225,6 +202,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(101)]
// GetBaasAccountManagerForApplication(nn::account::Uid) -> object<nn::account::baas::IManagerForApplication>
public long GetBaasAccountManagerForApplication(ServiceCtx context)
{
@ -248,6 +226,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(110)]
// StoreSaveDataThumbnail(nn::account::Uid, buffer<bytes, 5>)
public long StoreSaveDataThumbnail(ServiceCtx context)
{
@ -285,6 +264,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(111)]
// ClearSaveDataThumbnail(nn::account::Uid)
public long ClearSaveDataThumbnail(ServiceCtx context)
{
@ -307,6 +287,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(150)] // 6.0.0+
// IsUserAccountSwitchLocked() -> bool
public long IsUserAccountSwitchLocked(ServiceCtx context)
{

View file

@ -1,33 +1,21 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Services.Arp;
using Ryujinx.HLE.Utilities;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Acc
{
class IManagerForApplication : IpcService
{
private UInt128 _userId;
private UInt128 _userId;
private ApplicationLaunchProperty _applicationLaunchProperty;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IManagerForApplication(UInt128 userId, ApplicationLaunchProperty applicationLaunchProperty)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, CheckAvailability },
{ 1, GetAccountId }
};
_userId = userId;
_applicationLaunchProperty = applicationLaunchProperty;
}
[Command(0)]
// CheckAvailability()
public long CheckAvailability(ServiceCtx context)
{
@ -36,6 +24,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(1)]
// GetAccountId() -> nn::account::NetworkServiceAccountId
public long GetAccountId(ServiceCtx context)
{

View file

@ -1,9 +1,7 @@
using ChocolArm64.Memory;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Utilities;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
@ -12,29 +10,17 @@ namespace Ryujinx.HLE.HOS.Services.Acc
{
class IProfile : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private UserProfile _profile;
private Stream _profilePictureStream;
private Stream _profilePictureStream;
public IProfile(UserProfile profile)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Get },
{ 1, GetBase },
{ 10, GetImageSize },
{ 11, LoadImage }
};
_profile = profile;
_profile = profile;
_profilePictureStream = Assembly.GetCallingAssembly().GetManifestResourceStream("Ryujinx.HLE.RyujinxProfileImage.jpg");
}
[Command(0)]
// Get() -> (nn::account::profile::ProfileBase, buffer<nn::account::profile::UserData, 0x1a>)
public long Get(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAcc);
@ -50,6 +36,8 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return GetBase(context);
}
[Command(1)]
// GetBase() -> nn::account::profile::ProfileBase
public long GetBase(ServiceCtx context)
{
_profile.UserId.Write(context.ResponseData);
@ -63,6 +51,17 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
[Command(10)]
// GetImageSize() -> u32
private long GetImageSize(ServiceCtx context)
{
context.ResponseData.Write(_profilePictureStream.Length);
return 0;
}
[Command(11)]
// LoadImage() -> (u32, buffer<bytes, 6>)
private long LoadImage(ServiceCtx context)
{
long bufferPosition = context.Request.ReceiveBuff[0].Position;
@ -78,12 +77,5 @@ namespace Ryujinx.HLE.HOS.Services.Acc
return 0;
}
private long GetImageSize(ServiceCtx context)
{
context.ResponseData.Write(_profilePictureStream.Length);
return 0;
}
}
}

View file

@ -1,23 +1,12 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
[Service("appletAE")]
class IAllSystemAppletProxiesService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAllSystemAppletProxiesService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 100, OpenSystemAppletProxy }
};
}
public IAllSystemAppletProxiesService(ServiceCtx context) { }
[Command(100)]
// OpenSystemAppletProxy(u64, pid, handle<copy>) -> object<nn::am::service::ISystemAppletProxy>
public long OpenSystemAppletProxy(ServiceCtx context)
{
MakeObject(context, new ISystemAppletProxy());

View file

@ -1,20 +1,7 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IApplicationCreator : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IApplicationCreator()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public IApplicationCreator() { }
}
}

View file

@ -1,31 +1,13 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IApplicationFunctions : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IApplicationFunctions()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 1, PopLaunchParameter },
{ 20, EnsureSaveData },
{ 21, GetDesiredLanguage },
{ 22, SetTerminateResult },
{ 23, GetDisplayVersion },
{ 40, NotifyRunning },
{ 50, GetPseudoDeviceId },
{ 66, InitializeGamePlayRecording },
{ 67, SetGamePlayRecordingState }
};
}
public IApplicationFunctions() { }
[Command(1)]
// PopLaunchParameter(u32) -> object<nn::am::service::IStorage>
public long PopLaunchParameter(ServiceCtx context)
{
// Only the first 0x18 bytes of the Data seems to be actually used.
@ -34,6 +16,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(20)]
// EnsureSaveData(nn::account::Uid) -> u64
public long EnsureSaveData(ServiceCtx context)
{
long uIdLow = context.RequestData.ReadInt64();
@ -46,6 +30,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(21)]
// GetDesiredLanguage() -> nn::settings::LanguageCode
public long GetDesiredLanguage(ServiceCtx context)
{
context.ResponseData.Write(context.Device.System.State.DesiredLanguageCode);
@ -53,6 +39,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(22)]
// SetTerminateResult(u32)
public long SetTerminateResult(ServiceCtx context)
{
int errorCode = context.RequestData.ReadInt32();
@ -72,6 +60,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return $"{(2000 + module):d4}-{description:d4}";
}
[Command(23)]
// GetDisplayVersion() -> nn::oe::DisplayVersion
public long GetDisplayVersion(ServiceCtx context)
{
// FIXME: Need to check correct version on a switch.
@ -81,6 +71,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(40)]
// NotifyRunning() -> b8
public long NotifyRunning(ServiceCtx context)
{
context.ResponseData.Write(1);
@ -88,6 +80,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(50)] // 2.0.0+
// GetPseudoDeviceId() -> nn::util::Uuid
public long GetPseudoDeviceId(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);
@ -98,6 +92,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(66)] // 3.0.0+
// InitializeGamePlayRecording(u64, handle<copy>)
public long InitializeGamePlayRecording(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);
@ -105,6 +101,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(67)] // 3.0.0+
// SetGamePlayRecordingState(u32)
public long SetGamePlayRecordingState(ServiceCtx context)
{
int state = context.RequestData.ReadInt32();
@ -114,4 +112,4 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
}
}
}

View file

@ -1,29 +1,11 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IApplicationProxy : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IApplicationProxy()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetCommonStateGetter },
{ 1, GetSelfController },
{ 2, GetWindowController },
{ 3, GetAudioController },
{ 4, GetDisplayController },
{ 11, GetLibraryAppletCreator },
{ 20, GetApplicationFunctions },
{ 1000, GetDebugFunctions }
};
}
public IApplicationProxy() { }
[Command(0)]
// GetCommonStateGetter() -> object<nn::am::service::ICommonStateGetter>
public long GetCommonStateGetter(ServiceCtx context)
{
MakeObject(context, new ICommonStateGetter(context.Device.System));
@ -31,6 +13,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(1)]
// GetSelfController() -> object<nn::am::service::ISelfController>
public long GetSelfController(ServiceCtx context)
{
MakeObject(context, new ISelfController(context.Device.System));
@ -38,6 +22,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(2)]
// GetWindowController() -> object<nn::am::service::IWindowController>
public long GetWindowController(ServiceCtx context)
{
MakeObject(context, new IWindowController());
@ -45,6 +31,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(3)]
// GetAudioController() -> object<nn::am::service::IAudioController>
public long GetAudioController(ServiceCtx context)
{
MakeObject(context, new IAudioController());
@ -52,6 +40,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(4)]
// GetDisplayController() -> object<nn::am::service::IDisplayController>
public long GetDisplayController(ServiceCtx context)
{
MakeObject(context, new IDisplayController());
@ -59,6 +49,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(11)]
// GetLibraryAppletCreator() -> object<nn::am::service::ILibraryAppletCreator>
public long GetLibraryAppletCreator(ServiceCtx context)
{
MakeObject(context, new ILibraryAppletCreator());
@ -66,6 +58,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(20)]
// GetApplicationFunctions() -> object<nn::am::service::IApplicationFunctions>
public long GetApplicationFunctions(ServiceCtx context)
{
MakeObject(context, new IApplicationFunctions());
@ -73,6 +67,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(1000)]
// GetDebugFunctions() -> object<nn::am::service::IDebugFunctions>
public long GetDebugFunctions(ServiceCtx context)
{
MakeObject(context, new IDebugFunctions());

View file

@ -1,23 +1,12 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
[Service("appletOE")]
class IApplicationProxyService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IApplicationProxyService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, OpenApplicationProxy }
};
}
public IApplicationProxyService(ServiceCtx context) { }
[Command(0)]
// OpenApplicationProxy(u64, pid, handle<copy>) -> object<nn::am::service::IApplicationProxy>
public long OpenApplicationProxy(ServiceCtx context)
{
MakeObject(context, new IApplicationProxy());

View file

@ -1,27 +1,13 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IAudioController : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAudioController()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, SetExpectedMasterVolume },
{ 1, GetMainAppletExpectedMasterVolume },
{ 2, GetLibraryAppletExpectedMasterVolume },
{ 3, ChangeMainAppletMasterVolume },
{ 4, SetTransparentVolumeRate }
};
}
public IAudioController() { }
[Command(0)]
// SetExpectedMasterVolume(f32, f32)
public long SetExpectedMasterVolume(ServiceCtx context)
{
float appletVolume = context.RequestData.ReadSingle();
@ -32,6 +18,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(1)]
// GetMainAppletExpectedMasterVolume() -> f32
public long GetMainAppletExpectedMasterVolume(ServiceCtx context)
{
context.ResponseData.Write(1f);
@ -41,6 +29,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(2)]
// GetLibraryAppletExpectedMasterVolume() -> f32
public long GetLibraryAppletExpectedMasterVolume(ServiceCtx context)
{
context.ResponseData.Write(1f);
@ -50,6 +40,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(3)]
// ChangeMainAppletMasterVolume(f32, u64)
public long ChangeMainAppletMasterVolume(ServiceCtx context)
{
float unknown0 = context.RequestData.ReadSingle();
@ -60,6 +52,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(4)]
// SetTransparentVolumeRate(f32)
public long SetTransparentVolumeRate(ServiceCtx context)
{
float unknown0 = context.RequestData.ReadSingle();
@ -69,4 +63,4 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
}
}
}

View file

@ -3,7 +3,6 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
using System.Collections.Generic;
using static Ryujinx.HLE.HOS.ErrorCode;
@ -11,29 +10,15 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class ICommonStateGetter : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent _displayResolutionChangeEvent;
public ICommonStateGetter(Horizon system)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetEventHandle },
{ 1, ReceiveMessage },
{ 5, GetOperationMode },
{ 6, GetPerformanceMode },
{ 8, GetBootMode },
{ 9, GetCurrentFocusState },
{ 60, GetDefaultDisplayResolution },
{ 61, GetDefaultDisplayResolutionChangeEvent }
};
_displayResolutionChangeEvent = new KEvent(system);
}
[Command(0)]
// GetEventHandle() -> handle<copy>
public long GetEventHandle(ServiceCtx context)
{
KEvent Event = context.Device.System.AppletState.MessageEvent;
@ -48,6 +33,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(1)]
// ReceiveMessage() -> nn::am::AppletMessage
public long ReceiveMessage(ServiceCtx context)
{
if (!context.Device.System.AppletState.TryDequeueMessage(out MessageInfo message))
@ -60,6 +47,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(5)]
// GetOperationMode() -> u8
public long GetOperationMode(ServiceCtx context)
{
OperationMode mode = context.Device.System.State.DockedMode
@ -71,6 +60,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(6)]
// GetPerformanceMode() -> u32
public long GetPerformanceMode(ServiceCtx context)
{
Apm.PerformanceMode mode = context.Device.System.State.DockedMode
@ -82,6 +73,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(8)]
// GetBootMode() -> u8
public long GetBootMode(ServiceCtx context)
{
context.ResponseData.Write((byte)0); //Unknown value.
@ -91,6 +84,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(9)]
// GetCurrentFocusState() -> u8
public long GetCurrentFocusState(ServiceCtx context)
{
context.ResponseData.Write((byte)context.Device.System.AppletState.FocusState);
@ -98,6 +93,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(60)] // 3.0.0+
// GetDefaultDisplayResolution() -> (u32, u32)
public long GetDefaultDisplayResolution(ServiceCtx context)
{
context.ResponseData.Write(1280);
@ -106,6 +103,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(61)] // 3.0.0+
// GetDefaultDisplayResolutionChangeEvent() -> handle<copy>
public long GetDefaultDisplayResolutionChangeEvent(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_displayResolutionChangeEvent.ReadableEvent, out int handle) != KernelResult.Success)
@ -120,4 +119,4 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
}
}
}

View file

@ -1,20 +1,7 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IDebugFunctions : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IDebugFunctions()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public IDebugFunctions() { }
}
}

View file

@ -1,20 +1,7 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IDisplayController : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IDisplayController()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public IDisplayController() { }
}
}

View file

@ -1,20 +1,7 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IGlobalStateController : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IGlobalStateController()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public IGlobalStateController() { }
}
}

View file

@ -3,30 +3,21 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IHomeMenuFunctions : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent _channelEvent;
public IHomeMenuFunctions(Horizon system)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 10, RequestToGetForeground },
{ 21, GetPopFromGeneralChannelEvent }
};
// TODO: Signal this Event somewhere in future.
_channelEvent = new KEvent(system);
}
[Command(10)]
// RequestToGetForeground()
public long RequestToGetForeground(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);
@ -34,6 +25,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(21)]
// GetPopFromGeneralChannelEvent() -> handle<copy>
public long GetPopFromGeneralChannelEvent(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_channelEvent.ReadableEvent, out int handle) != KernelResult.Success)
@ -48,4 +41,4 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
}
}
}

View file

@ -3,32 +3,20 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class ILibraryAppletAccessor : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent _stateChangedEvent;
public ILibraryAppletAccessor(Horizon system)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetAppletStateChangedEvent },
{ 10, Start },
{ 30, GetResult },
{ 100, PushInData },
{ 101, PopOutData }
};
_stateChangedEvent = new KEvent(system);
}
[Command(0)]
// GetAppletStateChangedEvent() -> handle<copy>
public long GetAppletStateChangedEvent(ServiceCtx context)
{
_stateChangedEvent.ReadableEvent.Signal();
@ -45,6 +33,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(10)]
// Start()
public long Start(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);
@ -52,6 +42,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(30)]
// GetResult()
public long GetResult(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);
@ -59,6 +51,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(100)]
// PushInData(object<nn::am::service::IStorage>)
public long PushInData(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);
@ -66,6 +60,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(101)]
// PopOutData() -> object<nn::am::service::IStorage>
public long PopOutData(ServiceCtx context)
{
MakeObject(context, new IStorage(StorageHelper.MakeLaunchParams()));

View file

@ -1,23 +1,11 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class ILibraryAppletCreator : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ILibraryAppletCreator()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, CreateLibraryApplet },
{ 10, CreateStorage }
};
}
public ILibraryAppletCreator() { }
[Command(0)]
// CreateLibraryApplet(u32, u32) -> object<nn::am::service::ILibraryAppletAccessor>
public long CreateLibraryApplet(ServiceCtx context)
{
MakeObject(context, new ILibraryAppletAccessor(context.Device.System));
@ -25,6 +13,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(10)]
// CreateStorage(u64) -> object<nn::am::service::IStorage>
public long CreateStorage(ServiceCtx context)
{
long size = context.RequestData.ReadInt64();

View file

@ -3,16 +3,11 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class ISelfController : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent _libraryAppletLaunchableEvent;
private KEvent _accumulatedSuspendedTickChangedEvent;
@ -22,54 +17,11 @@ namespace Ryujinx.HLE.HOS.Services.Am
public ISelfController(Horizon system)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Exit },
{ 1, LockExit },
{ 2, UnlockExit },
//{ 3, EnterFatalSection }, // 2.0.0+
//{ 4, LeaveFatalSection }, // 2.0.0+
{ 9, GetLibraryAppletLaunchableEvent },
{ 10, SetScreenShotPermission },
{ 11, SetOperationModeChangedNotification },
{ 12, SetPerformanceModeChangedNotification },
{ 13, SetFocusHandlingMode },
{ 14, SetRestartMessageEnabled },
//{ 15, SetScreenShotAppletIdentityInfo }, // 2.0.0+
{ 16, SetOutOfFocusSuspendingEnabled }, // 2.0.0+
//{ 17, SetControllerFirmwareUpdateSection }, // 3.0.0+
//{ 18, SetRequiresCaptureButtonShortPressedMessage }, // 3.0.0+
{ 19, SetScreenShotImageOrientation }, // 3.0.0+
//{ 20, SetDesirableKeyboardLayout }, // 4.0.0+
//{ 40, CreateManagedDisplayLayer },
//{ 41, IsSystemBufferSharingEnabled }, // 4.0.0+
//{ 42, GetSystemSharedLayerHandle }, // 4.0.0+
//{ 43, GetSystemSharedBufferHandle }, // 5.0.0+
{ 50, SetHandlesRequestToDisplay },
//{ 51, ApproveToDisplay },
//{ 60, OverrideAutoSleepTimeAndDimmingTime },
//{ 61, SetMediaPlaybackState },
{ 62, SetIdleTimeDetectionExtension },
{ 63, GetIdleTimeDetectionExtension },
//{ 64, SetInputDetectionSourceSet },
//{ 65, ReportUserIsActive }, // 2.0.0+
//{ 66, GetCurrentIlluminance }, // 3.0.0+
//{ 67, IsIlluminanceAvailable }, // 3.0.0+
//{ 68, SetAutoSleepDisabled }, // 5.0.0+
//{ 69, IsAutoSleepDisabled }, // 5.0.0+
//{ 70, ReportMultimediaError }, // 4.0.0+
//{ 71, GetCurrentIlluminanceEx }, // 5.0.0+
//{ 80, SetWirelessPriorityMode }, // 4.0.0+
//{ 90, GetAccumulatedSuspendedTickValue }, // 6.0.0+
{ 91, GetAccumulatedSuspendedTickChangedEvent }, // 6.0.0+
//{ 100, SetAlbumImageTakenNotificationEnabled }, // 7.0.0+
//{ 110, SetApplicationAlbumUserData }, // 8.0.0+
//{ 1000, GetDebugStorageChannel }, // 7.0.0+
};
_libraryAppletLaunchableEvent = new KEvent(system);
}
[Command(0)]
// Exit()
public long Exit(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);
@ -77,6 +29,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(1)]
// LockExit()
public long LockExit(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);
@ -84,6 +38,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(2)]
// UnlockExit()
public long UnlockExit(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);
@ -91,6 +47,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(9)]
// GetLibraryAppletLaunchableEvent() -> handle<copy>
public long GetLibraryAppletLaunchableEvent(ServiceCtx context)
{
_libraryAppletLaunchableEvent.ReadableEvent.Signal();
@ -107,6 +65,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(10)]
// SetScreenShotPermission(u32)
public long SetScreenShotPermission(ServiceCtx context)
{
bool enable = context.RequestData.ReadByte() != 0;
@ -116,6 +76,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(11)]
// SetOperationModeChangedNotification(b8)
public long SetOperationModeChangedNotification(ServiceCtx context)
{
bool enable = context.RequestData.ReadByte() != 0;
@ -125,6 +87,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(12)]
// SetPerformanceModeChangedNotification(b8)
public long SetPerformanceModeChangedNotification(ServiceCtx context)
{
bool enable = context.RequestData.ReadByte() != 0;
@ -134,6 +98,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(13)]
// SetFocusHandlingMode(b8, b8, b8)
public long SetFocusHandlingMode(ServiceCtx context)
{
bool flag1 = context.RequestData.ReadByte() != 0;
@ -145,6 +111,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(14)]
// SetRestartMessageEnabled(b8)
public long SetRestartMessageEnabled(ServiceCtx context)
{
bool enable = context.RequestData.ReadByte() != 0;
@ -154,6 +122,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(16)] // 2.0.0+
// SetOutOfFocusSuspendingEnabled(b8)
public long SetOutOfFocusSuspendingEnabled(ServiceCtx context)
{
bool enable = context.RequestData.ReadByte() != 0;
@ -163,6 +133,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(19)] // 3.0.0+
public long SetScreenShotImageOrientation(ServiceCtx context)
{
int orientation = context.RequestData.ReadInt32();
@ -172,6 +143,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(50)]
// SetHandlesRequestToDisplay(b8)
public long SetHandlesRequestToDisplay(ServiceCtx context)
{
bool enable = context.RequestData.ReadByte() != 0;
@ -181,6 +154,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(62)]
// SetIdleTimeDetectionExtension(u32)
public long SetIdleTimeDetectionExtension(ServiceCtx context)
{
@ -191,6 +165,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(63)]
// GetIdleTimeDetectionExtension() -> u32
public long GetIdleTimeDetectionExtension(ServiceCtx context)
{
@ -201,6 +176,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(91)] // 6.0.0+
// GetAccumulatedSuspendedTickChangedEvent() -> handle<copy>
public long GetAccumulatedSuspendedTickChangedEvent(ServiceCtx context)
{
@ -221,4 +197,4 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
}
}
}

View file

@ -1,26 +1,16 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IStorage : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public byte[] Data { get; private set; }
public IStorage(byte[] data)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Open }
};
Data = data;
}
[Command(0)]
// Open() -> object<nn::am::service::IStorageAccessor>
public long Open(ServiceCtx context)
{
MakeObject(context, new IStorageAccessor(this));

View file

@ -1,29 +1,18 @@
using Ryujinx.HLE.HOS.Ipc;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IStorageAccessor : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private IStorage _storage;
public IStorageAccessor(IStorage storage)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetSize },
{ 10, Write },
{ 11, Read }
};
_storage = storage;
}
[Command(0)]
// GetSize() -> u64
public long GetSize(ServiceCtx context)
{
context.ResponseData.Write((long)_storage.Data.Length);
@ -31,6 +20,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(10)]
// Write(u64, buffer<bytes, 0x21>)
public long Write(ServiceCtx context)
{
// TODO: Error conditions.
@ -55,6 +46,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(11)]
// Read(u64) -> buffer<bytes, 0x22>
public long Read(ServiceCtx context)
{
// TODO: Error conditions.

View file

@ -1,31 +1,11 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class ISystemAppletProxy : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISystemAppletProxy()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetCommonStateGetter },
{ 1, GetSelfController },
{ 2, GetWindowController },
{ 3, GetAudioController },
{ 4, GetDisplayController },
{ 11, GetLibraryAppletCreator },
{ 20, GetHomeMenuFunctions },
{ 21, GetGlobalStateController },
{ 22, GetApplicationCreator },
{ 1000, GetDebugFunctions }
};
}
public ISystemAppletProxy() { }
[Command(0)]
// GetCommonStateGetter() -> object<nn::am::service::ICommonStateGetter>
public long GetCommonStateGetter(ServiceCtx context)
{
MakeObject(context, new ICommonStateGetter(context.Device.System));
@ -33,6 +13,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(1)]
// GetSelfController() -> object<nn::am::service::ISelfController>
public long GetSelfController(ServiceCtx context)
{
MakeObject(context, new ISelfController(context.Device.System));
@ -40,6 +22,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(2)]
// GetWindowController() -> object<nn::am::service::IWindowController>
public long GetWindowController(ServiceCtx context)
{
MakeObject(context, new IWindowController());
@ -47,6 +31,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(3)]
// GetAudioController() -> object<nn::am::service::IAudioController>
public long GetAudioController(ServiceCtx context)
{
MakeObject(context, new IAudioController());
@ -54,6 +40,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(4)]
// GetDisplayController() -> object<nn::am::service::IDisplayController>
public long GetDisplayController(ServiceCtx context)
{
MakeObject(context, new IDisplayController());
@ -61,6 +49,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(11)]
// GetLibraryAppletCreator() -> object<nn::am::service::ILibraryAppletCreator>
public long GetLibraryAppletCreator(ServiceCtx context)
{
MakeObject(context, new ILibraryAppletCreator());
@ -68,6 +58,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(20)]
// GetHomeMenuFunctions() -> object<nn::am::service::IHomeMenuFunctions>
public long GetHomeMenuFunctions(ServiceCtx context)
{
MakeObject(context, new IHomeMenuFunctions(context.Device.System));
@ -75,6 +67,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(21)]
// GetGlobalStateController() -> object<nn::am::service::IGlobalStateController>
public long GetGlobalStateController(ServiceCtx context)
{
MakeObject(context, new IGlobalStateController());
@ -82,6 +76,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(22)]
// GetApplicationCreator() -> object<nn::am::service::IApplicationCreator>
public long GetApplicationCreator(ServiceCtx context)
{
MakeObject(context, new IApplicationCreator());
@ -89,6 +85,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(1000)]
// GetDebugFunctions() -> object<nn::am::service::IDebugFunctions>
public long GetDebugFunctions(ServiceCtx context)
{
MakeObject(context, new IDebugFunctions());

View file

@ -1,24 +1,13 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Am
{
class IWindowController : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IWindowController()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 1, GetAppletResourceUserId },
{ 10, AcquireForegroundRights }
};
}
public IWindowController() { }
[Command(1)]
// GetAppletResourceUserId() -> nn::applet::AppletResourceUserId
public long GetAppletResourceUserId(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);
@ -28,6 +17,8 @@ namespace Ryujinx.HLE.HOS.Services.Am
return 0;
}
[Command(10)]
// AcquireForegroundRights()
public long AcquireForegroundRights(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAm);

View file

@ -1,24 +1,13 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Apm
{
[Service("apm")]
[Service("apm:p")]
class IManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IManager(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, OpenSession }
};
}
public IManager(ServiceCtx context) { }
[Command(0)]
// OpenSession() -> object<nn::apm::ISession>
public long OpenSession(ServiceCtx context)
{
MakeObject(context, new ISession());

View file

@ -1,24 +1,13 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Apm
{
class ISession : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISession()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, SetPerformanceConfiguration },
{ 1, GetPerformanceConfiguration }
};
}
public ISession() { }
[Command(0)]
// SetPerformanceConfiguration(nn::apm::PerformanceMode, nn::apm::PerformanceConfiguration)
public long SetPerformanceConfiguration(ServiceCtx context)
{
PerformanceMode perfMode = (PerformanceMode)context.RequestData.ReadInt32();
@ -27,6 +16,8 @@ namespace Ryujinx.HLE.HOS.Services.Apm
return 0;
}
[Command(1)]
// GetPerformanceConfiguration(nn::apm::PerformanceMode) -> nn::apm::PerformanceConfiguration
public long GetPerformanceConfiguration(ServiceCtx context)
{
PerformanceMode perfMode = (PerformanceMode)context.RequestData.ReadInt32();

View file

@ -4,42 +4,24 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
{
class IAudioOut : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private IAalOutput _audioOut;
private KEvent _releaseEvent;
private int _track;
private KEvent _releaseEvent;
private int _track;
public IAudioOut(IAalOutput audioOut, KEvent releaseEvent, int track)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetAudioOutState },
{ 1, StartAudioOut },
{ 2, StopAudioOut },
{ 3, AppendAudioOutBuffer },
{ 4, RegisterBufferEvent },
{ 5, GetReleasedAudioOutBuffer },
{ 6, ContainsAudioOutBuffer },
{ 7, AppendAudioOutBufferAuto },
{ 8, GetReleasedAudioOutBufferAuto }
};
_audioOut = audioOut;
_releaseEvent = releaseEvent;
_track = track;
}
[Command(0)]
// GetAudioOutState() -> u32 state
public long GetAudioOutState(ServiceCtx context)
{
context.ResponseData.Write((int)_audioOut.GetState(_track));
@ -47,6 +29,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
return 0;
}
[Command(1)]
// StartAudioOut()
public long StartAudioOut(ServiceCtx context)
{
_audioOut.Start(_track);
@ -54,6 +38,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
return 0;
}
[Command(2)]
// StopAudioOut()
public long StopAudioOut(ServiceCtx context)
{
_audioOut.Stop(_track);
@ -61,11 +47,15 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
return 0;
}
[Command(3)]
// AppendAudioOutBuffer(u64 tag, buffer<nn::audio::AudioOutBuffer, 5>)
public long AppendAudioOutBuffer(ServiceCtx context)
{
return AppendAudioOutBufferImpl(context, context.Request.SendBuff[0].Position);
}
[Command(4)]
// RegisterBufferEvent() -> handle<copy>
public long RegisterBufferEvent(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_releaseEvent.ReadableEvent, out int handle) != KernelResult.Success)
@ -78,6 +68,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
return 0;
}
[Command(5)]
// GetReleasedAudioOutBuffer() -> (u32 count, buffer<nn::audio::AudioOutBuffer, 6>)
public long GetReleasedAudioOutBuffer(ServiceCtx context)
{
long position = context.Request.ReceiveBuff[0].Position;
@ -86,6 +78,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
return GetReleasedAudioOutBufferImpl(context, position, size);
}
[Command(6)]
// ContainsAudioOutBuffer(u64 tag) -> b8
public long ContainsAudioOutBuffer(ServiceCtx context)
{
long tag = context.RequestData.ReadInt64();
@ -95,6 +89,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
return 0;
}
[Command(7)] // 3.0.0+
// AppendAudioOutBufferAuto(u64 tag, buffer<nn::audio::AudioOutBuffer, 0x21>)
public long AppendAudioOutBufferAuto(ServiceCtx context)
{
(long position, long size) = context.Request.GetBufferType0x21();
@ -119,6 +115,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
return 0;
}
[Command(8)] // 3.0.0+
// GetReleasedAudioOutBufferAuto() -> (u32 count, buffer<nn::audio::AudioOutBuffer, 0x22>)
public long GetReleasedAudioOutBufferAuto(ServiceCtx context)
{
(long position, long size) = context.Request.GetBufferType0x22();
@ -162,4 +160,4 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
}
}
}
}
}

View file

@ -7,7 +7,6 @@ using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.Utilities;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
@ -23,10 +22,6 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
// high latency).
private const int MixBufferSamplesCount = 960;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent _updateEvent;
private MemoryManager _memory;
@ -49,18 +44,6 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
IAalOutput audioOut,
AudioRendererParameter Params)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetSampleRate },
{ 1, GetSampleCount },
{ 2, GetMixBufferCount },
{ 3, GetState },
{ 4, RequestUpdateAudioRenderer },
{ 5, StartAudioRenderer },
{ 6, StopAudioRenderer },
{ 7, QuerySystemEvent }
};
_updateEvent = new KEvent(system);
_memory = memory;
@ -81,7 +64,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
_playState = PlayState.Stopped;
}
// GetSampleRate() -> u32
[Command(0)]
// GetSampleRate() -> u32
public long GetSampleRate(ServiceCtx context)
{
context.ResponseData.Write(_params.SampleRate);
@ -89,7 +73,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
return 0;
}
// GetSampleCount() -> u32
[Command(1)]
// GetSampleCount() -> u32
public long GetSampleCount(ServiceCtx context)
{
context.ResponseData.Write(_params.SampleCount);
@ -97,6 +82,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
return 0;
}
[Command(2)]
// GetMixBufferCount() -> u32
public long GetMixBufferCount(ServiceCtx context)
{
@ -105,6 +91,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
return 0;
}
[Command(3)]
// GetState() -> u32
private long GetState(ServiceCtx context)
{
@ -141,6 +128,9 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
_audioOut.Start(_track);
}
[Command(4)]
// RequestUpdateAudioRenderer(buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 5>)
// -> (buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 6>, buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 6>)
public long RequestUpdateAudioRenderer(ServiceCtx context)
{
long outputPosition = context.Request.ReceiveBuff[0].Position;
@ -247,6 +237,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
return 0;
}
[Command(5)]
// Start()
public long StartAudioRenderer(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAudio);
@ -256,6 +248,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
return 0;
}
[Command(6)]
// Stop()
public long StopAudioRenderer(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAudio);
@ -265,6 +259,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
return 0;
}
[Command(7)]
// QuerySystemEvent() -> handle<copy, event>
public long QuerySystemEvent(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_updateEvent.ReadableEvent, out int handle) != KernelResult.Success)
@ -405,4 +401,4 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
}
}
}
}
}

View file

@ -4,42 +4,24 @@ using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.SystemState;
using System;
using System.Collections.Generic;
using System.Text;
namespace Ryujinx.HLE.HOS.Services.Aud
{
class IAudioDevice : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent _systemEvent;
public IAudioDevice(Horizon system)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, ListAudioDeviceName },
{ 1, SetAudioDeviceOutputVolume },
{ 3, GetActiveAudioDeviceName },
{ 4, QueryAudioDeviceSystemEvent },
{ 5, GetActiveChannelCount },
{ 6, ListAudioDeviceNameAuto },
{ 7, SetAudioDeviceOutputVolumeAuto },
{ 8, GetAudioDeviceOutputVolumeAuto },
{ 10, GetActiveAudioDeviceNameAuto },
{ 11, QueryAudioDeviceInputEvent },
{ 12, QueryAudioDeviceOutputEvent }
};
_systemEvent = new KEvent(system);
// TODO: We shouldn't be signaling this here.
_systemEvent.ReadableEvent.Signal();
}
[Command(0)]
// ListAudioDeviceName() -> (u32, buffer<bytes, 6>)
public long ListAudioDeviceName(ServiceCtx context)
{
string[] deviceNames = SystemStateMgr.AudioOutputs;
@ -70,6 +52,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(1)]
// SetAudioDeviceOutputVolume(u32, buffer<bytes, 5>)
public long SetAudioDeviceOutputVolume(ServiceCtx context)
{
float volume = context.RequestData.ReadSingle();
@ -86,6 +70,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(3)]
// GetActiveAudioDeviceName() -> buffer<bytes, 6>
public long GetActiveAudioDeviceName(ServiceCtx context)
{
string name = context.Device.System.State.ActiveAudioOutput;
@ -107,6 +93,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(4)]
// QueryAudioDeviceSystemEvent() -> handle<copy, event>
public long QueryAudioDeviceSystemEvent(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_systemEvent.ReadableEvent, out int handle) != KernelResult.Success)
@ -121,6 +109,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(5)]
// GetActiveChannelCount() -> u32
public long GetActiveChannelCount(ServiceCtx context)
{
context.ResponseData.Write(2);
@ -130,6 +120,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(6)]
// ListAudioDeviceNameAuto() -> (u32, buffer<bytes, 0x22>)
public long ListAudioDeviceNameAuto(ServiceCtx context)
{
string[] deviceNames = SystemStateMgr.AudioOutputs;
@ -159,6 +151,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(7)]
// SetAudioDeviceOutputVolumeAuto(u32, buffer<bytes, 0x21>)
public long SetAudioDeviceOutputVolumeAuto(ServiceCtx context)
{
float volume = context.RequestData.ReadSingle();
@ -174,6 +168,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(8)]
// GetAudioDeviceOutputVolumeAuto(buffer<bytes, 0x21>) -> u32
public long GetAudioDeviceOutputVolumeAuto(ServiceCtx context)
{
context.ResponseData.Write(1f);
@ -183,6 +179,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(10)]
// GetActiveAudioDeviceNameAuto() -> buffer<bytes, 0x22>
public long GetActiveAudioDeviceNameAuto(ServiceCtx context)
{
string name = context.Device.System.State.ActiveAudioOutput;
@ -203,6 +201,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(11)]
// QueryAudioDeviceInputEvent() -> handle<copy, event>
public long QueryAudioDeviceInputEvent(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_systemEvent.ReadableEvent, out int handle) != KernelResult.Success)
@ -217,6 +217,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(12)]
// QueryAudioDeviceOutputEvent() -> handle<copy, event>
public long QueryAudioDeviceOutputEvent(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_systemEvent.ReadableEvent, out int handle) != KernelResult.Success)
@ -231,4 +233,4 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
}
}
}

View file

@ -1,10 +1,8 @@
using ChocolArm64.Memory;
using Ryujinx.Audio;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.Aud.AudioOut;
using System.Collections.Generic;
using System.Text;
using static Ryujinx.HLE.HOS.ErrorCode;
@ -14,27 +12,14 @@ namespace Ryujinx.HLE.HOS.Services.Aud
[Service("audout:u")]
class IAudioOutManager : IpcService
{
private const string DefaultAudioOutput = "DeviceOut";
private const string DefaultAudioOutput = "DeviceOut";
private const int DefaultSampleRate = 48000;
private const int DefaultChannelsCount = 2;
private const int DefaultSampleRate = 48000;
private const int DefaultChannelsCount = 2;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAudioOutManager(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, ListAudioOuts },
{ 1, OpenAudioOut },
{ 2, ListAudioOutsAuto },
{ 3, OpenAudioOutAuto }
};
}
public IAudioOutManager(ServiceCtx context) { }
[Command(0)]
// ListAudioOuts() -> (u32 count, buffer<bytes, 6>)
public long ListAudioOuts(ServiceCtx context)
{
return ListAudioOutsImpl(
@ -43,6 +28,9 @@ namespace Ryujinx.HLE.HOS.Services.Aud
context.Request.ReceiveBuff[0].Size);
}
[Command(1)]
// OpenAudioOut(u32 sample_rate, u16 unused, u16 channel_count, nn::applet::AppletResourceUserId, pid, handle<copy, process>, buffer<bytes, 5> name_in)
// -> (u32 sample_rate, u32 channel_count, u32 pcm_format, u32, object<nn::audio::detail::IAudioOut>, buffer<bytes, 6> name_out)
public long OpenAudioOut(ServiceCtx context)
{
return OpenAudioOutImpl(
@ -53,6 +41,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
context.Request.ReceiveBuff[0].Size);
}
[Command(2)] // 3.0.0+
// ListAudioOutsAuto() -> (u32 count, buffer<bytes, 0x22>)
public long ListAudioOutsAuto(ServiceCtx context)
{
(long recvPosition, long recvSize) = context.Request.GetBufferType0x22();
@ -60,6 +50,9 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return ListAudioOutsImpl(context, recvPosition, recvSize);
}
[Command(3)] // 3.0.0+
// OpenAudioOutAuto(u32 sample_rate, u16 unused, u16 channel_count, nn::applet::AppletResourceUserId, pid, handle<copy, process>, buffer<bytes, 0x21>)
// -> (u32 sample_rate, u32 channel_count, u32 pcm_format, u32, object<nn::audio::detail::IAudioOut>, buffer<bytes, 0x22> name_out)
public long OpenAudioOutAuto(ServiceCtx context)
{
(long sendPosition, long sendSize) = context.Request.GetBufferType0x21();
@ -168,4 +161,4 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
}
}
}

View file

@ -1,9 +1,7 @@
using Ryujinx.Audio;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Services.Aud.AudioRenderer;
using Ryujinx.HLE.Utilities;
using System.Collections.Generic;
using static Ryujinx.HLE.HOS.ErrorCode;
@ -21,21 +19,11 @@ namespace Ryujinx.HLE.HOS.Services.Aud
public const int RevMagic = Rev0Magic + (Rev << 24);
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAudioRendererManager(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, OpenAudioRenderer },
{ 1, GetAudioRendererWorkBufferSize },
{ 2, GetAudioDeviceService },
{ 4, GetAudioDeviceServiceWithRevisionInfo }
};
}
public IAudioRendererManager(ServiceCtx context) { }
[Command(0)]
// OpenAudioRenderer(nn::audio::detail::AudioRendererParameterInternal, u64, nn::applet::AppletResourceUserId, pid, handle<copy>, handle<copy>)
// -> object<nn::audio::detail::IAudioRenderer>
public long OpenAudioRenderer(ServiceCtx context)
{
IAalOutput audioOut = context.Device.AudioOut;
@ -51,6 +39,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(1)]
// GetWorkBufferSize(nn::audio::detail::AudioRendererParameterInternal) -> u64
public long GetAudioRendererWorkBufferSize(ServiceCtx context)
{
AudioRendererParameter Params = GetAudioRendererParameter(context);
@ -178,6 +168,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return result / 8;
}
[Command(2)]
// GetAudioDeviceService(nn::applet::AppletResourceUserId) -> object<nn::audio::detail::IAudioDevice>
public long GetAudioDeviceService(ServiceCtx context)
{
@ -188,6 +179,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(4)] // 4.0.0+
// GetAudioDeviceServiceWithRevisionInfo(nn::applet::AppletResourceUserId, u32) -> object<nn::audio::detail::IAudioDevice>
private long GetAudioDeviceServiceWithRevisionInfo(ServiceCtx context)
{

View file

@ -1,6 +1,4 @@
using Concentus.Structs;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
using static Ryujinx.HLE.HOS.ErrorCode;
@ -10,10 +8,6 @@ namespace Ryujinx.HLE.HOS.Services.Aud
{
private const int FixedSampleRate = 48000;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private int _sampleRate;
private int _channelsCount;
@ -21,29 +15,14 @@ namespace Ryujinx.HLE.HOS.Services.Aud
public IHardwareOpusDecoder(int sampleRate, int channelsCount)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, DecodeInterleaved },
{ 4, DecodeInterleavedWithPerf }
};
_sampleRate = sampleRate;
_channelsCount = channelsCount;
_decoder = new OpusDecoder(FixedSampleRate, channelsCount);
}
public long DecodeInterleavedWithPerf(ServiceCtx context)
{
long result = DecodeInterleaved(context);
// TODO: Figure out what this value is.
// According to switchbrew, it is now used.
context.ResponseData.Write(0L);
return result;
}
[Command(0)]
// DecodeInterleaved(buffer<unknown, 5>) -> (u32, u32, buffer<unknown, 6>)
public long DecodeInterleaved(ServiceCtx context)
{
long inPosition = context.Request.SendBuff[0].Position;
@ -87,5 +66,18 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(4)]
// DecodeInterleavedWithPerf(buffer<unknown, 5>) -> (u32, u32, u64, buffer<unknown, 0x46>)
public long DecodeInterleavedWithPerf(ServiceCtx context)
{
long result = DecodeInterleaved(context);
// TODO: Figure out what this value is.
// According to switchbrew, it is now used.
context.ResponseData.Write(0L);
return result;
}
}
}
}

View file

@ -1,24 +1,12 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Aud
{
[Service("hwopus")]
class IHardwareOpusDecoderManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IHardwareOpusDecoderManager(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Initialize },
{ 1, GetWorkBufferSize }
};
}
public IHardwareOpusDecoderManager(ServiceCtx context) { }
[Command(0)]
// Initialize(bytes<8, 4>, u32, handle<copy>) -> object<nn::codec::detail::IHardwareOpusDecoder>
public long Initialize(ServiceCtx context)
{
int sampleRate = context.RequestData.ReadInt32();
@ -29,6 +17,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
return 0;
}
[Command(1)]
// GetWorkBufferSize(bytes<8, 4>) -> u32
public long GetWorkBufferSize(ServiceCtx context)
{
// Note: The sample rate is ignored because it is fixed to 48KHz.
@ -70,4 +60,4 @@ namespace Ryujinx.HLE.HOS.Services.Aud
celtSigSize;
}
}
}
}

View file

@ -1,21 +1,7 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Bcat
{
class IBcatService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IBcatService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public IBcatService() { }
}
}
}

View file

@ -1,21 +1,7 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Bcat
{
class IDeliveryCacheStorageService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IDeliveryCacheStorageService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public IDeliveryCacheStorageService() { }
}
}
}

View file

@ -1,6 +1,3 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Bcat
{
[Service("bcat:a")]
@ -9,19 +6,10 @@ namespace Ryujinx.HLE.HOS.Services.Bcat
[Service("bcat:s")]
class IServiceCreator : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IServiceCreator(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, CreateBcatService },
{ 1, CreateDeliveryCacheStorageService }
};
}
public IServiceCreator(ServiceCtx context) { }
[Command(0)]
// CreateBcatService(u64, pid) -> object<nn::bcat::detail::ipc::IBcatService>
public long CreateBcatService(ServiceCtx context)
{
long id = context.RequestData.ReadInt64();
@ -31,6 +19,8 @@ namespace Ryujinx.HLE.HOS.Services.Bcat
return 0;
}
[Command(1)]
// CreateDeliveryCacheStorageService(u64, pid) -> object<nn::bcat::detail::ipc::IDeliveryCacheStorageService>
public long CreateDeliveryCacheStorageService(ServiceCtx context)
{
long id = context.RequestData.ReadInt64();

View file

@ -1,5 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.Utilities;
using System.Collections.Generic;
using System.Net;
@ -100,52 +99,14 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
private List<BsdSocket> _sockets = new List<BsdSocket>();
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IClient(ServiceCtx context, bool isPrivileged)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, RegisterClient },
{ 1, StartMonitoring },
{ 2, Socket },
{ 3, SocketExempt },
{ 4, Open },
{ 5, Select },
{ 6, Poll },
{ 7, Sysctl },
{ 8, Recv },
{ 9, RecvFrom },
{ 10, Send },
{ 11, SendTo },
{ 12, Accept },
{ 13, Bind },
{ 14, Connect },
{ 15, GetPeerName },
{ 16, GetSockName },
{ 17, GetSockOpt },
{ 18, Listen },
{ 19, Ioctl },
{ 20, Fcntl },
{ 21, SetSockOpt },
{ 22, Shutdown },
{ 23, ShutdownAllSockets },
{ 24, Write },
{ 25, Read },
{ 26, Close },
{ 27, DuplicateSocket }
};
_isPrivileged = isPrivileged;
}
private LinuxError ConvertError(WsaError errorCode)
{
LinuxError errno;
if (!_errorMap.TryGetValue(errorCode, out errno))
if (!_errorMap.TryGetValue(errorCode, out LinuxError errno))
{
errno = (LinuxError)errorCode;
}
@ -259,6 +220,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
WriteSockAddr(context, bufferPosition, endPoint);
}
[Command(0)]
// Initialize(nn::socket::BsdBufferConfig config, u64 pid, u64 transferMemorySize, KObject<copy, transfer_memory>, pid) -> u32 bsd_errno
public long RegisterClient(ServiceCtx context)
{
@ -283,6 +245,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return 0;
}
[Command(1)]
// StartMonitoring(u64, pid)
public long StartMonitoring(ServiceCtx context)
{
@ -293,18 +256,21 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return 0;
}
[Command(2)]
// Socket(u32 domain, u32 type, u32 protocol) -> (i32 ret, u32 bsd_errno)
public long Socket(ServiceCtx context)
{
return SocketInternal(context, false);
}
[Command(3)]
// SocketExempt(u32 domain, u32 type, u32 protocol) -> (i32 ret, u32 bsd_errno)
public long SocketExempt(ServiceCtx context)
{
return SocketInternal(context, true);
}
[Command(4)]
// Open(u32 flags, array<unknown, 0x21> path) -> (i32 ret, u32 bsd_errno)
public long Open(ServiceCtx context)
{
@ -322,6 +288,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return 0;
}
[Command(5)]
// Select(u32 nfds, nn::socket::timeout timeout, buffer<nn::socket::fd_set, 0x21, 0> readfds_in, buffer<nn::socket::fd_set, 0x21, 0> writefds_in, buffer<nn::socket::fd_set, 0x21, 0> errorfds_in) -> (i32 ret, u32 bsd_errno, buffer<nn::socket::fd_set, 0x22, 0> readfds_out, buffer<nn::socket::fd_set, 0x22, 0> writefds_out, buffer<nn::socket::fd_set, 0x22, 0> errorfds_out)
public long Select(ServiceCtx context)
{
@ -332,6 +299,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return 0;
}
[Command(6)]
// Poll(u32 nfds, u32 timeout, buffer<unknown, 0x21, 0> fds) -> (i32 ret, u32 bsd_errno, buffer<unknown, 0x22, 0>)
public long Poll(ServiceCtx context)
{
@ -457,6 +425,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, readEvents.Count + writeEvents.Count + errorEvents.Count, LinuxError.SUCCESS);
}
[Command(7)]
// Sysctl(buffer<unknown, 0x21, 0>, buffer<unknown, 0x21, 0>) -> (i32 ret, u32 bsd_errno, u32, buffer<unknown, 0x22, 0>)
public long Sysctl(ServiceCtx context)
{
@ -467,6 +436,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return 0;
}
[Command(8)]
// Recv(u32 socket, u32 flags) -> (i32 ret, u32 bsd_errno, array<i8, 0x22> message)
public long Recv(ServiceCtx context)
{
@ -506,6 +476,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, result, errno);
}
[Command(9)]
// RecvFrom(u32 sock, u32 flags) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer<i8, 0x22, 0> message, buffer<nn::socket::sockaddr_in, 0x22, 0x10>)
public long RecvFrom(ServiceCtx context)
{
@ -550,6 +521,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, result, errno);
}
[Command(10)]
// Send(u32 socket, u32 flags, buffer<i8, 0x21, 0>) -> (i32 ret, u32 bsd_errno)
public long Send(ServiceCtx context)
{
@ -589,6 +561,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, result, errno);
}
[Command(11)]
// SendTo(u32 socket, u32 flags, buffer<i8, 0x21, 0>, buffer<nn::socket::sockaddr_in, 0x21, 0x10>) -> (i32 ret, u32 bsd_errno)
public long SendTo(ServiceCtx context)
{
@ -630,6 +603,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, result, errno);
}
[Command(12)]
// Accept(u32 socket) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer<nn::socket::sockaddr_in, 0x22, 0x10> addr)
public long Accept(ServiceCtx context)
{
@ -684,6 +658,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, -1, errno);
}
[Command(13)]
// Bind(u32 socket, buffer<nn::socket::sockaddr_in, 0x21, 0x10> addr) -> (i32 ret, u32 bsd_errno)
public long Bind(ServiceCtx context)
{
@ -713,6 +688,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(14)]
// Connect(u32 socket, buffer<nn::socket::sockaddr_in, 0x21, 0x10>) -> (i32 ret, u32 bsd_errno)
public long Connect(ServiceCtx context)
{
@ -741,6 +717,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(15)]
// GetPeerName(u32 socket) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer<nn::socket::sockaddr_in, 0x22, 0x10> addr)
public long GetPeerName(ServiceCtx context)
{
@ -763,6 +740,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(16)]
// GetSockName(u32 socket) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer<nn::socket::sockaddr_in, 0x22, 0x10> addr)
public long GetSockName(ServiceCtx context)
{
@ -785,6 +763,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(17)]
// GetSockOpt(u32 socket, u32 level, u32 option_name) -> (i32 ret, u32 bsd_errno, u32, buffer<unknown, 0x22, 0>)
public long GetSockOpt(ServiceCtx context)
{
@ -814,6 +793,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(18)]
// Listen(u32 socket, u32 backlog) -> (i32 ret, u32 bsd_errno)
public long Listen(ServiceCtx context)
{
@ -840,6 +820,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(19)]
// Ioctl(u32 fd, u32 request, u32 bufcount, buffer<unknown, 0x21, 0>, buffer<unknown, 0x21, 0>, buffer<unknown, 0x21, 0>, buffer<unknown, 0x21, 0>) -> (i32 ret, u32 bsd_errno, buffer<unknown, 0x22, 0>, buffer<unknown, 0x22, 0>, buffer<unknown, 0x22, 0>, buffer<unknown, 0x22, 0>)
public long Ioctl(ServiceCtx context)
{
@ -874,6 +855,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(20)]
// Fcntl(u32 socket, u32 cmd, u32 arg) -> (i32 ret, u32 bsd_errno)
public long Fcntl(ServiceCtx context)
{
@ -995,6 +977,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
}
}
[Command(21)]
// SetSockOpt(u32 socket, u32 level, u32 option_name, buffer<unknown, 0x21, 0> option_value) -> (i32 ret, u32 bsd_errno)
public long SetSockOpt(ServiceCtx context)
{
@ -1024,6 +1007,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(22)]
// Shutdown(u32 socket, u32 how) -> (i32 ret, u32 bsd_errno)
public long Shutdown(ServiceCtx context)
{
@ -1055,6 +1039,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(23)]
// ShutdownAllSockets(u32 how) -> (i32 ret, u32 bsd_errno)
public long ShutdownAllSockets(ServiceCtx context)
{
@ -1086,6 +1071,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(24)]
// Write(u32 socket, buffer<i8, 0x21, 0> message) -> (i32 ret, u32 bsd_errno)
public long Write(ServiceCtx context)
{
@ -1115,6 +1101,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, result, errno);
}
[Command(25)]
// Read(u32 socket) -> (i32 ret, u32 bsd_errno, buffer<i8, 0x22, 0> message)
public long Read(ServiceCtx context)
{
@ -1144,6 +1131,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, result, errno);
}
[Command(26)]
// Close(u32 socket) -> (i32 ret, u32 bsd_errno)
public long Close(ServiceCtx context)
{
@ -1164,6 +1152,7 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, 0, errno);
}
[Command(27)]
// DuplicateSocket(u32 socket, u64 reserved) -> (i32 ret, u32 bsd_errno)
public long DuplicateSocket(ServiceCtx context)
{
@ -1189,4 +1178,4 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
return WriteBsdResult(context, newSockFd, errno);
}
}
}
}

View file

@ -1,21 +1,8 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Caps
{
[Service("caps:a")]
class IAlbumAccessorService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAlbumAccessorService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public IAlbumAccessorService(ServiceCtx context) { }
}
}

View file

@ -1,21 +1,8 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Caps
{
[Service("caps:ss")]
class IScreenshotService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IScreenshotService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public IScreenshotService(ServiceCtx context) { }
}
}

View file

@ -0,0 +1,12 @@
using System;
namespace Ryujinx.HLE.HOS.Services
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class CommandAttribute : Attribute
{
public readonly int Id;
public CommandAttribute(int id) => Id = id;
}
}

View file

@ -1,20 +1,12 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services
namespace Ryujinx.HLE.HOS.Services
{
class DummyService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public string ServiceName { get; set; }
public DummyService(string serviceName)
{
_commands = new Dictionary<int, ServiceProcessRequest>();
ServiceName = serviceName;
}
}
}
}

View file

@ -1,21 +1,8 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Es
namespace Ryujinx.HLE.HOS.Services.Es
{
[Service("es")]
class IeTicketService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IeTicketService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
//...
};
}
public IeTicketService(ServiceCtx context) { }
}
}

View file

@ -1,27 +1,11 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Friend
{
class IDaemonSuspendSessionService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private FriendServicePermissionLevel PermissionLevel;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IDaemonSuspendSessionService(FriendServicePermissionLevel permissionLevel)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
//{ 0, Unknown0 }, // 4.0.0+
//{ 1, Unknown1 }, // 4.0.0+
//{ 2, Unknown2 }, // 4.0.0+
//{ 3, Unknown3 }, // 4.0.0+
//{ 4, Unknown4 }, // 4.0.0+
};
PermissionLevel = permissionLevel;
}
}

View file

@ -1,9 +1,7 @@
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Utilities;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
@ -13,95 +11,16 @@ namespace Ryujinx.HLE.HOS.Services.Friend
{
class IFriendService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private FriendServicePermissionLevel _permissionLevel;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IFriendService(FriendServicePermissionLevel permissionLevel)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
//{ 0, GetCompletionEvent },
//{ 1, Cancel },
{ 10100, GetFriendListIds },
{ 10101, GetFriendList },
//{ 10102, UpdateFriendInfo },
//{ 10110, GetFriendProfileImage },
//{ 10200, SendFriendRequestForApplication },
//{ 10211, AddFacedFriendRequestForApplication },
//{ 10400, GetBlockedUserListIds },
//{ 10500, GetProfileList },
{ 10600, DeclareOpenOnlinePlaySession },
{ 10601, DeclareCloseOnlinePlaySession },
{ 10610, UpdateUserPresence },
//{ 10700, GetPlayHistoryRegistrationKey },
//{ 10701, GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId },
//{ 10702, AddPlayHistory },
//{ 11000, GetProfileImageUrl },
//{ 20100, GetFriendCount },
//{ 20101, GetNewlyFriendCount },
//{ 20102, GetFriendDetailedInfo },
//{ 20103, SyncFriendList },
//{ 20104, RequestSyncFriendList },
//{ 20110, LoadFriendSetting },
//{ 20200, GetReceivedFriendRequestCount },
//{ 20201, GetFriendRequestList },
//{ 20300, GetFriendCandidateList },
//{ 20301, GetNintendoNetworkIdInfo }, // 3.0.0+
//{ 20302, GetSnsAccountLinkage }, // 5.0.0+
//{ 20303, GetSnsAccountProfile }, // 5.0.0+
//{ 20304, GetSnsAccountFriendList }, // 5.0.0+
//{ 20400, GetBlockedUserList },
//{ 20401, SyncBlockedUserList },
//{ 20500, GetProfileExtraList },
//{ 20501, GetRelationship },
//{ 20600, GetUserPresenceView },
//{ 20700, GetPlayHistoryList },
//{ 20701, GetPlayHistoryStatistics },
//{ 20800, LoadUserSetting },
//{ 20801, SyncUserSetting },
//{ 20900, RequestListSummaryOverlayNotification },
//{ 21000, GetExternalApplicationCatalog },
//{ 30100, DropFriendNewlyFlags },
//{ 30101, DeleteFriend },
//{ 30110, DropFriendNewlyFlag },
//{ 30120, ChangeFriendFavoriteFlag },
//{ 30121, ChangeFriendOnlineNotificationFlag },
//{ 30200, SendFriendRequest },
//{ 30201, SendFriendRequestWithApplicationInfo },
//{ 30202, CancelFriendRequest },
//{ 30203, AcceptFriendRequest },
//{ 30204, RejectFriendRequest },
//{ 30205, ReadFriendRequest },
//{ 30210, GetFacedFriendRequestRegistrationKey },
//{ 30211, AddFacedFriendRequest },
//{ 30212, CancelFacedFriendRequest },
//{ 30213, GetFacedFriendRequestProfileImage },
//{ 30214, GetFacedFriendRequestProfileImageFromPath },
//{ 30215, SendFriendRequestWithExternalApplicationCatalogId },
//{ 30216, ResendFacedFriendRequest },
//{ 30217, SendFriendRequestWithNintendoNetworkIdInfo }, // 3.0.0+
//{ 30300, GetSnsAccountLinkPageUrl }, // 5.0.0+
//{ 30301, UnlinkSnsAccount }, // 5.0.0+
//{ 30400, BlockUser },
//{ 30401, BlockUserWithApplicationInfo },
//{ 30402, UnblockUser },
//{ 30500, GetProfileExtraFromFriendCode },
//{ 30700, DeletePlayHistory },
//{ 30810, ChangePresencePermission },
//{ 30811, ChangeFriendRequestReception },
//{ 30812, ChangePlayLogPermission },
//{ 30820, IssueFriendCode },
//{ 30830, ClearPlayLog },
//{ 49900, DeleteNetworkServiceAccountCache },
};
_permissionLevel = permissionLevel;
}
// nn::friends::GetFriendListIds(int offset, nn::account::Uid userUUID, nn::friends::detail::ipc::SizedFriendFilter friendFilter, ulong pidPlaceHolder, pid) -> int outCount, array<nn::account::NetworkServiceAccountId, 0xa>
[Command(10100)]
// nn::friends::GetFriendListIds(int offset, nn::account::Uid userUUID, nn::friends::detail::ipc::SizedFriendFilter friendFilter, ulong pidPlaceHolder, pid)
// -> int outCount, array<nn::account::NetworkServiceAccountId, 0xa>
public long GetFriendListIds(ServiceCtx context)
{
int offset = context.RequestData.ReadInt32();
@ -138,7 +57,9 @@ namespace Ryujinx.HLE.HOS.Services.Friend
return 0;
}
// nn::friends::GetFriendList(int offset, nn::account::Uid userUUID, nn::friends::detail::ipc::SizedFriendFilter friendFilter, ulong pidPlaceHolder, pid) -> int outCount, array<nn::friends::detail::FriendImpl, 0x6>
[Command(10101)]
// nn::friends::GetFriendList(int offset, nn::account::Uid userUUID, nn::friends::detail::ipc::SizedFriendFilter friendFilter, ulong pidPlaceHolder, pid)
// -> int outCount, array<nn::friends::detail::FriendImpl, 0x6>
public long GetFriendList(ServiceCtx context)
{
int offset = context.RequestData.ReadInt32();
@ -174,6 +95,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend
return 0;
}
[Command(10600)]
// nn::friends::DeclareOpenOnlinePlaySession(nn::account::Uid)
public long DeclareOpenOnlinePlaySession(ServiceCtx context)
{
@ -194,6 +116,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend
return 0;
}
[Command(10601)]
// nn::friends::DeclareCloseOnlinePlaySession(nn::account::Uid)
public long DeclareCloseOnlinePlaySession(ServiceCtx context)
{
@ -214,6 +137,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend
return 0;
}
[Command(10610)]
// nn::friends::UpdateUserPresence(nn::account::Uid, u64, pid, buffer<nn::friends::detail::UserPresenceImpl, 0x19>)
public long UpdateUserPresence(ServiceCtx context)
{
@ -244,4 +168,4 @@ namespace Ryujinx.HLE.HOS.Services.Friend
return 0;
}
}
}
}

View file

@ -20,25 +20,13 @@ namespace Ryujinx.HLE.HOS.Services.Friend
private KEvent _notificationEvent;
private int _notificationEventHandle = 0;
private LinkedList<NotificationInfo> _notifications;
private bool _hasNewFriendRequest;
private bool _hasFriendListUpdate;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public INotificationService(ServiceCtx context, UInt128 userId, FriendServicePermissionLevel permissionLevel)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetEvent }, // 2.0.0+
{ 1, Clear }, // 2.0.0+
{ 2, Pop }, // 2.0.0+
};
_userId = userId;
_permissionLevel = permissionLevel;
_notifications = new LinkedList<NotificationInfo>();
@ -50,6 +38,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend
NotificationEventHandler.Instance.RegisterNotificationService(this);
}
[Command(0)] //2.0.0+
// nn::friends::detail::ipc::INotificationService::GetEvent() -> handle<copy>
public long GetEvent(ServiceCtx context)
{
@ -66,6 +55,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend
return 0;
}
[Command(1)] //2.0.0+
// nn::friends::detail::ipc::INotificationService::Clear()
public long Clear(ServiceCtx context)
{
@ -80,6 +70,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend
return 0;
}
[Command(2)] // 2.0.0+
// nn::friends::detail::ipc::INotificationService::Pop() -> nn::friends::detail::ipc::SizedNotificationInfo
public long Pop(ServiceCtx context)
{

View file

@ -1,7 +1,5 @@
using Ryujinx.Common;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.Utilities;
using System.Collections.Generic;
using static Ryujinx.HLE.HOS.ErrorCode;
@ -16,22 +14,12 @@ namespace Ryujinx.HLE.HOS.Services.Friend
{
private FriendServicePermissionLevel _permissionLevel;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IServiceCreator(ServiceCtx context, FriendServicePermissionLevel permissionLevel)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, CreateFriendService },
{ 1, CreateNotificationService }, // 2.0.0+
{ 2, CreateDaemonSuspendSessionService }, // 4.0.0+
};
_permissionLevel = permissionLevel;
}
[Command(0)]
// CreateFriendService() -> object<nn::friends::detail::ipc::IFriendService>
public long CreateFriendService(ServiceCtx context)
{
@ -40,6 +28,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend
return 0;
}
[Command(1)] // 2.0.0+
// CreateNotificationService(nn::account::Uid) -> object<nn::friends::detail::ipc::INotificationService>
public long CreateNotificationService(ServiceCtx context)
{
@ -55,6 +44,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend
return 0;
}
[Command(2)] // 4.0.0+
// CreateDaemonSuspendSessionService() -> object<nn::friends::detail::ipc::IDaemonSuspendSessionService>
public long CreateDaemonSuspendSessionService(ServiceCtx context)
{
@ -63,4 +53,4 @@ namespace Ryujinx.HLE.HOS.Services.Friend
return 0;
}
}
}
}

View file

@ -1,5 +1,4 @@
using LibHac;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
using System.Text;
@ -9,27 +8,17 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{
private const int DirectoryEntrySize = 0x310;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private IEnumerator<LibHac.Fs.DirectoryEntry> _enumerator;
private LibHac.Fs.IDirectory _baseDirectory;
public IDirectory(LibHac.Fs.IDirectory directory)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Read },
{ 1, GetEntryCount }
};
_baseDirectory = directory;
_enumerator = directory.Read().GetEnumerator();
_enumerator = directory.Read().GetEnumerator();
}
[Command(0)]
// Read() -> (u64 count, buffer<nn::fssrv::sf::IDirectoryEntry, 6, 0> entries)
public long Read(ServiceCtx context)
{
@ -76,6 +65,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
context.Memory.WriteInt64(position + 0x308, entry.Size);
}
[Command(1)]
// GetEntryCount() -> u64
public long GetEntryCount(ServiceCtx context)
{

View file

@ -1,33 +1,19 @@
using LibHac;
using LibHac.Fs;
using Ryujinx.HLE.HOS.Ipc;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.FspSrv
{
class IFile : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private LibHac.Fs.IFile _baseFile;
public IFile(LibHac.Fs.IFile baseFile)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Read },
{ 1, Write },
{ 2, Flush },
{ 3, SetSize },
{ 4, GetSize }
};
_baseFile = baseFile;
}
[Command(0)]
// Read(u32 readOption, u64 offset, u64 size) -> (u64 out_size, buffer<u8, 0x46, 0> out_buf)
public long Read(ServiceCtx context)
{
@ -58,6 +44,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(1)]
// Write(u32 writeOption, u64 offset, u64 size, buffer<u8, 0x45, 0>)
public long Write(ServiceCtx context)
{
@ -83,6 +70,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(2)]
// Flush()
public long Flush(ServiceCtx context)
{
@ -98,6 +86,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(3)]
// SetSize(u64 size)
public long SetSize(ServiceCtx context)
{
@ -115,6 +104,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(4)]
// GetSize() -> u64 fileSize
public long GetSize(ServiceCtx context)
{

View file

@ -1,7 +1,5 @@
using LibHac;
using LibHac.Fs;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
using static Ryujinx.HLE.HOS.ErrorCode;
using static Ryujinx.HLE.Utilities.StringUtils;
@ -10,36 +8,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{
class IFileSystem : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private LibHac.Fs.IFileSystem _fileSystem;
public IFileSystem(LibHac.Fs.IFileSystem provider)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, CreateFile },
{ 1, DeleteFile },
{ 2, CreateDirectory },
{ 3, DeleteDirectory },
{ 4, DeleteDirectoryRecursively },
{ 5, RenameFile },
{ 6, RenameDirectory },
{ 7, GetEntryType },
{ 8, OpenFile },
{ 9, OpenDirectory },
{ 10, Commit },
{ 11, GetFreeSpaceSize },
{ 12, GetTotalSpaceSize },
{ 13, CleanDirectoryRecursively },
{ 14, GetFileTimeStampRaw }
};
_fileSystem = provider;
}
[Command(0)]
// CreateFile(u32 createOption, u64 size, buffer<bytes<0x301>, 0x19, 0x301> path)
public long CreateFile(ServiceCtx context)
{
@ -62,6 +38,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(1)]
// DeleteFile(buffer<bytes<0x301>, 0x19, 0x301> path)
public long DeleteFile(ServiceCtx context)
{
@ -79,6 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(2)]
// CreateDirectory(buffer<bytes<0x301>, 0x19, 0x301> path)
public long CreateDirectory(ServiceCtx context)
{
@ -96,6 +74,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(3)]
// DeleteDirectory(buffer<bytes<0x301>, 0x19, 0x301> path)
public long DeleteDirectory(ServiceCtx context)
{
@ -113,6 +92,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(4)]
// DeleteDirectoryRecursively(buffer<bytes<0x301>, 0x19, 0x301> path)
public long DeleteDirectoryRecursively(ServiceCtx context)
{
@ -130,6 +110,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(5)]
// RenameFile(buffer<bytes<0x301>, 0x19, 0x301> oldPath, buffer<bytes<0x301>, 0x19, 0x301> newPath)
public long RenameFile(ServiceCtx context)
{
@ -148,6 +129,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(6)]
// RenameDirectory(buffer<bytes<0x301>, 0x19, 0x301> oldPath, buffer<bytes<0x301>, 0x19, 0x301> newPath)
public long RenameDirectory(ServiceCtx context)
{
@ -166,6 +148,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(7)]
// GetEntryType(buffer<bytes<0x301>, 0x19, 0x301> path) -> nn::fssrv::sf::DirectoryEntryType
public long GetEntryType(ServiceCtx context)
{
@ -192,6 +175,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(8)]
// OpenFile(u32 mode, buffer<bytes<0x301>, 0x19, 0x301> path) -> object<nn::fssrv::sf::IFile> file
public long OpenFile(ServiceCtx context)
{
@ -215,6 +199,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(9)]
// OpenDirectory(u32 filter_flags, buffer<bytes<0x301>, 0x19, 0x301> path) -> object<nn::fssrv::sf::IDirectory> directory
public long OpenDirectory(ServiceCtx context)
{
@ -238,6 +223,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(10)]
// Commit()
public long Commit(ServiceCtx context)
{
@ -253,6 +239,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(11)]
// GetFreeSpaceSize(buffer<bytes<0x301>, 0x19, 0x301> path) -> u64 totalFreeSpace
public long GetFreeSpaceSize(ServiceCtx context)
{
@ -270,6 +257,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(12)]
// GetTotalSpaceSize(buffer<bytes<0x301>, 0x19, 0x301> path) -> u64 totalSize
public long GetTotalSpaceSize(ServiceCtx context)
{
@ -287,6 +275,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(13)]
// CleanDirectoryRecursively(buffer<bytes<0x301>, 0x19, 0x301> path)
public long CleanDirectoryRecursively(ServiceCtx context)
{
@ -304,6 +293,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(14)]
// GetFileTimeStampRaw(buffer<bytes<0x301>, 0x19, 0x301> path) -> bytes<0x20> timestamp
public long GetFileTimeStampRaw(ServiceCtx context)
{

View file

@ -4,9 +4,7 @@ using LibHac.Fs.NcaUtils;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.Utilities;
using System.Collections.Generic;
using System.IO;
using static Ryujinx.HLE.FileSystem.VirtualFileSystem;
@ -18,34 +16,16 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
[Service("fsp-srv")]
class IFileSystemProxy : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IFileSystemProxy(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 1, Initialize },
{ 8, OpenFileSystemWithId },
{ 11, OpenBisFileSystem },
{ 18, OpenSdCardFileSystem },
{ 51, OpenSaveDataFileSystem },
{ 52, OpenSaveDataFileSystemBySystemSaveDataId },
{ 200, OpenDataStorageByCurrentProcess },
{ 202, OpenDataStorageByDataId },
{ 203, OpenPatchDataStorageByCurrentProcess },
{ 1005, GetGlobalAccessLogMode },
{ 1006, OutputAccessLogToSdCard }
};
}
public IFileSystemProxy(ServiceCtx context) { }
[Command(1)]
// Initialize(u64, pid)
public long Initialize(ServiceCtx context)
{
return 0;
}
[Command(8)]
// OpenFileSystemWithId(nn::fssrv::sf::FileSystemType filesystem_type, nn::ApplicationId tid, buffer<bytes<0x301>, 0x19, 0x301> path)
// -> object<nn::fssrv::sf::IFileSystem> contentFs
public long OpenFileSystemWithId(ServiceCtx context)
@ -80,6 +60,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return MakeError(ErrorModule.Fs, FsErr.InvalidInput);
}
[Command(11)]
// OpenBisFileSystem(nn::fssrv::sf::Partition partitionID, buffer<bytes<0x301>, 0x19, 0x301>) -> object<nn::fssrv::sf::IFileSystem> Bis
public long OpenBisFileSystem(ServiceCtx context)
{
@ -112,6 +93,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(18)]
// OpenSdCardFileSystem() -> object<nn::fssrv::sf::IFileSystem>
public long OpenSdCardFileSystem(ServiceCtx context)
{
@ -124,18 +106,21 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(51)]
// OpenSaveDataFileSystem(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object<nn::fssrv::sf::IFileSystem> saveDataFs
public long OpenSaveDataFileSystem(ServiceCtx context)
{
return LoadSaveDataFileSystem(context);
}
[Command(52)]
// OpenSaveDataFileSystemBySystemSaveDataId(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object<nn::fssrv::sf::IFileSystem> systemSaveDataFs
public long OpenSaveDataFileSystemBySystemSaveDataId(ServiceCtx context)
{
return LoadSaveDataFileSystem(context);
}
[Command(200)]
// OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage
public long OpenDataStorageByCurrentProcess(ServiceCtx context)
{
@ -144,6 +129,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(202)]
// OpenDataStorageByDataId(u8 storageId, nn::ApplicationId tid) -> object<nn::fssrv::sf::IStorage> dataStorage
public long OpenDataStorageByDataId(ServiceCtx context)
{
@ -204,6 +190,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
throw new FileNotFoundException($"System archive with titleid {titleId:x16} was not found on Storage {storageId}. Found in {installedStorage}.");
}
[Command(203)]
// OpenPatchDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage>
public long OpenPatchDataStorageByCurrentProcess(ServiceCtx context)
{
@ -212,6 +199,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(1005)]
// GetGlobalAccessLogMode() -> u32 logMode
public long GetGlobalAccessLogMode(ServiceCtx context)
{
@ -222,6 +210,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(1006)]
// OutputAccessLogToSdCard(buffer<bytes, 5> log_text)
public long OutputAccessLogToSdCard(ServiceCtx context)
{

View file

@ -1,28 +1,18 @@
using LibHac;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.FspSrv
{
class IStorage : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private LibHac.Fs.IStorage _baseStorage;
public IStorage(LibHac.Fs.IStorage baseStorage)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Read },
{ 4, GetSize }
};
_baseStorage = baseStorage;
}
[Command(0)]
// Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer
public long Read(ServiceCtx context)
{
@ -56,6 +46,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
[Command(4)]
// GetSize() -> u64 size
public long GetSize(ServiceCtx context)
{
@ -71,4 +62,4 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
}
}
}

View file

@ -1,22 +1,11 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Hid
{
class IActiveApplicationDeviceList : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IActiveApplicationDeviceList()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, ActivateVibrationDevice }
};
}
public IActiveApplicationDeviceList() { }
[Command(0)]
// ActivateVibrationDevice(nn::hid::VibrationDeviceHandle)
public long ActivateVibrationDevice(ServiceCtx context)
{
int vibrationDeviceHandle = context.RequestData.ReadInt32();

View file

@ -2,28 +2,20 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Memory;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Hid
{
class IAppletResource : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KSharedMemory _hidSharedMem;
public IAppletResource(KSharedMemory hidSharedMem)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetSharedMemoryHandle }
};
_hidSharedMem = hidSharedMem;
}
[Command(0)]
// GetSharedMemoryHandle() -> handle<copy>
public long GetSharedMemoryHandle(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_hidSharedMem, out int handle) != KernelResult.Success)

View file

@ -4,15 +4,12 @@ using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.Input;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Hid
{
[Service("hid")]
class IHidServer : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private KEvent _npadStyleSetUpdateEvent;
private KEvent _xpadIdEvent;
private KEvent _palmaOperationCompleteEvent;
@ -39,117 +36,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid
private HidAccelerometerParameters _accelerometerParams;
private HidVibrationValue _vibrationValue;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IHidServer(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, CreateAppletResource },
{ 1, ActivateDebugPad },
{ 11, ActivateTouchScreen },
{ 21, ActivateMouse },
{ 31, ActivateKeyboard },
{ 40, AcquireXpadIdEventHandle },
{ 41, ReleaseXpadIdEventHandle },
{ 51, ActivateXpad },
{ 55, GetXpadIds },
{ 56, ActivateJoyXpad },
{ 58, GetJoyXpadLifoHandle },
{ 59, GetJoyXpadIds },
{ 60, ActivateSixAxisSensor },
{ 61, DeactivateSixAxisSensor },
{ 62, GetSixAxisSensorLifoHandle },
{ 63, ActivateJoySixAxisSensor },
{ 64, DeactivateJoySixAxisSensor },
{ 65, GetJoySixAxisSensorLifoHandle },
{ 66, StartSixAxisSensor },
{ 67, StopSixAxisSensor },
{ 68, IsSixAxisSensorFusionEnabled },
{ 69, EnableSixAxisSensorFusion },
{ 70, SetSixAxisSensorFusionParameters },
{ 71, GetSixAxisSensorFusionParameters },
{ 72, ResetSixAxisSensorFusionParameters },
{ 73, SetAccelerometerParameters },
{ 74, GetAccelerometerParameters },
{ 75, ResetAccelerometerParameters },
{ 76, SetAccelerometerPlayMode },
{ 77, GetAccelerometerPlayMode },
{ 78, ResetAccelerometerPlayMode },
{ 79, SetGyroscopeZeroDriftMode },
{ 80, GetGyroscopeZeroDriftMode },
{ 81, ResetGyroscopeZeroDriftMode },
{ 82, IsSixAxisSensorAtRest },
{ 91, ActivateGesture },
{ 100, SetSupportedNpadStyleSet },
{ 101, GetSupportedNpadStyleSet },
{ 102, SetSupportedNpadIdType },
{ 103, ActivateNpad },
{ 104, DeactivateNpad },
{ 106, AcquireNpadStyleSetUpdateEventHandle },
{ 107, DisconnectNpad },
{ 108, GetPlayerLedPattern },
{ 109, ActivateNpadWithRevision },
{ 120, SetNpadJoyHoldType },
{ 121, GetNpadJoyHoldType },
{ 122, SetNpadJoyAssignmentModeSingleByDefault },
{ 123, SetNpadJoyAssignmentModeSingle },
{ 124, SetNpadJoyAssignmentModeDual },
{ 125, MergeSingleJoyAsDualJoy },
{ 126, StartLrAssignmentMode },
{ 127, StopLrAssignmentMode },
{ 128, SetNpadHandheldActivationMode },
{ 129, GetNpadHandheldActivationMode },
{ 130, SwapNpadAssignment },
{ 131, IsUnintendedHomeButtonInputProtectionEnabled },
{ 132, EnableUnintendedHomeButtonInputProtection },
{ 133, SetNpadJoyAssignmentModeSingleWithDestination },
{ 200, GetVibrationDeviceInfo },
{ 201, SendVibrationValue },
{ 202, GetActualVibrationValue },
{ 203, CreateActiveVibrationDeviceList },
{ 204, PermitVibration },
{ 205, IsVibrationPermitted },
{ 206, SendVibrationValues },
{ 207, SendVibrationGcErmCommand },
{ 208, GetActualVibrationGcErmCommand },
{ 209, BeginPermitVibrationSession },
{ 210, EndPermitVibrationSession },
{ 300, ActivateConsoleSixAxisSensor },
{ 301, StartConsoleSixAxisSensor },
{ 302, StopConsoleSixAxisSensor },
{ 303, ActivateSevenSixAxisSensor },
{ 304, StartSevenSixAxisSensor },
{ 305, StopSevenSixAxisSensor },
{ 306, InitializeSevenSixAxisSensor },
{ 307, FinalizeSevenSixAxisSensor },
{ 308, SetSevenSixAxisSensorFusionStrength },
{ 309, GetSevenSixAxisSensorFusionStrength },
{ 400, IsUsbFullKeyControllerEnabled },
{ 401, EnableUsbFullKeyController },
{ 402, IsUsbFullKeyControllerConnected },
{ 403, HasBattery },
{ 404, HasLeftRightBattery },
{ 405, GetNpadInterfaceType },
{ 406, GetNpadLeftRightInterfaceType },
{ 500, GetPalmaConnectionHandle },
{ 501, InitializePalma },
{ 502, AcquirePalmaOperationCompleteEvent },
{ 503, GetPalmaOperationInfo },
{ 504, PlayPalmaActivity },
{ 505, SetPalmaFrModeType },
{ 506, ReadPalmaStep },
{ 507, EnablePalmaStep },
{ 508, SuspendPalmaStep },
{ 509, ResetPalmaStep },
{ 510, ReadPalmaApplicationSection },
{ 511, WritePalmaApplicationSection },
{ 512, ReadPalmaUniqueCode },
{ 513, SetPalmaUniqueCodeInvalid },
{ 1000, SetNpadCommunicationMode },
{ 1001, GetNpadCommunicationMode }
};
_npadStyleSetUpdateEvent = new KEvent(context.Device.System);
_xpadIdEvent = new KEvent(context.Device.System);
_palmaOperationCompleteEvent = new KEvent(context.Device.System);
@ -168,6 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
_xpadIdEvent.ReadableEvent.Signal();
}
[Command(0)]
// CreateAppletResource(nn::applet::AppletResourceUserId) -> object<nn::hid::IAppletResource>
public long CreateAppletResource(ServiceCtx context)
{
@ -178,6 +67,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(1)]
// ActivateDebugPad(nn::applet::AppletResourceUserId)
public long ActivateDebugPad(ServiceCtx context)
{
@ -188,6 +78,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(11)]
// ActivateTouchScreen(nn::applet::AppletResourceUserId)
public long ActivateTouchScreen(ServiceCtx context)
{
@ -198,6 +89,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(21)]
// ActivateMouse(nn::applet::AppletResourceUserId)
public long ActivateMouse(ServiceCtx context)
{
@ -208,6 +100,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(31)]
// ActivateKeyboard(nn::applet::AppletResourceUserId)
public long ActivateKeyboard(ServiceCtx context)
{
@ -218,6 +111,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(40)]
// AcquireXpadIdEventHandle(ulong XpadId) -> nn::sf::NativeHandle
public long AcquireXpadIdEventHandle(ServiceCtx context)
{
@ -235,6 +129,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(41)]
// ReleaseXpadIdEventHandle(ulong XpadId)
public long ReleaseXpadIdEventHandle(ServiceCtx context)
{
@ -247,6 +142,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(51)]
// ActivateXpad(nn::hid::BasicXpadId, nn::applet::AppletResourceUserId)
public long ActivateXpad(ServiceCtx context)
{
@ -258,6 +154,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(55)]
// GetXpadIds() -> long IdsCount, buffer<array<nn::hid::BasicXpadId>, type: 0xa>
public long GetXpadIds(ServiceCtx context)
{
@ -269,6 +166,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(56)]
// ActivateJoyXpad(nn::hid::JoyXpadId)
public long ActivateJoyXpad(ServiceCtx context)
{
@ -279,6 +177,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(58)]
// GetJoyXpadLifoHandle(nn::hid::JoyXpadId) -> nn::sf::NativeHandle
public long GetJoyXpadLifoHandle(ServiceCtx context)
{
@ -293,6 +192,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(59)]
// GetJoyXpadIds() -> long IdsCount, buffer<array<nn::hid::JoyXpadId>, type: 0xa>
public long GetJoyXpadIds(ServiceCtx context)
{
@ -304,6 +204,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(60)]
// ActivateSixAxisSensor(nn::hid::BasicXpadId)
public long ActivateSixAxisSensor(ServiceCtx context)
{
@ -314,6 +215,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(61)]
// DeactivateSixAxisSensor(nn::hid::BasicXpadId)
public long DeactivateSixAxisSensor(ServiceCtx context)
{
@ -324,6 +226,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(62)]
// GetSixAxisSensorLifoHandle(nn::hid::BasicXpadId) -> nn::sf::NativeHandle
public long GetSixAxisSensorLifoHandle(ServiceCtx context)
{
@ -338,6 +241,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(63)]
// ActivateJoySixAxisSensor(nn::hid::JoyXpadId)
public long ActivateJoySixAxisSensor(ServiceCtx context)
{
@ -348,6 +252,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(64)]
// DeactivateJoySixAxisSensor(nn::hid::JoyXpadId)
public long DeactivateJoySixAxisSensor(ServiceCtx context)
{
@ -358,6 +263,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(65)]
// GetJoySixAxisSensorLifoHandle(nn::hid::JoyXpadId) -> nn::sf::NativeHandle
public long GetJoySixAxisSensorLifoHandle(ServiceCtx context)
{
@ -372,6 +278,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(66)]
// StartSixAxisSensor(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public long StartSixAxisSensor(ServiceCtx context)
{
@ -383,6 +290,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(67)]
// StopSixAxisSensor(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public long StopSixAxisSensor(ServiceCtx context)
{
@ -394,6 +302,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(68)]
// IsSixAxisSensorFusionEnabled(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsEnabled
public long IsSixAxisSensorFusionEnabled(ServiceCtx context)
{
@ -407,6 +316,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(69)]
// EnableSixAxisSensorFusion(bool Enabled, nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public long EnableSixAxisSensorFusion(ServiceCtx context)
{
@ -419,6 +329,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(70)]
// SetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, float RevisePower, float ReviseRange, nn::applet::AppletResourceUserId)
public long SetSixAxisSensorFusionParameters(ServiceCtx context)
{
@ -437,6 +348,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(71)]
// GetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> float RevisePower, float ReviseRange)
public long GetSixAxisSensorFusionParameters(ServiceCtx context)
{
@ -451,6 +363,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(72)]
// ResetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public long ResetSixAxisSensorFusionParameters(ServiceCtx context)
{
@ -465,6 +378,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(73)]
// SetAccelerometerParameters(nn::hid::SixAxisSensorHandle, float X, float Y, nn::applet::AppletResourceUserId)
public long SetAccelerometerParameters(ServiceCtx context)
{
@ -483,6 +397,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(74)]
// GetAccelerometerParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> float X, float Y
public long GetAccelerometerParameters(ServiceCtx context)
{
@ -497,6 +412,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(75)]
// ResetAccelerometerParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public long ResetAccelerometerParameters(ServiceCtx context)
{
@ -511,6 +427,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(76)]
// SetAccelerometerPlayMode(nn::hid::SixAxisSensorHandle, uint PlayMode, nn::applet::AppletResourceUserId)
public long SetAccelerometerPlayMode(ServiceCtx context)
{
@ -523,6 +440,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(77)]
// GetAccelerometerPlayMode(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> uint PlayMode
public long GetAccelerometerPlayMode(ServiceCtx context)
{
@ -536,6 +454,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(78)]
// ResetAccelerometerPlayMode(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public long ResetAccelerometerPlayMode(ServiceCtx context)
{
@ -549,6 +468,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(79)]
// SetGyroscopeZeroDriftMode(nn::hid::SixAxisSensorHandle, uint GyroscopeZeroDriftMode, nn::applet::AppletResourceUserId)
public long SetGyroscopeZeroDriftMode(ServiceCtx context)
{
@ -561,6 +481,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(80)]
// GetGyroscopeZeroDriftMode(nn::applet::AppletResourceUserId, nn::hid::SixAxisSensorHandle) -> int GyroscopeZeroDriftMode
public long GetGyroscopeZeroDriftMode(ServiceCtx context)
{
@ -574,6 +495,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(81)]
// ResetGyroscopeZeroDriftMode(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public long ResetGyroscopeZeroDriftMode(ServiceCtx context)
{
@ -587,6 +509,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(82)]
// IsSixAxisSensorAtRest(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsAsRest
public long IsSixAxisSensorAtRest(ServiceCtx context)
{
@ -602,6 +525,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(91)]
// ActivateGesture(nn::applet::AppletResourceUserId, int Unknown0)
public long ActivateGesture(ServiceCtx context)
{
@ -613,7 +537,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(100)]
// SetSupportedNpadStyleSet(nn::applet::AppletResourceUserId, nn::hid::NpadStyleTag)
public long SetSupportedNpadStyleSet(ServiceCtx context)
{
@ -628,6 +552,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(101)]
// GetSupportedNpadStyleSet(nn::applet::AppletResourceUserId) -> uint nn::hid::NpadStyleTag
public long GetSupportedNpadStyleSet(ServiceCtx context)
{
@ -640,6 +565,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(102)]
// SetSupportedNpadIdType(nn::applet::AppletResourceUserId, array<NpadIdType, 9>)
public long SetSupportedNpadIdType(ServiceCtx context)
{
@ -651,6 +577,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(103)]
// ActivateNpad(nn::applet::AppletResourceUserId)
public long ActivateNpad(ServiceCtx context)
{
@ -661,6 +588,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(104)]
// DeactivateNpad(nn::applet::AppletResourceUserId)
public long DeactivateNpad(ServiceCtx context)
{
@ -671,6 +599,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(106)]
// AcquireNpadStyleSetUpdateEventHandle(nn::applet::AppletResourceUserId, uint, ulong) -> nn::sf::NativeHandle
public long AcquireNpadStyleSetUpdateEventHandle(ServiceCtx context)
{
@ -690,6 +619,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(107)]
// DisconnectNpad(nn::applet::AppletResourceUserId, uint NpadIdType)
public long DisconnectNpad(ServiceCtx context)
{
@ -701,6 +631,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(108)]
// GetPlayerLedPattern(uint NpadId) -> ulong LedPattern
public long GetPlayerLedPattern(ServiceCtx context)
{
@ -715,6 +646,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(109)] // 5.0.0+
// ActivateNpadWithRevision(nn::applet::AppletResourceUserId, int Unknown)
public long ActivateNpadWithRevision(ServiceCtx context)
{
@ -726,6 +658,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(120)]
// SetNpadJoyHoldType(nn::applet::AppletResourceUserId, long NpadJoyHoldType)
public long SetNpadJoyHoldType(ServiceCtx context)
{
@ -737,6 +670,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(121)]
// GetNpadJoyHoldType(nn::applet::AppletResourceUserId) -> long NpadJoyHoldType
public long GetNpadJoyHoldType(ServiceCtx context)
{
@ -749,6 +683,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(122)]
// SetNpadJoyAssignmentModeSingleByDefault(uint HidControllerId, nn::applet::AppletResourceUserId)
public long SetNpadJoyAssignmentModeSingleByDefault(ServiceCtx context)
{
@ -762,6 +697,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(123)]
// SetNpadJoyAssignmentModeSingle(uint HidControllerId, nn::applet::AppletResourceUserId, long HidNpadJoyDeviceType)
public long SetNpadJoyAssignmentModeSingle(ServiceCtx context)
{
@ -776,6 +712,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(124)]
// SetNpadJoyAssignmentModeDual(uint HidControllerId, nn::applet::AppletResourceUserId)
public long SetNpadJoyAssignmentModeDual(ServiceCtx context)
{
@ -789,6 +726,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(125)]
// MergeSingleJoyAsDualJoy(uint SingleJoyId0, uint SingleJoyId1, nn::applet::AppletResourceUserId)
public long MergeSingleJoyAsDualJoy(ServiceCtx context)
{
@ -801,6 +739,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(126)]
// StartLrAssignmentMode(nn::applet::AppletResourceUserId)
public long StartLrAssignmentMode(ServiceCtx context)
{
@ -811,6 +750,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(127)]
// StopLrAssignmentMode(nn::applet::AppletResourceUserId)
public long StopLrAssignmentMode(ServiceCtx context)
{
@ -821,6 +761,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(128)]
// SetNpadHandheldActivationMode(nn::applet::AppletResourceUserId, long HidNpadHandheldActivationMode)
public long SetNpadHandheldActivationMode(ServiceCtx context)
{
@ -832,6 +773,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(129)]
// GetNpadHandheldActivationMode(nn::applet::AppletResourceUserId) -> long HidNpadHandheldActivationMode
public long GetNpadHandheldActivationMode(ServiceCtx context)
{
@ -844,6 +786,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(130)]
// SwapNpadAssignment(uint OldNpadAssignment, uint NewNpadAssignment, nn::applet::AppletResourceUserId)
public long SwapNpadAssignment(ServiceCtx context)
{
@ -856,6 +799,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(131)]
// IsUnintendedHomeButtonInputProtectionEnabled(uint Unknown0, nn::applet::AppletResourceUserId) -> bool IsEnabled
public long IsUnintendedHomeButtonInputProtectionEnabled(ServiceCtx context)
{
@ -869,6 +813,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(132)]
// EnableUnintendedHomeButtonInputProtection(bool Enable, uint Unknown0, nn::applet::AppletResourceUserId)
public long EnableUnintendedHomeButtonInputProtection(ServiceCtx context)
{
@ -881,6 +826,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(133)] // 5.0.0+
// SetNpadJoyAssignmentModeSingleWithDestination(uint HidControllerId, long HidNpadJoyDeviceType, nn::applet::AppletResourceUserId) -> bool Unknown0, uint Unknown1
public long SetNpadJoyAssignmentModeSingleWithDestination(ServiceCtx context)
{
@ -905,6 +851,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(200)]
// GetVibrationDeviceInfo(nn::hid::VibrationDeviceHandle) -> nn::hid::VibrationDeviceInfo
public long GetVibrationDeviceInfo(ServiceCtx context)
{
@ -924,6 +871,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(201)]
// SendVibrationValue(nn::hid::VibrationDeviceHandle, nn::hid::VibrationValue, nn::applet::AppletResourceUserId)
public long SendVibrationValue(ServiceCtx context)
{
@ -951,6 +899,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(202)]
// GetActualVibrationValue(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId) -> nn::hid::VibrationValue
public long GetActualVibrationValue(ServiceCtx context)
{
@ -974,6 +923,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(203)]
// CreateActiveVibrationDeviceList() -> object<nn::hid::IActiveVibrationDeviceList>
public long CreateActiveVibrationDeviceList(ServiceCtx context)
{
@ -982,6 +932,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(204)]
// PermitVibration(bool Enable)
public long PermitVibration(ServiceCtx context)
{
@ -992,6 +943,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(205)]
// IsVibrationPermitted() -> bool IsEnabled
public long IsVibrationPermitted(ServiceCtx context)
{
@ -1002,6 +954,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(206)]
// SendVibrationValues(nn::applet::AppletResourceUserId, buffer<array<nn::hid::VibrationDeviceHandle>, type: 9>, buffer<array<nn::hid::VibrationValue>, type: 9>)
public long SendVibrationValues(ServiceCtx context)
{
@ -1026,6 +979,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(207)] // 4.0.0+
// SendVibrationGcErmCommand(nn::hid::VibrationDeviceHandle, nn::hid::VibrationGcErmCommand, nn::applet::AppletResourceUserId)
public long SendVibrationGcErmCommand(ServiceCtx context)
{
@ -1038,6 +992,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(208)] // 4.0.0+
// GetActualVibrationGcErmCommand(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId) -> nn::hid::VibrationGcErmCommand
public long GetActualVibrationGcErmCommand(ServiceCtx context)
{
@ -1051,6 +1006,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(209)] // 4.0.0+
// BeginPermitVibrationSession(nn::applet::AppletResourceUserId)
public long BeginPermitVibrationSession(ServiceCtx context)
{
@ -1061,6 +1017,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(210)] // 4.0.0+
// EndPermitVibrationSession()
public long EndPermitVibrationSession(ServiceCtx context)
{
@ -1069,6 +1026,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(300)]
// ActivateConsoleSixAxisSensor(nn::applet::AppletResourceUserId)
public long ActivateConsoleSixAxisSensor(ServiceCtx context)
{
@ -1079,6 +1037,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(301)]
// StartConsoleSixAxisSensor(nn::hid::ConsoleSixAxisSensorHandle, nn::applet::AppletResourceUserId)
public long StartConsoleSixAxisSensor(ServiceCtx context)
{
@ -1090,6 +1049,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(302)]
// StopConsoleSixAxisSensor(nn::hid::ConsoleSixAxisSensorHandle, nn::applet::AppletResourceUserId)
public long StopConsoleSixAxisSensor(ServiceCtx context)
{
@ -1101,6 +1061,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(303)] // 5.0.0+
// ActivateSevenSixAxisSensor(nn::applet::AppletResourceUserId)
public long ActivateSevenSixAxisSensor(ServiceCtx context)
{
@ -1111,6 +1072,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(304)] // 5.0.0+
// StartSevenSixAxisSensor(nn::applet::AppletResourceUserId)
public long StartSevenSixAxisSensor(ServiceCtx context)
{
@ -1121,6 +1083,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(305)] // 5.0.0+
// StopSevenSixAxisSensor(nn::applet::AppletResourceUserId)
public long StopSevenSixAxisSensor(ServiceCtx context)
{
@ -1131,6 +1094,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(306)] // 5.0.0+
// InitializeSevenSixAxisSensor(array<nn::sf::NativeHandle>, ulong Counter0, array<nn::sf::NativeHandle>, ulong Counter1, nn::applet::AppletResourceUserId)
public long InitializeSevenSixAxisSensor(ServiceCtx context)
{
@ -1145,6 +1109,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(307)] // 5.0.0+
// FinalizeSevenSixAxisSensor(nn::applet::AppletResourceUserId)
public long FinalizeSevenSixAxisSensor(ServiceCtx context)
{
@ -1155,6 +1120,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(308)] // 5.0.0+
// SetSevenSixAxisSensorFusionStrength(float Strength, nn::applet::AppletResourceUserId)
public long SetSevenSixAxisSensorFusionStrength(ServiceCtx context)
{
@ -1166,6 +1132,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(309)] // 5.0.0+
// GetSevenSixAxisSensorFusionStrength(nn::applet::AppletResourceUserId) -> float Strength
public long GetSevenSixAxisSensorFusionStrength(ServiceCtx context)
{
@ -1178,6 +1145,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(400)]
// IsUsbFullKeyControllerEnabled() -> bool IsEnabled
public long IsUsbFullKeyControllerEnabled(ServiceCtx context)
{
@ -1188,6 +1156,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(401)]
// EnableUsbFullKeyController(bool Enable)
public long EnableUsbFullKeyController(ServiceCtx context)
{
@ -1198,6 +1167,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(402)]
// IsUsbFullKeyControllerConnected(uint Unknown0) -> bool Connected
public long IsUsbFullKeyControllerConnected(ServiceCtx context)
{
@ -1210,6 +1180,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(403)] // 4.0.0+
// HasBattery(uint NpadId) -> bool HasBattery
public long HasBattery(ServiceCtx context)
{
@ -1222,6 +1193,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(404)] // 4.0.0+
// HasLeftRightBattery(uint NpadId) -> bool HasLeftBattery, bool HasRightBattery
public long HasLeftRightBattery(ServiceCtx context)
{
@ -1235,6 +1207,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(405)] // 4.0.0+
// GetNpadInterfaceType(uint NpadId) -> uchar InterfaceType
public long GetNpadInterfaceType(ServiceCtx context)
{
@ -1247,6 +1220,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(406)] // 4.0.0+
// GetNpadLeftRightInterfaceType(uint NpadId) -> uchar LeftInterfaceType, uchar RightInterfaceType
public long GetNpadLeftRightInterfaceType(ServiceCtx context)
{
@ -1260,6 +1234,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(500)] // 5.0.0+
// GetPalmaConnectionHandle(uint Unknown0, nn::applet::AppletResourceUserId) -> nn::hid::PalmaConnectionHandle
public long GetPalmaConnectionHandle(ServiceCtx context)
{
@ -1275,6 +1250,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(501)] // 5.0.0+
// InitializePalma(nn::hid::PalmaConnectionHandle)
public long InitializePalma(ServiceCtx context)
{
@ -1287,6 +1263,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(502)] // 5.0.0+
// AcquirePalmaOperationCompleteEvent(nn::hid::PalmaConnectionHandle) -> nn::sf::NativeHandle
public long AcquirePalmaOperationCompleteEvent(ServiceCtx context)
{
@ -1304,6 +1281,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(503)] // 5.0.0+
// GetPalmaOperationInfo(nn::hid::PalmaConnectionHandle) -> long Unknown0, buffer<Unknown>
public long GetPalmaOperationInfo(ServiceCtx context)
{
@ -1318,6 +1296,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(504)] // 5.0.0+
// PlayPalmaActivity(nn::hid::PalmaConnectionHandle, ulong Unknown0)
public long PlayPalmaActivity(ServiceCtx context)
{
@ -1331,6 +1310,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(505)] // 5.0.0+
// SetPalmaFrModeType(nn::hid::PalmaConnectionHandle, ulong FrModeType)
public long SetPalmaFrModeType(ServiceCtx context)
{
@ -1344,6 +1324,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(506)] // 5.0.0+
// ReadPalmaStep(nn::hid::PalmaConnectionHandle)
public long ReadPalmaStep(ServiceCtx context)
{
@ -1354,6 +1335,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(507)] // 5.0.0+
// EnablePalmaStep(nn::hid::PalmaConnectionHandle, bool Enable)
public long EnablePalmaStep(ServiceCtx context)
{
@ -1367,18 +1349,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
// SuspendPalmaStep(nn::hid::PalmaConnectionHandle)
public long SuspendPalmaStep(ServiceCtx context)
{
int palmaConnectionHandle = context.RequestData.ReadInt32();
Logger.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
_palmaOperationCompleteEvent.ReadableEvent.Signal();
return 0;
}
[Command(508)] // 5.0.0+
// ResetPalmaStep(nn::hid::PalmaConnectionHandle)
public long ResetPalmaStep(ServiceCtx context)
{
@ -1391,6 +1362,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(509)] // 5.0.0+
// ReadPalmaApplicationSection(nn::hid::PalmaConnectionHandle, ulong Unknown0, ulong Unknown1)
public long ReadPalmaApplicationSection(ServiceCtx context)
{
@ -1403,6 +1375,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(510)] // 5.0.0+
// WritePalmaApplicationSection(nn::hid::PalmaConnectionHandle, ulong Unknown0, ulong Unknown1, nn::hid::PalmaApplicationSectionAccessBuffer)
public long WritePalmaApplicationSection(ServiceCtx context)
{
@ -1418,6 +1391,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(511)] // 5.0.0+
// ReadPalmaUniqueCode(nn::hid::PalmaConnectionHandle)
public long ReadPalmaUniqueCode(ServiceCtx context)
{
@ -1428,6 +1402,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(512)] // 5.0.0+
// SetPalmaUniqueCodeInvalid(nn::hid::PalmaConnectionHandle)
public long SetPalmaUniqueCodeInvalid(ServiceCtx context)
{
@ -1438,6 +1413,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(1000)]
// SetNpadCommunicationMode(long CommunicationMode, nn::applet::AppletResourceUserId)
public long SetNpadCommunicationMode(ServiceCtx context)
{
@ -1449,6 +1425,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
[Command(1001)]
// GetNpadCommunicationMode() -> long CommunicationMode
public long GetNpadCommunicationMode(ServiceCtx context)
{

View file

@ -3,7 +3,6 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.Input;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs
{
@ -12,35 +11,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
{
private int _irsensorSharedMemoryHandle = 0;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IIrSensorServer(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 302, ActivateIrsensor },
{ 303, DeactivateIrsensor },
{ 304, GetIrsensorSharedMemoryHandle },
//{ 305, StopImageProcessor },
//{ 306, RunMomentProcessor },
//{ 307, RunClusteringProcessor },
//{ 308, RunImageTransferProcessor },
//{ 309, GetImageTransferProcessorState },
//{ 310, RunTeraPluginProcessor },
{ 311, GetNpadIrCameraHandle },
//{ 312, RunPointingProcessor },
//{ 313, SuspendImageProcessor },
//{ 314, CheckFirmwareVersion }, // 3.0.0+
//{ 315, SetFunctionLevel }, // 4.0.0+
//{ 316, RunImageTransferExProcessor }, // 4.0.0+
//{ 317, RunIrLedProcessor }, // 4.0.0+
//{ 318, StopImageProcessorAsync }, // 4.0.0+
{ 319, ActivateIrsensorWithFunctionLevel }, // 4.0.0+
};
}
public IIrSensorServer(ServiceCtx context) { }
[Command(302)]
// ActivateIrsensor(nn::applet::AppletResourceUserId, pid)
public long ActivateIrsensor(ServiceCtx context)
{
@ -51,6 +24,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
return 0;
}
[Command(303)]
// DeactivateIrsensor(nn::applet::AppletResourceUserId, pid)
public long DeactivateIrsensor(ServiceCtx context)
{
@ -61,6 +35,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
return 0;
}
[Command(304)]
// GetIrsensorSharedMemoryHandle(nn::applet::AppletResourceUserId, pid) -> handle<copy>
public long GetIrsensorSharedMemoryHandle(ServiceCtx context)
{
@ -77,6 +52,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
return 0;
}
[Command(311)]
// GetNpadIrCameraHandle(u32) -> nn::irsensor::IrCameraHandle
public long GetNpadIrCameraHandle(ServiceCtx context)
{
@ -99,6 +75,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
return 0;
}
[Command(319)] // 4.0.0+
// ActivateIrsensorWithFunctionLevel(nn::applet::AppletResourceUserId, nn::irsensor::PackedFunctionLevel, pid)
public long ActivateIrsensorWithFunctionLevel(ServiceCtx context)
{

View file

@ -1,10 +1,10 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
using System.Reflection;
namespace Ryujinx.HLE.HOS.Services
{
interface IIpcService
{
IReadOnlyDictionary<int, ServiceProcessRequest> Commands { get; }
IReadOnlyDictionary<int, MethodInfo> Commands { get; }
}
}

View file

@ -7,12 +7,14 @@ using System;
using System.Collections.Generic;
using System.IO;
using Ryujinx.Profiler;
using System.Reflection;
using System.Linq;
namespace Ryujinx.HLE.HOS.Services
{
abstract class IpcService : IIpcService
{
public abstract IReadOnlyDictionary<int, ServiceProcessRequest> Commands { get; }
public IReadOnlyDictionary<int, MethodInfo> Commands { get; }
private IdDictionary _domainObjects;
@ -22,6 +24,13 @@ namespace Ryujinx.HLE.HOS.Services
public IpcService()
{
Commands = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => type == GetType())
.SelectMany(type => type.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public))
.SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandAttribute))
.Select(command => (((CommandAttribute)command).Id, methodInfo)))
.ToDictionary(command => command.Id, command => command.methodInfo);
_domainObjects = new IdDictionary();
_selfId = -1;
@ -90,7 +99,7 @@ namespace Ryujinx.HLE.HOS.Services
long sfciMagic = context.RequestData.ReadInt64();
int commandId = (int)context.RequestData.ReadInt64();
bool serviceExists = service.Commands.TryGetValue(commandId, out ServiceProcessRequest processRequest);
bool serviceExists = service.Commands.TryGetValue(commandId, out MethodInfo processRequest);
if (ServiceConfiguration.IgnoreMissingServices || serviceExists)
{
@ -100,19 +109,23 @@ namespace Ryujinx.HLE.HOS.Services
if (serviceExists)
{
Logger.PrintDebug(LogClass.KernelIpc, $"{service.GetType().Name}: {processRequest.Method.Name}");
Logger.PrintDebug(LogClass.KernelIpc, $"{service.GetType().Name}: {processRequest.Name}");
ProfileConfig profile = Profiles.ServiceCall;
profile.SessionGroup = service.GetType().Name;
profile.SessionItem = processRequest.Method.Name;
profile.SessionGroup = service.GetType().Name;
profile.SessionItem = processRequest.Name;
Profile.Begin(profile);
result = processRequest(context);
result = (long)processRequest.Invoke(service, new object[] { context });
Profile.End(profile);
}
else
{
string serviceName;
DummyService dummyService = service as DummyService;
serviceName = (dummyService == null) ? service.GetType().FullName : dummyService.ServiceName;

View file

@ -98,10 +98,6 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
[Service("ldr:ro")]
class IRoInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private const int MaxNrr = 0x40;
private const int MaxNro = 0x40;
@ -115,15 +111,6 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
public IRoInterface(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, LoadNro },
{ 1, UnloadNro },
{ 2, LoadNrr },
{ 3, UnloadNrr },
{ 4, Initialize }
};
_nrrInfos = new List<NrrInfo>(MaxNrr);
_nroInfos = new List<NroInfo>(MaxNro);
}
@ -448,6 +435,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return MakeError(ErrorModule.Loader, LoaderErr.BadNroAddress);
}
[Command(0)]
// LoadNro(u64, u64, u64, u64, u64, pid) -> u64
public long LoadNro(ServiceCtx context)
{
@ -485,6 +473,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return result;
}
[Command(1)]
// UnloadNro(u64, u64, pid)
public long UnloadNro(ServiceCtx context)
{
@ -508,6 +497,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return result;
}
[Command(2)]
// LoadNrr(u64, u64, u64, pid)
public long LoadNrr(ServiceCtx context)
{
@ -540,6 +530,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return result;
}
[Command(3)]
// UnloadNrr(u64, u64, pid)
public long UnloadNrr(ServiceCtx context)
{
@ -563,6 +554,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return result;
}
[Command(4)]
// Initialize(u64, pid, KObject)
public long Initialize(ServiceCtx context)
{
@ -572,4 +564,4 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return 0;
}
}
}
}

View file

@ -1,23 +1,12 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Lm
{
[Service("lm")]
class ILogService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ILogService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Initialize }
};
}
public ILogService(ServiceCtx context) { }
[Command(0)]
// Initialize(u64, pid) -> object<nn::lm::ILogger>
public long Initialize(ServiceCtx context)
{
MakeObject(context, new ILogger());

View file

@ -1,6 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
using System.IO;
using System.Text;
@ -8,21 +6,12 @@ namespace Ryujinx.HLE.HOS.Services.Lm
{
class ILogger : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ILogger()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Log }
};
}
public ILogger() { }
[Command(0)]
// Log(buffer<unknown, 0x21>)
public long Log(ServiceCtx context)
{
(long bufPos, long bufSize) = context.Request.GetBufferType0x21();
byte[] logBuffer = context.Memory.ReadBytes(bufPos, bufSize);
@ -94,4 +83,4 @@ namespace Ryujinx.HLE.HOS.Services.Lm
return 0;
}
}
}
}

View file

@ -1,8 +1,6 @@
using LibHac.Fs.NcaUtils;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
using System.Text;
using static Ryujinx.HLE.HOS.ErrorCode;
@ -12,170 +10,41 @@ namespace Ryujinx.HLE.HOS.Services.Lr
{
class ILocationResolver : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private StorageId _storageId;
public ILocationResolver(StorageId storageId)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, ResolveProgramPath },
{ 1, RedirectProgramPath },
{ 2, ResolveApplicationControlPath },
{ 3, ResolveApplicationHtmlDocumentPath },
{ 4, ResolveDataPath },
{ 5, RedirectApplicationControlPath },
{ 6, RedirectApplicationHtmlDocumentPath },
{ 7, ResolveApplicationLegalInformationPath },
{ 8, RedirectApplicationLegalInformationPath },
{ 9, Refresh },
{ 10, SetProgramNcaPath2 },
{ 11, ClearLocationResolver2 },
{ 12, DeleteProgramNcaPath },
{ 13, DeleteControlNcaPath },
{ 14, DeleteDocHtmlNcaPath },
{ 15, DeleteInfoHtmlNcaPath }
};
_storageId = storageId;
}
// DeleteInfoHtmlNcaPath()
public long DeleteInfoHtmlNcaPath(ServiceCtx context)
[Command(0)]
// ResolveProgramPath()
public long ResolveProgramPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Manual);
return 0;
}
// DeleteDocHtmlNcaPath()
public long DeleteDocHtmlNcaPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Manual);
return 0;
}
// DeleteControlNcaPath()
public long DeleteControlNcaPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Control);
return 0;
}
// DeleteProgramNcaPath()
public long DeleteProgramNcaPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Program);
return 0;
}
// ClearLocationResolver2()
public long ClearLocationResolver2(ServiceCtx context)
{
context.Device.System.ContentManager.RefreshEntries(_storageId, 1);
return 0;
}
// SetProgramNcaPath2()
public long SetProgramNcaPath2(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Program);
return 0;
}
// RedirectApplicationControlPath()
public long RedirectApplicationControlPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Control);
return 0;
}
// RedirectApplicationHtmlDocumentPath()
public long RedirectApplicationHtmlDocumentPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Manual);
return 0;
}
// RedirectApplicationLegalInformationPath()
public long RedirectApplicationLegalInformationPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Manual);
return 0;
}
// ResolveDataPath()
public long ResolveDataPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Data) || ResolvePath(context, titleId, ContentType.PublicData))
if (ResolvePath(context, titleId, ContentType.Program))
{
return 0;
}
else
{
return MakeError(ErrorModule.Lr, LrErr.AccessDenied);
return MakeError(ErrorModule.Lr, LrErr.ProgramLocationEntryNotFound);
}
}
// ResolveApplicationHtmlDocumentPath()
public long ResolveApplicationHtmlDocumentPath(ServiceCtx context)
[Command(1)]
// RedirectProgramPath()
public long RedirectProgramPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Manual))
{
return 0;
}
else
{
return MakeError(ErrorModule.Lr, LrErr.AccessDenied);
}
}
// ResolveApplicationLegalInformationPath()
public long ResolveApplicationLegalInformationPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Manual))
{
return 0;
}
else
{
return MakeError(ErrorModule.Lr, LrErr.AccessDenied);
}
RedirectPath(context, titleId, 0, ContentType.Program);
return 0;
}
[Command(2)]
// ResolveApplicationControlPath()
public long ResolveApplicationControlPath(ServiceCtx context)
{
@ -191,16 +60,88 @@ namespace Ryujinx.HLE.HOS.Services.Lr
}
}
// RedirectProgramPath()
public long RedirectProgramPath(ServiceCtx context)
[Command(3)]
// ResolveApplicationHtmlDocumentPath()
public long ResolveApplicationHtmlDocumentPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
RedirectPath(context, titleId, 0, ContentType.Program);
if (ResolvePath(context, titleId, ContentType.Manual))
{
return 0;
}
else
{
return MakeError(ErrorModule.Lr, LrErr.AccessDenied);
}
}
[Command(4)]
// ResolveDataPath()
public long ResolveDataPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Data) || ResolvePath(context, titleId, ContentType.PublicData))
{
return 0;
}
else
{
return MakeError(ErrorModule.Lr, LrErr.AccessDenied);
}
}
[Command(5)]
// RedirectApplicationControlPath()
public long RedirectApplicationControlPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Control);
return 0;
}
[Command(6)]
// RedirectApplicationHtmlDocumentPath()
public long RedirectApplicationHtmlDocumentPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Manual);
return 0;
}
[Command(7)]
// ResolveApplicationLegalInformationPath()
public long ResolveApplicationLegalInformationPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Manual))
{
return 0;
}
else
{
return MakeError(ErrorModule.Lr, LrErr.AccessDenied);
}
}
[Command(8)]
// RedirectApplicationLegalInformationPath()
public long RedirectApplicationLegalInformationPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Manual);
return 0;
}
[Command(9)]
// Refresh()
public long Refresh(ServiceCtx context)
{
@ -209,19 +150,68 @@ namespace Ryujinx.HLE.HOS.Services.Lr
return 0;
}
// ResolveProgramPath()
public long ResolveProgramPath(ServiceCtx context)
[Command(10)]
// SetProgramNcaPath2()
public long SetProgramNcaPath2(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Program))
{
return 0;
}
else
{
return MakeError(ErrorModule.Lr, LrErr.ProgramLocationEntryNotFound);
}
RedirectPath(context, titleId, 1, ContentType.Program);
return 0;
}
[Command(11)]
// ClearLocationResolver2()
public long ClearLocationResolver2(ServiceCtx context)
{
context.Device.System.ContentManager.RefreshEntries(_storageId, 1);
return 0;
}
[Command(12)]
// DeleteProgramNcaPath()
public long DeleteProgramNcaPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Program);
return 0;
}
[Command(13)]
// DeleteControlNcaPath()
public long DeleteControlNcaPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Control);
return 0;
}
[Command(14)]
// DeleteDocHtmlNcaPath()
public long DeleteDocHtmlNcaPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Manual);
return 0;
}
[Command(15)]
// DeleteInfoHtmlNcaPath()
public long DeleteInfoHtmlNcaPath(ServiceCtx context)
{
long titleId = context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Manual);
return 0;
}
private void RedirectPath(ServiceCtx context, long titleId, int flag, ContentType contentType)

View file

@ -1,24 +1,13 @@
using System.Collections.Generic;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem;
namespace Ryujinx.HLE.HOS.Services.Lr
{
[Service("lr")]
class ILocationResolverManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ILocationResolverManager(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, OpenLocationResolver }
};
}
public ILocationResolverManager(ServiceCtx context) { }
[Command(0)]
// OpenLocationResolver()
private long OpenLocationResolver(ServiceCtx context)
{
@ -29,4 +18,4 @@ namespace Ryujinx.HLE.HOS.Services.Lr
return 0;
}
}
}
}

View file

@ -1,31 +1,13 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Mm
{
[Service("mm:u")]
class IRequest : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IRequest(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, InitializeOld },
{ 1, FinalizeOld },
{ 2, SetAndWaitOld },
{ 3, GetOld },
{ 4, Initialize },
{ 5, Finalize },
{ 6, SetAndWait },
{ 7, Get }
};
}
public IRequest(ServiceCtx context) { }
[Command(0)]
// InitializeOld(u32, u32, u32)
public long InitializeOld(ServiceCtx context)
{
@ -38,6 +20,7 @@ namespace Ryujinx.HLE.HOS.Services.Mm
return 0;
}
[Command(1)]
// FinalizeOld(u32)
public long FinalizeOld(ServiceCtx context)
{
@ -48,6 +31,7 @@ namespace Ryujinx.HLE.HOS.Services.Mm
return 0;
}
[Command(2)]
// SetAndWaitOld(u32, u32, u32)
public long SetAndWaitOld(ServiceCtx context)
{
@ -59,6 +43,7 @@ namespace Ryujinx.HLE.HOS.Services.Mm
return 0;
}
[Command(3)]
// GetOld(u32) -> u32
public long GetOld(ServiceCtx context)
{
@ -71,6 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Mm
return 0;
}
[Command(4)]
// Initialize()
public long Initialize(ServiceCtx context)
{
@ -79,6 +65,7 @@ namespace Ryujinx.HLE.HOS.Services.Mm
return 0;
}
[Command(5)]
// Finalize(u32)
public long Finalize(ServiceCtx context)
{
@ -89,6 +76,7 @@ namespace Ryujinx.HLE.HOS.Services.Mm
return 0;
}
[Command(6)]
// SetAndWait(u32, u32, u32)
public long SetAndWait(ServiceCtx context)
{
@ -101,6 +89,7 @@ namespace Ryujinx.HLE.HOS.Services.Mm
return 0;
}
[Command(7)]
// Get(u32) -> u32
public long Get(ServiceCtx context)
{

View file

@ -1,21 +1,8 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ncm
namespace Ryujinx.HLE.HOS.Services.Ncm
{
[Service("ncm")]
class IContentManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IContentManager(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
//...
};
}
public IContentManager(ServiceCtx context) { }
}
}

View file

@ -1,20 +1,7 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ncm
namespace Ryujinx.HLE.HOS.Services.Ncm
{
class IContentStorage : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IContentStorage()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
};
}
public IContentStorage() { }
}
}
}

View file

@ -1,5 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
@ -18,42 +17,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
private List<Device> _devices = new List<Device>();
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IUser()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Initialize },
{ 1, Finalize },
{ 2, ListDevices },
{ 3, StartDetection },
{ 4, StopDetection },
{ 5, Mount },
{ 6, Unmount },
{ 7, OpenApplicationArea },
{ 8, GetApplicationArea },
{ 9, SetApplicationArea },
{ 10, Flush },
{ 11, Restore },
{ 12, CreateApplicationArea },
{ 13, GetTagInfo },
{ 14, GetRegisterInfo },
{ 15, GetCommonInfo },
{ 16, GetModelInfo },
{ 17, AttachActivateEvent },
{ 18, AttachDeactivateEvent },
{ 19, GetState },
{ 20, GetDeviceState },
{ 21, GetNpadId },
{ 22, GetApplicationAreaSize },
{ 23, AttachAvailabilityChangeEvent }, // 3.0.0+
{ 24, RecreateApplicationArea }, // 3.0.0+
};
}
public IUser() { }
[Command(0)]
// Initialize(u64, u64, pid, buffer<unknown, 5>)
public long Initialize(ServiceCtx context)
{
@ -87,6 +53,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
return 0;
}
[Command(1)]
// Finalize()
public long Finalize(ServiceCtx context)
{
@ -101,6 +68,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
return 0;
}
[Command(2)]
// ListDevices() -> (u32, buffer<unknown, 0xa>)
public long ListDevices(ServiceCtx context)
{
@ -127,90 +95,105 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
return 0;
}
[Command(3)]
// StartDetection(bytes<8, 4>)
public long StartDetection(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(4)]
// StopDetection(bytes<8, 4>)
public long StopDetection(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(5)]
// Mount(bytes<8, 4>, u32, u32)
public long Mount(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(6)]
// Unmount(bytes<8, 4>)
public long Unmount(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(7)]
// OpenApplicationArea(bytes<8, 4>, u32)
public long OpenApplicationArea(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(8)]
// GetApplicationArea(bytes<8, 4>) -> (u32, buffer<unknown, 6>)
public long GetApplicationArea(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(9)]
// SetApplicationArea(bytes<8, 4>, buffer<unknown, 5>)
public long SetApplicationArea(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(10)]
// Flush(bytes<8, 4>)
public long Flush(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(11)]
// Restore(bytes<8, 4>)
public long Restore(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(12)]
// CreateApplicationArea(bytes<8, 4>, u32, buffer<unknown, 5>)
public long CreateApplicationArea(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(13)]
// GetTagInfo(bytes<8, 4>) -> buffer<unknown<0x58>, 0x1a>
public long GetTagInfo(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(14)]
// GetRegisterInfo(bytes<8, 4>) -> buffer<unknown<0x100>, 0x1a>
public long GetRegisterInfo(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(15)]
// GetCommonInfo(bytes<8, 4>) -> buffer<unknown<0x40>, 0x1a>
public long GetCommonInfo(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(16)]
// GetModelInfo(bytes<8, 4>) -> buffer<unknown<0x40>, 0x1a>
public long GetModelInfo(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(17)]
// AttachActivateEvent(bytes<8, 4>) -> handle<copy>
public long AttachActivateEvent(ServiceCtx context)
{
@ -239,6 +222,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
return ErrorCode.MakeError(ErrorModule.Nfp, NfpError.DeviceNotFound);
}
[Command(18)]
// AttachDeactivateEvent(bytes<8, 4>) -> handle<copy>
public long AttachDeactivateEvent(ServiceCtx context)
{
@ -267,6 +251,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
return ErrorCode.MakeError(ErrorModule.Nfp, NfpError.DeviceNotFound);
}
[Command(19)]
// GetState() -> u32
public long GetState(ServiceCtx context)
{
@ -275,6 +260,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
return 0;
}
[Command(20)]
// GetDeviceState(bytes<8, 4>) -> u32
public long GetDeviceState(ServiceCtx context)
{
@ -295,6 +281,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
return ErrorCode.MakeError(ErrorModule.Nfp, NfpError.DeviceNotFound);
}
[Command(21)]
// GetNpadId(bytes<8, 4>) -> u32
public long GetNpadId(ServiceCtx context)
{
@ -313,12 +300,14 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
return ErrorCode.MakeError(ErrorModule.Nfp, NfpError.DeviceNotFound);
}
[Command(22)]
// GetApplicationAreaSize(bytes<8, 4>) -> u32
public long GetApplicationAreaSize(ServiceCtx context)
{
throw new ServiceNotImplementedException(context);
}
[Command(23)] // 3.0.0+
// AttachAvailabilityChangeEvent() -> handle<copy>
public long AttachAvailabilityChangeEvent(ServiceCtx context)
{
@ -337,6 +326,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
return 0;
}
[Command(24)] // 3.0.0+
// RecreateApplicationArea(bytes<8, 4>, u32, buffer<unknown, 5>)
public long RecreateApplicationArea(ServiceCtx context)
{

View file

@ -1,23 +1,12 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
{
[Service("nfp:user")]
class IUserManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IUserManager(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetUserInterface }
};
}
public IUserManager(ServiceCtx context) { }
[Command(0)]
// CreateUserInterface() -> object<nn::nfp::detail::IUser>
public long GetUserInterface(ServiceCtx context)
{
MakeObject(context, new IUser());

View file

@ -1,7 +1,5 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
@ -13,19 +11,10 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
{
class IGeneralService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IGeneralService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 4, CreateRequest },
{ 12, GetCurrentIpAddress }
};
}
public IGeneralService() { }
[Command(4)]
// CreateRequest(u32) -> object<nn::nifm::detail::IRequest>
public long CreateRequest(ServiceCtx context)
{
int unknown = context.RequestData.ReadInt32();
@ -37,6 +26,8 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
return 0;
}
[Command(12)]
// GetCurrentIpAddress() -> nn::nifm::IpV4Address
public long GetCurrentIpAddress(ServiceCtx context)
{
if (!NetworkInterface.GetIsNetworkAvailable())
@ -55,4 +46,4 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
return 0;
}
}
}
}

View file

@ -3,35 +3,22 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Nifm
{
class IRequest : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent _event0;
private KEvent _event1;
public IRequest(Horizon system)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetRequestState },
{ 1, GetResult },
{ 2, GetSystemEventReadableHandles },
{ 3, Cancel },
{ 4, Submit },
{ 11, SetConnectionConfirmationOption }
};
_event0 = new KEvent(system);
_event1 = new KEvent(system);
}
[Command(0)]
// GetRequestState() -> u32
public long GetRequestState(ServiceCtx context)
{
context.ResponseData.Write(1);
@ -41,6 +28,8 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
return 0;
}
[Command(1)]
// GetResult()
public long GetResult(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceNifm);
@ -48,6 +37,8 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
return 0;
}
[Command(2)]
// GetSystemEventReadableHandles() -> (handle<copy>, handle<copy>)
public long GetSystemEventReadableHandles(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_event0.ReadableEvent, out int handle0) != KernelResult.Success)
@ -65,6 +56,8 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
return 0;
}
[Command(3)]
// Cancel()
public long Cancel(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceNifm);
@ -72,6 +65,8 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
return 0;
}
[Command(4)]
// Submit()
public long Submit(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceNifm);
@ -79,6 +74,8 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
return 0;
}
[Command(11)]
// SetConnectionConfirmationOption(i8)
public long SetConnectionConfirmationOption(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceNifm);

View file

@ -1,24 +1,12 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Nifm
{
[Service("nifm:u")]
class IStaticService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IStaticService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 4, CreateGeneralServiceOld },
{ 5, CreateGeneralService }
};
}
public IStaticService(ServiceCtx context) { }
[Command(4)]
// CreateGeneralServiceOld() -> object<nn::nifm::detail::IGeneralService>
public long CreateGeneralServiceOld(ServiceCtx context)
{
MakeObject(context, new IGeneralService());
@ -26,6 +14,8 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
return 0;
}
[Command(5)] // 3.0.0+
// CreateGeneralService(u64, pid) -> object<nn::nifm::detail::IGeneralService>
public long CreateGeneralService(ServiceCtx context)
{
MakeObject(context, new IGeneralService());

View file

@ -1,25 +1,14 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ns
{
[Service("aoc:u")]
class IAddOnContentManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAddOnContentManager(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 2, CountAddOnContent },
{ 3, ListAddOnContent }
};
}
public IAddOnContentManager(ServiceCtx context) { }
[Command(2)]
// CountAddOnContent(u64, pid) -> u32
public static long CountAddOnContent(ServiceCtx context)
{
context.ResponseData.Write(0);
@ -29,6 +18,8 @@ namespace Ryujinx.HLE.HOS.Services.Ns
return 0;
}
[Command(3)]
// ListAddOnContent(u32, u32, u64, pid) -> (u32, buffer<u32, 6>)
public static long ListAddOnContent(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceNs);

View file

@ -1,7 +1,5 @@
using LibHac;
using Ryujinx.HLE.HOS.Ipc;
using System;
using System.Collections.Generic;
using System.Text;
namespace Ryujinx.HLE.HOS.Services.Ns
@ -9,18 +7,10 @@ namespace Ryujinx.HLE.HOS.Services.Ns
[Service("ns:am")]
class IApplicationManagerInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IApplicationManagerInterface(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 400, GetApplicationControlData }
};
}
public IApplicationManagerInterface(ServiceCtx context) { }
[Command(400)]
// GetApplicationControlData(unknown<0x10>) -> (unknown<4>, buffer<unknown, 6>)
public long GetApplicationControlData(ServiceCtx context)
{
long position = context.Request.ReceiveBuff[0].Position;
@ -220,4 +210,4 @@ namespace Ryujinx.HLE.HOS.Services.Ns
return 0;
}
}
}
}

View file

@ -1,24 +1,13 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ns
{
[Service("ns:am2")]
[Service("ns:ec")]
class IServiceGetterInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IServiceGetterInterface(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 7996, GetApplicationManagerInterface }
};
}
public IServiceGetterInterface(ServiceCtx context) { }
[Command(7996)]
// GetApplicationManagerInterface() -> object<nn::ns::detail::IApplicationManagerInterface>
public long GetApplicationManagerInterface(ServiceCtx context)
{
MakeObject(context, new IApplicationManagerInterface(context));

View file

@ -1,21 +1,8 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ns
{
[Service("ns:su")]
class ISystemUpdateInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISystemUpdateInterface(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public ISystemUpdateInterface(ServiceCtx context) { }
}
}

View file

@ -1,21 +1,8 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ns
{
[Service("ns:vm")]
class IVulnerabilityManagerInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IVulnerabilityManagerInterface(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public IVulnerabilityManagerInterface(ServiceCtx context) { }
}
}

View file

@ -20,10 +20,6 @@ namespace Ryujinx.HLE.HOS.Services.Nv
{
private delegate int IoctlProcessor(ServiceCtx context, int cmd);
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private static Dictionary<string, IoctlProcessor> _ioctlProcessors =
new Dictionary<string, IoctlProcessor>()
{
@ -42,19 +38,6 @@ namespace Ryujinx.HLE.HOS.Services.Nv
public INvDrvServices(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Open },
{ 1, Ioctl },
{ 2, Close },
{ 3, Initialize },
{ 4, QueryEvent },
{ 8, SetClientPid },
{ 9, DumpGraphicsMemoryInfo },
{ 11, Ioctl },
{ 13, FinishInitialize }
};
_event = new KEvent(context.Device.System);
}
@ -63,6 +46,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
Fds = new GlobalStateTable();
}
[Command(0)]
// Open(buffer<bytes, 5> path) -> (u32 fd, u32 error_code)
public long Open(ServiceCtx context)
{
long namePtr = context.Request.SendBuff[0].Position;
@ -77,6 +62,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv
return 0;
}
[Command(1)]
// Ioctl(u32 fd, u32 rq_id, buffer<bytes, 0x21>) -> (u32 error_code, buffer<bytes, 0x22>)
[Command(11)] // 3.0.0+
// Ioctl2(u32, u32, buffer<bytes, 0x21>, buffer<bytes, 0x21>) -> (u32, buffer<bytes, 0x22>)
public long Ioctl(ServiceCtx context)
{
int fd = context.RequestData.ReadInt32();
@ -101,6 +90,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
return 0;
}
[Command(2)]
// Close(u32 fd) -> u32 error_code
public long Close(ServiceCtx context)
{
int fd = context.RequestData.ReadInt32();
@ -112,6 +103,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
return 0;
}
[Command(3)]
// Initialize(u32 transfer_memory_size, handle<copy, process> current_process, handle<copy, transfer_memory> transfer_memory) -> u32 error_code
public long Initialize(ServiceCtx context)
{
long transferMemSize = context.RequestData.ReadInt64();
@ -124,6 +117,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
return 0;
}
[Command(4)]
// QueryEvent(u32 fd, u32 event_id) -> (u32, handle<copy, event>)
public long QueryEvent(ServiceCtx context)
{
int fd = context.RequestData.ReadInt32();
@ -142,6 +137,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
return 0;
}
[Command(8)]
// SetClientPID(u64, pid) -> u32 error_code
public long SetClientPid(ServiceCtx context)
{
long pid = context.RequestData.ReadInt64();
@ -151,6 +148,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
return 0;
}
[Command(9)]
// DumpGraphicsMemoryInfo()
public long DumpGraphicsMemoryInfo(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceNv);
@ -158,6 +157,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
return 0;
}
[Command(13)]
// FinishInitialize(unknown<8>)
public long FinishInitialize(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceNv);
@ -232,4 +233,4 @@ namespace Ryujinx.HLE.HOS.Services.Nv
NvMapIoctl.UnloadProcess(process);
}
}
}
}

View file

@ -1,30 +1,20 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Pctl
{
class IParentalControlService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private bool _initialized = false;
private bool _needInitialize;
public IParentalControlService(bool needInitialize = true)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 1, Initialize },
{ 1001, CheckFreeCommunicationPermission }
};
_needInitialize = needInitialize;
}
[Command(1)] // 4.0.0+
// Initialize()
public long Initialize(ServiceCtx context)
{
if (_needInitialize && !_initialized)
@ -39,6 +29,8 @@ namespace Ryujinx.HLE.HOS.Services.Pctl
return 0;
}
[Command(1001)]
// CheckFreeCommunicationPermission()
public long CheckFreeCommunicationPermission(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServicePctl);

View file

@ -1,6 +1,3 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Pctl
{
[Service("pctl")]
@ -9,19 +6,10 @@ namespace Ryujinx.HLE.HOS.Services.Pctl
[Service("pctl:s")]
class IParentalControlServiceFactory : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IParentalControlServiceFactory(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, CreateService },
{ 1, CreateServiceWithoutInitialize }
};
}
public IParentalControlServiceFactory(ServiceCtx context) { }
[Command(0)]
// CreateService(u64, pid) -> object<nn::pctl::detail::ipc::IParentalControlService>
public long CreateService(ServiceCtx context)
{
MakeObject(context, new IParentalControlService());
@ -29,6 +17,8 @@ namespace Ryujinx.HLE.HOS.Services.Pctl
return 0;
}
[Command(1)] // 4.0.0+
// CreateServiceWithoutInitialize(u64, pid) -> object<nn::pctl::detail::ipc::IParentalControlService>
public long CreateServiceWithoutInitialize(ServiceCtx context)
{
MakeObject(context, new IParentalControlService(false));

View file

@ -2,30 +2,16 @@ using Ryujinx.HLE.HOS.Font;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Pl
{
[Service("pl:u")]
class ISharedFontManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISharedFontManager(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, RequestLoad },
{ 1, GetLoadState },
{ 2, GetFontSize },
{ 3, GetSharedMemoryAddressOffset },
{ 4, GetSharedMemoryNativeHandle },
{ 5, GetSharedFontInOrderOfPriority }
};
}
public ISharedFontManager(ServiceCtx context) { }
[Command(0)]
// RequestLoad(u32)
public long RequestLoad(ServiceCtx context)
{
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
@ -35,6 +21,8 @@ namespace Ryujinx.HLE.HOS.Services.Pl
return 0;
}
[Command(1)]
// GetLoadState(u32) -> u32
public long GetLoadState(ServiceCtx context)
{
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
@ -46,6 +34,8 @@ namespace Ryujinx.HLE.HOS.Services.Pl
return 0;
}
[Command(2)]
// GetFontSize(u32) -> u32
public long GetFontSize(ServiceCtx context)
{
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
@ -55,6 +45,8 @@ namespace Ryujinx.HLE.HOS.Services.Pl
return 0;
}
[Command(3)]
// GetSharedMemoryAddressOffset(u32) -> u32
public long GetSharedMemoryAddressOffset(ServiceCtx context)
{
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
@ -64,6 +56,8 @@ namespace Ryujinx.HLE.HOS.Services.Pl
return 0;
}
[Command(4)]
// GetSharedMemoryNativeHandle() -> handle<copy>
public long GetSharedMemoryNativeHandle(ServiceCtx context)
{
context.Device.System.Font.EnsureInitialized(context.Device.System.ContentManager);
@ -78,6 +72,8 @@ namespace Ryujinx.HLE.HOS.Services.Pl
return 0;
}
[Command(5)]
// GetSharedFontInOrderOfPriority(bytes<8, 1>) -> (u8, u32, buffer<unknown, 6>, buffer<unknown, 6>, buffer<unknown, 6>)
public long GetSharedFontInOrderOfPriority(ServiceCtx context)
{
long languageCode = context.RequestData.ReadInt64();

View file

@ -1,23 +1,11 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Pm
namespace Ryujinx.HLE.HOS.Services.Pm
{
[Service("pm:shell")]
class IShellInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IShellInterface(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 6, GetApplicationPid }
};
}
public IShellInterface(ServiceCtx context) { }
[Command(6)]
// GetApplicationPid() -> u64
public long GetApplicationPid(ServiceCtx context)
{

View file

@ -1,6 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Prepo
{
@ -8,18 +6,10 @@ namespace Ryujinx.HLE.HOS.Services.Prepo
[Service("prepo:u")]
class IPrepoService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IPrepoService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 10101, SaveReportWithUser }
};
}
public IPrepoService(ServiceCtx context) { }
[Command(10101)]
// SaveReportWithUser(nn::account::Uid, u64, pid, buffer<u8, 9>, buffer<bytes, 5>)
public static long SaveReportWithUser(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServicePrepo);

View file

@ -1,6 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Psm
{
@ -14,20 +12,9 @@ namespace Ryujinx.HLE.HOS.Services.Psm
UsbC
}
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IPsmServer(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetBatteryChargePercentage },
{ 1, GetChargerType },
{ 7, OpenSession }
};
}
public IPsmServer(ServiceCtx context) { }
[Command(0)]
// GetBatteryChargePercentage() -> u32
public static long GetBatteryChargePercentage(ServiceCtx context)
{
@ -40,6 +27,7 @@ namespace Ryujinx.HLE.HOS.Services.Psm
return 0;
}
[Command(1)]
// GetChargerType() -> u32
public static long GetChargerType(ServiceCtx context)
{
@ -52,6 +40,7 @@ namespace Ryujinx.HLE.HOS.Services.Psm
return 0;
}
[Command(7)]
// OpenSession() -> IPsmSession
public long OpenSession(ServiceCtx context)
{

View file

@ -2,34 +2,21 @@
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Psm
{
class IPsmSession : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent _stateChangeEvent;
private int _stateChangeEventHandle;
public IPsmSession(Horizon system)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, BindStateChangeEvent },
{ 1, UnbindStateChangeEvent },
{ 2, SetChargerTypeChangeEventEnabled },
{ 3, SetPowerSupplyChangeEventEnabled },
{ 4, SetBatteryVoltageStateChangeEventEnabled }
};
_stateChangeEvent = new KEvent(system);
_stateChangeEventHandle = -1;
}
[Command(0)]
// BindStateChangeEvent() -> KObject
public long BindStateChangeEvent(ServiceCtx context)
{
@ -50,6 +37,7 @@ namespace Ryujinx.HLE.HOS.Services.Psm
return 0;
}
[Command(1)]
// UnbindStateChangeEvent()
public long UnbindStateChangeEvent(ServiceCtx context)
{
@ -64,6 +52,7 @@ namespace Ryujinx.HLE.HOS.Services.Psm
return 0;
}
[Command(2)]
// SetChargerTypeChangeEventEnabled(u8)
public long SetChargerTypeChangeEventEnabled(ServiceCtx context)
{
@ -74,6 +63,7 @@ namespace Ryujinx.HLE.HOS.Services.Psm
return 0;
}
[Command(3)]
// SetPowerSupplyChangeEventEnabled(u8)
public long SetPowerSupplyChangeEventEnabled(ServiceCtx context)
{
@ -84,6 +74,7 @@ namespace Ryujinx.HLE.HOS.Services.Psm
return 0;
}
[Command(4)]
// SetBatteryVoltageStateChangeEventEnabled(u8)
public long SetBatteryVoltageStateChangeEventEnabled(ServiceCtx context)
{

View file

@ -1,8 +1,6 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.SystemState;
using System;
using System.Collections.Generic;
using static Ryujinx.HLE.HOS.ErrorCode;
@ -11,27 +9,9 @@ namespace Ryujinx.HLE.HOS.Services.Set
[Service("set")]
class ISettingsServer : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISettingsServer(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetLanguageCode },
{ 1, GetAvailableLanguageCodes },
{ 2, MakeLanguageCode }, // 4.0.0+
{ 3, GetAvailableLanguageCodeCount },
//{ 4, GetRegionCode },
{ 5, GetAvailableLanguageCodes2 },
{ 6, GetAvailableLanguageCodeCount2 },
//{ 7, GetKeyCodeMap }, // 4.0.0+
{ 8, GetQuestFlag }, // 5.0.0+
//{ 9, GetKeyCodeMap2 }, // 6.0.0+
};
}
public ISettingsServer(ServiceCtx context) { }
[Command(0)]
// GetLanguageCode() -> nn::settings::LanguageCode
public static long GetLanguageCode(ServiceCtx context)
{
@ -40,6 +20,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
return 0;
}
[Command(1)]
// GetAvailableLanguageCodes() -> (u32, buffer<nn::settings::LanguageCode, 0xa>)
public static long GetAvailableLanguageCodes(ServiceCtx context)
{
@ -50,6 +31,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
0xF);
}
[Command(2)] // 4.0.0+
// MakeLanguageCode(nn::settings::Language language_index) -> nn::settings::LanguageCode
public static long MakeLanguageCode(ServiceCtx context)
{
@ -65,6 +47,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
return 0;
}
[Command(3)]
// GetAvailableLanguageCodeCount() -> u32
public static long GetAvailableLanguageCodeCount(ServiceCtx context)
{
@ -73,6 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
return 0;
}
[Command(5)]
// GetAvailableLanguageCodes2() -> (u32, buffer<nn::settings::LanguageCode, 6>)
public static long GetAvailableLanguageCodes2(ServiceCtx context)
{
@ -83,6 +67,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
SystemStateMgr.LanguageCodes.Length);
}
[Command(6)]
// GetAvailableLanguageCodeCount2() -> u32
public static long GetAvailableLanguageCodeCount2(ServiceCtx context)
{
@ -91,6 +76,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
return 0;
}
[Command(8)] // 5.0.0+
// GetQuestFlag() -> bool
public static long GetQuestFlag(ServiceCtx context)
{
@ -122,4 +108,4 @@ namespace Ryujinx.HLE.HOS.Services.Set
return 0;
}
}
}
}

View file

@ -2,10 +2,8 @@ using LibHac.Fs;
using LibHac.Fs.NcaUtils;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.SystemState;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
@ -14,28 +12,16 @@ namespace Ryujinx.HLE.HOS.Services.Set
[Service("set:sys")]
class ISystemSettingsServer : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISystemSettingsServer(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 3, GetFirmwareVersion },
{ 4, GetFirmwareVersion2 },
{ 23, GetColorSetId },
{ 24, SetColorSetId },
{ 38, GetSettingsItemValue }
};
}
public ISystemSettingsServer(ServiceCtx context) { }
[Command(3)]
// GetFirmwareVersion() -> buffer<nn::settings::system::FirmwareVersion, 0x1a, 0x100>
public static long GetFirmwareVersion(ServiceCtx context)
{
return GetFirmwareVersion2(context);
}
[Command(4)]
// GetFirmwareVersion2() -> buffer<nn::settings::system::FirmwareVersion, 0x1a, 0x100>
public static long GetFirmwareVersion2(ServiceCtx context)
{
@ -95,6 +81,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
return 0;
}
[Command(23)]
// GetColorSetId() -> i32
public static long GetColorSetId(ServiceCtx context)
{
@ -103,6 +90,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
return 0;
}
[Command(24)]
// GetColorSetId() -> i32
public static long SetColorSetId(ServiceCtx context)
{
@ -113,6 +101,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
return 0;
}
[Command(38)]
// GetSettingsItemValue(buffer<nn::settings::SettingsName, 0x19, 0x48>, buffer<nn::settings::SettingsItemKey, 0x19, 0x48>) -> (u64, buffer<unknown, 6, 0>)
public static long GetSettingsItemValue(ServiceCtx context)
{
@ -206,4 +195,4 @@ namespace Ryujinx.HLE.HOS.Services.Set
}
}
}
}
}

View file

@ -1,5 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System;
using System.Collections.Generic;
using System.Net;
@ -13,25 +12,7 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
[Service("sfdnsres")]
class IResolver : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IResolver(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, SetDnsAddressesPrivate },
{ 1, GetDnsAddressesPrivate },
{ 2, GetHostByName },
{ 3, GetHostByAddress },
{ 4, GetHostStringError },
{ 5, GetGaiStringError },
{ 8, RequestCancelHandle },
{ 9, CancelSocketCall },
{ 11, ClearDnsAddresses }
};
}
public IResolver(ServiceCtx context) { }
private long SerializeHostEnt(ServiceCtx context, IPHostEntry hostEntry, List<IPAddress> addresses = null)
{
@ -159,6 +140,7 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
return result;
}
[Command(0)]
// SetDnsAddressesPrivate(u32, buffer<unknown, 5, 0>)
public long SetDnsAddressesPrivate(ServiceCtx context)
{
@ -172,6 +154,7 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
return MakeError(ErrorModule.Os, 1023);
}
[Command(1)]
// GetDnsAddressPrivate(u32) -> buffer<unknown, 6, 0>
public long GetDnsAddressesPrivate(ServiceCtx context)
{
@ -183,6 +166,7 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
return MakeError(ErrorModule.Os, 1023);
}
[Command(2)]
// GetHostByName(u8, u32, u64, pid, buffer<unknown, 5, 0>) -> (u32, u32, u32, buffer<unknown, 6, 0>)
public long GetHostByName(ServiceCtx context)
{
@ -262,6 +246,7 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
return 0;
}
[Command(3)]
// GetHostByAddr(u32, u32, u32, u64, pid, buffer<unknown, 5, 0>) -> (u32, u32, u32, buffer<unknown, 6, 0>)
public long GetHostByAddress(ServiceCtx context)
{
@ -331,6 +316,7 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
return 0;
}
[Command(4)]
// GetHostStringError(u32) -> buffer<unknown, 6, 0>
public long GetHostStringError(ServiceCtx context)
{
@ -347,6 +333,7 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
return resultCode;
}
[Command(5)]
// GetGaiStringError(u32) -> buffer<unknown, 6, 0>
public long GetGaiStringError(ServiceCtx context)
{
@ -363,6 +350,7 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
return resultCode;
}
[Command(8)]
// RequestCancelHandle(u64, pid) -> u32
public long RequestCancelHandle(ServiceCtx context)
{
@ -375,6 +363,7 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
return 0;
}
[Command(9)]
// CancelSocketCall(u32, u64, pid)
public long CancelSocketCall(ServiceCtx context)
{
@ -386,6 +375,7 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
return 0;
}
[Command(11)]
// ClearDnsAddresses(u32)
public long ClearDnsAddresses(ServiceCtx context)
{
@ -396,4 +386,4 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
return 0;
}
}
}
}

View file

@ -16,24 +16,12 @@ namespace Ryujinx.HLE.HOS.Services.Sm
{
private Dictionary<string, Type> _services;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private ConcurrentDictionary<string, KPort> _registeredServices;
private bool _isInitialized;
public IUserInterface(ServiceCtx context = null)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Initialize },
{ 1, GetService },
{ 2, RegisterService },
{ 3, UnregisterService }
};
_registeredServices = new ConcurrentDictionary<string, KPort>();
_services = Assembly.GetExecutingAssembly().GetTypes()
@ -51,6 +39,8 @@ namespace Ryujinx.HLE.HOS.Services.Sm
port.ClientPort.Service = new IUserInterface();
}
[Command(0)]
// Initialize(pid, u64 reserved)
public long Initialize(ServiceCtx context)
{
_isInitialized = true;
@ -58,6 +48,8 @@ namespace Ryujinx.HLE.HOS.Services.Sm
return 0;
}
[Command(1)]
// GetService(ServiceName name) -> handle<move, session>
public long GetService(ServiceCtx context)
{
if (!_isInitialized)
@ -117,6 +109,8 @@ namespace Ryujinx.HLE.HOS.Services.Sm
return 0;
}
[Command(2)]
// RegisterService(ServiceName name, u8, u32 maxHandles) -> handle<move, port>
public long RegisterService(ServiceCtx context)
{
if (!_isInitialized)
@ -158,6 +152,8 @@ namespace Ryujinx.HLE.HOS.Services.Sm
return 0;
}
[Command(3)]
// UnregisterService(ServiceName name)
public long UnregisterService(ServiceCtx context)
{
if (!_isInitialized)

View file

@ -1,6 +1,4 @@
using Ryujinx.HLE.HOS.Ipc;
using System;
using System.Collections.Generic;
using System;
using System.Security.Cryptography;
namespace Ryujinx.HLE.HOS.Services.Spl
@ -8,22 +6,15 @@ namespace Ryujinx.HLE.HOS.Services.Spl
[Service("csrng")]
class IRandomInterface : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private RNGCryptoServiceProvider _rng;
public IRandomInterface(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetRandomBytes }
};
_rng = new RNGCryptoServiceProvider();
}
[Command(0)]
// GetRandomBytes() -> buffer<unknown, 6>
public long GetRandomBytes(ServiceCtx context)
{
byte[] randomBytes = new byte[context.Request.ReceiveBuff[0].Size];

View file

@ -1,20 +1,7 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ssl
{
class ISslContext : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISslContext()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
// ...
};
}
public ISslContext() { }
}
}

View file

@ -1,25 +1,13 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ssl
{
[Service("ssl")]
class ISslService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISslService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, CreateContext },
{ 5, SetInterfaceVersion }
};
}
public ISslService(ServiceCtx context) { }
[Command(0)]
// CreateContext(nn::ssl::sf::SslVersion, u64, pid) -> object<nn::ssl::sf::ISslContext>
public long CreateContext(ServiceCtx context)
{
@ -33,6 +21,7 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
return 0;
}
[Command(5)]
// SetInterfaceVersion(u32)
public long SetInterfaceVersion(ServiceCtx context)
{

View file

@ -1,7 +1,6 @@
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Time
{
@ -12,39 +11,11 @@ namespace Ryujinx.HLE.HOS.Services.Time
{
private int _timeSharedMemoryNativeHandle = 0;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private static readonly DateTime StartupDate = DateTime.UtcNow;
public IStaticService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetStandardUserSystemClock },
{ 1, GetStandardNetworkSystemClock },
{ 2, GetStandardSteadyClock },
{ 3, GetTimeZoneService },
{ 4, GetStandardLocalSystemClock },
//{ 5, GetEphemeralNetworkSystemClock }, // 4.0.0+
{ 20, GetSharedMemoryNativeHandle }, // 6.0.0+
//{ 30, GetStandardNetworkClockOperationEventReadableHandle }, // 6.0.0+
//{ 31, GetEphemeralNetworkClockOperationEventReadableHandle }, // 6.0.0+
//{ 50, SetStandardSteadyClockInternalOffset }, // 4.0.0+
//{ 100, IsStandardUserSystemClockAutomaticCorrectionEnabled },
//{ 101, SetStandardUserSystemClockAutomaticCorrectionEnabled },
//{ 102, GetStandardUserSystemClockInitialYear }, // 5.0.0+
//{ 200, IsStandardNetworkSystemClockAccuracySufficient }, // 3.0.0+
//{ 201, GetStandardUserSystemClockAutomaticCorrectionUpdatedTime }, // 6.0.0+
{ 300, CalculateMonotonicSystemClockBaseTimePoint }, // 4.0.0+
//{ 400, GetClockSnapshot }, // 4.0.0+
//{ 401, GetClockSnapshotFromSystemClockContext }, // 4.0.0+
//{ 500, CalculateStandardUserSystemClockDifferenceByUser }, // 4.0.0+
//{ 501, CalculateSpanBetween }, // 4.0.0+
};
}
public IStaticService(ServiceCtx context) { }
[Command(0)]
// GetStandardUserSystemClock() -> object<nn::timesrv::detail::service::ISystemClock>
public long GetStandardUserSystemClock(ServiceCtx context)
{
@ -53,6 +24,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(1)]
// GetStandardNetworkSystemClock() -> object<nn::timesrv::detail::service::ISystemClock>
public long GetStandardNetworkSystemClock(ServiceCtx context)
{
@ -61,6 +33,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(2)]
// GetStandardSteadyClock() -> object<nn::timesrv::detail::service::ISteadyClock>
public long GetStandardSteadyClock(ServiceCtx context)
{
@ -69,6 +42,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(3)]
// GetTimeZoneService() -> object<nn::timesrv::detail::service::ITimeZoneService>
public long GetTimeZoneService(ServiceCtx context)
{
@ -77,6 +51,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(4)]
// GetStandardLocalSystemClock() -> object<nn::timesrv::detail::service::ISystemClock>
public long GetStandardLocalSystemClock(ServiceCtx context)
{
@ -85,6 +60,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(20)] // 6.0.0+
// GetSharedMemoryNativeHandle() -> handle<copy>
public long GetSharedMemoryNativeHandle(ServiceCtx context)
{
@ -101,6 +77,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(300)] // 4.0.0+
// CalculateMonotonicSystemClockBaseTimePoint(nn::time::SystemClockContext) -> u64
public long CalculateMonotonicSystemClockBaseTimePoint(ServiceCtx context)
{

View file

@ -1,29 +1,18 @@
using Ryujinx.HLE.HOS.Ipc;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Time
{
class ISteadyClock : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private ulong _testOffset;
public ISteadyClock()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetCurrentTimePoint },
{ 1, GetTestOffset },
{ 2, SetTestOffset }
};
_testOffset = 0;
}
[Command(0)]
// GetCurrentTimePoint() -> nn::time::SteadyClockTimePoint
public long GetCurrentTimePoint(ServiceCtx context)
{
context.ResponseData.Write((long)(System.Diagnostics.Process.GetCurrentProcess().StartTime - DateTime.Now).TotalSeconds);
@ -36,6 +25,8 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(1)]
// GetTestOffset() -> nn::TimeSpanType
public long GetTestOffset(ServiceCtx context)
{
context.ResponseData.Write(_testOffset);
@ -43,6 +34,8 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(2)]
// SetTestOffset(nn::TimeSpanType)
public long SetTestOffset(ServiceCtx context)
{
_testOffset = context.RequestData.ReadUInt64();

View file

@ -1,38 +1,20 @@
using Ryujinx.HLE.HOS.Ipc;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Time
{
class ISystemClock : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private SystemClockType _clockType;
private DateTime _systemClockContextEpoch;
private long _systemClockTimePoint;
private byte[] _systemClockContextEnding;
private long _timeOffset;
private DateTime _systemClockContextEpoch;
private long _systemClockTimePoint;
private byte[] _systemClockContextEnding;
private long _timeOffset;
public ISystemClock(SystemClockType clockType)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetCurrentTime },
{ 1, SetCurrentTime },
{ 2, GetSystemClockContext },
{ 3, SetSystemClockContext }
};
_clockType = clockType;
_clockType = clockType;
_systemClockContextEpoch = System.Diagnostics.Process.GetCurrentProcess().StartTime;
_systemClockContextEnding = new byte[0x10];
_timeOffset = 0;
@ -46,6 +28,8 @@ namespace Ryujinx.HLE.HOS.Services.Time
_systemClockTimePoint = (long)(_systemClockContextEpoch - Epoch).TotalSeconds;
}
[Command(0)]
// GetCurrentTime() -> nn::time::PosixTime
public long GetCurrentTime(ServiceCtx context)
{
DateTime currentTime = DateTime.Now;
@ -61,6 +45,8 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(1)]
// SetCurrentTime(nn::time::PosixTime)
public long SetCurrentTime(ServiceCtx context)
{
DateTime currentTime = DateTime.Now;
@ -76,6 +62,8 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(2)]
// GetSystemClockContext() -> nn::time::SystemClockContext
public long GetSystemClockContext(ServiceCtx context)
{
context.ResponseData.Write((long)(_systemClockContextEpoch - Epoch).TotalSeconds);
@ -92,6 +80,8 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(3)]
// SetSystemClockContext(nn::time::SystemClockContext)
public long SetSystemClockContext(ServiceCtx context)
{
long newSystemClockEpoch = context.RequestData.ReadInt64();

View file

@ -1,10 +1,8 @@
using ChocolArm64.Memory;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
using System;
using System.Collections.Generic;
using System.Text;
using static Ryujinx.HLE.HOS.ErrorCode;
@ -13,28 +11,9 @@ namespace Ryujinx.HLE.HOS.Services.Time
{
class ITimeZoneService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ITimeZoneService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetDeviceLocationName },
{ 1, SetDeviceLocationName },
{ 2, GetTotalLocationNameCount },
{ 3, LoadLocationNameList },
{ 4, LoadTimeZoneRule },
//{ 5, GetTimeZoneRuleVersion }, // 2.0.0+
//{ 6, GetDeviceLocationNameAndUpdatedTime }, // 5.0.0+
{ 100, ToCalendarTime },
{ 101, ToCalendarTimeWithMyRule },
{ 201, ToPosixTime },
{ 202, ToPosixTimeWithMyRule }
};
}
public ITimeZoneService() { }
[Command(0)]
// GetDeviceLocationName() -> nn::time::LocationName
public long GetDeviceLocationName(ServiceCtx context)
{
@ -57,6 +36,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(1)]
// SetDeviceLocationName(nn::time::LocationName)
public long SetDeviceLocationName(ServiceCtx context)
{
@ -65,6 +45,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return TimeZoneManager.Instance.SetDeviceLocationName(locationName);
}
[Command(2)]
// GetTotalLocationNameCount() -> u32
public long GetTotalLocationNameCount(ServiceCtx context)
{
@ -73,6 +54,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0;
}
[Command(3)]
// LoadLocationNameList(u32 index) -> (u32 outCount, buffer<nn::time::LocationName, 6>)
public long LoadLocationNameList(ServiceCtx context)
{
@ -108,6 +90,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return errorCode;
}
[Command(4)]
// LoadTimeZoneRule(nn::time::LocationName locationName) -> buffer<nn::time::TimeZoneRule, 0x16>
public long LoadTimeZoneRule(ServiceCtx context)
{
@ -136,6 +119,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return resultCode;
}
[Command(100)]
// ToCalendarTime(nn::time::PosixTime time, buffer<nn::time::TimeZoneRule, 0x15> rules) -> (nn::time::CalendarTime, nn::time::sf::CalendarAdditionalInfo)
public long ToCalendarTime(ServiceCtx context)
{
@ -163,6 +147,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return resultCode;
}
[Command(101)]
// ToCalendarTimeWithMyRule(nn::time::PosixTime) -> (nn::time::CalendarTime, nn::time::sf::CalendarAdditionalInfo)
public long ToCalendarTimeWithMyRule(ServiceCtx context)
{
@ -178,6 +163,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return resultCode;
}
[Command(201)]
// ToPosixTime(nn::time::CalendarTime calendarTime, buffer<nn::time::TimeZoneRule, 0x15> rules) -> (u32 outCount, buffer<nn::time::PosixTime, 0xa>)
public long ToPosixTime(ServiceCtx context)
{
@ -210,6 +196,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return resultCode;
}
[Command(202)]
// ToPosixTimeWithMyRule(nn::time::CalendarTime calendarTime) -> (u32 outCount, buffer<nn::time::PosixTime, 0xa>)
public long ToPosixTimeWithMyRule(ServiceCtx context)
{
@ -231,4 +218,4 @@ namespace Ryujinx.HLE.HOS.Services.Time
return resultCode;
}
}
}
}

View file

@ -1,7 +1,6 @@
using ChocolArm64.Memory;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using System.Collections.Generic;
using System;
using System.IO;
using System.Text;
@ -13,45 +12,26 @@ namespace Ryujinx.HLE.HOS.Services.Vi
{
class IApplicationDisplayService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private IdDictionary _displays;
public IApplicationDisplayService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 100, GetRelayService },
{ 101, GetSystemDisplayService },
{ 102, GetManagerDisplayService },
{ 103, GetIndirectDisplayTransactionService },
{ 1000, ListDisplays },
{ 1010, OpenDisplay },
{ 1020, CloseDisplay },
{ 1102, GetDisplayResolution },
{ 2020, OpenLayer },
{ 2021, CloseLayer },
{ 2030, CreateStrayLayer },
{ 2031, DestroyStrayLayer },
{ 2101, SetLayerScalingMode },
{ 2102, ConvertScalingMode },
{ 5202, GetDisplayVSyncEvent }
};
_displays = new IdDictionary();
}
[Command(100)]
// GetRelayService() -> object<nns::hosbinder::IHOSBinderDriver>
public long GetRelayService(ServiceCtx context)
{
MakeObject(context, new IhosBinderDriver(
MakeObject(context, new IHOSBinderDriver(
context.Device.System,
context.Device.Gpu.Renderer));
return 0;
}
[Command(101)]
// GetSystemDisplayService() -> object<nn::visrv::sf::ISystemDisplayService>
public long GetSystemDisplayService(ServiceCtx context)
{
MakeObject(context, new ISystemDisplayService(this));
@ -59,6 +39,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(102)]
// GetManagerDisplayService() -> object<nn::visrv::sf::IManagerDisplayService>
public long GetManagerDisplayService(ServiceCtx context)
{
MakeObject(context, new IManagerDisplayService(this));
@ -66,15 +48,19 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(103)] // 2.0.0+
// GetIndirectDisplayTransactionService() -> object<nns::hosbinder::IHOSBinderDriver>
public long GetIndirectDisplayTransactionService(ServiceCtx context)
{
MakeObject(context, new IhosBinderDriver(
MakeObject(context, new IHOSBinderDriver(
context.Device.System,
context.Device.Gpu.Renderer));
return 0;
}
[Command(1000)]
// ListDisplays() -> (u64, buffer<nn::vi::DisplayInfo, 6>)
public long ListDisplays(ServiceCtx context)
{
long recBuffPtr = context.Request.ReceiveBuff[0].Position;
@ -93,6 +79,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(1010)]
// OpenDisplay(nn::vi::DisplayName) -> u64
public long OpenDisplay(ServiceCtx context)
{
string name = GetDisplayName(context);
@ -104,6 +92,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(1020)]
// CloseDisplay(u64)
public long CloseDisplay(ServiceCtx context)
{
int displayId = context.RequestData.ReadInt32();
@ -113,6 +103,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(1102)]
// GetDisplayResolution(u64) -> (u64, u64)
public long GetDisplayResolution(ServiceCtx context)
{
long displayId = context.RequestData.ReadInt32();
@ -123,6 +115,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(2020)]
// OpenLayer(nn::vi::DisplayName, u64, nn::applet::AppletResourceUserId, pid) -> (u64, buffer<bytes, 6>)
public long OpenLayer(ServiceCtx context)
{
long layerId = context.RequestData.ReadInt64();
@ -139,6 +133,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(2021)]
// CloseLayer(u64)
public long CloseLayer(ServiceCtx context)
{
long layerId = context.RequestData.ReadInt64();
@ -146,6 +142,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(2030)]
// CreateStrayLayer(u32, u64) -> (u64, u64, buffer<bytes, 6>)
public long CreateStrayLayer(ServiceCtx context)
{
long layerFlags = context.RequestData.ReadInt64();
@ -165,11 +163,15 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(2031)]
// DestroyStrayLayer(u64)
public long DestroyStrayLayer(ServiceCtx context)
{
return 0;
}
[Command(2101)]
// SetLayerScalingMode(u32, u64)
public long SetLayerScalingMode(ServiceCtx context)
{
int scalingMode = context.RequestData.ReadInt32();
@ -178,6 +180,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(2102)] // 5.0.0+
// ConvertScalingMode(unknown) -> unknown
public long ConvertScalingMode(ServiceCtx context)
{
SrcScalingMode scalingMode = (SrcScalingMode)context.RequestData.ReadInt32();
@ -216,6 +220,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return null;
}
[Command(5202)]
// GetDisplayVsyncEvent(u64) -> handle<copy>
public long GetDisplayVSyncEvent(ServiceCtx context)
{
string name = GetDisplayName(context);

View file

@ -1,23 +1,12 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Vi
{
[Service("vi:u")]
class IApplicationRootService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IApplicationRootService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetDisplayService }
};
}
public IApplicationRootService(ServiceCtx context) { }
[Command(0)]
// GetDisplayService(u32) -> object<nn::visrv::sf::IApplicationDisplayService>
public long GetDisplayService(ServiceCtx context)
{
int serviceType = context.RequestData.ReadInt32();

View file

@ -4,30 +4,17 @@ using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.Android;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Vi
{
class IhosBinderDriver : IpcService, IDisposable
class IHOSBinderDriver : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent _binderEvent;
private NvFlinger _flinger;
public IhosBinderDriver(Horizon system, IGalRenderer renderer)
public IHOSBinderDriver(Horizon system, IGalRenderer renderer)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, TransactParcel },
{ 1, AdjustRefcount },
{ 2, GetNativeHandle },
{ 3, TransactParcelAuto }
};
_binderEvent = new KEvent(system);
_binderEvent.ReadableEvent.Signal();
@ -35,6 +22,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
_flinger = new NvFlinger(renderer, _binderEvent);
}
[Command(0)]
// TransactParcel(s32, u32, u32, buffer<unknown, 5, 0>) -> buffer<unknown, 6, 0>
public long TransactParcel(ServiceCtx context)
{
int id = context.RequestData.ReadInt32();
@ -50,20 +39,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return _flinger.ProcessParcelRequest(context, data, code);
}
public long TransactParcelAuto(ServiceCtx context)
{
int id = context.RequestData.ReadInt32();
int code = context.RequestData.ReadInt32();
(long dataPos, long dataSize) = context.Request.GetBufferType0x21();
byte[] data = context.Memory.ReadBytes(dataPos, dataSize);
data = Parcel.GetParcelData(data);
return _flinger.ProcessParcelRequest(context, data, code);
}
[Command(1)]
// AdjustRefcount(s32, s32, s32)
public long AdjustRefcount(ServiceCtx context)
{
int id = context.RequestData.ReadInt32();
@ -73,6 +50,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(2)]
// GetNativeHandle(s32, s32) -> handle<copy>
public long GetNativeHandle(ServiceCtx context)
{
int id = context.RequestData.ReadInt32();
@ -88,6 +67,22 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(3)] // 3.0.0+
// TransactParcelAuto(s32, u32, u32, buffer<unknown, 21, 0>) -> buffer<unknown, 22, 0>
public long TransactParcelAuto(ServiceCtx context)
{
int id = context.RequestData.ReadInt32();
int code = context.RequestData.ReadInt32();
(long dataPos, long dataSize) = context.Request.GetBufferType0x21();
byte[] data = context.Memory.ReadBytes(dataPos, dataSize);
data = Parcel.GetParcelData(data);
return _flinger.ProcessParcelRequest(context, data, code);
}
public void Dispose()
{
Dispose(true);

View file

@ -1,27 +1,18 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Vi
{
class IManagerDisplayService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private static IApplicationDisplayService _applicationDisplayService;
public IManagerDisplayService(IApplicationDisplayService applicationDisplayService)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 2010, CreateManagedLayer },
{ 2011, DestroyManagedLayer },
{ 2012, applicationDisplayService.CreateStrayLayer },
{ 6000, AddToLayerStack },
{ 6002, SetLayerVisibility }
};
_applicationDisplayService = applicationDisplayService;
}
[Command(2010)]
// CreateManagedLayer(u32, u64, nn::applet::AppletResourceUserId) -> u64
public static long CreateManagedLayer(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceVi);
@ -31,6 +22,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(2011)]
// DestroyManagedLayer(u64)
public long DestroyManagedLayer(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceVi);
@ -38,6 +31,17 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(2012)] // 7.0.0+
// CreateStrayLayer(u32, u64) -> (u64, u64, buffer<bytes, 6>)
public static long CreateStrayLayer(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceVi);
return _applicationDisplayService.CreateStrayLayer(context);
}
[Command(6000)]
// AddToLayerStack(u32, u64)
public static long AddToLayerStack(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceVi);
@ -45,6 +49,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(6002)]
// SetLayerVisibility(b8, u64)
public static long SetLayerVisibility(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceVi);

View file

@ -1,23 +1,12 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Vi
{
[Service("vi:m")]
class IManagerRootService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IManagerRootService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 2, GetDisplayService }
};
}
public IManagerRootService(ServiceCtx context) { }
[Command(2)]
// GetDisplayService(u32) -> object<nn::visrv::sf::IApplicationDisplayService>
public long GetDisplayService(ServiceCtx context)
{
int serviceType = context.RequestData.ReadInt32();

View file

@ -1,26 +1,18 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Vi
{
class ISystemDisplayService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private static IApplicationDisplayService _applicationDisplayService;
public ISystemDisplayService(IApplicationDisplayService applicationDisplayService)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 2205, SetLayerZ },
{ 2207, SetLayerVisibility },
{ 2312, applicationDisplayService.CreateStrayLayer },
{ 3200, GetDisplayMode }
};
_applicationDisplayService = applicationDisplayService;
}
[Command(2205)]
// SetLayerZ(u64, u64)
public static long SetLayerZ(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceVi);
@ -28,6 +20,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(2207)]
// SetLayerVisibility(b8, u64)
public static long SetLayerVisibility(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceVi);
@ -35,6 +29,17 @@ namespace Ryujinx.HLE.HOS.Services.Vi
return 0;
}
[Command(2312)] // 1.0.0-6.2.0
// CreateStrayLayer(u32, u64) -> (u64, u64, buffer<bytes, 6>)
public static long CreateStrayLayer(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceVi);
return _applicationDisplayService.CreateStrayLayer(context);
}
[Command(3200)]
// GetDisplayMode(u64) -> nn::vi::DisplayModeInfo
public static long GetDisplayMode(ServiceCtx context)
{
// TODO: De-hardcode resolution.

View file

@ -1,23 +1,12 @@
using Ryujinx.HLE.HOS.Ipc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Vi
{
[Service("vi:s")]
class ISystemRootService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISystemRootService(ServiceCtx context)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 1, GetDisplayService }
};
}
public ISystemRootService(ServiceCtx context) { }
[Command(1)]
// GetDisplayService(u32) -> object<nn::visrv::sf::IApplicationDisplayService>
public long GetDisplayService(ServiceCtx context)
{
int serviceType = context.RequestData.ReadInt32();