2014-04-25 01:19:57 +00:00
|
|
|
|
using System;
|
2014-11-24 00:38:29 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
2014-11-30 14:52:52 +00:00
|
|
|
|
using BizHawk.Common.ReflectionExtensions;
|
2014-04-25 01:19:57 +00:00
|
|
|
|
|
2014-05-31 14:29:27 +00:00
|
|
|
|
namespace BizHawk.Emulation.Common.IEmulatorExtensions
|
2014-04-25 01:19:57 +00:00
|
|
|
|
{
|
|
|
|
|
public static class Extensions
|
|
|
|
|
{
|
|
|
|
|
public static CoreAttributes Attributes(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
return (CoreAttributes)Attribute.GetCustomAttribute(core.GetType(), typeof(CoreAttributes));
|
|
|
|
|
}
|
2014-09-01 18:43:41 +00:00
|
|
|
|
|
2014-12-15 22:25:06 +00:00
|
|
|
|
// todo: most of the special cases involving the NullEmulator should probably go away
|
2014-12-05 00:15:28 +00:00
|
|
|
|
public static bool IsNull(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
return core == null || core is NullEmulator;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-01 18:43:41 +00:00
|
|
|
|
public static bool HasMemoryDomains(this IEmulator core)
|
|
|
|
|
{
|
2014-12-05 00:52:16 +00:00
|
|
|
|
if (core == null)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return core.ServiceProvider.HasService<IMemoryDomains>();
|
2014-09-01 18:43:41 +00:00
|
|
|
|
}
|
2014-11-24 00:38:29 +00:00
|
|
|
|
|
2014-12-05 00:32:29 +00:00
|
|
|
|
public static IMemoryDomains AsMemoryDomains(this IEmulator core)
|
2014-12-05 00:17:34 +00:00
|
|
|
|
{
|
|
|
|
|
return (IMemoryDomains)core.ServiceProvider.GetService<IMemoryDomains>();
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-30 15:22:08 +00:00
|
|
|
|
public static bool HasSaveRam(this IEmulator core)
|
|
|
|
|
{
|
2014-12-05 00:52:16 +00:00
|
|
|
|
if (core == null)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return core.ServiceProvider.HasService<ISaveRam>();
|
2014-11-30 15:22:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-05 00:32:29 +00:00
|
|
|
|
public static ISaveRam AsSaveRam(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
return (ISaveRam)core.ServiceProvider.GetService<ISaveRam>();
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-30 16:42:58 +00:00
|
|
|
|
public static bool HasSavestates(this IEmulator core)
|
|
|
|
|
{
|
2014-12-05 00:52:16 +00:00
|
|
|
|
if (core == null)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return core.ServiceProvider.HasService<IStatable>();
|
2014-11-30 16:42:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-05 00:32:29 +00:00
|
|
|
|
public static IStatable AsStatable(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
return (IStatable)core.ServiceProvider.GetService<IStatable>();
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-30 20:29:30 +00:00
|
|
|
|
public static bool CanPollInput(this IEmulator core)
|
|
|
|
|
{
|
2014-12-05 00:52:16 +00:00
|
|
|
|
if (core == null)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return core.ServiceProvider.HasService<IInputPollable>();
|
2014-11-30 14:18:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-05 00:32:29 +00:00
|
|
|
|
public static IInputPollable AsInputPollable(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
return (IInputPollable)core.ServiceProvider.GetService<IInputPollable>();
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-12 01:49:54 +00:00
|
|
|
|
public static bool HasDriveLight(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
if (core == null)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return core.ServiceProvider.HasService<IDriveLight>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IDriveLight AsDriveLight(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
return (IDriveLight)core.ServiceProvider.GetService<IDriveLight>();
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-05 01:56:45 +00:00
|
|
|
|
public static bool CanDebug(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
if (core == null)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return core.ServiceProvider.HasService<IDebuggable>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IDebuggable AsDebuggable(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
return (IDebuggable)core.ServiceProvider.GetService<IDebuggable>();
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-05 00:05:40 +00:00
|
|
|
|
public static bool CpuTraceAvailable(this IEmulator core)
|
|
|
|
|
{
|
2014-12-05 01:56:45 +00:00
|
|
|
|
if (core == null)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-23 01:58:12 +00:00
|
|
|
|
return core.ServiceProvider.HasService<ITraceable>();
|
|
|
|
|
}
|
2014-12-05 00:05:40 +00:00
|
|
|
|
|
2014-12-23 01:58:12 +00:00
|
|
|
|
public static ITraceable AsTracer(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
return (ITraceable)core.ServiceProvider.GetService<ITraceable>();
|
2014-12-05 00:05:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-05 01:56:45 +00:00
|
|
|
|
public static bool MemoryCallbacksAvailable(this IEmulator core)
|
2014-12-05 00:05:40 +00:00
|
|
|
|
{
|
2014-12-05 00:52:16 +00:00
|
|
|
|
if (core == null)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-05 01:56:45 +00:00
|
|
|
|
// TODO: this is a pretty ugly way to handle this
|
|
|
|
|
var debuggable = (IDebuggable)core.ServiceProvider.GetService<IDebuggable>();
|
|
|
|
|
if (debuggable != null)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var tracer = debuggable.MemoryCallbacks;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (NotImplementedException)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-05 00:05:40 +00:00
|
|
|
|
|
2014-12-05 01:56:45 +00:00
|
|
|
|
return false;
|
2014-12-05 00:05:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-13 20:52:52 +00:00
|
|
|
|
public static bool CanDisassemble(this IEmulator core)
|
|
|
|
|
{
|
|
|
|
|
if (core == null)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return core.ServiceProvider.HasService<IDisassemblable>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IDisassemblable AsDissassembler(this IEmulator core)
|
|
|
|
|
{
|
2014-12-15 22:25:06 +00:00
|
|
|
|
return (IDisassemblable)core.ServiceProvider.GetService<IDisassemblable>();
|
2014-12-13 20:52:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-11-24 00:38:29 +00:00
|
|
|
|
// TODO: a better place for these
|
|
|
|
|
public static bool IsImplemented(this MethodInfo info)
|
|
|
|
|
{
|
2014-11-30 14:52:52 +00:00
|
|
|
|
// If a method is marked as Not implemented, it is not implemented no matter what the body is
|
2014-12-04 00:38:42 +00:00
|
|
|
|
if (info.GetCustomAttributes(false).Any(a => a is FeatureNotImplemented))
|
2014-11-30 14:52:52 +00:00
|
|
|
|
{
|
2014-12-04 00:38:42 +00:00
|
|
|
|
return false;
|
2014-11-30 14:52:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If a method is not marked but all it does is throw an exception, consider it not implemented
|
|
|
|
|
return !info.ThrowsError();
|
2014-11-24 00:38:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool IsImplemented(this PropertyInfo info)
|
|
|
|
|
{
|
2014-12-04 00:38:42 +00:00
|
|
|
|
return !info.GetCustomAttributes(false).Any(a => a is FeatureNotImplemented);
|
2014-11-24 00:38:29 +00:00
|
|
|
|
}
|
2014-04-25 01:19:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|