12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187 |
- /*
- ===========================================================================
- Doom 3 GPL Source Code
- Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
- Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 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 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.
- ===========================================================================
- */
- #include "../idlib/precompiled.h"
- #pragma hdrstop
- void SCR_DrawTextLeftAlign( float &y, const char *text, ... ) id_attribute((format(printf,2,3)));
- void SCR_DrawTextRightAlign( float &y, const char *text, ... ) id_attribute((format(printf,2,3)));
- #define LINE_WIDTH 78
- #define NUM_CON_TIMES 4
- #define CON_TEXTSIZE 0x30000
- #define TOTAL_LINES (CON_TEXTSIZE / LINE_WIDTH)
- #define CONSOLE_FIRSTREPEAT 200
- #define CONSOLE_REPEAT 100
- #define COMMAND_HISTORY 64
- // the console will query the cvar and command systems for
- // command completion information
- class idConsoleLocal : public idConsole {
- public:
- virtual void Init( void );
- virtual void Shutdown( void );
- virtual void LoadGraphics( void );
- virtual bool ProcessEvent( const sysEvent_t *event, bool forceAccept );
- virtual bool Active( void );
- virtual void ClearNotifyLines( void );
- virtual void Close( void );
- virtual void Print( const char *text );
- virtual void Draw( bool forceFullScreen );
- void Dump( const char *toFile );
- void Clear();
- //============================
- const idMaterial * charSetShader;
- private:
- void KeyDownEvent( int key );
- void Linefeed();
- void PageUp();
- void PageDown();
- void Top();
- void Bottom();
- void DrawInput();
- void DrawNotify();
- void DrawSolidConsole( float frac );
- void Scroll();
- void SetDisplayFraction( float frac );
- void UpdateDisplayFraction( void );
- //============================
- bool keyCatching;
- 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
- float displayFrac; // approaches finalFrac at scr_conspeed
- float finalFrac; // 0.0 to 1.0 lines of console to display
- int fracTime; // time of last displayFrac update
- int vislines; // in scanlines
- int times[NUM_CON_TIMES]; // cls.realtime time the line was generated
- // for transparent notify lines
- idVec4 color;
- idEditField historyEditLines[COMMAND_HISTORY];
- int nextHistoryLine;// the last line in the history buffer, not masked
- int historyLine; // the line being displayed from history buffer
- // will be <= nextHistoryLine
- idEditField consoleField;
- static idCVar con_speed;
- static idCVar con_notifyTime;
- static idCVar con_noPrint;
- const idMaterial * whiteShader;
- const idMaterial * consoleShader;
- };
- static idConsoleLocal localConsole;
- idConsole *console = &localConsole;
- 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
- 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" );
- #else
- 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" );
- #endif
- /*
- =============================================================================
- Misc stats
- =============================================================================
- */
- /*
- ==================
- SCR_DrawTextLeftAlign
- ==================
- */
- void SCR_DrawTextLeftAlign( float &y, const char *text, ... ) {
- char string[MAX_STRING_CHARS];
- va_list argptr;
- va_start( argptr, text );
- idStr::vsnPrintf( string, sizeof( string ), text, argptr );
- va_end( argptr );
- renderSystem->DrawSmallStringExt( 0, y + 2, string, colorWhite, true, localConsole.charSetShader );
- y += SMALLCHAR_HEIGHT + 4;
- }
- /*
- ==================
- SCR_DrawTextRightAlign
- ==================
- */
- void SCR_DrawTextRightAlign( float &y, const char *text, ... ) {
- 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( 635 - i * SMALLCHAR_WIDTH, y + 2, string, colorWhite, true, localConsole.charSetShader );
- y += SMALLCHAR_HEIGHT + 4;
- }
- /*
- ==================
- SCR_DrawFPS
- ==================
- */
- #define FPS_FRAMES 4
- float SCR_DrawFPS( float y ) {
- char *s;
- int w;
- static int previousTimes[FPS_FRAMES];
- static int index;
- int i, total;
- int fps;
- static int previous;
- int t, frameTime;
- // don't use serverTime, because that will be drifting to
- // correct for internet lag changes, timescales, timedemos, etc
- t = Sys_Milliseconds();
- frameTime = t - previous;
- previous = t;
- previousTimes[index % FPS_FRAMES] = frameTime;
- index++;
- if ( index > FPS_FRAMES ) {
- // average multiple frames together to smooth changes out a bit
- total = 0;
- for ( i = 0 ; i < FPS_FRAMES ; i++ ) {
- total += previousTimes[i];
- }
- if ( !total ) {
- total = 1;
- }
- fps = 10000 * FPS_FRAMES / total;
- fps = (fps + 5)/10;
- s = va( "%ifps", fps );
- w = strlen( s ) * BIGCHAR_WIDTH;
- renderSystem->DrawBigStringExt( 635 - w, idMath::FtoiFast( y ) + 2, s, colorWhite, true, localConsole.charSetShader);
- }
- return y + BIGCHAR_HEIGHT + 4;
- }
- /*
- ==================
- SCR_DrawMemoryUsage
- ==================
- */
- float SCR_DrawMemoryUsage( float y ) {
- memoryStats_t allocs, frees;
-
- Mem_GetStats( allocs );
- SCR_DrawTextRightAlign( y, "total allocated memory: %4d, %4dkB", allocs.num, allocs.totalSize>>10 );
- Mem_GetFrameStats( allocs, frees );
- SCR_DrawTextRightAlign( y, "frame alloc: %4d, %4dkB frame free: %4d, %4dkB", allocs.num, allocs.totalSize>>10, frees.num, frees.totalSize>>10 );
- Mem_ClearFrameStats();
- return y;
- }
- /*
- ==================
- SCR_DrawAsyncStats
- ==================
- */
- float SCR_DrawAsyncStats( float y ) {
- int i, outgoingRate, incomingRate;
- float outgoingCompression, incomingCompression;
- if ( idAsyncNetwork::server.IsActive() ) {
- SCR_DrawTextRightAlign( y, "server delay = %d msec", idAsyncNetwork::server.GetDelay() );
- SCR_DrawTextRightAlign( y, "total outgoing rate = %d KB/s", idAsyncNetwork::server.GetOutgoingRate() >> 10 );
- SCR_DrawTextRightAlign( y, "total incoming rate = %d KB/s", idAsyncNetwork::server.GetIncomingRate() >> 10 );
- for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) {
- outgoingRate = idAsyncNetwork::server.GetClientOutgoingRate( i );
- incomingRate = idAsyncNetwork::server.GetClientIncomingRate( i );
- outgoingCompression = idAsyncNetwork::server.GetClientOutgoingCompression( i );
- incomingCompression = idAsyncNetwork::server.GetClientIncomingCompression( i );
- if ( outgoingRate != -1 && incomingRate != -1 ) {
- SCR_DrawTextRightAlign( y, "client %d: out rate = %d B/s (% -2.1f%%), in rate = %d B/s (% -2.1f%%)",
- i, outgoingRate, outgoingCompression, incomingRate, incomingCompression );
- }
- }
- idStr msg;
- idAsyncNetwork::server.GetAsyncStatsAvgMsg( msg );
- SCR_DrawTextRightAlign( y, msg.c_str() );
- } else if ( idAsyncNetwork::client.IsActive() ) {
- outgoingRate = idAsyncNetwork::client.GetOutgoingRate();
- incomingRate = idAsyncNetwork::client.GetIncomingRate();
- outgoingCompression = idAsyncNetwork::client.GetOutgoingCompression();
- incomingCompression = idAsyncNetwork::client.GetIncomingCompression();
- if ( outgoingRate != -1 && incomingRate != -1 ) {
- SCR_DrawTextRightAlign( y, "out rate = %d B/s (% -2.1f%%), in rate = %d B/s (% -2.1f%%)",
- outgoingRate, outgoingCompression, incomingRate, incomingCompression );
- }
- SCR_DrawTextRightAlign( y, "packet loss = %d%%, client prediction = %d",
- (int)idAsyncNetwork::client.GetIncomingPacketLoss(), idAsyncNetwork::client.GetPrediction() );
- SCR_DrawTextRightAlign( y, "predicted frames: %d", idAsyncNetwork::client.GetPredictedFrames() );
- }
- return y;
- }
- /*
- ==================
- SCR_DrawSoundDecoders
- ==================
- */
- float SCR_DrawSoundDecoders( float y ) {
- int index, numActiveDecoders;
- soundDecoderInfo_t decoderInfo;
- index = -1;
- numActiveDecoders = 0;
- while( ( index = soundSystem->GetSoundDecoderInfo( index, decoderInfo ) ) != -1 ) {
- int localTime = decoderInfo.current44kHzTime - decoderInfo.start44kHzTime;
- int sampleTime = decoderInfo.num44kHzSamples / decoderInfo.numChannels;
- int percent;
- if ( localTime > sampleTime ) {
- if ( decoderInfo.looping ) {
- percent = ( localTime % sampleTime ) * 100 / sampleTime;
- } else {
- percent = 100;
- }
- } else {
- percent = localTime * 100 / sampleTime;
- }
- SCR_DrawTextLeftAlign( y, "%3d: %3d%% (%1.2f) %s: %s (%dkB)", numActiveDecoders, percent, decoderInfo.lastVolume, decoderInfo.format.c_str(), decoderInfo.name.c_str(), decoderInfo.numBytes >> 10 );
- numActiveDecoders++;
- }
- return y;
- }
- //=========================================================================
- /*
- ==============
- Con_Clear_f
- ==============
- */
- static void Con_Clear_f( const idCmdArgs &args ) {
- localConsole.Clear();
- }
- /*
- ==============
- Con_Dump_f
- ==============
- */
- static void Con_Dump_f( const idCmdArgs &args ) {
- if ( args.Argc() != 2 ) {
- common->Printf( "usage: conDump <filename>\n" );
- return;
- }
- idStr fileName = args.Argv(1);
- fileName.DefaultFileExtension(".txt");
- common->Printf( "Dumped console text to %s.\n", fileName.c_str() );
- localConsole.Dump( fileName.c_str() );
- }
- /*
- ==============
- idConsoleLocal::Init
- ==============
- */
- void idConsoleLocal::Init( void ) {
- int i;
- keyCatching = false;
- lastKeyEvent = -1;
- nextKeyEvent = CONSOLE_FIRSTREPEAT;
- consoleField.Clear();
- consoleField.SetWidthInChars( LINE_WIDTH );
- for ( i = 0 ; i < COMMAND_HISTORY ; i++ ) {
- historyEditLines[i].Clear();
- historyEditLines[i].SetWidthInChars( LINE_WIDTH );
- }
- 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
- ==============
- */
- void idConsoleLocal::Shutdown( void ) {
- cmdSystem->RemoveCommand( "clear" );
- cmdSystem->RemoveCommand( "conDump" );
- }
- /*
- ==============
- LoadGraphics
- Can't be combined with init, because init happens before
- the renderSystem is initialized
- ==============
- */
- void idConsoleLocal::LoadGraphics() {
- charSetShader = declManager->FindMaterial( "textures/bigchars" );
- whiteShader = declManager->FindMaterial( "_white" );
- consoleShader = declManager->FindMaterial( "console" );
- }
- /*
- ================
- idConsoleLocal::Active
- ================
- */
- bool idConsoleLocal::Active( void ) {
- return keyCatching;
- }
- /*
- ================
- idConsoleLocal::ClearNotifyLines
- ================
- */
- void idConsoleLocal::ClearNotifyLines() {
- int i;
- for ( i = 0 ; i < NUM_CON_TIMES ; i++ ) {
- times[i] = 0;
- }
- }
- /*
- ================
- idConsoleLocal::Close
- ================
- */
- void idConsoleLocal::Close() {
- keyCatching = false;
- SetDisplayFraction( 0 );
- displayFrac = 0; // don't scroll to that point, go immediately
- ClearNotifyLines();
- }
- /*
- ================
- idConsoleLocal::Clear
- ================
- */
- void idConsoleLocal::Clear() {
- int i;
- for ( i = 0 ; i < CON_TEXTSIZE ; i++ ) {
- text[i] = (idStr::ColorIndex(C_COLOR_CYAN)<<8) | ' ';
- }
- Bottom(); // go to end
- }
- /*
- ================
- idConsoleLocal::Dump
- Save the console contents out to a file
- ================
- */
- void idConsoleLocal::Dump( const char *fileName ) {
- int l, x, i;
- short * line;
- idFile *f;
- char buffer[LINE_WIDTH + 3];
- f = fileSystem->OpenFileWrite( fileName );
- if ( !f ) {
- common->Warning( "couldn't open %s", fileName );
- return;
- }
- // skip empty lines
- l = current - TOTAL_LINES + 1;
- if ( l < 0 ) {
- l = 0;
- }
- for ( ; l <= current ; l++ )
- {
- line = text + ( l % TOTAL_LINES ) * LINE_WIDTH;
- for ( x = 0; x < LINE_WIDTH; x++ )
- if ( ( line[x] & 0xff ) > ' ' )
- break;
- if ( x != LINE_WIDTH )
- break;
- }
- // write the remaining lines
- for ( ; l <= current; l++ ) {
- line = text + ( l % TOTAL_LINES ) * LINE_WIDTH;
- for( i = 0; i < LINE_WIDTH; i++ ) {
- buffer[i] = line[i] & 0xff;
- }
- for ( x = LINE_WIDTH-1; x >= 0; x-- ) {
- if ( buffer[x] <= ' ' ) {
- buffer[x] = 0;
- } else {
- break;
- }
- }
- buffer[x+1] = '\r';
- buffer[x+2] = '\n';
- buffer[x+3] = 0;
- f->Write( buffer, strlen( buffer ) );
- }
- fileSystem->CloseFile( f );
- }
- /*
- ================
- idConsoleLocal::PageUp
- ================
- */
- void idConsoleLocal::PageUp( void ) {
- display -= 2;
- if ( current - display >= TOTAL_LINES ) {
- display = current - TOTAL_LINES + 1;
- }
- }
- /*
- ================
- idConsoleLocal::PageDown
- ================
- */
- void idConsoleLocal::PageDown( void ) {
- display += 2;
- if ( display > current ) {
- display = current;
- }
- }
- /*
- ================
- idConsoleLocal::Top
- ================
- */
- void idConsoleLocal::Top( void ) {
- display = 0;
- }
- /*
- ================
- idConsoleLocal::Bottom
- ================
- */
- void idConsoleLocal::Bottom( void ) {
- display = current;
- }
- /*
- =============================================================================
- CONSOLE LINE EDITING
- ==============================================================================
- */
- /*
- ====================
- KeyDownEvent
- Handles history and console scrollback
- ====================
- */
- void idConsoleLocal::KeyDownEvent( int key ) {
-
- // Execute F key bindings
- if ( key >= K_F1 && key <= K_F12 ) {
- idKeyInput::ExecKeyBinding( key );
- return;
- }
- // ctrl-L clears screen
- if ( key == 'l' && idKeyInput::IsDown( K_CTRL ) ) {
- Clear();
- return;
- }
- // enter finishes the line
- if ( key == K_ENTER || key == K_KP_ENTER ) {
- common->Printf ( "]%s\n", consoleField.GetBuffer() );
- cmdSystem->BufferCommandText( CMD_EXEC_APPEND, consoleField.GetBuffer() ); // valid command
- cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "\n" );
- // copy line to history buffer
- historyEditLines[nextHistoryLine % COMMAND_HISTORY] = consoleField;
- nextHistoryLine++;
- historyLine = nextHistoryLine;
- consoleField.Clear();
- consoleField.SetWidthInChars( LINE_WIDTH );
- session->UpdateScreen();// force an update, because the command
- // may take some time
- return;
- }
- // command completion
- if ( key == K_TAB ) {
- consoleField.AutoComplete();
- return;
- }
- // command history (ctrl-p ctrl-n for unix style)
- if ( ( key == K_UPARROW ) ||
- ( ( tolower(key) == 'p' ) && idKeyInput::IsDown( K_CTRL ) ) ) {
- if ( nextHistoryLine - historyLine < COMMAND_HISTORY && historyLine > 0 ) {
- historyLine--;
- }
- consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ];
- return;
- }
- if ( ( key == K_DOWNARROW ) ||
- ( ( tolower( key ) == 'n' ) && idKeyInput::IsDown( K_CTRL ) ) ) {
- if ( historyLine == nextHistoryLine ) {
- return;
- }
- historyLine++;
- consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ];
- return;
- }
- // console scrolling
- if ( key == K_PGUP ) {
- PageUp();
- lastKeyEvent = eventLoop->Milliseconds();
- nextKeyEvent = CONSOLE_FIRSTREPEAT;
- return;
- }
- if ( key == K_PGDN ) {
- PageDown();
- lastKeyEvent = eventLoop->Milliseconds();
- nextKeyEvent = CONSOLE_FIRSTREPEAT;
- return;
- }
- if ( key == K_MWHEELUP ) {
- PageUp();
- return;
- }
- if ( key == K_MWHEELDOWN ) {
- PageDown();
- return;
- }
- // ctrl-home = top of console
- if ( key == K_HOME && idKeyInput::IsDown( K_CTRL ) ) {
- Top();
- return;
- }
- // ctrl-end = bottom of console
- if ( key == K_END && idKeyInput::IsDown( K_CTRL ) ) {
- Bottom();
- return;
- }
- // pass to the normal editline routine
- consoleField.KeyDownEvent( key );
- }
- /*
- ==============
- Scroll
- deals with scrolling text because we don't have key repeat
- ==============
- */
- void idConsoleLocal::Scroll( ) {
- if (lastKeyEvent == -1 || (lastKeyEvent+200) > eventLoop->Milliseconds()) {
- return;
- }
- // console scrolling
- if ( idKeyInput::IsDown( K_PGUP ) ) {
- PageUp();
- nextKeyEvent = CONSOLE_REPEAT;
- return;
- }
- if ( idKeyInput::IsDown( K_PGDN ) ) {
- PageDown();
- nextKeyEvent = CONSOLE_REPEAT;
- return;
- }
- }
- /*
- ==============
- SetDisplayFraction
- Causes the console to start opening the desired amount.
- ==============
- */
- void idConsoleLocal::SetDisplayFraction( float frac ) {
- finalFrac = frac;
- fracTime = com_frameTime;
- }
- /*
- ==============
- UpdateDisplayFraction
- Scrolls the console up or down based on conspeed
- ==============
- */
- void idConsoleLocal::UpdateDisplayFraction( void ) {
- if ( con_speed.GetFloat() <= 0.1f ) {
- fracTime = com_frameTime;
- displayFrac = finalFrac;
- return;
- }
- // scroll towards the destination height
- if ( finalFrac < displayFrac ) {
- displayFrac -= con_speed.GetFloat() * ( com_frameTime - fracTime ) * 0.001f;
- if ( finalFrac > displayFrac ) {
- displayFrac = finalFrac;
- }
- fracTime = com_frameTime;
- } else if ( finalFrac > displayFrac ) {
- displayFrac += con_speed.GetFloat() * ( com_frameTime - fracTime ) * 0.001f;
- if ( finalFrac < displayFrac ) {
- displayFrac = finalFrac;
- }
- fracTime = com_frameTime;
- }
- }
- /*
- ==============
- ProcessEvent
- ==============
- */
- bool idConsoleLocal::ProcessEvent( const sysEvent_t *event, bool forceAccept ) {
- bool consoleKey;
- consoleKey = event->evType == SE_KEY && ( event->evValue == Sys_GetConsoleKey( false ) || event->evValue == Sys_GetConsoleKey( true ) );
- #if ID_CONSOLE_LOCK
- // If the console's not already down, and we have it turned off, check for ctrl+alt
- if ( !keyCatching && !com_allowConsole.GetBool() ) {
- if ( !idKeyInput::IsDown( K_CTRL ) || !idKeyInput::IsDown( K_ALT ) ) {
- consoleKey = false;
- }
- }
- #endif
- // we always catch the console key event
- if ( !forceAccept && consoleKey ) {
- // ignore up events
- if ( event->evValue2 == 0 ) {
- return true;
- }
- consoleField.ClearAutoComplete();
- // a down event will toggle the destination lines
- if ( keyCatching ) {
- Close();
- Sys_GrabMouseCursor( true );
- cvarSystem->SetCVarBool( "ui_chat", false );
- } else {
- consoleField.Clear();
- keyCatching = true;
- if ( idKeyInput::IsDown( K_SHIFT ) ) {
- // if the shift key is down, don't open the console as much
- SetDisplayFraction( 0.2f );
- } else {
- SetDisplayFraction( 0.5f );
- }
- cvarSystem->SetCVarBool( "ui_chat", true );
- }
- return true;
- }
- // if we aren't key catching, dump all the other events
- if ( !forceAccept && !keyCatching ) {
- return false;
- }
- // handle key and character events
- if ( event->evType == SE_CHAR ) {
- // never send the console key as a character
- if ( event->evValue != Sys_GetConsoleKey( false ) && event->evValue != Sys_GetConsoleKey( true ) ) {
- consoleField.CharEvent( event->evValue );
- }
- return true;
- }
- if ( event->evType == SE_KEY ) {
- // ignore up key events
- if ( event->evValue2 == 0 ) {
- return true;
- }
- KeyDownEvent( event->evValue );
- return true;
- }
- // we don't handle things like mouse, joystick, and network packets
- return false;
- }
- /*
- ==============================================================================
- PRINTING
- ==============================================================================
- */
- /*
- ===============
- Linefeed
- ===============
- */
- void idConsoleLocal::Linefeed() {
- int i;
- // mark time for transparent overlay
- if ( current >= 0 ) {
- times[current % NUM_CON_TIMES] = com_frameTime;
- }
- x = 0;
- if ( display == current ) {
- display++;
- }
- current++;
- for ( i = 0; i < LINE_WIDTH; i++ ) {
- text[(current%TOTAL_LINES)*LINE_WIDTH+i] = (idStr::ColorIndex(C_COLOR_CYAN)<<8) | ' ';
- }
- }
- /*
- ================
- Print
- Handles cursor positioning, line wrapping, etc
- ================
- */
- void idConsoleLocal::Print( const char *txt ) {
- int y;
- int c, l;
- int color;
- #ifdef ID_ALLOW_TOOLS
- RadiantPrint( txt );
- if( com_editors & EDITOR_MATERIAL ) {
- MaterialEditorPrintConsole(txt);
- }
- #endif
- color = idStr::ColorIndex( C_COLOR_CYAN );
- while ( (c = *(const unsigned char*)txt) != 0 ) {
- if ( idStr::IsColor( txt ) ) {
- if ( *(txt+1) == C_COLOR_DEFAULT ) {
- color = idStr::ColorIndex( C_COLOR_CYAN );
- } else {
- color = idStr::ColorIndex( *(txt+1) );
- }
- txt += 2;
- continue;
- }
- y = current % TOTAL_LINES;
- // if we are about to print a new word, check to see
- // if we should wrap to the new line
- if ( c > ' ' && ( x == 0 || text[y*LINE_WIDTH+x-1] <= ' ' ) ) {
- // count word length
- for (l=0 ; l< LINE_WIDTH ; l++) {
- if ( txt[l] <= ' ') {
- break;
- }
- }
- // word wrap
- if (l != LINE_WIDTH && (x + l >= LINE_WIDTH) ) {
- Linefeed();
- }
- }
- txt++;
- switch( c ) {
- case '\n':
- Linefeed ();
- break;
- case '\t':
- do {
- text[y*LINE_WIDTH+x] = (color << 8) | ' ';
- x++;
- if ( x >= LINE_WIDTH ) {
- Linefeed();
- x = 0;
- }
- } while ( x & 3 );
- break;
- case '\r':
- x = 0;
- break;
- default: // display character and advance
- text[y*LINE_WIDTH+x] = (color << 8) | c;
- x++;
- if ( x >= LINE_WIDTH ) {
- Linefeed();
- x = 0;
- }
- break;
- }
- }
- // mark time for transparent overlay
- if ( current >= 0 ) {
- times[current % NUM_CON_TIMES] = com_frameTime;
- }
- }
- /*
- ==============================================================================
- DRAWING
- ==============================================================================
- */
- /*
- ================
- DrawInput
- Draw the editline after a ] prompt
- ================
- */
- void idConsoleLocal::DrawInput() {
- int y, autoCompleteLength;
- y = vislines - ( SMALLCHAR_HEIGHT * 2 );
- if ( consoleField.GetAutoCompleteLength() != 0 ) {
- autoCompleteLength = strlen( consoleField.GetBuffer() ) - consoleField.GetAutoCompleteLength();
- if ( autoCompleteLength > 0 ) {
- renderSystem->SetColor4( .8f, .2f, .2f, .45f );
- renderSystem->DrawStretchPic( 2 * SMALLCHAR_WIDTH + consoleField.GetAutoCompleteLength() * SMALLCHAR_WIDTH,
- y + 2, autoCompleteLength * SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT - 2, 0, 0, 0, 0, whiteShader );
- }
- }
- renderSystem->SetColor( idStr::ColorForIndex( C_COLOR_CYAN ) );
- renderSystem->DrawSmallChar( 1 * SMALLCHAR_WIDTH, y, ']', localConsole.charSetShader );
- consoleField.Draw(2 * SMALLCHAR_WIDTH, y, SCREEN_WIDTH - 3 * SMALLCHAR_WIDTH, true, charSetShader );
- }
- /*
- ================
- DrawNotify
- Draws the last few lines of output transparently over the game top
- ================
- */
- void idConsoleLocal::DrawNotify() {
- int x, v;
- short *text_p;
- int i;
- int time;
- int currentColor;
- if ( con_noPrint.GetBool() ) {
- return;
- }
- currentColor = idStr::ColorIndex( C_COLOR_WHITE );
- renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
- v = 0;
- for ( i = current-NUM_CON_TIMES+1; i <= current; i++ ) {
- if ( i < 0 ) {
- continue;
- }
- time = times[i % NUM_CON_TIMES];
- if ( time == 0 ) {
- continue;
- }
- time = com_frameTime - time;
- if ( time > con_notifyTime.GetFloat() * 1000 ) {
- continue;
- }
- text_p = text + (i % TOTAL_LINES)*LINE_WIDTH;
-
- for ( x = 0; x < LINE_WIDTH; x++ ) {
- if ( ( text_p[x] & 0xff ) == ' ' ) {
- continue;
- }
- if ( idStr::ColorIndex(text_p[x]>>8) != currentColor ) {
- currentColor = idStr::ColorIndex(text_p[x]>>8);
- renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
- }
- renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, v, text_p[x] & 0xff, localConsole.charSetShader );
- }
- v += SMALLCHAR_HEIGHT;
- }
- renderSystem->SetColor( colorCyan );
- }
- /*
- ================
- DrawSolidConsole
- Draws the console with the solid background
- ================
- */
- void idConsoleLocal::DrawSolidConsole( float frac ) {
- int i, x;
- float y;
- int rows;
- short *text_p;
- int row;
- int lines;
- int currentColor;
- lines = idMath::FtoiFast( SCREEN_HEIGHT * frac );
- if ( lines <= 0 ) {
- return;
- }
- if ( lines > SCREEN_HEIGHT ) {
- lines = SCREEN_HEIGHT;
- }
- // draw the background
- y = frac * SCREEN_HEIGHT - 2;
- if ( y < 1.0f ) {
- y = 0.0f;
- } else {
- renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, y, 0, 1.0f - displayFrac, 1, 1, consoleShader );
- }
- renderSystem->SetColor( colorCyan );
- renderSystem->DrawStretchPic( 0, y, SCREEN_WIDTH, 2, 0, 0, 0, 0, whiteShader );
- renderSystem->SetColor( colorWhite );
- // draw the version number
- renderSystem->SetColor( idStr::ColorForIndex( C_COLOR_CYAN ) );
- idStr version = va("%s.%i", ENGINE_VERSION, BUILD_NUMBER);
- i = version.Length();
- for ( x = 0; x < i; x++ ) {
- renderSystem->DrawSmallChar( SCREEN_WIDTH - ( i - x ) * SMALLCHAR_WIDTH,
- (lines-(SMALLCHAR_HEIGHT+SMALLCHAR_HEIGHT/2)), version[x], localConsole.charSetShader );
- }
- // draw the text
- vislines = lines;
- rows = (lines-SMALLCHAR_WIDTH)/SMALLCHAR_WIDTH; // rows of text to draw
- y = lines - (SMALLCHAR_HEIGHT*3);
- // draw from the bottom up
- if ( display != current ) {
- // draw arrows to show the buffer is backscrolled
- renderSystem->SetColor( idStr::ColorForIndex( C_COLOR_CYAN ) );
- for ( x = 0; x < LINE_WIDTH; x += 4 ) {
- renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, idMath::FtoiFast( y ), '^', localConsole.charSetShader );
- }
- y -= SMALLCHAR_HEIGHT;
- rows--;
- }
-
- row = display;
- if ( x == 0 ) {
- row--;
- }
- currentColor = idStr::ColorIndex( C_COLOR_WHITE );
- renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
- for ( i = 0; i < rows; i++, y -= SMALLCHAR_HEIGHT, row-- ) {
- if ( row < 0 ) {
- break;
- }
- if ( current - row >= TOTAL_LINES ) {
- // past scrollback wrap point
- continue;
- }
- text_p = text + (row % TOTAL_LINES)*LINE_WIDTH;
- for ( x = 0; x < LINE_WIDTH; x++ ) {
- if ( ( text_p[x] & 0xff ) == ' ' ) {
- continue;
- }
- if ( idStr::ColorIndex(text_p[x]>>8) != currentColor ) {
- currentColor = idStr::ColorIndex(text_p[x]>>8);
- renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
- }
- renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, idMath::FtoiFast( y ), text_p[x] & 0xff, localConsole.charSetShader );
- }
- }
- // draw the input prompt, user text, and cursor if desired
- DrawInput();
- renderSystem->SetColor( colorCyan );
- }
- /*
- ==============
- Draw
- ForceFullScreen is used by the editor
- ==============
- */
- void idConsoleLocal::Draw( bool forceFullScreen ) {
- float y = 0.0f;
- if ( !charSetShader ) {
- return;
- }
- if ( forceFullScreen ) {
- // if we are forced full screen because of a disconnect,
- // we want the console closed when we go back to a session state
- Close();
- // we are however catching keyboard input
- keyCatching = true;
- }
- Scroll();
- UpdateDisplayFraction();
- if ( forceFullScreen ) {
- DrawSolidConsole( 1.0f );
- } else if ( displayFrac ) {
- DrawSolidConsole( displayFrac );
- } else {
- // only draw the notify lines if the developer cvar is set,
- // or we are a debug build
- if ( !con_noPrint.GetBool() ) {
- DrawNotify();
- }
- }
- if ( com_showFPS.GetBool() ) {
- y = SCR_DrawFPS( 0 );
- }
- if ( com_showMemoryUsage.GetBool() ) {
- y = SCR_DrawMemoryUsage( y );
- }
- if ( com_showAsyncStats.GetBool() ) {
- y = SCR_DrawAsyncStats( y );
- }
- if ( com_showSoundDecoders.GetBool() ) {
- y = SCR_DrawSoundDecoders( y );
- }
- }
|