]> git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/shaderplug/shaderplug.cpp
bikeshedding: unifying some variable in contrib/shaderplug
[xonotic/netradiant.git] / contrib / shaderplug / shaderplug.cpp
1 /*
2    Copyright (C) 2006, Stefan Greven.
3    All Rights Reserved.
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 "shaderplug.h"
23
24 #include "debugging/debugging.h"
25
26 #include <string>
27 #include <vector>
28 #include "string/string.h"
29 #include "modulesystem/singletonmodule.h"
30 #include "stream/stringstream.h"
31 #include "os/file.h"
32
33 #include <gtk/gtk.h>
34
35 #include "iplugin.h"
36 #include "qerplugin.h"
37 #include "ifilesystem.h"
38 #include "iarchive.h"
39 #include "ishaders.h"
40 #include "iscriplib.h"
41
42 #include "generic/callback.h"
43
44 #define CMD_ABOUT "About..."
45
46 namespace {
47 const char SHADERTAG_FILE[] = "shadertags.xml";
48 }
49
50 class ShaderPlugPluginDependencies : public GlobalRadiantModuleRef,
51         public GlobalFileSystemModuleRef,
52         public GlobalShadersModuleRef
53 {
54 public:
55 ShaderPlugPluginDependencies() :
56         GlobalShadersModuleRef( GlobalRadiant().getRequiredGameDescriptionKeyValue( "shaders" ) ){
57 }
58 };
59
60 namespace Shaderplug
61 {
62 ui::Window main_window{ui::null};
63
64 std::vector<const char*> archives;
65 std::set<std::string> shaders;
66 std::set<std::string> textures;
67
68 XmlTagBuilder TagBuilder;
69 void CreateTagFile();
70
71 const char* init( void* hApp, void* pMainWidget ){
72         main_window = ui::Window::from(pMainWidget);
73         return "";
74 }
75
76 const char* getName(){
77         return PLUGIN_NAME;
78 }
79
80 const char* getCommandList(){
81         return CMD_ABOUT ";-;Create tag file";
82 }
83
84 const char* getCommandTitleList(){
85         return "";
86 }
87
88 void dispatch( const char* command, float* vMin, float* vMax, bool bSingleBrush ){
89         if ( string_equal( command, CMD_ABOUT ) ) {
90                 const char *label_text =
91                         PLUGIN_NAME " " PLUGIN_VERSION " for "
92                         RADIANT_NAME " " RADIANT_VERSION "\n\n"
93                         "Written by Shaderman <shaderman@gmx.net>\n\n"
94                         "Built against "
95                         RADIANT_NAME " " RADIANT_VERSION_STRING "\n"
96                         __DATE__;
97
98                 GlobalRadiant().m_pfnMessageBox( main_window, label_text,
99                                                                                  "About " PLUGIN_NAME,
100                                                                                  eMB_OK,
101                                                                                  eMB_ICONDEFAULT );
102         }
103
104         if ( string_equal( command, "Create tag file" ) ) {
105                 CreateTagFile();
106         }
107 }
108
109 void loadArchiveFile( const char* filename ){
110         archives.push_back( filename );
111 }
112
113 void LoadTextureFile( const char* filename ){
114         std::string s_filename = filename;
115
116         char buffer[256];
117         strcpy( buffer, "textures/" );
118
119         // append filename without trailing file extension (.tga or .jpg for example)
120         strncat( buffer, filename, s_filename.length() - 4 );
121
122         std::set<std::string>::iterator iter;
123         iter = shaders.find( buffer );
124
125         // a shader with this name already exists
126         if ( iter == shaders.end() ) {
127                 textures.insert( buffer );
128         }
129 }
130
131 void GetTextures( const char* extension ){
132         GlobalFileSystem().forEachFile("textures/", extension, makeCallbackF(LoadTextureFile), 0);
133 }
134
135 void LoadShaderList( const char* filename ){
136         if ( string_equal_prefix( filename, "textures/" ) ) {
137                 shaders.insert( filename );
138         }
139 }
140
141 void GetAllShaders(){
142         GlobalShaderSystem().foreachShaderName(makeCallbackF(LoadShaderList));
143 }
144
145 void GetArchiveList(){
146         GlobalFileSystem().forEachArchive(makeCallbackF(loadArchiveFile));
147         globalOutputStream() << PLUGIN_NAME ": " << (const Unsigned)Shaderplug::archives.size() << " archives found.\n";
148 }
149
150 void CreateTagFile(){
151         const char* shader_type = GlobalRadiant().getGameDescriptionKeyValue( "shaders" );
152
153         GetAllShaders();
154         globalOutputStream() << PLUGIN_NAME ": " << (const Unsigned)shaders.size() << " shaders found.\n";
155
156         if ( string_equal( shader_type, "quake3" ) ) {
157                 GetTextures( "jpg" );
158                 GetTextures( "tga" );
159                 GetTextures( "png" );
160
161                 globalOutputStream() << PLUGIN_NAME ":" << (const Unsigned)textures.size() << " textures found.\n";
162         }
163
164         if ( shaders.size() || textures.size() != 0 ) {
165                 globalOutputStream() << PLUGIN_NAME ":Creating XML tag file.\n";
166
167                 TagBuilder.CreateXmlDocument();
168
169                 std::set<std::string>::reverse_iterator r_iter;
170
171                 for ( r_iter = textures.rbegin(); r_iter != textures.rend(); ++r_iter )
172                 {
173                         TagBuilder.AddShaderNode( const_cast<char*>( ( *r_iter ).c_str() ), STOCK, TEXTURE );
174                 }
175
176                 for ( r_iter = shaders.rbegin(); r_iter != shaders.rend(); ++r_iter )
177                 {
178                         TagBuilder.AddShaderNode( const_cast<char*>( ( *r_iter ).c_str() ), STOCK, SHADER );
179                 }
180
181                 // Get the tag file
182                 StringOutputStream tagFileStream( 256 );
183                 tagFileStream << GlobalRadiant().getLocalRcPath() << SHADERTAG_FILE;
184                 char* tagFile = tagFileStream.c_str();
185
186                 char message[256];
187                 strcpy( message, "Tag file saved to\n" );
188                 strcat( message, tagFile );
189                 strcat( message, "\nPlease restart " RADIANT_NAME " now.\n" );
190
191                 if ( file_exists( tagFile ) ) {
192                         EMessageBoxReturn result = GlobalRadiant().m_pfnMessageBox( main_window ,
193                                                                                                                                                 "WARNING! A tag file already exists! Overwrite it?", "Overwrite tag file?",
194                                                                                                                                                 eMB_NOYES,
195                                                                                                                                                 eMB_ICONWARNING );
196
197                         if ( result == eIDYES ) {
198                                 TagBuilder.SaveXmlDoc( tagFile );
199                                 GlobalRadiant().m_pfnMessageBox( main_window, message, "INFO", eMB_OK, eMB_ICONASTERISK );
200                         }
201                 }
202                 else {
203                         TagBuilder.SaveXmlDoc( tagFile );
204                         GlobalRadiant().m_pfnMessageBox( main_window, message, "INFO", eMB_OK, eMB_ICONASTERISK );
205                 }
206         }
207         else {
208                 GlobalRadiant().m_pfnMessageBox( main_window,
209                                                                                  "No shaders or textures found. No XML tag file created!\n"
210                                                                                  "",
211                                                                                  "ERROR",
212                                                                                  eMB_OK,
213                                                                                  eMB_ICONERROR );
214         }
215 }
216 } // namespace
217
218 class ShaderPluginModule
219 {
220 _QERPluginTable m_plugin;
221 public:
222 typedef _QERPluginTable Type;
223 STRING_CONSTANT( Name, PLUGIN_NAME );
224
225 ShaderPluginModule(){
226         m_plugin.m_pfnQERPlug_Init = &Shaderplug::init;
227         m_plugin.m_pfnQERPlug_GetName = &Shaderplug::getName;
228         m_plugin.m_pfnQERPlug_GetCommandList = &Shaderplug::getCommandList;
229         m_plugin.m_pfnQERPlug_GetCommandTitleList = &Shaderplug::getCommandTitleList;
230         m_plugin.m_pfnQERPlug_Dispatch = &Shaderplug::dispatch;
231 }
232 _QERPluginTable* getTable(){
233         return &m_plugin;
234 }
235 };
236
237 typedef SingletonModule<ShaderPluginModule, ShaderPlugPluginDependencies> SingletonShaderPluginModule;
238
239 SingletonShaderPluginModule g_ShaderPluginModule;
240
241 extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){
242         initialiseModule( server );
243
244         g_ShaderPluginModule.selfRegister();
245 }