2 //**************************************************************************
4 //** m_misc.c : Heretic 2 : Raven Software, Corp.
11 //**************************************************************************
13 // HEADER FILES ------------------------------------------------------------
17 #include <unistd.h> /* jim write() read() close() */
23 // MACROS ------------------------------------------------------------------
28 // TYPES -------------------------------------------------------------------
30 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
33 extern void OGL_GrabScreen();
36 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
38 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
40 static int ReadFile(char const *name, byte **buffer, int mallocType);
42 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
43 extern char *SavePath;
45 // PUBLIC DATA DEFINITIONS -------------------------------------------------
50 // PRIVATE DATA DEFINITIONS ------------------------------------------------
52 // CODE --------------------------------------------------------------------
54 //==========================================================================
58 // Checks for the given parameter in the program's command line arguments.
59 // Returns the argument number (1 to argc-1) or 0 if not present.
61 //==========================================================================
63 int M_CheckParm(char *check)
67 for(i = 1; i < myargc; i++)
69 if(!strcasecmp(check, myargv[i]))
77 //==========================================================================
81 // Returns true if the given parameter exists in the program's command
82 // line arguments, false if not.
84 //==========================================================================
86 boolean M_ParmExists(char *check)
88 return M_CheckParm(check) != 0 ? true : false;
91 //==========================================================================
95 //==========================================================================
97 void M_ExtractFileBase(char *path, char *dest)
102 src = path+strlen(path)-1;
104 // Back up until a \ or the start
105 while(src != path && *(src-1) != '\\' && *(src-1) != '/')
110 // Copy up to eight characters
113 while(*src && *src != '.')
117 I_Error("Filename base of %s > 8 chars", path);
119 *dest++ = toupper((int)*src++);
128 = Returns a 0-255 number
134 // This is the new flat distribution table
135 unsigned char rndtable[256] = {
136 201, 1,243, 19, 18, 42,183,203,101,123,154,137, 34,118, 10,216,
137 135,246, 0,107,133,229, 35,113,177,211,110, 17,139, 84,251,235,
138 182,166,161,230,143, 91, 24, 81, 22, 94, 7, 51,232,104,122,248,
139 175,138,127,171,222,213, 44, 16, 9, 33, 88,102,170,150,136,114,
140 62, 3,142,237, 6,252,249, 56, 74, 30, 13, 21,180,199, 32,132,
141 187,234, 78,210, 46,131,197, 8,206,244, 73, 4,236,178,195, 70,
142 121, 97,167,217,103, 40,247,186,105, 39, 95,163, 99,149,253, 29,
143 119, 83,254, 26,202, 65,130,155, 60, 64,184,106,221, 93,164,196,
144 112,108,179,141, 54,109, 11,126, 75,165,191,227, 87,225,156, 15,
145 98,162,116, 79,169,140,190,205,168,194, 41,250, 27, 20, 14,241,
146 50,214, 72,192,220,233, 67,148, 96,185,176,181,215,207,172, 85,
147 89, 90,209,128,124, 2, 55,173, 66,152, 47,129, 59, 43,159,240,
148 239, 12,189,212,144, 28,200, 77,219,198,134,228, 45, 92,125,151,
149 5, 53,255, 52, 68,245,160,158, 61, 86, 58, 82,117, 37,242,145,
150 69,188,115, 76, 63,100, 49,111,153, 80, 38, 57,174,224, 71,231,
151 23, 25, 48,218,120,147,208, 36,226,223,193,238,157,204,146, 31
160 rndindex = (rndindex+1)&0xff;
161 return rndtable[rndindex];
164 void M_ClearRandom (void)
166 rndindex = prndindex = 0;
170 void M_ClearBox (fixed_t *box)
172 box[BOXTOP] = box[BOXRIGHT] = MININT;
173 box[BOXBOTTOM] = box[BOXLEFT] = MAXINT;
176 void M_AddToBox (fixed_t *box, fixed_t x, fixed_t y)
180 else if (x>box[BOXRIGHT])
182 if (y<box[BOXBOTTOM])
184 else if (y>box[BOXTOP])
200 boolean M_WriteFile (char const *name, void *source, int length)
204 handle = open (name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
207 count = write (handle, source, length);
216 //==========================================================================
220 // Read a file into a buffer allocated using Z_Malloc().
222 //==========================================================================
224 int M_ReadFile(char const *name, byte **buffer)
226 return ReadFile(name, buffer, MALLOC_ZONE);
229 //==========================================================================
233 // Read a file into a buffer allocated using malloc().
235 //==========================================================================
237 int M_ReadFileCLib(char const *name, byte **buffer)
239 return ReadFile(name, buffer, MALLOC_CLIB);
242 //==========================================================================
246 //==========================================================================
248 static int ReadFile(char const *name, byte **buffer, int mallocType)
250 int handle, count, length;
251 struct stat fileinfo;
254 handle = open(name, O_RDONLY|O_BINARY, 0666);
257 I_Error("Couldn't read file %s", name);
259 if(fstat(handle, &fileinfo) == -1)
261 I_Error("Couldn't read file %s", name);
263 length = fileinfo.st_size;
264 if(mallocType == MALLOC_ZONE)
265 { // Use zone memory allocation
266 buf = Z_Malloc(length, PU_STATIC, NULL);
269 { // Use c library memory allocation
270 buf = malloc(length);
273 I_Error("Couldn't malloc buffer %d for file %s.",
277 count = read(handle, buf, length);
281 I_Error("Couldn't read file %s", name);
287 //---------------------------------------------------------------------------
289 // PROC M_FindResponseFile
291 //---------------------------------------------------------------------------
295 void M_FindResponseFile(void)
299 for(i = 1; i < myargc; i++)
301 if(myargv[i][0] == '@')
313 // READ THE RESPONSE FILE INTO MEMORY
314 handle = fopen(&myargv[i][1], "rb");
317 printf("\nNo such response file!");
320 ST_Message("Found response file %s!\n",&myargv[i][1]);
321 fseek (handle,0,SEEK_END);
322 size = ftell(handle);
323 fseek (handle,0,SEEK_SET);
324 file = malloc (size);
325 fread (file,size,1,handle);
328 // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG
329 for (index = 0,k = i+1; k < myargc; k++)
330 moreargs[index++] = myargv[k];
332 firstargv = myargv[0];
333 myargv = malloc(sizeof(char *)*MAXARGVS);
334 memset(myargv,0,sizeof(char *)*MAXARGVS);
335 myargv[0] = firstargv;
339 indexinfile++; // SKIP PAST ARGV[0] (KEEP IT)
342 myargv[indexinfile++] = infile+k;
345 ((*(infile+k)>= ' '+1) && (*(infile+k)<='z')))
349 ((*(infile+k)<= ' ') || (*(infile+k)>'z')))
353 for (k = 0;k < index;k++)
354 myargv[indexinfile++] = moreargs[k];
355 myargc = indexinfile;
357 if(M_CheckParm("-debug"))
359 ST_Message("%d command-line args:\n", myargc);
360 for(k = 1; k < myargc; k++)
362 ST_Message("%s\n", myargv[k]);
370 //---------------------------------------------------------------------------
372 // PROC M_ForceUppercase
374 // Change string to uppercase.
376 //---------------------------------------------------------------------------
378 void M_ForceUppercase(char *text)
382 while((c = *text) != 0)
384 if(c >= 'a' && c <= 'z')
386 *text++ = c-('a'-'A');
396 ==============================================================================
400 ==============================================================================
406 extern int mouselook;
407 extern boolean cdaudio;
408 extern boolean alwaysrun;
410 extern int key_right, key_left, key_up, key_down;
411 extern int key_strafeleft, key_straferight, key_jump;
412 extern int key_fire, key_use, key_strafe, key_speed;
413 extern int key_flyup, key_flydown, key_flycenter;
414 extern int key_lookup, key_lookdown, key_lookcenter;
415 extern int key_invleft, key_invright, key_useartifact;
417 extern int mousebfire;
418 extern int mousebstrafe;
419 extern int mousebforward;
420 extern int mousebjump;
423 extern int joybstrafe;
425 extern int joybspeed;
428 extern boolean messageson;
430 extern int viewwidth, viewheight;
432 int mouseSensitivity;
434 extern int screenblocks;
436 extern char *chat_macros[10];
441 extern int snd_Channels;
442 extern int snd_DesiredMusicDevice, snd_DesiredSfxDevice;
443 extern int snd_MusicDevice, // current music card # (index to dmxCodes)
444 snd_SfxDevice; // current sfx card # (index to dmxCodes)
446 extern int snd_SBport, snd_SBirq, snd_SBdma; // sound blaster variables
447 extern int snd_Mport; // midi variables
450 default_t defaults[] =
452 { "mouse_sensitivity", &mouseSensitivity, 5 },
453 { "sfx_volume", &snd_MaxVolume, 10},
454 { "music_volume", &snd_MusicVolume, 10},
456 #define SC_INSERT 0x52
457 #define SC_DELETE 0x53
458 #define SC_PAGEUP 0x49
459 #define SC_PAGEDOWN 0x51
463 { "key_right", &key_right, KEY_RIGHTARROW },
464 { "key_left", &key_left, KEY_LEFTARROW },
465 { "key_up", &key_up, KEY_UPARROW },
466 { "key_down", &key_down, KEY_DOWNARROW },
467 { "key_strafeleft", &key_strafeleft, ',' },
468 { "key_straferight", &key_straferight, '.' },
469 { "key_jump", &key_jump, '/'},
470 { "key_flyup", &key_flyup, SC_PAGEUP },
471 { "key_flydown", &key_flydown, SC_INSERT },
472 { "key_flycenter", &key_flycenter, SC_HOME },
473 { "key_lookup", &key_lookup, SC_PAGEDOWN },
474 { "key_lookdown", &key_lookdown, SC_DELETE },
475 { "key_lookcenter", &key_lookcenter, SC_END },
476 { "key_invleft", &key_invleft, '[' },
477 { "key_invright", &key_invright, ']' },
478 { "key_useartifact", &key_useartifact, 13 },
479 { "key_fire", &key_fire, KEY_RCTRL, 1 },
480 { "key_use", &key_use, ' ', 1 },
481 { "key_strafe", &key_strafe, KEY_RALT, 1 },
482 { "key_speed", &key_speed, KEY_RSHIFT, 1 },
483 { "use_mouse", &usemouse, 1 },
484 { "mouseb_fire", &mousebfire, 0 },
485 { "mouseb_strafe", &mousebstrafe, 1 },
486 { "mouseb_forward", &mousebforward, 2 },
487 { "mouseb_jump", &mousebjump, -1 },
488 { "use_joystick", &usejoystick, 0 },
489 { "joyb_fire", &joybfire, 0 },
490 { "joyb_strafe", &joybstrafe, 1 },
491 { "joyb_use", &joybuse, 3 },
492 { "joyb_speed", &joybspeed, 2 },
493 { "joyb_jump", &joybjump, -1 },
494 { "screenblocks", &screenblocks, 10 },
495 { "snd_channels", &snd_Channels, 3 },
496 { "snd_musicdevice", &snd_DesiredMusicDevice, 0 },
497 { "snd_sfxdevice", &snd_DesiredSfxDevice, 0 },
498 { "snd_sbport", &snd_SBport, 544 },
499 { "snd_sbirq", &snd_SBirq, -1 },
500 { "snd_sbdma", &snd_SBdma, -1 },
501 { "snd_mport", &snd_Mport, -1 },
503 { "usegamma", &usegamma, 0 },
505 #define DEFAULT_SAVEPATH "hexndata/"
507 { "savedir", (int *) &SavePath, (int) DEFAULT_SAVEPATH },
509 { "messageson", (int *) &messageson, 1 },
511 { "chatmacro0", (int *) &chat_macros[0], (int) HUSTR_CHATMACRO0 },
512 { "chatmacro1", (int *) &chat_macros[1], (int) HUSTR_CHATMACRO1 },
513 { "chatmacro2", (int *) &chat_macros[2], (int) HUSTR_CHATMACRO2 },
514 { "chatmacro3", (int *) &chat_macros[3], (int) HUSTR_CHATMACRO3 },
515 { "chatmacro4", (int *) &chat_macros[4], (int) HUSTR_CHATMACRO4 },
516 { "chatmacro5", (int *) &chat_macros[5], (int) HUSTR_CHATMACRO5 },
517 { "chatmacro6", (int *) &chat_macros[6], (int) HUSTR_CHATMACRO6 },
518 { "chatmacro7", (int *) &chat_macros[7], (int) HUSTR_CHATMACRO7 },
519 { "chatmacro8", (int *) &chat_macros[8], (int) HUSTR_CHATMACRO8 },
520 { "chatmacro9", (int *) &chat_macros[9], (int) HUSTR_CHATMACRO9 },
521 { "mouselook", &mouselook, 0 },
522 { "cdaudio", (int *) &cdaudio, false }, /* jim cast added (warning) */
523 { "alwaysrun", (int *) &alwaysrun, false }
527 char defaultfile[128];
537 void M_SaveDefaults (void)
542 f = fopen (defaultfile, "w");
544 return; // can't write the file, but don't complain
546 for (i=0 ; i<numdefaults ; i++)
548 if (defaults[i].defaultvalue > -0xfff
549 && defaults[i].defaultvalue < 0xfff)
551 v = *defaults[i].location;
552 fprintf (f,"%s\t\t%i\n",defaults[i].name,v);
554 fprintf (f,"%s\t\t\"%s\"\n",defaults[i].name,
555 * (char **) (defaults[i].location));
562 //==========================================================================
566 //==========================================================================
568 extern byte scantokey[128];
570 void M_LoadDefaults(char *fileName)
577 char *newstring = NULL; /* jim initialiser added */
581 // Set everything to base values
582 numdefaults = sizeof(defaults)/sizeof(defaults[0]);
583 ST_Message("M_LoadDefaults: %d default settings loaded\n", numdefaults);
584 for(i = 0; i < numdefaults; i++)
586 *defaults[i].location = defaults[i].defaultvalue;
589 // Check for a custom config file
590 i = M_CheckParm("-config");
591 if(i && i < myargc-1)
593 strcpy(defaultfile, myargv[i+1]);
594 ST_Message("config file: %s\n", defaultfile);
598 sprintf(defaultfile, "c:\\hexndata\\%s", fileName);
602 strcpy(defaultfile, fileName);
605 // Scan the config file
606 f = fopen(defaultfile, "r");
612 if(fscanf(f, "%79s %[^\n]\n", def, strparm) == 2)
614 if(strparm[0] == '"')
616 // Get a string default
618 len = strlen(strparm);
619 newstring = (char *)malloc(len);
620 if (newstring == NULL) I_Error("can't malloc newstring");
622 strcpy(newstring, strparm+1);
624 else if(strparm[0] == '0' && strparm[1] == 'x')
626 sscanf(strparm+2, "%x", &parm);
630 sscanf(strparm, "%i", &parm);
632 for(i = 0; i < numdefaults; i++)
634 if(!strcmp(def, defaults[i].name))
638 *defaults[i].location = parm;
642 *defaults[i].location = (int)newstring;
655 ==============================================================================
659 ==============================================================================
669 unsigned short xmin,ymin,xmax,ymax;
670 unsigned short hres,vres;
671 unsigned char palette[48];
674 unsigned short bytes_per_line;
675 unsigned short palette_type;
677 unsigned char data; // unbounded
688 void WritePCXfile (char *filename, byte *data, int width, int height, byte *palette)
694 pcx = Z_Malloc (width*height*2+1000, PU_STATIC, NULL);
696 pcx->manufacturer = 0x0a; // PCX id
697 pcx->version = 5; // 256 color
698 pcx->encoding = 1; // uncompressed
699 pcx->bits_per_pixel = 8; // 256 color
702 pcx->xmax = SHORT(width-1);
703 pcx->ymax = SHORT(height-1);
704 pcx->hres = SHORT(width);
705 pcx->vres = SHORT(height);
706 memset (pcx->palette,0,sizeof(pcx->palette));
707 pcx->color_planes = 1; // chunky image
708 pcx->bytes_per_line = SHORT(width);
709 pcx->palette_type = SHORT(2); // not a grey scale
710 memset (pcx->filler,0,sizeof(pcx->filler));
717 for (i=0 ; i<width*height ; i++)
718 if ( (*data & 0xc0) != 0xc0)
729 *pack++ = 0x0c; // palette ID byte
730 for (i=0 ; i<768 ; i++)
731 *pack++ = *palette++;
736 length = pack - (byte *)pcx;
737 M_WriteFile (filename, pcx, length);
743 //==============================================================================
753 void M_ScreenShot (void)
758 void M_ScreenShot (void)
766 // munge planar buffer to linear
770 // find a file name to save it to
772 strcpy(lbmname,"HEXEN00.pcx");
774 for (i=0 ; i<=99 ; i++)
776 lbmname[5] = i/10 + '0';
777 lbmname[6] = i%10 + '0';
778 if (access(lbmname,0) == -1)
779 break; // file doesn't exist
782 I_Error ("M_ScreenShot: Couldn't create a PCX");
787 pal = (byte *)W_CacheLumpName("PLAYPAL", PU_CACHE);
789 WritePCXfile (lbmname, linear, SCREENWIDTH, SCREENHEIGHT
792 P_SetMessage(&players[consoleplayer], "SCREEN SHOT", false);