2016-03-16 22:06:53 +00:00
using System ;
2016-03-26 22:07:44 +00:00
using System.Collections.Generic ;
using System.Linq ;
2016-03-16 22:06:53 +00:00
using System.Reflection ;
2016-03-26 22:07:44 +00:00
using System.Threading.Tasks ;
2016-04-06 20:10:36 +00:00
using System.Windows.Forms ;
2016-03-26 22:07:44 +00:00
using BizHawk.Client.Common ;
2018-12-22 18:40:30 +00:00
using BizHawk.Emulation.Common ;
2016-03-26 22:07:44 +00:00
using BizHawk.Emulation.Cores.Nintendo.Gameboy ;
using BizHawk.Emulation.Cores.PCEngine ;
using BizHawk.Emulation.Cores.Sega.MasterSystem ;
2016-05-29 14:50:16 +00:00
using BizHawk.Client.ApiHawk.Classes.Events ;
using System.IO ;
2016-03-16 22:06:53 +00:00
namespace BizHawk.Client.ApiHawk
{
/// <summary>
/// This class contains some methods that
/// interract with BizHawk client
/// </summary>
public static class ClientApi
{
#region Fields
2018-12-22 18:40:30 +00:00
private static IEmulator Emulator ;
private static IVideoProvider VideoProvider ;
2016-03-16 22:06:53 +00:00
private static readonly Assembly clientAssembly ;
2016-04-03 16:17:22 +00:00
private static readonly object clientMainFormInstance ;
private static readonly Type mainFormClass ;
2016-04-06 20:10:36 +00:00
private static readonly Array joypadButtonsArray = Enum . GetValues ( typeof ( JoypadButton ) ) ;
2016-04-03 16:17:22 +00:00
2016-03-26 22:07:44 +00:00
internal static readonly BizHawkSystemIdToEnumConverter SystemIdConverter = new BizHawkSystemIdToEnumConverter ( ) ;
internal static readonly JoypadStringToEnumConverter JoypadConverter = new JoypadStringToEnumConverter ( ) ;
2016-03-20 22:05:38 +00:00
2016-03-26 22:07:44 +00:00
private static List < Joypad > allJoypads ;
2016-05-29 14:50:16 +00:00
/// <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 succesfully loaded
/// </summary>
public static event EventHandler RomLoaded ;
/// <summary>
/// Occurs when a savestate is sucessfully loaded
/// </summary>
public static event StateLoadedEventHandler StateLoaded ;
/// <summary>
/// Occurs when a savestate is successfully saved
/// </summary>
public static event StateSavedEventHandler StateSaved ;
2016-03-16 22:06:53 +00:00
#endregion
#region cTor ( s )
2016-04-03 16:17:22 +00:00
/// <summary>
/// Static stuff initilization
/// </summary>
2016-03-16 22:06:53 +00:00
static ClientApi ( )
{
clientAssembly = Assembly . GetEntryAssembly ( ) ;
2016-04-03 16:17:22 +00:00
clientMainFormInstance = clientAssembly . GetType ( "BizHawk.Client.EmuHawk.GlobalWin" ) . GetField ( "MainForm" ) . GetValue ( null ) ;
mainFormClass = clientAssembly . GetType ( "BizHawk.Client.EmuHawk.MainForm" ) ;
2016-03-16 22:06:53 +00:00
}
2018-12-22 18:40:30 +00:00
public static void UpdateEmulatorAndVP ( IEmulator emu = null )
{
Emulator = emu ;
VideoProvider = Emulation . Common . IEmulatorExtensions . Extensions . AsVideoProviderOrDefault ( emu ) ;
}
2016-03-16 22:06:53 +00:00
#endregion
#region Methods
2018-12-22 18:40:30 +00:00
#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 ) ;
2019-04-23 03:54:07 +00:00
if ( method ! = null )
method . Invoke ( clientMainFormInstance , paramList ) ;
2018-12-22 18:40:30 +00:00
}
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
2016-03-26 22:07:44 +00:00
#region Public
2016-03-23 22:05:05 +00:00
/// <summary>
/// THE FrameAdvance stuff
/// </summary>
2016-03-26 22:07:44 +00:00
public static void DoFrameAdvance ( )
2016-03-20 22:05:38 +00:00
{
2018-12-22 18:40:30 +00:00
InvokeMainFormMethod ( "FrameAdvance" , null ) ;
2016-04-03 16:17:22 +00:00
2018-12-22 18:40:30 +00:00
InvokeMainFormMethod ( "StepRunLoop_Throttle" , null ) ;
2016-04-03 16:17:22 +00:00
2018-12-22 18:40:30 +00:00
InvokeMainFormMethod ( "Render" , null ) ;
2016-03-26 22:07:44 +00:00
}
/// <summary>
/// THE FrameAdvance stuff
/// Auto unpause emulation
/// </summary>
public static void DoFrameAdvanceAndUnpause ( )
{
2016-04-03 16:17:22 +00:00
DoFrameAdvance ( ) ;
UnpauseEmulation ( ) ;
2016-03-26 22:07:44 +00:00
}
/// <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 ( player < 1 | | player > RunningSystem . MaxControllers )
{
2019-03-20 05:52:54 +00:00
throw new IndexOutOfRangeException ( $"{RunningSystem.DisplayName} does not support {player} controller(s)" ) ;
2016-03-26 22:07:44 +00:00
}
else
{
GetAllInputs ( ) ;
return allJoypads [ player - 1 ] ;
}
}
2016-03-20 22:05:38 +00:00
2016-05-29 14:50:16 +00:00
/// <summary>
/// Load a savestate specified by its name
/// </summary>
/// <param name="name">Savetate friendly name</param>
public static void LoadState ( string name )
{
2019-03-20 05:52:54 +00:00
InvokeMainFormMethod ( "LoadState" , new object [ ] { Path . Combine ( PathManager . GetSaveStatePath ( Global . Game ) , $"{name}.{" State "}" ) , name , false , false } ) ;
2016-05-29 14:50:16 +00:00
}
/// <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 )
{
BeforeQuickLoadEventArgs 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 )
{
BeforeQuickSaveEventArgs 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 )
{
if ( StateLoaded ! = null )
{
StateLoaded ( 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 )
{
if ( StateSaved ! = null )
{
StateSaved ( sender , new StateSavedEventArgs ( stateName ) ) ;
}
}
2016-03-16 22:06:53 +00:00
/// <summary>
/// Raise when a rom is successfully Loaded
/// </summary>
2018-12-22 18:40:30 +00:00
public static void OnRomLoaded ( IEmulator emu )
2016-03-16 22:06:53 +00:00
{
2018-12-22 18:40:30 +00:00
Emulator = emu ;
VideoProvider = Emulation . Common . IEmulatorExtensions . Extensions . AsVideoProviderOrDefault ( emu ) ;
RomLoaded ? . Invoke ( null , EventArgs . Empty ) ;
2016-03-26 22:07:44 +00:00
allJoypads = new List < Joypad > ( RunningSystem . MaxControllers ) ;
for ( int i = 1 ; i < = RunningSystem . MaxControllers ; i + + )
{
allJoypads . Add ( new Joypad ( RunningSystem , i ) ) ;
}
2016-03-16 22:06:53 +00:00
}
2016-03-26 22:07:44 +00:00
2016-05-29 14:50:16 +00:00
/// <summary>
/// Save a state with specified name
/// </summary>
/// <param name="name">Savetate friendly name</param>
public static void SaveState ( string name )
{
2019-03-20 05:52:54 +00:00
InvokeMainFormMethod ( "SaveState" , new object [ ] { Path . Combine ( PathManager . GetSaveStatePath ( Global . Game ) , $"{name}.{" State "}" ) , name , false } ) ;
2018-12-22 18:40:30 +00:00
}
/// <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 ) ;
2016-05-29 14:50:16 +00:00
}
2018-12-22 18:40:30 +00:00
/// <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 ) ;
}
2016-05-29 14:50:16 +00:00
2016-03-16 22:06:53 +00:00
/// <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>
2018-12-22 19:58:14 +00:00
public static void SetExtraPadding ( int left , int top , int right , int bottom )
2016-03-16 22:06:53 +00:00
{
2016-04-06 20:10:36 +00:00
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 ) ) ;
2016-04-03 16:17:22 +00:00
2018-12-22 18:40:30 +00:00
InvokeMainFormMethod ( "FrameBufferResized" ) ;
2016-03-16 22:06:53 +00:00
}
/// <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>
2018-12-22 19:58:14 +00:00
public static void SetExtraPadding ( int left )
2016-03-16 22:06:53 +00:00
{
2018-12-22 19:58:14 +00:00
SetExtraPadding ( left , 0 , 0 , 0 ) ;
2016-03-16 22:06:53 +00:00
}
/// <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>
2018-12-22 19:58:14 +00:00
public static void SetExtraPadding ( int left , int top )
2016-03-16 22:06:53 +00:00
{
2018-12-22 19:58:14 +00:00
SetExtraPadding ( left , top , 0 , 0 ) ;
2016-03-16 22:06:53 +00:00
}
/// <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>
2018-12-22 19:58:14 +00:00
public static void SetExtraPadding ( int left , int top , int right )
2016-03-16 22:06:53 +00:00
{
2018-12-22 19:58:14 +00:00
SetExtraPadding ( left , top , right , 0 ) ;
2016-03-16 22:06:53 +00:00
}
2016-03-20 22:05:38 +00:00
/// <summary>
2016-03-26 22:07:44 +00:00
/// Set inputs in specified <see cref="Joypad"/> to specified player
2016-03-20 22:05:38 +00:00
/// </summary>
2016-03-26 22:07:44 +00:00
/// <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>
2016-04-06 20:10:36 +00:00
/// <remarks>Still have some strange behaviour with multiple inputs; so this feature is still in beta</remarks>
2016-03-26 22:07:44 +00:00
public static void SetInput ( int player , Joypad joypad )
2016-03-20 22:05:38 +00:00
{
2016-03-26 22:07:44 +00:00
if ( player < 1 | | player > RunningSystem . MaxControllers )
2016-03-20 22:05:38 +00:00
{
2019-03-20 05:52:54 +00:00
throw new IndexOutOfRangeException ( $"{RunningSystem.DisplayName} does not support {player} controller(s)" ) ;
2016-03-26 22:07:44 +00:00
}
else
{
2016-04-03 16:17:22 +00:00
if ( joypad . Inputs = = 0 )
2016-03-26 22:07:44 +00:00
{
2016-04-03 16:17:22 +00:00
AutoFireStickyXorAdapter joypadAdaptor = Global . AutofireStickyXORAdapter ;
joypadAdaptor . ClearStickies ( ) ;
}
else
{
2016-04-06 20:10:36 +00:00
foreach ( JoypadButton button in joypadButtonsArray )
2016-03-26 22:07:44 +00:00
{
2016-04-03 16:17:22 +00:00
if ( joypad . Inputs . HasFlag ( button ) )
{
AutoFireStickyXorAdapter joypadAdaptor = Global . AutofireStickyXORAdapter ;
2016-04-06 20:10:36 +00:00
if ( RunningSystem = = SystemInfo . GB )
{
2019-03-20 05:52:54 +00:00
joypadAdaptor . SetSticky ( $"{JoypadConverter.ConvertBack(button, RunningSystem)}" , true ) ;
2016-04-06 20:10:36 +00:00
}
else
{
2019-03-20 05:52:54 +00:00
joypadAdaptor . SetSticky ( $"P{player} {JoypadConverter.ConvertBack(button, RunningSystem)}" , true ) ;
2016-04-06 20:10:36 +00:00
}
2016-04-03 16:17:22 +00:00
}
2016-03-26 22:07:44 +00:00
}
}
2016-04-06 20:10:36 +00:00
//Using this break joypad usage (even in UI); have to figure out why
/ * if ( ( RunningSystem . AvailableButtons & JoypadButton . AnalogStick ) = = JoypadButton . AnalogStick )
{
AutoFireStickyXorAdapter joypadAdaptor = Global . AutofireStickyXORAdapter ;
for ( int i = 1 ; i < = RunningSystem . MaxControllers ; i + + )
{
2019-03-20 05:52:54 +00:00
joypadAdaptor . SetFloat ( $"P{i} X Axis" , allJoypads [ i - 1 ] . AnalogX ) ;
joypadAdaptor . SetFloat ( $"P{i} Y Axis" , allJoypads [ i - 1 ] . AnalogY ) ;
2016-04-06 20:10:36 +00:00
}
} * /
2016-03-26 22:07:44 +00:00
}
}
2016-03-20 22:05:38 +00:00
2016-03-26 22:07:44 +00:00
/// <summary>
/// Resume the emulation
/// </summary>
public static void UnpauseEmulation ( )
2016-04-06 20:10:36 +00:00
{
2018-12-22 18:40:30 +00:00
InvokeMainFormMethod ( "UnpauseEmulator" , null ) ;
2016-03-20 22:05:38 +00:00
}
2016-03-26 22:07:44 +00:00
#endregion Public
2016-03-20 22:05:38 +00:00
/// <summary>
2016-03-26 22:07:44 +00:00
/// Gets all current inputs for each joypad and store
/// them in <see cref="Joypad"/> class collection
2016-03-20 22:05:38 +00:00
/// </summary>
2016-03-26 22:07:44 +00:00
private static void GetAllInputs ( )
2016-03-20 22:05:38 +00:00
{
2016-03-26 22:07:44 +00:00
AutoFireStickyXorAdapter joypadAdaptor = Global . AutofireStickyXORAdapter ;
2016-03-20 22:05:38 +00:00
2016-12-12 18:30:32 +00:00
IEnumerable < string > pressedButtons = from button in joypadAdaptor . Definition . BoolButtons
2016-12-14 20:12:16 +00:00
where joypadAdaptor . IsPressed ( button )
2016-03-26 22:07:44 +00:00
select button ;
2016-03-20 22:05:38 +00:00
2016-03-26 22:07:44 +00:00
foreach ( Joypad j in allJoypads )
{
j . ClearInputs ( ) ;
}
2016-03-20 22:05:38 +00:00
2016-03-26 22:07:44 +00:00
Parallel . ForEach < string > ( pressedButtons , button = >
{
int player ;
2016-04-06 20:10:36 +00:00
if ( RunningSystem = = SystemInfo . GB )
2016-03-26 22:07:44 +00:00
{
2016-04-06 20:10:36 +00:00
allJoypads [ 0 ] . AddInput ( JoypadConverter . Convert ( button ) ) ;
}
else
{
if ( int . TryParse ( button . Substring ( 1 , 2 ) , out player ) )
{
allJoypads [ player - 1 ] . AddInput ( JoypadConverter . Convert ( button . Substring ( 3 ) ) ) ;
}
2016-03-26 22:07:44 +00:00
}
} ) ;
if ( ( RunningSystem . AvailableButtons & JoypadButton . AnalogStick ) = = JoypadButton . AnalogStick )
{
2016-04-06 20:10:36 +00:00
for ( int i = 1 ; i < = RunningSystem . MaxControllers ; i + + )
{
2019-03-20 05:52:54 +00:00
allJoypads [ i - 1 ] . AnalogX = joypadAdaptor . GetFloat ( $"P{i} X Axis" ) ;
allJoypads [ i - 1 ] . AnalogY = joypadAdaptor . GetFloat ( $"P{i} Y Axis" ) ;
2016-04-06 20:10:36 +00:00
}
2016-03-20 22:05:38 +00:00
}
}
2018-12-22 18:40:30 +00:00
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" ) ;
2019-03-20 05:52:54 +00:00
m . Invoke ( osd , new Object [ ] { $"Window size set to {size}x" } ) ;
2018-12-22 18:40:30 +00:00
}
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 ) ;
}
2016-03-20 22:05:38 +00:00
#endregion
#region Properties
/// <summary>
2016-03-26 22:07:44 +00:00
/// Gets current emulated system
2016-03-20 22:05:38 +00:00
/// </summary>
2016-03-26 22:07:44 +00:00
public static SystemInfo RunningSystem
2016-03-20 22:05:38 +00:00
{
get
{
2016-03-26 22:07:44 +00:00
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 )
{
return SystemInfo . GB ;
}
else if ( Global . Emulator is GBColors )
{
return SystemInfo . GBC ;
}
else
{
2018-12-22 18:40:30 +00:00
return SystemInfo . DualGB ;
2016-03-26 22:07:44 +00:00
}
default :
2018-12-22 18:40:30 +00:00
return SystemInfo . FindByCoreSystem ( SystemIdConverter . Convert ( Global . Emulator . SystemId ) ) ;
2016-03-26 22:07:44 +00:00
}
2016-03-20 22:05:38 +00:00
}
}
2016-03-16 22:06:53 +00:00
#endregion
}
}