diff --git a/pom.xml b/pom.xml
index 796fce56..fdc1bf38 100644
--- a/pom.xml
+++ b/pom.xml
@@ -115,6 +115,8 @@
org/newdawn/slick/GameContainer.*
org/newdawn/slick/Image.*
org/newdawn/slick/Music.*
+ org/newdawn/slick/Input.*
+ org/newdawn/slick/Input$NullOutputStream.*
org/newdawn/slick/gui/TextField.*
org/newdawn/slick/openal/AudioInputStream*
org/newdawn/slick/openal/OpenALStreamPlayer*
diff --git a/src/org/newdawn/slick/Input.java b/src/org/newdawn/slick/Input.java
new file mode 100644
index 00000000..1066ca34
--- /dev/null
+++ b/src/org/newdawn/slick/Input.java
@@ -0,0 +1,1568 @@
+/*
+ * Copyright (c) 2013, Slick2D
+ * 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 the Slick2D 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 org.newdawn.slick;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.lwjgl.LWJGLException;
+import org.lwjgl.input.Controller;
+import org.lwjgl.input.Controllers;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.Display;
+import org.newdawn.slick.util.Log;
+
+/**
+ * A wrapped for all keyboard, mouse and controller input
+ *
+ * @author kevin
+ */
+@SuppressWarnings({"rawtypes", "unchecked", "unused"})
+public class Input {
+ /** The controller index to pass to check all controllers */
+ public static final int ANY_CONTROLLER = -1;
+
+ /** The maximum number of buttons on controllers */
+ private static final int MAX_BUTTONS = 100;
+
+ /** */
+ public static final int KEY_ESCAPE = 0x01;
+ /** */
+ public static final int KEY_1 = 0x02;
+ /** */
+ public static final int KEY_2 = 0x03;
+ /** */
+ public static final int KEY_3 = 0x04;
+ /** */
+ public static final int KEY_4 = 0x05;
+ /** */
+ public static final int KEY_5 = 0x06;
+ /** */
+ public static final int KEY_6 = 0x07;
+ /** */
+ public static final int KEY_7 = 0x08;
+ /** */
+ public static final int KEY_8 = 0x09;
+ /** */
+ public static final int KEY_9 = 0x0A;
+ /** */
+ public static final int KEY_0 = 0x0B;
+ /** */
+ public static final int KEY_MINUS = 0x0C; /* - on main keyboard */
+ /** */
+ public static final int KEY_EQUALS = 0x0D;
+ /** */
+ public static final int KEY_BACK = 0x0E; /* backspace */
+ /** */
+ public static final int KEY_TAB = 0x0F;
+ /** */
+ public static final int KEY_Q = 0x10;
+ /** */
+ public static final int KEY_W = 0x11;
+ /** */
+ public static final int KEY_E = 0x12;
+ /** */
+ public static final int KEY_R = 0x13;
+ /** */
+ public static final int KEY_T = 0x14;
+ /** */
+ public static final int KEY_Y = 0x15;
+ /** */
+ public static final int KEY_U = 0x16;
+ /** */
+ public static final int KEY_I = 0x17;
+ /** */
+ public static final int KEY_O = 0x18;
+ /** */
+ public static final int KEY_P = 0x19;
+ /** */
+ public static final int KEY_LBRACKET = 0x1A;
+ /** */
+ public static final int KEY_RBRACKET = 0x1B;
+ /** */
+ public static final int KEY_RETURN = 0x1C; /* Enter on main keyboard */
+ /** */
+ public static final int KEY_ENTER = 0x1C; /* Enter on main keyboard */
+ /** */
+ public static final int KEY_LCONTROL = 0x1D;
+ /** */
+ public static final int KEY_A = 0x1E;
+ /** */
+ public static final int KEY_S = 0x1F;
+ /** */
+ public static final int KEY_D = 0x20;
+ /** */
+ public static final int KEY_F = 0x21;
+ /** */
+ public static final int KEY_G = 0x22;
+ /** */
+ public static final int KEY_H = 0x23;
+ /** */
+ public static final int KEY_J = 0x24;
+ /** */
+ public static final int KEY_K = 0x25;
+ /** */
+ public static final int KEY_L = 0x26;
+ /** */
+ public static final int KEY_SEMICOLON = 0x27;
+ /** */
+ public static final int KEY_APOSTROPHE = 0x28;
+ /** */
+ public static final int KEY_GRAVE = 0x29; /* accent grave */
+ /** */
+ public static final int KEY_LSHIFT = 0x2A;
+ /** */
+ public static final int KEY_BACKSLASH = 0x2B;
+ /** */
+ public static final int KEY_Z = 0x2C;
+ /** */
+ public static final int KEY_X = 0x2D;
+ /** */
+ public static final int KEY_C = 0x2E;
+ /** */
+ public static final int KEY_V = 0x2F;
+ /** */
+ public static final int KEY_B = 0x30;
+ /** */
+ public static final int KEY_N = 0x31;
+ /** */
+ public static final int KEY_M = 0x32;
+ /** */
+ public static final int KEY_COMMA = 0x33;
+ /** */
+ public static final int KEY_PERIOD = 0x34; /* . on main keyboard */
+ /** */
+ public static final int KEY_SLASH = 0x35; /* / on main keyboard */
+ /** */
+ public static final int KEY_RSHIFT = 0x36;
+ /** */
+ public static final int KEY_MULTIPLY = 0x37; /* * on numeric keypad */
+ /** */
+ public static final int KEY_LMENU = 0x38; /* left Alt */
+ /** */
+ public static final int KEY_SPACE = 0x39;
+ /** */
+ public static final int KEY_CAPITAL = 0x3A;
+ /** */
+ public static final int KEY_F1 = 0x3B;
+ /** */
+ public static final int KEY_F2 = 0x3C;
+ /** */
+ public static final int KEY_F3 = 0x3D;
+ /** */
+ public static final int KEY_F4 = 0x3E;
+ /** */
+ public static final int KEY_F5 = 0x3F;
+ /** */
+ public static final int KEY_F6 = 0x40;
+ /** */
+ public static final int KEY_F7 = 0x41;
+ /** */
+ public static final int KEY_F8 = 0x42;
+ /** */
+ public static final int KEY_F9 = 0x43;
+ /** */
+ public static final int KEY_F10 = 0x44;
+ /** */
+ public static final int KEY_NUMLOCK = 0x45;
+ /** */
+ public static final int KEY_SCROLL = 0x46; /* Scroll Lock */
+ /** */
+ public static final int KEY_NUMPAD7 = 0x47;
+ /** */
+ public static final int KEY_NUMPAD8 = 0x48;
+ /** */
+ public static final int KEY_NUMPAD9 = 0x49;
+ /** */
+ public static final int KEY_SUBTRACT = 0x4A; /* - on numeric keypad */
+ /** */
+ public static final int KEY_NUMPAD4 = 0x4B;
+ /** */
+ public static final int KEY_NUMPAD5 = 0x4C;
+ /** */
+ public static final int KEY_NUMPAD6 = 0x4D;
+ /** */
+ public static final int KEY_ADD = 0x4E; /* + on numeric keypad */
+ /** */
+ public static final int KEY_NUMPAD1 = 0x4F;
+ /** */
+ public static final int KEY_NUMPAD2 = 0x50;
+ /** */
+ public static final int KEY_NUMPAD3 = 0x51;
+ /** */
+ public static final int KEY_NUMPAD0 = 0x52;
+ /** */
+ public static final int KEY_DECIMAL = 0x53; /* . on numeric keypad */
+ /** */
+ public static final int KEY_F11 = 0x57;
+ /** */
+ public static final int KEY_F12 = 0x58;
+ /** */
+ public static final int KEY_F13 = 0x64; /* (NEC PC98) */
+ /** */
+ public static final int KEY_F14 = 0x65; /* (NEC PC98) */
+ /** */
+ public static final int KEY_F15 = 0x66; /* (NEC PC98) */
+ /** */
+ public static final int KEY_KANA = 0x70; /* (Japanese keyboard) */
+ /** */
+ public static final int KEY_CONVERT = 0x79; /* (Japanese keyboard) */
+ /** */
+ public static final int KEY_NOCONVERT = 0x7B; /* (Japanese keyboard) */
+ /** */
+ public static final int KEY_YEN = 0x7D; /* (Japanese keyboard) */
+ /** */
+ public static final int KEY_NUMPADEQUALS = 0x8D; /* = on numeric keypad (NEC PC98) */
+ /** */
+ public static final int KEY_CIRCUMFLEX = 0x90; /* (Japanese keyboard) */
+ /** */
+ public static final int KEY_AT = 0x91; /* (NEC PC98) */
+ /** */
+ public static final int KEY_COLON = 0x92; /* (NEC PC98) */
+ /** */
+ public static final int KEY_UNDERLINE = 0x93; /* (NEC PC98) */
+ /** */
+ public static final int KEY_KANJI = 0x94; /* (Japanese keyboard) */
+ /** */
+ public static final int KEY_STOP = 0x95; /* (NEC PC98) */
+ /** */
+ public static final int KEY_AX = 0x96; /* (Japan AX) */
+ /** */
+ public static final int KEY_UNLABELED = 0x97; /* (J3100) */
+ /** */
+ public static final int KEY_NUMPADENTER = 0x9C; /* Enter on numeric keypad */
+ /** */
+ public static final int KEY_RCONTROL = 0x9D;
+ /** */
+ public static final int KEY_NUMPADCOMMA = 0xB3; /* , on numeric keypad (NEC PC98) */
+ /** */
+ public static final int KEY_DIVIDE = 0xB5; /* / on numeric keypad */
+ /** */
+ public static final int KEY_SYSRQ = 0xB7;
+ /** */
+ public static final int KEY_RMENU = 0xB8; /* right Alt */
+ /** */
+ public static final int KEY_PAUSE = 0xC5; /* Pause */
+ /** */
+ public static final int KEY_HOME = 0xC7; /* Home on arrow keypad */
+ /** */
+ public static final int KEY_UP = 0xC8; /* UpArrow on arrow keypad */
+ /** */
+ public static final int KEY_PRIOR = 0xC9; /* PgUp on arrow keypad */
+ /** */
+ public static final int KEY_LEFT = 0xCB; /* LeftArrow on arrow keypad */
+ /** */
+ public static final int KEY_RIGHT = 0xCD; /* RightArrow on arrow keypad */
+ /** */
+ public static final int KEY_END = 0xCF; /* End on arrow keypad */
+ /** */
+ public static final int KEY_DOWN = 0xD0; /* DownArrow on arrow keypad */
+ /** */
+ public static final int KEY_NEXT = 0xD1; /* PgDn on arrow keypad */
+ /** */
+ public static final int KEY_INSERT = 0xD2; /* Insert on arrow keypad */
+ /** */
+ public static final int KEY_DELETE = 0xD3; /* Delete on arrow keypad */
+ /** */
+ public static final int KEY_LWIN = 0xDB; /* Left Windows key */
+ /** */
+ public static final int KEY_RWIN = 0xDC; /* Right Windows key */
+ /** */
+ public static final int KEY_APPS = 0xDD; /* AppMenu key */
+ /** */
+ public static final int KEY_POWER = 0xDE;
+ /** */
+ public static final int KEY_SLEEP = 0xDF;
+
+ /** A helper for left ALT */
+ public static final int KEY_LALT = KEY_LMENU;
+ /** A helper for right ALT */
+ public static final int KEY_RALT = KEY_RMENU;
+
+ /** Control index */
+ private static final int LEFT = 0;
+ /** Control index */
+ private static final int RIGHT = 1;
+ /** Control index */
+ private static final int UP = 2;
+ /** Control index */
+ private static final int DOWN = 3;
+ /** Control index */
+ private static final int BUTTON1 = 4;
+ /** Control index */
+ private static final int BUTTON2 = 5;
+ /** Control index */
+ private static final int BUTTON3 = 6;
+ /** Control index */
+ private static final int BUTTON4 = 7;
+ /** Control index */
+ private static final int BUTTON5 = 8;
+ /** Control index */
+ private static final int BUTTON6 = 9;
+ /** Control index */
+ private static final int BUTTON7 = 10;
+ /** Control index */
+ private static final int BUTTON8 = 11;
+ /** Control index */
+ private static final int BUTTON9 = 12;
+ /** Control index */
+ private static final int BUTTON10 = 13;
+
+ /** The left mouse button indicator */
+ public static final int MOUSE_LEFT_BUTTON = 0;
+ /** The right mouse button indicator */
+ public static final int MOUSE_RIGHT_BUTTON = 1;
+ /** The middle mouse button indicator */
+ public static final int MOUSE_MIDDLE_BUTTON = 2;
+
+ /** True if the controllers system has been initialised */
+ private static boolean controllersInited = false;
+ /** The list of controllers */
+ private static ArrayList controllers = new ArrayList();
+
+ /** The last recorded mouse x position */
+ private int lastMouseX;
+ /** The last recorded mouse y position */
+ private int lastMouseY;
+ /** THe state of the mouse buttons */
+ protected boolean[] mousePressed = new boolean[10];
+ /** THe state of the controller buttons */
+ private boolean[][] controllerPressed = new boolean[100][MAX_BUTTONS];
+
+ /** The character values representing the pressed keys */
+ protected char[] keys = new char[1024];
+ /** True if the key has been pressed since last queries */
+ protected boolean[] pressed = new boolean[1024];
+ /** The time since the next key repeat to be fired for the key */
+ protected long[] nextRepeat = new long[1024];
+
+ /** The control states from the controllers */
+ private boolean[][] controls = new boolean[10][MAX_BUTTONS+10];
+ /** True if the event has been consumed */
+ protected boolean consumed = false;
+ /** A list of listeners to be notified of input events */
+ protected HashSet allListeners = new HashSet();
+ /** The listeners to notify of key events */
+ protected ArrayList keyListeners = new ArrayList();
+ /** The listener to add */
+ protected ArrayList keyListenersToAdd = new ArrayList();
+ /** The listeners to notify of mouse events */
+ protected ArrayList mouseListeners = new ArrayList();
+ /** The listener to add */
+ protected ArrayList mouseListenersToAdd = new ArrayList();
+ /** The listener to nofiy of controller events */
+ protected ArrayList controllerListeners = new ArrayList();
+ /** The current value of the wheel */
+ private int wheel;
+ /** The height of the display */
+ private int height;
+
+ /** True if the display is active */
+ private boolean displayActive = true;
+
+ /** True if key repeat is enabled */
+ private boolean keyRepeat;
+ /** The initial delay for key repeat starts */
+ private int keyRepeatInitial;
+ /** The interval of key repeat */
+ private int keyRepeatInterval;
+
+ /** True if the input is currently paused */
+ private boolean paused;
+ /** The scale to apply to screen coordinates */
+ private float scaleX = 1;
+ /** The scale to apply to screen coordinates */
+ private float scaleY = 1;
+ /** The offset to apply to screen coordinates */
+ private float xoffset = 0;
+ /** The offset to apply to screen coordinates */
+ private float yoffset = 0;
+
+ /** The delay before determining a single or double click */
+ private int doubleClickDelay = 250;
+ /** The timer running out for a single click */
+ private long doubleClickTimeout = 0;
+
+ /** The clicked x position */
+ private int clickX;
+ /** The clicked y position */
+ private int clickY;
+ /** The clicked button */
+ private int clickButton;
+
+ /** The x position location the mouse was pressed */
+ private int pressedX = -1;
+
+ /** The x position location the mouse was pressed */
+ private int pressedY = -1;
+
+ /** The pixel distance the mouse can move to accept a mouse click */
+ private int mouseClickTolerance = 5;
+
+ /**
+ * Disables support for controllers. This means the jinput JAR and native libs
+ * are not required.
+ */
+ public static void disableControllers() {
+ controllersInited = true;
+ }
+
+ /**
+ * Create a new input with the height of the screen
+ *
+ * @param height The height of the screen
+ */
+ public Input(int height) {
+ init(height);
+ }
+
+ /**
+ * Set the double click interval, the time between the first
+ * and second clicks that should be interpreted as a
+ * double click.
+ *
+ * @param delay The delay between clicks
+ */
+ public void setDoubleClickInterval(int delay) {
+ doubleClickDelay = delay;
+ }
+
+ /**
+ * Set the pixel distance the mouse can move to accept a mouse click.
+ * Default is 5.
+ *
+ * @param mouseClickTolerance The number of pixels.
+ */
+ public void setMouseClickTolerance (int mouseClickTolerance) {
+ this.mouseClickTolerance = mouseClickTolerance;
+ }
+
+ /**
+ * Set the scaling to apply to screen coordinates
+ *
+ * @param scaleX The scaling to apply to the horizontal axis
+ * @param scaleY The scaling to apply to the vertical axis
+ */
+ public void setScale(float scaleX, float scaleY) {
+ this.scaleX = scaleX;
+ this.scaleY = scaleY;
+ }
+
+ /**
+ * Set the offset to apply to the screen coodinates
+ *
+ * @param xoffset The offset on the x-axis
+ * @param yoffset The offset on the y-axis
+ */
+ public void setOffset(float xoffset, float yoffset) {
+ this.xoffset = xoffset;
+ this.yoffset = yoffset;
+ }
+
+ /**
+ * Reset the transformation being applied to the input to the default
+ */
+ public void resetInputTransform() {
+ setOffset(0, 0);
+ setScale(1, 1);
+ }
+
+ /**
+ * Add a listener to be notified of input events
+ *
+ * @param listener The listener to be notified
+ */
+ public void addListener(InputListener listener) {
+ addKeyListener(listener);
+ addMouseListener(listener);
+ addControllerListener(listener);
+ }
+
+ /**
+ * Add a key listener to be notified of key input events
+ *
+ * @param listener The listener to be notified
+ */
+ public void addKeyListener(KeyListener listener) {
+ keyListenersToAdd.add(listener);
+ }
+
+ /**
+ * Add a key listener to be notified of key input events
+ *
+ * @param listener The listener to be notified
+ */
+ private void addKeyListenerImpl(KeyListener listener) {
+ if (keyListeners.contains(listener)) {
+ return;
+ }
+ keyListeners.add(listener);
+ allListeners.add(listener);
+ }
+
+ /**
+ * Add a mouse listener to be notified of mouse input events
+ *
+ * @param listener The listener to be notified
+ */
+ public void addMouseListener(MouseListener listener) {
+ mouseListenersToAdd.add(listener);
+ }
+
+ /**
+ * Add a mouse listener to be notified of mouse input events
+ *
+ * @param listener The listener to be notified
+ */
+ private void addMouseListenerImpl(MouseListener listener) {
+ if (mouseListeners.contains(listener)) {
+ return;
+ }
+ mouseListeners.add(listener);
+ allListeners.add(listener);
+ }
+
+ /**
+ * Add a controller listener to be notified of controller input events
+ *
+ * @param listener The listener to be notified
+ */
+ public void addControllerListener(ControllerListener listener) {
+ if (controllerListeners.contains(listener)) {
+ return;
+ }
+ controllerListeners.add(listener);
+ allListeners.add(listener);
+ }
+
+ /**
+ * Remove all the listeners from this input
+ */
+ public void removeAllListeners() {
+ removeAllKeyListeners();
+ removeAllMouseListeners();
+ removeAllControllerListeners();
+ }
+
+ /**
+ * Remove all the key listeners from this input
+ */
+ public void removeAllKeyListeners() {
+ allListeners.removeAll(keyListeners);
+ keyListeners.clear();
+ }
+
+ /**
+ * Remove all the mouse listeners from this input
+ */
+ public void removeAllMouseListeners() {
+ allListeners.removeAll(mouseListeners);
+ mouseListeners.clear();
+ }
+
+ /**
+ * Remove all the controller listeners from this input
+ */
+ public void removeAllControllerListeners() {
+ allListeners.removeAll(controllerListeners);
+ controllerListeners.clear();
+ }
+
+ /**
+ * Add a listener to be notified of input events. This listener
+ * will get events before others that are currently registered
+ *
+ * @param listener The listener to be notified
+ */
+ public void addPrimaryListener(InputListener listener) {
+ removeListener(listener);
+
+ keyListeners.add(0, listener);
+ mouseListeners.add(0, listener);
+ controllerListeners.add(0, listener);
+
+ allListeners.add(listener);
+ }
+
+ /**
+ * Remove a listener that will no longer be notified
+ *
+ * @param listener The listen to be removed
+ */
+ public void removeListener(InputListener listener) {
+ removeKeyListener(listener);
+ removeMouseListener(listener);
+ removeControllerListener(listener);
+ }
+
+ /**
+ * Remove a key listener that will no longer be notified
+ *
+ * @param listener The listen to be removed
+ */
+ public void removeKeyListener(KeyListener listener) {
+ keyListeners.remove(listener);
+
+ if (!mouseListeners.contains(listener) && !controllerListeners.contains(listener)) {
+ allListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Remove a controller listener that will no longer be notified
+ *
+ * @param listener The listen to be removed
+ */
+ public void removeControllerListener(ControllerListener listener) {
+ controllerListeners.remove(listener);
+
+ if (!mouseListeners.contains(listener) && !keyListeners.contains(listener)) {
+ allListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Remove a mouse listener that will no longer be notified
+ *
+ * @param listener The listen to be removed
+ */
+ public void removeMouseListener(MouseListener listener) {
+ mouseListeners.remove(listener);
+
+ if (!controllerListeners.contains(listener) && !keyListeners.contains(listener)) {
+ allListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Initialise the input system
+ *
+ * @param height The height of the window
+ */
+ void init(int height) {
+ this.height = height;
+ lastMouseX = getMouseX();
+ lastMouseY = getMouseY();
+ }
+
+ /**
+ * Get the character representation of the key identified by the specified code
+ *
+ * @param code The key code of the key to retrieve the name of
+ * @return The name or character representation of the key requested
+ */
+ public static String getKeyName(int code) {
+ return Keyboard.getKeyName(code);
+ }
+
+ /**
+ * Check if a particular key has been pressed since this method
+ * was last called for the specified key
+ *
+ * @param code The key code of the key to check
+ * @return True if the key has been pressed
+ */
+ public boolean isKeyPressed(int code) {
+ if (pressed[code]) {
+ pressed[code] = false;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if a mouse button has been pressed since last call
+ *
+ * @param button The button to check
+ * @return True if the button has been pressed since last call
+ */
+ public boolean isMousePressed(int button) {
+ if (mousePressed[button]) {
+ mousePressed[button] = false;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if a controller button has been pressed since last
+ * time
+ *
+ * @param button The button to check for (note that this includes directional controls first)
+ * @return True if the button has been pressed since last time
+ */
+ public boolean isControlPressed(int button) {
+ return isControlPressed(button, 0);
+ }
+
+ /**
+ * Check if a controller button has been pressed since last
+ * time
+ *
+ * @param controller The index of the controller to check
+ * @param button The button to check for (note that this includes directional controls first)
+ * @return True if the button has been pressed since last time
+ */
+ public boolean isControlPressed(int button, int controller) {
+ if (controllerPressed[controller][button]) {
+ controllerPressed[controller][button] = false;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Clear the state for isControlPressed method. This will reset all
+ * controls to not pressed
+ */
+ public void clearControlPressedRecord() {
+ for (int i=0;iisKeyPressed method. This will
+ * resort in all keys returning that they haven't been pressed, until
+ * they are pressed again
+ */
+ public void clearKeyPressedRecord() {
+ Arrays.fill(pressed, false);
+ }
+
+ /**
+ * Clear the state for the isMousePressed
method. This will
+ * resort in all mouse buttons returning that they haven't been pressed, until
+ * they are pressed again
+ */
+ public void clearMousePressedRecord() {
+ Arrays.fill(mousePressed, false);
+ }
+
+ /**
+ * Check if a particular key is down
+ *
+ * @param code The key code of the key to check
+ * @return True if the key is down
+ */
+ public boolean isKeyDown(int code) {
+ return Keyboard.isKeyDown(code);
+ }
+
+ /**
+ * Get the absolute x position of the mouse cursor within the container
+ *
+ * @return The absolute x position of the mouse cursor
+ */
+ public int getAbsoluteMouseX() {
+ return Mouse.getX();
+ }
+
+ /**
+ * Get the absolute y position of the mouse cursor within the container
+ *
+ * @return The absolute y position of the mouse cursor
+ */
+ public int getAbsoluteMouseY() {
+ return height - Mouse.getY();
+ }
+
+ /**
+ * Get the x position of the mouse cursor
+ *
+ * @return The x position of the mouse cursor
+ */
+ public int getMouseX() {
+ return (int) ((Mouse.getX() * scaleX)+xoffset);
+ }
+
+ /**
+ * Get the y position of the mouse cursor
+ *
+ * @return The y position of the mouse cursor
+ */
+ public int getMouseY() {
+ return (int) (((height-Mouse.getY()) * scaleY)+yoffset);
+ }
+
+ /**
+ * Check if a given mouse button is down
+ *
+ * @param button The index of the button to check (starting at 0)
+ * @return True if the mouse button is down
+ */
+ public boolean isMouseButtonDown(int button) {
+ return Mouse.isButtonDown(button);
+ }
+
+ /**
+ * Check if any mouse button is down
+ *
+ * @return True if any mouse button is down
+ */
+ private boolean anyMouseDown() {
+ for (int i=0;i<3;i++) {
+ if (Mouse.isButtonDown(i)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get a count of the number of controlles available
+ *
+ * @return The number of controllers available
+ */
+ public int getControllerCount() {
+ try {
+ initControllers();
+ } catch (SlickException e) {
+ throw new RuntimeException("Failed to initialise controllers");
+ }
+
+ return controllers.size();
+ }
+
+ /**
+ * Get the number of axis that are avaiable on a given controller
+ *
+ * @param controller The index of the controller to check
+ * @return The number of axis available on the controller
+ */
+ public int getAxisCount(int controller) {
+ return ((Controller) controllers.get(controller)).getAxisCount();
+ }
+
+ /**
+ * Get the value of the axis with the given index
+ *
+ * @param controller The index of the controller to check
+ * @param axis The index of the axis to read
+ * @return The axis value at time of reading
+ */
+ public float getAxisValue(int controller, int axis) {
+ return ((Controller) controllers.get(controller)).getAxisValue(axis);
+ }
+
+ /**
+ * Get the name of the axis with the given index
+ *
+ * @param controller The index of the controller to check
+ * @param axis The index of the axis to read
+ * @return The name of the specified axis
+ */
+ public String getAxisName(int controller, int axis) {
+ return ((Controller) controllers.get(controller)).getAxisName(axis);
+ }
+
+ /**
+ * Check if the controller has the left direction pressed
+ *
+ * @param controller The index of the controller to check
+ * @return True if the controller is pressed to the left
+ */
+ public boolean isControllerLeft(int controller) {
+ if (controller >= getControllerCount()) {
+ return false;
+ }
+
+ if (controller == ANY_CONTROLLER) {
+ for (int i=0;i= getControllerCount()) {
+ return false;
+ }
+
+ if (controller == ANY_CONTROLLER) {
+ for (int i=0;i 0.5f
+ || ((Controller) controllers.get(controller)).getPovX() > 0.5f;
+ }
+
+ /**
+ * Check if the controller has the up direction pressed
+ *
+ * @param controller The index of the controller to check
+ * @return True if the controller is pressed to the up
+ */
+ public boolean isControllerUp(int controller) {
+ if (controller >= getControllerCount()) {
+ return false;
+ }
+
+ if (controller == ANY_CONTROLLER) {
+ for (int i=0;i= getControllerCount()) {
+ return false;
+ }
+
+ if (controller == ANY_CONTROLLER) {
+ for (int i=0;i 0.5f
+ || ((Controller) controllers.get(controller)).getPovY() > 0.5f;
+
+ }
+
+ /**
+ * Check if controller button is pressed
+ *
+ * @param controller The index of the controller to check
+ * @param index The index of the button to check
+ * @return True if the button is pressed
+ */
+ public boolean isButtonPressed(int index, int controller) {
+ if (controller >= getControllerCount()) {
+ return false;
+ }
+
+ if (controller == ANY_CONTROLLER) {
+ for (int i=0;i= 3) && (controller.getButtonCount() < MAX_BUTTONS)) {
+ controllers.add(controller);
+ }
+ }
+
+ Log.info("Found "+controllers.size()+" controllers");
+ for (int i=0;i doubleClickTimeout) {
+ doubleClickTimeout = 0;
+ }
+ }
+
+ this.height = height;
+
+ Iterator allStarts = allListeners.iterator();
+ while (allStarts.hasNext()) {
+ ControlledInputReciever listener = (ControlledInputReciever) allStarts.next();
+ listener.inputStarted();
+ }
+
+ while (Keyboard.next()) {
+ if (Keyboard.getEventKeyState()) {
+ int eventKey = resolveEventKey(Keyboard.getEventKey(), Keyboard.getEventCharacter());
+
+ keys[eventKey] = Keyboard.getEventCharacter();
+ pressed[eventKey] = true;
+ nextRepeat[eventKey] = System.currentTimeMillis() + keyRepeatInitial;
+
+ consumed = false;
+ for (int i=0;i= 0) {
+ if (Mouse.getEventButtonState()) {
+ consumed = false;
+ mousePressed[Mouse.getEventButton()] = true;
+
+ pressedX = (int) (xoffset + (Mouse.getEventX() * scaleX));
+ pressedY = (int) (yoffset + ((height-Mouse.getEventY()) * scaleY));
+
+ for (int i=0;i nextRepeat[i]) {
+ nextRepeat[i] = System.currentTimeMillis() + keyRepeatInterval;
+ consumed = false;
+ for (int j=0;j= BUTTON1) {
+ return isButtonPressed((index-BUTTON1), controllerIndex);
+ }
+
+ throw new RuntimeException("Unknown control index");
+ }
+
+
+ /**
+ * Pauses the polling and sending of input events.
+ */
+ public void pause() {
+ paused = true;
+
+ // Reset all polling arrays
+ clearKeyPressedRecord();
+ clearMousePressedRecord();
+ clearControlPressedRecord();
+ }
+
+ /**
+ * Resumes the polling and sending of input events.
+ */
+ public void resume() {
+ paused = false;
+ }
+
+ /**
+ * Notify listeners that the mouse button has been clicked
+ *
+ * @param button The button that has been clicked
+ * @param x The location at which the button was clicked
+ * @param y The location at which the button was clicked
+ * @param clickCount The number of times the button was clicked (single or double click)
+ */
+ private void fireMouseClicked(int button, int x, int y, int clickCount) {
+ consumed = false;
+ for (int i=0;i