misc code cleanups in BizHawk.Emulation.Common

This commit is contained in:
adelikat 2017-04-14 12:28:23 -05:00
parent 8eda3dfe16
commit 7ab8455e84
28 changed files with 543 additions and 517 deletions

View File

@ -22,9 +22,7 @@ namespace BizHawk.Emulation.Common
// this removes the possibility of automagically picking up a service in a nested class, (find the type, then // this removes the possibility of automagically picking up a service in a nested class, (find the type, then
// find the field), but we're going to keep such logic out of the basic provider. anything the passed // find the field), but we're going to keep such logic out of the basic provider. anything the passed
// core doesn't implement directly needs to be added with Register() // core doesn't implement directly needs to be added with Register()
// this also fully allows services that are not IEmulatorService // this also fully allows services that are not IEmulatorService
Type coreType = core.GetType(); Type coreType = core.GetType();
var services = coreType.GetInterfaces() var services = coreType.GetInterfaces()

View File

@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Common
/// <seealso cref="ITraceable"/> /// <seealso cref="ITraceable"/>
/// <seealso cref="IDebuggable"/> /// <seealso cref="IDebuggable"/>
/// <seealso cref="IMemoryDomains"/> /// <seealso cref="IMemoryDomains"/>
/// /// <seealso cref="IDisassemblable"/> /// <seealso cref="IDisassemblable"/>
public abstract class CallbackBasedTraceBuffer : ITraceable public abstract class CallbackBasedTraceBuffer : ITraceable
{ {
public CallbackBasedTraceBuffer(IDebuggable debuggableCore, IMemoryDomains memoryDomains, IDisassemblable disassembler) public CallbackBasedTraceBuffer(IDebuggable debuggableCore, IMemoryDomains memoryDomains, IDisassemblable disassembler)
@ -50,10 +50,7 @@ namespace BizHawk.Emulation.Common
private ITraceSink _sink; private ITraceSink _sink;
public bool Enabled public bool Enabled => Sink != null;
{
get { return Sink != null; }
}
public void Put(TraceInfo info) public void Put(TraceInfo info)
{ {
@ -87,27 +84,15 @@ namespace BizHawk.Emulation.Common
Callback = callback; Callback = callback;
} }
public MemoryCallbackType Type public MemoryCallbackType Type => MemoryCallbackType.Execute;
{
get { return MemoryCallbackType.Execute; }
}
public string Name public string Name => "Trace Logging";
{
get { return "Trace Logging"; }
}
public Action Callback { get; private set; } public Action Callback { get; }
public uint? Address public uint? Address => null;
{
get { return null; }
}
public uint? AddressMask public uint? AddressMask => null;
{
get { return null; }
}
} }
} }
} }

View File

@ -65,12 +65,18 @@ namespace BizHawk.Emulation.Common
public void ApplyAxisConstraints(string constraintClass, IDictionary<string, float> floatButtons) public void ApplyAxisConstraints(string constraintClass, IDictionary<string, float> floatButtons)
{ {
if (AxisConstraints == null) return; if (AxisConstraints == null)
{
return;
}
foreach (var constraint in AxisConstraints) foreach (var constraint in AxisConstraints)
{ {
if (constraint.Class != constraintClass) if (constraint.Class != constraintClass)
{
continue; continue;
}
switch (constraint.Type) switch (constraint.Type)
{ {
case AxisConstraintType.Circular: case AxisConstraintType.Circular:

View File

@ -62,10 +62,7 @@ namespace BizHawk.Emulation.Common
{ {
if ((hadAny && !hasAny) || (!hadAny && hasAny)) if ((hadAny && !hasAny) || (!hadAny && hasAny))
{ {
if (ActiveChanged != null) ActiveChanged?.Invoke();
{
ActiveChanged();
}
} }
} }
} }

View File

@ -66,9 +66,11 @@ namespace BizHawk.Emulation.Common
for (int i = 0; i < cbs.Count; i++) for (int i = 0; i < cbs.Count; i++)
{ {
if (!cbs[i].Address.HasValue || cbs[i].Address == (addr & cbs[i].AddressMask)) if (!cbs[i].Address.HasValue || cbs[i].Address == (addr & cbs[i].AddressMask))
{
cbs[i].Callback(); cbs[i].Callback();
} }
} }
}
public void CallReads(uint addr) public void CallReads(uint addr)
{ {
@ -94,20 +96,11 @@ namespace BizHawk.Emulation.Common
} }
} }
public bool HasReads public bool HasReads => _hasReads;
{
get { return _hasReads; }
}
public bool HasWrites public bool HasWrites => _hasWrites;
{
get { return _hasWrites; }
}
public bool HasExecutes public bool HasExecutes => _hasExecutes;
{
get { return _hasExecutes; }
}
private void UpdateHasVariables() private void UpdateHasVariables()
{ {
@ -123,13 +116,19 @@ namespace BizHawk.Emulation.Common
var execsToRemove = Execs.Where(imc => imc.Callback == action).ToList(); var execsToRemove = Execs.Where(imc => imc.Callback == action).ToList();
foreach (var read in readsToRemove) foreach (var read in readsToRemove)
{
Reads.Remove(read); Reads.Remove(read);
}
foreach (var write in writesToRemove) foreach (var write in writesToRemove)
{
Writes.Remove(write); Writes.Remove(write);
}
foreach (var exec in execsToRemove) foreach (var exec in execsToRemove)
{
Execs.Remove(exec); Execs.Remove(exec);
}
UpdateHasVariables(); UpdateHasVariables();
@ -142,7 +141,10 @@ namespace BizHawk.Emulation.Common
{ {
bool newEmpty = !HasReads && !HasWrites && !HasExecutes; bool newEmpty = !HasReads && !HasWrites && !HasExecutes;
if (newEmpty != _empty) if (newEmpty != _empty)
{
Changes(); Changes();
}
_empty = newEmpty; _empty = newEmpty;
} }
} }
@ -154,11 +156,15 @@ namespace BizHawk.Emulation.Common
{ {
changed |= RemoveInternal(action) > 0; changed |= RemoveInternal(action) > 0;
} }
if (changed) if (changed)
{ {
bool newEmpty = !HasReads && !HasWrites && !HasExecutes; bool newEmpty = !HasReads && !HasWrites && !HasExecutes;
if (newEmpty != _empty) if (newEmpty != _empty)
{
Changes(); Changes();
}
_empty = newEmpty; _empty = newEmpty;
} }
@ -168,17 +174,26 @@ namespace BizHawk.Emulation.Common
public void Clear() public void Clear()
{ {
// Remove one-by-one to avoid NotifyCollectionChangedAction.Reset events. // Remove one-by-one to avoid NotifyCollectionChangedAction.Reset events.
for(int i = (Reads.Count - 1); i >= 0; i--) for (int i = Reads.Count - 1; i >= 0; i--)
{
Reads.RemoveAt(i); Reads.RemoveAt(i);
}
for(int i = (Reads.Count - 1); i >= 0; i--) for (int i = Reads.Count - 1; i >= 0; i--)
{
Writes.RemoveAt(i); Writes.RemoveAt(i);
}
for(int i = (Reads.Count - 1); i >= 0; i--) for (int i = Reads.Count - 1; i >= 0; i--)
{
Execs.RemoveAt(i); Execs.RemoveAt(i);
}
if (!_empty) if (!_empty)
{
Changes(); Changes();
}
_empty = true; _empty = true;
UpdateHasVariables(); UpdateHasVariables();
@ -195,10 +210,7 @@ namespace BizHawk.Emulation.Common
private void Changes() private void Changes()
{ {
if (ActiveChanged != null) ActiveChanged?.Invoke();
{
ActiveChanged();
}
} }
public void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) public void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
@ -208,19 +220,13 @@ namespace BizHawk.Emulation.Common
case NotifyCollectionChangedAction.Add: case NotifyCollectionChangedAction.Add:
foreach(IMemoryCallback callback in args.NewItems) foreach(IMemoryCallback callback in args.NewItems)
{ {
if(CallbackAdded != null) CallbackAdded?.Invoke(callback);
{
CallbackAdded(callback);
}
} }
break; break;
case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Remove:
foreach(IMemoryCallback callback in args.OldItems) foreach(IMemoryCallback callback in args.OldItems)
{ {
if(CallbackRemoved != null) CallbackRemoved?.Invoke(callback);
{
CallbackRemoved(callback);
}
} }
break; break;
} }
@ -276,13 +282,13 @@ namespace BizHawk.Emulation.Common
Name = name; Name = name;
Callback = callback; Callback = callback;
Address = address; Address = address;
AddressMask = (mask.HasValue ? mask : 0xFFFFFFFF); AddressMask = mask ?? 0xFFFFFFFF;
} }
public MemoryCallbackType Type { get; private set; } public MemoryCallbackType Type { get; }
public string Name { get; private set; } public string Name { get; }
public Action Callback { get; private set; } public Action Callback { get; }
public uint? Address { get; private set; } public uint? Address { get; }
public uint? AddressMask { get; private set; } public uint? AddressMask { get; }
} }
} }

View File

@ -7,8 +7,24 @@ namespace BizHawk.Emulation.Common
private Func<long, byte> _peek; private Func<long, byte> _peek;
private Action<long, byte> _poke; private Action<long, byte> _poke;
public Func<long, byte> Peek { get { return _peek; } set { _peek = value; } } public Func<long, byte> Peek
public Action<long, byte> Poke { get { return _poke; } set { _poke = value; Writable = value != null; } } {
get { return _peek; } set { _peek = value; }
}
public Action<long, byte> Poke
{
get
{
return _poke;
}
set
{
_poke = value;
Writable = value != null;
}
}
public override byte PeekByte(long addr) public override byte PeekByte(long addr)
{ {
@ -17,8 +33,7 @@ namespace BizHawk.Emulation.Common
public override void PokeByte(long addr, byte val) public override void PokeByte(long addr, byte val)
{ {
if (_poke != null) _poke?.Invoke(addr, val);
_poke(addr, val);
} }
public MemoryDomainDelegate(string name, long size, Endian endian, Func<long, byte> peek, Action<long, byte> poke, int wordSize) public MemoryDomainDelegate(string name, long size, Endian endian, Func<long, byte> peek, Action<long, byte> poke, int wordSize)
@ -37,7 +52,19 @@ namespace BizHawk.Emulation.Common
{ {
private byte[] _data; private byte[] _data;
public byte[] Data { get { return _data; } set { _data = value; Size = _data.LongLength; } } public byte[] Data
{
get
{
return _data;
}
set
{
_data = value;
Size = _data.LongLength;
}
}
public override byte PeekByte(long addr) public override byte PeekByte(long addr)
{ {
@ -47,8 +74,10 @@ namespace BizHawk.Emulation.Common
public override void PokeByte(long addr, byte val) public override void PokeByte(long addr, byte val)
{ {
if (Writable) if (Writable)
{
Data[addr] = val; Data[addr] = val;
} }
}
public MemoryDomainByteArray(string name, Endian endian, byte[] data, bool writable, int wordSize) public MemoryDomainByteArray(string name, Endian endian, byte[] data, bool writable, int wordSize)
{ {
@ -67,8 +96,10 @@ namespace BizHawk.Emulation.Common
public override byte PeekByte(long addr) public override byte PeekByte(long addr)
{ {
if ((ulong)addr < (ulong)Size) if ((ulong)addr < (ulong)Size)
{
return ((byte*)Data)[addr]; return ((byte*)Data)[addr];
else }
throw new ArgumentOutOfRangeException(nameof(addr)); throw new ArgumentOutOfRangeException(nameof(addr));
} }
@ -77,11 +108,15 @@ namespace BizHawk.Emulation.Common
if (Writable) if (Writable)
{ {
if ((ulong)addr < (ulong)Size) if ((ulong)addr < (ulong)Size)
{
((byte*)Data)[addr] = val; ((byte*)Data)[addr] = val;
}
else else
{
throw new ArgumentOutOfRangeException(nameof(addr)); throw new ArgumentOutOfRangeException(nameof(addr));
} }
} }
}
public void SetSize(long size) public void SetSize(long size)
{ {
@ -106,8 +141,10 @@ namespace BizHawk.Emulation.Common
public override byte PeekByte(long addr) public override byte PeekByte(long addr)
{ {
if ((ulong)addr < (ulong)Size) if ((ulong)addr < (ulong)Size)
{
return ((byte*)Data)[addr ^ 1]; return ((byte*)Data)[addr ^ 1];
else }
throw new ArgumentOutOfRangeException(nameof(addr)); throw new ArgumentOutOfRangeException(nameof(addr));
} }
@ -116,11 +153,15 @@ namespace BizHawk.Emulation.Common
if (Writable) if (Writable)
{ {
if ((ulong)addr < (ulong)Size) if ((ulong)addr < (ulong)Size)
{
((byte*)Data)[addr ^ 1] = val; ((byte*)Data)[addr ^ 1] = val;
}
else else
{
throw new ArgumentOutOfRangeException(nameof(addr)); throw new ArgumentOutOfRangeException(nameof(addr));
} }
} }
}
public MemoryDomainIntPtrSwap16(string name, Endian endian, IntPtr data, long size, bool writable) public MemoryDomainIntPtrSwap16(string name, Endian endian, IntPtr data, long size, bool writable)
{ {

View File

@ -116,7 +116,9 @@ namespace BizHawk.Emulation.Common
var d1 = dest as T; var d1 = dest as T;
var s1 = src as T; var s1 = src as T;
if (d1 != null && s1 != null) if (d1 != null && s1 != null)
{
func(d1, s1); func(d1, s1);
} }
} }
} }
}

View File

@ -29,21 +29,26 @@ namespace BizHawk.Emulation.Common
#region IEmulator #region IEmulator
public IEmulatorServiceProvider ServiceProvider { get; private set; } public IEmulatorServiceProvider ServiceProvider { get; }
public ControllerDefinition ControllerDefinition public ControllerDefinition ControllerDefinition => NullController.Instance.Definition;
{
get { return NullController.Instance.Definition; }
}
public IController Controller { get; set; } public IController Controller { get; set; }
public void FrameAdvance(bool render, bool rendersound) public void FrameAdvance(bool render, bool rendersound)
{ {
if (render == false) return; if (render == false)
{
return;
}
if (!_settings.SnowyDisplay) if (!_settings.SnowyDisplay)
{ {
if (_frameBufferClear) return; if (_frameBufferClear)
{
return;
}
_frameBufferClear = true; _frameBufferClear = true;
Array.Clear(FrameBuffer, 0, 256 * 192); Array.Clear(FrameBuffer, 0, 256 * 192);
return; return;
@ -69,22 +74,24 @@ namespace BizHawk.Emulation.Common
Frame++; Frame++;
} }
public int Frame { get; set; } public int Frame { get; private set; }
public string SystemId { get { return "NULL"; } } public string SystemId => "NULL";
public bool DeterministicEmulation { get { return true; } } public bool DeterministicEmulation => true;
public void ResetCounters() public void ResetCounters()
{ {
Frame = 0; Frame = 0;
} }
public string BoardName { get { return null; } } public string BoardName => null;
public CoreComm CoreComm { get; private set; } public CoreComm CoreComm { get; }
public void Dispose() { } public void Dispose()
{
}
#endregion #endregion
@ -95,30 +102,15 @@ namespace BizHawk.Emulation.Common
return FrameBuffer; return FrameBuffer;
} }
public int VirtualWidth public int VirtualWidth => 256;
{
get { return 256; }
}
public int VirtualHeight public int VirtualHeight => 192;
{
get { return 192; }
}
public int BufferWidth public int BufferWidth => 256;
{
get { return 256; }
}
public int BufferHeight public int BufferHeight => 192;
{
get { return 192; }
}
public int BackgroundColor public int BackgroundColor => 0;
{
get { return 0; }
}
#endregion #endregion
@ -166,10 +158,7 @@ namespace BizHawk.Emulation.Common
} }
} }
public bool CanProvideAsync public bool CanProvideAsync => true;
{
get { return true; }
}
public SyncSoundMode SyncMode { get; private set; } public SyncSoundMode SyncMode { get; private set; }

View File

@ -22,7 +22,6 @@ namespace BizHawk.Emulation.Common
/// <summary> /// <summary>
/// create a NullSound that provides an exact number of audio samples per call when in sync mode /// create a NullSound that provides an exact number of audio samples per call when in sync mode
/// </summary> /// </summary>
/// <param name="spf"></param>
public NullSound(int spf) public NullSound(int spf)
: this() : this()
{ {
@ -33,41 +32,38 @@ namespace BizHawk.Emulation.Common
/// <summary> /// <summary>
/// create a NullSound that exactly matches a given framerate when in sync mode /// create a NullSound that exactly matches a given framerate when in sync mode
/// </summary> /// </summary>
/// <param name="fpsNum"></param>
/// <param name="fpsDen"></param>
public NullSound(long fpsNum, long fpsDen) public NullSound(long fpsNum, long fpsDen)
{ {
_spfNumerator = fpsDen * 44100; _spfNumerator = fpsDen * 44100;
_spfDenominator = fpsNum; _spfDenominator = fpsNum;
} }
public bool CanProvideAsync public bool CanProvideAsync => true;
{
get { return true; }
}
public SyncSoundMode SyncMode public SyncSoundMode SyncMode { get; private set; }
{
get;
private set;
}
public void GetSamplesSync(out short[] samples, out int nsamp) public void GetSamplesSync(out short[] samples, out int nsamp)
{ {
if (SyncMode != SyncSoundMode.Sync) if (SyncMode != SyncSoundMode.Sync)
{
throw new InvalidOperationException("Wrong sound mode"); throw new InvalidOperationException("Wrong sound mode");
}
int s = (int)((_spfNumerator + _remainder) / _spfDenominator); int s = (int)((_spfNumerator + _remainder) / _spfDenominator);
_remainder = (_spfNumerator + _remainder) % _spfDenominator; _remainder = (_spfNumerator + _remainder) % _spfDenominator;
if (_buff.Length < s * 2) if (_buff.Length < s * 2)
{
_buff = new short[s * 2]; _buff = new short[s * 2];
}
samples = _buff; samples = _buff;
nsamp = s; nsamp = s;
} }
public void DiscardSamples() { } public void DiscardSamples()
{
}
public void SetSyncMode(SyncSoundMode mode) public void SetSyncMode(SyncSoundMode mode)
{ {
@ -77,7 +73,10 @@ namespace BizHawk.Emulation.Common
public void GetSamplesAsync(short[] samples) public void GetSamplesAsync(short[] samples)
{ {
if (SyncMode != SyncSoundMode.Async) if (SyncMode != SyncSoundMode.Async)
{
throw new InvalidOperationException("Wrong sound mode"); throw new InvalidOperationException("Wrong sound mode");
}
Array.Clear(samples, 0, samples.Length); Array.Clear(samples, 0, samples.Length);
} }
} }

View File

@ -1,7 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Common.Base_Implementations namespace BizHawk.Emulation.Common.Base_Implementations
{ {
@ -13,22 +10,18 @@ namespace BizHawk.Emulation.Common.Base_Implementations
private short[] _buffer = new short[0]; private short[] _buffer = new short[0];
private int _nsamp = 0; private int _nsamp = 0;
public bool CanProvideAsync public bool CanProvideAsync => false;
{
get { return false; }
}
public void SetSyncMode(SyncSoundMode mode) public void SetSyncMode(SyncSoundMode mode)
{ {
if (mode != SyncSoundMode.Sync) if (mode != SyncSoundMode.Sync)
{
throw new ArgumentException("Only supports Sync mode"); throw new ArgumentException("Only supports Sync mode");
} }
public SyncSoundMode SyncMode
{
get { return SyncSoundMode.Sync; }
} }
public SyncSoundMode SyncMode => SyncSoundMode.Sync;
/// <summary> /// <summary>
/// Add samples to be output. no queueing; must be drained every frame /// Add samples to be output. no queueing; must be drained every frame
/// </summary> /// </summary>
@ -37,10 +30,15 @@ namespace BizHawk.Emulation.Common.Base_Implementations
public void PutSamples(short[] samples, int nsamp) public void PutSamples(short[] samples, int nsamp)
{ {
if (_nsamp != 0) if (_nsamp != 0)
{
Console.WriteLine("Warning: Samples disappeared from SimpleSyncSoundProvider"); Console.WriteLine("Warning: Samples disappeared from SimpleSyncSoundProvider");
}
if (_buffer.Length < nsamp * 2) if (_buffer.Length < nsamp * 2)
{
_buffer = new short[nsamp * 2]; _buffer = new short[nsamp * 2];
}
Array.Copy(samples, _buffer, nsamp * 2); Array.Copy(samples, _buffer, nsamp * 2);
_nsamp = nsamp; _nsamp = nsamp;
} }

View File

@ -1,16 +1,15 @@
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Linq.Expressions;
using System.IO;
using BizHawk.Common;
using BizHawk.Common.ReflectionExtensions;
using System.Collections.Concurrent;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using BizHawk.Common;
namespace BizHawk.Emulation.Common namespace BizHawk.Emulation.Common
{ {
public class BinaryQuickSerializer public class BinaryQuickSerializer

View File

@ -1,10 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Reflection; using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.Common.BizInvoke namespace BizHawk.Emulation.Common.BizInvoke
@ -24,9 +24,11 @@ namespace BizHawk.Emulation.Common.BizInvoke
{ {
var ret = Activator.CreateInstance(ImplType); var ret = Activator.CreateInstance(ImplType);
foreach (var f in Hooks) foreach (var f in Hooks)
{
f(ret, dll); f(ret, dll);
if (ConnectMonitor != null) }
ConnectMonitor(ret, monitor);
ConnectMonitor?.Invoke(ret, monitor);
return ret; return ret;
} }
} }
@ -40,6 +42,7 @@ namespace BizHawk.Emulation.Common.BizInvoke
/// the assembly that all proxies are placed in /// the assembly that all proxies are placed in
/// </summary> /// </summary>
private static readonly AssemblyBuilder ImplAssemblyBuilder; private static readonly AssemblyBuilder ImplAssemblyBuilder;
/// <summary> /// <summary>
/// the module that all proxies are placed in /// the module that all proxies are placed in
/// </summary> /// </summary>
@ -68,8 +71,12 @@ namespace BizHawk.Emulation.Common.BizInvoke
Impls.Add(baseType, impl); Impls.Add(baseType, impl);
} }
} }
if (impl.ConnectMonitor != null) if (impl.ConnectMonitor != null)
{
throw new InvalidOperationException("Class was previously proxied with a monitor!"); throw new InvalidOperationException("Class was previously proxied with a monitor!");
}
return (T)impl.Create(dll, null); return (T)impl.Create(dll, null);
} }
@ -86,22 +93,33 @@ namespace BizHawk.Emulation.Common.BizInvoke
Impls.Add(baseType, impl); Impls.Add(baseType, impl);
} }
} }
if (impl.ConnectMonitor == null) if (impl.ConnectMonitor == null)
{
throw new InvalidOperationException("Class was previously proxied without a monitor!"); throw new InvalidOperationException("Class was previously proxied without a monitor!");
}
return (T)impl.Create(dll, monitor); return (T)impl.Create(dll, monitor);
} }
private static InvokerImpl CreateProxy(Type baseType, bool monitor) private static InvokerImpl CreateProxy(Type baseType, bool monitor)
{ {
if (baseType.IsSealed) if (baseType.IsSealed)
{
throw new InvalidOperationException("Can't proxy a sealed type"); throw new InvalidOperationException("Can't proxy a sealed type");
}
if (!baseType.IsPublic) if (!baseType.IsPublic)
{
// the proxy type will be in a new assembly, so public is required here // the proxy type will be in a new assembly, so public is required here
throw new InvalidOperationException("Type must be public"); throw new InvalidOperationException("Type must be public");
}
var baseConstructor = baseType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null); var baseConstructor = baseType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
if (baseConstructor == null) if (baseConstructor == null)
{
throw new InvalidOperationException("Base type must have a zero arg constructor"); throw new InvalidOperationException("Base type must have a zero arg constructor");
}
var baseMethods = baseType.GetMethods(BindingFlags.Instance | BindingFlags.Public) var baseMethods = baseType.GetMethods(BindingFlags.Instance | BindingFlags.Public)
.Select(m => new .Select(m => new
@ -113,7 +131,9 @@ namespace BizHawk.Emulation.Common.BizInvoke
.ToList(); .ToList();
if (baseMethods.Count == 0) if (baseMethods.Count == 0)
{
throw new InvalidOperationException("Couldn't find any [BizImport] methods to proxy"); throw new InvalidOperationException("Couldn't find any [BizImport] methods to proxy");
}
{ {
var uo = baseMethods.FirstOrDefault(a => !a.Info.IsVirtual || a.Info.IsFinal); var uo = baseMethods.FirstOrDefault(a => !a.Info.IsVirtual || a.Info.IsFinal);
@ -288,6 +308,7 @@ namespace BizHawk.Emulation.Common.BizInvoke
// arg 0 is this, so + 1 // arg 0 is this, so + 1
nativeParamTypes.Add(EmitParamterLoad(il, i + 1, paramTypes[i])); nativeParamTypes.Add(EmitParamterLoad(il, i + 1, paramTypes[i]));
} }
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, field); il.Emit(OpCodes.Ldfld, field);
il.EmitCalli(OpCodes.Calli, nativeCall, returnType, nativeParamTypes.ToArray()); il.EmitCalli(OpCodes.Calli, nativeCall, returnType, nativeParamTypes.ToArray());
@ -452,11 +473,7 @@ namespace BizHawk.Emulation.Common.BizInvoke
[AttributeUsage(AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Method)]
public class BizImportAttribute : Attribute public class BizImportAttribute : Attribute
{ {
public CallingConvention CallingConvention public CallingConvention CallingConvention { get; }
{
get { return _callingConvention; }
}
private readonly CallingConvention _callingConvention;
/// <summary> /// <summary>
/// name of entry point; if not given, the method's name is used /// name of entry point; if not given, the method's name is used
@ -469,12 +486,11 @@ namespace BizHawk.Emulation.Common.BizInvoke
public bool Compatibility { get; set; } public bool Compatibility { get; set; }
/// <summary> /// <summary>
///
/// </summary> /// </summary>
/// <param name="c">unmanaged calling convention</param> /// <param name="c">unmanaged calling convention</param>
public BizImportAttribute(CallingConvention c) public BizImportAttribute(CallingConvention c)
{ {
_callingConvention = c; CallingConvention = c;
} }
} }
} }

View File

@ -19,13 +19,7 @@ namespace BizHawk.Emulation.Common
public ICoreFileProvider CoreFileProvider; public ICoreFileProvider CoreFileProvider;
public double VsyncRate public double VsyncRate => VsyncNum / (double)VsyncDen;
{
get
{
return VsyncNum / (double)VsyncDen;
}
}
public int VsyncNum = 60; public int VsyncNum = 60;
public int VsyncDen = 1; public int VsyncDen = 1;

View File

@ -22,6 +22,7 @@ namespace BizHawk.Emulation.Common
else else
crc >>= 1; crc >>= 1;
} }
CRC32Table[i] = crc; CRC32Table[i] = crc;
} }
} }
@ -31,9 +32,8 @@ namespace BizHawk.Emulation.Common
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;
} }
} }
} }

View File

@ -4,7 +4,6 @@ using System.IO;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using BizHawk.Common;
using BizHawk.Common.BufferExtensions; using BizHawk.Common.BufferExtensions;
namespace BizHawk.Emulation.Common namespace BizHawk.Emulation.Common

View File

@ -6,7 +6,6 @@ namespace BizHawk.Emulation.Common
{ {
public MissingFirmwareException(string message) : base(message) public MissingFirmwareException(string message) : base(message)
{ {
} }
} }
@ -18,7 +17,6 @@ namespace BizHawk.Emulation.Common
public UnsupportedGameException(string message) public UnsupportedGameException(string message)
: base(message) : base(message)
{ {
} }
} }

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using BizHawk.Common.ReflectionExtensions;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace BizHawk.Emulation.Common.IEmulatorExtensions namespace BizHawk.Emulation.Common.IEmulatorExtensions
@ -37,8 +36,6 @@ namespace BizHawk.Emulation.Common.IEmulatorExtensions
/// <summary> /// <summary>
/// Returns the core's VideoProvider, or a suitable dummy provider /// Returns the core's VideoProvider, or a suitable dummy provider
/// </summary> /// </summary>
/// <param name="core"></param>
/// <returns></returns>
public static IVideoProvider AsVideoProviderOrDefault(this IEmulator core) public static IVideoProvider AsVideoProviderOrDefault(this IEmulator core)
{ {
return core.ServiceProvider.GetService<IVideoProvider>() return core.ServiceProvider.GetService<IVideoProvider>()
@ -67,10 +64,8 @@ namespace BizHawk.Emulation.Common.IEmulatorExtensions
/// </summary> /// </summary>
public static ISoundProvider AsSoundProviderOrDefault(this IEmulator core) public static ISoundProvider AsSoundProviderOrDefault(this IEmulator core)
{ {
var ret = core.ServiceProvider.GetService<ISoundProvider>(); return core.ServiceProvider.GetService<ISoundProvider>()
if (ret == null) ?? CachedNullSoundProviders.GetValue(core, e => new NullSound(e.CoreComm.VsyncNum, e.CoreComm.VsyncDen));
ret = CachedNullSoundProviders.GetValue(core, e => new NullSound(e.CoreComm.VsyncNum, e.CoreComm.VsyncDen));
return ret;
} }
public static bool HasMemoryDomains(this IEmulator core) public static bool HasMemoryDomains(this IEmulator core)
@ -269,7 +264,6 @@ namespace BizHawk.Emulation.Common.IEmulatorExtensions
} }
// once upon a time, we did a try { poke(peek) } here, but that was before Writable was added. the poke(peek) is not acceptable. If there are further problems, make sure Writable is correct. // once upon a time, we did a try { poke(peek) } here, but that was before Writable was added. the poke(peek) is not acceptable. If there are further problems, make sure Writable is correct.
return true; return true;
} }

View File

@ -7,12 +7,12 @@
public interface IDriveLight : IEmulatorService public interface IDriveLight : IEmulatorService
{ {
/// <summary> /// <summary>
/// Specifies whether there is currently a Drive light available /// Gets a value indicating whether there is currently a Drive light available
/// </summary> /// </summary>
bool DriveLightEnabled { get; } bool DriveLightEnabled { get; }
/// <summary> /// <summary>
/// Specifies whether the light is currently lit /// Gets a value indicating whether the light is currently lit
/// </summary> /// </summary>
bool DriveLightOn { get; } bool DriveLightOn { get; }
} }

View File

@ -11,7 +11,7 @@ namespace BizHawk.Emulation.Common
public interface IStatable : IEmulatorService public interface IStatable : IEmulatorService
{ {
/// <summary> /// <summary>
/// true if the core would rather give a binary savestate than a text one. both must function regardless /// Gets a value indicating whether the core would rather give a binary savestate than a text one. Both must function regardless
/// </summary> /// </summary>
bool BinarySaveStatesPreferred { get; } bool BinarySaveStatesPreferred { get; }

View File

@ -9,7 +9,9 @@ namespace BizHawk.Emulation.Common
/// By Convention it should also throw a NotImplementedException /// By Convention it should also throw a NotImplementedException
/// Any feature that does not have this attribute is assumed to be implemented /// Any feature that does not have this attribute is assumed to be implemented
/// </summary> /// </summary>
public class FeatureNotImplemented : Attribute { } public class FeatureNotImplemented : Attribute
{
}
/// <summary> /// <summary>
/// Should be added to any implementation of IEmulator to document any /// Should be added to any implementation of IEmulator to document any
@ -23,14 +25,7 @@ namespace BizHawk.Emulation.Common
{ {
public ServiceNotApplicable(params Type[] types) public ServiceNotApplicable(params Type[] types)
{ {
if (types != null) NotApplicableTypes = types?.ToList() ?? new List<Type>();
{
NotApplicableTypes = types.ToList();
}
else
{
NotApplicableTypes = new List<Type>();
}
} }
public IEnumerable<Type> NotApplicableTypes { get; private set; } public IEnumerable<Type> NotApplicableTypes { get; private set; }

View File

@ -39,7 +39,10 @@ namespace BizHawk.Emulation.Common
{ {
tmp[0] = source.GetService(propinfo.PropertyType); tmp[0] = source.GetService(propinfo.PropertyType);
if (tmp[0] == null) if (tmp[0] == null)
{
return false; return false;
}
propinfo.GetSetMethod(true).Invoke(target, tmp); propinfo.GetSetMethod(true).Invoke(target, tmp);
} }
@ -48,6 +51,7 @@ namespace BizHawk.Emulation.Common
tmp[0] = source.GetService(propinfo.PropertyType); tmp[0] = source.GetService(propinfo.PropertyType);
propinfo.GetSetMethod(true).Invoke(target, tmp); propinfo.GetSetMethod(true).Invoke(target, tmp);
} }
return true; return true;
} }
@ -59,7 +63,7 @@ namespace BizHawk.Emulation.Common
{ {
return targetType.GetPropertiesWithAttrib(typeof(RequiredService)) return targetType.GetPropertiesWithAttrib(typeof(RequiredService))
.Select(pi => pi.PropertyType) .Select(pi => pi.PropertyType)
.All(t => source.HasService(t)); .All(source.HasService);
} }
} }

View File

@ -5,17 +5,16 @@ namespace BizHawk.Emulation.Common
/// <summary> /// <summary>
/// implements a DC block filter on top of an ISoundProvider. rather simple. /// implements a DC block filter on top of an ISoundProvider. rather simple.
/// </summary> /// </summary>
sealed public class DCFilter : ISoundProvider public sealed class DCFilter : ISoundProvider
{ {
private ISoundProvider _soundProvider; private readonly ISoundProvider _soundProvider;
private int _latchL = 0;
private int _latchR = 0;
private int _accumL = 0;
private int _accumR = 0;
private readonly int _depth; private readonly int _depth;
private int _latchL;
private int _latchR;
private int _accumL;
private int _accumR;
private static int DepthFromFilterwidth(int filterwidth) private static int DepthFromFilterwidth(int filterwidth)
{ {
int ret = -2; int ret = -2;
@ -24,6 +23,7 @@ namespace BizHawk.Emulation.Common
filterwidth >>= 1; filterwidth >>= 1;
ret++; ret++;
} }
return ret; return ret;
} }
@ -82,21 +82,35 @@ namespace BizHawk.Emulation.Common
int bigL = _accumL >> 12; int bigL = _accumL >> 12;
int bigR = _accumR >> 12; int bigR = _accumR >> 12;
// check for clipping // check for clipping
if (bigL > 32767) if (bigL > 32767)
{
samplesout[i] = 32767; samplesout[i] = 32767;
}
else if (bigL < -32768) else if (bigL < -32768)
{
samplesout[i] = -32768; samplesout[i] = -32768;
}
else else
{
samplesout[i] = (short)bigL; samplesout[i] = (short)bigL;
}
if (bigR > 32767) if (bigR > 32767)
{
samplesout[i + 1] = 32767; samplesout[i + 1] = 32767;
}
else if (bigR < -32768) else if (bigR < -32768)
{
samplesout[i + 1] = -32768; samplesout[i + 1] = -32768;
}
else else
{
samplesout[i + 1] = (short)bigR; samplesout[i + 1] = (short)bigR;
} }
} }
}
public void GetSamplesAsync(short[] samples) public void GetSamplesAsync(short[] samples)
{ {
@ -122,15 +136,9 @@ namespace BizHawk.Emulation.Common
nsamp = nsampin; nsamp = nsampin;
} }
public SyncSoundMode SyncMode public SyncSoundMode SyncMode => _soundProvider.SyncMode;
{
get { return _soundProvider.SyncMode; }
}
public bool CanProvideAsync public bool CanProvideAsync => _soundProvider.CanProvideAsync;
{
get { return _soundProvider.CanProvideAsync; }
}
public void SetSyncMode(SyncSoundMode mode) public void SetSyncMode(SyncSoundMode mode)
{ {

View File

@ -34,15 +34,9 @@ namespace BizHawk.Emulation.Common
buffer.clear(); buffer.clear();
} }
public bool CanProvideAsync public bool CanProvideAsync => true;
{
get { return true; }
}
public SyncSoundMode SyncMode public SyncSoundMode SyncMode => SyncSoundMode.Async;
{
get { return SyncSoundMode.Async; }
}
public void SetSyncMode(SyncSoundMode mode) public void SetSyncMode(SyncSoundMode mode)
{ {
@ -253,6 +247,7 @@ namespace BizHawk.Emulation.Common
size--; size--;
} }
} }
left = curr[0]; left = curr[0];
right = curr[1]; right = curr[1];
} }
@ -267,7 +262,7 @@ namespace BizHawk.Emulation.Common
public ssamp(short ll, short rr) { l = ll; r = rr; } public ssamp(short ll, short rr) { l = ll; r = rr; }
}; };
List<ssamp> sampleQueue = new List<ssamp>(); 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) static int pingpong(int x, int y)

View File

@ -1,8 +1,5 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text;
namespace BizHawk.Emulation.Common namespace BizHawk.Emulation.Common
{ {

View File

@ -1,7 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -29,6 +27,7 @@ namespace BizHawk.Emulation.Common
{ {
return Data.Count > 0; return Data.Count > 0;
} }
public bool ShouldSerializeObjects() public bool ShouldSerializeObjects()
{ {
return Objects.Count > 0; return Objects.Count > 0;
@ -39,6 +38,7 @@ namespace BizHawk.Emulation.Common
[JsonIgnore] [JsonIgnore]
Stack<Node> Nodes; Stack<Node> Nodes;
[JsonIgnore] [JsonIgnore]
Node Current { get { return Nodes.Peek(); } } Node Current { get { return Nodes.Peek(); } }
@ -54,6 +54,7 @@ namespace BizHawk.Emulation.Common
Marshal.Copy(data, d, 0, length); Marshal.Copy(data, d, 0, length);
Current.Data.Add(name, d); // will except for us if the key is already present Current.Data.Add(name, d); // will except for us if the key is already present
} }
public void Load(IntPtr data, int length, string name) public void Load(IntPtr data, int length, string name)
{ {
byte[] d = Current.Data[name]; byte[] d = Current.Data[name];
@ -61,17 +62,20 @@ namespace BizHawk.Emulation.Common
throw new InvalidOperationException(); throw new InvalidOperationException();
Marshal.Copy(d, 0, data, length); Marshal.Copy(d, 0, data, length);
} }
public void EnterSectionSave(string name) public void EnterSectionSave(string name)
{ {
Node next = new Node(); Node next = new Node();
Current.Objects.Add(name, next); Current.Objects.Add(name, next);
Nodes.Push(next); Nodes.Push(next);
} }
public void EnterSectionLoad(string name) public void EnterSectionLoad(string name)
{ {
Node next = Current.Objects[name]; Node next = Current.Objects[name];
Nodes.Push(next); Nodes.Push(next);
} }
public void EnterSection(string name) public void EnterSection(string name)
{ {
// works for either save or load, but as a consequence cannot report intelligent // works for either save or load, but as a consequence cannot report intelligent
@ -85,6 +89,7 @@ namespace BizHawk.Emulation.Common
} }
Nodes.Push(next); Nodes.Push(next);
} }
public void ExitSection(string name) public void ExitSection(string name)
{ {
Node last = Nodes.Pop(); Node last = Nodes.Pop();
@ -105,6 +110,7 @@ namespace BizHawk.Emulation.Common
ExitSection = new TextStateFPtrs.SectionFunction(ExitSection) ExitSection = new TextStateFPtrs.SectionFunction(ExitSection)
}; };
} }
public TextStateFPtrs GetFunctionPointersLoad() public TextStateFPtrs GetFunctionPointersLoad()
{ {
return new TextStateFPtrs return new TextStateFPtrs
@ -116,6 +122,7 @@ namespace BizHawk.Emulation.Common
}; };
} }
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct TextStateFPtrs public struct TextStateFPtrs
{ {
@ -129,6 +136,4 @@ namespace BizHawk.Emulation.Common
public SectionFunction EnterSection; public SectionFunction EnterSection;
public SectionFunction ExitSection; public SectionFunction ExitSection;
} }
} }

View File

@ -18,6 +18,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1210/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1210/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ARGB/@EntryIndexedValue">ARGB</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ARGB/@EntryIndexedValue">ARGB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CDL/@EntryIndexedValue">CDL</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CDL/@EntryIndexedValue">CDL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CGB/@EntryIndexedValue">CGB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DB/@EntryIndexedValue">DB</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DB/@EntryIndexedValue">DB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IO/@EntryIndexedValue">IO</s:String></wpf:ResourceDictionary> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IO/@EntryIndexedValue">IO</s:String></wpf:ResourceDictionary>