1 /* $Id: piggy.c,v 1.30 2003-03-27 01:26:47 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.30 2003-03-27 01:26:47 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
516 extern short cd_VRefNum;
517 extern void ConcatPStr(StringPtr dst, StringPtr src);
518 extern int ConvertPToCStr(StringPtr inPStr, char* outCStrBuf);
519 extern int ConvertCToPStr(char* inCStr, StringPtr outPStrBuf);
522 int piggy_is_substitutable_bitmap( char * name, char * subst_name );
525 void piggy_write_pigfile(char *filename);
526 static void write_int(int i,FILE *file);
529 void swap_0_255(grs_bitmap *bmp)
533 for (i = 0; i < bmp->bm_h * bmp->bm_w; i++) {
534 if(bmp->bm_data[i] == 0)
535 bmp->bm_data[i] = 255;
536 else if (bmp->bm_data[i] == 255)
541 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
544 Assert( Num_bitmap_files < MAX_BITMAP_FILES );
546 temp.index = Num_bitmap_files;
550 if ( FindArg("-macdata") )
553 if ( !BigPig ) gr_bitmap_rle_compress( bmp );
554 Num_bitmap_files_new++;
557 strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
558 hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
559 GameBitmaps[Num_bitmap_files] = *bmp;
561 GameBitmapOffset[Num_bitmap_files] = 0;
562 GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
569 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
573 Assert( Num_sound_files < MAX_SOUND_FILES );
575 strncpy( AllSounds[Num_sound_files].name, name, 12 );
576 hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
577 GameSounds[Num_sound_files] = *snd;
579 SoundOffset[Num_sound_files] = 0;
585 Num_sound_files_new++;
591 bitmap_index piggy_find_bitmap( char * name )
599 if ((t=strchr(name,'#'))!=NULL)
602 for (i=0;i<Num_aliases;i++)
603 if (stricmp(name,alias_list[i].alias_name)==0) {
604 if (t) { //extra stuff for ABMs
605 static char temp[FILENAME_LEN];
606 _splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
612 name=alias_list[i].file_name;
619 i = hashtable_search( &AllBitmapsNames, name );
628 int piggy_find_sound( char * name )
632 i = hashtable_search( &AllDigiSndNames, name );
640 CFILE * Piggy_fp = NULL;
642 #define FILENAME_LEN 13
644 char Current_pigfile[FILENAME_LEN] = "";
646 void piggy_close_file()
651 Current_pigfile[0] = 0;
655 int Pigfile_initialized=0;
657 #define PIGFILE_ID MAKE_SIG('G','I','P','P') //PPIG
658 #define PIGFILE_VERSION 2
660 extern char CDROM_dir[];
662 int request_cd(void);
667 //copies a pigfile from the CD to the current dir
668 //retuns file handle of new pig
669 CFILE *copy_pigfile_from_cd(char *filename) // MACINTOSH VERSION
672 char sourcePathAndFileCStr[255] = "";
673 char destPathAndFileCStr[255] = "";
675 FILE* sourceFile = NULL;
676 FILE* destFile = NULL;
677 const int BUF_SIZE = 4096;
681 Str255 sourcePathAndFilePStr = "\p";
682 Str255 destPathAndFilePStr = "\p";
683 Str255 pigfileNamePStr = "\p";
684 HParamBlockRec theSourcePigHFSParams;
685 HParamBlockRec theDestPigHFSParams;
686 OSErr theErr = noErr;
687 char oldDirCStr[255] = "";
689 getcwd(oldDirCStr, 255);
691 show_boxed_message("Copying bitmap data from CD...");
692 gr_palette_load(gr_palette); //I don't think this line is really needed
695 //First, delete all PIG files currently in the directory
696 if( !FileFindFirst( "*.pig", &find ) )
701 } while( !FileFindNext( &find ) );
707 //Now, copy over new pig
708 songs_stop_redbook(); //so we can read off the cd
710 // make the source path "<cd volume>:Data:filename.pig"
711 //MWA ConvertCToPStr(filename, pigfileNamePStr);
713 //MWA ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:"); // volume ID is cd_VRefNum
714 //MWA ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
717 strcpy(sourcePathAndFileCStr, "Descent II:Data:");
718 strcat(sourcePathAndFileCStr, filename);
720 // make the destination path "<default directory>:Data:filename.pig"
721 //MWA ConcatPStr(destPathAndFilePStr, "\p:Data:");
722 //MWA ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
723 //MWA ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
724 //MWA ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
726 strcpy(destPathAndFileCStr, ":Data:");
727 strcat(destPathAndFileCStr, filename);
729 strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
730 strcpy(destPathAndFilePStr, destPathAndFileCStr);
731 c2pstr(sourcePathAndFilePStr);
732 c2pstr(destPathAndFilePStr);
735 // Open the source file
736 sourceFile = fopen(sourcePathAndFileCStr,"rb");
740 if (request_cd() == -1)
741 Error("Cannot load file <%s> from CD",filename);
744 } while (!sourceFile);
747 // Get the time stamp from the source file
748 theSourcePigHFSParams.fileParam.ioCompletion = nil;
749 theSourcePigHFSParams.fileParam.ioNamePtr = sourcePathAndFilePStr;
750 theSourcePigHFSParams.fileParam.ioVRefNum = cd_VRefNum;
751 theSourcePigHFSParams.fileParam.ioFDirIndex = 0;
752 theSourcePigHFSParams.fileParam.ioDirID = 0;
754 theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
757 // Error getting file time stamp!! Why? JTS
758 Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
761 // Copy the file over
764 // Open the destination file
765 destFile = fopen(destPathAndFileCStr,"wb");
768 Error("Cannot create file: <%s>\n", destPathAndFileCStr);
771 // Copy bytes until the end of the source file
772 while (!feof(sourceFile))
777 bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
778 if (ferror(sourceFile))
779 Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
781 // Assert is bogus Assert(bytes_read == BUF_SIZE || feof(sourceFile));
783 fwrite(buf,1,bytes_read,destFile);
784 if (ferror(destFile))
785 Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
788 // close the source/dest files
789 if (fclose(sourceFile))
790 Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
791 if (fclose(destFile))
792 Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
794 // Get the current hfs data for the new file
795 theDestPigHFSParams.fileParam.ioCompletion = nil;
796 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
797 theDestPigHFSParams.fileParam.ioVRefNum = 0;
798 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
799 theDestPigHFSParams.fileParam.ioDirID = 0;
800 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
801 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
803 // Error getting file time stamp!! Why? JTS
804 Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
807 // Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
808 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
809 theDestPigHFSParams.fileParam.ioVRefNum = 0;
810 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
811 theDestPigHFSParams.fileParam.ioDirID = 0;
813 // Copy the time stamp from the source file info
814 theDestPigHFSParams.fileParam.ioFlCrDat = theSourcePigHFSParams.fileParam.ioFlCrDat;
815 theDestPigHFSParams.fileParam.ioFlMdDat = theSourcePigHFSParams.fileParam.ioFlMdDat;
816 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
817 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
819 // Set the dest file's time stamp to the source file's time stamp values
820 theErr = PBHSetFInfo(&theDestPigHFSParams, false);
822 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
824 Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
827 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
829 return cfopen(destPathAndFileCStr, "rb");
832 #else //PC Version of copy_pigfile_from_cd is below
834 //copies a pigfile from the CD to the current dir
835 //retuns file handle of new pig
836 CFILE *copy_pigfile_from_cd(char *filename)
842 return cfopen(filename, "rb");
843 show_boxed_message("Copying bitmap data from CD...");
844 gr_palette_load(gr_palette); //I don't think this line is really needed
846 //First, delete all PIG files currently in the directory
848 if( !FileFindFirst( "*.pig", &find ) ) {
851 } while( !FileFindNext( &find ) );
855 //Now, copy over new pig
857 songs_stop_redbook(); //so we can read off the cd
859 //new code to unarj file
860 strcpy(name,CDROM_dir);
861 strcat(name,"descent2.sow");
864 // ret = unarj_specific_file(name,filename,filename);
869 if (ret != EXIT_SUCCESS) {
871 //delete file, so we don't leave partial file
875 if (request_cd() == -1)
877 //NOTE LINK TO ABOVE IF
878 Error("Cannot load file <%s> from CD",filename);
881 } while (ret != EXIT_SUCCESS);
883 return cfopen(filename, "rb");
886 #endif // end of ifdef MAC around copy_pigfile_from_cd
888 //initialize a pigfile, reading headers
889 //returns the size of all the bitmap data
890 void piggy_init_pigfile(char *filename)
894 char temp_name_read[16];
895 grs_bitmap temp_bitmap;
896 DiskBitmapHeader bmh;
897 int header_size, N_bitmaps, data_size, data_start;
899 char name[255]; // filename + path for the mac
902 piggy_close_file(); //close old pig if still open
904 //rename pigfile for shareware
905 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
906 filename = DEFAULT_PIGFILE_SHAREWARE;
909 Piggy_fp = cfopen( filename, "rb" );
911 sprintf(name, ":Data:%s", filename);
912 Piggy_fp = cfopen( name, "rb" );
914 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
915 if (Piggy_fp == NULL)
917 Error("Cannot load required file <%s>",name);
919 #endif // end of if def shareware
925 return; //if editor, ok to not have pig, because we'll build one
927 Piggy_fp = copy_pigfile_from_cd(filename);
931 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
932 int pig_id,pig_version;
934 pig_id = cfile_read_int(Piggy_fp);
935 pig_version = cfile_read_int(Piggy_fp);
936 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
937 cfclose(Piggy_fp); //out of date pig
938 Piggy_fp = NULL; //..so pretend it's not here
945 return; //if editor, ok to not have pig, because we'll build one
947 Error("Cannot load required file <%s>",filename);
951 strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
953 N_bitmaps = cfile_read_int(Piggy_fp);
955 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
957 data_start = header_size + cftell(Piggy_fp);
959 data_size = cfilelength(Piggy_fp) - data_start;
961 Num_bitmap_files = 1;
963 for (i=0; i<N_bitmaps; i++ ) {
964 DiskBitmapHeader_read(&bmh, Piggy_fp);
965 memcpy( temp_name_read, bmh.name, 8 );
966 temp_name_read[8] = 0;
967 if ( bmh.dflags & DBM_FLAG_ABM )
968 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
970 strcpy( temp_name, temp_name_read );
971 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
972 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
973 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
974 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
975 temp_bitmap.avg_color = bmh.avg_color;
976 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
978 GameBitmapFlags[i+1] = 0;
979 if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_TRANSPARENT;
980 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_SUPER_TRANSPARENT;
981 if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i+1] |= BM_FLAG_NO_LIGHTING;
982 if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i+1] |= BM_FLAG_RLE;
983 if ( bmh.flags & BM_FLAG_RLE_BIG ) GameBitmapFlags[i+1] |= BM_FLAG_RLE_BIG;
985 GameBitmapOffset[i+1] = bmh.offset + data_start;
986 Assert( (i+1) == Num_bitmap_files );
987 piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
991 Piggy_bitmap_cache_size = data_size + (data_size/10); //extra mem for new bitmaps
992 Assert( Piggy_bitmap_cache_size > 0 );
994 Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
996 if (piggy_low_memory)
997 Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
1000 BitmapBits = d_malloc( Piggy_bitmap_cache_size );
1001 if ( BitmapBits == NULL )
1002 Error( "Not enough memory to load bitmaps\n" );
1003 Piggy_bitmap_cache_data = BitmapBits;
1004 Piggy_bitmap_cache_next = 0;
1006 #if defined(MACINTOSH) && defined(SHAREWARE)
1007 // load_exit_models();
1010 Pigfile_initialized=1;
1013 #define FILENAME_LEN 13
1014 #define MAX_BITMAPS_PER_BRUSH 30
1016 extern int compute_average_pixel(grs_bitmap *new);
1018 //reads in a new pigfile (for new palette)
1019 //returns the size of all the bitmap data
1020 void piggy_new_pigfile(char *pigname)
1024 char temp_name_read[16];
1025 grs_bitmap temp_bitmap;
1026 DiskBitmapHeader bmh;
1027 int header_size, N_bitmaps, data_size, data_start;
1028 int must_rewrite_pig = 0;
1035 //rename pigfile for shareware
1036 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
1037 pigname = DEFAULT_PIGFILE_SHAREWARE;
1039 if (strnicmp(Current_pigfile,pigname,sizeof(Current_pigfile))==0)
1040 return; //already have correct pig
1042 if (!Pigfile_initialized) { //have we ever opened a pigfile?
1043 piggy_init_pigfile(pigname); //..no, so do initialization stuff
1047 piggy_close_file(); //close old pig if still open
1049 Piggy_bitmap_cache_next = 0; //free up cache
1051 strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
1054 Piggy_fp = cfopen( pigname, "rb" );
1056 sprintf(name, ":Data:%s", pigname);
1057 Piggy_fp = cfopen( name, "rb" );
1059 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
1060 if (Piggy_fp == NULL)
1062 Error("Cannot load required file <%s>",name);
1064 #endif // end of if def shareware
1069 Piggy_fp = copy_pigfile_from_cd(pigname);
1072 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1073 int pig_id,pig_version;
1075 pig_id = cfile_read_int(Piggy_fp);
1076 pig_version = cfile_read_int(Piggy_fp);
1077 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1078 cfclose(Piggy_fp); //out of date pig
1079 Piggy_fp = NULL; //..so pretend it's not here
1084 if (!Piggy_fp) Error ("Piggy_fp not defined in piggy_new_pigfile.");
1089 N_bitmaps = cfile_read_int(Piggy_fp);
1091 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
1093 data_start = header_size + cftell(Piggy_fp);
1095 data_size = cfilelength(Piggy_fp) - data_start;
1097 for (i=1; i<=N_bitmaps; i++ ) {
1098 DiskBitmapHeader_read(&bmh, Piggy_fp);
1099 memcpy( temp_name_read, bmh.name, 8 );
1100 temp_name_read[8] = 0;
1102 if ( bmh.dflags & DBM_FLAG_ABM )
1103 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
1105 strcpy( temp_name, temp_name_read );
1107 //Make sure name matches
1108 if (strcmp(temp_name,AllBitmaps[i].name)) {
1109 //Int3(); //this pig is out of date. Delete it
1113 strcpy(AllBitmaps[i].name,temp_name);
1115 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1117 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1118 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1119 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1120 temp_bitmap.avg_color = bmh.avg_color;
1121 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1123 GameBitmapFlags[i] = 0;
1125 if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i] |= BM_FLAG_TRANSPARENT;
1126 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i] |= BM_FLAG_SUPER_TRANSPARENT;
1127 if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i] |= BM_FLAG_NO_LIGHTING;
1128 if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i] |= BM_FLAG_RLE;
1129 if ( bmh.flags & BM_FLAG_RLE_BIG ) GameBitmapFlags[i] |= BM_FLAG_RLE_BIG;
1131 GameBitmapOffset[i] = bmh.offset + data_start;
1133 GameBitmaps[i] = temp_bitmap;
1137 N_bitmaps = 0; //no pigfile, so no bitmaps
1141 Assert(N_bitmaps == Num_bitmap_files-1);
1145 if (must_rewrite_pig || (N_bitmaps < Num_bitmap_files-1)) {
1148 //re-read the bitmaps that aren't in this pig
1150 for (i=N_bitmaps+1;i<Num_bitmap_files;i++) {
1153 p = strchr(AllBitmaps[i].name,'#');
1155 if (p) { //this is an ABM
1156 char abmname[FILENAME_LEN];
1158 grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
1159 int iff_error; //reference parm to avoid warning message
1161 char basename[FILENAME_LEN];
1164 strcpy(basename,AllBitmaps[i].name);
1165 basename[p-AllBitmaps[i].name] = 0; //cut off "#nn" part
1167 sprintf( abmname, "%s.abm", basename );
1169 iff_error = iff_read_animbrush(abmname,bm,MAX_BITMAPS_PER_BRUSH,&nframes,newpal);
1171 if (iff_error != IFF_NO_ERROR) {
1172 mprintf((1,"File %s - IFF error: %s",abmname,iff_errormsg(iff_error)));
1173 Error("File %s - IFF error: %s",abmname,iff_errormsg(iff_error));
1176 for (fnum=0;fnum<nframes; fnum++) {
1180 sprintf( tempname, "%s#%d", basename, fnum );
1182 //SuperX = (GameBitmaps[i+fnum].bm_flags&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1183 SuperX = (GameBitmapFlags[i+fnum]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1184 //above makes assumption that supertransparent color is 254
1186 if ( iff_has_transparency )
1187 gr_remap_bitmap_good( bm[fnum], newpal, iff_transparent_color, SuperX );
1189 gr_remap_bitmap_good( bm[fnum], newpal, -1, SuperX );
1191 bm[fnum]->avg_color = compute_average_pixel(bm[fnum]);
1194 if ( FindArg("-macdata") )
1195 swap_0_255( bm[fnum] );
1197 if ( !BigPig ) gr_bitmap_rle_compress( bm[fnum] );
1199 if (bm[fnum]->bm_flags & BM_FLAG_RLE)
1200 size = *((int *) bm[fnum]->bm_data);
1202 size = bm[fnum]->bm_w * bm[fnum]->bm_h;
1204 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],bm[fnum]->bm_data,size);
1205 d_free(bm[fnum]->bm_data);
1206 bm[fnum]->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1207 Piggy_bitmap_cache_next += size;
1209 GameBitmaps[i+fnum] = *bm[fnum];
1211 // -- mprintf( (0, "U" ));
1215 i += nframes-1; //filled in multiple bitmaps
1217 else { //this is a BBM
1220 ubyte newpal[256*3];
1222 char bbmname[FILENAME_LEN];
1225 MALLOC( new, grs_bitmap, 1 );
1227 sprintf( bbmname, "%s.bbm", AllBitmaps[i].name );
1228 iff_error = iff_read_bitmap(bbmname,new,BM_LINEAR,newpal);
1231 if (iff_error != IFF_NO_ERROR) {
1232 mprintf((1, "File %s - IFF error: %s",bbmname,iff_errormsg(iff_error)));
1233 Error("File %s - IFF error: %s",bbmname,iff_errormsg(iff_error));
1236 SuperX = (GameBitmapFlags[i]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1237 //above makes assumption that supertransparent color is 254
1239 if ( iff_has_transparency )
1240 gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
1242 gr_remap_bitmap_good( new, newpal, -1, SuperX );
1244 new->avg_color = compute_average_pixel(new);
1247 if ( FindArg("-macdata") )
1250 if ( !BigPig ) gr_bitmap_rle_compress( new );
1252 if (new->bm_flags & BM_FLAG_RLE)
1253 size = *((int *) new->bm_data);
1255 size = new->bm_w * new->bm_h;
1257 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],new->bm_data,size);
1258 d_free(new->bm_data);
1259 new->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1260 Piggy_bitmap_cache_next += size;
1262 GameBitmaps[i] = *new;
1266 // -- mprintf( (0, "U" ));
1270 //@@Dont' do these things which are done when writing
1271 //@@for (i=0; i < Num_bitmap_files; i++ ) {
1272 //@@ bitmap_index bi;
1274 //@@ PIGGY_PAGE_IN( bi );
1277 //@@piggy_close_file();
1279 piggy_write_pigfile(pigname);
1281 Current_pigfile[0] = 0; //say no pig, to force reload
1283 piggy_new_pigfile(pigname); //read in just-generated pig
1287 #endif //ifdef EDITOR
1291 ubyte bogus_data[64*64];
1292 grs_bitmap bogus_bitmap;
1293 ubyte bogus_bitmap_initialized=0;
1294 digi_sound bogus_sound;
1296 #define HAMFILE_ID MAKE_SIG('!','M','A','H') //HAM!
1297 #define HAMFILE_VERSION 3
1298 //version 1 -> 2: save marker_model_num
1299 //version 2 -> 3: removed sound files
1301 #define SNDFILE_ID MAKE_SIG('D','N','S','D') //DSND
1302 #define SNDFILE_VERSION 1
1306 CFILE * ham_fp = NULL;
1308 int sound_offset = 0;
1314 ham_fp = cfopen( DEFAULT_HAMFILE, "rb" );
1316 sprintf(name, ":Data:%s", DEFAULT_HAMFILE );
1317 ham_fp = cfopen( name, "rb" );
1320 if (ham_fp == NULL) {
1321 Must_write_hamfile = 1;
1325 //make sure ham is valid type file & is up-to-date
1326 ham_id = cfile_read_int(ham_fp);
1327 Piggy_hamfile_version = cfile_read_int(ham_fp);
1328 if (ham_id != HAMFILE_ID)
1329 Error("Cannot open ham file %s\n", DEFAULT_HAMFILE);
1331 if (ham_id != HAMFILE_ID || Piggy_hamfile_version != HAMFILE_VERSION) {
1332 Must_write_hamfile = 1;
1333 cfclose(ham_fp); //out of date ham
1338 if (Piggy_hamfile_version < 3) // hamfile contains sound info
1339 sound_offset = cfile_read_int(ham_fp);
1345 bm_read_all(ham_fp);
1346 cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1348 //for (i = 0; i < MAX_BITMAP_FILES; i++) {
1349 //GameBitmapXlat[i] = INTEL_SHORT(GameBitmapXlat[i]);
1350 //printf("GameBitmapXlat[%d] = %d\n", i, GameBitmapXlat[i]);
1355 if (Piggy_hamfile_version < 3) {
1360 DiskSoundHeader sndh;
1361 digi_sound temp_sound;
1362 char temp_name_read[16];
1365 cfseek(ham_fp, sound_offset, SEEK_SET);
1366 N_sounds = cfile_read_int(ham_fp);
1368 sound_start = cftell(ham_fp);
1370 header_size = N_sounds * DISKSOUNDHEADER_SIZE;
1374 for (i=0; i<N_sounds; i++ ) {
1375 DiskSoundHeader_read(&sndh, ham_fp);
1376 temp_sound.length = sndh.length;
1377 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1378 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1379 memcpy( temp_name_read, sndh.name, 8 );
1380 temp_name_read[8] = 0;
1381 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1383 if (piggy_is_needed(i))
1384 #endif // note link to if.
1385 sbytes += sndh.length;
1386 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1389 SoundBits = d_malloc( sbytes + 16 );
1390 if ( SoundBits == NULL )
1391 Error( "Not enough memory to load sounds\n" );
1393 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1395 // piggy_read_sounds(ham_fp);
1407 CFILE * snd_fp = NULL;
1408 int snd_id,snd_version;
1413 DiskSoundHeader sndh;
1414 digi_sound temp_sound;
1415 char temp_name_read[16];
1422 snd_fp = cfopen( DEFAULT_SNDFILE, "rb" );
1424 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1425 snd_fp = cfopen( name, "rb");
1431 //make sure soundfile is valid type file & is up-to-date
1432 snd_id = cfile_read_int(snd_fp);
1433 snd_version = cfile_read_int(snd_fp);
1434 if (snd_id != SNDFILE_ID || snd_version != SNDFILE_VERSION) {
1435 cfclose(snd_fp); //out of date sound file
1439 N_sounds = cfile_read_int(snd_fp);
1441 sound_start = cftell(snd_fp);
1442 size = cfilelength(snd_fp) - sound_start;
1444 mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
1446 header_size = N_sounds*sizeof(DiskSoundHeader);
1450 for (i=0; i<N_sounds; i++ ) {
1451 DiskSoundHeader_read(&sndh, snd_fp);
1452 //size -= sizeof(DiskSoundHeader);
1453 temp_sound.length = sndh.length;
1454 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1455 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1456 memcpy( temp_name_read, sndh.name, 8 );
1457 temp_name_read[8] = 0;
1458 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1460 if (piggy_is_needed(i))
1461 #endif // note link to if.
1462 sbytes += sndh.length;
1463 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1466 SoundBits = d_malloc( sbytes + 16 );
1467 if ( SoundBits == NULL )
1468 Error( "Not enough memory to load sounds\n" );
1470 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1472 // piggy_read_sounds(snd_fp);
1479 int piggy_init(void)
1481 int ham_ok=0,snd_ok=0;
1484 hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
1485 hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
1487 for (i=0; i<MAX_SOUND_FILES; i++ ) {
1488 GameSounds[i].length = 0;
1489 GameSounds[i].data = NULL;
1493 for (i=0; i<MAX_BITMAP_FILES; i++ )
1494 GameBitmapXlat[i] = i;
1496 if ( !bogus_bitmap_initialized ) {
1499 bogus_bitmap_initialized = 1;
1500 memset( &bogus_bitmap, 0, sizeof(grs_bitmap) );
1501 bogus_bitmap.bm_w = bogus_bitmap.bm_h = bogus_bitmap.bm_rowsize = 64;
1502 bogus_bitmap.bm_data = bogus_data;
1503 c = gr_find_closest_color( 0, 0, 63 );
1504 for (i=0; i<4096; i++ ) bogus_data[i] = c;
1505 c = gr_find_closest_color( 63, 0, 0 );
1506 // Make a big red X !
1507 for (i=0; i<64; i++ ) {
1508 bogus_data[i*64+i] = c;
1509 bogus_data[i*64+(63-i)] = c;
1511 piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
1512 bogus_sound.length = 64*64;
1513 bogus_sound.data = bogus_data;
1514 GameBitmapOffset[0] = 0;
1517 if ( FindArg( "-bigpig" ))
1520 if ( FindArg( "-lowmem" ))
1521 piggy_low_memory = 1;
1523 if ( FindArg( "-nolowmem" ))
1524 piggy_low_memory = 0;
1526 if (piggy_low_memory)
1529 WIN(DDGRLOCK(dd_grd_curcanv));
1530 gr_set_curfont( SMALL_FONT );
1531 gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
1532 gr_printf( 0x8000, grd_curcanv->cv_h-20, "%s...", TXT_LOADING_DATA );
1533 WIN(DDGRUNLOCK(dd_grd_curcanv));
1535 #if 1 //def EDITOR //need for d1 mission briefings
1536 piggy_init_pigfile(DEFAULT_PIGFILE);
1539 snd_ok = ham_ok = read_hamfile();
1541 if (Piggy_hamfile_version >= 3)
1542 snd_ok = read_sndfile();
1544 atexit(piggy_close);
1546 mprintf ((0,"HamOk=%d SndOk=%d\n",ham_ok,snd_ok));
1547 return (ham_ok && snd_ok); //read ok
1550 int piggy_is_needed(int soundnum)
1554 if ( !digi_lomem ) return 1;
1556 for (i=0; i<MAX_SOUNDS; i++ ) {
1557 if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
1564 void piggy_read_sounds(void)
1577 fp = cfopen( DEFAULT_SNDFILE, "rb" );
1579 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1580 fp = cfopen( name, "rb");
1586 for (i=0; i<Num_sound_files; i++ ) {
1587 digi_sound *snd = &GameSounds[i];
1589 if ( SoundOffset[i] > 0 ) {
1590 if ( piggy_is_needed(i) ) {
1591 cfseek( fp, SoundOffset[i], SEEK_SET );
1593 // Read in the sound data!!!
1596 sbytes += snd->length;
1597 cfread( snd->data, snd->length, 1, fp );
1600 snd->data = (ubyte *) -1;
1606 mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
1611 extern int descent_critical_error;
1612 extern unsigned descent_critical_deverror;
1613 extern unsigned descent_critical_errcode;
1615 char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
1616 "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
1617 "Read fault", "General Failure" };
1619 void piggy_critical_error()
1621 grs_canvas * save_canv;
1622 grs_font * save_font;
1624 save_canv = grd_curcanv;
1625 save_font = grd_curcanv->cv_font;
1626 gr_palette_load( gr_palette );
1627 i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A' );
1630 gr_set_current_canvas(save_canv);
1631 grd_curcanv->cv_font = save_font;
1634 void piggy_bitmap_page_in( bitmap_index bitmap )
1643 Assert( i < MAX_BITMAP_FILES );
1644 Assert( i < Num_bitmap_files );
1645 Assert( Piggy_bitmap_cache_size > 0 );
1647 if ( i < 1 ) return;
1648 if ( i >= MAX_BITMAP_FILES ) return;
1649 if ( i >= Num_bitmap_files ) return;
1651 if ( GameBitmapOffset[i] == 0 ) return; // A read-from-disk bitmap!!!
1653 if ( piggy_low_memory ) {
1655 i = GameBitmapXlat[i]; // Xlat for low-memory settings!
1658 bmp = &GameBitmaps[i];
1660 if ( bmp->bm_flags & BM_FLAG_PAGED_OUT ) {
1664 descent_critical_error = 0;
1665 cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
1666 if ( descent_critical_error ) {
1667 piggy_critical_error();
1671 bmp->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1672 bmp->bm_flags = GameBitmapFlags[i];
1674 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1676 descent_critical_error = 0;
1677 zsize = cfile_read_int(Piggy_fp);
1678 if ( descent_critical_error ) {
1679 piggy_critical_error();
1683 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1684 //Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );
1685 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1687 piggy_bitmap_page_out_all();
1690 descent_critical_error = 0;
1691 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next+4], 1, zsize-4, Piggy_fp );
1692 if ( descent_critical_error ) {
1693 piggy_critical_error();
1698 switch (cfilelength(Piggy_fp)) {
1700 if (!FindArg("-macdata"))
1702 // otherwise, fall through...
1703 case MAC_ALIEN1_PIGSIZE:
1704 case MAC_ALIEN2_PIGSIZE:
1705 case MAC_FIRE_PIGSIZE:
1706 case MAC_GROUPA_PIGSIZE:
1707 case MAC_ICE_PIGSIZE:
1708 case MAC_WATER_PIGSIZE:
1709 rle_swap_0_255( bmp );
1710 memcpy(&zsize, bmp->bm_data, 4);
1715 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
1716 Piggy_bitmap_cache_next += zsize;
1717 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1719 piggy_bitmap_page_out_all();
1724 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1725 Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );
1726 if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) {
1727 piggy_bitmap_page_out_all();
1730 descent_critical_error = 0;
1731 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
1732 if ( descent_critical_error ) {
1733 piggy_critical_error();
1736 Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
1739 switch (cfilelength(Piggy_fp)) {
1741 if (!FindArg("-macdata"))
1743 // otherwise, fall through...
1744 case MAC_ALIEN1_PIGSIZE:
1745 case MAC_ALIEN2_PIGSIZE:
1746 case MAC_FIRE_PIGSIZE:
1747 case MAC_GROUPA_PIGSIZE:
1748 case MAC_ICE_PIGSIZE:
1749 case MAC_WATER_PIGSIZE:
1756 //@@if ( bmp->bm_selector ) {
1757 //@@#if !defined(WINDOWS) && !defined(MACINTOSH)
1758 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1759 //@@ Error( "Error modifying selector base in piggy.c\n" );
1766 if ( piggy_low_memory ) {
1768 GameBitmaps[org_i] = GameBitmaps[i];
1771 //@@Removed from John's code:
1773 //@@ if ( bmp->bm_selector ) {
1774 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1775 //@@ Error( "Error modifying selector base in piggy.c\n" );
1781 void piggy_bitmap_page_out_all()
1785 Piggy_bitmap_cache_next = 0;
1787 piggy_page_flushed++;
1792 for (i=0; i<Num_bitmap_files; i++ ) {
1793 if ( GameBitmapOffset[i] > 0 ) { // Don't page out bitmaps read from disk!!!
1794 GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
1795 GameBitmaps[i].bm_data = Piggy_bitmap_cache_data;
1799 mprintf(( 0, "Flushing piggy bitmap cache\n" ));
1802 void piggy_load_level_data()
1804 piggy_bitmap_page_out_all();
1810 void change_filename_ext( char *dest, char *src, char *ext );
1812 void piggy_write_pigfile(char *filename)
1815 int bitmap_data_start,data_offset;
1816 DiskBitmapHeader bmh;
1818 char subst_name[32];
1821 char tname[FILENAME_LEN];
1823 // -- mprintf( (0, "Paging in all piggy bitmaps..." ));
1824 for (i=0; i < Num_bitmap_files; i++ ) {
1827 PIGGY_PAGE_IN( bi );
1829 // -- mprintf( (0, "\n" ));
1833 // -- mprintf( (0, "Creating %s...",filename ));
1835 pig_fp = fopen( filename, "wb" ); //open PIG file
1836 Assert( pig_fp!=NULL );
1838 write_int(PIGFILE_ID,pig_fp);
1839 write_int(PIGFILE_VERSION,pig_fp);
1842 fwrite( &Num_bitmap_files, sizeof(int), 1, pig_fp );
1845 bitmap_data_start = ftell(pig_fp);
1846 bitmap_data_start += (Num_bitmap_files-1)*DISKBITMAPHEADER_SIZE;
1847 data_offset = bitmap_data_start;
1849 change_filename_ext(tname,filename,"lst");
1850 fp1 = fopen( tname, "wt" );
1851 change_filename_ext(tname,filename,"all");
1852 fp2 = fopen( tname, "wt" );
1854 for (i=1; i < Num_bitmap_files; i++ ) {
1860 p = strchr(AllBitmaps[i].name,'#');
1867 fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
1868 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1870 bmh.dflags = DBM_FLAG_ABM + n;
1874 fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
1875 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1879 bmp = &GameBitmaps[i];
1881 Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
1884 fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
1885 org_offset = ftell(pig_fp);
1886 bmh.offset = data_offset - bitmap_data_start;
1887 fseek( pig_fp, data_offset, SEEK_SET );
1889 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1890 size = (int *)bmp->bm_data;
1891 fwrite( bmp->bm_data, sizeof(ubyte), *size, pig_fp );
1892 data_offset += *size;
1894 fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
1896 fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, pig_fp );
1897 data_offset += bmp->bm_rowsize * bmp->bm_h;
1899 fprintf( fp1, ".\n" );
1901 fseek( pig_fp, org_offset, SEEK_SET );
1902 Assert( GameBitmaps[i].bm_w < 4096 );
1903 bmh.width = (GameBitmaps[i].bm_w & 0xff);
1904 bmh.wh_extra = ((GameBitmaps[i].bm_w >> 8) & 0x0f);
1905 Assert( GameBitmaps[i].bm_h < 4096 );
1906 bmh.height = GameBitmaps[i].bm_h;
1907 bmh.wh_extra |= ((GameBitmaps[i].bm_h >> 4) & 0xf0);
1908 bmh.flags = GameBitmaps[i].bm_flags;
1909 if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name )) {
1910 bitmap_index other_bitmap;
1911 other_bitmap = piggy_find_bitmap( subst_name );
1912 GameBitmapXlat[i] = other_bitmap.index;
1913 bmh.flags |= BM_FLAG_PAGED_OUT;
1914 //mprintf(( 0, "Skipping bitmap %d\n", i ));
1915 //mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
1917 bmh.flags &= ~BM_FLAG_PAGED_OUT;
1919 bmh.avg_color=GameBitmaps[i].avg_color;
1920 fwrite( &bmh, DISKBITMAPHEADER_SIZE, 1, pig_fp ); // Mark as a bitmap
1925 mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
1926 fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
1933 static void write_int(int i,FILE *file)
1935 if (fwrite( &i, sizeof(i), 1, file) != 1)
1936 Error( "Error reading int in gamesave.c" );
1940 void piggy_dump_all()
1944 int org_offset,data_offset=0;
1945 DiskSoundHeader sndh;
1946 int sound_data_start=0;
1949 #ifdef NO_DUMP_SOUNDS
1950 Num_sound_files = 0;
1951 Num_sound_files_new = 0;
1954 if (!Must_write_hamfile && (Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
1957 fp1 = fopen( "ham.lst", "wt" );
1958 fp2 = fopen( "ham.all", "wt" );
1960 if (Must_write_hamfile || Num_bitmap_files_new) {
1962 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1964 ham_fp = fopen( DEFAULT_HAMFILE, "wb" ); //open HAM file
1965 Assert( ham_fp!=NULL );
1967 write_int(HAMFILE_ID,ham_fp);
1968 write_int(HAMFILE_VERSION,ham_fp);
1970 bm_write_all(ham_fp);
1971 xlat_offset = ftell(ham_fp);
1972 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1975 if (Num_bitmap_files_new)
1976 piggy_write_pigfile(DEFAULT_PIGFILE);
1978 //free up memeory used by new bitmaps
1979 for (i=Num_bitmap_files-Num_bitmap_files_new;i<Num_bitmap_files;i++)
1980 d_free(GameBitmaps[i].bm_data);
1982 //next thing must be done after pig written
1983 fseek( ham_fp, xlat_offset, SEEK_SET );
1984 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1987 mprintf( (0, "\n" ));
1990 if (Num_sound_files_new) {
1992 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1993 // Now dump sound file
1994 ham_fp = fopen( DEFAULT_SNDFILE, "wb" );
1995 Assert( ham_fp!=NULL );
1997 write_int(SNDFILE_ID,ham_fp);
1998 write_int(SNDFILE_VERSION,ham_fp);
2000 fwrite( &Num_sound_files, sizeof(int), 1, ham_fp );
2002 mprintf( (0, "\nDumping sounds..." ));
2004 sound_data_start = ftell(ham_fp);
2005 sound_data_start += Num_sound_files*sizeof(DiskSoundHeader);
2006 data_offset = sound_data_start;
2008 for (i=0; i < Num_sound_files; i++ ) {
2011 snd = &GameSounds[i];
2012 strcpy( sndh.name, AllSounds[i].name );
2013 sndh.length = GameSounds[i].length;
2014 sndh.offset = data_offset - sound_data_start;
2016 org_offset = ftell(ham_fp);
2017 fseek( ham_fp, data_offset, SEEK_SET );
2019 sndh.data_length = GameSounds[i].length;
2020 fwrite( snd->data, sizeof(ubyte), snd->length, ham_fp );
2021 data_offset += snd->length;
2022 fseek( ham_fp, org_offset, SEEK_SET );
2023 fwrite( &sndh, sizeof(DiskSoundHeader), 1, ham_fp ); // Mark as a bitmap
2025 fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
2026 fprintf( fp2, "%s.raw\n", AllSounds[i].name );
2030 mprintf( (0, "\n" ));
2033 fprintf( fp1, "Total sound size: %d bytes\n", data_offset-sound_data_start);
2034 mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
2035 fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
2040 // Never allow the game to run after building ham.
2054 d_free( SoundBits );
2056 hashtable_free( &AllBitmapsNames );
2057 hashtable_free( &AllDigiSndNames );
2061 int piggy_does_bitmap_exist_slow( char * name )
2065 for (i=0; i<Num_bitmap_files; i++ ) {
2066 if ( !strcmp( AllBitmaps[i].name, name) )
2073 #define NUM_GAUGE_BITMAPS 23
2074 char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = {
2075 "gauge01", "gauge01b",
2076 "gauge02", "gauge02b",
2077 "gauge06", "gauge06b",
2078 "targ01", "targ01b",
2079 "targ02", "targ02b",
2080 "targ03", "targ03b",
2081 "targ04", "targ04b",
2082 "targ05", "targ05b",
2083 "targ06", "targ06b",
2084 "gauge18", "gauge18b",
2090 int piggy_is_gauge_bitmap( char * base_name )
2093 for (i=0; i<NUM_GAUGE_BITMAPS; i++ ) {
2094 if ( !stricmp( base_name, gauge_bitmap_names[i] ))
2101 int piggy_is_substitutable_bitmap( char * name, char * subst_name )
2105 char base_name[ 16 ];
2107 strcpy( subst_name, name );
2108 p = strchr( subst_name, '#' );
2110 frame = atoi( &p[1] );
2112 strcpy( base_name, subst_name );
2113 if ( !piggy_is_gauge_bitmap( base_name )) {
2114 sprintf( subst_name, "%s#%d", base_name, frame+1 );
2115 if ( piggy_does_bitmap_exist_slow( subst_name ) ) {
2117 sprintf( subst_name, "%s#%d", base_name, frame-1 );
2123 strcpy( subst_name, name );
2130 // New Windows stuff
2132 // windows bitmap page in
2133 // Page in a bitmap, if ddraw, then page it into a ddsurface in
2134 // 'video' memory. if that fails, page it in normally.
2136 void piggy_bitmap_page_in_w( bitmap_index bitmap, int ddraw )
2141 // Essential when switching video modes!
2143 void piggy_bitmap_page_out_all_w()
2151 * Functions for loading replacement textures
2152 * 1) From .pog files
2153 * 2) From descent.pig (for loading d1 levels)
2156 extern void change_filename_extension( char *dest, char *src, char *new_ext );
2157 extern char last_palette_loaded_pig[];
2159 ubyte *Bitmap_replacement_data=NULL;
2161 void free_bitmap_replacements()
2163 if (Bitmap_replacement_data) {
2164 d_free(Bitmap_replacement_data);
2165 Bitmap_replacement_data = NULL;
2169 void load_bitmap_replacements(char *level_name)
2171 char ifile_name[FILENAME_LEN];
2175 //first, free up data allocated for old bitmaps
2176 free_bitmap_replacements();
2178 change_filename_extension(ifile_name, level_name, ".POG" );
2180 ifile = cfopen(ifile_name,"rb");
2183 int id,version,n_bitmaps;
2184 int bitmap_data_size;
2187 id = cfile_read_int(ifile);
2188 version = cfile_read_int(ifile);
2190 if (id != MAKE_SIG('G','O','P','D') || version != 1) {
2195 n_bitmaps = cfile_read_int(ifile);
2197 MALLOC( indices, ushort, n_bitmaps );
2199 for (i = 0; i < n_bitmaps; i++)
2200 indices[i] = cfile_read_short(ifile);
2202 bitmap_data_size = cfilelength(ifile) - cftell(ifile) - DISKBITMAPHEADER_SIZE * n_bitmaps;
2203 MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
2205 for (i=0;i<n_bitmaps;i++) {
2206 DiskBitmapHeader bmh;
2207 grs_bitmap temp_bitmap;
2209 DiskBitmapHeader_read(&bmh, ifile);
2211 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2213 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2214 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2215 temp_bitmap.avg_color = bmh.avg_color;
2216 temp_bitmap.bm_data = Bitmap_replacement_data + bmh.offset;
2218 if ( bmh.flags & BM_FLAG_TRANSPARENT ) temp_bitmap.bm_flags |= BM_FLAG_TRANSPARENT;
2219 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) temp_bitmap.bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2220 if ( bmh.flags & BM_FLAG_NO_LIGHTING ) temp_bitmap.bm_flags |= BM_FLAG_NO_LIGHTING;
2221 if ( bmh.flags & BM_FLAG_RLE ) temp_bitmap.bm_flags |= BM_FLAG_RLE;
2222 if ( bmh.flags & BM_FLAG_RLE_BIG ) temp_bitmap.bm_flags |= BM_FLAG_RLE_BIG;
2224 GameBitmaps[indices[i]] = temp_bitmap;
2227 cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
2233 last_palette_loaded_pig[0]= 0; //force pig re-load
2235 texmerge_flush(); //for re-merging with new textures
2238 atexit(free_bitmap_replacements);
2241 #define FIRST_D1_TEXTURE 722
2242 #define LAST_D1_STATIC_TEXTURE 1042//1342 //afterwards, we have door frames and stuff
2243 #define FIRST_D2_TEXTURE 1243
2245 void load_d1_bitmap_replacements()
2247 CFILE * d1_Piggy_fp;
2248 grs_bitmap temp_bitmap;
2249 DiskBitmapHeader bmh;
2250 int pig_data_start, bitmap_header_start, bitmap_data_start;
2251 int N_bitmaps, zsize;
2252 int d1_index, d2_index;
2253 ubyte colormap[256];
2254 ubyte *next_bitmap; // to which address we write the next bitmap
2256 d1_Piggy_fp = cfopen( D1_PIGFILE, "rb" );
2259 return; // use d2 bitmaps instead...
2261 //first, free up data allocated for old bitmaps
2262 free_bitmap_replacements();
2264 // read d1 palette, build colormap
2267 ubyte d1_palette[256*3];
2268 CFILE * palette_file = cfopen(D1_PALETTE, "rb" );
2269 Assert( palette_file );
2270 Assert( cfilelength( palette_file ) == 9472 );
2271 cfread( d1_palette, 256, 3, palette_file);
2272 cfclose( palette_file );
2273 build_colormap_good( d1_palette, colormap, freq );
2274 // don't change transparencies:
2275 colormap[254] = 254;
2276 colormap[255] = 255;
2279 switch (cfilelength(d1_Piggy_fp)) {
2280 case D1_SHAREWARE_10_PIGSIZE:
2281 case D1_SHAREWARE_PIGSIZE:
2287 case D1_OEM_PIGSIZE:
2288 case D1_MAC_PIGSIZE:
2289 case D1_MAC_SHARE_PIGSIZE:
2291 pig_data_start = cfile_read_int(d1_Piggy_fp );
2292 bm_read_all_d1( d1_Piggy_fp );
2293 //for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2297 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2298 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2300 int N_sounds = cfile_read_int(d1_Piggy_fp);
2301 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2302 + N_sounds * DISKSOUNDHEADER_SIZE;
2303 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2304 bitmap_data_start = bitmap_header_start + header_size;
2307 MALLOC( Bitmap_replacement_data, ubyte, cfilelength(d1_Piggy_fp) - bitmap_data_start ); // too much
2308 //TODO: handle case where b_r_d == 0! (have to convert textures, return, not bm_read_all_d1)
2310 next_bitmap = Bitmap_replacement_data;
2312 for (d1_index=1; d1_index<=N_bitmaps; d1_index++ ) {
2313 // only change wall texture bitmaps
2314 if (d1_index >= FIRST_D1_TEXTURE && d1_index <= LAST_D1_STATIC_TEXTURE) {
2315 d2_index = d1_index + FIRST_D2_TEXTURE - FIRST_D1_TEXTURE;
2317 cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2318 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2320 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2322 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2323 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2324 temp_bitmap.avg_color = bmh.avg_color;
2326 //GameBitmapFlags[convert_d1_bitmap_num(d1_index)] = 0;
2328 if ( bmh.flags & BM_FLAG_TRANSPARENT )
2329 temp_bitmap.bm_flags |= BM_FLAG_TRANSPARENT;
2330 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT )
2331 temp_bitmap.bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2332 if ( bmh.flags & BM_FLAG_NO_LIGHTING )
2333 temp_bitmap.bm_flags |= BM_FLAG_NO_LIGHTING;
2334 if ( bmh.flags & BM_FLAG_RLE )
2335 temp_bitmap.bm_flags |= BM_FLAG_RLE;
2336 if ( bmh.flags & BM_FLAG_RLE_BIG )
2337 temp_bitmap.bm_flags |= BM_FLAG_RLE_BIG;
2339 temp_bitmap.bm_data = next_bitmap;
2341 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2342 zsize = cfile_read_int(d1_Piggy_fp);
2343 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2344 cfread(next_bitmap, 1, zsize, d1_Piggy_fp);
2346 switch(cfilelength(d1_Piggy_fp)) {
2347 case D1_MAC_PIGSIZE:
2348 case D1_MAC_SHARE_PIGSIZE:
2349 rle_swap_0_255(&temp_bitmap);
2351 rle_remap(&temp_bitmap, colormap);
2353 GameBitmaps[d2_index] = temp_bitmap;
2355 memcpy(&zsize, temp_bitmap.bm_data, 4);
2356 next_bitmap += zsize;
2360 cfclose(d1_Piggy_fp);
2362 last_palette_loaded_pig[0]= 0; //force pig re-load
2364 texmerge_flush(); //for re-merging with new textures
2366 atexit(free_bitmap_replacements);
2370 extern int extra_bitmap_num;
2373 * Find and load the named bitmap from descent.pig
2374 * similar to exitmodel_bm_load_sub
2376 bitmap_index read_extra_d1_bitmap(char *name)
2378 bitmap_index bitmap_num;
2379 grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2381 bitmap_num.index = 0;
2386 DiskBitmapHeader bmh;
2387 int pig_data_start, bitmap_header_start, bitmap_data_start;
2388 int N_bitmaps, zsize;
2389 ubyte colormap[256];
2391 d1_Piggy_fp = cfopen(D1_PIGFILE, "rb");
2394 con_printf(CON_DEBUG, "could not open %s\n", D1_PIGFILE);
2398 // read d1 palette, build colormap
2401 ubyte d1_palette[256*3];
2402 CFILE * palette_file = cfopen(D1_PALETTE, "rb");
2403 if (!palette_file || cfilelength(palette_file) != 9472)
2405 con_printf(CON_DEBUG, "could not open %s\n", D1_PALETTE);
2408 cfread( d1_palette, 256, 3, palette_file);
2409 cfclose( palette_file );
2410 build_colormap_good( d1_palette, colormap, freq );
2411 // don't change transparencies:
2412 colormap[254] = 254;
2413 colormap[255] = 255;
2416 switch (cfilelength(d1_Piggy_fp)) {
2417 case D1_SHAREWARE_10_PIGSIZE:
2418 case D1_SHAREWARE_PIGSIZE:
2424 case D1_OEM_PIGSIZE:
2425 case D1_MAC_PIGSIZE:
2426 case D1_MAC_SHARE_PIGSIZE:
2427 pig_data_start = cfile_read_int(d1_Piggy_fp);
2431 cfseek(d1_Piggy_fp, pig_data_start, SEEK_SET);
2432 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2434 int N_sounds = cfile_read_int(d1_Piggy_fp);
2435 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2436 + N_sounds * DISKSOUNDHEADER_SIZE;
2437 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2438 bitmap_data_start = bitmap_header_start + header_size;
2441 for (i = 0; i < N_bitmaps; i++)
2443 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2444 if (!strnicmp(bmh.name, name, 8))
2448 if (strnicmp(bmh.name, name, 8))
2450 con_printf(CON_DEBUG, "could not find bitmap %s\n", name);
2454 memset( new, 0, sizeof(grs_bitmap) );
2456 new->bm_w = new->bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2457 new->bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2458 new->avg_color = bmh.avg_color;
2460 if ( bmh.flags & BM_FLAG_TRANSPARENT )
2461 new->bm_flags |= BM_FLAG_TRANSPARENT;
2462 if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT )
2463 new->bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2464 if ( bmh.flags & BM_FLAG_NO_LIGHTING )
2465 new->bm_flags |= BM_FLAG_NO_LIGHTING;
2466 if ( bmh.flags & BM_FLAG_RLE )
2467 new->bm_flags |= BM_FLAG_RLE;
2468 if ( bmh.flags & BM_FLAG_RLE_BIG )
2469 new->bm_flags |= BM_FLAG_RLE_BIG;
2471 if ( bmh.flags & BM_FLAG_RLE )
2473 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2474 zsize = cfile_read_int(d1_Piggy_fp);
2477 zsize = new->bm_w * new->bm_h;
2478 new->bm_data = d_malloc(zsize);
2479 cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2480 cfread(new->bm_data, 1, zsize, d1_Piggy_fp);
2482 switch(cfilelength(d1_Piggy_fp)) {
2483 case D1_MAC_PIGSIZE:
2484 case D1_MAC_SHARE_PIGSIZE:
2485 rle_swap_0_255(new);
2487 rle_remap(new, colormap);
2489 cfclose(d1_Piggy_fp);
2492 new->avg_color = 0; //compute_average_pixel(new);
2494 bitmap_num.index = extra_bitmap_num;
2496 GameBitmaps[extra_bitmap_num++] = *new;
2502 #ifndef FAST_FILE_IO
2504 * reads a bitmap_index structure from a CFILE
2506 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2508 bi->index = cfile_read_short(fp);
2512 * reads n bitmap_index structs from a CFILE
2514 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2518 for (i = 0; i < n; i++)
2519 bi[i].index = cfile_read_short(fp);
2524 * reads a DiskBitmapHeader structure from a CFILE
2526 void DiskBitmapHeader_read(DiskBitmapHeader *dbh, CFILE *fp)
2528 cfread(dbh->name, 8, 1, fp);
2529 dbh->dflags = cfile_read_byte(fp);
2530 dbh->width = cfile_read_byte(fp);
2531 dbh->height = cfile_read_byte(fp);
2532 dbh->wh_extra = cfile_read_byte(fp);
2533 dbh->flags = cfile_read_byte(fp);
2534 dbh->avg_color = cfile_read_byte(fp);
2535 dbh->offset = cfile_read_int(fp);
2539 * reads a DiskSoundHeader structure from a CFILE
2541 void DiskSoundHeader_read(DiskSoundHeader *dsh, CFILE *fp)
2543 cfread(dsh->name, 8, 1, fp);
2544 dsh->length = cfile_read_int(fp);
2545 dsh->data_length = cfile_read_int(fp);
2546 dsh->offset = cfile_read_int(fp);
2548 #endif // FAST_FILE_IO
2551 * reads a descent 1 DiskBitmapHeader structure from a CFILE
2553 void DiskBitmapHeader_d1_read(DiskBitmapHeader *dbh, CFILE *fp)
2555 cfread(dbh->name, 8, 1, fp);
2556 dbh->dflags = cfile_read_byte(fp);
2557 dbh->width = cfile_read_byte(fp);
2558 dbh->height = cfile_read_byte(fp);
2560 dbh->flags = cfile_read_byte(fp);
2561 dbh->avg_color = cfile_read_byte(fp);
2562 dbh->offset = cfile_read_int(fp);