1 /* $Id: piggy.c,v 1.44 2003-11-03 11:03:48 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.44 2003-11-03 11:03:48 btb Exp $";
411 #include "gamefont.h"
415 #include "gamemine.h"
416 #include "textures.h"
417 #include "texmerge.h"
423 #include "byteswap.h"
424 #include "findfile.h"
428 // #include "unarj.h"
430 #include <Strings.h> // MacOS Toolbox header
435 //#define NO_DUMP_SOUNDS 1 //if set, dump bitmaps but not sounds
437 #define DEFAULT_PIGFILE_REGISTERED "groupa.pig"
438 #define DEFAULT_PIGFILE_SHAREWARE "d2demo.pig"
439 #define DEFAULT_HAMFILE_REGISTERED "descent2.ham"
440 #define DEFAULT_HAMFILE_SHAREWARE "d2demo.ham"
442 #define D1_PALETTE "palette.256"
444 #define DEFAULT_PIGFILE (cfexist(DEFAULT_PIGFILE_REGISTERED)?DEFAULT_PIGFILE_REGISTERED:DEFAULT_PIGFILE_SHAREWARE)
445 #define DEFAULT_HAMFILE (cfexist(DEFAULT_HAMFILE_REGISTERED)?DEFAULT_HAMFILE_REGISTERED:DEFAULT_HAMFILE_SHAREWARE)
446 #define DEFAULT_SNDFILE ((Piggy_hamfile_version < 3)?DEFAULT_HAMFILE_SHAREWARE:(digi_sample_rate==SAMPLE_RATE_22K)?"descent2.s22":"descent2.s11")
448 #define MAC_ALIEN1_PIGSIZE 5013035
449 #define MAC_ALIEN2_PIGSIZE 4909916
450 #define MAC_FIRE_PIGSIZE 4969035
451 #define MAC_GROUPA_PIGSIZE 4929684 // also used for mac shareware
452 #define MAC_ICE_PIGSIZE 4923425
453 #define MAC_WATER_PIGSIZE 4832403
455 ubyte *BitmapBits = NULL;
456 ubyte *SoundBits = NULL;
458 typedef struct BitmapFile {
462 typedef struct SoundFile {
466 hashtable AllBitmapsNames;
467 hashtable AllDigiSndNames;
469 int Num_bitmap_files = 0;
470 int Num_sound_files = 0;
472 digi_sound GameSounds[MAX_SOUND_FILES];
473 int SoundOffset[MAX_SOUND_FILES];
474 grs_bitmap GameBitmaps[MAX_BITMAP_FILES];
476 alias alias_list[MAX_ALIASES];
479 int Must_write_hamfile = 0;
480 int Num_bitmap_files_new = 0;
481 int Num_sound_files_new = 0;
482 BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
483 static SoundFile AllSounds[ MAX_SOUND_FILES ];
485 int Piggy_hamfile_version = 0;
487 int piggy_low_memory = 0;
489 int Piggy_bitmap_cache_size = 0;
490 int Piggy_bitmap_cache_next = 0;
491 ubyte * Piggy_bitmap_cache_data = NULL;
492 static int GameBitmapOffset[MAX_BITMAP_FILES];
493 static ubyte GameBitmapFlags[MAX_BITMAP_FILES];
494 ushort GameBitmapXlat[MAX_BITMAP_FILES];
496 #define PIGGY_BUFFER_SIZE (2400*1024)
499 #define PIGGY_SMALL_BUFFER_SIZE (1400*1024) // size of buffer when piggy_low_memory is set
502 #undef PIGGY_BUFFER_SIZE
503 #undef PIGGY_SMALL_BUFFER_SIZE
505 #define PIGGY_BUFFER_SIZE (2000*1024)
506 #define PIGGY_SMALL_BUFFER_SIZE (1100 * 1024)
511 int piggy_page_flushed = 0;
513 #define DBM_FLAG_ABM 64 // animated bitmap
514 #define DBM_NUM_FRAMES 63
516 #define BM_FLAGS_TO_COPY (BM_FLAG_TRANSPARENT | BM_FLAG_SUPER_TRANSPARENT \
517 | BM_FLAG_NO_LIGHTING | BM_FLAG_RLE | BM_FLAG_RLE_BIG)
522 extern short cd_VRefNum;
523 extern void ConcatPStr(StringPtr dst, StringPtr src);
524 extern int ConvertPToCStr(StringPtr inPStr, char* outCStrBuf);
525 extern int ConvertCToPStr(char* inCStr, StringPtr outPStrBuf);
528 int piggy_is_substitutable_bitmap( char * name, char * subst_name );
531 void piggy_write_pigfile(char *filename);
532 static void write_int(int i,FILE *file);
535 void swap_0_255(grs_bitmap *bmp)
539 for (i = 0; i < bmp->bm_h * bmp->bm_w; i++) {
540 if(bmp->bm_data[i] == 0)
541 bmp->bm_data[i] = 255;
542 else if (bmp->bm_data[i] == 255)
547 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
550 Assert( Num_bitmap_files < MAX_BITMAP_FILES );
552 temp.index = Num_bitmap_files;
556 if ( FindArg("-macdata") )
559 if ( !BigPig ) gr_bitmap_rle_compress( bmp );
560 Num_bitmap_files_new++;
563 strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
564 hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
565 GameBitmaps[Num_bitmap_files] = *bmp;
567 GameBitmapOffset[Num_bitmap_files] = 0;
568 GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
575 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
579 Assert( Num_sound_files < MAX_SOUND_FILES );
581 strncpy( AllSounds[Num_sound_files].name, name, 12 );
582 hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
583 GameSounds[Num_sound_files] = *snd;
585 SoundOffset[Num_sound_files] = 0;
591 Num_sound_files_new++;
597 bitmap_index piggy_find_bitmap( char * name )
605 if ((t=strchr(name,'#'))!=NULL)
608 for (i=0;i<Num_aliases;i++)
609 if (stricmp(name,alias_list[i].alias_name)==0) {
610 if (t) { //extra stuff for ABMs
611 static char temp[FILENAME_LEN];
612 _splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
618 name=alias_list[i].file_name;
625 i = hashtable_search( &AllBitmapsNames, name );
634 int piggy_find_sound( char * name )
638 i = hashtable_search( &AllDigiSndNames, name );
646 CFILE * Piggy_fp = NULL;
648 #define FILENAME_LEN 13
650 char Current_pigfile[FILENAME_LEN] = "";
652 void piggy_close_file()
657 Current_pigfile[0] = 0;
661 int Pigfile_initialized=0;
663 #define PIGFILE_ID MAKE_SIG('G','I','P','P') //PPIG
664 #define PIGFILE_VERSION 2
666 extern char CDROM_dir[];
668 int request_cd(void);
673 //copies a pigfile from the CD to the current dir
674 //retuns file handle of new pig
675 CFILE *copy_pigfile_from_cd(char *filename) // MACINTOSH VERSION
678 char sourcePathAndFileCStr[255] = "";
679 char destPathAndFileCStr[255] = "";
681 FILE* sourceFile = NULL;
682 FILE* destFile = NULL;
683 const int BUF_SIZE = 4096;
687 Str255 sourcePathAndFilePStr = "\p";
688 Str255 destPathAndFilePStr = "\p";
689 Str255 pigfileNamePStr = "\p";
690 HParamBlockRec theSourcePigHFSParams;
691 HParamBlockRec theDestPigHFSParams;
692 OSErr theErr = noErr;
693 char oldDirCStr[255] = "";
695 getcwd(oldDirCStr, 255);
697 show_boxed_message("Copying bitmap data from CD...");
698 gr_palette_load(gr_palette); //I don't think this line is really needed
701 //First, delete all PIG files currently in the directory
702 if( !FileFindFirst( "*.pig", &find ) )
707 } while( !FileFindNext( &find ) );
713 //Now, copy over new pig
714 songs_stop_redbook(); //so we can read off the cd
716 // make the source path "<cd volume>:Data:filename.pig"
717 //MWA ConvertCToPStr(filename, pigfileNamePStr);
719 //MWA ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:"); // volume ID is cd_VRefNum
720 //MWA ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
723 strcpy(sourcePathAndFileCStr, "Descent II:Data:");
724 strcat(sourcePathAndFileCStr, filename);
726 // make the destination path "<default directory>:Data:filename.pig"
727 //MWA ConcatPStr(destPathAndFilePStr, "\p:Data:");
728 //MWA ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
729 //MWA ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
730 //MWA ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
732 strcpy(destPathAndFileCStr, ":Data:");
733 strcat(destPathAndFileCStr, filename);
735 strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
736 strcpy(destPathAndFilePStr, destPathAndFileCStr);
737 c2pstr(sourcePathAndFilePStr);
738 c2pstr(destPathAndFilePStr);
741 // Open the source file
742 sourceFile = fopen(sourcePathAndFileCStr,"rb");
746 if (request_cd() == -1)
747 Error("Cannot load file <%s> from CD",filename);
750 } while (!sourceFile);
753 // Get the time stamp from the source file
754 theSourcePigHFSParams.fileParam.ioCompletion = nil;
755 theSourcePigHFSParams.fileParam.ioNamePtr = sourcePathAndFilePStr;
756 theSourcePigHFSParams.fileParam.ioVRefNum = cd_VRefNum;
757 theSourcePigHFSParams.fileParam.ioFDirIndex = 0;
758 theSourcePigHFSParams.fileParam.ioDirID = 0;
760 theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
763 // Error getting file time stamp!! Why? JTS
764 Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
767 // Copy the file over
770 // Open the destination file
771 destFile = fopen(destPathAndFileCStr,"wb");
774 Error("Cannot create file: <%s>\n", destPathAndFileCStr);
777 // Copy bytes until the end of the source file
778 while (!feof(sourceFile))
783 bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
784 if (ferror(sourceFile))
785 Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
787 // Assert is bogus Assert(bytes_read == BUF_SIZE || feof(sourceFile));
789 fwrite(buf,1,bytes_read,destFile);
790 if (ferror(destFile))
791 Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
794 // close the source/dest files
795 if (fclose(sourceFile))
796 Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
797 if (fclose(destFile))
798 Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
800 // Get the current hfs data for the new file
801 theDestPigHFSParams.fileParam.ioCompletion = nil;
802 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
803 theDestPigHFSParams.fileParam.ioVRefNum = 0;
804 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
805 theDestPigHFSParams.fileParam.ioDirID = 0;
806 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
807 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
809 // Error getting file time stamp!! Why? JTS
810 Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
813 // Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
814 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
815 theDestPigHFSParams.fileParam.ioVRefNum = 0;
816 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
817 theDestPigHFSParams.fileParam.ioDirID = 0;
819 // Copy the time stamp from the source file info
820 theDestPigHFSParams.fileParam.ioFlCrDat = theSourcePigHFSParams.fileParam.ioFlCrDat;
821 theDestPigHFSParams.fileParam.ioFlMdDat = theSourcePigHFSParams.fileParam.ioFlMdDat;
822 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
823 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
825 // Set the dest file's time stamp to the source file's time stamp values
826 theErr = PBHSetFInfo(&theDestPigHFSParams, false);
828 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
830 Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
833 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
835 return cfopen(destPathAndFileCStr, "rb");
838 #else //PC Version of copy_pigfile_from_cd is below
840 //copies a pigfile from the CD to the current dir
841 //retuns file handle of new pig
842 CFILE *copy_pigfile_from_cd(char *filename)
848 return cfopen(filename, "rb");
849 show_boxed_message("Copying bitmap data from CD...");
850 gr_palette_load(gr_palette); //I don't think this line is really needed
852 //First, delete all PIG files currently in the directory
854 if( !FileFindFirst( "*.pig", &find ) ) {
856 cfile_delete(find.name);
857 } while( !FileFindNext( &find ) );
861 //Now, copy over new pig
863 songs_stop_redbook(); //so we can read off the cd
865 //new code to unarj file
866 strcpy(name,CDROM_dir);
867 strcat(name,"descent2.sow");
870 // ret = unarj_specific_file(name,filename,filename);
875 if (ret != EXIT_SUCCESS) {
877 //delete file, so we don't leave partial file
878 cfile_delete(filename);
881 if (request_cd() == -1)
883 //NOTE LINK TO ABOVE IF
884 Error("Cannot load file <%s> from CD",filename);
887 } while (ret != EXIT_SUCCESS);
889 return cfopen(filename, "rb");
892 #endif // end of ifdef MAC around copy_pigfile_from_cd
894 //initialize a pigfile, reading headers
895 //returns the size of all the bitmap data
896 void piggy_init_pigfile(char *filename)
900 char temp_name_read[16];
901 grs_bitmap temp_bitmap;
902 DiskBitmapHeader bmh;
903 int header_size, N_bitmaps, data_size, data_start;
905 char name[255]; // filename + path for the mac
908 piggy_close_file(); //close old pig if still open
910 //rename pigfile for shareware
911 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
912 filename = DEFAULT_PIGFILE_SHAREWARE;
915 Piggy_fp = cfopen( filename, "rb" );
917 sprintf(name, ":Data:%s", filename);
918 Piggy_fp = cfopen( name, "rb" );
920 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
921 if (Piggy_fp == NULL)
923 Error("Cannot load required file <%s>",name);
925 #endif // end of if def shareware
931 return; //if editor, ok to not have pig, because we'll build one
933 Piggy_fp = copy_pigfile_from_cd(filename);
937 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
938 int pig_id,pig_version;
940 pig_id = cfile_read_int(Piggy_fp);
941 pig_version = cfile_read_int(Piggy_fp);
942 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
943 cfclose(Piggy_fp); //out of date pig
944 Piggy_fp = NULL; //..so pretend it's not here
951 return; //if editor, ok to not have pig, because we'll build one
953 Error("Cannot load required file <%s>",filename);
957 strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
959 N_bitmaps = cfile_read_int(Piggy_fp);
961 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
963 data_start = header_size + cftell(Piggy_fp);
965 data_size = cfilelength(Piggy_fp) - data_start;
967 Num_bitmap_files = 1;
969 for (i=0; i<N_bitmaps; i++ ) {
970 DiskBitmapHeader_read(&bmh, Piggy_fp);
971 memcpy( temp_name_read, bmh.name, 8 );
972 temp_name_read[8] = 0;
973 if ( bmh.dflags & DBM_FLAG_ABM )
974 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & DBM_NUM_FRAMES );
976 strcpy( temp_name, temp_name_read );
977 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
978 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
979 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
980 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
981 temp_bitmap.avg_color = bmh.avg_color;
982 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
984 GameBitmapFlags[i+1] = bmh.flags & BM_FLAGS_TO_COPY;
986 GameBitmapOffset[i+1] = bmh.offset + data_start;
987 Assert( (i+1) == Num_bitmap_files );
988 piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
992 Piggy_bitmap_cache_size = data_size + (data_size/10); //extra mem for new bitmaps
993 Assert( Piggy_bitmap_cache_size > 0 );
995 Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
997 if (piggy_low_memory)
998 Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
1001 BitmapBits = d_malloc( Piggy_bitmap_cache_size );
1002 if ( BitmapBits == NULL )
1003 Error( "Not enough memory to load bitmaps\n" );
1004 Piggy_bitmap_cache_data = BitmapBits;
1005 Piggy_bitmap_cache_next = 0;
1007 #if defined(MACINTOSH) && defined(SHAREWARE)
1008 // load_exit_models();
1011 Pigfile_initialized=1;
1014 #define FILENAME_LEN 13
1015 #define MAX_BITMAPS_PER_BRUSH 30
1017 extern int compute_average_pixel(grs_bitmap *new);
1019 ubyte *Bitmap_replacement_data = NULL;
1021 //reads in a new pigfile (for new palette)
1022 //returns the size of all the bitmap data
1023 void piggy_new_pigfile(char *pigname)
1027 char temp_name_read[16];
1028 grs_bitmap temp_bitmap;
1029 DiskBitmapHeader bmh;
1030 int header_size, N_bitmaps, data_size, data_start;
1031 int must_rewrite_pig = 0;
1038 //rename pigfile for shareware
1039 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
1040 pigname = DEFAULT_PIGFILE_SHAREWARE;
1042 if (strnicmp(Current_pigfile, pigname, sizeof(Current_pigfile)) == 0 // correct pig already loaded
1043 && !Bitmap_replacement_data) // no need to reload: no bitmaps were altered
1046 if (!Pigfile_initialized) { //have we ever opened a pigfile?
1047 piggy_init_pigfile(pigname); //..no, so do initialization stuff
1051 piggy_close_file(); //close old pig if still open
1053 Piggy_bitmap_cache_next = 0; //free up cache
1055 strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
1058 Piggy_fp = cfopen( pigname, "rb" );
1060 sprintf(name, ":Data:%s", pigname);
1061 Piggy_fp = cfopen( name, "rb" );
1063 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
1064 if (Piggy_fp == NULL)
1066 Error("Cannot load required file <%s>",name);
1068 #endif // end of if def shareware
1073 Piggy_fp = copy_pigfile_from_cd(pigname);
1076 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1077 int pig_id,pig_version;
1079 pig_id = cfile_read_int(Piggy_fp);
1080 pig_version = cfile_read_int(Piggy_fp);
1081 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1082 cfclose(Piggy_fp); //out of date pig
1083 Piggy_fp = NULL; //..so pretend it's not here
1089 Error("Cannot open correct version of <%s>", pigname);
1094 N_bitmaps = cfile_read_int(Piggy_fp);
1096 header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
1098 data_start = header_size + cftell(Piggy_fp);
1100 data_size = cfilelength(Piggy_fp) - data_start;
1102 for (i=1; i<=N_bitmaps; i++ ) {
1103 DiskBitmapHeader_read(&bmh, Piggy_fp);
1104 memcpy( temp_name_read, bmh.name, 8 );
1105 temp_name_read[8] = 0;
1107 if ( bmh.dflags & DBM_FLAG_ABM )
1108 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & DBM_NUM_FRAMES );
1110 strcpy( temp_name, temp_name_read );
1112 //Make sure name matches
1113 if (strcmp(temp_name,AllBitmaps[i].name)) {
1114 //Int3(); //this pig is out of date. Delete it
1118 strcpy(AllBitmaps[i].name,temp_name);
1120 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1122 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1123 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1124 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1125 temp_bitmap.avg_color = bmh.avg_color;
1126 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1128 GameBitmapFlags[i] = bmh.flags & BM_FLAGS_TO_COPY;
1130 GameBitmapOffset[i] = bmh.offset + data_start;
1132 GameBitmaps[i] = temp_bitmap;
1136 N_bitmaps = 0; //no pigfile, so no bitmaps
1140 Assert(N_bitmaps == Num_bitmap_files-1);
1144 if (must_rewrite_pig || (N_bitmaps < Num_bitmap_files-1)) {
1147 //re-read the bitmaps that aren't in this pig
1149 for (i=N_bitmaps+1;i<Num_bitmap_files;i++) {
1152 p = strchr(AllBitmaps[i].name,'#');
1154 if (p) { // this is an ABM == animated bitmap
1155 char abmname[FILENAME_LEN];
1157 grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
1158 int iff_error; //reference parm to avoid warning message
1160 char basename[FILENAME_LEN];
1163 strcpy(basename,AllBitmaps[i].name);
1164 basename[p-AllBitmaps[i].name] = 0; //cut off "#nn" part
1166 sprintf( abmname, "%s.abm", basename );
1168 iff_error = iff_read_animbrush(abmname,bm,MAX_BITMAPS_PER_BRUSH,&nframes,newpal);
1170 if (iff_error != IFF_NO_ERROR) {
1171 mprintf((1,"File %s - IFF error: %s",abmname,iff_errormsg(iff_error)));
1172 Error("File %s - IFF error: %s",abmname,iff_errormsg(iff_error));
1175 for (fnum=0;fnum<nframes; fnum++) {
1179 sprintf( tempname, "%s#%d", basename, fnum );
1181 //SuperX = (GameBitmaps[i+fnum].bm_flags&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1182 SuperX = (GameBitmapFlags[i+fnum]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1183 //above makes assumption that supertransparent color is 254
1185 if ( iff_has_transparency )
1186 gr_remap_bitmap_good( bm[fnum], newpal, iff_transparent_color, SuperX );
1188 gr_remap_bitmap_good( bm[fnum], newpal, -1, SuperX );
1190 bm[fnum]->avg_color = compute_average_pixel(bm[fnum]);
1193 if ( FindArg("-macdata") )
1194 swap_0_255( bm[fnum] );
1196 if ( !BigPig ) gr_bitmap_rle_compress( bm[fnum] );
1198 if (bm[fnum]->bm_flags & BM_FLAG_RLE)
1199 size = *((int *) bm[fnum]->bm_data);
1201 size = bm[fnum]->bm_w * bm[fnum]->bm_h;
1203 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],bm[fnum]->bm_data,size);
1204 d_free(bm[fnum]->bm_data);
1205 bm[fnum]->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1206 Piggy_bitmap_cache_next += size;
1208 GameBitmaps[i+fnum] = *bm[fnum];
1210 // -- mprintf( (0, "U" ));
1214 i += nframes-1; //filled in multiple bitmaps
1216 else { //this is a BBM
1219 ubyte newpal[256*3];
1221 char bbmname[FILENAME_LEN];
1224 MALLOC( new, grs_bitmap, 1 );
1226 sprintf( bbmname, "%s.bbm", AllBitmaps[i].name );
1227 iff_error = iff_read_bitmap(bbmname,new,BM_LINEAR,newpal);
1230 if (iff_error != IFF_NO_ERROR) {
1231 mprintf((1, "File %s - IFF error: %s",bbmname,iff_errormsg(iff_error)));
1232 Error("File %s - IFF error: %s",bbmname,iff_errormsg(iff_error));
1235 SuperX = (GameBitmapFlags[i]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1236 //above makes assumption that supertransparent color is 254
1238 if ( iff_has_transparency )
1239 gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
1241 gr_remap_bitmap_good( new, newpal, -1, SuperX );
1243 new->avg_color = compute_average_pixel(new);
1246 if ( FindArg("-macdata") )
1249 if ( !BigPig ) gr_bitmap_rle_compress( new );
1251 if (new->bm_flags & BM_FLAG_RLE)
1252 size = *((int *) new->bm_data);
1254 size = new->bm_w * new->bm_h;
1256 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],new->bm_data,size);
1257 d_free(new->bm_data);
1258 new->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1259 Piggy_bitmap_cache_next += size;
1261 GameBitmaps[i] = *new;
1265 // -- mprintf( (0, "U" ));
1269 //@@Dont' do these things which are done when writing
1270 //@@for (i=0; i < Num_bitmap_files; i++ ) {
1271 //@@ bitmap_index bi;
1273 //@@ PIGGY_PAGE_IN( bi );
1276 //@@piggy_close_file();
1278 piggy_write_pigfile(pigname);
1280 Current_pigfile[0] = 0; //say no pig, to force reload
1282 piggy_new_pigfile(pigname); //read in just-generated pig
1286 #endif //ifdef EDITOR
1290 ubyte bogus_data[64*64];
1291 grs_bitmap bogus_bitmap;
1292 ubyte bogus_bitmap_initialized=0;
1293 digi_sound bogus_sound;
1295 #define HAMFILE_ID MAKE_SIG('!','M','A','H') //HAM!
1296 #define HAMFILE_VERSION 3
1297 //version 1 -> 2: save marker_model_num
1298 //version 2 -> 3: removed sound files
1300 #define SNDFILE_ID MAKE_SIG('D','N','S','D') //DSND
1301 #define SNDFILE_VERSION 1
1305 CFILE * ham_fp = NULL;
1307 int sound_offset = 0;
1313 ham_fp = cfopen( DEFAULT_HAMFILE, "rb" );
1315 sprintf(name, ":Data:%s", DEFAULT_HAMFILE );
1316 ham_fp = cfopen( name, "rb" );
1319 if (ham_fp == NULL) {
1320 Must_write_hamfile = 1;
1324 //make sure ham is valid type file & is up-to-date
1325 ham_id = cfile_read_int(ham_fp);
1326 Piggy_hamfile_version = cfile_read_int(ham_fp);
1327 if (ham_id != HAMFILE_ID)
1328 Error("Cannot open ham file %s\n", DEFAULT_HAMFILE);
1330 if (ham_id != HAMFILE_ID || Piggy_hamfile_version != HAMFILE_VERSION) {
1331 Must_write_hamfile = 1;
1332 cfclose(ham_fp); //out of date ham
1337 if (Piggy_hamfile_version < 3) // hamfile contains sound info
1338 sound_offset = cfile_read_int(ham_fp);
1344 bm_read_all(ham_fp);
1345 cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1347 //for (i = 0; i < MAX_BITMAP_FILES; i++) {
1348 //GameBitmapXlat[i] = INTEL_SHORT(GameBitmapXlat[i]);
1349 //printf("GameBitmapXlat[%d] = %d\n", i, GameBitmapXlat[i]);
1354 if (Piggy_hamfile_version < 3) {
1359 DiskSoundHeader sndh;
1360 digi_sound temp_sound;
1361 char temp_name_read[16];
1364 cfseek(ham_fp, sound_offset, SEEK_SET);
1365 N_sounds = cfile_read_int(ham_fp);
1367 sound_start = cftell(ham_fp);
1369 header_size = N_sounds * DISKSOUNDHEADER_SIZE;
1373 for (i=0; i<N_sounds; i++ ) {
1374 DiskSoundHeader_read(&sndh, ham_fp);
1375 temp_sound.length = sndh.length;
1376 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1377 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1378 memcpy( temp_name_read, sndh.name, 8 );
1379 temp_name_read[8] = 0;
1380 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1382 if (piggy_is_needed(i))
1383 #endif // note link to if.
1384 sbytes += sndh.length;
1385 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1388 SoundBits = d_malloc( sbytes + 16 );
1389 if ( SoundBits == NULL )
1390 Error( "Not enough memory to load sounds\n" );
1392 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1394 // piggy_read_sounds(ham_fp);
1406 CFILE * snd_fp = NULL;
1407 int snd_id,snd_version;
1412 DiskSoundHeader sndh;
1413 digi_sound temp_sound;
1414 char temp_name_read[16];
1421 snd_fp = cfopen( DEFAULT_SNDFILE, "rb" );
1423 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1424 snd_fp = cfopen( name, "rb");
1430 //make sure soundfile is valid type file & is up-to-date
1431 snd_id = cfile_read_int(snd_fp);
1432 snd_version = cfile_read_int(snd_fp);
1433 if (snd_id != SNDFILE_ID || snd_version != SNDFILE_VERSION) {
1434 cfclose(snd_fp); //out of date sound file
1438 N_sounds = cfile_read_int(snd_fp);
1440 sound_start = cftell(snd_fp);
1441 size = cfilelength(snd_fp) - sound_start;
1443 mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
1445 header_size = N_sounds*sizeof(DiskSoundHeader);
1449 for (i=0; i<N_sounds; i++ ) {
1450 DiskSoundHeader_read(&sndh, snd_fp);
1451 //size -= sizeof(DiskSoundHeader);
1452 temp_sound.length = sndh.length;
1453 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1454 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1455 memcpy( temp_name_read, sndh.name, 8 );
1456 temp_name_read[8] = 0;
1457 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1459 if (piggy_is_needed(i))
1460 #endif // note link to if.
1461 sbytes += sndh.length;
1462 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1465 SoundBits = d_malloc( sbytes + 16 );
1466 if ( SoundBits == NULL )
1467 Error( "Not enough memory to load sounds\n" );
1469 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1471 // piggy_read_sounds(snd_fp);
1478 int piggy_init(void)
1480 int ham_ok=0,snd_ok=0;
1483 hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
1484 hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
1486 for (i=0; i<MAX_SOUND_FILES; i++ ) {
1487 GameSounds[i].length = 0;
1488 GameSounds[i].data = NULL;
1492 for (i=0; i<MAX_BITMAP_FILES; i++ )
1493 GameBitmapXlat[i] = i;
1495 if ( !bogus_bitmap_initialized ) {
1498 bogus_bitmap_initialized = 1;
1499 memset( &bogus_bitmap, 0, sizeof(grs_bitmap) );
1500 bogus_bitmap.bm_w = bogus_bitmap.bm_h = bogus_bitmap.bm_rowsize = 64;
1501 bogus_bitmap.bm_data = bogus_data;
1502 c = gr_find_closest_color( 0, 0, 63 );
1503 for (i=0; i<4096; i++ ) bogus_data[i] = c;
1504 c = gr_find_closest_color( 63, 0, 0 );
1505 // Make a big red X !
1506 for (i=0; i<64; i++ ) {
1507 bogus_data[i*64+i] = c;
1508 bogus_data[i*64+(63-i)] = c;
1510 piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
1511 bogus_sound.length = 64*64;
1512 bogus_sound.data = bogus_data;
1513 GameBitmapOffset[0] = 0;
1516 if ( FindArg( "-bigpig" ))
1519 if ( FindArg( "-lowmem" ))
1520 piggy_low_memory = 1;
1522 if ( FindArg( "-nolowmem" ))
1523 piggy_low_memory = 0;
1525 if (piggy_low_memory)
1528 WIN(DDGRLOCK(dd_grd_curcanv));
1529 gr_set_curfont( SMALL_FONT );
1530 gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
1531 gr_printf( 0x8000, grd_curcanv->cv_h-20, "%s...", TXT_LOADING_DATA );
1532 WIN(DDGRUNLOCK(dd_grd_curcanv));
1534 #if 1 //def EDITOR //need for d1 mission briefings
1535 piggy_init_pigfile(DEFAULT_PIGFILE);
1538 snd_ok = ham_ok = read_hamfile();
1540 if (Piggy_hamfile_version >= 3)
1541 snd_ok = read_sndfile();
1543 atexit(piggy_close);
1545 mprintf ((0,"HamOk=%d SndOk=%d\n",ham_ok,snd_ok));
1546 return (ham_ok && snd_ok); //read ok
1549 int piggy_is_needed(int soundnum)
1553 if ( !digi_lomem ) return 1;
1555 for (i=0; i<MAX_SOUNDS; i++ ) {
1556 if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
1563 void piggy_read_sounds(void)
1576 fp = cfopen( DEFAULT_SNDFILE, "rb" );
1578 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1579 fp = cfopen( name, "rb");
1585 for (i=0; i<Num_sound_files; i++ ) {
1586 digi_sound *snd = &GameSounds[i];
1588 if ( SoundOffset[i] > 0 ) {
1589 if ( piggy_is_needed(i) ) {
1590 cfseek( fp, SoundOffset[i], SEEK_SET );
1592 // Read in the sound data!!!
1595 sbytes += snd->length;
1596 cfread( snd->data, snd->length, 1, fp );
1599 snd->data = (ubyte *) -1;
1605 mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
1610 extern int descent_critical_error;
1611 extern unsigned descent_critical_deverror;
1612 extern unsigned descent_critical_errcode;
1614 char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
1615 "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
1616 "Read fault", "General Failure" };
1618 void piggy_critical_error()
1620 grs_canvas * save_canv;
1621 grs_font * save_font;
1623 save_canv = grd_curcanv;
1624 save_font = grd_curcanv->cv_font;
1625 gr_palette_load( gr_palette );
1626 i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A' );
1629 gr_set_current_canvas(save_canv);
1630 grd_curcanv->cv_font = save_font;
1633 void piggy_bitmap_page_in( bitmap_index bitmap )
1642 Assert( i < MAX_BITMAP_FILES );
1643 Assert( i < Num_bitmap_files );
1644 Assert( Piggy_bitmap_cache_size > 0 );
1646 if ( i < 1 ) return;
1647 if ( i >= MAX_BITMAP_FILES ) return;
1648 if ( i >= Num_bitmap_files ) return;
1650 if ( GameBitmapOffset[i] == 0 ) return; // A read-from-disk bitmap!!!
1652 if ( piggy_low_memory ) {
1654 i = GameBitmapXlat[i]; // Xlat for low-memory settings!
1657 bmp = &GameBitmaps[i];
1659 if ( bmp->bm_flags & BM_FLAG_PAGED_OUT ) {
1663 descent_critical_error = 0;
1664 cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
1665 if ( descent_critical_error ) {
1666 piggy_critical_error();
1670 bmp->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1671 bmp->bm_flags = GameBitmapFlags[i];
1673 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1675 descent_critical_error = 0;
1676 zsize = cfile_read_int(Piggy_fp);
1677 if ( descent_critical_error ) {
1678 piggy_critical_error();
1682 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1683 //Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );
1684 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1686 piggy_bitmap_page_out_all();
1689 descent_critical_error = 0;
1690 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next+4], 1, zsize-4, Piggy_fp );
1691 if ( descent_critical_error ) {
1692 piggy_critical_error();
1697 switch (cfilelength(Piggy_fp)) {
1699 if (!FindArg("-macdata"))
1701 // otherwise, fall through...
1702 case MAC_ALIEN1_PIGSIZE:
1703 case MAC_ALIEN2_PIGSIZE:
1704 case MAC_FIRE_PIGSIZE:
1705 case MAC_GROUPA_PIGSIZE:
1706 case MAC_ICE_PIGSIZE:
1707 case MAC_WATER_PIGSIZE:
1708 rle_swap_0_255( bmp );
1709 memcpy(&zsize, bmp->bm_data, 4);
1714 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
1715 Piggy_bitmap_cache_next += zsize;
1716 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1718 piggy_bitmap_page_out_all();
1723 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1724 Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );
1725 if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) {
1726 piggy_bitmap_page_out_all();
1729 descent_critical_error = 0;
1730 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
1731 if ( descent_critical_error ) {
1732 piggy_critical_error();
1735 Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
1738 switch (cfilelength(Piggy_fp)) {
1740 if (!FindArg("-macdata"))
1742 // otherwise, fall through...
1743 case MAC_ALIEN1_PIGSIZE:
1744 case MAC_ALIEN2_PIGSIZE:
1745 case MAC_FIRE_PIGSIZE:
1746 case MAC_GROUPA_PIGSIZE:
1747 case MAC_ICE_PIGSIZE:
1748 case MAC_WATER_PIGSIZE:
1755 //@@if ( bmp->bm_selector ) {
1756 //@@#if !defined(WINDOWS) && !defined(MACINTOSH)
1757 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1758 //@@ Error( "Error modifying selector base in piggy.c\n" );
1765 if ( piggy_low_memory ) {
1767 GameBitmaps[org_i] = GameBitmaps[i];
1770 //@@Removed from John's code:
1772 //@@ if ( bmp->bm_selector ) {
1773 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1774 //@@ Error( "Error modifying selector base in piggy.c\n" );
1780 void piggy_bitmap_page_out_all()
1784 Piggy_bitmap_cache_next = 0;
1786 piggy_page_flushed++;
1791 for (i=0; i<Num_bitmap_files; i++ ) {
1792 if ( GameBitmapOffset[i] > 0 ) { // Don't page out bitmaps read from disk!!!
1793 GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
1794 GameBitmaps[i].bm_data = Piggy_bitmap_cache_data;
1798 mprintf(( 0, "Flushing piggy bitmap cache\n" ));
1801 void piggy_load_level_data()
1803 piggy_bitmap_page_out_all();
1809 void change_filename_ext( char *dest, char *src, char *ext );
1811 void piggy_write_pigfile(char *filename)
1814 int bitmap_data_start, data_offset;
1815 DiskBitmapHeader bmh;
1817 char subst_name[32];
1820 char tname[FILENAME_LEN];
1822 // -- mprintf( (0, "Paging in all piggy bitmaps..." ));
1823 for (i=0; i < Num_bitmap_files; i++ ) {
1826 PIGGY_PAGE_IN( bi );
1828 // -- mprintf( (0, "\n" ));
1832 // -- mprintf( (0, "Creating %s...",filename ));
1834 pig_fp = fopen( filename, "wb" ); //open PIG file
1835 Assert( pig_fp!=NULL );
1837 write_int(PIGFILE_ID,pig_fp);
1838 write_int(PIGFILE_VERSION,pig_fp);
1841 fwrite( &Num_bitmap_files, sizeof(int), 1, pig_fp );
1844 bitmap_data_start = ftell(pig_fp);
1845 bitmap_data_start += (Num_bitmap_files-1)*DISKBITMAPHEADER_SIZE;
1846 data_offset = bitmap_data_start;
1848 change_filename_ext(tname,filename,"lst");
1849 fp1 = fopen( tname, "wt" );
1850 change_filename_ext(tname,filename,"all");
1851 fp2 = fopen( tname, "wt" );
1853 for (i=1; i < Num_bitmap_files; i++ ) {
1859 p = strchr(AllBitmaps[i].name, '#');
1860 if (p) { // this is an ABM == animated bitmap
1866 fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
1867 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1868 Assert( n <= DBM_NUM_FRAMES );
1869 bmh.dflags = DBM_FLAG_ABM + n;
1873 fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
1874 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1878 bmp = &GameBitmaps[i];
1880 Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
1883 fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
1884 org_offset = ftell(pig_fp);
1885 bmh.offset = data_offset - bitmap_data_start;
1886 fseek( pig_fp, data_offset, SEEK_SET );
1888 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1889 size = (int *)bmp->bm_data;
1890 fwrite( bmp->bm_data, sizeof(ubyte), *size, pig_fp );
1891 data_offset += *size;
1893 fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
1895 fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, pig_fp );
1896 data_offset += bmp->bm_rowsize * bmp->bm_h;
1898 fprintf( fp1, ".\n" );
1900 fseek( pig_fp, org_offset, SEEK_SET );
1901 Assert( GameBitmaps[i].bm_w < 4096 );
1902 bmh.width = (GameBitmaps[i].bm_w & 0xff);
1903 bmh.wh_extra = ((GameBitmaps[i].bm_w >> 8) & 0x0f);
1904 Assert( GameBitmaps[i].bm_h < 4096 );
1905 bmh.height = GameBitmaps[i].bm_h;
1906 bmh.wh_extra |= ((GameBitmaps[i].bm_h >> 4) & 0xf0);
1907 bmh.flags = GameBitmaps[i].bm_flags;
1908 if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name )) {
1909 bitmap_index other_bitmap;
1910 other_bitmap = piggy_find_bitmap( subst_name );
1911 GameBitmapXlat[i] = other_bitmap.index;
1912 bmh.flags |= BM_FLAG_PAGED_OUT;
1913 //mprintf(( 0, "Skipping bitmap %d\n", i ));
1914 //mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
1916 bmh.flags &= ~BM_FLAG_PAGED_OUT;
1918 bmh.avg_color=GameBitmaps[i].avg_color;
1919 fwrite( &bmh, DISKBITMAPHEADER_SIZE, 1, pig_fp ); // Mark as a bitmap
1924 mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
1925 fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
1932 static void write_int(int i,FILE *file)
1934 if (fwrite( &i, sizeof(i), 1, file) != 1)
1935 Error( "Error reading int in gamesave.c" );
1939 void piggy_dump_all()
1943 int org_offset,data_offset=0;
1944 DiskSoundHeader sndh;
1945 int sound_data_start=0;
1948 #ifdef NO_DUMP_SOUNDS
1949 Num_sound_files = 0;
1950 Num_sound_files_new = 0;
1953 if (!Must_write_hamfile && (Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
1956 fp1 = fopen( "ham.lst", "wt" );
1957 fp2 = fopen( "ham.all", "wt" );
1959 if (Must_write_hamfile || Num_bitmap_files_new) {
1961 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1963 ham_fp = fopen( DEFAULT_HAMFILE, "wb" ); //open HAM file
1964 Assert( ham_fp!=NULL );
1966 write_int(HAMFILE_ID,ham_fp);
1967 write_int(HAMFILE_VERSION,ham_fp);
1969 bm_write_all(ham_fp);
1970 xlat_offset = ftell(ham_fp);
1971 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1974 if (Num_bitmap_files_new)
1975 piggy_write_pigfile(DEFAULT_PIGFILE);
1977 //free up memeory used by new bitmaps
1978 for (i=Num_bitmap_files-Num_bitmap_files_new;i<Num_bitmap_files;i++)
1979 d_free(GameBitmaps[i].bm_data);
1981 //next thing must be done after pig written
1982 fseek( ham_fp, xlat_offset, SEEK_SET );
1983 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1986 mprintf( (0, "\n" ));
1989 if (Num_sound_files_new) {
1991 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1992 // Now dump sound file
1993 ham_fp = fopen( DEFAULT_SNDFILE, "wb" );
1994 Assert( ham_fp!=NULL );
1996 write_int(SNDFILE_ID,ham_fp);
1997 write_int(SNDFILE_VERSION,ham_fp);
1999 fwrite( &Num_sound_files, sizeof(int), 1, ham_fp );
2001 mprintf( (0, "\nDumping sounds..." ));
2003 sound_data_start = ftell(ham_fp);
2004 sound_data_start += Num_sound_files*sizeof(DiskSoundHeader);
2005 data_offset = sound_data_start;
2007 for (i=0; i < Num_sound_files; i++ ) {
2010 snd = &GameSounds[i];
2011 strcpy( sndh.name, AllSounds[i].name );
2012 sndh.length = GameSounds[i].length;
2013 sndh.offset = data_offset - sound_data_start;
2015 org_offset = ftell(ham_fp);
2016 fseek( ham_fp, data_offset, SEEK_SET );
2018 sndh.data_length = GameSounds[i].length;
2019 fwrite( snd->data, sizeof(ubyte), snd->length, ham_fp );
2020 data_offset += snd->length;
2021 fseek( ham_fp, org_offset, SEEK_SET );
2022 fwrite( &sndh, sizeof(DiskSoundHeader), 1, ham_fp ); // Mark as a bitmap
2024 fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
2025 fprintf( fp2, "%s.raw\n", AllSounds[i].name );
2029 mprintf( (0, "\n" ));
2032 fprintf( fp1, "Total sound size: %d bytes\n", data_offset-sound_data_start);
2033 mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
2034 fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
2039 // Never allow the game to run after building ham.
2053 d_free( SoundBits );
2055 hashtable_free( &AllBitmapsNames );
2056 hashtable_free( &AllDigiSndNames );
2060 int piggy_does_bitmap_exist_slow( char * name )
2064 for (i=0; i<Num_bitmap_files; i++ ) {
2065 if ( !strcmp( AllBitmaps[i].name, name) )
2072 #define NUM_GAUGE_BITMAPS 23
2073 char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = {
2074 "gauge01", "gauge01b",
2075 "gauge02", "gauge02b",
2076 "gauge06", "gauge06b",
2077 "targ01", "targ01b",
2078 "targ02", "targ02b",
2079 "targ03", "targ03b",
2080 "targ04", "targ04b",
2081 "targ05", "targ05b",
2082 "targ06", "targ06b",
2083 "gauge18", "gauge18b",
2089 int piggy_is_gauge_bitmap( char * base_name )
2092 for (i=0; i<NUM_GAUGE_BITMAPS; i++ ) {
2093 if ( !stricmp( base_name, gauge_bitmap_names[i] ))
2100 int piggy_is_substitutable_bitmap( char * name, char * subst_name )
2104 char base_name[ 16 ];
2106 strcpy( subst_name, name );
2107 p = strchr( subst_name, '#' );
2109 frame = atoi( &p[1] );
2111 strcpy( base_name, subst_name );
2112 if ( !piggy_is_gauge_bitmap( base_name )) {
2113 sprintf( subst_name, "%s#%d", base_name, frame+1 );
2114 if ( piggy_does_bitmap_exist_slow( subst_name ) ) {
2116 sprintf( subst_name, "%s#%d", base_name, frame-1 );
2122 strcpy( subst_name, name );
2129 // New Windows stuff
2131 // windows bitmap page in
2132 // Page in a bitmap, if ddraw, then page it into a ddsurface in
2133 // 'video' memory. if that fails, page it in normally.
2135 void piggy_bitmap_page_in_w( bitmap_index bitmap, int ddraw )
2140 // Essential when switching video modes!
2142 void piggy_bitmap_page_out_all_w()
2150 * Functions for loading replacement textures
2151 * 1) From .pog files
2152 * 2) From descent.pig (for loading d1 levels)
2155 extern void change_filename_extension( char *dest, char *src, char *new_ext );
2156 extern char last_palette_loaded_pig[];
2158 void free_bitmap_replacements()
2160 if (Bitmap_replacement_data) {
2161 d_free(Bitmap_replacement_data);
2162 Bitmap_replacement_data = NULL;
2166 void load_bitmap_replacements(char *level_name)
2168 char ifile_name[FILENAME_LEN];
2172 //first, free up data allocated for old bitmaps
2173 free_bitmap_replacements();
2175 change_filename_extension(ifile_name, level_name, ".POG" );
2177 ifile = cfopen(ifile_name,"rb");
2180 int id,version,n_bitmaps;
2181 int bitmap_data_size;
2184 id = cfile_read_int(ifile);
2185 version = cfile_read_int(ifile);
2187 if (id != MAKE_SIG('G','O','P','D') || version != 1) {
2192 n_bitmaps = cfile_read_int(ifile);
2194 MALLOC( indices, ushort, n_bitmaps );
2196 for (i = 0; i < n_bitmaps; i++)
2197 indices[i] = cfile_read_short(ifile);
2199 bitmap_data_size = cfilelength(ifile) - cftell(ifile) - DISKBITMAPHEADER_SIZE * n_bitmaps;
2200 MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
2202 for (i=0;i<n_bitmaps;i++) {
2203 DiskBitmapHeader bmh;
2204 grs_bitmap temp_bitmap;
2206 DiskBitmapHeader_read(&bmh, ifile);
2208 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2210 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2211 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2212 temp_bitmap.avg_color = bmh.avg_color;
2213 temp_bitmap.bm_data = Bitmap_replacement_data + bmh.offset;
2215 temp_bitmap.bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2217 GameBitmaps[indices[i]] = temp_bitmap;
2218 // don't we need the following? GameBitmapOffset[indices[i]] = 0; // don't try to read bitmap from current pigfile
2221 cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
2227 last_palette_loaded_pig[0]= 0; //force pig re-load
2229 texmerge_flush(); //for re-merging with new textures
2232 atexit(free_bitmap_replacements);
2235 /* calculate table to translate d1 bitmaps to current palette,
2236 * return -1 on error
2238 int get_d1_colormap( ubyte *d1_palette, ubyte *colormap )
2241 CFILE * palette_file = cfopen(D1_PALETTE, "rb");
2242 if (!palette_file || cfilelength(palette_file) != 9472)
2244 cfread( d1_palette, 256, 3, palette_file);
2245 cfclose( palette_file );
2246 build_colormap_good( d1_palette, colormap, freq );
2247 // don't change transparencies:
2248 colormap[254] = 254;
2249 colormap[255] = 255;
2253 void bitmap_read_d1( grs_bitmap *bitmap, /* read into this bitmap */
2254 CFILE *d1_Piggy_fp, /* read from this file */
2255 int bitmap_data_start, /* specific to file */
2256 DiskBitmapHeader *bmh, /* header info for bitmap */
2257 ubyte *(*get_mem)(int), /* function to find out where to store data */
2258 ubyte *d1_palette, /* what palette the bitmap has */
2259 ubyte *colormap) /* how to translate bitmap's colors */
2262 memset( bitmap, 0, sizeof(grs_bitmap) );
2264 bitmap->bm_w = bitmap->bm_rowsize = bmh->width + ((short) (bmh->wh_extra&0x0f)<<8);
2265 bitmap->bm_h = bmh->height + ((short) (bmh->wh_extra&0xf0)<<4);
2266 bitmap->avg_color = bmh->avg_color;
2267 bitmap->bm_flags |= bmh->flags & BM_FLAGS_TO_COPY;
2269 cfseek(d1_Piggy_fp, bitmap_data_start + bmh->offset, SEEK_SET);
2270 if (bmh->flags & BM_FLAG_RLE) {
2271 zsize = cfile_read_int(d1_Piggy_fp);
2272 cfseek(d1_Piggy_fp, -4, SEEK_CUR);
2274 zsize = bitmap->bm_h * bitmap->bm_w;
2276 bitmap->bm_data = (*get_mem)(zsize);
2277 cfread(bitmap->bm_data, 1, zsize, d1_Piggy_fp);
2278 switch(cfilelength(d1_Piggy_fp)) {
2279 case D1_MAC_PIGSIZE:
2280 case D1_MAC_SHARE_PIGSIZE:
2281 if (bmh->flags & BM_FLAG_RLE)
2282 rle_swap_0_255(bitmap);
2286 if (bmh->flags & BM_FLAG_RLE)
2287 rle_remap(bitmap, colormap);
2289 gr_remap_bitmap_good(bitmap, d1_palette, TRANSPARENCY_COLOR, -1);
2290 if (bmh->flags & BM_FLAG_RLE)
2291 if (memcmp(&zsize, bitmap->bm_data, 4))
2292 Warning("Swapping and remapping changed the size of this bitmap. Too bad!");
2295 #define D1_MAX_TEXTURES 800
2296 #define D1_MAX_TMAP_NUM 1600 // 1555 in descent.pig PC registered
2298 /* the inverse of the Textures array, for descent 1.
2299 * "Textures" looks up a d2 bitmap index given a d2 tmap_num
2300 * "d1_tmap_nums" looks up a d1 tmap_num given a d1 bitmap. "-1" means "None"
2302 short *d1_tmap_nums = NULL;
2304 void free_d1_tmap_nums() {
2306 d_free(d1_tmap_nums);
2307 d1_tmap_nums = NULL;
2311 void bm_read_d1_tmap_nums(CFILE *d1pig)
2315 free_d1_tmap_nums();
2316 cfseek(d1pig, 8, SEEK_SET);
2317 MALLOC(d1_tmap_nums, short, D1_MAX_TMAP_NUM);
2318 for (i = 0; i < D1_MAX_TMAP_NUM; i++)
2319 d1_tmap_nums[i] = -1;
2320 for (i = 0; i < D1_MAX_TEXTURES; i++) {
2321 d1_index = cfile_read_short(d1pig);
2322 Assert(d1_index >= 0 && d1_index < D1_MAX_TMAP_NUM);
2323 d1_tmap_nums[d1_index] = i;
2325 atexit(free_d1_tmap_nums);
2328 /* If the given d1_index is the index of a bitmap we have to load
2329 * (because it is unique to descent 1), then returns the d2_index that
2330 * the given d1_index replaces.
2331 * Returns -1 if the given d1_index is not unique to descent 1.
2333 short d2_index_for_d1_index(short d1_index)
2335 Assert(d1_index >= 0 && d1_index < D1_MAX_TMAP_NUM);
2336 if (! d1_tmap_nums || d1_tmap_nums[d1_index] == -1
2337 || ! d1_tmap_num_unique(d1_tmap_nums[d1_index]))
2340 return Textures[convert_d1_tmap_num(d1_tmap_nums[d1_index])].index;
2343 #define D1_BITMAPS_SIZE 300000
2345 static ubyte *next_bitmap; // to which address we write the next bitmap in load_d1_bitmap_replacements
2346 static ubyte *get_next_bitmap(int zsize)
2348 ubyte *this_bitmap = next_bitmap;
2349 next_bitmap += zsize;
2350 Assert(next_bitmap - Bitmap_replacement_data < D1_BITMAPS_SIZE);
2353 static ubyte *my_d_malloc(int zsize)
2355 return d_malloc(zsize);
2358 void load_d1_bitmap_replacements()
2360 CFILE * d1_Piggy_fp;
2361 DiskBitmapHeader bmh;
2362 int pig_data_start, bitmap_header_start, bitmap_data_start;
2364 short d1_index, d2_index;
2365 ubyte colormap[256];
2366 ubyte d1_palette[256*3];
2369 d1_Piggy_fp = cfopen( D1_PIGFILE, "rb" );
2371 #define D1_PIG_LOAD_FAILED "Failed loading " D1_PIGFILE
2373 Warning(D1_PIG_LOAD_FAILED);
2377 //first, free up data allocated for old bitmaps
2378 free_bitmap_replacements();
2380 Assert( get_d1_colormap( d1_palette, colormap ) == 0 );
2382 switch (cfilelength(d1_Piggy_fp)) {
2383 case D1_SHAREWARE_10_PIGSIZE:
2384 case D1_SHAREWARE_BIG_PIGSIZE:
2385 case D1_SHAREWARE_PIGSIZE:
2386 case D1_10_BIG_PIGSIZE:
2389 Warning(D1_PIG_LOAD_FAILED ". descent.pig of v1.0 and all PC shareware versions not supported.");
2393 Warning("Unknown size for " D1_PIGFILE);
2397 case D1_OEM_PIGSIZE:
2398 case D1_MAC_PIGSIZE:
2399 case D1_MAC_SHARE_PIGSIZE:
2400 pig_data_start = cfile_read_int(d1_Piggy_fp );
2401 bm_read_d1_tmap_nums(d1_Piggy_fp); //was: bm_read_all_d1(fp);
2402 //for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2406 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2407 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2409 int N_sounds = cfile_read_int(d1_Piggy_fp);
2410 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2411 + N_sounds * DISKSOUNDHEADER_SIZE;
2412 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2413 bitmap_data_start = bitmap_header_start + header_size;
2416 MALLOC( Bitmap_replacement_data, ubyte, D1_BITMAPS_SIZE);
2417 if (!Bitmap_replacement_data) {
2418 Warning(D1_PIG_LOAD_FAILED);
2421 atexit(free_bitmap_replacements);
2423 next_bitmap = Bitmap_replacement_data;
2425 for (d1_index = 1; d1_index <= N_bitmaps; d1_index++ ) {
2426 d2_index = d2_index_for_d1_index(d1_index);
2427 // only change bitmaps which are unique to d1
2428 if (d2_index != -1) {
2429 cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2430 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2432 bitmap_read_d1( &GameBitmaps[d2_index], d1_Piggy_fp, bitmap_data_start, &bmh, &get_next_bitmap, d1_palette, colormap );
2433 GameBitmapOffset[d2_index] = 0; // don't try to read bitmap from current d2 pigfile
2434 GameBitmapFlags[d2_index] = bmh.flags;
2436 if ( (p = strchr(AllBitmaps[d2_index].name, '#')) /* d2 BM is animated */
2437 && !(bmh.dflags & DBM_FLAG_ABM) ) { /* d1 bitmap is not animated */
2438 int i, len = p - AllBitmaps[d2_index].name;
2439 for (i = 0; i < Num_bitmap_files; i++)
2440 if (i != d2_index && ! memcmp(AllBitmaps[d2_index].name, AllBitmaps[i].name, len)) {
2441 GameBitmaps[i] = GameBitmaps[d2_index];
2442 GameBitmapOffset[i] = 0;
2443 GameBitmapFlags[i] = bmh.flags;
2449 cfclose(d1_Piggy_fp);
2451 last_palette_loaded_pig[0]= 0; //force pig re-load
2453 texmerge_flush(); //for re-merging with new textures
2457 extern int extra_bitmap_num;
2460 * Find and load the named bitmap from descent.pig
2461 * similar to read_extra_bitmap_iff
2463 bitmap_index read_extra_bitmap_d1_pig(char *name)
2465 bitmap_index bitmap_num;
2466 grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2468 bitmap_num.index = 0;
2472 DiskBitmapHeader bmh;
2473 int pig_data_start, bitmap_header_start, bitmap_data_start;
2475 ubyte colormap[256];
2476 ubyte d1_palette[256*3];
2478 d1_Piggy_fp = cfopen(D1_PIGFILE, "rb");
2482 Warning(D1_PIG_LOAD_FAILED);
2486 Assert( get_d1_colormap( d1_palette, colormap ) == 0 );
2488 switch (cfilelength(d1_Piggy_fp)) {
2489 case D1_SHAREWARE_10_PIGSIZE:
2490 case D1_SHAREWARE_BIG_PIGSIZE:
2491 case D1_SHAREWARE_PIGSIZE:
2492 case D1_10_BIG_PIGSIZE:
2497 Warning("Unknown size for " D1_PIGFILE);
2501 case D1_OEM_PIGSIZE:
2502 case D1_MAC_PIGSIZE:
2503 case D1_MAC_SHARE_PIGSIZE:
2504 pig_data_start = cfile_read_int(d1_Piggy_fp );
2509 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2510 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2512 int N_sounds = cfile_read_int(d1_Piggy_fp);
2513 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2514 + N_sounds * DISKSOUNDHEADER_SIZE;
2515 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2516 bitmap_data_start = bitmap_header_start + header_size;
2519 for (i = 1; i <= N_bitmaps; i++)
2521 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2522 if (!strnicmp(bmh.name, name, 8))
2526 if (strnicmp(bmh.name, name, 8))
2528 con_printf(CON_DEBUG, "could not find bitmap %s\n", name);
2532 bitmap_read_d1( new, d1_Piggy_fp, bitmap_data_start, &bmh, &my_d_malloc, d1_palette, colormap );
2534 cfclose(d1_Piggy_fp);
2537 new->avg_color = 0; //compute_average_pixel(new);
2539 bitmap_num.index = extra_bitmap_num;
2541 GameBitmaps[extra_bitmap_num++] = *new;
2547 #ifndef FAST_FILE_IO
2549 * reads a bitmap_index structure from a CFILE
2551 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2553 bi->index = cfile_read_short(fp);
2557 * reads n bitmap_index structs from a CFILE
2559 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2563 for (i = 0; i < n; i++)
2564 bi[i].index = cfile_read_short(fp);
2569 * reads a DiskBitmapHeader structure from a CFILE
2571 void DiskBitmapHeader_read(DiskBitmapHeader *dbh, CFILE *fp)
2573 cfread(dbh->name, 8, 1, fp);
2574 dbh->dflags = cfile_read_byte(fp);
2575 dbh->width = cfile_read_byte(fp);
2576 dbh->height = cfile_read_byte(fp);
2577 dbh->wh_extra = cfile_read_byte(fp);
2578 dbh->flags = cfile_read_byte(fp);
2579 dbh->avg_color = cfile_read_byte(fp);
2580 dbh->offset = cfile_read_int(fp);
2584 * reads a DiskSoundHeader structure from a CFILE
2586 void DiskSoundHeader_read(DiskSoundHeader *dsh, CFILE *fp)
2588 cfread(dsh->name, 8, 1, fp);
2589 dsh->length = cfile_read_int(fp);
2590 dsh->data_length = cfile_read_int(fp);
2591 dsh->offset = cfile_read_int(fp);
2593 #endif // FAST_FILE_IO
2596 * reads a descent 1 DiskBitmapHeader structure from a CFILE
2598 void DiskBitmapHeader_d1_read(DiskBitmapHeader *dbh, CFILE *fp)
2600 cfread(dbh->name, 8, 1, fp);
2601 dbh->dflags = cfile_read_byte(fp);
2602 dbh->width = cfile_read_byte(fp);
2603 dbh->height = cfile_read_byte(fp);
2605 dbh->flags = cfile_read_byte(fp);
2606 dbh->avg_color = cfile_read_byte(fp);
2607 dbh->offset = cfile_read_int(fp);