void key_init() { // Initialize queue if (key_inited) return; key_inited = 1; INITIALIZE_CRITICAL_SECTION(key_lock); ENTER_CRITICAL_SECTION(key_lock); #ifdef SCP_UNIX FillSDLArray(); #endif keyd_time_when_last_pressed = timer_get_milliseconds(); keyd_buffer_type = 1; keyd_repeat = 1; // Clear the keyboard array key_flush(); // Clear key filter key_clear_filter(); LEAVE_CRITICAL_SECTION(key_lock); #ifdef _WIN32 #ifdef USE_DIRECTINPUT di_init(); #endif OSVERSIONINFO ver; ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&ver); if ( ver.dwPlatformId == VER_PLATFORM_WIN32_NT ) { Key_running_NT = 1; } else { Key_running_NT = 0; if ( key_numlock_is_on() ) { Key_numlock_was_on = 1; key_turn_off_numlock(); } } #endif atexit(key_close); }
// Add a key up or down code to the key buffer. state=1 -> down, state=0 -> up // latency => time difference in ms between when key was actually pressed and now //void key_mark( uint code, int state ) void key_mark( uint code, int state, uint latency ) { uint scancode, breakbit, temp, event_time; ushort keycode; if ( !key_inited ) return; ENTER_CRITICAL_SECTION( key_lock ); // If running in the UK, need to translate their wacky slash scancode to ours if ( code == KEY_SLASH_UK ) { code = KEY_SLASH; } #ifndef SCP_UNIX if ( (code == 0xc5) && !Key_running_NT ) { key_turn_off_numlock(); } #endif Assert( code < NUM_KEYS ); event_time = timer_get_milliseconds() - latency; // event_time = timeGetTime() - latency; // Read in scancode scancode = code & (NUM_KEYS-1); breakbit = !state; if (breakbit) { // Key going up keyd_last_released = scancode; keyd_pressed[scancode] = 0; key_data.NumUps[scancode]++; // What is the point of this code? "temp" is never used! temp = 0; temp |= keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]; temp |= keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT]; temp |= keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL]; temp |= keyd_pressed[KEY_DEBUG_KEY]; if (event_time < key_data.TimeKeyWentDown[scancode]) { key_data.TimeKeyHeldDown[scancode] = 0; } else { key_data.TimeKeyHeldDown[scancode] += event_time - key_data.TimeKeyWentDown[scancode]; } Current_key_down = scancode; if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) { Current_key_down |= KEY_SHIFTED; } if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) { Current_key_down |= KEY_ALTED; } if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) { Current_key_down |= KEY_CTRLED; } Script_system.SetHookVar("Key", 's', textify_scancode(Current_key_down)); Script_system.RunCondition(CHA_KEYRELEASED); Script_system.RemHookVar("Key"); } else { // Key going down keyd_last_pressed = scancode; keyd_time_when_last_pressed = event_time; if (!keyd_pressed[scancode]) { // First time down key_data.TimeKeyWentDown[scancode] = event_time; keyd_pressed[scancode] = 1; key_data.NumDowns[scancode]++; key_data.down_check[scancode]++; //WMC - For scripting Current_key_down = scancode; if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) { Current_key_down |= KEY_SHIFTED; } if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) { Current_key_down |= KEY_ALTED; } if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) { Current_key_down |= KEY_CTRLED; } Script_system.SetHookVar("Key", 's', textify_scancode(Current_key_down)); Script_system.RunCondition(CHA_KEYPRESSED); Script_system.RemHookVar("Key"); } else if (!keyd_repeat) { // Don't buffer repeating key if repeat mode is off scancode = 0xAA; } if ( scancode!=0xAA ) { keycode = (unsigned short)scancode; if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) { keycode |= KEY_SHIFTED; } if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) { keycode |= KEY_ALTED; } if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) { keycode |= KEY_CTRLED; } #ifndef NDEBUG if ( keyd_pressed[KEY_DEBUG_KEY] ) { keycode |= KEY_DEBUGGED; } #else if ( keyd_pressed[KEY_DEBUG_KEY] ) { mprintf(("Cheats_enabled = %i, Key_normal_game = %i\n", Cheats_enabled, Key_normal_game)); if (Cheats_enabled && Key_normal_game) { keycode |= KEY_DEBUGGED1; } } #endif if ( keycode ) { temp = key_data.keytail+1; if ( temp >= KEY_BUFFER_SIZE ) temp=0; if (temp!=key_data.keyhead) { key_data.keybuffer[key_data.keytail] = keycode; key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed; key_data.keytail = temp; } } } } LEAVE_CRITICAL_SECTION( key_lock ); }
// Add a key up or down code to the key buffer. state=1 -> down, state=0 -> up // latency => time difference in ms between when key was actually pressed and now //void key_mark( uint code, int state ) void key_mark( uint code, int state, uint latency ) { uint scancode, breakbit, temp, event_time; ushort keycode; if ( !key_inited ) return; ENTER_CRITICAL_SECTION( key_lock ); // If running in the UK, need to translate their wacky slash scancode to ours if ( code == KEY_SLASH_UK ) { code = KEY_SLASH; } if(Lcl_fr){ switch (code) { case KEY_A: code = KEY_Q; break; case KEY_M: code = KEY_COMMA; break; case KEY_Q: code = KEY_A; break; case KEY_W: code = KEY_Z; break; case KEY_Z: code = KEY_W; break; case KEY_SEMICOL: code = KEY_M; break; case KEY_COMMA: code = KEY_SEMICOL; break; } #if defined(SCP_UNIX) && !defined(__APPLE__) } else if(Lcl_gr){ switch (code) { case KEY_Y: code = KEY_Z; break; case KEY_Z: code = KEY_Y; break; } #endif } if ( (code == 0xc5) && !Key_running_NT ) { key_turn_off_numlock(); } Assert( code < NUM_KEYS ); event_time = timer_get_milliseconds() - latency; // event_time = timeGetTime() - latency; // Read in scancode scancode = code & (NUM_KEYS-1); breakbit = !state; if (breakbit) { // Key going up keyd_last_released = scancode; keyd_pressed[scancode] = 0; key_data.NumUps[scancode]++; // What is the point of this code? "temp" is never used! temp = 0; temp |= keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]; temp |= keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT]; temp |= keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL]; //#ifndef NDEBUG temp |= keyd_pressed[KEY_DEBUG_KEY]; //#endif if (event_time < key_data.TimeKeyWentDown[scancode]) key_data.TimeKeyHeldDown[scancode] = 0; else key_data.TimeKeyHeldDown[scancode] += event_time - key_data.TimeKeyWentDown[scancode]; } else { // Key going down keyd_last_pressed = scancode; keyd_time_when_last_pressed = event_time; if (!keyd_pressed[scancode]) { // First time down key_data.TimeKeyWentDown[scancode] = event_time; keyd_pressed[scancode] = 1; key_data.NumDowns[scancode]++; key_data.down_check[scancode]++; // mprintf(( "Scancode = %x\n", scancode )); // if ( scancode == KEY_BREAK ) // Int3(); } else if (!keyd_repeat) { // Don't buffer repeating key if repeat mode is off scancode = 0xAA; } if ( scancode!=0xAA ) { keycode = (unsigned short)scancode; if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) keycode |= KEY_SHIFTED; if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) keycode |= KEY_ALTED; if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) keycode |= KEY_CTRLED; #ifndef NDEBUG if ( keyd_pressed[KEY_DEBUG_KEY] ) keycode |= KEY_DEBUGGED; // if ( keycode == (KEY_BACKSP + KEY_DEBUGGED) ) { // keycode = 0; // keyd_pressed[KEY_DEBUG_KEY] = 0; // keyd_pressed[KEY_BACKSP] = 0; // Int3(); // } #else if ( keyd_pressed[KEY_DEBUG_KEY] ) { mprintf(("Cheats_enabled = %i, Key_normal_game = %i\n", Cheats_enabled, Key_normal_game)); if (Cheats_enabled && Key_normal_game) { keycode |= KEY_DEBUGGED1; } } #endif if ( keycode ) { temp = key_data.keytail+1; if ( temp >= KEY_BUFFER_SIZE ) temp=0; if (temp!=key_data.keyhead) { int i, accept_key = 1; // Num_filter_keys will only be non-zero when a key filter has // been explicity set up via key_set_filter() for ( i = 0; i < Num_filter_keys; i++ ) { accept_key = 0; if ( Key_filter[i] == keycode ) { accept_key = 1; break; } } if ( accept_key ) { key_data.keybuffer[key_data.keytail] = keycode; key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed; key_data.keytail = temp; } } } } } LEAVE_CRITICAL_SECTION( key_lock ); }