1 /* $Id: piggy.c,v 1.29 2003-03-25 10:17:05 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.29 2003-03-25 10:17:05 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 #define MAC_ALIEN1_PIGSIZE 5013035
445 #define MAC_ALIEN2_PIGSIZE 4909916
446 #define MAC_FIRE_PIGSIZE 4969035
447 #define MAC_GROUPA_PIGSIZE 4929684 // also used for mac shareware
448 #define MAC_ICE_PIGSIZE 4923425
449 #define MAC_WATER_PIGSIZE 4832403
451 ubyte *BitmapBits = NULL;
452 ubyte *SoundBits = NULL;
454 typedef struct BitmapFile {
458 typedef struct SoundFile {
462 hashtable AllBitmapsNames;
463 hashtable AllDigiSndNames;
465 int Num_bitmap_files = 0;
466 int Num_sound_files = 0;
468 digi_sound GameSounds[MAX_SOUND_FILES];
469 int SoundOffset[MAX_SOUND_FILES];
470 grs_bitmap GameBitmaps[MAX_BITMAP_FILES];
472 alias alias_list[MAX_ALIASES];
475 int Must_write_hamfile = 0;
476 int Num_bitmap_files_new = 0;
477 int Num_sound_files_new = 0;
478 BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
479 static SoundFile AllSounds[ MAX_SOUND_FILES ];
481 int Piggy_hamfile_version = 0;
483 int piggy_low_memory = 0;
485 int Piggy_bitmap_cache_size = 0;
486 int Piggy_bitmap_cache_next = 0;
487 ubyte * Piggy_bitmap_cache_data = NULL;
488 static int GameBitmapOffset[MAX_BITMAP_FILES];
489 static ubyte GameBitmapFlags[MAX_BITMAP_FILES];
490 ushort GameBitmapXlat[MAX_BITMAP_FILES];
492 #define PIGGY_BUFFER_SIZE (2400*1024)
495 #define PIGGY_SMALL_BUFFER_SIZE (1400*1024) // size of buffer when piggy_low_memory is set
498 #undef PIGGY_BUFFER_SIZE
499 #undef PIGGY_SMALL_BUFFER_SIZE
501 #define PIGGY_BUFFER_SIZE (2000*1024)
502 #define PIGGY_SMALL_BUFFER_SIZE (1100 * 1024)
507 int piggy_page_flushed = 0;
509 #define DBM_FLAG_ABM 64
514 extern short cd_VRefNum;
515 extern void ConcatPStr(StringPtr dst, StringPtr src);
516 extern int ConvertPToCStr(StringPtr inPStr, char* outCStrBuf);
517 extern int ConvertCToPStr(char* inCStr, StringPtr outPStrBuf);
520 int piggy_is_substitutable_bitmap( char * name, char * subst_name );
523 void piggy_write_pigfile(char *filename);
524 static void write_int(int i,FILE *file);
527 void swap_0_255(grs_bitmap *bmp)
531 for (i = 0; i < bmp->bm_h * bmp->bm_w; i++) {
532 if(bmp->bm_data[i] == 0)
533 bmp->bm_data[i] = 255;
534 else if (bmp->bm_data[i] == 255)
539 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
542 Assert( Num_bitmap_files < MAX_BITMAP_FILES );
544 temp.index = Num_bitmap_files;
548 if ( FindArg("-macdata") )
551 if ( !BigPig ) gr_bitmap_rle_compress( bmp );
552 Num_bitmap_files_new++;
555 strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
556 hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
557 GameBitmaps[Num_bitmap_files] = *bmp;
559 GameBitmapOffset[Num_bitmap_files] = 0;
560 GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
567 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
571 Assert( Num_sound_files < MAX_SOUND_FILES );
573 strncpy( AllSounds[Num_sound_files].name, name, 12 );
574 hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
575 GameSounds[Num_sound_files] = *snd;
577 SoundOffset[Num_sound_files] = 0;
583 Num_sound_files_new++;
589 bitmap_index piggy_find_bitmap( char * name )
597 if ((t=strchr(name,'#'))!=NULL)
600 for (i=0;i<Num_aliases;i++)
601 if (stricmp(name,alias_list[i].alias_name)==0) {
602 if (t) { //extra stuff for ABMs
603 static char temp[FILENAME_LEN];
604 _splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
610 name=alias_list[i].file_name;
617 i = hashtable_search( &AllBitmapsNames, name );
626 int piggy_find_sound( char * name )
630 i = hashtable_search( &AllDigiSndNames, name );
638 CFILE * Piggy_fp = NULL;
640 #define FILENAME_LEN 13
642 char Current_pigfile[FILENAME_LEN] = "";
644 void piggy_close_file()
649 Current_pigfile[0] = 0;
653 int Pigfile_initialized=0;
655 #define PIGFILE_ID MAKE_SIG('G','I','P','P') //PPIG
656 #define PIGFILE_VERSION 2
658 extern char CDROM_dir[];
660 int request_cd(void);
665 //copies a pigfile from the CD to the current dir
666 //retuns file handle of new pig
667 CFILE *copy_pigfile_from_cd(char *filename) // MACINTOSH VERSION
670 char sourcePathAndFileCStr[255] = "";
671 char destPathAndFileCStr[255] = "";
673 FILE* sourceFile = NULL;
674 FILE* destFile = NULL;
675 const int BUF_SIZE = 4096;
679 Str255 sourcePathAndFilePStr = "\p";
680 Str255 destPathAndFilePStr = "\p";
681 Str255 pigfileNamePStr = "\p";
682 HParamBlockRec theSourcePigHFSParams;
683 HParamBlockRec theDestPigHFSParams;
684 OSErr theErr = noErr;
685 char oldDirCStr[255] = "";
687 getcwd(oldDirCStr, 255);
689 show_boxed_message("Copying bitmap data from CD...");
690 gr_palette_load(gr_palette); //I don't think this line is really needed
693 //First, delete all PIG files currently in the directory
694 if( !FileFindFirst( "*.pig", &find ) )
699 } while( !FileFindNext( &find ) );
705 //Now, copy over new pig
706 songs_stop_redbook(); //so we can read off the cd
708 // make the source path "<cd volume>:Data:filename.pig"
709 //MWA ConvertCToPStr(filename, pigfileNamePStr);
711 //MWA ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:"); // volume ID is cd_VRefNum
712 //MWA ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
715 strcpy(sourcePathAndFileCStr, "Descent II:Data:");
716 strcat(sourcePathAndFileCStr, filename);
718 // make the destination path "<default directory>:Data:filename.pig"
719 //MWA ConcatPStr(destPathAndFilePStr, "\p:Data:");
720 //MWA ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
721 //MWA ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
722 //MWA ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
724 strcpy(destPathAndFileCStr, ":Data:");
725 strcat(destPathAndFileCStr, filename);
727 strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
728 strcpy(destPathAndFilePStr, destPathAndFileCStr);
729 c2pstr(sourcePathAndFilePStr);
730 c2pstr(destPathAndFilePStr);
733 // Open the source file
734 sourceFile = fopen(sourcePathAndFileCStr,"rb");
738 if (request_cd() == -1)
739 Error("Cannot load file <%s> from CD",filename);
742 } while (!sourceFile);
745 // Get the time stamp from the source file
746 theSourcePigHFSParams.fileParam.ioCompletion = nil;
747 theSourcePigHFSParams.fileParam.ioNamePtr = sourcePathAndFilePStr;
748 theSourcePigHFSParams.fileParam.ioVRefNum = cd_VRefNum;
749 theSourcePigHFSParams.fileParam.ioFDirIndex = 0;
750 theSourcePigHFSParams.fileParam.ioDirID = 0;
752 theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
755 // Error getting file time stamp!! Why? JTS
756 Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
759 // Copy the file over
762 // Open the destination file
763 destFile = fopen(destPathAndFileCStr,"wb");
766 Error("Cannot create file: <%s>\n", destPathAndFileCStr);
769 // Copy bytes until the end of the source file
770 while (!feof(sourceFile))
775 bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
776 if (ferror(sourceFile))
777 Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
779 // Assert is bogus Assert(bytes_read == BUF_SIZE || feof(sourceFile));
781 fwrite(buf,1,bytes_read,destFile);
782 if (ferror(destFile))
783 Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
786 // close the source/dest files
787 if (fclose(sourceFile))
788 Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
789 if (fclose(destFile))
790 Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
792 // Get the current hfs data for the new file
793 theDestPigHFSParams.fileParam.ioCompletion = nil;
794 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
795 theDestPigHFSParams.fileParam.ioVRefNum = 0;
796 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
797 theDestPigHFSParams.fileParam.ioDirID = 0;
798 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
799 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
801 // Error getting file time stamp!! Why? JTS
802 Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
805 // Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
806 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
807 theDestPigHFSParams.fileParam.ioVRefNum = 0;
808 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
809 theDestPigHFSParams.fileParam.ioDirID = 0;
811 // Copy the time stamp from the source file info
812 theDestPigHFSParams.fileParam.ioFlCrDat = theSourcePigHFSParams.fileParam.ioFlCrDat;
813 theDestPigHFSParams.fileParam.ioFlMdDat = theSourcePigHFSParams.fileParam.ioFlMdDat;
814 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
815 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
817 // Set the dest file's time stamp to the source file's time stamp values
818 theErr = PBHSetFInfo(&theDestPigHFSParams, false);
820 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
822 Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
825 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
827 return cfopen(destPathAndFileCStr, "rb");
830 #else //PC Version of copy_pigfile_from_cd is below
832 //copies a pigfile from the CD to the current dir
833 //retuns file handle of new pig
834 CFILE *copy_pigfile_from_cd(char *filename)
840 return cfopen(filename, "rb");
841 show_boxed_message("Copying bitmap data from CD...");
842 gr_palette_load(gr_palette); //I don't think this line is really needed
844 //First, delete all PIG files currently in the directory
846 if( !FileFindFirst( "*.pig", &find ) ) {
849 } while( !FileFindNext( &find ) );
853 //Now, copy over new pig
855 songs_stop_redbook(); //so we can read off the cd
857 //new code to unarj file
858 strcpy(name,CDROM_dir);
859 strcat(name,"descent2.sow");
862 // ret = unarj_specific_file(name,filename,filename);
867 if (ret != EXIT_SUCCESS) {
869 //delete file, so we don't leave partial file
873 if (request_cd() == -1)
875 //NOTE LINK TO ABOVE IF
876 Error("Cannot load file <%s> from CD",filename);
879 } while (ret != EXIT_SUCCESS);
881 return cfopen(filename, "rb");
884 #endif // end of ifdef MAC around copy_pigfile_from_cd
886 //initialize a pigfile, reading headers
887 //returns the size of all the bitmap data
888 void piggy_init_pigfile(char *filename)
892 char temp_name_read[16];
893 grs_bitmap temp_bitmap;
894 DiskBitmapHeader bmh;
895 int header_size, N_bitmaps, data_size, data_start;
897 char name[255]; // filename + path for the mac
900 piggy_close_file(); //close old pig if still open
902 //rename pigfile for shareware
903 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
904 filename = DEFAULT_PIGFILE_SHAREWARE;
907 Piggy_fp = cfopen( filename, "rb" );
909 sprintf(name, ":Data:%s", filename);
910 Piggy_fp = cfopen( name, "rb" );
912 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
913 if (Piggy_fp == NULL)
915 Error("Cannot load required file <%s>",name);
917 #endif // end of if def shareware
923 return; //if editor, ok to not have pig, because we'll build one
925 Piggy_fp = copy_pigfile_from_cd(filename);
929 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
930 int pig_id,pig_version;
932 pig_id = cfile_read_int(Piggy_fp);
933 pig_version = cfile_read_int(Piggy_fp);
934 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
935 cfclose(Piggy_fp); //out of date pig
936 Piggy_fp = NULL; //..so pretend it's not here
943 return; //if editor, ok to not have pig, because we'll build one
945 Error("Cannot load required file <%s>",filename);
949 strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
951 N_bitmaps = cfile_read_int(Piggy_fp);
953 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
955 data_start = header_size + cftell(Piggy_fp);
957 data_size = cfilelength(Piggy_fp) - data_start;
959 Num_bitmap_files = 1;
961 for (i=0; i<N_bitmaps; i++ ) {
962 DiskBitmapHeader_read(&bmh, Piggy_fp);
963 memcpy( temp_name_read, bmh.name, 8 );
964 temp_name_read[8] = 0;
965 if ( bmh.dflags & DBM_FLAG_ABM )
966 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
968 strcpy( temp_name, temp_name_read );
969 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
970 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
971 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
972 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
973 temp_bitmap.avg_color = bmh.avg_color;
974 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
976 GameBitmapFlags[i+1] = 0;
977 if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_TRANSPARENT;
978 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_SUPER_TRANSPARENT;
979 if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i+1] |= BM_FLAG_NO_LIGHTING;
980 if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i+1] |= BM_FLAG_RLE;
981 if ( bmh.flags & BM_FLAG_RLE_BIG ) GameBitmapFlags[i+1] |= BM_FLAG_RLE_BIG;
983 GameBitmapOffset[i+1] = bmh.offset + data_start;
984 Assert( (i+1) == Num_bitmap_files );
985 piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
989 Piggy_bitmap_cache_size = data_size + (data_size/10); //extra mem for new bitmaps
990 Assert( Piggy_bitmap_cache_size > 0 );
992 Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
994 if (piggy_low_memory)
995 Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
998 BitmapBits = d_malloc( Piggy_bitmap_cache_size );
999 if ( BitmapBits == NULL )
1000 Error( "Not enough memory to load bitmaps\n" );
1001 Piggy_bitmap_cache_data = BitmapBits;
1002 Piggy_bitmap_cache_next = 0;
1004 #if defined(MACINTOSH) && defined(SHAREWARE)
1005 // load_exit_models();
1008 Pigfile_initialized=1;
1011 #define FILENAME_LEN 13
1012 #define MAX_BITMAPS_PER_BRUSH 30
1014 extern int compute_average_pixel(grs_bitmap *new);
1016 //reads in a new pigfile (for new palette)
1017 //returns the size of all the bitmap data
1018 void piggy_new_pigfile(char *pigname)
1022 char temp_name_read[16];
1023 grs_bitmap temp_bitmap;
1024 DiskBitmapHeader bmh;
1025 int header_size, N_bitmaps, data_size, data_start;
1026 int must_rewrite_pig = 0;
1033 //rename pigfile for shareware
1034 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
1035 pigname = DEFAULT_PIGFILE_SHAREWARE;
1037 if (strnicmp(Current_pigfile,pigname,sizeof(Current_pigfile))==0)
1038 return; //already have correct pig
1040 if (!Pigfile_initialized) { //have we ever opened a pigfile?
1041 piggy_init_pigfile(pigname); //..no, so do initialization stuff
1045 piggy_close_file(); //close old pig if still open
1047 Piggy_bitmap_cache_next = 0; //free up cache
1049 strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
1052 Piggy_fp = cfopen( pigname, "rb" );
1054 sprintf(name, ":Data:%s", pigname);
1055 Piggy_fp = cfopen( name, "rb" );
1057 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
1058 if (Piggy_fp == NULL)
1060 Error("Cannot load required file <%s>",name);
1062 #endif // end of if def shareware
1067 Piggy_fp = copy_pigfile_from_cd(pigname);
1070 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1071 int pig_id,pig_version;
1073 pig_id = cfile_read_int(Piggy_fp);
1074 pig_version = cfile_read_int(Piggy_fp);
1075 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1076 cfclose(Piggy_fp); //out of date pig
1077 Piggy_fp = NULL; //..so pretend it's not here
1082 if (!Piggy_fp) Error ("Piggy_fp not defined in piggy_new_pigfile.");
1087 N_bitmaps = cfile_read_int(Piggy_fp);
1089 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
1091 data_start = header_size + cftell(Piggy_fp);
1093 data_size = cfilelength(Piggy_fp) - data_start;
1095 for (i=1; i<=N_bitmaps; i++ ) {
1096 DiskBitmapHeader_read(&bmh, Piggy_fp);
1097 memcpy( temp_name_read, bmh.name, 8 );
1098 temp_name_read[8] = 0;
1100 if ( bmh.dflags & DBM_FLAG_ABM )
1101 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
1103 strcpy( temp_name, temp_name_read );
1105 //Make sure name matches
1106 if (strcmp(temp_name,AllBitmaps[i].name)) {
1107 //Int3(); //this pig is out of date. Delete it
1111 strcpy(AllBitmaps[i].name,temp_name);
1113 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1115 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1116 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1117 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1118 temp_bitmap.avg_color = bmh.avg_color;
1119 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1121 GameBitmapFlags[i] = 0;
1123 if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i] |= BM_FLAG_TRANSPARENT;
1124 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i] |= BM_FLAG_SUPER_TRANSPARENT;
1125 if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i] |= BM_FLAG_NO_LIGHTING;
1126 if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i] |= BM_FLAG_RLE;
1127 if ( bmh.flags & BM_FLAG_RLE_BIG ) GameBitmapFlags[i] |= BM_FLAG_RLE_BIG;
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 ubyte *Bitmap_replacement_data=NULL;
2159 void free_bitmap_replacements()
2161 if (Bitmap_replacement_data) {
2162 d_free(Bitmap_replacement_data);
2163 Bitmap_replacement_data = NULL;
2167 void load_bitmap_replacements(char *level_name)
2169 char ifile_name[FILENAME_LEN];
2173 //first, free up data allocated for old bitmaps
2174 free_bitmap_replacements();
2176 change_filename_extension(ifile_name, level_name, ".POG" );
2178 ifile = cfopen(ifile_name,"rb");
2181 int id,version,n_bitmaps;
2182 int bitmap_data_size;
2185 id = cfile_read_int(ifile);
2186 version = cfile_read_int(ifile);
2188 if (id != MAKE_SIG('G','O','P','D') || version != 1) {
2193 n_bitmaps = cfile_read_int(ifile);
2195 MALLOC( indices, ushort, n_bitmaps );
2197 for (i = 0; i < n_bitmaps; i++)
2198 indices[i] = cfile_read_short(ifile);
2200 bitmap_data_size = cfilelength(ifile) - cftell(ifile) - DISKBITMAPHEADER_SIZE * n_bitmaps;
2201 MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
2203 for (i=0;i<n_bitmaps;i++) {
2204 DiskBitmapHeader bmh;
2205 grs_bitmap temp_bitmap;
2207 DiskBitmapHeader_read(&bmh, ifile);
2209 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2211 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2212 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2213 temp_bitmap.avg_color = bmh.avg_color;
2214 temp_bitmap.bm_data = Bitmap_replacement_data + bmh.offset;
2216 if ( bmh.flags & BM_FLAG_TRANSPARENT ) temp_bitmap.bm_flags |= BM_FLAG_TRANSPARENT;
2217 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) temp_bitmap.bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2218 if ( bmh.flags & BM_FLAG_NO_LIGHTING ) temp_bitmap.bm_flags |= BM_FLAG_NO_LIGHTING;
2219 if ( bmh.flags & BM_FLAG_RLE ) temp_bitmap.bm_flags |= BM_FLAG_RLE;
2220 if ( bmh.flags & BM_FLAG_RLE_BIG ) temp_bitmap.bm_flags |= BM_FLAG_RLE_BIG;
2222 GameBitmaps[indices[i]] = temp_bitmap;
2225 cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
2231 last_palette_loaded_pig[0]= 0; //force pig re-load
2233 texmerge_flush(); //for re-merging with new textures
2236 atexit(free_bitmap_replacements);
2239 #define FIRST_D1_TEXTURE 722
2240 #define LAST_D1_STATIC_TEXTURE 1042//1342 //afterwards, we have door frames and stuff
2241 #define FIRST_D2_TEXTURE 1243
2243 void load_d1_bitmap_replacements()
2245 CFILE * d1_Piggy_fp;
2246 grs_bitmap temp_bitmap;
2247 DiskBitmapHeader bmh;
2248 int pig_data_start, bitmap_header_start, bitmap_data_start;
2249 int N_bitmaps, zsize;
2250 int d1_index, d2_index;
2251 ubyte colormap[256];
2252 ubyte *next_bitmap; // to which address we write the next bitmap
2254 d1_Piggy_fp = cfopen( D1_PIGFILE, "rb" );
2257 return; // use d2 bitmaps instead...
2259 //first, free up data allocated for old bitmaps
2260 free_bitmap_replacements();
2262 // read d1 palette, build colormap
2265 ubyte d1_palette[256*3];
2266 CFILE * palette_file = cfopen( "palette.256", "rb" );
2267 Assert( palette_file );
2268 Assert( cfilelength( palette_file ) == 9472 );
2269 cfread( d1_palette, 256, 3, palette_file);
2270 cfclose( palette_file );
2271 build_colormap_good( d1_palette, colormap, freq );
2272 // don't change transparencies:
2273 colormap[254] = 254;
2274 colormap[255] = 255;
2277 switch (cfilelength(d1_Piggy_fp)) {
2278 case D1_SHAREWARE_10_PIGSIZE:
2279 case D1_SHAREWARE_PIGSIZE:
2285 case D1_OEM_PIGSIZE:
2286 case D1_MAC_PIGSIZE:
2287 case D1_MAC_SHARE_PIGSIZE:
2289 pig_data_start = cfile_read_int(d1_Piggy_fp );
2290 bm_read_all_d1( d1_Piggy_fp );
2291 //for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2295 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2296 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2298 int N_sounds = cfile_read_int(d1_Piggy_fp);
2299 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2300 + N_sounds * DISKSOUNDHEADER_SIZE;
2301 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2302 bitmap_data_start = bitmap_header_start + header_size;
2305 MALLOC( Bitmap_replacement_data, ubyte, cfilelength(d1_Piggy_fp) - bitmap_data_start ); // too much
2306 //TODO: handle case where b_r_d == 0! (have to convert textures, return, not bm_read_all_d1)
2308 next_bitmap = Bitmap_replacement_data;
2310 for (d1_index=1; d1_index<=N_bitmaps; d1_index++ ) {
2311 // only change wall texture bitmaps
2312 if (d1_index >= FIRST_D1_TEXTURE && d1_index <= LAST_D1_STATIC_TEXTURE) {
2313 d2_index = d1_index + FIRST_D2_TEXTURE - FIRST_D1_TEXTURE;
2315 cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2316 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2318 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2320 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2321 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2322 temp_bitmap.avg_color = bmh.avg_color;
2324 //GameBitmapFlags[convert_d1_bitmap_num(d1_index)] = 0;
2326 if ( bmh.flags & BM_FLAG_TRANSPARENT )
2327 temp_bitmap.bm_flags |= BM_FLAG_TRANSPARENT;
2328 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT )
2329 temp_bitmap.bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2330 if ( bmh.flags & BM_FLAG_NO_LIGHTING )
2331 temp_bitmap.bm_flags |= BM_FLAG_NO_LIGHTING;
2332 if ( bmh.flags & BM_FLAG_RLE )
2333 temp_bitmap.bm_flags |= BM_FLAG_RLE;
2334 if ( bmh.flags & BM_FLAG_RLE_BIG )
2335 temp_bitmap.bm_flags |= BM_FLAG_RLE_BIG;
2337 temp_bitmap.bm_data = next_bitmap;
2339 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2340 zsize = cfile_read_int(d1_Piggy_fp);
2341 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2342 cfread(next_bitmap, 1, zsize, d1_Piggy_fp);
2344 switch(cfilelength(d1_Piggy_fp)) {
2345 case D1_MAC_PIGSIZE:
2346 case D1_MAC_SHARE_PIGSIZE:
2347 rle_swap_0_255(&temp_bitmap);
2349 rle_remap(&temp_bitmap, colormap);
2351 GameBitmaps[d2_index] = temp_bitmap;
2353 memcpy(&zsize, temp_bitmap.bm_data, 4);
2354 next_bitmap += zsize;
2358 cfclose(d1_Piggy_fp);
2360 last_palette_loaded_pig[0]= 0; //force pig re-load
2362 texmerge_flush(); //for re-merging with new textures
2364 atexit(free_bitmap_replacements);
2368 extern int extra_bitmap_num;
2371 * Find and load the named bitmap from descent.pig
2372 * similar to exitmodel_bm_load_sub
2374 bitmap_index read_extra_d1_bitmap(char *name)
2376 bitmap_index bitmap_num;
2377 grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2379 bitmap_num.index = 0;
2384 DiskBitmapHeader bmh;
2385 int pig_data_start, bitmap_header_start, bitmap_data_start;
2386 int N_bitmaps, zsize;
2387 ubyte colormap[256];
2389 d1_Piggy_fp = cfopen(D1_PIGFILE, "rb");
2392 con_printf(CON_DEBUG, "could not open %s\n", D1_PIGFILE);
2396 // read d1 palette, build colormap
2399 ubyte d1_palette[256*3];
2400 CFILE * palette_file = cfopen( "palette.256", "rb" );
2401 Assert( palette_file );
2402 Assert( cfilelength( palette_file ) == 9472 );
2403 cfread( d1_palette, 256, 3, palette_file);
2404 cfclose( palette_file );
2405 build_colormap_good( d1_palette, colormap, freq );
2406 // don't change transparencies:
2407 colormap[254] = 254;
2408 colormap[255] = 255;
2411 switch (cfilelength(d1_Piggy_fp)) {
2412 case D1_SHAREWARE_10_PIGSIZE:
2413 case D1_SHAREWARE_PIGSIZE:
2419 case D1_OEM_PIGSIZE:
2420 case D1_MAC_PIGSIZE:
2421 case D1_MAC_SHARE_PIGSIZE:
2422 pig_data_start = cfile_read_int(d1_Piggy_fp);
2426 cfseek(d1_Piggy_fp, pig_data_start, SEEK_SET);
2427 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2429 int N_sounds = cfile_read_int(d1_Piggy_fp);
2430 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2431 + N_sounds * DISKSOUNDHEADER_SIZE;
2432 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2433 bitmap_data_start = bitmap_header_start + header_size;
2436 for (i = 0; i < N_bitmaps; i++)
2438 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2439 if (!strnicmp(bmh.name, name, 8))
2443 Assert(!strnicmp(bmh.name, name, 8));
2445 memset( new, 0, sizeof(grs_bitmap) );
2447 new->bm_w = new->bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2448 new->bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2449 new->avg_color = bmh.avg_color;
2451 if ( bmh.flags & BM_FLAG_TRANSPARENT )
2452 new->bm_flags |= BM_FLAG_TRANSPARENT;
2453 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT )
2454 new->bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2455 if ( bmh.flags & BM_FLAG_NO_LIGHTING )
2456 new->bm_flags |= BM_FLAG_NO_LIGHTING;
2457 if ( bmh.flags & BM_FLAG_RLE )
2458 new->bm_flags |= BM_FLAG_RLE;
2459 if ( bmh.flags & BM_FLAG_RLE_BIG )
2460 new->bm_flags |= BM_FLAG_RLE_BIG;
2462 if ( bmh.flags & BM_FLAG_RLE )
2464 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2465 zsize = cfile_read_int(d1_Piggy_fp);
2468 zsize = new->bm_w * new->bm_h;
2469 new->bm_data = d_malloc(zsize);
2470 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2471 cfread(new->bm_data, 1, zsize, d1_Piggy_fp);
2473 switch(cfilelength(d1_Piggy_fp)) {
2474 case D1_MAC_PIGSIZE:
2475 case D1_MAC_SHARE_PIGSIZE:
2476 rle_swap_0_255(new);
2478 rle_remap(new, colormap);
2480 cfclose(d1_Piggy_fp);
2483 new->avg_color = 0; //compute_average_pixel(new);
2485 bitmap_num.index = extra_bitmap_num;
2487 GameBitmaps[extra_bitmap_num++] = *new;
2493 #ifndef FAST_FILE_IO
2495 * reads a bitmap_index structure from a CFILE
2497 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2499 bi->index = cfile_read_short(fp);
2503 * reads n bitmap_index structs from a CFILE
2505 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2509 for (i = 0; i < n; i++)
2510 bi[i].index = cfile_read_short(fp);
2515 * reads a DiskBitmapHeader structure from a CFILE
2517 void DiskBitmapHeader_read(DiskBitmapHeader *dbh, CFILE *fp)
2519 cfread(dbh->name, 8, 1, fp);
2520 dbh->dflags = cfile_read_byte(fp);
2521 dbh->width = cfile_read_byte(fp);
2522 dbh->height = cfile_read_byte(fp);
2523 dbh->wh_extra = cfile_read_byte(fp);
2524 dbh->flags = cfile_read_byte(fp);
2525 dbh->avg_color = cfile_read_byte(fp);
2526 dbh->offset = cfile_read_int(fp);
2530 * reads a DiskSoundHeader structure from a CFILE
2532 void DiskSoundHeader_read(DiskSoundHeader *dsh, CFILE *fp)
2534 cfread(dsh->name, 8, 1, fp);
2535 dsh->length = cfile_read_int(fp);
2536 dsh->data_length = cfile_read_int(fp);
2537 dsh->offset = cfile_read_int(fp);
2539 #endif // FAST_FILE_IO
2542 * reads a descent 1 DiskBitmapHeader structure from a CFILE
2544 void DiskBitmapHeader_d1_read(DiskBitmapHeader *dbh, CFILE *fp)
2546 cfread(dbh->name, 8, 1, fp);
2547 dbh->dflags = cfile_read_byte(fp);
2548 dbh->width = cfile_read_byte(fp);
2549 dbh->height = cfile_read_byte(fp);
2551 dbh->flags = cfile_read_byte(fp);
2552 dbh->avg_color = cfile_read_byte(fp);
2553 dbh->offset = cfile_read_int(fp);