From 33c48f4cad34c57e7827f77019472125d9e5863a Mon Sep 17 00:00:00 2001 From: g-cont Date: Tue, 29 Nov 2016 00:00:00 +0300 Subject: [PATCH] 29 Nov 2016 --- common/bspfile.h | 32 +++++-- common/com_model.h | 15 +++- common/render_api.h | 1 + engine/client/gl_decals.c | 15 ++-- engine/client/gl_rlight.c | 10 ++- engine/client/gl_rmain.c | 4 + engine/client/gl_rsurf.c | 64 ++++++++------ engine/common/mod_local.h | 1 + engine/common/model.c | 174 +++++++++++++++++++++++++++++--------- engine/server/sv_init.c | 4 +- engine/server/sv_world.c | 10 ++- 11 files changed, 235 insertions(+), 95 deletions(-) diff --git a/common/bspfile.h b/common/bspfile.h index a6fd1bdc..3794edcf 100644 --- a/common/bspfile.h +++ b/common/bspfile.h @@ -31,8 +31,8 @@ BRUSH MODELS #define XTBSP_VERSION 31 // extended lightmaps and expanded clipnodes limit #define IDEXTRAHEADER (('H'<<24)+('S'<<16)+('A'<<8)+'X') // little-endian "XASH" -#define EXTRA_VERSION 2 // because version 1 was occupied by old versions of XashXT -#define EXTRA_VERSION_3 3 // same as version 2 but with old lightmap resolution (1 luxel per 16 pixels) +#define EXTRA_VERSION 4 // ver. 1 was occupied by old versions of XashXT, ver. 2 was occupied by old vesrions of P2:savior + // ver. 3 was occupied by experimental versions of P2:savior change fmt #define DELUXEMAP_VERSION 1 #define IDDELUXEMAPHEADER (('T'<<24)+('I'<<16)+('L'<<8)+'Q') // little-endian "QLIT" @@ -104,11 +104,19 @@ BRUSH MODELS #define LUMP_CLIPNODES3 16 // hull2 goes into LUMP_CLIPNODES2, hull3 goes into LUMP_CLIPNODES3 #define HEADER_LUMPS_31 17 -#define LUMP_FACES_EXTRADATA 0 // extension of dface_t -#define LUMP_VERTS_EXTRADATA 1 // extension of dvertex_t -#define LUMP_CUBEMAPS 2 // cubemap description - -#define EXTRA_LUMPS 8 // g-cont. just for future expansions +#define LUMP_LIGHTVECS 0 // deluxemap data +#define LUMP_FACEINFO 1 // landscape and lightmap resolution info +#define LUMP_VERTNORMALS 2 // phong shaded vertex normals +#define LUMP_CUBEMAPS 3 // cubemap description +#define LUMP_LEAF_LIGHTING 4 // contain compressed light cubes per empty leafs +#define LUMP_WORLDLIGHTS 5 // list of all the virtual and real lights (used to relight models in-game) +#define LUMP_COLLISION 6 // physics engine collision hull dump +#define LUMP_AINODEGRAPH 7 // node graph that stored into the bsp +#define LUMP_UNUSED0 8 // one lump reserved for me +#define LUMP_UNUSED1 9 // one lump reserved for me +#define LUMP_UNUSED2 10 // one lump reserved for me +#define LUMP_UNUSED3 11 // one lump reserved for me +#define EXTRA_LUMPS 12 // count of the extra lumps // texture flags #define TEX_SPECIAL BIT( 0 ) // sky or slime, no lightmap or 256 subdivision @@ -218,9 +226,17 @@ typedef struct float vecs[2][4]; // texmatrix [s/t][xyz offset] int miptex; short flags; - short groupid; + short faceinfo; // -1 no face info otherwise dfaceinfo_t } dtexinfo_t; +typedef struct +{ + char landname[16]; // name of decsription in mapname_land.txt + unsigned short texture_step; // default is 16, pixels\luxels ratio + unsigned short max_extent; // default is 16, subdivision step ((texture_step * max_extent) - texture_step) + short groupid; // to determine equal landscapes from various groups, -1 - no group +} dfaceinfo_t; + typedef word dmarkface_t; // leaf marksurfaces indexes typedef int dsurfedge_t; // map surfedges diff --git a/common/com_model.h b/common/com_model.h index 815125b5..f290baf0 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -82,15 +82,24 @@ typedef struct texture_s unsigned int unused[3]; // reserved } texture_t; +typedef struct +{ + char landname[16]; // name of decsription in mapname_land.txt + unsigned short texture_step; // default is 16, pixels\luxels ratio + unsigned short max_extent; // default is 16, subdivision step ((texture_step * max_extent) - texture_step) + short groupid; // to determine equal landscapes from various groups, -1 - no group + + int reserved[32]; // just for future expansions or mod-makers +} mfaceinfo_t; + typedef struct { float vecs[2][4]; // [s/t] unit vectors in world space. // [i][3] is the s/t offset relative to the origin. // s or t = dot( 3Dpoint, vecs[i] ) + vecs[i][3] - float mipadjust; // mipmap limits for very small surfaces + mfaceinfo_t *faceinfo; // pointer to landscape info and lightmap resolution (may be NULL) texture_t *texture; - short flags; // sky or slime, no lightmap or 256 subdivision - short groupid; + int flags; // sky or slime, no lightmap or 256 subdivision } mtexinfo_t; // 73 bytes per VBO vertex diff --git a/common/render_api.h b/common/render_api.h index 4bd2a99b..11cc1334 100644 --- a/common/render_api.h +++ b/common/render_api.h @@ -66,6 +66,7 @@ GNU General Public License for more details. #define PARM_CLIENT_ACTIVE 30 #define PARM_REBUILD_GAMMA 31 // if true lightmaps rebuilding for gamma change #define PARM_DEDICATED_SERVER 32 +#define PARM_SURF_SAMPLESIZE 33 // lightmap resolution per face (second arg interpret as facenumber) enum { diff --git a/engine/client/gl_decals.c b/engine/client/gl_decals.c index 32810a86..a9b4d7e4 100644 --- a/engine/client/gl_decals.c +++ b/engine/client/gl_decals.c @@ -404,22 +404,23 @@ static void R_DecalVertsLight( float *v, msurface_t *surf, int vertCount ) { float s, t; mtexinfo_t *tex; - int j; + int j, sample_size; + sample_size = Mod_SampleSizeForFace( surf ); tex = surf->texinfo; for( j = 0; j < vertCount; j++, v += VERTEXSIZE ) { // lightmap texture coordinates s = DotProduct( v, tex->vecs[0] ) + tex->vecs[0][3] - surf->texturemins[0]; - s += surf->light_s * LM_SAMPLE_SIZE; - s += LM_SAMPLE_SIZE >> 1; - s /= BLOCK_SIZE * LM_SAMPLE_SIZE; //fa->texinfo->texture->width; + s += surf->light_s * sample_size; + s += sample_size >> 1; + s /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->width; t = DotProduct( v, tex->vecs[1] ) + tex->vecs[1][3] - surf->texturemins[1]; - t += surf->light_t * LM_SAMPLE_SIZE; - t += LM_SAMPLE_SIZE >> 1; - t /= BLOCK_SIZE * LM_SAMPLE_SIZE; //fa->texinfo->texture->height; + t += surf->light_t * sample_size; + t += sample_size >> 1; + t /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->height; v[5] = s; v[6] = t; diff --git a/engine/client/gl_rlight.c b/engine/client/gl_rlight.c index 683386aa..ee2e888c 100644 --- a/engine/client/gl_rlight.c +++ b/engine/client/gl_rlight.c @@ -237,6 +237,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, const vec3 { float front, back, frac; int i, map, side, size, s, t; + int sample_size; msurface_t *surf; mtexinfo_t *tex; color24 *lm; @@ -269,6 +270,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, const vec3 // check for impact on this node surf = model->surfaces + node->firstsurface; + sample_size = Mod_SampleSizeForFace( surf ); for( i = 0; i < node->numsurfaces; i++, surf++ ) { @@ -283,16 +285,16 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, const vec3 if(( s < 0 || s > surf->extents[0] ) || ( t < 0 || t > surf->extents[1] )) continue; - s /= LM_SAMPLE_SIZE; - t /= LM_SAMPLE_SIZE; + s /= sample_size; + t /= sample_size; if( !surf->samples ) return true; VectorClear( r_pointColor ); - lm = surf->samples + (t * ((surf->extents[0] / LM_SAMPLE_SIZE) + 1) + s); - size = ((surf->extents[0] / LM_SAMPLE_SIZE) + 1) * ((surf->extents[1] / LM_SAMPLE_SIZE) + 1); + lm = surf->samples + (t * ((surf->extents[0] / sample_size) + 1) + s); + size = ((surf->extents[0] / sample_size) + 1) * ((surf->extents[1] / sample_size) + 1); for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ ) { diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index 4de5ab5a..58c37e82 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -1445,6 +1445,10 @@ static int GL_RenderGetParm( int parm, int arg ) return glConfig.softwareGammaUpdate; case PARM_DEDICATED_SERVER: return (host.type == HOST_DEDICATED); + case PARM_SURF_SAMPLESIZE: + if( arg >= 0 && arg < cl.worldmodel->numsurfaces ) + return Mod_SampleSizeForFace( &cl.worldmodel->surfaces[arg] ); + return LM_SAMPLE_SIZE; } return 0; } diff --git a/engine/client/gl_rsurf.c b/engine/client/gl_rsurf.c index 2c31ac8f..b6c66a5f 100644 --- a/engine/client/gl_rsurf.c +++ b/engine/client/gl_rsurf.c @@ -78,6 +78,7 @@ static void BoundPoly( int numverts, float *verts, vec3_t mins, vec3_t maxs ) static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts ) { int i, j, k, f, b; + int sample_size; vec3_t mins, maxs; float m, frac, s, t, *v, vertsDiv; vec3_t front[SUBDIVIDE_SIZE], back[SUBDIVIDE_SIZE], total; @@ -87,6 +88,7 @@ static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts if( numverts > ( SUBDIVIDE_SIZE - 4 )) Host_Error( "Mod_SubdividePolygon: too many vertexes on face ( %i )\n", numverts ); + sample_size = Mod_SampleSizeForFace( warpface ); BoundPoly( numverts, verts, mins, maxs ); for( i = 0; i < 3; i++ ) @@ -181,15 +183,15 @@ static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts // lightmap texture coordinates s = DotProduct( verts, warpface->texinfo->vecs[0] ) + warpface->texinfo->vecs[0][3]; s -= warpface->texturemins[0]; - s += warpface->light_s * LM_SAMPLE_SIZE; - s += LM_SAMPLE_SIZE >> 1; - s /= BLOCK_SIZE * LM_SAMPLE_SIZE; //fa->texinfo->texture->width; + s += warpface->light_s * sample_size; + s += sample_size >> 1; + s /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->width; t = DotProduct( verts, warpface->texinfo->vecs[1] ) + warpface->texinfo->vecs[1][3]; t -= warpface->texturemins[1]; - t += warpface->light_t * LM_SAMPLE_SIZE; - t += LM_SAMPLE_SIZE >> 1; - t /= BLOCK_SIZE * LM_SAMPLE_SIZE; //fa->texinfo->texture->height; + t += warpface->light_t * sample_size; + t += sample_size >> 1; + t /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->height; poly->verts[i+1][5] = s; poly->verts[i+1][6] = t; @@ -284,8 +286,8 @@ GL_BuildPolygonFromSurface void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa ) { int i, lindex, lnumverts; + int vertpage, sample_size; medge_t *pedges, *r_pedge; - int vertpage; texture_t *tex; gltexture_t *glt; float *vec; @@ -309,6 +311,8 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa ) glt->srcHeight = tex->height; } + sample_size = Mod_SampleSizeForFace( fa ); + // reconstruct the polygon pedges = mod->edges; lnumverts = fa->numedges; @@ -349,15 +353,15 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa ) // lightmap texture coordinates s = DotProduct( vec, fa->texinfo->vecs[0] ) + fa->texinfo->vecs[0][3]; s -= fa->texturemins[0]; - s += fa->light_s * LM_SAMPLE_SIZE; - s += LM_SAMPLE_SIZE >> 1; - s /= BLOCK_SIZE * LM_SAMPLE_SIZE; //fa->texinfo->texture->width; + s += fa->light_s * sample_size; + s += sample_size >> 1; + s /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->width; t = DotProduct( vec, fa->texinfo->vecs[1] ) + fa->texinfo->vecs[1][3]; t -= fa->texturemins[1]; - t += fa->light_t * LM_SAMPLE_SIZE; - t += LM_SAMPLE_SIZE >> 1; - t /= BLOCK_SIZE * LM_SAMPLE_SIZE; //fa->texinfo->texture->height; + t += fa->light_t * sample_size; + t += sample_size >> 1; + t /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->height; poly->verts[i][5] = s; poly->verts[i][6] = t; @@ -466,6 +470,7 @@ void R_AddDynamicLights( msurface_t *surf ) int lnum, s, t, sd, td, smax, tmax; float sl, tl, sacc, tacc; vec3_t impact, origin_l; + int sample_size; mtexinfo_t *tex; dlight_t *dl; uint *bl; @@ -473,8 +478,9 @@ void R_AddDynamicLights( msurface_t *surf ) // no dlighted surfaces here if( !R_CountSurfaceDlights( surf )) return; - smax = (surf->extents[0] / LM_SAMPLE_SIZE) + 1; - tmax = (surf->extents[1] / LM_SAMPLE_SIZE) + 1; + sample_size = Mod_SampleSizeForFace( surf ); + smax = (surf->extents[0] / sample_size) + 1; + tmax = (surf->extents[1] / sample_size) + 1; tex = surf->texinfo; for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ ) @@ -511,12 +517,12 @@ void R_AddDynamicLights( msurface_t *surf ) tl = DotProduct( impact, tex->vecs[1] ) + tex->vecs[1][3] - surf->texturemins[1]; bl = r_blocklights; - for( t = 0, tacc = 0; t < tmax; t++, tacc += LM_SAMPLE_SIZE ) + for( t = 0, tacc = 0; t < tmax; t++, tacc += sample_size ) { td = tl - tacc; if( td < 0 ) td = -td; - for( s = 0, sacc = 0; s < smax; s++, sacc += LM_SAMPLE_SIZE, bl += 3 ) + for( s = 0, sacc = 0; s < smax; s++, sacc += sample_size, bl += 3 ) { sd = sl - sacc; if( sd < 0 ) sd = -sd; @@ -655,10 +661,12 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean int smax, tmax; uint *bl, scale; int i, map, size, s, t; + int sample_size; color24 *lm; - smax = ( surf->extents[0] / LM_SAMPLE_SIZE ) + 1; - tmax = ( surf->extents[1] / LM_SAMPLE_SIZE ) + 1; + sample_size = Mod_SampleSizeForFace( surf ); + smax = ( surf->extents[0] / sample_size ) + 1; + tmax = ( surf->extents[1] / sample_size ) + 1; size = smax * tmax; lm = surf->samples; @@ -879,10 +887,12 @@ void R_BlendLightmaps( void ) for( surf = gl_lms.dynamic_surfaces; surf != NULL; surf = surf->lightmapchain ) { int smax, tmax; + int sample_size; byte *base; - smax = ( surf->extents[0] / LM_SAMPLE_SIZE ) + 1; - tmax = ( surf->extents[1] / LM_SAMPLE_SIZE ) + 1; + sample_size = Mod_SampleSizeForFace( surf ); + smax = ( surf->extents[0] / sample_size ) + 1; + tmax = ( surf->extents[1] / sample_size ) + 1; info = SURF_INFO( surf, RI.currentmodel ); if( LM_AllocBlock( smax, tmax, &info->dlight_s, &info->dlight_t )) @@ -1192,10 +1202,12 @@ dynamic: if(( fa->styles[maps] >= 32 || fa->styles[maps] == 0 ) && ( fa->dlightframe != tr.framecount )) { byte temp[132*132*4]; + int sample_size; int smax, tmax; - smax = ( fa->extents[0] / LM_SAMPLE_SIZE ) + 1; - tmax = ( fa->extents[1] / LM_SAMPLE_SIZE ) + 1; + sample_size = Mod_SampleSizeForFace( fa ); + smax = ( fa->extents[0] / sample_size ) + 1; + tmax = ( fa->extents[1] / sample_size ) + 1; R_BuildLightMap( fa, temp, smax * 4, true ); R_SetCacheState( fa ); @@ -2000,14 +2012,16 @@ GL_CreateSurfaceLightmap void GL_CreateSurfaceLightmap( msurface_t *surf ) { int smax, tmax; + int sample_size; byte *base; if( !cl.worldmodel->lightdata ) return; if( surf->flags & SURF_DRAWTILED ) return; - smax = ( surf->extents[0] / LM_SAMPLE_SIZE ) + 1; - tmax = ( surf->extents[1] / LM_SAMPLE_SIZE ) + 1; + sample_size = Mod_SampleSizeForFace( surf ); + smax = ( surf->extents[0] / sample_size ) + 1; + tmax = ( surf->extents[1] / sample_size ) + 1; if( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t )) { diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index 569f1607..8e8ffa85 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -144,6 +144,7 @@ int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, q qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits ); void Mod_BuildSurfacePolygons( msurface_t *surf, mextrasurf_t *info ); void Mod_AmbientLevels( const vec3_t p, byte *pvolumes ); +int Mod_SampleSizeForFace( msurface_t *surf ); byte *Mod_GetPVSForPoint( const vec3_t p ); modtype_t Mod_GetType( int handle ); model_t *Mod_Handle( int handle ); diff --git a/engine/common/model.c b/engine/common/model.c index 586659ef..72f2cfee 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -519,6 +519,21 @@ void Mod_AmbientLevels( const vec3_t p, byte *pvolumes ) *(int *)pvolumes = *(int *)leaf->ambient_sound_level; } +/* +================== +Mod_SampleSizeForFace + +return the current lightmap resolution per face +================== +*/ +int Mod_SampleSizeForFace( msurface_t *surf ) +{ + if( !surf || !surf->texinfo || !surf->texinfo->faceinfo ) + return LM_SAMPLE_SIZE; + + return surf->texinfo->faceinfo->texture_step; +} + /* ================== Mod_CheckWaterAlphaSupport @@ -1160,14 +1175,49 @@ static void Mod_LoadTextures( const dlump_t *l ) Mod_LoadTexInfo ================= */ -static void Mod_LoadTexInfo( const dlump_t *l ) +static mfaceinfo_t *Mod_LoadFaceInfo( const dlump_t *l, int *numfaceinfo ) +{ + dfaceinfo_t *in; + mfaceinfo_t *out, *faceinfo; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if( l->filelen % sizeof( *in )) + Host_Error( "Mod_LoadFaceInfo: funny lump size in %s\n", loadmodel->name ); + + count = l->filelen / sizeof( *in ); + faceinfo = out = Mem_Alloc( loadmodel->mempool, count * sizeof( *out )); + + for( i = 0; i < count; i++, in++, out++ ) + { + Q_strncpy( out->landname, in->landname, sizeof( out->landname )); + out->texture_step = in->texture_step; + out->max_extent = in->max_extent; + out->groupid = in->groupid; + } + + *numfaceinfo = count; + + return faceinfo; +} + +/* +================= +Mod_LoadTexInfo +================= +*/ +static void Mod_LoadTexInfo( const dlump_t *l, dextrahdr_t *extrahdr ) { dtexinfo_t *in; mtexinfo_t *out; int miptex; + mfaceinfo_t *fi = NULL; + int fi_count; int i, j, count; - float len1, len2; - + + if( extrahdr != NULL ) + fi = Mod_LoadFaceInfo( &extrahdr->lumps[LUMP_FACEINFO], &fi_count ); + in = (void *)(mod_base + l->fileofs); if( l->filelen % sizeof( *in )) Host_Error( "Mod_LoadTexInfo: funny lump size in %s\n", loadmodel->name ); @@ -1183,23 +1233,16 @@ static void Mod_LoadTexInfo( const dlump_t *l ) for( j = 0; j < 8; j++ ) out->vecs[0][j] = in->vecs[0][j]; - len1 = VectorLength( out->vecs[0] ); - len2 = VectorLength( out->vecs[1] ); - len1 = ( len1 + len2 ) / 2; - - // g-cont: can use this info for GL_TEXTURE_LOAD_BIAS_EXT ? - if( len1 < 0.32f ) out->mipadjust = 4; - else if( len1 < 0.49f ) out->mipadjust = 3; - else if( len1 < 0.99f ) out->mipadjust = 2; - else out->mipadjust = 1; - miptex = in->miptex; if( miptex < 0 || miptex > loadmodel->numtextures ) Host_Error( "Mod_LoadTexInfo: bad miptex number in '%s'\n", loadmodel->name ); out->texture = loadmodel->textures[miptex]; out->flags = in->flags; - out->groupid = in->groupid; + + // make sure what faceinfo is really exist + if( extrahdr != NULL && in->faceinfo != -1 && in->faceinfo < fi_count ) + out->faceinfo = &fi[in->faceinfo]; } } @@ -1267,12 +1310,37 @@ static void Mod_LoadDeluxemap( void ) Mem_Free( in ); } +/* +================= +Mod_LoadLightVecs +================= +*/ +static void Mod_LoadLightVecs( const dlump_t *l ) +{ + byte *in; + + in = (void *)(mod_base + l->fileofs); + world.vecdatasize = l->filelen; + + if( world.vecdatasize != world.litdatasize ) + { + MsgDev( D_ERROR, "Mod_LoadLightVecs: has mismatched size (%i should be %i)\n", world.vecdatasize, world.litdatasize ); + world.deluxedata = NULL; + world.vecdatasize = 0; + return; + } + + world.deluxedata = Mem_Alloc( loadmodel->mempool, world.vecdatasize ); + memcpy( world.deluxedata, in, world.vecdatasize ); + MsgDev( D_INFO, "Mod_LoadLightVecs: loaded\n" ); +} + /* ================= Mod_LoadLighting ================= */ -static void Mod_LoadLighting( const dlump_t *l ) +static void Mod_LoadLighting( const dlump_t *l, dextrahdr_t *extrahdr ) { byte d, *in; color24 *out; @@ -1316,8 +1384,20 @@ static void Mod_LoadLighting( const dlump_t *l ) break; } + if( !world.loading ) return; // only world can have deluxedata (FIXME: what about quake models?) + + // not supposed to be load ? + if( !FBitSet( host.features, ENGINE_LOAD_DELUXEDATA )) + { + world.deluxedata = NULL; + world.vecdatasize = 0; + return; + } + // try to loading deluxemap too - Mod_LoadDeluxemap (); + if( extrahdr != NULL ) + Mod_LoadLightVecs( &extrahdr->lumps[LUMP_LIGHTVECS] ); + else Mod_LoadDeluxemap (); // old method } /* @@ -1331,10 +1411,11 @@ static void Mod_CalcSurfaceExtents( msurface_t *surf ) { float mins[2], maxs[2], val; int bmins[2], bmaxs[2]; - int i, j, e; + int i, j, e, sample_size; mtexinfo_t *tex; mvertex_t *v; + sample_size = Mod_SampleSizeForFace( surf ); tex = surf->texinfo; mins[0] = mins[1] = 999999; @@ -1360,11 +1441,11 @@ static void Mod_CalcSurfaceExtents( msurface_t *surf ) for( i = 0; i < 2; i++ ) { - bmins[i] = floor( mins[i] / LM_SAMPLE_SIZE ); - bmaxs[i] = ceil( maxs[i] / LM_SAMPLE_SIZE ); + bmins[i] = floor( mins[i] / sample_size ); + bmaxs[i] = ceil( maxs[i] / sample_size ); - surf->texturemins[i] = bmins[i] * LM_SAMPLE_SIZE; - surf->extents[i] = (bmaxs[i] - bmins[i]) * LM_SAMPLE_SIZE; + surf->texturemins[i] = bmins[i] * sample_size; + surf->extents[i] = (bmaxs[i] - bmins[i]) * sample_size; if( !FBitSet( tex->flags, TEX_SPECIAL ) && surf->extents[i] > 4096 ) MsgDev( D_ERROR, "Bad surface extents %i\n", surf->extents[i] ); @@ -1411,7 +1492,7 @@ static void Mod_BuildPolygon( mextrasurf_t *info, msurface_t *surf, int numVerts uint bufSize; vec3_t normal, tangent, binormal; mtexinfo_t *texinfo = surf->texinfo; - int i, numElems; + int i, numElems, sample_size; byte *buffer; msurfmesh_t *mesh; @@ -1421,6 +1502,7 @@ static void Mod_BuildPolygon( mextrasurf_t *info, msurface_t *surf, int numVerts bufSize = sizeof( msurfmesh_t ) + numVerts * sizeof( glvert_t ) + numElems * sizeof( word ); buffer = Mem_Alloc( loadmodel->mempool, bufSize ); + sample_size = Mod_SampleSizeForFace( surf ); mesh = (msurfmesh_t *)buffer; buffer += sizeof( msurfmesh_t ); mesh->numVerts = numVerts; @@ -1477,14 +1559,14 @@ static void Mod_BuildPolygon( mextrasurf_t *info, msurface_t *surf, int numVerts // lightmap texture coordinates s = DotProduct( verts, texinfo->vecs[0] ) + texinfo->vecs[0][3] - surf->texturemins[0]; - s += surf->light_s * LM_SAMPLE_SIZE; - s += LM_SAMPLE_SIZE >> 1; - s /= BLOCK_SIZE * LM_SAMPLE_SIZE; + s += surf->light_s * sample_size; + s += sample_size >> 1; + s /= BLOCK_SIZE * sample_size; t = DotProduct( verts, texinfo->vecs[1] ) + texinfo->vecs[1][3] - surf->texturemins[1]; - t += surf->light_t * LM_SAMPLE_SIZE; - t += LM_SAMPLE_SIZE >> 1; - t /= BLOCK_SIZE * LM_SAMPLE_SIZE; + t += surf->light_t * sample_size; + t += sample_size >> 1; + t /= BLOCK_SIZE * sample_size; out->lmcoord[0] = s; out->lmcoord[1] = t; @@ -1508,6 +1590,7 @@ static void Mod_SubdividePolygon( mextrasurf_t *info, msurface_t *surf, int numV vec3_t normal, tangent, binormal, mins, maxs; mtexinfo_t *texinfo = surf->texinfo; vec2_t totalST, totalLM; + int sample_size; float s, t, scale; int i, j, f, b; uint bufSize; @@ -1519,6 +1602,8 @@ static void Mod_SubdividePolygon( mextrasurf_t *info, msurface_t *surf, int numV for( i = 0, v = verts; i < numVerts; i++, v += 3 ) AddPointToBounds( v, mins, maxs ); + sample_size = Mod_SampleSizeForFace( surf ); + for( i = 0; i < 3; i++ ) { m = tessSize * (float)floor((( mins[i] + maxs[i] ) * 0.5f ) / tessSize + 0.5f ); @@ -1645,14 +1730,14 @@ static void Mod_SubdividePolygon( mextrasurf_t *info, msurface_t *surf, int numV { // lightmap texture coordinates s = DotProduct( verts, texinfo->vecs[0] ) + texinfo->vecs[0][3] - surf->texturemins[0]; - s += surf->light_s * LM_SAMPLE_SIZE; - s += LM_SAMPLE_SIZE >> 1; - s /= BLOCK_SIZE * LM_SAMPLE_SIZE; + s += surf->light_s * sample_size; + s += sample_size >> 1; + s /= BLOCK_SIZE * sample_size; t = DotProduct( verts, texinfo->vecs[1] ) + texinfo->vecs[1][3] - surf->texturemins[1]; - t += surf->light_t * LM_SAMPLE_SIZE; - t += LM_SAMPLE_SIZE >> 1; - t /= BLOCK_SIZE * LM_SAMPLE_SIZE; + t += surf->light_t * sample_size; + t += sample_size >> 1; + t /= BLOCK_SIZE * sample_size; } else { @@ -2704,9 +2789,7 @@ static void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *load sample_size = 16; break; case XTBSP_VERSION: - if( extrahdr->id == IDEXTRAHEADER && extrahdr->version == EXTRA_VERSION_3 ) - sample_size = 16; - else sample_size = 8; + sample_size = 8; break; default: MsgDev( D_ERROR, "%s has wrong version number (%i should be %i)", loadmodel->name, i, HLBSP_VERSION ); @@ -2725,12 +2808,18 @@ static void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *load MsgDev( D_ERROR, "%s has wrong version number (%i should be %i)", loadmodel->name, i, world.version ); return; } + + loadmodel->numframes = sample_size; // NOTE: world store sample size into model_t->numframes bmodel_version = i; // share it // swap all the lumps mod_base = (byte *)header; loadmodel->mempool = Mem_AllocPool( va( "^2%s^7", loadmodel->name )); + // make sure what extrahdr is valid + if( extrahdr->id != IDEXTRAHEADER || extrahdr->version != EXTRA_VERSION ) + extrahdr = NULL; // no extra header + // load into heap if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 && (header->lumps[LUMP_ENTITIES].filelen % sizeof( dplane_t )) == 0 ) { @@ -2754,9 +2843,9 @@ static void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *load Mod_LoadEdges( &header->lumps[LUMP_EDGES] ); Mod_LoadSurfEdges( &header->lumps[LUMP_SURFEDGES] ); Mod_LoadTextures( &header->lumps[LUMP_TEXTURES] ); - Mod_LoadLighting( &header->lumps[LUMP_LIGHTING] ); + Mod_LoadLighting( &header->lumps[LUMP_LIGHTING], extrahdr ); Mod_LoadVisibility( &header->lumps[LUMP_VISIBILITY] ); - Mod_LoadTexInfo( &header->lumps[LUMP_TEXINFO] ); + Mod_LoadTexInfo( &header->lumps[LUMP_TEXINFO], extrahdr ); Mod_LoadSurfaces( &header->lumps[LUMP_FACES] ); Mod_LoadMarkSurfaces( &header->lumps[LUMP_MARKSURFACES] ); Mod_LoadLeafs( &header->lumps[LUMP_LEAFS] ); @@ -2767,8 +2856,7 @@ static void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *load else Mod_LoadClipnodes( &header->lumps[LUMP_CLIPNODES] ); Mod_MakeHull0 (); - - loadmodel->numframes = 2; // regular and alternate animation + ents = loadmodel->entities; // set up the submodels @@ -3108,7 +3196,9 @@ void Mod_GetFrames( int handle, int *numFrames ) return; } - *numFrames = mod->numframes; + if( mod->type == mod_brush ) + *numFrames = 2; // regular and alternate animation + else *numFrames = mod->numframes; if( *numFrames < 1 ) *numFrames = 1; } diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 6524bf83..72bc1b6b 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -627,7 +627,7 @@ A brand new game has been started void SV_InitGame( void ) { edict_t *ent; - int i; + int i, load = sv.loadgame; if( svs.initialized ) { @@ -695,7 +695,7 @@ void SV_InitGame( void ) svs.num_client_entities = sv_maxclients->integer * SV_UPDATE_BACKUP * NUM_PACKET_ENTITIES; svs.packet_entities = Z_Malloc( sizeof( entity_state_t ) * svs.num_client_entities ); svs.baselines = Z_Malloc( sizeof( entity_state_t ) * GI->max_edicts ); - MsgDev( D_INFO, "%s alloced by server packet entities\n", Q_memprint( sizeof( entity_state_t ) * svs.num_client_entities )); + if( !load ) MsgDev( D_INFO, "%s alloced by server packet entities\n", Q_memprint( sizeof( entity_state_t ) * svs.num_client_entities )); // client frames will be allocated in SV_DirectConnect diff --git a/engine/server/sv_world.c b/engine/server/sv_world.c index 5085bf37..2495dbac 100644 --- a/engine/server/sv_world.c +++ b/engine/server/sv_world.c @@ -1437,6 +1437,7 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec mtexinfo_t *tex; float front, back, scale, frac; int i, map, size, s, t; + int sample_size; color24 *lm; vec3_t mid; @@ -1474,6 +1475,7 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec // check for impact on this node surf = model->surfaces + node->firstsurface; + sample_size = Mod_SampleSizeForFace( surf ); for( i = 0; i < node->numsurfaces; i++, surf++ ) { @@ -1488,16 +1490,16 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec if(( s < 0.0f || s > surf->extents[0] ) || ( t < 0.0f || t > surf->extents[1] )) continue; - s /= LM_SAMPLE_SIZE; - t /= LM_SAMPLE_SIZE; + s /= sample_size; + t /= sample_size; if( !surf->samples ) return true; VectorClear( sv_pointColor ); - lm = surf->samples + (t * ((surf->extents[0] / LM_SAMPLE_SIZE) + 1) + s); - size = ((surf->extents[0] / LM_SAMPLE_SIZE) + 1) * ((surf->extents[1] / LM_SAMPLE_SIZE) + 1); + lm = surf->samples + (t * ((surf->extents[0] / sample_size) + 1) + s); + size = ((surf->extents[0] / sample_size) + 1) * ((surf->extents[1] / sample_size) + 1); for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ ) {