Tutorial *83*
In this tutorial I'll make the quake console more like the DOS prompt with doskey running. You'll be able to use the left arrow key to scroll back to the beginning of whatever you're typing to make corrections without having to retype the whole thing, like you have had to with Quake before. Also you can go back to the middle and use the insert key to insert text in the middle. I made this tutorial for Winquake/GlQuake but it will probably work under [gl]qwcl as well.

Open keys.c

Near the beginning of the file, after:



int	key_lastpress;

add this line:


int	key_insert; // insert key toggle

Now find the Key_Console function. This is the function that handles all key presses meant for the console when the console is down. There are quite a few changes in this function so I'm just going to print most of the function, any changes I made are in red:



void Key_Console (int key)

{

	char	*cmd;



	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;    // 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

		cmd = Cmd_CompleteCommand (key_lines[edit_line]+1);

		if (!cmd)

			cmd = Cvar_CompleteVariable (key_lines[edit_line]+1);

		if (cmd)

		{

			Q_strcpy (key_lines[edit_line]+1, cmd);

			key_linepos = Q_strlen(cmd)+1;

			key_lines[edit_line][key_linepos] = ' ';

			key_linepos++;

			key_lines[edit_line][key_linepos] = 0;

			return;

		}

	}



// left arrow will just move left one w/o earsing, backspace will

// actually erase charcter

	if (key == K_LEFTARROW)

	{

		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 we're at the end, get one character from previous line,

// otherwise just go right one

	if (key == K_RIGHTARROW)

	{

		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;

	}



	if (key == K_UPARROW)

	{

		do

		{

(snip)---skip to near end of function


	if (key < 32 || key > 127)

		return;	// non printable



	if (key_linepos < MAXCMDLINE-1)

	{

		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];

		key_lines[edit_line][key_linepos] = key;

		key_linepos++;

		if (!i)

			key_lines[edit_line][key_linepos] = 0;

	}



}

Now find the Key_Init function. This function initializes keyboard settings, including which characters are meant for the console. We just used Insert and Delete in the Key_Console function, but it happens that these keys have not been set to be sent to the console. After this line:



consolekeys[K_BACKSPACE] = true;

Add these two lines:


consolekeys[K_DEL] = true;
consolekeys[K_INS] = true;
That's all for keys.c, now open console.c

Near the beginning of the file, after:



extern int	key_linepos;

add this line:


extern int	key_insert; // insert key toggle

Now find the Con_DrawInputFunction, the function that draws the line of text you're typing in at the console. More major changes to this function:



// use strlen of edit_line instead of key_linepos to allow editing

// of early characters w/o erasing

void Con_DrawInput (void)

{

	int		y;

	int		i;

	char	editlinecopy[256], *text;



	if (key_dest != key_console && !con_forcedup)

		return;		// don't draw anything



	text = strcpy(editlinecopy, key_lines[edit_line]);



	y = strlen(text);



// fill out remainder with spaces

	for (i = y; i < 256; i++)

		text[i] = ' ';



// add the cursor frame

	if ((int)(realtime * con_cursorspeed) & 1)	// cursor is visible

		text[key_linepos] = 11 + 130 * key_insert;	// either solid block or triagle facing right



//	prestep if horizontally scrolling

	if (key_linepos >= con_linewidth)

		text += 1 + key_linepos - con_linewidth;



// draw it

	y = con_vislines-16;



	for (i=0 ; i < con_linewidth ; i++)

		Draw_Character ( (i+1)<<3, con_vislines - 16, text[i]);



// remove cursor

//	key_lines[edit_line][key_linepos] = 0;

}

There--now you can make all those mistakes you used to make typing in the console and not spend as much time correcting them! :)


 
Sign up
Login:
Passwd:
[Remember Me]