diff --git a/jme3-core/src/main/java/com/jme3/input/JoystickCompatibilityMappings.java b/jme3-core/src/main/java/com/jme3/input/JoystickCompatibilityMappings.java index 60a4e126f..ee2434d54 100644 --- a/jme3-core/src/main/java/com/jme3/input/JoystickCompatibilityMappings.java +++ b/jme3-core/src/main/java/com/jme3/input/JoystickCompatibilityMappings.java @@ -68,10 +68,10 @@ public class JoystickCompatibilityMappings { } protected static Map getMappings( String joystickName, boolean create ) { - Map result = joystickMappings.get(joystickName); + Map result = joystickMappings.get(joystickName.trim()); if( result == null && create ) { result = new HashMap(); - joystickMappings.put(joystickName,result); + joystickMappings.put(joystickName.trim(),result); } return result; } @@ -94,7 +94,7 @@ public class JoystickCompatibilityMappings { * it returns an empty map. */ public static Map getJoystickMappings( String joystickName ) { - Map result = getMappings(joystickName, false); + Map result = getMappings(joystickName.trim(), false); if( result == null ) return Collections.emptyMap(); return Collections.unmodifiableMap(result); @@ -121,7 +121,7 @@ public class JoystickCompatibilityMappings { for( Map.Entry e : p.entrySet() ) { String key = String.valueOf(e.getKey()).trim(); - int split = key.indexOf( '.' ); + int split = key.lastIndexOf( '.' ); if( split < 0 ) { logger.log(Level.WARNING, "Skipping mapping:{0}", e); continue; diff --git a/jme3-core/src/main/resources/joystick-mapping.properties b/jme3-core/src/main/resources/joystick-mapping.properties index 73d0f504f..83a6996de 100644 --- a/jme3-core/src/main/resources/joystick-mapping.properties +++ b/jme3-core/src/main/resources/joystick-mapping.properties @@ -7,10 +7,26 @@ # interface. # # Keys with spaces in them should have those spaces escaped. -# Values do not need their spaces escaped. For example: +# Values do not need their spaces escaped : # +# Joystick\ Name.{axis/button id}={remapping id value} +# +# For example : # Some\ Joystick.0=3 # +# Mappings logicalId : +# triangle / 1 : 0 +# circle / 2 : 1 +# cross / 3 : 2 +# square / 4 : 3 +# L1 : 4 +# R1 : 5 +# L2 : 6 +# R2 : 7 +# select : 8 +# start : 9 +# Lstick button : 10 +# Rstick button : 11 # Final Fantasy XIV mapping @@ -132,3 +148,30 @@ XBOX\ 360\ For\ Windows\ (Controller).ry=rz # requires custom code to support trigger buttons but this # keeps it from confusing the .rx mapping. XBOX\ 360\ For\ Windows\ (Controller).z=trigger + +# from : Freebox controller as "DragonRise Inc. Generic USB Joystick" +DragonRise\ Inc.\ \ \ Generic\ \ \ USB\ \ Joystick.x=rx +DragonRise\ Inc.\ \ \ Generic\ \ \ USB\ \ Joystick.y=ry +DragonRise\ Inc.\ \ \ Generic\ \ \ USB\ \ Joystick.z=y +DragonRise\ Inc.\ \ \ Generic\ \ \ USB\ \ Joystick.rx=z +DragonRise\ Inc.\ \ \ Generic\ \ \ USB\ \ Joystick.rz=rz + +# from : Two dots controller as "GASIA CORP. PLAYSTATION(R)3 Controller" +# most of the button have a analog axis +# two controllers are detected at the same time instead of one +# some button mappings are missing (triangle, circle, cross) on linux +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.8=6 +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.9=7 +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.10=4 +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.11=5 +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.12=3 + +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.0=8 +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.3=9 +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.1=10 +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.2=11 + +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.5=POV +X +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.6=POV -Y +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.7=POV -X +GASIA\ CORP.\ PLAYSTATION(R)3\ Controller.4=POV +Y \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/input/TestJoystick.java b/jme3-examples/src/main/java/jme3test/input/TestJoystick.java index 9d9abc914..29a9166fe 100644 --- a/jme3-examples/src/main/java/jme3test/input/TestJoystick.java +++ b/jme3-examples/src/main/java/jme3test/input/TestJoystick.java @@ -1,11 +1,15 @@ package jme3test.input; import com.jme3.app.SimpleApplication; +import com.jme3.collision.CollisionResult; +import com.jme3.collision.CollisionResults; 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.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; import com.jme3.input.event.JoyAxisEvent; import com.jme3.input.event.JoyButtonEvent; import com.jme3.input.event.KeyInputEvent; @@ -16,7 +20,10 @@ 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.Ray; import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Camera; import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.shape.Quad; @@ -33,6 +40,7 @@ public class TestJoystick extends SimpleApplication { private GamepadView gamepad; private Node joystickInfo; private float yInfo = 0; + private JoystickButton lastButton; public static void main(String[] args){ TestJoystick app = new TestJoystick(); @@ -44,6 +52,8 @@ public class TestJoystick extends SimpleApplication { @Override public void simpleInitApp() { + getFlyByCamera().setEnabled(false); + Joystick[] joysticks = inputManager.getJoysticks(); if (joysticks == null) throw new IllegalStateException("Cannot find any joysticks!"); @@ -54,9 +64,9 @@ public class TestJoystick extends SimpleApplication { 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(); @@ -71,6 +81,18 @@ public class TestJoystick extends SimpleApplication { // Add a raw listener because it's eisier to get all joystick events // this way. inputManager.addRawInputListener( new JoystickEventListener() ); + + // add action listener for mouse click + // to all easier custom mapping + inputManager.addMapping("mouseClick", new MouseButtonTrigger(mouseInput.BUTTON_LEFT)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if(isPressed){ + pickGamePad(getInputManager().getCursorPosition()); + } + } + }, "mouseClick"); } protected void dumpJoysticks( Joystick[] joysticks, PrintWriter out ) { @@ -199,7 +221,7 @@ public class TestJoystick extends SimpleApplication { leftStick = new Geometry( "leftStick", new Quad(64, 64) ); leftStick.setMaterial(m); attachChild(leftStick); - rightStick = new Geometry( "leftStick", new Quad(64, 64) ); + rightStick = new Geometry( "rightStick", new Quad(64, 64) ); rightStick.setMaterial(m); attachChild(rightStick); @@ -288,6 +310,7 @@ public class TestJoystick extends SimpleApplication { public void setButtonValue( JoystickButton button, boolean isPressed ) { System.out.println( "Button:" + button.getName() + "=" + (isPressed ? "Down" : "Up") ); setButtonValue( button.getLogicalId(), isPressed ); + lastButton = button; } protected void setButtonValue( String name, boolean isPressed ) { @@ -389,4 +412,32 @@ public class TestJoystick extends SimpleApplication { resetState(); } } + + private void pickGamePad(Vector2f mouseLoc){ + if (lastButton != null) { + CollisionResults cresults = pick(cam, mouseLoc, gamepad); + for (CollisionResult cr : cresults) { + Node n = cr.getGeometry().getParent(); + if (n != null && (n instanceof ButtonView)) { + String b = ((ButtonView) n).getName().substring("Button:".length()); + String name = lastButton.getJoystick().getName().replaceAll(" ", "\\\\ "); + String id = lastButton.getLogicalId().replaceAll(" ", "\\\\ "); + System.out.println(name + "." + id + "=" + b); + return; + } + } + } + } + + private static CollisionResults pick(Camera cam, Vector2f mouseLoc, Node node) { + CollisionResults results = new CollisionResults(); + Ray ray = new Ray(); + Vector3f pos = new Vector3f(mouseLoc.x, mouseLoc.y, -1); + Vector3f dir = new Vector3f(mouseLoc.x, mouseLoc.y, 1); + dir.subtractLocal(pos).normalizeLocal(); + ray.setOrigin(pos); + ray.setDirection(dir); + node.collideWith(ray, results); + return results; + } } diff --git a/jme3-lwjgl/src/main/java/com/jme3/input/lwjgl/JInputJoyInput.java b/jme3-lwjgl/src/main/java/com/jme3/input/lwjgl/JInputJoyInput.java index 606ebec87..d89a07af5 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/input/lwjgl/JInputJoyInput.java +++ b/jme3-lwjgl/src/main/java/com/jme3/input/lwjgl/JInputJoyInput.java @@ -1,3 +1,35 @@ +/* + * Copyright (c) 2009-2016 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + package com.jme3.input.lwjgl; import com.jme3.input.AbstractJoystick; @@ -60,8 +92,7 @@ public class JInputJoyInput implements JoyInput { logger.log(Level.FINE, "Attempting to create joystick for: \"{0}\"", c); // Try to create it like a joystick - JInputJoystick stick = new JInputJoystick(inputManager, this, c, list.size(), - c.getName()); + JInputJoystick stick = new JInputJoystick(inputManager, this, c, list.size(), c.getName()); for( Component comp : c.getComponents() ) { stick.addComponent(comp); } @@ -210,13 +241,18 @@ public class JInputJoyInput implements JoyInput { Identifier id = comp.getIdentifier(); if( !(id instanceof Button) ) { - throw new IllegalArgumentException( "Component is not an axis:" + comp ); + throw new IllegalArgumentException( "Component is not an button:" + comp ); } String name = comp.getName(); String original = id.getName(); + try { + Integer.parseInt(original); + } catch (NumberFormatException e){ + original = String.valueOf(buttonIndex.size()); + } String logicalId = JoystickCompatibilityMappings.remapComponent( controller.getName(), original ); - if( name != original ) { + if( logicalId != original ) { logger.log(Level.FINE, "Remapped:" + original + " to:" + logicalId); } @@ -238,7 +274,7 @@ public class JInputJoyInput implements JoyInput { String name = comp.getName(); String original = id.getName(); String logicalId = JoystickCompatibilityMappings.remapComponent( controller.getName(), original ); - if( name != original ) { + if( logicalId != original ) { logger.log(Level.FINE, "Remapped:" + original + " to:" + logicalId); }