From ed2b396131454300f9dc17ad77d9139c18e2211b Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Wed, 19 Nov 2025 00:32:38 -0600 Subject: [PATCH] Enable full trimming Enables full trimming for Ryujinx, and in doing so removes many usages of reflection, namely: IUserService no longer uses reflection to find possible service types, and now has a generated switch based on name Ryujinx.HLE.HOS.Tamper no longer uses dynamic to do operations, now using INumber and friends Cmif and Tipc commands in Ryujinx.HLE.HOS.Services no longer get resolved via reflection and are now done via generated virtual methods Fix things broken by trimming (profile panel, DiscordRPC) --- .gitignore | 3 + Directory.Build.targets | 6 + Directory.Packages.props | 3 +- .../Ryujinx.BuildValidationTasks.csproj | 4 +- .../Formatters/DynamicObjectFormatter.cs | 2 + .../IpcCommandGenerator.cs | 173 ++++++++++++++++++ .../IpcServiceGenerator.cs | 78 -------- .../Ryujinx.HLE.Generators.csproj | 6 +- .../ServiceSyntaxReceiver.cs | 24 --- .../UserServiceGenerator.cs | 93 ++++++++++ .../ServiceNotImplementedException.cs | 55 ++---- .../AccountService/IManagerForApplication.cs | 2 +- .../IManagerForSystemService.cs | 2 +- .../Account/Acc/AccountService/IProfile.cs | 2 +- .../Acc/AccountService/IProfileEditor.cs | 2 +- .../Acc/IAccountServiceForAdministrator.cs | 2 +- .../Acc/IAccountServiceForApplication.cs | 2 +- .../Acc/IAccountServiceForSystemService.cs | 2 +- .../HOS/Services/Account/Acc/IAsyncContext.cs | 2 +- .../IAsyncNetworkServiceLicenseKindContext.cs | 2 +- .../Account/Acc/IBaasAccessTokenAccessor.cs | 2 +- .../ILibraryAppletProxy.cs | 2 +- .../ISystemAppletProxy.cs | 2 +- .../ILibraryAppletAccessor.cs | 2 +- .../ILibraryAppletSelfAccessor.cs | 2 +- .../IProcessWindingController.cs | 2 +- .../SystemAppletProxy/IAudioController.cs | 2 +- .../SystemAppletProxy/ICommonStateGetter.cs | 2 +- .../SystemAppletProxy/IDisplayController.cs | 2 +- .../SystemAppletProxy/IHomeMenuFunctions.cs | 2 +- .../ILibraryAppletCreator.cs | 2 +- .../SystemAppletProxy/ISelfController.cs | 2 +- .../SystemAppletProxy/IWindowController.cs | 2 +- .../IAllSystemAppletProxiesService.cs | 2 +- .../HOS/Services/Am/AppletAE/IStorage.cs | 2 +- .../Services/Am/AppletAE/IStorageAccessor.cs | 2 +- .../ApplicationProxy/IApplicationFunctions.cs | 2 +- .../IApplicationProxy.cs | 2 +- .../Am/AppletOE/IApplicationProxyService.cs | 2 +- src/Ryujinx.HLE/HOS/Services/Apm/IManager.cs | 2 +- .../HOS/Services/Apm/IManagerPrivileged.cs | 2 +- src/Ryujinx.HLE/HOS/Services/Apm/ISession.cs | 2 +- .../HOS/Services/Apm/ISystemManager.cs | 2 +- .../Services/Bluetooth/IBluetoothDriver.cs | 2 +- .../HOS/Services/Bluetooth/IBluetoothUser.cs | 2 +- .../BluetoothManager/BtmUser/IBtmUserCore.cs | 2 +- .../HOS/Services/BluetoothManager/IBtmUser.cs | 2 +- .../Services/Caps/IAlbumApplicationService.cs | 2 +- .../HOS/Services/Caps/IAlbumControlService.cs | 2 +- .../Caps/IScreenShotApplicationService.cs | 2 +- .../HOS/Services/Ectx/IContextRegistrar.cs | 2 +- .../Services/Ectx/IWriterForApplication.cs | 2 +- .../HOS/Services/Fatal/IService.cs | 2 +- .../Services/Fs/FileSystemProxy/IDirectory.cs | 2 +- .../HOS/Services/Fs/FileSystemProxy/IFile.cs | 2 +- .../Fs/FileSystemProxy/IFileSystem.cs | 2 +- .../Services/Fs/FileSystemProxy/IStorage.cs | 2 +- .../HOS/Services/Fs/IDeviceOperator.cs | 2 +- .../HOS/Services/Fs/IFileSystemProxy.cs | 2 +- .../HOS/Services/Fs/IMultiCommitManager.cs | 2 +- .../HOS/Services/Fs/ISaveDataInfoReader.cs | 2 +- .../HidServer/IActiveVibrationDeviceList.cs | 2 +- .../Services/Hid/HidServer/IAppletResource.cs | 2 +- .../HOS/Services/Hid/IHidServer.cs | 2 +- .../HOS/Services/Hid/IHidSystemServer.cs | 2 +- .../HOS/Services/Hid/IHidbusServer.cs | 2 +- .../HOS/Services/Hid/Irs/IIrSensorServer.cs | 2 +- src/Ryujinx.HLE/HOS/Services/IpcService.cs | 172 ++++++----------- .../HOS/Services/Ldn/IUserServiceCreator.cs | 2 +- .../HOS/Services/Ldn/Lp2p/IServiceCreator.cs | 2 +- .../HOS/Services/Ldn/Lp2p/ISfService.cs | 2 +- .../Services/Ldn/Lp2p/ISfServiceMonitor.cs | 2 +- .../IClientProcessMonitor.cs | 2 +- .../IUserLocalCommunicationService.cs | 2 +- .../HOS/Services/Mii/IImageDatabaseService.cs | 2 +- .../HOS/Services/Mii/IStaticService.cs | 2 +- .../Mii/StaticService/IDatabaseService.cs | 2 +- .../Services/Mnpp/IServiceForApplication.cs | 2 +- .../Ncm/Lr/ILocationResolverManager.cs | 2 +- .../ILocationResolver.cs | 2 +- .../HOS/Services/Nfc/ISystemManager.cs | 2 +- .../HOS/Services/Nfc/IUserManager.cs | 2 +- .../HOS/Services/Nfc/Mifare/IUserManager.cs | 2 +- .../Nfc/Mifare/MifareManager/IMifare.cs | 2 +- .../HOS/Services/Nfc/NfcManager/INfc.cs | 2 +- .../HOS/Services/Nfc/Nfp/IDebugManager.cs | 2 +- .../HOS/Services/Nfc/Nfp/ISystemManager.cs | 2 +- .../HOS/Services/Nfc/Nfp/IUserManager.cs | 2 +- .../HOS/Services/Nfc/Nfp/NfpManager/INfp.cs | 2 +- src/Ryujinx.HLE/HOS/Services/Ngct/IService.cs | 2 +- .../Ngct/IServiceWithManagementApi.cs | 2 +- .../HOS/Services/Nifm/IStaticService.cs | 2 +- .../Nifm/StaticService/IGeneralService.cs | 2 +- .../Services/Nifm/StaticService/IRequest.cs | 2 +- .../Services/Nim/IShopServiceAccessServer.cs | 2 +- .../Nim/IShopServiceAccessServerInterface.cs | 2 +- .../HOS/Services/Nim/IShopServiceAccessor.cs | 2 +- .../HOS/Services/Nim/Ntc/IStaticService.cs | 2 +- .../IEnsureNetworkClockAvailabilityService.cs | 2 +- .../Services/Ns/Aoc/IAddOnContentManager.cs | 2 +- .../Services/Ns/Aoc/IPurchaseEventManager.cs | 2 +- .../Ns/IApplicationManagerInterface.cs | 2 +- ...ReadOnlyApplicationControlDataInterface.cs | 2 +- .../Services/Ns/IServiceGetterInterface.cs | 2 +- .../HOS/Services/Nv/INvDrvServices.cs | 35 ++-- .../Olsc/IOlscServiceForApplication.cs | 2 +- .../Pctl/IParentalControlServiceFactory.cs | 2 +- .../IParentalControlService.cs | 2 +- .../HOS/Services/Pcv/Bpc/IRtcManager.cs | 2 +- .../Clkrst/ClkrstManager/IClkrstSession.cs | 2 +- .../HOS/Services/Pcv/Clkrst/IClkrstManager.cs | 2 +- .../HOS/Services/Pm/IDebugMonitorInterface.cs | 2 +- .../HOS/Services/Pm/IInformationInterface.cs | 2 +- .../HOS/Services/Pm/IShellInterface.cs | 2 +- .../HOS/Services/Ptm/Psm/IPsmServer.cs | 2 +- .../HOS/Services/Ptm/Psm/IPsmSession.cs | 2 +- .../HOS/Services/Ro/IRoInterface.cs | 2 +- .../HOS/Services/Sdb/Pdm/IQueryService.cs | 2 +- .../HOS/Services/Sdb/Pl/ISharedFontManager.cs | 2 +- .../HOS/Services/Settings/ISettingsServer.cs | 2 +- .../Settings/ISystemSettingsServer.cs | 2 +- .../HOS/Services/Sm/IUserInterface.cs | 21 +-- .../HOS/Services/Sockets/Bsd/IClient.cs | 2 +- .../HOS/Services/Sockets/Nsd/IManager.cs | 2 +- .../Services/Sockets/Sfdnsres/IResolver.cs | 2 +- .../HOS/Services/Spl/IGeneralInterface.cs | 2 +- .../HOS/Services/Spl/IRandomInterface.cs | 2 +- .../HOS/Services/Ssl/ISslService.cs | 2 +- .../Services/Ssl/SslService/ISslConnection.cs | 2 +- .../Services/Ssl/SslService/ISslContext.cs | 2 +- .../SurfaceFlinger/IHOSBinderDriver.cs | 2 +- .../Services/Time/IStaticServiceForGlue.cs | 2 +- .../HOS/Services/Time/IStaticServiceForPsc.cs | 2 +- .../HOS/Services/Time/ITimeServiceManager.cs | 2 +- .../Time/StaticService/ISteadyClock.cs | 2 +- .../Time/StaticService/ISystemClock.cs | 2 +- .../StaticService/ITimeZoneServiceForGlue.cs | 2 +- .../StaticService/ITimeZoneServiceForPsc.cs | 2 +- .../Services/Vi/IApplicationRootService.cs | 2 +- .../HOS/Services/Vi/IManagerRootService.cs | 2 +- .../HOS/Services/Vi/ISystemRootService.cs | 2 +- .../IManagerDisplayService.cs | 2 +- .../ISystemDisplayService.cs | 2 +- .../RootService/IApplicationDisplayService.cs | 2 +- .../HOS/Tamper/CodeEmitters/Arithmetic.cs | 37 ++-- .../HOS/Tamper/CodeEmitters/DebugLog.cs | 11 +- .../Tamper/CodeEmitters/LegacyArithmetic.cs | 14 +- .../CodeEmitters/LoadRegisterWithMemory.cs | 3 +- .../CodeEmitters/StoreConstantToAddress.cs | 4 +- .../CodeEmitters/StoreConstantToMemory.cs | 2 +- .../CodeEmitters/StoreRegisterToMemory.cs | 2 +- .../HOS/Tamper/Conditions/CondEQ.cs | 12 +- .../HOS/Tamper/Conditions/CondGE.cs | 12 +- .../HOS/Tamper/Conditions/CondGT.cs | 12 +- .../HOS/Tamper/Conditions/CondLE.cs | 12 +- .../HOS/Tamper/Conditions/CondLT.cs | 15 +- .../HOS/Tamper/Conditions/CondNE.cs | 15 +- .../Tamper/Conditions/IConditionFactory.cs | 10 + .../HOS/Tamper/InstructionHelper.cs | 47 ++--- .../HOS/Tamper/Operations/IOperand.cs | 6 +- .../HOS/Tamper/Operations/IOperation.cs | 3 + .../Tamper/Operations/IOperationFactory.cs | 10 + .../HOS/Tamper/Operations/OpAdd.cs | 13 +- .../HOS/Tamper/Operations/OpAnd.cs | 13 +- .../HOS/Tamper/Operations/OpLog.cs | 5 +- .../HOS/Tamper/Operations/OpLsh.cs | 13 +- .../HOS/Tamper/Operations/OpMov.cs | 11 +- .../HOS/Tamper/Operations/OpMul.cs | 13 +- .../HOS/Tamper/Operations/OpNot.cs | 13 +- src/Ryujinx.HLE/HOS/Tamper/Operations/OpOr.cs | 13 +- .../HOS/Tamper/Operations/OpRsh.cs | 13 +- .../HOS/Tamper/Operations/OpSub.cs | 13 +- .../HOS/Tamper/Operations/OpXor.cs | 13 +- src/Ryujinx.HLE/HOS/Tamper/Pointer.cs | 5 +- src/Ryujinx.HLE/HOS/Tamper/Register.cs | 9 +- src/Ryujinx.HLE/HOS/Tamper/Value.cs | 11 +- src/Ryujinx/Ryujinx.csproj | 15 +- src/Ryujinx/TrimmerRootDescriptor.xml | 3 + .../UI/Controls/NavigationDialogHost.axaml.cs | 3 +- .../UI/ViewModels/MainWindowViewModel.cs | 4 +- src/Ryujinx/Utilities/ValueFormatUtils.cs | 1 - 181 files changed, 794 insertions(+), 552 deletions(-) create mode 100644 Directory.Build.targets create mode 100644 src/Ryujinx.HLE.Generators/IpcCommandGenerator.cs delete mode 100644 src/Ryujinx.HLE.Generators/IpcServiceGenerator.cs delete mode 100644 src/Ryujinx.HLE.Generators/ServiceSyntaxReceiver.cs create mode 100644 src/Ryujinx.HLE.Generators/UserServiceGenerator.cs create mode 100644 src/Ryujinx.HLE/HOS/Tamper/Conditions/IConditionFactory.cs create mode 100644 src/Ryujinx.HLE/HOS/Tamper/Operations/IOperationFactory.cs create mode 100644 src/Ryujinx/TrimmerRootDescriptor.xml diff --git a/.gitignore b/.gitignore index 6f887e638..17df1588e 100644 --- a/.gitignore +++ b/.gitignore @@ -185,3 +185,6 @@ PublishProfiles/ # Ignore distribution build files distribution/macos/temp/ distribution/macos/output/ + +# MSBuild logs +*.binlog diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 000000000..9ef091149 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,6 @@ + + + true + true + + diff --git a/Directory.Packages.props b/Directory.Packages.props index 9e3e9c97d..049218476 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -23,7 +23,7 @@ - + @@ -38,6 +38,7 @@ + diff --git a/src/Ryujinx.BuildValidationTasks/Ryujinx.BuildValidationTasks.csproj b/src/Ryujinx.BuildValidationTasks/Ryujinx.BuildValidationTasks.csproj index c89a044b2..eff20a215 100644 --- a/src/Ryujinx.BuildValidationTasks/Ryujinx.BuildValidationTasks.csproj +++ b/src/Ryujinx.BuildValidationTasks/Ryujinx.BuildValidationTasks.csproj @@ -2,12 +2,14 @@ Exe + false + false - + { + public required string Namespace { get; init; } + public required string TypeName { get; init; } + public required string MethodName { get; init; } + public required ImmutableArray CommandIds { get; init; } + + public bool Equals(CommandData other) + { + return Namespace == other.Namespace && TypeName == other.TypeName && MethodName == other.MethodName && CommandIds.SequenceEqual(other.CommandIds); + } + + public override bool Equals(object obj) + => obj is CommandData other && Equals(other); + + public override int GetHashCode() + { + unchecked + { + var hashCode = (Namespace != null ? Namespace.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (TypeName != null ? TypeName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (MethodName != null ? MethodName.GetHashCode() : 0); + return hashCode; + } + } + } + + private sealed class ServiceData : IEquatable + { + public required string Namespace { get; init; } + public required string TypeName { get; init; } + public required ImmutableArray CmifCommands { get; init; } + public required ImmutableArray TipcCommands { get; init; } + + + public bool Equals(ServiceData other) + { + return Namespace == other.Namespace && TypeName == other.TypeName && CmifCommands.SequenceEqual(other.CmifCommands) && TipcCommands.SequenceEqual(other.TipcCommands); + } + + public override bool Equals(object obj) + { + return obj is ServiceData other && Equals(other); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = (Namespace != null ? Namespace.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (TypeName != null ? TypeName.GetHashCode() : 0); + return hashCode; + } + } + } + + public void Initialize(IncrementalGeneratorInitializationContext context) + { + Func predicate = (node, _) => node is MethodDeclarationSyntax; + Func transform = (ctx, _) => + { + var target = (IMethodSymbol)ctx.TargetSymbol; + return new CommandData + { + Namespace = target.ContainingType.ContainingNamespace?.ToDisplayString(), + TypeName = target.ContainingType.Name, + MethodName = target.Name, + CommandIds = ctx.Attributes.Select(attr => (int)attr.ConstructorArguments[0].Value!).ToImmutableArray(), + }; + }; + IncrementalValuesProvider cmifCommands = + context.SyntaxProvider.ForAttributeWithMetadataName("Ryujinx.HLE.HOS.Services.CommandCmifAttribute", + predicate, + transform + ); + IncrementalValuesProvider tipcCommands = + context.SyntaxProvider.ForAttributeWithMetadataName("Ryujinx.HLE.HOS.Services.CommandTipcAttribute", + predicate, + transform + ); + + IncrementalValueProvider<(ImmutableArray Left, ImmutableArray Right)> allCommands = + cmifCommands.Collect().Combine(tipcCommands.Collect()); + + IncrementalValuesProvider types = allCommands.SelectMany((commands, _) => + { + ILookup<(string Namespace, string TypeName), CommandData> cmif = commands.Left.ToLookup(c => (c.Namespace, c.TypeName)); + ILookup<(string Namespace, string TypeName), CommandData> tipc = commands.Right.ToLookup(c => (c.Namespace, c.TypeName)); + + ImmutableArray.Builder builder = ImmutableArray.CreateBuilder(); + + foreach ((string Namespace, string TypeName) type in cmif.Select(c => c.Key).Union(tipc.Select(t => t.Key))) + { + builder.Add(new ServiceData + { + Namespace = type.Namespace, + TypeName = type.TypeName, + CmifCommands = cmif.Contains(type) ? cmif[type].ToImmutableArray() : [], + TipcCommands = tipc.Contains(type) ? tipc[type].ToImmutableArray() : [], + }); + } + + return builder.DrainToImmutable(); + }); + + context.RegisterSourceOutput(types, (ctx, data) => + { + var generator = new CodeGenerator(); + + generator.AppendLine("using Ryujinx.HLE.HOS;"); + generator.AppendLine("using RC = global::Ryujinx.HLE.HOS.ResultCode;"); + + generator.EnterScope($"namespace {data.Namespace}"); + generator.EnterScope($"partial class {data.TypeName}"); + + if (!data.CmifCommands.IsEmpty) + { + GenerateCommandMethod("Cmif", data.CmifCommands); + } + + if (!data.TipcCommands.IsEmpty) + { + GenerateCommandMethod("Tipc", data.TipcCommands); + } + + generator.LeaveScope(); + generator.LeaveScope(); + + ctx.AddSource($"{data.Namespace}.{data.TypeName}.g.cs", generator.ToString()); + + void GenerateCommandMethod(string commandType, ImmutableArray commands) + { + generator.EnterScope($"protected override RC Invoke{commandType}Method(int id, ServiceCtx context)"); + generator.EnterScope("switch (id)"); + foreach (CommandData command in commands) + { + generator.AppendLine($"case {string.Join(" or ", command.CommandIds)}:"); + generator.IncreaseIndentation(); + generator.AppendLine($"LogInvoke(\"{command.MethodName}\");"); + generator.AppendLine($"return (RC){command.MethodName}(context);"); + generator.DecreaseIndentation(); + } + generator.AppendLine($"default: return base.Invoke{commandType}Method(id, context);"); + generator.LeaveScope(); + generator.LeaveScope(); + + generator.EnterScope($"public override int {commandType}CommandIdByMethodName(string name)"); + generator.EnterScope("return name switch"); + foreach (CommandData command in commands) + { + // just return the first command with this name + generator.AppendLine($"\"{command.MethodName}\" => {command.CommandIds[0]},"); + } + generator.AppendLine($"_ => base.{commandType}CommandIdByMethodName(name),"); + generator.LeaveScope(";"); + generator.LeaveScope(); + } + }); + } + } +} diff --git a/src/Ryujinx.HLE.Generators/IpcServiceGenerator.cs b/src/Ryujinx.HLE.Generators/IpcServiceGenerator.cs deleted file mode 100644 index cdd062826..000000000 --- a/src/Ryujinx.HLE.Generators/IpcServiceGenerator.cs +++ /dev/null @@ -1,78 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using System.Linq; - -namespace Ryujinx.HLE.Generators -{ - [Generator] - public class IpcServiceGenerator : ISourceGenerator - { - public void Execute(GeneratorExecutionContext context) - { - ServiceSyntaxReceiver syntaxReceiver = (ServiceSyntaxReceiver)context.SyntaxReceiver; - CodeGenerator generator = new(); - - generator.AppendLine("#nullable enable"); - generator.AppendLine("using System;"); - generator.EnterScope($"namespace Ryujinx.HLE.HOS.Services.Sm"); - generator.EnterScope($"partial class IUserInterface"); - - generator.EnterScope($"public IpcService? GetServiceInstance(Type type, ServiceCtx context, object? parameter = null)"); - foreach (ClassDeclarationSyntax className in syntaxReceiver.Types) - { - if (className.Modifiers.Any(SyntaxKind.AbstractKeyword) || className.Modifiers.Any(SyntaxKind.PrivateKeyword) || !className.AttributeLists.Any(x => x.Attributes.Any(y => y.ToString().StartsWith("Service")))) - continue; - string name = GetFullName(className, context).Replace("global::", string.Empty); - if (!name.StartsWith("Ryujinx.HLE.HOS.Services")) - continue; - ConstructorDeclarationSyntax[] constructors = className.ChildNodes().Where(x => x.IsKind(SyntaxKind.ConstructorDeclaration)).Select(y => y as ConstructorDeclarationSyntax).ToArray(); - - if (!constructors.Any(x => x.ParameterList.Parameters.Count >= 1)) - continue; - - if (constructors.Where(x => x.ParameterList.Parameters.Count >= 1).FirstOrDefault().ParameterList.Parameters[0].Type.ToString() == "ServiceCtx") - { - generator.EnterScope($"if (type == typeof({GetFullName(className, context)}))"); - if (constructors.Any(x => x.ParameterList.Parameters.Count == 2)) - { - TypeSyntax type = constructors.Where(x => x.ParameterList.Parameters.Count == 2).FirstOrDefault().ParameterList.Parameters[1].Type; - SemanticModel model = context.Compilation.GetSemanticModel(type.SyntaxTree); - INamedTypeSymbol typeSymbol = model.GetSymbolInfo(type).Symbol as INamedTypeSymbol; - string fullName = typeSymbol.ToString(); - generator.EnterScope("if (parameter != null)"); - generator.AppendLine($"return new {GetFullName(className, context)}(context, ({fullName})parameter);"); - generator.LeaveScope(); - } - - if (constructors.Any(x => x.ParameterList.Parameters.Count == 1)) - { - generator.AppendLine($"return new {GetFullName(className, context)}(context);"); - } - - generator.LeaveScope(); - } - } - - generator.AppendLine("return null;"); - generator.LeaveScope(); - - generator.LeaveScope(); - generator.LeaveScope(); - generator.AppendLine("#nullable disable"); - context.AddSource($"IUserInterface.g.cs", generator.ToString()); - } - - private string GetFullName(ClassDeclarationSyntax syntaxNode, GeneratorExecutionContext context) - { - INamedTypeSymbol typeSymbol = context.Compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetDeclaredSymbol(syntaxNode); - - return typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); - } - - public void Initialize(GeneratorInitializationContext context) - { - context.RegisterForSyntaxNotifications(() => new ServiceSyntaxReceiver()); - } - } -} diff --git a/src/Ryujinx.HLE.Generators/Ryujinx.HLE.Generators.csproj b/src/Ryujinx.HLE.Generators/Ryujinx.HLE.Generators.csproj index 4791a3b27..5de37c865 100644 --- a/src/Ryujinx.HLE.Generators/Ryujinx.HLE.Generators.csproj +++ b/src/Ryujinx.HLE.Generators/Ryujinx.HLE.Generators.csproj @@ -3,8 +3,6 @@ netstandard2.0 true - true - Generated true $(DefaultItemExcludes);._* @@ -15,6 +13,10 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Ryujinx.HLE.Generators/ServiceSyntaxReceiver.cs b/src/Ryujinx.HLE.Generators/ServiceSyntaxReceiver.cs deleted file mode 100644 index 7513f5f45..000000000 --- a/src/Ryujinx.HLE.Generators/ServiceSyntaxReceiver.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using System.Collections.Generic; - -namespace Ryujinx.HLE.Generators -{ - internal class ServiceSyntaxReceiver : ISyntaxReceiver - { - public HashSet Types = []; - - public void OnVisitSyntaxNode(SyntaxNode syntaxNode) - { - if (syntaxNode is ClassDeclarationSyntax classDeclaration) - { - if (classDeclaration.BaseList == null) - { - return; - } - - Types.Add(classDeclaration); - } - } - } -} diff --git a/src/Ryujinx.HLE.Generators/UserServiceGenerator.cs b/src/Ryujinx.HLE.Generators/UserServiceGenerator.cs new file mode 100644 index 000000000..7b30988fb --- /dev/null +++ b/src/Ryujinx.HLE.Generators/UserServiceGenerator.cs @@ -0,0 +1,93 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Ryujinx.HLE.Generators +{ + [Generator] + public sealed class UserServiceGenerator : IIncrementalGenerator + { + private sealed class ServiceData : IEquatable + { + public required string FullName { get; init; } + public required IReadOnlyList<(string ServiceName, string ParameterValue)> Instances { get; init; } + + public override bool Equals(object obj) + => obj is ServiceData data && Equals(data); + + public bool Equals(ServiceData other) + { + return this.FullName == other.FullName && this.Instances.SequenceEqual(other.Instances); + } + + public override int GetHashCode() => FullName.GetHashCode(); + } + + public void Initialize(IncrementalGeneratorInitializationContext context) + { + IncrementalValuesProvider pipeline = context.SyntaxProvider.ForAttributeWithMetadataName("Ryujinx.HLE.HOS.Services.ServiceAttribute", + predicate: (node, _) => node is ClassDeclarationSyntax decl && !decl.Modifiers.Any(SyntaxKind.AbstractKeyword) && !decl.Modifiers.Any(SyntaxKind.PrivateKeyword), + transform: (ctx, _) => + { + var target = (INamedTypeSymbol)ctx.TargetSymbol; + IEnumerable<(string, string param)> instances = ctx.Attributes.Select(attr => + { + string param = attr.ConstructorArguments is [_, { IsNull: false } arg] ? arg.ToCSharpString() : null; + return ((string)attr.ConstructorArguments[0].Value, param); + }); + return new ServiceData + { + FullName = target.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), + Instances = instances.ToList(), + }; + } + ); + + context.RegisterSourceOutput(pipeline.Collect(), + (ctx, data) => + { + var generator = new CodeGenerator(); + + generator.AppendLine("#nullable enable"); + generator.AppendLine("using System;"); + generator.EnterScope("namespace Ryujinx.HLE.HOS.Services.Sm"); + generator.EnterScope("partial class IUserInterface"); + + generator.EnterScope("public IpcService? GetServiceInstance(string name, ServiceCtx context)"); + + generator.EnterScope("return name switch"); + + foreach (ServiceData serviceImpl in data) + { + foreach ((string ServiceName, string ParameterValue) instance in serviceImpl.Instances) + { + if (instance.ParameterValue == null) + { + generator.AppendLine($"\"{instance.ServiceName}\" => new {serviceImpl.FullName}(context),"); + } + else + { + generator.AppendLine($"\"{instance.ServiceName}\" => new {serviceImpl.FullName}(context, {instance.ParameterValue}),"); + } + } + } + + generator.AppendLine("_ => null,"); + + generator.LeaveScope(";"); + + generator.LeaveScope(); + + generator.LeaveScope(); + generator.LeaveScope(); + + generator.AppendLine("#nullable disable"); + + ctx.AddSource("IUserInterface.g.cs", generator.ToString()); + }); + } + } +} diff --git a/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs b/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs index 23068bf72..19684c273 100644 --- a/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs +++ b/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; namespace Ryujinx.HLE.Exceptions @@ -17,22 +18,22 @@ namespace Ryujinx.HLE.Exceptions public IpcService Service { get; } public ServiceCtx Context { get; } public IpcMessage Request { get; } + private string MethodName { get; } - public ServiceNotImplementedException(IpcService service, ServiceCtx context) - : this(service, context, "The service call is not implemented.") { } - - public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message) : base(message) + public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message = "The service call is not implemented.", [CallerMemberName] string methodName = null) : base(message) { Service = service; Context = context; Request = context.Request; + MethodName = methodName; } - public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message, Exception inner) : base(message, inner) + public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message, Exception inner, [CallerMemberName] string methodName = null) : base(message, inner) { Service = service; Context = context; Request = context.Request; + MethodName = methodName; } public override string Message @@ -47,25 +48,12 @@ namespace Ryujinx.HLE.Exceptions { StringBuilder sb = new(); - // Print the IPC command details (service name, command ID, and handler) - (Type callingType, MethodBase callingMethod) = WalkStackTrace(new StackTrace(this)); + int commandId = Request.Type > IpcMessageType.TipcCloseSession + ? Service.TipcCommandIdByMethodName(MethodName) + : Service.CmifCommandIdByMethodName(MethodName); - if (callingType != null && callingMethod != null) - { - // If the type is past 0xF, we are using TIPC - IReadOnlyDictionary ipcCommands = Request.Type > IpcMessageType.TipcCloseSession ? Service.TipcCommands : Service.CmifCommands; - - // Find the handler for the method called - KeyValuePair ipcHandler = ipcCommands.FirstOrDefault(x => x.Value == callingMethod); - int ipcCommandId = ipcHandler.Key; - MethodInfo ipcMethod = ipcHandler.Value; - - if (ipcMethod != null) - { - sb.AppendLine($"Service Command: {Service.GetType().FullName}: {ipcCommandId} ({ipcMethod.Name})"); - sb.AppendLine(); - } - } + sb.AppendLine($"Service Command: {Service.GetType().FullName}: {commandId} ({MethodName})"); + sb.AppendLine(); sb.AppendLine("Guest Stack Trace:"); sb.AppendLine(Context.Thread.GetGuestStackTrace()); @@ -137,26 +125,5 @@ namespace Ryujinx.HLE.Exceptions return sb.ToString(); } - - private static (Type, MethodBase) WalkStackTrace(StackTrace trace) - { - int i = 0; - - StackFrame frame; - - // Find the IIpcService method that threw this exception - while ((frame = trace.GetFrame(i++)) != null) - { - MethodBase method = frame.GetMethod(); - Type declType = method.DeclaringType; - - if (typeof(IpcService).IsAssignableFrom(declType)) - { - return (declType, method); - } - } - - return (null, null); - } } } diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForApplication.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForApplication.cs index a00514cb6..486e50aed 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForApplication.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForApplication.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService { - class IManagerForApplication : IpcService + partial class IManagerForApplication : IpcService { private readonly ManagerServer _managerServer; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForSystemService.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForSystemService.cs index 40c73c439..b9e29d516 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForSystemService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForSystemService.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService { - class IManagerForSystemService : IpcService + partial class IManagerForSystemService : IpcService { private readonly ManagerServer _managerServer; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IProfile.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IProfile.cs index a0021917f..391cb0b72 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IProfile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IProfile.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService { - class IProfile : IpcService + partial class IProfile : IpcService { private readonly ProfileServer _profileServer; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IProfileEditor.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IProfileEditor.cs index 5d5d0dd69..e605ddc63 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IProfileEditor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IProfileEditor.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService { - class IProfileEditor : IpcService + partial class IProfileEditor : IpcService { private readonly ProfileServer _profileServer; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForAdministrator.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForAdministrator.cs index 74c135aed..b0b1718af 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForAdministrator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForAdministrator.cs @@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc.AccountService; namespace Ryujinx.HLE.HOS.Services.Account.Acc { [Service("acc:su", AccountServiceFlag.Administrator)] // Max Sessions: 8 - class IAccountServiceForAdministrator : IpcService + partial class IAccountServiceForAdministrator : IpcService { private readonly ApplicationServiceServer _applicationServiceServer; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs index 98af10694..a8558e5f4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs @@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Arp; namespace Ryujinx.HLE.HOS.Services.Account.Acc { [Service("acc:u0", AccountServiceFlag.Application)] // Max Sessions: 4 - class IAccountServiceForApplication : IpcService + partial class IAccountServiceForApplication : IpcService { private readonly ApplicationServiceServer _applicationServiceServer; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForSystemService.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForSystemService.cs index 682b5327f..4b4c823ff 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForSystemService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForSystemService.cs @@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc.AccountService; namespace Ryujinx.HLE.HOS.Services.Account.Acc { [Service("acc:u1", AccountServiceFlag.SystemService)] // Max Sessions: 16 - class IAccountServiceForSystemService : IpcService + partial class IAccountServiceForSystemService : IpcService { private readonly ApplicationServiceServer _applicationServiceServer; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs index 91daba5f0..24886cd91 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs @@ -5,7 +5,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Account.Acc { - class IAsyncContext : IpcService + partial class IAsyncContext : IpcService { protected AsyncExecution AsyncExecution; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs index 175838506..27a97cd8c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs @@ -2,7 +2,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext; namespace Ryujinx.HLE.HOS.Services.Account.Acc { - class IAsyncNetworkServiceLicenseKindContext : IAsyncContext + partial class IAsyncNetworkServiceLicenseKindContext : IAsyncContext { private readonly NetworkServiceLicenseKind? _serviceLicenseKind; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IBaasAccessTokenAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IBaasAccessTokenAccessor.cs index b88815778..3f2832ef2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IBaasAccessTokenAccessor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IBaasAccessTokenAccessor.cs @@ -3,6 +3,6 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc [Service("acc:aa", AccountServiceFlag.BaasAccessTokenAccessor)] // Max Sessions: 4 class IBaasAccessTokenAccessor : IpcService { - public IBaasAccessTokenAccessor(ServiceCtx context) { } + public IBaasAccessTokenAccessor(ServiceCtx context, AccountServiceFlag serviceFlag) { } } } diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs index 7700cac09..2644641a8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemA namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService { - class ILibraryAppletProxy : IpcService + partial class ILibraryAppletProxy : IpcService { private readonly ulong _pid; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs index dd015fd80..30f8f8b57 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs @@ -2,7 +2,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemA namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService { - class ISystemAppletProxy : IpcService + partial class ISystemAppletProxy : IpcService { private readonly ulong _pid; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs index cd71103ca..6d4c2e3a7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs @@ -9,7 +9,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletCreator { - class ILibraryAppletAccessor : DisposableIpcService + partial class ILibraryAppletAccessor : DisposableIpcService { private readonly KernelContext _kernelContext; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs index fc02ea172..7c5b51dce 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs @@ -3,7 +3,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy { - class ILibraryAppletSelfAccessor : IpcService + partial class ILibraryAppletSelfAccessor : IpcService { private readonly AppletStandalone _appletStandalone = new(); diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/IProcessWindingController.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/IProcessWindingController.cs index d86a896d6..33a333786 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/IProcessWindingController.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/IProcessWindingController.cs @@ -2,7 +2,7 @@ using Ryujinx.Common; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy { - class IProcessWindingController : IpcService + partial class IProcessWindingController : IpcService { public IProcessWindingController() { } diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IAudioController.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IAudioController.cs index 05a4b0a63..a9141ffb9 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IAudioController.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IAudioController.cs @@ -2,7 +2,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy { - class IAudioController : IpcService + partial class IAudioController : IpcService { public IAudioController() { } diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs index ad776fe6e..f07372fe4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs @@ -10,7 +10,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy { - class ICommonStateGetter : DisposableIpcService + partial class ICommonStateGetter : DisposableIpcService { private readonly ServiceCtx _context; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IDisplayController.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IDisplayController.cs index 6bd35a779..fe88c3570 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IDisplayController.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IDisplayController.cs @@ -6,7 +6,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy { - class IDisplayController : IpcService + partial class IDisplayController : IpcService { private readonly KTransferMemory _transferMem; private bool _lastApplicationCaptureBufferAcquired; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IHomeMenuFunctions.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IHomeMenuFunctions.cs index 78f47e0e9..7ba2a5c51 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IHomeMenuFunctions.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IHomeMenuFunctions.cs @@ -6,7 +6,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy { - class IHomeMenuFunctions : IpcService + partial class IHomeMenuFunctions : IpcService { private readonly KEvent _channelEvent; private int _channelEventHandle; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ILibraryAppletCreator.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ILibraryAppletCreator.cs index f1ae81f8d..70e85585e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ILibraryAppletCreator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ILibraryAppletCreator.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Library namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy { - class ILibraryAppletCreator : IpcService + partial class ILibraryAppletCreator : IpcService { public ILibraryAppletCreator() { } diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs index 7aac6f3ea..479bfe09b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs @@ -8,7 +8,7 @@ using System.Threading; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy { - class ISelfController : IpcService + partial class ISelfController : IpcService { private readonly ulong _pid; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IWindowController.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IWindowController.cs index 46dc4916d..9c5815670 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IWindowController.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IWindowController.cs @@ -2,7 +2,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy { - class IWindowController : IpcService + partial class IWindowController : IpcService { private readonly ulong _pid; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IAllSystemAppletProxiesService.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IAllSystemAppletProxiesService.cs index b8741b22b..8d7ed5e3f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IAllSystemAppletProxiesService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IAllSystemAppletProxiesService.cs @@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE { [Service("appletAE")] - class IAllSystemAppletProxiesService : IpcService + partial class IAllSystemAppletProxiesService : IpcService { public IAllSystemAppletProxiesService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorage.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorage.cs index 311084aa1..e8169fea8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorage.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorage.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE { - class IStorage : IpcService + partial class IStorage : IpcService { public bool IsReadOnly { get; private set; } public byte[] Data { get; private set; } diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorageAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorageAccessor.cs index 54c7b69e5..fead139f7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorageAccessor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IStorageAccessor.cs @@ -2,7 +2,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE { - class IStorageAccessor : IpcService + partial class IStorageAccessor : IpcService { private readonly IStorage _storage; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs index 9986bf824..1ba8ffc63 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs @@ -22,7 +22,7 @@ using ApplicationId = LibHac.Ncm.ApplicationId; namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy { - class IApplicationFunctions : IpcService + partial class IApplicationFunctions : IpcService { private long _defaultSaveDataSize = 200000000; private long _defaultJournalSaveDataSize = 200000000; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs index b24e1bf4f..c763ffe53 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationPr namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService { - class IApplicationProxy : IpcService + partial class IApplicationProxy : IpcService { private readonly ulong _pid; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/IApplicationProxyService.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/IApplicationProxyService.cs index 9814976f7..e64c2037b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/IApplicationProxyService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/IApplicationProxyService.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService; namespace Ryujinx.HLE.HOS.Services.Am { [Service("appletOE")] - class IApplicationProxyService : IpcService + partial class IApplicationProxyService : IpcService { public IApplicationProxyService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/IManager.cs b/src/Ryujinx.HLE/HOS/Services/Apm/IManager.cs index 83215befa..5398a20e5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/IManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/IManager.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Apm { - abstract class IManager : IpcService + abstract partial class IManager : IpcService { public IManager(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/IManagerPrivileged.cs b/src/Ryujinx.HLE/HOS/Services/Apm/IManagerPrivileged.cs index bb0049d1b..08b681d57 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/IManagerPrivileged.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/IManagerPrivileged.cs @@ -3,7 +3,7 @@ namespace Ryujinx.HLE.HOS.Services.Apm // NOTE: This service doesn’t exist anymore after firmware 7.0.1. But some outdated homebrew still uses it. [Service("apm:p")] // 1.0.0-7.0.1 - class IManagerPrivileged : IpcService + partial class IManagerPrivileged : IpcService { public IManagerPrivileged(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/ISession.cs b/src/Ryujinx.HLE/HOS/Services/Apm/ISession.cs index 6ee696056..f4103e00b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/ISession.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/ISession.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Apm { - abstract class ISession : IpcService + abstract partial class ISession : IpcService { public ISession(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs b/src/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs index 375423cf2..d01e33872 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Apm { - abstract class ISystemManager : IpcService + abstract partial class ISystemManager : IpcService { public ISystemManager(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs b/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs index 8f2642695..a8d2c66a7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs +++ b/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs @@ -8,7 +8,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Bluetooth { [Service("btdrv")] - class IBluetoothDriver : IpcService + partial class IBluetoothDriver : IpcService { #pragma warning disable CS0414, IDE0052 // Remove unread private member private string _unknownLowEnergy; diff --git a/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothUser.cs b/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothUser.cs index ea4a46f92..2756ede7c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothUser.cs +++ b/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothUser.cs @@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Settings; namespace Ryujinx.HLE.HOS.Services.Bluetooth { [Service("bt")] - class IBluetoothUser : IpcService + partial class IBluetoothUser : IpcService { public IBluetoothUser(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/BtmUser/IBtmUserCore.cs b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/BtmUser/IBtmUserCore.cs index d4e23b93d..9d06e44e7 100644 --- a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/BtmUser/IBtmUserCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/BtmUser/IBtmUserCore.cs @@ -5,7 +5,7 @@ using Ryujinx.Horizon.Common; namespace Ryujinx.HLE.HOS.Services.BluetoothManager.BtmUser { - class IBtmUserCore : IpcService + partial class IBtmUserCore : IpcService { public KEvent _bleScanEvent; public int _bleScanEventHandle; diff --git a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmUser.cs b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmUser.cs index 78f8fd8f5..29190eb44 100644 --- a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmUser.cs +++ b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmUser.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.BluetoothManager.BtmUser; namespace Ryujinx.HLE.HOS.Services.BluetoothManager { [Service("btm:u")] // 5.0.0+ - class IBtmUser : IpcService + partial class IBtmUser : IpcService { public IBtmUser(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/IAlbumApplicationService.cs b/src/Ryujinx.HLE/HOS/Services/Caps/IAlbumApplicationService.cs index 754a44025..e794be54e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/IAlbumApplicationService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/IAlbumApplicationService.cs @@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Caps.Types; namespace Ryujinx.HLE.HOS.Services.Caps { [Service("caps:u")] - class IAlbumApplicationService : IpcService + partial class IAlbumApplicationService : IpcService { public IAlbumApplicationService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/IAlbumControlService.cs b/src/Ryujinx.HLE/HOS/Services/Caps/IAlbumControlService.cs index 4376c4d14..81295f910 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/IAlbumControlService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/IAlbumControlService.cs @@ -1,7 +1,7 @@ namespace Ryujinx.HLE.HOS.Services.Caps { [Service("caps:c")] - class IAlbumControlService : IpcService + partial class IAlbumControlService : IpcService { public IAlbumControlService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs b/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs index 0723b57cc..153f7df7c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs @@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Caps.Types; namespace Ryujinx.HLE.HOS.Services.Caps { [Service("caps:su")] // 6.0.0+ - class IScreenShotApplicationService : IpcService + partial class IScreenShotApplicationService : IpcService { public IScreenShotApplicationService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ectx/IContextRegistrar.cs b/src/Ryujinx.HLE/HOS/Services/Ectx/IContextRegistrar.cs index 34adfe9be..8cc33637f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ectx/IContextRegistrar.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ectx/IContextRegistrar.cs @@ -4,7 +4,7 @@ using Ryujinx.Horizon.Common; namespace Ryujinx.HLE.HOS.Services.Ectx { - class IContextRegistrar : DisposableIpcService + partial class IContextRegistrar : DisposableIpcService { public IContextRegistrar(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForApplication.cs b/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForApplication.cs index c8ef155e3..177349c33 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForApplication.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForApplication.cs @@ -1,7 +1,7 @@ namespace Ryujinx.HLE.HOS.Services.Ectx { [Service("ectx:aw")] // 11.0.0+ - class IWriterForApplication : IpcService + partial class IWriterForApplication : IpcService { public IWriterForApplication(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Fatal/IService.cs b/src/Ryujinx.HLE/HOS/Services/Fatal/IService.cs index c3ed92ed0..55efbdf6e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fatal/IService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fatal/IService.cs @@ -7,7 +7,7 @@ using System.Text; namespace Ryujinx.HLE.HOS.Services.Fatal { [Service("fatal:u")] - class IService : IpcService + partial class IService : IpcService { public IService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs index 0fe7bcdd6..91e3ea08f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs @@ -5,7 +5,7 @@ using Ryujinx.Memory; namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy { - class IDirectory : DisposableIpcService + partial class IDirectory : DisposableIpcService { private SharedRef _baseDirectory; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs index 0ea57f5a4..1fd69520d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs @@ -7,7 +7,7 @@ using Ryujinx.Memory; namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy { - class IFile : DisposableIpcService + partial class IFile : DisposableIpcService { private SharedRef _baseFile; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs index 168dfc37a..4f74bb272 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs @@ -7,7 +7,7 @@ using Path = LibHac.FsSrv.Sf.Path; namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy { - class IFileSystem : DisposableIpcService + partial class IFileSystem : DisposableIpcService { private SharedRef _fileSystem; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs index 480899ae1..4d8d84e36 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs @@ -10,7 +10,7 @@ using System.Threading; namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy { - class IStorage : DisposableIpcService + partial class IStorage : DisposableIpcService { private SharedRef _baseStorage; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs b/src/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs index 49453e83a..75f6fbd2a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs @@ -5,7 +5,7 @@ using GameCardHandle = System.UInt32; namespace Ryujinx.HLE.HOS.Services.Fs { - class IDeviceOperator : DisposableIpcService + partial class IDeviceOperator : DisposableIpcService { private SharedRef _baseOperator; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs b/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs index 08ede2b5b..c95f7192e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs @@ -25,7 +25,7 @@ using IStorage = LibHac.FsSrv.Sf.IStorage; namespace Ryujinx.HLE.HOS.Services.Fs { [Service("fsp-srv")] - class IFileSystemProxy : DisposableIpcService + partial class IFileSystemProxy : DisposableIpcService { private SharedRef _baseFileSystemProxy; private ulong _pid; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/IMultiCommitManager.cs b/src/Ryujinx.HLE/HOS/Services/Fs/IMultiCommitManager.cs index 134e2ed8c..033fa9da1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/IMultiCommitManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/IMultiCommitManager.cs @@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy; namespace Ryujinx.HLE.HOS.Services.Fs { - class IMultiCommitManager : DisposableIpcService // 6.0.0+ + partial class IMultiCommitManager : DisposableIpcService // 6.0.0+ { private SharedRef _baseCommitManager; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs b/src/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs index b86eb1fa1..49a8608a8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs @@ -5,7 +5,7 @@ using Ryujinx.Memory; namespace Ryujinx.HLE.HOS.Services.Fs { - class ISaveDataInfoReader : DisposableIpcService + partial class ISaveDataInfoReader : DisposableIpcService { private SharedRef _baseReader; diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/IActiveVibrationDeviceList.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/IActiveVibrationDeviceList.cs index 93f19c915..eef5bda83 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/IActiveVibrationDeviceList.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/IActiveVibrationDeviceList.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid.HidServer { - class IActiveApplicationDeviceList : IpcService + partial class IActiveApplicationDeviceList : IpcService { public IActiveApplicationDeviceList() { } diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/IAppletResource.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/IAppletResource.cs index 56eb345af..a9df89a0e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/IAppletResource.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/IAppletResource.cs @@ -5,7 +5,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Hid.HidServer { - class IAppletResource : IpcService + partial class IAppletResource : IpcService { private readonly KSharedMemory _hidSharedMem; private int _hidSharedMemHandle; diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs index 08e2a2d68..0ebb5e7c6 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs @@ -13,7 +13,7 @@ using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid { [Service("hid")] - class IHidServer : IpcService + partial class IHidServer : IpcService { private readonly KEvent _xpadIdEvent; private readonly KEvent _palmaOperationCompleteEvent; diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/IHidSystemServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/IHidSystemServer.cs index 0b4eba948..3255a644c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/IHidSystemServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/IHidSystemServer.cs @@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Hid.Types; namespace Ryujinx.HLE.HOS.Services.Hid { [Service("hid:sys")] - class IHidSystemServer : IpcService + partial class IHidSystemServer : IpcService { public IHidSystemServer(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs index 5082bddc2..614e865d4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs @@ -4,7 +4,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Hid { [Service("hidbus")] - class IHidbusServer : IpcService + partial class IHidbusServer : IpcService { public IHidbusServer(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorServer.cs index 8a30ce066..50b8c14cf 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorServer.cs @@ -9,7 +9,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Hid.Irs { [Service("irs")] - class IIrSensorServer : IpcService + partial class IIrSensorServer : IpcService { private int _irsensorSharedMemoryHandle = 0; diff --git a/src/Ryujinx.HLE/HOS/Services/IpcService.cs b/src/Ryujinx.HLE/HOS/Services/IpcService.cs index c7dee64fb..780b68f79 100644 --- a/src/Ryujinx.HLE/HOS/Services/IpcService.cs +++ b/src/Ryujinx.HLE/HOS/Services/IpcService.cs @@ -13,9 +13,6 @@ namespace Ryujinx.HLE.HOS.Services { abstract class IpcService { - public IReadOnlyDictionary CmifCommands { get; } - public IReadOnlyDictionary TipcCommands { get; } - public ServerBase Server { get; private set; } private IpcService _parent; @@ -23,46 +20,8 @@ namespace Ryujinx.HLE.HOS.Services private int _selfId; private bool _isDomain; - // cache array so we don't recreate it all the time - private object[] _parameters = [null]; - - public IpcService(ServerBase server = null, bool registerTipc = false) + public IpcService(ServerBase server = null) { - Stopwatch sw = Stopwatch.StartNew(); - - CmifCommands = GetType() - .GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public) - .SelectMany(methodInfo => methodInfo.GetCustomAttributes() - .Select(command => (command.Id, methodInfo))) - .ToDictionary(command => command.Id, command => command.methodInfo); - - sw.Stop(); - - Logger.Debug?.Print( - LogClass.Emulation, - $"{CmifCommands.Count} Cmif commands loaded in {sw.ElapsedTicks} ticks ({Stopwatch.Frequency} tps).", - GetType().AsPrettyString() - ); - - if (registerTipc) - { - sw.Start(); - - TipcCommands = GetType() - .GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public) - .SelectMany(methodInfo => methodInfo.GetCustomAttributes() - .Select(command => (command.Id, methodInfo))) - .ToDictionary(command => command.Id, command => command.methodInfo); - - sw.Stop(); - - Logger.Debug?.Print( - LogClass.Emulation, - $"{TipcCommands.Count} Tipc commands loaded in {sw.ElapsedTicks} ticks ({Stopwatch.Frequency} tps).", - GetType().AsPrettyString() - ); - } - Server = server; _parent = this; @@ -87,6 +46,49 @@ namespace Ryujinx.HLE.HOS.Services _isDomain = false; } + protected virtual ResultCode InvokeCmifMethod(int id, ServiceCtx context) + { + if (!context.Device.Configuration.IgnoreMissingServices) + { + string dbgMessage = $"{this.GetType().FullName}: {id}"; + + throw new ServiceNotImplementedException(this, context, dbgMessage); + } + + string serviceName = (this is not DummyService dummyService) + ? this.GetType().FullName + : dummyService.ServiceName; + + Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {id} ignored"); + + return ResultCode.Success; + } + + public virtual int CmifCommandIdByMethodName(string name) => -1; + + protected virtual ResultCode InvokeTipcMethod(int id, ServiceCtx context) + { + if (!context.Device.Configuration.IgnoreMissingServices) + { + string dbgMessage = $"{this.GetType().FullName}: {id}"; + + throw new ServiceNotImplementedException(this, context, dbgMessage); + } + + string serviceName = (this is not DummyService dummyService) + ? this.GetType().FullName + : dummyService.ServiceName; + + Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {id} ignored"); + + return ResultCode.Success; + } + + public virtual int TipcCommandIdByMethodName(string name) => -1; + + protected void LogInvoke(string name) + => Logger.Trace?.Print(LogClass.KernelIpc, $"{this.GetType().Name}: {name}"); + public void CallCmifMethod(ServiceCtx context) { IpcService service = this; @@ -137,93 +139,39 @@ namespace Ryujinx.HLE.HOS.Services #pragma warning restore IDE0059 int commandId = (int)context.RequestData.ReadInt64(); - bool serviceExists = service.CmifCommands.TryGetValue(commandId, out MethodInfo processRequest); + context.ResponseData.BaseStream.Seek(_isDomain ? 0x20 : 0x10, SeekOrigin.Begin); - if (context.Device.Configuration.IgnoreMissingServices || serviceExists) + ResultCode result = service.InvokeCmifMethod(commandId, context); + + if (_isDomain) { - ResultCode result = ResultCode.Success; - - context.ResponseData.BaseStream.Seek(_isDomain ? 0x20 : 0x10, SeekOrigin.Begin); - - if (serviceExists) + foreach (int id in context.Response.ObjectIds) { - Logger.Trace?.Print(LogClass.KernelIpc, $"{service.GetType().Name}: {processRequest.Name}"); - - _parameters[0] = context; - - result = (ResultCode)processRequest.Invoke(service, _parameters); - } - else - { - string serviceName = (service is not DummyService dummyService) ? service.GetType().FullName : dummyService.ServiceName; - - Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored"); + context.ResponseData.Write(id); } - if (_isDomain) - { - foreach (int id in context.Response.ObjectIds) - { - 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.BaseStream.Seek(_isDomain ? 0x10 : 0, SeekOrigin.Begin); - - context.ResponseData.Write(IpcMagic.Sfco); - context.ResponseData.Write((long)result); + context.ResponseData.Write(context.Response.ObjectIds.Count); } - else - { - string dbgMessage = $"{service.GetType().FullName}: {commandId}"; - throw new ServiceNotImplementedException(service, context, dbgMessage); - } + context.ResponseData.BaseStream.Seek(_isDomain ? 0x10 : 0, SeekOrigin.Begin); + + context.ResponseData.Write(IpcMagic.Sfco); + context.ResponseData.Write((long)result); } public void CallTipcMethod(ServiceCtx context) { int commandId = (int)context.Request.Type - 0x10; - bool serviceExists = TipcCommands.TryGetValue(commandId, out MethodInfo processRequest); + context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin); - if (context.Device.Configuration.IgnoreMissingServices || serviceExists) - { - ResultCode result = ResultCode.Success; + ResultCode result = InvokeTipcMethod(commandId, context); - context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin); + context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin); - if (serviceExists) - { - Logger.Debug?.Print(LogClass.KernelIpc, $"{GetType().Name}: {processRequest.Name}"); - - _parameters[0] = context; - - result = (ResultCode)processRequest.Invoke(this, _parameters); - } - else - { - string serviceName; - - serviceName = (this is not DummyService dummyService) ? GetType().FullName : dummyService.ServiceName; - - Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored"); - } - - context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin); - - context.ResponseData.Write((uint)result); - } - else - { - string dbgMessage = $"{GetType().FullName}: {commandId}"; - - throw new ServiceNotImplementedException(this, context, dbgMessage); - } + context.ResponseData.Write((uint)result); } protected void MakeObject(ServiceCtx context, IpcService obj) diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/IUserServiceCreator.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/IUserServiceCreator.cs index 3e3a226ae..bbb0c3190 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/IUserServiceCreator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/IUserServiceCreator.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator; namespace Ryujinx.HLE.HOS.Services.Ldn { [Service("ldn:u")] - class IUserServiceCreator : IpcService + partial class IUserServiceCreator : IpcService { public IUserServiceCreator(ServiceCtx context) : base(context.Device.System.LdnServer) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/IServiceCreator.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/IServiceCreator.cs index 705e5f258..16b7da424 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/IServiceCreator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/IServiceCreator.cs @@ -2,7 +2,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p { [Service("lp2p:app")] // 9.0.0+ [Service("lp2p:sys")] // 9.0.0+ - class IServiceCreator : IpcService + partial class IServiceCreator : IpcService { public IServiceCreator(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfService.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfService.cs index 8f9f0e3e4..7533e3cd0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfService.cs @@ -2,7 +2,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p { - class ISfService : IpcService + partial class ISfService : IpcService { public ISfService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfServiceMonitor.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfServiceMonitor.cs index d3a8bead2..92181127c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfServiceMonitor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfServiceMonitor.cs @@ -6,7 +6,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p { - class ISfServiceMonitor : IpcService + partial class ISfServiceMonitor : IpcService { private readonly KEvent _stateChangeEvent; private readonly KEvent _jointEvent; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IClientProcessMonitor.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IClientProcessMonitor.cs index 349d51a3f..07b3eb757 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IClientProcessMonitor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IClientProcessMonitor.cs @@ -2,7 +2,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator { - class IClientProcessMonitor : DisposableIpcService + partial class IClientProcessMonitor : DisposableIpcService { public IClientProcessMonitor(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs index 71d1623f3..265528d07 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs @@ -23,7 +23,7 @@ using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator { - class IUserLocalCommunicationService : IpcService, IDisposable + partial class IUserLocalCommunicationService : IpcService, IDisposable { public INetworkClient NetworkClient { get; private set; } diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/IImageDatabaseService.cs b/src/Ryujinx.HLE/HOS/Services/Mii/IImageDatabaseService.cs index 88d7d7b3c..a36aad19a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/IImageDatabaseService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/IImageDatabaseService.cs @@ -3,7 +3,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Mii { [Service("miiimg")] // 5.0.0+ - class IImageDatabaseService : IpcService + partial class IImageDatabaseService : IpcService { private uint _imageCount; private bool _isDirty; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/IStaticService.cs b/src/Ryujinx.HLE/HOS/Services/Mii/IStaticService.cs index 8a6800024..a2713d3c1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/IStaticService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/IStaticService.cs @@ -6,7 +6,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii { [Service("mii:e", true)] [Service("mii:u", false)] - class IStaticService : IpcService + partial class IStaticService : IpcService { private readonly DatabaseImpl _databaseImpl; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs b/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs index 1a1c20d6e..715d49e8b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs @@ -6,7 +6,7 @@ using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Mii.StaticService { - abstract class IDatabaseService : IpcService + abstract partial class IDatabaseService : IpcService { [CommandCmif(0)] // IsUpdated(SourceFlag flag) -> bool diff --git a/src/Ryujinx.HLE/HOS/Services/Mnpp/IServiceForApplication.cs b/src/Ryujinx.HLE/HOS/Services/Mnpp/IServiceForApplication.cs index 8cdab6419..10010193a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mnpp/IServiceForApplication.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mnpp/IServiceForApplication.cs @@ -6,7 +6,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc; namespace Ryujinx.HLE.HOS.Services.Mnpp { [Service("mnpp:app")] // 13.0.0+ - class IServiceForApplication : IpcService + partial class IServiceForApplication : IpcService { public IServiceForApplication(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs b/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs index 35e311c4d..7a11166a1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs @@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager; namespace Ryujinx.HLE.HOS.Services.Ncm.Lr { [Service("lr")] - class ILocationResolverManager : IpcService + partial class ILocationResolverManager : IpcService { public ILocationResolverManager(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs b/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs index 71ed56385..c81d50869 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs @@ -6,7 +6,7 @@ using static Ryujinx.HLE.Utilities.StringUtils; namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager { - class ILocationResolver : IpcService + partial class ILocationResolver : IpcService { private readonly StorageId _storageId; diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/ISystemManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/ISystemManager.cs index be23d2cdc..2c1dc3af7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/ISystemManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/ISystemManager.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.NfcManager; namespace Ryujinx.HLE.HOS.Services.Nfc { [Service("nfc:sys")] - class ISystemManager : IpcService + partial class ISystemManager : IpcService { public ISystemManager(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/IUserManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/IUserManager.cs index 5b8afce79..24e9a1475 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/IUserManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/IUserManager.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.NfcManager; namespace Ryujinx.HLE.HOS.Services.Nfc { [Service("nfc:user")] - class IUserManager : IpcService + partial class IUserManager : IpcService { public IUserManager(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/IUserManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/IUserManager.cs index 53b6549c5..df8e298b6 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/IUserManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/IUserManager.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Mifare.MifareManager; namespace Ryujinx.HLE.HOS.Services.Nfc.Mifare { [Service("nfc:mf:u")] - class IUserManager : IpcService + partial class IUserManager : IpcService { public IUserManager(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/MifareManager/IMifare.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/MifareManager/IMifare.cs index 43e28b5cf..4a2a11609 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/MifareManager/IMifare.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/MifareManager/IMifare.cs @@ -14,7 +14,7 @@ using System.Threading.Tasks; namespace Ryujinx.HLE.HOS.Services.Nfc.Mifare.MifareManager { - class IMifare : IpcService + partial class IMifare : IpcService { private State _state; diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/INfc.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/INfc.cs index 72027cf48..635fe2a2a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/INfc.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/INfc.cs @@ -2,7 +2,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Nfc.NfcManager { - class INfc : IpcService + partial class INfc : IpcService { private readonly NfcPermissionLevel _permissionLevel; private State _state; diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IDebugManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IDebugManager.cs index b3eff0c2d..677f81127 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IDebugManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IDebugManager.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { [Service("nfp:dbg")] - class IAmManager : IpcService + partial class IAmManager : IpcService { public IAmManager(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ISystemManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ISystemManager.cs index 4cb541a6c..5d429d0ba 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ISystemManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ISystemManager.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { [Service("nfp:sys")] - class ISystemManager : IpcService + partial class ISystemManager : IpcService { public ISystemManager(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IUserManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IUserManager.cs index 229386c01..4cfc0c247 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IUserManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IUserManager.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { [Service("nfp:user")] - class IUserManager : IpcService + partial class IUserManager : IpcService { public IUserManager(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs index ca833e33d..5e12510a1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs @@ -16,7 +16,7 @@ using System.Threading.Tasks; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { - class INfp : IpcService + partial class INfp : IpcService { #pragma warning disable IDE0052 // Remove unread private member private ulong _appletResourceUserId; diff --git a/src/Ryujinx.HLE/HOS/Services/Ngct/IService.cs b/src/Ryujinx.HLE/HOS/Services/Ngct/IService.cs index d9ca70047..6925695c9 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ngct/IService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ngct/IService.cs @@ -1,7 +1,7 @@ namespace Ryujinx.HLE.HOS.Services.Ngct { [Service("ngct:u")] // 9.0.0+ - class IService : IpcService + partial class IService : IpcService { public IService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ngct/IServiceWithManagementApi.cs b/src/Ryujinx.HLE/HOS/Services/Ngct/IServiceWithManagementApi.cs index 88995335c..a5026e227 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ngct/IServiceWithManagementApi.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ngct/IServiceWithManagementApi.cs @@ -1,7 +1,7 @@ namespace Ryujinx.HLE.HOS.Services.Ngct { [Service("ngct:s")] // 9.0.0+ - class IServiceWithManagementApi : IpcService + partial class IServiceWithManagementApi : IpcService { public IServiceWithManagementApi(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs index d669caba1..dc69f19d3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs @@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm [Service("nifm:a")] // Max sessions: 2 [Service("nifm:s")] // Max sessions: 16 [Service("nifm:u")] // Max sessions: 5 - class IStaticService : IpcService + partial class IStaticService : IpcService { public IStaticService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs index dd4efce6e..3abb52b9b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs @@ -10,7 +10,7 @@ using System.Runtime.CompilerServices; namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService { - class IGeneralService : DisposableIpcService + partial class IGeneralService : DisposableIpcService { private readonly GeneralServiceDetail _generalServiceDetail; diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs index 577d03822..68ba510a2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs @@ -6,7 +6,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService { - class IRequest : IpcService + partial class IRequest : IpcService { private enum RequestState { diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServer.cs b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServer.cs index 4deecc531..9bdc8ea04 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServer.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceA namespace Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface { - class IShopServiceAccessServer : IpcService + partial class IShopServiceAccessServer : IpcService { public IShopServiceAccessServer() { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServerInterface.cs b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServerInterface.cs index d7e276ea0..213338299 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServerInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServerInterface.cs @@ -6,7 +6,7 @@ using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface; namespace Ryujinx.HLE.HOS.Services.Nim { [Service("nim:eca")] // 5.0.0+ - class IShopServiceAccessServerInterface : IpcService + partial class IShopServiceAccessServerInterface : IpcService { public IShopServiceAccessServerInterface(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessor.cs index c1f58a076..6ec5d8b13 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessor.cs @@ -7,7 +7,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer { - class IShopServiceAccessor : IpcService + partial class IShopServiceAccessor : IpcService { private readonly KEvent _event; diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs b/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs index ed6e4472e..ead72efe0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs @@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService; namespace Ryujinx.HLE.HOS.Services.Nim.Ntc { [Service("ntc")] - class IStaticService : IpcService + partial class IStaticService : IpcService { public IStaticService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs b/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs index 2bd6f4f0d..11247af1a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs @@ -6,7 +6,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService { - class IEnsureNetworkClockAvailabilityService : IpcService + partial class IEnsureNetworkClockAvailabilityService : IpcService { private readonly KEvent _finishNotificationEvent; private ResultCode _taskResultCode; diff --git a/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs b/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs index c77358803..cd4ab6d4e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs @@ -8,7 +8,7 @@ using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Ns.Aoc { [Service("aoc:u")] - class IAddOnContentManager : IpcService + partial class IAddOnContentManager : IpcService { private readonly KEvent _addOnContentListChangedEvent; private int _addOnContentListChangedEventHandle; diff --git a/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IPurchaseEventManager.cs b/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IPurchaseEventManager.cs index 8521adc6e..b01db8a35 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IPurchaseEventManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IPurchaseEventManager.cs @@ -6,7 +6,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Ns.Aoc { - class IPurchaseEventManager : IpcService + partial class IPurchaseEventManager : IpcService { private readonly KEvent _purchasedEvent; diff --git a/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs index f510da594..e9cca2935 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs @@ -4,7 +4,7 @@ using Ryujinx.Common.Utilities; namespace Ryujinx.HLE.HOS.Services.Ns { [Service("ns:am")] - class IApplicationManagerInterface : IpcService + partial class IApplicationManagerInterface : IpcService { public IApplicationManagerInterface(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs index ca7d42b48..a052c6d0e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs @@ -3,7 +3,7 @@ using LibHac.Ns; namespace Ryujinx.HLE.HOS.Services.Ns { - class IReadOnlyApplicationControlDataInterface : IpcService + partial class IReadOnlyApplicationControlDataInterface : IpcService { public IReadOnlyApplicationControlDataInterface(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ns/IServiceGetterInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ns/IServiceGetterInterface.cs index e45c6750c..bcca7278f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ns/IServiceGetterInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ns/IServiceGetterInterface.cs @@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns [Service("ns:rid")] [Service("ns:rt")] [Service("ns:web")] - class IServiceGetterInterface : IpcService + partial class IServiceGetterInterface : IpcService { public IServiceGetterInterface(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs index ed14b3e15..50e041766 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs @@ -24,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv [Service("nvdrv:a")] [Service("nvdrv:s")] [Service("nvdrv:t")] - class INvDrvServices : IpcService + partial class INvDrvServices : IpcService { private static readonly List _deviceFileDebugRegistry = [ @@ -32,20 +32,20 @@ namespace Ryujinx.HLE.HOS.Services.Nv "/dev/nvhost-prof-gpu" ]; - private static readonly Dictionary _deviceFileRegistry = new() + private static readonly Dictionary> _deviceFileRegistry = new() { - { "/dev/nvmap", typeof(NvMapDeviceFile) }, - { "/dev/nvhost-ctrl", typeof(NvHostCtrlDeviceFile) }, - { "/dev/nvhost-ctrl-gpu", typeof(NvHostCtrlGpuDeviceFile) }, - { "/dev/nvhost-as-gpu", typeof(NvHostAsGpuDeviceFile) }, - { "/dev/nvhost-gpu", typeof(NvHostGpuDeviceFile) }, - //{ "/dev/nvhost-msenc", typeof(NvHostChannelDeviceFile) }, - { "/dev/nvhost-nvdec", typeof(NvHostChannelDeviceFile) }, - //{ "/dev/nvhost-nvjpg", typeof(NvHostChannelDeviceFile) }, - { "/dev/nvhost-vic", typeof(NvHostChannelDeviceFile) }, - //{ "/dev/nvhost-display", typeof(NvHostChannelDeviceFile) }, - { "/dev/nvhost-dbg-gpu", typeof(NvHostDbgGpuDeviceFile) }, - { "/dev/nvhost-prof-gpu", typeof(NvHostProfGpuDeviceFile) }, + { "/dev/nvmap", (ctx, mem, owner) => new NvMapDeviceFile(ctx, mem, owner) }, + { "/dev/nvhost-ctrl", (ctx, mem, owner) => new NvHostCtrlDeviceFile(ctx, mem, owner) }, + { "/dev/nvhost-ctrl-gpu", (ctx, mem, owner) => new NvHostCtrlGpuDeviceFile(ctx, mem, owner) }, + { "/dev/nvhost-as-gpu", (ctx, mem, owner) => new NvHostAsGpuDeviceFile(ctx, mem, owner) }, + { "/dev/nvhost-gpu", (ctx, mem, owner) => new NvHostGpuDeviceFile(ctx, mem, owner) }, + //{ "/dev/nvhost-msenc", (ctx, mem, owner) => new NvHostChannelDeviceFile(ctx, mem, owner) }, + { "/dev/nvhost-nvdec", (ctx, mem, owner) => new NvHostChannelDeviceFile(ctx, mem, owner) }, + //{ "/dev/nvhost-nvjpg", (ctx, mem, owner) => new NvHostChannelDeviceFile(ctx, mem, owner) }, + { "/dev/nvhost-vic", (ctx, mem, owner) => new NvHostChannelDeviceFile(ctx, mem, owner) }, + //{ "/dev/nvhost-display", (ctx, mem, owner) => new NvHostChannelDeviceFile(ctx, mem, owner) }, + { "/dev/nvhost-dbg-gpu", (ctx, mem, owner) => new NvHostDbgGpuDeviceFile(ctx, mem, owner) }, + { "/dev/nvhost-prof-gpu", (ctx, mem, owner) => new NvHostProfGpuDeviceFile(ctx, mem, owner) }, }; private static readonly ArrayPool _byteArrayPool = ArrayPool.Create(); @@ -78,12 +78,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv return NvResult.NotSupported; } - if (_deviceFileRegistry.TryGetValue(path, out Type deviceFileClass)) + if (_deviceFileRegistry.TryGetValue(path, out Func deviceFileFactory)) { - ConstructorInfo constructor = deviceFileClass.GetConstructor([typeof(ServiceCtx), typeof(IVirtualMemoryManager), typeof(ulong) - ]); - - NvDeviceFile deviceFile = (NvDeviceFile)constructor.Invoke([context, _clientMemory, _owner]); + NvDeviceFile deviceFile = deviceFileFactory(context, _clientMemory, _owner); deviceFile.Path = path; diff --git a/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForApplication.cs b/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForApplication.cs index 1513d6fed..aac888272 100644 --- a/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForApplication.cs +++ b/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForApplication.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Olsc { [Service("olsc:u")] // 10.0.0+ - class IOlscServiceForApplication : IpcService + partial class IOlscServiceForApplication : IpcService { private bool _initialized; private Dictionary _saveDataBackupSettingDatabase; diff --git a/src/Ryujinx.HLE/HOS/Services/Pctl/IParentalControlServiceFactory.cs b/src/Ryujinx.HLE/HOS/Services/Pctl/IParentalControlServiceFactory.cs index 707f6423c..12938bf2b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pctl/IParentalControlServiceFactory.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pctl/IParentalControlServiceFactory.cs @@ -6,7 +6,7 @@ namespace Ryujinx.HLE.HOS.Services.Pctl [Service("pctl:a", 0x83BE)] [Service("pctl:r", 0x8040)] [Service("pctl:s", 0x838E)] - class IParentalControlServiceFactory : IpcService + partial class IParentalControlServiceFactory : IpcService { private readonly int _permissionFlag; diff --git a/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs b/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs index c36482e41..ddf7b21bd 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs @@ -5,7 +5,7 @@ using static LibHac.Ns.ApplicationControlProperty; namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory { - class IParentalControlService : IpcService + partial class IParentalControlService : IpcService { private readonly ulong _pid; private readonly int _permissionFlag; diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IRtcManager.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IRtcManager.cs index c37176845..7cab9a2a0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IRtcManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IRtcManager.cs @@ -3,7 +3,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Pcv.Bpc { [Service("bpc:r")] // 1.0.0 - 8.1.0 - class IRtcManager : IpcService + partial class IRtcManager : IpcService { public IRtcManager(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs index 5d90fcbe2..3bdfe9119 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs @@ -4,7 +4,7 @@ using System.Linq; namespace Ryujinx.HLE.HOS.Services.Pcv.Clkrst.ClkrstManager { - class IClkrstSession : IpcService + partial class IClkrstSession : IpcService { private readonly DeviceCode _deviceCode; #pragma warning disable IDE0052 // Remove unread private member diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs index c7c459196..228a3d632 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs @@ -8,7 +8,7 @@ namespace Ryujinx.HLE.HOS.Services.Pcv.Clkrst { [Service("clkrst")] // 8.0.0+ [Service("clkrst:i")] // 8.0.0+ - class IClkrstManager : IpcService + partial class IClkrstManager : IpcService { private int _moduleStateTableEventHandle = 0; diff --git a/src/Ryujinx.HLE/HOS/Services/Pm/IDebugMonitorInterface.cs b/src/Ryujinx.HLE/HOS/Services/Pm/IDebugMonitorInterface.cs index 9becc6e46..12fdad24f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pm/IDebugMonitorInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pm/IDebugMonitorInterface.cs @@ -6,7 +6,7 @@ using Ryujinx.Horizon.Common; namespace Ryujinx.HLE.HOS.Services.Pm { [Service("pm:dmnt")] - class IDebugMonitorInterface : IpcService + partial class IDebugMonitorInterface : IpcService { public IDebugMonitorInterface(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Pm/IInformationInterface.cs b/src/Ryujinx.HLE/HOS/Services/Pm/IInformationInterface.cs index d6440a4d1..e3277f3ff 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pm/IInformationInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pm/IInformationInterface.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Kernel.Process; namespace Ryujinx.HLE.HOS.Services.Pm { [Service("pm:info")] - class IInformationInterface : IpcService + partial class IInformationInterface : IpcService { public IInformationInterface(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Pm/IShellInterface.cs b/src/Ryujinx.HLE/HOS/Services/Pm/IShellInterface.cs index 1ee2c377f..9bac12bca 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pm/IShellInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pm/IShellInterface.cs @@ -1,7 +1,7 @@ namespace Ryujinx.HLE.HOS.Services.Pm { [Service("pm:shell")] - class IShellInterface : IpcService + partial class IShellInterface : IpcService { public IShellInterface(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmServer.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmServer.cs index 3ce502974..94536382f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmServer.cs @@ -3,7 +3,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Ptm.Psm { [Service("psm")] - class IPsmServer : IpcService + partial class IPsmServer : IpcService { public IPsmServer(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmSession.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmSession.cs index edfa60afd..3d737108d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmSession.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmSession.cs @@ -5,7 +5,7 @@ using Ryujinx.Horizon.Common; namespace Ryujinx.HLE.HOS.Services.Ptm.Psm { - class IPsmSession : IpcService + partial class IPsmSession : IpcService { private readonly KEvent _stateChangeEvent; private int _stateChangeEventHandle; diff --git a/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs index 873782d87..e8e80853e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs @@ -16,7 +16,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro { [Service("ldr:ro")] [Service("ro:1")] // 7.0.0+ - class IRoInterface : DisposableIpcService + partial class IRoInterface : DisposableIpcService { private const int MaxNrr = 0x40; private const int MaxNro = 0x40; diff --git a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/IQueryService.cs b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/IQueryService.cs index 6508794ab..ecc28e111 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/IQueryService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/IQueryService.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService; namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm { [Service("pdm:qry")] - class IQueryService : IpcService + partial class IQueryService : IpcService { public IQueryService(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Sdb/Pl/ISharedFontManager.cs b/src/Ryujinx.HLE/HOS/Services/Sdb/Pl/ISharedFontManager.cs index 45c4ce7e1..e8df8d2da 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sdb/Pl/ISharedFontManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sdb/Pl/ISharedFontManager.cs @@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl { [Service("pl:u")] [Service("pl:s")] // 9.0.0+ - class ISharedFontManager : IpcService + partial class ISharedFontManager : IpcService { private int _fontSharedMemHandle; diff --git a/src/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs b/src/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs index fef994bf8..68ca85df3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs @@ -6,7 +6,7 @@ using System.Text; namespace Ryujinx.HLE.HOS.Services.Settings { [Service("set")] - class ISettingsServer : IpcService + partial class ISettingsServer : IpcService { public ISettingsServer(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs b/src/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs index cfad2884a..7dc89b5f1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs @@ -15,7 +15,7 @@ using System.Text; namespace Ryujinx.HLE.HOS.Services.Settings { [Service("set:sys")] - class ISystemSettingsServer : IpcService + partial class ISystemSettingsServer : IpcService { public ISystemSettingsServer(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs b/src/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs index f19eeebfc..bf1ba5b8e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs @@ -4,37 +4,24 @@ using Ryujinx.HLE.HOS.Kernel; using Ryujinx.HLE.HOS.Kernel.Ipc; using Ryujinx.Horizon.Common; using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Reflection; using System.Text; namespace Ryujinx.HLE.HOS.Services.Sm { partial class IUserInterface : IpcService { - private static readonly Dictionary _services; - private readonly SmRegistry _registry; private readonly ServerBase _commonServer; private bool _isInitialized; - public IUserInterface(KernelContext context, SmRegistry registry) : base(registerTipc: true) + public IUserInterface(KernelContext context, SmRegistry registry) { _commonServer = new ServerBase(context, "CommonServer"); _registry = registry; } - static IUserInterface() - { - _services = typeof(IUserInterface).Assembly.GetTypes() - .SelectMany(type => type.GetCustomAttributes(typeof(ServiceAttribute), true) - .Select(service => (((ServiceAttribute)service).Name, type))) - .ToDictionary(service => service.Name, service => service.type); - } - [CommandCmif(0)] [CommandTipc(0)] // 12.0.0+ // Initialize(pid, u64 reserved) @@ -91,12 +78,8 @@ namespace Ryujinx.HLE.HOS.Services.Sm } else { - if (_services.TryGetValue(name, out Type type)) + if (GetServiceInstance(name, context) is { } service) { - ServiceAttribute serviceAttribute = type.GetCustomAttributes().First(service => service.Name == name); - - IpcService service = GetServiceInstance(type, context, serviceAttribute.Parameter); - service.TrySetServer(_commonServer); service.Server.AddSessionObj(session.ServerSession, service); } diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs index ef3b68b27..cb56be35b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs @@ -14,7 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { [Service("bsd:s", true)] [Service("bsd:u", false)] - class IClient : IpcService + partial class IClient : IpcService { private static readonly List _pollManagers = [ diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs index 9e13a005c..17ec989c2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs @@ -11,7 +11,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd { [Service("nsd:a")] // Max sessions: 5 [Service("nsd:u")] // Max sessions: 20 - class IManager : IpcService + partial class IManager : IpcService { public static readonly NsdSettings NsdSettings; private readonly FqdnResolver _fqdnResolver; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs index 80bdbec8a..2df19228d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs @@ -16,7 +16,7 @@ using System.Text; namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres { [Service("sfdnsres")] - class IResolver : IpcService + partial class IResolver : IpcService { public IResolver(ServiceCtx context) { diff --git a/src/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs b/src/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs index 6a9b4d442..725b27054 100644 --- a/src/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs @@ -10,7 +10,7 @@ namespace Ryujinx.HLE.HOS.Services.Spl [Service("spl:manu")] [Service("spl:mig")] [Service("spl:ssl")] - class IGeneralInterface : IpcService + partial class IGeneralInterface : IpcService { public IGeneralInterface(ServiceCtx context) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs b/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs index fc58613f5..65b482bf2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs @@ -3,7 +3,7 @@ using System.Security.Cryptography; namespace Ryujinx.HLE.HOS.Services.Spl { [Service("csrng")] - class IRandomInterface : DisposableIpcService + partial class IRandomInterface : DisposableIpcService { private readonly RandomNumberGenerator _rng; diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs index 3d8fb5d51..d796577dc 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs @@ -10,7 +10,7 @@ namespace Ryujinx.HLE.HOS.Services.Ssl { [Service("ssl")] [Service("ssl:s")] - class ISslService : IpcService + partial class ISslService : IpcService { // NOTE: The SSL service is used by games to connect it to various official online services, which we do not intend to support. // In this case it is acceptable to stub all calls of the service. diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs index 623990a58..830eb635a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs @@ -8,7 +8,7 @@ using System.Text; namespace Ryujinx.HLE.HOS.Services.Ssl.SslService { - class ISslConnection : IpcService, IDisposable + partial class ISslConnection : IpcService, IDisposable { private bool _doNotClockSocket; private bool _getServerCertChain; diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs index 7b371d299..d86c87bd0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs @@ -4,7 +4,7 @@ using System.Text; namespace Ryujinx.HLE.HOS.Services.Ssl.SslService { - class ISslContext : IpcService + partial class ISslContext : IpcService { private uint _connectionCount; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs index e23e6fa3f..9a3da9571 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs @@ -6,7 +6,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { - abstract class IHOSBinderDriver : IpcService + abstract partial class IHOSBinderDriver : IpcService { public IHOSBinderDriver() { } diff --git a/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs b/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs index eaddf9cff..2c2c63f9f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs @@ -10,7 +10,7 @@ namespace Ryujinx.HLE.HOS.Services.Time [Service("time:a", TimePermissions.Admin)] [Service("time:r", TimePermissions.Repair)] [Service("time:u", TimePermissions.User)] - class IStaticServiceForGlue : IpcService + partial class IStaticServiceForGlue : IpcService { private readonly IStaticServiceForPsc _inner; private readonly TimePermissions _permissions; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs b/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs index a6b33e4ae..53cd1b87e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs @@ -16,7 +16,7 @@ namespace Ryujinx.HLE.HOS.Services.Time { [Service("time:s", TimePermissions.System)] [Service("time:su", TimePermissions.SystemUpdate)] - class IStaticServiceForPsc : IpcService + partial class IStaticServiceForPsc : IpcService { private readonly TimeManager _timeManager; private readonly TimePermissions _permissions; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs b/src/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs index 1648aa3e1..3abee97df 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs @@ -11,7 +11,7 @@ using System.IO; namespace Ryujinx.HLE.HOS.Services.Time { [Service("time:m")] // 9.0.0+ - class ITimeServiceManager : IpcService + partial class ITimeServiceManager : IpcService { private readonly TimeManager _timeManager; private int _automaticCorrectionEvent; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ISteadyClock.cs b/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ISteadyClock.cs index 8ddb646b9..6c99bf683 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ISteadyClock.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ISteadyClock.cs @@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Time.Clock; namespace Ryujinx.HLE.HOS.Services.Time.StaticService { - class ISteadyClock : IpcService + partial class ISteadyClock : IpcService { private readonly SteadyClockCore _steadyClock; private readonly bool _writePermission; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ISystemClock.cs b/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ISystemClock.cs index ada5f057a..47bcfc802 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ISystemClock.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ISystemClock.cs @@ -8,7 +8,7 @@ using System; namespace Ryujinx.HLE.HOS.Services.Time.StaticService { - class ISystemClock : IpcService + partial class ISystemClock : IpcService { private readonly SystemClockCore _clockCore; private readonly bool _writePermission; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs b/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs index 81944c835..028506a3e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs @@ -10,7 +10,7 @@ using System.Text; namespace Ryujinx.HLE.HOS.Services.Time.StaticService { - class ITimeZoneServiceForGlue : IpcService + partial class ITimeZoneServiceForGlue : IpcService { private readonly TimeZoneContentManager _timeZoneContentManager; private readonly ITimeZoneServiceForPsc _inner; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs b/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs index b18a4f76c..245a5a050 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs @@ -12,7 +12,7 @@ using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.StaticService { - class ITimeZoneServiceForPsc : IpcService + partial class ITimeZoneServiceForPsc : IpcService { private readonly TimeZoneManager _timeZoneManager; private readonly bool _writePermission; diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/IApplicationRootService.cs b/src/Ryujinx.HLE/HOS/Services/Vi/IApplicationRootService.cs index 9cc9d421f..385ef486e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/IApplicationRootService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/IApplicationRootService.cs @@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Vi.Types; namespace Ryujinx.HLE.HOS.Services.Vi { [Service("vi:u")] - class IApplicationRootService : IpcService + partial class IApplicationRootService : IpcService { public IApplicationRootService(ServiceCtx context) : base(context.Device.System.ViServer) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/IManagerRootService.cs b/src/Ryujinx.HLE/HOS/Services/Vi/IManagerRootService.cs index dd4b25a08..0ef80b196 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/IManagerRootService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/IManagerRootService.cs @@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Vi.Types; namespace Ryujinx.HLE.HOS.Services.Vi { [Service("vi:m")] - class IManagerRootService : IpcService + partial class IManagerRootService : IpcService { // vi:u/m/s aren't on 3 separate threads but we can't put them together with the current ServerBase public IManagerRootService(ServiceCtx context) : base(context.Device.System.ViServerM) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/ISystemRootService.cs b/src/Ryujinx.HLE/HOS/Services/Vi/ISystemRootService.cs index b2415f2e4..974684d36 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/ISystemRootService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/ISystemRootService.cs @@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Vi.Types; namespace Ryujinx.HLE.HOS.Services.Vi { [Service("vi:s")] - class ISystemRootService : IpcService + partial class ISystemRootService : IpcService { // vi:u/m/s aren't on 3 separate threads but we can't put them together with the current ServerBase public ISystemRootService(ServiceCtx context) : base(context.Device.System.ViServerS) { } diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs index 0e5d103d1..5a3780bb6 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs @@ -2,7 +2,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService { - class IManagerDisplayService : IpcService + partial class IManagerDisplayService : IpcService { private readonly IApplicationDisplayService _applicationDisplayService; diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/ISystemDisplayService.cs b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/ISystemDisplayService.cs index 507290692..0140c0ee1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/ISystemDisplayService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/ISystemDisplayService.cs @@ -2,7 +2,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService { - class ISystemDisplayService : IpcService + partial class ISystemDisplayService : IpcService { private readonly IApplicationDisplayService _applicationDisplayService; diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs index 99c640aa0..c5cc05610 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs @@ -17,7 +17,7 @@ using System.Text; namespace Ryujinx.HLE.HOS.Services.Vi.RootService { - class IApplicationDisplayService : IpcService + partial class IApplicationDisplayService : IpcService { private readonly ViServiceType _serviceType; diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs index ce1b91cec..b93efbe43 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs @@ -1,7 +1,5 @@ using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Operations; -using System; -using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { @@ -71,53 +69,42 @@ namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters throw new TamperCompilationException($"Invalid right-hand side switch {rightHandSideIsImmediate} in Atmosphere cheat"); } - void Emit(Type operationType, IOperand rhs = null) + void EmitCore(IOperand rhs = null) where TOp : IOperationFactory { - List operandList = - [ - destinationRegister, - leftHandSideRegister - ]; - - if (rhs != null) - { - operandList.Add(rhs); - } - - InstructionHelper.Emit(operationType, operationWidth, context, operandList.ToArray()); + InstructionHelper.Emit(operationWidth, context, destinationRegister, leftHandSideRegister, rhs); } switch (operation) { case Add: - Emit(typeof(OpAdd<>), rightHandSideOperand); + EmitCore(rightHandSideOperand); break; case Sub: - Emit(typeof(OpSub<>), rightHandSideOperand); + EmitCore(rightHandSideOperand); break; case Mul: - Emit(typeof(OpMul<>), rightHandSideOperand); + EmitCore(rightHandSideOperand); break; case Lsh: - Emit(typeof(OpLsh<>), rightHandSideOperand); + EmitCore(rightHandSideOperand); break; case Rsh: - Emit(typeof(OpRsh<>), rightHandSideOperand); + EmitCore(rightHandSideOperand); break; case And: - Emit(typeof(OpAnd<>), rightHandSideOperand); + EmitCore(rightHandSideOperand); break; case Or: - Emit(typeof(OpOr<>), rightHandSideOperand); + EmitCore(rightHandSideOperand); break; case Not: - Emit(typeof(OpNot<>)); + EmitCore(); break; case Xor: - Emit(typeof(OpXor<>), rightHandSideOperand); + EmitCore(rightHandSideOperand); break; case Mov: - Emit(typeof(OpMov<>)); + EmitCore(); break; default: throw new TamperCompilationException($"Invalid arithmetic operation {operation} in Atmosphere cheat"); diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs index d74a998f4..771b87d1a 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs @@ -1,5 +1,6 @@ using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Operations; +using System; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { @@ -81,7 +82,15 @@ namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters throw new TamperCompilationException($"Invalid operand type {operandType} in Atmosphere cheat"); } - InstructionHelper.Emit(typeof(OpLog<>), operationWidth, context, logId, sourceOperand); + IOperation op = operationWidth switch + { + 1 => new OpLog(logId, sourceOperand), + 2 => new OpLog(logId, sourceOperand), + 4 => new OpLog(logId, sourceOperand), + 8 => new OpLog(logId, sourceOperand), + _ => throw new NotSupportedException(), + }; + InstructionHelper.Emit(op, context); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs index 3f222864f..ba1acb172 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs @@ -37,27 +37,27 @@ namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters ulong immediate = InstructionHelper.GetImmediate(instruction, ValueImmediateIndex, ValueImmediateSize); Value rightHandSideValue = new(immediate); - void Emit(Type operationType) + void EmitCore() where TOp : IOperationFactory { - InstructionHelper.Emit(operationType, operationWidth, context, register, register, rightHandSideValue); + InstructionHelper.Emit(operationWidth, context, register, register, rightHandSideValue); } switch (operation) { case Add: - Emit(typeof(OpAdd<>)); + EmitCore(); break; case Sub: - Emit(typeof(OpSub<>)); + EmitCore(); break; case Mul: - Emit(typeof(OpMul<>)); + EmitCore(); break; case Lsh: - Emit(typeof(OpLsh<>)); + EmitCore(); break; case Rsh: - Emit(typeof(OpRsh<>)); + EmitCore(); break; default: throw new TamperCompilationException($"Invalid arithmetic operation {operation} in Atmosphere cheat"); diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs index 3440efcec..45448b99d 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs @@ -1,4 +1,5 @@ using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { @@ -52,7 +53,7 @@ namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters throw new TamperCompilationException($"Invalid source mode {useDestinationAsSourceIndex} in Atmosphere cheat"); } - InstructionHelper.EmitMov(operationWidth, context, destinationRegister, sourceMemory); + InstructionHelper.Emit(operationWidth, context, destinationRegister, sourceMemory, null); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs index 537166798..25e39bd71 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs @@ -1,3 +1,5 @@ +using Ryujinx.HLE.HOS.Tamper.Operations; + namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { /// @@ -35,7 +37,7 @@ namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters ulong valueImmediate = InstructionHelper.GetImmediate(instruction, ValueImmediateIndex, valueImmediateSize); Value storeValue = new(valueImmediate); - InstructionHelper.EmitMov(operationWidth, context, dstMem, storeValue); + InstructionHelper.Emit(operationWidth, context, dstMem, storeValue, null); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs index 27a99bb63..bb53f3a7b 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs @@ -51,7 +51,7 @@ namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters throw new TamperCompilationException($"Invalid offset mode {useOffsetRegister} in Atmosphere cheat"); } - InstructionHelper.EmitMov(operationWidth, context, destinationMemory, storeValue); + InstructionHelper.Emit(operationWidth, context, destinationMemory, storeValue, null); switch (incrementAddressRegister) { diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs index d7f3045bc..a64b4ebbc 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs @@ -79,7 +79,7 @@ namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters throw new TamperCompilationException($"Invalid offset type {offsetType} in Atmosphere cheat"); } - InstructionHelper.EmitMov(operationWidth, context, destinationMemory, sourceRegister); + InstructionHelper.Emit(operationWidth, context, destinationMemory, sourceRegister, null); switch (incrementAddressRegister) { diff --git a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondEQ.cs b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondEQ.cs index 529ed25b6..897170864 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondEQ.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondEQ.cs @@ -1,8 +1,16 @@ using Ryujinx.HLE.HOS.Tamper.Operations; +using System.Numerics; namespace Ryujinx.HLE.HOS.Tamper.Conditions { - class CondEQ : ICondition where T : unmanaged + sealed class CondEQFactory : IConditionFactory + { + private CondEQFactory() { } + + public static ICondition CreateFor(IOperand lhs, IOperand rhs) where T : unmanaged, INumber + => new CondEQ(lhs, rhs); + } + class CondEQ : ICondition where T : unmanaged, INumber { private readonly IOperand _lhs; private readonly IOperand _rhs; @@ -15,7 +23,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Conditions public bool Evaluate() { - return (dynamic)_lhs.Get() == (dynamic)_rhs.Get(); + return _lhs.Get() == _rhs.Get(); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondGE.cs b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondGE.cs index 94877c2a6..7442d1f63 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondGE.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondGE.cs @@ -1,8 +1,16 @@ using Ryujinx.HLE.HOS.Tamper.Operations; +using System.Numerics; namespace Ryujinx.HLE.HOS.Tamper.Conditions { - class CondGE : ICondition where T : unmanaged + sealed class CondGEFactory : IConditionFactory + { + private CondGEFactory() { } + + public static ICondition CreateFor(IOperand lhs, IOperand rhs) where T : unmanaged, INumber + => new CondGE(lhs, rhs); + } + class CondGE : ICondition where T : unmanaged, INumber { private readonly IOperand _lhs; private readonly IOperand _rhs; @@ -15,7 +23,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Conditions public bool Evaluate() { - return (dynamic)_lhs.Get() >= (dynamic)_rhs.Get(); + return _lhs.Get() >= _rhs.Get(); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondGT.cs b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondGT.cs index 350688164..7b631b887 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondGT.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondGT.cs @@ -1,8 +1,16 @@ using Ryujinx.HLE.HOS.Tamper.Operations; +using System.Numerics; namespace Ryujinx.HLE.HOS.Tamper.Conditions { - class CondGT : ICondition where T : unmanaged + sealed class CondGTFactory : IConditionFactory + { + private CondGTFactory() { } + + public static ICondition CreateFor(IOperand lhs, IOperand rhs) where T : unmanaged, INumber + => new CondGT(lhs, rhs); + } + class CondGT : ICondition where T : unmanaged, INumber { private readonly IOperand _lhs; private readonly IOperand _rhs; @@ -15,7 +23,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Conditions public bool Evaluate() { - return (dynamic)_lhs.Get() > (dynamic)_rhs.Get(); + return _lhs.Get() > _rhs.Get(); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondLE.cs b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondLE.cs index dd9cf70cc..81bdb4056 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondLE.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondLE.cs @@ -1,8 +1,16 @@ using Ryujinx.HLE.HOS.Tamper.Operations; +using System.Numerics; namespace Ryujinx.HLE.HOS.Tamper.Conditions { - class CondLE : ICondition where T : unmanaged + sealed class CondLEFactory : IConditionFactory + { + private CondLEFactory() { } + + public static ICondition CreateFor(IOperand lhs, IOperand rhs) where T : unmanaged, INumber + => new CondLE(lhs, rhs); + } + class CondLE : ICondition where T : unmanaged, INumber { private readonly IOperand _lhs; private readonly IOperand _rhs; @@ -15,7 +23,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Conditions public bool Evaluate() { - return (dynamic)_lhs.Get() <= (dynamic)_rhs.Get(); + return _lhs.Get() <= _rhs.Get(); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondLT.cs b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondLT.cs index 0c85f5e47..980ab8515 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondLT.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondLT.cs @@ -1,8 +1,16 @@ using Ryujinx.HLE.HOS.Tamper.Operations; +using System.Numerics; namespace Ryujinx.HLE.HOS.Tamper.Conditions { - class CondLT : ICondition where T : unmanaged + sealed class CondLTFactory : IConditionFactory + { + private CondLTFactory() { } + + public static ICondition CreateFor(IOperand lhs, IOperand rhs) where T : unmanaged, INumber + => new CondLT(lhs, rhs); + } + class CondLT : ICondition where T : unmanaged, INumber { private readonly IOperand _lhs; private readonly IOperand _rhs; @@ -15,7 +23,10 @@ namespace Ryujinx.HLE.HOS.Tamper.Conditions public bool Evaluate() { - return (dynamic)_lhs.Get() < (dynamic)_rhs.Get(); + return _lhs.Get() < _rhs.Get(); } + + public static ICondition CreateFor(IOperand lhs, IOperand rhs) where T1 : INumber + => new CondLT(lhs, rhs); } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondNE.cs b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondNE.cs index b649eccee..0cbd62a54 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondNE.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Conditions/CondNE.cs @@ -1,8 +1,16 @@ using Ryujinx.HLE.HOS.Tamper.Operations; +using System.Numerics; namespace Ryujinx.HLE.HOS.Tamper.Conditions { - class CondNE : ICondition where T : unmanaged + sealed class CondNEFactory : IConditionFactory + { + private CondNEFactory() { } + + public static ICondition CreateFor(IOperand lhs, IOperand rhs) where T : unmanaged, INumber + => new CondNE(lhs, rhs); + } + class CondNE : ICondition where T : unmanaged, INumber { private readonly IOperand _lhs; private readonly IOperand _rhs; @@ -15,7 +23,10 @@ namespace Ryujinx.HLE.HOS.Tamper.Conditions public bool Evaluate() { - return (dynamic)_lhs.Get() != (dynamic)_rhs.Get(); + return _lhs.Get() != _rhs.Get(); } + + public static ICondition CreateFor(IOperand lhs, IOperand rhs) where T1 : INumber + => new CondNE(lhs, rhs); } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Conditions/IConditionFactory.cs b/src/Ryujinx.HLE/HOS/Tamper/Conditions/IConditionFactory.cs new file mode 100644 index 000000000..af0886307 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Tamper/Conditions/IConditionFactory.cs @@ -0,0 +1,10 @@ +using Ryujinx.HLE.HOS.Tamper.Operations; +using System.Numerics; + +namespace Ryujinx.HLE.HOS.Tamper.Conditions +{ + interface IConditionFactory + { + static abstract ICondition CreateFor(IOperand lhs, IOperand rhs) where T : unmanaged, INumber; + } +} diff --git a/src/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs b/src/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs index 46e4fd9f7..76409945e 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs @@ -15,46 +15,47 @@ namespace Ryujinx.HLE.HOS.Tamper context.CurrentOperations.Add(operation); } - public static void Emit(Type instruction, byte width, CompilationContext context, params Object[] operands) + public static void Emit(byte width, CompilationContext context, IOperand destination, IOperand lhs, IOperand rhs) where TOp : IOperationFactory { - Emit((IOperation)Create(instruction, width, operands), context); - } - - public static void EmitMov(byte width, CompilationContext context, IOperand destination, IOperand source) - { - Emit(typeof(OpMov<>), width, context, destination, source); + Emit(Create(width, destination, lhs, rhs), context); } public static ICondition CreateCondition(Comparison comparison, byte width, IOperand lhs, IOperand rhs) { - ICondition Create(Type conditionType) + ICondition CreateCore() where TOp : IConditionFactory { - return (ICondition)InstructionHelper.Create(conditionType, width, lhs, rhs); + return width switch + { + 1 => TOp.CreateFor(lhs, rhs), + 2 => TOp.CreateFor(lhs, rhs), + 4 => TOp.CreateFor(lhs, rhs), + 8 => TOp.CreateFor(lhs, rhs), + _ => throw new NotSupportedException(), + }; } return comparison switch { - Comparison.Greater => Create(typeof(CondGT<>)), - Comparison.GreaterOrEqual => Create(typeof(CondGE<>)), - Comparison.Less => Create(typeof(CondLT<>)), - Comparison.LessOrEqual => Create(typeof(CondLE<>)), - Comparison.Equal => Create(typeof(CondEQ<>)), - Comparison.NotEqual => Create(typeof(CondNE<>)), + Comparison.Greater => CreateCore(), + Comparison.GreaterOrEqual => CreateCore(), + Comparison.Less => CreateCore(), + Comparison.LessOrEqual => CreateCore(), + Comparison.Equal => CreateCore(), + Comparison.NotEqual => CreateCore(), _ => throw new TamperCompilationException($"Invalid comparison {comparison} in Atmosphere cheat"), }; } - public static Object Create(Type instruction, byte width, params Object[] operands) + public static IOperation Create(byte width, IOperand destination, IOperand lhs, IOperand rhs) where TOp : IOperationFactory { - Type realType = width switch + return width switch { - 1 => instruction.MakeGenericType(typeof(byte)), - 2 => instruction.MakeGenericType(typeof(ushort)), - 4 => instruction.MakeGenericType(typeof(uint)), - 8 => instruction.MakeGenericType(typeof(ulong)), - _ => throw new TamperCompilationException($"Invalid instruction width {width} in Atmosphere cheat"), + 1 => TOp.CreateFor(destination, lhs, rhs), + 2 => TOp.CreateFor(destination, lhs, rhs), + 4 => TOp.CreateFor(destination, lhs, rhs), + 8 => TOp.CreateFor(destination, lhs, rhs), + _ => throw new NotSupportedException(), }; - return Activator.CreateInstance(realType, operands); } public static ulong GetImmediate(byte[] instruction, int index, int nybbleCount) diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperand.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperand.cs index 1aadda0bf..d7345d727 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperand.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperand.cs @@ -1,8 +1,10 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { interface IOperand { - public T Get() where T : unmanaged; - public void Set(T value) where T : unmanaged; + public T Get() where T : unmanaged, INumber; + public void Set(T value) where T : unmanaged, INumber; } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperation.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperation.cs index a4474979c..7ffbb4a9a 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperation.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperation.cs @@ -1,3 +1,6 @@ +using System; +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { interface IOperation diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperationFactory.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperationFactory.cs new file mode 100644 index 000000000..85f7c90c0 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/IOperationFactory.cs @@ -0,0 +1,10 @@ +using System; +using System.Numerics; + +namespace Ryujinx.HLE.HOS.Tamper.Operations +{ + interface IOperationFactory + { + static abstract IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger; + } +} diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpAdd.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpAdd.cs index 855245e34..9cbf44b12 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpAdd.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpAdd.cs @@ -1,6 +1,15 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpAdd : IOperation where T : unmanaged + sealed class OpAddFactory : IOperationFactory + { + private OpAddFactory() { } + + public static IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger + => new OpAdd(destination, lhs, rhs); + } + class OpAdd : IOperation where T : unmanaged, INumber { readonly IOperand _destination; readonly IOperand _lhs; @@ -15,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Operations public void Execute() { - _destination.Set((T)((dynamic)_lhs.Get() + (dynamic)_rhs.Get())); + _destination.Set(_lhs.Get() + _rhs.Get()); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpAnd.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpAnd.cs index 7d1fa10b9..5e623702c 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpAnd.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpAnd.cs @@ -1,6 +1,15 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpAnd : IOperation where T : unmanaged + sealed class OpAndFactory : IOperationFactory + { + private OpAndFactory() { } + + public static IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger + => new OpAnd(destination, lhs, rhs); + } + class OpAnd : IOperation where T : unmanaged, IBinaryNumber { readonly IOperand _destination; readonly IOperand _lhs; @@ -15,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Operations public void Execute() { - _destination.Set((T)((dynamic)_lhs.Get() & (dynamic)_rhs.Get())); + _destination.Set(_lhs.Get() & _rhs.Get()); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpLog.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpLog.cs index 4017e5f75..b33431330 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpLog.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpLog.cs @@ -1,8 +1,9 @@ using Ryujinx.Common.Logging; +using System.Numerics; namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpLog : IOperation where T : unmanaged + class OpLog : IOperation where T : unmanaged, INumber { readonly int _logId; readonly IOperand _source; @@ -15,7 +16,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Operations public void Execute() { - Logger.Debug?.Print(LogClass.TamperMachine, $"Tamper debug log id={_logId} value={(dynamic)_source.Get():X}"); + Logger.Debug?.Print(LogClass.TamperMachine, $"Tamper debug log id={_logId} value={_source.Get():X}"); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpLsh.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpLsh.cs index 6c846425f..18156f1ff 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpLsh.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpLsh.cs @@ -1,6 +1,15 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpLsh : IOperation where T : unmanaged + sealed class OpLshFactory : IOperationFactory + { + private OpLshFactory() { } + + public static IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger + => new OpLsh(destination, lhs, rhs); + } + class OpLsh : IOperation where T : unmanaged, IBinaryInteger { readonly IOperand _destination; readonly IOperand _lhs; @@ -15,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Operations public void Execute() { - _destination.Set((T)((dynamic)_lhs.Get() << (dynamic)_rhs.Get())); + _destination.Set(_lhs.Get() << int.CreateTruncating(_rhs.Get())); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpMov.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpMov.cs index af82f18e0..13c3009a3 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpMov.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpMov.cs @@ -1,6 +1,15 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpMov : IOperation where T : unmanaged + sealed class OpMovFactory : IOperationFactory + { + private OpMovFactory() { } + + public static IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger + => new OpMov(destination, lhs); + } + class OpMov : IOperation where T : unmanaged, INumber { readonly IOperand _destination; readonly IOperand _source; diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpMul.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpMul.cs index a1b080f00..f760447b8 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpMul.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpMul.cs @@ -1,6 +1,15 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpMul : IOperation where T : unmanaged + sealed class OpMulFactory : IOperationFactory + { + private OpMulFactory() { } + + public static IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger + => new OpMul(destination, lhs, rhs); + } + class OpMul : IOperation where T : unmanaged, INumber { readonly IOperand _destination; readonly IOperand _lhs; @@ -15,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Operations public void Execute() { - _destination.Set((T)((dynamic)_lhs.Get() * (dynamic)_rhs.Get())); + _destination.Set(_lhs.Get() * _rhs.Get()); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpNot.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpNot.cs index 034e22008..56f9c3f82 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpNot.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpNot.cs @@ -1,6 +1,15 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpNot : IOperation where T : unmanaged + sealed class OpNotFactory : IOperationFactory + { + private OpNotFactory() { } + + public static IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger + => new OpNot(destination, lhs); + } + class OpNot : IOperation where T : unmanaged, IBinaryNumber { readonly IOperand _destination; readonly IOperand _source; @@ -13,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Operations public void Execute() { - _destination.Set((T)(~(dynamic)_source.Get())); + _destination.Set(~_source.Get()); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpOr.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpOr.cs index 0afdc3f4b..4e47dacd4 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpOr.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpOr.cs @@ -1,6 +1,15 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpOr : IOperation where T : unmanaged + sealed class OpOrFactory : IOperationFactory + { + private OpOrFactory() { } + + public static IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger + => new OpOr(destination, lhs, rhs); + } + class OpOr : IOperation where T : unmanaged, IBinaryNumber { readonly IOperand _destination; readonly IOperand _lhs; @@ -15,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Operations public void Execute() { - _destination.Set((T)((dynamic)_lhs.Get() | (dynamic)_rhs.Get())); + _destination.Set(_lhs.Get() | _rhs.Get()); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpRsh.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpRsh.cs index e7e0f870e..d40b29ee8 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpRsh.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpRsh.cs @@ -1,6 +1,15 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpRsh : IOperation where T : unmanaged + sealed class OpRshFactory : IOperationFactory + { + private OpRshFactory() { } + + public static IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger + => new OpRsh(destination, lhs, rhs); + } + class OpRsh : IOperation where T : unmanaged, IBinaryInteger { readonly IOperand _destination; readonly IOperand _lhs; @@ -15,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Operations public void Execute() { - _destination.Set((T)((dynamic)_lhs.Get() >> (dynamic)_rhs.Get())); + _destination.Set(_lhs.Get() >> int.CreateTruncating(_rhs.Get())); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpSub.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpSub.cs index d860d66fd..9f76b1ffd 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpSub.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpSub.cs @@ -1,6 +1,15 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpSub : IOperation where T : unmanaged + sealed class OpSubFactory : IOperationFactory + { + private OpSubFactory() { } + + public static IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger + => new OpSub(destination, lhs, rhs); + } + class OpSub : IOperation where T : unmanaged, INumber { readonly IOperand _destination; readonly IOperand _lhs; @@ -15,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Operations public void Execute() { - _destination.Set((T)((dynamic)_lhs.Get() - (dynamic)_rhs.Get())); + _destination.Set(_lhs.Get() - _rhs.Get()); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpXor.cs b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpXor.cs index 07ba6b335..8a820f4a1 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Operations/OpXor.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Operations/OpXor.cs @@ -1,6 +1,15 @@ +using System.Numerics; + namespace Ryujinx.HLE.HOS.Tamper.Operations { - class OpXor : IOperation where T : unmanaged + sealed class OpXorFactory : IOperationFactory + { + private OpXorFactory() { } + + public static IOperation CreateFor(IOperand destination, IOperand lhs, IOperand rhs) where T : unmanaged, IBinaryInteger + => new OpXor(destination, lhs, rhs); + } + class OpXor : IOperation where T : unmanaged, IBinaryNumber { readonly IOperand _destination; readonly IOperand _lhs; @@ -15,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Operations public void Execute() { - _destination.Set((T)((dynamic)_lhs.Get() ^ (dynamic)_rhs.Get())); + _destination.Set(_lhs.Get() ^ _rhs.Get()); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Pointer.cs b/src/Ryujinx.HLE/HOS/Tamper/Pointer.cs index c961e1a7d..aeb7fcf62 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Pointer.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Pointer.cs @@ -1,5 +1,6 @@ using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Tamper.Operations; +using System.Numerics; using System.Runtime.CompilerServices; namespace Ryujinx.HLE.HOS.Tamper @@ -15,12 +16,12 @@ namespace Ryujinx.HLE.HOS.Tamper _process = process; } - public T Get() where T : unmanaged + public T Get() where T : unmanaged, INumber { return _process.ReadMemory(_position.Get()); } - public void Set(T value) where T : unmanaged + public void Set(T value) where T : unmanaged, INumber { ulong position = _position.Get(); diff --git a/src/Ryujinx.HLE/HOS/Tamper/Register.cs b/src/Ryujinx.HLE/HOS/Tamper/Register.cs index cce13ee69..69b1d14b6 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Register.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Register.cs @@ -1,5 +1,6 @@ using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Tamper.Operations; +using System.Numerics; namespace Ryujinx.HLE.HOS.Tamper { @@ -13,16 +14,16 @@ namespace Ryujinx.HLE.HOS.Tamper _alias = alias; } - public T Get() where T : unmanaged + public T Get() where T : unmanaged, INumber { - return (T)(dynamic)_register; + return T.CreateTruncating(_register); } - public void Set(T value) where T : unmanaged + public void Set(T value) where T : unmanaged, INumber { Logger.Debug?.Print(LogClass.TamperMachine, $"{_alias}: {value}"); - _register = (ulong)(dynamic)value; + _register = ulong.CreateTruncating(value); } } } diff --git a/src/Ryujinx.HLE/HOS/Tamper/Value.cs b/src/Ryujinx.HLE/HOS/Tamper/Value.cs index 436fc13d3..8e72d7c0b 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Value.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Value.cs @@ -1,8 +1,9 @@ using Ryujinx.HLE.HOS.Tamper.Operations; +using System.Numerics; namespace Ryujinx.HLE.HOS.Tamper { - class Value : IOperand where TP : unmanaged + class Value : IOperand where TP : unmanaged, INumber { private TP _value; @@ -11,14 +12,14 @@ namespace Ryujinx.HLE.HOS.Tamper _value = value; } - public T Get() where T : unmanaged + public T Get() where T : unmanaged, INumber { - return (T)(dynamic)_value; + return T.CreateTruncating(_value); } - public void Set(T value) where T : unmanaged + public void Set(T value) where T : unmanaged, INumber { - _value = (TP)(dynamic)value; + _value = TP.CreateTruncating(value); } } } diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index 489b2c313..3d9d60960 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -26,18 +26,6 @@ true false true - partial - - - - - - true @@ -177,4 +165,7 @@ + + + diff --git a/src/Ryujinx/TrimmerRootDescriptor.xml b/src/Ryujinx/TrimmerRootDescriptor.xml new file mode 100644 index 000000000..7ba5de5ed --- /dev/null +++ b/src/Ryujinx/TrimmerRootDescriptor.xml @@ -0,0 +1,3 @@ + + + diff --git a/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs b/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs index fb0bd5e82..0107e6536 100644 --- a/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs +++ b/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs @@ -16,6 +16,7 @@ using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS.Services.Account.Acc; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; using UserId = Ryujinx.HLE.HOS.Services.Account.Acc.UserId; @@ -59,7 +60,7 @@ namespace Ryujinx.Ava.UI.Controls LoadProfiles(); } - public void Navigate(Type sourcePageType, object parameter) + public void Navigate([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type sourcePageType, object parameter) => ContentFrame.Navigate(sourcePageType, parameter); public static async Task Show( diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index ae84a15a2..b140f5681 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -1407,8 +1407,8 @@ namespace Ryujinx.Ava.UI.ViewModels public void SetGridMode() => Glyph = Glyph.Grid; - public void SetAspectRatio(AspectRatio aspectRatio) => - ConfigurationState.Instance.Graphics.AspectRatio.Value = aspectRatio; + public void SetAspectRatio(object aspectRatio) => + ConfigurationState.Instance.Graphics.AspectRatio.Value = (AspectRatio)aspectRatio; public async Task InstallFirmwareFromFile() { diff --git a/src/Ryujinx/Utilities/ValueFormatUtils.cs b/src/Ryujinx/Utilities/ValueFormatUtils.cs index 39723f511..e3d7e8a4a 100644 --- a/src/Ryujinx/Utilities/ValueFormatUtils.cs +++ b/src/Ryujinx/Utilities/ValueFormatUtils.cs @@ -1,5 +1,4 @@ using Humanizer; -using Humanizer.Localisation; using Ryujinx.Ava.Common.Locale; using System; using System.Globalization;