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; 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 { 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; consolekeys[K_DEL] = true; Near the beginning of the file, after: extern int key_linepos; 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; } |