1377 lines
33 KiB
C
1377 lines
33 KiB
C
/*
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
// model_common.c -- model loading and caching
|
|
// 2001-12-28 Merged model functions by Maddes
|
|
|
|
// models are the only shared resource between a client and server running
|
|
// on the same machine.
|
|
|
|
#include "quakedef.h"
|
|
|
|
model_t *loadmodel;
|
|
char loadname[32]; // for hunk tags
|
|
|
|
byte mod_novis[MAX_MAP_LEAFS/8];
|
|
|
|
#ifdef GLQUAKE
|
|
cvar_t *gl_subdivide_size;
|
|
#endif
|
|
|
|
float fog_density, old_density, fade_time, fade_done, fog_red, fog_green, fog_blue, old_red, old_green, old_blue; // FOG
|
|
|
|
cvar_t *external_lit; // 2001-09-11 Colored lightning by LordHavoc/Sarcazm/Maddes
|
|
cvar_t *external_ent; // 2001-09-12 .ENT support by Maddes
|
|
cvar_t *external_vis; // 2001-12-28 .VIS support by Maddes
|
|
int lightingavailable; // leilei - point lighting, determines if our data is made available
|
|
int lightingcantbeavailable; // determines if we can't make this available (stripped lights/not enough lights)
|
|
// 2001-09-18 New cvar system by Maddes (Init) start
|
|
/*
|
|
===============
|
|
Mod_Init_Cvars
|
|
===============
|
|
*/
|
|
void Mod_Init_Cvars (void)
|
|
{
|
|
#ifdef GLQUAKE
|
|
gl_subdivide_size = Cvar_Get ("gl_subdivide_size", "128", CVAR_ARCHIVE|CVAR_ORIGINAL);
|
|
#endif
|
|
|
|
// 2001-09-11 Colored lightning by LordHavoc/Sarcazm/Maddes start
|
|
external_lit = Cvar_Get ("external_lit", "1", CVAR_NONE);
|
|
Cvar_SetRangecheck (external_lit, Cvar_RangecheckBool, 0, 1);
|
|
Cvar_Set(external_lit, external_lit->string); // do rangecheck
|
|
// 2001-09-11 Colored lightning by LordHavoc/Sarcazm/Maddes end
|
|
|
|
// 2001-09-12 .ENT support by Maddes start
|
|
external_ent = Cvar_Get ("external_ent", "1", CVAR_NONE);
|
|
Cvar_SetRangecheck (external_ent, Cvar_RangecheckBool, 0, 1);
|
|
Cvar_Set(external_ent, external_ent->string); // do rangecheck
|
|
// 2001-09-12 .ENT support by Maddes end
|
|
|
|
// 2001-12-28 .VIS support by Maddes start
|
|
external_vis = Cvar_Get ("external_vis", "1", CVAR_NONE);
|
|
Cvar_SetRangecheck (external_vis, Cvar_RangecheckBool, 0, 1);
|
|
Cvar_Set(external_vis, external_vis->string); // do rangecheck
|
|
// 2001-12-28 .VIS support by Maddes end
|
|
}
|
|
// 2001-09-18 New cvar system by Maddes (Init) end
|
|
|
|
/*
|
|
===============
|
|
Mod_Init
|
|
===============
|
|
*/
|
|
void Mod_Init (void)
|
|
{
|
|
// 2001-09-18 New cvar system by Maddes (Init) start
|
|
/*
|
|
#ifdef GLQUAKE
|
|
gl_subdivide_size = Cvar_Get ("gl_subdivide_size", "128", CVAR_ARCHIVE|CVAR_ORIGINAL);
|
|
#endif
|
|
|
|
// 2001-09-11 Colored lightning by LordHavoc/Sarcazm/Maddes start
|
|
external_lit = Cvar_Get ("external_lit", "1", CVAR_NONE);
|
|
Cvar_SetRangecheck (external_lit, Cvar_RangecheckBool, 0, 1);
|
|
Cvar_Set(external_lit, external_lit->string); // do rangecheck
|
|
// 2001-09-11 Colored lightning by LordHavoc/Sarcazm/Maddes end
|
|
|
|
// 2001-09-12 .ENT support by Maddes start
|
|
external_ent = Cvar_Get ("external_ent", "1", CVAR_NONE);
|
|
Cvar_SetRangecheck (external_ent, Cvar_RangecheckBool, 0, 1);
|
|
Cvar_Set(external_ent, external_ent->string); // do rangecheck
|
|
// 2001-09-12 .ENT support by Maddes end
|
|
*/
|
|
// 2001-09-18 New cvar system by Maddes (Init) end
|
|
|
|
memset (mod_novis, 0xff, sizeof(mod_novis));
|
|
|
|
// THE_precache_model("prog3/fx.spr");
|
|
}
|
|
|
|
/*
|
|
===============
|
|
Mod_Extradata
|
|
|
|
Caches the data if needed
|
|
===============
|
|
*/
|
|
void *Mod_Extradata (model_t *mod)
|
|
{
|
|
void *r;
|
|
|
|
r = Cache_Check (&mod->cache);
|
|
if (r)
|
|
return r;
|
|
|
|
Mod_LoadModel (mod, true);
|
|
|
|
if (!mod->cache.data)
|
|
Sys_Error ("Mod_Extradata: caching failed");
|
|
return mod->cache.data;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
Mod_PointInLeaf
|
|
===============
|
|
*/
|
|
mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
|
|
{
|
|
mnode_t *node;
|
|
float d;
|
|
mplane_t *plane;
|
|
|
|
if (!model || !model->nodes)
|
|
Sys_Error ("Mod_PointInLeaf: bad model");
|
|
|
|
node = model->nodes;
|
|
while (1)
|
|
{
|
|
if (node->contents < 0)
|
|
return (mleaf_t *)node;
|
|
plane = node->plane;
|
|
d = DotProduct (p,plane->normal) - plane->dist;
|
|
if (d > 0)
|
|
node = node->children[0];
|
|
else
|
|
node = node->children[1];
|
|
}
|
|
|
|
return NULL; // never reached
|
|
}
|
|
|
|
|
|
/*
|
|
===================
|
|
Mod_DecompressVis
|
|
===================
|
|
*/
|
|
byte *Mod_DecompressVis (byte *in, model_t *model)
|
|
{
|
|
static byte decompressed[MAX_MAP_LEAFS/8];
|
|
int c;
|
|
byte *out;
|
|
int row;
|
|
|
|
row = (model->numleafs+7)>>3;
|
|
out = decompressed;
|
|
|
|
#if 0
|
|
memcpy (out, in, row);
|
|
#else
|
|
if (!in)
|
|
{ // no vis info, so make all visible
|
|
while (row)
|
|
{
|
|
*out++ = 0xff;
|
|
row--;
|
|
}
|
|
return decompressed;
|
|
}
|
|
|
|
do
|
|
{
|
|
if (*in)
|
|
{
|
|
*out++ = *in++;
|
|
continue;
|
|
}
|
|
|
|
c = in[1];
|
|
in += 2;
|
|
while (c)
|
|
{
|
|
*out++ = 0;
|
|
c--;
|
|
}
|
|
} while (out - decompressed < row);
|
|
#endif
|
|
|
|
return decompressed;
|
|
}
|
|
|
|
byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
|
|
{
|
|
if (leaf == model->leafs)
|
|
return mod_novis;
|
|
return Mod_DecompressVis (leaf->compressed_vis, model);
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Mod_ForName
|
|
|
|
Loads in a model for the given name
|
|
==================
|
|
*/
|
|
model_t *Mod_ForName (char *name, qboolean crash)
|
|
{
|
|
model_t *mod;
|
|
|
|
mod = Mod_FindName (name);
|
|
|
|
return Mod_LoadModel (mod, crash);
|
|
}
|
|
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
BRUSHMODEL LOADING
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
byte *mod_base;
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadVisibility
|
|
=================
|
|
*/
|
|
void Mod_LoadVisibility (lump_t *l)
|
|
{
|
|
if (!l->filelen)
|
|
{
|
|
loadmodel->visdata = NULL;
|
|
return;
|
|
}
|
|
// 2001-12-28 .VIS support by Maddes start
|
|
// loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname);
|
|
loadmodel->visdata = Hunk_AllocName ( l->filelen, "INT_VIS");
|
|
// 2001-12-28 .VIS support by Maddes end
|
|
memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadEntities
|
|
=================
|
|
*/
|
|
void Mod_LoadEntities (lump_t *l, loadedfile_t *brush_fileinfo) // 2001-09-12 .ENT support by Maddes
|
|
{
|
|
// 2001-09-12 .ENT support by Maddes start
|
|
char entfilename[1024];
|
|
loadedfile_t *fileinfo;
|
|
searchpath_t *s_check;
|
|
|
|
loadmodel->entities = NULL;
|
|
|
|
if (external_ent->value)
|
|
{
|
|
// check for a .ENT file
|
|
strcpy(entfilename, loadmodel->name);
|
|
COM_StripExtension(entfilename, entfilename);
|
|
strcat(entfilename, ".ent");
|
|
|
|
fileinfo = COM_LoadHunkFile (entfilename);
|
|
if (fileinfo && fileinfo->filelen)
|
|
{
|
|
// .ENT file only allowed from same directory of map file or another directory before in the searchpath
|
|
s_check = COM_GetDirSearchPath(brush_fileinfo->path); // get last searchpath of map directory
|
|
while ( (s_check = s_check->next) ) // next searchpath
|
|
{
|
|
if (s_check == fileinfo->path) // found .ENT searchpath = after map directory
|
|
{
|
|
Con_DPrintf("%s not allowed from %s as map is from %s\n", entfilename, fileinfo->path->pack ? fileinfo->path->pack->filename : fileinfo->path->filename, brush_fileinfo->path->pack ? brush_fileinfo->path->pack->filename : brush_fileinfo->path->filename);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!s_check) // .ENT searchpath not found = before map directory
|
|
{
|
|
Con_DPrintf("%s loaded from %s\n", entfilename, fileinfo->path->pack ? fileinfo->path->pack->filename : fileinfo->path->filename);
|
|
loadmodel->entities = fileinfo->data;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// no .ENT found, use the original entity list
|
|
}
|
|
// 2001-09-12 .ENT support by Maddes end
|
|
|
|
if (!l->filelen)
|
|
{
|
|
loadmodel->entities = NULL;
|
|
return;
|
|
}
|
|
// 2001-09-12 .ENT support by Maddes start
|
|
// loadmodel->entities = Hunk_AllocName ( l->filelen, loadname);
|
|
loadmodel->entities = Hunk_AllocName ( l->filelen, "INT_ENT");
|
|
// 2001-09-12 .ENT support by Maddes end
|
|
memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen);
|
|
CL_ParseEntityLump(loadmodel->entities); // Tomaz - Parse Data
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadVertexes
|
|
=================
|
|
*/
|
|
void Mod_LoadVertexes (lump_t *l)
|
|
{
|
|
dvertex_t *in;
|
|
mvertex_t *out;
|
|
int i, count;
|
|
|
|
in = (void *)(mod_base + l->fileofs);
|
|
if (l->filelen % sizeof(*in))
|
|
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
|
count = l->filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( count*sizeof(*out), loadname);
|
|
|
|
loadmodel->vertexes = out;
|
|
loadmodel->numvertexes = count;
|
|
|
|
for ( i=0 ; i<count ; i++, in++, out++)
|
|
{
|
|
out->position[0] = LittleFloat (in->point[0]);
|
|
out->position[1] = LittleFloat (in->point[1]);
|
|
out->position[2] = LittleFloat (in->point[2]);
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadSubmodels
|
|
=================
|
|
*/
|
|
void Mod_LoadSubmodels (lump_t *l)
|
|
{
|
|
dmodel_t *in;
|
|
dmodel_t *out;
|
|
int i, j, count;
|
|
|
|
in = (void *)(mod_base + l->fileofs);
|
|
if (l->filelen % sizeof(*in))
|
|
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
|
count = l->filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( count*sizeof(*out), loadname);
|
|
|
|
loadmodel->submodels = out;
|
|
loadmodel->numsubmodels = count;
|
|
|
|
for ( i=0 ; i<count ; i++, in++, out++)
|
|
{
|
|
// leilei - unrolled
|
|
{ // spread the mins / maxs by a pixel
|
|
out->mins[0] = LittleFloat (in->mins[0]) - 1;
|
|
out->maxs[0] = LittleFloat (in->maxs[0]) + 1;
|
|
out->origin[0] = LittleFloat (in->origin[0]);
|
|
|
|
out->mins[1] = LittleFloat (in->mins[1]) - 1;
|
|
out->maxs[1] = LittleFloat (in->maxs[1]) + 1;
|
|
out->origin[1] = LittleFloat (in->origin[1]);
|
|
|
|
out->mins[2] = LittleFloat (in->mins[2]) - 1;
|
|
out->maxs[2] = LittleFloat (in->maxs[2]) + 1;
|
|
out->origin[2] = LittleFloat (in->origin[2]);
|
|
}
|
|
for (j=0 ; j<MAX_MAP_HULLS ; j++)
|
|
out->headnode[j] = LittleLong (in->headnode[j]);
|
|
out->visleafs = LittleLong (in->visleafs);
|
|
out->firstface = LittleLong (in->firstface);
|
|
out->numfaces = LittleLong (in->numfaces);
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadEdges
|
|
=================
|
|
*/
|
|
void Mod_LoadEdges (lump_t *l)
|
|
{
|
|
dedge_t *in;
|
|
medge_t *out;
|
|
int i, count;
|
|
|
|
in = (void *)(mod_base + l->fileofs);
|
|
if (l->filelen % sizeof(*in))
|
|
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
|
count = l->filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname);
|
|
|
|
loadmodel->edges = out;
|
|
loadmodel->numedges = count;
|
|
|
|
for ( i=0 ; i<count ; i++, in++, out++)
|
|
{
|
|
out->v[0] = (unsigned short)LittleShort(in->v[0]);
|
|
out->v[1] = (unsigned short)LittleShort(in->v[1]);
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadTexinfo
|
|
=================
|
|
*/
|
|
void Mod_LoadTexinfo (lump_t *l)
|
|
{
|
|
texinfo_t *in;
|
|
mtexinfo_t *out;
|
|
int i, j, count;
|
|
int miptex;
|
|
float len1, len2;
|
|
|
|
in = (void *)(mod_base + l->fileofs);
|
|
if (l->filelen % sizeof(*in))
|
|
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
|
count = l->filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( count*sizeof(*out), loadname);
|
|
|
|
loadmodel->texinfo = out;
|
|
loadmodel->numtexinfo = count;
|
|
|
|
for ( i=0 ; i<count ; i++, in++, out++)
|
|
{
|
|
for (j=0 ; j<8 ; j++)
|
|
out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
|
|
len1 = Length (out->vecs[0]);
|
|
len2 = Length (out->vecs[1]);
|
|
len1 = (len1 + len2)/2;
|
|
if (len1 < 0.32)
|
|
out->mipadjust = 4;
|
|
else if (len1 < 0.49)
|
|
out->mipadjust = 3;
|
|
else if (len1 < 0.99)
|
|
out->mipadjust = 2;
|
|
else
|
|
out->mipadjust = 1;
|
|
#if 0
|
|
if (len1 + len2 < 0.001)
|
|
out->mipadjust = 1; // don't crash
|
|
else
|
|
out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 );
|
|
#endif
|
|
|
|
miptex = LittleLong (in->miptex);
|
|
out->flags = LittleLong (in->flags);
|
|
|
|
if (!loadmodel->textures)
|
|
{
|
|
out->texture = r_notexture_mip; // checkerboard texture
|
|
out->flags = 0;
|
|
}
|
|
else
|
|
{
|
|
if (miptex >= loadmodel->numtextures)
|
|
Sys_Error ("miptex >= loadmodel->numtextures");
|
|
out->texture = loadmodel->textures[miptex];
|
|
if (!out->texture)
|
|
{
|
|
out->texture = r_notexture_mip; // texture not found
|
|
out->flags = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_SetParent
|
|
=================
|
|
*/
|
|
void Mod_SetParent (mnode_t *node, mnode_t *parent)
|
|
{
|
|
node->parent = parent;
|
|
if (node->contents < 0)
|
|
return;
|
|
Mod_SetParent (node->children[0], node);
|
|
Mod_SetParent (node->children[1], node);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadNodes
|
|
=================
|
|
*/
|
|
void Mod_LoadNodes (lump_t *l)
|
|
{
|
|
int i, j, count, p;
|
|
dnode_t *in;
|
|
mnode_t *out;
|
|
|
|
in = (void *)(mod_base + l->fileofs);
|
|
if (l->filelen % sizeof(*in))
|
|
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
|
count = l->filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( count*sizeof(*out), loadname);
|
|
|
|
loadmodel->nodes = out;
|
|
loadmodel->numnodes = count;
|
|
|
|
for ( i=0 ; i<count ; i++, in++, out++)
|
|
{
|
|
// for (j=0 ; j<3 ; j++) // l
|
|
{
|
|
out->minmaxs[0] = LittleShort (in->mins[0]);
|
|
out->minmaxs[3+0] = LittleShort (in->maxs[0]);
|
|
|
|
out->minmaxs[1] = LittleShort (in->mins[1]);
|
|
out->minmaxs[3+1] = LittleShort (in->maxs[1]);
|
|
|
|
out->minmaxs[2] = LittleShort (in->mins[2]);
|
|
out->minmaxs[3+2] = LittleShort (in->maxs[2]);
|
|
}
|
|
|
|
p = LittleLong(in->planenum);
|
|
out->plane = loadmodel->planes + p;
|
|
|
|
out->firstsurface = LittleShort (in->firstface);
|
|
out->numsurfaces = LittleShort (in->numfaces);
|
|
|
|
for (j=0 ; j<2 ; j++)
|
|
{
|
|
p = LittleShort (in->children[j]);
|
|
if (p >= 0)
|
|
out->children[j] = loadmodel->nodes + p;
|
|
else
|
|
out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
|
|
}
|
|
}
|
|
|
|
Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
|
|
}
|
|
|
|
void Mod_ProcessLeafs (dleaf_t *in, int filelen); // 2001-12-28 .VIS support by Maddes
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadLeafs
|
|
=================
|
|
*/
|
|
void Mod_LoadLeafs (lump_t *l)
|
|
{
|
|
dleaf_t *in;
|
|
// 2001-12-28 .VIS support by Maddes start
|
|
/*
|
|
mleaf_t *out;
|
|
int i, j, count, p;
|
|
*/
|
|
// 2001-12-28 .VIS support by Maddes end
|
|
|
|
in = (void *)(mod_base + l->fileofs);
|
|
// 2001-12-28 .VIS support by Maddes start
|
|
/*
|
|
if (l->filelen % sizeof(*in))
|
|
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
|
count = l->filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( count*sizeof(*out), loadname);
|
|
*/
|
|
|
|
Mod_ProcessLeafs (in, l->filelen);
|
|
}
|
|
|
|
void Mod_ProcessLeafs (dleaf_t *in, int filelen)
|
|
{
|
|
mleaf_t *out;
|
|
int i, j, count, p;
|
|
|
|
if (filelen % sizeof(*in))
|
|
Sys_Error ("Mod_ProcessLeafs: funny lump size in %s", loadmodel->name);
|
|
count = filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( count*sizeof(*out), "USE_LEAF");
|
|
// 2001-12-28 .VIS support by Maddes end
|
|
|
|
loadmodel->leafs = out;
|
|
loadmodel->numleafs = count;
|
|
|
|
for ( i=0 ; i<count ; i++, in++, out++)
|
|
{
|
|
for (j=0 ; j<3 ; j++)
|
|
{
|
|
out->minmaxs[j] = LittleShort (in->mins[j]);
|
|
out->minmaxs[3+j] = LittleShort (in->maxs[j]);
|
|
}
|
|
|
|
p = LittleLong(in->contents);
|
|
out->contents = p;
|
|
|
|
out->firstmarksurface = loadmodel->marksurfaces +
|
|
LittleShort(in->firstmarksurface);
|
|
out->nummarksurfaces = LittleShort(in->nummarksurfaces);
|
|
|
|
p = LittleLong(in->visofs);
|
|
if (p == -1)
|
|
out->compressed_vis = NULL;
|
|
else
|
|
out->compressed_vis = loadmodel->visdata + p;
|
|
out->efrags = NULL;
|
|
|
|
for (j=0 ; j<4 ; j++)
|
|
out->ambient_sound_level[j] = in->ambient_level[j];
|
|
|
|
#ifdef GLQUAKE
|
|
// gl underwater warp
|
|
if (out->contents != CONTENTS_EMPTY)
|
|
{
|
|
for (j=0 ; j<out->nummarksurfaces ; j++)
|
|
out->firstmarksurface[j]->flags |= SURF_UNDERWATER;
|
|
}
|
|
#else
|
|
// software underwater warp
|
|
// TODO: Caustics
|
|
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadClipnodes
|
|
=================
|
|
*/
|
|
void Mod_LoadClipnodes (lump_t *l)
|
|
{
|
|
dclipnode_t *in, *out;
|
|
int i, count;
|
|
hull_t *hull;
|
|
|
|
in = (void *)(mod_base + l->fileofs);
|
|
if (l->filelen % sizeof(*in))
|
|
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
|
count = l->filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( count*sizeof(*out), loadname);
|
|
|
|
loadmodel->clipnodes = out;
|
|
loadmodel->numclipnodes = count;
|
|
|
|
hull = &loadmodel->hulls[1];
|
|
hull->clipnodes = out;
|
|
hull->firstclipnode = 0;
|
|
hull->lastclipnode = count-1;
|
|
hull->planes = loadmodel->planes;
|
|
hull->clip_mins[0] = -16;
|
|
hull->clip_mins[1] = -16;
|
|
hull->clip_mins[2] = -24;
|
|
hull->clip_maxs[0] = 16;
|
|
hull->clip_maxs[1] = 16;
|
|
hull->clip_maxs[2] = 32;
|
|
|
|
hull = &loadmodel->hulls[2];
|
|
hull->clipnodes = out;
|
|
hull->firstclipnode = 0;
|
|
hull->lastclipnode = count-1;
|
|
hull->planes = loadmodel->planes;
|
|
hull->clip_mins[0] = -32;
|
|
hull->clip_mins[1] = -32;
|
|
hull->clip_mins[2] = -24;
|
|
hull->clip_maxs[0] = 32;
|
|
hull->clip_maxs[1] = 32;
|
|
hull->clip_maxs[2] = 64;
|
|
|
|
for (i=0 ; i<count ; i++, out++, in++)
|
|
{
|
|
out->planenum = LittleLong(in->planenum);
|
|
out->children[0] = LittleShort(in->children[0]);
|
|
out->children[1] = LittleShort(in->children[1]);
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_MakeHull0
|
|
|
|
Deplicate the drawing hull structure as a clipping hull
|
|
=================
|
|
*/
|
|
void Mod_MakeHull0 (void)
|
|
{
|
|
mnode_t *in, *child;
|
|
dclipnode_t *out;
|
|
int i, j, count;
|
|
hull_t *hull;
|
|
|
|
hull = &loadmodel->hulls[0];
|
|
|
|
in = loadmodel->nodes;
|
|
count = loadmodel->numnodes;
|
|
out = Hunk_AllocName ( count*sizeof(*out), loadname);
|
|
|
|
hull->clipnodes = out;
|
|
hull->firstclipnode = 0;
|
|
hull->lastclipnode = count-1;
|
|
hull->planes = loadmodel->planes;
|
|
|
|
for (i=0 ; i<count ; i++, out++, in++)
|
|
{
|
|
out->planenum = in->plane - loadmodel->planes;
|
|
for (j=0 ; j<2 ; j++)
|
|
{
|
|
child = in->children[j];
|
|
if (child->contents < 0)
|
|
out->children[j] = child->contents;
|
|
else
|
|
out->children[j] = child - loadmodel->nodes;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadMarksurfaces
|
|
=================
|
|
*/
|
|
void Mod_LoadMarksurfaces (lump_t *l)
|
|
{
|
|
int i, j, count;
|
|
short *in;
|
|
msurface_t **out;
|
|
|
|
in = (void *)(mod_base + l->fileofs);
|
|
if (l->filelen % sizeof(*in))
|
|
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
|
count = l->filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( count*sizeof(*out), loadname);
|
|
|
|
loadmodel->marksurfaces = out;
|
|
loadmodel->nummarksurfaces = count;
|
|
|
|
for ( i=0 ; i<count ; i++)
|
|
{
|
|
j = LittleShort(in[i]);
|
|
if (j >= loadmodel->numsurfaces)
|
|
Sys_Error ("Mod_ParseMarksurfaces: bad surface number");
|
|
out[i] = loadmodel->surfaces + j;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadSurfedges
|
|
=================
|
|
*/
|
|
void Mod_LoadSurfedges (lump_t *l)
|
|
{
|
|
int i, count;
|
|
int *in, *out;
|
|
|
|
in = (void *)(mod_base + l->fileofs);
|
|
if (l->filelen % sizeof(*in))
|
|
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
|
count = l->filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( count*sizeof(*out), loadname);
|
|
|
|
loadmodel->surfedges = out;
|
|
loadmodel->numsurfedges = count;
|
|
|
|
for ( i=0 ; i<count ; i++)
|
|
out[i] = LittleLong (in[i]);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadPlanes
|
|
=================
|
|
*/
|
|
void Mod_LoadPlanes (lump_t *l)
|
|
{
|
|
int i, j;
|
|
mplane_t *out;
|
|
dplane_t *in;
|
|
int count;
|
|
int bits;
|
|
|
|
in = (void *)(mod_base + l->fileofs);
|
|
if (l->filelen % sizeof(*in))
|
|
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
|
count = l->filelen / sizeof(*in);
|
|
out = Hunk_AllocName ( count*2*sizeof(*out), loadname);
|
|
|
|
loadmodel->planes = out;
|
|
loadmodel->numplanes = count;
|
|
|
|
for ( i=0 ; i<count ; i++, in++, out++)
|
|
{
|
|
bits = 0;
|
|
for (j=0 ; j<3 ; j++)
|
|
{
|
|
out->normal[j] = LittleFloat (in->normal[j]);
|
|
if (out->normal[j] < 0)
|
|
bits |= 1<<j;
|
|
}
|
|
|
|
out->dist = LittleFloat (in->dist);
|
|
out->type = LittleLong (in->type);
|
|
out->signbits = bits;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
RadiusFromBounds
|
|
=================
|
|
*/
|
|
float RadiusFromBounds (vec3_t mins, vec3_t maxs)
|
|
{
|
|
int i;
|
|
vec3_t corner;
|
|
|
|
for (i=0 ; i<3 ; i++)
|
|
{
|
|
corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
|
|
}
|
|
|
|
return Length (corner);
|
|
}
|
|
|
|
// 2001-12-28 .VIS support by Maddes start
|
|
/*
|
|
=================
|
|
Mod_LoadExternalVisibility
|
|
=================
|
|
*/
|
|
void Mod_LoadExternalVisibility (int fhandle)
|
|
{
|
|
long filelen;
|
|
|
|
// get visibility data length
|
|
filelen = 0;
|
|
Sys_FileRead (fhandle, &filelen, 4);
|
|
filelen = LittleLong(filelen);
|
|
|
|
Con_Printf("...%i bytes visibility data\n", filelen);
|
|
|
|
// load visibility data
|
|
if (!filelen)
|
|
{
|
|
loadmodel->visdata = NULL;
|
|
return;
|
|
}
|
|
loadmodel->visdata = Hunk_AllocName ( filelen, "EXT_VIS");
|
|
Sys_FileRead (fhandle, loadmodel->visdata, filelen);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadExternalLeafs
|
|
=================
|
|
*/
|
|
void Mod_LoadExternalLeafs (int fhandle)
|
|
{
|
|
dleaf_t *in;
|
|
long filelen;
|
|
|
|
// get leaf data length
|
|
filelen = 0;
|
|
Sys_FileRead (fhandle, &filelen, 4);
|
|
filelen = LittleLong(filelen);
|
|
|
|
Con_Printf("...%i bytes leaf data\n", filelen);
|
|
|
|
// load leaf data
|
|
if (!filelen)
|
|
{
|
|
loadmodel->leafs = NULL;
|
|
loadmodel->numleafs = 0;
|
|
return;
|
|
}
|
|
in = Hunk_AllocName (filelen, "EXT_LEAF");
|
|
Sys_FileRead (fhandle, in, filelen);
|
|
|
|
Mod_ProcessLeafs (in, filelen);
|
|
}
|
|
|
|
int Mod_FindExternalVIS (loadedfile_t *brush_fileinfo)
|
|
{
|
|
char visfilename[1024];
|
|
int fhandle;
|
|
int len, i, pos;
|
|
searchpath_t *s_vis;
|
|
vispatch_t header;
|
|
char mapname[VISPATCH_MAPNAME_LENGTH+5]; // + ".vis" + EoS
|
|
|
|
fhandle = -1;
|
|
|
|
if (external_vis->value)
|
|
{
|
|
// check for a .VIS file
|
|
strcpy(visfilename, loadmodel->name);
|
|
COM_StripExtension(visfilename, visfilename);
|
|
strcat(visfilename, ".vis");
|
|
|
|
len = COM_OpenFile (visfilename, &fhandle, &s_vis);
|
|
if (fhandle == -1) // check for a .VIS file with map's directory name (e.g. ID1.VIS)
|
|
{
|
|
strcpy(visfilename, "maps/");
|
|
strcat(visfilename, COM_SkipPath(brush_fileinfo->path->filename));
|
|
strcat(visfilename, ".vis");
|
|
len = COM_OpenFile (visfilename, &fhandle, &s_vis);
|
|
}
|
|
|
|
if (fhandle >= 0)
|
|
{
|
|
// check file for size
|
|
if (len <= 0)
|
|
{
|
|
COM_CloseFile(fhandle);
|
|
fhandle = -1;
|
|
}
|
|
}
|
|
|
|
if (fhandle >= 0)
|
|
{
|
|
// search map in visfile
|
|
strncpy(mapname, loadname, VISPATCH_MAPNAME_LENGTH);
|
|
mapname[VISPATCH_MAPNAME_LENGTH] = 0;
|
|
strcat(mapname, ".bsp");
|
|
|
|
pos = 0;
|
|
while ((i = Sys_FileRead (fhandle, &header, sizeof(struct vispatch_s))) == sizeof(struct vispatch_s))
|
|
{
|
|
header.filelen = LittleLong(header.filelen);
|
|
|
|
pos += i;
|
|
|
|
if (!Q_strncasecmp (header.mapname, mapname, VISPATCH_MAPNAME_LENGTH)) // found
|
|
{
|
|
break;
|
|
}
|
|
|
|
pos += header.filelen;
|
|
|
|
Sys_FileSeek(fhandle, pos);
|
|
}
|
|
|
|
if (i != sizeof(struct vispatch_s))
|
|
{
|
|
COM_CloseFile(fhandle);
|
|
fhandle = -1;
|
|
}
|
|
}
|
|
|
|
if (fhandle >= 0)
|
|
{
|
|
Con_DPrintf("%s for %s loaded from %s\n", visfilename, mapname, s_vis->pack ? s_vis->pack->filename : s_vis->filename);
|
|
}
|
|
}
|
|
|
|
return fhandle;
|
|
}
|
|
// 2001-12-28 .VIS support by Maddes end
|
|
|
|
/*
|
|
=================
|
|
Mod_LoadBrushModel
|
|
=================
|
|
*/
|
|
extern cvar_t *r_coloredlights;
|
|
extern cvar_t *r_lowworld;
|
|
extern cvar_t *r_overbrightBits;
|
|
extern cvar_t *r_fullbrights;
|
|
extern cvar_t *r_dither;
|
|
extern int ditheredrend;
|
|
extern int nolookups;
|
|
extern int fogcolr, fogcolg, fogcolb, fogthick, fogrange; // leilei - fog
|
|
|
|
/*
|
|
=============
|
|
Fog_ParseWorldspawn
|
|
|
|
called at map load
|
|
|
|
from FITZQUAKE!
|
|
=============
|
|
*/
|
|
void Fog_ParseWorldspawn (void)
|
|
{
|
|
char key[128], value[4096];
|
|
char *data;
|
|
|
|
//initially no fog
|
|
fog_density = 0.0;
|
|
old_density = 0.0;
|
|
fade_time = 0.0;
|
|
fade_done = 0.0;
|
|
|
|
// default fog settings
|
|
fogthick = 0;
|
|
fogcolr = 0.3 * 255;
|
|
fogcolg = 0.3 * 255;
|
|
fogcolb = 0.3 * 255;
|
|
// leilei - fog test (Force pink fog)
|
|
/* fogrange = 2;
|
|
fogcolr = 128;
|
|
fogcolg = 28;
|
|
fogcolb = 128;
|
|
fogthick = 150;
|
|
foguse = 1;
|
|
return;*/
|
|
data = COM_Parse(cl.worldmodel->entities);
|
|
if (!data)
|
|
return; // error
|
|
if (com_token[0] != '{')
|
|
return; // error
|
|
while (1)
|
|
{
|
|
data = COM_Parse(data);
|
|
if (!data)
|
|
return; // error
|
|
if (com_token[0] == '}')
|
|
break; // end of worldspawn
|
|
if (com_token[0] == '_')
|
|
strcpy(key, com_token + 1);
|
|
else
|
|
strcpy(key, com_token);
|
|
while (key[strlen(key)-1] == ' ') // remove trailing spaces
|
|
key[strlen(key)-1] = 0;
|
|
data = COM_Parse(data);
|
|
if (!data)
|
|
return; // error
|
|
strcpy(value, com_token);
|
|
|
|
if (!strcmp("fog", key))
|
|
{
|
|
sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
|
|
}
|
|
}
|
|
if (!fog_red){
|
|
// Con_Printf("Incomplete fog key! Fog DISABLED!!! (%f %f %f %f)\n", fog_density, fog_red, fog_green, fog_blue);
|
|
fog_red = 0;
|
|
fog_green = 0;
|
|
fog_blue = 0; // assume the mapper screwed up totally and gave us only density :(
|
|
fogenabled = 0;
|
|
|
|
return;
|
|
}
|
|
fogcolr = fog_red * 256;
|
|
fogcolg = fog_green * 256;
|
|
fogcolb = fog_blue * 256;
|
|
fogrange = 2;
|
|
fogthick = fog_density * 1600; // slightly sad attempt to match DirectQ
|
|
if (fogthick)
|
|
fogenabled = 1;
|
|
else
|
|
fogenabled = 0;
|
|
}
|
|
|
|
|
|
void FogStuffs (void){
|
|
if (fogthick){
|
|
fogenabled = 1;
|
|
}
|
|
else {
|
|
fogenabled = 0;
|
|
return;
|
|
}
|
|
// Sys_Error("YEA");
|
|
|
|
if (foguse)
|
|
FogTableRefresh();
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
=============
|
|
Fog_FogCommand_f
|
|
|
|
handle the 'fog' console command
|
|
=============
|
|
*/
|
|
|
|
|
|
/*
|
|
=============
|
|
Fog_Update
|
|
|
|
update internal variables
|
|
=============
|
|
*/
|
|
void Fog_Update (float density, float red, float green, float blue, float time)
|
|
{
|
|
//save previous settings for fade
|
|
if (time > 0)
|
|
{
|
|
//check for a fade in progress
|
|
if (fade_done > cl.time)
|
|
{
|
|
float f, d;
|
|
|
|
f = (fade_done - cl.time) / fade_time;
|
|
old_density = f * old_density + (1.0 - f) * fog_density;
|
|
old_red = f * old_red + (1.0 - f) * fog_red;
|
|
old_green = f * old_green + (1.0 - f) * fog_green;
|
|
old_blue = f * old_blue + (1.0 - f) * fog_blue;
|
|
}
|
|
else
|
|
{
|
|
old_density = fog_density;
|
|
old_red = fog_red;
|
|
old_green = fog_green;
|
|
old_blue = fog_blue;
|
|
}
|
|
}
|
|
|
|
fog_density = density;
|
|
fog_red = red;
|
|
fog_green = green;
|
|
fog_blue = blue;
|
|
fade_time = time;
|
|
fade_done = cl.time + time;
|
|
|
|
fogcolr = fog_red * 255;
|
|
fogcolg = fog_green * 255;
|
|
fogcolb = fog_blue * 255;
|
|
fogrange = 2;
|
|
fogthick = fog_density * 1600; // slightly sad attempt to match DirectQ
|
|
if (fogthick)
|
|
fogenabled = 1;
|
|
else
|
|
fogenabled = 0;
|
|
|
|
if (fogcolr > 254) fogcolr = 254;
|
|
if (fogcolg > 254) fogcolg = 254;
|
|
if (fogcolb > 254) fogcolb = 254;
|
|
if (fogcolr < 0) fogcolr = 0;
|
|
if (fogcolg < 0) fogcolg = 0;
|
|
if (fogcolb < 0) fogcolb = 0;
|
|
// check if we got new colors...
|
|
// if (fog_red != old_red || fog_blue != old_blue || fog_green != old_green)
|
|
FogTableRefresh();
|
|
}
|
|
|
|
|
|
void Fog_FogCommand_f (void)
|
|
{
|
|
switch (Cmd_Argc())
|
|
{
|
|
default:
|
|
case 1:
|
|
Con_Printf("usage:\n");
|
|
Con_Printf(" fog <density>\n");
|
|
Con_Printf(" fog <red> <green> <blue>\n");
|
|
Con_Printf(" fog <density> <red> <green> <blue>\n");
|
|
Con_Printf("current values:\n");
|
|
Con_Printf(" \"density\" is \"%f\"\n", fog_density);
|
|
Con_Printf(" \"red\" is \"%f\"\n", fog_red);
|
|
Con_Printf(" \"green\" is \"%f\"\n", fog_green);
|
|
Con_Printf(" \"blue\" is \"%f\"\n", fog_blue);
|
|
break;
|
|
case 2:
|
|
Fog_Update(max(0.0, atof(Cmd_Argv(1))),
|
|
fog_red,
|
|
fog_green,
|
|
fog_blue,
|
|
0.0);
|
|
break;
|
|
case 3: //TEST
|
|
Fog_Update(max(0.0, atof(Cmd_Argv(1))),
|
|
fog_red,
|
|
fog_green,
|
|
fog_blue,
|
|
atof(Cmd_Argv(2)));
|
|
break;
|
|
case 4:
|
|
Fog_Update(fog_density,
|
|
CLAMP(0.0, atof(Cmd_Argv(1)), 1.0),
|
|
CLAMP(0.0, atof(Cmd_Argv(2)), 1.0),
|
|
CLAMP(0.0, atof(Cmd_Argv(3)), 1.0),
|
|
0.0);
|
|
break;
|
|
case 5:
|
|
Fog_Update(max(0.0, atof(Cmd_Argv(1))),
|
|
CLAMP(0.0, atof(Cmd_Argv(2)), 1.0),
|
|
CLAMP(0.0, atof(Cmd_Argv(3)), 1.0),
|
|
CLAMP(0.0, atof(Cmd_Argv(4)), 1.0),
|
|
0.0);
|
|
break;
|
|
case 6: //TEST
|
|
Fog_Update(max(0.0, atof(Cmd_Argv(1))),
|
|
CLAMP(0.0, atof(Cmd_Argv(2)), 1.0),
|
|
CLAMP(0.0, atof(Cmd_Argv(3)), 1.0),
|
|
CLAMP(0.0, atof(Cmd_Argv(4)), 1.0),
|
|
atof(Cmd_Argv(5)));
|
|
break;
|
|
}
|
|
}
|
|
|
|
extern cvar_t *r_truecolor;
|
|
int truecolor;
|
|
extern int hqlite;
|
|
extern int coloredmethod;
|
|
void Mod_LoadBrushModel (model_t *mod, void *buffer, loadedfile_t *brush_fileinfo) // 2001-09-12 .ENT support by Maddes
|
|
{
|
|
int i, j;
|
|
dheader_t *header;
|
|
dmodel_t *bm;
|
|
int fhandle; // 2001-12-28 .VIS support by Maddes
|
|
|
|
if (r_coloredlights->value == 2){
|
|
coloredlights = 1; // normal light quality
|
|
if (hqlite)
|
|
coloredmethod = 0; // don't do lookup stuff
|
|
else
|
|
coloredmethod = 1; // do lookup stuff because we don't have a high quality table. :(
|
|
}
|
|
else if (r_coloredlights->value == 1){
|
|
coloredlights = 1; // normal light quality
|
|
coloredmethod = 1; // do lookup stuff
|
|
}
|
|
else if (r_coloredlights->value == 3){
|
|
coloredlights = 2; // dithered light quality
|
|
coloredmethod = 0; // don't do lookup stuff
|
|
}
|
|
else
|
|
{
|
|
coloredlights = 0; // mono lights
|
|
coloredmethod = 0; // don't do lookup stuff
|
|
}
|
|
|
|
truecolor = (int)r_truecolor->value; // sanity check
|
|
lowworld = (int)r_lowworld->value; // sanity check
|
|
ditheredrend = (int)r_dither->value; // sanity checking also
|
|
|
|
// FogTableRefresh();
|
|
if (nolookups){
|
|
coloredlights = 0; // DON'T ALLOW THESE THINGS!!!
|
|
ditheredrend = 0;
|
|
}
|
|
// if(overbrights != r_overbrightBits->value || (fullbrights != (int)r_fullbrights->value)){
|
|
// overbrights = r_overbrightBits->value;
|
|
// fullbrights = r_fullbrights->value;
|
|
// GrabColorMap();
|
|
// }
|
|
|
|
loadmodel->type = mod_brush;
|
|
|
|
header = (dheader_t *)buffer;
|
|
|
|
i = LittleLong (header->version);
|
|
if ((i != BSPVERSION) && (i != BSPVERSIONHL) && (i != BSPVERSION91))
|
|
// 2001-12-16 No crash on wrong BSP version by MrG start
|
|
// Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
|
|
{
|
|
Con_Printf("Mod_LoadBrushModel: %s has wrong version number (%i should be 28, 29 or 30)", mod->name, i, BSPVERSION);
|
|
mod->numvertexes=-1; // HACK - incorrect BSP version is no longer fatal
|
|
return;
|
|
}
|
|
// 2001-12-16 No crash on wrong BSP version by MrG end
|
|
if (i == BSPVERSIONHL)
|
|
loadmodel->fromgame = fg_halflife;
|
|
|
|
if (i == BSPVERSION91)
|
|
loadmodel->fromgame = fg_quakeold;
|
|
// swap all the lumps
|
|
mod_base = (byte *)header;
|
|
|
|
for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
|
|
((int *)header)[i] = LittleLong ( ((int *)header)[i]);
|
|
|
|
// load into heap
|
|
Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
|
|
Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
|
|
Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
|
|
if (truecolor)
|
|
Mod_LoadTextures32 (&header->lumps[LUMP_TEXTURES]);
|
|
else
|
|
Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
|
|
Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
|
|
Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
|
|
Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
|
|
Mod_LoadFaces (&header->lumps[LUMP_FACES]);
|
|
Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
|
|
// 2001-12-28 .VIS support by Maddes start
|
|
loadmodel->visdata = NULL;
|
|
loadmodel->leafs = NULL;
|
|
loadmodel->numleafs = 0;
|
|
|
|
fhandle = Mod_FindExternalVIS (brush_fileinfo);
|
|
if (fhandle >= 0)
|
|
{
|
|
Mod_LoadExternalVisibility (fhandle);
|
|
Mod_LoadExternalLeafs (fhandle);
|
|
}
|
|
|
|
if ((loadmodel->visdata == NULL)
|
|
|| (loadmodel->leafs == NULL)
|
|
|| (loadmodel->numleafs == 0))
|
|
{
|
|
if (fhandle >= 0)
|
|
{
|
|
Con_Printf("External VIS data are invalid!!!\n");
|
|
}
|
|
// 2001-12-28 .VIS support by Maddes end
|
|
Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
|
|
Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
|
|
// 2001-12-28 .VIS support by Maddes start
|
|
}
|
|
|
|
if (fhandle >= 0)
|
|
{
|
|
COM_CloseFile(fhandle);
|
|
}
|
|
// 2001-12-28 .VIS support by Maddes end
|
|
Mod_LoadNodes (&header->lumps[LUMP_NODES]);
|
|
Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]);
|
|
Mod_LoadEntities (&header->lumps[LUMP_ENTITIES], brush_fileinfo); // 2001-09-12 .ENT support by Maddes
|
|
Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
|
|
|
|
|
|
|
|
Mod_MakeHull0 ();
|
|
|
|
mod->numframes = 2; // regular and alternate animation
|
|
#ifndef GLQUAKE
|
|
mod->flags = 0;
|
|
#endif
|
|
|
|
//
|
|
// set up the submodels (FIXME: this is confusing)
|
|
//
|
|
for (i=0 ; i<mod->numsubmodels ; i++)
|
|
{
|
|
bm = &mod->submodels[i];
|
|
|
|
mod->hulls[0].firstclipnode = bm->headnode[0];
|
|
for (j=1 ; j<MAX_MAP_HULLS ; j++)
|
|
{
|
|
mod->hulls[j].firstclipnode = bm->headnode[j];
|
|
mod->hulls[j].lastclipnode = mod->numclipnodes-1;
|
|
}
|
|
|
|
mod->firstmodelsurface = bm->firstface;
|
|
mod->nummodelsurfaces = bm->numfaces;
|
|
|
|
VectorCopy (bm->maxs, mod->maxs);
|
|
VectorCopy (bm->mins, mod->mins);
|
|
mod->radius = RadiusFromBounds (mod->mins, mod->maxs);
|
|
|
|
mod->numleafs = bm->visleafs;
|
|
|
|
if (i < mod->numsubmodels-1)
|
|
{ // duplicate the basic information
|
|
char name[10];
|
|
|
|
sprintf (name, "*%i", i+1);
|
|
loadmodel = Mod_FindName (name);
|
|
*loadmodel = *mod;
|
|
strcpy (loadmodel->name, name);
|
|
mod = loadmodel;
|
|
}
|
|
}
|
|
// if (sv.worldmodel && !lightingavailable)
|
|
// LoadPointLighting(sv.worldmodel->entities);
|
|
}
|