]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/eclass_def.cpp
reorganized about dialog code, added updated 1.5.0 .ico
[xonotic/netradiant.git] / radiant / eclass_def.cpp
1 /*
2    Copyright (C) 1999-2007 id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
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.
11
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.
16
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
20  */
21
22 #include "cmdlib.h"
23
24 #include "synapse.h"
25 #define USE_QERTABLE_DEFINE
26 #include "qerplugin.h"
27 #define USE_ECLASSMANAGER_DEFINE
28 #include "ieclass.h"
29 #define USE_SCRIPLIBTABLE_DEFINE
30 #include "iscriplib.h"
31
32 #define __VFSTABLENAME g_FileSystemTable_def
33 #define USE_VFSTABLE_DEFINE
34 #include "ifilesystem.h"
35
36
37 #include "eclass_def.h"
38
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"
44  */
45
46 _QERScripLibTable g_ScripLibTable;
47 _EClassManagerTable g_EClassManagerTable;
48 _QERFuncTable_1 g_FuncTable;
49 _QERFileSystemTable g_FileSystemTable_def;
50
51 CSynapseBuiltinClientDef eclass_def;
52
53 // forward declare, I'm cheap
54 void Eclass_ScanFile( char *filename );
55
56 const char* EClass_GetExtension(){
57         return "def";
58 }
59
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 );
66
67         AddAPI( ECLASS_MAJOR, "def", sizeof( _EClassTable ) );
68 }
69
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;
75
76                 return true;
77         }
78
79         Syn_Printf( "ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo() );
80         return false;
81 }
82
83 #include "version.h"
84
85 const char* CSynapseBuiltinClientDef::GetInfo(){
86         return "Builtin .def module built " __DATE__ " " RADIANT_VERSION;
87 }
88
89 // ------------------------------------------------------------------------------------------------
90
91 qboolean eclass_found;
92 char *debugname;
93
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.
97
98         char *pText = NULL;
99         char *where = NULL;
100
101         p = NULL; // incase we don't find what we're looking for.
102         where = strstr( e->comments,pWhat );
103         if ( !where ) {
104                 return;
105         }
106
107         pText = where + strlen( pWhat );
108         if ( *pText == '\"' ) {
109                 pText++;
110         }
111
112         where = strchr( pText,'\"' );
113         if ( where ) {
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
118         }
119         else{
120                 p = strdup( pText );
121         }
122 }
123
124 eclass_t *Eclass_InitFromText( char *text ){
125         char    *t;
126         int len;
127         int r, i;
128         char parms[256], *p;
129         eclass_t    *e;
130         char color[128];
131
132         e = (eclass_t*)malloc( sizeof( *e ) );
133         memset( e, 0, sizeof( *e ) );
134
135         text += strlen( "/*QUAKED " );
136
137         // grab the name
138         text = COM_Parse( text );
139         e->name = (char*)malloc( strlen( Get_COM_Token() ) + 1 );
140         strcpy( e->name, Get_COM_Token() );
141         debugname = e->name;
142
143         // grab the color, reformat as texture name
144         r = sscanf( text," (%f %f %f)", &e->color[0], &e->color[1], &e->color[2] );
145         if ( r != 3 ) {
146                 return e;
147         }
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 );
151
152         while ( *text != ')' )
153         {
154                 if ( !*text ) {
155                         return e;
156                 }
157                 text++;
158         }
159         text++;
160
161         // get the size
162         text = COM_Parse( text );
163         if ( Get_COM_Token()[0] == '(' ) { // parse the size as two vectors
164                 e->fixedsize = true;
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] );
167                 if ( r != 6 ) {
168                         return e;
169                 }
170
171                 for ( i = 0 ; i < 2 ; i++ )
172                 {
173                         while ( *text != ')' )
174                         {
175                                 if ( !*text ) {
176                                         return e;
177                                 }
178                                 text++;
179                         }
180                         text++;
181                 }
182         }
183
184         // get the flags
185
186         // copy to the first /n
187         p = parms;
188         while ( *text && *text != '\n' )
189                 *p++ = *text++;
190         *p = 0;
191         text++;
192
193         // any remaining words are parm flags
194         p = parms;
195         for ( i = 0 ; i < MAX_FLAGS ; i++ )
196         {
197                 p = COM_Parse( p );
198                 if ( !p ) {
199                         break;
200                 }
201                 strcpy( e->flagnames[i], Get_COM_Token() );
202         }
203
204         // find the length until close comment
205         for ( t = text ; t[0] && !( t[0] == '*' && t[1] == '/' ) ; t++ )
206                 ;
207
208         // copy the comment block out
209         len = t - text;
210         e->comments = (char*)malloc( len + 1 );
211         memcpy( e->comments, text, len );
212 #ifdef _WIN32
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] = ' ';
218                 }
219                 else{
220                         e->comments[i] = text[i];
221                 }
222 #endif
223         e->comments[len] = 0;
224
225         setSpecialLoad( e, "model=", e->modelpath );
226         setSpecialLoad( e, "skin=", e->skinpath );
227         char *pFrame = NULL;
228         setSpecialLoad( e, "frame=", pFrame );
229         if ( pFrame != NULL ) {
230                 e->nFrame = atoi( pFrame );
231                 delete pFrame; //Hydra - Fixed memory leak!
232         }
233
234         if ( !e->skinpath ) {
235                 setSpecialLoad( e, "texture=", e->skinpath );
236         }
237
238         // setup show flags
239         e->nShowFlags = 0;
240         if ( strcmpi( e->name, "light" ) == 0 || strcmpi( e->name, "dlight" ) == 0 || strcmpi( e->name, "lightjunior" ) == 0 ) {
241                 e->nShowFlags |= ECLASS_LIGHT;
242         }
243
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 )
248                   ) {
249                 e->nShowFlags |= ECLASS_ANGLE;
250         }
251         if ( strcmpi( e->name, "path" ) == 0 ) {
252                 e->nShowFlags |= ECLASS_PATH;
253         }
254         if ( strcmpi( e->name, "misc_model" ) == 0 ) {
255                 e->nShowFlags |= ECLASS_MISCMODEL;
256         }
257
258
259         return e;
260 }
261
262 void Eclass_ScanFile( char *filename ){
263         int size;
264         char    *data;
265         eclass_t    *e;
266         int i;
267         char temp[1024];
268
269         QE_ConvertDOSToUnixName( temp, filename );
270
271         size = vfsLoadFullPathFile( filename, (void**)&data );
272         if ( size <= 0 ) {
273                 Sys_FPrintf( SYS_ERR, "Eclass_ScanFile: %s not found\n", filename );
274                 return;
275         }
276         Sys_Printf( "ScanFile: %s\n", temp );
277         eclass_found = false;
278         for ( i = 0 ; i < size ; i++ )
279         {
280                 if ( !strncmp( data + i, "/*QUAKED",8 ) ) {
281                         e = Eclass_InitFromText( data + i );
282                         if ( e ) {
283                                 Eclass_InsertAlphabetized( e );
284                         }
285                         else{
286                                 Sys_FPrintf( SYS_ERR, "Error parsing: %s in %s\n",debugname, filename );
287                         }
288
289                         // single ?
290                         *Get_Eclass_E() = e;
291                         Set_Eclass_Found( true );
292                         if ( Get_Parsing_Single() ) {
293                                 break;
294                         }
295                 }
296         }
297
298         g_free( data );
299 }