Ver Fonte

Merge pull request #486 from Dokthar/joysticks

Joystick detection on linux and more...
Paul Speed há 9 anos atrás
pai
commit
7c74262087

+ 4 - 4
jme3-core/src/main/java/com/jme3/input/JoystickCompatibilityMappings.java

@@ -68,10 +68,10 @@ public class JoystickCompatibilityMappings {
     }
     }
 
 
     protected static Map<String,String> getMappings( String joystickName, boolean create ) {
     protected static Map<String,String> getMappings( String joystickName, boolean create ) {
-        Map<String,String> result = joystickMappings.get(joystickName);
+        Map<String,String> result = joystickMappings.get(joystickName.trim());
         if( result == null && create ) {
         if( result == null && create ) {
             result = new HashMap<String,String>();
             result = new HashMap<String,String>();
-            joystickMappings.put(joystickName,result);
+            joystickMappings.put(joystickName.trim(),result);
         }
         }
         return result;          
         return result;          
     }
     }
@@ -94,7 +94,7 @@ public class JoystickCompatibilityMappings {
      *  it returns an empty map.
      *  it returns an empty map.
      */
      */
     public static Map<String,String> getJoystickMappings( String joystickName ) {
     public static Map<String,String> getJoystickMappings( String joystickName ) {
-        Map<String,String> result = getMappings(joystickName, false);
+        Map<String,String> result = getMappings(joystickName.trim(), false);
         if( result == null )
         if( result == null )
             return Collections.emptyMap();
             return Collections.emptyMap();
         return Collections.unmodifiableMap(result);
         return Collections.unmodifiableMap(result);
@@ -121,7 +121,7 @@ public class JoystickCompatibilityMappings {
         for( Map.Entry<Object,Object> e : p.entrySet() ) {
         for( Map.Entry<Object,Object> e : p.entrySet() ) {
             String key = String.valueOf(e.getKey()).trim();
             String key = String.valueOf(e.getKey()).trim();
             
             
-            int split = key.indexOf( '.' );
+            int split = key.lastIndexOf( '.' );
             if( split < 0 ) {
             if( split < 0 ) {
                 logger.log(Level.WARNING, "Skipping mapping:{0}", e);
                 logger.log(Level.WARNING, "Skipping mapping:{0}", e);
                 continue;
                 continue;

+ 44 - 1
jme3-core/src/main/resources/joystick-mapping.properties

@@ -7,10 +7,26 @@
 #   interface.
 #   interface.
 #
 #
 #   Keys with spaces in them should have those spaces escaped.
 #   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
 #   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
 # Final Fantasy XIV mapping
@@ -132,3 +148,30 @@ XBOX\ 360\ For\ Windows\ (Controller).ry=rz
 # requires custom code to support trigger buttons but this
 # requires custom code to support trigger buttons but this
 # keeps it from confusing the .rx mapping.
 # keeps it from confusing the .rx mapping.
 XBOX\ 360\ For\ Windows\ (Controller).z=trigger
 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

+ 54 - 3
jme3-examples/src/main/java/jme3test/input/TestJoystick.java

@@ -1,11 +1,15 @@
 package jme3test.input;
 package jme3test.input;
 
 
 import com.jme3.app.SimpleApplication;
 import com.jme3.app.SimpleApplication;
+import com.jme3.collision.CollisionResult;
+import com.jme3.collision.CollisionResults;
 import com.jme3.font.BitmapText;
 import com.jme3.font.BitmapText;
 import com.jme3.input.Joystick;
 import com.jme3.input.Joystick;
 import com.jme3.input.JoystickAxis;
 import com.jme3.input.JoystickAxis;
 import com.jme3.input.JoystickButton;
 import com.jme3.input.JoystickButton;
 import com.jme3.input.RawInputListener;
 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.JoyAxisEvent;
 import com.jme3.input.event.JoyButtonEvent;
 import com.jme3.input.event.JoyButtonEvent;
 import com.jme3.input.event.KeyInputEvent;
 import com.jme3.input.event.KeyInputEvent;
@@ -16,7 +20,10 @@ import com.jme3.material.Material;
 import com.jme3.material.RenderState.BlendMode;
 import com.jme3.material.RenderState.BlendMode;
 import com.jme3.math.ColorRGBA;
 import com.jme3.math.ColorRGBA;
 import com.jme3.math.FastMath;
 import com.jme3.math.FastMath;
+import com.jme3.math.Ray;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.Camera;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.Node;
 import com.jme3.scene.Node;
 import com.jme3.scene.shape.Quad;
 import com.jme3.scene.shape.Quad;
@@ -33,6 +40,7 @@ public class TestJoystick extends SimpleApplication {
     private GamepadView gamepad;
     private GamepadView gamepad;
     private Node joystickInfo;
     private Node joystickInfo;
     private float yInfo = 0;
     private float yInfo = 0;
+    private JoystickButton lastButton;
 
 
     public static void main(String[] args){
     public static void main(String[] args){
         TestJoystick app = new TestJoystick();
         TestJoystick app = new TestJoystick();
@@ -44,6 +52,8 @@ public class TestJoystick extends SimpleApplication {
     
     
     @Override
     @Override
     public void simpleInitApp() {
     public void simpleInitApp() {
+        getFlyByCamera().setEnabled(false);
+
         Joystick[] joysticks = inputManager.getJoysticks();
         Joystick[] joysticks = inputManager.getJoysticks();
         if (joysticks == null)
         if (joysticks == null)
             throw new IllegalStateException("Cannot find any joysticks!");
             throw new IllegalStateException("Cannot find any joysticks!");
@@ -54,9 +64,9 @@ public class TestJoystick extends SimpleApplication {
             out.close();
             out.close();
         } catch( IOException e ) {
         } catch( IOException e ) {
             throw new RuntimeException( "Error writing joystick dump", e );
             throw new RuntimeException( "Error writing joystick dump", e );
-        }
+        }   
+
 
 
- 
         int gamepadSize = cam.getHeight() / 2;
         int gamepadSize = cam.getHeight() / 2;
         float scale = gamepadSize / 512.0f;        
         float scale = gamepadSize / 512.0f;        
         gamepad = new GamepadView();       
         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
         // Add a raw listener because it's eisier to get all joystick events
         // this way.
         // this way.
         inputManager.addRawInputListener( new JoystickEventListener() );
         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 ) {
     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 = new Geometry( "leftStick", new Quad(64, 64) );
             leftStick.setMaterial(m);
             leftStick.setMaterial(m);
             attachChild(leftStick);
             attachChild(leftStick);
-            rightStick = new Geometry( "leftStick", new Quad(64, 64) );
+            rightStick = new Geometry( "rightStick", new Quad(64, 64) );
             rightStick.setMaterial(m);
             rightStick.setMaterial(m);
             attachChild(rightStick);
             attachChild(rightStick);
 
 
@@ -288,6 +310,7 @@ public class TestJoystick extends SimpleApplication {
         public void setButtonValue( JoystickButton button, boolean isPressed ) {
         public void setButtonValue( JoystickButton button, boolean isPressed ) {
             System.out.println( "Button:" + button.getName() + "=" + (isPressed ? "Down" : "Up") );
             System.out.println( "Button:" + button.getName() + "=" + (isPressed ? "Down" : "Up") );
             setButtonValue( button.getLogicalId(), isPressed );
             setButtonValue( button.getLogicalId(), isPressed );
+            lastButton = button;
         }
         }
 
 
         protected void setButtonValue( String name, boolean isPressed ) {
         protected void setButtonValue( String name, boolean isPressed ) {
@@ -389,4 +412,32 @@ public class TestJoystick extends SimpleApplication {
             resetState();
             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;
+    }
 }
 }

+ 41 - 5
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;
 package com.jme3.input.lwjgl;
 
 
 import com.jme3.input.AbstractJoystick;
 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);        
             logger.log(Level.FINE, "Attempting to create joystick for: \"{0}\"", c);        
  
  
             // Try to create it like a joystick
             // 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() ) {
             for( Component comp : c.getComponents() ) {
                 stick.addComponent(comp);                   
                 stick.addComponent(comp);                   
             }
             }
@@ -210,13 +241,18 @@ public class JInputJoyInput implements JoyInput {
             
             
             Identifier id = comp.getIdentifier();            
             Identifier id = comp.getIdentifier();            
             if( !(id instanceof Button) ) {
             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 name = comp.getName();
             String original = id.getName();
             String original = id.getName();
+            try { 
+                Integer.parseInt(original);
+            } catch (NumberFormatException e){
+                original = String.valueOf(buttonIndex.size());
+            }
             String logicalId = JoystickCompatibilityMappings.remapComponent( controller.getName(), original );
             String logicalId = JoystickCompatibilityMappings.remapComponent( controller.getName(), original );
-            if( name != original ) {
+            if( logicalId != original ) {
                 logger.log(Level.FINE, "Remapped:" + original + " to:" + logicalId);
                 logger.log(Level.FINE, "Remapped:" + original + " to:" + logicalId);
             }
             }
  
  
@@ -238,7 +274,7 @@ public class JInputJoyInput implements JoyInput {
             String name = comp.getName();
             String name = comp.getName();
             String original = id.getName();
             String original = id.getName();
             String logicalId = JoystickCompatibilityMappings.remapComponent( controller.getName(), original );
             String logicalId = JoystickCompatibilityMappings.remapComponent( controller.getName(), original );
-            if( name != original ) {
+            if( logicalId != original ) {
                 logger.log(Level.FINE, "Remapped:" + original + " to:" + logicalId);
                 logger.log(Level.FINE, "Remapped:" + original + " to:" + logicalId);
             }
             }