I got DirectInput working with SharpDX in MonoGame! @StainlessTobii and @MuntyScruntFundle, if you want to try this out, I recommend MonoGame 3.7.1 or newer, as I’ve only tested on 3.7.1 and 3.8.
-Open Visual Studio (I used the 2017 version) and your existing MonoGame Windows Project, or make a new one.
-Make sure you’re connected to the Internet, then go to Tools>NuGet Package Manager>Package Manager Console. The console will appear at the bottom of your VS window, replacing Output/Build/Debug.
-If you’re using a MonoGame Shared Project, make sure the console’s “Default project” is your WindowsDX project.
-Paste the following into the console and press Enter:
Install-Package SharpDX.DirectInput -Version 4.0.1
-You now have DInput! You can use the following complete code to test it out. I named my project DInputTest:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SharpDX.DirectInput;
using System;
using Keyboard = Microsoft.Xna.Framework.Input.Keyboard;
using Mouse = Microsoft.Xna.Framework.Input.Mouse;
namespace DInputTest
{
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//DirectInput vars, partially copied from online sources
DirectInput directInput = new DirectInput(); // Initialize DirectInput
Guid gamepadGuid = Guid.Empty, joystickGuid = Guid.Empty; //there may be DInput gamepads out there (Logitech Dual Action Gamepad?), let's test for them
SharpDX.DirectInput.Joystick joystick;
bool noDInputsConnected = false, pressed = false;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
DInputChecker(); //this can be called from Update() as well whenever the user may have plugged in a new joystick, maybe good for the Options menu
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
if (!noDInputsConnected)
{
try
{
joystick.Poll(); //ask the joystick for input
var state = joystick.GetCurrentState(); //return the state of all buttons, axes, etc.
if(state.Buttons[0]) pressed = true; else pressed = false;
}
catch {} //catches any odd SharpDX errors
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
//Simple way to demonstrate that the joystick is connected without SpriteFonts:
if(!pressed)
GraphicsDevice.Clear(Color.CornflowerBlue); //standard blue background means Button 0 is not being pressed
else
GraphicsDevice.Clear(Color.Yellow); //light up to show that Button 0 has been read and is being pressed!
base.Draw(gameTime);
}
private void DInputChecker()
{
foreach (var deviceInstance in directInput.GetDevices(DeviceType.Gamepad, DeviceEnumerationFlags.AllDevices)) //look for connected DInput gamepads
gamepadGuid = deviceInstance.InstanceGuid;
foreach (var deviceInstance in directInput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AllDevices)) //if, or even if none found, look for DInput joysticks
joystickGuid = deviceInstance.InstanceGuid;
if (gamepadGuid != Guid.Empty || joystickGuid != Guid.Empty)
{
noDInputsConnected = false;
joystick = new SharpDX.DirectInput.Joystick(directInput, joystickGuid);
joystick.Properties.BufferSize = 128; //allocate a buffer to hold the device's state
joystick.Acquire(); //do this for every joystick that's plugged in, the user may have multiple joysticks plugged in
}
else
noDInputsConnected = true; //if this variable did not exist, the game would crash when 0 joysticks are connected
}
}
}
Of course, this is just an example and you’ll want to check if more than one joystick is connected in a real game.
Two other caveats I’m aware of, one of which is fixed in the code at lines 6 & 7:
- Adding SharpDX.DirectInput creates ambiguity between i.e. “Microsoft.Xna.Framework.Input.Keyboard” and “SharpDX.DirectInput.Keyboard”. I recommend including those
usingstatements at the top to associate Keyboard and Mouse only with XNA’s handling. - On 3.7.1 at least, this reference can add several seconds to the game’s startup time compared to not using SharpDX.DirectInput in the project. On my mid-range PC from 2015, it adds about 5 seconds of Windows’ spinning cursor before the game opens.