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 + -
显示快捷键?