DasherJava / src / dasherJava / core / input / JoystickInput.java
JoystickInput.java
Raw
package dasherJava.core.input;

import java.io.File;

import dasherJava.DasherJava;
import dasherJava.core.startStop.StartStopAction;
import net.java.games.input.Component;
import net.java.games.input.Controller;
import net.java.games.input.ControllerEnvironment;

public class JoystickInput implements InputProvider {
	
	private final Controller joystick;
	private final Component componentX;
	private final Component componentY;
	private final Component componentStartStop;
	private final float sensitivityX;
	private final float sensitivityY;
	private final float offsetX;
	private final float offsetY;
	private boolean lastButtonPressed = false;
	
	//JInput unfortunately does not provide a way to check if the required libraries/plugins failed to load or
	//if there actually are no connected controllers. It simply prints out any errors it encounters to the log
	//and to System.err, with no way to catch and/or properly report them to the user.
	
	static {
		System.setProperty("net.java.games.input.librarypath", DasherJava.BASE_DIRECTORY+File.separator+"libs"
				+File.separator);
		System.setProperty("jinput.loglevel", "WARNING"); //hide all JInput log output below warning level
	}
	
	public JoystickInput(String joystickName, String componentNameX, String componentNameY,
	                     String componentNameStartStop, float sensitivityX, float sensitivityY, float offsetX,
	                     float offsetY) throws JoystickNotFoundException {
		this.sensitivityX=sensitivityX;
		this.sensitivityY=sensitivityY;
		this.offsetX=offsetX;
		this.offsetY=offsetY;
		Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers();
		for (Controller controller : controllers) {
			if (controller.getName().equals(joystickName)) {
				joystick=controller;
				componentX=getComponentByName(controller, componentNameX);
				componentY=getComponentByName(controller, componentNameY);
				componentStartStop=getComponentByName(controller, componentNameStartStop);
				return;
			}
		}
		throw new JoystickNotFoundException("Joystick \""+joystickName+"\" not found");
	}
	
	public static String getConnectedControllersInfo() {
		Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers();
		StringBuilder sb = new StringBuilder("Number of controllers: ");
		sb.append(controllers.length);
		for (Controller controller : controllers) {
			sb.append("\nController \"");
			sb.append(controller.getName());
			sb.append("\", type: ");
			sb.append(controller.getType());
			for (Component component : controller.getComponents()) {
				sb.append("\n  ");
				if (component.isAnalog()) {
					sb.append(component.isRelative() ? "Relative" : "Absolute");
					sb.append(" axis");
				} else sb.append("Button");
				sb.append(" \"");
				sb.append(component.getName());
				sb.append("\"");
			}
		}
		return sb.toString();
	}
	
	@Override
	public float getInputX() {
		float value = 0.0f; //no axis selected
		if (componentX!=null) {
			joystick.poll();
			value=componentX.getPollData();
		}
		return InputProvider.clampToInputRange(value*sensitivityX+offsetX);
	}
	
	@Override
	public float getInputY() {
		float value = 0.0f; //no axis selected
		if (componentY!=null) {
			joystick.poll();
			value=componentY.getPollData();
		}
		return InputProvider.clampToInputRange(value*sensitivityY+offsetY);
	}
	
	@Override
	public StartStopAction getStartStopAction() {
		if (componentStartStop==null) return StartStopAction.NOTHING; //no button selected
		joystick.poll();
		boolean buttonPressed = componentStartStop.getPollData()==1.0f;
		if (buttonPressed && !lastButtonPressed) {
			lastButtonPressed=true;
			return StartStopAction.TOGGLE;
		}
		lastButtonPressed=buttonPressed;
		return StartStopAction.NOTHING;
	}
	
	private static Component getComponentByName(Controller controller, String componentName)
			throws JoystickNotFoundException {
		if (componentName.isEmpty()) return null;
		for (Component component : controller.getComponents()) {
			if (component.getName().equals(componentName)) return component;
		}
		throw new JoystickNotFoundException("Component \""+componentName+"\" of joystick \""+controller.getName()
				+"\" not found");
	}
	
	public static class JoystickNotFoundException extends Exception {
		public JoystickNotFoundException(String message) {
			super(message);
		}
	}
}