aboutsummaryrefslogtreecommitdiff
path: root/mp/src/utils/vbsp/worldvertextransitionfixup.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /mp/src/utils/vbsp/worldvertextransitionfixup.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/utils/vbsp/worldvertextransitionfixup.cpp')
-rw-r--r--mp/src/utils/vbsp/worldvertextransitionfixup.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/mp/src/utils/vbsp/worldvertextransitionfixup.cpp b/mp/src/utils/vbsp/worldvertextransitionfixup.cpp
new file mode 100644
index 00000000..5d00f3f5
--- /dev/null
+++ b/mp/src/utils/vbsp/worldvertextransitionfixup.cpp
@@ -0,0 +1,212 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "bsplib.h"
+#include "vbsp.h"
+#include "tier1/UtlBuffer.h"
+#include "tier1/utlvector.h"
+#include "KeyValues.h"
+#include "materialpatch.h"
+
+struct entitySideList_t
+{
+ int firstBrushSide;
+ int brushSideCount;
+};
+
+static bool SideIsNotDispAndHasDispMaterial( int iSide )
+{
+ side_t *pSide = &g_MainMap->brushsides[iSide];
+
+ // If it's a displacement, then it's fine to have a displacement-only material.
+ if ( pSide->pMapDisp )
+ {
+ return false;
+ }
+
+ pSide->texinfo;
+
+ return true;
+}
+
+static void BackSlashToForwardSlash( char *pname )
+{
+ while ( *pname ) {
+ if ( *pname == '\\' )
+ *pname = '/';
+ pname++;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Generate patched material name
+//-----------------------------------------------------------------------------
+static void GeneratePatchedMaterialName( const char *pMaterialName, char *pBuffer, int nMaxLen )
+{
+ int nLen = Q_snprintf( pBuffer, nMaxLen, "maps/%s/%s_wvt_patch", mapbase, pMaterialName );
+
+ Assert( nLen < TEXTURE_NAME_LENGTH - 1 );
+ if ( nLen >= TEXTURE_NAME_LENGTH - 1 )
+ {
+ Error( "Generated worldvertextransition patch name : %s too long! (max = %d)\n", pBuffer, TEXTURE_NAME_LENGTH );
+ }
+
+ BackSlashToForwardSlash( pBuffer );
+ Q_strlower( pBuffer );
+}
+
+static void RemoveKey( KeyValues *kv, const char *pSubKeyName )
+{
+ KeyValues *pSubKey = kv->FindKey( pSubKeyName );
+ if( pSubKey )
+ {
+ kv->RemoveSubKey( pSubKey );
+ pSubKey->deleteThis();
+ }
+}
+
+void CreateWorldVertexTransitionPatchedMaterial( const char *pOriginalMaterialName, const char *pPatchedMaterialName )
+{
+ KeyValues *kv = LoadMaterialKeyValues( pOriginalMaterialName, 0 );
+ if( kv )
+ {
+ // change shader to Lightmappedgeneric (from worldvertextransition*)
+ kv->SetName( "LightmappedGeneric" );
+ // don't need no stinking $basetexture2 or any other second texture vars
+ RemoveKey( kv, "$basetexture2" );
+ RemoveKey( kv, "$bumpmap2" );
+ RemoveKey( kv, "$bumpframe2" );
+ RemoveKey( kv, "$basetexture2noenvmap" );
+ RemoveKey( kv, "$blendmodulatetexture" );
+ RemoveKey( kv, "$maskedblending" );
+ RemoveKey( kv, "$surfaceprop2" );
+ // If we didn't want a basetexture on the first texture in the blend, we don't want an envmap at all.
+ KeyValues *basetexturenoenvmap = kv->FindKey( "$BASETEXTURENOENVMAP" );
+ if( basetexturenoenvmap->GetInt() )
+ {
+ RemoveKey( kv, "$envmap" );
+ }
+
+ Warning( "Patching WVT material: %s\n", pPatchedMaterialName );
+ WriteMaterialKeyValuesToPak( pPatchedMaterialName, kv );
+ }
+}
+
+int CreateBrushVersionOfWorldVertexTransitionMaterial( int originalTexInfo )
+{
+ // Don't make cubemap tex infos for nodes
+ if ( originalTexInfo == TEXINFO_NODE )
+ return originalTexInfo;
+
+ texinfo_t *pTexInfo = &texinfo[originalTexInfo];
+ dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
+ const char *pOriginalMaterialName = TexDataStringTable_GetString( pTexData->nameStringTableID );
+
+ // Get out of here if the originalTexInfo is already a patched wvt material
+ if ( Q_stristr( pOriginalMaterialName, "_wvt_patch" ) )
+ return originalTexInfo;
+
+ char patchedMaterialName[1024];
+ GeneratePatchedMaterialName( pOriginalMaterialName, patchedMaterialName, 1024 );
+// Warning( "GeneratePatchedMaterialName: %s %s\n", pMaterialName, patchedMaterialName );
+
+ // Make sure the texdata doesn't already exist.
+ int nTexDataID = FindTexData( patchedMaterialName );
+ bool bHasTexData = (nTexDataID != -1);
+ if( !bHasTexData )
+ {
+ // Create the new vmt material file
+ CreateWorldVertexTransitionPatchedMaterial( pOriginalMaterialName, patchedMaterialName );
+
+ // Make a new texdata
+ nTexDataID = AddCloneTexData( pTexData, patchedMaterialName );
+ }
+
+ Assert( nTexDataID != -1 );
+
+ texinfo_t newTexInfo;
+ newTexInfo = *pTexInfo;
+ newTexInfo.texdata = nTexDataID;
+
+ int nTexInfoID = -1;
+
+ // See if we need to make a new texinfo
+ bool bHasTexInfo = false;
+ if( bHasTexData )
+ {
+ nTexInfoID = FindTexInfo( newTexInfo );
+ bHasTexInfo = (nTexInfoID != -1);
+ }
+
+ // Make a new texinfo if we need to.
+ if( !bHasTexInfo )
+ {
+ nTexInfoID = texinfo.AddToTail( newTexInfo );
+ }
+
+ Assert( nTexInfoID != -1 );
+ return nTexInfoID;
+}
+
+const char *GetShaderNameForTexInfo( int iTexInfo )
+{
+ texinfo_t *pTexInfo = &texinfo[iTexInfo];
+ dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
+ const char *pMaterialName = TexDataStringTable_GetString( pTexData->nameStringTableID );
+ MaterialSystemMaterial_t hMaterial = FindMaterial( pMaterialName, NULL, false );
+ const char *pShaderName = GetMaterialShaderName( hMaterial );
+ return pShaderName;
+}
+
+void WorldVertexTransitionFixup( void )
+{
+ CUtlVector<entitySideList_t> sideList;
+ sideList.SetCount( g_MainMap->num_entities );
+ int i;
+ for ( i = 0; i < g_MainMap->num_entities; i++ )
+ {
+ sideList[i].firstBrushSide = 0;
+ sideList[i].brushSideCount = 0;
+ }
+
+ for ( i = 0; i < g_MainMap->nummapbrushes; i++ )
+ {
+ sideList[g_MainMap->mapbrushes[i].entitynum].brushSideCount += g_MainMap->mapbrushes[i].numsides;
+ }
+ int curSide = 0;
+ for ( i = 0; i < g_MainMap->num_entities; i++ )
+ {
+ sideList[i].firstBrushSide = curSide;
+ curSide += sideList[i].brushSideCount;
+ }
+
+ int currentEntity = 0;
+ for ( int iSide = 0; iSide < g_MainMap->nummapbrushsides; ++iSide )
+ {
+ side_t *pSide = &g_MainMap->brushsides[iSide];
+
+ // skip displacments
+ if ( pSide->pMapDisp )
+ continue;
+
+ if( pSide->texinfo < 0 )
+ continue;
+
+ const char *pShaderName = GetShaderNameForTexInfo( pSide->texinfo );
+ if ( !pShaderName || !Q_stristr( pShaderName, "worldvertextransition" ) )
+ {
+ continue;
+ }
+
+ while ( currentEntity < g_MainMap->num_entities-1 &&
+ iSide > sideList[currentEntity].firstBrushSide + sideList[currentEntity].brushSideCount )
+ {
+ currentEntity++;
+ }
+
+ pSide->texinfo = CreateBrushVersionOfWorldVertexTransitionMaterial( pSide->texinfo );
+ }
+} \ No newline at end of file