I've never been a big fan of QuakeWorld. While it's client-side
prediction was the starting point for what has become a major
factor in the succesful play of modern games such as Quake Arena and
Unreal Tournament, it was the first of it's kind and
I was never able to get used to it. There was, nowever, one feature of
the QuakeWorld client that I did wish would've been implemented in
NetQuake... The way that the console would "hold it's place" when you
scrolled back was a gem. Nothing more frustrating than trying
to look back in the consle history to read over something that had
occurred only to have the text scroll back down to the bottom
everytime something new got added to the console.
Surprising to me, it was quite easy to add this feature to the released source. Thanks to Radix and Maddes
whose other works on console code pointed me in the right direction to
come up with the code for this feature. Let's dig right in.
Right to the meat, in CONSOLE.C locate the function Con_Print. Find the line:
and comment it right out
// con_backscroll = 0; Enhanced scrollback [Fett]
Believe it or not, that's our meat and potatoes.
The little bugger that forces us all the way back down to the bottom of
the console
history everytime a new event is added. If con_backscroll has a value
it is used by the drawing routines to
determine how far back in the console history to start drawing. As it
was, everytime something new got printed to the console
we would get forced back down to the bottom.
Now we need to clean up some details. also in CONSOLE.C locate the Con_Linefeed function. Before the first line:
add the following:
// Enhanced scrollback [Fett]
if (con_backscroll)
con_backscroll++;
// Enhanced scrollback [Fett]
Everytime a line is added to the console it changes the relative location of all previous lines in the history.
Without the above code the console would still scroll when lines were added. While we wouldn't get forced back down to
the bottom, what we are looking for might still scroll off the screen again if there's a lot of action going on. This is
easy to understand if you see it. If you really want a clear picture comment this line out later after we've finished.
Now, onto some cosmetics. We'll recreate the up arrows that QuakeWorld uses to show that you are scrolled back in the console.
Still in CONSOLE.C, head down to the Con_DrawConsole function. Starting from the top:
after:
add:
int sb; // Enhanced scrollback [Fett]
then, after:
y = lines - 16 - (rows<<3); // may start slightly negative
add:
// Enhanced scrollback [Fett]
if (con_backscroll)
sb=2;
else
sb=0;
// Enhanced scrollback [Fett]
sb is going to be used by the upcoming drawing loop. If the console is scrolled back we need to leave some space for the
scrollback indicator so we don't want to draw the last two lines of text that would normally be there by default.
Let's comment out the definition of the drawing loop:
// for (i= con_current - rows + 1 ; i<=con_current ; i++, y+=8) //IDCODE
and let it take advantage of the sb variable as follows:
for (i= con_current - rows + 1 ; i<=con_current - sb ; i++, y+=8) // Enhanced scrollback [Fett]
Lastly let's put the drawing routine for the scrollback indicator. Immediately after the close of this last loop
add the following:
// Enhanced scrollback [Fett]
if (sb) // are we scrolled back?
{
y+=8; // skip a line
// draw arrows to show the buffer is backscrolled
for (x=0 ; x<con_linewidth ; x+=4)
Draw_Character ((x+1)<<3, y, '^');
}
// Enhanced scrollback [Fett]
That takes care of the drawing routines. One feature that would be convenient is to enable the HOME and END keys.
HOME taking us to the top of the console history and END taking us immediately down to the bottom (saves having to
PAGEDOWN over and over to get back down to the 'current events').
The code to do this already exists in the KEYS.C function Key_Console however the HOME and END keys aren't enabled
in the console. To activate them goto the KEYS.C function Key_Init. The list of keys that are valid within the
console end with the line:
consolekeys['~'] = false;
Add the following immediately after:
// Enhanced scrollback [Fett]
consolekeys[K_HOME] = true;
consolekeys[K_END] = true;
// Enhanced scrollback [Fett]
Now we have the HOME and END key functionality. One thing to note. There's a finite amount of memory allocated to the console
history before events are "lost forever". Hitting the HOME key early after starting up Quake will result in what appears to
be a blank console. It is, but it isn't. The HOME keys projects us to the beginning of the memory allocated to the console
history. Since it's early on, there haven't been enough events to fill up this space yet. Hitting PAGEDOWN enough times
will eventually yield text once we start hitting used lines. I'd ultimately like to have the HOME key bring us to the first
'readable' line in the history, but haven't endeavored to lick that yet. Based on the amount of feedback I got regarding the
math on my last tutorial, I wouldn't be surprised to see a fix for this issue fairly quickly in my mailbox.
As with most other tutorials you see around these days, this code 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.
While the GPL doesn't require that you give me credit if you use my code, it would be a nice thing to do. |