Revert "Adjust naming conventions and general refactoring in HLE Project (#490)" (#526)

This reverts commit 85dbb9559a.
This commit is contained in:
gdkchan 2018-12-04 22:52:39 -02:00 committed by GitHub
parent 85dbb9559a
commit 3615a70cae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
299 changed files with 12276 additions and 12268 deletions

View file

@ -10,13 +10,13 @@ namespace Ryujinx.HLE.HOS.Services.Acc
{
class IAccountService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IAccountService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetUserCount },
{ 1, GetUserExistence },
@ -32,131 +32,131 @@ namespace Ryujinx.HLE.HOS.Services.Acc
}
// GetUserCount() -> i32
public long GetUserCount(ServiceCtx context)
public long GetUserCount(ServiceCtx Context)
{
context.ResponseData.Write(context.Device.System.State.GetUserCount());
Context.ResponseData.Write(Context.Device.System.State.GetUserCount());
return 0;
}
// GetUserExistence(nn::account::Uid) -> bool
public long GetUserExistence(ServiceCtx context)
public long GetUserExistence(ServiceCtx Context)
{
UInt128 uuid = new UInt128(
context.RequestData.ReadInt64(),
context.RequestData.ReadInt64());
UInt128 Uuid = new UInt128(
Context.RequestData.ReadInt64(),
Context.RequestData.ReadInt64());
context.ResponseData.Write(context.Device.System.State.TryGetUser(uuid, out _));
Context.ResponseData.Write(Context.Device.System.State.TryGetUser(Uuid, out _));
return 0;
}
// ListAllUsers() -> array<nn::account::Uid, 0xa>
public long ListAllUsers(ServiceCtx context)
public long ListAllUsers(ServiceCtx Context)
{
return WriteUserList(context, context.Device.System.State.GetAllUsers());
return WriteUserList(Context, Context.Device.System.State.GetAllUsers());
}
// ListOpenUsers() -> array<nn::account::Uid, 0xa>
public long ListOpenUsers(ServiceCtx context)
public long ListOpenUsers(ServiceCtx Context)
{
return WriteUserList(context, context.Device.System.State.GetOpenUsers());
return WriteUserList(Context, Context.Device.System.State.GetOpenUsers());
}
private long WriteUserList(ServiceCtx context, IEnumerable<UserProfile> profiles)
private long WriteUserList(ServiceCtx Context, IEnumerable<UserProfile> Profiles)
{
long outputPosition = context.Request.RecvListBuff[0].Position;
long outputSize = context.Request.RecvListBuff[0].Size;
long OutputPosition = Context.Request.RecvListBuff[0].Position;
long OutputSize = Context.Request.RecvListBuff[0].Size;
long offset = 0;
long Offset = 0;
foreach (UserProfile profile in profiles)
foreach (UserProfile Profile in Profiles)
{
if ((ulong)offset + 16 > (ulong)outputSize)
if ((ulong)Offset + 16 > (ulong)OutputSize)
{
break;
}
context.Memory.WriteInt64(outputPosition, profile.Uuid.Low);
context.Memory.WriteInt64(outputPosition + 8, profile.Uuid.High);
Context.Memory.WriteInt64(OutputPosition, Profile.Uuid.Low);
Context.Memory.WriteInt64(OutputPosition + 8, Profile.Uuid.High);
}
return 0;
}
// GetLastOpenedUser() -> nn::account::Uid
public long GetLastOpenedUser(ServiceCtx context)
public long GetLastOpenedUser(ServiceCtx Context)
{
UserProfile lastOpened = context.Device.System.State.LastOpenUser;
UserProfile LastOpened = Context.Device.System.State.LastOpenUser;
lastOpened.Uuid.Write(context.ResponseData);
LastOpened.Uuid.Write(Context.ResponseData);
return 0;
}
// GetProfile(nn::account::Uid) -> object<nn::account::profile::IProfile>
public long GetProfile(ServiceCtx context)
public long GetProfile(ServiceCtx Context)
{
UInt128 uuid = new UInt128(
context.RequestData.ReadInt64(),
context.RequestData.ReadInt64());
UInt128 Uuid = new UInt128(
Context.RequestData.ReadInt64(),
Context.RequestData.ReadInt64());
if (!context.Device.System.State.TryGetUser(uuid, out UserProfile profile))
if (!Context.Device.System.State.TryGetUser(Uuid, out UserProfile Profile))
{
Logger.PrintWarning(LogClass.ServiceAcc, $"User 0x{uuid} not found!");
Logger.PrintWarning(LogClass.ServiceAcc, $"User 0x{Uuid} not found!");
return MakeError(ErrorModule.Account, AccErr.UserNotFound);
}
MakeObject(context, new IProfile(profile));
MakeObject(Context, new IProfile(Profile));
return 0;
}
// IsUserRegistrationRequestPermitted(u64, pid) -> bool
public long IsUserRegistrationRequestPermitted(ServiceCtx context)
public long IsUserRegistrationRequestPermitted(ServiceCtx Context)
{
long unknown = context.RequestData.ReadInt64();
long Unknown = Context.RequestData.ReadInt64();
Logger.PrintStub(LogClass.ServiceAcc, $"Stubbed. Unknown: {unknown}");
Logger.PrintStub(LogClass.ServiceAcc, $"Stubbed. Unknown: {Unknown}");
context.ResponseData.Write(false);
Context.ResponseData.Write(false);
return 0;
}
// TrySelectUserWithoutInteraction(bool) -> nn::account::Uid
public long TrySelectUserWithoutInteraction(ServiceCtx context)
public long TrySelectUserWithoutInteraction(ServiceCtx Context)
{
bool unknown = context.RequestData.ReadBoolean();
bool Unknown = Context.RequestData.ReadBoolean();
Logger.PrintStub(LogClass.ServiceAcc, $"Stubbed. Unknown: {unknown}");
Logger.PrintStub(LogClass.ServiceAcc, $"Stubbed. Unknown: {Unknown}");
UserProfile profile = context.Device.System.State.LastOpenUser;
UserProfile Profile = Context.Device.System.State.LastOpenUser;
profile.Uuid.Write(context.ResponseData);
Profile.Uuid.Write(Context.ResponseData);
return 0;
}
// InitializeApplicationInfo(u64, pid)
public long InitializeApplicationInfo(ServiceCtx context)
public long InitializeApplicationInfo(ServiceCtx Context)
{
long unknown = context.RequestData.ReadInt64();
long Unknown = Context.RequestData.ReadInt64();
Logger.PrintStub(LogClass.ServiceAcc, $"Stubbed. Unknown: {unknown}");
Logger.PrintStub(LogClass.ServiceAcc, $"Stubbed. Unknown: {Unknown}");
return 0;
}
// GetBaasAccountManagerForApplication(nn::account::Uid) -> object<nn::account::baas::IManagerForApplication>
public long GetBaasAccountManagerForApplication(ServiceCtx context)
public long GetBaasAccountManagerForApplication(ServiceCtx Context)
{
UInt128 uuid = new UInt128(
context.RequestData.ReadInt64(),
context.RequestData.ReadInt64());
UInt128 Uuid = new UInt128(
Context.RequestData.ReadInt64(),
Context.RequestData.ReadInt64());
MakeObject(context, new IManagerForApplication(uuid));
MakeObject(Context, new IManagerForApplication(Uuid));
return 0;
}

View file

@ -7,25 +7,25 @@ namespace Ryujinx.HLE.HOS.Services.Acc
{
class IManagerForApplication : IpcService
{
private UInt128 _uuid;
private UInt128 Uuid;
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IManagerForApplication(UInt128 uuid)
public IManagerForApplication(UInt128 Uuid)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, CheckAvailability },
{ 1, GetAccountId }
};
_uuid = uuid;
this.Uuid = Uuid;
}
// CheckAvailability()
public long CheckAvailability(ServiceCtx context)
public long CheckAvailability(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAcc, "Stubbed.");
@ -33,13 +33,13 @@ namespace Ryujinx.HLE.HOS.Services.Acc
}
// GetAccountId() -> nn::account::NetworkServiceAccountId
public long GetAccountId(ServiceCtx context)
public long GetAccountId(ServiceCtx Context)
{
long networkServiceAccountId = 0xcafe;
long NetworkServiceAccountId = 0xcafe;
Logger.PrintStub(LogClass.ServiceAcc, $"Stubbed. NetworkServiceAccountId: {networkServiceAccountId}");
Logger.PrintStub(LogClass.ServiceAcc, $"Stubbed. NetworkServiceAccountId: {NetworkServiceAccountId}");
context.ResponseData.Write(networkServiceAccountId);
Context.ResponseData.Write(NetworkServiceAccountId);
return 0;
}

View file

@ -12,76 +12,76 @@ namespace Ryujinx.HLE.HOS.Services.Acc
{
class IProfile : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private UserProfile _profile;
private UserProfile Profile;
private Stream _profilePictureStream;
private Stream ProfilePictureStream;
public IProfile(UserProfile profile)
public IProfile(UserProfile Profile)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Get },
{ 1, GetBase },
{ 10, GetImageSize },
{ 11, LoadImage }
{ 11, LoadImage },
};
_profile = profile;
this.Profile = Profile;
_profilePictureStream = Assembly.GetCallingAssembly().GetManifestResourceStream("Ryujinx.HLE.RyujinxProfileImage.jpg");
ProfilePictureStream = Assembly.GetCallingAssembly().GetManifestResourceStream("Ryujinx.HLE.RyujinxProfileImage.jpg");
}
public long Get(ServiceCtx context)
public long Get(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAcc, "Stubbed.");
long position = context.Request.ReceiveBuff[0].Position;
long Position = Context.Request.ReceiveBuff[0].Position;
MemoryHelper.FillWithZeros(context.Memory, position, 0x80);
MemoryHelper.FillWithZeros(Context.Memory, Position, 0x80);
context.Memory.WriteInt32(position, 0);
context.Memory.WriteInt32(position + 4, 1);
context.Memory.WriteInt64(position + 8, 1);
Context.Memory.WriteInt32(Position, 0);
Context.Memory.WriteInt32(Position + 4, 1);
Context.Memory.WriteInt64(Position + 8, 1);
return GetBase(context);
return GetBase(Context);
}
public long GetBase(ServiceCtx context)
public long GetBase(ServiceCtx Context)
{
_profile.Uuid.Write(context.ResponseData);
Profile.Uuid.Write(Context.ResponseData);
context.ResponseData.Write(_profile.LastModifiedTimestamp);
Context.ResponseData.Write(Profile.LastModifiedTimestamp);
byte[] username = StringUtils.GetFixedLengthBytes(_profile.Name, 0x20, Encoding.UTF8);
byte[] Username = StringUtils.GetFixedLengthBytes(Profile.Name, 0x20, Encoding.UTF8);
context.ResponseData.Write(username);
Context.ResponseData.Write(Username);
return 0;
}
private long LoadImage(ServiceCtx context)
private long LoadImage(ServiceCtx Context)
{
long bufferPosition = context.Request.ReceiveBuff[0].Position;
long bufferLen = context.Request.ReceiveBuff[0].Size;
long BufferPosition = Context.Request.ReceiveBuff[0].Position;
long BufferLen = Context.Request.ReceiveBuff[0].Size;
byte[] profilePictureData = new byte[bufferLen];
byte[] ProfilePictureData = new byte[BufferLen];
_profilePictureStream.Read(profilePictureData, 0, profilePictureData.Length);
ProfilePictureStream.Read(ProfilePictureData, 0, ProfilePictureData.Length);
context.Memory.WriteBytes(bufferPosition, profilePictureData);
Context.Memory.WriteBytes(BufferPosition, ProfilePictureData);
context.ResponseData.Write(_profilePictureStream.Length);
Context.ResponseData.Write(ProfilePictureStream.Length);
return 0;
}
private long GetImageSize(ServiceCtx context)
private long GetImageSize(ServiceCtx Context)
{
context.ResponseData.Write(_profilePictureStream.Length);
Context.ResponseData.Write(ProfilePictureStream.Length);
return 0;
}

View file

@ -5,21 +5,21 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IAllSystemAppletProxiesService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IAllSystemAppletProxiesService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 100, OpenSystemAppletProxy }
};
}
public long OpenSystemAppletProxy(ServiceCtx context)
public long OpenSystemAppletProxy(ServiceCtx Context)
{
MakeObject(context, new ISystemAppletProxy());
MakeObject(Context, new ISystemAppletProxy());
return 0;
}

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IApplicationCreator : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IApplicationCreator()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -6,13 +6,13 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IApplicationFunctions : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IApplicationFunctions()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 1, PopLaunchParameter },
{ 20, EnsureSaveData },
@ -26,88 +26,88 @@ namespace Ryujinx.HLE.HOS.Services.Am
};
}
public long PopLaunchParameter(ServiceCtx context)
public long PopLaunchParameter(ServiceCtx Context)
{
//Only the first 0x18 bytes of the Data seems to be actually used.
MakeObject(context, new IStorage(StorageHelper.MakeLaunchParams()));
MakeObject(Context, new IStorage(StorageHelper.MakeLaunchParams()));
return 0;
}
public long EnsureSaveData(ServiceCtx context)
public long EnsureSaveData(ServiceCtx Context)
{
long uIdLow = context.RequestData.ReadInt64();
long uIdHigh = context.RequestData.ReadInt64();
long UIdLow = Context.RequestData.ReadInt64();
long UIdHigh = Context.RequestData.ReadInt64();
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
context.ResponseData.Write(0L);
Context.ResponseData.Write(0L);
return 0;
}
public long GetDesiredLanguage(ServiceCtx context)
public long GetDesiredLanguage(ServiceCtx Context)
{
context.ResponseData.Write(context.Device.System.State.DesiredLanguageCode);
Context.ResponseData.Write(Context.Device.System.State.DesiredLanguageCode);
return 0;
}
public long SetTerminateResult(ServiceCtx context)
public long SetTerminateResult(ServiceCtx Context)
{
int errorCode = context.RequestData.ReadInt32();
int ErrorCode = Context.RequestData.ReadInt32();
string result = GetFormattedErrorCode(errorCode);
string Result = GetFormattedErrorCode(ErrorCode);
Logger.PrintInfo(LogClass.ServiceAm, $"Result = 0x{errorCode:x8} ({result}).");
Logger.PrintInfo(LogClass.ServiceAm, $"Result = 0x{ErrorCode:x8} ({Result}).");
return 0;
}
private string GetFormattedErrorCode(int errorCode)
private string GetFormattedErrorCode(int ErrorCode)
{
int module = (errorCode >> 0) & 0x1ff;
int description = (errorCode >> 9) & 0x1fff;
int Module = (ErrorCode >> 0) & 0x1ff;
int Description = (ErrorCode >> 9) & 0x1fff;
return $"{(2000 + module):d4}-{description:d4}";
return $"{(2000 + Module):d4}-{Description:d4}";
}
public long GetDisplayVersion(ServiceCtx context)
public long GetDisplayVersion(ServiceCtx Context)
{
//FIXME: Need to check correct version on a switch.
context.ResponseData.Write(1L);
context.ResponseData.Write(0L);
Context.ResponseData.Write(1L);
Context.ResponseData.Write(0L);
return 0;
}
public long NotifyRunning(ServiceCtx context)
public long NotifyRunning(ServiceCtx Context)
{
context.ResponseData.Write(1);
Context.ResponseData.Write(1);
return 0;
}
public long GetPseudoDeviceId(ServiceCtx context)
public long GetPseudoDeviceId(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
context.ResponseData.Write(0L);
context.ResponseData.Write(0L);
Context.ResponseData.Write(0L);
Context.ResponseData.Write(0L);
return 0;
}
public long InitializeGamePlayRecording(ServiceCtx context)
public long InitializeGamePlayRecording(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetGamePlayRecordingState(ServiceCtx context)
public long SetGamePlayRecordingState(ServiceCtx Context)
{
int state = context.RequestData.ReadInt32();
int State = Context.RequestData.ReadInt32();
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IApplicationProxy : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IApplicationProxy()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetCommonStateGetter },
{ 1, GetSelfController },
@ -24,58 +24,58 @@ namespace Ryujinx.HLE.HOS.Services.Am
};
}
public long GetCommonStateGetter(ServiceCtx context)
public long GetCommonStateGetter(ServiceCtx Context)
{
MakeObject(context, new ICommonStateGetter(context.Device.System));
MakeObject(Context, new ICommonStateGetter(Context.Device.System));
return 0;
}
public long GetSelfController(ServiceCtx context)
public long GetSelfController(ServiceCtx Context)
{
MakeObject(context, new ISelfController(context.Device.System));
MakeObject(Context, new ISelfController(Context.Device.System));
return 0;
}
public long GetWindowController(ServiceCtx context)
public long GetWindowController(ServiceCtx Context)
{
MakeObject(context, new IWindowController());
MakeObject(Context, new IWindowController());
return 0;
}
public long GetAudioController(ServiceCtx context)
public long GetAudioController(ServiceCtx Context)
{
MakeObject(context, new IAudioController());
MakeObject(Context, new IAudioController());
return 0;
}
public long GetDisplayController(ServiceCtx context)
public long GetDisplayController(ServiceCtx Context)
{
MakeObject(context, new IDisplayController());
MakeObject(Context, new IDisplayController());
return 0;
}
public long GetLibraryAppletCreator(ServiceCtx context)
public long GetLibraryAppletCreator(ServiceCtx Context)
{
MakeObject(context, new ILibraryAppletCreator());
MakeObject(Context, new ILibraryAppletCreator());
return 0;
}
public long GetApplicationFunctions(ServiceCtx context)
public long GetApplicationFunctions(ServiceCtx Context)
{
MakeObject(context, new IApplicationFunctions());
MakeObject(Context, new IApplicationFunctions());
return 0;
}
public long GetDebugFunctions(ServiceCtx context)
public long GetDebugFunctions(ServiceCtx Context)
{
MakeObject(context, new IDebugFunctions());
MakeObject(Context, new IDebugFunctions());
return 0;
}

View file

@ -5,21 +5,21 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IApplicationProxyService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IApplicationProxyService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, OpenApplicationProxy }
};
}
public long OpenApplicationProxy(ServiceCtx context)
public long OpenApplicationProxy(ServiceCtx Context)
{
MakeObject(context, new IApplicationProxy());
MakeObject(Context, new IApplicationProxy());
return 0;
}

View file

@ -6,13 +6,13 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IAudioController : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IAudioController()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, SetExpectedMasterVolume },
{ 1, GetMainAppletExpectedMasterVolume },
@ -22,47 +22,47 @@ namespace Ryujinx.HLE.HOS.Services.Am
};
}
public long SetExpectedMasterVolume(ServiceCtx context)
public long SetExpectedMasterVolume(ServiceCtx Context)
{
float appletVolume = context.RequestData.ReadSingle();
float libraryAppletVolume = context.RequestData.ReadSingle();
float AppletVolume = Context.RequestData.ReadSingle();
float LibraryAppletVolume = Context.RequestData.ReadSingle();
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long GetMainAppletExpectedMasterVolume(ServiceCtx context)
public long GetMainAppletExpectedMasterVolume(ServiceCtx Context)
{
context.ResponseData.Write(1f);
Context.ResponseData.Write(1f);
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long GetLibraryAppletExpectedMasterVolume(ServiceCtx context)
public long GetLibraryAppletExpectedMasterVolume(ServiceCtx Context)
{
context.ResponseData.Write(1f);
Context.ResponseData.Write(1f);
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long ChangeMainAppletMasterVolume(ServiceCtx context)
public long ChangeMainAppletMasterVolume(ServiceCtx Context)
{
float unknown0 = context.RequestData.ReadSingle();
long unknown1 = context.RequestData.ReadInt64();
float Unknown0 = Context.RequestData.ReadSingle();
long Unknown1 = Context.RequestData.ReadInt64();
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetTransparentVolumeRate(ServiceCtx context)
public long SetTransparentVolumeRate(ServiceCtx Context)
{
float unknown0 = context.RequestData.ReadSingle();
float Unknown0 = Context.RequestData.ReadSingle();
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");

View file

@ -10,15 +10,15 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class ICommonStateGetter : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent _displayResolutionChangeEvent;
private KEvent DisplayResolutionChangeEvent;
public ICommonStateGetter(Horizon system)
public ICommonStateGetter(Horizon System)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetEventHandle },
{ 1, ReceiveMessage },
@ -30,89 +30,89 @@ namespace Ryujinx.HLE.HOS.Services.Am
{ 61, GetDefaultDisplayResolutionChangeEvent }
};
_displayResolutionChangeEvent = new KEvent(system);
DisplayResolutionChangeEvent = new KEvent(System);
}
public long GetEventHandle(ServiceCtx context)
public long GetEventHandle(ServiceCtx Context)
{
KEvent Event = context.Device.System.AppletState.MessageEvent;
KEvent Event = Context.Device.System.AppletState.MessageEvent;
if (context.Process.HandleTable.GenerateHandle(Event.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(Event.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
return 0;
}
public long ReceiveMessage(ServiceCtx context)
public long ReceiveMessage(ServiceCtx Context)
{
if (!context.Device.System.AppletState.TryDequeueMessage(out MessageInfo message))
if (!Context.Device.System.AppletState.TryDequeueMessage(out MessageInfo Message))
{
return MakeError(ErrorModule.Am, AmErr.NoMessages);
}
context.ResponseData.Write((int)message);
Context.ResponseData.Write((int)Message);
return 0;
}
public long GetOperationMode(ServiceCtx context)
public long GetOperationMode(ServiceCtx Context)
{
OperationMode mode = context.Device.System.State.DockedMode
OperationMode Mode = Context.Device.System.State.DockedMode
? OperationMode.Docked
: OperationMode.Handheld;
context.ResponseData.Write((byte)mode);
Context.ResponseData.Write((byte)Mode);
return 0;
}
public long GetPerformanceMode(ServiceCtx context)
public long GetPerformanceMode(ServiceCtx Context)
{
Apm.PerformanceMode mode = context.Device.System.State.DockedMode
Apm.PerformanceMode Mode = Context.Device.System.State.DockedMode
? Apm.PerformanceMode.Docked
: Apm.PerformanceMode.Handheld;
context.ResponseData.Write((int)mode);
Context.ResponseData.Write((int)Mode);
return 0;
}
public long GetBootMode(ServiceCtx context)
public long GetBootMode(ServiceCtx Context)
{
context.ResponseData.Write((byte)0); //Unknown value.
Context.ResponseData.Write((byte)0); //Unknown value.
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long GetCurrentFocusState(ServiceCtx context)
public long GetCurrentFocusState(ServiceCtx Context)
{
context.ResponseData.Write((byte)context.Device.System.AppletState.FocusState);
Context.ResponseData.Write((byte)Context.Device.System.AppletState.FocusState);
return 0;
}
public long GetDefaultDisplayResolution(ServiceCtx context)
public long GetDefaultDisplayResolution(ServiceCtx Context)
{
context.ResponseData.Write(1280);
context.ResponseData.Write(720);
Context.ResponseData.Write(1280);
Context.ResponseData.Write(720);
return 0;
}
public long GetDefaultDisplayResolutionChangeEvent(ServiceCtx context)
public long GetDefaultDisplayResolutionChangeEvent(ServiceCtx Context)
{
if (context.Process.HandleTable.GenerateHandle(_displayResolutionChangeEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(DisplayResolutionChangeEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IDebugFunctions : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IDebugFunctions()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IDisplayController : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IDisplayController()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IGlobalStateController : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IGlobalStateController()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -8,39 +8,39 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IHomeMenuFunctions : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent _channelEvent;
private KEvent ChannelEvent;
public IHomeMenuFunctions(Horizon system)
public IHomeMenuFunctions(Horizon System)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 10, RequestToGetForeground },
{ 21, GetPopFromGeneralChannelEvent }
};
//ToDo: Signal this Event somewhere in future.
_channelEvent = new KEvent(system);
ChannelEvent = new KEvent(System);
}
public long RequestToGetForeground(ServiceCtx context)
public long RequestToGetForeground(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long GetPopFromGeneralChannelEvent(ServiceCtx context)
public long GetPopFromGeneralChannelEvent(ServiceCtx Context)
{
if (context.Process.HandleTable.GenerateHandle(_channelEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(ChannelEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");

View file

@ -8,15 +8,15 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class ILibraryAppletAccessor : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent _stateChangedEvent;
private KEvent StateChangedEvent;
public ILibraryAppletAccessor(Horizon system)
public ILibraryAppletAccessor(Horizon System)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetAppletStateChangedEvent },
{ 10, Start },
@ -25,49 +25,49 @@ namespace Ryujinx.HLE.HOS.Services.Am
{ 101, PopOutData }
};
_stateChangedEvent = new KEvent(system);
StateChangedEvent = new KEvent(System);
}
public long GetAppletStateChangedEvent(ServiceCtx context)
public long GetAppletStateChangedEvent(ServiceCtx Context)
{
_stateChangedEvent.ReadableEvent.Signal();
StateChangedEvent.ReadableEvent.Signal();
if (context.Process.HandleTable.GenerateHandle(_stateChangedEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(StateChangedEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long Start(ServiceCtx context)
public long Start(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long GetResult(ServiceCtx context)
public long GetResult(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long PushInData(ServiceCtx context)
public long PushInData(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long PopOutData(ServiceCtx context)
public long PopOutData(ServiceCtx Context)
{
MakeObject(context, new IStorage(StorageHelper.MakeLaunchParams()));
MakeObject(Context, new IStorage(StorageHelper.MakeLaunchParams()));
return 0;
}

View file

@ -5,31 +5,31 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class ILibraryAppletCreator : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ILibraryAppletCreator()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, CreateLibraryApplet },
{ 10, CreateStorage }
};
}
public long CreateLibraryApplet(ServiceCtx context)
public long CreateLibraryApplet(ServiceCtx Context)
{
MakeObject(context, new ILibraryAppletAccessor(context.Device.System));
MakeObject(Context, new ILibraryAppletAccessor(Context.Device.System));
return 0;
}
public long CreateStorage(ServiceCtx context)
public long CreateStorage(ServiceCtx Context)
{
long size = context.RequestData.ReadInt64();
long Size = Context.RequestData.ReadInt64();
MakeObject(context, new IStorage(new byte[size]));
MakeObject(Context, new IStorage(new byte[Size]));
return 0;
}

View file

@ -8,17 +8,17 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class ISelfController : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent _launchableEvent;
private KEvent LaunchableEvent;
private int _idleTimeDetectionExtension;
private int IdleTimeDetectionExtension;
public ISelfController(Horizon system)
public ISelfController(Horizon System)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Exit },
{ 1, LockExit },
@ -36,114 +36,114 @@ namespace Ryujinx.HLE.HOS.Services.Am
{ 63, GetIdleTimeDetectionExtension }
};
_launchableEvent = new KEvent(system);
LaunchableEvent = new KEvent(System);
}
public long Exit(ServiceCtx context)
public long Exit(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long LockExit(ServiceCtx context)
public long LockExit(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long UnlockExit(ServiceCtx context)
public long UnlockExit(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long GetLibraryAppletLaunchableEvent(ServiceCtx context)
public long GetLibraryAppletLaunchableEvent(ServiceCtx Context)
{
_launchableEvent.ReadableEvent.Signal();
LaunchableEvent.ReadableEvent.Signal();
if (context.Process.HandleTable.GenerateHandle(_launchableEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(LaunchableEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetScreenShotPermission(ServiceCtx context)
public long SetScreenShotPermission(ServiceCtx Context)
{
bool enable = context.RequestData.ReadByte() != 0;
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetOperationModeChangedNotification(ServiceCtx context)
public long SetOperationModeChangedNotification(ServiceCtx Context)
{
bool enable = context.RequestData.ReadByte() != 0;
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetPerformanceModeChangedNotification(ServiceCtx context)
public long SetPerformanceModeChangedNotification(ServiceCtx Context)
{
bool enable = context.RequestData.ReadByte() != 0;
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetFocusHandlingMode(ServiceCtx context)
public long SetFocusHandlingMode(ServiceCtx Context)
{
bool flag1 = context.RequestData.ReadByte() != 0;
bool flag2 = context.RequestData.ReadByte() != 0;
bool flag3 = context.RequestData.ReadByte() != 0;
bool Flag1 = Context.RequestData.ReadByte() != 0 ? true : false;
bool Flag2 = Context.RequestData.ReadByte() != 0 ? true : false;
bool Flag3 = Context.RequestData.ReadByte() != 0 ? true : false;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetRestartMessageEnabled(ServiceCtx context)
public long SetRestartMessageEnabled(ServiceCtx Context)
{
bool enable = context.RequestData.ReadByte() != 0;
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetOutOfFocusSuspendingEnabled(ServiceCtx context)
public long SetOutOfFocusSuspendingEnabled(ServiceCtx Context)
{
bool enable = context.RequestData.ReadByte() != 0;
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetScreenShotImageOrientation(ServiceCtx context)
public long SetScreenShotImageOrientation(ServiceCtx Context)
{
int orientation = context.RequestData.ReadInt32();
int Orientation = Context.RequestData.ReadInt32();
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetHandlesRequestToDisplay(ServiceCtx context)
public long SetHandlesRequestToDisplay(ServiceCtx Context)
{
bool enable = context.RequestData.ReadByte() != 0;
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
@ -151,21 +151,21 @@ namespace Ryujinx.HLE.HOS.Services.Am
}
// SetIdleTimeDetectionExtension(u32)
public long SetIdleTimeDetectionExtension(ServiceCtx context)
public long SetIdleTimeDetectionExtension(ServiceCtx Context)
{
_idleTimeDetectionExtension = context.RequestData.ReadInt32();
IdleTimeDetectionExtension = Context.RequestData.ReadInt32();
Logger.PrintStub(LogClass.ServiceAm, $"Stubbed. IdleTimeDetectionExtension: {_idleTimeDetectionExtension}");
Logger.PrintStub(LogClass.ServiceAm, $"Stubbed. IdleTimeDetectionExtension: {IdleTimeDetectionExtension}");
return 0;
}
// GetIdleTimeDetectionExtension() -> u32
public long GetIdleTimeDetectionExtension(ServiceCtx context)
public long GetIdleTimeDetectionExtension(ServiceCtx Context)
{
context.ResponseData.Write(_idleTimeDetectionExtension);
Context.ResponseData.Write(IdleTimeDetectionExtension);
Logger.PrintStub(LogClass.ServiceAm, $"Stubbed. IdleTimeDetectionExtension: {_idleTimeDetectionExtension}");
Logger.PrintStub(LogClass.ServiceAm, $"Stubbed. IdleTimeDetectionExtension: {IdleTimeDetectionExtension}");
return 0;
}

View file

@ -5,25 +5,25 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IStorage : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public byte[] Data { get; }
public byte[] Data { get; private set; }
public IStorage(byte[] data)
public IStorage(byte[] Data)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Open }
};
Data = data;
this.Data = Data;
}
public long Open(ServiceCtx context)
public long Open(ServiceCtx Context)
{
MakeObject(context, new IStorageAccessor(this));
MakeObject(Context, new IStorageAccessor(this));
return 0;
}

View file

@ -6,76 +6,76 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IStorageAccessor : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private IStorage _storage;
private IStorage Storage;
public IStorageAccessor(IStorage storage)
public IStorageAccessor(IStorage Storage)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetSize },
{ 10, Write },
{ 11, Read }
};
_storage = storage;
this.Storage = Storage;
}
public long GetSize(ServiceCtx context)
public long GetSize(ServiceCtx Context)
{
context.ResponseData.Write((long)_storage.Data.Length);
Context.ResponseData.Write((long)Storage.Data.Length);
return 0;
}
public long Write(ServiceCtx context)
public long Write(ServiceCtx Context)
{
//TODO: Error conditions.
long writePosition = context.RequestData.ReadInt64();
long WritePosition = Context.RequestData.ReadInt64();
(long position, long size) = context.Request.GetBufferType0x21();
(long Position, long Size) = Context.Request.GetBufferType0x21();
if (size > 0)
if (Size > 0)
{
long maxSize = _storage.Data.Length - writePosition;
long MaxSize = Storage.Data.Length - WritePosition;
if (size > maxSize)
if (Size > MaxSize)
{
size = maxSize;
Size = MaxSize;
}
byte[] data = context.Memory.ReadBytes(position, size);
byte[] Data = Context.Memory.ReadBytes(Position, Size);
Buffer.BlockCopy(data, 0, _storage.Data, (int)writePosition, (int)size);
Buffer.BlockCopy(Data, 0, Storage.Data, (int)WritePosition, (int)Size);
}
return 0;
}
public long Read(ServiceCtx context)
public long Read(ServiceCtx Context)
{
//TODO: Error conditions.
long readPosition = context.RequestData.ReadInt64();
long ReadPosition = Context.RequestData.ReadInt64();
(long position, long size) = context.Request.GetBufferType0x22();
(long Position, long Size) = Context.Request.GetBufferType0x22();
byte[] data;
byte[] Data;
if (_storage.Data.Length > size)
if (Storage.Data.Length > Size)
{
data = new byte[size];
Data = new byte[Size];
Buffer.BlockCopy(_storage.Data, 0, data, 0, (int)size);
Buffer.BlockCopy(Storage.Data, 0, Data, 0, (int)Size);
}
else
{
data = _storage.Data;
Data = Storage.Data;
}
context.Memory.WriteBytes(position, data);
Context.Memory.WriteBytes(Position, Data);
return 0;
}

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class ISystemAppletProxy : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ISystemAppletProxy()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetCommonStateGetter },
{ 1, GetSelfController },
@ -26,72 +26,72 @@ namespace Ryujinx.HLE.HOS.Services.Am
};
}
public long GetCommonStateGetter(ServiceCtx context)
public long GetCommonStateGetter(ServiceCtx Context)
{
MakeObject(context, new ICommonStateGetter(context.Device.System));
MakeObject(Context, new ICommonStateGetter(Context.Device.System));
return 0;
}
public long GetSelfController(ServiceCtx context)
public long GetSelfController(ServiceCtx Context)
{
MakeObject(context, new ISelfController(context.Device.System));
MakeObject(Context, new ISelfController(Context.Device.System));
return 0;
}
public long GetWindowController(ServiceCtx context)
public long GetWindowController(ServiceCtx Context)
{
MakeObject(context, new IWindowController());
MakeObject(Context, new IWindowController());
return 0;
}
public long GetAudioController(ServiceCtx context)
public long GetAudioController(ServiceCtx Context)
{
MakeObject(context, new IAudioController());
MakeObject(Context, new IAudioController());
return 0;
}
public long GetDisplayController(ServiceCtx context)
public long GetDisplayController(ServiceCtx Context)
{
MakeObject(context, new IDisplayController());
MakeObject(Context, new IDisplayController());
return 0;
}
public long GetLibraryAppletCreator(ServiceCtx context)
public long GetLibraryAppletCreator(ServiceCtx Context)
{
MakeObject(context, new ILibraryAppletCreator());
MakeObject(Context, new ILibraryAppletCreator());
return 0;
}
public long GetHomeMenuFunctions(ServiceCtx context)
public long GetHomeMenuFunctions(ServiceCtx Context)
{
MakeObject(context, new IHomeMenuFunctions(context.Device.System));
MakeObject(Context, new IHomeMenuFunctions(Context.Device.System));
return 0;
}
public long GetGlobalStateController(ServiceCtx context)
public long GetGlobalStateController(ServiceCtx Context)
{
MakeObject(context, new IGlobalStateController());
MakeObject(Context, new IGlobalStateController());
return 0;
}
public long GetApplicationCreator(ServiceCtx context)
public long GetApplicationCreator(ServiceCtx Context)
{
MakeObject(context, new IApplicationCreator());
MakeObject(Context, new IApplicationCreator());
return 0;
}
public long GetDebugFunctions(ServiceCtx context)
public long GetDebugFunctions(ServiceCtx Context)
{
MakeObject(context, new IDebugFunctions());
MakeObject(Context, new IDebugFunctions());
return 0;
}

View file

@ -6,29 +6,29 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IWindowController : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IWindowController()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 1, GetAppletResourceUserId },
{ 10, AcquireForegroundRights }
};
}
public long GetAppletResourceUserId(ServiceCtx context)
public long GetAppletResourceUserId(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
context.ResponseData.Write(0L);
Context.ResponseData.Write(0L);
return 0;
}
public long AcquireForegroundRights(ServiceCtx context)
public long AcquireForegroundRights(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");

View file

@ -9,18 +9,18 @@ namespace Ryujinx.HLE.HOS.Services.Am
public static byte[] MakeLaunchParams()
{
//Size needs to be at least 0x88 bytes otherwise application errors.
using (MemoryStream ms = new MemoryStream())
using (MemoryStream MS = new MemoryStream())
{
BinaryWriter writer = new BinaryWriter(ms);
BinaryWriter Writer = new BinaryWriter(MS);
ms.SetLength(0x88);
MS.SetLength(0x88);
writer.Write(LaunchParamsMagic);
writer.Write(1); //IsAccountSelected? Only lower 8 bits actually used.
writer.Write(1L); //User Id Low (note: User Id needs to be != 0)
writer.Write(0L); //User Id High
Writer.Write(LaunchParamsMagic);
Writer.Write(1); //IsAccountSelected? Only lower 8 bits actually used.
Writer.Write(1L); //User Id Low (note: User Id needs to be != 0)
Writer.Write(0L); //User Id High
return ms.ToArray();
return MS.ToArray();
}
}
}

View file

@ -5,21 +5,21 @@ namespace Ryujinx.HLE.HOS.Services.Apm
{
class IManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IManager()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, OpenSession }
};
}
public long OpenSession(ServiceCtx context)
public long OpenSession(ServiceCtx Context)
{
MakeObject(context, new ISession());
MakeObject(Context, new ISession());
return 0;
}

View file

@ -6,32 +6,32 @@ namespace Ryujinx.HLE.HOS.Services.Apm
{
class ISession : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ISession()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, SetPerformanceConfiguration },
{ 1, GetPerformanceConfiguration }
};
}
public long SetPerformanceConfiguration(ServiceCtx context)
public long SetPerformanceConfiguration(ServiceCtx Context)
{
PerformanceMode perfMode = (PerformanceMode)context.RequestData.ReadInt32();
PerformanceConfiguration perfConfig = (PerformanceConfiguration)context.RequestData.ReadInt32();
PerformanceMode PerfMode = (PerformanceMode)Context.RequestData.ReadInt32();
PerformanceConfiguration PerfConfig = (PerformanceConfiguration)Context.RequestData.ReadInt32();
return 0;
}
public long GetPerformanceConfiguration(ServiceCtx context)
public long GetPerformanceConfiguration(ServiceCtx Context)
{
PerformanceMode perfMode = (PerformanceMode)context.RequestData.ReadInt32();
PerformanceMode PerfMode = (PerformanceMode)Context.RequestData.ReadInt32();
context.ResponseData.Write((uint)PerformanceConfiguration.PerformanceConfiguration1);
Context.ResponseData.Write((uint)PerformanceConfiguration.PerformanceConfiguration1);
Logger.PrintStub(LogClass.ServiceApm, "Stubbed.");

View file

@ -9,19 +9,19 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
{
class IAudioOut : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private IAalOutput _audioOut;
private IAalOutput AudioOut;
private KEvent _releaseEvent;
private KEvent ReleaseEvent;
private int _track;
private int Track;
public IAudioOut(IAalOutput audioOut, KEvent releaseEvent, int track)
public IAudioOut(IAalOutput AudioOut, KEvent ReleaseEvent, int Track)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetAudioOutState },
{ 1, StartAudioOut },
@ -34,116 +34,116 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
{ 8, GetReleasedAudioOutBufferAuto }
};
_audioOut = audioOut;
_releaseEvent = releaseEvent;
_track = track;
this.AudioOut = AudioOut;
this.ReleaseEvent = ReleaseEvent;
this.Track = Track;
}
public long GetAudioOutState(ServiceCtx context)
public long GetAudioOutState(ServiceCtx Context)
{
context.ResponseData.Write((int)_audioOut.GetState(_track));
Context.ResponseData.Write((int)AudioOut.GetState(Track));
return 0;
}
public long StartAudioOut(ServiceCtx context)
public long StartAudioOut(ServiceCtx Context)
{
_audioOut.Start(_track);
AudioOut.Start(Track);
return 0;
}
public long StopAudioOut(ServiceCtx context)
public long StopAudioOut(ServiceCtx Context)
{
_audioOut.Stop(_track);
AudioOut.Stop(Track);
return 0;
}
public long AppendAudioOutBuffer(ServiceCtx context)
public long AppendAudioOutBuffer(ServiceCtx Context)
{
return AppendAudioOutBufferImpl(context, context.Request.SendBuff[0].Position);
return AppendAudioOutBufferImpl(Context, Context.Request.SendBuff[0].Position);
}
public long RegisterBufferEvent(ServiceCtx context)
public long RegisterBufferEvent(ServiceCtx Context)
{
if (context.Process.HandleTable.GenerateHandle(_releaseEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(ReleaseEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
return 0;
}
public long GetReleasedAudioOutBuffer(ServiceCtx context)
public long GetReleasedAudioOutBuffer(ServiceCtx Context)
{
long position = context.Request.ReceiveBuff[0].Position;
long size = context.Request.ReceiveBuff[0].Size;
long Position = Context.Request.ReceiveBuff[0].Position;
long Size = Context.Request.ReceiveBuff[0].Size;
return GetReleasedAudioOutBufferImpl(context, position, size);
return GetReleasedAudioOutBufferImpl(Context, Position, Size);
}
public long ContainsAudioOutBuffer(ServiceCtx context)
public long ContainsAudioOutBuffer(ServiceCtx Context)
{
long tag = context.RequestData.ReadInt64();
long Tag = Context.RequestData.ReadInt64();
context.ResponseData.Write(_audioOut.ContainsBuffer(_track, tag) ? 1 : 0);
Context.ResponseData.Write(AudioOut.ContainsBuffer(Track, Tag) ? 1 : 0);
return 0;
}
public long AppendAudioOutBufferAuto(ServiceCtx context)
public long AppendAudioOutBufferAuto(ServiceCtx Context)
{
(long position, long size) = context.Request.GetBufferType0x21();
(long Position, long Size) = Context.Request.GetBufferType0x21();
return AppendAudioOutBufferImpl(context, position);
return AppendAudioOutBufferImpl(Context, Position);
}
public long AppendAudioOutBufferImpl(ServiceCtx context, long position)
public long AppendAudioOutBufferImpl(ServiceCtx Context, long Position)
{
long tag = context.RequestData.ReadInt64();
long Tag = Context.RequestData.ReadInt64();
AudioOutData data = MemoryHelper.Read<AudioOutData>(
context.Memory,
position);
AudioOutData Data = MemoryHelper.Read<AudioOutData>(
Context.Memory,
Position);
byte[] buffer = context.Memory.ReadBytes(
data.SampleBufferPtr,
data.SampleBufferSize);
byte[] Buffer = Context.Memory.ReadBytes(
Data.SampleBufferPtr,
Data.SampleBufferSize);
_audioOut.AppendBuffer(_track, tag, buffer);
AudioOut.AppendBuffer(Track, Tag, Buffer);
return 0;
}
public long GetReleasedAudioOutBufferAuto(ServiceCtx context)
public long GetReleasedAudioOutBufferAuto(ServiceCtx Context)
{
(long position, long size) = context.Request.GetBufferType0x22();
(long Position, long Size) = Context.Request.GetBufferType0x22();
return GetReleasedAudioOutBufferImpl(context, position, size);
return GetReleasedAudioOutBufferImpl(Context, Position, Size);
}
public long GetReleasedAudioOutBufferImpl(ServiceCtx context, long position, long size)
public long GetReleasedAudioOutBufferImpl(ServiceCtx Context, long Position, long Size)
{
uint count = (uint)((ulong)size >> 3);
uint Count = (uint)((ulong)Size >> 3);
long[] releasedBuffers = _audioOut.GetReleasedBuffers(_track, (int)count);
long[] ReleasedBuffers = AudioOut.GetReleasedBuffers(Track, (int)Count);
for (uint index = 0; index < count; index++)
for (uint Index = 0; Index < Count; Index++)
{
long tag = 0;
long Tag = 0;
if (index < releasedBuffers.Length)
if (Index < ReleasedBuffers.Length)
{
tag = releasedBuffers[index];
Tag = ReleasedBuffers[Index];
}
context.Memory.WriteInt64(position + index * 8, tag);
Context.Memory.WriteInt64(Position + Index * 8, Tag);
}
context.ResponseData.Write(releasedBuffers.Length);
Context.ResponseData.Write(ReleasedBuffers.Length);
return 0;
}
@ -153,11 +153,11 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
Dispose(true);
}
protected virtual void Dispose(bool disposing)
protected virtual void Dispose(bool Disposing)
{
if (disposing)
if (Disposing)
{
_audioOut.CloseTrack(_track);
AudioOut.CloseTrack(Track);
}
}
}

View file

@ -22,33 +22,33 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
//high latency).
private const int MixBufferSamplesCount = 960;
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent _updateEvent;
private KEvent UpdateEvent;
private MemoryManager _memory;
private MemoryManager Memory;
private IAalOutput _audioOut;
private IAalOutput AudioOut;
private AudioRendererParameter _params;
private AudioRendererParameter Params;
private MemoryPoolContext[] _memoryPools;
private MemoryPoolContext[] MemoryPools;
private VoiceContext[] _voices;
private VoiceContext[] Voices;
private int _track;
private int Track;
private PlayState _playState;
private PlayState PlayState;
public IAudioRenderer(
Horizon system,
MemoryManager memory,
IAalOutput audioOut,
Horizon System,
MemoryManager Memory,
IAalOutput AudioOut,
AudioRendererParameter Params)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetSampleRate },
{ 1, GetSampleCount },
@ -60,75 +60,75 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
{ 7, QuerySystemEvent }
};
_updateEvent = new KEvent(system);
UpdateEvent = new KEvent(System);
_memory = memory;
_audioOut = audioOut;
_params = Params;
this.Memory = Memory;
this.AudioOut = AudioOut;
this.Params = Params;
_track = audioOut.OpenTrack(
Track = AudioOut.OpenTrack(
AudioConsts.HostSampleRate,
AudioConsts.HostChannelsCount,
AudioCallback);
_memoryPools = CreateArray<MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4);
MemoryPools = CreateArray<MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4);
_voices = CreateArray<VoiceContext>(Params.VoiceCount);
Voices = CreateArray<VoiceContext>(Params.VoiceCount);
InitializeAudioOut();
_playState = PlayState.Stopped;
PlayState = PlayState.Stopped;
}
// GetSampleRate() -> u32
public long GetSampleRate(ServiceCtx context)
public long GetSampleRate(ServiceCtx Context)
{
context.ResponseData.Write(_params.SampleRate);
Context.ResponseData.Write(Params.SampleRate);
return 0;
}
// GetSampleCount() -> u32
public long GetSampleCount(ServiceCtx context)
public long GetSampleCount(ServiceCtx Context)
{
context.ResponseData.Write(_params.SampleCount);
Context.ResponseData.Write(Params.SampleCount);
return 0;
}
// GetMixBufferCount() -> u32
public long GetMixBufferCount(ServiceCtx context)
public long GetMixBufferCount(ServiceCtx Context)
{
context.ResponseData.Write(_params.MixCount);
Context.ResponseData.Write(Params.MixCount);
return 0;
}
// GetState() -> u32
private long GetState(ServiceCtx context)
private long GetState(ServiceCtx Context)
{
context.ResponseData.Write((int)_playState);
Context.ResponseData.Write((int)PlayState);
Logger.PrintStub(LogClass.ServiceAudio, $"Stubbed. Renderer State: {Enum.GetName(typeof(PlayState), _playState)}");
Logger.PrintStub(LogClass.ServiceAudio, $"Stubbed. Renderer State: {Enum.GetName(typeof(PlayState), PlayState)}");
return 0;
}
private void AudioCallback()
{
_updateEvent.ReadableEvent.Signal();
UpdateEvent.ReadableEvent.Signal();
}
private static T[] CreateArray<T>(int size) where T : new()
private static T[] CreateArray<T>(int Size) where T : new()
{
T[] output = new T[size];
T[] Output = new T[Size];
for (int index = 0; index < size; index++)
for (int Index = 0; Index < Size; Index++)
{
output[index] = new T();
Output[Index] = new T();
}
return output;
return Output;
}
private void InitializeAudioOut()
@ -137,258 +137,258 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
AppendMixedBuffer(1);
AppendMixedBuffer(2);
_audioOut.Start(_track);
AudioOut.Start(Track);
}
public long RequestUpdateAudioRenderer(ServiceCtx context)
public long RequestUpdateAudioRenderer(ServiceCtx Context)
{
long outputPosition = context.Request.ReceiveBuff[0].Position;
long outputSize = context.Request.ReceiveBuff[0].Size;
long OutputPosition = Context.Request.ReceiveBuff[0].Position;
long OutputSize = Context.Request.ReceiveBuff[0].Size;
MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize);
MemoryHelper.FillWithZeros(Context.Memory, OutputPosition, (int)OutputSize);
long inputPosition = context.Request.SendBuff[0].Position;
long InputPosition = Context.Request.SendBuff[0].Position;
StructReader reader = new StructReader(context.Memory, inputPosition);
StructWriter writer = new StructWriter(context.Memory, outputPosition);
StructReader Reader = new StructReader(Context.Memory, InputPosition);
StructWriter Writer = new StructWriter(Context.Memory, OutputPosition);
UpdateDataHeader inputHeader = reader.Read<UpdateDataHeader>();
UpdateDataHeader InputHeader = Reader.Read<UpdateDataHeader>();
reader.Read<BehaviorIn>(inputHeader.BehaviorSize);
Reader.Read<BehaviorIn>(InputHeader.BehaviorSize);
MemoryPoolIn[] memoryPoolsIn = reader.Read<MemoryPoolIn>(inputHeader.MemoryPoolSize);
MemoryPoolIn[] MemoryPoolsIn = Reader.Read<MemoryPoolIn>(InputHeader.MemoryPoolSize);
for (int index = 0; index < memoryPoolsIn.Length; index++)
for (int Index = 0; Index < MemoryPoolsIn.Length; Index++)
{
MemoryPoolIn memoryPool = memoryPoolsIn[index];
MemoryPoolIn MemoryPool = MemoryPoolsIn[Index];
if (memoryPool.State == MemoryPoolState.RequestAttach)
if (MemoryPool.State == MemoryPoolState.RequestAttach)
{
_memoryPools[index].OutStatus.State = MemoryPoolState.Attached;
MemoryPools[Index].OutStatus.State = MemoryPoolState.Attached;
}
else if (memoryPool.State == MemoryPoolState.RequestDetach)
else if (MemoryPool.State == MemoryPoolState.RequestDetach)
{
_memoryPools[index].OutStatus.State = MemoryPoolState.Detached;
MemoryPools[Index].OutStatus.State = MemoryPoolState.Detached;
}
}
reader.Read<VoiceChannelResourceIn>(inputHeader.VoiceResourceSize);
Reader.Read<VoiceChannelResourceIn>(InputHeader.VoiceResourceSize);
VoiceIn[] voicesIn = reader.Read<VoiceIn>(inputHeader.VoiceSize);
VoiceIn[] VoicesIn = Reader.Read<VoiceIn>(InputHeader.VoiceSize);
for (int index = 0; index < voicesIn.Length; index++)
for (int Index = 0; Index < VoicesIn.Length; Index++)
{
VoiceIn voice = voicesIn[index];
VoiceIn Voice = VoicesIn[Index];
VoiceContext voiceCtx = _voices[index];
VoiceContext VoiceCtx = Voices[Index];
voiceCtx.SetAcquireState(voice.Acquired != 0);
VoiceCtx.SetAcquireState(Voice.Acquired != 0);
if (voice.Acquired == 0)
if (Voice.Acquired == 0)
{
continue;
}
if (voice.FirstUpdate != 0)
if (Voice.FirstUpdate != 0)
{
voiceCtx.AdpcmCtx = GetAdpcmDecoderContext(
voice.AdpcmCoeffsPosition,
voice.AdpcmCoeffsSize);
VoiceCtx.AdpcmCtx = GetAdpcmDecoderContext(
Voice.AdpcmCoeffsPosition,
Voice.AdpcmCoeffsSize);
voiceCtx.SampleFormat = voice.SampleFormat;
voiceCtx.SampleRate = voice.SampleRate;
voiceCtx.ChannelsCount = voice.ChannelsCount;
VoiceCtx.SampleFormat = Voice.SampleFormat;
VoiceCtx.SampleRate = Voice.SampleRate;
VoiceCtx.ChannelsCount = Voice.ChannelsCount;
voiceCtx.SetBufferIndex(voice.BaseWaveBufferIndex);
VoiceCtx.SetBufferIndex(Voice.BaseWaveBufferIndex);
}
voiceCtx.WaveBuffers[0] = voice.WaveBuffer0;
voiceCtx.WaveBuffers[1] = voice.WaveBuffer1;
voiceCtx.WaveBuffers[2] = voice.WaveBuffer2;
voiceCtx.WaveBuffers[3] = voice.WaveBuffer3;
voiceCtx.Volume = voice.Volume;
voiceCtx.PlayState = voice.PlayState;
VoiceCtx.WaveBuffers[0] = Voice.WaveBuffer0;
VoiceCtx.WaveBuffers[1] = Voice.WaveBuffer1;
VoiceCtx.WaveBuffers[2] = Voice.WaveBuffer2;
VoiceCtx.WaveBuffers[3] = Voice.WaveBuffer3;
VoiceCtx.Volume = Voice.Volume;
VoiceCtx.PlayState = Voice.PlayState;
}
UpdateAudio();
UpdateDataHeader outputHeader = new UpdateDataHeader();
UpdateDataHeader OutputHeader = new UpdateDataHeader();
int updateHeaderSize = Marshal.SizeOf<UpdateDataHeader>();
int UpdateHeaderSize = Marshal.SizeOf<UpdateDataHeader>();
outputHeader.Revision = IAudioRendererManager.RevMagic;
outputHeader.BehaviorSize = 0xb0;
outputHeader.MemoryPoolSize = (_params.EffectCount + _params.VoiceCount * 4) * 0x10;
outputHeader.VoiceSize = _params.VoiceCount * 0x10;
outputHeader.EffectSize = _params.EffectCount * 0x10;
outputHeader.SinkSize = _params.SinkCount * 0x20;
outputHeader.PerformanceManagerSize = 0x10;
outputHeader.TotalSize = updateHeaderSize +
outputHeader.BehaviorSize +
outputHeader.MemoryPoolSize +
outputHeader.VoiceSize +
outputHeader.EffectSize +
outputHeader.SinkSize +
outputHeader.PerformanceManagerSize;
OutputHeader.Revision = IAudioRendererManager.RevMagic;
OutputHeader.BehaviorSize = 0xb0;
OutputHeader.MemoryPoolSize = (Params.EffectCount + Params.VoiceCount * 4) * 0x10;
OutputHeader.VoiceSize = Params.VoiceCount * 0x10;
OutputHeader.EffectSize = Params.EffectCount * 0x10;
OutputHeader.SinkSize = Params.SinkCount * 0x20;
OutputHeader.PerformanceManagerSize = 0x10;
OutputHeader.TotalSize = UpdateHeaderSize +
OutputHeader.BehaviorSize +
OutputHeader.MemoryPoolSize +
OutputHeader.VoiceSize +
OutputHeader.EffectSize +
OutputHeader.SinkSize +
OutputHeader.PerformanceManagerSize;
writer.Write(outputHeader);
Writer.Write(OutputHeader);
foreach (MemoryPoolContext memoryPool in _memoryPools)
foreach (MemoryPoolContext MemoryPool in MemoryPools)
{
writer.Write(memoryPool.OutStatus);
Writer.Write(MemoryPool.OutStatus);
}
foreach (VoiceContext voice in _voices)
foreach (VoiceContext Voice in Voices)
{
writer.Write(voice.OutStatus);
Writer.Write(Voice.OutStatus);
}
return 0;
}
public long StartAudioRenderer(ServiceCtx context)
public long StartAudioRenderer(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");
_playState = PlayState.Playing;
PlayState = PlayState.Playing;
return 0;
}
public long StopAudioRenderer(ServiceCtx context)
public long StopAudioRenderer(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");
_playState = PlayState.Stopped;
PlayState = PlayState.Stopped;
return 0;
}
public long QuerySystemEvent(ServiceCtx context)
public long QuerySystemEvent(ServiceCtx Context)
{
if (context.Process.HandleTable.GenerateHandle(_updateEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(UpdateEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
return 0;
}
private AdpcmDecoderContext GetAdpcmDecoderContext(long position, long size)
private AdpcmDecoderContext GetAdpcmDecoderContext(long Position, long Size)
{
if (size == 0)
if (Size == 0)
{
return null;
}
AdpcmDecoderContext context = new AdpcmDecoderContext();
AdpcmDecoderContext Context = new AdpcmDecoderContext();
context.Coefficients = new short[size >> 1];
Context.Coefficients = new short[Size >> 1];
for (int offset = 0; offset < size; offset += 2)
for (int Offset = 0; Offset < Size; Offset += 2)
{
context.Coefficients[offset >> 1] = _memory.ReadInt16(position + offset);
Context.Coefficients[Offset >> 1] = Memory.ReadInt16(Position + Offset);
}
return context;
return Context;
}
private void UpdateAudio()
{
long[] released = _audioOut.GetReleasedBuffers(_track, 2);
long[] Released = AudioOut.GetReleasedBuffers(Track, 2);
for (int index = 0; index < released.Length; index++)
for (int Index = 0; Index < Released.Length; Index++)
{
AppendMixedBuffer(released[index]);
AppendMixedBuffer(Released[Index]);
}
}
private void AppendMixedBuffer(long tag)
private unsafe void AppendMixedBuffer(long Tag)
{
int[] mixBuffer = new int[MixBufferSamplesCount * AudioConsts.HostChannelsCount];
int[] MixBuffer = new int[MixBufferSamplesCount * AudioConsts.HostChannelsCount];
foreach (VoiceContext voice in _voices)
foreach (VoiceContext Voice in Voices)
{
if (!voice.Playing)
if (!Voice.Playing)
{
continue;
}
int outOffset = 0;
int pendingSamples = MixBufferSamplesCount;
float volume = voice.Volume;
int OutOffset = 0;
int PendingSamples = MixBufferSamplesCount;
float Volume = Voice.Volume;
while (pendingSamples > 0)
while (PendingSamples > 0)
{
int[] samples = voice.GetBufferData(_memory, pendingSamples, out int returnedSamples);
int[] Samples = Voice.GetBufferData(Memory, PendingSamples, out int ReturnedSamples);
if (returnedSamples == 0)
if (ReturnedSamples == 0)
{
break;
}
pendingSamples -= returnedSamples;
PendingSamples -= ReturnedSamples;
for (int offset = 0; offset < samples.Length; offset++)
for (int Offset = 0; Offset < Samples.Length; Offset++)
{
mixBuffer[outOffset++] += (int)(samples[offset] * voice.Volume);
MixBuffer[OutOffset++] += (int)(Samples[Offset] * Voice.Volume);
}
}
}
_audioOut.AppendBuffer(_track, tag, GetFinalBuffer(mixBuffer));
AudioOut.AppendBuffer(Track, Tag, GetFinalBuffer(MixBuffer));
}
private static unsafe short[] GetFinalBuffer(int[] buffer)
private unsafe static short[] GetFinalBuffer(int[] Buffer)
{
short[] output = new short[buffer.Length];
short[] Output = new short[Buffer.Length];
int offset = 0;
int Offset = 0;
// Perform Saturation using SSE2 if supported
if (Sse2.IsSupported)
{
fixed (int* inptr = buffer)
fixed (short* outptr = output)
fixed (int* inptr = Buffer)
fixed (short* outptr = Output)
{
for (; offset + 32 <= buffer.Length; offset += 32)
for (; Offset + 32 <= Buffer.Length; Offset += 32)
{
// Unroll the loop a little to ensure the CPU pipeline
// is always full.
Vector128<int> block1A = Sse2.LoadVector128(inptr + offset + 0);
Vector128<int> block1B = Sse2.LoadVector128(inptr + offset + 4);
Vector128<int> block1A = Sse2.LoadVector128(inptr + Offset + 0);
Vector128<int> block1B = Sse2.LoadVector128(inptr + Offset + 4);
Vector128<int> block2A = Sse2.LoadVector128(inptr + offset + 8);
Vector128<int> block2B = Sse2.LoadVector128(inptr + offset + 12);
Vector128<int> block2A = Sse2.LoadVector128(inptr + Offset + 8);
Vector128<int> block2B = Sse2.LoadVector128(inptr + Offset + 12);
Vector128<int> block3A = Sse2.LoadVector128(inptr + offset + 16);
Vector128<int> block3B = Sse2.LoadVector128(inptr + offset + 20);
Vector128<int> block3A = Sse2.LoadVector128(inptr + Offset + 16);
Vector128<int> block3B = Sse2.LoadVector128(inptr + Offset + 20);
Vector128<int> block4A = Sse2.LoadVector128(inptr + offset + 24);
Vector128<int> block4B = Sse2.LoadVector128(inptr + offset + 28);
Vector128<int> block4A = Sse2.LoadVector128(inptr + Offset + 24);
Vector128<int> block4B = Sse2.LoadVector128(inptr + Offset + 28);
Vector128<short> output1 = Sse2.PackSignedSaturate(block1A, block1B);
Vector128<short> output2 = Sse2.PackSignedSaturate(block2A, block2B);
Vector128<short> output3 = Sse2.PackSignedSaturate(block3A, block3B);
Vector128<short> output4 = Sse2.PackSignedSaturate(block4A, block4B);
Sse2.Store(outptr + offset + 0, output1);
Sse2.Store(outptr + offset + 8, output2);
Sse2.Store(outptr + offset + 16, output3);
Sse2.Store(outptr + offset + 24, output4);
Sse2.Store(outptr + Offset + 0, output1);
Sse2.Store(outptr + Offset + 8, output2);
Sse2.Store(outptr + Offset + 16, output3);
Sse2.Store(outptr + Offset + 24, output4);
}
}
}
// Process left overs
for (; offset < buffer.Length; offset++)
for (; Offset < Buffer.Length; Offset++)
{
output[offset] = DspUtils.Saturate(buffer[offset]);
Output[Offset] = DspUtils.Saturate(Buffer[Offset]);
}
return output;
return Output;
}
public void Dispose()
@ -396,11 +396,11 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
Dispose(true);
}
protected virtual void Dispose(bool disposing)
protected virtual void Dispose(bool Disposing)
{
if (disposing)
if (Disposing)
{
_audioOut.CloseTrack(_track);
AudioOut.CloseTrack(Track);
}
}
}

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
{
enum MemoryPoolState
enum MemoryPoolState : int
{
Invalid = 0,
Unknown = 1,

View file

@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
static class Resampler
{
#region "LookUp Tables"
private static short[] _curveLut0 = new short[]
private static short[] CurveLut0 = new short[]
{
6600, 19426, 6722, 3, 6479, 19424, 6845, 9, 6359, 19419, 6968, 15, 6239, 19412, 7093, 22,
6121, 19403, 7219, 28, 6004, 19391, 7345, 34, 5888, 19377, 7472, 41, 5773, 19361, 7600, 48,
@ -41,7 +41,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
22, 7093, 19412, 6239, 15, 6968, 19419, 6359, 9, 6845, 19424, 6479, 3, 6722, 19426, 6600
};
private static short[] _curveLut1 = new short[]
private static short[] CurveLut1 = new short[]
{
-68, 32639, 69, -5, -200, 32630, 212, -15, -328, 32613, 359, -26, -450, 32586, 512, -36,
-568, 32551, 669, -47, -680, 32507, 832, -58, -788, 32454, 1000, -69, -891, 32393, 1174, -80,
@ -77,7 +77,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
-36, 512, 32586, -450, -26, 359, 32613, -328, -15, 212, 32630, -200, -5, 69, 32639, -68
};
private static short[] _curveLut2 = new short[]
private static short[] CurveLut2 = new short[]
{
3195, 26287, 3329, -32, 3064, 26281, 3467, -34, 2936, 26270, 3608, -38, 2811, 26253, 3751, -42,
2688, 26230, 3897, -46, 2568, 26202, 4046, -50, 2451, 26169, 4199, -54, 2338, 26130, 4354, -58,
@ -115,77 +115,77 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
#endregion
public static int[] Resample2Ch(
int[] buffer,
int srcSampleRate,
int dstSampleRate,
int samplesCount,
ref int fracPart)
int[] Buffer,
int SrcSampleRate,
int DstSampleRate,
int SamplesCount,
ref int FracPart)
{
if (buffer == null)
if (Buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
throw new ArgumentNullException(nameof(Buffer));
}
if (srcSampleRate <= 0)
if (SrcSampleRate <= 0)
{
throw new ArgumentOutOfRangeException(nameof(srcSampleRate));
throw new ArgumentOutOfRangeException(nameof(SrcSampleRate));
}
if (dstSampleRate <= 0)
if (DstSampleRate <= 0)
{
throw new ArgumentOutOfRangeException(nameof(dstSampleRate));
throw new ArgumentOutOfRangeException(nameof(DstSampleRate));
}
double ratio = (double)srcSampleRate / dstSampleRate;
double Ratio = (double)SrcSampleRate / DstSampleRate;
int newSamplesCount = (int)(samplesCount / ratio);
int NewSamplesCount = (int)(SamplesCount / Ratio);
int step = (int)(ratio * 0x8000);
int Step = (int)(Ratio * 0x8000);
int[] output = new int[newSamplesCount * 2];
int[] Output = new int[NewSamplesCount * 2];
short[] lut;
short[] Lut;
if (step > 0xaaaa)
if (Step > 0xaaaa)
{
lut = _curveLut0;
Lut = CurveLut0;
}
else if (step <= 0x8000)
else if (Step <= 0x8000)
{
lut = _curveLut1;
Lut = CurveLut1;
}
else
{
lut = _curveLut2;
Lut = CurveLut2;
}
int inOffs = 0;
int InOffs = 0;
for (int outOffs = 0; outOffs < output.Length; outOffs += 2)
for (int OutOffs = 0; OutOffs < Output.Length; OutOffs += 2)
{
int lutIndex = (fracPart >> 8) * 4;
int LutIndex = (FracPart >> 8) * 4;
int sample0 = buffer[(inOffs + 0) * 2 + 0] * lut[lutIndex + 0] +
buffer[(inOffs + 1) * 2 + 0] * lut[lutIndex + 1] +
buffer[(inOffs + 2) * 2 + 0] * lut[lutIndex + 2] +
buffer[(inOffs + 3) * 2 + 0] * lut[lutIndex + 3];
int Sample0 = Buffer[(InOffs + 0) * 2 + 0] * Lut[LutIndex + 0] +
Buffer[(InOffs + 1) * 2 + 0] * Lut[LutIndex + 1] +
Buffer[(InOffs + 2) * 2 + 0] * Lut[LutIndex + 2] +
Buffer[(InOffs + 3) * 2 + 0] * Lut[LutIndex + 3];
int sample1 = buffer[(inOffs + 0) * 2 + 1] * lut[lutIndex + 0] +
buffer[(inOffs + 1) * 2 + 1] * lut[lutIndex + 1] +
buffer[(inOffs + 2) * 2 + 1] * lut[lutIndex + 2] +
buffer[(inOffs + 3) * 2 + 1] * lut[lutIndex + 3];
int Sample1 = Buffer[(InOffs + 0) * 2 + 1] * Lut[LutIndex + 0] +
Buffer[(InOffs + 1) * 2 + 1] * Lut[LutIndex + 1] +
Buffer[(InOffs + 2) * 2 + 1] * Lut[LutIndex + 2] +
Buffer[(InOffs + 3) * 2 + 1] * Lut[LutIndex + 3];
int newOffset = fracPart + step;
int NewOffset = FracPart + Step;
inOffs += newOffset >> 15;
InOffs += NewOffset >> 15;
fracPart = newOffset & 0x7fff;
FracPart = NewOffset & 0x7fff;
output[outOffs + 0] = sample0 >> 15;
output[outOffs + 1] = sample1 >> 15;
Output[OutOffs + 0] = Sample0 >> 15;
Output[OutOffs + 1] = Sample1 >> 15;
}
return output;
return Output;
}
}
}

View file

@ -6,13 +6,13 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
{
class VoiceContext
{
private bool _acquired;
private bool _bufferReload;
private bool Acquired;
private bool BufferReload;
private int _resamplerFracPart;
private int ResamplerFracPart;
private int _bufferIndex;
private int _offset;
private int BufferIndex;
private int Offset;
public int SampleRate;
public int ChannelsCount;
@ -29,138 +29,138 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
public VoiceOut OutStatus;
private int[] _samples;
private int[] Samples;
public bool Playing => _acquired && PlayState == PlayState.Playing;
public bool Playing => Acquired && PlayState == PlayState.Playing;
public VoiceContext()
{
WaveBuffers = new WaveBuffer[4];
}
public void SetAcquireState(bool newState)
public void SetAcquireState(bool NewState)
{
if (_acquired && !newState)
if (Acquired && !NewState)
{
//Release.
Reset();
}
_acquired = newState;
Acquired = NewState;
}
private void Reset()
{
_bufferReload = true;
BufferReload = true;
_bufferIndex = 0;
_offset = 0;
BufferIndex = 0;
Offset = 0;
OutStatus.PlayedSamplesCount = 0;
OutStatus.PlayedWaveBuffersCount = 0;
OutStatus.VoiceDropsCount = 0;
}
public int[] GetBufferData(MemoryManager memory, int maxSamples, out int samplesCount)
public int[] GetBufferData(MemoryManager Memory, int MaxSamples, out int SamplesCount)
{
if (!Playing)
{
samplesCount = 0;
SamplesCount = 0;
return null;
}
if (_bufferReload)
if (BufferReload)
{
_bufferReload = false;
BufferReload = false;
UpdateBuffer(memory);
UpdateBuffer(Memory);
}
WaveBuffer wb = WaveBuffers[_bufferIndex];
WaveBuffer Wb = WaveBuffers[BufferIndex];
int maxSize = _samples.Length - _offset;
int MaxSize = Samples.Length - Offset;
int size = maxSamples * AudioConsts.HostChannelsCount;
int Size = MaxSamples * AudioConsts.HostChannelsCount;
if (size > maxSize)
if (Size > MaxSize)
{
size = maxSize;
Size = MaxSize;
}
int[] output = new int[size];
int[] Output = new int[Size];
Array.Copy(_samples, _offset, output, 0, size);
Array.Copy(Samples, Offset, Output, 0, Size);
samplesCount = size / AudioConsts.HostChannelsCount;
SamplesCount = Size / AudioConsts.HostChannelsCount;
OutStatus.PlayedSamplesCount += samplesCount;
OutStatus.PlayedSamplesCount += SamplesCount;
_offset += size;
Offset += Size;
if (_offset == _samples.Length)
if (Offset == Samples.Length)
{
_offset = 0;
Offset = 0;
if (wb.Looping == 0)
if (Wb.Looping == 0)
{
SetBufferIndex((_bufferIndex + 1) & 3);
SetBufferIndex((BufferIndex + 1) & 3);
}
OutStatus.PlayedWaveBuffersCount++;
if (wb.LastBuffer != 0)
if (Wb.LastBuffer != 0)
{
PlayState = PlayState.Paused;
}
}
return output;
return Output;
}
private void UpdateBuffer(MemoryManager memory)
private void UpdateBuffer(MemoryManager Memory)
{
//TODO: Implement conversion for formats other
//than interleaved stereo (2 channels).
//As of now, it assumes that HostChannelsCount == 2.
WaveBuffer wb = WaveBuffers[_bufferIndex];
WaveBuffer Wb = WaveBuffers[BufferIndex];
if (wb.Position == 0)
if (Wb.Position == 0)
{
_samples = new int[0];
Samples = new int[0];
return;
}
if (SampleFormat == SampleFormat.PcmInt16)
{
int samplesCount = (int)(wb.Size / (sizeof(short) * ChannelsCount));
int SamplesCount = (int)(Wb.Size / (sizeof(short) * ChannelsCount));
_samples = new int[samplesCount * AudioConsts.HostChannelsCount];
Samples = new int[SamplesCount * AudioConsts.HostChannelsCount];
if (ChannelsCount == 1)
{
for (int index = 0; index < samplesCount; index++)
for (int Index = 0; Index < SamplesCount; Index++)
{
short sample = memory.ReadInt16(wb.Position + index * 2);
short Sample = Memory.ReadInt16(Wb.Position + Index * 2);
_samples[index * 2 + 0] = sample;
_samples[index * 2 + 1] = sample;
Samples[Index * 2 + 0] = Sample;
Samples[Index * 2 + 1] = Sample;
}
}
else
{
for (int index = 0; index < samplesCount * 2; index++)
for (int Index = 0; Index < SamplesCount * 2; Index++)
{
_samples[index] = memory.ReadInt16(wb.Position + index * 2);
Samples[Index] = Memory.ReadInt16(Wb.Position + Index * 2);
}
}
}
else if (SampleFormat == SampleFormat.Adpcm)
{
byte[] buffer = memory.ReadBytes(wb.Position, wb.Size);
byte[] Buffer = Memory.ReadBytes(Wb.Position, Wb.Size);
_samples = AdpcmDecoder.Decode(buffer, AdpcmCtx);
Samples = AdpcmDecoder.Decode(Buffer, AdpcmCtx);
}
else
{
@ -172,24 +172,24 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
//TODO: We should keep the frames being discarded (see the 4 below)
//on a buffer and include it on the next samples buffer, to allow
//the resampler to do seamless interpolation between wave buffers.
int samplesCount = _samples.Length / AudioConsts.HostChannelsCount;
int SamplesCount = Samples.Length / AudioConsts.HostChannelsCount;
samplesCount = Math.Max(samplesCount - 4, 0);
SamplesCount = Math.Max(SamplesCount - 4, 0);
_samples = Resampler.Resample2Ch(
_samples,
Samples = Resampler.Resample2Ch(
Samples,
SampleRate,
AudioConsts.HostSampleRate,
samplesCount,
ref _resamplerFracPart);
SamplesCount,
ref ResamplerFracPart);
}
}
public void SetBufferIndex(int index)
public void SetBufferIndex(int Index)
{
_bufferIndex = index & 3;
BufferIndex = Index & 3;
_bufferReload = true;
BufferReload = true;
}
}
}

View file

@ -10,15 +10,15 @@ namespace Ryujinx.HLE.HOS.Services.Aud
{
class IAudioDevice : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent _systemEvent;
private KEvent SystemEvent;
public IAudioDevice(Horizon system)
public IAudioDevice(Horizon System)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, ListAudioDeviceName },
{ 1, SetAudioDeviceOutputVolume },
@ -33,197 +33,197 @@ namespace Ryujinx.HLE.HOS.Services.Aud
{ 12, QueryAudioDeviceOutputEvent }
};
_systemEvent = new KEvent(system);
SystemEvent = new KEvent(System);
//TODO: We shouldn't be signaling this here.
_systemEvent.ReadableEvent.Signal();
SystemEvent.ReadableEvent.Signal();
}
public long ListAudioDeviceName(ServiceCtx context)
public long ListAudioDeviceName(ServiceCtx Context)
{
string[] deviceNames = SystemStateMgr.AudioOutputs;
string[] DeviceNames = SystemStateMgr.AudioOutputs;
context.ResponseData.Write(deviceNames.Length);
Context.ResponseData.Write(DeviceNames.Length);
long position = context.Request.ReceiveBuff[0].Position;
long size = context.Request.ReceiveBuff[0].Size;
long Position = Context.Request.ReceiveBuff[0].Position;
long Size = Context.Request.ReceiveBuff[0].Size;
long basePosition = position;
long BasePosition = Position;
foreach (string name in deviceNames)
foreach (string Name in DeviceNames)
{
byte[] buffer = Encoding.ASCII.GetBytes(name + "\0");
byte[] Buffer = Encoding.ASCII.GetBytes(Name + "\0");
if ((position - basePosition) + buffer.Length > size)
if ((Position - BasePosition) + Buffer.Length > Size)
{
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {size} too small!");
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!");
break;
}
context.Memory.WriteBytes(position, buffer);
Context.Memory.WriteBytes(Position, Buffer);
position += buffer.Length;
Position += Buffer.Length;
}
return 0;
}
public long SetAudioDeviceOutputVolume(ServiceCtx context)
public long SetAudioDeviceOutputVolume(ServiceCtx Context)
{
float volume = context.RequestData.ReadSingle();
float Volume = Context.RequestData.ReadSingle();
long position = context.Request.SendBuff[0].Position;
long size = context.Request.SendBuff[0].Size;
long Position = Context.Request.SendBuff[0].Position;
long Size = Context.Request.SendBuff[0].Size;
byte[] deviceNameBuffer = context.Memory.ReadBytes(position, size);
byte[] DeviceNameBuffer = Context.Memory.ReadBytes(Position, Size);
string deviceName = Encoding.ASCII.GetString(deviceNameBuffer);
string DeviceName = Encoding.ASCII.GetString(DeviceNameBuffer);
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");
return 0;
}
public long GetActiveAudioDeviceName(ServiceCtx context)
public long GetActiveAudioDeviceName(ServiceCtx Context)
{
string name = context.Device.System.State.ActiveAudioOutput;
string Name = Context.Device.System.State.ActiveAudioOutput;
long position = context.Request.ReceiveBuff[0].Position;
long size = context.Request.ReceiveBuff[0].Size;
long Position = Context.Request.ReceiveBuff[0].Position;
long Size = Context.Request.ReceiveBuff[0].Size;
byte[] deviceNameBuffer = Encoding.ASCII.GetBytes(name + "\0");
byte[] DeviceNameBuffer = Encoding.ASCII.GetBytes(Name + "\0");
if ((ulong)deviceNameBuffer.Length <= (ulong)size)
if ((ulong)DeviceNameBuffer.Length <= (ulong)Size)
{
context.Memory.WriteBytes(position, deviceNameBuffer);
Context.Memory.WriteBytes(Position, DeviceNameBuffer);
}
else
{
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {size} too small!");
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!");
}
return 0;
}
public long QueryAudioDeviceSystemEvent(ServiceCtx context)
public long QueryAudioDeviceSystemEvent(ServiceCtx Context)
{
if (context.Process.HandleTable.GenerateHandle(_systemEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(SystemEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");
return 0;
}
public long GetActiveChannelCount(ServiceCtx context)
public long GetActiveChannelCount(ServiceCtx Context)
{
context.ResponseData.Write(2);
Context.ResponseData.Write(2);
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");
return 0;
}
public long ListAudioDeviceNameAuto(ServiceCtx context)
public long ListAudioDeviceNameAuto(ServiceCtx Context)
{
string[] deviceNames = SystemStateMgr.AudioOutputs;
string[] DeviceNames = SystemStateMgr.AudioOutputs;
context.ResponseData.Write(deviceNames.Length);
Context.ResponseData.Write(DeviceNames.Length);
(long position, long size) = context.Request.GetBufferType0x22();
(long Position, long Size) = Context.Request.GetBufferType0x22();
long basePosition = position;
long BasePosition = Position;
foreach (string name in deviceNames)
foreach (string Name in DeviceNames)
{
byte[] buffer = Encoding.UTF8.GetBytes(name + '\0');
byte[] Buffer = Encoding.UTF8.GetBytes(Name + '\0');
if ((position - basePosition) + buffer.Length > size)
if ((Position - BasePosition) + Buffer.Length > Size)
{
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {size} too small!");
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!");
break;
}
context.Memory.WriteBytes(position, buffer);
Context.Memory.WriteBytes(Position, Buffer);
position += buffer.Length;
Position += Buffer.Length;
}
return 0;
}
public long SetAudioDeviceOutputVolumeAuto(ServiceCtx context)
public long SetAudioDeviceOutputVolumeAuto(ServiceCtx Context)
{
float volume = context.RequestData.ReadSingle();
float Volume = Context.RequestData.ReadSingle();
(long position, long size) = context.Request.GetBufferType0x21();
(long Position, long Size) = Context.Request.GetBufferType0x21();
byte[] deviceNameBuffer = context.Memory.ReadBytes(position, size);
byte[] DeviceNameBuffer = Context.Memory.ReadBytes(Position, Size);
string deviceName = Encoding.UTF8.GetString(deviceNameBuffer);
string DeviceName = Encoding.UTF8.GetString(DeviceNameBuffer);
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");
return 0;
}
public long GetAudioDeviceOutputVolumeAuto(ServiceCtx context)
public long GetAudioDeviceOutputVolumeAuto(ServiceCtx Context)
{
context.ResponseData.Write(1f);
Context.ResponseData.Write(1f);
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");
return 0;
}
public long GetActiveAudioDeviceNameAuto(ServiceCtx context)
public long GetActiveAudioDeviceNameAuto(ServiceCtx Context)
{
string name = context.Device.System.State.ActiveAudioOutput;
string Name = Context.Device.System.State.ActiveAudioOutput;
(long position, long size) = context.Request.GetBufferType0x22();
(long Position, long Size) = Context.Request.GetBufferType0x22();
byte[] deviceNameBuffer = Encoding.UTF8.GetBytes(name + '\0');
byte[] DeviceNameBuffer = Encoding.UTF8.GetBytes(Name + '\0');
if ((ulong)deviceNameBuffer.Length <= (ulong)size)
if ((ulong)DeviceNameBuffer.Length <= (ulong)Size)
{
context.Memory.WriteBytes(position, deviceNameBuffer);
Context.Memory.WriteBytes(Position, DeviceNameBuffer);
}
else
{
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {size} too small!");
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!");
}
return 0;
}
public long QueryAudioDeviceInputEvent(ServiceCtx context)
public long QueryAudioDeviceInputEvent(ServiceCtx Context)
{
if (context.Process.HandleTable.GenerateHandle(_systemEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(SystemEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");
return 0;
}
public long QueryAudioDeviceOutputEvent(ServiceCtx context)
public long QueryAudioDeviceOutputEvent(ServiceCtx Context)
{
if (context.Process.HandleTable.GenerateHandle(_systemEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(SystemEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");

View file

@ -19,13 +19,13 @@ namespace Ryujinx.HLE.HOS.Services.Aud
private const int DefaultChannelsCount = 2;
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IAudioOutManager()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, ListAudioOuts },
{ 1, OpenAudioOut },
@ -34,135 +34,135 @@ namespace Ryujinx.HLE.HOS.Services.Aud
};
}
public long ListAudioOuts(ServiceCtx context)
public long ListAudioOuts(ServiceCtx Context)
{
return ListAudioOutsImpl(
context,
context.Request.ReceiveBuff[0].Position,
context.Request.ReceiveBuff[0].Size);
Context,
Context.Request.ReceiveBuff[0].Position,
Context.Request.ReceiveBuff[0].Size);
}
public long OpenAudioOut(ServiceCtx context)
public long OpenAudioOut(ServiceCtx Context)
{
return OpenAudioOutImpl(
context,
context.Request.SendBuff[0].Position,
context.Request.SendBuff[0].Size,
context.Request.ReceiveBuff[0].Position,
context.Request.ReceiveBuff[0].Size);
Context,
Context.Request.SendBuff[0].Position,
Context.Request.SendBuff[0].Size,
Context.Request.ReceiveBuff[0].Position,
Context.Request.ReceiveBuff[0].Size);
}
public long ListAudioOutsAuto(ServiceCtx context)
public long ListAudioOutsAuto(ServiceCtx Context)
{
(long recvPosition, long recvSize) = context.Request.GetBufferType0x22();
(long RecvPosition, long RecvSize) = Context.Request.GetBufferType0x22();
return ListAudioOutsImpl(context, recvPosition, recvSize);
return ListAudioOutsImpl(Context, RecvPosition, RecvSize);
}
public long OpenAudioOutAuto(ServiceCtx context)
public long OpenAudioOutAuto(ServiceCtx Context)
{
(long sendPosition, long sendSize) = context.Request.GetBufferType0x21();
(long recvPosition, long recvSize) = context.Request.GetBufferType0x22();
(long SendPosition, long SendSize) = Context.Request.GetBufferType0x21();
(long RecvPosition, long RecvSize) = Context.Request.GetBufferType0x22();
return OpenAudioOutImpl(
context,
sendPosition,
sendSize,
recvPosition,
recvSize);
Context,
SendPosition,
SendSize,
RecvPosition,
RecvSize);
}
private long ListAudioOutsImpl(ServiceCtx context, long position, long size)
private long ListAudioOutsImpl(ServiceCtx Context, long Position, long Size)
{
int nameCount = 0;
int NameCount = 0;
byte[] deviceNameBuffer = Encoding.ASCII.GetBytes(DefaultAudioOutput + "\0");
byte[] DeviceNameBuffer = Encoding.ASCII.GetBytes(DefaultAudioOutput + "\0");
if ((ulong)deviceNameBuffer.Length <= (ulong)size)
if ((ulong)DeviceNameBuffer.Length <= (ulong)Size)
{
context.Memory.WriteBytes(position, deviceNameBuffer);
Context.Memory.WriteBytes(Position, DeviceNameBuffer);
nameCount++;
NameCount++;
}
else
{
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {size} too small!");
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!");
}
context.ResponseData.Write(nameCount);
Context.ResponseData.Write(NameCount);
return 0;
}
private long OpenAudioOutImpl(ServiceCtx context, long sendPosition, long sendSize, long receivePosition, long receiveSize)
private long OpenAudioOutImpl(ServiceCtx Context, long SendPosition, long SendSize, long ReceivePosition, long ReceiveSize)
{
string deviceName = MemoryHelper.ReadAsciiString(
context.Memory,
sendPosition,
sendSize);
string DeviceName = MemoryHelper.ReadAsciiString(
Context.Memory,
SendPosition,
SendSize);
if (deviceName == string.Empty)
if (DeviceName == string.Empty)
{
deviceName = DefaultAudioOutput;
DeviceName = DefaultAudioOutput;
}
if (deviceName != DefaultAudioOutput)
if (DeviceName != DefaultAudioOutput)
{
Logger.PrintWarning(LogClass.Audio, "Invalid device name!");
return MakeError(ErrorModule.Audio, AudErr.DeviceNotFound);
}
byte[] deviceNameBuffer = Encoding.ASCII.GetBytes(deviceName + "\0");
byte[] DeviceNameBuffer = Encoding.ASCII.GetBytes(DeviceName + "\0");
if ((ulong)deviceNameBuffer.Length <= (ulong)receiveSize)
if ((ulong)DeviceNameBuffer.Length <= (ulong)ReceiveSize)
{
context.Memory.WriteBytes(receivePosition, deviceNameBuffer);
Context.Memory.WriteBytes(ReceivePosition, DeviceNameBuffer);
}
else
{
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {receiveSize} too small!");
Logger.PrintError(LogClass.ServiceAudio, $"Output buffer size {ReceiveSize} too small!");
}
int sampleRate = context.RequestData.ReadInt32();
int channels = context.RequestData.ReadInt32();
int SampleRate = Context.RequestData.ReadInt32();
int Channels = Context.RequestData.ReadInt32();
if (sampleRate == 0)
if (SampleRate == 0)
{
sampleRate = DefaultSampleRate;
SampleRate = DefaultSampleRate;
}
if (sampleRate != DefaultSampleRate)
if (SampleRate != DefaultSampleRate)
{
Logger.PrintWarning(LogClass.Audio, "Invalid sample rate!");
return MakeError(ErrorModule.Audio, AudErr.UnsupportedSampleRate);
}
channels = (ushort)channels;
Channels = (ushort)Channels;
if (channels == 0)
if (Channels == 0)
{
channels = DefaultChannelsCount;
Channels = DefaultChannelsCount;
}
KEvent releaseEvent = new KEvent(context.Device.System);
KEvent ReleaseEvent = new KEvent(Context.Device.System);
ReleaseCallback callback = () =>
ReleaseCallback Callback = () =>
{
releaseEvent.ReadableEvent.Signal();
ReleaseEvent.ReadableEvent.Signal();
};
IAalOutput audioOut = context.Device.AudioOut;
IAalOutput AudioOut = Context.Device.AudioOut;
int track = audioOut.OpenTrack(sampleRate, channels, callback);
int Track = AudioOut.OpenTrack(SampleRate, Channels, Callback);
MakeObject(context, new IAudioOut(audioOut, releaseEvent, track));
MakeObject(Context, new IAudioOut(AudioOut, ReleaseEvent, Track));
context.ResponseData.Write(sampleRate);
context.ResponseData.Write(channels);
context.ResponseData.Write((int)SampleFormat.PcmInt16);
context.ResponseData.Write((int)PlaybackState.Stopped);
Context.ResponseData.Write(SampleRate);
Context.ResponseData.Write(Channels);
Context.ResponseData.Write((int)SampleFormat.PcmInt16);
Context.ResponseData.Write((int)PlaybackState.Stopped);
return 0;
}

View file

@ -20,13 +20,13 @@ namespace Ryujinx.HLE.HOS.Services.Aud
public const int RevMagic = Rev0Magic + (Rev << 24);
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IAudioRendererManager()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, OpenAudioRenderer },
{ 1, GetAudioRendererWorkBufferSize },
@ -35,81 +35,81 @@ namespace Ryujinx.HLE.HOS.Services.Aud
};
}
public long OpenAudioRenderer(ServiceCtx context)
public long OpenAudioRenderer(ServiceCtx Context)
{
IAalOutput audioOut = context.Device.AudioOut;
IAalOutput AudioOut = Context.Device.AudioOut;
AudioRendererParameter Params = GetAudioRendererParameter(context);
AudioRendererParameter Params = GetAudioRendererParameter(Context);
MakeObject(context, new IAudioRenderer(
context.Device.System,
context.Memory,
audioOut,
MakeObject(Context, new IAudioRenderer(
Context.Device.System,
Context.Memory,
AudioOut,
Params));
return 0;
}
public long GetAudioRendererWorkBufferSize(ServiceCtx context)
public long GetAudioRendererWorkBufferSize(ServiceCtx Context)
{
AudioRendererParameter Params = GetAudioRendererParameter(context);
AudioRendererParameter Params = GetAudioRendererParameter(Context);
int revision = (Params.Revision - Rev0Magic) >> 24;
int Revision = (Params.Revision - Rev0Magic) >> 24;
if (revision <= Rev)
if (Revision <= Rev)
{
bool isSplitterSupported = revision >= 3;
bool IsSplitterSupported = Revision >= 3;
long size;
long Size;
size = IntUtils.AlignUp(Params.Unknown8 * 4, 64);
size += Params.MixCount * 0x400;
size += (Params.MixCount + 1) * 0x940;
size += Params.VoiceCount * 0x3F0;
size += IntUtils.AlignUp((Params.MixCount + 1) * 8, 16);
size += IntUtils.AlignUp(Params.VoiceCount * 8, 16);
size += IntUtils.AlignUp(
Size = IntUtils.AlignUp(Params.Unknown8 * 4, 64);
Size += Params.MixCount * 0x400;
Size += (Params.MixCount + 1) * 0x940;
Size += Params.VoiceCount * 0x3F0;
Size += IntUtils.AlignUp((Params.MixCount + 1) * 8, 16);
Size += IntUtils.AlignUp(Params.VoiceCount * 8, 16);
Size += IntUtils.AlignUp(
((Params.SinkCount + Params.MixCount) * 0x3C0 + Params.SampleCount * 4) *
(Params.Unknown8 + 6), 64);
size += (Params.SinkCount + Params.MixCount) * 0x2C0;
size += (Params.EffectCount + Params.VoiceCount * 4) * 0x30 + 0x50;
Size += (Params.SinkCount + Params.MixCount) * 0x2C0;
Size += (Params.EffectCount + Params.VoiceCount * 4) * 0x30 + 0x50;
if (isSplitterSupported)
if (IsSplitterSupported)
{
size += IntUtils.AlignUp((
Size += IntUtils.AlignUp((
NodeStatesGetWorkBufferSize(Params.MixCount + 1) +
EdgeMatrixGetWorkBufferSize(Params.MixCount + 1)), 16);
size += Params.SplitterDestinationDataCount * 0xE0;
size += Params.SplitterCount * 0x20;
size += IntUtils.AlignUp(Params.SplitterDestinationDataCount * 4, 16);
Size += Params.SplitterDestinationDataCount * 0xE0;
Size += Params.SplitterCount * 0x20;
Size += IntUtils.AlignUp(Params.SplitterDestinationDataCount * 4, 16);
}
size = Params.EffectCount * 0x4C0 +
Size = Params.EffectCount * 0x4C0 +
Params.SinkCount * 0x170 +
Params.VoiceCount * 0x100 +
IntUtils.AlignUp(size, 64) + 0x40;
IntUtils.AlignUp(Size, 64) + 0x40;
if (Params.PerformanceManagerCount >= 1)
{
size += (((Params.EffectCount +
Size += (((Params.EffectCount +
Params.SinkCount +
Params.VoiceCount +
Params.MixCount + 1) * 16 + 0x658) *
(Params.PerformanceManagerCount + 1) + 0x13F) & ~0x3FL;
}
size = (size + 0x1907D) & ~0xFFFL;
Size = (Size + 0x1907D) & ~0xFFFL;
context.ResponseData.Write(size);
Context.ResponseData.Write(Size);
Logger.PrintDebug(LogClass.ServiceAudio, $"WorkBufferSize is 0x{size:x16}.");
Logger.PrintDebug(LogClass.ServiceAudio, $"WorkBufferSize is 0x{Size:x16}.");
return 0;
}
else
{
context.ResponseData.Write(0L);
Context.ResponseData.Write(0L);
Logger.PrintWarning(LogClass.ServiceAudio, $"Library Revision 0x{Params.Revision:x8} is not supported!");
@ -117,71 +117,71 @@ namespace Ryujinx.HLE.HOS.Services.Aud
}
}
private AudioRendererParameter GetAudioRendererParameter(ServiceCtx context)
private AudioRendererParameter GetAudioRendererParameter(ServiceCtx Context)
{
AudioRendererParameter Params = new AudioRendererParameter();
Params.SampleRate = context.RequestData.ReadInt32();
Params.SampleCount = context.RequestData.ReadInt32();
Params.Unknown8 = context.RequestData.ReadInt32();
Params.MixCount = context.RequestData.ReadInt32();
Params.VoiceCount = context.RequestData.ReadInt32();
Params.SinkCount = context.RequestData.ReadInt32();
Params.EffectCount = context.RequestData.ReadInt32();
Params.PerformanceManagerCount = context.RequestData.ReadInt32();
Params.VoiceDropEnable = context.RequestData.ReadInt32();
Params.SplitterCount = context.RequestData.ReadInt32();
Params.SplitterDestinationDataCount = context.RequestData.ReadInt32();
Params.Unknown2C = context.RequestData.ReadInt32();
Params.Revision = context.RequestData.ReadInt32();
Params.SampleRate = Context.RequestData.ReadInt32();
Params.SampleCount = Context.RequestData.ReadInt32();
Params.Unknown8 = Context.RequestData.ReadInt32();
Params.MixCount = Context.RequestData.ReadInt32();
Params.VoiceCount = Context.RequestData.ReadInt32();
Params.SinkCount = Context.RequestData.ReadInt32();
Params.EffectCount = Context.RequestData.ReadInt32();
Params.PerformanceManagerCount = Context.RequestData.ReadInt32();
Params.VoiceDropEnable = Context.RequestData.ReadInt32();
Params.SplitterCount = Context.RequestData.ReadInt32();
Params.SplitterDestinationDataCount = Context.RequestData.ReadInt32();
Params.Unknown2C = Context.RequestData.ReadInt32();
Params.Revision = Context.RequestData.ReadInt32();
return Params;
}
private static int NodeStatesGetWorkBufferSize(int value)
private static int NodeStatesGetWorkBufferSize(int Value)
{
int result = IntUtils.AlignUp(value, 64);
int Result = IntUtils.AlignUp(Value, 64);
if (result < 0)
if (Result < 0)
{
result |= 7;
Result |= 7;
}
return 4 * (value * value) + 0x12 * value + 2 * (result / 8);
return 4 * (Value * Value) + 0x12 * Value + 2 * (Result / 8);
}
private static int EdgeMatrixGetWorkBufferSize(int value)
private static int EdgeMatrixGetWorkBufferSize(int Value)
{
int result = IntUtils.AlignUp(value * value, 64);
int Result = IntUtils.AlignUp(Value * Value, 64);
if (result < 0)
if (Result < 0)
{
result |= 7;
Result |= 7;
}
return result / 8;
return Result / 8;
}
// GetAudioDeviceService(nn::applet::AppletResourceUserId) -> object<nn::audio::detail::IAudioDevice>
public long GetAudioDeviceService(ServiceCtx context)
public long GetAudioDeviceService(ServiceCtx Context)
{
long appletResourceUserId = context.RequestData.ReadInt64();
long AppletResourceUserId = Context.RequestData.ReadInt64();
MakeObject(context, new IAudioDevice(context.Device.System));
MakeObject(Context, new IAudioDevice(Context.Device.System));
return 0;
}
// GetAudioDeviceServiceWithRevisionInfo(nn::applet::AppletResourceUserId, u32) -> object<nn::audio::detail::IAudioDevice>
private long GetAudioDeviceServiceWithRevisionInfo(ServiceCtx context)
private long GetAudioDeviceServiceWithRevisionInfo(ServiceCtx Context)
{
long appletResourceUserId = context.RequestData.ReadInt64();
int revisionInfo = context.RequestData.ReadInt32();
long AppletResourceUserId = Context.RequestData.ReadInt64();
int RevisionInfo = Context.RequestData.ReadInt32();
Logger.PrintStub(LogClass.ServiceAudio, $"Stubbed. AppletResourceUserId: {appletResourceUserId} - " +
$"RevisionInfo: {revisionInfo}");
Logger.PrintStub(LogClass.ServiceAudio, $"Stubbed. AppletResourceUserId: {AppletResourceUserId} - " +
$"RevisionInfo: {RevisionInfo}");
return GetAudioDeviceService(context);
return GetAudioDeviceService(Context);
}
}
}

View file

@ -10,80 +10,80 @@ namespace Ryujinx.HLE.HOS.Services.Aud
{
private const int FixedSampleRate = 48000;
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private int _sampleRate;
private int _channelsCount;
private int SampleRate;
private int ChannelsCount;
private OpusDecoder _decoder;
private OpusDecoder Decoder;
public IHardwareOpusDecoder(int sampleRate, int channelsCount)
public IHardwareOpusDecoder(int SampleRate, int ChannelsCount)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, DecodeInterleaved },
{ 4, DecodeInterleavedWithPerf }
};
_sampleRate = sampleRate;
_channelsCount = channelsCount;
this.SampleRate = SampleRate;
this.ChannelsCount = ChannelsCount;
_decoder = new OpusDecoder(FixedSampleRate, channelsCount);
Decoder = new OpusDecoder(FixedSampleRate, ChannelsCount);
}
public long DecodeInterleavedWithPerf(ServiceCtx context)
public long DecodeInterleavedWithPerf(ServiceCtx Context)
{
long result = DecodeInterleaved(context);
long Result = DecodeInterleaved(Context);
//TODO: Figure out what this value is.
//According to switchbrew, it is now used.
context.ResponseData.Write(0L);
Context.ResponseData.Write(0L);
return result;
return Result;
}
public long DecodeInterleaved(ServiceCtx context)
public long DecodeInterleaved(ServiceCtx Context)
{
long inPosition = context.Request.SendBuff[0].Position;
long inSize = context.Request.SendBuff[0].Size;
long InPosition = Context.Request.SendBuff[0].Position;
long InSize = Context.Request.SendBuff[0].Size;
if (inSize < 8)
if (InSize < 8)
{
return MakeError(ErrorModule.Audio, AudErr.OpusInvalidInput);
}
long outPosition = context.Request.ReceiveBuff[0].Position;
long outSize = context.Request.ReceiveBuff[0].Size;
long OutPosition = Context.Request.ReceiveBuff[0].Position;
long OutSize = Context.Request.ReceiveBuff[0].Size;
byte[] opusData = context.Memory.ReadBytes(inPosition, inSize);
byte[] OpusData = Context.Memory.ReadBytes(InPosition, InSize);
int processed = ((opusData[0] << 24) |
(opusData[1] << 16) |
(opusData[2] << 8) |
(opusData[3] << 0)) + 8;
int Processed = ((OpusData[0] << 24) |
(OpusData[1] << 16) |
(OpusData[2] << 8) |
(OpusData[3] << 0)) + 8;
if ((uint)processed > (ulong)inSize)
if ((uint)Processed > (ulong)InSize)
{
return MakeError(ErrorModule.Audio, AudErr.OpusInvalidInput);
}
short[] pcm = new short[outSize / 2];
short[] Pcm = new short[OutSize / 2];
int frameSize = pcm.Length / (_channelsCount * 2);
int FrameSize = Pcm.Length / (ChannelsCount * 2);
int samples = _decoder.Decode(opusData, 0, opusData.Length, pcm, 0, frameSize);
int Samples = Decoder.Decode(OpusData, 0, OpusData.Length, Pcm, 0, FrameSize);
foreach (short sample in pcm)
foreach (short Sample in Pcm)
{
context.Memory.WriteInt16(outPosition, sample);
Context.Memory.WriteInt16(OutPosition, Sample);
outPosition += 2;
OutPosition += 2;
}
context.ResponseData.Write(processed);
context.ResponseData.Write(samples);
Context.ResponseData.Write(Processed);
Context.ResponseData.Write(Samples);
return 0;
}

View file

@ -5,68 +5,68 @@ namespace Ryujinx.HLE.HOS.Services.Aud
{
class IHardwareOpusDecoderManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IHardwareOpusDecoderManager()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Initialize },
{ 1, GetWorkBufferSize }
};
}
public long Initialize(ServiceCtx context)
public long Initialize(ServiceCtx Context)
{
int sampleRate = context.RequestData.ReadInt32();
int channelsCount = context.RequestData.ReadInt32();
int SampleRate = Context.RequestData.ReadInt32();
int ChannelsCount = Context.RequestData.ReadInt32();
MakeObject(context, new IHardwareOpusDecoder(sampleRate, channelsCount));
MakeObject(Context, new IHardwareOpusDecoder(SampleRate, ChannelsCount));
return 0;
}
public long GetWorkBufferSize(ServiceCtx context)
public long GetWorkBufferSize(ServiceCtx Context)
{
//Note: The sample rate is ignored because it is fixed to 48KHz.
int sampleRate = context.RequestData.ReadInt32();
int channelsCount = context.RequestData.ReadInt32();
int SampleRate = Context.RequestData.ReadInt32();
int ChannelsCount = Context.RequestData.ReadInt32();
context.ResponseData.Write(GetOpusDecoderSize(channelsCount));
Context.ResponseData.Write(GetOpusDecoderSize(ChannelsCount));
return 0;
}
private static int GetOpusDecoderSize(int channelsCount)
private static int GetOpusDecoderSize(int ChannelsCount)
{
const int silkDecoderSize = 0x2198;
const int SilkDecoderSize = 0x2198;
if (channelsCount < 1 || channelsCount > 2)
if (ChannelsCount < 1 || ChannelsCount > 2)
{
return 0;
}
int celtDecoderSize = GetCeltDecoderSize(channelsCount);
int CeltDecoderSize = GetCeltDecoderSize(ChannelsCount);
int opusDecoderSize = (channelsCount * 0x800 + 0x4807) & -0x800 | 0x50;
int OpusDecoderSize = (ChannelsCount * 0x800 + 0x4807) & -0x800 | 0x50;
return opusDecoderSize + silkDecoderSize + celtDecoderSize;
return OpusDecoderSize + SilkDecoderSize + CeltDecoderSize;
}
private static int GetCeltDecoderSize(int channelsCount)
private static int GetCeltDecoderSize(int ChannelsCount)
{
const int decodeBufferSize = 0x2030;
const int celtDecoderSize = 0x58;
const int celtSigSize = 0x4;
const int overlap = 120;
const int eBandsCount = 21;
const int DecodeBufferSize = 0x2030;
const int CeltDecoderSize = 0x58;
const int CeltSigSize = 0x4;
const int Overlap = 120;
const int EBandsCount = 21;
return (decodeBufferSize + overlap * 4) * channelsCount +
eBandsCount * 16 +
celtDecoderSize +
celtSigSize;
return (DecodeBufferSize + Overlap * 4) * ChannelsCount +
EBandsCount * 16 +
CeltDecoderSize +
CeltSigSize;
}
}
}

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Bcat
{
class IBcatService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IBcatService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Bcat
{
class IDeliveryCacheStorageService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IDeliveryCacheStorageService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -5,33 +5,33 @@ namespace Ryujinx.HLE.HOS.Services.Bcat
{
class IServiceCreator : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IServiceCreator()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, CreateBcatService },
{ 1, CreateDeliveryCacheStorageService }
};
}
public long CreateBcatService(ServiceCtx context)
public long CreateBcatService(ServiceCtx Context)
{
long id = context.RequestData.ReadInt64();
long Id = Context.RequestData.ReadInt64();
MakeObject(context, new IBcatService());
MakeObject(Context, new IBcatService());
return 0;
}
public long CreateDeliveryCacheStorageService(ServiceCtx context)
public long CreateDeliveryCacheStorageService(ServiceCtx Context)
{
long id = context.RequestData.ReadInt64();
long Id = Context.RequestData.ReadInt64();
MakeObject(context, new IDeliveryCacheStorageService());
MakeObject(Context, new IDeliveryCacheStorageService());
return 0;
}

View file

@ -2,6 +2,6 @@
{
enum BsdIoctl
{
AtMark = 0x40047307
AtMark = 0x40047307,
}
}

File diff suppressed because it is too large Load diff

View file

@ -9,20 +9,20 @@
Output = 4,
Error = 8,
Disconnected = 0x10,
Invalid = 0x20
Invalid = 0x20,
}
public int SocketFd { get; }
public BsdSocket Socket { get; }
public EventTypeMask InputEvents { get; }
public EventTypeMask OutputEvents { get; }
public int SocketFd { get; private set; }
public BsdSocket Socket { get; private set; }
public EventTypeMask InputEvents { get; private set; }
public EventTypeMask OutputEvents { get; private set; }
public PollEvent(int socketFd, BsdSocket socket, EventTypeMask inputEvents, EventTypeMask outputEvents)
public PollEvent(int SocketFd, BsdSocket Socket, EventTypeMask InputEvents, EventTypeMask OutputEvents)
{
SocketFd = socketFd;
Socket = socket;
InputEvents = inputEvents;
OutputEvents = outputEvents;
this.SocketFd = SocketFd;
this.Socket = Socket;
this.InputEvents = InputEvents;
this.OutputEvents = OutputEvents;
}
}
}

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Caps
{
class IAlbumAccessorService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IAlbumAccessorService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Caps
{
class IScreenshotService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IScreenshotService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -1,19 +1,20 @@
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Es
{
class IeTicketService : IpcService
class IETicketService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private bool _isInitialized;
private bool IsInitialized;
public IeTicketService()
public IETicketService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
};

View file

@ -8,13 +8,13 @@ namespace Ryujinx.HLE.HOS.Services.Friend
{
class IFriendService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IFriendService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 10101, GetFriendList },
{ 10601, DeclareCloseOnlinePlaySession },
@ -23,76 +23,76 @@ namespace Ryujinx.HLE.HOS.Services.Friend
}
// nn::friends::GetFriendListGetFriendListIds(nn::account::Uid, int Unknown0, nn::friends::detail::ipc::SizedFriendFilter, ulong Unknown1) -> int CounterIds, array<nn::account::NetworkServiceAccountId>
public long GetFriendList(ServiceCtx context)
public long GetFriendList(ServiceCtx Context)
{
UInt128 uuid = new UInt128(
context.RequestData.ReadInt64(),
context.RequestData.ReadInt64());
UInt128 Uuid = new UInt128(
Context.RequestData.ReadInt64(),
Context.RequestData.ReadInt64());
int unknown0 = context.RequestData.ReadInt32();
int Unknown0 = Context.RequestData.ReadInt32();
FriendFilter filter = new FriendFilter
FriendFilter Filter = new FriendFilter()
{
PresenceStatus = (PresenceStatusFilter)context.RequestData.ReadInt32(),
IsFavoriteOnly = context.RequestData.ReadBoolean(),
IsSameAppPresenceOnly = context.RequestData.ReadBoolean(),
IsSameAppPlayedOnly = context.RequestData.ReadBoolean(),
IsArbitraryAppPlayedOnly = context.RequestData.ReadBoolean(),
PresenceGroupId = context.RequestData.ReadInt64()
PresenceStatus = (PresenceStatusFilter)Context.RequestData.ReadInt32(),
IsFavoriteOnly = Context.RequestData.ReadBoolean(),
IsSameAppPresenceOnly = Context.RequestData.ReadBoolean(),
IsSameAppPlayedOnly = Context.RequestData.ReadBoolean(),
IsArbitraryAppPlayedOnly = Context.RequestData.ReadBoolean(),
PresenceGroupId = Context.RequestData.ReadInt64()
};
long unknown1 = context.RequestData.ReadInt64();
long Unknown1 = Context.RequestData.ReadInt64();
// There are no friends online, so we return 0 because the nn::account::NetworkServiceAccountId array is empty.
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
Logger.PrintStub(LogClass.ServiceFriend, $"Stubbed. UserId: {uuid.ToString()} - " +
$"Unknown0: {unknown0} - " +
$"PresenceStatus: {filter.PresenceStatus} - " +
$"IsFavoriteOnly: {filter.IsFavoriteOnly} - " +
$"IsSameAppPresenceOnly: {filter.IsSameAppPresenceOnly} - " +
$"IsSameAppPlayedOnly: {filter.IsSameAppPlayedOnly} - " +
$"IsArbitraryAppPlayedOnly: {filter.IsArbitraryAppPlayedOnly} - " +
$"PresenceGroupId: {filter.PresenceGroupId} - " +
$"Unknown1: {unknown1}");
Logger.PrintStub(LogClass.ServiceFriend, $"Stubbed. UserId: {Uuid.ToString()} - " +
$"Unknown0: {Unknown0} - " +
$"PresenceStatus: {Filter.PresenceStatus} - " +
$"IsFavoriteOnly: {Filter.IsFavoriteOnly} - " +
$"IsSameAppPresenceOnly: {Filter.IsSameAppPresenceOnly} - " +
$"IsSameAppPlayedOnly: {Filter.IsSameAppPlayedOnly} - " +
$"IsArbitraryAppPlayedOnly: {Filter.IsArbitraryAppPlayedOnly} - " +
$"PresenceGroupId: {Filter.PresenceGroupId} - " +
$"Unknown1: {Unknown1}");
return 0;
}
// DeclareCloseOnlinePlaySession(nn::account::Uid)
public long DeclareCloseOnlinePlaySession(ServiceCtx context)
public long DeclareCloseOnlinePlaySession(ServiceCtx Context)
{
UInt128 uuid = new UInt128(
context.RequestData.ReadInt64(),
context.RequestData.ReadInt64());
UInt128 Uuid = new UInt128(
Context.RequestData.ReadInt64(),
Context.RequestData.ReadInt64());
if (context.Device.System.State.TryGetUser(uuid, out UserProfile profile))
if (Context.Device.System.State.TryGetUser(Uuid, out UserProfile Profile))
{
profile.OnlinePlayState = OpenCloseState.Closed;
Profile.OnlinePlayState = OpenCloseState.Closed;
}
Logger.PrintStub(LogClass.ServiceFriend, $"Stubbed. Uuid: {uuid.ToString()} - " +
$"OnlinePlayState: {profile.OnlinePlayState}");
Logger.PrintStub(LogClass.ServiceFriend, $"Stubbed. Uuid: {Uuid.ToString()} - " +
$"OnlinePlayState: {Profile.OnlinePlayState}");
return 0;
}
// UpdateUserPresence(nn::account::Uid, ulong Unknown0) -> buffer<Unknown1, type: 0x19, size: 0xe0>
public long UpdateUserPresence(ServiceCtx context)
public long UpdateUserPresence(ServiceCtx Context)
{
UInt128 uuid = new UInt128(
context.RequestData.ReadInt64(),
context.RequestData.ReadInt64());
UInt128 Uuid = new UInt128(
Context.RequestData.ReadInt64(),
Context.RequestData.ReadInt64());
long unknown0 = context.RequestData.ReadInt64();
long Unknown0 = Context.RequestData.ReadInt64();
long position = context.Request.PtrBuff[0].Position;
long size = context.Request.PtrBuff[0].Size;
long Position = Context.Request.PtrBuff[0].Position;
long Size = Context.Request.PtrBuff[0].Size;
//Todo: Write the buffer content.
Logger.PrintStub(LogClass.ServiceFriend, $"Stubbed. Uuid: {uuid.ToString()} - " +
$"Unknown0: {unknown0}");
Logger.PrintStub(LogClass.ServiceFriend, $"Stubbed. Uuid: {Uuid.ToString()} - " +
$"Unknown0: {Unknown0}");
return 0;
}

View file

@ -5,21 +5,21 @@ namespace Ryujinx.HLE.HOS.Services.Friend
{
class IServiceCreator : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IServiceCreator()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, CreateFriendService }
};
}
public static long CreateFriendService(ServiceCtx context)
public static long CreateFriendService(ServiceCtx Context)
{
MakeObject(context, new IFriendService());
MakeObject(Context, new IFriendService());
return 0;
}

View file

@ -1,17 +1,21 @@
namespace Ryujinx.HLE.HOS.Services.FspSrv
using System;
using System.Collections.Generic;
using System.Text;
namespace Ryujinx.HLE.HOS.Services.FspSrv
{
public struct DirectoryEntry
{
public string Path { get; }
public long Size { get; }
public string Path { get; private set; }
public long Size { get; private set; }
public DirectoryEntryType EntryType { get; set; }
public DirectoryEntry(string path, DirectoryEntryType directoryEntryType, long size = 0)
public DirectoryEntry(string Path, DirectoryEntryType DirectoryEntryType, long Size = 0)
{
Path = path;
EntryType = directoryEntryType;
Size = size;
this.Path = Path;
EntryType = DirectoryEntryType;
this.Size = Size;
}
}
}

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.FspSrv
{
enum FileSystemType
enum FileSystemType : int
{
Logo = 2,
ContentControl = 3,

View file

@ -11,88 +11,88 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{
private const int DirectoryEntrySize = 0x310;
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private List<DirectoryEntry> _directoryEntries;
private List<DirectoryEntry> DirectoryEntries;
private int _currentItemIndex;
private int CurrentItemIndex;
public event EventHandler<EventArgs> Disposed;
public string DirectoryPath { get; }
public string DirectoryPath { get; private set; }
private IFileSystemProvider _provider;
private IFileSystemProvider Provider;
public IDirectory(string directoryPath, int flags, IFileSystemProvider provider)
public IDirectory(string DirectoryPath, int Flags, IFileSystemProvider Provider)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Read },
{ 1, GetEntryCount }
};
_provider = provider;
DirectoryPath = directoryPath;
this.Provider = Provider;
this.DirectoryPath = DirectoryPath;
_directoryEntries = new List<DirectoryEntry>();
DirectoryEntries = new List<DirectoryEntry>();
if ((flags & 1) != 0)
if ((Flags & 1) != 0)
{
_directoryEntries.AddRange(provider.GetDirectories(directoryPath));
DirectoryEntries.AddRange(Provider.GetDirectories(DirectoryPath));
}
if ((flags & 2) != 0)
if ((Flags & 2) != 0)
{
_directoryEntries.AddRange(provider.GetFiles(directoryPath));
DirectoryEntries.AddRange(Provider.GetFiles(DirectoryPath));
}
_currentItemIndex = 0;
CurrentItemIndex = 0;
}
// Read() -> (u64 count, buffer<nn::fssrv::sf::IDirectoryEntry, 6, 0> entries)
public long Read(ServiceCtx context)
public long Read(ServiceCtx Context)
{
long bufferPosition = context.Request.ReceiveBuff[0].Position;
long bufferLen = context.Request.ReceiveBuff[0].Size;
long BufferPosition = Context.Request.ReceiveBuff[0].Position;
long BufferLen = Context.Request.ReceiveBuff[0].Size;
int maxReadCount = (int)(bufferLen / DirectoryEntrySize);
int MaxReadCount = (int)(BufferLen / DirectoryEntrySize);
int count = Math.Min(_directoryEntries.Count - _currentItemIndex, maxReadCount);
int Count = Math.Min(DirectoryEntries.Count - CurrentItemIndex, MaxReadCount);
for (int index = 0; index < count; index++)
for (int Index = 0; Index < Count; Index++)
{
long position = bufferPosition + index * DirectoryEntrySize;
long Position = BufferPosition + Index * DirectoryEntrySize;
WriteDirectoryEntry(context, position, _directoryEntries[_currentItemIndex++]);
WriteDirectoryEntry(Context, Position, DirectoryEntries[CurrentItemIndex++]);
}
context.ResponseData.Write((long)count);
Context.ResponseData.Write((long)Count);
return 0;
}
private void WriteDirectoryEntry(ServiceCtx context, long position, DirectoryEntry entry)
private void WriteDirectoryEntry(ServiceCtx Context, long Position, DirectoryEntry Entry)
{
for (int offset = 0; offset < 0x300; offset += 8)
for (int Offset = 0; Offset < 0x300; Offset += 8)
{
context.Memory.WriteInt64(position + offset, 0);
Context.Memory.WriteInt64(Position + Offset, 0);
}
byte[] nameBuffer = Encoding.UTF8.GetBytes(Path.GetFileName(entry.Path));
byte[] NameBuffer = Encoding.UTF8.GetBytes(Path.GetFileName(Entry.Path));
context.Memory.WriteBytes(position, nameBuffer);
Context.Memory.WriteBytes(Position, NameBuffer);
context.Memory.WriteInt32(position + 0x300, 0); //Padding?
context.Memory.WriteInt32(position + 0x304, (byte)entry.EntryType);
context.Memory.WriteInt64(position + 0x308, entry.Size);
Context.Memory.WriteInt32(Position + 0x300, 0); //Padding?
Context.Memory.WriteInt32(Position + 0x304, (byte)Entry.EntryType);
Context.Memory.WriteInt64(Position + 0x308, Entry.Size);
}
// GetEntryCount() -> u64
public long GetEntryCount(ServiceCtx context)
public long GetEntryCount(ServiceCtx Context)
{
context.ResponseData.Write((long)_directoryEntries.Count);
Context.ResponseData.Write((long)DirectoryEntries.Count);
return 0;
}

View file

@ -7,19 +7,19 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{
class IFile : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private Stream _baseStream;
private Stream BaseStream;
public event EventHandler<EventArgs> Disposed;
public string HostPath { get; }
public string HostPath { get; private set; }
public IFile(Stream baseStream, string hostPath)
public IFile(Stream BaseStream, string HostPath)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Read },
{ 1, Write },
@ -28,71 +28,71 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{ 4, GetSize }
};
_baseStream = baseStream;
HostPath = hostPath;
this.BaseStream = BaseStream;
this.HostPath = HostPath;
}
// Read(u32, u64 offset, u64 size) -> (u64 out_size, buffer<u8, 0x46, 0> out_buf)
public long Read(ServiceCtx context)
public long Read(ServiceCtx Context)
{
long position = context.Request.ReceiveBuff[0].Position;
long Position = Context.Request.ReceiveBuff[0].Position;
long zero = context.RequestData.ReadInt64();
long offset = context.RequestData.ReadInt64();
long size = context.RequestData.ReadInt64();
long Zero = Context.RequestData.ReadInt64();
long Offset = Context.RequestData.ReadInt64();
long Size = Context.RequestData.ReadInt64();
byte[] data = new byte[size];
byte[] Data = new byte[Size];
_baseStream.Seek(offset, SeekOrigin.Begin);
BaseStream.Seek(Offset, SeekOrigin.Begin);
int readSize = _baseStream.Read(data, 0, (int)size);
int ReadSize = BaseStream.Read(Data, 0, (int)Size);
context.Memory.WriteBytes(position, data);
Context.Memory.WriteBytes(Position, Data);
context.ResponseData.Write((long)readSize);
Context.ResponseData.Write((long)ReadSize);
return 0;
}
// Write(u32, u64 offset, u64 size, buffer<u8, 0x45, 0>)
public long Write(ServiceCtx context)
public long Write(ServiceCtx Context)
{
long position = context.Request.SendBuff[0].Position;
long Position = Context.Request.SendBuff[0].Position;
long zero = context.RequestData.ReadInt64();
long offset = context.RequestData.ReadInt64();
long size = context.RequestData.ReadInt64();
long Zero = Context.RequestData.ReadInt64();
long Offset = Context.RequestData.ReadInt64();
long Size = Context.RequestData.ReadInt64();
byte[] data = context.Memory.ReadBytes(position, size);
byte[] Data = Context.Memory.ReadBytes(Position, Size);
_baseStream.Seek(offset, SeekOrigin.Begin);
_baseStream.Write(data, 0, (int)size);
BaseStream.Seek(Offset, SeekOrigin.Begin);
BaseStream.Write(Data, 0, (int)Size);
return 0;
}
// Flush()
public long Flush(ServiceCtx context)
public long Flush(ServiceCtx Context)
{
_baseStream.Flush();
BaseStream.Flush();
return 0;
}
// SetSize(u64 size)
public long SetSize(ServiceCtx context)
public long SetSize(ServiceCtx Context)
{
long size = context.RequestData.ReadInt64();
long Size = Context.RequestData.ReadInt64();
_baseStream.SetLength(size);
BaseStream.SetLength(Size);
return 0;
}
// GetSize() -> u64 fileSize
public long GetSize(ServiceCtx context)
public long GetSize(ServiceCtx Context)
{
context.ResponseData.Write(_baseStream.Length);
Context.ResponseData.Write(BaseStream.Length);
return 0;
}
@ -104,9 +104,9 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
protected virtual void Dispose(bool disposing)
{
if (disposing && _baseStream != null)
if (disposing && BaseStream != null)
{
_baseStream.Dispose();
BaseStream.Dispose();
Disposed?.Invoke(this, EventArgs.Empty);
}

View file

@ -11,19 +11,19 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{
class IFileSystem : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private HashSet<string> _openPaths;
private HashSet<string> OpenPaths;
private string _path;
private string Path;
private IFileSystemProvider _provider;
private IFileSystemProvider Provider;
public IFileSystem(string path, IFileSystemProvider provider)
public IFileSystem(string Path, IFileSystemProvider Provider)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, CreateFile },
{ 1, DeleteFile },
@ -38,196 +38,196 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{ 10, Commit },
{ 11, GetFreeSpaceSize },
{ 12, GetTotalSpaceSize },
{ 13, CleanDirectoryRecursively }
{ 13, CleanDirectoryRecursively },
//{ 14, GetFileTimeStampRaw }
};
_openPaths = new HashSet<string>();
OpenPaths = new HashSet<string>();
_path = path;
_provider = provider;
this.Path = Path;
this.Provider = Provider;
}
// CreateFile(u32 mode, u64 size, buffer<bytes<0x301>, 0x19, 0x301> path)
public long CreateFile(ServiceCtx context)
public long CreateFile(ServiceCtx Context)
{
string name = ReadUtf8String(context);
string Name = ReadUtf8String(Context);
long mode = context.RequestData.ReadInt64();
int size = context.RequestData.ReadInt32();
long Mode = Context.RequestData.ReadInt64();
int Size = Context.RequestData.ReadInt32();
string fileName = _provider.GetFullPath(name);
string FileName = Provider.GetFullPath(Name);
if (fileName == null)
if (FileName == null)
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
if (_provider.FileExists(fileName))
if (Provider.FileExists(FileName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
}
if (IsPathAlreadyInUse(fileName))
if (IsPathAlreadyInUse(FileName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse);
}
return _provider.CreateFile(fileName, size);
return Provider.CreateFile(FileName, Size);
}
// DeleteFile(buffer<bytes<0x301>, 0x19, 0x301> path)
public long DeleteFile(ServiceCtx context)
public long DeleteFile(ServiceCtx Context)
{
string name = ReadUtf8String(context);
string Name = ReadUtf8String(Context);
string fileName = _provider.GetFullPath(name);
string FileName = Provider.GetFullPath(Name);
if (!_provider.FileExists(fileName))
if (!Provider.FileExists(FileName))
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
if (IsPathAlreadyInUse(fileName))
if (IsPathAlreadyInUse(FileName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse);
}
return _provider.DeleteFile(fileName);
return Provider.DeleteFile(FileName);
}
// CreateDirectory(buffer<bytes<0x301>, 0x19, 0x301> path)
public long CreateDirectory(ServiceCtx context)
public long CreateDirectory(ServiceCtx Context)
{
string name = ReadUtf8String(context);
string Name = ReadUtf8String(Context);
string dirName = _provider.GetFullPath(name);
string DirName = Provider.GetFullPath(Name);
if (dirName == null)
if (DirName == null)
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
if (_provider.DirectoryExists(dirName))
if (Provider.DirectoryExists(DirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
}
if (IsPathAlreadyInUse(dirName))
if (IsPathAlreadyInUse(DirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse);
}
_provider.CreateDirectory(dirName);
Provider.CreateDirectory(DirName);
return 0;
}
// DeleteDirectory(buffer<bytes<0x301>, 0x19, 0x301> path)
public long DeleteDirectory(ServiceCtx context)
public long DeleteDirectory(ServiceCtx Context)
{
return DeleteDirectory(context, false);
return DeleteDirectory(Context, false);
}
// DeleteDirectoryRecursively(buffer<bytes<0x301>, 0x19, 0x301> path)
public long DeleteDirectoryRecursively(ServiceCtx context)
public long DeleteDirectoryRecursively(ServiceCtx Context)
{
return DeleteDirectory(context, true);
return DeleteDirectory(Context, true);
}
private long DeleteDirectory(ServiceCtx context, bool recursive)
private long DeleteDirectory(ServiceCtx Context, bool Recursive)
{
string name = ReadUtf8String(context);
string Name = ReadUtf8String(Context);
string dirName = _provider.GetFullPath(name);
string DirName = Provider.GetFullPath(Name);
if (!Directory.Exists(dirName))
if (!Directory.Exists(DirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
if (IsPathAlreadyInUse(dirName))
if (IsPathAlreadyInUse(DirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse);
}
_provider.DeleteDirectory(dirName, recursive);
Provider.DeleteDirectory(DirName, Recursive);
return 0;
}
// RenameFile(buffer<bytes<0x301>, 0x19, 0x301> oldPath, buffer<bytes<0x301>, 0x19, 0x301> newPath)
public long RenameFile(ServiceCtx context)
public long RenameFile(ServiceCtx Context)
{
string oldName = ReadUtf8String(context, 0);
string newName = ReadUtf8String(context, 1);
string OldName = ReadUtf8String(Context, 0);
string NewName = ReadUtf8String(Context, 1);
string oldFileName = _provider.GetFullPath(oldName);
string newFileName = _provider.GetFullPath(newName);
string OldFileName = Provider.GetFullPath(OldName);
string NewFileName = Provider.GetFullPath(NewName);
if (_provider.FileExists(oldFileName))
if (Provider.FileExists(OldFileName))
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
if (_provider.FileExists(newFileName))
if (Provider.FileExists(NewFileName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
}
if (IsPathAlreadyInUse(oldFileName))
if (IsPathAlreadyInUse(OldFileName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse);
}
return _provider.RenameFile(oldFileName, newFileName);
return Provider.RenameFile(OldFileName, NewFileName);
}
// RenameDirectory(buffer<bytes<0x301>, 0x19, 0x301> oldPath, buffer<bytes<0x301>, 0x19, 0x301> newPath)
public long RenameDirectory(ServiceCtx context)
public long RenameDirectory(ServiceCtx Context)
{
string oldName = ReadUtf8String(context, 0);
string newName = ReadUtf8String(context, 1);
string OldName = ReadUtf8String(Context, 0);
string NewName = ReadUtf8String(Context, 1);
string oldDirName = _provider.GetFullPath(oldName);
string newDirName = _provider.GetFullPath(newName);
string OldDirName = Provider.GetFullPath(OldName);
string NewDirName = Provider.GetFullPath(NewName);
if (!_provider.DirectoryExists(oldDirName))
if (!Provider.DirectoryExists(OldDirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
if (!_provider.DirectoryExists(newDirName))
if (!Provider.DirectoryExists(NewDirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
}
if (IsPathAlreadyInUse(oldDirName))
if (IsPathAlreadyInUse(OldDirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse);
}
return _provider.RenameDirectory(oldDirName, newDirName);
return Provider.RenameDirectory(OldDirName, NewDirName);
}
// GetEntryType(buffer<bytes<0x301>, 0x19, 0x301> path) -> nn::fssrv::sf::DirectoryEntryType
public long GetEntryType(ServiceCtx context)
public long GetEntryType(ServiceCtx Context)
{
string name = ReadUtf8String(context);
string Name = ReadUtf8String(Context);
string fileName = _provider.GetFullPath(name);
string FileName = Provider.GetFullPath(Name);
if (_provider.FileExists(fileName))
if (Provider.FileExists(FileName))
{
context.ResponseData.Write(1);
Context.ResponseData.Write(1);
}
else if (_provider.DirectoryExists(fileName))
else if (Provider.DirectoryExists(FileName))
{
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
}
else
{
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
@ -236,167 +236,167 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
}
// OpenFile(u32 mode, buffer<bytes<0x301>, 0x19, 0x301> path) -> object<nn::fssrv::sf::IFile> file
public long OpenFile(ServiceCtx context)
public long OpenFile(ServiceCtx Context)
{
int filterFlags = context.RequestData.ReadInt32();
int FilterFlags = Context.RequestData.ReadInt32();
string name = ReadUtf8String(context);
string Name = ReadUtf8String(Context);
string fileName = _provider.GetFullPath(name);
string FileName = Provider.GetFullPath(Name);
if (!_provider.FileExists(fileName))
if (!Provider.FileExists(FileName))
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
if (IsPathAlreadyInUse(fileName))
if (IsPathAlreadyInUse(FileName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse);
}
long error = _provider.OpenFile(fileName, out IFile fileInterface);
long Error = Provider.OpenFile(FileName, out IFile FileInterface);
if (error == 0)
if (Error == 0)
{
fileInterface.Disposed += RemoveFileInUse;
FileInterface.Disposed += RemoveFileInUse;
lock (_openPaths)
lock (OpenPaths)
{
_openPaths.Add(fileName);
OpenPaths.Add(FileName);
}
MakeObject(context, fileInterface);
MakeObject(Context, FileInterface);
return 0;
}
return error;
return Error;
}
// OpenDirectory(u32 filter_flags, buffer<bytes<0x301>, 0x19, 0x301> path) -> object<nn::fssrv::sf::IDirectory> directory
public long OpenDirectory(ServiceCtx context)
public long OpenDirectory(ServiceCtx Context)
{
int filterFlags = context.RequestData.ReadInt32();
int FilterFlags = Context.RequestData.ReadInt32();
string name = ReadUtf8String(context);
string Name = ReadUtf8String(Context);
string dirName = _provider.GetFullPath(name);
string DirName = Provider.GetFullPath(Name);
if (!_provider.DirectoryExists(dirName))
if (!Provider.DirectoryExists(DirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
if (IsPathAlreadyInUse(dirName))
if (IsPathAlreadyInUse(DirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse);
}
long error = _provider.OpenDirectory(dirName, filterFlags, out IDirectory dirInterface);
long Error = Provider.OpenDirectory(DirName, FilterFlags, out IDirectory DirInterface);
if (error == 0)
if (Error == 0)
{
dirInterface.Disposed += RemoveDirectoryInUse;
DirInterface.Disposed += RemoveDirectoryInUse;
lock (_openPaths)
lock (OpenPaths)
{
_openPaths.Add(dirName);
OpenPaths.Add(DirName);
}
MakeObject(context, dirInterface);
MakeObject(Context, DirInterface);
}
return error;
return Error;
}
// Commit()
public long Commit(ServiceCtx context)
public long Commit(ServiceCtx Context)
{
return 0;
}
// GetFreeSpaceSize(buffer<bytes<0x301>, 0x19, 0x301> path) -> u64 totalFreeSpace
public long GetFreeSpaceSize(ServiceCtx context)
public long GetFreeSpaceSize(ServiceCtx Context)
{
string name = ReadUtf8String(context);
string Name = ReadUtf8String(Context);
context.ResponseData.Write(_provider.GetFreeSpace(context));
Context.ResponseData.Write(Provider.GetFreeSpace(Context));
return 0;
}
// GetTotalSpaceSize(buffer<bytes<0x301>, 0x19, 0x301> path) -> u64 totalSize
public long GetTotalSpaceSize(ServiceCtx context)
public long GetTotalSpaceSize(ServiceCtx Context)
{
string name = ReadUtf8String(context);
string Name = ReadUtf8String(Context);
context.ResponseData.Write(_provider.GetFreeSpace(context));
Context.ResponseData.Write(Provider.GetFreeSpace(Context));
return 0;
}
// CleanDirectoryRecursively(buffer<bytes<0x301>, 0x19, 0x301> path)
public long CleanDirectoryRecursively(ServiceCtx context)
public long CleanDirectoryRecursively(ServiceCtx Context)
{
string name = ReadUtf8String(context);
string Name = ReadUtf8String(Context);
string dirName = _provider.GetFullPath(name);
string DirName = Provider.GetFullPath(Name);
if (!_provider.DirectoryExists(dirName))
if (!Provider.DirectoryExists(DirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
if (IsPathAlreadyInUse(dirName))
if (IsPathAlreadyInUse(DirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse);
}
foreach (DirectoryEntry entry in _provider.GetEntries(dirName))
foreach (DirectoryEntry Entry in Provider.GetEntries(DirName))
{
if (_provider.DirectoryExists(entry.Path))
if (Provider.DirectoryExists(Entry.Path))
{
_provider.DeleteDirectory(entry.Path, true);
Provider.DeleteDirectory(Entry.Path, true);
}
else if (_provider.FileExists(entry.Path))
else if (Provider.FileExists(Entry.Path))
{
_provider.DeleteFile(entry.Path);
Provider.DeleteFile(Entry.Path);
}
}
return 0;
}
private bool IsPathAlreadyInUse(string path)
private bool IsPathAlreadyInUse(string Path)
{
lock (_openPaths)
lock (OpenPaths)
{
return _openPaths.Contains(path);
return OpenPaths.Contains(Path);
}
}
private void RemoveFileInUse(object sender, EventArgs e)
{
IFile fileInterface = (IFile)sender;
IFile FileInterface = (IFile)sender;
lock (_openPaths)
lock (OpenPaths)
{
fileInterface.Disposed -= RemoveFileInUse;
FileInterface.Disposed -= RemoveFileInUse;
_openPaths.Remove(fileInterface.HostPath);
OpenPaths.Remove(FileInterface.HostPath);
}
}
private void RemoveDirectoryInUse(object sender, EventArgs e)
{
IDirectory dirInterface = (IDirectory)sender;
IDirectory DirInterface = (IDirectory)sender;
lock (_openPaths)
lock (OpenPaths)
{
dirInterface.Disposed -= RemoveDirectoryInUse;
DirInterface.Disposed -= RemoveDirectoryInUse;
_openPaths.Remove(dirInterface.DirectoryPath);
OpenPaths.Remove(DirInterface.DirectoryPath);
}
}
}

View file

@ -14,13 +14,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{
class IFileSystemProxy : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IFileSystemProxy()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 1, Initialize },
{ 8, OpenFileSystemWithId },
@ -36,246 +36,246 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
}
// Initialize(u64, pid)
public long Initialize(ServiceCtx context)
public long Initialize(ServiceCtx Context)
{
return 0;
}
// OpenFileSystemWithId(nn::fssrv::sf::FileSystemType filesystem_type, nn::ApplicationId tid, buffer<bytes<0x301>, 0x19, 0x301> path)
// -> object<nn::fssrv::sf::IFileSystem> contentFs
public long OpenFileSystemWithId(ServiceCtx context)
public long OpenFileSystemWithId(ServiceCtx Context)
{
FileSystemType fileSystemType = (FileSystemType)context.RequestData.ReadInt32();
long titleId = context.RequestData.ReadInt64();
string switchPath = ReadUtf8String(context);
string fullPath = context.Device.FileSystem.SwitchPathToSystemPath(switchPath);
FileSystemType FileSystemType = (FileSystemType)Context.RequestData.ReadInt32();
long TitleId = Context.RequestData.ReadInt64();
string SwitchPath = ReadUtf8String(Context);
string FullPath = Context.Device.FileSystem.SwitchPathToSystemPath(SwitchPath);
if (!File.Exists(fullPath))
if (!File.Exists(FullPath))
{
if (fullPath.Contains("."))
if (FullPath.Contains("."))
{
return OpenFileSystemFromInternalFile(context, fullPath);
return OpenFileSystemFromInternalFile(Context, FullPath);
}
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
FileStream fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read);
string extension = Path.GetExtension(fullPath);
FileStream FileStream = new FileStream(FullPath, FileMode.Open, FileAccess.Read);
string Extension = Path.GetExtension(FullPath);
if (extension == ".nca")
if (Extension == ".nca")
{
return OpenNcaFs(context, fullPath, fileStream);
return OpenNcaFs(Context, FullPath, FileStream);
}
else if (extension == ".nsp")
else if (Extension == ".nsp")
{
return OpenNsp(context, fullPath);
return OpenNsp(Context, FullPath);
}
return MakeError(ErrorModule.Fs, FsErr.InvalidInput);
}
// OpenBisFileSystem(nn::fssrv::sf::Partition partitionID, buffer<bytes<0x301>, 0x19, 0x301>) -> object<nn::fssrv::sf::IFileSystem> Bis
public long OpenBisFileSystem(ServiceCtx context)
public long OpenBisFileSystem(ServiceCtx Context)
{
int bisPartitionId = context.RequestData.ReadInt32();
string partitionString = ReadUtf8String(context);
string bisPartitonPath = string.Empty;
int BisPartitionId = Context.RequestData.ReadInt32();
string PartitionString = ReadUtf8String(Context);
string BisPartitonPath = string.Empty;
switch (bisPartitionId)
switch (BisPartitionId)
{
case 29:
bisPartitonPath = SafeNandPath;
BisPartitonPath = SafeNandPath;
break;
case 30:
case 31:
bisPartitonPath = SystemNandPath;
BisPartitonPath = SystemNandPath;
break;
case 32:
bisPartitonPath = UserNandPath;
BisPartitonPath = UserNandPath;
break;
default:
return MakeError(ErrorModule.Fs, FsErr.InvalidInput);
}
string fullPath = context.Device.FileSystem.GetFullPartitionPath(bisPartitonPath);
string FullPath = Context.Device.FileSystem.GetFullPartitionPath(BisPartitonPath);
FileSystemProvider fileSystemProvider = new FileSystemProvider(fullPath, context.Device.FileSystem.GetBasePath());
FileSystemProvider FileSystemProvider = new FileSystemProvider(FullPath, Context.Device.FileSystem.GetBasePath());
MakeObject(context, new IFileSystem(fullPath, fileSystemProvider));
MakeObject(Context, new IFileSystem(FullPath, FileSystemProvider));
return 0;
}
// OpenSdCardFileSystem() -> object<nn::fssrv::sf::IFileSystem>
public long OpenSdCardFileSystem(ServiceCtx context)
public long OpenSdCardFileSystem(ServiceCtx Context)
{
string sdCardPath = context.Device.FileSystem.GetSdCardPath();
string SdCardPath = Context.Device.FileSystem.GetSdCardPath();
FileSystemProvider fileSystemProvider = new FileSystemProvider(sdCardPath, context.Device.FileSystem.GetBasePath());
FileSystemProvider FileSystemProvider = new FileSystemProvider(SdCardPath, Context.Device.FileSystem.GetBasePath());
MakeObject(context, new IFileSystem(sdCardPath, fileSystemProvider));
MakeObject(Context, new IFileSystem(SdCardPath, FileSystemProvider));
return 0;
}
// OpenSaveDataFileSystem(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object<nn::fssrv::sf::IFileSystem> saveDataFs
public long OpenSaveDataFileSystem(ServiceCtx context)
public long OpenSaveDataFileSystem(ServiceCtx Context)
{
LoadSaveDataFileSystem(context);
LoadSaveDataFileSystem(Context);
return 0;
}
// OpenSaveDataFileSystemBySystemSaveDataId(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object<nn::fssrv::sf::IFileSystem> systemSaveDataFs
public long OpenSaveDataFileSystemBySystemSaveDataId(ServiceCtx context)
public long OpenSaveDataFileSystemBySystemSaveDataId(ServiceCtx Context)
{
LoadSaveDataFileSystem(context);
LoadSaveDataFileSystem(Context);
return 0;
}
// OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage
public long OpenDataStorageByCurrentProcess(ServiceCtx context)
public long OpenDataStorageByCurrentProcess(ServiceCtx Context)
{
MakeObject(context, new IStorage(context.Device.FileSystem.RomFs));
MakeObject(Context, new IStorage(Context.Device.FileSystem.RomFs));
return 0;
}
// OpenDataStorageByDataId(u8 storageId, nn::ApplicationId tid) -> object<nn::fssrv::sf::IStorage> dataStorage
public long OpenDataStorageByDataId(ServiceCtx context)
public long OpenDataStorageByDataId(ServiceCtx Context)
{
StorageId storageId = (StorageId)context.RequestData.ReadByte();
byte[] padding = context.RequestData.ReadBytes(7);
long titleId = context.RequestData.ReadInt64();
StorageId StorageId = (StorageId)Context.RequestData.ReadByte();
byte[] Padding = Context.RequestData.ReadBytes(7);
long TitleId = Context.RequestData.ReadInt64();
StorageId installedStorage =
context.Device.System.ContentManager.GetInstalledStorage(titleId, ContentType.Data, storageId);
StorageId InstalledStorage =
Context.Device.System.ContentManager.GetInstalledStorage(TitleId, ContentType.Data, StorageId);
if (installedStorage == StorageId.None)
if (InstalledStorage == StorageId.None)
{
installedStorage =
context.Device.System.ContentManager.GetInstalledStorage(titleId, ContentType.AocData, storageId);
InstalledStorage =
Context.Device.System.ContentManager.GetInstalledStorage(TitleId, ContentType.AocData, StorageId);
}
if (installedStorage != StorageId.None)
if (InstalledStorage != StorageId.None)
{
string contentPath = context.Device.System.ContentManager.GetInstalledContentPath(titleId, storageId, ContentType.AocData);
string ContentPath = Context.Device.System.ContentManager.GetInstalledContentPath(TitleId, StorageId, ContentType.AocData);
if (string.IsNullOrWhiteSpace(contentPath))
if (string.IsNullOrWhiteSpace(ContentPath))
{
contentPath = context.Device.System.ContentManager.GetInstalledContentPath(titleId, storageId, ContentType.AocData);
ContentPath = Context.Device.System.ContentManager.GetInstalledContentPath(TitleId, StorageId, ContentType.AocData);
}
string installPath = context.Device.FileSystem.SwitchPathToSystemPath(contentPath);
string InstallPath = Context.Device.FileSystem.SwitchPathToSystemPath(ContentPath);
if (!string.IsNullOrWhiteSpace(installPath))
if (!string.IsNullOrWhiteSpace(InstallPath))
{
string ncaPath = installPath;
string NcaPath = InstallPath;
if (File.Exists(ncaPath))
if (File.Exists(NcaPath))
{
FileStream ncaStream = new FileStream(ncaPath, FileMode.Open, FileAccess.Read);
Nca nca = new Nca(context.Device.System.KeySet, ncaStream, false);
NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
Stream romfsStream = nca.OpenSection(romfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel);
FileStream NcaStream = new FileStream(NcaPath, FileMode.Open, FileAccess.Read);
Nca Nca = new Nca(Context.Device.System.KeySet, NcaStream, false);
NcaSection RomfsSection = Nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
Stream RomfsStream = Nca.OpenSection(RomfsSection.SectionNum, false, Context.Device.System.FsIntegrityCheckLevel);
MakeObject(context, new IStorage(romfsStream));
MakeObject(Context, new IStorage(RomfsStream));
return 0;
}
else
{
throw new FileNotFoundException($"No Nca found in Path `{ncaPath}`.");
throw new FileNotFoundException($"No Nca found in Path `{NcaPath}`.");
}
}
else
{
throw new DirectoryNotFoundException($"Path for title id {titleId:x16} on Storage {storageId} was not found in Path {installPath}.");
throw new DirectoryNotFoundException($"Path for title id {TitleId:x16} on Storage {StorageId} was not found in Path {InstallPath}.");
}
}
throw new FileNotFoundException($"System archive with titleid {titleId:x16} was not found on Storage {storageId}. Found in {installedStorage}.");
throw new FileNotFoundException($"System archive with titleid {TitleId:x16} was not found on Storage {StorageId}. Found in {InstalledStorage}.");
}
// OpenPatchDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage>
public long OpenPatchDataStorageByCurrentProcess(ServiceCtx context)
public long OpenPatchDataStorageByCurrentProcess(ServiceCtx Context)
{
MakeObject(context, new IStorage(context.Device.FileSystem.RomFs));
MakeObject(Context, new IStorage(Context.Device.FileSystem.RomFs));
return 0;
}
// GetGlobalAccessLogMode() -> u32 logMode
public long GetGlobalAccessLogMode(ServiceCtx context)
public long GetGlobalAccessLogMode(ServiceCtx Context)
{
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
return 0;
}
public void LoadSaveDataFileSystem(ServiceCtx context)
public void LoadSaveDataFileSystem(ServiceCtx Context)
{
SaveSpaceId saveSpaceId = (SaveSpaceId)context.RequestData.ReadInt64();
SaveSpaceId SaveSpaceId = (SaveSpaceId)Context.RequestData.ReadInt64();
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
UInt128 userId = new UInt128(
context.RequestData.ReadInt64(),
context.RequestData.ReadInt64());
UInt128 UserId = new UInt128(
Context.RequestData.ReadInt64(),
Context.RequestData.ReadInt64());
long saveId = context.RequestData.ReadInt64();
SaveDataType saveDataType = (SaveDataType)context.RequestData.ReadByte();
SaveInfo saveInfo = new SaveInfo(titleId, saveId, saveDataType, userId, saveSpaceId);
string savePath = context.Device.FileSystem.GetGameSavePath(saveInfo, context);
FileSystemProvider fileSystemProvider = new FileSystemProvider(savePath, context.Device.FileSystem.GetBasePath());
long SaveId = Context.RequestData.ReadInt64();
SaveDataType SaveDataType = (SaveDataType)Context.RequestData.ReadByte();
SaveInfo SaveInfo = new SaveInfo(TitleId, SaveId, SaveDataType, UserId, SaveSpaceId);
string SavePath = Context.Device.FileSystem.GetGameSavePath(SaveInfo, Context);
FileSystemProvider FileSystemProvider = new FileSystemProvider(SavePath, Context.Device.FileSystem.GetBasePath());
MakeObject(context, new IFileSystem(savePath, fileSystemProvider));
MakeObject(Context, new IFileSystem(SavePath, FileSystemProvider));
}
private long OpenNsp(ServiceCtx context, string pfsPath)
private long OpenNsp(ServiceCtx Context, string PfsPath)
{
FileStream pfsFile = new FileStream(pfsPath, FileMode.Open, FileAccess.Read);
Pfs nsp = new Pfs(pfsFile);
PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));
FileStream PfsFile = new FileStream(PfsPath, FileMode.Open, FileAccess.Read);
Pfs Nsp = new Pfs(PfsFile);
PfsFileEntry TicketFile = Nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));
if (ticketFile != null)
if (TicketFile != null)
{
Ticket ticket = new Ticket(nsp.OpenFile(ticketFile));
Ticket Ticket = new Ticket(Nsp.OpenFile(TicketFile));
context.Device.System.KeySet.TitleKeys[ticket.RightsId] =
ticket.GetTitleKey(context.Device.System.KeySet);
Context.Device.System.KeySet.TitleKeys[Ticket.RightsId] =
Ticket.GetTitleKey(Context.Device.System.KeySet);
}
IFileSystem nspFileSystem = new IFileSystem(pfsPath, new PFsProvider(nsp));
IFileSystem NspFileSystem = new IFileSystem(PfsPath, new PFsProvider(Nsp));
MakeObject(context, nspFileSystem);
MakeObject(Context, NspFileSystem);
return 0;
}
private long OpenNcaFs(ServiceCtx context,string ncaPath, Stream ncaStream)
private long OpenNcaFs(ServiceCtx Context,string NcaPath, Stream NcaStream)
{
Nca nca = new Nca(context.Device.System.KeySet, ncaStream, false);
Nca Nca = new Nca(Context.Device.System.KeySet, NcaStream, false);
NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
NcaSection pfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Pfs0);
NcaSection RomfsSection = Nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
NcaSection PfsSection = Nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Pfs0);
if (romfsSection != null)
if (RomfsSection != null)
{
Stream romfsStream = nca.OpenSection(romfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel);
IFileSystem ncaFileSystem = new IFileSystem(ncaPath, new RomFsProvider(romfsStream));
Stream RomfsStream = Nca.OpenSection(RomfsSection.SectionNum, false, Context.Device.System.FsIntegrityCheckLevel);
IFileSystem NcaFileSystem = new IFileSystem(NcaPath, new RomFsProvider(RomfsStream));
MakeObject(context, ncaFileSystem);
MakeObject(Context, NcaFileSystem);
}
else if(pfsSection !=null)
else if(PfsSection !=null)
{
Stream pfsStream = nca.OpenSection(pfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel);
Pfs pfs = new Pfs(pfsStream);
IFileSystem ncaFileSystem = new IFileSystem(ncaPath, new PFsProvider(pfs));
Stream PfsStream = Nca.OpenSection(PfsSection.SectionNum, false, Context.Device.System.FsIntegrityCheckLevel);
Pfs Pfs = new Pfs(PfsStream);
IFileSystem NcaFileSystem = new IFileSystem(NcaPath, new PFsProvider(Pfs));
MakeObject(context, ncaFileSystem);
MakeObject(Context, NcaFileSystem);
}
else
{
@ -285,38 +285,38 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
private long OpenFileSystemFromInternalFile(ServiceCtx context, string fullPath)
private long OpenFileSystemFromInternalFile(ServiceCtx Context, string FullPath)
{
DirectoryInfo archivePath = new DirectoryInfo(fullPath).Parent;
DirectoryInfo ArchivePath = new DirectoryInfo(FullPath).Parent;
while (string.IsNullOrWhiteSpace(archivePath.Extension))
while (string.IsNullOrWhiteSpace(ArchivePath.Extension))
{
archivePath = archivePath.Parent;
ArchivePath = ArchivePath.Parent;
}
if (archivePath.Extension == ".nsp" && File.Exists(archivePath.FullName))
if (ArchivePath.Extension == ".nsp" && File.Exists(ArchivePath.FullName))
{
FileStream pfsFile = new FileStream(
archivePath.FullName.TrimEnd(Path.DirectorySeparatorChar),
FileStream PfsFile = new FileStream(
ArchivePath.FullName.TrimEnd(Path.DirectorySeparatorChar),
FileMode.Open,
FileAccess.Read);
Pfs nsp = new Pfs(pfsFile);
PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));
Pfs Nsp = new Pfs(PfsFile);
PfsFileEntry TicketFile = Nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));
if (ticketFile != null)
if (TicketFile != null)
{
Ticket ticket = new Ticket(nsp.OpenFile(ticketFile));
Ticket Ticket = new Ticket(Nsp.OpenFile(TicketFile));
context.Device.System.KeySet.TitleKeys[ticket.RightsId] =
ticket.GetTitleKey(context.Device.System.KeySet);
Context.Device.System.KeySet.TitleKeys[Ticket.RightsId] =
Ticket.GetTitleKey(Context.Device.System.KeySet);
}
string filename = fullPath.Replace(archivePath.FullName, string.Empty).TrimStart('\\');
string Filename = FullPath.Replace(ArchivePath.FullName, string.Empty).TrimStart('\\');
if (nsp.FileExists(filename))
if (Nsp.FileExists(Filename))
{
return OpenNcaFs(context, fullPath, nsp.OpenFile(filename));
return OpenNcaFs(Context, FullPath, Nsp.OpenFile(Filename));
}
}

View file

@ -6,47 +6,47 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{
class IStorage : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private Stream _baseStream;
private Stream BaseStream;
public IStorage(Stream baseStream)
public IStorage(Stream BaseStream)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Read }
};
_baseStream = baseStream;
this.BaseStream = BaseStream;
}
// Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer
public long Read(ServiceCtx context)
public long Read(ServiceCtx Context)
{
long offset = context.RequestData.ReadInt64();
long size = context.RequestData.ReadInt64();
long Offset = Context.RequestData.ReadInt64();
long Size = Context.RequestData.ReadInt64();
if (context.Request.ReceiveBuff.Count > 0)
if (Context.Request.ReceiveBuff.Count > 0)
{
IpcBuffDesc buffDesc = context.Request.ReceiveBuff[0];
IpcBuffDesc BuffDesc = Context.Request.ReceiveBuff[0];
//Use smaller length to avoid overflows.
if (size > buffDesc.Size)
if (Size > BuffDesc.Size)
{
size = buffDesc.Size;
Size = BuffDesc.Size;
}
byte[] data = new byte[size];
byte[] Data = new byte[Size];
lock (_baseStream)
lock (BaseStream)
{
_baseStream.Seek(offset, SeekOrigin.Begin);
_baseStream.Read(data, 0, data.Length);
BaseStream.Seek(Offset, SeekOrigin.Begin);
BaseStream.Read(Data, 0, Data.Length);
}
context.Memory.WriteBytes(buffDesc.Position, data);
Context.Memory.WriteBytes(BuffDesc.Position, Data);
}
return 0;

View file

@ -5,26 +5,26 @@ namespace Ryujinx.HLE.HOS.Services.Hid
public enum HidNpadJoyAssignmentMode
{
Dual,
Single
Single,
}
public enum HidNpadHandheldActivationMode
{
Dual,
Single,
None
None,
}
public enum HidNpadJoyDeviceType
{
Left,
Right
Right,
}
public enum HidNpadJoyHoldType
{
Vertical,
Horizontal
Horizontal,
}
[Flags]
@ -36,6 +36,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
Dual = 1 << 2,
Left = 1 << 3,
Right = 1 << 4,
Invalid = 1 << 5
Invalid = 1 << 5,
}
}

View file

@ -10,7 +10,7 @@
{
None,
Left,
Right
Right,
}
public struct HidVibrationDeviceValue

View file

@ -5,21 +5,21 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
class IActiveApplicationDeviceList : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IActiveApplicationDeviceList()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, ActivateVibrationDevice }
};
}
public long ActivateVibrationDevice(ServiceCtx context)
public long ActivateVibrationDevice(ServiceCtx Context)
{
int vibrationDeviceHandle = context.RequestData.ReadInt32();
int VibrationDeviceHandle = Context.RequestData.ReadInt32();
return 0;
}

View file

@ -7,30 +7,30 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
class IAppletResource : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KSharedMemory _hidSharedMem;
private KSharedMemory HidSharedMem;
public IAppletResource(KSharedMemory hidSharedMem)
public IAppletResource(KSharedMemory HidSharedMem)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetSharedMemoryHandle }
};
_hidSharedMem = hidSharedMem;
this.HidSharedMem = HidSharedMem;
}
public long GetSharedMemoryHandle(ServiceCtx context)
public long GetSharedMemoryHandle(ServiceCtx Context)
{
if (context.Process.HandleTable.GenerateHandle(_hidSharedMem, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(HidSharedMem, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -11,176 +11,176 @@ namespace Ryujinx.HLE.HOS.Services
{
public abstract IReadOnlyDictionary<int, ServiceProcessRequest> Commands { get; }
private IdDictionary _domainObjects;
private IdDictionary DomainObjects;
private int _selfId;
private int SelfId;
private bool _isDomain;
private bool IsDomain;
public IpcService()
{
_domainObjects = new IdDictionary();
DomainObjects = new IdDictionary();
_selfId = -1;
SelfId = -1;
}
public int ConvertToDomain()
{
if (_selfId == -1)
if (SelfId == -1)
{
_selfId = _domainObjects.Add(this);
SelfId = DomainObjects.Add(this);
}
_isDomain = true;
IsDomain = true;
return _selfId;
return SelfId;
}
public void ConvertToSession()
{
_isDomain = false;
IsDomain = false;
}
public void CallMethod(ServiceCtx context)
public void CallMethod(ServiceCtx Context)
{
IIpcService service = this;
IIpcService Service = this;
if (_isDomain)
if (IsDomain)
{
int domainWord0 = context.RequestData.ReadInt32();
int domainObjId = context.RequestData.ReadInt32();
int DomainWord0 = Context.RequestData.ReadInt32();
int DomainObjId = Context.RequestData.ReadInt32();
int domainCmd = (domainWord0 >> 0) & 0xff;
int inputObjCount = (domainWord0 >> 8) & 0xff;
int dataPayloadSize = (domainWord0 >> 16) & 0xffff;
int DomainCmd = (DomainWord0 >> 0) & 0xff;
int InputObjCount = (DomainWord0 >> 8) & 0xff;
int DataPayloadSize = (DomainWord0 >> 16) & 0xffff;
context.RequestData.BaseStream.Seek(0x10 + dataPayloadSize, SeekOrigin.Begin);
Context.RequestData.BaseStream.Seek(0x10 + DataPayloadSize, SeekOrigin.Begin);
for (int index = 0; index < inputObjCount; index++)
for (int Index = 0; Index < InputObjCount; Index++)
{
context.Request.ObjectIds.Add(context.RequestData.ReadInt32());
Context.Request.ObjectIds.Add(Context.RequestData.ReadInt32());
}
context.RequestData.BaseStream.Seek(0x10, SeekOrigin.Begin);
Context.RequestData.BaseStream.Seek(0x10, SeekOrigin.Begin);
if (domainCmd == 1)
if (DomainCmd == 1)
{
service = GetObject(domainObjId);
Service = GetObject(DomainObjId);
context.ResponseData.Write(0L);
context.ResponseData.Write(0L);
Context.ResponseData.Write(0L);
Context.ResponseData.Write(0L);
}
else if (domainCmd == 2)
else if (DomainCmd == 2)
{
Delete(domainObjId);
Delete(DomainObjId);
context.ResponseData.Write(0L);
Context.ResponseData.Write(0L);
return;
}
else
{
throw new NotImplementedException($"Domain command: {domainCmd}");
throw new NotImplementedException($"Domain command: {DomainCmd}");
}
}
long sfciMagic = context.RequestData.ReadInt64();
int commandId = (int)context.RequestData.ReadInt64();
long SfciMagic = Context.RequestData.ReadInt64();
int CommandId = (int)Context.RequestData.ReadInt64();
if (service.Commands.TryGetValue(commandId, out ServiceProcessRequest processRequest))
if (Service.Commands.TryGetValue(CommandId, out ServiceProcessRequest ProcessRequest))
{
context.ResponseData.BaseStream.Seek(_isDomain ? 0x20 : 0x10, SeekOrigin.Begin);
Context.ResponseData.BaseStream.Seek(IsDomain ? 0x20 : 0x10, SeekOrigin.Begin);
Logger.PrintDebug(LogClass.KernelIpc, $"{service.GetType().Name}: {processRequest.Method.Name}");
Logger.PrintDebug(LogClass.KernelIpc, $"{Service.GetType().Name}: {ProcessRequest.Method.Name}");
long result = processRequest(context);
long Result = ProcessRequest(Context);
if (_isDomain)
if (IsDomain)
{
foreach (int id in context.Response.ObjectIds)
foreach (int Id in Context.Response.ObjectIds)
{
context.ResponseData.Write(id);
Context.ResponseData.Write(Id);
}
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
Context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
context.ResponseData.Write(context.Response.ObjectIds.Count);
Context.ResponseData.Write(Context.Response.ObjectIds.Count);
}
context.ResponseData.BaseStream.Seek(_isDomain ? 0x10 : 0, SeekOrigin.Begin);
Context.ResponseData.BaseStream.Seek(IsDomain ? 0x10 : 0, SeekOrigin.Begin);
context.ResponseData.Write(IpcMagic.Sfco);
context.ResponseData.Write(result);
Context.ResponseData.Write(IpcMagic.Sfco);
Context.ResponseData.Write(Result);
}
else
{
string dbgMessage = $"{context.Session.ServiceName} {service.GetType().Name}: {commandId}";
string DbgMessage = $"{Context.Session.ServiceName} {Service.GetType().Name}: {CommandId}";
throw new NotImplementedException(dbgMessage);
throw new NotImplementedException(DbgMessage);
}
}
protected static void MakeObject(ServiceCtx context, IpcService obj)
protected static void MakeObject(ServiceCtx Context, IpcService Obj)
{
IpcService service = context.Session.Service;
IpcService Service = Context.Session.Service;
if (service._isDomain)
if (Service.IsDomain)
{
context.Response.ObjectIds.Add(service.Add(obj));
Context.Response.ObjectIds.Add(Service.Add(Obj));
}
else
{
KSession session = new KSession(obj, context.Session.ServiceName);
KSession Session = new KSession(Obj, Context.Session.ServiceName);
if (context.Process.HandleTable.GenerateHandle(session, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(Session, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeMove(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
}
}
protected static T GetObject<T>(ServiceCtx context, int index) where T : IpcService
protected static T GetObject<T>(ServiceCtx Context, int Index) where T : IpcService
{
IpcService service = context.Session.Service;
IpcService Service = Context.Session.Service;
if (!service._isDomain)
if (!Service.IsDomain)
{
int handle = context.Request.HandleDesc.ToMove[index];
int Handle = Context.Request.HandleDesc.ToMove[Index];
KSession session = context.Process.HandleTable.GetObject<KSession>(handle);
KSession Session = Context.Process.HandleTable.GetObject<KSession>(Handle);
return session?.Service is T ? (T)session.Service : null;
return Session?.Service is T ? (T)Session.Service : null;
}
int objId = context.Request.ObjectIds[index];
int ObjId = Context.Request.ObjectIds[Index];
IIpcService obj = service.GetObject(objId);
IIpcService Obj = Service.GetObject(ObjId);
return obj is T ? (T)obj : null;
return Obj is T ? (T)Obj : null;
}
private int Add(IIpcService obj)
private int Add(IIpcService Obj)
{
return _domainObjects.Add(obj);
return DomainObjects.Add(Obj);
}
private bool Delete(int id)
private bool Delete(int Id)
{
object obj = _domainObjects.Delete(id);
object Obj = DomainObjects.Delete(Id);
if (obj is IDisposable disposableObj)
if (Obj is IDisposable DisposableObj)
{
disposableObj.Dispose();
DisposableObj.Dispose();
}
return obj != null;
return Obj != null;
}
private IIpcService GetObject(int id)
private IIpcService GetObject(int Id)
{
return _domainObjects.GetData<IIpcService>(id);
return DomainObjects.GetData<IIpcService>(Id);
}
}
}

View file

@ -6,15 +6,15 @@ namespace Ryujinx.HLE.HOS.Services.Irs
{
class IIrSensorServer : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private bool _activated;
private bool Activated;
public IIrSensorServer()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 302, ActivateIrsensor },
{ 303, DeactivateIrsensor }
@ -22,21 +22,21 @@ namespace Ryujinx.HLE.HOS.Services.Irs
}
// ActivateIrsensor(nn::applet::AppletResourceUserId, pid)
public long ActivateIrsensor(ServiceCtx context)
public long ActivateIrsensor(ServiceCtx Context)
{
long appletResourceUserId = context.RequestData.ReadInt64();
long AppletResourceUserId = Context.RequestData.ReadInt64();
Logger.PrintStub(LogClass.ServiceIrs, $"Stubbed. AppletResourceUserId: {appletResourceUserId}");
Logger.PrintStub(LogClass.ServiceIrs, $"Stubbed. AppletResourceUserId: {AppletResourceUserId}");
return 0;
}
// DeactivateIrsensor(nn::applet::AppletResourceUserId, pid)
public long DeactivateIrsensor(ServiceCtx context)
public long DeactivateIrsensor(ServiceCtx Context)
{
long appletResourceUserId = context.RequestData.ReadInt64();
long AppletResourceUserId = Context.RequestData.ReadInt64();
Logger.PrintStub(LogClass.ServiceIrs, $"Stubbed. AppletResourceUserId: {appletResourceUserId}");
Logger.PrintStub(LogClass.ServiceIrs, $"Stubbed. AppletResourceUserId: {AppletResourceUserId}");
return 0;
}

View file

@ -4,6 +4,7 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.Loaders.Executables;
using Ryujinx.HLE.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -50,54 +51,54 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
class NrrInfo
{
public NrrHeader Header { get; }
public List<byte[]> Hashes { get; }
public long NrrAddress { get; }
public NrrHeader Header { get; private set; }
public List<byte[]> Hashes { get; private set; }
public long NrrAddress { get; private set; }
public NrrInfo(long nrrAddress, NrrHeader header, List<byte[]> hashes)
public NrrInfo(long NrrAddress, NrrHeader Header, List<byte[]> Hashes)
{
NrrAddress = nrrAddress;
Header = header;
Hashes = hashes;
this.NrrAddress = NrrAddress;
this.Header = Header;
this.Hashes = Hashes;
}
}
class NroInfo
{
public NxRelocatableObject Executable { get; }
public NxRelocatableObject Executable { get; private set; }
public byte[] Hash { get; }
public ulong NroAddress { get; }
public ulong NroSize { get; }
public ulong BssAddress { get; }
public ulong BssSize { get; }
public ulong TotalSize { get; }
public byte[] Hash { get; private set; }
public ulong NroAddress { get; private set; }
public ulong NroSize { get; private set; }
public ulong BssAddress { get; private set; }
public ulong BssSize { get; private set; }
public ulong TotalSize { get; private set; }
public ulong NroMappedAddress { get; set; }
public NroInfo(
NxRelocatableObject executable,
byte[] hash,
ulong nroAddress,
ulong nroSize,
ulong bssAddress,
ulong bssSize,
ulong totalSize)
NxRelocatableObject Executable,
byte[] Hash,
ulong NroAddress,
ulong NroSize,
ulong BssAddress,
ulong BssSize,
ulong TotalSize)
{
Executable = executable;
Hash = hash;
NroAddress = nroAddress;
NroSize = nroSize;
BssAddress = bssAddress;
BssSize = bssSize;
TotalSize = totalSize;
this.Executable = Executable;
this.Hash = Hash;
this.NroAddress = NroAddress;
this.NroSize = NroSize;
this.BssAddress = BssAddress;
this.BssSize = BssSize;
this.TotalSize = TotalSize;
}
}
class IRoInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private const int MaxNrr = 0x40;
private const int MaxNro = 0x40;
@ -105,70 +106,70 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
private const uint NrrMagic = 0x3052524E;
private const uint NroMagic = 0x304F524E;
private List<NrrInfo> _nrrInfos;
private List<NroInfo> _nroInfos;
private List<NrrInfo> NrrInfos;
private List<NroInfo> NroInfos;
private bool _isInitialized;
private bool IsInitialized;
public IRoInterface()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, LoadNro },
{ 1, UnloadNro },
{ 2, LoadNrr },
{ 3, UnloadNrr },
{ 4, Initialize }
{ 4, Initialize },
};
_nrrInfos = new List<NrrInfo>(MaxNrr);
_nroInfos = new List<NroInfo>(MaxNro);
NrrInfos = new List<NrrInfo>(MaxNrr);
NroInfos = new List<NroInfo>(MaxNro);
}
private long ParseNrr(out NrrInfo nrrInfo, ServiceCtx context, long nrrAddress, long nrrSize)
private long ParseNrr(out NrrInfo NrrInfo, ServiceCtx Context, long NrrAddress, long NrrSize)
{
nrrInfo = null;
NrrInfo = null;
if (nrrSize == 0 || nrrAddress + nrrSize <= nrrAddress || (nrrSize & 0xFFF) != 0)
if (NrrSize == 0 || NrrAddress + NrrSize <= NrrAddress || (NrrSize & 0xFFF) != 0)
{
return MakeError(ErrorModule.Loader, LoaderErr.BadSize);
}
else if ((nrrAddress & 0xFFF) != 0)
else if ((NrrAddress & 0xFFF) != 0)
{
return MakeError(ErrorModule.Loader, LoaderErr.UnalignedAddress);
}
StructReader reader = new StructReader(context.Memory, nrrAddress);
NrrHeader header = reader.Read<NrrHeader>();
StructReader Reader = new StructReader(Context.Memory, NrrAddress);
NrrHeader Header = Reader.Read<NrrHeader>();
if (header.Magic != NrrMagic)
if (Header.Magic != NrrMagic)
{
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNrr);
}
else if (header.NrrSize != nrrSize)
else if (Header.NrrSize != NrrSize)
{
return MakeError(ErrorModule.Loader, LoaderErr.BadSize);
}
List<byte[]> hashes = new List<byte[]>();
List<byte[]> Hashes = new List<byte[]>();
for (int i = 0; i < header.HashCount; i++)
for (int i = 0; i < Header.HashCount; i++)
{
hashes.Add(context.Memory.ReadBytes(nrrAddress + header.HashOffset + (i * 0x20), 0x20));
Hashes.Add(Context.Memory.ReadBytes(NrrAddress + Header.HashOffset + (i * 0x20), 0x20));
}
nrrInfo = new NrrInfo(nrrAddress, header, hashes);
NrrInfo = new NrrInfo(NrrAddress, Header, Hashes);
return 0;
}
public bool IsNroHashPresent(byte[] nroHash)
public bool IsNroHashPresent(byte[] NroHash)
{
foreach (NrrInfo info in _nrrInfos)
foreach (NrrInfo Info in NrrInfos)
{
foreach (byte[] hash in info.Hashes)
foreach (byte[] Hash in Info.Hashes)
{
if (hash.SequenceEqual(nroHash))
if (Hash.SequenceEqual(NroHash))
{
return true;
}
@ -178,11 +179,11 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return false;
}
public bool IsNroLoaded(byte[] nroHash)
public bool IsNroLoaded(byte[] NroHash)
{
foreach (NroInfo info in _nroInfos)
foreach (NroInfo Info in NroInfos)
{
if (info.Hash.SequenceEqual(nroHash))
if (Info.Hash.SequenceEqual(NroHash))
{
return true;
}
@ -191,206 +192,206 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return false;
}
public long ParseNro(out NroInfo res, ServiceCtx context, ulong nroAddress, ulong nroSize, ulong bssAddress, ulong bssSize)
public long ParseNro(out NroInfo Res, ServiceCtx Context, ulong NroAddress, ulong NroSize, ulong BssAddress, ulong BssSize)
{
res = null;
Res = null;
if (_nroInfos.Count >= MaxNro)
if (NroInfos.Count >= MaxNro)
{
return MakeError(ErrorModule.Loader, LoaderErr.MaxNro);
}
else if (nroSize == 0 || nroAddress + nroSize <= nroAddress || (nroSize & 0xFFF) != 0)
else if (NroSize == 0 || NroAddress + NroSize <= NroAddress || (NroSize & 0xFFF) != 0)
{
return MakeError(ErrorModule.Loader, LoaderErr.BadSize);
}
else if (bssSize != 0 && bssAddress + bssSize <= bssAddress)
else if (BssSize != 0 && BssAddress + BssSize <= BssAddress)
{
return MakeError(ErrorModule.Loader, LoaderErr.BadSize);
}
else if ((nroAddress & 0xFFF) != 0)
else if ((NroAddress & 0xFFF) != 0)
{
return MakeError(ErrorModule.Loader, LoaderErr.UnalignedAddress);
}
uint magic = context.Memory.ReadUInt32((long)nroAddress + 0x10);
uint nroFileSize = context.Memory.ReadUInt32((long)nroAddress + 0x18);
uint Magic = Context.Memory.ReadUInt32((long)NroAddress + 0x10);
uint NroFileSize = Context.Memory.ReadUInt32((long)NroAddress + 0x18);
if (magic != NroMagic || nroSize != nroFileSize)
if (Magic != NroMagic || NroSize != NroFileSize)
{
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNro);
}
byte[] nroData = context.Memory.ReadBytes((long)nroAddress, (long)nroSize);
byte[] nroHash = null;
byte[] NroData = Context.Memory.ReadBytes((long)NroAddress, (long)NroSize);
byte[] NroHash = null;
MemoryStream stream = new MemoryStream(nroData);
MemoryStream Stream = new MemoryStream(NroData);
using (SHA256 hasher = SHA256.Create())
using (SHA256 Hasher = SHA256.Create())
{
nroHash = hasher.ComputeHash(stream);
NroHash = Hasher.ComputeHash(Stream);
}
if (!IsNroHashPresent(nroHash))
if (!IsNroHashPresent(NroHash))
{
return MakeError(ErrorModule.Loader, LoaderErr.NroHashNotPresent);
}
if (IsNroLoaded(nroHash))
if (IsNroLoaded(NroHash))
{
return MakeError(ErrorModule.Loader, LoaderErr.NroAlreadyLoaded);
}
stream.Position = 0;
Stream.Position = 0;
NxRelocatableObject executable = new NxRelocatableObject(stream, nroAddress, bssAddress);
NxRelocatableObject Executable = new NxRelocatableObject(Stream, NroAddress, BssAddress);
// check if everything is page align.
if ((executable.Text.Length & 0xFFF) != 0 || (executable.Ro.Length & 0xFFF) != 0 ||
(executable.Data.Length & 0xFFF) != 0 || (executable.BssSize & 0xFFF) != 0)
if ((Executable.Text.Length & 0xFFF) != 0 || (Executable.RO.Length & 0xFFF) != 0 ||
(Executable.Data.Length & 0xFFF) != 0 || (Executable.BssSize & 0xFFF) != 0)
{
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNro);
}
// check if everything is contiguous.
if (executable.RoOffset != executable.TextOffset + executable.Text.Length ||
executable.DataOffset != executable.RoOffset + executable.Ro.Length ||
nroFileSize != executable.DataOffset + executable.Data.Length)
if (Executable.ROOffset != Executable.TextOffset + Executable.Text.Length ||
Executable.DataOffset != Executable.ROOffset + Executable.RO.Length ||
NroFileSize != Executable.DataOffset + Executable.Data.Length)
{
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNro);
}
// finally check the bss size match.
if ((ulong)executable.BssSize != bssSize)
if ((ulong)Executable.BssSize != BssSize)
{
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNro);
}
int totalSize = executable.Text.Length + executable.Ro.Length + executable.Data.Length + executable.BssSize;
int TotalSize = Executable.Text.Length + Executable.RO.Length + Executable.Data.Length + Executable.BssSize;
res = new NroInfo(
executable,
nroHash,
nroAddress,
nroSize,
bssAddress,
bssSize,
(ulong)totalSize);
Res = new NroInfo(
Executable,
NroHash,
NroAddress,
NroSize,
BssAddress,
BssSize,
(ulong)TotalSize);
return 0;
}
private long MapNro(ServiceCtx context, NroInfo info, out ulong nroMappedAddress)
private long MapNro(ServiceCtx Context, NroInfo Info, out ulong NroMappedAddress)
{
nroMappedAddress = 0;
NroMappedAddress = 0;
KMemoryManager memMgr = context.Process.MemoryManager;
KMemoryManager MemMgr = Context.Process.MemoryManager;
ulong targetAddress = memMgr.GetAddrSpaceBaseAddr();
ulong TargetAddress = MemMgr.GetAddrSpaceBaseAddr();
while (true)
{
if (targetAddress + info.TotalSize >= memMgr.AddrSpaceEnd)
if (TargetAddress + Info.TotalSize >= MemMgr.AddrSpaceEnd)
{
return MakeError(ErrorModule.Loader, LoaderErr.InvalidMemoryState);
}
KMemoryInfo memInfo = memMgr.QueryMemory(targetAddress);
KMemoryInfo MemInfo = MemMgr.QueryMemory(TargetAddress);
if (memInfo.State == MemoryState.Unmapped && memInfo.Size >= info.TotalSize)
if (MemInfo.State == MemoryState.Unmapped && MemInfo.Size >= Info.TotalSize)
{
if (!memMgr.InsideHeapRegion (targetAddress, info.TotalSize) &&
!memMgr.InsideAliasRegion(targetAddress, info.TotalSize))
if (!MemMgr.InsideHeapRegion (TargetAddress, Info.TotalSize) &&
!MemMgr.InsideAliasRegion(TargetAddress, Info.TotalSize))
{
break;
}
}
targetAddress += memInfo.Size;
TargetAddress += MemInfo.Size;
}
KernelResult result = memMgr.MapProcessCodeMemory(targetAddress, info.NroAddress, info.NroSize);
KernelResult Result = MemMgr.MapProcessCodeMemory(TargetAddress, Info.NroAddress, Info.NroSize);
if (result != KernelResult.Success)
if (Result != KernelResult.Success)
{
return MakeError(ErrorModule.Loader, LoaderErr.InvalidMemoryState);
}
ulong bssTargetAddress = targetAddress + info.NroSize;
ulong BssTargetAddress = TargetAddress + Info.NroSize;
if (info.BssSize != 0)
if (Info.BssSize != 0)
{
result = memMgr.MapProcessCodeMemory(bssTargetAddress, info.BssAddress, info.BssSize);
Result = MemMgr.MapProcessCodeMemory(BssTargetAddress, Info.BssAddress, Info.BssSize);
if (result != KernelResult.Success)
if (Result != KernelResult.Success)
{
memMgr.UnmapProcessCodeMemory(targetAddress, info.NroAddress, info.NroSize);
MemMgr.UnmapProcessCodeMemory(TargetAddress, Info.NroAddress, Info.NroSize);
return MakeError(ErrorModule.Loader, LoaderErr.InvalidMemoryState);
}
}
result = LoadNroIntoMemory(context.Process, info.Executable, targetAddress);
Result = LoadNroIntoMemory(Context.Process, Info.Executable, TargetAddress);
if (result != KernelResult.Success)
if (Result != KernelResult.Success)
{
memMgr.UnmapProcessCodeMemory(targetAddress, info.NroAddress, info.NroSize);
MemMgr.UnmapProcessCodeMemory(TargetAddress, Info.NroAddress, Info.NroSize);
if (info.BssSize != 0)
if (Info.BssSize != 0)
{
memMgr.UnmapProcessCodeMemory(bssTargetAddress, info.BssAddress, info.BssSize);
MemMgr.UnmapProcessCodeMemory(BssTargetAddress, Info.BssAddress, Info.BssSize);
}
return 0;
}
info.NroMappedAddress = targetAddress;
nroMappedAddress = targetAddress;
Info.NroMappedAddress = TargetAddress;
NroMappedAddress = TargetAddress;
return 0;
}
private KernelResult LoadNroIntoMemory(KProcess process, IExecutable relocatableObject, ulong baseAddress)
private KernelResult LoadNroIntoMemory(KProcess Process, IExecutable RelocatableObject, ulong BaseAddress)
{
ulong textStart = baseAddress + (ulong)relocatableObject.TextOffset;
ulong roStart = baseAddress + (ulong)relocatableObject.RoOffset;
ulong dataStart = baseAddress + (ulong)relocatableObject.DataOffset;
ulong TextStart = BaseAddress + (ulong)RelocatableObject.TextOffset;
ulong ROStart = BaseAddress + (ulong)RelocatableObject.ROOffset;
ulong DataStart = BaseAddress + (ulong)RelocatableObject.DataOffset;
ulong bssStart = dataStart + (ulong)relocatableObject.Data.Length;
ulong BssStart = DataStart + (ulong)RelocatableObject.Data.Length;
ulong bssEnd = BitUtils.AlignUp(bssStart + (ulong)relocatableObject.BssSize, KMemoryManager.PageSize);
ulong BssEnd = BitUtils.AlignUp(BssStart + (ulong)RelocatableObject.BssSize, KMemoryManager.PageSize);
process.CpuMemory.WriteBytes((long)textStart, relocatableObject.Text);
process.CpuMemory.WriteBytes((long)roStart, relocatableObject.Ro);
process.CpuMemory.WriteBytes((long)dataStart, relocatableObject.Data);
Process.CpuMemory.WriteBytes((long)TextStart, RelocatableObject.Text);
Process.CpuMemory.WriteBytes((long)ROStart, RelocatableObject.RO);
Process.CpuMemory.WriteBytes((long)DataStart, RelocatableObject.Data);
MemoryHelper.FillWithZeros(process.CpuMemory, (long)bssStart, (int)(bssEnd - bssStart));
MemoryHelper.FillWithZeros(Process.CpuMemory, (long)BssStart, (int)(BssEnd - BssStart));
KernelResult result;
KernelResult Result;
result = process.MemoryManager.SetProcessMemoryPermission(textStart, roStart - textStart, MemoryPermission.ReadAndExecute);
Result = Process.MemoryManager.SetProcessMemoryPermission(TextStart, ROStart - TextStart, MemoryPermission.ReadAndExecute);
if (result != KernelResult.Success)
if (Result != KernelResult.Success)
{
return result;
return Result;
}
result = process.MemoryManager.SetProcessMemoryPermission(roStart, dataStart - roStart, MemoryPermission.Read);
Result = Process.MemoryManager.SetProcessMemoryPermission(ROStart, DataStart - ROStart, MemoryPermission.Read);
if (result != KernelResult.Success)
if (Result != KernelResult.Success)
{
return result;
return Result;
}
return process.MemoryManager.SetProcessMemoryPermission(dataStart, bssEnd - dataStart, MemoryPermission.ReadAndWrite);
return Process.MemoryManager.SetProcessMemoryPermission(DataStart, BssEnd - DataStart, MemoryPermission.ReadAndWrite);
}
private long RemoveNrrInfo(long nrrAddress)
private long RemoveNrrInfo(long NrrAddress)
{
foreach (NrrInfo info in _nrrInfos)
foreach (NrrInfo Info in NrrInfos)
{
if (info.NrrAddress == nrrAddress)
if (Info.NrrAddress == NrrAddress)
{
_nrrInfos.Remove(info);
NrrInfos.Remove(Info);
return 0;
}
@ -399,46 +400,46 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return MakeError(ErrorModule.Loader, LoaderErr.BadNrrAddress);
}
private long RemoveNroInfo(ServiceCtx context, ulong nroMappedAddress)
private long RemoveNroInfo(ServiceCtx Context, ulong NroMappedAddress)
{
foreach (NroInfo info in _nroInfos)
foreach (NroInfo Info in NroInfos)
{
if (info.NroMappedAddress == nroMappedAddress)
if (Info.NroMappedAddress == NroMappedAddress)
{
_nroInfos.Remove(info);
NroInfos.Remove(Info);
ulong textSize = (ulong)info.Executable.Text.Length;
ulong roSize = (ulong)info.Executable.Ro.Length;
ulong dataSize = (ulong)info.Executable.Data.Length;
ulong bssSize = (ulong)info.Executable.BssSize;
ulong TextSize = (ulong)Info.Executable.Text.Length;
ulong ROSize = (ulong)Info.Executable.RO.Length;
ulong DataSize = (ulong)Info.Executable.Data.Length;
ulong BssSize = (ulong)Info.Executable.BssSize;
KernelResult result = KernelResult.Success;
KernelResult Result = KernelResult.Success;
if (info.Executable.BssSize != 0)
if (Info.Executable.BssSize != 0)
{
result = context.Process.MemoryManager.UnmapProcessCodeMemory(
info.NroMappedAddress + textSize + roSize + dataSize,
info.Executable.BssAddress,
bssSize);
Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(
Info.NroMappedAddress + TextSize + ROSize + DataSize,
Info.Executable.BssAddress,
BssSize);
}
if (result == KernelResult.Success)
if (Result == KernelResult.Success)
{
result = context.Process.MemoryManager.UnmapProcessCodeMemory(
info.NroMappedAddress + textSize + roSize,
info.Executable.SourceAddress + textSize + roSize,
dataSize);
Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(
Info.NroMappedAddress + TextSize + ROSize,
Info.Executable.SourceAddress + TextSize + ROSize,
DataSize);
if (result == KernelResult.Success)
if (Result == KernelResult.Success)
{
result = context.Process.MemoryManager.UnmapProcessCodeMemory(
info.NroMappedAddress,
info.Executable.SourceAddress,
textSize + roSize);
Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(
Info.NroMappedAddress,
Info.Executable.SourceAddress,
TextSize + ROSize);
}
}
return (long)result;
return (long)Result;
}
}
@ -446,125 +447,125 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
}
// LoadNro(u64, u64, u64, u64, u64, pid) -> u64
public long LoadNro(ServiceCtx context)
public long LoadNro(ServiceCtx Context)
{
long result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
long Result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
// Zero
context.RequestData.ReadUInt64();
Context.RequestData.ReadUInt64();
ulong nroHeapAddress = context.RequestData.ReadUInt64();
ulong nroSize = context.RequestData.ReadUInt64();
ulong bssHeapAddress = context.RequestData.ReadUInt64();
ulong bssSize = context.RequestData.ReadUInt64();
ulong NroHeapAddress = Context.RequestData.ReadUInt64();
ulong NroSize = Context.RequestData.ReadUInt64();
ulong BssHeapAddress = Context.RequestData.ReadUInt64();
ulong BssSize = Context.RequestData.ReadUInt64();
ulong nroMappedAddress = 0;
ulong NroMappedAddress = 0;
if (_isInitialized)
if (IsInitialized)
{
NroInfo info;
NroInfo Info;
result = ParseNro(out info, context, nroHeapAddress, nroSize, bssHeapAddress, bssSize);
Result = ParseNro(out Info, Context, NroHeapAddress, NroSize, BssHeapAddress, BssSize);
if (result == 0)
if (Result == 0)
{
result = MapNro(context, info, out nroMappedAddress);
Result = MapNro(Context, Info, out NroMappedAddress);
if (result == 0)
if (Result == 0)
{
_nroInfos.Add(info);
NroInfos.Add(Info);
}
}
}
context.ResponseData.Write(nroMappedAddress);
Context.ResponseData.Write(NroMappedAddress);
return result;
return Result;
}
// UnloadNro(u64, u64, pid)
public long UnloadNro(ServiceCtx context)
public long UnloadNro(ServiceCtx Context)
{
long result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
long Result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
// Zero
context.RequestData.ReadUInt64();
Context.RequestData.ReadUInt64();
ulong nroMappedAddress = context.RequestData.ReadUInt64();
ulong NroMappedAddress = Context.RequestData.ReadUInt64();
if (_isInitialized)
if (IsInitialized)
{
if ((nroMappedAddress & 0xFFF) != 0)
if ((NroMappedAddress & 0xFFF) != 0)
{
return MakeError(ErrorModule.Loader, LoaderErr.UnalignedAddress);
}
result = RemoveNroInfo(context, nroMappedAddress);
Result = RemoveNroInfo(Context, NroMappedAddress);
}
return result;
return Result;
}
// LoadNrr(u64, u64, u64, pid)
public long LoadNrr(ServiceCtx context)
public long LoadNrr(ServiceCtx Context)
{
long result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
long Result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
// Zero
context.RequestData.ReadUInt64();
Context.RequestData.ReadUInt64();
long nrrAddress = context.RequestData.ReadInt64();
long nrrSize = context.RequestData.ReadInt64();
long NrrAddress = Context.RequestData.ReadInt64();
long NrrSize = Context.RequestData.ReadInt64();
if (_isInitialized)
if (IsInitialized)
{
NrrInfo info;
result = ParseNrr(out info, context, nrrAddress, nrrSize);
NrrInfo Info;
Result = ParseNrr(out Info, Context, NrrAddress, NrrSize);
if(result == 0)
if(Result == 0)
{
if (_nrrInfos.Count >= MaxNrr)
if (NrrInfos.Count >= MaxNrr)
{
result = MakeError(ErrorModule.Loader, LoaderErr.MaxNrr);
Result = MakeError(ErrorModule.Loader, LoaderErr.MaxNrr);
}
else
{
_nrrInfos.Add(info);
NrrInfos.Add(Info);
}
}
}
return result;
return Result;
}
// UnloadNrr(u64, u64, pid)
public long UnloadNrr(ServiceCtx context)
public long UnloadNrr(ServiceCtx Context)
{
long result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
long Result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
// Zero
context.RequestData.ReadUInt64();
Context.RequestData.ReadUInt64();
long nrrHeapAddress = context.RequestData.ReadInt64();
long NrrHeapAddress = Context.RequestData.ReadInt64();
if (_isInitialized)
if (IsInitialized)
{
if ((nrrHeapAddress & 0xFFF) != 0)
if ((NrrHeapAddress & 0xFFF) != 0)
{
return MakeError(ErrorModule.Loader, LoaderErr.UnalignedAddress);
}
result = RemoveNrrInfo(nrrHeapAddress);
Result = RemoveNrrInfo(NrrHeapAddress);
}
return result;
return Result;
}
// Initialize(u64, pid, KObject)
public long Initialize(ServiceCtx context)
public long Initialize(ServiceCtx Context)
{
// TODO: we actually ignore the pid and process handle receive, we will need to use them when we will have multi process support.
_isInitialized = true;
IsInitialized = true;
return 0;
}

View file

@ -5,21 +5,21 @@ namespace Ryujinx.HLE.HOS.Services.Lm
{
class ILogService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ILogService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Initialize }
};
}
public long Initialize(ServiceCtx context)
public long Initialize(ServiceCtx Context)
{
MakeObject(context, new ILogger());
MakeObject(Context, new ILogger());
return 0;
}

View file

@ -8,91 +8,91 @@ namespace Ryujinx.HLE.HOS.Services.Lm
{
class ILogger : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ILogger()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Log }
};
}
public long Log(ServiceCtx context)
public long Log(ServiceCtx Context)
{
(long bufPos, long bufSize) = context.Request.GetBufferType0x21();
byte[] logBuffer = context.Memory.ReadBytes(bufPos, bufSize);
(long BufPos, long BufSize) = Context.Request.GetBufferType0x21();
byte[] LogBuffer = Context.Memory.ReadBytes(BufPos, BufSize);
using (MemoryStream ms = new MemoryStream(logBuffer))
using (MemoryStream MS = new MemoryStream(LogBuffer))
{
BinaryReader reader = new BinaryReader(ms);
BinaryReader Reader = new BinaryReader(MS);
long pid = reader.ReadInt64();
long threadContext = reader.ReadInt64();
short flags = reader.ReadInt16();
byte level = reader.ReadByte();
byte verbosity = reader.ReadByte();
int payloadLength = reader.ReadInt32();
long Pid = Reader.ReadInt64();
long ThreadContext = Reader.ReadInt64();
short Flags = Reader.ReadInt16();
byte Level = Reader.ReadByte();
byte Verbosity = Reader.ReadByte();
int PayloadLength = Reader.ReadInt32();
StringBuilder sb = new StringBuilder();
StringBuilder SB = new StringBuilder();
sb.AppendLine("Guest log:");
SB.AppendLine("Guest log:");
while (ms.Position < ms.Length)
while (MS.Position < MS.Length)
{
byte type = reader.ReadByte();
byte size = reader.ReadByte();
byte Type = Reader.ReadByte();
byte Size = Reader.ReadByte();
LmLogField field = (LmLogField)type;
LmLogField Field = (LmLogField)Type;
string fieldStr = string.Empty;
string FieldStr = string.Empty;
if (field == LmLogField.Start)
if (Field == LmLogField.Start)
{
reader.ReadBytes(size);
Reader.ReadBytes(Size);
continue;
}
else if (field == LmLogField.Stop)
else if (Field == LmLogField.Stop)
{
break;
}
else if (field == LmLogField.Line)
else if (Field == LmLogField.Line)
{
fieldStr = $"{field}: {reader.ReadInt32()}";
FieldStr = $"{Field}: {Reader.ReadInt32()}";
}
else if (field == LmLogField.DropCount)
else if (Field == LmLogField.DropCount)
{
fieldStr = $"{field}: {reader.ReadInt64()}";
FieldStr = $"{Field}: {Reader.ReadInt64()}";
}
else if (field == LmLogField.Time)
else if (Field == LmLogField.Time)
{
fieldStr = $"{field}: {reader.ReadInt64()}s";
FieldStr = $"{Field}: {Reader.ReadInt64()}s";
}
else if (field < LmLogField.Count)
else if (Field < LmLogField.Count)
{
fieldStr = $"{field}: '{Encoding.UTF8.GetString(reader.ReadBytes(size)).TrimEnd()}'";
FieldStr = $"{Field}: '{Encoding.UTF8.GetString(Reader.ReadBytes(Size)).TrimEnd()}'";
}
else
{
fieldStr = $"Field{field}: '{Encoding.UTF8.GetString(reader.ReadBytes(size)).TrimEnd()}'";
FieldStr = $"Field{Field}: '{Encoding.UTF8.GetString(Reader.ReadBytes(Size)).TrimEnd()}'";
}
sb.AppendLine(" " + fieldStr);
SB.AppendLine(" " + FieldStr);
}
string text = sb.ToString();
string Text = SB.ToString();
switch((LmLogLevel)level)
switch((LmLogLevel)Level)
{
case LmLogLevel.Trace: Logger.PrintDebug (LogClass.ServiceLm, text); break;
case LmLogLevel.Info: Logger.PrintInfo (LogClass.ServiceLm, text); break;
case LmLogLevel.Warning: Logger.PrintWarning(LogClass.ServiceLm, text); break;
case LmLogLevel.Error: Logger.PrintError (LogClass.ServiceLm, text); break;
case LmLogLevel.Critical: Logger.PrintError (LogClass.ServiceLm, text); break;
case LmLogLevel.Trace: Logger.PrintDebug (LogClass.ServiceLm, Text); break;
case LmLogLevel.Info: Logger.PrintInfo (LogClass.ServiceLm, Text); break;
case LmLogLevel.Warning: Logger.PrintWarning(LogClass.ServiceLm, Text); break;
case LmLogLevel.Error: Logger.PrintError (LogClass.ServiceLm, Text); break;
case LmLogLevel.Critical: Logger.PrintError (LogClass.ServiceLm, Text); break;
}
}

View file

@ -12,15 +12,15 @@ namespace Ryujinx.HLE.HOS.Services.Lr
{
class ILocationResolver : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private StorageId _storageId;
private StorageId StorageId;
public ILocationResolver(StorageId storageId)
public ILocationResolver(StorageId StorageId)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, ResolveProgramPath },
{ 1, RedirectProgramPath },
@ -40,103 +40,103 @@ namespace Ryujinx.HLE.HOS.Services.Lr
{ 15, DeleteInfoHtmlNcaPath }
};
_storageId = storageId;
this.StorageId = StorageId;
}
// DeleteInfoHtmlNcaPath()
public long DeleteInfoHtmlNcaPath(ServiceCtx context)
public long DeleteInfoHtmlNcaPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Manual);
DeleteContentPath(Context, TitleId, ContentType.Manual);
return 0;
}
// DeleteDocHtmlNcaPath()
public long DeleteDocHtmlNcaPath(ServiceCtx context)
public long DeleteDocHtmlNcaPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Manual);
DeleteContentPath(Context, TitleId, ContentType.Manual);
return 0;
}
// DeleteControlNcaPath()
public long DeleteControlNcaPath(ServiceCtx context)
public long DeleteControlNcaPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Control);
DeleteContentPath(Context, TitleId, ContentType.Control);
return 0;
}
// DeleteProgramNcaPath()
public long DeleteProgramNcaPath(ServiceCtx context)
public long DeleteProgramNcaPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
DeleteContentPath(context, titleId, ContentType.Program);
DeleteContentPath(Context, TitleId, ContentType.Program);
return 0;
}
// ClearLocationResolver2()
public long ClearLocationResolver2(ServiceCtx context)
public long ClearLocationResolver2(ServiceCtx Context)
{
context.Device.System.ContentManager.RefreshEntries(_storageId, 1);
Context.Device.System.ContentManager.RefreshEntries(StorageId, 1);
return 0;
}
// SetProgramNcaPath2()
public long SetProgramNcaPath2(ServiceCtx context)
public long SetProgramNcaPath2(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Program);
RedirectPath(Context, TitleId, 1, ContentType.Program);
return 0;
}
// RedirectApplicationControlPath()
public long RedirectApplicationControlPath(ServiceCtx context)
public long RedirectApplicationControlPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Control);
RedirectPath(Context, TitleId, 1, ContentType.Control);
return 0;
}
// RedirectApplicationHtmlDocumentPath()
public long RedirectApplicationHtmlDocumentPath(ServiceCtx context)
public long RedirectApplicationHtmlDocumentPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Manual);
RedirectPath(Context, TitleId, 1, ContentType.Manual);
return 0;
}
// RedirectApplicationLegalInformationPath()
public long RedirectApplicationLegalInformationPath(ServiceCtx context)
public long RedirectApplicationLegalInformationPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
RedirectPath(context, titleId, 1, ContentType.Manual);
RedirectPath(Context, TitleId, 1, ContentType.Manual);
return 0;
}
// ResolveDataPath()
public long ResolveDataPath(ServiceCtx context)
public long ResolveDataPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Data) || ResolvePath(context, titleId, ContentType.AocData))
if (ResolvePath(Context, TitleId, ContentType.Data) || ResolvePath(Context, TitleId, ContentType.AocData))
{
return 0;
}
@ -147,11 +147,11 @@ namespace Ryujinx.HLE.HOS.Services.Lr
}
// ResolveApplicationHtmlDocumentPath()
public long ResolveApplicationHtmlDocumentPath(ServiceCtx context)
public long ResolveApplicationHtmlDocumentPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Manual))
if (ResolvePath(Context, TitleId, ContentType.Manual))
{
return 0;
}
@ -162,11 +162,11 @@ namespace Ryujinx.HLE.HOS.Services.Lr
}
// ResolveApplicationLegalInformationPath()
public long ResolveApplicationLegalInformationPath(ServiceCtx context)
public long ResolveApplicationLegalInformationPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Manual))
if (ResolvePath(Context, TitleId, ContentType.Manual))
{
return 0;
}
@ -177,11 +177,11 @@ namespace Ryujinx.HLE.HOS.Services.Lr
}
// ResolveApplicationControlPath()
public long ResolveApplicationControlPath(ServiceCtx context)
public long ResolveApplicationControlPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Control))
if (ResolvePath(Context, TitleId, ContentType.Control))
{
return 0;
}
@ -192,29 +192,29 @@ namespace Ryujinx.HLE.HOS.Services.Lr
}
// RedirectProgramPath()
public long RedirectProgramPath(ServiceCtx context)
public long RedirectProgramPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
RedirectPath(context, titleId, 0, ContentType.Program);
RedirectPath(Context, TitleId, 0, ContentType.Program);
return 0;
}
// Refresh()
public long Refresh(ServiceCtx context)
public long Refresh(ServiceCtx Context)
{
context.Device.System.ContentManager.RefreshEntries(_storageId, 1);
Context.Device.System.ContentManager.RefreshEntries(StorageId, 1);
return 0;
}
// ResolveProgramPath()
public long ResolveProgramPath(ServiceCtx context)
public long ResolveProgramPath(ServiceCtx Context)
{
long titleId = context.RequestData.ReadInt64();
long TitleId = Context.RequestData.ReadInt64();
if (ResolvePath(context, titleId, ContentType.Program))
if (ResolvePath(Context, TitleId, ContentType.Program))
{
return 0;
}
@ -224,27 +224,27 @@ namespace Ryujinx.HLE.HOS.Services.Lr
}
}
private void RedirectPath(ServiceCtx context, long titleId, int flag, ContentType contentType)
private void RedirectPath(ServiceCtx Context, long TitleId, int Flag, ContentType ContentType)
{
string contentPath = ReadUtf8String(context);
LocationEntry newLocation = new LocationEntry(contentPath, flag, titleId, contentType);
string ContentPath = ReadUtf8String(Context);
LocationEntry NewLocation = new LocationEntry(ContentPath, Flag, TitleId, ContentType);
context.Device.System.ContentManager.RedirectLocation(newLocation, _storageId);
Context.Device.System.ContentManager.RedirectLocation(NewLocation, StorageId);
}
private bool ResolvePath(ServiceCtx context, long titleId,ContentType contentType)
private bool ResolvePath(ServiceCtx Context, long TitleId,ContentType ContentType)
{
ContentManager contentManager = context.Device.System.ContentManager;
string contentPath = contentManager.GetInstalledContentPath(titleId, _storageId, ContentType.Program);
ContentManager ContentManager = Context.Device.System.ContentManager;
string ContentPath = ContentManager.GetInstalledContentPath(TitleId, StorageId, ContentType.Program);
if (!string.IsNullOrWhiteSpace(contentPath))
if (!string.IsNullOrWhiteSpace(ContentPath))
{
long position = context.Request.RecvListBuff[0].Position;
long size = context.Request.RecvListBuff[0].Size;
long Position = Context.Request.RecvListBuff[0].Position;
long Size = Context.Request.RecvListBuff[0].Size;
byte[] contentPathBuffer = Encoding.UTF8.GetBytes(contentPath);
byte[] ContentPathBuffer = Encoding.UTF8.GetBytes(ContentPath);
context.Memory.WriteBytes(position, contentPathBuffer);
Context.Memory.WriteBytes(Position, ContentPathBuffer);
}
else
{
@ -254,12 +254,12 @@ namespace Ryujinx.HLE.HOS.Services.Lr
return true;
}
private void DeleteContentPath(ServiceCtx context, long titleId, ContentType contentType)
private void DeleteContentPath(ServiceCtx Context, long TitleId, ContentType ContentType)
{
ContentManager contentManager = context.Device.System.ContentManager;
string contentPath = contentManager.GetInstalledContentPath(titleId, _storageId, ContentType.Manual);
ContentManager ContentManager = Context.Device.System.ContentManager;
string ContentPath = ContentManager.GetInstalledContentPath(TitleId, StorageId, ContentType.Manual);
contentManager.ClearEntry(titleId, ContentType.Manual, _storageId);
ContentManager.ClearEntry(TitleId, ContentType.Manual, StorageId);
}
}
}

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.FileSystem;
@ -6,24 +7,24 @@ namespace Ryujinx.HLE.HOS.Services.Lr
{
class ILocationResolverManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ILocationResolverManager()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, OpenLocationResolver }
{ 0, OpenLocationResolver },
};
}
// OpenLocationResolver()
private long OpenLocationResolver(ServiceCtx context)
private long OpenLocationResolver(ServiceCtx Context)
{
StorageId storageId = (StorageId)context.RequestData.ReadByte();
StorageId StorageId = (StorageId)Context.RequestData.ReadByte();
MakeObject(context, new ILocationResolver(storageId));
MakeObject(Context, new ILocationResolver(StorageId));
return 0;
}

View file

@ -6,13 +6,13 @@ namespace Ryujinx.HLE.HOS.Services.Mm
{
class IRequest : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IRequest()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 1, InitializeOld },
{ 4, Initialize },
@ -23,43 +23,43 @@ namespace Ryujinx.HLE.HOS.Services.Mm
}
// InitializeOld(u32, u32, u32)
public long InitializeOld(ServiceCtx context)
public long InitializeOld(ServiceCtx Context)
{
int unknown0 = context.RequestData.ReadInt32();
int unknown1 = context.RequestData.ReadInt32();
int unknown2 = context.RequestData.ReadInt32();
int Unknown0 = Context.RequestData.ReadInt32();
int Unknown1 = Context.RequestData.ReadInt32();
int Unknown2 = Context.RequestData.ReadInt32();
Logger.PrintStub(LogClass.ServiceMm, "Stubbed.");
return 0;
}
public long Initialize(ServiceCtx context)
public long Initialize(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceMm, "Stubbed.");
return 0;
}
public long Finalize(ServiceCtx context)
public long Finalize(ServiceCtx Context)
{
context.Device.Gpu.UninitializeVideoDecoder();
Context.Device.Gpu.UninitializeVideoDecoder();
Logger.PrintStub(LogClass.ServiceMm, "Stubbed.");
return 0;
}
public long SetAndWait(ServiceCtx context)
public long SetAndWait(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceMm, "Stubbed.");
return 0;
}
public long Get(ServiceCtx context)
public long Get(ServiceCtx Context)
{
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
Logger.PrintStub(LogClass.ServiceMm, "Stubbed.");

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Ncm
{
class IContentManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IContentManager()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
};

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Ncm
{
class IContentStorage : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IContentStorage()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
};

View file

@ -9,25 +9,25 @@ namespace Ryujinx.HLE.HOS.Services.Nfp
{
class IUser : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private const HidControllerId NpadId = HidControllerId.ControllerPlayer1;
private const HidControllerId NpadId = HidControllerId.CONTROLLER_PLAYER_1;
private State _state = State.NonInitialized;
private State State = State.NonInitialized;
private DeviceState _deviceState = DeviceState.Initialized;
private DeviceState DeviceState = DeviceState.Initialized;
private KEvent _activateEvent;
private KEvent ActivateEvent;
private KEvent _deactivateEvent;
private KEvent DeactivateEvent;
private KEvent _availabilityChangeEvent;
private KEvent AvailabilityChangeEvent;
public IUser(Horizon system)
public IUser(Horizon System)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Initialize },
{ 17, AttachActivateEvent },
@ -38,85 +38,85 @@ namespace Ryujinx.HLE.HOS.Services.Nfp
{ 23, AttachAvailabilityChangeEvent }
};
_activateEvent = new KEvent(system);
_deactivateEvent = new KEvent(system);
_availabilityChangeEvent = new KEvent(system);
ActivateEvent = new KEvent(System);
DeactivateEvent = new KEvent(System);
AvailabilityChangeEvent = new KEvent(System);
}
public long Initialize(ServiceCtx context)
public long Initialize(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceNfp, "Stubbed.");
_state = State.Initialized;
State = State.Initialized;
return 0;
}
public long AttachActivateEvent(ServiceCtx context)
public long AttachActivateEvent(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceNfp, "Stubbed.");
if (context.Process.HandleTable.GenerateHandle(_activateEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(ActivateEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);;
return 0;
}
public long AttachDeactivateEvent(ServiceCtx context)
public long AttachDeactivateEvent(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceNfp, "Stubbed.");
if (context.Process.HandleTable.GenerateHandle(_deactivateEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(DeactivateEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
return 0;
}
public long GetState(ServiceCtx context)
public long GetState(ServiceCtx Context)
{
context.ResponseData.Write((int)_state);
Context.ResponseData.Write((int)State);
Logger.PrintStub(LogClass.ServiceNfp, "Stubbed.");
return 0;
}
public long GetDeviceState(ServiceCtx context)
public long GetDeviceState(ServiceCtx Context)
{
context.ResponseData.Write((int)_deviceState);
Context.ResponseData.Write((int)DeviceState);
Logger.PrintStub(LogClass.ServiceNfp, "Stubbed.");
return 0;
}
public long GetNpadId(ServiceCtx context)
public long GetNpadId(ServiceCtx Context)
{
context.ResponseData.Write((int)NpadId);
Context.ResponseData.Write((int)NpadId);
Logger.PrintStub(LogClass.ServiceNfp, "Stubbed.");
return 0;
}
public long AttachAvailabilityChangeEvent(ServiceCtx context)
public long AttachAvailabilityChangeEvent(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceNfp, "Stubbed.");
if (context.Process.HandleTable.GenerateHandle(_availabilityChangeEvent.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(AvailabilityChangeEvent.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
return 0;
}

View file

@ -5,21 +5,21 @@ namespace Ryujinx.HLE.HOS.Services.Nfp
{
class IUserManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IUserManager()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetUserInterface }
};
}
public long GetUserInterface(ServiceCtx context)
public long GetUserInterface(ServiceCtx Context)
{
MakeObject(context, new IUser(context.Device.System));
MakeObject(Context, new IUser(Context.Device.System));
return 0;
}

View file

@ -13,44 +13,44 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
{
class IGeneralService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IGeneralService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 4, CreateRequest },
{ 12, GetCurrentIpAddress }
};
}
public long CreateRequest(ServiceCtx context)
public long CreateRequest(ServiceCtx Context)
{
int unknown = context.RequestData.ReadInt32();
int Unknown = Context.RequestData.ReadInt32();
MakeObject(context, new IRequest(context.Device.System));
MakeObject(Context, new IRequest(Context.Device.System));
Logger.PrintStub(LogClass.ServiceNifm, "Stubbed.");
return 0;
}
public long GetCurrentIpAddress(ServiceCtx context)
public long GetCurrentIpAddress(ServiceCtx Context)
{
if (!NetworkInterface.GetIsNetworkAvailable())
{
return MakeError(ErrorModule.Nifm, NifmErr.NoInternetConnection);
}
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
IPHostEntry Host = Dns.GetHostEntry(Dns.GetHostName());
IPAddress address = host.AddressList.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork);
IPAddress Address = Host.AddressList.FirstOrDefault(A => A.AddressFamily == AddressFamily.InterNetwork);
context.ResponseData.Write(BitConverter.ToUInt32(address.GetAddressBytes()));
Context.ResponseData.Write(BitConverter.ToUInt32(Address.GetAddressBytes()));
Logger.PrintInfo(LogClass.ServiceNifm, $"Console's local IP is \"{address}\".");
Logger.PrintInfo(LogClass.ServiceNifm, $"Console's local IP is \"{Address}\".");
return 0;
}

View file

@ -8,16 +8,16 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
{
class IRequest : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent _event0;
private KEvent _event1;
private KEvent Event0;
private KEvent Event1;
public IRequest(Horizon system)
public IRequest(Horizon System)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetRequestState },
{ 1, GetResult },
@ -27,58 +27,58 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
{ 11, SetConnectionConfirmationOption }
};
_event0 = new KEvent(system);
_event1 = new KEvent(system);
Event0 = new KEvent(System);
Event1 = new KEvent(System);
}
public long GetRequestState(ServiceCtx context)
public long GetRequestState(ServiceCtx Context)
{
context.ResponseData.Write(1);
Context.ResponseData.Write(1);
Logger.PrintStub(LogClass.ServiceNifm, "Stubbed.");
return 0;
}
public long GetResult(ServiceCtx context)
public long GetResult(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceNifm, "Stubbed.");
return 0;
}
public long GetSystemEventReadableHandles(ServiceCtx context)
public long GetSystemEventReadableHandles(ServiceCtx Context)
{
if (context.Process.HandleTable.GenerateHandle(_event0.ReadableEvent, out int handle0) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(Event0.ReadableEvent, out int Handle0) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
if (context.Process.HandleTable.GenerateHandle(_event1.ReadableEvent, out int handle1) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(Event1.ReadableEvent, out int Handle1) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle0, handle1);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle0, Handle1);
return 0;
}
public long Cancel(ServiceCtx context)
public long Cancel(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceNifm, "Stubbed.");
return 0;
}
public long Submit(ServiceCtx context)
public long Submit(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceNifm, "Stubbed.");
return 0;
}
public long SetConnectionConfirmationOption(ServiceCtx context)
public long SetConnectionConfirmationOption(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceNifm, "Stubbed.");

View file

@ -5,29 +5,29 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
{
class IStaticService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IStaticService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 4, CreateGeneralServiceOld },
{ 5, CreateGeneralService }
};
}
public long CreateGeneralServiceOld(ServiceCtx context)
public long CreateGeneralServiceOld(ServiceCtx Context)
{
MakeObject(context, new IGeneralService());
MakeObject(Context, new IGeneralService());
return 0;
}
public long CreateGeneralService(ServiceCtx context)
public long CreateGeneralService(ServiceCtx Context)
{
MakeObject(context, new IGeneralService());
MakeObject(Context, new IGeneralService());
return 0;
}

View file

@ -6,35 +6,35 @@ namespace Ryujinx.HLE.HOS.Services.Ns
{
class IAddOnContentManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IAddOnContentManager()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 2, CountAddOnContent },
{ 3, ListAddOnContent }
};
}
public static long CountAddOnContent(ServiceCtx context)
public static long CountAddOnContent(ServiceCtx Context)
{
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
Logger.PrintStub(LogClass.ServiceNs, "Stubbed.");
return 0;
}
public static long ListAddOnContent(ServiceCtx context)
public static long ListAddOnContent(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceNs, "Stubbed.");
//TODO: This is supposed to write a u32 array aswell.
//It's unknown what it contains.
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
return 0;
}

View file

@ -1,19 +1,20 @@
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ns
{
class IApplicationManagerInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private bool _isInitialized;
private bool IsInitialized;
public IApplicationManagerInterface()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
};

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Ns
{
class IServiceGetterInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IServiceGetterInterface()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Ns
{
class ISystemUpdateInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ISystemUpdateInterface()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -5,13 +5,13 @@ namespace Ryujinx.HLE.HOS.Services.Ns
{
class IVulnerabilityManagerInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IVulnerabilityManagerInterface()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
//...
};

View file

@ -14,15 +14,15 @@ namespace Ryujinx.HLE.HOS.Services.Nv
{
class INvDrvServices : IpcService
{
private delegate int IoctlProcessor(ServiceCtx context, int cmd);
private delegate int IoctlProcessor(ServiceCtx Context, int Cmd);
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private static Dictionary<string, IoctlProcessor> _ioctlProcessors =
new Dictionary<string, IoctlProcessor>
{
private static Dictionary<string, IoctlProcessor> IoctlProcessors =
new Dictionary<string, IoctlProcessor>()
{
{ "/dev/nvhost-as-gpu", ProcessIoctlNvGpuAS },
{ "/dev/nvhost-ctrl", ProcessIoctlNvHostCtrl },
{ "/dev/nvhost-ctrl-gpu", ProcessIoctlNvGpuGpu },
@ -32,13 +32,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv
{ "/dev/nvmap", ProcessIoctlNvMap }
};
public static GlobalStateTable Fds { get; }
public static GlobalStateTable Fds { get; private set; }
private KEvent _event;
private KEvent Event;
public INvDrvServices(Horizon system)
public INvDrvServices(Horizon System)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Open },
{ 1, Ioctl },
@ -50,7 +50,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
{ 13, FinishInitialize }
};
_event = new KEvent(system);
Event = new KEvent(System);
}
static INvDrvServices()
@ -58,166 +58,166 @@ namespace Ryujinx.HLE.HOS.Services.Nv
Fds = new GlobalStateTable();
}
public long Open(ServiceCtx context)
public long Open(ServiceCtx Context)
{
long namePtr = context.Request.SendBuff[0].Position;
long NamePtr = Context.Request.SendBuff[0].Position;
string name = MemoryHelper.ReadAsciiString(context.Memory, namePtr);
string Name = MemoryHelper.ReadAsciiString(Context.Memory, NamePtr);
int fd = Fds.Add(context.Process, new NvFd(name));
int Fd = Fds.Add(Context.Process, new NvFd(Name));
context.ResponseData.Write(fd);
context.ResponseData.Write(0);
Context.ResponseData.Write(Fd);
Context.ResponseData.Write(0);
return 0;
}
public long Ioctl(ServiceCtx context)
public long Ioctl(ServiceCtx Context)
{
int fd = context.RequestData.ReadInt32();
int cmd = context.RequestData.ReadInt32();
int Fd = Context.RequestData.ReadInt32();
int Cmd = Context.RequestData.ReadInt32();
NvFd fdData = Fds.GetData<NvFd>(context.Process, fd);
NvFd FdData = Fds.GetData<NvFd>(Context.Process, Fd);
int result;
int Result;
if (_ioctlProcessors.TryGetValue(fdData.Name, out IoctlProcessor process))
if (IoctlProcessors.TryGetValue(FdData.Name, out IoctlProcessor Process))
{
result = process(context, cmd);
Result = Process(Context, Cmd);
}
else
{
throw new NotImplementedException($"{fdData.Name} {cmd:x4}");
throw new NotImplementedException($"{FdData.Name} {Cmd:x4}");
}
//TODO: Verify if the error codes needs to be translated.
context.ResponseData.Write(result);
Context.ResponseData.Write(Result);
return 0;
}
public long Close(ServiceCtx context)
public long Close(ServiceCtx Context)
{
int fd = context.RequestData.ReadInt32();
int Fd = Context.RequestData.ReadInt32();
Fds.Delete(context.Process, fd);
Fds.Delete(Context.Process, Fd);
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
return 0;
}
public long Initialize(ServiceCtx context)
public long Initialize(ServiceCtx Context)
{
long transferMemSize = context.RequestData.ReadInt64();
int transferMemHandle = context.Request.HandleDesc.ToCopy[0];
long TransferMemSize = Context.RequestData.ReadInt64();
int TransferMemHandle = Context.Request.HandleDesc.ToCopy[0];
NvMapIoctl.InitializeNvMap(context);
NvMapIoctl.InitializeNvMap(Context);
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
return 0;
}
public long QueryEvent(ServiceCtx context)
public long QueryEvent(ServiceCtx Context)
{
int fd = context.RequestData.ReadInt32();
int eventId = context.RequestData.ReadInt32();
int Fd = Context.RequestData.ReadInt32();
int EventId = Context.RequestData.ReadInt32();
//TODO: Use Fd/EventId, different channels have different events.
if (context.Process.HandleTable.GenerateHandle(_event.ReadableEvent, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(Event.ReadableEvent, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
return 0;
}
public long SetClientPid(ServiceCtx context)
public long SetClientPid(ServiceCtx Context)
{
long pid = context.RequestData.ReadInt64();
long Pid = Context.RequestData.ReadInt64();
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
return 0;
}
public long FinishInitialize(ServiceCtx context)
public long FinishInitialize(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return 0;
}
private static int ProcessIoctlNvGpuAS(ServiceCtx context, int cmd)
private static int ProcessIoctlNvGpuAS(ServiceCtx Context, int Cmd)
{
return ProcessIoctl(context, cmd, NvGpuASIoctl.ProcessIoctl);
return ProcessIoctl(Context, Cmd, NvGpuASIoctl.ProcessIoctl);
}
private static int ProcessIoctlNvHostCtrl(ServiceCtx context, int cmd)
private static int ProcessIoctlNvHostCtrl(ServiceCtx Context, int Cmd)
{
return ProcessIoctl(context, cmd, NvHostCtrlIoctl.ProcessIoctl);
return ProcessIoctl(Context, Cmd, NvHostCtrlIoctl.ProcessIoctl);
}
private static int ProcessIoctlNvGpuGpu(ServiceCtx context, int cmd)
private static int ProcessIoctlNvGpuGpu(ServiceCtx Context, int Cmd)
{
return ProcessIoctl(context, cmd, NvGpuGpuIoctl.ProcessIoctl);
return ProcessIoctl(Context, Cmd, NvGpuGpuIoctl.ProcessIoctl);
}
private static int ProcessIoctlNvHostChannel(ServiceCtx context, int cmd)
private static int ProcessIoctlNvHostChannel(ServiceCtx Context, int Cmd)
{
return ProcessIoctl(context, cmd, NvHostChannelIoctl.ProcessIoctl);
return ProcessIoctl(Context, Cmd, NvHostChannelIoctl.ProcessIoctl);
}
private static int ProcessIoctlNvMap(ServiceCtx context, int cmd)
private static int ProcessIoctlNvMap(ServiceCtx Context, int Cmd)
{
return ProcessIoctl(context, cmd, NvMapIoctl.ProcessIoctl);
return ProcessIoctl(Context, Cmd, NvMapIoctl.ProcessIoctl);
}
private static int ProcessIoctl(ServiceCtx context, int cmd, IoctlProcessor processor)
private static int ProcessIoctl(ServiceCtx Context, int Cmd, IoctlProcessor Processor)
{
if (CmdIn(cmd) && context.Request.GetBufferType0x21().Position == 0)
if (CmdIn(Cmd) && Context.Request.GetBufferType0x21().Position == 0)
{
Logger.PrintError(LogClass.ServiceNv, "Input buffer is null!");
return NvResult.InvalidInput;
}
if (CmdOut(cmd) && context.Request.GetBufferType0x22().Position == 0)
if (CmdOut(Cmd) && Context.Request.GetBufferType0x22().Position == 0)
{
Logger.PrintError(LogClass.ServiceNv, "Output buffer is null!");
return NvResult.InvalidInput;
}
return processor(context, cmd);
return Processor(Context, Cmd);
}
private static bool CmdIn(int cmd)
private static bool CmdIn(int Cmd)
{
return ((cmd >> 30) & 1) != 0;
return ((Cmd >> 30) & 1) != 0;
}
private static bool CmdOut(int cmd)
private static bool CmdOut(int Cmd)
{
return ((cmd >> 31) & 1) != 0;
return ((Cmd >> 31) & 1) != 0;
}
public static void UnloadProcess(KProcess process)
public static void UnloadProcess(KProcess Process)
{
Fds.DeleteProcess(process);
Fds.DeleteProcess(Process);
NvGpuASIoctl.UnloadProcess(process);
NvGpuASIoctl.UnloadProcess(Process);
NvHostChannelIoctl.UnloadProcess(process);
NvHostChannelIoctl.UnloadProcess(Process);
NvHostCtrlIoctl.UnloadProcess(process);
NvHostCtrlIoctl.UnloadProcess(Process);
NvMapIoctl.UnloadProcess(process);
NvMapIoctl.UnloadProcess(Process);
}
}
}

View file

@ -2,11 +2,11 @@ namespace Ryujinx.HLE.HOS.Services.Nv
{
class NvFd
{
public string Name { get; }
public string Name { get; private set; }
public NvFd(string name)
public NvFd(string Name)
{
Name = name;
this.Name = Name;
}
}
}

View file

@ -5,73 +5,73 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvGpuAS
{
class NvGpuASCtx
{
public NvGpuVmm Vmm { get; }
public NvGpuVmm Vmm { get; private set; }
private class Range
{
public ulong Start { get; }
public ulong End { get; }
public ulong Start { get; private set; }
public ulong End { get; private set; }
public Range(long position, long size)
public Range(long Position, long Size)
{
Start = (ulong)position;
End = (ulong)size + Start;
Start = (ulong)Position;
End = (ulong)Size + Start;
}
}
private class MappedMemory : Range
{
public long PhysicalAddress { get; }
public bool VaAllocated { get; }
public long PhysicalAddress { get; private set; }
public bool VaAllocated { get; private set; }
public MappedMemory(
long position,
long size,
long physicalAddress,
bool vaAllocated) : base(position, size)
long Position,
long Size,
long PhysicalAddress,
bool VaAllocated) : base(Position, Size)
{
PhysicalAddress = physicalAddress;
VaAllocated = vaAllocated;
this.PhysicalAddress = PhysicalAddress;
this.VaAllocated = VaAllocated;
}
}
private SortedList<long, Range> _maps;
private SortedList<long, Range> _reservations;
private SortedList<long, Range> Maps;
private SortedList<long, Range> Reservations;
public NvGpuASCtx(ServiceCtx context)
public NvGpuASCtx(ServiceCtx Context)
{
Vmm = new NvGpuVmm(context.Memory);
Vmm = new NvGpuVmm(Context.Memory);
_maps = new SortedList<long, Range>();
_reservations = new SortedList<long, Range>();
Maps = new SortedList<long, Range>();
Reservations = new SortedList<long, Range>();
}
public bool ValidateFixedBuffer(long position, long size)
public bool ValidateFixedBuffer(long Position, long Size)
{
long mapEnd = position + size;
long MapEnd = Position + Size;
//Check if size is valid (0 is also not allowed).
if ((ulong)mapEnd <= (ulong)position)
if ((ulong)MapEnd <= (ulong)Position)
{
return false;
}
//Check if address is page aligned.
if ((position & NvGpuVmm.PageMask) != 0)
if ((Position & NvGpuVmm.PageMask) != 0)
{
return false;
}
//Check if region is reserved.
if (BinarySearch(_reservations, position) == null)
if (BinarySearch(Reservations, Position) == null)
{
return false;
}
//Check for overlap with already mapped buffers.
Range map = BinarySearchLt(_maps, mapEnd);
Range Map = BinarySearchLt(Maps, MapEnd);
if (map != null && map.End > (ulong)position)
if (Map != null && Map.End > (ulong)Position)
{
return false;
}
@ -80,25 +80,25 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvGpuAS
}
public void AddMap(
long position,
long size,
long physicalAddress,
bool vaAllocated)
long Position,
long Size,
long PhysicalAddress,
bool VaAllocated)
{
_maps.Add(position, new MappedMemory(position, size, physicalAddress, vaAllocated));
Maps.Add(Position, new MappedMemory(Position, Size, PhysicalAddress, VaAllocated));
}
public bool RemoveMap(long position, out long size)
public bool RemoveMap(long Position, out long Size)
{
size = 0;
Size = 0;
if (_maps.Remove(position, out Range value))
if (Maps.Remove(Position, out Range Value))
{
MappedMemory map = (MappedMemory)value;
MappedMemory Map = (MappedMemory)Value;
if (map.VaAllocated)
if (Map.VaAllocated)
{
size = (long)(map.End - map.Start);
Size = (long)(Map.End - Map.Start);
}
return true;
@ -107,94 +107,94 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvGpuAS
return false;
}
public bool TryGetMapPhysicalAddress(long position, out long physicalAddress)
public bool TryGetMapPhysicalAddress(long Position, out long PhysicalAddress)
{
Range map = BinarySearch(_maps, position);
Range Map = BinarySearch(Maps, Position);
if (map != null)
if (Map != null)
{
physicalAddress = ((MappedMemory)map).PhysicalAddress;
PhysicalAddress = ((MappedMemory)Map).PhysicalAddress;
return true;
}
physicalAddress = 0;
PhysicalAddress = 0;
return false;
}
public void AddReservation(long position, long size)
public void AddReservation(long Position, long Size)
{
_reservations.Add(position, new Range(position, size));
Reservations.Add(Position, new Range(Position, Size));
}
public bool RemoveReservation(long position)
public bool RemoveReservation(long Position)
{
return _reservations.Remove(position);
return Reservations.Remove(Position);
}
private Range BinarySearch(SortedList<long, Range> lst, long position)
private Range BinarySearch(SortedList<long, Range> Lst, long Position)
{
int left = 0;
int right = lst.Count - 1;
int Left = 0;
int Right = Lst.Count - 1;
while (left <= right)
while (Left <= Right)
{
int size = right - left;
int Size = Right - Left;
int middle = left + (size >> 1);
int Middle = Left + (Size >> 1);
Range rg = lst.Values[middle];
Range Rg = Lst.Values[Middle];
if ((ulong)position >= rg.Start && (ulong)position < rg.End)
if ((ulong)Position >= Rg.Start && (ulong)Position < Rg.End)
{
return rg;
return Rg;
}
if ((ulong)position < rg.Start)
if ((ulong)Position < Rg.Start)
{
right = middle - 1;
Right = Middle - 1;
}
else
{
left = middle + 1;
Left = Middle + 1;
}
}
return null;
}
private Range BinarySearchLt(SortedList<long, Range> lst, long position)
private Range BinarySearchLt(SortedList<long, Range> Lst, long Position)
{
Range ltRg = null;
Range LtRg = null;
int left = 0;
int right = lst.Count - 1;
int Left = 0;
int Right = Lst.Count - 1;
while (left <= right)
while (Left <= Right)
{
int size = right - left;
int Size = Right - Left;
int middle = left + (size >> 1);
int Middle = Left + (Size >> 1);
Range rg = lst.Values[middle];
Range Rg = Lst.Values[Middle];
if ((ulong)position < rg.Start)
if ((ulong)Position < Rg.Start)
{
right = middle - 1;
Right = Middle - 1;
}
else
{
left = middle + 1;
Left = Middle + 1;
if ((ulong)position > rg.Start)
if ((ulong)Position > Rg.Start)
{
ltRg = rg;
LtRg = Rg;
}
}
}
return ltRg;
return LtRg;
}
}
}

View file

@ -14,182 +14,182 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvGpuAS
private const int FlagRemapSubRange = 0x100;
private static ConcurrentDictionary<KProcess, NvGpuASCtx> _asCtxs;
private static ConcurrentDictionary<KProcess, NvGpuASCtx> ASCtxs;
static NvGpuASIoctl()
{
_asCtxs = new ConcurrentDictionary<KProcess, NvGpuASCtx>();
ASCtxs = new ConcurrentDictionary<KProcess, NvGpuASCtx>();
}
public static int ProcessIoctl(ServiceCtx context, int cmd)
public static int ProcessIoctl(ServiceCtx Context, int Cmd)
{
switch (cmd & 0xffff)
switch (Cmd & 0xffff)
{
case 0x4101: return BindChannel (context);
case 0x4102: return AllocSpace (context);
case 0x4103: return FreeSpace (context);
case 0x4105: return UnmapBuffer (context);
case 0x4106: return MapBufferEx (context);
case 0x4108: return GetVaRegions(context);
case 0x4109: return InitializeEx(context);
case 0x4114: return Remap (context, cmd);
case 0x4101: return BindChannel (Context);
case 0x4102: return AllocSpace (Context);
case 0x4103: return FreeSpace (Context);
case 0x4105: return UnmapBuffer (Context);
case 0x4106: return MapBufferEx (Context);
case 0x4108: return GetVaRegions(Context);
case 0x4109: return InitializeEx(Context);
case 0x4114: return Remap (Context, Cmd);
}
throw new NotImplementedException(cmd.ToString("x8"));
throw new NotImplementedException(Cmd.ToString("x8"));
}
private static int BindChannel(ServiceCtx context)
private static int BindChannel(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int AllocSpace(ServiceCtx context)
private static int AllocSpace(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvGpuASAllocSpace args = MemoryHelper.Read<NvGpuASAllocSpace>(context.Memory, inputPosition);
NvGpuASAllocSpace Args = MemoryHelper.Read<NvGpuASAllocSpace>(Context.Memory, InputPosition);
NvGpuASCtx asCtx = GetASCtx(context);
NvGpuASCtx ASCtx = GetASCtx(Context);
ulong size = (ulong)args.Pages *
(ulong)args.PageSize;
ulong Size = (ulong)Args.Pages *
(ulong)Args.PageSize;
int result = NvResult.Success;
int Result = NvResult.Success;
lock (asCtx)
lock (ASCtx)
{
//Note: When the fixed offset flag is not set,
//the Offset field holds the alignment size instead.
if ((args.Flags & FlagFixedOffset) != 0)
if ((Args.Flags & FlagFixedOffset) != 0)
{
args.Offset = asCtx.Vmm.ReserveFixed(args.Offset, (long)size);
Args.Offset = ASCtx.Vmm.ReserveFixed(Args.Offset, (long)Size);
}
else
{
args.Offset = asCtx.Vmm.Reserve((long)size, args.Offset);
Args.Offset = ASCtx.Vmm.Reserve((long)Size, Args.Offset);
}
if (args.Offset < 0)
if (Args.Offset < 0)
{
args.Offset = 0;
Args.Offset = 0;
Logger.PrintWarning(LogClass.ServiceNv, $"Failed to allocate size {size:x16}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Failed to allocate size {Size:x16}!");
result = NvResult.OutOfMemory;
Result = NvResult.OutOfMemory;
}
else
{
asCtx.AddReservation(args.Offset, (long)size);
ASCtx.AddReservation(Args.Offset, (long)Size);
}
}
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return result;
return Result;
}
private static int FreeSpace(ServiceCtx context)
private static int FreeSpace(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvGpuASAllocSpace args = MemoryHelper.Read<NvGpuASAllocSpace>(context.Memory, inputPosition);
NvGpuASAllocSpace Args = MemoryHelper.Read<NvGpuASAllocSpace>(Context.Memory, InputPosition);
NvGpuASCtx asCtx = GetASCtx(context);
NvGpuASCtx ASCtx = GetASCtx(Context);
int result = NvResult.Success;
int Result = NvResult.Success;
lock (asCtx)
lock (ASCtx)
{
ulong size = (ulong)args.Pages *
(ulong)args.PageSize;
ulong Size = (ulong)Args.Pages *
(ulong)Args.PageSize;
if (asCtx.RemoveReservation(args.Offset))
if (ASCtx.RemoveReservation(Args.Offset))
{
asCtx.Vmm.Free(args.Offset, (long)size);
ASCtx.Vmm.Free(Args.Offset, (long)Size);
}
else
{
Logger.PrintWarning(LogClass.ServiceNv,
$"Failed to free offset 0x{args.Offset:x16} size 0x{size:x16}!");
$"Failed to free offset 0x{Args.Offset:x16} size 0x{Size:x16}!");
result = NvResult.InvalidInput;
Result = NvResult.InvalidInput;
}
}
return result;
return Result;
}
private static int UnmapBuffer(ServiceCtx context)
private static int UnmapBuffer(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvGpuASUnmapBuffer args = MemoryHelper.Read<NvGpuASUnmapBuffer>(context.Memory, inputPosition);
NvGpuASUnmapBuffer Args = MemoryHelper.Read<NvGpuASUnmapBuffer>(Context.Memory, InputPosition);
NvGpuASCtx asCtx = GetASCtx(context);
NvGpuASCtx ASCtx = GetASCtx(Context);
lock (asCtx)
lock (ASCtx)
{
if (asCtx.RemoveMap(args.Offset, out long size))
if (ASCtx.RemoveMap(Args.Offset, out long Size))
{
if (size != 0)
if (Size != 0)
{
asCtx.Vmm.Free(args.Offset, size);
ASCtx.Vmm.Free(Args.Offset, Size);
}
}
else
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid buffer offset {args.Offset:x16}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid buffer offset {Args.Offset:x16}!");
}
}
return NvResult.Success;
}
private static int MapBufferEx(ServiceCtx context)
private static int MapBufferEx(ServiceCtx Context)
{
const string mapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16} and size 0x{1:x16}!";
const string MapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16} and size 0x{1:x16}!";
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvGpuASMapBufferEx args = MemoryHelper.Read<NvGpuASMapBufferEx>(context.Memory, inputPosition);
NvGpuASMapBufferEx Args = MemoryHelper.Read<NvGpuASMapBufferEx>(Context.Memory, InputPosition);
NvGpuASCtx asCtx = GetASCtx(context);
NvGpuASCtx ASCtx = GetASCtx(Context);
NvMapHandle map = NvMapIoctl.GetNvMapWithFb(context, args.NvMapHandle);
NvMapHandle Map = NvMapIoctl.GetNvMapWithFb(Context, Args.NvMapHandle);
if (map == null)
if (Map == null)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{args.NvMapHandle:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{Args.NvMapHandle:x8}!");
return NvResult.InvalidInput;
}
long pa;
long PA;
if ((args.Flags & FlagRemapSubRange) != 0)
if ((Args.Flags & FlagRemapSubRange) != 0)
{
lock (asCtx)
lock (ASCtx)
{
if (asCtx.TryGetMapPhysicalAddress(args.Offset, out pa))
if (ASCtx.TryGetMapPhysicalAddress(Args.Offset, out PA))
{
long va = args.Offset + args.BufferOffset;
long VA = Args.Offset + Args.BufferOffset;
pa += args.BufferOffset;
PA += Args.BufferOffset;
if (asCtx.Vmm.Map(pa, va, args.MappingSize) < 0)
if (ASCtx.Vmm.Map(PA, VA, Args.MappingSize) < 0)
{
string msg = string.Format(mapErrorMsg, va, args.MappingSize);
string Msg = string.Format(MapErrorMsg, VA, Args.MappingSize);
Logger.PrintWarning(LogClass.ServiceNv, msg);
Logger.PrintWarning(LogClass.ServiceNv, Msg);
return NvResult.InvalidInput;
}
@ -198,117 +198,117 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvGpuAS
}
else
{
Logger.PrintWarning(LogClass.ServiceNv, $"Address 0x{args.Offset:x16} not mapped!");
Logger.PrintWarning(LogClass.ServiceNv, $"Address 0x{Args.Offset:x16} not mapped!");
return NvResult.InvalidInput;
}
}
}
pa = map.Address + args.BufferOffset;
PA = Map.Address + Args.BufferOffset;
long size = args.MappingSize;
long Size = Args.MappingSize;
if (size == 0)
if (Size == 0)
{
size = (uint)map.Size;
Size = (uint)Map.Size;
}
int result = NvResult.Success;
int Result = NvResult.Success;
lock (asCtx)
lock (ASCtx)
{
//Note: When the fixed offset flag is not set,
//the Offset field holds the alignment size instead.
bool vaAllocated = (args.Flags & FlagFixedOffset) == 0;
bool VaAllocated = (Args.Flags & FlagFixedOffset) == 0;
if (!vaAllocated)
if (!VaAllocated)
{
if (asCtx.ValidateFixedBuffer(args.Offset, size))
if (ASCtx.ValidateFixedBuffer(Args.Offset, Size))
{
args.Offset = asCtx.Vmm.Map(pa, args.Offset, size);
Args.Offset = ASCtx.Vmm.Map(PA, Args.Offset, Size);
}
else
{
string msg = string.Format(mapErrorMsg, args.Offset, size);
string Msg = string.Format(MapErrorMsg, Args.Offset, Size);
Logger.PrintWarning(LogClass.ServiceNv, msg);
Logger.PrintWarning(LogClass.ServiceNv, Msg);
result = NvResult.InvalidInput;
Result = NvResult.InvalidInput;
}
}
else
{
args.Offset = asCtx.Vmm.Map(pa, size);
Args.Offset = ASCtx.Vmm.Map(PA, Size);
}
if (args.Offset < 0)
if (Args.Offset < 0)
{
args.Offset = 0;
Args.Offset = 0;
Logger.PrintWarning(LogClass.ServiceNv, $"Failed to map size 0x{size:x16}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Failed to map size 0x{Size:x16}!");
result = NvResult.InvalidInput;
Result = NvResult.InvalidInput;
}
else
{
asCtx.AddMap(args.Offset, size, pa, vaAllocated);
ASCtx.AddMap(Args.Offset, Size, PA, VaAllocated);
}
}
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return result;
return Result;
}
private static int GetVaRegions(ServiceCtx context)
private static int GetVaRegions(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int InitializeEx(ServiceCtx context)
private static int InitializeEx(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int Remap(ServiceCtx context, int cmd)
private static int Remap(ServiceCtx Context, int Cmd)
{
int count = ((cmd >> 16) & 0xff) / 0x14;
int Count = ((Cmd >> 16) & 0xff) / 0x14;
long inputPosition = context.Request.GetBufferType0x21().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
for (int index = 0; index < count; index++, inputPosition += 0x14)
for (int Index = 0; Index < Count; Index++, InputPosition += 0x14)
{
NvGpuASRemap args = MemoryHelper.Read<NvGpuASRemap>(context.Memory, inputPosition);
NvGpuASRemap Args = MemoryHelper.Read<NvGpuASRemap>(Context.Memory, InputPosition);
NvGpuVmm vmm = GetASCtx(context).Vmm;
NvGpuVmm Vmm = GetASCtx(Context).Vmm;
NvMapHandle map = NvMapIoctl.GetNvMapWithFb(context, args.NvMapHandle);
NvMapHandle Map = NvMapIoctl.GetNvMapWithFb(Context, Args.NvMapHandle);
if (map == null)
if (Map == null)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{args.NvMapHandle:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{Args.NvMapHandle:x8}!");
return NvResult.InvalidInput;
}
long result = vmm.Map(map.Address, (long)(uint)args.Offset << 16,
(long)(uint)args.Pages << 16);
long Result = Vmm.Map(Map.Address, (long)(uint)Args.Offset << 16,
(long)(uint)Args.Pages << 16);
if (result < 0)
if (Result < 0)
{
Logger.PrintWarning(LogClass.ServiceNv,
$"Page 0x{args.Offset:x16} size 0x{args.Pages:x16} not allocated!");
$"Page 0x{Args.Offset:x16} size 0x{Args.Pages:x16} not allocated!");
return NvResult.InvalidInput;
}
@ -317,14 +317,14 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvGpuAS
return NvResult.Success;
}
public static NvGpuASCtx GetASCtx(ServiceCtx context)
public static NvGpuASCtx GetASCtx(ServiceCtx Context)
{
return _asCtxs.GetOrAdd(context.Process, (key) => new NvGpuASCtx(context));
return ASCtxs.GetOrAdd(Context.Process, (Key) => new NvGpuASCtx(Context));
}
public static void UnloadProcess(KProcess process)
public static void UnloadProcess(KProcess Process)
{
_asCtxs.TryRemove(process, out _);
ASCtxs.TryRemove(Process, out _);
}
}
}

View file

@ -7,181 +7,181 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvGpuGpu
{
class NvGpuGpuIoctl
{
private static Stopwatch _pTimer;
private static Stopwatch PTimer;
private static double _ticksToNs;
private static double TicksToNs;
static NvGpuGpuIoctl()
{
_pTimer = new Stopwatch();
PTimer = new Stopwatch();
_pTimer.Start();
PTimer.Start();
_ticksToNs = (1.0 / Stopwatch.Frequency) * 1_000_000_000;
TicksToNs = (1.0 / Stopwatch.Frequency) * 1_000_000_000;
}
public static int ProcessIoctl(ServiceCtx context, int cmd)
public static int ProcessIoctl(ServiceCtx Context, int Cmd)
{
switch (cmd & 0xffff)
switch (Cmd & 0xffff)
{
case 0x4701: return ZcullGetCtxSize (context);
case 0x4702: return ZcullGetInfo (context);
case 0x4703: return ZbcSetTable (context);
case 0x4705: return GetCharacteristics(context);
case 0x4706: return GetTpcMasks (context);
case 0x4714: return GetActiveSlotMask (context);
case 0x471c: return GetGpuTime (context);
case 0x4701: return ZcullGetCtxSize (Context);
case 0x4702: return ZcullGetInfo (Context);
case 0x4703: return ZbcSetTable (Context);
case 0x4705: return GetCharacteristics(Context);
case 0x4706: return GetTpcMasks (Context);
case 0x4714: return GetActiveSlotMask (Context);
case 0x471c: return GetGpuTime (Context);
}
throw new NotImplementedException(cmd.ToString("x8"));
throw new NotImplementedException(Cmd.ToString("x8"));
}
private static int ZcullGetCtxSize(ServiceCtx context)
private static int ZcullGetCtxSize(ServiceCtx Context)
{
long outputPosition = context.Request.GetBufferType0x22().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvGpuGpuZcullGetCtxSize args = new NvGpuGpuZcullGetCtxSize();
NvGpuGpuZcullGetCtxSize Args = new NvGpuGpuZcullGetCtxSize();
args.Size = 1;
Args.Size = 1;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int ZcullGetInfo(ServiceCtx context)
private static int ZcullGetInfo(ServiceCtx Context)
{
long outputPosition = context.Request.GetBufferType0x22().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvGpuGpuZcullGetInfo args = new NvGpuGpuZcullGetInfo();
NvGpuGpuZcullGetInfo Args = new NvGpuGpuZcullGetInfo();
args.WidthAlignPixels = 0x20;
args.HeightAlignPixels = 0x20;
args.PixelSquaresByAliquots = 0x400;
args.AliquotTotal = 0x800;
args.RegionByteMultiplier = 0x20;
args.RegionHeaderSize = 0x20;
args.SubregionHeaderSize = 0xc0;
args.SubregionWidthAlignPixels = 0x20;
args.SubregionHeightAlignPixels = 0x40;
args.SubregionCount = 0x10;
Args.WidthAlignPixels = 0x20;
Args.HeightAlignPixels = 0x20;
Args.PixelSquaresByAliquots = 0x400;
Args.AliquotTotal = 0x800;
Args.RegionByteMultiplier = 0x20;
Args.RegionHeaderSize = 0x20;
Args.SubregionHeaderSize = 0xc0;
Args.SubregionWidthAlignPixels = 0x20;
Args.SubregionHeightAlignPixels = 0x40;
Args.SubregionCount = 0x10;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int ZbcSetTable(ServiceCtx context)
private static int ZbcSetTable(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int GetCharacteristics(ServiceCtx context)
private static int GetCharacteristics(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvGpuGpuGetCharacteristics args = MemoryHelper.Read<NvGpuGpuGetCharacteristics>(context.Memory, inputPosition);
NvGpuGpuGetCharacteristics Args = MemoryHelper.Read<NvGpuGpuGetCharacteristics>(Context.Memory, InputPosition);
args.BufferSize = 0xa0;
Args.BufferSize = 0xa0;
args.Arch = 0x120;
args.Impl = 0xb;
args.Rev = 0xa1;
args.NumGpc = 0x1;
args.L2CacheSize = 0x40000;
args.OnBoardVideoMemorySize = 0x0;
args.NumTpcPerGpc = 0x2;
args.BusType = 0x20;
args.BigPageSize = 0x20000;
args.CompressionPageSize = 0x20000;
args.PdeCoverageBitCount = 0x1b;
args.AvailableBigPageSizes = 0x30000;
args.GpcMask = 0x1;
args.SmArchSmVersion = 0x503;
args.SmArchSpaVersion = 0x503;
args.SmArchWarpCount = 0x80;
args.GpuVaBitCount = 0x28;
args.Reserved = 0x0;
args.Flags = 0x55;
args.TwodClass = 0x902d;
args.ThreedClass = 0xb197;
args.ComputeClass = 0xb1c0;
args.GpfifoClass = 0xb06f;
args.InlineToMemoryClass = 0xa140;
args.DmaCopyClass = 0xb0b5;
args.MaxFbpsCount = 0x1;
args.FbpEnMask = 0x0;
args.MaxLtcPerFbp = 0x2;
args.MaxLtsPerLtc = 0x1;
args.MaxTexPerTpc = 0x0;
args.MaxGpcCount = 0x1;
args.RopL2EnMask0 = 0x21d70;
args.RopL2EnMask1 = 0x0;
args.ChipName = 0x6230326d67;
args.GrCompbitStoreBaseHw = 0x0;
Args.Arch = 0x120;
Args.Impl = 0xb;
Args.Rev = 0xa1;
Args.NumGpc = 0x1;
Args.L2CacheSize = 0x40000;
Args.OnBoardVideoMemorySize = 0x0;
Args.NumTpcPerGpc = 0x2;
Args.BusType = 0x20;
Args.BigPageSize = 0x20000;
Args.CompressionPageSize = 0x20000;
Args.PdeCoverageBitCount = 0x1b;
Args.AvailableBigPageSizes = 0x30000;
Args.GpcMask = 0x1;
Args.SmArchSmVersion = 0x503;
Args.SmArchSpaVersion = 0x503;
Args.SmArchWarpCount = 0x80;
Args.GpuVaBitCount = 0x28;
Args.Reserved = 0x0;
Args.Flags = 0x55;
Args.TwodClass = 0x902d;
Args.ThreedClass = 0xb197;
Args.ComputeClass = 0xb1c0;
Args.GpfifoClass = 0xb06f;
Args.InlineToMemoryClass = 0xa140;
Args.DmaCopyClass = 0xb0b5;
Args.MaxFbpsCount = 0x1;
Args.FbpEnMask = 0x0;
Args.MaxLtcPerFbp = 0x2;
Args.MaxLtsPerLtc = 0x1;
Args.MaxTexPerTpc = 0x0;
Args.MaxGpcCount = 0x1;
Args.RopL2EnMask0 = 0x21d70;
Args.RopL2EnMask1 = 0x0;
Args.ChipName = 0x6230326d67;
Args.GrCompbitStoreBaseHw = 0x0;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int GetTpcMasks(ServiceCtx context)
private static int GetTpcMasks(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvGpuGpuGetTpcMasks args = MemoryHelper.Read<NvGpuGpuGetTpcMasks>(context.Memory, inputPosition);
NvGpuGpuGetTpcMasks Args = MemoryHelper.Read<NvGpuGpuGetTpcMasks>(Context.Memory, InputPosition);
if (args.MaskBufferSize != 0)
if (Args.MaskBufferSize != 0)
{
args.TpcMask = 3;
Args.TpcMask = 3;
}
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int GetActiveSlotMask(ServiceCtx context)
private static int GetActiveSlotMask(ServiceCtx Context)
{
long outputPosition = context.Request.GetBufferType0x22().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvGpuGpuGetActiveSlotMask args = new NvGpuGpuGetActiveSlotMask();
NvGpuGpuGetActiveSlotMask Args = new NvGpuGpuGetActiveSlotMask();
args.Slot = 0x07;
args.Mask = 0x01;
Args.Slot = 0x07;
Args.Mask = 0x01;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int GetGpuTime(ServiceCtx context)
private static int GetGpuTime(ServiceCtx Context)
{
long outputPosition = context.Request.GetBufferType0x22().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
context.Memory.WriteInt64(outputPosition, GetPTimerNanoSeconds());
Context.Memory.WriteInt64(OutputPosition, GetPTimerNanoSeconds());
return NvResult.Success;
}
private static long GetPTimerNanoSeconds()
{
double ticks = _pTimer.ElapsedTicks;
double Ticks = PTimer.ElapsedTicks;
return (long)(ticks * _ticksToNs) & 0xff_ffff_ffff_ffff;
return (long)(Ticks * TicksToNs) & 0xff_ffff_ffff_ffff;
}
}
}

View file

@ -11,57 +11,62 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvHostChannel
{
class NvHostChannelIoctl
{
private static ConcurrentDictionary<KProcess, NvChannel> _channels;
private static ConcurrentDictionary<KProcess, NvChannel> Channels;
static NvHostChannelIoctl()
{
_channels = new ConcurrentDictionary<KProcess, NvChannel>();
Channels = new ConcurrentDictionary<KProcess, NvChannel>();
}
public static int ProcessIoctl(ServiceCtx context, int cmd)
public static int ProcessIoctl(ServiceCtx Context, int Cmd)
{
switch (cmd & 0xffff)
switch (Cmd & 0xffff)
{
case 0x0001: return Submit (context);
case 0x0002: return GetSyncpoint (context);
case 0x0003: return GetWaitBase (context);
case 0x0009: return MapBuffer (context);
case 0x000a: return UnmapBuffer (context);
case 0x480b: return ZcullBind (context);
case 0x480c: return SetErrorNotifier (context);
case 0x4803: return SetTimeout (context);
case 0x481a: return AllocGpfifoEx2 (context);
case 0x481b: return KickoffPbWithAttr(context);
case 0x0001: return Submit (Context);
case 0x0002: return GetSyncpoint (Context);
case 0x0003: return GetWaitBase (Context);
case 0x0009: return MapBuffer (Context);
case 0x000a: return UnmapBuffer (Context);
case 0x4714: return SetUserData (Context);
case 0x4801: return SetNvMap (Context);
case 0x4803: return SetTimeout (Context);
case 0x4808: return SubmitGpfifo (Context);
case 0x4809: return AllocObjCtx (Context);
case 0x480b: return ZcullBind (Context);
case 0x480c: return SetErrorNotifier (Context);
case 0x480d: return SetPriority (Context);
case 0x481a: return AllocGpfifoEx2 (Context);
case 0x481b: return KickoffPbWithAttr(Context);
}
throw new NotImplementedException(cmd.ToString("x8"));
throw new NotImplementedException(Cmd.ToString("x8"));
}
private static int Submit(ServiceCtx context)
private static int Submit(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvHostChannelSubmit args = MemoryHelper.Read<NvHostChannelSubmit>(context.Memory, inputPosition);
NvHostChannelSubmit Args = MemoryHelper.Read<NvHostChannelSubmit>(Context.Memory, InputPosition);
NvGpuVmm vmm = NvGpuASIoctl.GetASCtx(context).Vmm;
NvGpuVmm Vmm = NvGpuASIoctl.GetASCtx(Context).Vmm;
for (int index = 0; index < args.CmdBufsCount; index++)
for (int Index = 0; Index < Args.CmdBufsCount; Index++)
{
long cmdBufOffset = inputPosition + 0x10 + index * 0xc;
long CmdBufOffset = InputPosition + 0x10 + Index * 0xc;
NvHostChannelCmdBuf cmdBuf = MemoryHelper.Read<NvHostChannelCmdBuf>(context.Memory, cmdBufOffset);
NvHostChannelCmdBuf CmdBuf = MemoryHelper.Read<NvHostChannelCmdBuf>(Context.Memory, CmdBufOffset);
NvMapHandle map = NvMapIoctl.GetNvMap(context, cmdBuf.MemoryId);
NvMapHandle Map = NvMapIoctl.GetNvMap(Context, CmdBuf.MemoryId);
int[] cmdBufData = new int[cmdBuf.WordsCount];
int[] CmdBufData = new int[CmdBuf.WordsCount];
for (int offset = 0; offset < cmdBufData.Length; offset++)
for (int Offset = 0; Offset < CmdBufData.Length; Offset++)
{
cmdBufData[offset] = context.Memory.ReadInt32(map.Address + cmdBuf.Offset + offset * 4);
CmdBufData[Offset] = Context.Memory.ReadInt32(Map.Address + CmdBuf.Offset + Offset * 4);
}
context.Device.Gpu.PushCommandBuffer(vmm, cmdBufData);
Context.Device.Gpu.PushCommandBuffer(Vmm, CmdBufData);
}
//TODO: Relocation, waitchecks, etc.
@ -69,99 +74,99 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvHostChannel
return NvResult.Success;
}
private static int GetSyncpoint(ServiceCtx context)
private static int GetSyncpoint(ServiceCtx Context)
{
//TODO
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvHostChannelGetParamArg args = MemoryHelper.Read<NvHostChannelGetParamArg>(context.Memory, inputPosition);
NvHostChannelGetParamArg Args = MemoryHelper.Read<NvHostChannelGetParamArg>(Context.Memory, InputPosition);
args.Value = 0;
Args.Value = 0;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int GetWaitBase(ServiceCtx context)
private static int GetWaitBase(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvHostChannelGetParamArg args = MemoryHelper.Read<NvHostChannelGetParamArg>(context.Memory, inputPosition);
NvHostChannelGetParamArg Args = MemoryHelper.Read<NvHostChannelGetParamArg>(Context.Memory, InputPosition);
args.Value = 0;
Args.Value = 0;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int MapBuffer(ServiceCtx context)
private static int MapBuffer(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvHostChannelMapBuffer args = MemoryHelper.Read<NvHostChannelMapBuffer>(context.Memory, inputPosition);
NvHostChannelMapBuffer Args = MemoryHelper.Read<NvHostChannelMapBuffer>(Context.Memory, InputPosition);
NvGpuVmm vmm = NvGpuASIoctl.GetASCtx(context).Vmm;
NvGpuVmm Vmm = NvGpuASIoctl.GetASCtx(Context).Vmm;
for (int index = 0; index < args.NumEntries; index++)
for (int Index = 0; Index < Args.NumEntries; Index++)
{
int handle = context.Memory.ReadInt32(inputPosition + 0xc + index * 8);
int Handle = Context.Memory.ReadInt32(InputPosition + 0xc + Index * 8);
NvMapHandle map = NvMapIoctl.GetNvMap(context, handle);
NvMapHandle Map = NvMapIoctl.GetNvMap(Context, Handle);
if (map == null)
if (Map == null)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{handle:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Handle:x8}!");
return NvResult.InvalidInput;
}
lock (map)
lock (Map)
{
if (map.DmaMapAddress == 0)
if (Map.DmaMapAddress == 0)
{
map.DmaMapAddress = vmm.MapLow(map.Address, map.Size);
Map.DmaMapAddress = Vmm.MapLow(Map.Address, Map.Size);
}
context.Memory.WriteInt32(outputPosition + 0xc + 4 + index * 8, (int)map.DmaMapAddress);
Context.Memory.WriteInt32(OutputPosition + 0xc + 4 + Index * 8, (int)Map.DmaMapAddress);
}
}
return NvResult.Success;
}
private static int UnmapBuffer(ServiceCtx context)
private static int UnmapBuffer(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
NvHostChannelMapBuffer args = MemoryHelper.Read<NvHostChannelMapBuffer>(context.Memory, inputPosition);
NvHostChannelMapBuffer Args = MemoryHelper.Read<NvHostChannelMapBuffer>(Context.Memory, InputPosition);
NvGpuVmm vmm = NvGpuASIoctl.GetASCtx(context).Vmm;
NvGpuVmm Vmm = NvGpuASIoctl.GetASCtx(Context).Vmm;
for (int index = 0; index < args.NumEntries; index++)
for (int Index = 0; Index < Args.NumEntries; Index++)
{
int handle = context.Memory.ReadInt32(inputPosition + 0xc + index * 8);
int Handle = Context.Memory.ReadInt32(InputPosition + 0xc + Index * 8);
NvMapHandle map = NvMapIoctl.GetNvMap(context, handle);
NvMapHandle Map = NvMapIoctl.GetNvMap(Context, Handle);
if (map == null)
if (Map == null)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{handle:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Handle:x8}!");
return NvResult.InvalidInput;
}
lock (map)
lock (Map)
{
if (map.DmaMapAddress != 0)
if (Map.DmaMapAddress != 0)
{
vmm.Free(map.DmaMapAddress, map.Size);
Vmm.Free(Map.DmaMapAddress, Map.Size);
map.DmaMapAddress = 0;
Map.DmaMapAddress = 0;
}
}
}
@ -169,146 +174,146 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvHostChannel
return NvResult.Success;
}
private static int SetUserData(ServiceCtx context)
private static int SetUserData(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int SetNvMap(ServiceCtx context)
private static int SetNvMap(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int SetTimeout(ServiceCtx context)
private static int SetTimeout(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
GetChannel(context).Timeout = context.Memory.ReadInt32(inputPosition);
GetChannel(Context).Timeout = Context.Memory.ReadInt32(InputPosition);
return NvResult.Success;
}
private static int SubmitGpfifo(ServiceCtx context)
private static int SubmitGpfifo(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvHostChannelSubmitGpfifo args = MemoryHelper.Read<NvHostChannelSubmitGpfifo>(context.Memory, inputPosition);
NvHostChannelSubmitGpfifo Args = MemoryHelper.Read<NvHostChannelSubmitGpfifo>(Context.Memory, InputPosition);
NvGpuVmm vmm = NvGpuASIoctl.GetASCtx(context).Vmm;
NvGpuVmm Vmm = NvGpuASIoctl.GetASCtx(Context).Vmm;;
for (int index = 0; index < args.NumEntries; index++)
for (int Index = 0; Index < Args.NumEntries; Index++)
{
long gpfifo = context.Memory.ReadInt64(inputPosition + 0x18 + index * 8);
long Gpfifo = Context.Memory.ReadInt64(InputPosition + 0x18 + Index * 8);
PushGpfifo(context, vmm, gpfifo);
PushGpfifo(Context, Vmm, Gpfifo);
}
args.SyncptId = 0;
args.SyncptValue = 0;
Args.SyncptId = 0;
Args.SyncptValue = 0;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int AllocObjCtx(ServiceCtx context)
private static int AllocObjCtx(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int ZcullBind(ServiceCtx context)
private static int ZcullBind(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int SetErrorNotifier(ServiceCtx context)
private static int SetErrorNotifier(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int SetPriority(ServiceCtx context)
private static int SetPriority(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int AllocGpfifoEx2(ServiceCtx context)
private static int AllocGpfifoEx2(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int KickoffPbWithAttr(ServiceCtx context)
private static int KickoffPbWithAttr(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvHostChannelSubmitGpfifo args = MemoryHelper.Read<NvHostChannelSubmitGpfifo>(context.Memory, inputPosition);
NvHostChannelSubmitGpfifo Args = MemoryHelper.Read<NvHostChannelSubmitGpfifo>(Context.Memory, InputPosition);
NvGpuVmm vmm = NvGpuASIoctl.GetASCtx(context).Vmm;
NvGpuVmm Vmm = NvGpuASIoctl.GetASCtx(Context).Vmm;;
for (int index = 0; index < args.NumEntries; index++)
for (int Index = 0; Index < Args.NumEntries; Index++)
{
long gpfifo = context.Memory.ReadInt64(args.Address + index * 8);
long Gpfifo = Context.Memory.ReadInt64(Args.Address + Index * 8);
PushGpfifo(context, vmm, gpfifo);
PushGpfifo(Context, Vmm, Gpfifo);
}
args.SyncptId = 0;
args.SyncptValue = 0;
Args.SyncptId = 0;
Args.SyncptValue = 0;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static void PushGpfifo(ServiceCtx context, NvGpuVmm vmm, long gpfifo)
private static void PushGpfifo(ServiceCtx Context, NvGpuVmm Vmm, long Gpfifo)
{
context.Device.Gpu.Pusher.Push(vmm, gpfifo);
Context.Device.Gpu.Pusher.Push(Vmm, Gpfifo);
}
public static NvChannel GetChannel(ServiceCtx context)
public static NvChannel GetChannel(ServiceCtx Context)
{
return _channels.GetOrAdd(context.Process, (key) => new NvChannel());
return Channels.GetOrAdd(Context.Process, (Key) => new NvChannel());
}
public static void UnloadProcess(KProcess process)
public static void UnloadProcess(KProcess Process)
{
_channels.TryRemove(process, out _);
Channels.TryRemove(Process, out _);
}
}
}

View file

@ -10,116 +10,116 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvHostCtrl
{
class NvHostCtrlIoctl
{
private static ConcurrentDictionary<KProcess, NvHostCtrlUserCtx> _userCtxs;
private static ConcurrentDictionary<KProcess, NvHostCtrlUserCtx> UserCtxs;
private static bool _isProductionMode = true;
private static bool IsProductionMode = true;
static NvHostCtrlIoctl()
{
_userCtxs = new ConcurrentDictionary<KProcess, NvHostCtrlUserCtx>();
UserCtxs = new ConcurrentDictionary<KProcess, NvHostCtrlUserCtx>();
if (Set.NxSettings.Settings.TryGetValue("nv!rmos_set_production_mode", out object productionModeSetting))
if (Set.NxSettings.Settings.TryGetValue("nv!rmos_set_production_mode", out object ProductionModeSetting))
{
_isProductionMode = ((string)productionModeSetting) != "0"; // Default value is ""
IsProductionMode = ((string)ProductionModeSetting) != "0"; // Default value is ""
}
}
public static int ProcessIoctl(ServiceCtx context, int cmd)
public static int ProcessIoctl(ServiceCtx Context, int Cmd)
{
switch (cmd & 0xffff)
switch (Cmd & 0xffff)
{
case 0x0014: return SyncptRead (context);
case 0x0015: return SyncptIncr (context);
case 0x0016: return SyncptWait (context);
case 0x0019: return SyncptWaitEx (context);
case 0x001a: return SyncptReadMax (context);
case 0x001b: return GetConfig (context);
case 0x001d: return EventWait (context);
case 0x001e: return EventWaitAsync(context);
case 0x001f: return EventRegister (context);
case 0x0014: return SyncptRead (Context);
case 0x0015: return SyncptIncr (Context);
case 0x0016: return SyncptWait (Context);
case 0x0019: return SyncptWaitEx (Context);
case 0x001a: return SyncptReadMax (Context);
case 0x001b: return GetConfig (Context);
case 0x001d: return EventWait (Context);
case 0x001e: return EventWaitAsync(Context);
case 0x001f: return EventRegister (Context);
}
throw new NotImplementedException(cmd.ToString("x8"));
throw new NotImplementedException(Cmd.ToString("x8"));
}
private static int SyncptRead(ServiceCtx context)
private static int SyncptRead(ServiceCtx Context)
{
return SyncptReadMinOrMax(context, max: false);
return SyncptReadMinOrMax(Context, Max: false);
}
private static int SyncptIncr(ServiceCtx context)
private static int SyncptIncr(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
int id = context.Memory.ReadInt32(inputPosition);
int Id = Context.Memory.ReadInt32(InputPosition);
if ((uint)id >= NvHostSyncpt.SyncptsCount)
if ((uint)Id >= NvHostSyncpt.SyncptsCount)
{
return NvResult.InvalidInput;
}
GetUserCtx(context).Syncpt.Increment(id);
GetUserCtx(Context).Syncpt.Increment(Id);
return NvResult.Success;
}
private static int SyncptWait(ServiceCtx context)
private static int SyncptWait(ServiceCtx Context)
{
return SyncptWait(context, extended: false);
return SyncptWait(Context, Extended: false);
}
private static int SyncptWaitEx(ServiceCtx context)
private static int SyncptWaitEx(ServiceCtx Context)
{
return SyncptWait(context, extended: true);
return SyncptWait(Context, Extended: true);
}
private static int SyncptReadMax(ServiceCtx context)
private static int SyncptReadMax(ServiceCtx Context)
{
return SyncptReadMinOrMax(context, max: true);
return SyncptReadMinOrMax(Context, Max: true);
}
private static int GetConfig(ServiceCtx context)
private static int GetConfig(ServiceCtx Context)
{
if (!_isProductionMode)
if (!IsProductionMode)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
string domain = MemoryHelper.ReadAsciiString(context.Memory, inputPosition + 0, 0x41);
string name = MemoryHelper.ReadAsciiString(context.Memory, inputPosition + 0x41, 0x41);
string Domain = MemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0, 0x41);
string Name = MemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0x41, 0x41);
if (Set.NxSettings.Settings.TryGetValue($"{domain}!{name}", out object nvSetting))
if (Set.NxSettings.Settings.TryGetValue($"{Domain}!{Name}", out object NvSetting))
{
byte[] settingBuffer = new byte[0x101];
byte[] SettingBuffer = new byte[0x101];
if (nvSetting is string stringValue)
if (NvSetting is string StringValue)
{
if (stringValue.Length > 0x100)
if (StringValue.Length > 0x100)
{
Logger.PrintError(LogClass.ServiceNv, $"{domain}!{name} String value size is too big!");
Logger.PrintError(LogClass.ServiceNv, $"{Domain}!{Name} String value size is too big!");
}
else
{
settingBuffer = Encoding.ASCII.GetBytes(stringValue + "\0");
SettingBuffer = Encoding.ASCII.GetBytes(StringValue + "\0");
}
}
if (nvSetting is int intValue)
if (NvSetting is int IntValue)
{
settingBuffer = BitConverter.GetBytes(intValue);
SettingBuffer = BitConverter.GetBytes(IntValue);
}
else if (nvSetting is bool boolValue)
else if (NvSetting is bool BoolValue)
{
settingBuffer[0] = boolValue ? (byte)1 : (byte)0;
SettingBuffer[0] = BoolValue ? (byte)1 : (byte)0;
}
else
{
throw new NotImplementedException(nvSetting.GetType().Name);
throw new NotImplementedException(NvSetting.GetType().Name);
}
context.Memory.WriteBytes(outputPosition + 0x82, settingBuffer);
Context.Memory.WriteBytes(OutputPosition + 0x82, SettingBuffer);
Logger.PrintDebug(LogClass.ServiceNv, $"Got setting {domain}!{name}");
Logger.PrintDebug(LogClass.ServiceNv, $"Got setting {Domain}!{Name}");
}
return NvResult.Success;
@ -128,156 +128,156 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvHostCtrl
return NvResult.NotAvailableInProduction;
}
private static int EventWait(ServiceCtx context)
private static int EventWait(ServiceCtx Context)
{
return EventWait(context, async: false);
return EventWait(Context, Async: false);
}
private static int EventWaitAsync(ServiceCtx context)
private static int EventWaitAsync(ServiceCtx Context)
{
return EventWait(context, async: true);
return EventWait(Context, Async: true);
}
private static int EventRegister(ServiceCtx context)
private static int EventRegister(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
int eventId = context.Memory.ReadInt32(inputPosition);
int EventId = Context.Memory.ReadInt32(InputPosition);
Logger.PrintStub(LogClass.ServiceNv, "Stubbed.");
return NvResult.Success;
}
private static int SyncptReadMinOrMax(ServiceCtx context, bool max)
private static int SyncptReadMinOrMax(ServiceCtx Context, bool Max)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvHostCtrlSyncptRead args = MemoryHelper.Read<NvHostCtrlSyncptRead>(context.Memory, inputPosition);
NvHostCtrlSyncptRead Args = MemoryHelper.Read<NvHostCtrlSyncptRead>(Context.Memory, InputPosition);
if ((uint)args.Id >= NvHostSyncpt.SyncptsCount)
if ((uint)Args.Id >= NvHostSyncpt.SyncptsCount)
{
return NvResult.InvalidInput;
}
if (max)
if (Max)
{
args.Value = GetUserCtx(context).Syncpt.GetMax(args.Id);
Args.Value = GetUserCtx(Context).Syncpt.GetMax(Args.Id);
}
else
{
args.Value = GetUserCtx(context).Syncpt.GetMin(args.Id);
Args.Value = GetUserCtx(Context).Syncpt.GetMin(Args.Id);
}
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int SyncptWait(ServiceCtx context, bool extended)
private static int SyncptWait(ServiceCtx Context, bool Extended)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvHostCtrlSyncptWait args = MemoryHelper.Read<NvHostCtrlSyncptWait>(context.Memory, inputPosition);
NvHostCtrlSyncptWait Args = MemoryHelper.Read<NvHostCtrlSyncptWait>(Context.Memory, InputPosition);
NvHostSyncpt syncpt = GetUserCtx(context).Syncpt;
NvHostSyncpt Syncpt = GetUserCtx(Context).Syncpt;
if ((uint)args.Id >= NvHostSyncpt.SyncptsCount)
if ((uint)Args.Id >= NvHostSyncpt.SyncptsCount)
{
return NvResult.InvalidInput;
}
int result;
int Result;
if (syncpt.MinCompare(args.Id, args.Thresh))
if (Syncpt.MinCompare(Args.Id, Args.Thresh))
{
result = NvResult.Success;
Result = NvResult.Success;
}
else if (args.Timeout == 0)
else if (Args.Timeout == 0)
{
result = NvResult.TryAgain;
Result = NvResult.TryAgain;
}
else
{
Logger.PrintDebug(LogClass.ServiceNv, "Waiting syncpt with timeout of " + args.Timeout + "ms...");
Logger.PrintDebug(LogClass.ServiceNv, "Waiting syncpt with timeout of " + Args.Timeout + "ms...");
using (ManualResetEvent waitEvent = new ManualResetEvent(false))
using (ManualResetEvent WaitEvent = new ManualResetEvent(false))
{
syncpt.AddWaiter(args.Thresh, waitEvent);
Syncpt.AddWaiter(Args.Thresh, WaitEvent);
//Note: Negative (> INT_MAX) timeouts aren't valid on .NET,
//in this case we just use the maximum timeout possible.
int timeout = args.Timeout;
int Timeout = Args.Timeout;
if (timeout < -1)
if (Timeout < -1)
{
timeout = int.MaxValue;
Timeout = int.MaxValue;
}
if (timeout == -1)
if (Timeout == -1)
{
waitEvent.WaitOne();
WaitEvent.WaitOne();
result = NvResult.Success;
Result = NvResult.Success;
}
else if (waitEvent.WaitOne(timeout))
else if (WaitEvent.WaitOne(Timeout))
{
result = NvResult.Success;
Result = NvResult.Success;
}
else
{
result = NvResult.TimedOut;
Result = NvResult.TimedOut;
}
}
Logger.PrintDebug(LogClass.ServiceNv, "Resuming...");
}
if (extended)
if (Extended)
{
context.Memory.WriteInt32(outputPosition + 0xc, syncpt.GetMin(args.Id));
Context.Memory.WriteInt32(OutputPosition + 0xc, Syncpt.GetMin(Args.Id));
}
return result;
return Result;
}
private static int EventWait(ServiceCtx context, bool async)
private static int EventWait(ServiceCtx Context, bool Async)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvHostCtrlSyncptWaitEx args = MemoryHelper.Read<NvHostCtrlSyncptWaitEx>(context.Memory, inputPosition);
NvHostCtrlSyncptWaitEx Args = MemoryHelper.Read<NvHostCtrlSyncptWaitEx>(Context.Memory, InputPosition);
if ((uint)args.Id >= NvHostSyncpt.SyncptsCount)
if ((uint)Args.Id >= NvHostSyncpt.SyncptsCount)
{
return NvResult.InvalidInput;
}
void WriteArgs()
{
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
}
NvHostSyncpt syncpt = GetUserCtx(context).Syncpt;
NvHostSyncpt Syncpt = GetUserCtx(Context).Syncpt;
if (syncpt.MinCompare(args.Id, args.Thresh))
if (Syncpt.MinCompare(Args.Id, Args.Thresh))
{
args.Value = syncpt.GetMin(args.Id);
Args.Value = Syncpt.GetMin(Args.Id);
WriteArgs();
return NvResult.Success;
}
if (!async)
if (!Async)
{
args.Value = 0;
Args.Value = 0;
}
if (args.Timeout == 0)
if (Args.Timeout == 0)
{
WriteArgs();
@ -286,114 +286,114 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvHostCtrl
NvHostEvent Event;
int result, eventIndex;
int Result, EventIndex;
if (async)
if (Async)
{
eventIndex = args.Value;
EventIndex = Args.Value;
if ((uint)eventIndex >= NvHostCtrlUserCtx.EventsCount)
if ((uint)EventIndex >= NvHostCtrlUserCtx.EventsCount)
{
return NvResult.InvalidInput;
}
Event = GetUserCtx(context).Events[eventIndex];
Event = GetUserCtx(Context).Events[EventIndex];
}
else
{
Event = GetFreeEvent(context, syncpt, args.Id, out eventIndex);
Event = GetFreeEvent(Context, Syncpt, Args.Id, out EventIndex);
}
if (Event != null &&
(Event.State == NvHostEventState.Registered ||
Event.State == NvHostEventState.Free))
{
Event.Id = args.Id;
Event.Thresh = args.Thresh;
Event.Id = Args.Id;
Event.Thresh = Args.Thresh;
Event.State = NvHostEventState.Waiting;
if (!async)
if (!Async)
{
args.Value = ((args.Id & 0xfff) << 16) | 0x10000000;
Args.Value = ((Args.Id & 0xfff) << 16) | 0x10000000;
}
else
{
args.Value = args.Id << 4;
Args.Value = Args.Id << 4;
}
args.Value |= eventIndex;
Args.Value |= EventIndex;
result = NvResult.TryAgain;
Result = NvResult.TryAgain;
}
else
{
result = NvResult.InvalidInput;
Result = NvResult.InvalidInput;
}
WriteArgs();
return result;
return Result;
}
private static NvHostEvent GetFreeEvent(
ServiceCtx context,
NvHostSyncpt syncpt,
int id,
out int eventIndex)
ServiceCtx Context,
NvHostSyncpt Syncpt,
int Id,
out int EventIndex)
{
NvHostEvent[] events = GetUserCtx(context).Events;
NvHostEvent[] Events = GetUserCtx(Context).Events;
eventIndex = NvHostCtrlUserCtx.EventsCount;
EventIndex = NvHostCtrlUserCtx.EventsCount;
int nullIndex = NvHostCtrlUserCtx.EventsCount;
int NullIndex = NvHostCtrlUserCtx.EventsCount;
for (int index = 0; index < NvHostCtrlUserCtx.EventsCount; index++)
for (int Index = 0; Index < NvHostCtrlUserCtx.EventsCount; Index++)
{
NvHostEvent Event = events[index];
NvHostEvent Event = Events[Index];
if (Event != null)
{
if (Event.State == NvHostEventState.Registered ||
Event.State == NvHostEventState.Free)
{
eventIndex = index;
EventIndex = Index;
if (Event.Id == id)
if (Event.Id == Id)
{
return Event;
}
}
}
else if (nullIndex == NvHostCtrlUserCtx.EventsCount)
else if (NullIndex == NvHostCtrlUserCtx.EventsCount)
{
nullIndex = index;
NullIndex = Index;
}
}
if (nullIndex < NvHostCtrlUserCtx.EventsCount)
if (NullIndex < NvHostCtrlUserCtx.EventsCount)
{
eventIndex = nullIndex;
EventIndex = NullIndex;
return events[nullIndex] = new NvHostEvent();
return Events[NullIndex] = new NvHostEvent();
}
if (eventIndex < NvHostCtrlUserCtx.EventsCount)
if (EventIndex < NvHostCtrlUserCtx.EventsCount)
{
return events[eventIndex];
return Events[EventIndex];
}
return null;
}
public static NvHostCtrlUserCtx GetUserCtx(ServiceCtx context)
public static NvHostCtrlUserCtx GetUserCtx(ServiceCtx Context)
{
return _userCtxs.GetOrAdd(context.Process, (key) => new NvHostCtrlUserCtx());
return UserCtxs.GetOrAdd(Context.Process, (Key) => new NvHostCtrlUserCtx());
}
public static void UnloadProcess(KProcess process)
public static void UnloadProcess(KProcess Process)
{
_userCtxs.TryRemove(process, out _);
UserCtxs.TryRemove(Process, out _);
}
}
}

View file

@ -5,9 +5,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvHostCtrl
public const int LocksCount = 16;
public const int EventsCount = 64;
public NvHostSyncpt Syncpt { get; }
public NvHostSyncpt Syncpt { get; private set; }
public NvHostEvent[] Events { get; }
public NvHostEvent[] Events { get; private set; }
public NvHostCtrlUserCtx()
{

View file

@ -9,98 +9,98 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvHostCtrl
{
public const int SyncptsCount = 192;
private int[] _counterMin;
private int[] _counterMax;
private int[] CounterMin;
private int[] CounterMax;
private long _eventMask;
private long EventMask;
private ConcurrentDictionary<EventWaitHandle, int> _waiters;
private ConcurrentDictionary<EventWaitHandle, int> Waiters;
public NvHostSyncpt()
{
_counterMin = new int[SyncptsCount];
_counterMax = new int[SyncptsCount];
CounterMin = new int[SyncptsCount];
CounterMax = new int[SyncptsCount];
_waiters = new ConcurrentDictionary<EventWaitHandle, int>();
Waiters = new ConcurrentDictionary<EventWaitHandle, int>();
}
public int GetMin(int id)
public int GetMin(int Id)
{
return _counterMin[id];
return CounterMin[Id];
}
public int GetMax(int id)
public int GetMax(int Id)
{
return _counterMax[id];
return CounterMax[Id];
}
public int Increment(int id)
public int Increment(int Id)
{
if (((_eventMask >> id) & 1) != 0)
if (((EventMask >> Id) & 1) != 0)
{
Interlocked.Increment(ref _counterMax[id]);
Interlocked.Increment(ref CounterMax[Id]);
}
return IncrementMin(id);
return IncrementMin(Id);
}
public int IncrementMin(int id)
public int IncrementMin(int Id)
{
int value = Interlocked.Increment(ref _counterMin[id]);
int Value = Interlocked.Increment(ref CounterMin[Id]);
WakeUpWaiters(id, value);
WakeUpWaiters(Id, Value);
return value;
return Value;
}
public int IncrementMax(int id)
public int IncrementMax(int Id)
{
return Interlocked.Increment(ref _counterMax[id]);
return Interlocked.Increment(ref CounterMax[Id]);
}
public void AddWaiter(int threshold, EventWaitHandle waitEvent)
public void AddWaiter(int Threshold, EventWaitHandle WaitEvent)
{
if (!_waiters.TryAdd(waitEvent, threshold))
if (!Waiters.TryAdd(WaitEvent, Threshold))
{
throw new InvalidOperationException();
}
}
public bool RemoveWaiter(EventWaitHandle waitEvent)
public bool RemoveWaiter(EventWaitHandle WaitEvent)
{
return _waiters.TryRemove(waitEvent, out _);
return Waiters.TryRemove(WaitEvent, out _);
}
private void WakeUpWaiters(int id, int newValue)
private void WakeUpWaiters(int Id, int NewValue)
{
foreach (KeyValuePair<EventWaitHandle, int> kv in _waiters)
foreach (KeyValuePair<EventWaitHandle, int> KV in Waiters)
{
if (MinCompare(id, newValue, _counterMax[id], kv.Value))
if (MinCompare(Id, NewValue, CounterMax[Id], KV.Value))
{
kv.Key.Set();
KV.Key.Set();
_waiters.TryRemove(kv.Key, out _);
Waiters.TryRemove(KV.Key, out _);
}
}
}
public bool MinCompare(int id, int threshold)
public bool MinCompare(int Id, int Threshold)
{
return MinCompare(id, _counterMin[id], _counterMax[id], threshold);
return MinCompare(Id, CounterMin[Id], CounterMax[Id], Threshold);
}
private bool MinCompare(int id, int min, int max, int threshold)
private bool MinCompare(int Id, int Min, int Max, int Threshold)
{
int minDiff = min - threshold;
int maxDiff = max - threshold;
int MinDiff = Min - Threshold;
int MaxDiff = Max - Threshold;
if (((_eventMask >> id) & 1) != 0)
if (((EventMask >> Id) & 1) != 0)
{
return minDiff >= 0;
return MinDiff >= 0;
}
else
{
return (uint)maxDiff >= (uint)minDiff;
return (uint)MaxDiff >= (uint)MinDiff;
}
}
}

View file

@ -13,26 +13,26 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvMap
public bool Allocated;
public long DmaMapAddress;
private long _dupes;
private long Dupes;
public NvMapHandle()
{
_dupes = 1;
Dupes = 1;
}
public NvMapHandle(int size) : this()
public NvMapHandle(int Size) : this()
{
Size = size;
this.Size = Size;
}
public void IncrementRefCount()
{
Interlocked.Increment(ref _dupes);
Interlocked.Increment(ref Dupes);
}
public long DecrementRefCount()
{
return Interlocked.Decrement(ref _dupes);
return Interlocked.Decrement(ref Dupes);
}
}
}

View file

@ -11,290 +11,290 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvMap
{
private const int FlagNotFreedYet = 1;
private static ConcurrentDictionary<KProcess, IdDictionary> _maps;
private static ConcurrentDictionary<KProcess, IdDictionary> Maps;
static NvMapIoctl()
{
_maps = new ConcurrentDictionary<KProcess, IdDictionary>();
Maps = new ConcurrentDictionary<KProcess, IdDictionary>();
}
public static int ProcessIoctl(ServiceCtx context, int cmd)
public static int ProcessIoctl(ServiceCtx Context, int Cmd)
{
switch (cmd & 0xffff)
switch (Cmd & 0xffff)
{
case 0x0101: return Create(context);
case 0x0103: return FromId(context);
case 0x0104: return Alloc (context);
case 0x0105: return Free (context);
case 0x0109: return Param (context);
case 0x010e: return GetId (context);
case 0x0101: return Create(Context);
case 0x0103: return FromId(Context);
case 0x0104: return Alloc (Context);
case 0x0105: return Free (Context);
case 0x0109: return Param (Context);
case 0x010e: return GetId (Context);
}
Logger.PrintWarning(LogClass.ServiceNv, $"Unsupported Ioctl command 0x{cmd:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Unsupported Ioctl command 0x{Cmd:x8}!");
return NvResult.NotSupported;
}
private static int Create(ServiceCtx context)
private static int Create(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvMapCreate args = MemoryHelper.Read<NvMapCreate>(context.Memory, inputPosition);
NvMapCreate Args = MemoryHelper.Read<NvMapCreate>(Context.Memory, InputPosition);
if (args.Size == 0)
if (Args.Size == 0)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid size 0x{args.Size:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid size 0x{Args.Size:x8}!");
return NvResult.InvalidInput;
}
int size = IntUtils.AlignUp(args.Size, NvGpuVmm.PageSize);
int Size = IntUtils.AlignUp(Args.Size, NvGpuVmm.PageSize);
args.Handle = AddNvMap(context, new NvMapHandle(size));
Args.Handle = AddNvMap(Context, new NvMapHandle(Size));
Logger.PrintInfo(LogClass.ServiceNv, $"Created map {args.Handle} with size 0x{size:x8}!");
Logger.PrintInfo(LogClass.ServiceNv, $"Created map {Args.Handle} with size 0x{Size:x8}!");
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int FromId(ServiceCtx context)
private static int FromId(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvMapFromId args = MemoryHelper.Read<NvMapFromId>(context.Memory, inputPosition);
NvMapFromId Args = MemoryHelper.Read<NvMapFromId>(Context.Memory, InputPosition);
NvMapHandle map = GetNvMap(context, args.Id);
NvMapHandle Map = GetNvMap(Context, Args.Id);
if (map == null)
if (Map == null)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{args.Handle:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!");
return NvResult.InvalidInput;
}
map.IncrementRefCount();
Map.IncrementRefCount();
args.Handle = args.Id;
Args.Handle = Args.Id;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int Alloc(ServiceCtx context)
private static int Alloc(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvMapAlloc args = MemoryHelper.Read<NvMapAlloc>(context.Memory, inputPosition);
NvMapAlloc Args = MemoryHelper.Read<NvMapAlloc>(Context.Memory, InputPosition);
NvMapHandle map = GetNvMap(context, args.Handle);
NvMapHandle Map = GetNvMap(Context, Args.Handle);
if (map == null)
if (Map == null)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{args.Handle:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!");
return NvResult.InvalidInput;
}
if ((args.Align & (args.Align - 1)) != 0)
if ((Args.Align & (Args.Align - 1)) != 0)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid alignment 0x{args.Align:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid alignment 0x{Args.Align:x8}!");
return NvResult.InvalidInput;
}
if ((uint)args.Align < NvGpuVmm.PageSize)
if ((uint)Args.Align < NvGpuVmm.PageSize)
{
args.Align = NvGpuVmm.PageSize;
Args.Align = NvGpuVmm.PageSize;
}
int result = NvResult.Success;
int Result = NvResult.Success;
if (!map.Allocated)
if (!Map.Allocated)
{
map.Allocated = true;
Map.Allocated = true;
map.Align = args.Align;
map.Kind = (byte)args.Kind;
Map.Align = Args.Align;
Map.Kind = (byte)Args.Kind;
int size = IntUtils.AlignUp(map.Size, NvGpuVmm.PageSize);
int Size = IntUtils.AlignUp(Map.Size, NvGpuVmm.PageSize);
long address = args.Address;
long Address = Args.Address;
if (address == 0)
if (Address == 0)
{
//When the address is zero, we need to allocate
//our own backing memory for the NvMap.
//TODO: Is this allocation inside the transfer memory?
result = NvResult.OutOfMemory;
Result = NvResult.OutOfMemory;
}
if (result == NvResult.Success)
if (Result == NvResult.Success)
{
map.Size = size;
map.Address = address;
Map.Size = Size;
Map.Address = Address;
}
}
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return result;
return Result;
}
private static int Free(ServiceCtx context)
private static int Free(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvMapFree args = MemoryHelper.Read<NvMapFree>(context.Memory, inputPosition);
NvMapFree Args = MemoryHelper.Read<NvMapFree>(Context.Memory, InputPosition);
NvMapHandle map = GetNvMap(context, args.Handle);
NvMapHandle Map = GetNvMap(Context, Args.Handle);
if (map == null)
if (Map == null)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{args.Handle:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!");
return NvResult.InvalidInput;
}
if (map.DecrementRefCount() <= 0)
if (Map.DecrementRefCount() <= 0)
{
DeleteNvMap(context, args.Handle);
DeleteNvMap(Context, Args.Handle);
Logger.PrintInfo(LogClass.ServiceNv, $"Deleted map {args.Handle}!");
Logger.PrintInfo(LogClass.ServiceNv, $"Deleted map {Args.Handle}!");
args.Address = map.Address;
args.Flags = 0;
Args.Address = Map.Address;
Args.Flags = 0;
}
else
{
args.Address = 0;
args.Flags = FlagNotFreedYet;
Args.Address = 0;
Args.Flags = FlagNotFreedYet;
}
args.Size = map.Size;
Args.Size = Map.Size;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int Param(ServiceCtx context)
private static int Param(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvMapParam args = MemoryHelper.Read<NvMapParam>(context.Memory, inputPosition);
NvMapParam Args = MemoryHelper.Read<NvMapParam>(Context.Memory, InputPosition);
NvMapHandle map = GetNvMap(context, args.Handle);
NvMapHandle Map = GetNvMap(Context, Args.Handle);
if (map == null)
if (Map == null)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{args.Handle:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!");
return NvResult.InvalidInput;
}
switch ((NvMapHandleParam)args.Param)
switch ((NvMapHandleParam)Args.Param)
{
case NvMapHandleParam.Size: args.Result = map.Size; break;
case NvMapHandleParam.Align: args.Result = map.Align; break;
case NvMapHandleParam.Heap: args.Result = 0x40000000; break;
case NvMapHandleParam.Kind: args.Result = map.Kind; break;
case NvMapHandleParam.Compr: args.Result = 0; break;
case NvMapHandleParam.Size: Args.Result = Map.Size; break;
case NvMapHandleParam.Align: Args.Result = Map.Align; break;
case NvMapHandleParam.Heap: Args.Result = 0x40000000; break;
case NvMapHandleParam.Kind: Args.Result = Map.Kind; break;
case NvMapHandleParam.Compr: Args.Result = 0; break;
//Note: Base is not supported and returns an error.
//Any other value also returns an error.
default: return NvResult.InvalidInput;
}
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int GetId(ServiceCtx context)
private static int GetId(ServiceCtx Context)
{
long inputPosition = context.Request.GetBufferType0x21().Position;
long outputPosition = context.Request.GetBufferType0x22().Position;
long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position;
NvMapGetId args = MemoryHelper.Read<NvMapGetId>(context.Memory, inputPosition);
NvMapGetId Args = MemoryHelper.Read<NvMapGetId>(Context.Memory, InputPosition);
NvMapHandle map = GetNvMap(context, args.Handle);
NvMapHandle Map = GetNvMap(Context, Args.Handle);
if (map == null)
if (Map == null)
{
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{args.Handle:x8}!");
Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!");
return NvResult.InvalidInput;
}
args.Id = args.Handle;
Args.Id = Args.Handle;
MemoryHelper.Write(context.Memory, outputPosition, args);
MemoryHelper.Write(Context.Memory, OutputPosition, Args);
return NvResult.Success;
}
private static int AddNvMap(ServiceCtx context, NvMapHandle map)
private static int AddNvMap(ServiceCtx Context, NvMapHandle Map)
{
IdDictionary dict = _maps.GetOrAdd(context.Process, (key) =>
IdDictionary Dict = Maps.GetOrAdd(Context.Process, (Key) =>
{
IdDictionary newDict = new IdDictionary();
IdDictionary NewDict = new IdDictionary();
newDict.Add(0, new NvMapHandle());
NewDict.Add(0, new NvMapHandle());
return newDict;
return NewDict;
});
return dict.Add(map);
return Dict.Add(Map);
}
private static bool DeleteNvMap(ServiceCtx context, int handle)
private static bool DeleteNvMap(ServiceCtx Context, int Handle)
{
if (_maps.TryGetValue(context.Process, out IdDictionary dict))
if (Maps.TryGetValue(Context.Process, out IdDictionary Dict))
{
return dict.Delete(handle) != null;
return Dict.Delete(Handle) != null;
}
return false;
}
public static void InitializeNvMap(ServiceCtx context)
public static void InitializeNvMap(ServiceCtx Context)
{
IdDictionary dict = _maps.GetOrAdd(context.Process, (key) =>new IdDictionary());
IdDictionary Dict = Maps.GetOrAdd(Context.Process, (Key) =>new IdDictionary());
dict.Add(0, new NvMapHandle());
Dict.Add(0, new NvMapHandle());
}
public static NvMapHandle GetNvMapWithFb(ServiceCtx context, int handle)
public static NvMapHandle GetNvMapWithFb(ServiceCtx Context, int Handle)
{
if (_maps.TryGetValue(context.Process, out IdDictionary dict))
if (Maps.TryGetValue(Context.Process, out IdDictionary Dict))
{
return dict.GetData<NvMapHandle>(handle);
return Dict.GetData<NvMapHandle>(Handle);
}
return null;
}
public static NvMapHandle GetNvMap(ServiceCtx context, int handle)
public static NvMapHandle GetNvMap(ServiceCtx Context, int Handle)
{
if (handle != 0 && _maps.TryGetValue(context.Process, out IdDictionary dict))
if (Handle != 0 && Maps.TryGetValue(Context.Process, out IdDictionary Dict))
{
return dict.GetData<NvMapHandle>(handle);
return Dict.GetData<NvMapHandle>(Handle);
}
return null;
}
public static void UnloadProcess(KProcess process)
public static void UnloadProcess(KProcess Process)
{
_maps.TryRemove(process, out _);
Maps.TryRemove(Process, out _);
}
}
}

View file

@ -6,29 +6,29 @@ namespace Ryujinx.HLE.HOS.Services.Pctl
{
class IParentalControlService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private bool _initialized = false;
private bool Initialized = false;
private bool _needInitialize;
private bool NeedInitialize;
public IParentalControlService(bool needInitialize = true)
public IParentalControlService(bool NeedInitialize = true)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 1, Initialize }
};
_needInitialize = needInitialize;
this.NeedInitialize = NeedInitialize;
}
public long Initialize(ServiceCtx context)
public long Initialize(ServiceCtx Context)
{
if (_needInitialize && !_initialized)
if (NeedInitialize && !Initialized)
{
_initialized = true;
Initialized = true;
}
else
{

View file

@ -5,29 +5,29 @@ namespace Ryujinx.HLE.HOS.Services.Pctl
{
class IParentalControlServiceFactory : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IParentalControlServiceFactory()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, CreateService },
{ 1, CreateServiceWithoutInitialize }
};
}
public long CreateService(ServiceCtx context)
public long CreateService(ServiceCtx Context)
{
MakeObject(context, new IParentalControlService());
MakeObject(Context, new IParentalControlService());
return 0;
}
public long CreateServiceWithoutInitialize(ServiceCtx context)
public long CreateServiceWithoutInitialize(ServiceCtx Context)
{
MakeObject(context, new IParentalControlService(false));
MakeObject(Context, new IParentalControlService(false));
return 0;
}

View file

@ -8,13 +8,13 @@ namespace Ryujinx.HLE.HOS.Services.Pl
{
class ISharedFontManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ISharedFontManager()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, RequestLoad },
{ 1, GetLoadState },
@ -25,104 +25,104 @@ namespace Ryujinx.HLE.HOS.Services.Pl
};
}
public long RequestLoad(ServiceCtx context)
public long RequestLoad(ServiceCtx Context)
{
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
SharedFontType FontType = (SharedFontType)Context.RequestData.ReadInt32();
//We don't need to do anything here because we do lazy initialization
//on SharedFontManager (the font is loaded when necessary).
return 0;
}
public long GetLoadState(ServiceCtx context)
public long GetLoadState(ServiceCtx Context)
{
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
SharedFontType FontType = (SharedFontType)Context.RequestData.ReadInt32();
//1 (true) indicates that the font is already loaded.
//All fonts are already loaded.
context.ResponseData.Write(1);
Context.ResponseData.Write(1);
return 0;
}
public long GetFontSize(ServiceCtx context)
public long GetFontSize(ServiceCtx Context)
{
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
SharedFontType FontType = (SharedFontType)Context.RequestData.ReadInt32();
context.ResponseData.Write(context.Device.System.Font.GetFontSize(fontType));
Context.ResponseData.Write(Context.Device.System.Font.GetFontSize(FontType));
return 0;
}
public long GetSharedMemoryAddressOffset(ServiceCtx context)
public long GetSharedMemoryAddressOffset(ServiceCtx Context)
{
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
SharedFontType FontType = (SharedFontType)Context.RequestData.ReadInt32();
context.ResponseData.Write(context.Device.System.Font.GetSharedMemoryAddressOffset(fontType));
Context.ResponseData.Write(Context.Device.System.Font.GetSharedMemoryAddressOffset(FontType));
return 0;
}
public long GetSharedMemoryNativeHandle(ServiceCtx context)
public long GetSharedMemoryNativeHandle(ServiceCtx Context)
{
context.Device.System.Font.EnsureInitialized(context.Device.System.ContentManager);
Context.Device.System.Font.EnsureInitialized(Context.Device.System.ContentManager);
if (context.Process.HandleTable.GenerateHandle(context.Device.System.FontSharedMem, out int handle) != KernelResult.Success)
if (Context.Process.HandleTable.GenerateHandle(Context.Device.System.FontSharedMem, out int Handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
return 0;
}
public long GetSharedFontInOrderOfPriority(ServiceCtx context)
public long GetSharedFontInOrderOfPriority(ServiceCtx Context)
{
long languageCode = context.RequestData.ReadInt64();
int loadedCount = 0;
long LanguageCode = Context.RequestData.ReadInt64();
int LoadedCount = 0;
for (SharedFontType type = 0; type < SharedFontType.Count; type++)
for (SharedFontType Type = 0; Type < SharedFontType.Count; Type++)
{
int offset = (int)type * 4;
int Offset = (int)Type * 4;
if (!AddFontToOrderOfPriorityList(context, type, offset))
if (!AddFontToOrderOfPriorityList(Context, (SharedFontType)Type, Offset))
{
break;
}
loadedCount++;
LoadedCount++;
}
context.ResponseData.Write(loadedCount);
context.ResponseData.Write((int)SharedFontType.Count);
Context.ResponseData.Write(LoadedCount);
Context.ResponseData.Write((int)SharedFontType.Count);
return 0;
}
private bool AddFontToOrderOfPriorityList(ServiceCtx context, SharedFontType fontType, int offset)
private bool AddFontToOrderOfPriorityList(ServiceCtx Context, SharedFontType FontType, int Offset)
{
long typesPosition = context.Request.ReceiveBuff[0].Position;
long typesSize = context.Request.ReceiveBuff[0].Size;
long TypesPosition = Context.Request.ReceiveBuff[0].Position;
long TypesSize = Context.Request.ReceiveBuff[0].Size;
long offsetsPosition = context.Request.ReceiveBuff[1].Position;
long offsetsSize = context.Request.ReceiveBuff[1].Size;
long OffsetsPosition = Context.Request.ReceiveBuff[1].Position;
long OffsetsSize = Context.Request.ReceiveBuff[1].Size;
long fontSizeBufferPosition = context.Request.ReceiveBuff[2].Position;
long fontSizeBufferSize = context.Request.ReceiveBuff[2].Size;
long FontSizeBufferPosition = Context.Request.ReceiveBuff[2].Position;
long FontSizeBufferSize = Context.Request.ReceiveBuff[2].Size;
if ((uint)offset + 4 > (uint)typesSize ||
(uint)offset + 4 > (uint)offsetsSize ||
(uint)offset + 4 > (uint)fontSizeBufferSize)
if ((uint)Offset + 4 > (uint)TypesSize ||
(uint)Offset + 4 > (uint)OffsetsSize ||
(uint)Offset + 4 > (uint)FontSizeBufferSize)
{
return false;
}
context.Memory.WriteInt32(typesPosition + offset, (int)fontType);
Context.Memory.WriteInt32(TypesPosition + Offset, (int)FontType);
context.Memory.WriteInt32(offsetsPosition + offset, context.Device.System.Font.GetSharedMemoryAddressOffset(fontType));
Context.Memory.WriteInt32(OffsetsPosition + Offset, Context.Device.System.Font.GetSharedMemoryAddressOffset(FontType));
context.Memory.WriteInt32(fontSizeBufferPosition + offset, context.Device.System.Font.GetFontSize(fontType));
Context.Memory.WriteInt32(FontSizeBufferPosition + Offset, Context.Device.System.Font.GetFontSize(FontType));
return true;
}

View file

@ -6,19 +6,19 @@ namespace Ryujinx.HLE.HOS.Services.Prepo
{
class IPrepoService : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IPrepoService()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 10101, SaveReportWithUser }
};
}
public static long SaveReportWithUser(ServiceCtx context)
public static long SaveReportWithUser(ServiceCtx Context)
{
Logger.PrintStub(LogClass.ServicePrepo, "Stubbed.");

View file

@ -6,20 +6,20 @@ namespace Ryujinx.HLE.HOS.Services.Psm
{
class IPsmServer : IpcService
{
enum ChargerType
enum ChargerType : int
{
None,
ChargerOrDock,
UsbC
}
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IPsmServer()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetBatteryChargePercentage },
{ 1, GetChargerType },
@ -28,21 +28,21 @@ namespace Ryujinx.HLE.HOS.Services.Psm
}
// GetBatteryChargePercentage() -> u32
public static long GetBatteryChargePercentage(ServiceCtx context)
public static long GetBatteryChargePercentage(ServiceCtx Context)
{
int chargePercentage = 100;
int ChargePercentage = 100;
context.ResponseData.Write(chargePercentage);
Context.ResponseData.Write(ChargePercentage);
Logger.PrintStub(LogClass.ServicePsm, $"Stubbed. ChargePercentage: {chargePercentage}");
Logger.PrintStub(LogClass.ServicePsm, $"Stubbed. ChargePercentage: {ChargePercentage}");
return 0;
}
// GetChargerType() -> u32
public static long GetChargerType(ServiceCtx context)
public static long GetChargerType(ServiceCtx Context)
{
context.ResponseData.Write((int)ChargerType.ChargerOrDock);
Context.ResponseData.Write((int)ChargerType.ChargerOrDock);
Logger.PrintStub(LogClass.ServicePsm, $"Stubbed. ChargerType: {ChargerType.ChargerOrDock}");
@ -50,9 +50,9 @@ namespace Ryujinx.HLE.HOS.Services.Psm
}
// OpenSession() -> IPsmSession
public long OpenSession(ServiceCtx context)
public long OpenSession(ServiceCtx Context)
{
MakeObject(context, new IPsmSession(context.Device.System));
MakeObject(Context, new IPsmSession(Context.Device.System));
return 0;
}

View file

@ -7,16 +7,16 @@ namespace Ryujinx.HLE.HOS.Services.Psm
{
class IPsmSession : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent _stateChangeEvent;
private int _stateChangeEventHandle;
private KEvent StateChangeEvent;
private int StateChangeEventHandle;
public IPsmSession(Horizon system)
public IPsmSession(Horizon System)
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, BindStateChangeEvent },
{ 1, UnbindStateChangeEvent },
@ -25,24 +25,24 @@ namespace Ryujinx.HLE.HOS.Services.Psm
{ 4, SetBatteryVoltageStateChangeEventEnabled }
};
_stateChangeEvent = new KEvent(system);
_stateChangeEventHandle = -1;
StateChangeEvent = new KEvent(System);
StateChangeEventHandle = -1;
}
// BindStateChangeEvent() -> KObject
public long BindStateChangeEvent(ServiceCtx context)
public long BindStateChangeEvent(ServiceCtx Context)
{
if (_stateChangeEventHandle == -1)
if (StateChangeEventHandle == -1)
{
KernelResult resultCode = context.Process.HandleTable.GenerateHandle(_stateChangeEvent, out int stateChangeEventHandle);
KernelResult ResultCode = Context.Process.HandleTable.GenerateHandle(StateChangeEvent, out int StateChangeEventHandle);
if (resultCode != KernelResult.Success)
if (ResultCode != KernelResult.Success)
{
return (long)resultCode;
return (long)ResultCode;
}
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_stateChangeEventHandle);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(StateChangeEventHandle);
Logger.PrintStub(LogClass.ServicePsm, "Stubbed.");
@ -50,12 +50,12 @@ namespace Ryujinx.HLE.HOS.Services.Psm
}
// UnbindStateChangeEvent()
public long UnbindStateChangeEvent(ServiceCtx context)
public long UnbindStateChangeEvent(ServiceCtx Context)
{
if (_stateChangeEventHandle != -1)
if (StateChangeEventHandle != -1)
{
context.Process.HandleTable.CloseHandle(_stateChangeEventHandle);
_stateChangeEventHandle = -1;
Context.Process.HandleTable.CloseHandle(StateChangeEventHandle);
StateChangeEventHandle = -1;
}
Logger.PrintStub(LogClass.ServicePsm, "Stubbed.");
@ -64,31 +64,31 @@ namespace Ryujinx.HLE.HOS.Services.Psm
}
// SetChargerTypeChangeEventEnabled(u8)
public long SetChargerTypeChangeEventEnabled(ServiceCtx context)
public long SetChargerTypeChangeEventEnabled(ServiceCtx Context)
{
bool chargerTypeChangeEventEnabled = context.RequestData.ReadBoolean();
bool ChargerTypeChangeEventEnabled = Context.RequestData.ReadBoolean();
Logger.PrintStub(LogClass.ServicePsm, $"Stubbed. ChargerTypeChangeEventEnabled: {chargerTypeChangeEventEnabled}");
Logger.PrintStub(LogClass.ServicePsm, $"Stubbed. ChargerTypeChangeEventEnabled: {ChargerTypeChangeEventEnabled}");
return 0;
}
// SetPowerSupplyChangeEventEnabled(u8)
public long SetPowerSupplyChangeEventEnabled(ServiceCtx context)
public long SetPowerSupplyChangeEventEnabled(ServiceCtx Context)
{
bool powerSupplyChangeEventEnabled = context.RequestData.ReadBoolean();
bool PowerSupplyChangeEventEnabled = Context.RequestData.ReadBoolean();
Logger.PrintStub(LogClass.ServicePsm, $"Stubbed. PowerSupplyChangeEventEnabled: {powerSupplyChangeEventEnabled}");
Logger.PrintStub(LogClass.ServicePsm, $"Stubbed. PowerSupplyChangeEventEnabled: {PowerSupplyChangeEventEnabled}");
return 0;
}
// SetBatteryVoltageStateChangeEventEnabled(u8)
public long SetBatteryVoltageStateChangeEventEnabled(ServiceCtx context)
public long SetBatteryVoltageStateChangeEventEnabled(ServiceCtx Context)
{
bool batteryVoltageStateChangeEventEnabled = context.RequestData.ReadBoolean();
bool BatteryVoltageStateChangeEventEnabled = Context.RequestData.ReadBoolean();
Logger.PrintStub(LogClass.ServicePsm, $"Stubbed. BatteryVoltageStateChangeEventEnabled: {batteryVoltageStateChangeEventEnabled}");
Logger.PrintStub(LogClass.ServicePsm, $"Stubbed. BatteryVoltageStateChangeEventEnabled: {BatteryVoltageStateChangeEventEnabled}");
return 0;
}

View file

@ -31,9 +31,9 @@ namespace Ryujinx.HLE.HOS.Services
{
static class ServiceFactory
{
public static IpcService MakeService(Horizon system, string name)
public static IpcService MakeService(Horizon System, string Name)
{
switch (name)
switch (Name)
{
case "acc:u0":
return new IAccountService();
@ -90,7 +90,7 @@ namespace Ryujinx.HLE.HOS.Services
return new IRandomInterface();
case "es":
return new IeTicketService();
return new IETicketService();
case "friend:a":
return new Friend.IServiceCreator();
@ -102,7 +102,7 @@ namespace Ryujinx.HLE.HOS.Services
return new IFileSystemProxy();
case "hid":
return new IHidServer(system);
return new IHidServer(System);
case "irs":
return new IIrSensorServer();
@ -141,10 +141,10 @@ namespace Ryujinx.HLE.HOS.Services
return new IVulnerabilityManagerInterface();
case "nvdrv":
return new INvDrvServices(system);
return new INvDrvServices(System);
case "nvdrv:a":
return new INvDrvServices(system);
return new INvDrvServices(System);
case "pctl:s":
return new IParentalControlServiceFactory();
@ -204,7 +204,7 @@ namespace Ryujinx.HLE.HOS.Services
return new IApplicationRootService();
}
throw new NotImplementedException(name);
throw new NotImplementedException(Name);
}
}
}

View file

@ -6,13 +6,13 @@ namespace Ryujinx.HLE.HOS.Services.Set
{
class ISettingsServer : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ISettingsServer()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, GetLanguageCode },
{ 1, GetAvailableLanguageCodes },
@ -21,57 +21,57 @@ namespace Ryujinx.HLE.HOS.Services.Set
};
}
public static long GetLanguageCode(ServiceCtx context)
public static long GetLanguageCode(ServiceCtx Context)
{
context.ResponseData.Write(context.Device.System.State.DesiredLanguageCode);
Context.ResponseData.Write(Context.Device.System.State.DesiredLanguageCode);
return 0;
}
public static long GetAvailableLanguageCodes(ServiceCtx context)
public static long GetAvailableLanguageCodes(ServiceCtx Context)
{
GetAvailableLanguagesCodesImpl(
context,
context.Request.RecvListBuff[0].Position,
context.Request.RecvListBuff[0].Size);
Context,
Context.Request.RecvListBuff[0].Position,
Context.Request.RecvListBuff[0].Size);
return 0;
}
public static long GetAvailableLanguageCodeCount(ServiceCtx context)
public static long GetAvailableLanguageCodeCount(ServiceCtx Context)
{
context.ResponseData.Write(SystemStateMgr.LanguageCodes.Length);
Context.ResponseData.Write(SystemStateMgr.LanguageCodes.Length);
return 0;
}
public static long GetAvailableLanguageCodes2(ServiceCtx context)
public static long GetAvailableLanguageCodes2(ServiceCtx Context)
{
GetAvailableLanguagesCodesImpl(
context,
context.Request.ReceiveBuff[0].Position,
context.Request.ReceiveBuff[0].Size);
Context,
Context.Request.ReceiveBuff[0].Position,
Context.Request.ReceiveBuff[0].Size);
return 0;
}
public static long GetAvailableLanguagesCodesImpl(ServiceCtx context, long position, long size)
public static long GetAvailableLanguagesCodesImpl(ServiceCtx Context, long Position, long Size)
{
int count = (int)(size / 8);
int Count = (int)(Size / 8);
if (count > SystemStateMgr.LanguageCodes.Length)
if (Count > SystemStateMgr.LanguageCodes.Length)
{
count = SystemStateMgr.LanguageCodes.Length;
Count = SystemStateMgr.LanguageCodes.Length;
}
for (int index = 0; index < count; index++)
for (int Index = 0; Index < Count; Index++)
{
context.Memory.WriteInt64(position, SystemStateMgr.GetLanguageCode(index));
Context.Memory.WriteInt64(Position, SystemStateMgr.GetLanguageCode(Index));
position += 8;
Position += 8;
}
context.ResponseData.Write(count);
Context.ResponseData.Write(Count);
return 0;
}

View file

@ -12,13 +12,13 @@ namespace Ryujinx.HLE.HOS.Services.Set
{
class ISystemSettingsServer : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ISystemSettingsServer()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 3, GetFirmwareVersion },
{ 4, GetFirmwareVersion2 },
@ -29,185 +29,185 @@ namespace Ryujinx.HLE.HOS.Services.Set
}
// GetFirmwareVersion() -> buffer<nn::settings::system::FirmwareVersion, 0x1a, 0x100>
public static long GetFirmwareVersion(ServiceCtx context)
public static long GetFirmwareVersion(ServiceCtx Context)
{
return GetFirmwareVersion2(context);
return GetFirmwareVersion2(Context);
}
// GetFirmwareVersion2() -> buffer<nn::settings::system::FirmwareVersion, 0x1a, 0x100>
public static long GetFirmwareVersion2(ServiceCtx context)
public static long GetFirmwareVersion2(ServiceCtx Context)
{
long replyPos = context.Request.RecvListBuff[0].Position;
long replySize = context.Request.RecvListBuff[0].Size;
long ReplyPos = Context.Request.RecvListBuff[0].Position;
long ReplySize = Context.Request.RecvListBuff[0].Size;
byte[] firmwareData = GetFirmwareData(context.Device);
byte[] FirmwareData = GetFirmwareData(Context.Device);
if (firmwareData != null)
if (FirmwareData != null)
{
context.Memory.WriteBytes(replyPos, firmwareData);
Context.Memory.WriteBytes(ReplyPos, FirmwareData);
return 0;
}
const byte majorFwVersion = 0x03;
const byte minorFwVersion = 0x00;
const byte microFwVersion = 0x00;
const byte unknown = 0x00; //Build?
const byte MajorFWVersion = 0x03;
const byte MinorFWVersion = 0x00;
const byte MicroFWVersion = 0x00;
const byte Unknown = 0x00; //Build?
const int revisionNumber = 0x0A;
const int RevisionNumber = 0x0A;
const string platform = "NX";
const string unknownHex = "7fbde2b0bba4d14107bf836e4643043d9f6c8e47";
const string version = "3.0.0";
const string build = "NintendoSDK Firmware for NX 3.0.0-10.0";
const string Platform = "NX";
const string UnknownHex = "7fbde2b0bba4d14107bf836e4643043d9f6c8e47";
const string Version = "3.0.0";
const string Build = "NintendoSDK Firmware for NX 3.0.0-10.0";
//http://switchbrew.org/index.php?title=System_Version_Title
using (MemoryStream ms = new MemoryStream(0x100))
using (MemoryStream MS = new MemoryStream(0x100))
{
BinaryWriter writer = new BinaryWriter(ms);
BinaryWriter Writer = new BinaryWriter(MS);
writer.Write(majorFwVersion);
writer.Write(minorFwVersion);
writer.Write(microFwVersion);
writer.Write(unknown);
Writer.Write(MajorFWVersion);
Writer.Write(MinorFWVersion);
Writer.Write(MicroFWVersion);
Writer.Write(Unknown);
writer.Write(revisionNumber);
Writer.Write(RevisionNumber);
writer.Write(Encoding.ASCII.GetBytes(platform));
Writer.Write(Encoding.ASCII.GetBytes(Platform));
ms.Seek(0x28, SeekOrigin.Begin);
MS.Seek(0x28, SeekOrigin.Begin);
writer.Write(Encoding.ASCII.GetBytes(unknownHex));
Writer.Write(Encoding.ASCII.GetBytes(UnknownHex));
ms.Seek(0x68, SeekOrigin.Begin);
MS.Seek(0x68, SeekOrigin.Begin);
writer.Write(Encoding.ASCII.GetBytes(version));
Writer.Write(Encoding.ASCII.GetBytes(Version));
ms.Seek(0x80, SeekOrigin.Begin);
MS.Seek(0x80, SeekOrigin.Begin);
writer.Write(Encoding.ASCII.GetBytes(build));
Writer.Write(Encoding.ASCII.GetBytes(Build));
context.Memory.WriteBytes(replyPos, ms.ToArray());
Context.Memory.WriteBytes(ReplyPos, MS.ToArray());
}
return 0;
}
// GetColorSetId() -> i32
public static long GetColorSetId(ServiceCtx context)
public static long GetColorSetId(ServiceCtx Context)
{
context.ResponseData.Write((int)context.Device.System.State.ThemeColor);
Context.ResponseData.Write((int)Context.Device.System.State.ThemeColor);
return 0;
}
// GetColorSetId() -> i32
public static long SetColorSetId(ServiceCtx context)
public static long SetColorSetId(ServiceCtx Context)
{
int colorSetId = context.RequestData.ReadInt32();
int ColorSetId = Context.RequestData.ReadInt32();
context.Device.System.State.ThemeColor = (ColorSet)colorSetId;
Context.Device.System.State.ThemeColor = (ColorSet)ColorSetId;
return 0;
}
// GetSettingsItemValue(buffer<nn::settings::SettingsName, 0x19, 0x48>, buffer<nn::settings::SettingsItemKey, 0x19, 0x48>) -> (u64, buffer<unknown, 6, 0>)
public static long GetSettingsItemValue(ServiceCtx context)
public static long GetSettingsItemValue(ServiceCtx Context)
{
long classPos = context.Request.PtrBuff[0].Position;
long classSize = context.Request.PtrBuff[0].Size;
long ClassPos = Context.Request.PtrBuff[0].Position;
long ClassSize = Context.Request.PtrBuff[0].Size;
long namePos = context.Request.PtrBuff[1].Position;
long nameSize = context.Request.PtrBuff[1].Size;
long NamePos = Context.Request.PtrBuff[1].Position;
long NameSize = Context.Request.PtrBuff[1].Size;
long replyPos = context.Request.ReceiveBuff[0].Position;
long replySize = context.Request.ReceiveBuff[0].Size;
long ReplyPos = Context.Request.ReceiveBuff[0].Position;
long ReplySize = Context.Request.ReceiveBuff[0].Size;
byte[] Class = context.Memory.ReadBytes(classPos, classSize);
byte[] name = context.Memory.ReadBytes(namePos, nameSize);
byte[] Class = Context.Memory.ReadBytes(ClassPos, ClassSize);
byte[] Name = Context.Memory.ReadBytes(NamePos, NameSize);
string askedSetting = Encoding.ASCII.GetString(Class).Trim('\0') + "!" + Encoding.ASCII.GetString(name).Trim('\0');
string AskedSetting = Encoding.ASCII.GetString(Class).Trim('\0') + "!" + Encoding.ASCII.GetString(Name).Trim('\0');
NxSettings.Settings.TryGetValue(askedSetting, out object nxSetting);
NxSettings.Settings.TryGetValue(AskedSetting, out object NxSetting);
if (nxSetting != null)
if (NxSetting != null)
{
byte[] settingBuffer = new byte[replySize];
byte[] SettingBuffer = new byte[ReplySize];
if (nxSetting is string stringValue)
if (NxSetting is string StringValue)
{
if (stringValue.Length + 1 > replySize)
if (StringValue.Length + 1 > ReplySize)
{
Logger.PrintError(LogClass.ServiceSet, $"{askedSetting} String value size is too big!");
Logger.PrintError(LogClass.ServiceSet, $"{AskedSetting} String value size is too big!");
}
else
{
settingBuffer = Encoding.ASCII.GetBytes(stringValue + "\0");
SettingBuffer = Encoding.ASCII.GetBytes(StringValue + "\0");
}
}
if (nxSetting is int intValue)
if (NxSetting is int IntValue)
{
settingBuffer = BitConverter.GetBytes(intValue);
SettingBuffer = BitConverter.GetBytes(IntValue);
}
else if (nxSetting is bool boolValue)
else if (NxSetting is bool BoolValue)
{
settingBuffer[0] = boolValue ? (byte)1 : (byte)0;
SettingBuffer[0] = BoolValue ? (byte)1 : (byte)0;
}
else
{
throw new NotImplementedException(nxSetting.GetType().Name);
throw new NotImplementedException(NxSetting.GetType().Name);
}
context.Memory.WriteBytes(replyPos, settingBuffer);
Context.Memory.WriteBytes(ReplyPos, SettingBuffer);
Logger.PrintDebug(LogClass.ServiceSet, $"{askedSetting} set value: {nxSetting} as {nxSetting.GetType()}");
Logger.PrintDebug(LogClass.ServiceSet, $"{AskedSetting} set value: {NxSetting} as {NxSetting.GetType()}");
}
else
{
Logger.PrintError(LogClass.ServiceSet, $"{askedSetting} not found!");
Logger.PrintError(LogClass.ServiceSet, $"{AskedSetting} not found!");
}
return 0;
}
public static byte[] GetFirmwareData(Switch device)
public static byte[] GetFirmwareData(Switch Device)
{
byte[] data = null;
long titleId = 0x0100000000000809;
string contentPath = device.System.ContentManager.GetInstalledContentPath(titleId, StorageId.NandSystem, ContentType.Data);
byte[] Data = null;
long TitleId = 0x0100000000000809;
string ContentPath = Device.System.ContentManager.GetInstalledContentPath(TitleId, StorageId.NandSystem, ContentType.Data);
if(string.IsNullOrWhiteSpace(contentPath))
if(string.IsNullOrWhiteSpace(ContentPath))
{
return null;
}
string firmwareTitlePath = device.FileSystem.SwitchPathToSystemPath(contentPath);
FileStream firmwareStream = File.Open(firmwareTitlePath, FileMode.Open, FileAccess.Read);
Nca firmwareContent = new Nca(device.System.KeySet, firmwareStream, false);
Stream romFsStream = firmwareContent.OpenSection(0, false, device.System.FsIntegrityCheckLevel);
string FirmwareTitlePath = Device.FileSystem.SwitchPathToSystemPath(ContentPath);
FileStream FirmwareStream = File.Open(FirmwareTitlePath, FileMode.Open, FileAccess.Read);
Nca FirmwareContent = new Nca(Device.System.KeySet, FirmwareStream, false);
Stream RomFsStream = FirmwareContent.OpenSection(0, false, Device.System.FsIntegrityCheckLevel);
if(romFsStream == null)
if(RomFsStream == null)
{
return null;
}
Romfs firmwareRomFs = new Romfs(romFsStream);
Romfs FirmwareRomFs = new Romfs(RomFsStream);
using(MemoryStream memoryStream = new MemoryStream())
using(MemoryStream MemoryStream = new MemoryStream())
{
using (Stream firmwareFile = firmwareRomFs.OpenFile("/file"))
using (Stream FirmwareFile = FirmwareRomFs.OpenFile("/file"))
{
firmwareFile.CopyTo(memoryStream);
FirmwareFile.CopyTo(MemoryStream);
}
data = memoryStream.ToArray();
Data = MemoryStream.ToArray();
}
firmwareContent.Dispose();
firmwareStream.Dispose();
FirmwareContent.Dispose();
FirmwareStream.Dispose();
return data;
return Data;
}
}
}

View file

@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
static class NxSettings
{
//Generated automatically from a Switch 3.0 config file (Tid: 0100000000000818).
public static Dictionary<string, object> Settings = new Dictionary<string, object>
public static Dictionary<string, object> Settings = new Dictionary<string, object>()
{
{ "account!na_required_for_network_service", true },
{ "account.daemon!background_awaking_periodicity", 10800 },
@ -1705,7 +1705,7 @@ namespace Ryujinx.HLE.HOS.Services.Set
{ "time!standard_steady_clock_rtc_update_interval_minutes", 5 },
{ "time!standard_network_clock_sufficient_accuracy_minutes", 43200 },
{ "usb!usb30_force_enabled", false },
{ "wlan_debug!skip_wlan_boot", false }
{ "wlan_debug!skip_wlan_boot", false },
};
}
}

View file

@ -17,6 +17,6 @@
BadHints,
Protocol,
Overflow,
Max
Max,
}
}

View file

@ -12,13 +12,13 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
{
class IResolver : IpcService
{
private Dictionary<int, ServiceProcessRequest> _commands;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IResolver()
{
_commands = new Dictionary<int, ServiceProcessRequest>
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, SetDnsAddressesPrivate },
{ 1, GetDnsAddressesPrivate },
@ -28,65 +28,65 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
{ 5, GetGaiStringError },
{ 8, RequestCancelHandle },
{ 9, CancelSocketCall },
{ 11, ClearDnsAddresses }
{ 11, ClearDnsAddresses },
};
}
private long SerializeHostEnt(ServiceCtx context, IPHostEntry hostEntry, List<IPAddress> addresses = null)
private long SerializeHostEnt(ServiceCtx Context, IPHostEntry HostEntry, List<IPAddress> Addresses = null)
{
long originalBufferPosition = context.Request.ReceiveBuff[0].Position;
long bufferPosition = originalBufferPosition;
long bufferSize = context.Request.ReceiveBuff[0].Size;
long OriginalBufferPosition = Context.Request.ReceiveBuff[0].Position;
long BufferPosition = OriginalBufferPosition;
long BufferSize = Context.Request.ReceiveBuff[0].Size;
string hostName = hostEntry.HostName + '\0';
string HostName = HostEntry.HostName + '\0';
// h_name
context.Memory.WriteBytes(bufferPosition, Encoding.ASCII.GetBytes(hostName));
bufferPosition += hostName.Length;
Context.Memory.WriteBytes(BufferPosition, Encoding.ASCII.GetBytes(HostName));
BufferPosition += HostName.Length;
// h_aliases list size
context.Memory.WriteInt32(bufferPosition, IPAddress.HostToNetworkOrder(hostEntry.Aliases.Length));
bufferPosition += 4;
Context.Memory.WriteInt32(BufferPosition, IPAddress.HostToNetworkOrder(HostEntry.Aliases.Length));
BufferPosition += 4;
// Actual aliases
foreach (string alias in hostEntry.Aliases)
foreach (string Alias in HostEntry.Aliases)
{
context.Memory.WriteBytes(bufferPosition, Encoding.ASCII.GetBytes(alias + '\0'));
bufferPosition += alias.Length + 1;
Context.Memory.WriteBytes(BufferPosition, Encoding.ASCII.GetBytes(Alias + '\0'));
BufferPosition += Alias.Length + 1;
}
// h_addrtype but it's a short (also only support IPv4)
context.Memory.WriteInt16(bufferPosition, IPAddress.HostToNetworkOrder((short)2));
bufferPosition += 2;
Context.Memory.WriteInt16(BufferPosition, IPAddress.HostToNetworkOrder((short)2));
BufferPosition += 2;
// h_length but it's a short
context.Memory.WriteInt16(bufferPosition, IPAddress.HostToNetworkOrder((short)4));
bufferPosition += 2;
Context.Memory.WriteInt16(BufferPosition, IPAddress.HostToNetworkOrder((short)4));
BufferPosition += 2;
// Ip address count, we can only support ipv4 (blame Nintendo)
context.Memory.WriteInt32(bufferPosition, addresses != null ? IPAddress.HostToNetworkOrder(addresses.Count) : 0);
bufferPosition += 4;
Context.Memory.WriteInt32(BufferPosition, Addresses != null ? IPAddress.HostToNetworkOrder(Addresses.Count) : 0);
BufferPosition += 4;
if (addresses != null)
if (Addresses != null)
{
foreach (IPAddress ip in addresses)
foreach (IPAddress Ip in Addresses)
{
context.Memory.WriteInt32(bufferPosition, IPAddress.HostToNetworkOrder(BitConverter.ToInt32(ip.GetAddressBytes(), 0)));
bufferPosition += 4;
Context.Memory.WriteInt32(BufferPosition, IPAddress.HostToNetworkOrder(BitConverter.ToInt32(Ip.GetAddressBytes(), 0)));
BufferPosition += 4;
}
}
return bufferPosition - originalBufferPosition;
return BufferPosition - OriginalBufferPosition;
}
private string GetGaiStringErrorFromErrorCode(GaiError errorCode)
private string GetGaiStringErrorFromErrorCode(GaiError ErrorCode)
{
if (errorCode > GaiError.Max)
if (ErrorCode > GaiError.Max)
{
errorCode = GaiError.Max;
ErrorCode = GaiError.Max;
}
switch (errorCode)
switch (ErrorCode)
{
case GaiError.AddressFamily:
return "Address family for hostname not supported";
@ -123,275 +123,275 @@ namespace Ryujinx.HLE.HOS.Services.Sfdnsres
}
}
private string GetHostStringErrorFromErrorCode(NetDbError errorCode)
private string GetHostStringErrorFromErrorCode(NetDBError ErrorCode)
{
if (errorCode <= NetDbError.Internal)
if (ErrorCode <= NetDBError.Internal)
{
return "Resolver internal error";
}
switch (errorCode)
switch (ErrorCode)
{
case NetDbError.Success:
case NetDBError.Success:
return "Resolver Error 0 (no error)";
case NetDbError.HostNotFound:
case NetDBError.HostNotFound:
return "Unknown host";
case NetDbError.TryAgain:
case NetDBError.TryAgain:
return "Host name lookup failure";
case NetDbError.NoRecovery:
case NetDBError.NoRecovery:
return "Unknown server error";
case NetDbError.NoData:
case NetDBError.NoData:
return "No address associated with name";
default:
return "Unknown resolver error";
}
}
private List<IPAddress> GetIpv4Addresses(IPHostEntry hostEntry)
private List<IPAddress> GetIPV4Addresses(IPHostEntry HostEntry)
{
List<IPAddress> result = new List<IPAddress>();
foreach (IPAddress ip in hostEntry.AddressList)
List<IPAddress> Result = new List<IPAddress>();
foreach (IPAddress Ip in HostEntry.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
result.Add(ip);
if (Ip.AddressFamily == AddressFamily.InterNetwork)
Result.Add(Ip);
}
return result;
return Result;
}
// SetDnsAddressesPrivate(u32, buffer<unknown, 5, 0>)
public long SetDnsAddressesPrivate(ServiceCtx context)
public long SetDnsAddressesPrivate(ServiceCtx Context)
{
uint unknown0 = context.RequestData.ReadUInt32();
long bufferPosition = context.Request.SendBuff[0].Position;
long bufferSize = context.Request.SendBuff[0].Size;
uint Unknown0 = Context.RequestData.ReadUInt32();
long BufferPosition = Context.Request.SendBuff[0].Position;
long BufferSize = Context.Request.SendBuff[0].Size;
// TODO: This is stubbed in 2.0.0+, reverse 1.0.0 version for the sake completeness.
Logger.PrintStub(LogClass.ServiceSfdnsres, $"Stubbed. Unknown0: {unknown0}");
Logger.PrintStub(LogClass.ServiceSfdnsres, $"Stubbed. Unknown0: {Unknown0}");
return MakeError(ErrorModule.Os, 1023);
}
// GetDnsAddressPrivate(u32) -> buffer<unknown, 6, 0>
public long GetDnsAddressesPrivate(ServiceCtx context)
public long GetDnsAddressesPrivate(ServiceCtx Context)
{
uint unknown0 = context.RequestData.ReadUInt32();
uint Unknown0 = Context.RequestData.ReadUInt32();
// TODO: This is stubbed in 2.0.0+, reverse 1.0.0 version for the sake completeness.
Logger.PrintStub(LogClass.ServiceSfdnsres, $"Stubbed. Unknown0: {unknown0}");
Logger.PrintStub(LogClass.ServiceSfdnsres, $"Stubbed. Unknown0: {Unknown0}");
return MakeError(ErrorModule.Os, 1023);
}
// GetHostByName(u8, u32, u64, pid, buffer<unknown, 5, 0>) -> (u32, u32, u32, buffer<unknown, 6, 0>)
public long GetHostByName(ServiceCtx context)
public long GetHostByName(ServiceCtx Context)
{
byte[] rawName = context.Memory.ReadBytes(context.Request.SendBuff[0].Position, context.Request.SendBuff[0].Size);
string name = Encoding.ASCII.GetString(rawName).TrimEnd('\0');
byte[] RawName = Context.Memory.ReadBytes(Context.Request.SendBuff[0].Position, Context.Request.SendBuff[0].Size);
string Name = Encoding.ASCII.GetString(RawName).TrimEnd('\0');
// TODO: use params
bool enableNsdResolve = context.RequestData.ReadInt32() == 1;
int timeOut = context.RequestData.ReadInt32();
ulong pidPlaceholder = context.RequestData.ReadUInt64();
bool EnableNsdResolve = Context.RequestData.ReadInt32() == 1;
int TimeOut = Context.RequestData.ReadInt32();
ulong PidPlaceholder = Context.RequestData.ReadUInt64();
IPHostEntry hostEntry = null;
IPHostEntry HostEntry = null;
NetDbError netDbErrorCode = NetDbError.Success;
GaiError errno = GaiError.Overflow;
long serializedSize = 0;
NetDBError NetDBErrorCode = NetDBError.Success;
GaiError Errno = GaiError.Overflow;
long SerializedSize = 0;
if (name.Length <= 255)
if (Name.Length <= 255)
{
try
{
hostEntry = Dns.GetHostEntry(name);
HostEntry = Dns.GetHostEntry(Name);
}
catch (SocketException exception)
catch (SocketException Exception)
{
netDbErrorCode = NetDbError.Internal;
NetDBErrorCode = NetDBError.Internal;
if (exception.ErrorCode == 11001)
if (Exception.ErrorCode == 11001)
{
netDbErrorCode = NetDbError.HostNotFound;
errno = GaiError.NoData;
NetDBErrorCode = NetDBError.HostNotFound;
Errno = GaiError.NoData;
}
else if (exception.ErrorCode == 11002)
else if (Exception.ErrorCode == 11002)
{
netDbErrorCode = NetDbError.TryAgain;
NetDBErrorCode = NetDBError.TryAgain;
}
else if (exception.ErrorCode == 11003)
else if (Exception.ErrorCode == 11003)
{
netDbErrorCode = NetDbError.NoRecovery;
NetDBErrorCode = NetDBError.NoRecovery;
}
else if (exception.ErrorCode == 11004)
else if (Exception.ErrorCode == 11004)
{
netDbErrorCode = NetDbError.NoData;
NetDBErrorCode = NetDBError.NoData;
}
else if (exception.ErrorCode == 10060)
else if (Exception.ErrorCode == 10060)
{
errno = GaiError.Again;
Errno = GaiError.Again;
}
}
}
else
{
netDbErrorCode = NetDbError.HostNotFound;
NetDBErrorCode = NetDBError.HostNotFound;
}
if (hostEntry != null)
if (HostEntry != null)
{
errno = GaiError.Success;
Errno = GaiError.Success;
List<IPAddress> addresses = GetIpv4Addresses(hostEntry);
List<IPAddress> Addresses = GetIPV4Addresses(HostEntry);
if (addresses.Count == 0)
if (Addresses.Count == 0)
{
errno = GaiError.NoData;
netDbErrorCode = NetDbError.NoAddress;
Errno = GaiError.NoData;
NetDBErrorCode = NetDBError.NoAddress;
}
else
{
serializedSize = SerializeHostEnt(context, hostEntry, addresses);
SerializedSize = SerializeHostEnt(Context, HostEntry, Addresses);
}
}
context.ResponseData.Write((int)netDbErrorCode);
context.ResponseData.Write((int)errno);
context.ResponseData.Write(serializedSize);
Context.ResponseData.Write((int)NetDBErrorCode);
Context.ResponseData.Write((int)Errno);
Context.ResponseData.Write(SerializedSize);
return 0;
}
// GetHostByAddr(u32, u32, u32, u64, pid, buffer<unknown, 5, 0>) -> (u32, u32, u32, buffer<unknown, 6, 0>)
public long GetHostByAddress(ServiceCtx context)
public long GetHostByAddress(ServiceCtx Context)
{
byte[] rawIp = context.Memory.ReadBytes(context.Request.SendBuff[0].Position, context.Request.SendBuff[0].Size);
byte[] RawIp = Context.Memory.ReadBytes(Context.Request.SendBuff[0].Position, Context.Request.SendBuff[0].Size);
// TODO: use params
uint socketLength = context.RequestData.ReadUInt32();
uint type = context.RequestData.ReadUInt32();
int timeOut = context.RequestData.ReadInt32();
ulong pidPlaceholder = context.RequestData.ReadUInt64();
uint SocketLength = Context.RequestData.ReadUInt32();
uint Type = Context.RequestData.ReadUInt32();
int TimeOut = Context.RequestData.ReadInt32();
ulong PidPlaceholder = Context.RequestData.ReadUInt64();
IPHostEntry hostEntry = null;
IPHostEntry HostEntry = null;
NetDbError netDbErrorCode = NetDbError.Success;
GaiError errno = GaiError.AddressFamily;
long serializedSize = 0;
NetDBError NetDBErrorCode = NetDBError.Success;
GaiError Errno = GaiError.AddressFamily;
long SerializedSize = 0;
if (rawIp.Length == 4)
if (RawIp.Length == 4)
{
try
{
IPAddress address = new IPAddress(rawIp);
IPAddress Address = new IPAddress(RawIp);
hostEntry = Dns.GetHostEntry(address);
HostEntry = Dns.GetHostEntry(Address);
}
catch (SocketException exception)
catch (SocketException Exception)
{
netDbErrorCode = NetDbError.Internal;
if (exception.ErrorCode == 11001)
NetDBErrorCode = NetDBError.Internal;
if (Exception.ErrorCode == 11001)
{
netDbErrorCode = NetDbError.HostNotFound;
errno = GaiError.NoData;
NetDBErrorCode = NetDBError.HostNotFound;
Errno = GaiError.NoData;
}
else if (exception.ErrorCode == 11002)
else if (Exception.ErrorCode == 11002)
{
netDbErrorCode = NetDbError.TryAgain;
NetDBErrorCode = NetDBError.TryAgain;
}
else if (exception.ErrorCode == 11003)
else if (Exception.ErrorCode == 11003)
{
netDbErrorCode = NetDbError.NoRecovery;
NetDBErrorCode = NetDBError.NoRecovery;
}
else if (exception.ErrorCode == 11004)
else if (Exception.ErrorCode == 11004)
{
netDbErrorCode = NetDbError.NoData;
NetDBErrorCode = NetDBError.NoData;
}
else if (exception.ErrorCode == 10060)
else if (Exception.ErrorCode == 10060)
{
errno = GaiError.Again;
Errno = GaiError.Again;
}
}
}
else
{
netDbErrorCode = NetDbError.NoAddress;
NetDBErrorCode = NetDBError.NoAddress;
}
if (hostEntry != null)
if (HostEntry != null)
{
errno = GaiError.Success;
serializedSize = SerializeHostEnt(context, hostEntry, GetIpv4Addresses(hostEntry));
Errno = GaiError.Success;
SerializedSize = SerializeHostEnt(Context, HostEntry, GetIPV4Addresses(HostEntry));
}
context.ResponseData.Write((int)netDbErrorCode);
context.ResponseData.Write((int)errno);
context.ResponseData.Write(serializedSize);
Context.ResponseData.Write((int)NetDBErrorCode);
Context.ResponseData.Write((int)Errno);
Context.ResponseData.Write(SerializedSize);
return 0;
}
// GetHostStringError(u32) -> buffer<unknown, 6, 0>
public long GetHostStringError(ServiceCtx context)
public long GetHostStringError(ServiceCtx Context)
{
long resultCode = MakeError(ErrorModule.Os, 1023);
NetDbError errorCode = (NetDbError)context.RequestData.ReadInt32();
string errorString = GetHostStringErrorFromErrorCode(errorCode);
long ResultCode = MakeError(ErrorModule.Os, 1023);
NetDBError ErrorCode = (NetDBError)Context.RequestData.ReadInt32();
string ErrorString = GetHostStringErrorFromErrorCode(ErrorCode);
if (errorString.Length + 1 <= context.Request.ReceiveBuff[0].Size)
if (ErrorString.Length + 1 <= Context.Request.ReceiveBuff[0].Size)
{
resultCode = 0;
context.Memory.WriteBytes(context.Request.ReceiveBuff[0].Position, Encoding.ASCII.GetBytes(errorString + '\0'));
ResultCode = 0;
Context.Memory.WriteBytes(Context.Request.ReceiveBuff[0].Position, Encoding.ASCII.GetBytes(ErrorString + '\0'));
}
return resultCode;
return ResultCode;
}
// GetGaiStringError(u32) -> buffer<unknown, 6, 0>
public long GetGaiStringError(ServiceCtx context)
public long GetGaiStringError(ServiceCtx Context)
{
long resultCode = MakeError(ErrorModule.Os, 1023);
GaiError errorCode = (GaiError)context.RequestData.ReadInt32();
string errorString = GetGaiStringErrorFromErrorCode(errorCode);
long ResultCode = MakeError(ErrorModule.Os, 1023);
GaiError ErrorCode = (GaiError)Context.RequestData.ReadInt32();
string ErrorString = GetGaiStringErrorFromErrorCode(ErrorCode);
if (errorString.Length + 1 <= context.Request.ReceiveBuff[0].Size)
if (ErrorString.Length + 1 <= Context.Request.ReceiveBuff[0].Size)
{
resultCode = 0;
context.Memory.WriteBytes(context.Request.ReceiveBuff[0].Position, Encoding.ASCII.GetBytes(errorString + '\0'));
ResultCode = 0;
Context.Memory.WriteBytes(Context.Request.ReceiveBuff[0].Position, Encoding.ASCII.GetBytes(ErrorString + '\0'));
}
return resultCode;
return ResultCode;
}
// RequestCancelHandle(u64, pid) -> u32
public long RequestCancelHandle(ServiceCtx context)
public long RequestCancelHandle(ServiceCtx Context)
{
ulong unknown0 = context.RequestData.ReadUInt64();
ulong Unknown0 = Context.RequestData.ReadUInt64();
context.ResponseData.Write(0);
Context.ResponseData.Write(0);
Logger.PrintStub(LogClass.ServiceSfdnsres, $"Stubbed. Unknown0: {unknown0}");
Logger.PrintStub(LogClass.ServiceSfdnsres, $"Stubbed. Unknown0: {Unknown0}");
return 0;
}
// CancelSocketCall(u32, u64, pid)
public long CancelSocketCall(ServiceCtx context)
public long CancelSocketCall(ServiceCtx Context)
{
uint unknown0 = context.RequestData.ReadUInt32();
ulong unknown1 = context.RequestData.ReadUInt64();
uint Unknown0 = Context.RequestData.ReadUInt32();
ulong Unknown1 = Context.RequestData.ReadUInt64();
Logger.PrintStub(LogClass.ServiceSfdnsres, $"Stubbed. Unknown0: {unknown0} - " +
$"Unknown1: {unknown1}");
Logger.PrintStub(LogClass.ServiceSfdnsres, $"Stubbed. Unknown0: {Unknown0} - " +
$"Unknown1: {Unknown1}");
return 0;
}
// ClearDnsAddresses(u32)
public long ClearDnsAddresses(ServiceCtx context)
public long ClearDnsAddresses(ServiceCtx Context)
{
uint unknown0 = context.RequestData.ReadUInt32();
uint Unknown0 = Context.RequestData.ReadUInt32();
Logger.PrintStub(LogClass.ServiceSfdnsres, $"Stubbed. Unknown0: {unknown0}");
Logger.PrintStub(LogClass.ServiceSfdnsres, $"Stubbed. Unknown0: {Unknown0}");
return 0;
}

Some files were not shown because too many files have changed in this diff Show more