2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 HydraToolz by Dominic Clifton - Hydra (Hydra@Hydras-World.com)
33 This plugin allows the user to rebuild the "wad" key pair in the worldspawn
34 so that it has a list of all the .wad files in use.
43 - Added more console output
44 - Removed some old test code
46 - Fixed up for Radiant 1.3.5
56 // =============================================================================
59 _QERFuncTable_1 g_FuncTable;
60 _QERFileSystemTable g_FileSystemTable;
61 _QEREntityTable g_EntityTable;
64 // =============================================================================
65 // Ripped from cmdlib.cpp
72 void HYDRA_ExtractFilePath( const char *path, char *dest ){
75 src = path + strlen( path ) - 1;
78 // back up until a \ or the start
80 while ( src != path && *( src - 1 ) != '/' && *( src - 1 ) != '\\' )
83 memcpy( dest, path, src - path );
87 void HYDRA_ExtractFileName( const char *path, char *dest ){
90 src = path + strlen( path ) - 1;
93 // back up until a \ or the start
95 while ( src != path && *( src - 1 ) != '/'
96 && *( src - 1 ) != '\\' )
106 void HYDRA_ConvertDOSToUnixName( char *dst, const char *src ){
109 if ( *src == '\\' ) {
120 // End of rip from cmdlib.cpp
122 // =============================================================================
123 // Actual Plugin Code
125 // get the wad name from the shader name (or an actual wadname) and add to a list of wad names making
126 // sure we don't add duplicates.
128 GSList *AddToWadList( GSList *wadlist, const char *shadername, const char *wad ){
129 char tmpstr[QER_MAX_NAMELEN];
131 if ( !shadername && !wad ) {
136 if ( strcmp( shadername,"color" ) == 0 ) {
139 HYDRA_ExtractFilePath( shadername,tmpstr );
140 // Sys_Printf("checking: %s\n",shadername);
142 int l = strlen( tmpstr ) - 1;
144 if ( tmpstr[l] == '/' || tmpstr[l] == '\\' ) {
149 Sys_Printf( "HydraToolz: WARNING: Unknown wad file for shader %s\n",shadername );
153 HYDRA_ExtractFileName( tmpstr,tmpstr );
155 wadname = (char *)malloc( strlen( tmpstr ) + 5 );
156 sprintf( wadname,"%s.wad",tmpstr );
160 wadname = strdup( wad );
163 for ( GSList *l = wadlist; l != NULL ; l = l->next )
165 if ( !stricmp( (char *)l->data,wadname ) ) {
171 Sys_Printf( "HydraToolz: Adding Wad File to WAD list: %s (reason: ",wadname );
173 Sys_Printf( "see shader \"%s\")\n", shadername );
176 Sys_Printf( "already in WAD key. )\n" );
178 return ( g_slist_append( wadlist, wadname ) );
181 void UpdateWadKeyPair( void ){
184 char wads[2048]; // change to CString usage ?
189 GSList *wadlist = NULL;
192 char cleanwadname[QER_MAX_NAMELEN];
196 pEntity = (entity_t *)g_FuncTable.m_pfnGetEntityHandle( 0 ); // get the worldspawn ent
198 Sys_Printf( "HydraToolz: Searching for in-use wad files...\n" );
199 for ( pEpair = pEntity->epairs; pEpair != NULL; pEpair = pEpair->next )
201 if ( stricmp( pEpair->key,"wad" ) == 0 ) {
202 strcpy( wads,pEpair->value );
203 HYDRA_ConvertDOSToUnixName( wads,wads );
205 Sys_Printf( "HydraToolz: Current wad key is \"%s\"!\n",wads );
207 // ok, we got the list of ; delimited wads, now split it into a GSList that contains
208 // just the wad names themselves.
214 p2 = strchr( p1,';' );
216 *p2 = 0; // swap the ; with a null terminator
219 if ( strchr( p1,'/' ) || strchr( p1,'\\' ) ) {
220 HYDRA_ExtractFileName( p1,cleanwadname );
221 wadlist = AddToWadList( wadlist, NULL, cleanwadname );
225 wadlist = AddToWadList( wadlist, NULL, p1 );
228 p1 = p2 + 1; // point back to the remainder of the string
231 p1 = NULL; // make it so we exit the loop.
236 // ok, now we have a list of wads in GSList.
237 // now we need to add any new wadfiles (with their paths) to this list
238 // so scan all brushes and see what wads are in use
239 // FIXME: scan brushes only in the region ?
241 break; // we don't need to process any more key/pairs.
246 Sys_Printf( "HydraToolz: No \"wad\" keypair wound in worldspawn\n" );
250 nb = g_FuncTable.m_pfnAllocateActiveBrushHandles();
251 for ( i = 0; i < nb; i++ )
253 b = (brush_t *)g_FuncTable.m_pfnGetActiveBrushHandle( i );
254 if ( b->patchBrush ) { // patches in halflife ?
255 wadlist = AddToWadList( wadlist, b->pPatch->pShader->getName(),NULL );
259 for ( f = b->brush_faces ; f ; f = f->next )
261 wadlist = AddToWadList( wadlist, f->pShader->getName(),NULL );
265 g_FuncTable.m_pfnReleaseActiveBrushHandles();
267 nb = g_FuncTable.m_pfnAllocateSelectedBrushHandles();
268 for ( i = 0; i < nb; i++ )
270 b = (brush_t *)g_FuncTable.m_pfnGetSelectedBrushHandle( i );
271 if ( b->patchBrush ) { // patches in halflife ?
272 wadlist = AddToWadList( wadlist, b->pPatch->pShader->getName(),NULL );
276 for ( f = b->brush_faces ; f ; f = f->next )
278 wadlist = AddToWadList( wadlist, f->pShader->getName(),NULL );
282 g_FuncTable.m_pfnReleaseSelectedBrushHandles();
284 Sys_Printf( "HydraToolz: Rebuilding worldspawn's \"wad\" key-pair...\n" );
285 // Now we have a complete list of wadnames (without paths) so we just have to turn this
286 // back to a ; delimited list.
291 // skip wad files if they start with "common-"
292 if ( strnicmp( (char *)wadlist->data,"common-",7 ) == 0 ) {
293 Sys_Printf( "HydraToolz: Skipping radiant/user-supplied wad file %s\n",(char *)wadlist->data );
301 actualwad = vfsGetFullPath( (char *)wadlist->data, 0, 0 );
304 strcat( wads, actualwad );
308 Sys_Printf( "HydraToolz: WARNING: could not locate wad file %s\n",(char *)wadlist->data );
309 strcat( wads, (char *)wadlist->data );
313 free( wadlist->data );
314 wadlist = g_slist_remove( wadlist, wadlist->data );
317 // store the wad list back in the worldspawn.
319 //free(pEpair->value);
320 //pEpair->value = strdup(wads);
321 SetKeyValue( pEntity, "wad", wads );
322 Sys_Printf( "HydraToolz: Setting worldspawn \"wad\" key value to \"%s\"\n",wads );
326 Sys_Printf( "HydraToolz: Finished rebuilding wad keypair!\n" );
330 // =============================================================================
331 // PLUGIN INTERFACE STUFF
334 const char *PLUGIN_NAME = "HydraToolz";
336 // commands in the menu
337 const char *PLUGIN_COMMANDS = "About...;Create/Update WAD keypair";
339 const char *PLUGIN_ABOUT = "HydraToolz v1.0 for GTKRadiant\n\n"
342 extern "C" void* WINAPI QERPlug_GetFuncTable(){
346 const char* QERPlug_Init( void* hApp, void *pWidget ){
347 return "HydraToolz for GTKRadiant"; // do we need this ? hmmm
350 const char* QERPlug_GetName(){
351 return (char*)PLUGIN_NAME;
354 const char* QERPlug_GetCommandList(){
355 return PLUGIN_COMMANDS;
358 extern "C" void QERPlug_Dispatch( const char* p, vec3_t vMin, vec3_t vMax, bool bSingleBrush ){
359 if ( !strcmp( p, "Create/Update WAD keypair" ) ) {
362 else if ( !strcmp( p, "About..." ) ) {
363 g_FuncTable.m_pfnMessageBox( NULL, PLUGIN_ABOUT, "About", MB_OK, NULL );
367 // =============================================================================
370 CSynapseServer* g_pSynapseServer = NULL;
371 CSynapseClientHydraToolz g_SynapseClient;
374 #pragma GCC visibility push(default)
376 extern "C" CSynapseClient * SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces( const char *version, CSynapseServer *pServer ) {
378 #pragma GCC visibility pop
380 if ( strcmp( version, SYNAPSE_VERSION ) ) {
381 Syn_Printf( "ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version );
384 g_pSynapseServer = pServer;
385 g_pSynapseServer->IncRef();
386 Set_Syn_Printf( g_pSynapseServer->Get_Syn_Printf() );
388 g_SynapseClient.AddAPI( PLUGIN_MAJOR, "HydraToolz", sizeof( _QERPluginTable ) );
389 g_SynapseClient.AddAPI( RADIANT_MAJOR, NULL, sizeof( g_FuncTable ), SYN_REQUIRE, &g_FuncTable );
390 g_SynapseClient.AddAPI( VFS_MAJOR, "wad", sizeof( g_FileSystemTable ), SYN_REQUIRE, &g_FileSystemTable );
391 g_SynapseClient.AddAPI( ENTITY_MAJOR, NULL, sizeof( g_EntityTable ), SYN_REQUIRE, &g_EntityTable );
392 return &g_SynapseClient;
395 bool CSynapseClientHydraToolz::RequestAPI( APIDescriptor_t *pAPI ){
396 if ( !strcmp( pAPI->major_name, PLUGIN_MAJOR ) ) {
397 _QERPluginTable *pTable = static_cast<_QERPluginTable*>( pAPI->mpTable );
398 pTable->m_pfnQERPlug_Init = QERPlug_Init;
399 pTable->m_pfnQERPlug_GetName = QERPlug_GetName;
400 pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;
401 pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch;
405 Syn_Printf( "ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo() );
409 const char* CSynapseClientHydraToolz::GetInfo(){
410 return "HydraToolz plugin built " __DATE__ " " RADIANT_VERSION;