1 /* $Id: cfile.c,v 1.10 2002-10-04 07:19:59 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
31 typedef struct hogfile {
37 #define MAX_HOGFILES 300
39 hogfile HogFiles[MAX_HOGFILES];
40 char Hogfile_initialized = 0;
44 hogfile D1HogFiles[MAX_HOGFILES];
45 char D1Hogfile_initialized = 0;
46 int D1Num_hogfiles = 0;
47 char D1HogFilename[64];
49 hogfile AltHogFiles[MAX_HOGFILES];
50 char AltHogfile_initialized = 0;
51 int AltNum_hogfiles = 0;
52 char AltHogFilename[64];
55 char AltHogdir_initialized = 0;
57 // routine to take a DOS path and turn it into a macintosh
58 // pathname. This routine is based on the fact that we should
59 // see a \ character in the dos path. The sequence .\ a tthe
60 // beginning of a path is turned into a :
63 void macify_dospath(char *dos_path, char *mac_path)
67 if (!strncmp(dos_path, ".\\", 2)) {
68 strcpy(mac_path, ":");
69 strcat(mac_path, &(dos_path[2]) );
71 strcpy(mac_path, dos_path);
73 while ( (p = strchr(mac_path, '\\')) != NULL)
79 void cfile_use_alternate_hogdir( char * path )
82 strcpy( AltHogDir, path );
83 AltHogdir_initialized = 1;
85 AltHogdir_initialized = 0;
89 //in case no one installs one
90 int default_error_counter=0;
92 //ptr to counter of how many critical errors
93 int *critical_error_counter_ptr=&default_error_counter;
95 //tell cfile about your critical error counter
96 void cfile_set_critical_error_counter_ptr(int *ptr)
98 critical_error_counter_ptr = ptr;
103 FILE * cfile_get_filehandle( char * filename, char * mode )
108 *critical_error_counter_ptr = 0;
109 fp = fopen( filename, mode );
110 if ( fp && *critical_error_counter_ptr ) {
114 if ( (fp==NULL) && (AltHogdir_initialized) ) {
115 strcpy( temp, AltHogDir );
117 strcat( temp, filename );
118 *critical_error_counter_ptr = 0;
119 fp = fopen( temp, mode );
120 if ( fp && *critical_error_counter_ptr ) {
128 //returns 1 if file loaded with no errors
129 int cfile_init_hogfile(char *fname, hogfile * hog_files, int * nfiles )
137 fp = cfile_get_filehandle( fname, "rb" );
138 if ( fp == NULL ) return 0;
140 fread( id, 3, 1, fp );
141 if ( strncmp( id, "DHF", 3 ) ) {
148 if ( *nfiles >= MAX_HOGFILES ) {
150 Error( "HOGFILE is limited to %d files.\n", MAX_HOGFILES );
152 i = fread( hog_files[*nfiles].name, 13, 1, fp );
153 if ( i != 1 ) { //eof here is ok
157 i = fread( &len, 4, 1, fp );
162 hog_files[*nfiles].length = INTEL_INT(len);
163 hog_files[*nfiles].offset = ftell( fp );
164 *nfiles = (*nfiles) + 1;
166 i = fseek( fp, INTEL_INT(len), SEEK_CUR );
170 //Specify the name of the hogfile. Returns 1 if hogfile found & had files
171 int cfile_init(char *hogname)
176 macify_dospath(hogname, mac_path);
179 Assert(Hogfile_initialized == 0);
182 if (cfile_init_hogfile(hogname, HogFiles, &Num_hogfiles )) {
183 strcpy( HogFilename, hogname );
185 if (cfile_init_hogfile(mac_path, HogFiles, &Num_hogfiles )) {
186 strcpy( HogFilename, mac_path );
188 Hogfile_initialized = 1;
192 return 0; //not loaded!
196 int cfile_size(char *hogname)
201 fp = cfopen(hogname, "rb");
204 fstat(fileno(fp->file), &statbuf);
206 return statbuf.st_size;
210 * return handle for file called "name", embedded in one of the hogfiles
212 FILE * cfile_find_libfile(char * name, int * length)
217 if ( AltHogfile_initialized ) {
218 for (i=0; i<AltNum_hogfiles; i++ ) {
219 if ( !stricmp( AltHogFiles[i].name, name )) {
220 fp = cfile_get_filehandle( AltHogFilename, "rb" );
221 if ( fp == NULL ) return NULL;
222 fseek( fp, AltHogFiles[i].offset, SEEK_SET );
223 *length = AltHogFiles[i].length;
229 if (D1Hogfile_initialized) {
230 for (i = 0; i < D1Num_hogfiles; i++) {
231 if (!stricmp(D1HogFiles[i].name, name)) {
232 fp = cfile_get_filehandle(D1HogFilename, "rb");
233 if (fp == NULL) return NULL;
234 fseek(fp, D1HogFiles[i].offset, SEEK_SET);
235 *length = D1HogFiles[i].length;
241 if ( !Hogfile_initialized ) {
242 //@@cfile_init_hogfile( "DESCENT2.HOG", HogFiles, &Num_hogfiles );
243 //@@Hogfile_initialized = 1;
245 //Int3(); //hogfile ought to be initialized
248 for (i=0; i<Num_hogfiles; i++ ) {
249 if ( !stricmp( HogFiles[i].name, name )) {
250 fp = cfile_get_filehandle( HogFilename, "rb" );
251 if ( fp == NULL ) return NULL;
252 fseek( fp, HogFiles[i].offset, SEEK_SET );
253 *length = HogFiles[i].length;
260 int cfile_use_alternate_hogfile( char * name )
266 macify_dospath(name, mac_path);
267 strcpy( AltHogFilename, mac_path);
269 strcpy( AltHogFilename, name );
271 cfile_init_hogfile( AltHogFilename, AltHogFiles, &AltNum_hogfiles );
272 AltHogfile_initialized = 1;
273 return (AltNum_hogfiles > 0);
275 AltHogfile_initialized = 0;
280 int cfile_use_descent1_hogfile( char * name )
286 macify_dospath(name, mac_path);
287 strcpy(D1HogFilename, mac_path);
289 strcpy(D1HogFilename, name);
291 cfile_init_hogfile(D1HogFilename, D1HogFiles, &D1Num_hogfiles);
292 D1Hogfile_initialized = 1;
293 return (D1Num_hogfiles > 0);
295 D1Hogfile_initialized = 0;
300 int cfexist( char * filename )
306 if (filename[0] != '\x01')
307 fp = cfile_get_filehandle( filename, "rb" ); // Check for non-hog file first...
309 fp = NULL; //don't look in dir, only in hogfile
318 fp = cfile_find_libfile(filename, &length );
321 return 2; // file found in hog
324 return 0; // Couldn't find it.
328 CFILE * cfopen(char * filename, char * mode )
334 if (stricmp( mode, "rb")) {
335 Error( "cfiles can only be opened with mode==rb\n" );
338 if (filename[0] != '\x01') {
342 macify_dospath(filename, mac_path);
343 fp = cfile_get_filehandle( mac_path, mode);
345 fp = cfile_get_filehandle( filename, mode ); // Check for non-hog file first...
348 fp = NULL; //don't look in dir, only in hogfile
353 fp = cfile_find_libfile(filename, &length );
355 return NULL; // No file found
356 cfile = d_malloc ( sizeof(CFILE) );
357 if ( cfile == NULL ) {
362 cfile->size = length;
363 cfile->lib_offset = ftell( fp );
364 cfile->raw_position = 0;
367 cfile = d_malloc ( sizeof(CFILE) );
368 if ( cfile == NULL ) {
373 cfile->size = filelength( fileno(fp) );
374 cfile->lib_offset = 0;
375 cfile->raw_position = 0;
380 int cfilelength( CFILE *fp )
385 int cfgetc( CFILE * fp )
389 if (fp->raw_position >= fp->size ) return EOF;
391 c = getc( fp->file );
395 // Assert( fp->raw_position==(ftell(fp->file)-fp->lib_offset) );
400 char * cfgets( char * buf, size_t n, CFILE * fp )
406 for (i=0; i<n-1; i++ ) {
408 if (fp->raw_position >= fp->size ) {
412 c = fgetc( fp->file );
414 if (c == 0 || c == 10) // Unix line ending
416 if (c == 13) { // Mac or DOS line ending
419 c1 = fgetc( fp->file );
420 fseek( fp->file, -1, SEEK_CUR);
421 if ( c1 == 10 ) // DOS line ending
423 else // Mac line ending
427 if ( c == 13 ) // because cr-lf is a bad thing on the mac
428 c = '\n'; // and anyway -- 0xod is CR on mac, not 0x0a
430 if ( c=='\n' ) break;
436 size_t cfread( void * buf, size_t elsize, size_t nelem, CFILE * fp )
438 unsigned int i, size;
440 size = elsize * nelem;
441 if ( size < 1 ) return 0;
443 i = fread ( buf, 1, size, fp->file );
444 fp->raw_position += i;
449 int cftell( CFILE *fp )
451 return fp->raw_position;
454 int cfseek( CFILE *fp, long int offset, int where )
456 int c, goal_position;
460 goal_position = offset;
463 goal_position = fp->raw_position+offset;
466 goal_position = fp->size+offset;
471 c = fseek( fp->file, fp->lib_offset + goal_position, SEEK_SET );
472 fp->raw_position = ftell(fp->file)-fp->lib_offset;
476 void cfclose( CFILE * fp )
483 // routines to read basic data types from CFILE's. Put here to
484 // simplify mac/pc reading from cfiles.
486 int cfile_read_int(CFILE *file)
490 if (cfread( &i, sizeof(i), 1, file) != 1)
491 Error( "Error reading int in cfile_read_int()" );
497 short cfile_read_short(CFILE *file)
501 if (cfread( &s, sizeof(s), 1, file) != 1)
502 Error( "Error reading short in cfile_read_short()" );
508 byte cfile_read_byte(CFILE *file)
512 if (cfread( &b, sizeof(b), 1, file) != 1)
513 Error( "Error reading byte in cfile_read_byte()" );
518 fix cfile_read_fix(CFILE *file)
522 if (cfread( &f, sizeof(f), 1, file) != 1)
523 Error( "Error reading fix in cfile_read_fix()" );
525 f = (fix)INTEL_INT((int)f);
529 fixang cfile_read_fixang(CFILE *file)
533 if (cfread(&f, 2, 1, file) != 1)
534 Error("Error reading fixang in cfile_read_fixang()");
536 f = (fixang) INTEL_SHORT((int) f);
540 void cfile_read_vector(vms_vector *v, CFILE *file)
542 v->x = cfile_read_fix(file);
543 v->y = cfile_read_fix(file);
544 v->z = cfile_read_fix(file);
547 void cfile_read_angvec(vms_angvec *v, CFILE *file)
549 v->p = cfile_read_fixang(file);
550 v->b = cfile_read_fixang(file);
551 v->h = cfile_read_fixang(file);
554 void cfile_read_matrix(vms_matrix *m,CFILE *file)
556 cfile_read_vector(&m->rvec,file);
557 cfile_read_vector(&m->uvec,file);
558 cfile_read_vector(&m->fvec,file);