Annotation of quakeworld/client/d_surf.c, revision 1.1.1.1

1.1       root        1: /*
                      2: Copyright (C) 1996-1997 Id Software, Inc.
                      3: 
                      4: This program is free software; you can redistribute it and/or
                      5: modify it under the terms of the GNU General Public License
                      6: as published by the Free Software Foundation; either version 2
                      7: of the License, or (at your option) any later version.
                      8: 
                      9: This program is distributed in the hope that it will be useful,
                     10: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
                     12: 
                     13: See the GNU General Public License for more details.
                     14: 
                     15: You should have received a copy of the GNU General Public License
                     16: along with this program; if not, write to the Free Software
                     17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
                     18: 
                     19: */
                     20: // d_surf.c: rasterization driver surface heap manager
                     21: 
                     22: #include "quakedef.h"
                     23: #include "d_local.h"
                     24: #include "r_local.h"
                     25: 
                     26: float           surfscale;
                     27: qboolean        r_cache_thrash;         // set if surface cache is thrashing
                     28: 
                     29: int                                     sc_size;
                     30: surfcache_t                     *sc_rover, *sc_base;
                     31: 
                     32: #define GUARDSIZE       4
                     33: 
                     34: 
                     35: int     D_SurfaceCacheForRes (int width, int height)
                     36: {
                     37:        int             size, pix;
                     38: 
                     39:        if (COM_CheckParm ("-surfcachesize"))
                     40:        {
                     41:                size = Q_atoi(com_argv[COM_CheckParm("-surfcachesize")+1]) * 1024;
                     42:                return size;
                     43:        }
                     44:        
                     45:        size = SURFCACHE_SIZE_AT_320X200;
                     46: 
                     47:        pix = width*height;
                     48:        if (pix > 64000)
                     49:                size += (pix-64000)*3;
                     50:                
                     51: 
                     52:        return size;
                     53: }
                     54: 
                     55: void D_CheckCacheGuard (void)
                     56: {
                     57:        byte    *s;
                     58:        int             i;
                     59: 
                     60:        s = (byte *)sc_base + sc_size;
                     61:        for (i=0 ; i<GUARDSIZE ; i++)
                     62:                if (s[i] != (byte)i)
                     63:                        Sys_Error ("D_CheckCacheGuard: failed");
                     64: }
                     65: 
                     66: void D_ClearCacheGuard (void)
                     67: {
                     68:        byte    *s;
                     69:        int             i;
                     70:        
                     71:        s = (byte *)sc_base + sc_size;
                     72:        for (i=0 ; i<GUARDSIZE ; i++)
                     73:                s[i] = (byte)i;
                     74: }
                     75: 
                     76: 
                     77: /*
                     78: ================
                     79: D_InitCaches
                     80: 
                     81: ================
                     82: */
                     83: void D_InitCaches (void *buffer, int size)
                     84: {
                     85: //     if (!msg_suppress_1)
                     86: //             Con_Printf ("%ik surface cache\n", size/1024);
                     87: 
                     88:        sc_size = size - GUARDSIZE;
                     89:        sc_base = (surfcache_t *)buffer;
                     90:        sc_rover = sc_base;
                     91:        
                     92:        sc_base->next = NULL;
                     93:        sc_base->owner = NULL;
                     94:        sc_base->size = sc_size;
                     95:        
                     96:        D_ClearCacheGuard ();
                     97: }
                     98: 
                     99: 
                    100: /*
                    101: ==================
                    102: D_FlushCaches
                    103: ==================
                    104: */
                    105: void D_FlushCaches (void)
                    106: {
                    107:        surfcache_t     *c;
                    108:        
                    109:        if (!sc_base)
                    110:                return;
                    111: 
                    112:        for (c = sc_base ; c ; c = c->next)
                    113:        {
                    114:                if (c->owner)
                    115:                        *c->owner = NULL;
                    116:        }
                    117:        
                    118:        sc_rover = sc_base;
                    119:        sc_base->next = NULL;
                    120:        sc_base->owner = NULL;
                    121:        sc_base->size = sc_size;
                    122: }
                    123: 
                    124: /*
                    125: =================
                    126: D_SCAlloc
                    127: =================
                    128: */
                    129: surfcache_t     *D_SCAlloc (int width, int size)
                    130: {
                    131:        surfcache_t             *new;
                    132:        qboolean                wrapped_this_time;
                    133: 
                    134:        if ((width < 0) || (width > 256))
                    135:                Sys_Error ("D_SCAlloc: bad cache width %d\n", width);
                    136: 
                    137:        if ((size <= 0) || (size > 0x10000))
                    138:                Sys_Error ("D_SCAlloc: bad cache size %d\n", size);
                    139:        
                    140: #ifdef __alpha__
                    141:        size = (int)((long)&((surfcache_t *)0)->data[size]);
                    142: #else
                    143:        size = (int)&((surfcache_t *)0)->data[size];
                    144: #endif
                    145:        size = (size + 3) & ~3;
                    146:        if (size > sc_size)
                    147:                Sys_Error ("D_SCAlloc: %i > cache size",size);
                    148: 
                    149: // if there is not size bytes after the rover, reset to the start
                    150:        wrapped_this_time = false;
                    151: 
                    152:        if ( !sc_rover || (byte *)sc_rover - (byte *)sc_base > sc_size - size)
                    153:        {
                    154:                if (sc_rover)
                    155:                {
                    156:                        wrapped_this_time = true;
                    157:                }
                    158:                sc_rover = sc_base;
                    159:        }
                    160:                
                    161: // colect and free surfcache_t blocks until the rover block is large enough
                    162:        new = sc_rover;
                    163:        if (sc_rover->owner)
                    164:                *sc_rover->owner = NULL;
                    165:        
                    166:        while (new->size < size)
                    167:        {
                    168:        // free another
                    169:                sc_rover = sc_rover->next;
                    170:                if (!sc_rover)
                    171:                        Sys_Error ("D_SCAlloc: hit the end of memory");
                    172:                if (sc_rover->owner)
                    173:                        *sc_rover->owner = NULL;
                    174:                        
                    175:                new->size += sc_rover->size;
                    176:                new->next = sc_rover->next;
                    177:        }
                    178: 
                    179: // create a fragment out of any leftovers
                    180:        if (new->size - size > 256)
                    181:        {
                    182:                sc_rover = (surfcache_t *)( (byte *)new + size);
                    183:                sc_rover->size = new->size - size;
                    184:                sc_rover->next = new->next;
                    185:                sc_rover->width = 0;
                    186:                sc_rover->owner = NULL;
                    187:                new->next = sc_rover;
                    188:                new->size = size;
                    189:        }
                    190:        else
                    191:                sc_rover = new->next;
                    192:        
                    193:        new->width = width;
                    194: // DEBUG
                    195:        if (width > 0)
                    196:                new->height = (size - sizeof(*new) + sizeof(new->data)) / width;
                    197: 
                    198:        new->owner = NULL;              // should be set properly after return
                    199: 
                    200:        if (d_roverwrapped)
                    201:        {
                    202:                if (wrapped_this_time || (sc_rover >= d_initial_rover))
                    203:                        r_cache_thrash = true;
                    204:        }
                    205:        else if (wrapped_this_time)
                    206:        {       
                    207:                d_roverwrapped = true;
                    208:        }
                    209: 
                    210: D_CheckCacheGuard ();   // DEBUG
                    211:        return new;
                    212: }
                    213: 
                    214: 
                    215: /*
                    216: =================
                    217: D_SCDump
                    218: =================
                    219: */
                    220: void D_SCDump (void)
                    221: {
                    222:        surfcache_t             *test;
                    223: 
                    224:        for (test = sc_base ; test ; test = test->next)
                    225:        {
                    226:                if (test == sc_rover)
                    227:                        Sys_Printf ("ROVER:\n");
                    228:                printf ("%p : %i bytes     %i width\n",test, test->size, test->width);
                    229:        }
                    230: }
                    231: 
                    232: //=============================================================================
                    233: 
                    234: // if the num is not a power of 2, assume it will not repeat
                    235: 
                    236: int     MaskForNum (int num)
                    237: {
                    238:        if (num==128)
                    239:                return 127;
                    240:        if (num==64)
                    241:                return 63;
                    242:        if (num==32)
                    243:                return 31;
                    244:        if (num==16)
                    245:                return 15;
                    246:        return 255;
                    247: }
                    248: 
                    249: int D_log2 (int num)
                    250: {
                    251:        int     c;
                    252:        
                    253:        c = 0;
                    254:        
                    255:        while (num>>=1)
                    256:                c++;
                    257:        return c;
                    258: }
                    259: 
                    260: //=============================================================================
                    261: 
                    262: /*
                    263: ================
                    264: D_CacheSurface
                    265: ================
                    266: */
                    267: surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel)
                    268: {
                    269:        surfcache_t     *cache;
                    270: 
                    271: //
                    272: // if the surface is animating or flashing, flush the cache
                    273: //
                    274:        r_drawsurf.texture = R_TextureAnimation (surface->texinfo->texture);
                    275:        r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]];
                    276:        r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]];
                    277:        r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]];
                    278:        r_drawsurf.lightadj[3] = d_lightstylevalue[surface->styles[3]];
                    279:        
                    280: //
                    281: // see if the cache holds apropriate data
                    282: //
                    283:        cache = surface->cachespots[miplevel];
                    284: 
                    285:        if (cache && !cache->dlight && surface->dlightframe != r_framecount
                    286:                        && cache->texture == r_drawsurf.texture
                    287:                        && cache->lightadj[0] == r_drawsurf.lightadj[0]
                    288:                        && cache->lightadj[1] == r_drawsurf.lightadj[1]
                    289:                        && cache->lightadj[2] == r_drawsurf.lightadj[2]
                    290:                        && cache->lightadj[3] == r_drawsurf.lightadj[3] )
                    291:                return cache;
                    292: 
                    293: //
                    294: // determine shape of surface
                    295: //
                    296:        surfscale = 1.0 / (1<<miplevel);
                    297:        r_drawsurf.surfmip = miplevel;
                    298:        r_drawsurf.surfwidth = surface->extents[0] >> miplevel;
                    299:        r_drawsurf.rowbytes = r_drawsurf.surfwidth;
                    300:        r_drawsurf.surfheight = surface->extents[1] >> miplevel;
                    301:        
                    302: //
                    303: // allocate memory if needed
                    304: //
                    305:        if (!cache)     // if a texture just animated, don't reallocate it
                    306:        {
                    307:                cache = D_SCAlloc (r_drawsurf.surfwidth,
                    308:                                                   r_drawsurf.surfwidth * r_drawsurf.surfheight);
                    309:                surface->cachespots[miplevel] = cache;
                    310:                cache->owner = &surface->cachespots[miplevel];
                    311:                cache->mipscale = surfscale;
                    312:        }
                    313:        
                    314:        if (surface->dlightframe == r_framecount)
                    315:                cache->dlight = 1;
                    316:        else
                    317:                cache->dlight = 0;
                    318: 
                    319:        r_drawsurf.surfdat = (pixel_t *)cache->data;
                    320:        
                    321:        cache->texture = r_drawsurf.texture;
                    322:        cache->lightadj[0] = r_drawsurf.lightadj[0];
                    323:        cache->lightadj[1] = r_drawsurf.lightadj[1];
                    324:        cache->lightadj[2] = r_drawsurf.lightadj[2];
                    325:        cache->lightadj[3] = r_drawsurf.lightadj[3];
                    326: 
                    327: //
                    328: // draw and light the surface texture
                    329: //
                    330:        r_drawsurf.surf = surface;
                    331: 
                    332:        c_surf++;
                    333:        R_DrawSurface ();
                    334: 
                    335:        return surface->cachespots[miplevel];
                    336: }
                    337: 
                    338: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.