/* Add things to a DOOM level 1/7/96 Requires PC byte order */ #include #include #include #include #include unsigned char entry[16], thing[10]; void getdirent (FILE *fp, char lname[9], long int *loffset, long int *lsize) { assert (fread (entry, 1, 16, fp) == 16); strncpy (lname, entry+8, 8); lname[8] = '\0'; *loffset = *(long int *)(entry); *lsize = *(long int *)(entry+4); } void getthing (FILE *fp, short *x, short *y, short *angle, short *type, short *options) { assert (fread (thing, 1, 10, fp) == 10); *x = *(short *)(thing); *y = *(short *)(thing+2); *angle = *(short *)(thing+4); *type = *(short *)(thing+6); *options = *(short *)(thing+8); } #define RND_DENOM 2147483648.0 float rnd () { double temp = 2.0; while (temp < 0.0 || temp >= 1.0) /* I've seen 1.0 before.... */ temp = (double)(random ()) / RND_DENOM; return (float)temp; } short rndboom (short min, short max) { return min + (short)((rnd () * (max - min + 1))); } int main (int argc, char **argv) { FILE *fp, *outwad; unsigned char header[12], *tempthings, level[11][16]; char wadtype[5], lname[9]; int btoadd, typetoadd = 2035; long int dirstart, numlumps, looper, loffset, lsize, numthings, non_thing_size = 0, thingsize, thingoffset, maxsize=0; short minx, miny, maxx, maxy; if (argc != 2 && argc != 3 && argc != 5 && argc != 6) { fprintf (stderr, "FOOM produces a PWAD to add more things to a DOOM level.\n\ Usage: foom wadfilename to list wad directory\n\ foom wadfilename levelname to list THINGS\n\ foom wadfilename levelname N outfilename to add N barrels\n\ foom wadfilename levelname N outfilename boss to add N boss shooters\n"); exit (-1); } assert (fp = fopen (argv[1], "r")); if (!strcmp (argv[5], "boss")) typetoadd = 89; /* Read header */ assert (fread (header, 1, 12, fp) == 12); assert (!strncmp (header, "IWAD", 4) || !strncmp (header, "PWAD", 4)); strncpy (wadtype, header, 4); wadtype[4] = '\0'; printf ("%s\n", wadtype); numlumps = *(long int *)(header+4); printf ("Number of lumps: %ld\n", numlumps); dirstart = *(long int *)(header+8); printf ("File offset to start of directory: %ld\n\n", dirstart); /* Scan directory for level*/ assert (!fseek (fp, dirstart, SEEK_SET)); for (looper=0;looper maxsize) maxsize = lsize; } printf ("\n"); /* Scan things */ assert (!fseek (fp, thingoffset, SEEK_SET)); for (looper=0;looper maxx) maxx = x; if (y < miny) miny = y; if (y > maxy) maxy = y; } if (argc == 3) printf ("x=%hd y=%hd angle=%hd type=%hd options=%hd\n", x, y, angle, type, options); } printf ("X range: %hd .. %hd Y range: %hd .. %hd\n", minx, maxx, miny, maxy); if (argc == 3) exit (0); assert (sscanf (argv[3], "%d", &btoadd) == 1); assert (btoadd > 0); printf ("Adding %d things....\n", btoadd); assert (outwad = fopen (argv[4], "w")); /* Write header for out wad */ header[0] = 'P'; *(long int *)(header+4) = 11; /* 11 lumps */ *(long int *)(header+8) = 12 + (numthings + btoadd) * 10 + non_thing_size; /* dirstart */ assert (fwrite (header, 1, 12, outwad) == 12); /* Copy things from old wad */ assert (tempthings = (unsigned char *) malloc (maxsize)); assert (!fseek (fp, thingoffset, SEEK_SET)); assert (fread (tempthings, 1, thingsize, fp) == thingsize); assert (fwrite (tempthings, 1, thingsize, outwad) == thingsize); /* Add things */ /* Code for barrel: x y angle=0 type=2035 options=7 */ *(short *)(thing+6) = typetoadd; /* type */ *(short *)(thing+8) = 7; /* options */ srandom (time (NULL)); for (looper=0;looper