Skip to content

Commit

Permalink
-Change: more comments about Keyboard input functions
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Bernard <miniupnp@free.fr>
  • Loading branch information
miniupnp committed May 12, 2018
1 parent f5e6783 commit fa9c2e4
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 62 deletions.
6 changes: 3 additions & 3 deletions src/gui/widget_draw.c
Expand Up @@ -747,10 +747,10 @@ void GUI_Widget_ActionPanel_Draw(bool forceDraw)
buttons[i]->shortcut = GUI_Widget_GetShortcut(String_Get_ByIndex(buttons[i]->stringID)[0]);

if (g_config.language == LANGUAGE_FRENCH) {
if (buttons[i]->stringID == STR_MOVE) buttons[i]->shortcut2 = 0x27;
else if (buttons[i]->stringID == STR_RETURN) buttons[i]->shortcut2 = 0x13;
if (buttons[i]->stringID == STR_MOVE) buttons[i]->shortcut2 = 0x27; /* L key */
else if (buttons[i]->stringID == STR_RETURN) buttons[i]->shortcut2 = 0x13; /* E key */
} else if (g_config.language == LANGUAGE_GERMAN) {
if (buttons[i]->stringID == STR_GUARD) buttons[i]->shortcut2 = 0x17;
if (buttons[i]->stringID == STR_GUARD) buttons[i]->shortcut2 = 0x17; /* U key */
}

GUI_Widget_MakeVisible(buttons[i]);
Expand Down
202 changes: 145 additions & 57 deletions src/input/input.c
Expand Up @@ -22,20 +22,51 @@ static uint16 s_historyTail = 0; /*!< The current tail inside the #s
static bool s_input_extendedKey = false; /*!< If we are currently actively reading an extended key. */
static uint8 s_activeInputMap[16]; /*!< A 96 bit array, where each active bit means that the Nth key is pressed. */

/* Dune II key codes :
* 0x00 : invalid
* 0x01 - 0x37 : ASCII characters (except 0x0e, 0x1e, 0x2a, 0x2c)
* 0x1e : CAPS LOCK
* 0x2b : ENTER
* 0x2c : LSHIFT
* 0x2d : MOUSE MOVE
* 0x39 : RSHIFT
* 0x3a : LCTRL
* 0x3c : LALT
* 0x3d : SPACE (printable)
* 0x3e : RALT
* 0x40 : RCTRL
* 0x41 : LEFT MOUSE BUTTON
* 0x42 : RIGHT MOUSE BUTTON
* 0x4b - 0x56 : INSERT DELETE LEFT HOME END UP DOWN PGUP PGDOWN RIGHT
* 0x59 : KP / (?)
* 0x5a - 0x5d : NUMLOCK KP 7 4 1
* 0x5f - 0x6a : KP / 8 5 2 0 * 9 6 3 . - +
* 0x6c : KP ENTER
* 0x6e : ESCAPE
* 0x70 - 0x7b : F1-F12
* 0x7d : SCROLL LOCK
*/

static const uint8 s_keymapIgnore[] = {30, ',', '9', ':', '<', '>', '@', 'Z', 128}; /*!< Keys to ignore when reading. */
/* Dune II codes 0x1e, 0x2c, 0x39, 0x3a, 0x3c, 0x3e, 0x40, 0x5a, 0x80 */
/* CAPS LSHFT RSHFT LCTRL LALT RALT RCTRL NUMLK */

/** Per bit, mask which keys are special and should be done &= 0x1F. */
/** Per bit, mask which keys are letters and special and should be done &= 0x1F when ALT is pressed (or CTLR ?) */
static const uint8 s_keymapSpecialMask[] = {0x00, 0x00, 0xFE, 0x87, 0xFF, 0xC0, 0x1F, 0x00};
/* 0x11-0x1b : qwertyuiop
* 0x1f-0x27 : asdfghjkl
* 0x2e-0x34 : zxcvbnm
*/

/** Keymap to convert scancode to ASCII with capslock off and shift released. */
/** Keymap to convert Dune II codes to ASCII with capslock off and shift released. */
static const uint8 s_keymapNormal[] = {
0, '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 8,
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\\', 0, 'a',
's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 0, '\r', 0, '-', 'z', 'x',
'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, 0, 0, 0, 0, ' '
0, '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 8, /* 0x00 - 0x0f */
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\\', 0, 'a', /* 0x10 - 0x1f */
's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 0, '\r', 0, '-', 'z', 'x', /* 0x20 - 0x2f */
'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, 0, 0, 0, 0, ' ' /* 0x30 - 0x3d */
};

/** Keymap to convert scancode to ASCII with capslock off and shift pressed. */
/** Keymap to convert Dune II codes to ASCII with capslock off and shift pressed. */
static const uint8 s_keymapShift[] = {
0, '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 8,
'\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '|', 0, 'A',
Expand All @@ -46,26 +77,70 @@ static const uint8 s_keymapShift[] = {
/** Keymap to convert scancode to for numpad with numlock on. */
static const uint8 s_keymapNumlock[] = {0, '7', '4', '1', 0, '/', '8', '5', '2', '0', '*', '9', '6', '3', '.', '-', '+', 0, '\r', 0};

/* when escaped with 0xE0, scancodes in s_translateExtendedMap are translated to s_translateMap */
/** Some kind of translation map for extended keys. */
static const uint8 s_translateExtendedMap[] = {'8', 29, 'R', 'S', 'K', 'G', 'O', 'H', 'P', 'I', 'Q', 'M', '5', 28, '7', 'F'};
/* scancodes : 0x38, 0x1d, 0x52, 0x53, 0x4b, 0x47, 0x4f, 0x48, 0x50, 0x49, 0x51, 0x4d, 0x35, 0x1c, 0x37, 0x46 */
/* 0xE0 keys : RALT RCTRL INSRT DEL LEFT 7HOME 1END 8UP DOWN 9PGUP 3PGDN 6RGHT KP/ ENTR *PRNSCN SCLOCK */

/** Some kind of translation map. */
static const uint8 s_translateMap[] = {'>', '@', 'K', 'L', 'O', 'P', 'Q', 'S', 'T', 'U', 'V', 'Y', '_', 'l', '|', 0};
/* DuneII codes : 0x3e 0x40 0x4b 0x4c 0x4f 0x50 0x51 0x53 0x54 0x55 0x56 0x59 0x5f 0x6c 0x7c 0x00 */
/* RALT RCTL KP / KPENTER */

/** To what a match in #s_translateMap translates. */
static const uint8 s_translateTo[] = {'<', ':', 'c', 'h', '\\', '[', ']', '`', 'b', 'e', 'g', 'f', '7', '+', '|', 0};
/* DuneII codes : 0x3c 0x3a 0x63 0x68 0x5c 0x5b 0x5d 0x60 0x62 0x65 0x67 0x66 0x37 0x2b 0x7c 0x00 */
/* LALT LCTL KP 0 KP . KP 4 KP 7 KP 1 KP 8 KP 2 KP 9 KP 3 KP 6 / ENTER */

assert_compile(lengthof(s_translateExtendedMap) == lengthof(s_translateMap));
assert_compile(lengthof(s_translateMap) == lengthof(s_translateTo));

/** Key translation table. */
/** Key translation table.
* From XT/AT scancodes to Dune II codes :
* 0x00 => 0x7f
* 0x01 => 0x6e ESC
* [0x02:0x0d] => n 1 2 3 4 5 6 7 8 9 0 - =
* [0x0e:0x1b] => n+1 BACKSPACE TAB q w e r t y u i o p [ ]
* 0x1c => 0x2b ENTER
* 0x1d => 0x3a LCTRL
* [0x1e:0x28] => n+1 a s d f g h j k l ; '
* 0x29 => 0x01 ~' (key left to 1)
* 0x2a => 0x2c LSHIFT
* 0x2b => 0x1d | (key left to Z)
* [0x2c:0x35] => n+2 z x c v b n m , . /
* 0x36 => 0x39 RSHIFT
* 0x37 => 0x64 KP *
* 0x38 => 0x3c LALT
* 0x39 => 0x3d SPACE
* 0x3a => 0x1e CAPS LOCK
* [0x3b:0x44] => [0x70:0x79] (n+0x35) F1-F10
* 0x45 => 0x5a NUMLOCK
* 0x46 => 0x7d SCROLL LOCK
* 0x47 => 0x5b KP 7 HOME
* 0x48 => 0x60 KP 8 UP
* 0x49 => 0x65 KP 9 PGUP
* 0x4a => 0x69 KP -
* 0x4b => 0x5c KP 4 LEFT
* 0x4c => 0x61 KP 5
* 0x4d => 0x66 KP 6 RIGHT
* 0x4e => 0x6a KP +
* 0x4f => 0x5d KP 1 END
* 0x50 => 0x62 KP 2 DOWN
* 0x51 => 0x67 KP 3 PGDN
* 0x52 => 0x63 KP 0 INS
* 0x53 => 0x68 KP . DEL
* [0x54:0x56] => 0x7f
* 0x57 => 0x7a F11
* 0x58 => 0x7b F12
*/
static const uint8 s_keyTranslate[] = {
127, 'n', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, '+', ':', 31, ' ',
'!', '"', '#', '$', '%', '&', '\'', '(', ')', 1, ',', 29, '.', '/', '0', '1',
'2', '3', '4', '5', '6', '7', '9', 'd', '<', '=', 30, 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'Z', '}', '[', '`', 'e', 'i', '\\', 'a', 'f', 'j', ']',
'b', 'g', 'c', 'h', 127, 127, 127, 'z', '{'
127, 'n', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, /* 0x00 - 0x0f */
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, '+', ':', 31, ' ', /* 0x10 - 0x1f */
'!', '"', '#', '$', '%', '&', '\'', '(', ')', 1, ',', 29, '.', '/', '0', '1', /* 0x20 - 0x2f */
'2', '3', '4', '5', '6', '7', '9', 'd', '<', '=', 30, 'p', 'q', 'r', 's', 't', /* 0x30 - 0x3f */
'u', 'v', 'w', 'x', 'y', 'Z', '}', '[', '`', 'e', 'i', '\\', 'a', 'f', 'j', ']', /* 0x40 - 0x4f */
'b', 'g', 'c', 'h', 127, 127, 127, 'z', '{' /* 0x50 - 0x58 */
};

void Input_Init(void)
Expand Down Expand Up @@ -95,13 +170,15 @@ static uint16 Input_Keyboard_Translate(uint16 keyValue)
return keyValue;
}

/* Receive the keyboard scancodes from the AT keyboard */
void Input_EventHandler(uint8 key)
{
uint8 state;
uint8 i;

state = 0;

/* escape code for escaped scancodes */
if (key == 0xE0) {
s_input_extendedKey = true;
return;
Expand All @@ -110,7 +187,7 @@ void Input_EventHandler(uint8 key)
/* Key up */
if ((key & 0x80) != 0) {
key &= 0x7F;
state |= 0x08;
state |= 0x08; /* KEYUP */
}

if (s_input_extendedKey) {
Expand All @@ -129,15 +206,15 @@ void Input_EventHandler(uint8 key)
key = s_keyTranslate[key & 0x7F];
}

if ((s_activeInputMap[7] & 0x4) != 0) return;
if ((s_activeInputMap[7] & 0x50) != 0) state |= 0x04;
if ((s_activeInputMap[7] & 0x4) != 0) return; /* 0x3a : LCTRL */
if ((s_activeInputMap[7] & 0x50) != 0) state |= 0x04; /* 0x3c 0x3e : LALT RALT => ALT */

key = Input_Keyboard_Translate(key) & 0xFF;

if ((s_activeInputMap[7] & 0x2) != 0) state |= 0x01;
if ((s_activeInputMap[7] & 0x2) != 0) state |= 0x01; /* 0x39 : RSHIFT */

if (state == 0x06 && key == 0x68) return;
if (state == 0x06 && key == 0x4C) return;
if (state == 0x06 && key == 0x68) return; /* state == ALT+??? && key == KP DEL */
if (state == 0x06 && key == 0x4C) return; /* state == ALT+??? && key == DELETE */

Input_HandleInput((state << 8) | key);
}
Expand Down Expand Up @@ -308,6 +385,12 @@ static uint16 Input_AddHistory(uint16 value)
/**
* Handle input.
* @param input New input.
* Upper byte is flags, lower byte is Dune II keycode
* Flags :
* 0x01 SHIFT
* 0x02 ALT
* 0x04 ?
* 0x08 KEYUP / RELEASE
*/
void Input_HandleInput(uint16 input)
{
Expand Down Expand Up @@ -396,6 +479,7 @@ void Input_HandleInput(uint16 input)
g_mouseX = inputMouseX;
g_mouseY = inputMouseY;
if (g_mouseLock == 0) {
/* Move mouse pointer */
GUI_Mouse_Hide();
GUI_Mouse_Show();
}
Expand All @@ -412,9 +496,9 @@ void Input_HandleInput(uint16 input)

value = input & 0xFF;
if (value == 0x2D || value == 0x41 || value == 0x42) {
/* mouse buttons : 0x2D '-' : no change
0x41 'A' : change for 1st button
0x42 'B' : change for 2nd button */
/* mouse buttons : 0x2D : no change
0x41 : change for 1st button
0x42 : change for 2nd button */
if ((Input_History_Add(inputMouseX) != 0) || (Input_History_Add(inputMouseY) != 0)) {
s_historyTail = oldTail;
return;
Expand All @@ -426,8 +510,8 @@ void Input_HandleInput(uint16 input)
}

bit_value = 1;
value = input & 0xFF;
if (value != 0x2D && value != 0x7F && (input & 0x800) != 0) bit_value = 0;
/* bitvalue = 0 if release, 1 for key press */

if (value == 0x2D || value == 0x7F ||
((input & 0x800) != 0 && (flags & INPUT_FLAG_KEY_RELEASE) == 0 && value != 0x41 && value != 0x42)) {
Expand All @@ -439,8 +523,8 @@ void Input_HandleInput(uint16 input)
if ((bit_value & s_activeInputMap[index]) != 0 && (flags & INPUT_FLAG_KEY_REPEAT) == 0) {
s_historyTail = oldTail;
}
s_activeInputMap[index] &= (1 << (value & 7)) ^ 0xFF;
s_activeInputMap[index] |= bit_value;
s_activeInputMap[index] &= (1 << (value & 7)) ^ 0xFF; /* Clear bit */
s_activeInputMap[index] |= bit_value; /* set bit */

if (g_mouseMode != INPUT_MOUSE_MODE_RECORD || value == 0x7D) return;

Expand Down Expand Up @@ -500,75 +584,79 @@ uint16 Input_Test(uint16 value)
/**
* Handle keyboard input.
* @param value Combined keycode and modifier flags.
* @return key value and modifier flags.
* @return key value and modifier flags. (ASCII value or > 0x80)
* @todo Most users seem to ignore the returned high byte, perhaps make it a
* uint8 at some time in the future?
*/
uint16 Input_Keyboard_HandleKeys(uint16 value)
{
uint8 keyValue;
uint16 keyFlags;

keyValue = value & 0x00FF;
keyFlags = value & 0xFF00;
value &= 0x00FF;

if ((keyFlags & 0x8000) != 0 || (keyFlags & 0x800) != 0) {
return 0;
return 0; /* return on key up */
}

if (keyValue == 0x6E) {
return keyFlags | 0x1B;
if (value == 0x6E) {
return keyFlags | 0x1B; /* ESCAPE */
}

if (keyValue < 0x3E) {
uint8 keySave = keyValue & 0x3F;
if (value < 0x3E) { /* Printables Chars */
uint8 keySave = value & 0x3F;
uint16 asciiValue;

if ((keyFlags & 0x100) != 0) {
keyValue = s_keymapShift[keySave];
asciiValue = s_keymapShift[keySave];
} else {
keyValue = s_keymapNormal[keySave];
asciiValue = s_keymapNormal[keySave];
}

if ((keyFlags & 0x200) != 0) {
if ((keyFlags & 0x200) != 0) { /* ALT */
if ((s_keymapSpecialMask[keySave >> 3] & (1 << (keySave & 7))) != 0) {
keyValue &= 0x1F;
asciiValue &= 0x1F;
}
}
return keyFlags | keyValue;
return keyFlags | asciiValue;
}

if (keyValue < 0x4B) {
if (keyValue >= 0x41) {
return keyFlags | (keyValue + 0x85);
if (value < 0x4B) {
/* 0x3E - 0x4A : unused codes ? */
if (value >= 0x41) {
return keyFlags | (value + 0x85); /* 0x41-0x4A => 0xC6-0xCF */
}
return keyFlags | keyValue | 0x80;
return keyFlags | value | 0x80; /* 0x3E 0x3F 0x40 => 0xBE 0xBF 0xC0 */
}

if (keyValue < 0x6E) {
uint8 keySave = keyValue - 0x4B;

return s_keymapNumlock[keySave - 0xF];
if (value < 0x6E) {
/* 0x4B - 0x6D : Keypad + grey edit keys */
if (value >= 0x5A) {
return s_keymapNumlock[value - 0x5A];
} else {
/*return s_keymapNumpad[value - 0x4B]; CODE has been removed in 1b81370b006 */
}
}

if (keyValue < 0x70 || keyValue > 0x79) {
return keyFlags | keyValue | 0x80;
if (value < 0x70 || value > 0x79) {
return keyFlags | value | 0x80;
}
keyValue -= 0x70;
value -= 0x70; /* F1-F10 Function keys */
if ((keyFlags & 0x700) != 0) {
if ((keyFlags & 0x400) == 0) {
if ((keyFlags & 0x200) == 0) {
return keyFlags | (0xAC - keyValue);
if ((keyFlags & 0x400) == 0) { /* ? */
if ((keyFlags & 0x200) == 0) { /* ALT */
return keyFlags | (0xAC - value); /* 0xA3 - 0xAC */
}
return keyFlags | (0xA2 - keyValue);
return keyFlags | (0xA2 - value); /* ? : 0x99 - 0xA2 */
}
return keyFlags | (0x98 - keyValue);
return keyFlags | (0x98 - value); /* SHIFT or ALT : 0x8F - 0x98 */
}
return keyFlags | (0xC5 - keyValue);
return keyFlags | (0xC5 - value); /* No modifier : 0xBC - 0xC5 */
}

/**
* Wait for valid input.
* @return Read input.
* @return Read input. (ASCII VALUE or > 0x80)
*/
uint16 Input_WaitForValidInput(void)
{
Expand Down
4 changes: 2 additions & 2 deletions src/input/mouse.c
Expand Up @@ -246,14 +246,14 @@ uint16 Mouse_CheckButtons(uint16 newButtonState)
if ((change & 0x2) != 0) {
result = 0x42;
if ((newButtonState & 0x2) == 0) {
result |= 0x800;
result |= 0x800; /* RELEASE */
}
}

if ((change & 0x1) != 0) {
result = 0x41;
if ((newButtonState & 0x1) == 0) {
result |= 0x800;
result |= 0x800; /* RELEASE */
}
}

Expand Down

0 comments on commit fa9c2e4

Please sign in to comment.