Annotation of quakeworld/server/model.c, revision 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 "qwsvdef.h"
        !            26: 
        !            27: model_t        *loadmodel;
        !            28: char   loadname[32];   // for hunk tags
        !            29: 
        !            30: void Mod_LoadSpriteModel (model_t *mod, void *buffer);
        !            31: void Mod_LoadBrushModel (model_t *mod, void *buffer);
        !            32: void Mod_LoadAliasModel (model_t *mod, void *buffer);
        !            33: model_t *Mod_LoadModel (model_t *mod, qboolean crash);
        !            34: 
        !            35: byte   mod_novis[MAX_MAP_LEAFS/8];
        !            36: 
        !            37: #define        MAX_MOD_KNOWN   256
        !            38: model_t        mod_known[MAX_MOD_KNOWN];
        !            39: int            mod_numknown;
        !            40: 
        !            41: texture_t      r_notexture_mip;
        !            42: 
        !            43: unsigned *model_checksum;
        !            44: 
        !            45: /*
        !            46: ===============
        !            47: Mod_Init
        !            48: ===============
        !            49: */
        !            50: void Mod_Init (void)
        !            51: {
        !            52:        memset (mod_novis, 0xff, sizeof(mod_novis));
        !            53: }
        !            54: 
        !            55: /*
        !            56: ===============
        !            57: Mod_PointInLeaf
        !            58: ===============
        !            59: */
        !            60: mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
        !            61: {
        !            62:        mnode_t         *node;
        !            63:        float           d;
        !            64:        mplane_t        *plane;
        !            65:        
        !            66:        if (!model || !model->nodes)
        !            67:                SV_Error ("Mod_PointInLeaf: bad model");
        !            68: 
        !            69:        node = model->nodes;
        !            70:        while (1)
        !            71:        {
        !            72:                if (node->contents < 0)
        !            73:                        return (mleaf_t *)node;
        !            74:                plane = node->plane;
        !            75:                d = DotProduct (p,plane->normal) - plane->dist;
        !            76:                if (d > 0)
        !            77:                        node = node->children[0];
        !            78:                else
        !            79:                        node = node->children[1];
        !            80:        }
        !            81:        
        !            82:        return NULL;    // never reached
        !            83: }
        !            84: 
        !            85: 
        !            86: /*
        !            87: ===================
        !            88: Mod_DecompressVis
        !            89: ===================
        !            90: */
        !            91: byte *Mod_DecompressVis (byte *in, model_t *model)
        !            92: {
        !            93:        static byte     decompressed[MAX_MAP_LEAFS/8];
        !            94:        int             c;
        !            95:        byte    *out;
        !            96:        int             row;
        !            97: 
        !            98:        row = (model->numleafs+7)>>3;   
        !            99:        out = decompressed;
        !           100: 
        !           101: #if 0
        !           102:        memcpy (out, in, row);
        !           103: #else
        !           104:        if (!in)
        !           105:        {       // no vis info, so make all visible
        !           106:                while (row)
        !           107:                {
        !           108:                        *out++ = 0xff;
        !           109:                        row--;
        !           110:                }
        !           111:                return decompressed;            
        !           112:        }
        !           113: 
        !           114:        do
        !           115:        {
        !           116:                if (*in)
        !           117:                {
        !           118:                        *out++ = *in++;
        !           119:                        continue;
        !           120:                }
        !           121:        
        !           122:                c = in[1];
        !           123:                in += 2;
        !           124:                while (c)
        !           125:                {
        !           126:                        *out++ = 0;
        !           127:                        c--;
        !           128:                }
        !           129:        } while (out - decompressed < row);
        !           130: #endif
        !           131:        
        !           132:        return decompressed;
        !           133: }
        !           134: 
        !           135: byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
        !           136: {
        !           137:        if (leaf == model->leafs)
        !           138:                return mod_novis;
        !           139:        return Mod_DecompressVis (leaf->compressed_vis, model);
        !           140: }
        !           141: 
        !           142: /*
        !           143: ===================
        !           144: Mod_ClearAll
        !           145: ===================
        !           146: */
        !           147: void Mod_ClearAll (void)
        !           148: {
        !           149:        int             i;
        !           150:        model_t *mod;
        !           151:        
        !           152:        for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
        !           153:                if (mod->type != mod_alias)
        !           154:                        mod->needload = true;
        !           155: }
        !           156: 
        !           157: /*
        !           158: ==================
        !           159: Mod_FindName
        !           160: 
        !           161: ==================
        !           162: */
        !           163: model_t *Mod_FindName (char *name)
        !           164: {
        !           165:        int             i;
        !           166:        model_t *mod;
        !           167:        
        !           168:        if (!name[0])
        !           169:                SV_Error ("Mod_ForName: NULL name");
        !           170:                
        !           171: //
        !           172: // search the currently loaded models
        !           173: //
        !           174:        for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
        !           175:                if (!strcmp (mod->name, name) )
        !           176:                        break;
        !           177:                        
        !           178:        if (i == mod_numknown)
        !           179:        {
        !           180:                if (mod_numknown == MAX_MOD_KNOWN)
        !           181:                        SV_Error ("mod_numknown == MAX_MOD_KNOWN");
        !           182:                strcpy (mod->name, name);
        !           183:                mod->needload = true;
        !           184:                mod_numknown++;
        !           185:        }
        !           186: 
        !           187:        return mod;
        !           188: }
        !           189: 
        !           190: 
        !           191: /*
        !           192: ==================
        !           193: Mod_LoadModel
        !           194: 
        !           195: Loads a model into the cache
        !           196: ==================
        !           197: */
        !           198: model_t *Mod_LoadModel (model_t *mod, qboolean crash)
        !           199: {
        !           200:        void    *d;
        !           201:        unsigned *buf;
        !           202:        byte    stackbuf[1024];         // avoid dirtying the cache heap
        !           203: 
        !           204:        if (!mod->needload)
        !           205:        {
        !           206:                if (mod->type == mod_alias)
        !           207:                {
        !           208:                        d = Cache_Check (&mod->cache);
        !           209:                        if (d)
        !           210:                                return mod;
        !           211:                }
        !           212:                else
        !           213:                        return mod;             // not cached at all
        !           214:        }
        !           215:        
        !           216: //
        !           217: // load the file
        !           218: //
        !           219:        buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf));
        !           220:        if (!buf)
        !           221:        {
        !           222:                if (crash)
        !           223:                        SV_Error ("Mod_NumForName: %s not found", mod->name);
        !           224:                return NULL;
        !           225:        }
        !           226:        
        !           227: //
        !           228: // allocate a new model
        !           229: //
        !           230:        COM_FileBase (mod->name, loadname);
        !           231:        
        !           232:        loadmodel = mod;
        !           233: 
        !           234: //
        !           235: // fill it in
        !           236: //
        !           237: 
        !           238: // call the apropriate loader
        !           239:        mod->needload = false;
        !           240:        
        !           241:        Mod_LoadBrushModel (mod, buf);
        !           242: 
        !           243:        return mod;
        !           244: }
        !           245: 
        !           246: /*
        !           247: ==================
        !           248: Mod_ForName
        !           249: 
        !           250: Loads in a model for the given name
        !           251: ==================
        !           252: */
        !           253: model_t *Mod_ForName (char *name, qboolean crash)
        !           254: {
        !           255:        model_t *mod;
        !           256:        
        !           257:        mod = Mod_FindName (name);
        !           258:        
        !           259:        return Mod_LoadModel (mod, crash);
        !           260: }
        !           261: 
        !           262: 
        !           263: /*
        !           264: ===============================================================================
        !           265: 
        !           266:                                        BRUSHMODEL LOADING
        !           267: 
        !           268: ===============================================================================
        !           269: */
        !           270: 
        !           271: byte   *mod_base;
        !           272: 
        !           273: 
        !           274: /*
        !           275: =================
        !           276: Mod_LoadTextures
        !           277: =================
        !           278: */
        !           279: void Mod_LoadTextures (lump_t *l)
        !           280: {
        !           281:        int             i, j, pixels, num, max, altmax;
        !           282:        miptex_t        *mt;
        !           283:        texture_t       *tx, *tx2;
        !           284:        texture_t       *anims[10];
        !           285:        texture_t       *altanims[10];
        !           286:        dmiptexlump_t *m;
        !           287: 
        !           288:        if (!l->filelen)
        !           289:        {
        !           290:                loadmodel->textures = NULL;
        !           291:                return;
        !           292:        }
        !           293:        m = (dmiptexlump_t *)(mod_base + l->fileofs);
        !           294:        
        !           295:        m->nummiptex = LittleLong (m->nummiptex);
        !           296:        
        !           297:        loadmodel->numtextures = m->nummiptex;
        !           298:        loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname);
        !           299: 
        !           300:        for (i=0 ; i<m->nummiptex ; i++)
        !           301:        {
        !           302:                m->dataofs[i] = LittleLong(m->dataofs[i]);
        !           303:                if (m->dataofs[i] == -1)
        !           304:                        continue;
        !           305:                mt = (miptex_t *)((byte *)m + m->dataofs[i]);
        !           306:                mt->width = LittleLong (mt->width);
        !           307:                mt->height = LittleLong (mt->height);
        !           308:                for (j=0 ; j<MIPLEVELS ; j++)
        !           309:                        mt->offsets[j] = LittleLong (mt->offsets[j]);
        !           310:                
        !           311:                if ( (mt->width & 15) || (mt->height & 15) )
        !           312:                        SV_Error ("Texture %s is not 16 aligned", mt->name);
        !           313:                pixels = mt->width*mt->height/64*85;
        !           314:                tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
        !           315:                loadmodel->textures[i] = tx;
        !           316: 
        !           317:                memcpy (tx->name, mt->name, sizeof(tx->name));
        !           318:                tx->width = mt->width;
        !           319:                tx->height = mt->height;
        !           320:                for (j=0 ; j<MIPLEVELS ; j++)
        !           321:                        tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
        !           322:                // the pixels immediately follow the structures
        !           323:                memcpy ( tx+1, mt+1, pixels);
        !           324:        }
        !           325: 
        !           326: //
        !           327: // sequence the animations
        !           328: //
        !           329:        for (i=0 ; i<m->nummiptex ; i++)
        !           330:        {
        !           331:                tx = loadmodel->textures[i];
        !           332:                if (!tx || tx->name[0] != '+')
        !           333:                        continue;
        !           334:                if (tx->anim_next)
        !           335:                        continue;       // allready sequenced
        !           336: 
        !           337:        // find the number of frames in the animation
        !           338:                memset (anims, 0, sizeof(anims));
        !           339:                memset (altanims, 0, sizeof(altanims));
        !           340: 
        !           341:                max = tx->name[1];
        !           342:                altmax = 0;
        !           343:                if (max >= 'a' && max <= 'z')
        !           344:                        max -= 'a' - 'A';
        !           345:                if (max >= '0' && max <= '9')
        !           346:                {
        !           347:                        max -= '0';
        !           348:                        altmax = 0;
        !           349:                        anims[max] = tx;
        !           350:                        max++;
        !           351:                }
        !           352:                else if (max >= 'A' && max <= 'J')
        !           353:                {
        !           354:                        altmax = max - 'A';
        !           355:                        max = 0;
        !           356:                        altanims[altmax] = tx;
        !           357:                        altmax++;
        !           358:                }
        !           359:                else
        !           360:                        SV_Error ("Bad animating texture %s", tx->name);
        !           361: 
        !           362:                for (j=i+1 ; j<m->nummiptex ; j++)
        !           363:                {
        !           364:                        tx2 = loadmodel->textures[j];
        !           365:                        if (!tx2 || tx2->name[0] != '+')
        !           366:                                continue;
        !           367:                        if (strcmp (tx2->name+2, tx->name+2))
        !           368:                                continue;
        !           369: 
        !           370:                        num = tx2->name[1];
        !           371:                        if (num >= 'a' && num <= 'z')
        !           372:                                num -= 'a' - 'A';
        !           373:                        if (num >= '0' && num <= '9')
        !           374:                        {
        !           375:                                num -= '0';
        !           376:                                anims[num] = tx2;
        !           377:                                if (num+1 > max)
        !           378:                                        max = num + 1;
        !           379:                        }
        !           380:                        else if (num >= 'A' && num <= 'J')
        !           381:                        {
        !           382:                                num = num - 'A';
        !           383:                                altanims[num] = tx2;
        !           384:                                if (num+1 > altmax)
        !           385:                                        altmax = num+1;
        !           386:                        }
        !           387:                        else
        !           388:                                SV_Error ("Bad animating texture %s", tx->name);
        !           389:                }
        !           390:                
        !           391: #define        ANIM_CYCLE      2
        !           392:        // link them all together
        !           393:                for (j=0 ; j<max ; j++)
        !           394:                {
        !           395:                        tx2 = anims[j];
        !           396:                        if (!tx2)
        !           397:                                SV_Error ("Missing frame %i of %s",j, tx->name);
        !           398:                        tx2->anim_total = max * ANIM_CYCLE;
        !           399:                        tx2->anim_min = j * ANIM_CYCLE;
        !           400:                        tx2->anim_max = (j+1) * ANIM_CYCLE;
        !           401:                        tx2->anim_next = anims[ (j+1)%max ];
        !           402:                        if (altmax)
        !           403:                                tx2->alternate_anims = altanims[0];
        !           404:                }
        !           405:                for (j=0 ; j<altmax ; j++)
        !           406:                {
        !           407:                        tx2 = altanims[j];
        !           408:                        if (!tx2)
        !           409:                                SV_Error ("Missing frame %i of %s",j, tx->name);
        !           410:                        tx2->anim_total = altmax * ANIM_CYCLE;
        !           411:                        tx2->anim_min = j * ANIM_CYCLE;
        !           412:                        tx2->anim_max = (j+1) * ANIM_CYCLE;
        !           413:                        tx2->anim_next = altanims[ (j+1)%altmax ];
        !           414:                        if (max)
        !           415:                                tx2->alternate_anims = anims[0];
        !           416:                }
        !           417:        }
        !           418: }
        !           419: 
        !           420: /*
        !           421: =================
        !           422: Mod_LoadLighting
        !           423: =================
        !           424: */
        !           425: void Mod_LoadLighting (lump_t *l)
        !           426: {
        !           427:        if (!l->filelen)
        !           428:        {
        !           429:                loadmodel->lightdata = NULL;
        !           430:                return;
        !           431:        }
        !           432:        loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname);  
        !           433:        memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
        !           434: }
        !           435: 
        !           436: 
        !           437: /*
        !           438: =================
        !           439: Mod_LoadVisibility
        !           440: =================
        !           441: */
        !           442: void Mod_LoadVisibility (lump_t *l)
        !           443: {
        !           444:        if (!l->filelen)
        !           445:        {
        !           446:                loadmodel->visdata = NULL;
        !           447:                return;
        !           448:        }
        !           449:        loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname);    
        !           450:        memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
        !           451: }
        !           452: 
        !           453: 
        !           454: /*
        !           455: =================
        !           456: Mod_LoadEntities
        !           457: =================
        !           458: */
        !           459: void Mod_LoadEntities (lump_t *l)
        !           460: {
        !           461:        if (!l->filelen)
        !           462:        {
        !           463:                loadmodel->entities = NULL;
        !           464:                return;
        !           465:        }
        !           466:        loadmodel->entities = Hunk_AllocName ( l->filelen, loadname);   
        !           467:        memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen);
        !           468: }
        !           469: 
        !           470: 
        !           471: /*
        !           472: =================
        !           473: Mod_LoadVertexes
        !           474: =================
        !           475: */
        !           476: void Mod_LoadVertexes (lump_t *l)
        !           477: {
        !           478:        dvertex_t       *in;
        !           479:        mvertex_t       *out;
        !           480:        int                     i, count;
        !           481: 
        !           482:        in = (void *)(mod_base + l->fileofs);
        !           483:        if (l->filelen % sizeof(*in))
        !           484:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !           485:        count = l->filelen / sizeof(*in);
        !           486:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
        !           487: 
        !           488:        loadmodel->vertexes = out;
        !           489:        loadmodel->numvertexes = count;
        !           490: 
        !           491:        for ( i=0 ; i<count ; i++, in++, out++)
        !           492:        {
        !           493:                out->position[0] = LittleFloat (in->point[0]);
        !           494:                out->position[1] = LittleFloat (in->point[1]);
        !           495:                out->position[2] = LittleFloat (in->point[2]);
        !           496:        }
        !           497: }
        !           498: 
        !           499: /*
        !           500: =================
        !           501: Mod_LoadSubmodels
        !           502: =================
        !           503: */
        !           504: void Mod_LoadSubmodels (lump_t *l)
        !           505: {
        !           506:        dmodel_t        *in;
        !           507:        dmodel_t        *out;
        !           508:        int                     i, j, count;
        !           509: 
        !           510:        in = (void *)(mod_base + l->fileofs);
        !           511:        if (l->filelen % sizeof(*in))
        !           512:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !           513:        count = l->filelen / sizeof(*in);
        !           514:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
        !           515: 
        !           516:        loadmodel->submodels = out;
        !           517:        loadmodel->numsubmodels = count;
        !           518: 
        !           519:        for ( i=0 ; i<count ; i++, in++, out++)
        !           520:        {
        !           521:                for (j=0 ; j<3 ; j++)
        !           522:                {       // spread the mins / maxs by a pixel
        !           523:                        out->mins[j] = LittleFloat (in->mins[j]) - 1;
        !           524:                        out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
        !           525:                        out->origin[j] = LittleFloat (in->origin[j]);
        !           526:                }
        !           527:                for (j=0 ; j<MAX_MAP_HULLS ; j++)
        !           528:                        out->headnode[j] = LittleLong (in->headnode[j]);
        !           529:                out->visleafs = LittleLong (in->visleafs);
        !           530:                out->firstface = LittleLong (in->firstface);
        !           531:                out->numfaces = LittleLong (in->numfaces);
        !           532:        }
        !           533: }
        !           534: 
        !           535: /*
        !           536: =================
        !           537: Mod_LoadEdges
        !           538: =================
        !           539: */
        !           540: void Mod_LoadEdges (lump_t *l)
        !           541: {
        !           542:        dedge_t *in;
        !           543:        medge_t *out;
        !           544:        int     i, count;
        !           545: 
        !           546:        in = (void *)(mod_base + l->fileofs);
        !           547:        if (l->filelen % sizeof(*in))
        !           548:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !           549:        count = l->filelen / sizeof(*in);
        !           550:        out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname);   
        !           551: 
        !           552:        loadmodel->edges = out;
        !           553:        loadmodel->numedges = count;
        !           554: 
        !           555:        for ( i=0 ; i<count ; i++, in++, out++)
        !           556:        {
        !           557:                out->v[0] = (unsigned short)LittleShort(in->v[0]);
        !           558:                out->v[1] = (unsigned short)LittleShort(in->v[1]);
        !           559:        }
        !           560: }
        !           561: 
        !           562: /*
        !           563: =================
        !           564: Mod_LoadTexinfo
        !           565: =================
        !           566: */
        !           567: void Mod_LoadTexinfo (lump_t *l)
        !           568: {
        !           569:        texinfo_t *in;
        !           570:        mtexinfo_t *out;
        !           571:        int     i, j, count;
        !           572:        int             miptex;
        !           573:        float   len1, len2;
        !           574: 
        !           575:        in = (void *)(mod_base + l->fileofs);
        !           576:        if (l->filelen % sizeof(*in))
        !           577:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !           578:        count = l->filelen / sizeof(*in);
        !           579:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
        !           580: 
        !           581:        loadmodel->texinfo = out;
        !           582:        loadmodel->numtexinfo = count;
        !           583: 
        !           584:        for ( i=0 ; i<count ; i++, in++, out++)
        !           585:        {
        !           586: #if 0
        !           587:                for (j=0 ; j<8 ; j++)
        !           588:                        out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
        !           589:                len1 = Length (in->vecs[0]);
        !           590:                len2 = Length (in->vecs[1]);
        !           591: #else
        !           592:                for (j=0 ; j<4 ; j++) {
        !           593:                        out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
        !           594:                        out->vecs[1][j] = LittleFloat (in->vecs[1][j]);
        !           595:                }
        !           596:                len1 = Length (out->vecs[0]);
        !           597:                len2 = Length (out->vecs[1]);
        !           598: #endif
        !           599:                if (len1 + len2 < 2 /*0.001*/)
        !           600:                        out->mipadjust = 1;
        !           601:                else
        !           602:                        out->mipadjust = 1 / floor( (len1+len2)/2 );
        !           603: 
        !           604:                miptex = LittleLong (in->miptex);
        !           605:                out->flags = LittleLong (in->flags);
        !           606:        
        !           607:                if (!loadmodel->textures)
        !           608:                {
        !           609:                        out->texture = &r_notexture_mip;        // checkerboard texture
        !           610:                        out->flags = 0;
        !           611:                }
        !           612:                else
        !           613:                {
        !           614:                        if (miptex >= loadmodel->numtextures)
        !           615:                                SV_Error ("miptex >= loadmodel->numtextures");
        !           616:                        out->texture = loadmodel->textures[miptex];
        !           617:                        if (!out->texture)
        !           618:                        {
        !           619:                                out->texture = &r_notexture_mip; // texture not found
        !           620:                                out->flags = 0;
        !           621:                        }
        !           622:                }
        !           623:        }
        !           624: }
        !           625: 
        !           626: /*
        !           627: ================
        !           628: CalcSurfaceExtents
        !           629: 
        !           630: Fills in s->texturemins[] and s->extents[]
        !           631: ================
        !           632: */
        !           633: void CalcSurfaceExtents (msurface_t *s)
        !           634: {
        !           635:        float   mins[2], maxs[2], val;
        !           636:        int             i,j, e;
        !           637:        mvertex_t       *v;
        !           638:        mtexinfo_t      *tex;
        !           639:        int             bmins[2], bmaxs[2];
        !           640: 
        !           641:        mins[0] = mins[1] = 999999;
        !           642:        maxs[0] = maxs[1] = -99999;
        !           643: 
        !           644:        tex = s->texinfo;
        !           645:        
        !           646:        for (i=0 ; i<s->numedges ; i++)
        !           647:        {
        !           648:                e = loadmodel->surfedges[s->firstedge+i];
        !           649:                if (e >= 0)
        !           650:                        v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
        !           651:                else
        !           652:                        v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
        !           653:                
        !           654:                for (j=0 ; j<2 ; j++)
        !           655:                {
        !           656:                        val = v->position[0] * tex->vecs[j][0] + 
        !           657:                                v->position[1] * tex->vecs[j][1] +
        !           658:                                v->position[2] * tex->vecs[j][2] +
        !           659:                                tex->vecs[j][3];
        !           660:                        if (val < mins[j])
        !           661:                                mins[j] = val;
        !           662:                        if (val > maxs[j])
        !           663:                                maxs[j] = val;
        !           664:                }
        !           665:        }
        !           666: 
        !           667:        for (i=0 ; i<2 ; i++)
        !           668:        {       
        !           669:                bmins[i] = floor(mins[i]/16);
        !           670:                bmaxs[i] = ceil(maxs[i]/16);
        !           671: 
        !           672:                s->texturemins[i] = bmins[i] * 16;
        !           673:                s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
        !           674:                if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 256)
        !           675:                        SV_Error ("Bad surface extents");
        !           676:        }
        !           677: }
        !           678: 
        !           679: 
        !           680: /*
        !           681: =================
        !           682: Mod_LoadFaces
        !           683: =================
        !           684: */
        !           685: void Mod_LoadFaces (lump_t *l)
        !           686: {
        !           687:        dface_t         *in;
        !           688:        msurface_t      *out;
        !           689:        int                     i, count, surfnum;
        !           690:        int                     planenum, side;
        !           691: 
        !           692:        in = (void *)(mod_base + l->fileofs);
        !           693:        if (l->filelen % sizeof(*in))
        !           694:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !           695:        count = l->filelen / sizeof(*in);
        !           696:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
        !           697: 
        !           698:        loadmodel->surfaces = out;
        !           699:        loadmodel->numsurfaces = count;
        !           700: 
        !           701:        for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
        !           702:        {
        !           703:                out->firstedge = LittleLong(in->firstedge);
        !           704:                out->numedges = LittleShort(in->numedges);              
        !           705:                out->flags = 0;
        !           706: 
        !           707:                planenum = LittleShort(in->planenum);
        !           708:                side = LittleShort(in->side);
        !           709:                if (side)
        !           710:                        out->flags |= SURF_PLANEBACK;                   
        !           711: 
        !           712:                out->plane = loadmodel->planes + planenum;
        !           713: 
        !           714:                out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
        !           715: 
        !           716:                CalcSurfaceExtents (out);
        !           717:                                
        !           718:        // lighting info
        !           719: 
        !           720:                for (i=0 ; i<MAXLIGHTMAPS ; i++)
        !           721:                        out->styles[i] = in->styles[i];
        !           722:                i = LittleLong(in->lightofs);
        !           723:                if (i == -1)
        !           724:                        out->samples = NULL;
        !           725:                else
        !           726:                        out->samples = loadmodel->lightdata + i;
        !           727:                
        !           728:        // set the drawing flags flag
        !           729:                
        !           730:                if (!Q_strncmp(out->texinfo->texture->name,"sky",3))    // sky
        !           731:                {
        !           732:                        out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED);
        !           733:                        continue;
        !           734:                }
        !           735:                
        !           736:                if (!Q_strncmp(out->texinfo->texture->name,"*",1))              // turbulent
        !           737:                {
        !           738:                        out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED);
        !           739:                        for (i=0 ; i<2 ; i++)
        !           740:                        {
        !           741:                                out->extents[i] = 16384;
        !           742:                                out->texturemins[i] = -8192;
        !           743:                        }
        !           744:                        continue;
        !           745:                }
        !           746:        }
        !           747: }
        !           748: 
        !           749: 
        !           750: /*
        !           751: =================
        !           752: Mod_SetParent
        !           753: =================
        !           754: */
        !           755: void Mod_SetParent (mnode_t *node, mnode_t *parent)
        !           756: {
        !           757:        node->parent = parent;
        !           758:        if (node->contents < 0)
        !           759:                return;
        !           760:        Mod_SetParent (node->children[0], node);
        !           761:        Mod_SetParent (node->children[1], node);
        !           762: }
        !           763: 
        !           764: /*
        !           765: =================
        !           766: Mod_LoadNodes
        !           767: =================
        !           768: */
        !           769: void Mod_LoadNodes (lump_t *l)
        !           770: {
        !           771:        int                     i, j, count, p;
        !           772:        dnode_t         *in;
        !           773:        mnode_t         *out;
        !           774: 
        !           775:        in = (void *)(mod_base + l->fileofs);
        !           776:        if (l->filelen % sizeof(*in))
        !           777:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !           778:        count = l->filelen / sizeof(*in);
        !           779:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
        !           780: 
        !           781:        loadmodel->nodes = out;
        !           782:        loadmodel->numnodes = count;
        !           783: 
        !           784:        for ( i=0 ; i<count ; i++, in++, out++)
        !           785:        {
        !           786:                for (j=0 ; j<3 ; j++)
        !           787:                {
        !           788:                        out->minmaxs[j] = LittleShort (in->mins[j]);
        !           789:                        out->minmaxs[3+j] = LittleShort (in->maxs[j]);
        !           790:                }
        !           791:        
        !           792:                p = LittleLong(in->planenum);
        !           793:                out->plane = loadmodel->planes + p;
        !           794: 
        !           795:                out->firstsurface = LittleShort (in->firstface);
        !           796:                out->numsurfaces = LittleShort (in->numfaces);
        !           797:                
        !           798:                for (j=0 ; j<2 ; j++)
        !           799:                {
        !           800:                        p = LittleShort (in->children[j]);
        !           801:                        if (p >= 0)
        !           802:                                out->children[j] = loadmodel->nodes + p;
        !           803:                        else
        !           804:                                out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
        !           805:                }
        !           806:        }
        !           807:        
        !           808:        Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
        !           809: }
        !           810: 
        !           811: /*
        !           812: =================
        !           813: Mod_LoadLeafs
        !           814: =================
        !           815: */
        !           816: void Mod_LoadLeafs (lump_t *l)
        !           817: {
        !           818:        dleaf_t         *in;
        !           819:        mleaf_t         *out;
        !           820:        int                     i, j, count, p;
        !           821: 
        !           822:        in = (void *)(mod_base + l->fileofs);
        !           823:        if (l->filelen % sizeof(*in))
        !           824:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !           825:        count = l->filelen / sizeof(*in);
        !           826:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
        !           827: 
        !           828:        loadmodel->leafs = out;
        !           829:        loadmodel->numleafs = count;
        !           830: 
        !           831:        for ( i=0 ; i<count ; i++, in++, out++)
        !           832:        {
        !           833:                for (j=0 ; j<3 ; j++)
        !           834:                {
        !           835:                        out->minmaxs[j] = LittleShort (in->mins[j]);
        !           836:                        out->minmaxs[3+j] = LittleShort (in->maxs[j]);
        !           837:                }
        !           838: 
        !           839:                p = LittleLong(in->contents);
        !           840:                out->contents = p;
        !           841: 
        !           842:                out->firstmarksurface = loadmodel->marksurfaces +
        !           843:                        LittleShort(in->firstmarksurface);
        !           844:                out->nummarksurfaces = LittleShort(in->nummarksurfaces);
        !           845:                
        !           846:                p = LittleLong(in->visofs);
        !           847:                if (p == -1)
        !           848:                        out->compressed_vis = NULL;
        !           849:                else
        !           850:                        out->compressed_vis = loadmodel->visdata + p;
        !           851:                out->efrags = NULL;
        !           852:                
        !           853:                for (j=0 ; j<4 ; j++)
        !           854:                        out->ambient_sound_level[j] = in->ambient_level[j];
        !           855:        }       
        !           856: }
        !           857: 
        !           858: /*
        !           859: =================
        !           860: Mod_LoadClipnodes
        !           861: =================
        !           862: */
        !           863: void Mod_LoadClipnodes (lump_t *l)
        !           864: {
        !           865:        dclipnode_t *in, *out;
        !           866:        int                     i, count;
        !           867:        hull_t          *hull;
        !           868: 
        !           869:        in = (void *)(mod_base + l->fileofs);
        !           870:        if (l->filelen % sizeof(*in))
        !           871:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !           872:        count = l->filelen / sizeof(*in);
        !           873:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
        !           874: 
        !           875:        loadmodel->clipnodes = out;
        !           876:        loadmodel->numclipnodes = count;
        !           877: 
        !           878:        hull = &loadmodel->hulls[1];
        !           879:        hull->clipnodes = out;
        !           880:        hull->firstclipnode = 0;
        !           881:        hull->lastclipnode = count-1;
        !           882:        hull->planes = loadmodel->planes;
        !           883:        hull->clip_mins[0] = -16;
        !           884:        hull->clip_mins[1] = -16;
        !           885:        hull->clip_mins[2] = -24;
        !           886:        hull->clip_maxs[0] = 16;
        !           887:        hull->clip_maxs[1] = 16;
        !           888:        hull->clip_maxs[2] = 32;
        !           889: 
        !           890:        hull = &loadmodel->hulls[2];
        !           891:        hull->clipnodes = out;
        !           892:        hull->firstclipnode = 0;
        !           893:        hull->lastclipnode = count-1;
        !           894:        hull->planes = loadmodel->planes;
        !           895:        hull->clip_mins[0] = -32;
        !           896:        hull->clip_mins[1] = -32;
        !           897:        hull->clip_mins[2] = -24;
        !           898:        hull->clip_maxs[0] = 32;
        !           899:        hull->clip_maxs[1] = 32;
        !           900:        hull->clip_maxs[2] = 64;
        !           901: 
        !           902:        for (i=0 ; i<count ; i++, out++, in++)
        !           903:        {
        !           904:                out->planenum = LittleLong(in->planenum);
        !           905:                out->children[0] = LittleShort(in->children[0]);
        !           906:                out->children[1] = LittleShort(in->children[1]);
        !           907:        }
        !           908: }
        !           909: 
        !           910: /*
        !           911: =================
        !           912: Mod_MakeHull0
        !           913: 
        !           914: Deplicate the drawing hull structure as a clipping hull
        !           915: =================
        !           916: */
        !           917: void Mod_MakeHull0 (void)
        !           918: {
        !           919:        mnode_t         *in, *child;
        !           920:        dclipnode_t *out;
        !           921:        int                     i, j, count;
        !           922:        hull_t          *hull;
        !           923:        
        !           924:        hull = &loadmodel->hulls[0];    
        !           925:        
        !           926:        in = loadmodel->nodes;
        !           927:        count = loadmodel->numnodes;
        !           928:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
        !           929: 
        !           930:        hull->clipnodes = out;
        !           931:        hull->firstclipnode = 0;
        !           932:        hull->lastclipnode = count-1;
        !           933:        hull->planes = loadmodel->planes;
        !           934: 
        !           935:        for (i=0 ; i<count ; i++, out++, in++)
        !           936:        {
        !           937:                out->planenum = in->plane - loadmodel->planes;
        !           938:                for (j=0 ; j<2 ; j++)
        !           939:                {
        !           940:                        child = in->children[j];
        !           941:                        if (child->contents < 0)
        !           942:                                out->children[j] = child->contents;
        !           943:                        else
        !           944:                                out->children[j] = child - loadmodel->nodes;
        !           945:                }
        !           946:        }
        !           947: }
        !           948: 
        !           949: /*
        !           950: =================
        !           951: Mod_LoadMarksurfaces
        !           952: =================
        !           953: */
        !           954: void Mod_LoadMarksurfaces (lump_t *l)
        !           955: {      
        !           956:        int             i, j, count;
        !           957:        short           *in;
        !           958:        msurface_t **out;
        !           959:        
        !           960:        in = (void *)(mod_base + l->fileofs);
        !           961:        if (l->filelen % sizeof(*in))
        !           962:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !           963:        count = l->filelen / sizeof(*in);
        !           964:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
        !           965: 
        !           966:        loadmodel->marksurfaces = out;
        !           967:        loadmodel->nummarksurfaces = count;
        !           968: 
        !           969:        for ( i=0 ; i<count ; i++)
        !           970:        {
        !           971:                j = LittleShort(in[i]);
        !           972:                if (j >= loadmodel->numsurfaces)
        !           973:                        SV_Error ("Mod_ParseMarksurfaces: bad surface number");
        !           974:                out[i] = loadmodel->surfaces + j;
        !           975:        }
        !           976: }
        !           977: 
        !           978: /*
        !           979: =================
        !           980: Mod_LoadSurfedges
        !           981: =================
        !           982: */
        !           983: void Mod_LoadSurfedges (lump_t *l)
        !           984: {      
        !           985:        int             i, count;
        !           986:        int             *in, *out;
        !           987:        
        !           988:        in = (void *)(mod_base + l->fileofs);
        !           989:        if (l->filelen % sizeof(*in))
        !           990:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !           991:        count = l->filelen / sizeof(*in);
        !           992:        out = Hunk_AllocName ( count*sizeof(*out), loadname);   
        !           993: 
        !           994:        loadmodel->surfedges = out;
        !           995:        loadmodel->numsurfedges = count;
        !           996: 
        !           997:        for ( i=0 ; i<count ; i++)
        !           998:                out[i] = LittleLong (in[i]);
        !           999: }
        !          1000: 
        !          1001: /*
        !          1002: =================
        !          1003: Mod_LoadPlanes
        !          1004: =================
        !          1005: */
        !          1006: void Mod_LoadPlanes (lump_t *l)
        !          1007: {
        !          1008:        int                     i, j;
        !          1009:        mplane_t        *out;
        !          1010:        dplane_t        *in;
        !          1011:        int                     count;
        !          1012:        int                     bits;
        !          1013:        
        !          1014:        in = (void *)(mod_base + l->fileofs);
        !          1015:        if (l->filelen % sizeof(*in))
        !          1016:                SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
        !          1017:        count = l->filelen / sizeof(*in);
        !          1018:        out = Hunk_AllocName ( count*2*sizeof(*out), loadname); 
        !          1019:        
        !          1020:        loadmodel->planes = out;
        !          1021:        loadmodel->numplanes = count;
        !          1022: 
        !          1023:        for ( i=0 ; i<count ; i++, in++, out++)
        !          1024:        {
        !          1025:                bits = 0;
        !          1026:                for (j=0 ; j<3 ; j++)
        !          1027:                {
        !          1028:                        out->normal[j] = LittleFloat (in->normal[j]);
        !          1029:                        if (out->normal[j] < 0)
        !          1030:                                bits |= 1<<j;
        !          1031:                }
        !          1032: 
        !          1033:                out->dist = LittleFloat (in->dist);
        !          1034:                out->type = LittleLong (in->type);
        !          1035:                out->signbits = bits;
        !          1036:        }
        !          1037: }
        !          1038: 
        !          1039: 
        !          1040: /*
        !          1041: =================
        !          1042: Mod_LoadBrushModel
        !          1043: =================
        !          1044: */
        !          1045: void Mod_LoadBrushModel (model_t *mod, void *buffer)
        !          1046: {
        !          1047:        int                     i, j;
        !          1048:        dheader_t       *header;
        !          1049:        dmodel_t        *bm;
        !          1050:        
        !          1051:        loadmodel->type = mod_brush;
        !          1052:        
        !          1053:        header = (dheader_t *)buffer;
        !          1054: 
        !          1055:        i = LittleLong (header->version);
        !          1056:        if (i != BSPVERSION)
        !          1057:                SV_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
        !          1058: 
        !          1059: // swap all the lumps
        !          1060:        mod_base = (byte *)header;
        !          1061: 
        !          1062:        for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
        !          1063:                ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
        !          1064: 
        !          1065: // load into heap
        !          1066: 
        !          1067:        mod->checksum = 0;
        !          1068:        mod->checksum2 = 0;
        !          1069: 
        !          1070:        // checksum all of the map, except for entities
        !          1071:        for (i = 0; i < HEADER_LUMPS; i++) {
        !          1072:                if (i == LUMP_ENTITIES)
        !          1073:                        continue;
        !          1074:                mod->checksum ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, 
        !          1075:                        header->lumps[i].filelen));
        !          1076: 
        !          1077:                if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES)
        !          1078:                        continue;
        !          1079:                mod->checksum2 ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, 
        !          1080:                        header->lumps[i].filelen));
        !          1081:        }
        !          1082: 
        !          1083:        Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
        !          1084:        Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
        !          1085:        Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
        !          1086:        Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
        !          1087:        Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
        !          1088:        Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
        !          1089:        Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
        !          1090:        Mod_LoadFaces (&header->lumps[LUMP_FACES]);
        !          1091:        Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
        !          1092:        Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
        !          1093:        Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
        !          1094:        Mod_LoadNodes (&header->lumps[LUMP_NODES]);
        !          1095:        Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]);
        !          1096:        Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]);
        !          1097:        Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
        !          1098: 
        !          1099:        Mod_MakeHull0 ();
        !          1100:        
        !          1101:        mod->numframes = 2;             // regular and alternate animation
        !          1102:        
        !          1103: //
        !          1104: // set up the submodels (FIXME: this is confusing)
        !          1105: //
        !          1106:        for (i=0 ; i<mod->numsubmodels ; i++)
        !          1107:        {
        !          1108:                bm = &mod->submodels[i];
        !          1109: 
        !          1110:                mod->hulls[0].firstclipnode = bm->headnode[0];
        !          1111:                for (j=1 ; j<MAX_MAP_HULLS ; j++)
        !          1112:                {
        !          1113:                        mod->hulls[j].firstclipnode = bm->headnode[j];
        !          1114:                        mod->hulls[j].lastclipnode = mod->numclipnodes-1;
        !          1115:                }
        !          1116:                
        !          1117:                mod->firstmodelsurface = bm->firstface;
        !          1118:                mod->nummodelsurfaces = bm->numfaces;
        !          1119:                
        !          1120:                VectorCopy (bm->maxs, mod->maxs);
        !          1121:                VectorCopy (bm->mins, mod->mins);
        !          1122:        
        !          1123:                mod->numleafs = bm->visleafs;
        !          1124: 
        !          1125:                if (i < mod->numsubmodels-1)
        !          1126:                {       // duplicate the basic information
        !          1127:                        char    name[10];
        !          1128: 
        !          1129:                        sprintf (name, "*%i", i+1);
        !          1130:                        loadmodel = Mod_FindName (name);
        !          1131:                        *loadmodel = *mod;
        !          1132:                        strcpy (loadmodel->name, name);
        !          1133:                        mod = loadmodel;
        !          1134:                }
        !          1135:        }
        !          1136: }
        !          1137: 

unix.superglobalmegacorp.com

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