8 Commits

Author SHA1 Message Date
Markil3
b08fc29734 Updated for the 3.4 release. 2021-10-07 09:11:38 -06:00
Markil3
2adb2a3b87 Enables the features added in https://github.com/Markil3/jmonkeyengine/tree/joyAxisUpdate. 2021-02-26 17:21:37 -07:00
Markil3
c9e0fce4d2 Optimizes the build and prepares for a new version. 2021-02-26 16:47:16 -07:00
Markil3
5e32ac16bb Allows the calibration screen to record ranges.
This will take advantage of changes in 3.4.
2021-02-26 16:17:14 -07:00
Markil3
e5c2828848 Fixes some errors in how joystick positions were calculated. 2021-02-26 16:14:08 -07:00
Markil3
dbb9ee23be Made the default axis value displayed "0.0"
"-1.0" didn't seem right.
2021-02-26 16:11:04 -07:00
Markil3
6a2c444910 Gives the calibrator the option of rendering unused buttons useless.
This prevents them from accidentally interfering with buttons we want.
2021-02-26 11:31:14 -07:00
Markil3
399b5a2b81 Fixes a bug with how the calibrater handled button DPads. 2021-02-26 10:44:43 -07:00
10 changed files with 545 additions and 87 deletions

View File

@@ -23,7 +23,7 @@ If you wish to change the colors of the buttons, simply change the color values
* jme3-lwjgl3 or jme3-lwjgl (if running as standalone)
* jme3-android (if running on Android)
* jme3-android-natives (if running on Android)
* slf4j-api 1.7.15+
* slf4j-api 1.7.30+
## Building from Source
To build from source, start by downloading the source from github. If you have the [git command line tool](https://git-scm.com/downloads) installed, the following line will download the git repository from github:
@@ -45,7 +45,7 @@ If you want to test this without implementing it in your software, simply downlo
This will run a bare-bones version dedicated to the utility using LWJGL3.
Alternativly, you can use the :desktopLegacy subproject for LWJGL2, or the :android subproject for testing on Android.
Alternatively, you can use the :desktopLegacy subproject for LWJGL2, or the :android subproject for testing on Android.
## Troubleshooting

View File

@@ -5,7 +5,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.1'
classpath 'com.android.tools.build:gradle:4.1.2'
}
}
@@ -17,13 +17,13 @@ repositories {
}
android {
compileSdkVersion 29
buildToolsVersion "30.0.2"
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "markil3.controller"
minSdkVersion 19
targetSdkVersion 29
targetSdkVersion 30
versionCode 1
versionName "1.0"
@@ -43,15 +43,17 @@ android {
}
dependencies {
api(project(":desktop")) {
exclude module: "jme3-lwjgl3"
exclude module: "jme3-desktop"
api(project(":library")) {
exclude module: "slf4j-simple"
}
implementation "uk.uuid.slf4j:slf4j-android:1.7.30-0"
implementation "${jme3.g}:jme3-android:${jme3.version}"
implementation "${jme3.g}:jme3-android-native:${jme3.version}"
implementation "androidx.appcompat:appcompat:1.1.0"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.0.9"
// implementation rootProject.files('libs/jme3-android.jar')
// implementation rootProject.files('libs/jme3-core.jar')
// implementation rootProject.files('libs/jme3-plugins.jar')
// implementation rootProject.files('libs/jme3-android-native.jar')
implementation "androidx.appcompat:appcompat:1.2.0"
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
}

View File

@@ -0,0 +1,276 @@
/*
* Copyright 2020 Markil 3. All rights reserved.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package markil3.controller;
import com.jme3.app.DebugKeysAppState;
import com.jme3.app.SimpleApplication;
import com.jme3.app.StatsAppState;
import com.jme3.font.BitmapText;
import com.jme3.input.JoystickCompatibilityMappings;
import com.jme3.input.controls.ActionListener;
import com.jme3.scene.Node;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeSystem;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/**
* Launch point for the application. This is primarily for demo purposes, and
* games using this as a library can safely ignore it.
*
* @author Markil 3
* @version 1.0
*/
public class Main extends SimpleApplication implements ActionListener
{
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.
getLogger(Main.class);
public static File GAME_FOLDER;
public static File CALIBRATION_FILE;
public static File getGameFolder()
{
return GAME_FOLDER;
}
private static void initializeJoystickMappings()
{
if (CALIBRATION_FILE == null)
{
CALIBRATION_FILE =
new File(GAME_FOLDER, "controllerCalibration.properties");
URL mappingUrl;
switch (JmeSystem.getPlatform())
{
case Windows32:
case Windows64:
mappingUrl = Main.class.
getResource("/joystick-mapping.windows.properties");
break;
case MacOSX32:
case MacOSX64:
case MacOSX_PPC32:
case MacOSX_PPC64:
mappingUrl = Main.class.
getResource("/joystick-mapping.osx.properties");
break;
case Linux32:
case Linux64:
case Linux_ARM32:
case Linux_ARM64:
mappingUrl = Main.class.
getResource("/joystick-mapping.linux.properties");
break;
case Android_ARM5:
case Android_ARM6:
case Android_ARM7:
case Android_ARM8:
case Android_X86:
case Android_Other:
mappingUrl = Main.class.
getResource("/joystick-mapping.android.properties");
break;
case iOS_ARM:
case iOS_X86:
mappingUrl = Main.class.
getResource("/joystick-mapping.ios.properties");
break;
default:
mappingUrl = null;
}
if (mappingUrl != null)
{
try
{
JoystickCompatibilityMappings
.loadMappingProperties(mappingUrl);
}
catch (IOException e)
{
logger.error("Unable to load joystick mappings for " +
mappingUrl, e);
}
}
mappingUrl = Main.class.
getResource("/joystick-mapping." +
JmeSystem.getPlatform().toString().toLowerCase() +
".properties");
if (mappingUrl != null)
{
try
{
JoystickCompatibilityMappings
.loadMappingProperties(mappingUrl);
}
catch (IOException e)
{
logger.error("Unable to load joystick mappings for " +
mappingUrl, e);
}
}
if (CALIBRATION_FILE.isFile())
{
try
{
JoystickCompatibilityMappings.loadMappingProperties(
CALIBRATION_FILE.toURI().toURL());
}
catch (IOException e)
{
logger.error("Unable to load joystick mappings.", e);
}
}
}
}
public static void main(String[] args)
{
Main app;
AppSettings settings;
app = new Main();
settings = new AppSettings(true);
settings.setTitle("Joystick Preview");
settings.setUseJoysticks(true);
settings.setEmulateMouse(true);
settings.setVSync(true);
settings.setWidth(1280);
settings.setHeight(720);
app.setSettings(settings);
app.start();
}
private Node calibrateButton;
public Main()
{
super(new StatsAppState(), new DebugKeysAppState(),
new JoystickPreviewScreen());
}
@Override
public void initialize()
{
final File[] possibleGameDirs =
new File[]{new File(System.getProperty("user.dir")),
new File(System.getProperty("user.home")),
JmeSystem.getStorageFolder(
JmeSystem.StorageFolderType.External)};
int i, l;
if (GAME_FOLDER == null)
{
for (i = 0, l = possibleGameDirs.length; i < l; i++)
{
GAME_FOLDER = possibleGameDirs[i];
if (!GAME_FOLDER.isDirectory())
{
if (!GAME_FOLDER.mkdir())
{
logger.warn("Cannot make " + GAME_FOLDER);
continue;
}
}
if (!GAME_FOLDER.canWrite())
{
logger.warn("Cannot write to " + GAME_FOLDER);
continue;
}
break;
}
if (i == l)
{
throw new RuntimeException(
"Could not create game directory folder.");
}
}
/*
* Add custom joystick mappings before the input manager is loaded.
*/
initializeJoystickMappings();
super.initialize();
}
@Override
public void simpleInitApp()
{
this.calibrateButton =
GUIUtils.createButton(this.getAssetManager(), this.guiFont,
this.getContext().getTouchInput() != null, "calibrate",
"Calibrate Gamepad");
}
@Override
public void simpleUpdate(float tpf)
{
JoystickPreviewScreen screen =
this.getStateManager().getState(JoystickPreviewScreen.class);
if (this.calibrateButton.getParent() == null && screen != null)
{
this.guiNode.attachChild(this.calibrateButton);
this.calibrateButton.setLocalTranslation(
(this.getCamera().getWidth() -
((BitmapText) this.calibrateButton.getChild(1))
.getLineWidth() - 10) / 2F,
this.getCamera().getHeight(), 0);
this.inputManager.addListener(this, screen.CLICK_MAPPING);
}
else if (this.calibrateButton.getParent() != null && screen == null)
{
this.guiNode.detachChild(this.calibrateButton);
this.inputManager.removeListener(this);
}
}
@Override
public void onAction(String name, boolean isPressed, float tpf)
{
String buttonId;
JoystickPreviewScreen screen =
this.getStateManager().getState(JoystickPreviewScreen.class);
if (screen != null && name.equals(screen.CLICK_MAPPING))
{
buttonId = GUIUtils.handleButtonPress(this.calibrateButton,
this.getInputManager().getCursorPosition(), isPressed);
if (!isPressed && "calibrate".equals(buttonId))
{
this.getStateManager().detach(screen);
this.getStateManager()
.attach(new CalibrateInputScreen(CALIBRATION_FILE));
}
}
}
@Override
public void restart()
{
super.restart();
this.enqueue(() -> {
JoystickPreviewScreen previewScreen = this.getStateManager()
.getState(JoystickPreviewScreen.class);
CalibrateInputScreen calibrateScreen =
this.getStateManager().getState(CalibrateInputScreen.class);
if (previewScreen != null)
{
previewScreen.resize();
}
if (calibrateScreen != null)
{
calibrateScreen.resize();
}
this.calibrateButton.setLocalTranslation(
(this.getCamera().getWidth() -
((BitmapText) this.calibrateButton.getChild(1))
.getLineWidth() - 10) / 2F,
this.getCamera().getHeight(), 0);
});
}
}

View File

@@ -1,10 +1,8 @@
package markil3.controller;
import android.content.res.Configuration;
import android.os.Bundle;
import com.jme3.app.AndroidHarness;
import com.jme3.system.AppSettings;
import java.util.logging.Level;
import java.util.logging.LogManager;

View File

@@ -9,10 +9,10 @@
*/
ext {
jme3 = [version: '3.3.2-stable', g: 'org.jmonkeyengine']
jme3 = [version: '3.4.0-stable', g: 'org.jmonkeyengine']
versionNumber = 2
}
version = "1.1"
version = "1.2"
task run {
doFirst {

View File

@@ -20,15 +20,41 @@ plugins {
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
//def lwjglVersion = '3.2.3'
dependencies {
// Logging
implementation "org.slf4j:slf4j-api:1.7.15"
implementation "org.slf4j:slf4j-api:1.7.30"
implementation "org.slf4j:slf4j-simple:1.7.5"
implementation project(':library')
implementation "${jme3.g}:jme3-core:${jme3.version}"
implementation "${jme3.g}:jme3-desktop:${jme3.version}"
implementation "${jme3.g}:jme3-lwjgl3:${jme3.version}"
// implementation rootProject.files('libs/jme3-core.jar')
// implementation rootProject.files('libs/jme3-desktop.jar')
// implementation rootProject.files('libs/jme3-lwjgl3.jar')
// implementation "org.lwjgl:lwjgl:${lwjglVersion}"
// implementation "org.lwjgl:lwjgl-glfw:${lwjglVersion}"
// implementation "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}"
// implementation "org.lwjgl:lwjgl-openal:${lwjglVersion}"
// implementation "org.lwjgl:lwjgl-opencl:${lwjglVersion}"
// implementation "org.lwjgl:lwjgl-opengl:${lwjglVersion}"
// runtime "org.lwjgl:lwjgl:${lwjglVersion}:natives-windows"
// runtime "org.lwjgl:lwjgl:${lwjglVersion}:natives-linux"
// runtime "org.lwjgl:lwjgl:${lwjglVersion}:natives-macos"
// runtime "org.lwjgl:lwjgl-glfw:${lwjglVersion}:natives-windows"
// runtime "org.lwjgl:lwjgl-glfw:${lwjglVersion}:natives-linux"
// runtime "org.lwjgl:lwjgl-glfw:${lwjglVersion}:natives-macos"
// runtime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:natives-windows"
// runtime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:natives-linux"
// runtime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:natives-macos"
// runtime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:natives-windows"
// runtime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:natives-linux"
// runtime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:natives-macos"
// runtime "org.lwjgl:lwjgl-openal:${lwjglVersion}:natives-windows"
// runtime "org.lwjgl:lwjgl-openal:${lwjglVersion}:natives-linux"
// runtime "org.lwjgl:lwjgl-openal:${lwjglVersion}:natives-macos"
}
// Define the main class for the application
@@ -38,7 +64,7 @@ mainClassName = 'markil3.controller.Main'
* TODO - The default zipped distributions are a bit of a mess.
*/
jar {
baseName rootProject.name
baseName rootProject.name + "-desktop"
version rootProject.version
manifest {
attributes "Main-Class": mainClassName,

View File

@@ -22,9 +22,18 @@ plugins {
dependencies {
implementation(project(':desktop')) {
exclude group: jme3.g, module: "jme3-lwjgl3"
exclude module: "jme3-lwjgl3"
exclude group: "org.lwjgl"
}
implementation "${jme3.g}:jme3-lwjgl:${jme3.version}"
// implementation rootProject.files('libs/jme3-lwjgl.jar')
// implementation 'org.lwjgl.lwjgl:lwjgl:2.9.3'
// /*
// * Upgrades the default jinput-2.0.5 to jinput-2.0.9 to fix a bug with gamepads on Linux.
// * See https://hub.jmonkeyengine.org/t/linux-gamepad-input-on-jme3-lwjgl-splits-input-between-two-logical-gamepads
// */
// implementation 'net.java.jinput:jinput:2.0.9'
// implementation 'net.java.jinput:jinput:2.0.9:natives-all'
}
// Define the main class for the application

View File

@@ -18,11 +18,13 @@ targetCompatibility = "1.8"
dependencies {
// Logging
implementation "org.slf4j:slf4j-api:1.7.15"
implementation "org.slf4j:slf4j-api:1.7.30"
implementation "org.slf4j:slf4j-simple:1.7.5"
implementation "${jme3.g}:jme3-core:${jme3.version}"
implementation "${jme3.g}:jme3-testdata:${jme3.version}"
// implementation rootProject.files('libs/jme3-core.jar')
// implementation rootProject.files('libs/jme3-testdata.jar')
}
processResources {

View File

@@ -19,7 +19,6 @@ 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.math.ColorRGBA;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;
@@ -27,6 +26,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -52,8 +52,9 @@ import static markil3.controller.JoystickPreviewScreen.START;
/**
* Provides a series of prompts that will build a controller calibration file.
*
* @author Markil3
* @version 1.1
* @version 1.2
*/
public class CalibrateInputScreen extends BaseAppState
implements RawInputListener, ActionListener
@@ -118,6 +119,8 @@ public class CalibrateInputScreen extends BaseAppState
private Node skipButton;
private Node cancelButton;
private Node restartButton;
private Node yesButton;
private Node noButton;
private JoystickPreviewScreen.GamepadView gamepad;
private BitmapText currentJoystick;
@@ -141,12 +144,17 @@ public class CalibrateInputScreen extends BaseAppState
*/
private boolean triggers2;
private HashMap<String, Object> maps = new HashMap<>();
private HashMap<String, float[]> rangeMaps = new HashMap<>();
private HashMap<String, Boolean> mapBias = new HashMap<>();
private HashMap<Object, Float> defaultValues = new HashMap<>();
private HashMap<Object, float[]> defaultValues = new HashMap<>();
private boolean clear;
private float greatestVal, smallestVal;
/**
* Creates a screen for calibrating and remapping a game controller.
*
* @param calibrationFile - The file to store the results in.
*/
public CalibrateInputScreen(File calibrationFile)
@@ -181,8 +189,9 @@ public class CalibrateInputScreen extends BaseAppState
this.introCont.attachChild(text);
this.startButton =
GUIUtils.createButton(app.getAssetManager(), this.guiFont, app.getContext().getTouchInput() != null,
"start", "Start");
GUIUtils.createButton(app.getAssetManager(), this.guiFont,
app.getContext().getTouchInput() != null, "start",
"Start");
// this.startButton.addClickCommands(this);
this.introCont.attachChild(this.startButton);
@@ -193,17 +202,28 @@ public class CalibrateInputScreen extends BaseAppState
"on the controller you want to calibrate."));
this.skipButton =
GUIUtils.createButton(app.getAssetManager(), this.guiFont, app.getContext().getTouchInput() != null,
"skip", "Skip");
GUIUtils.createButton(app.getAssetManager(), this.guiFont,
app.getContext().getTouchInput() != null, "skip",
"Skip");
this.cancelButton =
GUIUtils.createButton(app.getAssetManager(), this.guiFont, app.getContext().getTouchInput() != null,
"cancel", "Cancel");
GUIUtils.createButton(app.getAssetManager(), this.guiFont,
app.getContext().getTouchInput() != null, "cancel",
"Cancel");
this.introCont.attachChild(this.cancelButton);
this.restartButton =
GUIUtils.createButton(app.getAssetManager(), this.guiFont, app.getContext().getTouchInput() != null,
"close", "Close Application");
GUIUtils.createButton(app.getAssetManager(), this.guiFont,
app.getContext().getTouchInput() != null, "close",
"Close Application");
this.yesButton =
GUIUtils.createButton(app.getAssetManager(), this.guiFont,
app.getContext().getTouchInput() != null, "yes",
"Yes");
this.noButton =
GUIUtils.createButton(app.getAssetManager(), this.guiFont,
app.getContext().getTouchInput() != null, "no",
"No");
this.gui.attachChild(this.introCont);
@@ -260,7 +280,7 @@ public class CalibrateInputScreen extends BaseAppState
case JoystickAxis.POV_X:
if (this.focusedJoyElement instanceof JoystickButton)
{
this.maps.put(this.focusValue > 0 ? DPAD_RIGHT :
this.maps.put(this.currentBias ? DPAD_RIGHT :
DPAD_LEFT, this.focusedJoyElement);
}
else
@@ -272,7 +292,7 @@ public class CalibrateInputScreen extends BaseAppState
case JoystickAxis.POV_Y:
if (this.focusedJoyElement instanceof JoystickButton)
{
this.maps.put(this.focusValue > 0 ? DPAD_UP : DPAD_DOWN,
this.maps.put(this.currentBias ? DPAD_UP : DPAD_DOWN,
this.focusedJoyElement);
}
else
@@ -286,6 +306,17 @@ public class CalibrateInputScreen extends BaseAppState
break;
}
this.mapBias.put(this.currentButton, this.focusValue > 0);
if (this.focusedJoyElement instanceof JoystickAxis)
{
if (!this.rangeMaps.containsKey(this.currentButton))
{
this.rangeMaps.put(this.currentButton, new float[2]);
}
this.rangeMaps.get(this.currentButton)[this.currentBias ?
1 :
0] =
this.greatestVal;
}
this.timeHeld = -1;
this.focusedJoyElement = null;
this.focusValue = 0;
@@ -340,6 +371,7 @@ public class CalibrateInputScreen extends BaseAppState
/**
* Scales and positions elements of this screen.
*
* @param width - The width to scale to.
* @param height - The height to scale to.
*/
@@ -420,6 +452,12 @@ public class CalibrateInputScreen extends BaseAppState
case "close":
this.getApplication().stop();
break;
case "yes":
this.clearUnused();
break;
case "no":
this.recordFile();
break;
}
}
}
@@ -427,8 +465,9 @@ public class CalibrateInputScreen extends BaseAppState
/**
* Set which joystick to use for calibration. This change affects all
* joysticks sharing the same name, so you don't have to run this for
* every controller you have if some of them are identical.
* joysticks sharing the same name, so you don't have to run this for every
* controller you have if some of them are identical.
*
* @param joystick - The joystick to use for calibration.
*/
private void setJoystick(Joystick joystick)
@@ -626,27 +665,50 @@ public class CalibrateInputScreen extends BaseAppState
}
else
{
this.recordFile();
this.promptClearUnused();
}
}
private void promptClearUnused()
{
this.currentStage = null;
this.mainOptions.removeFromParent();
this.gamepad.removeFromParent();
this.introCont.detachAllChildren();
this.introCont.attachChild(this.guiFont.createLabel(
"Do you wish to set all buttons and axes not used to not " +
"trigger?\nThis has the benefit of ensuring unused " +
"buttons don't interfere with\n" +
"anything else."));
this.introCont.attachChild(this.yesButton);
this.introCont.attachChild(this.noButton);
this.gui.attachChild(this.introCont);
this.resize();
}
private void clearUnused()
{
this.clear = true;
this.recordFile();
}
/**
* Saves the calibration settings to the file and prompts for an
* application restart.
* Saves the calibration settings to the file and prompts for an application
* restart.
*/
private void recordFile()
{
/*
* Enable this in JME 3.4.
*/
boolean perComponentEnabled = false;
boolean perComponentEnabled = true;
JoystickAxis axis;
JoystickButton button;
float[] range;
Properties props = new Properties();
this.currentStage = null;
this.mainOptions.removeFromParent();
this.gamepad.removeFromParent();
this.introCont.removeFromParent();
if (!calibrationFile.exists())
{
@@ -665,7 +727,7 @@ public class CalibrateInputScreen extends BaseAppState
this.introCont.attachChild(this.cancelButton);
this.introCont.attachChild(
this.guiFont.createLabel("Error Details:"));
this.listStack(this.introCont, ioe, 0);
this.listStack(this.introCont, ioe);
this.gui.attachChild(this.introCont);
this.resize();
}
@@ -681,13 +743,17 @@ public class CalibrateInputScreen extends BaseAppState
}
finally
{
ArrayList<Object> elements = new ArrayList<>();
elements.addAll(this.joystick.getAxes());
elements.addAll(this.joystick.getButtons());
for (Map.Entry<String, Object> calibrationEntry : this.maps
.entrySet())
{
if (calibrationEntry.getValue() instanceof JoystickButton)
{
button = (JoystickButton) calibrationEntry.getValue();
if (!button.getName().equals(calibrationEntry.getKey()))
if (!button.getName()
.equals(calibrationEntry.getKey()) || clear)
{
props.put((perComponentEnabled ? "button." : "") +
this.joystick.getName() + "." +
@@ -697,11 +763,42 @@ public class CalibrateInputScreen extends BaseAppState
else if (calibrationEntry.getValue() instanceof JoystickAxis)
{
axis = (JoystickAxis) calibrationEntry.getValue();
if (!axis.getName().equals(calibrationEntry.getKey()))
if (!axis.getName()
.equals(calibrationEntry.getKey()) || clear)
{
range = this.rangeMaps.get(calibrationEntry.getKey());
// defaultValue = this.defaultValues.get(axis);
props.put((perComponentEnabled ? "axis." : "") +
this.joystick.getName() + "." + axis.getName(),
calibrationEntry.getKey());
calibrationEntry.getKey() + (perComponentEnabled && range != null ?
("[" + (range[0] != 0 ?
(1.0F / range[0]) :
0) + "," + (
range[1] != 0 ?
(1.0F / range[1]) :
0) + "]") :
""));
}
}
elements.remove(calibrationEntry.getValue());
}
if (this.clear)
{
for (Object element : elements)
{
if (element instanceof JoystickButton)
{
button = (JoystickButton) element;
props.put((perComponentEnabled ? "button." : "") +
this.joystick.getName() + "." +
button.getName(), "null");
}
else if (element instanceof JoystickAxis)
{
axis = (JoystickAxis) element;
props.put((perComponentEnabled ? "axis." : "") +
this.joystick.getName() + "." + axis.getName(),
"null");
}
}
}
@@ -728,7 +825,7 @@ public class CalibrateInputScreen extends BaseAppState
this.introCont.attachChild(this.cancelButton);
this.introCont.attachChild(
this.guiFont.createLabel("Error Details:"));
this.listStack(this.introCont, ioe, 0);
this.listStack(this.introCont, ioe);
this.gui.attachChild(this.introCont);
this.resize();
}
@@ -737,12 +834,12 @@ public class CalibrateInputScreen extends BaseAppState
/**
* Display an error stack trace on the screen.
*
* @param errorCont - The container to use for the error.
* @param error - The error.
* @param depth - How many levels of exceptions throwing exceptions we
* are in. This is for recursively calling the method.
* in. This is for recursively calling the method.
*/
private void listStack(Node errorCont, Throwable error, int depth)
private void listStack(Node errorCont, Throwable error)
{
StringBuilder errorBuilder = new StringBuilder();
Throwable cause = error;
@@ -768,20 +865,24 @@ public class CalibrateInputScreen extends BaseAppState
@Override
public void onJoyAxisEvent(JoyAxisEvent evt)
{
float[] defaultValue = this.defaultValues.get(evt.getAxis());
// this.setJoystick(evt.getAxis().getJoystick());
if (this.joystick != null)
{
if (evt.getValue() != 0 && Math.abs(evt.getValue()) > 0.5 &&
(this.defaultValues.get(evt.getAxis()) == null || Math.abs(
this.defaultValues.get(evt.getAxis()) -
evt.getValue()) > 0.001F))
// TODO - Use getRawValue() in 3.4
if (evt.getRawValue() != 0 && Math.abs(evt.getRawValue()) > 0.5 &&
(defaultValue == null || Math.abs(
defaultValue[0] -
evt.getRawValue()) > 0.001F))
{
if (this.focusedJoyElement != evt.getAxis() ||
this.focusValue != evt.getValue())
this.focusValue != evt.getRawValue())
{
this.focusedJoyElement = evt.getAxis();
this.timeHeld = 0;
this.focusValue = evt.getValue();
this.focusValue = evt.getRawValue();
this.greatestVal = 0;
this.smallestVal = evt.getRawValue();
this.currentElement.setText(
(this.focusValue > 0 ? "+ " : "- ") +
evt.getAxis().getName());
@@ -789,6 +890,17 @@ public class CalibrateInputScreen extends BaseAppState
this.gui.attachChild(this.currentTime);
this.resize();
}
else
{
if (Math.abs(evt.getRawValue()) < Math.abs(this.smallestVal))
{
this.smallestVal = evt.getRawValue();
}
else if (Math.abs(evt.getRawValue()) > Math.abs(this.greatestVal))
{
this.greatestVal = evt.getRawValue();
}
}
}
else
{
@@ -804,8 +916,20 @@ public class CalibrateInputScreen extends BaseAppState
}
else
{
this.defaultValues.put(evt.getAxis(), evt.getValue());
defaultValue = new float[]{evt.getRawValue(), 0, 0};
this.defaultValues.put(evt.getAxis(), defaultValue);
}
// if (defaultValue != null)
// {
// if (evt.getRawValue() < defaultValue[1])
// {
// defaultValue[1] = evt.getRawValue();
// }
// if (evt.getRawValue() > defaultValue[2])
// {
// defaultValue[2] = evt.getRawValue();
// }
// }
}
@Override
@@ -815,7 +939,7 @@ public class CalibrateInputScreen extends BaseAppState
{
if (evt.isPressed() &&
(this.defaultValues.get(evt.getButton()) == null ||
Math.abs(this.defaultValues.get(evt.getButton()) -
Math.abs(this.defaultValues.get(evt.getButton())[0] -
1F) > 0.001F))
{
if (this.focusedJoyElement != evt.getButton() ||
@@ -845,7 +969,8 @@ public class CalibrateInputScreen extends BaseAppState
else
{
this.defaultValues
.put(evt.getButton(), evt.isPressed() ? 1.0F : 0.0F);
.put(evt.getButton(),
new float[]{evt.isPressed() ? 1.0F : 0.0F, 0, 0});
}
if (!evt.isPressed())
{

View File

@@ -47,12 +47,12 @@ import java.util.Map;
/**
* Adding this app state will display a GUI screen showing the controllers
* connected and information on what buttons are pressed. It is primarily
* useful for debugging controllers.
* connected and information on what buttons are pressed. It is primarily useful
* for debugging controllers.
* <p>Note that this class relies on three textures not found in the default
* JME core: "Interface/Joystick/gamepad-buttons.png",
* "Interface/Joystick/gamepad-frame.png," and
* "Interface/Joystick/gamepad-stick.png." These textures can be obtained
* "Interface/Joystick/gamepad-frame.png,"
* and "Interface/Joystick/gamepad-stick.png." These textures can be obtained
* from the org.jmonkeyengine:jme3-testdata library.</p>
*
* @author Markil 3
@@ -61,6 +61,7 @@ import java.util.Map;
* @author Paul Speed
* @author dokthar
* @author Stephen Gold
* @version 1.2
*/
public class JoystickPreviewScreen extends BaseAppState
implements RawInputListener, JoystickConnectionListener, ActionListener
@@ -87,13 +88,13 @@ public class JoystickPreviewScreen extends BaseAppState
public static final String L1 = JoystickButton.BUTTON_4;
public static final String R1 = JoystickButton.BUTTON_5;
/**
* Some gamepads (Xbox controllers notable) will use
* {@link JoystickAxis#LEFT_TRIGGER} instead.
* Some gamepads (Xbox controllers notable) will use {@link
* JoystickAxis#LEFT_TRIGGER} instead.
*/
public static final String L2 = JoystickButton.BUTTON_6;
/**
* Some gamepads (Xbox controllers notable) will use
* {@link JoystickAxis#RIGHT_TRIGGER} instead.
* Some gamepads (Xbox controllers notable) will use {@link
* JoystickAxis#RIGHT_TRIGGER} instead.
*/
public static final String R2 = JoystickButton.BUTTON_7;
public static final String SELECT = JoystickButton.BUTTON_8;
@@ -125,8 +126,8 @@ public class JoystickPreviewScreen extends BaseAppState
final String CLICK_MAPPING = "previewButtonClick";
/**
* This node serves as the center of logic for each gamepad connected to
* the computer.
* This node serves as the center of logic for each gamepad connected to the
* computer.
*/
static class GamepadView extends Node
{
@@ -261,7 +262,7 @@ public class JoystickPreviewScreen extends BaseAppState
}
else if (axis == axis.getJoystick().getYAxis())
{
setYAxis(-value);
setYAxis(value);
}
else if (axis == axis.getJoystick().getAxis(JoystickAxis.Z_AXIS))
{
@@ -280,7 +281,7 @@ public class JoystickPreviewScreen extends BaseAppState
else if (axis ==
axis.getJoystick().getAxis(JoystickAxis.Z_ROTATION))
{
setZRotation(-value);
setZRotation(value);
}
else if (axis ==
axis.getJoystick().getAxis(JoystickAxis.LEFT_TRIGGER))
@@ -467,8 +468,8 @@ public class JoystickPreviewScreen extends BaseAppState
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);
float y = FastMath.sin(-angle) * length * 10;
leftStick.setLocalTranslation(xBase + x, yBase - y, 0);
xBase = 291;
dir = new Vector2f(zAxis, zRotation);
@@ -477,8 +478,8 @@ public class JoystickPreviewScreen extends BaseAppState
angle = dir.getAngle();
x = FastMath.cos(angle) * length * 10;
y = FastMath.sin(angle) * length * 10;
rightStick.setLocalTranslation(xBase + x, yBase + y, 0);
y = FastMath.sin(-angle) * length * 10;
rightStick.setLocalTranslation(xBase + x, yBase - y, 0);
}
}
@@ -531,8 +532,9 @@ public class JoystickPreviewScreen extends BaseAppState
/**
* Checks to see if the visual displays if the button is pressed.
* @return True if the visual displays that the button is pressed,
* false otherwise.
*
* @return True if the visual displays that the button is pressed, false
* otherwise.
*/
public boolean isDown()
{
@@ -541,6 +543,7 @@ public class JoystickPreviewScreen extends BaseAppState
/**
* Updates the button to display that it is pressed.
*
* @see #up()
*/
public void down()
@@ -551,6 +554,7 @@ public class JoystickPreviewScreen extends BaseAppState
/**
* Updates the button to display that it is not pressed.
*
* @see #down()
*/
public void up()
@@ -699,8 +703,9 @@ public class JoystickPreviewScreen extends BaseAppState
/**
* Obtain the size of the screen based on the game camera.
* @return The screen size in a two-dimensional float vector. Note that
* the numbers will always be integers.
*
* @return The screen size in a two-dimensional float vector. Note that the
* numbers will always be integers.
*/
private Vector2f getScreenSize()
{
@@ -738,11 +743,15 @@ public class JoystickPreviewScreen extends BaseAppState
/**
* Updates the values of the gamepad labels as buttons and axis are
* manipulated.
*
* @param joy - The gamepad to update.
*/
private void setLabels(Joystick joy)
{
int offset = this.getApplication().getContext().getTouchInput() != null ? 10: 0;
int offset =
this.getApplication().getContext().getTouchInput() != null ?
10 :
0;
/*
* Removes the old labels.
*/
@@ -767,7 +776,9 @@ public class JoystickPreviewScreen extends BaseAppState
// "Gamepad " + joy.getJoyId() + ": " + joy.getName());
this.labels[joy.getJoyId()][0] =
this.guiFont.createLabel(joy.getName());
this.labels[joy.getJoyId()][0].setLocalTranslation(20, -25 - offset, 0);
this.labels[joy.getJoyId()][0].setLocalTranslation(20,
-25 - offset,
0);
this.gamepadCont[joy.getJoyId()]
.attachChild(this.labels[joy.getJoyId()][0]);
/*
@@ -780,7 +791,9 @@ public class JoystickPreviewScreen extends BaseAppState
*/
this.labels[joy.getJoyId()][1] = this.guiFont
.createLabel("Axis Index: Axis Name (logical ID, axis ID)");
this.labels[joy.getJoyId()][1].setLocalTranslation(20, -50 - offset, 0);
this.labels[joy.getJoyId()][1].setLocalTranslation(20,
-50 - offset,
0);
this.gamepadCont[joy.getJoyId()]
.attachChild(this.labels[joy.getJoyId()][1]);
/*
@@ -804,7 +817,7 @@ public class JoystickPreviewScreen extends BaseAppState
/*
* The current value of the axis.
*/
BitmapText label2 = this.guiFont.createLabel("-1.0");
BitmapText label2 = this.guiFont.createLabel("0.0");
label2.setLocalTranslation(label.getLocalTranslation()
.add(label.getLineWidth(), 0, 0));
this.labels[joy.getJoyId()][i * 2 + 2] = label2;
@@ -907,6 +920,7 @@ public class JoystickPreviewScreen extends BaseAppState
/**
* Scales and positions elements of this screen.
*
* @param width - The width to scale to.
* @param height - The height to scale to.
*/
@@ -919,7 +933,11 @@ public class JoystickPreviewScreen extends BaseAppState
for (int i = 0, l = this.gamepadHeaders.length; i < l; i++)
{
button = this.gamepadHeaders[i];
button.setLocalTranslation((this.getApplication().getContext().getTouchInput() != null ? 192 : 128) * i, 0, 0);
button.setLocalTranslation((this.getApplication()
.getContext()
.getTouchInput() != null ?
192 :
128) * i, 0, 0);
}
}
if (this.gamepadView != null)
@@ -1015,8 +1033,9 @@ public class JoystickPreviewScreen extends BaseAppState
}
/**
* Displays which button is which as the user hovers over the button.
* TODO - Doesn't trigger.
* Displays which button is which as the user hovers over the button. TODO -
* Doesn't trigger.
*
* @param evt - Input event data.
*/
@Override
@@ -1055,6 +1074,7 @@ public class JoystickPreviewScreen extends BaseAppState
/**
* Triggers the gamepad tab buttons.
*
* @param evt - Input event data.
*/
@Override