2 Copyright (C) 2006, Stefan Greven.
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
22 #include "shaderplug.h"
24 #include "debugging/debugging.h"
28 #include "string/string.h"
29 #include "modulesystem/singletonmodule.h"
30 #include "stream/stringstream.h"
36 #include "qerplugin.h"
37 #include "ifilesystem.h"
40 #include "iscriplib.h"
42 #include "generic/callback.h"
44 #define CMD_ABOUT "About..."
47 const char SHADERTAG_FILE[] = "shadertags.xml";
50 class ShaderPlugPluginDependencies : public GlobalRadiantModuleRef,
51 public GlobalFileSystemModuleRef,
52 public GlobalShadersModuleRef
55 ShaderPlugPluginDependencies() :
56 GlobalShadersModuleRef( GlobalRadiant().getRequiredGameDescriptionKeyValue( "shaders" ) ){
62 ui::Window main_window{ui::null};
64 std::vector<const char*> archives;
65 std::set<std::string> shaders;
66 std::set<std::string> textures;
68 XmlTagBuilder TagBuilder;
71 const char* init( void* hApp, void* pMainWidget ){
72 main_window = ui::Window::from(pMainWidget);
76 const char* getName(){
80 const char* getCommandList(){
81 return CMD_ABOUT ";-;Create tag file";
84 const char* getCommandTitleList(){
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"
95 RADIANT_NAME " " RADIANT_VERSION_STRING "\n"
98 GlobalRadiant().m_pfnMessageBox( main_window, label_text,
104 if ( string_equal( command, "Create tag file" ) ) {
109 void loadArchiveFile( const char* filename ){
110 archives.push_back( filename );
113 void LoadTextureFile( const char* filename ){
114 std::string s_filename = filename;
117 strcpy( buffer, "textures/" );
119 // append filename without trailing file extension (.tga or .jpg for example)
120 strncat( buffer, filename, s_filename.length() - 4 );
122 std::set<std::string>::iterator iter;
123 iter = shaders.find( buffer );
125 // a shader with this name already exists
126 if ( iter == shaders.end() ) {
127 textures.insert( buffer );
131 void GetTextures( const char* extension ){
132 GlobalFileSystem().forEachFile("textures/", extension, makeCallbackF(LoadTextureFile), 0);
135 void LoadShaderList( const char* filename ){
136 if ( string_equal_prefix( filename, "textures/" ) ) {
137 shaders.insert( filename );
141 void GetAllShaders(){
142 GlobalShaderSystem().foreachShaderName(makeCallbackF(LoadShaderList));
145 void GetArchiveList(){
146 GlobalFileSystem().forEachArchive(makeCallbackF(loadArchiveFile));
147 globalOutputStream() << PLUGIN_NAME ": " << (const Unsigned)Shaderplug::archives.size() << " archives found.\n";
150 void CreateTagFile(){
151 const char* shader_type = GlobalRadiant().getGameDescriptionKeyValue( "shaders" );
154 globalOutputStream() << PLUGIN_NAME ": " << (const Unsigned)shaders.size() << " shaders found.\n";
156 if ( string_equal( shader_type, "quake3" ) ) {
157 GetTextures( "jpg" );
158 GetTextures( "tga" );
159 GetTextures( "png" );
161 globalOutputStream() << PLUGIN_NAME ":" << (const Unsigned)textures.size() << " textures found.\n";
164 if ( shaders.size() || textures.size() != 0 ) {
165 globalOutputStream() << PLUGIN_NAME ":Creating XML tag file.\n";
167 TagBuilder.CreateXmlDocument();
169 std::set<std::string>::reverse_iterator r_iter;
171 for ( r_iter = textures.rbegin(); r_iter != textures.rend(); ++r_iter )
173 TagBuilder.AddShaderNode( const_cast<char*>( ( *r_iter ).c_str() ), STOCK, TEXTURE );
176 for ( r_iter = shaders.rbegin(); r_iter != shaders.rend(); ++r_iter )
178 TagBuilder.AddShaderNode( const_cast<char*>( ( *r_iter ).c_str() ), STOCK, SHADER );
182 StringOutputStream tagFileStream( 256 );
183 tagFileStream << GlobalRadiant().getLocalRcPath() << SHADERTAG_FILE;
184 char* tagFile = tagFileStream.c_str();
187 strcpy( message, "Tag file saved to\n" );
188 strcat( message, tagFile );
189 strcat( message, "\nPlease restart " RADIANT_NAME " now.\n" );
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?",
197 if ( result == eIDYES ) {
198 TagBuilder.SaveXmlDoc( tagFile );
199 GlobalRadiant().m_pfnMessageBox( main_window, message, "INFO", eMB_OK, eMB_ICONASTERISK );
203 TagBuilder.SaveXmlDoc( tagFile );
204 GlobalRadiant().m_pfnMessageBox( main_window, message, "INFO", eMB_OK, eMB_ICONASTERISK );
208 GlobalRadiant().m_pfnMessageBox( main_window,
209 "No shaders or textures found. No XML tag file created!\n"
218 class ShaderPluginModule
220 _QERPluginTable m_plugin;
222 typedef _QERPluginTable Type;
223 STRING_CONSTANT( Name, PLUGIN_NAME );
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;
232 _QERPluginTable* getTable(){
237 typedef SingletonModule<ShaderPluginModule, ShaderPlugPluginDependencies> SingletonShaderPluginModule;
239 SingletonShaderPluginModule g_ShaderPluginModule;
241 extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){
242 initialiseModule( server );
244 g_ShaderPluginModule.selfRegister();