Angband Forums

Angband Forums (http://angband.oook.cz/forum/index.php)
-   Development (http://angband.oook.cz/forum/forumdisplay.php?f=10)
-   -   Fixing dir, shift-dir and ctrl-dir keys part 2: GCU client (http://angband.oook.cz/forum/showthread.php?t=5525)

PowerWyrm May 30, 2012 13:04

Fixing dir, shift-dir and ctrl-dir keys part 2: GCU client
 
The problem: shift-dir keys (keypad) don't work at all

A partial solution (main-gcu.c, excerpt from the keypress code):

Code:

#ifdef KEY_DOWN
    /* Handle special keys */
    switch (i)
    {
        /* Control keys */
        case 8: i = KC_BACKSPACE; break;
        case 9: i = KC_TAB; break;
        case 13: i = KC_ENTER; break;
        case 27: i = ESCAPE; break;

        /* Keypad keys */
        case 0xFC: i = '0'; break;
        case 0xFD: i = '.'; break;
        case 0xC0: i = '\b'; break;
        case 0xDF: i = '1'; break;
        case 0xF5: i = '3'; break;
        case 0xE9: i = '5'; break;
        case 0xC1: i = '7'; break;
        case 0xF4: i = '9'; break;

        /* Key definitions, part 1 */
        case KEY_DOWN: i = ARROW_DOWN; break;
        case KEY_UP: i = ARROW_UP; break;
        case KEY_LEFT: i = ARROW_LEFT; break;
        case KEY_RIGHT: i = ARROW_RIGHT; break;
        case KEY_HOME: i = KC_HOME; break;
        case KEY_BACKSPACE: i = KC_BACKSPACE; break;

        /* Key definitions, part 2 */
        case KEY_DC: i = KC_DELETE; break;
        case KEY_IC: i = KC_INSERT; break;
        case KEY_NPAGE: i = KC_PGDOWN; break;
        case KEY_PPAGE: i = KC_PGUP; break;
        case KEY_ENTER: i = KC_ENTER; mods |= KC_MOD_KEYPAD; break;
        case KEY_END: i = KC_END; break;
        case KEY_SDC: i = KC_DELETE; mods |= KC_MOD_SHIFT; break;
        case KEY_SEND: i = KC_END; mods |= KC_MOD_SHIFT; break;
        case KEY_SHOME: i = KC_HOME; mods |= KC_MOD_SHIFT; break;
        case KEY_SIC: i = KC_INSERT; mods |= KC_MOD_SHIFT; break;

        /* Key definitions, part 3 */
        case KEY_SLEFT: i = ARROW_LEFT; mods |= KC_MOD_SHIFT; break;
        case KEY_SNEXT: i = KC_PGDOWN; mods |= KC_MOD_SHIFT; break;
        case KEY_SPREVIOUS: i = KC_PGUP; mods |= KC_MOD_SHIFT; break;
        case KEY_SRIGHT: i = ARROW_RIGHT; mods |= KC_MOD_SHIFT; break;

        /* Key definitions, part 4 */
        case CTL_LEFT: i = ARROW_LEFT; mods |= KC_MOD_CONTROL; break;
        case CTL_RIGHT: i = ARROW_RIGHT; mods |= KC_MOD_CONTROL; break;
        case CTL_PGUP: i = KC_PGUP; mods |= KC_MOD_CONTROL; break;
        case CTL_PGDN: i = KC_PGDOWN; mods |= KC_MOD_CONTROL; break;
        case CTL_HOME: i = KC_HOME; mods |= KC_MOD_CONTROL; break;
        case CTL_END: i = KC_END; mods |= KC_MOD_CONTROL; break;

        /* Virtual keypad keys (NUMLOCK off) */
        /* Hack -- Use these keys to handle shift-dir when NUMLOCK is on */
        case KEY_A1: i = '7'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case KEY_A2: i = '8'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case KEY_A3: i = '9'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case KEY_B1: i = '4'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case KEY_B2: i = '5'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case KEY_B3: i = '6'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case KEY_C1: i = '1'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case KEY_C2: i = '2'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case KEY_C3: i = '3'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;

        /* Keypad keys */
        case PADSLASH: i = '/'; mods |= KC_MOD_KEYPAD; break;
        case PADENTER: i = KC_ENTER; mods |= KC_MOD_KEYPAD; break;
        case PADSTOP: i = '.'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case PADSTAR: i = '*'; mods |= KC_MOD_KEYPAD; break;
        case PADMINUS: i = '-'; mods |= KC_MOD_KEYPAD; break;
        case PADPLUS: i = '+'; mods |= KC_MOD_KEYPAD; break;

        /* Key definitions, part 5 */
        case CTL_UP: i = ARROW_UP; mods |= KC_MOD_CONTROL; break;
        case CTL_DOWN: i = ARROW_DOWN; mods |= KC_MOD_CONTROL; break;
        case PAD0: i = '0'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;

        /* Key definitions, part 6 */
        case CTL_PAD0: i = '0'; mods |= (KC_MOD_CONTROL | KC_MOD_KEYPAD); break;
        case CTL_PAD1: i = '1'; mods |= (KC_MOD_CONTROL | KC_MOD_KEYPAD); break;
        case CTL_PAD2: i = '2'; mods |= (KC_MOD_CONTROL | KC_MOD_KEYPAD); break;
        case CTL_PAD3: i = '3'; mods |= (KC_MOD_CONTROL | KC_MOD_KEYPAD); break;
        case CTL_PAD4: i = '4'; mods |= (KC_MOD_CONTROL | KC_MOD_KEYPAD); break;
        case CTL_PAD5: i = '5'; mods |= (KC_MOD_CONTROL | KC_MOD_KEYPAD); break;
        case CTL_PAD6: i = '6'; mods |= (KC_MOD_CONTROL | KC_MOD_KEYPAD); break;
        case CTL_PAD7: i = '7'; mods |= (KC_MOD_CONTROL | KC_MOD_KEYPAD); break;
        case CTL_PAD8: i = '8'; mods |= (KC_MOD_CONTROL | KC_MOD_KEYPAD); break;
        case CTL_PAD9: i = '9'; mods |= (KC_MOD_CONTROL | KC_MOD_KEYPAD); break;

        /* Key definitions, part 7 */
        case KEY_SUP: i = ARROW_UP; mods |= KC_MOD_SHIFT; break;
        case KEY_SDOWN: i = ARROW_DOWN; mods |= KC_MOD_SHIFT; break;

        default:
        {
            if (i < KEY_MIN) break;

            /* Mega-Hack -- Fold, spindle, and mutilate the keys to fit in 7 bits. */
            if (i >= 252) i = KEY_F(63) - (i - 252);
            if (i >= ARROW_DOWN) i += 4;

            i = 128 + (i & 127);
            break;
        }
    }
#endif

This works with Win7 and an AZERTY keyboard (the previous code also fixes some commands that didn't work for me). The problem with GCU is that the NUMLOCK key acts as a toggle for the "shift" mod when using the keypad:
- Numlock on + Shift off: keypad mapped to 0x31-0x39
- Numlock on + Shift on: keypad mapped to 0x1c1-0x1c9
- Numlock off + Shift off: keypad mapped to 0x1c1-0x1c9
- Numlock off + Shift on: keypad mapped to 0x31-0x39

The partial solution is to map shift-dir to the 0x1c1-0x1c9 keys to get a consistent behavior with numlock on. I don't see how the problem can be fixed completely, so the side effect is that walking and running are reversed when numlock is off.

PowerWyrm June 1, 2012 19:34

See http://angband.oook.cz/forum/showthread.php?t=5514.

By design, pressing shift-numlock-keypad key has the same effect as pressing the keypad key with no modifiers. The fix should then be applied so that the behavior is correct for NUMLOCK off.

Code:

        /* Use these keys to handle shift-dir when NUMLOCK is off */
        case 0x31: i = '1'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case 0x32: i = '2'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case 0x33: i = '3'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case 0x34: i = '4'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case 0x35: i = '5'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case 0x36: i = '6'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case 0x37: i = '7'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case 0x38: i = '8'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;
        case 0x39: i = '9'; mods |= (KC_MOD_SHIFT | KC_MOD_KEYPAD); break;

        /* Virtual keypad keys (NUMLOCK off) */
        case KEY_A1: i = '7'; mods |= KC_MOD_KEYPAD; break;
        case KEY_A2: i = '8'; mods |= KC_MOD_KEYPAD; break;
        case KEY_A3: i = '9'; mods |= KC_MOD_KEYPAD; break;
        case KEY_B1: i = '4'; mods |= KC_MOD_KEYPAD; break;
        case KEY_B2: i = '5'; mods |= KC_MOD_KEYPAD; break;
        case KEY_B3: i = '6'; mods |= KC_MOD_KEYPAD; break;
        case KEY_C1: i = '1'; mods |= KC_MOD_KEYPAD; break;
        case KEY_C2: i = '2'; mods |= KC_MOD_KEYPAD; break;
        case KEY_C3: i = '3'; mods |= KC_MOD_KEYPAD; break;

This has the problem of forcing running when pressing a numpad key with numlock on, which could be problematic...


All times are GMT +1. The time now is 08:16.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.