Merge branch 'msys2thread' into 'master'
[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 #include "stream/stringstream.h"
32
33 #include "portals.h"
34 #include "AboutDialog.h"
35 #include "ConfigDialog.h"
36 #include "LoadPortalFileDialog.h"
37
38 #define Q3R_CMD_SPLITTER "-"
39 #define Q3R_CMD_ABOUT "About Portal Viewer"
40 #define Q3R_CMD_LOAD "Load .prt file"
41 #define Q3R_CMD_RELEASE "Unload .prt file"
42 #define Q3R_CMD_SHOW_3D "Toggle portals (3D)"
43 #define Q3R_CMD_SHOW_2D "Toggle portals (2D)"
44 #define Q3R_CMD_OPTIONS "Configure Portal Viewer"
45
46 CopiedString INIfn;
47
48 /////////////////////////////////////////////////////////////////////////////
49 // CPrtViewApp construction
50
51 const char *RENDER_2D = "Render2D";
52 const char *WIDTH_2D = "Width2D";
53 const char *AA_2D = "AntiAlias2D";
54 const char *COLOR_2D = "Color2D";
55
56 const char *RENDER_3D = "Render3D";
57 const char *WIDTH_3D = "Width3D";
58 const char *AA_3D = "AntiAlias3D";
59 const char *COLOR_3D = "Color3D";
60 const char *COLOR_FOG = "ColorFog";
61 const char *FOG = "Fog";
62 const char *ZBUFFER = "ZBuffer";
63 const char *POLYGON = "Polygons";
64 const char *LINE = "Lines";
65 const char *TRANS_3D = "Transparency";
66 const char *CLIP_RANGE = "ClipRange";
67 const char *CLIP = "Clip";
68
69
70 void PrtView_construct(){
71         StringOutputStream tmp( 64 );
72         tmp << GlobalRadiant().getSettingsPath() << "prtview.ini";
73         INIfn = tmp.c_str();
74
75         portals.show_2d = INIGetInt( RENDER_2D, FALSE ) ? true : false;
76         portals.aa_2d = INIGetInt( AA_2D, FALSE ) ? true : false;
77         portals.width_2d = (float)INIGetInt( WIDTH_2D, 10 );
78         portals.color_2d = (PackedColour)INIGetInt( COLOR_2D, RGB( 0, 0, 255 ) ) & 0xFFFFFF;
79
80         if ( portals.width_2d > 40.0f ) {
81                 portals.width_2d = 40.0f;
82         }
83         else if ( portals.width_2d < 2.0f ) {
84                 portals.width_2d = 2.0f;
85         }
86
87         portals.show_3d = INIGetInt( RENDER_3D, TRUE ) ? true : false;
88
89         portals.zbuffer = INIGetInt( ZBUFFER, 1 );
90         portals.fog = INIGetInt( FOG, FALSE ) ? true : false;
91         portals.polygons = INIGetInt( POLYGON, TRUE );
92         portals.lines = INIGetInt( LINE, TRUE );
93         portals.aa_3d = INIGetInt( AA_3D, FALSE ) ? true : false;
94         portals.width_3d = (float)INIGetInt( WIDTH_3D, 4 );
95         portals.color_3d = (PackedColour)INIGetInt( COLOR_3D, RGB( 255, 255, 0 ) ) & 0xFFFFFF;
96         portals.color_fog = (PackedColour)INIGetInt( COLOR_FOG, RGB( 127, 127, 127 ) ) & 0xFFFFFF;
97         portals.trans_3d = (float)INIGetInt( TRANS_3D, 50 );
98         portals.clip = INIGetInt( CLIP, FALSE ) ? true : false;
99         portals.clip_range = (float)INIGetInt( CLIP_RANGE, 16 );
100
101         if ( portals.clip_range < 1 ) {
102                 portals.clip_range = 1;
103         }
104         else if ( portals.clip_range > 128 ) {
105                 portals.clip_range = 128;
106         }
107
108         if ( portals.zbuffer < 0 ) {
109                 portals.zbuffer = 0;
110         }
111         else if ( portals.zbuffer > 2 ) {
112                 portals.zbuffer = 0;
113         }
114
115         if ( portals.width_3d > 40.0f ) {
116                 portals.width_3d = 40.0f;
117         }
118         else if ( portals.width_3d < 2.0f ) {
119                 portals.width_3d = 2.0f;
120         }
121
122         if ( portals.trans_3d > 100.0f ) {
123                 portals.trans_3d = 100.0f;
124         }
125         else if ( portals.trans_3d < 0.0f ) {
126                 portals.trans_3d = 0.0f;
127         }
128
129         SaveConfig();
130
131         portals.FixColors();
132
133         Portals_constructShaders();
134         GlobalShaderCache().attachRenderable( render );
135 }
136
137 void PrtView_destroy(){
138         GlobalShaderCache().detachRenderable( render );
139         Portals_destroyShaders();
140 }
141
142 void SaveConfig(){
143         INISetInt( RENDER_2D, portals.show_2d, "Draw in 2D windows" );
144         INISetInt( WIDTH_2D, (int)portals.width_2d, "Width of lines in 2D windows (in units of 1/2)" );
145         INISetInt( COLOR_2D, (int)portals.color_2d, "Color of lines in 2D windows" );
146         INISetInt( AA_2D, portals.aa_2d, "Draw lines in 2D window anti-aliased" );
147
148         INISetInt( ZBUFFER, portals.zbuffer, "ZBuffer level in 3D window" );
149         INISetInt( FOG, portals.fog, "Use depth cueing in 3D window" );
150         INISetInt( POLYGON, portals.polygons, "Render using polygons polygons in 3D window" );
151         INISetInt( LINE, portals.polygons, "Render using lines in 3D window" );
152         INISetInt( RENDER_3D, portals.show_3d, "Draw in 3D windows" );
153         INISetInt( WIDTH_3D, (int)portals.width_3d, "Width of lines in 3D window (in units of 1/2)" );
154         INISetInt( COLOR_3D, (int)portals.color_3d, "Color of lines/polygons in 3D window" );
155         INISetInt( COLOR_FOG, (int)portals.color_fog, "Color of distant lines/polygons in 3D window" );
156         INISetInt( AA_3D, portals.aa_3d, "Draw lines in 3D window anti-aliased" );
157         INISetInt( TRANS_3D, (int)portals.trans_3d, "Transparency in 3d view (0 = solid, 100 = invisible)" );
158         INISetInt( CLIP, portals.clip, "Cubic clipper active for portal viewer" );
159         INISetInt( CLIP_RANGE, (int)portals.clip_range, "Portal viewer cubic clip distance (in units of 64)" );
160 }
161
162
163 const char *CONFIG_SECTION = "Configuration";
164
165 int INIGetInt( const char *key, int def ){
166         char value[1024];
167
168         if ( read_var( INIfn.c_str(), CONFIG_SECTION, key, value ) ) {
169                 return atoi( value );
170         }
171         else{
172                 return def;
173         }
174 }
175
176 void INISetInt( const char *key, int val, const char *comment /* = NULL */ ){
177         char s[1000];
178
179         if ( comment ) {
180                 sprintf( s, "%d        ; %s", val, comment );
181         }
182         else{
183                 sprintf( s, "%d", val );
184         }
185         save_var( INIfn.c_str(), CONFIG_SECTION, key, s );
186 }
187
188
189 // plugin name
190 static const char *PLUGIN_NAME = "Portal Viewer";
191 // commands in the menu
192 static const char *PLUGIN_COMMANDS =
193         Q3R_CMD_ABOUT ";"
194         Q3R_CMD_SPLITTER ";"
195         Q3R_CMD_OPTIONS ";"
196         Q3R_CMD_SPLITTER ";"
197         Q3R_CMD_SHOW_2D ";"
198         Q3R_CMD_SHOW_3D ";"
199         Q3R_CMD_SPLITTER ";"
200         Q3R_CMD_RELEASE ";"
201         Q3R_CMD_LOAD;
202
203
204
205 const char* QERPlug_Init( void *hApp, void* pMainWidget ){
206         return "Portal Viewer for Q3Radiant";
207 }
208
209 const char* QERPlug_GetName(){
210         return PLUGIN_NAME;
211 }
212
213 const char* QERPlug_GetCommandList(){
214         return PLUGIN_COMMANDS;
215 }
216
217
218 const char* QERPlug_GetCommandTitleList(){
219         return "";
220 }
221
222
223 void QERPlug_Dispatch( const char* p, float* vMin, float* vMax, bool bSingleBrush ){
224         globalOutputStream() << MSG_PREFIX "Command \"" << p << "\"\n";
225
226         if ( !strcmp( p,Q3R_CMD_ABOUT ) ) {
227                 DoAboutDlg();
228         }
229         else if ( !strcmp( p,Q3R_CMD_LOAD ) ) {
230                 if ( DoLoadPortalFileDialog() == IDOK ) {
231                         portals.Load();
232                         SceneChangeNotify();
233                 }
234                 else
235                 {
236                         globalOutputStream() << MSG_PREFIX "Portal file load aborted.\n";
237                 }
238         }
239         else if ( !strcmp( p,Q3R_CMD_RELEASE ) ) {
240                 portals.Purge();
241
242                 SceneChangeNotify();
243
244                 globalOutputStream() << MSG_PREFIX "Portals unloaded.\n";
245         }
246         else if ( !strcmp( p,Q3R_CMD_SHOW_2D ) ) {
247                 portals.show_2d = !portals.show_2d;
248
249                 SceneChangeNotify();
250                 SaveConfig();
251
252                 if ( portals.show_2d ) {
253                         globalOutputStream() << MSG_PREFIX "Portals will be rendered in 2D view.\n";
254                 }
255                 else{
256                         globalOutputStream() << MSG_PREFIX "Portals will NOT be rendered in 2D view.\n";
257                 }
258         }
259         else if ( !strcmp( p,Q3R_CMD_SHOW_3D ) ) {
260                 portals.show_3d = !portals.show_3d;
261                 SaveConfig();
262
263                 SceneChangeNotify();
264
265                 if ( portals.show_3d ) {
266                         globalOutputStream() << MSG_PREFIX "Portals will be rendered in 3D view.\n";
267                 }
268                 else{
269                         globalOutputStream() << MSG_PREFIX "Portals will NOT be rendered in 3D view.\n";
270                 }
271         }
272         else if ( !strcmp( p,Q3R_CMD_OPTIONS ) ) {
273                 DoConfigDialog();
274                 SaveConfig();
275
276                 SceneChangeNotify();
277         }
278 }
279
280
281 #include "modulesystem/singletonmodule.h"
282
283 class PrtViewPluginDependencies :
284         public GlobalSceneGraphModuleRef,
285         public GlobalRadiantModuleRef,
286         public GlobalShaderCacheModuleRef,
287         public GlobalOpenGLModuleRef,
288         public GlobalOpenGLStateLibraryModuleRef
289 {
290 };
291
292 class PrtViewPluginModule
293 {
294 _QERPluginTable m_plugin;
295 public:
296 typedef _QERPluginTable Type;
297 STRING_CONSTANT( Name, "prtview" );
298
299 PrtViewPluginModule(){
300         m_plugin.m_pfnQERPlug_Init = QERPlug_Init;
301         m_plugin.m_pfnQERPlug_GetName = QERPlug_GetName;
302         m_plugin.m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;
303         m_plugin.m_pfnQERPlug_GetCommandTitleList = QERPlug_GetCommandTitleList;
304         m_plugin.m_pfnQERPlug_Dispatch = QERPlug_Dispatch;
305
306         PrtView_construct();
307 }
308 ~PrtViewPluginModule(){
309         PrtView_destroy();
310 }
311 _QERPluginTable* getTable(){
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         initialiseModule( server );
323
324         g_PrtViewPluginModule.selfRegister();
325 }