2014-04-12 12:19:49 +00:00
/*
Copyright ( C ) 1996 - 1997 Id Software , Inc .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
2015-08-20 13:34:12 +00:00
# include "globaldef.h"
2014-04-12 12:19:49 +00:00
// 2001-12-15 Windows Clipboard pasting by FrikaC start
# ifdef _WIN32
# include <windows.h>
# endif
// 2001-12-15 Windows Clipboard pasting by FrikaC end
/*
key up events are sent even if in console mode
*/
# define MAXCMDLINE 256
char key_lines [ 32 ] [ MAXCMDLINE ] ;
int key_linepos ;
int shift_down = false ;
int key_lastpress ;
int key_insert ; // 2000-01-05 Console typing enhancement by Radix
// insert key toggle
int edit_line = 0 ;
int history_line = 0 ;
keydest_t key_dest ;
int key_count ; // incremented every key event
char * keybindings [ 256 ] ;
2014-04-12 12:29:30 +00:00
char * keybindings2 [ 256 ] ; // leilei - splitscreen hack
2014-04-12 12:19:49 +00:00
qboolean consolekeys [ 256 ] ; // if true, can't be rebound while in console
qboolean menubound [ 256 ] ; // if true, can't be rebound while in menu
int keyshift [ 256 ] ; // key to map to if shift held down in console
int key_repeats [ 256 ] ; // if > 1, it is autorepeating
qboolean keydown [ 256 ] ;
typedef struct
{
char * name ;
int keynum ;
} keyname_t ;
keyname_t keynames [ ] =
{
{ " TAB " , K_TAB } ,
{ " ENTER " , K_ENTER } ,
{ " ESCAPE " , K_ESCAPE } ,
{ " SPACE " , K_SPACE } ,
{ " BACKSPACE " , K_BACKSPACE } ,
{ " UPARROW " , K_UPARROW } ,
{ " DOWNARROW " , K_DOWNARROW } ,
{ " LEFTARROW " , K_LEFTARROW } ,
{ " RIGHTARROW " , K_RIGHTARROW } ,
{ " ALT " , K_ALT } ,
{ " CTRL " , K_CTRL } ,
{ " SHIFT " , K_SHIFT } ,
{ " F1 " , K_F1 } ,
{ " F2 " , K_F2 } ,
{ " F3 " , K_F3 } ,
{ " F4 " , K_F4 } ,
{ " F5 " , K_F5 } ,
{ " F6 " , K_F6 } ,
{ " F7 " , K_F7 } ,
{ " F8 " , K_F8 } ,
{ " F9 " , K_F9 } ,
{ " F10 " , K_F10 } ,
{ " F11 " , K_F11 } ,
{ " F12 " , K_F12 } ,
{ " INS " , K_INS } ,
{ " DEL " , K_DEL } ,
{ " PGDN " , K_PGDN } ,
{ " PGUP " , K_PGUP } ,
{ " HOME " , K_HOME } ,
{ " END " , K_END } ,
{ " MOUSE1 " , K_MOUSE1 } ,
{ " MOUSE2 " , K_MOUSE2 } ,
{ " MOUSE3 " , K_MOUSE3 } ,
{ " JOY1 " , K_JOY1 } ,
{ " JOY2 " , K_JOY2 } ,
{ " JOY3 " , K_JOY3 } ,
{ " JOY4 " , K_JOY4 } ,
{ " AUX1 " , K_AUX1 } ,
{ " AUX2 " , K_AUX2 } ,
{ " AUX3 " , K_AUX3 } ,
{ " AUX4 " , K_AUX4 } ,
{ " AUX5 " , K_AUX5 } ,
{ " AUX6 " , K_AUX6 } ,
{ " AUX7 " , K_AUX7 } ,
{ " AUX8 " , K_AUX8 } ,
{ " AUX9 " , K_AUX9 } ,
{ " AUX10 " , K_AUX10 } ,
{ " AUX11 " , K_AUX11 } ,
{ " AUX12 " , K_AUX12 } ,
{ " AUX13 " , K_AUX13 } ,
{ " AUX14 " , K_AUX14 } ,
{ " AUX15 " , K_AUX15 } ,
{ " AUX16 " , K_AUX16 } ,
{ " AUX17 " , K_AUX17 } ,
{ " AUX18 " , K_AUX18 } ,
{ " AUX19 " , K_AUX19 } ,
{ " AUX20 " , K_AUX20 } ,
{ " AUX21 " , K_AUX21 } ,
{ " AUX22 " , K_AUX22 } ,
{ " AUX23 " , K_AUX23 } ,
{ " AUX24 " , K_AUX24 } ,
{ " AUX25 " , K_AUX25 } ,
{ " AUX26 " , K_AUX26 } ,
{ " AUX27 " , K_AUX27 } ,
{ " AUX28 " , K_AUX28 } ,
{ " AUX29 " , K_AUX29 } ,
{ " AUX30 " , K_AUX30 } ,
{ " AUX31 " , K_AUX31 } ,
{ " AUX32 " , K_AUX32 } ,
{ " PAUSE " , K_PAUSE } ,
{ " MWHEELUP " , K_MWHEELUP } ,
{ " MWHEELDOWN " , K_MWHEELDOWN } ,
{ " SEMICOLON " , ' ; ' } , // because a raw semicolon seperates commands
{ NULL , 0 }
} ;
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
LINE TYPING INTO THE CONSOLE
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = = = =
Key_Console
Interactive line editing and console scrollback
= = = = = = = = = = = = = = = = = = = =
*/
void Key_Console ( int key )
{
char * cmd ;
int history_line_last ; // 2000-01-05 Console typing enhancement by Radix/Maddes
// 2001-12-15 Windows Clipboard pasting by FrikaC start
# ifdef _WIN32
char * s ;
int i ;
HANDLE th ;
char * clipText , * textCopied ;
# endif
// 2001-12-15 Windows Clipboard pasting by FrikaC end
if ( key = = K_ENTER )
{
Cbuf_AddText ( key_lines [ edit_line ] + 1 ) ; // skip the >
Cbuf_AddText ( " \n " ) ;
Con_Printf ( " %s \n " , key_lines [ edit_line ] ) ;
edit_line = ( edit_line + 1 ) & 31 ;
history_line = edit_line ;
key_lines [ edit_line ] [ 0 ] = ' ] ' ;
key_lines [ edit_line ] [ 1 ] = 0 ; // 2000-01-05 Console typing enhancement by Radix
// null terminate
key_linepos = 1 ;
if ( cls . state = = ca_disconnected )
SCR_UpdateScreen ( ) ; // force an update, because the command
// may take some time
return ;
}
if ( key = = K_TAB )
{ // command completion
// 2001-12-15 Enhanced console command completion by Fett/Maddes start
/*
cmd = Cmd_CompleteCommand ( key_lines [ edit_line ] + 1 ) ;
if ( ! cmd )
cmd = Cvar_CompleteVariable ( key_lines [ edit_line ] + 1 ) ;
*/
int c , v , a ;
cmd = NULL ;
// Count the number of possible matches
c = Cmd_CompleteCountPossible ( key_lines [ edit_line ] + 1 ) ;
v = Cvar_CompleteCountPossible ( key_lines [ edit_line ] + 1 ) ;
a = Cmd_CompleteAliasCountPossible ( key_lines [ edit_line ] + 1 ) ;
if ( ! ( c + v + a ) ) // No possible matches, don't do anything
return ;
if ( c + v + a > 1 ) // More than a single possible match
{
// the 'classic' Quakebar
Con_Printf ( " \n \35 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \37 \n " ) ;
// Print possible commands
if ( c )
{
if ( c = = 1 )
Con_Printf ( " 1 possible command: \n " ) ;
else
Con_Printf ( " %i possible commands: \n " , c ) ;
Cmd_CompletePrintPossible ( key_lines [ edit_line ] + 1 ) ;
}
// Print possible variables
if ( v )
{
if ( v = = 1 )
Con_Printf ( " 1 possible variable: \n " ) ;
else
Con_Printf ( " %i possible variables: \n " , v ) ;
Cvar_CompletePrintPossible ( key_lines [ edit_line ] + 1 ) ;
}
// Print possible aliases
if ( a )
{
if ( a = = 1 )
Con_Printf ( " 1 possible alias: \n " ) ;
else
Con_Printf ( " %i possible aliases: \n " , a ) ;
Cmd_CompleteAliasPrintPossible ( key_lines [ edit_line ] + 1 ) ;
}
return ;
}
// We know there's only one match so use the original id functions
// to complete the line.
if ( c )
cmd = Cmd_CompleteCommand ( key_lines [ edit_line ] + 1 ) ;
if ( v )
cmd = Cvar_CompleteVariable ( key_lines [ edit_line ] + 1 ) ;
if ( a )
cmd = Cmd_CompleteAlias ( key_lines [ edit_line ] + 1 ) ;
// 2001-12-15 Enhanced console command completion by Fett/Maddes end
if ( cmd )
{
strcpy ( key_lines [ edit_line ] + 1 , cmd ) ;
key_linepos = strlen ( cmd ) + 1 ;
key_lines [ edit_line ] [ key_linepos ] = ' ' ;
key_linepos + + ;
key_lines [ edit_line ] [ key_linepos ] = 0 ;
return ;
}
}
// 2000-01-05 Console typing enhancement by Radix start
if ( key = = K_LEFTARROW )
{
// left arrow will just move left one w/o earsing, backspace will
// actually erase charcter
if ( key_linepos > 1 )
{
key_linepos - - ;
}
return ;
}
if ( key = = K_BACKSPACE )
{
// delete char before cursor
if ( key_linepos > 1 )
{
strcpy ( key_lines [ edit_line ] + key_linepos - 1 , key_lines [ edit_line ] + key_linepos ) ;
key_linepos - - ;
}
return ;
}
if ( key = = K_DEL )
{
// delete char on cursor
if ( key_linepos < strlen ( key_lines [ edit_line ] ) )
{
strcpy ( key_lines [ edit_line ] + key_linepos , key_lines [ edit_line ] + key_linepos + 1 ) ;
}
return ;
}
if ( key = = K_RIGHTARROW )
{
// if we're at the end, get one character from previous line,
// otherwise just go right one
if ( strlen ( key_lines [ edit_line ] ) = = key_linepos )
{
if ( strlen ( key_lines [ ( edit_line + 31 ) & 31 ] ) < = key_linepos )
{
return ; // no character to get
}
key_lines [ edit_line ] [ key_linepos ] = key_lines [ ( edit_line + 31 ) & 31 ] [ key_linepos ] ;
key_linepos + + ;
key_lines [ edit_line ] [ key_linepos ] = 0 ;
}
else
{
key_linepos + + ;
}
return ;
}
if ( key = = K_INS )
{
// toggle insert mode
key_insert ^ = 1 ;
return ;
}
// 2000-01-05 Console typing enhancement by Radix end
if ( key = = K_UPARROW )
{
history_line_last = history_line ; // 2000-01-05 Console typing enhancement by Radix/Maddes
do
{
history_line = ( history_line - 1 ) & 31 ;
} while ( history_line ! = edit_line
& & ! key_lines [ history_line ] [ 1 ] ) ;
if ( history_line = = edit_line )
// 2000-01-05 Console typing enhancement by Radix/Maddes start
// history_line = (edit_line+1)&31;
history_line = history_line_last ;
// 2000-01-05 Console typing enhancement by Radix/Maddes end
strcpy ( key_lines [ edit_line ] , key_lines [ history_line ] ) ;
key_linepos = strlen ( key_lines [ edit_line ] ) ;
return ;
}
if ( key = = K_DOWNARROW )
{
if ( history_line = = edit_line ) return ;
do
{
history_line = ( history_line + 1 ) & 31 ;
}
while ( history_line ! = edit_line
& & ! key_lines [ history_line ] [ 1 ] ) ;
if ( history_line = = edit_line )
{
key_lines [ edit_line ] [ 0 ] = ' ] ' ;
key_lines [ edit_line ] [ 1 ] = 0 ; // 2000-01-05 Console typing enhancement by Radix/Maddes
// null terminate
key_linepos = 1 ;
}
else
{
strcpy ( key_lines [ edit_line ] , key_lines [ history_line ] ) ;
key_linepos = strlen ( key_lines [ edit_line ] ) ;
}
return ;
}
if ( key = = K_PGUP | | key = = K_MWHEELUP )
{
con_backscroll + = 2 ;
return ;
}
if ( key = = K_PGDN | | key = = K_MWHEELDOWN )
{
con_backscroll - = 2 ;
return ;
}
if ( key = = K_HOME )
{
con_backscroll = con_current - 1 ;
return ;
}
if ( key = = K_END )
{
con_backscroll = 0 ;
return ;
}
// 2001-12-15 Windows Clipboard pasting by FrikaC start
# ifdef _WIN32
if ( ( key = = ' V ' | | key = = ' v ' ) & & GetKeyState ( VK_CONTROL ) < 0 ) {
if ( OpenClipboard ( NULL ) ) {
th = GetClipboardData ( CF_TEXT ) ;
if ( th ) {
clipText = GlobalLock ( th ) ;
if ( clipText ) {
textCopied = malloc ( GlobalSize ( th ) + 1 ) ;
strcpy ( textCopied , clipText ) ;
/* Substitutes a NULL for every token */
strtok ( textCopied , " \n \r \b " ) ;
i = strlen ( textCopied ) ;
if ( i + key_linepos > = MAXCMDLINE )
i = MAXCMDLINE - key_linepos ;
if ( i > 0 ) {
textCopied [ i ] = 0 ;
strcat ( key_lines [ edit_line ] , textCopied ) ;
key_linepos + = i ; ;
}
free ( textCopied ) ;
}
GlobalUnlock ( th ) ;
}
CloseClipboard ( ) ;
return ;
}
}
# endif
// 2001-12-15 Windows Clipboard pasting by FrikaC end
if ( key < 32 | | key > 127 )
return ; // non printable
if ( key_linepos < MAXCMDLINE - 1 )
{
// 2000-01-05 Console typing enhancement by Radix start
int i ;
// check insert mode
if ( key_insert )
{ // can't do strcpy to move string to right
i = strlen ( key_lines [ edit_line ] ) - 1 ;
if ( i = = 254 ) i - - ;
for ( ; i > = key_linepos ; i - - )
key_lines [ edit_line ] [ i + 1 ] = key_lines [ edit_line ] [ i ] ;
}
// only null terminate if at the end
i = key_lines [ edit_line ] [ key_linepos ] ;
// 2000-01-05 Console typing enhancement by Radix end
key_lines [ edit_line ] [ key_linepos ] = key ;
key_linepos + + ;
if ( ! i ) // 2000-01-05 Console typing enhancement by Radix
key_lines [ edit_line ] [ key_linepos ] = 0 ;
}
}
//============================================================================
char chat_buffer [ 32 ] ;
qboolean team_message = false ;
void Key_Message ( int key )
{
static int chat_bufferlen = 0 ;
if ( key = = K_ENTER )
{
if ( team_message )
Cbuf_AddText ( " say_team \" " ) ;
else
Cbuf_AddText ( " say \" " ) ;
Cbuf_AddText ( chat_buffer ) ;
Cbuf_AddText ( " \" \n " ) ;
key_dest = key_game ;
chat_bufferlen = 0 ;
chat_buffer [ 0 ] = 0 ;
return ;
}
if ( key = = K_ESCAPE )
{
key_dest = key_game ;
chat_bufferlen = 0 ;
chat_buffer [ 0 ] = 0 ;
return ;
}
if ( key < 32 | | key > 127 )
return ; // non printable
if ( key = = K_BACKSPACE )
{
if ( chat_bufferlen )
{
chat_bufferlen - - ;
chat_buffer [ chat_bufferlen ] = 0 ;
}
return ;
}
if ( chat_bufferlen = = 31 )
return ; // all full
chat_buffer [ chat_bufferlen + + ] = key ;
chat_buffer [ chat_bufferlen ] = 0 ;
}
//============================================================================
/*
= = = = = = = = = = = = = = = = = = =
Key_StringToKeynum
Returns a key number to be used to index keybindings [ ] by looking at
the given string . Single ascii characters return themselves , while
the K_ * names are matched up .
= = = = = = = = = = = = = = = = = = =
*/
int Key_StringToKeynum ( char * str )
{
keyname_t * kn ;
if ( ! str | | ! str [ 0 ] )
return - 1 ;
if ( ! str [ 1 ] )
return str [ 0 ] ;
for ( kn = keynames ; kn - > name ; kn + + )
{
if ( ! Q_strcasecmp ( str , kn - > name ) )
return kn - > keynum ;
}
return - 1 ;
}
/*
= = = = = = = = = = = = = = = = = = =
Key_KeynumToString
Returns a string ( either a single ascii char , or a K_ * name ) for the
given keynum .
FIXME : handle quote special ( general escape sequence ? )
= = = = = = = = = = = = = = = = = = =
*/
char * Key_KeynumToString ( int keynum )
{
keyname_t * kn ;
static char tinystr [ 2 ] ;
if ( keynum = = - 1 )
return " <KEY NOT FOUND> " ;
if ( keynum > 32 & & keynum < 127 )
{ // printable ascii
tinystr [ 0 ] = keynum ;
tinystr [ 1 ] = 0 ;
return tinystr ;
}
for ( kn = keynames ; kn - > name ; kn + + )
if ( keynum = = kn - > keynum )
return kn - > name ;
return " <UNKNOWN KEYNUM> " ;
}
/*
= = = = = = = = = = = = = = = = = = =
Key_SetBinding
= = = = = = = = = = = = = = = = = = =
*/
void Key_SetBinding ( int keynum , char * binding )
{
char * new ;
int l ;
if ( keynum = = - 1 )
return ;
// free old bindings
if ( keybindings [ keynum ] )
{
Z_Free ( mainzone , keybindings [ keynum ] ) ; // 2001-09-20 Enhanced zone handling by Maddes
keybindings [ keynum ] = NULL ;
}
// allocate memory for new binding
l = strlen ( binding ) ;
new = Z_Malloc ( mainzone , l + 1 ) ; // 2001-09-20 Enhanced zone handling by Maddes
strcpy ( new , binding ) ;
new [ l ] = 0 ;
keybindings [ keynum ] = new ;
}
/*
= = = = = = = = = = = = = = = = = = =
Key_Unbind_f
= = = = = = = = = = = = = = = = = = =
*/
void Key_Unbind_f ( void )
{
int b ;
if ( Cmd_Argc ( ) ! = 2 )
{
Con_Printf ( " unbind <key> : remove commands from a key \n " ) ;
return ;
}
b = Key_StringToKeynum ( Cmd_Argv ( 1 ) ) ;
if ( b = = - 1 )
{
Con_Printf ( " \" %s \" isn't a valid key \n " , Cmd_Argv ( 1 ) ) ;
return ;
}
Key_SetBinding ( b , " " ) ;
}
void Key_Unbindall_f ( void )
{
int i ;
for ( i = 0 ; i < 256 ; i + + )
if ( keybindings [ i ] )
Key_SetBinding ( i , " " ) ;
}
/*
= = = = = = = = = = = = = = = = = = =
Key_Bind_f
= = = = = = = = = = = = = = = = = = =
*/
void Key_Bind_f ( void )
{
int i , c , b ;
char cmd [ 1024 ] ;
c = Cmd_Argc ( ) ;
if ( c ! = 2 & & c ! = 3 )
{
Con_Printf ( " bind <key> [command] : attach a command to a key \n " ) ;
return ;
}
b = Key_StringToKeynum ( Cmd_Argv ( 1 ) ) ;
if ( b = = - 1 )
{
Con_Printf ( " \" %s \" isn't a valid key \n " , Cmd_Argv ( 1 ) ) ;
return ;
}
if ( c = = 2 )
{
if ( keybindings [ b ] )
Con_Printf ( " \" %s \" = \" %s \" \n " , Cmd_Argv ( 1 ) , keybindings [ b ] ) ;
else
Con_Printf ( " \" %s \" is not bound \n " , Cmd_Argv ( 1 ) ) ;
return ;
}
// copy the rest of the command line
cmd [ 0 ] = 0 ; // start out with a null string
for ( i = 2 ; i < c ; i + + )
{
if ( i > 2 )
strcat ( cmd , " " ) ;
strcat ( cmd , Cmd_Argv ( i ) ) ;
}
Key_SetBinding ( b , cmd ) ;
}
2014-04-12 12:29:30 +00:00
/*
= = = = = = = = = = = = = = = = = = =
Key_SetBinding2
= = = = = = = = = = = = = = = = = = =
*/
void Key_SetBinding2 ( int keynum , char * binding )
{
char * new ;
int l ;
if ( keynum = = - 1 )
return ;
// free old bindings
if ( keybindings [ keynum ] )
{
Z_Free ( mainzone , keybindings [ keynum ] ) ; // 2001-09-20 Enhanced zone handling by Maddes
keybindings [ keynum ] = NULL ;
}
// allocate memory for new binding
l = strlen ( binding ) ;
new = Z_Malloc ( mainzone , l + 1 ) ; // 2001-09-20 Enhanced zone handling by Maddes
strcpy ( new , binding ) ;
new [ l ] = 0 ;
keybindings [ keynum ] = new ;
}
/*
= = = = = = = = = = = = = = = = = = =
Key_Unbind2_f
= = = = = = = = = = = = = = = = = = =
*/
void Key_Unbind2_f ( void )
{
int b ;
if ( Cmd_Argc ( ) ! = 2 )
{
Con_Printf ( " unbind <key> : remove commands from a key \n " ) ;
return ;
}
b = Key_StringToKeynum ( Cmd_Argv ( 1 ) ) ;
if ( b = = - 1 )
{
Con_Printf ( " \" %s \" isn't a valid key \n " , Cmd_Argv ( 1 ) ) ;
return ;
}
Key_SetBinding ( b , " " ) ;
}
void Key_Unbindall2_f ( void )
{
int i ;
for ( i = 0 ; i < 256 ; i + + )
if ( keybindings [ i ] )
Key_SetBinding ( i , " " ) ;
}
/*
= = = = = = = = = = = = = = = = = = =
Key_Bind2_f
leilei - splitscreen hack
Binds a key for the second client in a splitscreen environment
( for separate keyboards or joypads )
= = = = = = = = = = = = = = = = = = =
*/
void Key_Bind2_f ( void )
{
int i , c , b ;
char cmd [ 1024 ] ;
c = Cmd_Argc ( ) ;
// the messages are wittier, just because we're not done.
if ( c ! = 2 & & c ! = 3 )
{
Con_Printf ( " bind2 <key> [command] : attach a command to a key for the second player. which is highly experimental, should not be taken seriously, and other warnings here. \n " ) ;
return ;
}
b = Key_StringToKeynum ( Cmd_Argv ( 1 ) ) ;
if ( b = = - 1 )
{
Con_Printf ( " \" %s \" isn't a valid key for the second player. Too bad. Try again. :( \n " , Cmd_Argv ( 1 ) ) ;
return ;
}
if ( c = = 2 )
{
if ( keybindings [ b ] )
Con_Printf ( " \" %s \" = \" %s \" \n " , Cmd_Argv ( 1 ) , keybindings [ b ] ) ;
else
Con_Printf ( " \" %s \" is not bound, so bind it!!! \n " , Cmd_Argv ( 1 ) ) ;
return ;
}
// copy the rest of the command line
cmd [ 0 ] = 0 ; // start out with a null string
for ( i = 2 ; i < c ; i + + )
{
if ( i > 2 )
strcat ( cmd , " " ) ;
strcat ( cmd , Cmd_Argv ( i ) ) ;
}
Key_SetBinding2 ( b , cmd ) ;
}
2014-04-12 12:19:49 +00:00
/*
= = = = = = = = = = = =
Key_WriteBindings
Writes lines containing " bind key value "
= = = = = = = = = = = =
*/
void Key_WriteBindings ( FILE * f )
{
int i ;
for ( i = 0 ; i < 256 ; i + + )
if ( keybindings [ i ] )
if ( * keybindings [ i ] )
fprintf ( f , " bind \" %s \" \" %s \" \n " , Key_KeynumToString ( i ) , keybindings [ i ] ) ;
}
/*
= = = = = = = = = = = = = = = = = = =
Key_Init
= = = = = = = = = = = = = = = = = = =
*/
void Key_Init ( void )
{
int i ;
2014-04-12 12:29:30 +00:00
2014-04-12 12:19:49 +00:00
for ( i = 0 ; i < 32 ; i + + )
{
key_lines [ i ] [ 0 ] = ' ] ' ;
key_lines [ i ] [ 1 ] = 0 ;
}
key_linepos = 1 ;
//
// init ascii characters in console mode
//
for ( i = 32 ; i < 128 ; i + + )
consolekeys [ i ] = true ;
consolekeys [ K_ENTER ] = true ;
consolekeys [ K_TAB ] = true ;
consolekeys [ K_LEFTARROW ] = true ;
consolekeys [ K_RIGHTARROW ] = true ;
consolekeys [ K_UPARROW ] = true ;
consolekeys [ K_DOWNARROW ] = true ;
consolekeys [ K_BACKSPACE ] = true ;
// 2000-01-05 Console typing enhancement by Radix/Maddes start
consolekeys [ K_DEL ] = true ;
consolekeys [ K_INS ] = true ;
// 2000-01-05 Console typing enhancement by Radix/Maddes end
// 2000-01-05 Console scrolling fix by Maddes start
consolekeys [ K_HOME ] = true ;
consolekeys [ K_END ] = true ;
// 2000-01-05 Console scrolling fix by Maddes end
consolekeys [ K_PGUP ] = true ;
consolekeys [ K_PGDN ] = true ;
consolekeys [ K_SHIFT ] = true ;
consolekeys [ K_MWHEELUP ] = true ;
consolekeys [ K_MWHEELDOWN ] = true ;
consolekeys [ ' ` ' ] = false ;
consolekeys [ ' ~ ' ] = false ;
for ( i = 0 ; i < 256 ; i + + )
keyshift [ i ] = i ;
for ( i = ' a ' ; i < = ' z ' ; i + + )
keyshift [ i ] = i - ' a ' + ' A ' ;
keyshift [ ' 1 ' ] = ' ! ' ;
keyshift [ ' 2 ' ] = ' @ ' ;
keyshift [ ' 3 ' ] = ' # ' ;
keyshift [ ' 4 ' ] = ' $ ' ;
keyshift [ ' 5 ' ] = ' % ' ;
keyshift [ ' 6 ' ] = ' ^ ' ;
keyshift [ ' 7 ' ] = ' & ' ;
keyshift [ ' 8 ' ] = ' * ' ;
keyshift [ ' 9 ' ] = ' ( ' ;
keyshift [ ' 0 ' ] = ' ) ' ;
keyshift [ ' - ' ] = ' _ ' ;
keyshift [ ' = ' ] = ' + ' ;
keyshift [ ' , ' ] = ' < ' ;
keyshift [ ' . ' ] = ' > ' ;
keyshift [ ' / ' ] = ' ? ' ;
keyshift [ ' ; ' ] = ' : ' ;
keyshift [ ' \' ' ] = ' " ' ;
keyshift [ ' [ ' ] = ' { ' ;
keyshift [ ' ] ' ] = ' } ' ;
keyshift [ ' ` ' ] = ' ~ ' ;
keyshift [ ' \\ ' ] = ' | ' ;
menubound [ K_ESCAPE ] = true ;
2014-04-12 12:29:30 +00:00
menubound [ K_AUX8 ] = true ; // leilei - start button.
2014-04-12 12:19:49 +00:00
for ( i = 0 ; i < 12 ; i + + )
menubound [ K_F1 + i ] = true ;
//
// register our functions
//
Cmd_AddCommand ( " bind " , Key_Bind_f ) ;
Cmd_AddCommand ( " unbind " , Key_Unbind_f ) ;
Cmd_AddCommand ( " unbindall " , Key_Unbindall_f ) ;
2014-04-12 12:29:30 +00:00
// leilei - splitscreen hack
Cmd_AddCommand ( " bind2 " , Key_Bind2_f ) ;
Cmd_AddCommand ( " unbind2 " , Key_Unbind2_f ) ;
2014-04-12 12:19:49 +00:00
}
/*
= = = = = = = = = = = = = = = = = = =
Key_Event
Called by the system between frames for both key up and key down events
Should NOT be called during an interrupt !
= = = = = = = = = = = = = = = = = = =
*/
void Key_Event ( int key , qboolean down )
{
char * kb ;
char cmd [ 1024 ] ;
keydown [ key ] = down ;
if ( ! down )
key_repeats [ key ] = 0 ;
key_lastpress = key ;
key_count + + ;
if ( key_count < = 0 )
{
return ; // just catching keys for Con_NotifyBox
}
// update auto-repeat status
if ( down )
{
key_repeats [ key ] + + ;
if ( key ! = K_BACKSPACE & & key ! = K_PAUSE & & key_repeats [ key ] > 1 )
{
return ; // ignore most autorepeats
}
if ( key > = 200 & & ! keybindings [ key ] )
Con_Printf ( " %s is unbound, hit F4 to set. \n " , Key_KeynumToString ( key ) ) ;
}
if ( key = = K_SHIFT )
shift_down = down ;
//
// handle escape specialy, so the user can never unbind it
//
if ( key = = K_ESCAPE )
{
if ( ! down )
return ;
switch ( key_dest )
{
case key_message :
Key_Message ( key ) ;
break ;
case key_menu :
M_Keydown ( key ) ;
break ;
case key_game :
case key_console :
M_ToggleMenu_f ( ) ;
break ;
default :
Sys_Error ( " Bad key_dest " ) ;
}
return ;
}
//
// key up events only generate commands if the game key binding is
// a button command (leading + sign). These will occur even in console mode,
// to keep the character from continuing an action started before a console
// switch. Button commands include the kenum as a parameter, so multiple
// downs can be matched with ups
//
if ( ! down )
{
kb = keybindings [ key ] ;
if ( kb & & kb [ 0 ] = = ' + ' )
{
sprintf ( cmd , " -%s %i \n " , kb + 1 , key ) ;
Cbuf_AddText ( cmd ) ;
}
if ( keyshift [ key ] ! = key )
{
kb = keybindings [ keyshift [ key ] ] ;
if ( kb & & kb [ 0 ] = = ' + ' )
{
sprintf ( cmd , " -%s %i \n " , kb + 1 , key ) ;
Cbuf_AddText ( cmd ) ;
}
}
return ;
}
//
// during demo playback, most keys bring up the main menu
//
if ( cls . demoplayback & & down & & consolekeys [ key ] & & key_dest = = key_game )
{
M_ToggleMenu_f ( ) ;
return ;
}
//
// if not a consolekey, send to the interpreter no matter what mode is
//
if ( ( key_dest = = key_menu & & menubound [ key ] )
| | ( key_dest = = key_console & & ! consolekeys [ key ] )
| | ( key_dest = = key_game & & ( ! con_forcedup | | ! consolekeys [ key ] ) ) )
{
kb = keybindings [ key ] ;
if ( kb )
{
if ( kb [ 0 ] = = ' + ' )
{ // button commands add keynum as a parm
sprintf ( cmd , " %s %i \n " , kb , key ) ;
Cbuf_AddText ( cmd ) ;
}
else
{
Cbuf_AddText ( kb ) ;
Cbuf_AddText ( " \n " ) ;
}
}
return ;
}
if ( ! down )
return ; // other systems only care about key down events
if ( shift_down )
{
key = keyshift [ key ] ;
}
switch ( key_dest )
{
case key_message :
Key_Message ( key ) ;
break ;
case key_menu :
M_Keydown ( key ) ;
break ;
case key_game :
case key_console :
Key_Console ( key ) ;
break ;
default :
Sys_Error ( " Bad key_dest " ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = =
Key_ClearStates
= = = = = = = = = = = = = = = = = = =
*/
void Key_ClearStates ( void )
{
int i ;
for ( i = 0 ; i < 256 ; i + + )
{
keydown [ i ] = false ;
key_repeats [ i ] = 0 ;
}
}
2014-04-12 12:29:30 +00:00