home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / piggy.c < prev    next >
Text File  |  1998-06-08  |  34KB  |  1,267 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: f:/miner/source/main/rcs/piggy.c $
  15.  * $Revision: 2.10 $
  16.  * $Author: john $
  17.  * $Date: 1995/10/07 13:17:26 $
  18.  * 
  19.  * Functions for managing the pig files.
  20.  * 
  21.  * $Log: piggy.c $
  22.  * Revision 2.10  1995/10/07  13:17:26  john
  23.  * Made all bitmaps paged out by default.
  24.  * 
  25.  * Revision 2.9  1995/04/14  14:05:24  john
  26.  * *** empty log message ***
  27.  * 
  28.  * Revision 2.8  1995/04/12  13:39:37  john
  29.  * Fixed bug with -lowmem not working.
  30.  * 
  31.  * Revision 2.7  1995/03/29  23:23:17  john
  32.  * Fixed major bug with sounds not building into pig right.
  33.  * 
  34.  * Revision 2.6  1995/03/28  18:05:00  john
  35.  * Fixed it so you don't have to delete pig after changing bitmaps.tbl
  36.  * 
  37.  * Revision 2.5  1995/03/16  23:13:06  john
  38.  * Fixed bug with piggy paging in bitmap not checking for disk
  39.  * error, hence bogifying textures if you pull the CD out.
  40.  * 
  41.  * Revision 2.4  1995/03/14  16:22:27  john
  42.  * Added cdrom alternate directory stuff.
  43.  * 
  44.  * Revision 2.3  1995/03/06  15:23:20  john
  45.  * New screen techniques.
  46.  * 
  47.  * Revision 2.2  1995/02/27  13:13:40  john
  48.  * Removed floating point.
  49.  * 
  50.  * Revision 2.1  1995/02/27  12:31:25  john
  51.  * Made work without editor.
  52.  * 
  53.  * Revision 2.0  1995/02/27  11:28:02  john
  54.  * New version 2.0, which has no anonymous unions, builds with
  55.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  56.  * 
  57.  * Revision 1.85  1995/02/09  12:54:24  john
  58.  * Made paged out bitmaps have bm_data be a valid pointer
  59.  * instead of NULL, in case anyone accesses it.
  60.  * 
  61.  * Revision 1.84  1995/02/09  12:50:59  john
  62.  * Bullet-proofed the piggy loading code.
  63.  * 
  64.  * Revision 1.83  1995/02/07  17:08:51  john
  65.  * Added some error handling stuff instead of asserts.
  66.  * 
  67.  * Revision 1.82  1995/02/03  17:06:48  john
  68.  * Changed sound stuff to allow low memory usage.
  69.  * Also, changed so that Sounds isn't an array of digi_sounds, it
  70.  * is a ubyte pointing into GameSounds, this way the digi.c code that
  71.  * locks sounds won't accidentally unlock a sound that is already playing, but
  72.  * since it's Sounds[soundno] is different, it would erroneously be unlocked.
  73.  * 
  74.  * Revision 1.81  1995/02/02  21:56:39  matt
  75.  * Added data for new gauge bitmaps
  76.  * 
  77.  * Revision 1.80  1995/02/01  23:31:57  john
  78.  * Took out loading bar.
  79.  * 
  80.  * Revision 1.79  1995/01/28  15:13:18  allender
  81.  * bumped up Piggy_bitmap_cache_size
  82.  * 
  83.  * Revision 1.78  1995/01/26  12:30:43  john
  84.  * Took out prev.
  85.  * 
  86.  * Revision 1.77  1995/01/26  12:12:17  john
  87.  * Made buffer be big for bitmaps.
  88.  * 
  89.  * Revision 1.76  1995/01/25  20:15:38  john
  90.  * Made editor allocate all mem.
  91.  * 
  92.  * Revision 1.75  1995/01/25  14:52:56  john
  93.  * Made bitmap buffer be 1.5 MB.
  94.  * 
  95.  * Revision 1.74  1995/01/22  16:03:19  mike
  96.  * localization.
  97.  * 
  98.  * Revision 1.73  1995/01/22  15:58:36  mike
  99.  * localization
  100.  * 
  101.  * Revision 1.72  1995/01/18  20:51:20  john
  102.  * Took out warnings.
  103.  * 
  104.  * Revision 1.71  1995/01/18  20:47:21  john
  105.  * Added code to allocate sounds & bitmaps into diff
  106.  * buffers, also made sounds not be compressed for registered.
  107.  * 
  108.  * Revision 1.70  1995/01/18  15:08:41  john
  109.  * Added start/stop time around paging.
  110.  * Made paging clear screen around globe.
  111.  * 
  112.  * Revision 1.69  1995/01/18  10:07:51  john
  113.  * 
  114.  * Took out debugging mprintfs.
  115.  * 
  116.  * Revision 1.68  1995/01/17  14:27:42  john
  117.  * y
  118.  * 
  119.  * Revision 1.67  1995/01/17  12:14:39  john
  120.  * Made walls, object explosion vclips load at level start.
  121.  * 
  122.  * Revision 1.66  1995/01/15  13:15:44  john
  123.  * Made so that paging always happens, lowmem just loads less.
  124.  * Also, make KB load print to hud.
  125.  * 
  126.  * Revision 1.65  1995/01/15  11:56:28  john
  127.  * Working version of paging.
  128.  * 
  129.  * Revision 1.64  1995/01/14  19:17:07  john
  130.  * First version of new bitmap paging code.
  131.  * 
  132.  * Revision 1.63  1994/12/15  12:26:44  john
  133.  * Added -nolowmem function.
  134.  * 
  135.  * Revision 1.62  1994/12/14  21:12:26  john
  136.  * Fixed bug with page fault when exiting and using
  137.  * -nosound.
  138.  * 
  139.  * Revision 1.61  1994/12/14  11:35:31  john
  140.  * Evened out thermometer for pig read.
  141.  * 
  142.  * Revision 1.60  1994/12/14  10:51:00  john
  143.  * Sped up sound loading.
  144.  * 
  145.  * Revision 1.59  1994/12/14  10:12:08  john
  146.  * Sped up pig loading.
  147.  * 
  148.  * Revision 1.58  1994/12/13  09:14:47  john
  149.  * *** empty log message ***
  150.  * 
  151.  * Revision 1.57  1994/12/13  09:12:57  john
  152.  * Made the bar always fill up.
  153.  * 
  154.  * Revision 1.56  1994/12/13  03:49:08  john
  155.  * Made -lowmem not load the unnecessary bitmaps.
  156.  * 
  157.  * Revision 1.55  1994/12/06  16:06:35  john
  158.  * Took out piggy sorting.
  159.  * 
  160.  * Revision 1.54  1994/12/06  15:11:14  john
  161.  * Fixed bug with reading pigs.
  162.  * 
  163.  * Revision 1.53  1994/12/06  14:14:47  john
  164.  * Added code to set low mem based on memory.
  165.  * 
  166.  * Revision 1.52  1994/12/06  14:01:10  john
  167.  * Fixed bug that was causing -lowmem all the time..
  168.  * 
  169.  * Revision 1.51  1994/12/06  13:33:48  john
  170.  * Added lowmem option.
  171.  * 
  172.  * Revision 1.50  1994/12/05  19:40:10  john
  173.  * If -nosound or no sound card selected, don't load sounds from pig.
  174.  * 
  175.  * Revision 1.49  1994/12/05  12:17:44  john
  176.  * Added code that locks/unlocks digital sounds on demand.
  177.  * 
  178.  * Revision 1.48  1994/12/05  11:39:03  matt
  179.  * Fixed little mistake
  180.  * 
  181.  * Revision 1.47  1994/12/05  09:29:22  john
  182.  * Added clength to the sound field.
  183.  * 
  184.  * Revision 1.46  1994/12/04  15:27:15  john
  185.  * Fixed my stupid bug that looked at -nosound instead of digi_driver_card
  186.  * to see whether or not to lock down sound memory.
  187.  * 
  188.  * Revision 1.45  1994/12/03  14:17:00  john
  189.  * Took out my debug mprintf.
  190.  * 
  191.  * Revision 1.44  1994/12/03  13:32:37  john
  192.  * Fixed bug with offscreen bitmap.
  193.  * 
  194.  * Revision 1.43  1994/12/03  13:07:13  john
  195.  * Made the pig read/write compressed sounds.
  196.  * 
  197.  * Revision 1.42  1994/12/03  11:48:51  matt
  198.  * Added option to not dump sounds to pigfile
  199.  * 
  200.  * Revision 1.41  1994/12/02  20:02:20  matt
  201.  * Made sound files constant match constant for table
  202.  * 
  203.  * Revision 1.40  1994/11/29  11:03:09  adam
  204.  * upped # of sounds
  205.  * 
  206.  * Revision 1.39  1994/11/27  23:13:51  matt
  207.  * Made changes for new mprintf calling convention
  208.  * 
  209.  * Revision 1.38  1994/11/20  18:40:34  john
  210.  * MAde the piggy.lst and piggy.all not dump for release.
  211.  * 
  212.  * Revision 1.37  1994/11/19  23:54:45  mike
  213.  * up number of bitmaps for shareware version.
  214.  * 
  215.  * Revision 1.36  1994/11/19  19:53:05  mike
  216.  * change MAX_BITMAP_FILES
  217.  * 
  218.  * Revision 1.35  1994/11/19  10:42:56  matt
  219.  * Increased number of bitmaps for non-shareware version
  220.  * 
  221.  * Revision 1.34  1994/11/19  09:11:52  john
  222.  * Added avg_color to bitmaps saved in pig.
  223.  * 
  224.  * Revision 1.33  1994/11/19  00:07:05  john
  225.  * Fixed bug with 8 char sound filenames not getting read from pig.
  226.  * 
  227.  * Revision 1.32  1994/11/18  22:24:54  john
  228.  * Added -bigpig command line that doesn't rle your pig.
  229.  * 
  230.  * Revision 1.31  1994/11/18  21:56:53  john
  231.  * Added a better, leaner pig format.
  232.  * 
  233.  * Revision 1.30  1994/11/16  12:06:16  john
  234.  * Fixed bug with calling .bbms abms.
  235.  * 
  236.  * Revision 1.29  1994/11/16  12:00:56  john
  237.  * Added piggy.all dump.
  238.  * 
  239.  * Revision 1.28  1994/11/10  21:16:02  adam
  240.  * nothing important
  241.  * 
  242.  * Revision 1.27  1994/11/10  13:42:00  john
  243.  * Made sounds not lock down if using -nosound.
  244.  * 
  245.  * Revision 1.26  1994/11/09  19:55:40  john
  246.  * Added full rle support with texture rle caching.
  247.  * 
  248.  * Revision 1.25  1994/11/09  16:36:42  john
  249.  * First version with RLE bitmaps in Pig.
  250.  * 
  251.  * Revision 1.24  1994/10/27  19:42:59  john
  252.  * Disable the piglet option.
  253.  * 
  254.  * Revision 1.23  1994/10/27  18:51:40  john
  255.  * Added -piglet option that only loads needed textures for a 
  256.  * mine.  Only saved ~1MB, and code still doesn't free textures
  257.  * before you load a new mine.
  258.  * 
  259.  * Revision 1.22  1994/10/25  13:11:42  john
  260.  * Made the sounds sort. Dumped piggy.lst.
  261.  * 
  262.  * Revision 1.21  1994/10/06  17:06:23  john
  263.  * Took out rle stuff.
  264.  * 
  265.  * Revision 1.20  1994/10/06  15:45:36  adam
  266.  * bumped MAX_BITMAP_FILES again!
  267.  * 
  268.  * Revision 1.19  1994/10/06  11:01:17  yuan
  269.  * Upped MAX_BITMAP_FILES
  270.  * 
  271.  * Revision 1.18  1994/10/06  10:44:45  john
  272.  * Added diagnostic message and psuedo run-length-encoder
  273.  * to see how much memory we would save by storing bitmaps
  274.  * in a RLE method.  Also, I commented out the code that
  275.  * stores 4K bitmaps on a 4K boundry to reduce pig size 
  276.  * a bit.
  277.  * 
  278.  * Revision 1.17  1994/10/04  20:03:13  matt
  279.  * Upped maximum number of bitmaps
  280.  * 
  281.  * Revision 1.16  1994/10/03  18:04:20  john
  282.  * Fixed bug with data_offset not set right for bitmaps
  283.  * that are 64x64 and not aligned on a 4k boundry.
  284.  * 
  285.  * Revision 1.15  1994/09/28  11:30:55  john
  286.  * changed inferno.pig to descent.pig, changed the way it
  287.  * is read.
  288.  * 
  289.  * Revision 1.14  1994/09/22  16:14:17  john
  290.  * Redid intro sequecing.
  291.  * 
  292.  * Revision 1.13  1994/09/19  14:42:47  john
  293.  * Locked down sounds with Virtual memory.
  294.  * 
  295.  * Revision 1.12  1994/09/10  17:31:52  mike
  296.  * Increase number of loadable bitmaps.
  297.  * 
  298.  * Revision 1.11  1994/09/01  19:32:49  mike
  299.  * Boost texture map allocation.
  300.  * 
  301.  * Revision 1.10  1994/08/16  11:51:02  john
  302.  * Added grwased pigs.
  303.  * 
  304.  * Revision 1.9  1994/07/06  09:18:03  adam
  305.  * upped bitmap #s
  306.  * 
  307.  * Revision 1.8  1994/06/20  22:02:15  matt
  308.  * Fixed bug from last change
  309.  * 
  310.  * Revision 1.7  1994/06/20  21:33:18  matt
  311.  * Made bm.h not include sounds.h, to reduce dependencies
  312.  * 
  313.  * Revision 1.6  1994/06/20  16:52:19  john
  314.  * cleaned up init output a bit.
  315.  * 
  316.  * Revision 1.5  1994/06/08  14:20:57  john
  317.  * Made piggy dump before going into game.
  318.  * 
  319.  * Revision 1.4  1994/06/02  18:59:22  matt
  320.  * Clear selector field of bitmap loaded from pig file
  321.  * 
  322.  * Revision 1.3  1994/05/06  15:31:41  john
  323.  * Made name field a bit longer.
  324.  * 
  325.  * Revision 1.2  1994/05/06  13:02:44  john
  326.  * Added piggy stuff; worked on supertransparency
  327.  * 
  328.  * Revision 1.1  1994/05/06  11:47:26  john
  329.  * Initial revision
  330.  * 
  331.  * 
  332.  */
  333.  
  334.  
  335. #pragma off (unreferenced)
  336. static char rcsid[] = "$Id: piggy.c 2.10 1995/10/07 13:17:26 john Exp $";
  337. #pragma on (unreferenced)
  338.  
  339. #include <stdio.h>
  340. #include <stdlib.h>
  341. #include <stdarg.h>
  342. #include <conio.h>
  343. #include <string.h>
  344. #include <io.h>
  345.  
  346. #include "types.h"
  347. #include "inferno.h"
  348. #include "gr.h"
  349. //#include "mem.h"
  350. #include "cflib.h"
  351. #include "mono.h"
  352. #include "error.h"
  353. #include "sounds.h"
  354. #include "bm.h"
  355. #include "hash.h"
  356. #include "args.h"
  357. #include "dpmi.h"
  358. #include "palette.h"
  359. #include "gamefont.h"
  360. #include "rle.h"
  361. #include "screens.h"
  362.  
  363. //#include "soscomp.h"
  364. //The above include is part of a commercial 
  365. //sound library, so it cannot be included in a public 
  366. //release of the source code. -KRB
  367. #include "no_sos.h" //Added by KRB
  368.  
  369. #include "piggy.h"
  370. #include "texmerge.h"
  371. #include "paging.h"
  372. #include "game.h"
  373. #include "text.h"
  374. #include "cfile.h"
  375. #include "newmenu.h"
  376.  
  377. //#define NO_DUMP_SOUNDS    1        //if set, dump bitmaps but not sounds
  378.  
  379. ubyte *BitmapBits = NULL;
  380. ubyte *SoundBits = NULL;
  381.  
  382. typedef struct BitmapFile    {
  383.     char            name[15];
  384. } BitmapFile;
  385.  
  386. typedef struct SoundFile    {
  387.     char            name[15];
  388. } SoundFile;
  389.  
  390. hashtable AllBitmapsNames;
  391. hashtable AllDigiSndNames;
  392.  
  393. int Num_bitmap_files = 0;
  394. int Num_sound_files = 0;
  395.  
  396. digi_sound GameSounds[MAX_SOUND_FILES];
  397. int SoundOffset[MAX_SOUND_FILES];
  398. grs_bitmap GameBitmaps[MAX_BITMAP_FILES];
  399.  
  400. int Num_bitmap_files_new = 0;
  401. int Num_sound_files_new = 0;
  402. static BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
  403. static SoundFile AllSounds[ MAX_SOUND_FILES ];
  404.  
  405. int piggy_low_memory = 0;
  406.  
  407. #define DBM_FLAG_LARGE     128        // Flags added onto the flags struct in b
  408. #define DBM_FLAG_ABM        64
  409.  
  410. int Piggy_bitmap_cache_size = 0;
  411. int Piggy_bitmap_cache_next = 0;
  412. ubyte * Piggy_bitmap_cache_data = NULL;
  413. static int GameBitmapOffset[MAX_BITMAP_FILES];
  414. static ubyte GameBitmapFlags[MAX_BITMAP_FILES];
  415. ushort GameBitmapXlat[MAX_BITMAP_FILES];
  416.  
  417. #define PIGGY_BUFFER_SIZE (2048*1024)
  418.  
  419. int piggy_page_flushed = 0;
  420.  
  421. typedef struct DiskBitmapHeader {
  422.     char name[8];
  423.     ubyte dflags;
  424.     ubyte    width;    
  425.     ubyte height;
  426.     ubyte flags;
  427.     ubyte avg_color;
  428.     int offset;
  429. } DiskBitmapHeader;
  430.  
  431. typedef struct DiskSoundHeader {
  432.     char name[8];
  433.     int length;
  434.     int data_length;
  435.     int offset;
  436. } DiskSoundHeader;
  437.  
  438. ubyte BigPig = 0;
  439.  
  440.  
  441. //#define BUILD_PSX_DATA 1
  442.  
  443. #ifdef BUILD_PSX_DATA
  444. FILE * count_file = NULL;
  445.  
  446. int num_good=0,num_bad=0;
  447. int num_good64=0,num_bad64=0;
  448.  
  449. void close_count_file()
  450. {
  451.      if ( count_file )    {
  452.         fprintf( count_file,"Good = %d\n", num_good );
  453.         fprintf( count_file,"Bad = %d\n", num_bad );
  454.         fprintf( count_file,"64Good = %d\n", num_good64 );
  455.         fprintf( count_file,"64Bad = %d\n", num_bad64 );
  456.         fclose(count_file);
  457.         count_file=NULL;
  458.     }
  459. }
  460.  
  461. void count_colors( int bnum, grs_bitmap * bmp )
  462. {
  463.     int i,colors;
  464.     ushort n[256];
  465.  
  466.     quantize_colors( bnum, bmp );
  467.  
  468.     if ( count_file == NULL )    {
  469.         atexit( close_count_file );
  470.         count_file = fopen( "bitmap.cnt", "wt" );
  471.     }
  472.     for (i=0; i<256; i++ )
  473.         n[i] = 0;
  474.  
  475.     for (i=0; i<bmp->bm_w*bmp->bm_h; i++ )    {
  476.         n[bmp->bm_data[i]]++;
  477.     }
  478.  
  479.     colors = 0;
  480.     for (i=0; i<256; i++ )
  481.         if (n[i]) colors++;
  482.  
  483.     if ( colors > 16 )    {
  484.         if ( (bmp->bm_w==64) && (bmp->bm_h==64) ) num_bad64++;
  485.         num_bad++;
  486.         fprintf( count_file, "Bmp has %d colors (%d x %d)\n", colors, bmp->bm_w, bmp->bm_h );
  487.     } else {
  488.         if ( (bmp->bm_w==64) && (bmp->bm_h==64) ) num_good64++;
  489.         num_good++;
  490.     }
  491. }
  492. #endif
  493.  
  494. void piggy_get_bitmap_name( int i, char * name )
  495. {
  496.     strncpy( name, AllBitmaps[i].name, 12 );
  497.     name[12] = 0;
  498. }
  499.  
  500. bitmap_index piggy_register_bitmap( grs_bitmap * bmp, char * name, int in_file )
  501. {
  502.     bitmap_index temp;
  503.     Assert( Num_bitmap_files < MAX_BITMAP_FILES );
  504.  
  505.     temp.index = Num_bitmap_files;
  506.  
  507.  
  508.     if (!in_file)    {
  509.         if ( !BigPig )    gr_bitmap_rle_compress( bmp );
  510.         Num_bitmap_files_new++;
  511.     }
  512.  
  513.     strncpy( AllBitmaps[Num_bitmap_files].name, name, 12 );
  514.     hashtable_insert( &AllBitmapsNames, AllBitmaps[Num_bitmap_files].name, Num_bitmap_files );
  515.     GameBitmaps[Num_bitmap_files] = *bmp;
  516.     if ( !in_file )    {
  517.         GameBitmapOffset[Num_bitmap_files] = 0;
  518.         GameBitmapFlags[Num_bitmap_files] = bmp->bm_flags;
  519.     }
  520.     Num_bitmap_files++;
  521.  
  522.     return temp;
  523. }
  524.  
  525. int piggy_register_sound( digi_sound * snd, char * name, int in_file )
  526. {
  527.     int i;
  528.  
  529.     Assert( Num_sound_files < MAX_SOUND_FILES );
  530.  
  531.     strncpy( AllSounds[Num_sound_files].name, name, 12 );
  532.     hashtable_insert( &AllDigiSndNames, AllSounds[Num_sound_files].name, Num_sound_files );
  533.     GameSounds[Num_sound_files] = *snd;
  534.     if ( !in_file )    {
  535.         SoundOffset[Num_sound_files] = 0;    
  536.     }
  537.  
  538.     i = Num_sound_files;
  539.    
  540.     if (!in_file)
  541.         Num_sound_files_new++;
  542.  
  543.     Num_sound_files++;
  544.     return i;
  545. }
  546.  
  547. bitmap_index piggy_find_bitmap( char * name )    
  548. {
  549.     bitmap_index bmp;
  550.     int i;
  551.  
  552.     bmp.index = 0;
  553.  
  554.     i = hashtable_search( &AllBitmapsNames, name );
  555.     Assert( i != 0 );
  556.     if ( i < 0 )
  557.         return bmp;
  558.  
  559.     bmp.index = i;
  560.     return bmp;
  561. }
  562.  
  563. int piggy_find_sound( char * name )    
  564. {
  565.     int i;
  566.  
  567.     i = hashtable_search( &AllDigiSndNames, name );
  568.  
  569.     if ( i < 0 )
  570.         return 255;
  571.  
  572.     return i;
  573. }
  574.  
  575. CFILE * Piggy_fp = NULL;
  576.  
  577. void piggy_close_file()
  578. {
  579.     if ( Piggy_fp )    {
  580.         cfclose( Piggy_fp );
  581.         Piggy_fp    = NULL;
  582.     }
  583. }
  584.  
  585. ubyte bogus_data[64*64];
  586. grs_bitmap bogus_bitmap;
  587. ubyte bogus_bitmap_initialized=0;
  588. digi_sound bogus_sound;
  589.  
  590. extern void bm_read_all(CFILE * fp);
  591.  
  592. int piggy_init()
  593. {
  594.     int sbytes = 0;
  595.     char temp_name_read[16];
  596.     char temp_name[16];
  597.     grs_bitmap temp_bitmap;
  598.     digi_sound temp_sound;
  599.     DiskBitmapHeader bmh;
  600.     DiskSoundHeader sndh;
  601.     int header_size, N_bitmaps, N_sounds;
  602.     int i,size, length, x, y;
  603.     char * filename;
  604.     int read_sounds = 1;
  605.     int Pigdata_start;
  606.  
  607.     hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
  608.     hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );
  609.  
  610.     if ( FindArg( "-nosound" ) || (digi_driver_board<1) )        {
  611.         read_sounds = 0;
  612.         mprintf(( 0, "Not loading sound data!!!!!\n" ));
  613.     }
  614.     
  615.     for (i=0; i<MAX_SOUND_FILES; i++ )    {
  616.         GameSounds[i].length = 0;
  617.         GameSounds[i].data = NULL;
  618.         SoundOffset[i] = 0;
  619.     }
  620.  
  621.     for (i=0; i<MAX_BITMAP_FILES; i++ )        {
  622.         GameBitmapXlat[i] = i;
  623.         GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
  624.     }
  625.  
  626.     if ( !bogus_bitmap_initialized )    {
  627.         int i;
  628.         ubyte c;
  629.         bogus_bitmap_initialized = 1;
  630.         memset( &bogus_bitmap, 0, sizeof(grs_bitmap) );
  631.         bogus_bitmap.bm_w = bogus_bitmap.bm_h = bogus_bitmap.bm_rowsize = 64;
  632.         bogus_bitmap.bm_data = bogus_data;
  633.         c = gr_find_closest_color( 0, 0, 63 );
  634.         for (i=0; i<4096; i++ ) bogus_data[i] = c;
  635.         c = gr_find_closest_color( 63, 0, 0 );
  636.         // Make a big red X !
  637.         for (i=0; i<64; i++ )    {
  638.             bogus_data[i*64+i] = c;
  639.             bogus_data[i*64+(63-i)] = c;
  640.         }
  641.         piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
  642.         bogus_sound.length = 64*64;
  643.         bogus_sound.data = bogus_data;
  644.         GameBitmapOffset[0] = 0;
  645.     }
  646.  
  647.     filename = "DESCENT.PIG";
  648.     
  649.     if ( FindArg( "-bigpig" ))
  650.         BigPig = 1;
  651.  
  652.     if ( FindArg( "-lowmem" ))
  653.         piggy_low_memory = 1;
  654.  
  655.     if ( FindArg( "-nolowmem" ))
  656.         piggy_low_memory = 0;
  657.  
  658.     if (piggy_low_memory)
  659.         digi_lomem = 1;
  660.  
  661.     if ( (i=FindArg( "-piggy" )) )    {
  662.         filename    = Args[i+1];
  663.         mprintf( (0, "Using alternate pigfile, '%s'\n", filename ));
  664.     }
  665.     Piggy_fp = cfopen( filename, "rb" );
  666.     if (Piggy_fp==NULL) return 0;
  667.  
  668.     cfread( &Pigdata_start, sizeof(int), 1, Piggy_fp );
  669. #ifdef EDITOR
  670.     if ( FindArg("-nobm") )
  671. #endif
  672.     {
  673.         bm_read_all( Piggy_fp );    // Note connection to above if!!!
  674.         cfread( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, Piggy_fp );
  675.     }
  676.  
  677.     cfseek( Piggy_fp, Pigdata_start, SEEK_SET );
  678.     size = cfilelength(Piggy_fp) - Pigdata_start;
  679.     length = size;
  680.     mprintf( (0, "\nReading data (%d KB) ", size/1024 ));
  681.  
  682.     cfread( &N_bitmaps, sizeof(int), 1, Piggy_fp );
  683.     size -= sizeof(int);
  684.     cfread( &N_sounds, sizeof(int), 1, Piggy_fp );
  685.     size -= sizeof(int);
  686.  
  687.     header_size = (N_bitmaps*sizeof(DiskBitmapHeader)) + (N_sounds*sizeof(DiskSoundHeader));
  688.  
  689.     x = 60; y = 189;
  690.  
  691.     gr_set_curfont( Gamefonts[GFONT_SMALL] );    
  692.     gr_set_fontcolor(gr_find_closest_color_current( 20, 20, 20 ),-1 );
  693.     gr_printf( 0x8000, y-10, "%s...", TXT_LOADING_DATA );
  694.  
  695.     for (i=0; i<N_bitmaps; i++ )    {
  696.         cfread( &bmh, sizeof(DiskBitmapHeader), 1, Piggy_fp );
  697.         //size -= sizeof(DiskBitmapHeader);
  698.         memcpy( temp_name_read, bmh.name, 8 );
  699.         temp_name_read[8] = 0;
  700.         if ( bmh.dflags & DBM_FLAG_ABM )    
  701.             sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
  702.         else
  703.             strcpy( temp_name, temp_name_read );
  704.         memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
  705.         if ( bmh.dflags & DBM_FLAG_LARGE )
  706.             temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width+256;
  707.         else
  708.             temp_bitmap.bm_w = temp_bitmap.bm_rowsize = bmh.width;
  709.         temp_bitmap.bm_h = bmh.height;
  710.         temp_bitmap.bm_flags = BM_FLAG_PAGED_OUT;
  711.         temp_bitmap.avg_color = bmh.avg_color;
  712.         temp_bitmap.bm_data = Piggy_bitmap_cache_data;
  713.  
  714.         GameBitmapFlags[i+1] = 0;
  715.         if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_TRANSPARENT;
  716.         if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_SUPER_TRANSPARENT;
  717.         if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i+1] |= BM_FLAG_NO_LIGHTING;
  718.         if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i+1] |= BM_FLAG_RLE;
  719.  
  720.         GameBitmapOffset[i+1] = bmh.offset + header_size + (sizeof(int)*2) + Pigdata_start;
  721.         Assert( (i+1) == Num_bitmap_files );
  722.         piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
  723.     }
  724.  
  725.     for (i=0; i<N_sounds; i++ )    {
  726.         cfread( &sndh, sizeof(DiskSoundHeader), 1, Piggy_fp );
  727.         //size -= sizeof(DiskSoundHeader);
  728.         temp_sound.length = sndh.length;
  729.         temp_sound.data = (ubyte *)(sndh.offset + header_size + (sizeof(int)*2)+Pigdata_start);
  730.         SoundOffset[Num_sound_files] = sndh.offset + header_size + (sizeof(int)*2)+Pigdata_start;
  731.         memcpy( temp_name_read, sndh.name, 8 );
  732.         temp_name_read[8] = 0;
  733.         piggy_register_sound( &temp_sound, temp_name_read, 1 );
  734.         sbytes += sndh.length;
  735.         //mprintf(( 0, "%d bytes of sound\n", sbytes ));
  736.     }
  737.  
  738.     SoundBits = malloc( sbytes + 16 );
  739.     if ( SoundBits == NULL )
  740.         Error( "Not enough memory to load DESCENT.PIG sounds\n" );
  741.  
  742. #ifdef EDITOR
  743.     Piggy_bitmap_cache_size    = size - header_size - sbytes + 16;
  744.     Assert( Piggy_bitmap_cache_size > 0 );
  745. #else
  746.     Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
  747. #endif
  748.     BitmapBits = malloc( Piggy_bitmap_cache_size );
  749.     if ( BitmapBits == NULL )
  750.         Error( "Not enough memory to load DESCENT.PIG bitmaps\n" );
  751.     Piggy_bitmap_cache_data = BitmapBits;    
  752.     Piggy_bitmap_cache_next = 0;
  753.     
  754.     mprintf(( 0, "\nBitmaps: %d KB   Sounds: %d KB\n", Piggy_bitmap_cache_size/1024, sbytes/1024 ));
  755.  
  756.     atexit(piggy_close_file);
  757.  
  758. //    mprintf( (0, "<<<<Paging in all piggy bitmaps...>>>>>" ));
  759. //    for (i=0; i < Num_bitmap_files; i++ )    {
  760. //        bitmap_index bi;
  761. //        bi.index = i;
  762. //        PIGGY_PAGE_IN( bi );
  763. //    }
  764. //    mprintf( (0, "\n (USed %d / %d KB)\n", Piggy_bitmap_cache_next/1024, (size - header_size - sbytes + 16)/1024 ));
  765. //    key_getch();
  766.  
  767.     return 0;
  768. }
  769.  
  770. int piggy_is_needed(int soundnum)
  771. {
  772.     int i;
  773.  
  774.     if ( !digi_lomem ) return 1;
  775.  
  776.     for (i=0; i<MAX_SOUNDS; i++ )    {
  777.         if ( (AltSounds[i] < 255) && (Sounds[AltSounds[i]] == soundnum) )
  778.             return 1;
  779.     }
  780.     return 0;
  781. }
  782.  
  783. void piggy_read_sounds()
  784. {
  785.     ubyte * ptr;
  786.     int i, sbytes;
  787.  
  788.     ptr = SoundBits;
  789.     sbytes = 0;
  790.  
  791.     for (i=0; i<Num_sound_files; i++ )    {
  792.         digi_sound *snd = &GameSounds[i];
  793.  
  794.         if ( SoundOffset[i] > 0 )    {
  795.             if ( piggy_is_needed(i) )    {
  796.                 cfseek( Piggy_fp, SoundOffset[i], SEEK_SET );
  797.     
  798.                 // Read in the sound data!!!
  799.                 snd->data = ptr;
  800.                 ptr += snd->length;
  801.                 sbytes += snd->length;
  802.                 cfread( snd->data, snd->length, 1, Piggy_fp );
  803.             }
  804.         }
  805.     }
  806.  
  807.     mprintf(( 0, "\nActual Sound usage: %d KB\n", sbytes/1024 ));
  808.  
  809. }
  810.  
  811. extern int descent_critical_error;
  812. extern unsigned descent_critical_deverror;
  813. extern unsigned descent_critical_errcode;
  814.  
  815. char * crit_errors[13] = { "Write Protected", "Unknown Unit", "Drive Not Ready", "Unknown Command", "CRC Error", \
  816. "Bad struct length", "Seek Error", "Unknown media type", "Sector not found", "Printer out of paper", "Write Fault", \
  817. "Read fault", "General Failure" };
  818.  
  819. void piggy_critical_error()
  820. {
  821.     grs_canvas * save_canv;
  822.     grs_font * save_font;
  823.     int i;
  824.     save_canv = grd_curcanv;
  825.     save_font = grd_curcanv->cv_font;
  826.     gr_palette_load( gr_palette );
  827.     i = nm_messagebox( "Disk Error", 2, "Retry", "Exit", "%s\non drive %c:", crit_errors[descent_critical_errcode&0xf], (descent_critical_deverror&0xf)+'A'  );
  828.     if ( i == 1 )
  829.         exit(1);
  830.     gr_set_current_canvas(save_canv);
  831.     grd_curcanv->cv_font = save_font;
  832. }
  833.  
  834. void piggy_bitmap_page_in( bitmap_index bitmap )
  835. {
  836.     grs_bitmap * bmp;
  837.     int i,org_i,temp;
  838.             
  839.     i = bitmap.index;
  840.     Assert( i >= 0 );
  841.     Assert( i < MAX_BITMAP_FILES );
  842.     Assert( i < Num_bitmap_files );
  843.     Assert( Piggy_bitmap_cache_size > 0 );
  844.  
  845.     if ( i < 1 ) return;
  846.     if ( i >= MAX_BITMAP_FILES ) return;
  847.     if ( i >= Num_bitmap_files ) return;
  848.  
  849.     if ( GameBitmapOffset[i] == 0 ) return;        // A read-from-disk bitmap!!!
  850.  
  851.     if ( piggy_low_memory )    {
  852.         org_i = i;
  853.         i = GameBitmapXlat[i];        // Xlat for low-memory settings!
  854.     }
  855.     bmp = &GameBitmaps[i];
  856.     
  857.     if ( bmp->bm_flags & BM_FLAG_PAGED_OUT )    {
  858.         stop_time();
  859.  
  860.     ReDoIt:
  861.         descent_critical_error = 0;
  862.         cfseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
  863.         if ( descent_critical_error )    {
  864.             piggy_critical_error();
  865.             goto ReDoIt;
  866.         }
  867.         
  868.         bmp->bm_data = &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next];
  869.         bmp->bm_flags = GameBitmapFlags[i];
  870.     
  871.         if ( bmp->bm_flags & BM_FLAG_RLE )    {
  872.             int zsize = 0;
  873.             descent_critical_error = 0;
  874.             temp = cfread( &zsize, 1, sizeof(int), Piggy_fp );
  875.             if ( descent_critical_error )    {
  876.                 piggy_critical_error();
  877.                 goto ReDoIt;
  878.             }
  879.     
  880.             // GET JOHN NOW IF YOU GET THIS ASSERT!!!
  881.             Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );    
  882.             if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size )    {
  883.                 piggy_bitmap_page_out_all();
  884.                 goto ReDoIt;
  885.             }
  886.             memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
  887.             Piggy_bitmap_cache_next += sizeof(int);
  888.             descent_critical_error = 0;
  889.             temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, zsize-4, Piggy_fp );
  890.             if ( descent_critical_error )    {
  891.                 piggy_critical_error();
  892.                 goto ReDoIt;
  893.             }
  894.             Piggy_bitmap_cache_next += zsize-4;
  895.         } else {
  896.             // GET JOHN NOW IF YOU GET THIS ASSERT!!!
  897.             Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );    
  898.             if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size )    {
  899.                 piggy_bitmap_page_out_all();
  900.                 goto ReDoIt;
  901.             }
  902.             descent_critical_error = 0;
  903.             temp = cfread( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w, Piggy_fp );
  904.             if ( descent_critical_error )    {
  905.                 piggy_critical_error();
  906.                 goto ReDoIt;
  907.             }
  908.             Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
  909.         }
  910.     
  911.         if ( bmp->bm_selector ) {
  912.             if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
  913.                 Error( "Error modifying selector base in piggy.c\n" );
  914.         }
  915.         start_time();
  916.     }
  917.  
  918.     if ( piggy_low_memory )    {
  919.         if ( org_i != i )
  920.             GameBitmaps[org_i] = GameBitmaps[i];
  921.     }
  922.     
  923. }
  924.  
  925. void piggy_bitmap_page_out_all()
  926. {
  927.     int i;
  928.     
  929.     Piggy_bitmap_cache_next = 0;
  930.  
  931.     piggy_page_flushed++;
  932.  
  933.     texmerge_flush();
  934.     rle_cache_flush();
  935.  
  936.     for (i=0; i<Num_bitmap_files; i++ )        {
  937.         if ( GameBitmapOffset[i] > 0 )    {    // Don't page out bitmaps read from disk!!!
  938.             GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
  939.             GameBitmaps[i].bm_data = Piggy_bitmap_cache_data;
  940.         }
  941.     }
  942.  
  943.     mprintf(( 0, "Flushing piggy bitmap cache\n" ));
  944. }
  945.  
  946. void piggy_load_level_data()
  947. {
  948.     piggy_bitmap_page_out_all();
  949.     paging_touch_all();
  950. }
  951.  
  952. #ifdef EDITOR
  953. void piggy_dump_all()
  954. {
  955.     int i, xlat_offset;
  956.     FILE * fp;
  957. #ifndef RELEASE
  958.     FILE * fp1;
  959.     FILE * fp2;
  960. #endif
  961.     char * filename;
  962.     int data_offset;
  963.     int org_offset;
  964.     DiskBitmapHeader bmh;
  965.     DiskSoundHeader sndh;
  966.     int header_offset;
  967.     char subst_name[32];
  968.  
  969.     #ifdef NO_DUMP_SOUNDS
  970.     Num_sound_files = 0;
  971.     Num_sound_files_new = 0;
  972.     #endif
  973.  
  974. //    {
  975. //    bitmap_index bi;
  976. //    bi.index = 614;
  977. //    PIGGY_PAGE_IN( bi );
  978. //    count_colors( bi.index, &GameBitmaps[bi.index] );
  979. //    key_getch();
  980. //    }
  981. //    {
  982. //    bitmap_index bi;
  983. //    bi.index = 478;
  984. //    PIGGY_PAGE_IN( bi );
  985. //    Int3();
  986. //    count_colors( bi.index, &GameBitmaps[bi.index] );
  987. //    key_getch();
  988. //    }
  989. //    {
  990. //    bitmap_index bi;
  991. //    bi.index = 1398;
  992. //    PIGGY_PAGE_IN( bi );
  993. //    count_colors( bi.index, &GameBitmaps[bi.index] );
  994. //    key_getch();
  995. //    }
  996. //    {
  997. //    bitmap_index bi;
  998. //    bi.index = 642;
  999. //    PIGGY_PAGE_IN( bi );
  1000. //    count_colors( bi.index, &GameBitmaps[bi.index] );
  1001. //    key_getch();
  1002. //    }
  1003. //    {
  1004. //    bitmap_index bi;
  1005. //    bi.index = 529;
  1006. //    PIGGY_PAGE_IN( bi );
  1007. //    count_colors( bi.index, &GameBitmaps[bi.index] );
  1008. //    key_getch();
  1009. //    }
  1010. //    exit(0);
  1011. //
  1012.     if ((Num_bitmap_files_new == 0) && (Num_sound_files_new == 0) )
  1013.         return;
  1014.  
  1015.     mprintf( (0, "Paging in all piggy bitmaps..." ));
  1016.     for (i=0; i < Num_bitmap_files; i++ )    {
  1017.         bitmap_index bi;
  1018.         bi.index = i;
  1019.         PIGGY_PAGE_IN( bi );
  1020.     }
  1021.     mprintf( (0, "\n" ));
  1022.  
  1023.     piggy_close_file();
  1024.  
  1025.     mprintf( (0, "Creating DESCENT.PIG..." ));
  1026.     filename = "DESCENT.PIG";
  1027.     if ( (i=FindArg( "-piggy" )) )    {
  1028.         filename    = Args[i+1];
  1029.         mprintf( (0, "Dumping alternate pigfile, '%s'\n", filename ));
  1030.     } 
  1031.     mprintf( (0, "\nDumping bitmaps..." ));
  1032.  
  1033.     fp = fopen( filename, "wb" );
  1034.     Assert( fp!=NULL );
  1035.  
  1036. #ifndef RELEASE
  1037.     fp1 = fopen( "piggy.lst", "wt" );
  1038.     fp2 = fopen( "piggy.all", "wt" );
  1039. #endif
  1040.  
  1041.     i = 0;
  1042.     fwrite( &i, sizeof(int), 1, fp );    
  1043.     bm_write_all(fp);
  1044.     xlat_offset = ftell(fp);
  1045.     fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, fp );
  1046.     i = ftell(fp);
  1047.     fseek( fp, 0, SEEK_SET );
  1048.     fwrite( &i, sizeof(int), 1, fp );
  1049.     fseek( fp, i, SEEK_SET );
  1050.         
  1051.     Num_bitmap_files--;
  1052.     fwrite( &Num_bitmap_files, sizeof(int), 1, fp );
  1053.     Num_bitmap_files++;
  1054.     fwrite( &Num_sound_files, sizeof(int), 1, fp );
  1055.  
  1056.     header_offset = ftell(fp);
  1057.     header_offset += ((Num_bitmap_files-1)*sizeof(DiskBitmapHeader)) + (Num_sound_files*sizeof(DiskSoundHeader));
  1058.     data_offset = header_offset;
  1059.  
  1060.     for (i=1; i < Num_bitmap_files; i++ )    {
  1061.         int *size;
  1062.         grs_bitmap *bmp;
  1063.  
  1064.         {        
  1065.             char * p, *p1;
  1066.             p = strchr(AllBitmaps[i].name,'#');
  1067.             if (p)    {
  1068.                 int n;
  1069.                 p1 = p; p1++; 
  1070.                 n = atoi(p1);
  1071.                 *p = 0;
  1072. #ifndef RELEASE
  1073.                 if (n==0)    {        
  1074.                     fprintf( fp2, "%s.abm\n", AllBitmaps[i].name );
  1075.                 }    
  1076. #endif
  1077.                 memcpy( bmh.name, AllBitmaps[i].name, 8 );
  1078.                 Assert( n <= 63 );
  1079.                 bmh.dflags = DBM_FLAG_ABM + n;
  1080.                 *p = '#';
  1081.             }else {
  1082. #ifndef RELEASE
  1083.                 fprintf( fp2, "%s.bbm\n", AllBitmaps[i].name );
  1084. #endif
  1085.                 memcpy( bmh.name, AllBitmaps[i].name, 8 );
  1086.                 bmh.dflags = 0;
  1087.             }
  1088.         }
  1089.         bmp = &GameBitmaps[i];
  1090.  
  1091.         Assert( !(bmp->bm_flags&BM_FLAG_PAGED_OUT) );
  1092.  
  1093. #ifndef RELEASE
  1094.         fprintf( fp1, "BMP: %s, size %d bytes", AllBitmaps[i].name, bmp->bm_rowsize * bmp->bm_h );
  1095. #endif
  1096.         org_offset = ftell(fp);
  1097.         bmh.offset = data_offset - header_offset;
  1098.         fseek( fp, data_offset, SEEK_SET );
  1099.  
  1100.         if ( bmp->bm_flags & BM_FLAG_RLE )    {
  1101.             size = (int *)bmp->bm_data;
  1102.             fwrite( bmp->bm_data, sizeof(ubyte), *size, fp );
  1103.             data_offset += *size;
  1104.             //bmh.data_length = *size;
  1105. #ifndef RELEASE
  1106.             fprintf( fp1, ", and is already compressed to %d bytes.\n", *size );
  1107. #endif
  1108.         } else {
  1109.             fwrite( bmp->bm_data, sizeof(ubyte), bmp->bm_rowsize * bmp->bm_h, fp );
  1110.             data_offset += bmp->bm_rowsize * bmp->bm_h;
  1111.             //bmh.data_length = bmp->bm_rowsize * bmp->bm_h;
  1112. #ifndef RELEASE
  1113.             fprintf( fp1, ".\n" );
  1114. #endif
  1115.         }
  1116.         fseek( fp, org_offset, SEEK_SET );
  1117.         if ( GameBitmaps[i].bm_w > 255 )    {
  1118.             Assert( GameBitmaps[i].bm_w < 512 );
  1119.             bmh.width = GameBitmaps[i].bm_w - 256;
  1120.             bmh.dflags |= DBM_FLAG_LARGE;
  1121.         } else {
  1122.             bmh.width = GameBitmaps[i].bm_w;
  1123.         }
  1124.         Assert( GameBitmaps[i].bm_h < 256 );
  1125.         bmh.height = GameBitmaps[i].bm_h;
  1126.         bmh.flags = GameBitmaps[i].bm_flags;
  1127.         if (piggy_is_substitutable_bitmap( AllBitmaps[i].name, subst_name ))    {
  1128.             bitmap_index other_bitmap;
  1129.             other_bitmap = piggy_find_bitmap( subst_name );
  1130.             GameBitmapXlat[i] = other_bitmap.index;
  1131.             bmh.flags |= BM_FLAG_PAGED_OUT;
  1132.             //mprintf(( 0, "Skipping bitmap %d\n", i ));
  1133.             //mprintf(( 0, "Marking '%s' as substitutible\n", AllBitmaps[i].name ));
  1134.         } else    {
  1135. #ifdef BUILD_PSX_DATA
  1136.             count_colors( i, &GameBitmaps[i] );
  1137. #endif
  1138.             bmh.flags &= ~BM_FLAG_PAGED_OUT;
  1139.         }
  1140.         bmh.avg_color=GameBitmaps[i].avg_color;
  1141.         fwrite( &bmh, sizeof(DiskBitmapHeader), 1, fp );            // Mark as a bitmap
  1142.     }
  1143.  
  1144.     mprintf( (0, "\nDumping sounds..." ));
  1145.  
  1146.     for (i=0; i < Num_sound_files; i++ )    {
  1147.         digi_sound *snd;
  1148.  
  1149.         snd = &GameSounds[i];
  1150.         strcpy( sndh.name, AllSounds[i].name );
  1151.         sndh.length = GameSounds[i].length;
  1152.         sndh.offset = data_offset - header_offset;
  1153.  
  1154.         org_offset = ftell(fp);
  1155.         fseek( fp, data_offset, SEEK_SET );
  1156.  
  1157.         sndh.data_length = GameSounds[i].length;
  1158.         fwrite( snd->data, sizeof(ubyte), snd->length, fp );
  1159.         data_offset += snd->length;
  1160.         fseek( fp, org_offset, SEEK_SET );
  1161.         fwrite( &sndh, sizeof(DiskSoundHeader), 1, fp );            // Mark as a bitmap
  1162.  
  1163. #ifndef RELEASE
  1164.         fprintf( fp1, "SND: %s, size %d bytes\n", AllSounds[i].name, snd->length );
  1165.  
  1166.         fprintf( fp2, "%s.raw\n", AllSounds[i].name );
  1167. #endif
  1168.     }
  1169.  
  1170.     fseek( fp, xlat_offset, SEEK_SET );
  1171.     fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, fp );
  1172.  
  1173.     fclose(fp);
  1174.  
  1175.     mprintf( (0, "\n" ));
  1176.  
  1177.     mprintf( (0, " Dumped %d assorted bitmaps.\n", Num_bitmap_files ));
  1178.     mprintf( (0, " Dumped %d assorted sounds.\n", Num_sound_files ));
  1179.  
  1180. #ifndef RELEASE
  1181.     fprintf( fp1, " Dumped %d assorted bitmaps.\n", Num_bitmap_files );
  1182.     fprintf( fp1, " Dumped %d assorted sounds.\n", Num_sound_files );
  1183.  
  1184.     fclose(fp1);
  1185.     fclose(fp2);
  1186. #endif
  1187.  
  1188. #ifdef BUILD_PSX_DATA
  1189.     fp = fopen( "psx/descent.dat", "wb" );
  1190.     fwrite( &i, sizeof(int), 1, fp );    
  1191.     bm_write_all(fp);
  1192.     fwrite( GameBitmapXlat, sizeof(ushort)*MAX_BITMAP_FILES, 1, fp );
  1193.     fclose(fp);
  1194. #endif
  1195.  
  1196.     // Never allow the game to run after building pig.
  1197.     exit(0);
  1198. }
  1199.  
  1200. #endif
  1201.  
  1202. void piggy_close()
  1203. {
  1204.     if (BitmapBits)
  1205.         free(BitmapBits);
  1206.  
  1207.     if ( SoundBits )
  1208.         free( SoundBits );
  1209.  
  1210.     hashtable_free( &AllBitmapsNames );
  1211.     hashtable_free( &AllDigiSndNames );
  1212.  
  1213. }
  1214.  
  1215. int piggy_does_bitmap_exist_slow( char * name )
  1216. {
  1217.     int i;
  1218.  
  1219.     for (i=0; i<Num_bitmap_files; i++ )    {
  1220.         if ( !strcmp( AllBitmaps[i].name, name) )
  1221.             return 1;
  1222.     }
  1223.     return 0;
  1224. }
  1225.  
  1226.  
  1227. #define NUM_GAUGE_BITMAPS 10
  1228. char * gauge_bitmap_names[NUM_GAUGE_BITMAPS] = { "gauge01", "gauge02", "gauge06", "targ01", "targ02", "targ03", "targ04", "targ05", "targ06", "gauge18" };
  1229.  
  1230. int piggy_is_gauge_bitmap( char * base_name )
  1231. {
  1232.     int i;
  1233.     for (i=0; i<NUM_GAUGE_BITMAPS; i++ )    {
  1234.         if ( !stricmp( base_name, gauge_bitmap_names[i] ))    
  1235.             return 1;
  1236.     }
  1237.  
  1238.     return 0;    
  1239. }
  1240.  
  1241. int piggy_is_substitutable_bitmap( char * name, char * subst_name )
  1242. {
  1243.     int frame;
  1244.     char * p;
  1245.     char base_name[ 16 ];
  1246.     
  1247.     strcpy( subst_name, name );
  1248.     p = strchr( subst_name, '#' );
  1249.     if ( p )     {
  1250.         frame = atoi( &p[1] );
  1251.         *p = 0;
  1252.         strcpy( base_name, subst_name );
  1253.         if ( !piggy_is_gauge_bitmap( base_name ))    {
  1254.             sprintf( subst_name, "%s#%d", base_name, frame+1 );
  1255.             if ( piggy_does_bitmap_exist_slow( subst_name )  )     {
  1256.                 if ( frame & 1 ) {
  1257.                     sprintf( subst_name, "%s#%d", base_name, frame-1 );
  1258.                     return 1;
  1259.                 }
  1260.             }
  1261.         }
  1262.     }
  1263.     strcpy( subst_name, name );
  1264.     return 0;
  1265. }
  1266.  
  1267.