From c464e1ec522d41565923fbc542148ebeca61749e Mon Sep 17 00:00:00 2001 From: Thog Date: Wed, 12 Feb 2020 00:07:13 +0100 Subject: [PATCH] Stub the application copyright framebuffer api (#921) * Stub the application copyright framebuffer api As we currently don't support multi layers on vi/nvnflinger, this PR implement a stub of this API. * Address Cyuubi's comments * Add IPC checks and comments for future reversing Co-authored-by: Ac_K Co-authored-by: Ac_K --- .../SystemAppletProxy/ICommonStateGetter.cs | 2 +- .../ApplicationProxy/IApplicationFunctions.cs | 109 ++++++++++++++++++ Ryujinx.HLE/HOS/Services/Am/ResultCode.cs | 11 +- 3 files changed, 116 insertions(+), 6 deletions(-) diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs index 085d9fe60..10c732b75 100644 --- a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs +++ b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs @@ -128,7 +128,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys if (cpuBoostMode > 1) { - return ResultCode.CpuBoostModeInvalid; + return ResultCode.InvalidParameters; } _cpuBoostMode = (CpuBoostMode)cpuBoostMode; diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs index 3ae24c555..990b18ee9 100644 --- a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs +++ b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs @@ -8,6 +8,7 @@ using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Common; +using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Am.AppletAE.Storage; using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService; @@ -168,6 +169,114 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati return ResultCode.Success; } + [Command(100)] // 5.0.0+ + // InitializeApplicationCopyrightFrameBuffer(s32 width, s32 height, handle transfer_memory, u64 transfer_memory_size) + public ResultCode InitializeApplicationCopyrightFrameBuffer(ServiceCtx context) + { + int width = context.RequestData.ReadInt32(); + int height = context.RequestData.ReadInt32(); + ulong transferMemorySize = context.RequestData.ReadUInt64(); + int transferMemoryHandle = context.Request.HandleDesc.ToCopy[0]; + ulong transferMemoryAddress = context.Process.HandleTable.GetObject(transferMemoryHandle).Address; + + ResultCode resultCode = ResultCode.InvalidParameters; + + if (((transferMemorySize & 0x3FFFF) == 0) && width <= 1280 && height <= 720) + { + resultCode = InitializeApplicationCopyrightFrameBufferImpl(transferMemoryAddress, transferMemorySize, width, height); + } + + /* + if (transferMemoryHandle) + { + svcCloseHandle(transferMemoryHandle); + } + */ + + return resultCode; + } + + private ResultCode InitializeApplicationCopyrightFrameBufferImpl(ulong transferMemoryAddress, ulong transferMemorySize, int width, int height) + { + ResultCode resultCode = ResultCode.ObjectInvalid; + + if ((transferMemorySize & 0x3FFFF) != 0) + { + return ResultCode.InvalidParameters; + } + + // if (_copyrightBuffer == null) + { + // TODO: Initialize buffer and object. + + Logger.PrintStub(LogClass.ServiceAm, new { transferMemoryAddress, transferMemorySize, width, height }); + + resultCode = ResultCode.Success; + } + + return resultCode; + } + + [Command(101)] // 5.0.0+ + // SetApplicationCopyrightImage(buffer frame_buffer, s32 x, s32 y, s32 width, s32 height, s32 window_origin_mode) + public ResultCode SetApplicationCopyrightImage(ServiceCtx context) + { + long frameBufferPos = context.Request.SendBuff[0].Position; + long frameBufferSize = context.Request.SendBuff[0].Size; + int x = context.RequestData.ReadInt32(); + int y = context.RequestData.ReadInt32(); + int width = context.RequestData.ReadInt32(); + int height = context.RequestData.ReadInt32(); + uint windowOriginMode = context.RequestData.ReadUInt32(); + + ResultCode resultCode = ResultCode.InvalidParameters; + + if (((y | x) >= 0) && width >= 1 && height >= 1) + { + ResultCode result = SetApplicationCopyrightImageImpl(x, y, width, height, frameBufferPos, frameBufferSize, windowOriginMode); + + if (resultCode != ResultCode.Success) + { + resultCode = result; + } + else + { + resultCode = ResultCode.Success; + } + } + + Logger.PrintStub(LogClass.ServiceAm, new { frameBufferPos, frameBufferSize, x, y, width, height, windowOriginMode }); + + return resultCode; + } + + private ResultCode SetApplicationCopyrightImageImpl(int x, int y, int width, int height, long frameBufferPos, long frameBufferSize, uint windowOriginMode) + { + /* + if (_copyrightBuffer == null) + { + return ResultCode.NullCopyrightObject; + } + */ + + Logger.PrintStub(LogClass.ServiceAm, new { x, y, width, height, frameBufferPos, frameBufferSize, windowOriginMode }); + + return ResultCode.Success; + } + + [Command(102)] // 5.0.0+ + // SetApplicationCopyrightVisibility(bool visible) + public ResultCode SetApplicationCopyrightVisibility(ServiceCtx context) + { + bool visible = context.RequestData.ReadBoolean(); + + Logger.PrintStub(LogClass.ServiceAm, new { visible }); + + // NOTE: It sets an internal field and return ResultCode.Success in all case. + + return ResultCode.Success; + } + [Command(110)] // 5.0.0+ // QueryApplicationPlayStatistics(buffer title_id_list) -> (buffer entries, s32 entries_count) public ResultCode QueryApplicationPlayStatistics(ServiceCtx context) diff --git a/Ryujinx.HLE/HOS/Services/Am/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Am/ResultCode.cs index d8979f4af..2ff83d7f4 100644 --- a/Ryujinx.HLE/HOS/Services/Am/ResultCode.cs +++ b/Ryujinx.HLE/HOS/Services/Am/ResultCode.cs @@ -7,10 +7,11 @@ namespace Ryujinx.HLE.HOS.Services.Am Success = 0, - NotAvailable = (2 << ErrorCodeShift) | ModuleId, - NoMessages = (3 << ErrorCodeShift) | ModuleId, - ObjectInvalid = (500 << ErrorCodeShift) | ModuleId, - OutOfBounds = (503 << ErrorCodeShift) | ModuleId, - CpuBoostModeInvalid = (506 << ErrorCodeShift) | ModuleId + NotAvailable = (2 << ErrorCodeShift) | ModuleId, + NoMessages = (3 << ErrorCodeShift) | ModuleId, + ObjectInvalid = (500 << ErrorCodeShift) | ModuleId, + OutOfBounds = (503 << ErrorCodeShift) | ModuleId, + InvalidParameters = (506 << ErrorCodeShift) | ModuleId, + NullObject = (518 << ErrorCodeShift) | ModuleId } } \ No newline at end of file