home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1996 by Raphael Quinet. All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation. If more than a few
- * lines of this code are used in a program which displays a copyright
- * notice or credit notice, the following acknowledgment must also be
- * displayed on the same screen: "This product includes software
- * developed by Raphael Quinet for use in the Quake Editing Utilities
- * project." THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR
- * IMPLIED WARRANTY.
- *
- * More information about the QEU project can be found on the WWW:
- * "http://www.montefiore.ulg.ac.be/~quinet/games/editing.html" or by
- * mail: Raphael Quinet, 9 rue des Martyrs, B-4550 Nandrin, Belgium.
- */
-
- /*
- * F_BSP.C - Read and write Quake BSP files.
- */
-
- #include "qeu.h"
- #include "q_misc.h"
- #include "q_files.h"
- #include "f_bsp.h"
-
- /*
- * Read the BSP directory into memory. The optional offset to the
- * start of the BSP file is given in "offset". The number of chunks in
- * the directory is returned in *dirsize_r.
- */
- BSPDirPtr ReadBSPDirectory(FILE *bspfile, UInt32 offset, UInt16 *dirsize_r)
- {
- BSPDirPtr dir;
- UInt16 max, i;
-
- *dirsize_r = 0;
- if (bspfile == NULL)
- return NULL;
- if ((fseek(bspfile, offset, SEEK_SET) < 0)
- || (ReadMagic(bspfile) != FTYPE_BSP))
- return NULL;
- max = 14;
- dir = (BSPDirPtr)QMalloc(max * sizeof(struct BSPDirectory));
- for (i = 0; i < max; i++)
- {
- if (ReadBytes(bspfile, &dir[i], sizeof(struct BSPDirectory)) == FALSE)
- {
- QFree(dir);
- return NULL;
- }
- dir[i].offset = SwapInt32(dir[i].offset);
- dir[i].size = SwapInt32(dir[i].size);
- }
- *dirsize_r = max;
- return dir;
- }
-
-
- /*
- * Print the contents of the BSP directory in "outf".
- */
- void DumpBSPDirectory(FILE *outf, BSPDirPtr dir, UInt16 dirsize)
- {
- UInt16 i;
- UInt32 sum;
- UInt32 sum2;
-
- if (outf == NULL || dir == NULL || dirsize == 0)
- return;
- fprintf(outf, "num offset size\n");
- fprintf(outf, " (hex) (dec)\n");
- sum = 0L;
- sum2 = 0L;
- for (i = 0; i < dirsize; i++)
- {
- fprintf(outf, "%3u 0x%08lx %6ld (entry%02d)\n",
- i, dir[i].offset, dir[i].size, i);
- sum += dir[i].size;
- sum2 += (dir[i].size + 3) & (~3);
- }
- fprintf(outf, "\nTotal size for %3u entries: %7lu bytes (%lu with padding).\n", dirsize, sum, sum2);
- fprintf(outf, "Size of the BSP directory: %7lu bytes.\n",
- (UInt32)dirsize * (UInt32)sizeof(struct BSPDirectory));
- fprintf(outf, "Total (header + data + dir): %7lu bytes (%lu with padding).\n",
- 4L + sum + (UInt32)dirsize * (UInt32)sizeof(struct BSPDirectory),
- 4L + sum2 + (UInt32)dirsize * (UInt32)sizeof(struct BSPDirectory));
- }
-
-
- /*
- * If "entrynum" is smaller than dirsize, extract the corresponding
- * entry from a BSP file. Otherwise, extract all entries and save
- * them in separate files. The files will be saved in the directory
- * "prefixpath". If "outf" is not null, progress information will be
- * printed in it.
- */
- Bool UnBSPFile(FILE *outf, FILE *bspfile, UInt32 offset, BSPDirPtr dir,
- UInt16 dirsize, UInt16 entrynum, char *prefixpath)
- {
- char *newname;
- char *p;
- FILE *newfile;
- FILE *indexfile;
- UInt16 i;
- UInt32 sum;
-
- if (bspfile == NULL || dir == NULL || dirsize == 0)
- return FALSE;
- if (prefixpath == NULL)
- prefixpath = ".";
- newname = (char *)QMalloc(strlen(prefixpath) + 12 + 2);
- strcpy(newname, prefixpath);
- p = &newname[strlen(newname) - 1];
- #ifdef QEU_DOS
- if (*p != '\\')
- {
- p++;
- *p = '\\';
- }
- #else
- if (*p != '/')
- {
- p++;
- *p = '/';
- }
- #endif
- p++;
- strcpy(p, QEU_INDEX_FILE);
- if (outf != NULL)
- fprintf(outf, "Creating index file %s\n", newname);
- CreatePathToFile(newname);
- indexfile = fopen(newname, "a");
- fprintf(indexfile, "BEGIN BSP\n");
- sum = 0L;
- for (i = 0; i < dirsize; i++)
- {
- if (entrynum < dirsize && i != entrynum)
- continue; /* horrible trick... */
- sprintf(p, "entry%02d.lmp", i);
- if (outf != NULL)
- fprintf(outf, "Saving %6ld bytes to %s\n", dir[i].size, newname);
- CreatePathToFile(newname);
- newfile = fopen(newname, "wb");
- if (newfile == NULL)
- {
- fclose(indexfile);
- QFree(newname);
- return FALSE;
- }
- fprintf(indexfile, "+ %s = %s\n", p, p);
- if ((fseek(bspfile, offset + dir[i].offset, SEEK_SET) < 0)
- || (CopyBytes(newfile, bspfile, dir[i].size) == FALSE))
- {
- fclose(newfile);
- fclose(indexfile);
- QFree(newname);
- return FALSE;
- }
- fclose(newfile);
- sum += dir[i].size;
- }
- if (outf != NULL && entrynum >= dirsize)
- fprintf(outf, "Saved %lu bytes in %u files.\n", sum, dirsize);
- fprintf(indexfile, "END BSP\n");
- fclose(indexfile);
- QFree(newname);
- return TRUE;
- }
-
- /* end of file */
-