summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/quake/console.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/progs/quake/console.c')
-rw-r--r--apps/plugins/sdl/progs/quake/console.c644
1 files changed, 644 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/console.c b/apps/plugins/sdl/progs/quake/console.c
new file mode 100644
index 0000000000..59c7de368c
--- /dev/null
+++ b/apps/plugins/sdl/progs/quake/console.c
@@ -0,0 +1,644 @@
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20// console.c
21
22#include "quakedef.h"
23
24int con_linewidth;
25
26float con_cursorspeed = 4;
27
28#define CON_TEXTSIZE 16384
29
30qboolean con_forcedup; // because no entities to refresh
31
32int con_totallines; // total lines in console scrollback
33int con_backscroll; // lines up from bottom to display
34int con_current; // where next message will be printed
35int con_x; // offset in current line for next print
36char *con_text=0;
37
38cvar_t con_notifytime = {"con_notifytime","3"}; //seconds
39
40#define NUM_CON_TIMES 4
41float con_times[NUM_CON_TIMES]; // realtime time the line was generated
42 // for transparent notify lines
43
44int con_vislines;
45
46qboolean con_debuglog;
47
48#define MAXCMDLINE 256
49extern char key_lines[32][MAXCMDLINE];
50extern int edit_line;
51extern int key_linepos;
52
53
54qboolean con_initialized;
55
56int con_notifylines; // scan lines to clear for notify lines
57
58extern void M_Menu_Main_f (void);
59
60/*
61================
62Con_ToggleConsole_f
63================
64*/
65void Con_ToggleConsole_f (void)
66{
67 if (key_dest == key_console)
68 {
69 if (cls.state == ca_connected)
70 {
71 key_dest = key_game;
72 key_lines[edit_line][1] = 0; // clear any typing
73 key_linepos = 1;
74 }
75 else
76 {
77 M_Menu_Main_f ();
78 }
79 }
80 else
81 key_dest = key_console;
82
83 SCR_EndLoadingPlaque ();
84 memset (con_times, 0, sizeof(con_times));
85}
86
87/*
88================
89Con_Clear_f
90================
91*/
92void Con_Clear_f (void)
93{
94 if (con_text)
95 Q_memset (con_text, ' ', CON_TEXTSIZE);
96}
97
98
99/*
100================
101Con_ClearNotify
102================
103*/
104void Con_ClearNotify (void)
105{
106 int i;
107
108 for (i=0 ; i<NUM_CON_TIMES ; i++)
109 con_times[i] = 0;
110}
111
112
113/*
114================
115Con_MessageMode_f
116================
117*/
118extern qboolean team_message;
119
120void Con_MessageMode_f (void)
121{
122 key_dest = key_message;
123 team_message = false;
124}
125
126
127/*
128================
129Con_MessageMode2_f
130================
131*/
132void Con_MessageMode2_f (void)
133{
134 key_dest = key_message;
135 team_message = true;
136}
137
138
139/*
140================
141Con_CheckResize
142
143If the line width has changed, reformat the buffer.
144================
145*/
146void Con_CheckResize (void)
147{
148 int i, j, width, oldwidth, oldtotallines, numlines, numchars;
149 char tbuf[CON_TEXTSIZE];
150
151 width = (vid.width >> 3) - 2;
152
153 if (width == con_linewidth)
154 return;
155
156 if (width < 1) // video hasn't been initialized yet
157 {
158 width = 38;
159 con_linewidth = width;
160 con_totallines = CON_TEXTSIZE / con_linewidth;
161 Q_memset (con_text, ' ', CON_TEXTSIZE);
162 }
163 else
164 {
165 oldwidth = con_linewidth;
166 con_linewidth = width;
167 oldtotallines = con_totallines;
168 con_totallines = CON_TEXTSIZE / con_linewidth;
169 numlines = oldtotallines;
170
171 if (con_totallines < numlines)
172 numlines = con_totallines;
173
174 numchars = oldwidth;
175
176 if (con_linewidth < numchars)
177 numchars = con_linewidth;
178
179 Q_memcpy (tbuf, con_text, CON_TEXTSIZE);
180 Q_memset (con_text, ' ', CON_TEXTSIZE);
181
182 for (i=0 ; i<numlines ; i++)
183 {
184 for (j=0 ; j<numchars ; j++)
185 {
186 con_text[(con_totallines - 1 - i) * con_linewidth + j] =
187 tbuf[((con_current - i + oldtotallines) %
188 oldtotallines) * oldwidth + j];
189 }
190 }
191
192 Con_ClearNotify ();
193 }
194
195 con_backscroll = 0;
196 con_current = con_totallines - 1;
197}
198
199
200/*
201================
202Con_Init
203================
204*/
205void Con_Init (void)
206{
207#define MAXGAMEDIRLEN 1000
208 char temp[MAXGAMEDIRLEN+1];
209 char *t2 = "/qconsole.log";
210
211 con_debuglog = COM_CheckParm("-condebug");
212
213 if (con_debuglog)
214 {
215 if (strlen (com_gamedir) < (MAXGAMEDIRLEN - strlen (t2)))
216 {
217 sprintf (temp, "%s%s", com_gamedir, t2);
218 unlink (temp);
219 }
220 }
221
222 con_text = Hunk_AllocName (CON_TEXTSIZE, "context");
223 Q_memset (con_text, ' ', CON_TEXTSIZE);
224 con_linewidth = -1;
225 Con_CheckResize ();
226
227 Con_Printf ("Console initialized.\n");
228
229//
230// register our commands
231//
232 Cvar_RegisterVariable (&con_notifytime);
233
234 Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f);
235 Cmd_AddCommand ("messagemode", Con_MessageMode_f);
236 Cmd_AddCommand ("messagemode2", Con_MessageMode2_f);
237 Cmd_AddCommand ("clear", Con_Clear_f);
238 con_initialized = true;
239}
240
241
242/*
243===============
244Con_Linefeed
245===============
246*/
247void Con_Linefeed (void)
248{
249 if ( ! con_initialized ) return;
250 con_x = 0;
251 con_current++;
252 Q_memset (&con_text[(con_current%con_totallines)*con_linewidth]
253 , ' ', con_linewidth);
254}
255
256/*
257================
258Con_Print
259
260Handles cursor positioning, line wrapping, etc
261All console printing must go through this in order to be logged to disk
262If no console is visible, the notify window will pop up.
263================
264*/
265void Con_Print (char *txt)
266{
267 int y;
268 int c, l;
269 static int cr;
270 int mask;
271
272 if ( ! con_initialized ) return;
273 con_backscroll = 0;
274
275 if (txt[0] == 1)
276 {
277 mask = 128; // go to colored text
278 S_LocalSound ("misc/talk.wav");
279 // play talk wav
280 txt++;
281 }
282 else if (txt[0] == 2)
283 {
284 mask = 128; // go to colored text
285 txt++;
286 }
287 else
288 mask = 0;
289
290
291 while ( (c = *txt) )
292 {
293 // count word length
294 for (l=0 ; l< con_linewidth ; l++)
295 if ( txt[l] <= ' ')
296 break;
297
298 // word wrap
299 if (l != con_linewidth && (con_x + l > con_linewidth) )
300 con_x = 0;
301
302 txt++;
303
304 if (cr)
305 {
306 con_current--;
307 cr = false;
308 }
309
310
311 if (!con_x)
312 {
313 Con_Linefeed ();
314 // mark time for transparent overlay
315 if (con_current >= 0)
316 con_times[con_current % NUM_CON_TIMES] = realtime;
317 }
318
319 switch (c)
320 {
321 case '\n':
322 con_x = 0;
323 break;
324
325 case '\r':
326 con_x = 0;
327 cr = 1;
328 break;
329
330 default: // display character and advance
331 y = con_current % con_totallines;
332 con_text[y*con_linewidth+con_x] = c | mask;
333 con_x++;
334 if (con_x >= con_linewidth)
335 con_x = 0;
336 break;
337 }
338
339 }
340}
341
342
343/*
344================
345Con_DebugLog
346================
347*/
348void Con_DebugLog(char *file, char *fmt, ...)
349{
350 va_list argptr;
351 static char data[1024];
352 int fd;
353
354 va_start(argptr, fmt);
355 vsprintf(data, fmt, argptr);
356 va_end(argptr);
357 fd = rb->open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);
358 rb->write(fd, data, strlen(data));
359 rb->close(fd);
360}
361
362
363/*
364================
365Con_Printf
366
367Handles cursor positioning, line wrapping, etc
368================
369*/
370#define MAXPRINTMSG 4096
371// FIXME: make a buffer size safe vsprintf?
372void Con_Printf (char *fmt, ...)
373{
374 va_list argptr;
375 char msg[MAXPRINTMSG];
376 static qboolean inupdate;
377
378 va_start (argptr,fmt);
379 vsprintf (msg,fmt,argptr);
380 va_end (argptr);
381
382// also echo to debugging console
383 Sys_Printf ("%s", msg); // also echo to debugging console
384
385// log all messages to file
386 if (con_debuglog)
387 Con_DebugLog(va("%s/qconsole.log",com_gamedir), "%s", msg);
388
389 if (!con_initialized)
390 return;
391
392 if (cls.state == ca_dedicated)
393 return; // no graphics mode
394
395// write it to the scrollable buffer
396 Con_Print (msg);
397
398// update the screen if the console is displayed
399 if (cls.signon != SIGNONS && !scr_disabled_for_loading )
400 {
401 // protect against infinite loop if something in SCR_UpdateScreen calls
402 // Con_Printd
403 if (!inupdate)
404 {
405 inupdate = true;
406 SCR_UpdateScreen ();
407 inupdate = false;
408 }
409 }
410}
411
412/*
413================
414Con_DPrintf
415
416A Con_Printf that only shows up if the "developer" cvar is set
417================
418*/
419void Con_DPrintf (char *fmt, ...)
420{
421 va_list argptr;
422 char msg[MAXPRINTMSG];
423
424 if (!developer.value)
425 return; // don't confuse non-developers with techie stuff...
426
427 va_start (argptr,fmt);
428 vsprintf (msg,fmt,argptr);
429 va_end (argptr);
430
431 Con_Printf ("%s", msg);
432}
433
434
435/*
436==================
437Con_SafePrintf
438
439Okay to call even when the screen can't be updated
440==================
441*/
442void Con_SafePrintf (char *fmt, ...)
443{
444 va_list argptr;
445 char msg[1024];
446 int temp;
447
448 va_start (argptr,fmt);
449 vsprintf (msg,fmt,argptr);
450 va_end (argptr);
451
452 temp = scr_disabled_for_loading;
453 scr_disabled_for_loading = true;
454 Con_Printf ("%s", msg);
455 scr_disabled_for_loading = temp;
456}
457
458
459/*
460==============================================================================
461
462DRAWING
463
464==============================================================================
465*/
466
467
468/*
469================
470Con_DrawInput
471
472The input line scrolls horizontally if typing goes beyond the right edge
473================
474*/
475void Con_DrawInput (void)
476{
477 int y;
478 int i;
479 char *text;
480
481 if (key_dest != key_console && !con_forcedup)
482 return; // don't draw anything
483
484 text = key_lines[edit_line];
485
486// add the cursor frame
487 text[key_linepos] = 10+((int)(realtime*con_cursorspeed)&1);
488
489// fill out remainder with spaces
490 for (i=key_linepos+1 ; i< con_linewidth ; i++)
491 text[i] = ' ';
492
493// prestep if horizontally scrolling
494 if (key_linepos >= con_linewidth)
495 text += 1 + key_linepos - con_linewidth;
496
497// draw it
498 y = con_vislines-16;
499
500 for (i=0 ; i<con_linewidth ; i++)
501 Draw_Character ( (i+1)<<3, con_vislines - 16, text[i]);
502
503// remove cursor
504 key_lines[edit_line][key_linepos] = 0;
505}
506
507
508/*
509================
510Con_DrawNotify
511
512Draws the last few lines of output transparently over the game top
513================
514*/
515void Con_DrawNotify (void)
516{
517 int x, v;
518 char *text;
519 int i;
520 float time;
521 extern char chat_buffer[];
522
523 v = 0;
524 for (i= con_current-NUM_CON_TIMES+1 ; i<=con_current ; i++)
525 {
526 if (i < 0)
527 continue;
528 time = con_times[i % NUM_CON_TIMES];
529 if (time == 0)
530 continue;
531 time = realtime - time;
532 if (time > con_notifytime.value)
533 continue;
534 text = con_text + (i % con_totallines)*con_linewidth;
535
536 clearnotify = 0;
537 scr_copytop = 1;
538
539 for (x = 0 ; x < con_linewidth ; x++)
540 Draw_Character ( (x+1)<<3, v, text[x]);
541
542 v += 8;
543 }
544
545
546 if (key_dest == key_message)
547 {
548 clearnotify = 0;
549 scr_copytop = 1;
550
551 x = 0;
552
553 Draw_String (8, v, "say:");
554 while(chat_buffer[x])
555 {
556 Draw_Character ( (x+5)<<3, v, chat_buffer[x]);
557 x++;
558 }
559 Draw_Character ( (x+5)<<3, v, 10+((int)(realtime*con_cursorspeed)&1));
560 v += 8;
561 }
562
563 if (v > con_notifylines)
564 con_notifylines = v;
565}
566
567/*
568================
569Con_DrawConsole
570
571Draws the console with the solid background
572The typing input line at the bottom should only be drawn if typing is allowed
573================
574*/
575void Con_DrawConsole (int lines, qboolean drawinput)
576{
577 int i, x, y;
578 int rows;
579 char *text;
580 int j;
581
582 if (lines <= 0)
583 return;
584
585// draw the background
586 Draw_ConsoleBackground (lines);
587
588// draw the text
589 con_vislines = lines;
590
591 rows = (lines-16)>>3; // rows of text to draw
592 y = lines - 16 - (rows<<3); // may start slightly negative
593
594 for (i= con_current - rows + 1 ; i<=con_current ; i++, y+=8 )
595 {
596 j = i - con_backscroll;
597 if (j<0)
598 j = 0;
599 text = con_text + (j % con_totallines)*con_linewidth;
600
601 for (x=0 ; x<con_linewidth ; x++)
602 Draw_Character ( (x+1)<<3, y, text[x]);
603 }
604
605// draw the input prompt, user text, and cursor if desired
606 if (drawinput)
607 Con_DrawInput ();
608}
609
610
611/*
612==================
613Con_NotifyBox
614==================
615*/
616void Con_NotifyBox (char *text)
617{
618 double t1, t2;
619
620// during startup for sound / cd warnings
621 Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
622
623 Con_Printf (text);
624
625 Con_Printf ("Press a key.\n");
626 Con_Printf("\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
627
628 key_count = -2; // wait for a key down and up
629 key_dest = key_console;
630
631 do
632 {
633 t1 = Sys_FloatTime ();
634 SCR_UpdateScreen ();
635 Sys_SendKeyEvents ();
636 t2 = Sys_FloatTime ();
637 realtime += t2-t1; // make the cursor blink
638 } while (key_count < 0);
639
640 Con_Printf ("\n");
641 key_dest = key_game;
642 realtime = 0; // put the cursor back to invisible
643}
644