home *** CD-ROM | disk | FTP | other *** search
/ Deathday Collection / dday.bin / edit / doombsp / wadfile.m < prev   
Text File  |  1994-04-06  |  5KB  |  289 lines

  1. #import "doombsp.h"
  2. #import <ctype.h>
  3.  
  4. typedef struct
  5. {
  6.     char        identification[4];        // should be IWAD
  7.     int        numlumps;
  8.     int        infotableofs;
  9. } wadinfo_t;
  10.  
  11.  
  12. typedef struct
  13. {
  14.     int        filepos;
  15.     int        size;
  16.     char        name[8];
  17. } lumpinfo_t;
  18.  
  19.  
  20. @implementation Wadfile
  21.  
  22. //=============================================================================
  23.  
  24. /*
  25. ============
  26. =
  27. = initFromFile:
  28. =
  29. ============
  30. */
  31.  
  32. - initFromFile: (char const *)path
  33. {
  34.     wadinfo_t    wad;
  35.     lumpinfo_t    *lumps;
  36.     int            i;
  37.     
  38.     pathname = malloc(strlen(path)+1);
  39.     strcpy (pathname, path);
  40.     dirty = NO;
  41.     handle = open (pathname, O_RDWR, 0666);
  42.     if (handle== -1)
  43.     {
  44.         [self free];
  45.         return nil;
  46.     }
  47. //
  48. // read in the header
  49. //
  50.     read (handle, &wad, sizeof(wad));
  51.     if (strncmp(wad.identification,"IWAD",4))
  52.     {
  53.         close (handle);
  54.         [self free];
  55.         return nil;
  56.     }
  57.     wad.numlumps = LONG (wad.numlumps);
  58.     wad.infotableofs = LONG (wad.infotableofs);
  59.     
  60. //
  61. // read in the lumpinfo
  62. //
  63.     lseek (handle, wad.infotableofs, L_SET);
  64.     info = [[Storage alloc] initCount: wad.numlumps elementSize: sizeof(lumpinfo_t) description: ""];
  65.     lumps = [info elementAt: 0];
  66.     
  67.     read (handle, lumps, wad.numlumps*sizeof(lumpinfo_t));
  68.     for (i=0 ; i<wad.numlumps ; i++, lumps++)
  69.     {
  70.         lumps->filepos = LONG (lumps->filepos);
  71.         lumps->size = LONG (lumps->size);
  72.     }
  73.     
  74.     return self;
  75. }
  76.  
  77.  
  78. /*
  79. ============
  80. =
  81. = initNew:
  82. =
  83. ============
  84. */
  85.  
  86. - initNew: (char const *)path
  87. {
  88.     wadinfo_t    wad;
  89.  
  90.     pathname = malloc(strlen(path)+1);
  91.     strcpy (pathname, path);
  92.     info = [[Storage alloc] initCount: 0 elementSize: sizeof(lumpinfo_t) description: ""];
  93.     dirty = YES;
  94.     handle = open (pathname, O_CREAT | O_TRUNC | O_RDWR, 0666);
  95.     if (handle== -1)
  96.         return nil;
  97. // leave space for wad header
  98.     write (handle, &wad, sizeof(wad));
  99.     
  100.     return self;
  101. }
  102.  
  103. -close
  104. {
  105.     close (handle);
  106.     return self;
  107. }
  108.  
  109. -free
  110. {
  111.     close (handle);
  112.     [info free];
  113.     free (pathname);
  114.     return [super free];
  115. }
  116.  
  117. //=============================================================================
  118.  
  119. - (int)numLumps
  120. {
  121.     return [info count];
  122. }
  123.  
  124. - (int)lumpsize: (int)lump
  125. {
  126.     lumpinfo_t    *inf;
  127.     inf = [info elementAt: lump];
  128.     return inf->size;
  129. }
  130.  
  131. - (int)lumpstart: (int)lump
  132. {
  133.     lumpinfo_t    *inf;
  134.     inf = [info elementAt: lump];
  135.     return inf->filepos;
  136. }
  137.  
  138. - (char const *)lumpname: (int)lump
  139. {
  140.     lumpinfo_t    *inf;
  141.     inf = [info elementAt: lump];
  142.     return inf->name;
  143. }
  144.  
  145. /*
  146. ================
  147. =
  148. = lumpNamed:
  149. =
  150. ================
  151. */
  152.  
  153. - (int)lumpNamed: (char const *)name
  154. {
  155.     lumpinfo_t    *inf;
  156.     int            i, count;
  157.     char            name8[9];
  158.     int            v1,v2;
  159.  
  160. // make the name into two integers for easy compares
  161.  
  162.     memset(name8,0,9);
  163.     if (strlen(name) < 9)
  164.         strncpy (name8,name,9);
  165.     for (i=0 ; i<9 ; i++)
  166.         name8[i] = toupper(name8[i]);    // case insensitive
  167.  
  168.     v1 = *(int *)name8;
  169.     v2 = *(int *)&name8[4];
  170.  
  171.  
  172. // scan backwards so patch lump files take precedence
  173.  
  174.     count = [info count];
  175.     for (i=count-1 ; i>=0 ; i--)
  176.     {
  177.         inf = [info elementAt: i];
  178.         if ( *(int *)inf->name == v1 && *(int *)&inf->name[4] == v2)
  179.             return i;
  180.     }
  181.     return  -1;
  182. }
  183.  
  184. /*
  185. ================
  186. =
  187. = loadLump:
  188. =
  189. ================
  190. */
  191.  
  192. - (void *)loadLump: (int)lump
  193. {
  194.     lumpinfo_t    *inf;
  195.     byte            *buf;
  196.     
  197.     inf = [info elementAt: lump];
  198.     buf = malloc (inf->size);
  199.     
  200.     lseek (handle, inf->filepos, L_SET);
  201.     read (handle, buf, inf->size);
  202.     
  203.     return buf;
  204. }
  205.  
  206. - (void *)loadLumpNamed: (char const *)name
  207. {
  208.     return [self loadLump:[self lumpNamed: name]];
  209. }
  210.  
  211. //============================================================================
  212.  
  213. /*
  214. ================
  215. =
  216. = addName:data:size:
  217. =
  218. ================
  219. */
  220.  
  221. - addName: (char const *)name data: (void *)data size: (int)size
  222. {
  223.     int        i;
  224.     lumpinfo_t    new;
  225.     
  226.     dirty = YES;
  227.     memset (new.name,0,sizeof(new.name));
  228.     strncpy (new.name, name, 8);
  229.     for (i=0 ; i<8 ; i++)
  230.         new.name[i] = toupper(new.name[i]);
  231.     new.filepos = lseek(handle,0, L_XTND);
  232.     new.size = size;
  233.     [info addElement: &new];
  234.     
  235.     write (handle, data, size);
  236.     
  237.     return self;
  238. }
  239.  
  240.  
  241. /*
  242. ================
  243. =
  244. = writeDirectory:
  245. =
  246.     char        identification[4];        // should be IWAD
  247.     int        numlumps;
  248.     int        infotableofs;
  249. ================
  250. */
  251.  
  252. - writeDirectory
  253. {
  254.     wadinfo_t    wad;
  255.     int            i,count;
  256.     lumpinfo_t    *inf;
  257.     
  258. //
  259. // write the directory
  260. //
  261.     count = [info count];
  262.     inf = [info elementAt:0];
  263.     for (i=0 ; i<count ; i++)
  264.     {
  265.         inf[i].filepos = LONG (inf[i].filepos);
  266.         inf[i].size = LONG (inf[i].size);
  267.     }
  268.     wad.infotableofs = LONG (lseek(handle,0, L_XTND));
  269.     write (handle, inf, count*sizeof(lumpinfo_t));
  270.     for (i=0 ; i<count ; i++)
  271.     {
  272.         inf[i].filepos = LONG (inf[i].filepos);
  273.         inf[i].size = LONG (inf[i].size);
  274.     }
  275.     
  276. //
  277. // write the header
  278. //
  279.     strncpy (wad.identification, "IWAD",4);
  280.     wad.numlumps = LONG ([info count]);
  281.     lseek (handle, 0, L_SET);
  282.     write (handle, &wad, sizeof(wad));
  283.     
  284.     return self;
  285. }
  286.  
  287. @end
  288.  
  289.