diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
index 86dcd49b0c..3b94629eba 100644
--- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
+++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
@@ -84,7 +84,7 @@
..\output\dll\nlua\NLua.dll
False
-
+
False
..\References\OpenTK.dll
diff --git a/BizHawk.Client.EmuHawk/Input/Input.cs b/BizHawk.Client.EmuHawk/Input/Input.cs
index a890029682..c1d873ad76 100644
--- a/BizHawk.Client.EmuHawk/Input/Input.cs
+++ b/BizHawk.Client.EmuHawk/Input/Input.cs
@@ -133,7 +133,7 @@ namespace BizHawk.Client.EmuHawk
else
{
OTK_Keyboard.Initialize();
-// OTK_Gamepad.Initialize();
+ OTK_GamePad.Initialize();
}
Instance = new Input();
}
@@ -341,7 +341,7 @@ namespace BizHawk.Client.EmuHawk
}
else
{
- //TODO
+ OTK_GamePad.UpdateAll();
}
//this block is going to massively modify data structures that the binding method uses, so we have to lock it all
@@ -357,6 +357,22 @@ namespace BizHawk.Client.EmuHawk
{
//FloatValues.Clear();
+ // analyse OpenTK xinput (or is it libinput?)
+ foreach (var pad in OTK_GamePad.EnumerateDevices())
+ {
+ foreach (var but in pad.buttonObjects)
+ {
+ HandleButton(pad.InputNamePrefix + but.ButtonName, but.ButtonAction());
+ }
+ foreach (var sv in pad.GetFloats())
+ {
+ var n = $"{pad.InputNamePrefix}{sv.Item1} Axis";
+ var f = sv.Item2;
+ if (trackdeltas) FloatDeltas[n] += Math.Abs(f - FloatValues[n]);
+ FloatValues[n] = f;
+ }
+ }
+
//analyze xinput
foreach (var pad in GamePad360.EnumerateDevices())
{
diff --git a/BizHawk.Client.EmuHawk/Input/OTK_Gamepad.cs b/BizHawk.Client.EmuHawk/Input/OTK_Gamepad.cs
index da73c5e2ac..e9109a3d87 100644
--- a/BizHawk.Client.EmuHawk/Input/OTK_Gamepad.cs
+++ b/BizHawk.Client.EmuHawk/Input/OTK_Gamepad.cs
@@ -1,148 +1,367 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+
using OpenTK.Input;
+using OpenTKGamePad = OpenTK.Input.GamePad;
+
namespace BizHawk.Client.EmuHawk
{
+ ///
+ /// Modified OpenTK Gamepad Handler
+ /// The jump from OpenTK 1.x to 3.x broke the original OpenTK.Input.Joystick implementation, but we gain OpenTK.Input.GamePad support on Unix. However, the gamepad auto-mapping is a little suspect, so we use both methods.
+ /// As a side-effect, it should make it easier to implement virtual→host haptics in the future.
+ ///
public class OTK_GamePad
{
- //Note: OpenTK has both Gamepad and Joystick classes. An OpenTK Gamepad is a simplified version of Joystick
- //with pre-defined features that match an XInput controller. They did this to mimic XNA's controller API.
- //We're going to use Joystick directly, because it gives us full access to all possible buttons.
- //And it looks like GamePad itself isn't supported on OpenTK OS X.
+ #region Static Members
- public static List Devices;
- private const int MAX_JOYSTICKS = 4; //They don't have a way to query this for some reason. 4 is the minimum promised.
+ /// They don't have a way to query this for some reason. 4 is the minimum promised.
+ private const int MAX_GAMEPADS = 4;
+ private static readonly object _syncObj = new object();
+
+ private static readonly List Devices = new List();
+
+ /// Initialization is only called once when MainForm loads
public static void Initialize()
{
- Devices = new List();
-
- for (int i = 0; i < MAX_JOYSTICKS; i++)
+ CloseAll();
+ var playerCount = 0;
+ for (var i = 0; i < MAX_GAMEPADS; i++)
{
- JoystickState jss = Joystick.GetState(i);
- if (jss.IsConnected)
+ if (OpenTKGamePad.GetState(i).IsConnected || Joystick.GetState(i).IsConnected)
{
- Console.WriteLine($"joydevice index: {i}"); //OpenTK doesn't expose the GUID, even though it stores it internally...
-
- OTK_GamePad ogp = new OTK_GamePad(i);
- Devices.Add(ogp);
+ Console.WriteLine($"OTK GamePad/Joystick index: {i}");
+ Devices.Add(new OTK_GamePad(i, ++playerCount));
}
}
+ }
+ public static IEnumerable EnumerateDevices()
+ {
+ lock (_syncObj)
+ {
+ foreach (var device in Devices) yield return device;
+ }
}
public static void UpdateAll()
{
- foreach (var device in Devices)
- device.Update();
+ lock (_syncObj)
+ {
+ foreach (var device in Devices) device.Update();
+ }
}
public static void CloseAll()
{
- if (Devices != null)
+ lock (_syncObj)
{
Devices.Clear();
}
}
- // ********************************** Instance Members **********************************
-
- readonly Guid _guid;
- readonly int _stickIdx;
- JoystickState state = new JoystickState();
-
- OTK_GamePad(int index)
+ /// The things that use (analog controls) appear to require values -10000.0..10000.0 rather than the -1.0..1.0 that OpenTK returns (although even then the results may be slightly outside of these bounds)
+ private static float ConstrainFloatInput(float num)
{
- _guid = Guid.NewGuid();
- _stickIdx = index;
+ if (num > 1) return 10000.0f;
+ if (num < -1) return -10000.0f;
+ return num * 10000.0f;
+ }
+
+ #endregion
+
+ #region Instance Members
+
+ /// The GUID as detected by OpenTK.Input.Joystick (or if that failed, a random one generated on construction)
+ public readonly Guid Guid;
+
+ /// Signals whether OpenTK returned a GUID for this device
+ private readonly bool _guidObtained;
+
+ /// The OpenTK device index
+ private readonly int _deviceIndex;
+
+ /// The index to lookup into Devices
+ private readonly int _playerIndex;
+
+ /// The name (if any) that OpenTK GamePad has resolved via its internal mapping database
+ private readonly string _name;
+
+ /// The object returned by
+ private readonly GamePadCapabilities? _gamePadCapabilities;
+
+ /// The object returned by
+ private readonly JoystickCapabilities? _joystickCapabilities;
+
+ /// For use in keybind boxes
+ public readonly string InputNamePrefix;
+
+ /// Public check on whether mapped gamepad config is being used
+ public bool MappedGamePad => _gamePadCapabilities?.IsMapped == true;
+
+ /// Gamepad Device state information - updated constantly
+ private GamePadState state;
+
+ /// Joystick Device state information - updated constantly
+ private JoystickState jState;
+
+ private OTK_GamePad(int index, int playerIndex)
+ {
+ _deviceIndex = index;
+ _playerIndex = playerIndex;
+
+ if (Joystick.GetState(_deviceIndex).IsConnected)
+ {
+ Guid = Joystick.GetGuid(_deviceIndex);
+ _guidObtained = true;
+ _joystickCapabilities = Joystick.GetCapabilities(_deviceIndex);
+ }
+ else
+ {
+ Guid = Guid.NewGuid();
+ _guidObtained = false;
+ }
+
+ if (OpenTKGamePad.GetState(_deviceIndex).IsConnected)
+ {
+ _name = OpenTKGamePad.GetName(_deviceIndex);
+ _gamePadCapabilities = OpenTKGamePad.GetCapabilities(_deviceIndex);
+ }
+ else
+ {
+ _name = "OTK GamePad Undetermined Name";
+ }
+
+ InputNamePrefix = $"{(MappedGamePad ? "X" : "J")}{_playerIndex} ";
+
Update();
- InitializeCallbacks();
+
+ Console.WriteLine($"Initialising OpenTK GamePad: {Guid}");
+ Console.WriteLine($"OpenTK Mapping: {_name}");
+
+ InitializeMappings();
}
public void Update()
{
- state = Joystick.GetState(_stickIdx);
+ // update both here just in case
+ var tmpState = OpenTKGamePad.GetState(_deviceIndex);
+ DebugState(tmpState);
+ state = tmpState;
+ var tmpJstate = Joystick.GetState(_deviceIndex);
+ DebugState(tmpJstate);
+ jState = tmpJstate;
+ }
+
+ [Conditional("DEBUG")]
+ private void DebugState(GamePadState tmpState)
+ {
+ if (!tmpState.Equals(state)) Debug.WriteLine($"GamePad State:\t{tmpState}");
+ }
+
+ [Conditional("DEBUG")]
+ private void DebugState(JoystickState tmpJstate)
+ {
+ if (!tmpJstate.Equals(jState)) Debug.WriteLine($"Joystick State:\t{tmpJstate}");
}
public IEnumerable> GetFloats()
{
- for (int pi = 0; pi < 64; pi++)
- yield return new Tuple(pi.ToString(), 10.0f * state.GetAxis(pi));
- }
-
- /// FOR DEBUGGING ONLY
- public JoystickState GetInternalState()
- {
- return state;
- }
-
- public string Name { get { return $"Joystick {_stickIdx}"; } }
- public Guid Guid { get { return _guid; } }
-
-
- public string ButtonName(int index)
- {
- return names[index];
- }
- public bool Pressed(int index)
- {
- return actions[index]();
- }
- public int NumButtons { get; private set; }
-
- private readonly List names = new List();
- private readonly List> actions = new List>();
-
- void AddItem(string _name, Func callback)
- {
- names.Add(_name);
- actions.Add(callback);
- NumButtons++;
- }
-
- void InitializeCallbacks()
- {
- const int dzp = 400;
- const int dzn = -400;
-
- names.Clear();
- actions.Clear();
- NumButtons = 0;
-
- AddItem("X+", () => state.GetAxis(0) >= dzp);
- AddItem("X-", () => state.GetAxis(0) <= dzn);
- AddItem("Y+", () => state.GetAxis(1) >= dzp);
- AddItem("Y-", () => state.GetAxis(1) <= dzn);
- AddItem("Z+", () => state.GetAxis(2) >= dzp);
- AddItem("Z-", () => state.GetAxis(2) <= dzn);
-
- // Enjoy our delicious sliders. They're smaller than regular burgers but cost more.
-
- int jb = 1;
- for (int i = 0; i < 64; i++)
+ if (MappedGamePad)
{
- AddItem($"B{jb}", () => state.GetButton(i)==ButtonState.Pressed);
- jb++;
+ // automapping identified - use OpenTKGamePad
+ yield return new Tuple("LeftThumbX", ConstrainFloatInput(state.ThumbSticks.Left.X));
+ yield return new Tuple("LeftThumbY", ConstrainFloatInput(state.ThumbSticks.Left.Y));
+ yield return new Tuple("RightThumbX", ConstrainFloatInput(state.ThumbSticks.Right.X));
+ yield return new Tuple("RightThumbY", ConstrainFloatInput(state.ThumbSticks.Right.Y));
+ yield return new Tuple("LeftTrigger", ConstrainFloatInput(state.Triggers.Left));
+ yield return new Tuple("RightTrigger", ConstrainFloatInput(state.Triggers.Right));
+ yield break;
}
-
- jb = 1;
- foreach (JoystickHat enval in Enum.GetValues(typeof(JoystickHat)))
+ else
{
- AddItem($"POV{jb}U", () => state.GetHat(enval).IsUp);
- AddItem($"POV{jb}D", () => state.GetHat(enval).IsDown);
- AddItem($"POV{jb}L", () => state.GetHat(enval).IsLeft);
- AddItem($"POV{jb}R", () => state.GetHat(enval).IsRight);
- jb++;
+ // use Joystick
+ yield return new Tuple("X", ConstrainFloatInput(jState.GetAxis(0)));
+ yield return new Tuple("Y", ConstrainFloatInput(jState.GetAxis(1)));
+ yield return new Tuple("Z", ConstrainFloatInput(jState.GetAxis(2)));
+ yield return new Tuple("W", ConstrainFloatInput(jState.GetAxis(3)));
+ yield return new Tuple("V", ConstrainFloatInput(jState.GetAxis(4)));
+ yield return new Tuple("S", ConstrainFloatInput(jState.GetAxis(5)));
+ yield return new Tuple("Q", ConstrainFloatInput(jState.GetAxis(6)));
+ yield return new Tuple("P", ConstrainFloatInput(jState.GetAxis(7)));
+ yield return new Tuple("N", ConstrainFloatInput(jState.GetAxis(8)));
+
+ for (var i = 9; i < 64; i++)
+ {
+ var j = i;
+ yield return new Tuple($"Axis{j.ToString()}", ConstrainFloatInput(jState.GetAxis(j)));
+ }
+
+ yield break;
}
}
- // 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 string Name => $"Joystick {_playerIndex} ({_name})";
+
+ /// Contains name and delegate function for all buttons, hats and axis
+ public readonly List buttonObjects = new List();
+
+ private void AddItem(string name, Func pressed) =>
+ buttonObjects.Add(new ButtonObject
+ {
+ ButtonName = name,
+ ButtonAction = pressed
+ });
+
+ public struct ButtonObject
{
- //Not supported in OTK Joystick. It is supported for OTK Gamepad, but I have to use Joystick for reasons mentioned above.
+ public string ButtonName;
+ public Func ButtonAction;
}
+ ///
+ /// Setup mappings prior to button initialization.
+ /// This is also here in case in the future we want users to be able to supply their own mappings for a device, perhaps via an input form. Possibly wishful thinking/overly complex.
+ ///
+ private void InitializeMappings()
+ {
+ if (_guidObtained)
+ {
+ // placeholder for if/when we figure out how to supply OpenTK with custom GamePadConfigurationDatabase entries
+ }
+
+ // currently OpenTK has an internal database of mappings for the GamePad class: https://github.com/opentk/opentk/blob/master/src/OpenTK/Input/GamePadConfigurationDatabase.cs
+ if (MappedGamePad)
+ {
+ // internal map detected - use OpenTKGamePad
+ InitializeGamePadControls();
+ }
+ else
+ {
+ // no internal map detected - use Joystick
+ InitializeJoystickControls();
+ }
+ }
+
+ private void InitializeJoystickControls()
+ {
+ // OpenTK's GetAxis returns float values (as opposed to the shorts of SlimDX)
+ const float ConversionFactor = 1.0f / short.MaxValue;
+ const float dzp = (short)4000 * ConversionFactor;
+ const float dzn = (short)-4000 * ConversionFactor;
+ //const float dzt = 0.6f;
+
+ // axis
+ AddItem("X+", () => jState.GetAxis(0) >= dzp);
+ AddItem("X-", () => jState.GetAxis(0) <= dzn);
+ AddItem("Y+", () => jState.GetAxis(1) >= dzp);
+ AddItem("Y-", () => jState.GetAxis(1) <= dzn);
+ AddItem("Z+", () => jState.GetAxis(2) >= dzp);
+ AddItem("Z-", () => jState.GetAxis(2) <= dzn);
+ AddItem("W+", () => jState.GetAxis(3) >= dzp);
+ AddItem("W-", () => jState.GetAxis(3) <= dzn);
+ AddItem("V+", () => jState.GetAxis(4) >= dzp);
+ AddItem("V-", () => jState.GetAxis(4) <= dzn);
+ AddItem("S+", () => jState.GetAxis(5) >= dzp);
+ AddItem("S-", () => jState.GetAxis(5) <= dzn);
+ AddItem("Q+", () => jState.GetAxis(6) >= dzp);
+ AddItem("Q-", () => jState.GetAxis(6) <= dzn);
+ AddItem("P+", () => jState.GetAxis(7) >= dzp);
+ AddItem("P-", () => jState.GetAxis(7) <= dzn);
+ AddItem("N+", () => jState.GetAxis(8) >= dzp);
+ AddItem("N-", () => jState.GetAxis(8) <= dzn);
+ // should be enough axis, but just in case:
+ for (var i = 9; i < 64; i++)
+ {
+ var j = i;
+ AddItem($"Axis{j.ToString()}+", () => jState.GetAxis(j) >= dzp);
+ AddItem($"Axis{j.ToString()}-", () => jState.GetAxis(j) <= dzn);
+ }
+
+ // buttons
+ for (var i = 0; i < (_joystickCapabilities?.ButtonCount ?? 0); i++)
+ {
+ var j = i;
+ AddItem($"B{i + 1}", () => jState.GetButton(j) == ButtonState.Pressed);
+ }
+
+ // hats
+ AddItem("POV1U", () => jState.GetHat(JoystickHat.Hat0).IsUp);
+ AddItem("POV1D", () => jState.GetHat(JoystickHat.Hat0).IsDown);
+ AddItem("POV1L", () => jState.GetHat(JoystickHat.Hat0).IsLeft);
+ AddItem("POV1R", () => jState.GetHat(JoystickHat.Hat0).IsRight);
+ AddItem("POV2U", () => jState.GetHat(JoystickHat.Hat1).IsUp);
+ AddItem("POV2D", () => jState.GetHat(JoystickHat.Hat1).IsDown);
+ AddItem("POV2L", () => jState.GetHat(JoystickHat.Hat1).IsLeft);
+ AddItem("POV2R", () => jState.GetHat(JoystickHat.Hat1).IsRight);
+ AddItem("POV3U", () => jState.GetHat(JoystickHat.Hat2).IsUp);
+ AddItem("POV3D", () => jState.GetHat(JoystickHat.Hat2).IsDown);
+ AddItem("POV3L", () => jState.GetHat(JoystickHat.Hat2).IsLeft);
+ AddItem("POV3R", () => jState.GetHat(JoystickHat.Hat2).IsRight);
+ AddItem("POV4U", () => jState.GetHat(JoystickHat.Hat3).IsUp);
+ AddItem("POV4D", () => jState.GetHat(JoystickHat.Hat3).IsDown);
+ AddItem("POV4L", () => jState.GetHat(JoystickHat.Hat3).IsLeft);
+ AddItem("POV4R", () => jState.GetHat(JoystickHat.Hat3).IsRight);
+ }
+
+ private void InitializeGamePadControls()
+ {
+ // OpenTK's ThumbSticks contain float values (as opposed to the shorts of SlimDX)
+ const float ConversionFactor = 1.0f / short.MaxValue;
+ const float dzp = (short)4000 * ConversionFactor;
+ const float dzn = (short)-4000 * ConversionFactor;
+ const float dzt = 0.6f;
+
+ // buttons
+ AddItem("A", () => state.Buttons.A == ButtonState.Pressed);
+ AddItem("B", () => state.Buttons.B == ButtonState.Pressed);
+ AddItem("X", () => state.Buttons.X == ButtonState.Pressed);
+ AddItem("Y", () => state.Buttons.Y == ButtonState.Pressed);
+ AddItem("Guide", () => state.Buttons.BigButton == ButtonState.Pressed);
+ AddItem("Start", () => state.Buttons.Start == ButtonState.Pressed);
+ AddItem("Back", () => state.Buttons.Back == ButtonState.Pressed);
+ AddItem("LeftThumb", () => state.Buttons.LeftStick == ButtonState.Pressed);
+ AddItem("RightThumb", () => state.Buttons.RightStick == ButtonState.Pressed);
+ AddItem("LeftShoulder", () => state.Buttons.LeftShoulder == ButtonState.Pressed);
+ AddItem("RightShoulder", () => state.Buttons.RightShoulder == ButtonState.Pressed);
+
+ // dpad
+ AddItem("DpadUp", () => state.DPad.Up == ButtonState.Pressed);
+ AddItem("DpadDown", () => state.DPad.Down == ButtonState.Pressed);
+ AddItem("DpadLeft", () => state.DPad.Left == ButtonState.Pressed);
+ AddItem("DpadRight", () => state.DPad.Right == ButtonState.Pressed);
+
+ // sticks
+ AddItem("LStickUp", () => state.ThumbSticks.Left.Y >= dzp);
+ AddItem("LStickDown", () => state.ThumbSticks.Left.Y <= dzn);
+ AddItem("LStickLeft", () => state.ThumbSticks.Left.X <= dzn);
+ AddItem("LStickRight", () => state.ThumbSticks.Left.X >= dzp);
+ AddItem("RStickUp", () => state.ThumbSticks.Right.Y >= dzp);
+ AddItem("RStickDown", () => state.ThumbSticks.Right.Y <= dzn);
+ AddItem("RStickLeft", () => state.ThumbSticks.Right.X <= dzn);
+ AddItem("RStickRight", () => state.ThumbSticks.Right.X >= dzp);
+
+ // triggers
+ AddItem("LeftTrigger", () => state.Triggers.Left > dzt);
+ AddItem("RightTrigger", () => state.Triggers.Right > dzt);
+ }
+
+ ///
+ /// Sets the gamepad's left and right vibration
+ /// We don't currently use this in Bizhawk - do we have any cores that support this?
+ ///
+ ///
+ ///
+ public void SetVibration(float left, float right) => OpenTKGamePad.SetVibration(
+ _deviceIndex,
+ _gamePadCapabilities?.HasLeftVibrationMotor == true ? left : 0,
+ _gamePadCapabilities?.HasRightVibrationMotor == true ? right : 0
+ );
+
+ #endregion
}
}
diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index f589bfa790..80088fb826 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -68,10 +68,6 @@
..\References\Newtonsoft.Json.dll
-
- False
- ..\References\OpenTK.dll
-
..\References\PeNet.dll
diff --git a/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/BizHawk.Bizware.BizwareGL.GdiPlus.csproj b/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/BizHawk.Bizware.BizwareGL.GdiPlus.csproj
index d672923fe1..e8c8f7bf56 100644
--- a/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/BizHawk.Bizware.BizwareGL.GdiPlus.csproj
+++ b/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/BizHawk.Bizware.BizwareGL.GdiPlus.csproj
@@ -37,7 +37,7 @@
MinimumRecommendedRules.ruleset
-
+
False
..\..\References\OpenTK.dll
diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj
index 2f55beb615..6fc816f4c6 100644
--- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj
+++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj
@@ -41,11 +41,11 @@
false
-
+
False
..\..\References\OpenTK.dll
-
+
False
..\..\References\OpenTK.GLControl.dll
diff --git a/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/BizHawk.Bizware.BizwareGL.SlimDX.csproj b/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/BizHawk.Bizware.BizwareGL.SlimDX.csproj
index cf7d477acb..0e850c9838 100644
--- a/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/BizHawk.Bizware.BizwareGL.SlimDX.csproj
+++ b/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/BizHawk.Bizware.BizwareGL.SlimDX.csproj
@@ -37,7 +37,7 @@
MinimumRecommendedRules.ruleset
-
+
False
..\..\References\OpenTK.dll
diff --git a/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj b/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj
index 91d0f9902d..f39ab75b16 100644
--- a/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj
+++ b/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj
@@ -41,7 +41,7 @@
false
-
+
False
..\..\References\OpenTK.dll