1 /* $Id: piggy.c,v 1.28 2003-03-25 09:54:12 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.28 2003-03-25 09:54:12 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 DEFAULT_PIGFILE (cfexist(DEFAULT_PIGFILE_REGISTERED)?DEFAULT_PIGFILE_REGISTERED:DEFAULT_PIGFILE_SHAREWARE)
441 #define DEFAULT_HAMFILE (cfexist(DEFAULT_HAMFILE_REGISTERED)?DEFAULT_HAMFILE_REGISTERED:DEFAULT_HAMFILE_SHAREWARE)
442 #define DEFAULT_SNDFILE ((Piggy_hamfile_version < 3)?DEFAULT_HAMFILE_SHAREWARE:(digi_sample_rate==SAMPLE_RATE_22K)?"descent2.s22":"descent2.s11")
444 ubyte *BitmapBits = NULL;
445 ubyte *SoundBits = NULL;
447 typedef struct BitmapFile {
451 typedef struct SoundFile {
455 hashtable AllBitmapsNames;
456 hashtable AllDigiSndNames;
458 int Num_bitmap_files = 0;
459 int Num_sound_files = 0;
461 digi_sound GameSounds[MAX_SOUND_FILES];
462 int SoundOffset[MAX_SOUND_FILES];
463 grs_bitmap GameBitmaps[MAX_BITMAP_FILES];
465 alias alias_list[MAX_ALIASES];
468 int Must_write_hamfile = 0;
469 int Num_bitmap_files_new = 0;
470 int Num_sound_files_new = 0;
471 BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
472 static SoundFile AllSounds[ MAX_SOUND_FILES ];
474 int Piggy_hamfile_version = 0;
476 int piggy_low_memory = 0;
478 int Piggy_bitmap_cache_size = 0;
479 int Piggy_bitmap_cache_next = 0;
480 ubyte * Piggy_bitmap_cache_data = NULL;
481 static int GameBitmapOffset[MAX_BITMAP_FILES];
482 static ubyte GameBitmapFlags[MAX_BITMAP_FILES];
483 ushort GameBitmapXlat[MAX_BITMAP_FILES];
485 #define PIGGY_BUFFER_SIZE (2400*1024)
488 #define PIGGY_SMALL_BUFFER_SIZE (1400*1024) // size of buffer when piggy_low_memory is set
491 #undef PIGGY_BUFFER_SIZE
492 #undef PIGGY_SMALL_BUFFER_SIZE
494 #define PIGGY_BUFFER_SIZE (2000*1024)
495 #define PIGGY_SMALL_BUFFER_SIZE (1100 * 1024)
500 int piggy_page_flushed = 0;
502 #define DBM_FLAG_ABM 64
507 extern short cd_VRefNum;
508 extern void ConcatPStr(StringPtr dst, StringPtr src);
509 extern int ConvertPToCStr(StringPtr inPStr, char* outCStrBuf);
510 extern int ConvertCToPStr(char* inCStr, StringPtr outPStrBuf);
513 int piggy_is_substitutable_bitmap( char * name, char * subst_name );
516 void piggy_write_pigfile(char *filename);
517 static void write_int(int i,FILE *file);
520 void swap_0_255(grs_bitmap *bmp)
524 for (i = 0; i < bmp->bm_h * bmp->bm_w; i++) {
525 if(bmp->bm_data[i] == 0)
526 bmp->bm_data[i] = 255;
527 else if (bmp->bm_data[i] == 255)
532 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
535 Assert( Num_bitmap_files < MAX_BITMAP_FILES );
537 temp.index = Num_bitmap_files;
541 if ( FindArg("-macdata") )
544 if ( !BigPig ) gr_bitmap_rle_compress( bmp );
545 Num_bitmap_files_new++;
548 strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
549 hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
550 GameBitmaps[Num_bitmap_files] = *bmp;
552 GameBitmapOffset[Num_bitmap_files] = 0;
553 GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
560 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
564 Assert( Num_sound_files < MAX_SOUND_FILES );
566 strncpy( AllSounds[Num_sound_files].name, name, 12 );
567 hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
568 GameSounds[Num_sound_files] = *snd;
570 SoundOffset[Num_sound_files] = 0;
576 Num_sound_files_new++;
582 bitmap_index piggy_find_bitmap( char * name )
590 if ((t=strchr(name,'#'))!=NULL)
593 for (i=0;i<Num_aliases;i++)
594 if (stricmp(name,alias_list[i].alias_name)==0) {
595 if (t) { //extra stuff for ABMs
596 static char temp[FILENAME_LEN];
597 _splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
603 name=alias_list[i].file_name;
610 i = hashtable_search( &AllBitmapsNames, name );
619 int piggy_find_sound( char * name )
623 i = hashtable_search( &AllDigiSndNames, name );
631 CFILE * Piggy_fp = NULL;
633 #define FILENAME_LEN 13
635 char Current_pigfile[FILENAME_LEN] = "";
637 void piggy_close_file()
642 Current_pigfile[0] = 0;
646 int Pigfile_initialized=0;
648 #define PIGFILE_ID MAKE_SIG('G','I','P','P') //PPIG
649 #define PIGFILE_VERSION 2
651 extern char CDROM_dir[];
653 int request_cd(void);
658 //copies a pigfile from the CD to the current dir
659 //retuns file handle of new pig
660 CFILE *copy_pigfile_from_cd(char *filename) // MACINTOSH VERSION
663 char sourcePathAndFileCStr[255] = "";
664 char destPathAndFileCStr[255] = "";
666 FILE* sourceFile = NULL;
667 FILE* destFile = NULL;
668 const int BUF_SIZE = 4096;
672 Str255 sourcePathAndFilePStr = "\p";
673 Str255 destPathAndFilePStr = "\p";
674 Str255 pigfileNamePStr = "\p";
675 HParamBlockRec theSourcePigHFSParams;
676 HParamBlockRec theDestPigHFSParams;
677 OSErr theErr = noErr;
678 char oldDirCStr[255] = "";
680 getcwd(oldDirCStr, 255);
682 show_boxed_message("Copying bitmap data from CD...");
683 gr_palette_load(gr_palette); //I don't think this line is really needed
686 //First, delete all PIG files currently in the directory
687 if( !FileFindFirst( "*.pig", &find ) )
692 } while( !FileFindNext( &find ) );
698 //Now, copy over new pig
699 songs_stop_redbook(); //so we can read off the cd
701 // make the source path "<cd volume>:Data:filename.pig"
702 //MWA ConvertCToPStr(filename, pigfileNamePStr);
704 //MWA ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:"); // volume ID is cd_VRefNum
705 //MWA ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
708 strcpy(sourcePathAndFileCStr, "Descent II:Data:");
709 strcat(sourcePathAndFileCStr, filename);
711 // make the destination path "<default directory>:Data:filename.pig"
712 //MWA ConcatPStr(destPathAndFilePStr, "\p:Data:");
713 //MWA ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
714 //MWA ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
715 //MWA ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
717 strcpy(destPathAndFileCStr, ":Data:");
718 strcat(destPathAndFileCStr, filename);
720 strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
721 strcpy(destPathAndFilePStr, destPathAndFileCStr);
722 c2pstr(sourcePathAndFilePStr);
723 c2pstr(destPathAndFilePStr);
726 // Open the source file
727 sourceFile = fopen(sourcePathAndFileCStr,"rb");
731 if (request_cd() == -1)
732 Error("Cannot load file <%s> from CD",filename);
735 } while (!sourceFile);
738 // Get the time stamp from the source file
739 theSourcePigHFSParams.fileParam.ioCompletion = nil;
740 theSourcePigHFSParams.fileParam.ioNamePtr = sourcePathAndFilePStr;
741 theSourcePigHFSParams.fileParam.ioVRefNum = cd_VRefNum;
742 theSourcePigHFSParams.fileParam.ioFDirIndex = 0;
743 theSourcePigHFSParams.fileParam.ioDirID = 0;
745 theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
748 // Error getting file time stamp!! Why? JTS
749 Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
752 // Copy the file over
755 // Open the destination file
756 destFile = fopen(destPathAndFileCStr,"wb");
759 Error("Cannot create file: <%s>\n", destPathAndFileCStr);
762 // Copy bytes until the end of the source file
763 while (!feof(sourceFile))
768 bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
769 if (ferror(sourceFile))
770 Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
772 // Assert is bogus Assert(bytes_read == BUF_SIZE || feof(sourceFile));
774 fwrite(buf,1,bytes_read,destFile);
775 if (ferror(destFile))
776 Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
779 // close the source/dest files
780 if (fclose(sourceFile))
781 Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
782 if (fclose(destFile))
783 Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
785 // Get the current hfs data for the new file
786 theDestPigHFSParams.fileParam.ioCompletion = nil;
787 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
788 theDestPigHFSParams.fileParam.ioVRefNum = 0;
789 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
790 theDestPigHFSParams.fileParam.ioDirID = 0;
791 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
792 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
794 // Error getting file time stamp!! Why? JTS
795 Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
798 // Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
799 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
800 theDestPigHFSParams.fileParam.ioVRefNum = 0;
801 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
802 theDestPigHFSParams.fileParam.ioDirID = 0;
804 // Copy the time stamp from the source file info
805 theDestPigHFSParams.fileParam.ioFlCrDat = theSourcePigHFSParams.fileParam.ioFlCrDat;
806 theDestPigHFSParams.fileParam.ioFlMdDat = theSourcePigHFSParams.fileParam.ioFlMdDat;
807 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
808 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
810 // Set the dest file's time stamp to the source file's time stamp values
811 theErr = PBHSetFInfo(&theDestPigHFSParams, false);
813 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
815 Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
818 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
820 return cfopen(destPathAndFileCStr, "rb");
823 #else //PC Version of copy_pigfile_from_cd is below
825 //copies a pigfile from the CD to the current dir
826 //retuns file handle of new pig
827 CFILE *copy_pigfile_from_cd(char *filename)
833 return cfopen(filename, "rb");
834 show_boxed_message("Copying bitmap data from CD...");
835 gr_palette_load(gr_palette); //I don't think this line is really needed
837 //First, delete all PIG files currently in the directory
839 if( !FileFindFirst( "*.pig", &find ) ) {
842 } while( !FileFindNext( &find ) );
846 //Now, copy over new pig
848 songs_stop_redbook(); //so we can read off the cd
850 //new code to unarj file
851 strcpy(name,CDROM_dir);
852 strcat(name,"descent2.sow");
855 // ret = unarj_specific_file(name,filename,filename);
860 if (ret != EXIT_SUCCESS) {
862 //delete file, so we don't leave partial file
866 if (request_cd() == -1)
868 //NOTE LINK TO ABOVE IF
869 Error("Cannot load file <%s> from CD",filename);
872 } while (ret != EXIT_SUCCESS);
874 return cfopen(filename, "rb");
877 #endif // end of ifdef MAC around copy_pigfile_from_cd
879 //initialize a pigfile, reading headers
880 //returns the size of all the bitmap data
881 void piggy_init_pigfile(char *filename)
885 char temp_name_read[16];
886 grs_bitmap temp_bitmap;
887 DiskBitmapHeader bmh;
888 int header_size, N_bitmaps, data_size, data_start;
890 char name[255]; // filename + path for the mac
893 piggy_close_file(); //close old pig if still open
895 //rename pigfile for shareware
896 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
897 filename = DEFAULT_PIGFILE_SHAREWARE;
900 Piggy_fp = cfopen( filename, "rb" );
902 sprintf(name, ":Data:%s", filename);
903 Piggy_fp = cfopen( name, "rb" );
905 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
906 if (Piggy_fp == NULL)
908 Error("Cannot load required file <%s>",name);
910 #endif // end of if def shareware
916 return; //if editor, ok to not have pig, because we'll build one
918 Piggy_fp = copy_pigfile_from_cd(filename);
922 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
923 int pig_id,pig_version;
925 pig_id = cfile_read_int(Piggy_fp);
926 pig_version = cfile_read_int(Piggy_fp);
927 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
928 cfclose(Piggy_fp); //out of date pig
929 Piggy_fp = NULL; //..so pretend it's not here
936 return; //if editor, ok to not have pig, because we'll build one
938 Error("Cannot load required file <%s>",filename);
942 strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
944 N_bitmaps = cfile_read_int(Piggy_fp);
946 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
948 data_start = header_size + cftell(Piggy_fp);
950 data_size = cfilelength(Piggy_fp) - data_start;
952 Num_bitmap_files = 1;
954 for (i=0; i<N_bitmaps; i++ ) {
955 DiskBitmapHeader_read(&bmh, Piggy_fp);
956 memcpy( temp_name_read, bmh.name, 8 );
957 temp_name_read[8] = 0;
958 if ( bmh.dflags & DBM_FLAG_ABM )
959 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
961 strcpy( temp_name, temp_name_read );
962 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
963 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
964 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
965 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
966 temp_bitmap.avg_color = bmh.avg_color;
967 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
969 GameBitmapFlags[i+1] = 0;
970 if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_TRANSPARENT;
971 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_SUPER_TRANSPARENT;
972 if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i+1] |= BM_FLAG_NO_LIGHTING;
973 if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i+1] |= BM_FLAG_RLE;
974 if ( bmh.flags & BM_FLAG_RLE_BIG ) GameBitmapFlags[i+1] |= BM_FLAG_RLE_BIG;
976 GameBitmapOffset[i+1] = bmh.offset + data_start;
977 Assert( (i+1) == Num_bitmap_files );
978 piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
982 Piggy_bitmap_cache_size = data_size + (data_size/10); //extra mem for new bitmaps
983 Assert( Piggy_bitmap_cache_size > 0 );
985 Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
987 if (piggy_low_memory)
988 Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
991 BitmapBits = d_malloc( Piggy_bitmap_cache_size );
992 if ( BitmapBits == NULL )
993 Error( "Not enough memory to load bitmaps\n" );
994 Piggy_bitmap_cache_data = BitmapBits;
995 Piggy_bitmap_cache_next = 0;
997 #if defined(MACINTOSH) && defined(SHAREWARE)
998 // load_exit_models();
1001 Pigfile_initialized=1;
1004 #define FILENAME_LEN 13
1005 #define MAX_BITMAPS_PER_BRUSH 30
1007 extern int compute_average_pixel(grs_bitmap *new);
1009 //reads in a new pigfile (for new palette)
1010 //returns the size of all the bitmap data
1011 void piggy_new_pigfile(char *pigname)
1015 char temp_name_read[16];
1016 grs_bitmap temp_bitmap;
1017 DiskBitmapHeader bmh;
1018 int header_size, N_bitmaps, data_size, data_start;
1019 int must_rewrite_pig = 0;
1026 //rename pigfile for shareware
1027 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
1028 pigname = DEFAULT_PIGFILE_SHAREWARE;
1030 if (strnicmp(Current_pigfile,pigname,sizeof(Current_pigfile))==0)
1031 return; //already have correct pig
1033 if (!Pigfile_initialized) { //have we ever opened a pigfile?
1034 piggy_init_pigfile(pigname); //..no, so do initialization stuff
1038 piggy_close_file(); //close old pig if still open
1040 Piggy_bitmap_cache_next = 0; //free up cache
1042 strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
1045 Piggy_fp = cfopen( pigname, "rb" );
1047 sprintf(name, ":Data:%s", pigname);
1048 Piggy_fp = cfopen( name, "rb" );
1050 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
1051 if (Piggy_fp == NULL)
1053 Error("Cannot load required file <%s>",name);
1055 #endif // end of if def shareware
1060 Piggy_fp = copy_pigfile_from_cd(pigname);
1063 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1064 int pig_id,pig_version;
1066 pig_id = cfile_read_int(Piggy_fp);
1067 pig_version = cfile_read_int(Piggy_fp);
1068 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1069 cfclose(Piggy_fp); //out of date pig
1070 Piggy_fp = NULL; //..so pretend it's not here
1075 if (!Piggy_fp) Error ("Piggy_fp not defined in piggy_new_pigfile.");
1080 N_bitmaps = cfile_read_int(Piggy_fp);
1082 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
1084 data_start = header_size + cftell(Piggy_fp);
1086 data_size = cfilelength(Piggy_fp) - data_start;
1088 for (i=1; i<=N_bitmaps; i++ ) {
1089 DiskBitmapHeader_read(&bmh, Piggy_fp);
1090 memcpy( temp_name_read, bmh.name, 8 );
1091 temp_name_read[8] = 0;
1093 if ( bmh.dflags & DBM_FLAG_ABM )
1094 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
1096 strcpy( temp_name, temp_name_read );
1098 //Make sure name matches
1099 if (strcmp(temp_name,AllBitmaps[i].name)) {
1100 //Int3(); //this pig is out of date. Delete it
1104 strcpy(AllBitmaps[i].name,temp_name);
1106 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1108 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1109 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1110 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1111 temp_bitmap.avg_color = bmh.avg_color;
1112 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1114 GameBitmapFlags[i] = 0;
1116 if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i] |= BM_FLAG_TRANSPARENT;
1117 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i] |= BM_FLAG_SUPER_TRANSPARENT;
1118 if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i] |= BM_FLAG_NO_LIGHTING;
1119 if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i] |= BM_FLAG_RLE;
1120 if ( bmh.flags & BM_FLAG_RLE_BIG ) GameBitmapFlags[i] |= BM_FLAG_RLE_BIG;
1122 GameBitmapOffset[i] = bmh.offset + data_start;
1124 GameBitmaps[i] = temp_bitmap;
1128 N_bitmaps = 0; //no pigfile, so no bitmaps
1132 Assert(N_bitmaps == Num_bitmap_files-1);
1136 if (must_rewrite_pig || (N_bitmaps < Num_bitmap_files-1)) {
1139 //re-read the bitmaps that aren't in this pig
1141 for (i=N_bitmaps+1;i<Num_bitmap_files;i++) {
1144 p = strchr(AllBitmaps[i].name,'#');
1146 if (p) { //this is an ABM
1147 char abmname[FILENAME_LEN];
1149 grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
1150 int iff_error; //reference parm to avoid warning message
1152 char basename[FILENAME_LEN];
1155 strcpy(basename,AllBitmaps[i].name);
1156 basename[p-AllBitmaps[i].name] = 0; //cut off "#nn" part
1158 sprintf( abmname, "%s.abm", basename );
1160 iff_error = iff_read_animbrush(abmname,bm,MAX_BITMAPS_PER_BRUSH,&nframes,newpal);
1162 if (iff_error != IFF_NO_ERROR) {
1163 mprintf((1,"File %s - IFF error: %s",abmname,iff_errormsg(iff_error)));
1164 Error("File %s - IFF error: %s",abmname,iff_errormsg(iff_error));
1167 for (fnum=0;fnum<nframes; fnum++) {
1171 sprintf( tempname, "%s#%d", basename, fnum );
1173 //SuperX = (GameBitmaps[i+fnum].bm_flags&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1174 SuperX = (GameBitmapFlags[i+fnum]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1175 //above makes assumption that supertransparent color is 254
1177 if ( iff_has_transparency )
1178 gr_remap_bitmap_good( bm[fnum], newpal, iff_transparent_color, SuperX );
1180 gr_remap_bitmap_good( bm[fnum], newpal, -1, SuperX );
1182 bm[fnum]->avg_color = compute_average_pixel(bm[fnum]);
1185 if ( FindArg("-macdata") )
1186 swap_0_255( bm[fnum] );
1188 if ( !BigPig ) gr_bitmap_rle_compress( bm[fnum] );
1190 if (bm[fnum]->bm_flags & BM_FLAG_RLE)
1191 size = *((int *) bm[fnum]->bm_data);
1193 size = bm[fnum]->bm_w * bm[fnum]->bm_h;
1195 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],bm[fnum]->bm_data,size);
1196 d_free(bm[fnum]->bm_data);
1197 bm[fnum]->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1198 Piggy_bitmap_cache_next += size;
1200 GameBitmaps[i+fnum] = *bm[fnum];
1202 // -- mprintf( (0, "U" ));
1206 i += nframes-1; //filled in multiple bitmaps
1208 else { //this is a BBM
1211 ubyte newpal[256*3];
1213 char bbmname[FILENAME_LEN];
1216 MALLOC( new, grs_bitmap, 1 );
1218 sprintf( bbmname, "%s.bbm", AllBitmaps[i].name );
1219 iff_error = iff_read_bitmap(bbmname,new,BM_LINEAR,newpal);
1222 if (iff_error != IFF_NO_ERROR) {
1223 mprintf((1, "File %s - IFF error: %s",bbmname,iff_errormsg(iff_error)));
1224 Error("File %s - IFF error: %s",bbmname,iff_errormsg(iff_error));
1227 SuperX = (GameBitmapFlags[i]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1228 //above makes assumption that supertransparent color is 254
1230 if ( iff_has_transparency )
1231 gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
1233 gr_remap_bitmap_good( new, newpal, -1, SuperX );
1235 new->avg_color = compute_average_pixel(new);
1238 if ( FindArg("-macdata") )
1241 if ( !BigPig ) gr_bitmap_rle_compress( new );
1243 if (new->bm_flags & BM_FLAG_RLE)
1244 size = *((int *) new->bm_data);
1246 size = new->bm_w * new->bm_h;
1248 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],new->bm_data,size);
1249 d_free(new->bm_data);
1250 new->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1251 Piggy_bitmap_cache_next += size;
1253 GameBitmaps[i] = *new;
1257 // -- mprintf( (0, "U" ));
1261 //@@Dont' do these things which are done when writing
1262 //@@for (i=0; i < Num_bitmap_files; i++ ) {
1263 //@@ bitmap_index bi;
1265 //@@ PIGGY_PAGE_IN( bi );
1268 //@@piggy_close_file();
1270 piggy_write_pigfile(pigname);
1272 Current_pigfile[0] = 0; //say no pig, to force reload
1274 piggy_new_pigfile(pigname); //read in just-generated pig
1278 #endif //ifdef EDITOR
1282 ubyte bogus_data[64*64];
1283 grs_bitmap bogus_bitmap;
1284 ubyte bogus_bitmap_initialized=0;
1285 digi_sound bogus_sound;
1287 #define HAMFILE_ID MAKE_SIG('!','M','A','H') //HAM!
1288 #define HAMFILE_VERSION 3
1289 //version 1 -> 2: save marker_model_num
1290 //version 2 -> 3: removed sound files
1292 #define SNDFILE_ID MAKE_SIG('D','N','S','D') //DSND
1293 #define SNDFILE_VERSION 1
1297 CFILE * ham_fp = NULL;
1299 int sound_offset = 0;
1305 ham_fp = cfopen( DEFAULT_HAMFILE, "rb" );
1307 sprintf(name, ":Data:%s", DEFAULT_HAMFILE );
1308 ham_fp = cfopen( name, "rb" );
1311 if (ham_fp == NULL) {
1312 Must_write_hamfile = 1;
1316 //make sure ham is valid type file & is up-to-date
1317 ham_id = cfile_read_int(ham_fp);
1318 Piggy_hamfile_version = cfile_read_int(ham_fp);
1319 if (ham_id != HAMFILE_ID)
1320 Error("Cannot open ham file %s\n", DEFAULT_HAMFILE);
1322 if (ham_id != HAMFILE_ID || Piggy_hamfile_version != HAMFILE_VERSION) {
1323 Must_write_hamfile = 1;
1324 cfclose(ham_fp); //out of date ham
1329 if (Piggy_hamfile_version < 3) // hamfile contains sound info
1330 sound_offset = cfile_read_int(ham_fp);
1336 bm_read_all(ham_fp);
1337 cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1339 //for (i = 0; i < MAX_BITMAP_FILES; i++) {
1340 //GameBitmapXlat[i] = INTEL_SHORT(GameBitmapXlat[i]);
1341 //printf("GameBitmapXlat[%d] = %d\n", i, GameBitmapXlat[i]);
1346 if (Piggy_hamfile_version < 3) {
1351 DiskSoundHeader sndh;
1352 digi_sound temp_sound;
1353 char temp_name_read[16];
1356 cfseek(ham_fp, sound_offset, SEEK_SET);
1357 N_sounds = cfile_read_int(ham_fp);
1359 sound_start = cftell(ham_fp);
1361 header_size = N_sounds * DISKSOUNDHEADER_SIZE;
1365 for (i=0; i<N_sounds; i++ ) {
1366 DiskSoundHeader_read(&sndh, ham_fp);
1367 temp_sound.length = sndh.length;
1368 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1369 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1370 memcpy( temp_name_read, sndh.name, 8 );
1371 temp_name_read[8] = 0;
1372 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1374 if (piggy_is_needed(i))
1375 #endif // note link to if.
1376 sbytes += sndh.length;
1377 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1380 SoundBits = d_malloc( sbytes + 16 );
1381 if ( SoundBits == NULL )
1382 Error( "Not enough memory to load sounds\n" );
1384 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1386 // piggy_read_sounds(ham_fp);
1398 CFILE * snd_fp = NULL;
1399 int snd_id,snd_version;
1404 DiskSoundHeader sndh;
1405 digi_sound temp_sound;
1406 char temp_name_read[16];
1413 snd_fp = cfopen( DEFAULT_SNDFILE, "rb" );
1415 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1416 snd_fp = cfopen( name, "rb");
1422 //make sure soundfile is valid type file & is up-to-date
1423 snd_id = cfile_read_int(snd_fp);
1424 snd_version = cfile_read_int(snd_fp);
1425 if (snd_id != SNDFILE_ID || snd_version != SNDFILE_VERSION) {
1426 cfclose(snd_fp); //out of date sound file
1430 N_sounds = cfile_read_int(snd_fp);
1432 sound_start = cftell(snd_fp);
1433 size = cfilelength(snd_fp) - sound_start;
1435 mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
1437 header_size = N_sounds*sizeof(DiskSoundHeader);
1441 for (i=0; i<N_sounds; i++ ) {
1442 DiskSoundHeader_read(&sndh, snd_fp);
1443 //size -= sizeof(DiskSoundHeader);
1444 temp_sound.length = sndh.length;
1445 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1446 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1447 memcpy( temp_name_read, sndh.name, 8 );
1448 temp_name_read[8] = 0;
1449 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1451 if (piggy_is_needed(i))
1452 #endif // note link to if.
1453 sbytes += sndh.length;
1454 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1457 SoundBits = d_malloc( sbytes + 16 );
1458 if ( SoundBits == NULL )
1459 Error( "Not enough memory to load sounds\n" );
1461 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1463 // piggy_read_sounds(snd_fp);
1470 int piggy_init(void)
1472 int ham_ok=0,snd_ok=0;
1475 hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
1476 hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
1478 for (i=0; i<MAX_SOUND_FILES; i++ ) {
1479 GameSounds[i].length = 0;
1480 GameSounds[i].data = NULL;
1484 for (i=0; i<MAX_BITMAP_FILES; i++ )
1485 GameBitmapXlat[i] = i;
1487 if ( !bogus_bitmap_initialized ) {
1490 bogus_bitmap_initialized = 1;
1491 memset( &bogus_bitmap, 0, sizeof(grs_bitmap) );
1492 bogus_bitmap.bm_w = bogus_bitmap.bm_h = bogus_bitmap.bm_rowsize = 64;
1493 bogus_bitmap.bm_data = bogus_data;
1494 c = gr_find_closest_color( 0, 0, 63 );
1495 for (i=0; i<4096; i++ ) bogus_data[i] = c;
1496 c = gr_find_closest_color( 63, 0, 0 );
1497 // Make a big red X !
1498 for (i=0; i<64; i++ ) {
1499 bogus_data[i*64+i] = c;
1500 bogus_data[i*64+(63-i)] = c;
1502 piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
1503 bogus_sound.length = 64*64;
1504 bogus_sound.data = bogus_data;
1505 GameBitmapOffset[0] = 0;
1508 if ( FindArg( "-bigpig" ))
1511 if ( FindArg( "-lowmem" ))
1512 piggy_low_memory = 1;
1514 if ( FindArg( "-nolowmem" ))
1515 piggy_low_memory = 0;
1517 if (piggy_low_memory)
1520 WIN(DDGRLOCK(dd_grd_curcanv));
1521 gr_set_curfont( SMALL_FONT );
1522 gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
1523 gr_printf( 0x8000, grd_curcanv->cv_h-20, "%s...", TXT_LOADING_DATA );
1524 WIN(DDGRUNLOCK(dd_grd_curcanv));
1526 #if 1 //def EDITOR //need for d1 mission briefings
1527 piggy_init_pigfile(DEFAULT_PIGFILE);
1530 snd_ok = ham_ok = read_hamfile();
1532 if (Piggy_hamfile_version >= 3)
1533 snd_ok = read_sndfile();
1535 atexit(piggy_close);
1537 mprintf ((0,"HamOk=%d SndOk=%d\n",ham_ok,snd_ok));
1538 return (ham_ok && snd_ok); //read ok
1541 int piggy_is_needed(int soundnum)
1545 if ( !digi_lomem ) return 1;
1547 for (i=0; i<MAX_SOUNDS; i++ ) {
1548 if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
1555 void piggy_read_sounds(void)
1568 fp = cfopen( DEFAULT_SNDFILE, "rb" );
1570 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1571 fp = cfopen( name, "rb");
1577 for (i=0; i<Num_sound_files; i++ ) {
1578 digi_sound *snd = &GameSounds[i];
1580 if ( SoundOffset[i] > 0 ) {
1581 if ( piggy_is_needed(i) ) {
1582 cfseek( fp, SoundOffset[i], SEEK_SET );
1584 // Read in the sound data!!!
1587 sbytes += snd->length;
1588 cfread( snd->data, snd->length, 1, fp );
1591 snd->data = (ubyte *) -1;
1597 mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
1602 extern int descent_critical_error;
1603 extern unsigned descent_critical_deverror;
1604 extern unsigned descent_critical_errcode;
1606 char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
1607 "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
1608 "Read fault", "General Failure" };
1610 void piggy_critical_error()
1612 grs_canvas * save_canv;
1613 grs_font * save_font;
1615 save_canv = grd_curcanv;
1616 save_font = grd_curcanv->cv_font;
1617 gr_palette_load( gr_palette );
1618 i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A' );
1621 gr_set_current_canvas(save_canv);
1622 grd_curcanv->cv_font = save_font;
1625 void piggy_bitmap_page_in( bitmap_index bitmap )
1634 Assert( i < MAX_BITMAP_FILES );
1635 Assert( i < Num_bitmap_files );
1636 Assert( Piggy_bitmap_cache_size > 0 );
1638 if ( i < 1 ) return;
1639 if ( i >= MAX_BITMAP_FILES ) return;
1640 if ( i >= Num_bitmap_files ) return;
1642 if ( GameBitmapOffset[i] == 0 ) return; // A read-from-disk bitmap!!!
1644 if ( piggy_low_memory ) {
1646 i = GameBitmapXlat[i]; // Xlat for low-memory settings!
1649 bmp = &GameBitmaps[i];
1651 if ( bmp->bm_flags & BM_FLAG_PAGED_OUT ) {
1655 descent_critical_error = 0;
1656 cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
1657 if ( descent_critical_error ) {
1658 piggy_critical_error();
1662 bmp->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1663 bmp->bm_flags = GameBitmapFlags[i];
1665 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1667 descent_critical_error = 0;
1668 zsize = cfile_read_int(Piggy_fp);
1669 if ( descent_critical_error ) {
1670 piggy_critical_error();
1674 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1675 //Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );
1676 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1678 piggy_bitmap_page_out_all();
1681 descent_critical_error = 0;
1682 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next+4], 1, zsize-4, Piggy_fp );
1683 if ( descent_critical_error ) {
1684 piggy_critical_error();
1689 switch (cfilelength(Piggy_fp)) {
1691 if (!FindArg("-macdata"))
1693 // otherwise, fall through...
1694 case MAC_ALIEN1_PIGSIZE:
1695 case MAC_ALIEN2_PIGSIZE:
1696 case MAC_FIRE_PIGSIZE:
1697 case MAC_GROUPA_PIGSIZE:
1698 case MAC_ICE_PIGSIZE:
1699 case MAC_WATER_PIGSIZE:
1700 rle_swap_0_255( bmp );
1701 memcpy(&zsize, bmp->bm_data, 4);
1706 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
1707 Piggy_bitmap_cache_next += zsize;
1708 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1710 piggy_bitmap_page_out_all();
1715 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1716 Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );
1717 if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) {
1718 piggy_bitmap_page_out_all();
1721 descent_critical_error = 0;
1722 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
1723 if ( descent_critical_error ) {
1724 piggy_critical_error();
1727 Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
1730 switch (cfilelength(Piggy_fp)) {
1732 if (!FindArg("-macdata"))
1734 // otherwise, fall through...
1735 case MAC_ALIEN1_PIGSIZE:
1736 case MAC_ALIEN2_PIGSIZE:
1737 case MAC_FIRE_PIGSIZE:
1738 case MAC_GROUPA_PIGSIZE:
1739 case MAC_ICE_PIGSIZE:
1740 case MAC_WATER_PIGSIZE:
1747 //@@if ( bmp->bm_selector ) {
1748 //@@#if !defined(WINDOWS) && !defined(MACINTOSH)
1749 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1750 //@@ Error( "Error modifying selector base in piggy.c\n" );
1757 if ( piggy_low_memory ) {
1759 GameBitmaps[org_i] = GameBitmaps[i];
1762 //@@Removed from John's code:
1764 //@@ if ( bmp->bm_selector ) {
1765 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1766 //@@ Error( "Error modifying selector base in piggy.c\n" );
1772 void piggy_bitmap_page_out_all()
1776 Piggy_bitmap_cache_next = 0;
1778 piggy_page_flushed++;
1783 for (i=0; i<Num_bitmap_files; i++ ) {
1784 if ( GameBitmapOffset[i] > 0 ) { // Don't page out bitmaps read from disk!!!
1785 GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
1786 GameBitmaps[i].bm_data = Piggy_bitmap_cache_data;
1790 mprintf(( 0, "Flushing piggy bitmap cache\n" ));
1793 void piggy_load_level_data()
1795 piggy_bitmap_page_out_all();
1801 void change_filename_ext( char *dest, char *src, char *ext );
1803 void piggy_write_pigfile(char *filename)
1806 int bitmap_data_start,data_offset;
1807 DiskBitmapHeader bmh;
1809 char subst_name[32];
1812 char tname[FILENAME_LEN];
1814 // -- mprintf( (0, "Paging in all piggy bitmaps..." ));
1815 for (i=0; i < Num_bitmap_files; i++ ) {
1818 PIGGY_PAGE_IN( bi );
1820 // -- mprintf( (0, "\n" ));
1824 // -- mprintf( (0, "Creating %s...",filename ));
1826 pig_fp = fopen( filename, "wb" ); //open PIG file
1827 Assert( pig_fp!=NULL );
1829 write_int(PIGFILE_ID,pig_fp);
1830 write_int(PIGFILE_VERSION,pig_fp);
1833 fwrite( &Num_bitmap_files, sizeof(int), 1, pig_fp );
1836 bitmap_data_start = ftell(pig_fp);
1837 bitmap_data_start += (Num_bitmap_files-1)*DISKBITMAPHEADER_SIZE;
1838 data_offset = bitmap_data_start;
1840 change_filename_ext(tname,filename,"lst");
1841 fp1 = fopen( tname, "wt" );
1842 change_filename_ext(tname,filename,"all");
1843 fp2 = fopen( tname, "wt" );
1845 for (i=1; i < Num_bitmap_files; i++ ) {
1851 p = strchr(AllBitmaps[i].name,'#');
1858 fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
1859 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1861 bmh.dflags = DBM_FLAG_ABM + n;
1865 fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
1866 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1870 bmp = &GameBitmaps[i];
1872 Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
1875 fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
1876 org_offset = ftell(pig_fp);
1877 bmh.offset = data_offset - bitmap_data_start;
1878 fseek( pig_fp, data_offset, SEEK_SET );
1880 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1881 size = (int *)bmp->bm_data;
1882 fwrite( bmp->bm_data, sizeof(ubyte), *size, pig_fp );
1883 data_offset += *size;
1885 fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
1887 fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, pig_fp );
1888 data_offset += bmp->bm_rowsize * bmp->bm_h;
1890 fprintf( fp1, ".\n" );
1892 fseek( pig_fp, org_offset, SEEK_SET );
1893 Assert( GameBitmaps[i].bm_w < 4096 );
1894 bmh.width = (GameBitmaps[i].bm_w & 0xff);
1895 bmh.wh_extra = ((GameBitmaps[i].bm_w >> 8) & 0x0f);
1896 Assert( GameBitmaps[i].bm_h < 4096 );
1897 bmh.height = GameBitmaps[i].bm_h;
1898 bmh.wh_extra |= ((GameBitmaps[i].bm_h >> 4) & 0xf0);
1899 bmh.flags = GameBitmaps[i].bm_flags;
1900 if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name )) {
1901 bitmap_index other_bitmap;
1902 other_bitmap = piggy_find_bitmap( subst_name );
1903 GameBitmapXlat[i] = other_bitmap.index;
1904 bmh.flags |= BM_FLAG_PAGED_OUT;
1905 //mprintf(( 0, "Skipping bitmap %d\n", i ));
1906 //mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
1908 bmh.flags &= ~BM_FLAG_PAGED_OUT;
1910 bmh.avg_color=GameBitmaps[i].avg_color;
1911 fwrite( &bmh, DISKBITMAPHEADER_SIZE, 1, pig_fp ); // Mark as a bitmap
1916 mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
1917 fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
1924 static void write_int(int i,FILE *file)
1926 if (fwrite( &i, sizeof(i), 1, file) != 1)
1927 Error( "Error reading int in gamesave.c" );
1931 void piggy_dump_all()
1935 int org_offset,data_offset=0;
1936 DiskSoundHeader sndh;
1937 int sound_data_start=0;
1940 #ifdef NO_DUMP_SOUNDS
1941 Num_sound_files = 0;
1942 Num_sound_files_new = 0;
1945 if (!Must_write_hamfile && (Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
1948 fp1 = fopen( "ham.lst", "wt" );
1949 fp2 = fopen( "ham.all", "wt" );
1951 if (Must_write_hamfile || Num_bitmap_files_new) {
1953 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1955 ham_fp = fopen( DEFAULT_HAMFILE, "wb" ); //open HAM file
1956 Assert( ham_fp!=NULL );
1958 write_int(HAMFILE_ID,ham_fp);
1959 write_int(HAMFILE_VERSION,ham_fp);
1961 bm_write_all(ham_fp);
1962 xlat_offset = ftell(ham_fp);
1963 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1966 if (Num_bitmap_files_new)
1967 piggy_write_pigfile(DEFAULT_PIGFILE);
1969 //free up memeory used by new bitmaps
1970 for (i=Num_bitmap_files-Num_bitmap_files_new;i<Num_bitmap_files;i++)
1971 d_free(GameBitmaps[i].bm_data);
1973 //next thing must be done after pig written
1974 fseek( ham_fp, xlat_offset, SEEK_SET );
1975 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1978 mprintf( (0, "\n" ));
1981 if (Num_sound_files_new) {
1983 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1984 // Now dump sound file
1985 ham_fp = fopen( DEFAULT_SNDFILE, "wb" );
1986 Assert( ham_fp!=NULL );
1988 write_int(SNDFILE_ID,ham_fp);
1989 write_int(SNDFILE_VERSION,ham_fp);
1991 fwrite( &Num_sound_files, sizeof(int), 1, ham_fp );
1993 mprintf( (0, "\nDumping sounds..." ));
1995 sound_data_start = ftell(ham_fp);
1996 sound_data_start += Num_sound_files*sizeof(DiskSoundHeader);
1997 data_offset = sound_data_start;
1999 for (i=0; i < Num_sound_files; i++ ) {
2002 snd = &GameSounds[i];
2003 strcpy( sndh.name, AllSounds[i].name );
2004 sndh.length = GameSounds[i].length;
2005 sndh.offset = data_offset - sound_data_start;
2007 org_offset = ftell(ham_fp);
2008 fseek( ham_fp, data_offset, SEEK_SET );
2010 sndh.data_length = GameSounds[i].length;
2011 fwrite( snd->data, sizeof(ubyte), snd->length, ham_fp );
2012 data_offset += snd->length;
2013 fseek( ham_fp, org_offset, SEEK_SET );
2014 fwrite( &sndh, sizeof(DiskSoundHeader), 1, ham_fp ); // Mark as a bitmap
2016 fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
2017 fprintf( fp2, "%s.raw\n", AllSounds[i].name );
2021 mprintf( (0, "\n" ));
2024 fprintf( fp1, "Total sound size: %d bytes\n", data_offset-sound_data_start);
2025 mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
2026 fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
2031 // Never allow the game to run after building ham.
2045 d_free( SoundBits );
2047 hashtable_free( &AllBitmapsNames );
2048 hashtable_free( &AllDigiSndNames );
2052 int piggy_does_bitmap_exist_slow( char * name )
2056 for (i=0; i<Num_bitmap_files; i++ ) {
2057 if ( !strcmp( AllBitmaps[i].name, name) )
2064 #define NUM_GAUGE_BITMAPS 23
2065 char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = {
2066 "gauge01", "gauge01b",
2067 "gauge02", "gauge02b",
2068 "gauge06", "gauge06b",
2069 "targ01", "targ01b",
2070 "targ02", "targ02b",
2071 "targ03", "targ03b",
2072 "targ04", "targ04b",
2073 "targ05", "targ05b",
2074 "targ06", "targ06b",
2075 "gauge18", "gauge18b",
2081 int piggy_is_gauge_bitmap( char * base_name )
2084 for (i=0; i<NUM_GAUGE_BITMAPS; i++ ) {
2085 if ( !stricmp( base_name, gauge_bitmap_names[i] ))
2092 int piggy_is_substitutable_bitmap( char * name, char * subst_name )
2096 char base_name[ 16 ];
2098 strcpy( subst_name, name );
2099 p = strchr( subst_name, '#' );
2101 frame = atoi( &p[1] );
2103 strcpy( base_name, subst_name );
2104 if ( !piggy_is_gauge_bitmap( base_name )) {
2105 sprintf( subst_name, "%s#%d", base_name, frame+1 );
2106 if ( piggy_does_bitmap_exist_slow( subst_name ) ) {
2108 sprintf( subst_name, "%s#%d", base_name, frame-1 );
2114 strcpy( subst_name, name );
2121 // New Windows stuff
2123 // windows bitmap page in
2124 // Page in a bitmap, if ddraw, then page it into a ddsurface in
2125 // 'video' memory. if that fails, page it in normally.
2127 void piggy_bitmap_page_in_w( bitmap_index bitmap, int ddraw )
2132 // Essential when switching video modes!
2134 void piggy_bitmap_page_out_all_w()
2142 * Functions for loading replacement textures
2143 * 1) From .pog files
2144 * 2) From descent.pig (for loading d1 levels)
2147 extern void change_filename_extension( char *dest, char *src, char *new_ext );
2148 extern char last_palette_loaded_pig[];
2150 ubyte *Bitmap_replacement_data=NULL;
2152 void free_bitmap_replacements()
2154 if (Bitmap_replacement_data) {
2155 d_free(Bitmap_replacement_data);
2156 Bitmap_replacement_data = NULL;
2160 void load_bitmap_replacements(char *level_name)
2162 char ifile_name[FILENAME_LEN];
2166 //first, free up data allocated for old bitmaps
2167 free_bitmap_replacements();
2169 change_filename_extension(ifile_name, level_name, ".POG" );
2171 ifile = cfopen(ifile_name,"rb");
2174 int id,version,n_bitmaps;
2175 int bitmap_data_size;
2178 id = cfile_read_int(ifile);
2179 version = cfile_read_int(ifile);
2181 if (id != MAKE_SIG('G','O','P','D') || version != 1) {
2186 n_bitmaps = cfile_read_int(ifile);
2188 MALLOC( indices, ushort, n_bitmaps );
2190 for (i = 0; i < n_bitmaps; i++)
2191 indices[i] = cfile_read_short(ifile);
2193 bitmap_data_size = cfilelength(ifile) - cftell(ifile) - DISKBITMAPHEADER_SIZE * n_bitmaps;
2194 MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
2196 for (i=0;i<n_bitmaps;i++) {
2197 DiskBitmapHeader bmh;
2198 grs_bitmap temp_bitmap;
2200 DiskBitmapHeader_read(&bmh, ifile);
2202 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2204 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2205 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2206 temp_bitmap.avg_color = bmh.avg_color;
2207 temp_bitmap.bm_data = Bitmap_replacement_data + bmh.offset;
2209 if ( bmh.flags & BM_FLAG_TRANSPARENT ) temp_bitmap.bm_flags |= BM_FLAG_TRANSPARENT;
2210 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) temp_bitmap.bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2211 if ( bmh.flags & BM_FLAG_NO_LIGHTING ) temp_bitmap.bm_flags |= BM_FLAG_NO_LIGHTING;
2212 if ( bmh.flags & BM_FLAG_RLE ) temp_bitmap.bm_flags |= BM_FLAG_RLE;
2213 if ( bmh.flags & BM_FLAG_RLE_BIG ) temp_bitmap.bm_flags |= BM_FLAG_RLE_BIG;
2215 GameBitmaps[indices[i]] = temp_bitmap;
2218 cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
2224 last_palette_loaded_pig[0]= 0; //force pig re-load
2226 texmerge_flush(); //for re-merging with new textures
2229 atexit(free_bitmap_replacements);
2232 #define FIRST_D1_TEXTURE 722
2233 #define LAST_D1_STATIC_TEXTURE 1042//1342 //afterwards, we have door frames and stuff
2234 #define FIRST_D2_TEXTURE 1243
2236 void load_d1_bitmap_replacements()
2238 CFILE * d1_Piggy_fp;
2239 grs_bitmap temp_bitmap;
2240 DiskBitmapHeader bmh;
2241 int pig_data_start, bitmap_header_start, bitmap_data_start;
2242 int N_bitmaps, zsize;
2243 int d1_index, d2_index;
2244 ubyte colormap[256];
2245 ubyte *next_bitmap; // to which address we write the next bitmap
2248 d1_Piggy_fp = cfopen( "descent.pig", "rb" );
2250 d1_Piggy_fp = cfopen( "Data:Descent.pig", "rb" );
2251 #endif // end of ifndef/else MACINTOSH
2254 return; // use d2 bitmaps instead...
2256 //first, free up data allocated for old bitmaps
2257 free_bitmap_replacements();
2259 // read d1 palette, build colormap
2262 ubyte d1_palette[256*3];
2263 CFILE * palette_file = cfopen( "palette.256", "rb" );
2264 Assert( palette_file );
2265 Assert( cfilelength( palette_file ) == 9472 );
2266 cfread( d1_palette, 256, 3, palette_file);
2267 cfclose( palette_file );
2268 build_colormap_good( d1_palette, colormap, freq );
2269 // don't change transparencies:
2270 colormap[254] = 254;
2271 colormap[255] = 255;
2274 switch (cfilelength(d1_Piggy_fp)) {
2275 case D1_SHAREWARE_10_PIGSIZE:
2276 case D1_SHAREWARE_PIGSIZE:
2282 case D1_OEM_PIGSIZE:
2283 case D1_MAC_PIGSIZE:
2284 case D1_MAC_SHARE_PIGSIZE:
2286 pig_data_start = cfile_read_int(d1_Piggy_fp );
2287 bm_read_all_d1( d1_Piggy_fp );
2288 //for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2292 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2293 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2295 int N_sounds = cfile_read_int(d1_Piggy_fp);
2296 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2297 + N_sounds * DISKSOUNDHEADER_SIZE;
2298 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2299 bitmap_data_start = bitmap_header_start + header_size;
2302 MALLOC( Bitmap_replacement_data, ubyte, cfilelength(d1_Piggy_fp) - bitmap_data_start ); // too much
2303 //TODO: handle case where b_r_d == 0! (have to convert textures, return, not bm_read_all_d1)
2305 next_bitmap = Bitmap_replacement_data;
2307 for (d1_index=1; d1_index<=N_bitmaps; d1_index++ ) {
2308 // only change wall texture bitmaps
2309 if (d1_index >= FIRST_D1_TEXTURE && d1_index <= LAST_D1_STATIC_TEXTURE) {
2310 d2_index = d1_index + FIRST_D2_TEXTURE - FIRST_D1_TEXTURE;
2312 cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2313 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2315 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2317 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2318 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2319 temp_bitmap.avg_color = bmh.avg_color;
2321 //GameBitmapFlags[convert_d1_bitmap_num(d1_index)] = 0;
2323 if ( bmh.flags & BM_FLAG_TRANSPARENT )
2324 temp_bitmap.bm_flags |= BM_FLAG_TRANSPARENT;
2325 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT )
2326 temp_bitmap.bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2327 if ( bmh.flags & BM_FLAG_NO_LIGHTING )
2328 temp_bitmap.bm_flags |= BM_FLAG_NO_LIGHTING;
2329 if ( bmh.flags & BM_FLAG_RLE )
2330 temp_bitmap.bm_flags |= BM_FLAG_RLE;
2331 if ( bmh.flags & BM_FLAG_RLE_BIG )
2332 temp_bitmap.bm_flags |= BM_FLAG_RLE_BIG;
2334 temp_bitmap.bm_data = next_bitmap;
2336 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2337 zsize = cfile_read_int(d1_Piggy_fp);
2338 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2339 cfread(next_bitmap, 1, zsize, d1_Piggy_fp);
2341 switch(cfilelength(d1_Piggy_fp)) {
2342 case D1_MAC_PIGSIZE:
2343 case D1_MAC_SHARE_PIGSIZE:
2344 rle_swap_0_255(&temp_bitmap);
2346 rle_remap(&temp_bitmap, colormap);
2348 GameBitmaps[d2_index] = temp_bitmap;
2350 memcpy(&zsize, temp_bitmap.bm_data, 4);
2351 next_bitmap += zsize;
2355 cfclose(d1_Piggy_fp);
2357 last_palette_loaded_pig[0]= 0; //force pig re-load
2359 texmerge_flush(); //for re-merging with new textures
2361 atexit(free_bitmap_replacements);
2365 extern int extra_bitmap_num;
2368 * Find and load the named bitmap from descent.pig
2369 * similar to exitmodel_bm_load_sub
2371 bitmap_index read_extra_d1_bitmap(char *name)
2373 bitmap_index bitmap_num;
2374 grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2376 bitmap_num.index = 0;
2381 DiskBitmapHeader bmh;
2382 int pig_data_start, bitmap_header_start, bitmap_data_start;
2383 int N_bitmaps, zsize;
2384 ubyte colormap[256];
2386 d1_Piggy_fp = cfopen("descent.pig", "rb");
2389 con_printf(CON_DEBUG, "could not open descent.pig\n", name);
2393 // read d1 palette, build colormap
2396 ubyte d1_palette[256*3];
2397 CFILE * palette_file = cfopen( "palette.256", "rb" );
2398 Assert( palette_file );
2399 Assert( cfilelength( palette_file ) == 9472 );
2400 cfread( d1_palette, 256, 3, palette_file);
2401 cfclose( palette_file );
2402 build_colormap_good( d1_palette, colormap, freq );
2403 // don't change transparencies:
2404 colormap[254] = 254;
2405 colormap[255] = 255;
2408 switch (cfilelength(d1_Piggy_fp)) {
2409 case D1_SHAREWARE_10_PIGSIZE:
2410 case D1_SHAREWARE_PIGSIZE:
2416 case D1_OEM_PIGSIZE:
2417 case D1_MAC_PIGSIZE:
2418 case D1_MAC_SHARE_PIGSIZE:
2419 pig_data_start = cfile_read_int(d1_Piggy_fp);
2423 cfseek(d1_Piggy_fp, pig_data_start, SEEK_SET);
2424 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2426 int N_sounds = cfile_read_int(d1_Piggy_fp);
2427 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2428 + N_sounds * DISKSOUNDHEADER_SIZE;
2429 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2430 bitmap_data_start = bitmap_header_start + header_size;
2433 for (i = 0; i < N_bitmaps; i++)
2435 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2436 if (!strnicmp(bmh.name, name, 8))
2440 Assert(!strnicmp(bmh.name, name, 8));
2442 memset( new, 0, sizeof(grs_bitmap) );
2444 new->bm_w = new->bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2445 new->bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2446 new->avg_color = bmh.avg_color;
2448 if ( bmh.flags & BM_FLAG_TRANSPARENT )
2449 new->bm_flags |= BM_FLAG_TRANSPARENT;
2450 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT )
2451 new->bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2452 if ( bmh.flags & BM_FLAG_NO_LIGHTING )
2453 new->bm_flags |= BM_FLAG_NO_LIGHTING;
2454 if ( bmh.flags & BM_FLAG_RLE )
2455 new->bm_flags |= BM_FLAG_RLE;
2456 if ( bmh.flags & BM_FLAG_RLE_BIG )
2457 new->bm_flags |= BM_FLAG_RLE_BIG;
2459 if ( bmh.flags & BM_FLAG_RLE )
2461 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2462 zsize = cfile_read_int(d1_Piggy_fp);
2465 zsize = new->bm_w * new->bm_h;
2466 new->bm_data = d_malloc(zsize);
2467 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2468 cfread(new->bm_data, 1, zsize, d1_Piggy_fp);
2470 switch(cfilelength(d1_Piggy_fp)) {
2471 case D1_MAC_PIGSIZE:
2472 case D1_MAC_SHARE_PIGSIZE:
2473 rle_swap_0_255(new);
2475 rle_remap(new, colormap);
2477 cfclose(d1_Piggy_fp);
2480 new->avg_color = 0; //compute_average_pixel(new);
2482 bitmap_num.index = extra_bitmap_num;
2484 GameBitmaps[extra_bitmap_num++] = *new;
2490 #ifndef FAST_FILE_IO
2492 * reads a bitmap_index structure from a CFILE
2494 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2496 bi->index = cfile_read_short(fp);
2500 * reads n bitmap_index structs from a CFILE
2502 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2506 for (i = 0; i < n; i++)
2507 bi[i].index = cfile_read_short(fp);
2512 * reads a DiskBitmapHeader structure from a CFILE
2514 void DiskBitmapHeader_read(DiskBitmapHeader *dbh, CFILE *fp)
2516 cfread(dbh->name, 8, 1, fp);
2517 dbh->dflags = cfile_read_byte(fp);
2518 dbh->width = cfile_read_byte(fp);
2519 dbh->height = cfile_read_byte(fp);
2520 dbh->wh_extra = cfile_read_byte(fp);
2521 dbh->flags = cfile_read_byte(fp);
2522 dbh->avg_color = cfile_read_byte(fp);
2523 dbh->offset = cfile_read_int(fp);
2527 * reads a DiskSoundHeader structure from a CFILE
2529 void DiskSoundHeader_read(DiskSoundHeader *dsh, CFILE *fp)
2531 cfread(dsh->name, 8, 1, fp);
2532 dsh->length = cfile_read_int(fp);
2533 dsh->data_length = cfile_read_int(fp);
2534 dsh->offset = cfile_read_int(fp);
2536 #endif // FAST_FILE_IO
2539 * reads a descent 1 DiskBitmapHeader structure from a CFILE
2541 void DiskBitmapHeader_d1_read(DiskBitmapHeader *dbh, CFILE *fp)
2543 cfread(dbh->name, 8, 1, fp);
2544 dbh->dflags = cfile_read_byte(fp);
2545 dbh->width = cfile_read_byte(fp);
2546 dbh->height = cfile_read_byte(fp);
2548 dbh->flags = cfile_read_byte(fp);
2549 dbh->avg_color = cfile_read_byte(fp);
2550 dbh->offset = cfile_read_int(fp);