⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keys.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit keys;
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): keys.h,Keys.c - Input handling                                    }
{                                                                            }
{                                                                            }
{ Initial conversion by : ggs (tazipper@lyocs.com)                           }
{ Initial conversion on : -Jan-2002                                        }
{                                                                            }
{ This File contains part of convertion of Quake2 source to ObjectPascal.    }
{ More information about this project can be found at:                       }
{ http://www.sulaco.co.za/quake2/                                            }
{                                                                            }
{ Copyright (C) 1997-2001 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.                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ Updated on : 03-jun-2002                                                   }
{ Updated by : Juha Hartikainen (juha@linearteam.org)                        }
{ - added needed units to uses clause                                        }
{ - removed NODEPEND hack                                                    }
{}
{ Updated on : 04-jun-2002                                                   }
{ Updated by : Juha Hartikainen (juha@linearteam.org)                        }
{ - Moved keydown variable to globalscopy as qmenu.pas needs it}
{}
{ Updated on : 05-jun-2002                                                   }
{ Updated by : Juha Hartikainen (juha@linearteam.org)                        }
{ - conversion fixes}
{}
{ Updated on : 25-jul-2002                                                   }
{ Updated by : burnin (leonel@linuxbr.com.br)                                }
{ - Uncommented menu calls                                                   }
{----------------------------------------------------------------------------}
{  Key.h is used by Clients.h                                                }
{  Key.h is used by Clients.h                                                }
{ * Still dependent (to compile correctly) on:                               }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{----------------------------------------------------------------------------}

interface

uses
  Windows, Client, q_shared;

const
  //
  // these are the key numbers that should be passed to Key_Event
  //
  K_TAB = 9;
  K_ENTER = 13;
  K_ESCAPE = 27;
  K_SPACE = 32;

  // normal keys should be passed as lowercased ascii

  K_BACKSPACE = 127;
  K_UPARROW = 128;
  K_DOWNARROW = 129;
  K_LEFTARROW = 130;
  K_RIGHTARROW = 131;

  K_ALT = 132;
  K_CTRL = 133;
  K_SHIFT = 134;
  K_F1 = 135;
  K_F2 = 136;
  K_F3 = 137;
  K_F4 = 138;
  K_F5 = 139;
  K_F6 = 140;
  K_F7 = 141;
  K_F8 = 142;
  K_F9 = 143;
  K_F10 = 144;
  K_F11 = 145;
  K_F12 = 146;
  K_INS = 147;
  K_DEL = 148;
  K_PGDN = 149;
  K_PGUP = 150;
  K_HOME = 151;
  K_END = 152;

  K_KP_HOME = 160;
  K_KP_UPARROW = 161;
  K_KP_PGUP = 162;
  K_KP_LEFTARROW = 163;
  K_KP_5 = 164;
  K_KP_RIGHTARROW = 165;
  K_KP_END = 166;
  K_KP_DOWNARROW = 167;
  K_KP_PGDN = 168;
  K_KP_ENTER = 169;
  K_KP_INS = 170;
  K_KP_DEL = 171;
  K_KP_SLASH = 172;
  K_KP_MINUS = 173;
  K_KP_PLUS = 174;

  K_PAUSE = 255;

  //
  // mouse buttons generate virtual keys
  //
  K_MOUSE1 = 200;
  K_MOUSE2 = 201;
  K_MOUSE3 = 202;

  //
  // joystick buttons
  //
  K_JOY1 = 203;
  K_JOY2 = 204;
  K_JOY3 = 205;
  K_JOY4 = 206;

  //
  // aux keys are for multi-buttoned joysticks to generate so they can use
  // the normal binding process
  //
  K_AUX1 = 207;
  K_AUX2 = 208;
  K_AUX3 = 209;
  K_AUX4 = 210;
  K_AUX5 = 211;
  K_AUX6 = 212;
  K_AUX7 = 213;
  K_AUX8 = 214;
  K_AUX9 = 215;
  K_AUX10 = 216;
  K_AUX11 = 217;
  K_AUX12 = 218;
  K_AUX13 = 219;
  K_AUX14 = 220;
  K_AUX15 = 221;
  K_AUX16 = 222;
  K_AUX17 = 223;
  K_AUX18 = 224;
  K_AUX19 = 225;
  K_AUX20 = 226;
  K_AUX21 = 227;
  K_AUX22 = 228;
  K_AUX23 = 229;
  K_AUX24 = 230;
  K_AUX25 = 231;
  K_AUX26 = 232;
  K_AUX27 = 233;
  K_AUX28 = 234;
  K_AUX29 = 235;
  K_AUX30 = 236;
  K_AUX31 = 237;
  K_AUX32 = 238;

  K_MWHEELDOWN = 239;
  K_MWHEELUP = 240;

procedure Key_Event(key: integer; Down: qboolean; time: Longword);
procedure Key_Init;
procedure Key_WriteBindings(var f: integer);
procedure Key_SetBinding(keynum: integer; binding: Pchar);
procedure Key_ClearStates;
function Key_GetKey: integer;
function Key_KeynumToString(keynum: Integer): Pchar;

// variable that need to be put in the Interface section
var
  chat_team: qboolean;
  chat_buffer: array[0..255] of char;
  chat_bufferlen: integer;
  anykeydown: integer;
  key_repeats: array[0..255] of Integer; // if > 1, it is autorepeating
  keybindings: array[0..255] of Pchar; //char *keybindings[256];
  keydown: array[0..255] of qboolean;

const
  MaxCmdLine = 256;

var
  key_lines: array[0..32-1, 0..MAXCMDLINE - 1] of char;
  key_linepos: integer;
  edit_line: integer = 0;

implementation

uses
  Sysutils,
  Cmd,
  Common,
  CVar,
  Console,
  sys_win,
  cl_main,
  menu,
  cl_scrn;

// key up events are sent even if in console mode
var
  shift_down: qBoolean = false; // int shift_down=false;

  history_line: integer = 0;

  key_waiting: integer;

  consolekeys: array[0..255] of qboolean; // if true, can't be rebound while in console
  menubound: array[0..255] of qboolean; // if true, can't be rebound while in menu
  keyshift: array[0..255] of Integer; // key to map to if shift held down in console

type
  keyname_p = ^keyname_t;
  keyname_t = record
    name: pchar;
    keynum: integer;
  end;

const
  keynames: array[0..88] of keyname_t =
  (
    (name: 'TAB'; keynum: K_TAB),
    (name: 'ENTER'; keynum: K_ENTER),
    (name: 'ESCAPE'; keynum: K_ESCAPE),
    (name: 'SPACE'; keynum: K_SPACE),
    (name: 'BACKSPACE'; keynum: K_BACKSPACE),
    (name: 'UPARROW'; keynum: K_UPARROW),
    (name: 'DOWNARROW'; keynum: K_DOWNARROW),
    (name: 'LEFTARROW'; keynum: K_LEFTARROW),
    (name: 'RIGHTARROW'; keynum: K_RIGHTARROW),

    (name: 'ALT'; keynum: K_ALT),
    (name: 'CTRL'; keynum: K_CTRL),
    (name: 'SHIFT'; keynum: K_SHIFT),

    (name: 'F1'; keynum: K_F1),
    (name: 'F2'; keynum: K_F2),
    (name: 'F3'; keynum: K_F3),
    (name: 'F4'; keynum: K_F4),
    (name: 'F5'; keynum: K_F5),
    (name: 'F6'; keynum: K_F6),
    (name: 'F7'; keynum: K_F7),
    (name: 'F8'; keynum: K_F8),
    (name: 'F9'; keynum: K_F9),
    (name: 'F10'; keynum: K_F10),
    (name: 'F11'; keynum: K_F11),
    (name: 'F12'; keynum: K_F12),

    (name: 'INS'; keynum: K_INS),
    (name: 'DEL'; keynum: K_DEL),
    (name: 'PGDN'; keynum: K_PGDN),
    (name: 'PGUP'; keynum: K_PGUP),
    (name: 'HOME'; keynum: K_HOME),
    (name: 'END'; keynum: K_END),

    (name: 'MOUSE1'; keynum: K_MOUSE1),
    (name: 'MOUSE2'; keynum: K_MOUSE2),
    (name: 'MOUSE3'; keynum: K_MOUSE3),

    (name: 'JOY1'; keynum: K_JOY1),
    (name: 'JOY2'; keynum: K_JOY2),
    (name: 'JOY3'; keynum: K_JOY3),
    (name: 'JOY4'; keynum: K_JOY4),

    (name: 'AUX1'; keynum: K_AUX1),
    (name: 'AUX2'; keynum: K_AUX2),
    (name: 'AUX3'; keynum: K_AUX3),
    (name: 'AUX4'; keynum: K_AUX4),
    (name: 'AUX5'; keynum: K_AUX5),
    (name: 'AUX6'; keynum: K_AUX6),
    (name: 'AUX7'; keynum: K_AUX7),
    (name: 'AUX8'; keynum: K_AUX8),
    (name: 'AUX9'; keynum: K_AUX9),
    (name: 'AUX10'; keynum: K_AUX10),
    (name: 'AUX11'; keynum: K_AUX11),
    (name: 'AUX12'; keynum: K_AUX12),
    (name: 'AUX13'; keynum: K_AUX13),
    (name: 'AUX14'; keynum: K_AUX14),
    (name: 'AUX15'; keynum: K_AUX15),
    (name: 'AUX16'; keynum: K_AUX16),
    (name: 'AUX17'; keynum: K_AUX17),
    (name: 'AUX18'; keynum: K_AUX18),
    (name: 'AUX19'; keynum: K_AUX19),
    (name: 'AUX20'; keynum: K_AUX20),
    (name: 'AUX21'; keynum: K_AUX21),
    (name: 'AUX22'; keynum: K_AUX22),
    (name: 'AUX23'; keynum: K_AUX23),
    (name: 'AUX24'; keynum: K_AUX24),
    (name: 'AUX25'; keynum: K_AUX25),
    (name: 'AUX26'; keynum: K_AUX26),
    (name: 'AUX27'; keynum: K_AUX27),
    (name: 'AUX28'; keynum: K_AUX28),
    (name: 'AUX29'; keynum: K_AUX29),
    (name: 'AUX30'; keynum: K_AUX30),
    (name: 'AUX31'; keynum: K_AUX31),
    (name: 'AUX32'; keynum: K_AUX32),

    (name: 'KP_HOME'; keynum: K_KP_HOME),
    (name: 'KP_UPARROW'; keynum: K_KP_UPARROW),
    (name: 'KP_PGUP'; keynum: K_KP_PGUP),
    (name: 'KP_LEFTARROW'; keynum: K_KP_LEFTARROW),
    (name: 'KP_5'; keynum: K_KP_5),
    (name: 'KP_RIGHTARROW'; keynum: K_KP_RIGHTARROW),
    (name: 'KP_END'; keynum: K_KP_END),
    (name: 'KP_DOWNARROW'; keynum: K_KP_DOWNARROW),
    (name: 'KP_PGDN'; keynum: K_KP_PGDN),
    (name: 'KP_ENTER'; keynum: K_KP_ENTER),
    (name: 'KP_INS'; keynum: K_KP_INS),
    (name: 'KP_DEL'; keynum: K_KP_DEL),
    (name: 'KP_SLASH'; keynum: K_KP_SLASH),
    (name: 'KP_MINUS'; keynum: K_KP_MINUS),
    (name: 'KP_PLUS'; keynum: K_KP_PLUS),

    (name: 'MWHEELUP'; keynum: K_MWHEELUP),
    (name: 'MWHEELDOWN'; keynum: K_MWHEELDOWN),

    (name: 'PAUSE'; keynum: K_PAUSE),

    (name: 'SEMICOLON'; keynum: ord(';')), // because a raw semicolon seperates commands
    (name: nil; keynum: - 1)
  );

  {
  ==============================================================================

                        LINE TYPING INTO THE CONSOLE

  ==============================================================================
  }

procedure CompleteCommand;
var
  s, cmd: Pchar; // s,cmd : String;
begin
  // TODO : Conferm string handling translation
  s := @key_lines[edit_line][1]; // key_lines[edit_line]+1; this works to, but isnt clear
  if (s[0] = '/') or (s[0] = '\') then
    Inc(s);
  cmd := Cmd_CompleteCommand(s);
  if cmd = nil then
    cmd := Cvar_CompleteVariable(s);
  if cmd <> nil then
  begin
    key_lines[edit_line][1] := '/';
    strcopy(@key_lines[edit_line][2], cmd); //  strcpy (key_lines[edit_line]+2, cmd);
    key_linepos := strlen(cmd) + 2;
    key_lines[edit_line][key_linepos] := ' ';
    Inc(key_linepos);
    key_lines[edit_line][key_linepos] := #0;
  end;
end; {CompleteCommand}

{
====================
Key_Console

Interactive line editing and console scrollback
====================
void Key_Console (int key)
}

procedure Key_Console(Key: integer);
var
  cbd: pchar;
  Index: integer;
begin
  case key of
    K_KP_SLASH: key := Ord('/');
    K_KP_MINUS: key := Ord('-');
    K_KP_PLUS: key := Ord('+');
    K_KP_HOME: key := Ord('7');
    K_KP_UPARROW: key := Ord('8');
    K_KP_PGUP: key := Ord('9');
    K_KP_LEFTARROW: key := Ord('4');
    K_KP_5: key := Ord('5');
    K_KP_RIGHTARROW: key := Ord('6');
    K_KP_END: key := Ord('1');
    K_KP_DOWNARROW: key := Ord('2');
    K_KP_PGDN: key := Ord('3');
    K_KP_INS: key := Ord('0');
    K_KP_DEL: key := Ord('.');
  end; {case}

  if ((UpCase(Char(key)) = 'V') and keydown[K_CTRL]) or
    (((key = K_INS) or (key = K_KP_INS)) and keydown[K_SHIFT]) then
  begin
    cbd := Sys_GetClipboardData;
    if cbd <> nil then
    begin
      // TODO : doesnt use the function result!
     //StrScan( cbd, #10#13#08); // strtok( cbd, "\n\r\b" );

      Index := strlen(cbd);
      if Index + key_linepos >= MAXCMDLINE then
        Index := MAXCMDLINE - key_linepos;

      if Index > 0 then
      begin
        cbd[Index] := #0;
        strcat(key_lines[edit_line], cbd);
        Inc(key_linepos, Index);
      end;
      FreeMem(cbd);
    end;
    exit;
  end;

  if (key = Ord('l')) and keydown[K_CTRL] then
  begin
    Cbuf_AddText('clear'#10);
    Exit;
  end;

  if (key = K_ENTER) or (key = K_KP_ENTER) then
  begin
    // backslash text are commands, else chat
    if (key_lines[edit_line][1] = '\') or (key_lines[edit_line][1] = '/') then
      Cbuf_AddText(@key_lines[edit_line][2]) //(key_lines[edit_line]+2)   // skip the >
    else
      Cbuf_AddText(@key_lines[edit_line][1]); //(key_lines[edit_line]+1); // valid command

    Cbuf_AddText(#10);
    Com_Printf('%s'#10, [key_lines[edit_line]]); //  Com_Printf ("%s\n",key_lines[edit_line]);

    //  edit_line := (edit_line + 1) & 31;
    history_line := edit_line;
    key_lines[edit_line][0] := ']';
    key_linepos := 1;
    // TODO -cDependancy : Unknown dependancy
    if (cls.state = ca_disconnected) then
      // force an update, because the command. may take some time
      SCR_UpdateScreen();
    exit;
  end;

  if key = K_TAB then
  begin // command completion
    CompleteCommand();
    Exit;
  end;

  if (key = K_BACKSPACE) or (key = K_LEFTARROW) or (key = K_KP_LEFTARROW) or
    ((UpCase(char(key)) = 'H') and keydown[K_CTRL]) then
  begin
    if key_linepos > 1 then
      Dec(key_linepos);
    exit;
  end;

  if (key = K_UPARROW) or (key = K_KP_UPARROW) or
    ((UpCase(char(key)) = 'p') and keydown[K_CTRL]) then
  begin
    while (history_line <> edit_line) and (key_lines[history_line][1] <> #0) do
      history_line := (history_line - 1) and 31;
    if history_line = edit_line then
      history_line := (edit_line + 1) and 31;
    strcopy(key_lines[edit_line], key_lines[history_line]);
    key_linepos := strlen(key_lines[edit_line]);
    exit;
  end;

  if (key = K_DOWNARROW) or (key = K_KP_DOWNARROW) or
    ((UpCase(char(key)) = 'n') and keydown[K_CTRL]) then
  begin
    if history_line = edit_line then
      exit;
    while (history_line <> edit_line) and (key_lines[history_line][1] <> #0) do
      history_line := (history_line + 1) and 31;
    if history_line = edit_line then
    begin
      key_lines[edit_line][0] := ']';
      key_linepos := 1;
    end
    else
    begin
      strcopy(key_lines[edit_line], key_lines[history_line]);
      key_linepos := strlen(key_lines[edit_line]);
    end;
    exit;
  end;

  if (key = K_PGUP) or (key = K_KP_PGUP) then
  begin
    con.display := con.display - 2;
    exit;
  end;

  if (key = K_PGDN) or (key = K_KP_PGDN) then
  begin
    con.display := con.display + 2;
    if (con.display > con.current) then
      con.display := con.current;
    exit;
  end;

  if (key = K_HOME) or (key = K_KP_HOME) then
  begin
    con.display := con.current - con.totallines + 10;
    exit;
  end;

  if (key = K_END) or (key = K_KP_END) then
  begin
    con.display := con.current;
    exit;
  end;

  if (key < 32) or (key > 127) then
    exit; // non printable

  if (key_linepos < MAXCMDLINE - 1) then
  begin
    key_lines[edit_line][key_linepos] := Char(key);
    Inc(key_linepos);
    key_lines[edit_line][key_linepos] := #0;
  end;
end; {Key_Console}

//============================================================================

procedure Key_Message(key: integer);
begin
  if (key = K_ENTER) or (key = K_KP_ENTER) then
  begin
    if chat_team then
      Cbuf_AddText('say_team "')
    else
      Cbuf_AddText('say "');
    Cbuf_AddText(chat_buffer);
    Cbuf_AddText('"'#10);
    cls.key_dest := Client.key_game;
    chat_bufferlen := 0;
    chat_buffer[0] := #0;
    exit;
  end;

  if (key = K_ESCAPE) then
  begin
    cls.key_dest := Client.key_game;
    chat_bufferlen := 0;
    chat_buffer[0] := #0;
    exit;
  end;

  if (key < 32) or (key > 127) then
    exit; // non printable

  if (key = K_BACKSPACE) then
  begin
    if chat_bufferlen <> 0 then
    begin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -