Search code examples
javavirtualdirectinputgamepadxinput

Java Virtual Gamepad


Problem I am developing a custom hardware controller and I would like to map its input to an virtual XInput controller after processecing it in Java. Essentially for all intents and purposes, I want to controll an XInput controller directly from java.

Solutions I have thought of

  • Writing a device driver, this seems like a real pain in the ass that I would gladly avoid. I have never written a device driver before nor do I have any idea how to register an XInput controller. It seems like this will take a very long time to do, time I don't have nor want to spend.
  • Using PPJoy and this library. I would like to avoid this as PPJoy is very dated (over 10 years since last update I could find) and would require an additional layer to convert DirectInput to XInput. The library also refuses to compile for me.
  • Develop a wrapper for VJoy. That would however require a remap from DirectInput to XInput. I am not familiar with C/C++ wrapping but so far this seems like the best alternative.

Does anyone have a good idea how to solve this problem? I have considered skipping XInput and do it with keyboard/mouse using Robot (AWT) but games refuse to pick up the software input, most likely they only read hardware data. Emulating keyboard/mouse would be fine but not optimal as it would be rather awkward, I am not however able to find a way to do it in a way that games recognize. All help appreciated!


Solution

  • Write a wrapper, you won't need to know any, I repeat any C++ code, if you really don't want to. Simply use swig. There are plenty of examples, start with something basic. (Note I am not going to include example because there is already enough stuff out there). If you have trouble leave a comment, and I'll help you out.

    EDIT Ok I'll be nice, quick example, say you have a example.h file, create a example.i in the same location with:

    %module example
    
    %{
    #include "example.h"
    %}
    
    %include "example.h"
    

    Make sure swig is in your path then do:

    %swig -java example.i
    

    Then you need to build a native java library, such as how it's done here, (note you don't need to do all the javah stuff), but basically:

    % g++ -Wl,--add-stdcall-alias -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" 
      -shared -o example.dll example.c example.cpp
    

    Which gives you your dll, which you will have to stick in your path with any other dependent libararies when running your java program. Note if you compile a 32 bit library you need to use a 32 bit jvm.