the Fiddler's picture

[Input] Add static classes for Mouse, Keyboard and GamePad input

Project:The Open Toolkit library

These classes should be independent of the GameWindow and usable on their own. Proposed API:

MouseState OpenTK.Input.Mouse.GetState(int index);
KeyboardState OpenTK.Input.Keyboard.GetState(int index);
GamePadState OpenTK.Input.GamePad.GetState(int index);

[Mouse|Keyboard|GamePad]State are structs that encapsulate the state vector of the relevant device at the time when GetState was called. 'Index' is an optional parameter that specifies which device is queried, when multiple devices are connected to the computer. It is not an error to query a device index for a non-existent device: in that case, the state vector will indicate IsConnected = false.

Device indices may not after application startup. For example, if the computer has 3 devices (0, 1, 2) and device 1 is disconnected, the indices of the other devices may not change: they shall remain (0, 2).


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture


New APIs implementated:

Keyboard.GetDeviceName(int index)
Mouse.GetDeviceName(int index)

I have never seen a worse designed API than XInput1. Good APIs make simple things easy and hard things possible. XInput1 is the first API I've seen that moves everything right into impossible. Relative mouse motion? No can do. Tracking mouse and keyboard outside a window? Only a single application at a time (woe to yourself if you try to use a debugger while the keyboard is grabbed). Delivering input events to two windows at the same time? He, he, he.

Now I can understand why wine never managed to emulate mouse input correctly. It's simply impossible.

Yeah, I'm going to add XInput2 keyboards. I will probably make them the only option, too, if they work. Too bad they require an XServer from 2010.

the Fiddler's picture


To add insult to injury, distros lock you out of the kernel input interfaces and force you to go through the culster-f that is XInput1.

Can it really be that there are no X extensions to fix this madness?

jdomnitz's picture


I have a link for you but the spam filter on this site is blocking every post I try to make.....

the Fiddler's picture


PM please!

Inertia's picture


Status of joystick APIs under windows: DirectInput8 is discontinued and XInput is it's successor.

DirectInput8 plays nicely with flightsticks, racing wheels, gamepads, etc. and supports force feedback for those devices. Microsoft's xbox 360 gamepad is the exception, it only works partially with DirectInput: The trigger buttons will not work correctly, no force feedback and no support for the microphone.

XInput is designed around the xbox 360 gamepad. Force Feedback, Microphone and all buttons/axes will work. But only for the 360 gamepad. No other tested gamepad works with it out of the box. (axes and buttons mapped horribly wrong, although perfectly calibrated in the system settings)

(short break here for laughter to calm down and to stop shaking heads in disbelief)

There exist 2 emulator projects that deal with this:
-XBCD allows xbox 360 gamepads to work with DirectInput8 games.
-X360CE allows all other joysticks to work with XInput games.

This is far from perfect, but may help in the decision where to go to when looking into force feedback support. The way I understand it, all "old" gamepads only lack a proper XInput driver. XInput is way cleaner API than DirectInput8 and will certainly stay maintained. XInput will likely be the better long-term choice if there has to be a decision between them.

jdomnitz's picture


Is there any way to detect which works correctly with XInput and which works correctly with DirectInput?

Inertia's picture


According to MSDN, DirectInput Device ID looks like this:

XInput DEvice ID looks like this:

AFAIK this is the closest you can get to knowing which API to use with which device, without creating a database and enter every single device on the market manually.

The best solution would be an XInput driver, that reroutes all commands to DirectInput8. So everyone could simply accept XInput. But Microsoft obviously wants to sell 360 gamepads....

jdomnitz's picture


Any chance openTK could auto-switch depending on the device id?

the Fiddler's picture


Ok, this is a royal mess. Here is some example code to detect XInput devices (isXInput method), which more or less checks for the presence of "&IG_".

I think the most sane approach is to go with the path of least resistance: add an XInput driver and fallback to the current WinMM implementation for non-XInput devices. Once that is working we can look into DirectInput if necessary.

jdomnitz's picture


Bug in the windows raw input implementation:

If a device is plugged in while opentk is running the RefreshDevices routine the GetDeviceName function can sometimes return an empty string triggering an exception in the FindRegistryKey function.