keys.c
来自「quake1 dos源代码最新版本」· C语言 代码 · 共 980 行 · 第 1/2 页
C
980 行
/*
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.
*/
#include "quakedef.h"
// 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];
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_BACKSPACE || key == K_LEFTARROW)
{
if (key_linepos > 1)
key_linepos--;
return;
}
*/
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;
// 2000-01-05 Console scrolling fix by Maddes start
/*
if (con_backscroll > con_totallines - (vid.height>>3) - 1)
con_backscroll = con_totallines - (vid.height>>3) - 1;
*/
// 2000-01-05 Console scrolling fix by Maddes end
return;
}
if (key == K_PGDN || key==K_MWHEELDOWN)
{
con_backscroll -= 2;
// 2000-01-05 Console scrolling fix by Maddes start
/*
if (con_backscroll < 0)
con_backscroll = 0;
*/
// 2000-01-05 Console scrolling fix by Maddes end
return;
}
if (key == K_HOME)
{
// 2000-01-05 Console scrolling fix by Maddes start
// con_backscroll = con_totallines - (vid.height>>3) - 1;
con_backscroll = con_current - 1;
// 2000-01-05 Console scrolling fix by Maddes end
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;
}
}
//============================================================================
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?