]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/hydratoolz/plugin.cpp
uncrustify! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / contrib / hydratoolz / plugin.cpp
1 /*
2    Copyright (C) 1999-2007 id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
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.
11
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.
16
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
20  */
21
22 #include "plugin.h"
23 #include "version.h"
24
25 /*! \file plugin.cpp
26     \brief HydraToolz!
27
28     HydraToolz by Dominic Clifton - Hydra (Hydra@Hydras-World.com)
29
30     Overview
31     ========
32
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.
35
36     Version History
37     ===============
38
39     v0.1 - 28/May/2002
40       - Initial version.
41
42     v1.0 - 10/March/2003
43       - Added more console output
44       - Removed some old test code
45       - Tweaked dialog box.
46       - Fixed up for Radiant 1.3.5
47
48
49     ToDo
50     ====
51
52     Nothing...
53
54  */
55
56 // =============================================================================
57 // Globals
58
59 _QERFuncTable_1 g_FuncTable;
60 _QERFileSystemTable g_FileSystemTable;
61 _QEREntityTable g_EntityTable;
62
63
64 // =============================================================================
65 // Ripped from cmdlib.cpp
66
67 /*
68    ====================
69    Extract file parts
70    ====================
71  */
72 void HYDRA_ExtractFilePath( const char *path, char *dest ){
73         const char *src;
74
75         src = path + strlen( path ) - 1;
76
77 //
78 // back up until a \ or the start
79 //
80         while ( src != path && *( src - 1 ) != '/' && *( src - 1 ) != '\\' )
81                 src--;
82
83         memcpy( dest, path, src - path );
84         dest[src - path] = 0;
85 }
86
87 void HYDRA_ExtractFileName( const char *path, char *dest ){
88         const char *src;
89
90         src = path + strlen( path ) - 1;
91
92 //
93 // back up until a \ or the start
94 //
95         while ( src != path && *( src - 1 ) != '/'
96                         && *( src - 1 ) != '\\' )
97                 src--;
98
99         while ( *src )
100         {
101                 *dest++ = *src++;
102         }
103         *dest = 0;
104 }
105
106 void HYDRA_ConvertDOSToUnixName( char *dst, const char *src ){
107         while ( *src )
108         {
109                 if ( *src == '\\' ) {
110                         *dst = '/';
111                 }
112                 else{
113                         *dst = *src;
114                 }
115                 dst++; src++;
116         }
117         *dst = 0;
118 }
119
120 // End of rip from cmdlib.cpp
121
122 // =============================================================================
123 // Actual Plugin Code
124
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.
127
128 GSList *AddToWadList( GSList *wadlist, const char *shadername, const char *wad ){
129         char tmpstr[QER_MAX_NAMELEN];
130         char *wadname;
131         if ( !shadername && !wad ) {
132                 return wadlist;
133         }
134
135         if ( shadername ) {
136                 if ( strcmp( shadername,"color" ) == 0 ) {
137                         return wadlist;
138                 }
139                 HYDRA_ExtractFilePath( shadername,tmpstr );
140                 // Sys_Printf("checking: %s\n",shadername);
141
142                 int l = strlen( tmpstr ) - 1;
143
144                 if ( tmpstr[l] == '/' || tmpstr[l] == '\\' ) {
145                         tmpstr[l] = 0;
146                 }
147                 else
148                 {
149                         Sys_Printf( "HydraToolz: WARNING: Unknown wad file for shader %s\n",shadername );
150                         return wadlist;
151                 }
152
153                 HYDRA_ExtractFileName( tmpstr,tmpstr );
154
155                 wadname = (char *)malloc( strlen( tmpstr ) + 5 );
156                 sprintf( wadname,"%s.wad",tmpstr );
157         }
158         else
159         {
160                 wadname = strdup( wad );
161         }
162
163         for ( GSList *l = wadlist; l != NULL ; l = l->next )
164         {
165                 if ( !stricmp( (char *)l->data,wadname ) ) {
166                         free( wadname );
167                         return wadlist;
168                 }
169         }
170
171         Sys_Printf( "HydraToolz: Adding Wad File to WAD list: %s (reason: ",wadname );
172         if ( shadername ) {
173                 Sys_Printf( "see shader \"%s\")\n", shadername );
174         }
175         else{
176                 Sys_Printf( "already in WAD key. )\n" );
177         }
178         return ( g_slist_append( wadlist, wadname ) );
179 }
180
181 void UpdateWadKeyPair( void ){
182         int i,nb;
183
184         char wads[2048]; // change to CString usage ?
185         *wads = 0;
186         char *p1,*p2;
187         entity_t *pEntity;
188         epair_t *pEpair;
189         GSList *wadlist = NULL;
190         face_t  *f;
191         brush_t *b;
192         char cleanwadname[QER_MAX_NAMELEN];
193         char *actualwad;
194
195
196         pEntity = (entity_t *)g_FuncTable.m_pfnGetEntityHandle( 0 ); // get the worldspawn ent
197
198         Sys_Printf( "HydraToolz: Searching for in-use wad files...\n" );
199         for ( pEpair = pEntity->epairs; pEpair != NULL; pEpair = pEpair->next )
200         {
201                 if ( stricmp( pEpair->key,"wad" ) == 0 ) {
202                         strcpy( wads,pEpair->value );
203                         HYDRA_ConvertDOSToUnixName( wads,wads );
204
205                         Sys_Printf( "HydraToolz: Current wad key is \"%s\"!\n",wads );
206
207                         // ok, we got the list of ; delimited wads, now split it into a GSList that contains
208                         // just the wad names themselves.
209
210                         p1 = wads;
211
212                         do
213                         {
214                                 p2 = strchr( p1,';' );
215                                 if ( p2 ) {
216                                         *p2 = 0; // swap the ; with a null terminator
217
218                                 }
219                                 if ( strchr( p1,'/' ) || strchr( p1,'\\' ) ) {
220                                         HYDRA_ExtractFileName( p1,cleanwadname );
221                                         wadlist = AddToWadList( wadlist, NULL, cleanwadname );
222                                 }
223                                 else
224                                 {
225                                         wadlist = AddToWadList( wadlist, NULL, p1 );
226                                 }
227                                 if ( p2 ) {
228                                         p1 = p2 + 1; // point back to the remainder of the string
229                                 }
230                                 else{
231                                         p1 = NULL; // make it so we exit the loop.
232
233                                 }
234                         } while ( p1 );
235
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 ?
240
241                         break; // we don't need to process any more key/pairs.
242                 }
243         }
244
245         if ( !*wads ) {
246                 Sys_Printf( "HydraToolz: No \"wad\" keypair wound in worldspawn\n" );
247         }
248
249
250         nb = g_FuncTable.m_pfnAllocateActiveBrushHandles();
251         for ( i = 0; i < nb; i++ )
252         {
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 );
256                 }
257                 else
258                 {
259                         for ( f = b->brush_faces ; f ; f = f->next )
260                         {
261                                 wadlist = AddToWadList( wadlist, f->pShader->getName(),NULL );
262                         }
263                 }
264         }
265         g_FuncTable.m_pfnReleaseActiveBrushHandles();
266
267         nb = g_FuncTable.m_pfnAllocateSelectedBrushHandles();
268         for ( i = 0; i < nb; i++ )
269         {
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 );
273                 }
274                 else
275                 {
276                         for ( f = b->brush_faces ; f ; f = f->next )
277                         {
278                                 wadlist = AddToWadList( wadlist, f->pShader->getName(),NULL );
279                         }
280                 }
281         }
282         g_FuncTable.m_pfnReleaseSelectedBrushHandles();
283
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.
287
288         *wads = 0;
289         while ( wadlist )
290         {
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 );
294                 }
295                 else
296                 {
297                         if ( wads[0] ) {
298                                 strcat( wads,";" );
299                         }
300
301                         actualwad = vfsGetFullPath( (char *)wadlist->data, 0, 0 );
302
303                         if ( actualwad ) {
304                                 strcat( wads, actualwad );
305                         }
306                         else
307                         {
308                                 Sys_Printf( "HydraToolz: WARNING: could not locate wad file %s\n",(char *)wadlist->data );
309                                 strcat( wads, (char *)wadlist->data );
310                         }
311                 }
312
313                 free( wadlist->data );
314                 wadlist = g_slist_remove( wadlist, wadlist->data );
315         }
316
317         // store the wad list back in the worldspawn.
318         if ( *wads ) {
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 );
323
324         }
325
326         Sys_Printf( "HydraToolz: Finished rebuilding wad keypair!\n" );
327
328 }
329
330 // =============================================================================
331 // PLUGIN INTERFACE STUFF
332
333 // plugin name
334 const char *PLUGIN_NAME = "HydraToolz";
335
336 // commands in the menu
337 const char *PLUGIN_COMMANDS = "About...;Create/Update WAD keypair";
338
339 const char *PLUGIN_ABOUT = "HydraToolz v1.0 for GTKRadiant\n\n"
340                                                    "By Hydra!";
341
342 extern "C" void* WINAPI QERPlug_GetFuncTable(){
343         return &g_FuncTable;
344 }
345
346 const char* QERPlug_Init( void* hApp, void *pWidget ){
347         return "HydraToolz for GTKRadiant"; // do we need this ? hmmm
348 }
349
350 const char* QERPlug_GetName(){
351         return (char*)PLUGIN_NAME;
352 }
353
354 const char* QERPlug_GetCommandList(){
355         return PLUGIN_COMMANDS;
356 }
357
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" ) ) {
360                 UpdateWadKeyPair();
361         }
362         else if ( !strcmp( p, "About..." ) ) {
363                 g_FuncTable.m_pfnMessageBox( NULL, PLUGIN_ABOUT, "About", MB_OK, NULL );
364         }
365 }
366
367 // =============================================================================
368 // SYNAPSE
369
370 CSynapseServer* g_pSynapseServer = NULL;
371 CSynapseClientHydraToolz g_SynapseClient;
372
373 #if __GNUC__ >= 4
374 #pragma GCC visibility push(default)
375 #endif
376 extern "C" CSynapseClient * SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces( const char *version, CSynapseServer *pServer ) {
377 #if __GNUC__ >= 4
378 #pragma GCC visibility pop
379 #endif
380         if ( strcmp( version, SYNAPSE_VERSION ) ) {
381                 Syn_Printf( "ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version );
382                 return NULL;
383         }
384         g_pSynapseServer = pServer;
385         g_pSynapseServer->IncRef();
386         Set_Syn_Printf( g_pSynapseServer->Get_Syn_Printf() );
387
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;
393 }
394
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;
402                 return true;
403         }
404
405         Syn_Printf( "ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo() );
406         return false;
407 }
408
409 const char* CSynapseClientHydraToolz::GetInfo(){
410         return "HydraToolz plugin built " __DATE__ " " RADIANT_VERSION;
411 }