소스 검색

Added new JoystickAxis.LEFT_TRIGGER/RIGHT_TRIGGER.
Updated JoystickCompatibilityMappings to support normalizing joystick names
based on a regex. For example:
XBOX.regex=(?i).*xbox.*
...will allow configuring all joysticks with xbox in the name with one
XBOX configuration.

Paul Speed 6 년 전
부모
커밋
5901a95363

+ 23 - 0
jme3-core/src/main/java/com/jme3/input/JoystickAxis.java

@@ -42,6 +42,29 @@ public interface JoystickAxis {
     public static final String Y_AXIS = "y";
     public static final String Z_AXIS = "z";
     public static final String Z_ROTATION = "rz";
+    public static final String LEFT_TRIGGER = "rx";
+    public static final String RIGHT_TRIGGER = "ry";
+    
+    // Note: the left/right trigger bit may be a bit controversial in
+    // the sense that this is one case where XBox controllers make a lot
+    // more sense.
+    // I've seen the following mappings for various things:
+    // 
+    // Axis          | XBox  | Non-Xbox (generally) (includes actual Sony PS4 controllers)
+    // --------------+-------+---------------
+    // left trigger  | z     | rx   (also button 6)
+    // right trigger | rz    | ry   (also button 7)
+    // left stick x  | x     | x
+    // left stick y  | y     | y
+    // right stick x | rx    | z
+    // right stick y | ry    | rz
+    //
+    // The issue is that in all cases I've seen, the XBox controllers will
+    // use the name "xbox" somewhere in their name.  The Non-XBox controllers
+    // never mention anything uniform... even the PS4 controller only calls
+    // itself "Wireless Controller".  In that light, it seems easier to make
+    // the default the ugly case and the "XBox" way the exception because it
+    // can more easily be identified.
 
     public static final String POV_X = "pov_x";
     public static final String POV_Y = "pov_y";

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

@@ -41,6 +41,8 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 
 /**
@@ -63,6 +65,10 @@ public class JoystickCompatibilityMappings {
 
     private static Map<String,Map<String,String>> joystickMappings = new HashMap<String,Map<String,String>>();
 
+    // Remaps names by regex.
+    private static Map<Pattern, String> nameRemappings = new HashMap<>();
+    private static Map<String, String> nameCache = new HashMap<>();
+
     static {
         loadDefaultMappings();
     }
@@ -81,11 +87,29 @@ public class JoystickCompatibilityMappings {
      *  is a mapping for it otherwise it returns the original name.
      */
     public static String remapComponent( String joystickName, String componentId ) {
-        Map<String,String> map = getMappings(joystickName.trim(), false);   
-        if( map == null )
+        logger.log(Level.FINE, "remapComponent(" + joystickName + ", " + componentId + ")");
+         
+        // Always try the specific name first.
+        joystickName = joystickName.trim();     
+        Map<String,String> map = getMappings(joystickName, false);   
+        if( map != null && map.containsKey(componentId) ) {
+            logger.log(Level.FINE, "returning remapped:" + map.get(componentId));        
+            return map.get(componentId);
+        }
+        // Try the normalized name
+        joystickName = getNormalizedName(joystickName);
+        logger.log(Level.FINE, "normalized joystick name:" + joystickName);         
+        if( joystickName == null ) {
+            return componentId;
+        }
+        map = getMappings(joystickName, false);
+        if( map == null ) {
             return componentId;
-        if( !map.containsKey(componentId) )
+        }   
+        if( !map.containsKey(componentId) ) {
             return componentId;
+        }
+        logger.log(Level.FINE, "returning remapped:" + map.get(componentId));        
         return map.get(componentId); 
     }       
  
@@ -130,8 +154,36 @@ public class JoystickCompatibilityMappings {
             String stick = key.substring(0, split).trim();
             String component = key.substring(split+1).trim();            
             String value = String.valueOf(e.getValue()).trim();
-            addMapping(stick, component, value);           
+            if( "regex".equals(component) ) {
+                // It's a name remapping
+                addJoystickNameRegex(value, stick);
+            }
+            addMapping(stick, component, value);
+        }
+    }
+ 
+    /**
+     *  Maps a regular expression to a normalized name for that joystick.
+     */
+    public static void addJoystickNameRegex( String regex, String name ) {
+        logger.log(Level.FINE, "addJoystickNameRegex(" + regex + ", " + name + ")");
+        nameRemappings.put(Pattern.compile(regex), name);   
+    }
+    
+    protected static String getNormalizedName( String name ) {
+        String result = nameCache.get(name);
+        if( result != null ) {
+            return result;
+        }
+        for( Map.Entry<Pattern, String> e : nameRemappings.entrySet() ) {
+            Pattern p = e.getKey();
+            Matcher m = p.matcher(name);
+            if( m.matches() ) {
+                nameCache.put(name, e.getValue());
+                return e.getValue();
+            }
         }
+        return null;
     }
  
     /**