2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
20 // models.c -- model loading and caching
22 // models are the only shared resource between a client and server running
23 // on the same machine.
29 char loadname
[32]; // for hunk tags
31 void Mod_LoadSpriteModel (model_t
*mod
, void *buffer
);
32 void Mod_LoadBrushModel (model_t
*mod
, void *buffer
);
33 void Mod_LoadAliasModel (model_t
*mod
, void *buffer
);
34 model_t
*Mod_LoadModel (model_t
*mod
, qboolean crash
);
36 byte mod_novis
[MAX_MAP_LEAFS
/8];
38 #define MAX_MOD_KNOWN 256
39 model_t mod_known
[MAX_MOD_KNOWN
];
42 // values for model_t's needload
44 #define NL_NEEDS_LOADED 1
45 #define NL_UNREFERENCED 2
54 memset (mod_novis
, 0xff, sizeof(mod_novis
));
61 Caches the data if needed
64 void *Mod_Extradata (model_t
*mod
)
68 r
= Cache_Check (&mod
->cache
);
72 Mod_LoadModel (mod
, true);
75 Sys_Error ("Mod_Extradata: caching failed");
76 return mod
->cache
.data
;
84 mleaf_t
*Mod_PointInLeaf (vec3_t p
, model_t
*model
)
90 if (!model
|| !model
->nodes
)
91 Sys_Error ("Mod_PointInLeaf: bad model");
96 if (node
->contents
< 0)
97 return (mleaf_t
*)node
;
99 d
= DotProduct (p
,plane
->normal
) - plane
->dist
;
101 node
= node
->children
[0];
103 node
= node
->children
[1];
106 return NULL
; // never reached
115 byte
*Mod_DecompressVis (byte
*in
, model_t
*model
)
117 static byte decompressed
[MAX_MAP_LEAFS
/8];
122 row
= (model
->numleafs
+7)>>3;
126 { // no vis info, so make all visible
150 } while (out
- decompressed
< row
);
155 byte
*Mod_LeafPVS (mleaf_t
*leaf
, model_t
*model
)
157 if (leaf
== model
->leafs
)
159 return Mod_DecompressVis (leaf
->compressed_vis
, model
);
167 void Mod_ClearAll (void)
173 for (i
=0 , mod
=mod_known
; i
<mod_numknown
; i
++, mod
++) {
174 mod
->needload
= NL_UNREFERENCED
;
175 //FIX FOR CACHE_ALLOC ERRORS:
176 if (mod
->type
== mod_sprite
) mod
->cache
.data
= NULL
;
186 model_t
*Mod_FindName (char *name
)
190 model_t
*avail
= NULL
;
193 Sys_Error ("Mod_ForName: NULL name");
196 // search the currently loaded models
198 for (i
=0 , mod
=mod_known
; i
<mod_numknown
; i
++, mod
++)
200 if (!strcmp (mod
->name
, name
) )
202 if (mod
->needload
== NL_UNREFERENCED
)
203 if (!avail
|| mod
->type
!= mod_alias
)
207 if (i
== mod_numknown
)
209 if (mod_numknown
== MAX_MOD_KNOWN
)
214 if (mod
->type
== mod_alias
)
215 if (Cache_Check (&mod
->cache
))
216 Cache_Free (&mod
->cache
);
219 Sys_Error ("mod_numknown == MAX_MOD_KNOWN");
223 strcpy (mod
->name
, name
);
224 mod
->needload
= NL_NEEDS_LOADED
;
236 void Mod_TouchModel (char *name
)
240 mod
= Mod_FindName (name
);
242 if (mod
->needload
== NL_PRESENT
)
244 if (mod
->type
== mod_alias
)
245 Cache_Check (&mod
->cache
);
253 Loads a model into the cache
256 model_t
*Mod_LoadModel (model_t
*mod
, qboolean crash
)
259 byte stackbuf
[1024]; // avoid dirtying the cache heap
261 if (mod
->type
== mod_alias
)
263 if (Cache_Check (&mod
->cache
))
265 mod
->needload
= NL_PRESENT
;
271 if (mod
->needload
== NL_PRESENT
)
276 // because the world is so huge, load it one piece at a time
282 buf
= (unsigned *)COM_LoadStackFile (mod
->name
, stackbuf
, sizeof(stackbuf
));
286 Sys_Error ("Mod_NumForName: %s not found", mod
->name
);
291 // allocate a new model
293 COM_FileBase (mod
->name
, loadname
);
301 // call the apropriate loader
302 mod
->needload
= NL_PRESENT
;
304 switch (LittleLong(*(unsigned *)buf
))
307 Mod_LoadAliasModel (mod
, buf
);
311 Mod_LoadSpriteModel (mod
, buf
);
315 Mod_LoadBrushModel (mod
, buf
);
326 Loads in a model for the given name
329 model_t
*Mod_ForName (char *name
, qboolean crash
)
333 mod
= Mod_FindName (name
);
335 return Mod_LoadModel (mod
, crash
);
340 ===============================================================================
344 ===============================================================================
355 void Mod_LoadTextures (lump_t
*l
)
357 int i
, j
, pixels
, num
, max
, altmax
;
360 texture_t
*anims
[10];
361 texture_t
*altanims
[10];
366 loadmodel
->textures
= NULL
;
369 m
= (dmiptexlump_t
*)(mod_base
+ l
->fileofs
);
371 m
->nummiptex
= LittleLong (m
->nummiptex
);
373 loadmodel
->numtextures
= m
->nummiptex
;
374 loadmodel
->textures
= Hunk_AllocName (m
->nummiptex
* sizeof(*loadmodel
->textures
) , loadname
);
376 for (i
=0 ; i
<m
->nummiptex
; i
++)
378 m
->dataofs
[i
] = LittleLong(m
->dataofs
[i
]);
379 if (m
->dataofs
[i
] == -1)
381 mt
= (miptex_t
*)((byte
*)m
+ m
->dataofs
[i
]);
382 mt
->width
= LittleLong (mt
->width
);
383 mt
->height
= LittleLong (mt
->height
);
384 for (j
=0 ; j
<MIPLEVELS
; j
++)
385 mt
->offsets
[j
] = LittleLong (mt
->offsets
[j
]);
387 if ( (mt
->width
& 15) || (mt
->height
& 15) )
388 Sys_Error ("Texture %s is not 16 aligned", mt
->name
);
389 pixels
= mt
->width
*mt
->height
/64*85;
390 tx
= Hunk_AllocName (sizeof(texture_t
) +pixels
, loadname
);
391 loadmodel
->textures
[i
] = tx
;
393 memcpy (tx
->name
, mt
->name
, sizeof(tx
->name
));
394 tx
->width
= mt
->width
;
395 tx
->height
= mt
->height
;
396 for (j
=0 ; j
<MIPLEVELS
; j
++)
397 tx
->offsets
[j
] = mt
->offsets
[j
] + sizeof(texture_t
) - sizeof(miptex_t
);
398 // the pixels immediately follow the structures
399 memcpy ( tx
+1, mt
+1, pixels
);
401 if (!Q_strncmp(mt
->name
,"sky",3))
406 // sequence the animations
408 for (i
=0 ; i
<m
->nummiptex
; i
++)
410 tx
= loadmodel
->textures
[i
];
411 if (!tx
|| tx
->name
[0] != '+')
414 continue; // allready sequenced
416 // find the number of frames in the animation
417 memset (anims
, 0, sizeof(anims
));
418 memset (altanims
, 0, sizeof(altanims
));
422 if (max
>= 'a' && max
<= 'z')
424 if (max
>= '0' && max
<= '9')
431 else if (max
>= 'A' && max
<= 'J')
435 altanims
[altmax
] = tx
;
439 Sys_Error ("Bad animating texture %s", tx
->name
);
441 for (j
=i
+1 ; j
<m
->nummiptex
; j
++)
443 tx2
= loadmodel
->textures
[j
];
444 if (!tx2
|| tx2
->name
[0] != '+')
446 if (strcmp (tx2
->name
+2, tx
->name
+2))
450 if (num
>= 'a' && num
<= 'z')
452 if (num
>= '0' && num
<= '9')
459 else if (num
>= 'A' && num
<= 'J')
467 Sys_Error ("Bad animating texture %s", tx
->name
);
471 // link them all together
472 for (j
=0 ; j
<max
; j
++)
476 Sys_Error ("Missing frame %i of %s",j
, tx
->name
);
477 tx2
->anim_total
= max
* ANIM_CYCLE
;
478 tx2
->anim_min
= j
* ANIM_CYCLE
;
479 tx2
->anim_max
= (j
+1) * ANIM_CYCLE
;
480 tx2
->anim_next
= anims
[ (j
+1)%max
];
482 tx2
->alternate_anims
= altanims
[0];
484 for (j
=0 ; j
<altmax
; j
++)
488 Sys_Error ("Missing frame %i of %s",j
, tx
->name
);
489 tx2
->anim_total
= altmax
* ANIM_CYCLE
;
490 tx2
->anim_min
= j
* ANIM_CYCLE
;
491 tx2
->anim_max
= (j
+1) * ANIM_CYCLE
;
492 tx2
->anim_next
= altanims
[ (j
+1)%altmax
];
494 tx2
->alternate_anims
= anims
[0];
504 void Mod_LoadLighting (lump_t
*l
)
508 loadmodel
->lightdata
= NULL
;
511 loadmodel
->lightdata
= Hunk_AllocName ( l
->filelen
, loadname
);
512 memcpy (loadmodel
->lightdata
, mod_base
+ l
->fileofs
, l
->filelen
);
521 void Mod_LoadVisibility (lump_t
*l
)
525 loadmodel
->visdata
= NULL
;
528 loadmodel
->visdata
= Hunk_AllocName ( l
->filelen
, loadname
);
529 memcpy (loadmodel
->visdata
, mod_base
+ l
->fileofs
, l
->filelen
);
538 void Mod_LoadEntities (lump_t
*l
)
542 loadmodel
->entities
= NULL
;
545 loadmodel
->entities
= Hunk_AllocName ( l
->filelen
, loadname
);
546 memcpy (loadmodel
->entities
, mod_base
+ l
->fileofs
, l
->filelen
);
555 void Mod_LoadVertexes (lump_t
*l
)
561 in
= (void *)(mod_base
+ l
->fileofs
);
562 if (l
->filelen
% sizeof(*in
))
563 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
564 count
= l
->filelen
/ sizeof(*in
);
565 out
= Hunk_AllocName ( count
*sizeof(*out
), loadname
);
567 loadmodel
->vertexes
= out
;
568 loadmodel
->numvertexes
= count
;
570 for ( i
=0 ; i
<count
; i
++, in
++, out
++)
572 out
->position
[0] = LittleFloat (in
->point
[0]);
573 out
->position
[1] = LittleFloat (in
->point
[1]);
574 out
->position
[2] = LittleFloat (in
->point
[2]);
583 void Mod_LoadSubmodels (lump_t
*l
)
589 in
= (void *)(mod_base
+ l
->fileofs
);
590 if (l
->filelen
% sizeof(*in
))
591 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
592 count
= l
->filelen
/ sizeof(*in
);
593 out
= Hunk_AllocName ( count
*sizeof(*out
), loadname
);
595 loadmodel
->submodels
= out
;
596 loadmodel
->numsubmodels
= count
;
598 for ( i
=0 ; i
<count
; i
++, in
++, out
++)
600 for (j
=0 ; j
<3 ; j
++)
601 { // spread the mins / maxs by a pixel
602 out
->mins
[j
] = LittleFloat (in
->mins
[j
]) - 1;
603 out
->maxs
[j
] = LittleFloat (in
->maxs
[j
]) + 1;
604 out
->origin
[j
] = LittleFloat (in
->origin
[j
]);
606 for (j
=0 ; j
<MAX_MAP_HULLS
; j
++)
607 out
->headnode
[j
] = LittleLong (in
->headnode
[j
]);
608 out
->visleafs
= LittleLong (in
->visleafs
);
609 out
->firstface
= LittleLong (in
->firstface
);
610 out
->numfaces
= LittleLong (in
->numfaces
);
619 void Mod_LoadEdges (lump_t
*l
)
625 in
= (void *)(mod_base
+ l
->fileofs
);
626 if (l
->filelen
% sizeof(*in
))
627 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
628 count
= l
->filelen
/ sizeof(*in
);
629 out
= Hunk_AllocName ( (count
+ 1) * sizeof(*out
), loadname
);
631 loadmodel
->edges
= out
;
632 loadmodel
->numedges
= count
;
634 for ( i
=0 ; i
<count
; i
++, in
++, out
++)
636 out
->v
[0] = (unsigned short)LittleShort(in
->v
[0]);
637 out
->v
[1] = (unsigned short)LittleShort(in
->v
[1]);
646 void Mod_LoadTexinfo (lump_t
*l
)
654 in
= (void *)(mod_base
+ l
->fileofs
);
655 if (l
->filelen
% sizeof(*in
))
656 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
657 count
= l
->filelen
/ sizeof(*in
);
658 out
= Hunk_AllocName ( count
*sizeof(*out
), loadname
);
660 loadmodel
->texinfo
= out
;
661 loadmodel
->numtexinfo
= count
;
663 for ( i
=0 ; i
<count
; i
++, in
++, out
++)
665 for (j
=0 ; j
<8 ; j
++)
666 out
->vecs
[0][j
] = LittleFloat (in
->vecs
[0][j
]);
667 len1
= Length (out
->vecs
[0]);
668 len2
= Length (out
->vecs
[1]);
669 len1
= (len1
+ len2
)/2;
672 else if (len1
< 0.49)
674 else if (len1
< 0.99)
679 if (len1
+ len2
< 0.001)
680 out
->mipadjust
= 1; // don't crash
682 out
->mipadjust
= 1 / floor( (len1
+len2
)/2 + 0.1 );
685 miptex
= LittleLong (in
->miptex
);
686 out
->flags
= LittleLong (in
->flags
);
688 if (!loadmodel
->textures
)
690 out
->texture
= r_notexture_mip
; // checkerboard texture
695 if (miptex
>= loadmodel
->numtextures
)
696 Sys_Error ("miptex >= loadmodel->numtextures");
697 out
->texture
= loadmodel
->textures
[miptex
];
700 out
->texture
= r_notexture_mip
; // texture not found
711 Fills in s->texturemins[] and s->extents[]
714 void CalcSurfaceExtents (msurface_t
*s
)
716 float mins
[2], maxs
[2], val
;
720 int bmins
[2], bmaxs
[2];
722 mins
[0] = mins
[1] = 999999;
723 maxs
[0] = maxs
[1] = -99999;
727 for (i
=0 ; i
<s
->numedges
; i
++)
729 e
= loadmodel
->surfedges
[s
->firstedge
+i
];
731 v
= &loadmodel
->vertexes
[loadmodel
->edges
[e
].v
[0]];
733 v
= &loadmodel
->vertexes
[loadmodel
->edges
[-e
].v
[1]];
735 for (j
=0 ; j
<2 ; j
++)
737 val
= v
->position
[0] * tex
->vecs
[j
][0] +
738 v
->position
[1] * tex
->vecs
[j
][1] +
739 v
->position
[2] * tex
->vecs
[j
][2] +
748 for (i
=0 ; i
<2 ; i
++)
750 bmins
[i
] = floor(mins
[i
]/16);
751 bmaxs
[i
] = ceil(maxs
[i
]/16);
753 s
->texturemins
[i
] = bmins
[i
] * 16;
754 s
->extents
[i
] = (bmaxs
[i
] - bmins
[i
]) * 16;
755 if ( !(tex
->flags
& TEX_SPECIAL
) && s
->extents
[i
] > 256)
756 Sys_Error ("Bad surface extents");
766 void Mod_LoadFaces (lump_t
*l
)
770 int i
, count
, surfnum
;
773 in
= (void *)(mod_base
+ l
->fileofs
);
774 if (l
->filelen
% sizeof(*in
))
775 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
776 count
= l
->filelen
/ sizeof(*in
);
777 out
= Hunk_AllocName ( count
*sizeof(*out
), loadname
);
779 loadmodel
->surfaces
= out
;
780 loadmodel
->numsurfaces
= count
;
782 for ( surfnum
=0 ; surfnum
<count
; surfnum
++, in
++, out
++)
784 out
->firstedge
= LittleLong(in
->firstedge
);
785 out
->numedges
= LittleShort(in
->numedges
);
788 planenum
= LittleShort(in
->planenum
);
789 side
= LittleShort(in
->side
);
791 out
->flags
|= SURF_PLANEBACK
;
793 out
->plane
= loadmodel
->planes
+ planenum
;
795 out
->texinfo
= loadmodel
->texinfo
+ LittleShort (in
->texinfo
);
797 CalcSurfaceExtents (out
);
801 for (i
=0 ; i
<MAXLIGHTMAPS
; i
++)
802 out
->styles
[i
] = in
->styles
[i
];
803 i
= LittleLong(in
->lightofs
);
807 out
->samples
= loadmodel
->lightdata
+ i
;
809 // set the drawing flags flag
811 if (!Q_strncmp(out
->texinfo
->texture
->name
,"sky",3)) // sky
813 out
->flags
|= (SURF_DRAWSKY
| SURF_DRAWTILED
);
817 if (!Q_strncmp(out
->texinfo
->texture
->name
,"*",1)) // turbulent
819 out
->flags
|= (SURF_DRAWTURB
| SURF_DRAWTILED
);
820 for (i
=0 ; i
<2 ; i
++)
822 out
->extents
[i
] = 16384;
823 out
->texturemins
[i
] = -8192;
836 void Mod_SetParent (mnode_t
*node
, mnode_t
*parent
)
838 node
->parent
= parent
;
839 if (node
->contents
< 0)
841 Mod_SetParent (node
->children
[0], node
);
842 Mod_SetParent (node
->children
[1], node
);
850 void Mod_LoadNodes (lump_t
*l
)
856 in
= (void *)(mod_base
+ l
->fileofs
);
857 if (l
->filelen
% sizeof(*in
))
858 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
859 count
= l
->filelen
/ sizeof(*in
);
860 out
= Hunk_AllocName ( count
*sizeof(*out
), loadname
);
862 loadmodel
->nodes
= out
;
863 loadmodel
->numnodes
= count
;
865 for ( i
=0 ; i
<count
; i
++, in
++, out
++)
867 for (j
=0 ; j
<3 ; j
++)
869 out
->minmaxs
[j
] = LittleShort (in
->mins
[j
]);
870 out
->minmaxs
[3+j
] = LittleShort (in
->maxs
[j
]);
873 p
= LittleLong(in
->planenum
);
874 out
->plane
= loadmodel
->planes
+ p
;
876 out
->firstsurface
= LittleShort (in
->firstface
);
877 out
->numsurfaces
= LittleShort (in
->numfaces
);
879 for (j
=0 ; j
<2 ; j
++)
881 p
= LittleShort (in
->children
[j
]);
883 out
->children
[j
] = loadmodel
->nodes
+ p
;
885 out
->children
[j
] = (mnode_t
*)(loadmodel
->leafs
+ (-1 - p
));
889 Mod_SetParent (loadmodel
->nodes
, NULL
); // sets nodes and leafs
897 void Mod_LoadLeafs (lump_t
*l
)
903 in
= (void *)(mod_base
+ l
->fileofs
);
904 if (l
->filelen
% sizeof(*in
))
905 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
906 count
= l
->filelen
/ sizeof(*in
);
907 out
= Hunk_AllocName ( count
*sizeof(*out
), loadname
);
909 loadmodel
->leafs
= out
;
910 loadmodel
->numleafs
= count
;
912 for ( i
=0 ; i
<count
; i
++, in
++, out
++)
914 for (j
=0 ; j
<3 ; j
++)
916 out
->minmaxs
[j
] = LittleShort (in
->mins
[j
]);
917 out
->minmaxs
[3+j
] = LittleShort (in
->maxs
[j
]);
920 p
= LittleLong(in
->contents
);
923 out
->firstmarksurface
= loadmodel
->marksurfaces
+
924 LittleShort(in
->firstmarksurface
);
925 out
->nummarksurfaces
= LittleShort(in
->nummarksurfaces
);
927 p
= LittleLong(in
->visofs
);
929 out
->compressed_vis
= NULL
;
931 out
->compressed_vis
= loadmodel
->visdata
+ p
;
934 for (j
=0 ; j
<4 ; j
++)
935 out
->ambient_sound_level
[j
] = in
->ambient_level
[j
];
944 void Mod_LoadClipnodes (lump_t
*l
)
946 dclipnode_t
*in
, *out
;
950 in
= (void *)(mod_base
+ l
->fileofs
);
951 if (l
->filelen
% sizeof(*in
))
952 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
953 count
= l
->filelen
/ sizeof(*in
);
954 out
= Hunk_AllocName ( count
*sizeof(*out
), loadname
);
956 loadmodel
->clipnodes
= out
;
957 loadmodel
->numclipnodes
= count
;
959 hull
= &loadmodel
->hulls
[1];
960 hull
->clipnodes
= out
;
961 hull
->firstclipnode
= 0;
962 hull
->lastclipnode
= count
-1;
963 hull
->planes
= loadmodel
->planes
;
964 hull
->clip_mins
[0] = -16;
965 hull
->clip_mins
[1] = -16;
966 hull
->clip_mins
[2] = -24;
967 hull
->clip_maxs
[0] = 16;
968 hull
->clip_maxs
[1] = 16;
969 hull
->clip_maxs
[2] = 32;
971 hull
= &loadmodel
->hulls
[2];
972 hull
->clipnodes
= out
;
973 hull
->firstclipnode
= 0;
974 hull
->lastclipnode
= count
-1;
975 hull
->planes
= loadmodel
->planes
;
976 hull
->clip_mins
[0] = -32;
977 hull
->clip_mins
[1] = -32;
978 hull
->clip_mins
[2] = -24;
979 hull
->clip_maxs
[0] = 32;
980 hull
->clip_maxs
[1] = 32;
981 hull
->clip_maxs
[2] = 64;
983 for (i
=0 ; i
<count
; i
++, out
++, in
++)
985 out
->planenum
= LittleLong(in
->planenum
);
986 out
->children
[0] = LittleShort(in
->children
[0]);
987 out
->children
[1] = LittleShort(in
->children
[1]);
995 Deplicate the drawing hull structure as a clipping hull
998 void Mod_MakeHull0 (void)
1000 mnode_t
*in
, *child
;
1005 hull
= &loadmodel
->hulls
[0];
1007 in
= loadmodel
->nodes
;
1008 count
= loadmodel
->numnodes
;
1009 out
= Hunk_AllocName ( count
*sizeof(*out
), loadname
);
1011 hull
->clipnodes
= out
;
1012 hull
->firstclipnode
= 0;
1013 hull
->lastclipnode
= count
-1;
1014 hull
->planes
= loadmodel
->planes
;
1016 for (i
=0 ; i
<count
; i
++, out
++, in
++)
1018 out
->planenum
= in
->plane
- loadmodel
->planes
;
1019 for (j
=0 ; j
<2 ; j
++)
1021 child
= in
->children
[j
];
1022 if (child
->contents
< 0)
1023 out
->children
[j
] = child
->contents
;
1025 out
->children
[j
] = child
- loadmodel
->nodes
;
1032 Mod_LoadMarksurfaces
1035 void Mod_LoadMarksurfaces (lump_t
*l
)
1041 in
= (void *)(mod_base
+ l
->fileofs
);
1042 if (l
->filelen
% sizeof(*in
))
1043 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
1044 count
= l
->filelen
/ sizeof(*in
);
1045 out
= Hunk_AllocName ( count
*sizeof(*out
), loadname
);
1047 loadmodel
->marksurfaces
= out
;
1048 loadmodel
->nummarksurfaces
= count
;
1050 for ( i
=0 ; i
<count
; i
++)
1052 j
= LittleShort(in
[i
]);
1053 if (j
>= loadmodel
->numsurfaces
)
1054 Sys_Error ("Mod_ParseMarksurfaces: bad surface number");
1055 out
[i
] = loadmodel
->surfaces
+ j
;
1064 void Mod_LoadSurfedges (lump_t
*l
)
1069 in
= (void *)(mod_base
+ l
->fileofs
);
1070 if (l
->filelen
% sizeof(*in
))
1071 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
1072 count
= l
->filelen
/ sizeof(*in
);
1073 out
= Hunk_AllocName ( count
*sizeof(*out
), loadname
);
1075 loadmodel
->surfedges
= out
;
1076 loadmodel
->numsurfedges
= count
;
1078 for ( i
=0 ; i
<count
; i
++)
1079 out
[i
] = LittleLong (in
[i
]);
1087 void Mod_LoadPlanes (lump_t
*l
)
1095 in
= (void *)(mod_base
+ l
->fileofs
);
1096 if (l
->filelen
% sizeof(*in
))
1097 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel
->name
);
1098 count
= l
->filelen
/ sizeof(*in
);
1099 out
= Hunk_AllocName ( count
*2*sizeof(*out
), loadname
);
1101 loadmodel
->planes
= out
;
1102 loadmodel
->numplanes
= count
;
1104 for ( i
=0 ; i
<count
; i
++, in
++, out
++)
1107 for (j
=0 ; j
<3 ; j
++)
1109 out
->normal
[j
] = LittleFloat (in
->normal
[j
]);
1110 if (out
->normal
[j
] < 0)
1114 out
->dist
= LittleFloat (in
->dist
);
1115 out
->type
= LittleLong (in
->type
);
1116 out
->signbits
= bits
;
1125 float RadiusFromBounds (vec3_t mins
, vec3_t maxs
)
1130 for (i
=0 ; i
<3 ; i
++)
1132 corner
[i
] = fabs(mins
[i
]) > fabs(maxs
[i
]) ? fabs(mins
[i
]) : fabs(maxs
[i
]);
1135 return Length (corner
);
1143 void Mod_LoadBrushModel (model_t
*mod
, void *buffer
)
1149 loadmodel
->type
= mod_brush
;
1151 header
= (dheader_t
*)buffer
;
1153 i
= LittleLong (header
->version
);
1154 if (i
!= BSPVERSION
)
1155 Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod
->name
, i
, BSPVERSION
);
1157 // swap all the lumps
1158 mod_base
= (byte
*)header
;
1160 for (i
=0 ; i
<sizeof(dheader_t
)/4 ; i
++)
1161 ((int *)header
)[i
] = LittleLong ( ((int *)header
)[i
]);
1165 Mod_LoadVertexes (&header
->lumps
[LUMP_VERTEXES
]);
1166 Mod_LoadEdges (&header
->lumps
[LUMP_EDGES
]);
1167 Mod_LoadSurfedges (&header
->lumps
[LUMP_SURFEDGES
]);
1168 Mod_LoadTextures (&header
->lumps
[LUMP_TEXTURES
]);
1169 Mod_LoadLighting (&header
->lumps
[LUMP_LIGHTING
]);
1170 Mod_LoadPlanes (&header
->lumps
[LUMP_PLANES
]);
1171 Mod_LoadTexinfo (&header
->lumps
[LUMP_TEXINFO
]);
1172 Mod_LoadFaces (&header
->lumps
[LUMP_FACES
]);
1173 Mod_LoadMarksurfaces (&header
->lumps
[LUMP_MARKSURFACES
]);
1174 Mod_LoadVisibility (&header
->lumps
[LUMP_VISIBILITY
]);
1175 Mod_LoadLeafs (&header
->lumps
[LUMP_LEAFS
]);
1176 Mod_LoadNodes (&header
->lumps
[LUMP_NODES
]);
1177 Mod_LoadClipnodes (&header
->lumps
[LUMP_CLIPNODES
]);
1178 Mod_LoadEntities (&header
->lumps
[LUMP_ENTITIES
]);
1179 Mod_LoadSubmodels (&header
->lumps
[LUMP_MODELS
]);
1183 mod
->numframes
= 2; // regular and alternate animation
1187 // set up the submodels (FIXME: this is confusing)
1189 for (i
=0 ; i
<mod
->numsubmodels
; i
++)
1191 bm
= &mod
->submodels
[i
];
1193 mod
->hulls
[0].firstclipnode
= bm
->headnode
[0];
1194 for (j
=1 ; j
<MAX_MAP_HULLS
; j
++)
1196 mod
->hulls
[j
].firstclipnode
= bm
->headnode
[j
];
1197 mod
->hulls
[j
].lastclipnode
= mod
->numclipnodes
-1;
1200 mod
->firstmodelsurface
= bm
->firstface
;
1201 mod
->nummodelsurfaces
= bm
->numfaces
;
1203 VectorCopy (bm
->maxs
, mod
->maxs
);
1204 VectorCopy (bm
->mins
, mod
->mins
);
1205 mod
->radius
= RadiusFromBounds (mod
->mins
, mod
->maxs
);
1207 mod
->numleafs
= bm
->visleafs
;
1209 if (i
< mod
->numsubmodels
-1)
1210 { // duplicate the basic information
1213 sprintf (name
, "*%i", i
+1);
1214 loadmodel
= Mod_FindName (name
);
1216 strcpy (loadmodel
->name
, name
);
1223 ==============================================================================
1227 ==============================================================================
1235 void * Mod_LoadAliasFrame (void * pin
, int *pframeindex
, int numv
,
1236 trivertx_t
*pbboxmin
, trivertx_t
*pbboxmax
, aliashdr_t
*pheader
, char *name
)
1238 trivertx_t
*pframe
, *pinframe
;
1240 daliasframe_t
*pdaliasframe
;
1242 pdaliasframe
= (daliasframe_t
*)pin
;
1244 strcpy (name
, pdaliasframe
->name
);
1246 for (i
=0 ; i
<3 ; i
++)
1248 // these are byte values, so we don't have to worry about
1250 pbboxmin
->v
[i
] = pdaliasframe
->bboxmin
.v
[i
];
1251 pbboxmax
->v
[i
] = pdaliasframe
->bboxmax
.v
[i
];
1254 pinframe
= (trivertx_t
*)(pdaliasframe
+ 1);
1255 pframe
= Hunk_AllocName (numv
* sizeof(*pframe
), loadname
);
1257 *pframeindex
= (byte
*)pframe
- (byte
*)pheader
;
1259 for (j
=0 ; j
<numv
; j
++)
1263 // these are all byte values, so no need to deal with endianness
1264 pframe
[j
].lightnormalindex
= pinframe
[j
].lightnormalindex
;
1266 for (k
=0 ; k
<3 ; k
++)
1268 pframe
[j
].v
[k
] = pinframe
[j
].v
[k
];
1274 return (void *)pinframe
;
1283 void * Mod_LoadAliasGroup (void * pin
, int *pframeindex
, int numv
,
1284 trivertx_t
*pbboxmin
, trivertx_t
*pbboxmax
, aliashdr_t
*pheader
, char *name
)
1286 daliasgroup_t
*pingroup
;
1287 maliasgroup_t
*paliasgroup
;
1289 daliasinterval_t
*pin_intervals
;
1290 float *poutintervals
;
1293 pingroup
= (daliasgroup_t
*)pin
;
1295 numframes
= LittleLong (pingroup
->numframes
);
1297 paliasgroup
= Hunk_AllocName (sizeof (maliasgroup_t
) +
1298 (numframes
- 1) * sizeof (paliasgroup
->frames
[0]), loadname
);
1300 paliasgroup
->numframes
= numframes
;
1302 for (i
=0 ; i
<3 ; i
++)
1304 // these are byte values, so we don't have to worry about endianness
1305 pbboxmin
->v
[i
] = pingroup
->bboxmin
.v
[i
];
1306 pbboxmax
->v
[i
] = pingroup
->bboxmax
.v
[i
];
1309 *pframeindex
= (byte
*)paliasgroup
- (byte
*)pheader
;
1311 pin_intervals
= (daliasinterval_t
*)(pingroup
+ 1);
1313 poutintervals
= Hunk_AllocName (numframes
* sizeof (float), loadname
);
1315 paliasgroup
->intervals
= (byte
*)poutintervals
- (byte
*)pheader
;
1317 for (i
=0 ; i
<numframes
; i
++)
1319 *poutintervals
= LittleFloat (pin_intervals
->interval
);
1320 if (*poutintervals
<= 0.0)
1321 Sys_Error ("Mod_LoadAliasGroup: interval<=0");
1327 ptemp
= (void *)pin_intervals
;
1329 for (i
=0 ; i
<numframes
; i
++)
1331 ptemp
= Mod_LoadAliasFrame (ptemp
,
1332 &paliasgroup
->frames
[i
].frame
,
1334 &paliasgroup
->frames
[i
].bboxmin
,
1335 &paliasgroup
->frames
[i
].bboxmax
,
1348 void * Mod_LoadAliasSkin (void * pin
, int *pskinindex
, int skinsize
,
1349 aliashdr_t
*pheader
)
1352 byte
*pskin
, *pinskin
;
1353 unsigned short *pusskin
;
1355 pskin
= Hunk_AllocName (skinsize
* r_pixbytes
, loadname
);
1356 pinskin
= (byte
*)pin
;
1357 *pskinindex
= (byte
*)pskin
- (byte
*)pheader
;
1359 if (r_pixbytes
== 1)
1361 Q_memcpy (pskin
, pinskin
, skinsize
);
1363 else if (r_pixbytes
== 2)
1365 pusskin
= (unsigned short *)pskin
;
1367 for (i
=0 ; i
<skinsize
; i
++)
1368 pusskin
[i
] = d_8to16table
[pinskin
[i
]];
1372 Sys_Error ("Mod_LoadAliasSkin: driver set invalid r_pixbytes: %d\n",
1376 pinskin
+= skinsize
;
1378 return ((void *)pinskin
);
1384 Mod_LoadAliasSkinGroup
1387 void * Mod_LoadAliasSkinGroup (void * pin
, int *pskinindex
, int skinsize
,
1388 aliashdr_t
*pheader
)
1390 daliasskingroup_t
*pinskingroup
;
1391 maliasskingroup_t
*paliasskingroup
;
1393 daliasskininterval_t
*pinskinintervals
;
1394 float *poutskinintervals
;
1397 pinskingroup
= (daliasskingroup_t
*)pin
;
1399 numskins
= LittleLong (pinskingroup
->numskins
);
1401 paliasskingroup
= Hunk_AllocName (sizeof (maliasskingroup_t
) +
1402 (numskins
- 1) * sizeof (paliasskingroup
->skindescs
[0]),
1405 paliasskingroup
->numskins
= numskins
;
1407 *pskinindex
= (byte
*)paliasskingroup
- (byte
*)pheader
;
1409 pinskinintervals
= (daliasskininterval_t
*)(pinskingroup
+ 1);
1411 poutskinintervals
= Hunk_AllocName (numskins
* sizeof (float),loadname
);
1413 paliasskingroup
->intervals
= (byte
*)poutskinintervals
- (byte
*)pheader
;
1415 for (i
=0 ; i
<numskins
; i
++)
1417 *poutskinintervals
= LittleFloat (pinskinintervals
->interval
);
1418 if (*poutskinintervals
<= 0)
1419 Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0");
1421 poutskinintervals
++;
1425 ptemp
= (void *)pinskinintervals
;
1427 for (i
=0 ; i
<numskins
; i
++)
1429 ptemp
= Mod_LoadAliasSkin (ptemp
,
1430 &paliasskingroup
->skindescs
[i
].skin
, skinsize
, pheader
);
1442 void Mod_LoadAliasModel (model_t
*mod
, void *buffer
)
1445 mdl_t
*pmodel
, *pinmodel
;
1446 stvert_t
*pstverts
, *pinstverts
;
1447 aliashdr_t
*pheader
;
1449 dtriangle_t
*pintriangles
;
1450 int version
, numframes
, numskins
;
1452 daliasframetype_t
*pframetype
;
1453 daliasskintype_t
*pskintype
;
1454 maliasskindesc_t
*pskindesc
;
1456 int start
, end
, total
;
1458 start
= Hunk_LowMark ();
1460 pinmodel
= (mdl_t
*)buffer
;
1462 version
= LittleLong (pinmodel
->version
);
1463 if (version
!= ALIAS_VERSION
)
1464 Sys_Error ("%s has wrong version number (%i should be %i)",
1465 mod
->name
, version
, ALIAS_VERSION
);
1468 // allocate space for a working header, plus all the data except the frames,
1469 // skin and group info
1471 size
= sizeof (aliashdr_t
) + (LittleLong (pinmodel
->numframes
) - 1) *
1472 sizeof (pheader
->frames
[0]) +
1474 LittleLong (pinmodel
->numverts
) * sizeof (stvert_t
) +
1475 LittleLong (pinmodel
->numtris
) * sizeof (mtriangle_t
);
1477 pheader
= Hunk_AllocName (size
, loadname
);
1478 pmodel
= (mdl_t
*) ((byte
*)&pheader
[1] +
1479 (LittleLong (pinmodel
->numframes
) - 1) *
1480 sizeof (pheader
->frames
[0]));
1482 // mod->cache.data = pheader;
1483 mod
->flags
= LittleLong (pinmodel
->flags
);
1486 // endian-adjust and copy the data, starting with the alias model header
1488 pmodel
->boundingradius
= LittleFloat (pinmodel
->boundingradius
);
1489 pmodel
->numskins
= LittleLong (pinmodel
->numskins
);
1490 pmodel
->skinwidth
= LittleLong (pinmodel
->skinwidth
);
1491 pmodel
->skinheight
= LittleLong (pinmodel
->skinheight
);
1493 if (pmodel
->skinheight
> MAX_LBM_HEIGHT
)
1494 Sys_Error ("model %s has a skin taller than %d", mod
->name
,
1497 pmodel
->numverts
= LittleLong (pinmodel
->numverts
);
1499 if (pmodel
->numverts
<= 0)
1500 Sys_Error ("model %s has no vertices", mod
->name
);
1502 if (pmodel
->numverts
> MAXALIASVERTS
)
1503 Sys_Error ("model %s has too many vertices", mod
->name
);
1505 pmodel
->numtris
= LittleLong (pinmodel
->numtris
);
1507 if (pmodel
->numtris
<= 0)
1508 Sys_Error ("model %s has no triangles", mod
->name
);
1510 pmodel
->numframes
= LittleLong (pinmodel
->numframes
);
1511 pmodel
->size
= LittleFloat (pinmodel
->size
) * ALIAS_BASE_SIZE_RATIO
;
1512 mod
->synctype
= LittleLong (pinmodel
->synctype
);
1513 mod
->numframes
= pmodel
->numframes
;
1515 for (i
=0 ; i
<3 ; i
++)
1517 pmodel
->scale
[i
] = LittleFloat (pinmodel
->scale
[i
]);
1518 pmodel
->scale_origin
[i
] = LittleFloat (pinmodel
->scale_origin
[i
]);
1519 pmodel
->eyeposition
[i
] = LittleFloat (pinmodel
->eyeposition
[i
]);
1522 numskins
= pmodel
->numskins
;
1523 numframes
= pmodel
->numframes
;
1525 if (pmodel
->skinwidth
& 0x03)
1526 Sys_Error ("Mod_LoadAliasModel: skinwidth not multiple of 4");
1528 pheader
->model
= (byte
*)pmodel
- (byte
*)pheader
;
1533 skinsize
= pmodel
->skinheight
* pmodel
->skinwidth
;
1536 Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins
);
1538 pskintype
= (daliasskintype_t
*)&pinmodel
[1];
1540 pskindesc
= Hunk_AllocName (numskins
* sizeof (maliasskindesc_t
),
1543 pheader
->skindesc
= (byte
*)pskindesc
- (byte
*)pheader
;
1545 for (i
=0 ; i
<numskins
; i
++)
1547 aliasskintype_t skintype
;
1549 skintype
= LittleLong (pskintype
->type
);
1550 pskindesc
[i
].type
= skintype
;
1552 if (skintype
== ALIAS_SKIN_SINGLE
)
1554 pskintype
= (daliasskintype_t
*)
1555 Mod_LoadAliasSkin (pskintype
+ 1,
1561 pskintype
= (daliasskintype_t
*)
1562 Mod_LoadAliasSkinGroup (pskintype
+ 1,
1569 // set base s and t vertices
1571 pstverts
= (stvert_t
*)&pmodel
[1];
1572 pinstverts
= (stvert_t
*)pskintype
;
1574 pheader
->stverts
= (byte
*)pstverts
- (byte
*)pheader
;
1576 for (i
=0 ; i
<pmodel
->numverts
; i
++)
1578 pstverts
[i
].onseam
= LittleLong (pinstverts
[i
].onseam
);
1579 // put s and t in 16.16 format
1580 pstverts
[i
].s
= LittleLong (pinstverts
[i
].s
) << 16;
1581 pstverts
[i
].t
= LittleLong (pinstverts
[i
].t
) << 16;
1585 // set up the triangles
1587 ptri
= (mtriangle_t
*)&pstverts
[pmodel
->numverts
];
1588 pintriangles
= (dtriangle_t
*)&pinstverts
[pmodel
->numverts
];
1590 pheader
->triangles
= (byte
*)ptri
- (byte
*)pheader
;
1592 for (i
=0 ; i
<pmodel
->numtris
; i
++)
1596 ptri
[i
].facesfront
= LittleLong (pintriangles
[i
].facesfront
);
1598 for (j
=0 ; j
<3 ; j
++)
1600 ptri
[i
].vertindex
[j
] =
1601 LittleLong (pintriangles
[i
].vertindex
[j
]);
1609 Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes
);
1611 pframetype
= (daliasframetype_t
*)&pintriangles
[pmodel
->numtris
];
1613 for (i
=0 ; i
<numframes
; i
++)
1615 aliasframetype_t frametype
;
1617 frametype
= LittleLong (pframetype
->type
);
1618 pheader
->frames
[i
].type
= frametype
;
1620 if (frametype
== ALIAS_SINGLE
)
1622 pframetype
= (daliasframetype_t
*)
1623 Mod_LoadAliasFrame (pframetype
+ 1,
1624 &pheader
->frames
[i
].frame
,
1626 &pheader
->frames
[i
].bboxmin
,
1627 &pheader
->frames
[i
].bboxmax
,
1628 pheader
, pheader
->frames
[i
].name
);
1632 pframetype
= (daliasframetype_t
*)
1633 Mod_LoadAliasGroup (pframetype
+ 1,
1634 &pheader
->frames
[i
].frame
,
1636 &pheader
->frames
[i
].bboxmin
,
1637 &pheader
->frames
[i
].bboxmax
,
1638 pheader
, pheader
->frames
[i
].name
);
1642 mod
->type
= mod_alias
;
1644 // FIXME: do this right
1645 mod
->mins
[0] = mod
->mins
[1] = mod
->mins
[2] = -16;
1646 mod
->maxs
[0] = mod
->maxs
[1] = mod
->maxs
[2] = 16;
1649 // move the complete, relocatable alias model to the cache
1651 end
= Hunk_LowMark ();
1652 total
= end
- start
;
1654 Cache_Alloc (&mod
->cache
, total
, loadname
);
1655 if (!mod
->cache
.data
)
1657 memcpy (mod
->cache
.data
, pheader
, total
);
1659 Hunk_FreeToLowMark (start
);
1662 //=============================================================================
1669 void * Mod_LoadSpriteFrame (void * pin
, mspriteframe_t
**ppframe
)
1671 dspriteframe_t
*pinframe
;
1672 mspriteframe_t
*pspriteframe
;
1673 int i
, width
, height
, size
, origin
[2];
1674 unsigned short *ppixout
;
1677 pinframe
= (dspriteframe_t
*)pin
;
1679 width
= LittleLong (pinframe
->width
);
1680 height
= LittleLong (pinframe
->height
);
1681 size
= width
* height
;
1683 pspriteframe
= Hunk_AllocName (sizeof (mspriteframe_t
) + size
*r_pixbytes
,
1686 Q_memset (pspriteframe
, 0, sizeof (mspriteframe_t
) + size
);
1687 *ppframe
= pspriteframe
;
1689 pspriteframe
->width
= width
;
1690 pspriteframe
->height
= height
;
1691 origin
[0] = LittleLong (pinframe
->origin
[0]);
1692 origin
[1] = LittleLong (pinframe
->origin
[1]);
1694 pspriteframe
->up
= origin
[1];
1695 pspriteframe
->down
= origin
[1] - height
;
1696 pspriteframe
->left
= origin
[0];
1697 pspriteframe
->right
= width
+ origin
[0];
1699 if (r_pixbytes
== 1)
1701 Q_memcpy (&pspriteframe
->pixels
[0], (byte
*)(pinframe
+ 1), size
);
1703 else if (r_pixbytes
== 2)
1705 ppixin
= (byte
*)(pinframe
+ 1);
1706 ppixout
= (unsigned short *)&pspriteframe
->pixels
[0];
1708 for (i
=0 ; i
<size
; i
++)
1709 ppixout
[i
] = d_8to16table
[ppixin
[i
]];
1713 Sys_Error ("Mod_LoadSpriteFrame: driver set invalid r_pixbytes: %d\n",
1717 return (void *)((byte
*)pinframe
+ sizeof (dspriteframe_t
) + size
);
1726 void * Mod_LoadSpriteGroup (void * pin
, mspriteframe_t
**ppframe
)
1728 dspritegroup_t
*pingroup
;
1729 mspritegroup_t
*pspritegroup
;
1731 dspriteinterval_t
*pin_intervals
;
1732 float *poutintervals
;
1735 pingroup
= (dspritegroup_t
*)pin
;
1737 numframes
= LittleLong (pingroup
->numframes
);
1739 pspritegroup
= Hunk_AllocName (sizeof (mspritegroup_t
) +
1740 (numframes
- 1) * sizeof (pspritegroup
->frames
[0]), loadname
);
1742 pspritegroup
->numframes
= numframes
;
1744 *ppframe
= (mspriteframe_t
*)pspritegroup
;
1746 pin_intervals
= (dspriteinterval_t
*)(pingroup
+ 1);
1748 poutintervals
= Hunk_AllocName (numframes
* sizeof (float), loadname
);
1750 pspritegroup
->intervals
= poutintervals
;
1752 for (i
=0 ; i
<numframes
; i
++)
1754 *poutintervals
= LittleFloat (pin_intervals
->interval
);
1755 if (*poutintervals
<= 0.0)
1756 Sys_Error ("Mod_LoadSpriteGroup: interval<=0");
1762 ptemp
= (void *)pin_intervals
;
1764 for (i
=0 ; i
<numframes
; i
++)
1766 ptemp
= Mod_LoadSpriteFrame (ptemp
, &pspritegroup
->frames
[i
]);
1778 void Mod_LoadSpriteModel (model_t
*mod
, void *buffer
)
1786 dspriteframetype_t
*pframetype
;
1788 pin
= (dsprite_t
*)buffer
;
1790 version
= LittleLong (pin
->version
);
1791 if (version
!= SPRITE_VERSION
)
1792 Sys_Error ("%s has wrong version number "
1793 "(%i should be %i)", mod
->name
, version
, SPRITE_VERSION
);
1795 numframes
= LittleLong (pin
->numframes
);
1797 size
= sizeof (msprite_t
) + (numframes
- 1) * sizeof (psprite
->frames
);
1799 psprite
= Hunk_AllocName (size
, loadname
);
1801 mod
->cache
.data
= psprite
;
1803 psprite
->type
= LittleLong (pin
->type
);
1804 psprite
->maxwidth
= LittleLong (pin
->width
);
1805 psprite
->maxheight
= LittleLong (pin
->height
);
1806 psprite
->beamlength
= LittleFloat (pin
->beamlength
);
1807 mod
->synctype
= LittleLong (pin
->synctype
);
1808 psprite
->numframes
= numframes
;
1810 mod
->mins
[0] = mod
->mins
[1] = -psprite
->maxwidth
/2;
1811 mod
->maxs
[0] = mod
->maxs
[1] = psprite
->maxwidth
/2;
1812 mod
->mins
[2] = -psprite
->maxheight
/2;
1813 mod
->maxs
[2] = psprite
->maxheight
/2;
1819 Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes
);
1821 mod
->numframes
= numframes
;
1824 pframetype
= (dspriteframetype_t
*)(pin
+ 1);
1826 for (i
=0 ; i
<numframes
; i
++)
1828 spriteframetype_t frametype
;
1830 frametype
= LittleLong (pframetype
->type
);
1831 psprite
->frames
[i
].type
= frametype
;
1833 if (frametype
== SPR_SINGLE
)
1835 pframetype
= (dspriteframetype_t
*)
1836 Mod_LoadSpriteFrame (pframetype
+ 1,
1837 &psprite
->frames
[i
].frameptr
);
1841 pframetype
= (dspriteframetype_t
*)
1842 Mod_LoadSpriteGroup (pframetype
+ 1,
1843 &psprite
->frames
[i
].frameptr
);
1847 mod
->type
= mod_sprite
;
1850 //=============================================================================
1857 void Mod_Print (void)
1862 Con_Printf ("Cached models:\n");
1863 for (i
=0, mod
=mod_known
; i
< mod_numknown
; i
++, mod
++)
1865 Con_Printf ("%8p : %s",mod
->cache
.data
, mod
->name
);
1866 if (mod
->needload
& NL_UNREFERENCED
)
1867 Con_Printf (" (!R)");
1868 if (mod
->needload
& NL_NEEDS_LOADED
)
1869 Con_Printf (" (!P)");