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 #if defined (__linux__) || defined(__FreeBSD__)
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
ReadCurrentTexture()62 void ReadCurrentTexture()
63 {
64 const char* textureName = g_FuncTable.m_pfnGetCurrentTexture();
65 strcpy(g_CurrentTexture, textureName);
66 }
67
GetCurrentTexture()68 const char* GetCurrentTexture()
69 {
70 ReadCurrentTexture();
71 return g_CurrentTexture;
72 }
73
MoveBlock(int dir,vec3_t min,vec3_t max,float dist)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
SetInitialStairPos(int dir,vec3_t min,vec3_t max,float width)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
TranslateString(char * buf)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
Sys_ERROR(char * text,...)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
UnixToDosPath(char * path)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
ExtractFilename(const char * path)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__) || defined (__FreeBSD__)
218 // the bCreateConsole parameter is ignored on linux ..
Q_Exec(const char * pCmd,bool bCreateConsole)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
Q_Exec(const char * pCmd,bool bCreateConsole)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
StartBSP()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
BuildMiniPrt(list<Str> * exclusionList)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
FindEntityFromTargetname(const char * targetname,int * entNum)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
FillDefaultTexture(_QERFaceData * faceData,vec3_t va,vec3_t vb,vec3_t vc,const char * texture)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
Determinant3x3(float a1,float a2,float a3,float b1,float b2,float b3,float c1,float c2,float c3)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
GetEntityCentre(const char * entity,vec3_t centre)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
Min(vec_t a,vec_t b)418 vec_t Min(vec_t a, vec_t b)
419 {
420 if(a < b)
421 return a;
422 return b;
423 }
424
MakeNormal(vec_t * va,vec_t * vb,vec_t * vc,vec_t * out)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 }
431