home *** CD-ROM | disk | FTP | other *** search
- /*
- * Doom PostScript map generator. V1.1
- * Copyright James Bonfield, 3/3/94
- *
- * Options:
- * -d debugging - displays the wad directory
- * -w wadfile select another wad file (default "doom.wad")
- * -l level choose another level (default "E1M1")
- * -o do not display objects
- * -m do not display monsters
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include "wad.h"
-
- /*
- * A4 paper is 8 1/4" by 11 3/4"
- * We allow 1/2" border.
- */
- #define PAPER_X (72 * 8.25)
- #define PAPER_Y (72 * 11.75)
- #define PAPER_BORDER (72 * 0.5)
-
- void doit(int fd, struct directory *dir, int size, char *lev_name,
- int objs, int mons);
-
- void dump_dir(struct directory *d, int size) {
- int i;
-
- for (i = 0; i < size; i++) {
- printf("Item=%5d, Start=%8d, Len=%8d, Name=%.8s\n",
- i, d[i].start, d[i].length, d[i].name);
- }
- }
-
-
- void usage() {
- puts("wad [-w wadfile] [-d] [-o] [-m] [-l level]");
- }
-
- int main(int argc, char **argv) {
- struct directory *d;
- int fd, size, c;
- int objs=1, mons=1, dump=0;
- char *level = "E1M1";
- char *wadfile = "doom.wad";
- extern char *optarg;
- extern int optind;
-
- while ((c = getopt(argc, argv, "domw:l:")) != EOF) {
- switch (c) {
- case 'w': /* wad file */
- wadfile = optarg;
- break;
- case 'd': /* debug */
- dump=1;
- break;
- case 'l': /* select the level */
- level = optarg;
- break;
- case 'o': /* don't display objects */
- objs=0;
- break;
- case 'm': /* don't display monsters */
- mons=0;
- break;
- }
- }
-
- if (optind != argc) {
- usage();
- return 1;
- }
-
- if (NULL == (d = open_wad(wadfile, &fd, &size))) {
- fprintf(stderr, "Failed to open wad file.\n");
- return 1;
- }
-
- if (dump) {
- dump_dir(d, size);
- return 0;
- }
-
- doit(fd, d, size, level, objs, mons);
-
- return 0;
- }
-
- void doit(int fd, struct directory *dir, int size, char *lev_name,
- int objs, int mons) {
- linedef *linedefs;
- vertex *vertexes;
- blockmap *blocks;
- sidedef *sidedefs;
- sector *sectors;
- thing *things;
- int numline, numvert, numblock, numside, numsect, numthing;
- int lev_index;
- int xorigin, yorigin, xsize, ysize;
- int2 sector;
- double xscale, yscale;
- int i, j;
-
- /* find level index */
- lev_index = get_index(dir, size, lev_name, 0);
- if (lev_index == 0) {
- fprintf(stderr, "Unknown level: %s\n", lev_name);
- exit(1);
- }
-
- /* load relevent arrays for this level */
- linedefs = read_linedefs(fd, dir, size, lev_index, &numline);
- vertexes = read_vertexes(fd, dir, size, lev_index, &numvert);
- blocks = read_blockmap(fd, dir, size, lev_index, &numblock);
- sidedefs = read_sidedefs(fd, dir, size, lev_index, &numside);
- sectors = read_sectors (fd, dir, size, lev_index, &numsect);
- things = read_things (fd, dir, size, lev_index, &numthing);
-
- /* calculate scaling info */
- xorigin = blocks[0];
- yorigin = blocks[1];
- xsize = blocks[2] * 0x80;
- ysize = blocks[3] * 0x80;
-
- xscale = (double)(PAPER_Y - 2*PAPER_BORDER)/xsize;
- yscale = (double)(PAPER_X - 2*PAPER_BORDER)/ysize;
-
- if (xscale > yscale)
- xscale = yscale;
- else
- yscale = xscale;
-
- /* output postscript header */
- printf("%%!\n");
- printf("newpath\n");
- printf("\n");
- printf("1 setlinecap\n");
- printf("%f %f translate\n", PAPER_BORDER, PAPER_Y - PAPER_BORDER);
- printf("-90 rotate\n");
- printf("%f %f scale\n", xscale, yscale);
- printf("%d %d translate\n", -xorigin, -yorigin);
- printf("%f setlinewidth\n", (double).5/xscale);
- printf("\n");
- printf("/l {\n");
- printf(" setgray setlinewidth moveto lineto stroke\n");
- printf("} def\n");
- printf("\n");
- printf("/a {\n");
- printf(" 5 0 360 arc stroke\n");
- printf("} def\n");
- printf("\n");
- printf("/m {\n");
- printf(" gsave\n");
- printf(" moveto rotate\n");
- printf(" 0 -13 rmoveto\n");
- printf(" 0 25 rlineto\n");
- printf(" -10 -10 rlineto\n");
- printf(" 10 10 rmoveto\n");
- printf(" 10 -10 rlineto\n");
- printf(" stroke\n");
- printf(" grestore\n");
- printf("} def\n");
-
- /*
- * Display the walls.
- * Secret passages are done in grey.
- */
- for (i = 0; i < numline; i++) {
- sector = sidedefs[linedefs[i].sidedef1].sector;
-
- printf("%d %d %d %d ",
- vertexes[linedefs[i].to_vertex].x,
- vertexes[linedefs[i].to_vertex].y,
- vertexes[linedefs[i].from_vertex].x,
- vertexes[linedefs[i].from_vertex].y);
-
- if (linedefs[i].attrib & LI_IMPASS) {
- printf("%f ", 1.2/xscale);
- } else {
- printf("%f ", 0.5/xscale);
- }
-
- if (linedefs[i].attrib & LI_SECRET || sectors[sector].special == 9) {
- printf(".5 l\n");
- } else {
- printf("0 l\n");
- }
- }
-
- /*
- * Do we need to display objects or monsters?
- */
- if (objs || mons) {
-
- printf(" %d setlinewidth\n", 1/xscale);
-
- for (i = 0; i < numthing; i++) {
-
- switch(things[i].type) {
- /* is this a monster? */
- case 7: /* spider */
- case 9: /* sergeant */
- case 16: /* cyber */
- case 58: /* invis */
- case 3001: /* imp */
- case 3002: /* demon */
- case 3003: /* minotaur */
- case 3004: /* human */
- case 3005: /* cacodemon */
- case 3006: /* skull */
- if (mons) {
- printf("%d %d %d m\n",
- things[i].angle, things[i].x, things[i].y);
- }
- break;
- default:
- /* not a monster - so direction isn't important */
- if (objs) {
- printf("%d %d a\n", things[i].x, things[i].y);
- }
- }
- }
- }
-
- puts("showpage");
-
- return;
- }
-