Annotation of quakeworld/client/model.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: // models.c -- model loading and caching
                     21: 
                     22: // models are the only shared resource between a client and server running
                     23: // on the same machine.
                     24: 
                     25: #include "quakedef.h"
                     26: #include "r_local.h"
                     27: 
                     28: model_t        *loadmodel;
                     29: char   loadname[32];   // for hunk tags
                     30: 
                     31: void Mod_LoadSpriteModel (model_t *mod, void *buffer);
                     32: void Mod_LoadBrushModel (model_t *mod, void *buffer);
                     33: void Mod_LoadAliasModel (model_t *mod, void *buffer);
                     34: model_t *Mod_LoadModel (model_t *mod, qboolean crash);
                     35: 
                     36: byte   mod_novis[MAX_MAP_LEAFS/8];
                     37: 
                     38: #define        MAX_MOD_KNOWN   256
                     39: model_t        mod_known[MAX_MOD_KNOWN];
                     40: int            mod_numknown;
                     41: 
                     42: /*
                     43: ===============
                     44: Mod_Init
                     45: ===============
                     46: */
                     47: void Mod_Init (void)
                     48: {
                     49:        memset (mod_novis, 0xff, sizeof(mod_novis));
                     50: }
                     51: 
                     52: /*
                     53: ===============
                     54: Mod_Init
                     55: 
                     56: Caches the data if needed
                     57: ===============
                     58: */
                     59: void *Mod_Extradata (model_t *mod)
                     60: {
                     61:        void    *r;
                     62:        
                     63:        r = Cache_Check (&mod->cache);
                     64:        if (r)
                     65:                return r;
                     66: 
                     67:        Mod_LoadModel (mod, true);
                     68:        
                     69:        if (!mod->cache.data)
                     70:                Sys_Error ("Mod_Extradata: caching failed");
                     71:        return mod->cache.data;
                     72: }
                     73: 
                     74: /*
                     75: ===============
                     76: Mod_PointInLeaf
                     77: ===============
                     78: */
                     79: mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
                     80: {
                     81:        mnode_t         *node;
                     82:        float           d;
                     83:        mplane_t        *plane;
                     84:        
                     85:        if (!model || !model->nodes)
                     86:                Sys_Error ("Mod_PointInLeaf: bad model");
                     87: 
                     88:        node = model->nodes;
                     89:        while (1)
                     90:        {
                     91:                if (node->contents < 0)
                     92:                        return (mleaf_t *)node;
                     93:                plane = node->plane;
                     94:                d = DotProduct (p,plane->normal) - plane->dist;
                     95:                if (d > 0)
                     96:                        node = node->children[0];
                     97:                else
                     98:                        node = node->children[1];
                     99:        }
                    100:        
                    101:        return NULL;    // never reached
                    102: }
                    103: 
                    104: 
                    105: /*
                    106: ===================
                    107: Mod_DecompressVis
                    108: ===================
                    109: */
                    110: byte *Mod_DecompressVis (byte *in, model_t *model)
                    111: {
                    112:        static byte     decompressed[MAX_MAP_LEAFS/8];
                    113:        int             c;
                    114:        byte    *out;
                    115:        int             row;
                    116: 
                    117:        row = (model->numleafs+7)>>3;   
                    118:        out = decompressed;
                    119: 
                    120: #if 0
                    121:        memcpy (out, in, row);
                    122: #else
                    123:        if (!in)
                    124:        {       // no vis info, so make all visible
                    125:                while (row)
                    126:                {
                    127:                        *out++ = 0xff;
                    128:                        row--;
                    129:                }
                    130:                return decompressed;            
                    131:        }
                    132: 
                    133:        do
                    134:        {
                    135:                if (*in)
                    136:                {
                    137:                        *out++ = *in++;
                    138:                        continue;
                    139:                }
                    140:        
                    141:                c = in[1];
                    142:                in += 2;
                    143:                while (c)
                    144:                {
                    145:                        *out++ = 0;
                    146:                        c--;
                    147:                }
                    148:        } while (out - decompressed < row);
                    149: #endif
                    150:        
                    151:        return decompressed;
                    152: }
                    153: 
                    154: byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
                    155: {
                    156:        if (leaf == model->leafs)
                    157:                return mod_novis;
                    158:        return Mod_DecompressVis (leaf->compressed_vis, model);
                    159: }
                    160: 
                    161: /*
                    162: ===================
                    163: Mod_ClearAll
                    164: ===================
                    165: */
                    166: void Mod_ClearAll (void)
                    167: {
                    168:        int             i;
                    169:        model_t *mod;
                    170:        
                    171:        for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
                    172:                if (mod->type != mod_alias)
                    173:                        mod->needload = true;
                    174: }
                    175: 
                    176: /*
                    177: ==================
                    178: Mod_FindName
                    179: 
                    180: ==================
                    181: */
                    182: model_t *Mod_FindName (char *name)
                    183: {
                    184:        int             i;
                    185:        model_t *mod;
                    186:        
                    187:        if (!name[0])
                    188:                Sys_Error ("Mod_ForName: NULL name");
                    189:                
                    190: //
                    191: // search the currently loaded models
                    192: //
                    193:        for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
                    194:                if (!strcmp (mod->name, name) )
                    195:                        break;
                    196:                        
                    197:        if (i == mod_numknown)
                    198:        {
                    199:                if (mod_numknown == MAX_MOD_KNOWN)
                    200:                        Sys_Error ("mod_numknown == MAX_MOD_KNOWN");
                    201:                strcpy (mod->name, name);
                    202:                mod->needload = true;
                    203:                mod_numknown++;
                    204:        }
                    205: 
                    206:        return mod;
                    207: }
                    208: 
                    209: /*
                    210: ==================
                    211: Mod_TouchModel
                    212: 
                    213: ==================
                    214: */
                    215: void Mod_TouchModel (char *name)
                    216: {
                    217:        model_t *mod;
                    218:        
                    219:        mod = Mod_FindName (name);
                    220:        
                    221:        if (!mod->needload)
                    222:        {
                    223:                if (mod->type == mod_alias)
                    224:                        Cache_Check (&mod->cache);
                    225:        }
                    226: }
                    227: 
                    228: /*
                    229: ==================
                    230: Mod_LoadModel
                    231: 
                    232: Loads a model into the cache
                    233: ==================
                    234: */
                    235: model_t *Mod_LoadModel (model_t *mod, qboolean crash)
                    236: {
                    237:        void    *d;
                    238:        unsigned *buf;
                    239:        byte    stackbuf[1024];         // avoid dirtying the cache heap
                    240: 
                    241:        if (!mod->needload)
                    242:        {
                    243:                if (mod->type == mod_alias)
                    244:                {
                    245:                        d = Cache_Check (&mod->cache);
                    246:                        if (d)
                    247:                                return mod;
                    248:                }
                    249:                else
                    250:                        return mod;             // not cached at all
                    251:        }
                    252: 
                    253: //
                    254: // because the world is so huge, load it one piece at a time
                    255: //
                    256:        if (!crash)
                    257:        {
                    258:        
                    259:        }
                    260:        
                    261: //
                    262: // load the file
                    263: //
                    264:        buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf));
                    265:        if (!buf)
                    266:        {
                    267:                if (crash)
                    268:                        Sys_Error ("Mod_NumForName: %s not found", mod->name);
                    269:                return NULL;
                    270:        }
                    271:        
                    272: //
                    273: // allocate a new model
                    274: //
                    275:        COM_FileBase (mod->name, loadname);
                    276:        
                    277:        loadmodel = mod;
                    278: 
                    279: //
                    280: // fill it in
                    281: //
                    282: 
                    283: // call the apropriate loader
                    284:        mod->needload = false;
                    285:        
                    286:        switch (LittleLong(*(unsigned *)buf))
                    287:        {
                    288:        case IDPOLYHEADER:
                    289:                Mod_LoadAliasModel (mod, buf);
                    290:                break;
                    291:                
                    292:        case IDSPRITEHEADER:
                    293:                Mod_LoadSpriteModel (mod, buf);
                    294:                break;
                    295:        
                    296:        default:
                    297:                Mod_LoadBrushModel (mod, buf);
                    298:                break;
                    299:        }
                    300: 
                    301:        return mod;
                    302: }
                    303: 
                    304: /*
                    305: ==================
                    306: Mod_ForName
                    307: 
                    308: Loads in a model for the given name
                    309: ==================
                    310: */
                    311: model_t *Mod_ForName (char *name, qboolean crash)
                    312: {
                    313:        model_t *mod;
                    314:        
                    315:        mod = Mod_FindName (name);
                    316:        
                    317:        return Mod_LoadModel (mod, crash);
                    318: }
                    319: 
                    320: 
                    321: /*
                    322: ===============================================================================
                    323: 
                    324:                                        BRUSHMODEL LOADING
                    325: 
                    326: ===============================================================================
                    327: */
                    328: 
                    329: byte   *mod_base;
                    330: 
                    331: 
                    332: /*
                    333: =================
                    334: Mod_LoadTextures
                    335: =================
                    336: */
                    337: void Mod_LoadTextures (lump_t *l)
                    338: {
                    339:        int             i, j, pixels, num, max, altmax;
                    340:        miptex_t        *mt;
                    341:        texture_t       *tx, *tx2;
                    342:        texture_t       *anims[10];
                    343:        texture_t       *altanims[10];
                    344:        dmiptexlump_t *m;
                    345: 
                    346:        if (!l->filelen)
                    347:        {
                    348:                loadmodel->textures = NULL;
                    349:                return;
                    350:        }
                    351:        m = (dmiptexlump_t *)(mod_base + l->fileofs);
                    352:        
                    353:        m->nummiptex = LittleLong (m->nummiptex);
                    354:        
                    355:        loadmodel->numtextures = m->nummiptex;
                    356:        loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname);
                    357: 
                    358:        for (i=0 ; i<m->nummiptex ; i++)
                    359:        {
                    360:                m->dataofs[i] = LittleLong(m->dataofs[i]);
                    361:                if (m->dataofs[i] == -1)
                    362:                        continue;
                    363:                mt = (miptex_t *)((byte *)m + m->dataofs[i]);
                    364:                mt->width = LittleLong (mt->width);
                    365:                mt->height = LittleLong (mt->height);
                    366:                for (j=0 ; j<MIPLEVELS ; j++)
                    367:                        mt->offsets[j] = LittleLong (mt->offsets[j]);
                    368:                
                    369:                if ( (mt->width & 15) || (mt->height & 15) )
                    370:                        Sys_Error ("Texture %s is not 16 aligned", mt->name);
                    371:                pixels = mt->width*mt->height/64*85;
                    372:                tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
                    373:                loadmodel->textures[i] = tx;
                    374: 
                    375:                memcpy (tx->name, mt->name, sizeof(tx->name));
                    376:                tx->width = mt->width;
                    377:                tx->height = mt->height;
                    378:                for (j=0 ; j<MIPLEVELS ; j++)
                    379:                        tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
                    380:                // the pixels immediately follow the structures
                    381:                memcpy ( tx+1, mt+1, pixels);
                    382:                
                    383:                if (!Q_strncmp(mt->name,"sky",3))       
                    384:                        R_InitSky (tx);
                    385:        }
                    386: 
                    387: //
                    388: // sequence the animations
                    389: //
                    390:        for (i=0 ; i<m->nummiptex ; i++)
                    391:        {
                    392:                tx = loadmodel->textures[i];
                    393:                if (!tx || tx->name[0] != '+')
                    394:                        continue;
                    395:                if (tx->anim_next)
                    396:                        continue;       // allready sequenced
                    397: 
                    398:        // find the number of frames in the animation
                    399:                memset (anims, 0, sizeof(anims));
                    400:                memset (altanims, 0, sizeof(altanims));
                    401: 
                    402:                max = tx->name[1];
                    403:                altmax = 0;
                    404:                if (max >= 'a' && max <= 'z')
                    405:                        max -= 'a' - 'A';
                    406:                if (max >= '0' && max <= '9')
                    407:                {
                    408:                        max -= '0';
                    409:                        altmax = 0;
                    410:                        anims[max] = tx;
                    411:                        max++;
                    412:                }
                    413:                else if (max >= 'A' && max <= 'J')
                    414:                {
                    415:                        altmax = max - 'A';
                    416:                        max = 0;
                    417:                        altanims[altmax] = tx;
                    418:                        altmax++;
                    419:                }
                    420:                else
                    421:                        Sys_Error ("Bad animating texture %s", tx->name);
                    422: 
                    423:                for (j=i+1 ; j<m->nummiptex ; j++)
                    424:                {
                    425:                        tx2 = loadmodel->textures[j];
                    426:                        if (!tx2 || tx2->name[0] != '+')
                    427:                                continue;
                    428:                        if (strcmp (tx2->name+2, tx->name+2))
                    429:                                continue;
                    430: 
                    431:                        num = tx2->name[1];
                    432:                        if (num >= 'a' && num <= 'z')
                    433:                                num -= 'a' - 'A';
                    434:                        if (num >= '0' && num <= '9')
                    435:                        {
                    436:                                num -= '0';
                    437:                                anims[num] = tx2;
                    438:                                if (num+1 > max)
                    439:                                        max = num + 1;
                    440:                        }
                    441:                        else if (num >= 'A' && num <= 'J')
                    442:                        {
                    443:                                num = num - 'A';
                    444:                                altanims[num] = tx2;
                    445:                                if (num+1 > altmax)
                    446:                                        altmax = num+1;
                    447:                        }
                    448:                        else
                    449:                                Sys_Error ("Bad animating texture %s", tx->name);
                    450:                }
                    451:                
                    452: #define        ANIM_CYCLE      2
                    453:        // link them all together
                    454:                for (j=0 ; j<max ; j++)
                    455:                {
                    456:                        tx2 = anims[j];
                    457:                        if (!tx2)
                    458:                                Sys_Error ("Missing frame %i of %s",j, tx->name);
                    459:                        tx2->anim_total = max * ANIM_CYCLE;
                    460:                        tx2->anim_min = j * ANIM_CYCLE;
                    461:                        tx2->anim_max = (j+1) * ANIM_CYCLE;
                    462:                        tx2->anim_next = anims[ (j+1)%max ];
                    463:                        if (altmax)
                    464:                                tx2->alternate_anims = altanims[0];
                    465:                }
                    466:                for (j=0 ; j<altmax ; j++)
                    467:                {
                    468:                        tx2 = altanims[j];
                    469:                        if (!tx2)
                    470:                                Sys_Error ("Missing frame %i of %s",j, tx->name);
                    471:                        tx2->anim_total = altmax * ANIM_CYCLE;
                    472:                        tx2->anim_min = j * ANIM_CYCLE;
                    473:                        tx2->anim_max = (j+1) * ANIM_CYCLE;
                    474:                        tx2->anim_next = altanims[ (j+1)%altmax ];
                    475:                        if (max)
                    476:                                tx2->alternate_anims = anims[0];
                    477:                }
                    478:        }
                    479: }
                    480: 
                    481: /*
                    482: =================
                    483: Mod_LoadLighting
                    484: =================
                    485: */
                    486: void Mod_LoadLighting (lump_t *l)
                    487: {
                    488:        if (!l->filelen)
                    489:        {
                    490:                loadmodel->lightdata = NULL;
                    491:                return;
                    492:        }
                    493:        loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname);  
                    494:        memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
                    495: }
                    496: 
                    497: 
                    498: /*
                    499: =================
                    500: Mod_LoadVisibility
                    501: =================
                    502: */
                    503: void Mod_LoadVisibility (lump_t *l)
                    504: {
                    505:        if (!l->filelen)
                    506:        {
                    507:                loadmodel->visdata = NULL;
                    508:                return;
                    509:        }
                    510:        loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname);    
                    511:        memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
                    512: }
                    513: 
                    514: 
                    515: /*
                    516: =================
                    517: Mod_LoadEntities
                    518: =================
                    519: */
                    520: void Mod_LoadEntities (lump_t *l)
                    521: {
                    522:        if (!l->filelen)
                    523:        {
                    524:                loadmodel->entities = NULL;
                    525:                return;
                    526:        }
                    527:        loadmodel->entities = Hunk_AllocName ( l->filelen, loadname);   
                    528:        memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen);
                    529: }
                    530: 
                    531: 
                    532: /*
                    533: =================
                    534: Mod_LoadVertexes
                    535: =================
                    536: */
                    537: void Mod_LoadVertexes (lump_t *l)
                    538: {
                    539:        dvertex_t       *in;
                    540:        mvertex_t       *out;
                    541:        int                     i, count;
                    542: 
                    543:        in = (void *)(mod_base + l->fileofs);
                    544:        if (l->filelen % sizeof(*in))
                    545:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    546:        count = l->filelen / sizeof(*in);
                    547:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
                    548: 
                    549:        loadmodel->vertexes = out;
                    550:        loadmodel->numvertexes = count;
                    551: 
                    552:        for ( i=0 ; i<count ; i++, in++, out++)
                    553:        {
                    554:                out->position[0] = LittleFloat (in->point[0]);
                    555:                out->position[1] = LittleFloat (in->point[1]);
                    556:                out->position[2] = LittleFloat (in->point[2]);
                    557:        }
                    558: }
                    559: 
                    560: /*
                    561: =================
                    562: Mod_LoadSubmodels
                    563: =================
                    564: */
                    565: void Mod_LoadSubmodels (lump_t *l)
                    566: {
                    567:        dmodel_t        *in;
                    568:        dmodel_t        *out;
                    569:        int                     i, j, count;
                    570: 
                    571:        in = (void *)(mod_base + l->fileofs);
                    572:        if (l->filelen % sizeof(*in))
                    573:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    574:        count = l->filelen / sizeof(*in);
                    575:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
                    576: 
                    577:        loadmodel->submodels = out;
                    578:        loadmodel->numsubmodels = count;
                    579: 
                    580:        for ( i=0 ; i<count ; i++, in++, out++)
                    581:        {
                    582:                for (j=0 ; j<3 ; j++)
                    583:                {       // spread the mins / maxs by a pixel
                    584:                        out->mins[j] = LittleFloat (in->mins[j]) - 1;
                    585:                        out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
                    586:                        out->origin[j] = LittleFloat (in->origin[j]);
                    587:                }
                    588:                for (j=0 ; j<MAX_MAP_HULLS ; j++)
                    589:                        out->headnode[j] = LittleLong (in->headnode[j]);
                    590:                out->visleafs = LittleLong (in->visleafs);
                    591:                out->firstface = LittleLong (in->firstface);
                    592:                out->numfaces = LittleLong (in->numfaces);
                    593:        }
                    594: }
                    595: 
                    596: /*
                    597: =================
                    598: Mod_LoadEdges
                    599: =================
                    600: */
                    601: void Mod_LoadEdges (lump_t *l)
                    602: {
                    603:        dedge_t *in;
                    604:        medge_t *out;
                    605:        int     i, count;
                    606: 
                    607:        in = (void *)(mod_base + l->fileofs);
                    608:        if (l->filelen % sizeof(*in))
                    609:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    610:        count = l->filelen / sizeof(*in);
                    611:        out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname);   
                    612: 
                    613:        loadmodel->edges = out;
                    614:        loadmodel->numedges = count;
                    615: 
                    616:        for ( i=0 ; i<count ; i++, in++, out++)
                    617:        {
                    618:                out->v[0] = (unsigned short)LittleShort(in->v[0]);
                    619:                out->v[1] = (unsigned short)LittleShort(in->v[1]);
                    620:        }
                    621: }
                    622: 
                    623: /*
                    624: =================
                    625: Mod_LoadTexinfo
                    626: =================
                    627: */
                    628: void Mod_LoadTexinfo (lump_t *l)
                    629: {
                    630:        texinfo_t *in;
                    631:        mtexinfo_t *out;
                    632:        int     i, j, count;
                    633:        int             miptex;
                    634:        float   len1, len2;
                    635: 
                    636:        in = (void *)(mod_base + l->fileofs);
                    637:        if (l->filelen % sizeof(*in))
                    638:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    639:        count = l->filelen / sizeof(*in);
                    640:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
                    641: 
                    642:        loadmodel->texinfo = out;
                    643:        loadmodel->numtexinfo = count;
                    644: 
                    645:        for ( i=0 ; i<count ; i++, in++, out++)
                    646:        {
                    647:                for (j=0 ; j<8 ; j++)
                    648:                        out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
                    649:                len1 = Length (out->vecs[0]);
                    650:                len2 = Length (out->vecs[1]);
                    651:                len1 = (len1 + len2)/2;
                    652:                if (len1 < 0.32)
                    653:                        out->mipadjust = 4;
                    654:                else if (len1 < 0.49)
                    655:                        out->mipadjust = 3;
                    656:                else if (len1 < 0.99)
                    657:                        out->mipadjust = 2;
                    658:                else
                    659:                        out->mipadjust = 1;
                    660: #if 0
                    661:                if (len1 + len2 < 0.001)
                    662:                        out->mipadjust = 1;             // don't crash
                    663:                else
                    664:                        out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 );
                    665: #endif
                    666: 
                    667:                miptex = LittleLong (in->miptex);
                    668:                out->flags = LittleLong (in->flags);
                    669:        
                    670:                if (!loadmodel->textures)
                    671:                {
                    672:                        out->texture = r_notexture_mip; // checkerboard texture
                    673:                        out->flags = 0;
                    674:                }
                    675:                else
                    676:                {
                    677:                        if (miptex >= loadmodel->numtextures)
                    678:                                Sys_Error ("miptex >= loadmodel->numtextures");
                    679:                        out->texture = loadmodel->textures[miptex];
                    680:                        if (!out->texture)
                    681:                        {
                    682:                                out->texture = r_notexture_mip; // texture not found
                    683:                                out->flags = 0;
                    684:                        }
                    685:                }
                    686:        }
                    687: }
                    688: 
                    689: /*
                    690: ================
                    691: CalcSurfaceExtents
                    692: 
                    693: Fills in s->texturemins[] and s->extents[]
                    694: ================
                    695: */
                    696: void CalcSurfaceExtents (msurface_t *s)
                    697: {
                    698:        float   mins[2], maxs[2], val;
                    699:        int             i,j, e;
                    700:        mvertex_t       *v;
                    701:        mtexinfo_t      *tex;
                    702:        int             bmins[2], bmaxs[2];
                    703: 
                    704:        mins[0] = mins[1] = 999999;
                    705:        maxs[0] = maxs[1] = -99999;
                    706: 
                    707:        tex = s->texinfo;
                    708:        
                    709:        for (i=0 ; i<s->numedges ; i++)
                    710:        {
                    711:                e = loadmodel->surfedges[s->firstedge+i];
                    712:                if (e >= 0)
                    713:                        v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
                    714:                else
                    715:                        v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
                    716:                
                    717:                for (j=0 ; j<2 ; j++)
                    718:                {
                    719:                        val = v->position[0] * tex->vecs[j][0] + 
                    720:                                v->position[1] * tex->vecs[j][1] +
                    721:                                v->position[2] * tex->vecs[j][2] +
                    722:                                tex->vecs[j][3];
                    723:                        if (val < mins[j])
                    724:                                mins[j] = val;
                    725:                        if (val > maxs[j])
                    726:                                maxs[j] = val;
                    727:                }
                    728:        }
                    729: 
                    730:        for (i=0 ; i<2 ; i++)
                    731:        {       
                    732:                bmins[i] = floor(mins[i]/16);
                    733:                bmaxs[i] = ceil(maxs[i]/16);
                    734: 
                    735:                s->texturemins[i] = bmins[i] * 16;
                    736:                s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
                    737:                if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 256)
                    738:                        Sys_Error ("Bad surface extents");
                    739:        }
                    740: }
                    741: 
                    742: 
                    743: /*
                    744: =================
                    745: Mod_LoadFaces
                    746: =================
                    747: */
                    748: void Mod_LoadFaces (lump_t *l)
                    749: {
                    750:        dface_t         *in;
                    751:        msurface_t      *out;
                    752:        int                     i, count, surfnum;
                    753:        int                     planenum, side;
                    754: 
                    755:        in = (void *)(mod_base + l->fileofs);
                    756:        if (l->filelen % sizeof(*in))
                    757:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    758:        count = l->filelen / sizeof(*in);
                    759:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
                    760: 
                    761:        loadmodel->surfaces = out;
                    762:        loadmodel->numsurfaces = count;
                    763: 
                    764:        for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
                    765:        {
                    766:                out->firstedge = LittleLong(in->firstedge);
                    767:                out->numedges = LittleShort(in->numedges);              
                    768:                out->flags = 0;
                    769: 
                    770:                planenum = LittleShort(in->planenum);
                    771:                side = LittleShort(in->side);
                    772:                if (side)
                    773:                        out->flags |= SURF_PLANEBACK;                   
                    774: 
                    775:                out->plane = loadmodel->planes + planenum;
                    776: 
                    777:                out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
                    778: 
                    779:                CalcSurfaceExtents (out);
                    780:                                
                    781:        // lighting info
                    782: 
                    783:                for (i=0 ; i<MAXLIGHTMAPS ; i++)
                    784:                        out->styles[i] = in->styles[i];
                    785:                i = LittleLong(in->lightofs);
                    786:                if (i == -1)
                    787:                        out->samples = NULL;
                    788:                else
                    789:                        out->samples = loadmodel->lightdata + i;
                    790:                
                    791:        // set the drawing flags flag
                    792:                
                    793:                if (!Q_strncmp(out->texinfo->texture->name,"sky",3))    // sky
                    794:                {
                    795:                        out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED);
                    796:                        continue;
                    797:                }
                    798:                
                    799:                if (!Q_strncmp(out->texinfo->texture->name,"*",1))              // turbulent
                    800:                {
                    801:                        out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED);
                    802:                        for (i=0 ; i<2 ; i++)
                    803:                        {
                    804:                                out->extents[i] = 16384;
                    805:                                out->texturemins[i] = -8192;
                    806:                        }
                    807:                        continue;
                    808:                }
                    809:        }
                    810: }
                    811: 
                    812: 
                    813: /*
                    814: =================
                    815: Mod_SetParent
                    816: =================
                    817: */
                    818: void Mod_SetParent (mnode_t *node, mnode_t *parent)
                    819: {
                    820:        node->parent = parent;
                    821:        if (node->contents < 0)
                    822:                return;
                    823:        Mod_SetParent (node->children[0], node);
                    824:        Mod_SetParent (node->children[1], node);
                    825: }
                    826: 
                    827: /*
                    828: =================
                    829: Mod_LoadNodes
                    830: =================
                    831: */
                    832: void Mod_LoadNodes (lump_t *l)
                    833: {
                    834:        int                     i, j, count, p;
                    835:        dnode_t         *in;
                    836:        mnode_t         *out;
                    837: 
                    838:        in = (void *)(mod_base + l->fileofs);
                    839:        if (l->filelen % sizeof(*in))
                    840:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    841:        count = l->filelen / sizeof(*in);
                    842:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
                    843: 
                    844:        loadmodel->nodes = out;
                    845:        loadmodel->numnodes = count;
                    846: 
                    847:        for ( i=0 ; i<count ; i++, in++, out++)
                    848:        {
                    849:                for (j=0 ; j<3 ; j++)
                    850:                {
                    851:                        out->minmaxs[j] = LittleShort (in->mins[j]);
                    852:                        out->minmaxs[3+j] = LittleShort (in->maxs[j]);
                    853:                }
                    854:        
                    855:                p = LittleLong(in->planenum);
                    856:                out->plane = loadmodel->planes + p;
                    857: 
                    858:                out->firstsurface = LittleShort (in->firstface);
                    859:                out->numsurfaces = LittleShort (in->numfaces);
                    860:                
                    861:                for (j=0 ; j<2 ; j++)
                    862:                {
                    863:                        p = LittleShort (in->children[j]);
                    864:                        if (p >= 0)
                    865:                                out->children[j] = loadmodel->nodes + p;
                    866:                        else
                    867:                                out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
                    868:                }
                    869:        }
                    870:        
                    871:        Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
                    872: }
                    873: 
                    874: /*
                    875: =================
                    876: Mod_LoadLeafs
                    877: =================
                    878: */
                    879: void Mod_LoadLeafs (lump_t *l)
                    880: {
                    881:        dleaf_t         *in;
                    882:        mleaf_t         *out;
                    883:        int                     i, j, count, p;
                    884: 
                    885:        in = (void *)(mod_base + l->fileofs);
                    886:        if (l->filelen % sizeof(*in))
                    887:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    888:        count = l->filelen / sizeof(*in);
                    889:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
                    890: 
                    891:        loadmodel->leafs = out;
                    892:        loadmodel->numleafs = count;
                    893: 
                    894:        for ( i=0 ; i<count ; i++, in++, out++)
                    895:        {
                    896:                for (j=0 ; j<3 ; j++)
                    897:                {
                    898:                        out->minmaxs[j] = LittleShort (in->mins[j]);
                    899:                        out->minmaxs[3+j] = LittleShort (in->maxs[j]);
                    900:                }
                    901: 
                    902:                p = LittleLong(in->contents);
                    903:                out->contents = p;
                    904: 
                    905:                out->firstmarksurface = loadmodel->marksurfaces +
                    906:                        LittleShort(in->firstmarksurface);
                    907:                out->nummarksurfaces = LittleShort(in->nummarksurfaces);
                    908:                
                    909:                p = LittleLong(in->visofs);
                    910:                if (p == -1)
                    911:                        out->compressed_vis = NULL;
                    912:                else
                    913:                        out->compressed_vis = loadmodel->visdata + p;
                    914:                out->efrags = NULL;
                    915:                
                    916:                for (j=0 ; j<4 ; j++)
                    917:                        out->ambient_sound_level[j] = in->ambient_level[j];
                    918:        }       
                    919: }
                    920: 
                    921: /*
                    922: =================
                    923: Mod_LoadClipnodes
                    924: =================
                    925: */
                    926: void Mod_LoadClipnodes (lump_t *l)
                    927: {
                    928:        dclipnode_t *in, *out;
                    929:        int                     i, count;
                    930:        hull_t          *hull;
                    931: 
                    932:        in = (void *)(mod_base + l->fileofs);
                    933:        if (l->filelen % sizeof(*in))
                    934:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    935:        count = l->filelen / sizeof(*in);
                    936:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
                    937: 
                    938:        loadmodel->clipnodes = out;
                    939:        loadmodel->numclipnodes = count;
                    940: 
                    941:        hull = &loadmodel->hulls[1];
                    942:        hull->clipnodes = out;
                    943:        hull->firstclipnode = 0;
                    944:        hull->lastclipnode = count-1;
                    945:        hull->planes = loadmodel->planes;
                    946:        hull->clip_mins[0] = -16;
                    947:        hull->clip_mins[1] = -16;
                    948:        hull->clip_mins[2] = -24;
                    949:        hull->clip_maxs[0] = 16;
                    950:        hull->clip_maxs[1] = 16;
                    951:        hull->clip_maxs[2] = 32;
                    952: 
                    953:        hull = &loadmodel->hulls[2];
                    954:        hull->clipnodes = out;
                    955:        hull->firstclipnode = 0;
                    956:        hull->lastclipnode = count-1;
                    957:        hull->planes = loadmodel->planes;
                    958:        hull->clip_mins[0] = -32;
                    959:        hull->clip_mins[1] = -32;
                    960:        hull->clip_mins[2] = -24;
                    961:        hull->clip_maxs[0] = 32;
                    962:        hull->clip_maxs[1] = 32;
                    963:        hull->clip_maxs[2] = 64;
                    964: 
                    965:        for (i=0 ; i<count ; i++, out++, in++)
                    966:        {
                    967:                out->planenum = LittleLong(in->planenum);
                    968:                out->children[0] = LittleShort(in->children[0]);
                    969:                out->children[1] = LittleShort(in->children[1]);
                    970:        }
                    971: }
                    972: 
                    973: /*
                    974: =================
                    975: Mod_MakeHull0
                    976: 
                    977: Deplicate the drawing hull structure as a clipping hull
                    978: =================
                    979: */
                    980: void Mod_MakeHull0 (void)
                    981: {
                    982:        mnode_t         *in, *child;
                    983:        dclipnode_t *out;
                    984:        int                     i, j, count;
                    985:        hull_t          *hull;
                    986:        
                    987:        hull = &loadmodel->hulls[0];    
                    988:        
                    989:        in = loadmodel->nodes;
                    990:        count = loadmodel->numnodes;
                    991:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
                    992: 
                    993:        hull->clipnodes = out;
                    994:        hull->firstclipnode = 0;
                    995:        hull->lastclipnode = count-1;
                    996:        hull->planes = loadmodel->planes;
                    997: 
                    998:        for (i=0 ; i<count ; i++, out++, in++)
                    999:        {
                   1000:                out->planenum = in->plane - loadmodel->planes;
                   1001:                for (j=0 ; j<2 ; j++)
                   1002:                {
                   1003:                        child = in->children[j];
                   1004:                        if (child->contents < 0)
                   1005:                                out->children[j] = child->contents;
                   1006:                        else
                   1007:                                out->children[j] = child - loadmodel->nodes;
                   1008:                }
                   1009:        }
                   1010: }
                   1011: 
                   1012: /*
                   1013: =================
                   1014: Mod_LoadMarksurfaces
                   1015: =================
                   1016: */
                   1017: void Mod_LoadMarksurfaces (lump_t *l)
                   1018: {      
                   1019:        int             i, j, count;
                   1020:        short           *in;
                   1021:        msurface_t **out;
                   1022:        
                   1023:        in = (void *)(mod_base + l->fileofs);
                   1024:        if (l->filelen % sizeof(*in))
                   1025:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                   1026:        count = l->filelen / sizeof(*in);
                   1027:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
                   1028: 
                   1029:        loadmodel->marksurfaces = out;
                   1030:        loadmodel->nummarksurfaces = count;
                   1031: 
                   1032:        for ( i=0 ; i<count ; i++)
                   1033:        {
                   1034:                j = LittleShort(in[i]);
                   1035:                if (j >= loadmodel->numsurfaces)
                   1036:                        Sys_Error ("Mod_ParseMarksurfaces: bad surface number");
                   1037:                out[i] = loadmodel->surfaces + j;
                   1038:        }
                   1039: }
                   1040: 
                   1041: /*
                   1042: =================
                   1043: Mod_LoadSurfedges
                   1044: =================
                   1045: */
                   1046: void Mod_LoadSurfedges (lump_t *l)
                   1047: {      
                   1048:        int             i, count;
                   1049:        int             *in, *out;
                   1050:        
                   1051:        in = (void *)(mod_base + l->fileofs);
                   1052:        if (l->filelen % sizeof(*in))
                   1053:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                   1054:        count = l->filelen / sizeof(*in);
                   1055:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
                   1056: 
                   1057:        loadmodel->surfedges = out;
                   1058:        loadmodel->numsurfedges = count;
                   1059: 
                   1060:        for ( i=0 ; i<count ; i++)
                   1061:                out[i] = LittleLong (in[i]);
                   1062: }
                   1063: 
                   1064: /*
                   1065: =================
                   1066: Mod_LoadPlanes
                   1067: =================
                   1068: */
                   1069: void Mod_LoadPlanes (lump_t *l)
                   1070: {
                   1071:        int                     i, j;
                   1072:        mplane_t        *out;
                   1073:        dplane_t        *in;
                   1074:        int                     count;
                   1075:        int                     bits;
                   1076:        
                   1077:        in = (void *)(mod_base + l->fileofs);
                   1078:        if (l->filelen % sizeof(*in))
                   1079:                Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                   1080:        count = l->filelen / sizeof(*in);
                   1081:        out = Hunk_AllocName ( count*2*sizeof(*out), loadname); 
                   1082:        
                   1083:        loadmodel->planes = out;
                   1084:        loadmodel->numplanes = count;
                   1085: 
                   1086:        for ( i=0 ; i<count ; i++, in++, out++)
                   1087:        {
                   1088:                bits = 0;
                   1089:                for (j=0 ; j<3 ; j++)
                   1090:                {
                   1091:                        out->normal[j] = LittleFloat (in->normal[j]);
                   1092:                        if (out->normal[j] < 0)
                   1093:                                bits |= 1<<j;
                   1094:                }
                   1095: 
                   1096:                out->dist = LittleFloat (in->dist);
                   1097:                out->type = LittleLong (in->type);
                   1098:                out->signbits = bits;
                   1099:        }
                   1100: }
                   1101: 
                   1102: /*
                   1103: =================
                   1104: RadiusFromBounds
                   1105: =================
                   1106: */
                   1107: float RadiusFromBounds (vec3_t mins, vec3_t maxs)
                   1108: {
                   1109:        int             i;
                   1110:        vec3_t  corner;
                   1111: 
                   1112:        for (i=0 ; i<3 ; i++)
                   1113:        {
                   1114:                corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
                   1115:        }
                   1116: 
                   1117:        return Length (corner);
                   1118: }
                   1119: 
                   1120: /*
                   1121: =================
                   1122: Mod_LoadBrushModel
                   1123: =================
                   1124: */
                   1125: void Mod_LoadBrushModel (model_t *mod, void *buffer)
                   1126: {
                   1127:        int                     i, j;
                   1128:        dheader_t       *header;
                   1129:        dmodel_t        *bm;
                   1130:        
                   1131:        loadmodel->type = mod_brush;
                   1132:        
                   1133:        header = (dheader_t *)buffer;
                   1134: 
                   1135:        i = LittleLong (header->version);
                   1136:        if (i != BSPVERSION)
                   1137:                Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
                   1138: 
                   1139: // swap all the lumps
                   1140:        mod_base = (byte *)header;
                   1141: 
                   1142:        for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
                   1143:                ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
                   1144: 
                   1145:        mod->checksum = 0;
                   1146:        mod->checksum2 = 0;
                   1147: 
                   1148: // checksum all of the map, except for entities
                   1149:        for (i = 0; i < HEADER_LUMPS; i++) {
                   1150:                if (i == LUMP_ENTITIES)
                   1151:                        continue;
                   1152:                mod->checksum ^= Com_BlockChecksum(mod_base + header->lumps[i].fileofs, 
                   1153:                        header->lumps[i].filelen);
                   1154: 
                   1155:                if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES)
                   1156:                        continue;
                   1157:                mod->checksum2 ^= Com_BlockChecksum(mod_base + header->lumps[i].fileofs, 
                   1158:                        header->lumps[i].filelen);
                   1159:        }
                   1160:        
                   1161: // load into heap
                   1162: 
                   1163:        Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
                   1164:        Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
                   1165:        Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
                   1166:        Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
                   1167:        Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
                   1168:        Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
                   1169:        Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
                   1170:        Mod_LoadFaces (&header->lumps[LUMP_FACES]);
                   1171:        Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
                   1172:        Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
                   1173:        Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
                   1174:        Mod_LoadNodes (&header->lumps[LUMP_NODES]);
                   1175:        Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]);
                   1176:        Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]);
                   1177:        Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
                   1178: 
                   1179:        Mod_MakeHull0 ();
                   1180:        
                   1181:        mod->numframes = 2;             // regular and alternate animation
                   1182:        
                   1183: //
                   1184: // set up the submodels (FIXME: this is confusing)
                   1185: //
                   1186:        for (i=0 ; i<mod->numsubmodels ; i++)
                   1187:        {
                   1188:                bm = &mod->submodels[i];
                   1189: 
                   1190:                mod->hulls[0].firstclipnode = bm->headnode[0];
                   1191:                for (j=1 ; j<MAX_MAP_HULLS ; j++)
                   1192:                {
                   1193:                        mod->hulls[j].firstclipnode = bm->headnode[j];
                   1194:                        mod->hulls[j].lastclipnode = mod->numclipnodes-1;
                   1195:                }
                   1196:                
                   1197:                mod->firstmodelsurface = bm->firstface;
                   1198:                mod->nummodelsurfaces = bm->numfaces;
                   1199:                mod->radius = RadiusFromBounds (mod->mins, mod->maxs);
                   1200:                
                   1201:                VectorCopy (bm->maxs, mod->maxs);
                   1202:                VectorCopy (bm->mins, mod->mins);
                   1203:        
                   1204:                mod->numleafs = bm->visleafs;
                   1205: 
                   1206:                if (i < mod->numsubmodels-1)
                   1207:                {       // duplicate the basic information
                   1208:                        char    name[10];
                   1209: 
                   1210:                        sprintf (name, "*%i", i+1);
                   1211:                        loadmodel = Mod_FindName (name);
                   1212:                        *loadmodel = *mod;
                   1213:                        strcpy (loadmodel->name, name);
                   1214:                        mod = loadmodel;
                   1215:                }
                   1216:        }
                   1217: }
                   1218: 
                   1219: /*
                   1220: ==============================================================================
                   1221: 
                   1222: ALIAS MODELS
                   1223: 
                   1224: ==============================================================================
                   1225: */
                   1226: 
                   1227: /*
                   1228: =================
                   1229: Mod_LoadAliasFrame
                   1230: =================
                   1231: */
                   1232: void * Mod_LoadAliasFrame (void * pin, int *pframeindex, int numv,
                   1233:        trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name)
                   1234: {
                   1235:        trivertx_t              *pframe, *pinframe;
                   1236:        int                             i, j;
                   1237:        daliasframe_t   *pdaliasframe;
                   1238: 
                   1239:        pdaliasframe = (daliasframe_t *)pin;
                   1240: 
                   1241:        strcpy (name, pdaliasframe->name);
                   1242: 
                   1243:        for (i=0 ; i<3 ; i++)
                   1244:        {
                   1245:        // these are byte values, so we don't have to worry about
                   1246:        // endianness
                   1247:                pbboxmin->v[i] = pdaliasframe->bboxmin.v[i];
                   1248:                pbboxmax->v[i] = pdaliasframe->bboxmax.v[i];
                   1249:        }
                   1250: 
                   1251:        pinframe = (trivertx_t *)(pdaliasframe + 1);
                   1252:        pframe = Hunk_AllocName (numv * sizeof(*pframe), loadname);
                   1253: 
                   1254:        *pframeindex = (byte *)pframe - (byte *)pheader;
                   1255: 
                   1256:        for (j=0 ; j<numv ; j++)
                   1257:        {
                   1258:                int             k;
                   1259: 
                   1260:        // these are all byte values, so no need to deal with endianness
                   1261:                pframe[j].lightnormalindex = pinframe[j].lightnormalindex;
                   1262: 
                   1263:                for (k=0 ; k<3 ; k++)
                   1264:                {
                   1265:                        pframe[j].v[k] = pinframe[j].v[k];
                   1266:                }
                   1267:        }
                   1268: 
                   1269:        pinframe += numv;
                   1270: 
                   1271:        return (void *)pinframe;
                   1272: }
                   1273: 
                   1274: 
                   1275: /*
                   1276: =================
                   1277: Mod_LoadAliasGroup
                   1278: =================
                   1279: */
                   1280: void * Mod_LoadAliasGroup (void * pin, int *pframeindex, int numv,
                   1281:        trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name)
                   1282: {
                   1283:        daliasgroup_t           *pingroup;
                   1284:        maliasgroup_t           *paliasgroup;
                   1285:        int                                     i, numframes;
                   1286:        daliasinterval_t        *pin_intervals;
                   1287:        float                           *poutintervals;
                   1288:        void                            *ptemp;
                   1289:        
                   1290:        pingroup = (daliasgroup_t *)pin;
                   1291: 
                   1292:        numframes = LittleLong (pingroup->numframes);
                   1293: 
                   1294:        paliasgroup = Hunk_AllocName (sizeof (maliasgroup_t) +
                   1295:                        (numframes - 1) * sizeof (paliasgroup->frames[0]), loadname);
                   1296: 
                   1297:        paliasgroup->numframes = numframes;
                   1298: 
                   1299:        for (i=0 ; i<3 ; i++)
                   1300:        {
                   1301:        // these are byte values, so we don't have to worry about endianness
                   1302:                pbboxmin->v[i] = pingroup->bboxmin.v[i];
                   1303:                pbboxmax->v[i] = pingroup->bboxmax.v[i];
                   1304:        }
                   1305: 
                   1306:        *pframeindex = (byte *)paliasgroup - (byte *)pheader;
                   1307: 
                   1308:        pin_intervals = (daliasinterval_t *)(pingroup + 1);
                   1309: 
                   1310:        poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname);
                   1311: 
                   1312:        paliasgroup->intervals = (byte *)poutintervals - (byte *)pheader;
                   1313: 
                   1314:        for (i=0 ; i<numframes ; i++)
                   1315:        {
                   1316:                *poutintervals = LittleFloat (pin_intervals->interval);
                   1317:                if (*poutintervals <= 0.0)
                   1318:                        Sys_Error ("Mod_LoadAliasGroup: interval<=0");
                   1319: 
                   1320:                poutintervals++;
                   1321:                pin_intervals++;
                   1322:        }
                   1323: 
                   1324:        ptemp = (void *)pin_intervals;
                   1325: 
                   1326:        for (i=0 ; i<numframes ; i++)
                   1327:        {
                   1328:                ptemp = Mod_LoadAliasFrame (ptemp,
                   1329:                                                                        &paliasgroup->frames[i].frame,
                   1330:                                                                        numv,
                   1331:                                                                        &paliasgroup->frames[i].bboxmin,
                   1332:                                                                        &paliasgroup->frames[i].bboxmax,
                   1333:                                                                        pheader, name);
                   1334:        }
                   1335: 
                   1336:        return ptemp;
                   1337: }
                   1338: 
                   1339: 
                   1340: /*
                   1341: =================
                   1342: Mod_LoadAliasSkin
                   1343: =================
                   1344: */
                   1345: void * Mod_LoadAliasSkin (void * pin, int *pskinindex, int skinsize,
                   1346:        aliashdr_t *pheader)
                   1347: {
                   1348:        int             i;
                   1349:        byte    *pskin, *pinskin;
                   1350:        unsigned short  *pusskin;
                   1351: 
                   1352:        pskin = Hunk_AllocName (skinsize * r_pixbytes, loadname);
                   1353:        pinskin = (byte *)pin;
                   1354:        *pskinindex = (byte *)pskin - (byte *)pheader;
                   1355: 
                   1356:        if (r_pixbytes == 1)
                   1357:        {
                   1358:                Q_memcpy (pskin, pinskin, skinsize);
                   1359:        }
                   1360:        else if (r_pixbytes == 2)
                   1361:        {
                   1362:                pusskin = (unsigned short *)pskin;
                   1363: 
                   1364:                for (i=0 ; i<skinsize ; i++)
                   1365:                        pusskin[i] = d_8to16table[pinskin[i]];
                   1366:        }
                   1367:        else
                   1368:        {
                   1369:                Sys_Error ("Mod_LoadAliasSkin: driver set invalid r_pixbytes: %d\n",
                   1370:                                 r_pixbytes);
                   1371:        }
                   1372: 
                   1373:        pinskin += skinsize;
                   1374: 
                   1375:        return ((void *)pinskin);
                   1376: }
                   1377: 
                   1378: 
                   1379: /*
                   1380: =================
                   1381: Mod_LoadAliasSkinGroup
                   1382: =================
                   1383: */
                   1384: void * Mod_LoadAliasSkinGroup (void * pin, int *pskinindex, int skinsize,
                   1385:        aliashdr_t *pheader)
                   1386: {
                   1387:        daliasskingroup_t               *pinskingroup;
                   1388:        maliasskingroup_t               *paliasskingroup;
                   1389:        int                                             i, numskins;
                   1390:        daliasskininterval_t    *pinskinintervals;
                   1391:        float                                   *poutskinintervals;
                   1392:        void                                    *ptemp;
                   1393: 
                   1394:        pinskingroup = (daliasskingroup_t *)pin;
                   1395: 
                   1396:        numskins = LittleLong (pinskingroup->numskins);
                   1397: 
                   1398:        paliasskingroup = Hunk_AllocName (sizeof (maliasskingroup_t) +
                   1399:                        (numskins - 1) * sizeof (paliasskingroup->skindescs[0]),
                   1400:                        loadname);
                   1401: 
                   1402:        paliasskingroup->numskins = numskins;
                   1403: 
                   1404:        *pskinindex = (byte *)paliasskingroup - (byte *)pheader;
                   1405: 
                   1406:        pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1);
                   1407: 
                   1408:        poutskinintervals = Hunk_AllocName (numskins * sizeof (float),loadname);
                   1409: 
                   1410:        paliasskingroup->intervals = (byte *)poutskinintervals - (byte *)pheader;
                   1411: 
                   1412:        for (i=0 ; i<numskins ; i++)
                   1413:        {
                   1414:                *poutskinintervals = LittleFloat (pinskinintervals->interval);
                   1415:                if (*poutskinintervals <= 0)
                   1416:                        Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0");
                   1417: 
                   1418:                poutskinintervals++;
                   1419:                pinskinintervals++;
                   1420:        }
                   1421: 
                   1422:        ptemp = (void *)pinskinintervals;
                   1423: 
                   1424:        for (i=0 ; i<numskins ; i++)
                   1425:        {
                   1426:                ptemp = Mod_LoadAliasSkin (ptemp,
                   1427:                                &paliasskingroup->skindescs[i].skin, skinsize, pheader);
                   1428:        }
                   1429: 
                   1430:        return ptemp;
                   1431: }
                   1432: 
                   1433: 
                   1434: /*
                   1435: =================
                   1436: Mod_LoadAliasModel
                   1437: =================
                   1438: */
                   1439: void Mod_LoadAliasModel (model_t *mod, void *buffer)
                   1440: {
                   1441:        int                                     i;
                   1442:        mdl_t                           *pmodel, *pinmodel;
                   1443:        stvert_t                        *pstverts, *pinstverts;
                   1444:        aliashdr_t                      *pheader;
                   1445:        mtriangle_t                     *ptri;
                   1446:        dtriangle_t                     *pintriangles;
                   1447:        int                                     version, numframes, numskins;
                   1448:        int                                     size;
                   1449:        daliasframetype_t       *pframetype;
                   1450:        daliasskintype_t        *pskintype;
                   1451:        maliasskindesc_t        *pskindesc;
                   1452:        int                                     skinsize;
                   1453:        int                                     start, end, total;
                   1454:        
                   1455:        if (!strcmp(loadmodel->name, "progs/player.mdl") ||
                   1456:                !strcmp(loadmodel->name, "progs/eyes.mdl")) {
                   1457:                unsigned short crc;
                   1458:                byte *p;
                   1459:                int len;
                   1460:                char st[40];
                   1461: 
                   1462:                CRC_Init(&crc);
                   1463:                for (len = com_filesize, p = buffer; len; len--, p++)
                   1464:                        CRC_ProcessByte(&crc, *p);
                   1465:        
                   1466:                sprintf(st, "%d", (int) crc);
                   1467:                Info_SetValueForKey (cls.userinfo, 
                   1468:                        !strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
                   1469:                        st, MAX_INFO_STRING);
                   1470: 
                   1471:                if (cls.state >= ca_connected) {
                   1472:                        MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
                   1473:                        sprintf(st, "setinfo %s %d", 
                   1474:                                !strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
                   1475:                                (int)crc);
                   1476:                        SZ_Print (&cls.netchan.message, st);
                   1477:                }
                   1478:        }
                   1479: 
                   1480:        start = Hunk_LowMark ();
                   1481: 
                   1482:        pinmodel = (mdl_t *)buffer;
                   1483: 
                   1484:        version = LittleLong (pinmodel->version);
                   1485:        if (version != ALIAS_VERSION)
                   1486:                Sys_Error ("%s has wrong version number (%i should be %i)",
                   1487:                                 mod->name, version, ALIAS_VERSION);
                   1488: 
                   1489: //
                   1490: // allocate space for a working header, plus all the data except the frames,
                   1491: // skin and group info
                   1492: //
                   1493:        size =  sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) *
                   1494:                         sizeof (pheader->frames[0]) +
                   1495:                        sizeof (mdl_t) +
                   1496:                        LittleLong (pinmodel->numverts) * sizeof (stvert_t) +
                   1497:                        LittleLong (pinmodel->numtris) * sizeof (mtriangle_t);
                   1498: 
                   1499:        pheader = Hunk_AllocName (size, loadname);
                   1500:        pmodel = (mdl_t *) ((byte *)&pheader[1] +
                   1501:                        (LittleLong (pinmodel->numframes) - 1) *
                   1502:                         sizeof (pheader->frames[0]));
                   1503:        
                   1504: //     mod->cache.data = pheader;
                   1505:        mod->flags = LittleLong (pinmodel->flags);
                   1506: 
                   1507: //
                   1508: // endian-adjust and copy the data, starting with the alias model header
                   1509: //
                   1510:        pmodel->boundingradius = LittleFloat (pinmodel->boundingradius);
                   1511:        pmodel->numskins = LittleLong (pinmodel->numskins);
                   1512:        pmodel->skinwidth = LittleLong (pinmodel->skinwidth);
                   1513:        pmodel->skinheight = LittleLong (pinmodel->skinheight);
                   1514: 
                   1515:        if (pmodel->skinheight > MAX_LBM_HEIGHT)
                   1516:                Sys_Error ("model %s has a skin taller than %d", mod->name,
                   1517:                                   MAX_LBM_HEIGHT);
                   1518: 
                   1519:        pmodel->numverts = LittleLong (pinmodel->numverts);
                   1520: 
                   1521:        if (pmodel->numverts <= 0)
                   1522:                Sys_Error ("model %s has no vertices", mod->name);
                   1523: 
                   1524:        if (pmodel->numverts > MAXALIASVERTS)
                   1525:                Sys_Error ("model %s has too many vertices", mod->name);
                   1526: 
                   1527:        pmodel->numtris = LittleLong (pinmodel->numtris);
                   1528: 
                   1529:        if (pmodel->numtris <= 0)
                   1530:                Sys_Error ("model %s has no triangles", mod->name);
                   1531: 
                   1532:        pmodel->numframes = LittleLong (pinmodel->numframes);
                   1533:        pmodel->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
                   1534:        mod->synctype = LittleLong (pinmodel->synctype);
                   1535:        mod->numframes = pmodel->numframes;
                   1536: 
                   1537:        for (i=0 ; i<3 ; i++)
                   1538:        {
                   1539:                pmodel->scale[i] = LittleFloat (pinmodel->scale[i]);
                   1540:                pmodel->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]);
                   1541:                pmodel->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]);
                   1542:        }
                   1543: 
                   1544:        numskins = pmodel->numskins;
                   1545:        numframes = pmodel->numframes;
                   1546: 
                   1547:        if (pmodel->skinwidth & 0x03)
                   1548:                Sys_Error ("Mod_LoadAliasModel: skinwidth not multiple of 4");
                   1549: 
                   1550:        pheader->model = (byte *)pmodel - (byte *)pheader;
                   1551: 
                   1552: //
                   1553: // load the skins
                   1554: //
                   1555:        skinsize = pmodel->skinheight * pmodel->skinwidth;
                   1556: 
                   1557:        if (numskins < 1)
                   1558:                Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins);
                   1559: 
                   1560:        pskintype = (daliasskintype_t *)&pinmodel[1];
                   1561: 
                   1562:        pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t),
                   1563:                                                                loadname);
                   1564: 
                   1565:        pheader->skindesc = (byte *)pskindesc - (byte *)pheader;
                   1566: 
                   1567:        for (i=0 ; i<numskins ; i++)
                   1568:        {
                   1569:                aliasskintype_t skintype;
                   1570: 
                   1571:                skintype = LittleLong (pskintype->type);
                   1572:                pskindesc[i].type = skintype;
                   1573: 
                   1574:                if (skintype == ALIAS_SKIN_SINGLE)
                   1575:                {
                   1576:                        pskintype = (daliasskintype_t *)
                   1577:                                        Mod_LoadAliasSkin (pskintype + 1,
                   1578:                                                                           &pskindesc[i].skin,
                   1579:                                                                           skinsize, pheader);
                   1580:                }
                   1581:                else
                   1582:                {
                   1583:                        pskintype = (daliasskintype_t *)
                   1584:                                        Mod_LoadAliasSkinGroup (pskintype + 1,
                   1585:                                                                                        &pskindesc[i].skin,
                   1586:                                                                                        skinsize, pheader);
                   1587:                }
                   1588:        }
                   1589: 
                   1590: //
                   1591: // set base s and t vertices
                   1592: //
                   1593:        pstverts = (stvert_t *)&pmodel[1];
                   1594:        pinstverts = (stvert_t *)pskintype;
                   1595: 
                   1596:        pheader->stverts = (byte *)pstverts - (byte *)pheader;
                   1597: 
                   1598:        for (i=0 ; i<pmodel->numverts ; i++)
                   1599:        {
                   1600:                pstverts[i].onseam = LittleLong (pinstverts[i].onseam);
                   1601:        // put s and t in 16.16 format
                   1602:                pstverts[i].s = LittleLong (pinstverts[i].s) << 16;
                   1603:                pstverts[i].t = LittleLong (pinstverts[i].t) << 16;
                   1604:        }
                   1605: 
                   1606: //
                   1607: // set up the triangles
                   1608: //
                   1609:        ptri = (mtriangle_t *)&pstverts[pmodel->numverts];
                   1610:        pintriangles = (dtriangle_t *)&pinstverts[pmodel->numverts];
                   1611: 
                   1612:        pheader->triangles = (byte *)ptri - (byte *)pheader;
                   1613: 
                   1614:        for (i=0 ; i<pmodel->numtris ; i++)
                   1615:        {
                   1616:                int             j;
                   1617: 
                   1618:                ptri[i].facesfront = LittleLong (pintriangles[i].facesfront);
                   1619: 
                   1620:                for (j=0 ; j<3 ; j++)
                   1621:                {
                   1622:                        ptri[i].vertindex[j] =
                   1623:                                        LittleLong (pintriangles[i].vertindex[j]);
                   1624:                }
                   1625:        }
                   1626: 
                   1627: //
                   1628: // load the frames
                   1629: //
                   1630:        if (numframes < 1)
                   1631:                Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes);
                   1632: 
                   1633:        pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris];
                   1634: 
                   1635:        for (i=0 ; i<numframes ; i++)
                   1636:        {
                   1637:                aliasframetype_t        frametype;
                   1638: 
                   1639:                frametype = LittleLong (pframetype->type);
                   1640:                pheader->frames[i].type = frametype;
                   1641: 
                   1642: 
                   1643:                if (frametype == ALIAS_SINGLE)
                   1644:                {
                   1645:                        pframetype = (daliasframetype_t *)
                   1646:                                        Mod_LoadAliasFrame (pframetype + 1,
                   1647:                                                                                &pheader->frames[i].frame,
                   1648:                                                                                pmodel->numverts,
                   1649:                                                                                &pheader->frames[i].bboxmin,
                   1650:                                                                                &pheader->frames[i].bboxmax,
                   1651:                                                                                pheader, pheader->frames[i].name);
                   1652:                }
                   1653:                else
                   1654:                {
                   1655:                        pframetype = (daliasframetype_t *)
                   1656:                                        Mod_LoadAliasGroup (pframetype + 1,
                   1657:                                                                                &pheader->frames[i].frame,
                   1658:                                                                                pmodel->numverts,
                   1659:                                                                                &pheader->frames[i].bboxmin,
                   1660:                                                                                &pheader->frames[i].bboxmax,
                   1661:                                                                                pheader, pheader->frames[i].name);
                   1662:                }
                   1663:        }
                   1664: 
                   1665:        mod->type = mod_alias;
                   1666: 
                   1667: // FIXME: do this right
                   1668:        mod->mins[0] = mod->mins[1] = mod->mins[2] = -16;
                   1669:        mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16;
                   1670: 
                   1671: //
                   1672: // move the complete, relocatable alias model to the cache
                   1673: //     
                   1674:        end = Hunk_LowMark ();
                   1675:        total = end - start;
                   1676:        
                   1677:        Cache_Alloc (&mod->cache, total, loadname);
                   1678:        if (!mod->cache.data)
                   1679:                return;
                   1680:        memcpy (mod->cache.data, pheader, total);
                   1681: 
                   1682:        Hunk_FreeToLowMark (start);
                   1683: }
                   1684: 
                   1685: //=============================================================================
                   1686: 
                   1687: /*
                   1688: =================
                   1689: Mod_LoadSpriteFrame
                   1690: =================
                   1691: */
                   1692: void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe)
                   1693: {
                   1694:        dspriteframe_t          *pinframe;
                   1695:        mspriteframe_t          *pspriteframe;
                   1696:        int                                     i, width, height, size, origin[2];
                   1697:        unsigned short          *ppixout;
                   1698:        byte                            *ppixin;
                   1699: 
                   1700:        pinframe = (dspriteframe_t *)pin;
                   1701: 
                   1702:        width = LittleLong (pinframe->width);
                   1703:        height = LittleLong (pinframe->height);
                   1704:        size = width * height;
                   1705: 
                   1706:        pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t) + size*r_pixbytes,
                   1707:                                                                   loadname);
                   1708: 
                   1709:        Q_memset (pspriteframe, 0, sizeof (mspriteframe_t) + size);
                   1710:        *ppframe = pspriteframe;
                   1711: 
                   1712:        pspriteframe->width = width;
                   1713:        pspriteframe->height = height;
                   1714:        origin[0] = LittleLong (pinframe->origin[0]);
                   1715:        origin[1] = LittleLong (pinframe->origin[1]);
                   1716: 
                   1717:        pspriteframe->up = origin[1];
                   1718:        pspriteframe->down = origin[1] - height;
                   1719:        pspriteframe->left = origin[0];
                   1720:        pspriteframe->right = width + origin[0];
                   1721: 
                   1722:        if (r_pixbytes == 1)
                   1723:        {
                   1724:                Q_memcpy (&pspriteframe->pixels[0], (byte *)(pinframe + 1), size);
                   1725:        }
                   1726:        else if (r_pixbytes == 2)
                   1727:        {
                   1728:                ppixin = (byte *)(pinframe + 1);
                   1729:                ppixout = (unsigned short *)&pspriteframe->pixels[0];
                   1730: 
                   1731:                for (i=0 ; i<size ; i++)
                   1732:                        ppixout[i] = d_8to16table[ppixin[i]];
                   1733:        }
                   1734:        else
                   1735:        {
                   1736:                Sys_Error ("Mod_LoadSpriteFrame: driver set invalid r_pixbytes: %d\n",
                   1737:                                 r_pixbytes);
                   1738:        }
                   1739: 
                   1740:        return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size);
                   1741: }
                   1742: 
                   1743: 
                   1744: /*
                   1745: =================
                   1746: Mod_LoadSpriteGroup
                   1747: =================
                   1748: */
                   1749: void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe)
                   1750: {
                   1751:        dspritegroup_t          *pingroup;
                   1752:        mspritegroup_t          *pspritegroup;
                   1753:        int                                     i, numframes;
                   1754:        dspriteinterval_t       *pin_intervals;
                   1755:        float                           *poutintervals;
                   1756:        void                            *ptemp;
                   1757: 
                   1758:        pingroup = (dspritegroup_t *)pin;
                   1759: 
                   1760:        numframes = LittleLong (pingroup->numframes);
                   1761: 
                   1762:        pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) +
                   1763:                                (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname);
                   1764: 
                   1765:        pspritegroup->numframes = numframes;
                   1766: 
                   1767:        *ppframe = (mspriteframe_t *)pspritegroup;
                   1768: 
                   1769:        pin_intervals = (dspriteinterval_t *)(pingroup + 1);
                   1770: 
                   1771:        poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname);
                   1772: 
                   1773:        pspritegroup->intervals = poutintervals;
                   1774: 
                   1775:        for (i=0 ; i<numframes ; i++)
                   1776:        {
                   1777:                *poutintervals = LittleFloat (pin_intervals->interval);
                   1778:                if (*poutintervals <= 0.0)
                   1779:                        Sys_Error ("Mod_LoadSpriteGroup: interval<=0");
                   1780: 
                   1781:                poutintervals++;
                   1782:                pin_intervals++;
                   1783:        }
                   1784: 
                   1785:        ptemp = (void *)pin_intervals;
                   1786: 
                   1787:        for (i=0 ; i<numframes ; i++)
                   1788:        {
                   1789:                ptemp = Mod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i]);
                   1790:        }
                   1791: 
                   1792:        return ptemp;
                   1793: }
                   1794: 
                   1795: 
                   1796: /*
                   1797: =================
                   1798: Mod_LoadSpriteModel
                   1799: =================
                   1800: */
                   1801: void Mod_LoadSpriteModel (model_t *mod, void *buffer)
                   1802: {
                   1803:        int                                     i;
                   1804:        int                                     version;
                   1805:        dsprite_t                       *pin;
                   1806:        msprite_t                       *psprite;
                   1807:        int                                     numframes;
                   1808:        int                                     size;
                   1809:        dspriteframetype_t      *pframetype;
                   1810:        
                   1811:        pin = (dsprite_t *)buffer;
                   1812: 
                   1813:        version = LittleLong (pin->version);
                   1814:        if (version != SPRITE_VERSION)
                   1815:                Sys_Error ("%s has wrong version number "
                   1816:                                 "(%i should be %i)", mod->name, version, SPRITE_VERSION);
                   1817: 
                   1818:        numframes = LittleLong (pin->numframes);
                   1819: 
                   1820:        size = sizeof (msprite_t) +     (numframes - 1) * sizeof (psprite->frames);
                   1821: 
                   1822:        psprite = Hunk_AllocName (size, loadname);
                   1823: 
                   1824:        mod->cache.data = psprite;
                   1825: 
                   1826:        psprite->type = LittleLong (pin->type);
                   1827:        psprite->maxwidth = LittleLong (pin->width);
                   1828:        psprite->maxheight = LittleLong (pin->height);
                   1829:        psprite->beamlength = LittleFloat (pin->beamlength);
                   1830:        mod->synctype = LittleLong (pin->synctype);
                   1831:        psprite->numframes = numframes;
                   1832: 
                   1833:        mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2;
                   1834:        mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2;
                   1835:        mod->mins[2] = -psprite->maxheight/2;
                   1836:        mod->maxs[2] = psprite->maxheight/2;
                   1837:        
                   1838: //
                   1839: // load the frames
                   1840: //
                   1841:        if (numframes < 1)
                   1842:                Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes);
                   1843: 
                   1844:        mod->numframes = numframes;
                   1845: 
                   1846:        pframetype = (dspriteframetype_t *)(pin + 1);
                   1847: 
                   1848:        for (i=0 ; i<numframes ; i++)
                   1849:        {
                   1850:                spriteframetype_t       frametype;
                   1851: 
                   1852:                frametype = LittleLong (pframetype->type);
                   1853:                psprite->frames[i].type = frametype;
                   1854: 
                   1855:                if (frametype == SPR_SINGLE)
                   1856:                {
                   1857:                        pframetype = (dspriteframetype_t *)
                   1858:                                        Mod_LoadSpriteFrame (pframetype + 1,
                   1859:                                                                                 &psprite->frames[i].frameptr);
                   1860:                }
                   1861:                else
                   1862:                {
                   1863:                        pframetype = (dspriteframetype_t *)
                   1864:                                        Mod_LoadSpriteGroup (pframetype + 1,
                   1865:                                                                                 &psprite->frames[i].frameptr);
                   1866:                }
                   1867:        }
                   1868: 
                   1869:        mod->type = mod_sprite;
                   1870: }
                   1871: 
                   1872: //=============================================================================
                   1873: 
                   1874: /*
                   1875: ================
                   1876: Mod_Print
                   1877: ================
                   1878: */
                   1879: void Mod_Print (void)
                   1880: {
                   1881:        int             i;
                   1882:        model_t *mod;
                   1883: 
                   1884:        Con_Printf ("Cached models:\n");
                   1885:        for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
                   1886:        {
                   1887:                Con_Printf ("%8p : %s\n",mod->cache.data, mod->name);
                   1888:        }
                   1889: }
                   1890: 
                   1891: 

unix.superglobalmegacorp.com

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