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