1 /* $Id: piggy.c,v 1.34 2003-08-02 18:17:50 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.34 2003-08-02 18:17:50 btb Exp $";
411 #include "gamefont.h"
415 #include "texmerge.h"
421 #include "byteswap.h"
422 #include "findfile.h"
426 // #include "unarj.h"
428 #include <Strings.h> // MacOS Toolbox header
433 //#define NO_DUMP_SOUNDS 1 //if set, dump bitmaps but not sounds
435 #define DEFAULT_PIGFILE_REGISTERED "groupa.pig"
436 #define DEFAULT_PIGFILE_SHAREWARE "d2demo.pig"
437 #define DEFAULT_HAMFILE_REGISTERED "descent2.ham"
438 #define DEFAULT_HAMFILE_SHAREWARE "d2demo.ham"
440 #define D1_PALETTE "palette.256"
442 #define DEFAULT_PIGFILE (cfexist(DEFAULT_PIGFILE_REGISTERED)?DEFAULT_PIGFILE_REGISTERED:DEFAULT_PIGFILE_SHAREWARE)
443 #define DEFAULT_HAMFILE (cfexist(DEFAULT_HAMFILE_REGISTERED)?DEFAULT_HAMFILE_REGISTERED:DEFAULT_HAMFILE_SHAREWARE)
444 #define DEFAULT_SNDFILE ((Piggy_hamfile_version < 3)?DEFAULT_HAMFILE_SHAREWARE:(digi_sample_rate==SAMPLE_RATE_22K)?"descent2.s22":"descent2.s11")
446 #define MAC_ALIEN1_PIGSIZE 5013035
447 #define MAC_ALIEN2_PIGSIZE 4909916
448 #define MAC_FIRE_PIGSIZE 4969035
449 #define MAC_GROUPA_PIGSIZE 4929684 // also used for mac shareware
450 #define MAC_ICE_PIGSIZE 4923425
451 #define MAC_WATER_PIGSIZE 4832403
453 ubyte *BitmapBits = NULL;
454 ubyte *SoundBits = NULL;
456 typedef struct BitmapFile {
460 typedef struct SoundFile {
464 hashtable AllBitmapsNames;
465 hashtable AllDigiSndNames;
467 int Num_bitmap_files = 0;
468 int Num_sound_files = 0;
470 digi_sound GameSounds[MAX_SOUND_FILES];
471 int SoundOffset[MAX_SOUND_FILES];
472 grs_bitmap GameBitmaps[MAX_BITMAP_FILES];
474 alias alias_list[MAX_ALIASES];
477 int Must_write_hamfile = 0;
478 int Num_bitmap_files_new = 0;
479 int Num_sound_files_new = 0;
480 BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
481 static SoundFile AllSounds[ MAX_SOUND_FILES ];
483 int Piggy_hamfile_version = 0;
485 int piggy_low_memory = 0;
487 int Piggy_bitmap_cache_size = 0;
488 int Piggy_bitmap_cache_next = 0;
489 ubyte * Piggy_bitmap_cache_data = NULL;
490 static int GameBitmapOffset[MAX_BITMAP_FILES];
491 static ubyte GameBitmapFlags[MAX_BITMAP_FILES];
492 ushort GameBitmapXlat[MAX_BITMAP_FILES];
494 #define PIGGY_BUFFER_SIZE (2400*1024)
497 #define PIGGY_SMALL_BUFFER_SIZE (1400*1024) // size of buffer when piggy_low_memory is set
500 #undef PIGGY_BUFFER_SIZE
501 #undef PIGGY_SMALL_BUFFER_SIZE
503 #define PIGGY_BUFFER_SIZE (2000*1024)
504 #define PIGGY_SMALL_BUFFER_SIZE (1100 * 1024)
509 int piggy_page_flushed = 0;
511 #define DBM_FLAG_ABM 64
513 #define BM_FLAGS_TO_COPY (BM_FLAG_TRANSPARENT | BM_FLAG_SUPER_TRANSPARENT \
514 | BM_FLAG_NO_LIGHTING | BM_FLAG_RLE | BM_FLAG_RLE_BIG)
519 extern short cd_VRefNum;
520 extern void ConcatPStr(StringPtr dst, StringPtr src);
521 extern int ConvertPToCStr(StringPtr inPStr, char* outCStrBuf);
522 extern int ConvertCToPStr(char* inCStr, StringPtr outPStrBuf);
525 int piggy_is_substitutable_bitmap( char * name, char * subst_name );
528 void piggy_write_pigfile(char *filename);
529 static void write_int(int i,FILE *file);
532 void swap_0_255(grs_bitmap *bmp)
536 for (i = 0; i < bmp->bm_h * bmp->bm_w; i++) {
537 if(bmp->bm_data[i] == 0)
538 bmp->bm_data[i] = 255;
539 else if (bmp->bm_data[i] == 255)
544 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
547 Assert( Num_bitmap_files < MAX_BITMAP_FILES );
549 temp.index = Num_bitmap_files;
553 if ( FindArg("-macdata") )
556 if ( !BigPig ) gr_bitmap_rle_compress( bmp );
557 Num_bitmap_files_new++;
560 strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
561 hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
562 GameBitmaps[Num_bitmap_files] = *bmp;
564 GameBitmapOffset[Num_bitmap_files] = 0;
565 GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
572 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
576 Assert( Num_sound_files < MAX_SOUND_FILES );
578 strncpy( AllSounds[Num_sound_files].name, name, 12 );
579 hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
580 GameSounds[Num_sound_files] = *snd;
582 SoundOffset[Num_sound_files] = 0;
588 Num_sound_files_new++;
594 bitmap_index piggy_find_bitmap( char * name )
602 if ((t=strchr(name,'#'))!=NULL)
605 for (i=0;i<Num_aliases;i++)
606 if (stricmp(name,alias_list[i].alias_name)==0) {
607 if (t) { //extra stuff for ABMs
608 static char temp[FILENAME_LEN];
609 _splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
615 name=alias_list[i].file_name;
622 i = hashtable_search( &AllBitmapsNames, name );
631 int piggy_find_sound( char * name )
635 i = hashtable_search( &AllDigiSndNames, name );
643 CFILE * Piggy_fp = NULL;
645 #define FILENAME_LEN 13
647 char Current_pigfile[FILENAME_LEN] = "";
649 void piggy_close_file()
654 Current_pigfile[0] = 0;
658 int Pigfile_initialized=0;
660 #define PIGFILE_ID MAKE_SIG('G','I','P','P') //PPIG
661 #define PIGFILE_VERSION 2
663 extern char CDROM_dir[];
665 int request_cd(void);
670 //copies a pigfile from the CD to the current dir
671 //retuns file handle of new pig
672 CFILE *copy_pigfile_from_cd(char *filename) // MACINTOSH VERSION
675 char sourcePathAndFileCStr[255] = "";
676 char destPathAndFileCStr[255] = "";
678 FILE* sourceFile = NULL;
679 FILE* destFile = NULL;
680 const int BUF_SIZE = 4096;
684 Str255 sourcePathAndFilePStr = "\p";
685 Str255 destPathAndFilePStr = "\p";
686 Str255 pigfileNamePStr = "\p";
687 HParamBlockRec theSourcePigHFSParams;
688 HParamBlockRec theDestPigHFSParams;
689 OSErr theErr = noErr;
690 char oldDirCStr[255] = "";
692 getcwd(oldDirCStr, 255);
694 show_boxed_message("Copying bitmap data from CD...");
695 gr_palette_load(gr_palette); //I don't think this line is really needed
698 //First, delete all PIG files currently in the directory
699 if( !FileFindFirst( "*.pig", &find ) )
704 } while( !FileFindNext( &find ) );
710 //Now, copy over new pig
711 songs_stop_redbook(); //so we can read off the cd
713 // make the source path "<cd volume>:Data:filename.pig"
714 //MWA ConvertCToPStr(filename, pigfileNamePStr);
716 //MWA ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:"); // volume ID is cd_VRefNum
717 //MWA ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
720 strcpy(sourcePathAndFileCStr, "Descent II:Data:");
721 strcat(sourcePathAndFileCStr, filename);
723 // make the destination path "<default directory>:Data:filename.pig"
724 //MWA ConcatPStr(destPathAndFilePStr, "\p:Data:");
725 //MWA ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
726 //MWA ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
727 //MWA ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
729 strcpy(destPathAndFileCStr, ":Data:");
730 strcat(destPathAndFileCStr, filename);
732 strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
733 strcpy(destPathAndFilePStr, destPathAndFileCStr);
734 c2pstr(sourcePathAndFilePStr);
735 c2pstr(destPathAndFilePStr);
738 // Open the source file
739 sourceFile = fopen(sourcePathAndFileCStr,"rb");
743 if (request_cd() == -1)
744 Error("Cannot load file <%s> from CD",filename);
747 } while (!sourceFile);
750 // Get the time stamp from the source file
751 theSourcePigHFSParams.fileParam.ioCompletion = nil;
752 theSourcePigHFSParams.fileParam.ioNamePtr = sourcePathAndFilePStr;
753 theSourcePigHFSParams.fileParam.ioVRefNum = cd_VRefNum;
754 theSourcePigHFSParams.fileParam.ioFDirIndex = 0;
755 theSourcePigHFSParams.fileParam.ioDirID = 0;
757 theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
760 // Error getting file time stamp!! Why? JTS
761 Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
764 // Copy the file over
767 // Open the destination file
768 destFile = fopen(destPathAndFileCStr,"wb");
771 Error("Cannot create file: <%s>\n", destPathAndFileCStr);
774 // Copy bytes until the end of the source file
775 while (!feof(sourceFile))
780 bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
781 if (ferror(sourceFile))
782 Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
784 // Assert is bogus Assert(bytes_read == BUF_SIZE || feof(sourceFile));
786 fwrite(buf,1,bytes_read,destFile);
787 if (ferror(destFile))
788 Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
791 // close the source/dest files
792 if (fclose(sourceFile))
793 Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
794 if (fclose(destFile))
795 Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
797 // Get the current hfs data for the new file
798 theDestPigHFSParams.fileParam.ioCompletion = nil;
799 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
800 theDestPigHFSParams.fileParam.ioVRefNum = 0;
801 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
802 theDestPigHFSParams.fileParam.ioDirID = 0;
803 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
804 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
806 // Error getting file time stamp!! Why? JTS
807 Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
810 // Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
811 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
812 theDestPigHFSParams.fileParam.ioVRefNum = 0;
813 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
814 theDestPigHFSParams.fileParam.ioDirID = 0;
816 // Copy the time stamp from the source file info
817 theDestPigHFSParams.fileParam.ioFlCrDat = theSourcePigHFSParams.fileParam.ioFlCrDat;
818 theDestPigHFSParams.fileParam.ioFlMdDat = theSourcePigHFSParams.fileParam.ioFlMdDat;
819 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
820 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
822 // Set the dest file's time stamp to the source file's time stamp values
823 theErr = PBHSetFInfo(&theDestPigHFSParams, false);
825 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
827 Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
830 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
832 return cfopen(destPathAndFileCStr, "rb");
835 #else //PC Version of copy_pigfile_from_cd is below
837 //copies a pigfile from the CD to the current dir
838 //retuns file handle of new pig
839 CFILE *copy_pigfile_from_cd(char *filename)
845 return cfopen(filename, "rb");
846 show_boxed_message("Copying bitmap data from CD...");
847 gr_palette_load(gr_palette); //I don't think this line is really needed
849 //First, delete all PIG files currently in the directory
851 if( !FileFindFirst( "*.pig", &find ) ) {
853 cfile_delete(find.name);
854 } while( !FileFindNext( &find ) );
858 //Now, copy over new pig
860 songs_stop_redbook(); //so we can read off the cd
862 //new code to unarj file
863 strcpy(name,CDROM_dir);
864 strcat(name,"descent2.sow");
867 // ret = unarj_specific_file(name,filename,filename);
872 if (ret != EXIT_SUCCESS) {
874 //delete file, so we don't leave partial file
875 cfile_delete(filename);
878 if (request_cd() == -1)
880 //NOTE LINK TO ABOVE IF
881 Error("Cannot load file <%s> from CD",filename);
884 } while (ret != EXIT_SUCCESS);
886 return cfopen(filename, "rb");
889 #endif // end of ifdef MAC around copy_pigfile_from_cd
891 //initialize a pigfile, reading headers
892 //returns the size of all the bitmap data
893 void piggy_init_pigfile(char *filename)
897 char temp_name_read[16];
898 grs_bitmap temp_bitmap;
899 DiskBitmapHeader bmh;
900 int header_size, N_bitmaps, data_size, data_start;
902 char name[255]; // filename + path for the mac
905 piggy_close_file(); //close old pig if still open
907 //rename pigfile for shareware
908 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
909 filename = DEFAULT_PIGFILE_SHAREWARE;
912 Piggy_fp = cfopen( filename, "rb" );
914 sprintf(name, ":Data:%s", filename);
915 Piggy_fp = cfopen( name, "rb" );
917 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
918 if (Piggy_fp == NULL)
920 Error("Cannot load required file <%s>",name);
922 #endif // end of if def shareware
928 return; //if editor, ok to not have pig, because we'll build one
930 Piggy_fp = copy_pigfile_from_cd(filename);
934 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
935 int pig_id,pig_version;
937 pig_id = cfile_read_int(Piggy_fp);
938 pig_version = cfile_read_int(Piggy_fp);
939 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
940 cfclose(Piggy_fp); //out of date pig
941 Piggy_fp = NULL; //..so pretend it's not here
948 return; //if editor, ok to not have pig, because we'll build one
950 Error("Cannot load required file <%s>",filename);
954 strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
956 N_bitmaps = cfile_read_int(Piggy_fp);
958 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
960 data_start = header_size + cftell(Piggy_fp);
962 data_size = cfilelength(Piggy_fp) - data_start;
964 Num_bitmap_files = 1;
966 for (i=0; i<N_bitmaps; i++ ) {
967 DiskBitmapHeader_read(&bmh, Piggy_fp);
968 memcpy( temp_name_read, bmh.name, 8 );
969 temp_name_read[8] = 0;
970 if ( bmh.dflags & DBM_FLAG_ABM )
971 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
973 strcpy( temp_name, temp_name_read );
974 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
975 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
976 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
977 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
978 temp_bitmap.avg_color = bmh.avg_color;
979 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
981 GameBitmapFlags[i+1] = bmh.flags & BM_FLAGS_TO_COPY;
983 GameBitmapOffset[i+1] = bmh.offset + data_start;
984 Assert( (i+1) == Num_bitmap_files );
985 piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
989 Piggy_bitmap_cache_size = data_size + (data_size/10); //extra mem for new bitmaps
990 Assert( Piggy_bitmap_cache_size > 0 );
992 Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
994 if (piggy_low_memory)
995 Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
998 BitmapBits = d_malloc( Piggy_bitmap_cache_size );
999 if ( BitmapBits == NULL )
1000 Error( "Not enough memory to load bitmaps\n" );
1001 Piggy_bitmap_cache_data = BitmapBits;
1002 Piggy_bitmap_cache_next = 0;
1004 #if defined(MACINTOSH) && defined(SHAREWARE)
1005 // load_exit_models();
1008 Pigfile_initialized=1;
1011 #define FILENAME_LEN 13
1012 #define MAX_BITMAPS_PER_BRUSH 30
1014 extern int compute_average_pixel(grs_bitmap *new);
1016 //reads in a new pigfile (for new palette)
1017 //returns the size of all the bitmap data
1018 void piggy_new_pigfile(char *pigname)
1022 char temp_name_read[16];
1023 grs_bitmap temp_bitmap;
1024 DiskBitmapHeader bmh;
1025 int header_size, N_bitmaps, data_size, data_start;
1026 int must_rewrite_pig = 0;
1033 //rename pigfile for shareware
1034 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
1035 pigname = DEFAULT_PIGFILE_SHAREWARE;
1037 if (strnicmp(Current_pigfile,pigname,sizeof(Current_pigfile))==0)
1038 return; //already have correct pig
1040 if (!Pigfile_initialized) { //have we ever opened a pigfile?
1041 piggy_init_pigfile(pigname); //..no, so do initialization stuff
1045 piggy_close_file(); //close old pig if still open
1047 Piggy_bitmap_cache_next = 0; //free up cache
1049 strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
1052 Piggy_fp = cfopen( pigname, "rb" );
1054 sprintf(name, ":Data:%s", pigname);
1055 Piggy_fp = cfopen( name, "rb" );
1057 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
1058 if (Piggy_fp == NULL)
1060 Error("Cannot load required file <%s>",name);
1062 #endif // end of if def shareware
1067 Piggy_fp = copy_pigfile_from_cd(pigname);
1070 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1071 int pig_id,pig_version;
1073 pig_id = cfile_read_int(Piggy_fp);
1074 pig_version = cfile_read_int(Piggy_fp);
1075 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1076 cfclose(Piggy_fp); //out of date pig
1077 Piggy_fp = NULL; //..so pretend it's not here
1083 Error("Cannot open correct version of <%s>", pigname);
1088 N_bitmaps = cfile_read_int(Piggy_fp);
1090 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
1092 data_start = header_size + cftell(Piggy_fp);
1094 data_size = cfilelength(Piggy_fp) - data_start;
1096 for (i=1; i<=N_bitmaps; i++ ) {
1097 DiskBitmapHeader_read(&bmh, Piggy_fp);
1098 memcpy( temp_name_read, bmh.name, 8 );
1099 temp_name_read[8] = 0;
1101 if ( bmh.dflags & DBM_FLAG_ABM )
1102 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
1104 strcpy( temp_name, temp_name_read );
1106 //Make sure name matches
1107 if (strcmp(temp_name,AllBitmaps[i].name)) {
1108 //Int3(); //this pig is out of date. Delete it
1112 strcpy(AllBitmaps[i].name,temp_name);
1114 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1116 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1117 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1118 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1119 temp_bitmap.avg_color = bmh.avg_color;
1120 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1122 GameBitmapFlags[i] = bmh.flags & BM_FLAGS_TO_COPY;
1124 GameBitmapOffset[i] = bmh.offset + data_start;
1126 GameBitmaps[i] = temp_bitmap;
1130 N_bitmaps = 0; //no pigfile, so no bitmaps
1134 Assert(N_bitmaps == Num_bitmap_files-1);
1138 if (must_rewrite_pig || (N_bitmaps < Num_bitmap_files-1)) {
1141 //re-read the bitmaps that aren't in this pig
1143 for (i=N_bitmaps+1;i<Num_bitmap_files;i++) {
1146 p = strchr(AllBitmaps[i].name,'#');
1148 if (p) { //this is an ABM
1149 char abmname[FILENAME_LEN];
1151 grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
1152 int iff_error; //reference parm to avoid warning message
1154 char basename[FILENAME_LEN];
1157 strcpy(basename,AllBitmaps[i].name);
1158 basename[p-AllBitmaps[i].name] = 0; //cut off "#nn" part
1160 sprintf( abmname, "%s.abm", basename );
1162 iff_error = iff_read_animbrush(abmname,bm,MAX_BITMAPS_PER_BRUSH,&nframes,newpal);
1164 if (iff_error != IFF_NO_ERROR) {
1165 mprintf((1,"File %s - IFF error: %s",abmname,iff_errormsg(iff_error)));
1166 Error("File %s - IFF error: %s",abmname,iff_errormsg(iff_error));
1169 for (fnum=0;fnum<nframes; fnum++) {
1173 sprintf( tempname, "%s#%d", basename, fnum );
1175 //SuperX = (GameBitmaps[i+fnum].bm_flags&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1176 SuperX = (GameBitmapFlags[i+fnum]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1177 //above makes assumption that supertransparent color is 254
1179 if ( iff_has_transparency )
1180 gr_remap_bitmap_good( bm[fnum], newpal, iff_transparent_color, SuperX );
1182 gr_remap_bitmap_good( bm[fnum], newpal, -1, SuperX );
1184 bm[fnum]->avg_color = compute_average_pixel(bm[fnum]);
1187 if ( FindArg("-macdata") )
1188 swap_0_255( bm[fnum] );
1190 if ( !BigPig ) gr_bitmap_rle_compress( bm[fnum] );
1192 if (bm[fnum]->bm_flags & BM_FLAG_RLE)
1193 size = *((int *) bm[fnum]->bm_data);
1195 size = bm[fnum]->bm_w * bm[fnum]->bm_h;
1197 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],bm[fnum]->bm_data,size);
1198 d_free(bm[fnum]->bm_data);
1199 bm[fnum]->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1200 Piggy_bitmap_cache_next += size;
1202 GameBitmaps[i+fnum] = *bm[fnum];
1204 // -- mprintf( (0, "U" ));
1208 i += nframes-1; //filled in multiple bitmaps
1210 else { //this is a BBM
1213 ubyte newpal[256*3];
1215 char bbmname[FILENAME_LEN];
1218 MALLOC( new, grs_bitmap, 1 );
1220 sprintf( bbmname, "%s.bbm", AllBitmaps[i].name );
1221 iff_error = iff_read_bitmap(bbmname,new,BM_LINEAR,newpal);
1224 if (iff_error != IFF_NO_ERROR) {
1225 mprintf((1, "File %s - IFF error: %s",bbmname,iff_errormsg(iff_error)));
1226 Error("File %s - IFF error: %s",bbmname,iff_errormsg(iff_error));
1229 SuperX = (GameBitmapFlags[i]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1230 //above makes assumption that supertransparent color is 254
1232 if ( iff_has_transparency )
1233 gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
1235 gr_remap_bitmap_good( new, newpal, -1, SuperX );
1237 new->avg_color = compute_average_pixel(new);
1240 if ( FindArg("-macdata") )
1243 if ( !BigPig ) gr_bitmap_rle_compress( new );
1245 if (new->bm_flags & BM_FLAG_RLE)
1246 size = *((int *) new->bm_data);
1248 size = new->bm_w * new->bm_h;
1250 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],new->bm_data,size);
1251 d_free(new->bm_data);
1252 new->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1253 Piggy_bitmap_cache_next += size;
1255 GameBitmaps[i] = *new;
1259 // -- mprintf( (0, "U" ));
1263 //@@Dont' do these things which are done when writing
1264 //@@for (i=0; i < Num_bitmap_files; i++ ) {
1265 //@@ bitmap_index bi;
1267 //@@ PIGGY_PAGE_IN( bi );
1270 //@@piggy_close_file();
1272 piggy_write_pigfile(pigname);
1274 Current_pigfile[0] = 0; //say no pig, to force reload
1276 piggy_new_pigfile(pigname); //read in just-generated pig
1280 #endif //ifdef EDITOR
1284 ubyte bogus_data[64*64];
1285 grs_bitmap bogus_bitmap;
1286 ubyte bogus_bitmap_initialized=0;
1287 digi_sound bogus_sound;
1289 #define HAMFILE_ID MAKE_SIG('!','M','A','H') //HAM!
1290 #define HAMFILE_VERSION 3
1291 //version 1 -> 2: save marker_model_num
1292 //version 2 -> 3: removed sound files
1294 #define SNDFILE_ID MAKE_SIG('D','N','S','D') //DSND
1295 #define SNDFILE_VERSION 1
1299 CFILE * ham_fp = NULL;
1301 int sound_offset = 0;
1307 ham_fp = cfopen( DEFAULT_HAMFILE, "rb" );
1309 sprintf(name, ":Data:%s", DEFAULT_HAMFILE );
1310 ham_fp = cfopen( name, "rb" );
1313 if (ham_fp == NULL) {
1314 Must_write_hamfile = 1;
1318 //make sure ham is valid type file & is up-to-date
1319 ham_id = cfile_read_int(ham_fp);
1320 Piggy_hamfile_version = cfile_read_int(ham_fp);
1321 if (ham_id != HAMFILE_ID)
1322 Error("Cannot open ham file %s\n", DEFAULT_HAMFILE);
1324 if (ham_id != HAMFILE_ID || Piggy_hamfile_version != HAMFILE_VERSION) {
1325 Must_write_hamfile = 1;
1326 cfclose(ham_fp); //out of date ham
1331 if (Piggy_hamfile_version < 3) // hamfile contains sound info
1332 sound_offset = cfile_read_int(ham_fp);
1338 bm_read_all(ham_fp);
1339 cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1341 //for (i = 0; i < MAX_BITMAP_FILES; i++) {
1342 //GameBitmapXlat[i] = INTEL_SHORT(GameBitmapXlat[i]);
1343 //printf("GameBitmapXlat[%d] = %d\n", i, GameBitmapXlat[i]);
1348 if (Piggy_hamfile_version < 3) {
1353 DiskSoundHeader sndh;
1354 digi_sound temp_sound;
1355 char temp_name_read[16];
1358 cfseek(ham_fp, sound_offset, SEEK_SET);
1359 N_sounds = cfile_read_int(ham_fp);
1361 sound_start = cftell(ham_fp);
1363 header_size = N_sounds * DISKSOUNDHEADER_SIZE;
1367 for (i=0; i<N_sounds; i++ ) {
1368 DiskSoundHeader_read(&sndh, ham_fp);
1369 temp_sound.length = sndh.length;
1370 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1371 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1372 memcpy( temp_name_read, sndh.name, 8 );
1373 temp_name_read[8] = 0;
1374 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1376 if (piggy_is_needed(i))
1377 #endif // note link to if.
1378 sbytes += sndh.length;
1379 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1382 SoundBits = d_malloc( sbytes + 16 );
1383 if ( SoundBits == NULL )
1384 Error( "Not enough memory to load sounds\n" );
1386 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1388 // piggy_read_sounds(ham_fp);
1400 CFILE * snd_fp = NULL;
1401 int snd_id,snd_version;
1406 DiskSoundHeader sndh;
1407 digi_sound temp_sound;
1408 char temp_name_read[16];
1415 snd_fp = cfopen( DEFAULT_SNDFILE, "rb" );
1417 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1418 snd_fp = cfopen( name, "rb");
1424 //make sure soundfile is valid type file & is up-to-date
1425 snd_id = cfile_read_int(snd_fp);
1426 snd_version = cfile_read_int(snd_fp);
1427 if (snd_id != SNDFILE_ID || snd_version != SNDFILE_VERSION) {
1428 cfclose(snd_fp); //out of date sound file
1432 N_sounds = cfile_read_int(snd_fp);
1434 sound_start = cftell(snd_fp);
1435 size = cfilelength(snd_fp) - sound_start;
1437 mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
1439 header_size = N_sounds*sizeof(DiskSoundHeader);
1443 for (i=0; i<N_sounds; i++ ) {
1444 DiskSoundHeader_read(&sndh, snd_fp);
1445 //size -= sizeof(DiskSoundHeader);
1446 temp_sound.length = sndh.length;
1447 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1448 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1449 memcpy( temp_name_read, sndh.name, 8 );
1450 temp_name_read[8] = 0;
1451 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1453 if (piggy_is_needed(i))
1454 #endif // note link to if.
1455 sbytes += sndh.length;
1456 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1459 SoundBits = d_malloc( sbytes + 16 );
1460 if ( SoundBits == NULL )
1461 Error( "Not enough memory to load sounds\n" );
1463 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1465 // piggy_read_sounds(snd_fp);
1472 int piggy_init(void)
1474 int ham_ok=0,snd_ok=0;
1477 hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
1478 hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
1480 for (i=0; i<MAX_SOUND_FILES; i++ ) {
1481 GameSounds[i].length = 0;
1482 GameSounds[i].data = NULL;
1486 for (i=0; i<MAX_BITMAP_FILES; i++ )
1487 GameBitmapXlat[i] = i;
1489 if ( !bogus_bitmap_initialized ) {
1492 bogus_bitmap_initialized = 1;
1493 memset( &bogus_bitmap, 0, sizeof(grs_bitmap) );
1494 bogus_bitmap.bm_w = bogus_bitmap.bm_h = bogus_bitmap.bm_rowsize = 64;
1495 bogus_bitmap.bm_data = bogus_data;
1496 c = gr_find_closest_color( 0, 0, 63 );
1497 for (i=0; i<4096; i++ ) bogus_data[i] = c;
1498 c = gr_find_closest_color( 63, 0, 0 );
1499 // Make a big red X !
1500 for (i=0; i<64; i++ ) {
1501 bogus_data[i*64+i] = c;
1502 bogus_data[i*64+(63-i)] = c;
1504 piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
1505 bogus_sound.length = 64*64;
1506 bogus_sound.data = bogus_data;
1507 GameBitmapOffset[0] = 0;
1510 if ( FindArg( "-bigpig" ))
1513 if ( FindArg( "-lowmem" ))
1514 piggy_low_memory = 1;
1516 if ( FindArg( "-nolowmem" ))
1517 piggy_low_memory = 0;
1519 if (piggy_low_memory)
1522 WIN(DDGRLOCK(dd_grd_curcanv));
1523 gr_set_curfont( SMALL_FONT );
1524 gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
1525 gr_printf( 0x8000, grd_curcanv->cv_h-20, "%s...", TXT_LOADING_DATA );
1526 WIN(DDGRUNLOCK(dd_grd_curcanv));
1528 #if 1 //def EDITOR //need for d1 mission briefings
1529 piggy_init_pigfile(DEFAULT_PIGFILE);
1532 snd_ok = ham_ok = read_hamfile();
1534 if (Piggy_hamfile_version >= 3)
1535 snd_ok = read_sndfile();
1537 atexit(piggy_close);
1539 mprintf ((0,"HamOk=%d SndOk=%d\n",ham_ok,snd_ok));
1540 return (ham_ok && snd_ok); //read ok
1543 int piggy_is_needed(int soundnum)
1547 if ( !digi_lomem ) return 1;
1549 for (i=0; i<MAX_SOUNDS; i++ ) {
1550 if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
1557 void piggy_read_sounds(void)
1570 fp = cfopen( DEFAULT_SNDFILE, "rb" );
1572 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1573 fp = cfopen( name, "rb");
1579 for (i=0; i<Num_sound_files; i++ ) {
1580 digi_sound *snd = &GameSounds[i];
1582 if ( SoundOffset[i] > 0 ) {
1583 if ( piggy_is_needed(i) ) {
1584 cfseek( fp, SoundOffset[i], SEEK_SET );
1586 // Read in the sound data!!!
1589 sbytes += snd->length;
1590 cfread( snd->data, snd->length, 1, fp );
1593 snd->data = (ubyte *) -1;
1599 mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
1604 extern int descent_critical_error;
1605 extern unsigned descent_critical_deverror;
1606 extern unsigned descent_critical_errcode;
1608 char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
1609 "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
1610 "Read fault", "General Failure" };
1612 void piggy_critical_error()
1614 grs_canvas * save_canv;
1615 grs_font * save_font;
1617 save_canv = grd_curcanv;
1618 save_font = grd_curcanv->cv_font;
1619 gr_palette_load( gr_palette );
1620 i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A' );
1623 gr_set_current_canvas(save_canv);
1624 grd_curcanv->cv_font = save_font;
1627 void piggy_bitmap_page_in( bitmap_index bitmap )
1636 Assert( i < MAX_BITMAP_FILES );
1637 Assert( i < Num_bitmap_files );
1638 Assert( Piggy_bitmap_cache_size > 0 );
1640 if ( i < 1 ) return;
1641 if ( i >= MAX_BITMAP_FILES ) return;
1642 if ( i >= Num_bitmap_files ) return;
1644 if ( GameBitmapOffset[i] == 0 ) return; // A read-from-disk bitmap!!!
1646 if ( piggy_low_memory ) {
1648 i = GameBitmapXlat[i]; // Xlat for low-memory settings!
1651 bmp = &GameBitmaps[i];
1653 if ( bmp->bm_flags & BM_FLAG_PAGED_OUT ) {
1657 descent_critical_error = 0;
1658 cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
1659 if ( descent_critical_error ) {
1660 piggy_critical_error();
1664 bmp->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1665 bmp->bm_flags = GameBitmapFlags[i];
1667 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1669 descent_critical_error = 0;
1670 zsize = cfile_read_int(Piggy_fp);
1671 if ( descent_critical_error ) {
1672 piggy_critical_error();
1676 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1677 //Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );
1678 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1680 piggy_bitmap_page_out_all();
1683 descent_critical_error = 0;
1684 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next+4], 1, zsize-4, Piggy_fp );
1685 if ( descent_critical_error ) {
1686 piggy_critical_error();
1691 switch (cfilelength(Piggy_fp)) {
1693 if (!FindArg("-macdata"))
1695 // otherwise, fall through...
1696 case MAC_ALIEN1_PIGSIZE:
1697 case MAC_ALIEN2_PIGSIZE:
1698 case MAC_FIRE_PIGSIZE:
1699 case MAC_GROUPA_PIGSIZE:
1700 case MAC_ICE_PIGSIZE:
1701 case MAC_WATER_PIGSIZE:
1702 rle_swap_0_255( bmp );
1703 memcpy(&zsize, bmp->bm_data, 4);
1708 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
1709 Piggy_bitmap_cache_next += zsize;
1710 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1712 piggy_bitmap_page_out_all();
1717 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1718 Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );
1719 if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) {
1720 piggy_bitmap_page_out_all();
1723 descent_critical_error = 0;
1724 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
1725 if ( descent_critical_error ) {
1726 piggy_critical_error();
1729 Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
1732 switch (cfilelength(Piggy_fp)) {
1734 if (!FindArg("-macdata"))
1736 // otherwise, fall through...
1737 case MAC_ALIEN1_PIGSIZE:
1738 case MAC_ALIEN2_PIGSIZE:
1739 case MAC_FIRE_PIGSIZE:
1740 case MAC_GROUPA_PIGSIZE:
1741 case MAC_ICE_PIGSIZE:
1742 case MAC_WATER_PIGSIZE:
1749 //@@if ( bmp->bm_selector ) {
1750 //@@#if !defined(WINDOWS) && !defined(MACINTOSH)
1751 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1752 //@@ Error( "Error modifying selector base in piggy.c\n" );
1759 if ( piggy_low_memory ) {
1761 GameBitmaps[org_i] = GameBitmaps[i];
1764 //@@Removed from John's code:
1766 //@@ if ( bmp->bm_selector ) {
1767 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1768 //@@ Error( "Error modifying selector base in piggy.c\n" );
1774 void piggy_bitmap_page_out_all()
1778 Piggy_bitmap_cache_next = 0;
1780 piggy_page_flushed++;
1785 for (i=0; i<Num_bitmap_files; i++ ) {
1786 if ( GameBitmapOffset[i] > 0 ) { // Don't page out bitmaps read from disk!!!
1787 GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
1788 GameBitmaps[i].bm_data = Piggy_bitmap_cache_data;
1792 mprintf(( 0, "Flushing piggy bitmap cache\n" ));
1795 void piggy_load_level_data()
1797 piggy_bitmap_page_out_all();
1803 void change_filename_ext( char *dest, char *src, char *ext );
1805 void piggy_write_pigfile(char *filename)
1808 int bitmap_data_start,data_offset;
1809 DiskBitmapHeader bmh;
1811 char subst_name[32];
1814 char tname[FILENAME_LEN];
1816 // -- mprintf( (0, "Paging in all piggy bitmaps..." ));
1817 for (i=0; i < Num_bitmap_files; i++ ) {
1820 PIGGY_PAGE_IN( bi );
1822 // -- mprintf( (0, "\n" ));
1826 // -- mprintf( (0, "Creating %s...",filename ));
1828 pig_fp = fopen( filename, "wb" ); //open PIG file
1829 Assert( pig_fp!=NULL );
1831 write_int(PIGFILE_ID,pig_fp);
1832 write_int(PIGFILE_VERSION,pig_fp);
1835 fwrite( &Num_bitmap_files, sizeof(int), 1, pig_fp );
1838 bitmap_data_start = ftell(pig_fp);
1839 bitmap_data_start += (Num_bitmap_files-1)*DISKBITMAPHEADER_SIZE;
1840 data_offset = bitmap_data_start;
1842 change_filename_ext(tname,filename,"lst");
1843 fp1 = fopen( tname, "wt" );
1844 change_filename_ext(tname,filename,"all");
1845 fp2 = fopen( tname, "wt" );
1847 for (i=1; i < Num_bitmap_files; i++ ) {
1853 p = strchr(AllBitmaps[i].name,'#');
1860 fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
1861 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1863 bmh.dflags = DBM_FLAG_ABM + n;
1867 fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
1868 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1872 bmp = &GameBitmaps[i];
1874 Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
1877 fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
1878 org_offset = ftell(pig_fp);
1879 bmh.offset = data_offset - bitmap_data_start;
1880 fseek( pig_fp, data_offset, SEEK_SET );
1882 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1883 size = (int *)bmp->bm_data;
1884 fwrite( bmp->bm_data, sizeof(ubyte), *size, pig_fp );
1885 data_offset += *size;
1887 fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
1889 fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, pig_fp );
1890 data_offset += bmp->bm_rowsize * bmp->bm_h;
1892 fprintf( fp1, ".\n" );
1894 fseek( pig_fp, org_offset, SEEK_SET );
1895 Assert( GameBitmaps[i].bm_w < 4096 );
1896 bmh.width = (GameBitmaps[i].bm_w & 0xff);
1897 bmh.wh_extra = ((GameBitmaps[i].bm_w >> 8) & 0x0f);
1898 Assert( GameBitmaps[i].bm_h < 4096 );
1899 bmh.height = GameBitmaps[i].bm_h;
1900 bmh.wh_extra |= ((GameBitmaps[i].bm_h >> 4) & 0xf0);
1901 bmh.flags = GameBitmaps[i].bm_flags;
1902 if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name )) {
1903 bitmap_index other_bitmap;
1904 other_bitmap = piggy_find_bitmap( subst_name );
1905 GameBitmapXlat[i] = other_bitmap.index;
1906 bmh.flags |= BM_FLAG_PAGED_OUT;
1907 //mprintf(( 0, "Skipping bitmap %d\n", i ));
1908 //mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
1910 bmh.flags &= ~BM_FLAG_PAGED_OUT;
1912 bmh.avg_color=GameBitmaps[i].avg_color;
1913 fwrite( &bmh, DISKBITMAPHEADER_SIZE, 1, pig_fp ); // Mark as a bitmap
1918 mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
1919 fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
1926 static void write_int(int i,FILE *file)
1928 if (fwrite( &i, sizeof(i), 1, file) != 1)
1929 Error( "Error reading int in gamesave.c" );
1933 void piggy_dump_all()
1937 int org_offset,data_offset=0;
1938 DiskSoundHeader sndh;
1939 int sound_data_start=0;
1942 #ifdef NO_DUMP_SOUNDS
1943 Num_sound_files = 0;
1944 Num_sound_files_new = 0;
1947 if (!Must_write_hamfile && (Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
1950 fp1 = fopen( "ham.lst", "wt" );
1951 fp2 = fopen( "ham.all", "wt" );
1953 if (Must_write_hamfile || Num_bitmap_files_new) {
1955 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1957 ham_fp = fopen( DEFAULT_HAMFILE, "wb" ); //open HAM file
1958 Assert( ham_fp!=NULL );
1960 write_int(HAMFILE_ID,ham_fp);
1961 write_int(HAMFILE_VERSION,ham_fp);
1963 bm_write_all(ham_fp);
1964 xlat_offset = ftell(ham_fp);
1965 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1968 if (Num_bitmap_files_new)
1969 piggy_write_pigfile(DEFAULT_PIGFILE);
1971 //free up memeory used by new bitmaps
1972 for (i=Num_bitmap_files-Num_bitmap_files_new;i<Num_bitmap_files;i++)
1973 d_free(GameBitmaps[i].bm_data);
1975 //next thing must be done after pig written
1976 fseek( ham_fp, xlat_offset, SEEK_SET );
1977 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1980 mprintf( (0, "\n" ));
1983 if (Num_sound_files_new) {
1985 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1986 // Now dump sound file
1987 ham_fp = fopen( DEFAULT_SNDFILE, "wb" );
1988 Assert( ham_fp!=NULL );
1990 write_int(SNDFILE_ID,ham_fp);
1991 write_int(SNDFILE_VERSION,ham_fp);
1993 fwrite( &Num_sound_files, sizeof(int), 1, ham_fp );
1995 mprintf( (0, "\nDumping sounds..." ));
1997 sound_data_start = ftell(ham_fp);
1998 sound_data_start += Num_sound_files*sizeof(DiskSoundHeader);
1999 data_offset = sound_data_start;
2001 for (i=0; i < Num_sound_files; i++ ) {
2004 snd = &GameSounds[i];
2005 strcpy( sndh.name, AllSounds[i].name );
2006 sndh.length = GameSounds[i].length;
2007 sndh.offset = data_offset - sound_data_start;
2009 org_offset = ftell(ham_fp);
2010 fseek( ham_fp, data_offset, SEEK_SET );
2012 sndh.data_length = GameSounds[i].length;
2013 fwrite( snd->data, sizeof(ubyte), snd->length, ham_fp );
2014 data_offset += snd->length;
2015 fseek( ham_fp, org_offset, SEEK_SET );
2016 fwrite( &sndh, sizeof(DiskSoundHeader), 1, ham_fp ); // Mark as a bitmap
2018 fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
2019 fprintf( fp2, "%s.raw\n", AllSounds[i].name );
2023 mprintf( (0, "\n" ));
2026 fprintf( fp1, "Total sound size: %d bytes\n", data_offset-sound_data_start);
2027 mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
2028 fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
2033 // Never allow the game to run after building ham.
2047 d_free( SoundBits );
2049 hashtable_free( &AllBitmapsNames );
2050 hashtable_free( &AllDigiSndNames );
2054 int piggy_does_bitmap_exist_slow( char * name )
2058 for (i=0; i<Num_bitmap_files; i++ ) {
2059 if ( !strcmp( AllBitmaps[i].name, name) )
2066 #define NUM_GAUGE_BITMAPS 23
2067 char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = {
2068 "gauge01", "gauge01b",
2069 "gauge02", "gauge02b",
2070 "gauge06", "gauge06b",
2071 "targ01", "targ01b",
2072 "targ02", "targ02b",
2073 "targ03", "targ03b",
2074 "targ04", "targ04b",
2075 "targ05", "targ05b",
2076 "targ06", "targ06b",
2077 "gauge18", "gauge18b",
2083 int piggy_is_gauge_bitmap( char * base_name )
2086 for (i=0; i<NUM_GAUGE_BITMAPS; i++ ) {
2087 if ( !stricmp( base_name, gauge_bitmap_names[i] ))
2094 int piggy_is_substitutable_bitmap( char * name, char * subst_name )
2098 char base_name[ 16 ];
2100 strcpy( subst_name, name );
2101 p = strchr( subst_name, '#' );
2103 frame = atoi( &p[1] );
2105 strcpy( base_name, subst_name );
2106 if ( !piggy_is_gauge_bitmap( base_name )) {
2107 sprintf( subst_name, "%s#%d", base_name, frame+1 );
2108 if ( piggy_does_bitmap_exist_slow( subst_name ) ) {
2110 sprintf( subst_name, "%s#%d", base_name, frame-1 );
2116 strcpy( subst_name, name );
2123 // New Windows stuff
2125 // windows bitmap page in
2126 // Page in a bitmap, if ddraw, then page it into a ddsurface in
2127 // 'video' memory. if that fails, page it in normally.
2129 void piggy_bitmap_page_in_w( bitmap_index bitmap, int ddraw )
2134 // Essential when switching video modes!
2136 void piggy_bitmap_page_out_all_w()
2144 * Functions for loading replacement textures
2145 * 1) From .pog files
2146 * 2) From descent.pig (for loading d1 levels)
2149 extern void change_filename_extension( char *dest, char *src, char *new_ext );
2150 extern char last_palette_loaded_pig[];
2152 ubyte *Bitmap_replacement_data=NULL;
2154 void free_bitmap_replacements()
2156 if (Bitmap_replacement_data) {
2157 d_free(Bitmap_replacement_data);
2158 Bitmap_replacement_data = NULL;
2162 void load_bitmap_replacements(char *level_name)
2164 char ifile_name[FILENAME_LEN];
2168 //first, free up data allocated for old bitmaps
2169 free_bitmap_replacements();
2171 change_filename_extension(ifile_name, level_name, ".POG" );
2173 ifile = cfopen(ifile_name,"rb");
2176 int id,version,n_bitmaps;
2177 int bitmap_data_size;
2180 id = cfile_read_int(ifile);
2181 version = cfile_read_int(ifile);
2183 if (id != MAKE_SIG('G','O','P','D') || version != 1) {
2188 n_bitmaps = cfile_read_int(ifile);
2190 MALLOC( indices, ushort, n_bitmaps );
2192 for (i = 0; i < n_bitmaps; i++)
2193 indices[i] = cfile_read_short(ifile);
2195 bitmap_data_size = cfilelength(ifile) - cftell(ifile) - DISKBITMAPHEADER_SIZE * n_bitmaps;
2196 MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
2198 for (i=0;i<n_bitmaps;i++) {
2199 DiskBitmapHeader bmh;
2200 grs_bitmap temp_bitmap;
2202 DiskBitmapHeader_read(&bmh, ifile);
2204 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2206 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2207 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2208 temp_bitmap.avg_color = bmh.avg_color;
2209 temp_bitmap.bm_data = Bitmap_replacement_data + bmh.offset;
2211 temp_bitmap.bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2213 GameBitmaps[indices[i]] = temp_bitmap;
2216 cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
2222 last_palette_loaded_pig[0]= 0; //force pig re-load
2224 texmerge_flush(); //for re-merging with new textures
2227 atexit(free_bitmap_replacements);
2230 #define FIRST_D1_TEXTURE 722
2231 #define LAST_D1_STATIC_TEXTURE 1042//1342 //afterwards, we have door frames and stuff
2232 #define FIRST_D2_TEXTURE 1243
2234 void load_d1_bitmap_replacements()
2236 CFILE * d1_Piggy_fp;
2237 grs_bitmap temp_bitmap;
2238 DiskBitmapHeader bmh;
2239 int pig_data_start, bitmap_header_start, bitmap_data_start;
2240 int N_bitmaps, zsize;
2241 int d1_index, d2_index;
2242 ubyte colormap[256];
2243 ubyte *next_bitmap; // to which address we write the next bitmap
2245 d1_Piggy_fp = cfopen( D1_PIGFILE, "rb" );
2248 return; // use d2 bitmaps instead...
2250 //first, free up data allocated for old bitmaps
2251 free_bitmap_replacements();
2253 // read d1 palette, build colormap
2256 ubyte d1_palette[256*3];
2257 CFILE * palette_file = cfopen(D1_PALETTE, "rb" );
2258 Assert( palette_file );
2259 Assert( cfilelength( palette_file ) == 9472 );
2260 cfread( d1_palette, 256, 3, palette_file);
2261 cfclose( palette_file );
2262 build_colormap_good( d1_palette, colormap, freq );
2263 // don't change transparencies:
2264 colormap[254] = 254;
2265 colormap[255] = 255;
2268 switch (cfilelength(d1_Piggy_fp)) {
2269 case D1_SHAREWARE_10_PIGSIZE:
2270 case D1_SHAREWARE_PIGSIZE:
2276 case D1_OEM_PIGSIZE:
2277 case D1_MAC_PIGSIZE:
2278 case D1_MAC_SHARE_PIGSIZE:
2280 pig_data_start = cfile_read_int(d1_Piggy_fp );
2281 bm_read_all_d1( d1_Piggy_fp );
2282 //for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2286 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2287 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2289 int N_sounds = cfile_read_int(d1_Piggy_fp);
2290 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2291 + N_sounds * DISKSOUNDHEADER_SIZE;
2292 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2293 bitmap_data_start = bitmap_header_start + header_size;
2296 MALLOC( Bitmap_replacement_data, ubyte, cfilelength(d1_Piggy_fp) - bitmap_data_start ); // too much
2297 //TODO: handle case where b_r_d == 0! (have to convert textures, return, not bm_read_all_d1)
2299 next_bitmap = Bitmap_replacement_data;
2301 for (d1_index=1; d1_index<=N_bitmaps; d1_index++ ) {
2302 // only change wall texture bitmaps
2303 if (d1_index >= FIRST_D1_TEXTURE && d1_index <= LAST_D1_STATIC_TEXTURE) {
2304 d2_index = d1_index + FIRST_D2_TEXTURE - FIRST_D1_TEXTURE;
2306 cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2307 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2309 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2311 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2312 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2313 temp_bitmap.avg_color = bmh.avg_color;
2315 //GameBitmapFlags[convert_d1_bitmap_num(d1_index)] = 0;
2317 temp_bitmap.bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2319 temp_bitmap.bm_data = next_bitmap;
2321 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2322 zsize = cfile_read_int(d1_Piggy_fp);
2323 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2324 cfread(next_bitmap, 1, zsize, d1_Piggy_fp);
2326 switch(cfilelength(d1_Piggy_fp)) {
2327 case D1_MAC_PIGSIZE:
2328 case D1_MAC_SHARE_PIGSIZE:
2329 rle_swap_0_255(&temp_bitmap);
2331 rle_remap(&temp_bitmap, colormap);
2333 GameBitmaps[d2_index] = temp_bitmap;
2335 memcpy(&zsize, temp_bitmap.bm_data, 4);
2336 next_bitmap += zsize;
2340 cfclose(d1_Piggy_fp);
2342 last_palette_loaded_pig[0]= 0; //force pig re-load
2344 texmerge_flush(); //for re-merging with new textures
2346 atexit(free_bitmap_replacements);
2350 extern int extra_bitmap_num;
2353 * Find and load the named bitmap from descent.pig
2354 * similar to read_extra_bitmap_iff
2356 bitmap_index read_extra_bitmap_d1_pig(char *name)
2358 bitmap_index bitmap_num;
2359 grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2361 bitmap_num.index = 0;
2366 DiskBitmapHeader bmh;
2367 int pig_data_start, bitmap_header_start, bitmap_data_start;
2368 int N_bitmaps, zsize;
2369 ubyte colormap[256];
2371 d1_Piggy_fp = cfopen(D1_PIGFILE, "rb");
2374 con_printf(CON_DEBUG, "could not open %s\n", D1_PIGFILE);
2378 // read d1 palette, build colormap
2381 ubyte d1_palette[256*3];
2382 CFILE * palette_file = cfopen(D1_PALETTE, "rb");
2383 if (!palette_file || cfilelength(palette_file) != 9472)
2385 con_printf(CON_DEBUG, "could not open %s\n", D1_PALETTE);
2388 cfread( d1_palette, 256, 3, palette_file);
2389 cfclose( palette_file );
2390 build_colormap_good( d1_palette, colormap, freq );
2391 // don't change transparencies:
2392 colormap[254] = 254;
2393 colormap[255] = 255;
2396 switch (cfilelength(d1_Piggy_fp)) {
2397 case D1_SHAREWARE_10_PIGSIZE:
2398 case D1_SHAREWARE_PIGSIZE:
2404 case D1_OEM_PIGSIZE:
2405 case D1_MAC_PIGSIZE:
2406 case D1_MAC_SHARE_PIGSIZE:
2407 pig_data_start = cfile_read_int(d1_Piggy_fp);
2411 cfseek(d1_Piggy_fp, pig_data_start, SEEK_SET);
2412 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2414 int N_sounds = cfile_read_int(d1_Piggy_fp);
2415 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2416 + N_sounds * DISKSOUNDHEADER_SIZE;
2417 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2418 bitmap_data_start = bitmap_header_start + header_size;
2421 for (i = 0; i < N_bitmaps; i++)
2423 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2424 if (!strnicmp(bmh.name, name, 8))
2428 if (strnicmp(bmh.name, name, 8))
2430 con_printf(CON_DEBUG, "could not find bitmap %s\n", name);
2434 memset( new, 0, sizeof(grs_bitmap) );
2436 new->bm_w = new->bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2437 new->bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2438 new->avg_color = bmh.avg_color;
2440 new->bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2442 if ( bmh.flags & BM_FLAG_RLE )
2444 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2445 zsize = cfile_read_int(d1_Piggy_fp);
2448 zsize = new->bm_w * new->bm_h;
2449 new->bm_data = d_malloc(zsize);
2450 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2451 cfread(new->bm_data, 1, zsize, d1_Piggy_fp);
2453 switch(cfilelength(d1_Piggy_fp)) {
2454 case D1_MAC_PIGSIZE:
2455 case D1_MAC_SHARE_PIGSIZE:
2456 rle_swap_0_255(new);
2458 rle_remap(new, colormap);
2460 cfclose(d1_Piggy_fp);
2463 new->avg_color = 0; //compute_average_pixel(new);
2465 bitmap_num.index = extra_bitmap_num;
2467 GameBitmaps[extra_bitmap_num++] = *new;
2473 #ifndef FAST_FILE_IO
2475 * reads a bitmap_index structure from a CFILE
2477 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2479 bi->index = cfile_read_short(fp);
2483 * reads n bitmap_index structs from a CFILE
2485 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2489 for (i = 0; i < n; i++)
2490 bi[i].index = cfile_read_short(fp);
2495 * reads a DiskBitmapHeader structure from a CFILE
2497 void DiskBitmapHeader_read(DiskBitmapHeader *dbh, CFILE *fp)
2499 cfread(dbh->name, 8, 1, fp);
2500 dbh->dflags = cfile_read_byte(fp);
2501 dbh->width = cfile_read_byte(fp);
2502 dbh->height = cfile_read_byte(fp);
2503 dbh->wh_extra = cfile_read_byte(fp);
2504 dbh->flags = cfile_read_byte(fp);
2505 dbh->avg_color = cfile_read_byte(fp);
2506 dbh->offset = cfile_read_int(fp);
2510 * reads a DiskSoundHeader structure from a CFILE
2512 void DiskSoundHeader_read(DiskSoundHeader *dsh, CFILE *fp)
2514 cfread(dsh->name, 8, 1, fp);
2515 dsh->length = cfile_read_int(fp);
2516 dsh->data_length = cfile_read_int(fp);
2517 dsh->offset = cfile_read_int(fp);
2519 #endif // FAST_FILE_IO
2522 * reads a descent 1 DiskBitmapHeader structure from a CFILE
2524 void DiskBitmapHeader_d1_read(DiskBitmapHeader *dbh, CFILE *fp)
2526 cfread(dbh->name, 8, 1, fp);
2527 dbh->dflags = cfile_read_byte(fp);
2528 dbh->width = cfile_read_byte(fp);
2529 dbh->height = cfile_read_byte(fp);
2531 dbh->flags = cfile_read_byte(fp);
2532 dbh->avg_color = cfile_read_byte(fp);
2533 dbh->offset = cfile_read_int(fp);