1 /* $Id: piggy.c,v 1.52 2004-05-22 22:24:28 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.52 2004-05-22 22:24:28 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 char* piggy_game_bitmap_name(grs_bitmap *bmp)
615 if (bmp >= GameBitmaps && bmp < &GameBitmaps[MAX_BITMAP_FILES])
617 int i = bmp-GameBitmaps; // i = (bmp - GameBitmaps) / sizeof(grs_bitmap);
618 Assert (bmp == &GameBitmaps[i] && i >= 0 && i < MAX_BITMAP_FILES);
619 return AllBitmaps[i].name;
624 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
627 Assert( Num_bitmap_files < MAX_BITMAP_FILES );
629 temp.index = Num_bitmap_files;
633 if ( FindArg("-macdata") )
636 if ( !BigPig ) gr_bitmap_rle_compress( bmp );
637 Num_bitmap_files_new++;
640 strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
641 hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
642 GameBitmaps[Num_bitmap_files] = *bmp;
644 GameBitmapOffset[Num_bitmap_files] = 0;
645 GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
652 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
656 Assert( Num_sound_files < MAX_SOUND_FILES );
658 strncpy( AllSounds[Num_sound_files].name, name, 12 );
659 hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
660 GameSounds[Num_sound_files] = *snd;
662 SoundOffset[Num_sound_files] = 0;
668 Num_sound_files_new++;
674 bitmap_index piggy_find_bitmap( char * name )
682 if ((t=strchr(name,'#'))!=NULL)
685 for (i=0;i<Num_aliases;i++)
686 if (stricmp(name,alias_list[i].alias_name)==0) {
687 if (t) { //extra stuff for ABMs
688 static char temp[FILENAME_LEN];
689 _splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
695 name=alias_list[i].file_name;
702 i = hashtable_search( &AllBitmapsNames, name );
711 int piggy_find_sound( char * name )
715 i = hashtable_search( &AllDigiSndNames, name );
723 CFILE * Piggy_fp = NULL;
725 #define FILENAME_LEN 13
727 char Current_pigfile[FILENAME_LEN] = "";
729 void piggy_close_file()
734 Current_pigfile[0] = 0;
738 int Pigfile_initialized=0;
740 #define PIGFILE_ID MAKE_SIG('G','I','P','P') //PPIG
741 #define PIGFILE_VERSION 2
743 extern char CDROM_dir[];
745 int request_cd(void);
750 //copies a pigfile from the CD to the current dir
751 //retuns file handle of new pig
752 CFILE *copy_pigfile_from_cd(char *filename) // MACINTOSH VERSION
755 char sourcePathAndFileCStr[255] = "";
756 char destPathAndFileCStr[255] = "";
758 FILE* sourceFile = NULL;
759 FILE* destFile = NULL;
760 const int BUF_SIZE = 4096;
764 Str255 sourcePathAndFilePStr = "\p";
765 Str255 destPathAndFilePStr = "\p";
766 Str255 pigfileNamePStr = "\p";
767 HParamBlockRec theSourcePigHFSParams;
768 HParamBlockRec theDestPigHFSParams;
769 OSErr theErr = noErr;
770 char oldDirCStr[255] = "";
772 getcwd(oldDirCStr, 255);
774 show_boxed_message("Copying bitmap data from CD...");
775 gr_palette_load(gr_palette); //I don't think this line is really needed
778 //First, delete all PIG files currently in the directory
779 if( !FileFindFirst( "*.pig", &find ) )
784 } while( !FileFindNext( &find ) );
790 //Now, copy over new pig
791 songs_stop_redbook(); //so we can read off the cd
793 // make the source path "<cd volume>:Data:filename.pig"
794 //MWA ConvertCToPStr(filename, pigfileNamePStr);
796 //MWA ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:"); // volume ID is cd_VRefNum
797 //MWA ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
800 strcpy(sourcePathAndFileCStr, "Descent II:Data:");
801 strcat(sourcePathAndFileCStr, filename);
803 // make the destination path "<default directory>:Data:filename.pig"
804 //MWA ConcatPStr(destPathAndFilePStr, "\p:Data:");
805 //MWA ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
806 //MWA ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
807 //MWA ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
809 strcpy(destPathAndFileCStr, ":Data:");
810 strcat(destPathAndFileCStr, filename);
812 strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
813 strcpy(destPathAndFilePStr, destPathAndFileCStr);
814 c2pstr(sourcePathAndFilePStr);
815 c2pstr(destPathAndFilePStr);
818 // Open the source file
819 sourceFile = fopen(sourcePathAndFileCStr,"rb");
823 if (request_cd() == -1)
824 Error("Cannot load file <%s> from CD",filename);
827 } while (!sourceFile);
830 // Get the time stamp from the source file
831 theSourcePigHFSParams.fileParam.ioCompletion = nil;
832 theSourcePigHFSParams.fileParam.ioNamePtr = sourcePathAndFilePStr;
833 theSourcePigHFSParams.fileParam.ioVRefNum = cd_VRefNum;
834 theSourcePigHFSParams.fileParam.ioFDirIndex = 0;
835 theSourcePigHFSParams.fileParam.ioDirID = 0;
837 theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
840 // Error getting file time stamp!! Why? JTS
841 Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
844 // Copy the file over
847 // Open the destination file
848 destFile = fopen(destPathAndFileCStr,"wb");
851 Error("Cannot create file: <%s>\n", destPathAndFileCStr);
854 // Copy bytes until the end of the source file
855 while (!feof(sourceFile))
860 bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
861 if (ferror(sourceFile))
862 Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
864 // Assert is bogus Assert(bytes_read == BUF_SIZE || feof(sourceFile));
866 fwrite(buf,1,bytes_read,destFile);
867 if (ferror(destFile))
868 Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
871 // close the source/dest files
872 if (fclose(sourceFile))
873 Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
874 if (fclose(destFile))
875 Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
877 // Get the current hfs data for the new file
878 theDestPigHFSParams.fileParam.ioCompletion = nil;
879 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
880 theDestPigHFSParams.fileParam.ioVRefNum = 0;
881 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
882 theDestPigHFSParams.fileParam.ioDirID = 0;
883 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
884 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
886 // Error getting file time stamp!! Why? JTS
887 Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
890 // Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
891 theDestPigHFSParams.fileParam.ioNamePtr = destPathAndFilePStr;
892 theDestPigHFSParams.fileParam.ioVRefNum = 0;
893 theDestPigHFSParams.fileParam.ioFDirIndex = 0;
894 theDestPigHFSParams.fileParam.ioDirID = 0;
896 // Copy the time stamp from the source file info
897 theDestPigHFSParams.fileParam.ioFlCrDat = theSourcePigHFSParams.fileParam.ioFlCrDat;
898 theDestPigHFSParams.fileParam.ioFlMdDat = theSourcePigHFSParams.fileParam.ioFlMdDat;
899 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
900 theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
902 // Set the dest file's time stamp to the source file's time stamp values
903 theErr = PBHSetFInfo(&theDestPigHFSParams, false);
905 if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
907 Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
910 theErr = PBHGetFInfo(&theDestPigHFSParams, false);
912 return cfopen(destPathAndFileCStr, "rb");
915 #else //PC Version of copy_pigfile_from_cd is below
917 //copies a pigfile from the CD to the current dir
918 //retuns file handle of new pig
919 CFILE *copy_pigfile_from_cd(char *filename)
925 return cfopen(filename, "rb");
926 show_boxed_message("Copying bitmap data from CD...");
927 gr_palette_load(gr_palette); //I don't think this line is really needed
929 //First, delete all PIG files currently in the directory
931 if( !FileFindFirst( "*.pig", &find ) ) {
933 cfile_delete(find.name);
934 } while( !FileFindNext( &find ) );
938 //Now, copy over new pig
940 songs_stop_redbook(); //so we can read off the cd
942 //new code to unarj file
943 strcpy(name,CDROM_dir);
944 strcat(name,"descent2.sow");
947 // ret = unarj_specific_file(name,filename,filename);
952 if (ret != EXIT_SUCCESS) {
954 //delete file, so we don't leave partial file
955 cfile_delete(filename);
958 if (request_cd() == -1)
960 //NOTE LINK TO ABOVE IF
961 Error("Cannot load file <%s> from CD",filename);
964 } while (ret != EXIT_SUCCESS);
966 return cfopen(filename, "rb");
969 #endif // end of ifdef MAC around copy_pigfile_from_cd
971 //initialize a pigfile, reading headers
972 //returns the size of all the bitmap data
973 void piggy_init_pigfile(char *filename)
977 char temp_name_read[16];
978 grs_bitmap temp_bitmap;
979 DiskBitmapHeader bmh;
980 int header_size, N_bitmaps, data_size, data_start;
982 char name[255]; // filename + path for the mac
985 piggy_close_file(); //close old pig if still open
987 //rename pigfile for shareware
988 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
989 filename = DEFAULT_PIGFILE_SHAREWARE;
992 Piggy_fp = cfopen( filename, "rb" );
994 sprintf(name, ":Data:%s", filename);
995 Piggy_fp = cfopen( name, "rb" );
997 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
998 if (Piggy_fp == NULL)
1000 Error("Cannot load required file <%s>",name);
1002 #endif // end of if def shareware
1008 return; //if editor, ok to not have pig, because we'll build one
1010 Piggy_fp = copy_pigfile_from_cd(filename);
1014 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1015 int pig_id,pig_version;
1017 pig_id = cfile_read_int(Piggy_fp);
1018 pig_version = cfile_read_int(Piggy_fp);
1019 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1020 cfclose(Piggy_fp); //out of date pig
1021 Piggy_fp = NULL; //..so pretend it's not here
1028 return; //if editor, ok to not have pig, because we'll build one
1030 Error("Cannot load required file <%s>",filename);
1034 strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
1036 N_bitmaps = cfile_read_int(Piggy_fp);
1038 header_size = N_bitmaps * sizeof(DiskBitmapHeader);
1040 data_start = header_size + cftell(Piggy_fp);
1042 data_size = cfilelength(Piggy_fp) - data_start;
1044 Num_bitmap_files = 1;
1046 for (i=0; i<N_bitmaps; i++ ) {
1047 DiskBitmapHeader_read(&bmh, Piggy_fp);
1048 memcpy( temp_name_read, bmh.name, 8 );
1049 temp_name_read[8] = 0;
1050 if ( bmh.dflags & DBM_FLAG_ABM )
1051 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & DBM_NUM_FRAMES );
1053 strcpy( temp_name, temp_name_read );
1054 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1055 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1056 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1057 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1058 temp_bitmap.avg_color = bmh.avg_color;
1059 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1061 GameBitmapFlags[i+1] = bmh.flags & BM_FLAGS_TO_COPY;
1063 GameBitmapOffset[i+1] = bmh.offset + data_start;
1064 Assert( (i+1) == Num_bitmap_files );
1065 piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
1069 Piggy_bitmap_cache_size = data_size + (data_size/10); //extra mem for new bitmaps
1070 Assert( Piggy_bitmap_cache_size > 0 );
1072 Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
1074 if (piggy_low_memory)
1075 Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
1078 BitmapBits = d_malloc( Piggy_bitmap_cache_size );
1079 if ( BitmapBits == NULL )
1080 Error( "Not enough memory to load bitmaps\n" );
1081 Piggy_bitmap_cache_data = BitmapBits;
1082 Piggy_bitmap_cache_next = 0;
1084 #if defined(MACINTOSH) && defined(SHAREWARE)
1085 // load_exit_models();
1088 Pigfile_initialized=1;
1091 #define FILENAME_LEN 13
1092 #define MAX_BITMAPS_PER_BRUSH 30
1094 extern int compute_average_pixel(grs_bitmap *new);
1096 ubyte *Bitmap_replacement_data = NULL;
1098 //reads in a new pigfile (for new palette)
1099 //returns the size of all the bitmap data
1100 void piggy_new_pigfile(char *pigname)
1104 char temp_name_read[16];
1105 grs_bitmap temp_bitmap;
1106 DiskBitmapHeader bmh;
1107 int header_size, N_bitmaps, data_size, data_start;
1108 int must_rewrite_pig = 0;
1115 //rename pigfile for shareware
1116 if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
1117 pigname = DEFAULT_PIGFILE_SHAREWARE;
1119 if (strnicmp(Current_pigfile, pigname, sizeof(Current_pigfile)) == 0 // correct pig already loaded
1120 && !Bitmap_replacement_data) // no need to reload: no bitmaps were altered
1123 if (!Pigfile_initialized) { //have we ever opened a pigfile?
1124 piggy_init_pigfile(pigname); //..no, so do initialization stuff
1128 piggy_close_file(); //close old pig if still open
1130 Piggy_bitmap_cache_next = 0; //free up cache
1132 strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
1135 Piggy_fp = cfopen( pigname, "rb" );
1137 sprintf(name, ":Data:%s", pigname);
1138 Piggy_fp = cfopen( name, "rb" );
1140 #ifdef SHAREWARE // if we are in the shareware version, we must have the pig by now.
1141 if (Piggy_fp == NULL)
1143 Error("Cannot load required file <%s>",name);
1145 #endif // end of if def shareware
1150 Piggy_fp = copy_pigfile_from_cd(pigname);
1153 if (Piggy_fp) { //make sure pig is valid type file & is up-to-date
1154 int pig_id,pig_version;
1156 pig_id = cfile_read_int(Piggy_fp);
1157 pig_version = cfile_read_int(Piggy_fp);
1158 if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1159 cfclose(Piggy_fp); //out of date pig
1160 Piggy_fp = NULL; //..so pretend it's not here
1166 Error("Cannot open correct version of <%s>", pigname);
1171 N_bitmaps = cfile_read_int(Piggy_fp);
1173 header_size = N_bitmaps * sizeof(DiskBitmapHeader);
1175 data_start = header_size + cftell(Piggy_fp);
1177 data_size = cfilelength(Piggy_fp) - data_start;
1179 for (i=1; i<=N_bitmaps; i++ ) {
1180 DiskBitmapHeader_read(&bmh, Piggy_fp);
1181 memcpy( temp_name_read, bmh.name, 8 );
1182 temp_name_read[8] = 0;
1184 if ( bmh.dflags & DBM_FLAG_ABM )
1185 sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & DBM_NUM_FRAMES );
1187 strcpy( temp_name, temp_name_read );
1189 //Make sure name matches
1190 if (strcmp(temp_name,AllBitmaps[i].name)) {
1191 //Int3(); //this pig is out of date. Delete it
1195 strcpy(AllBitmaps[i].name,temp_name);
1197 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1199 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1200 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1201 temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1202 temp_bitmap.avg_color = bmh.avg_color;
1203 temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1205 GameBitmapFlags[i] = bmh.flags & BM_FLAGS_TO_COPY;
1207 GameBitmapOffset[i] = bmh.offset + data_start;
1209 GameBitmaps[i] = temp_bitmap;
1213 N_bitmaps = 0; //no pigfile, so no bitmaps
1217 Assert(N_bitmaps == Num_bitmap_files-1);
1221 if (must_rewrite_pig || (N_bitmaps < Num_bitmap_files-1)) {
1224 //re-read the bitmaps that aren't in this pig
1226 for (i=N_bitmaps+1;i<Num_bitmap_files;i++) {
1229 p = strchr(AllBitmaps[i].name,'#');
1231 if (p) { // this is an ABM == animated bitmap
1232 char abmname[FILENAME_LEN];
1234 grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
1235 int iff_error; //reference parm to avoid warning message
1237 char basename[FILENAME_LEN];
1240 strcpy(basename,AllBitmaps[i].name);
1241 basename[p-AllBitmaps[i].name] = 0; //cut off "#nn" part
1243 sprintf( abmname, "%s.abm", basename );
1245 iff_error = iff_read_animbrush(abmname,bm,MAX_BITMAPS_PER_BRUSH,&nframes,newpal);
1247 if (iff_error != IFF_NO_ERROR) {
1248 mprintf((1,"File %s - IFF error: %s",abmname,iff_errormsg(iff_error)));
1249 Error("File %s - IFF error: %s",abmname,iff_errormsg(iff_error));
1252 for (fnum=0;fnum<nframes; fnum++) {
1256 sprintf( tempname, "%s#%d", basename, fnum );
1258 //SuperX = (GameBitmaps[i+fnum].bm_flags&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1259 SuperX = (GameBitmapFlags[i+fnum]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1260 //above makes assumption that supertransparent color is 254
1262 if ( iff_has_transparency )
1263 gr_remap_bitmap_good( bm[fnum], newpal, iff_transparent_color, SuperX );
1265 gr_remap_bitmap_good( bm[fnum], newpal, -1, SuperX );
1267 bm[fnum]->avg_color = compute_average_pixel(bm[fnum]);
1270 if ( FindArg("-macdata") )
1271 swap_0_255( bm[fnum] );
1273 if ( !BigPig ) gr_bitmap_rle_compress( bm[fnum] );
1275 if (bm[fnum]->bm_flags & BM_FLAG_RLE)
1276 size = *((int *) bm[fnum]->bm_data);
1278 size = bm[fnum]->bm_w * bm[fnum]->bm_h;
1280 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],bm[fnum]->bm_data,size);
1281 d_free(bm[fnum]->bm_data);
1282 bm[fnum]->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1283 Piggy_bitmap_cache_next += size;
1285 GameBitmaps[i+fnum] = *bm[fnum];
1287 // -- mprintf( (0, "U" ));
1291 i += nframes-1; //filled in multiple bitmaps
1293 else { //this is a BBM
1296 ubyte newpal[256*3];
1298 char bbmname[FILENAME_LEN];
1301 MALLOC( new, grs_bitmap, 1 );
1303 sprintf( bbmname, "%s.bbm", AllBitmaps[i].name );
1304 iff_error = iff_read_bitmap(bbmname,new,BM_LINEAR,newpal);
1307 if (iff_error != IFF_NO_ERROR) {
1308 mprintf((1, "File %s - IFF error: %s",bbmname,iff_errormsg(iff_error)));
1309 Error("File %s - IFF error: %s",bbmname,iff_errormsg(iff_error));
1312 SuperX = (GameBitmapFlags[i]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1313 //above makes assumption that supertransparent color is 254
1315 if ( iff_has_transparency )
1316 gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
1318 gr_remap_bitmap_good( new, newpal, -1, SuperX );
1320 new->avg_color = compute_average_pixel(new);
1323 if ( FindArg("-macdata") )
1326 if ( !BigPig ) gr_bitmap_rle_compress( new );
1328 if (new->bm_flags & BM_FLAG_RLE)
1329 size = *((int *) new->bm_data);
1331 size = new->bm_w * new->bm_h;
1333 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],new->bm_data,size);
1334 d_free(new->bm_data);
1335 new->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1336 Piggy_bitmap_cache_next += size;
1338 GameBitmaps[i] = *new;
1342 // -- mprintf( (0, "U" ));
1346 //@@Dont' do these things which are done when writing
1347 //@@for (i=0; i < Num_bitmap_files; i++ ) {
1348 //@@ bitmap_index bi;
1350 //@@ PIGGY_PAGE_IN( bi );
1353 //@@piggy_close_file();
1355 piggy_write_pigfile(pigname);
1357 Current_pigfile[0] = 0; //say no pig, to force reload
1359 piggy_new_pigfile(pigname); //read in just-generated pig
1363 #endif //ifdef EDITOR
1367 ubyte bogus_data[64*64];
1368 grs_bitmap bogus_bitmap;
1369 ubyte bogus_bitmap_initialized=0;
1370 digi_sound bogus_sound;
1372 #define HAMFILE_ID MAKE_SIG('!','M','A','H') //HAM!
1373 #define HAMFILE_VERSION 3
1374 //version 1 -> 2: save marker_model_num
1375 //version 2 -> 3: removed sound files
1377 #define SNDFILE_ID MAKE_SIG('D','N','S','D') //DSND
1378 #define SNDFILE_VERSION 1
1382 CFILE * ham_fp = NULL;
1384 int sound_offset = 0;
1390 ham_fp = cfopen( DEFAULT_HAMFILE, "rb" );
1392 sprintf(name, ":Data:%s", DEFAULT_HAMFILE );
1393 ham_fp = cfopen( name, "rb" );
1396 if (ham_fp == NULL) {
1397 Must_write_hamfile = 1;
1401 //make sure ham is valid type file & is up-to-date
1402 ham_id = cfile_read_int(ham_fp);
1403 Piggy_hamfile_version = cfile_read_int(ham_fp);
1404 if (ham_id != HAMFILE_ID)
1405 Error("Cannot open ham file %s\n", DEFAULT_HAMFILE);
1407 if (ham_id != HAMFILE_ID || Piggy_hamfile_version != HAMFILE_VERSION) {
1408 Must_write_hamfile = 1;
1409 cfclose(ham_fp); //out of date ham
1414 if (Piggy_hamfile_version < 3) // hamfile contains sound info
1415 sound_offset = cfile_read_int(ham_fp);
1421 bm_read_all(ham_fp);
1422 cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1424 //for (i = 0; i < MAX_BITMAP_FILES; i++) {
1425 //GameBitmapXlat[i] = INTEL_SHORT(GameBitmapXlat[i]);
1426 //printf("GameBitmapXlat[%d] = %d\n", i, GameBitmapXlat[i]);
1431 if (Piggy_hamfile_version < 3) {
1436 DiskSoundHeader sndh;
1437 digi_sound temp_sound;
1438 char temp_name_read[16];
1441 cfseek(ham_fp, sound_offset, SEEK_SET);
1442 N_sounds = cfile_read_int(ham_fp);
1444 sound_start = cftell(ham_fp);
1446 header_size = N_sounds * sizeof(DiskSoundHeader);
1450 for (i=0; i<N_sounds; i++ ) {
1451 DiskSoundHeader_read(&sndh, ham_fp);
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(ham_fp);
1483 CFILE * snd_fp = NULL;
1484 int snd_id,snd_version;
1489 DiskSoundHeader sndh;
1490 digi_sound temp_sound;
1491 char temp_name_read[16];
1498 snd_fp = cfopen( DEFAULT_SNDFILE, "rb" );
1500 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1501 snd_fp = cfopen( name, "rb");
1507 //make sure soundfile is valid type file & is up-to-date
1508 snd_id = cfile_read_int(snd_fp);
1509 snd_version = cfile_read_int(snd_fp);
1510 if (snd_id != SNDFILE_ID || snd_version != SNDFILE_VERSION) {
1511 cfclose(snd_fp); //out of date sound file
1515 N_sounds = cfile_read_int(snd_fp);
1517 sound_start = cftell(snd_fp);
1518 size = cfilelength(snd_fp) - sound_start;
1520 mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
1522 header_size = N_sounds*sizeof(DiskSoundHeader);
1526 for (i=0; i<N_sounds; i++ ) {
1527 DiskSoundHeader_read(&sndh, snd_fp);
1528 //size -= sizeof(DiskSoundHeader);
1529 temp_sound.length = sndh.length;
1530 temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1531 SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1532 memcpy( temp_name_read, sndh.name, 8 );
1533 temp_name_read[8] = 0;
1534 piggy_register_sound( &temp_sound, temp_name_read, 1 );
1536 if (piggy_is_needed(i))
1537 #endif // note link to if.
1538 sbytes += sndh.length;
1539 //mprintf(( 0, "%d bytes of sound\n", sbytes ));
1542 SoundBits = d_malloc( sbytes + 16 );
1543 if ( SoundBits == NULL )
1544 Error( "Not enough memory to load sounds\n" );
1546 mprintf(( 0, "\nBitmaps: %d KB Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1548 // piggy_read_sounds(snd_fp);
1555 int piggy_init(void)
1557 int ham_ok=0,snd_ok=0;
1560 hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
1561 hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
1563 for (i=0; i<MAX_SOUND_FILES; i++ ) {
1564 GameSounds[i].length = 0;
1565 GameSounds[i].data = NULL;
1569 for (i=0; i<MAX_BITMAP_FILES; i++ )
1570 GameBitmapXlat[i] = i;
1572 if ( !bogus_bitmap_initialized ) {
1575 bogus_bitmap_initialized = 1;
1576 memset( &bogus_bitmap, 0, sizeof(grs_bitmap) );
1577 bogus_bitmap.bm_w = bogus_bitmap.bm_h = bogus_bitmap.bm_rowsize = 64;
1578 bogus_bitmap.bm_data = bogus_data;
1579 c = gr_find_closest_color( 0, 0, 63 );
1580 for (i=0; i<4096; i++ ) bogus_data[i] = c;
1581 c = gr_find_closest_color( 63, 0, 0 );
1582 // Make a big red X !
1583 for (i=0; i<64; i++ ) {
1584 bogus_data[i*64+i] = c;
1585 bogus_data[i*64+(63-i)] = c;
1587 piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
1588 bogus_sound.length = 64*64;
1589 bogus_sound.data = bogus_data;
1590 GameBitmapOffset[0] = 0;
1593 if ( FindArg( "-bigpig" ))
1596 if ( FindArg( "-lowmem" ))
1597 piggy_low_memory = 1;
1599 if ( FindArg( "-nolowmem" ))
1600 piggy_low_memory = 0;
1602 if (piggy_low_memory)
1605 WIN(DDGRLOCK(dd_grd_curcanv));
1606 gr_set_curfont( SMALL_FONT );
1607 gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
1608 gr_printf( 0x8000, grd_curcanv->cv_h-20, "%s...", TXT_LOADING_DATA );
1609 WIN(DDGRUNLOCK(dd_grd_curcanv));
1611 #if 1 //def EDITOR //need for d1 mission briefings
1612 piggy_init_pigfile(DEFAULT_PIGFILE);
1615 snd_ok = ham_ok = read_hamfile();
1617 if (Piggy_hamfile_version >= 3)
1618 snd_ok = read_sndfile();
1620 atexit(piggy_close);
1622 mprintf ((0,"HamOk=%d SndOk=%d\n",ham_ok,snd_ok));
1623 return (ham_ok && snd_ok); //read ok
1626 int piggy_is_needed(int soundnum)
1630 if ( !digi_lomem ) return 1;
1632 for (i=0; i<MAX_SOUNDS; i++ ) {
1633 if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
1640 void piggy_read_sounds(void)
1653 fp = cfopen( DEFAULT_SNDFILE, "rb" );
1655 sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1656 fp = cfopen( name, "rb");
1662 for (i=0; i<Num_sound_files; i++ ) {
1663 digi_sound *snd = &GameSounds[i];
1665 if ( SoundOffset[i] > 0 ) {
1666 if ( piggy_is_needed(i) ) {
1667 cfseek( fp, SoundOffset[i], SEEK_SET );
1669 // Read in the sound data!!!
1672 sbytes += snd->length;
1673 cfread( snd->data, snd->length, 1, fp );
1676 snd->data = (ubyte *) -1;
1682 mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
1687 extern int descent_critical_error;
1688 extern unsigned descent_critical_deverror;
1689 extern unsigned descent_critical_errcode;
1691 char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
1692 "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
1693 "Read fault", "General Failure" };
1695 void piggy_critical_error()
1697 grs_canvas * save_canv;
1698 grs_font * save_font;
1700 save_canv = grd_curcanv;
1701 save_font = grd_curcanv->cv_font;
1702 gr_palette_load( gr_palette );
1703 i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A' );
1706 gr_set_current_canvas(save_canv);
1707 grd_curcanv->cv_font = save_font;
1710 void piggy_bitmap_page_in( bitmap_index bitmap )
1719 Assert( i < MAX_BITMAP_FILES );
1720 Assert( i < Num_bitmap_files );
1721 Assert( Piggy_bitmap_cache_size > 0 );
1723 if ( i < 1 ) return;
1724 if ( i >= MAX_BITMAP_FILES ) return;
1725 if ( i >= Num_bitmap_files ) return;
1727 if ( GameBitmapOffset[i] == 0 ) return; // A read-from-disk bitmap!!!
1729 if ( piggy_low_memory ) {
1731 i = GameBitmapXlat[i]; // Xlat for low-memory settings!
1734 bmp = &GameBitmaps[i];
1736 if ( bmp->bm_flags & BM_FLAG_PAGED_OUT ) {
1740 descent_critical_error = 0;
1741 cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
1742 if ( descent_critical_error ) {
1743 piggy_critical_error();
1747 bmp->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1748 bmp->bm_flags = GameBitmapFlags[i];
1750 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1752 descent_critical_error = 0;
1753 zsize = cfile_read_int(Piggy_fp);
1754 if ( descent_critical_error ) {
1755 piggy_critical_error();
1759 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1760 //Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );
1761 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1763 piggy_bitmap_page_out_all();
1766 descent_critical_error = 0;
1767 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next+4], 1, zsize-4, Piggy_fp );
1768 if ( descent_critical_error ) {
1769 piggy_critical_error();
1774 switch (cfilelength(Piggy_fp)) {
1776 if (!FindArg("-macdata"))
1778 // otherwise, fall through...
1779 case MAC_ALIEN1_PIGSIZE:
1780 case MAC_ALIEN2_PIGSIZE:
1781 case MAC_FIRE_PIGSIZE:
1782 case MAC_GROUPA_PIGSIZE:
1783 case MAC_ICE_PIGSIZE:
1784 case MAC_WATER_PIGSIZE:
1785 rle_swap_0_255( bmp );
1786 memcpy(&zsize, bmp->bm_data, 4);
1791 memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
1792 Piggy_bitmap_cache_next += zsize;
1793 if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1795 piggy_bitmap_page_out_all();
1800 // GET JOHN NOW IF YOU GET THIS ASSERT!!!
1801 Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );
1802 if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) {
1803 piggy_bitmap_page_out_all();
1806 descent_critical_error = 0;
1807 temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
1808 if ( descent_critical_error ) {
1809 piggy_critical_error();
1812 Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
1815 switch (cfilelength(Piggy_fp)) {
1817 if (!FindArg("-macdata"))
1819 // otherwise, fall through...
1820 case MAC_ALIEN1_PIGSIZE:
1821 case MAC_ALIEN2_PIGSIZE:
1822 case MAC_FIRE_PIGSIZE:
1823 case MAC_GROUPA_PIGSIZE:
1824 case MAC_ICE_PIGSIZE:
1825 case MAC_WATER_PIGSIZE:
1832 //@@if ( bmp->bm_selector ) {
1833 //@@#if !defined(WINDOWS) && !defined(MACINTOSH)
1834 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1835 //@@ Error( "Error modifying selector base in piggy.c\n" );
1842 if ( piggy_low_memory ) {
1844 GameBitmaps[org_i] = GameBitmaps[i];
1847 //@@Removed from John's code:
1849 //@@ if ( bmp->bm_selector ) {
1850 //@@ if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1851 //@@ Error( "Error modifying selector base in piggy.c\n" );
1857 void piggy_bitmap_page_out_all()
1861 Piggy_bitmap_cache_next = 0;
1863 piggy_page_flushed++;
1868 for (i=0; i<Num_bitmap_files; i++ ) {
1869 if ( GameBitmapOffset[i] > 0 ) { // Don't page out bitmaps read from disk!!!
1870 GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
1871 GameBitmaps[i].bm_data = Piggy_bitmap_cache_data;
1875 mprintf(( 0, "Flushing piggy bitmap cache\n" ));
1878 void piggy_load_level_data()
1880 piggy_bitmap_page_out_all();
1886 void change_filename_ext( char *dest, char *src, char *ext );
1888 void piggy_write_pigfile(char *filename)
1891 int bitmap_data_start, data_offset;
1892 DiskBitmapHeader bmh;
1894 char subst_name[32];
1897 char tname[FILENAME_LEN];
1899 // -- mprintf( (0, "Paging in all piggy bitmaps..." ));
1900 for (i=0; i < Num_bitmap_files; i++ ) {
1903 PIGGY_PAGE_IN( bi );
1905 // -- mprintf( (0, "\n" ));
1909 // -- mprintf( (0, "Creating %s...",filename ));
1911 pig_fp = fopen( filename, "wb" ); //open PIG file
1912 Assert( pig_fp!=NULL );
1914 write_int(PIGFILE_ID,pig_fp);
1915 write_int(PIGFILE_VERSION,pig_fp);
1918 fwrite( &Num_bitmap_files, sizeof(int), 1, pig_fp );
1921 bitmap_data_start = ftell(pig_fp);
1922 bitmap_data_start += (Num_bitmap_files - 1) * sizeof(DiskBitmapHeader);
1923 data_offset = bitmap_data_start;
1925 change_filename_ext(tname,filename,"lst");
1926 fp1 = fopen( tname, "wt" );
1927 change_filename_ext(tname,filename,"all");
1928 fp2 = fopen( tname, "wt" );
1930 for (i=1; i < Num_bitmap_files; i++ ) {
1936 p = strchr(AllBitmaps[i].name, '#');
1937 if (p) { // this is an ABM == animated bitmap
1943 fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
1944 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1945 Assert( n <= DBM_NUM_FRAMES );
1946 bmh.dflags = DBM_FLAG_ABM + n;
1950 fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
1951 memcpy( bmh.name, AllBitmaps[i].name, 8 );
1955 bmp = &GameBitmaps[i];
1957 Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
1960 fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
1961 org_offset = ftell(pig_fp);
1962 bmh.offset = data_offset - bitmap_data_start;
1963 fseek( pig_fp, data_offset, SEEK_SET );
1965 if ( bmp->bm_flags & BM_FLAG_RLE ) {
1966 size = (int *)bmp->bm_data;
1967 fwrite( bmp->bm_data, sizeof(ubyte), *size, pig_fp );
1968 data_offset += *size;
1970 fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
1972 fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, pig_fp );
1973 data_offset += bmp->bm_rowsize * bmp->bm_h;
1975 fprintf( fp1, ".\n" );
1977 fseek( pig_fp, org_offset, SEEK_SET );
1978 Assert( GameBitmaps[i].bm_w < 4096 );
1979 bmh.width = (GameBitmaps[i].bm_w & 0xff);
1980 bmh.wh_extra = ((GameBitmaps[i].bm_w >> 8) & 0x0f);
1981 Assert( GameBitmaps[i].bm_h < 4096 );
1982 bmh.height = GameBitmaps[i].bm_h;
1983 bmh.wh_extra |= ((GameBitmaps[i].bm_h >> 4) & 0xf0);
1984 bmh.flags = GameBitmaps[i].bm_flags;
1985 if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name )) {
1986 bitmap_index other_bitmap;
1987 other_bitmap = piggy_find_bitmap( subst_name );
1988 GameBitmapXlat[i] = other_bitmap.index;
1989 bmh.flags |= BM_FLAG_PAGED_OUT;
1990 //mprintf(( 0, "Skipping bitmap %d\n", i ));
1991 //mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
1993 bmh.flags &= ~BM_FLAG_PAGED_OUT;
1995 bmh.avg_color=GameBitmaps[i].avg_color;
1996 fwrite(&bmh, sizeof(DiskBitmapHeader), 1, pig_fp); // Mark as a bitmap
2001 mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
2002 fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
2009 static void write_int(int i,FILE *file)
2011 if (fwrite( &i, sizeof(i), 1, file) != 1)
2012 Error( "Error reading int in gamesave.c" );
2016 void piggy_dump_all()
2020 int org_offset,data_offset=0;
2021 DiskSoundHeader sndh;
2022 int sound_data_start=0;
2025 #ifdef NO_DUMP_SOUNDS
2026 Num_sound_files = 0;
2027 Num_sound_files_new = 0;
2030 if (!Must_write_hamfile && (Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
2033 fp1 = fopen( "ham.lst", "wt" );
2034 fp2 = fopen( "ham.all", "wt" );
2036 if (Must_write_hamfile || Num_bitmap_files_new) {
2038 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
2040 ham_fp = fopen( DEFAULT_HAMFILE, "wb" ); //open HAM file
2041 Assert( ham_fp!=NULL );
2043 write_int(HAMFILE_ID,ham_fp);
2044 write_int(HAMFILE_VERSION,ham_fp);
2046 bm_write_all(ham_fp);
2047 xlat_offset = ftell(ham_fp);
2048 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
2051 if (Num_bitmap_files_new)
2052 piggy_write_pigfile(DEFAULT_PIGFILE);
2054 //free up memeory used by new bitmaps
2055 for (i=Num_bitmap_files-Num_bitmap_files_new;i<Num_bitmap_files;i++)
2056 d_free(GameBitmaps[i].bm_data);
2058 //next thing must be done after pig written
2059 fseek( ham_fp, xlat_offset, SEEK_SET );
2060 fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
2063 mprintf( (0, "\n" ));
2066 if (Num_sound_files_new) {
2068 mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
2069 // Now dump sound file
2070 ham_fp = fopen( DEFAULT_SNDFILE, "wb" );
2071 Assert( ham_fp!=NULL );
2073 write_int(SNDFILE_ID,ham_fp);
2074 write_int(SNDFILE_VERSION,ham_fp);
2076 fwrite( &Num_sound_files, sizeof(int), 1, ham_fp );
2078 mprintf( (0, "\nDumping sounds..." ));
2080 sound_data_start = ftell(ham_fp);
2081 sound_data_start += Num_sound_files*sizeof(DiskSoundHeader);
2082 data_offset = sound_data_start;
2084 for (i=0; i < Num_sound_files; i++ ) {
2087 snd = &GameSounds[i];
2088 strcpy( sndh.name, AllSounds[i].name );
2089 sndh.length = GameSounds[i].length;
2090 sndh.offset = data_offset - sound_data_start;
2092 org_offset = ftell(ham_fp);
2093 fseek( ham_fp, data_offset, SEEK_SET );
2095 sndh.data_length = GameSounds[i].length;
2096 fwrite( snd->data, sizeof(ubyte), snd->length, ham_fp );
2097 data_offset += snd->length;
2098 fseek( ham_fp, org_offset, SEEK_SET );
2099 fwrite( &sndh, sizeof(DiskSoundHeader), 1, ham_fp ); // Mark as a bitmap
2101 fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
2102 fprintf( fp2, "%s.raw\n", AllSounds[i].name );
2106 mprintf( (0, "\n" ));
2109 fprintf( fp1, "Total sound size: %d bytes\n", data_offset-sound_data_start);
2110 mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
2111 fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
2116 // Never allow the game to run after building ham.
2130 d_free( SoundBits );
2132 hashtable_free( &AllBitmapsNames );
2133 hashtable_free( &AllDigiSndNames );
2137 int piggy_does_bitmap_exist_slow( char * name )
2141 for (i=0; i<Num_bitmap_files; i++ ) {
2142 if ( !strcmp( AllBitmaps[i].name, name) )
2149 #define NUM_GAUGE_BITMAPS 23
2150 char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = {
2151 "gauge01", "gauge01b",
2152 "gauge02", "gauge02b",
2153 "gauge06", "gauge06b",
2154 "targ01", "targ01b",
2155 "targ02", "targ02b",
2156 "targ03", "targ03b",
2157 "targ04", "targ04b",
2158 "targ05", "targ05b",
2159 "targ06", "targ06b",
2160 "gauge18", "gauge18b",
2166 int piggy_is_gauge_bitmap( char * base_name )
2169 for (i=0; i<NUM_GAUGE_BITMAPS; i++ ) {
2170 if ( !stricmp( base_name, gauge_bitmap_names[i] ))
2177 int piggy_is_substitutable_bitmap( char * name, char * subst_name )
2181 char base_name[ 16 ];
2183 strcpy( subst_name, name );
2184 p = strchr( subst_name, '#' );
2186 frame = atoi( &p[1] );
2188 strcpy( base_name, subst_name );
2189 if ( !piggy_is_gauge_bitmap( base_name )) {
2190 sprintf( subst_name, "%s#%d", base_name, frame+1 );
2191 if ( piggy_does_bitmap_exist_slow( subst_name ) ) {
2193 sprintf( subst_name, "%s#%d", base_name, frame-1 );
2199 strcpy( subst_name, name );
2206 // New Windows stuff
2208 // windows bitmap page in
2209 // Page in a bitmap, if ddraw, then page it into a ddsurface in
2210 // 'video' memory. if that fails, page it in normally.
2212 void piggy_bitmap_page_in_w( bitmap_index bitmap, int ddraw )
2217 // Essential when switching video modes!
2219 void piggy_bitmap_page_out_all_w()
2227 * Functions for loading replacement textures
2228 * 1) From .pog files
2229 * 2) From descent.pig (for loading d1 levels)
2232 extern void change_filename_extension( char *dest, char *src, char *new_ext );
2233 extern char last_palette_loaded_pig[];
2235 void free_bitmap_replacements()
2237 if (Bitmap_replacement_data) {
2238 d_free(Bitmap_replacement_data);
2239 Bitmap_replacement_data = NULL;
2243 void load_bitmap_replacements(char *level_name)
2245 char ifile_name[FILENAME_LEN];
2249 //first, free up data allocated for old bitmaps
2250 free_bitmap_replacements();
2252 change_filename_extension(ifile_name, level_name, ".POG" );
2254 ifile = cfopen(ifile_name,"rb");
2257 int id,version,n_bitmaps;
2258 int bitmap_data_size;
2261 id = cfile_read_int(ifile);
2262 version = cfile_read_int(ifile);
2264 if (id != MAKE_SIG('G','O','P','D') || version != 1) {
2269 n_bitmaps = cfile_read_int(ifile);
2271 MALLOC( indices, ushort, n_bitmaps );
2273 for (i = 0; i < n_bitmaps; i++)
2274 indices[i] = cfile_read_short(ifile);
2276 bitmap_data_size = cfilelength(ifile) - cftell(ifile) - sizeof(DiskBitmapHeader) * n_bitmaps;
2277 MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
2279 for (i=0;i<n_bitmaps;i++) {
2280 DiskBitmapHeader bmh;
2281 grs_bitmap temp_bitmap;
2283 DiskBitmapHeader_read(&bmh, ifile);
2285 memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2287 temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2288 temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2289 temp_bitmap.avg_color = bmh.avg_color;
2290 temp_bitmap.bm_data = Bitmap_replacement_data + bmh.offset;
2292 temp_bitmap.bm_flags |= bmh.flags & BM_FLAGS_TO_COPY;
2294 GameBitmaps[indices[i]] = temp_bitmap;
2295 // don't we need the following? GameBitmapOffset[indices[i]] = 0; // don't try to read bitmap from current pigfile
2298 cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
2304 last_palette_loaded_pig[0]= 0; //force pig re-load
2306 texmerge_flush(); //for re-merging with new textures
2309 atexit(free_bitmap_replacements);
2312 /* calculate table to translate d1 bitmaps to current palette,
2313 * return -1 on error
2315 int get_d1_colormap( ubyte *d1_palette, ubyte *colormap )
2318 CFILE * palette_file = cfopen(D1_PALETTE, "rb");
2319 if (!palette_file || cfilelength(palette_file) != 9472)
2321 cfread( d1_palette, 256, 3, palette_file);
2322 cfclose( palette_file );
2323 build_colormap_good( d1_palette, colormap, freq );
2324 // don't change transparencies:
2325 colormap[254] = 254;
2326 colormap[255] = 255;
2330 #define JUST_IN_CASE 132 /* is enough for d1 pc registered */
2331 void bitmap_read_d1( grs_bitmap *bitmap, /* read into this bitmap */
2332 CFILE *d1_Piggy_fp, /* read from this file */
2333 int bitmap_data_start, /* specific to file */
2334 DiskBitmapHeader *bmh, /* header info for bitmap */
2335 ubyte **next_bitmap, /* where to write it (if 0, use malloc) */
2336 ubyte *d1_palette, /* what palette the bitmap has */
2337 ubyte *colormap) /* how to translate bitmap's colors */
2340 memset( bitmap, 0, sizeof(grs_bitmap) );
2342 bitmap->bm_w = bitmap->bm_rowsize = bmh->width + ((short) (bmh->wh_extra&0x0f)<<8);
2343 bitmap->bm_h = bmh->height + ((short) (bmh->wh_extra&0xf0)<<4);
2344 bitmap->avg_color = bmh->avg_color;
2345 bitmap->bm_flags |= bmh->flags & BM_FLAGS_TO_COPY;
2347 cfseek(d1_Piggy_fp, bitmap_data_start + bmh->offset, SEEK_SET);
2348 if (bmh->flags & BM_FLAG_RLE) {
2349 zsize = cfile_read_int(d1_Piggy_fp);
2350 cfseek(d1_Piggy_fp, -4, SEEK_CUR);
2352 zsize = bitmap->bm_h * bitmap->bm_w;
2355 bitmap->bm_data = *next_bitmap;
2356 *next_bitmap += zsize;
2358 bitmap->bm_data = d_malloc(zsize + JUST_IN_CASE);
2360 cfread(bitmap->bm_data, 1, zsize, d1_Piggy_fp);
2361 switch(cfilelength(d1_Piggy_fp)) {
2362 case D1_MAC_PIGSIZE:
2363 case D1_MAC_SHARE_PIGSIZE:
2364 if (bmh->flags & BM_FLAG_RLE)
2365 rle_swap_0_255(bitmap);
2369 if (bmh->flags & BM_FLAG_RLE)
2370 rle_remap(bitmap, colormap);
2372 gr_remap_bitmap_good(bitmap, d1_palette, TRANSPARENCY_COLOR, -1);
2373 if (bmh->flags & BM_FLAG_RLE) { // size of bitmap could have changed!
2375 memcpy(&new_size, bitmap->bm_data, 4);
2377 *next_bitmap += new_size - zsize;
2379 Assert( zsize + JUST_IN_CASE >= new_size );
2380 bitmap->bm_data = d_realloc(bitmap->bm_data, new_size);
2381 Assert(bitmap->bm_data);
2386 #define D1_MAX_TEXTURES 800
2387 #define D1_MAX_TMAP_NUM 1630 // 1621 in descent.pig Mac registered
2389 /* the inverse of the Textures array, for descent 1.
2390 * "Textures" looks up a d2 bitmap index given a d2 tmap_num
2391 * "d1_tmap_nums" looks up a d1 tmap_num given a d1 bitmap. "-1" means "None"
2393 short *d1_tmap_nums = NULL;
2395 void free_d1_tmap_nums() {
2397 d_free(d1_tmap_nums);
2398 d1_tmap_nums = NULL;
2402 void bm_read_d1_tmap_nums(CFILE *d1pig)
2406 free_d1_tmap_nums();
2407 cfseek(d1pig, 8, SEEK_SET);
2408 MALLOC(d1_tmap_nums, short, D1_MAX_TMAP_NUM);
2409 for (i = 0; i < D1_MAX_TMAP_NUM; i++)
2410 d1_tmap_nums[i] = -1;
2411 for (i = 0; i < D1_MAX_TEXTURES; i++) {
2412 d1_index = cfile_read_short(d1pig);
2413 Assert(d1_index >= 0 && d1_index < D1_MAX_TMAP_NUM);
2414 d1_tmap_nums[d1_index] = i;
2416 atexit(free_d1_tmap_nums);
2419 /* If the given d1_index is the index of a bitmap we have to load
2420 * (because it is unique to descent 1), then returns the d2_index that
2421 * the given d1_index replaces.
2422 * Returns -1 if the given d1_index is not unique to descent 1.
2424 short d2_index_for_d1_index(short d1_index)
2426 Assert(d1_index >= 0 && d1_index < D1_MAX_TMAP_NUM);
2427 if (! d1_tmap_nums || d1_tmap_nums[d1_index] == -1
2428 || ! d1_tmap_num_unique(d1_tmap_nums[d1_index]))
2431 return Textures[convert_d1_tmap_num(d1_tmap_nums[d1_index])].index;
2434 #define D1_BITMAPS_SIZE 300000
2435 void load_d1_bitmap_replacements()
2437 CFILE * d1_Piggy_fp;
2438 DiskBitmapHeader bmh;
2439 int pig_data_start, bitmap_header_start, bitmap_data_start;
2441 short d1_index, d2_index;
2443 ubyte colormap[256];
2444 ubyte d1_palette[256*3];
2447 d1_Piggy_fp = cfopen( D1_PIGFILE, "rb" );
2449 #define D1_PIG_LOAD_FAILED "Failed loading " D1_PIGFILE
2451 Warning(D1_PIG_LOAD_FAILED);
2455 //first, free up data allocated for old bitmaps
2456 free_bitmap_replacements();
2458 Assert( get_d1_colormap( d1_palette, colormap ) == 0 );
2460 switch (cfilelength(d1_Piggy_fp)) {
2461 case D1_SHARE_BIG_PIGSIZE:
2462 case D1_SHARE_10_PIGSIZE:
2463 case D1_SHARE_PIGSIZE:
2464 case D1_10_BIG_PIGSIZE:
2467 Warning(D1_PIG_LOAD_FAILED ". descent.pig of v1.0 and all PC shareware versions not supported.");
2471 Warning("Unknown size for " D1_PIGFILE);
2475 case D1_OEM_PIGSIZE:
2476 case D1_MAC_PIGSIZE:
2477 case D1_MAC_SHARE_PIGSIZE:
2478 pig_data_start = cfile_read_int(d1_Piggy_fp );
2479 bm_read_d1_tmap_nums(d1_Piggy_fp); //was: bm_read_all_d1(fp);
2480 //for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2484 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2485 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2487 int N_sounds = cfile_read_int(d1_Piggy_fp);
2488 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2489 + N_sounds * sizeof(DiskSoundHeader);
2490 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2491 bitmap_data_start = bitmap_header_start + header_size;
2494 MALLOC( Bitmap_replacement_data, ubyte, D1_BITMAPS_SIZE);
2495 if (!Bitmap_replacement_data) {
2496 Warning(D1_PIG_LOAD_FAILED);
2499 atexit(free_bitmap_replacements);
2501 next_bitmap = Bitmap_replacement_data;
2503 for (d1_index = 1; d1_index <= N_bitmaps; d1_index++ ) {
2504 d2_index = d2_index_for_d1_index(d1_index);
2505 // only change bitmaps which are unique to d1
2506 if (d2_index != -1) {
2507 cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2508 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2510 bitmap_read_d1( &GameBitmaps[d2_index], d1_Piggy_fp, bitmap_data_start, &bmh, &next_bitmap, d1_palette, colormap );
2511 Assert(next_bitmap - Bitmap_replacement_data < D1_BITMAPS_SIZE);
2512 GameBitmapOffset[d2_index] = 0; // don't try to read bitmap from current d2 pigfile
2513 GameBitmapFlags[d2_index] = bmh.flags;
2515 if ( (p = strchr(AllBitmaps[d2_index].name, '#')) /* d2 BM is animated */
2516 && !(bmh.dflags & DBM_FLAG_ABM) ) { /* d1 bitmap is not animated */
2517 int i, len = p - AllBitmaps[d2_index].name;
2518 for (i = 0; i < Num_bitmap_files; i++)
2519 if (i != d2_index && ! memcmp(AllBitmaps[d2_index].name, AllBitmaps[i].name, len)) {
2520 GameBitmaps[i] = GameBitmaps[d2_index];
2521 GameBitmapOffset[i] = 0;
2522 GameBitmapFlags[i] = bmh.flags;
2528 cfclose(d1_Piggy_fp);
2530 last_palette_loaded_pig[0]= 0; //force pig re-load
2532 texmerge_flush(); //for re-merging with new textures
2536 extern int extra_bitmap_num;
2539 * Find and load the named bitmap from descent.pig
2540 * similar to read_extra_bitmap_iff
2542 bitmap_index read_extra_bitmap_d1_pig(char *name)
2544 bitmap_index bitmap_num;
2545 grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2547 bitmap_num.index = 0;
2551 DiskBitmapHeader bmh;
2552 int pig_data_start, bitmap_header_start, bitmap_data_start;
2554 ubyte colormap[256];
2555 ubyte d1_palette[256*3];
2557 d1_Piggy_fp = cfopen(D1_PIGFILE, "rb");
2561 Warning(D1_PIG_LOAD_FAILED);
2565 Assert( get_d1_colormap( d1_palette, colormap ) == 0 );
2567 switch (cfilelength(d1_Piggy_fp)) {
2568 case D1_SHARE_BIG_PIGSIZE:
2569 case D1_SHARE_10_PIGSIZE:
2570 case D1_SHARE_PIGSIZE:
2571 case D1_10_BIG_PIGSIZE:
2576 Warning("Unknown size for " D1_PIGFILE);
2580 case D1_OEM_PIGSIZE:
2581 case D1_MAC_PIGSIZE:
2582 case D1_MAC_SHARE_PIGSIZE:
2583 pig_data_start = cfile_read_int(d1_Piggy_fp );
2588 cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2589 N_bitmaps = cfile_read_int(d1_Piggy_fp);
2591 int N_sounds = cfile_read_int(d1_Piggy_fp);
2592 int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2593 + N_sounds * sizeof(DiskSoundHeader);
2594 bitmap_header_start = pig_data_start + 2 * sizeof(int);
2595 bitmap_data_start = bitmap_header_start + header_size;
2598 for (i = 1; i <= N_bitmaps; i++)
2600 DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2601 if (!strnicmp(bmh.name, name, 8))
2605 if (strnicmp(bmh.name, name, 8))
2607 con_printf(CON_DEBUG, "could not find bitmap %s\n", name);
2611 bitmap_read_d1( new, d1_Piggy_fp, bitmap_data_start, &bmh, 0, d1_palette, colormap );
2613 cfclose(d1_Piggy_fp);
2616 new->avg_color = 0; //compute_average_pixel(new);
2618 bitmap_num.index = extra_bitmap_num;
2620 GameBitmaps[extra_bitmap_num++] = *new;
2626 #ifndef FAST_FILE_IO
2628 * reads a bitmap_index structure from a CFILE
2630 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2632 bi->index = cfile_read_short(fp);
2636 * reads n bitmap_index structs from a CFILE
2638 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2642 for (i = 0; i < n; i++)
2643 bi[i].index = cfile_read_short(fp);
2646 #endif // FAST_FILE_IO