From fcf9d433b1ce2c61d9ace8c961020cd671f7ca93 Mon Sep 17 00:00:00 2001 From: Jay Dolan Date: Tue, 10 Nov 2020 12:29:07 -0500 Subject: [PATCH] Introduce idTech2 material filters for Quake2 and Quetoo, introduce sky filter as well. --- include/qertypes.h | 2 + plugins/shaders/shaders.h | 2 +- radiant/filters.cpp | 99 +++++++++++++++++++++++++++++++++------ radiant/mainframe.cpp | 46 ++++++++++++++---- radiant/mainframe.h | 4 +- radiant/qedefs.h | 3 +- radiant/qfiles.h | 3 ++ 7 files changed, 133 insertions(+), 26 deletions(-) diff --git a/include/qertypes.h b/include/qertypes.h index 941d34bb..d94f5dd6 100644 --- a/include/qertypes.h +++ b/include/qertypes.h @@ -725,7 +725,9 @@ struct bfilter_t //c++ style // 5=brush->face->texdef.flags (q2) // 6=brush->face->texdef.contents (q2) // 7=!brush->face->texdef.contents (q2) + // 8 idTech2 materials (q2 and quetoo) int mask; + int exclude; const char *string; bool active; }; diff --git a/plugins/shaders/shaders.h b/plugins/shaders/shaders.h index fbbf2f27..c5d1255b 100644 --- a/plugins/shaders/shaders.h +++ b/plugins/shaders/shaders.h @@ -45,7 +45,7 @@ class CShader : public IShader { int refCount; qtexture_t *m_pTexture; -// name is shader / texture name (if not a real shader) reletive to "textures/" directory +// name is shader / texture name (if not a real shader) relative to "textures/" directory char m_Name[QER_MAX_NAMELEN]; char m_ShaderFileName[QER_MAX_NAMELEN]; int m_nFlags; diff --git a/radiant/filters.cpp b/radiant/filters.cpp index 0a85902b..8cc08b24 100644 --- a/radiant/filters.cpp +++ b/radiant/filters.cpp @@ -71,6 +71,11 @@ bfilter_t *FilterAddImpl( bfilter_t *pFilter, int type, int bmask, const char *s if ( type == 2 || type == 4 || type == 5 || type == 6 || type == 7 ) { pNew->mask = bmask; } + if ( type == 8 ) { + pNew->string = str; + pNew->mask = bmask; + } + pNew->exclude = exclude; if ( g_qeglobals.d_savedinfo.exclude & exclude ) { pNew->active = true; } @@ -95,6 +100,7 @@ bfilter_t *FilterAddImpl( bfilter_t *pFilter, int type, int bmask, const char *s // type 5 = surface flags (q2) // type 6 = content flags (q2) // type 7 = content flags - no match (q2) +// type 8 = idTech2 materials (q2 and quetoo) bfilter_t *FilterAdd( bfilter_t *pFilter, int type, int bmask, const char *str, int exclude ){ return FilterAddImpl( pFilter, type, bmask, str, exclude, false ); } @@ -131,20 +137,38 @@ bfilter_t *FilterListDelete( bfilter_t *pFilter ){ bfilter_t *FilterAddBase( bfilter_t *pFilter ){ - pFilter = FilterAddImpl( pFilter,1,0,"clip",EXCLUDE_CLIP,true ); - pFilter = FilterAddImpl( pFilter,1,0,"caulk",EXCLUDE_CAULK,true ); - pFilter = FilterAddImpl( pFilter,1,0,"liquids",EXCLUDE_LIQUIDS,true ); - pFilter = FilterAddImpl( pFilter,1,0,"hint",EXCLUDE_HINTSSKIPS,true ); - pFilter = FilterAddImpl( pFilter,1,0,"clusterportal",EXCLUDE_CLUSTERPORTALS,true ); - pFilter = FilterAddImpl( pFilter,1,0,"areaportal",EXCLUDE_AREAPORTALS,true ); - pFilter = FilterAddImpl( pFilter,2,QER_TRANS,NULL,EXCLUDE_TRANSLUCENT,true ); - pFilter = FilterAddImpl( pFilter,3,0,"trigger",EXCLUDE_TRIGGERS,true ); - pFilter = FilterAddImpl( pFilter,4,ECLASS_MISCMODEL,NULL,EXCLUDE_MODELS,true ); - pFilter = FilterAddImpl( pFilter,4,ECLASS_LIGHT,NULL,EXCLUDE_LIGHTS,true ); - pFilter = FilterAddImpl( pFilter,4,ECLASS_PATH,NULL,EXCLUDE_PATHS,true ); - pFilter = FilterAddImpl( pFilter,1,0,"lightgrid",EXCLUDE_LIGHTGRID,true ); - pFilter = FilterAddImpl( pFilter,1,0,"botclip",EXCLUDE_BOTCLIP,true ); - pFilter = FilterAddImpl( pFilter,1,0,"clipmonster",EXCLUDE_BOTCLIP,true ); + + if ( g_pGameDescription->idTech2 ) { + + pFilter = FilterAddImpl( pFilter,1,0,"clip",EXCLUDE_CLIP,true ); + pFilter = FilterAddImpl( pFilter,1,0,"caulk",EXCLUDE_CAULK,true ); + pFilter = FilterAddImpl( pFilter,8,0,NULL,EXCLUDE_LIQUIDS,true ); + pFilter = FilterAddImpl( pFilter,8,0,NULL,EXCLUDE_HINTSSKIPS,true ); + pFilter = FilterAddImpl( pFilter,8,0,NULL,EXCLUDE_TRANSLUCENT,true ); + pFilter = FilterAddImpl( pFilter,8,0,NULL,EXCLUDE_SKY,true ); + pFilter = FilterAddImpl( pFilter,3,0,"trigger",EXCLUDE_TRIGGERS,true ); + pFilter = FilterAddImpl( pFilter,4,ECLASS_LIGHT,NULL,EXCLUDE_LIGHTS,true ); + pFilter = FilterAddImpl( pFilter,4,ECLASS_PATH,NULL,EXCLUDE_PATHS,true ); + + } else { + + pFilter = FilterAddImpl( pFilter,1,0,"clip",EXCLUDE_CLIP,true ); + pFilter = FilterAddImpl( pFilter,1,0,"caulk",EXCLUDE_CAULK,true ); + pFilter = FilterAddImpl( pFilter,1,0,"liquids",EXCLUDE_LIQUIDS,true ); + pFilter = FilterAddImpl( pFilter,1,0,"hint",EXCLUDE_HINTSSKIPS,true ); + pFilter = FilterAddImpl( pFilter,1,0,"sky",EXCLUDE_SKY,true ); + pFilter = FilterAddImpl( pFilter,1,0,"clusterportal",EXCLUDE_CLUSTERPORTALS,true ); + pFilter = FilterAddImpl( pFilter,1,0,"areaportal",EXCLUDE_AREAPORTALS,true ); + pFilter = FilterAddImpl( pFilter,2,QER_TRANS,NULL,EXCLUDE_TRANSLUCENT,true ); + pFilter = FilterAddImpl( pFilter,3,0,"trigger",EXCLUDE_TRIGGERS,true ); + pFilter = FilterAddImpl( pFilter,4,ECLASS_MISCMODEL,NULL,EXCLUDE_MODELS,true ); + pFilter = FilterAddImpl( pFilter,4,ECLASS_LIGHT,NULL,EXCLUDE_LIGHTS,true ); + pFilter = FilterAddImpl( pFilter,4,ECLASS_PATH,NULL,EXCLUDE_PATHS,true ); + pFilter = FilterAddImpl( pFilter,1,0,"lightgrid",EXCLUDE_LIGHTGRID,true ); + pFilter = FilterAddImpl( pFilter,1,0,"botclip",EXCLUDE_BOTCLIP,true ); + pFilter = FilterAddImpl( pFilter,1,0,"clipmonster",EXCLUDE_BOTCLIP,true ); + } + return pFilter; } @@ -228,7 +252,7 @@ bool FilterBrush( brush_t *pb ){ } // exclude by attribute 1 brush->face->pShader->getName() if ( filters->attribute == 1 ) { - if ( strstr( f->pShader->getName(),filters->string ) ) { + if ( strstr( f->pShader->getName(), filters->string ) ) { filterbrush = true; break; } @@ -259,6 +283,51 @@ bool FilterBrush( brush_t *pb ){ break; } } + // idTech2 material filters + else if ( filters->attribute == 8 ) { + switch ( filters->exclude ) { + case EXCLUDE_LIQUIDS: + if ( f->texdef.contents & (CONTENTS_WATER | CONTENTS_LAVA | CONTENTS_SLIME ) ) { + filterbrush = true; + } + if ( strstr( f->pShader->getName(), "water" ) || + strstr( f->pShader->getName(), "lava" ) || + strstr( f->pShader->getName(), "slime" ) ) { + filterbrush = true; + } + break; + case EXCLUDE_HINTSSKIPS: + if ( f->texdef.flags & (SURF_HINT | SURF_SKIP) ) { + filterbrush = true; + } + if ( strstr( f->pShader->getName(), "hint" ) || + strstr( f->pShader->getName(), "skip" ) ) { + filterbrush = true; + } + break; + case EXCLUDE_TRANSLUCENT: + if ( f->texdef.contents & CONTENTS_WINDOW ) { + filterbrush = true; + } + if ( f->texdef.flags & (SURF_TRANS33 | SURF_TRANS66 | SURF_ALPHA_TEST) ) { + filterbrush = true; + } + if ( strstr( f->pShader->getName(), "glass" ) || + strstr( f->pShader->getName(), "window" ) ) { + filterbrush = true; + } + break; + case EXCLUDE_SKY: + if ( f->texdef.flags & SURF_SKY ) { + filterbrush = true; + } + if ( strstr( f->pShader->getName(), "sky" ) ) { + filterbrush = true; + } + break; + + } + } } if ( !filterbrush ) { break; diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 46966051..7e4bf983 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -287,6 +287,7 @@ SCommandInfo g_Commands[] = {"FilterDetails", GDK_KEY_D, RAD_CONTROL, ID_FILTER_DETAILS, "menu_filter_details"}, {"FilterStructural", GDK_KEY_D, RAD_CONTROL | RAD_SHIFT, ID_FILTER_STRUCTURAL, "menu_filter_structural"}, {"FilterHintsSkips", GDK_KEY_H, RAD_CONTROL, ID_FILTER_HINTSSKIPS, "menu_filter_hintsskips"}, + {"FilterHintsSky", GDK_KEY_S, RAD_ALT, ID_FILTER_SKY, "menu_filter_sky"}, {"FilterModels", GDK_KEY_M, RAD_SHIFT, ID_FILTER_MODELS, "menu_filter_models"}, {"FilterTriggers", GDK_KEY_T, RAD_CONTROL | RAD_SHIFT, ID_FILTER_TRIGGERS, "menu_filter_triggers"}, {"LoadPointfile", GDK_KEY_L, RAD_SHIFT, ID_FILE_POINTFILE, "menu_load_pointfile"}, @@ -647,6 +648,7 @@ gint HandleCommand( GtkWidget *widget, gpointer data ){ case ID_FILTER_DETAILS: g_pParentWnd->OnFilterDetails(); break; case ID_FILTER_ENTITIES: g_pParentWnd->OnFilterEntities(); break; case ID_FILTER_HINTSSKIPS: g_pParentWnd->OnFilterHintsskips(); break; + case ID_FILTER_SKY: g_pParentWnd->OnFilterSky(); break; case ID_FILTER_LIGHTS: g_pParentWnd->OnFilterLights(); break; case ID_FILTER_LIQUIDS: g_pParentWnd->OnFilterLiquids(); break; case ID_FILTER_MODELS: g_pParentWnd->OnFilterModels(); break; @@ -1119,25 +1121,36 @@ void MainFrame::create_main_menu( GtkWidget *window, GtkWidget *vbox ){ g_object_set_data( G_OBJECT( window ), "menu_view_showworkzone", item ); menu_in_menu = create_menu_in_menu_with_mnemonic( menu, _( "Filter" ) ); + create_check_menu_item_with_mnemonic( menu_in_menu, _( "World" ), G_CALLBACK( HandleCommand ), ID_FILTER_WORLD, FALSE ); create_check_menu_item_with_mnemonic( menu_in_menu, _( "Entities" ), G_CALLBACK( HandleCommand ), ID_FILTER_ENTITIES, FALSE ); - create_check_menu_item_with_mnemonic( menu_in_menu, _( "Areaportals" ), G_CALLBACK( HandleCommand ), ID_FILTER_AREAPORTALS, FALSE ); - create_check_menu_item_with_mnemonic( menu_in_menu, _( "Translucent" ), G_CALLBACK( HandleCommand ), ID_FILTER_TRANSLUCENT, FALSE ); + if ( g_pGameDescription->idTech2 ) { + create_check_menu_item_with_mnemonic( menu_in_menu, _( "Windows" ), G_CALLBACK( HandleCommand ), ID_FILTER_TRANSLUCENT, FALSE ); + } else { + create_check_menu_item_with_mnemonic( menu_in_menu, _( "Translucent" ), G_CALLBACK( HandleCommand ), ID_FILTER_TRANSLUCENT, FALSE ); + } create_check_menu_item_with_mnemonic( menu_in_menu, _( "Liquids" ), G_CALLBACK( HandleCommand ), ID_FILTER_LIQUIDS, FALSE ); + create_check_menu_item_with_mnemonic( menu_in_menu, _( "Sky" ), G_CALLBACK( HandleCommand ), ID_FILTER_SKY, FALSE ); create_check_menu_item_with_mnemonic( menu_in_menu, _( "Caulk" ), G_CALLBACK( HandleCommand ), ID_FILTER_CAULK, FALSE ); create_check_menu_item_with_mnemonic( menu_in_menu, _( "Clips" ), G_CALLBACK( HandleCommand ), ID_FILTER_CLIPS, FALSE ); - create_check_menu_item_with_mnemonic( menu_in_menu, _( "Paths" ), G_CALLBACK( HandleCommand ), ID_FILTER_PATHS, FALSE ); - create_check_menu_item_with_mnemonic( menu_in_menu, _( "Clusterportals" ), G_CALLBACK( HandleCommand ), ID_FILTER_CLUSTERPORTALS, FALSE ); + create_check_menu_item_with_mnemonic( menu_in_menu, _( "Bot clips" ), G_CALLBACK( HandleCommand ), ID_FILTER_BOTCLIPS, FALSE ); create_check_menu_item_with_mnemonic( menu_in_menu, _( "Lights" ), G_CALLBACK( HandleCommand ), ID_FILTER_LIGHTS, FALSE ); create_check_menu_item_with_mnemonic( menu_in_menu, _( "Structural" ), G_CALLBACK( HandleCommand ), ID_FILTER_STRUCTURAL, FALSE ); - item = create_check_menu_item_with_mnemonic( menu_in_menu, _( "Lightgrid" ), G_CALLBACK( HandleCommand ), ID_FILTER_LIGHTGRID, FALSE ); - g_object_set_data( G_OBJECT( window ), "menu_filter_lightgrid", item ); - create_check_menu_item_with_mnemonic( menu_in_menu, _( "Patches" ), G_CALLBACK( HandleCommand ), ID_FILTER_PATCHES, FALSE ); create_check_menu_item_with_mnemonic( menu_in_menu, _( "Details" ), G_CALLBACK( HandleCommand ), ID_FILTER_DETAILS, FALSE ); create_check_menu_item_with_mnemonic( menu_in_menu, _( "Hints" ), G_CALLBACK( HandleCommand ), ID_FILTER_HINTSSKIPS, FALSE ); create_check_menu_item_with_mnemonic( menu_in_menu, _( "Models" ), G_CALLBACK( HandleCommand ), ID_FILTER_MODELS, FALSE ); + create_check_menu_item_with_mnemonic( menu_in_menu, _( "Areaportals" ), G_CALLBACK( HandleCommand ), ID_FILTER_AREAPORTALS, FALSE ); + if ( !g_pGameDescription->idTech2) { + create_check_menu_item_with_mnemonic( menu_in_menu, _( "Clusterportals" ), G_CALLBACK( HandleCommand ), ID_FILTER_CLUSTERPORTALS, FALSE ); + } create_check_menu_item_with_mnemonic( menu_in_menu, _( "Triggers" ), G_CALLBACK( HandleCommand ), ID_FILTER_TRIGGERS, FALSE ); - create_check_menu_item_with_mnemonic( menu_in_menu, _( "Botclips" ), G_CALLBACK( HandleCommand ), ID_FILTER_BOTCLIPS, FALSE ); + create_check_menu_item_with_mnemonic( menu_in_menu, _( "Paths" ), G_CALLBACK( HandleCommand ), ID_FILTER_PATHS, FALSE ); + + if ( !g_pGameDescription->idTech2) { + item = create_check_menu_item_with_mnemonic( menu_in_menu, _( "Lightgrid" ), G_CALLBACK( HandleCommand ), ID_FILTER_LIGHTGRID, FALSE ); + g_object_set_data( G_OBJECT( window ), "menu_filter_lightgrid", item ); + create_check_menu_item_with_mnemonic( menu_in_menu, _( "Patches" ), G_CALLBACK( HandleCommand ), ID_FILTER_PATCHES, FALSE ); + } menu_separator( menu ); menu_in_menu = create_menu_in_menu_with_mnemonic( menu, _( "Hide/Show" ) ); @@ -3999,6 +4012,9 @@ void MainFrame::SetButtonMenuStates(){ item = GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "menu_filter_hintsskips" ) ); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( item ), ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_HINTSSKIPS ) != 0 ); + item = GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "menu_filter_sky" ) ); + gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( item ), + ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_SKY ) != 0 ); item = GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "menu_filter_models" ) ); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( item ), ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_MODELS ) != 0 ); @@ -7808,6 +7824,20 @@ void MainFrame::OnFilterWorld(){ Sys_UpdateWindows( W_XY | W_CAMERA ); } +void MainFrame::OnFilterSky(){ + GtkWidget *item = GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "menu_filter_sky" ) ); + g_bIgnoreCommands++; + if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_SKY ) & EXCLUDE_SKY ) { + gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( item ), TRUE ); + } + else{ + gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( item ), FALSE ); + } + g_bIgnoreCommands--; + PerformFiltering(); + Sys_UpdateWindows( W_XY | W_CAMERA ); +} + diff --git a/radiant/mainframe.h b/radiant/mainframe.h index cdca6af2..51c967de 100644 --- a/radiant/mainframe.h +++ b/radiant/mainframe.h @@ -401,7 +401,8 @@ struct SKeyInfo #define ID_FILTER_CLUSTERPORTALS 40224 #define ID_FILTER_LIGHTGRID 40225 #define ID_FILTER_STRUCTURAL 40226 -#define ID_FILTER_BOTCLIPS 40227 +#define ID_FILTER_BOTCLIPS 40227 +#define ID_FILTER_SKY 40228 #define ID_CURVE_REDISPERSE_INTERMEDIATE_COLS 40230 #define ID_CURVE_REDISPERSE_INTERMEDIATE_ROWS 40231 @@ -898,6 +899,7 @@ void OnFilterPatches(); void OnFilterTranslucent(); void OnFilterTriggers(); void OnFilterWorld(); +void OnFilterSky(); void OnFilterPaths(); void OnFilterClusterportals(); void OnFilterLightgrid(); diff --git a/radiant/qedefs.h b/radiant/qedefs.h index 499e4faa..c3788dcd 100644 --- a/radiant/qedefs.h +++ b/radiant/qedefs.h @@ -83,7 +83,8 @@ #define EXCLUDE_TERRAIN 0x00008000 #define EXCLUDE_LIGHTGRID 0x00010000 #define EXCLUDE_STRUCTURAL 0x00020000 -#define EXCLUDE_BOTCLIP 0x00040000 +#define EXCLUDE_BOTCLIP 0x00040000 +#define EXCLUDE_SKY 0x00080000 #define INCLUDE_EASY 0x00000001 #define INCLUDE_NORMAL 0x00000002 diff --git a/radiant/qfiles.h b/radiant/qfiles.h index 945ba177..e493bbff 100644 --- a/radiant/qfiles.h +++ b/radiant/qfiles.h @@ -417,6 +417,9 @@ typedef struct texinfo_s #define SURF_TRANS66 0x20 #define SURF_FLOWING 0x40 // scroll towards angle #define SURF_NODRAW 0x80 // don't bother referencing the texture +#define SURF_HINT 0x100 +#define SURF_SKIP 0x200 +#define SURF_ALPHA_TEST 0x400 #define SURF_PATCH 0x20000000 #define SURF_CURVE_FAKE 0x40000000