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
92 key_dest = key_console;
94 // SCR_EndLoadingPlaque ();
95 memset (con_times, 0, sizeof(con_times));
103 void Con_Clear_f (void)
106 memset (con_text, ' ', CON_TEXTSIZE);
115 void Con_ClearNotify (void)
119 for (i=0 ; i<NUM_CON_TIMES ; i++)
129 extern qboolean team_message;
131 void Con_MessageMode_f (void)
133 key_dest = key_message;
134 team_message = false;
143 void Con_MessageMode2_f (void)
145 key_dest = key_message;
154 If the line width has changed, reformat the buffer.
157 void Con_CheckResize (void)
159 int i, j, width, oldwidth, oldtotallines, numlines, numchars;
160 char tbuf[CON_TEXTSIZE];
162 width = (vid.width >> 3) - 2;
164 if (width == con_linewidth)
167 if (width < 1) // video hasn't been initialized yet
169 width = 78; // LordHavoc: changed from 38 to 78 (320 -> 640 conversion)
170 con_linewidth = width;
171 con_totallines = CON_TEXTSIZE / con_linewidth;
172 memset (con_text, ' ', CON_TEXTSIZE);
176 oldwidth = con_linewidth;
177 con_linewidth = width;
178 oldtotallines = con_totallines;
179 con_totallines = CON_TEXTSIZE / con_linewidth;
180 numlines = oldtotallines;
182 if (con_totallines < numlines)
183 numlines = con_totallines;
187 if (con_linewidth < numchars)
188 numchars = con_linewidth;
190 memcpy (tbuf, con_text, CON_TEXTSIZE);
191 memset (con_text, ' ', CON_TEXTSIZE);
193 for (i=0 ; i<numlines ; i++)
195 for (j=0 ; j<numchars ; j++)
197 con_text[(con_totallines - 1 - i) * con_linewidth + j] =
198 tbuf[((con_current - i + oldtotallines) %
199 oldtotallines) * oldwidth + j];
207 con_current = con_totallines - 1;
218 #define MAXGAMEDIRLEN 1000
219 char temp[MAXGAMEDIRLEN+1];
220 char *t2 = "/qconsole.log";
222 Cvar_RegisterVariable(&logfile);
223 con_debuglog = COM_CheckParm("-condebug");
227 if (strlen (com_gamedir) < (MAXGAMEDIRLEN - strlen (t2)))
229 sprintf (temp, "%s%s", com_gamedir, t2);
235 con_text = Hunk_AllocName (CON_TEXTSIZE, "context");
236 memset (con_text, ' ', CON_TEXTSIZE);
240 Con_Printf ("Console initialized.\n");
243 // register our commands
245 Cvar_RegisterVariable (&con_notifytime);
247 Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f);
248 Cmd_AddCommand ("messagemode", Con_MessageMode_f);
249 Cmd_AddCommand ("messagemode2", Con_MessageMode2_f);
250 Cmd_AddCommand ("clear", Con_Clear_f);
251 con_initialized = true;
260 void Con_Linefeed (void)
264 memset (&con_text[(con_current%con_totallines)*con_linewidth]
265 , ' ', con_linewidth);
272 Handles cursor positioning, line wrapping, etc
273 All console printing must go through this in order to be logged to disk
274 If no console is visible, the notify window will pop up.
277 void Con_Print (char *txt)
288 mask = 128; // go to colored text
289 S_LocalSound ("misc/talk.wav");
293 else if (txt[0] == 2)
295 mask = 128; // go to colored text
305 for (l=0 ; l< con_linewidth ; l++)
310 if (l != con_linewidth && (con_x + l > con_linewidth) )
325 // mark time for transparent overlay
326 if (con_current >= 0)
327 con_times[con_current % NUM_CON_TIMES] = realtime;
341 default: // display character and advance
342 y = con_current % con_totallines;
343 con_text[y*con_linewidth+con_x] = c | mask;
345 if (con_x >= con_linewidth)
359 void Con_DebugLog(char *file, char *fmt, ...)
362 static char data[1024];
365 va_start(argptr, fmt);
366 vsprintf(data, fmt, argptr);
368 fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);
369 write(fd, data, strlen(data));
378 Handles cursor positioning, line wrapping, etc
381 // LordHavoc: increased from 4096 to 16384
382 #define MAXPRINTMSG 16384
383 // FIXME: make a buffer size safe vsprintf?
384 void Con_Printf (char *fmt, ...)
387 char msg[MAXPRINTMSG];
388 // static qboolean inupdate;
390 va_start (argptr,fmt);
391 vsprintf (msg,fmt,argptr);
394 // also echo to debugging console
395 Sys_Printf ("%s", msg); // also echo to debugging console
397 // log all messages to file
399 Con_DebugLog(va("%s/qconsole.log",com_gamedir), "%s", msg);
401 if (!con_initialized)
404 if (cls.state == ca_dedicated)
405 return; // no graphics mode
407 // write it to the scrollable buffer
410 // update the screen if the console is displayed
411 // LordHavoc: I don't think there's a real need for this
413 // LordHavoc: don't print text while loading scripts
414 if (cls.state != ca_disconnected)
415 if (cls.signon != SIGNONS && !scr_disabled_for_loading )
417 // protect against infinite loop if something in SCR_UpdateScreen calls
433 A Con_Printf that only shows up if the "developer" cvar is set
436 void Con_DPrintf (char *fmt, ...)
439 char msg[MAXPRINTMSG];
441 if (!developer.value)
442 return; // don't confuse non-developers with techie stuff...
444 va_start (argptr,fmt);
445 vsprintf (msg,fmt,argptr);
448 Con_Printf ("%s", msg);
456 Okay to call even when the screen can't be updated
459 void Con_SafePrintf (char *fmt, ...)
465 va_start (argptr,fmt);
466 vsprintf (msg,fmt,argptr);
469 temp = scr_disabled_for_loading;
470 scr_disabled_for_loading = true;
471 Con_Printf ("%s", msg);
472 scr_disabled_for_loading = temp;
477 ==============================================================================
481 ==============================================================================
489 The input line scrolls horizontally if typing goes beyond the right edge
492 void Con_DrawInput (void)
497 if (key_dest != key_console && !con_forcedup)
498 return; // don't draw anything
500 text = key_lines[edit_line];
502 // add the cursor frame
503 text[key_linepos] = 10+((int)(realtime*con_cursorspeed)&1);
505 text[key_linepos+1] = 0; // LordHavoc: null terminate, rather than padding with spaces
506 // fill out remainder with spaces
507 // for (i=key_linepos+1 ; i< con_linewidth ; i++)
510 // prestep if horizontally scrolling
511 if (key_linepos >= con_linewidth)
512 text += 1 + key_linepos - con_linewidth;
517 // for (i=0 ; i<con_linewidth ; i++)
518 // Draw_Character ( (i+1)<<3, con_vislines - 16, text[i]);
519 // LordHavoc: speedup
520 Draw_String(8, con_vislines - 16, text, con_linewidth);
523 key_lines[edit_line][key_linepos] = 0;
531 Draws the last few lines of output transparently over the game top
534 void Con_DrawNotify (void)
540 extern char chat_buffer[];
544 for (i= con_current-NUM_CON_TIMES+1 ; i<=con_current ; i++)
548 time = con_times[i % NUM_CON_TIMES];
551 time = realtime - time;
552 if (time > con_notifytime.value)
554 text = con_text + (i % con_totallines)*con_linewidth;
558 // for (x = 0 ; x < con_linewidth ; x++)
559 // Draw_Character ( (x+1)<<3, v, text[x]);
560 // LordHavoc: speedup
561 Draw_String(8, v, text, con_linewidth);
567 if (key_dest == key_message)
573 // LordHavoc: speedup, and other improvements
575 sprintf(temptext, "say_team:%s%c", chat_buffer, (int) 10+((int)(realtime*con_cursorspeed)&1));
577 sprintf(temptext, "say:%s%c", chat_buffer, (int) 10+((int)(realtime*con_cursorspeed)&1));
578 while (strlen(temptext) >= con_linewidth)
580 Draw_String (8, v, temptext, con_linewidth);
581 strcpy(temptext, &temptext[con_linewidth]);
584 if (strlen(temptext) > 0)
586 Draw_String (8, v, temptext, 0);
589 // Draw_String (8, v, "say:", 0);
590 // while(chat_buffer[x])
592 // Draw_Character ( (x+5)<<3, v, chat_buffer[x]);
595 // Draw_Character ( (x+5)<<3, v, 10+((int)(realtime*con_cursorspeed)&1));
599 if (v > con_notifylines)
607 Draws the console with the solid background
608 The typing input line at the bottom should only be drawn if typing is allowed
611 void Con_DrawConsole (int lines, qboolean drawinput)
621 // draw the background
622 Draw_ConsoleBackground (lines);
625 con_vislines = lines;
627 rows = (lines-16)>>3; // rows of text to draw
628 y = lines - 16 - (rows<<3); // may start slightly negative
630 for (i= con_current - rows + 1 ; i<=con_current ; i++, y+=8 )
632 j = i - con_backscroll;
635 text = con_text + (j % con_totallines)*con_linewidth;
637 // for (x=0 ; x<con_linewidth ; x++)
638 // Draw_Character ( (x+1)<<3, y, text[x]);
639 // LordHavoc: speedup
640 Draw_String(8, y, text, con_linewidth);
643 // draw the input prompt, user text, and cursor if desired