home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / qmapwos / src / surface.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-05  |  4.6 KB  |  193 lines

  1. /*  QMAP: Quake level viewer
  2.  *
  3.  *   surface.c   Copyright 1997 Sean Barrett
  4.  *
  5.  *  Build surfaces and cache them
  6.  *  The cache is moronic, using malloc
  7.  */
  8.  
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "s.h"
  12. #include "tm.h"
  13. #include "bspfile.h"
  14. #include "surface.h"
  15. #include "tmap3d.h"
  16.  
  17. static surface_t surface[MAX_CACHED_SURFACES];  // circular queue
  18. static int surface_head, surface_tail;          // index into surfaces
  19. static int cur_cache;                           // current storage in use
  20.  
  21. static short surface_cache[MAX_MAP_FACES];      // cache entry for each face
  22.  
  23. void init_cache(void)
  24. {
  25.    int i;
  26.    for (i=0; i < MAX_MAP_FACES; ++i)
  27.       surface_cache[i] = -1;
  28. }
  29.  
  30. void get_raw_tmap(bitmap *bm, int tex, int ml)
  31. {
  32.    dmiptexlump_t *mtl = (dmiptexlump_t *) dtexdata;
  33.    miptex_t *mip;
  34.    mip = (miptex_t *) (dtexdata + mtl->dataofs[tex]);
  35.    bm->bits = (char *) mip + mip->offsets[ml];
  36.    bm->wid  = mip->width >> ml;
  37.    bm->ht   = mip->height >> ml;
  38. }
  39.  
  40. #define ADJ_SURFACE(x)    ((x) & (MAX_CACHED_SURFACES-1))
  41.  
  42. void free_surface(int surf)
  43. {
  44.    if (surface[surf].valid)
  45.       surface_cache[surface[surf].face] = -1;
  46.  
  47.    cur_cache -= surface[surf].bm->wid * surface[surf].bm->ht + sizeof(bitmap);
  48.    free(surface[surf].bm);
  49. }
  50.  
  51. void free_next_surface(void)
  52. {
  53.    if (surface_head == surface_tail) return;
  54.    free_surface(surface_tail);
  55.    surface_tail = ADJ_SURFACE(surface_tail+1);
  56. }
  57.  
  58. int allocate_cached_surface(int size)
  59. {
  60.    int surf;
  61.  
  62.    // make sure there's a free surface entry
  63.    if (ADJ_SURFACE(surface_head+1) == surface_tail)
  64.       free_next_surface();
  65.  
  66.    surf = surface_head;
  67.    surface_head = ADJ_SURFACE(surface_head+1);
  68.  
  69.    size += sizeof(bitmap);
  70.  
  71.    // make sure there's enough storage
  72.    while (cur_cache + size > MAX_CACHE)
  73.       free_next_surface();
  74.  
  75.    surface[surf].bm = malloc(size);
  76.    cur_cache += size;
  77.  
  78.    return surf;
  79. }
  80.  
  81. extern int is_cached;
  82.  
  83. void build_block(char *out, bitmap *raw, int x, int y);
  84. static int shift, global_step, global_row, lightmap_width;
  85. static uchar *light_index;
  86.  
  87. void get_tmap(bitmap *bm, int face, int tex, int ml, float *u, float *v)
  88. {
  89.    int i,j, surf, u0,v0,u1,v1, step, x,y,x0;
  90.    bitmap raw;
  91.  
  92.    is_cached = 1;
  93.  
  94.    surf = surface_cache[face];
  95.    if (surf >= 0) {
  96.       if (surface[surf].mip_level == ml) {
  97.          *bm = *surface[surf].bm;
  98.          *u  =  surface[surf].u;
  99.          *v  =  surface[surf].v;
  100.          return;
  101.       }
  102.       surface[surf].valid = 0;
  103.       surface_cache[face] = -1;
  104.    }
  105.  
  106.    get_face_extent(face, &u0, &v0, &u1, &v1);
  107.  
  108.    bm->wid  = (u1-u0) >> ml;
  109.    bm->ht   = (v1-v0) >> ml;
  110.  
  111.    if (bm->wid > 256 || bm->ht > 256) {
  112.       is_cached = 0;
  113.       get_raw_tmap(bm, tex, ml);
  114.       return;
  115.    }
  116.    get_raw_tmap(&raw, tex, ml);
  117.  
  118.  
  119.    surf = surface_cache[face] = allocate_cached_surface(bm->wid * bm->ht);
  120.    bm->bits = (char *) &surface[surf].bm[1];
  121.    *surface[surf].bm = *bm;
  122.  
  123.    surface[surf].face = face;
  124.    surface[surf].mip_level = ml;
  125.    surface[surf].valid = 1;
  126.    *u = surface[surf].u = u0;
  127.    *v = surface[surf].v = v0;
  128.  
  129.    step = 16 >> ml;   // width of lightmap after mipmapping
  130.    shift = 4-ml;      // 1 << shift  == step
  131.  
  132.    lightmap_width = ((u1 - u0) >> 4)+1;
  133.  
  134.    // compute texture offsets
  135.    u0 >>= ml;
  136.    v0 >>= ml;
  137.  
  138.    global_step = step;
  139.    global_row  = bm->wid;
  140.    light_index = &dlightdata[dfaces[face].lightofs];
  141.  
  142.    y  = v0%raw.ht;  if ( y < 0)  y += raw.ht;   // fixup for signed mod
  143.    x0 = u0%raw.wid; if (x0 < 0) x0 += raw.wid;  // fixup for signed mod
  144.  
  145.    for (j=0; j < bm->ht; j += step) {
  146.       x = x0;
  147.       for (i=0; i < bm->wid; i += step, ++light_index) {
  148.          build_block(bm->bits+j*bm->wid+i, &raw, x,y);
  149.          x += step; if (x >= raw.wid) x -= raw.wid;
  150.       }
  151.       ++light_index;
  152.       y += step; if (y >= raw.ht) y -= raw.ht;
  153.    }
  154. }
  155.  
  156. // compute one lightmap square of surface
  157. void build_block(char *out, bitmap *raw, int x, int y)
  158. {
  159.    extern char colormap[][256];
  160.    fix c,dc;
  161.    int a,b,h,c0,c1,c2,c3, step = global_step, row = global_row - step;
  162.    int y_max = raw->ht, x_max = raw->wid;
  163.    unsigned char *s = raw->bits + y*raw->wid;
  164.  
  165.    c0 = (255 - light_index[0]) << 16;
  166.    c1 = (255 - light_index[1]) << 16;
  167.    c2 = (255 - light_index[lightmap_width]) << 16;
  168.    c3 = (255 - light_index[lightmap_width+1]) << 16;
  169.  
  170.    c2 = (c2 - c0) >> shift;
  171.    c3 = (c3 - c1) >> shift;
  172.  
  173.    for (b=0; b < step; ++b) {
  174.       h = x;
  175.       c = c0;
  176.       dc = (c1 - c0) >> shift;
  177.       for (a=0; a < step; ++a) {
  178.          *out++ = colormap[c >> 18][s[h]];
  179.          c += dc;
  180.          if (++h == x_max) h = 0;
  181.       }
  182.       out += row;
  183.       c0 += c2;
  184.       c1 += c3;
  185.  
  186.       if (++y == y_max) {
  187.           y = 0;
  188.           s = raw->bits;
  189.       } else
  190.          s += raw->wid;
  191.    }
  192. }
  193.