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