diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Services')
147 files changed, 2653 insertions, 1419 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs index d36ea931..2cea57e9 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs @@ -1,41 +1,85 @@ -using Ryujinx.Common; +using LibHac; +using LibHac.Fs; +using LibHac.Fs.Shim; +using Ryujinx.Common; +using Ryujinx.HLE.FileSystem; +using Ryujinx.HLE.FileSystem.Content; +using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Linq; namespace Ryujinx.HLE.HOS.Services.Account.Acc { public class AccountManager { + public static readonly UserId DefaultUserId = new UserId("00000000000000010000000000000000"); + + private readonly VirtualFileSystem _virtualFileSystem; + private readonly AccountSaveDataManager _accountSaveDataManager; + private ConcurrentDictionary<string, UserProfile> _profiles; public UserProfile LastOpenedUser { get; private set; } - public AccountManager() + public AccountManager(VirtualFileSystem virtualFileSystem) { + _virtualFileSystem = virtualFileSystem; + _profiles = new ConcurrentDictionary<string, UserProfile>(); - UserId defaultUserId = new UserId("00000000000000010000000000000000"); - byte[] defaultUserImage = EmbeddedResources.Read("Ryujinx.HLE/HOS/Services/Account/Acc/DefaultUserImage.jpg"); + _accountSaveDataManager = new AccountSaveDataManager(_profiles); + + if (!_profiles.TryGetValue(DefaultUserId.ToString(), out _)) + { + byte[] defaultUserImage = EmbeddedResources.Read("Ryujinx.HLE/HOS/Services/Account/Acc/DefaultUserImage.jpg"); - AddUser(defaultUserId, "Player", defaultUserImage); - - OpenUser(defaultUserId); + AddUser("RyuPlayer", defaultUserImage, DefaultUserId); + + OpenUser(DefaultUserId); + } + else + { + OpenUser(_accountSaveDataManager.LastOpened); + } } - public void AddUser(UserId userId, string name, byte[] image) + public void AddUser(string name, byte[] image, UserId userId = new UserId()) { + if (userId.IsNull) + { + userId = new UserId(Guid.NewGuid().ToString().Replace("-", "")); + } + UserProfile profile = new UserProfile(userId, name, image); _profiles.AddOrUpdate(userId.ToString(), profile, (key, old) => profile); + + _accountSaveDataManager.Save(_profiles); } public void OpenUser(UserId userId) { if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile)) { + // TODO: Support multiple open users ? + foreach (UserProfile userProfile in GetAllUsers()) + { + if (userProfile == LastOpenedUser) + { + userProfile.AccountState = AccountState.Closed; + + break; + } + } + (LastOpenedUser = profile).AccountState = AccountState.Open; + + _accountSaveDataManager.LastOpened = userId; } + + _accountSaveDataManager.Save(_profiles); } public void CloseUser(UserId userId) @@ -44,9 +88,117 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc { profile.AccountState = AccountState.Closed; } + + _accountSaveDataManager.Save(_profiles); + } + + public void OpenUserOnlinePlay(UserId userId) + { + if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile)) + { + // TODO: Support multiple open online users ? + foreach (UserProfile userProfile in GetAllUsers()) + { + if (userProfile == LastOpenedUser) + { + userProfile.OnlinePlayState = AccountState.Closed; + + break; + } + } + + profile.OnlinePlayState = AccountState.Open; + } + + _accountSaveDataManager.Save(_profiles); + } + + public void CloseUserOnlinePlay(UserId userId) + { + if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile)) + { + profile.OnlinePlayState = AccountState.Closed; + } + + _accountSaveDataManager.Save(_profiles); + } + + public void SetUserImage(UserId userId, byte[] image) + { + foreach (UserProfile userProfile in GetAllUsers()) + { + if (userProfile.UserId == userId) + { + userProfile.Image = image; + + break; + } + } + + _accountSaveDataManager.Save(_profiles); + } + + public void SetUserName(UserId userId, string name) + { + foreach (UserProfile userProfile in GetAllUsers()) + { + if (userProfile.UserId == userId) + { + userProfile.Name = name; + + break; + } + } + + _accountSaveDataManager.Save(_profiles); + } + + public void DeleteUser(UserId userId) + { + DeleteSaveData(userId); + + _profiles.Remove(userId.ToString(), out _); + + OpenUser(DefaultUserId); + + _accountSaveDataManager.Save(_profiles); + } + + private void DeleteSaveData(UserId userId) + { + SaveDataFilter saveDataFilter = new SaveDataFilter(); + saveDataFilter.SetUserId(new LibHac.Fs.UserId((ulong)userId.High, (ulong)userId.Low)); + + Result result = _virtualFileSystem.FsClient.OpenSaveDataIterator(out SaveDataIterator saveDataIterator, SaveDataSpaceId.User, ref saveDataFilter); + if (result.IsSuccess()) + { + Span<SaveDataInfo> saveDataInfo = stackalloc SaveDataInfo[10]; + + while (true) + { + saveDataIterator.ReadSaveDataInfo(out long readCount, saveDataInfo); + + if (readCount == 0) + { + break; + } + + for (int i = 0; i < readCount; i++) + { + // TODO: We use Directory.Delete workaround because DeleteSaveData softlock without, due to a bug in LibHac 0.12.0. + string savePath = Path.Combine(_virtualFileSystem.GetNandPath(), $"user/save/{saveDataInfo[i].SaveDataId:x16}"); + string saveMetaPath = Path.Combine(_virtualFileSystem.GetNandPath(), $"user/saveMeta/{saveDataInfo[i].SaveDataId:x16}"); + + Directory.Delete(savePath, true); + Directory.Delete(saveMetaPath, true); + + _virtualFileSystem.FsClient.DeleteSaveData(SaveDataSpaceId.User, saveDataInfo[i].SaveDataId); + } + } + } } - public int GetUserCount() + internal int GetUserCount() { return _profiles.Count; } @@ -56,7 +208,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc return _profiles.TryGetValue(userId.ToString(), out profile); } - internal IEnumerable<UserProfile> GetAllUsers() + public IEnumerable<UserProfile> GetAllUsers() { return _profiles.Values; } diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs new file mode 100644 index 00000000..44ef3f33 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs @@ -0,0 +1,87 @@ +using Ryujinx.Common.Configuration; +using Ryujinx.Common.Utilities; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Text.Json.Serialization; + +namespace Ryujinx.HLE.HOS.Services.Account.Acc +{ + class AccountSaveDataManager + { + private readonly string _profilesJsonPath = Path.Join(AppDataManager.BaseDirPath, "system", "Profiles.json"); + + private struct ProfilesJson + { + [JsonPropertyName("profiles")] + public List<UserProfileJson> Profiles { get; set; } + [JsonPropertyName("last_opened")] + public string LastOpened { get; set; } + } + + private struct UserProfileJson + { + [JsonPropertyName("user_id")] + public string UserId { get; set; } + [JsonPropertyName("name")] + public string Name { get; set; } + [JsonPropertyName("account_state")] + public AccountState AccountState { get; set; } + [JsonPropertyName("online_play_state")] + public AccountState OnlinePlayState { get; set; } + [JsonPropertyName("last_modified_timestamp")] + public long LastModifiedTimestamp { get; set; } + [JsonPropertyName("image")] + public byte[] Image { get; set; } + } + + public UserId LastOpened { get; set; } + + public AccountSaveDataManager(ConcurrentDictionary<string, UserProfile> profiles) + { + // TODO: Use 0x8000000000000010 system savedata instead of a JSON file if needed. + + if (File.Exists(_profilesJsonPath)) + { + ProfilesJson profilesJson = JsonHelper.DeserializeFromFile<ProfilesJson>(_profilesJsonPath); + + foreach (var profile in profilesJson.Profiles) + { + UserProfile addedProfile = new UserProfile(new UserId(profile.UserId), profile.Name, profile.Image, profile.LastModifiedTimestamp); + + profiles.AddOrUpdate(profile.UserId, addedProfile, (key, old) => addedProfile); + } + + LastOpened = new UserId(profilesJson.LastOpened); + } + else + { + LastOpened = AccountManager.DefaultUserId; + } + } + + public void Save(ConcurrentDictionary<string, UserProfile> profiles) + { + ProfilesJson profilesJson = new ProfilesJson() + { + Profiles = new List<UserProfileJson>(), + LastOpened = LastOpened.ToString() + }; + + foreach (var profile in profiles) + { + profilesJson.Profiles.Add(new UserProfileJson() + { + UserId = profile.Value.UserId.ToString(), + Name = profile.Value.Name, + AccountState = profile.Value.AccountState, + OnlinePlayState = profile.Value.OnlinePlayState, + LastModifiedTimestamp = profile.Value.LastModifiedTimestamp, + Image = profile.Value.Image, + }); + } + + File.WriteAllText(_profilesJsonPath, JsonHelper.Serialize(profilesJson, true)); + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs index c7efe778..471942f1 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs @@ -73,8 +73,8 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService public ResultCode LoadIdTokenCache(ServiceCtx context) { - long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferSize = context.Request.ReceiveBuff[0].Size; + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferSize = context.Request.ReceiveBuff[0].Size; // NOTE: This opens the file at "su/cache/USERID_IN_UUID_STRING.dat" (where USERID_IN_UUID_STRING is formatted as "%08x-%04x-%04x-%02x%02x-%08x%04x") // in the "account:/" savedata and writes some data in the buffer. diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ProfileServer.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ProfileServer.cs index 18534393..8e29f94b 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ProfileServer.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ProfileServer.cs @@ -16,16 +16,16 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService public ResultCode Get(ServiceCtx context) { - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(0x80L); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(0x80UL); - long bufferPosition = context.Request.RecvListBuff[0].Position; + ulong bufferPosition = context.Request.RecvListBuff[0].Position; MemoryHelper.FillWithZeros(context.Memory, bufferPosition, 0x80); // TODO: Determine the struct. - context.Memory.Write((ulong)bufferPosition, 0); // Unknown - context.Memory.Write((ulong)bufferPosition + 4, 1); // Icon ID. 0 = Mii, the rest are character icon IDs. - context.Memory.Write((ulong)bufferPosition + 8, (byte)1); // Profile icon background color ID + context.Memory.Write(bufferPosition, 0); // Unknown + context.Memory.Write(bufferPosition + 4, 1); // Icon ID. 0 = Mii, the rest are character icon IDs. + context.Memory.Write(bufferPosition + 8, (byte)1); // Profile icon background color ID // 0x07 bytes - Unknown // 0x10 bytes - Some ID related to the Mii? All zeros when a character icon is used. // 0x60 bytes - Usually zeros? @@ -57,15 +57,15 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService public ResultCode LoadImage(ServiceCtx context) { - long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferLen = context.Request.ReceiveBuff[0].Size; + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferLen = context.Request.ReceiveBuff[0].Size; - if (_profile.Image.Length > bufferLen) + if ((ulong)_profile.Image.Length > bufferLen) { return ResultCode.InvalidBufferSize; } - context.Memory.Write((ulong)bufferPosition, _profile.Image); + context.Memory.Write(bufferPosition, _profile.Image); context.ResponseData.Write(_profile.Image.Length); @@ -74,12 +74,12 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService public ResultCode Store(ServiceCtx context) { - long userDataPosition = context.Request.PtrBuff[0].Position; - long userDataSize = context.Request.PtrBuff[0].Size; + ulong userDataPosition = context.Request.PtrBuff[0].Position; + ulong userDataSize = context.Request.PtrBuff[0].Size; byte[] userData = new byte[userDataSize]; - context.Memory.Read((ulong)userDataPosition, userData); + context.Memory.Read(userDataPosition, userData); // TODO: Read the nn::account::profile::ProfileBase and store everything in the savedata. @@ -90,19 +90,19 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService public ResultCode StoreWithImage(ServiceCtx context) { - long userDataPosition = context.Request.PtrBuff[0].Position; - long userDataSize = context.Request.PtrBuff[0].Size; + ulong userDataPosition = context.Request.PtrBuff[0].Position; + ulong userDataSize = context.Request.PtrBuff[0].Size; byte[] userData = new byte[userDataSize]; - context.Memory.Read((ulong)userDataPosition, userData); + context.Memory.Read(userDataPosition, userData); - long profileImagePosition = context.Request.SendBuff[0].Position; - long profileImageSize = context.Request.SendBuff[0].Size; + ulong profileImagePosition = context.Request.SendBuff[0].Position; + ulong profileImageSize = context.Request.SendBuff[0].Size; byte[] profileImageData = new byte[profileImageSize]; - context.Memory.Read((ulong)profileImagePosition, profileImageData); + context.Memory.Read(profileImagePosition, profileImageData); // TODO: Read the nn::account::profile::ProfileBase and store everything in the savedata. diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/ApplicationServiceServer.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/ApplicationServiceServer.cs index 29cce5d7..794c72ce 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/ApplicationServiceServer.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/ApplicationServiceServer.cs @@ -53,8 +53,8 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc return ResultCode.InvalidBuffer; } - long outputPosition = context.Request.RecvListBuff[0].Position; - long outputSize = context.Request.RecvListBuff[0].Size; + ulong outputPosition = context.Request.RecvListBuff[0].Position; + ulong outputSize = context.Request.RecvListBuff[0].Size; MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize); @@ -67,8 +67,8 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc break; } - context.Memory.Write((ulong)outputPosition + offset, userProfile.UserId.High); - context.Memory.Write((ulong)outputPosition + offset + 8, userProfile.UserId.Low); + context.Memory.Write(outputPosition + offset, userProfile.UserId.High); + context.Memory.Write(outputPosition + offset + 8, userProfile.UserId.Low); offset += 0x10; } @@ -156,8 +156,8 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc return ResultCode.InvalidBuffer; } - long inputPosition = context.Request.SendBuff[0].Position; - long inputSize = context.Request.SendBuff[0].Size; + ulong inputPosition = context.Request.SendBuff[0].Position; + ulong inputSize = context.Request.SendBuff[0].Size; if (inputSize != 0x24000) { @@ -166,7 +166,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc byte[] thumbnailBuffer = new byte[inputSize]; - context.Memory.Read((ulong)inputPosition, thumbnailBuffer); + context.Memory.Read(inputPosition, thumbnailBuffer); // NOTE: Account service call nn::fs::WriteSaveDataThumbnailFile(). // TODO: Store thumbnailBuffer somewhere, in save data 0x8000000000000010 ? diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs index 6067dc44..2fbf950c 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs @@ -142,8 +142,8 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc // ListOpenContextStoredUsers() -> array<nn::account::Uid, 0xa> public ResultCode ListOpenContextStoredUsers(ServiceCtx context) { - long outputPosition = context.Request.RecvListBuff[0].Position; - long outputSize = context.Request.RecvListBuff[0].Size; + ulong outputPosition = context.Request.RecvListBuff[0].Position; + ulong outputSize = context.Request.RecvListBuff[0].Size; MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize); diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfile.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfile.cs index a57796c9..ef0a1a64 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfile.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfile.cs @@ -8,31 +8,80 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc public UserId UserId { get; } - public string Name { get; } + public long LastModifiedTimestamp { get; set; } - public byte[] Image { get; } + private string _name; - public long LastModifiedTimestamp { get; private set; } + public string Name + { + get => _name; + set + { + _name = value; + + UpdateLastModifiedTimestamp(); + } + } - public AccountState AccountState { get; set; } - public AccountState OnlinePlayState { get; set; } + private byte[] _image; - public UserProfile(UserId userId, string name, byte[] image) + public byte[] Image { - UserId = userId; - Name = name; + get => _image; + set + { + _image = value; - Image = image; + UpdateLastModifiedTimestamp(); + } + } + + private AccountState _accountState; - LastModifiedTimestamp = 0; + public AccountState AccountState + { + get => _accountState; + set + { + _accountState = value; + + UpdateLastModifiedTimestamp(); + } + } + + public AccountState _onlinePlayState; + + public AccountState OnlinePlayState + { + get => _onlinePlayState; + set + { + _onlinePlayState = value; + + UpdateLastModifiedTimestamp(); + } + } + + public UserProfile(UserId userId, string name, byte[] image, long lastModifiedTimestamp = 0) + { + UserId = userId; + Name = name; + Image = image; AccountState = AccountState.Closed; OnlinePlayState = AccountState.Closed; - UpdateTimestamp(); + if (lastModifiedTimestamp != 0) + { + LastModifiedTimestamp = lastModifiedTimestamp; + } + else + { + UpdateLastModifiedTimestamp(); + } } - private void UpdateTimestamp() + private void UpdateLastModifiedTimestamp() { LastModifiedTimestamp = (long)(DateTime.Now - Epoch).TotalSeconds; } diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorageAccessor.cs b/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorageAccessor.cs index cdc59678..33f5393f 100644 --- a/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorageAccessor.cs +++ b/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorageAccessor.cs @@ -29,20 +29,20 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE return ResultCode.ObjectInvalid; } - long writePosition = context.RequestData.ReadInt64(); + ulong writePosition = context.RequestData.ReadUInt64(); - if (writePosition > _storage.Data.Length) + if (writePosition > (ulong)_storage.Data.Length) { return ResultCode.OutOfBounds; } - (long position, long size) = context.Request.GetBufferType0x21(); + (ulong position, ulong size) = context.Request.GetBufferType0x21(); - size = Math.Min(size, _storage.Data.Length - writePosition); + size = Math.Min(size, (ulong)_storage.Data.Length - writePosition); if (size > 0) { - long maxSize = _storage.Data.Length - writePosition; + ulong maxSize = (ulong)_storage.Data.Length - writePosition; if (size > maxSize) { @@ -51,7 +51,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE byte[] data = new byte[size]; - context.Memory.Read((ulong)position, data); + context.Memory.Read(position, data); Buffer.BlockCopy(data, 0, _storage.Data, (int)writePosition, (int)size); } @@ -63,22 +63,22 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE // Read(u64) -> buffer<bytes, 0x22> public ResultCode Read(ServiceCtx context) { - long readPosition = context.RequestData.ReadInt64(); + ulong readPosition = context.RequestData.ReadUInt64(); - if (readPosition > _storage.Data.Length) + if (readPosition > (ulong)_storage.Data.Length) { return ResultCode.OutOfBounds; } - (long position, long size) = context.Request.GetBufferType0x22(); + (ulong position, ulong size) = context.Request.GetBufferType0x22(); - size = Math.Min(size, _storage.Data.Length - readPosition); + size = Math.Min(size, (ulong)_storage.Data.Length - readPosition); byte[] data = new byte[size]; Buffer.BlockCopy(_storage.Data, (int)readPosition, data, 0, (int)size); - context.Memory.Write((ulong)position, data); + context.Memory.Write(position, data); return ResultCode.Success; } 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 a1a5d8c4..e0633145 100644 --- a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs +++ b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs @@ -57,7 +57,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati switch (kind) { case LaunchParameterKind.UserChannel: - storageData = context.Device.UserChannelPersistence.Pop(); + storageData = context.Device.Configuration.UserChannelPersistence.Pop(); break; case LaunchParameterKind.PreselectedUser: // Only the first 0x18 bytes of the Data seems to be actually used. @@ -359,13 +359,13 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati // SetApplicationCopyrightImage(buffer<bytes, 0x45> 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(); + ulong frameBufferPos = context.Request.SendBuff[0].Position; + ulong 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; @@ -388,7 +388,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati return resultCode; } - private ResultCode SetApplicationCopyrightImageImpl(int x, int y, int width, int height, long frameBufferPos, long frameBufferSize, uint windowOriginMode) + private ResultCode SetApplicationCopyrightImageImpl(int x, int y, int width, int height, ulong frameBufferPos, ulong frameBufferSize, uint windowOriginMode) { /* if (_copyrightBuffer == null) @@ -453,7 +453,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati // ClearUserChannel() public ResultCode ClearUserChannel(ServiceCtx context) { - context.Device.UserChannelPersistence.Clear(); + context.Device.Configuration.UserChannelPersistence.Clear(); return ResultCode.Success; } @@ -464,7 +464,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati { AppletAE.IStorage data = GetObject<AppletAE.IStorage>(context, 0); - context.Device.UserChannelPersistence.Push(data.Data); + context.Device.Configuration.UserChannelPersistence.Push(data.Data); return ResultCode.Success; } @@ -473,7 +473,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati // GetPreviousProgramIndex() -> s32 program_index public ResultCode GetPreviousProgramIndex(ServiceCtx context) { - int previousProgramIndex = context.Device.UserChannelPersistence.PreviousIndex; + int previousProgramIndex = context.Device.Configuration.UserChannelPersistence.PreviousIndex; context.ResponseData.Write(previousProgramIndex); diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs index a89abce7..b45a4d2c 100644 --- a/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs @@ -45,7 +45,7 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioIn // AppendAudioInBuffer(u64 tag, buffer<nn::audio::AudioInBuffer, 5>) public ResultCode AppendAudioInBuffer(ServiceCtx context) { - long position = context.Request.SendBuff[0].Position; + ulong position = context.Request.SendBuff[0].Position; ulong bufferTag = context.RequestData.ReadUInt64(); @@ -74,8 +74,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioIn // GetReleasedAudioInBuffers() -> (u32 count, buffer<u64, 6> tags) public ResultCode GetReleasedAudioInBuffers(ServiceCtx context) { - long position = context.Request.ReceiveBuff[0].Position; - long size = context.Request.ReceiveBuff[0].Size; + ulong position = context.Request.ReceiveBuff[0].Position; + ulong size = context.Request.ReceiveBuff[0].Size; using (WritableRegion outputRegion = context.Memory.GetWritableRegion((ulong)position, (int)size)) { @@ -102,7 +102,7 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioIn // AppendUacInBuffer(u64 tag, handle<copy, unknown>, buffer<nn::audio::AudioInBuffer, 5>) public ResultCode AppendUacInBuffer(ServiceCtx context) { - long position = context.Request.SendBuff[0].Position; + ulong position = context.Request.SendBuff[0].Position; ulong bufferTag = context.RequestData.ReadUInt64(); uint handle = (uint)context.Request.HandleDesc.ToCopy[0]; @@ -116,7 +116,7 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioIn // AppendAudioInBufferAuto(u64 tag, buffer<nn::audio::AudioInBuffer, 0x21>) public ResultCode AppendAudioInBufferAuto(ServiceCtx context) { - (long position, _) = context.Request.GetBufferType0x21(); + (ulong position, _) = context.Request.GetBufferType0x21(); ulong bufferTag = context.RequestData.ReadUInt64(); @@ -129,9 +129,9 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioIn // GetReleasedAudioInBuffersAuto() -> (u32 count, buffer<u64, 0x22> tags) public ResultCode GetReleasedAudioInBuffersAuto(ServiceCtx context) { - (long position, long size) = context.Request.GetBufferType0x22(); + (ulong position, ulong size) = context.Request.GetBufferType0x22(); - using (WritableRegion outputRegion = context.Memory.GetWritableRegion((ulong)position, (int)size)) + using (WritableRegion outputRegion = context.Memory.GetWritableRegion(position, (int)size)) { ResultCode result = _impl.GetReleasedBuffers(MemoryMarshal.Cast<byte, ulong>(outputRegion.Memory.Span), out uint releasedCount); @@ -145,7 +145,7 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioIn // AppendUacInBufferAuto(u64 tag, handle<copy, event>, buffer<nn::audio::AudioInBuffer, 0x21>) public ResultCode AppendUacInBufferAuto(ServiceCtx context) { - (long position, _) = context.Request.GetBufferType0x21(); + (ulong position, _) = context.Request.GetBufferType0x21(); ulong bufferTag = context.RequestData.ReadUInt64(); uint handle = (uint)context.Request.HandleDesc.ToCopy[0]; diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioInManagerServer.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioInManagerServer.cs index 4806ebe9..7b243c71 100644 --- a/Ryujinx.HLE/HOS/Services/Audio/AudioInManagerServer.cs +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioInManagerServer.cs @@ -27,10 +27,10 @@ namespace Ryujinx.HLE.HOS.Services.Audio { string[] deviceNames = _impl.ListAudioIns(false); - long position = context.Request.ReceiveBuff[0].Position; - long size = context.Request.ReceiveBuff[0].Size; + ulong position = context.Request.ReceiveBuff[0].Position; + ulong size = context.Request.ReceiveBuff[0].Size; - long basePosition = position; + ulong basePosition = position; int count = 0; @@ -38,15 +38,15 @@ namespace Ryujinx.HLE.HOS.Services.Audio { byte[] buffer = Encoding.ASCII.GetBytes(name); - if ((position - basePosition) + buffer.Length > size) + if ((position - basePosition) + (ulong)buffer.Length > size) { Logger.Error?.Print(LogClass.ServiceAudio, $"Output buffer size {size} too small!"); break; } - context.Memory.Write((ulong)position, buffer); - MemoryHelper.FillWithZeros(context.Memory, position + buffer.Length, AudioInNameSize - buffer.Length); + context.Memory.Write(position, buffer); + MemoryHelper.FillWithZeros(context.Memory, position + (ulong)buffer.Length, AudioInNameSize - buffer.Length); position += AudioInNameSize; count++; @@ -65,15 +65,15 @@ namespace Ryujinx.HLE.HOS.Services.Audio AudioInputConfiguration inputConfiguration = context.RequestData.ReadStruct<AudioInputConfiguration>(); ulong appletResourceUserId = context.RequestData.ReadUInt64(); - long deviceNameInputPosition = context.Request.SendBuff[0].Position; - long deviceNameInputSize = context.Request.SendBuff[0].Size; + ulong deviceNameInputPosition = context.Request.SendBuff[0].Position; + ulong deviceNameInputSize = context.Request.SendBuff[0].Size; - long deviceNameOutputPosition = context.Request.ReceiveBuff[0].Position; - long deviceNameOutputSize = context.Request.ReceiveBuff[0].Size; + ulong deviceNameOutputPosition = context.Request.ReceiveBuff[0].Position; + ulong deviceNameOutputSize = context.Request.ReceiveBuff[0].Size; uint processHandle = (uint)context.Request.HandleDesc.ToCopy[0]; - string inputDeviceName = MemoryHelper.ReadAsciiString(context.Memory, deviceNameInputPosition, deviceNameInputSize); + string inputDeviceName = MemoryHelper.ReadAsciiString(context.Memory, deviceNameInputPosition, (long)deviceNameInputSize); ResultCode resultCode = _impl.OpenAudioIn(context, out string outputDeviceName, out AudioOutputConfiguration outputConfiguration, out IAudioIn obj, inputDeviceName, ref inputConfiguration, appletResourceUserId, processHandle); @@ -83,8 +83,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio byte[] outputDeviceNameRaw = Encoding.ASCII.GetBytes(outputDeviceName); - context.Memory.Write((ulong)deviceNameOutputPosition, outputDeviceNameRaw); - MemoryHelper.FillWithZeros(context.Memory, deviceNameOutputPosition + outputDeviceNameRaw.Length, AudioInNameSize - outputDeviceNameRaw.Length); + context.Memory.Write(deviceNameOutputPosition, outputDeviceNameRaw); + MemoryHelper.FillWithZeros(context.Memory, deviceNameOutputPosition + (ulong)outputDeviceNameRaw.Length, AudioInNameSize - outputDeviceNameRaw.Length); MakeObject(context, new AudioInServer(obj)); } @@ -98,9 +98,9 @@ namespace Ryujinx.HLE.HOS.Services.Audio { string[] deviceNames = _impl.ListAudioIns(false); - (long position, long size) = context.Request.GetBufferType0x22(); + (ulong position, ulong size) = context.Request.GetBufferType0x22(); - long basePosition = position; + ulong basePosition = position; int count = 0; @@ -108,15 +108,15 @@ namespace Ryujinx.HLE.HOS.Services.Audio { byte[] buffer = Encoding.ASCII.GetBytes(name); - if ((position - basePosition) + buffer.Length > size) + if ((position - basePosition) + (ulong)buffer.Length > size) { Logger.Error?.Print(LogClass.ServiceAudio, $"Output buffer size {size} too small!"); break; } - context.Memory.Write((ulong)position, buffer); - MemoryHelper.FillWithZeros(context.Memory, position + buffer.Length, AudioInNameSize - buffer.Length); + context.Memory.Write(position, buffer); + MemoryHelper.FillWithZeros(context.Memory, position + (ulong)buffer.Length, AudioInNameSize - buffer.Length); position += AudioInNameSize; count++; @@ -135,12 +135,12 @@ namespace Ryujinx.HLE.HOS.Services.Audio AudioInputConfiguration inputConfiguration = context.RequestData.ReadStruct<AudioInputConfiguration>(); ulong appletResourceUserId = context.RequestData.ReadUInt64(); - (long deviceNameInputPosition, long deviceNameInputSize) = context.Request.GetBufferType0x21(); - (long deviceNameOutputPosition, long deviceNameOutputSize) = context.Request.GetBufferType0x22(); + (ulong deviceNameInputPosition, ulong deviceNameInputSize) = context.Request.GetBufferType0x21(); + (ulong deviceNameOutputPosition, ulong deviceNameOutputSize) = context.Request.GetBufferType0x22(); uint processHandle = (uint)context.Request.HandleDesc.ToCopy[0]; - string inputDeviceName = MemoryHelper.ReadAsciiString(context.Memory, deviceNameInputPosition, deviceNameInputSize); + string inputDeviceName = MemoryHelper.ReadAsciiString(context.Memory, deviceNameInputPosition, (long)deviceNameInputSize); ResultCode resultCode = _impl.OpenAudioIn(context, out string outputDeviceName, out AudioOutputConfiguration outputConfiguration, out IAudioIn obj, inputDeviceName, ref inputConfiguration, appletResourceUserId, processHandle); @@ -150,8 +150,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio byte[] outputDeviceNameRaw = Encoding.ASCII.GetBytes(outputDeviceName); - context.Memory.Write((ulong)deviceNameOutputPosition, outputDeviceNameRaw); - MemoryHelper.FillWithZeros(context.Memory, deviceNameOutputPosition + outputDeviceNameRaw.Length, AudioInNameSize - outputDeviceNameRaw.Length); + context.Memory.Write(deviceNameOutputPosition, outputDeviceNameRaw); + MemoryHelper.FillWithZeros(context.Memory, deviceNameOutputPosition + (ulong)outputDeviceNameRaw.Length, AudioInNameSize - outputDeviceNameRaw.Length); MakeObject(context, new AudioInServer(obj)); } @@ -165,9 +165,9 @@ namespace Ryujinx.HLE.HOS.Services.Audio { string[] deviceNames = _impl.ListAudioIns(true); - (long position, long size) = context.Request.GetBufferType0x22(); + (ulong position, ulong size) = context.Request.GetBufferType0x22(); - long basePosition = position; + ulong basePosition = position; int count = 0; @@ -175,15 +175,15 @@ namespace Ryujinx.HLE.HOS.Services.Audio { byte[] buffer = Encoding.ASCII.GetBytes(name); - if ((position - basePosition) + buffer.Length > size) + if ((position - basePosition) + (ulong)buffer.Length > size) { Logger.Error?.Print(LogClass.ServiceAudio, $"Output buffer size {size} too small!"); break; } - context.Memory.Write((ulong)position, buffer); - MemoryHelper.FillWithZeros(context.Memory, position + buffer.Length, AudioInNameSize - buffer.Length); + context.Memory.Write(position, buffer); + MemoryHelper.FillWithZeros(context.Memory, position + (ulong)buffer.Length, AudioInNameSize - buffer.Length); position += AudioInNameSize; count++; @@ -205,15 +205,15 @@ namespace Ryujinx.HLE.HOS.Services.Audio AudioInputConfiguration inputConfiguration = context.RequestData.ReadStruct<AudioInputConfiguration>(); ulong appletResourceUserId = context.RequestData.ReadUInt64(); - long deviceNameInputPosition = context.Request.SendBuff[0].Position; - long deviceNameInputSize = context.Request.SendBuff[0].Size; + ulong deviceNameInputPosition = context.Request.SendBuff[0].Position; + ulong deviceNameInputSize = context.Request.SendBuff[0].Size; - long deviceNameOutputPosition = context.Request.ReceiveBuff[0].Position; - long deviceNameOutputSize = context.Request.ReceiveBuff[0].Size; + ulong deviceNameOutputPosition = context.Request.ReceiveBuff[0].Position; + ulong deviceNameOutputSize = context.Request.ReceiveBuff[0].Size; uint processHandle = (uint)context.Request.HandleDesc.ToCopy[0]; - string inputDeviceName = MemoryHelper.ReadAsciiString(context.Memory, deviceNameInputPosition, deviceNameInputSize); + string inputDeviceName = MemoryHelper.ReadAsciiString(context.Memory, deviceNameInputPosition, (long)deviceNameInputSize); ResultCode resultCode = _impl.OpenAudioIn(context, out string outputDeviceName, out AudioOutputConfiguration outputConfiguration, out IAudioIn obj, inputDeviceName, ref inputConfiguration, appletResourceUserId, processHandle); @@ -223,8 +223,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio byte[] outputDeviceNameRaw = Encoding.ASCII.GetBytes(outputDeviceName); - context.Memory.Write((ulong)deviceNameOutputPosition, outputDeviceNameRaw); - MemoryHelper.FillWithZeros(context.Memory, deviceNameOutputPosition + outputDeviceNameRaw.Length, AudioInNameSize - outputDeviceNameRaw.Length); + context.Memory.Write(deviceNameOutputPosition, outputDeviceNameRaw); + MemoryHelper.FillWithZeros(context.Memory, deviceNameOutputPosition + (ulong)outputDeviceNameRaw.Length, AudioInNameSize - outputDeviceNameRaw.Length); MakeObject(context, new AudioInServer(obj)); } diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOutServer.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOutServer.cs index 72ff4da7..b7515e0f 100644 --- a/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOutServer.cs +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOutServer.cs @@ -45,7 +45,7 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioOut // AppendAudioOutBuffer(u64 bufferTag, buffer<nn::audio::AudioOutBuffer, 5> buffer) public ResultCode AppendAudioOutBuffer(ServiceCtx context) { - long position = context.Request.SendBuff[0].Position; + ulong position = context.Request.SendBuff[0].Position; ulong bufferTag = context.RequestData.ReadUInt64(); @@ -74,10 +74,10 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioOut // GetReleasedAudioOutBuffers() -> (u32 count, buffer<u64, 6> tags) public ResultCode GetReleasedAudioOutBuffers(ServiceCtx context) { - long position = context.Request.ReceiveBuff[0].Position; - long size = context.Request.ReceiveBuff[0].Size; + ulong position = context.Request.ReceiveBuff[0].Position; + ulong size = context.Request.ReceiveBuff[0].Size; - using (WritableRegion outputRegion = context.Memory.GetWritableRegion((ulong)position, (int)size)) + using (WritableRegion outputRegion = context.Memory.GetWritableRegion(position, (int)size)) { ResultCode result = _impl.GetReleasedBuffers(MemoryMarshal.Cast<byte, ulong>(outputRegion.Memory.Span), out uint releasedCount); @@ -102,7 +102,7 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioOut // AppendAudioOutBufferAuto(u64 tag, buffer<nn::audio::AudioOutBuffer, 0x21>) public ResultCode AppendAudioOutBufferAuto(ServiceCtx context) { - (long position, _) = context.Request.GetBufferType0x21(); + (ulong position, _) = context.Request.GetBufferType0x21(); ulong bufferTag = context.RequestData.ReadUInt64(); @@ -115,9 +115,9 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioOut // GetReleasedAudioOutBuffersAuto() -> (u32 count, buffer<u64, 0x22> tags) public ResultCode GetReleasedAudioOutBuffersAuto(ServiceCtx context) { - (long position, long size) = context.Request.GetBufferType0x22(); + (ulong position, ulong size) = context.Request.GetBufferType0x22(); - using (WritableRegion outputRegion = context.Memory.GetWritableRegion((ulong)position, (int)size)) + using (WritableRegion outputRegion = context.Memory.GetWritableRegion(position, (int)size)) { ResultCode result = _impl.GetReleasedBuffers(MemoryMarshal.Cast<byte, ulong>(outputRegion.Memory.Span), out uint releasedCount); diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioOutManagerServer.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioOutManagerServer.cs index a220f90b..3040696e 100644 --- a/Ryujinx.HLE/HOS/Services/Audio/AudioOutManagerServer.cs +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioOutManagerServer.cs @@ -27,10 +27,10 @@ namespace Ryujinx.HLE.HOS.Services.Audio { string[] deviceNames = _impl.ListAudioOuts(); - long position = context.Request.ReceiveBuff[0].Position; - long size = context.Request.ReceiveBuff[0].Size; + ulong position = context.Request.ReceiveBuff[0].Position; + ulong size = context.Request.ReceiveBuff[0].Size; - long basePosition = position; + ulong basePosition = position; int count = 0; @@ -38,15 +38,15 @@ namespace Ryujinx.HLE.HOS.Services.Audio { byte[] buffer = Encoding.ASCII.GetBytes(name); - if ((position - basePosition) + buffer.Length > size) + if ((position - basePosition) + (ulong)buffer.Length > size) { Logger.Error?.Print(LogClass.ServiceAudio, $"Output buffer size {size} too small!"); break; } - context.Memory.Write((ulong)position, buffer); - MemoryHelper.FillWithZeros(context.Memory, position + buffer.Length, AudioOutNameSize - buffer.Length); + context.Memory.Write(position, buffer); + MemoryHelper.FillWithZeros(context.Memory, position + (ulong)buffer.Length, AudioOutNameSize - buffer.Length); position += AudioOutNameSize; count++; @@ -65,15 +65,15 @@ namespace Ryujinx.HLE.HOS.Services.Audio AudioInputConfiguration inputConfiguration = context.RequestData.ReadStruct<AudioInputConfiguration>(); ulong appletResourceUserId = context.RequestData.ReadUInt64(); - long deviceNameInputPosition = context.Request.SendBuff[0].Position; - long deviceNameInputSize = context.Request.SendBuff[0].Size; + ulong deviceNameInputPosition = context.Request.SendBuff[0].Position; + ulong deviceNameInputSize = context.Request.SendBuff[0].Size; - long deviceNameOutputPosition = context.Request.ReceiveBuff[0].Position; - long deviceNameOutputSize = context.Request.ReceiveBuff[0].Size; + ulong deviceNameOutputPosition = context.Request.ReceiveBuff[0].Position; + ulong deviceNameOutputSize = context.Request.ReceiveBuff[0].Size; uint processHandle = (uint)context.Request.HandleDesc.ToCopy[0]; - string inputDeviceName = MemoryHelper.ReadAsciiString(context.Memory, deviceNameInputPosition, deviceNameInputSize); + string inputDeviceName = MemoryHelper.ReadAsciiString(context.Memory, deviceNameInputPosition, (long)deviceNameInputSize); ResultCode resultCode = _impl.OpenAudioOut(context, out string outputDeviceName, out AudioOutputConfiguration outputConfiguration, out IAudioOut obj, inputDeviceName, ref inputConfiguration, appletResourceUserId, processHandle); @@ -83,8 +83,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio byte[] outputDeviceNameRaw = Encoding.ASCII.GetBytes(outputDeviceName); - context.Memory.Write((ulong)deviceNameOutputPosition, outputDeviceNameRaw); - MemoryHelper.FillWithZeros(context.Memory, deviceNameOutputPosition + outputDeviceNameRaw.Length, AudioOutNameSize - outputDeviceNameRaw.Length); + context.Memory.Write(deviceNameOutputPosition, outputDeviceNameRaw); + MemoryHelper.FillWithZeros(context.Memory, deviceNameOutputPosition + (ulong)outputDeviceNameRaw.Length, AudioOutNameSize - outputDeviceNameRaw.Length); MakeObject(context, new AudioOutServer(obj)); } @@ -98,9 +98,9 @@ namespace Ryujinx.HLE.HOS.Services.Audio { string[] deviceNames = _impl.ListAudioOuts(); - (long position, long size) = context.Request.GetBufferType0x22(); + (ulong position, ulong size) = context.Request.GetBufferType0x22(); - long basePosition = position; + ulong basePosition = position; int count = 0; @@ -108,15 +108,15 @@ namespace Ryujinx.HLE.HOS.Services.Audio { byte[] buffer = Encoding.ASCII.GetBytes(name); - if ((position - basePosition) + buffer.Length > size) + if ((position - basePosition) + (ulong)buffer.Length > size) { Logger.Error?.Print(LogClass.ServiceAudio, $"Output buffer size {size} too small!"); break; } - context.Memory.Write((ulong)position, buffer); - MemoryHelper.FillWithZeros(context.Memory, position + buffer.Length, AudioOutNameSize - buffer.Length); + context.Memory.Write(position, buffer); + MemoryHelper.FillWithZeros(context.Memory, position + (ulong)buffer.Length, AudioOutNameSize - buffer.Length); position += AudioOutNameSize; count++; @@ -135,12 +135,12 @@ namespace Ryujinx.HLE.HOS.Services.Audio AudioInputConfiguration inputConfiguration = context.RequestData.ReadStruct<AudioInputConfiguration>(); ulong appletResourceUserId = context.RequestData.ReadUInt64(); - (long deviceNameInputPosition, long deviceNameInputSize) = context.Request.GetBufferType0x21(); - (long deviceNameOutputPosition, long deviceNameOutputSize) = context.Request.GetBufferType0x22(); + (ulong deviceNameInputPosition, ulong deviceNameInputSize) = context.Request.GetBufferType0x21(); + (ulong deviceNameOutputPosition, ulong deviceNameOutputSize) = context.Request.GetBufferType0x22(); uint processHandle = (uint)context.Request.HandleDesc.ToCopy[0]; - string inputDeviceName = MemoryHelper.ReadAsciiString(context.Memory, deviceNameInputPosition, deviceNameInputSize); + string inputDeviceName = MemoryHelper.ReadAsciiString(context.Memory, deviceNameInputPosition, (long)deviceNameInputSize); ResultCode resultCode = _impl.OpenAudioOut(context, out string outputDeviceName, out AudioOutputConfiguration outputConfiguration, out IAudioOut obj, inputDeviceName, ref inputConfiguration, appletResourceUserId, processHandle); @@ -150,8 +150,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio byte[] outputDeviceNameRaw = Encoding.ASCII.GetBytes(outputDeviceName); - context.Memory.Write((ulong)deviceNameOutputPosition, outputDeviceNameRaw); - MemoryHelper.FillWithZeros(context.Memory, deviceNameOutputPosition + outputDeviceNameRaw.Length, AudioOutNameSize - outputDeviceNameRaw.Length); + context.Memory.Write(deviceNameOutputPosition, outputDeviceNameRaw); + MemoryHelper.FillWithZeros(context.Memory, deviceNameOutputPosition + (ulong)outputDeviceNameRaw.Length, AudioOutNameSize - outputDeviceNameRaw.Length); MakeObject(context, new AudioOutServer(obj)); } diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDeviceServer.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDeviceServer.cs index 437b8745..87ec2f6a 100644 --- a/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDeviceServer.cs +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDeviceServer.cs @@ -25,10 +25,10 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer { string[] deviceNames = _impl.ListAudioDeviceName(); - long position = context.Request.ReceiveBuff[0].Position; - long size = context.Request.ReceiveBuff[0].Size; + ulong position = context.Request.ReceiveBuff[0].Position; + ulong size = context.Request.ReceiveBuff[0].Size; - long basePosition = position; + ulong basePosition = position; int count = 0; @@ -36,15 +36,15 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer { byte[] buffer = Encoding.ASCII.GetBytes(name); - if ((position - basePosition) + buffer.Length > size) + if ((position - basePosition) + (ulong)buffer.Length > size) { Logger.Error?.Print(LogClass.ServiceAudio, $"Output buffer size {size} too small!"); break; } - context.Memory.Write((ulong)position, buffer); - MemoryHelper.FillWithZeros(context.Memory, position + buffer.Length, AudioDeviceNameSize - buffer.Length); + context.Memory.Write(position, buffer); + MemoryHelper.FillWithZeros(context.Memory, position + (ulong)buffer.Length, AudioDeviceNameSize - buffer.Length); position += AudioDeviceNameSize; count++; @@ -61,10 +61,10 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer { float volume = context.RequestData.ReadSingle(); - long position = context.Request.SendBuff[0].Position; - long size = context.Request.SendBuff[0].Size; + ulong position = context.Request.SendBuff[0].Position; + ulong size = context.Request.SendBuff[0].Size; - string deviceName = MemoryHelper.ReadAsciiString(context.Memory, position, size); + string deviceName = MemoryHelper.ReadAsciiString(context.Memory, position, (long)size); return _impl.SetAudioDeviceOutputVolume(deviceName, volume); } @@ -73,10 +73,10 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer // GetAudioDeviceOutputVolume(buffer<bytes, 5> name) -> f32 volume public ResultCode GetAudioDeviceOutputVolume(ServiceCtx context) { - long position = context.Request.SendBuff[0].Position; - long size = context.Request.SendBuff[0].Size; + ulong position = context.Request.SendBuff[0].Position; + ulong size = context.Request.SendBuff[0].Size; - string deviceName = MemoryHelper.ReadAsciiString(context.Memory, position, size); + string deviceName = MemoryHelper.ReadAsciiString(context.Memory, position, (long)size); ResultCode result = _impl.GetAudioDeviceOutputVolume(deviceName, out float volume); @@ -94,14 +94,14 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer { string name = _impl.GetActiveAudioDeviceName(); - long position = context.Request.ReceiveBuff[0].Position; - long size = context.Request.ReceiveBuff[0].Size; + ulong position = context.Request.ReceiveBuff[0].Position; + ulong size = context.Request.ReceiveBuff[0].Size; byte[] deviceNameBuffer = Encoding.ASCII.GetBytes(name + "\0"); - if ((ulong)deviceNameBuffer.Length <= (ulong)size) + if ((ulong)deviceNameBuffer.Length <= size) { - context.Memory.Write((ulong)position, deviceNameBuffer); + context.Memory.Write(position, deviceNameBuffer); } else { @@ -146,9 +146,9 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer { string[] deviceNames = _impl.ListAudioDeviceName(); - (long position, long size) = context.Request.GetBufferType0x22(); + (ulong position, ulong size) = context.Request.GetBufferType0x22(); - long basePosition = position; + ulong basePosition = position; int count = 0; @@ -156,15 +156,15 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer { byte[] buffer = Encoding.ASCII.GetBytes(name); - if ((position - basePosition) + buffer.Length > size) + if ((position - basePosition) + (ulong)buffer.Length > size) { Logger.Error?.Print(LogClass.ServiceAudio, $"Output buffer size {size} too small!"); break; } - context.Memory.Write((ulong)position, buffer); - MemoryHelper.FillWithZeros(context.Memory, position + buffer.Length, AudioDeviceNameSize - buffer.Length); + context.Memory.Write(position, buffer); + MemoryHelper.FillWithZeros(context.Memory, position + (ulong)buffer.Length, AudioDeviceNameSize - buffer.Length); position += AudioDeviceNameSize; count++; @@ -181,9 +181,9 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer { float volume = context.RequestData.ReadSingle(); - (long position, long size) = context.Request.GetBufferType0x21(); + (ulong position, ulong size) = context.Request.GetBufferType0x21(); - string deviceName = MemoryHelper.ReadAsciiString(context.Memory, position, size); + string deviceName = MemoryHelper.ReadAsciiString(context.Memory, position, (long)size); return _impl.SetAudioDeviceOutputVolume(deviceName, volume); } @@ -192,9 +192,9 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer // GetAudioDeviceOutputVolumeAuto(buffer<bytes, 0x21> name) -> f32 public ResultCode GetAudioDeviceOutputVolumeAuto(ServiceCtx context) { - (long position, long size) = context.Request.GetBufferType0x21(); + (ulong position, ulong size) = context.Request.GetBufferType0x21(); - string deviceName = MemoryHelper.ReadAsciiString(context.Memory, position, size); + string deviceName = MemoryHelper.ReadAsciiString(context.Memory, position, (long)size); ResultCode result = _impl.GetAudioDeviceOutputVolume(deviceName, out float volume); @@ -212,13 +212,13 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer { string name = _impl.GetActiveAudioDeviceName(); - (long position, long size) = context.Request.GetBufferType0x22(); + (ulong position, ulong size) = context.Request.GetBufferType0x22(); byte[] deviceNameBuffer = Encoding.UTF8.GetBytes(name + '\0'); - if ((ulong)deviceNameBuffer.Length <= (ulong)size) + if ((ulong)deviceNameBuffer.Length <= size) { - context.Memory.Write((ulong)position, deviceNameBuffer); + context.Memory.Write(position, deviceNameBuffer); } else { @@ -268,10 +268,10 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer // GetAudioSystemMasterVolumeSetting(buffer<bytes, 5> name) -> f32 public ResultCode GetAudioSystemMasterVolumeSetting(ServiceCtx context) { - long position = context.Request.SendBuff[0].Position; - long size = context.Request.SendBuff[0].Size; + ulong position = context.Request.SendBuff[0].Position; + ulong size = context.Request.SendBuff[0].Size; - string deviceName = MemoryHelper.ReadAsciiString(context.Memory, position, size); + string deviceName = MemoryHelper.ReadAsciiString(context.Memory, position, (long)size); ResultCode result = _impl.GetAudioSystemMasterVolumeSetting(deviceName, out float systemMasterVolume); diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRendererServer.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRendererServer.cs index 56eb173d..bb51b506 100644 --- a/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRendererServer.cs +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRendererServer.cs @@ -57,16 +57,16 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer // -> (buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 6> output, buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 6> performanceOutput) public ResultCode RequestUpdate(ServiceCtx context) { - long inputPosition = context.Request.SendBuff[0].Position; - long inputSize = context.Request.SendBuff[0].Size; + ulong inputPosition = context.Request.SendBuff[0].Position; + ulong inputSize = context.Request.SendBuff[0].Size; - long outputPosition = context.Request.ReceiveBuff[0].Position; - long outputSize = context.Request.ReceiveBuff[0].Size; + ulong outputPosition = context.Request.ReceiveBuff[0].Position; + ulong outputSize = context.Request.ReceiveBuff[0].Size; - long performanceOutputPosition = context.Request.ReceiveBuff[1].Position; - long performanceOutputSize = context.Request.ReceiveBuff[1].Size; + ulong performanceOutputPosition = context.Request.ReceiveBuff[1].Position; + ulong performanceOutputSize = context.Request.ReceiveBuff[1].Size; - ReadOnlyMemory<byte> input = context.Memory.GetSpan((ulong)inputPosition, (int)inputSize).ToArray(); + ReadOnlyMemory<byte> input = context.Memory.GetSpan(inputPosition, (int)inputSize).ToArray(); Memory<byte> output = new byte[outputSize]; Memory<byte> performanceOutput = new byte[performanceOutputSize]; @@ -78,8 +78,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer if (result == ResultCode.Success) { - context.Memory.Write((ulong)outputPosition, output.Span); - context.Memory.Write((ulong)performanceOutputPosition, performanceOutput.Span); + context.Memory.Write(outputPosition, output.Span); + context.Memory.Write(performanceOutputPosition, performanceOutput.Span); } else { @@ -149,11 +149,11 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer // -> (buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 0x22> output, buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 0x22> performanceOutput) public ResultCode RequestUpdateAuto(ServiceCtx context) { - (long inputPosition, long inputSize) = context.Request.GetBufferType0x21(); - (long outputPosition, long outputSize) = context.Request.GetBufferType0x22(0); - (long performanceOutputPosition, long performanceOutputSize) = context.Request.GetBufferType0x22(1); + (ulong inputPosition, ulong inputSize) = context.Request.GetBufferType0x21(); + (ulong outputPosition, ulong outputSize) = context.Request.GetBufferType0x22(0); + (ulong performanceOutputPosition, ulong performanceOutputSize) = context.Request.GetBufferType0x22(1); - ReadOnlyMemory<byte> input = context.Memory.GetSpan((ulong)inputPosition, (int)inputSize).ToArray(); + ReadOnlyMemory<byte> input = context.Memory.GetSpan(inputPosition, (int)inputSize).ToArray(); Memory<byte> output = new byte[outputSize]; Memory<byte> performanceOutput = new byte[performanceOutputSize]; @@ -165,8 +165,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer if (result == ResultCode.Success) { - context.Memory.Write((ulong)outputPosition, output.Span); - context.Memory.Write((ulong)performanceOutputPosition, performanceOutput.Span); + context.Memory.Write(outputPosition, output.Span); + context.Memory.Write(performanceOutputPosition, performanceOutput.Span); } return result; diff --git a/Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs b/Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs index a405457a..44eeb32d 100644 --- a/Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs +++ b/Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs @@ -106,24 +106,24 @@ namespace Ryujinx.HLE.HOS.Services.Audio.HardwareOpusDecoderManager { ResultCode result; - long inPosition = context.Request.SendBuff[0].Position; - long inSize = context.Request.SendBuff[0].Size; - long outputPosition = context.Request.ReceiveBuff[0].Position; - long outputSize = context.Request.ReceiveBuff[0].Size; + ulong inPosition = context.Request.SendBuff[0].Position; + ulong inSize = context.Request.SendBuff[0].Size; + ulong outputPosition = context.Request.ReceiveBuff[0].Position; + ulong outputSize = context.Request.ReceiveBuff[0].Size; byte[] buffer = new byte[inSize]; - context.Memory.Read((ulong)inPosition, buffer); + context.Memory.Read(inPosition, buffer); using (BinaryReader inputStream = new BinaryReader(new MemoryStream(buffer))) { - result = DecodeInterleavedInternal(inputStream, out short[] outPcmData, outputSize, out uint outConsumed, out int outSamples); + result = DecodeInterleavedInternal(inputStream, out short[] outPcmData, (long)outputSize, out uint outConsumed, out int outSamples); if (result == ResultCode.Success) { byte[] pcmDataBytes = new byte[outPcmData.Length * sizeof(short)]; Buffer.BlockCopy(outPcmData, 0, pcmDataBytes, 0, pcmDataBytes.Length); - context.Memory.Write((ulong)outputPosition, pcmDataBytes); + context.Memory.Write(outputPosition, pcmDataBytes); context.ResponseData.Write(outConsumed); context.ResponseData.Write(outSamples); @@ -139,24 +139,24 @@ namespace Ryujinx.HLE.HOS.Services.Audio.HardwareOpusDecoderManager { ResultCode result; - long inPosition = context.Request.SendBuff[0].Position; - long inSize = context.Request.SendBuff[0].Size; - long outputPosition = context.Request.ReceiveBuff[0].Position; - long outputSize = context.Request.ReceiveBuff[0].Size; + ulong inPosition = context.Request.SendBuff[0].Position; + ulong inSize = context.Request.SendBuff[0].Size; + ulong outputPosition = context.Request.ReceiveBuff[0].Position; + ulong outputSize = context.Request.ReceiveBuff[0].Size; byte[] buffer = new byte[inSize]; - context.Memory.Read((ulong)inPosition, buffer); + context.Memory.Read(inPosition, buffer); using (BinaryReader inputStream = new BinaryReader(new MemoryStream(buffer))) { - result = DecodeInterleavedInternal(inputStream, out short[] outPcmData, outputSize, out uint outConsumed, out int outSamples); + result = DecodeInterleavedInternal(inputStream, out short[] outPcmData, (long)outputSize, out uint outConsumed, out int outSamples); if (result == ResultCode.Success) { byte[] pcmDataBytes = new byte[outPcmData.Length * sizeof(short)]; Buffer.BlockCopy(outPcmData, 0, pcmDataBytes, 0, pcmDataBytes.Length); - context.Memory.Write((ulong)outputPosition, pcmDataBytes); + context.Memory.Write(outputPosition, pcmDataBytes); context.ResponseData.Write(outConsumed); context.ResponseData.Write(outSamples); @@ -177,24 +177,24 @@ namespace Ryujinx.HLE.HOS.Services.Audio.HardwareOpusDecoderManager _reset = context.RequestData.ReadBoolean(); - long inPosition = context.Request.SendBuff[0].Position; - long inSize = context.Request.SendBuff[0].Size; - long outputPosition = context.Request.ReceiveBuff[0].Position; - long outputSize = context.Request.ReceiveBuff[0].Size; + ulong inPosition = context.Request.SendBuff[0].Position; + ulong inSize = context.Request.SendBuff[0].Size; + ulong outputPosition = context.Request.ReceiveBuff[0].Position; + ulong outputSize = context.Request.ReceiveBuff[0].Size; byte[] buffer = new byte[inSize]; - context.Memory.Read((ulong)inPosition, buffer); + context.Memory.Read(inPosition, buffer); using (BinaryReader inputStream = new BinaryReader(new MemoryStream(buffer))) { - result = DecodeInterleavedInternal(inputStream, out short[] outPcmData, outputSize, out uint outConsumed, out int outSamples); + result = DecodeInterleavedInternal(inputStream, out short[] outPcmData, (long)outputSize, out uint outConsumed, out int outSamples); if (result == ResultCode.Success) { byte[] pcmDataBytes = new byte[outPcmData.Length * sizeof(short)]; Buffer.BlockCopy(outPcmData, 0, pcmDataBytes, 0, pcmDataBytes.Length); - context.Memory.Write((ulong)outputPosition, pcmDataBytes); + context.Memory.Write(outputPosition, pcmDataBytes); context.ResponseData.Write(outConsumed); context.ResponseData.Write(outSamples); @@ -215,24 +215,24 @@ namespace Ryujinx.HLE.HOS.Services.Audio.HardwareOpusDecoderManager _reset = context.RequestData.ReadBoolean(); - long inPosition = context.Request.SendBuff[0].Position; - long inSize = context.Request.SendBuff[0].Size; - long outputPosition = context.Request.ReceiveBuff[0].Position; - long outputSize = context.Request.ReceiveBuff[0].Size; + ulong inPosition = context.Request.SendBuff[0].Position; + ulong inSize = context.Request.SendBuff[0].Size; + ulong outputPosition = context.Request.ReceiveBuff[0].Position; + ulong outputSize = context.Request.ReceiveBuff[0].Size; byte[] buffer = new byte[inSize]; - context.Memory.Read((ulong)inPosition, buffer); + context.Memory.Read(inPosition, buffer); using (BinaryReader inputStream = new BinaryReader(new MemoryStream(buffer))) { - result = DecodeInterleavedInternal(inputStream, out short[] outPcmData, outputSize, out uint outConsumed, out int outSamples); + result = DecodeInterleavedInternal(inputStream, out short[] outPcmData, (long)outputSize, out uint outConsumed, out int outSamples); if (result == ResultCode.Success) { byte[] pcmDataBytes = new byte[outPcmData.Length * sizeof(short)]; Buffer.BlockCopy(outPcmData, 0, pcmDataBytes, 0, pcmDataBytes.Length); - context.Memory.Write((ulong)outputPosition, pcmDataBytes); + context.Memory.Write(outputPosition, pcmDataBytes); context.ResponseData.Write(outConsumed); context.ResponseData.Write(outSamples); diff --git a/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheDirectoryService.cs b/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheDirectoryService.cs index f232cd3e..51d8f66c 100644 --- a/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheDirectoryService.cs +++ b/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheDirectoryService.cs @@ -30,14 +30,14 @@ namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator // Read() -> (u32, buffer<nn::bcat::DeliveryCacheDirectoryEntry, 6>) public ResultCode Read(ServiceCtx context) { - long position = context.Request.ReceiveBuff[0].Position; - long size = context.Request.ReceiveBuff[0].Size; + ulong position = context.Request.ReceiveBuff[0].Position; + ulong size = context.Request.ReceiveBuff[0].Size; byte[] data = new byte[size]; Result result = _base.Read(out int entriesRead, MemoryMarshal.Cast<byte, DeliveryCacheDirectoryEntry>(data)); - context.Memory.Write((ulong)position, data); + context.Memory.Write(position, data); context.ResponseData.Write(entriesRead); diff --git a/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheFileService.cs b/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheFileService.cs index fe7c2ffc..9354b60e 100644 --- a/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheFileService.cs +++ b/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheFileService.cs @@ -30,8 +30,8 @@ namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator // Read(u64) -> (u64, buffer<bytes, 6>) public ResultCode Read(ServiceCtx context) { - long position = context.Request.ReceiveBuff[0].Position; - long size = context.Request.ReceiveBuff[0].Size; + ulong position = context.Request.ReceiveBuff[0].Position; + ulong size = context.Request.ReceiveBuff[0].Size; long offset = context.RequestData.ReadInt64(); @@ -39,7 +39,7 @@ namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator Result result = _base.Read(out long bytesRead, offset, data); - context.Memory.Write((ulong)position, data); + context.Memory.Write(position, data); context.ResponseData.Write(bytesRead); diff --git a/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheProgressService.cs b/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheProgressService.cs index f5a6fae0..61b1f1a1 100644 --- a/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheProgressService.cs +++ b/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheProgressService.cs @@ -49,7 +49,7 @@ namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator Result = 0 }; - long dcpSize = WriteDeliveryCacheProgressImpl(context, context.Request.RecvListBuff[0], deliveryCacheProgress); + ulong dcpSize = WriteDeliveryCacheProgressImpl(context, context.Request.RecvListBuff[0], deliveryCacheProgress); context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(dcpSize); Logger.Stub?.PrintStub(LogClass.ServiceBcat); @@ -57,7 +57,7 @@ namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator return ResultCode.Success; } - private long WriteDeliveryCacheProgressImpl(ServiceCtx context, IpcRecvListBuffDesc ipcDesc, DeliveryCacheProgressImpl deliveryCacheProgress) + private ulong WriteDeliveryCacheProgressImpl(ServiceCtx context, IpcRecvListBuffDesc ipcDesc, DeliveryCacheProgressImpl deliveryCacheProgress) { return MemoryHelper.Write(context.Memory, ipcDesc.Position, deliveryCacheProgress); } diff --git a/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheStorageService.cs b/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheStorageService.cs index 8e2fb4bf..cac5f170 100644 --- a/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheStorageService.cs +++ b/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheStorageService.cs @@ -46,14 +46,14 @@ namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator // EnumerateDeliveryCacheDirectory() -> (u32, buffer<nn::bcat::DirectoryName, 6>) public ResultCode EnumerateDeliveryCacheDirectory(ServiceCtx context) { - long position = context.Request.ReceiveBuff[0].Position; - long size = context.Request.ReceiveBuff[0].Size; + ulong position = context.Request.ReceiveBuff[0].Position; + ulong size = context.Request.ReceiveBuff[0].Size; byte[] data = new byte[size]; Result result = _base.EnumerateDeliveryCacheDirectory(out int count, MemoryMarshal.Cast<byte, DirectoryName>(data)); - context.Memory.Write((ulong)position, data); + context.Memory.Write(position, data); context.ResponseData.Write(count); diff --git a/Ryujinx.HLE/HOS/Services/Caps/CaptureManager.cs b/Ryujinx.HLE/HOS/Services/Caps/CaptureManager.cs index 37cc9bda..35781562 100644 --- a/Ryujinx.HLE/HOS/Services/Caps/CaptureManager.cs +++ b/Ryujinx.HLE/HOS/Services/Caps/CaptureManager.cs @@ -1,7 +1,6 @@ using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Caps.Types; using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.PixelFormats; using System; using System.IO; @@ -19,11 +18,6 @@ namespace Ryujinx.HLE.HOS.Services.Caps public CaptureManager(Switch device) { _sdCardPath = device.FileSystem.GetSdCardPath(); - - SixLabors.ImageSharp.Configuration.Default.ImageFormatsManager.SetEncoder(JpegFormat.Instance, new JpegEncoder() - { - Quality = 100 - }); } public ResultCode SetShimLibraryVersion(ServiceCtx context) diff --git a/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs b/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs index b907ff35..1789122e 100644 --- a/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs +++ b/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs @@ -26,10 +26,10 @@ namespace Ryujinx.HLE.HOS.Services.Caps ulong appletResourceUserId = context.RequestData.ReadUInt64(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); - long screenshotDataPosition = context.Request.SendBuff[0].Position; - long screenshotDataSize = context.Request.SendBuff[0].Size; + ulong screenshotDataPosition = context.Request.SendBuff[0].Position; + ulong screenshotDataSize = context.Request.SendBuff[0].Size; - byte[] screenshotData = context.Memory.GetSpan((ulong)screenshotDataPosition, (int)screenshotDataSize, true).ToArray(); + byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray(); ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Application.TitleId, out ApplicationAlbumEntry applicationAlbumEntry); @@ -49,16 +49,16 @@ namespace Ryujinx.HLE.HOS.Services.Caps ulong appletResourceUserId = context.RequestData.ReadUInt64(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); - long applicationDataPosition = context.Request.SendBuff[0].Position; - long applicationDataSize = context.Request.SendBuff[0].Size; + ulong applicationDataPosition = context.Request.SendBuff[0].Position; + ulong applicationDataSize = context.Request.SendBuff[0].Size; - long screenshotDataPosition = context.Request.SendBuff[1].Position; - long screenshotDataSize = context.Request.SendBuff[1].Size; + ulong screenshotDataPosition = context.Request.SendBuff[1].Position; + ulong screenshotDataSize = context.Request.SendBuff[1].Size; // TODO: Parse the application data: At 0x00 it's UserData (Size of 0x400), at 0x404 it's a uint UserDataSize (Always empty for now). - byte[] applicationData = context.Memory.GetSpan((ulong)applicationDataPosition, (int)applicationDataSize).ToArray(); + byte[] applicationData = context.Memory.GetSpan(applicationDataPosition, (int)applicationDataSize).ToArray(); - byte[] screenshotData = context.Memory.GetSpan((ulong)screenshotDataPosition, (int)screenshotDataSize, true).ToArray(); + byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray(); ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Application.TitleId, out ApplicationAlbumEntry applicationAlbumEntry); @@ -77,16 +77,16 @@ namespace Ryujinx.HLE.HOS.Services.Caps uint unknown = context.RequestData.ReadUInt32(); ulong appletResourceUserId = context.RequestData.ReadUInt64(); - long userIdListPosition = context.Request.SendBuff[0].Position; - long userIdListSize = context.Request.SendBuff[0].Size; + ulong userIdListPosition = context.Request.SendBuff[0].Position; + ulong userIdListSize = context.Request.SendBuff[0].Size; - long screenshotDataPosition = context.Request.SendBuff[1].Position; - long screenshotDataSize = context.Request.SendBuff[1].Size; + ulong screenshotDataPosition = context.Request.SendBuff[1].Position; + ulong screenshotDataSize = context.Request.SendBuff[1].Size; // TODO: Parse the UserIdList. - byte[] userIdList = context.Memory.GetSpan((ulong)userIdListPosition, (int)userIdListSize).ToArray(); + byte[] userIdList = context.Memory.GetSpan(userIdListPosition, (int)userIdListSize).ToArray(); - byte[] screenshotData = context.Memory.GetSpan((ulong)screenshotDataPosition, (int)screenshotDataSize, true).ToArray(); + byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray(); ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Application.TitleId, out ApplicationAlbumEntry applicationAlbumEntry); diff --git a/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs b/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs index 1ae5d487..a2865e9c 100644 --- a/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs +++ b/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs @@ -150,12 +150,9 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator return ResultCode.InvalidArgument; } - if (context.Device.System.AccountManager.TryGetUser(userId, out UserProfile profile)) - { - profile.OnlinePlayState = AccountState.Open; - } - - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = userId.ToString(), profile.OnlinePlayState }); + context.Device.System.AccountManager.OpenUserOnlinePlay(userId); + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = userId.ToString() }); return ResultCode.Success; } @@ -171,12 +168,9 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator return ResultCode.InvalidArgument; } - if (context.Device.System.AccountManager.TryGetUser(userId, out UserProfile profile)) - { - profile.OnlinePlayState = AccountState.Closed; - } + context.Device.System.AccountManager.CloseUserOnlinePlay(userId); - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = userId.ToString(), profile.OnlinePlayState }); + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = userId.ToString() }); return ResultCode.Success; } @@ -190,12 +184,12 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator // Pid placeholder context.RequestData.ReadInt64(); - long position = context.Request.PtrBuff[0].Position; - long size = context.Request.PtrBuff[0].Size; + ulong position = context.Request.PtrBuff[0].Position; + ulong size = context.Request.PtrBuff[0].Size; byte[] bufferContent = new byte[size]; - context.Memory.Read((ulong)position, bufferContent); + context.Memory.Read(position, bufferContent); if (uuid.IsNull) { @@ -221,9 +215,9 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator bool unknownBool = context.RequestData.ReadBoolean(); UserId userId = context.RequestData.ReadStruct<UserId>(); - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(0x40L); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(0x40UL); - long bufferPosition = context.Request.RecvListBuff[0].Position; + ulong bufferPosition = context.Request.RecvListBuff[0].Position; if (userId.IsNull) { @@ -271,8 +265,8 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator */ - context.Memory.Write((ulong)bufferPosition, playHistoryRegistrationKeyBuffer); - context.Memory.Write((ulong)bufferPosition + 0x20, new byte[0x20]); // HmacHash + context.Memory.Write(bufferPosition, playHistoryRegistrationKeyBuffer); + context.Memory.Write(bufferPosition + 0x20, new byte[0x20]); // HmacHash return ResultCode.Success; } @@ -287,14 +281,14 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator context.RequestData.ReadInt64(); long pid = context.Process.Pid; - long playHistoryRegistrationKeyPosition = context.Request.PtrBuff[0].Position; - long PlayHistoryRegistrationKeySize = context.Request.PtrBuff[0].Size; + ulong playHistoryRegistrationKeyPosition = context.Request.PtrBuff[0].Position; + ulong PlayHistoryRegistrationKeySize = context.Request.PtrBuff[0].Size; - long inAppScreenName1Position = context.Request.PtrBuff[1].Position; - long inAppScreenName1Size = context.Request.PtrBuff[1].Size; + ulong inAppScreenName1Position = context.Request.PtrBuff[1].Position; + ulong inAppScreenName1Size = context.Request.PtrBuff[1].Size; - long inAppScreenName2Position = context.Request.PtrBuff[2].Position; - long inAppScreenName2Size = context.Request.PtrBuff[2].Size; + ulong inAppScreenName2Position = context.Request.PtrBuff[2].Position; + ulong inAppScreenName2Size = context.Request.PtrBuff[2].Size; if (userId.IsNull || inAppScreenName1Size > 0x48 || inAppScreenName2Size > 0x48) { diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs index c4d251f9..7774af23 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs @@ -116,12 +116,12 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy public static Result ReadFsPath(out FsPath path, ServiceCtx context, int index = 0) { - long position = context.Request.PtrBuff[index].Position; - long size = context.Request.PtrBuff[index].Size; + ulong position = context.Request.PtrBuff[index].Position; + ulong size = context.Request.PtrBuff[index].Size; byte[] pathBytes = new byte[size]; - context.Memory.Read((ulong)position, pathBytes); + context.Memory.Read(position, pathBytes); return FsPath.FromSpan(out path, pathBytes); } diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs index 014e11f4..565ddc4c 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs @@ -18,15 +18,15 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy // Read() -> (u64 count, buffer<nn::fssrv::sf::IDirectoryEntry, 6, 0> entries) public ResultCode Read(ServiceCtx context) { - long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferLen = context.Request.ReceiveBuff[0].Size; + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferLen = context.Request.ReceiveBuff[0].Size; byte[] entriesBytes = new byte[bufferLen]; Span<DirectoryEntry> entries = MemoryMarshal.Cast<byte, DirectoryEntry>(entriesBytes); Result result = _baseDirectory.Read(out long entriesRead, entries); - context.Memory.Write((ulong)bufferPosition, entriesBytes); + context.Memory.Write(bufferPosition, entriesBytes); context.ResponseData.Write(entriesRead); return (ResultCode)result.Value; diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs index b5f342f0..681b6c17 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs @@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy // Read(u32 readOption, u64 offset, u64 size) -> (u64 out_size, buffer<u8, 0x46, 0> out_buf) public ResultCode Read(ServiceCtx context) { - long position = context.Request.ReceiveBuff[0].Position; + ulong position = context.Request.ReceiveBuff[0].Position; ReadOption readOption = new ReadOption(context.RequestData.ReadInt32()); context.RequestData.BaseStream.Position += 4; @@ -29,7 +29,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy Result result = _baseFile.Read(out long bytesRead, offset, data, readOption); - context.Memory.Write((ulong)position, data); + context.Memory.Write(position, data); context.ResponseData.Write(bytesRead); @@ -40,7 +40,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy // Write(u32 writeOption, u64 offset, u64 size, buffer<u8, 0x45, 0>) public ResultCode Write(ServiceCtx context) { - long position = context.Request.SendBuff[0].Position; + ulong position = context.Request.SendBuff[0].Position; WriteOption writeOption = new WriteOption(context.RequestData.ReadInt32()); context.RequestData.BaseStream.Position += 4; @@ -50,7 +50,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy byte[] data = new byte[size]; - context.Memory.Read((ulong)position, data); + context.Memory.Read(position, data); return (ResultCode)_baseFile.Write(offset, data, writeOption).Value; } diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs index 7889be4b..89955634 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs @@ -17,8 +17,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy // Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer public ResultCode Read(ServiceCtx context) { - long offset = context.RequestData.ReadInt64(); - long size = context.RequestData.ReadInt64(); + ulong offset = context.RequestData.ReadUInt64(); + ulong size = context.RequestData.ReadUInt64(); if (context.Request.ReceiveBuff.Count > 0) { @@ -32,9 +32,9 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy byte[] data = new byte[size]; - Result result = _baseStorage.Read(offset, data); + Result result = _baseStorage.Read((long)offset, data); - context.Memory.Write((ulong)buffDesc.Position, data); + context.Memory.Write(buffDesc.Position, data); return (ResultCode)result.Value; } diff --git a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs index eaaf1fe9..fd8844c7 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs @@ -38,7 +38,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs public ResultCode OpenFileSystemWithId(ServiceCtx context) { FileSystemType fileSystemType = (FileSystemType)context.RequestData.ReadInt32(); - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); string switchPath = ReadUtf8String(context); string fullPath = context.Device.FileSystem.SwitchPathToSystemPath(switchPath); @@ -337,14 +337,14 @@ namespace Ryujinx.HLE.HOS.Services.Fs SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); SaveDataFilter filter = context.RequestData.ReadStruct<SaveDataFilter>(); - long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferLen = context.Request.ReceiveBuff[0].Size; + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferLen = context.Request.ReceiveBuff[0].Size; byte[] infoBuffer = new byte[bufferLen]; Result result = _baseFileSystemProxy.FindSaveDataWithFilter(out long count, infoBuffer, spaceId, ref filter); - context.Memory.Write((ulong)bufferPosition, infoBuffer); + context.Memory.Write(bufferPosition, infoBuffer); context.ResponseData.Write(count); return (ResultCode)result.Value; @@ -392,11 +392,11 @@ namespace Ryujinx.HLE.HOS.Services.Fs { StorageId storageId = (StorageId)context.RequestData.ReadByte(); byte[] padding = context.RequestData.ReadBytes(7); - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); // We do a mitm here to find if the request is for an AOC. // This is because AOC can be distributed over multiple containers in the emulator. - if (context.Device.System.ContentManager.GetAocDataStorage((ulong)titleId, out LibHac.Fs.IStorage aocStorage)) + if (context.Device.System.ContentManager.GetAocDataStorage((ulong)titleId, out LibHac.Fs.IStorage aocStorage, context.Device.Configuration.FsIntegrityCheckLevel)) { Logger.Info?.Print(LogClass.Loader, $"Opened AddOnContent Data TitleID={titleId:X16}"); diff --git a/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs b/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs index 7c5d5e61..d6449a2d 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs @@ -16,14 +16,14 @@ namespace Ryujinx.HLE.HOS.Services.Fs // ReadSaveDataInfo() -> (u64, buffer<unknown, 6>) public ResultCode ReadSaveDataInfo(ServiceCtx context) { - long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferLen = context.Request.ReceiveBuff[0].Size; + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferLen = context.Request.ReceiveBuff[0].Size; byte[] infoBuffer = new byte[bufferLen]; Result result = _baseReader.Target.Read(out long readCount, infoBuffer); - context.Memory.Write((ulong)bufferPosition, infoBuffer); + context.Memory.Write(bufferPosition, infoBuffer); context.ResponseData.Write(readCount); return (ResultCode)result.Value; diff --git a/Ryujinx.HLE/HOS/Services/Hid/Hid.cs b/Ryujinx.HLE/HOS/Services/Hid/Hid.cs index 18a7ba11..61a12d9e 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Hid.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Hid.cs @@ -3,6 +3,14 @@ using Ryujinx.HLE.Exceptions; using Ryujinx.Common.Configuration.Hid; using System.Collections.Generic; using System.Runtime.CompilerServices; +using Ryujinx.Common.Memory; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad; namespace Ryujinx.HLE.HOS.Services.Hid { @@ -12,7 +20,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid private readonly ulong _hidMemoryAddress; - internal ref HidSharedMemory SharedMemory => ref _device.Memory.GetRef<HidSharedMemory>(_hidMemoryAddress); + internal ref SharedMemory SharedMemory => ref _device.Memory.GetRef<SharedMemory>(_hidMemoryAddress); internal const int SharedMemEntryCount = 17; @@ -22,40 +30,30 @@ namespace Ryujinx.HLE.HOS.Services.Hid public KeyboardDevice Keyboard; public NpadDevices Npads; - static Hid() + private static void CheckTypeSizeOrThrow<T>(int expectedSize) { - if (Unsafe.SizeOf<ShMemDebugPad>() != 0x400) - { - throw new InvalidStructLayoutException<ShMemDebugPad>(0x400); - } - if (Unsafe.SizeOf<ShMemTouchScreen>() != 0x3000) - { - throw new InvalidStructLayoutException<ShMemTouchScreen>(0x3000); - } - if (Unsafe.SizeOf<ShMemKeyboard>() != 0x400) - { - throw new InvalidStructLayoutException<ShMemKeyboard>(0x400); - } - if (Unsafe.SizeOf<ShMemMouse>() != 0x400) - { - throw new InvalidStructLayoutException<ShMemMouse>(0x400); - } - if (Unsafe.SizeOf<ShMemNpad>() != 0x5000) + if (Unsafe.SizeOf<T>() != expectedSize) { - throw new InvalidStructLayoutException<ShMemNpad>(0x5000); - } - if (Unsafe.SizeOf<HidSharedMemory>() != Horizon.HidSize) - { - throw new InvalidStructLayoutException<HidSharedMemory>(Horizon.HidSize); + throw new InvalidStructLayoutException<T>(expectedSize); } } + static Hid() + { + CheckTypeSizeOrThrow<RingLifo<DebugPadState>>(0x2c8); + CheckTypeSizeOrThrow<RingLifo<TouchScreenState>>(0x2C38); + CheckTypeSizeOrThrow<RingLifo<MouseState>>(0x350); + CheckTypeSizeOrThrow<RingLifo<KeyboardState>>(0x3D8); + CheckTypeSizeOrThrow<Array10<NpadState>>(0x32000); + CheckTypeSizeOrThrow<SharedMemory>(Horizon.HidSize); + } + public Hid(in Switch device, ulong sharedHidMemoryAddress) { _device = device; _hidMemoryAddress = sharedHidMemoryAddress; - device.Memory.ZeroFill(sharedHidMemoryAddress, Horizon.HidSize); + SharedMemory = SharedMemory.Create(); } public void InitDevices() @@ -67,7 +65,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid Npads = new NpadDevices(_device, true); } - internal void RefreshInputConfig(List<InputConfig> inputConfig) + public void RefreshInputConfig(List<InputConfig> inputConfig) { ControllerConfig[] npadConfig = new ControllerConfig[inputConfig.Count]; @@ -80,11 +78,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid _device.Hid.Npads.Configure(npadConfig); } - internal void RefreshInputConfigEvent(object _, ReactiveEventArgs<List<InputConfig>> args) - { - RefreshInputConfig(args.NewValue); - } - public ControllerKeys UpdateStickButtons(JoystickPosition leftStick, JoystickPosition rightStick) { const int stickButtonThreshold = short.MaxValue / 2; diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/BaseDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/BaseDevice.cs index 59d6dfa3..e8bf628a 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/BaseDevice.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/BaseDevice.cs @@ -12,18 +12,5 @@ namespace Ryujinx.HLE.HOS.Services.Hid _device = device; Active = active; } - - internal static int UpdateEntriesHeader(ref CommonEntriesHeader header, out int previousEntry) - { - header.NumEntries = SharedMemEntryCount; - header.MaxEntryIndex = SharedMemEntryCount - 1; - - previousEntry = (int)header.LatestEntry; - header.LatestEntry = (header.LatestEntry + 1) % SharedMemEntryCount; - - header.TimestampTicks = GetTimestampTicks(); - - return (int)header.LatestEntry; // EntryCount shouldn't overflow int - } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugPadDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugPadDevice.cs index 7e708e32..e3b95390 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugPadDevice.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugPadDevice.cs @@ -1,3 +1,6 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad; + namespace Ryujinx.HLE.HOS.Services.Hid { public class DebugPadDevice : BaseDevice @@ -6,20 +9,20 @@ namespace Ryujinx.HLE.HOS.Services.Hid public void Update() { - ref ShMemDebugPad debugPad = ref _device.Hid.SharedMemory.DebugPad; + ref RingLifo<DebugPadState> lifo = ref _device.Hid.SharedMemory.DebugPad; + + ref DebugPadState previousEntry = ref lifo.GetCurrentEntryRef(); - int currentIndex = UpdateEntriesHeader(ref debugPad.Header, out int previousIndex); + DebugPadState newState = new DebugPadState(); - if (!Active) + if (Active) { - return; + // TODO: This is a debug device only present in dev environment, do we want to support it? } - ref DebugPadEntry currentEntry = ref debugPad.Entries[currentIndex]; - DebugPadEntry previousEntry = debugPad.Entries[previousIndex]; + newState.SamplingNumber = previousEntry.SamplingNumber + 1; - currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1; - currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1; + lifo.Write(ref newState); } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/KeyboardDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/KeyboardDevice.cs index e8ed6a3e..99dc078d 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/KeyboardDevice.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/KeyboardDevice.cs @@ -1,3 +1,7 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard; +using System; + namespace Ryujinx.HLE.HOS.Services.Hid { public class KeyboardDevice : BaseDevice @@ -6,27 +10,26 @@ namespace Ryujinx.HLE.HOS.Services.Hid public unsafe void Update(KeyboardInput keyState) { - ref ShMemKeyboard keyboard = ref _device.Hid.SharedMemory.Keyboard; - - int currentIndex = UpdateEntriesHeader(ref keyboard.Header, out int previousIndex); + ref RingLifo<KeyboardState> lifo = ref _device.Hid.SharedMemory.Keyboard; if (!Active) { + lifo.Clear(); + return; } - ref KeyboardState currentEntry = ref keyboard.Entries[currentIndex]; - KeyboardState previousEntry = keyboard.Entries[previousIndex]; + ref KeyboardState previousEntry = ref lifo.GetCurrentEntryRef(); - currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1; - currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1; - - for (int i = 0; i < 8; ++i) + KeyboardState newState = new KeyboardState { - currentEntry.Keys[i] = (uint)keyState.Keys[i]; - } + SamplingNumber = previousEntry.SamplingNumber + 1, + }; + + keyState.Keys.AsSpan().CopyTo(newState.Keys.RawData.ToSpan()); + newState.Modifiers = (KeyboardModifier)keyState.Modifier; - currentEntry.Modifier = (ulong)keyState.Modifier; + lifo.Write(ref newState); } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs index ee58a563..e07c1d20 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs @@ -1,37 +1,35 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse; + namespace Ryujinx.HLE.HOS.Services.Hid { public class MouseDevice : BaseDevice { public MouseDevice(Switch device, bool active) : base(device, active) { } - public void Update(int mouseX, int mouseY, int buttons = 0, int scrollX = 0, int scrollY = 0) + public void Update(int mouseX, int mouseY, uint buttons = 0, int scrollX = 0, int scrollY = 0) { - ref ShMemMouse mouse = ref _device.Hid.SharedMemory.Mouse; + ref RingLifo<MouseState> lifo = ref _device.Hid.SharedMemory.Mouse; - int currentIndex = UpdateEntriesHeader(ref mouse.Header, out int previousIndex); + ref MouseState previousEntry = ref lifo.GetCurrentEntryRef(); + + MouseState newState = new MouseState() + { + SamplingNumber = previousEntry.SamplingNumber + 1, + }; - if (!Active) + if (Active) { - return; + newState.Buttons = (MouseButton)buttons; + newState.X = mouseX; + newState.Y = mouseY; + newState.DeltaX = mouseX - previousEntry.DeltaX; + newState.DeltaY = mouseY - previousEntry.DeltaY; + newState.WheelDeltaX = scrollX; + newState.WheelDeltaY = scrollY; } - ref MouseState currentEntry = ref mouse.Entries[currentIndex]; - MouseState previousEntry = mouse.Entries[previousIndex]; - - currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1; - currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1; - - currentEntry.Buttons = (ulong)buttons; - - currentEntry.Position = new MousePosition - { - X = mouseX, - Y = mouseY, - VelocityX = mouseX - previousEntry.Position.X, - VelocityY = mouseY - previousEntry.Position.Y, - ScrollVelocityX = scrollX, - ScrollVelocityY = scrollY - }; + lifo.Write(ref newState); } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs index 2150f278..3ff7e733 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs @@ -1,16 +1,17 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using Ryujinx.Common; using Ryujinx.Common.Logging; -using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Services.Hid.Types; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad; namespace Ryujinx.HLE.HOS.Services.Hid { public class NpadDevices : BaseDevice { - private const BatteryCharge DefaultBatteryCharge = BatteryCharge.Percent100; - private const int NoMatchNotifyFrequencyMs = 2000; private int _activeCount; private long _lastNotifyTimestamp; @@ -86,7 +87,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid continue; } - ControllerType currentType = _device.Hid.SharedMemory.Npads[i].Header.Type; + ControllerType currentType = (ControllerType)_device.Hid.SharedMemory.Npads[i].InternalState.StyleSet; if (currentType != ControllerType.None && (npad & acceptedTypes) != 0 && _supportedPlayers[i]) { @@ -135,12 +136,24 @@ namespace Ryujinx.HLE.HOS.Services.Hid { Remap(); - UpdateAllEntries(); + Span<bool> updated = stackalloc bool[10]; // Update configured inputs for (int i = 0; i < states.Count; ++i) { - UpdateInput(states[i]); + GamepadInput state = states[i]; + + updated[(int)state.PlayerId] = true; + + UpdateInput(state); + } + + for (int i = 0; i < updated.Length; i++) + { + if (!updated[i]) + { + UpdateDisconnectedInput((PlayerIndex)i); + } } } @@ -185,16 +198,16 @@ namespace Ryujinx.HLE.HOS.Services.Hid private void SetupNpad(PlayerIndex player, ControllerType type) { - ref ShMemNpad controller = ref _device.Hid.SharedMemory.Npads[(int)player]; + ref NpadInternalState controller = ref _device.Hid.SharedMemory.Npads[(int)player].InternalState; - ControllerType oldType = controller.Header.Type; + ControllerType oldType = (ControllerType)controller.StyleSet; if (oldType == type) { return; // Already configured } - controller = new ShMemNpad(); // Zero it + controller = NpadInternalState.Create(); // Reset it if (type == ControllerType.None) { @@ -207,87 +220,151 @@ namespace Ryujinx.HLE.HOS.Services.Hid } // TODO: Allow customizing colors at config - NpadStateHeader defaultHeader = new NpadStateHeader - { - IsHalf = false, - SingleColorBody = NpadColor.BodyGray, - SingleColorButtons = NpadColor.ButtonGray, - LeftColorBody = NpadColor.BodyNeonBlue, - LeftColorButtons = NpadColor.ButtonGray, - RightColorBody = NpadColor.BodyNeonRed, - RightColorButtons = NpadColor.ButtonGray - }; - - controller.SystemProperties = NpadSystemProperties.PowerInfo0Connected | - NpadSystemProperties.PowerInfo1Connected | - NpadSystemProperties.PowerInfo2Connected; - - controller.BatteryState.ToSpan().Fill(DefaultBatteryCharge); + controller.JoyAssignmentMode = NpadJoyAssignmentMode.Dual; + controller.FullKeyColor.FullKeyBody = (uint)NpadColor.BodyGray; + controller.FullKeyColor.FullKeyButtons = (uint)NpadColor.ButtonGray; + controller.JoyColor.LeftBody = (uint)NpadColor.BodyNeonBlue; + controller.JoyColor.LeftButtons = (uint)NpadColor.ButtonGray; + controller.JoyColor.RightBody = (uint)NpadColor.BodyNeonRed; + controller.JoyColor.RightButtons = (uint)NpadColor.ButtonGray; + + controller.SystemProperties = NpadSystemProperties.IsPoweredJoyDual | + NpadSystemProperties.IsPoweredJoyLeft | + NpadSystemProperties.IsPoweredJoyRight; + + controller.BatteryLevelJoyDual = NpadBatteryLevel.Percent100; + controller.BatteryLevelJoyLeft = NpadBatteryLevel.Percent100; + controller.BatteryLevelJoyRight = NpadBatteryLevel.Percent100; switch (type) { case ControllerType.ProController: - defaultHeader.Type = ControllerType.ProController; + controller.StyleSet = NpadStyleTag.FullKey; controller.DeviceType = DeviceType.FullKey; - controller.SystemProperties |= NpadSystemProperties.AbxyButtonOriented | - NpadSystemProperties.PlusButtonCapability | - NpadSystemProperties.MinusButtonCapability; + controller.SystemProperties |= NpadSystemProperties.IsAbxyButtonOriented | + NpadSystemProperties.IsPlusAvailable | + NpadSystemProperties.IsMinusAvailable; break; case ControllerType.Handheld: - defaultHeader.Type = ControllerType.Handheld; + controller.StyleSet = NpadStyleTag.Handheld; controller.DeviceType = DeviceType.HandheldLeft | DeviceType.HandheldRight; - controller.SystemProperties |= NpadSystemProperties.AbxyButtonOriented | - NpadSystemProperties.PlusButtonCapability | - NpadSystemProperties.MinusButtonCapability; + controller.SystemProperties |= NpadSystemProperties.IsAbxyButtonOriented | + NpadSystemProperties.IsPlusAvailable | + NpadSystemProperties.IsMinusAvailable; break; case ControllerType.JoyconPair: - defaultHeader.Type = ControllerType.JoyconPair; + controller.StyleSet = NpadStyleTag.JoyDual; controller.DeviceType = DeviceType.JoyLeft | DeviceType.JoyRight; - controller.SystemProperties |= NpadSystemProperties.AbxyButtonOriented | - NpadSystemProperties.PlusButtonCapability | - NpadSystemProperties.MinusButtonCapability; + controller.SystemProperties |= NpadSystemProperties.IsAbxyButtonOriented | + NpadSystemProperties.IsPlusAvailable | + NpadSystemProperties.IsMinusAvailable; break; case ControllerType.JoyconLeft: - defaultHeader.Type = ControllerType.JoyconLeft; - defaultHeader.IsHalf = true; + controller.StyleSet = NpadStyleTag.JoyLeft; + controller.JoyAssignmentMode = NpadJoyAssignmentMode.Single; controller.DeviceType = DeviceType.JoyLeft; - controller.SystemProperties |= NpadSystemProperties.SlSrButtonOriented | - NpadSystemProperties.MinusButtonCapability; + controller.SystemProperties |= NpadSystemProperties.IsSlSrButtonOriented | + NpadSystemProperties.IsMinusAvailable; break; case ControllerType.JoyconRight: - defaultHeader.Type = ControllerType.JoyconRight; - defaultHeader.IsHalf = true; + controller.StyleSet = NpadStyleTag.JoyRight; + controller.JoyAssignmentMode = NpadJoyAssignmentMode.Single; controller.DeviceType = DeviceType.JoyRight; - controller.SystemProperties |= NpadSystemProperties.SlSrButtonOriented | - NpadSystemProperties.PlusButtonCapability; + controller.SystemProperties |= NpadSystemProperties.IsSlSrButtonOriented | + NpadSystemProperties.IsPlusAvailable; break; case ControllerType.Pokeball: - defaultHeader.Type = ControllerType.Pokeball; + controller.StyleSet = NpadStyleTag.Palma; controller.DeviceType = DeviceType.Palma; break; } - controller.Header = defaultHeader; - _styleSetUpdateEvents[(int)player].ReadableEvent.Signal(); _activeCount++; Logger.Info?.Print(LogClass.Hid, $"Connected Controller {type} to {player}"); } - private static NpadLayoutsIndex ControllerTypeToNpadLayout(ControllerType controllerType) - => controllerType switch + private ref RingLifo<NpadCommonState> GetCommonStateLifo(ref NpadInternalState npad) + { + switch (npad.StyleSet) + { + case NpadStyleTag.FullKey: + return ref npad.FullKey; + case NpadStyleTag.Handheld: + return ref npad.Handheld; + case NpadStyleTag.JoyDual: + return ref npad.JoyDual; + case NpadStyleTag.JoyLeft: + return ref npad.JoyLeft; + case NpadStyleTag.JoyRight: + return ref npad.JoyRight; + case NpadStyleTag.Palma: + return ref npad.Palma; + default: + return ref npad.SystemExt; + } + } + + private void UpdateUnusedInputIfNotEqual(ref RingLifo<NpadCommonState> currentlyUsed, ref RingLifo<NpadCommonState> possiblyUnused) + { + bool isEquals; + + unsafe + { + var aPointer = Unsafe.AsPointer(ref currentlyUsed); + var bPointer = Unsafe.AsPointer(ref possiblyUnused); + + isEquals = aPointer == bPointer; + } + + if (!isEquals) + { + NpadCommonState newState = new NpadCommonState(); + + WriteNewInputEntry(ref possiblyUnused, ref newState); + } + } + + private void WriteNewInputEntry(ref RingLifo<NpadCommonState> lifo, ref NpadCommonState state) + { + ref NpadCommonState previousEntry = ref lifo.GetCurrentEntryRef(); + + state.SamplingNumber = previousEntry.SamplingNumber + 1; + + lifo.Write(ref state); + } + + private void UpdateUnusedSixInputIfNotEqual(ref RingLifo<SixAxisSensorState> currentlyUsed, ref RingLifo<SixAxisSensorState> possiblyUnused) { - ControllerType.ProController => NpadLayoutsIndex.ProController, - ControllerType.Handheld => NpadLayoutsIndex.Handheld, - ControllerType.JoyconPair => NpadLayoutsIndex.JoyDual, - ControllerType.JoyconLeft => NpadLayoutsIndex.JoyLeft, - ControllerType.JoyconRight => NpadLayoutsIndex.JoyRight, - ControllerType.Pokeball => NpadLayoutsIndex.Pokeball, - _ => NpadLayoutsIndex.SystemExternal - }; + bool isEquals; + + unsafe + { + var aPointer = Unsafe.AsPointer(ref currentlyUsed); + var bPointer = Unsafe.AsPointer(ref possiblyUnused); + + isEquals = aPointer == bPointer; + } + + if (!isEquals) + { + SixAxisSensorState newState = new SixAxisSensorState(); + + WriteNewSixInputEntry(ref possiblyUnused, ref newState); + } + } + + private void WriteNewSixInputEntry(ref RingLifo<SixAxisSensorState> lifo, ref SixAxisSensorState state) + { + ref SixAxisSensorState previousEntry = ref lifo.GetCurrentEntryRef(); + + state.SamplingNumber = previousEntry.SamplingNumber + 1; + + lifo.Write(ref state); + } private void UpdateInput(GamepadInput state) { @@ -296,43 +373,88 @@ namespace Ryujinx.HLE.HOS.Services.Hid return; } - ref ShMemNpad currentNpad = ref _device.Hid.SharedMemory.Npads[(int)state.PlayerId]; + ref NpadInternalState currentNpad = ref _device.Hid.SharedMemory.Npads[(int)state.PlayerId].InternalState; - if (currentNpad.Header.Type == ControllerType.None) + if (currentNpad.StyleSet == NpadStyleTag.None) { return; } - ref NpadLayout currentLayout = ref currentNpad.Layouts[(int)ControllerTypeToNpadLayout(currentNpad.Header.Type)]; - ref NpadState currentEntry = ref currentLayout.Entries[(int)currentLayout.Header.LatestEntry]; + ref RingLifo<NpadCommonState> lifo = ref GetCommonStateLifo(ref currentNpad); + + NpadCommonState newState = new NpadCommonState + { + Buttons = (NpadButton)state.Buttons, + AnalogStickL = new AnalogStickState + { + X = state.LStick.Dx, + Y = state.LStick.Dy, + }, + AnalogStickR = new AnalogStickState + { + X = state.RStick.Dx, + Y = state.RStick.Dy, + } + }; + + newState.Attributes = NpadAttribute.IsConnected; + + switch (currentNpad.StyleSet) + { + case NpadStyleTag.Handheld: + case NpadStyleTag.FullKey: + newState.Attributes |= NpadAttribute.IsWired; + break; + case NpadStyleTag.JoyDual: + newState.Attributes |= NpadAttribute.IsLeftConnected | + NpadAttribute.IsRightConnected; + break; + case NpadStyleTag.JoyLeft: + newState.Attributes |= NpadAttribute.IsLeftConnected; + break; + case NpadStyleTag.JoyRight: + newState.Attributes |= NpadAttribute.IsRightConnected; + break; + } - currentEntry.Buttons = state.Buttons; - currentEntry.LStickX = state.LStick.Dx; - currentEntry.LStickY = state.LStick.Dy; - currentEntry.RStickX = state.RStick.Dx; - currentEntry.RStickY = state.RStick.Dy; + WriteNewInputEntry(ref lifo, ref newState); // Mirror data to Default layout just in case - ref NpadLayout mainLayout = ref currentNpad.Layouts[(int)NpadLayoutsIndex.SystemExternal]; - mainLayout.Entries[(int)mainLayout.Header.LatestEntry] = currentEntry; + if (!currentNpad.StyleSet.HasFlag(NpadStyleTag.SystemExt)) + { + WriteNewInputEntry(ref currentNpad.SystemExt, ref newState); + } + + UpdateUnusedInputIfNotEqual(ref lifo, ref currentNpad.FullKey); + UpdateUnusedInputIfNotEqual(ref lifo, ref currentNpad.Handheld); + UpdateUnusedInputIfNotEqual(ref lifo, ref currentNpad.JoyDual); + UpdateUnusedInputIfNotEqual(ref lifo, ref currentNpad.JoyLeft); + UpdateUnusedInputIfNotEqual(ref lifo, ref currentNpad.JoyRight); + UpdateUnusedInputIfNotEqual(ref lifo, ref currentNpad.Palma); } - private static SixAxixLayoutsIndex ControllerTypeToSixAxisLayout(ControllerType controllerType) - => controllerType switch + private void UpdateDisconnectedInput(PlayerIndex index) { - ControllerType.ProController => SixAxixLayoutsIndex.ProController, - ControllerType.Handheld => SixAxixLayoutsIndex.Handheld, - ControllerType.JoyconPair => SixAxixLayoutsIndex.JoyDualLeft, - ControllerType.JoyconLeft => SixAxixLayoutsIndex.JoyLeft, - ControllerType.JoyconRight => SixAxixLayoutsIndex.JoyRight, - ControllerType.Pokeball => SixAxixLayoutsIndex.Pokeball, - _ => SixAxixLayoutsIndex.SystemExternal - }; + ref NpadInternalState currentNpad = ref _device.Hid.SharedMemory.Npads[(int)index].InternalState; + + NpadCommonState newState = new NpadCommonState(); + + WriteNewInputEntry(ref currentNpad.FullKey, ref newState); + WriteNewInputEntry(ref currentNpad.Handheld, ref newState); + WriteNewInputEntry(ref currentNpad.JoyDual, ref newState); + WriteNewInputEntry(ref currentNpad.JoyLeft, ref newState); + WriteNewInputEntry(ref currentNpad.JoyRight, ref newState); + WriteNewInputEntry(ref currentNpad.Palma, ref newState); + } public void UpdateSixAxis(IList<SixAxisInput> states) { + Span<bool> updated = stackalloc bool[10]; + for (int i = 0; i < states.Count; ++i) { + updated[(int)states[i].PlayerId] = true; + if (SetSixAxisState(states[i])) { i++; @@ -345,6 +467,40 @@ namespace Ryujinx.HLE.HOS.Services.Hid SetSixAxisState(states[i], true); } } + + for (int i = 0; i < updated.Length; i++) + { + if (!updated[i]) + { + UpdateDisconnectedInputSixAxis((PlayerIndex)i); + } + } + } + + private ref RingLifo<SixAxisSensorState> GetSixAxisSensorLifo(ref NpadInternalState npad, bool isRightPair) + { + switch (npad.StyleSet) + { + case NpadStyleTag.FullKey: + return ref npad.FullKeySixAxisSensor; + case NpadStyleTag.Handheld: + return ref npad.HandheldSixAxisSensor; + case NpadStyleTag.JoyDual: + if (isRightPair) + { + return ref npad.JoyDualRightSixAxisSensor; + } + else + { + return ref npad.JoyDualSixAxisSensor; + } + case NpadStyleTag.JoyLeft: + return ref npad.JoyLeftSixAxisSensor; + case NpadStyleTag.JoyRight: + return ref npad.JoyRightSixAxisSensor; + default: + throw new NotImplementedException($"{npad.StyleSet}"); + } } private bool SetSixAxisState(SixAxisInput state, bool isRightPair = false) @@ -354,9 +510,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid return false; } - ref ShMemNpad currentNpad = ref _device.Hid.SharedMemory.Npads[(int)state.PlayerId]; + ref NpadInternalState currentNpad = ref _device.Hid.SharedMemory.Npads[(int)state.PlayerId].InternalState; - if (currentNpad.Header.Type == ControllerType.None) + if (currentNpad.StyleSet == NpadStyleTag.None) { return false; } @@ -382,87 +538,57 @@ namespace Ryujinx.HLE.HOS.Services.Hid Z = state.Rotation.Z }; - ref NpadSixAxis currentLayout = ref currentNpad.Sixaxis[(int)ControllerTypeToSixAxisLayout(currentNpad.Header.Type) + (isRightPair ? 1 : 0)]; - ref SixAxisState currentEntry = ref currentLayout.Entries[(int)currentLayout.Header.LatestEntry]; + SixAxisSensorState newState = new SixAxisSensorState + { + Acceleration = accel, + AngularVelocity = gyro, + Angle = rotation, + Attributes = SixAxisSensorAttribute.IsConnected + }; - int previousEntryIndex = (int)(currentLayout.Header.LatestEntry == 0 ? - currentLayout.Header.MaxEntryIndex : currentLayout.Header.LatestEntry - 1); + state.Orientation.AsSpan().CopyTo(newState.Direction.ToSpan()); - ref SixAxisState previousEntry = ref currentLayout.Entries[previousEntryIndex]; + ref RingLifo<SixAxisSensorState> lifo = ref GetSixAxisSensorLifo(ref currentNpad, isRightPair); - currentEntry.Accelerometer = accel; - currentEntry.Gyroscope = gyro; - currentEntry.Rotations = rotation; + WriteNewSixInputEntry(ref lifo, ref newState); - unsafe + bool needUpdateRight = currentNpad.StyleSet == NpadStyleTag.JoyDual && !isRightPair; + + if (!isRightPair) { - for (int i = 0; i < 9; i++) - { - currentEntry.Orientation[i] = state.Orientation[i]; - } + UpdateUnusedSixInputIfNotEqual(ref lifo, ref currentNpad.FullKeySixAxisSensor); + UpdateUnusedSixInputIfNotEqual(ref lifo, ref currentNpad.HandheldSixAxisSensor); + UpdateUnusedSixInputIfNotEqual(ref lifo, ref currentNpad.JoyDualSixAxisSensor); + UpdateUnusedSixInputIfNotEqual(ref lifo, ref currentNpad.JoyLeftSixAxisSensor); + UpdateUnusedSixInputIfNotEqual(ref lifo, ref currentNpad.JoyRightSixAxisSensor); } - return currentNpad.Header.Type == ControllerType.JoyconPair && !isRightPair; - } - - private void UpdateAllEntries() - { - ref Array10<ShMemNpad> controllers = ref _device.Hid.SharedMemory.Npads; - for (int i = 0; i < controllers.Length; ++i) + if (!needUpdateRight) { - ref Array7<NpadLayout> layouts = ref controllers[i].Layouts; - for (int l = 0; l < layouts.Length; ++l) - { - ref NpadLayout currentLayout = ref layouts[l]; - int currentIndex = UpdateEntriesHeader(ref currentLayout.Header, out int previousIndex); + SixAxisSensorState emptyState = new SixAxisSensorState(); - ref NpadState currentEntry = ref currentLayout.Entries[currentIndex]; - NpadState previousEntry = currentLayout.Entries[previousIndex]; + emptyState.Attributes = SixAxisSensorAttribute.IsConnected; - currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1; - currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1; - - if (controllers[i].Header.Type == ControllerType.None) - { - continue; - } - - currentEntry.ConnectionState = NpadConnectionState.ControllerStateConnected; + WriteNewSixInputEntry(ref currentNpad.JoyDualRightSixAxisSensor, ref emptyState); + } - switch (controllers[i].Header.Type) - { - case ControllerType.Handheld: - case ControllerType.ProController: - currentEntry.ConnectionState |= NpadConnectionState.ControllerStateWired; - break; - case ControllerType.JoyconPair: - currentEntry.ConnectionState |= NpadConnectionState.JoyLeftConnected | - NpadConnectionState.JoyRightConnected; - break; - case ControllerType.JoyconLeft: - currentEntry.ConnectionState |= NpadConnectionState.JoyLeftConnected; - break; - case ControllerType.JoyconRight: - currentEntry.ConnectionState |= NpadConnectionState.JoyRightConnected; - break; - } - } + return needUpdateRight; + } - ref Array6<NpadSixAxis> sixaxis = ref controllers[i].Sixaxis; - for (int l = 0; l < sixaxis.Length; ++l) - { - ref NpadSixAxis currentLayout = ref sixaxis[l]; - int currentIndex = UpdateEntriesHeader(ref currentLayout.Header, out int previousIndex); + private void UpdateDisconnectedInputSixAxis(PlayerIndex index) + { + ref NpadInternalState currentNpad = ref _device.Hid.SharedMemory.Npads[(int)index].InternalState; - ref SixAxisState currentEntry = ref currentLayout.Entries[currentIndex]; - SixAxisState previousEntry = currentLayout.Entries[previousIndex]; + SixAxisSensorState newState = new SixAxisSensorState(); - currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1; - currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1; + newState.Attributes = SixAxisSensorAttribute.IsConnected; - currentEntry._unknown2 = 1; - } - } + WriteNewSixInputEntry(ref currentNpad.FullKeySixAxisSensor, ref newState); + WriteNewSixInputEntry(ref currentNpad.HandheldSixAxisSensor, ref newState); + WriteNewSixInputEntry(ref currentNpad.JoyDualSixAxisSensor, ref newState); + WriteNewSixInputEntry(ref currentNpad.JoyDualRightSixAxisSensor, ref newState); + WriteNewSixInputEntry(ref currentNpad.JoyLeftSixAxisSensor, ref newState); + WriteNewSixInputEntry(ref currentNpad.JoyRightSixAxisSensor, ref newState); } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs index 10c34453..432a37e3 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs @@ -1,3 +1,5 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen; using System; namespace Ryujinx.HLE.HOS.Services.Hid @@ -8,39 +10,38 @@ namespace Ryujinx.HLE.HOS.Services.Hid public void Update(params TouchPoint[] points) { - ref ShMemTouchScreen touchscreen = ref _device.Hid.SharedMemory.TouchScreen; + ref RingLifo<TouchScreenState> lifo = ref _device.Hid.SharedMemory.TouchScreen; - int currentIndex = UpdateEntriesHeader(ref touchscreen.Header, out int previousIndex); + ref TouchScreenState previousEntry = ref lifo.GetCurrentEntryRef(); - if (!Active) + TouchScreenState newState = new TouchScreenState { - return; - } - - ref TouchScreenState currentEntry = ref touchscreen.Entries[currentIndex]; - TouchScreenState previousEntry = touchscreen.Entries[previousIndex]; - - currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1; - currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1; + SamplingNumber = previousEntry.SamplingNumber + 1 + }; - currentEntry.NumTouches = (ulong)points.Length; + if (Active) + { + newState.TouchesCount = points.Length; - int pointsLength = Math.Min(points.Length, currentEntry.Touches.Length); + int pointsLength = Math.Min(points.Length, newState.Touches.Length); - for (int i = 0; i < pointsLength; ++i) - { - TouchPoint pi = points[i]; - currentEntry.Touches[i] = new TouchScreenStateData + for (int i = 0; i < pointsLength; ++i) { - SampleTimestamp = currentEntry.SampleTimestamp, - X = pi.X, - Y = pi.Y, - TouchIndex = (uint)i, - DiameterX = pi.DiameterX, - DiameterY = pi.DiameterY, - Angle = pi.Angle - }; + TouchPoint pi = points[i]; + newState.Touches[i] = new TouchState + { + DeltaTime = newState.SamplingNumber, + X = pi.X, + Y = pi.Y, + FingerId = (uint)i, + DiameterX = pi.DiameterX, + DiameterY = pi.DiameterY, + RotationAngle = pi.Angle + }; + } } + + lifo.Write(ref newState); } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/KeyboardInput.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/KeyboardInput.cs index 26681270..be6857fb 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/KeyboardInput.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/KeyboardInput.cs @@ -3,6 +3,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid public struct KeyboardInput { public int Modifier; - public int[] Keys; + public ulong[] Keys; } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs index e45e695f..e3c22edf 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs @@ -3,7 +3,10 @@ using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Hid.HidServer; +using Ryujinx.HLE.HOS.Services.Hid.Types; using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid { @@ -69,6 +72,13 @@ namespace Ryujinx.HLE.HOS.Services.Hid { long appletResourceUserId = context.RequestData.ReadInt64(); + // Initialize entries to avoid issues with some games. + + for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++) + { + context.Device.Hid.DebugPad.Update(); + } + Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId }); return ResultCode.Success; @@ -82,6 +92,13 @@ namespace Ryujinx.HLE.HOS.Services.Hid context.Device.Hid.Touchscreen.Active = true; + // Initialize entries to avoid issues with some games. + + for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++) + { + context.Device.Hid.Touchscreen.Update(); + } + Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId }); return ResultCode.Success; @@ -95,6 +112,13 @@ namespace Ryujinx.HLE.HOS.Services.Hid context.Device.Hid.Mouse.Active = true; + // Initialize entries to avoid issues with some games. + + for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++) + { + context.Device.Hid.Mouse.Update(0, 0); + } + Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId }); return ResultCode.Success; @@ -108,6 +132,16 @@ namespace Ryujinx.HLE.HOS.Services.Hid context.Device.Hid.Keyboard.Active = true; + // Initialize entries to avoid issues with some games. + + KeyboardInput emptyInput = new KeyboardInput(); + emptyInput.Keys = new ulong[4]; + + for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++) + { + context.Device.Hid.Keyboard.Update(emptyInput); + } + Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId }); return ResultCode.Success; @@ -590,25 +624,22 @@ namespace Ryujinx.HLE.HOS.Services.Hid public ResultCode SetSupportedNpadIdType(ServiceCtx context) { long appletResourceUserId = context.RequestData.ReadInt64(); - long arraySize = context.Request.PtrBuff[0].Size / 4; + ulong arrayPosition = context.Request.PtrBuff[0].Position; + ulong arraySize = context.Request.PtrBuff[0].Size; - NpadIdType[] supportedPlayerIds = new NpadIdType[arraySize]; + ReadOnlySpan<NpadIdType> supportedPlayerIds = MemoryMarshal.Cast<byte, NpadIdType>(context.Memory.GetSpan(arrayPosition, (int)arraySize)); context.Device.Hid.Npads.ClearSupportedPlayers(); - for (int i = 0; i < arraySize; ++i) + for (int i = 0; i < supportedPlayerIds.Length; ++i) { - NpadIdType id = context.Memory.Read<NpadIdType>((ulong)(context.Request.PtrBuff[0].Position + i * 4)); - - if (id >= 0) + if (supportedPlayerIds[i] >= 0) { - context.Device.Hid.Npads.SetSupportedPlayer(HidUtils.GetIndexFromNpadIdType(id)); + context.Device.Hid.Npads.SetSupportedPlayer(HidUtils.GetIndexFromNpadIdType(supportedPlayerIds[i])); } - - supportedPlayerIds[i] = id; } - Logger.Stub?.PrintStub(LogClass.ServiceHid, $"{arraySize} " + string.Join(",", supportedPlayerIds)); + Logger.Stub?.PrintStub(LogClass.ServiceHid, $"{supportedPlayerIds.Length} " + string.Join(",", supportedPlayerIds.ToArray())); return ResultCode.Success; } @@ -620,6 +651,32 @@ namespace Ryujinx.HLE.HOS.Services.Hid long appletResourceUserId = context.RequestData.ReadInt64(); context.Device.Hid.Npads.Active = true; + + // Initialize entries to avoid issues with some games. + + List<GamepadInput> emptyGamepadInputs = new List<GamepadInput>(); + List<SixAxisInput> emptySixAxisInputs = new List<SixAxisInput>(); + + for (int player = 0; player < NpadDevices.MaxControllers; player++) + { + GamepadInput gamepadInput = new GamepadInput(); + SixAxisInput sixaxisInput = new SixAxisInput(); + + gamepadInput.PlayerId = (PlayerIndex)player; + sixaxisInput.PlayerId = (PlayerIndex)player; + + sixaxisInput.Orientation = new float[9]; + + emptyGamepadInputs.Add(gamepadInput); + emptySixAxisInputs.Add(sixaxisInput); + } + + for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++) + { + context.Device.Hid.Npads.Update(emptyGamepadInputs); + context.Device.Hid.Npads.UpdateSixAxis(emptySixAxisInputs); + } + Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId }); return ResultCode.Success; @@ -692,6 +749,31 @@ namespace Ryujinx.HLE.HOS.Services.Hid int revision = context.RequestData.ReadInt32(); long appletResourceUserId = context.RequestData.ReadInt64(); + // Initialize entries to avoid issues with some games. + + List<GamepadInput> emptyGamepadInputs = new List<GamepadInput>(); + List<SixAxisInput> emptySixAxisInputs = new List<SixAxisInput>(); + + for (int player = 0; player < NpadDevices.MaxControllers; player++) + { + GamepadInput gamepadInput = new GamepadInput(); + SixAxisInput sixaxisInput = new SixAxisInput(); + + gamepadInput.PlayerId = (PlayerIndex)player; + sixaxisInput.PlayerId = (PlayerIndex)player; + + sixaxisInput.Orientation = new float[9]; + + emptyGamepadInputs.Add(gamepadInput); + emptySixAxisInputs.Add(sixaxisInput); + } + + for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++) + { + context.Device.Hid.Npads.Update(emptyGamepadInputs); + context.Device.Hid.Npads.UpdateSixAxis(emptySixAxisInputs); + } + Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, revision }); return ResultCode.Success; @@ -1007,11 +1089,11 @@ namespace Ryujinx.HLE.HOS.Services.Hid byte[] vibrationDeviceHandleBuffer = new byte[context.Request.PtrBuff[0].Size]; - context.Memory.Read((ulong)context.Request.PtrBuff[0].Position, vibrationDeviceHandleBuffer); + context.Memory.Read(context.Request.PtrBuff[0].Position, vibrationDeviceHandleBuffer); byte[] vibrationValueBuffer = new byte[context.Request.PtrBuff[1].Size]; - context.Memory.Read((ulong)context.Request.PtrBuff[1].Position, vibrationValueBuffer); + context.Memory.Read(context.Request.PtrBuff[1].Position, vibrationValueBuffer); // TODO: Read all handles and values from buffer. diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Boolean32.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Boolean32.cs deleted file mode 100644 index 5a8d51c6..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/Boolean32.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - struct Boolean32 - { - private uint _value; - public static implicit operator bool(Boolean32 value) => (value._value & 1) != 0; - public static implicit operator Boolean32(bool value) => new Boolean32() { _value = value ? 1u : 0u }; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/HidVector.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/HidVector.cs index b41bcb2e..18d9fd9c 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/HidVector.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/HidVector.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid.Types { struct HidVector { diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadColor.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadColor.cs index 57b4b366..3c311e21 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadColor.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadColor.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid { - public enum NpadColor : int + public enum NpadColor : uint { BodyGray = 0x828282, BodyNeonRed = 0xFF3C28, diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs index 5f6a68cb..1abd8468 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid { - public enum NpadIdType + public enum NpadIdType : int { Player1 = 0, Player2 = 1, @@ -13,4 +13,4 @@ Unknown = 16, Handheld = 32 } -}
\ No newline at end of file +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadJoyHoldType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/NpadJoyHoldType.cs index a6f29760..d3b51a24 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadJoyHoldType.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/NpadJoyHoldType.cs @@ -1,8 +1,8 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid.Types { enum NpadJoyHoldType { Vertical, Horizontal } -}
\ No newline at end of file +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/CommonEntriesHeader.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/CommonEntriesHeader.cs deleted file mode 100644 index f83fdcdf..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/CommonEntriesHeader.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - struct CommonEntriesHeader - { - public ulong TimestampTicks; - public ulong NumEntries; - public ulong LatestEntry; - public ulong MaxEntryIndex; - } -} - diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs deleted file mode 100644 index 3fbaa304..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Ryujinx.Common.Memory; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - unsafe struct ShMemDebugPad - { - public CommonEntriesHeader Header; - public Array17<DebugPadEntry> Entries; - fixed byte _padding[0x138]; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPadEntry.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPadEntry.cs deleted file mode 100644 index 3089fc5b..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPadEntry.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - unsafe struct DebugPadEntry - { - public ulong SampleTimestamp; - public ulong SampleTimestamp2; - fixed byte _unknown[0x18]; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs deleted file mode 100644 index d950425d..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Ryujinx.Common.Memory; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - // TODO: Add missing structs - unsafe struct HidSharedMemory - { - public ShMemDebugPad DebugPad; - public ShMemTouchScreen TouchScreen; - public ShMemMouse Mouse; - public ShMemKeyboard Keyboard; - public fixed byte BasicXpad[0x4 * 0x400]; - public fixed byte HomeButton[0x200]; - public fixed byte SleepButton[0x200]; - public fixed byte CaptureButton[0x200]; - public fixed byte InputDetector[0x10 * 0x80]; - public fixed byte UniquePad[0x10 * 0x400]; - public Array10<ShMemNpad> Npads; - public fixed byte Gesture[0x800]; - public fixed byte ConsoleSixAxisSensor[0x20]; - fixed byte _padding[0x3de0]; - } -} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs deleted file mode 100644 index e2c1844f..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Ryujinx.Common.Memory; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - unsafe struct ShMemKeyboard - { - public CommonEntriesHeader Header; - public Array17<KeyboardState> Entries; - fixed byte _padding[0x28]; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/KeyboardState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/KeyboardState.cs deleted file mode 100644 index 1f54a4fd..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/KeyboardState.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - unsafe struct KeyboardState - { - public ulong SampleTimestamp; - public ulong SampleTimestamp2; - public ulong Modifier; - public fixed uint Keys[8]; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs deleted file mode 100644 index 6b99e04a..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs +++ /dev/null @@ -1,12 +0,0 @@ - -using Ryujinx.Common.Memory; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - unsafe struct ShMemMouse - { - public CommonEntriesHeader Header; - public Array17<MouseState> Entries; - fixed byte _padding[0xB0]; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MousePosition.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MousePosition.cs deleted file mode 100644 index e94c9e0c..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MousePosition.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - struct MousePosition - { - public int X; - public int Y; - public int VelocityX; - public int VelocityY; - public int ScrollVelocityX; - public int ScrollVelocityY; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MouseState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MouseState.cs deleted file mode 100644 index 7856b09d..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MouseState.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - struct MouseState - { - public ulong SampleTimestamp; - public ulong SampleTimestamp2; - public MousePosition Position; - public ulong Buttons; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/BatterCharge.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/BatterCharge.cs deleted file mode 100644 index b94ab172..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/BatterCharge.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - enum BatteryCharge : int - { - Percent0 = 0, - Percent25 = 1, - Percent50 = 2, - Percent75 = 3, - Percent100 = 4 - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/DeviceType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/DeviceType.cs deleted file mode 100644 index f6d7b783..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/DeviceType.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - [Flags] - enum DeviceType : int - { - FullKey = 1 << 0, - DebugPad = 1 << 1, - HandheldLeft = 1 << 2, - HandheldRight = 1 << 3, - JoyLeft = 1 << 4, - JoyRight = 1 << 5, - Palma = 1 << 6, // Poké Ball Plus - FamicomLeft = 1 << 7, - FamicomRight = 1 << 8, - NESLeft = 1 << 9, - NESRight = 1 << 10, - HandheldFamicomLeft = 1 << 11, - HandheldFamicomRight = 1 << 12, - HandheldNESLeft = 1 << 13, - HandheldNESRight = 1 << 14, - Lucia = 1 << 15, - System = 1 << 31 - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs deleted file mode 100644 index 4ef83f3d..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Ryujinx.Common.Memory; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - // TODO: Add missing structs - unsafe struct ShMemNpad - { - public NpadStateHeader Header; - public Array7<NpadLayout> Layouts; // One for each NpadLayoutsIndex - public Array6<NpadSixAxis> Sixaxis; - public DeviceType DeviceType; - uint _padding1; - public NpadSystemProperties SystemProperties; - public uint NpadSystemButtonProperties; - public Array3<BatteryCharge> BatteryState; - public fixed byte NfcXcdDeviceHandleHeader[0x20]; - public fixed byte NfcXcdDeviceHandleState[0x20 * 2]; - public ulong Mutex; - public fixed byte NpadGcTriggerHeader[0x20]; - public fixed byte NpadGcTriggerState[0x18 * 17]; - fixed byte _padding2[0xC38]; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadColorDescription.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadColorDescription.cs deleted file mode 100644 index ccc7cb8d..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadColorDescription.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - [Flags] - enum NpadColorDescription : int - { - ColorDescriptionColorsNonexistent = (1 << 1) - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadConnectionState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadConnectionState.cs deleted file mode 100644 index 60f64fd3..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadConnectionState.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - [Flags] - enum NpadConnectionState : long - { - ControllerStateConnected = (1 << 0), - ControllerStateWired = (1 << 1), - JoyLeftConnected = (1 << 2), - JoyRightConnected = (1 << 4) - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs deleted file mode 100644 index 24c4f4d4..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Ryujinx.Common.Memory; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - struct NpadLayout - { - public CommonEntriesHeader Header; - public Array17<NpadState> Entries; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs deleted file mode 100644 index c4419336..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - enum NpadLayoutsIndex : int - { - ProController = 0, - Handheld = 1, - JoyDual = 2, - JoyLeft = 3, - JoyRight = 4, - Pokeball = 5, - SystemExternal = 6 - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs deleted file mode 100644 index a0a39fdc..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Ryujinx.Common.Memory; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - struct NpadSixAxis - { - public CommonEntriesHeader Header; - public Array17<SixAxisState> Entries; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadState.cs deleted file mode 100644 index 60a5f9d3..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadState.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - struct NpadState - { - public ulong SampleTimestamp; - public ulong SampleTimestamp2; - public ControllerKeys Buttons; - public int LStickX; - public int LStickY; - public int RStickX; - public int RStickY; - public NpadConnectionState ConnectionState; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadStatesHeader.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadStatesHeader.cs deleted file mode 100644 index 006d4357..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadStatesHeader.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - struct NpadStateHeader - { - public ControllerType Type; - public Boolean32 IsHalf; - public NpadColorDescription SingleColorsDescriptor; - public NpadColor SingleColorBody; - public NpadColor SingleColorButtons; - public NpadColorDescription SplitColorsDescriptor; - public NpadColor LeftColorBody; - public NpadColor LeftColorButtons; - public NpadColor RightColorBody; - public NpadColor RightColorButtons; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSystemProperties.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSystemProperties.cs deleted file mode 100644 index 708f7da9..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSystemProperties.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - [Flags] - enum NpadSystemProperties : long - { - PowerInfo0Charging = 1 << 0, - PowerInfo1Charging = 1 << 1, - PowerInfo2Charging = 1 << 2, - PowerInfo0Connected = 1 << 3, - PowerInfo1Connected = 1 << 4, - PowerInfo2Connected = 1 << 5, - UnsupportedButtonPressedNpadSystem = 1 << 9, - UnsupportedButtonPressedNpadSystemExt = 1 << 10, - AbxyButtonOriented = 1 << 11, - SlSrButtonOriented = 1 << 12, - PlusButtonCapability = 1 << 13, - MinusButtonCapability = 1 << 14, - DirectionalButtonsSupported = 1 << 15 - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisLayoutsIndex.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisLayoutsIndex.cs deleted file mode 100644 index a8795fc0..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisLayoutsIndex.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - enum SixAxixLayoutsIndex : int - { - ProController = 0, - Handheld = 1, - JoyDualLeft = 2, - JoyDualRight = 3, - JoyLeft = 4, - JoyRight = 5, - Pokeball = 6, - SystemExternal = 7 - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs deleted file mode 100644 index 12974e7e..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - unsafe struct SixAxisState - { - public ulong SampleTimestamp; - ulong _unknown1; - public ulong SampleTimestamp2; - public HidVector Accelerometer; - public HidVector Gyroscope; - public HidVector Rotations; - public fixed float Orientation[9]; - public ulong _unknown2; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreen.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreen.cs deleted file mode 100644 index 5f12295c..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreen.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Ryujinx.Common.Memory; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - unsafe struct ShMemTouchScreen - { - public CommonEntriesHeader Header; - public Array17<TouchScreenState> Entries; - fixed byte _padding[0x3c8]; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs deleted file mode 100644 index 1c85e291..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Ryujinx.Common.Memory; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ - struct TouchScreenState - { - public ulong SampleTimestamp; - public ulong SampleTimestamp2; - public ulong NumTouches; - public Array16<TouchScreenStateData> Touches; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs deleted file mode 100644 index 4d4c48d1..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - struct TouchScreenStateData - { - public ulong SampleTimestamp; -#pragma warning disable CS0169 - uint _padding; -#pragma warning restore CS0169 - public uint TouchIndex; - public uint X; - public uint Y; - public uint DiameterX; - public uint DiameterY; - public uint Angle; -#pragma warning disable CS0169 - uint _padding2; -#pragma warning restore CS0169 - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AnalogStickState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AnalogStickState.cs new file mode 100644 index 00000000..bf4b5888 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AnalogStickState.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common +{ + struct AnalogStickState + { + public int X; + public int Y; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs new file mode 100644 index 00000000..45b92ba9 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs @@ -0,0 +1,26 @@ +using System.Threading; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common +{ + struct AtomicStorage<T> where T: unmanaged + { + public ulong SamplingNumber; + public T Object; + + public ulong ReadSamplingNumberAtomic() + { + return Interlocked.Read(ref SamplingNumber); + } + + public void SetObject(ref T obj) + { + ISampledData samplingProvider = obj as ISampledData; + + Interlocked.Exchange(ref SamplingNumber, samplingProvider.SamplingNumber); + + Thread.MemoryBarrier(); + + Object = obj; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledData.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledData.cs new file mode 100644 index 00000000..08f76747 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledData.cs @@ -0,0 +1,7 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common +{ + interface ISampledData + { + ulong SamplingNumber { get; } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs new file mode 100644 index 00000000..615e3893 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs @@ -0,0 +1,149 @@ +using Ryujinx.Common.Memory; +using System; +using System.Runtime.CompilerServices; +using System.Threading; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common +{ + struct RingLifo<T> where T: unmanaged + { + private const ulong MaxEntries = 17; + +#pragma warning disable CS0169 + private ulong _unused; +#pragma warning restore CS0169 +#pragma warning disable CS0414 + private ulong _bufferCount; +#pragma warning restore CS0414 + private ulong _index; + private ulong _count; + private Array17<AtomicStorage<T>> _storage; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private ulong ReadCurrentIndex() + { + return Interlocked.Read(ref _index); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private ulong ReadCurrentCount() + { + return Interlocked.Read(ref _count); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ulong GetNextIndexForWrite(ulong index) + { + return (index + 1) % MaxEntries; + } + + public ref AtomicStorage<T> GetCurrentAtomicEntryRef() + { + ulong countAvailaible = Math.Min(Math.Max(0, ReadCurrentCount()), 1); + + if (countAvailaible == 0) + { + _storage[0] = default; + + return ref _storage[0]; + } + + ulong index = ReadCurrentIndex(); + + while (true) + { + int inputEntryIndex = (int)((index + MaxEntries + 1 - countAvailaible) % MaxEntries); + + ref AtomicStorage<T> result = ref _storage[inputEntryIndex]; + + ulong samplingNumber0 = result.ReadSamplingNumberAtomic(); + ulong samplingNumber1 = result.ReadSamplingNumberAtomic(); + + if (samplingNumber0 != samplingNumber1 && (result.SamplingNumber - result.SamplingNumber) != 1) + { + ulong tempCount = Math.Min(ReadCurrentCount(), countAvailaible); + + countAvailaible = Math.Min(tempCount, 1); + index = ReadCurrentIndex(); + + continue; + } + + return ref result; + } + } + + public ref T GetCurrentEntryRef() + { + return ref GetCurrentAtomicEntryRef().Object; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan<AtomicStorage<T>> ReadEntries(uint maxCount) + { + ulong countAvailaible = Math.Min(Math.Max(0, ReadCurrentCount()), maxCount); + + if (countAvailaible == 0) + { + return ReadOnlySpan<AtomicStorage<T>>.Empty; + } + + ulong index = ReadCurrentIndex(); + + AtomicStorage<T>[] result = new AtomicStorage<T>[countAvailaible]; + + for (ulong i = 0; i < countAvailaible; i++) + { + int inputEntryIndex = (int)((index + MaxEntries + 1 - countAvailaible + i) % MaxEntries); + int outputEntryIndex = (int)(countAvailaible - i - 1); + + ulong samplingNumber0 = _storage[inputEntryIndex].ReadSamplingNumberAtomic(); + result[outputEntryIndex] = _storage[inputEntryIndex]; + ulong samplingNumber1 = _storage[inputEntryIndex].ReadSamplingNumberAtomic(); + + if (samplingNumber0 != samplingNumber1 && (i > 0 && (result[outputEntryIndex].SamplingNumber - result[outputEntryIndex].SamplingNumber) != 1)) + { + ulong tempCount = Math.Min(ReadCurrentCount(), countAvailaible); + + countAvailaible = Math.Min(tempCount, maxCount); + index = ReadCurrentIndex(); + + i -= 1; + } + } + + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(ref T value) + { + ulong targetIndex = GetNextIndexForWrite(ReadCurrentIndex()); + + _storage[(int)targetIndex].SetObject(ref value); + + Interlocked.Exchange(ref _index, targetIndex); + + ulong count = ReadCurrentCount(); + + if (count < (MaxEntries - 1)) + { + Interlocked.Increment(ref _count); + } + } + + public void Clear() + { + Interlocked.Exchange(ref _count, 0); + Interlocked.Exchange(ref _index, 0); + } + + public static RingLifo<T> Create() + { + return new RingLifo<T> + { + _bufferCount = MaxEntries + }; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadAttribute.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadAttribute.cs new file mode 100644 index 00000000..ec5bd3c8 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadAttribute.cs @@ -0,0 +1,11 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad +{ + [Flags] + enum DebugPadAttribute : uint + { + None = 0, + Connected = 1 << 0 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadButton.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadButton.cs new file mode 100644 index 00000000..e8f28317 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadButton.cs @@ -0,0 +1,24 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad +{ + [Flags] + enum DebugPadButton : uint + { + None = 0, + A = 1 << 0, + B = 1 << 1, + X = 1 << 2, + Y = 1 << 3, + L = 1 << 4, + R = 1 << 5, + ZL = 1 << 6, + ZR = 1 << 7, + Start = 1 << 8, + Select = 1 << 9, + Left = 1 << 10, + Up = 1 << 11, + Right = 1 << 12, + Down = 1 << 13 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs new file mode 100644 index 00000000..3e1e1ad8 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs @@ -0,0 +1,15 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad +{ + struct DebugPadState : ISampledData + { + public ulong SamplingNumber; + public DebugPadAttribute Attributes; + public DebugPadButton Buttons; + public AnalogStickState AnalogStickR; + public AnalogStickState AnalogStickL; + + ulong ISampledData.SamplingNumber => SamplingNumber; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKey.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKey.cs new file mode 100644 index 00000000..22df7c79 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKey.cs @@ -0,0 +1,29 @@ +using Ryujinx.Common.Memory; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard +{ + struct KeyboardKey + { + public Array4<ulong> RawData; + + public bool this[KeyboardKeyShift index] + { + get + { + return (RawData[(int)index / 64] & (1UL << ((int)index & 63))) != 0; + } + set + { + int arrayIndex = (int)index / 64; + ulong mask = 1UL << ((int)index & 63); + + RawData[arrayIndex] &= ~mask; + + if (value) + { + RawData[arrayIndex] |= mask; + } + } + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKeyShift.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKeyShift.cs new file mode 100644 index 00000000..01c2bb30 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKeyShift.cs @@ -0,0 +1,138 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard +{ + enum KeyboardKeyShift + { + A = 4, + B = 5, + C = 6, + D = 7, + E = 8, + F = 9, + G = 10, + H = 11, + I = 12, + J = 13, + K = 14, + L = 15, + M = 16, + N = 17, + O = 18, + P = 19, + Q = 20, + R = 21, + S = 22, + T = 23, + U = 24, + V = 25, + W = 26, + X = 27, + Y = 28, + Z = 29, + D1 = 30, + D2 = 31, + D3 = 32, + D4 = 33, + D5 = 34, + D6 = 35, + D7 = 36, + D8 = 37, + D9 = 38, + D0 = 39, + Return = 40, + Escape = 41, + Backspace = 42, + Tab = 43, + Space = 44, + Minus = 45, + Plus = 46, + OpenBracket = 47, + CloseBracket = 48, + Pipe = 49, + Tilde = 50, + Semicolon = 51, + Quote = 52, + Backquote = 53, + Comma = 54, + Period = 55, + Slash = 56, + CapsLock = 57, + F1 = 58, + F2 = 59, + F3 = 60, + F4 = 61, + F5 = 62, + F6 = 63, + F7 = 64, + F8 = 65, + F9 = 66, + F10 = 67, + F11 = 68, + F12 = 69, + PrintScreen = 70, + ScrollLock = 71, + Pause = 72, + Insert = 73, + Home = 74, + PageUp = 75, + Delete = 76, + End = 77, + PageDown = 78, + RightArrow = 79, + LeftArrow = 80, + DownArrow = 81, + UpArrow = 82, + NumLock = 83, + NumPadDivide = 84, + NumPadMultiply = 85, + NumPadSubtract = 86, + NumPadAdd = 87, + NumPadEnter = 88, + NumPad1 = 89, + NumPad2 = 90, + NumPad3 = 91, + NumPad4 = 92, + NumPad5 = 93, + NumPad6 = 94, + NumPad7 = 95, + NumPad8 = 96, + NumPad9 = 97, + NumPad0 = 98, + NumPadDot = 99, + Backslash = 100, + Application = 101, + Power = 102, + NumPadEquals = 103, + F13 = 104, + F14 = 105, + F15 = 106, + F16 = 107, + F17 = 108, + F18 = 109, + F19 = 110, + F20 = 111, + F21 = 112, + F22 = 113, + F23 = 114, + F24 = 115, + NumPadComma = 133, + Ro = 135, + KatakanaHiragana = 136, + Yen = 137, + Henkan = 138, + Muhenkan = 139, + NumPadCommaPc98 = 140, + HangulEnglish = 144, + Hanja = 145, + Katakana = 146, + Hiragana = 147, + ZenkakuHankaku = 148, + LeftControl = 224, + LeftShift = 225, + LeftAlt = 226, + LeftGui = 227, + RightControl = 228, + RightShift = 229, + RightAlt = 230, + RightGui = 231 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs new file mode 100644 index 00000000..72d1603a --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs @@ -0,0 +1,21 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard +{ + // TODO: This seems entirely wrong + [Flags] + enum KeyboardModifier : uint + { + None = 0, + Control = 1 << 0, + Shift = 1 << 1, + LeftAlt = 1 << 2, + RightAlt = 1 << 3, + Gui = 1 << 4, + CapsLock = 1 << 8, + ScrollLock = 1 << 9, + NumLock = 1 << 10, + Katakana = 1 << 11, + Hiragana = 1 << 12 + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs new file mode 100644 index 00000000..37608506 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs @@ -0,0 +1,13 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard +{ + struct KeyboardState : ISampledData + { + public ulong SamplingNumber; + public KeyboardModifier Modifiers; + public KeyboardKey Keys; + + ulong ISampledData.SamplingNumber => SamplingNumber; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseAttribute.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseAttribute.cs new file mode 100644 index 00000000..5ffba0d7 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse +{ + [Flags] + enum MouseAttribute : uint + { + None = 0, + Transferable = 1 << 0, + IsConnected = 1 << 1 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseButton.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseButton.cs new file mode 100644 index 00000000..7e35140c --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseButton.cs @@ -0,0 +1,15 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse +{ + [Flags] + enum MouseButton : uint + { + None = 0, + Left = 1 << 0, + Right = 1 << 1, + Middle = 1 << 2, + Forward = 1 << 3, + Back = 1 << 4 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs new file mode 100644 index 00000000..67ad6bf1 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs @@ -0,0 +1,19 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse +{ + struct MouseState : ISampledData + { + public ulong SamplingNumber; + public int X; + public int Y; + public int DeltaX; + public int DeltaY; + public int WheelDeltaX; + public int WheelDeltaY; + public MouseButton Buttons; + public MouseAttribute Attributes; + + ulong ISampledData.SamplingNumber => SamplingNumber; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs new file mode 100644 index 00000000..b0201835 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs @@ -0,0 +1,29 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + [Flags] + enum DeviceType : int + { + None = 0, + + FullKey = 1 << 0, + DebugPad = 1 << 1, + HandheldLeft = 1 << 2, + HandheldRight = 1 << 3, + JoyLeft = 1 << 4, + JoyRight = 1 << 5, + Palma = 1 << 6, + LarkHvcLeft = 1 << 7, + LarkHvcRight = 1 << 8, + LarkNesLeft = 1 << 9, + LarkNesRight = 1 << 10, + HandheldLarkHvcLeft = 1 << 11, + HandheldLarkHvcRight = 1 << 12, + HandheldLarkNesLeft = 1 << 13, + HandheldLarkNesRight = 1 << 14, + Lucia = 1 << 15, + + System = 1 << 31 + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadAttribute.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadAttribute.cs new file mode 100644 index 00000000..0960b7bf --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadAttribute.cs @@ -0,0 +1,16 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + [Flags] + enum NpadAttribute : uint + { + None = 0, + IsConnected = 1 << 0, + IsWired = 1 << 1, + IsLeftConnected = 1 << 2, + IsLeftWired = 1 << 3, + IsRightConnected = 1 << 4, + IsRightWired = 1 << 5 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs new file mode 100644 index 00000000..477dfd10 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + enum NpadBatteryLevel : int + { + Percent0, + Percent25, + Percent50, + Percent75, + Percent100 + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadButton.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadButton.cs new file mode 100644 index 00000000..5b3e13a7 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadButton.cs @@ -0,0 +1,44 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + [Flags] + enum NpadButton : ulong + { + None = 0, + A = 1 << 0, + B = 1 << 1, + X = 1 << 2, + Y = 1 << 3, + StickL = 1 << 4, + StickR = 1 << 5, + L = 1 << 6, + R = 1 << 7, + ZL = 1 << 8, + ZR = 1 << 9, + Plus = 1 << 10, + Minus = 1 << 11, + Left = 1 << 12, + Up = 1 << 13, + Right = 1 << 14, + Down = 1 << 15, + StickLLeft = 1 << 16, + StickLUp = 1 << 17, + StickLRight = 1 << 18, + StickLDown = 1 << 19, + StickRLeft = 1 << 20, + StickRUp = 1 << 21, + StickRRight = 1 << 22, + StickRDown = 1 << 23, + LeftSL = 1 << 24, + LeftSR = 1 << 25, + RightSL = 1 << 26, + RightSR = 1 << 27, + Palma = 1 << 28, + + // FIXME: Probably a button on Lark. + Unknown29 = 1 << 29, + + HandheldLeftB = 1 << 30 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadColorAttribute.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadColorAttribute.cs new file mode 100644 index 00000000..1e547cc8 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadColorAttribute.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + enum NpadColorAttribute : uint + { + Ok, + ReadError, + NoController + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs new file mode 100644 index 00000000..eaccef80 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs @@ -0,0 +1,16 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + struct NpadCommonState : ISampledData + { + public ulong SamplingNumber; + public NpadButton Buttons; + public AnalogStickState AnalogStickL; + public AnalogStickState AnalogStickR; + public NpadAttribute Attributes; + private uint _reserved; + + ulong ISampledData.SamplingNumber => SamplingNumber; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadFullKeyColorState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadFullKeyColorState.cs new file mode 100644 index 00000000..990eafb2 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadFullKeyColorState.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + struct NpadFullKeyColorState + { + public NpadColorAttribute Attribute; + public uint FullKeyBody; + public uint FullKeyButtons; + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs new file mode 100644 index 00000000..52668f85 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs @@ -0,0 +1,15 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + struct NpadGcTriggerState : ISampledData + { +#pragma warning disable CS0649 + public ulong SamplingNumber; + public uint TriggerL; + public uint TriggerR; +#pragma warning restore CS0649 + + ulong ISampledData.SamplingNumber => SamplingNumber; + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadInternalState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadInternalState.cs new file mode 100644 index 00000000..f225ff67 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadInternalState.cs @@ -0,0 +1,61 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + struct NpadInternalState + { + public NpadStyleTag StyleSet; + public NpadJoyAssignmentMode JoyAssignmentMode; + public NpadFullKeyColorState FullKeyColor; + public NpadJoyColorState JoyColor; + public RingLifo<NpadCommonState> FullKey; + public RingLifo<NpadCommonState> Handheld; + public RingLifo<NpadCommonState> JoyDual; + public RingLifo<NpadCommonState> JoyLeft; + public RingLifo<NpadCommonState> JoyRight; + public RingLifo<NpadCommonState> Palma; + public RingLifo<NpadCommonState> SystemExt; + public RingLifo<SixAxisSensorState> FullKeySixAxisSensor; + public RingLifo<SixAxisSensorState> HandheldSixAxisSensor; + public RingLifo<SixAxisSensorState> JoyDualSixAxisSensor; + public RingLifo<SixAxisSensorState> JoyDualRightSixAxisSensor; + public RingLifo<SixAxisSensorState> JoyLeftSixAxisSensor; + public RingLifo<SixAxisSensorState> JoyRightSixAxisSensor; + public DeviceType DeviceType; + private uint _reserved1; + public NpadSystemProperties SystemProperties; + public NpadSystemButtonProperties SystemButtonProperties; + public NpadBatteryLevel BatteryLevelJoyDual; + public NpadBatteryLevel BatteryLevelJoyLeft; + public NpadBatteryLevel BatteryLevelJoyRight; + public uint AppletFooterUiAttributes; + public byte AppletFooterUiType; + private unsafe fixed byte _reserved2[0x7B]; + public RingLifo<NpadGcTriggerState> GcTrigger; + public NpadLarkType LarkTypeLeftAndMain; + public NpadLarkType LarkTypeRight; + public NpadLuciaType LuciaType; + public uint Unknown43EC; + + public static NpadInternalState Create() + { + return new NpadInternalState + { + FullKey = RingLifo<NpadCommonState>.Create(), + Handheld = RingLifo<NpadCommonState>.Create(), + JoyDual = RingLifo<NpadCommonState>.Create(), + JoyLeft = RingLifo<NpadCommonState>.Create(), + JoyRight = RingLifo<NpadCommonState>.Create(), + Palma = RingLifo<NpadCommonState>.Create(), + SystemExt = RingLifo<NpadCommonState>.Create(), + FullKeySixAxisSensor = RingLifo<SixAxisSensorState>.Create(), + HandheldSixAxisSensor = RingLifo<SixAxisSensorState>.Create(), + JoyDualSixAxisSensor = RingLifo<SixAxisSensorState>.Create(), + JoyDualRightSixAxisSensor = RingLifo<SixAxisSensorState>.Create(), + JoyLeftSixAxisSensor = RingLifo<SixAxisSensorState>.Create(), + JoyRightSixAxisSensor = RingLifo<SixAxisSensorState>.Create(), + GcTrigger = RingLifo<NpadGcTriggerState>.Create(), + }; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyAssignmentMode.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyAssignmentMode.cs new file mode 100644 index 00000000..871c4c5a --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyAssignmentMode.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + enum NpadJoyAssignmentMode : uint + { + Dual, + Single + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyColorState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyColorState.cs new file mode 100644 index 00000000..3986dd5e --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyColorState.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + struct NpadJoyColorState + { + public NpadColorAttribute Attribute; + public uint LeftBody; + public uint LeftButtons; + public uint RightBody; + public uint RightButtons; + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLarkType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLarkType.cs new file mode 100644 index 00000000..a487a911 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLarkType.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + enum NpadLarkType : uint + { + Invalid, + H1, + H2, + NL, + NR + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLuciaType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLuciaType.cs new file mode 100644 index 00000000..95148485 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLuciaType.cs @@ -0,0 +1,10 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + enum NpadLuciaType + { + Invalid, + J, + E, + U + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadState.cs new file mode 100644 index 00000000..ed9e7c0d --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadState.cs @@ -0,0 +1,18 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + [StructLayout(LayoutKind.Sequential, Size = 0x5000)] + struct NpadState + { + public NpadInternalState InternalState; + + public static NpadState Create() + { + return new NpadState + { + InternalState = NpadInternalState.Create() + }; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadStyleTag.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadStyleTag.cs new file mode 100644 index 00000000..f31978e2 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadStyleTag.cs @@ -0,0 +1,76 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + /// <summary> + /// Nintendo pad style + /// </summary> + [Flags] + enum NpadStyleTag : uint + { + /// <summary> + /// No type. + /// </summary> + None = 0, + + /// <summary> + /// Pro controller. + /// </summary> + FullKey = 1 << 0, + + /// <summary> + /// Joy-Con controller in handheld mode. + /// </summary> + Handheld = 1 << 1, + + /// <summary> + /// Joy-Con controller in dual mode. + /// </summary> + JoyDual = 1 << 2, + + /// <summary> + /// Joy-Con left controller in single mode. + /// </summary> + JoyLeft = 1 << 3, + + /// <summary> + /// Joy-Con right controller in single mode. + /// </summary> + JoyRight = 1 << 4, + + /// <summary> + /// GameCube controller. + /// </summary> + Gc = 1 << 5, + + /// <summary> + /// Poké Ball Plus controller. + /// </summary> + Palma = 1 << 6, + + /// <summary> + /// NES and Famicom controller. + /// </summary> + Lark = 1 << 7, + + /// <summary> + /// NES and Famicom controller in handheld mode. + /// </summary> + HandheldLark = 1 << 8, + + /// <summary> + /// SNES controller. + /// </summary> + Lucia = 1 << 9, + + /// <summary> + /// Generic external controller. + /// </summary> + SystemExt = 1 << 29, + + /// <summary> + /// Generic controller. + /// </summary> + System = 1 << 30 + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemButtonProperties.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemButtonProperties.cs new file mode 100644 index 00000000..68603271 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemButtonProperties.cs @@ -0,0 +1,11 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + [Flags] + enum NpadSystemButtonProperties : uint + { + None = 0, + IsUnintendedHomeButtonInputProtectionEnabled = 1 << 0 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemProperties.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemProperties.cs new file mode 100644 index 00000000..13444555 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemProperties.cs @@ -0,0 +1,24 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + [Flags] + enum NpadSystemProperties : ulong + { + None = 0, + + IsChargingJoyDual = 1 << 0, + IsChargingJoyLeft = 1 << 1, + IsChargingJoyRight = 1 << 2, + IsPoweredJoyDual = 1 << 3, + IsPoweredJoyLeft = 1 << 4, + IsPoweredJoyRight = 1 << 5, + IsUnsuportedButtonPressedOnNpadSystem = 1 << 9, + IsUnsuportedButtonPressedOnNpadSystemExt = 1 << 10, + IsAbxyButtonOriented = 1 << 11, + IsSlSrButtonOriented = 1 << 12, + IsPlusAvailable = 1 << 13, + IsMinusAvailable = 1 << 14, + IsDirectionalButtonsAvailable = 1 << 15 + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorAttribute.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorAttribute.cs new file mode 100644 index 00000000..7ed46d98 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + [Flags] + enum SixAxisSensorAttribute : uint + { + None = 0, + IsConnected = 1 << 0, + IsInterpolated = 1 << 1 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs new file mode 100644 index 00000000..d024b0b0 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs @@ -0,0 +1,19 @@ +using Ryujinx.Common.Memory; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +{ + struct SixAxisSensorState : ISampledData + { + public ulong DeltaTime; + public ulong SamplingNumber; + public HidVector Acceleration; + public HidVector AngularVelocity; + public HidVector Angle; + public Array9<float> Direction; + public SixAxisSensorAttribute Attributes; + private uint _reserved; + + ulong ISampledData.SamplingNumber => SamplingNumber; + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs new file mode 100644 index 00000000..48acfc3f --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs @@ -0,0 +1,66 @@ +using Ryujinx.Common.Memory; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory +{ + /// <summary> + /// Represent the shared memory shared between applications for input. + /// </summary> + [StructLayout(LayoutKind.Explicit, Size = 0x40000)] + struct SharedMemory + { + /// <summary> + /// Debug controller. + /// </summary> + [FieldOffset(0)] + public RingLifo<DebugPadState> DebugPad; + + /// <summary> + /// Touchscreen. + /// </summary> + [FieldOffset(0x400)] + public RingLifo<TouchScreenState> TouchScreen; + + /// <summary> + /// Mouse. + /// </summary> + [FieldOffset(0x3400)] + public RingLifo<MouseState> Mouse; + + /// <summary> + /// Keyboard. + /// </summary> + [FieldOffset(0x3800)] + public RingLifo<KeyboardState> Keyboard; + + /// <summary> + /// Nintendo Pads. + /// </summary> + [FieldOffset(0x9A00)] + public Array10<NpadState> Npads; + + public static SharedMemory Create() + { + SharedMemory result = new SharedMemory + { + DebugPad = RingLifo<DebugPadState>.Create(), + TouchScreen = RingLifo<TouchScreenState>.Create(), + Mouse = RingLifo<MouseState>.Create(), + Keyboard = RingLifo<KeyboardState>.Create(), + }; + + for (int i = 0; i < result.Npads.Length; i++) + { + result.Npads[i] = NpadState.Create(); + } + + return result; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs new file mode 100644 index 00000000..8a8f9cc1 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen +{ + [Flags] + enum TouchAttribute : uint + { + None = 0, + Start = 1 << 0, + End = 1 << 1 + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs new file mode 100644 index 00000000..8203e49b --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs @@ -0,0 +1,15 @@ +using Ryujinx.Common.Memory; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen +{ + struct TouchScreenState : ISampledData + { + public ulong SamplingNumber; + public int TouchesCount; + private int _reserved; + public Array16<TouchState> Touches; + + ulong ISampledData.SamplingNumber => SamplingNumber; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchState.cs new file mode 100644 index 00000000..ba621a2b --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchState.cs @@ -0,0 +1,19 @@ +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen +{ + struct TouchState + { + public ulong DeltaTime; +#pragma warning disable CS0649 + public TouchAttribute Attribute; +#pragma warning restore CS0649 + public uint FingerId; + public uint X; + public uint Y; + public uint DiameterX; + public uint DiameterY; + public uint RotationAngle; +#pragma warning disable CS0169 + private uint _reserved; +#pragma warning restore CS0169 + } +} diff --git a/Ryujinx.HLE/HOS/Services/IpcService.cs b/Ryujinx.HLE/HOS/Services/IpcService.cs index 69d461de..e9582c26 100644 --- a/Ryujinx.HLE/HOS/Services/IpcService.cs +++ b/Ryujinx.HLE/HOS/Services/IpcService.cs @@ -109,7 +109,7 @@ namespace Ryujinx.HLE.HOS.Services bool serviceExists = service.HipcCommands.TryGetValue(commandId, out MethodInfo processRequest); - if (ServiceConfiguration.IgnoreMissingServices || serviceExists) + if (context.Device.Configuration.IgnoreMissingServices || serviceExists) { ResultCode result = ResultCode.Success; @@ -163,7 +163,7 @@ namespace Ryujinx.HLE.HOS.Services bool serviceExists = TipcCommands.TryGetValue(commandId, out MethodInfo processRequest); - if (ServiceConfiguration.IgnoreMissingServices || serviceExists) + if (context.Device.Configuration.IgnoreMissingServices || serviceExists) { ResultCode result = ResultCode.Success; diff --git a/Ryujinx.HLE/HOS/Services/Lm/LogService/ILogger.cs b/Ryujinx.HLE/HOS/Services/Lm/LogService/ILogger.cs index 0bf6f177..3181668f 100644 --- a/Ryujinx.HLE/HOS/Services/Lm/LogService/ILogger.cs +++ b/Ryujinx.HLE/HOS/Services/Lm/LogService/ILogger.cs @@ -19,11 +19,11 @@ namespace Ryujinx.HLE.HOS.Services.Lm.LogService private string LogImpl(ServiceCtx context) { - (long bufPos, long bufSize) = context.Request.GetBufferType0x21(); + (ulong bufPos, ulong bufSize) = context.Request.GetBufferType0x21(); byte[] logBuffer = new byte[bufSize]; - context.Memory.Read((ulong)bufPos, logBuffer); + context.Memory.Read(bufPos, logBuffer); using MemoryStream ms = new MemoryStream(logBuffer); diff --git a/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs b/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs index 73f1a673..dea32f62 100644 --- a/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs +++ b/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs @@ -261,7 +261,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii.StaticService ResultCode result = Export(data); - context.Memory.Write((ulong)outputBuffer.Position, data.ToArray()); + context.Memory.Write(outputBuffer.Position, data.ToArray()); return result; } @@ -352,7 +352,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii.StaticService { rawData = new byte[ipcBuff.Size]; - context.Memory.Read((ulong)ipcBuff.Position, rawData); + context.Memory.Read(ipcBuff.Position, rawData); } return new Span<byte>(rawData); @@ -367,7 +367,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii.StaticService { Span<byte> rawData = MemoryMarshal.Cast<T, byte>(span); - context.Memory.Write((ulong)ipcBuff.Position, rawData); + context.Memory.Write(ipcBuff.Position, rawData); } protected abstract bool IsUpdated(SourceFlag flag); diff --git a/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs b/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs index 6cd643d3..bce52119 100644 --- a/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs +++ b/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs @@ -12,7 +12,7 @@ namespace Ryujinx.HLE.HOS.Services.Mm private static uint _uniqueId = 1; - public IRequest(ServiceCtx context) {} + public IRequest(ServiceCtx context) { } [CommandHipc(0)] // InitializeOld(u32, u32, u32) @@ -50,14 +50,14 @@ namespace Ryujinx.HLE.HOS.Services.Mm public ResultCode SetAndWaitOld(ServiceCtx context) { MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32(); - uint value = context.RequestData.ReadUInt32(); + uint frequenceHz = context.RequestData.ReadUInt32(); int timeout = context.RequestData.ReadInt32(); - Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType, value, timeout }); + Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType, frequenceHz, timeout }); lock (_sessionListLock) { - GetSessionByType(operationType)?.SetAndWait(value, timeout); + GetSessionByType(operationType)?.SetAndWait(frequenceHz, timeout); } return ResultCode.Success; @@ -120,15 +120,15 @@ namespace Ryujinx.HLE.HOS.Services.Mm // SetAndWait(u32, u32, u32) public ResultCode SetAndWait(ServiceCtx context) { - uint id = context.RequestData.ReadUInt32(); - uint value = context.RequestData.ReadUInt32(); - int timeout = context.RequestData.ReadInt32(); + uint id = context.RequestData.ReadUInt32(); + uint frequenceHz = context.RequestData.ReadUInt32(); + int timeout = context.RequestData.ReadInt32(); - Logger.Stub?.PrintStub(LogClass.ServiceMm, new { id, value, timeout }); + Logger.Stub?.PrintStub(LogClass.ServiceMm, new { id, frequenceHz, timeout }); lock (_sessionListLock) { - GetSessionById(id)?.SetAndWait(value, timeout); + GetSessionById(id)?.SetAndWait(frequenceHz, timeout); } return ResultCode.Success; diff --git a/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaOperationType.cs b/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaOperationType.cs index cf4cdf20..2742af6c 100644 --- a/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaOperationType.cs +++ b/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaOperationType.cs @@ -2,10 +2,9 @@ { enum MultiMediaOperationType : uint { - // TODO: figure out the unknown variants. - Unknown2 = 2, - VideoDecode = 5, - VideoEncode = 6, - Unknown7 = 7 + Ram = 2, + NvEnc = 5, + NvDec = 6, + NvJpg = 7 } -} +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs b/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs index 6ffa33f4..3fbc42a9 100644 --- a/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs +++ b/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs @@ -17,10 +17,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(0)] - // ResolveProgramPath() + // ResolveProgramPath(u64 titleId) public ResultCode ResolveProgramPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); if (ResolvePath(context, titleId, NcaContentType.Program)) { @@ -33,10 +33,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(1)] - // RedirectProgramPath() + // RedirectProgramPath(u64 titleId) public ResultCode RedirectProgramPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); RedirectPath(context, titleId, 0, NcaContentType.Program); @@ -44,10 +44,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(2)] - // ResolveApplicationControlPath() + // ResolveApplicationControlPath(u64 titleId) public ResultCode ResolveApplicationControlPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); if (ResolvePath(context, titleId, NcaContentType.Control)) { @@ -60,10 +60,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(3)] - // ResolveApplicationHtmlDocumentPath() + // ResolveApplicationHtmlDocumentPath(u64 titleId) public ResultCode ResolveApplicationHtmlDocumentPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); if (ResolvePath(context, titleId, NcaContentType.Manual)) { @@ -76,10 +76,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(4)] - // ResolveDataPath() + // ResolveDataPath(u64 titleId) public ResultCode ResolveDataPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); if (ResolvePath(context, titleId, NcaContentType.Data) || ResolvePath(context, titleId, NcaContentType.PublicData)) { @@ -92,10 +92,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(5)] - // RedirectApplicationControlPath() + // RedirectApplicationControlPath(u64 titleId) public ResultCode RedirectApplicationControlPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); RedirectPath(context, titleId, 1, NcaContentType.Control); @@ -103,10 +103,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(6)] - // RedirectApplicationHtmlDocumentPath() + // RedirectApplicationHtmlDocumentPath(u64 titleId) public ResultCode RedirectApplicationHtmlDocumentPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); RedirectPath(context, titleId, 1, NcaContentType.Manual); @@ -114,10 +114,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(7)] - // ResolveApplicationLegalInformationPath() + // ResolveApplicationLegalInformationPath(u64 titleId) public ResultCode ResolveApplicationLegalInformationPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); if (ResolvePath(context, titleId, NcaContentType.Manual)) { @@ -130,10 +130,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(8)] - // RedirectApplicationLegalInformationPath() + // RedirectApplicationLegalInformationPath(u64 titleId) public ResultCode RedirectApplicationLegalInformationPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); RedirectPath(context, titleId, 1, NcaContentType.Manual); @@ -150,10 +150,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(10)] - // SetProgramNcaPath2() + // SetProgramNcaPath2(u64 titleId) public ResultCode SetProgramNcaPath2(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); RedirectPath(context, titleId, 1, NcaContentType.Program); @@ -170,10 +170,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(12)] - // DeleteProgramNcaPath() + // DeleteProgramNcaPath(u64 titleId) public ResultCode DeleteProgramNcaPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); DeleteContentPath(context, titleId, NcaContentType.Program); @@ -181,10 +181,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(13)] - // DeleteControlNcaPath() + // DeleteControlNcaPath(u64 titleId) public ResultCode DeleteControlNcaPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); DeleteContentPath(context, titleId, NcaContentType.Control); @@ -192,10 +192,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(14)] - // DeleteDocHtmlNcaPath() + // DeleteDocHtmlNcaPath(u64 titleId) public ResultCode DeleteDocHtmlNcaPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); DeleteContentPath(context, titleId, NcaContentType.Manual); @@ -203,17 +203,17 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager } [CommandHipc(15)] - // DeleteInfoHtmlNcaPath() + // DeleteInfoHtmlNcaPath(u64 titleId) public ResultCode DeleteInfoHtmlNcaPath(ServiceCtx context) { - long titleId = context.RequestData.ReadInt64(); + ulong titleId = context.RequestData.ReadUInt64(); DeleteContentPath(context, titleId, NcaContentType.Manual); return ResultCode.Success; } - private void RedirectPath(ServiceCtx context, long titleId, int flag, NcaContentType contentType) + private void RedirectPath(ServiceCtx context, ulong titleId, int flag, NcaContentType contentType) { string contentPath = ReadUtf8String(context); LocationEntry newLocation = new LocationEntry(contentPath, flag, titleId, contentType); @@ -221,19 +221,19 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager context.Device.System.ContentManager.RedirectLocation(newLocation, _storageId); } - private bool ResolvePath(ServiceCtx context, long titleId, NcaContentType contentType) + private bool ResolvePath(ServiceCtx context, ulong titleId, NcaContentType contentType) { ContentManager contentManager = context.Device.System.ContentManager; string contentPath = contentManager.GetInstalledContentPath(titleId, _storageId, NcaContentType.Program); if (!string.IsNullOrWhiteSpace(contentPath)) { - long position = context.Request.RecvListBuff[0].Position; - long size = context.Request.RecvListBuff[0].Size; + ulong position = context.Request.RecvListBuff[0].Position; + ulong size = context.Request.RecvListBuff[0].Size; byte[] contentPathBuffer = Encoding.UTF8.GetBytes(contentPath); - context.Memory.Write((ulong)position, contentPathBuffer); + context.Memory.Write(position, contentPathBuffer); } else { @@ -243,7 +243,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager return true; } - private void DeleteContentPath(ServiceCtx context, long titleId, NcaContentType contentType) + private void DeleteContentPath(ServiceCtx context, ulong titleId, NcaContentType contentType) { ContentManager contentManager = context.Device.System.ContentManager; string contentPath = contentManager.GetInstalledContentPath(titleId, _storageId, NcaContentType.Manual); diff --git a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/IUser.cs b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/IUser.cs index dd3990ae..f241c311 100644 --- a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/IUser.cs +++ b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/IUser.cs @@ -37,12 +37,12 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp _appletResourceUserId = context.RequestData.ReadUInt64(); _mcuVersionData = context.RequestData.ReadUInt64(); - long inputPosition = context.Request.SendBuff[0].Position; - long inputSize = context.Request.SendBuff[0].Size; + ulong inputPosition = context.Request.SendBuff[0].Position; + ulong inputSize = context.Request.SendBuff[0].Size; _mcuData = new byte[inputSize]; - context.Memory.Read((ulong)inputPosition, _mcuData); + context.Memory.Read(inputPosition, _mcuData); // TODO: The mcuData buffer seems to contains entries with a size of 0x40 bytes each. Usage of the data needs to be determined. @@ -93,8 +93,8 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp return ResultCode.WrongArgument; } - long outputPosition = context.Request.RecvListBuff[0].Position; - long outputSize = context.Request.RecvListBuff[0].Size; + ulong outputPosition = context.Request.RecvListBuff[0].Position; + ulong outputSize = context.Request.RecvListBuff[0].Size; if (context.Device.System.NfpDevices.Count == 0) { @@ -107,7 +107,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { for (int i = 0; i < context.Device.System.NfpDevices.Count; i++) { - context.Memory.Write((ulong)(outputPosition + (i * sizeof(long))), (uint)context.Device.System.NfpDevices[i].Handle); + context.Memory.Write(outputPosition + ((uint)i * sizeof(long)), (uint)context.Device.System.NfpDevices[i].Handle); } context.ResponseData.Write(context.Device.System.NfpDevices.Count); @@ -159,7 +159,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagFound) { context.Device.System.NfpDevices[i].SignalActivate(); - Thread.Sleep(50); // NOTE: Simulate amiibo scanning delay. + Thread.Sleep(125); // NOTE: Simulate amiibo scanning delay. context.Device.System.NfpDevices[i].SignalDeactivate(); break; @@ -376,8 +376,8 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp return ResultCode.DeviceNotFound; } - long outputPosition = context.Request.ReceiveBuff[0].Position; - long outputSize = context.Request.ReceiveBuff[0].Size; + ulong outputPosition = context.Request.ReceiveBuff[0].Position; + ulong outputSize = context.Request.ReceiveBuff[0].Size; MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize); @@ -397,7 +397,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { byte[] applicationArea = VirtualAmiibo.GetApplicationArea(context.Device.System.NfpDevices[i].AmiiboId); - context.Memory.Write((ulong)outputPosition, applicationArea); + context.Memory.Write(outputPosition, applicationArea); size = (uint)applicationArea.Length; @@ -444,12 +444,12 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp return ResultCode.DeviceNotFound; } - long inputPosition = context.Request.SendBuff[0].Position; - long inputSize = context.Request.SendBuff[0].Size; + ulong inputPosition = context.Request.SendBuff[0].Position; + ulong inputSize = context.Request.SendBuff[0].Size; byte[] applicationArea = new byte[inputSize]; - context.Memory.Read((ulong)inputPosition, applicationArea); + context.Memory.Read(inputPosition, applicationArea); for (int i = 0; i < context.Device.System.NfpDevices.Count; i++) { @@ -523,12 +523,12 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp uint applicationAreaId = context.RequestData.ReadUInt32(); - long inputPosition = context.Request.SendBuff[0].Position; - long inputSize = context.Request.SendBuff[0].Size; + ulong inputPosition = context.Request.SendBuff[0].Position; + ulong inputSize = context.Request.SendBuff[0].Size; byte[] applicationArea = new byte[inputSize]; - context.Memory.Read((ulong)inputPosition, applicationArea); + context.Memory.Read(inputPosition, applicationArea); bool isCreated = false; @@ -582,9 +582,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp return ResultCode.WrongArgument; } - long outputPosition = context.Request.RecvListBuff[0].Position; + ulong outputPosition = context.Request.RecvListBuff[0].Position; - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(Marshal.SizeOf(typeof(TagInfo))); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf(typeof(TagInfo))); MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf(typeof(TagInfo))); @@ -625,7 +625,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp Uuid.CopyTo(tagInfo.Uuid.ToSpan()); - context.Memory.Write((ulong)outputPosition, tagInfo); + context.Memory.Write(outputPosition, tagInfo); resultCode = ResultCode.Success; } @@ -658,9 +658,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp return ResultCode.WrongArgument; } - long outputPosition = context.Request.RecvListBuff[0].Position; + ulong outputPosition = context.Request.RecvListBuff[0].Position; - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(Marshal.SizeOf(typeof(RegisterInfo))); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf(typeof(RegisterInfo))); MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf(typeof(RegisterInfo))); @@ -685,7 +685,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { RegisterInfo registerInfo = VirtualAmiibo.GetRegisterInfo(context.Device.System.NfpDevices[i].AmiiboId); - context.Memory.Write((ulong)outputPosition, registerInfo); + context.Memory.Write(outputPosition, registerInfo); resultCode = ResultCode.Success; } @@ -718,9 +718,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp return ResultCode.WrongArgument; } - long outputPosition = context.Request.RecvListBuff[0].Position; + ulong outputPosition = context.Request.RecvListBuff[0].Position; - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(Marshal.SizeOf(typeof(CommonInfo))); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf(typeof(CommonInfo))); MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf(typeof(CommonInfo))); @@ -745,7 +745,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { CommonInfo commonInfo = VirtualAmiibo.GetCommonInfo(context.Device.System.NfpDevices[i].AmiiboId); - context.Memory.Write((ulong)outputPosition, commonInfo); + context.Memory.Write(outputPosition, commonInfo); resultCode = ResultCode.Success; } @@ -778,9 +778,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp return ResultCode.WrongArgument; } - long outputPosition = context.Request.RecvListBuff[0].Position; + ulong outputPosition = context.Request.RecvListBuff[0].Position; - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(Marshal.SizeOf(typeof(ModelInfo))); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf(typeof(ModelInfo))); MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf(typeof(ModelInfo))); @@ -814,7 +814,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp modelInfo.ModelNumber = ushort.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(8, 4), NumberStyles.HexNumber); modelInfo.Type = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(6, 2), NumberStyles.HexNumber); - context.Memory.Write((ulong)outputPosition, modelInfo); + context.Memory.Write(outputPosition, modelInfo); resultCode = ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Ngct/NgctServer.cs b/Ryujinx.HLE/HOS/Services/Ngct/NgctServer.cs index a1907d4f..8d99721e 100644 --- a/Ryujinx.HLE/HOS/Services/Ngct/NgctServer.cs +++ b/Ryujinx.HLE/HOS/Services/Ngct/NgctServer.cs @@ -11,8 +11,8 @@ namespace Ryujinx.HLE.HOS.Services.Ngct // Then it checks if ngc.t!functionality_override_enabled is enabled and if sys:set GetT is == 2. // If both conditions are true, it does this following code. Since we currently stub it, it's fine to don't check settings service values. - long bufferPosition = context.Request.PtrBuff[0].Position; - long bufferSize = context.Request.PtrBuff[0].Size; + ulong bufferPosition = context.Request.PtrBuff[0].Position; + ulong bufferSize = context.Request.PtrBuff[0].Size; bool isMatch = false; string text = ""; @@ -27,7 +27,7 @@ namespace Ryujinx.HLE.HOS.Services.Ngct { byte[] buffer = new byte[bufferSize]; - context.Memory.Read((ulong)bufferPosition, buffer); + context.Memory.Read(bufferPosition, buffer); text = Encoding.ASCII.GetString(buffer); @@ -52,10 +52,10 @@ namespace Ryujinx.HLE.HOS.Services.Ngct // Then it checks if ngc.t!functionality_override_enabled is enabled and if sys:set GetT is == 2. // If both conditions are true, it does this following code. Since we currently stub it, it's fine to don't check settings service values. - long bufferPosition = context.Request.PtrBuff[0].Position; - long bufferSize = context.Request.PtrBuff[0].Size; + ulong bufferPosition = context.Request.PtrBuff[0].Position; + ulong bufferSize = context.Request.PtrBuff[0].Size; - long bufferFilteredPosition = context.Request.RecvListBuff[0].Position; + ulong bufferFilteredPosition = context.Request.RecvListBuff[0].Position; string text = ""; string textFiltered = ""; @@ -66,13 +66,13 @@ namespace Ryujinx.HLE.HOS.Services.Ngct { textFiltered = new string('*', text.Length); - context.Memory.Write((ulong)bufferFilteredPosition, Encoding.ASCII.GetBytes(textFiltered)); + context.Memory.Write(bufferFilteredPosition, Encoding.ASCII.GetBytes(textFiltered)); } else { byte[] buffer = new byte[bufferSize]; - context.Memory.Read((ulong)bufferPosition, buffer); + context.Memory.Read(bufferPosition, buffer); // NOTE: Ngct use the archive 0100000000001034 which contains a words table. This is pushed on Chinese Switchs using Bcat service. // This call check if the string contains words which are in the table then returns the same string with each matched words replaced by '*'. @@ -80,7 +80,7 @@ namespace Ryujinx.HLE.HOS.Services.Ngct textFiltered = text = Encoding.ASCII.GetString(buffer); - context.Memory.Write((ulong)bufferFilteredPosition, buffer); + context.Memory.Write(bufferFilteredPosition, buffer); } } diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs index 5f1f9b3a..e650879b 100644 --- a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs @@ -29,11 +29,11 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService // GetClientId() -> buffer<nn::nifm::ClientId, 0x1a, 4> public ResultCode GetClientId(ServiceCtx context) { - long position = context.Request.RecvListBuff[0].Position; + ulong position = context.Request.RecvListBuff[0].Position; - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(4); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(sizeof(int)); - context.Memory.Write((ulong)position, _generalServiceDetail.ClientId); + context.Memory.Write(position, _generalServiceDetail.ClientId); return ResultCode.Success; } @@ -58,7 +58,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService // GetCurrentNetworkProfile() -> buffer<nn::nifm::detail::sf::NetworkProfileData, 0x1a, 0x17c> public ResultCode GetCurrentNetworkProfile(ServiceCtx context) { - long networkProfileDataPosition = context.Request.RecvListBuff[0].Position; + ulong networkProfileDataPosition = context.Request.RecvListBuff[0].Position; (IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastAddress) = GetLocalInterface(); @@ -69,7 +69,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService Logger.Info?.Print(LogClass.ServiceNifm, $"Console's local IP is \"{unicastAddress.Address}\"."); - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(Unsafe.SizeOf<NetworkProfileData>()); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Unsafe.SizeOf<NetworkProfileData>()); NetworkProfileData networkProfile = new NetworkProfileData { @@ -81,7 +81,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService Encoding.ASCII.GetBytes("RyujinxNetwork").CopyTo(networkProfile.Name.ToSpan()); - context.Memory.Write((ulong)networkProfileDataPosition, networkProfile); + context.Memory.Write(networkProfileDataPosition, networkProfile); return ResultCode.Success; } @@ -148,10 +148,10 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService // IsAnyInternetRequestAccepted(buffer<nn::nifm::ClientId, 0x19, 4>) -> bool public ResultCode IsAnyInternetRequestAccepted(ServiceCtx context) { - long position = context.Request.PtrBuff[0].Position; - long size = context.Request.PtrBuff[0].Size; + ulong position = context.Request.PtrBuff[0].Position; + ulong size = context.Request.PtrBuff[0].Size; - int clientId = context.Memory.Read<int>((ulong)position); + int clientId = context.Memory.Read<int>(position); context.ResponseData.Write(GeneralServiceManager.Get(clientId).IsAnyInternetRequestAccepted); diff --git a/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs b/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs index ab10928f..d3a89178 100644 --- a/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs +++ b/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs @@ -12,11 +12,11 @@ byte source = (byte)context.RequestData.ReadInt64(); ulong titleId = context.RequestData.ReadUInt64(); - long position = context.Request.ReceiveBuff[0].Position; + ulong position = context.Request.ReceiveBuff[0].Position; byte[] nacpData = context.Device.Application.ControlData.ByteSpan.ToArray(); - context.Memory.Write((ulong)position, nacpData); + context.Memory.Write(position, nacpData); return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Ns/IPurchaseEventManager.cs b/Ryujinx.HLE/HOS/Services/Ns/IPurchaseEventManager.cs index 2ea3ee11..7ee74370 100644 --- a/Ryujinx.HLE/HOS/Services/Ns/IPurchaseEventManager.cs +++ b/Ryujinx.HLE/HOS/Services/Ns/IPurchaseEventManager.cs @@ -20,11 +20,11 @@ namespace Ryujinx.HLE.HOS.Services.Ns // SetDefaultDeliveryTarget(pid, buffer<bytes, 5> unknown) public ResultCode SetDefaultDeliveryTarget(ServiceCtx context) { - long inBufferPosition = context.Request.SendBuff[0].Position; - long inBufferSize = context.Request.SendBuff[0].Size; + ulong inBufferPosition = context.Request.SendBuff[0].Position; + ulong inBufferSize = context.Request.SendBuff[0].Size; byte[] buffer = new byte[inBufferSize]; - context.Memory.Read((ulong)inBufferPosition, buffer); + context.Memory.Read(inBufferPosition, buffer); // NOTE: Service use the pid to call arp:r GetApplicationLaunchProperty and store it in internal field. // Then it seems to use the buffer content and compare it with a stored linked instrusive list. diff --git a/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs b/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs index ff57beb0..3b6965d0 100644 --- a/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs +++ b/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs @@ -11,11 +11,11 @@ byte source = (byte)context.RequestData.ReadInt64(); ulong titleId = context.RequestData.ReadUInt64(); - long position = context.Request.ReceiveBuff[0].Position; + ulong position = context.Request.ReceiveBuff[0].Position; byte[] nacpData = context.Device.Application.ControlData.ByteSpan.ToArray(); - context.Memory.Write((ulong)position, nacpData); + context.Memory.Write(position, nacpData); return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs index 35bb4e6f..25279af3 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs @@ -73,8 +73,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv private NvResult GetIoctlArgument(ServiceCtx context, NvIoctl ioctlCommand, out Span<byte> arguments) { - (long inputDataPosition, long inputDataSize) = context.Request.GetBufferType0x21(0); - (long outputDataPosition, long outputDataSize) = context.Request.GetBufferType0x22(0); + (ulong inputDataPosition, ulong inputDataSize) = context.Request.GetBufferType0x21(0); + (ulong outputDataPosition, ulong outputDataSize) = context.Request.GetBufferType0x22(0); NvIoctl.Direction ioctlDirection = ioctlCommand.DirectionValue; uint ioctlSize = ioctlCommand.Size; @@ -106,7 +106,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv byte[] temp = new byte[inputDataSize]; - context.Memory.Read((ulong)inputDataPosition, temp); + context.Memory.Read(inputDataPosition, temp); Buffer.BlockCopy(temp, 0, outputData, 0, temp.Length); @@ -122,7 +122,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv { byte[] temp = new byte[inputDataSize]; - context.Memory.Read((ulong)inputDataPosition, temp); + context.Memory.Read(inputDataPosition, temp); arguments = new Span<byte>(temp); } @@ -226,10 +226,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv if (errorCode == NvResult.Success) { - long pathPtr = context.Request.SendBuff[0].Position; - long pathSize = context.Request.SendBuff[0].Size; + ulong pathPtr = context.Request.SendBuff[0].Position; + ulong pathSize = context.Request.SendBuff[0].Size; - string path = MemoryHelper.ReadAsciiString(context.Memory, pathPtr, pathSize); + string path = MemoryHelper.ReadAsciiString(context.Memory, pathPtr, (long)pathSize); fd = Open(context, path); @@ -275,7 +275,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv if ((ioctlCommand.DirectionValue & NvIoctl.Direction.Write) != 0) { - context.Memory.Write((ulong)context.Request.GetBufferType0x22(0).Position, arguments.ToArray()); + context.Memory.Write(context.Request.GetBufferType0x22(0).Position, arguments.ToArray()); } } } @@ -470,13 +470,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv int fd = context.RequestData.ReadInt32(); NvIoctl ioctlCommand = context.RequestData.ReadStruct<NvIoctl>(); - (long inlineInBufferPosition, long inlineInBufferSize) = context.Request.GetBufferType0x21(1); + (ulong inlineInBufferPosition, ulong inlineInBufferSize) = context.Request.GetBufferType0x21(1); errorCode = GetIoctlArgument(context, ioctlCommand, out Span<byte> arguments); byte[] temp = new byte[inlineInBufferSize]; - context.Memory.Read((ulong)inlineInBufferPosition, temp); + context.Memory.Read(inlineInBufferPosition, temp); Span<byte> inlineInBuffer = new Span<byte>(temp); @@ -497,7 +497,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv if ((ioctlCommand.DirectionValue & NvIoctl.Direction.Write) != 0) { - context.Memory.Write((ulong)context.Request.GetBufferType0x22(0).Position, arguments.ToArray()); + context.Memory.Write(context.Request.GetBufferType0x22(0).Position, arguments.ToArray()); } } } @@ -519,13 +519,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv int fd = context.RequestData.ReadInt32(); NvIoctl ioctlCommand = context.RequestData.ReadStruct<NvIoctl>(); - (long inlineOutBufferPosition, long inlineOutBufferSize) = context.Request.GetBufferType0x22(1); + (ulong inlineOutBufferPosition, ulong inlineOutBufferSize) = context.Request.GetBufferType0x22(1); errorCode = GetIoctlArgument(context, ioctlCommand, out Span<byte> arguments); byte[] temp = new byte[inlineOutBufferSize]; - context.Memory.Read((ulong)inlineOutBufferPosition, temp); + context.Memory.Read(inlineOutBufferPosition, temp); Span<byte> inlineOutBuffer = new Span<byte>(temp); @@ -546,8 +546,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv if ((ioctlCommand.DirectionValue & NvIoctl.Direction.Write) != 0) { - context.Memory.Write((ulong)context.Request.GetBufferType0x22(0).Position, arguments.ToArray()); - context.Memory.Write((ulong)inlineOutBufferPosition, inlineOutBuffer.ToArray()); + context.Memory.Write(context.Request.GetBufferType0x22(0).Position, arguments.ToArray()); + context.Memory.Write(inlineOutBufferPosition, inlineOutBuffer.ToArray()); } } } diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs b/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs index 1f24ab7d..44746db6 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs @@ -1,6 +1,5 @@ using Ryujinx.Common.Collections; using System.Collections.Generic; -using Ryujinx.Common; using System; using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Common.Logging; @@ -198,7 +197,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices { bool reachedEndOfAddresses = false; ulong targetAddress; - if(start == DefaultStart) + if (start == DefaultStart) { Logger.Debug?.Print(LogClass.ServiceNv, $"Target address set to start of the last available range: 0x{_list.Last.Value:X}."); targetAddress = _list.Last.Value; @@ -301,7 +300,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices freeAddressStartPosition = floorAddress; if (floorAddress != InvalidAddress) { - return !(gpuVa >= floorAddress && ((gpuVa + size) < _tree.Get(floorAddress))); + return !(gpuVa >= floorAddress && ((gpuVa + size) <= _tree.Get(floorAddress))); } } return true; diff --git a/Ryujinx.HLE/HOS/Services/Prepo/IPrepoService.cs b/Ryujinx.HLE/HOS/Services/Prepo/IPrepoService.cs index 8313a690..4f36d401 100644 --- a/Ryujinx.HLE/HOS/Services/Prepo/IPrepoService.cs +++ b/Ryujinx.HLE/HOS/Services/Prepo/IPrepoService.cs @@ -117,8 +117,8 @@ namespace Ryujinx.HLE.HOS.Services.Prepo return ResultCode.InvalidState; } - long inputPosition = context.Request.SendBuff[0].Position; - long inputSize = context.Request.SendBuff[0].Size; + ulong inputPosition = context.Request.SendBuff[0].Position; + ulong inputSize = context.Request.SendBuff[0].Size; if (inputSize == 0) { @@ -127,7 +127,7 @@ namespace Ryujinx.HLE.HOS.Services.Prepo byte[] inputBuffer = new byte[inputSize]; - context.Memory.Read((ulong)inputPosition, inputBuffer); + context.Memory.Read(inputPosition, inputBuffer); Logger.Info?.Print(LogClass.ServicePrepo, ReadReportBuffer(inputBuffer, gameRoom, userId)); diff --git a/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs b/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs index c8277699..8070cf54 100644 --- a/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs +++ b/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs @@ -40,7 +40,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro _owner = null; } - private ResultCode ParseNrr(out NrrInfo nrrInfo, ServiceCtx context, long nrrAddress, long nrrSize) + private ResultCode ParseNrr(out NrrInfo nrrInfo, ServiceCtx context, ulong nrrAddress, ulong nrrSize) { nrrInfo = null; @@ -71,12 +71,12 @@ namespace Ryujinx.HLE.HOS.Services.Ro { byte[] temp = new byte[0x20]; - _owner.CpuMemory.Read((ulong)(nrrAddress + header.HashOffset + (i * 0x20)), temp); + _owner.CpuMemory.Read(nrrAddress + header.HashOffset + (uint)(i * 0x20), temp); hashes.Add(temp); } - nrrInfo = new NrrInfo(nrrAddress, header, hashes); + nrrInfo = new NrrInfo((ulong)nrrAddress, header, hashes); return ResultCode.Success; } @@ -333,7 +333,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro process.CpuMemory.Write(roStart, relocatableObject.Ro); process.CpuMemory.Write(dataStart, relocatableObject.Data); - MemoryHelper.FillWithZeros(process.CpuMemory, (long)bssStart, (int)(bssEnd - bssStart)); + MemoryHelper.FillWithZeros(process.CpuMemory, bssStart, (int)(bssEnd - bssStart)); KernelResult result; @@ -354,7 +354,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro return process.MemoryManager.SetProcessMemoryPermission(dataStart, bssEnd - dataStart, KMemoryPermission.ReadAndWrite); } - private ResultCode RemoveNrrInfo(long nrrAddress) + private ResultCode RemoveNrrInfo(ulong nrrAddress) { foreach (NrrInfo info in _nrrInfos) { @@ -508,8 +508,8 @@ namespace Ryujinx.HLE.HOS.Services.Ro // pid placeholder, zero context.RequestData.ReadUInt64(); - long nrrAddress = context.RequestData.ReadInt64(); - long nrrSize = context.RequestData.ReadInt64(); + ulong nrrAddress = context.RequestData.ReadUInt64(); + ulong nrrSize = context.RequestData.ReadUInt64(); if (result == ResultCode.Success) { @@ -541,7 +541,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro // pid placeholder, zero context.RequestData.ReadUInt64(); - long nrrHeapAddress = context.RequestData.ReadInt64(); + ulong nrrHeapAddress = context.RequestData.ReadUInt64(); if (result == ResultCode.Success) { diff --git a/Ryujinx.HLE/HOS/Services/Ro/Types/NrrInfo.cs b/Ryujinx.HLE/HOS/Services/Ro/Types/NrrInfo.cs index 8e038fcb..45c34f1c 100644 --- a/Ryujinx.HLE/HOS/Services/Ro/Types/NrrInfo.cs +++ b/Ryujinx.HLE/HOS/Services/Ro/Types/NrrInfo.cs @@ -6,9 +6,9 @@ namespace Ryujinx.HLE.HOS.Services.Ro { public NrrHeader Header { get; private set; } public List<byte[]> Hashes { get; private set; } - public long NrrAddress { get; private set; } + public ulong NrrAddress { get; private set; } - public NrrInfo(long nrrAddress, NrrHeader header, List<byte[]> hashes) + public NrrInfo(ulong nrrAddress, NrrHeader header, List<byte[]> hashes) { NrrAddress = nrrAddress; Header = header; diff --git a/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs b/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs index aaaf26e4..3449e108 100644 --- a/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs @@ -15,11 +15,11 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService internal static ResultCode GetPlayStatistics(ServiceCtx context, bool byUserId = false) { - long inputPosition = context.Request.SendBuff[0].Position; - long inputSize = context.Request.SendBuff[0].Size; + ulong inputPosition = context.Request.SendBuff[0].Position; + ulong inputSize = context.Request.SendBuff[0].Size; - long outputPosition = context.Request.ReceiveBuff[0].Position; - long outputSize = context.Request.ReceiveBuff[0].Size; + ulong outputPosition = context.Request.ReceiveBuff[0].Position; + ulong outputSize = context.Request.ReceiveBuff[0].Size; UserId userId = byUserId ? context.RequestData.ReadStruct<UserId>() : new UserId(); @@ -35,9 +35,9 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService List<ulong> titleIds = new List<ulong>(); - for (int i = 0; i < inputSize / sizeof(ulong); i++) + for (ulong i = 0; i < inputSize / sizeof(ulong); i++) { - titleIds.Add(context.Memory.Read<ulong>((ulong)inputPosition)); + titleIds.Add(context.Memory.Read<ulong>(inputPosition)); } if (queryCapability == PlayLogQueryCapability.WhiteList) @@ -73,7 +73,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService for (int i = 0; i < filteredApplicationPlayStatistics.Count(); i++) { - MemoryHelper.Write(context.Memory, outputPosition + (i * Marshal.SizeOf<ApplicationPlayStatistics>()), filteredApplicationPlayStatistics.ElementAt(i).Value); + MemoryHelper.Write(context.Memory, outputPosition + (ulong)(i * Marshal.SizeOf<ApplicationPlayStatistics>()), filteredApplicationPlayStatistics.ElementAt(i).Value); } context.ResponseData.Write(filteredApplicationPlayStatistics.Count()); diff --git a/Ryujinx.HLE/HOS/Services/Sdb/Pl/ISharedFontManager.cs b/Ryujinx.HLE/HOS/Services/Sdb/Pl/ISharedFontManager.cs index 1a4bc5bd..d7397f7d 100644 --- a/Ryujinx.HLE/HOS/Services/Sdb/Pl/ISharedFontManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sdb/Pl/ISharedFontManager.cs @@ -87,7 +87,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl for (SharedFontType type = 0; type < SharedFontType.Count; type++) { - int offset = (int)type * 4; + uint offset = (uint)type * 4; if (!AddFontToOrderOfPriorityList(context, type, offset)) { @@ -103,27 +103,27 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl return ResultCode.Success; } - private bool AddFontToOrderOfPriorityList(ServiceCtx context, SharedFontType fontType, int offset) + private bool AddFontToOrderOfPriorityList(ServiceCtx context, SharedFontType fontType, uint offset) { - long typesPosition = context.Request.ReceiveBuff[0].Position; - long typesSize = context.Request.ReceiveBuff[0].Size; + ulong typesPosition = context.Request.ReceiveBuff[0].Position; + ulong typesSize = context.Request.ReceiveBuff[0].Size; - long offsetsPosition = context.Request.ReceiveBuff[1].Position; - long offsetsSize = context.Request.ReceiveBuff[1].Size; + ulong offsetsPosition = context.Request.ReceiveBuff[1].Position; + ulong offsetsSize = context.Request.ReceiveBuff[1].Size; - long fontSizeBufferPosition = context.Request.ReceiveBuff[2].Position; - long fontSizeBufferSize = context.Request.ReceiveBuff[2].Size; + ulong fontSizeBufferPosition = context.Request.ReceiveBuff[2].Position; + ulong fontSizeBufferSize = context.Request.ReceiveBuff[2].Size; - if ((uint)offset + 4 > (uint)typesSize || - (uint)offset + 4 > (uint)offsetsSize || - (uint)offset + 4 > (uint)fontSizeBufferSize) + if (offset + 4 > (uint)typesSize || + offset + 4 > (uint)offsetsSize || + offset + 4 > (uint)fontSizeBufferSize) { return false; } - context.Memory.Write((ulong)(typesPosition + offset), (int)fontType); - context.Memory.Write((ulong)(offsetsPosition + offset), context.Device.System.Font.GetSharedMemoryAddressOffset(fontType)); - context.Memory.Write((ulong)(fontSizeBufferPosition + offset), context.Device.System.Font.GetFontSize(fontType)); + context.Memory.Write(typesPosition + offset, (int)fontType); + context.Memory.Write(offsetsPosition + offset, context.Device.System.Font.GetSharedMemoryAddressOffset(fontType)); + context.Memory.Write(fontSizeBufferPosition + offset, context.Device.System.Font.GetFontSize(fontType)); return true; } diff --git a/Ryujinx.HLE/HOS/Services/ServerBase.cs b/Ryujinx.HLE/HOS/Services/ServerBase.cs index bf638800..c9d009a9 100644 --- a/Ryujinx.HLE/HOS/Services/ServerBase.cs +++ b/Ryujinx.HLE/HOS/Services/ServerBase.cs @@ -35,16 +35,17 @@ namespace Ryujinx.HLE.HOS.Services private readonly List<int> _sessionHandles = new List<int>(); private readonly List<int> _portHandles = new List<int>(); private readonly Dictionary<int, IpcService> _sessions = new Dictionary<int, IpcService>(); - private readonly Dictionary<int, IpcService> _ports = new Dictionary<int, IpcService>(); + private readonly Dictionary<int, Func<IpcService>> _ports = new Dictionary<int, Func<IpcService>>(); public ManualResetEvent InitDone { get; } - public IpcService SmObject { get; set; } + public Func<IpcService> SmObjectFactory { get; } public string Name { get; } - public ServerBase(KernelContext context, string name) + public ServerBase(KernelContext context, string name, Func<IpcService> smObjectFactory = null) { InitDone = new ManualResetEvent(false); Name = name; + SmObjectFactory = smObjectFactory; _context = context; const ProcessCreationFlags flags = @@ -58,10 +59,10 @@ namespace Ryujinx.HLE.HOS.Services KernelStatic.StartInitialProcess(context, creationInfo, DefaultCapabilities, 44, ServerLoop); } - private void AddPort(int serverPortHandle, IpcService obj) + private void AddPort(int serverPortHandle, Func<IpcService> objectFactory) { _portHandles.Add(serverPortHandle); - _ports.Add(serverPortHandle, obj); + _ports.Add(serverPortHandle, objectFactory); } public void AddSessionObj(KServerSession serverSession, IpcService obj) @@ -80,11 +81,11 @@ namespace Ryujinx.HLE.HOS.Services { _selfProcess = KernelStatic.GetCurrentProcess(); - if (SmObject != null) + if (SmObjectFactory != null) { _context.Syscall.ManageNamedPort("sm:", 50, out int serverPortHandle); - AddPort(serverPortHandle, SmObject); + AddPort(serverPortHandle, SmObjectFactory); InitDone.Set(); } @@ -141,7 +142,9 @@ namespace Ryujinx.HLE.HOS.Services // We got a new connection, accept the session to allow servicing future requests. if (_context.Syscall.AcceptSession(handles[signaledIndex], out int serverSessionHandle) == KernelResult.Success) { - AddSessionObj(serverSessionHandle, _ports[handles[signaledIndex]]); + IpcService obj = _ports[handles[signaledIndex]].Invoke(); + + AddSessionObj(serverSessionHandle, obj); } } @@ -180,17 +183,18 @@ namespace Ryujinx.HLE.HOS.Services { for (int i = 0; i < request.RecvListBuff.Count; i++) { - int size = BinaryPrimitives.ReadInt16LittleEndian(request.RawData.AsSpan().Slice(sizesOffset + i * 2, 2)); + ulong size = (ulong)BinaryPrimitives.ReadInt16LittleEndian(request.RawData.AsSpan().Slice(sizesOffset + i * 2, 2)); - response.PtrBuff.Add(new IpcPtrBuffDesc((long)tempAddr, i, size)); + response.PtrBuff.Add(new IpcPtrBuffDesc(tempAddr, (uint)i, size)); - request.RecvListBuff[i] = new IpcRecvListBuffDesc((long)tempAddr, size); + request.RecvListBuff[i] = new IpcRecvListBuffDesc(tempAddr, size); - tempAddr += (ulong)size; + tempAddr += size; } } bool shouldReply = true; + bool isTipcCommunication = false; using (MemoryStream raw = new MemoryStream(request.RawData)) { @@ -269,6 +273,8 @@ namespace Ryujinx.HLE.HOS.Services // If the type is past 0xF, we are using TIPC else if (request.Type > IpcMessageType.TipcCloseSession) { + isTipcCommunication = true; + // Response type is always the same as request on TIPC. response.Type = request.Type; @@ -290,13 +296,19 @@ namespace Ryujinx.HLE.HOS.Services response.RawData = resMs.ToArray(); } + + process.CpuMemory.Write(messagePtr, response.GetBytesTipc()); } else { throw new NotImplementedException(request.Type.ToString()); } - process.CpuMemory.Write(messagePtr, response.GetBytes((long)messagePtr, recvListAddr | ((ulong)PointerBufferSize << 48))); + if (!isTipcCommunication) + { + process.CpuMemory.Write(messagePtr, response.GetBytes((long)messagePtr, recvListAddr | ((ulong)PointerBufferSize << 48))); + } + return shouldReply; } } diff --git a/Ryujinx.HLE/HOS/Services/ServiceConfiguration.cs b/Ryujinx.HLE/HOS/Services/ServiceConfiguration.cs deleted file mode 100644 index d73c76d9..00000000 --- a/Ryujinx.HLE/HOS/Services/ServiceConfiguration.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services -{ - public static class ServiceConfiguration - { - public static bool IgnoreMissingServices { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs b/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs index 2932ee22..6f106789 100644 --- a/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs +++ b/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs @@ -190,17 +190,17 @@ namespace Ryujinx.HLE.HOS.Services.Settings break; } - context.Memory.Write((ulong)context.Request.ReceiveBuff[0].Position, keyCodeMap); + context.Memory.Write(context.Request.ReceiveBuff[0].Position, keyCodeMap); if (version == 1 && context.Device.System.State.DesiredKeyboardLayout == (long)KeyboardLayout.Default) { - context.Memory.Write((ulong)context.Request.ReceiveBuff[0].Position, (byte)0x01); + context.Memory.Write(context.Request.ReceiveBuff[0].Position, (byte)0x01); } return ResultCode.Success; } - public ResultCode GetAvailableLanguagesCodesImpl(ServiceCtx context, long position, long size, int maxSize) + public ResultCode GetAvailableLanguagesCodesImpl(ServiceCtx context, ulong position, ulong size, int maxSize) { int count = (int)(size / 8); @@ -211,7 +211,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings for (int index = 0; index < count; index++) { - context.Memory.Write((ulong)position, SystemStateMgr.GetLanguageCode(index)); + context.Memory.Write(position, SystemStateMgr.GetLanguageCode(index)); position += 8; } diff --git a/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs b/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs index 6bd6866d..54076b4b 100644 --- a/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs +++ b/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs @@ -29,7 +29,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings // GetFirmwareVersion2() -> buffer<nn::settings::system::FirmwareVersion, 0x1a, 0x100> public ResultCode GetFirmwareVersion2(ServiceCtx context) { - long replyPos = context.Request.RecvListBuff[0].Position; + ulong replyPos = context.Request.RecvListBuff[0].Position; context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(0x100L); @@ -37,7 +37,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings if (firmwareData != null) { - context.Memory.Write((ulong)replyPos, firmwareData); + context.Memory.Write(replyPos, firmwareData); return ResultCode.Success; } @@ -80,7 +80,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings writer.Write(Encoding.ASCII.GetBytes(build)); - context.Memory.Write((ulong)replyPos, ms.ToArray()); + context.Memory.Write(replyPos, ms.ToArray()); } return ResultCode.Success; @@ -110,19 +110,19 @@ namespace Ryujinx.HLE.HOS.Services.Settings // GetSettingsItemValueSize(buffer<nn::settings::SettingsName, 0x19>, buffer<nn::settings::SettingsItemKey, 0x19>) -> u64 public ResultCode GetSettingsItemValueSize(ServiceCtx context) { - long classPos = context.Request.PtrBuff[0].Position; - long classSize = context.Request.PtrBuff[0].Size; + ulong classPos = context.Request.PtrBuff[0].Position; + ulong classSize = context.Request.PtrBuff[0].Size; - long namePos = context.Request.PtrBuff[1].Position; - long nameSize = context.Request.PtrBuff[1].Size; + ulong namePos = context.Request.PtrBuff[1].Position; + ulong nameSize = context.Request.PtrBuff[1].Size; byte[] classBuffer = new byte[classSize]; - context.Memory.Read((ulong)classPos, classBuffer); + context.Memory.Read(classPos, classBuffer); byte[] nameBuffer = new byte[nameSize]; - context.Memory.Read((ulong)namePos, nameBuffer); + context.Memory.Read(namePos, nameBuffer); string askedSetting = Encoding.ASCII.GetString(classBuffer).Trim('\0') + "!" + Encoding.ASCII.GetString(nameBuffer).Trim('\0'); @@ -159,22 +159,22 @@ namespace Ryujinx.HLE.HOS.Services.Settings // GetSettingsItemValue(buffer<nn::settings::SettingsName, 0x19, 0x48>, buffer<nn::settings::SettingsItemKey, 0x19, 0x48>) -> (u64, buffer<unknown, 6, 0>) public ResultCode GetSettingsItemValue(ServiceCtx context) { - long classPos = context.Request.PtrBuff[0].Position; - long classSize = context.Request.PtrBuff[0].Size; + ulong classPos = context.Request.PtrBuff[0].Position; + ulong classSize = context.Request.PtrBuff[0].Size; - long namePos = context.Request.PtrBuff[1].Position; - long nameSize = context.Request.PtrBuff[1].Size; + ulong namePos = context.Request.PtrBuff[1].Position; + ulong nameSize = context.Request.PtrBuff[1].Size; - long replyPos = context.Request.ReceiveBuff[0].Position; - long replySize = context.Request.ReceiveBuff[0].Size; + ulong replyPos = context.Request.ReceiveBuff[0].Position; + ulong replySize = context.Request.ReceiveBuff[0].Size; byte[] classBuffer = new byte[classSize]; - context.Memory.Read((ulong)classPos, classBuffer); + context.Memory.Read(classPos, classBuffer); byte[] nameBuffer = new byte[nameSize]; - context.Memory.Read((ulong)namePos, nameBuffer); + context.Memory.Read(namePos, nameBuffer); string askedSetting = Encoding.ASCII.GetString(classBuffer).Trim('\0') + "!" + Encoding.ASCII.GetString(nameBuffer).Trim('\0'); @@ -186,7 +186,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings if (nxSetting is string stringValue) { - if (stringValue.Length + 1 > replySize) + if ((ulong)(stringValue.Length + 1) > replySize) { Logger.Error?.Print(LogClass.ServiceSet, $"{askedSetting} String value size is too big!"); } @@ -209,7 +209,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings throw new NotImplementedException(nxSetting.GetType().Name); } - context.Memory.Write((ulong)replyPos, settingBuffer); + context.Memory.Write(replyPos, settingBuffer); Logger.Debug?.Print(LogClass.ServiceSet, $"{askedSetting} set value: {nxSetting} as {nxSetting.GetType()}"); } @@ -235,8 +235,9 @@ namespace Ryujinx.HLE.HOS.Services.Settings public byte[] GetFirmwareData(Switch device) { - long titleId = 0x0100000000000809; - string contentPath = device.System.ContentManager.GetInstalledContentPath(titleId, StorageId.NandSystem, NcaContentType.Data); + const ulong SystemVersionTitleId = 0x0100000000000809; + + string contentPath = device.System.ContentManager.GetInstalledContentPath(SystemVersionTitleId, StorageId.NandSystem, NcaContentType.Data); if (string.IsNullOrWhiteSpace(contentPath)) { diff --git a/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs b/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs index d5dabb2d..8b1ec5b8 100644 --- a/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs +++ b/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs @@ -15,9 +15,9 @@ namespace Ryujinx.HLE.HOS.Services.Sm { class IUserInterface : IpcService { - private Dictionary<string, Type> _services; + private static Dictionary<string, Type> _services; - private readonly ConcurrentDictionary<string, KPort> _registeredServices; + private static readonly ConcurrentDictionary<string, KPort> _registeredServices; private readonly ServerBase _commonServer; @@ -25,16 +25,17 @@ namespace Ryujinx.HLE.HOS.Services.Sm public IUserInterface(KernelContext context) { + _commonServer = new ServerBase(context, "CommonServer"); + } + + static IUserInterface() + { _registeredServices = new ConcurrentDictionary<string, KPort>(); _services = Assembly.GetExecutingAssembly().GetTypes() .SelectMany(type => type.GetCustomAttributes(typeof(ServiceAttribute), true) .Select(service => (((ServiceAttribute)service).Name, type))) .ToDictionary(service => service.Name, service => service.type); - - TrySetServer(new ServerBase(context, "SmServer") { SmObject = this }); - - _commonServer = new ServerBase(context, "CommonServer"); } [CommandHipc(0)] @@ -47,9 +48,16 @@ namespace Ryujinx.HLE.HOS.Services.Sm return ResultCode.Success; } - [CommandHipc(1)] [CommandTipc(1)] // 12.0.0+ // GetService(ServiceName name) -> handle<move, session> + public ResultCode GetServiceTipc(ServiceCtx context) + { + context.Response.HandleDesc = IpcHandleDesc.MakeMove(0); + + return GetService(context); + } + + [CommandHipc(1)] public ResultCode GetService(ServiceCtx context) { if (!_isInitialized) @@ -90,7 +98,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm } else { - if (ServiceConfiguration.IgnoreMissingServices) + if (context.Device.Configuration.IgnoreMissingServices) { Logger.Warning?.Print(LogClass.Service, $"Missing service {name} ignored"); } @@ -142,6 +150,8 @@ namespace Ryujinx.HLE.HOS.Services.Sm { if (!_isInitialized) { + context.Response.HandleDesc = IpcHandleDesc.MakeMove(0); + return ResultCode.NotInitialized; } diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs index 1246c31b..63f639cb 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs @@ -197,28 +197,28 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return WriteBsdResult(context, _sockets.Count - 1); } - private IPEndPoint ParseSockAddr(ServiceCtx context, long bufferPosition, long bufferSize) + private IPEndPoint ParseSockAddr(ServiceCtx context, ulong bufferPosition, ulong bufferSize) { - int size = context.Memory.Read<byte>((ulong)bufferPosition); - int family = context.Memory.Read<byte>((ulong)bufferPosition + 1); - int port = BinaryPrimitives.ReverseEndianness(context.Memory.Read<ushort>((ulong)bufferPosition + 2)); + int size = context.Memory.Read<byte>(bufferPosition); + int family = context.Memory.Read<byte>(bufferPosition + 1); + int port = BinaryPrimitives.ReverseEndianness(context.Memory.Read<ushort>(bufferPosition + 2)); byte[] rawIp = new byte[4]; - context.Memory.Read((ulong)bufferPosition + 4, rawIp); + context.Memory.Read(bufferPosition + 4, rawIp); return new IPEndPoint(new IPAddress(rawIp), port); } - private void WriteSockAddr(ServiceCtx context, long bufferPosition, IPEndPoint endPoint) + private void WriteSockAddr(ServiceCtx context, ulong bufferPosition, IPEndPoint endPoint) { - context.Memory.Write((ulong)bufferPosition, (byte)0); - context.Memory.Write((ulong)bufferPosition + 1, (byte)endPoint.AddressFamily); - context.Memory.Write((ulong)bufferPosition + 2, BinaryPrimitives.ReverseEndianness((ushort)endPoint.Port)); - context.Memory.Write((ulong)bufferPosition + 4, endPoint.Address.GetAddressBytes()); + context.Memory.Write(bufferPosition, (byte)0); + context.Memory.Write(bufferPosition + 1, (byte)endPoint.AddressFamily); + context.Memory.Write(bufferPosition + 2, BinaryPrimitives.ReverseEndianness((ushort)endPoint.Port)); + context.Memory.Write(bufferPosition + 4, endPoint.Address.GetAddressBytes()); } - private void WriteSockAddr(ServiceCtx context, long bufferPosition, BsdSocket socket, bool isRemote) + private void WriteSockAddr(ServiceCtx context, ulong bufferPosition, BsdSocket socket, bool isRemote) { IPEndPoint endPoint = (isRemote ? socket.Handle.RemoteEndPoint : socket.Handle.LocalEndPoint) as IPEndPoint; @@ -282,13 +282,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd // Open(u32 flags, array<unknown, 0x21> path) -> (i32 ret, u32 bsd_errno) public ResultCode Open(ServiceCtx context) { - (long bufferPosition, long bufferSize) = context.Request.GetBufferType0x21(); + (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(); int flags = context.RequestData.ReadInt32(); byte[] rawPath = new byte[bufferSize]; - context.Memory.Read((ulong)bufferPosition, rawPath); + context.Memory.Read(bufferPosition, rawPath); string path = Encoding.ASCII.GetString(rawPath); @@ -317,10 +317,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd int fdsCount = context.RequestData.ReadInt32(); int timeout = context.RequestData.ReadInt32(); - (long bufferPosition, long bufferSize) = context.Request.GetBufferType0x21(); + (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(); - if (timeout < -1 || fdsCount < 0 || (fdsCount * 8) > bufferSize) + if (timeout < -1 || fdsCount < 0 || (ulong)(fdsCount * 8) > bufferSize) { return WriteBsdResult(context, -1, LinuxError.EINVAL); } @@ -329,7 +329,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd for (int i = 0; i < fdsCount; i++) { - int socketFd = context.Memory.Read<int>((ulong)(bufferPosition + i * 8)); + int socketFd = context.Memory.Read<int>(bufferPosition + (ulong)i * 8); BsdSocket socket = RetrieveSocket(socketFd); @@ -337,8 +337,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { return WriteBsdResult(context, -1, LinuxError.EBADF);} - PollEvent.EventTypeMask inputEvents = (PollEvent.EventTypeMask)context.Memory.Read<short>((ulong)(bufferPosition + i * 8 + 4)); - PollEvent.EventTypeMask outputEvents = (PollEvent.EventTypeMask)context.Memory.Read<short>((ulong)(bufferPosition + i * 8 + 6)); + PollEvent.EventTypeMask inputEvents = (PollEvent.EventTypeMask)context.Memory.Read<short>(bufferPosition + (ulong)i * 8 + 4); + PollEvent.EventTypeMask outputEvents = (PollEvent.EventTypeMask)context.Memory.Read<short>(bufferPosition + (ulong)i * 8 + 6); events[i] = new PollEvent(socketFd, socket, inputEvents, outputEvents); } @@ -413,8 +413,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd for (int i = 0; i < fdsCount; i++) { PollEvent Event = events[i]; - context.Memory.Write((ulong)(bufferPosition + i * 8), Event.SocketFd); - context.Memory.Write((ulong)(bufferPosition + i * 8 + 4), (short)Event.InputEvents); + context.Memory.Write(bufferPosition + (ulong)i * 8, Event.SocketFd); + context.Memory.Write(bufferPosition + (ulong)i * 8 + 4, (short)Event.InputEvents); PollEvent.EventTypeMask outputEvents = 0; @@ -443,7 +443,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd outputEvents |= PollEvent.EventTypeMask.Output; } - context.Memory.Write((ulong)(bufferPosition + i * 8 + 6), (short)outputEvents); + context.Memory.Write(bufferPosition + (ulong)i * 8 + 6, (short)outputEvents); } return WriteBsdResult(context, readEvents.Count + writeEvents.Count + errorEvents.Count, LinuxError.SUCCESS); @@ -467,7 +467,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd int socketFd = context.RequestData.ReadInt32(); SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32(); - (long receivePosition, long receiveLength) = context.Request.GetBufferType0x22(); + (ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -489,7 +489,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd result = socket.Handle.Receive(receivedBuffer, socketFlags); errno = SetResultErrno(socket.Handle, result); - context.Memory.Write((ulong)receivePosition, receivedBuffer); + context.Memory.Write(receivePosition, receivedBuffer); } catch (SocketException exception) { @@ -507,8 +507,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd int socketFd = context.RequestData.ReadInt32(); SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32(); - (long receivePosition, long receiveLength) = context.Request.GetBufferType0x22(); - (long sockAddrOutPosition, long sockAddrOutSize) = context.Request.GetBufferType0x22(1); + (ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22(); + (ulong sockAddrOutPosition, ulong sockAddrOutSize) = context.Request.GetBufferType0x22(1); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -532,7 +532,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd result = socket.Handle.ReceiveFrom(receivedBuffer, receivedBuffer.Length, socketFlags, ref endPoint); errno = SetResultErrno(socket.Handle, result); - context.Memory.Write((ulong)receivePosition, receivedBuffer); + context.Memory.Write(receivePosition, receivedBuffer); WriteSockAddr(context, sockAddrOutPosition, (IPEndPoint)endPoint); } catch (SocketException exception) @@ -551,7 +551,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd int socketFd = context.RequestData.ReadInt32(); SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32(); - (long sendPosition, long sendSize) = context.Request.GetBufferType0x21(); + (ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -569,7 +569,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd byte[] sendBuffer = new byte[sendSize]; - context.Memory.Read((ulong)sendPosition, sendBuffer); + context.Memory.Read(sendPosition, sendBuffer); try { @@ -593,8 +593,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd int socketFd = context.RequestData.ReadInt32(); SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32(); - (long sendPosition, long sendSize) = context.Request.GetBufferType0x21(); - (long bufferPosition, long bufferSize) = context.Request.GetBufferType0x21(1); + (ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21(); + (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(1); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -612,7 +612,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd byte[] sendBuffer = new byte[sendSize]; - context.Memory.Read((ulong)sendPosition, sendBuffer); + context.Memory.Read(sendPosition, sendBuffer); EndPoint endPoint = ParseSockAddr(context, bufferPosition, bufferSize); @@ -637,7 +637,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { int socketFd = context.RequestData.ReadInt32(); - (long bufferPos, long bufferSize) = context.Request.GetBufferType0x22(); + (ulong bufferPos, ulong bufferSize) = context.Request.GetBufferType0x22(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -692,7 +692,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { int socketFd = context.RequestData.ReadInt32(); - (long bufferPos, long bufferSize) = context.Request.GetBufferType0x21(); + (ulong bufferPos, ulong bufferSize) = context.Request.GetBufferType0x21(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -722,7 +722,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { int socketFd = context.RequestData.ReadInt32(); - (long bufferPos, long bufferSize) = context.Request.GetBufferType0x21(); + (ulong bufferPos, ulong bufferSize) = context.Request.GetBufferType0x21(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -751,7 +751,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { int socketFd = context.RequestData.ReadInt32(); - (long bufferPos, long bufferSize) = context.Request.GetBufferType0x22(); + (ulong bufferPos, ulong bufferSize) = context.Request.GetBufferType0x22(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -774,7 +774,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { int socketFd = context.RequestData.ReadInt32(); - (long bufferPos, long bufferSize) = context.Request.GetBufferType0x22(); + (ulong bufferPos, ulong bufferSize) = context.Request.GetBufferType0x22(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -799,7 +799,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd int level = context.RequestData.ReadInt32(); int optionName = context.RequestData.ReadInt32(); - (long bufferPosition, long bufferSize) = context.Request.GetBufferType0x22(); + (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x22(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -866,10 +866,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd case BsdIoctl.AtMark: errno = LinuxError.SUCCESS; - (long bufferPosition, long bufferSize) = context.Request.GetBufferType0x22(); + (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x22(); // FIXME: OOB not implemented. - context.Memory.Write((ulong)bufferPosition, 0); + context.Memory.Write(bufferPosition, 0); break; default: @@ -917,7 +917,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return WriteBsdResult(context, result, errno); } - private LinuxError HandleGetSocketOption(ServiceCtx context, BsdSocket socket, SocketOptionName optionName, long optionValuePosition, long optionValueSize) + private LinuxError HandleGetSocketOption(ServiceCtx context, BsdSocket socket, SocketOptionName optionName, ulong optionValuePosition, ulong optionValueSize) { try { @@ -938,13 +938,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd case SocketOptionName.Type: case SocketOptionName.Linger: socket.Handle.GetSocketOption(SocketOptionLevel.Socket, optionName, optionValue); - context.Memory.Write((ulong)optionValuePosition, optionValue); + context.Memory.Write(optionValuePosition, optionValue); return LinuxError.SUCCESS; case (SocketOptionName)0x200: socket.Handle.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, optionValue); - context.Memory.Write((ulong)optionValuePosition, optionValue); + context.Memory.Write(optionValuePosition, optionValue); return LinuxError.SUCCESS; @@ -960,7 +960,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd } } - private LinuxError HandleSetSocketOption(ServiceCtx context, BsdSocket socket, SocketOptionName optionName, long optionValuePosition, long optionValueSize) + private LinuxError HandleSetSocketOption(ServiceCtx context, BsdSocket socket, SocketOptionName optionName, ulong optionValuePosition, ulong optionValueSize) { try { @@ -1013,7 +1013,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd int level = context.RequestData.ReadInt32(); int optionName = context.RequestData.ReadInt32(); - (long bufferPos, long bufferSize) = context.Request.GetBufferType0x21(); + (ulong bufferPos, ulong bufferSize) = context.Request.GetBufferType0x21(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -1105,7 +1105,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { int socketFd = context.RequestData.ReadInt32(); - (long sendPosition, long sendSize) = context.Request.GetBufferType0x21(); + (ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -1115,7 +1115,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { byte[] sendBuffer = new byte[sendSize]; - context.Memory.Read((ulong)sendPosition, sendBuffer); + context.Memory.Read(sendPosition, sendBuffer); try { @@ -1137,7 +1137,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { int socketFd = context.RequestData.ReadInt32(); - (long receivePosition, long receiveLength) = context.Request.GetBufferType0x22(); + (ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22(); LinuxError errno = LinuxError.EBADF; BsdSocket socket = RetrieveSocket(socketFd); @@ -1151,7 +1151,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { result = socket.Handle.Receive(receivedBuffer); errno = SetResultErrno(socket.Handle, result); - context.Memory.Write((ulong)receivePosition, receivedBuffer); + context.Memory.Write(receivePosition, receivedBuffer); } catch (SocketException exception) { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs index f6b83eaa..f58953d8 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs @@ -3,6 +3,8 @@ using Ryujinx.Cpu; using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Services.Settings; using Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager; +using Ryujinx.HLE.HOS.Services.Sockets.Nsd.Types; +using System.Runtime.InteropServices; using System.Text; namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd @@ -11,8 +13,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd [Service("nsd:u")] // Max sessions: 20 class IManager : IpcService { - private NsdSettings _nsdSettings; - private FqdnResolver _fqdnResolver; + private readonly NsdSettings _nsdSettings; + private readonly FqdnResolver _fqdnResolver; private bool _isInitialized = false; @@ -20,12 +22,21 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd { // TODO: Load nsd settings through the savedata 0x80000000000000B0 (nsdsave:/). - NxSettings.Settings.TryGetValue("nsd!test_mode", out object testMode); + if (!NxSettings.Settings.TryGetValue("nsd!test_mode", out object testMode)) + { + // return ResultCode.InvalidSettingsValue; + } + + if (!NxSettings.Settings.TryGetValue("nsd!environment_identifier", out object environmentIdentifier)) + { + // return ResultCode.InvalidSettingsValue; + } _nsdSettings = new NsdSettings { Initialized = true, - TestMode = (bool)testMode + TestMode = (bool)testMode, + Environment = (string)environmentIdentifier }; _fqdnResolver = new FqdnResolver(_nsdSettings); @@ -33,37 +44,35 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd _isInitialized = true; } + [CommandHipc(5)] // 11.0.0+ + // GetSettingUrl() -> buffer<unknown<0x100>, 0x16> + public ResultCode GetSettingUrl(ServiceCtx context) + { + throw new ServiceNotImplementedException(this, context, false); + } + [CommandHipc(10)] // GetSettingName() -> buffer<unknown<0x100>, 0x16> public ResultCode GetSettingName(ServiceCtx context) { - (long outputPosition, long outputSize) = context.Request.GetBufferType0x22(); - - ResultCode result = _fqdnResolver.GetSettingName(context, out string settingName); - - if (result == ResultCode.Success) - { - byte[] settingNameBuffer = Encoding.UTF8.GetBytes(settingName + '\0'); - - context.Memory.Write((ulong)outputPosition, settingNameBuffer); - } - - return result; + throw new ServiceNotImplementedException(this, context, false); } [CommandHipc(11)] - // GetEnvironmentIdentifier() -> buffer<unknown<8>, 0x16> + // GetEnvironmentIdentifier() -> buffer<bytes<8> environment_identifier, 0x16> public ResultCode GetEnvironmentIdentifier(ServiceCtx context) { - (long outputPosition, long outputSize) = context.Request.GetBufferType0x22(); + (ulong outputPosition, ulong outputSize) = context.Request.GetBufferType0x22(); - ResultCode result = _fqdnResolver.GetEnvironmentIdentifier(context, out string identifier); + MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize); + + ResultCode result = _fqdnResolver.GetEnvironmentIdentifier(out string identifier); if (result == ResultCode.Success) { - byte[] identifierBuffer = Encoding.UTF8.GetBytes(identifier + '\0'); + byte[] identifierBuffer = Encoding.UTF8.GetBytes(identifier); - context.Memory.Write((ulong)outputPosition, identifierBuffer); + context.Memory.Write(outputPosition, identifierBuffer); } return result; @@ -122,23 +131,35 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd throw new ServiceNotImplementedException(this, context, false); } - [CommandHipc(15)] - // Unknown(bytes<1>) - public ResultCode Unknown(ServiceCtx context) + [CommandHipc(15)] // 4.0.0+ + // SetChangeEnvironmentIdentifierDisabled(bytes<1>) + public ResultCode SetChangeEnvironmentIdentifierDisabled(ServiceCtx context) { - throw new ServiceNotImplementedException(this, context, false); + byte disabled = context.RequestData.ReadByte(); + + // TODO: When sys:set service calls will be implemented + /* + if (((nn::settings::detail::GetServiceDiscoveryControlSettings() ^ disabled) & 1) != 0 ) + { + nn::settings::detail::SetServiceDiscoveryControlSettings(disabled & 1); + } + */ + + Logger.Stub?.PrintStub(LogClass.ServiceNsd, new { disabled }); + + return ResultCode.Success; } [CommandHipc(20)] // Resolve(buffer<unknown<0x100>, 0x15>) -> buffer<unknown<0x100>, 0x16> public ResultCode Resolve(ServiceCtx context) { - long outputPosition = context.Request.ReceiveBuff[0].Position; - long outputSize = context.Request.ReceiveBuff[0].Size; + ulong outputPosition = context.Request.ReceiveBuff[0].Position; + ulong outputSize = context.Request.ReceiveBuff[0].Size; ResultCode result = _fqdnResolver.ResolveEx(context, out _, out string resolvedAddress); - if (resolvedAddress.Length > outputSize) + if ((ulong)resolvedAddress.Length > outputSize) { return ResultCode.InvalidArgument; } @@ -147,7 +168,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize); - context.Memory.Write((ulong)outputPosition, resolvedAddressBuffer); + context.Memory.Write(outputPosition, resolvedAddressBuffer); return result; } @@ -156,12 +177,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd // ResolveEx(buffer<unknown<0x100>, 0x15>) -> (u32, buffer<unknown<0x100>, 0x16>) public ResultCode ResolveEx(ServiceCtx context) { - long outputPosition = context.Request.ReceiveBuff[0].Position; - long outputSize = context.Request.ReceiveBuff[0].Size; + ulong outputPosition = context.Request.ReceiveBuff[0].Position; + ulong outputSize = context.Request.ReceiveBuff[0].Size; ResultCode result = _fqdnResolver.ResolveEx(context, out ResultCode errorCode, out string resolvedAddress); - if (resolvedAddress.Length > outputSize) + if ((ulong)resolvedAddress.Length > outputSize) { return ResultCode.InvalidArgument; } @@ -170,7 +191,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize); - context.Memory.Write((ulong)outputPosition, resolvedAddressBuffer); + context.Memory.Write(outputPosition, resolvedAddressBuffer); context.ResponseData.Write((int)errorCode); @@ -226,6 +247,24 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd throw new ServiceNotImplementedException(this, context, false); } + [CommandHipc(51)] // 9.0.0+ + // WriteTestParameter(buffer<?>) + public ResultCode WriteTestParameter(ServiceCtx context) + { + // TODO: Write test parameter through the savedata 0x80000000000000B0 (nsdsave:/test_parameter). + + throw new ServiceNotImplementedException(this, context, false); + } + + [CommandHipc(52)] // 9.0.0+ + // ReadTestParameter() -> buffer<?> + public ResultCode ReadTestParameter(ServiceCtx context) + { + // TODO: Read test parameter through the savedata 0x80000000000000B0 (nsdsave:/test_parameter). + + throw new ServiceNotImplementedException(this, context, false); + } + [CommandHipc(60)] // ReadSaveDataFromFsForTest() -> buffer<unknown<0x12bf0>, 0x16> public ResultCode ReadSaveDataFromFsForTest(ServiceCtx context) @@ -235,8 +274,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd return ResultCode.ServiceNotInitialized; } - // TODO: Call nn::nsd::detail::fs::ReadSaveDataWithOffset() at offset 0 to write the - // whole savedata inside the buffer. + // TODO: Read the savedata 0x80000000000000B0 (nsdsave:/file) and write it inside the buffer. Logger.Stub?.PrintStub(LogClass.ServiceNsd); @@ -247,38 +285,114 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd // WriteSaveDataToFsForTest(buffer<unknown<0x12bf0>, 0x15>) public ResultCode WriteSaveDataToFsForTest(ServiceCtx context) { - // NOTE: Stubbed in system module. - - if (_isInitialized) + if (!_isInitialized) { - return ResultCode.NotImplemented; + return ResultCode.ServiceNotInitialized; } - else + + // TODO: When sys:set service calls will be implemented + /* + if (nn::settings::detail::GetSettingsItemValueSize("nsd", "test_mode") != 1) + { + return ResultCode.InvalidSettingsValue; + } + */ + + if (!_nsdSettings.TestMode) { - return ResultCode.ServiceNotInitialized; + return ResultCode.InvalidSettingsValue; } + + // TODO: Write the buffer inside the savedata 0x80000000000000B0 (nsdsave:/file). + + Logger.Stub?.PrintStub(LogClass.ServiceNsd); + + return ResultCode.Success; } [CommandHipc(62)] // DeleteSaveDataOfFsForTest() public ResultCode DeleteSaveDataOfFsForTest(ServiceCtx context) { - // NOTE: Stubbed in system module. - - if (_isInitialized) + if (!_isInitialized) { - return ResultCode.NotImplemented; + return ResultCode.ServiceNotInitialized; } - else + + // TODO: When sys:set service calls will be implemented + /* + if (nn::settings::detail::GetSettingsItemValueSize("nsd", "test_mode") != 1) + { + return ResultCode.InvalidSettingsValue; + } + */ + + if (!_nsdSettings.TestMode) { - return ResultCode.ServiceNotInitialized; + return ResultCode.InvalidSettingsValue; } + + // TODO: Delete the savedata 0x80000000000000B0. + + Logger.Stub?.PrintStub(LogClass.ServiceNsd); + + return ResultCode.Success; } - [CommandHipc(63)] + [CommandHipc(63)] // 4.0.0+ // IsChangeEnvironmentIdentifierDisabled() -> bytes<1> public ResultCode IsChangeEnvironmentIdentifierDisabled(ServiceCtx context) { + // TODO: When sys:set service calls will be implemented use nn::settings::detail::GetServiceDiscoveryControlSettings() + + bool disabled = false; + + context.ResponseData.Write(disabled); + + Logger.Stub?.PrintStub(LogClass.ServiceNsd, new { disabled }); + + return ResultCode.Success; + } + + [CommandHipc(100)] // 10.0.0+ + // GetApplicationServerEnvironmentType() -> bytes<1> + public ResultCode GetApplicationServerEnvironmentType(ServiceCtx context) + { + // TODO: Mount the savedata 0x80000000000000B0 (nsdsave:/test_parameter) and returns the environment type stored inside if the mount succeed. + // Returns ResultCode.NullOutputObject if failed. + + ResultCode result = _fqdnResolver.GetEnvironmentIdentifier(out string identifier); + + if (result != ResultCode.Success) + { + return result; + } + + byte environmentType = identifier.Substring(0, 2) switch + { + "lp" => (byte)ApplicationServerEnvironmentType.Lp, + "sd" => (byte)ApplicationServerEnvironmentType.Sd, + "sp" => (byte)ApplicationServerEnvironmentType.Sp, + "dp" => (byte)ApplicationServerEnvironmentType.Dp, + _ => (byte)ApplicationServerEnvironmentType.None + }; + + context.ResponseData.Write(environmentType); + + return ResultCode.Success; + } + + [CommandHipc(101)] // 10.0.0+ + // SetApplicationServerEnvironmentType(bytes<1>) + public ResultCode SetApplicationServerEnvironmentType(ServiceCtx context) + { + throw new ServiceNotImplementedException(this, context, false); + } + + [CommandHipc(102)] // 10.0.0+ + // DeleteApplicationServerEnvironmentType() + public ResultCode DeleteApplicationServerEnvironmentType(ServiceCtx context) + { throw new ServiceNotImplementedException(this, context, false); } } diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs index 6bdf06ad..2e23f3fb 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs @@ -13,38 +13,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager _nsdSettings = nsdSettings; } - public ResultCode GetSettingName(ServiceCtx context, out string settingName) + public ResultCode GetEnvironmentIdentifier(out string identifier) { if (_nsdSettings.TestMode) { - settingName = ""; + identifier = "err"; - return ResultCode.NotImplemented; - } - else - { - settingName = ""; - - if (true) // TODO: Determine field (struct + 0x2C) - { - settingName = _nsdSettings.Environment; - - return ResultCode.Success; - } - -#pragma warning disable CS0162 - return ResultCode.NullOutputObject; -#pragma warning restore CS0162 - } - } - - public ResultCode GetEnvironmentIdentifier(ServiceCtx context, out string identifier) - { - if (_nsdSettings.TestMode) - { - identifier = "rre"; - - return ResultCode.NotImplemented; + return ResultCode.InvalidSettingsValue; } else { @@ -56,7 +31,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager public ResultCode Resolve(ServiceCtx context, string address, out string resolvedAddress) { - if (address != "api.sect.srv.nintendo.net" || address != "conntest.nintendowifi.net") + if (address == "api.sect.srv.nintendo.net" || + address == "ctest.cdn.nintendo.net" || + address == "ctest.cdn.n.nintendoswitch.cn" || + address == "unknown.dummy.nintendo.net") + { + resolvedAddress = address; + } + else { // TODO: Load Environment from the savedata. address = address.Replace("%", _nsdSettings.Environment); @@ -87,22 +69,18 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager _ => address, }; } - else - { - resolvedAddress = address; - } return ResultCode.Success; } public ResultCode ResolveEx(ServiceCtx context, out ResultCode resultCode, out string resolvedAddress) { - long inputPosition = context.Request.SendBuff[0].Position; - long inputSize = context.Request.SendBuff[0].Size; + ulong inputPosition = context.Request.SendBuff[0].Position; + ulong inputSize = context.Request.SendBuff[0].Size; byte[] addressBuffer = new byte[inputSize]; - context.Memory.Read((ulong)inputPosition, addressBuffer); + context.Memory.Read(inputPosition, addressBuffer); string address = Encoding.UTF8.GetString(addressBuffer).TrimEnd('\0'); diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/ResultCode.cs index 0e636f9a..993fbe8a 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/ResultCode.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/ResultCode.cs @@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd Success = 0, - NotImplemented = ( 1 << ErrorCodeShift) | ModuleId, + InvalidSettingsValue = ( 1 << ErrorCodeShift) | ModuleId, InvalidObject1 = ( 3 << ErrorCodeShift) | ModuleId, InvalidObject2 = ( 4 << ErrorCodeShift) | ModuleId, NullOutputObject = ( 5 << ErrorCodeShift) | ModuleId, diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/ApplicationServerEnvironmentType.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/ApplicationServerEnvironmentType.cs new file mode 100644 index 00000000..150bdab4 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/ApplicationServerEnvironmentType.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Types +{ + enum ApplicationServerEnvironmentType : byte + { + None, + Lp, + Sd, + Sp, + Dp + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs index 2b31cb1d..0a72fa87 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs @@ -4,6 +4,6 @@ { public bool Initialized; public bool TestMode; - public string Environment = "lp1"; // or "dd1" if devkit. + public string Environment; } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs index f86a27dd..2baeb1ef 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs @@ -24,8 +24,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres public ResultCode SetDnsAddressesPrivateRequest(ServiceCtx context) { uint cancelHandleRequest = context.RequestData.ReadUInt32(); - long bufferPosition = context.Request.SendBuff[0].Position; - long bufferSize = context.Request.SendBuff[0].Size; + ulong bufferPosition = context.Request.SendBuff[0].Position; + ulong bufferSize = context.Request.SendBuff[0].Size; // TODO: This is stubbed in 2.0.0+, reverse 1.0.0 version for the sake of completeness. Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { cancelHandleRequest }); @@ -38,8 +38,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres public ResultCode GetDnsAddressPrivateRequest(ServiceCtx context) { uint cancelHandleRequest = context.RequestData.ReadUInt32(); - long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferSize = context.Request.ReceiveBuff[0].Size; + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferSize = context.Request.ReceiveBuff[0].Size; // TODO: This is stubbed in 2.0.0+, reverse 1.0.0 version for the sake of completeness. Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { cancelHandleRequest }); @@ -51,11 +51,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // GetHostByNameRequest(u8, u32, u64, pid, buffer<unknown, 5, 0>) -> (u32, u32, u32, buffer<unknown, 6, 0>) public ResultCode GetHostByNameRequest(ServiceCtx context) { - long inputBufferPosition = context.Request.SendBuff[0].Position; - long inputBufferSize = context.Request.SendBuff[0].Size; + ulong inputBufferPosition = context.Request.SendBuff[0].Position; + ulong inputBufferSize = context.Request.SendBuff[0].Size; - long outputBufferPosition = context.Request.ReceiveBuff[0].Position; - long outputBufferSize = context.Request.ReceiveBuff[0].Size; + ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position; + ulong outputBufferSize = context.Request.ReceiveBuff[0].Size; return GetHostByNameRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, 0, 0); } @@ -64,11 +64,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // GetHostByAddrRequest(u32, u32, u32, u64, pid, buffer<unknown, 5, 0>) -> (u32, u32, u32, buffer<unknown, 6, 0>) public ResultCode GetHostByAddrRequest(ServiceCtx context) { - long inputBufferPosition = context.Request.SendBuff[0].Position; - long inputBufferSize = context.Request.SendBuff[0].Size; + ulong inputBufferPosition = context.Request.SendBuff[0].Position; + ulong inputBufferSize = context.Request.SendBuff[0].Size; - long outputBufferPosition = context.Request.ReceiveBuff[0].Position; - long outputBufferSize = context.Request.ReceiveBuff[0].Size; + ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position; + ulong outputBufferSize = context.Request.ReceiveBuff[0].Size; return GetHostByAddrRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, 0, 0); } @@ -90,12 +90,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres _ => (errorCode <= NetDbError.Internal) ? "Resolver internal error" : "Unknown resolver error" }; - long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferSize = context.Request.ReceiveBuff[0].Size; + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferSize = context.Request.ReceiveBuff[0].Size; - if (errorString.Length + 1 <= bufferSize) + if ((ulong)(errorString.Length + 1) <= bufferSize) { - context.Memory.Write((ulong)bufferPosition, Encoding.ASCII.GetBytes(errorString + '\0')); + context.Memory.Write(bufferPosition, Encoding.ASCII.GetBytes(errorString + '\0')); resultCode = ResultCode.Success; } @@ -135,12 +135,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres _ => "Success" }; - long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferSize = context.Request.ReceiveBuff[0].Size; + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferSize = context.Request.ReceiveBuff[0].Size; - if (errorString.Length + 1 <= bufferSize) + if ((ulong)(errorString.Length + 1) <= bufferSize) { - context.Memory.Write((ulong)bufferPosition, Encoding.ASCII.GetBytes(errorString + '\0')); + context.Memory.Write(bufferPosition, Encoding.ASCII.GetBytes(errorString + '\0')); resultCode = ResultCode.Success; } @@ -152,8 +152,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // GetAddrInfoRequest(bool enable_nsd_resolve, u32, u64 pid_placeholder, pid, buffer<i8, 5, 0> host, buffer<i8, 5, 0> service, buffer<packed_addrinfo, 5, 0> hints) -> (i32 ret, u32 bsd_errno, u32 packed_addrinfo_size, buffer<packed_addrinfo, 6, 0> response) public ResultCode GetAddrInfoRequest(ServiceCtx context) { - long responseBufferPosition = context.Request.ReceiveBuff[0].Position; - long responseBufferSize = context.Request.ReceiveBuff[0].Size; + ulong responseBufferPosition = context.Request.ReceiveBuff[0].Position; + ulong responseBufferSize = context.Request.ReceiveBuff[0].Size; return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, 0, 0); } @@ -188,9 +188,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // GetHostByNameRequestWithOptions(u8, u32, u64, pid, buffer<unknown, 21, 0>, buffer<unknown, 21, 0>) -> (u32, u32, u32, buffer<unknown, 22, 0>) public ResultCode GetHostByNameRequestWithOptions(ServiceCtx context) { - (long inputBufferPosition, long inputBufferSize) = context.Request.GetBufferType0x21(); - (long outputBufferPosition, long outputBufferSize) = context.Request.GetBufferType0x22(); - (long optionsBufferPosition, long optionsBufferSize) = context.Request.GetBufferType0x21(); + (ulong inputBufferPosition, ulong inputBufferSize) = context.Request.GetBufferType0x21(); + (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); + (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); return GetHostByNameRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, optionsBufferPosition, optionsBufferSize); } @@ -199,9 +199,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // GetHostByAddrRequestWithOptions(u32, u32, u32, u64, pid, buffer<unknown, 21, 0>, buffer<unknown, 21, 0>) -> (u32, u32, u32, buffer<unknown, 22, 0>) public ResultCode GetHostByAddrRequestWithOptions(ServiceCtx context) { - (long inputBufferPosition, long inputBufferSize) = context.Request.GetBufferType0x21(); - (long outputBufferPosition, long outputBufferSize) = context.Request.GetBufferType0x22(); - (long optionsBufferPosition, long optionsBufferSize) = context.Request.GetBufferType0x21(); + (ulong inputBufferPosition, ulong inputBufferSize) = context.Request.GetBufferType0x21(); + (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); + (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); return GetHostByAddrRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, optionsBufferPosition, optionsBufferSize); } @@ -210,17 +210,17 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // GetAddrInfoRequestWithOptions(bool enable_nsd_resolve, u32, u64 pid_placeholder, pid, buffer<i8, 5, 0> host, buffer<i8, 5, 0> service, buffer<packed_addrinfo, 5, 0> hints, buffer<unknown, 21, 0>) -> (i32 ret, u32 bsd_errno, u32 unknown, u32 packed_addrinfo_size, buffer<packed_addrinfo, 22, 0> response) public ResultCode GetAddrInfoRequestWithOptions(ServiceCtx context) { - (long responseBufferPosition, long responseBufferSize) = context.Request.GetBufferType0x22(); - (long optionsBufferPosition, long optionsBufferSize) = context.Request.GetBufferType0x21(); + (ulong responseBufferPosition, ulong responseBufferSize) = context.Request.GetBufferType0x22(); + (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, optionsBufferPosition, optionsBufferSize); } - private ResultCode GetHostByNameRequestImpl(ServiceCtx context, long inputBufferPosition, long inputBufferSize, long outputBufferPosition, long outputBufferSize, long optionsBufferPosition, long optionsBufferSize) + private ResultCode GetHostByNameRequestImpl(ServiceCtx context, ulong inputBufferPosition, ulong inputBufferSize, ulong outputBufferPosition, ulong outputBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize) { byte[] rawName = new byte[inputBufferSize]; - context.Memory.Read((ulong)inputBufferPosition, rawName); + context.Memory.Read(inputBufferPosition, rawName); string name = Encoding.ASCII.GetString(rawName).TrimEnd('\0'); @@ -238,7 +238,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.Overflow; - long serializedSize = 0; + ulong serializedSize = 0; if (name.Length <= byte.MaxValue) { @@ -294,11 +294,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres return ResultCode.Success; } - private ResultCode GetHostByAddrRequestImpl(ServiceCtx context, long inputBufferPosition, long inputBufferSize, long outputBufferPosition, long outputBufferSize, long optionsBufferPosition, long optionsBufferSize) + private ResultCode GetHostByAddrRequestImpl(ServiceCtx context, ulong inputBufferPosition, ulong inputBufferSize, ulong outputBufferPosition, ulong outputBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize) { byte[] rawIp = new byte[inputBufferSize]; - context.Memory.Read((ulong)inputBufferPosition, rawIp); + context.Memory.Read(inputBufferPosition, rawIp); // TODO: Use params. uint socketLength = context.RequestData.ReadUInt32(); @@ -315,7 +315,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.AddressFamily; - long serializedSize = 0; + ulong serializedSize = 0; if (rawIp.Length == 4) { @@ -349,59 +349,59 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres return ResultCode.Success; } - private long SerializeHostEntries(ServiceCtx context, long outputBufferPosition, long outputBufferSize, IPHostEntry hostEntry, IEnumerable<IPAddress> addresses = null) + private ulong SerializeHostEntries(ServiceCtx context, ulong outputBufferPosition, ulong outputBufferSize, IPHostEntry hostEntry, IEnumerable<IPAddress> addresses = null) { - long originalBufferPosition = outputBufferPosition; - long bufferPosition = originalBufferPosition; + ulong originalBufferPosition = outputBufferPosition; + ulong bufferPosition = originalBufferPosition; string hostName = hostEntry.HostName + '\0'; // h_name - context.Memory.Write((ulong)bufferPosition, Encoding.ASCII.GetBytes(hostName)); - bufferPosition += hostName.Length; + context.Memory.Write(bufferPosition, Encoding.ASCII.GetBytes(hostName)); + bufferPosition += (ulong)hostName.Length; // h_aliases list size - context.Memory.Write((ulong)bufferPosition, BinaryPrimitives.ReverseEndianness(hostEntry.Aliases.Length)); - bufferPosition += 4; + context.Memory.Write(bufferPosition, BinaryPrimitives.ReverseEndianness(hostEntry.Aliases.Length)); + bufferPosition += sizeof(int); // Actual aliases foreach (string alias in hostEntry.Aliases) { - context.Memory.Write((ulong)bufferPosition, Encoding.ASCII.GetBytes(alias + '\0')); - bufferPosition += alias.Length + 1; + context.Memory.Write(bufferPosition, Encoding.ASCII.GetBytes(alias + '\0')); + bufferPosition += (ulong)(alias.Length + 1); } // h_addrtype but it's a short (also only support IPv4) - context.Memory.Write((ulong)bufferPosition, BinaryPrimitives.ReverseEndianness((short)AddressFamily.InterNetwork)); - bufferPosition += 2; + context.Memory.Write(bufferPosition, BinaryPrimitives.ReverseEndianness((short)AddressFamily.InterNetwork)); + bufferPosition += sizeof(short); // h_length but it's a short - context.Memory.Write((ulong)bufferPosition, BinaryPrimitives.ReverseEndianness((short)4)); - bufferPosition += 2; + context.Memory.Write(bufferPosition, BinaryPrimitives.ReverseEndianness((short)4)); + bufferPosition += sizeof(short); // Ip address count, we can only support ipv4 (blame Nintendo) - context.Memory.Write((ulong)bufferPosition, addresses != null ? BinaryPrimitives.ReverseEndianness(addresses.Count()) : 0); - bufferPosition += 4; + context.Memory.Write(bufferPosition, addresses != null ? BinaryPrimitives.ReverseEndianness(addresses.Count()) : 0); + bufferPosition += sizeof(int); if (addresses != null) { foreach (IPAddress ip in addresses) { - context.Memory.Write((ulong)bufferPosition, BinaryPrimitives.ReverseEndianness(BitConverter.ToInt32(ip.GetAddressBytes(), 0))); - bufferPosition += 4; + context.Memory.Write(bufferPosition, BinaryPrimitives.ReverseEndianness(BitConverter.ToInt32(ip.GetAddressBytes(), 0))); + bufferPosition += sizeof(int); } } return bufferPosition - originalBufferPosition; } - private ResultCode GetAddrInfoRequestImpl(ServiceCtx context, long responseBufferPosition, long responseBufferSize, long optionsBufferPosition, long optionsBufferSize) + private ResultCode GetAddrInfoRequestImpl(ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize) { bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; uint cancelHandle = context.RequestData.ReadUInt32(); - string host = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[0].Position, context.Request.SendBuff[0].Size); - string service = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[1].Position, context.Request.SendBuff[1].Size); + string host = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[0].Position, (long)context.Request.SendBuff[0].Size); + string service = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[1].Position, (long)context.Request.SendBuff[1].Size); // NOTE: We ignore hints for now. DeserializeAddrInfos(context.Memory, (ulong)context.Request.SendBuff[2].Position, (ulong)context.Request.SendBuff[2].Size); @@ -500,7 +500,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres } } - private ulong SerializeAddrInfos(ServiceCtx context, long responseBufferPosition, long responseBufferSize, IPHostEntry hostEntry, int port) + private ulong SerializeAddrInfos(ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, IPHostEntry hostEntry, int port) { ulong originalBufferPosition = (ulong)responseBufferPosition; ulong bufferPosition = originalBufferPosition; @@ -533,7 +533,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // Termination zero value. context.Memory.Write(bufferPosition, 0); - bufferPosition += 4; + bufferPosition += sizeof(int); return bufferPosition - originalBufferPosition; } diff --git a/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs b/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs index 3d6be4d8..62e118d9 100644 --- a/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs +++ b/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs @@ -21,7 +21,7 @@ namespace Ryujinx.HLE.HOS.Services.Spl _rng.GetBytes(randomBytes); - context.Memory.Write((ulong)context.Request.ReceiveBuff[0].Position, randomBytes); + context.Memory.Write(context.Request.ReceiveBuff[0].Position, randomBytes); return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs b/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs index 9d1ffe85..24f3d066 100644 --- a/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs +++ b/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs @@ -26,12 +26,12 @@ namespace Ryujinx.HLE.HOS.Services.Ssl.SslService // SetHostName(buffer<bytes, 5>) public ResultCode SetHostName(ServiceCtx context) { - long hostNameDataPosition = context.Request.SendBuff[0].Position; - long hostNameDataSize = context.Request.SendBuff[0].Size; + ulong hostNameDataPosition = context.Request.SendBuff[0].Position; + ulong hostNameDataSize = context.Request.SendBuff[0].Size; byte[] hostNameData = new byte[hostNameDataSize]; - context.Memory.Read((ulong)hostNameDataPosition, hostNameData); + context.Memory.Read(hostNameDataPosition, hostNameData); string hostName = Encoding.ASCII.GetString(hostNameData).Trim('\0'); @@ -75,12 +75,12 @@ namespace Ryujinx.HLE.HOS.Services.Ssl.SslService // Write(buffer<bytes, 5>) -> u32 public ResultCode Write(ServiceCtx context) { - long inputDataPosition = context.Request.SendBuff[0].Position; - long inputDataSize = context.Request.SendBuff[0].Size; + ulong inputDataPosition = context.Request.SendBuff[0].Position; + ulong inputDataSize = context.Request.SendBuff[0].Size; byte[] data = new byte[inputDataSize]; - context.Memory.Read((ulong)inputDataPosition, data); + context.Memory.Read(inputDataPosition, data); // NOTE: Tell the guest everything is transferred. uint transferredSize = (uint)inputDataSize; diff --git a/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs b/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs index ec4b5112..718af2cb 100644 --- a/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs +++ b/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs @@ -41,8 +41,8 @@ namespace Ryujinx.HLE.HOS.Services.Ssl.SslService { CertificateFormat certificateFormat = (CertificateFormat)context.RequestData.ReadUInt32(); - long certificateDataPosition = context.Request.SendBuff[0].Position; - long certificateDataSize = context.Request.SendBuff[0].Size; + ulong certificateDataPosition = context.Request.SendBuff[0].Position; + ulong certificateDataSize = context.Request.SendBuff[0].Size; context.ResponseData.Write(_serverCertificateId++); @@ -55,15 +55,15 @@ namespace Ryujinx.HLE.HOS.Services.Ssl.SslService // ImportClientPki(buffer<bytes, 5> certificate, buffer<bytes, 5> ascii_password) -> u64 certificateId public ResultCode ImportClientPki(ServiceCtx context) { - long certificateDataPosition = context.Request.SendBuff[0].Position; - long certificateDataSize = context.Request.SendBuff[0].Size; + ulong certificateDataPosition = context.Request.SendBuff[0].Position; + ulong certificateDataSize = context.Request.SendBuff[0].Size; - long asciiPasswordDataPosition = context.Request.SendBuff[1].Position; - long asciiPasswordDataSize = context.Request.SendBuff[1].Size; + ulong asciiPasswordDataPosition = context.Request.SendBuff[1].Position; + ulong asciiPasswordDataSize = context.Request.SendBuff[1].Size; byte[] asciiPasswordData = new byte[asciiPasswordDataSize]; - context.Memory.Read((ulong)asciiPasswordDataPosition, asciiPasswordData); + context.Memory.Read(asciiPasswordDataPosition, asciiPasswordData); string asciiPassword = Encoding.ASCII.GetString(asciiPasswordData).Trim('\0'); diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs index 011ab6ed..c3dcbee7 100644 --- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs +++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs @@ -18,11 +18,11 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger uint code = context.RequestData.ReadUInt32(); uint flags = context.RequestData.ReadUInt32(); - ulong dataPos = (ulong)context.Request.SendBuff[0].Position; - ulong dataSize = (ulong)context.Request.SendBuff[0].Size; + ulong dataPos = context.Request.SendBuff[0].Position; + ulong dataSize = context.Request.SendBuff[0].Size; - long replyPos = context.Request.ReceiveBuff[0].Position; - long replySize = context.Request.ReceiveBuff[0].Size; + ulong replyPos = context.Request.ReceiveBuff[0].Position; + ulong replySize = context.Request.ReceiveBuff[0].Size; ReadOnlySpan<byte> inputParcel = context.Memory.GetSpan(dataPos, (int)dataSize); @@ -32,7 +32,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger if (result == ResultCode.Success) { - context.Memory.Write((ulong)replyPos, outputParcel); + context.Memory.Write(replyPos, outputParcel); } return result; @@ -78,10 +78,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger uint code = context.RequestData.ReadUInt32(); uint flags = context.RequestData.ReadUInt32(); - (long dataPos, long dataSize) = context.Request.GetBufferType0x21(); - (long replyPos, long replySize) = context.Request.GetBufferType0x22(); + (ulong dataPos, ulong dataSize) = context.Request.GetBufferType0x21(); + (ulong replyPos, ulong replySize) = context.Request.GetBufferType0x22(); - ReadOnlySpan<byte> inputParcel = context.Memory.GetSpan((ulong)dataPos, (int)dataSize); + ReadOnlySpan<byte> inputParcel = context.Memory.GetSpan(dataPos, (int)dataSize); Span<byte> outputParcel = new Span<byte>(new byte[replySize]); @@ -89,7 +89,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger if (result == ResultCode.Success) { - context.Memory.Write((ulong)replyPos, outputParcel); + context.Memory.Write(replyPos, outputParcel); } return result; diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs index 556e6a3b..9d8e526f 100644 --- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs +++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs @@ -1,6 +1,5 @@ using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; -using Ryujinx.Configuration; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap; @@ -351,7 +350,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger bool flipX = item.Transform.HasFlag(NativeWindowTransform.FlipX); bool flipY = item.Transform.HasFlag(NativeWindowTransform.FlipY); - AspectRatio aspectRatio = ConfigurationState.Instance.Graphics.AspectRatio.Value; + AspectRatio aspectRatio = _device.Configuration.AspectRatio; bool isStretched = aspectRatio == AspectRatio.Stretched; ImageCrop crop = new ImageCrop( diff --git a/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs b/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs index 52530025..534af457 100644 --- a/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs +++ b/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs @@ -246,7 +246,7 @@ namespace Ryujinx.HLE.HOS.Services.Time { byte type = context.RequestData.ReadByte(); - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(Marshal.SizeOf<ClockSnapshot>()); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf<ClockSnapshot>()); ResultCode result = _timeManager.StandardUserSystemClock.GetClockContext(context.Thread, out SystemClockContext userContext); @@ -274,7 +274,7 @@ namespace Ryujinx.HLE.HOS.Services.Time { byte type = context.RequestData.ReadByte(); - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(Marshal.SizeOf<ClockSnapshot>()); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf<ClockSnapshot>()); context.RequestData.BaseStream.Position += 7; @@ -354,6 +354,7 @@ namespace Ryujinx.HLE.HOS.Services.Time clockSnapshot.IsAutomaticCorrectionEnabled = _timeManager.StandardUserSystemClock.IsAutomaticCorrectionEnabled(); clockSnapshot.UserContext = userContext; clockSnapshot.NetworkContext = networkContext; + clockSnapshot.SteadyClockTimePoint = currentTimePoint; ResultCode result = _timeManager.TimeZone.Manager.GetDeviceLocationName(out string deviceLocationName); @@ -404,11 +405,11 @@ namespace Ryujinx.HLE.HOS.Services.Time private ClockSnapshot ReadClockSnapshotFromBuffer(ServiceCtx context, IpcPtrBuffDesc ipcDesc) { - Debug.Assert(ipcDesc.Size == Marshal.SizeOf<ClockSnapshot>()); + Debug.Assert(ipcDesc.Size == (ulong)Marshal.SizeOf<ClockSnapshot>()); byte[] temp = new byte[ipcDesc.Size]; - context.Memory.Read((ulong)ipcDesc.Position, temp); + context.Memory.Read(ipcDesc.Position, temp); using (BinaryReader bufferReader = new BinaryReader(new MemoryStream(temp))) { diff --git a/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs b/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs index 9b6c59f6..8b4cd27c 100644 --- a/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs +++ b/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs @@ -121,11 +121,11 @@ namespace Ryujinx.HLE.HOS.Services.Time uint totalLocationNameCount = context.RequestData.ReadUInt32(); UInt128 timeZoneRuleVersion = context.RequestData.ReadStruct<UInt128>(); - (long bufferPosition, long bufferSize) = context.Request.GetBufferType0x21(); + (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(); byte[] temp = new byte[bufferSize]; - context.Memory.Read((ulong)bufferPosition, temp); + context.Memory.Read(bufferPosition, temp); using (MemoryStream timeZoneBinaryStream = new MemoryStream(temp)) { diff --git a/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs b/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs index 5f35412d..da806ab6 100644 --- a/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs +++ b/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs @@ -51,9 +51,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService // LoadLocationNameList(u32 index) -> (u32 outCount, buffer<nn::time::LocationName, 6>) public ResultCode LoadLocationNameList(ServiceCtx context) { - uint index = context.RequestData.ReadUInt32(); - long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferSize = context.Request.ReceiveBuff[0].Size; + uint index = context.RequestData.ReadUInt32(); + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferSize = context.Request.ReceiveBuff[0].Size; ResultCode errorCode = _timeZoneContentManager.LoadLocationNameList(index, out string[] locationNameArray, (uint)bufferSize / 0x24); @@ -70,8 +70,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService return ResultCode.LocationNameTooLong; } - context.Memory.Write((ulong)bufferPosition + offset, Encoding.ASCII.GetBytes(locationName)); - MemoryHelper.FillWithZeros(context.Memory, bufferPosition + offset + locationName.Length, padding); + context.Memory.Write(bufferPosition + offset, Encoding.ASCII.GetBytes(locationName)); + MemoryHelper.FillWithZeros(context.Memory, bufferPosition + offset + (ulong)locationName.Length, padding); offset += 0x24; } @@ -86,8 +86,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService // LoadTimeZoneRule(nn::time::LocationName locationName) -> buffer<nn::time::TimeZoneRule, 0x16> public ResultCode LoadTimeZoneRule(ServiceCtx context) { - long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferSize = context.Request.ReceiveBuff[0].Size; + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferSize = context.Request.ReceiveBuff[0].Size; if (bufferSize != 0x4000) { diff --git a/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs b/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs index 659e1331..d0ed9379 100644 --- a/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs +++ b/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs @@ -123,7 +123,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService return ResultCode.PermissionDenied; } - (long bufferPosition, long bufferSize) = context.Request.GetBufferType0x21(); + (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(); string locationName = Encoding.ASCII.GetString(context.RequestData.ReadBytes(0x24)).TrimEnd('\0'); @@ -131,7 +131,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService byte[] temp = new byte[bufferSize]; - context.Memory.Read((ulong)bufferPosition, temp); + context.Memory.Read(bufferPosition, temp); using (MemoryStream timeZoneBinaryStream = new MemoryStream(temp)) { @@ -145,10 +145,10 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService // ParseTimeZoneBinary(buffer<nn::time::TimeZoneBinary, 0x21> timeZoneBinary) -> buffer<nn::time::TimeZoneRule, 0x16> public ResultCode ParseTimeZoneBinary(ServiceCtx context) { - (long bufferPosition, long bufferSize) = context.Request.GetBufferType0x21(); + (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(); - long timeZoneRuleBufferPosition = context.Request.ReceiveBuff[0].Position; - long timeZoneRuleBufferSize = context.Request.ReceiveBuff[0].Size; + ulong timeZoneRuleBufferPosition = context.Request.ReceiveBuff[0].Position; + ulong timeZoneRuleBufferSize = context.Request.ReceiveBuff[0].Size; if (timeZoneRuleBufferSize != 0x4000) { @@ -162,7 +162,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService byte[] temp = new byte[bufferSize]; - context.Memory.Read((ulong)bufferPosition, temp); + context.Memory.Read(bufferPosition, temp); using (MemoryStream timeZoneBinaryStream = new MemoryStream(temp)) { @@ -188,9 +188,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService // ToCalendarTime(nn::time::PosixTime time, buffer<nn::time::TimeZoneRule, 0x15> rules) -> (nn::time::CalendarTime, nn::time::sf::CalendarAdditionalInfo) public ResultCode ToCalendarTime(ServiceCtx context) { - long posixTime = context.RequestData.ReadInt64(); - long bufferPosition = context.Request.SendBuff[0].Position; - long bufferSize = context.Request.SendBuff[0].Size; + long posixTime = context.RequestData.ReadInt64(); + ulong bufferPosition = context.Request.SendBuff[0].Position; + ulong bufferSize = context.Request.SendBuff[0].Size; if (bufferSize != 0x4000) { @@ -220,7 +220,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService ResultCode resultCode = _timeZoneManager.ToCalendarTimeWithMyRules(posixTime, out CalendarInfo calendar); - if (resultCode == 0) + if (resultCode == ResultCode.Success) { context.ResponseData.WriteStruct(calendar); } @@ -232,8 +232,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService // ToPosixTime(nn::time::CalendarTime calendarTime, buffer<nn::time::TimeZoneRule, 0x15> rules) -> (u32 outCount, buffer<nn::time::PosixTime, 0xa>) public ResultCode ToPosixTime(ServiceCtx context) { - long inBufferPosition = context.Request.SendBuff[0].Position; - long inBufferSize = context.Request.SendBuff[0].Size; + ulong inBufferPosition = context.Request.SendBuff[0].Position; + ulong inBufferSize = context.Request.SendBuff[0].Size; CalendarTime calendarTime = context.RequestData.ReadStruct<CalendarTime>(); @@ -249,12 +249,12 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService ResultCode resultCode = _timeZoneManager.ToPosixTime(rules, calendarTime, out long posixTime); - if (resultCode == 0) + if (resultCode == ResultCode.Success) { - long outBufferPosition = context.Request.RecvListBuff[0].Position; - long outBufferSize = context.Request.RecvListBuff[0].Size; + ulong outBufferPosition = context.Request.RecvListBuff[0].Position; + ulong outBufferSize = context.Request.RecvListBuff[0].Size; - context.Memory.Write((ulong)outBufferPosition, posixTime); + context.Memory.Write(outBufferPosition, posixTime); context.ResponseData.Write(1); } @@ -269,12 +269,12 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService ResultCode resultCode = _timeZoneManager.ToPosixTimeWithMyRules(calendarTime, out long posixTime); - if (resultCode == 0) + if (resultCode == ResultCode.Success) { - long outBufferPosition = context.Request.RecvListBuff[0].Position; - long outBufferSize = context.Request.RecvListBuff[0].Size; + ulong outBufferPosition = context.Request.RecvListBuff[0].Position; + ulong outBufferSize = context.Request.RecvListBuff[0].Size; - context.Memory.Write((ulong)outBufferPosition, posixTime); + context.Memory.Write(outBufferPosition, posixTime); // There could be only one result on one calendar as leap seconds aren't supported. context.ResponseData.Write(1); diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs index b66ffc3f..963ea9fd 100644 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs +++ b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs @@ -5,7 +5,6 @@ using LibHac.Fs.Fsa; using LibHac.FsSystem; using LibHac.FsSystem.NcaUtils; using Ryujinx.Common.Logging; -using Ryujinx.Configuration; using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem.Content; @@ -47,10 +46,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone InitializeLocationNameCache(); } - public string SanityCheckDeviceLocationName() + public string SanityCheckDeviceLocationName(string locationName) { - string locationName = ConfigurationState.Instance.System.TimeZone; - if (IsLocationNameValid(locationName)) { return locationName; @@ -58,8 +55,6 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone Logger.Warning?.Print(LogClass.ServiceTime, $"Invalid device TimeZone {locationName}, switching back to UTC"); - ConfigurationState.Instance.System.TimeZone.Value = "UTC"; - return "UTC"; } @@ -69,7 +64,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone SteadyClockTimePoint timeZoneUpdatedTimePoint = timeManager.StandardSteadyClock.GetCurrentTimePoint(null); - string deviceLocationName = SanityCheckDeviceLocationName(); + string deviceLocationName = SanityCheckDeviceLocationName(device.Configuration.TimeZone); ResultCode result = GetTimeZoneBinary(deviceLocationName, out Stream timeZoneBinaryStream, out LocalStorage ncaFile); diff --git a/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs b/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs index 37e603dc..5f161bee 100644 --- a/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs +++ b/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs @@ -61,16 +61,16 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService // ListDisplays() -> (u64, buffer<nn::vi::DisplayInfo, 6>) public ResultCode ListDisplays(ServiceCtx context) { - long recBuffPtr = context.Request.ReceiveBuff[0].Position; + ulong recBuffPtr = context.Request.ReceiveBuff[0].Position; MemoryHelper.FillWithZeros(context.Memory, recBuffPtr, 0x60); // Add only the default display to buffer - context.Memory.Write((ulong)recBuffPtr, Encoding.ASCII.GetBytes("Default")); - context.Memory.Write((ulong)recBuffPtr + 0x40, 0x1L); - context.Memory.Write((ulong)recBuffPtr + 0x48, 0x1L); - context.Memory.Write((ulong)recBuffPtr + 0x50, 1280L); - context.Memory.Write((ulong)recBuffPtr + 0x58, 720L); + context.Memory.Write(recBuffPtr, Encoding.ASCII.GetBytes("Default")); + context.Memory.Write(recBuffPtr + 0x40, 0x1UL); + context.Memory.Write(recBuffPtr + 0x48, 0x1UL); + context.Memory.Write(recBuffPtr + 0x50, 1280UL); + context.Memory.Write(recBuffPtr + 0x58, 720UL); context.ResponseData.Write(1L); @@ -120,9 +120,9 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService // TODO: support multi display. byte[] displayName = context.RequestData.ReadBytes(0x40); - long layerId = context.RequestData.ReadInt64(); - long userId = context.RequestData.ReadInt64(); - long parcelPtr = context.Request.ReceiveBuff[0].Position; + long layerId = context.RequestData.ReadInt64(); + long userId = context.RequestData.ReadInt64(); + ulong parcelPtr = context.Request.ReceiveBuff[0].Position; IBinder producer = context.Device.System.SurfaceFlinger.OpenLayer(context.Request.HandleDesc.PId, layerId); @@ -134,7 +134,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService ReadOnlySpan<byte> parcelData = parcel.Finish(); - context.Memory.Write((ulong)parcelPtr, parcelData); + context.Memory.Write(parcelPtr, parcelData); context.ResponseData.Write((long)parcelData.Length); @@ -159,7 +159,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService long layerFlags = context.RequestData.ReadInt64(); long displayId = context.RequestData.ReadInt64(); - long parcelPtr = context.Request.ReceiveBuff[0].Position; + ulong parcelPtr = context.Request.ReceiveBuff[0].Position; // TODO: support multi display. Display disp = _displays.GetData<Display>((int)displayId); @@ -174,7 +174,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService ReadOnlySpan<byte> parcelData = parcel.Finish(); - context.Memory.Write((ulong)parcelPtr, parcelData); + context.Memory.Write(parcelPtr, parcelData); context.ResponseData.Write(layerId); context.ResponseData.Write((long)parcelData.Length); @@ -250,11 +250,11 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService // The size of the layer buffer should be an aligned multiple of width * height // because it was created using GetIndirectLayerImageRequiredMemoryInfo as a guide. - long layerBuffPosition = context.Request.ReceiveBuff[0].Position; - long layerBuffSize = context.Request.ReceiveBuff[0].Size; + ulong layerBuffPosition = context.Request.ReceiveBuff[0].Position; + ulong layerBuffSize = context.Request.ReceiveBuff[0].Size; // Fill the layer with zeros. - context.Memory.Fill((ulong)layerBuffPosition, (ulong)layerBuffSize, 0x00); + context.Memory.Fill(layerBuffPosition, layerBuffSize, 0x00); Logger.Stub?.PrintStub(LogClass.ServiceVi); |
