doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Console.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 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.
23 
24 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.
25 
26 ===========================================================================
27 */
28 
29 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 void SCR_DrawTextLeftAlign( float &y, const char *text, ... ) id_attribute((format(printf,2,3)));
33 void SCR_DrawTextRightAlign( float &y, const char *text, ... ) id_attribute((format(printf,2,3)));
34 
35 #define LINE_WIDTH 78
36 #define NUM_CON_TIMES 4
37 #define CON_TEXTSIZE 0x30000
38 #define TOTAL_LINES (CON_TEXTSIZE / LINE_WIDTH)
39 #define CONSOLE_FIRSTREPEAT 200
40 #define CONSOLE_REPEAT 100
41 
42 #define COMMAND_HISTORY 64
43 
44 // the console will query the cvar and command systems for
45 // command completion information
46 
47 class idConsoleLocal : public idConsole {
48 public:
49  virtual void Init( void );
50  virtual void Shutdown( void );
51  virtual void LoadGraphics( void );
52  virtual bool ProcessEvent( const sysEvent_t *event, bool forceAccept );
53  virtual bool Active( void );
54  virtual void ClearNotifyLines( void );
55  virtual void Close( void );
56  virtual void Print( const char *text );
57  virtual void Draw( bool forceFullScreen );
58 
59  void Dump( const char *toFile );
60  void Clear();
61 
62  //============================
63 
65 
66 private:
67  void KeyDownEvent( int key );
68 
69  void Linefeed();
70 
71  void PageUp();
72  void PageDown();
73  void Top();
74  void Bottom();
75 
76  void DrawInput();
77  void DrawNotify();
78  void DrawSolidConsole( float frac );
79 
80  void Scroll();
81  void SetDisplayFraction( float frac );
82  void UpdateDisplayFraction( void );
83 
84  //============================
85 
87 
88  short text[CON_TEXTSIZE];
89  int current; // line where next message will be printed
90  int x; // offset in current line for next print
91  int display; // bottom of console displays this line
92  int lastKeyEvent; // time of last key event for scroll delay
93  int nextKeyEvent; // keyboard repeat rate
94 
95  float displayFrac; // approaches finalFrac at scr_conspeed
96  float finalFrac; // 0.0 to 1.0 lines of console to display
97  int fracTime; // time of last displayFrac update
98 
99  int vislines; // in scanlines
100 
101  int times[NUM_CON_TIMES]; // cls.realtime time the line was generated
102  // for transparent notify lines
104 
106 
107  int nextHistoryLine;// the last line in the history buffer, not masked
108  int historyLine; // the line being displayed from history buffer
109  // will be <= nextHistoryLine
110 
112 
116 
119 };
120 
121 static idConsoleLocal localConsole;
122 idConsole *console = &localConsole;
123 
124 idCVar idConsoleLocal::con_speed( "con_speed", "3", CVAR_SYSTEM, "speed at which the console moves up and down" );
125 idCVar idConsoleLocal::con_notifyTime( "con_notifyTime", "3", CVAR_SYSTEM, "time messages are displayed onscreen when console is pulled up" );
126 #ifdef DEBUG
127 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" );
128 #else
129 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" );
130 #endif
131 
132 
133 
134 /*
135 =============================================================================
136 
137  Misc stats
138 
139 =============================================================================
140 */
141 
142 /*
143 ==================
144 SCR_DrawTextLeftAlign
145 ==================
146 */
147 void SCR_DrawTextLeftAlign( float &y, const char *text, ... ) {
148  char string[MAX_STRING_CHARS];
149  va_list argptr;
150  va_start( argptr, text );
151  idStr::vsnPrintf( string, sizeof( string ), text, argptr );
152  va_end( argptr );
153  renderSystem->DrawSmallStringExt( 0, y + 2, string, colorWhite, true, localConsole.charSetShader );
154  y += SMALLCHAR_HEIGHT + 4;
155 }
156 
157 /*
158 ==================
159 SCR_DrawTextRightAlign
160 ==================
161 */
162 void SCR_DrawTextRightAlign( float &y, const char *text, ... ) {
163  char string[MAX_STRING_CHARS];
164  va_list argptr;
165  va_start( argptr, text );
166  int i = idStr::vsnPrintf( string, sizeof( string ), text, argptr );
167  va_end( argptr );
168  renderSystem->DrawSmallStringExt( 635 - i * SMALLCHAR_WIDTH, y + 2, string, colorWhite, true, localConsole.charSetShader );
169  y += SMALLCHAR_HEIGHT + 4;
170 }
171 
172 
173 
174 
175 /*
176 ==================
177 SCR_DrawFPS
178 ==================
179 */
180 #define FPS_FRAMES 4
181 float SCR_DrawFPS( float y ) {
182  char *s;
183  int w;
184  static int previousTimes[FPS_FRAMES];
185  static int index;
186  int i, total;
187  int fps;
188  static int previous;
189  int t, frameTime;
190 
191  // don't use serverTime, because that will be drifting to
192  // correct for internet lag changes, timescales, timedemos, etc
193  t = Sys_Milliseconds();
194  frameTime = t - previous;
195  previous = t;
196 
197  previousTimes[index % FPS_FRAMES] = frameTime;
198  index++;
199  if ( index > FPS_FRAMES ) {
200  // average multiple frames together to smooth changes out a bit
201  total = 0;
202  for ( i = 0 ; i < FPS_FRAMES ; i++ ) {
203  total += previousTimes[i];
204  }
205  if ( !total ) {
206  total = 1;
207  }
208  fps = 10000 * FPS_FRAMES / total;
209  fps = (fps + 5)/10;
210 
211  s = va( "%ifps", fps );
212  w = strlen( s ) * BIGCHAR_WIDTH;
213 
214  renderSystem->DrawBigStringExt( 635 - w, idMath::FtoiFast( y ) + 2, s, colorWhite, true, localConsole.charSetShader);
215  }
216 
217  return y + BIGCHAR_HEIGHT + 4;
218 }
219 
220 /*
221 ==================
222 SCR_DrawMemoryUsage
223 ==================
224 */
225 float SCR_DrawMemoryUsage( float y ) {
226  memoryStats_t allocs, frees;
227 
228  Mem_GetStats( allocs );
229  SCR_DrawTextRightAlign( y, "total allocated memory: %4d, %4dkB", allocs.num, allocs.totalSize>>10 );
230 
231  Mem_GetFrameStats( allocs, frees );
232  SCR_DrawTextRightAlign( y, "frame alloc: %4d, %4dkB frame free: %4d, %4dkB", allocs.num, allocs.totalSize>>10, frees.num, frees.totalSize>>10 );
233 
235 
236  return y;
237 }
238 
239 /*
240 ==================
241 SCR_DrawAsyncStats
242 ==================
243 */
244 float SCR_DrawAsyncStats( float y ) {
245  int i, outgoingRate, incomingRate;
246  float outgoingCompression, incomingCompression;
247 
248  if ( idAsyncNetwork::server.IsActive() ) {
249 
250  SCR_DrawTextRightAlign( y, "server delay = %d msec", idAsyncNetwork::server.GetDelay() );
251  SCR_DrawTextRightAlign( y, "total outgoing rate = %d KB/s", idAsyncNetwork::server.GetOutgoingRate() >> 10 );
252  SCR_DrawTextRightAlign( y, "total incoming rate = %d KB/s", idAsyncNetwork::server.GetIncomingRate() >> 10 );
253 
254  for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) {
255 
256  outgoingRate = idAsyncNetwork::server.GetClientOutgoingRate( i );
257  incomingRate = idAsyncNetwork::server.GetClientIncomingRate( i );
258  outgoingCompression = idAsyncNetwork::server.GetClientOutgoingCompression( i );
259  incomingCompression = idAsyncNetwork::server.GetClientIncomingCompression( i );
260 
261  if ( outgoingRate != -1 && incomingRate != -1 ) {
262  SCR_DrawTextRightAlign( y, "client %d: out rate = %d B/s (% -2.1f%%), in rate = %d B/s (% -2.1f%%)",
263  i, outgoingRate, outgoingCompression, incomingRate, incomingCompression );
264  }
265  }
266 
267  idStr msg;
269  SCR_DrawTextRightAlign( y, msg.c_str() );
270 
271  } else if ( idAsyncNetwork::client.IsActive() ) {
272 
273  outgoingRate = idAsyncNetwork::client.GetOutgoingRate();
274  incomingRate = idAsyncNetwork::client.GetIncomingRate();
275  outgoingCompression = idAsyncNetwork::client.GetOutgoingCompression();
276  incomingCompression = idAsyncNetwork::client.GetIncomingCompression();
277 
278  if ( outgoingRate != -1 && incomingRate != -1 ) {
279  SCR_DrawTextRightAlign( y, "out rate = %d B/s (% -2.1f%%), in rate = %d B/s (% -2.1f%%)",
280  outgoingRate, outgoingCompression, incomingRate, incomingCompression );
281  }
282 
283  SCR_DrawTextRightAlign( y, "packet loss = %d%%, client prediction = %d",
284  (int)idAsyncNetwork::client.GetIncomingPacketLoss(), idAsyncNetwork::client.GetPrediction() );
285 
286  SCR_DrawTextRightAlign( y, "predicted frames: %d", idAsyncNetwork::client.GetPredictedFrames() );
287 
288  }
289 
290  return y;
291 }
292 
293 /*
294 ==================
295 SCR_DrawSoundDecoders
296 ==================
297 */
298 float SCR_DrawSoundDecoders( float y ) {
299  int index, numActiveDecoders;
300  soundDecoderInfo_t decoderInfo;
301 
302  index = -1;
303  numActiveDecoders = 0;
304  while( ( index = soundSystem->GetSoundDecoderInfo( index, decoderInfo ) ) != -1 ) {
305  int localTime = decoderInfo.current44kHzTime - decoderInfo.start44kHzTime;
306  int sampleTime = decoderInfo.num44kHzSamples / decoderInfo.numChannels;
307  int percent;
308  if ( localTime > sampleTime ) {
309  if ( decoderInfo.looping ) {
310  percent = ( localTime % sampleTime ) * 100 / sampleTime;
311  } else {
312  percent = 100;
313  }
314  } else {
315  percent = localTime * 100 / sampleTime;
316  }
317  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 );
318  numActiveDecoders++;
319  }
320  return y;
321 }
322 
323 //=========================================================================
324 
325 /*
326 ==============
327 Con_Clear_f
328 ==============
329 */
330 static void Con_Clear_f( const idCmdArgs &args ) {
331  localConsole.Clear();
332 }
333 
334 /*
335 ==============
336 Con_Dump_f
337 ==============
338 */
339 static void Con_Dump_f( const idCmdArgs &args ) {
340  if ( args.Argc() != 2 ) {
341  common->Printf( "usage: conDump <filename>\n" );
342  return;
343  }
344 
345  idStr fileName = args.Argv(1);
346  fileName.DefaultFileExtension(".txt");
347 
348  common->Printf( "Dumped console text to %s.\n", fileName.c_str() );
349 
350  localConsole.Dump( fileName.c_str() );
351 }
352 
353 /*
354 ==============
355 idConsoleLocal::Init
356 ==============
357 */
358 void idConsoleLocal::Init( void ) {
359  int i;
360 
361  keyCatching = false;
362 
363  lastKeyEvent = -1;
365 
367 
369 
370  for ( i = 0 ; i < COMMAND_HISTORY ; i++ ) {
373  }
374 
375  cmdSystem->AddCommand( "clear", Con_Clear_f, CMD_FL_SYSTEM, "clears the console" );
376  cmdSystem->AddCommand( "conDump", Con_Dump_f, CMD_FL_SYSTEM, "dumps the console text to a file" );
377 }
378 
379 /*
380 ==============
381 idConsoleLocal::Shutdown
382 ==============
383 */
385  cmdSystem->RemoveCommand( "clear" );
386  cmdSystem->RemoveCommand( "conDump" );
387 }
388 
389 /*
390 ==============
391 LoadGraphics
392 
393 Can't be combined with init, because init happens before
394 the renderSystem is initialized
395 ==============
396 */
398  charSetShader = declManager->FindMaterial( "textures/bigchars" );
399  whiteShader = declManager->FindMaterial( "_white" );
400  consoleShader = declManager->FindMaterial( "console" );
401 }
402 
403 /*
404 ================
405 idConsoleLocal::Active
406 ================
407 */
409  return keyCatching;
410 }
411 
412 /*
413 ================
414 idConsoleLocal::ClearNotifyLines
415 ================
416 */
418  int i;
419 
420  for ( i = 0 ; i < NUM_CON_TIMES ; i++ ) {
421  times[i] = 0;
422  }
423 }
424 
425 /*
426 ================
427 idConsoleLocal::Close
428 ================
429 */
431  keyCatching = false;
432  SetDisplayFraction( 0 );
433  displayFrac = 0; // don't scroll to that point, go immediately
435 }
436 
437 /*
438 ================
439 idConsoleLocal::Clear
440 ================
441 */
443  int i;
444 
445  for ( i = 0 ; i < CON_TEXTSIZE ; i++ ) {
446  text[i] = (idStr::ColorIndex(C_COLOR_CYAN)<<8) | ' ';
447  }
448 
449  Bottom(); // go to end
450 }
451 
452 /*
453 ================
454 idConsoleLocal::Dump
455 
456 Save the console contents out to a file
457 ================
458 */
459 void idConsoleLocal::Dump( const char *fileName ) {
460  int l, x, i;
461  short * line;
462  idFile *f;
463  char buffer[LINE_WIDTH + 3];
464 
465  f = fileSystem->OpenFileWrite( fileName );
466  if ( !f ) {
467  common->Warning( "couldn't open %s", fileName );
468  return;
469  }
470 
471  // skip empty lines
472  l = current - TOTAL_LINES + 1;
473  if ( l < 0 ) {
474  l = 0;
475  }
476  for ( ; l <= current ; l++ )
477  {
478  line = text + ( l % TOTAL_LINES ) * LINE_WIDTH;
479  for ( x = 0; x < LINE_WIDTH; x++ )
480  if ( ( line[x] & 0xff ) > ' ' )
481  break;
482  if ( x != LINE_WIDTH )
483  break;
484  }
485 
486  // write the remaining lines
487  for ( ; l <= current; l++ ) {
488  line = text + ( l % TOTAL_LINES ) * LINE_WIDTH;
489  for( i = 0; i < LINE_WIDTH; i++ ) {
490  buffer[i] = line[i] & 0xff;
491  }
492  for ( x = LINE_WIDTH-1; x >= 0; x-- ) {
493  if ( buffer[x] <= ' ' ) {
494  buffer[x] = 0;
495  } else {
496  break;
497  }
498  }
499  buffer[x+1] = '\r';
500  buffer[x+2] = '\n';
501  buffer[x+3] = 0;
502  f->Write( buffer, strlen( buffer ) );
503  }
504 
505  fileSystem->CloseFile( f );
506 }
507 
508 /*
509 ================
510 idConsoleLocal::PageUp
511 ================
512 */
514  display -= 2;
515  if ( current - display >= TOTAL_LINES ) {
516  display = current - TOTAL_LINES + 1;
517  }
518 }
519 
520 /*
521 ================
522 idConsoleLocal::PageDown
523 ================
524 */
526  display += 2;
527  if ( display > current ) {
528  display = current;
529  }
530 }
531 
532 /*
533 ================
534 idConsoleLocal::Top
535 ================
536 */
537 void idConsoleLocal::Top( void ) {
538  display = 0;
539 }
540 
541 /*
542 ================
543 idConsoleLocal::Bottom
544 ================
545 */
547  display = current;
548 }
549 
550 
551 /*
552 =============================================================================
553 
554 CONSOLE LINE EDITING
555 
556 ==============================================================================
557 */
558 
559 /*
560 ====================
561 KeyDownEvent
562 
563 Handles history and console scrollback
564 ====================
565 */
567 
568  // Execute F key bindings
569  if ( key >= K_F1 && key <= K_F12 ) {
571  return;
572  }
573 
574  // ctrl-L clears screen
575  if ( key == 'l' && idKeyInput::IsDown( K_CTRL ) ) {
576  Clear();
577  return;
578  }
579 
580  // enter finishes the line
581  if ( key == K_ENTER || key == K_KP_ENTER ) {
582 
583  common->Printf ( "]%s\n", consoleField.GetBuffer() );
584 
587 
588  // copy line to history buffer
590  nextHistoryLine++;
592 
595 
596  session->UpdateScreen();// force an update, because the command
597  // may take some time
598  return;
599  }
600 
601  // command completion
602 
603  if ( key == K_TAB ) {
605  return;
606  }
607 
608  // command history (ctrl-p ctrl-n for unix style)
609 
610  if ( ( key == K_UPARROW ) ||
611  ( ( tolower(key) == 'p' ) && idKeyInput::IsDown( K_CTRL ) ) ) {
612  if ( nextHistoryLine - historyLine < COMMAND_HISTORY && historyLine > 0 ) {
613  historyLine--;
614  }
616  return;
617  }
618 
619  if ( ( key == K_DOWNARROW ) ||
620  ( ( tolower( key ) == 'n' ) && idKeyInput::IsDown( K_CTRL ) ) ) {
621  if ( historyLine == nextHistoryLine ) {
622  return;
623  }
624  historyLine++;
626  return;
627  }
628 
629  // console scrolling
630  if ( key == K_PGUP ) {
631  PageUp();
634  return;
635  }
636 
637  if ( key == K_PGDN ) {
638  PageDown();
641  return;
642  }
643 
644  if ( key == K_MWHEELUP ) {
645  PageUp();
646  return;
647  }
648 
649  if ( key == K_MWHEELDOWN ) {
650  PageDown();
651  return;
652  }
653 
654  // ctrl-home = top of console
655  if ( key == K_HOME && idKeyInput::IsDown( K_CTRL ) ) {
656  Top();
657  return;
658  }
659 
660  // ctrl-end = bottom of console
661  if ( key == K_END && idKeyInput::IsDown( K_CTRL ) ) {
662  Bottom();
663  return;
664  }
665 
666  // pass to the normal editline routine
667  consoleField.KeyDownEvent( key );
668 }
669 
670 /*
671 ==============
672 Scroll
673 deals with scrolling text because we don't have key repeat
674 ==============
675 */
677  if (lastKeyEvent == -1 || (lastKeyEvent+200) > eventLoop->Milliseconds()) {
678  return;
679  }
680  // console scrolling
681  if ( idKeyInput::IsDown( K_PGUP ) ) {
682  PageUp();
684  return;
685  }
686 
687  if ( idKeyInput::IsDown( K_PGDN ) ) {
688  PageDown();
690  return;
691  }
692 }
693 
694 /*
695 ==============
696 SetDisplayFraction
697 
698 Causes the console to start opening the desired amount.
699 ==============
700 */
702  finalFrac = frac;
704 }
705 
706 /*
707 ==============
708 UpdateDisplayFraction
709 
710 Scrolls the console up or down based on conspeed
711 ==============
712 */
714  if ( con_speed.GetFloat() <= 0.1f ) {
717  return;
718  }
719 
720  // scroll towards the destination height
721  if ( finalFrac < displayFrac ) {
723  if ( finalFrac > displayFrac ) {
725  }
727  } else if ( finalFrac > displayFrac ) {
729  if ( finalFrac < displayFrac ) {
731  }
733  }
734 }
735 
736 /*
737 ==============
738 ProcessEvent
739 ==============
740 */
741 bool idConsoleLocal::ProcessEvent( const sysEvent_t *event, bool forceAccept ) {
742  bool consoleKey;
743  consoleKey = event->evType == SE_KEY && ( event->evValue == Sys_GetConsoleKey( false ) || event->evValue == Sys_GetConsoleKey( true ) );
744 
745 #if ID_CONSOLE_LOCK
746  // If the console's not already down, and we have it turned off, check for ctrl+alt
747  if ( !keyCatching && !com_allowConsole.GetBool() ) {
749  consoleKey = false;
750  }
751  }
752 #endif
753 
754  // we always catch the console key event
755  if ( !forceAccept && consoleKey ) {
756  // ignore up events
757  if ( event->evValue2 == 0 ) {
758  return true;
759  }
760 
762 
763  // a down event will toggle the destination lines
764  if ( keyCatching ) {
765  Close();
766  Sys_GrabMouseCursor( true );
767  cvarSystem->SetCVarBool( "ui_chat", false );
768  } else {
770  keyCatching = true;
771  if ( idKeyInput::IsDown( K_SHIFT ) ) {
772  // if the shift key is down, don't open the console as much
773  SetDisplayFraction( 0.2f );
774  } else {
775  SetDisplayFraction( 0.5f );
776  }
777  cvarSystem->SetCVarBool( "ui_chat", true );
778  }
779  return true;
780  }
781 
782  // if we aren't key catching, dump all the other events
783  if ( !forceAccept && !keyCatching ) {
784  return false;
785  }
786 
787  // handle key and character events
788  if ( event->evType == SE_CHAR ) {
789  // never send the console key as a character
790  if ( event->evValue != Sys_GetConsoleKey( false ) && event->evValue != Sys_GetConsoleKey( true ) ) {
791  consoleField.CharEvent( event->evValue );
792  }
793  return true;
794  }
795 
796  if ( event->evType == SE_KEY ) {
797  // ignore up key events
798  if ( event->evValue2 == 0 ) {
799  return true;
800  }
801 
802  KeyDownEvent( event->evValue );
803  return true;
804  }
805 
806  // we don't handle things like mouse, joystick, and network packets
807  return false;
808 }
809 
810 /*
811 ==============================================================================
812 
813 PRINTING
814 
815 ==============================================================================
816 */
817 
818 /*
819 ===============
820 Linefeed
821 ===============
822 */
824  int i;
825 
826  // mark time for transparent overlay
827  if ( current >= 0 ) {
829  }
830 
831  x = 0;
832  if ( display == current ) {
833  display++;
834  }
835  current++;
836  for ( i = 0; i < LINE_WIDTH; i++ ) {
837  text[(current%TOTAL_LINES)*LINE_WIDTH+i] = (idStr::ColorIndex(C_COLOR_CYAN)<<8) | ' ';
838  }
839 }
840 
841 
842 /*
843 ================
844 Print
845 
846 Handles cursor positioning, line wrapping, etc
847 ================
848 */
849 void idConsoleLocal::Print( const char *txt ) {
850  int y;
851  int c, l;
852  int color;
853 
854 #ifdef ID_ALLOW_TOOLS
855  RadiantPrint( txt );
856 
857  if( com_editors & EDITOR_MATERIAL ) {
859  }
860 #endif
861 
862  color = idStr::ColorIndex( C_COLOR_CYAN );
863 
864  while ( (c = *(const unsigned char*)txt) != 0 ) {
865  if ( idStr::IsColor( txt ) ) {
866  if ( *(txt+1) == C_COLOR_DEFAULT ) {
867  color = idStr::ColorIndex( C_COLOR_CYAN );
868  } else {
869  color = idStr::ColorIndex( *(txt+1) );
870  }
871  txt += 2;
872  continue;
873  }
874 
875  y = current % TOTAL_LINES;
876 
877  // if we are about to print a new word, check to see
878  // if we should wrap to the new line
879  if ( c > ' ' && ( x == 0 || text[y*LINE_WIDTH+x-1] <= ' ' ) ) {
880  // count word length
881  for (l=0 ; l< LINE_WIDTH ; l++) {
882  if ( txt[l] <= ' ') {
883  break;
884  }
885  }
886 
887  // word wrap
888  if (l != LINE_WIDTH && (x + l >= LINE_WIDTH) ) {
889  Linefeed();
890  }
891  }
892 
893  txt++;
894 
895  switch( c ) {
896  case '\n':
897  Linefeed ();
898  break;
899  case '\t':
900  do {
901  text[y*LINE_WIDTH+x] = (color << 8) | ' ';
902  x++;
903  if ( x >= LINE_WIDTH ) {
904  Linefeed();
905  x = 0;
906  }
907  } while ( x & 3 );
908  break;
909  case '\r':
910  x = 0;
911  break;
912  default: // display character and advance
913  text[y*LINE_WIDTH+x] = (color << 8) | c;
914  x++;
915  if ( x >= LINE_WIDTH ) {
916  Linefeed();
917  x = 0;
918  }
919  break;
920  }
921  }
922 
923 
924  // mark time for transparent overlay
925  if ( current >= 0 ) {
927  }
928 }
929 
930 
931 /*
932 ==============================================================================
933 
934 DRAWING
935 
936 ==============================================================================
937 */
938 
939 
940 /*
941 ================
942 DrawInput
943 
944 Draw the editline after a ] prompt
945 ================
946 */
948  int y, autoCompleteLength;
949 
950  y = vislines - ( SMALLCHAR_HEIGHT * 2 );
951 
952  if ( consoleField.GetAutoCompleteLength() != 0 ) {
953  autoCompleteLength = strlen( consoleField.GetBuffer() ) - consoleField.GetAutoCompleteLength();
954 
955  if ( autoCompleteLength > 0 ) {
956  renderSystem->SetColor4( .8f, .2f, .2f, .45f );
957 
959  y + 2, autoCompleteLength * SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT - 2, 0, 0, 0, 0, whiteShader );
960 
961  }
962  }
963 
965 
966  renderSystem->DrawSmallChar( 1 * SMALLCHAR_WIDTH, y, ']', localConsole.charSetShader );
967 
969 }
970 
971 
972 /*
973 ================
974 DrawNotify
975 
976 Draws the last few lines of output transparently over the game top
977 ================
978 */
980  int x, v;
981  short *text_p;
982  int i;
983  int time;
984  int currentColor;
985 
986  if ( con_noPrint.GetBool() ) {
987  return;
988  }
989 
990  currentColor = idStr::ColorIndex( C_COLOR_WHITE );
991  renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
992 
993  v = 0;
994  for ( i = current-NUM_CON_TIMES+1; i <= current; i++ ) {
995  if ( i < 0 ) {
996  continue;
997  }
998  time = times[i % NUM_CON_TIMES];
999  if ( time == 0 ) {
1000  continue;
1001  }
1002  time = com_frameTime - time;
1003  if ( time > con_notifyTime.GetFloat() * 1000 ) {
1004  continue;
1005  }
1006  text_p = text + (i % TOTAL_LINES)*LINE_WIDTH;
1007 
1008  for ( x = 0; x < LINE_WIDTH; x++ ) {
1009  if ( ( text_p[x] & 0xff ) == ' ' ) {
1010  continue;
1011  }
1012  if ( idStr::ColorIndex(text_p[x]>>8) != currentColor ) {
1013  currentColor = idStr::ColorIndex(text_p[x]>>8);
1014  renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
1015  }
1016  renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, v, text_p[x] & 0xff, localConsole.charSetShader );
1017  }
1018 
1019  v += SMALLCHAR_HEIGHT;
1020  }
1021 
1023 }
1024 
1025 /*
1026 ================
1027 DrawSolidConsole
1028 
1029 Draws the console with the solid background
1030 ================
1031 */
1033  int i, x;
1034  float y;
1035  int rows;
1036  short *text_p;
1037  int row;
1038  int lines;
1039  int currentColor;
1040 
1041  lines = idMath::FtoiFast( SCREEN_HEIGHT * frac );
1042  if ( lines <= 0 ) {
1043  return;
1044  }
1045 
1046  if ( lines > SCREEN_HEIGHT ) {
1047  lines = SCREEN_HEIGHT;
1048  }
1049 
1050  // draw the background
1051  y = frac * SCREEN_HEIGHT - 2;
1052  if ( y < 1.0f ) {
1053  y = 0.0f;
1054  } else {
1055  renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, y, 0, 1.0f - displayFrac, 1, 1, consoleShader );
1056  }
1057 
1059  renderSystem->DrawStretchPic( 0, y, SCREEN_WIDTH, 2, 0, 0, 0, 0, whiteShader );
1061 
1062  // draw the version number
1063 
1065 
1067  i = version.Length();
1068 
1069  for ( x = 0; x < i; x++ ) {
1071  (lines-(SMALLCHAR_HEIGHT+SMALLCHAR_HEIGHT/2)), version[x], localConsole.charSetShader );
1072 
1073  }
1074 
1075 
1076  // draw the text
1077  vislines = lines;
1078  rows = (lines-SMALLCHAR_WIDTH)/SMALLCHAR_WIDTH; // rows of text to draw
1079 
1080  y = lines - (SMALLCHAR_HEIGHT*3);
1081 
1082  // draw from the bottom up
1083  if ( display != current ) {
1084  // draw arrows to show the buffer is backscrolled
1086  for ( x = 0; x < LINE_WIDTH; x += 4 ) {
1087  renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, idMath::FtoiFast( y ), '^', localConsole.charSetShader );
1088  }
1089  y -= SMALLCHAR_HEIGHT;
1090  rows--;
1091  }
1092 
1093  row = display;
1094 
1095  if ( x == 0 ) {
1096  row--;
1097  }
1098 
1099  currentColor = idStr::ColorIndex( C_COLOR_WHITE );
1100  renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
1101 
1102  for ( i = 0; i < rows; i++, y -= SMALLCHAR_HEIGHT, row-- ) {
1103  if ( row < 0 ) {
1104  break;
1105  }
1106  if ( current - row >= TOTAL_LINES ) {
1107  // past scrollback wrap point
1108  continue;
1109  }
1110 
1111  text_p = text + (row % TOTAL_LINES)*LINE_WIDTH;
1112 
1113  for ( x = 0; x < LINE_WIDTH; x++ ) {
1114  if ( ( text_p[x] & 0xff ) == ' ' ) {
1115  continue;
1116  }
1117 
1118  if ( idStr::ColorIndex(text_p[x]>>8) != currentColor ) {
1119  currentColor = idStr::ColorIndex(text_p[x]>>8);
1120  renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
1121  }
1122  renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, idMath::FtoiFast( y ), text_p[x] & 0xff, localConsole.charSetShader );
1123  }
1124  }
1125 
1126  // draw the input prompt, user text, and cursor if desired
1127  DrawInput();
1128 
1130 }
1131 
1132 
1133 /*
1134 ==============
1135 Draw
1136 
1137 ForceFullScreen is used by the editor
1138 ==============
1139 */
1140 void idConsoleLocal::Draw( bool forceFullScreen ) {
1141  float y = 0.0f;
1142 
1143  if ( !charSetShader ) {
1144  return;
1145  }
1146 
1147  if ( forceFullScreen ) {
1148  // if we are forced full screen because of a disconnect,
1149  // we want the console closed when we go back to a session state
1150  Close();
1151  // we are however catching keyboard input
1152  keyCatching = true;
1153  }
1154 
1155  Scroll();
1156 
1158 
1159  if ( forceFullScreen ) {
1160  DrawSolidConsole( 1.0f );
1161  } else if ( displayFrac ) {
1163  } else {
1164  // only draw the notify lines if the developer cvar is set,
1165  // or we are a debug build
1166  if ( !con_noPrint.GetBool() ) {
1167  DrawNotify();
1168  }
1169  }
1170 
1171  if ( com_showFPS.GetBool() ) {
1172  y = SCR_DrawFPS( 0 );
1173  }
1174 
1175  if ( com_showMemoryUsage.GetBool() ) {
1176  y = SCR_DrawMemoryUsage( y );
1177  }
1178 
1179  if ( com_showAsyncStats.GetBool() ) {
1180  y = SCR_DrawAsyncStats( y );
1181  }
1182 
1183  if ( com_showSoundDecoders.GetBool() ) {
1184  y = SCR_DrawSoundDecoders( y );
1185  }
1186 }
static bool IsDown(int keyNum)
Definition: KeyInput.cpp:271
idVec4 color
Definition: Console.cpp:103
void Draw(int x, int y, int width, bool showCursor, const idMaterial *material)
Definition: EditField.cpp:531
Definition: KeyInput.h:78
#define CONSOLE_REPEAT
Definition: Console.cpp:40
const int MAX_ASYNC_CLIENTS
Definition: AsyncNetwork.h:44
virtual void SetColor(const idVec4 &rgba)=0
const int C_COLOR_DEFAULT
Definition: Str.h:83
idCVar com_showSoundDecoders("com_showSoundDecoders","0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT,"show sound decoders")
void Mem_ClearFrameStats(void)
Definition: Heap.cpp:996
idCVarSystem * cvarSystem
Definition: CVarSystem.cpp:487
idVec4 colorWhite
Definition: Lib.cpp:116
void MaterialEditorPrintConsole(const char *msg)
Allows the doom engine to reflect console output to the material editors console. ...
Definition: edit_stub.cpp:78
const int BUILD_NUMBER
Definition: BuildVersion.h:28
GLenum GLsizei GLenum format
Definition: glext.h:2846
void Mem_GetStats(memoryStats_t &stats)
Definition: Heap.cpp:1018
float GetFloat(void) const
Definition: CVarSystem.h:144
const GLdouble * v
Definition: glext.h:2936
void DrawSolidConsole(float frac)
Definition: Console.cpp:1032
#define TOTAL_LINES
Definition: Console.cpp:38
idCVar com_showMemoryUsage("com_showMemoryUsage","0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT,"show total and per frame memory usage")
#define const
Definition: getdate.c:251
int Length(void) const
Definition: Str.h:702
void AutoComplete(void)
Definition: EditField.cpp:191
idCVar com_showAsyncStats("com_showAsyncStats","0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT,"show async network stats")
GLenum GLint GLint y
Definition: glext.h:2849
static idAsyncClient client
Definition: AsyncNetwork.h:168
int times[NUM_CON_TIMES]
Definition: Console.cpp:101
const int SCREEN_HEIGHT
Definition: RenderSystem.h:154
idRenderSystem * renderSystem
int lastKeyEvent
Definition: Console.cpp:92
float SCR_DrawAsyncStats(float y)
Definition: Console.cpp:244
int Sys_Milliseconds(void)
idEditField consoleField
Definition: Console.cpp:111
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
void UpdateDisplayFraction(void)
Definition: Console.cpp:713
idCVar com_showFPS("com_showFPS","0", CVAR_BOOL|CVAR_SYSTEM|CVAR_ARCHIVE|CVAR_NOCHEAT,"show frames rendered per second")
static int ColorIndex(int c)
Definition: Str.h:1036
static idCVar con_notifyTime
Definition: Console.cpp:114
#define LINE_WIDTH
Definition: Console.cpp:35
virtual int GetSoundDecoderInfo(int index, soundDecoderInfo_t &decoderInfo)=0
char * GetBuffer(void)
Definition: EditField.cpp:511
void ClearAutoComplete(void)
Definition: EditField.cpp:166
virtual void RemoveCommand(const char *cmdName)=0
void void SCR_DrawTextRightAlign(float &y, const char *text,...) id_attribute((format(printf
Definition: Console.cpp:162
float GetIncomingCompression(void) const
int nextHistoryLine
Definition: Console.cpp:107
idCmdSystem * cmdSystem
Definition: CmdSystem.cpp:116
void CharEvent(int c)
Definition: EditField.cpp:298
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
int com_frameTime
Definition: Common.cpp:94
virtual void DrawSmallChar(int x, int y, int ch, const idMaterial *material)=0
GLdouble s
Definition: glext.h:2935
idStr & DefaultFileExtension(const char *extension)
Definition: Str.cpp:794
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
Definition: KeyInput.h:91
virtual void Draw(bool forceFullScreen)
Definition: Console.cpp:1140
int current44kHzTime
Definition: sound.h:279
virtual void ClearNotifyLines(void)
Definition: Console.cpp:417
static idVec4 & ColorForIndex(int i)
Definition: Str.cpp:71
const int BIGCHAR_WIDTH
Definition: RenderSystem.h:148
list l
Definition: prepare.py:17
idConsole * console
Definition: Console.cpp:122
float SCR_DrawSoundDecoders(float y)
Definition: Console.cpp:298
int com_editors
Definition: Common.cpp:97
struct version_s version
Definition: File.h:50
const int C_COLOR_WHITE
Definition: Str.h:90
virtual void BufferCommandText(cmdExecution_t exec, const char *text)=0
float SCR_DrawMemoryUsage(float y)
Definition: Console.cpp:225
int start44kHzTime
Definition: sound.h:278
virtual bool Active(void)
Definition: Console.cpp:408
float GetClientOutgoingCompression(int clientNum) const
virtual void Print(const char *text)
Definition: Console.cpp:849
const int SMALLCHAR_WIDTH
Definition: RenderSystem.h:146
float displayFrac
Definition: Console.cpp:95
Definition: KeyInput.h:80
int num44kHzSamples
Definition: sound.h:274
GLuint index
Definition: glext.h:3476
const GLubyte * c
Definition: glext.h:4677
void KeyDownEvent(int key)
Definition: Console.cpp:566
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
Definition: Vector.h:808
static idAsyncServer server
Definition: AsyncNetwork.h:167
void Clear(void)
Definition: EditField.cpp:124
#define MAX_STRING_CHARS
Definition: Lib.h:95
void PageDown()
Definition: Console.cpp:525
static int FtoiFast(float f)
Definition: Math.h:801
void Clear()
Definition: Console.cpp:442
float finalFrac
Definition: Console.cpp:96
unsigned char Sys_GetConsoleKey(bool shifted)
Definition: main.cpp:189
void RadiantPrint(const char *text)
Definition: edit_stub.cpp:35
idCommon * common
Definition: Common.cpp:206
virtual void DrawSmallStringExt(int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material)=0
void KeyDownEvent(int key)
Definition: EditField.cpp:373
int evValue2
Definition: sys_public.h:218
int GetAutoCompleteLength(void) const
Definition: EditField.cpp:182
GLuint buffer
Definition: glext.h:3108
virtual void SetCVarBool(const char *name, const bool value, int flags=0)=0
void Scroll()
Definition: Console.cpp:676
virtual void Init(void)
Definition: Console.cpp:358
bool keyCatching
Definition: Console.cpp:86
virtual idFile * OpenFileWrite(const char *relativePath, const char *basePath="fs_savepath")=0
#define COMMAND_HISTORY
Definition: Console.cpp:42
void Mem_GetFrameStats(memoryStats_t &allocs, memoryStats_t &frees)
Definition: Heap.cpp:1008
Definition: KeyInput.h:47
void Bottom()
Definition: Console.cpp:546
#define CON_TEXTSIZE
Definition: Console.cpp:37
void SetDisplayFraction(float frac)
Definition: Console.cpp:701
int Argc(void) const
Definition: CmdArgs.h:48
virtual void LoadGraphics(void)
Definition: Console.cpp:397
float GetOutgoingCompression(void) const
float lastVolume
Definition: sound.h:277
void GetAsyncStatsAvgMsg(idStr &msg)
virtual void SetColor4(float r, float g, float b, float a)=0
const int C_COLOR_CYAN
Definition: Str.h:88
int totalSize
Definition: Heap.h:49
int GetClientIncomingRate(int clientNum) const
virtual void UpdateScreen(bool outOfSequence=true)=0
virtual void Printf(const char *fmt,...) id_attribute((format(printf
int GetOutgoingRate(void) const
virtual void Close(void)
Definition: Console.cpp:430
static idCVar con_speed
Definition: Console.cpp:113
float SCR_DrawFPS(float y)
Definition: Console.cpp:181
virtual void DrawStretchPic(const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material, bool clip=true, float min_x=0.0f, float min_y=0.0f, float max_x=640.0f, float max_y=480.0f)=0
int num
Definition: Heap.h:46
sysEventType_t evType
Definition: sys_public.h:216
static bool ExecKeyBinding(int keyNum)
Definition: KeyInput.cpp:726
const idMaterial * consoleShader
Definition: Console.cpp:118
idDeclManager * declManager
virtual void DrawBigStringExt(int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material)=0
idEventLoop * eventLoop
Definition: EventLoop.cpp:35
const int BIGCHAR_HEIGHT
Definition: RenderSystem.h:149
idCVar com_allowConsole("com_allowConsole","0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT,"allow toggling console with the tilde key")
#define FPS_FRAMES
Definition: Console.cpp:180
idVec4 colorCyan
Definition: Lib.cpp:122
virtual bool ProcessEvent(const sysEvent_t *event, bool forceAccept)
Definition: Console.cpp:741
int GetClientOutgoingRate(int clientNum) const
#define id_attribute(x)
Definition: sys_public.h:139
const int SCREEN_WIDTH
Definition: RenderSystem.h:153
static int static int vsnPrintf(char *dest, int size, const char *fmt, va_list argptr)
Definition: Str.cpp:1502
GLenum GLenum GLvoid * row
Definition: glext.h:2866
bool GetBool(void) const
Definition: CVarSystem.h:142
tuple f
Definition: idal.py:89
const idMaterial * whiteShader
Definition: Console.cpp:117
static idCVar con_noPrint
Definition: Console.cpp:115
Definition: KeyInput.h:70
idEditField historyEditLines[COMMAND_HISTORY]
Definition: Console.cpp:105
idSoundSystem * soundSystem
Definition: snd_system.cpp:92
void SetWidthInChars(int w)
Definition: EditField.cpp:137
virtual int Write(const void *buffer, int len)
Definition: File.cpp:189
Definition: Str.h:116
const int SMALLCHAR_HEIGHT
Definition: RenderSystem.h:147
void PageUp()
Definition: Console.cpp:513
float GetClientIncomingCompression(int clientNum) const
void DrawInput()
Definition: Console.cpp:947
void Dump(const char *toFile)
Definition: Console.cpp:459
const char * c_str(void) const
Definition: Str.h:487
int nextKeyEvent
Definition: Console.cpp:93
const char * Argv(int arg) const
Definition: CmdArgs.h:50
virtual void Shutdown(void)
Definition: Console.cpp:384
#define ENGINE_VERSION
Definition: Licensee.h:39
#define CONSOLE_FIRSTREPEAT
Definition: Console.cpp:39
void Linefeed()
Definition: Console.cpp:823
idSession * session
Definition: Session.cpp:48
char * va(const char *fmt,...)
Definition: Str.cpp:1568
virtual void CloseFile(idFile *f)=0
int GetIncomingRate(void) const
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
const idMaterial * charSetShader
Definition: Console.cpp:64
#define NUM_CON_TIMES
Definition: Console.cpp:36
virtual void AddCommand(const char *cmdName, cmdFunction_t function, int flags, const char *description, argCompletion_t argCompletion=NULL)=0
bool IsColor(void) const
Definition: Str.h:837
int Milliseconds(void)
Definition: EventLoop.cpp:248
void SCR_DrawTextLeftAlign(float &y, const char *text,...) id_attribute((format(printf
Definition: Console.cpp:147
GLdouble GLdouble t
Definition: glext.h:2943
void DrawNotify()
Definition: Console.cpp:979
void Sys_GrabMouseCursor(bool)
Definition: dedicated.cpp:43