Skip to content

Commit 9120fed

Browse files
committed
cleanup glfw mapper, and add SDL based joystick handling
1 parent 165969f commit 9120fed

13 files changed

Lines changed: 983 additions & 153 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,4 @@ javadoc_deploy.pub
5050
!.vscode/settings.json
5151
!.vscode/JME_style.xml
5252
!.vscode/extensions.json
53+
joysticks-*.txt

gradle/libs.versions.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ lwjgl3-jemalloc = { module = "org.lwjgl:lwjgl-jemalloc", version.ref = "lwjgl3"
3232
lwjgl3-openal = { module = "org.lwjgl:lwjgl-openal", version.ref = "lwjgl3" }
3333
lwjgl3-opencl = { module = "org.lwjgl:lwjgl-opencl", version.ref = "lwjgl3" }
3434
lwjgl3-opengl = { module = "org.lwjgl:lwjgl-opengl", version.ref = "lwjgl3" }
35+
lwjgl3-sdl = { module = "org.lwjgl:lwjgl-sdl", version.ref = "lwjgl3" }
3536

3637
mokito-core = "org.mockito:mockito-core:3.12.4"
3738

jme3-core/src/main/java/com/jme3/input/DefaultJoystickAxis.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class DefaultJoystickAxis implements JoystickAxis {
4848
private final boolean isAnalog;
4949
private final boolean isRelative;
5050
private float deadZone;
51+
private float jitterThreshold = 0f;
5152

5253
/**
5354
* Creates a new joystick axis instance. Only used internally.
@@ -166,6 +167,12 @@ public void setDeadZone(float f) {
166167
public String toString() {
167168
return "JoystickAxis[name=" + name + ", parent=" + parent.getName() + ", id=" + axisIndex
168169
+ ", logicalId=" + logicalId + ", isAnalog=" + isAnalog
169-
+ ", isRelative=" + isRelative + ", deadZone=" + deadZone + "]";
170+
+ ", isRelative=" + isRelative + ", deadZone=" + deadZone +
171+
", jitterThreshold=" + jitterThreshold + "]";
172+
}
173+
174+
@Override
175+
public float getJitterThreshold() {
176+
return jitterThreshold;
170177
}
171178
}

jme3-core/src/main/java/com/jme3/input/JoystickAxis.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,15 @@ public interface JoystickAxis {
115115
* @return the radius of the dead zone
116116
*/
117117
public float getDeadZone();
118+
119+
120+
/**
121+
* Returns the suggested jitter threshold for this axis. Movements with a delta
122+
* smaller than this threshold will be ignored by the backend input system
123+
*
124+
* @return the jitter threshold
125+
*/
126+
public default float getJitterThreshold(){
127+
return 0;
128+
}
118129
}

jme3-core/src/main/java/com/jme3/system/AppSettings.java

Lines changed: 82 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,31 @@ public final class AppSettings extends HashMap<String, Object> {
268268
*/
269269
public static final String JOAL = "JOAL";
270270

271+
/**
272+
* Map gamepads to Xbox-like layout.
273+
*/
274+
public static final String JOYSTICKS_XBOX_MAPPER = "JOYSTICKS_XBOX_MAPPER";
275+
276+
/**
277+
* Map gamepads to an Xbox-like layout, with fallback to raw if the gamepad is not recognized.
278+
*/
279+
public static final String JOYSTICKS_XBOX_WITH_FALLBACK_MAPPER = "JOYSTICKS_XBOX_WITH_FALLBACK_MAPPER";
280+
281+
/**
282+
* Map gamepads to an Xbox-like layout using the legacy jME input
283+
*/
284+
public static final String JOYSTICKS_XBOX_LEGACY_MAPPER = "JOYSTICKS_XBOX_LEGACY_MAPPER";
285+
286+
/**
287+
* Map gamepads using the legacy jME mapper and input.
288+
*/
289+
public static final String JOYSTICKS_LEGACY_MAPPER = "JOYSTICKS_LEGACY_MAPPER";
290+
291+
/**
292+
* Don't map gamepads, use raw events instead (ie. bring your own mapper)
293+
*/
294+
public static final String JOYSTICKS_RAW_MAPPER = "JOYSTICKS_RAW_MAPPER";
295+
271296
static {
272297
defaults.put("Display", 0);
273298
defaults.put("CenterWindow", true);
@@ -300,8 +325,10 @@ public final class AppSettings extends HashMap<String, Object> {
300325
defaults.put("WindowYPosition", 0);
301326
defaults.put("WindowXPosition", 0);
302327
defaults.put("X11PlatformPreferred", false);
303-
defaults.put("XboxLikeControllerLayout", true);
304-
defaults.put("TriggerToButtonThreshold", 0.5f);
328+
defaults.put("JoysticksMapper", JOYSTICKS_XBOX_MAPPER);
329+
defaults.put("JoysticksTriggerToButtonThreshold", 0.5f);
330+
defaults.put("JoysticksAxisJitterThreshold", 0.0001f);
331+
defaults.put("SDLGameControllerDBResourcePath", "");
305332
// defaults.put("Icons", null);
306333
}
307334

@@ -1616,27 +1643,20 @@ public boolean isX11PlatformPreferred() {
16161643
}
16171644

16181645
/**
1619-
* Enable/disable automatic normalization of gamepad mappings to an Xbox-like layout,
1620-
* when possible.
1621-
*
1622-
* <p>
1623-
* Depending on the platform and controller model, this setting might have no effect.
1624-
* It is primarily intended to provide a consistent default button/axis layout across common
1625-
* controllers.
1646+
* Set which joystick mapping to use for normalization of controller inputs
16261647
*
1627-
* @param enabled true to enable, false to disable (default: true)
1648+
* @param mapper
1649+
* JOYSTICKS_MAPPER_* constant defining which mapping to use
16281650
*/
1629-
public void setXboxLikeControllerLayout(boolean enabled){
1630-
putBoolean("XboxLikeControllerLayout", enabled);
1651+
public void setJoysticksMapper(String mapper) {
1652+
putString("JoysticksMapper", mapper);
16311653
}
16321654

16331655
/**
1634-
* Whether automatic normalization of controller mappings to an Xbox-like layout is enabled.
1635-
*
1636-
* @return true if enabled, otherwise false
1656+
* Get which joystick mapping to use for normalization of controller inputs
16371657
*/
1638-
public boolean isXboxLikeControllerLayout(){
1639-
return getBoolean("XboxLikeControllerLayout");
1658+
public String getJoysticksMapper() {
1659+
return getString("JoysticksMapper");
16401660
}
16411661

16421662
/**
@@ -1649,17 +1669,57 @@ public boolean isXboxLikeControllerLayout(){
16491669
*
16501670
* @param threshold the trigger threshold in the range [0, 1] (default: 0.5f)
16511671
*/
1652-
public void setTriggerToButtonThreshold(float threshold) {
1653-
putFloat("TriggerToButtonThreshold", threshold);
1672+
public void setJoysticksTriggerToButtonThreshold(float threshold) {
1673+
putFloat("JoysticksTriggerToButtonThreshold", threshold);
16541674
}
16551675

16561676
/**
16571677
* Gets the threshold above which an analog trigger should also generate a button-press event.
16581678
*
16591679
* @return the trigger threshold in the range [0, 1] (default: 0.5f)
1660-
* @see #setTriggerToButtonThreshold(float)
1680+
* @see #setJoysticksTriggerToButtonThreshold(float)
16611681
*/
1662-
public float getTriggerToButtonThreshold() {
1663-
return getFloat("TriggerToButtonThreshold");
1682+
public float getJoysticksTriggerToButtonThreshold() {
1683+
return getFloat("JoysticksTriggerToButtonThreshold");
1684+
}
1685+
1686+
/**
1687+
* Sets the jitter threshold for joystick axes.
1688+
*
1689+
* <p>
1690+
* Axis movements with a delta smaller than this threshold will be ignored. This is intended to reduce
1691+
* noise from analog joysticks.
1692+
*/
1693+
public void setJoysticksAxisJitterThreshold(float threshold) {
1694+
putFloat("JoysticksAxisJitterThreshold", threshold);
1695+
}
1696+
1697+
/**
1698+
* Gets the jitter threshold for joystick axes.
1699+
*
1700+
* @return the jitter threshold
1701+
* @see #setJoysticksAxisJitterThreshold(float)
1702+
*/
1703+
public float getJoysticksAxisJitterThreshold() {
1704+
return getFloat("JoysticksAxisJitterThreshold");
1705+
}
1706+
1707+
/**
1708+
* Set resource path for a custom SDL game controller database.
1709+
*
1710+
* @param path
1711+
*/
1712+
public void setSDLGameControllerDBResourcePath(String path) {
1713+
putString("SDLGameControllerDBResourcePath", path);
1714+
}
1715+
1716+
/**
1717+
* Get resource path for a custom SDL game controller database.
1718+
*
1719+
* @return resource path
1720+
*/
1721+
public String getSDLGameControllerDBResourcePath() {
1722+
return getString("SDLGameControllerDBResourcePath");
16641723
}
16651724
}
1725+

jme3-examples/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ dependencies {
1919
implementation project(':jme3-effects')
2020
implementation project(':jme3-jbullet')
2121
implementation project(':jme3-jogg')
22-
implementation project(':jme3-lwjgl')
23-
// implementation project(':jme3-lwjgl3')
22+
// implementation project(':jme3-lwjgl')
23+
implementation project(':jme3-lwjgl3')
2424
implementation project(':jme3-networking')
2525
implementation project(':jme3-niftygui')
2626
implementation project(':jme3-plugins')

jme3-examples/src/main/java/jme3test/input/TestJoystick.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ public class TestJoystick extends SimpleApplication {
4646
public static void main(String[] args){
4747
TestJoystick app = new TestJoystick();
4848
AppSettings settings = new AppSettings(true);
49+
settings.setJoysticksMapper(AppSettings.JOYSTICKS_XBOX_MAPPER);
4950
settings.setUseJoysticks(true);
51+
settings.setX11PlatformPreferred(true);
5052
app.setSettings(settings);
5153
app.start();
5254
}
@@ -155,7 +157,7 @@ protected void setViewedJoystick( Joystick stick ) {
155157

156158
}
157159
}
158-
160+
159161
/**
160162
* Easier to watch for all button and axis events with a raw input listener.
161163
*/
@@ -184,13 +186,15 @@ public void onJoyAxisEvent(JoyAxisEvent evt) {
184186
gamepad.setAxisValue( evt.getAxis(), value );
185187
if( value != 0 ) {
186188
lastValues.put(evt.getAxis(), value);
189+
evt.getAxis().getJoystick().rumble(0.5f);
187190
}
188191
}
189192

190193
@Override
191194
public void onJoyButtonEvent(JoyButtonEvent evt) {
192195
setViewedJoystick( evt.getButton().getJoystick() );
193196
gamepad.setButtonValue( evt.getButton(), evt.isPressed() );
197+
evt.getButton().getJoystick().rumble(1f);
194198
}
195199

196200
@Override
@@ -299,7 +303,7 @@ private void addButton( String name, float x, float y, float width, float height
299303
}
300304

301305
public void setAxisValue( JoystickAxis axis, float value ) {
302-
306+
303307
if( axis == axis.getJoystick().getAxis(JoystickAxis.AXIS_XBOX_LEFT_THUMB_STICK_X)){
304308
setXAxis(value);
305309
} else if( axis == axis.getJoystick().getAxis(JoystickAxis.AXIS_XBOX_LEFT_THUMB_STICK_Y)){

jme3-lwjgl3/build.gradle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ dependencies {
1212
api libs.lwjgl3.openal
1313
api libs.lwjgl3.opencl
1414
api libs.lwjgl3.opengl
15+
api libs.lwjgl3.sdl
1516

1617
runtimeOnly(variantOf(libs.lwjgl3.base){ classifier('natives-windows') })
1718
runtimeOnly(variantOf(libs.lwjgl3.base){ classifier('natives-windows-x86') })
@@ -52,6 +53,14 @@ dependencies {
5253
runtimeOnly(variantOf(libs.lwjgl3.openal){ classifier('natives-linux-arm64') })
5354
runtimeOnly(variantOf(libs.lwjgl3.openal){ classifier('natives-macos') })
5455
runtimeOnly(variantOf(libs.lwjgl3.openal){ classifier('natives-macos-arm64') })
56+
57+
runtimeOnly(variantOf(libs.lwjgl3.sdl){ classifier('natives-windows') })
58+
runtimeOnly(variantOf(libs.lwjgl3.sdl){ classifier('natives-windows-x86') })
59+
runtimeOnly(variantOf(libs.lwjgl3.sdl){ classifier('natives-linux') })
60+
runtimeOnly(variantOf(libs.lwjgl3.sdl){ classifier('natives-linux-arm32') })
61+
runtimeOnly(variantOf(libs.lwjgl3.sdl){ classifier('natives-linux-arm64') })
62+
runtimeOnly(variantOf(libs.lwjgl3.sdl){ classifier('natives-macos') })
63+
runtimeOnly(variantOf(libs.lwjgl3.sdl){ classifier('natives-macos-arm64') })
5564
}
5665

5766
javadoc {

0 commit comments

Comments
 (0)