home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / qube / entities.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-07  |  5.1 KB  |  256 lines

  1. /***
  2. ****  QuBE --- Entity manipulation routines.
  3. ***/
  4.  
  5. #include "qube.h"
  6. #include "entities.h"
  7.  
  8. /* Entitiesarray.  Maximum 2048 entities, which is fine for now, but again, it
  9.    should be a linked list or someentity more expandable */
  10.  
  11. entity *entityarray[2048];
  12. int nextentity = 0;
  13. int curentity = 0;
  14. long int linenum = 0;
  15.  
  16. long int readcount;
  17. int putback = 0;
  18. int lastread;
  19. long int maxlen;
  20.  
  21. /*
  22. **  EntList.  Prints out the entities, verbatim.
  23. */
  24.  
  25. void EntList(void)
  26. {
  27.     int c;
  28.  
  29.     if (header.id != 0x17)
  30.         Error("Not a valid .BSP file");
  31.  
  32.     fseek(fi, header.entities, SEEK_SET);
  33.     readcount = 0L;
  34.     maxlen = header.entitieslen;
  35.         while ((c = nextchar(fi)) != EOF) printf("%c", c);
  36. }
  37.  
  38. /*
  39. **  EntXtract.    Extracts out the entities, verbatim.
  40. */
  41.  
  42. void EntXtract(int argnum, char **argv)
  43. {
  44.     int c;
  45.     FILE *fo;
  46.  
  47.     if (header.id != 0x17)
  48.         Error("Not a valid .BSP file");
  49.  
  50.     fseek(fi, header.entities, SEEK_SET);
  51.     readcount = 0L;
  52.  
  53.     maxlen = header.entitieslen;
  54.         if ((fo = fopen(argv[argnum+1], "wt")) == NULL)
  55.         Error("Unable to create output file.");
  56.  
  57.     while ((c = nextchar(fi)) != EOF) fprintf(fo, "%c", c);
  58.  
  59.     fclose(fo);
  60. }
  61.  
  62. /*
  63. **  EntReplace.  Replaces the entities in a .BSP file.
  64. */
  65.  
  66. void EntReplace(int argnum, char **argv)
  67. {
  68.     FILE *fo, *tf;
  69.     char *tempstr, *tempstr2;
  70.     long charswritten = 0L;
  71.     char *temp;
  72.     long int i, j, k;
  73.     long int readsize;
  74.  
  75.     maxlen = 0x7FFFFFFF;
  76.  
  77.     if (header.id != 0x17)
  78.         Error("Not a valid .BSP file");
  79.  
  80.     readcount = 0L;
  81.  
  82.     temp = Qmalloc(32768);
  83.  
  84.         if ((fo = fopen("$$$_temp.bsp", "wb")) == NULL)
  85.         Error("Unable to create output file.");
  86.  
  87.     setvbuf(fo, NULL, _IOFBF, 32768);
  88.  
  89.     fseek(fi, 0, SEEK_SET);
  90.     fseek(fo, 0, SEEK_SET);
  91.  
  92.     for (j = 0L; j < header.entities; j += 32768L) {
  93.         if (header.entities - j >= 32768) k = 32768;
  94.         else k = header.entities - j;
  95.         readsize = fread(temp, sizeof(char), k, fi);
  96.         fwrite(temp, sizeof(char), readsize, fo);
  97.     }
  98.  
  99.     if ((tf = fopen(argv[argnum+1], "rt")) == NULL)
  100.         Error("Unable to open entity file.");
  101.  
  102.     setvbuf(tf, NULL, _IOFBF, 32768);
  103.  
  104.     while (!feof(tf)) {
  105.         skipspace(tf);
  106.                 if (!getopenbrace(tf))
  107.             Error("Missing opening brace in entity file.");
  108.  
  109.         fprintf(fo, "{\n");
  110.  
  111.                 do {
  112.                         skipspace(tf);
  113.                         if (nextchar(tf) == '}') break;
  114.                         putback = 1;
  115.             if (fileend())
  116.                 Error("Early end-of-file in entity file");
  117.                         if ((tempstr = getstring(tf)) == NULL)
  118.                 Error("Syntax error (line %ld) in entity file; type needed", linenum);
  119.                         skipspace(tf);
  120.             if (fileend())
  121.                 Error("Early end-of-file in entity file");
  122.                         if ((tempstr2 = getstring(tf)) == NULL)
  123.                 Error("Syntax error (line %ld) in entity file; entry needed", linenum);
  124.                         fprintf(fo, "\"%s\" \"%s\"\n", tempstr, tempstr2);
  125.             Qfree(tempstr);
  126.             Qfree(tempstr2);
  127.                         skipspace(tf);
  128.            } while (!feof(tf));
  129.  
  130.                 skipspace(tf);
  131.  
  132.         fprintf(fo, "}\n");
  133.         }
  134.     fclose(tf);
  135.  
  136.     charswritten = ftell(fo) - header.entities;
  137.     header.pictures += charswritten - header.entitieslen;
  138.     fseek(fi, header.entities + header.entitieslen, SEEK_SET);
  139.  
  140.     while (!feof(fi)) {
  141.         readsize = fread(temp, sizeof(char), 32768, fi);
  142.         fwrite(temp, sizeof(char), readsize, fo);
  143.     }
  144.  
  145.     fseek(fo, 0, SEEK_SET);
  146.     header.entitieslen = charswritten;
  147.     fwrite(&header, 4, 0x50, fo);
  148.  
  149.     Qfree(temp);
  150.  
  151.         fclose(fi);
  152.     fclose(fo);
  153.  
  154.     unlink(argv[filenamearg]);
  155.     rename("$$$_temp.bsp", argv[filenamearg]);
  156. }
  157.  
  158. /*
  159. **  getstring.    Reads in a "" delimited string, stripping the quotes.
  160. */
  161.  
  162. char *getstring(FILE *fp)
  163. {
  164.     char *temp = Qmalloc(32);
  165.     int totallen = 32;
  166.     int curlen = 0;
  167.     int c;
  168.  
  169.     if (nextchar(fp) != '\"') {
  170.         Qfree(temp);
  171.         return(NULL);
  172.         }
  173.  
  174.     do {
  175.         c = nextchar(fp);
  176.  
  177.         if (curlen >= totallen) temp = Qrealloc(temp, curlen += 32);
  178.  
  179.         temp[curlen++] = c;
  180.     } while (c != '\"' && c != '\n' && c != EOF);
  181.  
  182.     if (c != '\"') {
  183.         Qfree(temp);
  184.         return(NULL);
  185.         }
  186.  
  187.     if (curlen) curlen--;
  188.         temp[curlen] = '\0';
  189.  
  190.     return(temp);
  191. }
  192.  
  193. /*
  194. **  getopenbrace.  Reads in a left brace.
  195. */
  196.  
  197. int getopenbrace(FILE *fp)
  198. {
  199.     return(nextchar(fp) == '{');
  200. }
  201.  
  202. /*
  203. **  getclosebrace.  Reads in a right brace.
  204. */
  205.  
  206. int getclosebrace(FILE *fp)
  207. {
  208.     return(nextchar(fp) == '}');
  209. }
  210.  
  211. /*
  212. **  skipspace.    Skips over whitespace (space, tab, newline).
  213. */
  214.  
  215. void skipspace(FILE *fp)
  216. {
  217.     unsigned char c;
  218.  
  219.         do {
  220.         c = nextchar(fp);
  221.     } while (c <= 32);
  222.  
  223.     putback = 1;
  224. }
  225.  
  226. /*
  227. **  nextchar.  Reads in the next character, with putback.
  228. */
  229.  
  230. int nextchar(FILE *fp)
  231. {
  232.         if (putback) {
  233.         putback = 0;
  234.         return(lastread);
  235.         }
  236.  
  237.     if (readcount < maxlen) {
  238.                 readcount++;
  239.         lastread = fgetc(fp);
  240.         if (lastread == '\n') linenum++;
  241.                 return(lastread);
  242.         }
  243.     else return(lastread = EOF);
  244. }         
  245.  
  246. /*
  247. **  fileend.  Returns whether we're at the file's end.
  248. */
  249.  
  250. int fileend(void)
  251. {
  252.     if (lastread == EOF) return(1);
  253.     else return(0);
  254. }
  255.  
  256.