/* 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 "globaldef.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 ; iposition[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 ; imins[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 ; jheadnode[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 ; iv[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 ; ivecs[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 ; iminmaxs[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 ; iminmaxs[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 ; jnummarksurfaces ; 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 ; iplanenum = 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 ; iplanenum = 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= 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 ; ifileofs); 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 ; inormal[j] = LittleFloat (in->normal[j]); if (out->normal[j] < 0) bits |= 1<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 \n"); Con_Printf(" fog \n"); Con_Printf(" fog \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 ; ilumps[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 ; inumsubmodels ; i++) { bm = &mod->submodels[i]; mod->hulls[0].firstclipnode = bm->headnode[0]; for (j=1 ; jhulls[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); }