Merge branch 'master' into MoreUnixMonoCompatWork
This commit is contained in:
commit
35f56b88f8
|
@ -37,6 +37,10 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.SQLite, Version=1.0.105.2, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\Users\uptho\Documents\BizHawk-2.3\dll\System.Data.SQLite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
|
@ -48,6 +52,19 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="Attributes\BizHawkExternalToolUsageAttribute.cs" />
|
||||
<Compile Include="Attributes\BizHawkExternalToolAttribute.cs" />
|
||||
<Compile Include="Classes\ApiInjector.cs" />
|
||||
<Compile Include="Classes\Api\EmuApi.cs" />
|
||||
<Compile Include="Classes\Api\GameInfoApi.cs" />
|
||||
<Compile Include="Classes\Api\MemApi.cs" />
|
||||
<Compile Include="Classes\Api\MemApiBase.cs" />
|
||||
<Compile Include="Classes\Api\PluginBase.cs" />
|
||||
<Compile Include="Classes\Api\JoypadApi.cs" />
|
||||
<Compile Include="Classes\Api\MemEventsApi.cs" />
|
||||
<Compile Include="Classes\Api\MemorySaveStateApi.cs" />
|
||||
<Compile Include="Classes\Api\MovieApi.cs" />
|
||||
<Compile Include="Classes\Api\SqlApi.cs" />
|
||||
<Compile Include="Classes\Api\UserDataApi.cs" />
|
||||
<Compile Include="Classes\BasicApiProvider.cs" />
|
||||
<Compile Include="Classes\BizHawkSystemIdToCoreSystemEnumConverter.cs" />
|
||||
<Compile Include="Classes\Events\EventArgs\BeforeQuickLoadEventArgs.cs" />
|
||||
<Compile Include="Classes\Events\EventArgs\BeforeQuickSaveEventArgs.cs" />
|
||||
|
@ -62,7 +79,25 @@
|
|||
<Compile Include="Enums\BizHawkExternalToolUsage.cs" />
|
||||
<Compile Include="Classes\ClientApi.cs" />
|
||||
<Compile Include="Classes\ExternalToolManager.cs" />
|
||||
<Compile Include="Interfaces\Api\IComm.cs" />
|
||||
<Compile Include="Interfaces\Api\IInput.cs" />
|
||||
<Compile Include="Interfaces\Api\ITool.cs" />
|
||||
<Compile Include="Interfaces\Api\ISaveState.cs" />
|
||||
<Compile Include="Interfaces\Api\IUserData.cs" />
|
||||
<Compile Include="Interfaces\Api\ISql.cs" />
|
||||
<Compile Include="Interfaces\Api\IMovie.cs" />
|
||||
<Compile Include="Interfaces\Api\IMemorySavestate.cs" />
|
||||
<Compile Include="Interfaces\Api\IMemEvents.cs" />
|
||||
<Compile Include="Interfaces\Api\IEmu.cs" />
|
||||
<Compile Include="Interfaces\Api\IExternalApi.cs" />
|
||||
<Compile Include="Interfaces\Api\IJoypad.cs" />
|
||||
<Compile Include="Interfaces\IExternalApiProvider.cs" />
|
||||
<Compile Include="Interfaces\IExternalToolForm.cs" />
|
||||
<Compile Include="Interfaces\Api\IGameInfo.cs" />
|
||||
<Compile Include="Interfaces\Api\IGui.cs" />
|
||||
<Compile Include="Interfaces\Api\IMem.cs" />
|
||||
<Compile Include="Interfaces\IPlugin.cs" />
|
||||
<Compile Include="Interfaces\Api\IApiContainer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -95,4 +130,4 @@
|
|||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
|
@ -0,0 +1,459 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Emulation.Cores.Nintendo.NES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Cores.PCEngine;
|
||||
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
|
||||
using BizHawk.Emulation.Cores.Sega.MasterSystem;
|
||||
using BizHawk.Emulation.Cores.WonderSwan;
|
||||
using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
[Description("A library for interacting with the currently loaded emulator core")]
|
||||
public sealed class EmuApi : IEmu
|
||||
{
|
||||
private static class EmuStatic
|
||||
{
|
||||
public static void DisplayVsync(bool enabled)
|
||||
{
|
||||
Global.Config.VSync = enabled;
|
||||
}
|
||||
public static string GetSystemId()
|
||||
{
|
||||
return Global.Game.System;
|
||||
}
|
||||
public static void LimitFramerate(bool enabled)
|
||||
{
|
||||
Global.Config.ClockThrottle = enabled;
|
||||
}
|
||||
|
||||
public static void MinimizeFrameskip(bool enabled)
|
||||
{
|
||||
Global.Config.AutoMinimizeSkipping = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
[RequiredService]
|
||||
private IEmulator Emulator { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
private IDebuggable DebuggableCore { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
private IDisassemblable DisassemblableCore { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
private IMemoryDomains MemoryDomains { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
private IInputPollable InputPollableCore { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
private IRegionable RegionableCore { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
private IBoardInfo BoardInfo { get; set; }
|
||||
|
||||
public Action FrameAdvanceCallback { get; set; }
|
||||
public Action YieldCallback { get; set; }
|
||||
|
||||
public EmuApi()
|
||||
{ }
|
||||
|
||||
public void DisplayVsync(bool enabled)
|
||||
{
|
||||
EmuStatic.DisplayVsync(enabled);
|
||||
}
|
||||
|
||||
public void FrameAdvance()
|
||||
{
|
||||
FrameAdvanceCallback();
|
||||
}
|
||||
|
||||
public int FrameCount()
|
||||
{
|
||||
return Emulator.Frame;
|
||||
}
|
||||
|
||||
public object Disassemble(uint pc, string name = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DisassemblableCore == null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
MemoryDomain domain = MemoryDomains.SystemBus;
|
||||
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
domain = MemoryDomains[name];
|
||||
}
|
||||
|
||||
int l;
|
||||
var d = DisassemblableCore.Disassemble(domain, pc, out l);
|
||||
return new { disasm = d, length = l };
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
Console.WriteLine($"Error: {Emulator.Attributes().CoreName} does not yet implement disassemble()");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ulong? GetRegister(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DebuggableCore == null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
var registers = DebuggableCore.GetCpuFlagsAndRegisters();
|
||||
ulong? value = null;
|
||||
if (registers.ContainsKey(name)) value = registers[name].Value;
|
||||
return value;
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
Console.WriteLine($"Error: {Emulator.Attributes().CoreName} does not yet implement getregister()");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, ulong> GetRegisters()
|
||||
{
|
||||
var table = new Dictionary<string, ulong>();
|
||||
|
||||
try
|
||||
{
|
||||
if (DebuggableCore == null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
foreach (var kvp in DebuggableCore.GetCpuFlagsAndRegisters())
|
||||
{
|
||||
table[kvp.Key] = kvp.Value.Value;
|
||||
}
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
Console.WriteLine($"Error: {Emulator.Attributes().CoreName} does not yet implement getregisters()");
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
public void SetRegister(string register, int value)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DebuggableCore == null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
DebuggableCore.SetCpuRegister(register, value);
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
Console.WriteLine($"Error: {Emulator.Attributes().CoreName} does not yet implement setregister()");
|
||||
}
|
||||
}
|
||||
|
||||
public long TotalExecutedycles()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DebuggableCore == null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
return DebuggableCore.TotalExecutedCycles;
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
Console.WriteLine($"Error: {Emulator.Attributes().CoreName} does not yet implement totalexecutedcycles()");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSystemId()
|
||||
{
|
||||
return EmuStatic.GetSystemId();
|
||||
}
|
||||
|
||||
public bool IsLagged()
|
||||
{
|
||||
if (InputPollableCore != null)
|
||||
{
|
||||
return InputPollableCore.IsLagFrame;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Can not get lag information, {Emulator.Attributes().CoreName} does not implement IInputPollable");
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetIsLagged(bool value = true)
|
||||
{
|
||||
if (InputPollableCore != null)
|
||||
{
|
||||
InputPollableCore.IsLagFrame = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Can not set lag information, {Emulator.Attributes().CoreName} does not implement IInputPollable");
|
||||
}
|
||||
}
|
||||
|
||||
public int LagCount()
|
||||
{
|
||||
if (InputPollableCore != null)
|
||||
{
|
||||
return InputPollableCore.LagCount;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Can not get lag information, {Emulator.Attributes().CoreName} does not implement IInputPollable");
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void SetLagCount(int count)
|
||||
{
|
||||
if (InputPollableCore != null)
|
||||
{
|
||||
InputPollableCore.LagCount = count;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Can not set lag information, {Emulator.Attributes().CoreName} does not implement IInputPollable");
|
||||
}
|
||||
}
|
||||
|
||||
public void LimitFramerate(bool enabled)
|
||||
{
|
||||
EmuStatic.LimitFramerate(enabled);
|
||||
}
|
||||
|
||||
public void MinimizeFrameskip(bool enabled)
|
||||
{
|
||||
EmuStatic.MinimizeFrameskip(enabled);
|
||||
}
|
||||
|
||||
public void Yield()
|
||||
{
|
||||
YieldCallback();
|
||||
}
|
||||
|
||||
public string GetDisplayType()
|
||||
{
|
||||
if (RegionableCore != null)
|
||||
{
|
||||
return RegionableCore.Region.ToString();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public string GetBoardName()
|
||||
{
|
||||
if (BoardInfo != null)
|
||||
{
|
||||
return BoardInfo.BoardName;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
public object GetSettings()
|
||||
{
|
||||
if (Emulator is GPGX)
|
||||
{
|
||||
var gpgx = Emulator as GPGX;
|
||||
return gpgx.GetSettings();
|
||||
}
|
||||
else if (Emulator is LibsnesCore)
|
||||
{
|
||||
var snes = Emulator as LibsnesCore;
|
||||
return snes.GetSettings();
|
||||
}
|
||||
else if (Emulator is NES)
|
||||
{
|
||||
var nes = Emulator as NES;
|
||||
return nes.GetSettings();
|
||||
}
|
||||
else if (Emulator is QuickNES)
|
||||
{
|
||||
var quicknes = Emulator as QuickNES;
|
||||
return quicknes.GetSettings();
|
||||
}
|
||||
else if (Emulator is PCEngine)
|
||||
{
|
||||
var pce = Emulator as PCEngine;
|
||||
return pce.GetSettings();
|
||||
}
|
||||
else if (Emulator is SMS)
|
||||
{
|
||||
var sms = Emulator as SMS;
|
||||
return sms.GetSettings();
|
||||
}
|
||||
else if (Emulator is WonderSwan)
|
||||
{
|
||||
var ws = Emulator as WonderSwan;
|
||||
return ws.GetSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public bool PutSettings(object settings)
|
||||
{
|
||||
if (Emulator is GPGX)
|
||||
{
|
||||
var gpgx = Emulator as GPGX;
|
||||
return gpgx.PutSettings(settings as GPGX.GPGXSettings);
|
||||
}
|
||||
else if (Emulator is LibsnesCore)
|
||||
{
|
||||
var snes = Emulator as LibsnesCore;
|
||||
return snes.PutSettings(settings as LibsnesCore.SnesSettings);
|
||||
}
|
||||
else if (Emulator is NES)
|
||||
{
|
||||
var nes = Emulator as NES;
|
||||
return nes.PutSettings(settings as NES.NESSettings);
|
||||
}
|
||||
else if (Emulator is QuickNES)
|
||||
{
|
||||
var quicknes = Emulator as QuickNES;
|
||||
return quicknes.PutSettings(settings as QuickNES.QuickNESSettings);
|
||||
}
|
||||
else if (Emulator is PCEngine)
|
||||
{
|
||||
var pce = Emulator as PCEngine;
|
||||
return pce.PutSettings(settings as PCEngine.PCESettings);
|
||||
}
|
||||
else if (Emulator is SMS)
|
||||
{
|
||||
var sms = Emulator as SMS;
|
||||
return sms.PutSettings(settings as SMS.SMSSettings);
|
||||
}
|
||||
else if (Emulator is WonderSwan)
|
||||
{
|
||||
var ws = Emulator as WonderSwan;
|
||||
return ws.PutSettings(settings as WonderSwan.Settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public void SetRenderPlanes(params bool[] luaParam)
|
||||
{
|
||||
if (Emulator is GPGX)
|
||||
{
|
||||
var gpgx = Emulator as GPGX;
|
||||
var s = gpgx.GetSettings();
|
||||
s.DrawBGA = luaParam[0];
|
||||
s.DrawBGB = luaParam[1];
|
||||
s.DrawBGW = luaParam[2];
|
||||
s.DrawObj = luaParam[3];
|
||||
gpgx.PutSettings(s);
|
||||
|
||||
}
|
||||
else if (Emulator is LibsnesCore)
|
||||
{
|
||||
var snes = Emulator as LibsnesCore;
|
||||
var s = snes.GetSettings();
|
||||
s.ShowBG1_0 = s.ShowBG1_1 = luaParam[0];
|
||||
s.ShowBG2_0 = s.ShowBG2_1 = luaParam[1];
|
||||
s.ShowBG3_0 = s.ShowBG3_1 = luaParam[2];
|
||||
s.ShowBG4_0 = s.ShowBG4_1 = luaParam[3];
|
||||
s.ShowOBJ_0 = luaParam[4];
|
||||
s.ShowOBJ_1 = luaParam[5];
|
||||
s.ShowOBJ_2 = luaParam[6];
|
||||
s.ShowOBJ_3 = luaParam[7];
|
||||
snes.PutSettings(s);
|
||||
}
|
||||
else if (Emulator is NES)
|
||||
{
|
||||
// in the future, we could do something more arbitrary here.
|
||||
// but this isn't any worse than the old system
|
||||
var nes = Emulator as NES;
|
||||
var s = nes.GetSettings();
|
||||
s.DispSprites = luaParam[0];
|
||||
s.DispBackground = luaParam[1];
|
||||
nes.PutSettings(s);
|
||||
}
|
||||
else if (Emulator is QuickNES)
|
||||
{
|
||||
var quicknes = Emulator as QuickNES;
|
||||
var s = quicknes.GetSettings();
|
||||
|
||||
// this core doesn't support disabling BG
|
||||
bool showsp = GetSetting(0, luaParam);
|
||||
if (showsp && s.NumSprites == 0)
|
||||
{
|
||||
s.NumSprites = 8;
|
||||
}
|
||||
else if (!showsp && s.NumSprites > 0)
|
||||
{
|
||||
s.NumSprites = 0;
|
||||
}
|
||||
|
||||
quicknes.PutSettings(s);
|
||||
}
|
||||
else if (Emulator is PCEngine)
|
||||
{
|
||||
var pce = Emulator as PCEngine;
|
||||
var s = pce.GetSettings();
|
||||
s.ShowOBJ1 = GetSetting(0, luaParam);
|
||||
s.ShowBG1 = GetSetting(1, luaParam);
|
||||
if (luaParam.Length > 2)
|
||||
{
|
||||
s.ShowOBJ2 = GetSetting(2, luaParam);
|
||||
s.ShowBG2 = GetSetting(3, luaParam);
|
||||
}
|
||||
|
||||
pce.PutSettings(s);
|
||||
}
|
||||
else if (Emulator is SMS)
|
||||
{
|
||||
var sms = Emulator as SMS;
|
||||
var s = sms.GetSettings();
|
||||
s.DispOBJ = GetSetting(0, luaParam);
|
||||
s.DispBG = GetSetting(1, luaParam);
|
||||
sms.PutSettings(s);
|
||||
}
|
||||
else if (Emulator is WonderSwan)
|
||||
{
|
||||
var ws = Emulator as WonderSwan;
|
||||
var s = ws.GetSettings();
|
||||
s.EnableSprites = GetSetting(0, luaParam);
|
||||
s.EnableFG = GetSetting(1, luaParam);
|
||||
s.EnableBG = GetSetting(2, luaParam);
|
||||
ws.PutSettings(s);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool GetSetting(int index, bool[] settings)
|
||||
{
|
||||
if (index < settings.Length)
|
||||
{
|
||||
return settings[index];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public sealed class GameInfoApi : IGameInfo
|
||||
{
|
||||
[OptionalService]
|
||||
private IBoardInfo BoardInfo { get; set; }
|
||||
|
||||
public GameInfoApi()
|
||||
{ }
|
||||
|
||||
public string GetRomName()
|
||||
{
|
||||
if (Global.Game != null)
|
||||
{
|
||||
return Global.Game.Name ?? "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public string GetRomHash()
|
||||
{
|
||||
if (Global.Game != null)
|
||||
{
|
||||
return Global.Game.Hash ?? "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public bool InDatabase()
|
||||
{
|
||||
if (Global.Game != null)
|
||||
{
|
||||
return !Global.Game.NotInDatabase;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public string GetStatus()
|
||||
{
|
||||
if (Global.Game != null)
|
||||
{
|
||||
return Global.Game.Status.ToString();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public bool IsStatusBad()
|
||||
{
|
||||
if (Global.Game != null)
|
||||
{
|
||||
return Global.Game.IsRomStatusBad();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public string GetBoardType()
|
||||
{
|
||||
return BoardInfo?.BoardName ?? "";
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetOptions()
|
||||
{
|
||||
var options = new Dictionary<string, string>();
|
||||
|
||||
if (Global.Game != null)
|
||||
{
|
||||
foreach (var option in Global.Game.GetOptionsDict())
|
||||
{
|
||||
options[option.Key] = option.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public sealed class JoypadApi : IJoypad
|
||||
{
|
||||
public JoypadApi()
|
||||
{ }
|
||||
|
||||
public Dictionary<string,dynamic> Get(int? controller = null)
|
||||
{
|
||||
var buttons = new Dictionary<string, dynamic>();
|
||||
var adaptor = Global.AutofireStickyXORAdapter;
|
||||
foreach (var button in adaptor.Source.Definition.BoolButtons)
|
||||
{
|
||||
if (!controller.HasValue)
|
||||
{
|
||||
buttons[button] = adaptor.IsPressed(button);
|
||||
}
|
||||
else if (button.Length >= 3 && button.Substring(0, 2) == "P" + controller)
|
||||
{
|
||||
buttons[button.Substring(3)] = adaptor.IsPressed("P" + controller + " " + button.Substring(3));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var button in adaptor.Source.Definition.FloatControls)
|
||||
{
|
||||
if (controller == null)
|
||||
{
|
||||
buttons[button] = adaptor.GetFloat(button);
|
||||
}
|
||||
else if (button.Length >= 3 && button.Substring(0, 2) == "P" + controller)
|
||||
{
|
||||
buttons[button.Substring(3)] = adaptor.GetFloat("P" + controller + " " + button.Substring(3));
|
||||
}
|
||||
}
|
||||
|
||||
buttons["clear"] = null;
|
||||
buttons["getluafunctionslist"] = null;
|
||||
buttons["output"] = null;
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
// TODO: what about float controls?
|
||||
public Dictionary<string, dynamic> GetImmediate()
|
||||
{
|
||||
var buttons = new Dictionary<string, dynamic>();
|
||||
var adaptor = Global.ActiveController;
|
||||
foreach (var button in adaptor.Definition.BoolButtons)
|
||||
{
|
||||
buttons[button] = adaptor.IsPressed(button);
|
||||
}
|
||||
foreach (var button in adaptor.Definition.FloatControls)
|
||||
{
|
||||
buttons[button] = adaptor.GetFloat(button);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
public void SetFromMnemonicStr(string inputLogEntry)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lg = Global.MovieSession.MovieControllerInstance();
|
||||
lg.SetControllersAsMnemonic(inputLogEntry);
|
||||
|
||||
foreach (var button in lg.Definition.BoolButtons)
|
||||
{
|
||||
Global.LuaAndAdaptor.SetButton(button, lg.IsPressed(button));
|
||||
}
|
||||
|
||||
foreach (var floatButton in lg.Definition.FloatControls)
|
||||
{
|
||||
Global.LuaAndAdaptor.SetFloat(floatButton, lg.GetFloat(floatButton));
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Console.WriteLine("invalid mnemonic string: " + inputLogEntry);
|
||||
}
|
||||
}
|
||||
|
||||
public void Set(Dictionary<string,bool> buttons, int? controller = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var button in buttons.Keys)
|
||||
{
|
||||
var invert = false;
|
||||
bool? theValue;
|
||||
var theValueStr = buttons[button].ToString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(theValueStr))
|
||||
{
|
||||
if (theValueStr.ToLower() == "false")
|
||||
{
|
||||
theValue = false;
|
||||
}
|
||||
else if (theValueStr.ToLower() == "true")
|
||||
{
|
||||
theValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
invert = true;
|
||||
theValue = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
theValue = null;
|
||||
}
|
||||
|
||||
var toPress = button.ToString();
|
||||
if (controller.HasValue)
|
||||
{
|
||||
toPress = "P" + controller + " " + button;
|
||||
}
|
||||
|
||||
if (!invert)
|
||||
{
|
||||
if (theValue.HasValue) // Force
|
||||
{
|
||||
Global.LuaAndAdaptor.SetButton(toPress, theValue.Value);
|
||||
Global.ActiveController.Overrides(Global.LuaAndAdaptor);
|
||||
}
|
||||
else // Unset
|
||||
{
|
||||
Global.LuaAndAdaptor.UnSet(toPress);
|
||||
Global.ActiveController.Overrides(Global.LuaAndAdaptor);
|
||||
}
|
||||
}
|
||||
else // Inverse
|
||||
{
|
||||
Global.LuaAndAdaptor.SetInverse(toPress);
|
||||
Global.ActiveController.Overrides(Global.LuaAndAdaptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
/*Eat it*/
|
||||
}
|
||||
}
|
||||
public void Set(string button, bool? state = null, int? controller = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var toPress = button;
|
||||
if (controller.HasValue)
|
||||
{
|
||||
toPress = "P" + controller + " " + button;
|
||||
}
|
||||
if (state.HasValue)
|
||||
Global.LuaAndAdaptor.SetButton(toPress, state.Value);
|
||||
else
|
||||
Global.LuaAndAdaptor.UnSet(toPress);
|
||||
Global.ActiveController.Overrides(Global.LuaAndAdaptor);
|
||||
}
|
||||
catch
|
||||
{
|
||||
/*Eat it*/
|
||||
}
|
||||
}
|
||||
public void SetAnalog(Dictionary<string,float> controls, object controller = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var name in controls.Keys)
|
||||
{
|
||||
var theValueStr = controls[name].ToString();
|
||||
float? theValue = null;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(theValueStr))
|
||||
{
|
||||
float f;
|
||||
if (float.TryParse(theValueStr, out f))
|
||||
{
|
||||
theValue = f;
|
||||
}
|
||||
}
|
||||
|
||||
if (controller == null)
|
||||
{
|
||||
Global.StickyXORAdapter.SetFloat(name.ToString(), theValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Global.StickyXORAdapter.SetFloat("P" + controller + " " + name, theValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
/*Eat it*/
|
||||
}
|
||||
}
|
||||
public void SetAnalog(string control, float? value = null, object controller = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null)
|
||||
{
|
||||
Global.StickyXORAdapter.SetFloat(control, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Global.StickyXORAdapter.SetFloat("P" + controller + " " + control, value);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
/*Eat it*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,288 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Common.BufferExtensions;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public sealed class MemApi : MemApiBase, IMem
|
||||
{
|
||||
private MemoryDomain _currentMemoryDomain;
|
||||
private bool _isBigEndian = false;
|
||||
public MemApi()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
protected override MemoryDomain Domain
|
||||
{
|
||||
get
|
||||
{
|
||||
if (MemoryDomainCore != null)
|
||||
{
|
||||
if (_currentMemoryDomain == null)
|
||||
{
|
||||
_currentMemoryDomain = MemoryDomainCore.HasSystemBus
|
||||
? MemoryDomainCore.SystemBus
|
||||
: MemoryDomainCore.MainMemory;
|
||||
}
|
||||
|
||||
return _currentMemoryDomain;
|
||||
}
|
||||
|
||||
var error = $"Error: {Emulator.Attributes().CoreName} does not implement memory domains";
|
||||
Console.WriteLine(error);
|
||||
throw new NotImplementedException(error);
|
||||
}
|
||||
}
|
||||
|
||||
#region Unique Library Methods
|
||||
|
||||
public void SetBigEndian(bool enabled = true)
|
||||
{
|
||||
_isBigEndian = enabled;
|
||||
}
|
||||
|
||||
public List<string> GetMemoryDomainList()
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
foreach (var domain in DomainList)
|
||||
{
|
||||
list.Add(domain.Name);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public uint GetMemoryDomainSize(string name = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
return (uint)Domain.Size;
|
||||
}
|
||||
|
||||
return (uint)DomainList[VerifyMemoryDomain(name)].Size;
|
||||
}
|
||||
|
||||
public string GetCurrentMemoryDomain()
|
||||
{
|
||||
return Domain.Name;
|
||||
}
|
||||
|
||||
public uint GetCurrentMemoryDomainSize()
|
||||
{
|
||||
return (uint)Domain.Size;
|
||||
}
|
||||
|
||||
public bool UseMemoryDomain(string domain)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DomainList[domain] != null)
|
||||
{
|
||||
_currentMemoryDomain = DomainList[domain];
|
||||
return true;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Unable to find domain: {domain}");
|
||||
return false;
|
||||
}
|
||||
catch // Just in case
|
||||
{
|
||||
Console.WriteLine($"Unable to find domain: {domain}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public string HashRegion(long addr, int count, string domain = null)
|
||||
{
|
||||
var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)];
|
||||
|
||||
// checks
|
||||
if (addr < 0 || addr >= d.Size)
|
||||
{
|
||||
string error = $"Address {addr} is outside the bounds of domain {d.Name}";
|
||||
Console.WriteLine(error);
|
||||
throw new ArgumentOutOfRangeException(error);
|
||||
}
|
||||
if (addr + count > d.Size)
|
||||
{
|
||||
string error = $"Address {addr} + count {count} is outside the bounds of domain {d.Name}";
|
||||
Console.WriteLine(error);
|
||||
throw new ArgumentOutOfRangeException(error);
|
||||
}
|
||||
|
||||
byte[] data = new byte[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
data[i] = d.PeekByte(addr + i);
|
||||
}
|
||||
|
||||
using (var hasher = System.Security.Cryptography.SHA256.Create())
|
||||
{
|
||||
return hasher.ComputeHash(data).BytesToHexString();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Endian Handling
|
||||
|
||||
private int ReadSigned(long addr, int size, string domain = null)
|
||||
{
|
||||
if (_isBigEndian) return ReadSignedBig(addr, size, domain);
|
||||
else return ReadSignedLittle(addr, size, domain);
|
||||
}
|
||||
|
||||
private uint ReadUnsigned(long addr, int size, string domain = null)
|
||||
{
|
||||
if (_isBigEndian) return ReadUnsignedBig(addr, size, domain);
|
||||
else return ReadUnsignedLittle(addr, size, domain);
|
||||
}
|
||||
|
||||
private void WriteSigned(long addr, int value, int size, string domain = null)
|
||||
{
|
||||
if (_isBigEndian) WriteSignedBig(addr, value, size, domain);
|
||||
else WriteSignedLittle(addr, value, size, domain);
|
||||
}
|
||||
|
||||
private void WriteUnsigned(long addr, uint value, int size, string domain = null)
|
||||
{
|
||||
if (_isBigEndian) WriteUnsignedBig(addr, value, size, domain);
|
||||
else WriteUnsignedLittle(addr, value, size, domain);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Common Special and Legacy Methods
|
||||
|
||||
public uint ReadByte(long addr, string domain = null)
|
||||
{
|
||||
return ReadUnsignedByte(addr, domain);
|
||||
}
|
||||
|
||||
public void WriteByte(long addr, uint value, string domain = null)
|
||||
{
|
||||
WriteUnsignedByte(addr, value, domain);
|
||||
}
|
||||
|
||||
public new List<byte> ReadByteRange(long addr, int length, string domain = null)
|
||||
{
|
||||
return base.ReadByteRange(addr, length, domain);
|
||||
}
|
||||
|
||||
public new void WriteByteRange(long addr, List<byte> memoryblock, string domain = null)
|
||||
{
|
||||
base.WriteByteRange(addr, memoryblock, domain);
|
||||
}
|
||||
|
||||
public float ReadFloat(long addr, string domain = null)
|
||||
{
|
||||
return base.ReadFloat(addr, _isBigEndian, domain);
|
||||
}
|
||||
|
||||
public void WriteFloat(long addr, double value, string domain = null)
|
||||
{
|
||||
base.WriteFloat(addr, value, _isBigEndian, domain);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 1 Byte
|
||||
|
||||
public int ReadS8(long addr, string domain = null)
|
||||
{
|
||||
return (sbyte)ReadUnsignedByte(addr, domain);
|
||||
}
|
||||
|
||||
public uint ReadU8(long addr, string domain = null)
|
||||
{
|
||||
return (byte)ReadUnsignedByte(addr, domain);
|
||||
}
|
||||
|
||||
public void WriteS8(long addr, int value, string domain = null)
|
||||
{
|
||||
WriteSigned(addr, value, 1, domain);
|
||||
}
|
||||
|
||||
public void WriteU8(long addr, uint value, string domain = null)
|
||||
{
|
||||
WriteUnsignedByte(addr, value, domain);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 2 Byte
|
||||
public int ReadS16(long addr, string domain = null)
|
||||
{
|
||||
return (short)ReadSigned(addr, 2, domain);
|
||||
}
|
||||
|
||||
public void WriteS16(long addr, int value, string domain = null)
|
||||
{
|
||||
WriteSigned(addr, value, 2, domain);
|
||||
}
|
||||
|
||||
public uint ReadU16(long addr, string domain = null)
|
||||
{
|
||||
return (ushort)ReadUnsigned(addr, 2, domain);
|
||||
}
|
||||
|
||||
public void WriteU16(long addr, uint value, string domain = null)
|
||||
{
|
||||
WriteUnsigned(addr, value, 2, domain);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 3 Byte
|
||||
|
||||
public int ReadS24(long addr, string domain = null)
|
||||
{
|
||||
return ReadSigned(addr, 3, domain);
|
||||
}
|
||||
public void WriteS24(long addr, int value, string domain = null)
|
||||
{
|
||||
WriteSigned(addr, value, 3, domain);
|
||||
}
|
||||
|
||||
public uint ReadU24(long addr, string domain = null)
|
||||
{
|
||||
return ReadUnsigned(addr, 3, domain);
|
||||
}
|
||||
|
||||
public void WriteU24(long addr, uint value, string domain = null)
|
||||
{
|
||||
WriteUnsigned(addr, value, 3, domain);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 4 Byte
|
||||
|
||||
public int ReadS32(long addr, string domain = null)
|
||||
{
|
||||
return ReadSigned(addr, 4, domain);
|
||||
}
|
||||
|
||||
public void WriteS32(long addr, int value, string domain = null)
|
||||
{
|
||||
WriteSigned(addr, value, 4, domain);
|
||||
}
|
||||
|
||||
public uint ReadU32(long addr, string domain = null)
|
||||
{
|
||||
return ReadUnsigned(addr, 4, domain);
|
||||
}
|
||||
|
||||
public void WriteU32(long addr, uint value, string domain = null)
|
||||
{
|
||||
WriteUnsigned(addr, value, 4, domain);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for the Memory and MainMemory plugin libraries
|
||||
/// </summary>
|
||||
public abstract class MemApiBase : IExternalApi
|
||||
{
|
||||
[RequiredService]
|
||||
protected IEmulator Emulator { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
protected IMemoryDomains MemoryDomainCore { get; set; }
|
||||
|
||||
protected abstract MemoryDomain Domain { get; }
|
||||
|
||||
protected MemApiBase()
|
||||
{ }
|
||||
|
||||
protected IMemoryDomains DomainList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (MemoryDomainCore != null)
|
||||
{
|
||||
return MemoryDomainCore;
|
||||
}
|
||||
|
||||
var error = $"Error: {Emulator.Attributes().CoreName} does not implement memory domains";
|
||||
Console.WriteLine(error);
|
||||
throw new NotImplementedException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public string VerifyMemoryDomain(string domain)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DomainList[domain] == null)
|
||||
{
|
||||
Console.WriteLine($"Unable to find domain: {domain}, falling back to current");
|
||||
return Domain.Name;
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
catch // Just in case
|
||||
{
|
||||
Console.WriteLine($"Unable to find domain: {domain}, falling back to current");
|
||||
}
|
||||
|
||||
return Domain.Name;
|
||||
}
|
||||
|
||||
protected uint ReadUnsignedByte(long addr, string domain = null)
|
||||
{
|
||||
var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)];
|
||||
if (addr < d.Size)
|
||||
{
|
||||
return d.PeekByte(addr);
|
||||
}
|
||||
|
||||
Console.WriteLine("Warning: attempted read of " + addr + " outside the memory size of " + d.Size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected void WriteUnsignedByte(long addr, uint v, string domain = null)
|
||||
{
|
||||
var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)];
|
||||
if (d.CanPoke())
|
||||
{
|
||||
if (addr < d.Size)
|
||||
{
|
||||
d.PokeByte(addr, (byte)v);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Warning: attempted write to " + addr + " outside the memory size of " + d.Size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Error: the domain {d.Name} is not writable");
|
||||
}
|
||||
}
|
||||
|
||||
protected static int U2S(uint u, int size)
|
||||
{
|
||||
var s = (int)u;
|
||||
s <<= 8 * (4 - size);
|
||||
s >>= 8 * (4 - size);
|
||||
return s;
|
||||
}
|
||||
|
||||
protected int ReadSignedLittle(long addr, int size, string domain = null)
|
||||
{
|
||||
return U2S(ReadUnsignedLittle(addr, size, domain), size);
|
||||
}
|
||||
|
||||
protected uint ReadUnsignedLittle(long addr, int size, string domain = null)
|
||||
{
|
||||
uint v = 0;
|
||||
for (var i = 0; i < size; ++i)
|
||||
{
|
||||
v |= ReadUnsignedByte(addr + i, domain) << (8 * i);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
protected int ReadSignedBig(long addr, int size, string domain = null)
|
||||
{
|
||||
return U2S(ReadUnsignedBig(addr, size, domain), size);
|
||||
}
|
||||
|
||||
protected uint ReadUnsignedBig(long addr, int size, string domain = null)
|
||||
{
|
||||
uint v = 0;
|
||||
for (var i = 0; i < size; ++i)
|
||||
{
|
||||
v |= ReadUnsignedByte(addr + i, domain) << (8 * (size - 1 - i));
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
protected void WriteSignedLittle(long addr, int v, int size, string domain = null)
|
||||
{
|
||||
WriteUnsignedLittle(addr, (uint)v, size, domain);
|
||||
}
|
||||
|
||||
protected void WriteUnsignedLittle(long addr, uint v, int size, string domain = null)
|
||||
{
|
||||
for (var i = 0; i < size; ++i)
|
||||
{
|
||||
WriteUnsignedByte(addr + i, (v >> (8 * i)) & 0xFF, domain);
|
||||
}
|
||||
}
|
||||
|
||||
protected void WriteSignedBig(long addr, int v, int size, string domain = null)
|
||||
{
|
||||
WriteUnsignedBig(addr, (uint)v, size, domain);
|
||||
}
|
||||
|
||||
protected void WriteUnsignedBig(long addr, uint v, int size, string domain = null)
|
||||
{
|
||||
for (var i = 0; i < size; ++i)
|
||||
{
|
||||
WriteUnsignedByte(addr + i, (v >> (8 * (size - 1 - i))) & 0xFF, domain);
|
||||
}
|
||||
}
|
||||
|
||||
#region public Library implementations
|
||||
|
||||
protected List<byte> ReadByteRange(long addr, int length, string domain = null)
|
||||
{
|
||||
var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)];
|
||||
var lastAddr = length + addr;
|
||||
var list = new List<byte>();
|
||||
for (; addr <= lastAddr; addr++)
|
||||
{
|
||||
if (addr < d.Size)
|
||||
list.Add(d.PeekByte(addr));
|
||||
else {
|
||||
Console.WriteLine("Warning: Attempted read " + addr + " outside memory domain size of " + d.Size + " in readbyterange()");
|
||||
list.Add(0);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
protected void WriteByteRange(long addr, List<byte> memoryblock, string domain = null)
|
||||
{
|
||||
var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)];
|
||||
if (d.CanPoke())
|
||||
{
|
||||
for (var i = 0; i < memoryblock.Count; i++)
|
||||
{
|
||||
if (addr < d.Size)
|
||||
{
|
||||
d.PokeByte(addr++, memoryblock[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Warning: Attempted write " + addr + " outside memory domain size of " + d.Size + " in writebyterange()");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Error: the domain {d.Name} is not writable");
|
||||
}
|
||||
}
|
||||
|
||||
protected float ReadFloat(long addr, bool bigendian, string domain = null)
|
||||
{
|
||||
var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)];
|
||||
if (addr < d.Size)
|
||||
{
|
||||
var val = d.PeekUint(addr, bigendian);
|
||||
var bytes = BitConverter.GetBytes(val);
|
||||
return BitConverter.ToSingle(bytes, 0);
|
||||
}
|
||||
|
||||
Console.WriteLine("Warning: Attempted read " + addr + " outside memory size of " + d.Size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected void WriteFloat(long addr, double value, bool bigendian, string domain = null)
|
||||
{
|
||||
var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)];
|
||||
if (d.CanPoke())
|
||||
{
|
||||
if (addr < d.Size)
|
||||
{
|
||||
var dv = (float)value;
|
||||
var bytes = BitConverter.GetBytes(dv);
|
||||
var v = BitConverter.ToUInt32(bytes, 0);
|
||||
d.PokeUint(addr, v, bigendian);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Warning: Attempted write " + addr + " outside memory size of " + d.Size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Error: the domain {Domain.Name} is not writable");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public sealed class MemEventsApi : IMemEvents
|
||||
{
|
||||
[RequiredService]
|
||||
private IDebuggable DebuggableCore { get; set; }
|
||||
|
||||
public MemEventsApi () : base()
|
||||
{ }
|
||||
|
||||
public void AddReadCallback(Action cb, uint address, string domain)
|
||||
{
|
||||
if (DebuggableCore.MemoryCallbacksAvailable())
|
||||
{
|
||||
DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Read, "Plugin Hook", cb, address, null));
|
||||
}
|
||||
}
|
||||
public void AddWriteCallback(Action cb, uint address, string domain)
|
||||
{
|
||||
if (DebuggableCore.MemoryCallbacksAvailable())
|
||||
{
|
||||
DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Write, "Plugin Hook", cb, address, null));
|
||||
}
|
||||
}
|
||||
public void AddExecCallback(Action cb, uint address, string domain)
|
||||
{
|
||||
if (DebuggableCore.MemoryCallbacksAvailable() && DebuggableCore.MemoryCallbacks.ExecuteCallbacksAvailable)
|
||||
{
|
||||
DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Execute, "Plugin Hook", cb, address, null));
|
||||
}
|
||||
}
|
||||
public void RemoveMemoryCallback(Action cb)
|
||||
{
|
||||
if (DebuggableCore.MemoryCallbacksAvailable())
|
||||
{
|
||||
DebuggableCore.MemoryCallbacks.Remove(cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public sealed class MemorySaveStateApi : IMemorySaveState
|
||||
{
|
||||
public MemorySaveStateApi()
|
||||
{ }
|
||||
|
||||
[RequiredService]
|
||||
private IStatable StatableCore { get; set; }
|
||||
|
||||
private readonly Dictionary<Guid, byte[]> _memorySavestates = new Dictionary<Guid, byte[]>();
|
||||
|
||||
public string SaveCoreStateToMemory()
|
||||
{
|
||||
var guid = Guid.NewGuid();
|
||||
var bytes = (byte[])StatableCore.SaveStateBinary().Clone();
|
||||
|
||||
_memorySavestates.Add(guid, bytes);
|
||||
|
||||
return guid.ToString();
|
||||
}
|
||||
|
||||
public void LoadCoreStateFromMemory(string identifier)
|
||||
{
|
||||
var guid = new Guid(identifier);
|
||||
|
||||
try
|
||||
{
|
||||
var state = _memorySavestates[guid];
|
||||
|
||||
using (var ms = new MemoryStream(state))
|
||||
using (var br = new BinaryReader(ms))
|
||||
{
|
||||
StatableCore.LoadStateBinary(br);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Unable to find the given savestate in memory");
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteState(string identifier)
|
||||
{
|
||||
var guid = new Guid(identifier);
|
||||
_memorySavestates.Remove(guid);
|
||||
}
|
||||
|
||||
public void ClearInMemoryStates()
|
||||
{
|
||||
_memorySavestates.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,288 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public sealed class MovieApi : IMovie
|
||||
{
|
||||
private static class MoviePluginStatic
|
||||
{
|
||||
public static string Filename()
|
||||
{
|
||||
return Global.MovieSession.Movie.Filename;
|
||||
}
|
||||
|
||||
public static bool GetReadOnly()
|
||||
{
|
||||
return Global.MovieSession.ReadOnly;
|
||||
}
|
||||
|
||||
public static ulong GetRerecordCount()
|
||||
{
|
||||
return Global.MovieSession.Movie.Rerecords;
|
||||
}
|
||||
|
||||
public static bool GetRerecordCounting()
|
||||
{
|
||||
return Global.MovieSession.Movie.IsCountingRerecords;
|
||||
}
|
||||
|
||||
public static bool IsLoaded()
|
||||
{
|
||||
return Global.MovieSession.Movie.IsActive;
|
||||
}
|
||||
|
||||
public static double Length()
|
||||
{
|
||||
return Global.MovieSession.Movie.FrameCount;
|
||||
}
|
||||
|
||||
public static string Mode()
|
||||
{
|
||||
if (Global.MovieSession.Movie.IsFinished)
|
||||
{
|
||||
return "FINISHED";
|
||||
}
|
||||
|
||||
if (Global.MovieSession.Movie.IsPlaying)
|
||||
{
|
||||
return "PLAY";
|
||||
}
|
||||
|
||||
if (Global.MovieSession.Movie.IsRecording)
|
||||
{
|
||||
return "RECORD";
|
||||
}
|
||||
|
||||
return "INACTIVE";
|
||||
}
|
||||
|
||||
public static void SetReadOnly(bool readOnly)
|
||||
{
|
||||
Global.MovieSession.ReadOnly = readOnly;
|
||||
}
|
||||
|
||||
public static void SetRerecordCount(double count)
|
||||
{
|
||||
// Lua numbers are always double, integer precision holds up
|
||||
// to 53 bits, so throw an error if it's bigger than that.
|
||||
const double PrecisionLimit = 9007199254740992d;
|
||||
|
||||
if (count > PrecisionLimit)
|
||||
{
|
||||
throw new Exception("Rerecord count exceeds Lua integer precision.");
|
||||
}
|
||||
|
||||
Global.MovieSession.Movie.Rerecords = (ulong)count;
|
||||
}
|
||||
|
||||
public static void SetRerecordCounting(bool counting)
|
||||
{
|
||||
Global.MovieSession.Movie.IsCountingRerecords = counting;
|
||||
}
|
||||
|
||||
public static void Stop()
|
||||
{
|
||||
Global.MovieSession.Movie.Stop();
|
||||
}
|
||||
|
||||
public static double GetFps()
|
||||
{
|
||||
if (Global.MovieSession.Movie.IsActive)
|
||||
{
|
||||
var movie = Global.MovieSession.Movie;
|
||||
var system = movie.HeaderEntries[HeaderKeys.PLATFORM];
|
||||
var pal = movie.HeaderEntries.ContainsKey(HeaderKeys.PAL) &&
|
||||
movie.HeaderEntries[HeaderKeys.PAL] == "1";
|
||||
|
||||
return new PlatformFrameRates()[system, pal];
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
}
|
||||
public MovieApi()
|
||||
{ }
|
||||
|
||||
public bool StartsFromSavestate()
|
||||
{
|
||||
return Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.StartsFromSavestate;
|
||||
}
|
||||
|
||||
public bool StartsFromSaveram()
|
||||
{
|
||||
return Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.StartsFromSaveRam;
|
||||
}
|
||||
|
||||
public Dictionary<string, dynamic> GetInput(int frame)
|
||||
{
|
||||
if (!Global.MovieSession.Movie.IsActive)
|
||||
{
|
||||
Console.WriteLine("No movie loaded");
|
||||
return null;
|
||||
}
|
||||
|
||||
var input = new Dictionary<string, dynamic>();
|
||||
var adapter = Global.MovieSession.Movie.GetInputState(frame);
|
||||
|
||||
if (adapter == null)
|
||||
{
|
||||
Console.WriteLine("Can't get input of the last frame of the movie. Use the previous frame");
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var button in adapter.Definition.BoolButtons)
|
||||
{
|
||||
input[button] = adapter.IsPressed(button);
|
||||
}
|
||||
|
||||
foreach (var button in adapter.Definition.FloatControls)
|
||||
{
|
||||
input[button] = adapter.GetFloat(button);
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
public string GetInputAsMnemonic(int frame)
|
||||
{
|
||||
if (Global.MovieSession.Movie.IsActive && frame < Global.MovieSession.Movie.InputLogLength)
|
||||
{
|
||||
var lg = Global.MovieSession.LogGeneratorInstance();
|
||||
lg.SetSource(Global.MovieSession.Movie.GetInputState(frame));
|
||||
return lg.GenerateLogEntry();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public void Save(string filename = "")
|
||||
{
|
||||
if (!Global.MovieSession.Movie.IsActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(filename))
|
||||
{
|
||||
filename += "." + Global.MovieSession.Movie.PreferredExtension;
|
||||
var test = new FileInfo(filename);
|
||||
if (test.Exists)
|
||||
{
|
||||
Console.WriteLine($"File {filename} already exists, will not overwrite");
|
||||
return;
|
||||
}
|
||||
|
||||
Global.MovieSession.Movie.Filename = filename;
|
||||
}
|
||||
|
||||
Global.MovieSession.Movie.Save();
|
||||
}
|
||||
|
||||
public Dictionary<string,string> GetHeader()
|
||||
{
|
||||
var table = new Dictionary<string,string>();
|
||||
if (Global.MovieSession.Movie.IsActive)
|
||||
{
|
||||
foreach (var kvp in Global.MovieSession.Movie.HeaderEntries)
|
||||
{
|
||||
table[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
public List<string> GetComments()
|
||||
{
|
||||
var list = new List<string>(Global.MovieSession.Movie.Comments.Count);
|
||||
if (Global.MovieSession.Movie.IsActive)
|
||||
{
|
||||
for (int i = 0; i < Global.MovieSession.Movie.Comments.Count; i++)
|
||||
{
|
||||
list[i] = Global.MovieSession.Movie.Comments[i];
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<string> GetSubtitles()
|
||||
{
|
||||
var list = new List<string>(Global.MovieSession.Movie.Subtitles.Count);
|
||||
if (Global.MovieSession.Movie.IsActive)
|
||||
{
|
||||
for (int i = 0; i < Global.MovieSession.Movie.Subtitles.Count; i++)
|
||||
{
|
||||
list[i] = Global.MovieSession.Movie.Subtitles[i].ToString();
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public string Filename()
|
||||
{
|
||||
return MoviePluginStatic.Filename();
|
||||
}
|
||||
|
||||
public bool GetReadOnly()
|
||||
{
|
||||
return MoviePluginStatic.GetReadOnly();
|
||||
}
|
||||
|
||||
public ulong GetRerecordCount()
|
||||
{
|
||||
return MoviePluginStatic.GetRerecordCount();
|
||||
}
|
||||
|
||||
public bool GetRerecordCounting()
|
||||
{
|
||||
return MoviePluginStatic.GetRerecordCounting();
|
||||
}
|
||||
|
||||
public bool IsLoaded()
|
||||
{
|
||||
return MoviePluginStatic.IsLoaded();
|
||||
}
|
||||
|
||||
public double Length()
|
||||
{
|
||||
return MoviePluginStatic.Length();
|
||||
}
|
||||
|
||||
public string Mode()
|
||||
{
|
||||
return MoviePluginStatic.Mode();
|
||||
}
|
||||
|
||||
public void SetReadOnly(bool readOnly)
|
||||
{
|
||||
MoviePluginStatic.SetReadOnly(readOnly);
|
||||
}
|
||||
|
||||
public void SetRerecordCount(double count)
|
||||
{
|
||||
MoviePluginStatic.SetRerecordCount(count);
|
||||
}
|
||||
|
||||
public void SetRerecordCounting(bool counting)
|
||||
{
|
||||
MoviePluginStatic.SetRerecordCounting(counting);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
MoviePluginStatic.Stop();
|
||||
}
|
||||
|
||||
public double GetFps()
|
||||
{
|
||||
return MoviePluginStatic.GetFps();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public abstract class PluginBase : IPlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class from which all
|
||||
/// plugins will be derived
|
||||
///
|
||||
/// Actual plugins should implement
|
||||
/// one of the below callback methods
|
||||
/// or register memory callbacks in
|
||||
/// their Init function.
|
||||
/// </summary>
|
||||
protected IApiContainer _api;
|
||||
|
||||
public PluginBase() { }
|
||||
|
||||
public abstract string Name { get; }
|
||||
public abstract string Description { get; }
|
||||
|
||||
public bool Enabled => Running;
|
||||
public bool Paused => !Running;
|
||||
|
||||
public bool Running { get; set; }
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Running = false;
|
||||
}
|
||||
|
||||
public void Toggle()
|
||||
{
|
||||
Running = !Running;
|
||||
}
|
||||
|
||||
public virtual void PreFrameCallback() { }
|
||||
public virtual void PostFrameCallback() { }
|
||||
public virtual void SaveStateCallback(string name) { }
|
||||
public virtual void LoadStateCallback(string name) { }
|
||||
public virtual void InputPollCallback() { }
|
||||
public virtual void ExitCallback() { }
|
||||
public virtual void Init (IApiContainer api)
|
||||
{
|
||||
_api = api;
|
||||
Running = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data.SQLite;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public sealed class SqlApi : ISql
|
||||
{
|
||||
public SqlApi() : base()
|
||||
{ }
|
||||
|
||||
SQLiteConnection m_dbConnection;
|
||||
string connectionString;
|
||||
|
||||
public string CreateDatabase(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
SQLiteConnection.CreateFile(name);
|
||||
return "Database Created Successfully";
|
||||
}
|
||||
catch (SQLiteException sqlEX)
|
||||
{
|
||||
return sqlEX.Message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string OpenDatabase(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
SQLiteConnectionStringBuilder connBuilder = new SQLiteConnectionStringBuilder();
|
||||
connBuilder.DataSource = name;
|
||||
connBuilder.Version = 3; //SQLite version
|
||||
connBuilder.JournalMode = SQLiteJournalModeEnum.Wal; //Allows for reads and writes to happen at the same time
|
||||
connBuilder.DefaultIsolationLevel = System.Data.IsolationLevel.ReadCommitted; //This only helps make the database lock left. May be pointless now
|
||||
connBuilder.SyncMode = SynchronizationModes.Off; //This shortens the delay for do synchronous calls.
|
||||
m_dbConnection = new SQLiteConnection(connBuilder.ToString());
|
||||
connectionString = connBuilder.ToString();
|
||||
m_dbConnection.Open();
|
||||
m_dbConnection.Close();
|
||||
return "Database Opened Successfully";
|
||||
}
|
||||
catch (SQLiteException sqlEX)
|
||||
{
|
||||
return sqlEX.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public string WriteCommand(string query = "")
|
||||
{
|
||||
if (query == "")
|
||||
{
|
||||
return "query is empty";
|
||||
}
|
||||
try
|
||||
{
|
||||
m_dbConnection.Open();
|
||||
string sql = query;
|
||||
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
|
||||
command.ExecuteNonQuery();
|
||||
m_dbConnection.Close();
|
||||
|
||||
return "Command ran successfully";
|
||||
|
||||
}
|
||||
catch (NullReferenceException nullEX)
|
||||
{
|
||||
return "Database not open.";
|
||||
}
|
||||
catch (SQLiteException sqlEX)
|
||||
{
|
||||
m_dbConnection.Close();
|
||||
return sqlEX.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public dynamic ReadCommand(string query = "")
|
||||
{
|
||||
if (query == "")
|
||||
{
|
||||
return "query is empty";
|
||||
}
|
||||
try
|
||||
{
|
||||
var table = new Dictionary<string, object>();
|
||||
m_dbConnection.Open();
|
||||
string sql = "PRAGMA read_uncommitted =1;" + query;
|
||||
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
|
||||
SQLiteDataReader reader = command.ExecuteReader();
|
||||
bool rows = reader.HasRows;
|
||||
long rowCount = 0;
|
||||
var columns = new List<string>();
|
||||
for (int i = 0; i < reader.FieldCount; ++i) //Add all column names into list
|
||||
{
|
||||
columns.Add(reader.GetName(i));
|
||||
}
|
||||
while (reader.Read())
|
||||
{
|
||||
for (int i = 0; i < reader.FieldCount; ++i)
|
||||
{
|
||||
table[columns[i] + " " + rowCount.ToString()] = reader.GetValue(i);
|
||||
}
|
||||
rowCount += 1;
|
||||
}
|
||||
reader.Close();
|
||||
m_dbConnection.Close();
|
||||
if (rows == false)
|
||||
{
|
||||
return "No rows found";
|
||||
}
|
||||
|
||||
return table;
|
||||
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
return "Database not opened.";
|
||||
}
|
||||
catch (SQLiteException sqlEX)
|
||||
{
|
||||
m_dbConnection.Close();
|
||||
return sqlEX.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public sealed class UserDataApi : IUserData
|
||||
{
|
||||
public UserDataApi() : base()
|
||||
{ }
|
||||
|
||||
public void Set(string name, object value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
var t = value.GetType();
|
||||
if (!t.IsPrimitive && t != typeof(string))
|
||||
{
|
||||
throw new InvalidOperationException("Invalid type for userdata");
|
||||
}
|
||||
}
|
||||
|
||||
Global.UserBag[name] = value;
|
||||
}
|
||||
|
||||
public object Get(string key)
|
||||
{
|
||||
if (Global.UserBag.ContainsKey(key))
|
||||
{
|
||||
return Global.UserBag[key];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Global.UserBag.Clear();
|
||||
}
|
||||
|
||||
public bool Remove(string key)
|
||||
{
|
||||
return Global.UserBag.Remove(key);
|
||||
}
|
||||
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return Global.UserBag.ContainsKey(key);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common.ReflectionExtensions;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// injects Apis into other classes
|
||||
/// </summary>
|
||||
public static class ApiInjector
|
||||
{
|
||||
/// <summary>
|
||||
/// clears all Apis from a target
|
||||
/// </summary>
|
||||
public static void ClearApis(object target)
|
||||
{
|
||||
Type targetType = target.GetType();
|
||||
object[] tmp = new object[1];
|
||||
|
||||
foreach (var propinfo in
|
||||
targetType.GetPropertiesWithAttrib(typeof(RequiredApiAttribute))
|
||||
.Concat(targetType.GetPropertiesWithAttrib(typeof(OptionalApiAttribute))))
|
||||
{
|
||||
propinfo.GetSetMethod(true).Invoke(target, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Feeds the target its required Apis.
|
||||
/// </summary>
|
||||
/// <returns>false if update failed</returns>
|
||||
public static bool UpdateApis(IExternalApiProvider source, object target)
|
||||
{
|
||||
Type targetType = target.GetType();
|
||||
object[] tmp = new object[1];
|
||||
|
||||
foreach (var propinfo in targetType.GetPropertiesWithAttrib(typeof(RequiredApiAttribute)))
|
||||
{
|
||||
tmp[0] = source.GetApi(propinfo.PropertyType);
|
||||
if (tmp[0] == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
propinfo.GetSetMethod(true).Invoke(target, tmp);
|
||||
}
|
||||
|
||||
foreach (var propinfo in targetType.GetPropertiesWithAttrib(typeof(OptionalApiAttribute)))
|
||||
{
|
||||
tmp[0] = source.GetApi(propinfo.PropertyType);
|
||||
propinfo.GetSetMethod(true).Invoke(target, tmp);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a target is available, considering its dependencies
|
||||
/// and the Apis provided by the emulator core.
|
||||
/// </summary>
|
||||
public static bool IsAvailable(IExternalApiProvider source, Type targetType)
|
||||
{
|
||||
return targetType.GetPropertiesWithAttrib(typeof(RequiredApiAttribute))
|
||||
.Select(pi => pi.PropertyType)
|
||||
.All(source.HasApi);
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class RequiredApiAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class OptionalApiAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// A generic implementation of IExternalApi provider that provides
|
||||
/// this functionality to any core.
|
||||
/// The provider will scan an IExternal and register all IExternalApis
|
||||
/// that the core object itself implements. In addition it provides
|
||||
/// a Register() method to allow the core to pass in any additional Apis
|
||||
/// </summary>
|
||||
/// <seealso cref="IExternalApiProvider"/>
|
||||
public class BasicApiProvider : IExternalApiProvider
|
||||
{
|
||||
private readonly Dictionary<Type, IExternalApi> _Apis = new Dictionary<Type, IExternalApi>();
|
||||
|
||||
public BasicApiProvider(IApiContainer container)
|
||||
{
|
||||
// simplified logic here doesn't scan for possible Apis; just adds what it knows is implemented by the PluginApi
|
||||
// this removes the possibility of automagically picking up a Api 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
|
||||
// container doesn't implement directly needs to be added with Register()
|
||||
// this also fully allows apis that are not IExternalApi
|
||||
var libs = container.Libraries;
|
||||
|
||||
_Apis = libs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the client can call this to register an additional Api
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The <seealso cref="IExternalApi"/> to register</typeparam>
|
||||
public void Register<T>(T api)
|
||||
where T : IExternalApi
|
||||
{
|
||||
if (api == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(api));
|
||||
}
|
||||
|
||||
_Apis[typeof(T)] = api;
|
||||
}
|
||||
|
||||
public T GetApi<T>()
|
||||
where T : IExternalApi
|
||||
{
|
||||
return (T)GetApi(typeof(T));
|
||||
}
|
||||
|
||||
public object GetApi(Type t)
|
||||
{
|
||||
IExternalApi Api;
|
||||
KeyValuePair<Type, IExternalApi>[] k = _Apis.Where(kvp => t.IsAssignableFrom(kvp.Key)).ToArray();
|
||||
if (k.Length > 0)
|
||||
{
|
||||
return k[0].Value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool HasApi<T>()
|
||||
where T : IExternalApi
|
||||
{
|
||||
return HasApi(typeof(T));
|
||||
}
|
||||
|
||||
public bool HasApi(Type t)
|
||||
{
|
||||
return _Apis.ContainsKey(t);
|
||||
}
|
||||
|
||||
public IEnumerable<Type> AvailableApis
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Apis.Select(d => d.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ using System.Reflection;
|
|||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
|
||||
using BizHawk.Emulation.Cores.PCEngine;
|
||||
using BizHawk.Emulation.Cores.Sega.MasterSystem;
|
||||
|
@ -21,6 +22,9 @@ namespace BizHawk.Client.ApiHawk
|
|||
{
|
||||
#region Fields
|
||||
|
||||
private static IEmulator Emulator;
|
||||
private static IVideoProvider VideoProvider;
|
||||
|
||||
private static readonly Assembly clientAssembly;
|
||||
private static readonly object clientMainFormInstance;
|
||||
private static readonly Type mainFormClass;
|
||||
|
@ -68,24 +72,57 @@ namespace BizHawk.Client.ApiHawk
|
|||
mainFormClass = clientAssembly.GetType("BizHawk.Client.EmuHawk.MainForm");
|
||||
}
|
||||
|
||||
public static void UpdateEmulatorAndVP(IEmulator emu = null)
|
||||
{
|
||||
Emulator = emu;
|
||||
VideoProvider = Emulation.Common.IEmulatorExtensions.Extensions.AsVideoProviderOrDefault(emu);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
#region Helpers
|
||||
|
||||
private static void InvokeMainFormMethod(string name, dynamic[] paramList = null)
|
||||
{
|
||||
List<Type> typeList = new List<Type>();
|
||||
MethodInfo method;
|
||||
if (paramList != null)
|
||||
{
|
||||
foreach (var obj in paramList)
|
||||
{
|
||||
typeList.Add(obj.GetType());
|
||||
}
|
||||
method = mainFormClass.GetMethod(name, typeList.ToArray());
|
||||
}
|
||||
else method = mainFormClass.GetMethod(name);
|
||||
method.Invoke(clientMainFormInstance, paramList);
|
||||
}
|
||||
|
||||
private static object GetMainFormField(string name)
|
||||
{
|
||||
return mainFormClass.GetField(name);
|
||||
}
|
||||
|
||||
private static void SetMainFormField(string name, object value)
|
||||
{
|
||||
mainFormClass.GetField(name).SetValue(clientMainFormInstance, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
/// <summary>
|
||||
/// THE FrameAdvance stuff
|
||||
/// </summary>
|
||||
public static void DoFrameAdvance()
|
||||
{
|
||||
MethodInfo method = mainFormClass.GetMethod("FrameAdvance");
|
||||
method.Invoke(clientMainFormInstance, null);
|
||||
InvokeMainFormMethod("FrameAdvance", null);
|
||||
|
||||
method = mainFormClass.GetMethod("StepRunLoop_Throttle", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
method.Invoke(clientMainFormInstance, null);
|
||||
InvokeMainFormMethod("StepRunLoop_Throttle", null);
|
||||
|
||||
method = mainFormClass.GetMethod("Render", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
method.Invoke(clientMainFormInstance, null);
|
||||
InvokeMainFormMethod("Render", null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -124,8 +161,7 @@ namespace BizHawk.Client.ApiHawk
|
|||
/// <param name="name">Savetate friendly name</param>
|
||||
public static void LoadState(string name)
|
||||
{
|
||||
MethodInfo method = mainFormClass.GetMethod("LoadState");
|
||||
method.Invoke(clientMainFormInstance, new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), string.Format("{0}.{1}", name, "State")), name, false, false });
|
||||
InvokeMainFormMethod("LoadState", new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), string.Format("{0}.{1}", name, "State")), name, false, false });
|
||||
}
|
||||
|
||||
|
||||
|
@ -194,12 +230,11 @@ namespace BizHawk.Client.ApiHawk
|
|||
/// <summary>
|
||||
/// Raise when a rom is successfully Loaded
|
||||
/// </summary>
|
||||
public static void OnRomLoaded()
|
||||
public static void OnRomLoaded(IEmulator emu)
|
||||
{
|
||||
if (RomLoaded != null)
|
||||
{
|
||||
RomLoaded(null, EventArgs.Empty);
|
||||
}
|
||||
Emulator = emu;
|
||||
VideoProvider = Emulation.Common.IEmulatorExtensions.Extensions.AsVideoProviderOrDefault(emu);
|
||||
RomLoaded?.Invoke(null, EventArgs.Empty);
|
||||
|
||||
allJoypads = new List<Joypad>(RunningSystem.MaxControllers);
|
||||
for (int i = 1; i <= RunningSystem.MaxControllers; i++)
|
||||
|
@ -215,10 +250,55 @@ namespace BizHawk.Client.ApiHawk
|
|||
/// <param name="name">Savetate friendly name</param>
|
||||
public static void SaveState(string name)
|
||||
{
|
||||
MethodInfo method = mainFormClass.GetMethod("SaveState");
|
||||
method.Invoke(clientMainFormInstance, new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), string.Format("{0}.{1}", name, "State")), name, false });
|
||||
InvokeMainFormMethod("SaveState", new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), string.Format("{0}.{1}", name, "State")), name, false });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements
|
||||
/// </summary>
|
||||
/// <param name="left">Left padding</param>
|
||||
/// <param name="top">Top padding</param>
|
||||
/// <param name="right">Right padding</param>
|
||||
/// <param name="bottom">Bottom padding</param>
|
||||
public static void SetGameExtraPadding(int left, int top, int right, int bottom)
|
||||
{
|
||||
FieldInfo f = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin").GetField("DisplayManager");
|
||||
object displayManager = f.GetValue(null);
|
||||
f = f.FieldType.GetField("GameExtraPadding");
|
||||
f.SetValue(displayManager, new Padding(left, top, right, bottom));
|
||||
|
||||
InvokeMainFormMethod("FrameBufferResized");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements
|
||||
/// </summary>
|
||||
/// <param name="left">Left padding</param>
|
||||
public static void SetGameExtraPadding(int left)
|
||||
{
|
||||
SetGameExtraPadding(left, 0, 0, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements
|
||||
/// </summary>
|
||||
/// <param name="left">Left padding</param>
|
||||
/// <param name="top">Top padding</param>
|
||||
public static void SetGameExtraPadding(int left, int top)
|
||||
{
|
||||
SetGameExtraPadding(left, top, 0, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements
|
||||
/// </summary>
|
||||
/// <param name="left">Left padding</param>
|
||||
/// <param name="top">Top padding</param>
|
||||
/// <param name="right">Right padding</param>
|
||||
public static void SetGameExtraPadding(int left, int top, int right)
|
||||
{
|
||||
SetGameExtraPadding(left, top, right, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements
|
||||
|
@ -234,8 +314,7 @@ namespace BizHawk.Client.ApiHawk
|
|||
f = f.FieldType.GetField("ClientExtraPadding");
|
||||
f.SetValue(displayManager, new Padding(left, top, right, bottom));
|
||||
|
||||
MethodInfo resize = mainFormClass.GetMethod("FrameBufferResized");
|
||||
resize.Invoke(clientMainFormInstance, null);
|
||||
InvokeMainFormMethod("FrameBufferResized");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -268,7 +347,6 @@ namespace BizHawk.Client.ApiHawk
|
|||
SetExtraPadding(left, top, right, 0);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set inputs in specified <see cref="Joypad"/> to specified player
|
||||
/// </summary>
|
||||
|
@ -327,8 +405,7 @@ namespace BizHawk.Client.ApiHawk
|
|||
/// </summary>
|
||||
public static void UnpauseEmulation()
|
||||
{
|
||||
MethodInfo method = mainFormClass.GetMethod("UnpauseEmulator");
|
||||
method.Invoke(clientMainFormInstance, null);
|
||||
InvokeMainFormMethod("UnpauseEmulator", null);
|
||||
}
|
||||
#endregion Public
|
||||
|
||||
|
@ -375,6 +452,275 @@ namespace BizHawk.Client.ApiHawk
|
|||
}
|
||||
}
|
||||
|
||||
public static void CloseEmulator()
|
||||
{
|
||||
InvokeMainFormMethod("CloseEmulator");
|
||||
}
|
||||
|
||||
public static void CloseEmulatorWithCode(int exitCode)
|
||||
{
|
||||
InvokeMainFormMethod("CloseEmulator", new object[] {exitCode});
|
||||
}
|
||||
|
||||
public static int BorderHeight()
|
||||
{
|
||||
var point = new System.Drawing.Point(0, 0);
|
||||
Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin");
|
||||
FieldInfo f = t.GetField("DisplayManager");
|
||||
object displayManager = f.GetValue(null);
|
||||
MethodInfo m = t.GetMethod("TransFormPoint");
|
||||
point = (System.Drawing.Point) m.Invoke(displayManager, new object[] { point });
|
||||
return point.Y;
|
||||
}
|
||||
|
||||
public static int BorderWidth()
|
||||
{
|
||||
var point = new System.Drawing.Point(0, 0);
|
||||
Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin");
|
||||
FieldInfo f = t.GetField("DisplayManager");
|
||||
object displayManager = f.GetValue(null);
|
||||
MethodInfo m = t.GetMethod("TransFormPoint");
|
||||
point = (System.Drawing.Point)m.Invoke(displayManager, new object[] { point });
|
||||
return point.X;
|
||||
}
|
||||
|
||||
public static int BufferHeight()
|
||||
{
|
||||
return VideoProvider.BufferHeight;
|
||||
}
|
||||
|
||||
public static int BufferWidth()
|
||||
{
|
||||
return VideoProvider.BufferWidth;
|
||||
}
|
||||
|
||||
public static void ClearAutohold()
|
||||
{
|
||||
InvokeMainFormMethod("ClearHolds");
|
||||
}
|
||||
|
||||
public static void CloseRom()
|
||||
{
|
||||
InvokeMainFormMethod("CloseRom");
|
||||
}
|
||||
|
||||
public static void DisplayMessages(bool value)
|
||||
{
|
||||
Global.Config.DisplayMessages = value;
|
||||
}
|
||||
|
||||
public static void EnableRewind(bool enabled)
|
||||
{
|
||||
InvokeMainFormMethod("EnableRewind", new object[] {enabled});
|
||||
}
|
||||
|
||||
public static void FrameSkip(int numFrames)
|
||||
{
|
||||
if (numFrames > 0)
|
||||
{
|
||||
Global.Config.FrameSkip = numFrames;
|
||||
InvokeMainFormMethod("FrameSkipMessage");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Invalid frame skip value");
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetTargetScanlineIntensity()
|
||||
{
|
||||
return Global.Config.TargetScanlineFilterIntensity;
|
||||
}
|
||||
|
||||
public static int GetWindowSize()
|
||||
{
|
||||
return Global.Config.TargetZoomFactors[Emulator.SystemId];
|
||||
}
|
||||
|
||||
public static void SetSoundOn(bool enable)
|
||||
{
|
||||
Global.Config.SoundEnabled = enable;
|
||||
}
|
||||
|
||||
public static bool GetSoundOn()
|
||||
{
|
||||
return Global.Config.SoundEnabled;
|
||||
}
|
||||
|
||||
public static bool IsPaused()
|
||||
{
|
||||
return (bool) GetMainFormField("EmulatorPaused");
|
||||
}
|
||||
|
||||
public static bool IsTurbo()
|
||||
{
|
||||
return (bool)GetMainFormField("IsTurboing");
|
||||
}
|
||||
|
||||
public static bool IsSeeking()
|
||||
{
|
||||
return (bool)GetMainFormField("IsSeeking");
|
||||
}
|
||||
|
||||
public static void OpenRom(string path)
|
||||
{
|
||||
var ioa = OpenAdvancedSerializer.ParseWithLegacy(path);
|
||||
Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin.MainForm.LoadRomArgs");
|
||||
object o = Activator.CreateInstance(t);
|
||||
t.GetField("OpenAdvanced").SetValue(o, ioa);
|
||||
|
||||
InvokeMainFormMethod("LoadRom", new object[] {path, o});
|
||||
}
|
||||
|
||||
public static void Pause()
|
||||
{
|
||||
InvokeMainFormMethod("PauseEmulator");
|
||||
}
|
||||
|
||||
public static void PauseAv()
|
||||
{
|
||||
SetMainFormField("PauseAvi", true);
|
||||
}
|
||||
|
||||
public static void RebootCore()
|
||||
{
|
||||
InvokeMainFormMethod("RebootCore");
|
||||
}
|
||||
|
||||
public static void SaveRam()
|
||||
{
|
||||
InvokeMainFormMethod("FlushSaveRAM");
|
||||
}
|
||||
|
||||
public static int ScreenHeight()
|
||||
{
|
||||
Type t = GetMainFormField("PresentationPanel").GetType();
|
||||
object o = GetMainFormField("PresentationPanel");
|
||||
o = t.GetField("NativeSize").GetValue(o);
|
||||
t = t.GetField("NativeSize").GetType();
|
||||
|
||||
return (int) t.GetField("Height").GetValue(o);
|
||||
}
|
||||
|
||||
public static void Screenshot(string path = null)
|
||||
{
|
||||
if (path == null)
|
||||
{
|
||||
InvokeMainFormMethod("TakeScreenshot");
|
||||
}
|
||||
else
|
||||
{
|
||||
InvokeMainFormMethod("TakeScreenshot", new object[] {path});
|
||||
}
|
||||
}
|
||||
|
||||
public static void ScreenshotToClipboard()
|
||||
{
|
||||
InvokeMainFormMethod("TakeScreenshotToClipboard");
|
||||
}
|
||||
|
||||
public static void SetTargetScanlineIntensity(int val)
|
||||
{
|
||||
Global.Config.TargetScanlineFilterIntensity = val;
|
||||
}
|
||||
|
||||
public static void SetScreenshotOSD(bool value)
|
||||
{
|
||||
Global.Config.Screenshot_CaptureOSD = value;
|
||||
}
|
||||
|
||||
public static int ScreenWidth()
|
||||
{
|
||||
Type t = GetMainFormField("PresentationPanel").GetType();
|
||||
object o = GetMainFormField("PresentationPanel");
|
||||
o = t.GetField("NativeSize").GetValue(o);
|
||||
t = t.GetField("NativeSize").GetType();
|
||||
|
||||
return (int) t.GetField("Width").GetValue(o);
|
||||
}
|
||||
|
||||
public static void SetWindowSize(int size)
|
||||
{
|
||||
if (size == 1 || size == 2 || size == 3 || size == 4 || size == 5 || size == 10)
|
||||
{
|
||||
Global.Config.TargetZoomFactors[Emulator.SystemId] = size;
|
||||
InvokeMainFormMethod("FrameBufferResized");
|
||||
Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin");
|
||||
FieldInfo f = t.GetField("OSD");
|
||||
object osd = f.GetValue(null);
|
||||
t = f.GetType();
|
||||
MethodInfo m = t.GetMethod("AddMessage");
|
||||
m.Invoke(osd, new Object[] { "Window size set to " + size + "x" });
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Invalid window size");
|
||||
}
|
||||
}
|
||||
|
||||
public static void SpeedMode(int percent)
|
||||
{
|
||||
if (percent > 0 && percent < 6400)
|
||||
{
|
||||
InvokeMainFormMethod("ClickSpeedItem", new object[] {percent});
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Invalid speed value");
|
||||
}
|
||||
}
|
||||
|
||||
public static void TogglePause()
|
||||
{
|
||||
InvokeMainFormMethod("TogglePause");
|
||||
}
|
||||
|
||||
public static int TransformPointX(int x)
|
||||
{
|
||||
var point = new System.Drawing.Point(x, 0);
|
||||
Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin");
|
||||
FieldInfo f = t.GetField("DisplayManager");
|
||||
object displayManager = f.GetValue(null);
|
||||
MethodInfo m = t.GetMethod("TransFormPoint");
|
||||
point = (System.Drawing.Point)m.Invoke(displayManager, new object[] { point });
|
||||
return point.X;
|
||||
}
|
||||
|
||||
public static int TransformPointY(int y)
|
||||
{
|
||||
var point = new System.Drawing.Point(0, y);
|
||||
Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin");
|
||||
FieldInfo f = t.GetField("DisplayManager");
|
||||
object displayManager = f.GetValue(null);
|
||||
MethodInfo m = t.GetMethod("TransFormPoint");
|
||||
point = (System.Drawing.Point)m.Invoke(displayManager, new object[] { point });
|
||||
return point.Y;
|
||||
}
|
||||
|
||||
public static void Unpause()
|
||||
{
|
||||
InvokeMainFormMethod("UnpauseEmulator");
|
||||
}
|
||||
|
||||
public static void UnpauseAv()
|
||||
{
|
||||
SetMainFormField("PauseAvi", false);
|
||||
}
|
||||
|
||||
public static int Xpos()
|
||||
{
|
||||
object o = GetMainFormField("DesktopLocation");
|
||||
Type t = mainFormClass.GetField("DesktopLocation").GetType();
|
||||
return (int)t.GetField("X").GetValue(o);
|
||||
}
|
||||
|
||||
public static int Ypos()
|
||||
{
|
||||
object o = GetMainFormField("DesktopLocation");
|
||||
Type t = mainFormClass.GetField("DesktopLocation").GetType();
|
||||
return (int)t.GetField("Y").GetValue(o);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
@ -427,11 +773,11 @@ namespace BizHawk.Client.ApiHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
return SystemInfo.DualGB;
|
||||
return SystemInfo.DualGB;
|
||||
}
|
||||
|
||||
default:
|
||||
return SystemInfo.FindByCoreSystem(SystemIdConverter.Convert(Global.Emulator.SystemId));
|
||||
return SystemInfo.FindByCoreSystem(SystemIdConverter.Convert(Global.Emulator.SystemId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IApiContainer
|
||||
{
|
||||
Dictionary<Type, IExternalApi> Libraries { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IComm : IExternalApi
|
||||
{
|
||||
#region Sockets
|
||||
string SocketServerScreenShot();
|
||||
string SocketServerScreenShotResponse();
|
||||
string SocketServerSend(string SendString);
|
||||
string SocketServerResponse();
|
||||
bool SocketServerSuccessful();
|
||||
void SocketServerSetTimeout(int timeout);
|
||||
#endregion
|
||||
|
||||
#region MemoryMappedFiles
|
||||
void MmfSetFilename(string filename);
|
||||
string MmfSetFilename();
|
||||
int MmfScreenshot();
|
||||
int MmfWrite(string mmf_filename, string outputString);
|
||||
string MmfRead(string mmf_filename, int expectedSize);
|
||||
#endregion
|
||||
|
||||
#region HTTP
|
||||
string HttpTest();
|
||||
string HttpTestGet();
|
||||
string HttpGet(string url);
|
||||
string HttpPost(string url, string payload);
|
||||
string HttpPostScreenshot();
|
||||
void HttpSetTimeout(int timeout);
|
||||
void HttpSetPostUrl(string url);
|
||||
void HttpSetGetUrl(string url);
|
||||
string HttpGetPostUrl();
|
||||
string HttpGetGetUrl();
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IEmu : IExternalApi
|
||||
{
|
||||
Action FrameAdvanceCallback { get; set; }
|
||||
Action YieldCallback { get; set; }
|
||||
void DisplayVsync(bool enabled);
|
||||
void FrameAdvance();
|
||||
int FrameCount();
|
||||
object Disassemble(uint pc, string name = "");
|
||||
ulong? GetRegister(string name);
|
||||
Dictionary<string, ulong> GetRegisters();
|
||||
void SetRegister(string register, int value);
|
||||
long TotalExecutedycles();
|
||||
string GetSystemId();
|
||||
bool IsLagged();
|
||||
void SetIsLagged(bool value = true);
|
||||
int LagCount();
|
||||
void SetLagCount(int count);
|
||||
void LimitFramerate(bool enabled);
|
||||
void MinimizeFrameskip(bool enabled);
|
||||
void Yield();
|
||||
string GetDisplayType();
|
||||
string GetBoardName();
|
||||
object GetSettings();
|
||||
bool PutSettings(object settings);
|
||||
void SetRenderPlanes(params bool[] param);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface specifies that a client exposes a given interface, such as <seealso cref="IDebuggable"/>,
|
||||
/// for use by external tools.
|
||||
/// </summary>
|
||||
public interface IExternalApi
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IGameInfo : IExternalApi
|
||||
{
|
||||
string GetRomName();
|
||||
string GetRomHash();
|
||||
bool InDatabase();
|
||||
string GetStatus();
|
||||
bool IsStatusBad();
|
||||
string GetBoardType();
|
||||
Dictionary<string, string> GetOptions();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IGui : IExternalApi
|
||||
{
|
||||
#region Gui API
|
||||
void ToggleCompositingMode();
|
||||
ImageAttributes GetAttributes();
|
||||
void SetAttributes(ImageAttributes a);
|
||||
void DrawNew(string name, bool? clear = true);
|
||||
void DrawFinish();
|
||||
bool HasGUISurface { get; }
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
void SetPadding(int all);
|
||||
void SetPadding(int x, int y);
|
||||
void SetPadding(int l, int t, int r, int b);
|
||||
Padding GetPadding();
|
||||
#endregion
|
||||
|
||||
void AddMessage(string message);
|
||||
void ClearGraphics();
|
||||
void ClearText();
|
||||
void SetDefaultForegroundColor(Color color);
|
||||
void SetDefaultBackgroundColor(Color color);
|
||||
void SetDefaultTextBackground(Color color);
|
||||
void SetDefaultPixelFont(string fontfamily);
|
||||
void DrawBezier(Point p1, Point p2, Point p3, Point p4, Color? color = null);
|
||||
void DrawBeziers(Point[] points, Color? color = null);
|
||||
void DrawBox(int x, int y, int x2, int y2, Color? line = null, Color? background = null);
|
||||
void DrawEllipse(int x, int y, int width, int height, Color? line = null, Color? background = null);
|
||||
void DrawIcon(string path, int x, int y, int? width = null, int? height = null);
|
||||
void DrawImage(string path, int x, int y, int? width = null, int? height = null, bool cache = true);
|
||||
void ClearImageCache();
|
||||
void DrawImageRegion(string path, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int? dest_width = null, int? dest_height = null);
|
||||
void DrawLine(int x1, int y1, int x2, int y2, Color? color = null);
|
||||
void DrawAxis(int x, int y, int size, Color? color = null);
|
||||
void DrawPie(int x, int y, int width, int height, int startangle, int sweepangle, Color? line = null, Color? background = null);
|
||||
void DrawPixel(int x, int y, Color? color = null);
|
||||
void DrawPolygon(Point[] points, Color? line = null, Color? background = null);
|
||||
void DrawRectangle(int x, int y, int width, int height, Color? line = null, Color? background = null);
|
||||
void DrawString(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, int? fontsize = null,
|
||||
string fontfamily = null, string fontstyle = null, string horizalign = null, string vertalign = null);
|
||||
void DrawText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null);
|
||||
void Text(int x, int y, string message, Color? forecolor = null, string anchor = null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IInput : IExternalApi
|
||||
{
|
||||
Dictionary<string, bool> Get();
|
||||
Dictionary<string, dynamic> GetMouse();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IJoypad : IExternalApi
|
||||
{
|
||||
Dictionary<string, dynamic> Get(int? controller = null);
|
||||
|
||||
// TODO: what about float controls?
|
||||
Dictionary<string, dynamic> GetImmediate();
|
||||
void SetFromMnemonicStr(string inputLogEntry);
|
||||
void Set(Dictionary<string, bool> buttons, int? controller = null);
|
||||
void Set(string button, bool? state = null, int? controller = null);
|
||||
void SetAnalog(Dictionary<string, float> controls, object controller = null);
|
||||
void SetAnalog(string control, float? value = null, object controller = null);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IMem : IExternalApi
|
||||
{
|
||||
void SetBigEndian(bool enabled = true);
|
||||
|
||||
#region Domains
|
||||
List<string> GetMemoryDomainList();
|
||||
uint GetMemoryDomainSize(string name = "");
|
||||
string GetCurrentMemoryDomain();
|
||||
uint GetCurrentMemoryDomainSize();
|
||||
bool UseMemoryDomain(string domain);
|
||||
string HashRegion(long addr, int count, string domain = null);
|
||||
#endregion
|
||||
#region Read
|
||||
#region Special and Legacy Methods
|
||||
uint ReadByte(long addr, string domain = null);
|
||||
List<byte> ReadByteRange(long addr, int length, string domain = null);
|
||||
float ReadFloat(long addr, string domain = null);
|
||||
#endregion
|
||||
#region Signed
|
||||
int ReadS8(long addr, string domain = null);
|
||||
int ReadS16(long addr, string domain = null);
|
||||
int ReadS24(long addr, string domain = null);
|
||||
int ReadS32(long addr, string domain = null);
|
||||
#endregion
|
||||
#region Unsigned
|
||||
uint ReadU8(long addr, string domain = null);
|
||||
uint ReadU16(long addr, string domain = null);
|
||||
uint ReadU24(long addr, string domain = null);
|
||||
uint ReadU32(long addr, string domain = null);
|
||||
#endregion
|
||||
#endregion
|
||||
#region Write
|
||||
#region Special and Legacy Methods
|
||||
void WriteByte(long addr, uint value, string domain = null);
|
||||
void WriteByteRange(long addr, List<byte> memoryblock, string domain = null);
|
||||
void WriteFloat(long addr, double value, string domain = null);
|
||||
#endregion
|
||||
#region Signed
|
||||
void WriteS8(long addr, int value, string domain = null);
|
||||
void WriteS16(long addr, int value, string domain = null);
|
||||
void WriteS24(long addr, int value, string domain = null);
|
||||
void WriteS32(long addr, int value, string domain = null);
|
||||
#endregion
|
||||
#region Unigned
|
||||
void WriteU8(long addr, uint value, string domain = null);
|
||||
void WriteU16(long addr, uint value, string domain = null);
|
||||
void WriteU24(long addr, uint value, string domain = null);
|
||||
void WriteU32(long addr, uint value, string domain = null);
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IMemEvents : IExternalApi
|
||||
{
|
||||
void AddReadCallback(Action cb, uint address, string domain);
|
||||
void AddWriteCallback(Action cb, uint address, string domain);
|
||||
void AddExecCallback(Action cb, uint address, string domain);
|
||||
void RemoveMemoryCallback(Action cb);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IMemorySaveState : IExternalApi
|
||||
{
|
||||
string SaveCoreStateToMemory();
|
||||
void LoadCoreStateFromMemory(string identifier);
|
||||
void DeleteState(string identifier);
|
||||
void ClearInMemoryStates();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using System.Collections.Generic;
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IMovie : IExternalApi
|
||||
{
|
||||
bool StartsFromSavestate();
|
||||
bool StartsFromSaveram();
|
||||
string Filename();
|
||||
Dictionary<string, dynamic> GetInput(int frame);
|
||||
string GetInputAsMnemonic(int frame);
|
||||
bool GetReadOnly();
|
||||
ulong GetRerecordCount();
|
||||
bool GetRerecordCounting();
|
||||
bool IsLoaded();
|
||||
double Length();
|
||||
string Mode();
|
||||
void Save(string filename = "");
|
||||
void SetReadOnly(bool readOnly);
|
||||
void SetRerecordCount(double count);
|
||||
void SetRerecordCounting(bool counting);
|
||||
void Stop();
|
||||
double GetFps();
|
||||
Dictionary<string, string> GetHeader();
|
||||
List<string> GetComments();
|
||||
List<string> GetSubtitles();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface ISaveState : IExternalApi
|
||||
{
|
||||
void Load(string path);
|
||||
void LoadSlot(int slotNum);
|
||||
void Save(string path);
|
||||
void SaveSlot(int slotNum);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface ISql : IExternalApi
|
||||
{
|
||||
string CreateDatabase(string name);
|
||||
string OpenDatabase(string name);
|
||||
string WriteCommand(string query = "");
|
||||
dynamic ReadCommand(string query = "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface ITool : IExternalApi
|
||||
{
|
||||
Type GetTool(string name);
|
||||
object CreateInstance(string name);
|
||||
void OpenCheats();
|
||||
void OpenHexEditor();
|
||||
void OpenRamWatch();
|
||||
void OpenRamSearch();
|
||||
void OpenTasStudio();
|
||||
void OpenToolBox();
|
||||
void OpenTraceLogger();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
public interface IUserData : IExternalApi
|
||||
{
|
||||
void Set(string name, object value);
|
||||
object Get(string key);
|
||||
void Clear();
|
||||
bool Remove(string key);
|
||||
bool ContainsKey(string key);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface defines the mechanism by which External tools can retrieve <seealso cref="IExternalApi" />
|
||||
/// from a client implementation
|
||||
/// An implementation should collect all available IExternalApi instances.
|
||||
/// This interface defines only the external interaction. This interface does not specify the means
|
||||
/// by which a api provider will be populated with available apis. However, an implementation
|
||||
/// by design must provide this mechanism
|
||||
/// </summary>
|
||||
/// <seealso cref="IExternalApi"/>
|
||||
public interface IExternalApiProvider
|
||||
{
|
||||
/// <summary>e
|
||||
/// Returns whether or not T is available
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The <seealso cref="IExternalApi" /> to check</typeparam>
|
||||
bool HasApi<T>() where T : IExternalApi;
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether or not t is available
|
||||
/// </summary>
|
||||
bool HasApi(Type t);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an instance of T if T is available
|
||||
/// Else returns null
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The requested <seealso cref="IExternalApi" /></typeparam>
|
||||
T GetApi<T>() where T : IExternalApi;
|
||||
|
||||
/// <summary>
|
||||
/// Returns an instance of t if t is available
|
||||
/// Else returns null
|
||||
/// </summary>
|
||||
object GetApi(Type t);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all currently registered Apis available to be retrieved
|
||||
/// </summary>
|
||||
IEnumerable<Type> AvailableApis { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
interface IPlugin
|
||||
{
|
||||
void PreFrameCallback();
|
||||
void PostFrameCallback();
|
||||
void SaveStateCallback(string name);
|
||||
void LoadStateCallback(string name);
|
||||
void InputPollCallback();
|
||||
void Init(IApiContainer api);
|
||||
}
|
||||
}
|
|
@ -67,6 +67,7 @@
|
|||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
|
@ -247,6 +248,7 @@
|
|||
<Compile Include="movie\tasproj\TasMovieRecord.cs" />
|
||||
<Compile Include="movie\tasproj\TasStateManagerSettings.cs" />
|
||||
<Compile Include="NESGameGenieEncoderDecoder.cs" />
|
||||
<Compile Include="OpenAdvanced.cs" />
|
||||
<Compile Include="PathManager.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="QuickBmpFile.cs" />
|
||||
|
|
|
@ -10,7 +10,7 @@ using Newtonsoft.Json;
|
|||
//this file contains some cumbersome self-"serialization" in order to gain a modicum of control over what the serialized output looks like
|
||||
//I don't want them to look like crufty json
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
public interface IOpenAdvanced
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
class OpenAdvanced_Libretro : IOpenAdvanced, IOpenAdvancedLibretro
|
||||
public class OpenAdvanced_Libretro : IOpenAdvanced, IOpenAdvancedLibretro
|
||||
{
|
||||
public OpenAdvanced_Libretro()
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
public string CorePath { get { return token.CorePath; } set { token.CorePath = value; } }
|
||||
}
|
||||
|
||||
class OpenAdvanced_LibretroNoGame : IOpenAdvanced, IOpenAdvancedLibretro
|
||||
public class OpenAdvanced_LibretroNoGame : IOpenAdvanced, IOpenAdvancedLibretro
|
||||
{
|
||||
//you might think ideally we'd fetch the libretro core name from the core info inside it
|
||||
//but that would involve spinning up excess libretro core instances, which probably isnt good for stability, no matter how much we wish otherwise, not to mention slow.
|
||||
|
@ -140,7 +140,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
public string CorePath { get { return _corePath; } set { _corePath = value; } }
|
||||
}
|
||||
|
||||
class OpenAdvanced_OpenRom : IOpenAdvanced
|
||||
public class OpenAdvanced_OpenRom : IOpenAdvanced
|
||||
{
|
||||
public OpenAdvanced_OpenRom()
|
||||
{}
|
|
@ -973,7 +973,14 @@ namespace BizHawk.Client.Common
|
|||
|
||||
if (preference == "neshawk")
|
||||
{
|
||||
core = CoreInventory.Instance["NES", "NesHawk"];
|
||||
if (Global.Config.UseSubNESHawk)
|
||||
{
|
||||
core = CoreInventory.Instance["NES", "SubNESHawk"];
|
||||
}
|
||||
else
|
||||
{
|
||||
core = CoreInventory.Instance["NES", "NesHawk"];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -363,6 +363,12 @@ namespace BizHawk.Client.Common
|
|||
public float DispCustomUserARX = -1;
|
||||
public float DispCustomUserARY = -1;
|
||||
|
||||
//these default to 0 because by default we crop nothing
|
||||
public int DispCropLeft = 0;
|
||||
public int DispCropTop = 0;
|
||||
public int DispCropRight = 0;
|
||||
public int DispCropBottom = 0;
|
||||
|
||||
// Sound options
|
||||
#if WINDOWS
|
||||
public ESoundOutputMethod SoundOutputMethod = ESoundOutputMethod.DirectSound;
|
||||
|
@ -555,6 +561,7 @@ namespace BizHawk.Client.Common
|
|||
// as this setting spans multiple cores and doesn't actually affect the behavior of any core,
|
||||
// it hasn't been absorbed into the new system
|
||||
public bool GB_AsSGB = false;
|
||||
public bool UseSubNESHawk = false;
|
||||
public bool NES_InQuickNES = true;
|
||||
public bool SNES_InSnes9x = true;
|
||||
public bool GBA_UsemGBA = true;
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data.SQLite;
|
||||
using NLua;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
|
|
@ -26,10 +26,10 @@ __Types and notation__
|
|||
* ? (question mark)
|
||||
** A question mark next to a value indicates that it is a Nullable type (only applies to types that are not normally nullable)
|
||||
* [[]] (brackets)
|
||||
** Brackets around a parameter indicate that the parameter is optional. optional parameters have an equals sign followed by the value that will be used if no value is supplied.
|
||||
** Brackets around a parameter indicate that the parameter is optional. Optional parameters have an equals sign followed by the value that will be used if no value is supplied.
|
||||
** Brackets after a parameter type indicate it is an array
|
||||
* null
|
||||
** null is equivalent to the lua nil
|
||||
** null is equivalent to the lua nil. Lua doesn't support named arguments, it checks the arguments by position. So if you're sending an optional argument that goes ''after'' other optional arguments you don't want to send, replace those with lua nil.
|
||||
* Color
|
||||
** This is a .NET System.Drawing.Color struct. The value passed from lua is any value acceptable in the Color constructor. This means either a string with the color name such as ""red"", or a 0xAARRGGBB integer value. Unless specified, this is not a nullable value
|
||||
* object
|
||||
|
|
|
@ -166,6 +166,12 @@ namespace BizHawk.Client.Common
|
|||
|
||||
protected virtual void Write(string fn, bool backup = false)
|
||||
{
|
||||
if (Global.Emulator is BizHawk.Emulation.Cores.Nintendo.SubNESHawk.SubNESHawk)
|
||||
{
|
||||
var _subnes = (BizHawk.Emulation.Cores.Nintendo.SubNESHawk.SubNESHawk)Global.Emulator;
|
||||
Header["VBlankCount"] = _subnes.VBL_CNT.ToString();
|
||||
}
|
||||
|
||||
var file = new FileInfo(fn);
|
||||
if (!file.Directory.Exists)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SubNESHawk;
|
||||
using BizHawk.Emulation.Cores.Sega.MasterSystem;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
|
||||
|
@ -125,7 +126,17 @@ namespace BizHawk.Client.Common.MovieConversionExtensions
|
|||
|
||||
public static TasMovie ConvertToSavestateAnchoredMovie(this TasMovie old, int frame, byte[] savestate)
|
||||
{
|
||||
string newFilename = old.Filename + "." + TasMovie.Extension;
|
||||
string newFilename = old.Filename;
|
||||
|
||||
if (old.Filename.Contains("tasproj"))
|
||||
{
|
||||
newFilename = newFilename.Remove(newFilename.Length - 7, 7);
|
||||
newFilename = newFilename + "nfn." + TasMovie.Extension;
|
||||
}
|
||||
else
|
||||
{
|
||||
newFilename = old.Filename + "." + TasMovie.Extension;
|
||||
}
|
||||
|
||||
if (File.Exists(newFilename))
|
||||
{
|
||||
|
@ -200,7 +211,17 @@ namespace BizHawk.Client.Common.MovieConversionExtensions
|
|||
|
||||
public static TasMovie ConvertToSaveRamAnchoredMovie(this TasMovie old, byte[] saveRam)
|
||||
{
|
||||
string newFilename = old.Filename + "." + TasMovie.Extension;
|
||||
string newFilename = old.Filename;
|
||||
|
||||
if (old.Filename.Contains("tasproj"))
|
||||
{
|
||||
newFilename = newFilename.Remove(newFilename.Length - 7, 7);
|
||||
newFilename = newFilename + "nfsr." + TasMovie.Extension;
|
||||
}
|
||||
else
|
||||
{
|
||||
newFilename = old.Filename + "." + TasMovie.Extension;
|
||||
}
|
||||
|
||||
if (File.Exists(newFilename))
|
||||
{
|
||||
|
@ -336,6 +357,11 @@ namespace BizHawk.Client.Common.MovieConversionExtensions
|
|||
movie.HeaderEntries.Add("Is32X", "1");
|
||||
}
|
||||
|
||||
if (Global.Emulator is SubNESHawk)
|
||||
{
|
||||
movie.HeaderEntries.Add("VBlankCount", "0");
|
||||
}
|
||||
|
||||
movie.Core = ((CoreAttribute)Attribute
|
||||
.GetCustomAttribute(Global.Emulator.GetType(), typeof(CoreAttribute)))
|
||||
.CoreName;
|
||||
|
|
|
@ -384,7 +384,17 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
if (_states.Any())
|
||||
{
|
||||
StateManagerState power = _states.Values.First(s => s.Frame == 0);
|
||||
var temp_state = _states.Values;
|
||||
StateManagerState power = null;
|
||||
if (temp_state[0].Frame==0)
|
||||
{
|
||||
power = _states.Values.First(s => s.Frame == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
power = _states.Values[0];
|
||||
}
|
||||
|
||||
_states.Clear();
|
||||
SetState(0, power.State);
|
||||
Used = (ulong)power.State.Length;
|
||||
|
|
|
@ -217,9 +217,9 @@ namespace BizHawk.Client.Common
|
|||
case DisplayType.Hex:
|
||||
return val.ToHexString(8);
|
||||
case DisplayType.FixedPoint_20_12:
|
||||
return $"{val / 4096.0:0.######}";
|
||||
return $"{(int)val / 4096.0:0.######}";
|
||||
case DisplayType.FixedPoint_16_16:
|
||||
return $"{val / 65536.0:0.######}";
|
||||
return $"{(int)val / 65536.0:0.######}";
|
||||
case DisplayType.Float:
|
||||
var bytes = BitConverter.GetBytes(val);
|
||||
var _float = BitConverter.ToSingle(bytes, 0);
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
new FormatPreset("Matroska", "AVC video and Vorbis audio in a Matroska container.",
|
||||
"-c:a libvorbis -c:v libx264 -f matroska", false, "mkv"),
|
||||
new FormatPreset("MP4", "AVC video and AAC audio in an MP4 container.",
|
||||
"-c:a libvo_aacenc -c:v libx264 -f mp4", false, "mp4"),
|
||||
"-c:a aac -c:v libx264 -f mp4", false, "mp4"),
|
||||
new FormatPreset("WebM", "VP8 video and Vorbis audio in a WebM container.",
|
||||
"-c:a libvorbis -c:v libvpx -f webm", false, "webm"),
|
||||
new FormatPreset("Ogg", "Theora video and Vorbis audio in an Ogg contrainer.",
|
||||
|
@ -67,9 +67,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
new FormatPreset("Xvid", "Xvid video and MP3 audio in an AVI container.",
|
||||
"-c:a libmp3lame -c:v libxvid -f avi", false, "avi"),
|
||||
new FormatPreset("QuickTime", "AVC video and AAC audio in a QuickTime container.",
|
||||
"-c:a libvo_aacenc -c:v libx264 -f mov", false, "mov"),
|
||||
"-c:a aac -c:v libx264 -f mov", false, "mov"),
|
||||
new FormatPreset("FLV", "AVC video and AAC audio in a Flash Video container.",
|
||||
"-c:a libvo_aacenc -c:v libx264 -f flv", false, "flv"),
|
||||
"-c:a aac -c:v libx264 -f flv", false, "flv"),
|
||||
new FormatPreset("[Custom]", "Write your own ffmpeg command. For advanced users only.",
|
||||
"-c:a foo -c:v bar -f baz", true, "foobar"),
|
||||
};
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Client.ApiHawk;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public sealed class ApiContainer : IApiContainer
|
||||
{
|
||||
public IComm Comm => (IComm)Libraries[typeof(CommApi)];
|
||||
public IEmu Emu => (IEmu)Libraries[typeof(EmuApi)];
|
||||
public IGameInfo GameInfo => (IGameInfo)Libraries[typeof(GameInfoApi)];
|
||||
public IGui Gui => (IGui)Libraries[typeof(GuiApi)];
|
||||
public IInput Input => (IInput)Libraries[typeof(InputApi)];
|
||||
public IJoypad Joypad => (IJoypad)Libraries[typeof(JoypadApi)];
|
||||
public IMem Mem => (IMem)Libraries[typeof(MemApi)];
|
||||
public IMemEvents MemEvents => (IMemEvents)Libraries[typeof(MemEventsApi)];
|
||||
public IMemorySaveState MemorySaveState => (IMemorySaveState)Libraries[typeof(MemorySaveStateApi)];
|
||||
public IMovie Movie => (IMovie)Libraries[typeof(MovieApi)];
|
||||
public ISaveState SaveState => (ISaveState)Libraries[typeof(SaveStateApi)];
|
||||
public ISql Sql => (ISql)Libraries[typeof(SqlApi)];
|
||||
public ITool Tool => (ITool)Libraries[typeof(ToolApi)];
|
||||
public IUserData UserData => (IUserData)Libraries[typeof(UserDataApi)];
|
||||
public Dictionary<Type, IExternalApi> Libraries { get; set; }
|
||||
public ApiContainer(Dictionary<Type, IExternalApi> libs)
|
||||
{
|
||||
Libraries = libs;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using BizHawk.Common.ReflectionExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Client.ApiHawk;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
|
||||
{
|
||||
public static class ApiManager
|
||||
{
|
||||
private static ApiContainer container;
|
||||
private static void Register(IEmulatorServiceProvider serviceProvider)
|
||||
{
|
||||
// Register external apis
|
||||
var apis = Assembly
|
||||
.Load("BizHawk.Client.ApiHawk")
|
||||
.GetTypes()
|
||||
.Where(t => typeof(IExternalApi).IsAssignableFrom(t))
|
||||
.Where(t => t.IsSealed)
|
||||
.Where(t => ServiceInjector.IsAvailable(serviceProvider, t))
|
||||
.ToList();
|
||||
|
||||
apis.AddRange(
|
||||
Assembly
|
||||
.GetAssembly(typeof(ApiContainer))
|
||||
.GetTypes()
|
||||
.Where(t => typeof(IExternalApi).IsAssignableFrom(t))
|
||||
.Where(t => t.IsSealed)
|
||||
.Where(t => ServiceInjector.IsAvailable(serviceProvider, t)));
|
||||
|
||||
foreach (var api in apis)
|
||||
{
|
||||
var instance = (IExternalApi)Activator.CreateInstance(api);
|
||||
ServiceInjector.UpdateServices(serviceProvider, instance);
|
||||
Libraries.Add(api, instance);
|
||||
}
|
||||
container = new ApiContainer(Libraries);
|
||||
GlobalWin.ApiProvider = new BasicApiProvider(container);
|
||||
}
|
||||
private static readonly Dictionary<Type, IExternalApi> Libraries = new Dictionary<Type, IExternalApi>();
|
||||
public static void Restart(IEmulatorServiceProvider newServiceProvider)
|
||||
{
|
||||
Libraries.Clear();
|
||||
Register(newServiceProvider);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Client.ApiHawk;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public sealed class CommApi : IComm
|
||||
{
|
||||
[RequiredService]
|
||||
private IEmulator Emulator { get; set; }
|
||||
|
||||
[RequiredService]
|
||||
private IVideoProvider VideoProvider { get; set; }
|
||||
|
||||
public CommApi() : base()
|
||||
{ }
|
||||
|
||||
public string SocketServerScreenShot()
|
||||
{
|
||||
return GlobalWin.socketServer.SendScreenshot();
|
||||
}
|
||||
public string SocketServerScreenShotResponse()
|
||||
{
|
||||
return GlobalWin.socketServer.SendScreenshot(1000).ToString();
|
||||
}
|
||||
|
||||
public string SocketServerSend(string SendString)
|
||||
{
|
||||
return "Sent : " + GlobalWin.socketServer.SendString(SendString).ToString() + " bytes";
|
||||
}
|
||||
public string SocketServerResponse()
|
||||
{
|
||||
return GlobalWin.socketServer.ReceiveMessage();
|
||||
}
|
||||
|
||||
public bool SocketServerSuccessful()
|
||||
{
|
||||
return GlobalWin.socketServer.Successful();
|
||||
}
|
||||
public void SocketServerSetTimeout(int timeout)
|
||||
{
|
||||
GlobalWin.socketServer.SetTimeout(timeout);
|
||||
}
|
||||
// All MemoryMappedFile related methods
|
||||
public void MmfSetFilename(string filename)
|
||||
{
|
||||
GlobalWin.memoryMappedFiles.SetFilename(filename);
|
||||
}
|
||||
public string MmfSetFilename()
|
||||
{
|
||||
return GlobalWin.memoryMappedFiles.GetFilename();
|
||||
}
|
||||
|
||||
public int MmfScreenshot()
|
||||
{
|
||||
return GlobalWin.memoryMappedFiles.ScreenShotToFile();
|
||||
}
|
||||
|
||||
public int MmfWrite(string mmf_filename, string outputString)
|
||||
{
|
||||
return GlobalWin.memoryMappedFiles.WriteToFile(mmf_filename, Encoding.ASCII.GetBytes(outputString));
|
||||
}
|
||||
public string MmfRead(string mmf_filename, int expectedSize)
|
||||
{
|
||||
return GlobalWin.memoryMappedFiles.ReadFromFile(mmf_filename, expectedSize).ToString();
|
||||
}
|
||||
// All HTTP related methods
|
||||
public string HttpTest()
|
||||
{
|
||||
var list = new StringBuilder();
|
||||
list.AppendLine(GlobalWin.httpCommunication.TestGet());
|
||||
list.AppendLine(GlobalWin.httpCommunication.SendScreenshot());
|
||||
list.AppendLine("done testing");
|
||||
return list.ToString();
|
||||
}
|
||||
public string HttpTestGet()
|
||||
{
|
||||
return GlobalWin.httpCommunication.TestGet();
|
||||
}
|
||||
public string HttpGet(string url)
|
||||
{
|
||||
return GlobalWin.httpCommunication.ExecGet(url);
|
||||
}
|
||||
|
||||
public string HttpPost(string url, string payload)
|
||||
{
|
||||
return GlobalWin.httpCommunication.ExecPost(url, payload);
|
||||
}
|
||||
public string HttpPostScreenshot()
|
||||
{
|
||||
return GlobalWin.httpCommunication.SendScreenshot();
|
||||
}
|
||||
public void HttpSetTimeout(int timeout)
|
||||
{
|
||||
GlobalWin.httpCommunication.SetTimeout(timeout);
|
||||
}
|
||||
public void HttpSetPostUrl(string url)
|
||||
{
|
||||
GlobalWin.httpCommunication.SetPostUrl(url);
|
||||
}
|
||||
public void HttpSetGetUrl(string url)
|
||||
{
|
||||
GlobalWin.httpCommunication.SetGetUrl(url);
|
||||
}
|
||||
public string HttpGetPostUrl()
|
||||
{
|
||||
return GlobalWin.httpCommunication.GetPostUrl();
|
||||
}
|
||||
public string HttpGetGetUrl()
|
||||
{
|
||||
return GlobalWin.httpCommunication.GetGetUrl();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,655 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Client.ApiHawk;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public sealed class GuiApi : IGui
|
||||
{
|
||||
[RequiredService]
|
||||
private IEmulator Emulator { get; set; }
|
||||
private Color _defaultForeground = Color.White;
|
||||
private Color? _defaultBackground;
|
||||
private Color? _defaultTextBackground = Color.FromArgb(128, 0, 0, 0);
|
||||
private int _defaultPixelFont = 1; // gens
|
||||
private Padding _padding = new Padding(0);
|
||||
private ImageAttributes _attributes = new ImageAttributes();
|
||||
private System.Drawing.Drawing2D.CompositingMode _compositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
|
||||
|
||||
|
||||
public GuiApi()
|
||||
{ }
|
||||
|
||||
private DisplaySurface _GUISurface = null;
|
||||
|
||||
public bool HasGUISurface => _GUISurface != null;
|
||||
|
||||
#region Gui API
|
||||
public void ToggleCompositingMode()
|
||||
{
|
||||
_compositingMode = 1 - _compositingMode;
|
||||
}
|
||||
|
||||
public ImageAttributes GetAttributes()
|
||||
{
|
||||
return _attributes;
|
||||
}
|
||||
public void SetAttributes(ImageAttributes a)
|
||||
{
|
||||
_attributes = a;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var brush in _solidBrushes.Values)
|
||||
{
|
||||
brush.Dispose();
|
||||
}
|
||||
|
||||
foreach (var brush in _pens.Values)
|
||||
{
|
||||
brush.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawNew(string name, bool? clear = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
DrawFinish();
|
||||
_GUISurface = GlobalWin.DisplayManager.LockLuaSurface(name, clear ?? true);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawFinish()
|
||||
{
|
||||
if (_GUISurface != null)
|
||||
{
|
||||
GlobalWin.DisplayManager.UnlockLuaSurface(_GUISurface);
|
||||
}
|
||||
|
||||
_GUISurface = null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
private readonly Dictionary<string, Image> _imageCache = new Dictionary<string, Image>();
|
||||
private readonly Dictionary<Color, SolidBrush> _solidBrushes = new Dictionary<Color, SolidBrush>();
|
||||
private readonly Dictionary<Color, Pen> _pens = new Dictionary<Color, Pen>();
|
||||
private SolidBrush GetBrush(Color color)
|
||||
{
|
||||
SolidBrush b;
|
||||
if (!_solidBrushes.TryGetValue(color, out b))
|
||||
{
|
||||
b = new SolidBrush(color);
|
||||
_solidBrushes[color] = b;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
private Pen GetPen(Color color)
|
||||
{
|
||||
Pen p;
|
||||
if (!_pens.TryGetValue(color, out p))
|
||||
{
|
||||
p = new Pen(color);
|
||||
_pens[color] = p;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
private Graphics GetGraphics()
|
||||
{
|
||||
var g = _GUISurface == null ? Graphics.FromImage(new Bitmap(1,1)) : _GUISurface.GetGraphics();
|
||||
|
||||
// we don't like CoreComm, right? Someone should find a different way to do this then.
|
||||
var tx = Emulator.CoreComm.ScreenLogicalOffsetX;
|
||||
var ty = Emulator.CoreComm.ScreenLogicalOffsetY;
|
||||
if (tx != 0 || ty != 0)
|
||||
{
|
||||
var transform = g.Transform;
|
||||
transform.Translate(-tx, -ty);
|
||||
g.Transform = transform;
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
public void SetPadding(int all)
|
||||
{
|
||||
_padding = new Padding(all);
|
||||
}
|
||||
public void SetPadding(int x, int y)
|
||||
{
|
||||
_padding = new Padding(x / 2, y / 2, x / 2 + x & 1, y / 2 + y & 1);
|
||||
}
|
||||
public void SetPadding(int l, int t, int r, int b)
|
||||
{
|
||||
_padding = new Padding(l, t, r, b);
|
||||
}
|
||||
public Padding GetPadding()
|
||||
{
|
||||
return _padding;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void AddMessage(string message)
|
||||
{
|
||||
GlobalWin.OSD.AddMessage(message);
|
||||
}
|
||||
|
||||
public void ClearGraphics()
|
||||
{
|
||||
_GUISurface.Clear();
|
||||
DrawFinish();
|
||||
}
|
||||
|
||||
public void ClearText()
|
||||
{
|
||||
GlobalWin.OSD.ClearGUIText();
|
||||
}
|
||||
|
||||
public void SetDefaultForegroundColor(Color color)
|
||||
{
|
||||
_defaultForeground = color;
|
||||
}
|
||||
|
||||
public void SetDefaultBackgroundColor(Color color)
|
||||
{
|
||||
_defaultBackground = color;
|
||||
}
|
||||
|
||||
public void SetDefaultTextBackground(Color color)
|
||||
{
|
||||
_defaultTextBackground = color;
|
||||
}
|
||||
|
||||
public void SetDefaultPixelFont(string fontfamily)
|
||||
{
|
||||
switch (fontfamily)
|
||||
{
|
||||
case "fceux":
|
||||
case "0":
|
||||
_defaultPixelFont = 0;
|
||||
break;
|
||||
case "gens":
|
||||
case "1":
|
||||
_defaultPixelFont = 1;
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine($"Unable to find font family: {fontfamily}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawBezier(Point p1, Point p2, Point p3, Point p4, Color? color = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
try
|
||||
{
|
||||
g.CompositingMode = _compositingMode;
|
||||
g.DrawBezier(GetPen(color ?? _defaultForeground), p1, p2, p3, p4);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawBeziers(Point[] points, Color? color = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
try
|
||||
{
|
||||
g.CompositingMode = _compositingMode;
|
||||
g.DrawBeziers(GetPen(color ?? _defaultForeground), points);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void DrawBox(int x, int y, int x2, int y2, Color? line = null, Color? background = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
try
|
||||
{
|
||||
float w;
|
||||
float h;
|
||||
if (x < x2)
|
||||
{
|
||||
w = x2 - x;
|
||||
}
|
||||
else
|
||||
{
|
||||
x2 = x - x2;
|
||||
x -= x2;
|
||||
w = Math.Max(x2, 0.1f);
|
||||
}
|
||||
|
||||
if (y < y2)
|
||||
{
|
||||
h = y2 - y;
|
||||
}
|
||||
else
|
||||
{
|
||||
y2 = y - y2;
|
||||
y -= y2;
|
||||
h = Math.Max(y2, 0.1f);
|
||||
}
|
||||
|
||||
g.CompositingMode = _compositingMode;
|
||||
g.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, w, h);
|
||||
|
||||
var bg = background ?? _defaultBackground;
|
||||
if (bg.HasValue)
|
||||
{
|
||||
g.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, Math.Max(w - 1, 0), Math.Max(h - 1, 0));
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// need to stop the script from here
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawEllipse(int x, int y, int width, int height, Color? line = null, Color? background = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
try
|
||||
{
|
||||
var bg = background ?? _defaultBackground;
|
||||
if (bg.HasValue)
|
||||
{
|
||||
var brush = GetBrush(bg.Value);
|
||||
g.FillEllipse(brush, x, y, width, height);
|
||||
}
|
||||
|
||||
g.CompositingMode = _compositingMode;
|
||||
g.DrawEllipse(GetPen(line ?? _defaultForeground), x, y, width, height);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// need to stop the script from here
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawIcon(string path, int x, int y, int? width = null, int? height = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
AddMessage("File not found: " + path);
|
||||
return;
|
||||
}
|
||||
|
||||
Icon icon;
|
||||
if (width.HasValue && height.HasValue)
|
||||
{
|
||||
icon = new Icon(path, width.Value, height.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
icon = new Icon(path);
|
||||
}
|
||||
|
||||
g.CompositingMode = _compositingMode;
|
||||
g.DrawIcon(icon, x, y);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawImage(string path, int x, int y, int? width = null, int? height = null, bool cache = true)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
Console.WriteLine("File not found: " + path);
|
||||
return;
|
||||
}
|
||||
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
Image img;
|
||||
if (_imageCache.ContainsKey(path))
|
||||
{
|
||||
img = _imageCache[path];
|
||||
}
|
||||
else
|
||||
{
|
||||
img = Image.FromFile(path);
|
||||
if (cache)
|
||||
{
|
||||
_imageCache.Add(path, img);
|
||||
}
|
||||
}
|
||||
var destRect = new Rectangle(x, y, width ?? img.Width, height ?? img.Height);
|
||||
|
||||
g.CompositingMode = _compositingMode;
|
||||
g.DrawImage(img, destRect, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, _attributes);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearImageCache()
|
||||
{
|
||||
foreach (var image in _imageCache)
|
||||
{
|
||||
image.Value.Dispose();
|
||||
}
|
||||
|
||||
_imageCache.Clear();
|
||||
}
|
||||
|
||||
public void DrawImageRegion(string path, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int? dest_width = null, int? dest_height = null)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
Console.WriteLine("File not found: " + path);
|
||||
return;
|
||||
}
|
||||
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
Image img;
|
||||
if (_imageCache.ContainsKey(path))
|
||||
{
|
||||
img = _imageCache[path];
|
||||
}
|
||||
else
|
||||
{
|
||||
img = Image.FromFile(path);
|
||||
_imageCache.Add(path, img);
|
||||
}
|
||||
|
||||
var destRect = new Rectangle(dest_x, dest_y, dest_width ?? source_width, dest_height ?? source_height);
|
||||
|
||||
g.CompositingMode = _compositingMode;
|
||||
g.DrawImage(img, destRect, source_x, source_y, source_width, source_height, GraphicsUnit.Pixel, _attributes);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawLine(int x1, int y1, int x2, int y2, Color? color = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
g.CompositingMode = _compositingMode;
|
||||
g.DrawLine(GetPen(color ?? _defaultForeground), x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawAxis(int x, int y, int size, Color? color = null)
|
||||
{
|
||||
DrawLine(x + size, y, x - size, y, color ?? _defaultForeground);
|
||||
DrawLine(x, y + size, x, y - size, color ?? _defaultForeground);
|
||||
}
|
||||
|
||||
public void DrawPie(int x, int y, int width, int height, int startangle, int sweepangle, Color? line = null, Color? background = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
g.CompositingMode = _compositingMode;
|
||||
var bg = background ?? _defaultBackground;
|
||||
if (bg.HasValue)
|
||||
{
|
||||
var brush = GetBrush(bg.Value);
|
||||
g.FillPie(brush, x, y, width, height, startangle, sweepangle);
|
||||
}
|
||||
|
||||
g.DrawPie(GetPen(line ?? _defaultForeground), x + 1, y + 1, width - 1, height - 1, startangle, sweepangle);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawPixel(int x, int y, Color? color = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
try
|
||||
{
|
||||
g.DrawLine(GetPen(color ?? _defaultForeground), x, y, x + 0.1F, y);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawPolygon(Point[] points, Color? line = null, Color? background = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
try
|
||||
{
|
||||
g.DrawPolygon(GetPen(line ?? _defaultForeground), points);
|
||||
var bg = background ?? _defaultBackground;
|
||||
if (bg.HasValue)
|
||||
{
|
||||
g.FillPolygon(GetBrush(bg.Value), points);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawRectangle(int x, int y, int width, int height, Color? line = null, Color? background = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
var w = Math.Max(width, 0.1F);
|
||||
var h = Math.Max(height, 0.1F);
|
||||
g.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, w, h);
|
||||
var bg = background ?? _defaultBackground;
|
||||
if (bg.HasValue)
|
||||
{
|
||||
g.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, Math.Max(w - 1, 0), Math.Max(h - 1, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawString(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, int? fontsize = null,
|
||||
string fontfamily = null, string fontstyle = null, string horizalign = null, string vertalign = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
try
|
||||
{
|
||||
var family = FontFamily.GenericMonospace;
|
||||
if (fontfamily != null)
|
||||
{
|
||||
family = new FontFamily(fontfamily);
|
||||
}
|
||||
|
||||
var fstyle = FontStyle.Regular;
|
||||
if (fontstyle != null)
|
||||
{
|
||||
switch (fontstyle.ToLower())
|
||||
{
|
||||
default:
|
||||
case "regular":
|
||||
break;
|
||||
case "bold":
|
||||
fstyle = FontStyle.Bold;
|
||||
break;
|
||||
case "italic":
|
||||
fstyle = FontStyle.Italic;
|
||||
break;
|
||||
case "strikethrough":
|
||||
fstyle = FontStyle.Strikeout;
|
||||
break;
|
||||
case "underline":
|
||||
fstyle = FontStyle.Underline;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The text isn't written out using GenericTypographic, so measuring it using GenericTypographic seemed to make it worse.
|
||||
// And writing it out with GenericTypographic just made it uglier. :p
|
||||
var f = new StringFormat(StringFormat.GenericDefault);
|
||||
var font = new Font(family, fontsize ?? 12, fstyle, GraphicsUnit.Pixel);
|
||||
Size sizeOfText = g.MeasureString(message, font, 0, f).ToSize();
|
||||
if (horizalign != null)
|
||||
{
|
||||
switch (horizalign.ToLower())
|
||||
{
|
||||
default:
|
||||
case "left":
|
||||
break;
|
||||
case "center":
|
||||
x -= sizeOfText.Width / 2;
|
||||
break;
|
||||
case "right":
|
||||
x -= sizeOfText.Width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vertalign != null)
|
||||
{
|
||||
switch (vertalign.ToLower())
|
||||
{
|
||||
default:
|
||||
case "bottom":
|
||||
break;
|
||||
case "middle":
|
||||
y -= sizeOfText.Height / 2;
|
||||
break;
|
||||
case "top":
|
||||
y -= sizeOfText.Height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var bg = backcolor ?? _defaultBackground;
|
||||
if (bg.HasValue)
|
||||
{
|
||||
for (var xd = -1; xd <= 1; xd++)
|
||||
{
|
||||
for (var yd = -1; yd <= 1; yd++)
|
||||
{
|
||||
g.DrawString(message, font, GetBrush(bg.Value), x + xd, y + yd);
|
||||
}
|
||||
}
|
||||
}
|
||||
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
|
||||
g.DrawString(message, font, GetBrush(forecolor ?? _defaultForeground), x, y);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null)
|
||||
{
|
||||
using (var g = GetGraphics())
|
||||
{
|
||||
try
|
||||
{
|
||||
var index = 0;
|
||||
if (string.IsNullOrEmpty(fontfamily))
|
||||
{
|
||||
index = _defaultPixelFont;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (fontfamily)
|
||||
{
|
||||
case "fceux":
|
||||
case "0":
|
||||
index = 0;
|
||||
break;
|
||||
case "gens":
|
||||
case "1":
|
||||
index = 1;
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine($"Unable to find font family: {fontfamily}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var f = new StringFormat(StringFormat.GenericTypographic)
|
||||
{
|
||||
FormatFlags = StringFormatFlags.MeasureTrailingSpaces
|
||||
};
|
||||
var font = new Font(GlobalWin.DisplayManager.CustomFonts.Families[index], 8, FontStyle.Regular, GraphicsUnit.Pixel);
|
||||
Size sizeOfText = g.MeasureString(message, font, 0, f).ToSize();
|
||||
var rect = new Rectangle(new Point(x, y), sizeOfText + new Size(1, 0));
|
||||
if (backcolor.HasValue) g.FillRectangle(GetBrush(backcolor.Value), rect);
|
||||
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
|
||||
g.DrawString(message, font, GetBrush(forecolor ?? _defaultForeground), x, y);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Text(int x, int y, string message, Color? forecolor = null, string anchor = null)
|
||||
{
|
||||
var a = 0;
|
||||
|
||||
if (!string.IsNullOrEmpty(anchor))
|
||||
{
|
||||
switch (anchor)
|
||||
{
|
||||
case "0":
|
||||
case "topleft":
|
||||
a = 0;
|
||||
break;
|
||||
case "1":
|
||||
case "topright":
|
||||
a = 1;
|
||||
break;
|
||||
case "2":
|
||||
case "bottomleft":
|
||||
a = 2;
|
||||
break;
|
||||
case "3":
|
||||
case "bottomright":
|
||||
a = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x -= Emulator.CoreComm.ScreenLogicalOffsetX;
|
||||
y -= Emulator.CoreComm.ScreenLogicalOffsetY;
|
||||
}
|
||||
|
||||
GlobalWin.OSD.AddGUIText(message, x, y, Color.Black, forecolor ?? Color.White, a);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Client.ApiHawk;
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public sealed class InputApi : IInput
|
||||
{
|
||||
public InputApi() : base()
|
||||
{ }
|
||||
|
||||
public Dictionary<string,bool> Get()
|
||||
{
|
||||
var buttons = new Dictionary<string, bool>();
|
||||
foreach (var kvp in Global.ControllerInputCoalescer.BoolButtons().Where(kvp => kvp.Value))
|
||||
{
|
||||
buttons[kvp.Key] = true;
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
public Dictionary<string, dynamic> GetMouse()
|
||||
{
|
||||
var buttons = new Dictionary<string, dynamic>();
|
||||
|
||||
// TODO - need to specify whether in "emu" or "native" coordinate space.
|
||||
var p = GlobalWin.DisplayManager.UntransformPoint(Control.MousePosition);
|
||||
buttons["X"] = p.X;
|
||||
buttons["Y"] = p.Y;
|
||||
buttons[MouseButtons.Left.ToString()] = (Control.MouseButtons & MouseButtons.Left) != 0;
|
||||
buttons[MouseButtons.Middle.ToString()] = (Control.MouseButtons & MouseButtons.Middle) != 0;
|
||||
buttons[MouseButtons.Right.ToString()] = (Control.MouseButtons & MouseButtons.Right) != 0;
|
||||
buttons[MouseButtons.XButton1.ToString()] = (Control.MouseButtons & MouseButtons.XButton1) != 0;
|
||||
buttons[MouseButtons.XButton2.ToString()] = (Control.MouseButtons & MouseButtons.XButton2) != 0;
|
||||
buttons["Wheel"] = GlobalWin.MainForm.MouseWheelTracker;
|
||||
return buttons;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Client.ApiHawk;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public sealed class SaveStateApi : ISaveState
|
||||
{
|
||||
public SaveStateApi() : base()
|
||||
{ }
|
||||
|
||||
public void Load(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
Console.WriteLine($"could not find file: {path}");
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalWin.MainForm.LoadState(path, Path.GetFileName(path), true);
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadSlot(int slotNum)
|
||||
{
|
||||
if (slotNum >= 0 && slotNum <= 9)
|
||||
{
|
||||
GlobalWin.MainForm.LoadQuickSave("QuickSave" + slotNum, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(string path)
|
||||
{
|
||||
GlobalWin.MainForm.SaveState(path, path, true);
|
||||
}
|
||||
|
||||
public void SaveSlot(int slotNum)
|
||||
{
|
||||
if (slotNum >= 0 && slotNum <= 9)
|
||||
{
|
||||
GlobalWin.MainForm.SaveQuickSave("QuickSave" + slotNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Client.ApiHawk;
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public sealed class ToolApi : ITool
|
||||
{
|
||||
private class ToolStatic
|
||||
{
|
||||
public Type GetTool(string name)
|
||||
{
|
||||
var toolType = ReflectionUtil.GetTypeByName(name)
|
||||
.FirstOrDefault(x => typeof(IToolForm).IsAssignableFrom(x) && !x.IsInterface);
|
||||
|
||||
if (toolType != null)
|
||||
{
|
||||
GlobalWin.Tools.Load(toolType);
|
||||
}
|
||||
|
||||
var selectedTool = GlobalWin.Tools.AvailableTools
|
||||
.FirstOrDefault(tool => tool.GetType().Name.ToLower() == name.ToLower());
|
||||
|
||||
if (selectedTool != null)
|
||||
{
|
||||
return selectedTool;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object CreateInstance(string name)
|
||||
{
|
||||
var possibleTypes = ReflectionUtil.GetTypeByName(name);
|
||||
|
||||
if (possibleTypes.Any())
|
||||
{
|
||||
return Activator.CreateInstance(possibleTypes.First());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void OpenCheats()
|
||||
{
|
||||
GlobalWin.Tools.Load<Cheats>();
|
||||
}
|
||||
|
||||
public static void OpenHexEditor()
|
||||
{
|
||||
GlobalWin.Tools.Load<HexEditor>();
|
||||
}
|
||||
|
||||
public static void OpenRamWatch()
|
||||
{
|
||||
GlobalWin.Tools.LoadRamWatch(loadDialog: true);
|
||||
}
|
||||
|
||||
public static void OpenRamSearch()
|
||||
{
|
||||
GlobalWin.Tools.Load<RamSearch>();
|
||||
}
|
||||
|
||||
public static void OpenTasStudio()
|
||||
{
|
||||
GlobalWin.Tools.Load<TAStudio>();
|
||||
}
|
||||
|
||||
public static void OpenToolBox()
|
||||
{
|
||||
GlobalWin.Tools.Load<ToolBox>();
|
||||
}
|
||||
|
||||
public static void OpenTraceLogger()
|
||||
{
|
||||
GlobalWin.Tools.Load<TraceLogger>();
|
||||
}
|
||||
|
||||
}
|
||||
[RequiredService]
|
||||
private static IEmulator Emulator { get; set; }
|
||||
|
||||
[RequiredService]
|
||||
private static IVideoProvider VideoProvider { get; set; }
|
||||
|
||||
public ToolApi()
|
||||
{ }
|
||||
|
||||
public Type GetTool(string name)
|
||||
{
|
||||
var toolType = ReflectionUtil.GetTypeByName(name)
|
||||
.FirstOrDefault(x => typeof(IToolForm).IsAssignableFrom(x) && !x.IsInterface);
|
||||
|
||||
if (toolType != null)
|
||||
{
|
||||
GlobalWin.Tools.Load(toolType);
|
||||
}
|
||||
|
||||
var selectedTool = GlobalWin.Tools.AvailableTools
|
||||
.FirstOrDefault(tool => tool.GetType().Name.ToLower() == name.ToLower());
|
||||
|
||||
if (selectedTool != null)
|
||||
{
|
||||
return selectedTool;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object CreateInstance(string name)
|
||||
{
|
||||
var possibleTypes = ReflectionUtil.GetTypeByName(name);
|
||||
|
||||
if (possibleTypes.Any())
|
||||
{
|
||||
return Activator.CreateInstance(possibleTypes.First());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void OpenCheats()
|
||||
{
|
||||
ToolStatic.OpenCheats();
|
||||
}
|
||||
|
||||
public void OpenHexEditor()
|
||||
{
|
||||
ToolStatic.OpenHexEditor();
|
||||
}
|
||||
|
||||
public void OpenRamWatch()
|
||||
{
|
||||
ToolStatic.OpenRamWatch();
|
||||
}
|
||||
|
||||
public void OpenRamSearch()
|
||||
{
|
||||
ToolStatic.OpenRamSearch();
|
||||
}
|
||||
|
||||
public void OpenTasStudio()
|
||||
{
|
||||
ToolStatic.OpenTasStudio();
|
||||
}
|
||||
|
||||
public void OpenToolBox()
|
||||
{
|
||||
ToolStatic.OpenToolBox();
|
||||
}
|
||||
|
||||
public void OpenTraceLogger()
|
||||
{
|
||||
ToolStatic.OpenTraceLogger();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -691,6 +691,13 @@
|
|||
</Compile>
|
||||
<Compile Include="GLManager.cs" />
|
||||
<Compile Include="GlobalWin.cs" />
|
||||
<Compile Include="Api\ApiContainer.cs" />
|
||||
<Compile Include="Api\Libraries\ToolApi.cs" />
|
||||
<Compile Include="Api\Libraries\GuiApi.cs" />
|
||||
<Compile Include="Api\Libraries\InputApi.cs" />
|
||||
<Compile Include="Api\Libraries\SaveStateAPI.cs" />
|
||||
<Compile Include="Api\ApiManager.cs" />
|
||||
<Compile Include="Api\Libraries\CommApi.cs" />
|
||||
<!--<Compile Include="Input\GamePad.cs" Condition=" '$(OS)' == 'Windows_NT' " />-->
|
||||
<Compile Include="Input\GamePad.cs" />
|
||||
<Compile Include="Input\GamePad360.cs" />
|
||||
|
@ -764,7 +771,6 @@
|
|||
<Compile Include="NameStateForm.Designer.cs">
|
||||
<DependentUpon>NameStateForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="OpenAdvanced.cs" />
|
||||
<Compile Include="OpenAdvancedChooser.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
|
|
@ -181,6 +181,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
padding.Bottom += core_padding.Height - core_padding.Height / 2;
|
||||
}
|
||||
|
||||
//apply user's crop selections as a negative padding (believe it or not, this largely works)
|
||||
//is there an issue with the aspect ratio? I dont know--but if there is, there would be with the padding too
|
||||
padding.Left -= Global.Config.DispCropLeft;
|
||||
padding.Right -= Global.Config.DispCropRight;
|
||||
padding.Top -= Global.Config.DispCropTop;
|
||||
padding.Bottom -= Global.Config.DispCropBottom;
|
||||
|
||||
return padding;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using BizHawk.Bizware.BizwareGL;
|
||||
using BizHawk.Client.ApiHawk;
|
||||
|
||||
// ReSharper disable StyleCop.SA1401
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
|
@ -7,6 +8,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
public static MainForm MainForm;
|
||||
public static ToolManager Tools;
|
||||
public static BasicApiProvider ApiProvider;
|
||||
|
||||
/// <summary>
|
||||
/// the IGL to be used for rendering
|
||||
|
|
|
@ -199,6 +199,7 @@
|
|||
this.GBGambatteMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.GBGBHawkMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.GBInSGBMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SubNESHawkMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem16 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.allowGameDBCoreOverridesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator();
|
||||
|
@ -1845,6 +1846,7 @@
|
|||
this.SGBCoreSubmenu,
|
||||
this.GBCoreSubmenu,
|
||||
this.GBInSGBMenuItem,
|
||||
this.SubNESHawkMenuItem,
|
||||
this.toolStripMenuItem16,
|
||||
this.allowGameDBCoreOverridesToolStripMenuItem,
|
||||
this.toolStripSeparator8,
|
||||
|
@ -1982,6 +1984,13 @@
|
|||
this.GBInSGBMenuItem.Text = "GB in SGB";
|
||||
this.GBInSGBMenuItem.Click += new System.EventHandler(this.GbInSgbMenuItem_Click);
|
||||
//
|
||||
// SubNESHawkMenuItem
|
||||
//
|
||||
this.SubNESHawkMenuItem.Name = "SubNESHawkMenuItem";
|
||||
this.SubNESHawkMenuItem.Size = new System.Drawing.Size(239, 22);
|
||||
this.SubNESHawkMenuItem.Text = "SubNESHawk";
|
||||
this.SubNESHawkMenuItem.Click += new System.EventHandler(this.SubNESHawkMenuItem_Click);
|
||||
//
|
||||
// toolStripMenuItem16
|
||||
//
|
||||
this.toolStripMenuItem16.Name = "toolStripMenuItem16";
|
||||
|
@ -4532,6 +4541,7 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem MovieSettingsMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem CoresSubMenu;
|
||||
private System.Windows.Forms.ToolStripMenuItem GBInSGBMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SubNESHawkMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem batchRunnerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem DisplayConfigMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem PCEtileViewerToolStripMenuItem;
|
||||
|
|
|
@ -10,6 +10,7 @@ using BizHawk.Emulation.Cores.Atari.A7800Hawk;
|
|||
using BizHawk.Emulation.Cores.Calculators;
|
||||
using BizHawk.Emulation.Cores.ColecoVision;
|
||||
using BizHawk.Emulation.Cores.Nintendo.NES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SubNESHawk;
|
||||
using BizHawk.Emulation.Cores.Nintendo.N64;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES9X;
|
||||
|
@ -1215,6 +1216,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
private void CoresSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
GBInSGBMenuItem.Checked = Global.Config.GB_AsSGB;
|
||||
SubNESHawkMenuItem.Checked = Global.Config.UseSubNESHawk;
|
||||
|
||||
allowGameDBCoreOverridesToolStripMenuItem.Checked = Global.Config.CoreForcingViaGameDB;
|
||||
}
|
||||
|
@ -1308,6 +1310,16 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
private void SubNESHawkMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Global.Config.UseSubNESHawk ^= true;
|
||||
|
||||
if (!Emulator.IsNull())
|
||||
{
|
||||
FlagNeedsReboot();
|
||||
}
|
||||
}
|
||||
|
||||
private void AllowGameDBCoreOverridesToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Global.Config.CoreForcingViaGameDB ^= true;
|
||||
|
@ -1623,6 +1635,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
new NESGraphicsConfig().ShowDialog(this);
|
||||
}
|
||||
else if (Emulator is SubNESHawk)
|
||||
{
|
||||
new NESGraphicsConfig().ShowDialog(this);
|
||||
}
|
||||
else if (Emulator is QuickNES)
|
||||
{
|
||||
new QuickNesConfig().ShowDialog(this);
|
||||
|
@ -1693,6 +1709,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
new NesControllerSettings().ShowDialog();
|
||||
}
|
||||
else if (Emulator is SubNESHawk)
|
||||
{
|
||||
new NesControllerSettings().ShowDialog();
|
||||
}
|
||||
else if (Emulator is QuickNES)
|
||||
{
|
||||
GenericCoreConfig.DoDialog(this, "QuickNES Controller Settings", true, false);
|
||||
|
|
|
@ -1438,7 +1438,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
private void SetWindowText()
|
||||
public void SetWindowText()
|
||||
{
|
||||
string str = "";
|
||||
|
||||
|
@ -2672,6 +2672,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
LinkConnectStatusBarButton.Image = Emulator.AsLinkable().LinkConnected
|
||||
? _linkCableOn
|
||||
: _linkCableOff;
|
||||
|
||||
LinkConnectStatusBarButton.ToolTipText = Emulator.AsLinkable().LinkConnected
|
||||
? "Link connection is currently enabled"
|
||||
: "Link connection is currently disabled";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2964,10 +2968,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
GlobalWin.Tools.UpdateToolsBefore();
|
||||
}
|
||||
|
||||
_framesSinceLastFpsUpdate++;
|
||||
|
||||
UpdateFpsDisplay(currentTimestamp, isRewinding, isFastForwarding);
|
||||
|
||||
CaptureRewind(isRewinding);
|
||||
|
||||
// Set volume, if enabled
|
||||
|
@ -3011,7 +3011,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
|
||||
bool render = !_throttle.skipNextFrame || (_currAviWriter?.UsesVideo ?? false);
|
||||
Emulator.FrameAdvance(Global.ControllerOutput, render, renderSound);
|
||||
bool new_frame = Emulator.FrameAdvance(Global.ControllerOutput, render, renderSound);
|
||||
|
||||
Global.MovieSession.HandleMovieAfterFrameLoop();
|
||||
|
||||
|
@ -3050,11 +3050,18 @@ namespace BizHawk.Client.EmuHawk
|
|||
UpdateToolsAfter(SuppressLua);
|
||||
}
|
||||
|
||||
if (!PauseAvi)
|
||||
if (!PauseAvi && new_frame)
|
||||
{
|
||||
AvFrameAdvance();
|
||||
}
|
||||
|
||||
if (new_frame)
|
||||
{
|
||||
_framesSinceLastFpsUpdate++;
|
||||
|
||||
UpdateFpsDisplay(currentTimestamp, isRewinding, isFastForwarding);
|
||||
}
|
||||
|
||||
if (GlobalWin.Tools.IsLoaded<TAStudio>() &&
|
||||
GlobalWin.Tools.TAStudio.LastPositionFrame == Emulator.Frame)
|
||||
{
|
||||
|
@ -3794,6 +3801,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
ApiManager.Restart(Emulator.ServiceProvider);
|
||||
GlobalWin.Tools.Restart();
|
||||
|
||||
if (Global.Config.LoadCheatFileByGame)
|
||||
|
@ -3842,7 +3850,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
ClientApi.OnRomLoaded();
|
||||
ClientApi.OnRomLoaded(Emulator);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -3853,10 +3861,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
// The ROM has been loaded by a recursive invocation of the LoadROM method.
|
||||
if (!(Emulator is NullEmulator))
|
||||
{
|
||||
ClientApi.OnRomLoaded();
|
||||
ClientApi.OnRomLoaded(Emulator);
|
||||
return true;
|
||||
}
|
||||
|
||||
ClientApi.UpdateEmulatorAndVP(Emulator);
|
||||
HandlePlatformMenus();
|
||||
_stateSlots.Clear();
|
||||
UpdateStatusSlots();
|
||||
|
@ -3946,6 +3955,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
var coreComm = CreateCoreComm();
|
||||
CoreFileProvider.SyncCoreCommInputSignals(coreComm);
|
||||
Emulator = new NullEmulator(coreComm, Global.Config.GetCoreSettings<NullEmulator>());
|
||||
ClientApi.UpdateEmulatorAndVP(Emulator);
|
||||
Global.ActiveController = new Controller(NullController.Instance.Definition);
|
||||
Global.AutoFireController = _autofireNullControls;
|
||||
RewireSound();
|
||||
|
@ -3968,6 +3978,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
Global.Game = GameInfo.NullInstance;
|
||||
|
||||
GlobalWin.Tools.Restart();
|
||||
ApiManager.Restart(Emulator.ServiceProvider);
|
||||
RewireSound();
|
||||
Text = "BizHawk" + (VersionInfo.DeveloperBuild ? " (interim) " : "");
|
||||
HandlePlatformMenus();
|
||||
|
|
|
@ -10,8 +10,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
public partial class AmstradCPCPokeMemory : Form
|
||||
{
|
||||
private AmstradCPC.AmstradCPCSettings _settings;
|
||||
|
||||
public AmstradCPCPokeMemory()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
|
|
@ -87,6 +87,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (Global.Config.DispCustomUserARY != -1)
|
||||
txtCustomARY.Text = Global.Config.DispCustomUserARY.ToString();
|
||||
|
||||
txtCropLeft.Text = Global.Config.DispCropLeft.ToString();
|
||||
txtCropTop.Text = Global.Config.DispCropTop.ToString();
|
||||
txtCropRight.Text = Global.Config.DispCropRight.ToString();
|
||||
txtCropBottom.Text = Global.Config.DispCropBottom.ToString();
|
||||
|
||||
RefreshAspectRatioOptions();
|
||||
|
||||
if (PlatformLinkedLibSingleton.RunningOnUnix)
|
||||
|
@ -193,6 +198,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (rbVulkan.Checked)
|
||||
Global.Config.DispMethod = Config.EDispMethod.Vulkan;
|
||||
|
||||
int.TryParse(txtCropLeft.Text, out Global.Config.DispCropLeft);
|
||||
int.TryParse(txtCropTop.Text, out Global.Config.DispCropTop);
|
||||
int.TryParse(txtCropRight.Text, out Global.Config.DispCropRight);
|
||||
int.TryParse(txtCropBottom.Text, out Global.Config.DispCropBottom);
|
||||
|
||||
if (oldDisplayMethod != Global.Config.DispMethod)
|
||||
NeedReset = true;
|
||||
|
||||
|
|
|
@ -126,4 +126,7 @@
|
|||
<data name="label1.Text" xml:space="preserve">
|
||||
<value>For Windows operating systems >= Vista, with some video cards, the monitors may flicker when going 'windowed fullscreen' while the system disobeys us and goes actual fullscreen instead. This hack prevents that, but may increase frame latency (since in Microsoft's new and disimproved operating systems, windowed mode things may have higher latency)</value>
|
||||
</data>
|
||||
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -5,6 +5,7 @@ using System.Windows.Forms;
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Cores.Nintendo.NES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SubNESHawk;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -15,6 +16,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
// Hotkeys for BG & Sprite display toggle
|
||||
// NTSC filter settings? Hue, Tint (This should probably be a client thing, not a nes specific thing?)
|
||||
private NES _nes;
|
||||
private SubNESHawk _subneshawk;
|
||||
private NES.NESSettings _settings;
|
||||
private Bitmap _bmp;
|
||||
|
||||
|
@ -25,8 +27,17 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void NESGraphicsConfig_Load(object sender, EventArgs e)
|
||||
{
|
||||
_nes = (NES)Global.Emulator;
|
||||
_settings = _nes.GetSettings();
|
||||
if (Global.Emulator is NES)
|
||||
{
|
||||
_nes = (NES)Global.Emulator;
|
||||
_settings = _nes.GetSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
_subneshawk = (SubNESHawk)Global.Emulator;
|
||||
_settings = _subneshawk.GetSettings();
|
||||
}
|
||||
|
||||
LoadStuff();
|
||||
}
|
||||
|
||||
|
@ -146,7 +157,15 @@ namespace BizHawk.Client.EmuHawk
|
|||
_settings.BackgroundColor &= 0x00FFFFFF;
|
||||
}
|
||||
|
||||
_nes.PutSettings(_settings);
|
||||
if (Global.Emulator is NES)
|
||||
{
|
||||
_nes.PutSettings(_settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
_subneshawk.PutSettings(_settings);
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Windows.Forms;
|
|||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Cores.Nintendo.NES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SubNESHawk;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -14,7 +15,15 @@ namespace BizHawk.Client.EmuHawk
|
|||
public NesControllerSettings()
|
||||
{
|
||||
InitializeComponent();
|
||||
_syncSettings = ((NES)Global.Emulator).GetSyncSettings();
|
||||
if (Global.Emulator is NES)
|
||||
{
|
||||
_syncSettings = ((NES)Global.Emulator).GetSyncSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
_syncSettings = ((SubNESHawk)Global.Emulator).GetSyncSettings();
|
||||
}
|
||||
|
||||
|
||||
// TODO: use combobox extension and add descriptions to enum values
|
||||
comboBoxFamicom.Items.AddRange(NESControlSettings.GetFamicomExpansionValues().ToArray());
|
||||
|
|
|
@ -10,8 +10,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
public partial class ZXSpectrumPokeMemory : Form
|
||||
{
|
||||
private ZXSpectrum.ZXSpectrumSettings _settings;
|
||||
|
||||
public ZXSpectrumPokeMemory()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
|
|
@ -511,7 +511,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
|
||||
[LuaMethodExample("gui.drawText( 16, 32, \"Some message\", 0x7F0000FF, 0x00007FFF, 8, \"Arial Narrow\", \"bold\", \"center\", \"middle\" );")]
|
||||
[LuaMethod("drawText", "Draws the given message in the emulator screen space (like all draw functions) at the given x,y coordinates and the given color. The default color is white. A fontfamily can be specified and is monospace generic if none is specified (font family options are the same as the .NET FontFamily class). The fontsize default is 12. The default font style is regular. Font style options are regular, bold, italic, strikethrough, underline. Horizontal alignment options are left (default), center, or right. Vertical alignment options are bottom (default), middle, or top. Alignment options specify which ends of the text will be drawn at the x and y coordinates.")]
|
||||
[LuaMethod("drawText", "Draws the given message in the emulator screen space (like all draw functions) at the given x,y coordinates and the given color. The default color is white. A fontfamily can be specified and is monospace generic if none is specified (font family options are the same as the .NET FontFamily class). The fontsize default is 12. The default font style is regular. Font style options are regular, bold, italic, strikethrough, underline. Horizontal alignment options are left (default), center, or right. Vertical alignment options are bottom (default), middle, or top. Alignment options specify which ends of the text will be drawn at the x and y coordinates. For pixel-perfect font look, make sure to disable aspect ratio correction.")]
|
||||
public void DrawText(
|
||||
int x,
|
||||
int y,
|
||||
|
|
|
@ -169,6 +169,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
_autosaveTimer.Start();
|
||||
}
|
||||
|
||||
Mainform.SetWindowText();
|
||||
GlobalWin.Sound.StartSound();
|
||||
}
|
||||
|
||||
|
@ -267,17 +268,41 @@ namespace BizHawk.Client.EmuHawk
|
|||
private void ToBk2MenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
_autosaveTimer.Stop();
|
||||
var bk2 = CurrentTasMovie.ToBk2(true);
|
||||
var bk2 = CurrentTasMovie.ToBk2(true, true);
|
||||
MessageStatusLabel.Text = "Exporting to .bk2...";
|
||||
Cursor = Cursors.WaitCursor;
|
||||
Update();
|
||||
bk2.Save();
|
||||
string d_exp = " not exported.";
|
||||
var file = new FileInfo(bk2.Filename);
|
||||
if (file.Exists)
|
||||
{
|
||||
GlobalWin.Sound.StopSound();
|
||||
var result = MessageBox.Show(
|
||||
"Overwrite Existing File?",
|
||||
"Tastudio",
|
||||
MessageBoxButtons.YesNoCancel,
|
||||
MessageBoxIcon.Question,
|
||||
MessageBoxDefaultButton.Button3);
|
||||
|
||||
GlobalWin.Sound.StartSound();
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
bk2.Save();
|
||||
d_exp = " exported.";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bk2.Save();
|
||||
d_exp = " exported.";
|
||||
}
|
||||
|
||||
if (Settings.AutosaveInterval > 0)
|
||||
{
|
||||
_autosaveTimer.Start();
|
||||
}
|
||||
|
||||
MessageStatusLabel.Text = bk2.Name + " exported.";
|
||||
MessageStatusLabel.Text = bk2.Name + d_exp;
|
||||
Cursor = Cursors.Default;
|
||||
}
|
||||
|
||||
|
@ -1511,14 +1536,20 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (AskSaveChanges())
|
||||
{
|
||||
int index = TasView.SelectedRows.First();
|
||||
GoToFrame(index);
|
||||
|
||||
TasMovie newProject = CurrentTasMovie.ConvertToSaveRamAnchoredMovie(
|
||||
SaveRamEmulator.CloneSaveRam());
|
||||
|
||||
Mainform.PauseEmulator();
|
||||
LoadFile(new FileInfo(newProject.Filename), true);
|
||||
if (SaveRamEmulator.CloneSaveRam() != null)
|
||||
{
|
||||
int index = 0;
|
||||
if (TasView.SelectedRows.Count() > 0) { index = TasView.SelectedRows.First(); }
|
||||
GoToFrame(index);
|
||||
TasMovie newProject = CurrentTasMovie.ConvertToSaveRamAnchoredMovie(
|
||||
SaveRamEmulator.CloneSaveRam());
|
||||
Mainform.PauseEmulator();
|
||||
LoadFile(new FileInfo(newProject.Filename), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("No SaveRam");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1001,8 +1001,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
"Selected: " + TasView.SelectedRows.Count() + " frame" +
|
||||
(TasView.SelectedRows.Count() == 1 ? "" : "s") +
|
||||
", States: " + CurrentTasMovie.TasStateManager.StateCount.ToString() +
|
||||
", Clipboard: " + (_tasClipboard.Any() ? _tasClipboard.Count + " frame" +
|
||||
(_tasClipboard.Count == 1 ? "" : "s") : "empty");
|
||||
(_tasClipboard.Any()
|
||||
? ", Clipboard: " + _tasClipboard.Count + " frame" + (_tasClipboard.Count == 1 ? "" : "s")
|
||||
: "");
|
||||
}
|
||||
|
||||
private void UpdateChangesIndicator()
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Reflection;
|
|||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Client.ApiHawk;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -66,6 +66,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
continue;
|
||||
if (!ServiceInjector.IsAvailable(Emulator.ServiceProvider, t))
|
||||
continue;
|
||||
// if (!ApiInjector.IsAvailable(, t))
|
||||
// continue;
|
||||
|
||||
// Skip this tool on linux. It isnt finished and it causes exceptions
|
||||
if (t == typeof(HexView) && BizHawk.Common.PlatformLinkedLibSingleton.RunningOnUnix)
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Reflection;
|
|||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Client.ApiHawk;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Client.EmuHawk;
|
||||
using BizHawk.Client.EmuHawk.CoreExtensions;
|
||||
|
@ -123,6 +124,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
(newTool as Form).Owner = GlobalWin.MainForm;
|
||||
}
|
||||
|
||||
if (isExternal)
|
||||
{
|
||||
ApiInjector.UpdateApis(GlobalWin.ApiProvider, newTool);
|
||||
}
|
||||
|
||||
ServiceInjector.UpdateServices(Global.Emulator.ServiceProvider, newTool);
|
||||
string toolType = typeof(T).ToString();
|
||||
|
||||
|
@ -493,6 +499,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if ((tool.IsHandleCreated && !tool.IsDisposed) || tool is RamWatch) // Hack for RAM Watch - in display watches mode it wants to keep running even closed, it will handle disposed logic
|
||||
{
|
||||
if (tool is IExternalToolForm)
|
||||
ApiInjector.UpdateApis(GlobalWin.ApiProvider, tool);
|
||||
tool.Restart();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,4 +112,4 @@
|
|||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
|
@ -33,23 +33,23 @@ namespace BizHawk.Emulation.Common
|
|||
|
||||
public ControllerDefinition ControllerDefinition => NullController.Instance.Definition;
|
||||
|
||||
public void FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
public bool FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
if (render == false)
|
||||
{
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!_settings.SnowyDisplay)
|
||||
{
|
||||
if (_frameBufferClear)
|
||||
{
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
_frameBufferClear = true;
|
||||
Array.Clear(_frameBuffer, 0, 256 * 192);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
_frameBufferClear = false;
|
||||
|
@ -70,6 +70,8 @@ namespace BizHawk.Emulation.Common
|
|||
}
|
||||
|
||||
Frame++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int Frame { get; private set; }
|
||||
|
|
|
@ -121,6 +121,10 @@
|
|||
<Compile Include="Sound\Utilities\Waves.cs" />
|
||||
<Compile Include="SystemLookup.cs" />
|
||||
<Compile Include="TextState.cs" />
|
||||
<Compile Include="WorkingTypes\wshort.cs" />
|
||||
<Compile Include="WorkingTypes\wushort.cs" />
|
||||
<Compile Include="WorkingTypes\wsbyte.cs" />
|
||||
<Compile Include="WorkingTypes\wbyte.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BizHawk.Common\BizHawk.Common.csproj">
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace BizHawk.Emulation.Common
|
|||
/// <param name="render">Whether or not to render video, cores will pass false here in cases such as frame skipping</param>
|
||||
/// <param name="rendersound">Whether or not to render audio, cores will pass here false here in cases such as fast forwarding where bypassing sound may improve speed</param>
|
||||
/// </summary>
|
||||
void FrameAdvance(IController controller, bool render, bool rendersound = true);
|
||||
bool FrameAdvance(IController controller, bool render, bool rendersound = true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current frame count
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Security;
|
||||
|
||||
|
||||
namespace BizHawk.Emulation.Common.WorkingTypes
|
||||
{
|
||||
//
|
||||
// Summary:
|
||||
// Represents an 8-bit unsigned integer, that is capable of arithmetic without making you weep.
|
||||
// Also provides all the base functionality of the standard C# Byte by calling its methods where relevant.
|
||||
public unsafe class wbyte : IComparable, IFormattable, IComparable<wbyte>, IEquatable<wbyte>
|
||||
{
|
||||
private Byte val;
|
||||
public const Byte MaxValue = Byte.MaxValue;
|
||||
public const Byte MinValue = Byte.MinValue;
|
||||
public static implicit operator wbyte(ulong value)
|
||||
{
|
||||
return new wbyte(value);
|
||||
}
|
||||
public static implicit operator wbyte(wushort value)
|
||||
{
|
||||
return new wbyte(value);
|
||||
}
|
||||
public static implicit operator byte(wbyte value)
|
||||
{
|
||||
return value.val;
|
||||
}
|
||||
public wbyte()
|
||||
{
|
||||
|
||||
}
|
||||
public wbyte(ulong value)
|
||||
{
|
||||
val = (Byte)(value & 0xFF);
|
||||
}
|
||||
public wbyte(long value)
|
||||
{
|
||||
val = (Byte)(value & 0xFF);
|
||||
}
|
||||
public wbyte(double value)
|
||||
{
|
||||
val = (Byte)(((long)value) & 0xFF);
|
||||
}
|
||||
public static wbyte Parse(string s, NumberStyles style, IFormatProvider provider)
|
||||
{
|
||||
return (ulong)Byte.Parse(s, style, provider);
|
||||
}
|
||||
public static wbyte Parse(string s, IFormatProvider provider)
|
||||
{
|
||||
return (ulong)Byte.Parse(s, provider);
|
||||
}
|
||||
public static wbyte Parse(string s)
|
||||
{
|
||||
return (ulong)Byte.Parse(s);
|
||||
}
|
||||
public static wbyte Parse(string s, NumberStyles style)
|
||||
{
|
||||
return (ulong)Byte.Parse(s, style);
|
||||
}
|
||||
public static bool TryParse(string s, out wbyte result)
|
||||
{
|
||||
result = new wbyte();
|
||||
return byte.TryParse(s, out result.val);
|
||||
}
|
||||
public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out wbyte result)
|
||||
{
|
||||
result = new wbyte();
|
||||
return byte.TryParse(s, style, provider, out result.val);
|
||||
}
|
||||
public int CompareTo(wbyte value)
|
||||
{
|
||||
return val.CompareTo(value.val);
|
||||
}
|
||||
public int CompareTo(object value)
|
||||
{
|
||||
return val.CompareTo(value);
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return val.Equals(obj);
|
||||
}
|
||||
public bool Equals(wbyte obj)
|
||||
{
|
||||
return val.Equals(obj);
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return val.GetHashCode();
|
||||
}
|
||||
public TypeCode GetTypeCode()
|
||||
{
|
||||
return val.GetTypeCode();
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(string format, IFormatProvider provider)
|
||||
{
|
||||
return val.ToString(format, provider);
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public override string ToString()
|
||||
{
|
||||
return val.ToString();
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(string format)
|
||||
{
|
||||
return val.ToString(format);
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(IFormatProvider provider)
|
||||
{
|
||||
return val.ToString(provider);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Security;
|
||||
|
||||
namespace BizHawk.Emulation.Common.WorkingTypes
|
||||
{
|
||||
//
|
||||
// Summary:
|
||||
// Represents an 8-bit unsigned integer, that is capable of arithmetic without making you weep.
|
||||
// Also provides all the base functionality of the standard C# SByte by calling its methods where relevant.
|
||||
public unsafe class wsbyte : IComparable, IFormattable, IComparable<wsbyte>, IEquatable<wsbyte>
|
||||
{
|
||||
private SByte val;
|
||||
public const SByte MaxValue = SByte.MaxValue;
|
||||
public const SByte MinValue = SByte.MinValue;
|
||||
public static implicit operator wsbyte(long value)
|
||||
{
|
||||
return new wsbyte(value);
|
||||
}
|
||||
public static implicit operator SByte(wsbyte value)
|
||||
{
|
||||
return value.val;
|
||||
}
|
||||
public wsbyte()
|
||||
{
|
||||
|
||||
}
|
||||
public wsbyte(long value)
|
||||
{
|
||||
val = (SByte)(value & 0xFF);
|
||||
}
|
||||
public wsbyte(ulong value)
|
||||
{
|
||||
val = (SByte)(value & 0xFF);
|
||||
}
|
||||
public wsbyte(double value)
|
||||
{
|
||||
val = (SByte)(((ulong)value) & 0xFF);
|
||||
}
|
||||
public static wsbyte Parse(string s, NumberStyles style, IFormatProvider provider)
|
||||
{
|
||||
return (long)SByte.Parse(s, style, provider);
|
||||
}
|
||||
public static wsbyte Parse(string s, IFormatProvider provider)
|
||||
{
|
||||
return (long)SByte.Parse(s, provider);
|
||||
}
|
||||
public static wsbyte Parse(string s)
|
||||
{
|
||||
return (long)SByte.Parse(s);
|
||||
}
|
||||
public static wsbyte Parse(string s, NumberStyles style)
|
||||
{
|
||||
return (long)SByte.Parse(s, style);
|
||||
}
|
||||
public static bool TryParse(string s, out wsbyte result)
|
||||
{
|
||||
result = new wsbyte();
|
||||
return SByte.TryParse(s, out result.val);
|
||||
}
|
||||
public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out wsbyte result)
|
||||
{
|
||||
result = new wsbyte();
|
||||
return SByte.TryParse(s, style, provider, out result.val);
|
||||
}
|
||||
public int CompareTo(wsbyte value)
|
||||
{
|
||||
return val.CompareTo(value.val);
|
||||
}
|
||||
public int CompareTo(object value)
|
||||
{
|
||||
return val.CompareTo(value);
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return val.Equals(obj);
|
||||
}
|
||||
public bool Equals(wsbyte obj)
|
||||
{
|
||||
return val.Equals(obj);
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return val.GetHashCode();
|
||||
}
|
||||
public TypeCode GetTypeCode()
|
||||
{
|
||||
return val.GetTypeCode();
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(string format, IFormatProvider provider)
|
||||
{
|
||||
return val.ToString(format, provider);
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public override string ToString()
|
||||
{
|
||||
return val.ToString();
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(string format)
|
||||
{
|
||||
return val.ToString(format);
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(IFormatProvider provider)
|
||||
{
|
||||
return val.ToString(provider);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Security;
|
||||
|
||||
namespace BizHawk.Emulation.Common.WorkingTypes
|
||||
{
|
||||
//
|
||||
// Summary:
|
||||
// Represents an 16-bit unsigned integer, that is capable of arithmetic without making you weep.
|
||||
// Also provides all the base functionality of the standard C# Int16 by calling its methods where relevant.
|
||||
public unsafe class wshort : IComparable, IFormattable, IComparable<wshort>, IEquatable<wshort>
|
||||
{
|
||||
private Int16 val;
|
||||
public const Int16 MaxValue = Int16.MaxValue;
|
||||
public const Int16 MinValue = Int16.MinValue;
|
||||
public static implicit operator wshort(long value)
|
||||
{
|
||||
return new wshort(value);
|
||||
}
|
||||
public static implicit operator Int16(wshort value)
|
||||
{
|
||||
return value.val;
|
||||
}
|
||||
public wshort()
|
||||
{
|
||||
|
||||
}
|
||||
public wshort(long value)
|
||||
{
|
||||
val = (Int16)(value & 0xFFFF);
|
||||
}
|
||||
public wshort(ulong value)
|
||||
{
|
||||
val = (Int16)(value & 0xFFFF);
|
||||
}
|
||||
public wshort(double value)
|
||||
{
|
||||
val = (Int16)(((ulong)value) & 0xFFFF);
|
||||
}
|
||||
public static wshort Parse(string s, NumberStyles style, IFormatProvider provider)
|
||||
{
|
||||
return (long)Int16.Parse(s, style, provider);
|
||||
}
|
||||
public static wshort Parse(string s, IFormatProvider provider)
|
||||
{
|
||||
return (long)Int16.Parse(s, provider);
|
||||
}
|
||||
public static wshort Parse(string s)
|
||||
{
|
||||
return (long)Int16.Parse(s);
|
||||
}
|
||||
public static wshort Parse(string s, NumberStyles style)
|
||||
{
|
||||
return (long)Int16.Parse(s, style);
|
||||
}
|
||||
public static bool TryParse(string s, out wshort result)
|
||||
{
|
||||
result = new wshort();
|
||||
return Int16.TryParse(s, out result.val);
|
||||
}
|
||||
public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out wshort result)
|
||||
{
|
||||
result = new wshort();
|
||||
return Int16.TryParse(s, style, provider, out result.val);
|
||||
}
|
||||
public int CompareTo(wshort value)
|
||||
{
|
||||
return val.CompareTo(value.val);
|
||||
}
|
||||
public int CompareTo(object value)
|
||||
{
|
||||
return val.CompareTo(value);
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return val.Equals(obj);
|
||||
}
|
||||
public bool Equals(wshort obj)
|
||||
{
|
||||
return val.Equals(obj);
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return val.GetHashCode();
|
||||
}
|
||||
public TypeCode GetTypeCode()
|
||||
{
|
||||
return val.GetTypeCode();
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(string format, IFormatProvider provider)
|
||||
{
|
||||
return val.ToString(format, provider);
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public override string ToString()
|
||||
{
|
||||
return val.ToString();
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(string format)
|
||||
{
|
||||
return val.ToString(format);
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(IFormatProvider provider)
|
||||
{
|
||||
return val.ToString(provider);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Security;
|
||||
|
||||
|
||||
namespace BizHawk.Emulation.Common.WorkingTypes
|
||||
{
|
||||
//
|
||||
// Summary:
|
||||
// Represents an 16-bit unsigned integer, that is capable of arithmetic without making you weep.
|
||||
// Also provides all the base functionality of the standard C# UInt16 by calling its methods where relevant.
|
||||
public unsafe class wushort : IComparable, IFormattable, IComparable<wushort>, IEquatable<wushort>
|
||||
{
|
||||
private UInt16 val;
|
||||
public const UInt16 MaxValue = UInt16.MaxValue;
|
||||
public const UInt16 MinValue = UInt16.MinValue;
|
||||
public static implicit operator wushort(ulong value)
|
||||
{
|
||||
return new wushort(value);
|
||||
}
|
||||
public static implicit operator wushort(wbyte value)
|
||||
{
|
||||
return new wushort(value);
|
||||
}
|
||||
public static implicit operator UInt16(wushort value)
|
||||
{
|
||||
return value.val;
|
||||
}
|
||||
public wushort()
|
||||
{
|
||||
|
||||
}
|
||||
public wushort(ulong value)
|
||||
{
|
||||
val = (UInt16)(value & 0xFFFF);
|
||||
}
|
||||
public wushort(long value)
|
||||
{
|
||||
val = (UInt16)(value & 0xFFFF);
|
||||
}
|
||||
public wushort(double value)
|
||||
{
|
||||
val = (UInt16)(((long)value) & 0xFFFF);
|
||||
}
|
||||
public static wushort Parse(string s, NumberStyles style, IFormatProvider provider)
|
||||
{
|
||||
return (uint)UInt16.Parse(s, style, provider);
|
||||
}
|
||||
public static wushort Parse(string s, IFormatProvider provider)
|
||||
{
|
||||
return (uint)UInt16.Parse(s, provider);
|
||||
}
|
||||
public static wushort Parse(string s)
|
||||
{
|
||||
return (uint)UInt16.Parse(s);
|
||||
}
|
||||
public static wushort Parse(string s, NumberStyles style)
|
||||
{
|
||||
return (uint)UInt16.Parse(s, style);
|
||||
}
|
||||
public static bool TryParse(string s, out wushort result)
|
||||
{
|
||||
result = new wushort();
|
||||
return ushort.TryParse(s, out result.val);
|
||||
}
|
||||
public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out wushort result)
|
||||
{
|
||||
result = new wushort();
|
||||
return ushort.TryParse(s, style, provider, out result.val);
|
||||
}
|
||||
public int CompareTo(wushort value)
|
||||
{
|
||||
return val.CompareTo(value.val);
|
||||
}
|
||||
public int CompareTo(object value)
|
||||
{
|
||||
return val.CompareTo(value);
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return val.Equals(obj);
|
||||
}
|
||||
public bool Equals(wushort obj)
|
||||
{
|
||||
return val.Equals(obj);
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return val.GetHashCode();
|
||||
}
|
||||
public TypeCode GetTypeCode()
|
||||
{
|
||||
return val.GetTypeCode();
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(string format, IFormatProvider provider)
|
||||
{
|
||||
return val.ToString(format, provider);
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public override string ToString()
|
||||
{
|
||||
return val.ToString();
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(string format)
|
||||
{
|
||||
return val.ToString(format);
|
||||
}
|
||||
[SecuritySafeCritical]
|
||||
public string ToString(IFormatProvider provider)
|
||||
{
|
||||
return val.ToString(provider);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -317,9 +317,9 @@
|
|||
<Compile Include="Computers\Commodore64\SaveState.cs" />
|
||||
<Compile Include="Computers\Commodore64\User\UserPortDevice.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IFDDHost.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\StandardKeyboard.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\StandardKeyboard.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\AY38912.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\Beeper.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\Beeper.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Media\Disk\FloppyDisk.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IJoystick.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IPortIODevice.cs" />
|
||||
|
@ -327,23 +327,23 @@
|
|||
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\CHRN.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.Definitions.cs">
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.FDC.cs">
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.FDD.cs">
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.IPortIODevice.cs">
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.Timing.cs">
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPS765.Static.cs">
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>NECUPD765.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\CursorJoystick.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\SinclairJoystick2.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\SinclairJoystick1.cs" />
|
||||
|
@ -375,93 +375,93 @@
|
|||
<Compile Include="Computers\SinclairSpectrum\Machine\MachineType.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Input.cs">
|
||||
<DependentUpon>SpectrumBase.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>SpectrumBase.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Port.cs">
|
||||
<DependentUpon>SpectrumBase.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>SpectrumBase.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Memory.cs">
|
||||
<DependentUpon>SpectrumBase.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Media.cs">
|
||||
<DependentUpon>SpectrumBase.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ULA.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\CPUMonitor.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.cs" />
|
||||
<DependentUpon>SpectrumBase.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Media.cs">
|
||||
<DependentUpon>SpectrumBase.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ULA.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\CPUMonitor.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Memory.cs">
|
||||
<DependentUpon>ZX48.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Port.cs">
|
||||
<DependentUpon>ZX48.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZX48.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Port.cs">
|
||||
<DependentUpon>ZX48.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Screen.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum16K\ZX16.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum16K\ZX16.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Memory.cs">
|
||||
<DependentUpon>ZX128.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZX128.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Port.cs">
|
||||
<DependentUpon>ZX128.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZX128.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Screen.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2\ZX128Plus2.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2\ZX128Plus2.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Memory.cs">
|
||||
<DependentUpon>ZX128Plus2a.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZX128Plus2a.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Port.cs">
|
||||
<DependentUpon>ZX128Plus2a.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Screen.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.cs" />
|
||||
<DependentUpon>ZX128Plus2a.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Screen.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.Memory.cs">
|
||||
<DependentUpon>ZX128Plus3.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZX128Plus3.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.Port.cs">
|
||||
<DependentUpon>ZX128Plus3.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZX128Plus3.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Memory.cs">
|
||||
<DependentUpon>Pentagon128.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>Pentagon128.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Port.cs">
|
||||
<DependentUpon>Pentagon128.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Screen.cs" />
|
||||
<None Include="Computers\SinclairSpectrum\readme.md" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Rom\RomData.cs" />
|
||||
<DependentUpon>Pentagon128.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Screen.cs" />
|
||||
<None Include="Computers\SinclairSpectrum\readme.md" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Rom\RomData.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IDebuggable.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IEmulator.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IInputPollable.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.ICodeDataLog.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IMemoryDomains.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.ISettable.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IStatable.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Messaging.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Util.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Controllers.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Controllers.cs">
|
||||
<DependentUpon>ZXSpectrum.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Atari\2600\Atari2600.cs" />
|
||||
<Compile Include="Consoles\Atari\2600\Atari2600.Core.cs">
|
||||
<DependentUpon>Atari2600.cs</DependentUpon>
|
||||
|
@ -789,7 +789,7 @@
|
|||
<DependentUpon>VBANext.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\GBA\VBARegisterHelper.cs" />
|
||||
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.cs" />
|
||||
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.cs" />
|
||||
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.ICodeDataLog.cs" />
|
||||
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.IDebuggable.cs">
|
||||
<DependentUpon>GBHawkLink.cs</DependentUpon>
|
||||
|
@ -1201,6 +1201,25 @@
|
|||
<Compile Include="Consoles\Nintendo\NES\PPU.regs.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\PPU.run.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Unif.cs" />
|
||||
<Compile Include="Consoles\Nintendo\SubNESHawk\SubNESHawk.cs" />
|
||||
<Compile Include="Consoles\Nintendo\SubNESHawk\SubNESHawk.IDebuggable.cs">
|
||||
<DependentUpon>SubNESHawk.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\SubNESHawk\SubNESHawk.IEmulator.cs">
|
||||
<DependentUpon>SubNESHawk.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\SubNESHawk\SubNESHawk.IInputPollable.cs">
|
||||
<DependentUpon>SubNESHawk.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\SubNESHawk\SubNESHawk.IMemoryDomains.cs">
|
||||
<DependentUpon>SubNESHawk.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\SubNESHawk\SubNESHawk.ISaveRam.cs">
|
||||
<DependentUpon>SubNESHawk.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\SubNESHawk\SubNESHawk.IStatable.cs">
|
||||
<DependentUpon>SubNESHawk.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\QuickNES\LibQuickNES.cs" />
|
||||
<Compile Include="Consoles\Nintendo\QuickNES\Nes_NTSC_Colors.cs" />
|
||||
<Compile Include="Consoles\Nintendo\QuickNES\QuickNES.cs" />
|
||||
|
|
|
@ -189,7 +189,7 @@ namespace BizHawk.Emulation.Cores.Components.M68000
|
|||
int pc = info.PC + 2;
|
||||
int size = (op >> 6) & 3;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 3;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
|
@ -516,7 +516,7 @@ namespace BizHawk.Emulation.Cores.Components.M68000
|
|||
int pc = info.PC + 2;
|
||||
int size = (op >> 6) & 3;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 3;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
|
@ -1147,4 +1147,4 @@ namespace BizHawk.Emulation.Cores.Components.M68000
|
|||
info.Length = pc - info.PC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
"{0:X4}: {1,-9} {2} ",
|
||||
PC, rawbytes, disasm).PadRight(32),
|
||||
RegisterInfo = string.Format(
|
||||
"A:{0:X2} X:{1:X2} Y:{2:X2} SP:{4:X2} P:{3:X2} {6}{7}{8}{9}{10}{11}{12}{13} Cy:{5}",
|
||||
"A:{0:X2} X:{1:X2} Y:{2:X2} SP:{4:X2} P:{3:X2} {6}{7}{8}{9}{10}{11}{12}{13} Cy:{5} PPU-Cy:{15}",
|
||||
A, X, Y, P, S, TotalExecutedCycles,
|
||||
FlagN ? "N" : "n",
|
||||
FlagV ? "V" : "v",
|
||||
|
@ -84,7 +84,8 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
FlagI ? "I" : "i",
|
||||
FlagZ ? "Z" : "z",
|
||||
FlagC ? "C" : "c",
|
||||
!RDY ? "R" : "r")
|
||||
!RDY ? "R" : "r",
|
||||
ext_ppu_cycle)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -120,6 +121,9 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
public bool NMI;
|
||||
public bool RDY;
|
||||
|
||||
// ppu cycle (used with SubNESHawk)
|
||||
public int ext_ppu_cycle = 0;
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("MOS6502X");
|
||||
|
@ -143,6 +147,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
ser.Sync("interrupt_pending", ref interrupt_pending);
|
||||
ser.Sync("branch_irq_hack", ref branch_irq_hack);
|
||||
ser.Sync("rdy_freeze", ref rdy_freeze);
|
||||
ser.Sync("ext_ppu_cycle", ref ext_ppu_cycle);
|
||||
ser.EndSection();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
|
||||
public ControllerDefinition ControllerDefinition => TI83Controller;
|
||||
|
||||
public void FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
public bool FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
_controller = controller;
|
||||
_lagged = true;
|
||||
|
@ -59,6 +59,8 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
}
|
||||
|
||||
_isLag = _lagged;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int Frame
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
|
||||
public ControllerDefinition ControllerDefinition { get; set; }
|
||||
|
||||
public void FrameAdvance(IController controller, bool render, bool renderSound)
|
||||
public bool FrameAdvance(IController controller, bool render, bool renderSound)
|
||||
{
|
||||
_controller = controller;
|
||||
|
||||
|
@ -42,6 +42,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
{
|
||||
_lagCount++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int Frame
|
||||
|
|
|
@ -238,7 +238,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
|
||||
// output the data splitting and tabbing as neccessary
|
||||
var arr = d.Value.Split(' ');
|
||||
int cnt = 0;
|
||||
|
||||
List<string> builder = new List<string>();
|
||||
string working = "";
|
||||
|
|
|
@ -394,6 +394,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
sectorSize = 0x80 << ActiveCommandParams.SectorSize;
|
||||
}
|
||||
|
||||
var mtc = maxTransferCap;
|
||||
|
||||
// get the current track
|
||||
var track = ActiveDrive.Disk.DiskTracks.Where(a => a.TrackNumber == ActiveDrive.CurrentTrackID).FirstOrDefault();
|
||||
|
||||
|
@ -655,6 +657,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
int buffPos = 0;
|
||||
int sectorSize = 0;
|
||||
int maxTransferCap = 0;
|
||||
if (maxTransferCap > 0) { }
|
||||
|
||||
// calculate requested size of data required
|
||||
if (ActiveCommandParams.SectorSize == 0)
|
||||
|
@ -967,6 +970,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
int buffPos = 0;
|
||||
int sectorSize = 0;
|
||||
int maxTransferCap = 0;
|
||||
if (maxTransferCap > 0) { }
|
||||
|
||||
// calculate requested size of data required
|
||||
if (ActiveCommandParams.SectorSize == 0)
|
||||
|
@ -1031,7 +1035,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
break;
|
||||
}
|
||||
|
||||
FloppyDisk.Sector sector = null;
|
||||
//FloppyDisk.Sector sector = null;
|
||||
ActiveDrive.SectorIndex = 0;
|
||||
|
||||
int secCount = 0;
|
||||
|
@ -1371,7 +1375,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
|
||||
// get the first sector
|
||||
var track = ActiveDrive.Disk.DiskTracks[ActiveCommandParams.Cylinder];
|
||||
int secIndex = 0;
|
||||
//int secIndex = 0;
|
||||
for (int s = 0; s < track.Sectors.Length; s++)
|
||||
{
|
||||
if (track.Sectors[s].SectorID == endSecID)
|
||||
|
@ -1422,7 +1426,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
byte endSecID = ActiveCommandParams.EOT;
|
||||
bool lastSec = false;
|
||||
var track = ActiveDrive.Disk.DiskTracks[ActiveCommandParams.Cylinder];
|
||||
int secIndex = 0;
|
||||
//int secIndex = 0;
|
||||
|
||||
for (int s = 0; s < track.Sectors.Length; s++)
|
||||
{
|
||||
|
@ -1664,7 +1668,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
|
||||
// get the first sector
|
||||
var track = ActiveDrive.Disk.DiskTracks[ActiveCommandParams.Cylinder];
|
||||
int secIndex = 0;
|
||||
//int secIndex = 0;
|
||||
for (int s = 0; s < track.Sectors.Length; s++)
|
||||
{
|
||||
if (track.Sectors[s].SectorID == endSecID)
|
||||
|
@ -1715,7 +1719,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
byte endSecID = ActiveCommandParams.EOT;
|
||||
bool lastSec = false;
|
||||
var track = ActiveDrive.Disk.DiskTracks[ActiveCommandParams.Cylinder];
|
||||
int secIndex = 0;
|
||||
//int secIndex = 0;
|
||||
|
||||
for (int s = 0; s < track.Sectors.Length; s++)
|
||||
{
|
||||
|
@ -2397,18 +2401,12 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
break;
|
||||
}
|
||||
|
||||
//if (!CheckTiming())
|
||||
//{
|
||||
// UnSetBit(MSR_EXM, ref StatusMain);
|
||||
//}
|
||||
|
||||
return StatusMain;
|
||||
}
|
||||
private int testCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Handles CPU reading from the data register
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private byte ReadDataRegister()
|
||||
{
|
||||
// default return value
|
||||
|
|
|
@ -1103,7 +1103,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
ScreenLines.Clear();
|
||||
|
||||
return ScreenBuffer;
|
||||
|
||||
/*
|
||||
switch (borderType)
|
||||
{
|
||||
// crop to 768x272 (544)
|
||||
|
@ -1139,18 +1139,19 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
return croppedBuffer;
|
||||
*/
|
||||
/*
|
||||
var slWidth = BufferWidth;
|
||||
return ScreenBuffer;
|
||||
|
||||
var slWidth = BufferWidth;
|
||||
return ScreenBuffer;
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return ScreenBuffer;
|
||||
}
|
||||
}
|
||||
*/
|
||||
//return ScreenBuffer;
|
||||
}
|
||||
|
||||
public void SetupScreenSize()
|
||||
public void SetupScreenSize()
|
||||
{
|
||||
SysBufferWidth = 800;
|
||||
SysBufferHeight = 600;
|
||||
|
|
|
@ -28,8 +28,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
private short[] _audioBuffer;
|
||||
private int _audioBufferIndex;
|
||||
private int _lastStateRendered;
|
||||
private int _clockCyclesPerFrame;
|
||||
private int _cyclesPerSample;
|
||||
//private int _clockCyclesPerFrame;
|
||||
//private int _cyclesPerSample;
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -216,14 +216,14 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
private int CurrentPen;
|
||||
private int ScreenMode;
|
||||
private int INTScanlineCnt;
|
||||
private int VSYNCDelyCnt;
|
||||
//private int VSYNCDelyCnt;
|
||||
|
||||
private int[][] Lookup = new int[4][];
|
||||
|
||||
private bool DoModeUpdate;
|
||||
//private bool DoModeUpdate;
|
||||
|
||||
private int LatchedMode;
|
||||
private int buffPos;
|
||||
//private int LatchedMode;
|
||||
//private int buffPos;
|
||||
|
||||
public bool FrameEnd;
|
||||
|
||||
|
@ -387,7 +387,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
for (int i = 0; i < 17; i++)
|
||||
PenColours[i] = 0;
|
||||
INTScanlineCnt = 0;
|
||||
VSYNCDelyCnt = 0;
|
||||
//VSYNCDelyCnt = 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
tb.PauseInMS = db.PauseInMS;
|
||||
|
||||
double multiplier = (double)4 / (double)3.5;
|
||||
double cycleScale = ((40 << 16) / 35);
|
||||
//double cycleScale = ((40 << 16) / 35);
|
||||
double origPeriods = db.DataPeriods.Count();
|
||||
|
||||
for (int i = 0; i < origPeriods; i++)
|
||||
|
@ -1372,7 +1372,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
// get text length
|
||||
int strLen = data[_position++];
|
||||
|
||||
string title = "Info: ";
|
||||
string title = string.Empty;
|
||||
title = "Info: ";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
set { _blockData = value; }
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// An array of bytearray encoded strings (stored in this format for easy Bizhawk serialization)
|
||||
/// Its basically tape information
|
||||
|
@ -74,6 +75,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
return data;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#region Block Meta Data
|
||||
|
|
|
@ -14,9 +14,11 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
|
||||
public bool DeterministicEmulation => true;
|
||||
|
||||
public void FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
public bool FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
FrameAdv(controller, render, rendersound);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ResetCounters()
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
|
||||
public ControllerDefinition ControllerDefinition => C64ControllerDefinition;
|
||||
|
||||
public void FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
public bool FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
_board.Controller = controller;
|
||||
|
||||
|
@ -47,6 +47,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
DoCycle();
|
||||
}
|
||||
while (_frameCycles != 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int Frame => _frame;
|
||||
|
|
|
@ -362,6 +362,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// calculate maximum transfer capacity
|
||||
if (!CMD_FLAG_MF)
|
||||
maxTransferCap = 3328;
|
||||
|
||||
if (maxTransferCap == 0) { }
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -655,6 +657,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
int buffPos = 0;
|
||||
int sectorSize = 0;
|
||||
int maxTransferCap = 0;
|
||||
if (maxTransferCap > 0) { }
|
||||
|
||||
// calculate requested size of data required
|
||||
if (ActiveCommandParams.SectorSize == 0)
|
||||
|
@ -967,6 +970,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
int buffPos = 0;
|
||||
int sectorSize = 0;
|
||||
int maxTransferCap = 0;
|
||||
if (maxTransferCap > 0) { }
|
||||
|
||||
// calculate requested size of data required
|
||||
if (ActiveCommandParams.SectorSize == 0)
|
||||
|
@ -1031,7 +1035,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
break;
|
||||
}
|
||||
|
||||
FloppyDisk.Sector sector = null;
|
||||
//FloppyDisk.Sector sector = null;
|
||||
ActiveDrive.SectorIndex = 0;
|
||||
|
||||
int secCount = 0;
|
||||
|
@ -1371,7 +1375,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
// get the first sector
|
||||
var track = ActiveDrive.Disk.DiskTracks[ActiveCommandParams.Cylinder];
|
||||
int secIndex = 0;
|
||||
//int secIndex = 0;
|
||||
for (int s = 0; s < track.Sectors.Length; s++)
|
||||
{
|
||||
if (track.Sectors[s].SectorID == endSecID)
|
||||
|
@ -1422,7 +1426,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
byte endSecID = ActiveCommandParams.EOT;
|
||||
bool lastSec = false;
|
||||
var track = ActiveDrive.Disk.DiskTracks[ActiveCommandParams.Cylinder];
|
||||
int secIndex = 0;
|
||||
//int secIndex = 0;
|
||||
|
||||
for (int s = 0; s < track.Sectors.Length; s++)
|
||||
{
|
||||
|
@ -1664,7 +1668,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
// get the first sector
|
||||
var track = ActiveDrive.Disk.DiskTracks[ActiveCommandParams.Cylinder];
|
||||
int secIndex = 0;
|
||||
//int secIndex = 0;
|
||||
for (int s = 0; s < track.Sectors.Length; s++)
|
||||
{
|
||||
if (track.Sectors[s].SectorID == endSecID)
|
||||
|
@ -1715,7 +1719,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
byte endSecID = ActiveCommandParams.EOT;
|
||||
bool lastSec = false;
|
||||
var track = ActiveDrive.Disk.DiskTracks[ActiveCommandParams.Cylinder];
|
||||
int secIndex = 0;
|
||||
//int secIndex = 0;
|
||||
|
||||
for (int s = 0; s < track.Sectors.Length; s++)
|
||||
{
|
||||
|
@ -2404,7 +2408,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
return StatusMain;
|
||||
}
|
||||
private int testCount = 0;
|
||||
|
||||
//private int testCount = 0;
|
||||
/// <summary>
|
||||
/// Handles CPU reading from the data register
|
||||
/// </summary>
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
public class CursorJoystick : IJoystick
|
||||
{
|
||||
private int _joyLine;
|
||||
//private int _joyLine;
|
||||
private SpectrumBase _machine;
|
||||
|
||||
#region Construction
|
||||
|
@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public CursorJoystick(SpectrumBase machine, int playerNumber)
|
||||
{
|
||||
_machine = machine;
|
||||
_joyLine = 0;
|
||||
//_joyLine = 0;
|
||||
_playerNumber = playerNumber;
|
||||
|
||||
ButtonCollection = new List<string>
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
public class SinclairJoystick1 : IJoystick
|
||||
{
|
||||
private int _joyLine;
|
||||
//private int _joyLine;
|
||||
private SpectrumBase _machine;
|
||||
|
||||
#region Construction
|
||||
|
@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public SinclairJoystick1(SpectrumBase machine, int playerNumber)
|
||||
{
|
||||
_machine = machine;
|
||||
_joyLine = 0;
|
||||
//_joyLine = 0;
|
||||
_playerNumber = playerNumber;
|
||||
|
||||
ButtonCollection = new List<string>
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
public class SinclairJoystick2 : IJoystick
|
||||
{
|
||||
private int _joyLine;
|
||||
//private int _joyLine;
|
||||
private SpectrumBase _machine;
|
||||
|
||||
#region Construction
|
||||
|
@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public SinclairJoystick2(SpectrumBase machine, int playerNumber)
|
||||
{
|
||||
_machine = machine;
|
||||
_joyLine = 0;
|
||||
//_joyLine = 0;
|
||||
_playerNumber = playerNumber;
|
||||
|
||||
ButtonCollection = new List<string>
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
var e = ex.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -141,9 +141,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
s1Pos += blockSize;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -335,7 +335,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
}
|
||||
|
||||
// add block pause
|
||||
int actualPause = PAUSE_MS * 1000;
|
||||
//int actualPause = PAUSE_MS * 1000;
|
||||
//dataPeriods.Add(actualPause);
|
||||
|
||||
// default pause for tap files
|
||||
|
|
|
@ -1312,9 +1312,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// get text length
|
||||
int strLen = data[_position++];
|
||||
|
||||
string title = "Info: ";
|
||||
string title = String.Empty;
|
||||
title = "Info: ";
|
||||
|
||||
switch (type)
|
||||
switch (type)
|
||||
{
|
||||
case 0x00:
|
||||
title = "Full Title: ";
|
||||
|
|
|
@ -51,6 +51,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
set { _blockData = value; }
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/// <summary>
|
||||
/// An array of bytearray encoded strings (stored in this format for easy Bizhawk serialization)
|
||||
/// Its basically tape information
|
||||
|
@ -74,6 +76,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
return data;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#region Block Meta Data
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <summary>
|
||||
/// Position counter
|
||||
/// </summary>
|
||||
private int _position = 0;
|
||||
//private int _position = 0;
|
||||
|
||||
#region Construction
|
||||
|
||||
|
@ -91,7 +91,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
"This is not a valid WAV format file");
|
||||
}
|
||||
|
||||
_position = 0;
|
||||
//_position = 0;
|
||||
|
||||
MemoryStream stream = new MemoryStream();
|
||||
stream.Write(data, 0, data.Length);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue