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