]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/model/plugin.cpp
ea5ac937bec0b414ac32b488da10ce2f35d1aec2
[xonotic/netradiant.git] / plugins / model / plugin.cpp
1
2 /*
3 Copyright (C) 1999-2007 id Software, Inc. and contributors.
4 For a list of contributors, see the accompanying CONTRIBUTORS file.
5
6 This file is part of GtkRadiant.
7
8 GtkRadiant is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 GtkRadiant is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GtkRadiant; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21 */
22
23 #include "plugin.h"
24
25 // toolbar implementation
26
27 class CFlushReloadSelectedToolbarButton : public IToolbarButton
28 {
29 public:
30   virtual const char* getImage() const
31   {
32     return "model_reload_entity.bmp";
33   }
34   virtual const char* getText() const
35   {
36     return "Reload";
37   }
38   virtual const char* getTooltip() const
39   {
40     return "Flush & Reload Selected Model";
41   }
42   virtual void activate() const
43   {
44     DoFlushReloadSelected();
45   }
46   virtual EType getType() const
47   {
48     return eButton;
49   }
50 };
51
52 CFlushReloadSelectedToolbarButton g_flushreloadselected;
53
54 unsigned int ToolbarButtonCount()
55 {
56   return 1;
57 }
58
59 const IToolbarButton* GetToolbarButton(unsigned int index)
60 {
61   return &g_flushreloadselected;
62 }
63
64 // =============================================================================
65 // Pico utility functions
66
67 #include "picomodel.h"
68
69 void PicoPrintFunc( int level, const char *str )
70 {
71         if( str == NULL )
72                 return;
73         switch( level )
74         {
75                 case PICO_NORMAL:
76                         Sys_Printf( "%s\n", str );
77                         break;
78                 
79                 case PICO_VERBOSE:
80                         Sys_FPrintf( SYS_VRB, "%s\n", str );
81                         break;
82                 
83                 case PICO_WARNING:
84                         Sys_Printf( "WARNING: %s\n", str );
85                         break;
86                 
87                 case PICO_ERROR:
88                         Sys_FPrintf( SYS_VRB, "ERROR: %s\n", str );
89                         break;
90                 
91                 case PICO_FATAL:
92       Sys_Printf( "ERROR: %s\n", str );
93                         break;
94         }
95 }
96
97 void PicoLoadFileFunc( char *name, byte **buffer, int *bufSize )
98 {
99         *bufSize = vfsLoadFile( (const char*) name, (void**) buffer, 0 );
100 }
101
102 void PicoFreeFileFunc( void* file )
103 {
104         vfsFreeFile(file);
105 }
106
107 static void initialise()
108 {
109         PicoInit();
110         PicoSetMallocFunc( malloc );
111         PicoSetFreeFunc( free );
112         PicoSetPrintFunc( PicoPrintFunc );
113         PicoSetLoadFileFunc( PicoLoadFileFunc );
114         PicoSetFreeFileFunc( PicoFreeFileFunc );
115 }
116
117 static void add_model_apis(CSynapseClient& client)
118 {
119   const picoModule_t** modules = PicoModuleList( NULL );
120   while(*modules != NULL)
121   {
122     const picoModule_t* module = *modules++;
123     if(module->canload && module->load)
124       for(unsigned int j = 0; module->defaultExts[j] != NULL; j++)
125         client.AddAPI(MODEL_MAJOR, module->defaultExts[j], sizeof(_QERPlugModelTable));
126   }   
127 }
128
129 static bool model_is_supported(const char* extension)
130 {
131   const picoModule_t** modules = PicoModuleList( NULL );
132   while(*modules != NULL)
133   {
134     const picoModule_t* module = *modules++;
135     if(module->canload && module->load)
136       for(unsigned int j = 0; module->defaultExts[j] != NULL; j++)
137         if(strcmp(extension, module->defaultExts[j]) == 0)
138           return true;
139   }
140   return false;
141 }
142
143 void init_filetypes()
144 {
145   const picoModule_t **modules = PicoModuleList(NULL);
146   while(*modules != NULL)
147   {
148     const picoModule_t* module = *modules++;
149     if(module->canload && module->load)
150     {
151       for(char*const* ext = module->defaultExts; *ext != NULL; ++ext)
152       {
153         char buf[16];
154         buf[0] = '*';
155         buf[1] = '.';
156         strcpy(buf+2, *ext);
157         GetFileTypeRegistry()->addType(MODEL_MAJOR, filetype_t(module->displayName, buf));
158       }
159     }
160   }
161 }
162
163 // plugin implementation
164
165 static const char *PLUGIN_NAME = "Model loading module";
166 static const char *PLUGIN_COMMANDS = "About;-;Flush & Reload Models;Flush & Reload Selected";
167 static const char *PLUGIN_ABOUT = "Model Module v1.0 for GtkRadiant\nby Arnout van Meer (rr2do2@splashdamage.com)\n\nBased on the MD3Model Module by SPoG\nPicoModel Library Copyright (c) 2002, Randy Reddig & seaw0lf";
168
169 extern "C" const char* QERPlug_Init (void *hApp, void* pMainWidget)
170 {
171   init_filetypes();
172   return (char *) PLUGIN_NAME;
173 }
174
175 extern "C" const char* QERPlug_GetName ()
176 {
177   return (char *) PLUGIN_NAME;
178 }
179
180 extern "C" const char* QERPlug_GetCommandList ()
181 {
182   return (char *) PLUGIN_COMMANDS;
183 }
184
185 extern "C" void QERPlug_Dispatch (const char *p, vec3_t vMin, vec3_t vMax, bool bSingleBrush)
186 {
187   if( !strcmp( p, "Flush & Reload Selected" ) )
188     DoFlushReloadSelected();
189   else if( !strcmp( p, "Flush & Reload Models" ) )
190     DoFlushReloadAll();
191   else if( !strcmp( p, "About" ) )
192     g_FuncTable.m_pfnMessageBox(NULL, PLUGIN_ABOUT, "About", MB_OK, NULL);
193 }
194
195
196 void DoFlushReloadSelected() {
197 }
198
199 void DoFlushReloadAll() {
200   GetModelCache()->RefreshAll();
201 }
202
203 // =============================================================================
204
205 // function tables
206 _QERFuncTable_1 g_FuncTable;
207 _QERQglTable g_QglTable;
208 _QERShadersTable g_ShadersTable;
209 _QERFileSystemTable g_FileSystemTable;
210
211 // =============================================================================
212 // SYNAPSE
213
214 CSynapseServer* g_pSynapseServer = NULL;
215 CSynapseClientModel g_SynapseClient;
216
217 static const XMLConfigEntry_t entries[] = 
218   { { SHADERS_MAJOR, SYN_REQUIRE, sizeof(g_ShadersTable), &g_ShadersTable }, 
219     { VFS_MAJOR, SYN_REQUIRE, sizeof(g_FileSystemTable), &g_FileSystemTable },
220     { NULL, SYN_UNKNOWN, 0, NULL } };
221
222 #if __GNUC__ >= 4
223 #pragma GCC visibility push(default)
224 #endif
225 extern "C" CSynapseClient* SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces( const char *version, CSynapseServer *pServer ) {
226 #if __GNUC__ >= 4
227 #pragma GCC visibility pop
228 #endif
229   if (strcmp(version, SYNAPSE_VERSION))
230   {
231     Syn_Printf("ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version);
232     return NULL;
233   }
234   g_pSynapseServer = pServer;
235   g_pSynapseServer->IncRef();
236   Set_Syn_Printf( g_pSynapseServer->Get_Syn_Printf() );
237
238   initialise();
239   
240   add_model_apis(g_SynapseClient);
241   g_SynapseClient.AddAPI(TOOLBAR_MAJOR, "model", sizeof(_QERPlugToolbarTable));
242   g_SynapseClient.AddAPI(PLUGIN_MAJOR, "model", sizeof(_QERPluginTable));
243
244   g_SynapseClient.AddAPI(RADIANT_MAJOR, NULL, sizeof(g_FuncTable), SYN_REQUIRE, &g_FuncTable);
245   g_SynapseClient.AddAPI(QGL_MAJOR, NULL, sizeof(g_QglTable), SYN_REQUIRE, &g_QglTable);
246
247   if ( !g_SynapseClient.ConfigXML( pServer, NULL, entries ) ) {
248     return NULL;
249   }
250   
251   return &g_SynapseClient;
252 }
253
254 bool CSynapseClientModel::RequestAPI(APIDescriptor_t *pAPI)
255 {
256   if (!strcmp(pAPI->major_name, MODEL_MAJOR))
257   {
258     _QERPlugModelTable* pTable= static_cast<_QERPlugModelTable*>(pAPI->mpTable);
259
260     if (model_is_supported(pAPI->minor_name))
261     {
262       pTable->m_pfnLoadModel = &LoadModel;
263       return true;
264     }
265   }
266   else if (!strcmp(pAPI->major_name, TOOLBAR_MAJOR))
267   {
268     _QERPlugToolbarTable* pTable= static_cast<_QERPlugToolbarTable*>(pAPI->mpTable);
269
270     pTable->m_pfnToolbarButtonCount = &ToolbarButtonCount;
271     pTable->m_pfnGetToolbarButton = &GetToolbarButton;
272     return true;
273   }
274   else if (!strcmp(pAPI->major_name, PLUGIN_MAJOR))
275   {
276     _QERPluginTable* pTable= static_cast<_QERPluginTable*>(pAPI->mpTable);
277
278     pTable->m_pfnQERPlug_Init = QERPlug_Init;
279     pTable->m_pfnQERPlug_GetName = QERPlug_GetName;
280     pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;
281     pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch;
282     return true;
283   }
284
285   Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo());
286   return false;
287 }
288
289 #include "version.h"
290
291 const char* CSynapseClientModel::GetInfo()
292 {
293   return "picomodel loader module built " __DATE__ " " RADIANT_VERSION;
294 }
295
296 const char* CSynapseClientModel::GetName()
297 {
298   return "model";
299 }