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