1 /* $Id: piggy.c,v 1.64 2006-02-26 02:29:06 chris 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.
17 * Functions for managing the pig files.
27 static char rcsid[] = "$Id: piggy.c,v 1.64 2006-02-26 02:29:06 chris Exp $";
68 #include <Strings.h> // MacOS Toolbox header
73 //#define NO_DUMP_SOUNDS 1 //if set, dump bitmaps but not sounds
75 #define DEFAULT_PIGFILE_REGISTERED "groupa.pig"
76 #define DEFAULT_PIGFILE_SHAREWARE "d2demo.pig"
77 #define DEFAULT_HAMFILE_REGISTERED "descent2.ham"
78 #define DEFAULT_HAMFILE_SHAREWARE "d2demo.ham"
80 #define D1_PALETTE "palette.256"
82 #define DEFAULT_PIGFILE (cfexist(DEFAULT_PIGFILE_REGISTERED)?DEFAULT_PIGFILE_REGISTERED:DEFAULT_PIGFILE_SHAREWARE)
83 #define DEFAULT_HAMFILE (cfexist(DEFAULT_HAMFILE_REGISTERED)?DEFAULT_HAMFILE_REGISTERED:DEFAULT_HAMFILE_SHAREWARE)
84 #define DEFAULT_SNDFILE ((Piggy_hamfile_version < 3)?DEFAULT_HAMFILE_SHAREWARE:(digi_sample_rate==SAMPLE_RATE_22K)?"descent2.s22":"descent2.s11")
86 #define MAC_ALIEN1_PIGSIZE 5013035
87 #define MAC_ALIEN2_PIGSIZE 4909916
88 #define MAC_FIRE_PIGSIZE 4969035
89 #define MAC_GROUPA_PIGSIZE 4929684 // also used for mac shareware
90 #define MAC_ICE_PIGSIZE 4923425
91 #define MAC_WATER_PIGSIZE 4832403
93 ubyte *BitmapBits = NULL;
94 ubyte *SoundBits = NULL;
96 typedef struct BitmapFile {
100 typedef struct SoundFile {
104 hashtable AllBitmapsNames;
105 hashtable AllDigiSndNames;
107 int Num_bitmap_files = 0;
108 int Num_sound_files = 0;
110 digi_sound GameSounds[MAX_SOUND_FILES];
111 int SoundOffset[MAX_SOUND_FILES];
112 grs_bitmap GameBitmaps[MAX_BITMAP_FILES];
114 alias alias_list[MAX_ALIASES];
117 int Must_write_hamfile = 0;
118 int Num_bitmap_files_new = 0;
119 int Num_sound_files_new = 0;
120 BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
121 static SoundFile AllSounds[ MAX_SOUND_FILES ];
123 int Piggy_hamfile_version = 0;
125 int piggy_low_memory = 0;
127 int Piggy_bitmap_cache_size = 0;
128 int Piggy_bitmap_cache_next = 0;
129 ubyte * Piggy_bitmap_cache_data = NULL;
130 static int GameBitmapOffset[MAX_BITMAP_FILES];
131 static ubyte GameBitmapFlags[MAX_BITMAP_FILES];
132 ushort GameBitmapXlat[MAX_BITMAP_FILES];
134 #define PIGGY_BUFFER_SIZE (2400*1024)
137 #define PIGGY_SMALL_BUFFER_SIZE (1400*1024) // size of buffer when piggy_low_memory is set
140 #undef PIGGY_BUFFER_SIZE
141 #undef PIGGY_SMALL_BUFFER_SIZE
143 #define PIGGY_BUFFER_SIZE (2000*1024)
144 #define PIGGY_SMALL_BUFFER_SIZE (1100 * 1024)
149 int piggy_page_flushed = 0;
151 #define DBM_FLAG_ABM 64 // animated bitmap
152 #define DBM_NUM_FRAMES 63
154 #define BM_FLAGS_TO_COPY (BM_FLAG_TRANSPARENT | BM_FLAG_SUPER_TRANSPARENT \
155 | BM_FLAG_NO_LIGHTING | BM_FLAG_RLE | BM_FLAG_RLE_BIG)
157 typedef struct DiskBitmapHeader {
159 ubyte dflags; // bits 0-5 anim frame num, bit 6 abm flag
160 ubyte width; // low 8 bits here, 4 more bits in wh_extra
161 ubyte height; // low 8 bits here, 4 more bits in wh_extra
162 ubyte wh_extra; // bits 0-3 width, bits 4-7 height
166 } __pack__ DiskBitmapHeader;
168 #define DISKBITMAPHEADER_D1_SIZE 17 // no wh_extra
170 typedef struct DiskSoundHeader {
175 } __pack__ DiskSoundHeader;
178 #define DiskBitmapHeader_read(dbh, fp) cfread(dbh, sizeof(DiskBitmapHeader), 1, fp)
179 #define DiskSoundHeader_read(dsh, fp) cfread(dsh, sizeof(DiskSoundHeader), 1, fp)
182 * reads a DiskBitmapHeader structure from a CFILE
184 void DiskBitmapHeader_read(DiskBitmapHeader *dbh, CFILE *fp)
186 cfread(dbh->name, 8, 1, fp);
187 dbh->dflags = cfile_read_byte(fp);
188 dbh->width = cfile_read_byte(fp);
189 dbh->height = cfile_read_byte(fp);
190 dbh->wh_extra = cfile_read_byte(fp);
191 dbh->flags = cfile_read_byte(fp);
192 dbh->avg_color = cfile_read_byte(fp);
193 dbh->offset = cfile_read_int(fp);
197 * reads a DiskSoundHeader structure from a CFILE
199 void DiskSoundHeader_read(DiskSoundHeader *dsh, CFILE *fp)
201 cfread(dsh->name, 8, 1, fp);
202 dsh->length = cfile_read_int(fp);
203 dsh->data_length = cfile_read_int(fp);
204 dsh->offset = cfile_read_int(fp);
206 #endif // FAST_FILE_IO
209 * reads a descent 1 DiskBitmapHeader structure from a CFILE
211 void DiskBitmapHeader_d1_read(DiskBitmapHeader *dbh, CFILE *fp)
213 cfread(dbh->name, 8, 1, fp);
214 dbh->dflags = cfile_read_byte(fp);
215 dbh->width = cfile_read_byte(fp);
216 dbh->height = cfile_read_byte(fp);
218 dbh->flags = cfile_read_byte(fp);
219 dbh->avg_color = cfile_read_byte(fp);
220 dbh->offset = cfile_read_int(fp);
226 extern short cd_VRefNum;
227 extern void ConcatPStr(StringPtr dst, StringPtr src);
228 extern int ConvertPToCStr(StringPtr inPStr, char* outCStrBuf);
229 extern int ConvertCToPStr(char* inCStr, StringPtr outPStrBuf);
232 int piggy_is_substitutable_bitmap( char * name, char * subst_name );
235 void piggy_write_pigfile(char *filename);
236 static void write_int(int i,FILE *file);
239 void swap_0_255(grs_bitmap *bmp)
243 for (i = 0; i < bmp->bm_h * bmp->bm_w; i++) {
244 if(bmp->bm_data[i] == 0)
245 bmp->bm_data[i] = 255;
246 else if (bmp->bm_data[i] == 255)
251 char* piggy_game_bitmap_name(grs_bitmap *bmp)
253 if (bmp >= GameBitmaps && bmp < &GameBitmaps[MAX_BITMAP_FILES])
255 int i = bmp-GameBitmaps; // i = (bmp - GameBitmaps) / sizeof(grs_bitmap);
256 Assert (bmp == &GameBitmaps[i] && i >= 0 && i < MAX_BITMAP_FILES);
257 return AllBitmaps[i].name;
262 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
265 Assert( Num_bitmap_files < MAX_BITMAP_FILES );
267 temp.index = Num_bitmap_files;
271 if ( FindArg("-macdata") )
274 if ( !BigPig ) gr_bitmap_rle_compress( bmp );
275 Num_bitmap_files_new++;
278 strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
279 hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
280 //GameBitmaps[Num_bitmap_files] = *bmp;
282 GameBitmapOffset[Num_bitmap_files] = 0;
283 GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
290 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
294 Assert( Num_sound_files < MAX_SOUND_FILES );
296 strncpy( AllSounds[Num_sound_files].name, name, 12 );
297 hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
298 GameSounds[Num_sound_files] = *snd;
300 SoundOffset[Num_sound_files] = 0;
306 Num_sound_files_new++;
312 bitmap_index piggy_find_bitmap( char * name )
320 if ((t=strchr(name,'#'))!=NULL)
323 for (i=0;i<Num_aliases;i++)
324 if (stricmp(name,alias_list[i].alias_name)==0) {
325 if (t) { //extra stuff for ABMs
326 static char temp[FILENAME_LEN];
327 _splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
333 name=alias_list[i].file_name;
340 i = hashtable_search( &AllBitmapsNames, name );
349 int piggy_find_sound( char * name )
353 i = hashtable_search( &AllDigiSndNames, name );
361 CFILE * Piggy_fp = NULL;
363 #define FILENAME_LEN 13
365 char Current_pigfile[FILENAME_LEN] = "";
367 void piggy_close_file()
372 Current_pigfile[0] = 0;
376 int Pigfile_initialized=0;
378 #define PIGFILE_ID MAKE_SIG('G','I','P','P') //PPIG
379 #define PIGFILE_VERSION 2
381 extern char CDROM_dir[];
383 int request_cd(void);
388 //copies a pigfile from the CD to the current dir
389 //retuns file handle of new pig
390 CFILE *copy_pigfile_from_cd(char *filename) // MACINTOSH VERSION
393 char sourcePathAndFileCStr[255] = "";
394 char destPathAndFileCStr[255] = "";
396 FILE* sourceFile = NULL;
397 FILE* destFile = NULL;
398 const int BUF_SIZE = 4096;
402 Str255 sourcePathAndFilePStr = "\p";
403 Str255 destPathAndFilePStr = "\p";
404 Str255 pigfileNamePStr = "\p";
405 HParamBlockRec theSourcePigHFSParams;
406 HParamBlockRec theDestPigHFSParams;
407 OSErr theErr = noErr;
408 char oldDirCStr[255] = "";
410 getcwd(oldDirCStr, 255);
412 show_boxed_message("Copying bitmap data from CD...");
413 gr_palette_load(gr_palette); //I don't think this line is really needed
416 //First, delete all PIG files currently in the directory
417 if( !FileFindFirst( "*.pig", &find ) )
422 } while( !FileFindNext( &find ) );
428 //Now, copy over new pig
429 songs_stop_redbook(); //so we can read off the cd
431 // make the source path "<cd volume>:Data:filename.pig"
432 //MWA ConvertCToPStr(filename, pigfileNamePStr);
434 //MWA ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:"); // volume ID is cd_VRefNum
435 //MWA ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
438 strcpy(sourcePathAndFileCStr, "Descent II:Data:");
439 strcat(sourcePathAndFileCStr, filename);
441 // make the destination path "<default directory>:Data:filename.pig"
442 //MWA ConcatPStr(destPathAndFilePStr, "\p:Data:");
443 //MWA ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
444 //MWA ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
445 //MWA ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
447 strcpy(destPathAndFileCStr, ":Data:");
448 strcat(destPathAndFileCStr, filename);
450 strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
451 strcpy(destPathAndFilePStr, destPathAndFileCStr);
452 c2pstr(sourcePathAndFilePStr);
453 c2pstr(destPathAndFilePStr);
456 // Open the source file
457 sourceFile = fopen(sourcePathAndFileCStr,"rb");
461 if (request_cd() == -1)
462 Error("Cannot load file <%s> from CD",filename);
465 } while (!sourceFile);
468 // Get the time stamp from the source file
469 theSourcePigHFSParams.fileParam.ioCompletion = nil;
470 theSourcePigHFSParams.fileParam.ioNamePtr = sourcePathAndFilePStr;
471 theSourcePigHFSParams.fileParam.ioVRefNum = cd_VRefNum;
472 theSourcePigHFSParams.fileParam.ioFDirIndex = 0;
473 theSourcePigHFSParams.fileParam.ioDirID = 0;
475 theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
478 // Error getting file time stamp!! Why? JTS
479 Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
482 // Copy the file over
485 // Open the destination file
486 destFile = fopen(destPathAndFileCStr,"wb");
489 Error("Cannot create file: <%s>\n", destPathAndFileCStr);
492 // Copy bytes until the end of the source file
493 while (!feof(sourceFile))
498 bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
499 if (ferror(sourceFile))
500 Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
502 // Assert is bogus Assert(bytes_read == BUF_SIZE || feof(sourceFile));
504 fwrite(buf,1,bytes_read,destFile);
505 if (ferror(destFile))
506 Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
509 // close the source/dest files
510 if (fclose(sourceFile))
511 Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
512 if (fclose(destFile))
513 Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
515 // Get the current hfs data for the new file
516 theDestPigHFSParams.fileParam.ioCompletion = nil;
517 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
518 theDestPigHFSParams.fileParam.ioVRefNum = 0;
519 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
520 theDestPigHFSParams.fileParam.ioDirID = 0;
521 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
522 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
524 // Error getting file time stamp!! Why? JTS
525 Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
528 // Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
529 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
530 theDestPigHFSParams.fileParam.ioVRefNum = 0;
531 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
532 theDestPigHFSParams.fileParam.ioDirID = 0;
534 // Copy the time stamp from the source file info
535 theDestPigHFSParams.fileParam.ioFlCrDat = theSourcePigHFSParams.fileParam.ioFlCrDat;
536 theDestPigHFSParams.fileParam.ioFlMdDat = theSourcePigHFSParams.fileParam.ioFlMdDat;
537 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
538 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
540 // Set the dest file's time stamp to the source file's time stamp values
541 theErr = PBHSetFInfo(&theDestPigHFSParams, false);
543 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
545 Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
548 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
550 return cfopen(destPathAndFileCStr, "rb");
553 #else //PC Version of copy_pigfile_from_cd is below
555 //copies a pigfile from the CD to the current dir
556 //retuns file handle of new pig
557 CFILE *copy_pigfile_from_cd(char *filename)
564 show_boxed_message("Copying bitmap data from CD...");
565 gr_palette_load(gr_palette); //I don't think this line is really needed
567 //First, delete all PIG files currently in the directory
569 if( !FileFindFirst( "*.pig", &find ) ) {
571 cfile_delete(find.name);
572 } while( !FileFindNext( &find ) );
576 //Now, copy over new pig
578 songs_stop_redbook(); //so we can read off the cd
580 //new code to unarj file
581 strcpy(name,CDROM_dir);
582 strcat(name,"descent2.sow");
585 // ret = unarj_specific_file(name,filename,filename);
590 if (ret != EXIT_SUCCESS) {
592 //delete file, so we don't leave partial file
593 cfile_delete(filename);
596 if (request_cd() == -1)
598 //NOTE LINK TO ABOVE IF
599 Error("Cannot load file <%s> from CD",filename);
602 } while (ret != EXIT_SUCCESS);
605 return cfopen(filename, "rb");
608 #endif // end of ifdef MAC around copy_pigfile_from_cd
610 //initialize a pigfile, reading headers
611 //returns the size of all the bitmap data
612 void piggy_init_pigfile(char *filename)
616 char temp_name_read[16];
617 DiskBitmapHeader bmh;
618 int header_size, N_bitmaps, data_size, data_start;
620 char name[255]; // filename + path for the mac
623 piggy_close_file(); //close old pig if still open
625 //rename pigfile for shareware
626 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
627 filename = DEFAULT_PIGFILE_SHAREWARE;
630 Piggy_fp = cfopen( filename, "rb" );
632 sprintf(name, ":Data:%s", filename);
633 Piggy_fp = cfopen( name, "rb" );
635 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
636 if (Piggy_fp == NULL)
638 Error("Cannot load required file <%s>",name);
640 #endif // end of if def shareware
646 return; //if editor, ok to not have pig, because we'll build one
648 Piggy_fp = copy_pigfile_from_cd(filename);
652 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
653 int pig_id,pig_version;
655 pig_id = cfile_read_int(Piggy_fp);
656 pig_version = cfile_read_int(Piggy_fp);
657 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
658 cfclose(Piggy_fp); //out of date pig
659 Piggy_fp = NULL; //..so pretend it's not here
666 return; //if editor, ok to not have pig, because we'll build one
668 Error("Cannot load required file <%s>",filename);
672 strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
674 N_bitmaps = cfile_read_int(Piggy_fp);
676 header_size = N_bitmaps * sizeof(DiskBitmapHeader);
678 data_start = header_size + cftell(Piggy_fp);
680 data_size = cfilelength(Piggy_fp) - data_start;
682 Num_bitmap_files = 1;
684 for (i=0; i<N_bitmaps; i++ )
687 grs_bitmap *bm = &GameBitmaps[i + 1];
689 DiskBitmapHeader_read(&bmh, Piggy_fp);
690 memcpy( temp_name_read, bmh.name, 8 );
691 temp_name_read[8] = 0;
692 if ( bmh.dflags & DBM_FLAG_ABM )
693 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & DBM_NUM_FRAMES );
695 strcpy( temp_name, temp_name_read );
696 width = bmh.width + ((short) (bmh.wh_extra & 0x0f) << 8);
697 gr_init_bitmap(bm, 0, 0, 0, width, bmh.height + ((short) (bmh.wh_extra & 0xf0) << 4), width, NULL);
698 bm->bm_flags = BM_FLAG_PAGED_OUT;
699 bm->avg_color = bmh.avg_color;
701 GameBitmapFlags[i+1] = bmh.flags & BM_FLAGS_TO_COPY;
703 GameBitmapOffset[i+1] = bmh.offset + data_start;
704 Assert( (i+1) == Num_bitmap_files );
705 piggy_register_bitmap(bm, temp_name, 1);
709 Piggy_bitmap_cache_size = data_size + (data_size/10); //extra mem for new bitmaps
710 Assert( Piggy_bitmap_cache_size > 0 );
712 Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
714 if (piggy_low_memory)
715 Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
718 BitmapBits = d_malloc( Piggy_bitmap_cache_size );
719 if ( BitmapBits == NULL )
720 Error( "Not enough memory to load bitmaps\n" );
721 Piggy_bitmap_cache_data = BitmapBits;
722 Piggy_bitmap_cache_next = 0;
724 #if defined(MACINTOSH) && defined(SHAREWARE)
725 // load_exit_models();
728 Pigfile_initialized=1;
731 #define FILENAME_LEN 13
732 #define MAX_BITMAPS_PER_BRUSH 30
734 extern int compute_average_pixel(grs_bitmap *new);
735 extern void gr_set_bitmap_data(grs_bitmap *bm, unsigned char *data);
737 ubyte *Bitmap_replacement_data = NULL;
739 //reads in a new pigfile (for new palette)
740 //returns the size of all the bitmap data
741 void piggy_new_pigfile(char *pigname)
745 char temp_name_read[16];
746 DiskBitmapHeader bmh;
747 int header_size, N_bitmaps, data_size, data_start;
748 int must_rewrite_pig = 0;
755 //rename pigfile for shareware
756 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
757 pigname = DEFAULT_PIGFILE_SHAREWARE;
759 if (strnicmp(Current_pigfile, pigname, sizeof(Current_pigfile)) == 0 // correct pig already loaded
760 && !Bitmap_replacement_data) // no need to reload: no bitmaps were altered
763 if (!Pigfile_initialized) { //have we ever opened a pigfile?
764 piggy_init_pigfile(pigname); //..no, so do initialization stuff
768 piggy_close_file(); //close old pig if still open
770 Piggy_bitmap_cache_next = 0; //free up cache
772 strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
775 Piggy_fp = cfopen( pigname, "rb" );
777 sprintf(name, ":Data:%s", pigname);
778 Piggy_fp = cfopen( name, "rb" );
780 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
781 if (Piggy_fp == NULL)
783 Error("Cannot load required file <%s>",name);
785 #endif // end of if def shareware
790 Piggy_fp = copy_pigfile_from_cd(pigname);
793 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
794 int pig_id,pig_version;
796 pig_id = cfile_read_int(Piggy_fp);
797 pig_version = cfile_read_int(Piggy_fp);
798 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
799 cfclose(Piggy_fp); //out of date pig
800 Piggy_fp = NULL; //..so pretend it's not here
806 Error("Cannot open correct version of <%s>", pigname);
811 N_bitmaps = cfile_read_int(Piggy_fp);
813 header_size = N_bitmaps * sizeof(DiskBitmapHeader);
815 data_start = header_size + cftell(Piggy_fp);
817 data_size = cfilelength(Piggy_fp) - data_start;
819 for (i=1; i<=N_bitmaps; i++ )
821 grs_bitmap *bm = &GameBitmaps[i];
824 DiskBitmapHeader_read(&bmh, Piggy_fp);
825 memcpy( temp_name_read, bmh.name, 8 );
826 temp_name_read[8] = 0;
828 if ( bmh.dflags & DBM_FLAG_ABM )
829 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & DBM_NUM_FRAMES );
831 strcpy( temp_name, temp_name_read );
833 //Make sure name matches
834 if (strcmp(temp_name,AllBitmaps[i].name)) {
835 //Int3(); //this pig is out of date. Delete it
839 strcpy(AllBitmaps[i].name,temp_name);
841 width = bmh.width + ((short) (bmh.wh_extra & 0x0f) << 8);
842 gr_set_bitmap_data(bm, NULL); // free ogl texture
843 gr_init_bitmap(bm, 0, 0, 0, width, bmh.height + ((short) (bmh.wh_extra & 0xf0) << 4), width, NULL);
844 bm->bm_flags = BM_FLAG_PAGED_OUT;
845 bm->avg_color = bmh.avg_color;
847 GameBitmapFlags[i] = bmh.flags & BM_FLAGS_TO_COPY;
849 GameBitmapOffset[i] = bmh.offset + data_start;
853 N_bitmaps = 0; //no pigfile, so no bitmaps
857 Assert(N_bitmaps == Num_bitmap_files-1);
861 if (must_rewrite_pig || (N_bitmaps < Num_bitmap_files-1)) {
864 //re-read the bitmaps that aren't in this pig
866 for (i=N_bitmaps+1;i<Num_bitmap_files;i++) {
869 p = strchr(AllBitmaps[i].name,'#');
871 if (p) { // this is an ABM == animated bitmap
872 char abmname[FILENAME_LEN];
874 grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
875 int iff_error; //reference parm to avoid warning message
877 char basename[FILENAME_LEN];
880 strcpy(basename,AllBitmaps[i].name);
881 basename[p-AllBitmaps[i].name] = 0; //cut off "#nn" part
883 sprintf( abmname, "%s.abm", basename );
885 iff_error = iff_read_animbrush(abmname,bm,MAX_BITMAPS_PER_BRUSH,&nframes,newpal);
887 if (iff_error != IFF_NO_ERROR) {
888 mprintf((1,"File %s - IFF error: %s",abmname,iff_errormsg(iff_error)));
889 Error("File %s - IFF error: %s",abmname,iff_errormsg(iff_error));
892 for (fnum=0;fnum<nframes; fnum++) {
896 sprintf( tempname, "%s#%d", basename, fnum );
898 //SuperX = (GameBitmaps[i+fnum].bm_flags&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
899 SuperX = (GameBitmapFlags[i+fnum]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
900 //above makes assumption that supertransparent color is 254
902 if ( iff_has_transparency )
903 gr_remap_bitmap_good( bm[fnum], newpal, iff_transparent_color, SuperX );
905 gr_remap_bitmap_good( bm[fnum], newpal, -1, SuperX );
907 bm[fnum]->avg_color = compute_average_pixel(bm[fnum]);
910 if ( FindArg("-macdata") )
911 swap_0_255( bm[fnum] );
913 if ( !BigPig ) gr_bitmap_rle_compress( bm[fnum] );
915 if (bm[fnum]->bm_flags & BM_FLAG_RLE)
916 size = *((int *) bm[fnum]->bm_data);
918 size = bm[fnum]->bm_w * bm[fnum]->bm_h;
920 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],bm[fnum]->bm_data,size);
921 d_free(bm[fnum]->bm_data);
922 bm[fnum]->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
923 Piggy_bitmap_cache_next += size;
925 GameBitmaps[i+fnum] = *bm[fnum];
927 // -- mprintf( (0, "U" ));
931 i += nframes-1; //filled in multiple bitmaps
933 else { //this is a BBM
938 char bbmname[FILENAME_LEN];
941 MALLOC( new, grs_bitmap, 1 );
943 sprintf( bbmname, "%s.bbm", AllBitmaps[i].name );
944 iff_error = iff_read_bitmap(bbmname,new,BM_LINEAR,newpal);
947 if (iff_error != IFF_NO_ERROR) {
948 mprintf((1, "File %s - IFF error: %s",bbmname,iff_errormsg(iff_error)));
949 Error("File %s - IFF error: %s",bbmname,iff_errormsg(iff_error));
952 SuperX = (GameBitmapFlags[i]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
953 //above makes assumption that supertransparent color is 254
955 if ( iff_has_transparency )
956 gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
958 gr_remap_bitmap_good( new, newpal, -1, SuperX );
960 new->avg_color = compute_average_pixel(new);
963 if ( FindArg("-macdata") )
966 if ( !BigPig ) gr_bitmap_rle_compress( new );
968 if (new->bm_flags & BM_FLAG_RLE)
969 size = *((int *) new->bm_data);
971 size = new->bm_w * new->bm_h;
973 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],new->bm_data,size);
974 d_free(new->bm_data);
975 new->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
976 Piggy_bitmap_cache_next += size;
978 GameBitmaps[i] = *new;
982 // -- mprintf( (0, "U" ));
986 //@@Dont' do these things which are done when writing
987 //@@for (i=0; i < Num_bitmap_files; i++ ) {
988 //@@ bitmap_index bi;
990 //@@ PIGGY_PAGE_IN( bi );
993 //@@piggy_close_file();
995 piggy_write_pigfile(pigname);
997 Current_pigfile[0] = 0; //say no pig, to force reload
999 piggy_new_pigfile(pigname); //read in just-generated pig
1003 #endif //ifdef EDITOR
1007 ubyte bogus_data[64*64];
1008 ubyte bogus_bitmap_initialized=0;
1009 digi_sound bogus_sound;
1011 #define HAMFILE_ID MAKE_SIG('!','M','A','H') //HAM!
1012 #define HAMFILE_VERSION 3
1013 //version 1 -> 2: save marker_model_num
1014 //version 2 -> 3: removed sound files
1016 #define SNDFILE_ID MAKE_SIG('D','N','S','D') //DSND
1017 #define SNDFILE_VERSION 1
1021 CFILE * ham_fp = NULL;
1023 int sound_offset = 0;
1029 ham_fp = cfopen( DEFAULT_HAMFILE, "rb" );
1031 sprintf(name, ":Data:%s", DEFAULT_HAMFILE );
1032 ham_fp = cfopen( name, "rb" );
1035 if (ham_fp == NULL) {
1036 Must_write_hamfile = 1;
1040 //make sure ham is valid type file & is up-to-date
1041 ham_id = cfile_read_int(ham_fp);
1042 Piggy_hamfile_version = cfile_read_int(ham_fp);
1043 if (ham_id != HAMFILE_ID)
1044 Error("Cannot open ham file %s\n", DEFAULT_HAMFILE);
1046 if (ham_id != HAMFILE_ID || Piggy_hamfile_version != HAMFILE_VERSION) {
1047 Must_write_hamfile = 1;
1048 cfclose(ham_fp); //out of date ham
1053 if (Piggy_hamfile_version < 3) // hamfile contains sound info
1054 sound_offset = cfile_read_int(ham_fp);
1060 bm_read_all(ham_fp);
1061 cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1063 //for (i = 0; i < MAX_BITMAP_FILES; i++) {
1064 //GameBitmapXlat[i] = INTEL_SHORT(GameBitmapXlat[i]);
1065 //printf("GameBitmapXlat[%d] = %d\n", i, GameBitmapXlat[i]);
1070 if (Piggy_hamfile_version < 3) {
1075 DiskSoundHeader sndh;
1076 digi_sound temp_sound;
1077 char temp_name_read[16];
1080 cfseek(ham_fp, sound_offset, SEEK_SET);
1081 N_sounds = cfile_read_int(ham_fp);
1083 sound_start = cftell(ham_fp);
1085 header_size = N_sounds * sizeof(DiskSoundHeader);
1089 for (i=0; i<N_sounds; i++ ) {
1090 DiskSoundHeader_read(&sndh, ham_fp);
1091 temp_sound.length = sndh.length;
1092 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1093 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1094 memcpy( temp_name_read, sndh.name, 8 );
1095 temp_name_read[8] = 0;
1096 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1098 if (piggy_is_needed(i))
1099 #endif // note link to if.
1100 sbytes += sndh.length;
1101 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1104 SoundBits = d_malloc( sbytes + 16 );
1105 if ( SoundBits == NULL )
1106 Error( "Not enough memory to load sounds\n" );
1108 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1110 // piggy_read_sounds(ham_fp);
1122 CFILE * snd_fp = NULL;
1123 int snd_id,snd_version;
1128 DiskSoundHeader sndh;
1129 digi_sound temp_sound;
1130 char temp_name_read[16];
1137 snd_fp = cfopen( DEFAULT_SNDFILE, "rb" );
1139 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1140 snd_fp = cfopen( name, "rb");
1146 //make sure soundfile is valid type file & is up-to-date
1147 snd_id = cfile_read_int(snd_fp);
1148 snd_version = cfile_read_int(snd_fp);
1149 if (snd_id != SNDFILE_ID || snd_version != SNDFILE_VERSION) {
1150 cfclose(snd_fp); //out of date sound file
1154 N_sounds = cfile_read_int(snd_fp);
1156 sound_start = cftell(snd_fp);
1157 size = cfilelength(snd_fp) - sound_start;
1159 mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
1161 header_size = N_sounds*sizeof(DiskSoundHeader);
1165 for (i=0; i<N_sounds; i++ ) {
1166 DiskSoundHeader_read(&sndh, snd_fp);
1167 //size -= sizeof(DiskSoundHeader);
1168 temp_sound.length = sndh.length;
1169 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1170 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1171 memcpy( temp_name_read, sndh.name, 8 );
1172 temp_name_read[8] = 0;
1173 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1175 if (piggy_is_needed(i))
1176 #endif // note link to if.
1177 sbytes += sndh.length;
1178 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1181 SoundBits = d_malloc( sbytes + 16 );
1182 if ( SoundBits == NULL )
1183 Error( "Not enough memory to load sounds\n" );
1185 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1187 // piggy_read_sounds(snd_fp);
1194 int piggy_init(void)
1196 int ham_ok=0,snd_ok=0;
1199 hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
1200 hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
1202 for (i=0; i<MAX_SOUND_FILES; i++ ) {
1203 GameSounds[i].length = 0;
1204 GameSounds[i].data = NULL;
1208 for (i=0; i<MAX_BITMAP_FILES; i++ )
1209 GameBitmapXlat[i] = i;
1211 if ( !bogus_bitmap_initialized ) {
1215 bogus_bitmap_initialized = 1;
1216 c = gr_find_closest_color( 0, 0, 63 );
1217 for (i=0; i<4096; i++ ) bogus_data[i] = c;
1218 c = gr_find_closest_color( 63, 0, 0 );
1219 // Make a big red X !
1220 for (i=0; i<64; i++ ) {
1221 bogus_data[i*64+i] = c;
1222 bogus_data[i*64+(63-i)] = c;
1224 gr_init_bitmap(&GameBitmaps[Num_bitmap_files], 0, 0, 0, 64, 64, 64, bogus_data);
1225 piggy_register_bitmap(&GameBitmaps[Num_bitmap_files], "bogus", 1);
1226 bogus_sound.length = 64*64;
1227 bogus_sound.data = bogus_data;
1228 GameBitmapOffset[0] = 0;
1231 if ( FindArg( "-bigpig" ))
1234 if ( FindArg( "-lowmem" ))
1235 piggy_low_memory = 1;
1237 if ( FindArg( "-nolowmem" ))
1238 piggy_low_memory = 0;
1240 if (piggy_low_memory)
1243 gr_set_curfont( SMALL_FONT );
1244 gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
1245 gr_printf( 0x8000, grd_curcanv->cv_h-20, "%s...", TXT_LOADING_DATA );
1247 #if 1 //def EDITOR //need for d1 mission briefings
1248 piggy_init_pigfile(DEFAULT_PIGFILE);
1251 snd_ok = ham_ok = read_hamfile();
1253 if (Piggy_hamfile_version >= 3)
1254 snd_ok = read_sndfile();
1256 atexit(piggy_close);
1258 mprintf ((0,"HamOk=%d SndOk=%d\n",ham_ok,snd_ok));
1259 return (ham_ok && snd_ok); //read ok
1262 int piggy_is_needed(int soundnum)
1266 if ( !digi_lomem ) return 1;
1268 for (i=0; i<MAX_SOUNDS; i++ ) {
1269 if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
1276 void piggy_read_sounds(void)
1289 fp = cfopen( DEFAULT_SNDFILE, "rb" );
1291 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1292 fp = cfopen( name, "rb");
1298 for (i=0; i<Num_sound_files; i++ ) {
1299 digi_sound *snd = &GameSounds[i];
1301 if ( SoundOffset[i] > 0 ) {
1302 if ( piggy_is_needed(i) ) {
1303 cfseek( fp, SoundOffset[i], SEEK_SET );
1305 // Read in the sound data!!!
1308 sbytes += snd->length;
1309 cfread( snd->data, snd->length, 1, fp );
1312 snd->data = (ubyte *) -1;
1318 mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
1323 extern int descent_critical_error;
1324 extern unsigned descent_critical_deverror;
1325 extern unsigned descent_critical_errcode;
1327 char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
1328 "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
1329 "Read fault", "General Failure" };
1331 void piggy_critical_error()
1333 grs_canvas * save_canv;
1334 grs_font * save_font;
1336 save_canv = grd_curcanv;
1337 save_font = grd_curcanv->cv_font;
1338 gr_palette_load( gr_palette );
1339 i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A' );
1342 gr_set_current_canvas(save_canv);
1343 grd_curcanv->cv_font = save_font;
1346 extern void gr_set_bitmap_flags(grs_bitmap *pbm, int flags);
1348 void piggy_bitmap_page_in( bitmap_index bitmap )
1357 Assert( i < MAX_BITMAP_FILES );
1358 Assert( i < Num_bitmap_files );
1359 Assert( Piggy_bitmap_cache_size > 0 );
1361 if ( i < 1 ) return;
1362 if ( i >= MAX_BITMAP_FILES ) return;
1363 if ( i >= Num_bitmap_files ) return;
1365 if ( GameBitmapOffset[i] == 0 ) return; // A read-from-disk bitmap!!!
1367 if ( piggy_low_memory ) {
1369 i = GameBitmapXlat[i]; // Xlat for low-memory settings!
1372 bmp = &GameBitmaps[i];
1374 if ( bmp->bm_flags & BM_FLAG_PAGED_OUT ) {
1378 descent_critical_error = 0;
1379 cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
1380 if ( descent_critical_error ) {
1381 piggy_critical_error();
1385 gr_set_bitmap_flags(bmp, GameBitmapFlags[i]);
1387 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1388 int zsize = 0, pigsize = cfilelength(Piggy_fp);
1389 descent_critical_error = 0;
1390 zsize = cfile_read_int(Piggy_fp);
1391 if ( descent_critical_error ) {
1392 piggy_critical_error();
1396 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1397 //Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );
1398 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1400 piggy_bitmap_page_out_all();
1403 descent_critical_error = 0;
1404 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next+4], 1, zsize-4, Piggy_fp );
1405 if ( descent_critical_error ) {
1406 piggy_critical_error();
1409 *((int *) (Piggy_bitmap_cache_data + Piggy_bitmap_cache_next)) = INTEL_INT(zsize);
1410 gr_set_bitmap_data(bmp, &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next]);
1415 if (!FindArg("-macdata"))
1417 // otherwise, fall through...
1418 case MAC_ALIEN1_PIGSIZE:
1419 case MAC_ALIEN2_PIGSIZE:
1420 case MAC_FIRE_PIGSIZE:
1421 case MAC_GROUPA_PIGSIZE:
1422 case MAC_ICE_PIGSIZE:
1423 case MAC_WATER_PIGSIZE:
1424 rle_swap_0_255( bmp );
1425 memcpy(&zsize, bmp->bm_data, 4);
1430 Piggy_bitmap_cache_next += zsize;
1431 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1433 piggy_bitmap_page_out_all();
1438 int pigsize = cfilelength(Piggy_fp);
1439 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1440 Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );
1441 if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) {
1442 piggy_bitmap_page_out_all();
1445 descent_critical_error = 0;
1446 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
1447 if ( descent_critical_error ) {
1448 piggy_critical_error();
1451 gr_set_bitmap_data(bmp, &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next]);
1452 Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
1457 if (!FindArg("-macdata"))
1459 // otherwise, fall through...
1460 case MAC_ALIEN1_PIGSIZE:
1461 case MAC_ALIEN2_PIGSIZE:
1462 case MAC_FIRE_PIGSIZE:
1463 case MAC_GROUPA_PIGSIZE:
1464 case MAC_ICE_PIGSIZE:
1465 case MAC_WATER_PIGSIZE:
1472 //@@if ( bmp->bm_selector ) {
1473 //@@#if !defined(WINDOWS) && !defined(MACINTOSH)
1474 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1475 //@@ Error( "Error modifying selector base in piggy.c\n" );
1482 if ( piggy_low_memory ) {
1484 GameBitmaps[org_i] = GameBitmaps[i];
1487 //@@Removed from John's code:
1489 //@@ if ( bmp->bm_selector ) {
1490 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1491 //@@ Error( "Error modifying selector base in piggy.c\n" );
1497 void piggy_bitmap_page_out_all()
1501 Piggy_bitmap_cache_next = 0;
1503 piggy_page_flushed++;
1508 for (i=0; i<Num_bitmap_files; i++ ) {
1509 if ( GameBitmapOffset[i] > 0 ) { // Don't page out bitmaps read from disk!!!
1510 GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
1511 gr_set_bitmap_data(&GameBitmaps[i], NULL);
1515 mprintf(( 0, "Flushing piggy bitmap cache\n" ));
1518 void piggy_load_level_data()
1520 piggy_bitmap_page_out_all();
1526 void piggy_write_pigfile(char *filename)
1529 int bitmap_data_start, data_offset;
1530 DiskBitmapHeader bmh;
1532 char subst_name[32];
1535 char tname[FILENAME_LEN];
1537 // -- mprintf( (0, "Paging in all piggy bitmaps..." ));
1538 for (i=0; i < Num_bitmap_files; i++ ) {
1541 PIGGY_PAGE_IN( bi );
1543 // -- mprintf( (0, "\n" ));
1547 // -- mprintf( (0, "Creating %s...",filename ));
1549 pig_fp = fopen( filename, "wb" ); //open PIG file
1550 Assert( pig_fp!=NULL );
1552 write_int(PIGFILE_ID,pig_fp);
1553 write_int(PIGFILE_VERSION,pig_fp);
1556 fwrite( &Num_bitmap_files, sizeof(int), 1, pig_fp );
1559 bitmap_data_start = ftell(pig_fp);
1560 bitmap_data_start += (Num_bitmap_files - 1) * sizeof(DiskBitmapHeader);
1561 data_offset = bitmap_data_start;
1563 change_filename_extension(tname,filename,"lst");
1564 fp1 = fopen( tname, "wt" );
1565 change_filename_extension(tname,filename,"all");
1566 fp2 = fopen( tname, "wt" );
1568 for (i=1; i < Num_bitmap_files; i++ ) {
1574 p = strchr(AllBitmaps[i].name, '#');
1575 if (p) { // this is an ABM == animated bitmap
1581 fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
1582 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1583 Assert( n <= DBM_NUM_FRAMES );
1584 bmh.dflags = DBM_FLAG_ABM + n;
1588 fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
1589 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1593 bmp = &GameBitmaps[i];
1595 Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
1598 fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
1599 org_offset = ftell(pig_fp);
1600 bmh.offset = data_offset - bitmap_data_start;
1601 fseek( pig_fp, data_offset, SEEK_SET );
1603 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1604 size = (int *)bmp->bm_data;
1605 fwrite( bmp->bm_data, sizeof(ubyte), *size, pig_fp );
1606 data_offset += *size;
1608 fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
1610 fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, pig_fp );
1611 data_offset += bmp->bm_rowsize * bmp->bm_h;
1613 fprintf( fp1, ".\n" );
1615 fseek( pig_fp, org_offset, SEEK_SET );
1616 Assert( GameBitmaps[i].bm_w < 4096 );
1617 bmh.width = (GameBitmaps[i].bm_w & 0xff);
1618 bmh.wh_extra = ((GameBitmaps[i].bm_w >> 8) & 0x0f);
1619 Assert( GameBitmaps[i].bm_h < 4096 );
1620 bmh.height = GameBitmaps[i].bm_h;
1621 bmh.wh_extra |= ((GameBitmaps[i].bm_h >> 4) & 0xf0);
1622 bmh.flags = GameBitmaps[i].bm_flags;
1623 if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name )) {
1624 bitmap_index other_bitmap;
1625 other_bitmap = piggy_find_bitmap( subst_name );
1626 GameBitmapXlat[i] = other_bitmap.index;
1627 bmh.flags |= BM_FLAG_PAGED_OUT;
1628 //mprintf(( 0, "Skipping bitmap %d\n", i ));
1629 //mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
1631 bmh.flags &= ~BM_FLAG_PAGED_OUT;
1633 bmh.avg_color=GameBitmaps[i].avg_color;
1634 fwrite(&bmh, sizeof(DiskBitmapHeader), 1, pig_fp); // Mark as a bitmap
1639 mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
1640 fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
1647 static void write_int(int i,FILE *file)
1649 if (fwrite( &i, sizeof(i), 1, file) != 1)
1650 Error( "Error reading int in gamesave.c" );
1654 void piggy_dump_all()
1658 int org_offset,data_offset=0;
1659 DiskSoundHeader sndh;
1660 int sound_data_start=0;
1663 #ifdef NO_DUMP_SOUNDS
1664 Num_sound_files = 0;
1665 Num_sound_files_new = 0;
1668 if (!Must_write_hamfile && (Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
1671 fp1 = fopen( "ham.lst", "wt" );
1672 fp2 = fopen( "ham.all", "wt" );
1674 if (Must_write_hamfile || Num_bitmap_files_new) {
1676 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1678 ham_fp = fopen( DEFAULT_HAMFILE, "wb" ); //open HAM file
1679 Assert( ham_fp!=NULL );
1681 write_int(HAMFILE_ID,ham_fp);
1682 write_int(HAMFILE_VERSION,ham_fp);
1684 bm_write_all(ham_fp);
1685 xlat_offset = ftell(ham_fp);
1686 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1689 if (Num_bitmap_files_new)
1690 piggy_write_pigfile(DEFAULT_PIGFILE);
1692 //free up memeory used by new bitmaps
1693 for (i=Num_bitmap_files-Num_bitmap_files_new;i<Num_bitmap_files;i++)
1694 d_free(GameBitmaps[i].bm_data);
1696 //next thing must be done after pig written
1697 fseek( ham_fp, xlat_offset, SEEK_SET );
1698 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1701 mprintf( (0, "\n" ));
1704 if (Num_sound_files_new) {
1706 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1707 // Now dump sound file
1708 ham_fp = fopen( DEFAULT_SNDFILE, "wb" );
1709 Assert( ham_fp!=NULL );
1711 write_int(SNDFILE_ID,ham_fp);
1712 write_int(SNDFILE_VERSION,ham_fp);
1714 fwrite( &Num_sound_files, sizeof(int), 1, ham_fp );
1716 mprintf( (0, "\nDumping sounds..." ));
1718 sound_data_start = ftell(ham_fp);
1719 sound_data_start += Num_sound_files*sizeof(DiskSoundHeader);
1720 data_offset = sound_data_start;
1722 for (i=0; i < Num_sound_files; i++ ) {
1725 snd = &GameSounds[i];
1726 strcpy( sndh.name, AllSounds[i].name );
1727 sndh.length = GameSounds[i].length;
1728 sndh.offset = data_offset - sound_data_start;
1730 org_offset = ftell(ham_fp);
1731 fseek( ham_fp, data_offset, SEEK_SET );
1733 sndh.data_length = GameSounds[i].length;
1734 fwrite( snd->data, sizeof(ubyte), snd->length, ham_fp );
1735 data_offset += snd->length;
1736 fseek( ham_fp, org_offset, SEEK_SET );
1737 fwrite( &sndh, sizeof(DiskSoundHeader), 1, ham_fp ); // Mark as a bitmap
1739 fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
1740 fprintf( fp2, "%s.raw\n", AllSounds[i].name );
1744 mprintf( (0, "\n" ));
1747 fprintf( fp1, "Total sound size: %d bytes\n", data_offset-sound_data_start);
1748 mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
1749 fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
1754 // Never allow the game to run after building ham.
1768 d_free( SoundBits );
1770 hashtable_free( &AllBitmapsNames );
1771 hashtable_free( &AllDigiSndNames );
1775 int piggy_does_bitmap_exist_slow( char * name )
1779 for (i=0; i<Num_bitmap_files; i++ ) {
1780 if ( !strcmp( AllBitmaps[i].name, name) )
1787 #define NUM_GAUGE_BITMAPS 23
1788 char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = {
1789 "gauge01", "gauge01b",
1790 "gauge02", "gauge02b",
1791 "gauge06", "gauge06b",
1792 "targ01", "targ01b",
1793 "targ02", "targ02b",
1794 "targ03", "targ03b",
1795 "targ04", "targ04b",
1796 "targ05", "targ05b",
1797 "targ06", "targ06b",
1798 "gauge18", "gauge18b",
1804 int piggy_is_gauge_bitmap( char * base_name )
1807 for (i=0; i<NUM_GAUGE_BITMAPS; i++ ) {
1808 if ( !stricmp( base_name, gauge_bitmap_names[i] ))
1815 int piggy_is_substitutable_bitmap( char * name, char * subst_name )
1819 char base_name[ 16 ];
1821 strcpy( subst_name, name );
1822 p = strchr( subst_name, '#' );
1824 frame = atoi( &p[1] );
1826 strcpy( base_name, subst_name );
1827 if ( !piggy_is_gauge_bitmap( base_name )) {
1828 sprintf( subst_name, "%s#%d", base_name, frame+1 );
1829 if ( piggy_does_bitmap_exist_slow( subst_name ) ) {
1831 sprintf( subst_name, "%s#%d", base_name, frame-1 );
1837 strcpy( subst_name, name );
1844 * Functions for loading replacement textures
1845 * 1) From .pog files
1846 * 2) From descent.pig (for loading d1 levels)
1849 extern char last_palette_loaded_pig[];
1851 void free_bitmap_replacements()
1853 if (Bitmap_replacement_data) {
1854 d_free(Bitmap_replacement_data);
1855 Bitmap_replacement_data = NULL;
1859 void load_bitmap_replacements(char *level_name)
1861 char ifile_name[FILENAME_LEN];
1865 //first, free up data allocated for old bitmaps
1866 free_bitmap_replacements();
1868 change_filename_extension(ifile_name, level_name, ".POG" );
1870 ifile = cfopen(ifile_name,"rb");
1873 int id,version,n_bitmaps;
1874 int bitmap_data_size;
1877 id = cfile_read_int(ifile);
1878 version = cfile_read_int(ifile);
1880 if (id != MAKE_SIG('G','O','P','D') || version != 1) {
1885 n_bitmaps = cfile_read_int(ifile);
1887 MALLOC( indices, ushort, n_bitmaps );
1889 for (i = 0; i < n_bitmaps; i++)
1890 indices[i] = cfile_read_short(ifile);
1892 bitmap_data_size = cfilelength(ifile) - cftell(ifile) - sizeof(DiskBitmapHeader) * n_bitmaps;
1893 MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
1895 for (i=0;i<n_bitmaps;i++) {
1896 DiskBitmapHeader bmh;
1897 grs_bitmap *bm = &GameBitmaps[indices[i]];
1900 DiskBitmapHeader_read(&bmh, ifile);
1902 width = bmh.width + ((short) (bmh.wh_extra & 0x0f) << 8);
1903 gr_set_bitmap_data(bm, NULL); // free ogl texture
1904 gr_init_bitmap(bm, 0, 0, 0, width, bmh.height + ((short) (bmh.wh_extra & 0xf0) << 4), width, NULL);
1905 bm->avg_color = bmh.avg_color;
1906 bm->bm_data = (ubyte *) bmh.offset;
1908 gr_set_bitmap_flags(bm, bmh.flags & BM_FLAGS_TO_COPY);
1910 GameBitmapOffset[indices[i]] = 0; // don't try to read bitmap from current pigfile
1913 cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
1915 for (i = 0; i < n_bitmaps; i++)
1917 grs_bitmap *bm = &GameBitmaps[indices[i]];
1918 gr_set_bitmap_data(bm, Bitmap_replacement_data + (int) bm->bm_data);
1925 last_palette_loaded_pig[0]= 0; //force pig re-load
1927 texmerge_flush(); //for re-merging with new textures
1930 atexit(free_bitmap_replacements);
1933 /* calculate table to translate d1 bitmaps to current palette,
1934 * return -1 on error
1936 int get_d1_colormap( ubyte *d1_palette, ubyte *colormap )
1939 CFILE * palette_file = cfopen(D1_PALETTE, "rb");
1940 if (!palette_file || cfilelength(palette_file) != 9472)
1942 cfread( d1_palette, 256, 3, palette_file);
1943 cfclose( palette_file );
1944 build_colormap_good( d1_palette, colormap, freq );
1945 // don't change transparencies:
1946 colormap[254] = 254;
1947 colormap[255] = 255;
1951 #define JUST_IN_CASE 132 /* is enough for d1 pc registered */
1952 void bitmap_read_d1( grs_bitmap *bitmap, /* read into this bitmap */
1953 CFILE *d1_Piggy_fp, /* read from this file */
1954 int bitmap_data_start, /* specific to file */
1955 DiskBitmapHeader *bmh, /* header info for bitmap */
1956 ubyte **next_bitmap, /* where to write it (if 0, use malloc) */
1957 ubyte *d1_palette, /* what palette the bitmap has */
1958 ubyte *colormap) /* how to translate bitmap's colors */
1960 int zsize, pigsize = cfilelength(d1_Piggy_fp);
1964 width = bmh->width + ((short) (bmh->wh_extra & 0x0f) << 8);
1965 gr_set_bitmap_data(bitmap, NULL); // free ogl texture
1966 gr_init_bitmap(bitmap, 0, 0, 0, width, bmh->height + ((short) (bmh->wh_extra & 0xf0) << 4), width, NULL);
1967 bitmap->avg_color = bmh->avg_color;
1968 gr_set_bitmap_flags(bitmap, bmh->flags & BM_FLAGS_TO_COPY);
1970 cfseek(d1_Piggy_fp, bitmap_data_start + bmh->offset, SEEK_SET);
1971 if (bmh->flags & BM_FLAG_RLE) {
1972 zsize = cfile_read_int(d1_Piggy_fp);
1973 cfseek(d1_Piggy_fp, -4, SEEK_CUR);
1975 zsize = bitmap->bm_h * bitmap->bm_w;
1978 data = *next_bitmap;
1979 *next_bitmap += zsize;
1981 data = d_malloc(zsize + JUST_IN_CASE);
1985 cfread(data, 1, zsize, d1_Piggy_fp);
1986 gr_set_bitmap_data(bitmap, data);
1988 case D1_MAC_PIGSIZE:
1989 case D1_MAC_SHARE_PIGSIZE:
1990 if (bmh->flags & BM_FLAG_RLE)
1991 rle_swap_0_255(bitmap);
1995 if (bmh->flags & BM_FLAG_RLE)
1996 rle_remap(bitmap, colormap);
1998 gr_remap_bitmap_good(bitmap, d1_palette, TRANSPARENCY_COLOR, -1);
1999 if (bmh->flags & BM_FLAG_RLE) { // size of bitmap could have changed!
2001 memcpy(&new_size, bitmap->bm_data, 4);
2003 *next_bitmap += new_size - zsize;
2005 Assert( zsize + JUST_IN_CASE >= new_size );
2006 bitmap->bm_data = d_realloc(bitmap->bm_data, new_size);
2007 Assert(bitmap->bm_data);
2012 #define D1_MAX_TEXTURES 800
2013 #define D1_MAX_TMAP_NUM 1630 // 1621 in descent.pig Mac registered
2015 /* the inverse of the d2 Textures array, but for the descent 1 pigfile.
2016 * "Textures" looks up a d2 bitmap index given a d2 tmap_num.
2017 * "d1_tmap_nums" looks up a d1 tmap_num given a d1 bitmap. "-1" means "None".
2019 short *d1_tmap_nums = NULL;
2021 void free_d1_tmap_nums() {
2023 d_free(d1_tmap_nums);
2024 d1_tmap_nums = NULL;
2028 void bm_read_d1_tmap_nums(CFILE *d1pig)
2032 free_d1_tmap_nums();
2033 cfseek(d1pig, 8, SEEK_SET);
2034 MALLOC(d1_tmap_nums, short, D1_MAX_TMAP_NUM);
2035 for (i = 0; i < D1_MAX_TMAP_NUM; i++)
2036 d1_tmap_nums[i] = -1;
2037 for (i = 0; i < D1_MAX_TEXTURES; i++) {
2038 d1_index = cfile_read_short(d1pig);
2039 Assert(d1_index >= 0 && d1_index < D1_MAX_TMAP_NUM);
2040 d1_tmap_nums[d1_index] = i;
2042 atexit(free_d1_tmap_nums);
2045 void remove_char( char * s, char c )
2052 #define REMOVE_EOL(s) remove_char((s),'\n')
2053 #define REMOVE_COMMENTS(s) remove_char((s),';')
2054 #define REMOVE_DOTS(s) remove_char((s),'.')
2055 char *space = { " \t" };
2056 char *equal_space = { " \t=" };
2058 // this function is at the same position in the d1 shareware piggy loading
2059 // algorithm as bm_load_sub in main/bmread.c
2060 int get_d1_bm_index(char *filename, CFILE *d1_pig) {
2062 DiskBitmapHeader bmh;
2063 if (strchr (filename, '.'))
2064 *strchr (filename, '.') = '\0'; // remove extension
2065 cfseek (d1_pig, 0, SEEK_SET);
2066 N_bitmaps = cfile_read_int (d1_pig);
2067 cfseek (d1_pig, 8, SEEK_SET);
2068 for (i = 1; i <= N_bitmaps; i++) {
2069 DiskBitmapHeader_d1_read(&bmh, d1_pig);
2070 if (!strnicmp(bmh.name, filename, 8))
2076 // imitate the algorithm of bm_init_use_tbl in main/bmread.c
2077 void read_d1_tmap_nums_from_hog(CFILE *d1_pig)
2079 #define LINEBUF_SIZE 600
2080 int reading_textures = 0;
2081 short texture_count = 0;
2082 char inputline[LINEBUF_SIZE];
2084 int bitmaps_tbl_is_binary = 0;
2087 bitmaps = cfopen ("bitmaps.tbl", "rb");
2089 bitmaps = cfopen ("bitmaps.bin", "rb");
2090 bitmaps_tbl_is_binary = 1;
2094 Warning ("Could not find bitmaps.* for reading d1 textures");
2098 free_d1_tmap_nums();
2099 MALLOC(d1_tmap_nums, short, D1_MAX_TMAP_NUM);
2100 for (i = 0; i < D1_MAX_TMAP_NUM; i++)
2101 d1_tmap_nums[i] = -1;
2102 atexit(free_d1_tmap_nums);
2104 while (cfgets (inputline, LINEBUF_SIZE, bitmaps)) {
2107 if (bitmaps_tbl_is_binary)
2108 decode_text_line((inputline));
2110 while (inputline[(i=strlen(inputline))-2]=='\\')
2111 cfgets(inputline+i-2,LINEBUF_SIZE-(i-2), bitmaps); // strip comments
2112 REMOVE_EOL(inputline);
2113 if (strchr(inputline, ';')!=NULL) REMOVE_COMMENTS(inputline);
2114 if (strlen(inputline) == LINEBUF_SIZE-1) {
2115 Warning("Possible line truncation in BITMAPS.TBL");
2118 arg = strtok( inputline, space );
2119 if (arg && arg[0] == '@') {
2121 //Registered_only = 1;
2124 while (arg != NULL) {
2126 reading_textures = 0; // default
2127 if (!strcmp(arg, "$TEXTURES")) // BM_TEXTURES
2128 reading_textures = 1;
2129 else if (! stricmp(arg, "$ECLIP") // BM_ECLIP
2130 || ! stricmp(arg, "$WCLIP")) // BM_WCLIP
2132 else // not a special token, must be a bitmap!
2133 if (reading_textures) {
2134 while (*arg == '\t' || *arg == ' ')
2135 arg++;//remove unwanted blanks
2138 if (d1_tmap_num_unique(texture_count)) {
2139 int d1_index = get_d1_bm_index(arg, d1_pig);
2140 if (d1_index >= 0 && d1_index < D1_MAX_TMAP_NUM) {
2141 d1_tmap_nums[d1_index] = texture_count;
2142 //int d2_index = d2_index_for_d1_index(d1_index);
2145 Assert (texture_count < D1_MAX_TEXTURES);
2149 arg = strtok (NULL, equal_space);
2155 /* If the given d1_index is the index of a bitmap we have to load
2156 * (because it is unique to descent 1), then returns the d2_index that
2157 * the given d1_index replaces.
2158 * Returns -1 if the given d1_index is not unique to descent 1.
2160 short d2_index_for_d1_index(short d1_index)
2162 Assert(d1_index >= 0 && d1_index < D1_MAX_TMAP_NUM);
2163 if (! d1_tmap_nums || d1_tmap_nums[d1_index] == -1
2164 || ! d1_tmap_num_unique(d1_tmap_nums[d1_index]))
2167 return Textures[convert_d1_tmap_num(d1_tmap_nums[d1_index])].index;
2170 #define D1_BITMAPS_SIZE 300000
2171 void load_d1_bitmap_replacements()
2173 CFILE * d1_Piggy_fp;
2174 DiskBitmapHeader bmh;
2175 int pig_data_start, bitmap_header_start, bitmap_data_start;
2177 short d1_index, d2_index;
2179 ubyte colormap[256];
2180 ubyte d1_palette[256*3];
2184 d1_Piggy_fp = cfopen( D1_PIGFILE, "rb" );
2186 #define D1_PIG_LOAD_FAILED "Failed loading " D1_PIGFILE
2188 Warning(D1_PIG_LOAD_FAILED);
2192 //first, free up data allocated for old bitmaps
2193 free_bitmap_replacements();
2195 if (get_d1_colormap( d1_palette, colormap ) != 0)
2196 Warning("Could not load descent 1 color palette");
2198 pigsize = cfilelength(d1_Piggy_fp);
2200 case D1_SHARE_BIG_PIGSIZE:
2201 case D1_SHARE_10_PIGSIZE:
2202 case D1_SHARE_PIGSIZE:
2203 case D1_10_BIG_PIGSIZE:
2206 // OK, now we need to read d1_tmap_nums by emulating d1's bm_init_use_tbl()
2207 read_d1_tmap_nums_from_hog(d1_Piggy_fp);
2210 Warning("Unknown size for " D1_PIGFILE);
2214 case D1_OEM_PIGSIZE:
2215 case D1_MAC_PIGSIZE:
2216 case D1_MAC_SHARE_PIGSIZE:
2217 pig_data_start = cfile_read_int(d1_Piggy_fp );
2218 bm_read_d1_tmap_nums(d1_Piggy_fp); //was: bm_read_all_d1(fp);
2219 //for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2223 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2224 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2226 int N_sounds = cfile_read_int(d1_Piggy_fp);
2227 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2228 + N_sounds * sizeof(DiskSoundHeader);
2229 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2230 bitmap_data_start = bitmap_header_start + header_size;
2233 MALLOC( Bitmap_replacement_data, ubyte, D1_BITMAPS_SIZE);
2234 if (!Bitmap_replacement_data) {
2235 Warning(D1_PIG_LOAD_FAILED);
2238 atexit(free_bitmap_replacements);
2240 next_bitmap = Bitmap_replacement_data;
2242 for (d1_index = 1; d1_index <= N_bitmaps; d1_index++ ) {
2243 d2_index = d2_index_for_d1_index(d1_index);
2244 // only change bitmaps which are unique to d1
2245 if (d2_index != -1) {
2246 cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2247 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2249 bitmap_read_d1( &GameBitmaps[d2_index], d1_Piggy_fp, bitmap_data_start, &bmh, &next_bitmap, d1_palette, colormap );
2250 Assert(next_bitmap - Bitmap_replacement_data < D1_BITMAPS_SIZE);
2251 GameBitmapOffset[d2_index] = 0; // don't try to read bitmap from current d2 pigfile
2252 GameBitmapFlags[d2_index] = bmh.flags;
2254 if ( (p = strchr(AllBitmaps[d2_index].name, '#')) /* d2 BM is animated */
2255 && !(bmh.dflags & DBM_FLAG_ABM) ) { /* d1 bitmap is not animated */
2256 int i, len = p - AllBitmaps[d2_index].name;
2257 for (i = 0; i < Num_bitmap_files; i++)
2258 if (i != d2_index && ! memcmp(AllBitmaps[d2_index].name, AllBitmaps[i].name, len))
2260 gr_set_bitmap_data(&GameBitmaps[i], NULL); // free ogl texture
2261 GameBitmaps[i] = GameBitmaps[d2_index];
2262 GameBitmapOffset[i] = 0;
2263 GameBitmapFlags[i] = bmh.flags;
2269 cfclose(d1_Piggy_fp);
2271 last_palette_loaded_pig[0]= 0; //force pig re-load
2273 texmerge_flush(); //for re-merging with new textures
2277 extern int extra_bitmap_num;
2280 * Find and load the named bitmap from descent.pig
2281 * similar to read_extra_bitmap_iff
2283 bitmap_index read_extra_bitmap_d1_pig(char *name)
2285 bitmap_index bitmap_num;
2286 grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2288 bitmap_num.index = 0;
2292 DiskBitmapHeader bmh;
2293 int pig_data_start, bitmap_header_start, bitmap_data_start;
2295 ubyte colormap[256];
2296 ubyte d1_palette[256*3];
2299 d1_Piggy_fp = cfopen(D1_PIGFILE, "rb");
2303 Warning(D1_PIG_LOAD_FAILED);
2307 if (get_d1_colormap( d1_palette, colormap ) != 0)
2308 Warning("Could not load descent 1 color palette");
2310 pigsize = cfilelength(d1_Piggy_fp);
2312 case D1_SHARE_BIG_PIGSIZE:
2313 case D1_SHARE_10_PIGSIZE:
2314 case D1_SHARE_PIGSIZE:
2315 case D1_10_BIG_PIGSIZE:
2320 Warning("Unknown size for " D1_PIGFILE);
2324 case D1_OEM_PIGSIZE:
2325 case D1_MAC_PIGSIZE:
2326 case D1_MAC_SHARE_PIGSIZE:
2327 pig_data_start = cfile_read_int(d1_Piggy_fp );
2332 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2333 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2335 int N_sounds = cfile_read_int(d1_Piggy_fp);
2336 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2337 + N_sounds * sizeof(DiskSoundHeader);
2338 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2339 bitmap_data_start = bitmap_header_start + header_size;
2342 for (i = 1; i <= N_bitmaps; i++)
2344 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2345 if (!strnicmp(bmh.name, name, 8))
2349 if (strnicmp(bmh.name, name, 8))
2351 con_printf(CON_DEBUG, "could not find bitmap %s\n", name);
2355 bitmap_read_d1( new, d1_Piggy_fp, bitmap_data_start, &bmh, 0, d1_palette, colormap );
2357 cfclose(d1_Piggy_fp);
2360 new->avg_color = 0; //compute_average_pixel(new);
2362 bitmap_num.index = extra_bitmap_num;
2364 GameBitmaps[extra_bitmap_num++] = *new;
2370 #ifndef FAST_FILE_IO
2372 * reads a bitmap_index structure from a CFILE
2374 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2376 bi->index = cfile_read_short(fp);
2380 * reads n bitmap_index structs from a CFILE
2382 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2386 for (i = 0; i < n; i++)
2387 bi[i].index = cfile_read_short(fp);
2390 #endif // FAST_FILE_IO