Cleanup GamePad code, pass in mainform dependency
This commit is contained in:
parent
038f35f45e
commit
023da20cb9
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Windows.Forms;
|
||||||
using SlimDX;
|
using SlimDX;
|
||||||
using SlimDX.DirectInput;
|
using SlimDX.DirectInput;
|
||||||
|
|
||||||
|
@ -7,47 +8,47 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
public class GamePad
|
public class GamePad
|
||||||
{
|
{
|
||||||
// ********************************** Static interface **********************************
|
private static readonly object SyncObj = new object();
|
||||||
|
private static readonly List<GamePad> Devices = new List<GamePad>();
|
||||||
|
private static DirectInput _directInput;
|
||||||
|
|
||||||
private static readonly object _syncObj = new object();
|
public static void Initialize(Control parent)
|
||||||
private static readonly List<GamePad> _devices = new List<GamePad>();
|
|
||||||
private static DirectInput _dinput;
|
|
||||||
|
|
||||||
public static void Initialize()
|
|
||||||
{
|
{
|
||||||
lock (_syncObj)
|
lock (SyncObj)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
||||||
_dinput = new DirectInput();
|
_directInput = new DirectInput();
|
||||||
|
|
||||||
foreach (DeviceInstance device in _dinput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
|
foreach (DeviceInstance device in _directInput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
|
||||||
{
|
{
|
||||||
Console.WriteLine("joydevice: {0} `{1}`", device.InstanceGuid, device.ProductName);
|
Console.WriteLine("joy device: {0} `{1}`", device.InstanceGuid, device.ProductName);
|
||||||
|
|
||||||
if (device.ProductName.Contains("XBOX 360"))
|
if (device.ProductName.Contains("XBOX 360"))
|
||||||
continue; // Don't input XBOX 360 controllers into here; we'll process them via XInput (there are limitations in some trigger axes when xbox pads go over xinput)
|
continue; // Don't input XBOX 360 controllers into here; we'll process them via XInput (there are limitations in some trigger axes when xbox pads go over xinput)
|
||||||
|
|
||||||
var joystick = new Joystick(_dinput, device.InstanceGuid);
|
var joystick = new Joystick(_directInput, device.InstanceGuid);
|
||||||
joystick.SetCooperativeLevel(GlobalWin.MainForm.Handle, CooperativeLevel.Background | CooperativeLevel.Nonexclusive);
|
joystick.SetCooperativeLevel(parent.Handle, CooperativeLevel.Background | CooperativeLevel.Nonexclusive);
|
||||||
foreach (DeviceObjectInstance deviceObject in joystick.GetObjects())
|
foreach (DeviceObjectInstance deviceObject in joystick.GetObjects())
|
||||||
{
|
{
|
||||||
if ((deviceObject.ObjectType & ObjectDeviceType.Axis) != 0)
|
if ((deviceObject.ObjectType & ObjectDeviceType.Axis) != 0)
|
||||||
|
{
|
||||||
joystick.GetObjectPropertiesById((int)deviceObject.ObjectType).SetRange(-1000, 1000);
|
joystick.GetObjectPropertiesById((int)deviceObject.ObjectType).SetRange(-1000, 1000);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
joystick.Acquire();
|
joystick.Acquire();
|
||||||
|
|
||||||
GamePad p = new GamePad(device.InstanceName, device.InstanceGuid, joystick, _devices.Count);
|
GamePad p = new GamePad(joystick, Devices.Count);
|
||||||
_devices.Add(p);
|
Devices.Add(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<GamePad> EnumerateDevices()
|
public static IEnumerable<GamePad> EnumerateDevices()
|
||||||
{
|
{
|
||||||
lock (_syncObj)
|
lock (SyncObj)
|
||||||
{
|
{
|
||||||
foreach (var device in _devices)
|
foreach (var device in Devices)
|
||||||
{
|
{
|
||||||
yield return device;
|
yield return device;
|
||||||
}
|
}
|
||||||
|
@ -56,9 +57,9 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
public static void UpdateAll()
|
public static void UpdateAll()
|
||||||
{
|
{
|
||||||
lock (_syncObj)
|
lock (SyncObj)
|
||||||
{
|
{
|
||||||
foreach (var device in _devices)
|
foreach (var device in Devices)
|
||||||
{
|
{
|
||||||
device.Update();
|
device.Update();
|
||||||
}
|
}
|
||||||
|
@ -67,34 +68,31 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
public static void Cleanup()
|
public static void Cleanup()
|
||||||
{
|
{
|
||||||
lock (_syncObj)
|
lock (SyncObj)
|
||||||
{
|
{
|
||||||
foreach (var device in _devices)
|
foreach (var device in Devices)
|
||||||
{
|
{
|
||||||
device.joystick.Dispose();
|
device._joystick.Dispose();
|
||||||
}
|
}
|
||||||
_devices.Clear();
|
|
||||||
|
|
||||||
if (_dinput != null)
|
Devices.Clear();
|
||||||
|
|
||||||
|
if (_directInput != null)
|
||||||
{
|
{
|
||||||
_dinput.Dispose();
|
_directInput.Dispose();
|
||||||
_dinput = null;
|
_directInput = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ********************************** Instance Members **********************************
|
// ********************************** Instance Members **********************************
|
||||||
|
|
||||||
readonly string name;
|
private readonly Joystick _joystick;
|
||||||
readonly Guid guid;
|
private JoystickState _state = new JoystickState();
|
||||||
readonly Joystick joystick;
|
|
||||||
JoystickState state = new JoystickState();
|
|
||||||
|
|
||||||
GamePad(string name, Guid guid, Joystick joystick, int index)
|
GamePad(Joystick joystick, int index)
|
||||||
{
|
{
|
||||||
this.name = name;
|
_joystick = joystick;
|
||||||
this.guid = guid;
|
|
||||||
this.joystick = joystick;
|
|
||||||
PlayerNumber = index + 1;
|
PlayerNumber = index + 1;
|
||||||
Update();
|
Update();
|
||||||
InitializeCallbacks();
|
InitializeCallbacks();
|
||||||
|
@ -104,17 +102,21 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (joystick.Acquire().IsFailure)
|
if (_joystick.Acquire().IsFailure)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (joystick.Poll().IsFailure)
|
|
||||||
return;
|
|
||||||
|
|
||||||
state = joystick.GetCurrentState();
|
if (_joystick.Poll()
|
||||||
|
.IsFailure)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_state = _joystick.GetCurrentState();
|
||||||
if (Result.Last.IsFailure)
|
if (Result.Last.IsFailure)
|
||||||
// do something?
|
// do something?
|
||||||
return;
|
return;
|
||||||
|
@ -124,124 +126,125 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
var pis = typeof(JoystickState).GetProperties();
|
var pis = typeof(JoystickState).GetProperties();
|
||||||
foreach (var pi in pis)
|
foreach (var pi in pis)
|
||||||
yield return new Tuple<string, float>(pi.Name, 10.0f * (float)(int)pi.GetValue(state, null));
|
{
|
||||||
|
yield return new Tuple<string, float>(pi.Name, 10.0f * (float)(int)pi.GetValue(_state, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>FOR DEBUGGING ONLY</summary>
|
/// <summary>FOR DEBUGGING ONLY</summary>
|
||||||
public JoystickState GetInternalState()
|
public JoystickState GetInternalState()
|
||||||
{
|
{
|
||||||
return state;
|
return _state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get { return name; } }
|
public int PlayerNumber { get; }
|
||||||
public Guid Guid { get { return guid; } }
|
|
||||||
public int PlayerNumber { get; private set; }
|
|
||||||
|
|
||||||
public string ButtonName(int index)
|
public string ButtonName(int index)
|
||||||
{
|
{
|
||||||
return names[index];
|
return _names[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Pressed(int index)
|
public bool Pressed(int index)
|
||||||
{
|
{
|
||||||
return actions[index]();
|
return _actions[index]();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int NumButtons { get; private set; }
|
public int NumButtons { get; private set; }
|
||||||
|
|
||||||
private readonly List<string> names = new List<string>();
|
private readonly List<string> _names = new List<string>();
|
||||||
private readonly List<Func<bool>> actions = new List<Func<bool>>();
|
private readonly List<Func<bool>> _actions = new List<Func<bool>>();
|
||||||
|
|
||||||
void AddItem(string _name, Func<bool> callback)
|
private void AddItem(string name, Func<bool> callback)
|
||||||
{
|
{
|
||||||
names.Add(_name);
|
_names.Add(name);
|
||||||
actions.Add(callback);
|
_actions.Add(callback);
|
||||||
NumButtons++;
|
NumButtons++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeCallbacks()
|
private void InitializeCallbacks()
|
||||||
{
|
{
|
||||||
const int dzp = 400;
|
const int dzp = 400;
|
||||||
const int dzn = -400;
|
const int dzn = -400;
|
||||||
|
|
||||||
names.Clear();
|
_names.Clear();
|
||||||
actions.Clear();
|
_actions.Clear();
|
||||||
NumButtons = 0;
|
NumButtons = 0;
|
||||||
|
|
||||||
AddItem("AccelerationX+", () => state.AccelerationX >= dzp);
|
AddItem("AccelerationX+", () => _state.AccelerationX >= dzp);
|
||||||
AddItem("AccelerationX-", () => state.AccelerationX <= dzn);
|
AddItem("AccelerationX-", () => _state.AccelerationX <= dzn);
|
||||||
AddItem("AccelerationY+", () => state.AccelerationY >= dzp);
|
AddItem("AccelerationY+", () => _state.AccelerationY >= dzp);
|
||||||
AddItem("AccelerationY-", () => state.AccelerationY <= dzn);
|
AddItem("AccelerationY-", () => _state.AccelerationY <= dzn);
|
||||||
AddItem("AccelerationZ+", () => state.AccelerationZ >= dzp);
|
AddItem("AccelerationZ+", () => _state.AccelerationZ >= dzp);
|
||||||
AddItem("AccelerationZ-", () => state.AccelerationZ <= dzn);
|
AddItem("AccelerationZ-", () => _state.AccelerationZ <= dzn);
|
||||||
AddItem("AngularAccelerationX+", () => state.AngularAccelerationX >= dzp);
|
AddItem("AngularAccelerationX+", () => _state.AngularAccelerationX >= dzp);
|
||||||
AddItem("AngularAccelerationX-", () => state.AngularAccelerationX <= dzn);
|
AddItem("AngularAccelerationX-", () => _state.AngularAccelerationX <= dzn);
|
||||||
AddItem("AngularAccelerationY+", () => state.AngularAccelerationY >= dzp);
|
AddItem("AngularAccelerationY+", () => _state.AngularAccelerationY >= dzp);
|
||||||
AddItem("AngularAccelerationY-", () => state.AngularAccelerationY <= dzn);
|
AddItem("AngularAccelerationY-", () => _state.AngularAccelerationY <= dzn);
|
||||||
AddItem("AngularAccelerationZ+", () => state.AngularAccelerationZ >= dzp);
|
AddItem("AngularAccelerationZ+", () => _state.AngularAccelerationZ >= dzp);
|
||||||
AddItem("AngularAccelerationZ-", () => state.AngularAccelerationZ <= dzn);
|
AddItem("AngularAccelerationZ-", () => _state.AngularAccelerationZ <= dzn);
|
||||||
AddItem("AngularVelocityX+", () => state.AngularVelocityX >= dzp);
|
AddItem("AngularVelocityX+", () => _state.AngularVelocityX >= dzp);
|
||||||
AddItem("AngularVelocityX-", () => state.AngularVelocityX <= dzn);
|
AddItem("AngularVelocityX-", () => _state.AngularVelocityX <= dzn);
|
||||||
AddItem("AngularVelocityY+", () => state.AngularVelocityY >= dzp);
|
AddItem("AngularVelocityY+", () => _state.AngularVelocityY >= dzp);
|
||||||
AddItem("AngularVelocityY-", () => state.AngularVelocityY <= dzn);
|
AddItem("AngularVelocityY-", () => _state.AngularVelocityY <= dzn);
|
||||||
AddItem("AngularVelocityZ+", () => state.AngularVelocityZ >= dzp);
|
AddItem("AngularVelocityZ+", () => _state.AngularVelocityZ >= dzp);
|
||||||
AddItem("AngularVelocityZ-", () => state.AngularVelocityZ <= dzn);
|
AddItem("AngularVelocityZ-", () => _state.AngularVelocityZ <= dzn);
|
||||||
AddItem("ForceX+", () => state.ForceX >= dzp);
|
AddItem("ForceX+", () => _state.ForceX >= dzp);
|
||||||
AddItem("ForceX-", () => state.ForceX <= dzn);
|
AddItem("ForceX-", () => _state.ForceX <= dzn);
|
||||||
AddItem("ForceY+", () => state.ForceY >= dzp);
|
AddItem("ForceY+", () => _state.ForceY >= dzp);
|
||||||
AddItem("ForceY-", () => state.ForceY <= dzn);
|
AddItem("ForceY-", () => _state.ForceY <= dzn);
|
||||||
AddItem("ForceZ+", () => state.ForceZ >= dzp);
|
AddItem("ForceZ+", () => _state.ForceZ >= dzp);
|
||||||
AddItem("ForceZ-", () => state.ForceZ <= dzn);
|
AddItem("ForceZ-", () => _state.ForceZ <= dzn);
|
||||||
AddItem("RotationX+", () => state.RotationX >= dzp);
|
AddItem("RotationX+", () => _state.RotationX >= dzp);
|
||||||
AddItem("RotationX-", () => state.RotationX <= dzn);
|
AddItem("RotationX-", () => _state.RotationX <= dzn);
|
||||||
AddItem("RotationY+", () => state.RotationY >= dzp);
|
AddItem("RotationY+", () => _state.RotationY >= dzp);
|
||||||
AddItem("RotationY-", () => state.RotationY <= dzn);
|
AddItem("RotationY-", () => _state.RotationY <= dzn);
|
||||||
AddItem("RotationZ+", () => state.RotationZ >= dzp);
|
AddItem("RotationZ+", () => _state.RotationZ >= dzp);
|
||||||
AddItem("RotationZ-", () => state.RotationZ <= dzn);
|
AddItem("RotationZ-", () => _state.RotationZ <= dzn);
|
||||||
AddItem("TorqueX+", () => state.TorqueX >= dzp);
|
AddItem("TorqueX+", () => _state.TorqueX >= dzp);
|
||||||
AddItem("TorqueX-", () => state.TorqueX <= dzn);
|
AddItem("TorqueX-", () => _state.TorqueX <= dzn);
|
||||||
AddItem("TorqueY+", () => state.TorqueY >= dzp);
|
AddItem("TorqueY+", () => _state.TorqueY >= dzp);
|
||||||
AddItem("TorqueY-", () => state.TorqueY <= dzn);
|
AddItem("TorqueY-", () => _state.TorqueY <= dzn);
|
||||||
AddItem("TorqueZ+", () => state.TorqueZ >= dzp);
|
AddItem("TorqueZ+", () => _state.TorqueZ >= dzp);
|
||||||
AddItem("TorqueZ-", () => state.TorqueZ <= dzn);
|
AddItem("TorqueZ-", () => _state.TorqueZ <= dzn);
|
||||||
AddItem("VelocityX+", () => state.VelocityX >= dzp);
|
AddItem("VelocityX+", () => _state.VelocityX >= dzp);
|
||||||
AddItem("VelocityX-", () => state.VelocityX <= dzn);
|
AddItem("VelocityX-", () => _state.VelocityX <= dzn);
|
||||||
AddItem("VelocityY+", () => state.VelocityY >= dzp);
|
AddItem("VelocityY+", () => _state.VelocityY >= dzp);
|
||||||
AddItem("VelocityY-", () => state.VelocityY <= dzn);
|
AddItem("VelocityY-", () => _state.VelocityY <= dzn);
|
||||||
AddItem("VelocityZ+", () => state.VelocityZ >= dzp);
|
AddItem("VelocityZ+", () => _state.VelocityZ >= dzp);
|
||||||
AddItem("VelocityZ-", () => state.VelocityZ <= dzn);
|
AddItem("VelocityZ-", () => _state.VelocityZ <= dzn);
|
||||||
AddItem("X+", () => state.X >= dzp);
|
AddItem("X+", () => _state.X >= dzp);
|
||||||
AddItem("X-", () => state.X <= dzn);
|
AddItem("X-", () => _state.X <= dzn);
|
||||||
AddItem("Y+", () => state.Y >= dzp);
|
AddItem("Y+", () => _state.Y >= dzp);
|
||||||
AddItem("Y-", () => state.Y <= dzn);
|
AddItem("Y-", () => _state.Y <= dzn);
|
||||||
AddItem("Z+", () => state.Z >= dzp);
|
AddItem("Z+", () => _state.Z >= dzp);
|
||||||
AddItem("Z-", () => state.Z <= dzn);
|
AddItem("Z-", () => _state.Z <= dzn);
|
||||||
|
|
||||||
// i don't know what the "Slider"s do, so they're omitted for the moment
|
// i don't know what the "Slider"s do, so they're omitted for the moment
|
||||||
|
|
||||||
for (int i = 0; i < state.GetButtons().Length; i++)
|
for (int i = 0; i < _state.GetButtons().Length; i++)
|
||||||
{
|
{
|
||||||
int j = i;
|
int j = i;
|
||||||
AddItem($"B{i + 1}", () => state.IsPressed(j));
|
AddItem($"B{i + 1}", () => _state.IsPressed(j));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < state.GetPointOfViewControllers().Length; i++)
|
for (int i = 0; i < _state.GetPointOfViewControllers().Length; i++)
|
||||||
{
|
{
|
||||||
int j = i;
|
int j = i;
|
||||||
AddItem($"POV{i + 1}U",
|
AddItem($"POV{i + 1}U",
|
||||||
() => { int t = state.GetPointOfViewControllers()[j]; return (t >= 0 && t <= 4500) || (t >= 31500 && t < 36000); });
|
() => { int t = _state.GetPointOfViewControllers()[j]; return (t >= 0 && t <= 4500) || (t >= 31500 && t < 36000); });
|
||||||
AddItem($"POV{i + 1}D",
|
AddItem($"POV{i + 1}D",
|
||||||
() => { int t = state.GetPointOfViewControllers()[j]; return t >= 13500 && t <= 22500; });
|
() => { int t = _state.GetPointOfViewControllers()[j]; return t >= 13500 && t <= 22500; });
|
||||||
AddItem($"POV{i + 1}L",
|
AddItem($"POV{i + 1}L",
|
||||||
() => { int t = state.GetPointOfViewControllers()[j]; return t >= 22500 && t <= 31500; });
|
() => { int t = _state.GetPointOfViewControllers()[j]; return t >= 22500 && t <= 31500; });
|
||||||
AddItem($"POV{i + 1}R",
|
AddItem($"POV{i + 1}R",
|
||||||
() => { int t = state.GetPointOfViewControllers()[j]; return t >= 4500 && t <= 13500; });
|
() => { int t = _state.GetPointOfViewControllers()[j]; return t >= 4500 && t <= 13500; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that this does not appear to work at this time. I probably need to have more infos.
|
// Note that this does not appear to work at this time. I probably need to have more infos.
|
||||||
public void SetVibration(int left, int right)
|
public void SetVibration(int left, int right)
|
||||||
{
|
{
|
||||||
int[] temp1, temp2;
|
// my first clue that it doesn't work is that LEFT and RIGHT _AREN'T USED_
|
||||||
// my first clue that it doesnt work is that LEFT and RIGHT _ARENT USED_
|
|
||||||
// I should just look for C++ examples instead of trying to look for SlimDX examples
|
// I should just look for C++ examples instead of trying to look for SlimDX examples
|
||||||
|
|
||||||
var parameters = new EffectParameters
|
var parameters = new EffectParameters
|
||||||
|
@ -253,9 +256,9 @@ namespace BizHawk.Client.EmuHawk
|
||||||
TriggerRepeatInterval = 0x2710,
|
TriggerRepeatInterval = 0x2710,
|
||||||
Flags = EffectFlags.None
|
Flags = EffectFlags.None
|
||||||
};
|
};
|
||||||
parameters.GetAxes(out temp1, out temp2);
|
parameters.GetAxes(out var temp1, out var temp2);
|
||||||
parameters.SetAxes(temp1, temp2);
|
parameters.SetAxes(temp1, temp2);
|
||||||
var effect = new Effect(joystick, EffectGuid.ConstantForce);
|
var effect = new Effect(_joystick, EffectGuid.ConstantForce);
|
||||||
effect.SetParameters(parameters);
|
effect.SetParameters(parameters);
|
||||||
effect.Start(1);
|
effect.Start(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,29 +3,23 @@ using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using BizHawk.Common;
|
using BizHawk.Common;
|
||||||
|
|
||||||
using SlimDX.XInput;
|
using SlimDX.XInput;
|
||||||
|
|
||||||
#pragma warning disable 169
|
|
||||||
#pragma warning disable 414
|
|
||||||
|
|
||||||
namespace BizHawk.Client.EmuHawk
|
namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
public class GamePad360
|
public class GamePad360
|
||||||
{
|
{
|
||||||
// ********************************** Static interface **********************************
|
// ********************************** Static interface **********************************
|
||||||
|
|
||||||
private static readonly object _syncObj = new object();
|
private static readonly object SyncObj = new object();
|
||||||
private static readonly List<GamePad360> _devices = new List<GamePad360>();
|
private static readonly List<GamePad360> Devices = new List<GamePad360>();
|
||||||
private static readonly bool _isAvailable;
|
private static readonly bool IsAvailable;
|
||||||
|
|
||||||
delegate uint XInputGetStateExProcDelegate(uint dwUserIndex, out XINPUT_STATE state);
|
delegate uint XInputGetStateExProcDelegate(uint dwUserIndex, out XINPUT_STATE state);
|
||||||
|
|
||||||
static bool HasGetInputStateEx;
|
private static readonly XInputGetStateExProcDelegate XInputGetStateExProc;
|
||||||
static IntPtr LibraryHandle;
|
|
||||||
static XInputGetStateExProcDelegate XInputGetStateExProc;
|
|
||||||
|
|
||||||
struct XINPUT_GAMEPAD
|
private struct XINPUT_GAMEPAD
|
||||||
{
|
{
|
||||||
public ushort wButtons;
|
public ushort wButtons;
|
||||||
public byte bLeftTrigger;
|
public byte bLeftTrigger;
|
||||||
|
@ -36,7 +30,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
public short sThumbRY;
|
public short sThumbRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XINPUT_STATE
|
private struct XINPUT_STATE
|
||||||
{
|
{
|
||||||
public uint dwPacketNumber;
|
public uint dwPacketNumber;
|
||||||
public XINPUT_GAMEPAD Gamepad;
|
public XINPUT_GAMEPAD Gamepad;
|
||||||
|
@ -51,7 +45,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
var libraryHandle = llManager.LoadOrNull("xinput1_3.dll") ?? llManager.LoadOrNull("xinput1_4.dll");
|
var libraryHandle = llManager.LoadOrNull("xinput1_3.dll") ?? llManager.LoadOrNull("xinput1_4.dll");
|
||||||
if (libraryHandle != null)
|
if (libraryHandle != null)
|
||||||
{
|
{
|
||||||
HasGetInputStateEx = true;
|
|
||||||
XInputGetStateExProc = (XInputGetStateExProcDelegate) Marshal.GetDelegateForFunctionPointer(
|
XInputGetStateExProc = (XInputGetStateExProcDelegate) Marshal.GetDelegateForFunctionPointer(
|
||||||
Win32Imports.GetProcAddressOrdinal(libraryHandle.Value, new IntPtr(100)),
|
Win32Imports.GetProcAddressOrdinal(libraryHandle.Value, new IntPtr(100)),
|
||||||
typeof(XInputGetStateExProcDelegate)
|
typeof(XInputGetStateExProcDelegate)
|
||||||
|
@ -59,15 +52,13 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HasGetInputStateEx = false;
|
|
||||||
libraryHandle = llManager.LoadOrNull("xinput9_1_0.dll");
|
libraryHandle = llManager.LoadOrNull("xinput9_1_0.dll");
|
||||||
}
|
}
|
||||||
_isAvailable = libraryHandle != null;
|
IsAvailable = libraryHandle != null;
|
||||||
LibraryHandle = libraryHandle ?? IntPtr.Zero;
|
|
||||||
|
|
||||||
// don't remove this code. it's important to catch errors on systems with broken xinput installs.
|
// don't remove this code. it's important to catch errors on systems with broken xinput installs.
|
||||||
// (probably, checking for the library was adequate, but let's not get rid of this anyway)
|
// (probably, checking for the library was adequate, but let's not get rid of this anyway)
|
||||||
if (_isAvailable) _ = new Controller(UserIndex.One).IsConnected;
|
if (IsAvailable) _ = new Controller(UserIndex.One).IsConnected;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -77,35 +68,35 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
lock (_syncObj)
|
lock (SyncObj)
|
||||||
{
|
{
|
||||||
_devices.Clear();
|
Devices.Clear();
|
||||||
|
|
||||||
if (!_isAvailable)
|
if (!IsAvailable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//now, at this point, slimdx may be using one xinput, and we may be using another
|
//now, at this point, SlimDX may be using one xinput, and we may be using another
|
||||||
//i'm not sure how slimdx picks its dll to bind to.
|
//i'm not sure how SlimDX picks its dll to bind to.
|
||||||
//i'm not sure how troublesome this will be
|
//i'm not sure how troublesome this will be
|
||||||
//maybe we should get rid of slimdx for this altogether
|
//maybe we should get rid of SlimDX for this altogether
|
||||||
|
|
||||||
var c1 = new Controller(UserIndex.One);
|
var c1 = new Controller(UserIndex.One);
|
||||||
var c2 = new Controller(UserIndex.Two);
|
var c2 = new Controller(UserIndex.Two);
|
||||||
var c3 = new Controller(UserIndex.Three);
|
var c3 = new Controller(UserIndex.Three);
|
||||||
var c4 = new Controller(UserIndex.Four);
|
var c4 = new Controller(UserIndex.Four);
|
||||||
|
|
||||||
if (c1.IsConnected) _devices.Add(new GamePad360(0, c1));
|
if (c1.IsConnected) Devices.Add(new GamePad360(0, c1));
|
||||||
if (c2.IsConnected) _devices.Add(new GamePad360(1, c2));
|
if (c2.IsConnected) Devices.Add(new GamePad360(1, c2));
|
||||||
if (c3.IsConnected) _devices.Add(new GamePad360(2, c3));
|
if (c3.IsConnected) Devices.Add(new GamePad360(2, c3));
|
||||||
if (c4.IsConnected) _devices.Add(new GamePad360(3, c4));
|
if (c4.IsConnected) Devices.Add(new GamePad360(3, c4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<GamePad360> EnumerateDevices()
|
public static IEnumerable<GamePad360> EnumerateDevices()
|
||||||
{
|
{
|
||||||
lock (_syncObj)
|
lock (SyncObj)
|
||||||
{
|
{
|
||||||
foreach (var device in _devices)
|
foreach (var device in Devices)
|
||||||
{
|
{
|
||||||
yield return device;
|
yield return device;
|
||||||
}
|
}
|
||||||
|
@ -114,9 +105,9 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
public static void UpdateAll()
|
public static void UpdateAll()
|
||||||
{
|
{
|
||||||
lock (_syncObj)
|
lock (SyncObj)
|
||||||
{
|
{
|
||||||
foreach (var device in _devices)
|
foreach (var device in Devices)
|
||||||
{
|
{
|
||||||
device.Update();
|
device.Update();
|
||||||
}
|
}
|
||||||
|
@ -125,124 +116,117 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
// ********************************** Instance Members **********************************
|
// ********************************** Instance Members **********************************
|
||||||
|
|
||||||
readonly Controller controller;
|
private readonly Controller _controller;
|
||||||
uint index0;
|
private readonly uint _index0;
|
||||||
XINPUT_STATE state;
|
private XINPUT_STATE _state;
|
||||||
|
|
||||||
public int PlayerNumber { get { return (int)index0 + 1; } }
|
public int PlayerNumber => (int)_index0 + 1;
|
||||||
|
|
||||||
GamePad360(uint index0, Controller c)
|
GamePad360(uint index0, Controller c)
|
||||||
{
|
{
|
||||||
this.index0 = index0;
|
this._index0 = index0;
|
||||||
controller = c;
|
_controller = c;
|
||||||
InitializeButtons();
|
InitializeButtons();
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
if (controller.IsConnected == false)
|
if (_controller.IsConnected == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (XInputGetStateExProc != null)
|
if (XInputGetStateExProc != null)
|
||||||
{
|
{
|
||||||
state = new XINPUT_STATE();
|
_state = new XINPUT_STATE();
|
||||||
XInputGetStateExProc(index0, out state);
|
XInputGetStateExProc(_index0, out _state);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var slimstate = controller.GetState();
|
var slimState = _controller.GetState();
|
||||||
state.dwPacketNumber = slimstate.PacketNumber;
|
_state.dwPacketNumber = slimState.PacketNumber;
|
||||||
state.Gamepad.wButtons = (ushort)slimstate.Gamepad.Buttons;
|
_state.Gamepad.wButtons = (ushort)slimState.Gamepad.Buttons;
|
||||||
state.Gamepad.sThumbLX = slimstate.Gamepad.LeftThumbX;
|
_state.Gamepad.sThumbLX = slimState.Gamepad.LeftThumbX;
|
||||||
state.Gamepad.sThumbLY = slimstate.Gamepad.LeftThumbY;
|
_state.Gamepad.sThumbLY = slimState.Gamepad.LeftThumbY;
|
||||||
state.Gamepad.sThumbRX = slimstate.Gamepad.RightThumbX;
|
_state.Gamepad.sThumbRX = slimState.Gamepad.RightThumbX;
|
||||||
state.Gamepad.sThumbRY = slimstate.Gamepad.RightThumbY;
|
_state.Gamepad.sThumbRY = slimState.Gamepad.RightThumbY;
|
||||||
state.Gamepad.bLeftTrigger = slimstate.Gamepad.LeftTrigger;
|
_state.Gamepad.bLeftTrigger = slimState.Gamepad.LeftTrigger;
|
||||||
state.Gamepad.bRightTrigger = slimstate.Gamepad.RightTrigger;
|
_state.Gamepad.bRightTrigger = slimState.Gamepad.RightTrigger;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Tuple<string, float>> GetFloats()
|
public IEnumerable<Tuple<string, float>> GetFloats()
|
||||||
{
|
{
|
||||||
var g = state.Gamepad;
|
var g = _state.Gamepad;
|
||||||
|
|
||||||
//constant for adapting a +/- 32768 range to a +/-10000-based range
|
//constant for adapting a +/- 32768 range to a +/-10000-based range
|
||||||
const float f = 32768 / 10000.0f;
|
const float f = 32768 / 10000.0f;
|
||||||
|
|
||||||
//since our whole input framework really only understands whole axes, let's make the triggers look like an axis
|
//since our whole input framework really only understands whole axes, let's make the triggers look like an axis
|
||||||
float ltrig = g.bLeftTrigger / 255.0f * 2 - 1;
|
float lTrig = g.bLeftTrigger / 255.0f * 2 - 1;
|
||||||
float rtrig = g.bRightTrigger / 255.0f * 2 - 1;
|
float rTrig = g.bRightTrigger / 255.0f * 2 - 1;
|
||||||
ltrig *= 10000;
|
lTrig *= 10000;
|
||||||
rtrig *= 10000;
|
rTrig *= 10000;
|
||||||
|
|
||||||
yield return new Tuple<string, float>("LeftThumbX", g.sThumbLX / f);
|
yield return new Tuple<string, float>("LeftThumbX", g.sThumbLX / f);
|
||||||
yield return new Tuple<string, float>("LeftThumbY", g.sThumbLY / f);
|
yield return new Tuple<string, float>("LeftThumbY", g.sThumbLY / f);
|
||||||
yield return new Tuple<string, float>("RightThumbX", g.sThumbRX / f);
|
yield return new Tuple<string, float>("RightThumbX", g.sThumbRX / f);
|
||||||
yield return new Tuple<string, float>("RightThumbY", g.sThumbRY / f);
|
yield return new Tuple<string, float>("RightThumbY", g.sThumbRY / f);
|
||||||
yield return new Tuple<string, float>("LeftTrigger", ltrig);
|
yield return new Tuple<string, float>("LeftTrigger", lTrig);
|
||||||
yield return new Tuple<string, float>("RightTrigger", rtrig);
|
yield return new Tuple<string, float>("RightTrigger", rTrig);
|
||||||
yield break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int NumButtons { get; private set; }
|
public int NumButtons { get; private set; }
|
||||||
|
|
||||||
private readonly List<string> names = new List<string>();
|
private readonly List<string> _names = new List<string>();
|
||||||
private readonly List<Func<bool>> actions = new List<Func<bool>>();
|
private readonly List<Func<bool>> _actions = new List<Func<bool>>();
|
||||||
|
|
||||||
void InitializeButtons()
|
private void InitializeButtons()
|
||||||
{
|
{
|
||||||
const int dzp = 20000;
|
const int dzp = 20000;
|
||||||
const int dzn = -20000;
|
const int dzn = -20000;
|
||||||
const int dzt = 40;
|
const int dzt = 40;
|
||||||
|
|
||||||
AddItem("A", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.A) != 0);
|
AddItem("A", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.A) != 0);
|
||||||
AddItem("B", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.B) != 0);
|
AddItem("B", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.B) != 0);
|
||||||
AddItem("X", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.X) != 0);
|
AddItem("X", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.X) != 0);
|
||||||
AddItem("Y", () => (state.Gamepad.wButtons & unchecked((ushort)GamepadButtonFlags.Y)) != 0);
|
AddItem("Y", () => (_state.Gamepad.wButtons & unchecked((ushort)GamepadButtonFlags.Y)) != 0);
|
||||||
AddItem("Guide", () => (state.Gamepad.wButtons & 1024) != 0);
|
AddItem("Guide", () => (_state.Gamepad.wButtons & 1024) != 0);
|
||||||
|
|
||||||
AddItem("Start", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.Start) != 0);
|
AddItem("Start", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.Start) != 0);
|
||||||
AddItem("Back", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.Back) != 0);
|
AddItem("Back", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.Back) != 0);
|
||||||
AddItem("LeftThumb", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.LeftThumb) != 0);
|
AddItem("LeftThumb", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.LeftThumb) != 0);
|
||||||
AddItem("RightThumb", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.RightThumb) != 0);
|
AddItem("RightThumb", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.RightThumb) != 0);
|
||||||
AddItem("LeftShoulder", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.LeftShoulder) != 0);
|
AddItem("LeftShoulder", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.LeftShoulder) != 0);
|
||||||
AddItem("RightShoulder", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.RightShoulder) != 0);
|
AddItem("RightShoulder", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.RightShoulder) != 0);
|
||||||
|
|
||||||
AddItem("DpadUp", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.DPadUp) != 0);
|
AddItem("DpadUp", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.DPadUp) != 0);
|
||||||
AddItem("DpadDown", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.DPadDown) != 0);
|
AddItem("DpadDown", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.DPadDown) != 0);
|
||||||
AddItem("DpadLeft", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.DPadLeft) != 0);
|
AddItem("DpadLeft", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.DPadLeft) != 0);
|
||||||
AddItem("DpadRight", () => (state.Gamepad.wButtons & (ushort)GamepadButtonFlags.DPadRight) != 0);
|
AddItem("DpadRight", () => (_state.Gamepad.wButtons & (ushort)GamepadButtonFlags.DPadRight) != 0);
|
||||||
|
|
||||||
AddItem("LStickUp", () => state.Gamepad.sThumbLY >= dzp);
|
AddItem("LStickUp", () => _state.Gamepad.sThumbLY >= dzp);
|
||||||
AddItem("LStickDown", () => state.Gamepad.sThumbLY <= dzn);
|
AddItem("LStickDown", () => _state.Gamepad.sThumbLY <= dzn);
|
||||||
AddItem("LStickLeft", () => state.Gamepad.sThumbLX <= dzn);
|
AddItem("LStickLeft", () => _state.Gamepad.sThumbLX <= dzn);
|
||||||
AddItem("LStickRight", () => state.Gamepad.sThumbLX >= dzp);
|
AddItem("LStickRight", () => _state.Gamepad.sThumbLX >= dzp);
|
||||||
|
|
||||||
AddItem("RStickUp", () => state.Gamepad.sThumbRY >= dzp);
|
AddItem("RStickUp", () => _state.Gamepad.sThumbRY >= dzp);
|
||||||
AddItem("RStickDown", () => state.Gamepad.sThumbRY <= dzn);
|
AddItem("RStickDown", () => _state.Gamepad.sThumbRY <= dzn);
|
||||||
AddItem("RStickLeft", () => state.Gamepad.sThumbRX <= dzn);
|
AddItem("RStickLeft", () => _state.Gamepad.sThumbRX <= dzn);
|
||||||
AddItem("RStickRight", () => state.Gamepad.sThumbRX >= dzp);
|
AddItem("RStickRight", () => _state.Gamepad.sThumbRX >= dzp);
|
||||||
|
|
||||||
AddItem("LeftTrigger", () => state.Gamepad.bLeftTrigger > dzt);
|
AddItem("LeftTrigger", () => _state.Gamepad.bLeftTrigger > dzt);
|
||||||
AddItem("RightTrigger", () => state.Gamepad.bRightTrigger > dzt);
|
AddItem("RightTrigger", () => _state.Gamepad.bRightTrigger > dzt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddItem(string name, Func<bool> pressed)
|
private void AddItem(string name, Func<bool> pressed)
|
||||||
{
|
{
|
||||||
names.Add(name);
|
_names.Add(name);
|
||||||
actions.Add(pressed);
|
_actions.Add(pressed);
|
||||||
NumButtons++;
|
NumButtons++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ButtonName(int index)
|
public string ButtonName(int index) => _names[index];
|
||||||
{
|
|
||||||
return names[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Pressed(int index)
|
public bool Pressed(int index) => _actions[index]();
|
||||||
{
|
|
||||||
return actions[index]();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
KeyInput.Initialize(parent);
|
KeyInput.Initialize(parent);
|
||||||
IPCKeyInput.Initialize();
|
IPCKeyInput.Initialize();
|
||||||
GamePad.Initialize();
|
GamePad.Initialize(parent);
|
||||||
GamePad360.Initialize();
|
GamePad360.Initialize();
|
||||||
}
|
}
|
||||||
Instance = new Input();
|
Instance = new Input();
|
||||||
|
|
|
@ -2769,7 +2769,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
switch (m.Msg)
|
switch (m.Msg)
|
||||||
{
|
{
|
||||||
case WmDeviceChange:
|
case WmDeviceChange:
|
||||||
GamePad.Initialize();
|
GamePad.Initialize(this);
|
||||||
GamePad360.Initialize();
|
GamePad360.Initialize();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -394,6 +394,8 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Winform/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Winform/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=winforms/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=winforms/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=WSWAN/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=WSWAN/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=XBOX/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=xinput/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xjin/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xjin/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Yabause/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Yabause/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Zipheader/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Zipheader/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|
Loading…
Reference in New Issue