777 lines
22 KiB
C#
777 lines
22 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using BizHawk.Client.Common;
|
|
using BizHawk.Common;
|
|
using BizHawk.Emulation.Common;
|
|
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
|
|
using BizHawk.Emulation.Cores.PCEngine;
|
|
using BizHawk.Emulation.Cores.Sega.MasterSystem;
|
|
|
|
// ReSharper disable UnusedMember.Global
|
|
namespace BizHawk.Client.ApiHawk
|
|
{
|
|
/// <summary>
|
|
/// This class contains some methods that
|
|
/// interact with BizHawk client
|
|
/// </summary>
|
|
public static class ClientApi
|
|
{
|
|
#region Fields
|
|
|
|
private static IEmulator Emulator { get; set; }
|
|
private static IVideoProvider VideoProvider { get; set; }
|
|
|
|
private static readonly Assembly ClientAssembly;
|
|
private static readonly object ClientMainFormInstance;
|
|
private static readonly Type MainFormClass;
|
|
private static readonly Array JoypadButtonsArray = Enum.GetValues(typeof(JoypadButton));
|
|
|
|
internal static readonly BizHawkSystemIdToEnumConverter SystemIdConverter = new BizHawkSystemIdToEnumConverter();
|
|
internal static readonly JoypadStringToEnumConverter JoypadConverter = new JoypadStringToEnumConverter();
|
|
|
|
private static List<Joypad> _allJoyPads;
|
|
|
|
/// <summary>
|
|
/// Occurs before a quickload is done (just after user has pressed the shortcut button
|
|
/// or has click on the item menu)
|
|
/// </summary>
|
|
public static event BeforeQuickLoadEventHandler BeforeQuickLoad;
|
|
/// <summary>
|
|
/// Occurs before a quicksave is done (just after user has pressed the shortcut button
|
|
/// or has click on the item menu)
|
|
/// </summary>
|
|
public static event BeforeQuickSaveEventHandler BeforeQuickSave;
|
|
/// <summary>
|
|
/// Occurs when a ROM is successfully loaded
|
|
/// </summary>
|
|
public static event EventHandler RomLoaded;
|
|
/// <summary>
|
|
/// Occurs when a savestate is successfully loaded
|
|
/// </summary>
|
|
public static event StateLoadedEventHandler StateLoaded;
|
|
/// <summary>
|
|
/// Occurs when a savestate is successfully saved
|
|
/// </summary>
|
|
public static event StateSavedEventHandler StateSaved;
|
|
|
|
#endregion
|
|
|
|
#region cTor(s)
|
|
|
|
/// <summary>
|
|
/// Static stuff initialization
|
|
/// </summary>
|
|
static ClientApi()
|
|
{
|
|
ClientAssembly = Assembly.GetEntryAssembly();
|
|
ClientMainFormInstance = ClientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin").GetField("MainForm").GetValue(null);
|
|
MainFormClass = ClientAssembly.GetType("BizHawk.Client.EmuHawk.MainForm");
|
|
}
|
|
|
|
public static void UpdateEmulatorAndVP(IEmulator emu = null)
|
|
{
|
|
Emulator = emu;
|
|
VideoProvider = emu.AsVideoProviderOrDefault();
|
|
}
|
|
|
|
#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);
|
|
|
|
if(method != null)
|
|
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()
|
|
{
|
|
InvokeMainFormMethod("FrameAdvance");
|
|
|
|
InvokeMainFormMethod("StepRunLoop_Throttle");
|
|
|
|
InvokeMainFormMethod("Render");
|
|
}
|
|
|
|
/// <summary>
|
|
/// THE FrameAdvance stuff
|
|
/// Auto unpause emulation
|
|
/// </summary>
|
|
public static void DoFrameAdvanceAndUnpause()
|
|
{
|
|
DoFrameAdvance();
|
|
UnpauseEmulation();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a <see cref="Joypad"/> for specified player
|
|
/// </summary>
|
|
/// <param name="player">Player (one based) you want current inputs</param>
|
|
/// <returns>A <see cref="Joypad"/> populated with current inputs</returns>
|
|
/// <exception cref="IndexOutOfRangeException">Raised when you specify a player less than 1 or greater than maximum allows (see SystemInfo class to get this information)</exception>
|
|
public static Joypad GetInput(int player)
|
|
{
|
|
if (!1.RangeTo(RunningSystem.MaxControllers).Contains(player))
|
|
{
|
|
throw new IndexOutOfRangeException($"{RunningSystem.DisplayName} does not support {player} controller(s)");
|
|
}
|
|
|
|
GetAllInputs();
|
|
return _allJoyPads[player - 1];
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Load a savestate specified by its name
|
|
/// </summary>
|
|
/// <param name="name">Savestate friendly name</param>
|
|
public static void LoadState(string name)
|
|
{
|
|
InvokeMainFormMethod("LoadState", new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), $"{name}.State"), name, false, false });
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Raised before a quickload is done (just after pressing shortcut button)
|
|
/// </summary>
|
|
/// <param name="sender">Object who raised the event</param>
|
|
/// <param name="quickSaveSlotName">Slot used for quickload</param>
|
|
/// <param name="eventHandled">A boolean that can be set if users want to handle save themselves; if so, BizHawk won't do anything</param>
|
|
public static void OnBeforeQuickLoad(object sender, string quickSaveSlotName, out bool eventHandled)
|
|
{
|
|
eventHandled = false;
|
|
if (BeforeQuickLoad != null)
|
|
{
|
|
var e = new BeforeQuickLoadEventArgs(quickSaveSlotName);
|
|
BeforeQuickLoad(sender, e);
|
|
eventHandled = e.Handled;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Raised before a quicksave is done (just after pressing shortcut button)
|
|
/// </summary>
|
|
/// <param name="sender">Object who raised the event</param>
|
|
/// <param name="quickSaveSlotName">Slot used for quicksave</param>
|
|
/// <param name="eventHandled">A boolean that can be set if users want to handle save themselves; if so, BizHawk won't do anything</param>
|
|
public static void OnBeforeQuickSave(object sender, string quickSaveSlotName, out bool eventHandled)
|
|
{
|
|
eventHandled = false;
|
|
if (BeforeQuickSave != null)
|
|
{
|
|
var e = new BeforeQuickSaveEventArgs(quickSaveSlotName);
|
|
BeforeQuickSave(sender, e);
|
|
eventHandled = e.Handled;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Raise when a state is loaded
|
|
/// </summary>
|
|
/// <param name="sender">Object who raised the event</param>
|
|
/// <param name="stateName">User friendly name for saved state</param>
|
|
public static void OnStateLoaded(object sender, string stateName)
|
|
{
|
|
StateLoaded?.Invoke(sender, new StateLoadedEventArgs(stateName));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Raise when a state is saved
|
|
/// </summary>
|
|
/// <param name="sender">Object who raised the event</param>
|
|
/// <param name="stateName">User friendly name for saved state</param>
|
|
public static void OnStateSaved(object sender, string stateName)
|
|
{
|
|
StateSaved?.Invoke(sender, new StateSavedEventArgs(stateName));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Raise when a rom is successfully Loaded
|
|
/// </summary>
|
|
public static void OnRomLoaded(IEmulator emu)
|
|
{
|
|
Emulator = emu;
|
|
VideoProvider = emu.AsVideoProviderOrDefault();
|
|
RomLoaded?.Invoke(null, EventArgs.Empty);
|
|
|
|
_allJoyPads = new List<Joypad>(RunningSystem.MaxControllers);
|
|
for (int i = 1; i <= RunningSystem.MaxControllers; i++)
|
|
{
|
|
_allJoyPads.Add(new Joypad(RunningSystem, i));
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Save a state with specified name
|
|
/// </summary>
|
|
/// <param name="name">Savestate friendly name</param>
|
|
public static void SaveState(string name)
|
|
{
|
|
InvokeMainFormMethod("SaveState", new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), $"{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
|
|
/// </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 SetExtraPadding(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("ClientExtraPadding");
|
|
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 SetExtraPadding(int left)
|
|
{
|
|
SetExtraPadding(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 SetExtraPadding(int left, int top)
|
|
{
|
|
SetExtraPadding(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 SetExtraPadding(int left, int top, int right)
|
|
{
|
|
SetExtraPadding(left, top, right, 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set inputs in specified <see cref="Joypad"/> to specified player
|
|
/// </summary>
|
|
/// <param name="player">Player (one based) whom inputs must be set</param>
|
|
/// <param name="joypad"><see cref="Joypad"/> with inputs</param>
|
|
/// <exception cref="IndexOutOfRangeException">Raised when you specify a player less than 1 or greater than maximum allows (see SystemInfo class to get this information)</exception>
|
|
/// <remarks>Still have some strange behaviour with multiple inputs; so this feature is still in beta</remarks>
|
|
public static void SetInput(int player, Joypad joypad)
|
|
{
|
|
if (!1.RangeTo(RunningSystem.MaxControllers).Contains(player))
|
|
{
|
|
throw new IndexOutOfRangeException($"{RunningSystem.DisplayName} does not support {player} controller(s)");
|
|
}
|
|
else
|
|
{
|
|
if (joypad.Inputs == 0)
|
|
{
|
|
AutoFireStickyXorAdapter joypadAdapter = Global.AutofireStickyXORAdapter;
|
|
joypadAdapter.ClearStickies();
|
|
}
|
|
else
|
|
{
|
|
foreach (JoypadButton button in JoypadButtonsArray)
|
|
{
|
|
if (joypad.Inputs.HasFlag(button))
|
|
{
|
|
AutoFireStickyXorAdapter joypadAdapter = Global.AutofireStickyXORAdapter;
|
|
joypadAdapter.SetSticky(
|
|
RunningSystem == SystemInfo.GB
|
|
? $"{JoypadConverter.ConvertBack(button, RunningSystem)}"
|
|
: $"P{player} {JoypadConverter.ConvertBack(button, RunningSystem)}", true);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Using this break joypad usage (even in UI); have to figure out why
|
|
#if false
|
|
if ((RunningSystem.AvailableButtons & JoypadButton.AnalogStick) == JoypadButton.AnalogStick)
|
|
{
|
|
var joypadAdaptor = Global.AutofireStickyXORAdapter;
|
|
for (var i = 1; i <= RunningSystem.MaxControllers; i++)
|
|
{
|
|
joypadAdaptor.SetFloat($"P{i} X Axis", _allJoyPads[i - 1].AnalogX);
|
|
joypadAdaptor.SetFloat($"P{i} Y Axis", _allJoyPads[i - 1].AnalogY);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Resume the emulation
|
|
/// </summary>
|
|
public static void UnpauseEmulation()
|
|
{
|
|
InvokeMainFormMethod("UnpauseEmulator");
|
|
}
|
|
#endregion Public
|
|
|
|
/// <summary>
|
|
/// Gets all current inputs for each joypad and store
|
|
/// them in <see cref="Joypad"/> class collection
|
|
/// </summary>
|
|
private static void GetAllInputs()
|
|
{
|
|
var joypadAdapter = Global.AutofireStickyXORAdapter;
|
|
|
|
var pressedButtons = joypadAdapter.Definition.BoolButtons
|
|
.Where(b => joypadAdapter.IsPressed(b));
|
|
|
|
foreach (Joypad j in _allJoyPads)
|
|
{
|
|
j.ClearInputs();
|
|
}
|
|
|
|
Parallel.ForEach(pressedButtons, button =>
|
|
{
|
|
if (RunningSystem == SystemInfo.GB)
|
|
{
|
|
_allJoyPads[0].AddInput(JoypadConverter.Convert(button));
|
|
}
|
|
else
|
|
{
|
|
if (int.TryParse(button.Substring(1, 2), out var player))
|
|
{
|
|
_allJoyPads[player - 1].AddInput(JoypadConverter.Convert(button.Substring(3)));
|
|
}
|
|
}
|
|
});
|
|
|
|
if ((RunningSystem.AvailableButtons & JoypadButton.AnalogStick) == JoypadButton.AnalogStick)
|
|
{
|
|
for (int i = 1; i <= RunningSystem.MaxControllers; i++)
|
|
{
|
|
_allJoyPads[i - 1].AnalogX = joypadAdapter.GetFloat($"P{i} X Axis");
|
|
_allJoyPads[i - 1].AnalogY = joypadAdapter.GetFloat($"P{i} Y Axis");
|
|
}
|
|
}
|
|
}
|
|
|
|
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[] {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.ScreenshotCaptureOsd = 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.StrictlyBoundedBy(0.RangeTo(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
|
|
|
|
/// <summary>
|
|
/// Gets current emulated system
|
|
/// </summary>
|
|
public static SystemInfo RunningSystem
|
|
{
|
|
get
|
|
{
|
|
switch (Global.Emulator.SystemId)
|
|
{
|
|
case "PCE":
|
|
if (((PCEngine)Global.Emulator).Type == NecSystemType.TurboGrafx)
|
|
{
|
|
return SystemInfo.PCE;
|
|
}
|
|
else if (((PCEngine)Global.Emulator).Type == NecSystemType.SuperGrafx)
|
|
{
|
|
return SystemInfo.SGX;
|
|
}
|
|
else
|
|
{
|
|
return SystemInfo.PCECD;
|
|
}
|
|
|
|
case "SMS":
|
|
if (((SMS)Global.Emulator).IsSG1000)
|
|
{
|
|
return SystemInfo.SG;
|
|
}
|
|
else if (((SMS)Global.Emulator).IsGameGear)
|
|
{
|
|
return SystemInfo.GG;
|
|
}
|
|
else
|
|
{
|
|
return SystemInfo.SMS;
|
|
}
|
|
|
|
case "GB":
|
|
if (Global.Emulator is Gameboy gb)
|
|
{
|
|
return gb.IsCGBMode()
|
|
? SystemInfo.GBC
|
|
: SystemInfo.GB;
|
|
}
|
|
else
|
|
{
|
|
return SystemInfo.DualGB;
|
|
}
|
|
|
|
default:
|
|
return SystemInfo.FindByCoreSystem(SystemIdConverter.Convert(Global.Emulator.SystemId));
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|