2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition 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 3 of the License , or
( at your option ) any later version .
Doom 3 BFG Edition 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 Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# pragma hdrstop
2012-12-22 15:18:19 +00:00
# include "precompiled.h"
2012-11-26 18:58:24 +00:00
# include "ConsoleHistory.h"
# include "../renderer/ResolutionScale.h"
# include "Common_local.h"
# define CON_TEXTSIZE 0x30000
# define NUM_CON_TIMES 4
# define CONSOLE_FIRSTREPEAT 200
# define CONSOLE_REPEAT 100
# define COMMAND_HISTORY 64
2012-11-28 15:47:07 +00:00
struct overlayText_t
{
2012-11-26 18:58:24 +00:00
idStr text ;
justify_t justify ;
int time ;
} ;
// the console will query the cvar and command systems for
// command completion information
2012-11-28 15:47:07 +00:00
class idConsoleLocal : public idConsole
{
2012-11-26 18:58:24 +00:00
public :
virtual void Init ( ) ;
virtual void Shutdown ( ) ;
2012-11-28 15:47:07 +00:00
virtual bool ProcessEvent ( const sysEvent_t * event , bool forceAccept ) ;
2012-11-26 18:58:24 +00:00
virtual bool Active ( ) ;
virtual void ClearNotifyLines ( ) ;
2013-09-29 11:03:32 +00:00
virtual void Open ( ) ;
2012-11-26 18:58:24 +00:00
virtual void Close ( ) ;
2012-11-28 15:47:07 +00:00
virtual void Print ( const char * text ) ;
2012-11-26 18:58:24 +00:00
virtual void Draw ( bool forceFullScreen ) ;
2012-11-28 15:47:07 +00:00
virtual void PrintOverlay ( idOverlayHandle & handle , justify_t justify , const char * text , . . . ) ;
virtual idDebugGraph * CreateGraph ( int numItems ) ;
virtual void DestroyGraph ( idDebugGraph * graph ) ;
void Dump ( const char * toFile ) ;
2012-11-26 18:58:24 +00:00
void Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
private :
2013-09-21 12:12:42 +00:00
void Resize ( ) ;
2012-11-26 18:58:24 +00:00
void KeyDownEvent ( int key ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
void Linefeed ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
void PageUp ( ) ;
void PageDown ( ) ;
void Top ( ) ;
void Bottom ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
void DrawInput ( ) ;
void DrawNotify ( ) ;
void DrawSolidConsole ( float frac ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
void Scroll ( ) ;
void SetDisplayFraction ( float frac ) ;
void UpdateDisplayFraction ( ) ;
2012-11-28 15:47:07 +00:00
void DrawTextLeftAlign ( float x , float & y , const char * text , . . . ) ;
void DrawTextRightAlign ( float x , float & y , const char * text , . . . ) ;
2012-11-26 18:58:24 +00:00
float DrawFPS ( float y ) ;
float DrawMemoryUsage ( float y ) ;
2012-11-28 15:47:07 +00:00
void DrawOverlayText ( float & leftY , float & rightY , float & centerY ) ;
2012-11-26 18:58:24 +00:00
void DrawDebugGraphs ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//============================
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// allow these constants to be adjusted for HMD
int LOCALSAFE_LEFT ;
int LOCALSAFE_RIGHT ;
int LOCALSAFE_TOP ;
int LOCALSAFE_BOTTOM ;
int LOCALSAFE_WIDTH ;
int LOCALSAFE_HEIGHT ;
int LINE_WIDTH ;
int TOTAL_LINES ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
bool keyCatching ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
short text [ CON_TEXTSIZE ] ;
int current ; // line where next message will be printed
int x ; // offset in current line for next print
int display ; // bottom of console displays this line
int lastKeyEvent ; // time of last key event for scroll delay
int nextKeyEvent ; // keyboard repeat rate
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
float displayFrac ; // approaches finalFrac at con_speed
float finalFrac ; // 0.0 to 1.0 lines of console to display
int fracTime ; // time of last displayFrac update
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int vislines ; // in scanlines
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int times [ NUM_CON_TIMES ] ; // cls.realtime time the line was generated
2012-11-28 15:47:07 +00:00
// for transparent notify lines
2012-11-26 18:58:24 +00:00
idVec4 color ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idEditField historyEditLines [ COMMAND_HISTORY ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int nextHistoryLine ; // the last line in the history buffer, not masked
int historyLine ; // the line being displayed from history buffer
2012-11-28 15:47:07 +00:00
// will be <= nextHistoryLine
2012-11-26 18:58:24 +00:00
idEditField consoleField ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idList < overlayText_t > overlayText ;
2012-11-28 15:47:07 +00:00
idList < idDebugGraph * > debugGraphs ;
2013-09-21 12:12:42 +00:00
int lastVirtualScreenWidth ;
int lastVirtualScreenHeight ;
2012-11-26 18:58:24 +00:00
static idCVar con_speed ;
static idCVar con_notifyTime ;
static idCVar con_noPrint ;
} ;
static idConsoleLocal localConsole ;
2012-11-28 15:47:07 +00:00
idConsole * console = & localConsole ;
2012-11-26 18:58:24 +00:00
idCVar idConsoleLocal : : con_speed ( " con_speed " , " 3 " , CVAR_SYSTEM , " speed at which the console moves up and down " ) ;
idCVar idConsoleLocal : : con_notifyTime ( " con_notifyTime " , " 3 " , CVAR_SYSTEM , " time messages are displayed onscreen when console is pulled up " ) ;
# ifdef DEBUG
2012-11-28 15:47:07 +00:00
idCVar idConsoleLocal : : con_noPrint ( " con_noPrint " , " 0 " , CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT , " print on the console but not onscreen when console is pulled up " ) ;
2012-11-26 18:58:24 +00:00
# else
2012-11-28 15:47:07 +00:00
idCVar idConsoleLocal : : con_noPrint ( " con_noPrint " , " 1 " , CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT , " print on the console but not onscreen when console is pulled up " ) ;
2012-11-26 18:58:24 +00:00
# endif
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Misc stats
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = =
idConsoleLocal : : DrawTextLeftAlign
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawTextLeftAlign ( float x , float & y , const char * text , . . . )
{
2012-11-26 18:58:24 +00:00
char string [ MAX_STRING_CHARS ] ;
va_list argptr ;
va_start ( argptr , text ) ;
idStr : : vsnPrintf ( string , sizeof ( string ) , text , argptr ) ;
va_end ( argptr ) ;
renderSystem - > DrawSmallStringExt ( x , y + 2 , string , colorWhite , true ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
}
/*
= = = = = = = = = = = = = = = = = =
idConsoleLocal : : DrawTextRightAlign
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawTextRightAlign ( float x , float & y , const char * text , . . . )
{
2012-11-26 18:58:24 +00:00
char string [ MAX_STRING_CHARS ] ;
va_list argptr ;
va_start ( argptr , text ) ;
int i = idStr : : vsnPrintf ( string , sizeof ( string ) , text , argptr ) ;
va_end ( argptr ) ;
renderSystem - > DrawSmallStringExt ( x - i * SMALLCHAR_WIDTH , y + 2 , string , colorWhite , true ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
}
/*
= = = = = = = = = = = = = = = = = =
idConsoleLocal : : DrawFPS
= = = = = = = = = = = = = = = = = =
*/
# define FPS_FRAMES 6
2012-11-28 15:47:07 +00:00
float idConsoleLocal : : DrawFPS ( float y )
{
2012-11-26 18:58:24 +00:00
static int previousTimes [ FPS_FRAMES ] ;
static int index ;
static int previous ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// don't use serverTime, because that will be drifting to
// correct for internet lag changes, timescales, timedemos, etc
int t = Sys_Milliseconds ( ) ;
int frameTime = t - previous ;
previous = t ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
previousTimes [ index % FPS_FRAMES ] = frameTime ;
index + + ;
2012-11-28 15:47:07 +00:00
if ( index > FPS_FRAMES )
{
2012-11-26 18:58:24 +00:00
// average multiple frames together to smooth changes out a bit
int total = 0 ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < FPS_FRAMES ; i + + )
{
2012-11-26 18:58:24 +00:00
total + = previousTimes [ i ] ;
}
2012-11-28 15:47:07 +00:00
if ( ! total )
{
2012-11-26 18:58:24 +00:00
total = 1 ;
}
int fps = 1000000 * FPS_FRAMES / total ;
fps = ( fps + 500 ) / 1000 ;
2012-11-28 15:47:07 +00:00
const char * s = va ( " %ifps " , fps ) ;
2012-11-26 18:58:24 +00:00
int w = strlen ( s ) * BIGCHAR_WIDTH ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
renderSystem - > DrawBigStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , s , colorWhite , true ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
y + = BIGCHAR_HEIGHT + 4 ;
2012-11-28 15:47:07 +00:00
2013-01-20 14:52:01 +00:00
// DG: "com_showFPS 2" means: show FPS only, like in classic doom3
if ( com_showFPS . GetInteger ( ) = = 2 )
{
return y ;
}
// DG end
2012-11-26 18:58:24 +00:00
// print the resolution scale so we can tell when we are at reduced resolution
idStr resolutionText ;
resolutionScale . GetConsoleText ( resolutionText ) ;
int w = resolutionText . Length ( ) * BIGCHAR_WIDTH ;
renderSystem - > DrawBigStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , resolutionText . c_str ( ) , colorWhite , true ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
const int gameThreadTotalTime = commonLocal . GetGameThreadTotalTime ( ) ;
const int gameThreadGameTime = commonLocal . GetGameThreadGameTime ( ) ;
const int gameThreadRenderTime = commonLocal . GetGameThreadRenderTime ( ) ;
const int rendererBackEndTime = commonLocal . GetRendererBackEndMicroseconds ( ) ;
const int rendererShadowsTime = commonLocal . GetRendererShadowsMicroseconds ( ) ;
const int rendererGPUIdleTime = commonLocal . GetRendererIdleMicroseconds ( ) ;
const int rendererGPUTime = commonLocal . GetRendererGPUMicroseconds ( ) ;
const int maxTime = 16 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
y + = SMALLCHAR_HEIGHT + 4 ;
idStr timeStr ;
timeStr . Format ( " %sG+RF: %4d " , gameThreadTotalTime > maxTime ? S_COLOR_RED : " " , gameThreadTotalTime ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sG: %4d " , gameThreadGameTime > maxTime ? S_COLOR_RED : " " , gameThreadGameTime ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sRF: %4d " , gameThreadRenderTime > maxTime ? S_COLOR_RED : " " , gameThreadRenderTime ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sRB: %4.1f " , rendererBackEndTime > maxTime * 1000 ? S_COLOR_RED : " " , rendererBackEndTime / 1000.0f ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sSV: %4.1f " , rendererShadowsTime > maxTime * 1000 ? S_COLOR_RED : " " , rendererShadowsTime / 1000.0f ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sIDLE: %4.1f " , rendererGPUIdleTime > maxTime * 1000 ? S_COLOR_RED : " " , rendererGPUIdleTime / 1000.0f ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sGPU: %4.1f " , rendererGPUTime > maxTime * 1000 ? S_COLOR_RED : " " , rendererGPUTime / 1000.0f ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return y + BIGCHAR_HEIGHT + 4 ;
}
/*
= = = = = = = = = = = = = = = = = =
idConsoleLocal : : DrawMemoryUsage
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
float idConsoleLocal : : DrawMemoryUsage ( float y )
{
2012-11-26 18:58:24 +00:00
return y ;
}
//=========================================================================
/*
= = = = = = = = = = = = = =
Con_Clear_f
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
static void Con_Clear_f ( const idCmdArgs & args )
{
2012-11-26 18:58:24 +00:00
localConsole . Clear ( ) ;
}
/*
= = = = = = = = = = = = = =
Con_Dump_f
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
static void Con_Dump_f ( const idCmdArgs & args )
{
if ( args . Argc ( ) ! = 2 )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " usage: conDump <filename> \n " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
idStr fileName = args . Argv ( 1 ) ;
fileName . DefaultFileExtension ( " .txt " ) ;
2012-11-26 18:58:24 +00:00
common - > Printf ( " Dumped console text to %s. \n " , fileName . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
localConsole . Dump ( fileName . c_str ( ) ) ;
}
/*
= = = = = = = = = = = = = =
idConsoleLocal : : Init
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Init ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
keyCatching = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
LOCALSAFE_LEFT = 32 ;
2013-09-21 12:12:42 +00:00
LOCALSAFE_RIGHT = SCREEN_WIDTH - LOCALSAFE_LEFT ;
2012-11-26 18:58:24 +00:00
LOCALSAFE_TOP = 24 ;
2013-09-21 12:12:42 +00:00
LOCALSAFE_BOTTOM = SCREEN_HEIGHT - LOCALSAFE_TOP ;
2012-11-26 18:58:24 +00:00
LOCALSAFE_WIDTH = LOCALSAFE_RIGHT - LOCALSAFE_LEFT ;
LOCALSAFE_HEIGHT = LOCALSAFE_BOTTOM - LOCALSAFE_TOP ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
LINE_WIDTH = ( ( LOCALSAFE_WIDTH / SMALLCHAR_WIDTH ) - 2 ) ;
2012-11-28 15:47:07 +00:00
TOTAL_LINES = ( CON_TEXTSIZE / LINE_WIDTH ) ;
2012-11-26 18:58:24 +00:00
lastKeyEvent = - 1 ;
nextKeyEvent = CONSOLE_FIRSTREPEAT ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
consoleField . Clear ( ) ;
consoleField . SetWidthInChars ( LINE_WIDTH ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < COMMAND_HISTORY ; i + + )
{
2012-11-26 18:58:24 +00:00
historyEditLines [ i ] . Clear ( ) ;
historyEditLines [ i ] . SetWidthInChars ( LINE_WIDTH ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
cmdSystem - > AddCommand ( " clear " , Con_Clear_f , CMD_FL_SYSTEM , " clears the console " ) ;
cmdSystem - > AddCommand ( " conDump " , Con_Dump_f , CMD_FL_SYSTEM , " dumps the console text to a file " ) ;
}
/*
= = = = = = = = = = = = = =
idConsoleLocal : : Shutdown
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Shutdown ( )
{
2012-11-26 18:58:24 +00:00
cmdSystem - > RemoveCommand ( " clear " ) ;
cmdSystem - > RemoveCommand ( " conDump " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
debugGraphs . DeleteContents ( true ) ;
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : Active
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idConsoleLocal : : Active ( )
{
2012-11-26 18:58:24 +00:00
return keyCatching ;
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : ClearNotifyLines
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : ClearNotifyLines ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < NUM_CON_TIMES ; i + + )
{
2012-11-26 18:58:24 +00:00
times [ i ] = 0 ;
}
}
/*
= = = = = = = = = = = = = = = =
2013-09-29 11:03:32 +00:00
idConsoleLocal : : Open
= = = = = = = = = = = = = = = =
*/
void idConsoleLocal : : Open ( )
{
if ( keyCatching )
return ; // already open
consoleField . ClearAutoComplete ( ) ;
consoleField . Clear ( ) ;
keyCatching = true ;
SetDisplayFraction ( 0.5f ) ;
}
/*
= = = = = = = = = = = = = = = =
2012-11-26 18:58:24 +00:00
idConsoleLocal : : Close
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Close ( )
{
2012-11-26 18:58:24 +00:00
keyCatching = false ;
SetDisplayFraction ( 0 ) ;
displayFrac = 0 ; // don't scroll to that point, go immediately
ClearNotifyLines ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : Clear
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Clear ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < CON_TEXTSIZE ; i + + )
{
text [ i ] = ( idStr : : ColorIndex ( C_COLOR_CYAN ) < < 8 ) | ' ' ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Bottom ( ) ; // go to end
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : Dump
Save the console contents out to a file
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Dump ( const char * fileName )
{
2012-11-26 18:58:24 +00:00
int l , x , i ;
2012-11-28 15:47:07 +00:00
short * line ;
idFile * f ;
char * buffer = ( char * ) alloca ( LINE_WIDTH + 3 ) ;
2012-11-26 18:58:24 +00:00
f = fileSystem - > OpenFileWrite ( fileName ) ;
2012-11-28 15:47:07 +00:00
if ( ! f )
{
2012-11-26 18:58:24 +00:00
common - > Warning ( " couldn't open %s " , fileName ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// skip empty lines
l = current - TOTAL_LINES + 1 ;
2012-11-28 15:47:07 +00:00
if ( l < 0 )
{
2012-11-26 18:58:24 +00:00
l = 0 ;
}
2012-11-28 15:47:07 +00:00
for ( ; l < = current ; l + + )
2012-11-26 18:58:24 +00:00
{
line = text + ( l % TOTAL_LINES ) * LINE_WIDTH ;
2012-11-28 15:47:07 +00:00
for ( x = 0 ; x < LINE_WIDTH ; x + + )
if ( ( line [ x ] & 0xff ) > ' ' )
2012-11-26 18:58:24 +00:00
break ;
2012-11-28 15:47:07 +00:00
if ( x ! = LINE_WIDTH )
2012-11-26 18:58:24 +00:00
break ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// write the remaining lines
2012-11-28 15:47:07 +00:00
for ( ; l < = current ; l + + )
{
2012-11-26 18:58:24 +00:00
line = text + ( l % TOTAL_LINES ) * LINE_WIDTH ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < LINE_WIDTH ; i + + )
{
2012-11-26 18:58:24 +00:00
buffer [ i ] = line [ i ] & 0xff ;
}
2012-11-28 15:47:07 +00:00
for ( x = LINE_WIDTH - 1 ; x > = 0 ; x - - )
{
if ( buffer [ x ] < = ' ' )
{
2012-11-26 18:58:24 +00:00
buffer [ x ] = 0 ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2012-11-28 15:47:07 +00:00
buffer [ x + 1 ] = ' \r ' ;
buffer [ x + 2 ] = ' \n ' ;
buffer [ x + 3 ] = 0 ;
2012-11-26 18:58:24 +00:00
f - > Write ( buffer , strlen ( buffer ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fileSystem - > CloseFile ( f ) ;
}
2013-09-21 12:12:42 +00:00
/*
= = = = = = = = = = = = = =
idConsoleLocal : : Resize
= = = = = = = = = = = = = =
*/
void idConsoleLocal : : Resize ( )
{
if ( renderSystem - > GetVirtualWidth ( ) = = lastVirtualScreenWidth & & renderSystem - > GetVirtualHeight ( ) = = lastVirtualScreenHeight )
return ;
lastVirtualScreenWidth = renderSystem - > GetVirtualWidth ( ) ;
lastVirtualScreenHeight = renderSystem - > GetVirtualHeight ( ) ;
LOCALSAFE_RIGHT = renderSystem - > GetVirtualWidth ( ) - LOCALSAFE_LEFT ;
LOCALSAFE_BOTTOM = renderSystem - > GetVirtualHeight ( ) - LOCALSAFE_TOP ;
LOCALSAFE_WIDTH = LOCALSAFE_RIGHT - LOCALSAFE_LEFT ;
LOCALSAFE_HEIGHT = LOCALSAFE_BOTTOM - LOCALSAFE_TOP ;
}
2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : PageUp
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : PageUp ( )
{
2012-11-26 18:58:24 +00:00
display - = 2 ;
2012-11-28 15:47:07 +00:00
if ( current - display > = TOTAL_LINES )
{
2012-11-26 18:58:24 +00:00
display = current - TOTAL_LINES + 1 ;
}
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : PageDown
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : PageDown ( )
{
2012-11-26 18:58:24 +00:00
display + = 2 ;
2012-11-28 15:47:07 +00:00
if ( display > current )
{
2012-11-26 18:58:24 +00:00
display = current ;
}
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : Top
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Top ( )
{
2012-11-26 18:58:24 +00:00
display = 0 ;
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : Bottom
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Bottom ( )
{
2012-11-26 18:58:24 +00:00
display = current ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
CONSOLE LINE EDITING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = = = =
KeyDownEvent
Handles history and console scrollback
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : KeyDownEvent ( int key )
{
2012-11-26 18:58:24 +00:00
// Execute F key bindings
2012-11-28 15:47:07 +00:00
if ( key > = K_F1 & & key < = K_F12 )
{
2012-11-26 18:58:24 +00:00
idKeyInput : : ExecKeyBinding ( key ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// ctrl-L clears screen
2012-11-28 15:47:07 +00:00
if ( key = = K_L & & ( idKeyInput : : IsDown ( K_LCTRL ) | | idKeyInput : : IsDown ( K_RCTRL ) ) )
{
2012-11-26 18:58:24 +00:00
Clear ( ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// enter finishes the line
2012-11-28 15:47:07 +00:00
if ( key = = K_ENTER | | key = = K_KP_ENTER )
{
common - > Printf ( " ]%s \n " , consoleField . GetBuffer ( ) ) ;
2012-11-26 18:58:24 +00:00
cmdSystem - > BufferCommandText ( CMD_EXEC_APPEND , consoleField . GetBuffer ( ) ) ; // valid command
cmdSystem - > BufferCommandText ( CMD_EXEC_APPEND , " \n " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// copy line to history buffer
2012-11-28 15:47:07 +00:00
if ( consoleField . GetBuffer ( ) [ 0 ] ! = ' \n ' & & consoleField . GetBuffer ( ) [ 0 ] ! = ' \0 ' )
{
2012-11-26 18:58:24 +00:00
consoleHistory . AddToHistory ( consoleField . GetBuffer ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
consoleField . Clear ( ) ;
consoleField . SetWidthInChars ( LINE_WIDTH ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
const bool captureToImage = false ;
common - > UpdateScreen ( captureToImage ) ; // force an update, because the command
2012-11-28 15:47:07 +00:00
// may take some time
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// command completion
2012-11-28 15:47:07 +00:00
if ( key = = K_TAB )
{
2012-11-26 18:58:24 +00:00
consoleField . AutoComplete ( ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// command history (ctrl-p ctrl-n for unix style)
2012-11-28 15:47:07 +00:00
if ( ( key = = K_UPARROW ) | |
( key = = K_P & & ( idKeyInput : : IsDown ( K_LCTRL ) | | idKeyInput : : IsDown ( K_RCTRL ) ) ) )
{
2012-11-26 18:58:24 +00:00
idStr hist = consoleHistory . RetrieveFromHistory ( true ) ;
2012-11-28 15:47:07 +00:00
if ( ! hist . IsEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
consoleField . SetBuffer ( hist ) ;
}
return ;
}
2012-11-28 15:47:07 +00:00
if ( ( key = = K_DOWNARROW ) | |
( key = = K_N & & ( idKeyInput : : IsDown ( K_LCTRL ) | | idKeyInput : : IsDown ( K_RCTRL ) ) ) )
{
2012-11-26 18:58:24 +00:00
idStr hist = consoleHistory . RetrieveFromHistory ( false ) ;
2012-11-28 15:47:07 +00:00
if ( ! hist . IsEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
consoleField . SetBuffer ( hist ) ;
}
2012-12-21 03:52:56 +00:00
else // DG: if no more lines are in the history, show a blank line again
{
consoleField . Clear ( ) ;
} // DG end
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// console scrolling
2012-11-28 15:47:07 +00:00
if ( key = = K_PGUP )
{
2012-11-26 18:58:24 +00:00
PageUp ( ) ;
lastKeyEvent = eventLoop - > Milliseconds ( ) ;
nextKeyEvent = CONSOLE_FIRSTREPEAT ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( key = = K_PGDN )
{
2012-11-26 18:58:24 +00:00
PageDown ( ) ;
lastKeyEvent = eventLoop - > Milliseconds ( ) ;
nextKeyEvent = CONSOLE_FIRSTREPEAT ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( key = = K_MWHEELUP )
{
2012-11-26 18:58:24 +00:00
PageUp ( ) ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( key = = K_MWHEELDOWN )
{
2012-11-26 18:58:24 +00:00
PageDown ( ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// ctrl-home = top of console
2012-11-28 15:47:07 +00:00
if ( key = = K_HOME & & ( idKeyInput : : IsDown ( K_LCTRL ) | | idKeyInput : : IsDown ( K_RCTRL ) ) )
{
2012-11-26 18:58:24 +00:00
Top ( ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// ctrl-end = bottom of console
2012-11-28 15:47:07 +00:00
if ( key = = K_END & & ( idKeyInput : : IsDown ( K_LCTRL ) | | idKeyInput : : IsDown ( K_RCTRL ) ) )
{
2012-11-26 18:58:24 +00:00
Bottom ( ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// pass to the normal editline routine
consoleField . KeyDownEvent ( key ) ;
}
/*
= = = = = = = = = = = = = =
Scroll
deals with scrolling text because we don ' t have key repeat
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Scroll ( )
{
if ( lastKeyEvent = = - 1 | | ( lastKeyEvent + 200 ) > eventLoop - > Milliseconds ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
// console scrolling
2012-11-28 15:47:07 +00:00
if ( idKeyInput : : IsDown ( K_PGUP ) )
{
2012-11-26 18:58:24 +00:00
PageUp ( ) ;
nextKeyEvent = CONSOLE_REPEAT ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( idKeyInput : : IsDown ( K_PGDN ) )
{
2012-11-26 18:58:24 +00:00
PageDown ( ) ;
nextKeyEvent = CONSOLE_REPEAT ;
return ;
}
}
/*
= = = = = = = = = = = = = =
SetDisplayFraction
Causes the console to start opening the desired amount .
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : SetDisplayFraction ( float frac )
{
2012-11-26 18:58:24 +00:00
finalFrac = frac ;
fracTime = Sys_Milliseconds ( ) ;
}
/*
= = = = = = = = = = = = = =
UpdateDisplayFraction
Scrolls the console up or down based on conspeed
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : UpdateDisplayFraction ( )
{
if ( con_speed . GetFloat ( ) < = 0.1f )
{
2012-11-26 18:58:24 +00:00
fracTime = Sys_Milliseconds ( ) ;
displayFrac = finalFrac ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// scroll towards the destination height
2012-11-28 15:47:07 +00:00
if ( finalFrac < displayFrac )
{
2012-11-26 18:58:24 +00:00
displayFrac - = con_speed . GetFloat ( ) * ( Sys_Milliseconds ( ) - fracTime ) * 0.001f ;
2012-11-28 15:47:07 +00:00
if ( finalFrac > displayFrac )
{
2012-11-26 18:58:24 +00:00
displayFrac = finalFrac ;
}
fracTime = Sys_Milliseconds ( ) ;
2012-11-28 15:47:07 +00:00
}
else if ( finalFrac > displayFrac )
{
2012-11-26 18:58:24 +00:00
displayFrac + = con_speed . GetFloat ( ) * ( Sys_Milliseconds ( ) - fracTime ) * 0.001f ;
2012-11-28 15:47:07 +00:00
if ( finalFrac < displayFrac )
{
2012-11-26 18:58:24 +00:00
displayFrac = finalFrac ;
}
fracTime = Sys_Milliseconds ( ) ;
}
}
/*
= = = = = = = = = = = = = =
ProcessEvent
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idConsoleLocal : : ProcessEvent ( const sysEvent_t * event , bool forceAccept )
{
2012-11-26 18:58:24 +00:00
const bool consoleKey = event - > evType = = SE_KEY & & event - > evValue = = K_GRAVE & & com_allowConsole . GetBool ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// we always catch the console key event
2012-11-28 15:47:07 +00:00
if ( ! forceAccept & & consoleKey )
{
2012-11-26 18:58:24 +00:00
// ignore up events
2012-11-28 15:47:07 +00:00
if ( event - > evValue2 = = 0 )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
consoleField . ClearAutoComplete ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// a down event will toggle the destination lines
2012-11-28 15:47:07 +00:00
if ( keyCatching )
{
2012-11-26 18:58:24 +00:00
Close ( ) ;
Sys_GrabMouseCursor ( true ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
consoleField . Clear ( ) ;
keyCatching = true ;
2012-11-28 15:47:07 +00:00
if ( idKeyInput : : IsDown ( K_LSHIFT ) | | idKeyInput : : IsDown ( K_RSHIFT ) )
{
2012-11-26 18:58:24 +00:00
// if the shift key is down, don't open the console as much
SetDisplayFraction ( 0.2f ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
SetDisplayFraction ( 0.5f ) ;
}
}
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if we aren't key catching, dump all the other events
2012-11-28 15:47:07 +00:00
if ( ! forceAccept & & ! keyCatching )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// handle key and character events
2012-11-28 15:47:07 +00:00
if ( event - > evType = = SE_CHAR )
{
2012-11-26 18:58:24 +00:00
// never send the console key as a character
2012-11-28 15:47:07 +00:00
if ( event - > evValue ! = ' ` ' & & event - > evValue ! = ' ~ ' )
{
2012-11-26 18:58:24 +00:00
consoleField . CharEvent ( event - > evValue ) ;
}
return true ;
}
2012-11-28 15:47:07 +00:00
if ( event - > evType = = SE_KEY )
{
2012-11-26 18:58:24 +00:00
// ignore up key events
2012-11-28 15:47:07 +00:00
if ( event - > evValue2 = = 0 )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
KeyDownEvent ( event - > evValue ) ;
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// we don't handle things like mouse, joystick, and network packets
return false ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
PRINTING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = =
Linefeed
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Linefeed ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// mark time for transparent overlay
2012-11-28 15:47:07 +00:00
if ( current > = 0 )
{
2012-11-26 18:58:24 +00:00
times [ current % NUM_CON_TIMES ] = Sys_Milliseconds ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
x = 0 ;
2012-11-28 15:47:07 +00:00
if ( display = = current )
{
2012-11-26 18:58:24 +00:00
display + + ;
}
current + + ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < LINE_WIDTH ; i + + )
{
int offset = ( ( unsigned int ) current % TOTAL_LINES ) * LINE_WIDTH + i ;
text [ offset ] = ( idStr : : ColorIndex ( C_COLOR_CYAN ) < < 8 ) | ' ' ;
2012-11-26 18:58:24 +00:00
}
}
/*
= = = = = = = = = = = = = = = =
Print
Handles cursor positioning , line wrapping , etc
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Print ( const char * txt )
{
2012-11-26 18:58:24 +00:00
int y ;
int c , l ;
int color ;
2012-11-28 15:47:07 +00:00
if ( TOTAL_LINES = = 0 )
{
2012-11-26 18:58:24 +00:00
// not yet initialized
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
color = idStr : : ColorIndex ( C_COLOR_CYAN ) ;
2012-11-28 15:47:07 +00:00
while ( ( c = * ( const unsigned char * ) txt ) ! = 0 )
{
if ( idStr : : IsColor ( txt ) )
{
if ( * ( txt + 1 ) = = C_COLOR_DEFAULT )
{
2012-11-26 18:58:24 +00:00
color = idStr : : ColorIndex ( C_COLOR_CYAN ) ;
2012-11-28 15:47:07 +00:00
}
else
{
color = idStr : : ColorIndex ( * ( txt + 1 ) ) ;
2012-11-26 18:58:24 +00:00
}
txt + = 2 ;
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
y = current % TOTAL_LINES ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if we are about to print a new word, check to see
// if we should wrap to the new line
2012-11-28 15:47:07 +00:00
if ( c > ' ' & & ( x = = 0 | | text [ y * LINE_WIDTH + x - 1 ] < = ' ' ) )
{
2012-11-26 18:58:24 +00:00
// count word length
2012-11-28 15:47:07 +00:00
for ( l = 0 ; l < LINE_WIDTH ; l + + )
{
if ( txt [ l ] < = ' ' )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// word wrap
2012-11-28 15:47:07 +00:00
if ( l ! = LINE_WIDTH & & ( x + l > = LINE_WIDTH ) )
{
2012-11-26 18:58:24 +00:00
Linefeed ( ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
txt + + ;
2012-11-28 15:47:07 +00:00
switch ( c )
{
2012-11-26 18:58:24 +00:00
case ' \n ' :
2012-11-28 15:47:07 +00:00
Linefeed ( ) ;
2012-11-26 18:58:24 +00:00
break ;
case ' \t ' :
2012-11-28 15:47:07 +00:00
do
{
text [ y * LINE_WIDTH + x ] = ( color < < 8 ) | ' ' ;
2012-11-26 18:58:24 +00:00
x + + ;
2012-11-28 15:47:07 +00:00
if ( x > = LINE_WIDTH )
{
2012-11-26 18:58:24 +00:00
Linefeed ( ) ;
x = 0 ;
}
2012-11-28 15:47:07 +00:00
}
while ( x & 3 ) ;
2012-11-26 18:58:24 +00:00
break ;
case ' \r ' :
x = 0 ;
break ;
default : // display character and advance
2012-11-28 15:47:07 +00:00
text [ y * LINE_WIDTH + x ] = ( color < < 8 ) | c ;
2012-11-26 18:58:24 +00:00
x + + ;
2012-11-28 15:47:07 +00:00
if ( x > = LINE_WIDTH )
{
2012-11-26 18:58:24 +00:00
Linefeed ( ) ;
x = 0 ;
}
break ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// mark time for transparent overlay
2012-11-28 15:47:07 +00:00
if ( current > = 0 )
{
2012-11-26 18:58:24 +00:00
times [ current % NUM_CON_TIMES ] = Sys_Milliseconds ( ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
DRAWING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = =
DrawInput
Draw the editline after a ] prompt
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawInput ( )
{
2012-11-26 18:58:24 +00:00
int y , autoCompleteLength ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
y = vislines - ( SMALLCHAR_HEIGHT * 2 ) ;
2012-11-28 15:47:07 +00:00
if ( consoleField . GetAutoCompleteLength ( ) ! = 0 )
{
2012-11-26 18:58:24 +00:00
autoCompleteLength = strlen ( consoleField . GetBuffer ( ) ) - consoleField . GetAutoCompleteLength ( ) ;
2012-11-28 15:47:07 +00:00
if ( autoCompleteLength > 0 )
{
2012-11-26 18:58:24 +00:00
renderSystem - > DrawFilled ( idVec4 ( 0.8f , 0.2f , 0.2f , 0.45f ) ,
2012-11-28 15:47:07 +00:00
LOCALSAFE_LEFT + 2 * SMALLCHAR_WIDTH + consoleField . GetAutoCompleteLength ( ) * SMALLCHAR_WIDTH ,
y + 2 , autoCompleteLength * SMALLCHAR_WIDTH , SMALLCHAR_HEIGHT - 2 ) ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
renderSystem - > SetColor ( idStr : : ColorForIndex ( C_COLOR_CYAN ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
renderSystem - > DrawSmallChar ( LOCALSAFE_LEFT + 1 * SMALLCHAR_WIDTH , y , ' ] ' ) ;
2012-11-28 15:47:07 +00:00
2013-09-21 12:12:42 +00:00
consoleField . Draw ( LOCALSAFE_LEFT + 2 * SMALLCHAR_WIDTH , y , renderSystem - > GetVirtualWidth ( ) - 3 * SMALLCHAR_WIDTH , true ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = =
DrawNotify
Draws the last few lines of output transparently over the game top
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawNotify ( )
{
2012-11-26 18:58:24 +00:00
int x , v ;
2012-11-28 15:47:07 +00:00
short * text_p ;
2012-11-26 18:58:24 +00:00
int i ;
int time ;
int currentColor ;
2012-11-28 15:47:07 +00:00
if ( con_noPrint . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
currentColor = idStr : : ColorIndex ( C_COLOR_WHITE ) ;
renderSystem - > SetColor ( idStr : : ColorForIndex ( currentColor ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
v = 0 ;
2012-11-28 15:47:07 +00:00
for ( i = current - NUM_CON_TIMES + 1 ; i < = current ; i + + )
{
if ( i < 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
time = times [ i % NUM_CON_TIMES ] ;
2012-11-28 15:47:07 +00:00
if ( time = = 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
time = Sys_Milliseconds ( ) - time ;
2012-11-28 15:47:07 +00:00
if ( time > con_notifyTime . GetFloat ( ) * 1000 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
text_p = text + ( i % TOTAL_LINES ) * LINE_WIDTH ;
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
for ( x = 0 ; x < LINE_WIDTH ; x + + )
{
if ( ( text_p [ x ] & 0xff ) = = ' ' )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( idStr : : ColorIndex ( text_p [ x ] > > 8 ) ! = currentColor )
{
currentColor = idStr : : ColorIndex ( text_p [ x ] > > 8 ) ;
2012-11-26 18:58:24 +00:00
renderSystem - > SetColor ( idStr : : ColorForIndex ( currentColor ) ) ;
}
2012-11-28 15:47:07 +00:00
renderSystem - > DrawSmallChar ( LOCALSAFE_LEFT + ( x + 1 ) * SMALLCHAR_WIDTH , v , text_p [ x ] & 0xff ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
v + = SMALLCHAR_HEIGHT ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
renderSystem - > SetColor ( colorCyan ) ;
}
/*
= = = = = = = = = = = = = = = =
DrawSolidConsole
Draws the console with the solid background
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawSolidConsole ( float frac )
{
2012-11-26 18:58:24 +00:00
int i , x ;
float y ;
int rows ;
2012-11-28 15:47:07 +00:00
short * text_p ;
2012-11-26 18:58:24 +00:00
int row ;
int lines ;
int currentColor ;
2012-11-28 15:47:07 +00:00
2013-09-21 12:12:42 +00:00
lines = idMath : : Ftoi ( renderSystem - > GetVirtualHeight ( ) * frac ) ;
2012-11-28 15:47:07 +00:00
if ( lines < = 0 )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2013-09-21 12:12:42 +00:00
if ( lines > renderSystem - > GetVirtualHeight ( ) )
2012-11-28 15:47:07 +00:00
{
2013-09-21 12:12:42 +00:00
lines = renderSystem - > GetVirtualHeight ( ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// draw the background
2013-09-21 12:12:42 +00:00
y = frac * renderSystem - > GetVirtualHeight ( ) - 2 ;
2012-11-28 15:47:07 +00:00
if ( y < 1.0f )
{
2012-11-26 18:58:24 +00:00
y = 0.0f ;
2012-11-28 15:47:07 +00:00
}
else
{
2013-09-21 12:12:42 +00:00
renderSystem - > DrawFilled ( idVec4 ( 0.0f , 0.0f , 0.0f , 0.75f ) , 0 , 0 , renderSystem - > GetVirtualWidth ( ) , y ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2013-09-21 12:12:42 +00:00
renderSystem - > DrawFilled ( colorCyan , 0 , y , renderSystem - > GetVirtualWidth ( ) , 2 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// draw the version number
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
renderSystem - > SetColor ( idStr : : ColorForIndex ( C_COLOR_CYAN ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr version = va ( " %s.%i.%i " , ENGINE_VERSION , BUILD_NUMBER , BUILD_NUMBER_MINOR ) ;
i = version . Length ( ) ;
2012-11-28 15:47:07 +00:00
for ( x = 0 ; x < i ; x + + )
{
renderSystem - > DrawSmallChar ( LOCALSAFE_WIDTH - ( i - x ) * SMALLCHAR_WIDTH ,
( lines - ( SMALLCHAR_HEIGHT + SMALLCHAR_HEIGHT / 4 ) ) , version [ x ] ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// draw the text
vislines = lines ;
2012-11-28 15:47:07 +00:00
rows = ( lines - SMALLCHAR_WIDTH ) / SMALLCHAR_WIDTH ; // rows of text to draw
y = lines - ( SMALLCHAR_HEIGHT * 3 ) ;
2012-11-26 18:58:24 +00:00
// draw from the bottom up
2012-11-28 15:47:07 +00:00
if ( display ! = current )
{
2012-11-26 18:58:24 +00:00
// draw arrows to show the buffer is backscrolled
renderSystem - > SetColor ( idStr : : ColorForIndex ( C_COLOR_CYAN ) ) ;
2012-11-28 15:47:07 +00:00
for ( x = 0 ; x < LINE_WIDTH ; x + = 4 )
{
renderSystem - > DrawSmallChar ( LOCALSAFE_LEFT + ( x + 1 ) * SMALLCHAR_WIDTH , idMath : : Ftoi ( y ) , ' ^ ' ) ;
2012-11-26 18:58:24 +00:00
}
y - = SMALLCHAR_HEIGHT ;
rows - - ;
}
row = display ;
2012-11-28 15:47:07 +00:00
if ( x = = 0 )
{
2012-11-26 18:58:24 +00:00
row - - ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
currentColor = idStr : : ColorIndex ( C_COLOR_WHITE ) ;
renderSystem - > SetColor ( idStr : : ColorForIndex ( currentColor ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < rows ; i + + , y - = SMALLCHAR_HEIGHT , row - - )
{
if ( row < 0 )
{
2012-11-26 18:58:24 +00:00
break ;
}
2012-11-28 15:47:07 +00:00
if ( current - row > = TOTAL_LINES )
{
2012-11-26 18:58:24 +00:00
// past scrollback wrap point
2012-11-28 15:47:07 +00:00
continue ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
text_p = text + ( row % TOTAL_LINES ) * LINE_WIDTH ;
for ( x = 0 ; x < LINE_WIDTH ; x + + )
{
if ( ( text_p [ x ] & 0xff ) = = ' ' )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( idStr : : ColorIndex ( text_p [ x ] > > 8 ) ! = currentColor )
{
currentColor = idStr : : ColorIndex ( text_p [ x ] > > 8 ) ;
2012-11-26 18:58:24 +00:00
renderSystem - > SetColor ( idStr : : ColorForIndex ( currentColor ) ) ;
}
2012-11-28 15:47:07 +00:00
renderSystem - > DrawSmallChar ( LOCALSAFE_LEFT + ( x + 1 ) * SMALLCHAR_WIDTH , idMath : : Ftoi ( y ) , text_p [ x ] & 0xff ) ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// draw the input prompt, user text, and cursor if desired
DrawInput ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
renderSystem - > SetColor ( colorCyan ) ;
}
/*
= = = = = = = = = = = = = =
Draw
ForceFullScreen is used by the editor
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Draw ( bool forceFullScreen )
{
2013-09-21 12:12:42 +00:00
Resize ( ) ;
2012-11-28 15:47:07 +00:00
if ( forceFullScreen )
{
// if we are forced full screen because of a disconnect,
2012-11-26 18:58:24 +00:00
// we want the console closed when we go back to a session state
Close ( ) ;
// we are however catching keyboard input
keyCatching = true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Scroll ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
UpdateDisplayFraction ( ) ;
2012-11-28 15:47:07 +00:00
if ( forceFullScreen )
{
2012-11-26 18:58:24 +00:00
DrawSolidConsole ( 1.0f ) ;
2012-11-28 15:47:07 +00:00
}
else if ( displayFrac )
{
2012-11-26 18:58:24 +00:00
DrawSolidConsole ( displayFrac ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// only draw the notify lines if the developer cvar is set,
// or we are a debug build
2012-11-28 15:47:07 +00:00
if ( ! con_noPrint . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
DrawNotify ( ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
float lefty = LOCALSAFE_TOP ;
float righty = LOCALSAFE_TOP ;
float centery = LOCALSAFE_TOP ;
2012-11-28 15:47:07 +00:00
if ( com_showFPS . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
righty = DrawFPS ( righty ) ;
}
2012-11-28 15:47:07 +00:00
if ( com_showMemoryUsage . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
righty = DrawMemoryUsage ( righty ) ;
}
DrawOverlayText ( lefty , righty , centery ) ;
DrawDebugGraphs ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
2012-11-28 15:47:07 +00:00
idConsoleLocal : : PrintOverlay
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : PrintOverlay ( idOverlayHandle & handle , justify_t justify , const char * text , . . . )
{
if ( handle . index > = 0 & & handle . index < overlayText . Num ( ) )
{
if ( overlayText [ handle . index ] . time = = handle . time )
{
2012-11-26 18:58:24 +00:00
return ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
char string [ MAX_PRINT_MSG ] ;
va_list argptr ;
va_start ( argptr , text ) ;
idStr : : vsnPrintf ( string , sizeof ( string ) , text , argptr ) ;
va_end ( argptr ) ;
2012-11-28 15:47:07 +00:00
overlayText_t & overlay = overlayText . Alloc ( ) ;
2012-11-26 18:58:24 +00:00
overlay . text = string ;
overlay . justify = justify ;
overlay . time = Sys_Milliseconds ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
handle . index = overlayText . Num ( ) - 1 ;
handle . time = overlay . time ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idConsoleLocal : : DrawOverlayText
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawOverlayText ( float & leftY , float & rightY , float & centerY )
{
for ( int i = 0 ; i < overlayText . Num ( ) ; i + + )
{
const idStr & text = overlayText [ i ] . text ;
2012-11-26 18:58:24 +00:00
int maxWidth = 0 ;
int numLines = 0 ;
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < text . Length ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
int width = 1 ;
2012-11-28 15:47:07 +00:00
for ( ; j < text . Length ( ) & & text [ j ] ! = ' \n ' ; j + + )
{
2012-11-26 18:58:24 +00:00
width + + ;
}
numLines + + ;
2012-11-28 15:47:07 +00:00
if ( width > maxWidth )
{
2012-11-26 18:58:24 +00:00
maxWidth = width ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idVec4 bgColor ( 0.0f , 0.0f , 0.0f , 0.75f ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
const float width = maxWidth * SMALLCHAR_WIDTH ;
const float height = numLines * ( SMALLCHAR_HEIGHT + 4 ) ;
const float bgAdjust = - 0.5f * SMALLCHAR_WIDTH ;
2012-11-28 15:47:07 +00:00
if ( overlayText [ i ] . justify = = JUSTIFY_LEFT )
{
2012-11-26 18:58:24 +00:00
renderSystem - > DrawFilled ( bgColor , LOCALSAFE_LEFT + bgAdjust , leftY , width , height ) ;
2012-11-28 15:47:07 +00:00
}
else if ( overlayText [ i ] . justify = = JUSTIFY_RIGHT )
{
2012-11-26 18:58:24 +00:00
renderSystem - > DrawFilled ( bgColor , LOCALSAFE_RIGHT - width + bgAdjust , rightY , width , height ) ;
2012-11-28 15:47:07 +00:00
}
else if ( overlayText [ i ] . justify = = JUSTIFY_CENTER_LEFT | | overlayText [ i ] . justify = = JUSTIFY_CENTER_RIGHT )
{
2012-11-26 18:58:24 +00:00
renderSystem - > DrawFilled ( bgColor , LOCALSAFE_LEFT + ( LOCALSAFE_WIDTH - width + bgAdjust ) * 0.5f , centerY , width , height ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
assert ( false ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr singleLine ;
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < text . Length ( ) ; j + = singleLine . Length ( ) + 1 )
{
2012-11-26 18:58:24 +00:00
singleLine = " " ;
2012-11-28 15:47:07 +00:00
for ( int k = j ; k < text . Length ( ) & & text [ k ] ! = ' \n ' ; k + + )
{
2012-11-26 18:58:24 +00:00
singleLine . Append ( text [ k ] ) ;
}
2012-11-28 15:47:07 +00:00
if ( overlayText [ i ] . justify = = JUSTIFY_LEFT )
{
2012-11-26 18:58:24 +00:00
DrawTextLeftAlign ( LOCALSAFE_LEFT , leftY , " %s " , singleLine . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else if ( overlayText [ i ] . justify = = JUSTIFY_RIGHT )
{
2012-11-26 18:58:24 +00:00
DrawTextRightAlign ( LOCALSAFE_RIGHT , rightY , " %s " , singleLine . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else if ( overlayText [ i ] . justify = = JUSTIFY_CENTER_LEFT )
{
2012-11-26 18:58:24 +00:00
DrawTextLeftAlign ( LOCALSAFE_LEFT + ( LOCALSAFE_WIDTH - width ) * 0.5f , centerY , " %s " , singleLine . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else if ( overlayText [ i ] . justify = = JUSTIFY_CENTER_RIGHT )
{
2012-11-26 18:58:24 +00:00
DrawTextRightAlign ( LOCALSAFE_LEFT + ( LOCALSAFE_WIDTH + width ) * 0.5f , centerY , " %s " , singleLine . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
assert ( false ) ;
}
}
}
overlayText . SetNum ( 0 ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idConsoleLocal : : CreateGraph
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idDebugGraph * idConsoleLocal : : CreateGraph ( int numItems )
{
idDebugGraph * graph = new ( TAG_SYSTEM ) idDebugGraph ( numItems ) ;
2012-11-26 18:58:24 +00:00
debugGraphs . Append ( graph ) ;
return graph ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idConsoleLocal : : DestroyGraph
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DestroyGraph ( idDebugGraph * graph )
{
2012-11-26 18:58:24 +00:00
debugGraphs . Remove ( graph ) ;
delete graph ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
2012-11-28 15:47:07 +00:00
idConsoleLocal : : DrawDebugGraphs
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawDebugGraphs ( )
{
for ( int i = 0 ; i < debugGraphs . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
debugGraphs [ i ] - > Render ( renderSystem ) ;
}
2012-12-21 03:52:56 +00:00
}