diff --git a/Android/jni/androidkeys.c b/Android/jni/androidkeys.c index 70cd0b3c..f9c272a3 100644 --- a/Android/jni/androidkeys.c +++ b/Android/jni/androidkeys.c @@ -243,16 +243,20 @@ void android_keycode_to_emulator(int keyCode, int metaState, bool pressed) { } } while (0); + if (key < 0) { + return; + } + //LOG("keyCode:%08x -> key:%02x ('%c') metaState:%08x", keyCode, key, key, metaState); if (isASCII && _is_ctrl(metaState)) { - key = c_keys_ascii_to_scancode(key); - c_keys_handle_input(key, true, false); + key = keys_ascii2Scancode(key); + keys_handleInput(key, /*is_pressed:*/true, /*is_ascii:*/false); isASCII = false; pressed = false; } assert(key < 0x80); - c_keys_handle_input(key, pressed, isASCII); + keys_handleInput(key, pressed, isASCII); } diff --git a/Apple2Mac/Classes/OSX/EmulatorJoystickController.m b/Apple2Mac/Classes/OSX/EmulatorJoystickController.m index dee9dbc4..dc30a891 100644 --- a/Apple2Mac/Classes/OSX/EmulatorJoystickController.m +++ b/Apple2Mac/Classes/OSX/EmulatorJoystickController.m @@ -114,7 +114,7 @@ #ifdef KEYPAD_JOYSTICK if (joy_mode == JOY_KPAD) { - c_keys_handle_input(-1, 0, 0); + keys_handleInput(/*scancode:*/-1, /*is_pressed:*/false, /*is_ascii:*/false); } #endif } diff --git a/Apple2Mac/Classes/OSX/EmulatorPrefsController.m b/Apple2Mac/Classes/OSX/EmulatorPrefsController.m index 81b4d909..1ed1681a 100644 --- a/Apple2Mac/Classes/OSX/EmulatorPrefsController.m +++ b/Apple2Mac/Classes/OSX/EmulatorPrefsController.m @@ -272,11 +272,11 @@ static void prefsChangeCallback(const char *domain) { case ALT_LT: leftAltEngaged = !leftAltEngaged; - c_keys_handle_input(SCODE_L_ALT, /*pressed:*/leftAltEngaged, /*cooked:*/0); + keys_handleInput(SCODE_L_ALT, /*is_pressed:*/leftAltEngaged, /*is_ascii:*/false); break; case ALT_RT: rightAltEngaged = !rightAltEngaged; - c_keys_handle_input(SCODE_R_ALT, /*pressed:*/rightAltEngaged, /*cooked:*/0); + keys_handleInput(SCODE_R_ALT, /*is_pressed:*/rightAltEngaged, /*is_ascii:*/false); break; default: break; @@ -298,16 +298,16 @@ static void prefsChangeCallback(const char *domain) switch (scode) { case NSUpArrowFunctionKey: - c_keys_handle_input(SCODE_U, pressed, /*cooked:*/0); + keys_handleInput(SCODE_U, pressed, /*is_ascii:*/false); break; case NSDownArrowFunctionKey: - c_keys_handle_input(SCODE_D, pressed, /*cooked:*/0); + keys_handleInput(SCODE_D, pressed, /*is_ascii:*/false); break; case NSLeftArrowFunctionKey: - c_keys_handle_input(SCODE_L, pressed, /*cooked:*/0); + keys_handleInput(SCODE_L, pressed, /*is_ascii:*/false); break; case NSRightArrowFunctionKey: - c_keys_handle_input(SCODE_R, pressed, /*cooked:*/0); + keys_handleInput(SCODE_R, pressed, /*is_ascii:*/false); break; default: break; diff --git a/Apple2Mac/Classes/OSX/EmulatorWindowController.m b/Apple2Mac/Classes/OSX/EmulatorWindowController.m index 3e2236f2..41aff0e9 100644 --- a/Apple2Mac/Classes/OSX/EmulatorWindowController.m +++ b/Apple2Mac/Classes/OSX/EmulatorWindowController.m @@ -252,27 +252,27 @@ } case SHIFT_LT: - c_keys_handle_input(SCODE_L_SHIFT, ([event modifierFlags] & NSShiftKeyMask), 0); + keys_handleInput(SCODE_L_SHIFT, /*is_pressed:*/([event modifierFlags] & NSShiftKeyMask), /*is_ascii:*/false); break; case SHIFT_RT: - c_keys_handle_input(SCODE_R_SHIFT, ([event modifierFlags] & NSShiftKeyMask), 0); + keys_handleInput(SCODE_R_SHIFT, /*is_pressed:*/([event modifierFlags] & NSShiftKeyMask), /*is_ascii:*/false); break; case CTRL_LT: - c_keys_handle_input(SCODE_L_CTRL, ([event modifierFlags] & NSControlKeyMask), 0); + keys_handleInput(SCODE_L_CTRL, /*is_pressed:*/([event modifierFlags] & NSControlKeyMask), /*is_ascii:*/false); break; case CTRL_RT: - c_keys_handle_input(SCODE_R_CTRL, ([event modifierFlags] & NSControlKeyMask), 0); + keys_handleInput(SCODE_R_CTRL, /*is_pressed:*/([event modifierFlags] & NSControlKeyMask), /*is_ascii:*/false); break; case ALT_LT: - c_keys_handle_input(SCODE_L_ALT, ([event modifierFlags] & NSAlternateKeyMask), 0); + keys_handleInput(SCODE_L_ALT, /*is_pressed:*/([event modifierFlags] & NSAlternateKeyMask), /*is_ascii:*/false); break; case ALT_RT: - c_keys_handle_input(SCODE_R_ALT, ([event modifierFlags] & NSAlternateKeyMask), 0); + keys_handleInput(SCODE_R_ALT, /*is_pressed:*/([event modifierFlags] & NSAlternateKeyMask), /*is_ascii:*/false); break; default: @@ -378,7 +378,7 @@ default: if ([event modifierFlags] & NSControlKeyMask) { - scode = c_keys_ascii_to_scancode(scode); + scode = keys_ascii2Scancode(scode); cooked = 0; } else @@ -388,7 +388,7 @@ break; } - c_keys_handle_input(scode, pressed, cooked); + keys_handleInput(scode, pressed, cooked); } - (void)keyUp:(NSEvent *)event diff --git a/src/keys.c b/src/keys.c index 786bd96f..294ab690 100644 --- a/src/keys.c +++ b/src/keys.c @@ -15,8 +15,16 @@ #include "common.h" +#define DEBUG_KEYS 0 +#if DEBUG_KEYS +# define KEY_LOG(...) LOG(__VA_ARGS__) +#else +# define KEY_LOG(...) +#endif + static int next_key = -1; static int last_scancode = -1; + bool caps_lock = true; // default enabled because so much breaks otherwise bool use_system_caps_lock = false; @@ -183,26 +191,24 @@ uint8_t keys_apple2ASCII(uint8_t c, OUTPARM font_mode_t *mode) { } } -int c_keys_ascii_to_scancode(int c) -{ +int keys_ascii2Scancode(uint8_t c) { return scode_map[c&0x7f]; } -int c_keys_is_shifted() -{ +bool keys_isShifted(void) { return key_pressed[SCODE_L_SHIFT] || key_pressed[SCODE_R_SHIFT]; } -/* ------------------------------------------------------------------------- - Handle input : keys and joystick. - ------------------------------------------------------------------------- */ -void c_keys_handle_input(int scancode, int pressed, int is_cooked) -{ - int *keymap = NULL; +// ---------------------------------------------------------------------------- +// Handle input, both for keys and joystick. +// +// NOTE: `scancode` can be either a scancode or an ASCII key. +void keys_handleInput(int scancode, bool is_pressed, bool is_ascii) { + KEY_LOG("keys ... scancode:%d is_pressed:%d is_ascii:%d", scancode, is_pressed, is_ascii); - if (is_cooked) { + if (is_ascii) { last_scancode = -1; - if (!pressed) { + if (!is_pressed) { return; } if (! (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ]) ) { @@ -215,57 +221,45 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked) assert(scancode < 0x80); last_scancode = scancode; + int *keymap = NULL; if ((key_pressed[ SCODE_L_SHIFT ] || key_pressed[ SCODE_R_SHIFT ]) && - (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ])) + (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ])) { keymap = apple_iie_keymap_shift_ctrl; - } - else if (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ]) - { + } else if (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ]) { keymap = apple_iie_keymap_ctrl; - } - else if (key_pressed[ SCODE_L_SHIFT ] || key_pressed[ SCODE_R_SHIFT ]) - { + } else if (key_pressed[ SCODE_L_SHIFT ] || key_pressed[ SCODE_R_SHIFT ]) { keymap = apple_iie_keymap_shifted; - } - else if (caps_lock) - { + } else if (caps_lock) { keymap = apple_iie_keymap_caps; - } - else - { + } else { keymap = apple_iie_keymap_plain; } - if (pressed) - { + if (is_pressed) { key_pressed[ scancode ] = 1; - switch (keymap[ scancode ]) - { - case JB0: - run_args.joy_button0 = 0xff; /* open apple */ - break; - case JB1: - run_args.joy_button1 = 0xff; /* closed apple */ - break; - default: - next_key = keymap[scancode]; - break; + switch (keymap[ scancode ]) { + case JB0: + run_args.joy_button0 = 0xff; /* open apple */ + break; + case JB1: + run_args.joy_button1 = 0xff; /* closed apple */ + break; + default: + next_key = keymap[ scancode ]; + break; } - } - else - { + } else { key_pressed[ scancode ] = 0; - switch (keymap[ scancode ]) - { - case JB0: - run_args.joy_button0 = 0x00; - break; - case JB1: - run_args.joy_button1 = 0x00; - break; - default: - break; + switch (keymap[ scancode ]) { + case JB0: + run_args.joy_button0 = 0x00; + break; + case JB1: + run_args.joy_button1 = 0x00; + break; + default: + break; } } } @@ -282,16 +276,14 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked) int current_key = next_key; next_key = -1; - if (current_key < 128) - { + if (current_key < 0x80) { apple_ii_64k[0][0xC000] = current_key | 0x80; apple_ii_64k[1][0xC000] = current_key | 0x80; break; } #ifdef INTERFACE_CLASSIC - if (current_key == kF9) - { + if (current_key == kF9) { cpu_pause(); timing_toggleCPUSpeed(); cpu_resume(); @@ -367,18 +359,15 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked) } #endif - if (current_key == kEND) - { - if (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ]) - { + if (current_key == kEND) { + if (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ]) { cpu65_interrupt(ResetSig); } break; } #ifdef INTERFACE_CLASSIC - if ( c_keys_is_interface_key(current_key) || (current_key == kPAUSE) ) - { + if ( c_keys_is_interface_key(current_key) || (current_key == kPAUSE) ) { c_interface_begin(current_key); } #endif @@ -388,8 +377,7 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked) #ifdef KEYPAD_JOYSTICK // Keypad emulated joystick relies on "raw" keyboard input - if (joy_mode == JOY_KPAD) - { + if (joy_mode == JOY_KPAD) { bool joy_x_axis_unpressed = !( key_pressed[SCODE_KPAD_L] || key_pressed[SCODE_KPAD_R] || key_pressed[SCODE_KPAD_UL] || key_pressed[SCODE_KPAD_DL] || key_pressed[SCODE_KPAD_UR] || key_pressed[SCODE_KPAD_DR] || // and allow regular PC arrow keys to manipulate joystick... @@ -398,8 +386,7 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked) key_pressed[SCODE_KPAD_UL] || key_pressed[SCODE_KPAD_DL] || key_pressed[SCODE_KPAD_UR] || key_pressed[SCODE_KPAD_DR] || key_pressed[SCODE_U] || key_pressed[SCODE_D]); - if (key_pressed[ SCODE_KPAD_C ]) - { + if (key_pressed[ SCODE_KPAD_C ]) { joy_x = HALF_JOY_RANGE; joy_y = HALF_JOY_RANGE; } @@ -427,50 +414,34 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked) } } - if (key_pressed[ SCODE_KPAD_UL ] || key_pressed[ SCODE_KPAD_U ] || key_pressed[ SCODE_KPAD_UR ] ||/* regular arrow up */key_pressed[ SCODE_U ]) - { - if (joy_y > joy_step) - { + if (key_pressed[ SCODE_KPAD_UL ] || key_pressed[ SCODE_KPAD_U ] || key_pressed[ SCODE_KPAD_UR ] ||/* regular arrow up */key_pressed[ SCODE_U ]) { + if (joy_y > joy_step) { joy_y -= joy_step; - } - else - { + } else { joy_y = 0; } } - if (key_pressed[ SCODE_KPAD_DL ] || key_pressed[ SCODE_KPAD_D ] || key_pressed[ SCODE_KPAD_DR ] ||/* regular arrow dn */key_pressed[ SCODE_D ]) - { - if (joy_y < JOY_RANGE - joy_step) - { + if (key_pressed[ SCODE_KPAD_DL ] || key_pressed[ SCODE_KPAD_D ] || key_pressed[ SCODE_KPAD_DR ] ||/* regular arrow dn */key_pressed[ SCODE_D ]) { + if (joy_y < JOY_RANGE - joy_step) { joy_y += joy_step; - } - else - { + } else { joy_y = JOY_RANGE-1; } } - if (key_pressed[ SCODE_KPAD_UL ] || key_pressed[ SCODE_KPAD_L ] || key_pressed[ SCODE_KPAD_DL ] ||/* regular arrow l */key_pressed[ SCODE_L ]) - { - if (joy_x > joy_step) - { + if (key_pressed[ SCODE_KPAD_UL ] || key_pressed[ SCODE_KPAD_L ] || key_pressed[ SCODE_KPAD_DL ] ||/* regular arrow l */key_pressed[ SCODE_L ]) { + if (joy_x > joy_step) { joy_x -= joy_step; - } - else - { + } else { joy_x = 0; } } - if (key_pressed[ SCODE_KPAD_UR ] || key_pressed[ SCODE_KPAD_R ] || key_pressed[ SCODE_KPAD_DR ] ||/* regular arrow r */key_pressed[ SCODE_R ]) - { - if (joy_x < JOY_RANGE - joy_step) - { + if (key_pressed[ SCODE_KPAD_UR ] || key_pressed[ SCODE_KPAD_R ] || key_pressed[ SCODE_KPAD_DR ] ||/* regular arrow r */key_pressed[ SCODE_R ]) { + if (joy_x < JOY_RANGE - joy_step) { joy_x += joy_step; - } - else - { + } else { joy_x = JOY_RANGE-1; } } @@ -478,12 +449,12 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked) #endif } +#ifdef INTERFACE_CLASSIC int c_rawkey() { return last_scancode; } -#ifdef INTERFACE_CLASSIC int c_mygetch(int block) { int retval; diff --git a/src/keys.h b/src/keys.h index d2198f17..157a694d 100644 --- a/src/keys.h +++ b/src/keys.h @@ -138,15 +138,16 @@ extern bool caps_lock; extern bool use_system_caps_lock; +#ifdef INTERFACE_CLASSIC int c_mygetch(int block); int c_rawkey(void); -#ifdef INTERFACE_CLASSIC void c_keys_set_key(int key); bool c_keys_is_interface_key(int key); #endif -int c_keys_is_shifted(void); -int c_keys_ascii_to_scancode(int ch); -void c_keys_handle_input(int scancode, int pressed, int is_cooked); + +bool keys_isShifted(void); +int keys_ascii2Scancode(uint8_t ch); +void keys_handleInput(int scan_or_key, bool is_pressed, bool is_ascii); uint8_t keys_apple2ASCII(uint8_t c, OUTPARM font_mode_t *mode); diff --git a/src/video/glnode.c b/src/video/glnode.c index d3327d4e..b052452f 100644 --- a/src/video/glnode.c +++ b/src/video/glnode.c @@ -96,7 +96,7 @@ static void _glnode_updateGLUT(int unused) { } #endif - c_keys_handle_input(-1, 0, 0); + keys_handleInput(/*scancode:*/-1, /*is_pressed:*/false, /*is_ascii:*/false); glutPostRedisplay(); glutTimerFunc(17, _glnode_updateGLUT, 0); } diff --git a/src/video/gltouchjoy_kpad.c b/src/video/gltouchjoy_kpad.c index a33e5d68..a68595c3 100644 --- a/src/video/gltouchjoy_kpad.c +++ b/src/video/gltouchjoy_kpad.c @@ -142,7 +142,7 @@ static void touchkpad_keyboardReadCallback(void) { #warning FIXME TODO : implement proper keyboard repeat callback timing if (kpad.lastScancode >= 0) { - c_keys_handle_input(kpad.lastScancode, /*pressed:*/false, /*ASCII:*/false); + keys_handleInput(kpad.lastScancode, /*is_pressed:*/false, /*is_ascii:*/false); kpad.lastScancode = -1; } @@ -156,7 +156,7 @@ static void touchkpad_keyboardReadCallback(void) { struct timespec deltat = timespec_diff(kpad.timingBegins[kpad.fireIdx], now, NULL); if (deltat.tv_sec || deltat.tv_nsec > kpad.repeatThresholdNanos) { TOUCH_JOY_LOG("ACTIVE(%d,%d) REPEAT #%d/%lu/%lu: %d", kpad.axisLock, kpad.buttonLock, kpad.fireIdx, deltat.tv_sec, deltat.tv_nsec, scancode); - c_keys_handle_input(scancode, /*pressed:*/true, /*ASCII:*/false); + keys_handleInput(scancode, /*is_pressed:*/true, /*is_ascii:*/false); kpad.lastScancode = scancode; fired = kpad.fireIdx; } @@ -225,13 +225,13 @@ static void touchkpad_resetState(void) { for (unsigned int i=0; i %02X(%d)", key, key, scancode, scancode); - c_keys_handle_input(scancode, 1, 0); + keys_handleInput(scancode, /*is_pressed:*/true, /*is_ascii:*/false); } void gldriver_on_key_special_up(int key, int x, int y) { _capslock_hackaround(); int scancode = _glutkey_to_scancode(key); //LOG("onKeySpecialDown %08x(%d) -> %02X(%d)", key, key, scancode, scancode); - c_keys_handle_input(scancode, 0, 0); + keys_handleInput(scancode, /*is_pressed:*/false, /*is_ascii:*/false); } #define JOYSTICK_POLL_INTERVAL_MILLIS (ceilf(1000.f/60)) diff --git a/src/video/ncvideo.c b/src/video/ncvideo.c index 2115863c..2f3d6f88 100644 --- a/src/video/ncvideo.c +++ b/src/video/ncvideo.c @@ -318,10 +318,10 @@ static void _nc_convertAppleGlyphs(INOUT chtype *c, OUTPARM char **s, uint8_t *c } } -static int _nc_keyToEmulator(int ncKey, int *isCooked) { +static int _nc_keyToEmulator(int ncKey, bool *is_ascii) { int a2key = ncKey; - bool isASCII = false; + *is_ascii = false; switch (ncKey) { case KEY_F(1): @@ -388,14 +388,13 @@ static int _nc_keyToEmulator(int ncKey, int *isCooked) { case ASCII_TAB: default: if (a2key >= 0 && a2key < 256) { - isASCII = true; + is_ascii = true; } else { a2key = -1; } break; } - *isCooked = isASCII; return a2key; } @@ -548,18 +547,13 @@ static void ncvideo_main_loop(void) { // handle keyboard input int c = getch(); - int is_ascii = 0; if (c == ERR) { - c_keys_handle_input(-1, /*pressed:*/0, /*is_ascii:*/0); + keys_handleInput(/*scancode:*/-1, /*is_pressed:*/false, /*is_ascii:*/false); } else { + bool is_ascii = false; c = _nc_keyToEmulator(c, &is_ascii); - - if (is_ascii) { - c_keys_handle_input(c, /*pressed:*/1, /*is_ascii:*/1); - } else { - c_keys_handle_input(c, /*pressed:*/1, /*is_ascii:*/0); - c_keys_handle_input(c, /*pressed:*/0, /*is_ascii:*/0); - } + keys_handleInput(/*scancode:*/c, /*is_pressed:*/true, is_ascii); + keys_handleInput(/*scancode:*/c, /*is_pressed:*/false, is_ascii); } // FIXME TODO ... does not account for execution time drift diff --git a/src/video/xvideo.c b/src/video/xvideo.c index ac38f67d..6de3e1c6 100644 --- a/src/video/xvideo.c +++ b/src/video/xvideo.c @@ -406,19 +406,19 @@ void video_driver_sync(void) { post_image(); if (!XPending(display)) { - c_keys_handle_input(/*scancode:*/-1, /*pressed:*/0, 0); + keys_handleInput(/*scancode:*/-1, /*is_pressed:*/false, /*is_ascii:*/false); } else { do { XNextEvent(display, &xevent); int scancode = -1; - int pressed = 0; + bool is_pressed = false; if (xevent.type == KeyPress || xevent.type == KeyRelease) { scancode = keysym_to_scancode(); - pressed = (xevent.type == KeyPress); + is_pressed = (xevent.type == KeyPress); } - c_keys_handle_input(scancode, pressed, 0); + keys_handleInput(scancode, is_pressed, /*is_ascii:*/false); } while (XPending(display)); } }