mirror of
https://github.com/shadowfacts/lwjgl2-arm64.git
synced 2025-12-06 08:01:59 +01:00
488 lines
15 KiB
Java
488 lines
15 KiB
Java
/*
|
|
* Copyright (c) 2002 Light Weight Java Game Library Project
|
|
* 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 'Light Weight Java Game Library' 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.lwjgl.input;
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
import org.lwjgl.Display;
|
|
import org.lwjgl.Sys;
|
|
|
|
/**
|
|
* $Id$
|
|
*
|
|
* A raw Keyboard interface. This can be used to poll the current state of the
|
|
* keys, or read all the keyboard presses / releases since the last read.
|
|
* Buffering must be explicitly enabled; the size of the buffer is determined
|
|
* by the native implementation at its discretion.
|
|
*
|
|
* @author cix_foo <cix_foo@users.sourceforge.net>
|
|
* @version $Revision$
|
|
*/
|
|
public class Keyboard {
|
|
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_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;
|
|
|
|
// Maps keycodes to ascii characters
|
|
private static final char map[] =
|
|
{
|
|
0,
|
|
0,
|
|
'1',
|
|
'2',
|
|
'3',
|
|
'4',
|
|
'5',
|
|
'6',
|
|
'7',
|
|
'8',
|
|
'9',
|
|
'0',
|
|
'-',
|
|
'=',
|
|
0,
|
|
0,
|
|
'q',
|
|
'w',
|
|
'e',
|
|
'r',
|
|
't',
|
|
'y',
|
|
'u',
|
|
'i',
|
|
'o',
|
|
'p',
|
|
'[',
|
|
']',
|
|
0,
|
|
0,
|
|
'a',
|
|
's',
|
|
'd',
|
|
'f',
|
|
'g',
|
|
'h',
|
|
'j',
|
|
'k',
|
|
'l',
|
|
';',
|
|
'\'',
|
|
'#',
|
|
0,
|
|
'\\',
|
|
'z',
|
|
'x',
|
|
'c',
|
|
'v',
|
|
'b',
|
|
'n',
|
|
'm',
|
|
',',
|
|
'.',
|
|
'/',
|
|
0,
|
|
0,
|
|
0,
|
|
' ' };
|
|
private static final char shiftMap[] =
|
|
{
|
|
0,
|
|
0,
|
|
'!',
|
|
'"',
|
|
'*',
|
|
'$',
|
|
'%',
|
|
'^',
|
|
'&',
|
|
'*',
|
|
'(',
|
|
')',
|
|
'_',
|
|
'+',
|
|
0,
|
|
0,
|
|
'Q',
|
|
'W',
|
|
'E',
|
|
'R',
|
|
'T',
|
|
'Y',
|
|
'U',
|
|
'I',
|
|
'O',
|
|
'P',
|
|
'{',
|
|
'}',
|
|
0,
|
|
0,
|
|
'A',
|
|
'S',
|
|
'D',
|
|
'F',
|
|
'G',
|
|
'H',
|
|
'J',
|
|
'K',
|
|
'L',
|
|
':',
|
|
'@',
|
|
'~',
|
|
0,
|
|
'|',
|
|
'Z',
|
|
'X',
|
|
'C',
|
|
'V',
|
|
'B',
|
|
'N',
|
|
'M',
|
|
'<',
|
|
'>',
|
|
'?',
|
|
0,
|
|
0,
|
|
0,
|
|
' ' };
|
|
|
|
static {
|
|
initialize();
|
|
}
|
|
|
|
/** Has the keyboard been created? */
|
|
private static boolean created;
|
|
|
|
/** The keys status from the last poll */
|
|
private static final ByteBuffer keyDownBuffer = ByteBuffer.allocateDirect(256);
|
|
|
|
/** Address of the keyDown buffer */
|
|
private static final int keyDownAddress = Sys.getDirectBufferAddress(keyDownBuffer);
|
|
|
|
/**
|
|
* The key events from the last read: a sequence of pairs of key number,
|
|
* followed by state.
|
|
*/
|
|
private static ByteBuffer readBuffer;
|
|
|
|
/** Address of the read buffer */
|
|
private static int readBufferAddress;
|
|
|
|
/** The current keyboard event key being examined */
|
|
public static int key;
|
|
|
|
/** The current state of the key being examined in the event queue */
|
|
public static boolean state;
|
|
|
|
/**
|
|
* Mouse cannot be constructed.
|
|
*/
|
|
private Keyboard() {
|
|
}
|
|
|
|
/**
|
|
* Static initialization
|
|
*/
|
|
private static void initialize() {
|
|
System.loadLibrary(Sys.getLibraryName());
|
|
initIDs();
|
|
}
|
|
|
|
/**
|
|
* Register fields with the native library
|
|
*/
|
|
private static native void initIDs();
|
|
|
|
/**
|
|
* "Create" the keyboard. The display must first have been created. The
|
|
* reason for this is so the keyboard has a window to "focus" in.
|
|
*
|
|
* @throws Exception if the keyboard could not be created for any reason
|
|
*/
|
|
public static void create() throws Exception {
|
|
if (created)
|
|
return;
|
|
if (!Display.isCreated())
|
|
throw new Exception("The display has not yet been created.");
|
|
if (!nCreate())
|
|
throw new Exception("The keyboard could not be created.");
|
|
created = true;
|
|
}
|
|
|
|
/**
|
|
* Native method to create the keyboard
|
|
*
|
|
* @return true if the keyboard was created
|
|
*/
|
|
private static native boolean nCreate();
|
|
|
|
/**
|
|
* "Destroy" the keyboard
|
|
*/
|
|
public static void destroy() {
|
|
if (!created)
|
|
return;
|
|
created = false;
|
|
nDestroy();
|
|
}
|
|
|
|
/**
|
|
* Native method the destroy the keyboard
|
|
*/
|
|
private static native void nDestroy();
|
|
|
|
/**
|
|
* Polls the keyboard.
|
|
*/
|
|
public static void poll() {
|
|
assert created : "The keyboard has not been created.";
|
|
nPoll(keyDownAddress);
|
|
}
|
|
|
|
/**
|
|
* Native method to poll the keyboard.
|
|
*
|
|
* @param keyDownBufferAddress the address of a 256-byte buffer to place
|
|
* key states in.
|
|
*/
|
|
private static native void nPoll(int keyDownBufferAddress);
|
|
|
|
/**
|
|
* Reads the keyboard buffer.
|
|
*/
|
|
public static void read() {
|
|
assert created : "The keyboard has not been created.";
|
|
assert readBuffer != null : "Keyboard buffering has not been enabled.";
|
|
readBuffer.clear();
|
|
readBuffer.limit(nRead(readBufferAddress) << 1);
|
|
}
|
|
|
|
/**
|
|
* Native method to read the keyboard buffer
|
|
*
|
|
* @param readBufferAddress the address of the keyboard buffer
|
|
* @return the number of keyboard events read
|
|
*/
|
|
private static native int nRead(int readBufferAddress);
|
|
|
|
/**
|
|
* Enable keyboard buffering. Must be called after the keyboard is created.
|
|
* @return the size of the keyboard buffer in events, or 0 if no buffering
|
|
* can be enabled for any reason
|
|
*/
|
|
public static int enableBuffer() {
|
|
assert created : "The keyboard has not been created.";
|
|
return nEnableBuffer();
|
|
}
|
|
|
|
/**
|
|
* Native method to enable the buffer
|
|
* @return the size of the buffer allocated, in events (1 event is 2 bytes),
|
|
* or 0 if no buffer can be allocated
|
|
*/
|
|
private static native int nEnableBuffer();
|
|
|
|
/**
|
|
* Checks to see if a key is down.
|
|
* @param key Keycode to check
|
|
* @return true if the key is down according to the last poll()
|
|
*/
|
|
public static boolean isKeyDown(int key) {
|
|
assert created : "The keyboard has not been created.";
|
|
return keyDownBuffer.get(key) != 0;
|
|
}
|
|
|
|
/**
|
|
* Gets the number of keyboard events waiting after doing a read().
|
|
* @return the number of keyboard events
|
|
*/
|
|
public static int getNumKeyboardEvents() {
|
|
return readBuffer.limit() >> 1;
|
|
}
|
|
|
|
/**
|
|
* Gets the next keyboard event. This is stored in the publicly accessible
|
|
* static fields key and state.
|
|
* @return true if a keyboard event was read, false otherwise
|
|
*/
|
|
public static boolean next() {
|
|
assert created : "The keyboard has not been created.";
|
|
assert readBuffer != null : "Keyboard buffering has not been enabled.";
|
|
|
|
if (readBuffer.hasRemaining()) {
|
|
key = readBuffer.get() & 0xFF;
|
|
state = readBuffer.get() != 0;
|
|
return true;
|
|
} else
|
|
return false;
|
|
|
|
}
|
|
|
|
/**
|
|
* Maps a keycode to a character.
|
|
* @param keyCode The keycode
|
|
* @return the corresponding ASCII character or 0 if no mapping is possible
|
|
*/
|
|
public static char map(int keyCode) {
|
|
char c;
|
|
|
|
if (keyCode < 0 || keyCode >= map.length)
|
|
return 0;
|
|
else if (isKeyDown(KEY_LSHIFT) || isKeyDown(KEY_RSHIFT)) {
|
|
c = shiftMap[keyCode];
|
|
} else {
|
|
c = map[keyCode];
|
|
}
|
|
return c;
|
|
}
|
|
}
|