Annotation of quake1/d_surf.c, revision 1.1

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

unix.superglobalmegacorp.com

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