home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.68.zip / src / bme / datafile.c < prev    next >
C/C++ Source or Header  |  2008-04-01  |  4KB  |  166 lines

  1. //
  2. // Datafile creator
  3. //
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include <SDL/SDL_types.h>
  10. #include "bme_end.h"
  11.  
  12. #define MAXFILES 16384
  13. #define MAXFILENAME 64
  14.  
  15. typedef struct
  16. {
  17.     Uint32 offset;
  18.     Uint32 length;
  19.     char name[13];
  20. } HEADER;
  21.  
  22. static HEADER header[MAXFILES];
  23. static char fullname[MAXFILES][MAXFILENAME];
  24. static int files;
  25.  
  26. int main(int argc, char **argv);
  27. int addfile(HEADER *header, FILE *dest, char *name);
  28. void fwrite8(FILE *file, unsigned data);
  29. void fwritele16(FILE *file, unsigned data);
  30. void fwritele32(FILE *file, unsigned data);
  31.  
  32. int main(int argc, char **argv)
  33. {
  34.     FILE *datafile, *listfile;
  35.     int c;
  36.  
  37.     if (argc < 3)
  38.     {
  39.         printf("Usage: DATAFILE <datafile> <filelistfile>\n\n"
  40.                "The purpose of this program is to gather many files into one datafile, like\n"
  41.                "usually seen in games. The files can be read by BME's IO functions after\n"
  42.                "opening the datafile first with io_opendatafile(). The filelistfile must\n"
  43.                "contain name (use only 8+3 chars) of each file on its own row, for example:\n\n"
  44.                "editor.spr\n"
  45.                "fonts.spr\n");
  46.         return 0;
  47.     }
  48.     listfile = fopen(argv[2], "rt");
  49.     if (!listfile)
  50.     {
  51.         printf("ERROR: Couldn't open filelist.\n");
  52.         return 1;
  53.     }
  54.     datafile = fopen(argv[1], "wb");
  55.     if (!datafile)
  56.     {
  57.         printf("ERROR: Couldn't create datafile.\n");
  58.         fclose(listfile);
  59.         return 1;
  60.     }
  61.     memset(&header[0], 0, MAXFILES * sizeof(HEADER));
  62.     // Get names from list
  63.     for (;;)
  64.     {
  65.         char searchname[64];
  66.         int d;
  67.         FILE *test;
  68.  
  69.         if (fscanf(listfile, "%63s", searchname) == EOF) break;
  70.         test = fopen(searchname, "rb");
  71.         if (test)
  72.         {
  73.             fclose(test);
  74.  
  75.             strcpy(fullname[files], searchname);
  76.  
  77.             for (c = strlen(fullname[files]) - 1; c >= 0; c--)
  78.             {
  79.                 if (fullname[files][c] == '\\')
  80.                 {
  81.                     c++;
  82.                     break;
  83.                 }
  84.             }
  85.             if (c < 0) c = 0;
  86.             memset(header[files].name, 0, 13);
  87.             d = 0;
  88.             while (fullname[files][c])
  89.             {
  90.                 header[files].name[d] = toupper(fullname[files][c]);
  91.                 c++;
  92.                 d++;
  93.             }
  94.             files++;
  95.             if (files == MAXFILES) break;
  96.         }
  97.         if (files == MAXFILES) break;
  98.     }
  99.  
  100.     fclose(listfile);
  101.     // Write datafile header
  102.     fwrite("DAT!", 4, 1, datafile);
  103.     fwritele32(datafile, files);
  104.     // Write incomplete fileheaders
  105.     for (c = 0; c < files; c++)
  106.     {
  107.         fwritele32(datafile, header[c].offset);
  108.         fwritele32(datafile, header[c].length);
  109.         fwrite(header[c].name, 13, 1, datafile);
  110.     }
  111.     // Process each file
  112.     for (c = 0; c < files; c++)
  113.     {
  114.         printf("Adding %s...\n", header[c].name);
  115.         if (!addfile(&header[c], datafile, fullname[c]))
  116.         {
  117.             printf("Terminating & deleting datafile...\n");
  118.             fclose(datafile);
  119.             remove(argv[1]);
  120.             return 1;
  121.         }
  122.     }
  123.     // Seek back to start & write correct headers
  124.     fseek(datafile, sizeof files + 4, SEEK_SET);
  125.     for (c = 0; c < files; c++)
  126.     {
  127.         fwritele32(datafile, header[c].offset);
  128.         fwritele32(datafile, header[c].length);
  129.         fwrite(header[c].name, 13, 1, datafile);
  130.     }
  131.     fclose(datafile);
  132.     printf("Everything OK!\n");
  133.     return 0;
  134. }
  135.  
  136. int addfile(HEADER *header, FILE *dest, char *name)
  137. {
  138.     FILE *src;
  139.     unsigned char *originalbuf;
  140.  
  141.     src = fopen(name, "rb");
  142.     if (!src)
  143.     {
  144.         printf("ERROR: Couldn't open file %s\n", name);
  145.         return 0;
  146.     }
  147.     header->offset = ftell(dest);
  148.     fseek(src, 0, SEEK_END);
  149.     header->length = ftell(src);
  150.     fseek(src, 0, SEEK_SET);
  151.     originalbuf = malloc(header->length);
  152.     if (!originalbuf)
  153.     {
  154.         printf("ERROR: No memory to load file!\n");
  155.         fclose(src);
  156.         return 0;
  157.     }
  158.     printf("* Loading file\n");
  159.     fread(originalbuf, header->length, 1, src);
  160.     fclose(src);
  161.     printf("* Writing file (size was %d)\n", header->length);
  162.     fwrite(originalbuf, header->length, 1, dest);
  163.     free(originalbuf);
  164.     return 1;
  165. }
  166.