home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / qeu03 / f_bsp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-01  |  4.9 KB  |  175 lines

  1. /*
  2.  * Copyright (C) 1996 by Raphael Quinet.  All rights reserved.
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and
  5.  * its documentation for any purpose and without fee is hereby
  6.  * granted, provided that the above copyright notice appear in all
  7.  * copies and that both that copyright notice and this permission
  8.  * notice appear in supporting documentation.  If more than a few
  9.  * lines of this code are used in a program which displays a copyright
  10.  * notice or credit notice, the following acknowledgment must also be
  11.  * displayed on the same screen: "This product includes software
  12.  * developed by Raphael Quinet for use in the Quake Editing Utilities
  13.  * project."  THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR
  14.  * IMPLIED WARRANTY.
  15.  *
  16.  * More information about the QEU project can be found on the WWW:
  17.  * "http://www.montefiore.ulg.ac.be/~quinet/games/editing.html" or by
  18.  * mail: Raphael Quinet, 9 rue des Martyrs, B-4550 Nandrin, Belgium.
  19.  */
  20.  
  21. /*
  22.  * F_BSP.C - Read and write Quake BSP files.
  23.  */
  24.  
  25. #include "qeu.h"
  26. #include "q_misc.h"
  27. #include "q_files.h"
  28. #include "f_bsp.h"
  29.  
  30. /*
  31.  * Read the BSP directory into memory.  The optional offset to the
  32.  * start of the BSP file is given in "offset".  The number of chunks in
  33.  * the directory is returned in *dirsize_r.
  34.  */
  35. BSPDirPtr ReadBSPDirectory(FILE *bspfile, UInt32 offset, UInt16 *dirsize_r)
  36. {
  37.   BSPDirPtr dir;
  38.   UInt16     max, i;
  39.  
  40.   *dirsize_r = 0;
  41.   if (bspfile == NULL)
  42.     return NULL;
  43.   if ((fseek(bspfile, offset, SEEK_SET) < 0)
  44.       || (ReadMagic(bspfile) != FTYPE_BSP))
  45.     return NULL;
  46.   max = 14;
  47.   dir = (BSPDirPtr)QMalloc(max * sizeof(struct BSPDirectory));
  48.   for (i = 0; i < max; i++)
  49.     {
  50.       if (ReadBytes(bspfile, &dir[i], sizeof(struct BSPDirectory)) == FALSE)
  51.     {
  52.       QFree(dir);
  53.       return NULL;
  54.     }
  55.       dir[i].offset = SwapInt32(dir[i].offset);
  56.       dir[i].size = SwapInt32(dir[i].size);
  57.     }
  58.   *dirsize_r = max;
  59.   return dir;
  60. }
  61.  
  62.  
  63. /*
  64.  * Print the contents of the BSP directory in "outf".
  65.  */
  66. void DumpBSPDirectory(FILE *outf, BSPDirPtr dir, UInt16 dirsize)
  67. {
  68.   UInt16 i;
  69.   UInt32 sum;
  70.   UInt32 sum2;
  71.  
  72.   if (outf == NULL || dir == NULL || dirsize == 0)
  73.     return;
  74.   fprintf(outf, "num    offset     size\n");
  75.   fprintf(outf, "       (hex)      (dec)\n");
  76.   sum = 0L;
  77.   sum2 = 0L;
  78.   for (i = 0; i < dirsize; i++)
  79.     {
  80.       fprintf(outf, "%3u  0x%08lx  %6ld   (entry%02d)\n",
  81.           i, dir[i].offset, dir[i].size, i);
  82.       sum += dir[i].size;
  83.       sum2 += (dir[i].size + 3) & (~3);
  84.     }
  85.   fprintf(outf, "\nTotal size for %3u entries:  %7lu bytes (%lu with padding).\n", dirsize, sum, sum2);
  86.   fprintf(outf, "Size of the BSP directory:  %7lu bytes.\n",
  87.       (UInt32)dirsize * (UInt32)sizeof(struct BSPDirectory));
  88.   fprintf(outf, "Total (header + data + dir): %7lu bytes (%lu with padding).\n",
  89.       4L + sum + (UInt32)dirsize * (UInt32)sizeof(struct BSPDirectory),
  90.       4L + sum2 + (UInt32)dirsize * (UInt32)sizeof(struct BSPDirectory));
  91. }
  92.  
  93.  
  94. /*
  95.  * If "entrynum" is smaller than dirsize, extract the corresponding
  96.  * entry from a BSP file.  Otherwise, extract all entries and save
  97.  * them in separate files.  The files will be saved in the directory
  98.  * "prefixpath".  If "outf" is not null, progress information will be
  99.  * printed in it.
  100.  */
  101. Bool UnBSPFile(FILE *outf, FILE *bspfile, UInt32 offset, BSPDirPtr dir,
  102.            UInt16 dirsize, UInt16 entrynum, char *prefixpath)
  103. {
  104.   char   *newname;
  105.   char   *p;
  106.   FILE   *newfile;
  107.   FILE   *indexfile;
  108.   UInt16  i;
  109.   UInt32  sum;
  110.  
  111.   if (bspfile == NULL || dir == NULL || dirsize == 0)
  112.     return FALSE;
  113.   if (prefixpath == NULL)
  114.     prefixpath = ".";
  115.   newname = (char *)QMalloc(strlen(prefixpath) + 12 + 2);
  116.   strcpy(newname, prefixpath);
  117.   p = &newname[strlen(newname) - 1];
  118. #ifdef QEU_DOS
  119.   if (*p != '\\')
  120.     {
  121.       p++;
  122.       *p = '\\';
  123.     }
  124. #else
  125.   if (*p != '/')
  126.     {
  127.       p++;
  128.       *p = '/';
  129.     }
  130. #endif
  131.   p++;
  132.   strcpy(p, QEU_INDEX_FILE);
  133.   if (outf != NULL)
  134.     fprintf(outf, "Creating index file %s\n", newname);
  135.   CreatePathToFile(newname);
  136.   indexfile = fopen(newname, "a");
  137.   fprintf(indexfile, "BEGIN BSP\n");
  138.   sum = 0L;
  139.   for (i = 0; i < dirsize; i++)
  140.     {
  141.       if (entrynum < dirsize && i != entrynum)
  142.     continue; /* horrible trick... */
  143.       sprintf(p, "entry%02d.lmp", i);
  144.       if (outf != NULL)
  145.     fprintf(outf, "Saving %6ld bytes to %s\n", dir[i].size, newname);
  146.       CreatePathToFile(newname);
  147.       newfile = fopen(newname, "wb");
  148.       if (newfile == NULL)
  149.     {
  150.       fclose(indexfile);
  151.       QFree(newname);
  152.       return FALSE;
  153.     }
  154.       fprintf(indexfile, "+ %s = %s\n", p, p);
  155.       if ((fseek(bspfile, offset + dir[i].offset, SEEK_SET) < 0)
  156.       || (CopyBytes(newfile, bspfile, dir[i].size) == FALSE))
  157.     {
  158.       fclose(newfile);
  159.       fclose(indexfile);
  160.       QFree(newname);
  161.       return FALSE;
  162.     }
  163.       fclose(newfile);
  164.       sum += dir[i].size;
  165.     }
  166.   if (outf != NULL && entrynum >= dirsize)
  167.     fprintf(outf, "Saved %lu bytes in %u files.\n", sum, dirsize);
  168.   fprintf(indexfile, "END BSP\n");
  169.   fclose(indexfile);
  170.   QFree(newname);
  171.   return TRUE;
  172. }
  173.  
  174. /* end of file */
  175.