home *** CD-ROM | disk | FTP | other *** search
/ D!Zone (Collector's Edition) / D_ZONE_CD.ISO / programs / editors / vnb1050 / vnb.c < prev    next >
C/C++ Source or Header  |  1994-05-25  |  21KB  |  514 lines

  1. /******************************************************************************
  2.     PROGRAM:    VNB.C
  3.     WRITTEN BY:    Robert Fenske, Jr. (rfenske@swri.edu)
  4.                 Southwest Research Institute
  5.                 Electromagnetics Division
  6.                 6220 Culebra
  7.                 San Antonio, Texas 78238-5166
  8.     CREATED:    May  1994
  9.     DESCRIPTION:    This program is the VERDA Node Builder.  It extracts
  10.             the data from a DOOM-related PWAD, IWAD, or VERDA
  11.             patch file and builds the BSP-related structures segs,
  12.             subsectors, and nodes.  It can build these structures
  13.             for all the levels in the input file, or for a specific
  14.             level found in the input file.  The command line
  15.             arguments are as follows:
  16.                 [-e#m#] <input file> [output file]
  17.             where -e#m# specifies a particular level within the
  18.             input level, input file is the input filename, and
  19.             output file is the optional output filename.  If no
  20.             output file is specified, the input file is rewritten
  21.             with the new data.
  22.  
  23.             This program has been compiled and run under SunOS
  24.             using cc and under MS-DOS using DJGPP.
  25.  
  26.             There is a number of byte swapping calls used in the
  27.             SunOS case; these calls are ugly, but necessary since
  28.             the WAD files store data in little-endian order.
  29.  
  30.             DOOM is a trademark of id Software, Inc.
  31. ******************************************************************************/
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <math.h>
  35. #include "dmglobal.i"
  36.  
  37. #define SOFTVER        1.050            /* software version */
  38. #define SOFTDATE    "May 1994"        /* software version date */
  39.  
  40. #define RESOURCES_NEEDED ((1<<LINES)|(1<<VERTS))
  41.  
  42. #define update_resource(s,d,n) \
  43.             (blockfree(WInfo.data[WInfo.lvlndx+(s)]),\
  44.              WInfo.data[WInfo.lvlndx+(s)] = (char *)(d),\
  45.              WInfo.dir[WInfo.lvlndx+(s)].nbytes = \
  46.                                          (long)(n)*datasize[s],\
  47.              WInfo.changed[WInfo.lvlndx+(s)] = TRUE)
  48.  
  49. global WAD_INFO WInfo;                /* WAD information */
  50.  
  51. local long datasize[] = { 1, sizeof(DOOM_VERT), sizeof(DOOM_LINE),
  52.               sizeof(DOOM_SIDE), sizeof(DOOM_VERT),
  53.               sizeof(DOOM_SEGS), sizeof(DOOM_SSECTOR),
  54.               sizeof(DOOM_NODE), sizeof(DOOM_SECTOR),
  55.               sizeof(DOOM_REJECT), sizeof(DOOM_BLOCKMAP)
  56. };
  57.  
  58.  
  59. /******************************************************************************
  60.     ROUTINE:    main(ac,av)
  61.     WRITTEN BY:    Robert Fenske, Jr.
  62.     CREATED:    May  1994
  63.     DESCRIPTION:    This routine processes the command line arguments
  64.             and executes the appropriate build function.
  65. ******************************************************************************/
  66. main(ac,av)
  67. int ac;
  68. char *av[];
  69. {
  70.   char *ifile = NULL, *ofile = NULL;        /* input/output filenames */
  71.   boolean help = FALSE;                /* whether to display help */
  72.   boolean good = FALSE;                /* whether read/write worked */
  73.   boolean rewrite;                /* whether input rewritten */
  74.   boolean wad = FALSE,                /* (I/P)WAD file flag */
  75.           patch = FALSE;            /* VERDA patch file flag */
  76.   int epdo = 0, mpdo = 0;            /* specific ep/map to do */
  77.   register FILE *ifp, *ofp;            /* input/output file ptrs */
  78.   register int i;
  79.  
  80.   setbuf(stdout,(char *)NULL);            /* make stdout unbuffered */
  81.   printf("\n\t\t\t\tVERDA Node Builder\n");
  82.   printf("\tVersion %5.3lf of %s by Robert Fenske, Jr (rfenske@swri.edu)\n",
  83.          SOFTVER,SOFTDATE);
  84.   for (i = 1; i < ac; i++) {            /* scan all arguments */
  85.     if (av[i][0] == '-') {
  86.       if (2 != sscanf(av[i],"-e%1dm%1d",&epdo,&mpdo)) help = TRUE;
  87.     }else if (ifile == NULL)
  88.       ifile = ofile = av[i];
  89.     else
  90.       ofile = av[i];
  91.   }
  92.   if (ifile == NULL || help) {            /* show now to do corectly */
  93.     printf("\n%s [-e#m#] <input file> [output file]\n\n",av[0]);
  94.     printf("%*s -e#m#          specify level to process;\n",
  95.            strlen(av[0]),"");
  96.     printf("%*s                otherwise does all levels\n",
  97.            strlen(av[0]),"");
  98.     printf("%*s <input file>   PWAD, IWAD, or VERDA patch file\n",
  99.             strlen(av[0]),"");
  100.     printf("%*s <output file>  output file; if none specified,\n",
  101.             strlen(av[0]),"");
  102.     printf("%*s                input file is rewritten\n",
  103.            strlen(av[0]),"");
  104.     return 1;
  105.   }
  106.   ifp = fopen(ifile,"rb");            /* open input file */
  107.   if (ifp == NULL) {
  108.     fprintf(stderr,"\nunable to open %s for reading\n",ifile);
  109.     return 1;
  110.   }
  111.   fread((char *)&WInfo.head,sizeof WInfo.head,1,ifp);
  112.   if (strncmp(WInfo.head.ident,"PWAD",4) == 0 ||
  113.       strncmp(WInfo.head.ident,"IWAD",4) == 0) wad = TRUE;
  114.   rewind(ifp);
  115.   if (2 == fscanf(ifp," %d %d %*d %*lf",&WInfo.ep,&WInfo.mp)) patch = TRUE;
  116.   if (!wad && !patch) {                /* not a valid file */
  117.     fprintf(stderr,"\n%s is not a PWAD, IWAD, nor VERDA patch file\n",ifile);
  118.     return 1;
  119.   }
  120.   rewrite = !patch && ifile == ofile;        /* whether input rewritten */
  121.   WInfo.lvlndx = -ALL;
  122.   do {                        /* process file until done */
  123.     printf("\nReading %s file %s...",patch?"patch":"WAD",ifile);
  124.     if (patch)     good = patch_read(ifp,epdo,mpdo,RESOURCES_NEEDED);
  125.     else if (wad)  good = wad_read(ifp,epdo,mpdo,RESOURCES_NEEDED);
  126.     if (good) {                    /* process new level data */
  127.       DOOM_LINE *lines = Lines;
  128.       DOOM_VERT *verts = Verts;
  129.       DOOM_SEGS *segs = Segs;
  130.       DOOM_SSECTOR *ssecs = Ssecs;
  131.       DOOM_NODE *nodes = Nodes;
  132.       DOOM_BLOCKMAP *blockmaps = Blockmaps;
  133.       printf("done\n");
  134.       printf("Building BSP Tree for level E%1dM%1d...",WInfo.ep,WInfo.mp);
  135.       nodes_make(&nodes,&NNodes,&ssecs,&NSsecs,&segs,&NSegs,&verts,&NVerts,
  136.                  &lines,&NLines);
  137.       update_resource(VERTS,verts,NVerts);
  138.       update_resource(SEGS,segs,NSegs);
  139.       update_resource(SSECTS,ssecs,NSsecs);
  140.       update_resource(NODES,nodes,NNodes);
  141.       printf("%d nodes, %d segs          \n",NNodes,NSegs);
  142.       printf("Building BLOCKMAP for level E%1dM%1d...",WInfo.ep,WInfo.mp);
  143.       NBlockmaps = blockmap_make(&blockmaps,Lines,NLines,Verts);
  144.       for (i = 0; i < NBlockmaps; i++)
  145.         blockmaps[i] = bswapw(blockmaps[i]);
  146.       update_resource(BLKMAPS,blockmaps,NBlockmaps);
  147.       printf("done\n");
  148.     }else if (WInfo.lvlndx >= 0)        /* no more in file */
  149.       printf("no more levels\n");
  150.     else                    /* oops: bogus data */
  151.       printf("failed\n");
  152.     if (good) {                    /* if processed, write it */
  153.       ofp = fopen(ofile,rewrite?"r+b":"wb");
  154.       if (ofp == NULL) {
  155.         fprintf(stderr,"unable to open %s for writing\n",ofile);
  156.         return 1;
  157.       }
  158.       printf("Writing %s file %s...",patch?"patch":"WAD",ofile);
  159.       if (patch)     good = patch_write(ifp,ofp,rewrite);
  160.       else if (wad)  good = wad_write(ifp,ofp,rewrite);
  161.       fclose(ofp);
  162.       if (good) printf("done\n");
  163.       else      printf("failed\n");
  164.     }
  165.   } while (good);
  166.   fclose(ifp);
  167.   return 0;                    /* everything is okay */
  168. }
  169.  
  170.  
  171. /******************************************************************************
  172.     ROUTINE:    patch_read(patch,epdo,mpdo,resources_needed)
  173.     WRITTEN BY:    Robert Fenske, Jr.
  174.     CREATED:    May  1994
  175.     DESCRIPTION:    This routine reads a VERDA patch file.  It reads the
  176.             file twice; the first time is to obtain the sizes of
  177.             each of the resources.  The input resources_needed is
  178.             ignored--everything in the patch file is read.  Also,
  179.             only one level's data is stored in a patch file.
  180. ******************************************************************************/
  181. patch_read(patch,epdo,mpdo,resources_needed)
  182. register FILE *patch;
  183. int epdo, mpdo, resources_needed;
  184. {
  185.   char str[256];
  186.   int type;
  187.   int i = 0;
  188.   register int t = 0, l = 0, s = 0, v = 0, c = 0;
  189.  
  190.   WInfo.lvlndx += ALL;
  191.   if (WInfo.lvlndx != 0)            /* can't do more than one */
  192.     return FALSE;                /* level with patch file  */
  193.   WInfo.dir = blockmem(DIR_ENTRY,WInfo.head.count = ALL);
  194.   WInfo.data = blockmem(char *,WInfo.head.count);
  195.   WInfo.changed = blockmem(boolean,WInfo.head.count);
  196.   WInfo.count = blockmem(int,WInfo.head.count);
  197.   sprintf(WInfo.dir[WInfo.lvlndx+MAINS].name,"E%1dM%1d",WInfo.ep,WInfo.mp);
  198.   rewind(patch);
  199.   while (fgets(str,sizeof str,patch) != NULL) {
  200.     if (i == 0) {
  201.       i = sscanf(str," %d %d %d %lf",&WInfo.ep,&WInfo.mp,&type,&WInfo.ver);
  202.       if