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