]> git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/misc.cpp
gcc: appease the hardening warnings
[xonotic/netradiant.git] / contrib / bobtoolz / misc.cpp
1 /*
2    BobToolz plugin for GtkRadiant
3    Copyright (C) 2001 Gordon Biggans
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 #include "misc.h"
21 #include "globaldefs.h"
22
23 #include <list>
24 #include "str.h"
25
26 #include "DPoint.h"
27 #include "DPlane.h"
28 #include "DBrush.h"
29 #include "DEPair.h"
30 #include "DPatch.h"
31 #include "DEntity.h"
32
33 #include "funchandlers.h"
34
35 #if GDEF_OS_POSIX
36
37 #include <sys/types.h>
38 #include <unistd.h>
39
40 #endif
41
42 #include "iundo.h"
43 #include "ientity.h"
44 #include "iscenegraph.h"
45 #include "qerplugin.h"
46
47 #include <vector>
48 #include <list>
49 #include <map>
50 #include <algorithm>
51
52 #include "scenelib.h"
53
54 /*==========================
55         Global Vars
56    ==========================*/
57
58 //HANDLE bsp_process;
59 char g_CurrentTexture[256] = "";
60
61 //=============================================================
62 //=============================================================
63
64 void ReadCurrentTexture()
65 {
66     const char *textureName = GlobalRadiant().TextureBrowser_getSelectedShader();
67     strcpy(g_CurrentTexture, textureName);
68 }
69
70 const char *GetCurrentTexture()
71 {
72     ReadCurrentTexture();
73     return g_CurrentTexture;
74 }
75
76 void MoveBlock(int dir, vec3_t min, vec3_t max, float dist)
77 {
78     switch (dir) {
79         case MOVE_EAST: {
80             min[0] += dist;
81             max[0] += dist;
82             break;
83         }
84         case MOVE_WEST: {
85             min[0] -= dist;
86             max[0] -= dist;
87             break;
88         }
89         case MOVE_NORTH: {
90             min[1] += dist;
91             max[1] += dist;
92             break;
93         }
94         case MOVE_SOUTH: {
95             min[1] -= dist;
96             max[1] -= dist;
97             break;
98         }
99     }
100 }
101
102 void SetInitialStairPos(int dir, vec3_t min, vec3_t max, float width)
103 {
104     switch (dir) {
105         case MOVE_EAST: {
106             max[0] = min[0] + width;
107             break;
108         }
109         case MOVE_WEST: {
110             min[0] = max[0] - width;
111             break;
112         }
113         case MOVE_NORTH: {
114             max[1] = min[1] + width;
115             break;
116         }
117         case MOVE_SOUTH: {
118             min[1] = max[1] - width;
119             break;
120         }
121     }
122 }
123
124 char *TranslateString(char *buf)
125 {
126     static char buf2[32768];
127
128     std::size_t l = strlen(buf);
129     char *out = buf2;
130     for (std::size_t i = 0; i < l; i++) {
131         if (buf[i] == '\n') {
132             *out++ = '\r';
133             *out++ = '\n';
134         } else {
135             *out++ = buf[i];
136         }
137     }
138     *out++ = 0;
139
140     return buf2;
141 }
142
143
144 char *UnixToDosPath(char *path)
145 {
146 #if !GDEF_OS_WINDOWS
147     return path;
148 #else
149     for ( char* p = path; *p; p++ )
150     {
151         if ( *p == '/' ) {
152             *p = '\\';
153         }
154     }
155     return path;
156 #endif
157 }
158
159 const char *ExtractFilename(const char *path)
160 {
161     const char *p = strrchr(path, '/');
162     if (!p) {
163         p = strrchr(path, '\\');
164
165         if (!p) {
166             return path;
167         }
168     }
169     return ++p;
170 }
171
172 extern char *PLUGIN_NAME;
173 /*char* GetGameFilename(char* buffer, const char* filename)
174    {
175     strcpy(buffer, g_FuncTable.m_pfnGetGamePath());
176     char* p = strrchr(buffer, '/');
177    *++p = '\0';
178     strcat(buffer, filename);
179     buffer = UnixToDosPath(buffer);
180     return buffer;
181    }*/
182
183 #if GDEF_OS_POSIX
184
185 // the bCreateConsole parameter is ignored on linux ..
186 bool Q_Exec(const char *pCmd, bool bCreateConsole)
187 {
188     switch (fork()) {
189         case -1:
190             return false;
191 //      Error ("CreateProcess failed");
192             break;
193         case 0:
194 #if GDEF_DEBUG
195             printf("Running system...\n");
196             printf("Command: %s\n", pCmd);
197 #endif
198             // NOTE: we could use that to detect when a step finishes. But then it
199             // would not work for remote compiling stuff.
200 //      execlp (pCmd, pCmd, NULL);
201             int ret = system(pCmd);
202             printf("system() returned");
203             _exit(ret);
204             break;
205     }
206     return true;
207 }
208
209 #endif
210
211 #if GDEF_OS_WINDOWS
212
213 #include <windows.h>
214
215 bool Q_Exec( const char *pCmd, bool bCreateConsole ){
216     // G_DeWan: Don't know if this is needed for linux version
217
218     PROCESS_INFORMATION pi;
219     STARTUPINFO si = {0};            // Initialize all members to zero
220     si.cb = sizeof( STARTUPINFO );     // Set byte count
221     DWORD dwCreationFlags;
222
223     if ( bCreateConsole ) {
224         dwCreationFlags = CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS;
225     }
226     else{
227         dwCreationFlags = DETACHED_PROCESS | NORMAL_PRIORITY_CLASS;
228     }
229
230     for (; *pCmd == ' '; pCmd++ ) ;
231
232     if ( !CreateProcess( NULL, (char *)pCmd, NULL, NULL, false, dwCreationFlags, NULL, NULL, &si, &pi ) ) {
233         return false;
234     }
235
236     return true;
237 }
238 #endif
239
240 void StartBSP()
241 {
242     char exename[256];
243     GetFilename(exename, "q3map");
244     UnixToDosPath(exename); // do we want this done in linux version?
245
246     char mapname[256];
247     const char *pn = GlobalRadiant().getMapsPath();
248
249     strcpy(mapname, pn);
250     strcat(mapname, "/ac_prt.map");
251     UnixToDosPath(mapname);
252
253     char command[1024];
254     sprintf(command, "%s -nowater -fulldetail %s", exename, mapname);
255
256     Q_Exec(command, true);
257 }
258
259 class EntityWriteMiniPrt {
260     mutable DEntity world;
261     FILE *pFile;
262     std::list<Str> *exclusionList;
263 public:
264     EntityWriteMiniPrt(FILE *pFile, std::list<Str> *exclusionList)
265             : pFile(pFile), exclusionList(exclusionList)
266     {
267     }
268
269     void operator()(scene::Instance &instance) const
270     {
271         const char *classname = Node_getEntity(instance.path().top())->getKeyValue("classname");
272
273         if (!strcmp(classname, "worldspawn")) {
274             world.LoadFromEntity(instance.path().top(), false);
275             world.RemoveNonCheckBrushes(exclusionList, true);
276             world.SaveToFile(pFile);
277         } else if (strstr(classname, "info_")) {
278             world.ClearBrushes();
279             world.ClearEPairs();
280             world.LoadEPairList(Node_getEntity(instance.path().top()));
281             world.SaveToFile(pFile);
282         }
283     }
284 };
285
286 void BuildMiniPrt(std::list<Str> *exclusionList)
287 {
288     // yes, we could just use -fulldetail option, but, as SPOG said
289     // it'd be faster without all the hint, donotenter etc textures and
290     // doors, etc
291
292
293
294     char buffer[128];
295     const char *pn = GlobalRadiant().getMapsPath();
296
297     strcpy(buffer, pn);
298     strcat(buffer, "/ac_prt.map");
299     FILE *pFile = fopen(buffer, "w");
300
301     // ahem, thx rr2
302     if (!pFile) {
303         return;
304     }
305
306     Scene_forEachEntity(EntityWriteMiniPrt(pFile, exclusionList));
307
308     fclose(pFile);
309
310     StartBSP();
311 }
312
313 class EntityFindByTargetName {
314     const char *targetname;
315 public:
316     mutable const scene::Path *result;
317
318     EntityFindByTargetName(const char *targetname)
319             : targetname(targetname), result(0)
320     {
321     }
322
323     void operator()(scene::Instance &instance) const
324     {
325         if (result == 0) {
326             const char *value = Node_getEntity(instance.path().top())->getKeyValue("targetname");
327
328             if (!strcmp(value, targetname)) {
329                 result = &instance.path();
330             }
331         }
332     }
333 };
334
335 const scene::Path *FindEntityFromTargetname(const char *targetname)
336 {
337     return Scene_forEachEntity(EntityFindByTargetName(targetname)).result;
338 }
339
340 void FillDefaultTexture(_QERFaceData *faceData, vec3_t va, vec3_t vb, vec3_t vc, const char *texture)
341 {
342     faceData->m_texdef.rotate = 0;
343     faceData->m_texdef.scale[0] = 0.5;
344     faceData->m_texdef.scale[1] = 0.5;
345     faceData->m_texdef.shift[0] = 0;
346     faceData->m_texdef.shift[1] = 0;
347     faceData->contents = 0;
348     faceData->flags = 0;
349     faceData->value = 0;
350     if (*texture) {
351         faceData->m_shader = texture;
352     } else {
353         faceData->m_shader = "textures/common/caulk";
354     }
355     VectorCopy(va, faceData->m_p0);
356     VectorCopy(vb, faceData->m_p1);
357     VectorCopy(vc, faceData->m_p2);
358 }
359
360 float Determinant3x3(float a1, float a2, float a3,
361                      float b1, float b2, float b3,
362                      float c1, float c2, float c3)
363 {
364     return a1 * (b2 * c3 - b3 * c2) - a2 * (b1 * c3 - b3 * c1) + a3 * (b1 * c2 - b2 * c1);
365 }
366
367 bool GetEntityCentre(const char *entity, vec3_t centre)
368 {
369     const scene::Path *ent = FindEntityFromTargetname(entity);
370     if (!ent) {
371         return false;
372     }
373
374     scene::Instance &instance = *GlobalSceneGraph().find(*ent);
375     VectorCopy(instance.worldAABB().origin, centre);
376
377     return true;
378 }
379
380 vec_t Min(vec_t a, vec_t b)
381 {
382     if (a < b) {
383         return a;
384     }
385     return b;
386 }
387
388 void MakeNormal(const vec_t *va, const vec_t *vb, const vec_t *vc, vec_t *out)
389 {
390     vec3_t v1, v2;
391     VectorSubtract(va, vb, v1);
392     VectorSubtract(vc, vb, v2);
393     CrossProduct(v1, v2, out);
394 }
395
396 char *GetFilename(char *buffer, const char *filename)
397 {
398     strcpy(buffer, GlobalRadiant().getAppPath());
399     strcat(buffer, "plugins/");
400     strcat(buffer, filename);
401     return buffer;
402 }