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));
42 // Mod_PointInLeaf moved to cpu_noasm.c
49 byte *Mod_DecompressVis (byte *in, model_t *model)
51 static byte decompressed[MAX_MAP_LEAFS/8];
56 row = (model->numleafs+7)>>3;
60 { // no vis info, so make all visible
84 } while (out - decompressed < row);
89 byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
91 if (leaf == model->leafs)
93 return Mod_DecompressVis (leaf->compressed_vis, model);
96 extern byte *mod_base;
98 extern cvar_t r_fullbrights;
105 void Mod_LoadTextures (lump_t *l)
107 int i, j, num, max, altmax, bytesperpixel, freeimage, transparent, fullbrights;
110 texture_t *anims[10];
111 texture_t *altanims[10];
118 loadmodel->textures = NULL;
122 m = (dmiptexlump_t *)(mod_base + l->fileofs);
124 m->nummiptex = LittleLong (m->nummiptex);
126 loadmodel->numtextures = m->nummiptex;
127 loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures), va("%s texture headers", loadname));
129 // just to work around bounds checking when debugging with it (array index out of bounds error thing)
131 for (i=0 ; i<m->nummiptex ; i++)
133 dofs[i] = LittleLong(dofs[i]);
136 mt = (miptex_t *)((byte *)m + dofs[i]);
137 mt->width = LittleLong (mt->width);
138 mt->height = LittleLong (mt->height);
139 for (j=0 ; j<MIPLEVELS ; j++)
140 mt->offsets[j] = LittleLong (mt->offsets[j]);
142 if ( (mt->width & 15) || (mt->height & 15) )
143 Host_Error ("Texture %s is not 16 aligned", mt->name);
144 // LordHavoc: rewriting the map texture loader for GLQuake
145 tx = Hunk_AllocName (sizeof(texture_t), va("%s textures", loadname));
146 loadmodel->textures[i] = tx;
148 // LordHavoc: force all names to lowercase and make sure they are terminated while copying
149 for (j = 0;mt->name[j] && j < 15;j++)
151 if (mt->name[j] >= 'A' && mt->name[j] <= 'Z')
152 tx->name[j] = mt->name[j] + ('a' - 'A');
154 tx->name[j] = mt->name[j];
159 tx->width = mt->width;
160 tx->height = mt->height;
161 for (j=0 ; j<MIPLEVELS ; j++)
167 data = loadimagepixels(tx->name, false, 0, 0); //tx->width, tx->height);
168 if (!data) // no external texture found
172 if (mt->offsets[0]) // texture included
177 data = W_ConvertWAD3Texture(mt);
178 tx->width = image_width;
179 tx->height = image_height;
181 byte *in, *out, *pal;
187 in = (byte *)((int) mt + mt->offsets[0]);
188 data = out = qmalloc(mt->width * mt->height * 4);
189 pal = in + (((mt->width * mt->height) * 85) >> 6);
190 // palsize = pal[1] * 0x100 + pal[0];
191 // if (palsize >= 256)
194 for (d = 0;d < mt->width * mt->height;d++)
197 if (mt->name[0] == '{' && p == 255)
199 out[0] = out[1] = out[2] = out[3] = 0;
219 data = W_GetTexture(mt->name);
220 tx->width = image_width;
221 tx->height = image_height;
228 data = (byte *)((int) r_notexture_mip + r_notexture_mip->offsets[0]);
229 tx->width = tx->height = 16;
234 if (mt->offsets[0]) // texture included
239 data = (byte *)((int) mt + mt->offsets[0]);
240 tx->width = mt->width;
241 tx->height = mt->height;
242 if (r_fullbrights.value && tx->name[0] != '*')
244 for (j = 0;j < tx->width*tx->height;j++)
246 if (data[j] >= 224) // fullbright
254 else // no texture, and no external replacement texture was found
259 data = (byte *)((int) r_notexture_mip + r_notexture_mip->offsets[0]);
260 tx->width = tx->height = 16;
264 if (!hlbsp && !strncmp(tx->name,"sky",3) && tx->width == 256 && tx->height == 128) // LordHavoc: HL sky textures are entirely unrelated
266 tx->transparent = false;
267 R_InitSky (data, bytesperpixel);
275 tx->transparent = false;
276 data2 = qmalloc(tx->width*tx->height);
277 for (j = 0;j < tx->width*tx->height;j++)
278 data2[j] = data[j] >= 224 ? 0 : data[j]; // no fullbrights
279 tx->gl_texturenum = GL_LoadTexture (tx->name, tx->width, tx->height, data2, true, false, 1);
280 strcpy(name, tx->name);
281 strcat(name, "_glow");
282 for (j = 0;j < tx->width*tx->height;j++)
283 data2[j] = data[j] >= 224 ? data[j] : 0; // only fullbrights
284 tx->gl_glowtexturenum = GL_LoadTexture (name, tx->width, tx->height, data2, true, false, 1);
289 tx->transparent = transparent;
290 tx->gl_texturenum = GL_LoadTexture (tx->name, tx->width, tx->height, data, true, transparent, bytesperpixel);
291 tx->gl_glowtexturenum = 0;
299 // sequence the animations
301 for (i=0 ; i<m->nummiptex ; i++)
303 tx = loadmodel->textures[i];
304 if (!tx || tx->name[0] != '+')
307 continue; // allready sequenced
309 // find the number of frames in the animation
310 memset (anims, 0, sizeof(anims));
311 memset (altanims, 0, sizeof(altanims));
315 if (max >= 'a' && max <= 'z')
317 if (max >= '0' && max <= '9')
324 else if (max >= 'A' && max <= 'J')
328 altanims[altmax] = tx;
332 Host_Error ("Bad animating texture %s", tx->name);
334 for (j=i+1 ; j<m->nummiptex ; j++)
336 tx2 = loadmodel->textures[j];
337 if (!tx2 || tx2->name[0] != '+')
339 if (strcmp (tx2->name+2, tx->name+2))
343 if (num >= 'a' && num <= 'z')
345 if (num >= '0' && num <= '9')
352 else if (num >= 'A' && num <= 'J')
360 Host_Error ("Bad animating texture %s", tx->name);
364 // link them all together
365 for (j=0 ; j<max ; j++)
369 Host_Error ("Missing frame %i of %s",j, tx->name);
370 tx2->anim_total = max * ANIM_CYCLE;
371 tx2->anim_min = j * ANIM_CYCLE;
372 tx2->anim_max = (j+1) * ANIM_CYCLE;
373 tx2->anim_next = anims[ (j+1)%max ];
375 tx2->alternate_anims = altanims[0];
377 for (j=0 ; j<altmax ; j++)
381 Host_Error ("Missing frame %i of %s",j, tx->name);
382 tx2->anim_total = altmax * ANIM_CYCLE;
383 tx2->anim_min = j * ANIM_CYCLE;
384 tx2->anim_max = (j+1) * ANIM_CYCLE;
385 tx2->anim_next = altanims[ (j+1)%altmax ];
387 tx2->alternate_anims = anims[0];
397 void Mod_LoadLighting (lump_t *l)
400 byte *in, *out, *data;
402 char litfilename[1024];
403 loadmodel->lightdata = NULL;
404 if (hlbsp) // LordHavoc: load the colored lighting data straight
406 loadmodel->lightdata = Hunk_AllocName ( l->filelen, va("%s lightmaps", loadname));
407 memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
409 else // LordHavoc: bsp version 29 (normal white lighting)
411 // LordHavoc: hope is not lost yet, check for a .lit file to load
412 strcpy(litfilename, loadmodel->name);
413 COM_StripExtension(litfilename, litfilename);
414 strcat(litfilename, ".lit");
415 data = (byte*) COM_LoadHunkFile (litfilename, false);
418 if (data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T')
420 i = LittleLong(((int *)data)[1]);
423 Con_DPrintf("%s loaded", litfilename);
424 loadmodel->lightdata = data + 8;
428 Con_Printf("Unknown .lit file version (%d)\n", i);
431 Con_Printf("Corrupt .lit file (old version?), ignoring\n");
433 // LordHavoc: oh well, expand the white lighting data
436 loadmodel->lightdata = Hunk_AllocName ( l->filelen*3, va("%s lightmaps", loadname));
437 in = loadmodel->lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write
438 out = loadmodel->lightdata;
439 memcpy (in, mod_base + l->fileofs, l->filelen);
440 for (i = 0;i < l->filelen;i++)
456 void Mod_LoadVisibility (lump_t *l)
460 loadmodel->visdata = NULL;
463 loadmodel->visdata = Hunk_AllocName ( l->filelen, va("%s visdata", loadname));
464 memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
467 void CL_ParseEntityLump(char *entdata);
469 extern qboolean isworldmodel;
476 void Mod_LoadEntities (lump_t *l)
480 loadmodel->entities = NULL;
483 loadmodel->entities = Hunk_AllocName ( l->filelen, va("%s entities", loadname));
484 memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen);
487 CL_ParseEntityLump(loadmodel->entities);
496 void Mod_LoadVertexes (lump_t *l)
502 in = (void *)(mod_base + l->fileofs);
503 if (l->filelen % sizeof(*in))
504 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
505 count = l->filelen / sizeof(*in);
506 out = Hunk_AllocName ( count*sizeof(*out), va("%s vertices", loadname));
508 loadmodel->vertexes = out;
509 loadmodel->numvertexes = count;
511 for ( i=0 ; i<count ; i++, in++, out++)
513 out->position[0] = LittleFloat (in->point[0]);
514 out->position[1] = LittleFloat (in->point[1]);
515 out->position[2] = LittleFloat (in->point[2]);
524 void Mod_LoadSubmodels (lump_t *l)
530 in = (void *)(mod_base + l->fileofs);
531 if (l->filelen % sizeof(*in))
532 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
533 count = l->filelen / sizeof(*in);
534 out = Hunk_AllocName ( count*sizeof(*out), va("%s submodels", loadname));
536 loadmodel->submodels = out;
537 loadmodel->numsubmodels = count;
539 for ( i=0 ; i<count ; i++, in++, out++)
541 for (j=0 ; j<3 ; j++)
542 { // spread the mins / maxs by a pixel
543 out->mins[j] = LittleFloat (in->mins[j]) - 1;
544 out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
545 out->origin[j] = LittleFloat (in->origin[j]);
547 for (j=0 ; j<MAX_MAP_HULLS ; j++)
548 out->headnode[j] = LittleLong (in->headnode[j]);
549 out->visleafs = LittleLong (in->visleafs);
550 out->firstface = LittleLong (in->firstface);
551 out->numfaces = LittleLong (in->numfaces);
560 void Mod_LoadEdges (lump_t *l)
566 in = (void *)(mod_base + l->fileofs);
567 if (l->filelen % sizeof(*in))
568 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
569 count = l->filelen / sizeof(*in);
570 out = Hunk_AllocName ( (count + 1) * sizeof(*out), va("%s edges", loadname));
572 loadmodel->edges = out;
573 loadmodel->numedges = count;
575 for ( i=0 ; i<count ; i++, in++, out++)
577 out->v[0] = (unsigned short)LittleShort(in->v[0]);
578 out->v[1] = (unsigned short)LittleShort(in->v[1]);
587 void Mod_LoadTexinfo (lump_t *l)
595 in = (void *)(mod_base + l->fileofs);
596 if (l->filelen % sizeof(*in))
597 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
598 count = l->filelen / sizeof(*in);
599 out = Hunk_AllocName ( count*sizeof(*out), va("%s texinfo", loadname));
601 loadmodel->texinfo = out;
602 loadmodel->numtexinfo = count;
604 for ( i=0 ; i<count ; i++, in++, out++)
606 for (k=0 ; k<2 ; k++)
607 for (j=0 ; j<4 ; j++)
608 out->vecs[k][j] = LittleFloat (in->vecs[k][j]);
609 len1 = Length (out->vecs[0]);
610 len2 = Length (out->vecs[1]);
611 len1 = (len1 + len2)/2;
614 else if (len1 < 0.49)
616 else if (len1 < 0.99)
621 if (len1 + len2 < 0.001)
622 out->mipadjust = 1; // don't crash
624 out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 );
627 miptex = LittleLong (in->miptex);
628 out->flags = LittleLong (in->flags);
630 if (!loadmodel->textures)
632 out->texture = r_notexture_mip; // checkerboard texture
634 out->texture->transparent = false;
638 if (miptex >= loadmodel->numtextures)
639 Host_Error ("miptex >= loadmodel->numtextures");
640 out->texture = loadmodel->textures[miptex];
643 out->texture = r_notexture_mip; // texture not found
645 out->texture->transparent = false;
655 Fills in s->texturemins[] and s->extents[]
658 void CalcSurfaceExtents (msurface_t *s)
660 float mins[2], maxs[2], val;
664 int bmins[2], bmaxs[2];
666 mins[0] = mins[1] = 999999;
667 maxs[0] = maxs[1] = -99999;
671 for (i=0 ; i<s->numedges ; i++)
673 e = loadmodel->surfedges[s->firstedge+i];
675 v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
677 v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
679 for (j=0 ; j<2 ; j++)
681 val = v->position[0] * tex->vecs[j][0] +
682 v->position[1] * tex->vecs[j][1] +
683 v->position[2] * tex->vecs[j][2] +
692 for (i=0 ; i<2 ; i++)
694 bmins[i] = floor(mins[i]/16);
695 bmaxs[i] = ceil(maxs[i]/16);
697 s->texturemins[i] = bmins[i] * 16;
698 s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
699 // if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512)
700 if ((tex->flags & TEX_SPECIAL) == 0 && (s->extents[i]+1) > (256*16))
701 Host_Error ("Bad surface extents");
705 void GL_SubdivideSurface (msurface_t *fa);
707 extern char skyname[];
714 void Mod_LoadFaces (lump_t *l)
718 int i, count, surfnum;
721 in = (void *)(mod_base + l->fileofs);
722 if (l->filelen % sizeof(*in))
723 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
724 count = l->filelen / sizeof(*in);
725 out = Hunk_AllocName ( count*sizeof(*out), va("%s faces", loadname));
727 loadmodel->surfaces = out;
728 loadmodel->numsurfaces = count;
730 for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
732 out->firstedge = LittleLong(in->firstedge);
733 out->numedges = LittleShort(in->numedges);
736 planenum = LittleShort(in->planenum);
737 side = LittleShort(in->side);
739 out->flags |= SURF_PLANEBACK;
741 out->plane = loadmodel->planes + planenum;
743 out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
745 CalcSurfaceExtents (out);
749 for (i=0 ; i<MAXLIGHTMAPS ; i++)
750 out->styles[i] = in->styles[i];
751 i = LittleLong(in->lightofs);
754 else if (hlbsp) // LordHavoc: HalfLife map (bsp version 30)
755 out->samples = loadmodel->lightdata + i;
756 else // LordHavoc: white lighting (bsp version 29)
757 out->samples = loadmodel->lightdata + (i * 3);
759 // set the drawing flags flag
761 // if (!strncmp(out->texinfo->texture->name,"sky",3)) // sky
762 // LordHavoc: faster check
763 if ((out->texinfo->texture->name[0] == 's' || out->texinfo->texture->name[0] == 'S')
764 && (out->texinfo->texture->name[1] == 'k' || out->texinfo->texture->name[1] == 'K')
765 && (out->texinfo->texture->name[2] == 'y' || out->texinfo->texture->name[2] == 'Y'))
767 // LordHavoc: for consistency reasons, mark sky as fullbright and solid as well
768 out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED | SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA);
769 GL_SubdivideSurface (out); // cut up polygon for warps
773 // if (!strncmp(out->texinfo->texture->name,"*",1)) // turbulent
774 if (out->texinfo->texture->name[0] == '*') // LordHavoc: faster check
776 out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED);
777 // LordHavoc: some turbulent textures should be fullbright and solid
778 if (!strncmp(out->texinfo->texture->name,"*lava",5)
779 || !strncmp(out->texinfo->texture->name,"*teleport",9)
780 || !strncmp(out->texinfo->texture->name,"*rift",5)) // Scourge of Armagon texture
781 out->flags |= (SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA);
782 for (i=0 ; i<2 ; i++)
784 out->extents[i] = 16384;
785 out->texturemins[i] = -8192;
787 GL_SubdivideSurface (out); // cut up polygon for warps
800 void Mod_SetParent (mnode_t *node, mnode_t *parent)
802 node->parent = parent;
803 if (node->contents < 0)
805 Mod_SetParent (node->children[0], node);
806 Mod_SetParent (node->children[1], node);
814 void Mod_LoadNodes (lump_t *l)
820 in = (void *)(mod_base + l->fileofs);
821 if (l->filelen % sizeof(*in))
822 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
823 count = l->filelen / sizeof(*in);
824 out = Hunk_AllocName ( count*sizeof(*out), va("%s nodes", loadname));
826 loadmodel->nodes = out;
827 loadmodel->numnodes = count;
829 for ( i=0 ; i<count ; i++, in++, out++)
831 for (j=0 ; j<3 ; j++)
833 out->minmaxs[j] = LittleShort (in->mins[j]);
834 out->minmaxs[3+j] = LittleShort (in->maxs[j]);
837 p = LittleLong(in->planenum);
838 out->plane = loadmodel->planes + p;
840 out->firstsurface = LittleShort (in->firstface);
841 out->numsurfaces = LittleShort (in->numfaces);
843 for (j=0 ; j<2 ; j++)
845 p = LittleShort (in->children[j]);
847 out->children[j] = loadmodel->nodes + p;
849 out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
853 Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
861 void Mod_LoadLeafs (lump_t *l)
867 in = (void *)(mod_base + l->fileofs);
868 if (l->filelen % sizeof(*in))
869 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
870 count = l->filelen / sizeof(*in);
871 out = Hunk_AllocName ( count*sizeof(*out), va("%s leafs", loadname));
873 loadmodel->leafs = out;
874 loadmodel->numleafs = count;
876 for ( i=0 ; i<count ; i++, in++, out++)
878 for (j=0 ; j<3 ; j++)
880 out->minmaxs[j] = LittleShort (in->mins[j]);
881 out->minmaxs[3+j] = LittleShort (in->maxs[j]);
884 p = LittleLong(in->contents);
887 out->firstmarksurface = loadmodel->marksurfaces +
888 LittleShort(in->firstmarksurface);
889 out->nummarksurfaces = LittleShort(in->nummarksurfaces);
891 p = LittleLong(in->visofs);
893 out->compressed_vis = NULL;
895 out->compressed_vis = loadmodel->visdata + p;
898 for (j=0 ; j<4 ; j++)
899 out->ambient_sound_level[j] = in->ambient_level[j];
901 // gl underwater warp
902 // LordHavoc: disabled underwater warping
904 if (out->contents != CONTENTS_EMPTY)
906 for (j=0 ; j<out->nummarksurfaces ; j++)
907 out->firstmarksurface[j]->flags |= SURF_UNDERWATER;
918 void Mod_LoadClipnodes (lump_t *l)
920 dclipnode_t *in, *out;
924 in = (void *)(mod_base + l->fileofs);
925 if (l->filelen % sizeof(*in))
926 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
927 count = l->filelen / sizeof(*in);
928 out = Hunk_AllocName ( count*sizeof(*out), va("%s clipnodes", loadname));
930 loadmodel->clipnodes = out;
931 loadmodel->numclipnodes = count;
935 hull = &loadmodel->hulls[1];
936 hull->clipnodes = out;
937 hull->firstclipnode = 0;
938 hull->lastclipnode = count-1;
939 hull->planes = loadmodel->planes;
940 hull->clip_mins[0] = -16;
941 hull->clip_mins[1] = -16;
942 hull->clip_mins[2] = -36;
943 hull->clip_maxs[0] = 16;
944 hull->clip_maxs[1] = 16;
945 hull->clip_maxs[2] = 36;
947 hull = &loadmodel->hulls[2];
948 hull->clipnodes = out;
949 hull->firstclipnode = 0;
950 hull->lastclipnode = count-1;
951 hull->planes = loadmodel->planes;
952 hull->clip_mins[0] = -32;
953 hull->clip_mins[1] = -32;
954 hull->clip_mins[2] = -32;
955 hull->clip_maxs[0] = 32;
956 hull->clip_maxs[1] = 32;
957 hull->clip_maxs[2] = 32;
959 hull = &loadmodel->hulls[3];
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] = -18;
967 hull->clip_maxs[0] = 16;
968 hull->clip_maxs[1] = 16;
969 hull->clip_maxs[2] = 18;
973 hull = &loadmodel->hulls[1];
974 hull->clipnodes = out;
975 hull->firstclipnode = 0;
976 hull->lastclipnode = count-1;
977 hull->planes = loadmodel->planes;
978 hull->clip_mins[0] = -16;
979 hull->clip_mins[1] = -16;
980 hull->clip_mins[2] = -24;
981 hull->clip_maxs[0] = 16;
982 hull->clip_maxs[1] = 16;
983 hull->clip_maxs[2] = 32;
985 hull = &loadmodel->hulls[2];
986 hull->clipnodes = out;
987 hull->firstclipnode = 0;
988 hull->lastclipnode = count-1;
989 hull->planes = loadmodel->planes;
990 hull->clip_mins[0] = -32;
991 hull->clip_mins[1] = -32;
992 hull->clip_mins[2] = -24;
993 hull->clip_maxs[0] = 32;
994 hull->clip_maxs[1] = 32;
995 hull->clip_maxs[2] = 64;
998 for (i=0 ; i<count ; i++, out++, in++)
1000 out->planenum = LittleLong(in->planenum);
1001 out->children[0] = LittleShort(in->children[0]);
1002 out->children[1] = LittleShort(in->children[1]);
1003 if (out->children[0] >= count || out->children[1] >= count)
1004 Host_Error("Corrupt clipping hull (out of range child)\n");
1012 Duplicate the drawing hull structure as a clipping hull
1015 void Mod_MakeHull0 (void)
1017 mnode_t *in, *child;
1022 hull = &loadmodel->hulls[0];
1024 in = loadmodel->nodes;
1025 count = loadmodel->numnodes;
1026 out = Hunk_AllocName ( count*sizeof(*out), va("%s hull0", loadname));
1028 hull->clipnodes = out;
1029 hull->firstclipnode = 0;
1030 hull->lastclipnode = count-1;
1031 hull->planes = loadmodel->planes;
1033 for (i=0 ; i<count ; i++, out++, in++)
1035 out->planenum = in->plane - loadmodel->planes;
1036 for (j=0 ; j<2 ; j++)
1038 child = in->children[j];
1039 if (child->contents < 0)
1040 out->children[j] = child->contents;
1042 out->children[j] = child - loadmodel->nodes;
1049 Mod_LoadMarksurfaces
1052 void Mod_LoadMarksurfaces (lump_t *l)
1058 in = (void *)(mod_base + l->fileofs);
1059 if (l->filelen % sizeof(*in))
1060 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
1061 count = l->filelen / sizeof(*in);
1062 out = Hunk_AllocName ( count*sizeof(*out), va("%s marksurfaces", loadname));
1064 loadmodel->marksurfaces = out;
1065 loadmodel->nummarksurfaces = count;
1067 for ( i=0 ; i<count ; i++)
1069 j = LittleShort(in[i]);
1070 if (j >= loadmodel->numsurfaces)
1071 Host_Error ("Mod_ParseMarksurfaces: bad surface number");
1072 out[i] = loadmodel->surfaces + j;
1081 void Mod_LoadSurfedges (lump_t *l)
1086 in = (void *)(mod_base + l->fileofs);
1087 if (l->filelen % sizeof(*in))
1088 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
1089 count = l->filelen / sizeof(*in);
1090 out = Hunk_AllocName ( count*sizeof(*out), va("%s surfedges", loadname));
1092 loadmodel->surfedges = out;
1093 loadmodel->numsurfedges = count;
1095 for ( i=0 ; i<count ; i++)
1096 out[i] = LittleLong (in[i]);
1105 void Mod_LoadPlanes (lump_t *l)
1113 in = (void *)(mod_base + l->fileofs);
1114 if (l->filelen % sizeof(*in))
1115 Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
1116 count = l->filelen / sizeof(*in);
1117 out = Hunk_AllocName ( count*2*sizeof(*out), va("%s planes", loadname));
1119 loadmodel->planes = out;
1120 loadmodel->numplanes = count;
1122 for ( i=0 ; i<count ; i++, in++, out++)
1125 for (j=0 ; j<3 ; j++)
1127 out->normal[j] = LittleFloat (in->normal[j]);
1128 // if (out->normal[j] < 0)
1132 out->dist = LittleFloat (in->dist);
1133 out->type = LittleLong (in->type);
1134 // out->signbits = bits;
1135 BoxOnPlaneSideClassify(out);
1144 void Mod_LoadBrushModel (model_t *mod, void *buffer)
1150 loadmodel->type = mod_brush;
1152 header = (dheader_t *)buffer;
1154 i = LittleLong (header->version);
1155 if (i != BSPVERSION && i != 30)
1156 Host_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i or 30 (HalfLife))", mod->name, i, BSPVERSION);
1158 halflifebsp.value = hlbsp;
1160 // swap all the lumps
1161 mod_base = (byte *)header;
1163 for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
1164 ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
1168 // LordHavoc: had to move entity loading above everything to allow parsing various settings from worldspawn
1169 Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]);
1171 Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
1172 Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
1173 Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
1174 Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
1175 Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
1176 Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
1177 Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
1178 Mod_LoadFaces (&header->lumps[LUMP_FACES]);
1179 Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
1180 Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
1181 Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
1182 Mod_LoadNodes (&header->lumps[LUMP_NODES]);
1183 Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]);
1184 // Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]);
1185 Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
1189 mod->numframes = 2; // regular and alternate animation
1192 // set up the submodels (FIXME: this is confusing)
1194 for (i=0 ; i<mod->numsubmodels ; i++)
1196 bm = &mod->submodels[i];
1198 mod->hulls[0].firstclipnode = bm->headnode[0];
1199 for (j=1 ; j<MAX_MAP_HULLS ; j++)
1201 mod->hulls[j].firstclipnode = bm->headnode[j];
1202 mod->hulls[j].lastclipnode = mod->numclipnodes-1;
1205 mod->firstmodelsurface = bm->firstface;
1206 mod->nummodelsurfaces = bm->numfaces;
1208 VectorCopy (bm->maxs, mod->maxs);
1209 VectorCopy (bm->mins, mod->mins);
1211 mod->radius = RadiusFromBounds (mod->mins, mod->maxs);
1213 mod->numleafs = bm->visleafs;
1215 if (isworldmodel && i < (mod->numsubmodels-1)) // LordHavoc: only register submodels if it is the world (prevents bsp models from replacing world submodels)
1216 { // duplicate the basic information
1219 sprintf (name, "*%i", i+1);
1220 loadmodel = Mod_FindName (name);
1222 strcpy (loadmodel->name, name);