From 5deb3054efec963265e40b9155ac6af3149a763a Mon Sep 17 00:00:00 2001 From: black Date: Mon, 6 Jun 2005 20:37:00 +0000 Subject: [PATCH] If the new Key_Event breaks anything for you, you can set #if 0 and activate the old one again. -Moved _Con_DrawString to cl_screen and changed its name to DrawQ_ColoredString. -Changed all the code to allow colored nicks. -Changed Win32 code to support two-char keys (it takes the second byte - may need some more testing). -Rewrote Key_Event to support typing in the ^ key on Germany keyboards (or at least mine). Press ^ two times, once to open the console and once to close it. If you type in a message, there will be a ^ char waiting for you (same in the console if you open it again). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5406 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_screen.c | 95 +++++++++++++++++++++++++++++++++++++++++++++ cl_screen.h | 2 + console.c | 101 ++++++++---------------------------------------- keys.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++- sbar.c | 4 +- vid_wgl.c | 7 +++- 6 files changed, 227 insertions(+), 90 deletions(-) diff --git a/cl_screen.c b/cl_screen.c index 650c64dc..5be03f47 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -45,6 +45,99 @@ static void R_Envmap_f (void); // backend void R_ClearScreen(void); +// color tag printing +static vec4_t _draw_colors[] = +{ + // Quake3 colors + // LordHavoc: why on earth is cyan before magenta in Quake3? + // LordHavoc: note: Doom3 uses white for [0] and [7] + {0.0, 0.0, 0.0, 1.0}, // black + {1.0, 0.0, 0.0, 1.0}, // red + {0.0, 1.0, 0.0, 1.0}, // green + {1.0, 1.0, 0.0, 1.0}, // yellow + {0.0, 0.0, 1.0, 1.0}, // blue + {0.0, 1.0, 1.0, 1.0}, // cyan + {1.0, 0.0, 1.0, 1.0}, // magenta + {1.0, 1.0, 1.0, 1.0} // white + // Black's color table + //{1.0, 1.0, 1.0, 1.0}, + //{1.0, 0.0, 0.0, 1.0}, + //{0.0, 1.0, 0.0, 1.0}, + //{0.0, 0.0, 1.0, 1.0}, + //{1.0, 1.0, 0.0, 1.0}, + //{0.0, 1.0, 1.0, 1.0}, + //{1.0, 0.0, 1.0, 1.0}, + //{0.1, 0.1, 0.1, 1.0} +}; + +#define _draw_colors_count (sizeof(_draw_colors) / sizeof(vec4_t)) +#define _draw_color_tag '^' +#define _draw_color_default 7 + +// color is read and changed in the end +void DrawQ_ColoredString( float x, float y, const char *text, int maxlen, float scalex, float scaley, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor ) +{ + vec_t *color; + const char *first, *last; + int len; + int colorindex; + + if( !outcolor || *outcolor == -1 ) { + colorindex = _draw_color_default; + } else { + colorindex = *outcolor; + } + + color = _draw_colors[colorindex]; + + if( maxlen < 1) + len = strlen( text ); + else + len = min( maxlen, (signed) strlen( text ) ); + + first = last = text; + while( len ) { + // iterate until we get the next color tag or reach the end of the text part to draw + for( ; len && *last != _draw_color_tag ; len--, last++ ) + ; + // only draw the partial string if we have read anything + if( last != first ) { + // draw the string + DrawQ_String( x, y, first, last - first, scalex, scaley, basered * color[0], basegreen * color[1], baseblue * color[2], basealpha * color[3], flags ); + // update x to be at the new start position + x += (last - first) * scalex; + // if we have reached the end, we have finished + if( !len ) + break; + } + first = last; + // jump over the tag + last++; + len--; + if( len && '0' <= *last && *last <= '9' ) { + colorindex = 0; + while( '0' <= *last && *last <= '9' && len ) { + colorindex = colorindex * 10 + *last - '0'; + if( colorindex < _draw_colors_count ) { + last++; + len--; + } else { + colorindex /= 10; + break; + } + } + + color = _draw_colors[colorindex]; + // we dont want to display the color tag and the color index + first = last; + } + } + + if( outcolor ) { + *outcolor = colorindex; + } +} + /* =============================================================================== @@ -541,6 +634,8 @@ void DrawQ_String(float x, float y, const char *string, int maxlen, float scalex DrawQ_String_Real(x,y,string,maxlen,scalex,scaley,red,green,blue,alpha,flags); } + + void DrawQ_Fill (float x, float y, float w, float h, float red, float green, float blue, float alpha, int flags) { DrawQ_SuperPic(x,y,NULL,w,h,0,0,red,green,blue,alpha,1,0,red,green,blue,alpha,0,1,red,green,blue,alpha,1,1,red,green,blue,alpha,flags); diff --git a/cl_screen.h b/cl_screen.h index d914bfaa..d9530c1e 100644 --- a/cl_screen.h +++ b/cl_screen.h @@ -47,6 +47,8 @@ void DrawQ_Clear(void); void DrawQ_Pic(float x, float y, const char *picname, float width, float height, float red, float green, float blue, float alpha, int flags); // draw a text string void DrawQ_String(float x, float y, const char *string, int maxlen, float scalex, float scaley, float red, float green, float blue, float alpha, int flags); +// draw a text string that supports color tags (colorindex can either be NULL, -1 to make it choose the default color or valid index to start with) +void DrawQ_ColoredString( float x, float y, const char *text, int maxlen, float scalex, float scaley, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor ); // draw a filled rectangle void DrawQ_Fill(float x, float y, float w, float h, float red, float green, float blue, float alpha, int flags); // draw a very fancy pic (per corner texcoord/color control), the order is tl, tr, bl, br diff --git a/console.c b/console.c index a7e3b3af..910038e5 100644 --- a/console.c +++ b/console.c @@ -550,6 +550,10 @@ void Con_Print(const char *msg) { // if this is the beginning of a new line, print timestamp char *timestamp = timestamps.integer ? Sys_TimeString(timeformat.string) : ""; + // reset the color + // FIXME: 1. perhaps we should use a terminal system 2. use a constant instead of 7! + line[index++] = '^'; + line[index++] = '7'; // special color codes for chat messages must always come first // for Con_PrintToHistory to work properly if (*msg <= 2) @@ -670,86 +674,6 @@ DRAWING ============================================================================== */ -static vec4_t _con_colors[] = -{ - // Quake3 colors - // LordHavoc: why on earth is cyan before magenta in Quake3? - // LordHavoc: note: Doom3 uses white for [0] and [7] - {0.0, 0.0, 0.0, 1.0}, // black - {1.0, 0.0, 0.0, 1.0}, // red - {0.0, 1.0, 0.0, 1.0}, // green - {1.0, 1.0, 0.0, 1.0}, // yellow - {0.0, 0.0, 1.0, 1.0}, // blue - {0.0, 1.0, 1.0, 1.0}, // cyan - {1.0, 0.0, 1.0, 1.0}, // magenta - {1.0, 1.0, 1.0, 1.0} // white - // Black's color table - //{1.0, 1.0, 1.0, 1.0}, - //{1.0, 0.0, 0.0, 1.0}, - //{0.0, 1.0, 0.0, 1.0}, - //{0.0, 0.0, 1.0, 1.0}, - //{1.0, 1.0, 0.0, 1.0}, - //{0.0, 1.0, 1.0, 1.0}, - //{1.0, 0.0, 1.0, 1.0}, - //{0.1, 0.1, 0.1, 1.0} -}; - -#define _con_colors_count (sizeof(_con_colors) / sizeof(vec3_t)) -#define _con_color_tag '^' - -// color is read and changed in the end -static void _Con_DrawString( float x, float y, const char *text, int maxlen, float scalex, float scaley, int flags ) -{ - vec_t *color; - const char *first, *last; - int len; - - color = _con_colors[7]; - if( maxlen < 1) - len = strlen( text ); - else - len = min( maxlen, (signed) strlen( text )); - - first = last = text; - while( 1 ) { - // iterate until we get the next color tag or reach the end of the text part to draw - for( ; len && *last != _con_color_tag ; len--, last++ ) - ; - // only draw the partial string if we have read anything - if( last != first ) { - // draw the string - DrawQ_String( x, y, first, last - first, scalex, scaley, color[0], color[1], color[2], color[3], flags ); - // update x to be at the new start position - x += (last - first) * scalex; - // if we have reached the end, we have finished - if( !len ) - break; - } - first = last; - // jump over the tag - last++; - len--; - if( len && '0' <= *last && *last <= '9' ) { - int index = 0; - - while( '0' <= *last && *last <= '9' && len ) { - index = index * 10 + *last - '0'; - if( index < _con_colors_count ) { - last++; - len--; - } else { - index /= 10; - break; - } - } - - color = _con_colors[index]; - // we dont want to display the color tag and the color index - first = last; - } - } -} - /* ================ Con_DrawInput @@ -792,7 +716,7 @@ void Con_DrawInput (void) text += 1 + key_linepos - con_linewidth; // draw it - _Con_DrawString(0, con_vislines - 16, text, con_linewidth, 8, 8, 0); + DrawQ_ColoredString(0, con_vislines - 16, text, con_linewidth, 8, 8, 1.0, 1.0, 1.0, 1.0, 0, NULL ); // remove cursor // key_lines[edit_line][key_linepos] = 0; @@ -814,6 +738,7 @@ void Con_DrawNotify (void) float time; extern char chat_buffer[]; char temptext[256]; + int colorindex = -1; //-1 for default if (con_notify.integer < 0) Cvar_SetValueQuick(&con_notify, 0); @@ -825,6 +750,7 @@ void Con_DrawNotify (void) v = 0; for (i= con_current-con_notify.integer+1 ; i<=con_current ; i++) { + if (i < 0) continue; time = con_times[i % con_notify.integer]; @@ -843,14 +769,16 @@ void Con_DrawNotify (void) } else x = 0; - _Con_DrawString(x, v, text, con_linewidth, 8, 8, 0); - + DrawQ_ColoredString( x, v, text, con_linewidth, 8, 8, 1.0, 1.0, 1.0, 1.0, 0, &colorindex ); + v += 8; } if (key_dest == key_message) { + int colorindex = -1; + x = 0; // LordHavoc: speedup, and other improvements @@ -860,13 +788,13 @@ void Con_DrawNotify (void) sprintf(temptext, "say:%s%c", chat_buffer, (int) 10+((int)(realtime*con_cursorspeed)&1)); while (strlen(temptext) >= (size_t) con_linewidth) { - _Con_DrawString (0, v, temptext, con_linewidth, 8, 8, 0); + DrawQ_ColoredString( 0, v, temptext, con_linewidth, 8, 8, 1.0, 1.0, 1.0, 1.0, 0, &colorindex ); strcpy(temptext, &temptext[con_linewidth]); v += 8; } if (strlen(temptext) > 0) { - _Con_DrawString (0, v, temptext, 0, 8, 8, 0); + DrawQ_ColoredString( 0, v, temptext, 0, 8, 8, 1.0, 1.0, 1.0, 1.0, 0, &colorindex ); v += 8; } } @@ -885,6 +813,7 @@ void Con_DrawConsole (int lines) { int i, y, rows, j; char *text; + int colorindex = -1; if (lines <= 0) return; @@ -907,7 +836,7 @@ void Con_DrawConsole (int lines) j = max(i - con_backscroll, 0); text = con_text + (j % con_totallines)*con_linewidth; - _Con_DrawString(0, y, text, con_linewidth, 8, 8, 0); + DrawQ_ColoredString( 0, y, text, con_linewidth, 8, 8, 1.0, 1.0, 1.0, 1.0, 0, &colorindex ); } // draw the input prompt, user text, and cursor if desired diff --git a/keys.c b/keys.c index 82c3edf6..a98f5433 100644 --- a/keys.c +++ b/keys.c @@ -804,8 +804,8 @@ Key_Init (void) consolekeys[K_KP_MINUS] = true; consolekeys[K_KP_DIVIDE] = true; consolekeys[K_KP_MULTIPLY] = true; - consolekeys['`'] = false; - consolekeys['~'] = false; + consolekeys['`'] = true; + consolekeys['~'] = true; menubound[K_ESCAPE] = true; for (i = 0; i < 12; i++) @@ -833,6 +833,109 @@ Should NOT be called during an interrupt! void Key_Event (int key, char ascii, qboolean down) { +#if 1 +#define USERPLAYING() ( !key_consoleactive && key_dest == key_game && (cls.state == ca_connected && cls.signon == SIGNONS) ) +//#define CONSOLEKEY() (key_consoleactive && !consolekeys[key]) +#define CONSOLEKEY() ( key_dest == key_console) + const char *bind; + + // get key binding + bind = keybindings[ key_bmap ][ key ]; + if( !bind ) { + bind = keybindings[ key_bmap2 ][ key ]; + } + + // set key state + keydown[ key ] = down; + + // update key repeats + if( down ) { + key_repeats[ key ]++; + if( key_repeats[ key ] > 1 ) { + if( (key_consoleactive && !consolekeys[key]) || USERPLAYING() ) + return; // ignore most autorepeats + } + } else { + key_repeats[ key ] = 0; + } + + if( key == K_CTRL ) { + ctrl_down = down; + } + + if( !down ) { + if( bind && bind[ 0 ] == '+') { + Cbuf_AddText( va( "-%s %i\n", bind + 1, key) ); + } + } else { + // handle ESCAPE specially, so unbinding wont help + if( key == K_ESCAPE ) { + // ctrl-escape is a safety measure for users who cant toggle the console otherwise + if( ctrl_down ) { + Con_ToggleConsole_f(); + return; + } + switch( key_dest ) { + case key_message: + Key_Message( key, ascii ); + break; + case key_menu: + MR_Keydown( key, ascii ); + break; + case key_game: + MR_ToggleMenu_f(); + break; + default: + Sys_Error( "Bad key_dest" ); + } + return; + } + + if (bind && !strncmp( bind, "toggleconsole", strlen( "toggleconsole" ) ) ) + { + Cbuf_AddText( bind ); + Cbuf_AddText( "\n" ); + } else { + // during demo playback, all keys ingame bring up the main menu + if( cls.demoplayback && !key_consoleactive && key_dest == key_game ) { + MR_ToggleMenu_f (); + return; + } + + // menu bind/function keys or normal binds + if( (key_dest == key_menu && menubound[key]) || USERPLAYING() ) { + if( bind ) { + if( bind[0] == '+' ) { // button commands add keynum as a parm + Cbuf_AddText( va( "%s %i\n", bind, key ) ); + } else { + Cbuf_AddText( bind ); + Cbuf_AddText( "\n" ); + } + } + return; + } + } + + // either console or game state key functions + if( key_consoleactive ) { + Key_Console( key, ascii ); + } else { + switch (key_dest) { + case key_message: + Key_Message( key, ascii ); + break; + case key_menu: + MR_Keydown( key, ascii ); + break; + case key_game: + // unbound key + break; + default: + Sys_Error( "Bad key_dest" ); + } + } + } +#else const char *kb; char cmd[1024]; @@ -976,6 +1079,7 @@ Key_Event (int key, char ascii, qboolean down) Sys_Error ("Bad key_dest"); } } +#endif } /* diff --git a/sbar.c b/sbar.c index 0aedcd9c..13f46e7b 100644 --- a/sbar.c +++ b/sbar.c @@ -1177,7 +1177,9 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y) c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8]; DrawQ_Fill(x + 8, y+4, 32, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0); // print the text - DrawQ_String(x, y, va("%c%4i %s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0); + //DrawQ_String(x, y, va("%c%4i %s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0); + // FIXME: use a constant for this color tag instead + DrawQ_ColoredString(x, y, va("%c%4i %s^7", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL ); return 8; } diff --git a/vid_wgl.c b/vid_wgl.c index 4c36b9a0..e014659c 100644 --- a/vid_wgl.c +++ b/vid_wgl.c @@ -474,6 +474,7 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) char state[256]; char asciichar[4]; int vkey; + int charlength; qboolean down = false; if ( uMsg == uiWheelMessage ) @@ -504,8 +505,12 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) GetKeyboardState (state); // alt/ctrl/shift tend to produce funky ToAscii values, // and if it's not a single character we don't know care about it - if (vkey == K_ALT || vkey == K_CTRL || vkey == K_SHIFT || ToAscii (wParam, lParam >> 16, state, (unsigned short *)asciichar, 0) != 1) + charlength = ToAscii (wParam, lParam >> 16, state, (unsigned short *)asciichar, 0); + if (vkey == K_ALT || vkey == K_CTRL || vkey == K_SHIFT || charlength == 0) asciichar[0] = 0; + else if( charlength == 2 ) { + asciichar[0] = asciichar[1]; + } Key_Event (vkey, asciichar[0], down); break; -- 2.39.2