settings: Implement GetDeviceNickName and SetDeviceNickName (#2383)

* settings: Implement GetDeviceNickName and SetDeviceNickName

This PR implement `set` and `sys:set` calls : `GetDeviceNickName` and `SetDeviceNickName` accordingly to RE.
I've cleaned up both services a bit and `SystemStateMgr` class too.

Closes #2110

* Addresses gdkchan_s feedback
This commit is contained in:
Ac_K 2021-06-24 01:18:36 +02:00 committed by GitHub
parent 55e0c71489
commit e053663f27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 23 deletions

View file

@ -1,6 +1,7 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.SystemState; using Ryujinx.HLE.HOS.SystemState;
using System; using System;
using System.Text;
namespace Ryujinx.HLE.HOS.Services.Settings namespace Ryujinx.HLE.HOS.Services.Settings
{ {
@ -117,11 +118,33 @@ namespace Ryujinx.HLE.HOS.Services.Settings
return GetKeyCodeMapImpl(context, 2); return GetKeyCodeMapImpl(context, 2);
} }
public ResultCode GetKeyCodeMapImpl(ServiceCtx context, int version) [CommandHipc(11)] // 10.1.0+
// GetDeviceNickName() -> buffer<nn::settings::system::DeviceNickName, 0x16>
public ResultCode GetDeviceNickName(ServiceCtx context)
{
ulong deviceNickNameBufferPosition = context.Request.ReceiveBuff[0].Position;
ulong deviceNickNameBufferSize = context.Request.ReceiveBuff[0].Size;
if (deviceNickNameBufferPosition == 0)
{
return ResultCode.NullDeviceNicknameBuffer;
}
if (deviceNickNameBufferSize != 0x80)
{
Logger.Warning?.Print(LogClass.ServiceSet, "Wrong buffer size");
}
context.Memory.Write(deviceNickNameBufferPosition, Encoding.ASCII.GetBytes(context.Device.System.State.DeviceNickName + '\0'));
return ResultCode.Success;
}
private ResultCode GetKeyCodeMapImpl(ServiceCtx context, int version)
{ {
if (context.Request.ReceiveBuff[0].Size != 0x1000) if (context.Request.ReceiveBuff[0].Size != 0x1000)
{ {
Logger.Warning?.Print(LogClass.ServiceSet, "Bad size"); Logger.Warning?.Print(LogClass.ServiceSet, "Wrong buffer size");
} }
byte[] keyCodeMap; byte[] keyCodeMap;
@ -200,7 +223,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings
return ResultCode.Success; return ResultCode.Success;
} }
public ResultCode GetAvailableLanguagesCodesImpl(ServiceCtx context, ulong position, ulong size, int maxSize) private ResultCode GetAvailableLanguagesCodesImpl(ServiceCtx context, ulong position, ulong size, int maxSize)
{ {
int count = (int)(size / 8); int count = (int)(size / 8);

View file

@ -228,7 +228,45 @@ namespace Ryujinx.HLE.HOS.Services.Settings
// NOTE: When set to true, is automatically synced with the internet. // NOTE: When set to true, is automatically synced with the internet.
context.ResponseData.Write(true); context.ResponseData.Write(true);
Logger.Stub?.PrintStub(LogClass.ServiceSet, "Stubbed"); Logger.Stub?.PrintStub(LogClass.ServiceSet);
return ResultCode.Success;
}
[CommandHipc(77)]
// GetDeviceNickName() -> buffer<nn::settings::system::DeviceNickName, 0x16>
public ResultCode GetDeviceNickName(ServiceCtx context)
{
ulong deviceNickNameBufferPosition = context.Request.ReceiveBuff[0].Position;
ulong deviceNickNameBufferSize = context.Request.ReceiveBuff[0].Size;
if (deviceNickNameBufferPosition == 0)
{
return ResultCode.NullDeviceNicknameBuffer;
}
if (deviceNickNameBufferSize != 0x80)
{
Logger.Warning?.Print(LogClass.ServiceSet, "Wrong buffer size");
}
context.Memory.Write(deviceNickNameBufferPosition, Encoding.ASCII.GetBytes(context.Device.System.State.DeviceNickName + '\0'));
return ResultCode.Success;
}
[CommandHipc(78)]
// SetDeviceNickName(buffer<nn::settings::system::DeviceNickName, 0x15>)
public ResultCode SetDeviceNickName(ServiceCtx context)
{
ulong deviceNickNameBufferPosition = context.Request.SendBuff[0].Position;
ulong deviceNickNameBufferSize = context.Request.SendBuff[0].Size;
byte[] deviceNickNameBuffer = new byte[deviceNickNameBufferSize];
context.Memory.Read(deviceNickNameBufferPosition, deviceNickNameBuffer);
context.Device.System.State.DeviceNickName = Encoding.ASCII.GetString(deviceNickNameBuffer);
return ResultCode.Success; return ResultCode.Success;
} }

View file

@ -35,39 +35,32 @@ namespace Ryujinx.HLE.HOS.SystemState
public TitleLanguage DesiredTitleLanguage { get; private set; } public TitleLanguage DesiredTitleLanguage { get; private set; }
internal string ActiveAudioOutput { get; private set; }
public bool DockedMode { get; set; } public bool DockedMode { get; set; }
public ColorSet ThemeColor { get; set; } public ColorSet ThemeColor { get; set; }
public bool InstallContents { get; set; } public string DeviceNickName { get; set; }
public SystemStateMgr() public SystemStateMgr()
{ {
// TODO: Let user specify. // TODO: Let user specify fields.
DesiredKeyboardLayout = (long)KeyboardLayout.Default; DesiredKeyboardLayout = (long)KeyboardLayout.Default;
DeviceNickName = "Ryujinx's Switch";
} }
public void SetLanguage(SystemLanguage language) public void SetLanguage(SystemLanguage language)
{ {
DesiredSystemLanguage = language; DesiredSystemLanguage = language;
DesiredLanguageCode = GetLanguageCode((int)DesiredSystemLanguage); DesiredLanguageCode = GetLanguageCode((int)DesiredSystemLanguage);
switch (language) DesiredTitleLanguage = language switch
{ {
case SystemLanguage.Taiwanese: SystemLanguage.Taiwanese or
case SystemLanguage.TraditionalChinese: SystemLanguage.TraditionalChinese => TitleLanguage.Taiwanese,
DesiredTitleLanguage = TitleLanguage.Taiwanese; SystemLanguage.Chinese or
break; SystemLanguage.SimplifiedChinese => TitleLanguage.Chinese,
case SystemLanguage.Chinese: _ => Enum.Parse<TitleLanguage>(Enum.GetName(typeof(SystemLanguage), language)),
case SystemLanguage.SimplifiedChinese: };
DesiredTitleLanguage = TitleLanguage.Chinese;
break;
default:
DesiredTitleLanguage = Enum.Parse<TitleLanguage>(Enum.GetName(typeof(SystemLanguage), language));
break;
}
} }
public void SetRegion(RegionCode region) public void SetRegion(RegionCode region)