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