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)
76 src = path + strlen(path) - 1;
79 // back up until a \ or the start
81 while (src != path && *(src-1) != '/' && *(src-1) != '\\')
84 memcpy (dest, path, src-path);
88 void HYDRA_ExtractFileName (const char *path, char *dest)
92 src = path + strlen(path) - 1;
95 // back up until a \ or the start
97 while (src != path && *(src-1) != '/'
108 void HYDRA_ConvertDOSToUnixName( char *dst, const char *src )
121 // End of rip from cmdlib.cpp
123 // =============================================================================
124 // Actual Plugin Code
126 // get the wad name from the shader name (or an actual wadname) and add to a list of wad names making
127 // sure we don't add duplicates.
129 GSList *AddToWadList(GSList *wadlist, const char *shadername, const char *wad)
131 char tmpstr[QER_MAX_NAMELEN];
133 if (!shadername && !wad) return wadlist;
137 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] == '\\')
148 Sys_Printf("HydraToolz: WARNING: Unknown wad file for shader %s\n",shadername);
152 HYDRA_ExtractFileName(tmpstr,tmpstr);
154 wadname = (char *)malloc(strlen(tmpstr) + 5);
155 sprintf(wadname,"%s.wad",tmpstr);
162 for (GSList *l = wadlist; l != NULL ; l = l->next)
164 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);
175 Sys_Printf("already in WAD key. )\n");
176 return ( g_slist_append (wadlist, wadname ) );
179 void UpdateWadKeyPair( void )
183 char wads[2048]; // change to CString usage ?
188 GSList *wadlist = NULL;
191 char cleanwadname[QER_MAX_NAMELEN];
195 pEntity = (entity_t *)g_FuncTable.m_pfnGetEntityHandle(0); // get the worldspawn ent
197 Sys_Printf("HydraToolz: Searching for in-use wad files...\n");
198 for(pEpair = pEntity->epairs; pEpair != NULL; pEpair = pEpair->next)
200 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.
216 *p2 = 0; // swap the ; with a null terminator
218 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
230 p1 = NULL; // make it so we exit the loop.
234 // ok, now we have a list of wads in GSList.
235 // now we need to add any new wadfiles (with their paths) to this list
236 // so scan all brushes and see what wads are in use
237 // FIXME: scan brushes only in the region ?
239 break; // we don't need to process any more key/pairs.
244 Sys_Printf("HydraToolz: No \"wad\" keypair wound in worldspawn\n");
247 nb = g_FuncTable.m_pfnAllocateActiveBrushHandles();
248 for( i = 0; i < nb; i++ )
250 b = (brush_t *)g_FuncTable.m_pfnGetActiveBrushHandle(i);
251 if (b->patchBrush) // patches in halflife ?
253 wadlist = AddToWadList(wadlist, b->pPatch->pShader->getName(),NULL);
256 for (f=b->brush_faces ; f ; f=f->next)
258 wadlist = AddToWadList(wadlist, f->pShader->getName(),NULL);
262 g_FuncTable.m_pfnReleaseActiveBrushHandles();
264 nb = g_FuncTable.m_pfnAllocateSelectedBrushHandles();
265 for( i = 0; i < nb; i++ )
267 b = (brush_t *)g_FuncTable.m_pfnGetSelectedBrushHandle(i);
268 if (b->patchBrush) // patches in halflife ?
270 wadlist = AddToWadList(wadlist, b->pPatch->pShader->getName(),NULL);
273 for (f=b->brush_faces ; f ; f=f->next)
275 wadlist = AddToWadList(wadlist, f->pShader->getName(),NULL);
279 g_FuncTable.m_pfnReleaseSelectedBrushHandles();
281 Sys_Printf("HydraToolz: Rebuilding worldspawn's \"wad\" key-pair...\n");
282 // Now we have a complete list of wadnames (without paths) so we just have to turn this
283 // back to a ; delimited list.
288 // skip wad files if they start with "common-"
289 if (strnicmp((char *)wadlist->data,"common-",7) == 0)
291 Sys_Printf("HydraToolz: Skipping radiant/user-supplied wad file %s\n",(char *)wadlist->data);
298 actualwad = vfsGetFullPath((char *)wadlist->data, 0, 0);
302 strcat(wads, actualwad);
306 Sys_Printf("HydraToolz: WARNING: could not locate wad file %s\n",(char *)wadlist->data);
307 strcat(wads, (char *)wadlist->data);
311 free (wadlist->data);
312 wadlist = g_slist_remove (wadlist, wadlist->data);
315 // store the wad list back in the worldspawn.
318 //free(pEpair->value);
319 //pEpair->value = strdup(wads);
320 SetKeyValue(pEntity, "wad", wads);
321 Sys_Printf("HydraToolz: Setting worldspawn \"wad\" key value to \"%s\"\n",wads);
325 Sys_Printf("HydraToolz: Finished rebuilding wad keypair!\n");
329 // =============================================================================
330 // PLUGIN INTERFACE STUFF
333 const char *PLUGIN_NAME = "HydraToolz";
335 // commands in the menu
336 const char *PLUGIN_COMMANDS = "About...;Create/Update WAD keypair";
338 const char *PLUGIN_ABOUT = "HydraToolz v1.0 for GTKRadiant\n\n"
341 extern "C" void* WINAPI QERPlug_GetFuncTable ()
346 const char* QERPlug_Init (void* hApp, void *pWidget)
348 return "HydraToolz for GTKRadiant"; // do we need this ? hmmm
351 const char* QERPlug_GetName()
353 return (char*)PLUGIN_NAME;
356 const char* QERPlug_GetCommandList()
358 return PLUGIN_COMMANDS;
361 extern "C" void QERPlug_Dispatch(const char* p, vec3_t vMin, vec3_t vMax, bool bSingleBrush)
363 if(!strcmp(p, "Create/Update WAD keypair"))
365 else if(!strcmp(p, "About..."))
366 g_FuncTable.m_pfnMessageBox(NULL, PLUGIN_ABOUT, "About", MB_OK, NULL);
369 // =============================================================================
372 CSynapseServer* g_pSynapseServer = NULL;
373 CSynapseClientHydraToolz g_SynapseClient;
376 #pragma GCC visibility push(default)
378 extern "C" CSynapseClient* SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces( const char *version, CSynapseServer *pServer ) {
380 #pragma GCC visibility pop
382 if (strcmp(version, SYNAPSE_VERSION))
384 Syn_Printf("ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version);
387 g_pSynapseServer = pServer;
388 g_pSynapseServer->IncRef();
389 Set_Syn_Printf(g_pSynapseServer->Get_Syn_Printf());
391 g_SynapseClient.AddAPI(PLUGIN_MAJOR, "HydraToolz", sizeof(_QERPluginTable));
392 g_SynapseClient.AddAPI(RADIANT_MAJOR, NULL, sizeof(g_FuncTable), SYN_REQUIRE, &g_FuncTable);
393 g_SynapseClient.AddAPI(VFS_MAJOR, "wad", sizeof(g_FileSystemTable), SYN_REQUIRE, &g_FileSystemTable);
394 g_SynapseClient.AddAPI(ENTITY_MAJOR, NULL, sizeof(g_EntityTable), SYN_REQUIRE, &g_EntityTable);
395 return &g_SynapseClient;
398 bool CSynapseClientHydraToolz::RequestAPI(APIDescriptor_t *pAPI)
400 if (!strcmp(pAPI->major_name, PLUGIN_MAJOR))
402 _QERPluginTable *pTable = static_cast<_QERPluginTable*>(pAPI->mpTable);
403 pTable->m_pfnQERPlug_Init = QERPlug_Init;
404 pTable->m_pfnQERPlug_GetName = QERPlug_GetName;
405 pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;
406 pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch;
410 Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo());
414 const char* CSynapseClientHydraToolz::GetInfo()
416 return "HydraToolz plugin built " __DATE__ " " RADIANT_VERSION;