1 /* $Id: piggy.c,v 1.33 2003-08-02 18:14:08 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.
17 * Functions for managing the pig files.
20 * Revision 1.16 1995/11/09 17:27:47 allender
21 * put in missing quote on new gauge name
23 * Revision 1.15 1995/11/08 17:28:03 allender
24 * add PC gauges to gauge list of non-substitutatble bitmaps
26 * Revision 1.14 1995/11/08 15:14:49 allender
27 * fixed horrible bug where the piggy cache size was incorrect
30 * Revision 1.13 1995/11/03 12:53:37 allender
33 * Revision 1.12 1995/10/21 22:25:14 allender
34 * added bald guy cheat
36 * Revision 1.11 1995/10/20 22:42:15 allender
37 * changed load path of descent.pig to :data:descent.pig
39 * Revision 1.10 1995/10/20 00:08:01 allender
40 * put in event loop calls when loading data (hides it nicely
41 * from user) so TM can get it's strokes stuff
43 * Revision 1.9 1995/09/13 08:48:01 allender
44 * added lower memory requirement to load alternate bitmaps
46 * Revision 1.8 1995/08/16 09:39:13 allender
47 * moved "loading" text up a little
49 * Revision 1.7 1995/08/08 13:54:26 allender
50 * added macsys header file
52 * Revision 1.6 1995/07/12 12:49:56 allender
53 * total hack for bitmaps > 512 bytes wide -- check these by name
55 * Revision 1.5 1995/07/05 16:47:05 allender
58 * Revision 1.4 1995/06/23 08:55:28 allender
59 * make "loading data" text y loc based off of curcanv
61 * Revision 1.3 1995/06/08 14:08:52 allender
62 * PPC aligned data sets
64 * Revision 1.2 1995/05/26 06:54:27 allender
65 * removed refences to sound data at end of pig file (since they will
66 * now be Macintosh snd resources for effects
68 * Revision 1.1 1995/05/16 15:29:51 allender
71 * Revision 2.10 1995/10/07 13:17:26 john
72 * Made all bitmaps paged out by default.
74 * Revision 2.9 1995/04/14 14:05:24 john
75 * *** empty log message ***
77 * Revision 2.8 1995/04/12 13:39:37 john
78 * Fixed bug with -lowmem not working.
80 * Revision 2.7 1995/03/29 23:23:17 john
81 * Fixed major bug with sounds not building into pig right.
83 * Revision 2.6 1995/03/28 18:05:00 john
84 * Fixed it so you don't have to delete pig after changing bitmaps.tbl
86 * Revision 2.5 1995/03/16 23:13:06 john
87 * Fixed bug with piggy paging in bitmap not checking for disk
88 * error, hence bogifying textures if you pull the CD out.
90 * Revision 2.4 1995/03/14 16:22:27 john
91 * Added cdrom alternate directory stuff.
93 * Revision 2.3 1995/03/06 15:23:20 john
94 * New screen techniques.
96 * Revision 2.2 1995/02/27 13:13:40 john
97 * Removed floating point.
99 * Revision 2.1 1995/02/27 12:31:25 john
100 * Made work without editor.
102 * Revision 2.0 1995/02/27 11:28:02 john
103 * New version 2.0, which has no anonymous unions, builds with
104 * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
106 * Revision 1.85 1995/02/09 12:54:24 john
107 * Made paged out bitmaps have bm_data be a valid pointer
108 * instead of NULL, in case anyone accesses it.
110 * Revision 1.84 1995/02/09 12:50:59 john
111 * Bullet-proofed the piggy loading code.
113 * Revision 1.83 1995/02/07 17:08:51 john
114 * Added some error handling stuff instead of asserts.
116 * Revision 1.82 1995/02/03 17:06:48 john
117 * Changed sound stuff to allow low memory usage.
118 * Also, changed so that Sounds isn't an array of digi_sounds, it
119 * is a ubyte pointing into GameSounds, this way the digi.c code that
120 * locks sounds won't accidentally unlock a sound that is already playing, but
121 * since it's Sounds[soundno] is different, it would erroneously be unlocked.
123 * Revision 1.81 1995/02/02 21:56:39 matt
124 * Added data for new gauge bitmaps
126 * Revision 1.80 1995/02/01 23:31:57 john
127 * Took out loading bar.
129 * Revision 1.79 1995/01/28 15:13:18 allender
130 * bumped up Piggy_bitmap_cache_size
132 * Revision 1.78 1995/01/26 12:30:43 john
135 * Revision 1.77 1995/01/26 12:12:17 john
136 * Made buffer be big for bitmaps.
138 * Revision 1.76 1995/01/25 20:15:38 john
139 * Made editor allocate all mem.
141 * Revision 1.75 1995/01/25 14:52:56 john
142 * Made bitmap buffer be 1.5 MB.
144 * Revision 1.74 1995/01/22 16:03:19 mike
147 * Revision 1.73 1995/01/22 15:58:36 mike
150 * Revision 1.72 1995/01/18 20:51:20 john
153 * Revision 1.71 1995/01/18 20:47:21 john
154 * Added code to allocate sounds & bitmaps into diff
155 * buffers, also made sounds not be compressed for registered.
157 * Revision 1.70 1995/01/18 15:08:41 john
158 * Added start/stop time around paging.
159 * Made paging clear screen around globe.
161 * Revision 1.69 1995/01/18 10:07:51 john
163 * Took out debugging mprintfs.
165 * Revision 1.68 1995/01/17 14:27:42 john
168 * Revision 1.67 1995/01/17 12:14:39 john
169 * Made walls, object explosion vclips load at level start.
171 * Revision 1.66 1995/01/15 13:15:44 john
172 * Made so that paging always happens, lowmem just loads less.
173 * Also, make KB load print to hud.
175 * Revision 1.65 1995/01/15 11:56:28 john
176 * Working version of paging.
178 * Revision 1.64 1995/01/14 19:17:07 john
179 * First version of new bitmap paging code.
181 * Revision 1.63 1994/12/15 12:26:44 john
182 * Added -nolowmem function.
184 * Revision 1.62 1994/12/14 21:12:26 john
185 * Fixed bug with page fault when exiting and using
188 * Revision 1.61 1994/12/14 11:35:31 john
189 * Evened out thermometer for pig read.
191 * Revision 1.60 1994/12/14 10:51:00 john
192 * Sped up sound loading.
194 * Revision 1.59 1994/12/14 10:12:08 john
195 * Sped up pig loading.
197 * Revision 1.58 1994/12/13 09:14:47 john
198 * *** empty log message ***
200 * Revision 1.57 1994/12/13 09:12:57 john
201 * Made the bar always fill up.
203 * Revision 1.56 1994/12/13 03:49:08 john
204 * Made -lowmem not load the unnecessary bitmaps.
206 * Revision 1.55 1994/12/06 16:06:35 john
207 * Took out piggy sorting.
209 * Revision 1.54 1994/12/06 15:11:14 john
210 * Fixed bug with reading pigs.
212 * Revision 1.53 1994/12/06 14:14:47 john
213 * Added code to set low mem based on memory.
215 * Revision 1.52 1994/12/06 14:01:10 john
216 * Fixed bug that was causing -lowmem all the time..
218 * Revision 1.51 1994/12/06 13:33:48 john
219 * Added lowmem option.
221 * Revision 1.50 1994/12/05 19:40:10 john
222 * If -nosound or no sound card selected, don't load sounds from pig.
224 * Revision 1.49 1994/12/05 12:17:44 john
225 * Added code that locks/unlocks digital sounds on demand.
227 * Revision 1.48 1994/12/05 11:39:03 matt
228 * Fixed little mistake
230 * Revision 1.47 1994/12/05 09:29:22 john
231 * Added clength to the sound field.
233 * Revision 1.46 1994/12/04 15:27:15 john
234 * Fixed my stupid bug that looked at -nosound instead of digi_driver_card
235 * to see whether or not to lock down sound memory.
237 * Revision 1.45 1994/12/03 14:17:00 john
238 * Took out my debug mprintf.
240 * Revision 1.44 1994/12/03 13:32:37 john
241 * Fixed bug with offscreen bitmap.
243 * Revision 1.43 1994/12/03 13:07:13 john
244 * Made the pig read/write compressed sounds.
246 * Revision 1.42 1994/12/03 11:48:51 matt
247 * Added option to not dump sounds to pigfile
249 * Revision 1.41 1994/12/02 20:02:20 matt
250 * Made sound files constant match constant for table
252 * Revision 1.40 1994/11/29 11:03:09 adam
255 * Revision 1.39 1994/11/27 23:13:51 matt
256 * Made changes for new mprintf calling convention
258 * Revision 1.38 1994/11/20 18:40:34 john
259 * MAde the piggy.lst and piggy.all not dump for release.
261 * Revision 1.37 1994/11/19 23:54:45 mike
262 * up number of bitmaps for shareware version.
264 * Revision 1.36 1994/11/19 19:53:05 mike
265 * change MAX_BITMAP_FILES
267 * Revision 1.35 1994/11/19 10:42:56 matt
268 * Increased number of bitmaps for non-shareware version
270 * Revision 1.34 1994/11/19 09:11:52 john
271 * Added avg_color to bitmaps saved in pig.
273 * Revision 1.33 1994/11/19 00:07:05 john
274 * Fixed bug with 8 char sound filenames not getting read from pig.
276 * Revision 1.32 1994/11/18 22:24:54 john
277 * Added -bigpig command line that doesn't rle your pig.
279 * Revision 1.31 1994/11/18 21:56:53 john
280 * Added a better, leaner pig format.
282 * Revision 1.30 1994/11/16 12:06:16 john
283 * Fixed bug with calling .bbms abms.
285 * Revision 1.29 1994/11/16 12:00:56 john
286 * Added piggy.all dump.
288 * Revision 1.28 1994/11/10 21:16:02 adam
291 * Revision 1.27 1994/11/10 13:42:00 john
292 * Made sounds not lock down if using -nosound.
294 * Revision 1.26 1994/11/09 19:55:40 john
295 * Added full rle support with texture rle caching.
297 * Revision 1.25 1994/11/09 16:36:42 john
298 * First version with RLE bitmaps in Pig.
300 * Revision 1.24 1994/10/27 19:42:59 john
301 * Disable the piglet option.
303 * Revision 1.23 1994/10/27 18:51:40 john
304 * Added -piglet option that only loads needed textures for a
305 * mine. Only saved ~1MB, and code still doesn't free textures
306 * before you load a new mine.
308 * Revision 1.22 1994/10/25 13:11:42 john
309 * Made the sounds sort. Dumped piggy.lst.
311 * Revision 1.21 1994/10/06 17:06:23 john
312 * Took out rle stuff.
314 * Revision 1.20 1994/10/06 15:45:36 adam
315 * bumped MAX_BITMAP_FILES again!
317 * Revision 1.19 1994/10/06 11:01:17 yuan
318 * Upped MAX_BITMAP_FILES
320 * Revision 1.18 1994/10/06 10:44:45 john
321 * Added diagnostic message and psuedo run-length-encoder
322 * to see how much memory we would save by storing bitmaps
323 * in a RLE method. Also, I commented out the code that
324 * stores 4K bitmaps on a 4K boundry to reduce pig size
327 * Revision 1.17 1994/10/04 20:03:13 matt
328 * Upped maximum number of bitmaps
330 * Revision 1.16 1994/10/03 18:04:20 john
331 * Fixed bug with data_offset not set right for bitmaps
332 * that are 64x64 and not aligned on a 4k boundry.
334 * Revision 1.15 1994/09/28 11:30:55 john
335 * changed inferno.pig to descent.pig, changed the way it
338 * Revision 1.14 1994/09/22 16:14:17 john
339 * Redid intro sequecing.
341 * Revision 1.13 1994/09/19 14:42:47 john
342 * Locked down sounds with Virtual memory.
344 * Revision 1.12 1994/09/10 17:31:52 mike
345 * Increase number of loadable bitmaps.
347 * Revision 1.11 1994/09/01 19:32:49 mike
348 * Boost texture map allocation.
350 * Revision 1.10 1994/08/16 11:51:02 john
351 * Added grwased pigs.
353 * Revision 1.9 1994/07/06 09:18:03 adam
356 * Revision 1.8 1994/06/20 22:02:15 matt
357 * Fixed bug from last change
359 * Revision 1.7 1994/06/20 21:33:18 matt
360 * Made bm.h not include sounds.h, to reduce dependencies
362 * Revision 1.6 1994/06/20 16:52:19 john
363 * cleaned up init output a bit.
365 * Revision 1.5 1994/06/08 14:20:57 john
366 * Made piggy dump before going into game.
368 * Revision 1.4 1994/06/02 18:59:22 matt
369 * Clear selector field of bitmap loaded from pig file
371 * Revision 1.3 1994/05/06 15:31:41 john
372 * Made name field a bit longer.
374 * Revision 1.2 1994/05/06 13:02:44 john
375 * Added piggy stuff; worked on supertransparency
377 * Revision 1.1 1994/05/06 11:47:26 john
389 static char rcsid[] = "$Id: piggy.c,v 1.33 2003-08-02 18:14:08 btb Exp $";
411 #include "gamefont.h"
415 #include "texmerge.h"
421 #include "byteswap.h"
422 #include "findfile.h"
426 // #include "unarj.h"
428 #include <Strings.h> // MacOS Toolbox header
433 //#define NO_DUMP_SOUNDS 1 //if set, dump bitmaps but not sounds
435 #define DEFAULT_PIGFILE_REGISTERED "groupa.pig"
436 #define DEFAULT_PIGFILE_SHAREWARE "d2demo.pig"
437 #define DEFAULT_HAMFILE_REGISTERED "descent2.ham"
438 #define DEFAULT_HAMFILE_SHAREWARE "d2demo.ham"
440 #define D1_PALETTE "palette.256"
442 #define DEFAULT_PIGFILE (cfexist(DEFAULT_PIGFILE_REGISTERED)?DEFAULT_PIGFILE_REGISTERED:DEFAULT_PIGFILE_SHAREWARE)
443 #define DEFAULT_HAMFILE (cfexist(DEFAULT_HAMFILE_REGISTERED)?DEFAULT_HAMFILE_REGISTERED:DEFAULT_HAMFILE_SHAREWARE)
444 #define DEFAULT_SNDFILE ((Piggy_hamfile_version < 3)?DEFAULT_HAMFILE_SHAREWARE:(digi_sample_rate==SAMPLE_RATE_22K)?"descent2.s22":"descent2.s11")
446 #define MAC_ALIEN1_PIGSIZE 5013035
447 #define MAC_ALIEN2_PIGSIZE 4909916
448 #define MAC_FIRE_PIGSIZE 4969035
449 #define MAC_GROUPA_PIGSIZE 4929684 // also used for mac shareware
450 #define MAC_ICE_PIGSIZE 4923425
451 #define MAC_WATER_PIGSIZE 4832403
453 ubyte *BitmapBits = NULL;
454 ubyte *SoundBits = NULL;
456 typedef struct BitmapFile {
460 typedef struct SoundFile {
464 hashtable AllBitmapsNames;
465 hashtable AllDigiSndNames;
467 int Num_bitmap_files = 0;
468 int Num_sound_files = 0;
470 digi_sound GameSounds[MAX_SOUND_FILES];
471 int SoundOffset[MAX_SOUND_FILES];
472 grs_bitmap GameBitmaps[MAX_BITMAP_FILES];
474 alias alias_list[MAX_ALIASES];
477 int Must_write_hamfile = 0;
478 int Num_bitmap_files_new = 0;
479 int Num_sound_files_new = 0;
480 BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
481 static SoundFile AllSounds[ MAX_SOUND_FILES ];
483 int Piggy_hamfile_version = 0;
485 int piggy_low_memory = 0;
487 int Piggy_bitmap_cache_size = 0;
488 int Piggy_bitmap_cache_next = 0;
489 ubyte * Piggy_bitmap_cache_data = NULL;
490 static int GameBitmapOffset[MAX_BITMAP_FILES];
491 static ubyte GameBitmapFlags[MAX_BITMAP_FILES];
492 ushort GameBitmapXlat[MAX_BITMAP_FILES];
494 #define PIGGY_BUFFER_SIZE (2400*1024)
497 #define PIGGY_SMALL_BUFFER_SIZE (1400*1024) // size of buffer when piggy_low_memory is set
500 #undef PIGGY_BUFFER_SIZE
501 #undef PIGGY_SMALL_BUFFER_SIZE
503 #define PIGGY_BUFFER_SIZE (2000*1024)
504 #define PIGGY_SMALL_BUFFER_SIZE (1100 * 1024)
509 int piggy_page_flushed = 0;
511 #define DBM_FLAG_ABM 64
513 #define BM_FLAGS_TO_COPY (BM_FLAG_TRANSPARENT | BM_FLAG_SUPER_TRANSPARENT \
514 | BM_FLAG_NO_LIGHTING | BM_FLAG_RLE | BM_FLAG_RLE_BIG)
519 extern short cd_VRefNum;
520 extern void ConcatPStr(StringPtr dst, StringPtr src);
521 extern int ConvertPToCStr(StringPtr inPStr, char* outCStrBuf);
522 extern int ConvertCToPStr(char* inCStr, StringPtr outPStrBuf);
525 int piggy_is_substitutable_bitmap( char * name, char * subst_name );
528 void piggy_write_pigfile(char *filename);
529 static void write_int(int i,FILE *file);
532 void swap_0_255(grs_bitmap *bmp)
536 for (i = 0; i < bmp->bm_h * bmp->bm_w; i++) {
537 if(bmp->bm_data[i] == 0)
538 bmp->bm_data[i] = 255;
539 else if (bmp->bm_data[i] == 255)
544 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
547 Assert( Num_bitmap_files < MAX_BITMAP_FILES );
549 temp.index = Num_bitmap_files;
553 if ( FindArg("-macdata") )
556 if ( !BigPig ) gr_bitmap_rle_compress( bmp );
557 Num_bitmap_files_new++;
560 strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
561 hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
562 GameBitmaps[Num_bitmap_files] = *bmp;
564 GameBitmapOffset[Num_bitmap_files] = 0;
565 GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
572 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
576 Assert( Num_sound_files < MAX_SOUND_FILES );
578 strncpy( AllSounds[Num_sound_files].name, name, 12 );
579 hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
580 GameSounds[Num_sound_files] = *snd;
582 SoundOffset[Num_sound_files] = 0;
588 Num_sound_files_new++;
594 bitmap_index piggy_find_bitmap( char * name )
602 if ((t=strchr(name,'#'))!=NULL)
605 for (i=0;i<Num_aliases;i++)
606 if (stricmp(name,alias_list[i].alias_name)==0) {
607 if (t) { //extra stuff for ABMs
608 static char temp[FILENAME_LEN];
609 _splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
615 name=alias_list[i].file_name;
622 i = hashtable_search( &AllBitmapsNames, name );
631 int piggy_find_sound( char * name )
635 i = hashtable_search( &AllDigiSndNames, name );
643 CFILE * Piggy_fp = NULL;
645 #define FILENAME_LEN 13
647 char Current_pigfile[FILENAME_LEN] = "";
649 void piggy_close_file()
654 Current_pigfile[0] = 0;
658 int Pigfile_initialized=0;
660 #define PIGFILE_ID MAKE_SIG('G','I','P','P') //PPIG
661 #define PIGFILE_VERSION 2
663 extern char CDROM_dir[];
665 int request_cd(void);
670 //copies a pigfile from the CD to the current dir
671 //retuns file handle of new pig
672 CFILE *copy_pigfile_from_cd(char *filename) // MACINTOSH VERSION
675 char sourcePathAndFileCStr[255] = "";
676 char destPathAndFileCStr[255] = "";
678 FILE* sourceFile = NULL;
679 FILE* destFile = NULL;
680 const int BUF_SIZE = 4096;
684 Str255 sourcePathAndFilePStr = "\p";
685 Str255 destPathAndFilePStr = "\p";
686 Str255 pigfileNamePStr = "\p";
687 HParamBlockRec theSourcePigHFSParams;
688 HParamBlockRec theDestPigHFSParams;
689 OSErr theErr = noErr;
690 char oldDirCStr[255] = "";
692 getcwd(oldDirCStr, 255);
694 show_boxed_message("Copying bitmap data from CD...");
695 gr_palette_load(gr_palette); //I don't think this line is really needed
698 //First, delete all PIG files currently in the directory
699 if( !FileFindFirst( "*.pig", &find ) )
704 } while( !FileFindNext( &find ) );
710 //Now, copy over new pig
711 songs_stop_redbook(); //so we can read off the cd
713 // make the source path "<cd volume>:Data:filename.pig"
714 //MWA ConvertCToPStr(filename, pigfileNamePStr);
716 //MWA ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:"); // volume ID is cd_VRefNum
717 //MWA ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
720 strcpy(sourcePathAndFileCStr, "Descent II:Data:");
721 strcat(sourcePathAndFileCStr, filename);
723 // make the destination path "<default directory>:Data:filename.pig"
724 //MWA ConcatPStr(destPathAndFilePStr, "\p:Data:");
725 //MWA ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
726 //MWA ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
727 //MWA ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
729 strcpy(destPathAndFileCStr, ":Data:");
730 strcat(destPathAndFileCStr, filename);
732 strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
733 strcpy(destPathAndFilePStr, destPathAndFileCStr);
734 c2pstr(sourcePathAndFilePStr);
735 c2pstr(destPathAndFilePStr);
738 // Open the source file
739 sourceFile = fopen(sourcePathAndFileCStr,"rb");
743 if (request_cd() == -1)
744 Error("Cannot load file <%s> from CD",filename);
747 } while (!sourceFile);
750 // Get the time stamp from the source file
751 theSourcePigHFSParams.fileParam.ioCompletion = nil;
752 theSourcePigHFSParams.fileParam.ioNamePtr = sourcePathAndFilePStr;
753 theSourcePigHFSParams.fileParam.ioVRefNum = cd_VRefNum;
754 theSourcePigHFSParams.fileParam.ioFDirIndex = 0;
755 theSourcePigHFSParams.fileParam.ioDirID = 0;
757 theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
760 // Error getting file time stamp!! Why? JTS
761 Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
764 // Copy the file over
767 // Open the destination file
768 destFile = fopen(destPathAndFileCStr,"wb");
771 Error("Cannot create file: <%s>\n", destPathAndFileCStr);
774 // Copy bytes until the end of the source file
775 while (!feof(sourceFile))
780 bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
781 if (ferror(sourceFile))
782 Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
784 // Assert is bogus Assert(bytes_read == BUF_SIZE || feof(sourceFile));
786 fwrite(buf,1,bytes_read,destFile);
787 if (ferror(destFile))
788 Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
791 // close the source/dest files
792 if (fclose(sourceFile))
793 Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
794 if (fclose(destFile))
795 Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
797 // Get the current hfs data for the new file
798 theDestPigHFSParams.fileParam.ioCompletion = nil;
799 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
800 theDestPigHFSParams.fileParam.ioVRefNum = 0;
801 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
802 theDestPigHFSParams.fileParam.ioDirID = 0;
803 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
804 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
806 // Error getting file time stamp!! Why? JTS
807 Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
810 // Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
811 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
812 theDestPigHFSParams.fileParam.ioVRefNum = 0;
813 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
814 theDestPigHFSParams.fileParam.ioDirID = 0;
816 // Copy the time stamp from the source file info
817 theDestPigHFSParams.fileParam.ioFlCrDat = theSourcePigHFSParams.fileParam.ioFlCrDat;
818 theDestPigHFSParams.fileParam.ioFlMdDat = theSourcePigHFSParams.fileParam.ioFlMdDat;
819 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
820 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
822 // Set the dest file's time stamp to the source file's time stamp values
823 theErr = PBHSetFInfo(&theDestPigHFSParams, false);
825 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
827 Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
830 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
832 return cfopen(destPathAndFileCStr, "rb");
835 #else //PC Version of copy_pigfile_from_cd is below
837 //copies a pigfile from the CD to the current dir
838 //retuns file handle of new pig
839 CFILE *copy_pigfile_from_cd(char *filename)
845 return cfopen(filename, "rb");
846 show_boxed_message("Copying bitmap data from CD...");
847 gr_palette_load(gr_palette); //I don't think this line is really needed
849 //First, delete all PIG files currently in the directory
851 if( !FileFindFirst( "*.pig", &find ) ) {
853 cfile_delete(find.name);
854 } while( !FileFindNext( &find ) );
858 //Now, copy over new pig
860 songs_stop_redbook(); //so we can read off the cd
862 //new code to unarj file
863 strcpy(name,CDROM_dir);
864 strcat(name,"descent2.sow");
867 // ret = unarj_specific_file(name,filename,filename);
872 if (ret != EXIT_SUCCESS) {
874 //delete file, so we don't leave partial file
875 cfile_delete(filename);
878 if (request_cd() == -1)
880 //NOTE LINK TO ABOVE IF
881 Error("Cannot load file <%s> from CD",filename);
884 } while (ret != EXIT_SUCCESS);
886 return cfopen(filename, "rb");
889 #endif // end of ifdef MAC around copy_pigfile_from_cd
891 //initialize a pigfile, reading headers
892 //returns the size of all the bitmap data
893 void piggy_init_pigfile(char *filename)
897 char temp_name_read[16];
898 grs_bitmap temp_bitmap;
899 DiskBitmapHeader bmh;
900 int header_size, N_bitmaps, data_size, data_start;
902 char name[255]; // filename + path for the mac
905 piggy_close_file(); //close old pig if still open
907 //rename pigfile for shareware
908 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
909 filename = DEFAULT_PIGFILE_SHAREWARE;
912 Piggy_fp = cfopen( filename, "rb" );
914 sprintf(name, ":Data:%s", filename);
915 Piggy_fp = cfopen( name, "rb" );
917 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
918 if (Piggy_fp == NULL)
920 Error("Cannot load required file <%s>",name);
922 #endif // end of if def shareware
928 return; //if editor, ok to not have pig, because we'll build one
930 Piggy_fp = copy_pigfile_from_cd(filename);
934 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
935 int pig_id,pig_version;
937 pig_id = cfile_read_int(Piggy_fp);
938 pig_version = cfile_read_int(Piggy_fp);
939 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
940 cfclose(Piggy_fp); //out of date pig
941 Piggy_fp = NULL; //..so pretend it's not here
948 return; //if editor, ok to not have pig, because we'll build one
950 Error("Cannot load required file <%s>",filename);
954 strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
956 N_bitmaps = cfile_read_int(Piggy_fp);
958 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
960 data_start = header_size + cftell(Piggy_fp);
962 data_size = cfilelength(Piggy_fp) - data_start;
964 Num_bitmap_files = 1;
966 for (i=0; i<N_bitmaps; i++ ) {
967 DiskBitmapHeader_read(&bmh, Piggy_fp);
968 memcpy( temp_name_read, bmh.name, 8 );
969 temp_name_read[8] = 0;
970 if ( bmh.dflags & DBM_FLAG_ABM )
971 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
973 strcpy( temp_name, temp_name_read );
974 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
975 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
976 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
977 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
978 temp_bitmap.avg_color = bmh.avg_color;
979 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
981 GameBitmapFlags[i+1] = bmh.flags & BM_FLAGS_TO_COPY;
983 GameBitmapOffset[i+1] = bmh.offset + data_start;
984 Assert( (i+1) == Num_bitmap_files );
985 piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
989 Piggy_bitmap_cache_size = data_size + (data_size/10); //extra mem for new bitmaps
990 Assert( Piggy_bitmap_cache_size > 0 );
992 Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
994 if (piggy_low_memory)
995 Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
998 BitmapBits = d_malloc( Piggy_bitmap_cache_size );
999 if ( BitmapBits == NULL )
1000 Error( "Not enough memory to load bitmaps\n" );
1001 Piggy_bitmap_cache_data = BitmapBits;
1002 Piggy_bitmap_cache_next = 0;
1004 #if defined(MACINTOSH) && defined(SHAREWARE)
1005 // load_exit_models();
1008 Pigfile_initialized=1;
1011 #define FILENAME_LEN 13
1012 #define MAX_BITMAPS_PER_BRUSH 30
1014 extern int compute_average_pixel(grs_bitmap *new);
1016 //reads in a new pigfile (for new palette)
1017 //returns the size of all the bitmap data
1018 void piggy_new_pigfile(char *pigname)
1022 char temp_name_read[16];
1023 grs_bitmap temp_bitmap;
1024 DiskBitmapHeader bmh;
1025 int header_size, N_bitmaps, data_size, data_start;
1026 int must_rewrite_pig = 0;
1033 //rename pigfile for shareware
1034 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
1035 pigname = DEFAULT_PIGFILE_SHAREWARE;
1037 if (strnicmp(Current_pigfile,pigname,sizeof(Current_pigfile))==0)
1038 return; //already have correct pig
1040 if (!Pigfile_initialized) { //have we ever opened a pigfile?
1041 piggy_init_pigfile(pigname); //..no, so do initialization stuff
1045 piggy_close_file(); //close old pig if still open
1047 Piggy_bitmap_cache_next = 0; //free up cache
1049 strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
1052 Piggy_fp = cfopen( pigname, "rb" );
1054 sprintf(name, ":Data:%s", pigname);
1055 Piggy_fp = cfopen( name, "rb" );
1057 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
1058 if (Piggy_fp == NULL)
1060 Error("Cannot load required file <%s>",name);
1062 #endif // end of if def shareware
1067 Piggy_fp = copy_pigfile_from_cd(pigname);
1070 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1071 int pig_id,pig_version;
1073 pig_id = cfile_read_int(Piggy_fp);
1074 pig_version = cfile_read_int(Piggy_fp);
1075 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1076 cfclose(Piggy_fp); //out of date pig
1077 Piggy_fp = NULL; //..so pretend it's not here
1082 if (!Piggy_fp) Error ("Piggy_fp not defined in piggy_new_pigfile.");
1087 N_bitmaps = cfile_read_int(Piggy_fp);
1089 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
1091 data_start = header_size + cftell(Piggy_fp);
1093 data_size = cfilelength(Piggy_fp) - data_start;
1095 for (i=1; i<=N_bitmaps; i++ ) {
1096 DiskBitmapHeader_read(&bmh, Piggy_fp);
1097 memcpy( temp_name_read, bmh.name, 8 );
1098 temp_name_read[8] = 0;
1100 if ( bmh.dflags & DBM_FLAG_ABM )
1101 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
1103 strcpy( temp_name, temp_name_read );
1105 //Make sure name matches
1106 if (strcmp(temp_name,AllBitmaps[i].name)) {
1107 //Int3(); //this pig is out of date. Delete it
1111 strcpy(AllBitmaps[i].name,temp_name);
1113 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1115 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1116 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1117 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1118 temp_bitmap.avg_color = bmh.avg_color;
1119 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1121 GameBitmapFlags[i] = bmh.flags & BM_FLAGS_TO_COPY;
1123 GameBitmapOffset[i] = bmh.offset + data_start;
1125 GameBitmaps[i] = temp_bitmap;
1129 N_bitmaps = 0; //no pigfile, so no bitmaps
1133 Assert(N_bitmaps == Num_bitmap_files-1);
1137 if (must_rewrite_pig || (N_bitmaps < Num_bitmap_files-1)) {
1140 //re-read the bitmaps that aren't in this pig
1142 for (i=N_bitmaps+1;i<Num_bitmap_files;i++) {
1145 p = strchr(AllBitmaps[i].name,'#');
1147 if (p) { //this is an ABM
1148 char abmname[FILENAME_LEN];
1150 grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
1151 int iff_error; //reference parm to avoid warning message
1153 char basename[FILENAME_LEN];
1156 strcpy(basename,AllBitmaps[i].name);
1157 basename[p-AllBitmaps[i].name] = 0; //cut off "#nn" part
1159 sprintf( abmname, "%s.abm", basename );
1161 iff_error = iff_read_animbrush(abmname,bm,MAX_BITMAPS_PER_BRUSH,&nframes,newpal);
1163 if (iff_error != IFF_NO_ERROR) {
1164 mprintf((1,"File %s - IFF error: %s",abmname,iff_errormsg(iff_error)));
1165 Error("File %s - IFF error: %s",abmname,iff_errormsg(iff_error));
1168 for (fnum=0;fnum<nframes; fnum++) {
1172 sprintf( tempname, "%s#%d", basename, fnum );
1174 //SuperX = (GameBitmaps[i+fnum].bm_flags&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1175 SuperX = (GameBitmapFlags[i+fnum]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1176 //above makes assumption that supertransparent color is 254
1178 if ( iff_has_transparency )
1179 gr_remap_bitmap_good( bm[fnum], newpal, iff_transparent_color, SuperX );
1181 gr_remap_bitmap_good( bm[fnum], newpal, -1, SuperX );
1183 bm[fnum]->avg_color = compute_average_pixel(bm[fnum]);
1186 if ( FindArg("-macdata") )
1187 swap_0_255( bm[fnum] );
1189 if ( !BigPig ) gr_bitmap_rle_compress( bm[fnum] );
1191 if (bm[fnum]->bm_flags & BM_FLAG_RLE)
1192 size = *((int *) bm[fnum]->bm_data);
1194 size = bm[fnum]->bm_w * bm[fnum]->bm_h;
1196 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],bm[fnum]->bm_data,size);
1197 d_free(bm[fnum]->bm_data);
1198 bm[fnum]->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1199 Piggy_bitmap_cache_next += size;
1201 GameBitmaps[i+fnum] = *bm[fnum];
1203 // -- mprintf( (0, "U" ));
1207 i += nframes-1; //filled in multiple bitmaps
1209 else { //this is a BBM
1212 ubyte newpal[256*3];
1214 char bbmname[FILENAME_LEN];
1217 MALLOC( new, grs_bitmap, 1 );
1219 sprintf( bbmname, "%s.bbm", AllBitmaps[i].name );
1220 iff_error = iff_read_bitmap(bbmname,new,BM_LINEAR,newpal);
1223 if (iff_error != IFF_NO_ERROR) {
1224 mprintf((1, "File %s - IFF error: %s",bbmname,iff_errormsg(iff_error)));
1225 Error("File %s - IFF error: %s",bbmname,iff_errormsg(iff_error));
1228 SuperX = (GameBitmapFlags[i]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1229 //above makes assumption that supertransparent color is 254
1231 if ( iff_has_transparency )
1232 gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
1234 gr_remap_bitmap_good( new, newpal, -1, SuperX );
1236 new->avg_color = compute_average_pixel(new);
1239 if ( FindArg("-macdata") )
1242 if ( !BigPig ) gr_bitmap_rle_compress( new );
1244 if (new->bm_flags & BM_FLAG_RLE)
1245 size = *((int *) new->bm_data);
1247 size = new->bm_w * new->bm_h;
1249 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],new->bm_data,size);
1250 d_free(new->bm_data);
1251 new->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1252 Piggy_bitmap_cache_next += size;
1254 GameBitmaps[i] = *new;
1258 // -- mprintf( (0, "U" ));
1262 //@@Dont' do these things which are done when writing
1263 //@@for (i=0; i < Num_bitmap_files; i++ ) {
1264 //@@ bitmap_index bi;
1266 //@@ PIGGY_PAGE_IN( bi );
1269 //@@piggy_close_file();
1271 piggy_write_pigfile(pigname);
1273 Current_pigfile[0] = 0; //say no pig, to force reload
1275 piggy_new_pigfile(pigname); //read in just-generated pig
1279 #endif //ifdef EDITOR
1283 ubyte bogus_data[64*64];
1284 grs_bitmap bogus_bitmap;
1285 ubyte bogus_bitmap_initialized=0;
1286 digi_sound bogus_sound;
1288 #define HAMFILE_ID MAKE_SIG('!','M','A','H') //HAM!
1289 #define HAMFILE_VERSION 3
1290 //version 1 -> 2: save marker_model_num
1291 //version 2 -> 3: removed sound files
1293 #define SNDFILE_ID MAKE_SIG('D','N','S','D') //DSND
1294 #define SNDFILE_VERSION 1
1298 CFILE * ham_fp = NULL;
1300 int sound_offset = 0;
1306 ham_fp = cfopen( DEFAULT_HAMFILE, "rb" );
1308 sprintf(name, ":Data:%s", DEFAULT_HAMFILE );
1309 ham_fp = cfopen( name, "rb" );
1312 if (ham_fp == NULL) {
1313 Must_write_hamfile = 1;
1317 //make sure ham is valid type file & is up-to-date
1318 ham_id = cfile_read_int(ham_fp);
1319 Piggy_hamfile_version = cfile_read_int(ham_fp);
1320 if (ham_id != HAMFILE_ID)
1321 Error("Cannot open ham file %s\n", DEFAULT_HAMFILE);
1323 if (ham_id != HAMFILE_ID || Piggy_hamfile_version != HAMFILE_VERSION) {
1324 Must_write_hamfile = 1;
1325 cfclose(ham_fp); //out of date ham
1330 if (Piggy_hamfile_version < 3) // hamfile contains sound info
1331 sound_offset = cfile_read_int(ham_fp);
1337 bm_read_all(ham_fp);
1338 cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1340 //for (i = 0; i < MAX_BITMAP_FILES; i++) {
1341 //GameBitmapXlat[i] = INTEL_SHORT(GameBitmapXlat[i]);
1342 //printf("GameBitmapXlat[%d] = %d\n", i, GameBitmapXlat[i]);
1347 if (Piggy_hamfile_version < 3) {
1352 DiskSoundHeader sndh;
1353 digi_sound temp_sound;
1354 char temp_name_read[16];
1357 cfseek(ham_fp, sound_offset, SEEK_SET);
1358 N_sounds = cfile_read_int(ham_fp);
1360 sound_start = cftell(ham_fp);
1362 header_size = N_sounds * DISKSOUNDHEADER_SIZE;
1366 for (i=0; i<N_sounds; i++ ) {
1367 DiskSoundHeader_read(&sndh, ham_fp);
1368 temp_sound.length = sndh.length;
1369 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1370 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1371 memcpy( temp_name_read, sndh.name, 8 );
1372 temp_name_read[8] = 0;
1373 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1375 if (piggy_is_needed(i))
1376 #endif // note link to if.
1377 sbytes += sndh.length;
1378 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1381 SoundBits = d_malloc( sbytes + 16 );
1382 if ( SoundBits == NULL )
1383 Error( "Not enough memory to load sounds\n" );
1385 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1387 // piggy_read_sounds(ham_fp);
1399 CFILE * snd_fp = NULL;
1400 int snd_id,snd_version;
1405 DiskSoundHeader sndh;
1406 digi_sound temp_sound;
1407 char temp_name_read[16];
1414 snd_fp = cfopen( DEFAULT_SNDFILE, "rb" );
1416 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1417 snd_fp = cfopen( name, "rb");
1423 //make sure soundfile is valid type file & is up-to-date
1424 snd_id = cfile_read_int(snd_fp);
1425 snd_version = cfile_read_int(snd_fp);
1426 if (snd_id != SNDFILE_ID || snd_version != SNDFILE_VERSION) {
1427 cfclose(snd_fp); //out of date sound file
1431 N_sounds = cfile_read_int(snd_fp);
1433 sound_start = cftell(snd_fp);
1434 size = cfilelength(snd_fp) - sound_start;
1436 mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
1438 header_size = N_sounds*sizeof(DiskSoundHeader);
1442 for (i=0; i<N_sounds; i++ ) {
1443 DiskSoundHeader_read(&sndh, snd_fp);
1444 //size -= sizeof(DiskSoundHeader);
1445 temp_sound.length = sndh.length;
1446 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1447 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1448 memcpy( temp_name_read, sndh.name, 8 );
1449 temp_name_read[8] = 0;
1450 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1452 if (piggy_is_needed(i))
1453 #endif // note link to if.
1454 sbytes += sndh.length;
1455 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1458 SoundBits = d_malloc( sbytes + 16 );
1459 if ( SoundBits == NULL )
1460 Error( "Not enough memory to load sounds\n" );
1462 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1464 // piggy_read_sounds(snd_fp);
1471 int piggy_init(void)
1473 int ham_ok=0,snd_ok=0;
1476 hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
1477 hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
1479 for (i=0; i<MAX_SOUND_FILES; i++ ) {
1480 GameSounds[i].length = 0;
1481 GameSounds[i].data = NULL;
1485 for (i=0; i<MAX_BITMAP_FILES; i++ )
1486 GameBitmapXlat[i] = i;
1488 if ( !bogus_bitmap_initialized ) {
1491 bogus_bitmap_initialized = 1;
1492 memset( &bogus_bitmap, 0, sizeof(grs_bitmap) );
1493 bogus_bitmap.bm_w = bogus_bitmap.bm_h = bogus_bitmap.bm_rowsize = 64;
1494 bogus_bitmap.bm_data = bogus_data;
1495 c = gr_find_closest_color( 0, 0, 63 );
1496 for (i=0; i<4096; i++ ) bogus_data[i] = c;
1497 c = gr_find_closest_color( 63, 0, 0 );
1498 // Make a big red X !
1499 for (i=0; i<64; i++ ) {
1500 bogus_data[i*64+i] = c;
1501 bogus_data[i*64+(63-i)] = c;
1503 piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
1504 bogus_sound.length = 64*64;
1505 bogus_sound.data = bogus_data;
1506 GameBitmapOffset[0] = 0;
1509 if ( FindArg( "-bigpig" ))
1512 if ( FindArg( "-lowmem" ))
1513 piggy_low_memory = 1;
1515 if ( FindArg( "-nolowmem" ))
1516 piggy_low_memory = 0;
1518 if (piggy_low_memory)
1521 WIN(DDGRLOCK(dd_grd_curcanv));
1522 gr_set_curfont( SMALL_FONT );
1523 gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
1524 gr_printf( 0x8000, grd_curcanv->cv_h-20, "%s...", TXT_LOADING_DATA );
1525 WIN(DDGRUNLOCK(dd_grd_curcanv));
1527 #if 1 //def EDITOR //need for d1 mission briefings
1528 piggy_init_pigfile(DEFAULT_PIGFILE);
1531 snd_ok = ham_ok = read_hamfile();
1533 if (Piggy_hamfile_version >= 3)
1534 snd_ok = read_sndfile();
1536 atexit(piggy_close);
1538 mprintf ((0,"HamOk=%d SndOk=%d\n",ham_ok,snd_ok));
1539 return (ham_ok && snd_ok); //read ok
1542 int piggy_is_needed(int soundnum)
1546 if ( !digi_lomem ) return 1;
1548 for (i=0; i<MAX_SOUNDS; i++ ) {
1549 if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
1556 void piggy_read_sounds(void)
1569 fp = cfopen( DEFAULT_SNDFILE, "rb" );
1571 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1572 fp = cfopen( name, "rb");
1578 for (i=0; i<Num_sound_files; i++ ) {
1579 digi_sound *snd = &GameSounds[i];
1581 if ( SoundOffset[i] > 0 ) {
1582 if ( piggy_is_needed(i) ) {
1583 cfseek( fp, SoundOffset[i], SEEK_SET );
1585 // Read in the sound data!!!
1588 sbytes += snd->length;
1589 cfread( snd->data, snd->length, 1, fp );
1592 snd->data = (ubyte *) -1;
1598 mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
1603 extern int descent_critical_error;
1604 extern unsigned descent_critical_deverror;
1605 extern unsigned descent_critical_errcode;
1607 char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
1608 "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
1609 "Read fault", "General Failure" };
1611 void piggy_critical_error()
1613 grs_canvas * save_canv;
1614 grs_font * save_font;
1616 save_canv = grd_curcanv;
1617 save_font = grd_curcanv->cv_font;
1618 gr_palette_load( gr_palette );
1619 i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A' );
1622 gr_set_current_canvas(save_canv);
1623 grd_curcanv->cv_font = save_font;
1626 void piggy_bitmap_page_in( bitmap_index bitmap )
1635 Assert( i < MAX_BITMAP_FILES );
1636 Assert( i < Num_bitmap_files );
1637 Assert( Piggy_bitmap_cache_size > 0 );
1639 if ( i < 1 ) return;
1640 if ( i >= MAX_BITMAP_FILES ) return;
1641 if ( i >= Num_bitmap_files ) return;
1643 if ( GameBitmapOffset[i] == 0 ) return; // A read-from-disk bitmap!!!
1645 if ( piggy_low_memory ) {
1647 i = GameBitmapXlat[i]; // Xlat for low-memory settings!
1650 bmp = &GameBitmaps[i];
1652 if ( bmp->bm_flags & BM_FLAG_PAGED_OUT ) {
1656 descent_critical_error = 0;
1657 cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
1658 if ( descent_critical_error ) {
1659 piggy_critical_error();
1663 bmp->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1664 bmp->bm_flags = GameBitmapFlags[i];
1666 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1668 descent_critical_error = 0;
1669 zsize = cfile_read_int(Piggy_fp);
1670 if ( descent_critical_error ) {
1671 piggy_critical_error();
1675 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1676 //Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );
1677 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1679 piggy_bitmap_page_out_all();
1682 descent_critical_error = 0;
1683 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next+4], 1, zsize-4, Piggy_fp );
1684 if ( descent_critical_error ) {
1685 piggy_critical_error();
1690 switch (cfilelength(Piggy_fp)) {
1692 if (!FindArg("-macdata"))
1694 // otherwise, fall through...
1695 case MAC_ALIEN1_PIGSIZE:
1696 case MAC_ALIEN2_PIGSIZE:
1697 case MAC_FIRE_PIGSIZE:
1698 case MAC_GROUPA_PIGSIZE:
1699 case MAC_ICE_PIGSIZE:
1700 case MAC_WATER_PIGSIZE:
1701 rle_swap_0_255( bmp );
1702 memcpy(&zsize, bmp->bm_data, 4);
1707 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
1708 Piggy_bitmap_cache_next += zsize;
1709 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1711 piggy_bitmap_page_out_all();
1716 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1717 Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );
1718 if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) {
1719 piggy_bitmap_page_out_all();
1722 descent_critical_error = 0;
1723 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
1724 if ( descent_critical_error ) {
1725 piggy_critical_error();
1728 Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
1731 switch (cfilelength(Piggy_fp)) {
1733 if (!FindArg("-macdata"))
1735 // otherwise, fall through...
1736 case MAC_ALIEN1_PIGSIZE:
1737 case MAC_ALIEN2_PIGSIZE:
1738 case MAC_FIRE_PIGSIZE:
1739 case MAC_GROUPA_PIGSIZE:
1740 case MAC_ICE_PIGSIZE:
1741 case MAC_WATER_PIGSIZE:
1748 //@@if ( bmp->bm_selector ) {
1749 //@@#if !defined(WINDOWS) && !defined(MACINTOSH)
1750 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1751 //@@ Error( "Error modifying selector base in piggy.c\n" );
1758 if ( piggy_low_memory ) {
1760 GameBitmaps[org_i] = GameBitmaps[i];
1763 //@@Removed from John's code:
1765 //@@ if ( bmp->bm_selector ) {
1766 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1767 //@@ Error( "Error modifying selector base in piggy.c\n" );
1773 void piggy_bitmap_page_out_all()
1777 Piggy_bitmap_cache_next = 0;
1779 piggy_page_flushed++;
1784 for (i=0; i<Num_bitmap_files; i++ ) {
1785 if ( GameBitmapOffset[i] > 0 ) { // Don't page out bitmaps read from disk!!!
1786 GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
1787 GameBitmaps[i].bm_data = Piggy_bitmap_cache_data;
1791 mprintf(( 0, "Flushing piggy bitmap cache\n" ));
1794 void piggy_load_level_data()
1796 piggy_bitmap_page_out_all();
1802 void change_filename_ext( char *dest, char *src, char *ext );
1804 void piggy_write_pigfile(char *filename)
1807 int bitmap_data_start,data_offset;
1808 DiskBitmapHeader bmh;
1810 char subst_name[32];
1813 char tname[FILENAME_LEN];
1815 // -- mprintf( (0, "Paging in all piggy bitmaps..." ));
1816 for (i=0; i < Num_bitmap_files; i++ ) {
1819 PIGGY_PAGE_IN( bi );
1821 // -- mprintf( (0, "\n" ));
1825 // -- mprintf( (0, "Creating %s...",filename ));
1827 pig_fp = fopen( filename, "wb" ); //open PIG file
1828 Assert( pig_fp!=NULL );
1830 write_int(PIGFILE_ID,pig_fp);
1831 write_int(PIGFILE_VERSION,pig_fp);
1834 fwrite( &Num_bitmap_files, sizeof(int), 1, pig_fp );
1837 bitmap_data_start = ftell(pig_fp);
1838 bitmap_data_start += (Num_bitmap_files-1)*DISKBITMAPHEADER_SIZE;
1839 data_offset = bitmap_data_start;
1841 change_filename_ext(tname,filename,"lst");
1842 fp1 = fopen( tname, "wt" );
1843 change_filename_ext(tname,filename,"all");
1844 fp2 = fopen( tname, "wt" );
1846 for (i=1; i < Num_bitmap_files; i++ ) {
1852 p = strchr(AllBitmaps[i].name,'#');
1859 fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
1860 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1862 bmh.dflags = DBM_FLAG_ABM + n;
1866 fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
1867 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1871 bmp = &GameBitmaps[i];
1873 Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
1876 fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
1877 org_offset = ftell(pig_fp);
1878 bmh.offset = data_offset - bitmap_data_start;
1879 fseek( pig_fp, data_offset, SEEK_SET );
1881 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1882 size = (int *)bmp->bm_data;
1883 fwrite( bmp->bm_data, sizeof(ubyte), *size, pig_fp );
1884 data_offset += *size;
1886 fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
1888 fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, pig_fp );
1889 data_offset += bmp->bm_rowsize * bmp->bm_h;
1891 fprintf( fp1, ".\n" );
1893 fseek( pig_fp, org_offset, SEEK_SET );
1894 Assert( GameBitmaps[i].bm_w < 4096 );
1895 bmh.width = (GameBitmaps[i].bm_w & 0xff);
1896 bmh.wh_extra = ((GameBitmaps[i].bm_w >> 8) & 0x0f);
1897 Assert( GameBitmaps[i].bm_h < 4096 );
1898 bmh.height = GameBitmaps[i].bm_h;
1899 bmh.wh_extra |= ((GameBitmaps[i].bm_h >> 4) & 0xf0);
1900 bmh.flags = GameBitmaps[i].bm_flags;
1901 if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name )) {
1902 bitmap_index other_bitmap;
1903 other_bitmap = piggy_find_bitmap( subst_name );
1904 GameBitmapXlat[i] = other_bitmap.index;
1905 bmh.flags |= BM_FLAG_PAGED_OUT;
1906 //mprintf(( 0, "Skipping bitmap %d\n", i ));
1907 //mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
1909 bmh.flags &= ~BM_FLAG_PAGED_OUT;
1911 bmh.avg_color=GameBitmaps[i].avg_color;
1912 fwrite( &bmh, DISKBITMAPHEADER_SIZE, 1, pig_fp ); // Mark as a bitmap
1917 mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
1918 fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
1925 static void write_int(int i,FILE *file)
1927 if (fwrite( &i, sizeof(i), 1, file) != 1)
1928 Error( "Error reading int in gamesave.c" );
1932 void piggy_dump_all()
1936 int org_offset,data_offset=0;
1937 DiskSoundHeader sndh;
1938 int sound_data_start=0;
1941 #ifdef NO_DUMP_SOUNDS
1942 Num_sound_files = 0;
1943 Num_sound_files_new = 0;
1946 if (!Must_write_hamfile && (Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
1949 fp1 = fopen( "ham.lst", "wt" );
1950 fp2 = fopen( "ham.all", "wt" );
1952 if (Must_write_hamfile || Num_bitmap_files_new) {
1954 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1956 ham_fp = fopen( DEFAULT_HAMFILE, "wb" ); //open HAM file
1957 Assert( ham_fp!=NULL );
1959 write_int(HAMFILE_ID,ham_fp);
1960 write_int(HAMFILE_VERSION,ham_fp);
1962 bm_write_all(ham_fp);
1963 xlat_offset = ftell(ham_fp);
1964 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1967 if (Num_bitmap_files_new)
1968 piggy_write_pigfile(DEFAULT_PIGFILE);
1970 //free up memeory used by new bitmaps
1971 for (i=Num_bitmap_files-Num_bitmap_files_new;i<Num_bitmap_files;i++)
1972 d_free(GameBitmaps[i].bm_data);
1974 //next thing must be done after pig written
1975 fseek( ham_fp, xlat_offset, SEEK_SET );
1976 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1979 mprintf( (0, "\n" ));
1982 if (Num_sound_files_new) {
1984 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1985 // Now dump sound file
1986 ham_fp = fopen( DEFAULT_SNDFILE, "wb" );
1987 Assert( ham_fp!=NULL );
1989 write_int(SNDFILE_ID,ham_fp);
1990 write_int(SNDFILE_VERSION,ham_fp);
1992 fwrite( &Num_sound_files, sizeof(int), 1, ham_fp );
1994 mprintf( (0, "\nDumping sounds..." ));
1996 sound_data_start = ftell(ham_fp);
1997 sound_data_start += Num_sound_files*sizeof(DiskSoundHeader);
1998 data_offset = sound_data_start;
2000 for (i=0; i < Num_sound_files; i++ ) {
2003 snd = &GameSounds[i];
2004 strcpy( sndh.name, AllSounds[i].name );
2005 sndh.length = GameSounds[i].length;
2006 sndh.offset = data_offset - sound_data_start;
2008 org_offset = ftell(ham_fp);
2009 fseek( ham_fp, data_offset, SEEK_SET );
2011 sndh.data_length = GameSounds[i].length;
2012 fwrite( snd->data, sizeof(ubyte), snd->length, ham_fp );
2013 data_offset += snd->length;
2014 fseek( ham_fp, org_offset, SEEK_SET );
2015 fwrite( &sndh, sizeof(DiskSoundHeader), 1, ham_fp ); // Mark as a bitmap
2017 fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
2018 fprintf( fp2, "%s.raw\n", AllSounds[i].name );
2022 mprintf( (0, "\n" ));
2025 fprintf( fp1, "Total sound size: %d bytes\n", data_offset-sound_data_start);
2026 mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
2027 fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
2032 // Never allow the game to run after building ham.
2046 d_free( SoundBits );
2048 hashtable_free( &AllBitmapsNames );
2049 hashtable_free( &AllDigiSndNames );
2053 int piggy_does_bitmap_exist_slow( char * name )
2057 for (i=0; i<Num_bitmap_files; i++ ) {
2058 if ( !strcmp( AllBitmaps[i].name, name) )
2065 #define NUM_GAUGE_BITMAPS 23
2066 char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = {
2067 "gauge01", "gauge01b",
2068 "gauge02", "gauge02b",
2069 "gauge06", "gauge06b",
2070 "targ01", "targ01b",
2071 "targ02", "targ02b",
2072 "targ03", "targ03b",
2073 "targ04", "targ04b",
2074 "targ05", "targ05b",
2075 "targ06", "targ06b",
2076 "gauge18", "gauge18b",
2082 int piggy_is_gauge_bitmap( char * base_name )
2085 for (i=0; i<NUM_GAUGE_BITMAPS; i++ ) {
2086 if ( !stricmp( base_name, gauge_bitmap_names[i] ))
2093 int piggy_is_substitutable_bitmap( char * name, char * subst_name )
2097 char base_name[ 16 ];
2099 strcpy( subst_name, name );
2100 p = strchr( subst_name, '#' );
2102 frame = atoi( &p[1] );
2104 strcpy( base_name, subst_name );
2105 if ( !piggy_is_gauge_bitmap( base_name )) {
2106 sprintf( subst_name, "%s#%d", base_name, frame+1 );
2107 if ( piggy_does_bitmap_exist_slow( subst_name ) ) {
2109 sprintf( subst_name, "%s#%d", base_name, frame-1 );
2115 strcpy( subst_name, name );
2122 // New Windows stuff
2124 // windows bitmap page in
2125 // Page in a bitmap, if ddraw, then page it into a ddsurface in
2126 // 'video' memory. if that fails, page it in normally.
2128 void piggy_bitmap_page_in_w( bitmap_index bitmap, int ddraw )
2133 // Essential when switching video modes!
2135 void piggy_bitmap_page_out_all_w()
2143 * Functions for loading replacement textures
2144 * 1) From .pog files
2145 * 2) From descent.pig (for loading d1 levels)
2148 extern void change_filename_extension( char *dest, char *src, char *new_ext );
2149 extern char last_palette_loaded_pig[];
2151 ubyte *Bitmap_replacement_data=NULL;
2153 void free_bitmap_replacements()
2155 if (Bitmap_replacement_data) {
2156 d_free(Bitmap_replacement_data);
2157 Bitmap_replacement_data = NULL;
2161 void load_bitmap_replacements(char *level_name)
2163 char ifile_name[FILENAME_LEN];
2167 //first, free up data allocated for old bitmaps
2168 free_bitmap_replacements();
2170 change_filename_extension(ifile_name, level_name, ".POG" );
2172 ifile = cfopen(ifile_name,"rb");
2175 int id,version,n_bitmaps;
2176 int bitmap_data_size;
2179 id = cfile_read_int(ifile);
2180 version = cfile_read_int(ifile);
2182 if (id != MAKE_SIG('G','O','P','D') || version != 1) {
2187 n_bitmaps = cfile_read_int(ifile);
2189 MALLOC( indices, ushort, n_bitmaps );
2191 for (i = 0; i < n_bitmaps; i++)
2192 indices[i] = cfile_read_short(ifile);
2194 bitmap_data_size = cfilelength(ifile) - cftell(ifile) - DISKBITMAPHEADER_SIZE * n_bitmaps;
2195 MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
2197 for (i=0;i<n_bitmaps;i++) {
2198 DiskBitmapHeader bmh;
2199 grs_bitmap temp_bitmap;
2201 DiskBitmapHeader_read(&bmh, ifile);
2203 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2205 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2206 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2207 temp_bitmap.avg_color = bmh.avg_color;
2208 temp_bitmap.bm_data = Bitmap_replacement_data + bmh.offset;
2210 temp_bitmap.bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2212 GameBitmaps[indices[i]] = temp_bitmap;
2215 cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
2221 last_palette_loaded_pig[0]= 0; //force pig re-load
2223 texmerge_flush(); //for re-merging with new textures
2226 atexit(free_bitmap_replacements);
2229 #define FIRST_D1_TEXTURE 722
2230 #define LAST_D1_STATIC_TEXTURE 1042//1342 //afterwards, we have door frames and stuff
2231 #define FIRST_D2_TEXTURE 1243
2233 void load_d1_bitmap_replacements()
2235 CFILE * d1_Piggy_fp;
2236 grs_bitmap temp_bitmap;
2237 DiskBitmapHeader bmh;
2238 int pig_data_start, bitmap_header_start, bitmap_data_start;
2239 int N_bitmaps, zsize;
2240 int d1_index, d2_index;
2241 ubyte colormap[256];
2242 ubyte *next_bitmap; // to which address we write the next bitmap
2244 d1_Piggy_fp = cfopen( D1_PIGFILE, "rb" );
2247 return; // use d2 bitmaps instead...
2249 //first, free up data allocated for old bitmaps
2250 free_bitmap_replacements();
2252 // read d1 palette, build colormap
2255 ubyte d1_palette[256*3];
2256 CFILE * palette_file = cfopen(D1_PALETTE, "rb" );
2257 Assert( palette_file );
2258 Assert( cfilelength( palette_file ) == 9472 );
2259 cfread( d1_palette, 256, 3, palette_file);
2260 cfclose( palette_file );
2261 build_colormap_good( d1_palette, colormap, freq );
2262 // don't change transparencies:
2263 colormap[254] = 254;
2264 colormap[255] = 255;
2267 switch (cfilelength(d1_Piggy_fp)) {
2268 case D1_SHAREWARE_10_PIGSIZE:
2269 case D1_SHAREWARE_PIGSIZE:
2275 case D1_OEM_PIGSIZE:
2276 case D1_MAC_PIGSIZE:
2277 case D1_MAC_SHARE_PIGSIZE:
2279 pig_data_start = cfile_read_int(d1_Piggy_fp );
2280 bm_read_all_d1( d1_Piggy_fp );
2281 //for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2285 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2286 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2288 int N_sounds = cfile_read_int(d1_Piggy_fp);
2289 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2290 + N_sounds * DISKSOUNDHEADER_SIZE;
2291 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2292 bitmap_data_start = bitmap_header_start + header_size;
2295 MALLOC( Bitmap_replacement_data, ubyte, cfilelength(d1_Piggy_fp) - bitmap_data_start ); // too much
2296 //TODO: handle case where b_r_d == 0! (have to convert textures, return, not bm_read_all_d1)
2298 next_bitmap = Bitmap_replacement_data;
2300 for (d1_index=1; d1_index<=N_bitmaps; d1_index++ ) {
2301 // only change wall texture bitmaps
2302 if (d1_index >= FIRST_D1_TEXTURE && d1_index <= LAST_D1_STATIC_TEXTURE) {
2303 d2_index = d1_index + FIRST_D2_TEXTURE - FIRST_D1_TEXTURE;
2305 cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2306 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2308 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2310 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2311 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2312 temp_bitmap.avg_color = bmh.avg_color;
2314 //GameBitmapFlags[convert_d1_bitmap_num(d1_index)] = 0;
2316 temp_bitmap.bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2318 temp_bitmap.bm_data = next_bitmap;
2320 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2321 zsize = cfile_read_int(d1_Piggy_fp);
2322 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2323 cfread(next_bitmap, 1, zsize, d1_Piggy_fp);
2325 switch(cfilelength(d1_Piggy_fp)) {
2326 case D1_MAC_PIGSIZE:
2327 case D1_MAC_SHARE_PIGSIZE:
2328 rle_swap_0_255(&temp_bitmap);
2330 rle_remap(&temp_bitmap, colormap);
2332 GameBitmaps[d2_index] = temp_bitmap;
2334 memcpy(&zsize, temp_bitmap.bm_data, 4);
2335 next_bitmap += zsize;
2339 cfclose(d1_Piggy_fp);
2341 last_palette_loaded_pig[0]= 0; //force pig re-load
2343 texmerge_flush(); //for re-merging with new textures
2345 atexit(free_bitmap_replacements);
2349 extern int extra_bitmap_num;
2352 * Find and load the named bitmap from descent.pig
2353 * similar to read_extra_bitmap_iff
2355 bitmap_index read_extra_bitmap_d1_pig(char *name)
2357 bitmap_index bitmap_num;
2358 grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2360 bitmap_num.index = 0;
2365 DiskBitmapHeader bmh;
2366 int pig_data_start, bitmap_header_start, bitmap_data_start;
2367 int N_bitmaps, zsize;
2368 ubyte colormap[256];
2370 d1_Piggy_fp = cfopen(D1_PIGFILE, "rb");
2373 con_printf(CON_DEBUG, "could not open %s\n", D1_PIGFILE);
2377 // read d1 palette, build colormap
2380 ubyte d1_palette[256*3];
2381 CFILE * palette_file = cfopen(D1_PALETTE, "rb");
2382 if (!palette_file || cfilelength(palette_file) != 9472)
2384 con_printf(CON_DEBUG, "could not open %s\n", D1_PALETTE);
2387 cfread( d1_palette, 256, 3, palette_file);
2388 cfclose( palette_file );
2389 build_colormap_good( d1_palette, colormap, freq );
2390 // don't change transparencies:
2391 colormap[254] = 254;
2392 colormap[255] = 255;
2395 switch (cfilelength(d1_Piggy_fp)) {
2396 case D1_SHAREWARE_10_PIGSIZE:
2397 case D1_SHAREWARE_PIGSIZE:
2403 case D1_OEM_PIGSIZE:
2404 case D1_MAC_PIGSIZE:
2405 case D1_MAC_SHARE_PIGSIZE:
2406 pig_data_start = cfile_read_int(d1_Piggy_fp);
2410 cfseek(d1_Piggy_fp, pig_data_start, SEEK_SET);
2411 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2413 int N_sounds = cfile_read_int(d1_Piggy_fp);
2414 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2415 + N_sounds * DISKSOUNDHEADER_SIZE;
2416 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2417 bitmap_data_start = bitmap_header_start + header_size;
2420 for (i = 0; i < N_bitmaps; i++)
2422 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2423 if (!strnicmp(bmh.name, name, 8))
2427 if (strnicmp(bmh.name, name, 8))
2429 con_printf(CON_DEBUG, "could not find bitmap %s\n", name);
2433 memset( new, 0, sizeof(grs_bitmap) );
2435 new->bm_w = new->bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2436 new->bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2437 new->avg_color = bmh.avg_color;
2439 new->bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2441 if ( bmh.flags & BM_FLAG_RLE )
2443 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2444 zsize = cfile_read_int(d1_Piggy_fp);
2447 zsize = new->bm_w * new->bm_h;
2448 new->bm_data = d_malloc(zsize);
2449 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2450 cfread(new->bm_data, 1, zsize, d1_Piggy_fp);
2452 switch(cfilelength(d1_Piggy_fp)) {
2453 case D1_MAC_PIGSIZE:
2454 case D1_MAC_SHARE_PIGSIZE:
2455 rle_swap_0_255(new);
2457 rle_remap(new, colormap);
2459 cfclose(d1_Piggy_fp);
2462 new->avg_color = 0; //compute_average_pixel(new);
2464 bitmap_num.index = extra_bitmap_num;
2466 GameBitmaps[extra_bitmap_num++] = *new;
2472 #ifndef FAST_FILE_IO
2474 * reads a bitmap_index structure from a CFILE
2476 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2478 bi->index = cfile_read_short(fp);
2482 * reads n bitmap_index structs from a CFILE
2484 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2488 for (i = 0; i < n; i++)
2489 bi[i].index = cfile_read_short(fp);
2494 * reads a DiskBitmapHeader structure from a CFILE
2496 void DiskBitmapHeader_read(DiskBitmapHeader *dbh, CFILE *fp)
2498 cfread(dbh->name, 8, 1, fp);
2499 dbh->dflags = cfile_read_byte(fp);
2500 dbh->width = cfile_read_byte(fp);
2501 dbh->height = cfile_read_byte(fp);
2502 dbh->wh_extra = cfile_read_byte(fp);
2503 dbh->flags = cfile_read_byte(fp);
2504 dbh->avg_color = cfile_read_byte(fp);
2505 dbh->offset = cfile_read_int(fp);
2509 * reads a DiskSoundHeader structure from a CFILE
2511 void DiskSoundHeader_read(DiskSoundHeader *dsh, CFILE *fp)
2513 cfread(dsh->name, 8, 1, fp);
2514 dsh->length = cfile_read_int(fp);
2515 dsh->data_length = cfile_read_int(fp);
2516 dsh->offset = cfile_read_int(fp);
2518 #endif // FAST_FILE_IO
2521 * reads a descent 1 DiskBitmapHeader structure from a CFILE
2523 void DiskBitmapHeader_d1_read(DiskBitmapHeader *dbh, CFILE *fp)
2525 cfread(dbh->name, 8, 1, fp);
2526 dbh->dflags = cfile_read_byte(fp);
2527 dbh->width = cfile_read_byte(fp);
2528 dbh->height = cfile_read_byte(fp);
2530 dbh->flags = cfile_read_byte(fp);
2531 dbh->avg_color = cfile_read_byte(fp);
2532 dbh->offset = cfile_read_int(fp);