CFILE.C 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  12. */
  13. /*
  14. * $Source: f:/miner/source/cfile/rcs/cfile.c $
  15. * $Revision: 1.24 $
  16. * $Author: john $
  17. * $Date: 1995/03/15 14:20:27 $
  18. *
  19. * Functions for accessing compressed files.
  20. *
  21. * $Log: cfile.c $
  22. * Revision 1.24 1995/03/15 14:20:27 john
  23. * Added critical error checker.
  24. *
  25. * Revision 1.23 1995/03/13 15:16:53 john
  26. * Added alternate directory stuff.
  27. *
  28. * Revision 1.22 1995/02/09 23:08:47 matt
  29. * Increased the max number of files in hogfile to 250
  30. *
  31. * Revision 1.21 1995/02/01 20:56:47 john
  32. * Added cfexist function
  33. *
  34. * Revision 1.20 1995/01/21 17:53:48 john
  35. * Added alternate pig file thing.
  36. *
  37. * Revision 1.19 1994/12/29 15:10:02 john
  38. * Increased hogfile max files to 200.
  39. *
  40. * Revision 1.18 1994/12/12 13:20:57 john
  41. * Made cfile work with fiellentth.
  42. *
  43. * Revision 1.17 1994/12/12 13:14:25 john
  44. * Made cfiles prefer non-hog files.
  45. *
  46. * Revision 1.16 1994/12/09 18:53:26 john
  47. * *** empty log message ***
  48. *
  49. * Revision 1.15 1994/12/09 18:52:56 john
  50. * Took out mem, error checking.
  51. *
  52. * Revision 1.14 1994/12/09 18:10:31 john
  53. * Speed up cfgets, which was slowing down the reading of
  54. * bitmaps.tbl, which was making POF loading look slow.
  55. *
  56. * Revision 1.13 1994/12/09 17:53:51 john
  57. * Added error checking to number of hogfiles..
  58. *
  59. * Revision 1.12 1994/12/08 19:02:55 john
  60. * Added cfgets.
  61. *
  62. * Revision 1.11 1994/12/07 21:57:48 john
  63. * Took out data dir.
  64. *
  65. * Revision 1.10 1994/12/07 21:38:02 john
  66. * Made cfile not return error..
  67. *
  68. * Revision 1.9 1994/12/07 21:35:34 john
  69. * Made it read from data directory.
  70. *
  71. * Revision 1.8 1994/12/07 21:33:55 john
  72. * Stripped out compression stuff...
  73. *
  74. * Revision 1.7 1994/04/13 23:44:59 matt
  75. * When file cannot be opened, free up the buffer for that file.
  76. *
  77. * Revision 1.6 1994/02/18 12:38:20 john
  78. * Optimized a bit
  79. *
  80. * Revision 1.5 1994/02/15 18:13:20 john
  81. * Fixed more bugs.
  82. *
  83. * Revision 1.4 1994/02/15 13:27:58 john
  84. * Works ok...
  85. *
  86. * Revision 1.3 1994/02/15 12:51:57 john
  87. * Crappy inbetween version
  88. *
  89. * Revision 1.2 1994/02/14 20:12:29 john
  90. * First version working with new cfile stuff.
  91. *
  92. * Revision 1.1 1994/02/14 15:51:33 john
  93. * Initial revision
  94. *
  95. * Revision 1.1 1994/02/10 15:45:12 john
  96. * Initial revision
  97. *
  98. *
  99. */
  100. #pragma off (unreferenced)
  101. static char rcsid[] = "$Id: cfile.c 1.24 1995/03/15 14:20:27 john Exp $";
  102. #pragma on (unreferenced)
  103. #include <time.h>
  104. #include <stdio.h>
  105. #include <stdlib.h>
  106. #include <string.h>
  107. #include <ctype.h>
  108. #include <stdarg.h>
  109. #include <conio.h>
  110. #include <dos.h>
  111. #include <fcntl.h>
  112. #include <io.h>
  113. #include <sys\types.h>
  114. #include <sys\stat.h>
  115. #include <errno.h>
  116. #include <string.h>
  117. #include "cfile.h"
  118. typedef struct hogfile {
  119. char name[13];
  120. int offset;
  121. int length;
  122. } hogfile;
  123. #define MAX_HOGFILES 250
  124. hogfile HogFiles[MAX_HOGFILES];
  125. char Hogfile_initialized = 0;
  126. int Num_hogfiles = 0;
  127. hogfile AltHogFiles[MAX_HOGFILES];
  128. char AltHogfile_initialized = 0;
  129. int AltNum_hogfiles = 0;
  130. char AltHogFilename[64];
  131. char AltHogDir[64];
  132. char AltHogdir_initialized = 0;
  133. void cfile_use_alternate_hogdir( char * path )
  134. {
  135. if ( path ) {
  136. strcpy( AltHogDir, path );
  137. AltHogdir_initialized = 1;
  138. } else {
  139. AltHogdir_initialized = 0;
  140. }
  141. }
  142. extern int descent_critical_error;
  143. FILE * cfile_get_filehandle( char * filename, char * mode )
  144. {
  145. FILE * fp;
  146. char temp[128];
  147. descent_critical_error = 0;
  148. fp = fopen( filename, mode );
  149. if ( fp && descent_critical_error ) {
  150. fclose(fp);
  151. fp = NULL;
  152. }
  153. if ( (fp==NULL) && (AltHogdir_initialized) ) {
  154. strcpy( temp, AltHogDir );
  155. strcat( temp, filename );
  156. descent_critical_error = 0;
  157. fp = fopen( temp, mode );
  158. if ( fp && descent_critical_error ) {
  159. fclose(fp);
  160. fp = NULL;
  161. }
  162. }
  163. return fp;
  164. }
  165. void cfile_init_hogfile(char *fname, hogfile * hog_files, int * nfiles )
  166. {
  167. char id[4];
  168. FILE * fp;
  169. int i, len;
  170. *nfiles = 0;
  171. fp = cfile_get_filehandle( fname, "rb" );
  172. if ( fp == NULL ) return;
  173. fread( id, 3, 1, fp );
  174. if ( strncmp( id, "DHF", 3 ) ) {
  175. fclose(fp);
  176. return;
  177. }
  178. while( 1 )
  179. {
  180. if ( *nfiles >= MAX_HOGFILES ) {
  181. printf( "ERROR: HOGFILE IS LIMITED TO %d FILES\n", MAX_HOGFILES );
  182. fclose(fp);
  183. exit(1);
  184. }
  185. i = fread( hog_files[*nfiles].name, 13, 1, fp );
  186. if ( i != 1 ) {
  187. fclose(fp);
  188. return;
  189. }
  190. i = fread( &len, 4, 1, fp );
  191. if ( i != 1 ) {
  192. fclose(fp);
  193. return;
  194. }
  195. hog_files[*nfiles].length = len;
  196. hog_files[*nfiles].offset = ftell( fp );
  197. *nfiles = (*nfiles) + 1;
  198. // Skip over
  199. i = fseek( fp, len, SEEK_CUR );
  200. }
  201. }
  202. FILE * cfile_find_libfile(char * name, int * length)
  203. {
  204. FILE * fp;
  205. int i;
  206. if ( AltHogfile_initialized ) {
  207. for (i=0; i<AltNum_hogfiles; i++ ) {
  208. if ( !stricmp( AltHogFiles[i].name, name )) {
  209. fp = cfile_get_filehandle( AltHogFilename, "rb" );
  210. if ( fp == NULL ) return NULL;
  211. fseek( fp, AltHogFiles[i].offset, SEEK_SET );
  212. *length = AltHogFiles[i].length;
  213. return fp;
  214. }
  215. }
  216. }
  217. if ( !Hogfile_initialized ) {
  218. cfile_init_hogfile( "DESCENT.HOG", HogFiles, &Num_hogfiles );
  219. Hogfile_initialized = 1;
  220. }
  221. for (i=0; i<Num_hogfiles; i++ ) {
  222. if ( !stricmp( HogFiles[i].name, name )) {
  223. fp = cfile_get_filehandle( "DESCENT.HOG", "rb" );
  224. if ( fp == NULL ) return NULL;
  225. fseek( fp, HogFiles[i].offset, SEEK_SET );
  226. *length = HogFiles[i].length;
  227. return fp;
  228. }
  229. }
  230. return NULL;
  231. }
  232. void cfile_use_alternate_hogfile( char * name )
  233. {
  234. if ( name ) {
  235. strcpy( AltHogFilename, name );
  236. cfile_init_hogfile( AltHogFilename, AltHogFiles, &AltNum_hogfiles );
  237. AltHogfile_initialized = 1;
  238. } else {
  239. AltHogfile_initialized = 0;
  240. }
  241. }
  242. int cfexist( char * filename )
  243. {
  244. int length;
  245. FILE *fp;
  246. fp = cfile_get_filehandle( filename, "rb" ); // Check for non-hog file first...
  247. if ( fp ) {
  248. fclose(fp);
  249. return 1;
  250. }
  251. fp = cfile_find_libfile(filename, &length );
  252. if ( fp ) {
  253. fclose(fp);
  254. return 2; // file found in hog
  255. }
  256. return 0; // Couldn't find it.
  257. }
  258. CFILE * cfopen(char * filename, char * mode )
  259. {
  260. int length;
  261. FILE * fp;
  262. CFILE *cfile;
  263. if (strcmpi( mode, "rb")) {
  264. printf( "CFILES CAN ONLY BE OPENED WITH RB\n" );
  265. exit(1);
  266. }
  267. fp = cfile_get_filehandle( filename, mode ); // Check for non-hog file first...
  268. if ( !fp ) {
  269. fp = cfile_find_libfile(filename, &length );
  270. if ( !fp )
  271. return NULL; // No file found
  272. cfile = malloc ( sizeof(CFILE) );
  273. if ( cfile == NULL ) {
  274. fclose(fp);
  275. return NULL;
  276. }
  277. cfile->file = fp;
  278. cfile->size = length;
  279. cfile->lib_offset = ftell( fp );
  280. cfile->raw_position = 0;
  281. return cfile;
  282. } else {
  283. cfile = malloc ( sizeof(CFILE) );
  284. if ( cfile == NULL ) {
  285. fclose(fp);
  286. return NULL;
  287. }
  288. cfile->file = fp;
  289. cfile->size = filelength( fileno(fp) );
  290. cfile->lib_offset = 0;
  291. cfile->raw_position = 0;
  292. return cfile;
  293. }
  294. }
  295. int cfilelength( CFILE *fp )
  296. {
  297. return fp->size;
  298. }
  299. int cfgetc( CFILE * fp )
  300. {
  301. int c;
  302. if (fp->raw_position >= fp->size ) return EOF;
  303. c = getc( fp->file );
  304. if (c!=EOF)
  305. fp->raw_position++;
  306. // Assert( fp->raw_position==(ftell(fp->file)-fp->lib_offset) );
  307. return c;
  308. }
  309. char * cfgets( char * buf, size_t n, CFILE * fp )
  310. {
  311. char * t = buf;
  312. int i;
  313. int c;
  314. for (i=0; i<n-1; i++ ) {
  315. do {
  316. if (fp->raw_position >= fp->size ) {
  317. *buf = 0;
  318. return NULL;
  319. }
  320. c = fgetc( fp->file );
  321. fp->raw_position++;
  322. } while ( c == 13 );
  323. *buf++ = c;
  324. if ( c=='\n' ) break;
  325. }
  326. *buf++ = 0;
  327. return t;
  328. }
  329. size_t cfread( void * buf, size_t elsize, size_t nelem, CFILE * fp )
  330. {
  331. int i;
  332. if ((fp->raw_position+(elsize*nelem)) > fp->size ) return EOF;
  333. i = fread( buf, elsize, nelem, fp->file );
  334. fp->raw_position += i*elsize;
  335. return i;
  336. }
  337. int cftell( CFILE *fp )
  338. {
  339. return fp->raw_position;
  340. }
  341. int cfseek( CFILE *fp, long int offset, int where )
  342. {
  343. int c, goal_position;
  344. switch( where ) {
  345. case SEEK_SET:
  346. goal_position = offset;
  347. break;
  348. case SEEK_CUR:
  349. goal_position = fp->raw_position+offset;
  350. break;
  351. case SEEK_END:
  352. goal_position = fp->size+offset;
  353. break;
  354. default:
  355. return 1;
  356. }
  357. c = fseek( fp->file, fp->lib_offset + goal_position, SEEK_SET );
  358. fp->raw_position = ftell(fp->file)-fp->lib_offset;
  359. return c;
  360. }
  361. void cfclose( CFILE * fp )
  362. {
  363. fclose(fp->file);
  364. free(fp);
  365. return;
  366. }
  367.