more misc cleanups
This commit is contained in:
parent
b488529a7b
commit
76b9367378
|
@ -14,7 +14,7 @@ namespace BizHawk.Emulation.Common
|
||||||
/// <seealso cref="IEmulatorServiceProvider"/>
|
/// <seealso cref="IEmulatorServiceProvider"/>
|
||||||
public class BasicServiceProvider : IEmulatorServiceProvider
|
public class BasicServiceProvider : IEmulatorServiceProvider
|
||||||
{
|
{
|
||||||
private Dictionary<Type, object> Services = new Dictionary<Type, object>();
|
private readonly Dictionary<Type, object> Services = new Dictionary<Type, object>();
|
||||||
|
|
||||||
public BasicServiceProvider(IEmulator core)
|
public BasicServiceProvider(IEmulator core)
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,6 +63,7 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
return _sink;
|
return _sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_sink = value;
|
_sink = value;
|
||||||
|
|
|
@ -31,37 +31,37 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the controller definition
|
/// Gets or sets the name of the controller definition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of all button types that have a boolean (on/off) value
|
/// Gets or sets a list of all button types that have a boolean (on/off) value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<string> BoolButtons { get; set; }
|
public List<string> BoolButtons { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of all non-boolean types, that can be represented by a numerical value (such as analog controls, stylus coordinates, etc
|
/// Gets a list of all non-boolean types, that can be represented by a numerical value (such as analog controls, stylus coordinates, etc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<string> FloatControls { get; private set; }
|
public List<string> FloatControls { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of all float ranges for each float control (must be one to one with FloatControls)
|
/// Gets a list of all float ranges for each float control (must be one to one with FloatControls)
|
||||||
/// FloatRanges include the min/max/default values
|
/// FloatRanges include the min/max/default values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<FloatRange> FloatRanges { get; private set; }
|
public List<FloatRange> FloatRanges { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Axis contraints apply artificial contraints to float values
|
/// Gets the axis constraints that apply artificial constraints to float values
|
||||||
/// For instance, a N64 controller's analog range is actually larger than the amount allowed by the plastic that artificially contrains it to lower values
|
/// For instance, a N64 controller's analog range is actually larger than the amount allowed by the plastic that artificially constrains it to lower values
|
||||||
/// Axis contraints provide a way to technically allow the full range but have a user option to contrain down to typical values that a real control would have
|
/// Axis constraints provide a way to technically allow the full range but have a user option to constrain down to typical values that a real control would have
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<AxisConstraint> AxisConstraints { get; private set; }
|
public List<AxisConstraint> AxisConstraints { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A means of categorizing controls in various controller display and config screens
|
/// Gets the category labels. These labels provide a means of categorizing controls in various controller display and config screens
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<string, string> CategoryLabels { get; private set; }
|
public Dictionary<string, string> CategoryLabels { get; }
|
||||||
|
|
||||||
public void ApplyAxisConstraints(string constraintClass, IDictionary<string, float> floatButtons)
|
public void ApplyAxisConstraints(string constraintClass, IDictionary<string, float> floatButtons)
|
||||||
{
|
{
|
||||||
|
@ -93,6 +93,7 @@ namespace BizHawk.Emulation.Common
|
||||||
xval *= ratio;
|
xval *= ratio;
|
||||||
yval *= ratio;
|
yval *= ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
floatButtons[xaxis] = (float)xval;
|
floatButtons[xaxis] = (float)xval;
|
||||||
floatButtons[yaxis] = (float)yval;
|
floatButtons[yaxis] = (float)yval;
|
||||||
break;
|
break;
|
||||||
|
@ -214,5 +215,4 @@ namespace BizHawk.Emulation.Common
|
||||||
return BoolButtons.Any() || FloatControls.Any();
|
return BoolButtons.Any() || FloatControls.Any();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Common
|
||||||
private bool _hasWrites;
|
private bool _hasWrites;
|
||||||
private bool _hasExecutes;
|
private bool _hasExecutes;
|
||||||
|
|
||||||
public bool ExecuteCallbacksAvailable { get; set; }
|
public bool ExecuteCallbacksAvailable { get; }
|
||||||
|
|
||||||
public void Add(IMemoryCallback callback)
|
public void Add(IMemoryCallback callback)
|
||||||
{
|
{
|
||||||
|
@ -222,12 +222,14 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
CallbackAdded?.Invoke(callback);
|
CallbackAdded?.Invoke(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NotifyCollectionChangedAction.Remove:
|
case NotifyCollectionChangedAction.Remove:
|
||||||
foreach (IMemoryCallback callback in args.OldItems)
|
foreach (IMemoryCallback callback in args.OldItems)
|
||||||
{
|
{
|
||||||
CallbackRemoved?.Invoke(callback);
|
CallbackRemoved?.Invoke(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace BizHawk.Emulation.Common
|
||||||
/// <param name="data">must remain valid as long as the MemoryDomain exists!</param>
|
/// <param name="data">must remain valid as long as the MemoryDomain exists!</param>
|
||||||
/// <param name="writable">if false, writes will be ignored</param>
|
/// <param name="writable">if false, writes will be ignored</param>
|
||||||
[Obsolete]
|
[Obsolete]
|
||||||
public unsafe static MemoryDomain FromIntPtr(string name, long size, Endian endian, IntPtr data, bool writable = true, int wordSize = 1)
|
public static unsafe MemoryDomain FromIntPtr(string name, long size, Endian endian, IntPtr data, bool writable = true, int wordSize = 1)
|
||||||
{
|
{
|
||||||
return new MemoryDomainIntPtr(name, endian, data, size, writable, wordSize);
|
return new MemoryDomainIntPtr(name, endian, data, size, writable, wordSize);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ namespace BizHawk.Emulation.Common
|
||||||
/// <param name="data">must remain valid as long as the MemoryDomain exists!</param>
|
/// <param name="data">must remain valid as long as the MemoryDomain exists!</param>
|
||||||
/// <param name="writable">if false, writes will be ignored</param>
|
/// <param name="writable">if false, writes will be ignored</param>
|
||||||
[Obsolete]
|
[Obsolete]
|
||||||
public unsafe static MemoryDomain FromIntPtrSwap16(string name, long size, Endian endian, IntPtr data, bool writable = true)
|
public static unsafe MemoryDomain FromIntPtrSwap16(string name, long size, Endian endian, IntPtr data, bool writable = true)
|
||||||
{
|
{
|
||||||
return new MemoryDomainIntPtrSwap16(name, endian, data, size, writable);
|
return new MemoryDomainIntPtrSwap16(name, endian, data, size, writable);
|
||||||
}
|
}
|
||||||
|
@ -69,9 +69,9 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case Endian.Big:
|
case Endian.Big:
|
||||||
return (ushort)((PeekByte(addr) << 8) | (PeekByte(addr + 1)));
|
return (ushort)((PeekByte(addr) << 8) | PeekByte(addr + 1));
|
||||||
case Endian.Little:
|
case Endian.Little:
|
||||||
return (ushort)((PeekByte(addr)) | (PeekByte(addr + 1) << 8));
|
return (ushort)(PeekByte(addr) | (PeekByte(addr + 1) << 8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,10 +102,10 @@ namespace BizHawk.Emulation.Common
|
||||||
default:
|
default:
|
||||||
case Endian.Big:
|
case Endian.Big:
|
||||||
PokeByte(addr + 0, (byte)(val >> 8));
|
PokeByte(addr + 0, (byte)(val >> 8));
|
||||||
PokeByte(addr + 1, (byte)(val));
|
PokeByte(addr + 1, (byte)val);
|
||||||
break;
|
break;
|
||||||
case Endian.Little:
|
case Endian.Little:
|
||||||
PokeByte(addr + 0, (byte)(val));
|
PokeByte(addr + 0, (byte)val);
|
||||||
PokeByte(addr + 1, (byte)(val >> 8));
|
PokeByte(addr + 1, (byte)(val >> 8));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -121,10 +121,10 @@ namespace BizHawk.Emulation.Common
|
||||||
PokeByte(addr + 0, (byte)(val >> 24));
|
PokeByte(addr + 0, (byte)(val >> 24));
|
||||||
PokeByte(addr + 1, (byte)(val >> 16));
|
PokeByte(addr + 1, (byte)(val >> 16));
|
||||||
PokeByte(addr + 2, (byte)(val >> 8));
|
PokeByte(addr + 2, (byte)(val >> 8));
|
||||||
PokeByte(addr + 3, (byte)(val));
|
PokeByte(addr + 3, (byte)val);
|
||||||
break;
|
break;
|
||||||
case Endian.Little:
|
case Endian.Little:
|
||||||
PokeByte(addr + 0, (byte)(val));
|
PokeByte(addr + 0, (byte)val);
|
||||||
PokeByte(addr + 1, (byte)(val >> 8));
|
PokeByte(addr + 1, (byte)(val >> 8));
|
||||||
PokeByte(addr + 2, (byte)(val >> 16));
|
PokeByte(addr + 2, (byte)(val >> 16));
|
||||||
PokeByte(addr + 3, (byte)(val >> 24));
|
PokeByte(addr + 3, (byte)(val >> 24));
|
||||||
|
|
|
@ -24,6 +24,6 @@
|
||||||
return 0f;
|
return 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NullController Instance = new NullController();
|
public static readonly NullController Instance = new NullController();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -201,7 +201,7 @@ namespace BizHawk.Emulation.Common
|
||||||
private bool _frameBufferClear = true;
|
private bool _frameBufferClear = true;
|
||||||
|
|
||||||
private bool _xmas;
|
private bool _xmas;
|
||||||
private Pleg _pleg;
|
private readonly Pleg _pleg;
|
||||||
|
|
||||||
private NullEmulatorSettings _settings;
|
private NullEmulatorSettings _settings;
|
||||||
|
|
||||||
|
@ -356,9 +356,7 @@ namespace BizHawk.Emulation.Common
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var s = new SinMan(1500, n);
|
var s = new SinMan(1500, n) { c = c, n = n };
|
||||||
s.c = c;
|
|
||||||
s.n = n;
|
|
||||||
SinMen.Add(s);
|
SinMen.Add(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,6 +376,7 @@ namespace BizHawk.Emulation.Common
|
||||||
ret += s.Next();
|
ret += s.Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret > 32767) ret = 32767;
|
if (ret > 32767) ret = 32767;
|
||||||
if (ret < -32767) ret = -32767;
|
if (ret < -32767) ret = -32767;
|
||||||
return (short)ret;
|
return (short)ret;
|
||||||
|
@ -432,10 +431,7 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
public bool fading = false;
|
public bool fading = false;
|
||||||
|
|
||||||
public bool Done
|
public bool Done => amp < 2.0;
|
||||||
{
|
|
||||||
get { return amp < 2.0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
static double GetFreq(int note)
|
static double GetFreq(int note)
|
||||||
{
|
{
|
||||||
|
@ -447,9 +443,15 @@ namespace BizHawk.Emulation.Common
|
||||||
short result = (short)(Math.Sin(theta) * amp);
|
short result = (short)(Math.Sin(theta) * amp);
|
||||||
theta += freq * Math.PI / 22050.0;
|
theta += freq * Math.PI / 22050.0;
|
||||||
if (theta >= Math.PI * 2.0)
|
if (theta >= Math.PI * 2.0)
|
||||||
|
{
|
||||||
theta -= Math.PI * 2.0;
|
theta -= Math.PI * 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
if (fading)
|
if (fading)
|
||||||
|
{
|
||||||
amp *= 0.87;
|
amp *= 0.87;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
return new int[BufferWidth * BufferHeight];
|
return new int[BufferWidth * BufferHeight];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NullVideo Instance { get; } = new NullVideo();
|
||||||
|
|
||||||
public int VirtualWidth => 256;
|
public int VirtualWidth => 256;
|
||||||
|
|
||||||
public int VirtualHeight => 192;
|
public int VirtualHeight => 192;
|
||||||
|
@ -21,9 +23,5 @@
|
||||||
public int BufferHeight => 192;
|
public int BufferHeight => 192;
|
||||||
|
|
||||||
public int BackgroundColor => 0;
|
public int BackgroundColor => 0;
|
||||||
|
|
||||||
private static readonly NullVideo _nullVideo = new NullVideo();
|
|
||||||
|
|
||||||
public static NullVideo Instance => _nullVideo;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,13 +23,18 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
var caller = e as MethodCallExpression;
|
var caller = e as MethodCallExpression;
|
||||||
if (caller == null)
|
if (caller == null)
|
||||||
|
{
|
||||||
throw new ArgumentException("Expression must be a method call");
|
throw new ArgumentException("Expression must be a method call");
|
||||||
|
}
|
||||||
|
|
||||||
return caller.Method;
|
return caller.Method;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MethodInfo Method(Expression<Action> f)
|
private static MethodInfo Method(Expression<Action> f)
|
||||||
{
|
{
|
||||||
return FromExpression(f.Body);
|
return FromExpression(f.Body);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MethodInfo Method<T>(Expression<Action<T>> f)
|
private static MethodInfo Method<T>(Expression<Action<T>> f)
|
||||||
{
|
{
|
||||||
return FromExpression(f.Body);
|
return FromExpression(f.Body);
|
||||||
|
@ -39,14 +44,17 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
#region read and write handlers for individual fields
|
#region read and write handlers for individual fields
|
||||||
|
|
||||||
private static Dictionary<Type, MethodInfo> readhandlers = new Dictionary<Type, MethodInfo>();
|
private static readonly Dictionary<Type, MethodInfo> readhandlers = new Dictionary<Type, MethodInfo>();
|
||||||
private static Dictionary<Type, MethodInfo> writehandlers = new Dictionary<Type, MethodInfo>();
|
private static readonly Dictionary<Type, MethodInfo> writehandlers = new Dictionary<Type, MethodInfo>();
|
||||||
|
|
||||||
private static void AddR<T>(Expression<Action<BinaryReader>> f)
|
private static void AddR<T>(Expression<Action<BinaryReader>> f)
|
||||||
{
|
{
|
||||||
var method = Method(f);
|
var method = Method(f);
|
||||||
if (!typeof(T).IsAssignableFrom(method.ReturnType))
|
if (!typeof(T).IsAssignableFrom(method.ReturnType))
|
||||||
|
{
|
||||||
throw new InvalidOperationException("Type mismatch");
|
throw new InvalidOperationException("Type mismatch");
|
||||||
|
}
|
||||||
|
|
||||||
readhandlers.Add(typeof(T), method);
|
readhandlers.Add(typeof(T), method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +62,10 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
var method = Method(f);
|
var method = Method(f);
|
||||||
if (!method.GetParameters()[0].ParameterType.IsAssignableFrom(typeof(T)))
|
if (!method.GetParameters()[0].ParameterType.IsAssignableFrom(typeof(T)))
|
||||||
|
{
|
||||||
throw new InvalidOperationException("Type mismatch");
|
throw new InvalidOperationException("Type mismatch");
|
||||||
|
}
|
||||||
|
|
||||||
writehandlers.Add(typeof(T), Method(f));
|
writehandlers.Add(typeof(T), Method(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,12 +136,17 @@ namespace BizHawk.Emulation.Common
|
||||||
il.Emit(OpCodes.Ldarg_1);
|
il.Emit(OpCodes.Ldarg_1);
|
||||||
MethodInfo m;
|
MethodInfo m;
|
||||||
if (!readhandlers.TryGetValue(field.FieldType, out m))
|
if (!readhandlers.TryGetValue(field.FieldType, out m))
|
||||||
|
{
|
||||||
throw new InvalidOperationException("(R) Can't handle nested type " + field.FieldType);
|
throw new InvalidOperationException("(R) Can't handle nested type " + field.FieldType);
|
||||||
|
}
|
||||||
|
|
||||||
il.Emit(OpCodes.Callvirt, m);
|
il.Emit(OpCodes.Callvirt, m);
|
||||||
il.Emit(OpCodes.Stfld, field);
|
il.Emit(OpCodes.Stfld, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
il.Emit(OpCodes.Ret);
|
il.Emit(OpCodes.Ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
var il = wmeth.GetILGenerator();
|
var il = wmeth.GetILGenerator();
|
||||||
var target = il.DeclareLocal(t);
|
var target = il.DeclareLocal(t);
|
||||||
|
@ -145,9 +161,13 @@ namespace BizHawk.Emulation.Common
|
||||||
il.Emit(OpCodes.Ldfld, field);
|
il.Emit(OpCodes.Ldfld, field);
|
||||||
MethodInfo m;
|
MethodInfo m;
|
||||||
if (!writehandlers.TryGetValue(field.FieldType, out m))
|
if (!writehandlers.TryGetValue(field.FieldType, out m))
|
||||||
|
{
|
||||||
throw new InvalidOperationException("(W) Can't handle nested type " + field.FieldType);
|
throw new InvalidOperationException("(W) Can't handle nested type " + field.FieldType);
|
||||||
|
}
|
||||||
|
|
||||||
il.Emit(OpCodes.Callvirt, m);
|
il.Emit(OpCodes.Callvirt, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
il.Emit(OpCodes.Ret);
|
il.Emit(OpCodes.Ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +181,7 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private static IDictionary<Type, SerializationFactory> serializers =
|
private static readonly IDictionary<Type, SerializationFactory> serializers =
|
||||||
new ConcurrentDictionary<Type, SerializationFactory>();
|
new ConcurrentDictionary<Type, SerializationFactory>();
|
||||||
|
|
||||||
private static SerializationFactory GetFactory(Type t)
|
private static SerializationFactory GetFactory(Type t)
|
||||||
|
@ -172,6 +192,7 @@ namespace BizHawk.Emulation.Common
|
||||||
f = CreateFactory(t);
|
f = CreateFactory(t);
|
||||||
serializers[t] = f;
|
serializers[t] = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace BizHawk.Emulation.Common.BizInvoke
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// dictionary of all generated proxy implementations and their basetypes
|
/// dictionary of all generated proxy implementations and their basetypes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static IDictionary<Type, InvokerImpl> Impls = new Dictionary<Type, InvokerImpl>();
|
private static readonly IDictionary<Type, InvokerImpl> Impls = new Dictionary<Type, InvokerImpl>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// the assembly that all proxies are placed in
|
/// the assembly that all proxies are placed in
|
||||||
|
@ -138,14 +138,18 @@ namespace BizHawk.Emulation.Common.BizInvoke
|
||||||
{
|
{
|
||||||
var uo = baseMethods.FirstOrDefault(a => !a.Info.IsVirtual || a.Info.IsFinal);
|
var uo = baseMethods.FirstOrDefault(a => !a.Info.IsVirtual || a.Info.IsFinal);
|
||||||
if (uo != null)
|
if (uo != null)
|
||||||
|
{
|
||||||
throw new InvalidOperationException("Method " + uo.Info.Name + " cannot be overriden!");
|
throw new InvalidOperationException("Method " + uo.Info.Name + " cannot be overriden!");
|
||||||
|
}
|
||||||
|
|
||||||
// there's no technical reason to disallow this, but we wouldn't be doing anything
|
// there's no technical reason to disallow this, but we wouldn't be doing anything
|
||||||
// with the base implementation, so it's probably a user error
|
// with the base implementation, so it's probably a user error
|
||||||
var na = baseMethods.FirstOrDefault(a => !a.Info.IsAbstract);
|
var na = baseMethods.FirstOrDefault(a => !a.Info.IsAbstract);
|
||||||
if (na != null)
|
if (na != null)
|
||||||
|
{
|
||||||
throw new InvalidOperationException("Method " + na.Info.Name + " is not abstract!");
|
throw new InvalidOperationException("Method " + na.Info.Name + " is not abstract!");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// hooks that will be run on the created proxy object
|
// hooks that will be run on the created proxy object
|
||||||
var postCreateHooks = new List<Action<object, IImportResolver>>();
|
var postCreateHooks = new List<Action<object, IImportResolver>>();
|
||||||
|
@ -171,7 +175,9 @@ namespace BizHawk.Emulation.Common.BizInvoke
|
||||||
ImplType = type.CreateType()
|
ImplType = type.CreateType()
|
||||||
};
|
};
|
||||||
if (monitor)
|
if (monitor)
|
||||||
|
{
|
||||||
ret.ConnectMonitor = (o, m) => o.GetType().GetField(monitorField.Name).SetValue(o, m);
|
ret.ConnectMonitor = (o, m) => o.GetType().GetField(monitorField.Name).SetValue(o, m);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -234,7 +240,9 @@ namespace BizHawk.Emulation.Common.BizInvoke
|
||||||
il.Emit(OpCodes.Ldarg_0);
|
il.Emit(OpCodes.Ldarg_0);
|
||||||
il.Emit(OpCodes.Ldfld, field);
|
il.Emit(OpCodes.Ldfld, field);
|
||||||
for (int i = 0; i < paramTypes.Length; i++)
|
for (int i = 0; i < paramTypes.Length; i++)
|
||||||
|
{
|
||||||
il.Emit(OpCodes.Ldarg, (short)(i + 1));
|
il.Emit(OpCodes.Ldarg, (short)(i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
il.Emit(OpCodes.Callvirt, delegateInvoke);
|
il.Emit(OpCodes.Callvirt, delegateInvoke);
|
||||||
|
|
||||||
|
@ -354,11 +362,18 @@ namespace BizHawk.Emulation.Common.BizInvoke
|
||||||
private static void LoadConstant(ILGenerator il, IntPtr p)
|
private static void LoadConstant(ILGenerator il, IntPtr p)
|
||||||
{
|
{
|
||||||
if (p == IntPtr.Zero)
|
if (p == IntPtr.Zero)
|
||||||
|
{
|
||||||
il.Emit(OpCodes.Ldc_I4_0);
|
il.Emit(OpCodes.Ldc_I4_0);
|
||||||
|
}
|
||||||
else if (IntPtr.Size == 4)
|
else if (IntPtr.Size == 4)
|
||||||
|
{
|
||||||
il.Emit(OpCodes.Ldc_I4, (int)p);
|
il.Emit(OpCodes.Ldc_I4, (int)p);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
il.Emit(OpCodes.Ldc_I8, (long)p);
|
il.Emit(OpCodes.Ldc_I8, (long)p);
|
||||||
|
}
|
||||||
|
|
||||||
il.Emit(OpCodes.Conv_I);
|
il.Emit(OpCodes.Conv_I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,11 +383,18 @@ namespace BizHawk.Emulation.Common.BizInvoke
|
||||||
private static void LoadConstant(ILGenerator il, UIntPtr p)
|
private static void LoadConstant(ILGenerator il, UIntPtr p)
|
||||||
{
|
{
|
||||||
if (p == UIntPtr.Zero)
|
if (p == UIntPtr.Zero)
|
||||||
|
{
|
||||||
il.Emit(OpCodes.Ldc_I4_0);
|
il.Emit(OpCodes.Ldc_I4_0);
|
||||||
|
}
|
||||||
else if (UIntPtr.Size == 4)
|
else if (UIntPtr.Size == 4)
|
||||||
|
{
|
||||||
il.Emit(OpCodes.Ldc_I4, (int)p);
|
il.Emit(OpCodes.Ldc_I4, (int)p);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
il.Emit(OpCodes.Ldc_I8, (long)p);
|
il.Emit(OpCodes.Ldc_I8, (long)p);
|
||||||
|
}
|
||||||
|
|
||||||
il.Emit(OpCodes.Conv_U);
|
il.Emit(OpCodes.Conv_U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,12 +404,18 @@ namespace BizHawk.Emulation.Common.BizInvoke
|
||||||
private static Type EmitParamterLoad(ILGenerator il, int idx, Type type)
|
private static Type EmitParamterLoad(ILGenerator il, int idx, Type type)
|
||||||
{
|
{
|
||||||
if (type.IsGenericType)
|
if (type.IsGenericType)
|
||||||
|
{
|
||||||
throw new InvalidOperationException("Generic types not supported");
|
throw new InvalidOperationException("Generic types not supported");
|
||||||
|
}
|
||||||
|
|
||||||
if (type.IsByRef)
|
if (type.IsByRef)
|
||||||
{
|
{
|
||||||
var et = type.GetElementType();
|
var et = type.GetElementType();
|
||||||
if (!et.IsPrimitive && !et.IsEnum)
|
if (!et.IsPrimitive && !et.IsEnum)
|
||||||
|
{
|
||||||
throw new InvalidOperationException("Only refs of primitive or enum types are supported!");
|
throw new InvalidOperationException("Only refs of primitive or enum types are supported!");
|
||||||
|
}
|
||||||
|
|
||||||
var loc = il.DeclareLocal(type, true);
|
var loc = il.DeclareLocal(type, true);
|
||||||
il.Emit(OpCodes.Ldarg, (short)idx);
|
il.Emit(OpCodes.Ldarg, (short)idx);
|
||||||
il.Emit(OpCodes.Dup);
|
il.Emit(OpCodes.Dup);
|
||||||
|
@ -395,17 +423,24 @@ namespace BizHawk.Emulation.Common.BizInvoke
|
||||||
il.Emit(OpCodes.Conv_I);
|
il.Emit(OpCodes.Conv_I);
|
||||||
return typeof(IntPtr);
|
return typeof(IntPtr);
|
||||||
}
|
}
|
||||||
else if (type.IsArray)
|
|
||||||
|
if (type.IsArray)
|
||||||
{
|
{
|
||||||
var et = type.GetElementType();
|
var et = type.GetElementType();
|
||||||
if (!et.IsPrimitive && !et.IsEnum)
|
if (!et.IsPrimitive && !et.IsEnum)
|
||||||
|
{
|
||||||
throw new InvalidOperationException("Only arrays of primitive or enum types are supported!");
|
throw new InvalidOperationException("Only arrays of primitive or enum types are supported!");
|
||||||
|
}
|
||||||
|
|
||||||
// these two cases aren't too hard to add
|
// these two cases aren't too hard to add
|
||||||
if (type.GetArrayRank() > 1)
|
if (type.GetArrayRank() > 1)
|
||||||
|
{
|
||||||
throw new InvalidOperationException("Multidimensional arrays are not supported!");
|
throw new InvalidOperationException("Multidimensional arrays are not supported!");
|
||||||
|
}
|
||||||
if (type.Name.Contains('*'))
|
if (type.Name.Contains('*'))
|
||||||
|
{
|
||||||
throw new InvalidOperationException("Only 0-based 1-dimensional arrays are supported!");
|
throw new InvalidOperationException("Only 0-based 1-dimensional arrays are supported!");
|
||||||
|
}
|
||||||
|
|
||||||
var loc = il.DeclareLocal(type, true);
|
var loc = il.DeclareLocal(type, true);
|
||||||
var end = il.DefineLabel();
|
var end = il.DefineLabel();
|
||||||
|
@ -428,7 +463,8 @@ namespace BizHawk.Emulation.Common.BizInvoke
|
||||||
|
|
||||||
return typeof(IntPtr);
|
return typeof(IntPtr);
|
||||||
}
|
}
|
||||||
else if (typeof(Delegate).IsAssignableFrom(type))
|
|
||||||
|
if (typeof(Delegate).IsAssignableFrom(type))
|
||||||
{
|
{
|
||||||
var mi = typeof(Marshal).GetMethod("GetFunctionPointerForDelegate", new[] { typeof(Delegate) });
|
var mi = typeof(Marshal).GetMethod("GetFunctionPointerForDelegate", new[] { typeof(Delegate) });
|
||||||
var end = il.DefineLabel();
|
var end = il.DefineLabel();
|
||||||
|
@ -446,23 +482,25 @@ namespace BizHawk.Emulation.Common.BizInvoke
|
||||||
il.MarkLabel(end);
|
il.MarkLabel(end);
|
||||||
return typeof(IntPtr);
|
return typeof(IntPtr);
|
||||||
}
|
}
|
||||||
else if (type.IsPrimitive || type.IsEnum)
|
|
||||||
|
if (type.IsPrimitive || type.IsEnum)
|
||||||
{
|
{
|
||||||
il.Emit(OpCodes.Ldarg, (short)idx);
|
il.Emit(OpCodes.Ldarg, (short)idx);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Unrecognized parameter type!");
|
throw new InvalidOperationException("Unrecognized parameter type!");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static CustomAttributeBuilder GetAttributeBuilder(object o)
|
private static CustomAttributeBuilder GetAttributeBuilder(object o)
|
||||||
{
|
{
|
||||||
// anything more clever we can do here?
|
// anything more clever we can do here?
|
||||||
var t = o.GetType();
|
var t = o.GetType();
|
||||||
if (t == typeof(OutAttribute) || t == typeof(InAttribute))
|
if (t == typeof(OutAttribute) || t == typeof(InAttribute))
|
||||||
|
{
|
||||||
return new CustomAttributeBuilder(t.GetConstructor(Type.EmptyTypes), new object[0]);
|
return new CustomAttributeBuilder(t.GetConstructor(Type.EmptyTypes), new object[0]);
|
||||||
|
}
|
||||||
|
|
||||||
throw new InvalidOperationException("Unknown parameter attribute " + t.Name);
|
throw new InvalidOperationException("Unknown parameter attribute " + t.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Common
|
namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
// the idea here is that various connected peripherals have their controls all merged
|
// the idea here is that various connected peripherals have their controls all merged
|
||||||
// into one definition, including logic to unmerge the data back so each one can work
|
// into one definition, including logic to unmerge the data back so each one can work
|
||||||
// with it without knowing what else is connected
|
// with it without knowing what else is connected
|
||||||
|
|
||||||
public static class ControllerDefinitionMerger
|
public static class ControllerDefinitionMerger
|
||||||
{
|
{
|
||||||
private static string Allocate(string input, ref int plr, ref int plrnext)
|
private static string Allocate(string input, ref int plr, ref int plrnext)
|
||||||
|
@ -16,22 +13,24 @@ namespace BizHawk.Emulation.Common
|
||||||
int offset = int.Parse(input.Substring(0, 1));
|
int offset = int.Parse(input.Substring(0, 1));
|
||||||
int currplr = plr + offset;
|
int currplr = plr + offset;
|
||||||
if (currplr >= plrnext)
|
if (currplr >= plrnext)
|
||||||
|
{
|
||||||
plrnext = currplr + 1;
|
plrnext = currplr + 1;
|
||||||
return string.Format("P{0} {1}", currplr, input.Substring(1));
|
}
|
||||||
|
|
||||||
|
return $"P{currplr} {input.Substring(1)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// merge some controller definitions for different ports, and such. i promise to fully document this tomorrow
|
/// merge some controller definitions for different ports, and such. i promise to fully document this tomorrow
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Controllers"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static ControllerDefinition GetMerged(IEnumerable<ControllerDefinition> Controllers, out List<ControlDefUnMerger> Unmergers)
|
public static ControllerDefinition GetMerged(IEnumerable<ControllerDefinition> controllers, out List<ControlDefUnMerger> unmergers)
|
||||||
{
|
{
|
||||||
ControllerDefinition ret = new ControllerDefinition();
|
ControllerDefinition ret = new ControllerDefinition();
|
||||||
Unmergers = new List<ControlDefUnMerger>();
|
unmergers = new List<ControlDefUnMerger>();
|
||||||
int plr = 1;
|
int plr = 1;
|
||||||
int plrnext = 1;
|
int plrnext = 1;
|
||||||
foreach (var def in Controllers)
|
foreach (var def in controllers)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> remaps = new Dictionary<string, string>();
|
Dictionary<string, string> remaps = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
@ -41,33 +40,37 @@ namespace BizHawk.Emulation.Common
|
||||||
ret.BoolButtons.Add(r);
|
ret.BoolButtons.Add(r);
|
||||||
remaps[s] = r;
|
remaps[s] = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (string s in def.FloatControls)
|
foreach (string s in def.FloatControls)
|
||||||
{
|
{
|
||||||
string r = Allocate(s, ref plr, ref plrnext);
|
string r = Allocate(s, ref plr, ref plrnext);
|
||||||
ret.FloatControls.Add(r);
|
ret.FloatControls.Add(r);
|
||||||
remaps[s] = r;
|
remaps[s] = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.FloatRanges.AddRange(def.FloatRanges);
|
ret.FloatRanges.AddRange(def.FloatRanges);
|
||||||
plr = plrnext;
|
plr = plrnext;
|
||||||
Unmergers.Add(new ControlDefUnMerger(remaps));
|
unmergers.Add(new ControlDefUnMerger(remaps));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ControlDefUnMerger
|
public class ControlDefUnMerger
|
||||||
{
|
{
|
||||||
Dictionary<string, string> Remaps;
|
private readonly Dictionary<string, string> Remaps;
|
||||||
|
|
||||||
public ControlDefUnMerger(Dictionary<string, string> Remaps)
|
public ControlDefUnMerger(Dictionary<string, string> remaps)
|
||||||
{
|
{
|
||||||
this.Remaps = Remaps;
|
Remaps = remaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DummyController : IController
|
private class DummyController : IController
|
||||||
{
|
{
|
||||||
IController src;
|
private readonly IController src;
|
||||||
Dictionary<string, string> remaps;
|
private readonly Dictionary<string, string> remaps;
|
||||||
|
|
||||||
public DummyController(IController src, Dictionary<string, string> remaps)
|
public DummyController(IController src, Dictionary<string, string> remaps)
|
||||||
{
|
{
|
||||||
this.src = src;
|
this.src = src;
|
||||||
|
@ -76,7 +79,7 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
public ControllerDefinition Definition { get { throw new NotImplementedException(); } }
|
public ControllerDefinition Definition { get { throw new NotImplementedException(); } }
|
||||||
|
|
||||||
public bool this[string button] { get { return IsPressed(button); } }
|
public bool this[string button] => IsPressed(button);
|
||||||
|
|
||||||
public bool IsPressed(string button)
|
public bool IsPressed(string button)
|
||||||
{
|
{
|
||||||
|
@ -93,6 +96,5 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
return new DummyController(c, Remaps);
|
return new DummyController(c, Remaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,10 @@ namespace BizHawk.Emulation.Common
|
||||||
/// <seealso cref="IEmulator" />
|
/// <seealso cref="IEmulator" />
|
||||||
public class CoreComm
|
public class CoreComm
|
||||||
{
|
{
|
||||||
public CoreComm(Action<string> showMessage, Action<string> NotifyMessage)
|
public CoreComm(Action<string> showMessage, Action<string> notifyMessage)
|
||||||
{
|
{
|
||||||
ShowMessage = showMessage;
|
ShowMessage = showMessage;
|
||||||
Notify = NotifyMessage;
|
Notify = notifyMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICoreFileProvider CoreFileProvider;
|
public ICoreFileProvider CoreFileProvider;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// we could get a little list of crcs from here and make it clear which crc this class was for, and expose others
|
// we could get a little list of crcs from here and make it clear which crc this class was for, and expose others
|
||||||
// http://www.ross.net/crc/download/crc_v3.txt
|
// http://www.ross.net/crc/download/crc_v3.txt
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Common
|
namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
// TODO - why am I here? put me alongside hash_md5 and such in a non-emulation-related class
|
// TODO - why am I here? put me alongside hash_md5 and such in a non-emulation-related class
|
||||||
|
@ -18,10 +17,14 @@ namespace BizHawk.Emulation.Common
|
||||||
for (int j = 8; j > 0; --j)
|
for (int j = 8; j > 0; --j)
|
||||||
{
|
{
|
||||||
if ((crc & 1) == 1)
|
if ((crc & 1) == 1)
|
||||||
crc = ((crc >> 1) ^ 0xEDB88320);
|
{
|
||||||
|
crc = (crc >> 1) ^ 0xEDB88320;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
crc >>= 1;
|
crc >>= 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CRC32Table[i] = crc;
|
CRC32Table[i] = crc;
|
||||||
}
|
}
|
||||||
|
@ -29,11 +32,13 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
public static int Calculate(byte[] data)
|
public static int Calculate(byte[] data)
|
||||||
{
|
{
|
||||||
uint Result = 0xFFFFFFFF;
|
uint result = 0xFFFFFFFF;
|
||||||
foreach (var b in data)
|
foreach (var b in data)
|
||||||
Result = (((Result) >> 8) ^ CRC32Table[b ^ ((Result) & 0xFF)]);
|
{
|
||||||
|
result = (result >> 8) ^ CRC32Table[b ^ (result & 0xFF)];
|
||||||
|
}
|
||||||
|
|
||||||
return (int) ~Result;
|
return (int)~result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ namespace BizHawk.Emulation.Common
|
||||||
public static GameInfo GetGameInfo(byte[] romData, string fileName)
|
public static GameInfo GetGameInfo(byte[] romData, string fileName)
|
||||||
{
|
{
|
||||||
CompactGameInfo cgi;
|
CompactGameInfo cgi;
|
||||||
var hash = string.Format("{0:X8}", CRC32.Calculate(romData));
|
var hash = $"{CRC32.Calculate(romData):X8}";
|
||||||
if (db.TryGetValue(hash, out cgi))
|
if (db.TryGetValue(hash, out cgi))
|
||||||
{
|
{
|
||||||
return new GameInfo(cgi);
|
return new GameInfo(cgi);
|
||||||
|
|
|
@ -168,12 +168,12 @@ namespace BizHawk.Emulation.Common
|
||||||
Option("PSX", "U", ps_30a);
|
Option("PSX", "U", ps_30a);
|
||||||
Option("PSX", "J", ps_30j);
|
Option("PSX", "J", ps_30j);
|
||||||
Option("PSX", "E", ps_30e);
|
Option("PSX", "E", ps_30e);
|
||||||
|
|
||||||
// in general, alternates arent allowed.. their quality isnt known.
|
// in general, alternates arent allowed.. their quality isnt known.
|
||||||
// we have this comment from fobby.net: "SCPH7502 works fine for European games" (TBD)
|
// we have this comment from fobby.net: "SCPH7502 works fine for European games" (TBD)
|
||||||
// however, we're sticking with the 3.0 series.
|
// however, we're sticking with the 3.0 series.
|
||||||
// please note: 2.1 or 2.2 would be a better choice, as the dates are the same and the bioses are more likely to matching in terms of entrypoints and such.
|
// please note: 2.1 or 2.2 would be a better choice, as the dates are the same and the bioses are more likely to matching in terms of entrypoints and such.
|
||||||
// but 3.0 is what mednafen used
|
// but 3.0 is what mednafen used
|
||||||
|
|
||||||
Option("PSX", "J", ps_10j, FirmwareOptionStatus.Unacceptable);
|
Option("PSX", "J", ps_10j, FirmwareOptionStatus.Unacceptable);
|
||||||
Option("PSX", "J", ps_11j, FirmwareOptionStatus.Unacceptable);
|
Option("PSX", "J", ps_11j, FirmwareOptionStatus.Unacceptable);
|
||||||
Option("PSX", "U", ps_20a, FirmwareOptionStatus.Unacceptable);
|
Option("PSX", "U", ps_20a, FirmwareOptionStatus.Unacceptable);
|
||||||
|
@ -205,7 +205,7 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds a defined firmware ID to the database
|
// adds a defined firmware ID to the database
|
||||||
static void Firmware(string systemId, string id, string descr)
|
private static void Firmware(string systemId, string id, string descr)
|
||||||
{
|
{
|
||||||
var fr = new FirmwareRecord
|
var fr = new FirmwareRecord
|
||||||
{
|
{
|
||||||
|
@ -218,7 +218,7 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds an acceptable option for a firmware ID to the database
|
// adds an acceptable option for a firmware ID to the database
|
||||||
static FirmwareOption Option(string hash, long size, string systemId, string id, FirmwareOptionStatus status = FirmwareOptionStatus.Acceptable)
|
private static FirmwareOption Option(string hash, long size, string systemId, string id, FirmwareOptionStatus status = FirmwareOptionStatus.Acceptable)
|
||||||
{
|
{
|
||||||
var fo = new FirmwareOption
|
var fo = new FirmwareOption
|
||||||
{
|
{
|
||||||
|
@ -233,22 +233,29 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
// first option is automatically ideal
|
// first option is automatically ideal
|
||||||
if (FirmwareOptions.Count == 1 && fo.status == FirmwareOptionStatus.Acceptable)
|
if (FirmwareOptions.Count == 1 && fo.status == FirmwareOptionStatus.Acceptable)
|
||||||
|
{
|
||||||
fo.status = FirmwareOptionStatus.Ideal;
|
fo.status = FirmwareOptionStatus.Ideal;
|
||||||
|
}
|
||||||
|
|
||||||
return fo;
|
return fo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds an acceptable option for a firmware ID to the database
|
// adds an acceptable option for a firmware ID to the database
|
||||||
static FirmwareOption Option(string systemId, string id, FirmwareFile ff, FirmwareOptionStatus status = FirmwareOptionStatus.Acceptable)
|
private static FirmwareOption Option(string systemId, string id, FirmwareFile ff, FirmwareOptionStatus status = FirmwareOptionStatus.Acceptable)
|
||||||
{
|
{
|
||||||
var fo = Option(ff.hash, ff.size, systemId, id, status);
|
var fo = Option(ff.hash, ff.size, systemId, id, status);
|
||||||
|
|
||||||
// make sure this goes in as bad
|
// make sure this goes in as bad
|
||||||
if(ff.bad) fo.status = FirmwareOptionStatus.Bad;
|
if (ff.bad)
|
||||||
|
{
|
||||||
|
fo.status = FirmwareOptionStatus.Bad;
|
||||||
|
}
|
||||||
|
|
||||||
return fo;
|
return fo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// defines a firmware file
|
// defines a firmware file
|
||||||
static FirmwareFile File(string hash, long size, string recommendedName, string descr, string additionalInfo = "")
|
private static FirmwareFile File(string hash, long size, string recommendedName, string descr, string additionalInfo = "")
|
||||||
{
|
{
|
||||||
string hashfix = hash.ToUpperInvariant();
|
string hashfix = hash.ToUpperInvariant();
|
||||||
|
|
||||||
|
@ -266,7 +273,7 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds a defined firmware ID and one file and option
|
// adds a defined firmware ID and one file and option
|
||||||
static void FirmwareAndOption(string hash, long size, string systemId, string id, string name, string descr)
|
private static void FirmwareAndOption(string hash, long size, string systemId, string id, string name, string descr)
|
||||||
{
|
{
|
||||||
Firmware(systemId, id, descr);
|
Firmware(systemId, id, descr);
|
||||||
File(hash, size, name, descr, "");
|
File(hash, size, name, descr, "");
|
||||||
|
@ -274,9 +281,9 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static List<FirmwareRecord> FirmwareRecords = new List<FirmwareRecord>();
|
public static readonly List<FirmwareRecord> FirmwareRecords = new List<FirmwareRecord>();
|
||||||
public static List<FirmwareOption> FirmwareOptions = new List<FirmwareOption>();
|
public static readonly List<FirmwareOption> FirmwareOptions = new List<FirmwareOption>();
|
||||||
public static List<FirmwareFile> FirmwareFiles = new List<FirmwareFile>();
|
public static readonly List<FirmwareFile> FirmwareFiles = new List<FirmwareFile>();
|
||||||
|
|
||||||
public static Dictionary<string, FirmwareFile> FirmwareFilesByHash = new Dictionary<string, FirmwareFile>();
|
public static Dictionary<string, FirmwareFile> FirmwareFilesByHash = new Dictionary<string, FirmwareFile>();
|
||||||
|
|
||||||
|
@ -295,7 +302,7 @@ namespace BizHawk.Emulation.Common
|
||||||
public string systemId;
|
public string systemId;
|
||||||
public string firmwareId;
|
public string firmwareId;
|
||||||
public string descr;
|
public string descr;
|
||||||
public string ConfigKey { get { return string.Format("{0}+{1}", systemId, firmwareId); } }
|
public string ConfigKey => $"{systemId}+{firmwareId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum FirmwareOptionStatus
|
public enum FirmwareOptionStatus
|
||||||
|
@ -311,7 +318,7 @@ namespace BizHawk.Emulation.Common
|
||||||
public long size;
|
public long size;
|
||||||
public FirmwareOptionStatus status;
|
public FirmwareOptionStatus status;
|
||||||
public bool IsAcceptableOrIdeal { get { return status == FirmwareOptionStatus.Ideal || status == FirmwareOptionStatus.Acceptable; } }
|
public bool IsAcceptableOrIdeal { get { return status == FirmwareOptionStatus.Ideal || status == FirmwareOptionStatus.Acceptable; } }
|
||||||
public string ConfigKey { get { return string.Format("{0}+{1}", systemId, firmwareId); } }
|
public string ConfigKey => $"{systemId}+{firmwareId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -325,6 +332,5 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
return found.FirstOrDefault();
|
return found.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // static class FirmwareDatabase
|
} // static class FirmwareDatabase
|
||||||
}
|
}
|
|
@ -13,18 +13,20 @@ namespace BizHawk.Emulation.Common
|
||||||
return Status == RomStatus.BadDump || Status == RomStatus.Overdump;
|
return Status == RomStatus.BadDump || Status == RomStatus.Overdump;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name;
|
public string Name { get; set; }
|
||||||
public string System;
|
public string System { get; set; }
|
||||||
public string Hash;
|
public string Hash { get; set; }
|
||||||
public string Region;
|
public string Region { get; set; }
|
||||||
public RomStatus Status = RomStatus.NotInDatabase;
|
public RomStatus Status { get; set; } = RomStatus.NotInDatabase;
|
||||||
public bool NotInDatabase = true;
|
public bool NotInDatabase { get; set; } = true;
|
||||||
public string FirmwareHash;
|
public string FirmwareHash { get; set; }
|
||||||
public string ForcedCore;
|
public string ForcedCore { get; private set; }
|
||||||
|
|
||||||
Dictionary<string, string> Options = new Dictionary<string, string>();
|
private Dictionary<string, string> Options { get; set; } = new Dictionary<string, string>();
|
||||||
|
|
||||||
public GameInfo() { }
|
public GameInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public GameInfo Clone()
|
public GameInfo Clone()
|
||||||
{
|
{
|
||||||
|
@ -33,27 +35,18 @@ namespace BizHawk.Emulation.Common
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameInfo NullInstance
|
public static GameInfo NullInstance => new GameInfo
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return new GameInfo
|
|
||||||
{
|
{
|
||||||
Name = "Null",
|
Name = "Null",
|
||||||
System = "NULL",
|
System = "NULL",
|
||||||
Hash = "",
|
Hash = string.Empty,
|
||||||
Region = "",
|
Region = string.Empty,
|
||||||
Status = RomStatus.GoodDump,
|
Status = RomStatus.GoodDump,
|
||||||
ForcedCore = "",
|
ForcedCore = string.Empty,
|
||||||
NotInDatabase = false
|
NotInDatabase = false
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsNullInstance
|
public bool IsNullInstance => System == "NULL";
|
||||||
{
|
|
||||||
get { return System == "NULL"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal GameInfo(CompactGameInfo cgi)
|
internal GameInfo(CompactGameInfo cgi)
|
||||||
{
|
{
|
||||||
|
@ -82,10 +75,7 @@ namespace BizHawk.Emulation.Common
|
||||||
Options.Remove(option);
|
Options.Remove(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool this[string option]
|
public bool this[string option] => Options.ContainsKey(option);
|
||||||
{
|
|
||||||
get { return Options.ContainsKey(option); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OptionPresent(string option)
|
public bool OptionPresent(string option)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +85,10 @@ namespace BizHawk.Emulation.Common
|
||||||
public string OptionValue(string option)
|
public string OptionValue(string option)
|
||||||
{
|
{
|
||||||
if (Options.ContainsKey(option))
|
if (Options.ContainsKey(option))
|
||||||
|
{
|
||||||
return Options[option];
|
return Options[option];
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,25 +107,37 @@ namespace BizHawk.Emulation.Common
|
||||||
return int.Parse(Options[option], NumberStyles.HexNumber);
|
return int.Parse(Options[option], NumberStyles.HexNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// /// Gets a boolean value from the database
|
||||||
|
/// </summary>
|
||||||
/// <param name="parameter">The option to look up</param>
|
/// <param name="parameter">The option to look up</param>
|
||||||
/// <param name="defaultVal">The value to return if the option is invalid or doesn't exist</param>
|
/// <param name="defaultVal">The value to return if the option is invalid or doesn't exist</param>
|
||||||
/// <returns> The bool value from the database if present, otherwise the given default value</returns>
|
/// <returns> The boolean value from the database if present, otherwise the given default value</returns>
|
||||||
public bool GetBool(string parameter, bool defaultVal)
|
public bool GetBool(string parameter, bool defaultVal)
|
||||||
{
|
{
|
||||||
if (OptionPresent(parameter) && OptionValue(parameter) == "true")
|
if (OptionPresent(parameter) && OptionValue(parameter) == "true")
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
else if (OptionPresent(parameter) && OptionValue(parameter) == "false")
|
}
|
||||||
|
|
||||||
|
if (OptionPresent(parameter) && OptionValue(parameter) == "false")
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
else
|
}
|
||||||
|
|
||||||
return defaultVal;
|
return defaultVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// /// Gets an integer value from the database
|
||||||
|
/// </summary>
|
||||||
/// <param name="parameter">The option to look up</param>
|
/// <param name="parameter">The option to look up</param>
|
||||||
/// <param name="defaultVal">The value to return if the option is invalid or doesn't exist</param>
|
/// <param name="defaultVal">The value to return if the option is invalid or doesn't exist</param>
|
||||||
/// <returns> The int value from the database if present, otherwise the given default value</returns>
|
/// <returns> The integer value from the database if present, otherwise the given default value</returns>
|
||||||
public int GetInt(string parameter, int defaultVal)
|
public int GetInt(string parameter, int defaultVal)
|
||||||
{
|
{
|
||||||
if (OptionPresent(parameter))
|
if (OptionPresent(parameter))
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return int.Parse(OptionValue(parameter));
|
return int.Parse(OptionValue(parameter));
|
||||||
|
@ -141,24 +146,27 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
return defaultVal;
|
return defaultVal;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
return defaultVal;
|
return defaultVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICollection<string> GetOptions()
|
public ICollection<string> GetOptions()
|
||||||
{
|
{
|
||||||
return Options.Keys;
|
return Options.Keys;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDictionary<string, string> GetOptionsDict()
|
public IDictionary<string, string> GetOptionsDict()
|
||||||
{
|
{
|
||||||
return new ReadOnlyDictionary<string, string>(Options);
|
return new ReadOnlyDictionary<string, string>(Options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseOptionsDictionary(string metaData)
|
private void ParseOptionsDictionary(string metaData)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(metaData))
|
if (string.IsNullOrEmpty(metaData))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var options = metaData.Split(';').Where(opt => string.IsNullOrEmpty(opt) == false).ToArray();
|
var options = metaData.Split(';').Where(opt => string.IsNullOrEmpty(opt) == false).ToArray();
|
||||||
|
|
||||||
|
@ -166,7 +174,7 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
var parts = opt.Split('=');
|
var parts = opt.Split('=');
|
||||||
var key = parts[0];
|
var key = parts[0];
|
||||||
var value = parts.Length > 1 ? parts[1] : "";
|
var value = parts.Length > 1 ? parts[1] : string.Empty;
|
||||||
Options[key] = value;
|
Options[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace BizHawk.Emulation.Common
|
namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
public enum SyncSoundMode { Sync, Async };
|
public enum SyncSoundMode { Sync, Async }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This service provides the ability to output sound from the client,
|
/// This service provides the ability to output sound from the client,
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
using System.Collections.Generic;
|
namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Common
|
|
||||||
{
|
{
|
||||||
public interface ITraceSink
|
public interface ITraceSink
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,30 +6,31 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
public sealed class Equalizer
|
public sealed class Equalizer
|
||||||
{
|
{
|
||||||
double lowFilter;
|
private double lowFilter;
|
||||||
double lowFilterPole0;
|
private double lowFilterPole0;
|
||||||
double lowFilterPole1;
|
private double lowFilterPole1;
|
||||||
double lowFilterPole2;
|
private double lowFilterPole2;
|
||||||
double lowFilterPole3;
|
private double lowFilterPole3;
|
||||||
|
|
||||||
double highFilter;
|
private double highFilter;
|
||||||
double highFilterPole0;
|
private double highFilterPole0;
|
||||||
double highFilterPole1;
|
private double highFilterPole1;
|
||||||
double highFilterPole2;
|
private double highFilterPole2;
|
||||||
double highFilterPole3;
|
private double highFilterPole3;
|
||||||
|
|
||||||
double sampleDataMinus1;
|
private double sampleDataMinus1;
|
||||||
double sampleDataMinus2;
|
private double sampleDataMinus2;
|
||||||
double sampleDataMinus3;
|
private double sampleDataMinus3;
|
||||||
|
|
||||||
double lowGain;
|
private double lowGain;
|
||||||
double midGain;
|
private double midGain;
|
||||||
double highGain;
|
private double highGain;
|
||||||
|
|
||||||
const double sampleRate = 44100.0;
|
private const double sampleRate = 44100.0;
|
||||||
const double verySmallAmount = (1.0 / 4294967295.0);
|
private const double verySmallAmount = 1.0 / 4294967295.0;
|
||||||
|
|
||||||
|
private double lowfreq;
|
||||||
|
|
||||||
double lowfreq;
|
|
||||||
public double LowFreqCutoff
|
public double LowFreqCutoff
|
||||||
{
|
{
|
||||||
get { return lowfreq; }
|
get { return lowfreq; }
|
||||||
|
@ -40,7 +41,7 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double highfreq;
|
private double highfreq;
|
||||||
public double HighFreqCutoff
|
public double HighFreqCutoff
|
||||||
{
|
{
|
||||||
get { return highfreq; }
|
get { return highfreq; }
|
||||||
|
@ -89,7 +90,9 @@ namespace BizHawk.Emulation.Common
|
||||||
public void Equalize(short[] samples)
|
public void Equalize(short[] samples)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < samples.Length; i++)
|
for (int i = 0; i < samples.Length; i++)
|
||||||
|
{
|
||||||
samples[i] = EqualizeSample(samples[i]);
|
samples[i] = EqualizeSample(samples[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -64,7 +64,7 @@ namespace BizHawk.Emulation.Common
|
||||||
// is to provide exact amounts of output samples,
|
// is to provide exact amounts of output samples,
|
||||||
// even when the input provided varies....
|
// even when the input provided varies....
|
||||||
int output_samples(short[] buf, int samples_requested);
|
int output_samples(short[] buf, int samples_requested);
|
||||||
};
|
}
|
||||||
|
|
||||||
public enum ESynchMethod
|
public enum ESynchMethod
|
||||||
{
|
{
|
||||||
|
@ -72,7 +72,7 @@ namespace BizHawk.Emulation.Common
|
||||||
ESynchMethod_Z, // zero's
|
ESynchMethod_Z, // zero's
|
||||||
//ESynchMethod_P, //PCSX2 spu2-x //ohno! not available yet in c#
|
//ESynchMethod_P, //PCSX2 spu2-x //ohno! not available yet in c#
|
||||||
ESynchMethod_V // vecna
|
ESynchMethod_V // vecna
|
||||||
};
|
}
|
||||||
|
|
||||||
public static class Metaspu
|
public static class Metaspu
|
||||||
{
|
{
|
||||||
|
@ -136,8 +136,10 @@ namespace BizHawk.Emulation.Common
|
||||||
if (!mixqueue_go)
|
if (!mixqueue_go)
|
||||||
{
|
{
|
||||||
if (adjustobuf.size > 200)
|
if (adjustobuf.size > 200)
|
||||||
|
{
|
||||||
mixqueue_go = true;
|
mixqueue_go = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < samples_requested; i++)
|
for (int i = 0; i < samples_requested; i++)
|
||||||
|
@ -147,6 +149,7 @@ namespace BizHawk.Emulation.Common
|
||||||
mixqueue_go = false;
|
mixqueue_go = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
done++;
|
done++;
|
||||||
short left, right;
|
short left, right;
|
||||||
adjustobuf.dequeue(out left, out right);
|
adjustobuf.dequeue(out left, out right);
|
||||||
|
@ -159,7 +162,8 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Adjustobuf adjustobuf;
|
private readonly Adjustobuf adjustobuf;
|
||||||
class Adjustobuf
|
|
||||||
|
private class Adjustobuf
|
||||||
{
|
{
|
||||||
public Adjustobuf(int _minLatency, int _maxLatency)
|
public Adjustobuf(int _minLatency, int _maxLatency)
|
||||||
{
|
{
|
||||||
|
@ -168,12 +172,12 @@ namespace BizHawk.Emulation.Common
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
float rate, cursor;
|
private float rate, cursor;
|
||||||
int minLatency, targetLatency, maxLatency;
|
private int minLatency, targetLatency, maxLatency;
|
||||||
Queue<short> buffer = new Queue<short>();
|
private readonly Queue<short> buffer = new Queue<short>();
|
||||||
Queue<int> statsHistory = new Queue<int>();
|
private readonly Queue<int> statsHistory = new Queue<int>();
|
||||||
public int size = 0;
|
public int size = 0;
|
||||||
short[] curr = new short[2];
|
private readonly short[] curr = new short[2];
|
||||||
|
|
||||||
public void clear()
|
public void clear()
|
||||||
{
|
{
|
||||||
|
@ -195,11 +199,11 @@ namespace BizHawk.Emulation.Common
|
||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
long rollingTotalSize;
|
private long rollingTotalSize;
|
||||||
|
|
||||||
uint kAverageSize;
|
private uint kAverageSize;
|
||||||
|
|
||||||
void addStatistic()
|
private void addStatistic()
|
||||||
{
|
{
|
||||||
statsHistory.Enqueue(size);
|
statsHistory.Enqueue(size);
|
||||||
rollingTotalSize += size;
|
rollingTotalSize += size;
|
||||||
|
@ -227,15 +231,17 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dequeue(out short left, out short right)
|
public void dequeue(out short left, out short right)
|
||||||
{
|
{
|
||||||
left = right = 0;
|
left = right = 0;
|
||||||
addStatistic();
|
addStatistic();
|
||||||
if (size == 0) { return; }
|
if (size == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cursor += rate;
|
cursor += rate;
|
||||||
while (cursor > 1.0f)
|
while (cursor > 1.0f)
|
||||||
{
|
{
|
||||||
|
@ -254,22 +260,29 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NitsujaSynchronizer : ISynchronizingAudioBuffer
|
internal class NitsujaSynchronizer : ISynchronizingAudioBuffer
|
||||||
{
|
{
|
||||||
struct ssamp
|
private struct ssamp
|
||||||
{
|
{
|
||||||
public short l, r;
|
public short l, r;
|
||||||
public ssamp(short ll, short rr) { l = ll; r = rr; }
|
|
||||||
};
|
|
||||||
|
|
||||||
readonly List<ssamp> sampleQueue = new List<ssamp>();
|
public ssamp(short ll, short rr)
|
||||||
|
{
|
||||||
|
l = ll; r = rr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<ssamp> sampleQueue = new List<ssamp>();
|
||||||
|
|
||||||
// returns values going between 0 and y-1 in a saw wave pattern, based on x
|
// returns values going between 0 and y-1 in a saw wave pattern, based on x
|
||||||
static int pingpong(int x, int y)
|
private static int pingpong(int x, int y)
|
||||||
{
|
{
|
||||||
x %= 2 * y;
|
x %= 2 * y;
|
||||||
if (x >= y)
|
if (x >= y)
|
||||||
x = 2 * y - x - 1;
|
{
|
||||||
|
x = (2 * y) - x - 1;
|
||||||
|
}
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
|
|
||||||
// in case we want to switch to odd buffer sizes for more sharpness
|
// in case we want to switch to odd buffer sizes for more sharpness
|
||||||
|
@ -279,12 +292,17 @@ namespace BizHawk.Emulation.Common
|
||||||
//return x;
|
//return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssamp crossfade(ssamp lhs, ssamp rhs, int cur, int start, int end)
|
private static ssamp crossfade(ssamp lhs, ssamp rhs, int cur, int start, int end)
|
||||||
{
|
{
|
||||||
if (cur <= start)
|
if (cur <= start)
|
||||||
|
{
|
||||||
return lhs;
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
if (cur >= end)
|
if (cur >= end)
|
||||||
|
{
|
||||||
return rhs;
|
return rhs;
|
||||||
|
}
|
||||||
|
|
||||||
// in case we want sine wave interpolation instead of linear here
|
// in case we want sine wave interpolation instead of linear here
|
||||||
//float ang = 3.14159f * (float)(cur - start) / (float)(end - start);
|
//float ang = 3.14159f * (float)(cur - start) / (float)(end - start);
|
||||||
|
@ -305,28 +323,38 @@ namespace BizHawk.Emulation.Common
|
||||||
sampleQueue.Clear();
|
sampleQueue.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_sample(short[] outbuf, ref int cursor, ssamp sample)
|
private static void emit_sample(short[] outbuf, ref int cursor, ssamp sample)
|
||||||
{
|
{
|
||||||
outbuf[cursor++] = sample.l;
|
outbuf[cursor++] = sample.l;
|
||||||
outbuf[cursor++] = sample.r;
|
outbuf[cursor++] = sample.r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_samples(short[] outbuf, ref int outcursor, ssamp[] samplebuf, int incursor, int samples)
|
private static void emit_samples(short[] outbuf, ref int outcursor, ssamp[] samplebuf, int incursor, int samples)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < samples; i++)
|
for (int i = 0; i < samples; i++)
|
||||||
|
{
|
||||||
emit_sample(outbuf, ref outcursor, samplebuf[i + incursor]);
|
emit_sample(outbuf, ref outcursor, samplebuf[i + incursor]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static short abs(short value)
|
|
||||||
{
|
|
||||||
if (value < 0) return (short)-value;
|
|
||||||
else return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int abs(int value)
|
private static short abs(short value)
|
||||||
{
|
{
|
||||||
if (value < 0) return -value;
|
if (value < 0)
|
||||||
else return value;
|
{
|
||||||
|
return (short)-value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int abs(int value)
|
||||||
|
{
|
||||||
|
if (value < 0)
|
||||||
|
{
|
||||||
|
return -value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enqueue_samples(short[] buf, int samples_provided)
|
public void enqueue_samples(short[] buf, int samples_provided)
|
||||||
|
@ -420,6 +448,7 @@ namespace BizHawk.Emulation.Common
|
||||||
beststart = i;
|
beststart = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = queued - 3; i > queued - 3 - 128; i -= 2)
|
for (int i = queued - 3; i > queued - 3 - 128; i -= 2)
|
||||||
{
|
{
|
||||||
int diff = abs(sampleQueue[i].l - sampleQueue[i + 1].l) + abs(sampleQueue[i].r - sampleQueue[i + 1].r);
|
int diff = abs(sampleQueue[i].l - sampleQueue[i + 1].l) + abs(sampleQueue[i].r - sampleQueue[i + 1].r);
|
||||||
|
@ -435,13 +464,17 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
int oksize = queued;
|
int oksize = queued;
|
||||||
while (oksize + queued * 2 + beststart + extraAtEnd <= samples_requested)
|
while (oksize + queued * 2 + beststart + extraAtEnd <= samples_requested)
|
||||||
|
{
|
||||||
oksize += queued * 2;
|
oksize += queued * 2;
|
||||||
|
}
|
||||||
|
|
||||||
audiosize = oksize;
|
audiosize = oksize;
|
||||||
|
|
||||||
for (int x = 0; x < beststart; x++)
|
for (int x = 0; x < beststart; x++)
|
||||||
{
|
{
|
||||||
emit_sample(buf, ref bufcursor, sampleQueue[x]);
|
emit_sample(buf, ref bufcursor, sampleQueue[x]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sampleQueue.erase(sampleQueue.begin(), sampleQueue.begin() + beststart);
|
// sampleQueue.erase(sampleQueue.begin(), sampleQueue.begin() + beststart);
|
||||||
sampleQueue.RemoveRange(0, beststart);
|
sampleQueue.RemoveRange(0, beststart);
|
||||||
// zero 08-nov-2010: did i do this right?
|
// zero 08-nov-2010: did i do this right?
|
||||||
|
@ -456,7 +489,6 @@ namespace BizHawk.Emulation.Common
|
||||||
// midpointXOffset = min(something,somethingElse);
|
// midpointXOffset = min(something,somethingElse);
|
||||||
// but it's a little difficult to work it out exactly
|
// but it's a little difficult to work it out exactly
|
||||||
// so here's a stupid search for the value for now:
|
// so here's a stupid search for the value for now:
|
||||||
|
|
||||||
int prevA = 999999;
|
int prevA = 999999;
|
||||||
int midpointXOffset = queued / 2;
|
int midpointXOffset = queued / 2;
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -494,9 +526,14 @@ namespace BizHawk.Emulation.Common
|
||||||
int dyMidLeft = (leftMidpointY < midpointY) ? 1 : -1;
|
int dyMidLeft = (leftMidpointY < midpointY) ? 1 : -1;
|
||||||
int dyMidRight = (rightMidpointY > midpointY) ? 1 : -1;
|
int dyMidRight = (rightMidpointY > midpointY) ? 1 : -1;
|
||||||
for (int x = leftMidpointX; x < midpointX; x++, y += dyMidLeft)
|
for (int x = leftMidpointX; x < midpointX; x++, y += dyMidLeft)
|
||||||
|
{
|
||||||
emit_sample(buf, ref bufcursor, sampleQueue[y]);
|
emit_sample(buf, ref bufcursor, sampleQueue[y]);
|
||||||
|
}
|
||||||
|
|
||||||
for (int x = midpointX; x < rightMidpointX; x++, y += dyMidRight)
|
for (int x = midpointX; x < rightMidpointX; x++, y += dyMidRight)
|
||||||
|
{
|
||||||
emit_sample(buf, ref bufcursor, sampleQueue[y]);
|
emit_sample(buf, ref bufcursor, sampleQueue[y]);
|
||||||
|
}
|
||||||
|
|
||||||
// output the end of the queued sound (section "C")
|
// output the end of the queued sound (section "C")
|
||||||
for (int x = rightMidpointX; x < audiosize; x++)
|
for (int x = rightMidpointX; x < audiosize; x++)
|
||||||
|
@ -510,12 +547,14 @@ namespace BizHawk.Emulation.Common
|
||||||
int i = queued + x;
|
int i = queued + x;
|
||||||
emit_sample(buf, ref bufcursor, sampleQueue[i]);
|
emit_sample(buf, ref bufcursor, sampleQueue[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
queued += extraAtEnd;
|
queued += extraAtEnd;
|
||||||
audiosize += beststart + extraAtEnd;
|
audiosize += beststart + extraAtEnd;
|
||||||
} // end else
|
} // end else
|
||||||
|
|
||||||
// sampleQueue.erase(sampleQueue.begin(), sampleQueue.begin() + queued);
|
// sampleQueue.erase(sampleQueue.begin(), sampleQueue.begin() + queued);
|
||||||
sampleQueue.RemoveRange(0, queued);
|
sampleQueue.RemoveRange(0, queued);
|
||||||
|
|
||||||
// zero 08-nov-2010: did i do this right?
|
// zero 08-nov-2010: did i do this right?
|
||||||
return audiosize;
|
return audiosize;
|
||||||
}
|
}
|
||||||
|
@ -529,20 +568,23 @@ namespace BizHawk.Emulation.Common
|
||||||
// and entering the "slow motion speed" branch above.
|
// and entering the "slow motion speed" branch above.
|
||||||
// but that's ok! because all of these branches sound similar enough that we can get away with it.
|
// but that's ok! because all of these branches sound similar enough that we can get away with it.
|
||||||
// so the two cases actually complement each other.
|
// so the two cases actually complement each other.
|
||||||
|
|
||||||
if (audiosize >= queued)
|
if (audiosize >= queued)
|
||||||
{
|
{
|
||||||
emit_samples(buf, ref bufcursor, sampleQueue.ToArray(), 0, queued);
|
emit_samples(buf, ref bufcursor, sampleQueue.ToArray(), 0, queued);
|
||||||
|
|
||||||
// sampleQueue.erase(sampleQueue.begin(), sampleQueue.begin() + queued);
|
// sampleQueue.erase(sampleQueue.begin(), sampleQueue.begin() + queued);
|
||||||
sampleQueue.RemoveRange(0, queued);
|
sampleQueue.RemoveRange(0, queued);
|
||||||
|
|
||||||
// zero 08-nov-2010: did i do this right?
|
// zero 08-nov-2010: did i do this right?
|
||||||
return queued;
|
return queued;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emit_samples(buf, ref bufcursor, sampleQueue.ToArray(), 0, audiosize);
|
emit_samples(buf, ref bufcursor, sampleQueue.ToArray(), 0, audiosize);
|
||||||
|
|
||||||
// sampleQueue.erase(sampleQueue.begin(), sampleQueue.begin()+audiosize);
|
// sampleQueue.erase(sampleQueue.begin(), sampleQueue.begin()+audiosize);
|
||||||
sampleQueue.RemoveRange(0, audiosize);
|
sampleQueue.RemoveRange(0, audiosize);
|
||||||
|
|
||||||
// zero 08-nov-2010: did i do this right?
|
// zero 08-nov-2010: did i do this right?
|
||||||
return audiosize;
|
return audiosize;
|
||||||
}
|
}
|
||||||
|
@ -554,13 +596,10 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // output_samples
|
} // output_samples
|
||||||
|
} // NitsujaSynchronizer
|
||||||
|
|
||||||
|
internal class VecnaSynchronizer : ISynchronizingAudioBuffer
|
||||||
}; //NitsujaSynchronizer
|
|
||||||
|
|
||||||
class VecnaSynchronizer : ISynchronizingAudioBuffer
|
|
||||||
{
|
{
|
||||||
// vecna's attempt at a fully synchronous sound provider.
|
// vecna's attempt at a fully synchronous sound provider.
|
||||||
// It's similar in philosophy to my "BufferedAsync" provider, but BufferedAsync is not
|
// It's similar in philosophy to my "BufferedAsync" provider, but BufferedAsync is not
|
||||||
|
@ -580,7 +619,7 @@ namespace BizHawk.Emulation.Common
|
||||||
// Since it has done this, it will go ahead and generate some excess silence in order
|
// Since it has done this, it will go ahead and generate some excess silence in order
|
||||||
// to restock its excess buffer.
|
// to restock its excess buffer.
|
||||||
|
|
||||||
struct Sample
|
private struct Sample
|
||||||
{
|
{
|
||||||
public short left, right;
|
public short left, right;
|
||||||
public Sample(short l, short r)
|
public Sample(short l, short r)
|
||||||
|
@ -590,11 +629,11 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Queue<Sample> buffer;
|
private Queue<Sample> buffer;
|
||||||
Sample[] resampleBuffer;
|
private Sample[] resampleBuffer;
|
||||||
|
|
||||||
const int SamplesInOneFrame = 735;
|
private const int SamplesInOneFrame = 735;
|
||||||
const int MaxExcessSamples = 2048;
|
private const int MaxExcessSamples = 2048;
|
||||||
|
|
||||||
public VecnaSynchronizer()
|
public VecnaSynchronizer()
|
||||||
{
|
{
|
||||||
|
@ -603,8 +642,10 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
// Give us a little buffer wiggle-room
|
// Give us a little buffer wiggle-room
|
||||||
for (int i = 0; i < 367; i++)
|
for (int i = 0; i < 367; i++)
|
||||||
|
{
|
||||||
buffer.Enqueue(new Sample(0, 0));
|
buffer.Enqueue(new Sample(0, 0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void enqueue_samples(short[] buf, int samples_provided)
|
public void enqueue_samples(short[] buf, int samples_provided)
|
||||||
{
|
{
|
||||||
|
@ -624,6 +665,7 @@ namespace BizHawk.Emulation.Common
|
||||||
// if buffer is overfull, dequeue old samples to make room for new samples.
|
// if buffer is overfull, dequeue old samples to make room for new samples.
|
||||||
buffer.Dequeue();
|
buffer.Dequeue();
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.Enqueue(new Sample(left, right));
|
buffer.Enqueue(new Sample(left, right));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +683,6 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
// if we're within 75% of target, then I guess we suck it up and resample.
|
// if we're within 75% of target, then I guess we suck it up and resample.
|
||||||
// we sample in a goofy way, we could probably do it a bit smarter, if we cared more.
|
// we sample in a goofy way, we could probably do it a bit smarter, if we cared more.
|
||||||
|
|
||||||
int samples_available = buffer.Count;
|
int samples_available = buffer.Count;
|
||||||
for (int i = 0; buffer.Count > 0; i++)
|
for (int i = 0; buffer.Count > 0; i++)
|
||||||
resampleBuffer[i] = buffer.Dequeue();
|
resampleBuffer[i] = buffer.Dequeue();
|
||||||
|
@ -672,6 +713,7 @@ namespace BizHawk.Emulation.Common
|
||||||
buf[index++] += sample.right;
|
buf[index++] += sample.right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return samples_requested;
|
return samples_requested;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Common
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SpeexResampler : IDisposable, ISoundProvider
|
public class SpeexResampler : IDisposable, ISoundProvider
|
||||||
{
|
{
|
||||||
static class LibSpeexDSP
|
private static class LibSpeexDSP
|
||||||
{
|
{
|
||||||
public const int QUALITY_MAX = 10;
|
public const int QUALITY_MAX = 10;
|
||||||
public const int QUALITY_MIN = 0;
|
public const int QUALITY_MIN = 0;
|
||||||
|
@ -24,7 +24,7 @@ namespace BizHawk.Emulation.Common
|
||||||
INVALID_ARG = 3,
|
INVALID_ARG = 3,
|
||||||
PTR_OVERLAP = 4,
|
PTR_OVERLAP = 4,
|
||||||
MAX_ERROR
|
MAX_ERROR
|
||||||
};
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new resampler with integer input and output rates.
|
/// Create a new resampler with integer input and output rates.
|
||||||
|
@ -281,7 +281,7 @@ namespace BizHawk.Emulation.Common
|
||||||
/// throw an exception based on error state
|
/// throw an exception based on error state
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
static void CheckError(LibSpeexDSP.RESAMPLER_ERR e)
|
private static void CheckError(LibSpeexDSP.RESAMPLER_ERR e)
|
||||||
{
|
{
|
||||||
switch (e)
|
switch (e)
|
||||||
{
|
{
|
||||||
|
@ -299,7 +299,6 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="quality">0 to 10</param>
|
/// <param name="quality">0 to 10</param>
|
||||||
/// <param name="rationum">numerator of srate change ratio (inrate / outrate)</param>
|
/// <param name="rationum">numerator of srate change ratio (inrate / outrate)</param>
|
||||||
|
@ -311,13 +310,17 @@ namespace BizHawk.Emulation.Common
|
||||||
public SpeexResampler(int quality, uint rationum, uint ratioden, uint sratein, uint srateout, Action<short[], int> drainer = null, ISoundProvider input = null)
|
public SpeexResampler(int quality, uint rationum, uint ratioden, uint sratein, uint srateout, Action<short[], int> drainer = null, ISoundProvider input = null)
|
||||||
{
|
{
|
||||||
if (drainer != null && input != null)
|
if (drainer != null && input != null)
|
||||||
|
{
|
||||||
throw new ArgumentException("Can't autofetch without being an ISyncSoundProvider?");
|
throw new ArgumentException("Can't autofetch without being an ISyncSoundProvider?");
|
||||||
|
}
|
||||||
|
|
||||||
LibSpeexDSP.RESAMPLER_ERR err = LibSpeexDSP.RESAMPLER_ERR.SUCCESS;
|
LibSpeexDSP.RESAMPLER_ERR err = LibSpeexDSP.RESAMPLER_ERR.SUCCESS;
|
||||||
st = LibSpeexDSP.speex_resampler_init_frac(2, rationum, ratioden, sratein, srateout, quality, ref err);
|
st = LibSpeexDSP.speex_resampler_init_frac(2, rationum, ratioden, sratein, srateout, quality, ref err);
|
||||||
|
|
||||||
if (st == IntPtr.Zero)
|
if (st == IntPtr.Zero)
|
||||||
|
{
|
||||||
throw new Exception("LibSpeexDSP returned null!");
|
throw new Exception("LibSpeexDSP returned null!");
|
||||||
|
}
|
||||||
|
|
||||||
CheckError(err);
|
CheckError(err);
|
||||||
|
|
||||||
|
@ -349,8 +352,10 @@ namespace BizHawk.Emulation.Common
|
||||||
inbuf[inbufpos++] = right;
|
inbuf[inbufpos++] = right;
|
||||||
|
|
||||||
if (inbufpos == inbuf.Length)
|
if (inbufpos == inbuf.Length)
|
||||||
|
{
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// add multiple samples to the queue
|
/// add multiple samples to the queue
|
||||||
|
@ -369,9 +374,11 @@ namespace BizHawk.Emulation.Common
|
||||||
numused += shortstocopy / 2;
|
numused += shortstocopy / 2;
|
||||||
|
|
||||||
if (inbufpos == inbuf.Length)
|
if (inbufpos == inbuf.Length)
|
||||||
|
{
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -386,9 +393,11 @@ namespace BizHawk.Emulation.Common
|
||||||
LibSpeexDSP.speex_resampler_process_interleaved_int(st, inbuf, ref inal, outbuf, ref outal);
|
LibSpeexDSP.speex_resampler_process_interleaved_int(st, inbuf, ref inal, outbuf, ref outal);
|
||||||
|
|
||||||
// reset inbuf
|
// reset inbuf
|
||||||
|
|
||||||
if (inal != inbufpos / 2)
|
if (inal != inbufpos / 2)
|
||||||
|
{
|
||||||
throw new Exception("Speexresampler didn't eat the whole array?");
|
throw new Exception("Speexresampler didn't eat the whole array?");
|
||||||
|
}
|
||||||
|
|
||||||
inbufpos = 0;
|
inbufpos = 0;
|
||||||
|
|
||||||
//Buffer.BlockCopy(inbuf, (int)inal * 2 * sizeof(short), inbuf, 0, inbufpos - (int)inal * 2);
|
//Buffer.BlockCopy(inbuf, (int)inal * 2 * sizeof(short), inbuf, 0, inbufpos - (int)inal * 2);
|
||||||
|
@ -413,7 +422,7 @@ namespace BizHawk.Emulation.Common
|
||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InternalDrain(short[] buf, int nsamp)
|
private void InternalDrain(short[] buf, int nsamp)
|
||||||
{
|
{
|
||||||
if (outbuf2pos + nsamp * 2 > outbuf2.Length)
|
if (outbuf2pos + nsamp * 2 > outbuf2.Length)
|
||||||
{
|
{
|
||||||
|
@ -421,6 +430,7 @@ namespace BizHawk.Emulation.Common
|
||||||
Buffer.BlockCopy(outbuf2, 0, newbuf, 0, outbuf2pos * sizeof(short));
|
Buffer.BlockCopy(outbuf2, 0, newbuf, 0, outbuf2pos * sizeof(short));
|
||||||
outbuf2 = newbuf;
|
outbuf2 = newbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer.BlockCopy(buf, 0, outbuf2, outbuf2pos * sizeof(short), nsamp * 2 * sizeof(short));
|
Buffer.BlockCopy(buf, 0, outbuf2, outbuf2pos * sizeof(short), nsamp * 2 * sizeof(short));
|
||||||
outbuf2pos += nsamp * 2;
|
outbuf2pos += nsamp * 2;
|
||||||
}
|
}
|
||||||
|
@ -434,6 +444,7 @@ namespace BizHawk.Emulation.Common
|
||||||
input.GetSamplesSync(out sampin, out nsampin);
|
input.GetSamplesSync(out sampin, out nsampin);
|
||||||
EnqueueSamples(sampin, nsampin);
|
EnqueueSamples(sampin, nsampin);
|
||||||
}
|
}
|
||||||
|
|
||||||
Flush();
|
Flush();
|
||||||
nsamp = outbuf2pos / 2;
|
nsamp = outbuf2pos / 2;
|
||||||
samples = outbuf2;
|
samples = outbuf2;
|
||||||
|
@ -445,15 +456,9 @@ namespace BizHawk.Emulation.Common
|
||||||
outbuf2pos = 0;
|
outbuf2pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanProvideAsync
|
public bool CanProvideAsync => false;
|
||||||
{
|
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public SyncSoundMode SyncMode
|
public SyncSoundMode SyncMode => SyncSoundMode.Sync;
|
||||||
{
|
|
||||||
get { return SyncSoundMode.Sync; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GetSamplesAsync(short[] samples)
|
public void GetSamplesAsync(short[] samples)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,8 +29,10 @@
|
||||||
{
|
{
|
||||||
int r = rnd.Next();
|
int r = rnd.Next();
|
||||||
if ((r & 1) > 0)
|
if ((r & 1) > 0)
|
||||||
|
{
|
||||||
NoiseWave[i] = short.MaxValue;
|
NoiseWave[i] = short.MaxValue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*TriangleWave = new short[512];
|
/*TriangleWave = new short[512];
|
||||||
for (int i = 0; i < 256; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
|
|
|
@ -18,8 +18,8 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
public class Node
|
public class Node
|
||||||
{
|
{
|
||||||
public Dictionary<string, byte[]> Data = new Dictionary<string, byte[]>();
|
public readonly Dictionary<string, byte[]> Data = new Dictionary<string, byte[]>();
|
||||||
public Dictionary<string, Node> Objects = new Dictionary<string, Node>();
|
public readonly Dictionary<string, Node> Objects = new Dictionary<string, Node>();
|
||||||
|
|
||||||
// methods named "ShouldSerialize*" are detected and dynamically invoked by JSON.NET
|
// methods named "ShouldSerialize*" are detected and dynamically invoked by JSON.NET
|
||||||
// if they return false during serialization, the field/prop is omitted from the created json
|
// if they return false during serialization, the field/prop is omitted from the created json
|
||||||
|
@ -34,13 +34,13 @@ namespace BizHawk.Emulation.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node Root = new Node();
|
public readonly Node Root = new Node();
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
Stack<Node> Nodes;
|
Stack<Node> Nodes;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
Node Current { get { return Nodes.Peek(); } }
|
private Node Current => Nodes.Peek();
|
||||||
|
|
||||||
public void Prepare()
|
public void Prepare()
|
||||||
{
|
{
|
||||||
|
@ -59,7 +59,10 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
byte[] d = Current.Data[name];
|
byte[] d = Current.Data[name];
|
||||||
if (length != d.Length)
|
if (length != d.Length)
|
||||||
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
Marshal.Copy(d, 0, data, length);
|
Marshal.Copy(d, 0, data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +90,7 @@ namespace BizHawk.Emulation.Common
|
||||||
next = new Node();
|
next = new Node();
|
||||||
Current.Objects.Add(name, next);
|
Current.Objects.Add(name, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
Nodes.Push(next);
|
Nodes.Push(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +98,10 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
Node last = Nodes.Pop();
|
Node last = Nodes.Pop();
|
||||||
if (Current.Objects[name] != last)
|
if (Current.Objects[name] != last)
|
||||||
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// other data besides the core
|
// other data besides the core
|
||||||
public T ExtraData;
|
public T ExtraData;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantCaseLabel/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1101/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1101/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1108/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1108/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1126/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1126/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
static class VersionInfo
|
static class VersionInfo
|
||||||
|
|
Loading…
Reference in New Issue