Use source generation for SettingsUtil.SetDefaultValues
This commit is contained in:
parent
5ce0aa24a5
commit
f2a4794105
|
@ -1,9 +1,9 @@
|
|||
namespace BizHawk.Analyzers;
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace BizHawk.Analyzers;
|
||||
|
||||
public static class RoslynUtils
|
||||
{
|
||||
public static SyntaxNode? EnclosingTypeDeclarationSyntax(this CSharpSyntaxNode node)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
/bin
|
||||
/obj
|
|
@ -0,0 +1,6 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<Import Project="../AnalyzersCommon.props" />
|
||||
</Project>
|
|
@ -0,0 +1,117 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace BizHawk.SrcGen.SettingsUtil;
|
||||
|
||||
[Generator]
|
||||
public class DefaultSetterGenerator : ISourceGenerator
|
||||
{
|
||||
public class SyntaxReceiver : ISyntaxContextReceiver
|
||||
{
|
||||
public readonly List<(ClassDeclarationSyntax, SemanticModel)> ClassDeclarations = new();
|
||||
|
||||
public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
|
||||
{
|
||||
if (context.Node is ClassDeclarationSyntax cds)
|
||||
{
|
||||
ClassDeclarations.Add((cds, context.SemanticModel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize(GeneratorInitializationContext context)
|
||||
=> context.RegisterForSyntaxNotifications(() => new SyntaxReceiver());
|
||||
|
||||
private static void CreateDefaultSetter(StringBuilder source, INamespaceOrTypeSymbol symbol)
|
||||
{
|
||||
var props = symbol
|
||||
.GetMembers()
|
||||
.Where(m => m.Kind == SymbolKind.Property)
|
||||
.ToImmutableArray();
|
||||
|
||||
source.Append($@"
|
||||
public static void SetDefaultValues({symbol} settings)
|
||||
{{");
|
||||
|
||||
foreach (var prop in props)
|
||||
{
|
||||
var defaultValueAttribute = prop
|
||||
.GetAttributes()
|
||||
.FirstOrDefault(
|
||||
a => a.AttributeClass?.Name == "DefaultValueAttribute");
|
||||
|
||||
var ctorArgs = defaultValueAttribute?.ConstructorArguments;
|
||||
if (!ctorArgs.HasValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (ctorArgs.Value.Length)
|
||||
{
|
||||
case 1:
|
||||
// this single arg is just the value assigned to the default value
|
||||
var arg = ctorArgs.Value[0];
|
||||
// a bit lame, but it'll work
|
||||
// TODO: do we even want to handle arrays? do we even have any arrays in default values???
|
||||
var converionStr = arg.Kind == TypedConstantKind.Array
|
||||
? $"new {arg.Type} " // new T[]
|
||||
: ""; // do we need a cast (i.e. (T)) here? probably not?
|
||||
source.Append($@"
|
||||
settings.{prop.Name} = {converionStr}{arg.ToCSharpString()};");
|
||||
break;
|
||||
case 2:
|
||||
// first arg is the type, the second arg is a string which converts it
|
||||
source.Append($@"
|
||||
settings.{prop.Name} = ({ctorArgs.Value[0].Value})System.ComponentModel.TypeDescriptor
|
||||
.GetConverter({ctorArgs.Value[0].ToCSharpString()})
|
||||
.ConvertFromInvariantString({ctorArgs.Value[1].ToCSharpString()});");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
source.Append(@"
|
||||
}
|
||||
");
|
||||
}
|
||||
|
||||
public void Execute(GeneratorExecutionContext context)
|
||||
{
|
||||
if (context.SyntaxContextReceiver is not SyntaxReceiver syntaxReceiver)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Generated source code
|
||||
var source = new StringBuilder(@"
|
||||
namespace BizHawk.Common
|
||||
{
|
||||
public static partial class SettingsUtil
|
||||
{");
|
||||
|
||||
foreach (var (cds, semanticModel) in syntaxReceiver.ClassDeclarations)
|
||||
{
|
||||
if (cds.AttributeLists.SelectMany(e => e.Attributes)
|
||||
.Any(e => e.Name.NormalizeWhitespace().ToFullString() == "CoreSettings"))
|
||||
{
|
||||
var symbol = semanticModel.GetDeclaredSymbol(cds);
|
||||
if (symbol is not null) // probably never happens?
|
||||
{
|
||||
CreateDefaultSetter(source, symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
source.Append(@"
|
||||
}
|
||||
}");
|
||||
|
||||
// Add the source code to the compilation
|
||||
context.AddSource("DefaultSetters.g.cs", source.ToString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
../.build_debug.sh
|
|
@ -0,0 +1 @@
|
|||
../.build_release.sh
|
Binary file not shown.
|
@ -10,7 +10,6 @@
|
|||
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageReference Include="System.Memory" Version="4.5.5" />
|
||||
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" PrivateAssets="all" />
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
|
||||
using BizHawk.Common.CollectionExtensions;
|
||||
|
||||
namespace BizHawk.Common
|
||||
{
|
||||
public static class SettingsUtil
|
||||
{
|
||||
private sealed class DefaultValueSetter
|
||||
{
|
||||
public readonly Action<object, object[]> SetDefaultValues;
|
||||
|
||||
public readonly object[] DefaultValues;
|
||||
|
||||
public DefaultValueSetter(Action<object, object[]> setDefaultValues, object[] defaultValues)
|
||||
{
|
||||
SetDefaultValues = setDefaultValues;
|
||||
DefaultValues = defaultValues;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static readonly IDictionary<Type, DefaultValueSetter> DefaultValueSetters = new ConcurrentDictionary<Type, DefaultValueSetter>();
|
||||
|
||||
/// <summary>
|
||||
/// set all properties (not fields!) of obj with a DefaultValueAttribute to that value
|
||||
/// </summary>
|
||||
/// <param name="obj">the obj to act on</param>
|
||||
public static void SetDefaultValues<T>(T obj)
|
||||
where T : notnull
|
||||
{
|
||||
var f = DefaultValueSetters.GetValueOrPut(typeof(T), CreateSetter);
|
||||
f.SetDefaultValues(obj, f.DefaultValues);
|
||||
}
|
||||
|
||||
private static readonly Dictionary<Type, OpCode> IntTypes = new Dictionary<Type,OpCode>
|
||||
{
|
||||
{ typeof(byte), OpCodes.Conv_U1 },
|
||||
{ typeof(sbyte), OpCodes.Conv_I1 },
|
||||
{ typeof(ushort), OpCodes.Conv_U2 },
|
||||
{ typeof(short), OpCodes.Conv_I2 },
|
||||
{ typeof(uint), OpCodes.Conv_U4 },
|
||||
{ typeof(int), OpCodes.Conv_I4 },
|
||||
{ typeof(ulong), OpCodes.Conv_U8 },
|
||||
{ typeof(long), OpCodes.Conv_I8 },
|
||||
{ typeof(UIntPtr), OpCodes.Conv_U },
|
||||
{ typeof(IntPtr), OpCodes.Conv_I },
|
||||
};
|
||||
|
||||
private static DefaultValueSetter CreateSetter(Type t)
|
||||
{
|
||||
var dyn = new DynamicMethod($"SetDefaultValues_{t.Name}", null, new[] { typeof(object), typeof(object[]) }, false);
|
||||
var il = dyn.GetILGenerator();
|
||||
List<object> DefaultValues = new List<object>();
|
||||
|
||||
il.Emit(OpCodes.Ldarg_0); // arg0: object to set properties of
|
||||
il.Emit(OpCodes.Castclass, t); // cast to appropriate type
|
||||
|
||||
foreach (var prop in t.GetProperties())
|
||||
{
|
||||
if (!prop.CanWrite)
|
||||
continue;
|
||||
MethodInfo method = prop.GetSetMethod(true);
|
||||
foreach (object attr in prop.GetCustomAttributes(true))
|
||||
{
|
||||
if (attr is DefaultValueAttribute dvAttr)
|
||||
{
|
||||
var value = dvAttr.Value;
|
||||
Type desiredType = method.GetParameters()[0].ParameterType;
|
||||
Type sourceType = value.GetType();
|
||||
|
||||
int idx = DefaultValues.Count;
|
||||
DefaultValues.Add(value);
|
||||
|
||||
il.Emit(OpCodes.Dup); // object to act on
|
||||
il.Emit(OpCodes.Ldarg_1); // arg1: array of default values
|
||||
il.Emit(OpCodes.Ldc_I4, idx); // load index
|
||||
il.Emit(OpCodes.Ldelem, typeof(object)); // get default value at appropriate index
|
||||
|
||||
// cast to the expected type of the set method
|
||||
if (desiredType.IsAssignableFrom(sourceType))
|
||||
{
|
||||
il.Emit(OpCodes.Unbox_Any, desiredType);
|
||||
}
|
||||
else if (IntTypes.ContainsKey(sourceType) && IntTypes.TryGetValue(desiredType, out var desiredOpcode))
|
||||
{
|
||||
il.Emit(OpCodes.Unbox_Any, sourceType);
|
||||
il.Emit(desiredOpcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"Default value assignment will fail for {t.Name}.{prop.Name}");
|
||||
}
|
||||
il.Emit(OpCodes.Callvirt, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
il.Emit(OpCodes.Pop);
|
||||
il.Emit(OpCodes.Ret);
|
||||
return new DefaultValueSetter(
|
||||
(Action<object, object[]>) dyn.CreateDelegate(typeof(Action<object, object[]>)),
|
||||
DefaultValues.ToArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,8 @@ namespace BizHawk.Emulation.Common
|
|||
/// <typeparam name="TSettings">The Type of the object that represent regular settings (settings that can be changed during the lifespan of a core instance</typeparam>
|
||||
/// <typeparam name="TSync">The Type of the object that represents sync settings (settings that can not change during the lifespan of the core and are required for movie sync</typeparam>
|
||||
public interface ISettable<TSettings, TSync> : IEmulatorService
|
||||
where TSettings : class, new()
|
||||
where TSync : class, new()
|
||||
{
|
||||
// in addition to these methods, it's expected that the constructor or Load() method
|
||||
// will take a Settings and SyncSettings object to set the initial state of the core
|
||||
|
@ -54,6 +56,15 @@ namespace BizHawk.Emulation.Common
|
|||
PutSettingsDirtyBits PutSyncSettings(TSync o);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Place this attribute for TSettings and TSync classes which use System.ComponentModel.DefaultValue
|
||||
/// Classes with this attribute will have a BizHawk.Common.SettingsUtil.SetDefaultValues(T) function generated
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class CoreSettings : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
//note: this is a bit of a frail API. If a frontend wants a new flag, cores won't know to yea or nay it
|
||||
//this could be solved by adding a KnownSettingsDirtyBits on the settings interface
|
||||
//or, in a pinch, the same thing could be done with THESE flags, so that the interface doesn't
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class MAMERTCSettings
|
||||
{
|
||||
[DisplayName("Initial Time")]
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="Google.FlatBuffers" Version="22.9.24" Private="true" />
|
||||
<Analyzer Include="$(ProjectDir)../../References/BizHawk.SrcGen.SettingsUtil.dll" Private="true" />
|
||||
<Reference Include="FlatBuffers.GenOutput" HintPath="$(ProjectDir)../../References/FlatBuffers.GenOutput.dll" Private="true" />
|
||||
<Reference Include="Virtu" HintPath="$(ProjectDir)../../References/Virtu.dll" Private="true" />
|
||||
<ProjectReference Include="$(ProjectDir)../BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj" />
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class AmstradCPCSettings
|
||||
{
|
||||
[DisplayName("AY-3-8912 Panning Config")]
|
||||
|
@ -85,6 +86,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class AmstradCPCSyncSettings
|
||||
{
|
||||
[DisplayName("Deterministic Emulation")]
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
private Settings _settings;
|
||||
private SyncSettings _syncSettings;
|
||||
|
||||
[CoreSettings]
|
||||
public class Settings
|
||||
{
|
||||
[DisplayName("Monochrome")]
|
||||
|
@ -25,6 +26,7 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
=> (Settings)MemberwiseClone();
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class SyncSettings
|
||||
{
|
||||
[DisplayName("Initial Time")]
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||
|
@ -31,6 +33,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
internal C64Settings Settings { get; private set; }
|
||||
internal C64SyncSettings SyncSettings { get; private set; }
|
||||
|
||||
[CoreSettings]
|
||||
public class C64Settings
|
||||
{
|
||||
[DisplayName("Border type")]
|
||||
|
@ -50,10 +53,11 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
|
||||
public C64Settings()
|
||||
{
|
||||
BizHawk.Common.SettingsUtil.SetDefaultValues(this);
|
||||
SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class C64SyncSettings
|
||||
{
|
||||
[DisplayName("VIC type")]
|
||||
|
@ -93,7 +97,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
|
||||
public C64SyncSettings()
|
||||
{
|
||||
BizHawk.Common.SettingsUtil.SetDefaultValues(this);
|
||||
SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
internal MSXSettings Settings { get; private set; }
|
||||
internal MSXSyncSettings SyncSettings { get; private set; }
|
||||
|
||||
[CoreSettings]
|
||||
public class MSXSettings
|
||||
{
|
||||
// graphics settings
|
||||
|
@ -62,6 +63,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class MSXSyncSettings
|
||||
{
|
||||
public enum ContrType
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class ZXSpectrumSettings
|
||||
{
|
||||
[DisplayName("AY-3-8912 Panning Config")]
|
||||
|
@ -97,6 +98,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class ZXSpectrumSyncSettings
|
||||
{
|
||||
[DisplayName("Deterministic Emulation")]
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace BizHawk.Emulation.Cores.Computers.TIC80
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class TIC80Settings
|
||||
{
|
||||
[DisplayName("Crop")]
|
||||
|
@ -44,6 +45,7 @@ namespace BizHawk.Emulation.Cores.Computers.TIC80
|
|||
=> (TIC80Settings)MemberwiseClone();
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class TIC80SyncSettings
|
||||
{
|
||||
[DisplayName("Gamepad 1 Enable")]
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
internal A2600Settings Settings { get; private set; }
|
||||
internal A2600SyncSettings SyncSettings { get; private set; }
|
||||
|
||||
[CoreSettings]
|
||||
public class A2600Settings
|
||||
{
|
||||
[JsonIgnore]
|
||||
|
@ -147,6 +148,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class A2600SyncSettings
|
||||
{
|
||||
[DefaultValue(Atari2600ControllerTypes.Joystick)]
|
||||
|
|
|
@ -6,59 +6,33 @@ using BizHawk.Emulation.Common;
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||
{
|
||||
public partial class A7800Hawk : IEmulator, ISettable<A7800Hawk.A7800Settings, A7800Hawk.A7800SyncSettings>
|
||||
public partial class A7800Hawk : IEmulator, ISettable<object, A7800Hawk.A7800SyncSettings>
|
||||
{
|
||||
public A7800Settings GetSettings()
|
||||
{
|
||||
return _settings.Clone();
|
||||
}
|
||||
public object GetSettings()
|
||||
=> null;
|
||||
|
||||
public A7800SyncSettings GetSyncSettings()
|
||||
{
|
||||
return _syncSettings.Clone();
|
||||
}
|
||||
=> _syncSettings.Clone();
|
||||
|
||||
public PutSettingsDirtyBits PutSettings(A7800Settings o)
|
||||
{
|
||||
_settings = o;
|
||||
return PutSettingsDirtyBits.None;
|
||||
}
|
||||
public PutSettingsDirtyBits PutSettings(object o)
|
||||
=> PutSettingsDirtyBits.None;
|
||||
|
||||
public PutSettingsDirtyBits PutSyncSettings(A7800SyncSettings o)
|
||||
{
|
||||
bool ret = A7800SyncSettings.NeedsReboot(_syncSettings, o);
|
||||
var ret = A7800SyncSettings.NeedsReboot(_syncSettings, o);
|
||||
_syncSettings = o;
|
||||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
private A7800Settings _settings = new A7800Settings();
|
||||
public A7800SyncSettings _syncSettings = new A7800SyncSettings();
|
||||
|
||||
public class A7800Settings
|
||||
{
|
||||
public A7800Settings Clone()
|
||||
{
|
||||
return (A7800Settings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public A7800Settings()
|
||||
{
|
||||
SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
}
|
||||
public A7800SyncSettings _syncSettings = new();
|
||||
|
||||
public class A7800SyncSettings
|
||||
{
|
||||
private string _port1 = A7800HawkControllerDeck.DefaultControllerName;
|
||||
private string _port2 = A7800HawkControllerDeck.DefaultControllerName;
|
||||
private string _Filter = "None";
|
||||
|
||||
[JsonIgnore]
|
||||
public string Filter
|
||||
{
|
||||
get => _Filter;
|
||||
set => _Filter = value;
|
||||
}
|
||||
public string Filter { get; set; } = "None";
|
||||
|
||||
[JsonIgnore]
|
||||
public string Port1
|
||||
|
@ -91,19 +65,10 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
}
|
||||
|
||||
public A7800SyncSettings Clone()
|
||||
{
|
||||
return (A7800SyncSettings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public A7800SyncSettings()
|
||||
{
|
||||
SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
=> (A7800SyncSettings)MemberwiseClone();
|
||||
|
||||
public static bool NeedsReboot(A7800SyncSettings x, A7800SyncSettings y)
|
||||
{
|
||||
return !DeepEquality.DeepEquals(x, y);
|
||||
}
|
||||
=> !DeepEquality.DeepEquals(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
[Core(CoreNames.A7800Hawk, "")]
|
||||
[ServiceNotApplicable(new[] { typeof(IDriveLight), typeof(ISettable<,>) })]
|
||||
public partial class A7800Hawk : IEmulator, ISaveRam, IDebuggable, IInputPollable,
|
||||
IRegionable, IBoardInfo, ISettable<A7800Hawk.A7800Settings, A7800Hawk.A7800SyncSettings>
|
||||
IRegionable, IBoardInfo, ISettable<object, A7800Hawk.A7800SyncSettings>
|
||||
{
|
||||
internal static class RomChecksums
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
}
|
||||
|
||||
[CoreConstructor(VSystemID.Raw.A78)]
|
||||
public A7800Hawk(CoreComm comm, byte[] rom, A7800Hawk.A7800Settings settings, A7800Hawk.A7800SyncSettings syncSettings)
|
||||
public A7800Hawk(CoreComm comm, byte[] rom, A7800SyncSettings syncSettings)
|
||||
{
|
||||
var ser = new BasicServiceProvider(this);
|
||||
|
||||
|
@ -94,7 +94,6 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
|
||||
_blip.SetRates(1789773, 44100);
|
||||
|
||||
_settings = settings ?? new A7800Settings();
|
||||
_syncSettings = syncSettings ?? new A7800SyncSettings();
|
||||
_controllerDeck = new A7800HawkControllerDeck(_syncSettings.Port1, _syncSettings.Port2);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class VirtualJaguarSettings
|
||||
{
|
||||
[DisplayName("Trace M68K (CPU)")]
|
||||
|
@ -54,6 +55,7 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
=> (VirtualJaguarSettings)MemberwiseClone();
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class VirtualJaguarSyncSettings
|
||||
{
|
||||
[DisplayName("Player 1 Connected")]
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class ChannelFSettings
|
||||
{
|
||||
[DisplayName("Default Background Color")]
|
||||
|
@ -50,6 +51,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class ChannelFSyncSettings
|
||||
{
|
||||
[DisplayName("Deterministic Emulation")]
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
|
|||
private object _settings = new object();
|
||||
public VectrexSyncSettings _syncSettings = new VectrexSyncSettings();
|
||||
|
||||
[CoreSettings]
|
||||
public class VectrexSyncSettings
|
||||
{
|
||||
[JsonIgnore]
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
|
|||
public O2Settings _settings = new O2Settings();
|
||||
public O2SyncSettings _syncSettings = new O2SyncSettings();
|
||||
|
||||
[CoreSettings]
|
||||
public class O2Settings
|
||||
{
|
||||
[DisplayName("Display Characters")]
|
||||
|
@ -70,6 +71,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class O2SyncSettings
|
||||
{
|
||||
[DisplayName("Use G7400 Enhanemants")]
|
||||
|
|
|
@ -109,6 +109,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.N3DS
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class CitraSettings
|
||||
{
|
||||
[DisplayName("Resolution Scale Factor")]
|
||||
|
@ -240,6 +241,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.N3DS
|
|||
=> SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class CitraSyncSettings
|
||||
{
|
||||
[DisplayName("Use CPU JIT")]
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Ares64
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class Ares64Settings
|
||||
{
|
||||
[DisplayName("Deinterlacer")]
|
||||
|
@ -50,6 +51,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Ares64
|
|||
=> (Ares64Settings)MemberwiseClone();
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class Ares64SyncSettings
|
||||
{
|
||||
[DisplayName("Initial Time")]
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
|
||||
private Settings _settings;
|
||||
|
||||
[CoreSettings]
|
||||
public class Settings
|
||||
{
|
||||
[DisplayName("Display BG Layer 0")]
|
||||
|
@ -143,6 +144,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
|
||||
private SyncSettings _syncSettings;
|
||||
|
||||
[CoreSettings]
|
||||
public class SyncSettings
|
||||
{
|
||||
[DisplayName("Skip BIOS")]
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
public GBSettings _settings = new GBSettings();
|
||||
public GBSyncSettings _syncSettings = new GBSyncSettings();
|
||||
|
||||
[CoreSettings]
|
||||
public class GBSettings
|
||||
{
|
||||
public enum PaletteType
|
||||
|
@ -82,6 +83,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class GBSyncSettings
|
||||
{
|
||||
public enum ConsoleModeType
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
|
|||
private GBLinkSettings linkSettings = new GBLinkSettings();
|
||||
public GBLinkSyncSettings linkSyncSettings = new GBLinkSyncSettings();
|
||||
|
||||
[CoreSettings]
|
||||
public class GBLinkSettings
|
||||
{
|
||||
[DisplayName("Color Mode")]
|
||||
|
@ -71,6 +72,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
|
|||
public GBLinkSettings() => SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class GBLinkSyncSettings
|
||||
{
|
||||
[DisplayName("Console Mode L")]
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
|
|||
private GBLink3xSettings Link3xSettings = new GBLink3xSettings();
|
||||
private GBLink3xSyncSettings Link3xSyncSettings = new GBLink3xSyncSettings();
|
||||
|
||||
[CoreSettings]
|
||||
public class GBLink3xSettings
|
||||
{
|
||||
[DisplayName("Color Mode")]
|
||||
|
@ -65,6 +66,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
|
|||
public GBLink3xSettings() => SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class GBLink3xSyncSettings
|
||||
{
|
||||
[DisplayName("Console Mode L")]
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
|
|||
private GBLink4xSettings Link4xSettings = new GBLink4xSettings();
|
||||
public GBLink4xSyncSettings Link4xSyncSettings = new GBLink4xSyncSettings();
|
||||
|
||||
[CoreSettings]
|
||||
public class GBLink4xSettings
|
||||
{
|
||||
[DisplayName("Color Mode A")]
|
||||
|
@ -71,6 +72,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
|
|||
public GBLink4xSettings() => SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class GBLink4xSyncSettings
|
||||
{
|
||||
[DisplayName("Console Mode A")]
|
||||
|
|
|
@ -97,6 +97,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class GambatteSyncSettings
|
||||
{
|
||||
[DisplayName("Use official Nintendo BootROM")]
|
||||
|
|
|
@ -122,6 +122,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
Rotate270,
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class NDSSettings
|
||||
{
|
||||
[DisplayName("Screen Layout")]
|
||||
|
@ -226,6 +227,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
private static readonly DateTime minDate = new(2000, 1, 1);
|
||||
private static readonly DateTime maxDate = new(2099, 12, 31, 23, 59, 59);
|
||||
|
||||
[CoreSettings]
|
||||
public class NDSSyncSettings
|
||||
{
|
||||
public enum ThreeDeeRendererType : int
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
|||
/// </summary>
|
||||
private QuickNESSyncSettings _syncSettingsNext;
|
||||
|
||||
[CoreSettings]
|
||||
public class QuickNESSettings
|
||||
{
|
||||
[DefaultValue(8)]
|
||||
|
@ -150,6 +151,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class QuickNESSyncSettings
|
||||
{
|
||||
[DefaultValue(true)]
|
||||
|
|
|
@ -149,6 +149,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class Settings
|
||||
{
|
||||
[DefaultValue(true)]
|
||||
|
@ -234,6 +235,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class SyncSettings
|
||||
{
|
||||
[DefaultValue(LibSnes9x.LeftPortDevice.Joypad)]
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class SameboySettings
|
||||
{
|
||||
public enum GBPaletteType : uint
|
||||
|
@ -192,6 +193,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
|
|||
=> _customPal = (int[])pal.Clone();
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class SameboySyncSettings
|
||||
{
|
||||
[DisplayName("Use official BIOS")]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
|
@ -7,14 +8,10 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
|
|||
public partial class GGHawkLink : IEmulator, IStatable, ISettable<GGHawkLink.GGLinkSettings, GGHawkLink.GGLinkSyncSettings>
|
||||
{
|
||||
public GGLinkSettings GetSettings()
|
||||
{
|
||||
return linkSettings.Clone();
|
||||
}
|
||||
=> linkSettings.Clone();
|
||||
|
||||
public GGLinkSyncSettings GetSyncSettings()
|
||||
{
|
||||
return linkSyncSettings.Clone();
|
||||
}
|
||||
=> linkSyncSettings.Clone();
|
||||
|
||||
public PutSettingsDirtyBits PutSettings(GGLinkSettings o)
|
||||
{
|
||||
|
@ -24,14 +21,15 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
|
|||
|
||||
public PutSettingsDirtyBits PutSyncSettings(GGLinkSyncSettings o)
|
||||
{
|
||||
bool ret = GGLinkSyncSettings.NeedsReboot(linkSyncSettings, o);
|
||||
var ret = GGLinkSyncSettings.NeedsReboot(linkSyncSettings, o);
|
||||
linkSyncSettings = o;
|
||||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
private GGLinkSettings linkSettings = new GGLinkSettings();
|
||||
public GGLinkSyncSettings linkSyncSettings = new GGLinkSyncSettings();
|
||||
private GGLinkSettings linkSettings = new();
|
||||
public GGLinkSyncSettings linkSyncSettings = new();
|
||||
|
||||
[CoreSettings]
|
||||
public class GGLinkSettings
|
||||
{
|
||||
public enum AudioSrc
|
||||
|
@ -46,29 +44,29 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
|
|||
[DefaultValue(AudioSrc.Left)]
|
||||
public AudioSrc AudioSet { get; set; }
|
||||
|
||||
public GGLinkSettings()
|
||||
=> SettingsUtil.SetDefaultValues(this);
|
||||
|
||||
public GGLinkSettings Clone()
|
||||
{
|
||||
return (GGLinkSettings)MemberwiseClone();
|
||||
}
|
||||
=> (GGLinkSettings)MemberwiseClone();
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class GGLinkSyncSettings
|
||||
{
|
||||
|
||||
[DisplayName("Use Existing SaveRAM")]
|
||||
[Description("When true, existing SaveRAM will be loaded at boot up")]
|
||||
[DefaultValue(true)]
|
||||
public bool Use_SRAM { get; set; }
|
||||
|
||||
public GGLinkSyncSettings()
|
||||
=> SettingsUtil.SetDefaultValues(this);
|
||||
|
||||
public GGLinkSyncSettings Clone()
|
||||
{
|
||||
return (GGLinkSyncSettings)MemberwiseClone();
|
||||
}
|
||||
=> (GGLinkSyncSettings)MemberwiseClone();
|
||||
|
||||
public static bool NeedsReboot(GGLinkSyncSettings x, GGLinkSyncSettings y)
|
||||
{
|
||||
return !DeepEquality.DeepEquals(x, y);
|
||||
}
|
||||
=> !DeepEquality.DeepEquals(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,6 +179,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive
|
|||
_core.SetCDReadCallback(_cdcallback);
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class SyncSettings
|
||||
{
|
||||
[DefaultValue(LibPicoDrive.Region.Auto)]
|
||||
|
|
|
@ -116,6 +116,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
private GPGXSyncSettings _syncSettings;
|
||||
private GPGXSettings _settings;
|
||||
|
||||
[CoreSettings]
|
||||
public class GPGXSettings
|
||||
{
|
||||
[DeepEqualsIgnore]
|
||||
|
@ -239,6 +240,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class GPGXSyncSettings
|
||||
{
|
||||
[DisplayName("Use Six Button Controllers")]
|
||||
|
|
|
@ -1142,6 +1142,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
BobOffset
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class Settings
|
||||
{
|
||||
[DisplayName("Determine Lag from GPU Frames")]
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
using System;
|
||||
using BizHawk.Emulation.Common;
|
||||
using System.ComponentModel;
|
||||
using BizHawk.Common;
|
||||
using System.Drawing;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.WonderSwan
|
||||
{
|
||||
partial class WonderSwan : ISettable<WonderSwan.Settings, WonderSwan.SyncSettings>
|
||||
|
@ -11,6 +12,7 @@ namespace BizHawk.Emulation.Cores.WonderSwan
|
|||
private Settings _settings;
|
||||
private SyncSettings _syncSettings;
|
||||
|
||||
[CoreSettings]
|
||||
public class Settings
|
||||
{
|
||||
[DisplayName("Background Layer")]
|
||||
|
@ -83,6 +85,7 @@ namespace BizHawk.Emulation.Cores.WonderSwan
|
|||
}
|
||||
}
|
||||
|
||||
[CoreSettings]
|
||||
public class SyncSettings
|
||||
{
|
||||
[DisplayName("Initial Time")]
|
||||
|
|
Loading…
Reference in New Issue