home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / texmerge.c < prev    next >
Text File  |  1998-06-08  |  11KB  |  414 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/texmerge.c $
  15.  * $Revision: 2.0 $
  16.  * $Author: john $
  17.  * $Date: 1995/02/27 11:31:08 $
  18.  * 
  19.  * Routines to cache merged textures.
  20.  * 
  21.  * $Log: texmerge.c $
  22.  * Revision 2.0  1995/02/27  11:31:08  john
  23.  * New version 2.0, which has no anonymous unions, builds with
  24.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  25.  * 
  26.  * Revision 1.28  1995/01/14  19:16:56  john
  27.  * First version of new bitmap paging code.
  28.  * 
  29.  * Revision 1.27  1994/12/14  18:21:58  yuan
  30.  * *** empty log message ***
  31.  * 
  32.  * Revision 1.26  1994/12/13  09:50:08  john
  33.  * Added Asserts to stop if wall looks like door.
  34.  * 
  35.  * Revision 1.25  1994/12/07  00:35:24  mike
  36.  * change how flat shading average color is computed for paste-ons.
  37.  * 
  38.  * Revision 1.24  1994/11/19  15:20:29  mike
  39.  * rip out unused code and data
  40.  * 
  41.  * Revision 1.23  1994/11/12  16:38:51  mike
  42.  * deal with avg_color in texture merging.
  43.  * 
  44.  * Revision 1.22  1994/11/09  19:55:39  john
  45.  * Added full rle support with texture rle caching.
  46.  * 
  47.  * Revision 1.21  1994/10/20  15:21:16  john
  48.  * Took out the texmerge caching.
  49.  * 
  50.  * Revision 1.20  1994/10/10  19:00:57  john
  51.  * Made caching info print every 1000 frames.
  52.  * 
  53.  * Revision 1.19  1994/10/10  18:41:21  john
  54.  * Printed out texture caching info.
  55.  * 
  56.  * Revision 1.18  1994/08/11  18:59:02  mike
  57.  * Use new assembler version of merge functions.
  58.  * 
  59.  * Revision 1.17  1994/06/09  12:13:14  john
  60.  * Changed selectors so that all bitmaps have a selector of
  61.  * 0, but inside the texture mapper they get a selector set.
  62.  * 
  63.  * Revision 1.16  1994/05/14  17:15:15  matt
  64.  * Got rid of externs in source (non-header) files
  65.  * 
  66.  * Revision 1.15  1994/05/09  17:21:09  john
  67.  * Took out mprintf with cache hits/misses.
  68.  * 
  69.  * Revision 1.14  1994/05/05  12:55:07  john
  70.  * Made SuperTransparency work.
  71.  * 
  72.  * Revision 1.13  1994/05/04  11:15:37  john
  73.  * Added Super Transparency
  74.  * 
  75.  * Revision 1.12  1994/04/28  23:36:04  john
  76.  * Took out a debugging mprintf.
  77.  * 
  78.  * Revision 1.11  1994/04/22  17:44:48  john
  79.  * Made top 2 bits of paste-ons pick the
  80.  * orientation of the bitmap.
  81.  * 
  82.  * Revision 1.10  1994/03/31  12:05:51  matt
  83.  * Cleaned up includes
  84.  * 
  85.  * Revision 1.9  1994/03/15  16:31:52  yuan
  86.  * Cleaned up bm-loading code.
  87.  * (And structures)
  88.  * 
  89.  * Revision 1.8  1994/01/24  13:15:19  john
  90.  * Made caching work with pointers, not texture numbers,
  91.  * that way, the animated textures cache.
  92.  * 
  93.  * Revision 1.7  1994/01/21  16:38:10  john
  94.  * Took out debug info.
  95.  * 
  96.  * Revision 1.6  1994/01/21  16:28:43  john
  97.  * added warning to print cache hit/miss.
  98.  * 
  99.  * Revision 1.5  1994/01/21  16:22:30  john
  100.  * Put in caching/
  101.  * 
  102.  * Revision 1.4  1994/01/21  15:34:49  john
  103.  * *** empty log message ***
  104.  * 
  105.  * Revision 1.3  1994/01/21  15:33:08  john
  106.  * *** empty log message ***
  107.  * 
  108.  * Revision 1.2  1994/01/21  15:15:35  john
  109.  * Created new module texmerge, that merges textures together and 
  110.  * caches the results.
  111.  * 
  112.  * Revision 1.1  1994/01/21  14:55:29  john
  113.  * Initial revision
  114.  * 
  115.  * 
  116.  */
  117.  
  118. #pragma off (unreferenced)
  119. static char rcsid[] = "$Id: texmerge.c 2.0 1995/02/27 11:31:08 john Exp $";
  120. #pragma on (unreferenced)
  121.  
  122. #include <stdlib.h>
  123.  
  124. #include "gr.h"
  125. #include "error.h"
  126. #include "game.h"
  127. #include "textures.h"
  128. #include "mono.h"
  129. #include "rle.h"
  130. #include "piggy.h"
  131.  
  132. #define MAX_NUM_CACHE_BITMAPS 50
  133.  
  134. //static grs_bitmap * cache_bitmaps[MAX_NUM_CACHE_BITMAPS];                     
  135.  
  136. typedef struct    {
  137.     grs_bitmap * bitmap;
  138.     grs_bitmap * bottom_bmp;
  139.     grs_bitmap * top_bmp;
  140.     int         orient;
  141.     int        last_frame_used;
  142. } TEXTURE_CACHE;
  143.  
  144. static TEXTURE_CACHE Cache[MAX_NUM_CACHE_BITMAPS];
  145.  
  146. static int num_cache_entries = 0;
  147.  
  148. static int cache_hits = 0;
  149. static int cache_misses = 0;
  150.  
  151. void texmerge_close();
  152.  
  153. //----------------------------------------------------------------------
  154.  
  155. int texmerge_init(int num_cached_textures)
  156. {
  157.     int i;
  158.  
  159.     if ( num_cached_textures <= MAX_NUM_CACHE_BITMAPS )
  160.         num_cache_entries = num_cached_textures;
  161.     else
  162.         num_cache_entries = MAX_NUM_CACHE_BITMAPS;
  163.     
  164.     for (i=0; i<num_cache_entries; i++ )    {
  165.             // Make temp tmap for use when combining
  166.         Cache[i].bitmap = gr_create_bitmap( 64, 64 );
  167.  
  168.         //if (get_selector( Cache[i].bitmap->bm_data, 64*64,  &Cache[i].bitmap->bm_selector))
  169.         //    Error( "ERROR ALLOCATING CACHE BITMAP'S SELECTORS!!!!" );
  170.  
  171.         Cache[i].last_frame_used = -1;
  172.         Cache[i].top_bmp = NULL;
  173.         Cache[i].bottom_bmp = NULL;
  174.         Cache[i].orient = -1;
  175.     }
  176.     atexit( texmerge_close );
  177.  
  178.     return 1;
  179. }
  180.  
  181. void texmerge_flush()
  182. {
  183.     int i;
  184.  
  185.     for (i=0; i<num_cache_entries; i++ )    {
  186.         Cache[i].last_frame_used = -1;
  187.         Cache[i].top_bmp = NULL;
  188.         Cache[i].bottom_bmp = NULL;
  189.         Cache[i].orient = -1;
  190.     }
  191. }
  192.  
  193.  
  194. //-------------------------------------------------------------------------
  195. void texmerge_close()
  196. {
  197.     int i;
  198.  
  199.     for (i=0; i<num_cache_entries; i++ )    {
  200.         gr_free_bitmap( Cache[i].bitmap );
  201.         Cache[i].bitmap = NULL;
  202.     }
  203. }
  204.  
  205. //--unused-- int info_printed = 0;
  206.  
  207. grs_bitmap * texmerge_get_cached_bitmap( int tmap_bottom, int tmap_top )
  208. {
  209.     grs_bitmap *bitmap_top, *bitmap_bottom;
  210.     int i, orient;
  211.     int lowest_frame_count;
  212.     int least_recently_used;
  213.  
  214. //    if ( ((FrameCount % 1000)==0) && ((cache_hits+cache_misses)>0) && (!info_printed) )    {
  215. //        mprintf( 0, "Texmap caching:  %d hits, %d misses. (Missed=%d%%)\n", cache_hits, cache_misses, (cache_misses*100)/(cache_hits+cache_misses)  );
  216. //        info_printed = 1;
  217. //    } else {
  218. //        info_printed = 0;
  219. //    }
  220.  
  221.     bitmap_top = &GameBitmaps[Textures[tmap_top&0x3FFF].index];
  222.     bitmap_bottom = &GameBitmaps[Textures[tmap_bottom].index];
  223.     
  224.     orient = ((tmap_top&0xC000)>>14) & 3;
  225.  
  226.     least_recently_used = 0;
  227.     lowest_frame_count = Cache[0].last_frame_used;
  228.     
  229.     for (i=0; i<num_cache_entries; i++ )    {
  230.         if ( (Cache[i].last_frame_used > -1) && (Cache[i].top_bmp==bitmap_top) && (Cache[i].bottom_bmp==bitmap_bottom) && (Cache[i].orient==orient ))    {
  231.             cache_hits++;
  232.             Cache[i].last_frame_used = FrameCount;
  233.             return Cache[i].bitmap;
  234.         }    
  235.         if ( Cache[i].last_frame_used < lowest_frame_count )    {
  236.             lowest_frame_count = Cache[i].last_frame_used;
  237.             least_recently_used = i;
  238.         }
  239.     }
  240.  
  241.     //---- Page out the LRU bitmap;
  242.     cache_misses++;
  243.  
  244.     // Make sure the bitmaps are paged in...
  245. #ifdef PIGGY_USE_PAGING
  246.     piggy_page_flushed = 0;
  247.  
  248.     PIGGY_PAGE_IN(Textures[tmap_top&0x3FFF]);
  249.     PIGGY_PAGE_IN(Textures[tmap_bottom]);
  250.     if (piggy_page_flushed)    {
  251.         // If cache got flushed, re-read 'em.
  252.         piggy_page_flushed = 0;
  253.         PIGGY_PAGE_IN(Textures[tmap_top&0x3FFF]);
  254.         PIGGY_PAGE_IN(Textures[tmap_bottom]);
  255.     }
  256.     Assert( piggy_page_flushed == 0 );
  257. #endif
  258.  
  259.     if (bitmap_top->bm_flags & BM_FLAG_SUPER_TRANSPARENT)    {
  260.         merge_textures_super_xparent( orient, bitmap_bottom, bitmap_top, Cache[least_recently_used].bitmap->bm_data );
  261.         Cache[least_recently_used].bitmap->bm_flags = BM_FLAG_TRANSPARENT;
  262.         Cache[least_recently_used].bitmap->avg_color = bitmap_top->avg_color;
  263.     } else    {
  264.         merge_textures_new( orient, bitmap_bottom, bitmap_top, Cache[least_recently_used].bitmap->bm_data );
  265.         Cache[least_recently_used].bitmap->bm_flags = bitmap_bottom->bm_flags & (~BM_FLAG_RLE);
  266.         Cache[least_recently_used].bitmap->avg_color = bitmap_bottom->avg_color;
  267.     }
  268.         
  269.     Cache[least_recently_used].top_bmp = bitmap_top;
  270.     Cache[least_recently_used].bottom_bmp = bitmap_bottom;
  271.     Cache[least_recently_used].last_frame_used = FrameCount;
  272.     Cache[least_recently_used].orient = orient;
  273.  
  274.     return Cache[least_recently_used].bitmap;
  275. }
  276.  
  277. void merge_textures_new( int type, grs_bitmap * bottom_bmp, grs_bitmap * top_bmp, ubyte * dest_data )
  278. {
  279. //    ubyte c;
  280. //    int x,y;
  281.     ubyte * top_data, *bottom_data;
  282.  
  283.     if ( top_bmp->bm_flags & BM_FLAG_RLE )
  284.         top_bmp = rle_expand_texture(top_bmp);
  285.  
  286.     if ( bottom_bmp->bm_flags & BM_FLAG_RLE )
  287.         bottom_bmp = rle_expand_texture(bottom_bmp);
  288.  
  289. //    Assert( bottom_bmp != top_bmp );
  290.  
  291.     top_data = top_bmp->bm_data;
  292.     bottom_data = bottom_bmp->bm_data;
  293.  
  294. //    Assert( bottom_data != top_data );
  295.  
  296.     // mprintf( 0, "Type=%d\n", type );
  297.  
  298.     switch( type )    {
  299.         case 0:
  300.             // Normal
  301.             
  302.  
  303.             gr_merge_textures( bottom_data, top_data, dest_data );
  304.             break;
  305.         case 1:
  306.             gr_merge_textures_1( bottom_data, top_data, dest_data );
  307.  
  308. //            for (y=0; y<64; y++ )
  309. //                for (x=0; x<64; x++ )    {
  310. //                    c = top_data[ 64*x+(63-y) ];        
  311. //                    if (c==255)
  312. //                        c = bottom_data[ 64*y+x ];
  313. //                    *dest_data++ = c;
  314. //                }
  315.             break;
  316.         case 2:
  317.             gr_merge_textures_2( bottom_data, top_data, dest_data );
  318. //            for (y=0; y<64; y++ )
  319. //                for (x=0; x<64; x++ )    {
  320. //                    c = top_data[ 64*(63-y)+(63-x) ];
  321. //                    if (c==255)
  322. //                        c = bottom_data[ 64*y+x ];
  323. //                    *dest_data++ = c;
  324. //                }
  325.             break;
  326.         case 3:
  327.             gr_merge_textures_3( bottom_data, top_data, dest_data );
  328. //            for (y=0; y<64; y++ )
  329. //                for (x=0; x<64; x++ )    {
  330. //                    c = top_data[ 64*(63-x)+y  ];
  331. //                    if (c==255)
  332. //                        c = bottom_data[ 64*y+x ];
  333. //                    *dest_data++ = c;
  334. //                }
  335.             break;
  336.     }
  337. }
  338.  
  339. void merge_textures_super_xparent( int type, grs_bitmap * bottom_bmp, grs_bitmap * top_bmp, ubyte * dest_data )
  340. {
  341.     ubyte c;
  342.     int x,y;
  343.  
  344.     ubyte * top_data, *bottom_data;
  345.  
  346.     if ( top_bmp->bm_flags & BM_FLAG_RLE )
  347.         top_bmp = rle_expand_texture(top_bmp);
  348.  
  349.     if ( bottom_bmp->bm_flags & BM_FLAG_RLE )
  350.         bottom_bmp = rle_expand_texture(bottom_bmp);
  351.  
  352. //    Assert( bottom_bmp != top_bmp );
  353.  
  354.     top_data = top_bmp->bm_data;
  355.     bottom_data = bottom_bmp->bm_data;
  356.  
  357. //    Assert( bottom_data != top_data );
  358.  
  359.     //mprintf( 0, "SuperX remapping type=%d\n", type );
  360.     //Int3();
  361.      
  362.     switch( type )    {
  363.         case 0:
  364.             // Normal
  365.             for (y=0; y<64; y++ )
  366.                 for (x=0; x<64; x++ )    {
  367.                     c = top_data[ 64*y+x ];        
  368.                     if (c==255)
  369.                         c = bottom_data[ 64*y+x ];
  370.                     else if (c==254)
  371.                         c = 255;
  372.                     *dest_data++ = c;
  373.                 }
  374.             break;
  375.         case 1:
  376.             // 
  377.             for (y=0; y<64; y++ )
  378.                 for (x=0; x<64; x++ )    {
  379.                     c = top_data[ 64*x+(63-y) ];        
  380.                     if (c==255)
  381.                         c = bottom_data[ 64*y+x ];
  382.                     else if (c==254)
  383.                         c = 255;
  384.                     *dest_data++ = c;
  385.                 }
  386.             break;
  387.         case 2:
  388.             // Normal
  389.             for (y=0; y<64; y++ )
  390.                 for (x=0; x<64; x++ )    {
  391.                     c = top_data[ 64*(63-y)+(63-x) ];
  392.                     if (c==255)
  393.                         c = bottom_data[ 64*y+x ];
  394.                     else if (c==254)
  395.                         c = 255;
  396.                     *dest_data++ = c;
  397.                 }
  398.             break;
  399.         case 3:
  400.             // Normal
  401.             for (y=0; y<64; y++ )
  402.                 for (x=0; x<64; x++ )    {
  403.                     c = top_data[ 64*(63-x)+y  ];
  404.                     if (c==255)
  405.                         c = bottom_data[ 64*y+x ];
  406.                     else if (c==254)
  407.                         c = 255;
  408.                     *dest_data++ = c;
  409.                 }
  410.             break;
  411.     }
  412. }
  413. 
  414.