1 /* $Id: piggy.c,v 1.31 2003/03/29 22:35:00 btb Exp $ */
2 /*
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.
13 */
14 
15 /*
16  *
17  * Functions for managing the pig files.
18  *
19  * Old Log:
20  * Revision 1.16  1995/11/09  17:27:47  allender
21  * put in missing quote on new gauge name
22  *
23  * Revision 1.15  1995/11/08  17:28:03  allender
24  * add PC gauges to gauge list of non-substitutatble bitmaps
25  *
26  * Revision 1.14  1995/11/08  15:14:49  allender
27  * fixed horrible bug where the piggy cache size was incorrect
28  * for mac shareware
29  *
30  * Revision 1.13  1995/11/03  12:53:37  allender
31  * shareware changes
32  *
33  * Revision 1.12  1995/10/21  22:25:14  allender
34  * added bald guy cheat
35  *
36  * Revision 1.11  1995/10/20  22:42:15  allender
37  * changed load path of descent.pig to :data:descent.pig
38  *
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
42  *
43  * Revision 1.9  1995/09/13  08:48:01  allender
44  * added lower memory requirement to load alternate bitmaps
45  *
46  * Revision 1.8  1995/08/16  09:39:13  allender
47  * moved "loading" text up a little
48  *
49  * Revision 1.7  1995/08/08  13:54:26  allender
50  * added macsys header file
51  *
52  * Revision 1.6  1995/07/12  12:49:56  allender
53  * total hack for bitmaps > 512 bytes wide -- check these by name
54  *
55  * Revision 1.5  1995/07/05  16:47:05  allender
56  * kitchen stuff
57  *
58  * Revision 1.4  1995/06/23  08:55:28  allender
59  * make "loading data" text y loc based off of curcanv
60  *
61  * Revision 1.3  1995/06/08  14:08:52  allender
62  * PPC aligned data sets
63  *
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
67  *
68  * Revision 1.1  1995/05/16  15:29:51  allender
69  * Initial revision
70  *
71  * Revision 2.10  1995/10/07  13:17:26  john
72  * Made all bitmaps paged out by default.
73  *
74  * Revision 2.9  1995/04/14  14:05:24  john
75  * *** empty log message ***
76  *
77  * Revision 2.8  1995/04/12  13:39:37  john
78  * Fixed bug with -lowmem not working.
79  *
80  * Revision 2.7  1995/03/29  23:23:17  john
81  * Fixed major bug with sounds not building into pig right.
82  *
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
85  *
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.
89  *
90  * Revision 2.4  1995/03/14  16:22:27  john
91  * Added cdrom alternate directory stuff.
92  *
93  * Revision 2.3  1995/03/06  15:23:20  john
94  * New screen techniques.
95  *
96  * Revision 2.2  1995/02/27  13:13:40  john
97  * Removed floating point.
98  *
99  * Revision 2.1  1995/02/27  12:31:25  john
100  * Made work without editor.
101  *
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.
105  *
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.
109  *
110  * Revision 1.84  1995/02/09  12:50:59  john
111  * Bullet-proofed the piggy loading code.
112  *
113  * Revision 1.83  1995/02/07  17:08:51  john
114  * Added some error handling stuff instead of asserts.
115  *
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.
122  *
123  * Revision 1.81  1995/02/02  21:56:39  matt
124  * Added data for new gauge bitmaps
125  *
126  * Revision 1.80  1995/02/01  23:31:57  john
127  * Took out loading bar.
128  *
129  * Revision 1.79  1995/01/28  15:13:18  allender
130  * bumped up Piggy_bitmap_cache_size
131  *
132  * Revision 1.78  1995/01/26  12:30:43  john
133  * Took out prev.
134  *
135  * Revision 1.77  1995/01/26  12:12:17  john
136  * Made buffer be big for bitmaps.
137  *
138  * Revision 1.76  1995/01/25  20:15:38  john
139  * Made editor allocate all mem.
140  *
141  * Revision 1.75  1995/01/25  14:52:56  john
142  * Made bitmap buffer be 1.5 MB.
143  *
144  * Revision 1.74  1995/01/22  16:03:19  mike
145  * localization.
146  *
147  * Revision 1.73  1995/01/22  15:58:36  mike
148  * localization
149  *
150  * Revision 1.72  1995/01/18  20:51:20  john
151  * Took out warnings.
152  *
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.
156  *
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.
160  *
161  * Revision 1.69  1995/01/18  10:07:51  john
162  *
163  * Took out debugging mprintfs.
164  *
165  * Revision 1.68  1995/01/17  14:27:42  john
166  * y
167  *
168  * Revision 1.67  1995/01/17  12:14:39  john
169  * Made walls, object explosion vclips load at level start.
170  *
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.
174  *
175  * Revision 1.65  1995/01/15  11:56:28  john
176  * Working version of paging.
177  *
178  * Revision 1.64  1995/01/14  19:17:07  john
179  * First version of new bitmap paging code.
180  *
181  * Revision 1.63  1994/12/15  12:26:44  john
182  * Added -nolowmem function.
183  *
184  * Revision 1.62  1994/12/14  21:12:26  john
185  * Fixed bug with page fault when exiting and using
186  * -nosound.
187  *
188  * Revision 1.61  1994/12/14  11:35:31  john
189  * Evened out thermometer for pig read.
190  *
191  * Revision 1.60  1994/12/14  10:51:00  john
192  * Sped up sound loading.
193  *
194  * Revision 1.59  1994/12/14  10:12:08  john
195  * Sped up pig loading.
196  *
197  * Revision 1.58  1994/12/13  09:14:47  john
198  * *** empty log message ***
199  *
200  * Revision 1.57  1994/12/13  09:12:57  john
201  * Made the bar always fill up.
202  *
203  * Revision 1.56  1994/12/13  03:49:08  john
204  * Made -lowmem not load the unnecessary bitmaps.
205  *
206  * Revision 1.55  1994/12/06  16:06:35  john
207  * Took out piggy sorting.
208  *
209  * Revision 1.54  1994/12/06  15:11:14  john
210  * Fixed bug with reading pigs.
211  *
212  * Revision 1.53  1994/12/06  14:14:47  john
213  * Added code to set low mem based on memory.
214  *
215  * Revision 1.52  1994/12/06  14:01:10  john
216  * Fixed bug that was causing -lowmem all the time..
217  *
218  * Revision 1.51  1994/12/06  13:33:48  john
219  * Added lowmem option.
220  *
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.
223  *
224  * Revision 1.49  1994/12/05  12:17:44  john
225  * Added code that locks/unlocks digital sounds on demand.
226  *
227  * Revision 1.48  1994/12/05  11:39:03  matt
228  * Fixed little mistake
229  *
230  * Revision 1.47  1994/12/05  09:29:22  john
231  * Added clength to the sound field.
232  *
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.
236  *
237  * Revision 1.45  1994/12/03  14:17:00  john
238  * Took out my debug mprintf.
239  *
240  * Revision 1.44  1994/12/03  13:32:37  john
241  * Fixed bug with offscreen bitmap.
242  *
243  * Revision 1.43  1994/12/03  13:07:13  john
244  * Made the pig read/write compressed sounds.
245  *
246  * Revision 1.42  1994/12/03  11:48:51  matt
247  * Added option to not dump sounds to pigfile
248  *
249  * Revision 1.41  1994/12/02  20:02:20  matt
250  * Made sound files constant match constant for table
251  *
252  * Revision 1.40  1994/11/29  11:03:09  adam
253  * upped # of sounds
254  *
255  * Revision 1.39  1994/11/27  23:13:51  matt
256  * Made changes for new mprintf calling convention
257  *
258  * Revision 1.38  1994/11/20  18:40:34  john
259  * MAde the piggy.lst and piggy.all not dump for release.
260  *
261  * Revision 1.37  1994/11/19  23:54:45  mike
262  * up number of bitmaps for shareware version.
263  *
264  * Revision 1.36  1994/11/19  19:53:05  mike
265  * change MAX_BITMAP_FILES
266  *
267  * Revision 1.35  1994/11/19  10:42:56  matt
268  * Increased number of bitmaps for non-shareware version
269  *
270  * Revision 1.34  1994/11/19  09:11:52  john
271  * Added avg_color to bitmaps saved in pig.
272  *
273  * Revision 1.33  1994/11/19  00:07:05  john
274  * Fixed bug with 8 char sound filenames not getting read from pig.
275  *
276  * Revision 1.32  1994/11/18  22:24:54  john
277  * Added -bigpig command line that doesn't rle your pig.
278  *
279  * Revision 1.31  1994/11/18  21:56:53  john
280  * Added a better, leaner pig format.
281  *
282  * Revision 1.30  1994/11/16  12:06:16  john
283  * Fixed bug with calling .bbms abms.
284  *
285  * Revision 1.29  1994/11/16  12:00:56  john
286  * Added piggy.all dump.
287  *
288  * Revision 1.28  1994/11/10  21:16:02  adam
289  * nothing important
290  *
291  * Revision 1.27  1994/11/10  13:42:00  john
292  * Made sounds not lock down if using -nosound.
293  *
294  * Revision 1.26  1994/11/09  19:55:40  john
295  * Added full rle support with texture rle caching.
296  *
297  * Revision 1.25  1994/11/09  16:36:42  john
298  * First version with RLE bitmaps in Pig.
299  *
300  * Revision 1.24  1994/10/27  19:42:59  john
301  * Disable the piglet option.
302  *
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.
307  *
308  * Revision 1.22  1994/10/25  13:11:42  john
309  * Made the sounds sort. Dumped piggy.lst.
310  *
311  * Revision 1.21  1994/10/06  17:06:23  john
312  * Took out rle stuff.
313  *
314  * Revision 1.20  1994/10/06  15:45:36  adam
315  * bumped MAX_BITMAP_FILES again!
316  *
317  * Revision 1.19  1994/10/06  11:01:17  yuan
318  * Upped MAX_BITMAP_FILES
319  *
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
325  * a bit.
326  *
327  * Revision 1.17  1994/10/04  20:03:13  matt
328  * Upped maximum number of bitmaps
329  *
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.
333  *
334  * Revision 1.15  1994/09/28  11:30:55  john
335  * changed inferno.pig to descent.pig, changed the way it
336  * is read.
337  *
338  * Revision 1.14  1994/09/22  16:14:17  john
339  * Redid intro sequecing.
340  *
341  * Revision 1.13  1994/09/19  14:42:47  john
342  * Locked down sounds with Virtual memory.
343  *
344  * Revision 1.12  1994/09/10  17:31:52  mike
345  * Increase number of loadable bitmaps.
346  *
347  * Revision 1.11  1994/09/01  19:32:49  mike
348  * Boost texture map allocation.
349  *
350  * Revision 1.10  1994/08/16  11:51:02  john
351  * Added grwased pigs.
352  *
353  * Revision 1.9  1994/07/06  09:18:03  adam
354  * upped bitmap #s
355  *
356  * Revision 1.8  1994/06/20  22:02:15  matt
357  * Fixed bug from last change
358  *
359  * Revision 1.7  1994/06/20  21:33:18  matt
360  * Made bm.h not include sounds.h, to reduce dependencies
361  *
362  * Revision 1.6  1994/06/20  16:52:19  john
363  * cleaned up init output a bit.
364  *
365  * Revision 1.5  1994/06/08  14:20:57  john
366  * Made piggy dump before going into game.
367  *
368  * Revision 1.4  1994/06/02  18:59:22  matt
369  * Clear selector field of bitmap loaded from pig file
370  *
371  * Revision 1.3  1994/05/06  15:31:41  john
372  * Made name field a bit longer.
373  *
374  * Revision 1.2  1994/05/06  13:02:44  john
375  * Added piggy stuff; worked on supertransparency
376  *
377  * Revision 1.1  1994/05/06  11:47:26  john
378  * Initial revision
379  *
380  *
381  */
382 
383 
384 #ifdef HAVE_CONFIG_H
385 #include <conf.h>
386 #endif
387 
388 #ifdef RCS
389 static char rcsid[] = "$Id: piggy.c,v 1.31 2003/03/29 22:35:00 btb Exp $";
390 #endif
391 
392 
393 #include <stdio.h>
394 #include <string.h>
395 
396 #include "pstypes.h"
397 #include "strutil.h"
398 #include "inferno.h"
399 #include "gr.h"
400 #include "u_mem.h"
401 #include "iff.h"
402 #include "mono.h"
403 #include "error.h"
404 #include "sounds.h"
405 #include "songs.h"
406 #include "bm.h"
407 #include "bmread.h"
408 #include "hash.h"
409 #include "args.h"
410 #include "palette.h"
411 #include "gamefont.h"
412 #include "rle.h"
413 #include "screens.h"
414 #include "piggy.h"
415 #include "texmerge.h"
416 #include "paging.h"
417 #include "game.h"
418 #include "text.h"
419 #include "cfile.h"
420 #include "newmenu.h"
421 #include "byteswap.h"
422 #include "findfile.h"
423 #include "makesig.h"
424 
425 #ifndef MACINTOSH
426 //	#include "unarj.h"
427 #else
428 	#include <Strings.h>		// MacOS Toolbox header
429 	#include <Files.h>
430 	#include <unistd.h>
431 #endif
432 
433 //#define NO_DUMP_SOUNDS        1   //if set, dump bitmaps but not sounds
434 
435 #define DEFAULT_PIGFILE_REGISTERED      "groupa.pig"
436 #define DEFAULT_PIGFILE_SHAREWARE       "d2demo.pig"
437 #define DEFAULT_HAMFILE_REGISTERED      "descent2.ham"
438 #define DEFAULT_HAMFILE_SHAREWARE       "d2demo.ham"
439 
440 #define D1_PALETTE "palette.256"
441 
442 #define DEFAULT_PIGFILE (cfexist(DEFAULT_PIGFILE_REGISTERED)?DEFAULT_PIGFILE_REGISTERED:DEFAULT_PIGFILE_SHAREWARE)
443 #define DEFAULT_HAMFILE (cfexist(DEFAULT_HAMFILE_REGISTERED)?DEFAULT_HAMFILE_REGISTERED:DEFAULT_HAMFILE_SHAREWARE)
444 #define DEFAULT_SNDFILE ((Piggy_hamfile_version < 3)?DEFAULT_HAMFILE_SHAREWARE:(digi_sample_rate==SAMPLE_RATE_22K)?"descent2.s22":"descent2.s11")
445 
446 #define MAC_ALIEN1_PIGSIZE      5013035
447 #define MAC_ALIEN2_PIGSIZE      4909916
448 #define MAC_FIRE_PIGSIZE        4969035
449 #define MAC_GROUPA_PIGSIZE      4929684 // also used for mac shareware
450 #define MAC_ICE_PIGSIZE         4923425
451 #define MAC_WATER_PIGSIZE       4832403
452 
453 ubyte *BitmapBits = NULL;
454 ubyte *SoundBits = NULL;
455 
456 typedef struct BitmapFile {
457 	char    name[15];
458 } BitmapFile;
459 
460 typedef struct SoundFile {
461 	char    name[15];
462 } SoundFile;
463 
464 hashtable AllBitmapsNames;
465 hashtable AllDigiSndNames;
466 
467 int Num_bitmap_files = 0;
468 int Num_sound_files = 0;
469 
470 digi_sound GameSounds[MAX_SOUND_FILES];
471 int SoundOffset[MAX_SOUND_FILES];
472 grs_bitmap GameBitmaps[MAX_BITMAP_FILES];
473 
474 alias alias_list[MAX_ALIASES];
475 int Num_aliases=0;
476 
477 int Must_write_hamfile = 0;
478 int Num_bitmap_files_new = 0;
479 int Num_sound_files_new = 0;
480 BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
481 static SoundFile AllSounds[ MAX_SOUND_FILES ];
482 
483 int Piggy_hamfile_version = 0;
484 
485 int piggy_low_memory = 0;
486 
487 int Piggy_bitmap_cache_size = 0;
488 int Piggy_bitmap_cache_next = 0;
489 ubyte * Piggy_bitmap_cache_data = NULL;
490 static int GameBitmapOffset[MAX_BITMAP_FILES];
491 static ubyte GameBitmapFlags[MAX_BITMAP_FILES];
492 ushort GameBitmapXlat[MAX_BITMAP_FILES];
493 
494 #define PIGGY_BUFFER_SIZE (2400*1024)
495 
496 #ifdef MACINTOSH
497 #define PIGGY_SMALL_BUFFER_SIZE (1400*1024)		// size of buffer when piggy_low_memory is set
498 
499 #ifdef SHAREWARE
500 #undef PIGGY_BUFFER_SIZE
501 #undef PIGGY_SMALL_BUFFER_SIZE
502 
503 #define PIGGY_BUFFER_SIZE (2000*1024)
504 #define PIGGY_SMALL_BUFFER_SIZE (1100 * 1024)
505 #endif		// SHAREWARE
506 
507 #endif
508 
509 int piggy_page_flushed = 0;
510 
511 #define DBM_FLAG_ABM            64
512 
513 ubyte BigPig = 0;
514 
515 #ifdef MACINTOSH
516 	extern short 	cd_VRefNum;
517 	extern void		ConcatPStr(StringPtr dst, StringPtr src);
518 	extern int		ConvertPToCStr(StringPtr inPStr, char* outCStrBuf);
519 	extern int		ConvertCToPStr(char* inCStr, StringPtr outPStrBuf);
520 #endif
521 
522 int piggy_is_substitutable_bitmap( char * name, char * subst_name );
523 
524 #ifdef EDITOR
525 void piggy_write_pigfile(char *filename);
526 static void write_int(int i,FILE *file);
527 #endif
528 
swap_0_255(grs_bitmap * bmp)529 void swap_0_255(grs_bitmap *bmp)
530 {
531 	int i;
532 
533 	for (i = 0; i < bmp->bm_h * bmp->bm_w; i++) {
534 		if(bmp->bm_data[i] == 0)
535 			bmp->bm_data[i] = 255;
536 		else if (bmp->bm_data[i] == 255)
537 			bmp->bm_data[i] = 0;
538 	}
539 }
540 
piggy_register_bitmap(grs_bitmap * bmp,char * name,int in_file)541 bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
542 {
543 	bitmap_index temp;
544 	Assert( Num_bitmap_files < MAX_BITMAP_FILES );
545 
546 	temp.index = Num_bitmap_files;
547 
548 	if (!in_file)   {
549 #ifdef EDITOR
550 		if ( FindArg("-macdata") )
551 			swap_0_255( bmp );
552 #endif
553 		if ( !BigPig )  gr_bitmap_rle_compress( bmp );
554 		Num_bitmap_files_new++;
555 	}
556 
557 	strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
558 	hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
559 	GameBitmaps[Num_bitmap_files] = *bmp;
560 	if ( !in_file ) {
561 		GameBitmapOffset[Num_bitmap_files] = 0;
562 		GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
563 	}
564 	Num_bitmap_files++;
565 
566 	return temp;
567 }
568 
piggy_register_sound(digi_sound * snd,char * name,int in_file)569 int piggy_register_sound( digi_sound * snd, char * name, int in_file )
570 {
571 	int i;
572 
573 	Assert( Num_sound_files < MAX_SOUND_FILES );
574 
575 	strncpy( AllSounds[Num_sound_files].name, name, 12 );
576 	hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
577 	GameSounds[Num_sound_files] = *snd;
578 	if ( !in_file ) {
579 		SoundOffset[Num_sound_files] = 0;
580 	}
581 
582 	i = Num_sound_files;
583 
584 	if (!in_file)
585 		Num_sound_files_new++;
586 
587 	Num_sound_files++;
588 	return i;
589 }
590 
piggy_find_bitmap(char * name)591 bitmap_index piggy_find_bitmap( char * name )
592 {
593 	bitmap_index bmp;
594 	int i;
595 	char *t;
596 
597 	bmp.index = 0;
598 
599 	if ((t=strchr(name,'#'))!=NULL)
600 		*t=0;
601 
602 	for (i=0;i<Num_aliases;i++)
603 		if (stricmp(name,alias_list[i].alias_name)==0) {
604 			if (t) {                //extra stuff for ABMs
605 				static char temp[FILENAME_LEN];
606 				_splitpath(alias_list[i].file_name, NULL, NULL, temp, NULL );
607 				name = temp;
608 				strcat(name,"#");
609 				strcat(name,t+1);
610 			}
611 			else
612 				name=alias_list[i].file_name;
613 			break;
614 		}
615 
616 	if (t)
617 		*t = '#';
618 
619 	i = hashtable_search( &AllBitmapsNames, name );
620 	Assert( i != 0 );
621 	if ( i < 0 )
622 		return bmp;
623 
624 	bmp.index = i;
625 	return bmp;
626 }
627 
piggy_find_sound(char * name)628 int piggy_find_sound( char * name )
629 {
630 	int i;
631 
632 	i = hashtable_search( &AllDigiSndNames, name );
633 
634 	if ( i < 0 )
635 		return 255;
636 
637 	return i;
638 }
639 
640 CFILE * Piggy_fp = NULL;
641 
642 #define FILENAME_LEN 13
643 
644 char Current_pigfile[FILENAME_LEN] = "";
645 
piggy_close_file()646 void piggy_close_file()
647 {
648 	if ( Piggy_fp ) {
649 		cfclose( Piggy_fp );
650 		Piggy_fp        = NULL;
651 		Current_pigfile[0] = 0;
652 	}
653 }
654 
655 int Pigfile_initialized=0;
656 
657 #define PIGFILE_ID              MAKE_SIG('G','I','P','P') //PPIG
658 #define PIGFILE_VERSION         2
659 
660 extern char CDROM_dir[];
661 
662 int request_cd(void);
663 
664 
665 #ifdef MACINTOSH
666 
667 //copies a pigfile from the CD to the current dir
668 //retuns file handle of new pig
copy_pigfile_from_cd(char * filename)669 CFILE *copy_pigfile_from_cd(char *filename)		// MACINTOSH VERSION
670 {
671 	// C Stuff
672 	char			sourcePathAndFileCStr[255] = "";
673 	char			destPathAndFileCStr[255]	= "";
674 	FILEFINDSTRUCT	find;
675 	FILE*			sourceFile	= NULL;
676 	FILE*			destFile	= NULL;
677 	const int		BUF_SIZE = 4096;
678 	ubyte 			buf[BUF_SIZE];
679 
680 	// Mac Stuff
681 	Str255			sourcePathAndFilePStr = "\p";
682 	Str255			destPathAndFilePStr = "\p";
683 	Str255			pigfileNamePStr = "\p";
684 	HParamBlockRec	theSourcePigHFSParams;
685 	HParamBlockRec	theDestPigHFSParams;
686 	OSErr			theErr = noErr;
687 	char			oldDirCStr[255] = "";
688 
689 	getcwd(oldDirCStr, 255);
690 
691 	show_boxed_message("Copying bitmap data from CD...");
692 	gr_palette_load(gr_palette);    //I don't think this line is really needed
693 
694 	chdir(":Data");
695 	//First, delete all PIG files currently in the directory
696 	if( !FileFindFirst( "*.pig", &find ) )
697 	{
698 		do
699 		{
700 			remove(find.name);
701 		} while( !FileFindNext( &find ) );
702 
703 		FileFindClose();
704 	}
705 	chdir(oldDirCStr);
706 
707 	//Now, copy over new pig
708 	songs_stop_redbook();           //so we can read off the cd
709 
710 	// make the source path "<cd volume>:Data:filename.pig"
711 //MWA	ConvertCToPStr(filename, pigfileNamePStr);
712 
713 //MWA	ConcatPStr(sourcePathAndFilePStr, "\pDescent II:Data:");	// volume ID is cd_VRefNum
714 //MWA	ConcatPStr(sourcePathAndFilePStr, pigfileNamePStr);
715 
716 	strupr(filename);
717 	strcpy(sourcePathAndFileCStr, "Descent II:Data:");
718 	strcat(sourcePathAndFileCStr, filename);
719 
720 	// make the destination path "<default directory>:Data:filename.pig"
721 //MWA	ConcatPStr(destPathAndFilePStr, "\p:Data:");
722 //MWA	ConcatPStr(destPathAndFilePStr, pigfileNamePStr);
723 //MWA	ConvertPToCStr(sourcePathAndFilePStr, sourcePathAndFileCStr);
724 //MWA	ConvertPToCStr(destPathAndFilePStr, destPathAndFileCStr);
725 
726 	strcpy(destPathAndFileCStr, ":Data:");
727 	strcat(destPathAndFileCStr, filename);
728 
729 	strcpy(sourcePathAndFilePStr, sourcePathAndFileCStr);
730 	strcpy(destPathAndFilePStr, destPathAndFileCStr);
731 	c2pstr(sourcePathAndFilePStr);
732 	c2pstr(destPathAndFilePStr);
733 
734 	do {
735 		// Open the source file
736 		sourceFile = fopen(sourcePathAndFileCStr,"rb");
737 
738 		if (!sourceFile) {
739 
740 			if (request_cd() == -1)
741 				Error("Cannot load file <%s> from CD",filename);
742 		}
743 
744 	} while (!sourceFile);
745 
746 
747 	// Get the time stamp from the source file
748 	theSourcePigHFSParams.fileParam.ioCompletion 	= nil;
749 	theSourcePigHFSParams.fileParam.ioNamePtr		= sourcePathAndFilePStr;
750 	theSourcePigHFSParams.fileParam.ioVRefNum		= cd_VRefNum;
751 	theSourcePigHFSParams.fileParam.ioFDirIndex	= 0;
752 	theSourcePigHFSParams.fileParam.ioDirID		= 0;
753 
754 	theErr = PBHGetFInfo(&theSourcePigHFSParams, false);
755 	if (theErr != noErr)
756 	{
757 		// Error getting file time stamp!! Why? JTS
758 		Error("Can't get old file time stamp: <%s>\n", sourcePathAndFileCStr);
759 	}
760 
761 	// Copy the file over
762 	// C Stuff......
763 
764 	// Open the destination file
765 	destFile = fopen(destPathAndFileCStr,"wb");
766 	if (!destFile)
767 	{
768 		Error("Cannot create file: <%s>\n", destPathAndFileCStr);
769 	}
770 
771 	// Copy bytes until the end of the source file
772 	while (!feof(sourceFile))
773 	{
774 		int bytes_read;
775 		int x;
776 
777 		bytes_read = fread(buf,1,BUF_SIZE,sourceFile);
778 		if (ferror(sourceFile))
779 			Error("Cannot read from file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
780 
781 // Assert is bogus		Assert(bytes_read == BUF_SIZE || feof(sourceFile));
782 
783 		fwrite(buf,1,bytes_read,destFile);
784 		if (ferror(destFile))
785 			Error("Cannot write to file <%s>: %s",destPathAndFileCStr, strerror(errno));
786 	}
787 
788 	// close the source/dest files
789 	if (fclose(sourceFile))
790 		Error("Error closing file <%s>: %s", sourcePathAndFileCStr, strerror(errno));
791 	if (fclose(destFile))
792 		Error("Error closing file <%s>: %s", destPathAndFileCStr, strerror(errno));
793 
794 	// Get the current hfs data for the new file
795 	theDestPigHFSParams.fileParam.ioCompletion 	= nil;
796 	theDestPigHFSParams.fileParam.ioNamePtr		= destPathAndFilePStr;
797 	theDestPigHFSParams.fileParam.ioVRefNum		= 0;
798 	theDestPigHFSParams.fileParam.ioFDirIndex	= 0;
799 	theDestPigHFSParams.fileParam.ioDirID		= 0;
800 	theErr = PBHGetFInfo(&theDestPigHFSParams, false);
801 	if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
802 	{
803 		// Error getting file time stamp!! Why? JTS
804 		Error("Can't get destination pig file information: <%s>\n", destPathAndFileCStr);
805 	}
806 
807 	// Reset this data !!!!! or else the relative pathname won't work, could use just filename instead but, oh well.
808 	theDestPigHFSParams.fileParam.ioNamePtr		= destPathAndFilePStr;
809 	theDestPigHFSParams.fileParam.ioVRefNum		= 0;
810 	theDestPigHFSParams.fileParam.ioFDirIndex	= 0;
811 	theDestPigHFSParams.fileParam.ioDirID		= 0;
812 
813 	// Copy the time stamp from the source file info
814 	theDestPigHFSParams.fileParam.ioFlCrDat	= theSourcePigHFSParams.fileParam.ioFlCrDat;
815 	theDestPigHFSParams.fileParam.ioFlMdDat	= theSourcePigHFSParams.fileParam.ioFlMdDat;
816 	theDestPigHFSParams.fileParam.ioFlFndrInfo.fdType = 'PGGY';
817 	theDestPigHFSParams.fileParam.ioFlFndrInfo.fdCreator = 'DCT2';
818 
819 	// Set the dest file's time stamp to the source file's time stamp values
820 	theErr = PBHSetFInfo(&theDestPigHFSParams, false);
821 
822 	if ((theErr != noErr) || (theDestPigHFSParams.fileParam.ioResult != noErr))
823 	{
824 		Error("Can't set destination pig file time stamp: <%s>\n", destPathAndFileCStr);
825 	}
826 
827 	theErr = PBHGetFInfo(&theDestPigHFSParams, false);
828 
829 	return cfopen(destPathAndFileCStr, "rb");
830 }
831 
832 #else	//PC Version of copy_pigfile_from_cd is below
833 
834 //copies a pigfile from the CD to the current dir
835 //retuns file handle of new pig
copy_pigfile_from_cd(char * filename)836 CFILE *copy_pigfile_from_cd(char *filename)
837 {
838 	char name[80];
839 	FILEFINDSTRUCT find;
840 	int ret;
841 
842 	return cfopen(filename, "rb");
843 	show_boxed_message("Copying bitmap data from CD...");
844 	gr_palette_load(gr_palette);    //I don't think this line is really needed
845 
846 	//First, delete all PIG files currently in the directory
847 
848 	if( !FileFindFirst( "*.pig", &find ) ) {
849 		do      {
850 			remove(find.name);
851 		} while( !FileFindNext( &find ) );
852 		FileFindClose();
853 	}
854 
855 	//Now, copy over new pig
856 
857 	songs_stop_redbook();           //so we can read off the cd
858 
859 	//new code to unarj file
860 	strcpy(name,CDROM_dir);
861 	strcat(name,"descent2.sow");
862 
863 	do {
864 //		ret = unarj_specific_file(name,filename,filename);
865 // DPH:FIXME
866 
867 		ret = !EXIT_SUCCESS;
868 
869 		if (ret != EXIT_SUCCESS) {
870 
871 			//delete file, so we don't leave partial file
872 			remove(filename);
873 
874 			#ifndef MACINTOSH
875 			if (request_cd() == -1)
876 			#endif
877 				//NOTE LINK TO ABOVE IF
878 				Error("Cannot load file <%s> from CD",filename);
879 		}
880 
881 	} while (ret != EXIT_SUCCESS);
882 
883 	return cfopen(filename, "rb");
884 }
885 
886 #endif // end of ifdef MAC around copy_pigfile_from_cd
887 
888 //initialize a pigfile, reading headers
889 //returns the size of all the bitmap data
piggy_init_pigfile(char * filename)890 void piggy_init_pigfile(char *filename)
891 {
892 	int i;
893 	char temp_name[16];
894 	char temp_name_read[16];
895 	grs_bitmap temp_bitmap;
896 	DiskBitmapHeader bmh;
897 	int header_size, N_bitmaps, data_size, data_start;
898 	#ifdef MACINTOSH
899 	char name[255];		// filename + path for the mac
900 	#endif
901 
902 	piggy_close_file();             //close old pig if still open
903 
904 	//rename pigfile for shareware
905 	if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(filename))
906 		filename = DEFAULT_PIGFILE_SHAREWARE;
907 
908 	#ifndef MACINTOSH
909 		Piggy_fp = cfopen( filename, "rb" );
910 	#else
911 		sprintf(name, ":Data:%s", filename);
912 		Piggy_fp = cfopen( name, "rb" );
913 
914 		#ifdef SHAREWARE	// if we are in the shareware version, we must have the pig by now.
915 			if (Piggy_fp == NULL)
916 			{
917 				Error("Cannot load required file <%s>",name);
918 			}
919 		#endif	// end of if def shareware
920 
921 	#endif
922 
923 	if (!Piggy_fp) {
924 		#ifdef EDITOR
925 			return;         //if editor, ok to not have pig, because we'll build one
926 		#else
927 			Piggy_fp = copy_pigfile_from_cd(filename);
928 		#endif
929 	}
930 
931 	if (Piggy_fp) {                         //make sure pig is valid type file & is up-to-date
932 		int pig_id,pig_version;
933 
934 		pig_id = cfile_read_int(Piggy_fp);
935 		pig_version = cfile_read_int(Piggy_fp);
936 		if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
937 			cfclose(Piggy_fp);              //out of date pig
938 			Piggy_fp = NULL;                        //..so pretend it's not here
939 		}
940 	}
941 
942 	if (!Piggy_fp) {
943 
944 		#ifdef EDITOR
945 			return;         //if editor, ok to not have pig, because we'll build one
946 		#else
947 			Error("Cannot load required file <%s>",filename);
948 		#endif
949 	}
950 
951 	strncpy(Current_pigfile,filename,sizeof(Current_pigfile));
952 
953 	N_bitmaps = cfile_read_int(Piggy_fp);
954 
955 	header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
956 
957 	data_start = header_size + cftell(Piggy_fp);
958 
959 	data_size = cfilelength(Piggy_fp) - data_start;
960 
961 	Num_bitmap_files = 1;
962 
963 	for (i=0; i<N_bitmaps; i++ )    {
964 		DiskBitmapHeader_read(&bmh, Piggy_fp);
965 		memcpy( temp_name_read, bmh.name, 8 );
966 		temp_name_read[8] = 0;
967 		if ( bmh.dflags & DBM_FLAG_ABM )
968 			sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
969 		else
970 			strcpy( temp_name, temp_name_read );
971 		memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
972 		temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
973 		temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
974 		temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
975 		temp_bitmap.avg_color = bmh.avg_color;
976 		temp_bitmap.bm_data = Piggy_bitmap_cache_data;
977 
978 		GameBitmapFlags[i+1] = 0;
979 		if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_TRANSPARENT;
980 		if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_SUPER_TRANSPARENT;
981 		if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i+1] |= BM_FLAG_NO_LIGHTING;
982 		if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i+1] |= BM_FLAG_RLE;
983 		if ( bmh.flags & BM_FLAG_RLE_BIG ) GameBitmapFlags[i+1] |= BM_FLAG_RLE_BIG;
984 
985 		GameBitmapOffset[i+1] = bmh.offset + data_start;
986 		Assert( (i+1) == Num_bitmap_files );
987 		piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
988 	}
989 
990 #ifdef EDITOR
991 	Piggy_bitmap_cache_size = data_size + (data_size/10);   //extra mem for new bitmaps
992 	Assert( Piggy_bitmap_cache_size > 0 );
993 #else
994 	Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
995 	#ifdef MACINTOSH
996 	if (piggy_low_memory)
997 		Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
998 	#endif
999 #endif
1000 	BitmapBits = d_malloc( Piggy_bitmap_cache_size );
1001 	if ( BitmapBits == NULL )
1002 		Error( "Not enough memory to load bitmaps\n" );
1003 	Piggy_bitmap_cache_data = BitmapBits;
1004 	Piggy_bitmap_cache_next = 0;
1005 
1006 	#if defined(MACINTOSH) && defined(SHAREWARE)
1007 //	load_exit_models();
1008 	#endif
1009 
1010 	Pigfile_initialized=1;
1011 }
1012 
1013 #define FILENAME_LEN 13
1014 #define MAX_BITMAPS_PER_BRUSH 30
1015 
1016 extern int compute_average_pixel(grs_bitmap *new);
1017 
1018 //reads in a new pigfile (for new palette)
1019 //returns the size of all the bitmap data
piggy_new_pigfile(char * pigname)1020 void piggy_new_pigfile(char *pigname)
1021 {
1022 	int i;
1023 	char temp_name[16];
1024 	char temp_name_read[16];
1025 	grs_bitmap temp_bitmap;
1026 	DiskBitmapHeader bmh;
1027 	int header_size, N_bitmaps, data_size, data_start;
1028 	int must_rewrite_pig = 0;
1029 	#ifdef MACINTOSH
1030 	char name[255];
1031 	#endif
1032 
1033 	strlwr(pigname);
1034 
1035 	//rename pigfile for shareware
1036 	if (stricmp(DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) == 0 && !cfexist(pigname))
1037 		pigname = DEFAULT_PIGFILE_SHAREWARE;
1038 
1039 	if (strnicmp(Current_pigfile,pigname,sizeof(Current_pigfile))==0)
1040 		return;         //already have correct pig
1041 
1042 	if (!Pigfile_initialized) {                     //have we ever opened a pigfile?
1043 		piggy_init_pigfile(pigname);            //..no, so do initialization stuff
1044 		return;
1045 	}
1046 	else
1047 		piggy_close_file();             //close old pig if still open
1048 
1049 	Piggy_bitmap_cache_next = 0;            //free up cache
1050 
1051 	strncpy(Current_pigfile,pigname,sizeof(Current_pigfile));
1052 
1053 	#ifndef MACINTOSH
1054 		Piggy_fp = cfopen( pigname, "rb" );
1055 	#else
1056 		sprintf(name, ":Data:%s", pigname);
1057 		Piggy_fp = cfopen( name, "rb" );
1058 
1059 		#ifdef SHAREWARE	// if we are in the shareware version, we must have the pig by now.
1060 			if (Piggy_fp == NULL)
1061 			{
1062 				Error("Cannot load required file <%s>",name);
1063 			}
1064 		#endif	// end of if def shareware
1065 	#endif
1066 
1067 	#ifndef EDITOR
1068 	if (!Piggy_fp)
1069 		Piggy_fp = copy_pigfile_from_cd(pigname);
1070 	#endif
1071 
1072 	if (Piggy_fp) {  //make sure pig is valid type file & is up-to-date
1073 		int pig_id,pig_version;
1074 
1075 		pig_id = cfile_read_int(Piggy_fp);
1076 		pig_version = cfile_read_int(Piggy_fp);
1077 		if (pig_id != PIGFILE_ID || pig_version != PIGFILE_VERSION) {
1078 			cfclose(Piggy_fp);              //out of date pig
1079 			Piggy_fp = NULL;                        //..so pretend it's not here
1080 		}
1081 	}
1082 
1083 	#ifndef EDITOR
1084 	if (!Piggy_fp) Error ("Piggy_fp not defined in piggy_new_pigfile.");
1085 	#endif
1086 
1087 	if (Piggy_fp) {
1088 
1089 		N_bitmaps = cfile_read_int(Piggy_fp);
1090 
1091 		header_size = N_bitmaps*DISKBITMAPHEADER_SIZE;
1092 
1093 		data_start = header_size + cftell(Piggy_fp);
1094 
1095 		data_size = cfilelength(Piggy_fp) - data_start;
1096 
1097 		for (i=1; i<=N_bitmaps; i++ )   {
1098 			DiskBitmapHeader_read(&bmh, Piggy_fp);
1099 			memcpy( temp_name_read, bmh.name, 8 );
1100 			temp_name_read[8] = 0;
1101 
1102 			if ( bmh.dflags & DBM_FLAG_ABM )
1103 				sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
1104 			else
1105 				strcpy( temp_name, temp_name_read );
1106 
1107 			//Make sure name matches
1108 			if (strcmp(temp_name,AllBitmaps[i].name)) {
1109 				//Int3();       //this pig is out of date.  Delete it
1110 				must_rewrite_pig=1;
1111 			}
1112 
1113 			strcpy(AllBitmaps[i].name,temp_name);
1114 
1115 			memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
1116 
1117 			temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
1118 			temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
1119 			temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
1120 			temp_bitmap.avg_color = bmh.avg_color;
1121 			temp_bitmap.bm_data = Piggy_bitmap_cache_data;
1122 
1123 			GameBitmapFlags[i] = 0;
1124 
1125 			if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i] |= BM_FLAG_TRANSPARENT;
1126 			if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i] |= BM_FLAG_SUPER_TRANSPARENT;
1127 			if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i] |= BM_FLAG_NO_LIGHTING;
1128 			if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i] |= BM_FLAG_RLE;
1129 			if ( bmh.flags & BM_FLAG_RLE_BIG ) GameBitmapFlags[i] |= BM_FLAG_RLE_BIG;
1130 
1131 			GameBitmapOffset[i] = bmh.offset + data_start;
1132 
1133 			GameBitmaps[i] = temp_bitmap;
1134 		}
1135 	}
1136 	else
1137 		N_bitmaps = 0;          //no pigfile, so no bitmaps
1138 
1139 	#ifndef EDITOR
1140 
1141 	Assert(N_bitmaps == Num_bitmap_files-1);
1142 
1143 	#else
1144 
1145 	if (must_rewrite_pig || (N_bitmaps < Num_bitmap_files-1)) {
1146 		int size;
1147 
1148 		//re-read the bitmaps that aren't in this pig
1149 
1150 		for (i=N_bitmaps+1;i<Num_bitmap_files;i++) {
1151 			char *p;
1152 
1153 			p = strchr(AllBitmaps[i].name,'#');
1154 
1155 			if (p) {                //this is an ABM
1156 				char abmname[FILENAME_LEN];
1157 				int fnum;
1158 				grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
1159 				int iff_error;          //reference parm to avoid warning message
1160 				ubyte newpal[768];
1161 				char basename[FILENAME_LEN];
1162 				int nframes;
1163 
1164 				strcpy(basename,AllBitmaps[i].name);
1165 				basename[p-AllBitmaps[i].name] = 0;             //cut off "#nn" part
1166 
1167 				sprintf( abmname, "%s.abm", basename );
1168 
1169 				iff_error = iff_read_animbrush(abmname,bm,MAX_BITMAPS_PER_BRUSH,&nframes,newpal);
1170 
1171 				if (iff_error != IFF_NO_ERROR)  {
1172 					mprintf((1,"File %s - IFF error: %s",abmname,iff_errormsg(iff_error)));
1173 					Error("File %s - IFF error: %s",abmname,iff_errormsg(iff_error));
1174 				}
1175 
1176 				for (fnum=0;fnum<nframes; fnum++)       {
1177 					char tempname[20];
1178 					int SuperX;
1179 
1180 					sprintf( tempname, "%s#%d", basename, fnum );
1181 
1182 					//SuperX = (GameBitmaps[i+fnum].bm_flags&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1183 					SuperX = (GameBitmapFlags[i+fnum]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1184 					//above makes assumption that supertransparent color is 254
1185 
1186 					if ( iff_has_transparency )
1187 						gr_remap_bitmap_good( bm[fnum], newpal, iff_transparent_color, SuperX );
1188 					else
1189 						gr_remap_bitmap_good( bm[fnum], newpal, -1, SuperX );
1190 
1191 					bm[fnum]->avg_color = compute_average_pixel(bm[fnum]);
1192 
1193 #ifdef EDITOR
1194 					if ( FindArg("-macdata") )
1195 						swap_0_255( bm[fnum] );
1196 #endif
1197 					if ( !BigPig ) gr_bitmap_rle_compress( bm[fnum] );
1198 
1199 					if (bm[fnum]->bm_flags & BM_FLAG_RLE)
1200 						size = *((int *) bm[fnum]->bm_data);
1201 					else
1202 						size = bm[fnum]->bm_w * bm[fnum]->bm_h;
1203 
1204 					memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],bm[fnum]->bm_data,size);
1205 					d_free(bm[fnum]->bm_data);
1206 					bm[fnum]->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1207 					Piggy_bitmap_cache_next += size;
1208 
1209 					GameBitmaps[i+fnum] = *bm[fnum];
1210 
1211 					// -- mprintf( (0, "U" ));
1212 					d_free( bm[fnum] );
1213 				}
1214 
1215 				i += nframes-1;         //filled in multiple bitmaps
1216 			}
1217 			else {          //this is a BBM
1218 
1219 				grs_bitmap * new;
1220 				ubyte newpal[256*3];
1221 				int iff_error;
1222 				char bbmname[FILENAME_LEN];
1223 				int SuperX;
1224 
1225 				MALLOC( new, grs_bitmap, 1 );
1226 
1227 				sprintf( bbmname, "%s.bbm", AllBitmaps[i].name );
1228 				iff_error = iff_read_bitmap(bbmname,new,BM_LINEAR,newpal);
1229 
1230 				new->bm_handle=0;
1231 				if (iff_error != IFF_NO_ERROR)          {
1232 					mprintf((1, "File %s - IFF error: %s",bbmname,iff_errormsg(iff_error)));
1233 					Error("File %s - IFF error: %s",bbmname,iff_errormsg(iff_error));
1234 				}
1235 
1236 				SuperX = (GameBitmapFlags[i]&BM_FLAG_SUPER_TRANSPARENT)?254:-1;
1237 				//above makes assumption that supertransparent color is 254
1238 
1239 				if ( iff_has_transparency )
1240 					gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
1241 				else
1242 					gr_remap_bitmap_good( new, newpal, -1, SuperX );
1243 
1244 				new->avg_color = compute_average_pixel(new);
1245 
1246 #ifdef EDITOR
1247 				if ( FindArg("-macdata") )
1248 					swap_0_255( new );
1249 #endif
1250 				if ( !BigPig )  gr_bitmap_rle_compress( new );
1251 
1252 				if (new->bm_flags & BM_FLAG_RLE)
1253 					size = *((int *) new->bm_data);
1254 				else
1255 					size = new->bm_w * new->bm_h;
1256 
1257 				memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next],new->bm_data,size);
1258 				d_free(new->bm_data);
1259 				new->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1260 				Piggy_bitmap_cache_next += size;
1261 
1262 				GameBitmaps[i] = *new;
1263 
1264 				d_free( new );
1265 
1266 				// -- mprintf( (0, "U" ));
1267 			}
1268 		}
1269 
1270 		//@@Dont' do these things which are done when writing
1271 		//@@for (i=0; i < Num_bitmap_files; i++ )       {
1272 		//@@    bitmap_index bi;
1273 		//@@    bi.index = i;
1274 		//@@    PIGGY_PAGE_IN( bi );
1275 		//@@}
1276 		//@@
1277 		//@@piggy_close_file();
1278 
1279 		piggy_write_pigfile(pigname);
1280 
1281 		Current_pigfile[0] = 0;                 //say no pig, to force reload
1282 
1283 		piggy_new_pigfile(pigname);             //read in just-generated pig
1284 
1285 
1286 	}
1287 	#endif  //ifdef EDITOR
1288 
1289 }
1290 
1291 ubyte bogus_data[64*64];
1292 grs_bitmap bogus_bitmap;
1293 ubyte bogus_bitmap_initialized=0;
1294 digi_sound bogus_sound;
1295 
1296 #define HAMFILE_ID              MAKE_SIG('!','M','A','H') //HAM!
1297 #define HAMFILE_VERSION 3
1298 //version 1 -> 2:  save marker_model_num
1299 //version 2 -> 3:  removed sound files
1300 
1301 #define SNDFILE_ID              MAKE_SIG('D','N','S','D') //DSND
1302 #define SNDFILE_VERSION 1
1303 
read_hamfile()1304 int read_hamfile()
1305 {
1306 	CFILE * ham_fp = NULL;
1307 	int ham_id;
1308 	int sound_offset = 0;
1309 	#ifdef MACINTOSH
1310 	char name[255];
1311 	#endif
1312 
1313 	#ifndef MACINTOSH
1314 	ham_fp = cfopen( DEFAULT_HAMFILE, "rb" );
1315 	#else
1316 	sprintf(name, ":Data:%s", DEFAULT_HAMFILE );
1317 	ham_fp = cfopen( name, "rb" );
1318 	#endif
1319 
1320 	if (ham_fp == NULL) {
1321 		Must_write_hamfile = 1;
1322 		return 0;
1323 	}
1324 
1325 	//make sure ham is valid type file & is up-to-date
1326 	ham_id = cfile_read_int(ham_fp);
1327 	Piggy_hamfile_version = cfile_read_int(ham_fp);
1328 	if (ham_id != HAMFILE_ID)
1329 		Error("Cannot open ham file %s\n", DEFAULT_HAMFILE);
1330 #if 0
1331 	if (ham_id != HAMFILE_ID || Piggy_hamfile_version != HAMFILE_VERSION) {
1332 		Must_write_hamfile = 1;
1333 		cfclose(ham_fp);						//out of date ham
1334 		return 0;
1335 	}
1336 #endif
1337 
1338 	if (Piggy_hamfile_version < 3) // hamfile contains sound info
1339 		sound_offset = cfile_read_int(ham_fp);
1340 
1341 	#ifndef EDITOR
1342 	{
1343 		//int i;
1344 
1345 		bm_read_all(ham_fp);
1346 		cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1347 		// no swap here?
1348 		//for (i = 0; i < MAX_BITMAP_FILES; i++) {
1349 			//GameBitmapXlat[i] = INTEL_SHORT(GameBitmapXlat[i]);
1350 			//printf("GameBitmapXlat[%d] = %d\n", i, GameBitmapXlat[i]);
1351 		//}
1352 	}
1353 	#endif
1354 
1355 	if (Piggy_hamfile_version < 3) {
1356 		int N_sounds;
1357 		int sound_start;
1358 		int header_size;
1359 		int i;
1360 		DiskSoundHeader sndh;
1361 		digi_sound temp_sound;
1362 		char temp_name_read[16];
1363 		int sbytes = 0;
1364 
1365 		cfseek(ham_fp, sound_offset, SEEK_SET);
1366 		N_sounds = cfile_read_int(ham_fp);
1367 
1368 		sound_start = cftell(ham_fp);
1369 
1370 		header_size = N_sounds * DISKSOUNDHEADER_SIZE;
1371 
1372 		//Read sounds
1373 
1374 		for (i=0; i<N_sounds; i++ ) {
1375 			DiskSoundHeader_read(&sndh, ham_fp);
1376 			temp_sound.length = sndh.length;
1377 			temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1378 			SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1379 			memcpy( temp_name_read, sndh.name, 8 );
1380 			temp_name_read[8] = 0;
1381 			piggy_register_sound( &temp_sound, temp_name_read, 1 );
1382 #ifdef MACINTOSH
1383 			if (piggy_is_needed(i))
1384 #endif		// note link to if.
1385 				sbytes += sndh.length;
1386 			//mprintf(( 0, "%d bytes of sound\n", sbytes ));
1387 		}
1388 
1389 		SoundBits = d_malloc( sbytes + 16 );
1390 		if ( SoundBits == NULL )
1391 			Error( "Not enough memory to load sounds\n" );
1392 
1393 		mprintf(( 0, "\nBitmaps: %d KB   Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1394 
1395 		//	piggy_read_sounds(ham_fp);
1396 
1397 	}
1398 
1399 	cfclose(ham_fp);
1400 
1401 	return 1;
1402 
1403 }
1404 
read_sndfile()1405 int read_sndfile()
1406 {
1407 	CFILE * snd_fp = NULL;
1408 	int snd_id,snd_version;
1409 	int N_sounds;
1410 	int sound_start;
1411 	int header_size;
1412 	int i,size, length;
1413 	DiskSoundHeader sndh;
1414 	digi_sound temp_sound;
1415 	char temp_name_read[16];
1416 	int sbytes = 0;
1417 	#ifdef MACINTOSH
1418 	char name[255];
1419 	#endif
1420 
1421 	#ifndef MACINTOSH
1422 	snd_fp = cfopen( DEFAULT_SNDFILE, "rb" );
1423 	#else
1424 	sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1425 	snd_fp = cfopen( name, "rb");
1426 	#endif
1427 
1428 	if (snd_fp == NULL)
1429 		return 0;
1430 
1431 	//make sure soundfile is valid type file & is up-to-date
1432 	snd_id = cfile_read_int(snd_fp);
1433 	snd_version = cfile_read_int(snd_fp);
1434 	if (snd_id != SNDFILE_ID || snd_version != SNDFILE_VERSION) {
1435 		cfclose(snd_fp);						//out of date sound file
1436 		return 0;
1437 	}
1438 
1439 	N_sounds = cfile_read_int(snd_fp);
1440 
1441 	sound_start = cftell(snd_fp);
1442 	size = cfilelength(snd_fp) - sound_start;
1443 	length = size;
1444 	mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
1445 
1446 	header_size = N_sounds*sizeof(DiskSoundHeader);
1447 
1448 	//Read sounds
1449 
1450 	for (i=0; i<N_sounds; i++ ) {
1451 		DiskSoundHeader_read(&sndh, snd_fp);
1452 		//size -= sizeof(DiskSoundHeader);
1453 		temp_sound.length = sndh.length;
1454 		temp_sound.data = (ubyte *)(sndh.offset + header_size + sound_start);
1455 		SoundOffset[Num_sound_files] = sndh.offset + header_size + sound_start;
1456 		memcpy( temp_name_read, sndh.name, 8 );
1457 		temp_name_read[8] = 0;
1458 		piggy_register_sound( &temp_sound, temp_name_read, 1 );
1459 		#ifdef MACINTOSH
1460 		if (piggy_is_needed(i))
1461 		#endif		// note link to if.
1462 		sbytes += sndh.length;
1463 		//mprintf(( 0, "%d bytes of sound\n", sbytes ));
1464 	}
1465 
1466 	SoundBits = d_malloc( sbytes + 16 );
1467 	if ( SoundBits == NULL )
1468 		Error( "Not enough memory to load sounds\n" );
1469 
1470 	mprintf(( 0, "\nBitmaps: %d KB   Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
1471 
1472 //	piggy_read_sounds(snd_fp);
1473 
1474 	cfclose(snd_fp);
1475 
1476 	return 1;
1477 }
1478 
piggy_init(void)1479 int piggy_init(void)
1480 {
1481 	int ham_ok=0,snd_ok=0;
1482 	int i;
1483 
1484 	hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
1485 	hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
1486 
1487 	for (i=0; i<MAX_SOUND_FILES; i++ )	{
1488 		GameSounds[i].length = 0;
1489 		GameSounds[i].data = NULL;
1490 		SoundOffset[i] = 0;
1491 	}
1492 
1493 	for (i=0; i<MAX_BITMAP_FILES; i++ )
1494 		GameBitmapXlat[i] = i;
1495 
1496 	if ( !bogus_bitmap_initialized )        {
1497 		int i;
1498 		ubyte c;
1499 		bogus_bitmap_initialized = 1;
1500 		memset( &bogus_bitmap, 0, sizeof(grs_bitmap) );
1501 		bogus_bitmap.bm_w = bogus_bitmap.bm_h = bogus_bitmap.bm_rowsize = 64;
1502 		bogus_bitmap.bm_data = bogus_data;
1503 		c = gr_find_closest_color( 0, 0, 63 );
1504 		for (i=0; i<4096; i++ ) bogus_data[i] = c;
1505 		c = gr_find_closest_color( 63, 0, 0 );
1506 		// Make a big red X !
1507 		for (i=0; i<64; i++ )   {
1508 			bogus_data[i*64+i] = c;
1509 			bogus_data[i*64+(63-i)] = c;
1510 		}
1511 		piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
1512 		bogus_sound.length = 64*64;
1513 		bogus_sound.data = bogus_data;
1514 		GameBitmapOffset[0] = 0;
1515 	}
1516 
1517 	if ( FindArg( "-bigpig" ))
1518 		BigPig = 1;
1519 
1520 	if ( FindArg( "-lowmem" ))
1521 		piggy_low_memory = 1;
1522 
1523 	if ( FindArg( "-nolowmem" ))
1524 		piggy_low_memory = 0;
1525 
1526 	if (piggy_low_memory)
1527 		digi_lomem = 1;
1528 
1529 	WIN(DDGRLOCK(dd_grd_curcanv));
1530 		gr_set_curfont( SMALL_FONT );
1531 		gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
1532 		gr_printf( 0x8000, grd_curcanv->cv_h-20, "%s...", TXT_LOADING_DATA );
1533 	WIN(DDGRUNLOCK(dd_grd_curcanv));
1534 
1535 #if 1 //def EDITOR //need for d1 mission briefings
1536 	piggy_init_pigfile(DEFAULT_PIGFILE);
1537 #endif
1538 
1539 	snd_ok = ham_ok = read_hamfile();
1540 
1541 	if (Piggy_hamfile_version >= 3)
1542 		snd_ok = read_sndfile();
1543 
1544 	atexit(piggy_close);
1545 
1546 	mprintf ((0,"HamOk=%d SndOk=%d\n",ham_ok,snd_ok));
1547 	return (ham_ok && snd_ok);               //read ok
1548 }
1549 
piggy_is_needed(int soundnum)1550 int piggy_is_needed(int soundnum)
1551 {
1552 	int i;
1553 
1554 	if ( !digi_lomem ) return 1;
1555 
1556 	for (i=0; i<MAX_SOUNDS; i++ )   {
1557 		if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
1558 			return 1;
1559 	}
1560 	return 0;
1561 }
1562 
1563 
piggy_read_sounds(void)1564 void piggy_read_sounds(void)
1565 {
1566 	CFILE * fp = NULL;
1567 	ubyte * ptr;
1568 	int i, sbytes;
1569 	#ifdef MACINTOSH
1570 	char name[255];
1571 	#endif
1572 
1573 	ptr = SoundBits;
1574 	sbytes = 0;
1575 
1576 	#ifndef MACINTOSH
1577 	fp = cfopen( DEFAULT_SNDFILE, "rb" );
1578 	#else
1579 	sprintf( name, ":Data:%s", DEFAULT_SNDFILE );
1580 	fp = cfopen( name, "rb");
1581 	#endif
1582 
1583 	if (fp == NULL)
1584 		return;
1585 
1586 	for (i=0; i<Num_sound_files; i++ )      {
1587 		digi_sound *snd = &GameSounds[i];
1588 
1589 		if ( SoundOffset[i] > 0 )       {
1590 			if ( piggy_is_needed(i) )       {
1591 				cfseek( fp, SoundOffset[i], SEEK_SET );
1592 
1593 				// Read in the sound data!!!
1594 				snd->data = ptr;
1595 				ptr += snd->length;
1596 				sbytes += snd->length;
1597 				cfread( snd->data, snd->length, 1, fp );
1598 			}
1599 			else
1600 				snd->data = (ubyte *) -1;
1601 		}
1602 	}
1603 
1604 	cfclose(fp);
1605 
1606 	mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
1607 
1608 }
1609 
1610 
1611 extern int descent_critical_error;
1612 extern unsigned descent_critical_deverror;
1613 extern unsigned descent_critical_errcode;
1614 
1615 char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
1616 "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
1617 "Read fault", "General Failure" };
1618 
piggy_critical_error()1619 void piggy_critical_error()
1620 {
1621 	grs_canvas * save_canv;
1622 	grs_font * save_font;
1623 	int i;
1624 	save_canv = grd_curcanv;
1625 	save_font = grd_curcanv->cv_font;
1626 	gr_palette_load( gr_palette );
1627 	i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A'  );
1628 	if ( i == 1 )
1629 		exit(1);
1630 	gr_set_current_canvas(save_canv);
1631 	grd_curcanv->cv_font = save_font;
1632 }
1633 
piggy_bitmap_page_in(bitmap_index bitmap)1634 void piggy_bitmap_page_in( bitmap_index bitmap )
1635 {
1636 	grs_bitmap * bmp;
1637 	int i,org_i,temp;
1638 
1639 	org_i = 0;
1640 
1641 	i = bitmap.index;
1642 	Assert( i >= 0 );
1643 	Assert( i < MAX_BITMAP_FILES );
1644 	Assert( i < Num_bitmap_files );
1645 	Assert( Piggy_bitmap_cache_size > 0 );
1646 
1647 	if ( i < 1 ) return;
1648 	if ( i >= MAX_BITMAP_FILES ) return;
1649 	if ( i >= Num_bitmap_files ) return;
1650 
1651 	if ( GameBitmapOffset[i] == 0 ) return;		// A read-from-disk bitmap!!!
1652 
1653 	if ( piggy_low_memory ) {
1654 		org_i = i;
1655 		i = GameBitmapXlat[i];          // Xlat for low-memory settings!
1656 	}
1657 
1658 	bmp = &GameBitmaps[i];
1659 
1660 	if ( bmp->bm_flags & BM_FLAG_PAGED_OUT )        {
1661 		stop_time();
1662 
1663 	ReDoIt:
1664 		descent_critical_error = 0;
1665 		cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
1666 		if ( descent_critical_error )   {
1667 			piggy_critical_error();
1668 			goto ReDoIt;
1669 		}
1670 
1671 		bmp->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
1672 		bmp->bm_flags = GameBitmapFlags[i];
1673 
1674 		if ( bmp->bm_flags & BM_FLAG_RLE )      {
1675 			int zsize = 0;
1676 			descent_critical_error = 0;
1677 			zsize = cfile_read_int(Piggy_fp);
1678 			if ( descent_critical_error )   {
1679 				piggy_critical_error();
1680 				goto ReDoIt;
1681 			}
1682 
1683 			// GET JOHN NOW IF YOU GET THIS ASSERT!!!
1684 			//Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );
1685 			if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1686 				Int3();
1687 				piggy_bitmap_page_out_all();
1688 				goto ReDoIt;
1689 			}
1690 			descent_critical_error = 0;
1691 			temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next+4], 1, zsize-4, Piggy_fp );
1692 			if ( descent_critical_error )   {
1693 				piggy_critical_error();
1694 				goto ReDoIt;
1695 			}
1696 
1697 #ifndef MACDATA
1698 			switch (cfilelength(Piggy_fp)) {
1699 			default:
1700 				if (!FindArg("-macdata"))
1701 					break;
1702 				// otherwise, fall through...
1703 			case MAC_ALIEN1_PIGSIZE:
1704 			case MAC_ALIEN2_PIGSIZE:
1705 			case MAC_FIRE_PIGSIZE:
1706 			case MAC_GROUPA_PIGSIZE:
1707 			case MAC_ICE_PIGSIZE:
1708 			case MAC_WATER_PIGSIZE:
1709 				rle_swap_0_255( bmp );
1710 				memcpy(&zsize, bmp->bm_data, 4);
1711 				break;
1712 			}
1713 #endif
1714 
1715 			memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
1716 			Piggy_bitmap_cache_next += zsize;
1717 			if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) {
1718 				Int3();
1719 				piggy_bitmap_page_out_all();
1720 				goto ReDoIt;
1721 			}
1722 
1723 		} else {
1724 			// GET JOHN NOW IF YOU GET THIS ASSERT!!!
1725 			Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );
1726 			if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) {
1727 				piggy_bitmap_page_out_all();
1728 				goto ReDoIt;
1729 			}
1730 			descent_critical_error = 0;
1731 			temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
1732 			if ( descent_critical_error )   {
1733 				piggy_critical_error();
1734 				goto ReDoIt;
1735 			}
1736 			Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
1737 
1738 #ifndef MACDATA
1739 			switch (cfilelength(Piggy_fp)) {
1740 			default:
1741 				if (!FindArg("-macdata"))
1742 					break;
1743 				// otherwise, fall through...
1744 			case MAC_ALIEN1_PIGSIZE:
1745 			case MAC_ALIEN2_PIGSIZE:
1746 			case MAC_FIRE_PIGSIZE:
1747 			case MAC_GROUPA_PIGSIZE:
1748 			case MAC_ICE_PIGSIZE:
1749 			case MAC_WATER_PIGSIZE:
1750 				swap_0_255( bmp );
1751 				break;
1752 			}
1753 #endif
1754 		}
1755 
1756 		//@@if ( bmp->bm_selector ) {
1757 		//@@#if !defined(WINDOWS) && !defined(MACINTOSH)
1758 		//@@	if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1759 		//@@		Error( "Error modifying selector base in piggy.c\n" );
1760 		//@@#endif
1761 		//@@}
1762 
1763 		start_time();
1764 	}
1765 
1766 	if ( piggy_low_memory ) {
1767 		if ( org_i != i )
1768 			GameBitmaps[org_i] = GameBitmaps[i];
1769 	}
1770 
1771 //@@Removed from John's code:
1772 //@@#ifndef WINDOWS
1773 //@@    if ( bmp->bm_selector ) {
1774 //@@            if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
1775 //@@                    Error( "Error modifying selector base in piggy.c\n" );
1776 //@@    }
1777 //@@#endif
1778 
1779 }
1780 
piggy_bitmap_page_out_all()1781 void piggy_bitmap_page_out_all()
1782 {
1783 	int i;
1784 
1785 	Piggy_bitmap_cache_next = 0;
1786 
1787 	piggy_page_flushed++;
1788 
1789 	texmerge_flush();
1790 	rle_cache_flush();
1791 
1792 	for (i=0; i<Num_bitmap_files; i++ )             {
1793 		if ( GameBitmapOffset[i] > 0 )  {       // Don't page out bitmaps read from disk!!!
1794 			GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
1795 			GameBitmaps[i].bm_data = Piggy_bitmap_cache_data;
1796 		}
1797 	}
1798 
1799 	mprintf(( 0, "Flushing piggy bitmap cache\n" ));
1800 }
1801 
piggy_load_level_data()1802 void piggy_load_level_data()
1803 {
1804 	piggy_bitmap_page_out_all();
1805 	paging_touch_all();
1806 }
1807 
1808 #ifdef EDITOR
1809 
1810 void change_filename_ext( char *dest, char *src, char *ext );
1811 
piggy_write_pigfile(char * filename)1812 void piggy_write_pigfile(char *filename)
1813 {
1814 	FILE *pig_fp;
1815 	int bitmap_data_start,data_offset;
1816 	DiskBitmapHeader bmh;
1817 	int org_offset;
1818 	char subst_name[32];
1819 	int i;
1820 	FILE *fp1,*fp2;
1821 	char tname[FILENAME_LEN];
1822 
1823 	// -- mprintf( (0, "Paging in all piggy bitmaps..." ));
1824 	for (i=0; i < Num_bitmap_files; i++ )   {
1825 		bitmap_index bi;
1826 		bi.index = i;
1827 		PIGGY_PAGE_IN( bi );
1828 	}
1829 	// -- mprintf( (0, "\n" ));
1830 
1831 	piggy_close_file();
1832 
1833 	// -- mprintf( (0, "Creating %s...",filename ));
1834 
1835 	pig_fp = fopen( filename, "wb" );       //open PIG file
1836 	Assert( pig_fp!=NULL );
1837 
1838 	write_int(PIGFILE_ID,pig_fp);
1839 	write_int(PIGFILE_VERSION,pig_fp);
1840 
1841 	Num_bitmap_files--;
1842 	fwrite( &Num_bitmap_files, sizeof(int), 1, pig_fp );
1843 	Num_bitmap_files++;
1844 
1845 	bitmap_data_start = ftell(pig_fp);
1846 	bitmap_data_start += (Num_bitmap_files-1)*DISKBITMAPHEADER_SIZE;
1847 	data_offset = bitmap_data_start;
1848 
1849 	change_filename_ext(tname,filename,"lst");
1850 	fp1 = fopen( tname, "wt" );
1851 	change_filename_ext(tname,filename,"all");
1852 	fp2 = fopen( tname, "wt" );
1853 
1854 	for (i=1; i < Num_bitmap_files; i++ )   {
1855 		int *size;
1856 		grs_bitmap *bmp;
1857 
1858 		{
1859 			char * p, *p1;
1860 			p = strchr(AllBitmaps[i].name,'#');
1861 			if (p)  {
1862 				int n;
1863 				p1 = p; p1++;
1864 				n = atoi(p1);
1865 				*p = 0;
1866 				if (fp2 && n==0)
1867 					fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
1868 				memcpy( bmh.name, AllBitmaps[i].name, 8 );
1869 				Assert( n <= 63 );
1870 				bmh.dflags = DBM_FLAG_ABM + n;
1871 				*p = '#';
1872 			}else {
1873 				if (fp2)
1874 					fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
1875 				memcpy( bmh.name, AllBitmaps[i].name, 8 );
1876 				bmh.dflags = 0;
1877 			}
1878 		}
1879 		bmp = &GameBitmaps[i];
1880 
1881 		Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
1882 
1883 		if (fp1)
1884 			fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
1885 		org_offset = ftell(pig_fp);
1886 		bmh.offset = data_offset - bitmap_data_start;
1887 		fseek( pig_fp, data_offset, SEEK_SET );
1888 
1889 		if ( bmp->bm_flags & BM_FLAG_RLE )      {
1890 			size = (int *)bmp->bm_data;
1891 			fwrite( bmp->bm_data, sizeof(ubyte), *size, pig_fp );
1892 			data_offset += *size;
1893 			if (fp1)
1894 				fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
1895 		} else {
1896 			fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, pig_fp );
1897 			data_offset += bmp->bm_rowsize * bmp->bm_h;
1898 			if (fp1)
1899 				fprintf( fp1, ".\n" );
1900 		}
1901 		fseek( pig_fp, org_offset, SEEK_SET );
1902 		Assert( GameBitmaps[i].bm_w < 4096 );
1903 		bmh.width = (GameBitmaps[i].bm_w & 0xff);
1904 		bmh.wh_extra = ((GameBitmaps[i].bm_w >> 8) & 0x0f);
1905 		Assert( GameBitmaps[i].bm_h < 4096 );
1906 		bmh.height = GameBitmaps[i].bm_h;
1907 		bmh.wh_extra |= ((GameBitmaps[i].bm_h >> 4) & 0xf0);
1908 		bmh.flags = GameBitmaps[i].bm_flags;
1909 		if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name ))    {
1910 			bitmap_index other_bitmap;
1911 			other_bitmap = piggy_find_bitmap( subst_name );
1912 			GameBitmapXlat[i] = other_bitmap.index;
1913 			bmh.flags |= BM_FLAG_PAGED_OUT;
1914 			//mprintf(( 0, "Skipping bitmap %d\n", i ));
1915 			//mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
1916 		} else  {
1917 			bmh.flags &= ~BM_FLAG_PAGED_OUT;
1918 		}
1919 		bmh.avg_color=GameBitmaps[i].avg_color;
1920 		fwrite( &bmh, DISKBITMAPHEADER_SIZE, 1, pig_fp );                    // Mark as a bitmap
1921 	}
1922 
1923 	fclose(pig_fp);
1924 
1925 	mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
1926 	fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
1927 
1928 	fclose(fp1);
1929 	fclose(fp2);
1930 
1931 }
1932 
write_int(int i,FILE * file)1933 static void write_int(int i,FILE *file)
1934 {
1935 	if (fwrite( &i, sizeof(i), 1, file) != 1)
1936 		Error( "Error reading int in gamesave.c" );
1937 
1938 }
1939 
piggy_dump_all()1940 void piggy_dump_all()
1941 {
1942 	int i, xlat_offset;
1943 	FILE * ham_fp;
1944 	int org_offset,data_offset=0;
1945 	DiskSoundHeader sndh;
1946 	int sound_data_start=0;
1947 	FILE *fp1,*fp2;
1948 
1949 	#ifdef NO_DUMP_SOUNDS
1950 	Num_sound_files = 0;
1951 	Num_sound_files_new = 0;
1952 	#endif
1953 
1954 	if (!Must_write_hamfile && (Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
1955 		return;
1956 
1957 	fp1 = fopen( "ham.lst", "wt" );
1958 	fp2 = fopen( "ham.all", "wt" );
1959 
1960 	if (Must_write_hamfile || Num_bitmap_files_new) {
1961 
1962 		mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1963 
1964 		ham_fp = fopen( DEFAULT_HAMFILE, "wb" );                       //open HAM file
1965 		Assert( ham_fp!=NULL );
1966 
1967 		write_int(HAMFILE_ID,ham_fp);
1968 		write_int(HAMFILE_VERSION,ham_fp);
1969 
1970 		bm_write_all(ham_fp);
1971 		xlat_offset = ftell(ham_fp);
1972 		fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1973 		//Dump bitmaps
1974 
1975 		if (Num_bitmap_files_new)
1976 			piggy_write_pigfile(DEFAULT_PIGFILE);
1977 
1978 		//free up memeory used by new bitmaps
1979 		for (i=Num_bitmap_files-Num_bitmap_files_new;i<Num_bitmap_files;i++)
1980 			d_free(GameBitmaps[i].bm_data);
1981 
1982 		//next thing must be done after pig written
1983 		fseek( ham_fp, xlat_offset, SEEK_SET );
1984 		fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, ham_fp );
1985 
1986 		fclose(ham_fp);
1987 		mprintf( (0, "\n" ));
1988 	}
1989 
1990 	if (Num_sound_files_new) {
1991 
1992 		mprintf( (0, "Creating %s...",DEFAULT_HAMFILE));
1993 		// Now dump sound file
1994 		ham_fp = fopen( DEFAULT_SNDFILE, "wb" );
1995 		Assert( ham_fp!=NULL );
1996 
1997 		write_int(SNDFILE_ID,ham_fp);
1998 		write_int(SNDFILE_VERSION,ham_fp);
1999 
2000 		fwrite( &Num_sound_files, sizeof(int), 1, ham_fp );
2001 
2002 		mprintf( (0, "\nDumping sounds..." ));
2003 
2004 		sound_data_start = ftell(ham_fp);
2005 		sound_data_start += Num_sound_files*sizeof(DiskSoundHeader);
2006 		data_offset = sound_data_start;
2007 
2008 		for (i=0; i < Num_sound_files; i++ )    {
2009 			digi_sound *snd;
2010 
2011 			snd = &GameSounds[i];
2012 			strcpy( sndh.name, AllSounds[i].name );
2013 			sndh.length = GameSounds[i].length;
2014 			sndh.offset = data_offset - sound_data_start;
2015 
2016 			org_offset = ftell(ham_fp);
2017 			fseek( ham_fp, data_offset, SEEK_SET );
2018 
2019 			sndh.data_length = GameSounds[i].length;
2020 			fwrite( snd->data, sizeof(ubyte), snd->length, ham_fp );
2021 			data_offset += snd->length;
2022 			fseek( ham_fp, org_offset, SEEK_SET );
2023 			fwrite( &sndh, sizeof(DiskSoundHeader), 1, ham_fp );                    // Mark as a bitmap
2024 
2025 			fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
2026 			fprintf( fp2, "%s.raw\n", AllSounds[i].name );
2027 		}
2028 
2029 		fclose(ham_fp);
2030 		mprintf( (0, "\n" ));
2031 	}
2032 
2033 	fprintf( fp1, "Total sound size: %d bytes\n", data_offset-sound_data_start);
2034 	mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
2035 	fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
2036 
2037 	fclose(fp1);
2038 	fclose(fp2);
2039 
2040 	// Never allow the game to run after building ham.
2041 	exit(0);
2042 }
2043 
2044 #endif
2045 
piggy_close()2046 void piggy_close()
2047 {
2048 	piggy_close_file();
2049 
2050 	if (BitmapBits)
2051 		d_free(BitmapBits);
2052 
2053 	if ( SoundBits )
2054 		d_free( SoundBits );
2055 
2056 	hashtable_free( &AllBitmapsNames );
2057 	hashtable_free( &AllDigiSndNames );
2058 
2059 }
2060 
piggy_does_bitmap_exist_slow(char * name)2061 int piggy_does_bitmap_exist_slow( char * name )
2062 {
2063 	int i;
2064 
2065 	for (i=0; i<Num_bitmap_files; i++ )     {
2066 		if ( !strcmp( AllBitmaps[i].name, name) )
2067 			return 1;
2068 	}
2069 	return 0;
2070 }
2071 
2072 
2073 #define NUM_GAUGE_BITMAPS 23
2074 char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = {
2075 	"gauge01", "gauge01b",
2076 	"gauge02", "gauge02b",
2077 	"gauge06", "gauge06b",
2078 	"targ01", "targ01b",
2079 	"targ02", "targ02b",
2080 	"targ03", "targ03b",
2081 	"targ04", "targ04b",
2082 	"targ05", "targ05b",
2083 	"targ06", "targ06b",
2084 	"gauge18", "gauge18b",
2085 	"gauss1", "helix1",
2086 	"phoenix1"
2087 };
2088 
2089 
piggy_is_gauge_bitmap(char * base_name)2090 int piggy_is_gauge_bitmap( char * base_name )
2091 {
2092 	int i;
2093 	for (i=0; i<NUM_GAUGE_BITMAPS; i++ )    {
2094 		if ( !stricmp( base_name, gauge_bitmap_names[i] ))
2095 			return 1;
2096 	}
2097 
2098 	return 0;
2099 }
2100 
piggy_is_substitutable_bitmap(char * name,char * subst_name)2101 int piggy_is_substitutable_bitmap( char * name, char * subst_name )
2102 {
2103 	int frame;
2104 	char * p;
2105 	char base_name[ 16 ];
2106 
2107 	strcpy( subst_name, name );
2108 	p = strchr( subst_name, '#' );
2109 	if ( p )        {
2110 		frame = atoi( &p[1] );
2111 		*p = 0;
2112 		strcpy( base_name, subst_name );
2113 		if ( !piggy_is_gauge_bitmap( base_name ))       {
2114 			sprintf( subst_name, "%s#%d", base_name, frame+1 );
2115 			if ( piggy_does_bitmap_exist_slow( subst_name )  )      {
2116 				if ( frame & 1 ) {
2117 					sprintf( subst_name, "%s#%d", base_name, frame-1 );
2118 					return 1;
2119 				}
2120 			}
2121 		}
2122 	}
2123 	strcpy( subst_name, name );
2124 	return 0;
2125 }
2126 
2127 
2128 
2129 #ifdef WINDOWS
2130 //	New Windows stuff
2131 
2132 //	windows bitmap page in
2133 //		Page in a bitmap, if ddraw, then page it into a ddsurface in
2134 //		'video' memory.  if that fails, page it in normally.
2135 
piggy_bitmap_page_in_w(bitmap_index bitmap,int ddraw)2136 void piggy_bitmap_page_in_w( bitmap_index bitmap, int ddraw )
2137 {
2138 }
2139 
2140 
2141 //	Essential when switching video modes!
2142 
piggy_bitmap_page_out_all_w()2143 void piggy_bitmap_page_out_all_w()
2144 {
2145 }
2146 
2147 #endif // WINDOWS
2148 
2149 
2150 /*
2151  * Functions for loading replacement textures
2152  *  1) From .pog files
2153  *  2) From descent.pig (for loading d1 levels)
2154  */
2155 
2156 extern void change_filename_extension( char *dest, char *src, char *new_ext );
2157 extern char last_palette_loaded_pig[];
2158 
2159 ubyte *Bitmap_replacement_data=NULL;
2160 
free_bitmap_replacements()2161 void free_bitmap_replacements()
2162 {
2163 	if (Bitmap_replacement_data) {
2164 		d_free(Bitmap_replacement_data);
2165 		Bitmap_replacement_data = NULL;
2166 	}
2167 }
2168 
load_bitmap_replacements(char * level_name)2169 void load_bitmap_replacements(char *level_name)
2170 {
2171 	char ifile_name[FILENAME_LEN];
2172 	CFILE *ifile;
2173 	int i;
2174 
2175 	//first, free up data allocated for old bitmaps
2176 	free_bitmap_replacements();
2177 
2178 	change_filename_extension(ifile_name, level_name, ".POG" );
2179 
2180 	ifile = cfopen(ifile_name,"rb");
2181 
2182 	if (ifile) {
2183 		int id,version,n_bitmaps;
2184 		int bitmap_data_size;
2185 		ushort *indices;
2186 
2187 		id = cfile_read_int(ifile);
2188 		version = cfile_read_int(ifile);
2189 
2190 		if (id != MAKE_SIG('G','O','P','D') || version != 1) {
2191 			cfclose(ifile);
2192 			return;
2193 		}
2194 
2195 		n_bitmaps = cfile_read_int(ifile);
2196 
2197 		MALLOC( indices, ushort, n_bitmaps );
2198 
2199 		for (i = 0; i < n_bitmaps; i++)
2200 			indices[i] = cfile_read_short(ifile);
2201 
2202 		bitmap_data_size = cfilelength(ifile) - cftell(ifile) - DISKBITMAPHEADER_SIZE * n_bitmaps;
2203 		MALLOC( Bitmap_replacement_data, ubyte, bitmap_data_size );
2204 
2205 		for (i=0;i<n_bitmaps;i++) {
2206 			DiskBitmapHeader bmh;
2207 			grs_bitmap temp_bitmap;
2208 
2209 			DiskBitmapHeader_read(&bmh, ifile);
2210 
2211 			memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2212 
2213 			temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2214 			temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2215 			temp_bitmap.avg_color = bmh.avg_color;
2216 			temp_bitmap.bm_data = Bitmap_replacement_data + bmh.offset;
2217 
2218 			if ( bmh.flags & BM_FLAG_TRANSPARENT ) temp_bitmap.bm_flags |= BM_FLAG_TRANSPARENT;
2219 			if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) temp_bitmap.bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2220 			if ( bmh.flags & BM_FLAG_NO_LIGHTING ) temp_bitmap.bm_flags |= BM_FLAG_NO_LIGHTING;
2221 			if ( bmh.flags & BM_FLAG_RLE ) temp_bitmap.bm_flags |= BM_FLAG_RLE;
2222 			if ( bmh.flags & BM_FLAG_RLE_BIG ) temp_bitmap.bm_flags |= BM_FLAG_RLE_BIG;
2223 
2224 			GameBitmaps[indices[i]] = temp_bitmap;
2225 		}
2226 
2227 		cfread(Bitmap_replacement_data,1,bitmap_data_size,ifile);
2228 
2229 		d_free(indices);
2230 
2231 		cfclose(ifile);
2232 
2233 		last_palette_loaded_pig[0]= 0;  //force pig re-load
2234 
2235 		texmerge_flush();       //for re-merging with new textures
2236 	}
2237 
2238 	atexit(free_bitmap_replacements);
2239 }
2240 
2241 #define FIRST_D1_TEXTURE 722
2242 #define LAST_D1_STATIC_TEXTURE 1042//1342 //afterwards, we have door frames and stuff
2243 #define FIRST_D2_TEXTURE 1243
2244 
load_d1_bitmap_replacements()2245 void load_d1_bitmap_replacements()
2246 {
2247 	CFILE * d1_Piggy_fp;
2248 	grs_bitmap temp_bitmap;
2249 	DiskBitmapHeader bmh;
2250 	int pig_data_start, bitmap_header_start, bitmap_data_start;
2251 	int N_bitmaps, zsize;
2252 	int d1_index, d2_index;
2253 	ubyte colormap[256];
2254 	ubyte *next_bitmap; // to which address we write the next bitmap
2255 
2256 	d1_Piggy_fp = cfopen( D1_PIGFILE, "rb" );
2257 
2258 	if (!d1_Piggy_fp)
2259 		return; // use d2 bitmaps instead...
2260 
2261 	//first, free up data allocated for old bitmaps
2262 	free_bitmap_replacements();
2263 
2264 	// read d1 palette, build colormap
2265 	{
2266 		int freq[256];
2267 		ubyte d1_palette[256*3];
2268 		CFILE * palette_file = cfopen(D1_PALETTE, "rb" );
2269 		Assert( palette_file );
2270 		Assert( cfilelength( palette_file ) == 9472 );
2271 		cfread( d1_palette, 256, 3, palette_file);
2272 		cfclose( palette_file );
2273 		build_colormap_good( d1_palette, colormap, freq );
2274 		// don't change transparencies:
2275 		colormap[254] = 254;
2276 		colormap[255] = 255;
2277 	}
2278 
2279 	switch (cfilelength(d1_Piggy_fp)) {
2280 	case D1_SHAREWARE_10_PIGSIZE:
2281 	case D1_SHAREWARE_PIGSIZE:
2282 		pig_data_start = 0;
2283 		break;
2284 	default:
2285 		Int3();
2286 	case D1_PIGSIZE:
2287 	case D1_OEM_PIGSIZE:
2288 	case D1_MAC_PIGSIZE:
2289 	case D1_MAC_SHARE_PIGSIZE:
2290 		//int i;
2291 		pig_data_start = cfile_read_int(d1_Piggy_fp );
2292 		bm_read_all_d1( d1_Piggy_fp );
2293 		//for (i = 0; i < 1800; i++) GameBitmapXlat[i] = cfile_read_short(d1_Piggy_fp);
2294 		break;
2295 	}
2296 
2297 	cfseek( d1_Piggy_fp, pig_data_start, SEEK_SET );
2298 	N_bitmaps = cfile_read_int(d1_Piggy_fp);
2299 	{
2300 		int N_sounds = cfile_read_int(d1_Piggy_fp);
2301 		int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2302 			+ N_sounds * DISKSOUNDHEADER_SIZE;
2303 		bitmap_header_start = pig_data_start + 2 * sizeof(int);
2304 		bitmap_data_start = bitmap_header_start + header_size;
2305 	}
2306 
2307 	MALLOC( Bitmap_replacement_data, ubyte, cfilelength(d1_Piggy_fp) - bitmap_data_start ); // too much
2308 	//TODO: handle case where b_r_d == 0! (have to convert textures, return, not bm_read_all_d1)
2309 
2310 	next_bitmap = Bitmap_replacement_data;
2311 
2312 	for (d1_index=1; d1_index<=N_bitmaps; d1_index++ ) {
2313 		// only change wall texture bitmaps
2314 		if (d1_index >= FIRST_D1_TEXTURE && d1_index <= LAST_D1_STATIC_TEXTURE) {
2315 			d2_index = d1_index + FIRST_D2_TEXTURE - FIRST_D1_TEXTURE;
2316 
2317 			cfseek(d1_Piggy_fp, bitmap_header_start + (d1_index-1) * DISKBITMAPHEADER_D1_SIZE, SEEK_SET);
2318 			DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2319 
2320 			memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
2321 
2322 			temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2323 			temp_bitmap.bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2324 			temp_bitmap.avg_color = bmh.avg_color;
2325 
2326 			//GameBitmapFlags[convert_d1_bitmap_num(d1_index)] = 0;
2327 
2328 			if ( bmh.flags & BM_FLAG_TRANSPARENT )
2329 				temp_bitmap.bm_flags |= BM_FLAG_TRANSPARENT;
2330 			if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT )
2331 				temp_bitmap.bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2332 			if ( bmh.flags & BM_FLAG_NO_LIGHTING )
2333 				temp_bitmap.bm_flags |= BM_FLAG_NO_LIGHTING;
2334 			if ( bmh.flags & BM_FLAG_RLE )
2335 				temp_bitmap.bm_flags |= BM_FLAG_RLE;
2336 			if ( bmh.flags & BM_FLAG_RLE_BIG )
2337 				temp_bitmap.bm_flags |= BM_FLAG_RLE_BIG;
2338 
2339 			temp_bitmap.bm_data = next_bitmap;
2340 
2341 			cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2342 			zsize = cfile_read_int(d1_Piggy_fp);
2343 			cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2344 			cfread(next_bitmap, 1, zsize, d1_Piggy_fp);
2345 
2346 			switch(cfilelength(d1_Piggy_fp)) {
2347 			case D1_MAC_PIGSIZE:
2348 			case D1_MAC_SHARE_PIGSIZE:
2349 				rle_swap_0_255(&temp_bitmap);
2350 			}
2351 			rle_remap(&temp_bitmap, colormap);
2352 
2353 			GameBitmaps[d2_index] = temp_bitmap;
2354 
2355 			memcpy(&zsize, temp_bitmap.bm_data, 4);
2356 			next_bitmap += zsize;
2357 		}
2358 	}
2359 
2360 	cfclose(d1_Piggy_fp);
2361 
2362 	last_palette_loaded_pig[0]= 0;  //force pig re-load
2363 
2364 	texmerge_flush();       //for re-merging with new textures
2365 
2366 	atexit(free_bitmap_replacements);
2367 }
2368 
2369 
2370 extern int extra_bitmap_num;
2371 
2372 /*
2373  * Find and load the named bitmap from descent.pig
2374  * similar to read_extra_bitmap_iff
2375  */
read_extra_bitmap_d1_pig(char * name)2376 bitmap_index read_extra_bitmap_d1_pig(char *name)
2377 {
2378 	bitmap_index bitmap_num;
2379 	grs_bitmap * new = &GameBitmaps[extra_bitmap_num];
2380 
2381 	bitmap_num.index = 0;
2382 
2383 	{
2384 		CFILE *d1_Piggy_fp;
2385 		int i;
2386 		DiskBitmapHeader bmh;
2387 		int pig_data_start, bitmap_header_start, bitmap_data_start;
2388 		int N_bitmaps, zsize;
2389 		ubyte colormap[256];
2390 
2391 		d1_Piggy_fp = cfopen(D1_PIGFILE, "rb");
2392 		if (!d1_Piggy_fp)
2393 		{
2394 			con_printf(CON_DEBUG, "could not open %s\n", D1_PIGFILE);
2395 			return bitmap_num;
2396 		}
2397 
2398 		// read d1 palette, build colormap
2399 		{
2400 			int freq[256];
2401 			ubyte d1_palette[256*3];
2402 			CFILE * palette_file = cfopen(D1_PALETTE, "rb");
2403 			if (!palette_file || cfilelength(palette_file) != 9472)
2404 			{
2405 				con_printf(CON_DEBUG, "could not open %s\n", D1_PALETTE);
2406 				return bitmap_num;
2407 			}
2408 			cfread( d1_palette, 256, 3, palette_file);
2409 			cfclose( palette_file );
2410 			build_colormap_good( d1_palette, colormap, freq );
2411 			// don't change transparencies:
2412 			colormap[254] = 254;
2413 			colormap[255] = 255;
2414 		}
2415 
2416 		switch (cfilelength(d1_Piggy_fp)) {
2417 		case D1_SHAREWARE_10_PIGSIZE:
2418 		case D1_SHAREWARE_PIGSIZE:
2419 			pig_data_start = 0;
2420 			break;
2421 		default:
2422 			Int3();
2423 		case D1_PIGSIZE:
2424 		case D1_OEM_PIGSIZE:
2425 		case D1_MAC_PIGSIZE:
2426 		case D1_MAC_SHARE_PIGSIZE:
2427 			pig_data_start = cfile_read_int(d1_Piggy_fp);
2428 			break;
2429 		}
2430 
2431 		cfseek(d1_Piggy_fp, pig_data_start, SEEK_SET);
2432 		N_bitmaps = cfile_read_int(d1_Piggy_fp);
2433 		{
2434 			int N_sounds = cfile_read_int(d1_Piggy_fp);
2435 			int header_size = N_bitmaps * DISKBITMAPHEADER_D1_SIZE
2436 				+ N_sounds * DISKSOUNDHEADER_SIZE;
2437 			bitmap_header_start = pig_data_start + 2 * sizeof(int);
2438 			bitmap_data_start = bitmap_header_start + header_size;
2439 		}
2440 
2441 		for (i = 0; i < N_bitmaps; i++)
2442 		{
2443 			DiskBitmapHeader_d1_read(&bmh, d1_Piggy_fp);
2444 			if (!strnicmp(bmh.name, name, 8))
2445 				break;
2446 		}
2447 
2448 		if (strnicmp(bmh.name, name, 8))
2449 		{
2450 			con_printf(CON_DEBUG, "could not find bitmap %s\n", name);
2451 			return bitmap_num;
2452 		}
2453 
2454 		memset( new, 0, sizeof(grs_bitmap) );
2455 
2456 		new->bm_w = new->bm_rowsize = bmh.width + ((short) (bmh.wh_extra&0x0f)<<8);
2457 		new->bm_h = bmh.height + ((short) (bmh.wh_extra&0xf0)<<4);
2458 		new->avg_color = bmh.avg_color;
2459 
2460 		if ( bmh.flags & BM_FLAG_TRANSPARENT )
2461 			new->bm_flags |= BM_FLAG_TRANSPARENT;
2462 		if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT )
2463 			new->bm_flags |= BM_FLAG_SUPER_TRANSPARENT;
2464 		if ( bmh.flags & BM_FLAG_NO_LIGHTING )
2465 			new->bm_flags |= BM_FLAG_NO_LIGHTING;
2466 		if ( bmh.flags & BM_FLAG_RLE )
2467 			new->bm_flags |= BM_FLAG_RLE;
2468 		if ( bmh.flags & BM_FLAG_RLE_BIG )
2469 			new->bm_flags |= BM_FLAG_RLE_BIG;
2470 
2471 		if ( bmh.flags & BM_FLAG_RLE )
2472 		{
2473 			cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2474 			zsize = cfile_read_int(d1_Piggy_fp);
2475 		}
2476 		else
2477 			zsize = new->bm_w * new->bm_h;
2478 		new->bm_data = d_malloc(zsize);
2479 		cfseek(d1_Piggy_fp, bitmap_data_start + bmh.offset, SEEK_SET);
2480 		cfread(new->bm_data, 1, zsize, d1_Piggy_fp);
2481 
2482 		switch(cfilelength(d1_Piggy_fp)) {
2483 		case D1_MAC_PIGSIZE:
2484 		case D1_MAC_SHARE_PIGSIZE:
2485 			rle_swap_0_255(new);
2486 		}
2487 		rle_remap(new, colormap);
2488 
2489 		cfclose(d1_Piggy_fp);
2490 	}
2491 
2492 	new->avg_color = 0;	//compute_average_pixel(new);
2493 
2494 	bitmap_num.index = extra_bitmap_num;
2495 
2496 	GameBitmaps[extra_bitmap_num++] = *new;
2497 
2498 	return bitmap_num;
2499 }
2500 
2501 
2502 #ifndef FAST_FILE_IO
2503 /*
2504  * reads a bitmap_index structure from a CFILE
2505  */
bitmap_index_read(bitmap_index * bi,CFILE * fp)2506 void bitmap_index_read(bitmap_index *bi, CFILE *fp)
2507 {
2508 	bi->index = cfile_read_short(fp);
2509 }
2510 
2511 /*
2512  * reads n bitmap_index structs from a CFILE
2513  */
bitmap_index_read_n(bitmap_index * bi,int n,CFILE * fp)2514 int bitmap_index_read_n(bitmap_index *bi, int n, CFILE *fp)
2515 {
2516 	int i;
2517 
2518 	for (i = 0; i < n; i++)
2519 		bi[i].index = cfile_read_short(fp);
2520 	return i;
2521 }
2522 
2523 /*
2524  * reads a DiskBitmapHeader structure from a CFILE
2525  */
DiskBitmapHeader_read(DiskBitmapHeader * dbh,CFILE * fp)2526 void DiskBitmapHeader_read(DiskBitmapHeader *dbh, CFILE *fp)
2527 {
2528 	cfread(dbh->name, 8, 1, fp);
2529 	dbh->dflags = cfile_read_byte(fp);
2530 	dbh->width = cfile_read_byte(fp);
2531 	dbh->height = cfile_read_byte(fp);
2532 	dbh->wh_extra = cfile_read_byte(fp);
2533 	dbh->flags = cfile_read_byte(fp);
2534 	dbh->avg_color = cfile_read_byte(fp);
2535 	dbh->offset = cfile_read_int(fp);
2536 }
2537 
2538 /*
2539  * reads a DiskSoundHeader structure from a CFILE
2540  */
DiskSoundHeader_read(DiskSoundHeader * dsh,CFILE * fp)2541 void DiskSoundHeader_read(DiskSoundHeader *dsh, CFILE *fp)
2542 {
2543 	cfread(dsh->name, 8, 1, fp);
2544 	dsh->length = cfile_read_int(fp);
2545 	dsh->data_length = cfile_read_int(fp);
2546 	dsh->offset = cfile_read_int(fp);
2547 }
2548 #endif // FAST_FILE_IO
2549 
2550 /*
2551  * reads a descent 1 DiskBitmapHeader structure from a CFILE
2552  */
DiskBitmapHeader_d1_read(DiskBitmapHeader * dbh,CFILE * fp)2553 void DiskBitmapHeader_d1_read(DiskBitmapHeader *dbh, CFILE *fp)
2554 {
2555 	cfread(dbh->name, 8, 1, fp);
2556 	dbh->dflags = cfile_read_byte(fp);
2557 	dbh->width = cfile_read_byte(fp);
2558 	dbh->height = cfile_read_byte(fp);
2559 	dbh->wh_extra = 0;
2560 	dbh->flags = cfile_read_byte(fp);
2561 	dbh->avg_color = cfile_read_byte(fp);
2562 	dbh->offset = cfile_read_int(fp);
2563 }
2564