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

View file

@ -206,8 +206,8 @@ namespace OpenTK
{ {
if (!OpenTK.Platform.SDL2.SDL.WasInit(0)) if (!OpenTK.Platform.SDL2.SDL.WasInit(0))
{ {
var flags = OpenTK.Platform.SDL2.SystemFlags.EVERYTHING; var flags =
flags &= ~OpenTK.Platform.SDL2.SystemFlags.AUDIO; OpenTK.Platform.SDL2.SystemFlags.VIDEO | Platform.SDL2.SystemFlags.TIMER;
if (OpenTK.Platform.SDL2.SDL.Init(flags) == 0) if (OpenTK.Platform.SDL2.SDL.Init(flags) == 0)
{ {
supported = true; 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 #region License
// //
// The Open Toolkit Library License // GamePad.cs
// //
// Copyright (c) 2006 - 2009 the Open Toolkit library. // Author:
// // Stefanos A. <stapostol@gmail.com>
// Permission is hereby granted, free of charge, to any person obtaining a copy //
// of this software and associated documentation files (the "Software"), to deal // Copyright (c) 2006-2014 Stefanos Apostolopoulos
// in the Software without restriction, including without limitation the rights to //
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // Permission is hereby granted, free of charge, to any person obtaining a copy
// the Software, and to permit persons to whom the Software is furnished to do // of this software and associated documentation files (the "Software"), to deal
// so, subject to the following conditions: // in the Software without restriction, including without limitation the rights
// // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// The above copyright notice and this permission notice shall be included in all // copies of the Software, and to permit persons to whom the Software is
// copies or substantial portions of the Software. // furnished to do so, subject to the following conditions:
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // The above copyright notice and this permission notice shall be included in
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // all copies or substantial portions of the Software.
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND //
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// OTHER DEALINGS IN THE SOFTWARE. // 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
#endregion // THE SOFTWARE.
//
#endregion
using System; using System;
namespace OpenTK.Input namespace OpenTK.Input
{ {
/// <summary> /// <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> /// </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. // THE SOFTWARE.
using System; using System;
namespace OpenTK namespace OpenTK.Input
{ {
public enum GamePadAxis [Flags]
{ internal enum GamePadAxes : byte
/// <summary>The first axis of the gamepad.</summary> {
Axis0 = 0, LeftX = 1 << 0,
/// <summary>The second axis of the gamepad.</summary> LeftY = 1 << 1,
Axis1, LeftTrigger = 1 << 2,
/// <summary>The third axis of the gamepad.</summary> RightX = 1 << 3,
Axis2, RightY = 1 << 4,
/// <summary>The fourth axis of the gamepad.</summary> RightTrigger = 1 << 5,
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
}
} }

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 namespace OpenTK.Input
{ {
/// <summary> /// <summary>
/// Encapsulates the state of a GamePad device. /// Describes the current state of a <see cref="GamePad"/> device.
/// </summary> /// </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 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); GamePadState GetState(int index);
GamePadCapabilities GetCapabilities(int index);
/// <summary> /// <summary>
/// Retrieves the device name for the gamepad device. /// Retrieves the device name for the gamepad device.
/// </summary> /// </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> /// <returns>A <see cref="System.String"/> with the name of the specified device or <see cref="System.String.Empty"/>.</returns>
/// <remarks> /// <remarks>
/// <para>If no device exists at the specified index, the return value is <see cref="System.String.Empty"/>.</para></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; } IMouseDriver2 MouseDriver { get; }
IKeyboardDriver2 KeyboardDriver { get; } IKeyboardDriver2 KeyboardDriver { get; }
IGamePadDriver GamePadDriver { 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. // Provides platform-specific information about the relevant JoystickDevice.
internal sealed class JoystickDevice<TDetail> : JoystickDevice internal sealed class JoystickDevice<TDetail> : JoystickDevice
where TDetail : new()
{ {
internal JoystickDevice(int id, int axes, int buttons) internal JoystickDevice(int id, int axes, int buttons)
: base(id, axes, buttons) : base(id, axes, buttons)
{ } { }
internal TDetail Details; internal TDetail Details = new TDetail();
} }
#endregion #endregion
@ -271,49 +272,6 @@ namespace OpenTK.Input
#endregion #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 #region JoystickButtonCollection
/// <summary> /// <summary>
@ -376,37 +334,6 @@ namespace OpenTK.Input
#endregion #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 #region JoystickAxisCollection
/// <summary> /// <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>
<Compile Include="DisplayIndex.cs" /> <Compile Include="DisplayIndex.cs" />
<Compile Include="Graphics\GraphicsModeComparer.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\IGamePadDriver.cs" />
<Compile Include="Input\IInputDriver2.cs" /> <Compile Include="Input\IInputDriver2.cs" />
<Compile Include="Input\IJoystickDriver2.cs" />
<Compile Include="Input\IKeyboardDriver2.cs" /> <Compile Include="Input\IKeyboardDriver2.cs" />
<Compile Include="Input\IMouseDriver2.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="InteropHelper.cs" />
<Compile Include="Math\Matrix2.cs" /> <Compile Include="Math\Matrix2.cs" />
<Compile Include="Math\Matrix2d.cs" /> <Compile Include="Math\Matrix2d.cs" />
@ -154,7 +163,9 @@
<Compile Include="Math\Matrix4x3.cs" /> <Compile Include="Math\Matrix4x3.cs" />
<Compile Include="Math\Matrix4x3d.cs" /> <Compile Include="Math\Matrix4x3d.cs" />
<Compile Include="Platform\DisplayDeviceBase.cs" /> <Compile Include="Platform\DisplayDeviceBase.cs" />
<Compile Include="Platform\MappedGamePadDriver.cs" />
<Compile Include="Platform\Windows\WinInputBase.cs" /> <Compile Include="Platform\Windows\WinInputBase.cs" />
<Compile Include="Platform\Windows\XInputJoystick.cs" />
<Compile Include="ToolkitOptions.cs" /> <Compile Include="ToolkitOptions.cs" />
<Compile Include="WindowBorder.cs"> <Compile Include="WindowBorder.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
@ -738,8 +749,7 @@
</EmbeddedResource> </EmbeddedResource>
<Compile Include="Platform\MacOS\HIDInput.cs" /> <Compile Include="Platform\MacOS\HIDInput.cs" />
<Compile Include="IntPtrEqualityComparer.cs" /> <Compile Include="IntPtrEqualityComparer.cs" />
<Compile Include="Input\GamePadButton.cs" /> <Compile Include="Input\GamePadAxes.cs" />
<Compile Include="Input\GamePadAxis.cs" />
<Compile Include="Platform\SDL2\Sdl2DisplayDeviceDriver.cs" /> <Compile Include="Platform\SDL2\Sdl2DisplayDeviceDriver.cs" />
<Compile Include="Platform\SDL2\Sdl2Factory.cs" /> <Compile Include="Platform\SDL2\Sdl2Factory.cs" />
<Compile Include="Platform\SDL2\Sdl2GraphicsContext.cs" /> <Compile Include="Platform\SDL2\Sdl2GraphicsContext.cs" />
@ -778,6 +788,16 @@
<Compile Include="RewrittenAttribute.cs" /> <Compile Include="RewrittenAttribute.cs" />
<Compile Include="Graphics\OpenGL\GLObsolete.cs" /> <Compile Include="Graphics\OpenGL\GLObsolete.cs" />
<Compile Include="Platform\MacOS\NS.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> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>

View file

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

View file

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

View file

@ -113,5 +113,10 @@ namespace OpenTK.Platform.MacOS
throw new NotImplementedException(); 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. // Requires Mac OS X 10.5 or higher.
// Todo: create a driver for older installations. Maybe use CGGetLastMouseDelta for that? // 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 #region Fields
@ -69,6 +69,8 @@ namespace OpenTK.Platform.MacOS
readonly CFString InputLoopMode = CF.RunLoopModeDefault; readonly CFString InputLoopMode = CF.RunLoopModeDefault;
readonly CFDictionary DeviceTypes = new CFDictionary(); readonly CFDictionary DeviceTypes = new CFDictionary();
readonly MappedGamePadDriver mapped_gamepad = new MappedGamePadDriver();
NativeMethods.IOHIDDeviceCallback HandleDeviceAdded; NativeMethods.IOHIDDeviceCallback HandleDeviceAdded;
NativeMethods.IOHIDDeviceCallback HandleDeviceRemoved; NativeMethods.IOHIDDeviceCallback HandleDeviceRemoved;
NativeMethods.IOHIDValueCallback HandleDeviceValueReceived; NativeMethods.IOHIDValueCallback HandleDeviceValueReceived;
@ -93,7 +95,7 @@ namespace OpenTK.Platform.MacOS
#endregion #endregion
#region Private Members #region Private Members
IOHIDManagerRef CreateHIDManager() IOHIDManagerRef CreateHIDManager()
{ {
@ -291,7 +293,8 @@ namespace OpenTK.Platform.MacOS
public IMouseDriver2 MouseDriver { get { return this; } } public IMouseDriver2 MouseDriver { get { return this; } }
public IKeyboardDriver2 KeyboardDriver { 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 #endregion
@ -366,6 +369,25 @@ namespace OpenTK.Platform.MacOS
#endregion #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 #region NativeMethods
class NativeMethods class NativeMethods

View file

@ -93,6 +93,11 @@ namespace OpenTK.Platform.MacOS
{ {
return InputDriver.GamePadDriver; return InputDriver.GamePadDriver;
} }
public IJoystickDriver2 CreateJoystickDriver()
{
return InputDriver.JoystickDriver;
}
#endregion #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 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// //
using System.Runtime.InteropServices;
#endregion #endregion
@ -118,10 +116,91 @@ namespace OpenTK.Platform.SDL2
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_FreeSurface", ExactSpelling = true)] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_FreeSurface", ExactSpelling = true)]
public static extern void FreeSurface(IntPtr surface); 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] [SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetCurrentDisplayMode", ExactSpelling = true)] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetCurrentDisplayMode", ExactSpelling = true)]
public static extern int GetCurrentDisplayMode(int displayIndex, out DisplayMode mode); 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] [SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetDisplayBounds", ExactSpelling = true)] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetDisplayBounds", ExactSpelling = true)]
public static extern int GetDisplayBounds(int displayIndex, out Rect rect); 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)] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_Init", ExactSpelling = true)]
public static extern int Init(SystemFlags flags); 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] [SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickClose", ExactSpelling = true)] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickClose", ExactSpelling = true)]
public static extern void JoystickClose(IntPtr joystick); 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] [SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickGetAxis", ExactSpelling = true)] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickGetAxis", ExactSpelling = true)]
public static extern short JoystickGetAxis(IntPtr joystick, int axis); 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)] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickGetButton", ExactSpelling = true)]
public static extern byte JoystickGetButton(IntPtr joystick, int button); 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] [SuppressUnmanagedCodeSecurity]
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickName", ExactSpelling = true)] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_JoystickName", ExactSpelling = true)]
static extern IntPtr JoystickNameInternal(IntPtr joystick); static extern IntPtr JoystickNameInternal(IntPtr joystick);
@ -462,6 +562,13 @@ namespace OpenTK.Platform.SDL2
ES = 0x0004 ES = 0x0004
} }
enum EventState
{
Query = -1,
Ignore = 0,
Enable = 1
}
enum EventType enum EventType
{ {
FIRSTEVENT = 0, FIRSTEVENT = 0,
@ -501,6 +608,61 @@ namespace OpenTK.Platform.SDL2
LASTEVENT = 0xFFFF 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 enum Keycode
{ {
UNKNOWN = 0, UNKNOWN = 0,
@ -1080,6 +1242,41 @@ namespace OpenTK.Platform.SDL2
#region Structs #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 struct DisplayMode
{ {
public uint Format; public uint Format;
@ -1110,21 +1307,21 @@ namespace OpenTK.Platform.SDL2
public MouseWheelEvent Wheel; public MouseWheelEvent Wheel;
[FieldOffset(0)] [FieldOffset(0)]
public JoyAxisEvent JoyAxis; 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 #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)] [FieldOffset(0)]
public QuitEvent quit; public QuitEvent quit;
[FieldOffset(0)] [FieldOffset(0)]
@ -1142,6 +1339,21 @@ namespace OpenTK.Platform.SDL2
#endif #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 struct JoyAxisEvent
{ {
public EventType Type; public EventType Type;
@ -1155,6 +1367,68 @@ namespace OpenTK.Platform.SDL2
UInt16 padding4; 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 struct KeyboardEvent
{ {
public EventType Type; public EventType Type;

View file

@ -34,7 +34,7 @@ namespace OpenTK.Platform.SDL2
{ {
class Sdl2Factory : IPlatformFactory class Sdl2Factory : IPlatformFactory
{ {
readonly IInputDriver2 InputDriver = new Sdl2InputDriver(); readonly Sdl2InputDriver InputDriver = new Sdl2InputDriver();
bool disposed; bool disposed;
/// <summary> /// <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) 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() public IDisplayDeviceDriver CreateDisplayDeviceDriver()
@ -104,6 +104,11 @@ namespace OpenTK.Platform.SDL2
return InputDriver.GamePadDriver; return InputDriver.GamePadDriver;
} }
public IJoystickDriver2 CreateJoystickDriver()
{
return InputDriver.JoystickDriver;
}
#endregion #endregion
#region IDisposable Members #region IDisposable Members

View file

@ -55,10 +55,21 @@ namespace OpenTK.Platform.SDL2
{ {
lock (SDL.Sync) lock (SDL.Sync)
{ {
SDL.GameControllerEventState(EventState.Enable);
SDL.JoystickEventState(EventState.Enable);
EventFilterDelegate = Marshal.GetFunctionPointerForDelegate(EventFilterDelegate_GCUnsafe); EventFilterDelegate = Marshal.GetFunctionPointerForDelegate(EventFilterDelegate_GCUnsafe);
driver_handle = new IntPtr(count++); driver_handle = new IntPtr(count++);
DriverHandles.Add(driver_handle, this); DriverHandles.Add(driver_handle, this);
SDL.AddEventWatch(EventFilterDelegate, driver_handle); 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: case EventType.MOUSEWHEEL:
driver.mouse_driver.ProcessWheelEvent(ev.Wheel); driver.mouse_driver.ProcessWheelEvent(ev.Wheel);
break; 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 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 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 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 HatCount { get; set; }
public int BallCount { 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; 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() public Sdl2JoystickDriver()
{ {
joysticks_readonly = joysticks.AsReadOnly(); joysticks_readonly = joysticks.AsReadOnly();
RefreshJoysticks();
} }
#region Private Members #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(); IntPtr handle = SDL.JoystickOpen(id);
for (int i = 0; i < count; i++) if (handle != IntPtr.Zero)
{ {
JoystickDevice<Sdl2JoystickDetails> joystick = null; num_axes = SDL.JoystickNumAxes(handle);
int num_axes = 0; num_buttons = SDL.JoystickNumButtons(handle);
int num_buttons = 0; num_hats = SDL.JoystickNumHats(handle);
int num_hats = 0; num_balls = SDL.JoystickNumBalls(handle);
int num_balls = 0;
IntPtr handle = SDL.JoystickOpen(i); joystick = new JoystickDevice<Sdl2JoystickDetails>(id, num_axes, num_buttons);
if (handle != IntPtr.Zero) joystick.Description = SDL.JoystickName(handle);
{ joystick.Details.Handle = handle;
num_axes = SDL.JoystickNumAxes(handle); joystick.Details.Guid = SDL.JoystickGetGUID(handle).ToGuid();
num_buttons = SDL.JoystickNumButtons(handle); joystick.Details.HatCount = num_hats;
num_hats = SDL.JoystickNumHats(handle); joystick.Details.BallCount = num_balls;
num_balls = SDL.JoystickNumBalls(handle);
joystick = new JoystickDevice<Sdl2JoystickDetails>(i, num_axes, num_buttons); Debug.Print("[SDL2] Joystick device {0} opened successfully. ", id);
joystick.Description = SDL.JoystickName(handle); Debug.Print("\t\t'{0}' has {1} axes, {2} buttons, {3} hats, {4} balls",
joystick.Details.Handle = handle; joystick.Description, joystick.Axis.Count, joystick.Button.Count,
joystick.Details.HatCount = num_hats; joystick.Details.HatCount, joystick.Details.BallCount);
joystick.Details.BallCount = num_balls; }
joysticks.Add(joystick); 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 #endregion
#region IJoystickDriver Members #region IJoystickDriver Members
@ -101,49 +522,114 @@ namespace OpenTK.Platform.SDL2
public void Poll() public void Poll()
{ {
SDL.JoystickUpdate(); // Do nothing
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);
}
}
} }
#endregion #endregion
#region IGamePadDriver Members #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) public GamePadState GetState(int index)
{ {
if (joysticks.Count >= index) if (IsControllerValid(index))
{ {
return controllers[index].State;
} }
return new GamePadState(); return new GamePadState();
} }
public string GetDeviceName(int index) public string GetName(int index)
{ {
return String.Empty; 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 #endregion

View file

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

View file

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

View file

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

View file

@ -36,7 +36,7 @@ using System.Diagnostics;
namespace OpenTK.Platform.Windows namespace OpenTK.Platform.Windows
{ {
sealed class WinMMJoystick : IJoystickDriver, IGamePadDriver sealed class WinMMJoystick : IJoystickDriver, IJoystickDriver2
{ {
#region Fields #region Fields
@ -133,6 +133,27 @@ namespace OpenTK.Platform.Windows
return stick; 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 #endregion
#region IJoystickDriver #region IJoystickDriver
@ -237,6 +258,95 @@ namespace OpenTK.Platform.Windows
#endregion #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 #region IDisposable
public void Dispose() public void Dispose()
@ -378,9 +488,11 @@ namespace OpenTK.Platform.Windows
[DllImport("Winmm.dll"), SuppressUnmanagedCodeSecurity] [DllImport("Winmm.dll"), SuppressUnmanagedCodeSecurity]
public static extern JoystickError joyGetDevCaps(int uJoyID, out JoyCaps pjc, int cbjc); public static extern JoystickError joyGetDevCaps(int uJoyID, out JoyCaps pjc, int cbjc);
[DllImport("Winmm.dll"), SuppressUnmanagedCodeSecurity] [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] [DllImport("Winmm.dll"), SuppressUnmanagedCodeSecurity]
public static extern int joyGetNumDevs(); public static extern int joyGetNumDevs();
[DllImport("Winmm.dll"), SuppressUnmanagedCodeSecurity]
public static extern JoystickError joyConfigChanged(int flags);
} }
#endregion #endregion
@ -427,21 +539,5 @@ namespace OpenTK.Platform.Windows
} }
#endregion #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; WinRawKeyboard keyboard_driver;
WinRawMouse mouse_driver; WinRawMouse mouse_driver;
WinMMJoystick joystick_driver; IGamePadDriver gamepad_driver;
IJoystickDriver2 joystick_driver;
IntPtr DevNotifyHandle; IntPtr DevNotifyHandle;
static readonly Guid DeviceInterfaceHid = new Guid("4D1E55B2-F16F-11CF-88CB-001111000030"); 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); keyboard_driver = new WinRawKeyboard(Parent.Handle);
mouse_driver = new WinRawMouse(Parent.Handle); mouse_driver = new WinRawMouse(Parent.Handle);
joystick_driver = new WinMMJoystick(); 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); DevNotifyHandle = RegisterForDeviceNotifications(Parent);
} }
@ -186,6 +196,11 @@ namespace OpenTK.Platform.Windows
} }
public override IGamePadDriver GamePadDriver public override IGamePadDriver GamePadDriver
{
get { return gamepad_driver; }
}
public override IJoystickDriver2 JoystickDriver
{ {
get { return joystick_driver; } 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(); return new X11Joystick();
} }
public virtual OpenTK.Input.IJoystickDriver2 CreateJoystickDriver()
{
return new X11Joystick();
}
#endregion #endregion
#region IDisposable Members #region IDisposable Members

View file

@ -36,7 +36,7 @@ namespace OpenTK.Platform.X11
{ {
struct X11JoyDetails { } struct X11JoyDetails { }
sealed class X11Joystick : IJoystickDriver, IGamePadDriver sealed class X11Joystick : IJoystickDriver, IJoystickDriver2, IGamePadDriver
{ {
#region Fields #region Fields
@ -259,21 +259,47 @@ namespace OpenTK.Platform.X11
#endregion #endregion
//HACK implement #region IGamePadDriver Members
public GamePadState GetState()
public GamePadCapabilities GetCapabilities(int index)
{ {
throw new NotImplementedException(); return new GamePadCapabilities();
} }
public GamePadState GetState(int index) public GamePadState GetState(int index)
{ {
Poll(); return new GamePadState();
throw new NotImplementedException();
} }
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 /// Set to false for applications that are not
/// DPI-aware (e.g. WinForms.) /// DPI-aware (e.g. WinForms.)
/// </summary> /// </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; } public bool EnableHighResolution { get; set; }
/// <summary> /// <summary>