summaryrefslogtreecommitdiff
path: root/src/heretic/m_misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/heretic/m_misc.c')
-rw-r--r--src/heretic/m_misc.c798
1 files changed, 798 insertions, 0 deletions
diff --git a/src/heretic/m_misc.c b/src/heretic/m_misc.c
new file mode 100644
index 00000000..6e465e90
--- /dev/null
+++ b/src/heretic/m_misc.c
@@ -0,0 +1,798 @@
+
+// M_misc.c
+
+#ifdef __NeXT__
+#include <libc.h>
+#else
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <direct.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#endif
+
+#include <ctype.h>
+
+#include "DoomDef.h"
+#include "soundst.h"
+
+int myargc;
+char **myargv;
+
+//---------------------------------------------------------------------------
+//
+// FUNC M_ValidEpisodeMap
+//
+//---------------------------------------------------------------------------
+
+boolean M_ValidEpisodeMap(int episode, int map)
+{
+ if(episode < 1 || map < 1 || map > 9)
+ {
+ return false;
+ }
+ if(shareware)
+ { // Shareware version checks
+ if(episode != 1)
+ {
+ return false;
+ }
+ }
+ else if(ExtendedWAD)
+ { // Extended version checks
+ if(episode == 6)
+ {
+ if(map > 3)
+ {
+ return false;
+ }
+ }
+ else if(episode > 5)
+ {
+ return false;
+ }
+ }
+ else
+ { // Registered version checks
+ if(episode == 4)
+ {
+ if(map != 1)
+ {
+ return false;
+ }
+ }
+ else if(episode > 3)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+/*
+=================
+=
+= M_CheckParm
+=
+= Checks for the given parameter in the program's command line arguments
+=
+= Returns the argument number (1 to argc-1) or 0 if not present
+=
+=================
+*/
+
+int M_CheckParm (char *check)
+{
+ int i;
+
+ for (i = 1;i<myargc;i++)
+ {
+ if ( !strcasecmp(check, myargv[i]) )
+ return i;
+ }
+
+ return 0;
+}
+
+
+
+/*
+===============
+=
+= M_Random
+=
+= Returns a 0-255 number
+=
+===============
+*/
+
+unsigned char rndtable[256] = {
+ 0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66,
+ 74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36,
+ 95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188,
+ 52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224,
+ 149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242,
+ 145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0,
+ 175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235,
+ 25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113,
+ 94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75,
+ 136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196,
+ 135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113,
+ 80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241,
+ 24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224,
+ 145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95,
+ 28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226,
+ 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36,
+ 17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106,
+ 197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136,
+ 120, 163, 236, 249
+};
+int rndindex = 0;
+int prndindex = 0;
+
+int P_Random (void)
+{
+ prndindex = (prndindex+1)&0xff;
+ return rndtable[prndindex];
+}
+
+int M_Random (void)
+{
+ rndindex = (rndindex+1)&0xff;
+ return rndtable[rndindex];
+}
+
+void M_ClearRandom (void)
+{
+ rndindex = prndindex = 0;
+}
+
+
+void M_ClearBox (fixed_t *box)
+{
+ box[BOXTOP] = box[BOXRIGHT] = MININT;
+ box[BOXBOTTOM] = box[BOXLEFT] = MAXINT;
+}
+
+void M_AddToBox (fixed_t *box, fixed_t x, fixed_t y)
+{
+ if (x<box[BOXLEFT])
+ box[BOXLEFT] = x;
+ else if (x>box[BOXRIGHT])
+ box[BOXRIGHT] = x;
+ if (y<box[BOXBOTTOM])
+ box[BOXBOTTOM] = y;
+ else if (y>box[BOXTOP])
+ box[BOXTOP] = y;
+}
+
+
+
+/*
+==================
+=
+= M_WriteFile
+=
+==================
+*/
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+boolean M_WriteFile (char const *name, void *source, int length)
+{
+ int handle, count;
+
+ handle = open (name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ if (handle == -1)
+ return false;
+ count = write (handle, source, length);
+ close (handle);
+
+ if (count < length)
+ return false;
+
+ return true;
+}
+
+
+/*
+==================
+=
+= M_ReadFile
+=
+==================
+*/
+
+int M_ReadFile (char const *name, byte **buffer)
+{
+ int handle, count, length;
+ struct stat fileinfo;
+ byte *buf;
+
+ handle = open (name, O_RDONLY | O_BINARY, 0666);
+ if (handle == -1)
+ I_Error ("Couldn't read file %s", name);
+ if (fstat (handle,&fileinfo) == -1)
+ I_Error ("Couldn't read file %s", name);
+ length = fileinfo.st_size;
+ buf = Z_Malloc (length, PU_STATIC, NULL);
+ count = read (handle, buf, length);
+ close (handle);
+
+ if (count < length)
+ I_Error ("Couldn't read file %s", name);
+
+ *buffer = buf;
+ return length;
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC M_FindResponseFile
+//
+//---------------------------------------------------------------------------
+
+#define MAXARGVS 100
+
+void M_FindResponseFile(void)
+{
+ int i;
+
+ for(i = 1; i < myargc; i++)
+ {
+ if(myargv[i][0] == '@')
+ {
+ FILE *handle;
+ int size;
+ int k;
+ int index;
+ int indexinfile;
+ char *infile;
+ char *file;
+ char *moreargs[20];
+ char *firstargv;
+
+ // READ THE RESPONSE FILE INTO MEMORY
+ handle = fopen(&myargv[i][1], "rb");
+ if(!handle)
+ {
+ printf("\nNo such response file!");
+ exit(1);
+ }
+ printf("Found response file %s!\n",&myargv[i][1]);
+ fseek (handle,0,SEEK_END);
+ size = ftell(handle);
+ fseek (handle,0,SEEK_SET);
+ file = malloc (size);
+ fread (file,size,1,handle);
+ fclose (handle);
+
+ // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG
+ for (index = 0,k = i+1; k < myargc; k++)
+ moreargs[index++] = myargv[k];
+
+ firstargv = myargv[0];
+ myargv = malloc(sizeof(char *)*MAXARGVS);
+ memset(myargv,0,sizeof(char *)*MAXARGVS);
+ myargv[0] = firstargv;
+
+ infile = file;
+ indexinfile = k = 0;
+ indexinfile++; // SKIP PAST ARGV[0] (KEEP IT)
+ do
+ {
+ myargv[indexinfile++] = infile+k;
+ while(k < size &&
+
+ ((*(infile+k)>= ' '+1) && (*(infile+k)<='z')))
+ k++;
+ *(infile+k) = 0;
+ while(k < size &&
+ ((*(infile+k)<= ' ') || (*(infile+k)>'z')))
+ k++;
+ } while(k < size);
+
+ for (k = 0;k < index;k++)
+ myargv[indexinfile++] = moreargs[k];
+ myargc = indexinfile;
+ // DISPLAY ARGS
+ if(M_CheckParm("-debug"))
+ {
+ printf("%d command-line args:\n", myargc);
+ for(k = 1; k < myargc; k++)
+ {
+ printf("%s\n", myargv[k]);
+ }
+ }
+ break;
+ }
+ }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC M_ForceUppercase
+//
+// Change string to uppercase.
+//
+//---------------------------------------------------------------------------
+
+void M_ForceUppercase(char *text)
+{
+ char c;
+
+ while((c = *text) != 0)
+ {
+ if(c >= 'a' && c <= 'z')
+ {
+ *text++ = c-('a'-'A');
+ }
+ else
+ {
+ text++;
+ }
+ }
+}
+
+/*
+==============================================================================
+
+ DEFAULTS
+
+==============================================================================
+*/
+
+int usemouse;
+int usejoystick;
+
+extern int key_right, key_left, key_up, key_down;
+extern int key_strafeleft, key_straferight;
+extern int key_fire, key_use, key_strafe, key_speed;
+extern int key_flyup, key_flydown, key_flycenter;
+extern int key_lookup, key_lookdown, key_lookcenter;
+extern int key_invleft, key_invright, key_useartifact;
+
+extern int mousebfire;
+extern int mousebstrafe;
+extern int mousebforward;
+
+extern int joybfire;
+extern int joybstrafe;
+extern int joybuse;
+extern int joybspeed;
+
+extern int viewwidth, viewheight;
+
+int mouseSensitivity;
+
+extern int screenblocks;
+
+extern char *chat_macros[10];
+
+typedef struct
+{
+ char *name;
+ int *location;
+ int defaultvalue;
+ int scantranslate; // PC scan code hack
+ int untranslated; // lousy hack
+} default_t;
+
+#ifndef __NeXT__
+extern int snd_Channels;
+extern int snd_DesiredMusicDevice, snd_DesiredSfxDevice;
+extern int snd_MusicDevice, // current music card # (index to dmxCodes)
+ snd_SfxDevice; // current sfx card # (index to dmxCodes)
+
+extern int snd_SBport, snd_SBirq, snd_SBdma; // sound blaster variables
+extern int snd_Mport; // midi variables
+#endif
+
+default_t defaults[] =
+{
+ { "mouse_sensitivity", &mouseSensitivity, 5 },
+
+#ifndef __NeXT__
+ { "sfx_volume", &snd_MaxVolume, 10},
+ { "music_volume", &snd_MusicVolume, 10},
+#endif
+
+#ifdef __WATCOMC__
+#define SC_UPARROW 0x48
+#define SC_DOWNARROW 0x50
+#define SC_LEFTARROW 0x4b
+#define SC_RIGHTARROW 0x4d
+#define SC_RCTRL 0x1d
+#define SC_RALT 0x38
+#define SC_RSHIFT 0x36
+#define SC_SPACE 0x39
+#define SC_COMMA 0x33
+#define SC_PERIOD 0x34
+#define SC_PAGEUP 0x49
+#define SC_INSERT 0x52
+#define SC_HOME 0x47
+#define SC_PAGEDOWN 0x51
+#define SC_DELETE 0x53
+#define SC_END 0x4f
+#define SC_ENTER 0x1c
+
+ { "key_right", &key_right, SC_RIGHTARROW, 1 },
+ { "key_left", &key_left, SC_LEFTARROW, 1 },
+ { "key_up", &key_up, SC_UPARROW, 1 },
+ { "key_down", &key_down, SC_DOWNARROW, 1 },
+ { "key_strafeleft", &key_strafeleft, SC_COMMA, 1 },
+ { "key_straferight", &key_straferight, SC_PERIOD, 1 },
+ { "key_flyup", &key_flyup, SC_PAGEUP, 1 },
+ { "key_flydown", &key_flydown, SC_INSERT, 1 },
+ { "key_flycenter", &key_flycenter, SC_HOME, 1 },
+ { "key_lookup", &key_lookup, SC_PAGEDOWN, 1 },
+ { "key_lookdown", &key_lookdown, SC_DELETE, 1 },
+ { "key_lookcenter", &key_lookcenter, SC_END, 1 },
+ { "key_invleft", &key_invleft, 0x1a, 1 },
+ { "key_invright", &key_invright, 0x1b, 1 },
+ { "key_useartifact", &key_useartifact, SC_ENTER, 1 },
+
+ { "key_fire", &key_fire, SC_RCTRL, 1 },
+ { "key_use", &key_use, SC_SPACE, 1 },
+ { "key_strafe", &key_strafe, SC_RALT, 1 },
+ { "key_speed", &key_speed, SC_RSHIFT, 1 },
+#endif
+
+#ifdef __NeXT__
+ { "key_right", &key_right, KEY_RIGHTARROW },
+ { "key_left", &key_left, KEY_LEFTARROW },
+ { "key_up", &key_up, KEY_UPARROW },
+ { "key_down", &key_down, KEY_DOWNARROW },
+ { "key_strafeleft", &key_strafeleft, ',' },
+ { "key_straferight", &key_straferight, '.' },
+ { "key_flyup", &key_flyup, 'u' },
+ { "key_flydown", &key_flydown, 'j' },
+ { "key_flycenter", &key_flycenter, 'k' },
+ { "key_lookup", &key_lookup, 'm' },
+ { "key_lookdown", &key_lookdown, 'b' },
+ { "key_lookcenter", &key_lookcenter, 'n' },
+ { "key_invleft", &key_invleft, '[' },
+ { "key_invright", &key_invright, ']' },
+ { "key_useartifact", &key_useartifact, 13 },
+
+ { "key_fire", &key_fire, ' ', 1 },
+ { "key_use", &key_use, 'x', 1 },
+ { "key_strafe", &key_strafe, 'c', 1 },
+ { "key_speed", &key_speed, 'z', 1 },
+#endif
+
+ { "use_mouse", &usemouse, 1 },
+ { "mouseb_fire", &mousebfire, 0 },
+ { "mouseb_strafe", &mousebstrafe, 1 },
+ { "mouseb_forward", &mousebforward, 2 },
+
+ { "use_joystick", &usejoystick, 0 },
+ { "joyb_fire", &joybfire, 0 },
+ { "joyb_strafe", &joybstrafe, 1 },
+ { "joyb_use", &joybuse, 3 },
+ { "joyb_speed", &joybspeed, 2 },
+
+ { "screenblocks", &screenblocks, 10 },
+
+#ifndef __NeXT__
+ { "snd_channels", &snd_Channels, 3 },
+ { "snd_musicdevice", &snd_DesiredMusicDevice, 0 },
+ { "snd_sfxdevice", &snd_DesiredSfxDevice, 0 },
+ { "snd_sbport", &snd_SBport, 544 },
+ { "snd_sbirq", &snd_SBirq, -1 },
+ { "snd_sbdma", &snd_SBdma, -1 },
+ { "snd_mport", &snd_Mport, -1 },
+#endif
+
+ { "usegamma", &usegamma, 0 },
+
+ { "chatmacro0", (int *) &chat_macros[0], (int) HUSTR_CHATMACRO0 },
+ { "chatmacro1", (int *) &chat_macros[1], (int) HUSTR_CHATMACRO1 },
+ { "chatmacro2", (int *) &chat_macros[2], (int) HUSTR_CHATMACRO2 },
+ { "chatmacro3", (int *) &chat_macros[3], (int) HUSTR_CHATMACRO3 },
+ { "chatmacro4", (int *) &chat_macros[4], (int) HUSTR_CHATMACRO4 },
+ { "chatmacro5", (int *) &chat_macros[5], (int) HUSTR_CHATMACRO5 },
+ { "chatmacro6", (int *) &chat_macros[6], (int) HUSTR_CHATMACRO6 },
+ { "chatmacro7", (int *) &chat_macros[7], (int) HUSTR_CHATMACRO7 },
+ { "chatmacro8", (int *) &chat_macros[8], (int) HUSTR_CHATMACRO8 },
+ { "chatmacro9", (int *) &chat_macros[9], (int) HUSTR_CHATMACRO9 }
+};
+
+int numdefaults;
+char *defaultfile;
+
+/*
+==============
+=
+= M_SaveDefaults
+=
+==============
+*/
+
+void M_SaveDefaults (void)
+{
+ int i,v;
+ FILE *f;
+
+ f = fopen (defaultfile, "w");
+ if (!f)
+ return; // can't write the file, but don't complain
+
+ for (i=0 ; i<numdefaults ; i++)
+ {
+#ifdef __WATCOMC__
+ if (defaults[i].scantranslate)
+ defaults[i].location = &defaults[i].untranslated;
+#endif
+ if (defaults[i].defaultvalue > -0xfff
+ && defaults[i].defaultvalue < 0xfff)
+ {
+ v = *defaults[i].location;
+ fprintf (f,"%s\t\t%i\n",defaults[i].name,v);
+ } else {
+ fprintf (f,"%s\t\t\"%s\"\n",defaults[i].name,
+ * (char **) (defaults[i].location));
+ }
+ }
+
+ fclose (f);
+}
+
+
+/*
+==============
+=
+= M_LoadDefaults
+=
+==============
+*/
+
+extern byte scantokey[128];
+extern char *basedefault;
+
+void M_LoadDefaults (void)
+{
+ int i, len;
+ FILE *f;
+ char def[80];
+ char strparm[100];
+ char *newstring;
+ int parm;
+ boolean isstring;
+
+//
+// set everything to base values
+//
+ numdefaults = sizeof(defaults)/sizeof(defaults[0]);
+ for (i=0 ; i<numdefaults ; i++)
+ *defaults[i].location = defaults[i].defaultvalue;
+
+//
+// check for a custom default file
+//
+ i = M_CheckParm("-config");
+ if(i && i<myargc-1)
+ {
+ defaultfile = myargv[i+1];
+ printf("default file: %s\n", defaultfile);
+ }
+ else if(cdrom)
+ {
+ defaultfile = "c:\\heretic.cd\\heretic.cfg";
+ }
+ else
+ {
+ defaultfile = basedefault;
+ }
+
+//
+// read the file in, overriding any set defaults
+//
+ f = fopen (defaultfile, "r");
+ if (f)
+ {
+ while (!feof(f))
+ {
+ isstring = false;
+ if (fscanf (f, "%79s %[^\n]\n", def, strparm) == 2)
+ {
+ if (strparm[0] == '"')
+ {
+ // get a string default
+ isstring = true;
+ len = strlen(strparm);
+ newstring = (char *) malloc(len);
+ strparm[len-1] = 0;
+ strcpy(newstring, strparm+1);
+ }
+ else if (strparm[0] == '0' && strparm[1] == 'x')
+ sscanf(strparm+2, "%x", &parm);
+ else
+ sscanf(strparm, "%i", &parm);
+ for (i=0 ; i<numdefaults ; i++)
+ if (!strcmp(def, defaults[i].name))
+ {
+ if (!isstring)
+ *defaults[i].location = parm;
+ else
+ *defaults[i].location =
+ (int) newstring;
+ break;
+ }
+ }
+ }
+
+ fclose (f);
+ }
+
+
+#ifdef __WATCOMC__
+ for(i = 0; i < numdefaults; i++)
+ {
+ if(defaults[i].scantranslate)
+ {
+ parm = *defaults[i].location;
+ defaults[i].untranslated = parm;
+ *defaults[i].location = scantokey[parm];
+ }
+ }
+#endif
+}
+
+
+/*
+==============================================================================
+
+ SCREEN SHOTS
+
+==============================================================================
+*/
+
+
+typedef struct
+{
+ char manufacturer;
+ char version;
+ char encoding;
+ char bits_per_pixel;
+ unsigned short xmin,ymin,xmax,ymax;
+ unsigned short hres,vres;
+ unsigned char palette[48];
+ char reserved;
+ char color_planes;
+ unsigned short bytes_per_line;
+ unsigned short palette_type;
+ char filler[58];
+ unsigned char data; // unbounded
+} pcx_t;
+
+/*
+==============
+=
+= WritePCXfile
+=
+==============
+*/
+
+void WritePCXfile (char *filename, byte *data, int width, int height, byte *palette)
+{
+ int i, length;
+ pcx_t *pcx;
+ byte *pack;
+
+ pcx = Z_Malloc (width*height*2+1000, PU_STATIC, NULL);
+
+ pcx->manufacturer = 0x0a; // PCX id
+ pcx->version = 5; // 256 color
+ pcx->encoding = 1; // uncompressed
+ pcx->bits_per_pixel = 8; // 256 color
+ pcx->xmin = 0;
+ pcx->ymin = 0;
+ pcx->xmax = SHORT(width-1);
+ pcx->ymax = SHORT(height-1);
+ pcx->hres = SHORT(width);
+ pcx->vres = SHORT(height);
+ memset (pcx->palette,0,sizeof(pcx->palette));
+ pcx->color_planes = 1; // chunky image
+ pcx->bytes_per_line = SHORT(width);
+ pcx->palette_type = SHORT(2); // not a grey scale
+ memset (pcx->filler,0,sizeof(pcx->filler));
+
+//
+// pack the image
+//
+ pack = &pcx->data;
+
+ for (i=0 ; i<width*height ; i++)
+ if ( (*data & 0xc0) != 0xc0)
+ *pack++ = *data++;
+ else
+ {
+ *pack++ = 0xc1;
+ *pack++ = *data++;
+ }
+
+//
+// write the palette
+//
+ *pack++ = 0x0c; // palette ID byte
+ for (i=0 ; i<768 ; i++)
+ *pack++ = *palette++;
+
+//
+// write output file
+//
+ length = pack - (byte *)pcx;
+ M_WriteFile (filename, pcx, length);
+
+ Z_Free (pcx);
+}
+
+
+//==============================================================================
+
+/*
+==================
+=
+= M_ScreenShot
+=
+==================
+*/
+
+void M_ScreenShot (void)
+{
+ int i;
+ byte *linear;
+ char lbmname[12];
+ byte *pal;
+
+#ifdef _WATCOMC_
+ extern byte *pcscreen;
+#endif
+//
+// munge planar buffer to linear
+//
+#ifdef _WATCOMC_
+ linear = pcscreen;
+#else
+ linear = screen;
+#endif
+//
+// find a file name to save it to
+//
+ strcpy(lbmname,"HRTIC00.pcx");
+
+ for (i=0 ; i<=99 ; i++)
+ {
+ lbmname[5] = i/10 + '0';
+ lbmname[6] = i%10 + '0';
+ if (access(lbmname,0) == -1)
+ break; // file doesn't exist
+ }
+ if (i==100)
+ I_Error ("M_ScreenShot: Couldn't create a PCX");
+
+//
+// save the pcx file
+//
+#ifdef __WATCOMC__
+ pal = (byte *)Z_Malloc(768, PU_STATIC, NULL);
+ outp(0x3c7, 0);
+ for(i = 0; i < 768; i++)
+ {
+ *(pal+i) = inp(0x3c9)<<2;
+ }
+#else
+ pal = (byte *)W_CacheLumpName("PLAYPAL", PU_CACHE);
+#endif
+
+ WritePCXfile (lbmname, linear, SCREENWIDTH, SCREENHEIGHT
+ , pal);
+
+ players[consoleplayer].message = "SCREEN SHOT";
+#ifdef __WATCOMC__
+ Z_Free(pal);
+#endif
+}