home *** CD-ROM | disk | FTP | other *** search
/ Doom 2 Explosion / Doom2Explosion.bin / doom2exp / programs / wadgc2 / wadgc.c < prev    next >
C/C++ Source or Header  |  1994-07-31  |  26KB  |  919 lines

  1. /* WADGC.C */
  2. /* A simple program to make Doom sprites, wall patches,
  3.    textures and floortiles and put them in a PWAD file
  4.    for inclusion in custom Doom levels.
  5.    Temporary beta version only - no support guaranteed!
  6.    Author: Stefan Gustavson (stefang@isy.liu.se) 1994
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <search.h>
  12. #include "doompal.h"
  13.  
  14. unsigned char sortedpal[256][4];
  15.  
  16. #define T1FILENAME "texture1.raw"
  17. #define T2FILENAME "texture2.raw"
  18. #define PNFILENAME "pnames.raw"
  19.  
  20.  
  21. #define square(x) ((x)*(x))
  22. #define TRUE (1)
  23. #define FALSE (0)
  24.  
  25. int comparecols(col1, col2)
  26.      char *col1, *col2;
  27. {
  28.   return(strncmp(col1, col2, 3));
  29. }
  30.  
  31. int lookup(pixel, palette, warning)
  32.      unsigned char pixel[4], palette[][4];
  33.      int *warning;
  34. {
  35.   char *p;
  36.   int i,index,err,minerr;
  37.  
  38.   /* Cyan in the input means transparent like in DMGRAPH */
  39.   if((pixel[0]==0)&&(pixel[1]==255)&&(pixel[2]==255))
  40.     return(-1);
  41.   /* Quick look for a perfect match - this requires a sorted palette */
  42.   p = (char*)bsearch(pixel, palette, 256, 4, comparecols);
  43.   if (p!=NULL) return(p[3]);
  44.  
  45.   /* If no perfect match is found, issue a warning and */
  46.   /* perform an extensive search for the closest match */
  47.   if(!*warning) /* Warn only once */
  48.     {
  49.       fprintf(stderr, "WARNING: the PPM file uses colors not present\n%s\n",
  50.           "in the Doom palette. The quantization will take some time.");
  51.       *warning = TRUE;
  52.     }
  53.   minerr=256*256*3;
  54.   for(i=0; i<256; i++)
  55.     {
  56.       err=(square(pixel[0]-palette[i][0])
  57.            + square(pixel[1]-palette[i][1])
  58.            + square(pixel[2]-palette[i][2]));
  59.       if(err<minerr)
  60.         {
  61.           minerr = err;
  62.           index = i;
  63.         }
  64.     }
  65.   return(index);
  66. }
  67.  
  68.  
  69. int findpatch(name, nump, pname)
  70.      char *name;
  71.      int nump;
  72.      char pname[][8];
  73. {
  74.   int i;
  75.   i=0;
  76.   while(strncmp(name, pname[i], 8) && (i<nump)) i++;
  77.   if(i==nump)
  78.     {
  79.       fprintf(stderr,"Couldn't find wall patch %s", name);
  80.       exit(-1);
  81.     }
  82.   return(i);
  83. }
  84.  
  85.  
  86. readppmfile(ppmfilename, imagedata, imgw, imgh)
  87.      char *ppmfilename;
  88.      short **imagedata;
  89.      int *imgw, *imgh;
  90. {
  91.   FILE *ppmfile;
  92.   char magic[2];
  93.   short *imageptr;
  94.   int i, warning;
  95.   unsigned char pixel[3];
  96.   
  97.   printf("Reading PPM file %s... \n", ppmfilename);
  98.   ppmfile = fopen(ppmfilename, "r");
  99.   if (ppmfile == NULL)
  100.     {
  101.       fprintf(stderr,"Unable to open PPM file %s.\n", ppmfilename);
  102.       exit(-1);
  103.     }
  104.   if(*imagedata != NULL) free(*imagedata);
  105.   fscanf(ppmfile, "%2c", magic);
  106.   if ((magic[0]!='P') || (magic[1]!='6'))
  107.     {
  108.       fprintf(stderr,"Image file %s is not a raw PPM file!\n", ppmfilename);
  109.       exit(-1);
  110.     }
  111.   fscanf(ppmfile, " ");
  112.   while(ungetc(getc(ppmfile),ppmfile) == '#') /* While comment */
  113.     while(getc(ppmfile) != '\n'); /* Read to end-of-line */
  114.   fscanf(ppmfile, " %d %d %*d%*1c", imgw, imgh);
  115.   imageptr = *imagedata = (short *)malloc(*imgw * *imgh * sizeof(short));
  116.   
  117.   warning = FALSE;
  118.   for (i=0; i<(*imgw * *imgh); i++)
  119.     {
  120.       pixel[0]=getc(ppmfile); /* Red */
  121.       pixel[1]=getc(ppmfile); /* Grn */
  122.       pixel[2]=getc(ppmfile); /* Blu */
  123.       *imageptr++ = (short)lookup(pixel, sortedpal, &warning);
  124.     }
  125.   fclose(ppmfile);
  126. }
  127.  
  128.  
  129. void rawtodoom(imagedata,imgw,imgh,ox,oy,w,h,x,y, doomimage, reslength)
  130.      short *imagedata;
  131.      int imgw, imgh, ox, oy, w, h, x, y;
  132.      unsigned char *doomimage;
  133.      int *reslength;
  134. {
  135.   int i,j;
  136.   int dataptr, tempptr;
  137.   short pxl;
  138.  
  139.   doomimage[0]= w & 0xff;
  140.   doomimage[1]= (w & 0xff00) >> 8;
  141.   doomimage[2]= h & 0xff;
  142.   doomimage[3]= (h & 0xff00) >> 8;
  143.   doomimage[4]= x & 0xff;
  144.   doomimage[5]= (x & 0xff00) >> 8;
  145.   doomimage[6]= y & 0xff;
  146.   doomimage[7]= (y & 0xff00) >> 8;
  147.   /* doomimage[8] to doomimage[8+w*4-1] are column indices */
  148.   dataptr=8+w*4;
  149.   for(i=0; i<w; i++)
  150.     {
  151.       doomimage[8+4*i] = dataptr & 0xff;
  152.       doomimage[8+4*i+1] = (dataptr & 0xff00) >> 8;
  153.       doomimage[8+4*i+2] = (dataptr & 0xff0000) >> 16;
  154.       doomimage[8+4*i+3] = (dataptr & 0xff000000) >> 24;
  155.  
  156.       j=0;
  157.       while(j<h)
  158.     {
  159.       while((imagedata[(oy+j)*imgw+ox+i]==-1) && (j<h)) j++;
  160.       if (j>=h) break;
  161.       /* Write out one post */
  162.       doomimage[dataptr++]=j & 0xff;
  163.       tempptr = dataptr++;
  164.       doomimage[dataptr++]=0; /* One dummy pixel for some reason */
  165.       while((j<h) && ((pxl=imagedata[(oy+j)*imgw+ox+i]) != -1))
  166.         {
  167.           doomimage[dataptr++]=pxl;
  168.           j++;
  169.         }
  170.       doomimage[dataptr++]=0; /* One dummy pixel for some reason */
  171.       doomimage[tempptr] = dataptr - tempptr - 3;
  172.     }
  173.       /* Write out the end-of-column marker */
  174.       doomimage[dataptr++]=255;
  175.     }
  176.   *reslength = dataptr;
  177. }
  178.  
  179.  
  180. void appenddata(wadfile, filename)
  181.      FILE *wadfile;
  182.      char *filename;
  183. {
  184.   FILE *datafile;
  185.   int buf;
  186.  
  187.   datafile = fopen(filename, "r");
  188.   if(datafile != NULL)
  189.     {
  190.       while (!feof(datafile))
  191.     {
  192.       buf = getc(datafile);
  193.       if(!feof(datafile)) putc(buf,wadfile);
  194.     }
  195.       fclose(datafile);
  196.     }
  197. }
  198.  
  199.  
  200. int getshort(filep)
  201.      FILE *filep;
  202. {
  203.   short s;
  204.   s = getc(filep) & 0xff;
  205.   s += (getc(filep) & 0xff)<<8;
  206.   return(s);
  207. }
  208.  
  209. int getlong(filep)
  210.      FILE *filep;
  211. {
  212.   int l;
  213.   l = getc(filep) & 0xff;
  214.   l += (getc(filep) & 0xff) <<8;
  215.   l += (getc(filep) & 0xff) <<16;
  216.   l += (getc(filep) & 0xff) <<24;
  217.   return(l);
  218. }
  219.  
  220. void putshort(d, filep)
  221.      short d;
  222.      FILE *filep;
  223. {
  224.   putc(d & 0xff, filep);
  225.   putc((d & 0xff00) >> 8, filep);  
  226. }
  227.  
  228. void putlong(d, filep)
  229.      long d;
  230.      FILE *filep;
  231. {
  232.   putc(d & 0xff, filep);
  233.   putc((d & 0xff00) >> 8, filep);
  234.   putc((d & 0xff0000) >> 16, filep);
  235.   putc((d & 0xff000000) >> 24, filep);
  236. }
  237.  
  238.  
  239. void allowcomment(infile)
  240.      FILE *infile;
  241. {
  242.   while (ungetc(getc(infile),infile) == '#')
  243.     while (getc(infile) != '\n');
  244. }
  245.  
  246.  
  247. int initpnames(filename, pname)
  248.      char *filename;
  249.      char pname[][8];
  250. {
  251.   FILE *pnfile;
  252.   int n;
  253.   pnfile = fopen(filename, "r");
  254.   if(pnfile==NULL)
  255.     {
  256.       fprintf(stderr, "Unable to open data file %s.\n", filename);
  257.       exit(-1);
  258.     }
  259.   n = getlong(pnfile);
  260.   fread(pname, 8, n, pnfile);
  261.   fclose(pnfile);
  262.   return(n);
  263. }
  264.  
  265.  
  266. int inittexture(filename, tsize, reslength, datafile)
  267.      char *filename;
  268.      long tsize[];
  269.      int *reslength;
  270.      FILE *datafile;
  271. {
  272.   FILE *tfile;
  273.   int numtextures, i, j, n;
  274.   char tname[8];
  275.  
  276.   tfile = fopen(filename, "r");
  277.   if(tfile==NULL)
  278.     {
  279.       fprintf(stderr, "Unable to open data file %s.\n", filename);
  280.       exit(-1);
  281.     }
  282.   numtextures = getlong(tfile);
  283.   for(i=0; i<numtextures; i++)
  284.     getlong(tfile); /* Skip the pointer table - it is rebuilt later */
  285.   for(i=0; i<numtextures; i++)
  286.     {
  287.       fread(tname, 8, 1, tfile);
  288.       fwrite(tname, 8, 1, datafile);
  289.       putshort(getshort(tfile), datafile);
  290.       putshort(getshort(tfile), datafile);
  291.       putshort(getshort(tfile), datafile); /* Width */
  292.       putshort(getshort(tfile), datafile); /* Height */
  293.       putlong(getlong(tfile), datafile);
  294.       putshort(n = getshort(tfile), datafile); /* Numpatches */
  295.       for(j=0; j<n; j++)
  296.     {
  297.       putshort(getshort(tfile), datafile); /* X offset */
  298.       putshort(getshort(tfile), datafile); /* Y offset */
  299.       putshort(getshort(tfile), datafile); /* Patch index */
  300.       putshort(getshort(tfile), datafile);
  301.       putshort(getshort(tfile), datafile);
  302.     }
  303.       tsize[i] = 22 + 10 * n;
  304.       *reslength += tsize[i] + 4;
  305.     }
  306.   return numtextures;
  307. }
  308.  
  309. int createtexture(texturename, infile, datafile, numpatches, pname)
  310.      char *texturename;
  311.      FILE *infile, *datafile;
  312.      int numpatches;
  313.      char pname[][8];
  314. {
  315.   int w, h, texturepatches, x, y;
  316.   int i, j;
  317.   char texturename8[8];
  318.   char patchname[20];
  319.   fscanf(infile, " %d %d %d ", &w, &h, &texturepatches);
  320.   allowcomment(infile);
  321.   strncpy(texturename8, texturename, 8);
  322.   fwrite(texturename8, 8, 1, datafile);
  323.   putshort(0, datafile);
  324.   putshort(0, datafile);
  325.   putshort(w, datafile);
  326.   putshort(h, datafile);
  327.   putlong(0, datafile);
  328.   putshort(texturepatches, datafile);
  329.   for (i=0; i< texturepatches; i++)
  330.     {
  331.       fscanf(infile, " %s %d %d ", patchname, &x, &y);
  332.       allowcomment(infile);
  333.       j = findpatch(patchname, numpatches, pname);
  334.       putshort(x, datafile);
  335.       putshort(y, datafile);
  336.       putshort(j, datafile);
  337.       putshort(0, datafile);
  338.       putshort(0, datafile);
  339.     }
  340.   return (22 + 10 * texturepatches);
  341.   /* t1size[numt1++] = 22 + 10 * texturepatches; */
  342.   /* reslength += t1size[numt1-1] + 4; */
  343.   /* fscanf(infile, " %s ", keyword); */
  344. }
  345.  
  346. main(argc, argv)
  347.      int argc;
  348.      char *argv[];
  349. {
  350.   FILE *infile, *wadfile;
  351.   FILE *dirfile1, *dirfile2, *datafile, *origfile;
  352.   char keyword[20];
  353.   char spritename[20], patchname[20], texturename[20], tilename[20];
  354.   char origname[8];
  355.   char ppmfilename[80], lastppmfilename[80];
  356.   short *imagedata;
  357.   int imgw, imgh;
  358.   int ox, oy, w, h, x, y;
  359.   unsigned char *doomimage;
  360.   int reslength, ackreslength, numdirentries;
  361.   int i, j;
  362.   int lastsprite;
  363.   char pname[1024][8]; /* For PNAMES index lookup entry */
  364.   int texturepatches, numpatches;
  365.   long t1size[512]; /* Temp buffer for TEXTURE1 sizes */
  366.   long t2size[512]; /* Temp buffer for TEXTURE2 sizes */
  367.   int numt1, numt2, orignumt1, orignumt2, ackpos;
  368.   char entryname[9], entryname8[8];
  369.   int entrysize, entrypos;
  370.   int spritesection, patchsection, texture1section, texture2section;
  371.   int flat1section, flat2section;
  372.  
  373.   if (argc != 3)
  374.     {
  375.       fprintf(stderr,"Usage: %s infile outfile\n", argv[0]);
  376.       exit(-1);
  377.     }
  378.   infile=fopen(argv[1],"r");
  379.   if(infile==NULL)
  380.     {
  381.       fprintf(stderr,"Unable to open input file %s\n", argv[1]);
  382.       exit(-1);
  383.     }
  384.   wadfile=fopen(argv[2],"w");
  385.   if(wadfile==NULL)
  386.     {
  387.       fprintf(stderr,"Unable to create output file %s\n", argv[2]);
  388.       exit(-1);
  389.     }
  390.   dirfile1=fopen("temp.d1","w"); /* Directory for TEXTURE1&2 and PNAMES */
  391.   if(dirfile1==NULL)
  392.     {
  393.       fprintf(stderr,"Unable to create temporary file temp.d1\n");
  394.       exit(-1);
  395.     }
  396.   dirfile2=fopen("temp.d2","w"); /* Directory from S_START to F_END */
  397.   if(dirfile2==NULL)
  398.     {
  399.       fprintf(stderr,"Unable to create temporary file temp.d2\n");
  400.       exit(-1);
  401.     }
  402.   lastppmfilename[0] = '\0';
  403.   imagedata = NULL;
  404.   /* No dynamic allocation - just make room for a full 320x200 image */
  405.   doomimage = (unsigned char *)malloc(68168*sizeof(char));
  406.   ackreslength = 0;
  407.   numdirentries = 0;
  408.  
  409.   /* Sort the palette to speed up the image input */
  410.   for(i=0; i<256; i++)
  411.     {
  412.       sortedpal[i][0]=doompal[i][0];
  413.       sortedpal[i][1]=doompal[i][1];
  414.       sortedpal[i][2]=doompal[i][2];
  415.       sortedpal[i][3]=i;
  416.     }      
  417.   qsort((char*)sortedpal, 256, 4, comparecols);
  418.  
  419.   spritesection = FALSE;
  420.   patchsection = FALSE;
  421.   texture1section = FALSE;
  422.   texture2section = FALSE;
  423.   flat1section = FALSE;
  424.   flat2section = FALSE;
  425.  
  426.   allowcomment(infile);
  427.   fscanf(infile, " %s ", keyword);
  428.  
  429.   if(!strcmp(keyword,"S_START"))
  430.     {
  431.       spritesection = TRUE;
  432.       datafile=fopen("temp.s","w");
  433.       if(datafile==NULL)
  434.     {
  435.       fprintf(stderr,"Unable to create temporary file temp.s\n");
  436.       exit(-1);
  437.     }
  438.       fprintf(dirfile2, "S_START 0\n");
  439.       numdirentries +=1;
  440.       /* Process sprites until S_END is found */
  441.       lastsprite = 0;
  442.       while(!lastsprite)
  443.     {
  444.       allowcomment(infile);
  445.       fscanf(infile, " %s ", spritename);
  446.       if(!strcmp(spritename,"S_END")) lastsprite = 1;
  447.       else
  448.         {
  449.           printf("Creating sprite %s... \n", spritename);
  450.           fscanf(infile, " %s @ %d %d W %d H %d X %d Y %d ",
  451.              ppmfilename, &ox, &oy, &w, &h, &x, &y);
  452.           allowcomment(infile);
  453.           /* If the ppm file is not the same as before: read it in */
  454.           if(strcmp(ppmfilename, lastppmfilename))
  455.         {
  456.           readppmfile(ppmfilename, &imagedata, &imgw, &imgh);
  457.           strcpy(lastppmfilename, ppmfilename);
  458.         }
  459.           /* Clip out the specified region and convert it */
  460.           rawtodoom(imagedata, imgw, imgh, ox, oy, w, h, x, y,
  461.             doomimage, &reslength);
  462.           /* Write data to datafile and some info to dirfile2 */
  463.           for(i=0; i<reslength; i++)
  464.         putc(doomimage[i], datafile);
  465.           fprintf(dirfile2, "%s %d\n", spritename, reslength);
  466.           ackreslength += reslength;
  467.           numdirentries +=1;
  468.         }
  469.     }
  470.       fprintf(dirfile2, "S_END 0\n");
  471.       numdirentries +=1;
  472.       fclose(datafile);
  473.       fscanf(infile, " %s ", keyword);
  474.     }
  475.  
  476.   if(!strcmp(keyword,"P_START"))
  477.     {
  478.       patchsection = TRUE;
  479.       /* Initialize PNAMES with all the original entries */
  480.       numpatches = initpnames(PNFILENAME, pname);
  481.       datafile=fopen("temp.p","w");
  482.       if(datafile==NULL)
  483.     {
  484.       fprintf(stderr,"Unable to create temporary file temp.p\n");
  485.       exit(-1);
  486.     }
  487.       /* Read patches one by one, updating pname[] and numpatches */
  488.       lastsprite = 0;
  489.       while(!lastsprite)
  490.     {
  491.       allowcomment(infile);
  492.       fscanf(infile, " %s ", spritename);
  493.       if(!strcmp(spritename,"P_END")) lastsprite = 1;
  494.       else
  495.         {
  496.           printf("Creating wall patch %s... \n", spritename);
  497.           strncpy(pname[numpatches++], spritename, 8);
  498.           fscanf(infile, " %s @ %d %d W %d H %d ",
  499.              ppmfilename, &ox, &oy, &w, &h);
  500.           allowcomment(infile);
  501.           /* If the ppm file is not the same as before: read it in */
  502.           if(strcmp(ppmfilename, lastppmfilename))
  503.         {
  504.           readppmfile(ppmfilename, &imagedata, &imgw, &imgh);
  505.           strcpy(lastppmfilename, ppmfilename);
  506.         }
  507.           /* Clip out the specified region and convert it */
  508.           rawtodoom(imagedata, imgw, imgh, ox, oy, w, h, w/2-1, h,
  509.             doomimage, &reslength);
  510.           /* Write data to datafile and some info to dirfile2 */
  511.           for(i=0; i<reslength; i++)
  512.         putc(doomimage[i], datafile);
  513.           fprintf(dirfile2, "%s %d\n", spritename, reslength);
  514.           ackreslength += reslength;
  515.           numdirentries +=1;
  516.         }
  517.     }
  518.       fclose(datafile);
  519.       allowcomment(infile);
  520.       fscanf(infile, " %s ", keyword);
  521.     }  
  522.   
  523.  
  524.   numt1 = 0;
  525.   if(!strcmp(keyword,"TEXTURE1_START"))
  526.     {
  527.       texture1section = TRUE;
  528.       datafile=fopen("temp.t1","w");
  529.       reslength = 4;
  530.       /* Open the file containing all the original entries */
  531.       origfile = fopen(T1FILENAME, "r");
  532.       if(origfile==NULL)
  533.     {
  534.       fprintf(stderr, "Unable to open data file %s.\n", T1FILENAME);
  535.       exit(-1);
  536.     }
  537.       orignumt1 = getlong(origfile);
  538.       for(i=0; i<orignumt1; i++)
  539.     getlong(origfile); /* Skip the pointer table - it is rebuilt later */
  540.       fread(origname, 8, 1, origfile);
  541.       
  542.       /* Read the textures, updating t1size, numt1 and reslength */
  543.       allowcomment(infile);
  544.       fscanf(infile, " %s ", keyword);
  545.       while(strcmp(keyword, "TEXTURE1_END"))
  546.     {
  547.       /* while ((original textures left) && (name does not match)) */
  548.       /*     copy one original texture to output */
  549.       while((numt1 < orignumt1) && (strncmp(origname, keyword, 8)))
  550.         {
  551.           fwrite(origname, 8, 1, datafile);
  552.           for(i=0; i<12; i++)
  553.         putc(getc(origfile), datafile);
  554.           texturepatches = getshort(origfile);
  555.           putshort(texturepatches, datafile);
  556.           for(i=0; i<texturepatches*10; i++)
  557.         putc(getc(origfile), datafile);
  558.           t1size[numt1] = 22 + texturepatches * 10;
  559.           reslength += t1size[numt1++] + 4;
  560.           if(numt1 < orignumt1)
  561.         fread(origname, 8, 1, origfile);
  562.         }
  563.  
  564.       /* if(name matches) */
  565.       /*     replace original texture with the new one */
  566.       /*     read past the original texture data */
  567.       if(!strncmp(origname, keyword, 8))
  568.         {
  569.           printf("Replacing texture %s...\n", keyword);
  570.           t1size[numt1] = createtexture(keyword, infile, datafile,
  571.                         numpatches, pname);
  572.           reslength += t1size[numt1] + 4;
  573.           numt1++;
  574.           for(i=0; i<12; i++)
  575.         getc(origfile);
  576.           texturepatches = getshort(origfile);
  577.           for(i=0; i<texturepatches*10; i++)
  578.         getc(origfile);
  579.           fscanf(infile, " %s ", keyword);
  580.           if(numt1 < orignumt1)
  581.         fread(origname, 8, 1, origfile);
  582.         }
  583.       else
  584.         {
  585.           /* No original entries remain, start creating new ones */
  586.           printf("Creating texture %s... \n", keyword);
  587.           t1size[numt1] = createtexture(keyword, infile, datafile,
  588.                         numpatches, pname);
  589.           reslength += t1size[numt1] + 4;
  590.           numt1++;
  591.           fscanf(infile, " %s ", keyword);
  592.         }
  593.     }
  594.       /* while (original textures left)          */
  595.       /*     copy one original texture to output */
  596.       while(numt1 < orignumt1)
  597.     {
  598.       fwrite(origname, 8, 1, datafile);
  599.       for(i=0; i<12; i++)
  600.         putc(getc(origfile), datafile);
  601.       texturepatches = getshort(origfile);
  602.       putshort(texturepatches, datafile);
  603.       for(i=0; i<texturepatches*10; i++)
  604.         putc(getc(origfile), datafile);
  605.       t1size[numt1] = 22 + texturepatches * 10;
  606.       reslength += t1size[numt1++] + 4;
  607.       if(numt1 < orignumt1)
  608.         fread(origname, 8, 1, origfile);
  609.     }
  610.       fprintf(dirfile1, "TEXTURE1 %d\n", reslength);
  611.       numdirentries +=1;
  612.       ackreslength += reslength;
  613.       fclose(datafile);
  614.       allowcomment(infile);
  615.       fscanf(infile, " %s ", keyword);
  616.     }
  617.   
  618.   numt2 = 0;
  619.   if(!strcmp(keyword,"TEXTURE2_START"))
  620.     {
  621.       texture2section = TRUE;
  622.       datafile=fopen("temp.t2","w");
  623.       reslength = 4;
  624.       /* Open the file containing all the original entries */
  625.       origfile = fopen(T2FILENAME, "r");
  626.       if(origfile==NULL)
  627.     {
  628.       fprintf(stderr, "Unable to open data file %s.\n", T2FILENAME);
  629.       exit(-1);
  630.     }
  631.       orignumt2 = getlong(origfile);
  632.       for(i=0; i<orignumt2; i++)
  633.     getlong(origfile); /* Skip the pointer table - it is rebuilt later */
  634.       fread(origname, 8, 1, origfile);
  635.       
  636.       /* Read the textures, updating t2size, numt2 and reslength */
  637.       allowcomment(infile);
  638.       fscanf(infile, " %s ", keyword);
  639.       while(strcmp(keyword, "TEXTURE2_END"))
  640.     {
  641.       /* while ((original textures left) && (name does not match)) */
  642.       /*     copy one original texture to output */
  643.       while((numt2 < orignumt2) && (strncmp(origname, keyword, 8)))
  644.         {
  645.           fwrite(origname, 8, 1, datafile);
  646.           for(i=0; i<12; i++)
  647.         putc(getc(origfile), datafile);
  648.           texturepatches = getshort(origfile);
  649.           putshort(texturepatches, datafile);
  650.           for(i=0; i<texturepatches*10; i++)
  651.         putc(getc(origfile), datafile);
  652.           t2size[numt2] = 22 + texturepatches * 10;
  653.           reslength += t2size[numt2++] + 4;
  654.           if(numt2 < orignumt2)
  655.         fread(origname, 8, 1, origfile);
  656.         }
  657.  
  658.       /* if(name matches) */
  659.       /*     replace original texture with the new one */
  660.       /*     read past the original texture data */
  661.       if(!strncmp(origname, keyword, 8))
  662.         {
  663.           printf("Replacing texture %s...\n", keyword);
  664.           t2size[numt2] = createtexture(keyword, infile, datafile,
  665.                         numpatches, pname);
  666.           reslength += t2size[numt2] + 4;
  667.           numt2++;
  668.           for(i=0; i<12; i++)
  669.         getc(origfile);
  670.           texturepatches = getshort(origfile);
  671.           for(i=0; i<texturepatches*10; i++)
  672.         getc(origfile);
  673.           fscanf(infile, " %s ", keyword);
  674.           if(numt2 < orignumt2)
  675.         fread(origname, 8, 1, origfile);
  676.         }
  677.       else
  678.         {
  679.           /* No original entries remain, start creating new ones */
  680.           printf("Creating texture %s... \n", keyword);
  681.           t2size[numt2] = createtexture(keyword, infile, datafile,
  682.                         numpatches, pname);
  683.           reslength += t2size[numt2] + 4;
  684.           numt2++;
  685.           fscanf(infile, " %s ", keyword);
  686.         }
  687.     }
  688.       /* while (original textures left)          */
  689.       /*     copy one original texture to output */
  690.       while(numt2 < orignumt2)
  691.     {
  692.       fwrite(origname, 8, 1, datafile);
  693.       for(i=0; i<12; i++)
  694.         putc(getc(origfile), datafile);
  695.       texturepatches = getshort(origfile);
  696.       putshort(texturepatches, datafile);
  697.       for(i=0; i<texturepatches*10; i++)
  698.         putc(getc(origfile), datafile);
  699.       t2size[numt2] = 22 + texturepatches * 10;
  700.       reslength += t2size[numt2++] + 4;
  701.       if(numt2 < orignumt2)
  702.         fread(origname, 8, 1, origfile);
  703.     }
  704.       fprintf(dirfile1, "TEXTURE2 %d\n", reslength);
  705.       numdirentries +=1;
  706.       ackreslength += reslength;
  707.       fclose(datafile);
  708.       allowcomment(infile);
  709.       fscanf(infile, " %s ", keyword);
  710.     }
  711.  
  712.   if (patchsection)
  713.     {
  714.       fprintf(dirfile1, "PNAMES %d\n", numpatches*8+4);
  715.       numdirentries +=1;
  716.       ackreslength += (numpatches*8+4);
  717.     }
  718.   fclose(dirfile1);
  719.   
  720.   if(!strcmp(keyword,"F_START"))
  721.     {
  722.       fprintf(dirfile2, "F_START 0\n");
  723.       numdirentries +=1;
  724.       allowcomment(infile);
  725.       fscanf(infile, " %s ", keyword);
  726.       if(!strcmp(keyword,"F1_START"))
  727.     {
  728.       allowcomment(infile);
  729.       flat1section = TRUE;
  730.       fprintf(dirfile2, "F1_START 0\n");
  731.       numdirentries +=1;
  732.       datafile=fopen("temp.f1","w");
  733.       /* Read the floor tiles one by one, writing names to dirfile2 */
  734.       fscanf(infile, " %s ", keyword);
  735.       while(strcmp(keyword, "F1_END"))
  736.         {
  737.           printf("Creating floor/ceiling %s... \n", keyword);
  738.           fscanf(infile, " %s @ %d %d ", ppmfilename, &ox, &oy);
  739.           allowcomment(infile);
  740.           /* If the ppm file is not the same as before: read it in */
  741.           if(strcmp(ppmfilename, lastppmfilename))
  742.         {
  743.           readppmfile(ppmfilename, &imagedata, &imgw, &imgh);
  744.           strcpy(lastppmfilename, ppmfilename);
  745.         }
  746.           /* Write out the specified region in raw format */
  747.           for (i=0; i<64; i++)
  748.         for(j=0; j<64; j++)
  749.           putc(imagedata[(oy+i)*imgw+ox+j], datafile);
  750.           /* Write some info to dirfile2 */
  751.           fprintf(dirfile2, "%s %d\n", keyword, 4096);
  752.           ackreslength += 4096;
  753.           numdirentries +=1;
  754.           fscanf(infile, " %s ", keyword);
  755.         }
  756.       fprintf(dirfile2, "F1_END 0\n");
  757.       numdirentries +=1;
  758.       fclose(datafile);
  759.       allowcomment(infile);
  760.       fscanf(infile, " %s ", keyword);
  761.     }
  762.       if(!strcmp(keyword,"F2_START"))
  763.     {
  764.       allowcomment(infile);
  765.       flat2section = TRUE;
  766.       fprintf(dirfile2, "F2_START 0\n");
  767.       numdirentries +=1;
  768.       datafile=fopen("temp.f2","w");
  769.       /* Read the floor tiles one by one, writing names to dirfile2 */
  770.       fscanf(infile, " %s ", keyword);
  771.       while(strcmp(keyword, "F2_END"))
  772.         {
  773.           printf("Creating floor/ceiling %s... \n", keyword);
  774.           fscanf(infile, " %s @ %d %d ", ppmfilename, &ox, &oy);
  775.           allowcomment(infile);
  776.           /* If the ppm file is not the same as before: read it in */
  777.           if(strcmp(ppmfilename, lastppmfilename))
  778.         {
  779.           readppmfile(ppmfilename, &imagedata, &imgw, &imgh);
  780.           strcpy(lastppmfilename, ppmfilename);
  781.         }
  782.           /* Write out the specified region in raw format */
  783.           for (i=0; i<64; i++)
  784.         for(j=0; j<64; j++)
  785.           putc(imagedata[(oy+i)*imgw+ox+j], datafile);
  786.           /* Write some info to dirfile2 */
  787.           fprintf(dirfile2, "%s %d\n", keyword, 4096);
  788.           ackreslength += 4096;
  789.           numdirentries +=1;
  790.           allowcomment(infile);
  791.           fscanf(infile, " %s ", keyword);
  792.         }
  793.       fprintf(dirfile2, "F2_END 0\n");
  794.       numdirentries +=1;
  795.       fclose(datafile);
  796.       allowcomment(infile);
  797.       fscanf(infile, " %s ", keyword);
  798.     }
  799.       fprintf(dirfile2, "F_END 0\n");
  800.       numdirentries +=1;
  801.       allowcomment(infile);
  802.       fscanf(infile, " %s ", keyword);
  803.     }
  804.   fclose(infile);
  805.   fclose(dirfile2);
  806.   free(doomimage);
  807.  
  808.   /* Concatenate all the data into the final PWAD file */
  809.   printf("Creating WAD file %s... \n", argv[2]);
  810.  
  811.   /* Header */
  812.   fprintf(wadfile,"PWAD");
  813.   putlong(numdirentries, wadfile);
  814.   ackreslength += 12; /* The header is 12 bytes */
  815.   putlong(ackreslength, wadfile);
  816.  
  817.   /* TEXTURE1 */
  818.   if(texture1section)
  819.     {
  820.       printf("Adding entry TEXTURE1\n");
  821.       putlong(numt1, wadfile);
  822.       ackpos = 4 + numt1*4;
  823.       for(i=0; i<numt1; i++)
  824.     {
  825.       putlong(ackpos, wadfile);
  826.       ackpos += t1size[i];
  827.     }
  828.       appenddata(wadfile, "temp.t1");
  829.     }
  830.  
  831.   /* TEXTURE2 */
  832.   if(texture2section)
  833.     {
  834.       printf("Adding entry TEXTURE2\n");
  835.       putlong(numt2, wadfile);
  836.       ackpos = 4 + numt2*4;
  837.       for(i=0; i<numt2; i++)
  838.     {
  839.       putlong(ackpos, wadfile);
  840.       ackpos += t2size[i];
  841.     }
  842.       appenddata(wadfile, "temp.t2");
  843.     }
  844.  
  845.   /* PNAMES */
  846.   if(patchsection)
  847.     {
  848.       printf("Adding entry PNAMES\n");
  849.       putlong(numpatches, wadfile);
  850.       fwrite(&pname[0][0], 8, numpatches, wadfile);
  851.     }
  852.   
  853.   /* Sprites */
  854.   if(spritesection)
  855.     {
  856.       printf("Adding sprite entries\n");
  857.       appenddata(wadfile, "temp.s");
  858.     }
  859.  
  860.   /* Wall patches */
  861.   if(patchsection)
  862.     {
  863.       printf("Adding wall patch entries\n");
  864.       appenddata(wadfile, "temp.p");
  865.     }
  866.  
  867.   /* Floor tiles */
  868.   if (flat1section)
  869.     appenddata(wadfile, "temp.f1");
  870.   if (flat2section)
  871.     appenddata(wadfile, "temp.f2");
  872.   
  873.   /* Now, write the directory by using data from the directory files. */
  874.   entrypos = 12;
  875.   dirfile1 = fopen("temp.d1","r");
  876.   if(dirfile1 != NULL)
  877.     {
  878.       while(!feof(dirfile1))
  879.     {
  880.       fscanf(dirfile1, " %s %d", entryname, &entrysize);
  881.       if (!feof(dirfile1))
  882.         {
  883.           putlong(entrypos, wadfile);
  884.           putlong(entrysize, wadfile);
  885.           strncpy(entryname8, entryname, 8);
  886.           fwrite(entryname8, 8, 1, wadfile);
  887.           entrypos += entrysize;
  888.         }
  889.     }
  890.       fclose(dirfile1);
  891.     }
  892.   dirfile2 = fopen("temp.d2","r");
  893.   if(dirfile2 != NULL)
  894.     {
  895.       while(!feof(dirfile2))
  896.     {
  897.       fscanf(dirfile2, " %s %d", entryname, &entrysize);
  898.       if (!feof(dirfile2))
  899.         {
  900.           putlong(entrypos, wadfile);
  901.           putlong(entrysize, wadfile);
  902.           strncpy(entryname8, entryname, 8);
  903.           fwrite(entryname8, 8, 1, wadfile);
  904.           entrypos += entrysize;
  905.         }
  906.     }
  907.       fclose(dirfile2);
  908.     }
  909.  
  910.   /* DONE! */
  911.   printf("WAD file %s complete.\n", argv[2]);
  912.   fclose(wadfile);
  913. }
  914.  
  915.  
  916.  
  917.  
  918.  
  919.