Annotation of quake2/ref_soft/r_model.c, revision 1.1.1.2

1.1       root        1: // models.c -- model loading and caching
                      2: 
                      3: // models are the only shared resource between a client and server running
                      4: // on the same machine.
                      5: 
                      6: #include "r_local.h"
                      7: 
                      8: model_t        *loadmodel;
                      9: char   loadname[32];   // for hunk tags
                     10: 
                     11: void Mod_LoadSpriteModel (model_t *mod, void *buffer);
                     12: void Mod_LoadBrushModel (model_t *mod, void *buffer);
                     13: void Mod_LoadAliasModel (model_t *mod, void *buffer);
                     14: model_t *Mod_LoadModel (model_t *mod, qboolean crash);
                     15: 
                     16: byte   mod_novis[MAX_MAP_LEAFS/8];
                     17: 
                     18: #define        MAX_MOD_KNOWN   256
                     19: model_t        mod_known[MAX_MOD_KNOWN];
                     20: int            mod_numknown;
                     21: 
                     22: // the inline * models from the current map are kept seperate
                     23: model_t        mod_inline[MAX_MOD_KNOWN];
                     24: 
                     25: int            registration_sequence;
                     26: int            modfilelen;
                     27: 
                     28: //===============================================================================
                     29: 
                     30: 
                     31: /*
                     32: ================
                     33: Mod_Modellist_f
                     34: ================
                     35: */
                     36: void Mod_Modellist_f (void)
                     37: {
                     38:        int             i;
                     39:        model_t *mod;
                     40:        int             total;
                     41: 
                     42:        total = 0;
                     43:        ri.Con_Printf (PRINT_ALL,"Loaded models:\n");
                     44:        for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
                     45:        {
                     46:                if (!mod->name[0])
                     47:                        continue;
                     48:                ri.Con_Printf (PRINT_ALL, "%8i : %s\n",mod->extradatasize, mod->name);
                     49:                total += mod->extradatasize;
                     50:        }
                     51:        ri.Con_Printf (PRINT_ALL, "Total resident: %i\n", total);
                     52: }
                     53: 
                     54: /*
                     55: ===============
                     56: Mod_Init
                     57: ===============
                     58: */
                     59: void Mod_Init (void)
                     60: {
                     61:        memset (mod_novis, 0xff, sizeof(mod_novis));
                     62: }
                     63: 
                     64: /*
                     65: ==================
                     66: Mod_ForName
                     67: 
                     68: Loads in a model for the given name
                     69: ==================
                     70: */
                     71: model_t *Mod_ForName (char *name, qboolean crash)
                     72: {
                     73:        model_t *mod;
                     74:        unsigned *buf;
                     75:        int             i;
                     76:        
                     77:        if (!name[0])
                     78:                ri.Sys_Error (ERR_DROP,"Mod_ForName: NULL name");
                     79: 
                     80:        //
                     81:        // inline models are grabbed only from worldmodel
                     82:        //
                     83:        if (name[0] == '*')
                     84:        {
                     85:                i = atoi(name+1);
                     86:                if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels)
                     87:                        ri.Sys_Error (ERR_DROP, "bad inline model number");
                     88:                return &mod_inline[i];
                     89:        }
                     90: 
                     91:        //
                     92:        // search the currently loaded models
                     93:        //
                     94:        for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
                     95:                if (!strcmp (mod->name, name) )
                     96:                        return mod;
                     97:                        
                     98:        //
                     99:        // find a free model slot spot
                    100:        //
                    101:        for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
                    102:        {
                    103:                if (!mod->name[0])
                    104:                        break;  // free spot
                    105:        }
                    106:        if (i == mod_numknown)
                    107:        {
                    108:                if (mod_numknown == MAX_MOD_KNOWN)
                    109:                        ri.Sys_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");
                    110:                mod_numknown++;
                    111:        }
                    112:        strcpy (mod->name, name);
                    113:        
                    114:        //
                    115:        // load the file
                    116:        //
                    117:        modfilelen = ri.FS_LoadFile (mod->name, (void **)&buf);
                    118:        if (!buf)
                    119:        {
                    120:                if (crash)
                    121:                        ri.Sys_Error (ERR_DROP,"Mod_NumForName: %s not found", mod->name);
                    122:                memset (mod->name, 0, sizeof(mod->name));
                    123:                return NULL;
                    124:        }
                    125:        
                    126:        loadmodel = mod;
                    127: 
                    128:        //
                    129:        // fill it in
                    130:        //
                    131: 
                    132:        // call the apropriate loader
                    133:        
                    134:        switch (LittleLong(*(unsigned *)buf))
                    135:        {
                    136:        case IDALIASHEADER:
                    137:                loadmodel->extradata = Hunk_Begin (0x200000);
                    138:                Mod_LoadAliasModel (mod, buf);
                    139:                break;
                    140:                
                    141:        case IDSPRITEHEADER:
                    142:                loadmodel->extradata = Hunk_Begin (0x10000);
                    143:                Mod_LoadSpriteModel (mod, buf);
                    144:                break;
                    145:        
                    146:        case IDBSPHEADER:
                    147:                loadmodel->extradata = Hunk_Begin (0x1000000);
                    148:                Mod_LoadBrushModel (mod, buf);
                    149:                break;
                    150: 
                    151:        default:
                    152:                ri.Sys_Error (ERR_DROP,"Mod_NumForName: unknown fileid for %s", mod->name);
                    153:                break;
                    154:        }
                    155: 
                    156:        loadmodel->extradatasize = Hunk_End ();
                    157: 
                    158:        ri.FS_FreeFile (buf);
                    159: 
                    160:        return mod;
                    161: }
                    162: 
                    163: 
                    164: /*
                    165: ===============
                    166: Mod_PointInLeaf
                    167: ===============
                    168: */
                    169: mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
                    170: {
                    171:        mnode_t         *node;
                    172:        float           d;
                    173:        mplane_t        *plane;
                    174:        
                    175:        if (!model || !model->nodes)
                    176:                ri.Sys_Error (ERR_DROP, "Mod_PointInLeaf: bad model");
                    177: 
                    178:        node = model->nodes;
                    179:        while (1)
                    180:        {
                    181:                if (node->contents != -1)
                    182:                        return (mleaf_t *)node;
                    183:                plane = node->plane;
                    184:                d = DotProduct (p,plane->normal) - plane->dist;
                    185:                if (d > 0)
                    186:                        node = node->children[0];
                    187:                else
                    188:                        node = node->children[1];
                    189:        }
                    190:        
                    191:        return NULL;    // never reached
                    192: }
                    193: 
                    194: 
                    195: /*
                    196: ===================
                    197: Mod_DecompressVis
                    198: ===================
                    199: */
                    200: byte *Mod_DecompressVis (byte *in, model_t *model)
                    201: {
                    202:        static byte     decompressed[MAX_MAP_LEAFS/8];
                    203:        int             c;
                    204:        byte    *out;
                    205:        int             row;
                    206: 
                    207:        row = (model->vis->numclusters+7)>>3;   
                    208:        out = decompressed;
                    209: 
                    210: #if 0
                    211:        memcpy (out, in, row);
                    212: #else
                    213:        if (!in)
                    214:        {       // no vis info, so make all visible
                    215:                while (row)
                    216:                {
                    217:                        *out++ = 0xff;
                    218:                        row--;
                    219:                }
                    220:                return decompressed;            
                    221:        }
                    222: 
                    223:        do
                    224:        {
                    225:                if (*in)
                    226:                {
                    227:                        *out++ = *in++;
                    228:                        continue;
                    229:                }
                    230:        
                    231:                c = in[1];
                    232:                in += 2;
                    233:                while (c)
                    234:                {
                    235:                        *out++ = 0;
                    236:                        c--;
                    237:                }
                    238:        } while (out - decompressed < row);
                    239: #endif
                    240:        
                    241:        return decompressed;
                    242: }
                    243: 
                    244: /*
                    245: ==============
                    246: Mod_ClusterPVS
                    247: ==============
                    248: */
                    249: byte *Mod_ClusterPVS (int cluster, model_t *model)
                    250: {
                    251:        if (cluster == -1 || !model->vis)
                    252:                return mod_novis;
                    253:        return Mod_DecompressVis ( (byte *)model->vis + model->vis->bitofs[cluster][DVIS_PVS],
                    254:                model);
                    255: }
                    256: 
                    257: /*
                    258: ===============================================================================
                    259: 
                    260:                                        BRUSHMODEL LOADING
                    261: 
                    262: ===============================================================================
                    263: */
                    264: 
                    265: byte   *mod_base;
                    266: 
                    267: 
                    268: /*
                    269: =================
                    270: Mod_LoadLighting
                    271: 
                    272: Converts the 24 bit lighting down to 8 bit
                    273: by taking the brightest component
                    274: =================
                    275: */
                    276: void Mod_LoadLighting (lump_t *l)
                    277: {
                    278:        int             i, size;
                    279:        byte    *in;
                    280: 
                    281:        if (!l->filelen)
                    282:        {
                    283:                loadmodel->lightdata = NULL;
                    284:                return;
                    285:        }
                    286:        size = l->filelen/3;
                    287:        loadmodel->lightdata = Hunk_Alloc (size);
                    288:        in = (void *)(mod_base + l->fileofs);
                    289:        for (i=0 ; i<size ; i++, in+=3)
                    290:        {
                    291:                if (in[0] > in[1] && in[0] > in[2])
                    292:                        loadmodel->lightdata[i] = in[0];
                    293:                else if (in[1] > in[0] && in[1] > in[2])
                    294:                        loadmodel->lightdata[i] = in[1];
                    295:                else
                    296:                        loadmodel->lightdata[i] = in[2];
                    297:        }
                    298: }
                    299: 
                    300: 
                    301: int            r_leaftovis[MAX_MAP_LEAFS];
                    302: int            r_vistoleaf[MAX_MAP_LEAFS];
                    303: int            r_numvisleafs;
                    304: 
                    305: void   R_NumberLeafs (mnode_t *node)
                    306: {
                    307:        mleaf_t *leaf;
                    308:        int             leafnum;
                    309: 
                    310:        if (node->contents != -1)
                    311:        {
                    312:                leaf = (mleaf_t *)node;
                    313:                leafnum = leaf - loadmodel->leafs;
                    314:                if (leaf->contents & CONTENTS_SOLID)
                    315:                        return;
                    316:                r_leaftovis[leafnum] = r_numvisleafs;
                    317:                r_vistoleaf[r_numvisleafs] = leafnum;
                    318:                r_numvisleafs++;
                    319:                return;
                    320:        }
                    321: 
                    322:        R_NumberLeafs (node->children[0]);
                    323:        R_NumberLeafs (node->children[1]);
                    324: }
                    325: 
                    326: 
                    327: /*
                    328: =================
                    329: Mod_LoadVisibility
                    330: =================
                    331: */
                    332: void Mod_LoadVisibility (lump_t *l)
                    333: {
                    334:        int             i;
                    335: 
                    336:        if (!l->filelen)
                    337:        {
                    338:                loadmodel->vis = NULL;
                    339:                return;
                    340:        }
                    341:        loadmodel->vis = Hunk_Alloc ( l->filelen);      
                    342:        memcpy (loadmodel->vis, mod_base + l->fileofs, l->filelen);
                    343: 
                    344:        loadmodel->vis->numclusters = LittleLong (loadmodel->vis->numclusters);
                    345:        for (i=0 ; i<loadmodel->vis->numclusters ; i++)
                    346:        {
                    347:                loadmodel->vis->bitofs[i][0] = LittleLong (loadmodel->vis->bitofs[i][0]);
                    348:                loadmodel->vis->bitofs[i][1] = LittleLong (loadmodel->vis->bitofs[i][1]);
                    349:        }
                    350: }
                    351: 
                    352: 
                    353: /*
                    354: =================
                    355: Mod_LoadVertexes
                    356: =================
                    357: */
                    358: void Mod_LoadVertexes (lump_t *l)
                    359: {
                    360:        dvertex_t       *in;
                    361:        mvertex_t       *out;
                    362:        int                     i, count;
                    363: 
                    364:        in = (void *)(mod_base + l->fileofs);
                    365:        if (l->filelen % sizeof(*in))
                    366:                ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    367:        count = l->filelen / sizeof(*in);
                    368:        out = Hunk_Alloc ( (count+8)*sizeof(*out));             // extra for skybox
                    369: 
                    370:        loadmodel->vertexes = out;
                    371:        loadmodel->numvertexes = count;
                    372: 
                    373:        for ( i=0 ; i<count ; i++, in++, out++)
                    374:        {
                    375:                out->position[0] = LittleFloat (in->point[0]);
                    376:                out->position[1] = LittleFloat (in->point[1]);
                    377:                out->position[2] = LittleFloat (in->point[2]);
                    378:        }
                    379: }
                    380: 
                    381: /*
                    382: =================
                    383: Mod_LoadSubmodels
                    384: =================
                    385: */
                    386: void Mod_LoadSubmodels (lump_t *l)
                    387: {
                    388:        dmodel_t        *in;
                    389:        dmodel_t        *out;
                    390:        int                     i, j, count;
                    391: 
                    392:        in = (void *)(mod_base + l->fileofs);
                    393:        if (l->filelen % sizeof(*in))
                    394:                ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    395:        count = l->filelen / sizeof(*in);
                    396:        out = Hunk_Alloc ( count*sizeof(*out)); 
                    397: 
                    398:        loadmodel->submodels = out;
                    399:        loadmodel->numsubmodels = count;
                    400: 
                    401:        for ( i=0 ; i<count ; i++, in++, out++)
                    402:        {
                    403:                for (j=0 ; j<3 ; j++)
                    404:                {       // spread the mins / maxs by a pixel
                    405:                        out->mins[j] = LittleFloat (in->mins[j]) - 1;
                    406:                        out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
                    407:                        out->origin[j] = LittleFloat (in->origin[j]);
                    408:                }
                    409:                out->headnode = LittleLong (in->headnode);
                    410:                out->firstface = LittleLong (in->firstface);
                    411:                out->numfaces = LittleLong (in->numfaces);
                    412:        }
                    413: }
                    414: 
                    415: /*
                    416: =================
                    417: Mod_LoadEdges
                    418: =================
                    419: */
                    420: void Mod_LoadEdges (lump_t *l)
                    421: {
                    422:        dedge_t *in;
                    423:        medge_t *out;
                    424:        int     i, count;
                    425: 
                    426:        in = (void *)(mod_base + l->fileofs);
                    427:        if (l->filelen % sizeof(*in))
                    428:                ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    429:        count = l->filelen / sizeof(*in);
                    430:        out = Hunk_Alloc ( (count + 13) * sizeof(*out));        // extra for skybox
                    431: 
                    432:        loadmodel->edges = out;
                    433:        loadmodel->numedges = count;
                    434: 
                    435:        for ( i=0 ; i<count ; i++, in++, out++)
                    436:        {
                    437:                out->v[0] = (unsigned short)LittleShort(in->v[0]);
                    438:                out->v[1] = (unsigned short)LittleShort(in->v[1]);
                    439:        }
                    440: }
                    441: 
                    442: /*
                    443: =================
                    444: Mod_LoadTexinfo
                    445: =================
                    446: */
                    447: void Mod_LoadTexinfo (lump_t *l)
                    448: {
                    449:        texinfo_t *in;
                    450:        mtexinfo_t *out, *step;
                    451:        int     i, j, count;
                    452:        float   len1, len2;
                    453:        char    name[MAX_QPATH];
                    454:        int             next;
                    455: 
                    456:        in = (void *)(mod_base + l->fileofs);
                    457:        if (l->filelen % sizeof(*in))
                    458:                ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    459:        count = l->filelen / sizeof(*in);
                    460:        out = Hunk_Alloc ( (count+6)*sizeof(*out));     // extra for skybox
                    461: 
                    462:        loadmodel->texinfo = out;
                    463:        loadmodel->numtexinfo = count;
                    464: 
                    465:        for ( i=0 ; i<count ; i++, in++, out++)
                    466:        {
                    467:                for (j=0 ; j<8 ; j++)
                    468:                        out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
                    469:                len1 = VectorLength (out->vecs[0]);
                    470:                len2 = VectorLength (out->vecs[1]);
                    471:                len1 = (len1 + len2)/2;
                    472:                if (len1 < 0.32)
                    473:                        out->mipadjust = 4;
                    474:                else if (len1 < 0.49)
                    475:                        out->mipadjust = 3;
                    476:                else if (len1 < 0.99)
                    477:                        out->mipadjust = 2;
                    478:                else
                    479:                        out->mipadjust = 1;
                    480: #if 0
                    481:                if (len1 + len2 < 0.001)
                    482:                        out->mipadjust = 1;             // don't crash
                    483:                else
                    484:                        out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 );
                    485: #endif
                    486: 
                    487:                out->flags = LittleLong (in->flags);
                    488: 
                    489:                next = LittleLong (in->nexttexinfo);
                    490:                if (next > 0)
                    491:                        out->next = loadmodel->texinfo + next;
                    492: 
                    493:                Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture);
                    494:                out->image = R_FindImage (name, it_wall);
                    495:                if (!out->image)
                    496:                {
                    497:                        out->image = r_notexture_mip; // texture not found
                    498:                        out->flags = 0;
                    499:                }
                    500:        }
                    501: 
                    502:        // count animation frames
                    503:        for (i=0 ; i<count ; i++)
                    504:        {
                    505:                out = &loadmodel->texinfo[i];
                    506:                out->numframes = 1;
                    507:                for (step = out->next ; step && step != out ; step=step->next)
                    508:                        out->numframes++;
                    509:        }
                    510: }
                    511: 
                    512: /*
                    513: ================
                    514: CalcSurfaceExtents
                    515: 
                    516: Fills in s->texturemins[] and s->extents[]
                    517: ================
                    518: */
                    519: void CalcSurfaceExtents (msurface_t *s)
                    520: {
                    521:        float   mins[2], maxs[2], val;
                    522:        int             i,j, e;
                    523:        mvertex_t       *v;
                    524:        mtexinfo_t      *tex;
                    525:        int             bmins[2], bmaxs[2];
                    526: 
                    527:        mins[0] = mins[1] = 999999;
                    528:        maxs[0] = maxs[1] = -99999;
                    529: 
                    530:        tex = s->texinfo;
                    531:        
                    532:        for (i=0 ; i<s->numedges ; i++)
                    533:        {
                    534:                e = loadmodel->surfedges[s->firstedge+i];
                    535:                if (e >= 0)
                    536:                        v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
                    537:                else
                    538:                        v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
                    539:                
                    540:                for (j=0 ; j<2 ; j++)
                    541:                {
                    542:                        val = v->position[0] * tex->vecs[j][0] + 
                    543:                                v->position[1] * tex->vecs[j][1] +
                    544:                                v->position[2] * tex->vecs[j][2] +
                    545:                                tex->vecs[j][3];
                    546:                        if (val < mins[j])
                    547:                                mins[j] = val;
                    548:                        if (val > maxs[j])
                    549:                                maxs[j] = val;
                    550:                }
                    551:        }
                    552: 
                    553:        for (i=0 ; i<2 ; i++)
                    554:        {       
                    555:                bmins[i] = floor(mins[i]/16);
                    556:                bmaxs[i] = ceil(maxs[i]/16);
                    557: 
                    558:                s->texturemins[i] = bmins[i] * 16;
                    559:                s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
                    560:                if (s->extents[i] < 16)
                    561:                        s->extents[i] = 16;     // take at least one cache block
                    562:                if ( !(tex->flags & (SURF_WARP|SURF_SKY)) && s->extents[i] > 256)
                    563:                        ri.Sys_Error (ERR_DROP,"Bad surface extents");
                    564:        }
                    565: }
                    566: 
                    567: 
                    568: /*
                    569: =================
                    570: Mod_LoadFaces
                    571: =================
                    572: */
                    573: void Mod_LoadFaces (lump_t *l)
                    574: {
                    575:        dface_t         *in;
                    576:        msurface_t      *out;
                    577:        int                     i, count, surfnum;
                    578:        int                     planenum, side;
                    579: 
                    580:        in = (void *)(mod_base + l->fileofs);
                    581:        if (l->filelen % sizeof(*in))
                    582:                ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    583:        count = l->filelen / sizeof(*in);
                    584:        out = Hunk_Alloc ( (count+6)*sizeof(*out));     // extra for skybox
                    585: 
                    586:        loadmodel->surfaces = out;
                    587:        loadmodel->numsurfaces = count;
                    588: 
                    589:        for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
                    590:        {
                    591:                out->firstedge = LittleLong(in->firstedge);
                    592:                out->numedges = LittleShort(in->numedges);              
                    593:                if (out->numedges < 3)
                    594:                        ri.Sys_Error (ERR_DROP,"Surface with %s edges", out->numedges);
                    595:                out->flags = 0;
                    596: 
                    597:                planenum = LittleShort(in->planenum);
                    598:                side = LittleShort(in->side);
                    599:                if (side)
                    600:                        out->flags |= SURF_PLANEBACK;                   
                    601: 
                    602:                out->plane = loadmodel->planes + planenum;
                    603: 
                    604:                out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
                    605: 
                    606:                CalcSurfaceExtents (out);
                    607:                                
                    608:        // lighting info is converted from 24 bit on disk to 8 bit
                    609: 
                    610:                for (i=0 ; i<MAXLIGHTMAPS ; i++)
                    611:                        out->styles[i] = in->styles[i];
                    612:                i = LittleLong(in->lightofs);
                    613:                if (i == -1)
                    614:                        out->samples = NULL;
                    615:                else
                    616:                        out->samples = loadmodel->lightdata + i/3;
                    617:                
                    618:        // set the drawing flags flag
                    619:                
                    620:                if (!out->texinfo->image)
                    621:                        continue;
                    622:                if (out->texinfo->flags & SURF_SKY)
                    623:                {
                    624:                        out->flags |= SURF_DRAWSKY;
                    625:                        continue;
                    626:                }
                    627:                
                    628:                if (out->texinfo->flags & SURF_WARP)
                    629:                {
                    630:                        out->flags |= SURF_DRAWTURB;
                    631:                        for (i=0 ; i<2 ; i++)
                    632:                        {
                    633:                                out->extents[i] = 16384;
                    634:                                out->texturemins[i] = -8192;
                    635:                        }
                    636:                        continue;
                    637:                }
1.1.1.2 ! root      638: //==============
        !           639: //PGM
        !           640:                // this marks flowing surfaces as turbulent, but with the new
        !           641:                // SURF_FLOW flag.
        !           642:                if (out->texinfo->flags & SURF_FLOWING)
        !           643:                {
        !           644:                        out->flags |= SURF_DRAWTURB | SURF_FLOW;
        !           645:                        for (i=0 ; i<2 ; i++)
        !           646:                        {
        !           647:                                out->extents[i] = 16384;
        !           648:                                out->texturemins[i] = -8192;
        !           649:                        }
        !           650:                        continue;
        !           651:                }
        !           652: //PGM
        !           653: //==============
1.1       root      654:        }
                    655: }
                    656: 
                    657: 
                    658: /*
                    659: =================
                    660: Mod_SetParent
                    661: =================
                    662: */
                    663: void Mod_SetParent (mnode_t *node, mnode_t *parent)
                    664: {
                    665:        node->parent = parent;
                    666:        if (node->contents != -1)
                    667:                return;
                    668:        Mod_SetParent (node->children[0], node);
                    669:        Mod_SetParent (node->children[1], node);
                    670: }
                    671: 
                    672: /*
                    673: =================
                    674: Mod_LoadNodes
                    675: =================
                    676: */
                    677: void Mod_LoadNodes (lump_t *l)
                    678: {
                    679:        int                     i, j, count, p;
                    680:        dnode_t         *in;
                    681:        mnode_t         *out;
                    682: 
                    683:        in = (void *)(mod_base + l->fileofs);
                    684:        if (l->filelen % sizeof(*in))
                    685:                ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    686:        count = l->filelen / sizeof(*in);
                    687:        out = Hunk_Alloc ( count*sizeof(*out)); 
                    688: 
                    689:        loadmodel->nodes = out;
                    690:        loadmodel->numnodes = count;
                    691: 
                    692:        for ( i=0 ; i<count ; i++, in++, out++)
                    693:        {
                    694:                for (j=0 ; j<3 ; j++)
                    695:                {
                    696:                        out->minmaxs[j] = LittleShort (in->mins[j]);
                    697:                        out->minmaxs[3+j] = LittleShort (in->maxs[j]);
                    698:                }
                    699:        
                    700:                p = LittleLong(in->planenum);
                    701:                out->plane = loadmodel->planes + p;
                    702: 
                    703:                out->firstsurface = LittleShort (in->firstface);
                    704:                out->numsurfaces = LittleShort (in->numfaces);
                    705:                out->contents = CONTENTS_NODE;  // differentiate from leafs
                    706:                
                    707:                for (j=0 ; j<2 ; j++)
                    708:                {
                    709:                        p = LittleLong (in->children[j]);
                    710:                        if (p >= 0)
                    711:                                out->children[j] = loadmodel->nodes + p;
                    712:                        else
                    713:                                out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
                    714:                }
                    715:        }
                    716:        
                    717:        Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
                    718: }
                    719: 
                    720: /*
                    721: =================
                    722: Mod_LoadLeafs
                    723: =================
                    724: */
                    725: void Mod_LoadLeafs (lump_t *l)
                    726: {
                    727:        dleaf_t         *in;
                    728:        mleaf_t         *out;
                    729:        int                     i, j, count;
                    730: 
                    731:        in = (void *)(mod_base + l->fileofs);
                    732:        if (l->filelen % sizeof(*in))
                    733:                ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    734:        count = l->filelen / sizeof(*in);
                    735:        out = Hunk_Alloc ( count*sizeof(*out));
                    736: 
                    737:        loadmodel->leafs = out;
                    738:        loadmodel->numleafs = count;
                    739: 
                    740:        for ( i=0 ; i<count ; i++, in++, out++)
                    741:        {
                    742:                for (j=0 ; j<3 ; j++)
                    743:                {
                    744:                        out->minmaxs[j] = LittleShort (in->mins[j]);
                    745:                        out->minmaxs[3+j] = LittleShort (in->maxs[j]);
                    746:                }
                    747: 
                    748:                out->contents = LittleLong(in->contents);
                    749:                out->cluster = LittleShort(in->cluster);
                    750:                out->area = LittleShort(in->area);
                    751: 
                    752:                out->firstmarksurface = loadmodel->marksurfaces +
                    753:                        LittleShort(in->firstleafface);
                    754:                out->nummarksurfaces = LittleShort(in->numleaffaces);
                    755:        }       
                    756: }
                    757: 
                    758: 
                    759: /*
                    760: =================
                    761: Mod_LoadMarksurfaces
                    762: =================
                    763: */
                    764: void Mod_LoadMarksurfaces (lump_t *l)
                    765: {      
                    766:        int             i, j, count;
                    767:        short           *in;
                    768:        msurface_t **out;
                    769:        
                    770:        in = (void *)(mod_base + l->fileofs);
                    771:        if (l->filelen % sizeof(*in))
                    772:                ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    773:        count = l->filelen / sizeof(*in);
                    774:        out = Hunk_Alloc ( count*sizeof(*out)); 
                    775: 
                    776:        loadmodel->marksurfaces = out;
                    777:        loadmodel->nummarksurfaces = count;
                    778: 
                    779:        for ( i=0 ; i<count ; i++)
                    780:        {
                    781:                j = LittleShort(in[i]);
                    782:                if (j >= loadmodel->numsurfaces)
                    783:                        ri.Sys_Error (ERR_DROP,"Mod_ParseMarksurfaces: bad surface number");
                    784:                out[i] = loadmodel->surfaces + j;
                    785:        }
                    786: }
                    787: 
                    788: /*
                    789: =================
                    790: Mod_LoadSurfedges
                    791: =================
                    792: */
                    793: void Mod_LoadSurfedges (lump_t *l)
                    794: {      
                    795:        int             i, count;
                    796:        int             *in, *out;
                    797:        
                    798:        in = (void *)(mod_base + l->fileofs);
                    799:        if (l->filelen % sizeof(*in))
                    800:                ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    801:        count = l->filelen / sizeof(*in);
                    802:        out = Hunk_Alloc ( (count+24)*sizeof(*out));    // extra for skybox
                    803: 
                    804:        loadmodel->surfedges = out;
                    805:        loadmodel->numsurfedges = count;
                    806: 
                    807:        for ( i=0 ; i<count ; i++)
                    808:                out[i] = LittleLong (in[i]);
                    809: }
                    810: 
                    811: /*
                    812: =================
                    813: Mod_LoadPlanes
                    814: =================
                    815: */
                    816: void Mod_LoadPlanes (lump_t *l)
                    817: {
                    818:        int                     i, j;
                    819:        mplane_t        *out;
                    820:        dplane_t        *in;
                    821:        int                     count;
                    822:        int                     bits;
                    823:        
                    824:        in = (void *)(mod_base + l->fileofs);
                    825:        if (l->filelen % sizeof(*in))
                    826:                ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
                    827:        count = l->filelen / sizeof(*in);
                    828:        out = Hunk_Alloc ( (count+6)*sizeof(*out));             // extra for skybox
                    829:        
                    830:        loadmodel->planes = out;
                    831:        loadmodel->numplanes = count;
                    832: 
                    833:        for ( i=0 ; i<count ; i++, in++, out++)
                    834:        {
                    835:                bits = 0;
                    836:                for (j=0 ; j<3 ; j++)
                    837:                {
                    838:                        out->normal[j] = LittleFloat (in->normal[j]);
                    839:                        if (out->normal[j] < 0)
                    840:                                bits |= 1<<j;
                    841:                }
                    842: 
                    843:                out->dist = LittleFloat (in->dist);
                    844:                out->type = LittleLong (in->type);
                    845:                out->signbits = bits;
                    846:        }
                    847: }
                    848: 
                    849: 
                    850: /*
                    851: =================
                    852: Mod_LoadBrushModel
                    853: =================
                    854: */
                    855: void Mod_LoadBrushModel (model_t *mod, void *buffer)
                    856: {
                    857:        int                     i;
                    858:        dheader_t       *header;
                    859:        dmodel_t        *bm;
                    860:        
                    861:        loadmodel->type = mod_brush;
                    862:        if (loadmodel != mod_known)
                    863:                ri.Sys_Error (ERR_DROP, "Loaded a brush model after the world");
                    864:        
                    865:        header = (dheader_t *)buffer;
                    866: 
                    867:        i = LittleLong (header->version);
                    868:        if (i != BSPVERSION)
                    869:                ri.Sys_Error (ERR_DROP,"Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
                    870: 
                    871: // swap all the lumps
                    872:        mod_base = (byte *)header;
                    873: 
                    874:        for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
                    875:                ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
                    876: 
                    877: // load into heap
                    878:        
                    879:        Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
                    880:        Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
                    881:        Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
                    882:        Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
                    883:        Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
                    884:        Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
                    885:        Mod_LoadFaces (&header->lumps[LUMP_FACES]);
                    886:        Mod_LoadMarksurfaces (&header->lumps[LUMP_LEAFFACES]);
                    887:        Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
                    888:        Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
                    889:        Mod_LoadNodes (&header->lumps[LUMP_NODES]);
                    890:        Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
                    891:        r_numvisleafs = 0;
                    892:        R_NumberLeafs (loadmodel->nodes);
                    893:        
                    894: //
                    895: // set up the submodels
                    896: //
                    897:        for (i=0 ; i<mod->numsubmodels ; i++)
                    898:        {
                    899:                model_t *starmod;
                    900: 
                    901:                bm = &mod->submodels[i];
                    902:                starmod = &mod_inline[i];
                    903: 
                    904:                *starmod = *loadmodel;
                    905:                
                    906:                starmod->firstmodelsurface = bm->firstface;
                    907:                starmod->nummodelsurfaces = bm->numfaces;
                    908:                starmod->firstnode = bm->headnode;
                    909:                if (starmod->firstnode >= loadmodel->numnodes)
                    910:                        ri.Sys_Error (ERR_DROP, "Inline model %i has bad firstnode", i);
                    911: 
                    912:                VectorCopy (bm->maxs, starmod->maxs);
                    913:                VectorCopy (bm->mins, starmod->mins);
                    914:        
                    915:                if (i == 0)
                    916:                        *loadmodel = *starmod;
                    917:        }
                    918: 
                    919:        R_InitSkyBox ();
                    920: }
                    921: 
                    922: /*
                    923: ==============================================================================
                    924: 
                    925: ALIAS MODELS
                    926: 
                    927: ==============================================================================
                    928: */
                    929: 
                    930: /*
                    931: =================
                    932: Mod_LoadAliasModel
                    933: =================
                    934: */
                    935: void Mod_LoadAliasModel (model_t *mod, void *buffer)
                    936: {
                    937:        int                                     i, j;
                    938:        dmdl_t                          *pinmodel, *pheader;
                    939:        dstvert_t                       *pinst, *poutst;
                    940:        dtriangle_t                     *pintri, *pouttri;
                    941:        daliasframe_t           *pinframe, *poutframe;
                    942:        int                                     *pincmd, *poutcmd;
                    943:        int                                     version;
                    944: 
                    945:        pinmodel = (dmdl_t *)buffer;
                    946: 
                    947:        version = LittleLong (pinmodel->version);
                    948:        if (version != ALIAS_VERSION)
                    949:                ri.Sys_Error (ERR_DROP, "%s has wrong version number (%i should be %i)",
                    950:                                 mod->name, version, ALIAS_VERSION);
                    951: 
                    952:        pheader = Hunk_Alloc (LittleLong(pinmodel->ofs_end));
                    953:        
                    954:        // byte swap the header fields and sanity check
                    955:        for (i=0 ; i<sizeof(dmdl_t)/4 ; i++)
                    956:                ((int *)pheader)[i] = LittleLong (((int *)buffer)[i]);
                    957: 
                    958:        if (pheader->skinheight > MAX_LBM_HEIGHT)
                    959:                ri.Sys_Error (ERR_DROP, "model %s has a skin taller than %d", mod->name,
                    960:                                   MAX_LBM_HEIGHT);
                    961: 
                    962:        if (pheader->num_xyz <= 0)
                    963:                ri.Sys_Error (ERR_DROP, "model %s has no vertices", mod->name);
                    964: 
                    965:        if (pheader->num_xyz > MAX_VERTS)
                    966:                ri.Sys_Error (ERR_DROP, "model %s has too many vertices", mod->name);
                    967: 
                    968:        if (pheader->num_st <= 0)
                    969:                ri.Sys_Error (ERR_DROP, "model %s has no st vertices", mod->name);
                    970: 
                    971:        if (pheader->num_tris <= 0)
                    972:                ri.Sys_Error (ERR_DROP, "model %s has no triangles", mod->name);
                    973: 
                    974:        if (pheader->num_frames <= 0)
                    975:                ri.Sys_Error (ERR_DROP, "model %s has no frames", mod->name);
                    976: 
                    977: //
                    978: // load base s and t vertices (not used in gl version)
                    979: //
                    980:        pinst = (dstvert_t *) ((byte *)pinmodel + pheader->ofs_st);
                    981:        poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st);
                    982: 
                    983:        for (i=0 ; i<pheader->num_st ; i++)
                    984:        {
                    985:                poutst[i].s = LittleShort (pinst[i].s);
                    986:                poutst[i].t = LittleShort (pinst[i].t);
                    987:        }
                    988: 
                    989: //
                    990: // load triangle lists
                    991: //
                    992:        pintri = (dtriangle_t *) ((byte *)pinmodel + pheader->ofs_tris);
                    993:        pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris);
                    994: 
                    995:        for (i=0 ; i<pheader->num_tris ; i++)
                    996:        {
                    997:                for (j=0 ; j<3 ; j++)
                    998:                {
                    999:                        pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]);
                   1000:                        pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]);
                   1001:                }
                   1002:        }
                   1003: 
                   1004: //
                   1005: // load the frames
                   1006: //
                   1007:        for (i=0 ; i<pheader->num_frames ; i++)
                   1008:        {
                   1009:                pinframe = (daliasframe_t *) ((byte *)pinmodel 
                   1010:                        + pheader->ofs_frames + i * pheader->framesize);
                   1011:                poutframe = (daliasframe_t *) ((byte *)pheader 
                   1012:                        + pheader->ofs_frames + i * pheader->framesize);
                   1013: 
                   1014:                memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name));
                   1015:                for (j=0 ; j<3 ; j++)
                   1016:                {
                   1017:                        poutframe->scale[j] = LittleFloat (pinframe->scale[j]);
                   1018:                        poutframe->translate[j] = LittleFloat (pinframe->translate[j]);
                   1019:                }
                   1020:                // verts are all 8 bit, so no swapping needed
                   1021:                memcpy (poutframe->verts, pinframe->verts, 
                   1022:                        pheader->num_xyz*sizeof(dtrivertx_t));
                   1023: 
                   1024:        }
                   1025: 
                   1026:        mod->type = mod_alias;
                   1027: 
                   1028:        //
                   1029:        // load the glcmds
                   1030:        //
                   1031:        pincmd = (int *) ((byte *)pinmodel + pheader->ofs_glcmds);
                   1032:        poutcmd = (int *) ((byte *)pheader + pheader->ofs_glcmds);
                   1033:        for (i=0 ; i<pheader->num_glcmds ; i++)
                   1034:                poutcmd[i] = LittleLong (pincmd[i]);
                   1035: 
                   1036: 
                   1037:        // register all skins
                   1038:        memcpy ((char *)pheader + pheader->ofs_skins, (char *)pinmodel + pheader->ofs_skins,
                   1039:                pheader->num_skins*MAX_SKINNAME);
                   1040:        for (i=0 ; i<pheader->num_skins ; i++)
                   1041:        {
                   1042:                mod->skins[i] = R_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin);
                   1043:        }
                   1044: }
                   1045: 
                   1046: /*
                   1047: ==============================================================================
                   1048: 
                   1049: SPRITE MODELS
                   1050: 
                   1051: ==============================================================================
                   1052: */
                   1053: 
                   1054: /*
                   1055: =================
                   1056: Mod_LoadSpriteModel
                   1057: =================
                   1058: */
                   1059: void Mod_LoadSpriteModel (model_t *mod, void *buffer)
                   1060: {
                   1061:        dsprite_t       *sprin, *sprout;
                   1062:        int                     i;
                   1063: 
                   1064:        sprin = (dsprite_t *)buffer;
                   1065:        sprout = Hunk_Alloc (modfilelen);
                   1066: 
                   1067:        sprout->ident = LittleLong (sprin->ident);
                   1068:        sprout->version = LittleLong (sprin->version);
                   1069:        sprout->numframes = LittleLong (sprin->numframes);
                   1070: 
                   1071:        if (sprout->version != SPRITE_VERSION)
                   1072:                ri.Sys_Error (ERR_DROP, "%s has wrong version number (%i should be %i)",
                   1073:                                 mod->name, sprout->version, SPRITE_VERSION);
                   1074: 
                   1075:        if (sprout->numframes > MAX_MD2SKINS)
                   1076:                ri.Sys_Error (ERR_DROP, "%s has too many frames (%i > %i)",
                   1077:                                 mod->name, sprout->numframes, MAX_MD2SKINS);
                   1078: 
                   1079:        // byte swap everything
                   1080:        for (i=0 ; i<sprout->numframes ; i++)
                   1081:        {
                   1082:                sprout->frames[i].width = LittleLong (sprin->frames[i].width);
                   1083:                sprout->frames[i].height = LittleLong (sprin->frames[i].height);
                   1084:                sprout->frames[i].origin_x = LittleLong (sprin->frames[i].origin_x);
                   1085:                sprout->frames[i].origin_y = LittleLong (sprin->frames[i].origin_y);
                   1086:                memcpy (sprout->frames[i].name, sprin->frames[i].name, MAX_SKINNAME);
                   1087:                mod->skins[i] = R_FindImage (sprout->frames[i].name, it_sprite);
                   1088:        }
                   1089: 
                   1090:        mod->type = mod_sprite;
                   1091: }
                   1092: 
                   1093: //=============================================================================
                   1094: 
                   1095: /*
                   1096: @@@@@@@@@@@@@@@@@@@@@
                   1097: R_BeginRegistration
                   1098: 
                   1099: Specifies the model that will be used as the world
                   1100: @@@@@@@@@@@@@@@@@@@@@
                   1101: */
                   1102: void R_BeginRegistration (char *model)
                   1103: {
                   1104:        char    fullname[MAX_QPATH];
                   1105:        cvar_t  *flushmap;
                   1106: 
                   1107:        registration_sequence++;
                   1108:        r_oldviewcluster = -1;          // force markleafs
                   1109:        Com_sprintf (fullname, sizeof(fullname), "maps/%s.bsp", model);
                   1110: 
                   1111:        D_FlushCaches ();
                   1112:        // explicitly free the old map if different
                   1113:        // this guarantees that mod_known[0] is the world map
                   1114:        flushmap = ri.Cvar_Get ("flushmap", "0", 0);
                   1115:        if ( strcmp(mod_known[0].name, fullname) || flushmap->value)
                   1116:                Mod_Free (&mod_known[0]);
                   1117:        r_worldmodel = R_RegisterModel (fullname);
                   1118:        R_NewMap ();
                   1119: }
                   1120: 
                   1121: 
                   1122: /*
                   1123: @@@@@@@@@@@@@@@@@@@@@
                   1124: R_RegisterModel
                   1125: 
                   1126: @@@@@@@@@@@@@@@@@@@@@
                   1127: */
                   1128: struct model_s *R_RegisterModel (char *name)
                   1129: {
                   1130:        model_t *mod;
                   1131:        int             i;
                   1132:        dsprite_t       *sprout;
                   1133:        dmdl_t          *pheader;
                   1134: 
                   1135:        mod = Mod_ForName (name, false);
                   1136:        if (mod)
                   1137:        {
                   1138:                mod->registration_sequence = registration_sequence;
                   1139: 
                   1140:                // register any images used by the models
                   1141:                if (mod->type == mod_sprite)
                   1142:                {
                   1143:                        sprout = (dsprite_t *)mod->extradata;
                   1144:                        for (i=0 ; i<sprout->numframes ; i++)
                   1145:                                mod->skins[i] = R_FindImage (sprout->frames[i].name, it_sprite);
                   1146:                }
                   1147:                else if (mod->type == mod_alias)
                   1148:                {
                   1149:                        pheader = (dmdl_t *)mod->extradata;
                   1150:                        for (i=0 ; i<pheader->num_skins ; i++)
                   1151:                                mod->skins[i] = R_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin);
1.1.1.2 ! root     1152: //PGM
        !          1153:                        mod->numframes = pheader->num_frames;
        !          1154: //PGM
1.1       root     1155:                }
                   1156:                else if (mod->type == mod_brush)
                   1157:                {
                   1158:                        for (i=0 ; i<mod->numtexinfo ; i++)
                   1159:                                mod->texinfo[i].image->registration_sequence = registration_sequence;
                   1160:                }
                   1161:        }
                   1162:        return mod;
                   1163: }
                   1164: 
                   1165: /*
                   1166: @@@@@@@@@@@@@@@@@@@@@
                   1167: R_EndRegistration
                   1168: 
                   1169: @@@@@@@@@@@@@@@@@@@@@
                   1170: */
                   1171: void R_EndRegistration (void)
                   1172: {
                   1173:        int             i;
                   1174:        model_t *mod;
                   1175: 
                   1176:        for (i=0, mod=mod_known ; i<mod_numknown ; i++, mod++)
                   1177:        {
                   1178:                if (!mod->name[0])
                   1179:                        continue;
                   1180:                if (mod->registration_sequence != registration_sequence)
                   1181:                {       // don't need this model
                   1182:                        Hunk_Free (mod->extradata);
                   1183:                        memset (mod, 0, sizeof(*mod));
                   1184:                }
                   1185:                else
                   1186:                {       // make sure it is paged in
                   1187:                        Com_PageInMemory (mod->extradata, mod->extradatasize);
                   1188:                }
                   1189:        }
                   1190: 
                   1191:        R_FreeUnusedImages ();
                   1192: }
                   1193: 
                   1194: 
                   1195: //=============================================================================
                   1196: 
                   1197: /*
                   1198: ================
                   1199: Mod_Free
                   1200: ================
                   1201: */
                   1202: void Mod_Free (model_t *mod)
                   1203: {
                   1204:        Hunk_Free (mod->extradata);
                   1205:        memset (mod, 0, sizeof(*mod));
                   1206: }
                   1207: 
                   1208: /*
                   1209: ================
                   1210: Mod_FreeAll
                   1211: ================
                   1212: */
                   1213: void Mod_FreeAll (void)
                   1214: {
                   1215:        int             i;
                   1216: 
                   1217:        for (i=0 ; i<mod_numknown ; i++)
                   1218:        {
                   1219:                if (mod_known[i].extradatasize)
                   1220:                        Mod_Free (&mod_known[i]);
                   1221:        }
                   1222: }

unix.superglobalmegacorp.com

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