No gamepads found

Hi All

I’ve written a small game, very much still in the prototype phase - here is the code. I am having trouble with the detection of gamepads though.

Using the TestJoystick project that comes with jmonkeyengine has the same issue - both my code and the test code cannot detect gamepads plugged into my computer.

I’d appreciate any tips for troubleshooting this issue! I was using jmonkeyengine 3, but moving to jmonkeyengine 3.1 beta 1 didn’t solve the issue. I am running windows 10.

edit: dimension drifter forum link works with a gamepad on my pc. Hmmmm.

In your app, you don’t seem to turn on joysticks in the app settings.

(Could have saved me a few clicks by just pasting it here… but whatever.)

Sorry about that - but its a bunch of code… But on line 53 in UserSettings.Java I do turn it on :

settings.setUseJoysticks(true);

Besides the testjoystick test app has the same issue :confused:

I found this post about Jinput, which I gather is the library jmonkeyengine uses for joysticks and stuff. I downloaded the linked zip file which contained a jar with a program that should show the joysticks detected by Jinput - running it gives me the same issue! Now I have something to go on - java.lang.UnsatisfiedLinkError: no jinput-dx8_64 in java.library.path looks pretty suspicious.

Microsoft Windows [Version 10.0.10240]
(c) 2015 Microsoft Corporation. All rights reserved.

C:\Users\Jacob>"c:\Program Files\jmonkeyplatform3.1beta1\jdk\bin\java.exe" -jar
"c:\Users\Jacob\Downloads\JInputJoystickTestV2\dist\JInputJoystickTestV2.jar"
Oct 09, 2015 10:48:56 AM net.java.games.input.DefaultControllerEnvironment getControllers
WARNING: Found unknown Windows version: Windows 8.1
Oct 09, 2015 10:48:56 AM net.java.games.input.DefaultControllerEnvironment getControllers
WARNING: Attempting to use default windows plug-in.
java.lang.UnsatisfiedLinkError: no jinput-dx8_64 in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865)
        at java.lang.Runtime.loadLibrary0(Runtime.java:870)
        at java.lang.System.loadLibrary(System.java:1122)
        at net.java.games.input.DirectInputEnvironmentPlugin$1.run(DirectInputEnvironmentPlugin.java:75)
        at java.security.AccessController.doPrivileged(Native Method)
        at net.java.games.input.DirectInputEnvironmentPlugin.loadLibrary(DirectInputEnvironmentPlugin.java:67)
        at net.java.games.input.DirectInputEnvironmentPlugin.<clinit>(DirectInputEnvironmentPlugin.java:109)
        at net.java.games.input.DirectAndRawInputEnvironmentPlugin.<init>(DirectAndRawInputEnvironmentPlugin.java:45)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
        at java.lang.Class.newInstance(Class.java:442)
        at net.java.games.input.DefaultControllerEnvironment.getControllers(DefaultControllerEnvironment.java:160)
        at jinputjoysticktestv2.JoystickTest.searchForControllers(JoystickTest.java:63)
        at jinputjoysticktestv2.JoystickTest.<init>(JoystickTest.java:49)
        at jinputjoysticktestv2.JoystickTest.main(JoystickTest.java:38)
java.lang.UnsatisfiedLinkError: no jinput-raw_64 in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865)
        at java.lang.Runtime.loadLibrary0(Runtime.java:870)
        at java.lang.System.loadLibrary(System.java:1122)
        at net.java.games.input.RawInputEnvironmentPlugin$1.run(RawInputEnvironmentPlugin.java:75)
        at java.security.AccessController.doPrivileged(Native Method)
        at net.java.games.input.RawInputEnvironmentPlugin.loadLibrary(RawInputEnvironmentPlugin.java:67)
        at net.java.games.input.RawInputEnvironmentPlugin.<clinit>(RawInputEnvironmentPlugin.java:109)
        at net.java.games.input.DirectAndRawInputEnvironmentPlugin.<init>(DirectAndRawInputEnvironmentPlugin.java:46)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
        at java.lang.Class.newInstance(Class.java:442)
        at net.java.games.input.DefaultControllerEnvironment.getControllers(DefaultControllerEnvironment.java:160)
        at jinputjoysticktestv2.JoystickTest.searchForControllers(JoystickTest.java:63)
        at jinputjoysticktestv2.JoystickTest.<init>(JoystickTest.java:49)
        at jinputjoysticktestv2.JoystickTest.main(JoystickTest.java:38)
Oct 09, 2015 10:48:56 AM net.java.games.input.ControllerEnvironment log
INFO: net.java.games.input.DirectAndRawInputEnvironmentPlugin is not supported


C:\Users\Jacob>

Maybe you can post your output from TestJoystick since I don’t think we’ve seen that or any previous errors you got.

Sure, there doesn’t seem to be anything interesting in it - but I could be mistaken:

ant -f "C:\\Users\\Jacob\\Documents\\jMonkeyEngine Projects\\JmeTests3.1b1" -Dnb.internal.action.name=run run
init:
Deleting: C:\Users\Jacob\Documents\jMonkeyEngine Projects\JmeTests3.1b1\build\built-jar.properties
deps-jar:
Updating property file: C:\Users\Jacob\Documents\jMonkeyEngine Projects\JmeTests3.1b1\build\built-jar.properties
compile:
run:
Oct 09, 2015 11:21:25 AM java.util.prefs.WindowsPreferences <init>
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
Oct 09, 2015 11:21:28 AM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.1-alpha1
 * Branch: master
 * Git Hash: c5c893f
 * Build Date: 2015-08-17
Oct 09, 2015 11:21:28 AM com.jme3.system.lwjgl.LwjglContext printContextInitInfo
INFO: LWJGL 2.9.3 context running on thread jME3 Main
 * Graphics Adapter: nvd3dumx,nvwgf2umx,nvwgf2umx,nvwgf2umx
 * Driver Version: 10.18.13.5598
 * Scaling Factor: 1
Oct 09, 2015 11:21:28 AM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: NVIDIA Corporation
 * Renderer: GeForce GTX 960/PCIe/SSE2
 * OpenGL Version: 4.5.0 NVIDIA 355.98
 * GLSL Version: 4.50 NVIDIA
 * Profile: Compatibility
Oct 09, 2015 11:21:28 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Device: OpenAL Soft
Oct 09, 2015 11:21:28 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Vendor: OpenAL Community
Oct 09, 2015 11:21:28 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Renderer: OpenAL Soft
Oct 09, 2015 11:21:28 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Version: 1.1 ALSOFT 1.15.1
Oct 09, 2015 11:21:28 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: ALC extensions: ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX ALC_EXT_thread_local_context ALC_SOFT_loopback
Oct 09, 2015 11:21:28 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: AL extensions: AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFTX_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_source_latency
Oct 09, 2015 11:21:28 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: AudioRenderer supports 64 channels
Oct 09, 2015 11:21:28 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
WARNING: Pausing audio device not supported.
Oct 09, 2015 11:21:28 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio effect extension version: 1.0
Oct 09, 2015 11:21:28 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio max auxilary sends: 4
Oct 09, 2015 11:21:28 AM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,6,main]
java.lang.IllegalStateException: Cannot find any joysticks!
	at jme3test.input.TestJoystick.simpleInitApp(TestJoystick.java:49)
	at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:227)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:131)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:212)
	at java.lang.Thread.run(Thread.java:745)

BUILD SUCCESSFUL (total time: 13 seconds)

I added

    ControllerEnvironment ce = ControllerEnvironment.getDefaultEnvironment();
    Controller[] cs = ce.getControllers();
    System.out.println("cs length " + cs.length);

to the simpleInitApp method in the TestJoystick.java class:

package jme3test.input;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.input.Joystick;
import com.jme3.input.JoystickAxis;
import com.jme3.input.JoystickButton;
import com.jme3.input.RawInputListener;
import com.jme3.input.event.JoyAxisEvent;
import com.jme3.input.event.JoyButtonEvent;
import com.jme3.input.event.KeyInputEvent;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector2f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Quad;
import com.jme3.system.AppSettings;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import net.java.games.input.Controller;
import net.java.games.input.ControllerEnvironment;

public class TestJoystick extends SimpleApplication {

    private Joystick viewedJoystick;
    private GamepadView gamepad;
    private Node joystickInfo;
    private float yInfo = 0;

    public static void main(String[] args){
        TestJoystick app = new TestJoystick();
        AppSettings settings = new AppSettings(true);
        settings.setUseJoysticks(true);
        app.setSettings(settings);
        app.start();
    }
    
    @Override
    public void simpleInitApp() {
        
        ControllerEnvironment ce = ControllerEnvironment.getDefaultEnvironment();
        Controller[] cs = ce.getControllers();
        System.out.println("cs length " + cs.length);
        
        Joystick[] joysticks = inputManager.getJoysticks();
        if (joysticks == null)
            throw new IllegalStateException("Cannot find any joysticks!");

        try {
            PrintWriter out = new PrintWriter( new FileWriter( "joysticks-" + System.currentTimeMillis() + ".txt" ) );
            dumpJoysticks( joysticks, out );
            out.close();
        } catch( IOException e ) {
            throw new RuntimeException( "Error writing joystick dump", e );
        }

 
        int gamepadSize = cam.getHeight() / 2;
        float scale = gamepadSize / 512.0f;        
        gamepad = new GamepadView();       
        gamepad.setLocalTranslation( cam.getWidth() - gamepadSize - (scale * 20), 0, 0 );
        gamepad.setLocalScale( scale, scale, scale ); 
        guiNode.attachChild(gamepad); 

        joystickInfo = new Node( "joystickInfo" );
        joystickInfo.setLocalTranslation( 0, cam.getHeight(), 0 );
        guiNode.attachChild( joystickInfo );

        // Add a raw listener because it's eisier to get all joystick events
        // this way.
        inputManager.addRawInputListener( new JoystickEventListener() );
    }

    protected void dumpJoysticks( Joystick[] joysticks, PrintWriter out ) {
        for( Joystick j : joysticks ) {
            out.println( "Joystick[" + j.getJoyId() + "]:" + j.getName() );
            out.println( "  buttons:" + j.getButtonCount() );
            for( JoystickButton b : j.getButtons() ) {
                out.println( "   " + b );
            }
            
            out.println( "  axes:" + j.getAxisCount() );
            for( JoystickAxis axis : j.getAxes() ) {
                out.println( "   " + axis );
            }
        }
    }

    protected void addInfo( String info, int column ) {
    
        BitmapText t = new BitmapText(guiFont);
        t.setText( info );
        t.setLocalTranslation( column * 200, yInfo, 0 );
        joystickInfo.attachChild(t);
        yInfo -= t.getHeight();
    }

    protected void setViewedJoystick( Joystick stick ) {
        if( this.viewedJoystick == stick )
            return;
 
        if( this.viewedJoystick != null ) {
            joystickInfo.detachAllChildren();
        }
                   
        this.viewedJoystick = stick;
 
        if( this.viewedJoystick != null ) {       
            // Draw the hud
            yInfo = 0;
 
            addInfo(  "Joystick:\"" + stick.getName() + "\"  id:" + stick.getJoyId(), 0 );
 
            yInfo -= 5;
                       
            float ySave = yInfo;
            
            // Column one for the buttons
            addInfo( "Buttons:", 0 );
            for( JoystickButton b : stick.getButtons() ) {
                addInfo( " '" + b.getName() + "' id:'" + b.getLogicalId() + "'", 0 );
            }
            yInfo = ySave;
            
            // Column two for the axes
            addInfo( "Axes:", 1 );
            for( JoystickAxis a : stick.getAxes() ) {
                addInfo( " '" + a.getName() + "' id:'" + a.getLogicalId() + "' analog:" + a.isAnalog(), 1 );
            }
            
        } 
    }
 
    /**
     *  Easier to watch for all button and axis events with a raw input listener.
     */   
    protected class JoystickEventListener implements RawInputListener {

        public void onJoyAxisEvent(JoyAxisEvent evt) {
            setViewedJoystick( evt.getAxis().getJoystick() );
            gamepad.setAxisValue( evt.getAxis(), evt.getValue() ); 
        }

        public void onJoyButtonEvent(JoyButtonEvent evt) {
            setViewedJoystick( evt.getButton().getJoystick() );
            gamepad.setButtonValue( evt.getButton(), evt.isPressed() ); 
        }

        public void beginInput() {}
        public void endInput() {}
        public void onMouseMotionEvent(MouseMotionEvent evt) {}
        public void onMouseButtonEvent(MouseButtonEvent evt) {}
        public void onKeyEvent(KeyInputEvent evt) {}
        public void onTouchEvent(TouchEvent evt) {}        
    }

    protected class GamepadView extends Node {
    
        float xAxis = 0;
        float yAxis = 0;
        float zAxis = 0;
        float zRotation = 0;
        
        float lastPovX = 0;
        float lastPovY = 0;
 
        Geometry leftStick;
        Geometry rightStick;
            
        Map<String, ButtonView> buttons = new HashMap<String, ButtonView>();
    
        public GamepadView() {
            super( "gamepad" );
 
            // Sizes naturally for the texture size.  All positions will
            // be in that space because it's easier.
            int size = 512;
 
            Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
            m.setTexture( "ColorMap", assetManager.loadTexture( "Interface/Joystick/gamepad-buttons.png" ) );
            m.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); 
            Geometry buttonPanel = new Geometry( "buttons", new Quad(size, size) );
            buttonPanel.setLocalTranslation( 0, 0, -1 );
            buttonPanel.setMaterial(m);
            attachChild(buttonPanel);
        
            m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
            m.setTexture( "ColorMap", assetManager.loadTexture( "Interface/Joystick/gamepad-frame.png" ) );
            m.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); 
            Geometry frame = new Geometry( "frame", new Quad(size, size) );
            frame.setMaterial(m);
            attachChild(frame);
            
            m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
            m.setTexture( "ColorMap", assetManager.loadTexture( "Interface/Joystick/gamepad-stick.png" ) );
            m.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); 
            leftStick = new Geometry( "leftStick", new Quad(64, 64) );
            leftStick.setMaterial(m);
            attachChild(leftStick);
            rightStick = new Geometry( "leftStick", new Quad(64, 64) );
            rightStick.setMaterial(m);
            attachChild(rightStick);

            // A "standard" mapping... fits a majority of my game pads
            addButton( JoystickButton.BUTTON_0, 371, 512 - 176, 42, 42 );
            addButton( JoystickButton.BUTTON_1, 407, 512 - 212, 42, 42 );
            addButton( JoystickButton.BUTTON_2, 371, 512 - 248, 42, 42 );
            addButton( JoystickButton.BUTTON_3, 334, 512 - 212, 42, 42 );
 
            // Front buttons  Some of these have the top ones and the bottoms ones flipped.           
            addButton( JoystickButton.BUTTON_4, 67, 512 - 111, 95, 21 );
            addButton( JoystickButton.BUTTON_5, 348, 512 - 111, 95, 21 );
            addButton( JoystickButton.BUTTON_6, 67, 512 - 89, 95, 21 );
            addButton( JoystickButton.BUTTON_7, 348, 512 - 89, 95, 21 );
 
            // Select and start buttons           
            addButton( JoystickButton.BUTTON_8, 206, 512 - 198, 48, 30 );
            addButton( JoystickButton.BUTTON_9, 262, 512 - 198, 48, 30 );
            
            // Joystick push buttons
            addButton( JoystickButton.BUTTON_10, 147, 512 - 300, 75, 70 );
            addButton( JoystickButton.BUTTON_11, 285, 512 - 300, 75, 70 );

            // Fake button highlights for the POV axes
            //
            //    +Y  
            //  -X  +X
            //    -Y
            //
            addButton( "POV +Y", 96, 512 - 174, 40, 38 );
            addButton( "POV +X", 128, 512 - 208, 40, 38 );
            addButton( "POV -Y", 96, 512 - 239, 40, 38 );
            addButton( "POV -X", 65, 512 - 208, 40, 38 );

            resetPositions();                                               
        }
 
        private void addButton( String name, float x, float y, float width, float height ) {
            ButtonView b = new ButtonView(name, x, y, width, height);
            attachChild(b);
            buttons.put(name, b);
        }
 
        public void setAxisValue( JoystickAxis axis, float value ) {
            System.out.println( "Axis:" + axis.getName() + "=" + value );
            if( axis == axis.getJoystick().getXAxis() ) {
                setXAxis(value);
            } else if( axis == axis.getJoystick().getYAxis() ) {
                setYAxis(-value);
            } else if( axis == axis.getJoystick().getAxis(JoystickAxis.Z_AXIS) ) {
                // Note: in the above condition, we could check the axis name but
                //       I have at least one joystick that reports 2 "Z Axis" axes.
                //       In this particular case, the first one is the right one so
                //       a name based lookup will find the proper one.  It's a problem
                //       because the erroneous axis sends a constant stream of values.
                setZAxis(value);
            } else if( axis == axis.getJoystick().getAxis(JoystickAxis.Z_ROTATION) ) {
                setZRotation(-value);
            } else if( axis == axis.getJoystick().getPovXAxis() ) {
                if( lastPovX < 0 ) {
                    setButtonValue( "POV -X", false );    
                } else if( lastPovX > 0 ) {
                    setButtonValue( "POV +X", false );    
                } 
                if( value < 0 ) {
                    setButtonValue( "POV -X", true );    
                } else if( value > 0 ) {
                    setButtonValue( "POV +X", true );    
                }
                lastPovX = value; 
            } else if( axis == axis.getJoystick().getPovYAxis() ) {
                if( lastPovY < 0 ) {
                    setButtonValue( "POV -Y", false );    
                } else if( lastPovY > 0 ) {
                    setButtonValue( "POV +Y", false );    
                } 
                if( value < 0 ) {
                    setButtonValue( "POV -Y", true );    
                } else if( value > 0 ) {
                    setButtonValue( "POV +Y", true );    
                }
                lastPovY = value; 
            }
        }
  
        public void setButtonValue( JoystickButton button, boolean isPressed ) {
            System.out.println( "Button:" + button.getName() + "=" + (isPressed ? "Down" : "Up") );
            setButtonValue( button.getLogicalId(), isPressed );
        }

        protected void setButtonValue( String name, boolean isPressed ) {
            ButtonView view = buttons.get(name);
            if( view != null ) {
                if( isPressed ) {
                    view.down();
                } else {
                    view.up();
                }
            }
        }           

        public void setXAxis( float f ) {
            xAxis = f;
            resetPositions();           
        }

        public void setYAxis( float f ) {
            yAxis = f;
            resetPositions();           
        }

        public void setZAxis( float f ) {
            zAxis = f;
            resetPositions();
        }

        public void setZRotation( float f ) {
            zRotation = f;
            resetPositions();
        }
            
        private void resetPositions() {
 
            float xBase = 155;
            float yBase = 212;
            
            Vector2f dir = new Vector2f(xAxis, yAxis);
            float length = Math.min(1, dir.length());
            dir.normalizeLocal();
            
            float angle = dir.getAngle();
            float x = FastMath.cos(angle) * length * 10;
            float y = FastMath.sin(angle) * length * 10;  
            leftStick.setLocalTranslation( xBase + x, yBase + y, 0 );
            
             
            xBase = 291;
            dir = new Vector2f(zAxis, zRotation);
            length = Math.min(1, dir.length());
            dir.normalizeLocal();
            
            angle = dir.getAngle();
            x = FastMath.cos(angle) * length * 10;
            y = FastMath.sin(angle) * length * 10;  
            rightStick.setLocalTranslation( xBase + x, yBase + y, 0 );
        }
    }
    
    protected class ButtonView extends Node {
 
        private int state = 0;
        private Material material;
        private ColorRGBA hilite = new ColorRGBA( 0.0f, 0.75f, 0.75f, 0.5f );
        
        public ButtonView( String name, float x, float y, float width, float height ) {
            super( "Button:" + name );
            setLocalTranslation( x, y, -0.5f );
            
            material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
            material.setColor( "Color", hilite );
            material.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); 

            Geometry g = new Geometry( "highlight", new Quad(width, height) );
            g.setMaterial(material); 
            attachChild(g);
            
            resetState();            
        }
 
        private void resetState() {
            if( state <= 0 ) {
                setCullHint( CullHint.Always );
            } else {
                setCullHint( CullHint.Dynamic );
            }
            
            System.out.println( getName() + " state:" + state );
        }
        
        public void down() {
            state++;            
            resetState();
        }
        
        public void up() {
            state--;
            resetState();
        } 
    }
}

Upon running, I got a similar error to before:

ant -f "C:\\Users\\Jacob\\Documents\\jMonkeyEngine Projects\\JmeTests3.1b1" -Dnb.internal.action.name=run run
init:
Deleting: C:\Users\Jacob\Documents\jMonkeyEngine Projects\JmeTests3.1b1\build\built-jar.properties
deps-jar:
Updating property file: C:\Users\Jacob\Documents\jMonkeyEngine Projects\JmeTests3.1b1\build\built-jar.properties
Compiling 1 source file to C:\Users\Jacob\Documents\jMonkeyEngine Projects\JmeTests3.1b1\build\classes
warning: [options] bootstrap class path not set in conjunction with -source 1.6
1 warning
compile:
run:
Oct 09, 2015 11:41:31 AM java.util.prefs.WindowsPreferences <init>
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
Oct 09, 2015 11:41:33 AM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.1-alpha1
 * Branch: master
 * Git Hash: c5c893f
 * Build Date: 2015-08-17
Oct 09, 2015 11:41:34 AM com.jme3.system.lwjgl.LwjglContext printContextInitInfo
INFO: LWJGL 2.9.3 context running on thread jME3 Main
 * Graphics Adapter: nvd3dumx,nvwgf2umx,nvwgf2umx,nvwgf2umx
 * Driver Version: 10.18.13.5598
 * Scaling Factor: 1
Oct 09, 2015 11:41:34 AM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: NVIDIA Corporation
 * Renderer: GeForce GTX 960/PCIe/SSE2
 * OpenGL Version: 4.5.0 NVIDIA 355.98
 * GLSL Version: 4.50 NVIDIA
 * Profile: Compatibility
Oct 09, 2015 11:41:34 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Device: OpenAL Soft
Oct 09, 2015 11:41:34 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Vendor: OpenAL Community
Oct 09, 2015 11:41:34 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Renderer: OpenAL Soft
Oct 09, 2015 11:41:34 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Version: 1.1 ALSOFT 1.15.1
Oct 09, 2015 11:41:34 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: ALC extensions: ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX ALC_EXT_thread_local_context ALC_SOFT_loopback
Oct 09, 2015 11:41:34 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: AL extensions: AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFTX_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_source_latency
Oct 09, 2015 11:41:34 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: AudioRenderer supports 64 channels
Oct 09, 2015 11:41:34 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
WARNING: Pausing audio device not supported.
Oct 09, 2015 11:41:34 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio effect extension version: 1.0
Oct 09, 2015 11:41:34 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio max auxilary sends: 4
Oct 09, 2015 11:41:34 AM net.java.games.input.DefaultControllerEnvironment getControllers
WARNING: Found unknown Windows version: Windows 8.1
Oct 09, 2015 11:41:34 AM net.java.games.input.DefaultControllerEnvironment getControllers
INFO: Attempting to use default windows plug-in.
Oct 09, 2015 11:41:34 AM net.java.games.input.DefaultControllerEnvironment getControllers
INFO: Loading: net.java.games.input.DirectAndRawInputEnvironmentPlugin
java.lang.UnsatisfiedLinkError: no jinput-dx8_64 in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865)
	at java.lang.Runtime.loadLibrary0(Runtime.java:870)
	at java.lang.System.loadLibrary(System.java:1122)
	at net.java.games.input.DirectInputEnvironmentPlugin$1.run(DirectInputEnvironmentPlugin.java:75)
	at java.security.AccessController.doPrivileged(Native Method)
	at net.java.games.input.DirectInputEnvironmentPlugin.loadLibrary(DirectInputEnvironmentPlugin.java:67)
	at net.java.games.input.DirectInputEnvironmentPlugin.<clinit>(DirectInputEnvironmentPlugin.java:109)
	at net.java.games.input.DirectAndRawInputEnvironmentPlugin.<init>(DirectAndRawInputEnvironmentPlugin.java:45)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
cs length 0
	at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
	at java.lang.Class.newInstance(Class.java:442)
	at net.java.games.input.DefaultControllerEnvironment.getControllers(DefaultControllerEnvironment.java:160)
	at jme3test.input.TestJoystick.simpleInitApp(TestJoystick.java:51)
	at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:227)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:131)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:212)
	at java.lang.Thread.run(Thread.java:745)
java.lang.UnsatisfiedLinkError: no jinput-raw_64 in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865)
	at java.lang.Runtime.loadLibrary0(Runtime.java:870)
	at java.lang.System.loadLibrary(System.java:1122)
	at net.java.games.input.RawInputEnvironmentPlugin$1.run(RawInputEnvironmentPlugin.java:75)
	at java.security.AccessController.doPrivileged(Native Method)
	at net.java.games.input.RawInputEnvironmentPlugin.loadLibrary(RawInputEnvironmentPlugin.java:67)
	at net.java.games.input.RawInputEnvironmentPlugin.<clinit>(RawInputEnvironmentPlugin.java:109)
	at net.java.games.input.DirectAndRawInputEnvironmentPlugin.<init>(DirectAndRawInputEnvironmentPlugin.java:46)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
	at java.lang.Class.newInstance(Class.java:442)
	at net.java.games.input.DefaultControllerEnvironment.getControllers(DefaultControllerEnvironment.java:160)
	at jme3test.input.TestJoystick.simpleInitApp(TestJoystick.java:51)
	at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:227)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:131)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:212)
	at java.lang.Thread.run(Thread.java:745)
Oct 09, 2015 11:41:34 AM net.java.games.input.ControllerEnvironment log
INFO: net.java.games.input.DirectAndRawInputEnvironmentPlugin is not supported

Oct 09, 2015 11:41:34 AM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,6,main]
java.lang.IllegalStateException: Cannot find any joysticks!
	at jme3test.input.TestJoystick.simpleInitApp(TestJoystick.java:56)
	at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:227)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:131)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:212)
	at java.lang.Thread.run(Thread.java:745)

BUILD SUCCESSFUL (total time: 15 seconds)

EDIT: This thread looks promising! jme3test.input.TestJoystick IllegalStateException - #21 by Yves_Tanas

From jinput-platform-2.0.5-natives-windows.jar I extracted:

  • jinput-dx8_64.dll
  • jinput-raw_64.dll
  • jinput-wintab.dll

and placed them in the root of my project directory.

I added

    ControllerEnvironment ce = ControllerEnvironment.getDefaultEnvironment();
    Controller[] cs = ce.getControllers();
    System.out.println("cs length " + cs.length);
    
    for (int i = 0; i < cs.length; i++) {
        System.out.println("cd name |" + cs[i].getName()+"|");
    }

to the simpleInitApp method in the Main.java class in my project:

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.scene.Node;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.heightmap.AbstractHeightMap;
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
import com.jme3.texture.Texture;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.Joystick;
import com.jme3.input.RawInputListener;
import com.jme3.input.controls.JoyAxisTrigger;
import com.jme3.input.controls.MouseAxisTrigger;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.java.games.input.Controller;
import net.java.games.input.ControllerEnvironment;

/**
 * Sample 3 - how to load an OBJ model, and OgreXML model, a material/texture,
 * or text.
 */
public class Main extends SimpleApplication {

    private TerrainQuad terrain;
    Material mat_terrain;
    private boolean left = false, right = false, up = false, down = false, isRunning = true, rotate = false;
    //Temporary vectors used on each frame.
    //They here to avoid instanciating new vectors on each frame
    private Vector3f camDir = new Vector3f();
    private Vector3f camLeft = new Vector3f();
    private Vector3f camOffset = new Vector3f(0.0f, 200.0f, 0.0f);
    //private JmeCursor mousePosition = new JmeCursor();
    //private Spatial sceneModel;
    private BulletAppState bulletAppState;
    private RigidBodyControl landscape;
    private Character playerCharacter;
    private NPCCharacter[] npcCharacter = new NPCCharacter[4];
    private UserSettings userSettings;
    private String gameName = "mygame";

    public static void main(String[] args) {
        Main app = new Main();
        app.setShowSettings(false);
        app.start();
    }

    @Override
    public void simpleInitApp() {
        
        
        ControllerEnvironment ce = ControllerEnvironment.getDefaultEnvironment();
        Controller[] cs = ce.getControllers();
        System.out.println("cs length " + cs.length);
        
        for (int i = 0; i < cs.length; i++) {
            System.out.println("cd name |" + cs[i].getName()+"|");
        }
        
        /* ================================================================ */
        bulletAppState = new BulletAppState();
        stateManager.attach(bulletAppState);

        mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");
        mat_terrain.setTexture("Alpha", assetManager.loadTexture("Textures/alphamap2.png"));

        /**
         * 1.4) Add ROAD texture into the blue layer (Tex3)
         */
        Texture rock = assetManager.loadTexture("Textures/grid8.png");
        rock.setWrap(Texture.WrapMode.Repeat);
        mat_terrain.setTexture("Tex3", rock);
        mat_terrain.setFloat("Tex3Scale", 4096f);

        /**
         * 2. Create the height map
         */
        Texture heightMapImage = assetManager.loadTexture("Textures/wellington-1m-dem 4096.png");

        AbstractHeightMap heightmap = new ImageBasedHeightMap(heightMapImage.getImage());
        heightmap.load();
        heightmap.smooth(1f);

        /**
         * 3. We have prepared material and heightmap. Now we create the actual
         * terrain: 3.1) Create a TerrainQuad and name it "my terrain". 3.2) A
         * good value for terrain tiles is 64x64 -- so we supply 64+1=65. 3.3)
         * We prepared a heightmap of size 512x512 -- so we supply 512+1=513.
         * 3.4) As LOD step scale we supply Vector3f(1,1,1). 3.5) We supply the
         * prepared heightmap itself.
         */
        int patchSize = 65;
        terrain = new TerrainQuad("my terrain", patchSize, 4097, heightmap.getHeightMap());

        /**
         * 4. We give the terrain its material, position & scale it, and attach
         * it.
         */
        terrain.setMaterial(mat_terrain);
        terrain.setLocalTranslation(0, -10, 0);
        terrain.setLocalScale(1f, 1f, 1f);
        rootNode.attachChild(terrain);

        /* player character ================================================================ */
        playerCharacter = new Character(rootNode, bulletAppState, assetManager, new Vector3f(0, 10, 0));

        /* npc character ================================================================ */
        npcCharacter[0] = new NPCCharacter(rootNode, bulletAppState, assetManager, new Vector3f(0, 10, 0));
        npcCharacter[1] = new NPCCharacter(rootNode, bulletAppState, assetManager, new Vector3f(1, 10, 1));
        npcCharacter[2] = new NPCCharacter(rootNode, bulletAppState, assetManager, new Vector3f(2, 10, 2));
        npcCharacter[3] = new NPCCharacter(rootNode, bulletAppState, assetManager, new Vector3f(3, 10, 3));

        /* setting's and stuff ================================================================ */
        try {
            userSettings = new UserSettings(settings, gameName);

            userSettings.load();

            userSettings.save();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

        /* ================================================================ */

        /* make terrain solid */
        CollisionShape sceneShape = CollisionShapeFactory.createMeshShape((Node) terrain);
        landscape = new RigidBodyControl(sceneShape, 0);
        terrain.addControl(landscape);

        bulletAppState.getPhysicsSpace().add(landscape);
        //bulletAppState.getPhysicsSpace().add(playerControl);

        // You must add a light to make the model visible
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
        rootNode.addLight(sun);

        // make a camera
        //this.cam.
        //this.chaseCam = new ChaseCamera(cam, player, inputManager);
        cam.setLocation(playerCharacter.getPhysicsLocation().add(camOffset));
        cam.lookAt(playerCharacter.getPhysicsLocation(), Vector3f.UNIT_Y);
 
        Joystick[] joysticks = inputManager.getJoysticks();

        if (joysticks == null) {
            System.out.println("Cannot find any joysticks!" + settings.useJoysticks());
        } else {
            System.out.println("joysticks " + joysticks.length);
        }
        //initMouseCursor();
        initKeys(); // load my custom keybinding

    }

//    private void initMouseCursor() {
//        Texture cursorTexture = assetManager.loadTexture("Textures/cursor.png");
//
//        Image image = cursorTexture.getImage();
//        ByteBuffer imgByteBuff = (ByteBuffer) image.getData(0).rewind();
//        IntBuffer curIntBuff = BufferUtils.createIntBuffer(image.getHeight() * image.getWidth());
//
//        while (imgByteBuff.hasRemaining()) {
//            int rgba = imgByteBuff.getInt();
//            int argb = ((rgba & 255) << 24) | (rgba >> 8);
//            curIntBuff.put(argb);
//        }
//        mousePosition.setImagesData((IntBuffer) curIntBuff.rewind());
//
//        mousePosition.setNumImages(1);
//
//        mousePosition.setHeight(image.getHeight());
//        mousePosition.setWidth(image.getWidth());
//       
//        mousePosition.setyHotSpot(image.getHeight() / 2);
//        mousePosition.setxHotSpot(image.getWidth() / 2);
//
//        inputManager.setMouseCursor(mousePosition);
//
//        inputManager.setCursorVisible(true);
//
//    }
    /**
     * Custom Keybinding: Map named actions to inputs.
     */
    private void initKeys() {
        // You can map one or several inputs to one named actions
        inputManager.addMapping("Left", new KeyTrigger(userSettings.getInteger("keyboardMapLeft")));

        inputManager.addMapping("Right", new KeyTrigger(userSettings.getInteger("keyboardMapRight")));
        inputManager.addMapping("Up", new KeyTrigger(userSettings.getInteger("keyboardMapUp")));
        inputManager.addMapping("Down", new KeyTrigger(userSettings.getInteger("keyboardMapDown")));
        inputManager.addMapping("Jump", new KeyTrigger(userSettings.getInteger("keyboardMapJump")));
        inputManager.addMapping("Rotate", new KeyTrigger(userSettings.getInteger("keyboardMapRotate")));
        inputManager.addMapping("Pause", new KeyTrigger(userSettings.getInteger("keyboardMapPause")));

        inputManager.addMapping("ZoomIn", new KeyTrigger(userSettings.getInteger("keyboardMapZoomIn")));
        inputManager.addMapping("ZoomOut", new KeyTrigger(userSettings.getInteger("keyboardMapZoomOut")));

        inputManager.addMapping("MouseMoveXPos", new MouseAxisTrigger(com.jme3.input.MouseInput.AXIS_X, false));
        inputManager.addMapping("MouseMoveXNeg", new MouseAxisTrigger(com.jme3.input.MouseInput.AXIS_X, true));
        inputManager.addMapping("MouseMoveYPos", new MouseAxisTrigger(com.jme3.input.MouseInput.AXIS_Y, false));
        inputManager.addMapping("MouseMoveYNeg", new MouseAxisTrigger(com.jme3.input.MouseInput.AXIS_Y, true));

        inputManager.addMapping("Joy0Axis0Pos", new JoyAxisTrigger(0, 0, false));
        inputManager.addMapping("Joy0Axis0Neg", new JoyAxisTrigger(0, 0, true));
        inputManager.addMapping("Joy0Axis1Pos", new JoyAxisTrigger(0, 1, false));
        inputManager.addMapping("Joy0Axis1Neg", new JoyAxisTrigger(0, 1, true));
        inputManager.addMapping("Joy0Axis2Pos", new JoyAxisTrigger(0, 2, false));
        inputManager.addMapping("Joy0Axis2Neg", new JoyAxisTrigger(0, 2, true));
        inputManager.addMapping("Joy0Axis3Pos", new JoyAxisTrigger(0, 3, false));
        inputManager.addMapping("Joy0Axis3Neg", new JoyAxisTrigger(0, 3, true));

        inputManager.addListener(actionListener, "Left");
        inputManager.addListener(actionListener, "Right");
        inputManager.addListener(actionListener, "Up");
        inputManager.addListener(actionListener, "Down");
        inputManager.addListener(actionListener, "Jump");
        inputManager.addListener(actionListener, "Rotate");
        inputManager.addListener(actionListener, "Pause");
        inputManager.addListener(actionListener, "ZoomIn");
        inputManager.addListener(actionListener, "ZoomOut");

        inputManager.addListener(analogListener, "MouseMoveXPos");
        inputManager.addListener(analogListener, "MouseMoveXNeg");
        inputManager.addListener(analogListener, "MouseMoveYPos");
        inputManager.addListener(analogListener, "MouseMoveYNeg");

        inputManager.addListener(analogListener, "Joy0Axis0Pos");
        inputManager.addListener(analogListener, "Joy0Axis0Neg");
        inputManager.addListener(analogListener, "Joy0Axis1Pos");
        inputManager.addListener(analogListener, "Joy0Axis1Neg");
        inputManager.addListener(analogListener, "Joy0Axis2Pos");
        inputManager.addListener(analogListener, "Joy0Axis2Neg");
        inputManager.addListener(analogListener, "Joy0Axis3Pos");
        inputManager.addListener(analogListener, "Joy0Axis3Neg");

    }

    /**
     * This is the main event loop--walking happens here. We check in which
     * direction the player is walking by interpreting the camera direction
     * forward (camDir) and to the side (camLeft). The setWalkDirection()
     * command is what lets a physics-controlled player walk. We also make sure
     * here that the camera moves with player.
     */
    @Override
    public void simpleUpdate(float tpf) {
//        camDir.set(cam.getDirection()).multLocal(0.6f);
//        camLeft.set(cam.getLeft()).multLocal(0.4f);
//        

//        Vector3f playerLocation = playerControl.getPhysicsLocation();
//        Vector3f playerTargetLocation = playerTarget.getLocalTranslation();
//        Vector3f targetOffset = playerLocation.subtract(playerTargetLocation);
        //System.out.println("simpleUpdate x,y |" + inputManager.getCursorPosition() + "|");
        Vector3f walkDirection = new Vector3f(0, 0, 0);
        playerCharacter.setWalkDirection(walkDirection);
        //walkDirection.set(playerTarget.getLocalTranslation().x,0,playerTarget.getLocalTranslation().z);

        if (left) {
            walkDirection.x = 0.5f;
        }
        if (right) {
            walkDirection.x = -0.5f;
        }
        if (up) {
            walkDirection.z = 0.5f;
        }
        if (down) {
            walkDirection.z = -0.5f;
        }
        playerCharacter.setWalkDirection(walkDirection);

        //playerTarget.setLocalTranslation(playerLocation.add(targetOffset.x,playerControl.getPhysicsLocation().y,targetOffset.z));
        cam.setLocation(playerCharacter.getPhysicsLocation().add(camOffset));
        cam.lookAt(playerCharacter.getPhysicsLocation(), Vector3f.UNIT_Y);
        playerCharacter.setTargetLocalTranslation(new Vector3f(-inputManager.getCursorPosition().x, playerCharacter.getPhysicsLocation().y, inputManager.getCursorPosition().y));

        
        
        /* Do AI why not */
        for (int i = 0; i < npcCharacter.length; i++) {
            npcCharacter[i].think();
        }

    }
    private ActionListener actionListener = new ActionListener() {
        public void onAction(String name, boolean keyPressed, float tpf) {
            //System.out.println("Key pressed onAction |" + playerControl.getWalkDirection().toString() + "| name |" + name + "| keyPressed | " + keyPressed + "|");

            if (name.equals("Pause") && keyPressed) {
                isRunning = !isRunning;
            } else if (name.equals("Left")) {
                left = keyPressed;
            } else if (name.equals("Right")) {
                right = keyPressed;
            } else if (name.equals("Up")) {
                up = keyPressed;
            } else if (name.equals("Down")) {
                down = keyPressed;
            } else if (name.equals("ZoomIn")) {
                camOffset.y = camOffset.y - 10;
            } else if (name.equals("ZoomOut")) {
                camOffset.y = camOffset.y + 10;
            } else if (name.equals("Jump")) {
                if (keyPressed) {
                    playerCharacter.jump();
                }
            }

        }
    };
    private AnalogListener analogListener = new AnalogListener() {
        public void onAnalog(String name, float value, float tpf) {
            //System.out.println("onAnalog name |" + name + "| value |" + value + "| tpf |" + tpf +"|");   

            if (isRunning) {
            } else {
                System.out.println("Press P to unpause.");
            }
        }
    };

}

Upon running the game, I get:

run:
Oct 09, 2015 12:05:06 PM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.1-alpha1
 * Branch: master
 * Git Hash: c5c893f
 * Build Date: 2015-08-17
Oct 09, 2015 12:05:07 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo
INFO: LWJGL 2.9.3 context running on thread jME3 Main
 * Graphics Adapter: nvd3dumx,nvwgf2umx,nvwgf2umx,nvwgf2umx
 * Driver Version: 10.18.13.5598
 * Scaling Factor: 1
Oct 09, 2015 12:05:07 PM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: NVIDIA Corporation
 * Renderer: GeForce GTX 960/PCIe/SSE2
 * OpenGL Version: 4.5.0 NVIDIA 355.98
 * GLSL Version: 4.50 NVIDIA
 * Profile: Compatibility
Oct 09, 2015 12:05:07 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Device: OpenAL Soft
Oct 09, 2015 12:05:07 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Vendor: OpenAL Community
Oct 09, 2015 12:05:07 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Renderer: OpenAL Soft
Oct 09, 2015 12:05:07 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Version: 1.1 ALSOFT 1.15.1
Oct 09, 2015 12:05:07 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: ALC extensions: ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX ALC_EXT_thread_local_context ALC_SOFT_loopback
Oct 09, 2015 12:05:07 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: AL extensions: AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFTX_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_source_latency
Oct 09, 2015 12:05:07 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: AudioRenderer supports 64 channels
Oct 09, 2015 12:05:07 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
WARNING: Pausing audio device not supported.
Oct 09, 2015 12:05:07 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio effect extension version: 1.0
Oct 09, 2015 12:05:07 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio max auxilary sends: 4
Oct 09, 2015 12:05:07 PM net.java.games.input.DefaultControllerEnvironment getControllers
WARNING: Found unknown Windows version: Windows 8.1
Oct 09, 2015 12:05:07 PM net.java.games.input.DefaultControllerEnvironment getControllers
INFO: Attempting to use default windows plug-in.
Oct 09, 2015 12:05:07 PM net.java.games.input.DefaultControllerEnvironment getControllers
INFO: Loading: net.java.games.input.DirectAndRawInputEnvironmentPlugin
cs length 25
cd name |HID Keyboard Device|
cd name |HID Keyboard Device|
cd name |HID Keyboard Device|
cd name |Logitech HID-compliant Unifying keyboard|
cd name |HID Keyboard Device|
cd name |HID-compliant mouse|
cd name |Logitech HID-compliant Unifying Mouse|
cd name |HID-compliant mouse|
cd name |Logitech HID-compliant Unifying Mouse|
cd name |USB Multimedia Keyboard|
cd name |Cordless Device|
cd name |W-01RN USB_V3.1|
cd name |USB Receiver|
cd name |USB Multimedia Keyboard|
cd name |USB Keyboard|
cd name |USB Receiver|
cd name |USB Keyboard|
cd name |USB Receiver|
cd name |W-01RN USB_V3.1|
cd name |USB Multimedia Keyboard|
cd name |Controller (XBOX 360 For Windows)|
cd name |Cordless Receiver|
cd name |Cordless Receiver|
cd name |Dual USB Vibration Joystick|
cd name |Dual USB Vibration Joystick|
user home dir is C:\Users\Jacob
LOADED
SAVED
Cannot find any joysticks!true
BUILD SUCCESSFUL (total time: 9 seconds)

So that is encouraging. Controller[] gets filled full of input devices, including the 3 controllers I have plugged in. But still, inputManager.getJoysticks(); just gives me null…

So I left this alone for a few days, but I fired up the debugger and stepped through the code and here is what I’ve found so far:

  • I had to add jinput-dx8_64.dll to the root of the project in order to get a list of controllers with

    ControllerEnvironment ce = ControllerEnvironment.getDefaultEnvironment();
    Controller[] cs = ce.getControllers();

  • I had to add jinput-raw_64 to the root of the project to get a list of the components that the controllers have

  • I am able to print out a list of all controllers, their components, the components ID, and test if the component was an axis or not.

  • Using settings.setUseJoysticks(true); and Joystick[] joysticks = inputManager.getJoysticks(); gives me a null array regardless.

  • Steeping through the code, it seems that before my simpleInitApp() even runs, before I get a chance to set settings.setUseJoysticks true, Application.java has already checked the variable and decided that joysticks are disabled , and declines to run any of the joystick initialisation code: Here on line 321

So I see a couple issue I need to resolve here. One is the dll placement - that doesn’t seem right to me. But maybe it is. i dunno. The other is the order that things happen - I feel like I am missing something, like is there something I need to do before simpleAppInit? A config file somewhere?

Here is my simple test app:

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.input.Joystick;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import net.java.games.input.Component;
import net.java.games.input.Controller;
import net.java.games.input.ControllerEnvironment;

/**
 * test
 * @author normenhansen
 */
public class Main extends SimpleApplication {

    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        System.out.println("settings.getBoolean(\"DisableJoysticks\") " + settings.getBoolean("DisableJoysticks"));
        
        settings.setUseJoysticks(true);
        
        System.out.println("use joysticks? " + settings.useJoysticks());
        System.out.println("settings.getBoolean(\"DisableJoysticks\") " + settings.getBoolean("DisableJoysticks"));

        Joystick[] joysticks = inputManager.getJoysticks();

        if (joysticks == null) {
            System.out.println("Cannot find any joysticks!" + settings.useJoysticks());
        } else {
            System.out.println("joysticks " + joysticks.length);
        }
        
        ControllerEnvironment ce = ControllerEnvironment.getDefaultEnvironment();
        Controller[] cs = ce.getControllers();
        
        System.out.println("cs length " + cs.length);

        for (int i = 0; i < cs.length; i++) {            
            System.out.println("cs type |" + cs[i].getType() + "| name |" + cs[i].getName() + "|");
            
            for( Component comp : cs[i].getComponents() ) {
                System.out.println("-- comp |" + comp.getName() + "| identifyer |" + comp.getIdentifier() +"| is axis? " + (comp.getIdentifier() instanceof Component.Identifier.Axis));
                
                if(comp.getIdentifier() instanceof Component.Identifier.Axis){
                    System.out.println("Component |"+ comp.getIdentifier() +"| Is an axis!");
                }
                        
            }
            
        }
        
        
        Box b = new Box(1, 1, 1);
        Geometry geom = new Geometry("Box", b);

        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        geom.setMaterial(mat);

        rootNode.attachChild(geom);
    }

    @Override
    public void simpleUpdate(float tpf) {
        //TODO: add update code
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //TODO: add render code
    }
}

Yes, you have to set the app settings up BEFORE you start the application. ie: in main()

Changing my main method from above to:

public static void main(String[] args) {
    Main app = new Main();
    AppSettings settings = new AppSettings(true);
    settings.setUseJoysticks(true);
    app.setSettings(settings);
    app.start();
}

works - thanks pspeed :slight_smile:

It also unbundles the correct dll’s so that I don’t have to manually unbundle them. yay :smiley:

1 Like