882 lines
20 KiB
C
882 lines
20 KiB
C
/*
|
|
===========================================================================
|
|
Copyright (C) 1999-2005 Id Software, Inc.
|
|
Copyright (C) 2007 HermitWorks Entertainment Corporation
|
|
|
|
This file is part of the Space Trader source code.
|
|
|
|
The Space Trader source 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.
|
|
|
|
The Space Trader source code 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 the Space Trader source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
// console.c
|
|
|
|
#include "client.h"
|
|
|
|
|
|
#define NUM_CON_TIMES 4
|
|
|
|
#define CON_TEXTSIZE 0x20000
|
|
#define CON_BORDERSIZE 4.0F
|
|
#define CON_SCROLLBARWIDTH 8.0F
|
|
|
|
|
|
typedef struct
|
|
{
|
|
qboolean initialized;
|
|
|
|
char text[CON_TEXTSIZE];
|
|
int textLen;
|
|
|
|
float fontScale;
|
|
|
|
float x, y, w, h;
|
|
|
|
int numLines; //number of lines in the console
|
|
int dispLines; //number of lines the console can display
|
|
int currLine; //bottom of console displays this line
|
|
|
|
int linewidth; //characters across screen
|
|
float displayFrac; //aproaches finalFrac at scr_conspeed
|
|
float finalFrac; //0.0 to 1.0 lines of console to display
|
|
|
|
float promptY;
|
|
|
|
vec4_t color; //for transparent notify lines
|
|
int time; //time last line was printed
|
|
|
|
} console_t;
|
|
|
|
#define DEFAULT_CONSOLE_WIDTH 78
|
|
|
|
static console_t cons[2];
|
|
|
|
|
|
cvar_t *con_conspeed;
|
|
cvar_t *con_notifytime;
|
|
|
|
const vec4_t console_color = { 1.0F, 1.0F, 1.0F, 1.0F };
|
|
|
|
static void Con_CountLines( int c )
|
|
{
|
|
fontInfo_t *font;
|
|
|
|
if( !re.GetFontFromFontSet )
|
|
return;
|
|
|
|
if( !cls.font )
|
|
return;
|
|
|
|
if( cls.glconfig.xscale == 0.0F )
|
|
return;
|
|
|
|
if( cons[c].w == 0.0F )
|
|
{
|
|
cons[c].x = -cls.glconfig.xbias / cls.glconfig.xscale;
|
|
cons[c].y = 0.0F;
|
|
cons[c].w = SCREEN_WIDTH + (cls.glconfig.xbias / cls.glconfig.xscale) * 2.0F;
|
|
cons[c].h = SCREEN_HEIGHT * 0.5F;
|
|
}
|
|
|
|
font = re.GetFontFromFontSet( cls.font, cons[c].fontScale );
|
|
|
|
cons[c].fontScale = ((c==0)?0.28F:0.35f) / cls.glconfig.yscale;
|
|
cons[c].dispLines = (int)(cons[c].h / (font->glyphs['A'].height * cons[c].fontScale * font->glyphScale * 1.5F));
|
|
|
|
//count lines
|
|
cons[c].numLines = CL_RenderText_ExtractLines( font, cons[c].fontScale * font->glyphScale, cons[c].color, cons[c].color,
|
|
cons[c].text, -1, 0, cons[c].w - CON_SCROLLBARWIDTH, NULL, 0, -1 ); //count lines - but don't store flow info
|
|
|
|
if( cons[c].currLine > cons[c].numLines - cons[c].dispLines - 1 )
|
|
cons[c].currLine = cons[c].numLines - cons[c].dispLines - 1;
|
|
}
|
|
|
|
void Con_Resize( int c, int display, float x, float y, float w, float h )
|
|
{
|
|
if( display >= 0 )
|
|
cons[c].currLine = display;
|
|
cons[c].x = x;
|
|
cons[c].y = y;
|
|
cons[c].w = w;
|
|
cons[c].h = h;
|
|
|
|
Con_CountLines( c );
|
|
}
|
|
|
|
void Con_HandleMouse( int c, float x, float y )
|
|
{
|
|
}
|
|
|
|
const char* Q_EXTERNAL_CALL Con_GetText( int console )
|
|
{
|
|
if( console >= 0 && console < lengthof( cons ) && cons[console].text )
|
|
return cons[console].text;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
void Con_HandleKey( int c, int key )
|
|
{
|
|
switch( key )
|
|
{
|
|
case K_HOME:
|
|
cons[c].currLine = cons[c].numLines ? 0 : -1;
|
|
break;
|
|
|
|
case K_END:
|
|
cons[c].currLine = cons[c].numLines - 1;
|
|
|
|
if( cons[c].currLine > cons[c].numLines - cons[c].dispLines - 1 )
|
|
cons[c].currLine = cons[c].numLines - cons[c].dispLines - 1;
|
|
break;
|
|
|
|
case K_PGUP:
|
|
cons[c].currLine -= 2;
|
|
|
|
if( cons[c].currLine < 0 )
|
|
cons[c].currLine = 0;
|
|
break;
|
|
|
|
case K_PGDN:
|
|
cons[c].currLine += 2;
|
|
|
|
if( cons[c].currLine > cons[c].numLines - cons[c].dispLines - 1 )
|
|
cons[c].currLine = cons[c].numLines - cons[c].dispLines - 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Con_Clear( int c )
|
|
{
|
|
cons[c].text[0] = 0;
|
|
cons[c].textLen = 0;
|
|
cons[c].numLines = 0;
|
|
|
|
Con_Bottom();
|
|
}
|
|
|
|
void Con_Draw( int index, float frac, bool scrollBar, bool background )
|
|
{
|
|
int i, n, rows, currLine, numChars;
|
|
float lineHeight,width=0.0f;
|
|
|
|
float cl[4];
|
|
|
|
//const vec4_t scrollBarColor = { 0.4F, 0.4F, 0.4F, 0.8F };
|
|
const vec4_t scrollThumbColor = { 0.7F, 0.7F, 0.7F, 0.75F };
|
|
|
|
const char *txt;
|
|
lineInfo_t lines[128];
|
|
|
|
fontInfo_t *font;
|
|
console_t *c = cons + index;
|
|
|
|
c->fontScale = ((index==0)?0.28F:0.35f) / cls.glconfig.yscale;
|
|
font = re.GetFontFromFontSet( cls.font, c->fontScale );
|
|
|
|
lineHeight = font->glyphs['A'].height * c->fontScale * font->glyphScale * 1.5F;
|
|
|
|
rows = (int)((c->h * frac) / lineHeight);
|
|
|
|
if( rows < 1 )
|
|
return;
|
|
|
|
currLine = c->currLine + c->dispLines - rows;
|
|
|
|
//
|
|
// draw scroll indicator
|
|
//
|
|
if( scrollBar )
|
|
{
|
|
float ty, th;
|
|
|
|
//SCR_FillRect( c->x + c->w - CON_SCROLLBARWIDTH, c->y, CON_SCROLLBARWIDTH, c->h * frac, scrollBarColor, cls.menu );
|
|
|
|
th = (float)c->dispLines / (float)c->numLines;
|
|
if( th > 1 )
|
|
th = 1;
|
|
|
|
ty = (float)c->currLine / (float)c->numLines;
|
|
|
|
SCR_FillRect( c->x + c->w - CON_SCROLLBARWIDTH - CON_BORDERSIZE, c->y + ty * c->h * frac, CON_SCROLLBARWIDTH, th * c->h * frac, scrollThumbColor, cls.menu );
|
|
}
|
|
|
|
//rip through the lines till we get to the one we want to draw from
|
|
txt = c->text;
|
|
Vec4_Cpy( cl, c->color );
|
|
|
|
for( i = currLine; i > 0; )
|
|
{
|
|
n = CL_RenderText_ExtractLines( font, c->fontScale * font->glyphScale, c->color, c->color,
|
|
txt, -1, 0, c->w - CON_SCROLLBARWIDTH, lines, 0, min( i, lengthof( lines ) ) );
|
|
|
|
i -= n;
|
|
txt = lines[n - 1].text + lines[n - 1].count;
|
|
|
|
if( txt[0] == '\n' )
|
|
txt++;
|
|
|
|
while( txt[0] == ' ' )
|
|
txt++;
|
|
|
|
Vec4_Cpy( cl, lines[n - 1].endColor );
|
|
}
|
|
|
|
//get line info
|
|
|
|
n = CL_RenderText_ExtractLines( font, c->fontScale * font->glyphScale, cl, c->color,
|
|
txt, -1, 0, c->w - CON_SCROLLBARWIDTH, lines, 0, min( rows, lengthof( lines ) ) );
|
|
|
|
numChars = 0;
|
|
for( i = 0; i < n; i++ ) {
|
|
numChars += lines[i].count;
|
|
width = max( width, lines[i].width );
|
|
}
|
|
|
|
if ( background ) {
|
|
float x = c->x;
|
|
float y = c->y;
|
|
float w = width+CON_BORDERSIZE*2.0f;
|
|
float h = n*lineHeight;
|
|
SCR_AdjustFrom640( &x, &y, &w, &h );
|
|
re.DrawStretchPic( x,y,w,h, NULL, 0, 0, 1, 1, cls.whiteShader );
|
|
}
|
|
|
|
re.TextBeginBlock( numChars );
|
|
|
|
for( i = 0; i < n; i++ )
|
|
{
|
|
re.SetColor( c->color );
|
|
if( !lines[i].count )
|
|
continue;
|
|
CL_RenderText_Line( lines + i, font, c->x + CON_BORDERSIZE, c->y + (i + 1) * lineHeight, c->fontScale * font->glyphScale, 1.0F, 1.0F, 0, -1, 0, qtrue );
|
|
}
|
|
|
|
re.TextEndBlock();
|
|
|
|
re.SetColor( NULL );
|
|
}
|
|
|
|
/*
|
|
================
|
|
Con_ToggleConsole_f
|
|
================
|
|
*/
|
|
void Q_EXTERNAL_CALL Con_ToggleConsole_f (void) {
|
|
// closing a full screen console restarts the demo loop
|
|
if ( cls.state == CA_DISCONNECTED && cls.keyCatchers == KEYCATCH_CONSOLE ) {
|
|
CL_StartDemoLoop();
|
|
return;
|
|
}
|
|
|
|
Field_Clear( &g_consoleField );
|
|
|
|
Con_ClearNotify ();
|
|
cls.keyCatchers ^= KEYCATCH_CONSOLE;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Con_MessageMode_f
|
|
================
|
|
*/
|
|
void Q_EXTERNAL_CALL Con_MessageMode_f (void)
|
|
{
|
|
#if 0
|
|
chat_playerNum = -1;
|
|
chat_team = qfalse;
|
|
Field_Clear( &chatField );
|
|
|
|
cls.keyCatchers ^= KEYCATCH_MESSAGE;
|
|
#else
|
|
VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_CHAT );
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
================
|
|
Con_MessageMode2_f
|
|
================
|
|
*/
|
|
void Q_EXTERNAL_CALL Con_MessageMode2_f (void) {
|
|
chat_playerNum = -1;
|
|
chat_team = qtrue;
|
|
Field_Clear( &chatField );
|
|
cls.keyCatchers ^= KEYCATCH_MESSAGE;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Con_MessageMode3_f
|
|
================
|
|
*/
|
|
void Q_EXTERNAL_CALL Con_MessageMode3_f (void) {
|
|
chat_playerNum = VM_Call( cgvm, CG_CROSSHAIR_PLAYER );
|
|
if ( chat_playerNum < 0 || chat_playerNum >= MAX_CLIENTS ) {
|
|
chat_playerNum = -1;
|
|
return;
|
|
}
|
|
chat_team = qfalse;
|
|
Field_Clear( &chatField );
|
|
cls.keyCatchers ^= KEYCATCH_MESSAGE;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Con_MessageMode4_f
|
|
================
|
|
*/
|
|
void Q_EXTERNAL_CALL Con_MessageMode4_f (void) {
|
|
chat_playerNum = VM_Call( cgvm, CG_LAST_ATTACKER );
|
|
if ( chat_playerNum < 0 || chat_playerNum >= MAX_CLIENTS ) {
|
|
chat_playerNum = -1;
|
|
return;
|
|
}
|
|
chat_team = qfalse;
|
|
Field_Clear( &chatField );
|
|
cls.keyCatchers ^= KEYCATCH_MESSAGE;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Con_Clear_f
|
|
================
|
|
*/
|
|
void Q_EXTERNAL_CALL Con_Clear_f (void) {
|
|
|
|
Con_Clear( 0 );
|
|
}
|
|
|
|
|
|
/*
|
|
================
|
|
Con_Dump_f
|
|
|
|
Save the console contents out to a file
|
|
================
|
|
*/
|
|
void Q_EXTERNAL_CALL Con_Dump_f (void)
|
|
{
|
|
fileHandle_t f;
|
|
|
|
if (Cmd_Argc() != 2)
|
|
{
|
|
Com_Printf ("usage: condump <filename>\n");
|
|
return;
|
|
}
|
|
|
|
Com_Printf ("Dumped console text to %s.\n", Cmd_Argv(1) );
|
|
|
|
f = FS_FOpenFileWrite( Cmd_Argv( 1 ) );
|
|
if (!f)
|
|
{
|
|
Com_Printf ("ERROR: couldn't open.\n");
|
|
return;
|
|
}
|
|
|
|
FS_Write( cons[ 0 ].text, strlen( cons[ 0 ].text ), f );
|
|
FS_FCloseFile( f );
|
|
}
|
|
|
|
|
|
/*
|
|
================
|
|
Con_ClearNotify
|
|
================
|
|
*/
|
|
void Con_ClearNotify( void )
|
|
{
|
|
|
|
}
|
|
|
|
/*
|
|
================
|
|
Con_Init
|
|
================
|
|
*/
|
|
void Con_Init (void) {
|
|
int i;
|
|
con_notifytime = Cvar_Get ("con_notifytime", "3", 0);
|
|
con_conspeed = Cvar_Get ("scr_conspeed", "6", 0);
|
|
|
|
Field_Clear( &g_consoleField );
|
|
for ( i = 0 ; i < COMMAND_HISTORY ; i++ ) {
|
|
Field_Clear( &historyEditLines[i] );
|
|
}
|
|
|
|
Cmd_AddCommand( "toggleconsole", Con_ToggleConsole_f );
|
|
Cmd_AddCommand( "messagemode", Con_MessageMode_f );
|
|
// Cmd_AddCommand( "messagemode2", Con_MessageMode2_f );
|
|
// Cmd_AddCommand( "messagemode3", Con_MessageMode3_f );
|
|
// Cmd_AddCommand( "messagemode4", Con_MessageMode4_f );
|
|
Cmd_AddCommand( "clear", Con_Clear_f );
|
|
Cmd_AddCommand( "condump", Con_Dump_f );
|
|
}
|
|
|
|
/*
|
|
================
|
|
CL_ConsolePrint
|
|
|
|
Handles cursor positioning, line wrapping, etc
|
|
All console printing must go through this in order to be logged to disk
|
|
================
|
|
*/
|
|
int Con_Print( int index, const char *txt )
|
|
{
|
|
int len;
|
|
bool notify = false;
|
|
bool colorClear, autoScroll;
|
|
console_t *c = cons + index;
|
|
|
|
if( Q_strncmp( txt, "[NOTICE]", 8 ) == 0 )
|
|
{
|
|
notify = true;
|
|
txt += 8;
|
|
}
|
|
|
|
c->time = cls.realtime;
|
|
|
|
if ( index == 1 ) {
|
|
if ( c->finalFrac < 0.25f )
|
|
c->finalFrac = 0.25f;
|
|
}
|
|
|
|
// for some demos we don't want to ever show anything on the console
|
|
if( cl_noprint && cl_noprint->integer )
|
|
return 0;
|
|
|
|
if( !c->initialized )
|
|
{
|
|
c->color[0] =
|
|
c->color[1] =
|
|
c->color[2] =
|
|
c->color[3] = 1.0F;
|
|
c->linewidth = -1;
|
|
|
|
Con_ClearNotify();
|
|
|
|
c->initialized = qtrue;
|
|
c->fontScale = 0.19F;
|
|
c->text[0] = 0;
|
|
c->textLen = 0;
|
|
|
|
c->numLines = 0;
|
|
c->currLine = 0;
|
|
c->dispLines = 0;
|
|
}
|
|
|
|
len = strlen( txt );
|
|
|
|
colorClear = false;
|
|
|
|
if( txt[len - 1] == '\n' )
|
|
{
|
|
//find out if we need to append a color reset code
|
|
|
|
int i;
|
|
|
|
for( i = 0; i < len; i++ )
|
|
if( Q_IsColorString( txt + i ) )
|
|
{
|
|
colorClear = txt[i + 1] != '-';
|
|
i++;
|
|
}
|
|
}
|
|
|
|
if( colorClear )
|
|
len += 2;
|
|
|
|
if( len > lengthof( c->text ) - 1 )
|
|
{
|
|
//line's too long - pretend it isn't
|
|
|
|
len = lengthof( c->text ) - 1;
|
|
}
|
|
|
|
if( len > lengthof( c->text ) - 1 - c->textLen )
|
|
{
|
|
//not enough room in the buffer - move stuff back
|
|
|
|
const char *ch;
|
|
int numRem = len - (lengthof( c->text ) - 1 - c->textLen);
|
|
|
|
ch = c->text + numRem;
|
|
while( ch[0] != 0 && ch[0] != '\n' ) //find a null or newline
|
|
ch++;
|
|
|
|
c->textLen -= (ch - c->text);
|
|
memmove( c->text, ch, c->textLen );
|
|
c->text[c->textLen] = 0;
|
|
}
|
|
|
|
//move the new text into the buffer
|
|
if( colorClear )
|
|
{
|
|
memmove( c->text + c->textLen, txt, len - 3 );
|
|
|
|
c->text[c->textLen + len - 3] = '^';
|
|
c->text[c->textLen + len - 2] = '-';
|
|
c->text[c->textLen + len - 1] = '\n';
|
|
}
|
|
else
|
|
{
|
|
memmove( c->text + c->textLen, txt, len );
|
|
}
|
|
c->textLen += len;
|
|
c->text[c->textLen] = 0;
|
|
|
|
autoScroll = c->currLine == c->numLines - c->dispLines - 1;
|
|
|
|
Con_CountLines( index );
|
|
|
|
//update position
|
|
if( autoScroll )
|
|
c->currLine = c->numLines - c->dispLines - 1;
|
|
|
|
return c->numLines;
|
|
}
|
|
|
|
void CL_ConsolePrint( char *txt ) {
|
|
Con_Print( 0, txt );
|
|
#if 0
|
|
#ifdef USE_IRC
|
|
if ( !(txt[0] == 'I' && txt[1] == 'R' && txt[2] == 'C') )
|
|
Net_IRC_SendChat("#consolespam", txt);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
/*
|
|
==============================================================================
|
|
|
|
DRAWING
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
|
|
/*
|
|
================
|
|
Con_DrawInput
|
|
|
|
Draw the editline after a ] prompt
|
|
================
|
|
*/
|
|
void Con_DrawInput ( float y )
|
|
{
|
|
float rect[ 4 ];
|
|
if ( cls.state != CA_DISCONNECTED && !(cls.keyCatchers & KEYCATCH_CONSOLE ) )
|
|
return;
|
|
|
|
rect[ 0 ] = 0.0f;
|
|
rect[ 1 ] = y;
|
|
rect[ 2 ] = SCREEN_WIDTH;
|
|
rect[ 3 ] = 200.0f;
|
|
|
|
Field_Draw( &g_consoleField, rect, "]", cons[ 0 ].fontScale, cons[ 0 ].color );
|
|
}
|
|
|
|
|
|
/*
|
|
================
|
|
Con_DrawNotify
|
|
|
|
Draws the last few lines of output transparently over the game top
|
|
================
|
|
*/
|
|
void Con_DrawNotify( void )
|
|
{
|
|
#if 0
|
|
|
|
int i;
|
|
int time;
|
|
|
|
static float border[4] = { 0.0f,0.0f,0.0f,0.0f };
|
|
float rect[4];
|
|
float textColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
|
float backColor[4] = { 0.2f, 0.2f, 0.2f, 0.65f };
|
|
|
|
//
|
|
// define chat box
|
|
//
|
|
rect[ 0 ] = cl_conXOffset->value;
|
|
rect[ 1 ] = cl_conYOffset->value;
|
|
rect[ 2 ] = cl_conWidth->value;
|
|
rect[ 3 ] = cl_conHeight->value;
|
|
|
|
//
|
|
// find the first line to display
|
|
//
|
|
for ( i=cons[ 0 ].current-NUM_CON_TIMES+1; i<=cons[ 0 ].current ; i++ )
|
|
{
|
|
if (i < 0)
|
|
continue;
|
|
time = cons[ 0 ].times[i % NUM_CON_TIMES];
|
|
if (time == 0)
|
|
continue;
|
|
time = cls.realtime - time;
|
|
if (time > con_notifytime->integer*1000)
|
|
continue;
|
|
if (cl.snap.ps.pm_type != PM_INTERMISSION && cls.keyCatchers & (KEYCATCH_UI | KEYCATCH_CGAME) )
|
|
continue;
|
|
|
|
// attempt to fade out background
|
|
backColor[ 3 ] = min( 0.65f, 1.0f - ( (float)time/(float)((con_notifytime->integer+1)*1000)) );
|
|
|
|
//
|
|
// draw a window around the text, text can grow this window if needed
|
|
//
|
|
SCR_FillRect( border[ 0 ]-8.0f, border[ 1 ] - 4.0f, rect[ 2 ]+16.0f, border[ 3 ] + 8.0f, backColor, cls.menu );
|
|
|
|
//
|
|
// draw chat text
|
|
//
|
|
CL_RenderText( rect,
|
|
cons[ 0 ].fontScale * 1.25f,
|
|
textColor,
|
|
cons[ 0 ].lines[ i ].text,
|
|
-1,
|
|
0,
|
|
2,
|
|
3,
|
|
-1,
|
|
0,
|
|
cls.font,
|
|
border );
|
|
|
|
break;
|
|
}
|
|
|
|
if (cls.keyCatchers & (KEYCATCH_UI | KEYCATCH_CGAME) ) {
|
|
return;
|
|
}
|
|
|
|
// draw the chat line
|
|
if ( cls.keyCatchers & KEYCATCH_MESSAGE )
|
|
{
|
|
float rect[4];
|
|
|
|
rect[ 0 ] = SCREEN_WIDTH * 0.25f,
|
|
rect[ 1 ] = SCREEN_HEIGHT * 0.35f;
|
|
rect[ 2 ] = SCREEN_WIDTH * 0.5f;
|
|
rect[ 3 ] = 0.0f;
|
|
|
|
Field_Draw( &chatField, rect, (chat_team)?"say_team:":"say:", cons[ 0 ].fontScale * 2.5f, cons[ 0 ].color );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
================
|
|
Con_DrawSolidConsole
|
|
|
|
Draws the console with the solid background
|
|
================
|
|
*/
|
|
void Con_DrawSolidConsole( float frac )
|
|
{
|
|
int lines;
|
|
vec4_t color = { 0.2f,0.2f,0.2f,0.8f };
|
|
float screenLeft, screenWidth, screenRight;
|
|
console_t *c = cons + 0;
|
|
|
|
lines = c->h * frac;
|
|
if( lines < 24.0F )
|
|
return;
|
|
|
|
screenLeft = -cls.glconfig.xbias / cls.glconfig.xscale;
|
|
screenWidth = c->w + (cls.glconfig.xbias / cls.glconfig.xscale)*2.0f;
|
|
screenRight = screenLeft + screenWidth;
|
|
|
|
SCR_FillRect( screenLeft, 0.0f, screenWidth - CON_SCROLLBARWIDTH, c->h * frac, color, cls.menu );
|
|
|
|
//
|
|
// draw the version number
|
|
//
|
|
{
|
|
float rect[4];
|
|
rect[0] = 0.0f;
|
|
rect[1] = 8.0F;
|
|
rect[2] = 600.0F;
|
|
rect[3] = 16.0F;
|
|
//SCR_FillRect( rect[0], rect[1], rect[2], rect[3], color, cls.menu );
|
|
CL_RenderText( rect, 0.3F, colorRed, Q3_VERSION, -1, 2, 1, 3, -1, 0, cls.font*2.0f, 0 );
|
|
}
|
|
|
|
#if 0
|
|
//draw error indicator
|
|
{
|
|
int i;
|
|
stretchRect_t *scrollColors;
|
|
int numScrollColors;
|
|
|
|
numScrollColors = 0;
|
|
scrollColors = Hunk_AllocateTempMemory( sizeof( stretchRect_t ) * cons[0].numLines );
|
|
|
|
for( i = 0; i < cons[0].numLines; i++ )
|
|
{
|
|
int j = 0;
|
|
float x = screenRight - CON_SCROLLBARWIDTH;
|
|
float y = ((float)i / (float)cons[0].totallines) * SCREEN_HEIGHT * frac;
|
|
float w = CON_SCROLLBARWIDTH;
|
|
float h = (float)j / (float)cons[0].totallines * SCREEN_HEIGHT * frac;
|
|
|
|
if( h * cls.glconfig.yscale < 1.0F )
|
|
h = 1.0F / cls.glconfig.yscale + 0.000001F;
|
|
|
|
SCR_AdjustFrom640( &x, &y, &w, &h );
|
|
|
|
//Color the scroll bar based off the color of the text on that line.
|
|
if( Q_IsColorString( cons[0].lines[ i ].text ) )
|
|
{
|
|
float * color = (float*)(g_color_table + ColorIndex( cons[0].lines[ i ].text[1] ));
|
|
|
|
scrollColors[numScrollColors].pos[0] = x;
|
|
scrollColors[numScrollColors].pos[1] = y;
|
|
scrollColors[numScrollColors].size[0] = w;
|
|
scrollColors[numScrollColors].size[1] = h;
|
|
scrollColors[numScrollColors].tc0[0] = scrollColors[numScrollColors].tc0[1] = 0;
|
|
scrollColors[numScrollColors].tc1[0] = scrollColors[numScrollColors].tc1[1] = 1;
|
|
Com_Memcpy( scrollColors[numScrollColors].color, color, sizeof( vec4_t ) );
|
|
|
|
numScrollColors++;
|
|
}
|
|
}
|
|
|
|
re.DrawStretchPicMulti( scrollColors, numScrollColors, cls.whiteShader );
|
|
|
|
Hunk_FreeTempMemory( scrollColors );
|
|
}
|
|
#endif
|
|
|
|
Con_Draw( 0, frac, qtrue, qfalse );
|
|
|
|
// draw the input prompt, user text, and cursor if desired
|
|
Con_DrawInput( (float)lines + 2.0f );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Con_DrawConsole
|
|
==================
|
|
*/
|
|
void Con_DrawConsole( void )
|
|
{
|
|
// if disconnected, render console full screen
|
|
if( cls.state == CA_DISCONNECTED )
|
|
{
|
|
if( !(cls.keyCatchers & (KEYCATCH_UI | KEYCATCH_CGAME)) )
|
|
{
|
|
Con_Resize( 0, cons[0].currLine,
|
|
-cls.glconfig.xbias / cls.glconfig.xscale, 0.0F,
|
|
SCREEN_WIDTH + (cls.glconfig.xbias / cls.glconfig.xscale) * 2.0F,
|
|
SCREEN_HEIGHT - 20.0F );
|
|
|
|
Con_DrawSolidConsole( 1.0F );
|
|
return;
|
|
}
|
|
}
|
|
else if( cons[0].h == SCREEN_HEIGHT - 20.0F )
|
|
{
|
|
Con_Resize( 0, cons[0].currLine, 0, 0, 0, 0 ); //force defaults
|
|
}
|
|
|
|
if( cons[0].displayFrac )
|
|
{
|
|
Con_DrawSolidConsole( cons[0].displayFrac );
|
|
}
|
|
else
|
|
{
|
|
#if 1
|
|
// draw notify lines
|
|
if ( cls.state == CA_ACTIVE && cons[1].displayFrac>0.0f ) {
|
|
vec4_t color = { 0.3f,0.3f,0.3f,0.75f };
|
|
re.SetColor( color );
|
|
cons[1].currLine = cons[1].numLines - cons[1].dispLines - 1;
|
|
Con_Draw( 1, cons[1].displayFrac, qfalse, qtrue );
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//================================================================
|
|
|
|
/*
|
|
==================
|
|
Con_RunConsole
|
|
|
|
Scroll it up or down
|
|
==================
|
|
*/
|
|
void Con_RunConsole (void) {
|
|
|
|
int i;
|
|
|
|
// decide on the destination height of the console
|
|
if ( cls.keyCatchers & KEYCATCH_CONSOLE )
|
|
cons[0].finalFrac = 1;
|
|
else
|
|
cons[0].finalFrac = 0;
|
|
|
|
if ( (cls.realtime - cons[1].time) > con_notifytime->integer*1000 ) {
|
|
cons[1].finalFrac = 0.0f;
|
|
}
|
|
|
|
for ( i=0; i<2; i++ ) {
|
|
// scroll towards the destination height
|
|
if (cons[i].finalFrac < cons[i].displayFrac)
|
|
{
|
|
cons[i].displayFrac -= con_conspeed->value*cls.realFrametime*0.002f;
|
|
if (cons[i].finalFrac > cons[i].displayFrac)
|
|
cons[i].displayFrac = cons[i].finalFrac;
|
|
|
|
}
|
|
else if (cons[i].finalFrac > cons[i].displayFrac)
|
|
{
|
|
cons[i].displayFrac += con_conspeed->value*cls.realFrametime*0.002f;
|
|
if (cons[i].finalFrac < cons[i].displayFrac)
|
|
cons[i].displayFrac = cons[i].finalFrac;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Con_PageUp( void ) {
|
|
Con_HandleKey( 0, K_PGUP );
|
|
}
|
|
|
|
void Con_PageDown( void ) {
|
|
Con_HandleKey( 0, K_PGDN );
|
|
}
|
|
|
|
void Con_Top( void ) {
|
|
Con_HandleKey( 0, K_HOME );
|
|
}
|
|
|
|
void Con_Bottom( void ) {
|
|
Con_HandleKey( 0, K_END );
|
|
}
|
|
|
|
|
|
void Con_Close( void ) {
|
|
if ( !com_cl_running->integer ) {
|
|
return;
|
|
}
|
|
Field_Clear( &g_consoleField );
|
|
Con_ClearNotify ();
|
|
cls.keyCatchers &= ~KEYCATCH_CONSOLE;
|
|
cons[ 0 ].finalFrac = 0; // none visible
|
|
cons[ 0 ].displayFrac = 0;
|
|
}
|