* patchMeta: fix: keep playerclip patches for collisions
* autocaulk: do not impact fog brushes with all faces culled (global fog case) decompilation: detail flag deduction: avoid detail hints, areaportals, antiportals by surfaceparm structural check change hardcoded surfaceflags use to statically evaluated ones for the given game
This commit is contained in:
parent
2b59253b26
commit
e62da4c621
|
|
@ -107,7 +107,7 @@ static void parseBspFile( const char *bspPath, StrList& outShaders, StrList& out
|
|||
}
|
||||
|
||||
for ( size_t i = 0; i < bspShaders.size(); ++i ){
|
||||
if ( drawsurfSHs[i] && !( bspShaders[i].surfaceFlags & 0x80 /* Q_SURF_NORAW */ ) ){
|
||||
if ( drawsurfSHs[i] && !( bspShaders[i].surfaceFlags & GetRequiredSurfaceParm( "nodraw"_Tstring ).surfaceFlags ) ){ // also sort out nodraw patches
|
||||
res2list( pk3Shaders, bspShaders[i].shader );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,16 +42,18 @@ static void autocaulk_write(){
|
|||
|
||||
FILE* file = SafeOpenWrite( filename, "wt" );
|
||||
|
||||
int fslime = 16;
|
||||
int fslime = 0;
|
||||
ApplySurfaceParm( "slime", &fslime, NULL, NULL );
|
||||
int flava = 8;
|
||||
int flava = 0;
|
||||
ApplySurfaceParm( "lava", &flava, NULL, NULL );
|
||||
|
||||
for ( const brush_t& b : entities[0].brushes ) {
|
||||
fprintf( file, "%i ", b.brushNum );
|
||||
const shaderInfo_t* contentShader = b.contentShader;
|
||||
const bool globalFog = ( contentShader->compileFlags & C_FOG )
|
||||
&& std::all_of( b.sides.cbegin(), b.sides.cend(), []( const side_t& side ){ return side.visibleHull.empty(); } );
|
||||
for( const side_t& side : b.sides ){
|
||||
if( !side.visibleHull.empty() || ( side.compileFlags & C_NODRAW ) ){
|
||||
if( !side.visibleHull.empty() || ( side.compileFlags & C_NODRAW ) || globalFog ){
|
||||
fprintf( file, "-" );
|
||||
}
|
||||
else if( contentShader->compileFlags & C_LIQUID ){
|
||||
|
|
|
|||
|
|
@ -337,18 +337,20 @@ static void ConvertBrush( FILE *f, int bspBrushNum, const Vector3& origin, bool
|
|||
fprintf( f, "\t{\n" );
|
||||
}
|
||||
|
||||
/* find out if brush is detail */ // note: this also flags structural transparent brushes as detail, e.g. hints
|
||||
/* find out if brush is detail */
|
||||
int contentFlag = 0;
|
||||
for( const auto& leaf : bspLeafs ){
|
||||
if( leaf.cluster >= 0 )
|
||||
for( auto id = bspLeafBrushes.cbegin() + leaf.firstBSPLeafBrush, end = id + leaf.numBSPLeafBrushes; id != end; ++id ){
|
||||
if( *id == bspBrushNum ){
|
||||
contentFlag = C_DETAIL;
|
||||
break;
|
||||
if( !( bspShaders[bspBrushes[bspBrushNum].shaderNum].contentFlags & GetRequiredSurfaceParm( "structural"_Tstring ).contentFlags ) ){ // sort out structural transparent brushes, e.g. hints
|
||||
for( const auto& leaf : bspLeafs ){
|
||||
if( leaf.cluster >= 0 )
|
||||
for( auto id = bspLeafBrushes.cbegin() + leaf.firstBSPLeafBrush, end = id + leaf.numBSPLeafBrushes; id != end; ++id ){
|
||||
if( *id == bspBrushNum ){
|
||||
contentFlag = C_DETAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( contentFlag == C_DETAIL)
|
||||
break;
|
||||
if( contentFlag == C_DETAIL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* iterate through build brush sides */
|
||||
|
|
|
|||
|
|
@ -493,11 +493,10 @@ void SetBrushContents( brush_t& b ){
|
|||
else if ( s->compileFlags & C_FOG ){
|
||||
b.contentShader = s->shaderInfo;
|
||||
}
|
||||
//playerclip
|
||||
else if ( b.contentShader->contentFlags & 0x10000 ){
|
||||
else if ( b.contentShader->contentFlags & GetRequiredSurfaceParm( "playerclip"_Tstring ).contentFlags ){
|
||||
continue;
|
||||
}
|
||||
else if ( s->contentFlags & 0x10000 ){
|
||||
else if ( s->contentFlags & GetRequiredSurfaceParm( "playerclip"_Tstring ).contentFlags ){
|
||||
b.contentShader = s->shaderInfo;
|
||||
}
|
||||
else if (!( b.contentShader->compileFlags & C_SOLID )){
|
||||
|
|
|
|||
|
|
@ -1841,6 +1841,22 @@ void TCModScale( tcMod_t& mod, float s, float t );
|
|||
void TCModRotate( tcMod_t& mod, float euler );
|
||||
|
||||
bool ApplySurfaceParm( const char *name, int *contentFlags, int *surfaceFlags, int *compileFlags );
|
||||
const surfaceParm_t *GetSurfaceParm( const char *name );
|
||||
|
||||
// Encode the string as a type
|
||||
template <char... chars>
|
||||
using TemplateString = std::integer_sequence<char, chars...>;
|
||||
// Create a user defined literal operator
|
||||
template <typename T, T... chars>
|
||||
constexpr TemplateString<chars...> operator""_Tstring() { return { }; }
|
||||
/// \brief returns statically evaluated \c surfaceParm_t for the given name or emits \c Error
|
||||
template<char... chars>
|
||||
const surfaceParm_t &GetRequiredSurfaceParm( const TemplateString<chars...> ){
|
||||
static constexpr char str[sizeof...(chars) + 1] = { chars..., '\0' }; // Recover the character data
|
||||
static const surfaceParm_t *const sp = GetSurfaceParm( str );
|
||||
ENSURE( sp != nullptr );
|
||||
return *sp;
|
||||
}
|
||||
|
||||
void BeginMapShaderFile( const char *mapFile );
|
||||
void WriteMapShaderFile( void );
|
||||
|
|
|
|||
|
|
@ -202,65 +202,43 @@ void TCModRotate( tcMod_t& mod, float euler ){
|
|||
|
||||
|
||||
|
||||
const surfaceParm_t *GetSurfaceParm( const char *name ){
|
||||
/* walk the current game's surfaceparms */
|
||||
for( const surfaceParm_t& sp : g_game->surfaceParms )
|
||||
if ( striEqual( name, sp.name ) )
|
||||
return &sp;
|
||||
|
||||
/* check custom info parms */
|
||||
for ( const surfaceParm_t& sp : Span( custSurfaceParms, numCustSurfaceParms ) )
|
||||
if ( striEqual( name, sp.name ) )
|
||||
return &sp;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
ApplySurfaceParm() - ydnar
|
||||
applies a named surfaceparm to the supplied flags
|
||||
*/
|
||||
|
||||
bool ApplySurfaceParm( const char *name, int *contentFlags, int *surfaceFlags, int *compileFlags ){
|
||||
int fake;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
if ( name == NULL ) {
|
||||
name = "";
|
||||
}
|
||||
if ( contentFlags == NULL ) {
|
||||
contentFlags = &fake;
|
||||
}
|
||||
if ( surfaceFlags == NULL ) {
|
||||
surfaceFlags = &fake;
|
||||
}
|
||||
if ( compileFlags == NULL ) {
|
||||
compileFlags = &fake;
|
||||
}
|
||||
|
||||
/* walk the current game's surfaceparms */
|
||||
for( const surfaceParm_t& sp : g_game->surfaceParms )
|
||||
{
|
||||
/* match? */
|
||||
if ( striEqual( name, sp.name ) ) {
|
||||
/* clear and set flags */
|
||||
*contentFlags &= ~( sp.contentFlagsClear );
|
||||
*contentFlags |= sp.contentFlags;
|
||||
*surfaceFlags &= ~( sp.surfaceFlagsClear );
|
||||
*surfaceFlags |= sp.surfaceFlags;
|
||||
*compileFlags &= ~( sp.compileFlagsClear );
|
||||
*compileFlags |= sp.compileFlags;
|
||||
|
||||
/* return ok */
|
||||
return true;
|
||||
if( const surfaceParm_t *sp = GetSurfaceParm( name ) ){
|
||||
/* clear and set flags */
|
||||
if( contentFlags != nullptr ){
|
||||
*contentFlags &= ~( sp->contentFlagsClear );
|
||||
*contentFlags |= sp->contentFlags;
|
||||
}
|
||||
}
|
||||
|
||||
/* check custom info parms */
|
||||
for ( const surfaceParm_t& sp : Span( custSurfaceParms, numCustSurfaceParms ) )
|
||||
{
|
||||
/* match? */
|
||||
if ( striEqual( name, sp.name ) ) {
|
||||
/* clear and set flags */
|
||||
*contentFlags &= ~( sp.contentFlagsClear );
|
||||
*contentFlags |= sp.contentFlags;
|
||||
*surfaceFlags &= ~( sp.surfaceFlagsClear );
|
||||
*surfaceFlags |= sp.surfaceFlags;
|
||||
*compileFlags &= ~( sp.compileFlagsClear );
|
||||
*compileFlags |= sp.compileFlags;
|
||||
|
||||
/* return ok */
|
||||
return true;
|
||||
if( surfaceFlags != nullptr ){
|
||||
*surfaceFlags &= ~( sp->surfaceFlagsClear );
|
||||
*surfaceFlags |= sp->surfaceFlags;
|
||||
}
|
||||
if( compileFlags != nullptr ){
|
||||
*compileFlags &= ~( sp->compileFlagsClear );
|
||||
*compileFlags |= sp->compileFlags;
|
||||
}
|
||||
/* return ok */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* no matching surfaceparm found */
|
||||
return false;
|
||||
}
|
||||
|
|
@ -659,7 +637,7 @@ void FinishShader( shaderInfo_t *si ){
|
|||
}
|
||||
|
||||
if( noob && !( si->compileFlags & C_OB ) ){
|
||||
ApplySurfaceParm( "noob", &si->contentFlags, &si->surfaceFlags, &si->compileFlags );
|
||||
ApplySurfaceParm( "noob", nullptr, &si->surfaceFlags, nullptr );
|
||||
}
|
||||
|
||||
/* set to finished */
|
||||
|
|
|
|||
|
|
@ -2196,8 +2196,6 @@ void EmitFlareSurface( mapDrawSurface_t *ds ){
|
|||
*/
|
||||
|
||||
void EmitPatchSurface( entity_t *e, mapDrawSurface_t *ds ){
|
||||
int surfaceFlags, contentFlags;
|
||||
|
||||
/* vortex: _patchMeta support */
|
||||
const bool forcePatchMeta = e->boolForKey( "_patchMeta", "patchMeta" );
|
||||
|
||||
|
|
@ -2232,8 +2230,8 @@ void EmitPatchSurface( entity_t *e, mapDrawSurface_t *ds ){
|
|||
}
|
||||
else if ( patchMeta || forcePatchMeta ) {
|
||||
/* patch meta requires that we have nodraw patches for collision */
|
||||
surfaceFlags = ds->shaderInfo->surfaceFlags;
|
||||
contentFlags = ds->shaderInfo->contentFlags;
|
||||
int surfaceFlags = ds->shaderInfo->surfaceFlags;
|
||||
int contentFlags = ds->shaderInfo->contentFlags;
|
||||
ApplySurfaceParm( "nodraw", &contentFlags, &surfaceFlags, NULL );
|
||||
ApplySurfaceParm( "pointlight", &contentFlags, &surfaceFlags, NULL );
|
||||
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ void TriangulatePatchSurface( entity_t *e, mapDrawSurface_t *ds ){
|
|||
memcpy( dsNew, ds, sizeof( *ds ) );
|
||||
|
||||
/* if the patch is nonsolid, then discard it */
|
||||
if ( !( ds->shaderInfo->compileFlags & C_SOLID ) ) {
|
||||
if ( !( ds->shaderInfo->compileFlags & C_SOLID ) && !( ds->shaderInfo->contentFlags & GetRequiredSurfaceParm( "playerclip"_Tstring ).contentFlags ) ) {
|
||||
ClearSurface( ds );
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user