2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
\r
5 This file is part of GtkRadiant.
\r
7 GtkRadiant is free software; you can redistribute it and/or modify
\r
8 it under the terms of the GNU General Public License as published by
\r
9 the Free Software Foundation; either version 2 of the License, or
\r
10 (at your option) any later version.
\r
12 GtkRadiant is distributed in the hope that it will be useful,
\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
15 GNU General Public License for more details.
\r
17 You should have received a copy of the GNU General Public License
\r
18 along with GtkRadiant; if not, write to the Free Software
\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\r
24 #include "synapse.h"
\r
25 #define USE_QERTABLE_DEFINE
\r
26 #include "qerplugin.h"
\r
27 #define USE_ECLASSMANAGER_DEFINE
\r
28 #include "ieclass.h"
\r
29 #define USE_SCRIPLIBTABLE_DEFINE
\r
30 #include "iscriplib.h"
\r
32 #define __VFSTABLENAME g_FileSystemTable_def
\r
33 #define USE_VFSTABLE_DEFINE
\r
34 #include "ifilesystem.h"
\r
37 #include "eclass_def.h"
\r
39 /*! \file eclass_def.cpp
\r
40 \brief .def entity description format
\r
41 implements parsing for .def entity format
\r
42 this is statically linked into the radiant core as we always need it, but really considered
\r
43 as an idependant module by the rest of the core. "ECLASS_MAJOR" "def"
\r
46 _QERScripLibTable g_ScripLibTable;
\r
47 _EClassManagerTable g_EClassManagerTable;
\r
48 _QERFuncTable_1 g_FuncTable;
\r
49 _QERFileSystemTable g_FileSystemTable_def;
\r
51 CSynapseBuiltinClientDef eclass_def;
\r
53 // forward declare, I'm cheap
\r
54 void Eclass_ScanFile (char *filename);
\r
56 const char* EClass_GetExtension()
\r
61 void CSynapseBuiltinClientDef::EnumerateInterfaces(CSynapseServer *server)
\r
63 AddAPI(SCRIPLIB_MAJOR, NULL, sizeof(g_ScripLibTable), SYN_REQUIRE, &g_ScripLibTable);
\r
64 AddAPI(RADIANT_MAJOR, NULL, sizeof(g_FuncTable), SYN_REQUIRE, &g_FuncTable);
\r
65 AddAPI(ECLASSMANAGER_MAJOR, NULL, sizeof(g_EClassManagerTable), SYN_REQUIRE, &g_EClassManagerTable);
\r
66 // hardcode the minor for now, we can still add it to the synapse.config at some point
\r
67 AddAPI(VFS_MAJOR, "pk3", sizeof(g_FileSystemTable_def), SYN_REQUIRE, &g_FileSystemTable_def);
\r
69 AddAPI(ECLASS_MAJOR, "def", sizeof(_EClassTable));
\r
72 bool CSynapseBuiltinClientDef::RequestAPI(APIDescriptor_t *pAPI)
\r
74 if (!strcmp(pAPI->major_name, ECLASS_MAJOR))
\r
76 _EClassTable* pTable= static_cast<_EClassTable*>(pAPI->mpTable);
\r
77 pTable->m_pfnScanFile = &Eclass_ScanFile;
\r
78 pTable->m_pfnGetExtension = &EClass_GetExtension;
\r
83 Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo());
\r
87 #include "version.h"
\r
89 const char* CSynapseBuiltinClientDef::GetInfo()
\r
91 return "Builtin .def module built " __DATE__ " " RADIANT_VERSION;
\r
94 // ------------------------------------------------------------------------------------------------
\r
96 qboolean eclass_found;
\r
99 void setSpecialLoad(eclass_t *e, const char* pWhat, char*& p)
\r
101 // Hydra: removed some amazingly bad cstring usage, whoever wrote that
\r
102 // needs to be taken out and shot.
\r
104 char *pText = NULL;
\r
105 char *where = NULL;
\r
107 p = NULL; // incase we don't find what we're looking for.
\r
108 where = strstr(e->comments,pWhat);
\r
112 pText = where + strlen(pWhat);
\r
113 if (*pText == '\"')
\r
116 where = strchr(pText,'\"');
\r
119 int len = (where-pText);
\r
120 p = new char[len + 1];
\r
121 strncpy(p,pText,len);
\r
122 p[len]=0; // just to make sure, as most implementations of strncpy don't null terminate
\r
128 eclass_t *Eclass_InitFromText (char *text)
\r
133 char parms[256], *p;
\r
137 e = (eclass_t*)malloc(sizeof(*e));
\r
138 memset (e, 0, sizeof(*e));
\r
140 text += strlen("/*QUAKED ");
\r
143 text = COM_Parse (text);
\r
144 e->name = (char*)malloc (strlen(Get_COM_Token())+1);
\r
145 strcpy (e->name, Get_COM_Token());
\r
146 debugname = e->name;
\r
148 // grab the color, reformat as texture name
\r
149 r = sscanf (text," (%f %f %f)", &e->color[0], &e->color[1], &e->color[2]);
\r
153 sprintf (color, "(%f %f %f)", e->color[0], e->color[1], e->color[2]);
\r
154 //strcpy (e->texdef.name, color);
\r
155 e->texdef.SetName(color);
\r
157 while (*text != ')')
\r
167 text = COM_Parse (text);
\r
168 if (Get_COM_Token()[0] == '(')
\r
169 { // parse the size as two vectors
\r
170 e->fixedsize = true;
\r
171 r = sscanf (text,"%f %f %f) (%f %f %f)", &e->mins[0], &e->mins[1], &e->mins[2],
\r
172 &e->maxs[0], &e->maxs[1], &e->maxs[2]);
\r
177 for (i=0 ; i<2 ; i++)
\r
179 while (*text != ')')
\r
192 // copy to the first /n
\r
194 while (*text && *text != '\n')
\r
199 // any remaining words are parm flags
\r
201 for (i=0 ; i<MAX_FLAGS ; i++)
\r
206 strcpy (e->flagnames[i], Get_COM_Token());
\r
209 // find the length until close comment
\r
210 for (t=text ; t[0] && !(t[0]=='*' && t[1]=='/') ; t++)
\r
213 // copy the comment block out
\r
215 e->comments = (char*)malloc (len+1);
\r
216 memcpy (e->comments, text, len);
\r
218 // the win32 Gtk widgets are expecting text stuff to be in unix format (that is CR only instead of DOS's CR/LF)
\r
219 // we convert on the fly by replacing the LF with a ' ' (yeah I'm cheap)
\r
220 for (i=0 ; i<len ; i++)
\r
221 if (text[i] == '\r')
\r
222 e->comments[i] = ' ';
\r
224 e->comments[i] = text[i];
\r
226 e->comments[len] = 0;
\r
228 setSpecialLoad(e, "model=", e->modelpath);
\r
229 setSpecialLoad(e, "skin=", e->skinpath);
\r
230 char *pFrame = NULL;
\r
231 setSpecialLoad(e, "frame=", pFrame);
\r
232 if (pFrame != NULL)
\r
234 e->nFrame = atoi(pFrame);
\r
235 delete pFrame; //Hydra - Fixed memory leak!
\r
239 setSpecialLoad(e, "texture=", e->skinpath);
\r
241 // setup show flags
\r
243 if (strcmpi(e->name, "light") == 0 || strcmpi(e->name, "dlight") == 0 || strcmpi(e->name, "lightjunior") == 0)
\r
245 e->nShowFlags |= ECLASS_LIGHT;
\r
248 if ( (strnicmp(e->name, "info_player", strlen("info_player")) == 0)
\r
249 ||(strnicmp(e->name, "path_corner", strlen("path_corner")) == 0)
\r
250 ||(strnicmp(e->name, "team_ctf", strlen("team_ctf")) == 0)
\r
251 ||(strnicmp(e->name, "misc_teleporter_dest", strlen("misc_teleporter_dest")) == 0)
\r
254 e->nShowFlags |= ECLASS_ANGLE;
\r
256 if (strcmpi(e->name, "path") == 0)
\r
258 e->nShowFlags |= ECLASS_PATH;
\r
260 if (strcmpi(e->name, "misc_model") == 0)
\r
262 e->nShowFlags |= ECLASS_MISCMODEL;
\r
269 void Eclass_ScanFile (char *filename)
\r
277 QE_ConvertDOSToUnixName( temp, filename );
\r
279 size = vfsLoadFullPathFile(filename, (void**)&data);
\r
282 Sys_FPrintf (SYS_ERR, "Eclass_ScanFile: %s not found\n", filename);
\r
285 Sys_Printf ("ScanFile: %s\n", temp);
\r
286 eclass_found = false;
\r
287 for (i=0 ; i<size ; i++)
\r
289 if (!strncmp(data+i, "/*QUAKED",8))
\r
291 e = Eclass_InitFromText (data+i);
\r
293 Eclass_InsertAlphabetized (e);
\r
295 Sys_FPrintf (SYS_ERR, "Error parsing: %s in %s\n",debugname, filename);
\r
298 *Get_Eclass_E() = e;
\r
299 Set_Eclass_Found(true);
\r
300 if ( Get_Parsing_Single() )
\r