1
2 /* M_misc.c */
3
4 #ifdef __NeXT__
5 #include <libc.h>
6 #else
7
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 #include <fcntl.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <assert.h>
14 #endif
15
16 #include <ctype.h>
17
18 #include "doomdef.h"
19 #include "soundst.h"
20
21 int myargc;
22 char **myargv;
23
24 extern char* gl_Driver;
25 long do_fullscreen;
26 long do_grabMouse;
27
28 /*
29 //---------------------------------------------------------------------------
30 //
31 // FUNC M_ValidEpisodeMap
32 //
33 //---------------------------------------------------------------------------
34 */
M_ValidEpisodeMap(int episode,int map)35 boolean M_ValidEpisodeMap(int episode, int map)
36 {
37 if(episode < 1
38 || map < 1
39 || map > 9)
40 {
41 return false;
42 }
43 if(shareware)
44 { /* Shareware version checks */
45 if(episode != 1)
46 {
47 return false;
48 }
49 }
50 else if(ExtendedWAD)
51 { /* Extended version checks */
52 if(episode == 6)
53 {
54 if(map > 3)
55 {
56 return false;
57 }
58 }
59 else if(episode > 5)
60 {
61 return false;
62 }
63 }
64 else
65 { /* Registered version checks */
66 if(episode == 4)
67 {
68 if(map != 1)
69 {
70 return false;
71 }
72 }
73 else if(episode > 3)
74 {
75 return false;
76 }
77 }
78 return true;
79 }
80
81 /*
82 =================
83 =
84 = M_CheckParm
85 =
86 = Checks for the given parameter in the program's command line arguments
87 =
88 = Returns the argument number (1 to argc-1) or 0 if not present
89 =
90 =================
91 */
92
M_CheckParm(char * check)93 int M_CheckParm (char *check)
94 {
95 int i;
96
97 for (i = 1;i<myargc;i++)
98 {
99 if ( !strcasecmp(check, myargv[i]) )
100 return i;
101 }
102
103 return 0;
104 }
105
106
107
108 /*
109 ===============
110 =
111 = M_Random
112 =
113 = Returns a 0-255 number
114 =
115 ===============
116 */
117
118 unsigned char rndtable[256] = {
119 0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66,
120 74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36,
121 95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188,
122 52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224,
123 149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242,
124 145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0,
125 175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235,
126 25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113,
127 94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75,
128 136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196,
129 135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113,
130 80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241,
131 24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224,
132 145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95,
133 28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226,
134 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36,
135 17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106,
136 197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136,
137 120, 163, 236, 249
138 };
139 int rndindex = 0;
140 int prndindex = 0;
141
P_Random(void)142 int P_Random (void)
143 {
144 prndindex = (prndindex+1)&0xff;
145 return rndtable[prndindex];
146 }
147
M_Random(void)148 int M_Random (void)
149 {
150 rndindex = (rndindex+1)&0xff;
151 return rndtable[rndindex];
152 }
153
M_ClearRandom(void)154 void M_ClearRandom (void)
155 {
156 rndindex = prndindex = 0;
157 }
158
159
M_ClearBox(fixed_t * box)160 void M_ClearBox (fixed_t *box)
161 {
162 box[BOXTOP] = box[BOXRIGHT] = MININT;
163 box[BOXBOTTOM] = box[BOXLEFT] = MAXINT;
164 }
165
M_AddToBox(fixed_t * box,fixed_t x,fixed_t y)166 void M_AddToBox (fixed_t *box, fixed_t x, fixed_t y)
167 {
168 if (x<box[BOXLEFT])
169 box[BOXLEFT] = x;
170 else if (x>box[BOXRIGHT])
171 box[BOXRIGHT] = x;
172 if (y<box[BOXBOTTOM])
173 box[BOXBOTTOM] = y;
174 else if (y>box[BOXTOP])
175 box[BOXTOP] = y;
176 }
177
178
179
180 /*
181 ==================
182 =
183 = M_WriteFile
184 =
185 ==================
186 */
187
188 #ifndef O_BINARY
189 #define O_BINARY 0
190 #endif
191
M_WriteFile(char const * name,void * source,int length)192 boolean M_WriteFile (char const *name, void *source, int length)
193 {
194 int handle, count;
195
196 handle = open (name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
197 if (handle == -1)
198 return false;
199 count = write (handle, source, length);
200 close (handle);
201
202 if (count < length)
203 return false;
204
205 return true;
206 }
207
208
209 /*
210 ==================
211 =
212 = M_ReadFile
213 =
214 ==================
215 */
216
M_ReadFile(char const * name,byte ** buffer)217 int M_ReadFile (char const *name, byte **buffer)
218 {
219 int handle, count, length;
220 struct stat fileinfo;
221 byte *buf;
222
223 handle = open (name, O_RDONLY | O_BINARY, 0666);
224 if (handle == -1)
225 I_Error ("Couldn't read file %s", name);
226 if (fstat (handle,&fileinfo) == -1)
227 I_Error ("Couldn't read file %s", name);
228 length = fileinfo.st_size;
229 buf = Z_Malloc (length, PU_STATIC, NULL);
230 count = read (handle, buf, length);
231 close (handle);
232
233 if (count < length)
234 I_Error ("Couldn't read file %s", name);
235
236 *buffer = buf;
237 return length;
238 }
239
240
241 /*
242 //---------------------------------------------------------------------------
243 //
244 // PROC M_FindResponseFile
245 //
246 //---------------------------------------------------------------------------
247 */
248 #define MAXARGVS 100
249
M_FindResponseFile(void)250 void M_FindResponseFile(void)
251 {
252 int i;
253
254 for(i = 1; i < myargc; i++)
255 {
256 if(myargv[i][0] == '@')
257 {
258 FILE *handle;
259 int size;
260 int k;
261 int index;
262 int indexinfile;
263 char *infile;
264 char *file;
265 char *moreargs[20];
266 char *firstargv;
267
268 /* READ THE RESPONSE FILE INTO MEMORY */
269 handle = fopen(&myargv[i][1], "rb");
270 if(!handle)
271 {
272 printf("\nNo such response file!");
273 exit(1);
274 }
275 printf("Found response file %s!\n",&myargv[i][1]);
276 fseek (handle,0,SEEK_END);
277 size = ftell(handle);
278 fseek (handle,0,SEEK_SET);
279 file = malloc (size);
280 assert(file);
281 fread (file,size,1,handle);
282 fclose (handle);
283
284 /* KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG */
285 for (index = 0,k = i+1; k < myargc; k++)
286 moreargs[index++] = myargv[k];
287
288 firstargv = myargv[0];
289 myargv = malloc(sizeof(char *)*MAXARGVS);
290 assert(myargv);
291 memset(myargv,0,sizeof(char *)*MAXARGVS);
292 myargv[0] = firstargv;
293
294 infile = file;
295 indexinfile = k = 0;
296 indexinfile++; /* SKIP PAST ARGV[0] (KEEP IT) */
297 do
298 {
299 myargv[indexinfile++] = infile+k;
300 while(k < size &&
301
302 ((*(infile+k)>= ' '+1) && (*(infile+k)<='z')))
303 k++;
304 *(infile+k) = 0;
305 while(k < size &&
306 ((*(infile+k)<= ' ') || (*(infile+k)>'z')))
307 k++;
308 } while(k < size);
309
310 for (k = 0;k < index;k++)
311 myargv[indexinfile++] = moreargs[k];
312 myargc = indexinfile;
313 /* DISPLAY ARGS */
314 if(M_CheckParm("-debug"))
315 {
316 printf("%d command-line args:\n", myargc);
317 for(k = 1; k < myargc; k++)
318 {
319 printf("%s\n", myargv[k]);
320 }
321 }
322 break;
323 }
324 }
325 }
326
327
328 /*
329 //---------------------------------------------------------------------------
330 //
331 // PROC M_ForceUppercase
332 //
333 // Change string to uppercase.
334 //
335 //---------------------------------------------------------------------------
336 */
M_ForceUppercase(char * text)337 void M_ForceUppercase(char *text)
338 {
339 char c;
340
341 while((c = *text) != 0)
342 {
343 if(c >= 'a' && c <= 'z')
344 {
345 *text++ = c-('a'-'A');
346 }
347 else
348 {
349 text++;
350 }
351 }
352 }
353
354 /*
355 ==============================================================================
356
357 DEFAULTS
358
359 ==============================================================================
360 */
361
362 long usemouse;
363 long usejoystick;
364
365 extern long key_right, key_left, key_up, key_down;
366 extern long key_strafeleft, key_straferight;
367 extern long key_fire, key_use, key_strafe, key_speed;
368 extern long key_health, key_tomeofpower, key_egg, key_firebomb;
369 extern long key_flyup, key_flydown, key_flycenter;
370 extern long key_lookup, key_lookdown, key_lookcenter;
371 extern long key_invleft, key_invright, key_useartifact;
372
373 extern long mousebfire;
374 extern long mousebstrafe;
375 extern long mousebforward;
376
377 extern long joybfire;
378 extern long joybstrafe;
379 extern long joybuse;
380 extern long joybspeed;
381
382 extern int viewwidth, viewheight;
383
384 /* rhandeev: differentiated mouse X and Y sensitivity */
385 long mouseXSensitivity;
386 long mouseYSensitivity;
387
388 /* rhandeev: added mouse invert and mouse look features */
389 long mouseInvert;
390 long mouseLook;
391
392 extern long screenblocks;
393
394 extern char *chat_macros[10];
395
396 #ifdef GL_HERETIC
397 extern long usecoronas;
398 extern long g_bMD2;
399 extern long g_bMD2Light, g_bDynLight, g_bSmoothSprite, g_bMonsterLight, g_bPlayerLight;
400 /* extern H_boolean g_bMD2Interpol; */
401 extern long g_iMaxImpacts;
402 #endif
403
404 typedef struct
405 {
406 char *name;
407 long *location;
408 long defaultvalue;
409 int scantranslate; /* PC scan code hack */
410 int untranslated; /* lousy hack */
411 } default_t;
412
413 extern long numChannels;
414
415 #ifdef __DOSOUND__
416 extern long mb_used;
417 #endif
418
419 #if defined(__DOSOUND__) || defined(__DOMUSIC__)
420 #include "i_sound.h"
421 #endif
422
423 #ifdef LINUX_MOUSE
424 char* mousetype;
425 char* mousedev;
426 #endif
427
428 #ifndef __NeXT__
429 extern long numChannels;
430 extern int snd_DesiredMusicDevice, snd_DesiredSfxDevice;
431 extern int snd_MusicDevice, /* current music card # (index to dmxCodes) */
432 snd_SfxDevice; /* current sfx card # (index to dmxCodes) */
433
434 extern int snd_SBport, snd_SBirq, snd_SBdma; /* sound blaster variables */
435 extern int snd_Mport; /* midi variables */
436 #endif
437
438 default_t defaults[] =
439 {
440
441 #ifdef UNIX
442 { "key_right", &key_right, KEY_RIGHTARROW },
443 { "key_left", &key_left, KEY_LEFTARROW },
444 { "key_up", &key_up, KEY_UPARROW },
445 { "key_down", &key_down, KEY_DOWNARROW },
446 { "key_strafeleft", &key_strafeleft, ',' },
447 { "key_straferight", &key_straferight, '.' },
448
449 { "key_fire", &key_fire, KEY_RCTRL, 1 },
450 { "key_use", &key_use, ' ', 1 },
451 { "key_health", &key_health, 'a' },
452 { "key_tomeofpower", &key_tomeofpower, 127},
453 { "key_egg", &key_egg, 'q'},
454 { "key_firebomb", &key_firebomb, 'b'},
455 { "key_strafe", &key_strafe, KEY_RALT, 1 },
456 { "key_speed", &key_speed, KEY_RSHIFT, 1 },
457
458 { "key_flyup", &key_flyup, KEY_PAGEUP },
459 { "key_flydown", &key_flydown, KEY_INSERT },
460 { "key_flycenter", &key_flycenter, KEY_HOME },
461 { "key_lookup", &key_lookup, KEY_PAGEDOWN },
462 { "key_lookdown", &key_lookdown, KEY_DELETE },
463 { "key_lookcenter", &key_lookcenter, KEY_END },
464
465 #ifdef ORIG_INVKEYS
466 { "key_invleft", &key_invleft, '[' },
467 { "key_invright", &key_invright, ']' },
468 #else
469 { "key_invleft", &key_invleft, 'k' },
470 { "key_invright", &key_invright, 'l' },
471 #endif
472
473 { "key_useartifact", &key_useartifact, KEY_ENTER },
474
475 #ifdef SNDSERV
476 {"sndserver", (long *) &sndserver_filename, (long) "sndserver"},
477 {"sndopts", (long *) &sndserver_options, (long) "-quiet"},
478 #endif
479 #ifdef __DOSOUND__
480 {"mb_used", &mb_used, 2},
481 #endif
482 #ifdef MUSSERV
483 {"musserver", (long *) &musserver_filename, (long) "musserver"},
484 {"musopts", (long *) &musserver_options, (long) ""},
485 #endif
486 #endif
487
488 #ifdef LINUX_MOUSE
489 {"mousedev", (long *)&mousedev, (long) "/dev/mouse"},
490 {"mousetype", (long *)&mousetype, (long) "microsoft"},
491 #endif
492
493 { "use_mouse", &usemouse, 1 },
494 { "mouseb_fire", &mousebfire, 0 },
495 { "mouseb_strafe", &mousebstrafe, 1 },
496 { "mouseb_forward", &mousebforward, 2 },
497
498 { "mouse_sensitivity", &mouseXSensitivity, 5 },
499 /* rhandeev: added mouse Y sensitivity default */
500 { "mouse_ysensitivity", &mouseYSensitivity, 5 },
501 /* rhandeev: added mouseLook, mouseInvert defaults */
502 { "mouse_look", &mouseLook, 1 },
503 { "mouse_invert", &mouseInvert, 0 },
504 {"grabMouse", &do_grabMouse, 1},
505
506 { "use_joystick", &usejoystick, 0 },
507 { "joyb_fire", &joybfire, 0 },
508 { "joyb_strafe", &joybstrafe, 1 },
509 { "joyb_use", &joybuse, 3 },
510 { "joyb_speed", &joybspeed, 2 },
511
512 { "screenblocks", &screenblocks, 10 },
513
514 { "snd_channels", &numChannels, 3 },
515
516 #ifdef GL_HERETIC
517 { "usegamma", &usegamma, 5 },
518 #else
519 { "usegamma", &usegamma, 1 },
520 #endif
521
522 {"fullscreen", &do_fullscreen, 1},
523
524 #ifdef GL_HERETIC
525 {"smoothsprites", &g_bSmoothSprite, 0},
526 {"usecoronas", &usecoronas, 1},
527 {"useMD2", &g_bMD2, 0},
528 {"dynamiclighting", &g_bDynLight, 2},
529 {"MD2lighting", &g_bMD2Light, 2},
530 {"monsterlighting", &g_bMonsterLight,1},
531 {"playerlighting", &g_bPlayerLight,1},
532 /* {"MD2interpolated", &g_bMD2Interpol,1}, */
533 {"MaxImpacts", &g_iMaxImpacts,10},
534 {"gl_driver", (long *)&gl_Driver, (long) "libGL.so"},
535 #endif
536
537 { "chatmacro0", (long *) &chat_macros[0], (long) HUSTR_CHATMACRO0 },
538 { "chatmacro1", (long *) &chat_macros[1], (long) HUSTR_CHATMACRO1 },
539 { "chatmacro2", (long *) &chat_macros[2], (long) HUSTR_CHATMACRO2 },
540 { "chatmacro3", (long *) &chat_macros[3], (long) HUSTR_CHATMACRO3 },
541 { "chatmacro4", (long *) &chat_macros[4], (long) HUSTR_CHATMACRO4 },
542 { "chatmacro5", (long *) &chat_macros[5], (long) HUSTR_CHATMACRO5 },
543 { "chatmacro6", (long *) &chat_macros[6], (long) HUSTR_CHATMACRO6 },
544 { "chatmacro7", (long *) &chat_macros[7], (long) HUSTR_CHATMACRO7 },
545 { "chatmacro8", (long *) &chat_macros[8], (long) HUSTR_CHATMACRO8 },
546 { "chatmacro9", (long *) &chat_macros[9], (long) HUSTR_CHATMACRO9 }
547 };
548
549 int numdefaults;
550 char *defaultfile;
551
552 /*
553 ==============
554 =
555 = M_SaveDefaults
556 =
557 ==============
558 */
559
M_SaveDefaults(void)560 void M_SaveDefaults (void)
561 {
562 int i,v;
563 FILE *f;
564
565 f = fopen (defaultfile, "w");
566 if (!f)
567 return; /* can't write the file, but don't complain */
568
569 for (i=0 ; i<numdefaults ; i++)
570 {
571 if (defaults[i].defaultvalue > -0xfff
572 && defaults[i].defaultvalue < 0xfff)
573 {
574 v = *defaults[i].location;
575 fprintf (f,"%s\t\t%i\n",defaults[i].name,v);
576 } else {
577 fprintf (f,"%s\t\t\"%s\"\n",defaults[i].name,
578 * (char **) (defaults[i].location));
579 }
580 }
581
582 fclose (f);
583 }
584
585
586 /*
587 ==============
588 =
589 = M_LoadDefaults
590 =
591 ==============
592 */
593
594 extern byte scantokey[128];
595 extern char *basedefault;
596
M_LoadDefaults(void)597 void M_LoadDefaults (void)
598 {
599 int i, len;
600 FILE *f;
601 char def[80];
602 char strparm[100];
603 /* changed from char *newstring */
604 char *newstring=NULL;
605 int parm;
606 boolean isstring;
607
608 /*
609 * set everything to base values
610 */
611 numdefaults = sizeof(defaults)/sizeof(defaults[0]);
612 for (i=0 ; i<numdefaults ; i++)
613 *defaults[i].location = defaults[i].defaultvalue;
614
615 /*
616 * check for a custom default file
617 */
618 i = M_CheckParm("-config");
619 if(i && i<myargc-1)
620 {
621 defaultfile = myargv[i+1];
622 printf("default file: %s\n", defaultfile);
623 }
624 else
625 defaultfile = basedefault;
626
627 /*
628 * read the file in, overriding any set defaults
629 */
630 fprintf(stdout, "opening basedefault: %s\n", defaultfile);
631 f = fopen (defaultfile, "r");
632 if (f)
633 {
634 while (!feof(f))
635 {
636 isstring = false;
637 if (fscanf (f, "%79s %[^\n]\n", def, strparm) == 2)
638 {
639 if (strparm[0] == '"')
640 {
641 /* get a string default */
642 isstring = true;
643 len = strlen(strparm);
644 newstring = (char *) malloc(len);
645 assert(newstring);
646 strparm[len-1] = 0;
647 strcpy(newstring, strparm+1);
648 }
649 else if (strparm[0] == '0' && strparm[1] == 'x')
650 sscanf(strparm+2, "%x", &parm);
651 else
652 sscanf(strparm, "%i", &parm);
653 for (i=0 ; i<numdefaults ; i++)
654 if (!strcmp(def, defaults[i].name))
655 {
656 if (!isstring)
657 *defaults[i].location = parm;
658 else
659 *defaults[i].location =
660 (long) newstring;
661 break;
662 }
663 }
664 }
665
666 fclose (f);
667 }
668 }
669
670
671 /*
672 ==============================================================================
673
674 SCREEN SHOTS
675
676 ==============================================================================
677 */
678
679
680 typedef struct
681 {
682 char manufacturer;
683 char version;
684 char encoding;
685 char bits_per_pixel;
686 unsigned short xmin,ymin,xmax,ymax;
687 unsigned short hres,vres;
688 unsigned char palette[48];
689 char reserved;
690 char color_planes;
691 unsigned short bytes_per_line;
692 unsigned short palette_type;
693 char filler[58];
694 unsigned char data; /* unbounded */
695 } pcx_t;
696
697 /*
698 ==============
699 =
700 = WritePCXfile
701 =
702 ==============
703 */
704
WritePCXfile(char * filename,byte * data,int width,int height,byte * palette)705 void WritePCXfile (char *filename, byte *data, int width, int height, byte *palette)
706 {
707 int i, length;
708 pcx_t *pcx;
709 byte *pack;
710
711 pcx = Z_Malloc (width*height*2+1000, PU_STATIC, NULL);
712
713 pcx->manufacturer = 0x0a; /* PCX id */
714 pcx->version = 5; /* 256 color */
715 pcx->encoding = 1; /* uncompressed */
716 pcx->bits_per_pixel = 8; /* 256 color */
717 pcx->xmin = 0;
718 pcx->ymin = 0;
719 pcx->xmax = SHORT(width-1);
720 pcx->ymax = SHORT(height-1);
721 pcx->hres = SHORT(width);
722 pcx->vres = SHORT(height);
723 memset (pcx->palette,0,sizeof(pcx->palette));
724 pcx->color_planes = 1; /* chunky image */
725 pcx->bytes_per_line = SHORT(width);
726 pcx->palette_type = SHORT(2); /* not a grey scale */
727 memset (pcx->filler,0,sizeof(pcx->filler));
728
729 /*
730 * pack the image
731 */
732 pack = &pcx->data;
733
734 for (i=0 ; i<width*height ; i++)
735 if ( (*data & 0xc0) != 0xc0)
736 *pack++ = *data++;
737 else
738 {
739 *pack++ = 0xc1;
740 *pack++ = *data++;
741 }
742
743 /*
744 * write the palette
745 */
746 *pack++ = 0x0c; /* palette ID byte */
747 for (i=0 ; i<768 ; i++)
748 *pack++ = *palette++;
749
750 /*
751 * write output file
752 */
753 length = pack - (byte *)pcx;
754 M_WriteFile (filename, pcx, length);
755
756 Z_Free (pcx);
757 }
758
759
760 /* ============================================================================== */
761
762 /*
763 ==================
764 =
765 = M_ScreenShot
766 =
767 ==================
768 */
769
770 #ifdef GL_HERETIC
771 extern void GL_ScreenShot(void);
772 #endif
773
M_ScreenShot(void)774 void M_ScreenShot (void)
775 {
776 #ifndef GL_HERETIC
777 int i;
778 byte *linear;
779 char lbmname[12];
780 byte *pal;
781
782
783 /*
784 * munge planar buffer to linear
785 */
786
787 linear = screen;
788
789 /*
790 * find a file name to save it to
791 */
792 strcpy(lbmname,"HRTIC00.pcx");
793
794 for (i=0 ; i<=99 ; i++)
795 {
796 lbmname[5] = i/10 + '0';
797 lbmname[6] = i%10 + '0';
798 if (access(lbmname,0) == -1)
799 break; /* file doesn't exist */
800 }
801 if (i==100)
802 I_Error ("M_ScreenShot: Couldn't create a PCX");
803
804 /*
805 * save the pcx file
806 */
807
808 pal = (byte *)W_CacheLumpName("PLAYPAL", PU_CACHE);
809
810 WritePCXfile (lbmname, linear, screenwidth, screenheight
811 , pal);
812
813 players[consoleplayer].message = "SCREEN SHOT";
814 #else
815 players[consoleplayer].message = "SCREEN SHOT";
816 GL_ScreenShot();
817 #endif /* GL_HERETIC */
818 }
819
820
821
822