ErrorApplet: Implement ApplicationErrorArg (#2123)

This PR implement `ApplicationErrorArg` to the Error Applet. It's used by the guest to throw some specific error messages.
The code was done for (and merged) LDN2 build since long time ago and have been tested a bunch of times because of that! In a way to reduce the differences between LDN and master build it's fine to add it to master.
This commit is contained in:
Ac_K 2021-03-19 00:04:49 +01:00 committed by GitHub
parent ca848d6359
commit db56b2166d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 0 deletions

View file

@ -0,0 +1,13 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Applets.Error
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct ApplicationErrorArg
{
public uint ErrorNumber;
public ulong LanguageCode;
public fixed byte MessageText[0x800];
public fixed byte DetailsText[0x800];
}
}

View file

@ -8,6 +8,7 @@ using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
using Ryujinx.HLE.HOS.SystemState;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
@ -51,6 +52,12 @@ namespace Ryujinx.HLE.HOS.Applets.Error
{
ParseErrorCommonArg();
break;
}
case ErrorType.ApplicationErrorArg:
{
ParseApplicationErrorArg();
break;
}
default: throw new NotImplementedException($"ErrorApplet type {_errorCommonHeader.Type} is not implemented.");
@ -163,6 +170,41 @@ namespace Ryujinx.HLE.HOS.Applets.Error
}
}
private void ParseApplicationErrorArg()
{
ApplicationErrorArg applicationErrorArg = IApplet.ReadStruct<ApplicationErrorArg>(_errorStorage);
byte[] messageTextBuffer = new byte[0x800];
byte[] detailsTextBuffer = new byte[0x800];
unsafe
{
Marshal.Copy((IntPtr)applicationErrorArg.MessageText, messageTextBuffer, 0, 0x800);
Marshal.Copy((IntPtr)applicationErrorArg.DetailsText, detailsTextBuffer, 0, 0x800);
}
string messageText = Encoding.ASCII.GetString(messageTextBuffer.TakeWhile(b => !b.Equals(0)).ToArray());
string detailsText = Encoding.ASCII.GetString(detailsTextBuffer.TakeWhile(b => !b.Equals(0)).ToArray());
List<string> buttons = new List<string>();
// TODO: Handle the LanguageCode to return the translated "OK" and "Details".
if (detailsText.Trim() != "")
{
buttons.Add("Details");
}
buttons.Add("OK");
bool showDetails = _horizon.Device.UiHandler.DisplayErrorAppletDialog($"Error Number: {applicationErrorArg.ErrorNumber}", "\n" + messageText, buttons.ToArray());
if (showDetails)
{
buttons.RemoveAt(0);
_horizon.Device.UiHandler.DisplayErrorAppletDialog($"Error Number: {applicationErrorArg.ErrorNumber} (Details)", "\n" + detailsText, buttons.ToArray());
}
}
public ResultCode GetResult()
{
return ResultCode.Success;