- Added LocalLcPath to plugin interface
[xonotic/netradiant.git] / radiant / 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 "plugin.h"
23
24 #include "debugging/debugging.h"
25
26 #include "qerplugin.h"
27 #include "ifilesystem.h"
28 #include "ishaders.h"
29 #include "ientity.h"
30 #include "ieclass.h"
31 #include "irender.h"
32 #include "iscenegraph.h"
33 #include "iselection.h"
34 #include "ifilter.h"
35 #include "iscriplib.h"
36 #include "igl.h"
37 #include "iundo.h"
38 #include "itextures.h"
39 #include "ireference.h"
40 #include "ifiletypes.h"
41 #include "preferencesystem.h"
42 #include "ibrush.h"
43 #include "ipatch.h"
44 #include "iimage.h"
45 #include "itoolbar.h"
46 #include "iplugin.h"
47 #include "imap.h"
48 #include "namespace.h"
49
50 #include "gtkutil/messagebox.h"
51 #include "gtkutil/filechooser.h"
52 #include "maplib.h"
53
54 #include "error.h"
55 #include "map.h"
56 #include "qe3.h"
57 #include "entityinspector.h"
58 #include "entitylist.h"
59 #include "points.h"
60 #include "gtkmisc.h"
61 #include "texwindow.h"
62 #include "mainframe.h"
63 #include "build.h"
64 #include "mru.h"
65 #include "multimon.h"
66 #include "surfacedialog.h"
67 #include "groupdialog.h"
68 #include "patchdialog.h"
69 #include "camwindow.h"
70 #include "watchbsp.h"
71 #include "xywindow.h"
72 #include "entity.h"
73 #include "select.h"
74 #include "preferences.h"
75 #include "autosave.h"
76 #include "plugintoolbar.h"
77 #include "findtexturedialog.h"
78 #include "nullmodel.h"
79 #include "grid.h"
80
81 #include "modulesystem/modulesmap.h"
82 #include "modulesystem/singletonmodule.h"
83
84 #include "generic/callback.h"
85
86 const char* GameDescription_getKeyValue(const char* key)
87 {
88   return g_pGameDescription->getKeyValue(key);
89 }
90
91 const char* GameDescription_getRequiredKeyValue(const char* key)
92 {
93   return g_pGameDescription->getRequiredKeyValue(key);
94 }
95
96 const char* getMapName()
97 {
98   return Map_Name(g_map);
99 }
100
101 scene::Node& getMapWorldEntity()
102 {
103   return Map_FindOrInsertWorldspawn(g_map);
104 }
105
106 VIEWTYPE XYWindow_getViewType()
107 {
108   return g_pParentWnd->GetXYWnd()->GetViewType();
109 }
110
111 Vector3 XYWindow_windowToWorld(const WindowVector& position)
112 {
113   Vector3 result(0, 0, 0);
114   g_pParentWnd->GetXYWnd()->XY_ToPoint(static_cast<int>(position.x()), static_cast<int>(position.y()), result);
115   return result;
116 }
117
118 const char* TextureBrowser_getSelectedShader()
119 {
120   return TextureBrowser_GetSelectedShader(GlobalTextureBrowser());
121 }
122
123 class RadiantCoreAPI
124 {
125   _QERFuncTable_1 m_radiantcore;
126 public:
127   typedef _QERFuncTable_1 Type;
128   STRING_CONSTANT(Name, "*");
129
130   RadiantCoreAPI()
131   {
132     m_radiantcore.getEnginePath = &EnginePath_get;
133         m_radiantcore.getLocalRcPath = &LocalRcPath_get;
134     m_radiantcore.getAppPath = &AppPath_get;
135     m_radiantcore.getGameToolsPath = &GameToolsPath_get;
136     m_radiantcore.getSettingsPath = &SettingsPath_get;
137     m_radiantcore.getMapsPath = &getMapsPath;
138
139     m_radiantcore.getGameName = &gamename_get;
140     m_radiantcore.getGameMode = &gamemode_get;
141
142     m_radiantcore.getMapName = &getMapName;
143     m_radiantcore.getMapWorldEntity = getMapWorldEntity;
144     m_radiantcore.getGridSize = GetGridSize;
145
146     m_radiantcore.getGameDescriptionKeyValue = &GameDescription_getKeyValue;
147     m_radiantcore.getRequiredGameDescriptionKeyValue = &GameDescription_getRequiredKeyValue;
148
149     m_radiantcore.attachGameToolsPathObserver = Radiant_attachGameToolsPathObserver;
150     m_radiantcore.detachGameToolsPathObserver = Radiant_detachGameToolsPathObserver;
151     m_radiantcore.attachEnginePathObserver = Radiant_attachEnginePathObserver;
152     m_radiantcore.detachEnginePathObserver = Radiant_detachEnginePathObserver;
153     m_radiantcore.attachGameNameObserver = Radiant_attachGameNameObserver;
154     m_radiantcore.detachGameNameObserver = Radiant_detachGameNameObserver;
155     m_radiantcore.attachGameModeObserver = Radiant_attachGameModeObserver;
156     m_radiantcore.detachGameModeObserver = Radiant_detachGameModeObserver;
157
158     m_radiantcore.XYWindowDestroyed_connect = XYWindowDestroyed_connect;
159     m_radiantcore.XYWindowDestroyed_disconnect = XYWindowDestroyed_disconnect;
160     m_radiantcore.XYWindowMouseDown_connect = XYWindowMouseDown_connect;
161     m_radiantcore.XYWindowMouseDown_disconnect = XYWindowMouseDown_disconnect;
162     m_radiantcore.XYWindow_getViewType = XYWindow_getViewType;
163     m_radiantcore.XYWindow_windowToWorld = XYWindow_windowToWorld;
164     m_radiantcore.TextureBrowser_getSelectedShader = TextureBrowser_getSelectedShader;
165
166     m_radiantcore.m_pfnMessageBox = &gtk_MessageBox;
167     m_radiantcore.m_pfnFileDialog = &file_dialog;
168     m_radiantcore.m_pfnColorDialog = &color_dialog;
169     m_radiantcore.m_pfnDirDialog = &dir_dialog;
170     m_radiantcore.m_pfnNewImage = &new_plugin_image;
171   }
172   _QERFuncTable_1* getTable()
173   {
174     return &m_radiantcore;
175   }
176 };
177
178 typedef SingletonModule<RadiantCoreAPI> RadiantCoreModule;
179 typedef Static<RadiantCoreModule> StaticRadiantCoreModule;
180 StaticRegisterModule staticRegisterRadiantCore(StaticRadiantCoreModule::instance());
181
182
183 class RadiantDependencies :
184   public GlobalRadiantModuleRef,
185   public GlobalFileSystemModuleRef,
186   public GlobalEntityModuleRef,
187   public GlobalShadersModuleRef,
188   public GlobalBrushModuleRef,
189   public GlobalSceneGraphModuleRef,
190   public GlobalShaderCacheModuleRef,
191   public GlobalFiletypesModuleRef,
192   public GlobalSelectionModuleRef,
193   public GlobalReferenceModuleRef,
194   public GlobalOpenGLModuleRef,
195   public GlobalEntityClassManagerModuleRef,
196   public GlobalUndoModuleRef,
197   public GlobalScripLibModuleRef,
198   public GlobalNamespaceModuleRef
199 {
200   ImageModulesRef m_image_modules;
201   MapModulesRef m_map_modules;
202   ToolbarModulesRef m_toolbar_modules;
203   PluginModulesRef m_plugin_modules;
204
205 public:
206   RadiantDependencies() :
207     GlobalEntityModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entities")),
208     GlobalShadersModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("shaders")),
209     GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")),
210     GlobalEntityClassManagerModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entityclass")),
211     m_image_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("texturetypes")),
212     m_map_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("maptypes")),
213     m_toolbar_modules("*"),
214     m_plugin_modules("*")
215   {
216   }
217
218   ImageModules& getImageModules()
219   {
220     return m_image_modules.get();
221   }
222   MapModules& getMapModules()
223   {
224     return m_map_modules.get();
225   }
226   ToolbarModules& getToolbarModules()
227   {
228     return m_toolbar_modules.get();
229   }
230   PluginModules& getPluginModules()
231   {
232     return m_plugin_modules.get();
233   }
234 };
235
236 class Radiant : public TypeSystemRef
237 {
238 public:
239   Radiant()
240   {
241     Preferences_Init();
242
243     GlobalFiletypes().addType("sound", "wav", filetype_t("PCM sound files", "*.wav"));
244
245     Selection_construct();
246     HomePaths_Construct();
247     VFS_Construct();
248     Grid_construct();
249     MultiMon_Construct();
250     MRU_Construct();
251     Pointfile_Construct();
252     GLWindow_Construct();
253     BuildMenu_Construct();
254     Map_Construct();
255     EntityList_Construct();
256     MainFrame_Construct();
257     GroupDialog_Construct();
258     SurfaceInspector_Construct();
259     PatchInspector_Construct();
260     CamWnd_Construct();
261     XYWindow_Construct();
262     BuildMonitor_Construct();
263     TextureBrowser_Construct();
264     Entity_Construct();
265     Autosave_Construct();
266     EntityInspector_construct();
267     FindTextureDialog_Construct();
268     NullModel_construct();
269     MapRoot_construct();
270
271     EnginePath_verify();
272     EnginePath_Realise();
273   }
274   ~Radiant()
275   {
276     EnginePath_Unrealise();
277
278     MapRoot_destroy();
279     NullModel_destroy();
280     FindTextureDialog_Destroy();
281     EntityInspector_destroy();
282     Autosave_Destroy();
283     Entity_Destroy();
284     TextureBrowser_Destroy();
285     BuildMonitor_Destroy();
286     XYWindow_Destroy();
287     CamWnd_Destroy();
288     PatchInspector_Destroy();
289     SurfaceInspector_Destroy();
290     GroupDialog_Destroy();
291     MainFrame_Destroy();
292     EntityList_Destroy();
293     Map_Destroy();
294     BuildMenu_Destroy();
295     GLWindow_Destroy();
296     Pointfile_Destroy();
297     MRU_Destroy();
298     MultiMon_Destroy();
299     Grid_destroy();
300     VFS_Destroy();
301     HomePaths_Destroy();
302     Selection_destroy();
303   }
304 };
305
306 namespace
307 {
308   bool g_RadiantInitialised = false;
309   RadiantDependencies* g_RadiantDependencies;
310   Radiant* g_Radiant;
311 }
312
313
314
315 bool Radiant_Construct(ModuleServer& server)
316 {
317   GlobalModuleServer::instance().set(server);
318   StaticModuleRegistryList().instance().registerModules();
319
320   g_RadiantDependencies = new RadiantDependencies();
321
322   g_RadiantInitialised = !server.getError();
323
324   if(g_RadiantInitialised)
325   {
326     g_Radiant = new Radiant;
327   }
328
329   return g_RadiantInitialised;
330 }
331 void Radiant_Destroy()
332 {
333   if(g_RadiantInitialised)
334   {
335     delete g_Radiant;
336   }
337
338   delete g_RadiantDependencies;
339 }
340
341 ImageModules& Radiant_getImageModules()
342 {
343   return g_RadiantDependencies->getImageModules();
344 }
345 MapModules& Radiant_getMapModules()
346 {
347   return g_RadiantDependencies->getMapModules();
348 }
349 ToolbarModules& Radiant_getToolbarModules()
350 {
351   return g_RadiantDependencies->getToolbarModules();
352 }
353 PluginModules& Radiant_getPluginModules()
354 {
355   return g_RadiantDependencies->getPluginModules();
356 }
357
358