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.
23 byte mod_novis[MAX_MAP_LEAFS/8];
25 qboolean hlbsp; // LordHavoc: true if it is a HalfLife BSP file (version 30)
27 cvar_t gl_subdivide_size = {"gl_subdivide_size", "128", true};
28 cvar_t halflifebsp = {"halflifebsp", "0"};
35 void Mod_BrushInit (void)
37 Cvar_RegisterVariable (&gl_subdivide_size);
38 Cvar_RegisterVariable (&halflifebsp);
39 memset (mod_novis, 0xff, sizeof(mod_novis));
47 mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
53 if (!model || !model->nodes)
54 Sys_Error ("Mod_PointInLeaf: bad model");
59 if (node->contents < 0)
60 return (mleaf_t *)node;
62 d = DotProduct (p,plane->normal) - plane->dist;
64 node = node->children[0];
66 node = node->children[1];
69 return NULL; // never reached
78 byte *Mod_DecompressVis (byte *in, model_t *model)
80 static byte decompressed[MAX_MAP_LEAFS/8];
85 row = (model->numleafs+7)>>3;
89 { // no vis info, so make all visible
113 } while (out - decompressed < row);
118 byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
120 if (leaf == model->leafs)
122 return Mod_DecompressVis (leaf->compressed_vis, model);
127 extern cvar_t r_fullbrights;
134 void Mod_LoadTextures (lump_t *l)
136 int i, j, num, max, altmax, bytesperpixel, freeimage, transparent, fullbrights;
139 texture_t *anims[10];
140 texture_t *altanims[10];
146 loadmodel->textures = NULL;
150 m = (dmiptexlump_t *)(mod_base + l->fileofs);
152 m->nummiptex = LittleLong (m->nummiptex);
154 loadmodel->numtextures = m->nummiptex;
155 loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname);
157 for (i=0 ; i<m->nummiptex ; i++)
159 m->dataofs[i] = LittleLong(m->dataofs[i]);
160 if (m->dataofs[i] == -1)
162 mt = (miptex_t *)((byte *)m + m->dataofs[i]);
163 mt->width = LittleLong (mt->width);
164 mt->height = LittleLong (mt->height);
165 for (j=0 ; j<MIPLEVELS ; j++)
166 mt->offsets[j] = LittleLong (mt->offsets[j]);
168 if ( (mt->width & 15) || (mt->height & 15) )
169 Sys_Error ("Texture %s is not 16 aligned", mt->name);
170 // LordHavoc: rewriting the map texture loader for GLQuake
171 tx = Hunk_AllocName (sizeof(texture_t), loadname );
172 loadmodel->textures[i] = tx;
174 memcpy (tx->name, mt->name, sizeof(tx->name));
175 tx->width = mt->width;
176 tx->height = mt->height;
177 for (j=0 ; j<MIPLEVELS ; j++)
183 data = loadimagepixels(mt->name, FALSE, tx->width, tx->height);
184 if (!data) // no external texture found
188 if (!hlbsp && mt->offsets[0]) // texture included
190 data = (byte *)((int) mt + mt->offsets[0]);
191 if (r_fullbrights.value && mt->name[0] != '*')
193 for (j = 0;j < tx->width*tx->height;j++)
194 if (data[j] >= 224) // fullbright
201 else // no texture, and no external replacement texture was found
203 tx->width = tx->height = 16;
204 data = (byte *)((int) r_notexture_mip + r_notexture_mip->offsets[0]);
209 for (j = 0;j < image_width*image_height;j++)
210 if (data[j*4+3] < 255)
216 if (!hlbsp && !strncmp(mt->name,"sky",3)) // LordHavoc: HL sky textures are entirely unrelated
218 tx->transparent = FALSE;
219 R_InitSky (data, bytesperpixel);
223 tx->transparent = transparent;
228 data2 = malloc(tx->width*tx->height);
229 for (j = 0;j < tx->width*tx->height;j++)
230 data2[j] = data[j] >= 224 ? 0 : data[j]; // no fullbrights
231 tx->gl_texturenum = GL_LoadTexture (tx->name, tx->width, tx->height, data2, true, 0, 1);
232 strcpy(name, tx->name);
233 strcat(name, "_glow");
234 for (j = 0;j < tx->width*tx->height;j++)
235 data2[j] = data[j] >= 224 ? data[j] : 0; // only fullbrights
236 tx->gl_glowtexturenum = GL_LoadTexture (name, tx->width, tx->height, data2, true, 0, 1);
241 tx->gl_texturenum = GL_LoadTexture (tx->name, tx->width, tx->height, data, true, transparent, bytesperpixel);
242 tx->gl_glowtexturenum = 0;
249 pixels = mt->width*mt->height/64*85;
250 tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
251 loadmodel->textures[i] = tx;
253 memcpy (tx->name, mt->name, sizeof(tx->name));
254 tx->width = mt->width;
255 tx->height = mt->height;
256 for (j=0 ; j<MIPLEVELS ; j++)
257 tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
258 // the pixels immediately follow the structures
259 memcpy ( tx+1, mt+1, pixels);
262 if (!strncmp(mt->name,"sky",3))
265 tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false, 1);
270 // sequence the animations
272 for (i=0 ; i<m->nummiptex ; i++)
274 tx = loadmodel->textures[i];
275 if (!tx || tx->name[0] != '+')
278 continue; // allready sequenced
280 // find the number of frames in the animation
281 memset (anims, 0, sizeof(anims));
282 memset (altanims, 0, sizeof(altanims));
286 if (max >= 'a' && max <= 'z')
288 if (max >= '0' && max <= '9')
295 else if (max >= 'A' && max <= 'J')
299 altanims[altmax] = tx;
303 Host_Error ("Bad animating texture %s", tx->name);
305 for (j=i+1 ; j<m->nummiptex ; j++)
307 tx2 = loadmodel->textures[j];
308 if (!tx2 || tx2->name[0] != '+')
310 if (strcmp (tx2->name+2, tx->name+2))
314 if (num >= 'a' && num <= 'z')
316 if (num >= '0' && num <= '9')
323 else if (num >= 'A' && num <= 'J')
331 Sys_Error ("Bad animating texture %s", tx->name);
335 // link them all together
336 for (j=0 ; j<max ; j++)
340 Sys_Error ("Missing frame %i of %s",j, tx->name);
341 tx2->anim_total = max * ANIM_CYCLE;
342 tx2->anim_min = j * ANIM_CYCLE;
343 tx2->anim_max = (j+1) * ANIM_CYCLE;
344 tx2->anim_next = anims[ (j+1)%max ];
346 tx2->alternate_anims = altanims[0];
348 for (j=0 ; j<altmax ; j++)
352 Sys_Error ("Missing frame %i of %s",j, tx->name);
353 tx2->anim_total = altmax * ANIM_CYCLE;
354 tx2->anim_min = j * ANIM_CYCLE;
355 tx2->anim_max = (j+1) * ANIM_CYCLE;
356 tx2->anim_next = altanims[ (j+1)%altmax ];
358 tx2->alternate_anims = anims[0];
368 void Mod_LoadLighting (lump_t *l)
371 byte *in, *out, *data;
373 char litfilename[1024];
374 loadmodel->lightdata = NULL;
377 if (hlbsp) // LordHavoc: load the colored lighting data straight
379 loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname);
380 memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
382 else // LordHavoc: bsp version 29 (normal white lighting)
384 // LordHavoc: hope is not lost yet, check for a .lit file to load
385 strcpy(litfilename, loadmodel->name);
386 COM_StripExtension(litfilename, litfilename);
387 strcat(litfilename, ".lit");
388 data = (byte*) COM_LoadHunkFile (litfilename, false);
391 if (data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T')
393 i = LittleLong(((int *)data)[1]);
396 loadmodel->lightdata = data + 8;
400 Con_Printf("Unknown .lit file version (%d)\n", i);
403 Con_Printf("Corrupt .lit file (old version?), ignoring\n");
405 // LordHavoc: oh well, expand the white lighting data
406 loadmodel->lightdata = Hunk_AllocName ( l->filelen*3, litfilename);
407 in = loadmodel->lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write
408 out = loadmodel->lightdata;
409 memcpy (in, mod_base + l->fileofs, l->filelen);
410 for (i = 0;i < l->filelen;i++)
426 void Mod_LoadVisibility (lump_t *l)
430 loadmodel->visdata = NULL;
433 loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname);
434 memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
437 void CL_ParseEntityLump(char *entdata);
439 extern qboolean isworldmodel;
446 void Mod_LoadEntities (lump_t *l)
450 loadmodel->entities = NULL;
453 loadmodel->entities = Hunk_AllocName ( l->filelen, loadname);
454 memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen);
457 CL_ParseEntityLump(loadmodel->entities);
466 void Mod_LoadVertexes (lump_t *l)
472 in = (void *)(mod_base + l->fileofs);
473 if (l->filelen % sizeof(*in))
474 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
475 count = l->filelen / sizeof(*in);
476 out = Hunk_AllocName ( count*sizeof(*out), loadname);
478 loadmodel->vertexes = out;
479 loadmodel->numvertexes = count;
481 for ( i=0 ; i<count ; i++, in++, out++)
483 out->position[0] = LittleFloat (in->point[0]);
484 out->position[1] = LittleFloat (in->point[1]);
485 out->position[2] = LittleFloat (in->point[2]);
494 void Mod_LoadSubmodels (lump_t *l)
500 in = (void *)(mod_base + l->fileofs);
501 if (l->filelen % sizeof(*in))
502 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
503 count = l->filelen / sizeof(*in);
504 out = Hunk_AllocName ( count*sizeof(*out), loadname);
506 loadmodel->submodels = out;
507 loadmodel->numsubmodels = count;
509 for ( i=0 ; i<count ; i++, in++, out++)
511 for (j=0 ; j<3 ; j++)
512 { // spread the mins / maxs by a pixel
513 out->mins[j] = LittleFloat (in->mins[j]) - 1;
514 out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
515 out->origin[j] = LittleFloat (in->origin[j]);
517 for (j=0 ; j<MAX_MAP_HULLS ; j++)
518 out->headnode[j] = LittleLong (in->headnode[j]);
519 out->visleafs = LittleLong (in->visleafs);
520 out->firstface = LittleLong (in->firstface);
521 out->numfaces = LittleLong (in->numfaces);
530 void Mod_LoadEdges (lump_t *l)
536 in = (void *)(mod_base + l->fileofs);
537 if (l->filelen % sizeof(*in))
538 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
539 count = l->filelen / sizeof(*in);
540 out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname);
542 loadmodel->edges = out;
543 loadmodel->numedges = count;
545 for ( i=0 ; i<count ; i++, in++, out++)
547 out->v[0] = (unsigned short)LittleShort(in->v[0]);
548 out->v[1] = (unsigned short)LittleShort(in->v[1]);
557 void Mod_LoadTexinfo (lump_t *l)
565 in = (void *)(mod_base + l->fileofs);
566 if (l->filelen % sizeof(*in))
567 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
568 count = l->filelen / sizeof(*in);
569 out = Hunk_AllocName ( count*sizeof(*out), loadname);
571 loadmodel->texinfo = out;
572 loadmodel->numtexinfo = count;
574 for ( i=0 ; i<count ; i++, in++, out++)
576 for (j=0 ; j<8 ; j++)
577 out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
578 len1 = Length (out->vecs[0]);
579 len2 = Length (out->vecs[1]);
580 len1 = (len1 + len2)/2;
583 else if (len1 < 0.49)
585 else if (len1 < 0.99)
590 if (len1 + len2 < 0.001)
591 out->mipadjust = 1; // don't crash
593 out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 );
596 miptex = LittleLong (in->miptex);
597 out->flags = LittleLong (in->flags);
599 if (!loadmodel->textures)
601 out->texture = r_notexture_mip; // checkerboard texture
606 if (miptex >= loadmodel->numtextures)
607 Sys_Error ("miptex >= loadmodel->numtextures");
608 out->texture = loadmodel->textures[miptex];
611 out->texture = r_notexture_mip; // texture not found
615 out->texture->transparent = FALSE;
624 Fills in s->texturemins[] and s->extents[]
627 void CalcSurfaceExtents (msurface_t *s)
629 float mins[2], maxs[2], val;
633 int bmins[2], bmaxs[2];
635 mins[0] = mins[1] = 999999;
636 maxs[0] = maxs[1] = -99999;
640 for (i=0 ; i<s->numedges ; i++)
642 e = loadmodel->surfedges[s->firstedge+i];
644 v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
646 v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
648 for (j=0 ; j<2 ; j++)
650 val = v->position[0] * tex->vecs[j][0] +
651 v->position[1] * tex->vecs[j][1] +
652 v->position[2] * tex->vecs[j][2] +
661 for (i=0 ; i<2 ; i++)
663 bmins[i] = floor(mins[i]/16);
664 bmaxs[i] = ceil(maxs[i]/16);
666 s->texturemins[i] = bmins[i] * 16;
667 s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
668 if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 /* 256 */ )
669 Sys_Error ("Bad surface extents");
673 void GL_SubdivideSurface (msurface_t *fa);
675 extern char skyname[];
682 void Mod_LoadFaces (lump_t *l)
686 int i, count, surfnum;
689 in = (void *)(mod_base + l->fileofs);
690 if (l->filelen % sizeof(*in))
691 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
692 count = l->filelen / sizeof(*in);
693 out = Hunk_AllocName ( count*sizeof(*out), loadname);
695 loadmodel->surfaces = out;
696 loadmodel->numsurfaces = count;
698 for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
700 out->firstedge = LittleLong(in->firstedge);
701 out->numedges = LittleShort(in->numedges);
704 planenum = LittleShort(in->planenum);
705 side = LittleShort(in->side);
707 out->flags |= SURF_PLANEBACK;
709 out->plane = loadmodel->planes + planenum;
711 out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
713 CalcSurfaceExtents (out);
717 for (i=0 ; i<MAXLIGHTMAPS ; i++)
718 out->styles[i] = in->styles[i];
719 i = LittleLong(in->lightofs);
722 else if (hlbsp) // LordHavoc: HalfLife map (bsp version 30)
723 out->samples = loadmodel->lightdata + i;
724 else // LordHavoc: white lighting (bsp version 29)
725 out->samples = loadmodel->lightdata + (i * 3);
727 // set the drawing flags flag
729 // if (!strncmp(out->texinfo->texture->name,"sky",3)) // sky
730 // LordHavoc: faster check
731 if ((out->texinfo->texture->name[0] == 's' || out->texinfo->texture->name[0] == 'S')
732 && (out->texinfo->texture->name[1] == 'k' || out->texinfo->texture->name[1] == 'K')
733 && (out->texinfo->texture->name[2] == 'y' || out->texinfo->texture->name[2] == 'Y'))
735 // LordHavoc: for consistency reasons, mark sky as fullbright and solid as well
736 out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED | SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA);
737 GL_SubdivideSurface (out); // cut up polygon for warps
741 // if (!strncmp(out->texinfo->texture->name,"*",1)) // turbulent
742 if (out->texinfo->texture->name[0] == '*') // LordHavoc: faster check
744 out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED);
745 // LordHavoc: some turbulent textures should be fullbright and solid
746 if (!strncmp(out->texinfo->texture->name,"*lava",5)
747 || !strncmp(out->texinfo->texture->name,"*teleport",9)
748 || !strncmp(out->texinfo->texture->name,"*rift",5)) // Scourge of Armagon texture
749 out->flags |= (SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA);
750 for (i=0 ; i<2 ; i++)
752 out->extents[i] = 16384;
753 out->texturemins[i] = -8192;
755 GL_SubdivideSurface (out); // cut up polygon for warps
768 void Mod_SetParent (mnode_t *node, mnode_t *parent)
770 node->parent = parent;
771 if (node->contents < 0)
773 Mod_SetParent (node->children[0], node);
774 Mod_SetParent (node->children[1], node);
782 void Mod_LoadNodes (lump_t *l)
788 in = (void *)(mod_base + l->fileofs);
789 if (l->filelen % sizeof(*in))
790 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
791 count = l->filelen / sizeof(*in);
792 out = Hunk_AllocName ( count*sizeof(*out), loadname);
794 loadmodel->nodes = out;
795 loadmodel->numnodes = count;
797 for ( i=0 ; i<count ; i++, in++, out++)
799 for (j=0 ; j<3 ; j++)
801 out->minmaxs[j] = LittleShort (in->mins[j]);
802 out->minmaxs[3+j] = LittleShort (in->maxs[j]);
805 p = LittleLong(in->planenum);
806 out->plane = loadmodel->planes + p;
808 out->firstsurface = LittleShort (in->firstface);
809 out->numsurfaces = LittleShort (in->numfaces);
811 for (j=0 ; j<2 ; j++)
813 p = LittleShort (in->children[j]);
815 out->children[j] = loadmodel->nodes + p;
817 out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
821 Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
829 void Mod_LoadLeafs (lump_t *l)
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);
841 loadmodel->leafs = out;
842 loadmodel->numleafs = count;
844 for ( i=0 ; i<count ; i++, in++, out++)
846 for (j=0 ; j<3 ; j++)
848 out->minmaxs[j] = LittleShort (in->mins[j]);
849 out->minmaxs[3+j] = LittleShort (in->maxs[j]);
852 p = LittleLong(in->contents);
855 out->firstmarksurface = loadmodel->marksurfaces +
856 LittleShort(in->firstmarksurface);
857 out->nummarksurfaces = LittleShort(in->nummarksurfaces);
859 p = LittleLong(in->visofs);
861 out->compressed_vis = NULL;
863 out->compressed_vis = loadmodel->visdata + p;
866 for (j=0 ; j<4 ; j++)
867 out->ambient_sound_level[j] = in->ambient_level[j];
869 // gl underwater warp
870 // LordHavoc: disabled underwater warping
872 if (out->contents != CONTENTS_EMPTY)
874 for (j=0 ; j<out->nummarksurfaces ; j++)
875 out->firstmarksurface[j]->flags |= SURF_UNDERWATER;
886 void Mod_LoadClipnodes (lump_t *l)
888 dclipnode_t *in, *out;
892 in = (void *)(mod_base + l->fileofs);
893 if (l->filelen % sizeof(*in))
894 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
895 count = l->filelen / sizeof(*in);
896 out = Hunk_AllocName ( count*sizeof(*out), loadname);
898 loadmodel->clipnodes = out;
899 loadmodel->numclipnodes = count;
901 hull = &loadmodel->hulls[1];
902 hull->clipnodes = out;
903 hull->firstclipnode = 0;
904 hull->lastclipnode = count-1;
905 hull->planes = loadmodel->planes;
906 hull->clip_mins[0] = -16;
907 hull->clip_mins[1] = -16;
908 hull->clip_mins[2] = -24;
909 hull->clip_maxs[0] = 16;
910 hull->clip_maxs[1] = 16;
911 hull->clip_maxs[2] = 32;
913 hull = &loadmodel->hulls[2];
914 hull->clipnodes = out;
915 hull->firstclipnode = 0;
916 hull->lastclipnode = count-1;
917 hull->planes = loadmodel->planes;
918 hull->clip_mins[0] = -32;
919 hull->clip_mins[1] = -32;
920 hull->clip_mins[2] = -24;
921 hull->clip_maxs[0] = 32;
922 hull->clip_maxs[1] = 32;
923 hull->clip_maxs[2] = 64;
925 for (i=0 ; i<count ; i++, out++, in++)
927 out->planenum = LittleLong(in->planenum);
928 out->children[0] = LittleShort(in->children[0]);
929 out->children[1] = LittleShort(in->children[1]);
937 Duplicate the drawing hull structure as a clipping hull
940 void Mod_MakeHull0 (void)
947 hull = &loadmodel->hulls[0];
949 in = loadmodel->nodes;
950 count = loadmodel->numnodes;
951 out = Hunk_AllocName ( count*sizeof(*out), loadname);
953 hull->clipnodes = out;
954 hull->firstclipnode = 0;
955 hull->lastclipnode = count-1;
956 hull->planes = loadmodel->planes;
958 for (i=0 ; i<count ; i++, out++, in++)
960 out->planenum = in->plane - loadmodel->planes;
961 for (j=0 ; j<2 ; j++)
963 child = in->children[j];
964 if (child->contents < 0)
965 out->children[j] = child->contents;
967 out->children[j] = child - loadmodel->nodes;
977 void Mod_LoadMarksurfaces (lump_t *l)
983 in = (void *)(mod_base + l->fileofs);
984 if (l->filelen % sizeof(*in))
985 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
986 count = l->filelen / sizeof(*in);
987 out = Hunk_AllocName ( count*sizeof(*out), loadname);
989 loadmodel->marksurfaces = out;
990 loadmodel->nummarksurfaces = count;
992 for ( i=0 ; i<count ; i++)
994 j = LittleShort(in[i]);
995 if (j >= loadmodel->numsurfaces)
996 Sys_Error ("Mod_ParseMarksurfaces: bad surface number");
997 out[i] = loadmodel->surfaces + j;
1006 void Mod_LoadSurfedges (lump_t *l)
1011 in = (void *)(mod_base + l->fileofs);
1012 if (l->filelen % sizeof(*in))
1013 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
1014 count = l->filelen / sizeof(*in);
1015 out = Hunk_AllocName ( count*sizeof(*out), loadname);
1017 loadmodel->surfedges = out;
1018 loadmodel->numsurfedges = count;
1020 for ( i=0 ; i<count ; i++)
1021 out[i] = LittleLong (in[i]);
1030 void Mod_LoadPlanes (lump_t *l)
1038 in = (void *)(mod_base + l->fileofs);
1039 if (l->filelen % sizeof(*in))
1040 Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
1041 count = l->filelen / sizeof(*in);
1042 out = Hunk_AllocName ( count*2*sizeof(*out), loadname);
1044 loadmodel->planes = out;
1045 loadmodel->numplanes = count;
1047 for ( i=0 ; i<count ; i++, in++, out++)
1050 for (j=0 ; j<3 ; j++)
1052 out->normal[j] = LittleFloat (in->normal[j]);
1053 // if (out->normal[j] < 0)
1057 out->dist = LittleFloat (in->dist);
1058 out->type = LittleLong (in->type);
1059 // out->signbits = bits;
1060 BoxOnPlaneSideClassify(out);
1069 void Mod_LoadBrushModel (model_t *mod, void *buffer)
1075 loadmodel->type = mod_brush;
1077 header = (dheader_t *)buffer;
1079 i = LittleLong (header->version);
1080 if (i != BSPVERSION & i != 30)
1081 Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i or 30 (HalfLife))", mod->name, i, BSPVERSION);
1083 halflifebsp.value = hlbsp;
1085 // swap all the lumps
1086 mod_base = (byte *)header;
1088 for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
1089 ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
1093 // LordHavoc: had to move entity loading above everything to allow parsing various settings from worldspawn
1094 Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]);
1096 Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
1097 Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
1098 Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
1099 Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
1100 Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
1101 Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
1102 Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
1103 Mod_LoadFaces (&header->lumps[LUMP_FACES]);
1104 Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
1105 Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
1106 Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
1107 Mod_LoadNodes (&header->lumps[LUMP_NODES]);
1108 Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]);
1109 // Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]);
1110 Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
1114 mod->numframes = 2; // regular and alternate animation
1117 // set up the submodels (FIXME: this is confusing)
1119 for (i=0 ; i<mod->numsubmodels ; i++)
1121 bm = &mod->submodels[i];
1123 mod->hulls[0].firstclipnode = bm->headnode[0];
1124 for (j=1 ; j<MAX_MAP_HULLS ; j++)
1126 mod->hulls[j].firstclipnode = bm->headnode[j];
1127 mod->hulls[j].lastclipnode = mod->numclipnodes-1;
1130 mod->firstmodelsurface = bm->firstface;
1131 mod->nummodelsurfaces = bm->numfaces;
1133 VectorCopy (bm->maxs, mod->maxs);
1134 VectorCopy (bm->mins, mod->mins);
1136 mod->radius = RadiusFromBounds (mod->mins, mod->maxs);
1138 mod->numleafs = bm->visleafs;
1140 if (isworldmodel && i < (mod->numsubmodels-1)) // LordHavoc: only register submodels if it is the world (prevents bsp models from replacing world submodels)
1141 { // duplicate the basic information
1144 sprintf (name, "*%i", i+1);
1145 loadmodel = Mod_FindName (name);
1147 strcpy (loadmodel->name, name);