📄 keys.pas
字号:
Dec(chat_bufferlen);
chat_buffer[chat_bufferlen] := #0;
end;
exit;
end;
if (chat_bufferlen = sizeof(chat_buffer) - 1) then
exit; // all full
chat_buffer[chat_bufferlen] := Char(key);
inc(chat_bufferlen);
chat_buffer[chat_bufferlen] := #0;
end; {Key_Message}
//============================================================================
{
===================
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)
}
function Key_StringToKeynum(str: PChar): integer;
var
kn: keyname_p;
begin
if (str = nil) or (str[0] = #0) then
begin
Result := -1;
exit;
end;
if str[1] = #0 then
begin
Result := Ord(str[0]);
exit;
end;
kn := @keynames[0];
while kn.name <> nil do
begin
// TODO -cDependancy : Check to see if Q_strcasecmp is case sensitive
// if StrIComp(str,kn.name) = 0 then // case insensitive version
if StrComp(str, kn.name) = 0 then
begin
Result := kn.keynum;
exit;
end;
Inc(kn);
end;
Result := -1;
end; {Key_StringToKeynum}
{
===================
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)
}
var // TODO : This Should be replaced with a delphi string!
tinystr: array[0..1] of char = (' ', ' ');
function Key_KeynumToString(keynum: Integer): Pchar;
var
kn: keyname_p;
begin
if (keynum = -1) then
begin
result := '<KEY NOT FOUND>';
exit;
end;
if (keynum > 32) and (keynum < 127) then
begin // printable ascii
tinystr[0] := Char(keynum);
tinystr[1] := #0;
result := tinystr;
exit;
end;
kn := @keynames[0];
while kn.name <> nil do
begin
if keynum = kn.keynum then
begin
Result := kn.name;
exit;
end;
Inc(kn);
end;
Result := '<UNKNOWN KEYNUM>';
end; {Key_KeynumToString}
{
===================
Key_SetBinding
===================
void Key_SetBinding (int keynum, char *binding)
}
procedure Key_SetBinding(keynum: integer; binding: PChar);
var
new: Pchar;
size: integer;
begin
if keynum = -1 then
exit;
// free old bindings
if keybindings[keynum] <> nil then
begin
Z_Free(keybindings[keynum]);
keybindings[keynum] := nil;
end;
// allocate memory for new binding
size := strlen(binding);
if size <> 0 then
begin
new := Z_Malloc(size + 1);
strcopy(new, binding);
new[size] := #0;
keybindings[keynum] := new;
end;
end; {Key_SetBinding}
{
===================
Key_Unbind_f
===================
void Key_Unbind_f (void)
}
procedure Key_Unbind_f; cdecl;
var
B: integer;
keystr: Pchar;
begin
if Cmd_Argc <> 2 then
begin
Com_Printf('unbind <key> : remove commands from a key'#10, []);
exit;
end;
keystr := Cmd_Argv(1);
b := Key_StringToKeynum(keystr);
if b = -1 then
begin
Com_Printf('"%d" isn''''t a valid key'#10, [keystr]);
exit;
end;
Key_SetBinding(b, '');
end; {Key_Unbind_f}
procedure Key_Unbindall_f; cdecl;
var
Index: integer;
begin
for index := 0 to 255 do
if keybindings[index] <> nil then
Key_SetBinding(Index, '');
end; {Key_Unbindall_f}
{
===================
Key_Bind_f
===================
void Key_Bind_f (void)
}
procedure Key_Bind_f; cdecl;
var
index, count, Keynum: integer;
cmd: array[0..1023] of char;
keystr: Pchar;
begin
count := Cmd_Argc();
if count < 2 then
begin
Com_Printf('bind <key> [command] : attach a command to a key'#10, []);
exit;
end;
keystr := Cmd_Argv(1);
Keynum := Key_StringToKeynum(keystr);
if Keynum = -1 then
begin
Com_Printf('"%s" isn''t a valid key'#10, [keystr]);
exit;
end;
if count = 2 then
begin
if (keybindings[Keynum] <> nil) then
Com_Printf('"%s" = "%s"'#10, [keystr, keybindings[Keynum]])
else
Com_Printf('"%s" is not bound'#10, [Cmd_Argv(1)]);
exit;
end;
// copy the rest of the command line
cmd[0] := #0; // start out with a null string
for index := 2 to count - 1 do
begin
strcat(cmd, Cmd_Argv(index));
if index <> count - 1 then
strcat(cmd, ' ');
end;
Key_SetBinding(Keynum, cmd);
end; {Key_Bind_f}
{
============
Key_WriteBindings
Writes lines containing "bind key value"
============
void Key_WriteBindings (FILE *f);
}
procedure Key_WriteBindings(var f: integer);
var
Index: integer;
tmp: string;
begin
For index := 0 to 255 do
if (keybindings[index] <> nil) and (keybindings[index][0] <> #0) then begin
tmp := 'bind ' + Key_KeynumToString(index) + ' "' + keybindings[index] + '"' + #13#10;
FileWrite(f, tmp[1], Length(tmp));
end;
end; {Key_WriteBindings}
{
============
Key_Bindlist_f
============
void Key_Bindlist_f (void)
}
procedure Key_Bindlist_f; cdecl;
var
Index: integer;
begin
for index := 0 to 255 do
if (keybindings[index] <> nil) and (keybindings[index][0] <> #0) then
Com_Printf('%s "%s"'#10, [Key_KeynumToString(index), keybindings[index]]);
end; {Key_Bindlist_f}
{
===================
Key_Init
===================
void Key_Init (void);
}
procedure Key_Init;
var
Index: integer;
begin
for Index := 0 to 31 do
begin
key_lines[Index][0] := ']';
key_lines[Index][1] := #0;
end;
key_linepos := 1;
//
// init ascii characters in console mode
//
for Index := 32 to 127 do
consolekeys[Index] := true;
consolekeys[K_ENTER] := true;
consolekeys[K_KP_ENTER] := true;
consolekeys[K_TAB] := true;
consolekeys[K_LEFTARROW] := true;
consolekeys[K_KP_LEFTARROW] := true;
consolekeys[K_RIGHTARROW] := true;
consolekeys[K_KP_RIGHTARROW] := true;
consolekeys[K_UPARROW] := true;
consolekeys[K_KP_UPARROW] := true;
consolekeys[K_DOWNARROW] := true;
consolekeys[K_KP_DOWNARROW] := true;
consolekeys[K_BACKSPACE] := true;
consolekeys[K_HOME] := true;
consolekeys[K_KP_HOME] := true;
consolekeys[K_END] := true;
consolekeys[K_KP_END] := true;
consolekeys[K_PGUP] := true;
consolekeys[K_KP_PGUP] := true;
consolekeys[K_PGDN] := true;
consolekeys[K_KP_PGDN] := true;
consolekeys[K_SHIFT] := true;
consolekeys[K_INS] := true;
consolekeys[K_KP_INS] := true;
consolekeys[K_KP_DEL] := true;
consolekeys[K_KP_SLASH] := true;
consolekeys[K_KP_PLUS] := true;
consolekeys[K_KP_MINUS] := true;
consolekeys[K_KP_5] := true;
consolekeys[Ord('`')] := false;
consolekeys[Ord('~')] := false;
for Index := 0 to 255 do
keyshift[Index] := Index;
for Index := ord('a') to ord('z') do
keyshift[Index] := Index - Ord('a') + Ord('A');
keyshift[Ord('1')] := Ord('!');
keyshift[Ord('2')] := Ord('@');
keyshift[Ord('3')] := Ord('#');
keyshift[Ord('4')] := Ord('$');
keyshift[Ord('5')] := Ord('%');
keyshift[Ord('6')] := Ord('^');
keyshift[Ord('7')] := Ord('&');
keyshift[Ord('8')] := Ord('*');
keyshift[Ord('9')] := Ord('(');
keyshift[Ord('0')] := Ord(')');
keyshift[Ord('-')] := Ord('_');
keyshift[Ord('=')] := Ord('+');
keyshift[Ord(',')] := Ord('<');
keyshift[Ord('.')] := Ord('>');
keyshift[Ord('/')] := Ord('?');
keyshift[Ord(';')] := Ord(':');
keyshift[Ord('''')] := Ord('"');
keyshift[Ord('[')] := Ord('{');
keyshift[Ord(']')] := Ord('}');
keyshift[Ord('`')] := Ord('~');
keyshift[Ord('\')] := Ord('|');
menubound[K_ESCAPE] := true;
for Index := 0 to 12 do
menubound[K_F1 + Index] := true;
//
// register our functions
//
Cmd_AddCommand('bind', @Key_Bind_f);
Cmd_AddCommand('unbind', @Key_Unbind_f);
Cmd_AddCommand('unbindall', @Key_Unbindall_f);
Cmd_AddCommand('bindlist', @Key_Bindlist_f);
end; {Key_Init}
{
===================
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, unsigned time);
}
procedure Key_Event(key: integer; Down: qboolean; time: Longword);
var
kb: pchar;
var
cmd: array[0..1023] of char;
begin
// hack for modal presses
if key_waiting = -1 then
begin
if down then
key_waiting := key;
exit;
end;
// update auto-repeat status
if down then
begin
Inc(key_repeats[key]);
if (key <> K_BACKSPACE) and
(key <> K_PAUSE) and
(key <> K_PGUP) and
(key <> K_KP_PGUP) and
(key <> K_PGDN) and
(key <> K_KP_PGDN) and
(key_repeats[key] > 1) then
exit; // ignore most autorepeats
if (key >= 200) and (keybindings[key] = nil) then
Com_Printf('%s is unbound, hit F4 to set.'#10, [Key_KeynumToString(key)]);
end
else
key_repeats[key] := 0;
if (key = K_SHIFT) then
shift_down := down;
// console key is hardcoded, so the user can never unbind it
if (key = ord('`')) or (key = ord('~')) then
begin
if not down then
exit;
Con_ToggleConsole_f();
exit;
end;
// any key during the attract mode will bring up the menu
if cl.attractloop and (cls.key_dest <> Client.key_menu) and
not ((key >= K_F1) and (key <= K_F12)) then
key := K_ESCAPE;
// menu key is hardcoded, so the user can never unbind it
if key = K_ESCAPE then
begin
if not down then
exit;
if (cl.frame.playerstate.stats[STAT_LAYOUTS] <> 0) and (cls.key_dest = Client.key_game) then
begin // put away help computer / inventory
Cbuf_AddText('cmd putaway'#10);
exit;
end;
case cls.key_dest of
Client.key_message: Key_Message(key);
Client.key_menu: M_Keydown(key);
Client.key_game,
Client.key_console: M_Menu_Main_f ();
else
Com_Error(ERR_FATAL, 'Bad cls.key_dest', []);
end;
exit;
end;
// track if any key is down for BUTTON_ANY
keydown[key] := down;
if down then
begin
if (key_repeats[key] = 1) then
inc(anykeydown);
end
else
begin
Dec(anykeydown);
if anykeydown < 0 then
anykeydown := 0;
end;
//
// 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 not down then
begin
kb := keybindings[key];
if (kb <> nil) and (kb[0] = '+') then
begin
Com_sprintf(cmd, sizeof(cmd), '-%s %d %d'#10, [kb + 1, key, time]);
Cbuf_AddText(@cmd[0]);
end;
if (keyshift[key] <> key) then
begin
kb := keybindings[keyshift[key]];
if (kb <> nil) and (kb[0] = '+') then
begin
Com_sprintf(cmd, sizeof(cmd), '-%s %d %d'#10, [kb + 1, key, time]);
Cbuf_AddText(@cmd[0]);
end;
end;
exit;
end;
//
// if not a consolekey, send to the interpreter no matter what mode is
//
if ((cls.key_dest = Client.key_menu) and menubound[key]) or
((cls.key_dest = Client.key_console) and (not consolekeys[key])) or
((cls.key_dest = Client.key_game) and ((cls.state = ca_active) or (not consolekeys[key]))) then
begin
kb := keybindings[key];
if (kb <> nil) then
begin
if (kb[0] = '+') then
begin
// button commands add keynum and time as a parm
Com_sprintf(cmd, sizeof(cmd), '%s %d %d'#10, [kb, key, time]);
Cbuf_AddText(cmd);
end
else
begin
Cbuf_AddText(kb);
Cbuf_AddText(#10);
end;
end;
exit;
end;
if not down then
exit; // other systems only care about key down events
if shift_down then
key := keyshift[key];
case cls.key_dest of
Client.key_message: Key_Message(key);
Client.key_menu: M_Keydown (key);
Client.key_game,
Client.key_console: Key_Console(key);
else
Com_Error(ERR_FATAL, 'Bad cls.key_dest', []);
end;
end; {Key_Event}
{
==========
Key_ClearStates
==========
void Key_ClearStates (void);
}
procedure Key_ClearStates;
var
Index: integer;
begin
anykeydown := 0;
for index := 0 to 255 do
begin
if keydown[index] and (key_repeats[index] <> 0) then
Key_Event(index, false, 0);
keydown[index] := false;
key_repeats[index] := 0;
end;
end; {Key_ClearStates}
{
==========
Key_GetKey
==========
int Key_GetKey (void);
}
function Key_GetKey: integer;
begin
key_waiting := -1;
while key_waiting = -1 do
Sys_SendKeyEvents;
result := key_waiting;
end;
initialization
finalization
// make sure the memory allocated for the key bindings is freed
Key_Unbindall_f;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -