/* * $Source: /cvsroot/dxx-rebirth/d2x-rebirth/arch/svgalib/key.c,v $ * $Revision: 1.1.1.1 $ * $Author: zicodxx $ * $Date: 2006/03/17 19:54:30 $ * * SVGALib keyboard input support * * $Log: key.c,v $ * Revision 1.1.1.1 2006/03/17 19:54:30 zicodxx * initial import * * Revision 1.2 2003/02/27 22:07:21 btb * use timer_delay instead of d_delay * * Revision 1.1 2001/10/24 09:25:05 bradleyb * Moved input stuff to arch subdirs, as in d1x. * * Revision 1.2 2001/01/29 14:03:57 bradleyb * Fixed build, minor fixes * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "event.h" #include "error.h" #include "key.h" #include "timer.h" #define KEY_BUFFER_SIZE 16 static unsigned char Installed = 0; //-------- Variable accessed by outside functions --------- unsigned char keyd_buffer_type; // 0=No buffer, 1=buffer ASCII, 2=buffer scans unsigned char keyd_repeat; unsigned char keyd_editor_mode; volatile unsigned char keyd_last_pressed; volatile unsigned char keyd_last_released; volatile unsigned char keyd_pressed[256]; volatile int keyd_time_when_last_pressed; typedef struct Key_info { ubyte state; // state of key 1 == down, 0 == up ubyte last_state; // previous state of key int counter; // incremented each time key is down in handler fix timewentdown; // simple counter incremented each time in interrupt and key is down fix timehelddown; // counter to tell how long key is down -- gets reset to 0 by key routines ubyte downcount; // number of key counts key was down ubyte upcount; // number of times key was released } Key_info; typedef struct keyboard { unsigned short keybuffer[KEY_BUFFER_SIZE]; Key_info keys[256]; fix time_pressed[KEY_BUFFER_SIZE]; unsigned int keyhead, keytail; } keyboard; static /*volatile*/ keyboard key_data; char *key_text[256]; unsigned char ascii_table[128] = { 255, 255, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',255,255, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 255, 255, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`', 255, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 255,'*', 255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255, 255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255 }; unsigned char shifted_ascii_table[128] = { 255, 255, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',255,255, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 255, 255, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 255, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 255,255, 255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255, 255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255 }; //killed on 10/03/98 by Matt Mueller //unsigned char key_to_ascii(int a) //{ // if (!isprint(a)) return 255; // if (a & KEY_SHIFTED) { // return (toupper((unsigned char) a)); // } else { // return ((unsigned char) a); // } //} //end kill -MM //added on 10/03/98 by Matt Mueller to fix shifted keys (copied from dos/key.c) unsigned char key_to_ascii(int keycode) { int shifted; shifted = keycode & KEY_SHIFTED; keycode &= 0xFF; if ( keycode>=127 ) return 255; if (shifted) return shifted_ascii_table[keycode]; else return ascii_table[keycode]; } //end addition -MM void key_handler(int scancode, int press) { ubyte state, key_state; int i, keycode, event_key; Key_info *key; unsigned char temp; if (press == KEY_EVENTPRESS) key_state = 1; else if (press == KEY_EVENTRELEASE) key_state = 0; else return; event_key = scancode; //===================================================== //Here a translation from win keycodes to mac keycodes! //===================================================== for (i = 255; i >= 0; i--) { keycode = i; key = &(key_data.keys[keycode]); if (i == event_key) state = key_state; else state = key->last_state; if ( key->last_state == state ) { if (state) { key->counter++; keyd_last_pressed = keycode; keyd_time_when_last_pressed = timer_get_fixed_seconds(); } } else { if (state) { keyd_last_pressed = keycode; keyd_pressed[keycode] = 1; key->downcount += state; key->state = 1; key->timewentdown = keyd_time_when_last_pressed = timer_get_fixed_seconds(); key->counter++; } else { keyd_pressed[keycode] = 0; keyd_last_released = keycode; key->upcount += key->state; key->state = 0; key->counter = 0; key->timehelddown += timer_get_fixed_seconds() - key->timewentdown; } } if ( (state && !key->last_state) || (state && key->last_state && (key->counter > 30) && (key->counter & 0x01)) ) { 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; if ( keyd_pressed[KEY_DELETE] ) keycode |= KEY_DEBUGGED; 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; } } key->last_state = state; } } void key_close() { Installed = 0; keyboard_close(); } void key_init() { if (keyboard_init()) Error ("SVGAlib Keyboard Init Failed"); Installed=1; keyboard_seteventhandler (key_handler); keyd_time_when_last_pressed = timer_get_fixed_seconds(); keyd_buffer_type = 1; keyd_repeat = 1; // Clear the keyboard array key_flush(); atexit(key_close); } void key_flush() { int i; fix curtime; if (!Installed) key_init(); key_data.keyhead = key_data.keytail = 0; //Clear the keyboard buffer for (i=0; i= KEY_BUFFER_SIZE ) n=0; return n; } int key_checkch() { int is_one_waiting = 0; event_poll(); if (key_data.keytail!=key_data.keyhead) is_one_waiting = 1; return is_one_waiting; } int key_inkey() { int key = 0; if (!Installed) key_init(); event_poll(); if (key_data.keytail!=key_data.keyhead) { key = key_data.keybuffer[key_data.keyhead]; key_data.keyhead = add_one(key_data.keyhead); } //added 9/3/98 by Matt Mueller to free cpu time instead of hogging during menus and such // else timer_delay(1); //end addition - Matt Mueller return key; } int key_inkey_time(fix * time) { int key = 0; if (!Installed) key_init(); event_poll(); if (key_data.keytail!=key_data.keyhead) { key = key_data.keybuffer[key_data.keyhead]; *time = key_data.time_pressed[key_data.keyhead]; key_data.keyhead = add_one(key_data.keyhead); } return key; } int key_peekkey() { int key = 0; event_poll(); if (key_data.keytail!=key_data.keyhead) key = key_data.keybuffer[key_data.keyhead]; return key; } int key_getch() { int dummy=0; if (!Installed) return 0; // return getch(); while (!key_checkch()) dummy++; return key_inkey(); } unsigned int key_get_shift_status() { unsigned int shift_status = 0; if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) shift_status |= KEY_SHIFTED; if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) shift_status |= KEY_ALTED; if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) shift_status |= KEY_CTRLED; #ifndef NDEBUG if (keyd_pressed[KEY_DELETE]) shift_status |=KEY_DEBUGGED; #endif return shift_status; } // Returns the number of seconds this key has been down since last call. fix key_down_time(int scancode) { fix time_down, time; event_poll(); if ((scancode<0)|| (scancode>255)) return 0; if (!keyd_pressed[scancode]) { time_down = key_data.keys[scancode].timehelddown; key_data.keys[scancode].timehelddown = 0; } else { time = timer_get_fixed_seconds(); time_down = time - key_data.keys[scancode].timewentdown; key_data.keys[scancode].timewentdown = time; } return time_down; } unsigned int key_down_count(int scancode) { int n; event_poll(); if ((scancode<0)|| (scancode>255)) return 0; n = key_data.keys[scancode].downcount; key_data.keys[scancode].downcount = 0; return n; } unsigned int key_up_count(int scancode) { int n; event_poll(); if ((scancode<0)|| (scancode>255)) return 0; n = key_data.keys[scancode].upcount; key_data.keys[scancode].upcount = 0; return n; }