1 /* $Id: piggy.c,v 1.47 2003-11-04 21:33:30 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.47 2003-11-04 21:33:30 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)
519 typedef struct DiskBitmapHeader {
521 ubyte dflags; // bits 0-5 anim frame num, bit 6 abm flag
522 ubyte width; // low 8 bits here, 4 more bits in wh_extra
523 ubyte height; // low 8 bits here, 4 more bits in wh_extra
524 ubyte wh_extra; // bits 0-3 width, bits 4-7 height
528 } __pack__ DiskBitmapHeader;
530 #define DISKBITMAPHEADER_D1_SIZE 17 // no wh_extra
532 typedef struct DiskSoundHeader {
537 } __pack__ DiskSoundHeader;
540 #define DiskBitmapHeader_read(dbh, fp) cfread(dbh, sizeof(DiskBitmapHeader), 1, fp)
541 #define DiskSoundHeader_read(dsh, fp) cfread(dsh, sizeof(DiskSoundHeader), 1, fp)
544 * reads a DiskBitmapHeader structure from a CFILE
546 void DiskBitmapHeader_read(DiskBitmapHeader *dbh, CFILE *fp)
548 cfread(dbh->name, 8, 1, fp);
549 dbh->dflags = cfile_read_byte(fp);
550 dbh->width = cfile_read_byte(fp);
551 dbh->height = cfile_read_byte(fp);
552 dbh->wh_extra = cfile_read_byte(fp);
553 dbh->flags = cfile_read_byte(fp);
554 dbh->avg_color = cfile_read_byte(fp);
555 dbh->offset = cfile_read_int(fp);
559 * reads a DiskSoundHeader structure from a CFILE
561 void DiskSoundHeader_read(DiskSoundHeader *dsh, CFILE *fp)
563 cfread(dsh->name, 8, 1, fp);
564 dsh->length = cfile_read_int(fp);
565 dsh->data_length = cfile_read_int(fp);
566 dsh->offset = cfile_read_int(fp);
568 #endif // FAST_FILE_IO
571 * reads a descent 1 DiskBitmapHeader structure from a CFILE
573 void DiskBitmapHeader_d1_read(DiskBitmapHeader *dbh, CFILE *fp)
575 cfread(dbh->name, 8, 1, fp);
576 dbh->dflags = cfile_read_byte(fp);
577 dbh->width = cfile_read_byte(fp);
578 dbh->height = cfile_read_byte(fp);
580 dbh->flags = cfile_read_byte(fp);
581 dbh->avg_color = cfile_read_byte(fp);
582 dbh->offset = cfile_read_int(fp);
588 extern short cd_VRefNum;
589 extern void ConcatPStr(StringPtr dst, StringPtr src);
590 extern int ConvertPToCStr(StringPtr inPStr, char* outCStrBuf);
591 extern int ConvertCToPStr(char* inCStr, StringPtr outPStrBuf);
594 int piggy_is_substitutable_bitmap( char * name, char * subst_name );
597 void piggy_write_pigfile(char *filename);
598 static void write_int(int i,FILE *file);
601 void swap_0_255(grs_bitmap *bmp)
605 for (i = 0; i < bmp->bm_h * bmp->bm_w; i++) {
606 if(bmp->bm_data[i] == 0)
607 bmp->bm_data[i] = 255;
608 else if (bmp->bm_data[i] == 255)
613 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
616 Assert( Num_bitmap_files < MAX_BITMAP_FILES );
618 temp.index = Num_bitmap_files;
622 if ( FindArg("-macdata") )
625 if ( !BigPig ) gr_bitmap_rle_compress( bmp );
626 Num_bitmap_files_new++;
629 strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
630 hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
631 GameBitmaps[Num_bitmap_files] = *bmp;
633 GameBitmapOffset[Num_bitmap_files] = 0;
634 GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
641 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
645 Assert( Num_sound_files < MAX_SOUND_FILES );
647 strncpy( AllSounds[Num_sound_files].name, name, 12 );
648 hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
649 GameSounds[Num_sound_files] = *snd;
651 SoundOffset[Num_sound_files] = 0;
657 Num_sound_files_new++;
663 bitmap_index piggy_find_bitmap( char * name )
671 if ((t=strchr(name,'#'))!=NULL)
674 for (i=0;i<Num_aliases;i++)
675 if (stricmp(name,alias_list[i].alias_name)==0) {
676 if (t) { //extra stuff for ABMs
677 static char temp[FILENAME_LEN];
678 _splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
684 name=alias_list[i].file_name;
691 i = hashtable_search( &AllBitmapsNames, name );
700 int piggy_find_sound( char * name )
704 i = hashtable_search( &AllDigiSndNames, name );
712 CFILE * Piggy_fp = NULL;
714 #define FILENAME_LEN 13
716 char Current_pigfile[FILENAME_LEN] = "";
718 void piggy_close_file()
723 Current_pigfile[0] = 0;
727 int Pigfile_initialized=0;
729 #define PIGFILE_ID MAKE_SIG('G','I','P','P') //PPIG
730 #define PIGFILE_VERSION 2
732 extern char CDROM_dir[];
734 int request_cd(void);
739 //copies a pigfile from the CD to the current dir
740 //retuns file handle of new pig
741 CFILE *copy_pigfile_from_cd(char *filename) // MACINTOSH VERSION
744 char sourcePathAndFileCStr[255] = "";
745 char destPathAndFileCStr[255] = "";
747 FILE* sourceFile = NULL;
748 FILE* destFile = NULL;
749 const int BUF_SIZE = 4096;
753 Str255 sourcePathAndFilePStr = "\p";
754 Str255 destPathAndFilePStr = "\p";
755 Str255 pigfileNamePStr = "\p";
756 HParamBlockRec theSourcePigHFSParams;
757 HParamBlockRec theDestPigHFSParams;
758 OSErr theErr = noErr;
759 char oldDirCStr[255] = "";
761 getcwd(oldDirCStr, 255);
763 show_boxed_message("Copying bitmap data from CD...");
764 gr_palette_load(gr_palette); //I don't think this line is really needed
767 //First, delete all PIG files currently in the directory
768 if( !FileFindFirst( "*.pig", &find ) )
773 } while( !FileFindNext( &find ) );
779 //Now, copy over new pig
780 songs_stop_redbook(); //so we can read off the cd
782 // make the source path "<cd volume>:Data:filename.pig"
783 //MWA ConvertCToPStr(filename, pigfileNamePStr);
785 //MWA ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:"); // volume ID is cd_VRefNum
786 //MWA ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
789 strcpy(sourcePathAndFileCStr, "Descent II:Data:");
790 strcat(sourcePathAndFileCStr, filename);
792 // make the destination path "<default directory>:Data:filename.pig"
793 //MWA ConcatPStr(destPathAndFilePStr, "\p:Data:");
794 //MWA ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
795 //MWA ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
796 //MWA ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
798 strcpy(destPathAndFileCStr, ":Data:");
799 strcat(destPathAndFileCStr, filename);
801 strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
802 strcpy(destPathAndFilePStr, destPathAndFileCStr);
803 c2pstr(sourcePathAndFilePStr);
804 c2pstr(destPathAndFilePStr);
807 // Open the source file
808 sourceFile = fopen(sourcePathAndFileCStr,"rb");
812 if (request_cd() == -1)
813 Error("Cannot load file <%s> from CD",filename);
816 } while (!sourceFile);
819 // Get the time stamp from the source file
820 theSourcePigHFSParams.fileParam.ioCompletion = nil;
821 theSourcePigHFSParams.fileParam.ioNamePtr = sourcePathAndFilePStr;
822 theSourcePigHFSParams.fileParam.ioVRefNum = cd_VRefNum;
823 theSourcePigHFSParams.fileParam.ioFDirIndex = 0;
824 theSourcePigHFSParams.fileParam.ioDirID = 0;
826 theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
829 // Error getting file time stamp!! Why? JTS
830 Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
833 // Copy the file over
836 // Open the destination file
837 destFile = fopen(destPathAndFileCStr,"wb");
840 Error("Cannot create file: <%s>\n", destPathAndFileCStr);
843 // Copy bytes until the end of the source file
844 while (!feof(sourceFile))
849 bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
850 if (ferror(sourceFile))
851 Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
853 // Assert is bogus Assert(bytes_read == BUF_SIZE || feof(sourceFile));
855 fwrite(buf,1,bytes_read,destFile);
856 if (ferror(destFile))
857 Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
860 // close the source/dest files
861 if (fclose(sourceFile))
862 Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
863 if (fclose(destFile))
864 Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
866 // Get the current hfs data for the new file
867 theDestPigHFSParams.fileParam.ioCompletion = nil;
868 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
869 theDestPigHFSParams.fileParam.ioVRefNum = 0;
870 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
871 theDestPigHFSParams.fileParam.ioDirID = 0;
872 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
873 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
875 // Error getting file time stamp!! Why? JTS
876 Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
879 // Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
880 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
881 theDestPigHFSParams.fileParam.ioVRefNum = 0;
882 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
883 theDestPigHFSParams.fileParam.ioDirID = 0;
885 // Copy the time stamp from the source file info
886 theDestPigHFSParams.fileParam.ioFlCrDat = theSourcePigHFSParams.fileParam.ioFlCrDat;
887 theDestPigHFSParams.fileParam.ioFlMdDat = theSourcePigHFSParams.fileParam.ioFlMdDat;
888 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
889 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
891 // Set the dest file's time stamp to the source file's time stamp values
892 theErr = PBHSetFInfo(&theDestPigHFSParams, false);
894 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
896 Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
899 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
901 return cfopen(destPathAndFileCStr, "rb");
904 #else //PC Version of copy_pigfile_from_cd is below
906 //copies a pigfile from the CD to the current dir
907 //retuns file handle of new pig
908 CFILE *copy_pigfile_from_cd(char *filename)
914 return cfopen(filename, "rb");
915 show_boxed_message("Copying bitmap data from CD...");
916 gr_palette_load(gr_palette); //I don't think this line is really needed
918 //First, delete all PIG files currently in the directory
920 if( !FileFindFirst( "*.pig", &find ) ) {
922 cfile_delete(find.name);
923 } while( !FileFindNext( &find ) );
927 //Now, copy over new pig
929 songs_stop_redbook(); //so we can read off the cd
931 //new code to unarj file
932 strcpy(name,CDROM_dir);
933 strcat(name,"descent2.sow");
936 // ret = unarj_specific_file(name,filename,filename);
941 if (ret != EXIT_SUCCESS) {
943 //delete file, so we don't leave partial file
944 cfile_delete(filename);
947 if (request_cd() == -1)
949 //NOTE LINK TO ABOVE IF
950 Error("Cannot load file <%s> from CD",filename);
953 } while (ret != EXIT_SUCCESS);
955 return cfopen(filename, "rb");
958 #endif // end of ifdef MAC around copy_pigfile_from_cd
960 //initialize a pigfile, reading headers
961 //returns the size of all the bitmap data
962 void piggy_init_pigfile(char *filename)
966 char temp_name_read[16];
967 grs_bitmap temp_bitmap;
968 DiskBitmapHeader bmh;
969 int header_size, N_bitmaps, data_size, data_start;
971 char name[255]; // filename + path for the mac
974 piggy_close_file(); //close old pig if still open
976 //rename pigfile for shareware
977 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
978 filename = DEFAULT_PIGFILE_SHAREWARE;
981 Piggy_fp = cfopen( filename, "rb" );
983 sprintf(name, ":Data:%s", filename);
984 Piggy_fp = cfopen( name, "rb" );
986 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
987 if (Piggy_fp == NULL)
989 Error("Cannot load required file <%s>",name);
991 #endif // end of if def shareware
997 return; //if editor, ok to not have pig, because we'll build one
999 Piggy_fp = copy_pigfile_from_cd(filename);
1003 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1004 int pig_id,pig_version;
1006 pig_id = cfile_read_int(Piggy_fp);
1007 pig_version = cfile_read_int(Piggy_fp);
1008 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1009 cfclose(Piggy_fp); //out of date pig
1010 Piggy_fp = NULL; //..so pretend it's not here
1017 return; //if editor, ok to not have pig, because we'll build one
1019 Error("Cannot load required file <%s>",filename);
1023 strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
1025 N_bitmaps = cfile_read_int(Piggy_fp);
1027 header_size = N_bitmaps * sizeof(DiskBitmapHeader);
1029 data_start = header_size + cftell(Piggy_fp);
1031 data_size = cfilelength(Piggy_fp) - data_start;
1033 Num_bitmap_files = 1;
1035 for (i=0; i<N_bitmaps; i++ ) {
1036 DiskBitmapHeader_read(&bmh, Piggy_fp);
1037 memcpy( temp_name_read, bmh.name, 8 );
1038 temp_name_read[8] = 0;
1039 if ( bmh.dflags & DBM_FLAG_ABM )
1040 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & DBM_NUM_FRAMES );
1042 strcpy( temp_name, temp_name_read );
1043 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1044 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1045 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1046 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1047 temp_bitmap.avg_color = bmh.avg_color;
1048 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1050 GameBitmapFlags[i+1] = bmh.flags & BM_FLAGS_TO_COPY;
1052 GameBitmapOffset[i+1] = bmh.offset + data_start;
1053 Assert( (i+1) == Num_bitmap_files );
1054 piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
1058 Piggy_bitmap_cache_size = data_size + (data_size/10); //extra mem for new bitmaps
1059 Assert( Piggy_bitmap_cache_size > 0 );
1061 Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
1063 if (piggy_low_memory)
1064 Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
1067 BitmapBits = d_malloc( Piggy_bitmap_cache_size );
1068 if ( BitmapBits == NULL )
1069 Error( "Not enough memory to load bitmaps\n" );
1070 Piggy_bitmap_cache_data = BitmapBits;
1071 Piggy_bitmap_cache_next = 0;
1073 #if defined(MACINTOSH) && defined(SHAREWARE)
1074 // load_exit_models();
1077 Pigfile_initialized=1;
1080 #define FILENAME_LEN 13
1081 #define MAX_BITMAPS_PER_BRUSH 30
1083 extern int compute_average_pixel(grs_bitmap *new);
1085 ubyte *Bitmap_replacement_data = NULL;
1087 //reads in a new pigfile (for new palette)
1088 //returns the size of all the bitmap data
1089 void piggy_new_pigfile(char *pigname)
1093 char temp_name_read[16];
1094 grs_bitmap temp_bitmap;
1095 DiskBitmapHeader bmh;
1096 int header_size, N_bitmaps, data_size, data_start;
1097 int must_rewrite_pig = 0;
1104 //rename pigfile for shareware
1105 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
1106 pigname = DEFAULT_PIGFILE_SHAREWARE;
1108 if (strnicmp(Current_pigfile, pigname, sizeof(Current_pigfile)) == 0 // correct pig already loaded
1109 && !Bitmap_replacement_data) // no need to reload: no bitmaps were altered
1112 if (!Pigfile_initialized) { //have we ever opened a pigfile?
1113 piggy_init_pigfile(pigname); //..no, so do initialization stuff
1117 piggy_close_file(); //close old pig if still open
1119 Piggy_bitmap_cache_next = 0; //free up cache
1121 strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
1124 Piggy_fp = cfopen( pigname, "rb" );
1126 sprintf(name, ":Data:%s", pigname);
1127 Piggy_fp = cfopen( name, "rb" );
1129 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
1130 if (Piggy_fp == NULL)
1132 Error("Cannot load required file <%s>",name);
1134 #endif // end of if def shareware
1139 Piggy_fp = copy_pigfile_from_cd(pigname);
1142 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1143 int pig_id,pig_version;
1145 pig_id = cfile_read_int(Piggy_fp);
1146 pig_version = cfile_read_int(Piggy_fp);
1147 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1148 cfclose(Piggy_fp); //out of date pig
1149 Piggy_fp = NULL; //..so pretend it's not here
1155 Error("Cannot open correct version of <%s>", pigname);
1160 N_bitmaps = cfile_read_int(Piggy_fp);
1162 header_size = N_bitmaps * sizeof(DiskBitmapHeader);
1164 data_start = header_size + cftell(Piggy_fp);
1166 data_size = cfilelength(Piggy_fp) - data_start;
1168 for (i=1; i<=N_bitmaps; i++ ) {
1169 DiskBitmapHeader_read(&bmh, Piggy_fp);
1170 memcpy( temp_name_read, bmh.name, 8 );
1171 temp_name_read[8] = 0;
1173 if ( bmh.dflags & DBM_FLAG_ABM )
1174 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & DBM_NUM_FRAMES );
1176 strcpy( temp_name, temp_name_read );
1178 //Make sure name matches
1179 if (strcmp(temp_name,AllBitmaps[i].name)) {
1180 //Int3(); //this pig is out of date. Delete it
1184 strcpy(AllBitmaps[i].name,temp_name);
1186 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1188 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1189 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1190 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1191 temp_bitmap.avg_color = bmh.avg_color;
1192 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1194 GameBitmapFlags[i] = bmh.flags & BM_FLAGS_TO_COPY;
1196 GameBitmapOffset[i] = bmh.offset + data_start;
1198 GameBitmaps[i] = temp_bitmap;
1202 N_bitmaps = 0; //no pigfile, so no bitmaps
1206 Assert(N_bitmaps == Num_bitmap_files-1);
1210 if (must_rewrite_pig || (N_bitmaps < Num_bitmap_files-1)) {
1213 //re-read the bitmaps that aren't in this pig
1215 for (i=N_bitmaps+1;i<Num_bitmap_files;i++) {
1218 p = strchr(AllBitmaps[i].name,'#');
1220 if (p) { // this is an ABM == animated bitmap
1221 char abmname[FILENAME_LEN];
1223 grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
1224 int iff_error; //reference parm to avoid warning message
1226 char basename[FILENAME_LEN];
1229 strcpy(basename,AllBitmaps[i].name);
1230 basename[p-AllBitmaps[i].name] = 0; //cut off "#nn" part
1232 sprintf( abmname, "%s.abm", basename );
1234 iff_error = iff_read_animbrush(abmname,bm,MAX_BITMAPS_PER_BRUSH,&nframes,newpal);
1236 if (iff_error != IFF_NO_ERROR) {
1237 mprintf((1,"File %s - IFF error: %s",abmname,iff_errormsg(iff_error)));
1238 Error("File %s - IFF error: %s",abmname,iff_errormsg(iff_error));
1241 for (fnum=0;fnum<nframes; fnum++) {
1245 sprintf( tempname, "%s#%d", basename, fnum );
1247 //SuperX = (GameBitmaps[i+fnum].bm_flags&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1248 SuperX = (GameBitmapFlags[i+fnum]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1249 //above makes assumption that supertransparent color is 254
1251 if ( iff_has_transparency )
1252 gr_remap_bitmap_good( bm[fnum], newpal, iff_transparent_color, SuperX );
1254 gr_remap_bitmap_good( bm[fnum], newpal, -1, SuperX );
1256 bm[fnum]->avg_color = compute_average_pixel(bm[fnum]);
1259 if ( FindArg("-macdata") )
1260 swap_0_255( bm[fnum] );
1262 if ( !BigPig ) gr_bitmap_rle_compress( bm[fnum] );
1264 if (bm[fnum]->bm_flags & BM_FLAG_RLE)
1265 size = *((int *) bm[fnum]->bm_data);
1267 size = bm[fnum]->bm_w * bm[fnum]->bm_h;
1269 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],bm[fnum]->bm_data,size);
1270 d_free(bm[fnum]->bm_data);
1271 bm[fnum]->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1272 Piggy_bitmap_cache_next += size;
1274 GameBitmaps[i+fnum] = *bm[fnum];
1276 // -- mprintf( (0, "U" ));
1280 i += nframes-1; //filled in multiple bitmaps
1282 else { //this is a BBM
1285 ubyte newpal[256*3];
1287 char bbmname[FILENAME_LEN];
1290 MALLOC( new, grs_bitmap, 1 );
1292 sprintf( bbmname, "%s.bbm", AllBitmaps[i].name );
1293 iff_error = iff_read_bitmap(bbmname,new,BM_LINEAR,newpal);
1296 if (iff_error != IFF_NO_ERROR) {
1297 mprintf((1, "File %s - IFF error: %s",bbmname,iff_errormsg(iff_error)));
1298 Error("File %s - IFF error: %s",bbmname,iff_errormsg(iff_error));
1301 SuperX = (GameBitmapFlags[i]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1302 //above makes assumption that supertransparent color is 254
1304 if ( iff_has_transparency )
1305 gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
1307 gr_remap_bitmap_good( new, newpal, -1, SuperX );
1309 new->avg_color = compute_average_pixel(new);
1312 if ( FindArg("-macdata") )
1315 if ( !BigPig ) gr_bitmap_rle_compress( new );
1317 if (new->bm_flags & BM_FLAG_RLE)
1318 size = *((int *) new->bm_data);
1320 size = new->bm_w * new->bm_h;
1322 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],new->bm_data,size);
1323 d_free(new->bm_data);
1324 new->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1325 Piggy_bitmap_cache_next += size;
1327 GameBitmaps[i] = *new;
1331 // -- mprintf( (0, "U" ));
1335 //@@Dont' do these things which are done when writing
1336 //@@for (i=0; i < Num_bitmap_files; i++ ) {
1337 //@@ bitmap_index bi;
1339 //@@ PIGGY_PAGE_IN( bi );
1342 //@@piggy_close_file();
1344 piggy_write_pigfile(pigname);
1346 Current_pigfile[0] = 0; //say no pig, to force reload
1348 piggy_new_pigfile(pigname); //read in just-generated pig
1352 #endif //ifdef EDITOR
1356 ubyte bogus_data[64*64];
1357 grs_bitmap bogus_bitmap;
1358 ubyte bogus_bitmap_initialized=0;
1359 digi_sound bogus_sound;
1361 #define HAMFILE_ID MAKE_SIG('!','M','A','H') //HAM!
1362 #define HAMFILE_VERSION 3
1363 //version 1 -> 2: save marker_model_num
1364 //version 2 -> 3: removed sound files
1366 #define SNDFILE_ID MAKE_SIG('D','N','S','D') //DSND
1367 #define SNDFILE_VERSION 1
1371 CFILE * ham_fp = NULL;
1373 int sound_offset = 0;
1379 ham_fp = cfopen( DEFAULT_HAMFILE, "rb" );
1381 sprintf(name, ":Data:%s", DEFAULT_HAMFILE );
1382 ham_fp = cfopen( name, "rb" );
1385 if (ham_fp == NULL) {
1386 Must_write_hamfile = 1;
1390 //make sure ham is valid type file & is up-to-date
1391 ham_id = cfile_read_int(ham_fp);
1392 Piggy_hamfile_version = cfile_read_int(ham_fp);
1393 if (ham_id != HAMFILE_ID)
1394 Error("Cannot open ham file %s\n", DEFAULT_HAMFILE);
1396 if (ham_id != HAMFILE_ID || Piggy_hamfile_version != HAMFILE_VERSION) {
1397 Must_write_hamfile = 1;
1398 cfclose(ham_fp); //out of date ham
1403 if (Piggy_hamfile_version < 3) // hamfile contains sound info
1404 sound_offset = cfile_read_int(ham_fp);
1410 bm_read_all(ham_fp);
1411 cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1413 //for (i = 0; i < MAX_BITMAP_FILES; i++) {
1414 //GameBitmapXlat[i] = INTEL_SHORT(GameBitmapXlat[i]);
1415 //printf("GameBitmapXlat[%d] = %d\n", i, GameBitmapXlat[i]);
1420 if (Piggy_hamfile_version < 3) {
1425 DiskSoundHeader sndh;
1426 digi_sound temp_sound;
1427 char temp_name_read[16];
1430 cfseek(ham_fp, sound_offset, SEEK_SET);
1431 N_sounds = cfile_read_int(ham_fp);
1433 sound_start = cftell(ham_fp);
1435 header_size = N_sounds * sizeof(DiskSoundHeader);
1439 for (i=0; i<N_sounds; i++ ) {
1440 DiskSoundHeader_read(&sndh, ham_fp);
1441 temp_sound.length = sndh.length;
1442 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1443 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1444 memcpy( temp_name_read, sndh.name, 8 );
1445 temp_name_read[8] = 0;
1446 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1448 if (piggy_is_needed(i))
1449 #endif // note link to if.
1450 sbytes += sndh.length;
1451 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1454 SoundBits = d_malloc( sbytes + 16 );
1455 if ( SoundBits == NULL )
1456 Error( "Not enough memory to load sounds\n" );
1458 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1460 // piggy_read_sounds(ham_fp);
1472 CFILE * snd_fp = NULL;
1473 int snd_id,snd_version;
1478 DiskSoundHeader sndh;
1479 digi_sound temp_sound;
1480 char temp_name_read[16];
1487 snd_fp = cfopen( DEFAULT_SNDFILE, "rb" );
1489 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1490 snd_fp = cfopen( name, "rb");
1496 //make sure soundfile is valid type file & is up-to-date
1497 snd_id = cfile_read_int(snd_fp);
1498 snd_version = cfile_read_int(snd_fp);
1499 if (snd_id != SNDFILE_ID || snd_version != SNDFILE_VERSION) {
1500 cfclose(snd_fp); //out of date sound file
1504 N_sounds = cfile_read_int(snd_fp);
1506 sound_start = cftell(snd_fp);
1507 size = cfilelength(snd_fp) - sound_start;
1509 mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
1511 header_size = N_sounds*sizeof(DiskSoundHeader);
1515 for (i=0; i<N_sounds; i++ ) {
1516 DiskSoundHeader_read(&sndh, snd_fp);
1517 //size -= sizeof(DiskSoundHeader);
1518 temp_sound.length = sndh.length;
1519 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1520 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1521 memcpy( temp_name_read, sndh.name, 8 );
1522 temp_name_read[8] = 0;
1523 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1525 if (piggy_is_needed(i))
1526 #endif // note link to if.
1527 sbytes += sndh.length;
1528 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1531 SoundBits = d_malloc( sbytes + 16 );
1532 if ( SoundBits == NULL )
1533 Error( "Not enough memory to load sounds\n" );
1535 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1537 // piggy_read_sounds(snd_fp);
1544 int piggy_init(void)
1546 int ham_ok=0,snd_ok=0;
1549 hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
1550 hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
1552 for (i=0; i<MAX_SOUND_FILES; i++ ) {
1553 GameSounds[i].length = 0;
1554 GameSounds[i].data = NULL;
1558 for (i=0; i<MAX_BITMAP_FILES; i++ )
1559 GameBitmapXlat[i] = i;
1561 if ( !bogus_bitmap_initialized ) {
1564 bogus_bitmap_initialized = 1;
1565 memset( &bogus_bitmap, 0, sizeof(grs_bitmap) );
1566 bogus_bitmap.bm_w = bogus_bitmap.bm_h = bogus_bitmap.bm_rowsize = 64;
1567 bogus_bitmap.bm_data = bogus_data;
1568 c = gr_find_closest_color( 0, 0, 63 );
1569 for (i=0; i<4096; i++ ) bogus_data[i] = c;
1570 c = gr_find_closest_color( 63, 0, 0 );
1571 // Make a big red X !
1572 for (i=0; i<64; i++ ) {
1573 bogus_data[i*64+i] = c;
1574 bogus_data[i*64+(63-i)] = c;
1576 piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
1577 bogus_sound.length = 64*64;
1578 bogus_sound.data = bogus_data;
1579 GameBitmapOffset[0] = 0;
1582 if ( FindArg( "-bigpig" ))
1585 if ( FindArg( "-lowmem" ))
1586 piggy_low_memory = 1;
1588 if ( FindArg( "-nolowmem" ))
1589 piggy_low_memory = 0;
1591 if (piggy_low_memory)
1594 WIN(DDGRLOCK(dd_grd_curcanv));
1595 gr_set_curfont( SMALL_FONT );
1596 gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
1597 gr_printf( 0x8000, grd_curcanv->cv_h-20, "%s...", TXT_LOADING_DATA );
1598 WIN(DDGRUNLOCK(dd_grd_curcanv));
1600 #if 1 //def EDITOR //need for d1 mission briefings
1601 piggy_init_pigfile(DEFAULT_PIGFILE);
1604 snd_ok = ham_ok = read_hamfile();
1606 if (Piggy_hamfile_version >= 3)
1607 snd_ok = read_sndfile();
1609 atexit(piggy_close);
1611 mprintf ((0,"HamOk=%d SndOk=%d\n",ham_ok,snd_ok));
1612 return (ham_ok && snd_ok); //read ok
1615 int piggy_is_needed(int soundnum)
1619 if ( !digi_lomem ) return 1;
1621 for (i=0; i<MAX_SOUNDS; i++ ) {
1622 if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
1629 void piggy_read_sounds(void)
1642 fp = cfopen( DEFAULT_SNDFILE, "rb" );
1644 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1645 fp = cfopen( name, "rb");
1651 for (i=0; i<Num_sound_files; i++ ) {
1652 digi_sound *snd = &GameSounds[i];
1654 if ( SoundOffset[i] > 0 ) {
1655 if ( piggy_is_needed(i) ) {
1656 cfseek( fp, SoundOffset[i], SEEK_SET );
1658 // Read in the sound data!!!
1661 sbytes += snd->length;
1662 cfread( snd->data, snd->length, 1, fp );
1665 snd->data = (ubyte *) -1;
1671 mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
1676 extern int descent_critical_error;
1677 extern unsigned descent_critical_deverror;
1678 extern unsigned descent_critical_errcode;
1680 char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
1681 "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
1682 "Read fault", "General Failure" };
1684 void piggy_critical_error()
1686 grs_canvas * save_canv;
1687 grs_font * save_font;
1689 save_canv = grd_curcanv;
1690 save_font = grd_curcanv->cv_font;
1691 gr_palette_load( gr_palette );
1692 i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A' );
1695 gr_set_current_canvas(save_canv);
1696 grd_curcanv->cv_font = save_font;
1699 void piggy_bitmap_page_in( bitmap_index bitmap )
1708 Assert( i < MAX_BITMAP_FILES );
1709 Assert( i < Num_bitmap_files );
1710 Assert( Piggy_bitmap_cache_size > 0 );
1712 if ( i < 1 ) return;
1713 if ( i >= MAX_BITMAP_FILES ) return;
1714 if ( i >= Num_bitmap_files ) return;
1716 if ( GameBitmapOffset[i] == 0 ) return; // A read-from-disk bitmap!!!
1718 if ( piggy_low_memory ) {
1720 i = GameBitmapXlat[i]; // Xlat for low-memory settings!
1723 bmp = &GameBitmaps[i];
1725 if ( bmp->bm_flags & BM_FLAG_PAGED_OUT ) {
1729 descent_critical_error = 0;
1730 cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
1731 if ( descent_critical_error ) {
1732 piggy_critical_error();
1736 bmp->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1737 bmp->bm_flags = GameBitmapFlags[i];
1739 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1741 descent_critical_error = 0;
1742 zsize = cfile_read_int(Piggy_fp);
1743 if ( descent_critical_error ) {
1744 piggy_critical_error();
1748 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1749 //Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );
1750 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1752 piggy_bitmap_page_out_all();
1755 descent_critical_error = 0;
1756 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next+4], 1, zsize-4, Piggy_fp );
1757 if ( descent_critical_error ) {
1758 piggy_critical_error();
1763 switch (cfilelength(Piggy_fp)) {
1765 if (!FindArg("-macdata"))
1767 // otherwise, fall through...
1768 case MAC_ALIEN1_PIGSIZE:
1769 case MAC_ALIEN2_PIGSIZE:
1770 case MAC_FIRE_PIGSIZE:
1771 case MAC_GROUPA_PIGSIZE:
1772 case MAC_ICE_PIGSIZE:
1773 case MAC_WATER_PIGSIZE:
1774 rle_swap_0_255( bmp );
1775 memcpy(&zsize, bmp->bm_data, 4);
1780 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
1781 Piggy_bitmap_cache_next += zsize;
1782 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1784 piggy_bitmap_page_out_all();
1789 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1790 Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );
1791 if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) {
1792 piggy_bitmap_page_out_all();
1795 descent_critical_error = 0;
1796 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
1797 if ( descent_critical_error ) {
1798 piggy_critical_error();
1801 Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
1804 switch (cfilelength(Piggy_fp)) {
1806 if (!FindArg("-macdata"))
1808 // otherwise, fall through...
1809 case MAC_ALIEN1_PIGSIZE:
1810 case MAC_ALIEN2_PIGSIZE:
1811 case MAC_FIRE_PIGSIZE:
1812 case MAC_GROUPA_PIGSIZE:
1813 case MAC_ICE_PIGSIZE:
1814 case MAC_WATER_PIGSIZE:
1821 //@@if ( bmp->bm_selector ) {
1822 //@@#if !defined(WINDOWS) && !defined(MACINTOSH)
1823 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1824 //@@ Error( "Error modifying selector base in piggy.c\n" );
1831 if ( piggy_low_memory ) {
1833 GameBitmaps[org_i] = GameBitmaps[i];
1836 //@@Removed from John's code:
1838 //@@ if ( bmp->bm_selector ) {
1839 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1840 //@@ Error( "Error modifying selector base in piggy.c\n" );
1846 void piggy_bitmap_page_out_all()
1850 Piggy_bitmap_cache_next = 0;
1852 piggy_page_flushed++;
1857 for (i=0; i<Num_bitmap_files; i++ ) {
1858 if ( GameBitmapOffset[i] > 0 ) { // Don't page out bitmaps read from disk!!!
1859 GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
1860 GameBitmaps[i].bm_data = Piggy_bitmap_cache_data;
1864 mprintf(( 0, "Flushing piggy bitmap cache\n" ));
1867 void piggy_load_level_data()
1869 piggy_bitmap_page_out_all();
1875 void change_filename_ext( char *dest, char *src, char *ext );
1877 void piggy_write_pigfile(char *filename)
1880 int bitmap_data_start, data_offset;
1881 DiskBitmapHeader bmh;
1883 char subst_name[32];
1886 char tname[FILENAME_LEN];
1888 // -- mprintf( (0, "Paging in all piggy bitmaps..." ));
1889 for (i=0; i < Num_bitmap_files; i++ ) {
1892 PIGGY_PAGE_IN( bi );
1894 // -- mprintf( (0, "\n" ));
1898 // -- mprintf( (0, "Creating %s...",filename ));
1900 pig_fp = fopen( filename, "wb" ); //open PIG file
1901 Assert( pig_fp!=NULL );
1903 write_int(PIGFILE_ID,pig_fp);
1904 write_int(PIGFILE_VERSION,pig_fp);
1907 fwrite( &Num_bitmap_files, sizeof(int), 1, pig_fp );
1910 bitmap_data_start = ftell(pig_fp);
1911 bitmap_data_start += (Num_bitmap_files - 1) * sizeof(DiskBitmapHeader);
1912 data_offset = bitmap_data_start;
1914 change_filename_ext(tname,filename,"lst");
1915 fp1 = fopen( tname, "wt" );
1916 change_filename_ext(tname,filename,"all");
1917 fp2 = fopen( tname, "wt" );
1919 for (i=1; i < Num_bitmap_files; i++ ) {
1925 p = strchr(AllBitmaps[i].name, '#');
1926 if (p) { // this is an ABM == animated bitmap
1932 fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
1933 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1934 Assert( n <= DBM_NUM_FRAMES );
1935 bmh.dflags = DBM_FLAG_ABM + n;
1939 fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
1940 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1944 bmp = &GameBitmaps[i];
1946 Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
1949 fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
1950 org_offset = ftell(pig_fp);
1951 bmh.offset = data_offset - bitmap_data_start;
1952 fseek( pig_fp, data_offset, SEEK_SET );
1954 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1955 size = (int *)bmp->bm_data;
1956 fwrite( bmp->bm_data, sizeof(ubyte), *size, pig_fp );
1957 data_offset += *size;
1959 fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
1961 fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, pig_fp );
1962 data_offset += bmp->bm_rowsize * bmp->bm_h;
1964 fprintf( fp1, ".\n" );
1966 fseek( pig_fp, org_offset, SEEK_SET );
1967 Assert( GameBitmaps[i].bm_w < 4096 );
1968 bmh.width = (GameBitmaps[i].bm_w & 0xff);
1969 bmh.wh_extra = ((GameBitmaps[i].bm_w >> 8) & 0x0f);
1970 Assert( GameBitmaps[i].bm_h < 4096 );
1971 bmh.height = GameBitmaps[i].bm_h;
1972 bmh.wh_extra |= ((GameBitmaps[i].bm_h >> 4) & 0xf0);
1973 bmh.flags = GameBitmaps[i].bm_flags;
1974 if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name )) {
1975 bitmap_index other_bitmap;
1976 other_bitmap = piggy_find_bitmap( subst_name );
1977 GameBitmapXlat[i] = other_bitmap.index;
1978 bmh.flags |= BM_FLAG_PAGED_OUT;
1979 //mprintf(( 0, "Skipping bitmap %d\n", i ));
1980 //mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
1982 bmh.flags &= ~BM_FLAG_PAGED_OUT;
1984 bmh.avg_color=GameBitmaps[i].avg_color;
1985 fwrite(&bmh, sizeof(DiskBitmapHeader), 1, pig_fp); // Mark as a bitmap
1990 mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
1991 fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
1998 static void write_int(int i,FILE *file)
2000 if (fwrite( &i, sizeof(i), 1, file) != 1)
2001 Error( "Error reading int in gamesave.c" );
2005 void piggy_dump_all()
2009 int org_offset,data_offset=0;
2010 DiskSoundHeader sndh;
2011 int sound_data_start=0;
2014 #ifdef NO_DUMP_SOUNDS
2015 Num_sound_files = 0;
2016 Num_sound_files_new = 0;
2019 if (!Must_write_hamfile && (Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
2022 fp1 = fopen( "ham.lst", "wt" );
2023 fp2 = fopen( "ham.all", "wt" );
2025 if (Must_write_hamfile || Num_bitmap_files_new) {
2027 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
2029 ham_fp = fopen( DEFAULT_HAMFILE, "wb" ); //open HAM file
2030 Assert( ham_fp!=NULL );
2032 write_int(HAMFILE_ID,ham_fp);
2033 write_int(HAMFILE_VERSION,ham_fp);
2035 bm_write_all(ham_fp);
2036 xlat_offset = ftell(ham_fp);
2037 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
2040 if (Num_bitmap_files_new)
2041 piggy_write_pigfile(DEFAULT_PIGFILE);
2043 //free up memeory used by new bitmaps
2044 for (i=Num_bitmap_files-Num_bitmap_files_new;i<Num_bitmap_files;i++)
2045 d_free(GameBitmaps[i].bm_data);
2047 //next thing must be done after pig written
2048 fseek( ham_fp, xlat_offset, SEEK_SET );
2049 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
2052 mprintf( (0, "\n" ));
2055 if (Num_sound_files_new) {
2057 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
2058 // Now dump sound file
2059 ham_fp = fopen( DEFAULT_SNDFILE, "wb" );
2060 Assert( ham_fp!=NULL );
2062 write_int(SNDFILE_ID,ham_fp);
2063 write_int(SNDFILE_VERSION,ham_fp);
2065 fwrite( &Num_sound_files, sizeof(int), 1, ham_fp );
2067 mprintf( (0, "\nDumping sounds..." ));
2069 sound_data_start = ftell(ham_fp);
2070 sound_data_start += Num_sound_files*sizeof(DiskSoundHeader);
2071 data_offset = sound_data_start;
2073 for (i=0; i < Num_sound_files; i++ ) {
2076 snd = &GameSounds[i];
2077 strcpy( sndh.name, AllSounds[i].name );
2078 sndh.length = GameSounds[i].length;
2079 sndh.offset = data_offset - sound_data_start;
2081 org_offset = ftell(ham_fp);
2082 fseek( ham_fp, data_offset, SEEK_SET );
2084 sndh.data_length = GameSounds[i].length;
2085 fwrite( snd->data, sizeof(ubyte), snd->length, ham_fp );
2086 data_offset += snd->length;
2087 fseek( ham_fp, org_offset, SEEK_SET );
2088 fwrite( &sndh, sizeof(DiskSoundHeader), 1, ham_fp ); // Mark as a bitmap
2090 fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
2091 fprintf( fp2, "%s.raw\n", AllSounds[i].name );
2095 mprintf( (0, "\n" ));
2098 fprintf( fp1, "Total sound size: %d bytes\n", data_offset-sound_data_start);
2099 mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
2100 fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
2105 // Never allow the game to run after building ham.
2119 d_free( SoundBits );
2121 hashtable_free( &AllBitmapsNames );
2122 hashtable_free( &AllDigiSndNames );
2126 int piggy_does_bitmap_exist_slow( char * name )
2130 for (i=0; i<Num_bitmap_files; i++ ) {
2131 if ( !strcmp( AllBitmaps[i].name, name) )
2138 #define NUM_GAUGE_BITMAPS 23
2139 char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = {
2140 "gauge01", "gauge01b",
2141 "gauge02", "gauge02b",
2142 "gauge06", "gauge06b",
2143 "targ01", "targ01b",
2144 "targ02", "targ02b",
2145 "targ03", "targ03b",
2146 "targ04", "targ04b",
2147 "targ05", "targ05b",
2148 "targ06", "targ06b",
2149 "gauge18", "gauge18b",
2155 int piggy_is_gauge_bitmap( char * base_name )
2158 for (i=0; i<NUM_GAUGE_BITMAPS; i++ ) {
2159 if ( !stricmp( base_name, gauge_bitmap_names[i] ))
2166 int piggy_is_substitutable_bitmap( char * name, char * subst_name )
2170 char base_name[ 16 ];
2172 strcpy( subst_name, name );
2173 p = strchr( subst_name, '#' );
2175 frame = atoi( &p[1] );
2177 strcpy( base_name, subst_name );
2178 if ( !piggy_is_gauge_bitmap( base_name )) {
2179 sprintf( subst_name, "%s#%d", base_name, frame+1 );
2180 if ( piggy_does_bitmap_exist_slow( subst_name ) ) {
2182 sprintf( subst_name, "%s#%d", base_name, frame-1 );
2188 strcpy( subst_name, name );
2195 // New Windows stuff
2197 // windows bitmap page in
2198 // Page in a bitmap, if ddraw, then page it into a ddsurface in
2199 // 'video' memory. if that fails, page it in normally.
2201 void piggy_bitmap_page_in_w( bitmap_index bitmap, int ddraw )
2206 // Essential when switching video modes!
2208 void piggy_bitmap_page_out_all_w()
2216 * Functions for loading replacement textures
2217 * 1) From .pog files
2218 * 2) From descent.pig (for loading d1 levels)
2221 extern void change_filename_extension( char *dest, char *src, char *new_ext );
2222 extern char last_palette_loaded_pig[];
2224 void free_bitmap_replacements()
2226 if (Bitmap_replacement_data) {
2227 d_free(Bitmap_replacement_data);
2228 Bitmap_replacement_data = NULL;
2232 void load_bitmap_replacements(char *level_name)
2234 char ifile_name[FILENAME_LEN];
2238 //first, free up data allocated for old bitmaps
2239 free_bitmap_replacements();
2241 change_filename_extension(ifile_name, level_name, ".POG" );
2243 ifile = cfopen(ifile_name,"rb");
2246 int id,version,n_bitmaps;
2247 int bitmap_data_size;
2250 id = cfile_read_int(ifile);
2251 version = cfile_read_int(ifile);
2253 if (id != MAKE_SIG('G','O','P','D') || version != 1) {
2258 n_bitmaps = cfile_read_int(ifile);
2260 MALLOC( indices, ushort, n_bitmaps );
2262 for (i = 0; i < n_bitmaps; i++)
2263 indices[i] = cfile_read_short(ifile);
2265 bitmap_data_size = cfilelength(ifile) - cftell(ifile) - sizeof(DiskBitmapHeader) * n_bitmaps;
2266 MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
2268 for (i=0;i<n_bitmaps;i++) {
2269 DiskBitmapHeader bmh;
2270 grs_bitmap temp_bitmap;
2272 DiskBitmapHeader_read(&bmh, ifile);
2274 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2276 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2277 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2278 temp_bitmap.avg_color = bmh.avg_color;
2279 temp_bitmap.bm_data = Bitmap_replacement_data + bmh.offset;
2281 temp_bitmap.bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2283 GameBitmaps[indices[i]] = temp_bitmap;
2284 // don't we need the following? GameBitmapOffset[indices[i]] = 0; // don't try to read bitmap from current pigfile
2287 cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
2293 last_palette_loaded_pig[0]= 0; //force pig re-load
2295 texmerge_flush(); //for re-merging with new textures
2298 atexit(free_bitmap_replacements);
2301 /* calculate table to translate d1 bitmaps to current palette,
2302 * return -1 on error
2304 int get_d1_colormap( ubyte *d1_palette, ubyte *colormap )
2307 CFILE * palette_file = cfopen(D1_PALETTE, "rb");
2308 if (!palette_file || cfilelength(palette_file) != 9472)
2310 cfread( d1_palette, 256, 3, palette_file);
2311 cfclose( palette_file );
2312 build_colormap_good( d1_palette, colormap, freq );
2313 // don't change transparencies:
2314 colormap[254] = 254;
2315 colormap[255] = 255;
2319 void bitmap_read_d1( grs_bitmap *bitmap, /* read into this bitmap */
2320 CFILE *d1_Piggy_fp, /* read from this file */
2321 int bitmap_data_start, /* specific to file */
2322 DiskBitmapHeader *bmh, /* header info for bitmap */
2323 ubyte *(*get_mem)(int), /* function to find out where to store data */
2324 ubyte *d1_palette, /* what palette the bitmap has */
2325 ubyte *colormap) /* how to translate bitmap's colors */
2328 memset( bitmap, 0, sizeof(grs_bitmap) );
2330 bitmap->bm_w = bitmap->bm_rowsize = bmh->width + ((short) (bmh->wh_extra&0x0f)<<8);
2331 bitmap->bm_h = bmh->height + ((short) (bmh->wh_extra&0xf0)<<4);
2332 bitmap->avg_color = bmh->avg_color;
2333 bitmap->bm_flags |= bmh->flags & BM_FLAGS_TO_COPY;
2335 cfseek(d1_Piggy_fp, bitmap_data_start + bmh->offset, SEEK_SET);
2336 if (bmh->flags & BM_FLAG_RLE) {
2337 zsize = cfile_read_int(d1_Piggy_fp);
2338 cfseek(d1_Piggy_fp, -4, SEEK_CUR);
2340 zsize = bitmap->bm_h * bitmap->bm_w;
2342 bitmap->bm_data = (*get_mem)(zsize);
2343 cfread(bitmap->bm_data, 1, zsize, d1_Piggy_fp);
2344 switch(cfilelength(d1_Piggy_fp)) {
2345 case D1_MAC_PIGSIZE:
2346 case D1_MAC_SHARE_PIGSIZE:
2347 if (bmh->flags & BM_FLAG_RLE)
2348 rle_swap_0_255(bitmap);
2352 if (bmh->flags & BM_FLAG_RLE)
2353 rle_remap(bitmap, colormap);
2355 gr_remap_bitmap_good(bitmap, d1_palette, TRANSPARENCY_COLOR, -1);
2356 if (bmh->flags & BM_FLAG_RLE)
2357 if (memcmp(&zsize, bitmap->bm_data, 4))
2358 Warning("Swapping and remapping changed the size of this bitmap. Too bad!");
2361 #define D1_MAX_TEXTURES 800
2362 #define D1_MAX_TMAP_NUM 1600 // 1555 in descent.pig PC registered
2364 /* the inverse of the Textures array, for descent 1.
2365 * "Textures" looks up a d2 bitmap index given a d2 tmap_num
2366 * "d1_tmap_nums" looks up a d1 tmap_num given a d1 bitmap. "-1" means "None"
2368 short *d1_tmap_nums = NULL;
2370 void free_d1_tmap_nums() {
2372 d_free(d1_tmap_nums);
2373 d1_tmap_nums = NULL;
2377 void bm_read_d1_tmap_nums(CFILE *d1pig)
2381 free_d1_tmap_nums();
2382 cfseek(d1pig, 8, SEEK_SET);
2383 MALLOC(d1_tmap_nums, short, D1_MAX_TMAP_NUM);
2384 for (i = 0; i < D1_MAX_TMAP_NUM; i++)
2385 d1_tmap_nums[i] = -1;
2386 for (i = 0; i < D1_MAX_TEXTURES; i++) {
2387 d1_index = cfile_read_short(d1pig);
2388 Assert(d1_index >= 0 && d1_index < D1_MAX_TMAP_NUM);
2389 d1_tmap_nums[d1_index] = i;
2391 atexit(free_d1_tmap_nums);
2394 /* If the given d1_index is the index of a bitmap we have to load
2395 * (because it is unique to descent 1), then returns the d2_index that
2396 * the given d1_index replaces.
2397 * Returns -1 if the given d1_index is not unique to descent 1.
2399 short d2_index_for_d1_index(short d1_index)
2401 Assert(d1_index >= 0 && d1_index < D1_MAX_TMAP_NUM);
2402 if (! d1_tmap_nums || d1_tmap_nums[d1_index] == -1
2403 || ! d1_tmap_num_unique(d1_tmap_nums[d1_index]))
2406 return Textures[convert_d1_tmap_num(d1_tmap_nums[d1_index])].index;
2409 #define D1_BITMAPS_SIZE 300000
2411 static ubyte *next_bitmap; // to which address we write the next bitmap in load_d1_bitmap_replacements
2412 static ubyte *get_next_bitmap(int zsize)
2414 ubyte *this_bitmap = next_bitmap;
2415 next_bitmap += zsize;
2416 Assert(next_bitmap - Bitmap_replacement_data < D1_BITMAPS_SIZE);
2419 static ubyte *my_d_malloc(int zsize)
2421 return d_malloc(zsize);
2424 void load_d1_bitmap_replacements()
2426 CFILE * d1_Piggy_fp;
2427 DiskBitmapHeader bmh;
2428 int pig_data_start, bitmap_header_start, bitmap_data_start;
2430 short d1_index, d2_index;
2431 ubyte colormap[256];
2432 ubyte d1_palette[256*3];
2435 d1_Piggy_fp = cfopen( D1_PIGFILE, "rb" );
2437 #define D1_PIG_LOAD_FAILED "Failed loading " D1_PIGFILE
2439 Warning(D1_PIG_LOAD_FAILED);
2443 //first, free up data allocated for old bitmaps
2444 free_bitmap_replacements();
2446 Assert( get_d1_colormap( d1_palette, colormap ) == 0 );
2448 switch (cfilelength(d1_Piggy_fp)) {
2449 case D1_SHARE_BIG_PIGSIZE:
2450 case D1_SHARE_10_PIGSIZE:
2451 case D1_SHARE_PIGSIZE:
2452 case D1_10_BIG_PIGSIZE:
2455 Warning(D1_PIG_LOAD_FAILED ". descent.pig of v1.0 and all PC shareware versions not supported.");
2459 Warning("Unknown size for " D1_PIGFILE);
2463 case D1_OEM_PIGSIZE:
2464 case D1_MAC_PIGSIZE:
2465 case D1_MAC_SHARE_PIGSIZE:
2466 pig_data_start = cfile_read_int(d1_Piggy_fp );
2467 bm_read_d1_tmap_nums(d1_Piggy_fp); //was: bm_read_all_d1(fp);
2468 //for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2472 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2473 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2475 int N_sounds = cfile_read_int(d1_Piggy_fp);
2476 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2477 + N_sounds * sizeof(DiskSoundHeader);
2478 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2479 bitmap_data_start = bitmap_header_start + header_size;
2482 MALLOC( Bitmap_replacement_data, ubyte, D1_BITMAPS_SIZE);
2483 if (!Bitmap_replacement_data) {
2484 Warning(D1_PIG_LOAD_FAILED);
2487 atexit(free_bitmap_replacements);
2489 next_bitmap = Bitmap_replacement_data;
2491 for (d1_index = 1; d1_index <= N_bitmaps; d1_index++ ) {
2492 d2_index = d2_index_for_d1_index(d1_index);
2493 // only change bitmaps which are unique to d1
2494 if (d2_index != -1) {
2495 cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2496 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2498 bitmap_read_d1( &GameBitmaps[d2_index], d1_Piggy_fp, bitmap_data_start, &bmh, &get_next_bitmap, d1_palette, colormap );
2499 GameBitmapOffset[d2_index] = 0; // don't try to read bitmap from current d2 pigfile
2500 GameBitmapFlags[d2_index] = bmh.flags;
2502 if ( (p = strchr(AllBitmaps[d2_index].name, '#')) /* d2 BM is animated */
2503 && !(bmh.dflags & DBM_FLAG_ABM) ) { /* d1 bitmap is not animated */
2504 int i, len = p - AllBitmaps[d2_index].name;
2505 for (i = 0; i < Num_bitmap_files; i++)
2506 if (i != d2_index && ! memcmp(AllBitmaps[d2_index].name, AllBitmaps[i].name, len)) {
2507 GameBitmaps[i] = GameBitmaps[d2_index];
2508 GameBitmapOffset[i] = 0;
2509 GameBitmapFlags[i] = bmh.flags;
2515 cfclose(d1_Piggy_fp);
2517 last_palette_loaded_pig[0]= 0; //force pig re-load
2519 texmerge_flush(); //for re-merging with new textures
2523 extern int extra_bitmap_num;
2526 * Find and load the named bitmap from descent.pig
2527 * similar to read_extra_bitmap_iff
2529 bitmap_index read_extra_bitmap_d1_pig(char *name)
2531 bitmap_index bitmap_num;
2532 grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2534 bitmap_num.index = 0;
2538 DiskBitmapHeader bmh;
2539 int pig_data_start, bitmap_header_start, bitmap_data_start;
2541 ubyte colormap[256];
2542 ubyte d1_palette[256*3];
2544 d1_Piggy_fp = cfopen(D1_PIGFILE, "rb");
2548 Warning(D1_PIG_LOAD_FAILED);
2552 Assert( get_d1_colormap( d1_palette, colormap ) == 0 );
2554 switch (cfilelength(d1_Piggy_fp)) {
2555 case D1_SHARE_BIG_PIGSIZE:
2556 case D1_SHARE_10_PIGSIZE:
2557 case D1_SHARE_PIGSIZE:
2558 case D1_10_BIG_PIGSIZE:
2563 Warning("Unknown size for " D1_PIGFILE);
2567 case D1_OEM_PIGSIZE:
2568 case D1_MAC_PIGSIZE:
2569 case D1_MAC_SHARE_PIGSIZE:
2570 pig_data_start = cfile_read_int(d1_Piggy_fp );
2575 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2576 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2578 int N_sounds = cfile_read_int(d1_Piggy_fp);
2579 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2580 + N_sounds * sizeof(DiskSoundHeader);
2581 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2582 bitmap_data_start = bitmap_header_start + header_size;
2585 for (i = 1; i <= N_bitmaps; i++)
2587 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2588 if (!strnicmp(bmh.name, name, 8))
2592 if (strnicmp(bmh.name, name, 8))
2594 con_printf(CON_DEBUG, "could not find bitmap %s\n", name);
2598 bitmap_read_d1( new, d1_Piggy_fp, bitmap_data_start, &bmh, &my_d_malloc, d1_palette, colormap );
2600 cfclose(d1_Piggy_fp);
2603 new->avg_color = 0; //compute_average_pixel(new);
2605 bitmap_num.index = extra_bitmap_num;
2607 GameBitmaps[extra_bitmap_num++] = *new;
2613 #ifndef FAST_FILE_IO
2615 * reads a bitmap_index structure from a CFILE
2617 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2619 bi->index = cfile_read_short(fp);
2623 * reads n bitmap_index structs from a CFILE
2625 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2629 for (i = 0; i < n; i++)
2630 bi[i].index = cfile_read_short(fp);
2633 #endif // FAST_FILE_IO