ported PrtView plugin
[xonotic/netradiant.git] / contrib / prtview / prtview.cpp
1 /*
2 PrtView plugin for GtkRadiant
3 Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20
21 #include "PrtView.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "profile/profile.h"
26
27 #include "qerplugin.h"
28 #include "iscenegraph.h"
29 #include "iglrender.h"
30 #include "iplugin.h"
31
32 #include "Portals.h"
33 #include "AboutDialog.h"
34 #include "ConfigDialog.h"
35 #include "LoadPortalFileDialog.h"
36
37 #define Q3R_CMD_SPLITTER "-"
38 #define Q3R_CMD_ABOUT "About Portal Viewer"
39 #define Q3R_CMD_LOAD "Load .prt file"
40 #define Q3R_CMD_RELEASE "Unload .prt file"
41 #define Q3R_CMD_SHOW_3D "Toggle portals (3D)"
42 #define Q3R_CMD_SHOW_2D "Toggle portals (2D)"
43 #define Q3R_CMD_OPTIONS "Configure Portal Viewer"
44
45 static char INIfn[PATH_MAX];
46
47 /////////////////////////////////////////////////////////////////////////////
48 // CPrtViewApp construction
49
50 #define RENDER_2D "Render2D"
51 #define WIDTH_2D "Width2D"
52 #define AA_2D "AntiAlias2D"
53 #define COLOR_2D "Color2D"
54
55 #define RENDER_3D "Render3D"
56 #define WIDTH_3D "Width3D"
57 #define AA_3D "AntiAlias3D"
58 #define COLOR_3D "Color3D"
59 #define COLOR_FOG "ColorFog"
60 #define FOG "Fog"
61 #define ZBUFFER "ZBuffer"
62 #define POLYGON "Polygons"
63 #define LINE "Lines"
64 #define TRANS_3D "Transparency"
65 #define CLIP_RANGE "ClipRange"
66 #define CLIP "Clip"
67
68
69 void PrtView_construct()
70 {
71   strcpy(INIfn, GlobalRadiant().getSettingsPath());
72   strcat(INIfn, "prtview.ini");
73
74   portals.show_2d = INIGetInt(RENDER_2D, FALSE) ? true : false;
75   portals.aa_2d = INIGetInt(AA_2D, FALSE) ? true : false;
76   portals.width_2d = (float)INIGetInt(WIDTH_2D, 10);
77   portals.color_2d = (PackedColour)INIGetInt(COLOR_2D, RGB(0, 0, 255)) & 0xFFFFFF;
78
79   if (portals.width_2d > 40.0f)
80     portals.width_2d = 40.0f;
81   else if (portals.width_2d < 2.0f)
82     portals.width_2d = 2.0f;
83
84   portals.show_3d = INIGetInt(RENDER_3D, TRUE) ? true : false;
85
86   portals.zbuffer = INIGetInt(ZBUFFER, 1);
87   portals.fog = INIGetInt(FOG, FALSE) ? true : false;
88   portals.polygons = INIGetInt(POLYGON, TRUE);
89   portals.lines = INIGetInt(LINE, TRUE);
90   portals.aa_3d = INIGetInt(AA_3D, FALSE) ? true : false;
91   portals.width_3d = (float)INIGetInt(WIDTH_3D, 4);
92   portals.color_3d = (PackedColour)INIGetInt(COLOR_3D, RGB(255, 255, 0)) & 0xFFFFFF;
93   portals.color_fog = (PackedColour)INIGetInt(COLOR_FOG, RGB(127, 127, 127)) & 0xFFFFFF;
94   portals.trans_3d = (float)INIGetInt(TRANS_3D, 50);
95   portals.clip = INIGetInt(CLIP, FALSE) ? true : false;
96   portals.clip_range = (float)INIGetInt(CLIP_RANGE, 16);
97
98   if (portals.clip_range < 1)
99     portals.clip_range = 1;
100   else if (portals.clip_range > 128)
101     portals.clip_range = 128;
102
103   if (portals.zbuffer < 0)
104     portals.zbuffer = 0;
105   else if (portals.zbuffer > 2)
106     portals.zbuffer = 0;
107
108   if (portals.width_3d > 40.0f)
109     portals.width_3d = 40.0f;
110   else if (portals.width_3d < 2.0f)
111     portals.width_3d = 2.0f;
112
113   if (portals.trans_3d > 100.0f)
114     portals.trans_3d = 100.0f;
115   else if (portals.trans_3d < 0.0f)
116     portals.trans_3d = 0.0f;
117
118   SaveConfig();
119
120   portals.FixColors();
121   
122   Portals_constructShaders();
123   GlobalShaderCache().attachRenderable(render);
124 }
125
126 void PrtView_destroy()
127 {
128   GlobalShaderCache().detachRenderable(render);
129   Portals_destroyShaders();
130 }
131
132 void SaveConfig () 
133 {
134   INISetInt(RENDER_2D, portals.show_2d, "Draw in 2D windows");
135   INISetInt(WIDTH_2D, (int)portals.width_2d, "Width of lines in 2D windows (in units of 1/2)");
136   INISetInt(COLOR_2D, (int)portals.color_2d, "Color of lines in 2D windows");
137   INISetInt(AA_2D, portals.aa_2d, "Draw lines in 2D window anti-aliased");
138
139   INISetInt(ZBUFFER, portals.zbuffer, "ZBuffer level in 3D window");
140   INISetInt(FOG, portals.fog, "Use depth cueing in 3D window");
141   INISetInt(POLYGON, portals.polygons, "Render using polygons polygons in 3D window");
142   INISetInt(LINE, portals.polygons, "Render using lines in 3D window");
143   INISetInt(RENDER_3D, portals.show_3d, "Draw in 3D windows");
144   INISetInt(WIDTH_3D, (int)portals.width_3d, "Width of lines in 3D window (in units of 1/2)");
145   INISetInt(COLOR_3D, (int)portals.color_3d, "Color of lines/polygons in 3D window");
146   INISetInt(COLOR_FOG, (int)portals.color_fog, "Color of distant lines/polygons in 3D window");
147   INISetInt(AA_3D, portals.aa_3d, "Draw lines in 3D window anti-aliased");
148   INISetInt(TRANS_3D, (int)portals.trans_3d, "Transparency in 3d view (0 = solid, 100 = invisible)");
149   INISetInt(CLIP, portals.clip, "Cubic clipper active for portal viewer");
150   INISetInt(CLIP_RANGE, (int)portals.clip_range, "Portal viewer cubic clip distance (in units of 64)");
151 }
152
153
154 #define CONFIG_SECTION "Configuration"
155
156 int INIGetInt(char *key, int def)
157 {
158   char value[1024];
159
160   if (read_var (INIfn, CONFIG_SECTION, key, value))
161     return atoi (value);
162   else
163     return def;
164 }
165
166 void INISetInt(char *key, int val, char *comment /* = NULL */)
167 {
168   char s[1000];
169
170   if(comment)
171     sprintf(s, "%d        ; %s", val, comment);
172   else
173     sprintf(s, "%d", val);
174   save_var (INIfn, CONFIG_SECTION, key, s);
175 }
176
177
178 // plugin name
179 static const char *PLUGIN_NAME = "Portal Viewer";
180 // commands in the menu
181 static const char *PLUGIN_COMMANDS =
182         Q3R_CMD_ABOUT ";"
183         Q3R_CMD_SPLITTER ";"
184         Q3R_CMD_OPTIONS ";"
185         Q3R_CMD_SPLITTER ";"
186         Q3R_CMD_SHOW_2D ";"
187         Q3R_CMD_SHOW_3D ";"
188         Q3R_CMD_SPLITTER ";"
189         Q3R_CMD_RELEASE ";"
190         Q3R_CMD_LOAD;
191
192
193
194 const char* QERPlug_Init (void *hApp, void* pMainWidget)
195 {  
196   return "Portal Viewer for Q3Radiant";
197 }
198
199 const char* QERPlug_GetName()
200 {
201   return PLUGIN_NAME;
202 }
203
204 const char* QERPlug_GetCommandList()
205 {
206   return PLUGIN_COMMANDS;
207 }
208
209
210 const char* QERPlug_GetCommandTitleList()
211 {
212   return "";
213 }
214
215
216 void QERPlug_Dispatch(const char* p, float* vMin, float* vMax, bool bSingleBrush)
217 {
218   globalOutputStream() << MSG_PREFIX "Command \"" << p << "\"\n";
219
220   if (!strcmp(p,Q3R_CMD_ABOUT))
221   {
222     DoAboutDlg ();
223   }
224   else if (!strcmp(p,Q3R_CMD_LOAD))
225   {
226     if (DoLoadPortalFileDialog () == IDOK)
227     {
228       portals.Load();
229       SceneChangeNotify();
230     }
231     else
232     {
233       globalOutputStream() << MSG_PREFIX "Portal file load aborted.\n", portals.fn;
234     }
235   }
236   else if (!strcmp(p,Q3R_CMD_RELEASE))
237   {
238     portals.Purge();
239
240     SceneChangeNotify();
241
242     globalOutputStream() << MSG_PREFIX "Portals unloaded.\n";
243   }
244   else if (!strcmp(p,Q3R_CMD_SHOW_2D))
245   {
246     portals.show_2d = !portals.show_2d;
247
248     SceneChangeNotify();
249     SaveConfig();
250
251     if(portals.show_2d)
252       globalOutputStream() << MSG_PREFIX "Portals will be rendered in 2D view.\n";
253     else
254       globalOutputStream() << MSG_PREFIX "Portals will NOT be rendered in 2D view.\n";
255   }
256   else if (!strcmp(p,Q3R_CMD_SHOW_3D))
257   {
258     portals.show_3d = !portals.show_3d;
259     SaveConfig();
260
261     SceneChangeNotify();
262
263     if (portals.show_3d)
264       globalOutputStream() << MSG_PREFIX "Portals will be rendered in 3D view.\n";
265     else
266       globalOutputStream() << MSG_PREFIX "Portals will NOT be rendered in 3D view.\n";
267   }
268   else if (!strcmp(p,Q3R_CMD_OPTIONS))
269   {
270     DoConfigDialog ();
271     SaveConfig();
272
273     SceneChangeNotify();
274   }
275 }
276
277
278 #include "modulesystem/singletonmodule.h"
279
280 class PrtViewPluginDependencies :
281   public GlobalSceneGraphModuleRef,
282   public GlobalRadiantModuleRef,
283   public GlobalShaderCacheModuleRef,
284   public GlobalOpenGLModuleRef, 
285   public GlobalOpenGLStateLibraryModuleRef
286 {
287 };
288
289 class PrtViewPluginModule
290 {
291   _QERPluginTable m_plugin;
292 public:
293   typedef _QERPluginTable Type;
294   STRING_CONSTANT(Name, "prtview");
295
296   PrtViewPluginModule()
297   {
298     m_plugin.m_pfnQERPlug_Init = QERPlug_Init;
299     m_plugin.m_pfnQERPlug_GetName = QERPlug_GetName;
300     m_plugin.m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;
301     m_plugin.m_pfnQERPlug_GetCommandTitleList = QERPlug_GetCommandTitleList;
302     m_plugin.m_pfnQERPlug_Dispatch = QERPlug_Dispatch;
303
304     PrtView_construct();
305   }
306   ~PrtViewPluginModule()
307   {
308     PrtView_destroy();
309   }
310   _QERPluginTable* getTable()
311   {
312     return &m_plugin;
313   }
314 };
315
316 typedef SingletonModule<PrtViewPluginModule, PrtViewPluginDependencies> SingletonPrtViewPluginModule;
317
318 SingletonPrtViewPluginModule g_PrtViewPluginModule;
319
320
321 extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules(ModuleServer& server)
322 {
323   GlobalErrorStream::instance().setOutputStream(server.getErrorStream());
324   GlobalOutputStream::instance().setOutputStream(server.getOutputStream());
325   GlobalDebugMessageHandler::instance().setHandler(server.getDebugMessageHandler());
326   GlobalModuleServer::instance().set(server);
327
328   g_PrtViewPluginModule.selfRegister();
329 }