1 /* $Id: piggy.c,v 1.35 2003-08-03 22:00:14 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.35 2003-08-03 22:00:14 btb Exp $";
411 #include "gamefont.h"
415 #include "gamemine.h"
416 #include "textures.h"
417 #include "texmerge.h"
423 #include "byteswap.h"
424 #include "findfile.h"
428 // #include "unarj.h"
430 #include <Strings.h> // MacOS Toolbox header
435 //#define NO_DUMP_SOUNDS 1 //if set, dump bitmaps but not sounds
437 #define DEFAULT_PIGFILE_REGISTERED "groupa.pig"
438 #define DEFAULT_PIGFILE_SHAREWARE "d2demo.pig"
439 #define DEFAULT_HAMFILE_REGISTERED "descent2.ham"
440 #define DEFAULT_HAMFILE_SHAREWARE "d2demo.ham"
442 #define D1_PALETTE "palette.256"
444 #define DEFAULT_PIGFILE (cfexist(DEFAULT_PIGFILE_REGISTERED)?DEFAULT_PIGFILE_REGISTERED:DEFAULT_PIGFILE_SHAREWARE)
445 #define DEFAULT_HAMFILE (cfexist(DEFAULT_HAMFILE_REGISTERED)?DEFAULT_HAMFILE_REGISTERED:DEFAULT_HAMFILE_SHAREWARE)
446 #define DEFAULT_SNDFILE ((Piggy_hamfile_version < 3)?DEFAULT_HAMFILE_SHAREWARE:(digi_sample_rate==SAMPLE_RATE_22K)?"descent2.s22":"descent2.s11")
448 #define MAC_ALIEN1_PIGSIZE 5013035
449 #define MAC_ALIEN2_PIGSIZE 4909916
450 #define MAC_FIRE_PIGSIZE 4969035
451 #define MAC_GROUPA_PIGSIZE 4929684 // also used for mac shareware
452 #define MAC_ICE_PIGSIZE 4923425
453 #define MAC_WATER_PIGSIZE 4832403
455 ubyte *BitmapBits = NULL;
456 ubyte *SoundBits = NULL;
458 typedef struct BitmapFile {
462 typedef struct SoundFile {
466 hashtable AllBitmapsNames;
467 hashtable AllDigiSndNames;
469 int Num_bitmap_files = 0;
470 int Num_sound_files = 0;
472 digi_sound GameSounds[MAX_SOUND_FILES];
473 int SoundOffset[MAX_SOUND_FILES];
474 grs_bitmap GameBitmaps[MAX_BITMAP_FILES];
476 alias alias_list[MAX_ALIASES];
479 int Must_write_hamfile = 0;
480 int Num_bitmap_files_new = 0;
481 int Num_sound_files_new = 0;
482 BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
483 static SoundFile AllSounds[ MAX_SOUND_FILES ];
485 int Piggy_hamfile_version = 0;
487 int piggy_low_memory = 0;
489 int Piggy_bitmap_cache_size = 0;
490 int Piggy_bitmap_cache_next = 0;
491 ubyte * Piggy_bitmap_cache_data = NULL;
492 static int GameBitmapOffset[MAX_BITMAP_FILES];
493 static ubyte GameBitmapFlags[MAX_BITMAP_FILES];
494 ushort GameBitmapXlat[MAX_BITMAP_FILES];
496 #define PIGGY_BUFFER_SIZE (2400*1024)
499 #define PIGGY_SMALL_BUFFER_SIZE (1400*1024) // size of buffer when piggy_low_memory is set
502 #undef PIGGY_BUFFER_SIZE
503 #undef PIGGY_SMALL_BUFFER_SIZE
505 #define PIGGY_BUFFER_SIZE (2000*1024)
506 #define PIGGY_SMALL_BUFFER_SIZE (1100 * 1024)
511 int piggy_page_flushed = 0;
513 #define DBM_FLAG_ABM 64
515 #define BM_FLAGS_TO_COPY (BM_FLAG_TRANSPARENT | BM_FLAG_SUPER_TRANSPARENT \
516 | BM_FLAG_NO_LIGHTING | BM_FLAG_RLE | BM_FLAG_RLE_BIG)
521 extern short cd_VRefNum;
522 extern void ConcatPStr(StringPtr dst, StringPtr src);
523 extern int ConvertPToCStr(StringPtr inPStr, char* outCStrBuf);
524 extern int ConvertCToPStr(char* inCStr, StringPtr outPStrBuf);
527 int piggy_is_substitutable_bitmap( char * name, char * subst_name );
530 void piggy_write_pigfile(char *filename);
531 static void write_int(int i,FILE *file);
534 void swap_0_255(grs_bitmap *bmp)
538 for (i = 0; i < bmp->bm_h * bmp->bm_w; i++) {
539 if(bmp->bm_data[i] == 0)
540 bmp->bm_data[i] = 255;
541 else if (bmp->bm_data[i] == 255)
546 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
549 Assert( Num_bitmap_files < MAX_BITMAP_FILES );
551 temp.index = Num_bitmap_files;
555 if ( FindArg("-macdata") )
558 if ( !BigPig ) gr_bitmap_rle_compress( bmp );
559 Num_bitmap_files_new++;
562 strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
563 hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
564 GameBitmaps[Num_bitmap_files] = *bmp;
566 GameBitmapOffset[Num_bitmap_files] = 0;
567 GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
574 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
578 Assert( Num_sound_files < MAX_SOUND_FILES );
580 strncpy( AllSounds[Num_sound_files].name, name, 12 );
581 hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
582 GameSounds[Num_sound_files] = *snd;
584 SoundOffset[Num_sound_files] = 0;
590 Num_sound_files_new++;
596 bitmap_index piggy_find_bitmap( char * name )
604 if ((t=strchr(name,'#'))!=NULL)
607 for (i=0;i<Num_aliases;i++)
608 if (stricmp(name,alias_list[i].alias_name)==0) {
609 if (t) { //extra stuff for ABMs
610 static char temp[FILENAME_LEN];
611 _splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
617 name=alias_list[i].file_name;
624 i = hashtable_search( &AllBitmapsNames, name );
633 int piggy_find_sound( char * name )
637 i = hashtable_search( &AllDigiSndNames, name );
645 CFILE * Piggy_fp = NULL;
647 #define FILENAME_LEN 13
649 char Current_pigfile[FILENAME_LEN] = "";
651 void piggy_close_file()
656 Current_pigfile[0] = 0;
660 int Pigfile_initialized=0;
662 #define PIGFILE_ID MAKE_SIG('G','I','P','P') //PPIG
663 #define PIGFILE_VERSION 2
665 extern char CDROM_dir[];
667 int request_cd(void);
672 //copies a pigfile from the CD to the current dir
673 //retuns file handle of new pig
674 CFILE *copy_pigfile_from_cd(char *filename) // MACINTOSH VERSION
677 char sourcePathAndFileCStr[255] = "";
678 char destPathAndFileCStr[255] = "";
680 FILE* sourceFile = NULL;
681 FILE* destFile = NULL;
682 const int BUF_SIZE = 4096;
686 Str255 sourcePathAndFilePStr = "\p";
687 Str255 destPathAndFilePStr = "\p";
688 Str255 pigfileNamePStr = "\p";
689 HParamBlockRec theSourcePigHFSParams;
690 HParamBlockRec theDestPigHFSParams;
691 OSErr theErr = noErr;
692 char oldDirCStr[255] = "";
694 getcwd(oldDirCStr, 255);
696 show_boxed_message("Copying bitmap data from CD...");
697 gr_palette_load(gr_palette); //I don't think this line is really needed
700 //First, delete all PIG files currently in the directory
701 if( !FileFindFirst( "*.pig", &find ) )
706 } while( !FileFindNext( &find ) );
712 //Now, copy over new pig
713 songs_stop_redbook(); //so we can read off the cd
715 // make the source path "<cd volume>:Data:filename.pig"
716 //MWA ConvertCToPStr(filename, pigfileNamePStr);
718 //MWA ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:"); // volume ID is cd_VRefNum
719 //MWA ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
722 strcpy(sourcePathAndFileCStr, "Descent II:Data:");
723 strcat(sourcePathAndFileCStr, filename);
725 // make the destination path "<default directory>:Data:filename.pig"
726 //MWA ConcatPStr(destPathAndFilePStr, "\p:Data:");
727 //MWA ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
728 //MWA ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
729 //MWA ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
731 strcpy(destPathAndFileCStr, ":Data:");
732 strcat(destPathAndFileCStr, filename);
734 strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
735 strcpy(destPathAndFilePStr, destPathAndFileCStr);
736 c2pstr(sourcePathAndFilePStr);
737 c2pstr(destPathAndFilePStr);
740 // Open the source file
741 sourceFile = fopen(sourcePathAndFileCStr,"rb");
745 if (request_cd() == -1)
746 Error("Cannot load file <%s> from CD",filename);
749 } while (!sourceFile);
752 // Get the time stamp from the source file
753 theSourcePigHFSParams.fileParam.ioCompletion = nil;
754 theSourcePigHFSParams.fileParam.ioNamePtr = sourcePathAndFilePStr;
755 theSourcePigHFSParams.fileParam.ioVRefNum = cd_VRefNum;
756 theSourcePigHFSParams.fileParam.ioFDirIndex = 0;
757 theSourcePigHFSParams.fileParam.ioDirID = 0;
759 theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
762 // Error getting file time stamp!! Why? JTS
763 Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
766 // Copy the file over
769 // Open the destination file
770 destFile = fopen(destPathAndFileCStr,"wb");
773 Error("Cannot create file: <%s>\n", destPathAndFileCStr);
776 // Copy bytes until the end of the source file
777 while (!feof(sourceFile))
782 bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
783 if (ferror(sourceFile))
784 Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
786 // Assert is bogus Assert(bytes_read == BUF_SIZE || feof(sourceFile));
788 fwrite(buf,1,bytes_read,destFile);
789 if (ferror(destFile))
790 Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
793 // close the source/dest files
794 if (fclose(sourceFile))
795 Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
796 if (fclose(destFile))
797 Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
799 // Get the current hfs data for the new file
800 theDestPigHFSParams.fileParam.ioCompletion = nil;
801 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
802 theDestPigHFSParams.fileParam.ioVRefNum = 0;
803 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
804 theDestPigHFSParams.fileParam.ioDirID = 0;
805 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
806 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
808 // Error getting file time stamp!! Why? JTS
809 Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
812 // Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
813 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
814 theDestPigHFSParams.fileParam.ioVRefNum = 0;
815 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
816 theDestPigHFSParams.fileParam.ioDirID = 0;
818 // Copy the time stamp from the source file info
819 theDestPigHFSParams.fileParam.ioFlCrDat = theSourcePigHFSParams.fileParam.ioFlCrDat;
820 theDestPigHFSParams.fileParam.ioFlMdDat = theSourcePigHFSParams.fileParam.ioFlMdDat;
821 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
822 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
824 // Set the dest file's time stamp to the source file's time stamp values
825 theErr = PBHSetFInfo(&theDestPigHFSParams, false);
827 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
829 Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
832 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
834 return cfopen(destPathAndFileCStr, "rb");
837 #else //PC Version of copy_pigfile_from_cd is below
839 //copies a pigfile from the CD to the current dir
840 //retuns file handle of new pig
841 CFILE *copy_pigfile_from_cd(char *filename)
847 return cfopen(filename, "rb");
848 show_boxed_message("Copying bitmap data from CD...");
849 gr_palette_load(gr_palette); //I don't think this line is really needed
851 //First, delete all PIG files currently in the directory
853 if( !FileFindFirst( "*.pig", &find ) ) {
855 cfile_delete(find.name);
856 } while( !FileFindNext( &find ) );
860 //Now, copy over new pig
862 songs_stop_redbook(); //so we can read off the cd
864 //new code to unarj file
865 strcpy(name,CDROM_dir);
866 strcat(name,"descent2.sow");
869 // ret = unarj_specific_file(name,filename,filename);
874 if (ret != EXIT_SUCCESS) {
876 //delete file, so we don't leave partial file
877 cfile_delete(filename);
880 if (request_cd() == -1)
882 //NOTE LINK TO ABOVE IF
883 Error("Cannot load file <%s> from CD",filename);
886 } while (ret != EXIT_SUCCESS);
888 return cfopen(filename, "rb");
891 #endif // end of ifdef MAC around copy_pigfile_from_cd
893 //initialize a pigfile, reading headers
894 //returns the size of all the bitmap data
895 void piggy_init_pigfile(char *filename)
899 char temp_name_read[16];
900 grs_bitmap temp_bitmap;
901 DiskBitmapHeader bmh;
902 int header_size, N_bitmaps, data_size, data_start;
904 char name[255]; // filename + path for the mac
907 piggy_close_file(); //close old pig if still open
909 //rename pigfile for shareware
910 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
911 filename = DEFAULT_PIGFILE_SHAREWARE;
914 Piggy_fp = cfopen( filename, "rb" );
916 sprintf(name, ":Data:%s", filename);
917 Piggy_fp = cfopen( name, "rb" );
919 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
920 if (Piggy_fp == NULL)
922 Error("Cannot load required file <%s>",name);
924 #endif // end of if def shareware
930 return; //if editor, ok to not have pig, because we'll build one
932 Piggy_fp = copy_pigfile_from_cd(filename);
936 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
937 int pig_id,pig_version;
939 pig_id = cfile_read_int(Piggy_fp);
940 pig_version = cfile_read_int(Piggy_fp);
941 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
942 cfclose(Piggy_fp); //out of date pig
943 Piggy_fp = NULL; //..so pretend it's not here
950 return; //if editor, ok to not have pig, because we'll build one
952 Error("Cannot load required file <%s>",filename);
956 strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
958 N_bitmaps = cfile_read_int(Piggy_fp);
960 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
962 data_start = header_size + cftell(Piggy_fp);
964 data_size = cfilelength(Piggy_fp) - data_start;
966 Num_bitmap_files = 1;
968 for (i=0; i<N_bitmaps; i++ ) {
969 DiskBitmapHeader_read(&bmh, Piggy_fp);
970 memcpy( temp_name_read, bmh.name, 8 );
971 temp_name_read[8] = 0;
972 if ( bmh.dflags & DBM_FLAG_ABM )
973 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
975 strcpy( temp_name, temp_name_read );
976 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
977 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
978 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
979 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
980 temp_bitmap.avg_color = bmh.avg_color;
981 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
983 GameBitmapFlags[i+1] = bmh.flags & BM_FLAGS_TO_COPY;
985 GameBitmapOffset[i+1] = bmh.offset + data_start;
986 Assert( (i+1) == Num_bitmap_files );
987 piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
991 Piggy_bitmap_cache_size = data_size + (data_size/10); //extra mem for new bitmaps
992 Assert( Piggy_bitmap_cache_size > 0 );
994 Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
996 if (piggy_low_memory)
997 Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
1000 BitmapBits = d_malloc( Piggy_bitmap_cache_size );
1001 if ( BitmapBits == NULL )
1002 Error( "Not enough memory to load bitmaps\n" );
1003 Piggy_bitmap_cache_data = BitmapBits;
1004 Piggy_bitmap_cache_next = 0;
1006 #if defined(MACINTOSH) && defined(SHAREWARE)
1007 // load_exit_models();
1010 Pigfile_initialized=1;
1013 #define FILENAME_LEN 13
1014 #define MAX_BITMAPS_PER_BRUSH 30
1016 extern int compute_average_pixel(grs_bitmap *new);
1018 ubyte *Bitmap_replacement_data = NULL;
1020 //reads in a new pigfile (for new palette)
1021 //returns the size of all the bitmap data
1022 void piggy_new_pigfile(char *pigname)
1026 char temp_name_read[16];
1027 grs_bitmap temp_bitmap;
1028 DiskBitmapHeader bmh;
1029 int header_size, N_bitmaps, data_size, data_start;
1030 int must_rewrite_pig = 0;
1037 //rename pigfile for shareware
1038 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
1039 pigname = DEFAULT_PIGFILE_SHAREWARE;
1041 if (strnicmp(Current_pigfile, pigname, sizeof(Current_pigfile)) == 0 // correct pig already loaded
1042 && !Bitmap_replacement_data) // no need to reload: no bitmaps were altered
1045 if (!Pigfile_initialized) { //have we ever opened a pigfile?
1046 piggy_init_pigfile(pigname); //..no, so do initialization stuff
1050 piggy_close_file(); //close old pig if still open
1052 Piggy_bitmap_cache_next = 0; //free up cache
1054 strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
1057 Piggy_fp = cfopen( pigname, "rb" );
1059 sprintf(name, ":Data:%s", pigname);
1060 Piggy_fp = cfopen( name, "rb" );
1062 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
1063 if (Piggy_fp == NULL)
1065 Error("Cannot load required file <%s>",name);
1067 #endif // end of if def shareware
1072 Piggy_fp = copy_pigfile_from_cd(pigname);
1075 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1076 int pig_id,pig_version;
1078 pig_id = cfile_read_int(Piggy_fp);
1079 pig_version = cfile_read_int(Piggy_fp);
1080 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1081 cfclose(Piggy_fp); //out of date pig
1082 Piggy_fp = NULL; //..so pretend it's not here
1088 Error("Cannot open correct version of <%s>", pigname);
1093 N_bitmaps = cfile_read_int(Piggy_fp);
1095 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
1097 data_start = header_size + cftell(Piggy_fp);
1099 data_size = cfilelength(Piggy_fp) - data_start;
1101 for (i=1; i<=N_bitmaps; i++ ) {
1102 DiskBitmapHeader_read(&bmh, Piggy_fp);
1103 memcpy( temp_name_read, bmh.name, 8 );
1104 temp_name_read[8] = 0;
1106 if ( bmh.dflags & DBM_FLAG_ABM )
1107 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
1109 strcpy( temp_name, temp_name_read );
1111 //Make sure name matches
1112 if (strcmp(temp_name,AllBitmaps[i].name)) {
1113 //Int3(); //this pig is out of date. Delete it
1117 strcpy(AllBitmaps[i].name,temp_name);
1119 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1121 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1122 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1123 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1124 temp_bitmap.avg_color = bmh.avg_color;
1125 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1127 GameBitmapFlags[i] = bmh.flags & BM_FLAGS_TO_COPY;
1129 GameBitmapOffset[i] = bmh.offset + data_start;
1131 GameBitmaps[i] = temp_bitmap;
1135 N_bitmaps = 0; //no pigfile, so no bitmaps
1139 Assert(N_bitmaps == Num_bitmap_files-1);
1143 if (must_rewrite_pig || (N_bitmaps < Num_bitmap_files-1)) {
1146 //re-read the bitmaps that aren't in this pig
1148 for (i=N_bitmaps+1;i<Num_bitmap_files;i++) {
1151 p = strchr(AllBitmaps[i].name,'#');
1153 if (p) { //this is an ABM
1154 char abmname[FILENAME_LEN];
1156 grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
1157 int iff_error; //reference parm to avoid warning message
1159 char basename[FILENAME_LEN];
1162 strcpy(basename,AllBitmaps[i].name);
1163 basename[p-AllBitmaps[i].name] = 0; //cut off "#nn" part
1165 sprintf( abmname, "%s.abm", basename );
1167 iff_error = iff_read_animbrush(abmname,bm,MAX_BITMAPS_PER_BRUSH,&nframes,newpal);
1169 if (iff_error != IFF_NO_ERROR) {
1170 mprintf((1,"File %s - IFF error: %s",abmname,iff_errormsg(iff_error)));
1171 Error("File %s - IFF error: %s",abmname,iff_errormsg(iff_error));
1174 for (fnum=0;fnum<nframes; fnum++) {
1178 sprintf( tempname, "%s#%d", basename, fnum );
1180 //SuperX = (GameBitmaps[i+fnum].bm_flags&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1181 SuperX = (GameBitmapFlags[i+fnum]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1182 //above makes assumption that supertransparent color is 254
1184 if ( iff_has_transparency )
1185 gr_remap_bitmap_good( bm[fnum], newpal, iff_transparent_color, SuperX );
1187 gr_remap_bitmap_good( bm[fnum], newpal, -1, SuperX );
1189 bm[fnum]->avg_color = compute_average_pixel(bm[fnum]);
1192 if ( FindArg("-macdata") )
1193 swap_0_255( bm[fnum] );
1195 if ( !BigPig ) gr_bitmap_rle_compress( bm[fnum] );
1197 if (bm[fnum]->bm_flags & BM_FLAG_RLE)
1198 size = *((int *) bm[fnum]->bm_data);
1200 size = bm[fnum]->bm_w * bm[fnum]->bm_h;
1202 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],bm[fnum]->bm_data,size);
1203 d_free(bm[fnum]->bm_data);
1204 bm[fnum]->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1205 Piggy_bitmap_cache_next += size;
1207 GameBitmaps[i+fnum] = *bm[fnum];
1209 // -- mprintf( (0, "U" ));
1213 i += nframes-1; //filled in multiple bitmaps
1215 else { //this is a BBM
1218 ubyte newpal[256*3];
1220 char bbmname[FILENAME_LEN];
1223 MALLOC( new, grs_bitmap, 1 );
1225 sprintf( bbmname, "%s.bbm", AllBitmaps[i].name );
1226 iff_error = iff_read_bitmap(bbmname,new,BM_LINEAR,newpal);
1229 if (iff_error != IFF_NO_ERROR) {
1230 mprintf((1, "File %s - IFF error: %s",bbmname,iff_errormsg(iff_error)));
1231 Error("File %s - IFF error: %s",bbmname,iff_errormsg(iff_error));
1234 SuperX = (GameBitmapFlags[i]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1235 //above makes assumption that supertransparent color is 254
1237 if ( iff_has_transparency )
1238 gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
1240 gr_remap_bitmap_good( new, newpal, -1, SuperX );
1242 new->avg_color = compute_average_pixel(new);
1245 if ( FindArg("-macdata") )
1248 if ( !BigPig ) gr_bitmap_rle_compress( new );
1250 if (new->bm_flags & BM_FLAG_RLE)
1251 size = *((int *) new->bm_data);
1253 size = new->bm_w * new->bm_h;
1255 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],new->bm_data,size);
1256 d_free(new->bm_data);
1257 new->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1258 Piggy_bitmap_cache_next += size;
1260 GameBitmaps[i] = *new;
1264 // -- mprintf( (0, "U" ));
1268 //@@Dont' do these things which are done when writing
1269 //@@for (i=0; i < Num_bitmap_files; i++ ) {
1270 //@@ bitmap_index bi;
1272 //@@ PIGGY_PAGE_IN( bi );
1275 //@@piggy_close_file();
1277 piggy_write_pigfile(pigname);
1279 Current_pigfile[0] = 0; //say no pig, to force reload
1281 piggy_new_pigfile(pigname); //read in just-generated pig
1285 #endif //ifdef EDITOR
1289 ubyte bogus_data[64*64];
1290 grs_bitmap bogus_bitmap;
1291 ubyte bogus_bitmap_initialized=0;
1292 digi_sound bogus_sound;
1294 #define HAMFILE_ID MAKE_SIG('!','M','A','H') //HAM!
1295 #define HAMFILE_VERSION 3
1296 //version 1 -> 2: save marker_model_num
1297 //version 2 -> 3: removed sound files
1299 #define SNDFILE_ID MAKE_SIG('D','N','S','D') //DSND
1300 #define SNDFILE_VERSION 1
1304 CFILE * ham_fp = NULL;
1306 int sound_offset = 0;
1312 ham_fp = cfopen( DEFAULT_HAMFILE, "rb" );
1314 sprintf(name, ":Data:%s", DEFAULT_HAMFILE );
1315 ham_fp = cfopen( name, "rb" );
1318 if (ham_fp == NULL) {
1319 Must_write_hamfile = 1;
1323 //make sure ham is valid type file & is up-to-date
1324 ham_id = cfile_read_int(ham_fp);
1325 Piggy_hamfile_version = cfile_read_int(ham_fp);
1326 if (ham_id != HAMFILE_ID)
1327 Error("Cannot open ham file %s\n", DEFAULT_HAMFILE);
1329 if (ham_id != HAMFILE_ID || Piggy_hamfile_version != HAMFILE_VERSION) {
1330 Must_write_hamfile = 1;
1331 cfclose(ham_fp); //out of date ham
1336 if (Piggy_hamfile_version < 3) // hamfile contains sound info
1337 sound_offset = cfile_read_int(ham_fp);
1343 bm_read_all(ham_fp);
1344 cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1346 //for (i = 0; i < MAX_BITMAP_FILES; i++) {
1347 //GameBitmapXlat[i] = INTEL_SHORT(GameBitmapXlat[i]);
1348 //printf("GameBitmapXlat[%d] = %d\n", i, GameBitmapXlat[i]);
1353 if (Piggy_hamfile_version < 3) {
1358 DiskSoundHeader sndh;
1359 digi_sound temp_sound;
1360 char temp_name_read[16];
1363 cfseek(ham_fp, sound_offset, SEEK_SET);
1364 N_sounds = cfile_read_int(ham_fp);
1366 sound_start = cftell(ham_fp);
1368 header_size = N_sounds * DISKSOUNDHEADER_SIZE;
1372 for (i=0; i<N_sounds; i++ ) {
1373 DiskSoundHeader_read(&sndh, ham_fp);
1374 temp_sound.length = sndh.length;
1375 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1376 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1377 memcpy( temp_name_read, sndh.name, 8 );
1378 temp_name_read[8] = 0;
1379 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1381 if (piggy_is_needed(i))
1382 #endif // note link to if.
1383 sbytes += sndh.length;
1384 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1387 SoundBits = d_malloc( sbytes + 16 );
1388 if ( SoundBits == NULL )
1389 Error( "Not enough memory to load sounds\n" );
1391 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1393 // piggy_read_sounds(ham_fp);
1405 CFILE * snd_fp = NULL;
1406 int snd_id,snd_version;
1411 DiskSoundHeader sndh;
1412 digi_sound temp_sound;
1413 char temp_name_read[16];
1420 snd_fp = cfopen( DEFAULT_SNDFILE, "rb" );
1422 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1423 snd_fp = cfopen( name, "rb");
1429 //make sure soundfile is valid type file & is up-to-date
1430 snd_id = cfile_read_int(snd_fp);
1431 snd_version = cfile_read_int(snd_fp);
1432 if (snd_id != SNDFILE_ID || snd_version != SNDFILE_VERSION) {
1433 cfclose(snd_fp); //out of date sound file
1437 N_sounds = cfile_read_int(snd_fp);
1439 sound_start = cftell(snd_fp);
1440 size = cfilelength(snd_fp) - sound_start;
1442 mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
1444 header_size = N_sounds*sizeof(DiskSoundHeader);
1448 for (i=0; i<N_sounds; i++ ) {
1449 DiskSoundHeader_read(&sndh, snd_fp);
1450 //size -= sizeof(DiskSoundHeader);
1451 temp_sound.length = sndh.length;
1452 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1453 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1454 memcpy( temp_name_read, sndh.name, 8 );
1455 temp_name_read[8] = 0;
1456 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1458 if (piggy_is_needed(i))
1459 #endif // note link to if.
1460 sbytes += sndh.length;
1461 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1464 SoundBits = d_malloc( sbytes + 16 );
1465 if ( SoundBits == NULL )
1466 Error( "Not enough memory to load sounds\n" );
1468 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1470 // piggy_read_sounds(snd_fp);
1477 int piggy_init(void)
1479 int ham_ok=0,snd_ok=0;
1482 hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
1483 hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
1485 for (i=0; i<MAX_SOUND_FILES; i++ ) {
1486 GameSounds[i].length = 0;
1487 GameSounds[i].data = NULL;
1491 for (i=0; i<MAX_BITMAP_FILES; i++ )
1492 GameBitmapXlat[i] = i;
1494 if ( !bogus_bitmap_initialized ) {
1497 bogus_bitmap_initialized = 1;
1498 memset( &bogus_bitmap, 0, sizeof(grs_bitmap) );
1499 bogus_bitmap.bm_w = bogus_bitmap.bm_h = bogus_bitmap.bm_rowsize = 64;
1500 bogus_bitmap.bm_data = bogus_data;
1501 c = gr_find_closest_color( 0, 0, 63 );
1502 for (i=0; i<4096; i++ ) bogus_data[i] = c;
1503 c = gr_find_closest_color( 63, 0, 0 );
1504 // Make a big red X !
1505 for (i=0; i<64; i++ ) {
1506 bogus_data[i*64+i] = c;
1507 bogus_data[i*64+(63-i)] = c;
1509 piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
1510 bogus_sound.length = 64*64;
1511 bogus_sound.data = bogus_data;
1512 GameBitmapOffset[0] = 0;
1515 if ( FindArg( "-bigpig" ))
1518 if ( FindArg( "-lowmem" ))
1519 piggy_low_memory = 1;
1521 if ( FindArg( "-nolowmem" ))
1522 piggy_low_memory = 0;
1524 if (piggy_low_memory)
1527 WIN(DDGRLOCK(dd_grd_curcanv));
1528 gr_set_curfont( SMALL_FONT );
1529 gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
1530 gr_printf( 0x8000, grd_curcanv->cv_h-20, "%s...", TXT_LOADING_DATA );
1531 WIN(DDGRUNLOCK(dd_grd_curcanv));
1533 #if 1 //def EDITOR //need for d1 mission briefings
1534 piggy_init_pigfile(DEFAULT_PIGFILE);
1537 snd_ok = ham_ok = read_hamfile();
1539 if (Piggy_hamfile_version >= 3)
1540 snd_ok = read_sndfile();
1542 atexit(piggy_close);
1544 mprintf ((0,"HamOk=%d SndOk=%d\n",ham_ok,snd_ok));
1545 return (ham_ok && snd_ok); //read ok
1548 int piggy_is_needed(int soundnum)
1552 if ( !digi_lomem ) return 1;
1554 for (i=0; i<MAX_SOUNDS; i++ ) {
1555 if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
1562 void piggy_read_sounds(void)
1575 fp = cfopen( DEFAULT_SNDFILE, "rb" );
1577 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1578 fp = cfopen( name, "rb");
1584 for (i=0; i<Num_sound_files; i++ ) {
1585 digi_sound *snd = &GameSounds[i];
1587 if ( SoundOffset[i] > 0 ) {
1588 if ( piggy_is_needed(i) ) {
1589 cfseek( fp, SoundOffset[i], SEEK_SET );
1591 // Read in the sound data!!!
1594 sbytes += snd->length;
1595 cfread( snd->data, snd->length, 1, fp );
1598 snd->data = (ubyte *) -1;
1604 mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
1609 extern int descent_critical_error;
1610 extern unsigned descent_critical_deverror;
1611 extern unsigned descent_critical_errcode;
1613 char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
1614 "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
1615 "Read fault", "General Failure" };
1617 void piggy_critical_error()
1619 grs_canvas * save_canv;
1620 grs_font * save_font;
1622 save_canv = grd_curcanv;
1623 save_font = grd_curcanv->cv_font;
1624 gr_palette_load( gr_palette );
1625 i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A' );
1628 gr_set_current_canvas(save_canv);
1629 grd_curcanv->cv_font = save_font;
1632 void piggy_bitmap_page_in( bitmap_index bitmap )
1641 Assert( i < MAX_BITMAP_FILES );
1642 Assert( i < Num_bitmap_files );
1643 Assert( Piggy_bitmap_cache_size > 0 );
1645 if ( i < 1 ) return;
1646 if ( i >= MAX_BITMAP_FILES ) return;
1647 if ( i >= Num_bitmap_files ) return;
1649 if ( GameBitmapOffset[i] == 0 ) return; // A read-from-disk bitmap!!!
1651 if ( piggy_low_memory ) {
1653 i = GameBitmapXlat[i]; // Xlat for low-memory settings!
1656 bmp = &GameBitmaps[i];
1658 if ( bmp->bm_flags & BM_FLAG_PAGED_OUT ) {
1662 descent_critical_error = 0;
1663 cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
1664 if ( descent_critical_error ) {
1665 piggy_critical_error();
1669 bmp->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1670 bmp->bm_flags = GameBitmapFlags[i];
1672 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1674 descent_critical_error = 0;
1675 zsize = cfile_read_int(Piggy_fp);
1676 if ( descent_critical_error ) {
1677 piggy_critical_error();
1681 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1682 //Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );
1683 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1685 piggy_bitmap_page_out_all();
1688 descent_critical_error = 0;
1689 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next+4], 1, zsize-4, Piggy_fp );
1690 if ( descent_critical_error ) {
1691 piggy_critical_error();
1696 switch (cfilelength(Piggy_fp)) {
1698 if (!FindArg("-macdata"))
1700 // otherwise, fall through...
1701 case MAC_ALIEN1_PIGSIZE:
1702 case MAC_ALIEN2_PIGSIZE:
1703 case MAC_FIRE_PIGSIZE:
1704 case MAC_GROUPA_PIGSIZE:
1705 case MAC_ICE_PIGSIZE:
1706 case MAC_WATER_PIGSIZE:
1707 rle_swap_0_255( bmp );
1708 memcpy(&zsize, bmp->bm_data, 4);
1713 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
1714 Piggy_bitmap_cache_next += zsize;
1715 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1717 piggy_bitmap_page_out_all();
1722 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1723 Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );
1724 if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) {
1725 piggy_bitmap_page_out_all();
1728 descent_critical_error = 0;
1729 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
1730 if ( descent_critical_error ) {
1731 piggy_critical_error();
1734 Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
1737 switch (cfilelength(Piggy_fp)) {
1739 if (!FindArg("-macdata"))
1741 // otherwise, fall through...
1742 case MAC_ALIEN1_PIGSIZE:
1743 case MAC_ALIEN2_PIGSIZE:
1744 case MAC_FIRE_PIGSIZE:
1745 case MAC_GROUPA_PIGSIZE:
1746 case MAC_ICE_PIGSIZE:
1747 case MAC_WATER_PIGSIZE:
1754 //@@if ( bmp->bm_selector ) {
1755 //@@#if !defined(WINDOWS) && !defined(MACINTOSH)
1756 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1757 //@@ Error( "Error modifying selector base in piggy.c\n" );
1764 if ( piggy_low_memory ) {
1766 GameBitmaps[org_i] = GameBitmaps[i];
1769 //@@Removed from John's code:
1771 //@@ if ( bmp->bm_selector ) {
1772 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1773 //@@ Error( "Error modifying selector base in piggy.c\n" );
1779 void piggy_bitmap_page_out_all()
1783 Piggy_bitmap_cache_next = 0;
1785 piggy_page_flushed++;
1790 for (i=0; i<Num_bitmap_files; i++ ) {
1791 if ( GameBitmapOffset[i] > 0 ) { // Don't page out bitmaps read from disk!!!
1792 GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
1793 GameBitmaps[i].bm_data = Piggy_bitmap_cache_data;
1797 mprintf(( 0, "Flushing piggy bitmap cache\n" ));
1800 void piggy_load_level_data()
1802 piggy_bitmap_page_out_all();
1808 void change_filename_ext( char *dest, char *src, char *ext );
1810 void piggy_write_pigfile(char *filename)
1813 int bitmap_data_start,data_offset;
1814 DiskBitmapHeader bmh;
1816 char subst_name[32];
1819 char tname[FILENAME_LEN];
1821 // -- mprintf( (0, "Paging in all piggy bitmaps..." ));
1822 for (i=0; i < Num_bitmap_files; i++ ) {
1825 PIGGY_PAGE_IN( bi );
1827 // -- mprintf( (0, "\n" ));
1831 // -- mprintf( (0, "Creating %s...",filename ));
1833 pig_fp = fopen( filename, "wb" ); //open PIG file
1834 Assert( pig_fp!=NULL );
1836 write_int(PIGFILE_ID,pig_fp);
1837 write_int(PIGFILE_VERSION,pig_fp);
1840 fwrite( &Num_bitmap_files, sizeof(int), 1, pig_fp );
1843 bitmap_data_start = ftell(pig_fp);
1844 bitmap_data_start += (Num_bitmap_files-1)*DISKBITMAPHEADER_SIZE;
1845 data_offset = bitmap_data_start;
1847 change_filename_ext(tname,filename,"lst");
1848 fp1 = fopen( tname, "wt" );
1849 change_filename_ext(tname,filename,"all");
1850 fp2 = fopen( tname, "wt" );
1852 for (i=1; i < Num_bitmap_files; i++ ) {
1858 p = strchr(AllBitmaps[i].name,'#');
1865 fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
1866 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1868 bmh.dflags = DBM_FLAG_ABM + n;
1872 fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
1873 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1877 bmp = &GameBitmaps[i];
1879 Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
1882 fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
1883 org_offset = ftell(pig_fp);
1884 bmh.offset = data_offset - bitmap_data_start;
1885 fseek( pig_fp, data_offset, SEEK_SET );
1887 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1888 size = (int *)bmp->bm_data;
1889 fwrite( bmp->bm_data, sizeof(ubyte), *size, pig_fp );
1890 data_offset += *size;
1892 fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
1894 fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, pig_fp );
1895 data_offset += bmp->bm_rowsize * bmp->bm_h;
1897 fprintf( fp1, ".\n" );
1899 fseek( pig_fp, org_offset, SEEK_SET );
1900 Assert( GameBitmaps[i].bm_w < 4096 );
1901 bmh.width = (GameBitmaps[i].bm_w & 0xff);
1902 bmh.wh_extra = ((GameBitmaps[i].bm_w >> 8) & 0x0f);
1903 Assert( GameBitmaps[i].bm_h < 4096 );
1904 bmh.height = GameBitmaps[i].bm_h;
1905 bmh.wh_extra |= ((GameBitmaps[i].bm_h >> 4) & 0xf0);
1906 bmh.flags = GameBitmaps[i].bm_flags;
1907 if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name )) {
1908 bitmap_index other_bitmap;
1909 other_bitmap = piggy_find_bitmap( subst_name );
1910 GameBitmapXlat[i] = other_bitmap.index;
1911 bmh.flags |= BM_FLAG_PAGED_OUT;
1912 //mprintf(( 0, "Skipping bitmap %d\n", i ));
1913 //mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
1915 bmh.flags &= ~BM_FLAG_PAGED_OUT;
1917 bmh.avg_color=GameBitmaps[i].avg_color;
1918 fwrite( &bmh, DISKBITMAPHEADER_SIZE, 1, pig_fp ); // Mark as a bitmap
1923 mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
1924 fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
1931 static void write_int(int i,FILE *file)
1933 if (fwrite( &i, sizeof(i), 1, file) != 1)
1934 Error( "Error reading int in gamesave.c" );
1938 void piggy_dump_all()
1942 int org_offset,data_offset=0;
1943 DiskSoundHeader sndh;
1944 int sound_data_start=0;
1947 #ifdef NO_DUMP_SOUNDS
1948 Num_sound_files = 0;
1949 Num_sound_files_new = 0;
1952 if (!Must_write_hamfile && (Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
1955 fp1 = fopen( "ham.lst", "wt" );
1956 fp2 = fopen( "ham.all", "wt" );
1958 if (Must_write_hamfile || Num_bitmap_files_new) {
1960 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1962 ham_fp = fopen( DEFAULT_HAMFILE, "wb" ); //open HAM file
1963 Assert( ham_fp!=NULL );
1965 write_int(HAMFILE_ID,ham_fp);
1966 write_int(HAMFILE_VERSION,ham_fp);
1968 bm_write_all(ham_fp);
1969 xlat_offset = ftell(ham_fp);
1970 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1973 if (Num_bitmap_files_new)
1974 piggy_write_pigfile(DEFAULT_PIGFILE);
1976 //free up memeory used by new bitmaps
1977 for (i=Num_bitmap_files-Num_bitmap_files_new;i<Num_bitmap_files;i++)
1978 d_free(GameBitmaps[i].bm_data);
1980 //next thing must be done after pig written
1981 fseek( ham_fp, xlat_offset, SEEK_SET );
1982 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1985 mprintf( (0, "\n" ));
1988 if (Num_sound_files_new) {
1990 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1991 // Now dump sound file
1992 ham_fp = fopen( DEFAULT_SNDFILE, "wb" );
1993 Assert( ham_fp!=NULL );
1995 write_int(SNDFILE_ID,ham_fp);
1996 write_int(SNDFILE_VERSION,ham_fp);
1998 fwrite( &Num_sound_files, sizeof(int), 1, ham_fp );
2000 mprintf( (0, "\nDumping sounds..." ));
2002 sound_data_start = ftell(ham_fp);
2003 sound_data_start += Num_sound_files*sizeof(DiskSoundHeader);
2004 data_offset = sound_data_start;
2006 for (i=0; i < Num_sound_files; i++ ) {
2009 snd = &GameSounds[i];
2010 strcpy( sndh.name, AllSounds[i].name );
2011 sndh.length = GameSounds[i].length;
2012 sndh.offset = data_offset - sound_data_start;
2014 org_offset = ftell(ham_fp);
2015 fseek( ham_fp, data_offset, SEEK_SET );
2017 sndh.data_length = GameSounds[i].length;
2018 fwrite( snd->data, sizeof(ubyte), snd->length, ham_fp );
2019 data_offset += snd->length;
2020 fseek( ham_fp, org_offset, SEEK_SET );
2021 fwrite( &sndh, sizeof(DiskSoundHeader), 1, ham_fp ); // Mark as a bitmap
2023 fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
2024 fprintf( fp2, "%s.raw\n", AllSounds[i].name );
2028 mprintf( (0, "\n" ));
2031 fprintf( fp1, "Total sound size: %d bytes\n", data_offset-sound_data_start);
2032 mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
2033 fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
2038 // Never allow the game to run after building ham.
2052 d_free( SoundBits );
2054 hashtable_free( &AllBitmapsNames );
2055 hashtable_free( &AllDigiSndNames );
2059 int piggy_does_bitmap_exist_slow( char * name )
2063 for (i=0; i<Num_bitmap_files; i++ ) {
2064 if ( !strcmp( AllBitmaps[i].name, name) )
2071 #define NUM_GAUGE_BITMAPS 23
2072 char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = {
2073 "gauge01", "gauge01b",
2074 "gauge02", "gauge02b",
2075 "gauge06", "gauge06b",
2076 "targ01", "targ01b",
2077 "targ02", "targ02b",
2078 "targ03", "targ03b",
2079 "targ04", "targ04b",
2080 "targ05", "targ05b",
2081 "targ06", "targ06b",
2082 "gauge18", "gauge18b",
2088 int piggy_is_gauge_bitmap( char * base_name )
2091 for (i=0; i<NUM_GAUGE_BITMAPS; i++ ) {
2092 if ( !stricmp( base_name, gauge_bitmap_names[i] ))
2099 int piggy_is_substitutable_bitmap( char * name, char * subst_name )
2103 char base_name[ 16 ];
2105 strcpy( subst_name, name );
2106 p = strchr( subst_name, '#' );
2108 frame = atoi( &p[1] );
2110 strcpy( base_name, subst_name );
2111 if ( !piggy_is_gauge_bitmap( base_name )) {
2112 sprintf( subst_name, "%s#%d", base_name, frame+1 );
2113 if ( piggy_does_bitmap_exist_slow( subst_name ) ) {
2115 sprintf( subst_name, "%s#%d", base_name, frame-1 );
2121 strcpy( subst_name, name );
2128 // New Windows stuff
2130 // windows bitmap page in
2131 // Page in a bitmap, if ddraw, then page it into a ddsurface in
2132 // 'video' memory. if that fails, page it in normally.
2134 void piggy_bitmap_page_in_w( bitmap_index bitmap, int ddraw )
2139 // Essential when switching video modes!
2141 void piggy_bitmap_page_out_all_w()
2149 * Functions for loading replacement textures
2150 * 1) From .pog files
2151 * 2) From descent.pig (for loading d1 levels)
2154 extern void change_filename_extension( char *dest, char *src, char *new_ext );
2155 extern char last_palette_loaded_pig[];
2157 void free_bitmap_replacements()
2159 if (Bitmap_replacement_data) {
2160 d_free(Bitmap_replacement_data);
2161 Bitmap_replacement_data = NULL;
2165 void load_bitmap_replacements(char *level_name)
2167 char ifile_name[FILENAME_LEN];
2171 //first, free up data allocated for old bitmaps
2172 free_bitmap_replacements();
2174 change_filename_extension(ifile_name, level_name, ".POG" );
2176 ifile = cfopen(ifile_name,"rb");
2179 int id,version,n_bitmaps;
2180 int bitmap_data_size;
2183 id = cfile_read_int(ifile);
2184 version = cfile_read_int(ifile);
2186 if (id != MAKE_SIG('G','O','P','D') || version != 1) {
2191 n_bitmaps = cfile_read_int(ifile);
2193 MALLOC( indices, ushort, n_bitmaps );
2195 for (i = 0; i < n_bitmaps; i++)
2196 indices[i] = cfile_read_short(ifile);
2198 bitmap_data_size = cfilelength(ifile) - cftell(ifile) - DISKBITMAPHEADER_SIZE * n_bitmaps;
2199 MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
2201 for (i=0;i<n_bitmaps;i++) {
2202 DiskBitmapHeader bmh;
2203 grs_bitmap temp_bitmap;
2205 DiskBitmapHeader_read(&bmh, ifile);
2207 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2209 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2210 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2211 temp_bitmap.avg_color = bmh.avg_color;
2212 temp_bitmap.bm_data = Bitmap_replacement_data + bmh.offset;
2214 temp_bitmap.bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2216 GameBitmaps[indices[i]] = temp_bitmap;
2217 // don't we need the following? GameBitmapOffset[indices[i]] = 0; // don't try to read bitmap from current pigfile
2220 cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
2226 last_palette_loaded_pig[0]= 0; //force pig re-load
2228 texmerge_flush(); //for re-merging with new textures
2231 atexit(free_bitmap_replacements);
2234 /* If the given d1_index is the index of a bitmap we have to load (because it is unique
2235 * to descent 1), then returns which d2_index it replaces.
2236 * Returns -1 if the given d1_index is not unique to descent 1.
2238 short d2_index_for_d1_index(short d1_index)
2241 int d1_tmap_num = -1;
2242 if (d1_Texture_indices)
2243 for (i = 0; i < D1_MAX_TEXTURES; i++)
2244 if (d1_Texture_indices[i] == d1_index) {
2248 if (d1_tmap_num == -1 || ! d1_tmap_num_unique(d1_tmap_num))
2251 return Textures[convert_d1_tmap_num(d1_tmap_num)].index;
2255 void load_d1_bitmap_replacements()
2257 CFILE * d1_Piggy_fp;
2258 grs_bitmap temp_bitmap;
2259 DiskBitmapHeader bmh;
2260 int pig_data_start, bitmap_header_start, bitmap_data_start;
2261 int N_bitmaps, zsize;
2262 short d1_index, d2_index;
2263 ubyte colormap[256];
2264 ubyte *next_bitmap; // to which address we write the next bitmap
2266 d1_Piggy_fp = cfopen( D1_PIGFILE, "rb" );
2268 #define D1_PIG_LOAD_FAILED "Failed loading " D1_PIGFILE
2270 Warning(D1_PIG_LOAD_FAILED);
2274 //first, free up data allocated for old bitmaps
2275 free_bitmap_replacements();
2277 // read d1 palette, build colormap
2280 ubyte d1_palette[256*3];
2281 CFILE * palette_file = cfopen(D1_PALETTE, "rb" );
2282 Assert( palette_file );
2283 Assert( cfilelength( palette_file ) == 9472 );
2284 cfread( d1_palette, 256, 3, palette_file);
2285 cfclose( palette_file );
2286 build_colormap_good( d1_palette, colormap, freq );
2287 // don't change transparencies:
2288 colormap[254] = 254;
2289 colormap[255] = 255;
2292 switch (cfilelength(d1_Piggy_fp)) {
2293 case D1_SHAREWARE_10_PIGSIZE:
2294 case D1_SHAREWARE_PIGSIZE:
2296 Warning(D1_PIG_LOAD_FAILED " Support for descent.pig of descent 1 shareware not complete.");
2300 Warning("Unknown size for " D1_PIGFILE);
2303 case D1_OEM_PIGSIZE:
2304 case D1_MAC_PIGSIZE:
2305 case D1_MAC_SHARE_PIGSIZE:
2306 pig_data_start = cfile_read_int(d1_Piggy_fp );
2307 bm_read_d1_texture_indices(d1_Piggy_fp); //was: bm_read_all_d1(fp);
2308 //for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2312 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2313 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2315 int N_sounds = cfile_read_int(d1_Piggy_fp);
2316 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2317 + N_sounds * DISKSOUNDHEADER_SIZE;
2318 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2319 bitmap_data_start = bitmap_header_start + header_size;
2322 #define D1_BITMAPS_SIZE 300000
2323 MALLOC( Bitmap_replacement_data, ubyte, D1_BITMAPS_SIZE);
2324 if (!Bitmap_replacement_data) {
2325 Warning(D1_PIG_LOAD_FAILED);
2328 atexit(free_bitmap_replacements);
2330 next_bitmap = Bitmap_replacement_data;
2332 for (d1_index = 1; d1_index <= N_bitmaps; d1_index++ ) {
2333 d2_index = d2_index_for_d1_index(d1_index);
2334 // only change bitmaps which are unique to d1
2335 if (d2_index != -1) {
2336 cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2337 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2339 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2341 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2342 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2343 temp_bitmap.avg_color = bmh.avg_color;
2345 //GameBitmapFlags[d2_index] = 0;
2347 temp_bitmap.bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2349 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2350 if (bmh.flags & BM_FLAG_RLE) {
2351 zsize = cfile_read_int(d1_Piggy_fp);
2352 cfseek(d1_Piggy_fp, -4, SEEK_CUR);
2354 zsize = temp_bitmap.bm_h * temp_bitmap.bm_w;
2356 Assert(next_bitmap + zsize - Bitmap_replacement_data < D1_BITMAPS_SIZE);
2357 cfread(next_bitmap, 1, zsize, d1_Piggy_fp);
2359 temp_bitmap.bm_data = next_bitmap;
2361 switch(cfilelength(d1_Piggy_fp)) {
2362 case D1_MAC_PIGSIZE:
2363 case D1_MAC_SHARE_PIGSIZE:
2364 if (bmh.flags & BM_FLAG_RLE)
2365 rle_swap_0_255(&temp_bitmap);
2367 swap_0_255(&temp_bitmap);
2369 if (bmh.flags & BM_FLAG_RLE)
2370 rle_remap(&temp_bitmap, colormap);
2372 gr_remap_bitmap_good(&temp_bitmap, colormap, TRANSPARENCY_COLOR, -1);
2374 GameBitmaps[d2_index] = temp_bitmap;
2375 GameBitmapOffset[d2_index] = 0; // don't try to read bitmap from current d2 pigfile
2376 GameBitmapFlags[d2_index] = bmh.flags;
2377 if (bmh.flags & BM_FLAG_RLE)
2378 memcpy(&zsize, temp_bitmap.bm_data, 4);
2379 next_bitmap += zsize;
2380 Assert(next_bitmap - Bitmap_replacement_data < D1_BITMAPS_SIZE);
2384 cfclose(d1_Piggy_fp);
2386 last_palette_loaded_pig[0]= 0; //force pig re-load
2388 texmerge_flush(); //for re-merging with new textures
2392 extern int extra_bitmap_num;
2395 * Find and load the named bitmap from descent.pig
2396 * similar to read_extra_bitmap_iff
2398 bitmap_index read_extra_bitmap_d1_pig(char *name)
2400 bitmap_index bitmap_num;
2401 grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2403 bitmap_num.index = 0;
2408 DiskBitmapHeader bmh;
2409 int pig_data_start, bitmap_header_start, bitmap_data_start;
2410 int N_bitmaps, zsize;
2411 ubyte colormap[256];
2413 d1_Piggy_fp = cfopen(D1_PIGFILE, "rb");
2416 con_printf(CON_DEBUG, "could not open %s\n", D1_PIGFILE);
2420 // read d1 palette, build colormap
2423 ubyte d1_palette[256*3];
2424 CFILE * palette_file = cfopen(D1_PALETTE, "rb");
2425 if (!palette_file || cfilelength(palette_file) != 9472)
2427 con_printf(CON_DEBUG, "could not open %s\n", D1_PALETTE);
2430 cfread( d1_palette, 256, 3, palette_file);
2431 cfclose( palette_file );
2432 build_colormap_good( d1_palette, colormap, freq );
2433 // don't change transparencies:
2434 colormap[254] = 254;
2435 colormap[255] = 255;
2438 switch (cfilelength(d1_Piggy_fp)) {
2439 case D1_SHAREWARE_10_PIGSIZE:
2440 case D1_SHAREWARE_PIGSIZE:
2446 case D1_OEM_PIGSIZE:
2447 case D1_MAC_PIGSIZE:
2448 case D1_MAC_SHARE_PIGSIZE:
2449 pig_data_start = cfile_read_int(d1_Piggy_fp);
2453 cfseek(d1_Piggy_fp, pig_data_start, SEEK_SET);
2454 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2456 int N_sounds = cfile_read_int(d1_Piggy_fp);
2457 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2458 + N_sounds * DISKSOUNDHEADER_SIZE;
2459 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2460 bitmap_data_start = bitmap_header_start + header_size;
2463 for (i = 0; i < N_bitmaps; i++)
2465 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2466 if (!strnicmp(bmh.name, name, 8))
2470 if (strnicmp(bmh.name, name, 8))
2472 con_printf(CON_DEBUG, "could not find bitmap %s\n", name);
2476 memset( new, 0, sizeof(grs_bitmap) );
2478 new->bm_w = new->bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2479 new->bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2480 new->avg_color = bmh.avg_color;
2482 new->bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2484 if ( bmh.flags & BM_FLAG_RLE )
2486 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2487 zsize = cfile_read_int(d1_Piggy_fp);
2490 zsize = new->bm_w * new->bm_h;
2491 new->bm_data = d_malloc(zsize);
2492 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2493 cfread(new->bm_data, 1, zsize, d1_Piggy_fp);
2495 switch(cfilelength(d1_Piggy_fp)) {
2496 case D1_MAC_PIGSIZE:
2497 case D1_MAC_SHARE_PIGSIZE:
2498 rle_swap_0_255(new);
2500 rle_remap(new, colormap);
2502 cfclose(d1_Piggy_fp);
2505 new->avg_color = 0; //compute_average_pixel(new);
2507 bitmap_num.index = extra_bitmap_num;
2509 GameBitmaps[extra_bitmap_num++] = *new;
2515 #ifndef FAST_FILE_IO
2517 * reads a bitmap_index structure from a CFILE
2519 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2521 bi->index = cfile_read_short(fp);
2525 * reads n bitmap_index structs from a CFILE
2527 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2531 for (i = 0; i < n; i++)
2532 bi[i].index = cfile_read_short(fp);
2537 * reads a DiskBitmapHeader structure from a CFILE
2539 void DiskBitmapHeader_read(DiskBitmapHeader *dbh, CFILE *fp)
2541 cfread(dbh->name, 8, 1, fp);
2542 dbh->dflags = cfile_read_byte(fp);
2543 dbh->width = cfile_read_byte(fp);
2544 dbh->height = cfile_read_byte(fp);
2545 dbh->wh_extra = cfile_read_byte(fp);
2546 dbh->flags = cfile_read_byte(fp);
2547 dbh->avg_color = cfile_read_byte(fp);
2548 dbh->offset = cfile_read_int(fp);
2552 * reads a DiskSoundHeader structure from a CFILE
2554 void DiskSoundHeader_read(DiskSoundHeader *dsh, CFILE *fp)
2556 cfread(dsh->name, 8, 1, fp);
2557 dsh->length = cfile_read_int(fp);
2558 dsh->data_length = cfile_read_int(fp);
2559 dsh->offset = cfile_read_int(fp);
2561 #endif // FAST_FILE_IO
2564 * reads a descent 1 DiskBitmapHeader structure from a CFILE
2566 void DiskBitmapHeader_d1_read(DiskBitmapHeader *dbh, CFILE *fp)
2568 cfread(dbh->name, 8, 1, fp);
2569 dbh->dflags = cfile_read_byte(fp);
2570 dbh->width = cfile_read_byte(fp);
2571 dbh->height = cfile_read_byte(fp);
2573 dbh->flags = cfile_read_byte(fp);
2574 dbh->avg_color = cfile_read_byte(fp);
2575 dbh->offset = cfile_read_int(fp);