Merge branch 'gamepad' into develop

Conflicts:
	Source/OpenTK/OpenTK.csproj
This commit is contained in:
thefiddler 2014-01-03 02:23:02 +01:00
commit 3a63496b6d
48 changed files with 4761 additions and 381 deletions

View file

@ -25,9 +25,8 @@ namespace Examples.Tests
int texture;
bool mouse_in_window = false;
bool viewport_changed = true;
bool refresh_text = true;
MouseState mouse, mouse_old;
KeyboardState keyboard, keyboard_old;
MouseState mouse;
KeyboardState keyboard;
public GameWindowStates()
: base(800, 600, GraphicsMode.Default)
@ -40,20 +39,9 @@ namespace Examples.Tests
MouseEnter += delegate { mouse_in_window = true; };
MouseLeave += delegate { mouse_in_window = false; };
Move += delegate { refresh_text = true; };
Resize += delegate { refresh_text = true; };
WindowBorderChanged += delegate { refresh_text = true; };
WindowStateChanged += delegate { refresh_text = true; };
FocusedChanged += delegate { refresh_text = true; };
Mouse.Move += MouseMoveHandler;
Mouse.ButtonDown += MouseButtonHandler;
Mouse.ButtonUp += MouseButtonHandler;
foreach (var joystick in Joysticks)
{
joystick.Move += delegate { refresh_text = true; };
joystick.ButtonDown += delegate { refresh_text = true; };
joystick.ButtonUp += delegate { refresh_text = true; };
}
}
private void KeyPressHandler(object sender, KeyPressEventArgs e)
@ -99,13 +87,10 @@ namespace Examples.Tests
void MouseMoveHandler(object sender, MouseMoveEventArgs e)
{
refresh_text = true;
}
void MouseButtonHandler(object sender, MouseButtonEventArgs e)
{
refresh_text = true;
if (e.Button == MouseButton.Left && e.IsPressed)
{
CursorVisible = false;
@ -163,7 +148,7 @@ namespace Examples.Tests
}
}
static void DrawJoysticks(Graphics gfx, IList<JoystickDevice> joysticks, int line)
static int DrawJoysticks(Graphics gfx, IList<JoystickDevice> joysticks, int line)
{
float space = gfx.MeasureString(" ", TextFont).Width;
@ -192,54 +177,45 @@ namespace Examples.Tests
line++;
}
return line;
}
protected override void OnUpdateFrame(FrameEventArgs e)
{;
{
InputDriver.Poll();
mouse = OpenTK.Input.Mouse.GetState();
if (mouse != mouse_old)
refresh_text = true;
mouse_old = mouse;
keyboard = OpenTK.Input.Keyboard.GetState();
if (keyboard != keyboard_old)
refresh_text = true;
keyboard_old = keyboard;
if (refresh_text)
using (Graphics gfx = Graphics.FromImage(TextBitmap))
{
refresh_text = false;
using (Graphics gfx = Graphics.FromImage(TextBitmap))
{
int line = 0;
int line = 0;
gfx.Clear(Color.Black);
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
gfx.Clear(Color.Black);
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
DrawString(gfx, GL.GetString(StringName.Vendor), line++);
DrawString(gfx, GL.GetString(StringName.Version), line++);
DrawString(gfx, GL.GetString(StringName.Renderer), line++);
DrawString(gfx, Context.GraphicsMode.ToString(), line++);
DrawString(gfx, GL.GetString(StringName.Vendor), line++);
DrawString(gfx, GL.GetString(StringName.Version), line++);
DrawString(gfx, GL.GetString(StringName.Renderer), line++);
DrawString(gfx, Context.GraphicsMode.ToString(), line++);
DrawString(gfx, String.Format("[1 - 4]: change WindowState (current: {0}).", this.WindowState), line++);
DrawString(gfx, String.Format("[5 - 7]: change WindowBorder (current: {0}).", this.WindowBorder), line++);
DrawString(gfx, String.Format("Focused: {0}.", this.Focused), line++);
DrawString(gfx, String.Format("Mouse {0} window.", mouse_in_window ? "inside" : "outside of"), line++);
DrawString(gfx, String.Format("Mouse visible: {0}", CursorVisible), line++);
DrawString(gfx, String.Format("Mouse position (absolute): {0}", new Vector3(Mouse.X, Mouse.Y, Mouse.Wheel)), line++);
DrawString(gfx, String.Format("Mouse position (relative): {0}", new Vector3(mouse.X, mouse.Y, mouse.WheelPrecise)), line++);
DrawString(gfx, String.Format("Window.Bounds: {0}", Bounds), line++);
DrawString(gfx, String.Format("Window.Location: {0}, Size: {1}", Location, Size), line++);
DrawString(gfx, String.Format("Window: {{X={0},Y={1},Width={2},Height={3}}}", X, Y, Width, Height), line++);
DrawString(gfx, String.Format("Window.ClientRectangle: {0}", ClientRectangle), line++);
DrawString(gfx, TypedText.ToString(), line++);
DrawKeyboard(gfx, keyboard, line++);
DrawMouse(gfx, mouse, line++);
DrawJoysticks(gfx, Joysticks, line++);
}
DrawString(gfx, String.Format("[1 - 4]: change WindowState (current: {0}).", this.WindowState), line++);
DrawString(gfx, String.Format("[5 - 7]: change WindowBorder (current: {0}).", this.WindowBorder), line++);
DrawString(gfx, String.Format("Focused: {0}.", this.Focused), line++);
DrawString(gfx, String.Format("Mouse {0} window.", mouse_in_window ? "inside" : "outside of"), line++);
DrawString(gfx, String.Format("Mouse visible: {0}", CursorVisible), line++);
DrawString(gfx, String.Format("Mouse position (absolute): {0}", new Vector3(Mouse.X, Mouse.Y, Mouse.Wheel)), line++);
DrawString(gfx, String.Format("Mouse position (relative): {0}", new Vector3(mouse.X, mouse.Y, mouse.WheelPrecise)), line++);
DrawString(gfx, String.Format("Window.Bounds: {0}", Bounds), line++);
DrawString(gfx, String.Format("Window.Location: {0}, Size: {1}", Location, Size), line++);
DrawString(gfx, String.Format("Window: {{X={0},Y={1},Width={2},Height={3}}}", X, Y, Width, Height), line++);
DrawString(gfx, String.Format("Window.ClientRectangle: {0}", ClientRectangle), line++);
DrawString(gfx, TypedText.ToString(), line++);
DrawKeyboard(gfx, keyboard, line++);
DrawMouse(gfx, mouse, line++);
line = DrawJoysticks(gfx, Joysticks, line++);
line = DrawGamePads(gfx, line++);
}
System.Drawing.Imaging.BitmapData data = TextBitmap.LockBits(
@ -249,7 +225,36 @@ namespace Examples.Tests
PixelType.UnsignedByte, data.Scan0);
TextBitmap.UnlockBits(data);
}
int DrawGamePads(Graphics gfx, int line)
{
line++;
DrawString(gfx, "GamePads:", line++);
for (int i = 0; i < 4; i++)
{
GamePadCapabilities caps = GamePad.GetCapabilities(i);
GamePadState state = GamePad.GetState(i);
if (state.IsConnected)
{
DrawString(gfx, caps.ToString(), line++);
DrawString(gfx, state.ToString(), line++);
}
}
line++;
DrawString(gfx, "Joysticks:", line++);
for (int i = 0; i < 4; i++)
{
JoystickCapabilities caps = Joystick.GetCapabilities(i);
JoystickState state = Joystick.GetState(i);
if (state.IsConnected)
{
DrawString(gfx, caps.ToString(), line++);
DrawString(gfx, state.ToString(), line++);
}
}
return line;
}
protected override void OnLoad(EventArgs e)
{

View file

@ -206,8 +206,8 @@ namespace OpenTK
{
if (!OpenTK.Platform.SDL2.SDL.WasInit(0))
{
var flags = OpenTK.Platform.SDL2.SystemFlags.EVERYTHING;
flags &= ~OpenTK.Platform.SDL2.SystemFlags.AUDIO;
var flags =
OpenTK.Platform.SDL2.SystemFlags.VIDEO | Platform.SDL2.SystemFlags.TIMER;
if (OpenTK.Platform.SDL2.SDL.Init(flags) == 0)
{
supported = true;

View file

@ -0,0 +1,166 @@
//
// GamePadButton.cs
//
// Author:
// robert <${AuthorEmail}>
//
// Copyright (c) 2012 robert
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
namespace OpenTK.Input
{
/// <summary>
/// Enumerates available buttons for a <c>GamePad</c> device.
/// </summary>
[Flags]
public enum Buttons
{
/// <summary>
/// DPad up direction button
/// </summary>
DPadUp = 1 << 0,
/// <summary>
/// DPad down direction button
/// </summary>
DPadDown = 1 << 1,
/// <summary>
/// DPad left direction button
/// </summary>
DPadLeft = 1 << 2,
/// <summary>
/// DPad right direction button
/// </summary>
DPadRight = 1 << 3,
/// <summary>
/// Start button
/// </summary>
Start = 1 << 4,
/// <summary>
/// Back button
/// </summary>
Back = 1 << 5,
/// <summary>
/// Left stick button
/// </summary>
LeftStick = 1 << 6,
/// <summary>
/// Right stick button
/// </summary>
RightStick = 1 << 7,
/// <summary>
/// Left shoulder button
/// </summary>
LeftShoulder = 1 << 8,
/// <summary>
/// Right shoulder button
/// </summary>
RightShoulder = 1 << 9,
/// <summary>
/// Home button
/// </summary>
Home = 1 << 11,
/// <summary>
/// Home button
/// </summary>
BigButton = Home,
/// <summary>
/// A button
/// </summary>
A = 1 << 12,
/// <summary>
/// B button
/// </summary>
B = 1 << 13,
/// <summary>
/// X button
/// </summary>
X = 1 << 14,
/// <summary>
/// Y button
/// </summary>
Y = 1 << 15,
/// <summary>
/// Left thumbstick left direction button
/// </summary>
LeftThumbstickLeft = 1 << 21,
/// <summary>
/// Right trigger button
/// </summary>
RightTrigger = 1 << 22,
/// <summary>
/// Left trigger button
/// </summary>
LeftTrigger = 1 << 23,
/// <summary>
/// Right thumbstick up direction button
/// </summary>
RightThumbstickUp = 1 << 24,
/// <summary>
/// Right thumbstick down direction button
/// </summary>
RightThumbstickDown = 1 << 25,
/// <summary>
/// Right stick right direction button
/// </summary>
RightThumbstickRight = 1 << 26,
/// <summary>
/// Right stick left direction button
/// </summary>
RightThumbstickLeft = 1 << 27,
/// <summary>
/// Left stick up direction button
/// </summary>
LeftThumbstickUp = 1 << 28,
/// <summary>
/// Left stick down direction button
/// </summary>
LeftThumbstickDown = 1 << 29,
/// <summary>
/// Left stick right direction button
/// </summary>
LeftThumbstickRight = 1 << 30,
}
}

View file

@ -0,0 +1,41 @@
#region License
//
// ConfigurationType.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
namespace OpenTK.Input
{
enum ConfigurationType
{
Unmapped = 0,
Axis,
Button
}
}

View file

@ -1,46 +1,96 @@
#region License
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2009 the Open Toolkit library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion
#region License
//
// GamePad.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
namespace OpenTK.Input
{
/// <summary>
/// Provides access to GamePad devices. Note: this API is not implemented yet.
/// Provides access to GamePad devices.
/// A GamePad device offers a well-defined layout with
/// one direction-pad, two thumbsticks, two triggers,
/// four main buttons (A, B, X, Y) and up to seven
/// auxilliary buttons.
/// Use <c>GetCapabilities</c> to retrieve the exact
/// capabilities of a given device.
/// Use <c>GetState</c> to retrieve the current state
/// of a given device.
/// </summary>
public class GamePad
public sealed class GamePad
{
#region Constructors
internal const int MaxAxisCount = 10;
internal const int MaxDPadCount = 2;
static GamePad()
static readonly IGamePadDriver driver =
Platform.Factory.Default.CreateGamePadDriver();
private GamePad() { }
/// <summary>
/// Retrieves a <c>GamePadCapabilities</c> structure describing the
/// capabilities of a gamepad device.
/// </summary>
/// <param name="index">The zero-based index of a gamepad device.</param>
/// <returns>A <c>GamePadCapabilities</c> structure describing the capabilities of the gamepad device.</returns>
public static GamePadCapabilities GetCapabilities(int index)
{
throw new NotImplementedException();
if (index < 0)
throw new IndexOutOfRangeException();
return driver.GetCapabilities(index);
}
#endregion
/// <summary>
/// Retrieves the <c>GamePadState</c> for the specified gamepad device.
/// </summary>
/// <param name="index">The zero-based index of a gamepad device.</param>
/// <returns>A <c>GamePadState</c> structure describing the state of the gamepad device.</returns>
public static GamePadState GetState(int index)
{
return driver.GetState(index);
}
/// <summary>
/// Sets the vibration intensity for the left and right motors of this <see cref="GamePad"/>
/// </summary>
/// <returns>
/// <c>true</c>, if vibration was set, <c>false</c> otherwise. This method can return false
/// if the <c>GamePad</c> hardware does not support vibration or if it cannot respond to
/// the command for any reason. Do not loop until this becomes true, but rather ignore
/// a return value of false.
/// </returns>
/// <param name="index">A zero-based device index for the <c>GamePad</c> device to affect</param>
/// <param name="left">The vibration intensity for the left motor, between 0.0 and 1.0.</param>
/// <param name="right">The vibration intensity for the right motor, between 0.0 and 1.0.</param>
public static bool SetVibration(int index, float left, float right)
{
return driver.SetVibration(index, left, right);
}
}
}

View file

@ -25,32 +25,17 @@
// THE SOFTWARE.
using System;
namespace OpenTK
namespace OpenTK.Input
{
public enum GamePadAxis
{
/// <summary>The first axis of the gamepad.</summary>
Axis0 = 0,
/// <summary>The second axis of the gamepad.</summary>
Axis1,
/// <summary>The third axis of the gamepad.</summary>
Axis2,
/// <summary>The fourth axis of the gamepad.</summary>
Axis3,
/// <summary>The fifth axis of the gamepad.</summary>
Axis4,
/// <summary>The sixth axis of the gamepad.</summary>
Axis5,
/// <summary>The seventh axis of the gamepad.</summary>
Axis6,
/// <summary>The eighth axis of the gamepad.</summary>
Axis7,
/// <summary>The ninth axis of the gamepad.</summary>
Axis8,
/// <summary>The tenth axis of the gamepad.</summary>
Axis9,
/// <summary>The last axis of the gamepad.</summary>
LastAxis
}
[Flags]
internal enum GamePadAxes : byte
{
LeftX = 1 << 0,
LeftY = 1 << 1,
LeftTrigger = 1 << 2,
RightX = 1 << 3,
RightY = 1 << 4,
RightTrigger = 1 << 5,
}
}

View file

@ -1,68 +0,0 @@
//
// GamePadButton.cs
//
// Author:
// robert <${AuthorEmail}>
//
// Copyright (c) 2012 robert
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
namespace OpenTK
{
public enum GamePadButton
{
/// <summary>The first button of the gamepad.</summary>
Button0 = 0,
/// <summary>The second button of the gamepad.</summary>
Button1,
/// <summary>The third button of the gamepad.</summary>
Button2,
/// <summary>The fourth button of the gamepad.</summary>
Button3,
/// <summary>The fifth button of the gamepad.</summary>
Button4,
/// <summary>The sixth button of the gamepad.</summary>
Button5,
/// <summary>The seventh button of the gamepad.</summary>
Button6,
/// <summary>The eighth button of the gamepad.</summary>
Button7,
/// <summary>The ninth button of the gamepad.</summary>
Button8,
/// <summary>The tenth button of the gamepad.</summary>
Button9,
/// <summary>The eleventh button of the gamepad.</summary>
Button10,
/// <summary>The twelfth button of the gamepad.</summary>
Button11,
/// <summary>The thirteenth button of the gamepad.</summary>
Button12,
/// <summary>The fourteenth button of the gamepad.</summary>
Button13,
/// <summary>The fifteenth button of the gamepad.</summary>
Button14,
/// <summary>The sixteenth button of the gamepad.</summary>
Button15,
/// <summary>The last button of the gamepad.</summary>
LastButton
}
}

View file

@ -0,0 +1,216 @@
#region License
//
// GamePadButtons.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
namespace OpenTK.Input
{
/// <summary>
/// Describes the <see cref="ButtonState"/> of <see cref="GamePad"/> <see cref="Buttons"/>.
/// </summary>
public struct GamePadButtons : IEquatable<GamePadButtons>
{
Buttons buttons;
/// <summary>
/// Initializes a new instance of the <see cref="OpenTK.Input.GamePadButtons"/> structure.
/// </summary>
/// <param name="state">A bitmask containing the button state.</param>
public GamePadButtons(Buttons state)
{
buttons = state;
}
#region Public Members
/// <summary>
/// Gets the <see cref="ButtonState"/> for the A button.
/// </summary>
public ButtonState A
{
get { return GetButton(Buttons.A); }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the B button.
/// </summary>
public ButtonState B
{
get { return GetButton(Buttons.B); }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the X button.
/// </summary>
public ButtonState X
{
get { return GetButton(Buttons.X); }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the Y button.
/// </summary>
public ButtonState Y
{
get { return GetButton(Buttons.Y); }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the Back button.
/// </summary>
public ButtonState Back
{
get { return GetButton(Buttons.Back); }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the big button.
/// This button is also known as Home or Guide.
/// </summary>
public ButtonState BigButton
{
get { return GetButton(Buttons.BigButton); }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the left shoulder button.
/// </summary>
public ButtonState LeftShoulder
{
get { return GetButton(Buttons.LeftShoulder); }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the left stick button.
/// This button represents a left stick that is pressed in.
/// </summary>
public ButtonState LeftStick
{
get { return GetButton(Buttons.LeftStick); }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the right shoulder button.
/// </summary>
public ButtonState RightShoulder
{
get { return GetButton(Buttons.RightShoulder); }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the right stick button.
/// This button represents a right stick that is pressed in.
/// </summary>
public ButtonState RightStick
{
get { return GetButton(Buttons.RightStick); }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the starth button.
/// </summary>
public ButtonState Start
{
get { return GetButton(Buttons.Start); }
}
/// <param name="left">A <see cref="GamePadButtons"/> instance to test for equality.</param>
/// <param name="right">A <see cref="GamePadButtons"/> instance to test for equality.</param>
public static bool operator ==(GamePadButtons left, GamePadButtons right)
{
return left.Equals(right);
}
/// <param name="left">A <see cref="GamePadButtons"/> instance to test for inequality.</param>
/// <param name="right">A <see cref="GamePadButtons"/> instance to test for inequality.</param>
public static bool operator !=(GamePadButtons left, GamePadButtons right)
{
return !left.Equals(right);
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadButtons"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadButtons"/>.</returns>
public override string ToString()
{
return Convert.ToString((int)buttons, 2).PadLeft(10, '0');
}
/// <summary>
/// Serves as a hash function for a <see cref="OpenTK.Input.GamePadButtons"/> object.
/// </summary>
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
/// hash table.</returns>
public override int GetHashCode()
{
return buttons.GetHashCode();
}
/// <summary>
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.GamePadButtons"/>.
/// </summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.GamePadButtons"/>.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadButtons"/>; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
return
obj is GamePadButtons &&
Equals((GamePadButtons)obj);
}
#endregion
#region IEquatable<GamePadButtons> Members
/// <summary>
/// Determines whether the specified <see cref="OpenTK.Input.GamePadButtons"/> is equal to the current <see cref="OpenTK.Input.GamePadButtons"/>.
/// </summary>
/// <param name="other">The <see cref="OpenTK.Input.GamePadButtons"/> to compare with the current <see cref="OpenTK.Input.GamePadButtons"/>.</param>
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.GamePadButtons"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadButtons"/>; otherwise, <c>false</c>.</returns>
public bool Equals(GamePadButtons other)
{
return buttons == other.buttons;
}
#endregion
#region Private Members
ButtonState GetButton(Buttons b)
{
return (buttons & b) != 0 ? ButtonState.Pressed : ButtonState.Released;
}
#endregion
}
}

View file

@ -0,0 +1,395 @@
#region License
//
// GamePadCapabilities.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
namespace OpenTK.Input
{
/// <summary>
/// Describes the capabilities of a <c>GamePad</c> input device.
/// </summary>
public struct GamePadCapabilities : IEquatable<GamePadCapabilities>
{
Buttons buttons;
GamePadAxes axes;
byte gamepad_type;
bool is_connected;
#region Constructors
internal GamePadCapabilities(GamePadType type, GamePadAxes axes, Buttons buttons, bool is_connected)
: this()
{
gamepad_type = (byte)type;
this.axes = axes;
this.buttons = buttons;
this.is_connected = is_connected;
}
#endregion
#region Public Members
/// <summary>
/// Gets a <see cref="GamePadType"/> value describing the type of a <see cref="GamePad"/> input device.
/// This value depends on the connected device and the drivers in use. If <c>IsConnected</c>
/// is false, then this value will be <c>GamePadType.Unknown</c>.
/// </summary>
/// <value>The <c>GamePadType</c> of the connected input device.</value>
public GamePadType GamePadType
{
get { return (GamePadType)gamepad_type; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// an up digital pad button.
/// </summary>
/// <value><c>true</c> if this instance has an up digital pad button; otherwise, <c>false</c>.</value>
public bool HasDPadUpButton
{
get { return (buttons & Buttons.DPadUp) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a down digital pad button.
/// </summary>
/// <value><c>true</c> if this instance has a down digital pad button; otherwise, <c>false</c>.</value>
public bool HasDPadDownButton
{
get { return (buttons & Buttons.DPadDown) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a left digital pad button.
/// </summary>
/// <value><c>true</c> if this instance has a left digital pad button; otherwise, <c>false</c>.</value>
public bool HasDPadLeftButton
{
get { return (buttons & Buttons.DPadLeft) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a right digital pad button.
/// </summary>
/// <value><c>true</c> if this instance has a right digital pad button; otherwise, <c>false</c>.</value>
public bool HasDPadRightButton
{
get { return (buttons & Buttons.DPadRight) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// an A button.
/// </summary>
/// <value><c>true</c> if this instance has an A button; otherwise, <c>false</c>.</value>
public bool HasAButton
{
get { return (buttons & Buttons.A) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a B button.
/// </summary>
/// <value><c>true</c> if this instance has a B button; otherwise, <c>false</c>.</value>
public bool HasBButton
{
get { return (buttons & Buttons.B) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a X button.
/// </summary>
/// <value><c>true</c> if this instance has a X button; otherwise, <c>false</c>.</value>
public bool HasXButton
{
get { return (buttons & Buttons.X) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a Y button.
/// </summary>
/// <value><c>true</c> if this instance has a Y button; otherwise, <c>false</c>.</value>
public bool HasYButton
{
get { return (buttons & Buttons.Y) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a left stick button.
/// </summary>
/// <value><c>true</c> if this instance has a left stick button; otherwise, <c>false</c>.</value>
public bool HasLeftStickButton
{
get { return (buttons & Buttons.LeftStick) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a right stick button.
/// </summary>
/// <value><c>true</c> if this instance has a right stick button; otherwise, <c>false</c>.</value>
public bool HasRightStickButton
{
get { return (buttons & Buttons.RightStick) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a left shoulder button.
/// </summary>
/// <value><c>true</c> if this instance has a left shoulder button; otherwise, <c>false</c>.</value>
public bool HasLeftShoulderButton
{
get { return (buttons & Buttons.LeftShoulder) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a right shoulder button.
/// </summary>
/// <value><c>true</c> if this instance has a right shoulder button; otherwise, <c>false</c>.</value>
public bool HasRightShoulderButton
{
get { return (buttons & Buttons.RightShoulder) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a back button.
/// </summary>
/// <value><c>true</c> if this instance has a back button; otherwise, <c>false</c>.</value>
public bool HasBackButton
{
get { return (buttons & Buttons.Back) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a big button. (also known as "guide" or "home" button).
/// </summary>
/// <value><c>true</c> if this instance has a big button; otherwise, <c>false</c>.</value>
public bool HasBigButton
{
get { return (buttons & Buttons.BigButton) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a start button.
/// </summary>
/// <value><c>true</c> if this instance has a start button; otherwise, <c>false</c>.</value>
public bool HasStartButton
{
get { return (buttons & Buttons.Start) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a left thumbstick with a x-axis.
/// </summary>
/// <value><c>true</c> if this instance has a left thumbstick with a x-axis; otherwise, <c>false</c>.</value>
public bool HasLeftXThumbStick
{
get { return (axes & GamePadAxes.LeftX) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a left thumbstick with a y-axis.
/// </summary>
/// <value><c>true</c> if this instance has a left thumbstick with a y-axis; otherwise, <c>false</c>.</value>
public bool HasLeftYThumbStick
{
get { return (axes & GamePadAxes.LeftY) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a right thumbstick with a x-axis.
/// </summary>
/// <value><c>true</c> if this instance has a right thumbstick with a x-axis; otherwise, <c>false</c>.</value>
public bool HasRightXThumbStick
{
get { return (axes & GamePadAxes.RightX) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a right thumbstick with a y-axis.
/// </summary>
/// <value><c>true</c> if this instance has a right thumbstick with a y-axis; otherwise, <c>false</c>.</value>
public bool HasRightYThumbStick
{
get { return (axes & GamePadAxes.RightY) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a left trigger.
/// </summary>
/// <value><c>true</c> if this instance has a left trigger; otherwise, <c>false</c>.</value>
public bool HasLeftTrigger
{
get { return (axes & GamePadAxes.LeftTrigger) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a right trigger.
/// </summary>
/// <value><c>true</c> if this instance has a right trigger; otherwise, <c>false</c>.</value>
public bool HasRightTrigger
{
get { return (axes & GamePadAxes.RightTrigger) != 0; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a low-frequency vibration motor.
/// </summary>
/// <value><c>true</c> if this instance has a low-frequency vibration motor; otherwise, <c>false</c>.</value>
public bool HasLeftVibrationMotor
{
get { return false; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a high-frequency vibration motor.
/// </summary>
/// <value><c>true</c> if this instance has a high frequency vibration motor; otherwise, <c>false</c>.</value>
public bool HasRightVibrationMotor
{
get { return false; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> has
/// a microphone input.
/// </summary>
/// <value><c>true</c> if this instance has a microphone input; otherwise, <c>false</c>.</value>
public bool HasVoiceSupport
{
get { return false; }
}
/// <summary>
/// Gets a <see cref="System.Boolean"/> value describing whether this <c>GamePad</c> is
/// currently connected.
/// </summary>
/// <value><c>true</c> if this instance is currently connected; otherwise, <c>false</c>.</value>
public bool IsConnected
{
get { return is_connected; }
}
/// <param name="left">A <see cref="GamePadCapabilities"/> structure to test for equality.</param>
/// <param name="right">A <see cref="GamePadCapabilities"/> structure to test for equality.</param>
public static bool operator ==(GamePadCapabilities left, GamePadCapabilities right)
{
return left.Equals(right);
}
/// <param name="left">A <see cref="GamePadCapabilities"/> structure to test for inequality.</param>
/// <param name="right">A <see cref="GamePadCapabilities"/> structure to test for inequality.</param>
public static bool operator !=(GamePadCapabilities left, GamePadCapabilities right)
{
return !left.Equals(right);
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadCapabilities"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadCapabilities"/>.</returns>
public override string ToString()
{
return String.Format(
"{{Type: {0}; Axes: {1}; Buttons: {2}; Connected: {3}}}",
GamePadType,
Convert.ToString((int)axes, 2),
Convert.ToString((int)buttons, 2),
IsConnected);
}
/// <summary>
/// Serves as a hash function for a <see cref="OpenTK.Input.GamePadCapabilities"/> object.
/// </summary>
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
/// hash table.</returns>
public override int GetHashCode()
{
return
buttons.GetHashCode() ^
is_connected.GetHashCode() ^
gamepad_type.GetHashCode();
}
/// <summary>
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.GamePadCapabilities"/>.
/// </summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.GamePadCapabilities"/>.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadCapabilities"/>; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
return
obj is GamePadCapabilities &&
Equals((GamePadCapabilities)obj);
}
#endregion
#region IEquatable<GamePadCapabilities> Members
/// <summary>
/// Determines whether the specified <see cref="OpenTK.Input.GamePadCapabilities"/> is equal to the current <see cref="OpenTK.Input.GamePadCapabilities"/>.
/// </summary>
/// <param name="other">The <see cref="OpenTK.Input.GamePadCapabilities"/> to compare with the current <see cref="OpenTK.Input.GamePadCapabilities"/>.</param>
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.GamePadCapabilities"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadCapabilities"/>; otherwise, <c>false</c>.</returns>
public bool Equals(GamePadCapabilities other)
{
return
buttons == other.buttons &&
is_connected == other.is_connected &&
gamepad_type == other.gamepad_type;
}
#endregion
}
}

View file

@ -0,0 +1,204 @@
#region License
//
// GamePadMapping.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace OpenTK.Input
{
sealed class GamePadConfiguration
{
static readonly char[] ConfigurationSeparator = new char[] { ',' };
Guid guid;
string name;
readonly List<GamePadConfigurationItem> configuration_items =
new List<GamePadConfigurationItem>();
public Guid Guid
{
get { return guid; }
private set { guid = value; }
}
public string Name
{
get { return name; }
private set { name = value; }
}
public GamePadConfiguration(string configuration)
{
ParseConfiguration(configuration);
}
public List<GamePadConfigurationItem>.Enumerator GetEnumerator()
{
return configuration_items.GetEnumerator();
}
#region Private Members
// Parses a GamePad configuration string. The string
// follows the rules for SDL2 GameController, outlined here:
// http://wiki.libsdl.org/SDL_GameControllerAddMapping
void ParseConfiguration(string configuration)
{
if (String.IsNullOrEmpty(configuration))
{
throw new ArgumentNullException();
}
// The mapping string has the format "GUID,name,config"
// - GUID is a unigue identifier returned by Joystick.GetGuid()
// - name is a human-readable name for the controller
// - config is a comma-separated list of configurations as follows:
// - [gamepad axis or button name]:[joystick axis, button or hat number]
string[] items = configuration.Split(ConfigurationSeparator, StringSplitOptions.RemoveEmptyEntries);
if (items.Length < 3)
{
throw new ArgumentException();
}
GamePadConfiguration map = this;
map.Guid = new Guid(items[0]);
map.Name = items[1];
for (int i = 2; i < items.Length; i++)
{
string[] config = items[i].Split(':');
GamePadConfigurationTarget target = ParseTarget(config[0]);
GamePadConfigurationSource source = ParseSource(config[1]);
configuration_items.Add(new GamePadConfigurationItem(source, target));
}
}
static GamePadConfigurationTarget ParseTarget(string target)
{
switch (target)
{
// Buttons
case "a":
return new GamePadConfigurationTarget(Buttons.A);
case "b":
return new GamePadConfigurationTarget(Buttons.B);
case "x":
return new GamePadConfigurationTarget(Buttons.X);
case "y":
return new GamePadConfigurationTarget(Buttons.Y);
case "start":
return new GamePadConfigurationTarget(Buttons.Start);
case "back":
return new GamePadConfigurationTarget(Buttons.Back);
case "guide":
return new GamePadConfigurationTarget(Buttons.BigButton);
case "leftshoulder":
return new GamePadConfigurationTarget(Buttons.LeftShoulder);
case "rightshoulder":
return new GamePadConfigurationTarget(Buttons.RightShoulder);
case "leftstick":
return new GamePadConfigurationTarget(Buttons.LeftStick);
case "rightstick":
return new GamePadConfigurationTarget(Buttons.RightStick);
case "dpup":
return new GamePadConfigurationTarget(Buttons.DPadUp);
case "dpdown":
return new GamePadConfigurationTarget(Buttons.DPadDown);
case "dpleft":
return new GamePadConfigurationTarget(Buttons.DPadLeft);
case "dpright":
return new GamePadConfigurationTarget(Buttons.DPadRight);
// Axes
case "leftx":
return new GamePadConfigurationTarget(GamePadAxes.LeftX);
case "lefty":
return new GamePadConfigurationTarget(GamePadAxes.LeftY);
case "rightx":
return new GamePadConfigurationTarget(GamePadAxes.RightX);
case "righty":
return new GamePadConfigurationTarget(GamePadAxes.RightY);
// Triggers
case "lefttrigger":
return new GamePadConfigurationTarget(GamePadAxes.LeftTrigger);
case "righttrigger":
return new GamePadConfigurationTarget(GamePadAxes.RightTrigger);
// Unmapped
default:
return new GamePadConfigurationTarget();
}
}
static GamePadConfigurationSource ParseSource(string item)
{
if (String.IsNullOrEmpty(item))
{
return new GamePadConfigurationSource();
}
switch (item[0])
{
case 'a':
return new GamePadConfigurationSource(ParseAxis(item));
case 'b':
return new GamePadConfigurationSource(ParseButton(item));
case 'h':
throw new NotImplementedException();
//return new MapItem(ParseHat(item));
default:
throw new InvalidOperationException("[Input] Invalid GamePad configuration value");
}
}
static JoystickAxis ParseAxis(string item)
{
// item is in the format "a#" where # a zero-based integer number
JoystickAxis axis = JoystickAxis.Axis0;
int id = Int32.Parse(item.Substring(1));
return axis + id;
}
static JoystickButton ParseButton(string item)
{
// item is in the format "b#" where # a zero-based integer nubmer
JoystickButton button = JoystickButton.Button0;
int id = Int32.Parse(item.Substring(1));
return button + id;
}
#endregion
}
}

View file

@ -0,0 +1,132 @@
#region License
//
// GamePadConfigurationDatabase.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
namespace OpenTK.Input
{
class GamePadConfigurationDatabase
{
readonly Dictionary<Guid, string> Configurations = new Dictionary<Guid, string>();
internal GamePadConfigurationDatabase()
{
// Configuration database copied from SDL
#region License
// Simple DirectMedia Layer
// Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
#endregion
// Default configuration, used when no suitable configuration is available.
// Add("00000000000000000000000000000000,Unknown Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,");
// Valid for all xinput devices on Windows:
Add("00000000000000000000000000000000,X360 Controller,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,");
// Windows
Add("341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,");
Add("ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,");
Add("6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,");
Add("6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,"); // Guide button doesn't seem to be sent in DInput mode.
Add("88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,");
Add("4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,");
Add("25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,");
// Mac OS X
Add("0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,");
Add("6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,"); /* Guide button doesn't seem to be sent in DInput mode. */
Add("6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,");
Add("6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,");
Add("6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,"); /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2"); at the very least. */
Add("4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,");
Add("5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,");
// Linux
Add("0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,");
Add("03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,");
Add("030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,");
Add("030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,");
Add("030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,");
Add("030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,"); /* Guide button doesn't seem to be sent in DInput mode. */
Add("030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,");
Add("030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,");
Add("03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,");
Add("030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,");
Add("030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,");
Add("030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,");
Add("030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,");
}
internal void Add(string config)
{
Guid guid = new Guid(config.Substring(0, 32));
if (!Configurations.ContainsKey(guid))
{
Configurations.Add(guid, config);
}
else
{
Configurations[guid] = config;
}
}
internal string this[Guid guid]
{
get
{
if (Configurations.ContainsKey(guid))
{
return Configurations[guid];
}
else
{
return Configurations[new Guid()]; // default configuration
}
}
}
}
}

View file

@ -0,0 +1,58 @@
#region License
//
// GamePadConfigurationItem.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
namespace OpenTK.Input
{
class GamePadConfigurationItem
{
GamePadConfigurationSource source;
GamePadConfigurationTarget target;
public GamePadConfigurationItem(GamePadConfigurationSource source, GamePadConfigurationTarget target)
{
Source = source;
Target = target;
}
public GamePadConfigurationSource Source
{
get { return source; }
private set { source = value; }
}
public GamePadConfigurationTarget Target
{
get { return target; }
private set { target = value; }
}
}
}

View file

@ -0,0 +1,72 @@
#region License
//
// GamePadConfigurationItem.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
namespace OpenTK.Input
{
struct GamePadConfigurationSource
{
ConfigurationType map_type;
Nullable<JoystickButton> map_button;
Nullable<JoystickAxis> map_axis;
public GamePadConfigurationSource(JoystickAxis axis)
: this()
{
Type = ConfigurationType.Axis;
Axis = axis;
}
public GamePadConfigurationSource(JoystickButton button)
: this()
{
Type = ConfigurationType.Button;
Button = button;
}
public ConfigurationType Type
{
get { return map_type; }
private set { map_type = value; }
}
public JoystickAxis Axis
{
get { return map_axis.Value; }
private set { map_axis = value; }
}
public JoystickButton Button
{
get { return map_button.Value; }
private set { map_button = value; }
}
}
}

View file

@ -0,0 +1,72 @@
#region License
//
// GamePadConfigurationTarget.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
namespace OpenTK.Input
{
struct GamePadConfigurationTarget
{
ConfigurationType map_type;
Nullable<Buttons> map_button;
Nullable<GamePadAxes> map_axis;
public GamePadConfigurationTarget(Buttons button)
: this()
{
Type = ConfigurationType.Button;
map_button = button;
}
public GamePadConfigurationTarget(GamePadAxes axis)
: this()
{
Type = ConfigurationType.Axis;
map_axis = axis;
}
public ConfigurationType Type
{
get { return map_type; }
private set { map_type = value; }
}
public GamePadAxes Axis
{
get { return map_axis.Value; }
private set { map_axis = value; }
}
public Buttons Button
{
get { return map_button.Value; }
private set { map_button = value; }
}
}
}

View file

@ -0,0 +1,223 @@
// #region License
//
// GamePadDPad.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// #endregion
using System;
namespace OpenTK.Input
{
/// <summary>
/// Describes the state of a <see cref="GamePad"/> directional pad.
/// </summary>
public struct GamePadDPad : IEquatable<GamePadDPad>
{
[Flags]
enum DPadButtons : byte
{
Up = Buttons.DPadUp,
Down = Buttons.DPadDown,
Left = Buttons.DPadLeft,
Right = Buttons.DPadRight
}
DPadButtons buttons;
#region Internal Members
internal GamePadDPad(Buttons state)
{
// DPad butons are stored in the lower 4bits
// of the Buttons enumeration.
buttons = (DPadButtons)((int)state & 0x0f);
}
#endregion
#region Public Members
/// <summary>
/// Gets the <see cref="ButtonState"/> for the up button.
/// </summary>
/// <value><c>ButtonState.Pressed</c> if the up button is pressed; otherwise, <c>ButtonState.Released</c>.</value>
public ButtonState Up
{
get { return IsUp ? ButtonState.Pressed : ButtonState.Released; }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the down button.
/// </summary>
/// <value><c>ButtonState.Pressed</c> if the down button is pressed; otherwise, <c>ButtonState.Released</c>.</value>
public ButtonState Down
{
get { return IsDown ? ButtonState.Pressed : ButtonState.Released; }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the left button.
/// </summary>
/// <value><c>ButtonState.Pressed</c> if the left button is pressed; otherwise, <c>ButtonState.Released</c>.</value>
public ButtonState Left
{
get { return IsLeft ? ButtonState.Pressed : ButtonState.Released; }
}
/// <summary>
/// Gets the <see cref="ButtonState"/> for the right button.
/// </summary>
/// <value><c>ButtonState.Pressed</c> if the right button is pressed; otherwise, <c>ButtonState.Released</c>.</value>
public ButtonState Right
{
get { return IsRight ? ButtonState.Pressed : ButtonState.Released; }
}
/// <summary>
/// Gets a value indicating whether the up button is pressed.
/// </summary>
/// <value><c>true</c> if the up button is pressed; otherwise, <c>false</c>.</value>
public bool IsUp
{
get { return (buttons & DPadButtons.Up) != 0; }
internal set { SetButton(DPadButtons.Up, value); }
}
/// <summary>
/// Gets a value indicating whether the down button is pressed.
/// </summary>
/// <value><c>true</c> if the down button is pressed; otherwise, <c>false</c>.</value>
public bool IsDown
{
get { return (buttons & DPadButtons.Down) != 0; }
internal set { SetButton(DPadButtons.Down, value); }
}
/// <summary>
/// Gets a value indicating whether the left button is pressed.
/// </summary>
/// <value><c>true</c> if the left button is pressed; otherwise, <c>false</c>.</value>
public bool IsLeft
{
get { return (buttons & DPadButtons.Left) != 0; }
internal set { SetButton(DPadButtons.Left, value); }
}
/// <summary>
/// Gets a value indicating whether the right button is pressed.
/// </summary>
/// <value><c>true</c> if the right button is pressed; otherwise, <c>false</c>.</value>
public bool IsRight
{
get { return (buttons & DPadButtons.Right) != 0; }
internal set { SetButton(DPadButtons.Right, value); }
}
/// <param name="left">A <see cref="GamePadDPad"/> instance to test for equality.</param>
/// <param name="right">A <see cref="GamePadDPad"/> instance to test for equality.</param>
public static bool operator ==(GamePadDPad left, GamePadDPad right)
{
return left.Equals(right);
}
/// <param name="left">A <see cref="GamePadDPad"/> instance to test for inequality.</param>
/// <param name="right">A <see cref="GamePadDPad"/> instance to test for inequality.</param>
public static bool operator !=(GamePadDPad left, GamePadDPad right)
{
return !left.Equals(right);
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadDPad"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadDPad"/>.</returns>
public override string ToString()
{
return String.Format(
"{{{0}{1}{2}{3}}}",
IsUp ? "U" : String.Empty,
IsLeft ? "L" : String.Empty,
IsDown ? "D" : String.Empty,
IsRight ? "R" : String.Empty);
}
/// <summary>
/// Serves as a hash function for a <see cref="OpenTK.Input.GamePadDPad"/> object.
/// </summary>
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
/// hash table.</returns>
public override int GetHashCode()
{
return buttons.GetHashCode();
}
/// <summary>
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.GamePadDPad"/>.
/// </summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.GamePadDPad"/>.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadDPad"/>; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
return
obj is GamePadDPad &&
Equals((GamePadDPad)obj);
}
#endregion
#region Private Members
void SetButton(DPadButtons button, bool value)
{
if (value)
{
buttons |= button;
}
else
{
buttons &= ~button;
}
}
#endregion
#region IEquatable<GamePadDPad> Members
/// <summary>
/// Determines whether the specified <see cref="OpenTK.Input.GamePadDPad"/> is equal to the current <see cref="OpenTK.Input.GamePadDPad"/>.
/// </summary>
/// <param name="other">The <see cref="OpenTK.Input.GamePadDPad"/> to compare with the current <see cref="OpenTK.Input.GamePadDPad"/>.</param>
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.GamePadDPad"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadDPad"/>; otherwise, <c>false</c>.</returns>
public bool Equals(GamePadDPad other)
{
return buttons == other.buttons;
}
#endregion
}
}

View file

@ -30,10 +30,216 @@ using System;
namespace OpenTK.Input
{
/// <summary>
/// Encapsulates the state of a GamePad device.
/// Describes the current state of a <see cref="GamePad"/> device.
/// </summary>
public struct GamePadState /*: IEquatable<GamePadState>*/
public struct GamePadState : IEquatable<GamePadState>
{
const float RangeMultiplier = 1.0f / (short.MaxValue + 1);
Buttons buttons;
int packet_number;
short left_stick_x;
short left_stick_y;
short right_stick_x;
short right_stick_y;
byte left_trigger;
byte right_trigger;
bool is_connected;
#region Public Members
/// <summary>
/// Gets a <see cref="GamePadThumbSticks"/> structure describing the
/// state of the <c>GamePad</c> thumb sticks.
/// </summary>
public GamePadThumbSticks ThumbSticks
{
get { return new GamePadThumbSticks(left_stick_x, left_stick_y, right_stick_x, right_stick_y); }
}
/// <summary>
/// Gets a <see cref="GamePadButtons"/> structure describing the
/// state of the <c>GamePad</c> buttons.
/// </summary>
public GamePadButtons Buttons
{
get { return new GamePadButtons(buttons); }
}
/// <summary>
/// Gets a <see cref="GamePadDPad"/> structure describing the
/// state of the <c>GamePad</c> directional pad.
/// </summary>
public GamePadDPad DPad
{
get { return new GamePadDPad(buttons); }
}
/// <summary>
/// Gets a <see cref="GamePadTriggers"/> structure describing the
/// state of the <c>GamePad</c> triggers.
/// </summary>
public GamePadTriggers Triggers
{
get { return new GamePadTriggers(left_trigger, right_trigger); }
}
/// <summary>
/// Gets a value indicating whether this <c>GamePad</c> instance is connected.
/// </summary>
/// <value><c>true</c> if this instance is connected; otherwise, <c>false</c>.</value>
public bool IsConnected
{
get { return is_connected; }
}
/// <summary>
/// Gets the packet number for this <c>GamePadState</c> instance.
/// Use the packet number to determine whether the state of a
/// <c>GamePad</c> device has changed.
/// </summary>
public int PacketNumber
{
get { return packet_number; }
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadState"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadState"/>.</returns>
public override string ToString()
{
return String.Format(
"{{Sticks: {0}; Buttons: {1}; DPad: {2}; IsConnected: {3}}}",
ThumbSticks, Buttons, DPad, IsConnected);
}
/// <summary>
/// Serves as a hash function for a <see cref="OpenTK.Input.GamePadState"/> object.
/// </summary>
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
/// hash table.</returns>
public override int GetHashCode()
{
return
ThumbSticks.GetHashCode() ^ Buttons.GetHashCode() ^
DPad.GetHashCode() ^ IsConnected.GetHashCode();
}
/// <summary>
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.GamePadState"/>.
/// </summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.GamePadState"/>.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadState"/>; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
return
obj is GamePadState &&
Equals((GamePadState)obj);
}
#endregion
#region IEquatable<GamePadState> Members
/// <summary>
/// Determines whether the specified <see cref="OpenTK.Input.GamePadState"/> is equal to the current <see cref="OpenTK.Input.GamePadState"/>.
/// </summary>
/// <param name="other">The <see cref="OpenTK.Input.GamePadState"/> to compare with the current <see cref="OpenTK.Input.GamePadState"/>.</param>
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.GamePadState"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadState"/>; otherwise, <c>false</c>.</returns>
public bool Equals(GamePadState other)
{
return
ThumbSticks == other.ThumbSticks &&
Buttons == other.Buttons &&
DPad == other.DPad &&
IsConnected == other.IsConnected;
}
#endregion
#region Internal Members
internal void SetAxis(GamePadAxes axis, short value)
{
if ((axis & GamePadAxes.LeftX) != 0)
{
left_stick_x = value;
}
if ((axis & GamePadAxes.LeftY) != 0)
{
left_stick_y = value;
}
if ((axis & GamePadAxes.RightX) != 0)
{
right_stick_x = value;
}
if ((axis & GamePadAxes.RightY) != 0)
{
right_stick_y = value;
}
if ((axis & GamePadAxes.LeftTrigger) != 0)
{
// Adjust from [-32768, 32767] to [0, 255]
left_trigger = (byte)((value - short.MinValue) >> 8);
}
if ((axis & GamePadAxes.RightTrigger) != 0)
{
// Adjust from [-32768, 32767] to [0, 255]
right_trigger = (byte)((value - short.MinValue) >> 8);
}
}
internal void SetButton(Buttons button, bool pressed)
{
if (pressed)
{
buttons |= button;
}
else
{
buttons &= ~button;
}
}
internal void SetConnected(bool connected)
{
is_connected = connected;
}
internal void SetTriggers(byte left, byte right)
{
left_trigger = left;
right_trigger = right;
}
internal void SetPacketNumber(int number)
{
packet_number = number;
}
#endregion
#region Private Members
bool IsAxisValid(GamePadAxes axis)
{
int index = (int)axis;
return index >= 0 && index < GamePad.MaxAxisCount;
}
bool IsDPadValid(int index)
{
return index >= 0 && index < GamePad.MaxDPadCount;
}
#endregion
}
}

View file

@ -0,0 +1,142 @@
#region License
//
// GamePadThumbSticks.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
namespace OpenTK.Input
{
/// <summary>
/// Describes the current thumb stick state of a <see cref="GamePad"/> device
/// </summary>
public struct GamePadThumbSticks : IEquatable<GamePadThumbSticks>
{
const float ConversionFactor = 1.0f / short.MaxValue;
short left_x, left_y;
short right_x, right_y;
internal GamePadThumbSticks(
short left_x, short left_y,
short right_x, short right_y)
{
this.left_x = left_x;
this.left_y = left_y;
this.right_x = right_x;
this.right_y = right_y;
}
#region Public Members
/// <summary>
/// Gets a <see cref="Vector2"/> describing the state of the left thumb stick.
/// </summary>
public Vector2 Left
{
get { return new Vector2(left_x * ConversionFactor, left_y * ConversionFactor); }
}
/// <summary>
/// Gets a <see cref="Vector2"/> describing the state of the right thumb stick.
/// </summary>
public Vector2 Right
{
get { return new Vector2(right_x * ConversionFactor, right_y * ConversionFactor); }
}
/// <param name="left">A <see cref="GamePadThumbSticks"/> instance to test for equality.</param>
/// <param name="right">A <see cref="GamePadThumbSticks"/> instance to test for equality.</param>
public static bool operator ==(GamePadThumbSticks left, GamePadThumbSticks right)
{
return left.Equals(right);
}
/// <param name="left">A <see cref="GamePadThumbSticks"/> instance to test for inequality.</param>
/// <param name="right">A <see cref="GamePadThumbSticks"/> instance to test for inequality.</param>
public static bool operator !=(GamePadThumbSticks left, GamePadThumbSticks right)
{
return !left.Equals(right);
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadThumbSticks"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadThumbSticks"/>.</returns>
public override string ToString()
{
return String.Format(
"{{Left: ({0:f4}; {1:f4}); Right: ({2:f4}; {3:f4})}}",
Left.X, Left.Y, Right.X, Right.Y);
}
/// <summary>
/// Serves as a hash function for a <see cref="OpenTK.Input.GamePadThumbSticks"/> object.
/// </summary>
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
/// hash table.</returns>
public override int GetHashCode()
{
return
left_x.GetHashCode() ^ left_y.GetHashCode() ^
right_x.GetHashCode() ^ right_y.GetHashCode();
}
/// <summary>
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.GamePadThumbSticks"/>.
/// </summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.GamePadThumbSticks"/>.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadThumbSticks"/>; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
return
obj is GamePadThumbSticks &&
Equals((GamePadThumbSticks)obj);
}
#endregion
#region IEquatable<GamePadThumbSticks> Members
/// <summary>
/// Determines whether the specified <see cref="OpenTK.Input.GamePadThumbSticks"/> is equal to the current <see cref="OpenTK.Input.GamePadThumbSticks"/>.
/// </summary>
/// <param name="other">The <see cref="OpenTK.Input.GamePadThumbSticks"/> to compare with the current <see cref="OpenTK.Input.GamePadThumbSticks"/>.</param>
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.GamePadThumbSticks"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadThumbSticks"/>; otherwise, <c>false</c>.</returns>
public bool Equals(GamePadThumbSticks other)
{
return
left_x == other.left_x &&
left_y == other.left_y &&
right_x == other.right_x &&
right_y == other.right_y;
}
#endregion
}
}

View file

@ -0,0 +1,136 @@
// #region License
//
// GamePadTriggers.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// #endregion
using System;
namespace OpenTK.Input
{
/// <summary>
/// Describes the state of a <see cref="GamePad"/> trigger buttons.
/// </summary>
public struct GamePadTriggers : IEquatable<GamePadTriggers>
{
const float ConversionFactor = 1.0f / short.MaxValue;
short left;
short right;
internal GamePadTriggers(short left, short right)
{
this.left = left;
this.right = right;
}
#region Public Members
/// <summary>
/// Gets the offset of the left trigger button, between 0.0 and 1.0.
/// </summary>
public float Left
{
get { return left * ConversionFactor; }
}
/// <summary>
/// Gets the offset of the left trigger button, between 0.0 and 1.0.
/// </summary>
public float Right
{
get { return right * ConversionFactor; }
}
/// <param name="left">A <see cref="GamePadTriggers"/> instance to test for equality.</param>
/// <param name="right">A <see cref="GamePadTriggers"/> instance to test for equality.</param>
public static bool operator ==(GamePadTriggers left, GamePadTriggers right)
{
return left.Equals(right);
}
/// <param name="left">A <see cref="GamePadTriggers"/> instance to test for equality.</param>
/// <param name="right">A <see cref="GamePadTriggers"/> instance to test for equality.</param>
public static bool operator !=(GamePadTriggers left, GamePadTriggers right)
{
return !left.Equals(right);
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadTriggers"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.GamePadTriggers"/>.</returns>
public override string ToString()
{
return String.Format(
"{{Left: {0:f2}; Right: {1:f2}}}",
Left, Right);
}
/// <summary>
/// Serves as a hash function for a <see cref="OpenTK.Input.GamePadTriggers"/> object.
/// </summary>
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
/// hash table.</returns>
public override int GetHashCode()
{
return
left.GetHashCode() ^ right.GetHashCode();
}
/// <summary>
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.GamePadTriggers"/>.
/// </summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.GamePadTriggers"/>.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadTriggers"/>; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
return
obj is GamePadTriggers &&
Equals((GamePadTriggers)obj);
}
#endregion
#region IEquatable<GamePadTriggers> Members
/// <summary>
/// Determines whether the specified <see cref="OpenTK.Input.GamePadTriggers"/> is equal to the current <see cref="OpenTK.Input.GamePadTriggers"/>.
/// </summary>
/// <param name="other">The <see cref="OpenTK.Input.GamePadTriggers"/> to compare with the current <see cref="OpenTK.Input.GamePadTriggers"/>.</param>
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.GamePadTriggers"/> is equal to the current
/// <see cref="OpenTK.Input.GamePadTriggers"/>; otherwise, <c>false</c>.</returns>
public bool Equals(GamePadTriggers other)
{
return
left == other.left &&
right == other.right;
}
#endregion
}
}

View file

@ -0,0 +1,97 @@
#region License
//
// GamePadType.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
namespace OpenTK.Input
{
/// <summary>
/// Enumerates available <see cref="GamePad"/> types.
/// </summary>
public enum GamePadType
{
/// <summary>
/// The <c>GamePad</c> is of an unknown type.
/// </summary>
Unknown = 0,
/// <summary>
/// The <c>GamePad</c> is an arcade stick.
/// </summary>
ArcadeStick,
/// <summary>
/// The <c>GamePad</c> is a dance pad.
/// </summary>
DancePad,
/// <summary>
/// The <c>GamePad</c> is a flight stick.
/// </summary>
FlightStick,
/// <summary>
/// The <c>GamePad</c> is a guitar.
/// </summary>
Guitar,
/// <summary>
/// The <c>GamePad</c> is a driving wheel.
/// </summary>
Wheel,
/// <summary>
/// The <c>GamePad</c> is an alternate guitar.
/// </summary>
AlternateGuitar,
/// <summary>
/// The <c>GamePad</c> is a big button pad.
/// </summary>
BigButtonPad,
/// <summary>
/// The <c>GamePad</c> is a drum kit.
/// </summary>
DrumKit,
/// <summary>
/// The <c>GamePad</c> is a game pad.
/// </summary>
GamePad,
/// <summary>
/// The <c>GamePad</c> is an arcade pad.
/// </summary>
ArcadePad,
/// <summary>
/// The <c>GamePad</c> is a bass guitar.
/// </summary>
BassGuitar,
}
}

View file

@ -6,19 +6,11 @@ namespace OpenTK.Input
{
interface IGamePadDriver
{
/// <summary>
/// Retrieves the combined <see cref="OpenTK.Input.GamePadState"/> for all gamepad devices.
/// </summary>
/// <returns>A <see cref="OpenTK.Input.GamePadState"/> structure containing the combined state for all gamepad devices.</returns>
GamePadState GetState();
/// <summary>
/// Retrieves the <see cref="OpenTK.Input.GamePadState"/> for the specified gamepad device.
/// </summary>
/// <param name="index">The index of the keyboard device.</param>
/// <returns>A <see cref="OpenTK.Input.GamePadState"/> structure containing the state of the gamepad device.</returns>
GamePadState GetState(int index);
GamePadCapabilities GetCapabilities(int index);
/// <summary>
/// Retrieves the device name for the gamepad device.
/// </summary>
@ -26,6 +18,8 @@ namespace OpenTK.Input
/// <returns>A <see cref="System.String"/> with the name of the specified device or <see cref="System.String.Empty"/>.</returns>
/// <remarks>
/// <para>If no device exists at the specified index, the return value is <see cref="System.String.Empty"/>.</para></remarks>
string GetDeviceName(int index);
string GetName(int index);
bool SetVibration(int index, float left, float right);
}
}

View file

@ -37,5 +37,6 @@ namespace OpenTK.Input
IMouseDriver2 MouseDriver { get; }
IKeyboardDriver2 KeyboardDriver { get; }
IGamePadDriver GamePadDriver { get; }
IJoystickDriver2 JoystickDriver { get; }
}
}

View file

@ -0,0 +1,42 @@
#region License
//
// IJoystickDriver2.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Input
{
interface IJoystickDriver2
{
JoystickState GetState(int index);
JoystickCapabilities GetCapabilities(int index);
Guid GetGuid(int index);
}
}

View file

@ -0,0 +1,92 @@
#region License
//
// Joystick.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Input
{
/// <summary>
/// Provides access to Joystick devices.
/// Joystick devices provide a varying number of axes and buttons.
/// Use <c>GetCapabilities</c> to retrieve the number of supported
/// axes and buttons on a given device.
/// Use <c>GetState</c> to retrieve the current state of a given device.
/// <seealso cref="GamePad"/>
/// </summary>
public sealed class Joystick
{
static readonly IJoystickDriver2 implementation =
Platform.Factory.Default.CreateJoystickDriver();
private Joystick() { }
/// <summary>
/// Retrieves the <see cref="JoystickCapabilities"/> of the device connected
/// at the specified index.
/// </summary>
/// <returns>
/// A <see cref="JoystickCapabilities"/> structure describing
/// the capabilities of the device at the specified index.
/// If no device is connected at the specified index, the <c>IsConnected</c>
/// property of the returned structure will be false.
/// </returns>
/// <param name="index">The zero-based index of the device to poll.</param>
public static JoystickCapabilities GetCapabilities(int index)
{
return implementation.GetCapabilities(index);
}
/// <summary>
/// Retrieves the <see cref="JoystickState"/> of the device connected
/// at the specified index.
/// </summary>
/// <returns>A <see cref="JoystickState"/> structure describing
/// the current state of the device at the specified index.
/// If no device is connected at this index, the <c>IsConnected</c>
/// property of the returned structure will be false.
/// </returns>
/// <param name="index">The zero-based index of the device to poll.</param>
public static JoystickState GetState(int index)
{
return implementation.GetState(index);
}
internal static Guid GetGuid(int index)
{
return implementation.GetGuid(index);
}
//public string GetName(int index)
//{
// return implementation.GetName(index);
//}
}
}

View file

@ -0,0 +1,62 @@
#region License
//
// JoystickAxis.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Input
{
/// <summary>
/// Defines available JoystickDevice axes.
/// </summary>
public enum JoystickAxis
{
/// <summary>The first axis of the JoystickDevice.</summary>
Axis0 = 0,
/// <summary>The second axis of the JoystickDevice.</summary>
Axis1,
/// <summary>The third axis of the JoystickDevice.</summary>
Axis2,
/// <summary>The fourth axis of the JoystickDevice.</summary>
Axis3,
/// <summary>The fifth axis of the JoystickDevice.</summary>
Axis4,
/// <summary>The sixth axis of the JoystickDevice.</summary>
Axis5,
/// <summary>The seventh axis of the JoystickDevice.</summary>
Axis6,
/// <summary>The eighth axis of the JoystickDevice.</summary>
Axis7,
/// <summary>The ninth axis of the JoystickDevice.</summary>
Axis8,
/// <summary>The tenth axis of the JoystickDevice.</summary>
Axis9,
}
}

View file

@ -0,0 +1,74 @@
#region License
//
// JoystickButton.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Input
{
/// <summary>
/// Defines available JoystickDevice buttons.
/// </summary>
public enum JoystickButton
{
/// <summary>The first button of the JoystickDevice.</summary>
Button0 = 0,
/// <summary>The second button of the JoystickDevice.</summary>
Button1,
/// <summary>The third button of the JoystickDevice.</summary>
Button2,
/// <summary>The fourth button of the JoystickDevice.</summary>
Button3,
/// <summary>The fifth button of the JoystickDevice.</summary>
Button4,
/// <summary>The sixth button of the JoystickDevice.</summary>
Button5,
/// <summary>The seventh button of the JoystickDevice.</summary>
Button6,
/// <summary>The eighth button of the JoystickDevice.</summary>
Button7,
/// <summary>The ninth button of the JoystickDevice.</summary>
Button8,
/// <summary>The tenth button of the JoystickDevice.</summary>
Button9,
/// <summary>The eleventh button of the JoystickDevice.</summary>
Button10,
/// <summary>The twelfth button of the JoystickDevice.</summary>
Button11,
/// <summary>The thirteenth button of the JoystickDevice.</summary>
Button12,
/// <summary>The fourteenth button of the JoystickDevice.</summary>
Button13,
/// <summary>The fifteenth button of the JoystickDevice.</summary>
Button14,
/// <summary>The sixteenth button of the JoystickDevice.</summary>
Button15,
}
}

View file

@ -0,0 +1,156 @@
#region License
//
// JoystickCapabilities.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Input
{
/// <summary>
/// Describes the <c>JoystickCapabilities</c> of a <see cref="JoystickDevice"/>.
/// </summary>
public struct JoystickCapabilities : IEquatable<JoystickCapabilities>
{
byte axis_count;
byte button_count;
byte dpad_count;
bool is_connected;
#region Constructors
internal JoystickCapabilities(int axis_count, int button_count, bool is_connected)
{
if (axis_count < 0 || axis_count >= JoystickState.MaxAxes)
throw new ArgumentOutOfRangeException("axis_count");
if (button_count < 0 || button_count >= JoystickState.MaxButtons)
throw new ArgumentOutOfRangeException("axis_count");
this.axis_count = (byte)axis_count;
this.button_count = (byte)button_count;
this.dpad_count = 0; // Todo: either remove dpad_count or add it as a parameter
this.is_connected = is_connected;
}
#endregion
#region Public Members
/// <summary>
/// Gets the number of axes supported by this <see cref="JoystickDevice"/>.
/// </summary>
public int AxisCount
{
get { return axis_count; }
}
/// <summary>
/// Gets the number of buttons supported by this <see cref="JoystickDevice"/>.
/// </summary>
public int ButtonCount
{
get { return button_count; }
}
/// <summary>
/// Gets a value indicating whether this <see cref="JoystickDevice"/> is connected.
/// </summary>
/// <value><c>true</c> if this instance is connected; otherwise, <c>false</c>.</value>
public bool IsConnected
{
get { return is_connected; }
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.JoystickCapabilities"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.JoystickCapabilities"/>.</returns>
public override string ToString()
{
return String.Format(
"{{Axes: {0}; Buttons: {1}; IsConnected: {2}}}",
AxisCount, ButtonCount, IsConnected);
}
/// <summary>
/// Serves as a hash function for a <see cref="OpenTK.Input.JoystickCapabilities"/> object.
/// </summary>
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
/// hash table.</returns>
public override int GetHashCode()
{
return
AxisCount.GetHashCode() ^
ButtonCount.GetHashCode() ^
IsConnected.GetHashCode();
}
/// <summary>
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.JoystickCapabilities"/>.
/// </summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.JoystickCapabilities"/>.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
/// <see cref="OpenTK.Input.JoystickCapabilities"/>; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
return
obj is JoystickCapabilities &&
Equals((JoystickCapabilities)obj);
}
#endregion
#region Private Members
int DPadCount
{
get { return dpad_count; }
}
#endregion
#region IEquatable<JoystickCapabilities> Members
/// <summary>
/// Determines whether the specified <see cref="OpenTK.Input.JoystickCapabilities"/> is equal to the current <see cref="OpenTK.Input.JoystickCapabilities"/>.
/// </summary>
/// <param name="other">The <see cref="OpenTK.Input.JoystickCapabilities"/> to compare with the current <see cref="OpenTK.Input.JoystickCapabilities"/>.</param>
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.JoystickCapabilities"/> is equal to the current
/// <see cref="OpenTK.Input.JoystickCapabilities"/>; otherwise, <c>false</c>.</returns>
public bool Equals(JoystickCapabilities other)
{
return
AxisCount == other.AxisCount &&
ButtonCount == other.ButtonCount &&
IsConnected == other.IsConnected;
}
#endregion
}
}

View file

@ -156,12 +156,13 @@ namespace OpenTK.Input
// Provides platform-specific information about the relevant JoystickDevice.
internal sealed class JoystickDevice<TDetail> : JoystickDevice
where TDetail : new()
{
internal JoystickDevice(int id, int axes, int buttons)
: base(id, axes, buttons)
{ }
internal TDetail Details;
internal TDetail Details = new TDetail();
}
#endregion
@ -271,49 +272,6 @@ namespace OpenTK.Input
#endregion
#region JoystickButton
/// <summary>
/// Defines available JoystickDevice buttons.
/// </summary>
public enum JoystickButton
{
/// <summary>The first button of the JoystickDevice.</summary>
Button0 = 0,
/// <summary>The second button of the JoystickDevice.</summary>
Button1,
/// <summary>The third button of the JoystickDevice.</summary>
Button2,
/// <summary>The fourth button of the JoystickDevice.</summary>
Button3,
/// <summary>The fifth button of the JoystickDevice.</summary>
Button4,
/// <summary>The sixth button of the JoystickDevice.</summary>
Button5,
/// <summary>The seventh button of the JoystickDevice.</summary>
Button6,
/// <summary>The eighth button of the JoystickDevice.</summary>
Button7,
/// <summary>The ninth button of the JoystickDevice.</summary>
Button8,
/// <summary>The tenth button of the JoystickDevice.</summary>
Button9,
/// <summary>The eleventh button of the JoystickDevice.</summary>
Button10,
/// <summary>The twelfth button of the JoystickDevice.</summary>
Button11,
/// <summary>The thirteenth button of the JoystickDevice.</summary>
Button12,
/// <summary>The fourteenth button of the JoystickDevice.</summary>
Button13,
/// <summary>The fifteenth button of the JoystickDevice.</summary>
Button14,
/// <summary>The sixteenth button of the JoystickDevice.</summary>
Button15,
}
#endregion
#region JoystickButtonCollection
/// <summary>
@ -376,37 +334,6 @@ namespace OpenTK.Input
#endregion
#region JoystickAxis
/// <summary>
/// Defines available JoystickDevice axes.
/// </summary>
public enum JoystickAxis
{
/// <summary>The first axis of the JoystickDevice.</summary>
Axis0 = 0,
/// <summary>The second axis of the JoystickDevice.</summary>
Axis1,
/// <summary>The third axis of the JoystickDevice.</summary>
Axis2,
/// <summary>The fourth axis of the JoystickDevice.</summary>
Axis3,
/// <summary>The fifth axis of the JoystickDevice.</summary>
Axis4,
/// <summary>The sixth axis of the JoystickDevice.</summary>
Axis5,
/// <summary>The seventh axis of the JoystickDevice.</summary>
Axis6,
/// <summary>The eighth axis of the JoystickDevice.</summary>
Axis7,
/// <summary>The ninth axis of the JoystickDevice.</summary>
Axis8,
/// <summary>The tenth axis of the JoystickDevice.</summary>
Axis9,
}
#endregion
#region JoystickAxisCollection
/// <summary>

View file

@ -0,0 +1,260 @@
#region License
//
// JoystickState.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Diagnostics;
using System.Text;
namespace OpenTK.Input
{
/// <summary>
/// Describes the current state of a <see cref="JoystickDevice"/>.
/// </summary>
public struct JoystickState : IEquatable<JoystickState>
{
// If we ever add more values to JoystickAxis or JoystickButton
// then we'll need to increase these limits.
internal const int MaxAxes = 10;
internal const int MaxButtons = 32;
const float ConversionFactor = 1.0f / (short.MaxValue + 0.5f);
unsafe fixed short axes[MaxAxes];
int buttons;
int packet_number;
bool is_connected;
#region Public Members
/// <summary>
/// Gets a value between -1.0 and 1.0 representing the current offset of the specified <see cref="JoystickAxis"/>.
/// </summary>
/// <returns>
/// A value between -1.0 and 1.0 representing offset of the specified <see cref="JoystickAxis"/>.
/// If the specified axis does not exist, then the return value is 0.0. Use <see cref="Joystick.GetCapabilities"/>
/// to query the number of available axes.
/// </returns>
/// <param name="axis">The <see cref="JoystickAxis"/> to query.</param>
public float GetAxis(JoystickAxis axis)
{
return GetAxisRaw(axis) * ConversionFactor;
}
/// <summary>
/// Gets the current <see cref="ButtonState"/> of the specified <see cref="JoystickButton"/>.
/// </summary>
/// <returns><see cref="ButtonState.Pressed"/> if the specified button is pressed; otherwise, <see cref="ButtonState.Released"/>.</returns>
/// <param name="button">The <see cref="JoystickButton"/> to query.</param>
public ButtonState GetButton(JoystickButton button)
{
return (buttons & (1 << (int)button)) != 0 ? ButtonState.Pressed : ButtonState.Released;
}
/// <summary>
/// Gets a value indicating whether the specified <see cref="JoystickButton"/> is currently pressed.
/// </summary>
/// <returns>true if the specified button is pressed; otherwise, false.</returns>
/// <param name="button">The <see cref="JoystickButton"/> to query.</param>
public bool IsButtonDown(JoystickButton button)
{
return (buttons & (1 << (int)button)) != 0;
}
/// <summary>
/// Gets a value indicating whether the specified <see cref="JoystickButton"/> is currently released.
/// </summary>
/// <returns>true if the specified button is released; otherwise, false.</returns>
/// <param name="button">The <see cref="JoystickButton"/> to query.</param>
public bool IsButtonUp(JoystickButton button)
{
return (buttons & (1 << (int)button)) == 0;
}
/// <summary>
/// Gets a value indicating whether this instance is connected.
/// </summary>
/// <value><c>true</c> if this instance is connected; otherwise, <c>false</c>.</value>
public bool IsConnected
{
get { return is_connected; }
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.JoystickState"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.JoystickState"/>.</returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < MaxAxes; i++)
{
sb.Append(" ");
sb.Append(String.Format("{0:f4}", GetAxis(JoystickAxis.Axis0 + i)));
}
return String.Format(
"{{Axes:{0}; Buttons: {1}; IsConnected: {2}}}",
sb.ToString(),
Convert.ToString((int)buttons, 2).PadLeft(16, '0'),
IsConnected);
}
/// <summary>
/// Serves as a hash function for a <see cref="OpenTK.Input.JoystickState"/> object.
/// </summary>
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
/// hash table.</returns>
public override int GetHashCode()
{
int hash = buttons.GetHashCode() ^ IsConnected.GetHashCode();
for (int i = 0; i < MaxAxes; i++)
{
hash ^= GetAxisUnsafe(i).GetHashCode();
}
return hash;
}
/// <summary>
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.JoystickState"/>.
/// </summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.JoystickState"/>.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
/// <see cref="OpenTK.Input.JoystickState"/>; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
return
obj is JoystickState &&
Equals((JoystickState)obj);
}
#endregion
#region Internal Members
internal int PacketNumber
{
get { return packet_number; }
}
internal short GetAxisRaw(JoystickAxis axis)
{
return GetAxisRaw((int)axis);
}
internal short GetAxisRaw(int axis)
{
short value = 0;
if (axis >= 0 && axis < MaxAxes)
{
value = GetAxisUnsafe(axis);
}
else
{
Debug.Print("[Joystick] Invalid axis {0}", axis);
}
return value;
}
internal void SetAxis(JoystickAxis axis, short value)
{
int index = (int)axis;
if (index < 0 || index >= MaxAxes)
throw new ArgumentOutOfRangeException("axis");
unsafe
{
fixed (short* paxes = axes)
{
*(paxes + index) = value;
}
}
}
internal void SetButton(JoystickButton button, bool value)
{
int index = 1 << (int)button;
if (value)
{
buttons |= index;
}
else
{
buttons &= ~index;
}
}
internal void SetIsConnected(bool value)
{
is_connected = value;
}
internal void SetPacketNumber(int number)
{
packet_number = number;
}
#endregion
#region Private Members
short GetAxisUnsafe(int index)
{
unsafe
{
fixed (short* paxis = axes)
{
return *(paxis + index);
}
}
}
#endregion
#region IEquatable<JoystickState> Members
/// <summary>
/// Determines whether the specified <see cref="OpenTK.Input.JoystickState"/> is equal to the current <see cref="OpenTK.Input.JoystickState"/>.
/// </summary>
/// <param name="other">The <see cref="OpenTK.Input.JoystickState"/> to compare with the current <see cref="OpenTK.Input.JoystickState"/>.</param>
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.JoystickState"/> is equal to the current
/// <see cref="OpenTK.Input.JoystickState"/>; otherwise, <c>false</c>.</returns>
public bool Equals(JoystickState other)
{
bool equals =
buttons == other.buttons &&
IsConnected == other.IsConnected;
for (int i = 0; equals && i < MaxAxes; i++)
{
equals &= GetAxisUnsafe(i) == other.GetAxisUnsafe(i);
}
return equals;
}
#endregion
}
}

View file

@ -133,10 +133,19 @@
</Compile>
<Compile Include="DisplayIndex.cs" />
<Compile Include="Graphics\GraphicsModeComparer.cs" />
<Compile Include="Input\GamePadThumbSticks.cs" />
<Compile Include="Input\GamePadTriggers.cs" />
<Compile Include="Input\GamePadType.cs" />
<Compile Include="Input\IGamePadDriver.cs" />
<Compile Include="Input\IInputDriver2.cs" />
<Compile Include="Input\IJoystickDriver2.cs" />
<Compile Include="Input\IKeyboardDriver2.cs" />
<Compile Include="Input\IMouseDriver2.cs" />
<Compile Include="Input\Joystick.cs" />
<Compile Include="Input\JoystickAxis.cs" />
<Compile Include="Input\JoystickButton.cs" />
<Compile Include="Input\JoystickCapabilities.cs" />
<Compile Include="Input\JoystickState.cs" />
<Compile Include="InteropHelper.cs" />
<Compile Include="Math\Matrix2.cs" />
<Compile Include="Math\Matrix2d.cs" />
@ -154,7 +163,9 @@
<Compile Include="Math\Matrix4x3.cs" />
<Compile Include="Math\Matrix4x3d.cs" />
<Compile Include="Platform\DisplayDeviceBase.cs" />
<Compile Include="Platform\MappedGamePadDriver.cs" />
<Compile Include="Platform\Windows\WinInputBase.cs" />
<Compile Include="Platform\Windows\XInputJoystick.cs" />
<Compile Include="ToolkitOptions.cs" />
<Compile Include="WindowBorder.cs">
<SubType>Code</SubType>
@ -738,8 +749,7 @@
</EmbeddedResource>
<Compile Include="Platform\MacOS\HIDInput.cs" />
<Compile Include="IntPtrEqualityComparer.cs" />
<Compile Include="Input\GamePadButton.cs" />
<Compile Include="Input\GamePadAxis.cs" />
<Compile Include="Input\GamePadAxes.cs" />
<Compile Include="Platform\SDL2\Sdl2DisplayDeviceDriver.cs" />
<Compile Include="Platform\SDL2\Sdl2Factory.cs" />
<Compile Include="Platform\SDL2\Sdl2GraphicsContext.cs" />
@ -778,6 +788,16 @@
<Compile Include="RewrittenAttribute.cs" />
<Compile Include="Graphics\OpenGL\GLObsolete.cs" />
<Compile Include="Platform\MacOS\NS.cs" />
<Compile Include="Input\GamePadCapabilities.cs" />
<Compile Include="Input\GamePadDPad.cs" />
<Compile Include="Input\GamePadButtons.cs" />
<Compile Include="Input\Buttons.cs" />
<Compile Include="Input\GamePadConfigurationDatabase.cs" />
<Compile Include="Input\GamePadConfiguration.cs" />
<Compile Include="Input\GamePadConfigurationTarget.cs" />
<Compile Include="Input\ConfigurationType.cs" />
<Compile Include="Input\GamePadConfigurationSource.cs" />
<Compile Include="Input\GamePadConfigurationItem.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>

View file

@ -149,6 +149,11 @@ namespace OpenTK.Platform
return default_implementation.CreateGamePadDriver();
}
public Input.IJoystickDriver2 CreateJoystickDriver()
{
return default_implementation.CreateJoystickDriver();
}
class UnsupportedPlatform : IPlatformFactory
{
#region Fields
@ -210,6 +215,11 @@ namespace OpenTK.Platform
throw new PlatformNotSupportedException(error_string);
}
public Input.IJoystickDriver2 CreateJoystickDriver()
{
throw new PlatformNotSupportedException(error_string);
}
#endregion
#region IDisposable Members

View file

@ -52,5 +52,7 @@ namespace OpenTK.Platform
OpenTK.Input.IMouseDriver2 CreateMouseDriver();
OpenTK.Input.IGamePadDriver CreateGamePadDriver();
Input.IJoystickDriver2 CreateJoystickDriver();
}
}

View file

@ -113,5 +113,10 @@ namespace OpenTK.Platform.MacOS
throw new NotImplementedException();
}
}
public IJoystickDriver2 JoystickDriver
{
get { throw new NotImplementedException(); }
}
}
}

View file

@ -50,7 +50,7 @@ namespace OpenTK.Platform.MacOS
// Requires Mac OS X 10.5 or higher.
// Todo: create a driver for older installations. Maybe use CGGetLastMouseDelta for that?
class HIDInput : IInputDriver2, IMouseDriver2, IKeyboardDriver2/*, IGamePadDriver*/
class HIDInput : IInputDriver2, IMouseDriver2, IKeyboardDriver2, IJoystickDriver2
{
#region Fields
@ -69,6 +69,8 @@ namespace OpenTK.Platform.MacOS
readonly CFString InputLoopMode = CF.RunLoopModeDefault;
readonly CFDictionary DeviceTypes = new CFDictionary();
readonly MappedGamePadDriver mapped_gamepad = new MappedGamePadDriver();
NativeMethods.IOHIDDeviceCallback HandleDeviceAdded;
NativeMethods.IOHIDDeviceCallback HandleDeviceRemoved;
NativeMethods.IOHIDValueCallback HandleDeviceValueReceived;
@ -93,7 +95,7 @@ namespace OpenTK.Platform.MacOS
#endregion
#region Private Members
#region Private Members
IOHIDManagerRef CreateHIDManager()
{
@ -291,7 +293,8 @@ namespace OpenTK.Platform.MacOS
public IMouseDriver2 MouseDriver { get { return this; } }
public IKeyboardDriver2 KeyboardDriver { get { return this; } }
public IGamePadDriver GamePadDriver { get { throw new NotImplementedException(); } }
public IGamePadDriver GamePadDriver { get { return mapped_gamepad; } }
public IJoystickDriver2 JoystickDriver { get { return this; } }
#endregion
@ -366,6 +369,25 @@ namespace OpenTK.Platform.MacOS
#endregion
#region IJoystickDriver2 Members
JoystickState IJoystickDriver2.GetState(int index)
{
return new JoystickState();
}
JoystickCapabilities IJoystickDriver2.GetCapabilities(int index)
{
return new JoystickCapabilities();
}
Guid IJoystickDriver2.GetGuid(int index)
{
return new Guid();
}
#endregion
#region NativeMethods
class NativeMethods

View file

@ -93,6 +93,11 @@ namespace OpenTK.Platform.MacOS
{
return InputDriver.GamePadDriver;
}
public IJoystickDriver2 CreateJoystickDriver()
{
return InputDriver.JoystickDriver;
}
#endregion

View file

@ -0,0 +1,196 @@
#region License
//
// MappedGamePadDriver.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using OpenTK.Input;
namespace OpenTK.Platform
{
/// \internal
/// <summary>
/// Implements IGamePadDriver using OpenTK.Input.Joystick
/// and a gamepad-specific axis/button mapping.
/// </summary>
/// <remarks>
/// <para>
/// This class supports OpenTK and is not meant to be accessed by user code.
/// </para>
/// <para>
/// To support gamepads on platforms that do not offer a gamepad-optimized API,
/// we need to use the generic OpenTK.Input.Joystick and implement a custom
/// mapping scheme to provide a stable mapping to OpenTK.Input.GamePad. This
/// class implements this mapping scheme.
/// </para>
/// </remarks>
class MappedGamePadDriver : IGamePadDriver
{
readonly GamePadConfigurationDatabase database =
new GamePadConfigurationDatabase();
readonly Dictionary<Guid, GamePadConfiguration> configurations =
new Dictionary<Guid, GamePadConfiguration>();
public GamePadState GetState(int index)
{
JoystickState joy = Joystick.GetState(index);
GamePadState pad = new GamePadState();
if (joy.IsConnected)
{
pad.SetConnected(true);
pad.SetPacketNumber(joy.PacketNumber);
GamePadConfiguration configuration = GetConfiguration(Joystick.GetGuid(index));
foreach (GamePadConfigurationItem map in configuration)
{
switch (map.Source.Type)
{
case ConfigurationType.Axis:
{
// JoystickAxis -> Buttons/GamePadAxes mapping
JoystickAxis source_axis = map.Source.Axis;
GamePadAxes target_axis = map.Target.Axis;
short value = joy.GetAxisRaw(source_axis);
switch (map.Target.Type)
{
case ConfigurationType.Axis:
pad.SetAxis(target_axis, value);
break;
case ConfigurationType.Button:
throw new NotImplementedException();
break;
}
}
break;
case ConfigurationType.Button:
{
// JoystickButton -> Buttons/GamePadAxes mapping
JoystickButton source_button = map.Source.Button;
Buttons target_button = map.Target.Button;
bool pressed = joy.GetButton(source_button) == ButtonState.Pressed;
switch (map.Target.Type)
{
case ConfigurationType.Axis:
throw new NotImplementedException();
break;
case ConfigurationType.Button:
pad.SetButton(target_button, pressed);
break;
}
}
break;
}
}
}
return pad;
}
public GamePadCapabilities GetCapabilities(int index)
{
JoystickCapabilities joy = Joystick.GetCapabilities(index);
GamePadCapabilities pad;
if (joy.IsConnected)
{
GamePadConfiguration configuration = GetConfiguration(Joystick.GetGuid(index));
GamePadAxes mapped_axes = 0;
Buttons mapped_buttons = 0;
foreach (GamePadConfigurationItem map in configuration)
{
switch (map.Target.Type)
{
case ConfigurationType.Axis:
mapped_axes |= map.Target.Axis;
break;
case ConfigurationType.Button:
mapped_buttons |= map.Target.Button;
break;
}
}
pad = new GamePadCapabilities(
GamePadType.GamePad, // Todo: detect different types
mapped_axes,
mapped_buttons,
true);
}
else
{
pad = new GamePadCapabilities();
}
return pad;
}
public string GetName(int index)
{
JoystickCapabilities joy = Joystick.GetCapabilities(index);
string name = String.Empty;
if (joy.IsConnected)
{
GamePadConfiguration map = GetConfiguration(Joystick.GetGuid(index));
name = map.Name;
}
return name;
}
public bool SetVibration(int index, float left, float right)
{
return false;
}
#region Private Members
GamePadConfiguration GetConfiguration(Guid guid)
{
if (!configurations.ContainsKey(guid))
{
string config = database[guid];
GamePadConfiguration map = new GamePadConfiguration(config);
configurations.Add(guid, map);
}
return configurations[guid];
}
bool IsMapped(GamePadConfigurationSource item)
{
return item.Type != ConfigurationType.Unmapped;
}
#endregion
}
}

View file

@ -23,8 +23,6 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
using System.Runtime.InteropServices;
#endregion
@ -118,10 +116,91 @@ namespace OpenTK.Platform.SDL2
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_FreeSurface", ExactSpelling = true)]
public static extern void FreeSurface(IntPtr surface);
#region GameContoller
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GameControllerEventState", ExactSpelling = true)]
public static extern EventState GameControllerEventState(EventState state);
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GameControllerGetAxis", ExactSpelling = true)]
public static extern short GameControllerGetAxis(IntPtr gamecontroller, GameControllerAxis axis);
/// <summary>
/// Gets the SDL joystick layer binding for the specified game controller axis
/// </summary>
/// <param name="gamecontroller">Pointer to a game controller instance returned by <c>GameControllerOpen</c>.</param>
/// <param name="axis">A value from the <c>GameControllerAxis</c> enumeration</param>
/// <returns>A GameControllerButtonBind instance describing the specified binding</returns>
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GameControllerGetBindForAxis", ExactSpelling = true)]
public static extern GameControllerButtonBind GameControllerGetBindForAxis(IntPtr gamecontroller, GameControllerAxis axis);
/// <summary>
/// Gets the SDL joystick layer binding for the specified game controller button
/// </summary>
/// <param name="gamecontroller">Pointer to a game controller instance returned by <c>GameControllerOpen</c>.</param>
/// <param name="button">A value from the <c>GameControllerButton</c> enumeration</param>
/// <returns>A GameControllerButtonBind instance describing the specified binding</returns>
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GameControllerGetBindForButton", ExactSpelling = true)]
public static extern GameControllerButtonBind GameControllerGetBindForButton(
IntPtr gamecontroller, GameControllerButton button);
/// <summary>
/// Gets the current state of a button on a game controller.
/// </summary>
/// <param name="gamecontroller">A game controller handle previously opened with <c>GameControllerOpen</c>.</param>
/// <param name="button">A zero-based <c>GameControllerButton</c> value.</param>
/// <returns><c>true</c> if the specified button is pressed; <c>false</c> otherwise.</returns>
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GameControllerGetButton", ExactSpelling = true)]
public static extern bool GameControllerGetButton(IntPtr gamecontroller, GameControllerButton button);
/// <summary>
/// Retrieve the joystick handle that corresponds to the specified game controller.
/// </summary>
/// <param name="gamecontroller">A game controller handle previously opened with <c>GameControllerOpen</c>.</param>
/// <returns>A handle to a joystick, or IntPtr.Zero in case of error. The pointer is owned by the callee. Use <c>SDL.GetError</c> to retrieve error information</returns>
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GameControllerGetJoystick", ExactSpelling = true)]
public static extern IntPtr GameControllerGetJoystick(IntPtr gamecontroller);
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetCurrentDisplayMode", ExactSpelling = true)]
public static extern int GetCurrentDisplayMode(int displayIndex, out DisplayMode mode);
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GameControllerName", ExactSpelling = true)]
static extern IntPtr GameControllerNameInternal(IntPtr gamecontroller);
/// <summary>
/// Return the name for an openend game controller instance.
/// </summary>
/// <returns>The name of the game controller name.</returns>
/// <param name="gamecontroller">Pointer to a game controller instance returned by <c>GameControllerOpen</c>.</param>
public static string GameControllerName(IntPtr gamecontroller)
{
unsafe
{
return new string((sbyte*)GameControllerNameInternal(gamecontroller));
}
}
/// <summary>
/// Opens a game controller for use.
/// </summary>
/// <param name="joystick_index">
/// A zero-based index for the game controller.
/// This index is the value which will identify this controller in future controller events.
/// </param>
/// <returns>A handle to the game controller instance, or IntPtr.Zero in case of error.</returns>
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GameControllerOpen", ExactSpelling = true)]
public static extern IntPtr GameControllerOpen(int joystick_index);
#endregion
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetDisplayBounds", ExactSpelling = true)]
public static extern int GetDisplayBounds(int displayIndex, out Rect rect);
@ -192,10 +271,27 @@ namespace OpenTK.Platform.SDL2
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_Init", ExactSpelling = true)]
public static extern int Init(SystemFlags flags);
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_InitSubSystem", ExactSpelling = true)]
public static extern int InitSubSystem(SystemFlags flags);
/// <summary>
/// Determines if the specified joystick is supported by the GameController API.
/// </summary>
/// <returns><c>true</c> if joystick_index is supported by the GameController API; <c>false</c> otherwise.</returns>
/// <param name="joystick_index">The index of the joystick to check.</param>
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_IsGameController", ExactSpelling = true)]
public static extern bool IsGameController(int joystick_index);
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickClose", ExactSpelling = true)]
public static extern void JoystickClose(IntPtr joystick);
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickEventState", ExactSpelling = true)]
public static extern EventState JoystickEventState(EventState enabled);
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickGetAxis", ExactSpelling = true)]
public static extern short JoystickGetAxis(IntPtr joystick, int axis);
@ -204,6 +300,10 @@ namespace OpenTK.Platform.SDL2
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickGetButton", ExactSpelling = true)]
public static extern byte JoystickGetButton(IntPtr joystick, int button);
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickGetGUID", ExactSpelling = true)]
public static extern JoystickGuid JoystickGetGUID(IntPtr joystick);
[SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickName", ExactSpelling = true)]
static extern IntPtr JoystickNameInternal(IntPtr joystick);
@ -462,6 +562,13 @@ namespace OpenTK.Platform.SDL2
ES = 0x0004
}
enum EventState
{
Query = -1,
Ignore = 0,
Enable = 1
}
enum EventType
{
FIRSTEVENT = 0,
@ -501,6 +608,61 @@ namespace OpenTK.Platform.SDL2
LASTEVENT = 0xFFFF
}
enum GameControllerAxis : byte
{
Invalid = 0xff,
LeftX = 0,
LeftY,
RightX,
RightY,
TriggerLeft,
TriggerRight,
Max
}
enum GameControllerButton : byte
{
INVALID = 0xff,
A = 0,
B,
X,
Y,
BACK,
GUIDE,
START,
LEFTSTICK,
RIGHTSTICK,
LEFTSHOULDER,
RIGHTSHOULDER,
DPAD_UP,
DPAD_DOWN,
DPAD_LEFT,
DPAD_RIGHT,
Max
}
enum GameControllerBindType : byte
{
None = 0,
Button,
Axis,
Hat
}
[Flags]
enum HatPosition : byte
{
Centered = 0x00,
Up = 0x01,
Right = 0x02,
Down = 0x03,
Left = 0x04,
RightUp = Right | Up,
RightDown = Right | Down,
LeftUp = Left | Up,
LeftDown = Left | Down
}
enum Keycode
{
UNKNOWN = 0,
@ -1080,6 +1242,41 @@ namespace OpenTK.Platform.SDL2
#region Structs
struct ControllerAxisEvent
{
public EventType Type;
public uint Timestamp;
public int Which;
public GameControllerAxis Axis;
byte padding1;
byte padding2;
byte padding3;
public short Value;
ushort padding4;
}
struct ControllerButtonEvent
{
public EventType Type;
public uint Timestamp;
public int Which;
public GameControllerButton Button;
public State State;
byte padding1;
byte padding2;
}
struct ControllerDeviceEvent
{
public EventType Type;
public uint Timestamp;
/// <summary>
/// The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event
/// </summary>
public int Which;
}
struct DisplayMode
{
public uint Format;
@ -1110,21 +1307,21 @@ namespace OpenTK.Platform.SDL2
public MouseWheelEvent Wheel;
[FieldOffset(0)]
public JoyAxisEvent JoyAxis;
[FieldOffset(0)]
public JoyBallEvent JoyBall;
[FieldOffset(0)]
public JoyHatEvent JoyHat;
[FieldOffset(0)]
public JoyButtonEvent JoyButton;
[FieldOffset(0)]
public JoyDeviceEvent JoyDevice;
[FieldOffset(0)]
public ControllerAxisEvent ControllerAxis;
[FieldOffset(0)]
public ControllerButtonEvent ControllerButton;
[FieldOffset(0)]
public ControllerDeviceEvent ControllerDevice;
#if false
[FieldOffset(0)]
public JoyBallEvent jball;
[FieldOffset(0)]
public JoyHatEvent jhat;
[FieldOffset(0)]
public JoyButtonEvent jbutton;
[FieldOffset(0)]
public JoyDeviceEvent jdevice;
[FieldOffset(0)]
public ControllerAxisEvent caxis;
[FieldOffset(0)]
public ControllerButtonEvent cbutton;
[FieldOffset(0)]
public ControllerDeviceEvent cdevice;
[FieldOffset(0)]
public QuitEvent quit;
[FieldOffset(0)]
@ -1142,6 +1339,21 @@ namespace OpenTK.Platform.SDL2
#endif
}
[StructLayout(LayoutKind.Explicit)]
struct GameControllerButtonBind
{
[FieldOffset(0)]
public GameControllerBindType BindType;
[FieldOffset(4)]
public Button Button;
[FieldOffset(4)]
public GameControllerAxis Axis;
[FieldOffset(4)]
public int Hat;
[FieldOffset(8)]
public int HatMask;
}
struct JoyAxisEvent
{
public EventType Type;
@ -1155,6 +1367,68 @@ namespace OpenTK.Platform.SDL2
UInt16 padding4;
}
struct JoyBallEvent
{
public EventType Type;
public uint Timestamp;
public int Which;
public byte Ball;
byte padding1;
byte padding2;
byte padding3;
public short Xrel;
public short Yrel;
}
struct JoyButtonEvent
{
public EventType Type;
public uint Timestamp;
public int Which;
public byte Button;
public State State;
byte padding1;
byte padding2;
}
struct JoyDeviceEvent
{
public EventType Type;
public uint Timestamp;
public int Which;
}
struct JoyHatEvent
{
public EventType Type;
public uint Timestamp;
public int Which;
public byte Hat;
public HatPosition Value;
byte padding1;
byte padding2;
}
struct JoystickGuid
{
unsafe fixed byte data[16];
public Guid ToGuid()
{
byte[] bytes = new byte[16];
unsafe
{
fixed (byte* pdata = data)
{
Marshal.Copy(new IntPtr(pdata), bytes, 0, bytes.Length);
}
}
return new Guid(bytes);
}
}
struct KeyboardEvent
{
public EventType Type;

View file

@ -34,7 +34,7 @@ namespace OpenTK.Platform.SDL2
{
class Sdl2Factory : IPlatformFactory
{
readonly IInputDriver2 InputDriver = new Sdl2InputDriver();
readonly Sdl2InputDriver InputDriver = new Sdl2InputDriver();
bool disposed;
/// <summary>
@ -58,7 +58,7 @@ namespace OpenTK.Platform.SDL2
public INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
{
return new Sdl2NativeWindow(x, y, width, height, title, options, device);
return new Sdl2NativeWindow(x, y, width, height, title, options, device, InputDriver);
}
public IDisplayDeviceDriver CreateDisplayDeviceDriver()
@ -104,6 +104,11 @@ namespace OpenTK.Platform.SDL2
return InputDriver.GamePadDriver;
}
public IJoystickDriver2 CreateJoystickDriver()
{
return InputDriver.JoystickDriver;
}
#endregion
#region IDisposable Members

View file

@ -55,10 +55,21 @@ namespace OpenTK.Platform.SDL2
{
lock (SDL.Sync)
{
SDL.GameControllerEventState(EventState.Enable);
SDL.JoystickEventState(EventState.Enable);
EventFilterDelegate = Marshal.GetFunctionPointerForDelegate(EventFilterDelegate_GCUnsafe);
driver_handle = new IntPtr(count++);
DriverHandles.Add(driver_handle, this);
SDL.AddEventWatch(EventFilterDelegate, driver_handle);
if (SDL.InitSubSystem(SystemFlags.JOYSTICK) < 0)
{
Debug.Print("[SDL2] InputDriver failed to init Joystick subsystem. Error: {0}", SDL.GetError());
}
if (SDL.InitSubSystem(SystemFlags.GAMECONTROLLER) < 0)
{
Debug.Print("[SDL2] InputDriver failed to init GameController subsystem. Error: {0}", SDL.GetError());
}
}
}
@ -92,6 +103,44 @@ namespace OpenTK.Platform.SDL2
case EventType.MOUSEWHEEL:
driver.mouse_driver.ProcessWheelEvent(ev.Wheel);
break;
case EventType.JOYDEVICEADDED:
case EventType.JOYDEVICEREMOVED:
driver.joystick_driver.ProcessJoystickEvent(ev.JoyDevice);
break;
case EventType.JOYAXISMOTION:
driver.joystick_driver.ProcessJoystickEvent(ev.JoyAxis);
break;
case EventType.JOYBALLMOTION:
driver.joystick_driver.ProcessJoystickEvent(ev.JoyBall);
break;
case EventType.JOYBUTTONDOWN:
case EventType.JOYBUTTONUP:
driver.joystick_driver.ProcessJoystickEvent(ev.JoyButton);
break;
case EventType.JOYHATMOTION:
driver.joystick_driver.ProcessJoystickEvent(ev.JoyHat);
break;
#if USE_SDL2_GAMECONTROLLER
case EventType.CONTROLLERDEVICEADDED:
case EventType.CONTROLLERDEVICEREMOVED:
driver.joystick_driver.ProcessControllerEvent(ev.ControllerDevice);
break;
case EventType.CONTROLLERAXISMOTION:
driver.joystick_driver.ProcessControllerEvent(ev.ControllerAxis);
break;
case EventType.CONTROLLERBUTTONDOWN:
case EventType.CONTROLLERBUTTONUP:
driver.joystick_driver.ProcessControllerEvent(ev.ControllerButton);
break;
#endif
}
}
}
@ -172,7 +221,15 @@ namespace OpenTK.Platform.SDL2
{
get
{
throw new NotImplementedException();
return joystick_driver;
}
}
public IJoystickDriver2 JoystickDriver
{
get
{
return joystick_driver;
}
}

View file

@ -32,61 +32,482 @@ using OpenTK.Input;
namespace OpenTK.Platform.SDL2
{
class Sdl2JoystickDriver : IJoystickDriver, IGamePadDriver, IDisposable
class Sdl2JoystickDriver : IJoystickDriver, IJoystickDriver2, IGamePadDriver, IDisposable
{
struct Sdl2JoystickDetails
const float RangeMultiplier = 1.0f / 32768.0f;
readonly MappedGamePadDriver gamepad_driver = new MappedGamePadDriver();
bool disposed;
class Sdl2JoystickDetails
{
public IntPtr Handle { get; set; }
public float RangeMultiplier { get { return 1.0f / 32768.0f; } }
public Guid Guid { get; set; }
public int PacketNumber { get; set; }
public int HatCount { get; set; }
public int BallCount { get; set; }
public bool IsConnected { get; set; }
}
readonly List<JoystickDevice> joysticks = new List<JoystickDevice>();
// For IJoystickDriver2 implementation
int last_joystick_instance = 0;
readonly List<JoystickDevice> joysticks = new List<JoystickDevice>(4);
readonly Dictionary<int, int> sdl_instanceid_to_joysticks = new Dictionary<int, int>();
// For IJoystickDriver implementation
IList<JoystickDevice> joysticks_readonly;
bool disposed = false;
#if USE_SDL2_GAMECONTROLLER
class Sdl2GamePad
{
public IntPtr Handle { get; private set; }
public GamePadState State;
public GamePadCapabilities Capabilities;
public Sdl2GamePad(IntPtr handle)
{
Handle = handle;
}
}
int last_controllers_instance = 0;
readonly List<Sdl2GamePad> controllers = new List<Sdl2GamePad>(4);
readonly Dictionary<int, int> sdl_instanceid_to_controllers = new Dictionary<int, int>();
#endif
public Sdl2JoystickDriver()
{
joysticks_readonly = joysticks.AsReadOnly();
RefreshJoysticks();
}
#region Private Members
void RefreshJoysticks()
JoystickDevice<Sdl2JoystickDetails> OpenJoystick(int id)
{
joysticks.Clear();
JoystickDevice<Sdl2JoystickDetails> joystick = null;
int num_axes = 0;
int num_buttons = 0;
int num_hats = 0;
int num_balls = 0;
int count = SDL.NumJoysticks();
for (int i = 0; i < count; i++)
IntPtr handle = SDL.JoystickOpen(id);
if (handle != IntPtr.Zero)
{
JoystickDevice<Sdl2JoystickDetails> joystick = null;
int num_axes = 0;
int num_buttons = 0;
int num_hats = 0;
int num_balls = 0;
num_axes = SDL.JoystickNumAxes(handle);
num_buttons = SDL.JoystickNumButtons(handle);
num_hats = SDL.JoystickNumHats(handle);
num_balls = SDL.JoystickNumBalls(handle);
IntPtr handle = SDL.JoystickOpen(i);
if (handle != IntPtr.Zero)
{
num_axes = SDL.JoystickNumAxes(handle);
num_buttons = SDL.JoystickNumButtons(handle);
num_hats = SDL.JoystickNumHats(handle);
num_balls = SDL.JoystickNumBalls(handle);
joystick = new JoystickDevice<Sdl2JoystickDetails>(id, num_axes, num_buttons);
joystick.Description = SDL.JoystickName(handle);
joystick.Details.Handle = handle;
joystick.Details.Guid = SDL.JoystickGetGUID(handle).ToGuid();
joystick.Details.HatCount = num_hats;
joystick.Details.BallCount = num_balls;
joystick = new JoystickDevice<Sdl2JoystickDetails>(i, num_axes, num_buttons);
joystick.Description = SDL.JoystickName(handle);
joystick.Details.Handle = handle;
joystick.Details.HatCount = num_hats;
joystick.Details.BallCount = num_balls;
joysticks.Add(joystick);
}
Debug.Print("[SDL2] Joystick device {0} opened successfully. ", id);
Debug.Print("\t\t'{0}' has {1} axes, {2} buttons, {3} hats, {4} balls",
joystick.Description, joystick.Axis.Count, joystick.Button.Count,
joystick.Details.HatCount, joystick.Details.BallCount);
}
else
{
Debug.Print("[SDL2] Failed to open joystick device {0}", id);
}
return joystick;
}
bool IsJoystickValid(int id)
{
return id >= 0 && id < joysticks.Count;
}
bool IsJoystickInstanceValid(int instance_id)
{
return sdl_instanceid_to_joysticks.ContainsKey(instance_id);
}
#if USE_SDL2_GAMECONTROLLER
bool IsControllerValid(int id)
{
return id >= 0 && id < controllers.Count;
}
bool IsControllerInstanceValid(int instance_id)
{
return sdl_instanceid_to_controllers.ContainsKey(instance_id);
}
GamePadAxes GetBoundAxes(IntPtr gamecontroller)
{
GamePadAxes axes = 0;
axes |= IsAxisBind(gamecontroller, GameControllerAxis.LeftX) ? GamePadAxes.LeftX : 0;
axes |= IsAxisBind(gamecontroller, GameControllerAxis.LeftY) ? GamePadAxes.LeftY : 0;
axes |= IsAxisBind(gamecontroller, GameControllerAxis.RightX) ? GamePadAxes.RightX : 0;
axes |= IsAxisBind(gamecontroller, GameControllerAxis.RightY) ? GamePadAxes.RightY : 0;
axes |= IsAxisBind(gamecontroller, GameControllerAxis.TriggerLeft) ? GamePadAxes.LeftTrigger : 0;
axes |= IsAxisBind(gamecontroller, GameControllerAxis.TriggerRight) ? GamePadAxes.RightTrigger : 0;
return axes;
}
Buttons GetBoundButtons(IntPtr gamecontroller)
{
Buttons buttons = 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.A) ? Buttons.A : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.B) ? Buttons.B : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.X) ? Buttons.X : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.Y) ? Buttons.Y : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.START) ? Buttons.Start : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.BACK) ? Buttons.Back : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.LEFTSHOULDER) ? Buttons.LeftShoulder : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.RIGHTSHOULDER) ? Buttons.RightShoulder : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.LEFTSTICK) ? Buttons.LeftStick : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.RIGHTSTICK) ? Buttons.RightStick : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.GUIDE) ? Buttons.BigButton : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.DPAD_DOWN) ? Buttons.DPadDown : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.DPAD_UP) ? Buttons.DPadUp : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.DPAD_LEFT) ? Buttons.DPadLeft : 0;
buttons |= IsButtonBind(gamecontroller, GameControllerButton.DPAD_RIGHT) ? Buttons.DPadRight : 0;
return buttons;
}
bool IsAxisBind(IntPtr gamecontroller, GameControllerAxis axis)
{
GameControllerButtonBind bind =
SDL.GameControllerGetBindForAxis(gamecontroller, axis);
return bind.BindType == GameControllerBindType.Axis;
}
bool IsButtonBind(IntPtr gamecontroller, GameControllerButton button)
{
GameControllerButtonBind bind =
SDL.GameControllerGetBindForButton(gamecontroller, button);
return bind.BindType == GameControllerBindType.Button;
}
GamePadAxes TranslateAxis(GameControllerAxis axis)
{
switch (axis)
{
case GameControllerAxis.LeftX:
return GamePadAxes.LeftX;
case GameControllerAxis.LeftY:
return GamePadAxes.LeftY;
case GameControllerAxis.RightX:
return GamePadAxes.RightX;
case GameControllerAxis.RightY:
return GamePadAxes.RightY;
case GameControllerAxis.TriggerLeft:
return GamePadAxes.LeftTrigger;
case GameControllerAxis.TriggerRight:
return GamePadAxes.RightTrigger;
default:
throw new ArgumentOutOfRangeException(
String.Format("[SDL] Unknown axis {0}", axis));
}
}
Buttons TranslateButton(GameControllerButton button)
{
switch (button)
{
case GameControllerButton.A:
return Buttons.A;
case GameControllerButton.B:
return Buttons.B;
case GameControllerButton.X:
return Buttons.X;
case GameControllerButton.Y:
return Buttons.Y;
case GameControllerButton.LEFTSHOULDER:
return Buttons.LeftShoulder;
case GameControllerButton.RIGHTSHOULDER:
return Buttons.RightShoulder;
case GameControllerButton.LEFTSTICK:
return Buttons.LeftStick;
case GameControllerButton.RIGHTSTICK:
return Buttons.RightStick;
case GameControllerButton.DPAD_UP:
return Buttons.DPadUp;
case GameControllerButton.DPAD_DOWN:
return Buttons.DPadDown;
case GameControllerButton.DPAD_LEFT:
return Buttons.DPadLeft;
case GameControllerButton.DPAD_RIGHT:
return Buttons.DPadRight;
case GameControllerButton.BACK:
return Buttons.Back;
case GameControllerButton.START:
return Buttons.Start;
case GameControllerButton.GUIDE:
return Buttons.BigButton;
default:
Debug.Print("[SDL2] Unknown button {0}", button);
return 0;
}
}
#endif
#endregion
#region Public Members
public void ProcessJoystickEvent(JoyDeviceEvent ev)
{
int id = ev.Which;
if (id < 0)
{
Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type);
return;
}
switch (ev.Type)
{
case EventType.JOYDEVICEADDED:
{
IntPtr handle = SDL.JoystickOpen(id);
if (handle != IntPtr.Zero)
{
int device_id = id;
int instance_id = last_joystick_instance++;
JoystickDevice<Sdl2JoystickDetails> joystick = OpenJoystick(id);
if (joystick != null)
{
joystick.Details.IsConnected = true;
if (device_id < joysticks.Count)
{
joysticks[device_id] = joystick;
}
else
{
joysticks.Add(joystick);
}
sdl_instanceid_to_joysticks.Add(instance_id, device_id);
}
}
}
break;
case EventType.JOYDEVICEREMOVED:
if (IsJoystickInstanceValid(id))
{
int instance_id = id;
int device_id = sdl_instanceid_to_joysticks[instance_id];
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[device_id];
joystick.Details.IsConnected = false;
sdl_instanceid_to_joysticks.Remove(instance_id);
}
else
{
Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type);
}
break;
}
}
public void ProcessJoystickEvent(JoyAxisEvent ev)
{
int id = ev.Which;
if (IsJoystickInstanceValid(id))
{
int index = sdl_instanceid_to_joysticks[id];
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
float value = ev.Value * RangeMultiplier;
joystick.SetAxis((JoystickAxis)ev.Axis, value);
joystick.Details.PacketNumber = Math.Max(0, unchecked(joystick.Details.PacketNumber + 1));
}
else
{
Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type);
}
}
public void ProcessJoystickEvent(JoyBallEvent ev)
{
int id = ev.Which;
if (IsJoystickInstanceValid(id))
{
int index = sdl_instanceid_to_joysticks[id];
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
// Todo: does it make sense to support balls?
joystick.Details.PacketNumber = Math.Max(0, unchecked(joystick.Details.PacketNumber + 1));
}
else
{
Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type);
}
}
public void ProcessJoystickEvent(JoyButtonEvent ev)
{
int id = ev.Which;
if (IsJoystickInstanceValid(id))
{
int index = sdl_instanceid_to_joysticks[id];
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
joystick.SetButton((JoystickButton)ev.Button, ev.State == State.Pressed);
joystick.Details.PacketNumber = Math.Max(0, unchecked(joystick.Details.PacketNumber + 1));
}
else
{
Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type);
}
}
public void ProcessJoystickEvent(JoyHatEvent ev)
{
int id = ev.Which;
if (IsJoystickInstanceValid(id))
{
int index = sdl_instanceid_to_joysticks[id];
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
// Todo: map hat to an extra axis
joystick.Details.PacketNumber = Math.Max(0, unchecked(joystick.Details.PacketNumber + 1));
}
else
{
Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type);
}
}
#if USE_SDL2_GAMECONTROLLER
public void ProcessControllerEvent(ControllerDeviceEvent ev)
{
int id = ev.Which;
if (id < 0)
{
Debug.Print("[SDL2] Invalid controller id {0} in {1}", id, ev.Type);
return;
}
switch (ev.Type)
{
case EventType.CONTROLLERDEVICEADDED:
IntPtr handle = SDL.GameControllerOpen(id);
if (handle != IntPtr.Zero)
{
// The id variable here corresponds to a device_id between 0 and Sdl.NumJoysticks().
// It is only used in the ADDED event. All other events use an instance_id which increases
// monotonically in each ADDED event.
// The idea is that device_id refers to the n-th connected joystick, whereas instance_id
// refers to the actual hardware device behind the n-th joystick.
// Yes, it's confusing.
int device_id = id;
int instance_id = last_controllers_instance++;
Sdl2GamePad pad = new Sdl2GamePad(handle);
IntPtr joystick = SDL.GameControllerGetJoystick(handle);
if (joystick != IntPtr.Zero)
{
pad.Capabilities = new GamePadCapabilities(
GamePadType.GamePad,
GetBoundAxes(joystick),
GetBoundButtons(joystick),
true);
pad.State.SetConnected(true);
// Connect this device and add the relevant device index
if (controllers.Count <= id)
{
controllers.Add(pad);
}
else
{
controllers[device_id] = pad;
}
sdl_instanceid_to_controllers.Add(instance_id, device_id);
}
else
{
Debug.Print("[SDL2] Failed to retrieve joystick from game controller. Error: {0}", SDL.GetError());
}
}
break;
case EventType.CONTROLLERDEVICEREMOVED:
if (IsControllerInstanceValid(id))
{
int instance_id = id;
int device_id = sdl_instanceid_to_controllers[instance_id];
controllers[device_id].State.SetConnected(false);
sdl_instanceid_to_controllers.Remove(device_id);
}
else
{
Debug.Print("[SDL2] Invalid game controller instance {0} in {1}", id, ev.Type);
}
break;
case EventType.CONTROLLERDEVICEREMAPPED:
if (IsControllerInstanceValid(id))
{
// Todo: what should we do in this case?
}
else
{
Debug.Print("[SDL2] Invalid game controller instance {0} in {1}", id, ev.Type);
}
break;
}
}
public void ProcessControllerEvent(ControllerAxisEvent ev)
{
int instance_id = ev.Which;
if (IsControllerInstanceValid(instance_id))
{
int id = sdl_instanceid_to_controllers[instance_id];
controllers[id].State.SetAxis(TranslateAxis(ev.Axis), ev.Value);
}
else
{
Debug.Print("[SDL2] Invalid game controller instance {0} in {1}", instance_id, ev.Type);
}
}
public void ProcessControllerEvent(ControllerButtonEvent ev)
{
int instance_id = ev.Which;
if (IsControllerInstanceValid(instance_id))
{
int id = sdl_instanceid_to_controllers[instance_id];
controllers[id].State.SetButton(TranslateButton(ev.Button), ev.State == State.Pressed);
}
else
{
Debug.Print("[SDL2] Invalid game controller instance {0} in {1}", instance_id, ev.Type);
}
}
#endif
#endregion
#region IJoystickDriver Members
@ -101,49 +522,114 @@ namespace OpenTK.Platform.SDL2
public void Poll()
{
SDL.JoystickUpdate();
foreach (var j in joysticks)
{
var joystick = (JoystickDevice<Sdl2JoystickDetails>)j;
IntPtr handle = joystick.Details.Handle;
for (int i = 0; i < joystick.Axis.Count; i++)
{
var axis = JoystickAxis.Axis0 + i;
joystick.SetAxis(axis, SDL.JoystickGetAxis(handle, i) * joystick.Details.RangeMultiplier);
}
for (int i = 0; i < joystick.Button.Count; i++)
{
var button = JoystickButton.Button0 + i;
joystick.SetButton(button, SDL.JoystickGetButton(handle, i) != 0);
}
}
// Do nothing
}
#endregion
#region IGamePadDriver Members
public GamePadState GetState()
#if USE_SDL2_GAMECONTOLLER
public GamePadCapabilities GetCapabilities(int index)
{
return new GamePadState();
if (IsControllerValid(index))
{
return controllers[index].Capabilities;
}
return new GamePadCapabilities();
}
public GamePadState GetState(int index)
{
if (joysticks.Count >= index)
if (IsControllerValid(index))
{
return controllers[index].State;
}
return new GamePadState();
}
public string GetDeviceName(int index)
public string GetName(int index)
{
return String.Empty;
}
#else
public GamePadCapabilities GetCapabilities(int index)
{
return gamepad_driver.GetCapabilities(index);
}
public GamePadState GetState(int index)
{
return gamepad_driver.GetState(index);
}
public string GetName(int index)
{
return gamepad_driver.GetName(index);
}
public bool SetVibration(int index, float left, float right)
{
return false;
}
#endif
#endregion
#region IJoystickDriver2 Members
JoystickState IJoystickDriver2.GetState(int index)
{
JoystickState state = new JoystickState();
if (IsJoystickValid(index))
{
JoystickDevice<Sdl2JoystickDetails> joystick =
(JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
for (int i = 0; i < joystick.Axis.Count; i++)
{
state.SetAxis(JoystickAxis.Axis0 + i, (short)(joystick.Axis[i] * short.MaxValue + 0.5f));
}
for (int i = 0; i < joystick.Button.Count; i++)
{
state.SetButton(JoystickButton.Button0 + i, joystick.Button[i]);
}
state.SetIsConnected(joystick.Details.IsConnected);
state.SetPacketNumber(joystick.Details.PacketNumber);
}
return state;
}
JoystickCapabilities IJoystickDriver2.GetCapabilities(int index)
{
if (IsJoystickValid(index))
{
JoystickDevice<Sdl2JoystickDetails> joystick =
(JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
return new JoystickCapabilities(
joystick.Axis.Count,
joystick.Button.Count,
joystick.Details.IsConnected);
}
return new JoystickCapabilities();
}
Guid IJoystickDriver2.GetGuid(int index)
{
Guid guid = new Guid();
if (IsJoystickValid(index))
{
JoystickDevice<Sdl2JoystickDetails> joystick =
(JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
return joystick.Details.Guid;
}
return guid;
}
#endregion

View file

@ -70,7 +70,7 @@ namespace OpenTK.Platform.SDL2
// Argument for KeyDown and KeyUp events (allocated once to avoid runtime allocations)
readonly KeyboardKeyEventArgs key_args = new KeyboardKeyEventArgs();
readonly IInputDriver input_driver = new Sdl2InputDriver();
readonly IInputDriver input_driver;
readonly EventFilter EventFilterDelegate_GCUnsafe = FilterEvents;
readonly IntPtr EventFilterDelegate;
@ -81,10 +81,13 @@ namespace OpenTK.Platform.SDL2
static readonly Sdl2KeyMap map = new Sdl2KeyMap();
public Sdl2NativeWindow(int x, int y, int width, int height,
string title, GameWindowFlags options, DisplayDevice device)
string title, GameWindowFlags options, DisplayDevice device,
IInputDriver input_driver)
{
lock (sync)
{
this.input_driver = input_driver;
var bounds = device.Bounds;
var flags = TranslateFlags(options);
flags |= WindowFlags.OPENGL;

View file

@ -130,7 +130,12 @@ namespace OpenTK.Platform.Windows
{
return InputDriver.GamePadDriver;
}
public IJoystickDriver2 CreateJoystickDriver()
{
return InputDriver.JoystickDriver;
}
#endregion
IInputDriver2 InputDriver

View file

@ -164,6 +164,8 @@ namespace OpenTK.Platform.Windows
public abstract IKeyboardDriver2 KeyboardDriver { get; }
public abstract IGamePadDriver GamePadDriver { get; }
public abstract IJoystickDriver2 JoystickDriver { get; }
#endregion
#region IDisposable Members

View file

@ -36,7 +36,7 @@ using System.Diagnostics;
namespace OpenTK.Platform.Windows
{
sealed class WinMMJoystick : IJoystickDriver, IGamePadDriver
sealed class WinMMJoystick : IJoystickDriver, IJoystickDriver2
{
#region Fields
@ -133,6 +133,27 @@ namespace OpenTK.Platform.Windows
return stick;
}
void UnplugJoystick(int index)
{
// Reset the system configuration. Without this,
// joysticks that are reconnected on different
// ports are given different ids, making it
// impossible to reconnect a disconnected user.
UnsafeNativeMethods.joyConfigChanged(0);
Debug.Print("[Win] WinMM joystick {0} unplugged", index);
}
bool IsValid(int index)
{
return index >= 0 && index < UnsafeNativeMethods.joyGetNumDevs();
}
static short CalculateOffset(int pos, int min, int max)
{
int offset = (ushort.MaxValue * (pos - min)) / (max - min) - short.MaxValue;
return (short)offset;
}
#endregion
#region IJoystickDriver
@ -237,6 +258,95 @@ namespace OpenTK.Platform.Windows
#endregion
#region IJoystickDriver2 Members
public JoystickCapabilities GetCapabilities(int index)
{
if (IsValid(index))
{
JoyCaps mmcaps;
JoystickError result = UnsafeNativeMethods.joyGetDevCaps(index, out mmcaps, JoyCaps.SizeInBytes);
if (result == JoystickError.NoError)
{
JoystickCapabilities caps = new JoystickCapabilities(
mmcaps.NumAxes, mmcaps.NumButtons, true);
//if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0)
// gpcaps.DPadCount++;
return caps;
}
else if (result == JoystickError.Unplugged)
{
UnplugJoystick(index);
}
}
else
{
Debug.Print("[Win] Invalid WinMM joystick device {0}", index);
}
return new JoystickCapabilities();
}
public JoystickState GetState(int index)
{
JoystickState state = new JoystickState();
if (IsValid(index))
{
JoyInfoEx info = new JoyInfoEx();
info.Size = JoyInfoEx.SizeInBytes;
info.Flags = JoystickFlags.All;
JoystickError result = UnsafeNativeMethods.joyGetPosEx(index, ref info);
if (result == JoystickError.NoError)
{
JoyCaps caps;
result = UnsafeNativeMethods.joyGetDevCaps(index, out caps, JoyCaps.SizeInBytes);
if (result == JoystickError.NoError)
{
state.SetAxis(JoystickAxis.Axis0, CalculateOffset(info.XPos, caps.XMin, caps.XMax));
state.SetAxis(JoystickAxis.Axis1, CalculateOffset(info.YPos, caps.YMin, caps.YMax));
state.SetAxis(JoystickAxis.Axis2, CalculateOffset(info.ZPos, caps.ZMin, caps.ZMax));
state.SetAxis(JoystickAxis.Axis3, CalculateOffset(info.RPos, caps.RMin, caps.RMax));
state.SetAxis(JoystickAxis.Axis4, CalculateOffset(info.UPos, caps.UMin, caps.UMax));
state.SetAxis(JoystickAxis.Axis5, CalculateOffset(info.VPos, caps.VMin, caps.VMax));
for (int i = 0; i < 16; i++)
{
state.SetButton(JoystickButton.Button0 + i, (info.Buttons & 1 << i) != 0);
}
state.SetIsConnected(true);
}
}
if (result == JoystickError.Unplugged)
{
UnplugJoystick(index);
}
}
else
{
Debug.Print("[Win] Invalid WinMM joystick device {0}", index);
}
return state;
}
public Guid GetGuid(int index)
{
Guid guid = new Guid();
if (IsValid(index))
{
// Todo: implement WinMM Guid retrieval
}
return guid;
}
#endregion
#region IDisposable
public void Dispose()
@ -378,9 +488,11 @@ namespace OpenTK.Platform.Windows
[DllImport("Winmm.dll"), SuppressUnmanagedCodeSecurity]
public static extern JoystickError joyGetDevCaps(int uJoyID, out JoyCaps pjc, int cbjc);
[DllImport("Winmm.dll"), SuppressUnmanagedCodeSecurity]
public static extern uint joyGetPosEx(int uJoyID, ref JoyInfoEx pji);
public static extern JoystickError joyGetPosEx(int uJoyID, ref JoyInfoEx pji);
[DllImport("Winmm.dll"), SuppressUnmanagedCodeSecurity]
public static extern int joyGetNumDevs();
[DllImport("Winmm.dll"), SuppressUnmanagedCodeSecurity]
public static extern JoystickError joyConfigChanged(int flags);
}
#endregion
@ -427,21 +539,5 @@ namespace OpenTK.Platform.Windows
}
#endregion
//HACK implement
public GamePadState GetState()
{
throw new NotImplementedException();
}
public GamePadState GetState(int index)
{
throw new NotImplementedException();
}
public string GetDeviceName(int index)
{
throw new NotImplementedException();
}
}
}

View file

@ -43,7 +43,8 @@ namespace OpenTK.Platform.Windows
WinRawKeyboard keyboard_driver;
WinRawMouse mouse_driver;
WinMMJoystick joystick_driver;
IGamePadDriver gamepad_driver;
IJoystickDriver2 joystick_driver;
IntPtr DevNotifyHandle;
static readonly Guid DeviceInterfaceHid = new Guid("4D1E55B2-F16F-11CF-88CB-001111000030");
@ -138,6 +139,15 @@ namespace OpenTK.Platform.Windows
keyboard_driver = new WinRawKeyboard(Parent.Handle);
mouse_driver = new WinRawMouse(Parent.Handle);
joystick_driver = new WinMMJoystick();
try
{
gamepad_driver = new XInputJoystick();
}
catch (Exception e)
{
Debug.Print("[Win] XInput driver not supported, falling back to WinMM");
gamepad_driver = new MappedGamePadDriver();
}
DevNotifyHandle = RegisterForDeviceNotifications(Parent);
}
@ -186,6 +196,11 @@ namespace OpenTK.Platform.Windows
}
public override IGamePadDriver GamePadDriver
{
get { return gamepad_driver; }
}
public override IJoystickDriver2 JoystickDriver
{
get { return joystick_driver; }
}

View file

@ -0,0 +1,405 @@
#region License
//
// XInputJoystick.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using OpenTK.Input;
using System.Runtime.InteropServices;
using System.Security;
using System.Diagnostics;
namespace OpenTK.Platform.Windows
{
class XInputJoystick : IGamePadDriver, IDisposable
{
XInput xinput = new XInput();
#region IGamePadDriver Members
public GamePadState GetState(int index)
{
XInputState xstate;
XInputErrorCode error = xinput.GetState((XInputUserIndex)index, out xstate);
GamePadState state = new GamePadState();
if (error == XInputErrorCode.Success)
{
state.SetConnected(true);
state.SetAxis(GamePadAxes.LeftX, xstate.GamePad.ThumbLX);
state.SetAxis(GamePadAxes.LeftY, xstate.GamePad.ThumbLY);
state.SetAxis(GamePadAxes.RightX, xstate.GamePad.ThumbRX);
state.SetAxis(GamePadAxes.RightY, xstate.GamePad.ThumbRY);
state.SetTriggers(xstate.GamePad.LeftTrigger, xstate.GamePad.RightTrigger);
state.SetButton(TranslateButtons(xstate.GamePad.Buttons), true);
}
return state;
}
public GamePadCapabilities GetCapabilities(int index)
{
XInputDeviceCapabilities xcaps;
XInputErrorCode error = xinput.GetCapabilities(
(XInputUserIndex)index,
XInputCapabilitiesFlags.Default,
out xcaps);
if (error == XInputErrorCode.Success)
{
GamePadType type = TranslateSubType(xcaps.SubType);
Buttons buttons = TranslateButtons(xcaps.GamePad.Buttons);
GamePadAxes axes = TranslateAxes(ref xcaps.GamePad);
return new GamePadCapabilities(type, axes, buttons, true);
}
return new GamePadCapabilities();
}
public string GetName(int index)
{
return String.Empty;
}
public bool SetVibration(int index, float left, float right)
{
return false;
}
#endregion
#region Private Members
GamePadAxes TranslateAxes(ref XInputGamePad pad)
{
GamePadAxes axes = 0;
axes |= pad.ThumbLX != 0 ? GamePadAxes.LeftX : 0;
axes |= pad.ThumbLY != 0 ? GamePadAxes.LeftY : 0;
axes |= pad.LeftTrigger != 0 ? GamePadAxes.LeftTrigger : 0;
axes |= pad.ThumbRX != 0 ? GamePadAxes.RightX : 0;
axes |= pad.ThumbRY != 0 ? GamePadAxes.RightY : 0;
axes |= pad.RightTrigger != 0 ? GamePadAxes.RightTrigger : 0;
return axes;
}
Buttons TranslateButtons(XInputButtons xbuttons)
{
Buttons buttons = 0;
buttons |= (xbuttons & XInputButtons.A) != 0 ? Buttons.A : 0;
buttons |= (xbuttons & XInputButtons.B) != 0 ? Buttons.B : 0;
buttons |= (xbuttons & XInputButtons.X) != 0 ? Buttons.X : 0;
buttons |= (xbuttons & XInputButtons.Y) != 0 ? Buttons.Y : 0;
buttons |= (xbuttons & XInputButtons.Start) != 0 ? Buttons.Start : 0;
buttons |= (xbuttons & XInputButtons.Back) != 0 ? Buttons.Back : 0;
//buttons |= (xbuttons & XInputButtons.BigButton) != 0 ? Buttons.BigButton : 0;
buttons |= (xbuttons & XInputButtons.LeftShoulder) != 0 ? Buttons.LeftShoulder : 0;
buttons |= (xbuttons & XInputButtons.RightShoulder) != 0 ? Buttons.RightShoulder : 0;
buttons |= (xbuttons & XInputButtons.LeftThumb) != 0 ? Buttons.LeftStick : 0;
buttons |= (xbuttons & XInputButtons.RightThumb) != 0 ? Buttons.RightStick : 0;
buttons |= (xbuttons & XInputButtons.DPadDown) != 0 ? Buttons.DPadDown : 0;
buttons |= (xbuttons & XInputButtons.DPadUp) != 0 ? Buttons.DPadUp : 0;
buttons |= (xbuttons & XInputButtons.DPadLeft) != 0 ? Buttons.DPadLeft : 0;
buttons |= (xbuttons & XInputButtons.DPadRight) != 0 ? Buttons.DPadRight : 0;
return buttons;
}
GamePadType TranslateSubType(XInputDeviceSubType xtype)
{
switch (xtype)
{
case XInputDeviceSubType.ArcadePad: return GamePadType.ArcadePad;
case XInputDeviceSubType.ArcadeStick: return GamePadType.ArcadeStick;
case XInputDeviceSubType.DancePad: return GamePadType.DancePad;
case XInputDeviceSubType.DrumKit: return GamePadType.DrumKit;
case XInputDeviceSubType.FlightStick: return GamePadType.FlightStick;
case XInputDeviceSubType.GamePad: return GamePadType.GamePad;
case XInputDeviceSubType.Guitar: return GamePadType.Guitar;
case XInputDeviceSubType.GuitarAlternate: return GamePadType.AlternateGuitar;
case XInputDeviceSubType.GuitarBass: return GamePadType.BassGuitar;
case XInputDeviceSubType.Wheel: return GamePadType.Wheel;
case XInputDeviceSubType.Unknown:
default:
return GamePadType.Unknown;
}
}
enum XInputErrorCode
{
Success = 0,
DeviceNotConnected
}
enum XInputDeviceType : byte
{
GamePad
}
enum XInputDeviceSubType : byte
{
Unknown = 0,
GamePad = 1,
Wheel = 2,
ArcadeStick = 3,
FlightStick = 4,
DancePad = 5,
Guitar = 6,
GuitarAlternate = 7,
DrumKit = 8,
GuitarBass = 0xb,
ArcadePad = 0x13
}
enum XInputCapabilities
{
ForceFeedback = 0x0001,
Wireless = 0x0002,
Voice = 0x0004,
PluginModules = 0x0008,
NoNavigation = 0x0010,
}
enum XInputButtons : ushort
{
DPadUp = 0x0001,
DPadDown = 0x0002,
DPadLeft = 0x0004,
DPadRight = 0x0008,
Start = 0x0010,
Back = 0x0020,
LeftThumb = 0x0040,
RightThumb = 0x0080,
LeftShoulder = 0x0100,
RightShoulder = 0x0200,
A = 0x1000,
B = 0x2000,
X = 0x4000,
Y = 0x8000
}
[Flags]
enum XInputCapabilitiesFlags
{
Default = 0,
GamePadOnly = 1
}
enum XInputBatteryType : byte
{
Disconnected = 0x00,
Wired = 0x01,
Alkaline = 0x02,
NiMH = 0x03,
Unknown = 0xff
}
enum XInputBatteryLevel : byte
{
Empty = 0x00,
Low = 0x01,
Medium = 0x02,
Full = 0x03
}
enum XInputUserIndex
{
First = 0,
Second,
Third,
Fourth,
Any = 0xff
}
struct XInputThresholds
{
public const int LeftThumbDeadzone = 7849;
public const int RightThumbDeadzone = 8689;
public const int TriggerThreshold = 30;
}
struct XInputGamePad
{
public XInputButtons Buttons;
public byte LeftTrigger;
public byte RightTrigger;
public short ThumbLX;
public short ThumbLY;
public short ThumbRX;
public short ThumbRY;
}
struct XInputState
{
public int PacketNumber;
public XInputGamePad GamePad;
}
struct XInputVibration
{
public short LeftMotorSpeed;
public short RightMotorSpeed;
}
struct XInputDeviceCapabilities
{
public XInputDeviceType Type;
public XInputDeviceSubType SubType;
public short Flags;
public XInputGamePad GamePad;
public XInputVibration Vibration;
}
struct XInputBatteryInformation
{
public XInputBatteryType Type;
public XInputBatteryLevel Level;
}
class XInput : IDisposable
{
IntPtr dll;
internal XInput()
{
// Try to load the newest XInput***.dll installed on the system
// The delegates below will be loaded dynamically from that dll
dll = Functions.LoadLibrary("XINPUT1_4");
if (dll == IntPtr.Zero)
dll = Functions.LoadLibrary("XINPUT1_3");
if (dll == IntPtr.Zero)
dll = Functions.LoadLibrary("XINPUT1_2");
if (dll == IntPtr.Zero)
dll = Functions.LoadLibrary("XINPUT1_1");
if (dll == IntPtr.Zero)
dll = Functions.LoadLibrary("XINPUT9_1_0");
if (dll == IntPtr.Zero)
throw new NotSupportedException("XInput was not found on this platform");
// Load the entry points we are interested in from that dll
GetCapabilities = (XInputGetCapabilities)Load("XInputGetCapabilities", typeof(XInputGetCapabilities));
GetState = (XInputGetState)Load("XInputGetState", typeof(XInputGetState));
SetState = (XInputSetState)Load("XInputSetState", typeof(XInputSetState));
}
#region Private Members
Delegate Load(string name, Type type)
{
IntPtr pfunc = Functions.GetProcAddress(dll, name);
if (pfunc != IntPtr.Zero)
return Marshal.GetDelegateForFunctionPointer(pfunc, type);
return null;
}
#endregion
#region Internal Members
internal XInputGetCapabilities GetCapabilities;
internal XInputGetState GetState;
internal XInputSetState SetState;
[SuppressUnmanagedCodeSecurity]
internal delegate XInputErrorCode XInputGetCapabilities(
XInputUserIndex dwUserIndex,
XInputCapabilitiesFlags dwFlags,
out XInputDeviceCapabilities pCapabilities);
[SuppressUnmanagedCodeSecurity]
internal delegate XInputErrorCode XInputGetState
(
XInputUserIndex dwUserIndex,
out XInputState pState
);
[SuppressUnmanagedCodeSecurity]
internal delegate XInputErrorCode XInputSetState
(
XInputUserIndex dwUserIndex,
ref XInputVibration pVibration
);
#endregion
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
void Dispose(bool manual)
{
if (manual)
{
if (dll != IntPtr.Zero)
{
Functions.FreeLibrary(dll);
dll = IntPtr.Zero;
}
}
}
#endregion
}
#endregion
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
void Dispose(bool manual)
{
if (manual)
{
xinput.Dispose();
}
else
{
Debug.Print("{0} leaked, did you forget to call Dispose()?", typeof(XInputJoystick).Name);
}
}
#if DEBUG
~XInputJoystick()
{
Dispose(false);
}
#endif
#endregion
}
}

View file

@ -98,6 +98,12 @@ namespace OpenTK.Platform.X11
return new X11Joystick();
}
public virtual OpenTK.Input.IJoystickDriver2 CreateJoystickDriver()
{
return new X11Joystick();
}
#endregion
#region IDisposable Members

View file

@ -36,7 +36,7 @@ namespace OpenTK.Platform.X11
{
struct X11JoyDetails { }
sealed class X11Joystick : IJoystickDriver, IGamePadDriver
sealed class X11Joystick : IJoystickDriver, IJoystickDriver2, IGamePadDriver
{
#region Fields
@ -259,21 +259,47 @@ namespace OpenTK.Platform.X11
#endregion
//HACK implement
public GamePadState GetState()
#region IGamePadDriver Members
public GamePadCapabilities GetCapabilities(int index)
{
throw new NotImplementedException();
return new GamePadCapabilities();
}
public GamePadState GetState(int index)
{
Poll();
throw new NotImplementedException();
return new GamePadState();
}
public string GetDeviceName(int index)
public string GetName(int index)
{
throw new NotImplementedException();
return String.Empty;
}
public bool SetVibration(int index, float left, float right)
{
return false;
}
#endregion
#region IJoystickDriver2 Members
JoystickState IJoystickDriver2.GetState(int index)
{
return new JoystickState();
}
JoystickCapabilities IJoystickDriver2.GetCapabilities(int index)
{
return new JoystickCapabilities();
}
Guid IJoystickDriver2.GetGuid(int index)
{
return new Guid();
}
#endregion
}
}

View file

@ -84,7 +84,7 @@ namespace OpenTK
/// Set to false for applications that are not
/// DPI-aware (e.g. WinForms.)
/// </summary>
/// <seealso cref="http://msdn.microsoft.com/en-us/library/windows/desktop/ee308410(v=vs.85).aspx"/>
/// See: http://msdn.microsoft.com/en-us/library/windows/desktop/ee308410(v=vs.85).aspx
public bool EnableHighResolution { get; set; }
/// <summary>