Basic parsing of hl2bsp static props.
This commit is contained in:
parent
76d232b007
commit
84313ce213
|
@ -3297,6 +3297,7 @@ void CL_ClearLerpEntsParticleState(void)
|
|||
}
|
||||
}
|
||||
|
||||
qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel);
|
||||
void CL_LinkStaticEntities(void *pvs, int *areas)
|
||||
{
|
||||
int i;
|
||||
|
@ -3401,6 +3402,33 @@ void CL_LinkStaticEntities(void *pvs, int *areas)
|
|||
// FIXME: no effects on static ents
|
||||
// CLQ1_AddPowerupShell(ent, false, stat->effects);
|
||||
}
|
||||
|
||||
if (cl.worldmodel->numstaticents)
|
||||
{
|
||||
entity_t *src;
|
||||
for (i = 0; i < cl.worldmodel->numstaticents; i++)
|
||||
{
|
||||
if (cl_numvisedicts == cl_maxvisedicts)
|
||||
{
|
||||
cl_expandvisents=true;
|
||||
break;
|
||||
}
|
||||
src = &cl.worldmodel->staticents[i];
|
||||
if (!src->model || src->model->loadstate != MLS_LOADED)
|
||||
{
|
||||
if (src->model && src->model->loadstate == MLS_NOTLOADED)
|
||||
Mod_LoadModel(src->model, MLV_WARN); //we use threads, so these'll load in time.
|
||||
continue;
|
||||
}
|
||||
if (!src->light_known)
|
||||
R_CalcModelLighting(src, src->model); //bake and cache, now everything else is working.
|
||||
|
||||
ent = &cl_visedicts[cl_numvisedicts++];
|
||||
*ent = *src;
|
||||
ent->framestate.g[FS_REG].frametime[0] = cl.time;
|
||||
ent->framestate.g[FS_REG].frametime[1] = cl.time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//returns cos(angle)
|
||||
|
|
|
@ -168,6 +168,7 @@ enum mod_purge_e
|
|||
};
|
||||
enum mlverbosity_e
|
||||
{
|
||||
MLV_NOLOAD, //leave it notloaded.
|
||||
MLV_SILENT,
|
||||
MLV_WARN,
|
||||
MLV_WARNSYNC,
|
||||
|
|
|
@ -2127,6 +2127,56 @@ void R_DrawNameTags(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0 ; i<cl.num_statics ; i++)
|
||||
{
|
||||
entity_t *state = &cl_static_entities[i].ent;
|
||||
mod = state->model;
|
||||
if (mod && mod->loadstate == MLS_LOADED)
|
||||
VectorInterpolate(mod->mins, 0.5, mod->maxs, org);
|
||||
else
|
||||
VectorClear(org);
|
||||
VectorAdd(org, state->origin, org);
|
||||
if (Matrix4x4_CM_Project(org, screenspace, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y))
|
||||
{
|
||||
char *entstr;
|
||||
int x, y;
|
||||
|
||||
entstr = state->model->name;
|
||||
if (entstr)
|
||||
{
|
||||
vec2_t scale = {8,8};
|
||||
x = screenspace[0]*r_refdef.vrect.width+r_refdef.vrect.x;
|
||||
y = (1-screenspace[1])*r_refdef.vrect.height+r_refdef.vrect.y;
|
||||
R_DrawTextField(x, y, vid.width - x, vid.height - y, entstr, CON_WHITEMASK, CPRINT_TALIGN, font_default, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0 ; i<cl.worldmodel->numstaticents; i++)
|
||||
{
|
||||
entity_t *state = &cl.worldmodel->staticents[i];
|
||||
mod = state->model;
|
||||
if (mod && mod->loadstate == MLS_LOADED)
|
||||
VectorInterpolate(mod->mins, 0.5, mod->maxs, org);
|
||||
else
|
||||
VectorClear(org);
|
||||
VectorAdd(org, state->origin, org);
|
||||
if (Matrix4x4_CM_Project(org, screenspace, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y))
|
||||
{
|
||||
char *entstr;
|
||||
int x, y;
|
||||
|
||||
entstr = state->model->name;
|
||||
if (entstr)
|
||||
{
|
||||
vec2_t scale = {8,8};
|
||||
x = screenspace[0]*r_refdef.vrect.width+r_refdef.vrect.x;
|
||||
y = (1-screenspace[1])*r_refdef.vrect.height+r_refdef.vrect.y;
|
||||
R_DrawTextField(x, y, vid.width - x, vid.height - y, entstr, CON_WHITEMASK, CPRINT_TALIGN, font_default, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef Q2SERVER //not enough fields for it to really be worth it.
|
||||
if (w == &sv.world && svs.gametype == GT_QUAKE2 && ge)
|
||||
|
|
|
@ -5476,6 +5476,200 @@ static qboolean CModHL2_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l
|
|||
return true;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
unsigned int count;
|
||||
struct {
|
||||
unsigned int id;
|
||||
unsigned short flags;
|
||||
unsigned short version;
|
||||
unsigned int ofs;
|
||||
unsigned int len;
|
||||
} sl[1];
|
||||
} hlgamelumpheader_t;
|
||||
static qboolean CModHL2_LoadStaticProps(model_t *mod, qbyte *offset, size_t size, int version)
|
||||
{
|
||||
struct {
|
||||
const char name[128];
|
||||
} *modelref;
|
||||
size_t nummodels, numleafrefs, numprops, i;
|
||||
unsigned short *leafref;
|
||||
entity_t *ent;
|
||||
|
||||
size_t modelindex;
|
||||
|
||||
qboolean skip = false;
|
||||
int dxlevel = 95, cpulevel=0, gpulevel=0;
|
||||
|
||||
qbyte *prop;
|
||||
size_t propsize;
|
||||
switch(version)
|
||||
{
|
||||
case 4:
|
||||
propsize = 14*4;
|
||||
break;
|
||||
case 5: //+scale
|
||||
propsize = 15*4;
|
||||
break;
|
||||
case 6://+dxlevels
|
||||
propsize = 16*4;
|
||||
break;
|
||||
case 7: //+rgba
|
||||
case 8: //-dxlevels+[cg]pulevels
|
||||
propsize = 17*4;
|
||||
break;
|
||||
case 9: //+360
|
||||
case 10://-360+flags
|
||||
propsize = 18*4;
|
||||
break;
|
||||
case 11://+scale
|
||||
propsize = 19*4;
|
||||
break;
|
||||
default:
|
||||
return true; //version not supported, just ignore it entirely. sorry.
|
||||
}
|
||||
|
||||
|
||||
nummodels = LittleLong(*(int*)offset);
|
||||
offset += 4;
|
||||
size -= 4;
|
||||
modelref = (void*)offset;
|
||||
offset += nummodels*sizeof(*modelref);
|
||||
size -= nummodels*sizeof(*modelref);
|
||||
|
||||
numleafrefs = LittleLong(*(int*)offset);
|
||||
offset += 4;
|
||||
size -= 4;
|
||||
leafref = (void*)offset;
|
||||
offset += numleafrefs*sizeof(*leafref);
|
||||
size -= numleafrefs*sizeof(*leafref);
|
||||
|
||||
numprops = LittleLong(*(int*)offset);
|
||||
offset += 4;
|
||||
size -= 4;
|
||||
prop = (void*)offset;
|
||||
offset += numprops*propsize;
|
||||
size -= numprops*propsize;
|
||||
|
||||
if (size)
|
||||
return true; //funny lump size...
|
||||
|
||||
mod->staticents = ZG_Malloc(&mod->memgroup, sizeof(*mod->staticents)*numprops);
|
||||
for (i = 0, ent = mod->staticents; i < numprops; i++)
|
||||
{
|
||||
skip = false;
|
||||
V_ClearEntity(ent);
|
||||
|
||||
ent->playerindex = -1;
|
||||
ent->topcolour = TOP_DEFAULT;
|
||||
ent->bottomcolour = BOTTOM_DEFAULT;
|
||||
#ifdef PEXT_SCALE
|
||||
ent->scale = 1;
|
||||
#endif
|
||||
ent->shaderRGBAf[0] = 1;
|
||||
ent->shaderRGBAf[1] = 1;
|
||||
ent->shaderRGBAf[2] = 1;
|
||||
ent->shaderRGBAf[3] = 1;
|
||||
ent->framestate.g[FS_REG].frame[0] = 0;
|
||||
ent->framestate.g[FS_REG].lerpweight[0] = 1;
|
||||
|
||||
|
||||
ent->origin[0] = LittleFloat(*(float*)prop); prop += sizeof(float);
|
||||
ent->origin[1] = LittleFloat(*(float*)prop); prop += sizeof(float);
|
||||
ent->origin[2] = LittleFloat(*(float*)prop); prop += sizeof(float);
|
||||
ent->angles[0] = LittleFloat(*(float*)prop); prop += sizeof(float);
|
||||
ent->angles[1] = LittleFloat(*(float*)prop); prop += sizeof(float);
|
||||
ent->angles[2] = LittleFloat(*(float*)prop); prop += sizeof(float);
|
||||
modelindex = (unsigned short)LittleShort(*(short*)prop); prop += sizeof(unsigned short);
|
||||
/*firstleaf = LittleShort(*(unsigned short*)prop)*/; prop += sizeof(unsigned short);
|
||||
/*leafcount = LittleShort(*(unsigned short*)prop)*/; prop += sizeof(unsigned short);
|
||||
/*ent->solid = *prop*/; prop += sizeof(qbyte);
|
||||
/*ent->flags = *prop*/; prop += sizeof(qbyte);
|
||||
ent->skinnum = LittleLong(*(unsigned int*)prop); prop += sizeof(unsigned int);
|
||||
/*ent->fademindist = LittleFloat(*(float*)prop)*/; prop += sizeof(float);
|
||||
/*ent->fademaxdist = LittleFloat(*(float*)prop)*/; prop += sizeof(float);
|
||||
/*ent->lightingorigin[0] = LittleFloat(*(float*)prop)*/; prop += sizeof(float);
|
||||
/*ent->lightingorigin[1] = LittleFloat(*(float*)prop)*/; prop += sizeof(float);
|
||||
/*ent->lightingorigin[2] = LittleFloat(*(float*)prop)*/; prop += sizeof(float);
|
||||
if (version >= 5)
|
||||
{
|
||||
/*ent->fadescale = LittleFloat(*(float*)prop);*/ prop += sizeof(float);
|
||||
}
|
||||
if (version >= 8)
|
||||
{
|
||||
skip |= (prop[0] > cpulevel || cpulevel > prop[1]); prop += sizeof(qbyte)*2;
|
||||
skip |= (prop[0] > gpulevel || gpulevel > prop[1]); prop += sizeof(qbyte)*2;
|
||||
}
|
||||
else if (version >= 6)
|
||||
{
|
||||
unsigned short minlev, maxlev;
|
||||
minlev = LittleShort(*(unsigned short*)prop); prop += sizeof(unsigned short);
|
||||
maxlev = LittleShort(*(unsigned short*)prop); prop += sizeof(unsigned short);
|
||||
skip |= (minlev > dxlevel || dxlevel > maxlev);
|
||||
}
|
||||
if (version >= 7)
|
||||
{
|
||||
VectorScale(prop, 1/255.0, ent->shaderRGBAf); prop += sizeof(qbyte)*4;
|
||||
}
|
||||
|
||||
if (version == 9)
|
||||
{
|
||||
/*disablex360 = LittleLong(*(int*)prop);*/ prop += sizeof(int);
|
||||
}
|
||||
if (version >= 10)
|
||||
{
|
||||
ent->flags = LittleLong(*(int*)prop); prop += sizeof(int);
|
||||
}
|
||||
if (version >= 11)
|
||||
{
|
||||
ent->scale = LittleFloat(*(float*)prop); prop += sizeof(float);
|
||||
}
|
||||
|
||||
//okay, we parsed the prop data now...
|
||||
skip |= modelindex >= nummodels;
|
||||
if (skip)
|
||||
continue; //we're ignoring it for some reason
|
||||
ent->model = Mod_FindName(modelref[modelindex].name);
|
||||
AngleVectorsFLU(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
|
||||
|
||||
//Hack: lighting is wrong.
|
||||
ent->light_known = 1;
|
||||
VectorSet(ent->light_dir, 0, 0.707, 0.707);
|
||||
VectorSet(ent->light_avg, 0.75, 0.75, 0.75);
|
||||
VectorSet(ent->light_range, 0.5, 0.5, 0.5);
|
||||
|
||||
//not all props will be emitted, according to d3d levels...
|
||||
mod->numstaticents++;
|
||||
ent++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
static qboolean CModHL2_LoadGameLump(model_t *mod, qbyte *mod_base, lump_t *l)
|
||||
{
|
||||
size_t i;
|
||||
hlgamelumpheader_t *blob = (void*)(mod_base + l->fileofs);
|
||||
if (!l->filelen)
|
||||
return true; //missing
|
||||
if (l->filelen < sizeof(*blob) + sizeof(*blob->sl)*(blob->count-1))
|
||||
return false; //not even enough space for the header...
|
||||
for (i = 0; i < blob->count; i++)
|
||||
{
|
||||
#define LUMPTYPE(a,b,c,d, minver, maxver) (blob->sl[i].id == (((qbyte)a<<24)|((qbyte)b<<16)|((qbyte)c<<8)|((qbyte)d<<0)) && blob->sl[i].version >= minver && blob->sl[i].version <= maxver)
|
||||
if (LUMPTYPE('s','p','r','p', 4,10) && !blob->sl[i].flags) //static props (placed by mapper)
|
||||
CModHL2_LoadStaticProps(mod, mod_base+blob->sl[i].ofs/*sigh*/, blob->sl[i].len, blob->sl[i].version);
|
||||
else if (LUMPTYPE('d','p','r','p', 4,4) && !blob->sl[i].flags) //dynamic props (generated by textures)
|
||||
;
|
||||
else if (LUMPTYPE('d','p','l','t', 0,0) && !blob->sl[i].flags) //detail prop ldr lighting
|
||||
;
|
||||
else if (LUMPTYPE('d','p','l','h', 0,0) && !blob->sl[i].flags) //detail prop hdr lighting
|
||||
;
|
||||
else
|
||||
Con_Printf("Unsupported gamelump id/version %c%c%c%c %i\n", (blob->sl[i].id>>24),(blob->sl[i].id>>16),(blob->sl[i].id>>8),(blob->sl[i].id>>0),blob->sl[i].version);
|
||||
#undef LUMPTYPE
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "fs.h"
|
||||
static searchpathfuncs_t *CModHL2_LoadArchive(model_t *mod, void *base, size_t len)
|
||||
{
|
||||
|
@ -5591,6 +5785,8 @@ static qboolean VBSP_LoadModel(model_t *mod, qbyte *mod_base, size_t filelen, ch
|
|||
noerrors = noerrors && CModQ2_LoadAreas (mod, mod_base, &header.lumps[VLUMP_AREAS]);
|
||||
noerrors = noerrors && CModHL2_LoadAreaPortals (mod, mod_base, &header.lumps[VLUMP_AREAPORTALS], &header.lumps[VLUMP_AREAPORTALVERTS]);
|
||||
|
||||
noerrors = noerrors && CModHL2_LoadGameLump (mod, mod_base, &header.lumps[VLUMP_GAMELUMP]);
|
||||
|
||||
if (!noerrors)
|
||||
return false;
|
||||
#ifdef HAVE_SERVER
|
||||
|
|
|
@ -1059,6 +1059,7 @@ void Mod_ModelLoaded(void *ctx, void *data, size_t a, size_t b)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (a != MLS_LOADED)
|
||||
switch(verbose)
|
||||
{
|
||||
default:
|
||||
|
@ -1070,6 +1071,7 @@ void Mod_ModelLoaded(void *ctx, void *data, size_t a, size_t b)
|
|||
if (*mod->name != '*' && strcmp(mod->name, "null") && mod_warnmodels.ival && !previouslyfailed)
|
||||
Con_Printf(CON_ERROR "Unable to load %s\n", mod->name);
|
||||
break;
|
||||
case MLV_NOLOAD: //shouldn't happen.
|
||||
case MLV_SILENT:
|
||||
break;
|
||||
}
|
||||
|
@ -1338,7 +1340,7 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b)
|
|||
|
||||
BZ_Free(buf);
|
||||
|
||||
COM_AddWork(WG_MAIN, Mod_ModelLoaded, mod, NULL, MLS_LOADED, 0);
|
||||
COM_AddWork(WG_MAIN, Mod_ModelLoaded, mod, NULL, MLS_LOADED, verbose);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1356,7 +1358,7 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b)
|
|||
|
||||
model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose)
|
||||
{
|
||||
if (mod->loadstate == MLS_NOTLOADED && *mod->name != '*')
|
||||
if (mod->loadstate == MLS_NOTLOADED && *mod->name != '*' && verbose != MLV_NOLOAD)
|
||||
{
|
||||
mod->loadstate = MLS_LOADING;
|
||||
if (verbose == MLV_ERROR || verbose == MLV_WARNSYNC)
|
||||
|
|
|
@ -1133,6 +1133,8 @@ typedef struct model_s
|
|||
#ifdef HL2BSPS
|
||||
dispinfo_t *displacements;
|
||||
unsigned int numdisplacements;
|
||||
entity_t *staticents;
|
||||
size_t numstaticents;
|
||||
#endif
|
||||
|
||||
modelfuncs_t funcs;
|
||||
|
|
Loading…
Reference in New Issue