Path: blob/master/SLICK_HOME/src/org/newdawn/slick/Input.java
1456 views
package org.newdawn.slick;12import java.io.IOException;3import java.io.OutputStream;4import java.util.ArrayList;5import java.util.Arrays;6import java.util.HashSet;7import java.util.Iterator;89import org.lwjgl.LWJGLException;10import org.lwjgl.input.Controller;11import org.lwjgl.input.Controllers;12import org.lwjgl.input.Keyboard;13import org.lwjgl.input.Mouse;14import org.lwjgl.opengl.Display;15import org.newdawn.slick.util.Log;1617/**18* A wrapped for all keyboard, mouse and controller input19*20* @author kevin21*/22public class Input {23/** The controller index to pass to check all controllers */24public static final int ANY_CONTROLLER = -1;2526/** The maximum number of buttons on controllers */27private static final int MAX_BUTTONS = 100;2829/** */30public static final int KEY_ESCAPE = 0x01;31/** */32public static final int KEY_1 = 0x02;33/** */34public static final int KEY_2 = 0x03;35/** */36public static final int KEY_3 = 0x04;37/** */38public static final int KEY_4 = 0x05;39/** */40public static final int KEY_5 = 0x06;41/** */42public static final int KEY_6 = 0x07;43/** */44public static final int KEY_7 = 0x08;45/** */46public static final int KEY_8 = 0x09;47/** */48public static final int KEY_9 = 0x0A;49/** */50public static final int KEY_0 = 0x0B;51/** */52public static final int KEY_MINUS = 0x0C; /* - on main keyboard */53/** */54public static final int KEY_EQUALS = 0x0D;55/** */56public static final int KEY_BACK = 0x0E; /* backspace */57/** */58public static final int KEY_TAB = 0x0F;59/** */60public static final int KEY_Q = 0x10;61/** */62public static final int KEY_W = 0x11;63/** */64public static final int KEY_E = 0x12;65/** */66public static final int KEY_R = 0x13;67/** */68public static final int KEY_T = 0x14;69/** */70public static final int KEY_Y = 0x15;71/** */72public static final int KEY_U = 0x16;73/** */74public static final int KEY_I = 0x17;75/** */76public static final int KEY_O = 0x18;77/** */78public static final int KEY_P = 0x19;79/** */80public static final int KEY_LBRACKET = 0x1A;81/** */82public static final int KEY_RBRACKET = 0x1B;83/** */84public static final int KEY_RETURN = 0x1C; /* Enter on main keyboard */85/** */86public static final int KEY_ENTER = 0x1C; /* Enter on main keyboard */87/** */88public static final int KEY_LCONTROL = 0x1D;89/** */90public static final int KEY_A = 0x1E;91/** */92public static final int KEY_S = 0x1F;93/** */94public static final int KEY_D = 0x20;95/** */96public static final int KEY_F = 0x21;97/** */98public static final int KEY_G = 0x22;99/** */100public static final int KEY_H = 0x23;101/** */102public static final int KEY_J = 0x24;103/** */104public static final int KEY_K = 0x25;105/** */106public static final int KEY_L = 0x26;107/** */108public static final int KEY_SEMICOLON = 0x27;109/** */110public static final int KEY_APOSTROPHE = 0x28;111/** */112public static final int KEY_GRAVE = 0x29; /* accent grave */113/** */114public static final int KEY_LSHIFT = 0x2A;115/** */116public static final int KEY_BACKSLASH = 0x2B;117/** */118public static final int KEY_Z = 0x2C;119/** */120public static final int KEY_X = 0x2D;121/** */122public static final int KEY_C = 0x2E;123/** */124public static final int KEY_V = 0x2F;125/** */126public static final int KEY_B = 0x30;127/** */128public static final int KEY_N = 0x31;129/** */130public static final int KEY_M = 0x32;131/** */132public static final int KEY_COMMA = 0x33;133/** */134public static final int KEY_PERIOD = 0x34; /* . on main keyboard */135/** */136public static final int KEY_SLASH = 0x35; /* / on main keyboard */137/** */138public static final int KEY_RSHIFT = 0x36;139/** */140public static final int KEY_MULTIPLY = 0x37; /* * on numeric keypad */141/** */142public static final int KEY_LMENU = 0x38; /* left Alt */143/** */144public static final int KEY_SPACE = 0x39;145/** */146public static final int KEY_CAPITAL = 0x3A;147/** */148public static final int KEY_F1 = 0x3B;149/** */150public static final int KEY_F2 = 0x3C;151/** */152public static final int KEY_F3 = 0x3D;153/** */154public static final int KEY_F4 = 0x3E;155/** */156public static final int KEY_F5 = 0x3F;157/** */158public static final int KEY_F6 = 0x40;159/** */160public static final int KEY_F7 = 0x41;161/** */162public static final int KEY_F8 = 0x42;163/** */164public static final int KEY_F9 = 0x43;165/** */166public static final int KEY_F10 = 0x44;167/** */168public static final int KEY_NUMLOCK = 0x45;169/** */170public static final int KEY_SCROLL = 0x46; /* Scroll Lock */171/** */172public static final int KEY_NUMPAD7 = 0x47;173/** */174public static final int KEY_NUMPAD8 = 0x48;175/** */176public static final int KEY_NUMPAD9 = 0x49;177/** */178public static final int KEY_SUBTRACT = 0x4A; /* - on numeric keypad */179/** */180public static final int KEY_NUMPAD4 = 0x4B;181/** */182public static final int KEY_NUMPAD5 = 0x4C;183/** */184public static final int KEY_NUMPAD6 = 0x4D;185/** */186public static final int KEY_ADD = 0x4E; /* + on numeric keypad */187/** */188public static final int KEY_NUMPAD1 = 0x4F;189/** */190public static final int KEY_NUMPAD2 = 0x50;191/** */192public static final int KEY_NUMPAD3 = 0x51;193/** */194public static final int KEY_NUMPAD0 = 0x52;195/** */196public static final int KEY_DECIMAL = 0x53; /* . on numeric keypad */197/** */198public static final int KEY_F11 = 0x57;199/** */200public static final int KEY_F12 = 0x58;201/** */202public static final int KEY_F13 = 0x64; /* (NEC PC98) */203/** */204public static final int KEY_F14 = 0x65; /* (NEC PC98) */205/** */206public static final int KEY_F15 = 0x66; /* (NEC PC98) */207/** */208public static final int KEY_KANA = 0x70; /* (Japanese keyboard) */209/** */210public static final int KEY_CONVERT = 0x79; /* (Japanese keyboard) */211/** */212public static final int KEY_NOCONVERT = 0x7B; /* (Japanese keyboard) */213/** */214public static final int KEY_YEN = 0x7D; /* (Japanese keyboard) */215/** */216public static final int KEY_NUMPADEQUALS = 0x8D; /* = on numeric keypad (NEC PC98) */217/** */218public static final int KEY_CIRCUMFLEX = 0x90; /* (Japanese keyboard) */219/** */220public static final int KEY_AT = 0x91; /* (NEC PC98) */221/** */222public static final int KEY_COLON = 0x92; /* (NEC PC98) */223/** */224public static final int KEY_UNDERLINE = 0x93; /* (NEC PC98) */225/** */226public static final int KEY_KANJI = 0x94; /* (Japanese keyboard) */227/** */228public static final int KEY_STOP = 0x95; /* (NEC PC98) */229/** */230public static final int KEY_AX = 0x96; /* (Japan AX) */231/** */232public static final int KEY_UNLABELED = 0x97; /* (J3100) */233/** */234public static final int KEY_NUMPADENTER = 0x9C; /* Enter on numeric keypad */235/** */236public static final int KEY_RCONTROL = 0x9D;237/** */238public static final int KEY_NUMPADCOMMA = 0xB3; /* , on numeric keypad (NEC PC98) */239/** */240public static final int KEY_DIVIDE = 0xB5; /* / on numeric keypad */241/** */242public static final int KEY_SYSRQ = 0xB7;243/** */244public static final int KEY_RMENU = 0xB8; /* right Alt */245/** */246public static final int KEY_PAUSE = 0xC5; /* Pause */247/** */248public static final int KEY_HOME = 0xC7; /* Home on arrow keypad */249/** */250public static final int KEY_UP = 0xC8; /* UpArrow on arrow keypad */251/** */252public static final int KEY_PRIOR = 0xC9; /* PgUp on arrow keypad */253/** */254public static final int KEY_LEFT = 0xCB; /* LeftArrow on arrow keypad */255/** */256public static final int KEY_RIGHT = 0xCD; /* RightArrow on arrow keypad */257/** */258public static final int KEY_END = 0xCF; /* End on arrow keypad */259/** */260public static final int KEY_DOWN = 0xD0; /* DownArrow on arrow keypad */261/** */262public static final int KEY_NEXT = 0xD1; /* PgDn on arrow keypad */263/** */264public static final int KEY_INSERT = 0xD2; /* Insert on arrow keypad */265/** */266public static final int KEY_DELETE = 0xD3; /* Delete on arrow keypad */267/** */268public static final int KEY_LWIN = 0xDB; /* Left Windows key */269/** */270public static final int KEY_RWIN = 0xDC; /* Right Windows key */271/** */272public static final int KEY_APPS = 0xDD; /* AppMenu key */273/** */274public static final int KEY_POWER = 0xDE;275/** */276public static final int KEY_SLEEP = 0xDF;277278/** A helper for left ALT */279public static final int KEY_LALT = KEY_LMENU;280/** A helper for right ALT */281public static final int KEY_RALT = KEY_RMENU;282283/** Control index */284private static final int LEFT = 0;285/** Control index */286private static final int RIGHT = 1;287/** Control index */288private static final int UP = 2;289/** Control index */290private static final int DOWN = 3;291/** Control index */292private static final int BUTTON1 = 4;293/** Control index */294private static final int BUTTON2 = 5;295/** Control index */296private static final int BUTTON3 = 6;297/** Control index */298private static final int BUTTON4 = 7;299/** Control index */300private static final int BUTTON5 = 8;301/** Control index */302private static final int BUTTON6 = 9;303/** Control index */304private static final int BUTTON7 = 10;305/** Control index */306private static final int BUTTON8 = 11;307/** Control index */308private static final int BUTTON9 = 12;309/** Control index */310private static final int BUTTON10 = 13;311312/** The left mouse button indicator */313public static final int MOUSE_LEFT_BUTTON = 0;314/** The right mouse button indicator */315public static final int MOUSE_RIGHT_BUTTON = 1;316/** The middle mouse button indicator */317public static final int MOUSE_MIDDLE_BUTTON = 2;318319/** True if the controllers system has been initialised */320private static boolean controllersInited = false;321/** The list of controllers */322private static ArrayList controllers = new ArrayList();323324/** The last recorded mouse x position */325private int lastMouseX;326/** The last recorded mouse y position */327private int lastMouseY;328/** THe state of the mouse buttons */329protected boolean[] mousePressed = new boolean[10];330/** THe state of the controller buttons */331private boolean[][] controllerPressed = new boolean[100][MAX_BUTTONS];332333/** The character values representing the pressed keys */334protected char[] keys = new char[1024];335/** True if the key has been pressed since last queries */336protected boolean[] pressed = new boolean[1024];337/** The time since the next key repeat to be fired for the key */338protected long[] nextRepeat = new long[1024];339340/** The control states from the controllers */341private boolean[][] controls = new boolean[10][MAX_BUTTONS+10];342/** True if the event has been consumed */343protected boolean consumed = false;344/** A list of listeners to be notified of input events */345protected HashSet allListeners = new HashSet();346/** The listeners to notify of key events */347protected ArrayList keyListeners = new ArrayList();348/** The listener to add */349protected ArrayList keyListenersToAdd = new ArrayList();350/** The listeners to notify of mouse events */351protected ArrayList mouseListeners = new ArrayList();352/** The listener to add */353protected ArrayList mouseListenersToAdd = new ArrayList();354/** The listener to nofiy of controller events */355protected ArrayList controllerListeners = new ArrayList();356/** The current value of the wheel */357private int wheel;358/** The height of the display */359private int height;360361/** True if the display is active */362private boolean displayActive = true;363364/** True if key repeat is enabled */365private boolean keyRepeat;366/** The initial delay for key repeat starts */367private int keyRepeatInitial;368/** The interval of key repeat */369private int keyRepeatInterval;370371/** True if the input is currently paused */372private boolean paused;373/** The scale to apply to screen coordinates */374private float scaleX = 1;375/** The scale to apply to screen coordinates */376private float scaleY = 1;377/** The offset to apply to screen coordinates */378private float xoffset = 0;379/** The offset to apply to screen coordinates */380private float yoffset = 0;381382/** The delay before determining a single or double click */383private int doubleClickDelay = 250;384/** The timer running out for a single click */385private long doubleClickTimeout = 0;386387/** The clicked x position */388private int clickX;389/** The clicked y position */390private int clickY;391/** The clicked button */392private int clickButton;393394/** The x position location the mouse was pressed */395private int pressedX = -1;396397/** The x position location the mouse was pressed */398private int pressedY = -1;399400/** The pixel distance the mouse can move to accept a mouse click */401private int mouseClickTolerance = 5;402403/**404* Disables support for controllers. This means the jinput JAR and native libs405* are not required.406*/407public static void disableControllers() {408controllersInited = true;409}410411/**412* Create a new input with the height of the screen413*414* @param height The height of the screen415*/416public Input(int height) {417init(height);418}419420/**421* Set the double click interval, the time between the first422* and second clicks that should be interpreted as a423* double click.424*425* @param delay The delay between clicks426*/427public void setDoubleClickInterval(int delay) {428doubleClickDelay = delay;429}430431/**432* Set the pixel distance the mouse can move to accept a mouse click.433* Default is 5.434*435* @param mouseClickTolerance The number of pixels.436*/437public void setMouseClickTolerance (int mouseClickTolerance) {438this.mouseClickTolerance = mouseClickTolerance;439}440441/**442* Set the scaling to apply to screen coordinates443*444* @param scaleX The scaling to apply to the horizontal axis445* @param scaleY The scaling to apply to the vertical axis446*/447public void setScale(float scaleX, float scaleY) {448this.scaleX = scaleX;449this.scaleY = scaleY;450}451452/**453* Set the offset to apply to the screen coodinates454*455* @param xoffset The offset on the x-axis456* @param yoffset The offset on the y-axis457*/458public void setOffset(float xoffset, float yoffset) {459this.xoffset = xoffset;460this.yoffset = yoffset;461}462463/**464* Reset the transformation being applied to the input to the default465*/466public void resetInputTransform() {467setOffset(0, 0);468setScale(1, 1);469}470471/**472* Add a listener to be notified of input events473*474* @param listener The listener to be notified475*/476public void addListener(InputListener listener) {477addKeyListener(listener);478addMouseListener(listener);479addControllerListener(listener);480}481482/**483* Add a key listener to be notified of key input events484*485* @param listener The listener to be notified486*/487public void addKeyListener(KeyListener listener) {488keyListenersToAdd.add(listener);489}490491/**492* Add a key listener to be notified of key input events493*494* @param listener The listener to be notified495*/496private void addKeyListenerImpl(KeyListener listener) {497if (keyListeners.contains(listener)) {498return;499}500keyListeners.add(listener);501allListeners.add(listener);502}503504/**505* Add a mouse listener to be notified of mouse input events506*507* @param listener The listener to be notified508*/509public void addMouseListener(MouseListener listener) {510mouseListenersToAdd.add(listener);511}512513/**514* Add a mouse listener to be notified of mouse input events515*516* @param listener The listener to be notified517*/518private void addMouseListenerImpl(MouseListener listener) {519if (mouseListeners.contains(listener)) {520return;521}522mouseListeners.add(listener);523allListeners.add(listener);524}525526/**527* Add a controller listener to be notified of controller input events528*529* @param listener The listener to be notified530*/531public void addControllerListener(ControllerListener listener) {532if (controllerListeners.contains(listener)) {533return;534}535controllerListeners.add(listener);536allListeners.add(listener);537}538539/**540* Remove all the listeners from this input541*/542public void removeAllListeners() {543removeAllKeyListeners();544removeAllMouseListeners();545removeAllControllerListeners();546}547548/**549* Remove all the key listeners from this input550*/551public void removeAllKeyListeners() {552allListeners.removeAll(keyListeners);553keyListeners.clear();554}555556/**557* Remove all the mouse listeners from this input558*/559public void removeAllMouseListeners() {560allListeners.removeAll(mouseListeners);561mouseListeners.clear();562}563564/**565* Remove all the controller listeners from this input566*/567public void removeAllControllerListeners() {568allListeners.removeAll(controllerListeners);569controllerListeners.clear();570}571572/**573* Add a listener to be notified of input events. This listener574* will get events before others that are currently registered575*576* @param listener The listener to be notified577*/578public void addPrimaryListener(InputListener listener) {579removeListener(listener);580581keyListeners.add(0, listener);582mouseListeners.add(0, listener);583controllerListeners.add(0, listener);584585allListeners.add(listener);586}587588/**589* Remove a listener that will no longer be notified590*591* @param listener The listen to be removed592*/593public void removeListener(InputListener listener) {594removeKeyListener(listener);595removeMouseListener(listener);596removeControllerListener(listener);597}598599/**600* Remove a key listener that will no longer be notified601*602* @param listener The listen to be removed603*/604public void removeKeyListener(KeyListener listener) {605keyListeners.remove(listener);606607if (!mouseListeners.contains(listener) && !controllerListeners.contains(listener)) {608allListeners.remove(listener);609}610}611612/**613* Remove a controller listener that will no longer be notified614*615* @param listener The listen to be removed616*/617public void removeControllerListener(ControllerListener listener) {618controllerListeners.remove(listener);619620if (!mouseListeners.contains(listener) && !keyListeners.contains(listener)) {621allListeners.remove(listener);622}623}624625/**626* Remove a mouse listener that will no longer be notified627*628* @param listener The listen to be removed629*/630public void removeMouseListener(MouseListener listener) {631mouseListeners.remove(listener);632633if (!controllerListeners.contains(listener) && !keyListeners.contains(listener)) {634allListeners.remove(listener);635}636}637638/**639* Initialise the input system640*641* @param height The height of the window642*/643void init(int height) {644this.height = height;645lastMouseX = getMouseX();646lastMouseY = getMouseY();647}648649/**650* Get the character representation of the key identified by the specified code651*652* @param code The key code of the key to retrieve the name of653* @return The name or character representation of the key requested654*/655public static String getKeyName(int code) {656return Keyboard.getKeyName(code);657}658659/**660* Check if a particular key has been pressed since this method661* was last called for the specified key662*663* @param code The key code of the key to check664* @return True if the key has been pressed665*/666public boolean isKeyPressed(int code) {667if (pressed[code]) {668pressed[code] = false;669return true;670}671672return false;673}674675/**676* Check if a mouse button has been pressed since last call677*678* @param button The button to check679* @return True if the button has been pressed since last call680*/681public boolean isMousePressed(int button) {682if (mousePressed[button]) {683mousePressed[button] = false;684return true;685}686687return false;688}689690/**691* Check if a controller button has been pressed since last692* time693*694* @param button The button to check for (note that this includes directional controls first)695* @return True if the button has been pressed since last time696*/697public boolean isControlPressed(int button) {698return isControlPressed(button, 0);699}700701/**702* Check if a controller button has been pressed since last703* time704*705* @param controller The index of the controller to check706* @param button The button to check for (note that this includes directional controls first)707* @return True if the button has been pressed since last time708*/709public boolean isControlPressed(int button, int controller) {710if (controllerPressed[controller][button]) {711controllerPressed[controller][button] = false;712return true;713}714715return false;716}717718/**719* Clear the state for isControlPressed method. This will reset all720* controls to not pressed721*/722public void clearControlPressedRecord() {723for (int i=0;i<controllers.size();i++) {724Arrays.fill(controllerPressed[i], false);725}726}727728/**729* Clear the state for the <code>isKeyPressed</code> method. This will730* resort in all keys returning that they haven't been pressed, until731* they are pressed again732*/733public void clearKeyPressedRecord() {734Arrays.fill(pressed, false);735}736737/**738* Clear the state for the <code>isMousePressed</code> method. This will739* resort in all mouse buttons returning that they haven't been pressed, until740* they are pressed again741*/742public void clearMousePressedRecord() {743Arrays.fill(mousePressed, false);744}745746/**747* Check if a particular key is down748*749* @param code The key code of the key to check750* @return True if the key is down751*/752public boolean isKeyDown(int code) {753return Keyboard.isKeyDown(code);754}755756/**757* Get the absolute x position of the mouse cursor within the container758*759* @return The absolute x position of the mouse cursor760*/761public int getAbsoluteMouseX() {762return Mouse.getX();763}764765/**766* Get the absolute y position of the mouse cursor within the container767*768* @return The absolute y position of the mouse cursor769*/770public int getAbsoluteMouseY() {771return height - Mouse.getY();772}773774/**775* Get the x position of the mouse cursor776*777* @return The x position of the mouse cursor778*/779public int getMouseX() {780return (int) ((Mouse.getX() * scaleX)+xoffset);781}782783/**784* Get the y position of the mouse cursor785*786* @return The y position of the mouse cursor787*/788public int getMouseY() {789return (int) (((height-Mouse.getY()) * scaleY)+yoffset);790}791792/**793* Check if a given mouse button is down794*795* @param button The index of the button to check (starting at 0)796* @return True if the mouse button is down797*/798public boolean isMouseButtonDown(int button) {799return Mouse.isButtonDown(button);800}801802/**803* Check if any mouse button is down804*805* @return True if any mouse button is down806*/807private boolean anyMouseDown() {808for (int i=0;i<3;i++) {809if (Mouse.isButtonDown(i)) {810return true;811}812}813814return false;815}816817/**818* Get a count of the number of controlles available819*820* @return The number of controllers available821*/822public int getControllerCount() {823try {824initControllers();825} catch (SlickException e) {826throw new RuntimeException("Failed to initialise controllers");827}828829return controllers.size();830}831832/**833* Get the number of axis that are avaiable on a given controller834*835* @param controller The index of the controller to check836* @return The number of axis available on the controller837*/838public int getAxisCount(int controller) {839return ((Controller) controllers.get(controller)).getAxisCount();840}841842/**843* Get the value of the axis with the given index844*845* @param controller The index of the controller to check846* @param axis The index of the axis to read847* @return The axis value at time of reading848*/849public float getAxisValue(int controller, int axis) {850return ((Controller) controllers.get(controller)).getAxisValue(axis);851}852853/**854* Get the name of the axis with the given index855*856* @param controller The index of the controller to check857* @param axis The index of the axis to read858* @return The name of the specified axis859*/860public String getAxisName(int controller, int axis) {861return ((Controller) controllers.get(controller)).getAxisName(axis);862}863864/**865* Check if the controller has the left direction pressed866*867* @param controller The index of the controller to check868* @return True if the controller is pressed to the left869*/870public boolean isControllerLeft(int controller) {871if (controller >= getControllerCount()) {872return false;873}874875if (controller == ANY_CONTROLLER) {876for (int i=0;i<controllers.size();i++) {877if (isControllerLeft(i)) {878return true;879}880}881882return false;883}884885return ((Controller) controllers.get(controller)).getXAxisValue() < -0.5f886|| ((Controller) controllers.get(controller)).getPovX() < -0.5f;887}888889/**890* Check if the controller has the right direction pressed891*892* @param controller The index of the controller to check893* @return True if the controller is pressed to the right894*/895public boolean isControllerRight(int controller) {896if (controller >= getControllerCount()) {897return false;898}899900if (controller == ANY_CONTROLLER) {901for (int i=0;i<controllers.size();i++) {902if (isControllerRight(i)) {903return true;904}905}906907return false;908}909910return ((Controller) controllers.get(controller)).getXAxisValue() > 0.5f911|| ((Controller) controllers.get(controller)).getPovX() > 0.5f;912}913914/**915* Check if the controller has the up direction pressed916*917* @param controller The index of the controller to check918* @return True if the controller is pressed to the up919*/920public boolean isControllerUp(int controller) {921if (controller >= getControllerCount()) {922return false;923}924925if (controller == ANY_CONTROLLER) {926for (int i=0;i<controllers.size();i++) {927if (isControllerUp(i)) {928return true;929}930}931932return false;933}934return ((Controller) controllers.get(controller)).getYAxisValue() < -0.5f935|| ((Controller) controllers.get(controller)).getPovY() < -0.5f;936}937938/**939* Check if the controller has the down direction pressed940*941* @param controller The index of the controller to check942* @return True if the controller is pressed to the down943*/944public boolean isControllerDown(int controller) {945if (controller >= getControllerCount()) {946return false;947}948949if (controller == ANY_CONTROLLER) {950for (int i=0;i<controllers.size();i++) {951if (isControllerDown(i)) {952return true;953}954}955956return false;957}958959return ((Controller) controllers.get(controller)).getYAxisValue() > 0.5f960|| ((Controller) controllers.get(controller)).getPovY() > 0.5f;961962}963964/**965* Check if controller button is pressed966*967* @param controller The index of the controller to check968* @param index The index of the button to check969* @return True if the button is pressed970*/971public boolean isButtonPressed(int index, int controller) {972if (controller >= getControllerCount()) {973return false;974}975976if (controller == ANY_CONTROLLER) {977for (int i=0;i<controllers.size();i++) {978if (isButtonPressed(index, i)) {979return true;980}981}982983return false;984}985986return ((Controller) controllers.get(controller)).isButtonPressed(index);987}988989/**990* Check if button 1 is pressed991*992* @param controller The index of the controller to check993* @return True if the button is pressed994*/995public boolean isButton1Pressed(int controller) {996return isButtonPressed(0, controller);997}998999/**1000* Check if button 2 is pressed1001*1002* @param controller The index of the controller to check1003* @return True if the button is pressed1004*/1005public boolean isButton2Pressed(int controller) {1006return isButtonPressed(1, controller);1007}10081009/**1010* Check if button 3 is pressed1011*1012* @param controller The index of the controller to check1013* @return True if the button is pressed1014*/1015public boolean isButton3Pressed(int controller) {1016return isButtonPressed(2, controller);1017}10181019/**1020* Initialise the controllers system1021*1022* @throws SlickException Indicates a failure to use the hardware1023*/1024public void initControllers() throws SlickException {1025if (controllersInited) {1026return;1027}10281029controllersInited = true;1030try {1031Controllers.create();1032int count = Controllers.getControllerCount();10331034for (int i = 0; i < count; i++) {1035Controller controller = Controllers.getController(i);10361037if ((controller.getButtonCount() >= 3) && (controller.getButtonCount() < MAX_BUTTONS)) {1038controllers.add(controller);1039}1040}10411042Log.info("Found "+controllers.size()+" controllers");1043for (int i=0;i<controllers.size();i++) {1044Log.info(i+" : "+((Controller) controllers.get(i)).getName());1045}1046} catch (LWJGLException e) {1047if (e.getCause() instanceof ClassNotFoundException) {1048throw new SlickException("Unable to create controller - no jinput found - add jinput.jar to your classpath");1049}1050throw new SlickException("Unable to create controllers");1051} catch (NoClassDefFoundError e) {1052// forget it, no jinput availble1053}1054}10551056/**1057* Notification from an event handle that an event has been consumed1058*/1059public void consumeEvent() {1060consumed = true;1061}10621063/**1064* A null stream to clear out those horrid errors1065*1066* @author kevin1067*/1068private class NullOutputStream extends OutputStream {1069/**1070* @see java.io.OutputStream#write(int)1071*/1072public void write(int b) throws IOException {1073// null implemetnation1074}10751076}10771078/**1079* Hook to allow us to translate any key character into special key1080* codes for easier use.1081*1082* @param key The original key code1083* @param c The character that was fired1084* @return The key code to fire1085*/1086private int resolveEventKey(int key, char c) {1087// BUG with LWJGL - equals comes back with keycode = 01088// See: http://slick.javaunlimited.net/viewtopic.php?t=6171089if ((c == 61) || (key == 0)) {1090return KEY_EQUALS;1091}10921093return key;1094}10951096/**1097* Notification that the mouse has been pressed and hence we1098* should consider what we're doing with double clicking1099*1100* @param button The button pressed/released1101* @param x The location of the mouse1102* @param y The location of the mouse1103*/1104public void considerDoubleClick(int button, int x, int y) {1105if (doubleClickTimeout == 0) {1106clickX = x;1107clickY = y;1108clickButton = button;1109doubleClickTimeout = System.currentTimeMillis() + doubleClickDelay;1110fireMouseClicked(button, x, y, 1);1111} else {1112if (clickButton == button) {1113if ((System.currentTimeMillis() < doubleClickTimeout)) {1114fireMouseClicked(button, x, y, 2);1115doubleClickTimeout = 0;1116}1117}1118}1119}11201121/**1122* Poll the state of the input1123*1124* @param width The width of the game view1125* @param height The height of the game view1126*/1127public void poll(int width, int height) {1128if (paused) {1129while (Keyboard.next()) {}1130while (Mouse.next()) {}1131return;1132}11331134// add any listeners requested since last time1135for (int i=0;i<keyListenersToAdd.size();i++) {1136addKeyListenerImpl((KeyListener) keyListenersToAdd.get(i));1137}1138keyListenersToAdd.clear();1139for (int i=0;i<mouseListenersToAdd.size();i++) {1140addMouseListenerImpl((MouseListener) mouseListenersToAdd.get(i));1141}1142mouseListenersToAdd.clear();11431144if (doubleClickTimeout != 0) {1145if (System.currentTimeMillis() > doubleClickTimeout) {1146doubleClickTimeout = 0;1147}1148}11491150this.height = height;11511152Iterator allStarts = allListeners.iterator();1153while (allStarts.hasNext()) {1154ControlledInputReciever listener = (ControlledInputReciever) allStarts.next();1155listener.inputStarted();1156}11571158while (Keyboard.next()) {1159if (Keyboard.getEventKeyState()) {1160int eventKey = resolveEventKey(Keyboard.getEventKey(), Keyboard.getEventCharacter());11611162keys[eventKey] = Keyboard.getEventCharacter();1163pressed[eventKey] = true;1164nextRepeat[eventKey] = System.currentTimeMillis() + keyRepeatInitial;11651166consumed = false;1167for (int i=0;i<keyListeners.size();i++) {1168KeyListener listener = (KeyListener) keyListeners.get(i);11691170if (listener.isAcceptingInput()) {1171listener.keyPressed(eventKey, Keyboard.getEventCharacter());1172if (consumed) {1173break;1174}1175}1176}1177} else {1178int eventKey = resolveEventKey(Keyboard.getEventKey(), Keyboard.getEventCharacter());1179nextRepeat[eventKey] = 0;11801181consumed = false;1182for (int i=0;i<keyListeners.size();i++) {1183KeyListener listener = (KeyListener) keyListeners.get(i);1184if (listener.isAcceptingInput()) {1185listener.keyReleased(eventKey, keys[eventKey]);1186if (consumed) {1187break;1188}1189}1190}1191}1192}11931194while (Mouse.next()) {1195if (Mouse.getEventButton() >= 0) {1196if (Mouse.getEventButtonState()) {1197consumed = false;1198mousePressed[Mouse.getEventButton()] = true;11991200pressedX = (int) (xoffset + (Mouse.getEventX() * scaleX));1201pressedY = (int) (yoffset + ((height-Mouse.getEventY()) * scaleY));12021203for (int i=0;i<mouseListeners.size();i++) {1204MouseListener listener = (MouseListener) mouseListeners.get(i);1205if (listener.isAcceptingInput()) {1206listener.mousePressed(Mouse.getEventButton(), pressedX, pressedY);1207if (consumed) {1208break;1209}1210}1211}1212} else {1213consumed = false;1214mousePressed[Mouse.getEventButton()] = false;12151216int releasedX = (int) (xoffset + (Mouse.getEventX() * scaleX));1217int releasedY = (int) (yoffset + ((height-Mouse.getEventY()) * scaleY));1218if ((pressedX != -1) &&1219(pressedY != -1) &&1220(Math.abs(pressedX - releasedX) < mouseClickTolerance) &&1221(Math.abs(pressedY - releasedY) < mouseClickTolerance)) {1222considerDoubleClick(Mouse.getEventButton(), releasedX, releasedY);1223pressedX = pressedY = -1;1224}12251226for (int i=0;i<mouseListeners.size();i++) {1227MouseListener listener = (MouseListener) mouseListeners.get(i);1228if (listener.isAcceptingInput()) {1229listener.mouseReleased(Mouse.getEventButton(), releasedX, releasedY);1230if (consumed) {1231break;1232}1233}1234}1235}1236} else {1237if (Mouse.isGrabbed()) {1238if ((Mouse.getEventDX() != 0) || (Mouse.getEventDY() != 0)) {1239consumed = false;1240for (int i=0;i<mouseListeners.size();i++) {1241MouseListener listener = (MouseListener) mouseListeners.get(i);1242if (listener.isAcceptingInput()) {1243if (anyMouseDown()) {1244listener.mouseDragged(0, 0, Mouse.getEventDX(), -Mouse.getEventDY());1245} else {1246listener.mouseMoved(0, 0, Mouse.getEventDX(), -Mouse.getEventDY());1247}12481249if (consumed) {1250break;1251}1252}1253}1254}1255}12561257int dwheel = Mouse.getEventDWheel();1258wheel += dwheel;1259if (dwheel != 0) {1260consumed = false;1261for (int i=0;i<mouseListeners.size();i++) {1262MouseListener listener = (MouseListener) mouseListeners.get(i);1263if (listener.isAcceptingInput()) {1264listener.mouseWheelMoved(dwheel);1265if (consumed) {1266break;1267}1268}1269}1270}1271}1272}12731274if (!displayActive) {1275lastMouseX = getMouseX();1276lastMouseY = getMouseY();1277} else {1278if ((lastMouseX != getMouseX()) || (lastMouseY != getMouseY())) {1279consumed = false;1280for (int i=0;i<mouseListeners.size();i++) {1281MouseListener listener = (MouseListener) mouseListeners.get(i);1282if (listener.isAcceptingInput()) {1283if (anyMouseDown()) {1284listener.mouseDragged(lastMouseX , lastMouseY, getMouseX(), getMouseY());1285} else {1286listener.mouseMoved(lastMouseX , lastMouseY, getMouseX(), getMouseY());1287}1288if (consumed) {1289break;1290}1291}1292}1293lastMouseX = getMouseX();1294lastMouseY = getMouseY();1295}1296}12971298if (controllersInited) {1299for (int i=0;i<getControllerCount();i++) {1300int count = ((Controller) controllers.get(i)).getButtonCount()+3;1301count = Math.min(count, 24);1302for (int c=0;c<=count;c++) {1303if (controls[i][c] && !isControlDwn(c, i)) {1304controls[i][c] = false;1305fireControlRelease(c, i);1306} else if (!controls[i][c] && isControlDwn(c, i)) {1307controllerPressed[i][c] = true;1308controls[i][c] = true;1309fireControlPress(c, i);1310}1311}1312}1313}13141315if (keyRepeat) {1316for (int i=0;i<1024;i++) {1317if (pressed[i] && (nextRepeat[i] != 0)) {1318if (System.currentTimeMillis() > nextRepeat[i]) {1319nextRepeat[i] = System.currentTimeMillis() + keyRepeatInterval;1320consumed = false;1321for (int j=0;j<keyListeners.size();j++) {1322KeyListener listener = (KeyListener) keyListeners.get(j);13231324if (listener.isAcceptingInput()) {1325listener.keyPressed(i, keys[i]);1326if (consumed) {1327break;1328}1329}1330}1331}1332}1333}1334}133513361337Iterator all = allListeners.iterator();1338while (all.hasNext()) {1339ControlledInputReciever listener = (ControlledInputReciever) all.next();1340listener.inputEnded();1341}13421343if (Display.isCreated()) {1344displayActive = Display.isActive();1345}1346}13471348/**1349* Enable key repeat for this input context. This will cause keyPressed to get called repeatedly1350* at a set interval while the key is pressed1351*1352* @param initial The interval before key repreating starts after a key press1353* @param interval The interval between key repeats in ms1354* @deprecated1355*/1356public void enableKeyRepeat(int initial, int interval) {1357Keyboard.enableRepeatEvents(true);1358}13591360/**1361* Enable key repeat for this input context. Uses the system settings for repeat1362* interval configuration.1363*/1364public void enableKeyRepeat() {1365Keyboard.enableRepeatEvents(true);1366}13671368/**1369* Disable key repeat for this input context1370*/1371public void disableKeyRepeat() {1372Keyboard.enableRepeatEvents(false);1373}13741375/**1376* Check if key repeat is enabled1377*1378* @return True if key repeat is enabled1379*/1380public boolean isKeyRepeatEnabled() {1381return Keyboard.areRepeatEventsEnabled();1382}13831384/**1385* Fire an event indicating that a control has been pressed1386*1387* @param index The index of the control pressed1388* @param controllerIndex The index of the controller on which the control was pressed1389*/1390private void fireControlPress(int index, int controllerIndex) {1391consumed = false;1392for (int i=0;i<controllerListeners.size();i++) {1393ControllerListener listener = (ControllerListener) controllerListeners.get(i);1394if (listener.isAcceptingInput()) {1395switch (index) {1396case LEFT:1397listener.controllerLeftPressed(controllerIndex);1398break;1399case RIGHT:1400listener.controllerRightPressed(controllerIndex);1401break;1402case UP:1403listener.controllerUpPressed(controllerIndex);1404break;1405case DOWN:1406listener.controllerDownPressed(controllerIndex);1407break;1408default:1409// assume button pressed1410listener.controllerButtonPressed(controllerIndex, (index - BUTTON1) + 1);1411break;1412}1413if (consumed) {1414break;1415}1416}1417}1418}14191420/**1421* Fire an event indicating that a control has been released1422*1423* @param index The index of the control released1424* @param controllerIndex The index of the controller on which the control was released1425*/1426private void fireControlRelease(int index, int controllerIndex) {1427consumed = false;1428for (int i=0;i<controllerListeners.size();i++) {1429ControllerListener listener = (ControllerListener) controllerListeners.get(i);1430if (listener.isAcceptingInput()) {1431switch (index) {1432case LEFT:1433listener.controllerLeftReleased(controllerIndex);1434break;1435case RIGHT:1436listener.controllerRightReleased(controllerIndex);1437break;1438case UP:1439listener.controllerUpReleased(controllerIndex);1440break;1441case DOWN:1442listener.controllerDownReleased(controllerIndex);1443break;1444default:1445// assume button release1446listener.controllerButtonReleased(controllerIndex, (index - BUTTON1) + 1);1447break;1448}1449if (consumed) {1450break;1451}1452}1453}1454}14551456/**1457* Check if a particular control is currently pressed1458*1459* @param index The index of the control1460* @param controllerIndex The index of the control to which the control belongs1461* @return True if the control is pressed1462*/1463private boolean isControlDwn(int index, int controllerIndex) {1464switch (index) {1465case LEFT:1466return isControllerLeft(controllerIndex);1467case RIGHT:1468return isControllerRight(controllerIndex);1469case UP:1470return isControllerUp(controllerIndex);1471case DOWN:1472return isControllerDown(controllerIndex);1473}14741475if (index >= BUTTON1) {1476return isButtonPressed((index-BUTTON1), controllerIndex);1477}14781479throw new RuntimeException("Unknown control index");1480}148114821483/**1484* Pauses the polling and sending of input events.1485*/1486public void pause() {1487paused = true;14881489// Reset all polling arrays1490clearKeyPressedRecord();1491clearMousePressedRecord();1492clearControlPressedRecord();1493}14941495/**1496* Resumes the polling and sending of input events.1497*/1498public void resume() {1499paused = false;1500}15011502/**1503* Notify listeners that the mouse button has been clicked1504*1505* @param button The button that has been clicked1506* @param x The location at which the button was clicked1507* @param y The location at which the button was clicked1508* @param clickCount The number of times the button was clicked (single or double click)1509*/1510private void fireMouseClicked(int button, int x, int y, int clickCount) {1511consumed = false;1512for (int i=0;i<mouseListeners.size();i++) {1513MouseListener listener = (MouseListener) mouseListeners.get(i);1514if (listener.isAcceptingInput()) {1515listener.mouseClicked(button, x, y, clickCount);1516if (consumed) {1517break;1518}1519}1520}1521}1522}152315241525