]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/model/plugin.cpp
Merge branch 'transfilterfix' into 'master'
[xonotic/netradiant.git] / plugins / model / plugin.cpp
1 /*
2    Copyright (C) 2001-2006, William Joseph.
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 <stdio.h>
23 #include "picomodel.h"
24
25 typedef unsigned char byte;
26
27 #include <stdlib.h>
28 #include <algorithm>
29 #include <list>
30
31 #include "iscenegraph.h"
32 #include "irender.h"
33 #include "iselection.h"
34 #include "iimage.h"
35 #include "imodel.h"
36 #include "igl.h"
37 #include "ifilesystem.h"
38 #include "iundo.h"
39 #include "ifiletypes.h"
40
41 #include "modulesystem/singletonmodule.h"
42 #include "stream/textstream.h"
43 #include "string/string.h"
44 #include "stream/stringstream.h"
45 #include "typesystem.h"
46
47 #include "model.h"
48
49 void PicoPrintFunc(int level, const char *str)
50 {
51     if (str == 0) {
52         return;
53     }
54     switch (level) {
55         case PICO_NORMAL:
56             globalOutputStream() << str << "\n";
57             break;
58
59         case PICO_VERBOSE:
60             //globalOutputStream() << "PICO_VERBOSE: " << str << "\n";
61             break;
62
63         case PICO_WARNING:
64             globalErrorStream() << "PICO_WARNING: " << str << "\n";
65             break;
66
67         case PICO_ERROR:
68             globalErrorStream() << "PICO_ERROR: " << str << "\n";
69             break;
70
71         case PICO_FATAL:
72             globalErrorStream() << "PICO_FATAL: " << str << "\n";
73             break;
74     }
75 }
76
77 void PicoLoadFileFunc(const char *name, byte **buffer, int *bufSize)
78 {
79     *bufSize = vfsLoadFile(name, (void **) buffer);
80 }
81
82 void PicoFreeFileFunc(void *file)
83 {
84     vfsFreeFile(file);
85 }
86
87 void pico_initialise()
88 {
89     PicoInit();
90     PicoSetMallocFunc(malloc);
91     PicoSetFreeFunc(free);
92     PicoSetPrintFunc(PicoPrintFunc);
93     PicoSetLoadFileFunc(PicoLoadFileFunc);
94     PicoSetFreeFileFunc(PicoFreeFileFunc);
95 }
96
97
98 class PicoModelLoader : public ModelLoader {
99     const picoModule_t *m_module;
100 public:
101     PicoModelLoader(const picoModule_t *module) : m_module(module)
102     {
103     }
104
105     scene::Node &loadModel(ArchiveFile &file)
106     {
107         return loadPicoModel(m_module, file);
108     }
109 };
110
111 class ModelPicoDependencies :
112         public GlobalFileSystemModuleRef,
113         public GlobalOpenGLModuleRef,
114         public GlobalUndoModuleRef,
115         public GlobalSceneGraphModuleRef,
116         public GlobalShaderCacheModuleRef,
117         public GlobalSelectionModuleRef,
118         public GlobalFiletypesModuleRef {
119 };
120
121 class ModelPicoAPI : public TypeSystemRef {
122     PicoModelLoader m_modelLoader;
123 public:
124     typedef ModelLoader Type;
125
126     ModelPicoAPI(const char *extension, const picoModule_t *module) :
127             m_modelLoader(module)
128     {
129         StringOutputStream filter(128);
130         filter << "*." << extension;
131         GlobalFiletypesModule::getTable().addType(Type::Name(), extension,
132                                                   filetype_t(module->displayName, filter.c_str()));
133     }
134
135     ModelLoader *getTable()
136     {
137         return &m_modelLoader;
138     }
139 };
140
141 class PicoModelAPIConstructor {
142     CopiedString m_extension;
143     const picoModule_t *m_module;
144 public:
145     PicoModelAPIConstructor(const char *extension, const picoModule_t *module) :
146             m_extension(extension), m_module(module)
147     {
148     }
149
150     const char *getName()
151     {
152         return m_extension.c_str();
153     }
154
155     ModelPicoAPI *constructAPI(ModelPicoDependencies &dependencies)
156     {
157         return new ModelPicoAPI(m_extension.c_str(), m_module);
158     }
159
160     void destroyAPI(ModelPicoAPI *api)
161     {
162         delete api;
163     }
164 };
165
166
167 typedef SingletonModule<ModelPicoAPI, ModelPicoDependencies, PicoModelAPIConstructor> PicoModelModule;
168 typedef std::list<PicoModelModule> PicoModelModules;
169 PicoModelModules g_PicoModelModules;
170
171
172 extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules(ModuleServer &server)
173 {
174     initialiseModule(server);
175
176     pico_initialise();
177
178     const picoModule_t **modules = PicoModuleList(0);
179     while (*modules != 0) {
180         const picoModule_t *module = *modules++;
181         if (module->canload && module->load) {
182             for (char *const *ext = module->defaultExts; *ext != 0; ++ext) {
183                 g_PicoModelModules.push_back(PicoModelModule(PicoModelAPIConstructor(*ext, module)));
184                 g_PicoModelModules.back().selfRegister();
185             }
186         }
187     }
188 }