2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 float con_cursorspeed = 4;
40 #define CON_TEXTSIZE 16384
42 qboolean con_forcedup; // because no entities to refresh
44 int con_totallines; // total lines in console scrollback
45 int con_backscroll; // lines up from bottom to display
46 int con_current; // where next message will be printed
47 int con_x; // offset in current line for next print
50 cvar_t con_notifytime = {"con_notifytime","3"}; //seconds
51 cvar_t logfile = {"logfile","0"};
53 #define NUM_CON_TIMES 4
54 float con_times[NUM_CON_TIMES]; // realtime time the line was generated
55 // for transparent notify lines
59 qboolean con_debuglog;
61 #define MAXCMDLINE 256
62 extern char key_lines[32][MAXCMDLINE];
64 extern int key_linepos;
67 qboolean con_initialized;
69 int con_notifylines; // scan lines to clear for notify lines
71 extern void M_Menu_Main_f (void);
78 void Con_ToggleConsole_f (void)
80 if (key_dest == key_console)
82 if (cls.state == ca_connected)
85 key_lines[edit_line][1] = 0; // clear any typing
94 key_dest = key_console;
96 // SCR_EndLoadingPlaque ();
97 memset (con_times, 0, sizeof(con_times));
105 void Con_Clear_f (void)
108 memset (con_text, ' ', CON_TEXTSIZE);
117 void Con_ClearNotify (void)
121 for (i=0 ; i<NUM_CON_TIMES ; i++)
131 extern qboolean team_message;
133 void Con_MessageMode_f (void)
135 key_dest = key_message;
136 team_message = false;
145 void Con_MessageMode2_f (void)
147 key_dest = key_message;
156 If the line width has changed, reformat the buffer.
159 void Con_CheckResize (void)
161 int i, j, width, oldwidth, oldtotallines, numlines, numchars;
162 char tbuf[CON_TEXTSIZE];
164 width = (vid.width >> 3) - 2;
166 if (width == con_linewidth)
169 if (width < 1) // video hasn't been initialized yet
171 width = 78; // LordHavoc: changed from 38 to 78 (320 -> 640 conversion)
172 con_linewidth = width;
173 con_totallines = CON_TEXTSIZE / con_linewidth;
174 memset (con_text, ' ', CON_TEXTSIZE);
178 oldwidth = con_linewidth;
179 con_linewidth = width;
180 oldtotallines = con_totallines;
181 con_totallines = CON_TEXTSIZE / con_linewidth;
182 numlines = oldtotallines;
184 if (con_totallines < numlines)
185 numlines = con_totallines;
189 if (con_linewidth < numchars)
190 numchars = con_linewidth;
192 memcpy (tbuf, con_text, CON_TEXTSIZE);
193 memset (con_text, ' ', CON_TEXTSIZE);
195 for (i=0 ; i<numlines ; i++)
197 for (j=0 ; j<numchars ; j++)
199 con_text[(con_totallines - 1 - i) * con_linewidth + j] =
200 tbuf[((con_current - i + oldtotallines) %
201 oldtotallines) * oldwidth + j];
209 con_current = con_totallines - 1;
220 #define MAXGAMEDIRLEN 1000
221 char temp[MAXGAMEDIRLEN+1];
222 char *t2 = "/qconsole.log";
224 Cvar_RegisterVariable(&logfile);
225 con_debuglog = COM_CheckParm("-condebug");
229 if (strlen (com_gamedir) < (MAXGAMEDIRLEN - strlen (t2)))
231 sprintf (temp, "%s%s", com_gamedir, t2);
237 con_text = Hunk_AllocName (CON_TEXTSIZE, "context");
238 memset (con_text, ' ', CON_TEXTSIZE);
242 Con_Printf ("Console initialized.\n");
245 // register our commands
247 Cvar_RegisterVariable (&con_notifytime);
249 Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f);
250 Cmd_AddCommand ("messagemode", Con_MessageMode_f);
251 Cmd_AddCommand ("messagemode2", Con_MessageMode2_f);
252 Cmd_AddCommand ("clear", Con_Clear_f);
253 con_initialized = true;
262 void Con_Linefeed (void)
266 memset (&con_text[(con_current%con_totallines)*con_linewidth]
267 , ' ', con_linewidth);
274 Handles cursor positioning, line wrapping, etc
275 All console printing must go through this in order to be logged to disk
276 If no console is visible, the notify window will pop up.
279 void Con_Print (char *txt)
290 mask = 128; // go to colored text
291 S_LocalSound ("misc/talk.wav");
295 else if (txt[0] == 2)
297 mask = 128; // go to colored text
307 for (l=0 ; l< con_linewidth ; l++)
312 if (l != con_linewidth && (con_x + l > con_linewidth) )
327 // mark time for transparent overlay
328 if (con_current >= 0)
329 con_times[con_current % NUM_CON_TIMES] = realtime;
343 default: // display character and advance
344 y = con_current % con_totallines;
345 con_text[y*con_linewidth+con_x] = c | mask;
347 if (con_x >= con_linewidth)
361 void Con_DebugLog(char *file, char *fmt, ...)
364 static char data[1024];
367 va_start(argptr, fmt);
368 vsprintf(data, fmt, argptr);
370 fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);
371 write(fd, data, strlen(data));
380 Handles cursor positioning, line wrapping, etc
383 // LordHavoc: increased from 4096 to 16384
384 #define MAXPRINTMSG 16384
385 // FIXME: make a buffer size safe vsprintf?
386 void Con_Printf (char *fmt, ...)
389 char msg[MAXPRINTMSG];
390 // static qboolean inupdate;
392 va_start (argptr,fmt);
393 vsprintf (msg,fmt,argptr);
396 // also echo to debugging console
397 Sys_Printf ("%s", msg); // also echo to debugging console
399 // log all messages to file
401 Con_DebugLog(va("%s/qconsole.log",com_gamedir), "%s", msg);
403 if (!con_initialized)
406 if (cls.state == ca_dedicated)
407 return; // no graphics mode
409 // write it to the scrollable buffer
412 // update the screen if the console is displayed
413 // LordHavoc: I don't think there's a real need for this
415 // LordHavoc: don't print text while loading scripts
416 if (cls.state != ca_disconnected)
417 if (cls.signon != SIGNONS && !scr_disabled_for_loading )
419 // protect against infinite loop if something in SCR_UpdateScreen calls
435 A Con_Printf that only shows up if the "developer" cvar is set
438 void Con_DPrintf (char *fmt, ...)
441 char msg[MAXPRINTMSG];
443 if (!developer.value)
444 return; // don't confuse non-developers with techie stuff...
446 va_start (argptr,fmt);
447 vsprintf (msg,fmt,argptr);
450 Con_Printf ("%s", msg);
458 Okay to call even when the screen can't be updated
461 void Con_SafePrintf (char *fmt, ...)
467 va_start (argptr,fmt);
468 vsprintf (msg,fmt,argptr);
471 temp = scr_disabled_for_loading;
472 scr_disabled_for_loading = true;
473 Con_Printf ("%s", msg);
474 scr_disabled_for_loading = temp;
479 ==============================================================================
483 ==============================================================================
491 The input line scrolls horizontally if typing goes beyond the right edge
494 void Con_DrawInput (void)
499 if (key_dest != key_console && !con_forcedup)
500 return; // don't draw anything
502 text = key_lines[edit_line];
504 // add the cursor frame
505 text[key_linepos] = 10+((int)(realtime*con_cursorspeed)&1);
507 text[key_linepos+1] = 0; // LordHavoc: null terminate, rather than padding with spaces
508 // fill out remainder with spaces
509 // for (i=key_linepos+1 ; i< con_linewidth ; i++)
512 // prestep if horizontally scrolling
513 if (key_linepos >= con_linewidth)
514 text += 1 + key_linepos - con_linewidth;
519 // for (i=0 ; i<con_linewidth ; i++)
520 // Draw_Character ( (i+1)<<3, con_vislines - 16, text[i]);
521 // LordHavoc: speedup
522 Draw_String(8, con_vislines - 16, text, con_linewidth);
525 key_lines[edit_line][key_linepos] = 0;
533 Draws the last few lines of output transparently over the game top
536 void Con_DrawNotify (void)
542 extern char chat_buffer[];
546 for (i= con_current-NUM_CON_TIMES+1 ; i<=con_current ; i++)
550 time = con_times[i % NUM_CON_TIMES];
553 time = realtime - time;
554 if (time > con_notifytime.value)
556 text = con_text + (i % con_totallines)*con_linewidth;
560 // for (x = 0 ; x < con_linewidth ; x++)
561 // Draw_Character ( (x+1)<<3, v, text[x]);
562 // LordHavoc: speedup
563 Draw_String(8, v, text, con_linewidth);
569 if (key_dest == key_message)
575 // LordHavoc: speedup, and other improvements
577 sprintf(temptext, "say_team:%s%c", chat_buffer, (int) 10+((int)(realtime*con_cursorspeed)&1));
579 sprintf(temptext, "say:%s%c", chat_buffer, (int) 10+((int)(realtime*con_cursorspeed)&1));
580 while (strlen(temptext) >= con_linewidth)
582 Draw_String (8, v, temptext, con_linewidth);
583 strcpy(temptext, &temptext[con_linewidth]);
586 if (strlen(temptext) > 0)
588 Draw_String (8, v, temptext, 0);
591 // Draw_String (8, v, "say:", 0);
592 // while(chat_buffer[x])
594 // Draw_Character ( (x+5)<<3, v, chat_buffer[x]);
597 // Draw_Character ( (x+5)<<3, v, 10+((int)(realtime*con_cursorspeed)&1));
601 if (v > con_notifylines)
609 Draws the console with the solid background
610 The typing input line at the bottom should only be drawn if typing is allowed
613 void Con_DrawConsole (int lines, qboolean drawinput)
623 // draw the background
624 Draw_ConsoleBackground (lines);
627 con_vislines = lines;
629 rows = (lines-16)>>3; // rows of text to draw
630 y = lines - 16 - (rows<<3); // may start slightly negative
632 for (i= con_current - rows + 1 ; i<=con_current ; i++, y+=8 )
634 j = i - con_backscroll;
637 text = con_text + (j % con_totallines)*con_linewidth;
639 // for (x=0 ; x<con_linewidth ; x++)
640 // Draw_Character ( (x+1)<<3, y, text[x]);
641 // LordHavoc: speedup
642 Draw_String(8, y, text, con_linewidth);
645 // draw the input prompt, user text, and cursor if desired