home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
D!Zone (Collector's Edition)
/
D_ZONE_CD.ISO
/
programs
/
editors
/
vnb1050
/
vnb.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-25
|
21KB
|
514 lines
/******************************************************************************
PROGRAM: VNB.C
WRITTEN BY: Robert Fenske, Jr. (rfenske@swri.edu)
Southwest Research Institute
Electromagnetics Division
6220 Culebra
San Antonio, Texas 78238-5166
CREATED: May 1994
DESCRIPTION: This program is the VERDA Node Builder. It extracts
the data from a DOOM-related PWAD, IWAD, or VERDA
patch file and builds the BSP-related structures segs,
subsectors, and nodes. It can build these structures
for all the levels in the input file, or for a specific
level found in the input file. The command line
arguments are as follows:
[-e#m#] <input file> [output file]
where -e#m# specifies a particular level within the
input level, input file is the input filename, and
output file is the optional output filename. If no
output file is specified, the input file is rewritten
with the new data.
This program has been compiled and run under SunOS
using cc and under MS-DOS using DJGPP.
There is a number of byte swapping calls used in the
SunOS case; these calls are ugly, but necessary since
the WAD files store data in little-endian order.
DOOM is a trademark of id Software, Inc.
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "dmglobal.i"
#define SOFTVER 1.050 /* software version */
#define SOFTDATE "May 1994" /* software version date */
#define RESOURCES_NEEDED ((1<<LINES)|(1<<VERTS))
#define update_resource(s,d,n) \
(blockfree(WInfo.data[WInfo.lvlndx+(s)]),\
WInfo.data[WInfo.lvlndx+(s)] = (char *)(d),\
WInfo.dir[WInfo.lvlndx+(s)].nbytes = \
(long)(n)*datasize[s],\
WInfo.changed[WInfo.lvlndx+(s)] = TRUE)
global WAD_INFO WInfo; /* WAD information */
local long datasize[] = { 1, sizeof(DOOM_VERT), sizeof(DOOM_LINE),
sizeof(DOOM_SIDE), sizeof(DOOM_VERT),
sizeof(DOOM_SEGS), sizeof(DOOM_SSECTOR),
sizeof(DOOM_NODE), sizeof(DOOM_SECTOR),
sizeof(DOOM_REJECT), sizeof(DOOM_BLOCKMAP)
};
/******************************************************************************
ROUTINE: main(ac,av)
WRITTEN BY: Robert Fenske, Jr.
CREATED: May 1994
DESCRIPTION: This routine processes the command line arguments
and executes the appropriate build function.
******************************************************************************/
main(ac,av)
int ac;
char *av[];
{
char *ifile = NULL, *ofile = NULL; /* input/output filenames */
boolean help = FALSE; /* whether to display help */
boolean good = FALSE; /* whether read/write worked */
boolean rewrite; /* whether input rewritten */
boolean wad = FALSE, /* (I/P)WAD file flag */
patch = FALSE; /* VERDA patch file flag */
int epdo = 0, mpdo = 0; /* specific ep/map to do */
register FILE *ifp, *ofp; /* input/output file ptrs */
register int i;
setbuf(stdout,(char *)NULL); /* make stdout unbuffered */
printf("\n\t\t\t\tVERDA Node Builder\n");
printf("\tVersion %5.3lf of %s by Robert Fenske, Jr (rfenske@swri.edu)\n",
SOFTVER,SOFTDATE);
for (i = 1; i < ac; i++) { /* scan all arguments */
if (av[i][0] == '-') {
if (2 != sscanf(av[i],"-e%1dm%1d",&epdo,&mpdo)) help = TRUE;
}else if (ifile == NULL)
ifile = ofile = av[i];
else
ofile = av[i];
}
if (ifile == NULL || help) { /* show now to do corectly */
printf("\n%s [-e#m#] <input file> [output file]\n\n",av[0]);
printf("%*s -e#m# specify level to process;\n",
strlen(av[0]),"");
printf("%*s otherwise does all levels\n",
strlen(av[0]),"");
printf("%*s <input file> PWAD, IWAD, or VERDA patch file\n",
strlen(av[0]),"");
printf("%*s <output file> output file; if none specified,\n",
strlen(av[0]),"");
printf("%*s input file is rewritten\n",
strlen(av[0]),"");
return 1;
}
ifp = fopen(ifile,"rb"); /* open input file */
if (ifp == NULL) {
fprintf(stderr,"\nunable to open %s for reading\n",ifile);
return 1;
}
fread((char *)&WInfo.head,sizeof WInfo.head,1,ifp);
if (strncmp(WInfo.head.ident,"PWAD",4) == 0 ||
strncmp(WInfo.head.ident,"IWAD",4) == 0) wad = TRUE;
rewind(ifp);
if (2 == fscanf(ifp," %d %d %*d %*lf",&WInfo.ep,&WInfo.mp)) patch = TRUE;
if (!wad && !patch) { /* not a valid file */
fprintf(stderr,"\n%s is not a PWAD, IWAD, nor VERDA patch file\n",ifile);
return 1;
}
rewrite = !patch && ifile == ofile; /* whether input rewritten */
WInfo.lvlndx = -ALL;
do { /* process file until done */
printf("\nReading %s file %s...",patch?"patch":"WAD",ifile);
if (patch) good = patch_read(ifp,epdo,mpdo,RESOURCES_NEEDED);
else if (wad) good = wad_read(ifp,epdo,mpdo,RESOURCES_NEEDED);
if (good) { /* process new level data */
DOOM_LINE *lines = Lines;
DOOM_VERT *verts = Verts;
DOOM_SEGS *segs = Segs;
DOOM_SSECTOR *ssecs = Ssecs;
DOOM_NODE *nodes = Nodes;
DOOM_BLOCKMAP *blockmaps = Blockmaps;
printf("done\n");
printf("Building BSP Tree for level E%1dM%1d...",WInfo.ep,WInfo.mp);
nodes_make(&nodes,&NNodes,&ssecs,&NSsecs,&segs,&NSegs,&verts,&NVerts,
&lines,&NLines);
update_resource(VERTS,verts,NVerts);
update_resource(SEGS,segs,NSegs);
update_resource(SSECTS,ssecs,NSsecs);
update_resource(NODES,nodes,NNodes);
printf("%d nodes, %d segs \n",NNodes,NSegs);
printf("Building BLOCKMAP for level E%1dM%1d...",WInfo.ep,WInfo.mp);
NBlockmaps = blockmap_make(&blockmaps,Lines,NLines,Verts);
for (i = 0; i < NBlockmaps; i++)
blockmaps[i] = bswapw(blockmaps[i]);
update_resource(BLKMAPS,blockmaps,NBlockmaps);
printf("done\n");
}else if (WInfo.lvlndx >= 0) /* no more in file */
printf("no more levels\n");
else /* oops: bogus data */
printf("failed\n");
if (good) { /* if processed, write it */
ofp = fopen(ofile,rewrite?"r+b":"wb");
if (ofp == NULL) {
fprintf(stderr,"unable to open %s for writing\n",ofile);
return 1;
}
printf("Writing %s file %s...",patch?"patch":"WAD",ofile);
if (patch) good = patch_write(ifp,ofp,rewrite);
else if (wad) good = wad_write(ifp,ofp,rewrite);
fclose(ofp);
if (good) printf("done\n");
else printf("failed\n");
}
} while (good);
fclose(ifp);
return 0; /* everything is okay */
}
/******************************************************************************
ROUTINE: patch_read(patch,epdo,mpdo,resources_needed)
WRITTEN BY: Robert Fenske, Jr.
CREATED: May 1994
DESCRIPTION: This routine reads a VERDA patch file. It reads the
file twice; the first time is to obtain the sizes of
each of the resources. The input resources_needed is
ignored--everything in the patch file is read. Also,
only one level's data is stored in a patch file.
******************************************************************************/
patch_read(patch,epdo,mpdo,resources_needed)
register FILE *patch;
int epdo, mpdo, resources_needed;
{
char str[256];
int type;
int i = 0;
register int t = 0, l = 0, s = 0, v = 0, c = 0;
WInfo.lvlndx += ALL;
if (WInfo.lvlndx != 0) /* can't do more than one */
return FALSE; /* level with patch file */
WInfo.dir = blockmem(DIR_ENTRY,WInfo.head.count = ALL);
WInfo.data = blockmem(char *,WInfo.head.count);
WInfo.changed = blockmem(boolean,WInfo.head.count);
WInfo.count = blockmem(int,WInfo.head.count);
sprintf(WInfo.dir[WInfo.lvlndx+MAINS].name,"E%1dM%1d",WInfo.ep,WInfo.mp);
rewind(patch);
while (fgets(str,sizeof str,patch) != NULL) {
if (i == 0) {
i = sscanf(str," %d %d %d %lf",&WInfo.ep,&WInfo.mp,&type,&WInfo.ver);
if