home *** CD-ROM | disk | FTP | other *** search
/ Toolkit for DOOM / DOOMTOOL.ISO / editors / wadgc2.zip / WADLC.C < prev    next >
C/C++ Source or Header  |  1994-07-31  |  12KB  |  399 lines

  1. /* WADLC.C */
  2. /* A simple program to make custom Doom levels.
  3.    Temporary beta version only - no support guaranteed!
  4.    Author: Stefan Gustavson (stefang@isy.liu.se) 1994
  5.    The entries SEGS, SSECTORS, NODES, REJECT and BLOCKMAP
  6.    are left empty, but they are created in order not to
  7.    confuse level editors and the program WAD_DWD used as
  8.    a preprocessor to IDBSP.
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include "wadlc.h"
  14.  
  15.  
  16. void putshort(d, filep)
  17.      short d;
  18.      FILE *filep;
  19. {
  20.   putc(d & 0xff, filep);
  21.   putc((d & 0xff00) >> 8, filep);  
  22. }
  23.  
  24.  
  25. void putlong(d, filep)
  26.      long d;
  27.      FILE *filep;
  28. {
  29.   putc(d & 0xff, filep);
  30.   putc((d & 0xff00) >> 8, filep);
  31.   putc((d & 0xff0000) >> 16, filep);
  32.   putc((d & 0xff000000) >> 24, filep);
  33. }
  34.  
  35. void addentry(pos, length, name, wadfile)
  36.      int *pos, length;
  37.      char *name;
  38.      FILE *wadfile;
  39. {
  40.   static char entryname8[8];
  41.  
  42.   putlong(*pos, wadfile);
  43.   putlong(length, wadfile);
  44.   *pos += length;
  45.   strncpy(entryname8, name, 8);
  46.   fwrite(entryname8, 8, 1, wadfile);
  47.   printf("Adding entry %s (%d bytes)\n", name, length);
  48. }
  49.  
  50. int findmatch(name, table, numentries, length)
  51.      char *name;
  52.      char *table;
  53.      int numentries;
  54.      int length;
  55. {
  56.   int i;
  57.   i=0;
  58.   while(strncmp(name, table, 8) && (i<numentries))
  59.     {
  60.       i++;
  61.       table += length;
  62.     }
  63.   if(i==numentries)
  64.     {
  65.       fprintf(stderr,"Couldn't match name: %s", name);
  66.       exit(-1);
  67.     }
  68.   return(i);
  69. }
  70.  
  71.  
  72. void allowcomment(infile)
  73.      FILE *infile;
  74. {
  75.   while (ungetc(getc(infile),infile) == '#')
  76.     while (getc(infile) != '\n');
  77. }
  78.  
  79.  
  80. main(argc, argv)
  81.      int argc;
  82.      char *argv[];
  83. {
  84.   FILE *infile, *wadfile;
  85.   FILE *datafile;
  86.   char keyword[20];
  87.   char vertexname[20], sectorname[20];
  88.   char fromvertexname[20], tovertexname[20];
  89.   int ox, oy, x, y;
  90.   int numentries, reslength;
  91.   int i, j;
  92.   int episode, level;
  93.   int lastitem;
  94.   int floorh, ceilingh, brightness, special, tag, type, attrs, angle;
  95.   char floort[20], ceilingt[20];
  96.   char uppert[20], lowert[20], normalt[20];
  97.   char rightsidedefname[20], leftsidedefname[20], thingname[20];
  98.   int fromvertexindex, tovertexindex, rightsidedefindex, leftsidedefindex;
  99.   int sectorindex;
  100.   
  101.   vertex_t  vertices[4096];
  102.   sector_t  sectors[1024];
  103.   sidedef_t sidedefs[8192];
  104.   linedef_t linedefs[8192];
  105.   thing_t   things[1024];
  106.   int numvertices, numsectors, numsidedefs, numlinedefs, numthings;
  107.  
  108.   char entryname[9];
  109.   int entrysize, entrypos;
  110.  
  111.   if (argc != 3)
  112.     {
  113.       fprintf(stderr,"Usage: %s infile outfile\n", argv[0]);
  114.       exit(-1);
  115.     }
  116.   infile=fopen(argv[1],"r");
  117.   if(infile==NULL)
  118.     {
  119.       fprintf(stderr,"Unable to open input file %s\n", argv[1]);
  120.       exit(-1);
  121.     }
  122.   wadfile=fopen(argv[2],"w");
  123.   if(wadfile==NULL)
  124.     {
  125.       fprintf(stderr,"Unable to create output file %s\n", argv[2]);
  126.       exit(-1);
  127.     }
  128.   allowcomment(infile);
  129.   fscanf(infile, " %s ", keyword);
  130.  
  131.   if(!strcmp(keyword,"LEVEL_START"))
  132.     {
  133.       fscanf(infile, " %d %d ", &episode, &level);
  134.       allowcomment(infile);
  135.       fscanf(infile, " %s ", keyword);
  136.     }
  137.   else
  138.     {
  139.       fprintf(stderr,"LEVEL_START marker missing!\n");
  140.       exit(-1);
  141.     }
  142.  
  143.   if(!strcmp(keyword,"VERTEXES_START") |
  144.      !strcmp(keyword, "VERTICES_START"))
  145.     {
  146.       /* Process vertices until VERTEXES_END is found */
  147.       lastitem = 0;
  148.       numvertices = 0;
  149.       while(!lastitem)
  150.     {
  151.       allowcomment(infile);
  152.       fscanf(infile, " %s ", vertexname);
  153.       if(!strcmp(vertexname,"VERTEXES_END") |
  154.          !strcmp(vertexname, "VERTICES_END"))
  155.         lastitem = 1;
  156.       else
  157.         {
  158.           fscanf(infile, " : %d %d ", &x, &y);
  159.           allowcomment(infile);
  160.           vertices[numvertices].x = x;
  161.           vertices[numvertices].y = y;
  162.           strncpy(vertices[numvertices].name, vertexname, 8);
  163.           numvertices++;
  164.         }
  165.     }
  166.       fscanf(infile, " %s ", keyword);
  167.     }
  168.   else
  169.     {
  170.       fprintf(stderr,"VERTEXES_START marker missing!\n");
  171.       exit(-1);
  172.     }
  173.   
  174.   if(!strcmp(keyword,"SECTORS_START"))
  175.     {
  176.       /* Process sectors until SECTORS_END is found */
  177.       lastitem = 0;
  178.       numsectors = 0;
  179.       while(!lastitem)
  180.     {
  181.       allowcomment(infile);
  182.       fscanf(infile, " %s ", sectorname);
  183.       if(!strcmp(sectorname,"SECTORS_END")) lastitem = 1;
  184.       else
  185.         {
  186.           fscanf(infile, " : %d %d %s %s %d %d %d ", &floorh, &ceilingh,
  187.              floort, ceilingt, &brightness, &special, &tag);
  188.           allowcomment(infile);
  189.           sectors[numsectors].floorheight = floorh;
  190.           sectors[numsectors].ceilingheight = ceilingh;
  191.           sectors[numsectors].brightness = brightness;
  192.           sectors[numsectors].special = special;
  193.           sectors[numsectors].tag = tag;
  194.           strncpy(sectors[numsectors].name, sectorname, 8);
  195.           strncpy(sectors[numsectors].floortexture, floort, 8);
  196.           strncpy(sectors[numsectors].ceilingtexture, ceilingt, 8);
  197.           numsectors++;
  198.         }
  199.     }
  200.       fscanf(infile, " %s ", keyword);
  201.     }
  202.   else
  203.     {
  204.       fprintf(stderr,"SECTORS_START marker missing!\n");
  205.       exit(-1);
  206.     }
  207.  
  208.   if(!strcmp(keyword,"LINEDEFS_START"))
  209.     {
  210.       /* Process sectors until LINEDEFS_END is found */
  211.       lastitem = 0;
  212.       numlinedefs = 0;
  213.       while(!lastitem)
  214.     {
  215.       allowcomment(infile);
  216.       fscanf(infile, " %s ", fromvertexname);
  217.       if(!strcmp(fromvertexname,"LINEDEFS_END")) lastitem = 1;
  218.       else
  219.         {
  220.           fscanf(infile, " %s : %d %d %d ", tovertexname,
  221.              &attrs, &type, &tag);
  222.           allowcomment(infile);
  223.           fromvertexindex = findmatch(fromvertexname, (char*)vertices,
  224.                       numvertices, sizeof(vertex_t));
  225.           tovertexindex = findmatch(tovertexname, (char*)vertices,
  226.                       numvertices, sizeof(vertex_t));
  227.           /* Read one or two SIDEDEFS */
  228.           fscanf(infile, " %s %d %d %s %s %s ", sectorname, &ox, &oy,
  229.              uppert, lowert, normalt);
  230.           allowcomment(infile);
  231.           sectorindex = findmatch(sectorname, (char*)sectors,
  232.                       numsectors, sizeof(sector_t));
  233.           sidedefs[numsidedefs].sector = sectorindex;
  234.           sidedefs[numsidedefs].xoffset = ox;
  235.           sidedefs[numsidedefs].yoffset = oy;
  236.           strncpy(sidedefs[numsidedefs].uppertexture, uppert, 8);
  237.           strncpy(sidedefs[numsidedefs].lowertexture, lowert, 8);
  238.           strncpy(sidedefs[numsidedefs].normaltexture, normalt, 8);
  239.           rightsidedefindex = numsidedefs;
  240.           numsidedefs++;
  241.           fscanf(infile, "%s", sectorname);
  242.           if(!strcmp(sectorname, "-"))
  243.         {
  244.           allowcomment(infile);
  245.           leftsidedefindex = -1;
  246.         }
  247.           else
  248.         {
  249.           fscanf(infile, " %d %d %s %s %s ", &ox, &oy,
  250.              uppert, lowert, normalt);
  251.           allowcomment(infile);
  252.           sectorindex = findmatch(sectorname, (char*)sectors,
  253.                       numsectors, sizeof(sector_t));
  254.           sidedefs[numsidedefs].sector = sectorindex;
  255.           sidedefs[numsidedefs].xoffset = ox;
  256.           sidedefs[numsidedefs].yoffset = oy;
  257.           strncpy(sidedefs[numsidedefs].uppertexture, uppert, 8);
  258.           strncpy(sidedefs[numsidedefs].lowertexture, lowert, 8);
  259.           strncpy(sidedefs[numsidedefs].normaltexture, normalt, 8);
  260.           leftsidedefindex = numsidedefs;
  261.           numsidedefs++;
  262.         }
  263.           linedefs[numlinedefs].from = fromvertexindex;
  264.           linedefs[numlinedefs].to = tovertexindex;
  265.           linedefs[numlinedefs].attrs = attrs;
  266.           linedefs[numlinedefs].type = type;
  267.           linedefs[numlinedefs].tag = tag;
  268.           linedefs[numlinedefs].rightsidedef = rightsidedefindex;
  269.           linedefs[numlinedefs].leftsidedef = leftsidedefindex;
  270.           numlinedefs++;
  271.         }
  272.     }
  273.       fscanf(infile, " %s ", keyword);
  274.     }
  275.   else
  276.     {
  277.       fprintf(stderr,"LINEDEFS_START marker missing!\n");
  278.       exit(-1);
  279.     }
  280.  
  281.   if(!strcmp(keyword,"THINGS_START"))
  282.     {
  283.       /* Process things until THINGS_END is found */
  284.       lastitem = 0;
  285.       numthings = 0;
  286.       while(!lastitem)
  287.     {
  288.       allowcomment(infile);
  289.       fscanf(infile, " %s ", thingname);
  290.       if(!strcmp(thingname,"THINGS_END")) lastitem = 1;
  291.       else
  292.         {
  293.           sscanf(thingname, "%d", &type);
  294.           fscanf(infile, " : %d %d %d %d ", &x, &y, &angle, &attrs);
  295.           allowcomment(infile);
  296.           things[numthings].type = type;
  297.           things[numthings].x = x;
  298.           things[numthings].y = y;
  299.           things[numthings].angle = angle;
  300.           things[numthings].attrs = attrs;
  301.           numthings++;
  302.         }
  303.     }
  304.       fscanf(infile, " %s ", keyword);
  305.     }
  306.   else
  307.     {
  308.       fprintf(stderr,"THINGS_START marker missing!\n");
  309.       exit(-1);
  310.     }
  311.  
  312.   fclose(infile);
  313.  
  314.   /* Concatenate all the data into the final PWAD file */
  315.  
  316.   /* Header */
  317.   fprintf(wadfile,"PWAD");
  318.   numentries = 11;
  319.   putlong(numentries, wadfile);
  320.   reslength = numthings*10 + numlinedefs*14 + numsidedefs*30 +
  321.     numvertices*4 + numsectors*26 + 12; /* The header is 12 bytes */
  322.   putlong(reslength, wadfile);
  323.  
  324.   /* ExMy - start at position 12 (zero length entry) */
  325.  
  326.   /* THINGS - start at position 12 */
  327.   for(i=0; i<numthings; i++)
  328.     {
  329.       putshort(things[i].x, wadfile);
  330.       putshort(things[i].y, wadfile);
  331.       putshort(things[i].angle, wadfile);
  332.       putshort(things[i].type, wadfile);
  333.       putshort(things[i].attrs, wadfile);
  334.     }
  335.   
  336.   /* LINEDEFS - start at position 12 + numthings*10 */
  337.   for(i=0; i<numlinedefs; i++)
  338.     {
  339.       putshort(linedefs[i].from, wadfile);
  340.       putshort(linedefs[i].to, wadfile);
  341.       putshort(linedefs[i].attrs, wadfile);
  342.       putshort(linedefs[i].type, wadfile);
  343.       putshort(linedefs[i].tag, wadfile);
  344.       putshort(linedefs[i].rightsidedef, wadfile);
  345.       putshort(linedefs[i].leftsidedef, wadfile);
  346.     }
  347.  
  348.   /* SIDEDEFS - start at position 12 + numthings*10 + numlinedefs*14 */
  349.   for(i=0; i<numsidedefs; i++)
  350.     {
  351.       putshort(sidedefs[i].xoffset, wadfile);
  352.       putshort(sidedefs[i].yoffset, wadfile);
  353.       fwrite(sidedefs[i].uppertexture, 8, 1, wadfile);
  354.       fwrite(sidedefs[i].lowertexture, 8, 1, wadfile);
  355.       fwrite(sidedefs[i].normaltexture, 8, 1, wadfile);    
  356.       putshort(sidedefs[i].sector, wadfile);
  357.     }
  358.   
  359.   /* VERTEXES - start at position 12 + numthings*10 + numlinedefs*14 + */
  360.   /* numsidedefs*30 */
  361.   for(i=0; i<numvertices; i++)
  362.     {
  363.       putshort(vertices[i].x, wadfile);
  364.       putshort(vertices[i].y, wadfile);
  365.     }
  366.   
  367.   /* SECTORS - start at position 12 + numthings*10 + numlinedefs*14+ */
  368.   /* numsidedefs*30 + numvertices*4 */
  369.   for(i=0; i<numsectors; i++)
  370.     {
  371.       putshort(sectors[i].floorheight, wadfile);
  372.       putshort(sectors[i].ceilingheight, wadfile);
  373.       fwrite(sectors[i].floortexture, 8, 1, wadfile);
  374.       fwrite(sectors[i].ceilingtexture, 8, 1, wadfile);
  375.       putshort(sectors[i].brightness, wadfile);
  376.       putshort(sectors[i].special, wadfile);
  377.       putshort(sectors[i].tag, wadfile);
  378.     }
  379.  
  380.   
  381.   /* Now, write the main directory */
  382.   entrypos = 12;
  383.   sprintf(entryname, "E%1dM%1d", episode, level);
  384.   addentry(&entrypos, 0, entryname, wadfile);
  385.   addentry(&entrypos, numthings*10, "THINGS", wadfile);
  386.   addentry(&entrypos, numlinedefs*14, "LINEDEFS", wadfile);
  387.   addentry(&entrypos, numsidedefs*30, "SIDEDEFS", wadfile);
  388.   addentry(&entrypos, numvertices*4, "VERTEXES", wadfile);
  389.   addentry(&entrypos, 0, "SEGS", wadfile);
  390.   addentry(&entrypos, 0, "SSECTORS", wadfile);
  391.   addentry(&entrypos, 0, "NODES", wadfile);
  392.   addentry(&entrypos, numsectors*26, "SECTORS", wadfile);
  393.   addentry(&entrypos, 0, "REJECT", wadfile);
  394.   addentry(&entrypos, 0, "BLOCKMAP", wadfile);
  395.   
  396.   /* DONE! */
  397.   fclose(wadfile);
  398. }
  399.