2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #define USE_QERTABLE_DEFINE
26 #include "qerplugin.h"
27 #define USE_ECLASSMANAGER_DEFINE
29 #define USE_SCRIPLIBTABLE_DEFINE
30 #include "iscriplib.h"
32 #define __VFSTABLENAME g_FileSystemTable_def
33 #define USE_VFSTABLE_DEFINE
34 #include "ifilesystem.h"
37 #include "eclass_def.h"
39 /*! \file eclass_def.cpp
40 \brief .def entity description format
41 implements parsing for .def entity format
42 this is statically linked into the radiant core as we always need it, but really considered
43 as an idependant module by the rest of the core. "ECLASS_MAJOR" "def"
46 _QERScripLibTable g_ScripLibTable;
47 _EClassManagerTable g_EClassManagerTable;
48 _QERFuncTable_1 g_FuncTable;
49 _QERFileSystemTable g_FileSystemTable_def;
51 CSynapseBuiltinClientDef eclass_def;
53 // forward declare, I'm cheap
54 void Eclass_ScanFile( char *filename );
56 const char* EClass_GetExtension(){
60 void CSynapseBuiltinClientDef::EnumerateInterfaces( CSynapseServer *server ){
61 AddAPI( SCRIPLIB_MAJOR, NULL, sizeof( g_ScripLibTable ), SYN_REQUIRE, &g_ScripLibTable );
62 AddAPI( RADIANT_MAJOR, NULL, sizeof( g_FuncTable ), SYN_REQUIRE, &g_FuncTable );
63 AddAPI( ECLASSMANAGER_MAJOR, NULL, sizeof( g_EClassManagerTable ), SYN_REQUIRE, &g_EClassManagerTable );
64 // hardcode the minor for now, we can still add it to the synapse.config at some point
65 AddAPI( VFS_MAJOR, "pk3", sizeof( g_FileSystemTable_def ), SYN_REQUIRE, &g_FileSystemTable_def );
67 AddAPI( ECLASS_MAJOR, "def", sizeof( _EClassTable ) );
70 bool CSynapseBuiltinClientDef::RequestAPI( APIDescriptor_t *pAPI ){
71 if ( !strcmp( pAPI->major_name, ECLASS_MAJOR ) ) {
72 _EClassTable* pTable = static_cast<_EClassTable*>( pAPI->mpTable );
73 pTable->m_pfnScanFile = &Eclass_ScanFile;
74 pTable->m_pfnGetExtension = &EClass_GetExtension;
79 Syn_Printf( "ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo() );
85 const char* CSynapseBuiltinClientDef::GetInfo(){
86 return "Builtin .def module built " __DATE__ " " RADIANT_VERSION;
89 // ------------------------------------------------------------------------------------------------
91 qboolean eclass_found;
94 void setSpecialLoad( eclass_t *e, const char* pWhat, char*& p ){
95 // Hydra: removed some amazingly bad cstring usage, whoever wrote that
96 // needs to be taken out and shot.
101 p = NULL; // incase we don't find what we're looking for.
102 where = strstr( e->comments,pWhat );
107 pText = where + strlen( pWhat );
108 if ( *pText == '\"' ) {
112 where = strchr( pText,'\"' );
114 int len = ( where - pText );
115 p = new char[len + 1];
116 strncpy( p,pText,len );
117 p[len] = 0; // just to make sure, as most implementations of strncpy don't null terminate
124 eclass_t *Eclass_InitFromText( char *text ){
132 e = (eclass_t*)malloc( sizeof( *e ) );
133 memset( e, 0, sizeof( *e ) );
135 text += strlen( "/*QUAKED " );
138 text = COM_Parse( text );
139 e->name = (char*)malloc( strlen( Get_COM_Token() ) + 1 );
140 strcpy( e->name, Get_COM_Token() );
143 // grab the color, reformat as texture name
144 r = sscanf( text," (%f %f %f)", &e->color[0], &e->color[1], &e->color[2] );
148 sprintf( color, "(%f %f %f)", e->color[0], e->color[1], e->color[2] );
149 //strcpy (e->texdef.name, color);
150 e->texdef.SetName( color );
152 while ( *text != ')' )
162 text = COM_Parse( text );
163 if ( Get_COM_Token()[0] == '(' ) { // parse the size as two vectors
165 r = sscanf( text,"%f %f %f) (%f %f %f)", &e->mins[0], &e->mins[1], &e->mins[2],
166 &e->maxs[0], &e->maxs[1], &e->maxs[2] );
171 for ( i = 0 ; i < 2 ; i++ )
173 while ( *text != ')' )
186 // copy to the first /n
188 while ( *text && *text != '\n' )
193 // any remaining words are parm flags
195 for ( i = 0 ; i < MAX_FLAGS ; i++ )
201 strcpy( e->flagnames[i], Get_COM_Token() );
204 // find the length until close comment
205 for ( t = text ; t[0] && !( t[0] == '*' && t[1] == '/' ) ; t++ )
208 // copy the comment block out
210 e->comments = (char*)malloc( len + 1 );
211 memcpy( e->comments, text, len );
213 // the win32 Gtk widgets are expecting text stuff to be in unix format (that is CR only instead of DOS's CR/LF)
214 // we convert on the fly by replacing the LF with a ' ' (yeah I'm cheap)
215 for ( i = 0 ; i < len ; i++ )
216 if ( text[i] == '\r' ) {
217 e->comments[i] = ' ';
220 e->comments[i] = text[i];
223 e->comments[len] = 0;
225 setSpecialLoad( e, "model=", e->modelpath );
226 setSpecialLoad( e, "skin=", e->skinpath );
228 setSpecialLoad( e, "frame=", pFrame );
229 if ( pFrame != NULL ) {
230 e->nFrame = atoi( pFrame );
231 delete pFrame; //Hydra - Fixed memory leak!
234 if ( !e->skinpath ) {
235 setSpecialLoad( e, "texture=", e->skinpath );
240 if ( strcmpi( e->name, "light" ) == 0 || strcmpi( e->name, "dlight" ) == 0 || strcmpi( e->name, "lightjunior" ) == 0 ) {
241 e->nShowFlags |= ECLASS_LIGHT;
244 if ( ( strnicmp( e->name, "info_player", strlen( "info_player" ) ) == 0 )
245 || ( strnicmp( e->name, "path_corner", strlen( "path_corner" ) ) == 0 )
246 || ( strnicmp( e->name, "team_ctf", strlen( "team_ctf" ) ) == 0 )
247 || ( strnicmp( e->name, "misc_teleporter_dest", strlen( "misc_teleporter_dest" ) ) == 0 )
249 e->nShowFlags |= ECLASS_ANGLE;
251 if ( strcmpi( e->name, "path" ) == 0 ) {
252 e->nShowFlags |= ECLASS_PATH;
254 if ( strcmpi( e->name, "misc_model" ) == 0 ) {
255 e->nShowFlags |= ECLASS_MISCMODEL;
262 void Eclass_ScanFile( char *filename ){
269 QE_ConvertDOSToUnixName( temp, filename );
271 size = vfsLoadFullPathFile( filename, (void**)&data );
273 Sys_FPrintf( SYS_ERR, "Eclass_ScanFile: %s not found\n", filename );
276 Sys_Printf( "ScanFile: %s\n", temp );
277 eclass_found = false;
278 for ( i = 0 ; i < size ; i++ )
280 if ( !strncmp( data + i, "/*QUAKED",8 ) ) {
281 e = Eclass_InitFromText( data + i );
283 Eclass_InsertAlphabetized( e );
286 Sys_FPrintf( SYS_ERR, "Error parsing: %s in %s\n",debugname, filename );
291 Set_Eclass_Found( true );
292 if ( Get_Parsing_Single() ) {