home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Toolkit for DOOM
/
DOOMTOOL.ISO
/
editors
/
wadgc2.zip
/
NEWFLATS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-31
|
9KB
|
351 lines
/* NEWFLATS.C replace and/or add flats to an IWAD file */
/* Stefan Gustavson 1994 */
#include <stdio.h>
typedef struct
{
char name[8];
long pos, size;
} direntry;
int getshort(filep)
FILE *filep;
{
short s;
s = getc(filep) & 0xff;
s += (getc(filep) & 0xff)<<8;
return(s);
}
int getlong(filep)
FILE *filep;
{
int l;
l = getc(filep) & 0xff;
l += (getc(filep) & 0xff) <<8;
l += (getc(filep) & 0xff) <<16;
l += (getc(filep) & 0xff) <<24;
return(l);
}
void putshort(d, filep)
short d;
FILE *filep;
{
putc(d & 0xff, filep);
putc((d & 0xff00) >> 8, filep);
}
void putlong(d, filep)
long d;
FILE *filep;
{
putc(d & 0xff, filep);
putc((d & 0xff00) >> 8, filep);
putc((d & 0xff0000) >> 16, filep);
putc((d & 0xff000000) >> 24, filep);
}
int readdir(dir, wadfile)
direntry dir[];
FILE *wadfile;
{
int i, numentries, dirstart;
fseek(wadfile, 4, 0); /* Skip four bytes */
numentries = getlong(wadfile);
dirstart = getlong(wadfile);
if(fseek(wadfile, dirstart, 0))
{
fprintf(stderr, "File seek error.\n");
exit(-1);
}
for(i=0; i<numentries; i++)
{
dir[i].pos = getlong(wadfile);
dir[i].size = getlong(wadfile);
fread(dir[i].name, 8, 1, wadfile);
}
return numentries;
}
void copytoflats(iwadfile, dir1, numentries1,
newiwadfile, dir3, numentries3)
FILE *iwadfile;
direntry dir1[];
int numentries1;
FILE *newiwadfile;
direntry dir3[];
int *numentries3;
{
int i, j, pos;
fprintf(newiwadfile, "IWAD");
putlong(0, newiwadfile); /* Save for later */
putlong(0, newiwadfile); /* Save for later */
pos = 12;
i = 0;
while(strncmp(dir1[i].name, "F_START", 7))
{
fseek(iwadfile, dir1[i].pos, 0);
for(j=0; j<dir1[i].size; j++)
putc(getc(iwadfile), newiwadfile);
dir3[i].pos = pos;
dir3[i].size = dir1[i].size;
pos += dir3[i].size;
strncpy(dir3[i].name, dir1[i].name, 8);
i++;
}
*numentries3 = i;
}
void mergeflats(iwadfile, dir1, numentries1,
pwadfile, dir2, numentries2,
newiwadfile, dir3, numentries3)
FILE *iwadfile;
direntry dir1[];
int numentries1;
FILE *pwadfile;
direntry dir2[];
int numentries2;
FILE *newiwadfile;
direntry dir3[];
int *numentries3;
{
int i1, i2, j, pos;
i1 = 0;
i2 = 0;
while(strcmp(dir1[i1].name, "F_START")) i1++;
while(strcmp(dir2[i2].name, "F_START")) i2++;
/* Find out where the flats section starts in the NEW file. */
/* Note that this will not necessarily be the same position */
/* as in the original IWAD. There are holes in DOOM.WAD ! */
/* Also, don't trust the position of zero length entries. */
for(j=0; ((*numentries3-j)>=0) & (dir3[*numentries3-j].size == 0); j++);
if((*numentries3-j)<0)
pos = 12; /* The flats start directly after the header */
else
/* The flats start after the closest preceding non-zero length entry */
pos = dir3[*numentries3-j].pos + dir3[*numentries3-j].size;
while(strcmp(dir1[i1].name, "F1_END") & strcmp(dir2[i2].name, "F1_END"))
{
if(strncmp(dir1[i1].name, dir2[i2].name, 8))
{
/* No replacement - copy the old entry */
fseek(iwadfile, dir1[i1].pos, 0);
for(j=0; j<dir1[i1].size; j++)
putc(getc(iwadfile), newiwadfile);
dir3[*numentries3].pos = pos;
dir3[*numentries3].size = dir1[i1].size;
pos += dir3[*numentries3].size;
strncpy(dir3[*numentries3].name, dir1[i1].name, 8);
(*numentries3)++;
i1++;
}
else
/* Replacement entry - copy the new entry instead */
{
fseek(pwadfile, dir2[i2].pos, 0);
for(j=0; j<dir2[i2].size; j++)
putc(getc(pwadfile), newiwadfile);
dir3[*numentries3].pos = pos;
dir3[*numentries3].size = dir2[i2].size;
pos += dir3[*numentries3].size;
strncpy(dir3[*numentries3].name, dir2[i2].name, 8);
(*numentries3)++;
i1++;
i2++;
}
}
/* Copy any remaining original entries */
while(strcmp(dir1[i1].name, "F1_END"))
{
fseek(iwadfile, dir1[i1].pos, 0);
for(j=0; j<dir1[i1].size; j++)
putc(getc(iwadfile), newiwadfile);
dir3[*numentries3].pos = pos;
dir3[*numentries3].size = dir1[i1].size;
pos += dir3[*numentries3].size;
strncpy(dir3[*numentries3].name, dir1[i1].name, 8);
(*numentries3)++;
i1++;
}
/* Add new entries, if any */
while(strcmp(dir2[i2].name, "F1_END"))
{
fseek(pwadfile, dir2[i2].pos, 0);
for(j=0; j<dir2[i2].size; j++)
putc(getc(pwadfile), newiwadfile);
dir3[*numentries3].pos = pos;
dir3[*numentries3].size = dir2[i2].size;
pos += dir3[*numentries3].size;
strncpy(dir3[*numentries3].name, dir2[i2].name, 8);
(*numentries3)++;
i2++;
}
/* Repeat the above procedure for the F2 section as well */
while(strcmp(dir1[i1].name, "F2_END") & strcmp(dir2[i2].name, "F2_END"))
{
if(strncmp(dir1[i1].name, dir2[i2].name, 8))
{
/* No replacement - copy the old entry */
fseek(iwadfile, dir1[i1].pos, 0);
for(j=0; j<dir1[i1].size; j++)
putc(getc(iwadfile), newiwadfile);
dir3[*numentries3].pos = pos;
dir3[*numentries3].size = dir1[i1].size;
pos += dir3[*numentries3].size;
strncpy(dir3[*numentries3].name, dir1[i1].name, 8);
(*numentries3)++;
i1++;
}
else
/* Replacement entry - copy the new entry instead */
{
fseek(pwadfile, dir2[i2].pos, 0);
for(j=0; j<dir2[i2].size; j++)
putc(getc(pwadfile), newiwadfile);
dir3[*numentries3].pos = pos;
dir3[*numentries3].size = dir2[i2].size;
pos += dir3[*numentries3].size;
strncpy(dir3[*numentries3].name, dir2[i2].name, 8);
(*numentries3)++;
i1++;
i2++;
}
}
/* Copy any remaining original entries */
while(strcmp(dir1[i1].name, "F2_END"))
{
fseek(iwadfile, dir1[i1].pos, 0);
for(j=0; j<dir1[i1].size; j++)
putc(getc(iwadfile), newiwadfile);
dir3[*numentries3].pos = pos;
dir3[*numentries3].size = dir1[i1].size;
pos += dir3[*numentries3].size;
strncpy(dir3[*numentries3].name, dir1[i1].name, 8);
(*numentries3)++;
i1++;
}
/* Add new entries, if any */
while(strcmp(dir2[i2].name, "F2_END"))
{
fseek(pwadfile, dir2[i2].pos, 0);
for(j=0; j<dir2[i2].size; j++)
putc(getc(pwadfile), newiwadfile);
dir3[*numentries3].pos = pos;
dir3[*numentries3].size = dir2[i2].size;
pos += dir3[*numentries3].size;
strncpy(dir3[*numentries3].name, dir2[i2].name, 8);
(*numentries3)++;
i2++;
}
/* Write the F2_END and F_END markers and exit */
dir3[*numentries3].pos = pos;
dir3[*numentries3].size = 0;
strncpy(dir3[*numentries3].name, "F2_END", 8);
(*numentries3)++;
dir3[*numentries3].pos = pos;
dir3[*numentries3].size = 0;
strncpy(dir3[*numentries3].name, "F_END", 8);
(*numentries3)++;
}
void writedir(wadfile, dir, n)
FILE *wadfile;
direntry dir[];
int n;
{
int i, dirstart;
for(i=0; i<n; i++)
{
putlong(dir[i].pos, wadfile);
putlong(dir[i].size, wadfile);
fwrite(dir[i].name, 8, 1, wadfile);
}
for(i=0; ((n-i)>=0) & (dir[n-i].size == 0); i++);
if((n-i)<0)
dirstart = 12;
else
dirstart = dir[n-i].pos + dir[n-i].size;
fseek(wadfile, 4, 0);
putlong(n, wadfile);
putlong(dirstart, wadfile);
}
main(argc, argv)
int argc;
char *argv[];
{
FILE *iwadfile, *pwadfile, *newiwadfile;
char identifier[4];
int i, numentries1, numentries2, numentries3;
direntry dir1[4096], dir2[1024], dir3[4096];
if (argc != 4)
{
fprintf(stderr, "Usage: %s iwad pwad newiwad\n", argv[0]);
exit(-1);
}
iwadfile = fopen(argv[1], "r");
if(iwadfile == NULL)
{
fprintf(stderr, "File %s not found.\n", argv[1]);
exit(-1);
}
fread(identifier, 4, 1, iwadfile);
if(strncmp("IWAD", identifier, 4))
{
fprintf(stderr, "File %s is not an IWAD file.\n", argv[1]);
exit(-1);
}
numentries1 = readdir(dir1, iwadfile);
pwadfile = fopen(argv[2], "r");
if(pwadfile == NULL)
{
fprintf(stderr, "File %s not found.\n", argv[2]);
exit(-1);
}
fread(identifier, 4, 1, pwadfile);
if(strncmp("PWAD", identifier, 4))
{
fprintf(stderr, "File %s is not a PWAD file.\n", argv[2]);
exit(-1);
}
numentries2 = readdir(dir2, pwadfile);
newiwadfile = fopen(argv[3], "w");
if(pwadfile == NULL)
{
fprintf(stderr, "Unable to open output file %s.\n", argv[3]);
exit(-1);
}
printf("Copying other entries from %s to %s...\n", argv[1], argv[3]);
copytoflats(iwadfile, dir1, numentries1,
newiwadfile, dir3, &numentries3);
printf("Merging flat entries from %s and %s into %s...\n",
argv[1], argv[2], argv[3]);
mergeflats(iwadfile, dir1, numentries1,
pwadfile, dir2, numentries2,
newiwadfile, dir3, &numentries3);
printf("Writing directory to %s.\n", argv[3]);
writedir(newiwadfile, dir3, numentries3);
fclose(iwadfile);
fclose(pwadfile);
fclose(newiwadfile);
}