]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/prtview/prtview.cpp
get the basics of a new scons build system together
[xonotic/netradiant.git] / contrib / prtview / prtview.cpp
1 /*\r
2 PrtView plugin for GtkRadiant\r
3 Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com\r
4 \r
5 This library is free software; you can redistribute it and/or\r
6 modify it under the terms of the GNU Lesser General Public\r
7 License as published by the Free Software Foundation; either\r
8 version 2.1 of the License, or (at your option) any later version.\r
9 \r
10 This library is distributed in the hope that it will be useful,\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
13 Lesser General Public License for more details.\r
14 \r
15 You should have received a copy of the GNU Lesser General Public\r
16 License along with this library; if not, write to the Free Software\r
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
18 */\r
19 \r
20 // PrtView.cpp : Defines the initialization routines for the DLL.\r
21 //\r
22 \r
23 #include "stdafx.h"\r
24 #include <stdio.h>\r
25 #include <stdlib.h>\r
26 \r
27 #define Q3R_CMD_SPLITTER "-"\r
28 #define Q3R_CMD_ABOUT "About Portal Viewer"\r
29 #define Q3R_CMD_LOAD "Load .prt file"\r
30 #define Q3R_CMD_RELEASE "Unload .prt file"\r
31 #define Q3R_CMD_SHOW_3D "Toggle portals (3D)"\r
32 #define Q3R_CMD_SHOW_2D "Toggle portals (2D)"\r
33 #define Q3R_CMD_OPTIONS "Configure Portal Viewer"\r
34 \r
35 static char INIfn[NAME_MAX];\r
36 \r
37 /////////////////////////////////////////////////////////////////////////////\r
38 // CPrtViewApp construction\r
39 \r
40 #define RENDER_2D "Render2D"\r
41 #define WIDTH_2D "Width2D"\r
42 #define AA_2D "AntiAlias2D"\r
43 #define COLOR_2D "Color2D"\r
44 \r
45 #define RENDER_3D "Render3D"\r
46 #define WIDTH_3D "Width3D"\r
47 #define AA_3D "AntiAlias3D"\r
48 #define COLOR_3D "Color3D"\r
49 #define COLOR_FOG "ColorFog"\r
50 #define FOG "Fog"\r
51 #define ZBUFFER "ZBuffer"\r
52 #define POLYGON "Polygons"\r
53 #define LINE "Lines"\r
54 #define TRANS_3D "Transparency"\r
55 #define CLIP_RANGE "ClipRange"\r
56 #define CLIP "Clip"\r
57 \r
58 void InitInstance () \r
59 {\r
60 #ifdef _WIN32\r
61   char fn[_MAX_PATH];\r
62   char fn_drive[_MAX_DRIVE];\r
63   char fn_dir[_MAX_DIR];\r
64   char fn_name[_MAX_FNAME];\r
65   char fn_ext[_MAX_EXT];\r
66 \r
67   GetModuleFileName(GetModuleHandle("PrtView.dll"), fn, _MAX_PATH);\r
68 \r
69   _splitpath(fn, fn_drive, fn_dir, fn_name, fn_ext);\r
70 \r
71   strcpy(INIfn, fn_drive);\r
72   strcat(INIfn, fn_dir);\r
73   strcat(INIfn, fn_name);\r
74   strcat(INIfn, ".ini");\r
75 #else // if def __linux__\r
76   strcpy (INIfn, g_get_home_dir ());\r
77   strcat (INIfn, "/.radiant/");\r
78   strcat (INIfn, RADIANT_VERSION);\r
79   strcat (INIfn, "/prtview.ini");\r
80 #endif\r
81 \r
82   portals.show_2d = INIGetInt(RENDER_2D, FALSE) ? true : false;\r
83   portals.aa_2d = INIGetInt(AA_2D, FALSE) ? true : false;\r
84   portals.width_2d = (float)INIGetInt(WIDTH_2D, 10);\r
85   portals.color_2d = (COLORREF)INIGetInt(COLOR_2D, RGB(0, 0, 255)) & 0xFFFFFF;\r
86 \r
87   if (portals.width_2d > 40.0f)\r
88     portals.width_2d = 40.0f;\r
89   else if (portals.width_2d < 2.0f)\r
90     portals.width_2d = 2.0f;\r
91 \r
92   portals.show_3d = INIGetInt(RENDER_3D, TRUE) ? true : false;\r
93 \r
94   portals.zbuffer = INIGetInt(ZBUFFER, 1);\r
95   portals.fog = INIGetInt(FOG, FALSE) ? true : false;\r
96   portals.polygons = INIGetInt(POLYGON, TRUE);\r
97   portals.lines = INIGetInt(LINE, TRUE);\r
98   portals.aa_3d = INIGetInt(AA_3D, FALSE) ? true : false;\r
99   portals.width_3d = (float)INIGetInt(WIDTH_3D, 4);\r
100   portals.color_3d = (COLORREF)INIGetInt(COLOR_3D, RGB(255, 255, 0)) & 0xFFFFFF;\r
101   portals.color_fog = (COLORREF)INIGetInt(COLOR_FOG, RGB(127, 127, 127)) & 0xFFFFFF;\r
102   portals.trans_3d = (float)INIGetInt(TRANS_3D, 50);\r
103   portals.clip = INIGetInt(CLIP, FALSE) ? true : false;\r
104   portals.clip_range = (float)INIGetInt(CLIP_RANGE, 16);\r
105 \r
106   if (portals.clip_range < 1)\r
107     portals.clip_range = 1;\r
108   else if (portals.clip_range > 128)\r
109     portals.clip_range = 128;\r
110 \r
111   if (portals.zbuffer < 0)\r
112     portals.zbuffer = 0;\r
113   else if (portals.zbuffer > 2)\r
114     portals.zbuffer = 0;\r
115 \r
116   if (portals.width_3d > 40.0f)\r
117     portals.width_3d = 40.0f;\r
118   else if (portals.width_3d < 2.0f)\r
119     portals.width_3d = 2.0f;\r
120 \r
121   if (portals.trans_3d > 100.0f)\r
122     portals.trans_3d = 100.0f;\r
123   else if (portals.trans_3d < 0.0f)\r
124     portals.trans_3d = 0.0f;\r
125 \r
126   SaveConfig();\r
127 \r
128   portals.FixColors();\r
129 }\r
130 \r
131 void SaveConfig () \r
132 {\r
133   INISetInt(RENDER_2D, portals.show_2d, "Draw in 2D windows");\r
134   INISetInt(WIDTH_2D, (int)portals.width_2d, "Width of lines in 2D windows (in units of 1/2)");\r
135   INISetInt(COLOR_2D, (int)portals.color_2d, "Color of lines in 2D windows");\r
136   INISetInt(AA_2D, portals.aa_2d, "Draw lines in 2D window anti-aliased");\r
137 \r
138   INISetInt(ZBUFFER, portals.zbuffer, "ZBuffer level in 3D window");\r
139   INISetInt(FOG, portals.fog, "Use depth cueing in 3D window");\r
140   INISetInt(POLYGON, portals.polygons, "Render using polygons polygons in 3D window");\r
141   INISetInt(LINE, portals.polygons, "Render using lines in 3D window");\r
142   INISetInt(RENDER_3D, portals.show_3d, "Draw in 3D windows");\r
143   INISetInt(WIDTH_3D, (int)portals.width_3d, "Width of lines in 3D window (in units of 1/2)");\r
144   INISetInt(COLOR_3D, (int)portals.color_3d, "Color of lines/polygons in 3D window");\r
145   INISetInt(COLOR_FOG, (int)portals.color_fog, "Color of distant lines/polygons in 3D window");\r
146   INISetInt(AA_3D, portals.aa_3d, "Draw lines in 3D window anti-aliased");\r
147   INISetInt(TRANS_3D, (int)portals.trans_3d, "Transparency in 3d view (0 = solid, 100 = invisible)");\r
148   INISetInt(CLIP, portals.clip, "Cubic clipper active for portal viewer");\r
149   INISetInt(CLIP_RANGE, (int)portals.clip_range, "Portal viewer cubic clip distance (in units of 64)");\r
150 }\r
151 \r
152 // Radiant function table\r
153 // use to access what Radiant provides\r
154 _QERFuncTable_1 g_FuncTable;\r
155 _QERQglTable g_QglTable;\r
156 \r
157 #define CONFIG_SECTION "Configuration"\r
158 \r
159 #if defined(__linux__) || defined(__APPLE__)\r
160 \r
161 static bool read_var (const char *filename, const char *section, const char *key, char *value)\r
162 {\r
163   char line[1024], *ptr;\r
164   FILE *rc;\r
165   \r
166   rc = fopen (filename, "rt");\r
167   \r
168   if (rc == NULL)\r
169     return false;\r
170   \r
171   while (fgets (line, 1024, rc) != 0)\r
172   {\r
173     // First we find the section\r
174     if (line[0] != '[')\r
175       continue;\r
176     \r
177     ptr = strchr (line, ']');\r
178     *ptr = '\0';\r
179     \r
180     if (strcmp (&line[1], section) == 0)\r
181     {\r
182       while (fgets (line, 1024, rc) != 0)\r
183       {\r
184         ptr = strchr (line, '=');\r
185         \r
186         if (ptr == NULL)\r
187         {\r
188           // reached the end of the section\r
189           fclose (rc);\r
190           return false;\r
191         }\r
192         *ptr = '\0';\r
193         \r
194         if (strcmp (line, key) == 0)\r
195         {\r
196           strcpy (value, ptr+1);\r
197           fclose (rc);\r
198           \r
199           while (value[strlen (value)-1] == 10 || \r
200             value[strlen (value)-1] == 13 ||\r
201             value[strlen (value)-1] == 32)\r
202             value[strlen (value)-1] = 0; \r
203           return true;\r
204         }\r
205       }\r
206     }\r
207   }\r
208 \r
209   fclose (rc);\r
210   return false;\r
211 }\r
212 \r
213 static bool save_var (const char *filename, const char *section, const char *key, const char *value)\r
214 {\r
215   char line[1024], *ptr;\r
216   FILE *old_rc = NULL, *rc;\r
217   bool found;\r
218 \r
219   rc = fopen (filename, "rb");\r
220 \r
221   if (rc != NULL)\r
222   {\r
223     guint32 len;\r
224     void *buf;\r
225 \r
226     char *tmpname = g_strdup_printf ("%s.tmp", filename);\r
227     old_rc = fopen (tmpname, "w+b");\r
228     g_free (tmpname);\r
229 \r
230     fseek (rc, 0, SEEK_END);\r
231     len = ftell (rc);\r
232     rewind (rc);\r
233     buf = g_malloc (len);\r
234     fread (buf, len, 1, rc);\r
235     fwrite (buf, len, 1, old_rc);\r
236     g_free (buf);\r
237     fclose (rc);\r
238     rewind (old_rc);\r
239   }\r
240 \r
241   rc = fopen (filename, "wb");\r
242 \r
243   if (rc == NULL)\r
244     return false;\r
245 \r
246   // First we need to find the section\r
247   found = false;\r
248   if (old_rc != NULL)\r
249   while (fgets (line, 1024, old_rc) != NULL)\r
250   {\r
251     fputs (line, rc);\r
252 \r
253     if (line[0] == '[')\r
254     {\r
255       ptr = strchr (line, ']');\r
256       *ptr = '\0';\r
257 \r
258       if (strcmp (&line[1], section) == 0)\r
259       {\r
260         found = true;\r
261         break;\r
262       }\r
263     }\r
264   } \r
265 \r
266   if (!found)\r
267   {\r
268     fputs ("\n", rc);\r
269     fprintf (rc, "[%s]\n", section);\r
270   }\r
271 \r
272   fprintf (rc, "%s=%s\n", key, value);\r
273 \r
274   if (old_rc != NULL)\r
275   {\r
276     while (fgets (line, 1024, old_rc) != NULL)\r
277     {\r
278       ptr = strchr (line, '=');\r
279 \r
280       if (ptr != NULL)\r
281       {\r
282         *ptr = '\0';\r
283 \r
284         if (strcmp (line, key) == 0)\r
285           break;\r
286  \r
287         *ptr = '=';\r
288         fputs (line, rc);\r
289       }\r
290       else\r
291       {\r
292         fputs (line, rc);\r
293         break;\r
294       }\r
295     }\r
296 \r
297     while (fgets (line, 1024, old_rc) != NULL)\r
298       fputs (line, rc);\r
299     \r
300     fclose (old_rc);\r
301 \r
302     char *tmpname = g_strdup_printf ("%s.tmp", filename);\r
303     remove (tmpname);\r
304     g_free (tmpname);\r
305   }\r
306 \r
307   fclose (rc);\r
308 \r
309   return true;\r
310 }\r
311 \r
312 #endif\r
313 \r
314 int INIGetInt(char *key, int def)\r
315 {\r
316 #if defined(__linux__) || defined(__APPLE__)\r
317   char value[1024];\r
318 \r
319   if (read_var (INIfn, CONFIG_SECTION, key, value))\r
320     return atoi (value);\r
321   else\r
322     return def;\r
323 #else\r
324   return GetPrivateProfileInt(CONFIG_SECTION, key, def, INIfn);\r
325 #endif\r
326 }\r
327 \r
328 void INISetInt(char *key, int val, char *comment /* = NULL */)\r
329 {\r
330   char s[1000];\r
331 \r
332   if(comment)\r
333     sprintf(s, "%d        ; %s", val, comment);\r
334   else\r
335     sprintf(s, "%d", val);\r
336 #if defined(__linux__) || defined(__APPLE__)\r
337   save_var (INIfn, CONFIG_SECTION, key, s);\r
338 #else\r
339   WritePrivateProfileString(CONFIG_SECTION, key, s, INIfn);\r
340 #endif\r
341 }\r
342 \r
343 \r
344 // plugin name\r
345 static const char *PLUGIN_NAME = "Portal Viewer";\r
346 // commands in the menu\r
347 static const char *PLUGIN_COMMANDS =\r
348         Q3R_CMD_ABOUT ";"\r
349         Q3R_CMD_SPLITTER ";"\r
350         Q3R_CMD_OPTIONS ";"\r
351         Q3R_CMD_SPLITTER ";"\r
352         Q3R_CMD_SHOW_2D ";"\r
353         Q3R_CMD_SHOW_3D ";"\r
354         Q3R_CMD_SPLITTER ";"\r
355         Q3R_CMD_RELEASE ";"\r
356         Q3R_CMD_LOAD;\r
357 \r
358 extern "C" LPVOID WINAPI QERPlug_GetFuncTable()\r
359 {\r
360   return &g_FuncTable;\r
361 }\r
362 \r
363 \r
364 //extern "C" LPCSTR WINAPI QERPlug_Init (HMODULE hApp, GtkWidget* hwndMain)\r
365 extern "C" const char* QERPlug_Init (void *hApp, void* pMainWidget)\r
366 {  \r
367   // Setup defaults & load config\r
368   InitInstance();\r
369   \r
370   return "Portal Viewer for Q3Radiant";\r
371 }\r
372 \r
373 extern "C" const char* QERPlug_GetName()\r
374 {\r
375   return (char*)PLUGIN_NAME;\r
376 }\r
377 \r
378 extern "C" const char* QERPlug_GetCommandList()\r
379 {\r
380   return (char*)PLUGIN_COMMANDS;\r
381 }\r
382 \r
383 /*\r
384 void Sys_Printf (char *text, ...)\r
385 {\r
386   va_list argptr;\r
387   char buf[32768];\r
388 \r
389   va_start (argptr,text);\r
390   vsprintf (buf, text, argptr);\r
391   va_end (argptr);\r
392 \r
393   g_FuncTable.m_pfnSysMsg (buf);\r
394 }\r
395 */\r
396 \r
397 bool interfaces_started = false;\r
398 \r
399 static void CheckInterfaces()\r
400 {\r
401   if (interfaces_started)\r
402     return;\r
403 \r
404   render.Register();\r
405 \r
406   interfaces_started = true;\r
407 }\r
408 \r
409 extern "C" void QERPlug_Dispatch(const char* p, vec3_t vMin, vec3_t vMax, bool bSingleBrush)\r
410 {\r
411   Sys_Printf (MSG_PREFIX "Command \"%s\"\n",p);\r
412 \r
413   if (!strcmp(p,Q3R_CMD_ABOUT))\r
414   {\r
415     DoAboutDlg ();\r
416   }\r
417   else if (!strcmp(p,Q3R_CMD_LOAD))\r
418   {\r
419     CheckInterfaces();\r
420 \r
421     if (interfaces_started)\r
422     {\r
423       if (DoLoadPortalFileDialog () == IDOK)\r
424       {\r
425         portals.Load();\r
426         g_FuncTable.m_pfnSysUpdateWindows(UPDATE_ALL);\r
427       }\r
428       else\r
429       {\r
430         Sys_Printf(MSG_PREFIX "Portal file load aborted.\n", portals.fn);\r
431       }\r
432     }\r
433   }\r
434   else if (!strcmp(p,Q3R_CMD_RELEASE))\r
435   {\r
436     portals.Purge();\r
437 \r
438     if (interfaces_started)\r
439       g_FuncTable.m_pfnSysUpdateWindows(UPDATE_ALL);\r
440 \r
441     Sys_Printf(MSG_PREFIX "Portals unloaded.\n");\r
442   }\r
443   else if (!strcmp(p,Q3R_CMD_SHOW_2D))\r
444   {\r
445     portals.show_2d = !portals.show_2d;\r
446 \r
447     if(interfaces_started)\r
448       g_FuncTable.m_pfnSysUpdateWindows(UPDATE_ALL);\r
449     SaveConfig();\r
450 \r
451     if(portals.show_2d)\r
452       Sys_Printf(MSG_PREFIX "Portals will be rendered in 2D view.\n");\r
453     else\r
454       Sys_Printf(MSG_PREFIX "Portals will NOT be rendered in 2D view.\n");\r
455   }\r
456   else if (!strcmp(p,Q3R_CMD_SHOW_3D))\r
457   {\r
458     portals.show_3d = !portals.show_3d;\r
459     SaveConfig();\r
460 \r
461     if (interfaces_started)\r
462       g_FuncTable.m_pfnSysUpdateWindows(UPDATE_ALL);\r
463 \r
464     if (portals.show_3d)\r
465       Sys_Printf(MSG_PREFIX "Portals will be rendered in 3D view.\n");\r
466     else\r
467       Sys_Printf(MSG_PREFIX "Portals will NOT be rendered in 3D view.\n");\r
468   }\r
469   else if (!strcmp(p,Q3R_CMD_OPTIONS))\r
470   {\r
471     DoConfigDialog ();\r
472     SaveConfig();\r
473 \r
474     if (interfaces_started)\r
475       g_FuncTable.m_pfnSysUpdateWindows(UPDATE_ALL);\r
476   }\r
477 }\r
478 \r
479 \r
480 \r
481 // =============================================================================\r
482 // SYNAPSE\r
483 \r
484 class CSynapseClientPrtView : public CSynapseClient\r
485 {\r
486 public:\r
487   // CSynapseClient API\r
488   bool RequestAPI(APIDescriptor_t *pAPI);\r
489   const char* GetInfo();\r
490   \r
491   CSynapseClientPrtView() { }\r
492   virtual ~CSynapseClientPrtView() { }\r
493 };\r
494 \r
495 \r
496 CSynapseServer* g_pSynapseServer = NULL;\r
497 CSynapseClientPrtView g_SynapseClient;\r
498 \r
499 extern "C" CSynapseClient* SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces (const char *version, CSynapseServer *pServer)\r
500 {\r
501   if (strcmp(version, SYNAPSE_VERSION))\r
502   {\r
503     Syn_Printf("ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version);\r
504     return NULL;\r
505   }\r
506   g_pSynapseServer = pServer;\r
507   g_pSynapseServer->IncRef();\r
508   Set_Syn_Printf(g_pSynapseServer->Get_Syn_Printf());\r
509     \r
510   g_SynapseClient.AddAPI(PLUGIN_MAJOR, PRTVIEW_MINOR, sizeof(_QERPluginTable));\r
511 \r
512   g_SynapseClient.AddAPI(RADIANT_MAJOR, NULL, sizeof(g_FuncTable), SYN_REQUIRE, &g_FuncTable);\r
513   g_SynapseClient.AddAPI(QGL_MAJOR, NULL, sizeof(g_QglTable), SYN_REQUIRE, &g_QglTable);\r
514 \r
515   return &g_SynapseClient;\r
516 }\r
517 \r
518 bool CSynapseClientPrtView::RequestAPI(APIDescriptor_t *pAPI)\r
519 {\r
520   if( !strcmp(pAPI->major_name, PLUGIN_MAJOR) )\r
521   {\r
522     if( !strcmp(pAPI->minor_name, PRTVIEW_MINOR) )\r
523     {\r
524       _QERPluginTable* pTable= static_cast<_QERPluginTable*>(pAPI->mpTable);\r
525 \r
526       pTable->m_pfnQERPlug_Init = QERPlug_Init;\r
527       pTable->m_pfnQERPlug_GetName = QERPlug_GetName;\r
528       pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;\r
529       pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch;\r
530       return true;\r
531     }\r
532   }\r
533 \r
534   Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo());\r
535   return false;\r
536 }\r
537 \r
538 #include "version.h"\r
539 \r
540 const char* CSynapseClientPrtView::GetInfo()\r
541 {\r
542   return "PrtView module built " __DATE__ " " RADIANT_VERSION;\r
543 }\r