diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-08-16 20:47:36 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-08-16 20:47:36 -0300 |
| commit | 521751795a1c97c0d97f6f8904a3be69b13d3a9d (patch) | |
| tree | 942a05899c40e2de6d92a38b93a494bd96ee64b8 /Ryujinx.HLE/HOS/Services/Am | |
| parent | 182d716867ae477c2b15a5332430dc2641fa1cc3 (diff) | |
Code style fixes and nits on the HLE project (#355)
* Some style fixes and nits on ITimeZoneService
* Remove some unneeded usings
* Remove the Ryujinx.HLE.OsHle.Handles namespace
* Remove hbmenu automatic load on process exit
* Rename Ns to Device, rename Os to System, rename SystemState to State
* Move Exceptions and Utilities out of OsHle
* Rename OsHle to HOS
* Rename OsHle folder to HOS
* IManagerDisplayService and ISystemDisplayService style fixes
* BsdError shouldn't be public
* Add a empty new line before using static
* Remove unused file
* Some style fixes on NPDM
* Exit gracefully when the application is closed
* Code style fixes on IGeneralService
* Add 0x prefix on values printed as hex
* Small improvements on finalization code
* Move ProcessId and ThreadId out of AThreadState
* Rename VFs to FileSystem
* FsAccessHeader shouldn't be public. Also fix file names casing
* More case changes on NPDM
* Remove unused files
* Move using to the correct place on NPDM
* Use properties on KernelAccessControlMmio
* Address PR feedback
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Am')
23 files changed, 1130 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Am/AmErr.cs b/Ryujinx.HLE/HOS/Services/Am/AmErr.cs new file mode 100644 index 00000000..4e7771b8 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/AmErr.cs @@ -0,0 +1,7 @@ +namespace Ryujinx.HLE.HOS.Services.Am +{ + static class AmErr + { + public const int NoMessages = 3; + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/FocusState.cs b/Ryujinx.HLE/HOS/Services/Am/FocusState.cs new file mode 100644 index 00000000..e8ae7223 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/FocusState.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.HOS.Services.Am +{ + enum FocusState + { + InFocus = 1, + OutOfFocus = 2 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/IAllSystemAppletProxiesService.cs b/Ryujinx.HLE/HOS/Services/Am/IAllSystemAppletProxiesService.cs new file mode 100644 index 00000000..2d44526a --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IAllSystemAppletProxiesService.cs @@ -0,0 +1,27 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IAllSystemAppletProxiesService : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IAllSystemAppletProxiesService() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 100, OpenSystemAppletProxy } + }; + } + + public long OpenSystemAppletProxy(ServiceCtx Context) + { + MakeObject(Context, new ISystemAppletProxy()); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/IApplicationCreator.cs b/Ryujinx.HLE/HOS/Services/Am/IApplicationCreator.cs new file mode 100644 index 00000000..c5ed09f5 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IApplicationCreator.cs @@ -0,0 +1,20 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IApplicationCreator : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IApplicationCreator() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + //... + }; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/IApplicationFunctions.cs b/Ryujinx.HLE/HOS/Services/Am/IApplicationFunctions.cs new file mode 100644 index 00000000..0a10d2a6 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IApplicationFunctions.cs @@ -0,0 +1,117 @@ +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.Logging; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IApplicationFunctions : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IApplicationFunctions() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 1, PopLaunchParameter }, + { 20, EnsureSaveData }, + { 21, GetDesiredLanguage }, + { 22, SetTerminateResult }, + { 23, GetDisplayVersion }, + { 40, NotifyRunning }, + { 50, GetPseudoDeviceId }, + { 66, InitializeGamePlayRecording }, + { 67, SetGamePlayRecordingState } + }; + } + + public long PopLaunchParameter(ServiceCtx Context) + { + //Only the first 0x18 bytes of the Data seems to be actually used. + MakeObject(Context, new IStorage(StorageHelper.MakeLaunchParams())); + + return 0; + } + + public long EnsureSaveData(ServiceCtx Context) + { + long UIdLow = Context.RequestData.ReadInt64(); + long UIdHigh = Context.RequestData.ReadInt64(); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + Context.ResponseData.Write(0L); + + return 0; + } + + public long GetDesiredLanguage(ServiceCtx Context) + { + Context.ResponseData.Write(Context.Device.System.State.DesiredLanguageCode); + + return 0; + } + + public long SetTerminateResult(ServiceCtx Context) + { + int ErrorCode = Context.RequestData.ReadInt32(); + + string Result = GetFormattedErrorCode(ErrorCode); + + Context.Device.Log.PrintInfo(LogClass.ServiceAm, $"Result = 0x{ErrorCode:x8} ({Result})."); + + return 0; + } + + private string GetFormattedErrorCode(int ErrorCode) + { + int Module = (ErrorCode >> 0) & 0x1ff; + int Description = (ErrorCode >> 9) & 0x1fff; + + return $"{(2000 + Module):d4}-{Description:d4}"; + } + + public long GetDisplayVersion(ServiceCtx Context) + { + //FIXME: Need to check correct version on a switch. + Context.ResponseData.Write(1L); + Context.ResponseData.Write(0L); + + return 0; + } + + public long NotifyRunning(ServiceCtx Context) + { + Context.ResponseData.Write(1); + + return 0; + } + + public long GetPseudoDeviceId(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + Context.ResponseData.Write(0L); + Context.ResponseData.Write(0L); + + return 0; + } + + public long InitializeGamePlayRecording(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long SetGamePlayRecordingState(ServiceCtx Context) + { + int State = Context.RequestData.ReadInt32(); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Am/IApplicationProxy.cs b/Ryujinx.HLE/HOS/Services/Am/IApplicationProxy.cs new file mode 100644 index 00000000..4003f151 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IApplicationProxy.cs @@ -0,0 +1,83 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IApplicationProxy : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IApplicationProxy() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 0, GetCommonStateGetter }, + { 1, GetSelfController }, + { 2, GetWindowController }, + { 3, GetAudioController }, + { 4, GetDisplayController }, + { 11, GetLibraryAppletCreator }, + { 20, GetApplicationFunctions }, + { 1000, GetDebugFunctions } + }; + } + + public long GetCommonStateGetter(ServiceCtx Context) + { + MakeObject(Context, new ICommonStateGetter()); + + return 0; + } + + public long GetSelfController(ServiceCtx Context) + { + MakeObject(Context, new ISelfController()); + + return 0; + } + + public long GetWindowController(ServiceCtx Context) + { + MakeObject(Context, new IWindowController()); + + return 0; + } + + public long GetAudioController(ServiceCtx Context) + { + MakeObject(Context, new IAudioController()); + + return 0; + } + + public long GetDisplayController(ServiceCtx Context) + { + MakeObject(Context, new IDisplayController()); + + return 0; + } + + public long GetLibraryAppletCreator(ServiceCtx Context) + { + MakeObject(Context, new ILibraryAppletCreator()); + + return 0; + } + + public long GetApplicationFunctions(ServiceCtx Context) + { + MakeObject(Context, new IApplicationFunctions()); + + return 0; + } + + public long GetDebugFunctions(ServiceCtx Context) + { + MakeObject(Context, new IDebugFunctions()); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/IApplicationProxyService.cs b/Ryujinx.HLE/HOS/Services/Am/IApplicationProxyService.cs new file mode 100644 index 00000000..fb518af9 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IApplicationProxyService.cs @@ -0,0 +1,27 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IApplicationProxyService : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IApplicationProxyService() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 0, OpenApplicationProxy } + }; + } + + public long OpenApplicationProxy(ServiceCtx Context) + { + MakeObject(Context, new IApplicationProxy()); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/IAudioController.cs b/Ryujinx.HLE/HOS/Services/Am/IAudioController.cs new file mode 100644 index 00000000..8968ad72 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IAudioController.cs @@ -0,0 +1,72 @@ +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.Logging; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IAudioController : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IAudioController() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 0, SetExpectedMasterVolume }, + { 1, GetMainAppletExpectedMasterVolume }, + { 2, GetLibraryAppletExpectedMasterVolume }, + { 3, ChangeMainAppletMasterVolume }, + { 4, SetTransparentVolumeRate } + }; + } + + public long SetExpectedMasterVolume(ServiceCtx Context) + { + float AppletVolume = Context.RequestData.ReadSingle(); + float LibraryAppletVolume = Context.RequestData.ReadSingle(); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long GetMainAppletExpectedMasterVolume(ServiceCtx Context) + { + Context.ResponseData.Write(1f); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long GetLibraryAppletExpectedMasterVolume(ServiceCtx Context) + { + Context.ResponseData.Write(1f); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long ChangeMainAppletMasterVolume(ServiceCtx Context) + { + float Unknown0 = Context.RequestData.ReadSingle(); + long Unknown1 = Context.RequestData.ReadInt64(); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long SetTransparentVolumeRate(ServiceCtx Context) + { + float Unknown0 = Context.RequestData.ReadSingle(); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Am/ICommonStateGetter.cs b/Ryujinx.HLE/HOS/Services/Am/ICommonStateGetter.cs new file mode 100644 index 00000000..3cdfbbdb --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/ICommonStateGetter.cs @@ -0,0 +1,115 @@ +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Kernel; +using Ryujinx.HLE.Logging; +using System.Collections.Generic; + +using static Ryujinx.HLE.HOS.ErrorCode; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class ICommonStateGetter : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + private KEvent DisplayResolutionChangeEvent; + + public ICommonStateGetter() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 0, GetEventHandle }, + { 1, ReceiveMessage }, + { 5, GetOperationMode }, + { 6, GetPerformanceMode }, + { 8, GetBootMode }, + { 9, GetCurrentFocusState }, + { 60, GetDefaultDisplayResolution }, + { 61, GetDefaultDisplayResolutionChangeEvent } + }; + + DisplayResolutionChangeEvent = new KEvent(); + } + + public long GetEventHandle(ServiceCtx Context) + { + KEvent Event = Context.Process.AppletState.MessageEvent; + + int Handle = Context.Process.HandleTable.OpenHandle(Event); + + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); + + return 0; + } + + public long ReceiveMessage(ServiceCtx Context) + { + if (!Context.Process.AppletState.TryDequeueMessage(out MessageInfo Message)) + { + return MakeError(ErrorModule.Am, AmErr.NoMessages); + } + + Context.ResponseData.Write((int)Message); + + return 0; + } + + public long GetOperationMode(ServiceCtx Context) + { + OperationMode Mode = Context.Device.System.State.DockedMode + ? OperationMode.Docked + : OperationMode.Handheld; + + Context.ResponseData.Write((byte)Mode); + + return 0; + } + + public long GetPerformanceMode(ServiceCtx Context) + { + Apm.PerformanceMode Mode = Context.Device.System.State.DockedMode + ? Apm.PerformanceMode.Docked + : Apm.PerformanceMode.Handheld; + + Context.ResponseData.Write((int)Mode); + + return 0; + } + + public long GetBootMode(ServiceCtx Context) + { + Context.ResponseData.Write((byte)0); //Unknown value. + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long GetCurrentFocusState(ServiceCtx Context) + { + Context.ResponseData.Write((byte)Context.Process.AppletState.FocusState); + + return 0; + } + + public long GetDefaultDisplayResolution(ServiceCtx Context) + { + Context.ResponseData.Write(1280); + Context.ResponseData.Write(720); + + return 0; + } + + public long GetDefaultDisplayResolutionChangeEvent(ServiceCtx Context) + { + int Handle = Context.Process.HandleTable.OpenHandle(DisplayResolutionChangeEvent); + + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Am/IDebugFunctions.cs b/Ryujinx.HLE/HOS/Services/Am/IDebugFunctions.cs new file mode 100644 index 00000000..d86743c0 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IDebugFunctions.cs @@ -0,0 +1,20 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IDebugFunctions : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IDebugFunctions() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + //... + }; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/IDisplayController.cs b/Ryujinx.HLE/HOS/Services/Am/IDisplayController.cs new file mode 100644 index 00000000..c4d49579 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IDisplayController.cs @@ -0,0 +1,20 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IDisplayController : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IDisplayController() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + //... + }; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/IGlobalStateController.cs b/Ryujinx.HLE/HOS/Services/Am/IGlobalStateController.cs new file mode 100644 index 00000000..e646327f --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IGlobalStateController.cs @@ -0,0 +1,20 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IGlobalStateController : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IGlobalStateController() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + //... + }; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/IHomeMenuFunctions.cs b/Ryujinx.HLE/HOS/Services/Am/IHomeMenuFunctions.cs new file mode 100644 index 00000000..95028ca0 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IHomeMenuFunctions.cs @@ -0,0 +1,46 @@ +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Kernel; +using Ryujinx.HLE.Logging; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IHomeMenuFunctions : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + private KEvent ChannelEvent; + + public IHomeMenuFunctions() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 10, RequestToGetForeground }, + { 21, GetPopFromGeneralChannelEvent } + }; + + //ToDo: Signal this Event somewhere in future. + ChannelEvent = new KEvent(); + } + + public long RequestToGetForeground(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long GetPopFromGeneralChannelEvent(ServiceCtx Context) + { + int Handle = Context.Process.HandleTable.OpenHandle(ChannelEvent); + + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Am/ILibraryAppletAccessor.cs b/Ryujinx.HLE/HOS/Services/Am/ILibraryAppletAccessor.cs new file mode 100644 index 00000000..e099ec64 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/ILibraryAppletAccessor.cs @@ -0,0 +1,71 @@ +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Kernel; +using Ryujinx.HLE.Logging; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class ILibraryAppletAccessor : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + private KEvent StateChangedEvent; + + public ILibraryAppletAccessor() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 0, GetAppletStateChangedEvent }, + { 10, Start }, + { 30, GetResult }, + { 100, PushInData }, + { 101, PopOutData } + }; + + StateChangedEvent = new KEvent(); + } + + public long GetAppletStateChangedEvent(ServiceCtx Context) + { + StateChangedEvent.WaitEvent.Set(); + + int Handle = Context.Process.HandleTable.OpenHandle(StateChangedEvent); + + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long Start(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long GetResult(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long PushInData(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long PopOutData(ServiceCtx Context) + { + MakeObject(Context, new IStorage(StorageHelper.MakeLaunchParams())); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/ILibraryAppletCreator.cs b/Ryujinx.HLE/HOS/Services/Am/ILibraryAppletCreator.cs new file mode 100644 index 00000000..065574c7 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/ILibraryAppletCreator.cs @@ -0,0 +1,37 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class ILibraryAppletCreator : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public ILibraryAppletCreator() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 0, CreateLibraryApplet }, + { 10, CreateStorage } + }; + } + + public long CreateLibraryApplet(ServiceCtx Context) + { + MakeObject(Context, new ILibraryAppletAccessor()); + + return 0; + } + + public long CreateStorage(ServiceCtx Context) + { + long Size = Context.RequestData.ReadInt64(); + + MakeObject(Context, new IStorage(new byte[Size])); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs b/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs new file mode 100644 index 00000000..ccd96e0d --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs @@ -0,0 +1,145 @@ +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Kernel; +using Ryujinx.HLE.Logging; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class ISelfController : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + private KEvent LaunchableEvent; + + public ISelfController() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 0, Exit }, + { 1, LockExit }, + { 2, UnlockExit }, + { 9, GetLibraryAppletLaunchableEvent }, + { 10, SetScreenShotPermission }, + { 11, SetOperationModeChangedNotification }, + { 12, SetPerformanceModeChangedNotification }, + { 13, SetFocusHandlingMode }, + { 14, SetRestartMessageEnabled }, + { 16, SetOutOfFocusSuspendingEnabled }, + { 19, SetScreenShotImageOrientation }, + { 50, SetHandlesRequestToDisplay } + }; + + LaunchableEvent = new KEvent(); + } + + public long Exit(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long LockExit(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long UnlockExit(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long GetLibraryAppletLaunchableEvent(ServiceCtx Context) + { + LaunchableEvent.WaitEvent.Set(); + + int Handle = Context.Process.HandleTable.OpenHandle(LaunchableEvent); + + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long SetScreenShotPermission(ServiceCtx Context) + { + bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long SetOperationModeChangedNotification(ServiceCtx Context) + { + bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long SetPerformanceModeChangedNotification(ServiceCtx Context) + { + bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long SetFocusHandlingMode(ServiceCtx Context) + { + bool Flag1 = Context.RequestData.ReadByte() != 0 ? true : false; + bool Flag2 = Context.RequestData.ReadByte() != 0 ? true : false; + bool Flag3 = Context.RequestData.ReadByte() != 0 ? true : false; + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long SetRestartMessageEnabled(ServiceCtx Context) + { + bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long SetOutOfFocusSuspendingEnabled(ServiceCtx Context) + { + bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long SetScreenShotImageOrientation(ServiceCtx Context) + { + int Orientation = Context.RequestData.ReadInt32(); + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + + public long SetHandlesRequestToDisplay(ServiceCtx Context) + { + bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; + + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Am/IStorage.cs b/Ryujinx.HLE/HOS/Services/Am/IStorage.cs new file mode 100644 index 00000000..10778122 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IStorage.cs @@ -0,0 +1,31 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IStorage : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public byte[] Data { get; private set; } + + public IStorage(byte[] Data) + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 0, Open } + }; + + this.Data = Data; + } + + public long Open(ServiceCtx Context) + { + MakeObject(Context, new IStorageAccessor(this)); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/IStorageAccessor.cs b/Ryujinx.HLE/HOS/Services/Am/IStorageAccessor.cs new file mode 100644 index 00000000..a60cf149 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IStorageAccessor.cs @@ -0,0 +1,83 @@ +using Ryujinx.HLE.HOS.Ipc; +using System; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IStorageAccessor : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + private IStorage Storage; + + public IStorageAccessor(IStorage Storage) + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 0, GetSize }, + { 10, Write }, + { 11, Read } + }; + + this.Storage = Storage; + } + + public long GetSize(ServiceCtx Context) + { + Context.ResponseData.Write((long)Storage.Data.Length); + + return 0; + } + + public long Write(ServiceCtx Context) + { + //TODO: Error conditions. + long WritePosition = Context.RequestData.ReadInt64(); + + (long Position, long Size) = Context.Request.GetBufferType0x21(); + + if (Size > 0) + { + long MaxSize = Storage.Data.Length - WritePosition; + + if (Size > MaxSize) + { + Size = MaxSize; + } + + byte[] Data = Context.Memory.ReadBytes(Position, Size); + + Buffer.BlockCopy(Data, 0, Storage.Data, (int)WritePosition, (int)Size); + } + + return 0; + } + + public long Read(ServiceCtx Context) + { + //TODO: Error conditions. + long ReadPosition = Context.RequestData.ReadInt64(); + + (long Position, long Size) = Context.Request.GetBufferType0x22(); + + byte[] Data; + + if (Storage.Data.Length > Size) + { + Data = new byte[Size]; + + Buffer.BlockCopy(Storage.Data, 0, Data, 0, (int)Size); + } + else + { + Data = Storage.Data; + } + + Context.Memory.WriteBytes(Position, Data); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/ISystemAppletProxy.cs b/Ryujinx.HLE/HOS/Services/Am/ISystemAppletProxy.cs new file mode 100644 index 00000000..c08d4018 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/ISystemAppletProxy.cs @@ -0,0 +1,99 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class ISystemAppletProxy : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public ISystemAppletProxy() + { + m_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 long GetCommonStateGetter(ServiceCtx Context) + { + MakeObject(Context, new ICommonStateGetter()); + + return 0; + } + + public long GetSelfController(ServiceCtx Context) + { + MakeObject(Context, new ISelfController()); + + return 0; + } + + public long GetWindowController(ServiceCtx Context) + { + MakeObject(Context, new IWindowController()); + + return 0; + } + + public long GetAudioController(ServiceCtx Context) + { + MakeObject(Context, new IAudioController()); + + return 0; + } + + public long GetDisplayController(ServiceCtx Context) + { + MakeObject(Context, new IDisplayController()); + + return 0; + } + + public long GetLibraryAppletCreator(ServiceCtx Context) + { + MakeObject(Context, new ILibraryAppletCreator()); + + return 0; + } + + public long GetHomeMenuFunctions(ServiceCtx Context) + { + MakeObject(Context, new IHomeMenuFunctions()); + + return 0; + } + + public long GetGlobalStateController(ServiceCtx Context) + { + MakeObject(Context, new IGlobalStateController()); + + return 0; + } + + public long GetApplicationCreator(ServiceCtx Context) + { + MakeObject(Context, new IApplicationCreator()); + + return 0; + } + + public long GetDebugFunctions(ServiceCtx Context) + { + MakeObject(Context, new IDebugFunctions()); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/IWindowController.cs b/Ryujinx.HLE/HOS/Services/Am/IWindowController.cs new file mode 100644 index 00000000..1a5a716f --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/IWindowController.cs @@ -0,0 +1,38 @@ +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.Logging; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class IWindowController : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IWindowController() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 1, GetAppletResourceUserId }, + { 10, AcquireForegroundRights } + }; + } + + public long GetAppletResourceUserId(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + Context.ResponseData.Write(0L); + + return 0; + } + + public long AcquireForegroundRights(ServiceCtx Context) + { + Context.Device.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/MessageInfo.cs b/Ryujinx.HLE/HOS/Services/Am/MessageInfo.cs new file mode 100644 index 00000000..65fddbed --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/MessageInfo.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Services.Am +{ + enum MessageInfo + { + FocusStateChanged = 0xf, + OperationModeChanged = 0x1e, + PerformanceModeChanged = 0x1f + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/OperationMode.cs b/Ryujinx.HLE/HOS/Services/Am/OperationMode.cs new file mode 100644 index 00000000..cb11fff9 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/OperationMode.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.HOS.Services.Am +{ + enum OperationMode + { + Handheld = 0, + Docked = 1 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Am/StorageHelper.cs b/Ryujinx.HLE/HOS/Services/Am/StorageHelper.cs new file mode 100644 index 00000000..b97ffc1e --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Am/StorageHelper.cs @@ -0,0 +1,27 @@ +using System.IO; + +namespace Ryujinx.HLE.HOS.Services.Am +{ + class StorageHelper + { + private const uint LaunchParamsMagic = 0xc79497ca; + + public static byte[] MakeLaunchParams() + { + //Size needs to be at least 0x88 bytes otherwise application errors. + using (MemoryStream MS = new MemoryStream()) + { + BinaryWriter Writer = new BinaryWriter(MS); + + MS.SetLength(0x88); + + Writer.Write(LaunchParamsMagic); + Writer.Write(1); //IsAccountSelected? Only lower 8 bits actually used. + Writer.Write(1L); //User Id Low (note: User Id needs to be != 0) + Writer.Write(0L); //User Id High + + return MS.ToArray(); + } + } + } +} |
