Reputation: 1509
How would I go about creating a "gamepad" which appears to DirectInput applications as a normal game controller but the state of its controls is actually defined by software?
Upvotes: 15
Views: 39001
Reputation: 682
The simplest solution I found was using vJoy and its C# wrapper. You need to download the vJoy driver from here.
You can use the vJoy SDK for implementing a feeder program: https://github.com/njz3/vJoy/tree/master/SDK/c%23
Use the C# starter project for this, or simply add the two .dll
-s to your existing project as references from the x86 or x64 folder.
You can find instructions on how to use the api in the readme.odt file.
Upvotes: 1
Reputation: 614
I know it is an old question but for anyone which is interested in this topic it is also worth looking at this project called ViGEm.
You can emulate some well known gamepads like Microsoft Xbox 360 Controller, Sony DualShock 4 Controller and Microsoft Xbox One Controller. The project offers also some API to interact with these virtual controllers. E.g. the C# API can be found here
Upvotes: 6
Reputation: 944
The easiest solution may be to emulate an XInput device (Xbox 360 and One). These are supported in most modern games and the set up is very simple. Here is a C++ project here that provides this without any installed drivers or external dependencies: https://github.com/shauleiz/vXboxInterface/
Upvotes: 5
Reputation:
There is vJoy opensource project: http://sourceforge.net/projects/vjoystick/ - can be worth looking at.
Upvotes: 6
Reputation:
Write a device driver to pretend to be one.
Specifically, Windows device drivers handle what are called Interrupt Requests via the Interrupt Request Protocol - which boils down to a wrapped up structure and a set of buffers internally in the driver.
Now the next thing you need to know is that many drivers are actually layered, or stacked, or whichever name you want to use. So for example to write a disk driver, you might interface with the driver above it (as a disk class) but use a driver below it (scsi port, for example) to actually send commands to your devices.
That's how real devices work. Fake devices need to conform to the top level interface requirements, e.g. a disk, or a controller, or a mouse, or whatever it is. However, underneath they can do anything they like - return whatever values they like.
This opens up the possibility of controlling a driver via a user-mode application and pretending to "be" a device. To send a driver messages, you can DeviceIoControl
to it; then to actually get those messages you can either:
Drivers can also access \\Registry\\Machine
and various other, non-user-specific non-explorer registry areas, so it is possible to communicate that way.
Finally, there's no saying you can't filter existing IO, rather than make it all up via a new device. There are a great many options and ways you can go about doing this.
If you're going to do this, you'll need:
You probably also want to start with the references on this blog post. You'll find that there are essentially a bazillion different names for driver code, so I'll interpret some of them:
Edit: I'm not massively knowledgeable on DirectInput - there may be a way to override the various API controls in use via DLL redirection and the like, which may be simpler than the way I've described.
Upvotes: 15