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