]> git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/model/plugin.cpp
uncrustify! now the code is only ugly on the *inside*
[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         return "model_reload_entity.bmp";
32 }
33 virtual const char* getText() const {
34         return "Reload";
35 }
36 virtual const char* getTooltip() const {
37         return "Flush & Reload Selected Model";
38 }
39 virtual void activate() const {
40         DoFlushReloadSelected();
41 }
42 virtual EType getType() const {
43         return eButton;
44 }
45 };
46
47 CFlushReloadSelectedToolbarButton g_flushreloadselected;
48
49 unsigned int ToolbarButtonCount(){
50         return 1;
51 }
52
53 const IToolbarButton* GetToolbarButton( unsigned int index ){
54         return &g_flushreloadselected;
55 }
56
57 // =============================================================================
58 // Pico utility functions
59
60 #include "picomodel.h"
61
62 void PicoPrintFunc( int level, const char *str ){
63         if ( str == NULL ) {
64                 return;
65         }
66         switch ( level )
67         {
68         case PICO_NORMAL:
69                 Sys_Printf( "%s\n", str );
70                 break;
71
72         case PICO_VERBOSE:
73                 Sys_FPrintf( SYS_VRB, "%s\n", str );
74                 break;
75
76         case PICO_WARNING:
77                 Sys_Printf( "WARNING: %s\n", str );
78                 break;
79
80         case PICO_ERROR:
81                 Sys_FPrintf( SYS_VRB, "ERROR: %s\n", str );
82                 break;
83
84         case PICO_FATAL:
85                 Sys_Printf( "ERROR: %s\n", str );
86                 break;
87         }
88 }
89
90 void PicoLoadFileFunc( char *name, byte **buffer, int *bufSize ){
91         *bufSize = vfsLoadFile( (const char*) name, (void**) buffer, 0 );
92 }
93
94 void PicoFreeFileFunc( void* file ){
95         vfsFreeFile( file );
96 }
97
98 static void initialise(){
99         PicoInit();
100         PicoSetMallocFunc( malloc );
101         PicoSetFreeFunc( free );
102         PicoSetPrintFunc( PicoPrintFunc );
103         PicoSetLoadFileFunc( PicoLoadFileFunc );
104         PicoSetFreeFileFunc( PicoFreeFileFunc );
105 }
106
107 static void add_model_apis( CSynapseClient& client ){
108         const picoModule_t** modules = PicoModuleList( NULL );
109         while ( *modules != NULL )
110         {
111                 const picoModule_t* module = *modules++;
112                 if ( module->canload && module->load ) {
113                         for ( unsigned int j = 0; module->defaultExts[j] != NULL; j++ )
114                                 client.AddAPI( MODEL_MAJOR, module->defaultExts[j], sizeof( _QERPlugModelTable ) );
115                 }
116         }
117 }
118
119 static bool model_is_supported( const char* extension ){
120         const picoModule_t** modules = PicoModuleList( NULL );
121         while ( *modules != NULL )
122         {
123                 const picoModule_t* module = *modules++;
124                 if ( module->canload && module->load ) {
125                         for ( unsigned int j = 0; module->defaultExts[j] != NULL; j++ )
126                                 if ( strcmp( extension, module->defaultExts[j] ) == 0 ) {
127                                         return true;
128                                 }
129                 }
130         }
131         return false;
132 }
133
134 void init_filetypes(){
135         const picoModule_t **modules = PicoModuleList( NULL );
136         while ( *modules != NULL )
137         {
138                 const picoModule_t* module = *modules++;
139                 if ( module->canload && module->load ) {
140                         for ( char*const* ext = module->defaultExts; *ext != NULL; ++ext )
141                         {
142                                 char buf[16];
143                                 buf[0] = '*';
144                                 buf[1] = '.';
145                                 strcpy( buf + 2, *ext );
146                                 GetFileTypeRegistry()->addType( MODEL_MAJOR, filetype_t( module->displayName, buf ) );
147                         }
148                 }
149         }
150 }
151
152 // plugin implementation
153
154 static const char *PLUGIN_NAME = "Model loading module";
155 static const char *PLUGIN_COMMANDS = "About;-;Flush & Reload Models;Flush & Reload Selected";
156 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\n\nSupported models:\n";
157
158 extern "C" const char* QERPlug_Init( void *hApp, void* pMainWidget ){
159         init_filetypes();
160         return (char *) PLUGIN_NAME;
161 }
162
163 extern "C" const char* QERPlug_GetName(){
164         return (char *) PLUGIN_NAME;
165 }
166
167 extern "C" const char* QERPlug_GetCommandList(){
168         return (char *) PLUGIN_COMMANDS;
169 }
170
171 extern "C" void QERPlug_Dispatch( const char *p, vec3_t vMin, vec3_t vMax, bool bSingleBrush ){
172         if ( !strcmp( p, "Flush & Reload Selected" ) ) {
173                 DoFlushReloadSelected();
174         }
175         else if ( !strcmp( p, "Flush & Reload Models" ) ) {
176                 DoFlushReloadAll();
177         }
178         else if ( !strcmp( p, "About" ) ) {
179                 const picoModule_t** modules = PicoModuleList( NULL );
180                 char about_buf[1024];
181                 strncpy( about_buf, PLUGIN_ABOUT, sizeof( about_buf ) - 1 );
182                 while ( *modules != NULL ) {
183                         const picoModule_t* module = *modules++;
184                         strncat( about_buf, module->displayName, sizeof( about_buf ) - 1 );
185                         strncat( about_buf, " (", sizeof( about_buf ) - 1 );
186                         strncat( about_buf, module->defaultExts[0], sizeof( about_buf ) - 1 );
187                         strncat( about_buf, ")\n\t", sizeof( about_buf ) - 1 );
188                         strncat( about_buf, module->copyright, sizeof( about_buf ) - 1 );
189                         strncat( about_buf, "\n", sizeof( about_buf ) - 1 );
190                 }
191                 g_FuncTable.m_pfnMessageBox( NULL, about_buf, "About", MB_OK, NULL );
192         }
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                 Syn_Printf( "ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version );
231                 return NULL;
232         }
233         g_pSynapseServer = pServer;
234         g_pSynapseServer->IncRef();
235         Set_Syn_Printf( g_pSynapseServer->Get_Syn_Printf() );
236
237         initialise();
238
239         add_model_apis( g_SynapseClient );
240         g_SynapseClient.AddAPI( TOOLBAR_MAJOR, "model", sizeof( _QERPlugToolbarTable ) );
241         g_SynapseClient.AddAPI( PLUGIN_MAJOR, "model", sizeof( _QERPluginTable ) );
242
243         g_SynapseClient.AddAPI( RADIANT_MAJOR, NULL, sizeof( g_FuncTable ), SYN_REQUIRE, &g_FuncTable );
244         g_SynapseClient.AddAPI( QGL_MAJOR, NULL, sizeof( g_QglTable ), SYN_REQUIRE, &g_QglTable );
245
246         if ( !g_SynapseClient.ConfigXML( pServer, NULL, entries ) ) {
247                 return NULL;
248         }
249
250         return &g_SynapseClient;
251 }
252
253 bool CSynapseClientModel::RequestAPI( APIDescriptor_t *pAPI ){
254         if ( !strcmp( pAPI->major_name, MODEL_MAJOR ) ) {
255                 _QERPlugModelTable* pTable = static_cast<_QERPlugModelTable*>( pAPI->mpTable );
256
257                 if ( model_is_supported( pAPI->minor_name ) ) {
258                         pTable->m_pfnLoadModel = &LoadModel;
259                         return true;
260                 }
261         }
262         else if ( !strcmp( pAPI->major_name, TOOLBAR_MAJOR ) ) {
263                 _QERPlugToolbarTable* pTable = static_cast<_QERPlugToolbarTable*>( pAPI->mpTable );
264
265                 pTable->m_pfnToolbarButtonCount = &ToolbarButtonCount;
266                 pTable->m_pfnGetToolbarButton = &GetToolbarButton;
267                 return true;
268         }
269         else if ( !strcmp( pAPI->major_name, PLUGIN_MAJOR ) ) {
270                 _QERPluginTable* pTable = static_cast<_QERPluginTable*>( pAPI->mpTable );
271
272                 pTable->m_pfnQERPlug_Init = QERPlug_Init;
273                 pTable->m_pfnQERPlug_GetName = QERPlug_GetName;
274                 pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;
275                 pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch;
276                 return true;
277         }
278
279         Syn_Printf( "ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo() );
280         return false;
281 }
282
283 #include "version.h"
284
285 const char* CSynapseClientModel::GetInfo(){
286         return "picomodel loader module built " __DATE__ " " RADIANT_VERSION;
287 }
288
289 const char* CSynapseClientModel::GetName(){
290         return "model";
291 }