Adjust naming conventions and general refactoring in HLE Project (#527)

* Rename enum fields

* Naming conventions

* Remove unneeded ".this"

* Remove unneeded semicolons

* Remove unused Usings

* Don't use var

* Remove unneeded enum underlying types

* Explicitly label class visibility

* Remove unneeded @ prefixes

* Remove unneeded commas

* Remove unneeded if expressions

* Method doesn't use unsafe code

* Remove unneeded casts

* Initialized objects don't need an empty constructor

* Remove settings from DotSettings

* Revert "Explicitly label class visibility"

This reverts commit ad5eb5787cc5b27a4631cd46ef5f551c4ae95e51.

* Small changes

* Revert external enum renaming

* Changes from feedback

* Apply previous refactorings to the merged code
This commit is contained in:
Alex Barney 2018-12-06 05:16:24 -06:00 committed by gdkchan
parent 3615a70cae
commit fb1d9493a3
298 changed files with 12034 additions and 12037 deletions

View file

@ -10,13 +10,13 @@ namespace Ryujinx.HLE.HOS.Services.Acc
{
class IAccountService : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAccountService()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IManagerForApplication(UInt128 Uuid)
public IManagerForApplication(UInt128 uuid)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, CheckAvailability },
{ 1, GetAccountId }
};
this.Uuid = Uuid;
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private UserProfile Profile;
private UserProfile _profile;
private Stream ProfilePictureStream;
private Stream _profilePictureStream;
public IProfile(UserProfile Profile)
public IProfile(UserProfile profile)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Get },
{ 1, GetBase },
{ 10, GetImageSize },
{ 11, LoadImage },
{ 11, LoadImage }
};
this.Profile = Profile;
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAllSystemAppletProxiesService()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IApplicationCreator()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
//...
};

View file

@ -6,13 +6,13 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IApplicationFunctions : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IApplicationFunctions()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IApplicationProxy()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IApplicationProxyService()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAudioController()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent DisplayResolutionChangeEvent;
private KEvent _displayResolutionChangeEvent;
public ICommonStateGetter(Horizon System)
public ICommonStateGetter(Horizon system)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IDebugFunctions()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
//...
};

View file

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

View file

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

View file

@ -8,39 +8,39 @@ namespace Ryujinx.HLE.HOS.Services.Am
{
class IHomeMenuFunctions : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent ChannelEvent;
private KEvent _channelEvent;
public IHomeMenuFunctions(Horizon System)
public IHomeMenuFunctions(Horizon system)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent StateChangedEvent;
private KEvent _stateChangedEvent;
public ILibraryAppletAccessor(Horizon System)
public ILibraryAppletAccessor(Horizon system)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ILibraryAppletCreator()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent LaunchableEvent;
private KEvent _launchableEvent;
private int IdleTimeDetectionExtension;
private int _idleTimeDetectionExtension;
public ISelfController(Horizon System)
public ISelfController(Horizon system)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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 ? true : false;
bool enable = context.RequestData.ReadByte() != 0;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetOperationModeChangedNotification(ServiceCtx Context)
public long SetOperationModeChangedNotification(ServiceCtx context)
{
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
bool enable = context.RequestData.ReadByte() != 0;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetPerformanceModeChangedNotification(ServiceCtx Context)
public long SetPerformanceModeChangedNotification(ServiceCtx context)
{
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
bool enable = context.RequestData.ReadByte() != 0;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetFocusHandlingMode(ServiceCtx Context)
public long SetFocusHandlingMode(ServiceCtx context)
{
bool Flag1 = Context.RequestData.ReadByte() != 0 ? true : false;
bool Flag2 = Context.RequestData.ReadByte() != 0 ? true : false;
bool Flag3 = Context.RequestData.ReadByte() != 0 ? true : false;
bool flag1 = context.RequestData.ReadByte() != 0;
bool flag2 = context.RequestData.ReadByte() != 0;
bool flag3 = context.RequestData.ReadByte() != 0;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetRestartMessageEnabled(ServiceCtx Context)
public long SetRestartMessageEnabled(ServiceCtx context)
{
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
bool enable = context.RequestData.ReadByte() != 0;
Logger.PrintStub(LogClass.ServiceAm, "Stubbed.");
return 0;
}
public long SetOutOfFocusSuspendingEnabled(ServiceCtx Context)
public long SetOutOfFocusSuspendingEnabled(ServiceCtx context)
{
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
bool enable = context.RequestData.ReadByte() != 0;
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 ? true : false;
bool enable = context.RequestData.ReadByte() != 0;
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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public byte[] Data { get; private set; }
public IStorage(byte[] Data)
public IStorage(byte[] data)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Open }
};
this.Data = Data;
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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private IStorage Storage;
private IStorage _storage;
public IStorageAccessor(IStorage Storage)
public IStorageAccessor(IStorage storage)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetSize },
{ 10, Write },
{ 11, Read }
};
this.Storage = Storage;
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISystemAppletProxy()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IWindowController()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IManager()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISession()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _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)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetAudioOutState },
{ 1, StartAudioOut },
@ -34,116 +34,116 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
{ 8, GetReleasedAudioOutBufferAuto }
};
this.AudioOut = AudioOut;
this.ReleaseEvent = ReleaseEvent;
this.Track = Track;
_audioOut = audioOut;
_releaseEvent = releaseEvent;
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _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)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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);
this.Memory = Memory;
this.AudioOut = AudioOut;
this.Params = Params;
_memory = memory;
_audioOut = audioOut;
_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 unsafe void AppendMixedBuffer(long Tag)
private 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 unsafe static 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 : int
enum MemoryPoolState
{
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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent SystemEvent;
private KEvent _systemEvent;
public IAudioDevice(Horizon System)
public IAudioDevice(Horizon system)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAudioOutManager()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAudioRendererManager()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _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)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, DecodeInterleaved },
{ 4, DecodeInterleavedWithPerf }
};
this.SampleRate = SampleRate;
this.ChannelsCount = ChannelsCount;
_sampleRate = sampleRate;
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IHardwareOpusDecoderManager()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IBcatService()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
//...
};

View file

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

View file

@ -5,33 +5,33 @@ namespace Ryujinx.HLE.HOS.Services.Bcat
{
class IServiceCreator : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IServiceCreator()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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,7 +9,7 @@
Output = 4,
Error = 8,
Disconnected = 0x10,
Invalid = 0x20,
Invalid = 0x20
}
public int SocketFd { get; private set; }
@ -17,12 +17,12 @@
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)
{
this.SocketFd = SocketFd;
this.Socket = Socket;
this.InputEvents = InputEvents;
this.OutputEvents = OutputEvents;
SocketFd = socketFd;
Socket = socket;
InputEvents = inputEvents;
OutputEvents = outputEvents;
}
}
}

View file

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

View file

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

View file

@ -1,20 +1,19 @@
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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private bool IsInitialized;
private bool _isInitialized;
public IETicketService()
public IeTicketService()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
};

View file

@ -8,13 +8,13 @@ namespace Ryujinx.HLE.HOS.Services.Friend
{
class IFriendService : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IFriendService()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IServiceCreator()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Ryujinx.HLE.HOS.Services.FspSrv
namespace Ryujinx.HLE.HOS.Services.FspSrv
{
public struct DirectoryEntry
{
@ -11,11 +7,11 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
public DirectoryEntryType EntryType { get; set; }
public DirectoryEntry(string Path, DirectoryEntryType DirectoryEntryType, long Size = 0)
public DirectoryEntry(string path, DirectoryEntryType directoryEntryType, long size = 0)
{
this.Path = Path;
EntryType = DirectoryEntryType;
this.Size = Size;
Path = path;
EntryType = directoryEntryType;
Size = size;
}
}
}

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.FspSrv
{
enum FileSystemType : int
enum FileSystemType
{
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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private List<DirectoryEntry> DirectoryEntries;
private List<DirectoryEntry> _directoryEntries;
private int CurrentItemIndex;
private int _currentItemIndex;
public event EventHandler<EventArgs> Disposed;
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)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Read },
{ 1, GetEntryCount }
};
this.Provider = Provider;
this.DirectoryPath = DirectoryPath;
_provider = provider;
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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private Stream BaseStream;
private Stream _baseStream;
public event EventHandler<EventArgs> Disposed;
public string HostPath { get; private set; }
public IFile(Stream BaseStream, string HostPath)
public IFile(Stream baseStream, string hostPath)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Read },
{ 1, Write },
@ -28,71 +28,71 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{ 4, GetSize }
};
this.BaseStream = BaseStream;
this.HostPath = HostPath;
_baseStream = baseStream;
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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _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)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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>();
this.Path = Path;
this.Provider = Provider;
_path = path;
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IFileSystemProxy()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private Stream BaseStream;
private Stream _baseStream;
public IStorage(Stream BaseStream)
public IStorage(Stream baseStream)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, Read }
};
this.BaseStream = BaseStream;
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IActiveApplicationDeviceList()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KSharedMemory HidSharedMem;
private KSharedMemory _hidSharedMem;
public IAppletResource(KSharedMemory HidSharedMem)
public IAppletResource(KSharedMemory hidSharedMem)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetSharedMemoryHandle }
};
this.HidSharedMem = HidSharedMem;
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private bool Activated;
private bool _activated;
public IIrSensorServer()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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,7 +4,6 @@ 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;
@ -55,11 +54,11 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
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)
{
this.NrrAddress = NrrAddress;
this.Header = Header;
this.Hashes = Hashes;
NrrAddress = nrrAddress;
Header = header;
Hashes = hashes;
}
}
@ -76,29 +75,29 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
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)
{
this.Executable = Executable;
this.Hash = Hash;
this.NroAddress = NroAddress;
this.NroSize = NroSize;
this.BssAddress = BssAddress;
this.BssSize = BssSize;
this.TotalSize = TotalSize;
Executable = executable;
Hash = hash;
NroAddress = nroAddress;
NroSize = nroSize;
BssAddress = bssAddress;
BssSize = bssSize;
TotalSize = totalSize;
}
}
class IRoInterface : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private const int MaxNrr = 0x40;
private const int MaxNro = 0x40;
@ -106,70 +105,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()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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;
}
@ -179,11 +178,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;
}
@ -192,206 +191,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;
}
@ -400,46 +399,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;
}
}
@ -447,125 +446,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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ILogService()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ILogger()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private StorageId StorageId;
private StorageId _storageId;
public ILocationResolver(StorageId StorageId)
public ILocationResolver(StorageId storageId)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, ResolveProgramPath },
{ 1, RedirectProgramPath },
@ -40,103 +40,103 @@ namespace Ryujinx.HLE.HOS.Services.Lr
{ 15, DeleteInfoHtmlNcaPath }
};
this.StorageId = StorageId;
_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,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.FileSystem;
@ -7,24 +6,24 @@ namespace Ryujinx.HLE.HOS.Services.Lr
{
class ILocationResolverManager : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ILocationResolverManager()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IRequest()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IContentManager()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
};

View file

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

View file

@ -9,25 +9,25 @@ namespace Ryujinx.HLE.HOS.Services.Nfp
{
class IUser : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private const HidControllerId NpadId = HidControllerId.CONTROLLER_PLAYER_1;
private const HidControllerId NpadId = HidControllerId.ControllerPlayer1;
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)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IUserManager()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IGeneralService()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent Event0;
private KEvent Event1;
private KEvent _event0;
private KEvent _event1;
public IRequest(Horizon System)
public IRequest(Horizon system)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IStaticService()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IAddOnContentManager()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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,20 +1,19 @@
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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private bool IsInitialized;
private bool _isInitialized;
public IApplicationManagerInterface()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
};

View file

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

View file

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

View file

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

View file

@ -14,13 +14,13 @@ 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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private static Dictionary<string, IoctlProcessor> IoctlProcessors =
private static Dictionary<string, IoctlProcessor> _ioctlProcessors =
new Dictionary<string, IoctlProcessor>()
{
{ "/dev/nvhost-as-gpu", ProcessIoctlNvGpuAS },
@ -34,11 +34,11 @@ namespace Ryujinx.HLE.HOS.Services.Nv
public static GlobalStateTable Fds { get; private set; }
private KEvent Event;
private KEvent _event;
public INvDrvServices(Horizon System)
public INvDrvServices(Horizon system)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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

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

View file

@ -12,10 +12,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvGpuAS
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;
}
}
@ -25,53 +25,53 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvGpuAS
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)
{
this.PhysicalAddress = PhysicalAddress;
this.VaAllocated = VaAllocated;
PhysicalAddress = physicalAddress;
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,62 +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 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);
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.
@ -74,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;
}
}
}
@ -174,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

@ -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()
{
this.Size = Size;
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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _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)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 1, Initialize }
};
this.NeedInitialize = NeedInitialize;
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IParentalControlServiceFactory()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISharedFontManager()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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, (SharedFontType)Type, Offset))
if (!AddFontToOrderOfPriorityList(context, 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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IPrepoService()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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 : int
enum ChargerType
{
None,
ChargerOrDock,
UsbC
}
private Dictionary<int, ServiceProcessRequest> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IPsmServer()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent StateChangeEvent;
private int StateChangeEventHandle;
private KEvent _stateChangeEvent;
private int _stateChangeEventHandle;
public IPsmSession(Horizon System)
public IPsmSession(Horizon system)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISettingsServer()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public ISystemSettingsServer()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
public IResolver()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_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;
}

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Sfdnsres
{
enum NetDBError
enum NetDbError
{
Internal = -1,
Success,
@ -8,6 +8,6 @@
TryAgain,
NoRecovery,
NoData,
NoAddress = NoData,
NoAddress = NoData
}
}

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