diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 1132e67ad..52c798309 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,7 @@ D2X-Rebirth Changelog 20110102 -------- main/credits.c, main/kconfig.c, main/menu.c, main/net_udp.c, main/newmenu.c, main/scores.c: Increasing general mouse functionality all over the game: Mouse wheel now can scroll through menu/listbox items; Right mouse button closes a menu (without the need of these ugly close boxes); Also added mouse-closing capabilities to credits, scores and kconfig menus; While being in UDP Netgames list, override keycode at PAGEUP/DOWN keypress to only flip pages without modifying citem also added messagebox showing TXT_INVALID_CHOICE when invalid netgame was chosen +arch/include/key.h, arch/sdl/key.c, main/newmenu.c, main/credits.c: Introduced function key_ismodlck to get the status of modifier keys or sticky keys; Let sticky keys survive flush so we can accurately use their real states; Added key repeating via SDL; Depending on status of KEY_NUMLOCK keypad will either be used as numerical or arrow input in menus; Fixed small typo for mouse.h include in credits.c 20101230 -------- diff --git a/arch/include/key.h b/arch/include/key.h index ac4a9ecf3..5ce593afa 100644 --- a/arch/include/key.h +++ b/arch/include/key.h @@ -25,6 +25,8 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "event.h" #define KEY_BUFFER_SIZE 16 +#define KEY_REPEAT_DELAY 1000 +#define KEY_REPEAT_INTERVAL 100 typedef struct d_event_keycommand { @@ -93,6 +95,10 @@ extern unsigned int key_up_count(int scancode); extern char * key_text[256]; +// for key_ismodlck +#define KEY_ISMOD 1 +#define KEY_ISLCK 2 + #define KEY_SHIFTED 0x100 #define KEY_ALTED 0x200 #define KEY_CTRLED 0x400 diff --git a/arch/sdl/key.c b/arch/sdl/key.c index abcca2430..6f4adfa32 100644 --- a/arch/sdl/key.c +++ b/arch/sdl/key.c @@ -21,7 +21,7 @@ static unsigned char Installed = 0; //-------- Variable accessed by outside functions --------- -unsigned char keyd_buffer_type; // 0=No buffer, 1=buffer ASCII, 2=buffer scans +int keyd_repeat = 0; // 1 = use repeats, 0 no repeats unsigned char keyd_editor_mode; volatile unsigned char keyd_last_pressed; volatile unsigned char keyd_last_released; @@ -32,7 +32,6 @@ unsigned char unicode_frame_buffer[KEY_BUFFER_SIZE] = { '\0', '\0', '\0', '\0', 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 fix64 timewentdown; // simple counter incremented each time in interrupt and key is down fix64 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 @@ -315,6 +314,28 @@ key_props key_properties[256] = { char *key_text[256]; +int key_ismodlck(int keycode) +{ + switch (keycode) + { + case KEY_LSHIFT: + case KEY_RSHIFT: + case KEY_LALT: + case KEY_RALT: + case KEY_LCTRL: + case KEY_RCTRL: + case KEY_LMETA: + case KEY_RMETA: + return KEY_ISMOD; + case KEY_NUMLOCK: + case KEY_SCROLLOCK: + case KEY_CAPSLOCK: + return KEY_ISLCK; + default: + return 0; + } +} + unsigned char key_ascii() { static unsigned char unibuffer[KEY_BUFFER_SIZE] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' }; @@ -379,7 +400,6 @@ void key_handler(SDL_KeyboardEvent *event) if ( key->last_state == state ) { if (state) { - key->counter++; keyd_last_pressed = keycode; keyd_time_when_last_pressed = timer_query(); } @@ -390,17 +410,15 @@ void key_handler(SDL_KeyboardEvent *event) key->downcount += state; key->state = 1; key->timewentdown = keyd_time_when_last_pressed = timer_query(); - key->counter++; } else { keyd_pressed[keycode] = 0; keyd_last_released = keycode; key->upcount += key->state; key->state = 0; - key->counter = 0; key->timehelddown += timer_query() - key->timewentdown; } } - if ( (state && !key->last_state) || (state && key->last_state && (key->counter > 30) && (key->counter & 0x01)) ) { + if ( (state && !key->last_state) || (state && key->last_state && keyd_repeat && !key_ismodlck(i)) ) { if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) keycode |= KEY_SHIFTED; if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT]) @@ -465,9 +483,10 @@ void key_init() Installed=1; SDL_EnableUNICODE(1); + if (SDL_EnableKeyRepeat(KEY_REPEAT_DELAY, KEY_REPEAT_INTERVAL) == 0) + keyd_repeat = 1; keyd_time_when_last_pressed = timer_query(); - keyd_buffer_type = 1; for(i=0; i<256; i++) key_text[i] = key_properties[i].key_text; @@ -479,6 +498,7 @@ void key_init() void key_flush() { int i; + Uint8 *keystate = SDL_GetKeyState(NULL); if (!Installed) key_init(); @@ -493,14 +513,26 @@ void key_flush() } for (i=0; i<256; i++ ) { - keyd_pressed[i] = 0; - key_data.keys[i].state = 1; - key_data.keys[i].last_state = 0; - key_data.keys[i].timewentdown = timer_query(); - key_data.keys[i].downcount=0; - key_data.keys[i].upcount=0; - key_data.keys[i].timehelddown = 0; - key_data.keys[i].counter = 0; + if (key_ismodlck(i) == KEY_ISLCK && keystate[key_properties[i].sym]) // do not flush status of sticky keys + { + keyd_pressed[i] = 1; + key_data.keys[i].state = 0; + key_data.keys[i].last_state = 1; + key_data.keys[i].timewentdown = timer_query(); + key_data.keys[i].downcount=1; + key_data.keys[i].upcount=0; + key_data.keys[i].timehelddown = 1; + } + else + { + keyd_pressed[i] = 0; + key_data.keys[i].state = 1; + key_data.keys[i].last_state = 0; + key_data.keys[i].timewentdown = timer_query(); + key_data.keys[i].downcount=0; + key_data.keys[i].upcount=0; + key_data.keys[i].timehelddown = 0; + } } } @@ -558,27 +590,6 @@ int key_getch() 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. fix64 key_down_time(int scancode) { diff --git a/main/credits.c b/main/credits.c index 03556a217..7f980e0d9 100644 --- a/main/credits.c +++ b/main/credits.c @@ -28,7 +28,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "gr.h" #include "window.h" #include "key.h" -#include "mouse.h +#include "mouse.h" #include "palette.h" #include "game.h" #include "gamepal.h" diff --git a/main/newmenu.c b/main/newmenu.c index e3a883ad9..4530b3153 100644 --- a/main/newmenu.c +++ b/main/newmenu.c @@ -863,19 +863,22 @@ int newmenu_key_command(window *wind, d_event *event, newmenu *menu) int changed = 0; int rval = 1; - switch( k ) + if (keyd_pressed[KEY_NUMLOCK]) { - case KEY_PAD0: k = KEY_0; break; - case KEY_PAD1: k = KEY_1; break; - case KEY_PAD2: k = KEY_2; break; - case KEY_PAD3: k = KEY_3; break; - case KEY_PAD4: k = KEY_4; break; - case KEY_PAD5: k = KEY_5; break; - case KEY_PAD6: k = KEY_6; break; - case KEY_PAD7: k = KEY_7; break; - case KEY_PAD8: k = KEY_8; break; - case KEY_PAD9: k = KEY_9; break; - case KEY_PADPERIOD: k = KEY_PERIOD; break; + switch( k ) + { + case KEY_PAD0: k = KEY_0; break; + case KEY_PAD1: k = KEY_1; break; + case KEY_PAD2: k = KEY_2; break; + case KEY_PAD3: k = KEY_3; break; + case KEY_PAD4: k = KEY_4; break; + case KEY_PAD5: k = KEY_5; break; + case KEY_PAD6: k = KEY_6; break; + case KEY_PAD7: k = KEY_7; break; + case KEY_PAD8: k = KEY_8; break; + case KEY_PAD9: k = KEY_9; break; + case KEY_PADPERIOD: k = KEY_PERIOD; break; + } } old_choice = menu->citem;