diff --git a/CHANGELOG.txt b/CHANGELOG.txt index a3f252024..3a0b8e4b2 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,7 @@ D2X-Rebirth Changelog 20081118 -------- main/console.c: When printing Gamelog, make sure canvas is NULL +main/newmenu.c, main/multi.c, main/automap.c, main/gamecntl.c, ui/inputbox.c, ui/menubar.c, arch/sdl/event.c, arch/sdl/key.c, arch/include/key.h: Yet another UNICODE overhaul - Using seperate buffer for UNICODE chars and only use it in key_ascii() while still using keysyms for the rest of the program so we do not screw up readings by key values altered by modifers - possibly still room to optimize 20081115 -------- diff --git a/arch/include/key.h b/arch/include/key.h index e15de7d1c..af6cdab32 100644 --- a/arch/include/key.h +++ b/arch/include/key.h @@ -12,23 +12,9 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* - * $Source: /cvsroot/dxx-rebirth/d2x-rebirth/arch/include/key.h,v $ - * $Revision: 1.1.1.1 $ - * $Author: zicodxx $ - * $Date: 2006/03/17 19:54:32 $ * * Header for keyboard functions * - * $Log: key.h,v $ - * Revision 1.1.1.1 2006/03/17 19:54:32 zicodxx - * initial import - * - * Revision 1.2 2001/01/28 16:21:54 bradleyb - * More header unification... - * - * Revision 1.1 2001/01/28 05:46:33 bradleyb - * Unified arch headers - * */ #ifndef _KEY_H @@ -37,6 +23,8 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "pstypes.h" #include "fix.h" +#define KEY_BUFFER_SIZE 16 + //========================================================================== // This installs the int9 vector and initializes the keyboard in buffered // ASCII mode. key_close simply undoes that. @@ -57,6 +45,9 @@ extern unsigned char keyd_editor_mode; // Time in seconds when last key was pressed... extern volatile int keyd_time_when_last_pressed; +// Stores Unicode values registered in one event_loop call +unsigned char unicode_frame_buffer[KEY_BUFFER_SIZE]; + //========================================================================== // These are the "buffered" keypress routines. Use them by setting the // "keyd_buffer_type" variable. @@ -69,7 +60,7 @@ extern int key_inkey(); // Gets key if one, other returns 0. extern int key_inkey_time(fix *time); // Same as inkey, but returns the time the key was pressed down. extern int key_peekkey(); // Same as inkey, but doesn't remove key from buffer. -extern unsigned char key_to_ascii(int keycode); +extern unsigned char key_ascii(); extern void key_debug(); // Does an INT3 diff --git a/arch/sdl/event.c b/arch/sdl/event.c index bdc3ff194..902bb06fa 100644 --- a/arch/sdl/event.c +++ b/arch/sdl/event.c @@ -12,55 +12,56 @@ #include #include +#include "key.h" #include extern void key_handler(SDL_KeyboardEvent *event); extern void mouse_button_handler(SDL_MouseButtonEvent *mbe); extern void mouse_motion_handler(SDL_MouseMotionEvent *mme); -#ifndef USE_LINUX_JOY // stpohle - so we can choose at compile time.. extern void joy_button_handler(SDL_JoyButtonEvent *jbe); extern void joy_hat_handler(SDL_JoyHatEvent *jhe); extern void joy_axis_handler(SDL_JoyAxisEvent *jae); -#endif static int initialised=0; void event_poll() { SDL_Event event; + int clean_uniframe=1; while (SDL_PollEvent(&event)) { switch(event.type) { - case SDL_KEYDOWN: - case SDL_KEYUP: - key_handler((SDL_KeyboardEvent *)&event); - break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - mouse_button_handler((SDL_MouseButtonEvent *)&event); - break; - case SDL_MOUSEMOTION: - mouse_motion_handler((SDL_MouseMotionEvent *)&event); - break; -#ifndef USE_LINUX_JOY // stpohle - so we can choose at compile time.. - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - joy_button_handler((SDL_JoyButtonEvent *)&event); - break; - case SDL_JOYAXISMOTION: - joy_axis_handler((SDL_JoyAxisEvent *)&event); - break; - case SDL_JOYHATMOTION: - joy_hat_handler((SDL_JoyHatEvent *)&event); - break; - case SDL_JOYBALLMOTION: - break; -#endif - case SDL_QUIT: { - void quit_request(); - quit_request(); - } break; + case SDL_KEYDOWN: + case SDL_KEYUP: + if (clean_uniframe) + memset(unicode_frame_buffer,'\0',sizeof(unsigned char)*KEY_BUFFER_SIZE); + clean_uniframe=0; + key_handler((SDL_KeyboardEvent *)&event); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + mouse_button_handler((SDL_MouseButtonEvent *)&event); + break; + case SDL_MOUSEMOTION: + mouse_motion_handler((SDL_MouseMotionEvent *)&event); + break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + joy_button_handler((SDL_JoyButtonEvent *)&event); + break; + case SDL_JOYAXISMOTION: + joy_axis_handler((SDL_JoyAxisEvent *)&event); + break; + case SDL_JOYHATMOTION: + joy_hat_handler((SDL_JoyHatEvent *)&event); + break; + case SDL_JOYBALLMOTION: + break; + case SDL_QUIT: { + void quit_request(); + quit_request(); + } break; } } } diff --git a/arch/sdl/key.c b/arch/sdl/key.c index 188f1fecd..8e330f8d8 100644 --- a/arch/sdl/key.c +++ b/arch/sdl/key.c @@ -20,8 +20,6 @@ #include "key.h" #include "timer.h" -#define KEY_BUFFER_SIZE 16 - static unsigned char Installed = 0; //-------- Variable accessed by outside functions --------- @@ -32,6 +30,7 @@ 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; +unsigned char unicode_frame_buffer[KEY_BUFFER_SIZE] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' }; typedef struct Key_info { ubyte state; // state of key 1 == down, 0 == up @@ -295,96 +294,79 @@ key_props key_properties[256] = { { "", 255, -1 }, { "", 255, -1 }, { "", 255, -1 }, -{ "!", '!', SDLK_EXCLAIM }, -{ "@", '@', SDLK_AT }, -{ "#", '#', SDLK_HASH }, -{ "$", '$', SDLK_DOLLAR }, -{ "%", '%', -1 }, // 240 -{ "^", '^', SDLK_CARET }, -{ "&", '&', SDLK_AMPERSAND }, -{ "(", '(', SDLK_LEFTPAREN }, -{ ")", ')', SDLK_RIGHTPAREN }, -{ "_", '_', SDLK_UNDERSCORE }, -{ "+", '+', SDLK_PLUS }, -{ "{", '{', -1 }, -{ "}", '}', -1 }, -{ ":", ':', SDLK_COLON }, -{ "\"", '"', SDLK_QUOTEDBL }, // 250 -{ "~", '~', -1 }, -{ "|", '|', -1 }, -{ "<", '<', SDLK_LESS }, -{ ">", '>', SDLK_GREATER }, -{ "?", '?', SDLK_QUESTION }, // 255 -}; - -// As UNICODE chars have no RELEASED state, we save each one together with the symbol assigned to it. -// If a symbol is RELEASED, check the list and we know which unicode we just released! -// This way we almost "emulate" the RELEASED state for UNICODE chars. -int sym2unimap[KEY_BUFFER_SIZE][2] = -{ - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, - { -1, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, // 240 +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, // 250 +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, +{ "", 255, -1 }, // 255 }; char *key_text[256]; -unsigned char key_to_ascii(int keycode) +unsigned char key_ascii() { - keycode &= 0xFF; - return key_properties[keycode].ascii_value; + static unsigned char unibuffer[KEY_BUFFER_SIZE] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' }; + int i=0, offset=0, count=0; + + offset=strlen((const char*)unibuffer); + + // move temporal chars from unicode_frame_buffer to empty space behind last unibuffer char (if any) + for (i=offset; i < KEY_BUFFER_SIZE; i++) + if (unicode_frame_buffer[count] != '\0') + { + unibuffer[i]=unicode_frame_buffer[count]; + unicode_frame_buffer[count]='\0'; + count++; + } + + // unibuffer is not empty. store first char, remove it, shift all chars one step left and then print our char + if (unibuffer[0] != '\0') + { + unsigned char retval = unibuffer[0]; + unsigned char unibuffer_shift[KEY_BUFFER_SIZE]; + memset(unibuffer_shift,'\0',sizeof(unsigned char)*KEY_BUFFER_SIZE); + memcpy(unibuffer_shift,unibuffer+1,sizeof(unsigned char)*(KEY_BUFFER_SIZE-1)); + memcpy(unibuffer,unibuffer_shift,sizeof(unsigned char)*KEY_BUFFER_SIZE); + return retval; + } + else + return 255; } -void key_handler(SDL_KeyboardEvent *event) +void key_handler(SDL_KeyboardEvent *event, int counter) { ubyte state; - int i, keycode, event_keysym=-1, event_keyuni=-1, key_state; + int i, keycode, event_keysym=-1, key_state; Key_info *key; unsigned char temp; // Read SDLK symbol and state event_keysym = event->keysym.sym; + key_state = (event->state == SDL_PRESSED); - // Read (latin) unicode - if (event->keysym.unicode > 31 && event->keysym.unicode < 255) - { - event_keyuni = tolower(event->keysym.unicode); - // Now add the UNICODE char to our map (see comment on sym2unimap declaration) + // fill the unicode frame-related unicode buffer + if (key_state && event->keysym.unicode > 31 && event->keysym.unicode < 255) for (i = 0; i < KEY_BUFFER_SIZE; i++) - { - if (sym2unimap[i][0] == -1) + if (unicode_frame_buffer[i] == '\0') { - sym2unimap[i][0] = event_keyuni; - sym2unimap[i][1] = event_keysym; + unicode_frame_buffer[i] = event->keysym.unicode; break; } - } - } - else // no valid UNICODE - possibly 0 - see if we remove it from the list - { - for (i = 0; i < KEY_BUFFER_SIZE; i++) - { - if (event_keysym == sym2unimap[i][1]) - { - event_keyuni = sym2unimap[i][0]; - sym2unimap[i][0] = sym2unimap[i][1] = -1; - } - } - } - key_state = (event->state == SDL_PRESSED); //===================================================== @@ -392,9 +374,7 @@ void key_handler(SDL_KeyboardEvent *event) keycode = i; key = &(key_data.keys[keycode]); - if (key_properties[i].ascii_value == event_keyuni && key_properties[i].ascii_value != 255) - state = key_state; - else if ((event_keyuni == -1 || event_keyuni == event_keysym) && key_properties[i].sym == event_keysym) + if (key_properties[i].sym == event_keysym) state = key_state; else state = key->last_state; @@ -482,12 +462,7 @@ void key_flush() for (i=0; i 0) { - int ascii = key_to_ascii(key); + { + int ascii = key_ascii(); if ((ascii < 255 )) if (Marker_index < 38 ) { diff --git a/main/gamecntl.c b/main/gamecntl.c index 96759c59c..6b56ea125 100644 --- a/main/gamecntl.c +++ b/main/gamecntl.c @@ -1822,7 +1822,7 @@ void FinalCheats(int key) int i; char *cryptstring; - key=key_to_ascii(key); + key=key_ascii(); for (i=0;i<15;i++) CheatBuffer[i]=CheatBuffer[i+1]; @@ -2228,58 +2228,55 @@ void ReadControls() if (Newdemo_state == ND_STATE_PLAYBACK ) update_vcr_state(); - while ((key=key_inkey_time(&key_time)) != 0) { - if (con_events(key) && con_render) - game_flush_inputs(); + key=key_inkey(); - if (DefiningMarkerMessage) - { - MarkerInputMessage(key); - continue; - } + if (con_events(key) && con_render) + return; + + if (DefiningMarkerMessage) + { + MarkerInputMessage(key); + return; + } #ifdef NETWORK - if ( (Game_mode & GM_MULTI) && (multi_sending_message || multi_defining_message) ) - { - multi_message_input_sub(key); - continue; - } + if ( (Game_mode & GM_MULTI) && (multi_sending_message || multi_defining_message) ) + { + multi_message_input_sub(key); + return; + } #endif + #ifndef RELEASE + #ifdef NETWORK + if ((key&KEY_DEBUGGED)&&(Game_mode&GM_MULTI)) { + Network_message_reciever = 100; // Send to everyone... + sprintf( Network_message, "%s %s", TXT_I_AM_A, TXT_CHEATER); + } + #endif + #endif + + if (Player_is_dead) + HandleDeathKey(key); + + if (Endlevel_sequence) + HandleEndlevelKey(key); + else if (Newdemo_state == ND_STATE_PLAYBACK ) { + HandleDemoKey(key); + #ifndef RELEASE - #ifdef NETWORK - if ((key&KEY_DEBUGGED)&&(Game_mode&GM_MULTI)) { - Network_message_reciever = 100; // Send to everyone... - sprintf( Network_message, "%s %s", TXT_I_AM_A, TXT_CHEATER); - } + HandleTestKey(key); #endif + } else { + FinalCheats(key); + + HandleSystemKey(key); + HandleVRKey(key); + HandleGameKey(key); + + #ifndef RELEASE + HandleTestKey(key); #endif - - if (Player_is_dead) - HandleDeathKey(key); - - if (Endlevel_sequence) - HandleEndlevelKey(key); - else if (Newdemo_state == ND_STATE_PLAYBACK ) { - HandleDemoKey(key); - - #ifndef RELEASE - HandleTestKey(key); - #endif - } else { - FinalCheats(key); - - HandleSystemKey(key); - HandleVRKey(key); - HandleGameKey(key); - - #ifndef RELEASE - HandleTestKey(key); - #endif - } -} - -// if ((Players[Player_num].flags & PLAYER_FLAGS_CONVERTER) && keyd_pressed[KEY_F8] && (keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT])) - // transfer_energy_to_shield(key_down_time(KEY_F8)); + } } diff --git a/main/multi.c b/main/multi.c index f4fb0ecd6..f926aaecc 100644 --- a/main/multi.c +++ b/main/multi.c @@ -1292,8 +1292,8 @@ void multi_message_input_sub(int key) game_flush_inputs(); break; default: - if (key > 0) { - int ascii = key_to_ascii(key); + { + int ascii = key_ascii(); if ((ascii < 255 ) && (ascii != 37)) { if (multi_message_index < MAX_MESSAGE_LEN-2 ) { Network_message[multi_message_index++] = ascii; diff --git a/main/newmenu.c b/main/newmenu.c index 96583f8b8..05bb6f1fe 100644 --- a/main/newmenu.c +++ b/main/newmenu.c @@ -1264,7 +1264,7 @@ int newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, item[choice].value--; item[choice].text[item[choice].value] = 0; } else { - ascii = key_to_ascii(k); + ascii = key_ascii(); if ((ascii < 255 ) && (item[choice].value < item[choice].text_len )) { int allowed; @@ -1289,7 +1289,7 @@ int newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, } else if ((item[choice].type!=NM_TYPE_INPUT) && (item[choice].type!=NM_TYPE_INPUT_MENU) ) { - ascii = key_to_ascii(k); + ascii = key_ascii(); if (ascii < 255 ) { int choice1 = choice; ascii = toupper(ascii); @@ -1804,8 +1804,8 @@ ReadFileNames: break; default: - if (key > 0) { - int ascii = key_to_ascii(key); + { + int ascii = key_ascii(); if ( ascii < 255 ) { int cc,cc1; cc=cc1=citem+1; @@ -2105,8 +2105,8 @@ int newmenu_listbox1( char * title, int nitems, char * items[], int allow_abort_ break; default: - if (key > 0) { - int ascii = key_to_ascii(key); + { + int ascii = key_ascii(); if ( ascii < 255 ) { int cc,cc1; cc=cc1=citem+1; diff --git a/ui/inputbox.c b/ui/inputbox.c index 061a7beba..88abfbc32 100644 --- a/ui/inputbox.c +++ b/ui/inputbox.c @@ -143,7 +143,7 @@ void ui_inputbox_do( UI_GADGET_INPUTBOX * inputbox, int keypress ) if (inputbox->first_time) inputbox->first_time = 0; break; default: - ascii = key_to_ascii(keypress); + ascii = key_ascii(); if ((ascii < 255 ) && (inputbox->position < inputbox->length-2)) { if (inputbox->first_time) { diff --git a/ui/menubar.c b/ui/menubar.c index 397e15217..7df2f7066 100644 --- a/ui/menubar.c +++ b/ui/menubar.c @@ -195,7 +195,7 @@ int menu_match_keypress( MENU * menu, int keypress ) keypress &= 0xFF; - c = key_to_ascii(keypress); + c = key_ascii(); for (i=0; i< menu->NumItems; i++ ) {