]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - plugins/eclassfgd/plugin.cpp
uncrustify! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / plugins / eclassfgd / plugin.cpp
index fa8920af18f2153e082dde8a7b035c9df89f24d9..eb389d8a07ce284d806ea218e5fe9f0dd1b8e581 100644 (file)
@@ -1,23 +1,23 @@
 /*
-Copyright (C) 1999-2007 id Software, Inc. and contributors.
-For a list of contributors, see the accompanying CONTRIBUTORS file.
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
 
-This file is part of GtkRadiant.
+   This file is part of GtkRadiant.
 
-GtkRadiant is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   GtkRadiant is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-GtkRadiant is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   GtkRadiant is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with GtkRadiant; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
+   You should have received a copy of the GNU General Public License
+   along with GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
 
 //#define FGD_VERBOSE // define this for extra info in the log.
 
@@ -46,11 +46,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
     Classes can request information in other classes.
 
-    Solid/Base and Point/Base classes can have the same names as other 
+    Solid/Base and Point/Base classes can have the same names as other
     classes but there can be only one of each solid/point/base class with
     the same name,
 
-    e.g.:  
+    e.g.:
 
     this is NOT allowed:
 
@@ -87,7 +87,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
         with the same name, adjusted Find_Class() so that it can search
         for baseclasses only,  this fixes the problem with PointClass "light"
         requesting the BaseClass "light".
+
     v0.4 - 25/March/2002
       - bleh, It turns out that non-baseclasses can request non-baseclasses
         so now I've changed Find_Class() so that it can ignore a specific class
@@ -105,19 +105,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     ToDo
     ====
 
   * add support for setting the eclass_t's modelpath.
+ * add support for setting the eclass_t's modelpath.
       (not useful for CS, but very useful for HL).
 
   * need to implement usage for e->skinpath in the core.
+ * need to implement usage for e->skinpath in the core.
 
   * cleanup some areas now that GetTokenExtra() is available
+ * cleanup some areas now that GetTokenExtra() is available
       (some parts were written prior to it's creation).
 
   * Import the comments between each BaseClass's main [ ] set.
+ * Import the comments between each BaseClass's main [ ] set.
       (unfortunatly they're // cstyle comments, which GetToken skips over)
       But still ignore comments OUTSIDE the main [ ] set.
 
-*/
+ */
 
 _QERScripLibTable g_ScripLibTable;
 _EClassManagerTable g_EClassManagerTable;
@@ -125,11 +125,10 @@ _QERFuncTable_1 g_FuncTable;
 _QERFileSystemTable g_FileSystemTable;
 
 // forward declare
-void Eclass_ScanFile (char *filename);
+void Eclass_ScanFile( char *filename );
 
-const char* EClass_GetExtension()
-{
-  return "fgd";
+const char* EClass_GetExtension(){
+       return "fgd";
 }
 
 CSynapseServer* g_pSynapseServer = NULL;
@@ -138,51 +137,47 @@ CSynapseClientFGD g_SynapseClient;
 #if __GNUC__ >= 4
 #pragma GCC visibility push(default)
 #endif
-extern "C" CSynapseClient* SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces( const char *version, CSynapseServer *pServer ) {
+extern "C" CSynapseClient * SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces( const char *version, CSynapseServer *pServer ) {
 #if __GNUC__ >= 4
 #pragma GCC visibility pop
 #endif
-  if (strcmp(version, SYNAPSE_VERSION))
-  {
-    Syn_Printf("ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version);
-    return NULL;
-  }
-  g_pSynapseServer = pServer;
-  g_pSynapseServer->IncRef();
-  Set_Syn_Printf(g_pSynapseServer->Get_Syn_Printf());
-  
-  g_SynapseClient.AddAPI(ECLASS_MAJOR, "fgd", sizeof(_EClassTable));
-  g_SynapseClient.AddAPI(SCRIPLIB_MAJOR, NULL, sizeof(g_ScripLibTable), SYN_REQUIRE, &g_ScripLibTable);
-  g_SynapseClient.AddAPI(RADIANT_MAJOR, NULL, sizeof(g_FuncTable), SYN_REQUIRE, &g_FuncTable);
-  g_SynapseClient.AddAPI(ECLASSMANAGER_MAJOR, NULL, sizeof(g_EClassManagerTable), SYN_REQUIRE, &g_EClassManagerTable);
-  
-  // Needs a 'default' option for this minor because we certainly don't load anything from wad files :)
-  g_SynapseClient.AddAPI(VFS_MAJOR, "wad", sizeof(g_FileSystemTable), SYN_REQUIRE, &g_FileSystemTable);
-
-  return &g_SynapseClient;
+       if ( strcmp( version, SYNAPSE_VERSION ) ) {
+               Syn_Printf( "ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version );
+               return NULL;
+       }
+       g_pSynapseServer = pServer;
+       g_pSynapseServer->IncRef();
+       Set_Syn_Printf( g_pSynapseServer->Get_Syn_Printf() );
+
+       g_SynapseClient.AddAPI( ECLASS_MAJOR, "fgd", sizeof( _EClassTable ) );
+       g_SynapseClient.AddAPI( SCRIPLIB_MAJOR, NULL, sizeof( g_ScripLibTable ), SYN_REQUIRE, &g_ScripLibTable );
+       g_SynapseClient.AddAPI( RADIANT_MAJOR, NULL, sizeof( g_FuncTable ), SYN_REQUIRE, &g_FuncTable );
+       g_SynapseClient.AddAPI( ECLASSMANAGER_MAJOR, NULL, sizeof( g_EClassManagerTable ), SYN_REQUIRE, &g_EClassManagerTable );
+
+       // Needs a 'default' option for this minor because we certainly don't load anything from wad files :)
+       g_SynapseClient.AddAPI( VFS_MAJOR, "wad", sizeof( g_FileSystemTable ), SYN_REQUIRE, &g_FileSystemTable );
+
+       return &g_SynapseClient;
 }
 
-bool CSynapseClientFGD::RequestAPI(APIDescriptor_t *pAPI)
-{
-  if (!strcmp(pAPI->major_name, ECLASS_MAJOR))
-  {
-    _EClassTable* pTable= static_cast<_EClassTable*>(pAPI->mpTable);
-
-    pTable->m_pfnGetExtension = &EClass_GetExtension;
-    pTable->m_pfnScanFile = &Eclass_ScanFile;
-    
-    return true;    
-  }
-  
-  Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo());
-  return false;
+bool CSynapseClientFGD::RequestAPI( APIDescriptor_t *pAPI ){
+       if ( !strcmp( pAPI->major_name, ECLASS_MAJOR ) ) {
+               _EClassTable* pTable = static_cast<_EClassTable*>( pAPI->mpTable );
+
+               pTable->m_pfnGetExtension = &EClass_GetExtension;
+               pTable->m_pfnScanFile = &Eclass_ScanFile;
+
+               return true;
+       }
+
+       Syn_Printf( "ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo() );
+       return false;
 }
 
 #include "version.h"
 
-const char* CSynapseClientFGD::GetInfo()
-{
-  return ".fgd eclass module built " __DATE__ " " RADIANT_VERSION;
+const char* CSynapseClientFGD::GetInfo(){
+       return ".fgd eclass module built " __DATE__ " " RADIANT_VERSION;
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -203,939 +198,915 @@ char *classnames[] = {"NOT DEFINED","BaseClass","PointClass","SolidClass"};
 char *optionnames[] = {"NOT DEFINED","String","Choices","Integer","Flags"};
 
 typedef struct choice_s {
-  int value;
-  char *name;
+       int value;
+       char *name;
 } choice_t;
 
 typedef struct option_s {
-  int optiontype;
-  char *optioninfo;
-  char *epairname;
-  char *optiondefault;
-  GSList *choices; // list of choices_t
+       int optiontype;
+       char *optioninfo;
+       char *epairname;
+       char *optiondefault;
+       GSList *choices; // list of choices_t
 } option_t;
 
 typedef struct class_s {
-  int classtype; // see CLASS_* above.
-  char *classname;
-  GSList *l_baselist; // when building the eclass_t, other class_s's with these names are required.
-  char *description;
-
-  GSList *l_optionlist; // when building the eclass_t, other class_s's with these names are required.
-
-  bool gotsize; // if set then boundingbox is valid.
-  vec3_t boundingbox[2]; // mins, maxs
-       
-  bool gotcolor; // if set then color is valid.  
-  vec3_t color; // R,G,B, loaded as 0-255 
-       
-  char *model; // relative path + filename to a model (.spr/.mdl) file, or NULL
+       int classtype; // see CLASS_* above.
+       char *classname;
+       GSList *l_baselist; // when building the eclass_t, other class_s's with these names are required.
+       char *description;
+
+       GSList *l_optionlist; // when building the eclass_t, other class_s's with these names are required.
+
+       bool gotsize; // if set then boundingbox is valid.
+       vec3_t boundingbox[2]; // mins, maxs
+
+       bool gotcolor; // if set then color is valid.
+       vec3_t color; // R,G,B, loaded as 0-255
+
+       char *model; // relative path + filename to a model (.spr/.mdl) file, or NULL
 } class_t;
 
 /*
-===========================================================
-utility functions
-
-===========================================================
-*/
-char *strlower (char *start)
-{
-       char    *in;
+   ===========================================================
+   utility functions
+
+   ===========================================================
+ */
+char *strlower( char *start ){
+       char    *in;
        in = start;
-       while (*in)
+       while ( *in )
        {
-               *in = tolower(*in); 
+               *in = tolower( *in );
                in++;
        }
        return start;
 }
 
-char *addstr(char *dest,char *source)
-{
-  if (dest)
-               {
-    char *ptr;
-    int len = strlen(dest);
-    ptr = (char *) malloc (len + strlen(source) + 1);
-    strcpy(ptr,dest);
-    strcpy(ptr+len,source);
-    free(dest);
-    dest = ptr;
-  }
-  else
-                       {
-    dest = strdup(source);
-                       }
-  return(dest);
+char *addstr( char *dest,char *source ){
+       if ( dest ) {
+               char *ptr;
+               int len = strlen( dest );
+               ptr = (char *) malloc( len + strlen( source ) + 1 );
+               strcpy( ptr,dest );
+               strcpy( ptr + len,source );
+               free( dest );
+               dest = ptr;
+       }
+       else
+       {
+               dest = strdup( source );
+       }
+       return( dest );
 }
 
-int getindex(unsigned int a)
-{
-  unsigned int count = 0;
-  unsigned int b = 0;
-  for (;b != a;count++)
-  {
-    b = (1<<count);
-    if (count > a)
-      return -1;    
-  }
-  return (count);
+int getindex( unsigned int a ){
+       unsigned int count = 0;
+       unsigned int b = 0;
+       for (; b != a; count++ )
+       {
+               b = ( 1 << count );
+               if ( count > a ) {
+                       return -1;
+               }
+       }
+       return ( count );
 }
 
-void ClearGSList (GSList* lst)
-{
-  GSList *p = lst;
-  while (p)
-  {
-    free (p->data);
-    p = g_slist_remove (p, p->data);
-               }
+void ClearGSList( GSList* lst ){
+       GSList *p = lst;
+       while ( p )
+       {
+               free( p->data );
+               p = g_slist_remove( p, p->data );
+       }
 }
-       
+
 /*!
-free a choice_t structure and it's contents
-*/
-void Free_Choice(choice_t *p)
-{
-  if (p->name) free(p->name);
-  free (p);
-       
+   free a choice_t structure and it's contents
+ */
+void Free_Choice( choice_t *p ){
+       if ( p->name ) {
+               free( p->name );
+       }
+       free( p );
+
 }
 
 /*
-===========================================================
-Main functions
+   ===========================================================
+   Main functions
 
-===========================================================
-*/
+   ===========================================================
+ */
 
 /*!
-free an option_t structure and it's contents
-*/
-void Free_Option(option_t *p)
-{
-  if (p->epairname) free(p->epairname);
-  if (p->optiondefault) free(p->optiondefault);
-  if (p->optioninfo) free(p->optioninfo);
-  GSList *l = p->choices;
-  while (l)
+   free an option_t structure and it's contents
+ */
+void Free_Option( option_t *p ){
+       if ( p->epairname ) {
+               free( p->epairname );
+       }
+       if ( p->optiondefault ) {
+               free( p->optiondefault );
+       }
+       if ( p->optioninfo ) {
+               free( p->optioninfo );
+       }
+       GSList *l = p->choices;
+       while ( l )
        {
-    Free_Choice ((choice_t *)l->data);
-    l = g_slist_remove (l, l->data);
+               Free_Choice( (choice_t *)l->data );
+               l = g_slist_remove( l, l->data );
        }
-  free (p);
+       free( p );
 }
 
 /*!
-free a class_t structure and it's contents
-*/
-void Free_Class(class_t *p)
-{
-  GSList *l = p->l_optionlist;
-  while (l)
-  {
-    Free_Option ((option_t *)l->data);
-    l = g_slist_remove (l, l->data);
+   free a class_t structure and it's contents
+ */
+void Free_Class( class_t *p ){
+       GSList *l = p->l_optionlist;
+       while ( l )
+       {
+               Free_Option( (option_t *)l->data );
+               l = g_slist_remove( l, l->data );
+       }
+
+       if ( p->classname ) {
+               free( p->classname );
        }
-       
-  if (p->classname) free(p->classname);
-  free (p);
+       free( p );
 }
 
 /*!
-find a class in the list
-*/
-class_t *Find_Class(GSList *l,char *classname, class_t *ignore)
-{
-  for (GSList *clst = l; clst != NULL; clst = clst->next)
-               {
-    class_t *c = (class_t *)clst->data;
+   find a class in the list
+ */
+class_t *Find_Class( GSList *l,char *classname, class_t *ignore ){
+       for ( GSList *clst = l; clst != NULL; clst = clst->next )
+       {
+               class_t *c = (class_t *)clst->data;
 
-    if (c == ignore)
-      continue;
+               if ( c == ignore ) {
+                       continue;
+               }
 
-    // NOTE: to speed up we could make all the classnames lower-case when they're initialised.
-    if (!stricmp(c->classname,classname))
-                       {
-      return c;
-                       }
-      
+               // NOTE: to speed up we could make all the classnames lower-case when they're initialised.
+               if ( !stricmp( c->classname,classname ) ) {
+                       return c;
                }
-  return NULL;
+
+       }
+       return NULL;
 }
 
 /*!
-Import as much as possible from a class_t into an eclass_t
-Note: this is somewhat recursive, as a class can require a class that requires a class and so on..
-*/
-void EClass_ImportFromClass(eclass_t *e, GSList *l_classes, class_t *bc)
-{
-  char color[128];
-
-  // We allocate 16k here, but only the memory actually used is kept allocated.
-  // this is just used for building the final comments string.
-  // Note: if the FGD file contains comments that are >16k (per entity) then
-  // radiant will crash upon loading such a file as the eclass_t will become
-  // corrupted.
-  // FIXME: we could add some length checking when building "newcomments", but
-  // that'd slow it down a bit.
-  char newcomments[16384] = "";
-
-  //Note: we override the values already in e.
-  //and we do it in such a way that the items that appear last in the l_baselist
-  //represent the final values.
-  
-  if (bc->description)
-       {
-    sprintf(newcomments,"%s\n",bc->description);
-    e->comments = addstr(e->comments,newcomments);
-    newcomments[0] = 0; // so we don't add them twice.
-       } 
+   Import as much as possible from a class_t into an eclass_t
+   Note: this is somewhat recursive, as a class can require a class that requires a class and so on..
+ */
+void EClass_ImportFromClass( eclass_t *e, GSList *l_classes, class_t *bc ){
+       char color[128];
+
+       // We allocate 16k here, but only the memory actually used is kept allocated.
+       // this is just used for building the final comments string.
+       // Note: if the FGD file contains comments that are >16k (per entity) then
+       // radiant will crash upon loading such a file as the eclass_t will become
+       // corrupted.
+       // FIXME: we could add some length checking when building "newcomments", but
+       // that'd slow it down a bit.
+       char newcomments[16384] = "";
+
+       //Note: we override the values already in e.
+       //and we do it in such a way that the items that appear last in the l_baselist
+       //represent the final values.
+
+       if ( bc->description ) {
+               sprintf( newcomments,"%s\n",bc->description );
+               e->comments = addstr( e->comments,newcomments );
+               newcomments[0] = 0; // so we don't add them twice.
+       }
 
 
-  // import from other classes if required.
+       // import from other classes if required.
 
-  if (bc->l_baselist)
-  {
-    // this class requires other base classes.
-       
-    for (GSList *bclst = bc->l_baselist; bclst != NULL; bclst = bclst->next)
-    {      
-      char *requestedclass = (char *)bclst->data;
+       if ( bc->l_baselist ) {
+               // this class requires other base classes.
+
+               for ( GSList *bclst = bc->l_baselist; bclst != NULL; bclst = bclst->next )
+               {
+                       char *requestedclass = (char *)bclst->data;
 
 //      class_t *rbc = Find_Class(l_classes, requestedclass, true);
-      class_t *rbc = Find_Class(l_classes, requestedclass, bc);
-
-      // make sure we don't request ourself!
-      if (rbc == bc)
-      {
-        Sys_Printf ("WARNING: baseclass '%s' tried to request itself!\n", bclst->data);
-      }
-                 else
-      {
-        if (!rbc)
-        {
-          Sys_Printf ("WARNING: could not find the requested baseclass '%s' when building '%s'\n", requestedclass,bc->classname);
+                       class_t *rbc = Find_Class( l_classes, requestedclass, bc );
+
+                       // make sure we don't request ourself!
+                       if ( rbc == bc ) {
+                               Sys_Printf( "WARNING: baseclass '%s' tried to request itself!\n", bclst->data );
+                       }
+                       else
+                       {
+                               if ( !rbc ) {
+                                       Sys_Printf( "WARNING: could not find the requested baseclass '%s' when building '%s'\n", requestedclass,bc->classname );
+                               }
+                               else
+                               {
+                                       // call ourself!
+                                       EClass_ImportFromClass( e, l_classes, rbc );
+                               }
+                       }
+               }
        }
-       else
-        {
-          // call ourself!
-          EClass_ImportFromClass(e, l_classes, rbc);
-        }
+       // SIZE
+       if ( bc->gotsize ) {
+               e->fixedsize = true;
+               memcpy( e->mins,bc->boundingbox[0],sizeof( vec3_t ) );
+               memcpy( e->maxs,bc->boundingbox[1],sizeof( vec3_t ) );
        }
-    }
-  }
-  // SIZE
-  if (bc->gotsize)
-  {
-    e->fixedsize = true;
-    memcpy(e->mins,bc->boundingbox[0],sizeof( vec3_t ));
-    memcpy(e->maxs,bc->boundingbox[1],sizeof( vec3_t ));
-  }
 /*
-  // Hydra: apparently, this would be bad.
+   // Hydra: apparently, this would be bad.
 
-  if (bc->sprite)
-  {
+   if (bc->sprite)
+   {
     // Hydra - NOTE: e->skinpath is not currently used by the editor but the code
     // to set it is used by both this eclass_t loader and the .DEF eclass_t loader.
     // TODO: implement using e->skinpath.
     if (e->skinpath)
-      free (e->skinpath); 
-       
+      free (e->skinpath);
+
     e->skinpath = strdup(bc->sprite);
-  }
-*/
-
-  // MODEL
-  if (bc->model)
-  {
-    if (e->modelpath)
-      free (e->modelpath);
-
-    e->modelpath = strdup(bc->model);
-  }
-
-  // COLOR
-  if (bc->gotcolor)
-  {
-    memcpy(e->color,bc->color,sizeof( vec3_t ));
-    sprintf (color, "(%f %f %f)", e->color[0], e->color[1], e->color[2]);
-       e->texdef.SetName(color);
-  }
-
-  // SPAWNFLAGS and COMMENTS
-  if (bc->l_optionlist)
-  {
-    for (GSList *optlst = bc->l_optionlist; optlst != NULL; optlst = optlst->next)
-    {
-      option_t *opt = (option_t*) optlst->data;
-       
-      if (opt->optiontype != OPTION_FLAGS)
-      {
-        // add some info to the comments.
-        if (opt->optioninfo)
-        {
-          sprintf(newcomments+strlen(newcomments),"%s '%s' %s%s\n",
-            opt->epairname, 
-            opt->optioninfo ? opt->optioninfo : "", 
-            opt->optiondefault ? ", Default: " : "",
-            opt->optiondefault ? opt->optiondefault : "");      
-        }
-        else
-        {
-          sprintf(newcomments+strlen(newcomments),"%s %s%s\n",
-            opt->epairname, 
-            opt->optiondefault ? ", Default: " : "",
-            opt->optiondefault ? opt->optiondefault : "");      
-        }
-      }
-
-      GSList *choicelst;
-      switch(opt->optiontype)
-      {        
-        case OPTION_FLAGS :
-          // grab the flags.
-          for (choicelst = opt->choices; choicelst != NULL; choicelst = choicelst->next)
-          {
-            choice_t *choice = (choice_t*) choicelst->data;
-       
-            int index = getindex(choice->value);
-            index--;
-            if (index < MAX_FLAGS)
-            {
-              strcpy(e->flagnames[index],choice->name);
-            }
-            else
-                 {
-              Sys_Printf ("WARNING: baseclass '%s' has a spawnflag out of range, ignored!\n", bc->classname);
-            }
-          }
-                           break;
-        case OPTION_CHOICES :
-          strcat(newcomments,"  Choices:\n");
-          for (choicelst = opt->choices; choicelst != NULL; choicelst = choicelst->next)
-          {
-            choice_t *choice = (choice_t*) choicelst->data;
-            sprintf(newcomments+strlen(newcomments),"  %5d - %s\n",choice->value,choice->name);
-          }       
-          break;
-      }
-    }
+   }
+ */
+
+       // MODEL
+       if ( bc->model ) {
+               if ( e->modelpath ) {
+                       free( e->modelpath );
+               }
+
+               e->modelpath = strdup( bc->model );
+       }
+
+       // COLOR
+       if ( bc->gotcolor ) {
+               memcpy( e->color,bc->color,sizeof( vec3_t ) );
+               sprintf( color, "(%f %f %f)", e->color[0], e->color[1], e->color[2] );
+               e->texdef.SetName( color );
+       }
+
+       // SPAWNFLAGS and COMMENTS
+       if ( bc->l_optionlist ) {
+               for ( GSList *optlst = bc->l_optionlist; optlst != NULL; optlst = optlst->next )
+               {
+                       option_t *opt = (option_t*) optlst->data;
+
+                       if ( opt->optiontype != OPTION_FLAGS ) {
+                               // add some info to the comments.
+                               if ( opt->optioninfo ) {
+                                       sprintf( newcomments + strlen( newcomments ),"%s '%s' %s%s\n",
+                                                        opt->epairname,
+                                                        opt->optioninfo ? opt->optioninfo : "",
+                                                        opt->optiondefault ? ", Default: " : "",
+                                                        opt->optiondefault ? opt->optiondefault : "" );
+                               }
+                               else
+                               {
+                                       sprintf( newcomments + strlen( newcomments ),"%s %s%s\n",
+                                                        opt->epairname,
+                                                        opt->optiondefault ? ", Default: " : "",
+                                                        opt->optiondefault ? opt->optiondefault : "" );
+                               }
+                       }
+
+                       GSList *choicelst;
+                       switch ( opt->optiontype )
+                       {
+                       case OPTION_FLAGS:
+                               // grab the flags.
+                               for ( choicelst = opt->choices; choicelst != NULL; choicelst = choicelst->next )
+                               {
+                                       choice_t *choice = (choice_t*) choicelst->data;
+
+                                       int index = getindex( choice->value );
+                                       index--;
+                                       if ( index < MAX_FLAGS ) {
+                                               strcpy( e->flagnames[index],choice->name );
+                                       }
+                                       else
+                                       {
+                                               Sys_Printf( "WARNING: baseclass '%s' has a spawnflag out of range, ignored!\n", bc->classname );
+                                       }
+                               }
+                               break;
+                       case OPTION_CHOICES:
+                               strcat( newcomments,"  Choices:\n" );
+                               for ( choicelst = opt->choices; choicelst != NULL; choicelst = choicelst->next )
+                               {
+                                       choice_t *choice = (choice_t*) choicelst->data;
+                                       sprintf( newcomments + strlen( newcomments ),"  %5d - %s\n",choice->value,choice->name );
+                               }
+                               break;
+                       }
+               }
+       }
+
+       // name
+       if ( e->name ) {
+               free( e->name );
        }
+       e->name = strdup( bc->classname );
+
+       // fixed size initialisation
+       if ( bc->classtype == CLASS_POINTCLASS ) {
+               e->fixedsize = true;
+               // some point classes dont seem to have size()'s in the fgd, so set up a default here..
+               if ( ( e->mins[0] == 0 ) && ( e->mins[1] == 0 ) && ( e->mins[2] == 0 ) &&
+                        ( e->maxs[0] == 0 ) && ( e->maxs[1] == 0 ) && ( e->maxs[2] == 0 ) ) {
+                       e->mins[0] = -8;
+                       e->mins[1] = -8;
+                       e->mins[2] = -8;
+                       e->maxs[0] = 8;
+                       e->maxs[1] = 8;
+                       e->maxs[2] = 8;
+               }
+
+               if ( e->texdef.GetName() == NULL ) {
+                       // no color specified for this entity in the fgd file
+                       // set one now
+                       // Note: if this eclass_t is not fully built, then this may be
+                       // overridden with the correct color.
 
-  // name
-  if (e->name) free(e->name);
-  e->name = strdup(bc->classname);
-       
-  // fixed size initialisation
-  if (bc->classtype == CLASS_POINTCLASS)
-  {    
-    e->fixedsize = true;
-    // some point classes dont seem to have size()'s in the fgd, so set up a default here..
-    if ((e->mins[0] == 0) && (e->mins[1] == 0) && (e->mins[2] == 0) && 
-        (e->maxs[0] == 0) && (e->maxs[1] == 0) && (e->maxs[2] == 0))
-  {
-      e->mins[0] = -8;
-      e->mins[1] = -8;
-      e->mins[2] = -8;
-      e->maxs[0] = 8;
-      e->maxs[1] = 8;
-      e->maxs[2] = 8;
-  }
-
-    if (e->texdef.GetName() == NULL)
-    {
-      // no color specified for this entity in the fgd file
-      // set one now
-      // Note: if this eclass_t is not fully built, then this may be
-      // overridden with the correct color.
-      
-      e->color[0] = 1;
-      e->color[1] = 0.5; // how about a nice bright pink, mmm, nice! :)
-      e->color[2] = 1;
-
-      sprintf (color, "(%f %f %f)", e->color[0], e->color[1], e->color[2]);
-       e->texdef.SetName(color);
-    }
-  }
-
-  // COMMENTS
-  if (newcomments[0])
-  {
-    e->comments = addstr(e->comments,newcomments);
-  }
+                       e->color[0] = 1;
+                       e->color[1] = 0.5; // how about a nice bright pink, mmm, nice! :)
+                       e->color[2] = 1;
+
+                       sprintf( color, "(%f %f %f)", e->color[0], e->color[1], e->color[2] );
+                       e->texdef.SetName( color );
+               }
+       }
+
+       // COMMENTS
+       if ( newcomments[0] ) {
+               e->comments = addstr( e->comments,newcomments );
+       }
 }
 
 /*!
-create the eclass_t structures and add to the global list.
-*/
-void Create_EClasses(GSList *l_classes)
-{
-  int count = 0;
-  // loop through the loaded structures finding all the non BaseClasses
-  for (GSList *clst = l_classes; clst != NULL; clst = clst->next)
-  {
-    class_t *c = (class_t *)clst->data;
-
-    if (c->classtype == CLASS_BASECLASS) // not looking for these.
-      continue;
-
-    eclass_t *e = (eclass_t *) malloc( sizeof( eclass_s ));
-    memset(e,0,sizeof( eclass_s ));
-
-    EClass_ImportFromClass(e, l_classes, c );
-
-    // radiant will crash if this is null, and it still could be at this point.
-    if (!e->comments)
-    {
-      e->comments=strdup("No description available, check documentation\n");
-    }
-
-    // dump the spawnflags to the end of the comments.
-    int i;
-    bool havespawnflags;
-
-    havespawnflags = false;
-    for (i = 0 ; i < MAX_FLAGS ; i++)
-    {
-      if (*e->flagnames[i]) havespawnflags = true;
-    }
-
-    if (havespawnflags)
-    {
-      char spawnline[80];
-      e->comments = addstr(e->comments,"Spawnflags\n");
-      for (i = 0 ; i < MAX_FLAGS ; i++)
-      {
-        if (*e->flagnames[i]) 
-        {
-          sprintf(spawnline,"  %d - %s\n", 1<<i, e->flagnames[i]); 
-          e->comments = addstr(e->comments,spawnline);
-        }
-      }
-    }
-
-    Eclass_InsertAlphabetized (e);
-    count ++;
-    // Hydra: ttimo, I don't think this code is required...
+   create the eclass_t structures and add to the global list.
+ */
+void Create_EClasses( GSList *l_classes ){
+       int count = 0;
+       // loop through the loaded structures finding all the non BaseClasses
+       for ( GSList *clst = l_classes; clst != NULL; clst = clst->next )
+       {
+               class_t *c = (class_t *)clst->data;
+
+               if ( c->classtype == CLASS_BASECLASS ) { // not looking for these.
+                       continue;
+               }
+
+               eclass_t *e = (eclass_t *) malloc( sizeof( eclass_s ) );
+               memset( e,0,sizeof( eclass_s ) );
+
+               EClass_ImportFromClass( e, l_classes, c );
+
+               // radiant will crash if this is null, and it still could be at this point.
+               if ( !e->comments ) {
+                       e->comments = strdup( "No description available, check documentation\n" );
+               }
+
+               // dump the spawnflags to the end of the comments.
+               int i;
+               bool havespawnflags;
+
+               havespawnflags = false;
+               for ( i = 0 ; i < MAX_FLAGS ; i++ )
+               {
+                       if ( *e->flagnames[i] ) {
+                               havespawnflags = true;
+                       }
+               }
+
+               if ( havespawnflags ) {
+                       char spawnline[80];
+                       e->comments = addstr( e->comments,"Spawnflags\n" );
+                       for ( i = 0 ; i < MAX_FLAGS ; i++ )
+                       {
+                               if ( *e->flagnames[i] ) {
+                                       sprintf( spawnline,"  %d - %s\n", 1 << i, e->flagnames[i] );
+                                       e->comments = addstr( e->comments,spawnline );
+                               }
+                       }
+               }
+
+               Eclass_InsertAlphabetized( e );
+               count++;
+               // Hydra: ttimo, I don't think this code is required...
                // single ?
                *Get_Eclass_E() = e;
-    Set_Eclass_Found(true);
-               if ( Get_Parsing_Single() )
+               Set_Eclass_Found( true );
+               if ( Get_Parsing_Single() ) {
                        break;
-  }
+               }
+       }
 
-  Sys_Printf ("FGD Loaded %d entities.\n", count);
+       Sys_Printf( "FGD Loaded %d entities.\n", count );
 }
 
-void Eclass_ScanFile (char *filename)
-{
-       int             size;
-       char    *data;
-       char    temp[1024];
-  GSList *l_classes = NULL;
-       char  token_debug[1024]; //++Hydra FIXME: cleanup this.
-  bool done = false;
-  int len,classtype;
-
-  char *token = Token();
-       
+void Eclass_ScanFile( char *filename ){
+       int size;
+       char    *data;
+       char temp[1024];
+       GSList *l_classes = NULL;
+       char token_debug[1024];  //++Hydra FIXME: cleanup this.
+       bool done = false;
+       int len,classtype;
+
+       char *token = Token();
+
        QE_ConvertDOSToUnixName( temp, filename );
-       
-       size = vfsLoadFullPathFile (filename, (void**)&data);
-  if (size <= 0)
-  {
-    Sys_FPrintf (SYS_ERR, "Eclass_ScanFile: %s not found\n", filename);
-    return;
-  }
-       Sys_Printf ("ScanFile: %s\n", temp);    
 
-  // start parsing the file
-  StartTokenParsing(data);
+       size = vfsLoadFullPathFile( filename, (void**)&data );
+       if ( size <= 0 ) {
+               Sys_FPrintf( SYS_ERR, "Eclass_ScanFile: %s not found\n", filename );
+               return;
+       }
+       Sys_Printf( "ScanFile: %s\n", temp );
 
-  // build a list of base classes first
+       // start parsing the file
+       StartTokenParsing( data );
 
-  while (!done)
+       // build a list of base classes first
+
+       while ( !done )
+       {
+               // find an @ sign.
+               do
                {
-    // find an @ sign.
-    do
-    {
-      if (!GetToken(true))
-      {
-        done = true;
-        break;
-      }
-    } while (token[0] != '@');
-
-    strcpy(temp,token+1); // skip the @
-
-    classtype = CLASS_NOCLASS;
-    if (!stricmp(temp,"BaseClass")) classtype = CLASS_BASECLASS;
-    if (!stricmp(temp,"PointClass")) classtype = CLASS_POINTCLASS;
-    if (!stricmp(temp,"SolidClass")) classtype = CLASS_SOLIDCLASS;
-
-    if (classtype)
-    {
-      class_t *newclass = (class_t *) malloc( sizeof(class_s) );
-      memset( newclass, 0, sizeof(class_s) );
-      newclass->classtype = classtype;
-
-      while (1)
-      {
-        GetTokenExtra(false,"(",false); // option or =
-        strcpy(token_debug,token);
-
-        if (!strcmp(token,"="))
-        {
-          UnGetToken();
-          break;
-        }
-                       else
-        {
-          strlower(token);
-          if (!strcmp(token,"base"))
-          {
-            GetTokenExtra(false,"(",true); // (
-
-            if (!strcmp(token,"("))
-            {
-              while (GetTokenExtra(false,",)",false)) // option) or option,
-              {
-                newclass->l_baselist = g_slist_append (newclass->l_baselist, strdup(token));
-
-                GetTokenExtra(false,",)",true); // , or )
-                if (!strcmp(token,")"))
-                  break;
-
-              }
-            }
-          }
-          else if (!strcmp(token,"size"))
-          {
-            // parse (w h d) or (x y z, x y z)
-
-            GetTokenExtra(false,"(",true); // (
-            if (!strcmp(token,"("))
-            {
-              int sizedone = false;
-              float w,h,d;
-              GetToken(false);
-              w = atof(token);
-              GetToken(false);
-              h = atof(token);
-              GetToken(false); // number) or number ,
-              strcpy(temp,token);
-              len = strlen(temp);
-              if (temp[len-1] == ')') sizedone = true;                
-              temp[len-1] = 0;
-              d = atof(temp);
-              if (sizedone)
-              {
-                // only one set of cordinates supplied, change the W,H,D to mins/maxs
-                newclass->boundingbox[0][0] = 0 - (w / 2);
-                newclass->boundingbox[1][0] = w / 2;
-                newclass->boundingbox[0][1] = 0 - (h / 2);
-                newclass->boundingbox[1][1] = h / 2;
-                newclass->boundingbox[0][2] = 0 - (d / 2);
-                newclass->boundingbox[1][2] = d / 2;
-                newclass->gotsize = true;
-              }
-              else
-              {
-                newclass->boundingbox[0][0] = w;
-                newclass->boundingbox[0][1] = h;
-                newclass->boundingbox[0][2] = d;
-                GetToken(false);
-                newclass->boundingbox[1][0] = atof(token);
-                GetToken(false);
-                newclass->boundingbox[1][1] = atof(token);
+                       if ( !GetToken( true ) ) {
+                               done = true;
+                               break;
+                       }
+               } while ( token[0] != '@' );
+
+               strcpy( temp,token + 1 ); // skip the @
+
+               classtype = CLASS_NOCLASS;
+               if ( !stricmp( temp,"BaseClass" ) ) {
+                       classtype = CLASS_BASECLASS;
+               }
+               if ( !stricmp( temp,"PointClass" ) ) {
+                       classtype = CLASS_POINTCLASS;
+               }
+               if ( !stricmp( temp,"SolidClass" ) ) {
+                       classtype = CLASS_SOLIDCLASS;
+               }
+
+               if ( classtype ) {
+                       class_t *newclass = (class_t *) malloc( sizeof( class_s ) );
+                       memset( newclass, 0, sizeof( class_s ) );
+                       newclass->classtype = classtype;
+
+                       while ( 1 )
+                       {
+                               GetTokenExtra( false,"(",false ); // option or =
+                               strcpy( token_debug,token );
+
+                               if ( !strcmp( token,"=" ) ) {
+                                       UnGetToken();
+                                       break;
+                               }
+                               else
+                               {
+                                       strlower( token );
+                                       if ( !strcmp( token,"base" ) ) {
+                                               GetTokenExtra( false,"(",true ); // (
+
+                                               if ( !strcmp( token,"(" ) ) {
+                                                       while ( GetTokenExtra( false,",)",false ) ) // option) or option,
+                                                       {
+                                                               newclass->l_baselist = g_slist_append( newclass->l_baselist, strdup( token ) );
+
+                                                               GetTokenExtra( false,",)",true ); // , or )
+                                                               if ( !strcmp( token,")" ) ) {
+                                                                       break;
+                                                               }
+
+                                                       }
+                                               }
+                                       }
+                                       else if ( !strcmp( token,"size" ) ) {
+                                               // parse (w h d) or (x y z, x y z)
+
+                                               GetTokenExtra( false,"(",true ); // (
+                                               if ( !strcmp( token,"(" ) ) {
+                                                       int sizedone = false;
+                                                       float w,h,d;
+                                                       GetToken( false );
+                                                       w = atof( token );
+                                                       GetToken( false );
+                                                       h = atof( token );
+                                                       GetToken( false ); // number) or number ,
+                                                       strcpy( temp,token );
+                                                       len = strlen( temp );
+                                                       if ( temp[len - 1] == ')' ) {
+                                                               sizedone = true;
+                                                       }
+                                                       temp[len - 1] = 0;
+                                                       d = atof( temp );
+                                                       if ( sizedone ) {
+                                                               // only one set of cordinates supplied, change the W,H,D to mins/maxs
+                                                               newclass->boundingbox[0][0] = 0 - ( w / 2 );
+                                                               newclass->boundingbox[1][0] = w / 2;
+                                                               newclass->boundingbox[0][1] = 0 - ( h / 2 );
+                                                               newclass->boundingbox[1][1] = h / 2;
+                                                               newclass->boundingbox[0][2] = 0 - ( d / 2 );
+                                                               newclass->boundingbox[1][2] = d / 2;
+                                                               newclass->gotsize = true;
+                                                       }
+                                                       else
+                                                       {
+                                                               newclass->boundingbox[0][0] = w;
+                                                               newclass->boundingbox[0][1] = h;
+                                                               newclass->boundingbox[0][2] = d;
+                                                               GetToken( false );
+                                                               newclass->boundingbox[1][0] = atof( token );
+                                                               GetToken( false );
+                                                               newclass->boundingbox[1][1] = atof( token );
 /*
                 GetToken(false); // "number)" or "number )"
                 strcpy(temp,token);
                 len = strlen(temp);
-                if (temp[len-1] == ')') 
+                if (temp[len-1] == ')')
                   temp[len-1] = 0;
                 else
                   GetToken(false); // )
                 newclass->boundingbox[1][2] = atof(temp);
-*/
-                GetTokenExtra(false,")",false); // number
-                newclass->boundingbox[1][2] = atof(token);
-                newclass->gotsize = true;
-                GetTokenExtra(false,")",true); // )
-              }
-            }
-          }
-          else if (!strcmp(token,"color"))
-          {
-            GetTokenExtra(false,"(",true); // (
-            if (!strcmp(token,"("))
-            {
-              // get the color values (0-255) and normalize them if required.
-              GetToken(false);
-              newclass->color[0] = atof(token);
-              if (newclass->color[0] > 1)
-                newclass->color[0]/=255;
-              GetToken(false);
-              newclass->color[1] = atof(token);
-              if (newclass->color[1] > 1)
-                newclass->color[1]/=255;
-              GetToken(false);
-              strcpy(temp,token);
-              len = strlen(temp);
-              if (temp[len-1] == ')') temp[len-1] = 0;
-              newclass->color[2] = atof(temp);
-              if (newclass->color[2] > 1)
-                newclass->color[2]/=255;
-              newclass->gotcolor = true;
-            }
-          }
-          else if (!strcmp(token,"iconsprite"))
-          {
-            GetTokenExtra(false,"(",true); // (
-            if (!strcmp(token,"("))
-            {
-              GetTokenExtra(false,")",false); // filename)
-              // the model plugins will handle sprites too.
-              // newclass->sprite = strdup(token);
-              newclass->model = strdup(token);
-              GetTokenExtra(false,")",true); // )
-            }
-          }
-          else if (!strcmp(token,"model"))
-          {
-            GetTokenExtra(false,"(",true); // (
-            if (!strcmp(token,"("))
-            {
-              GetTokenExtra(false,")",false); // filename)
-              newclass->model = strdup(token);
-              GetTokenExtra(false,")",true); // )
-            }
-          }
-          else 
-          {
-            // Unsupported
-            GetToken(false); // skip it.
-          }
-
-        }
-      }
-
-      GetToken(false); // =
-      strcpy(token_debug,token);
-      if (!strcmp(token,"="))
-      {
-        GetToken(false);
-        newclass->classname = strdup(token);
-      }
-
-      // Get the description
-      if (newclass->classtype != CLASS_BASECLASS)
-      {
-        GetToken(false);
-        if (!strcmp(token,":"))
-        {
-          GetToken(false);
-          newclass->description = strdup(token);
-        } else UnGetToken(); // no description
-      }
-
-      // now build the option list.
-      GetToken(true); // [ or []
-
-      if (strcmp(token,"[]"))  // got some options ?
-      {
-        if (!strcmp(token,"["))
-        {
-          // yup
-          bool optioncomplete = false;
-          option_t *newoption;
-
-          while (1)
-          {
-            GetToken(true);
-            if (!strcmp(token,"]"))
-              break; // no more options
-
-            // parse the data and build the option_t
-
-            strcpy(temp,token);
-            len = strlen(temp);
-            char *ptr = strchr(temp,'(');
-
-            if (!ptr)
-                                     break;
-
-            newoption = (option_t *) malloc ( sizeof( option_s ));
-            memset( newoption, 0, sizeof( option_s ));
-
-            *ptr++ = 0;
-            newoption->epairname = strdup(temp);
-
-            len = strlen(ptr);
-            if (ptr[len-1] != ')')
-              break;
-
-            ptr[len-1] = 0;
-            strlower(ptr);
-            if (!strcmp(ptr,"integer"))
-            {
-              newoption->optiontype = OPTION_INTEGER;
-            }
-            else if (!strcmp(ptr,"choices"))
-            {
-              newoption->optiontype = OPTION_CHOICES;
-            }
-            else if (!strcmp(ptr,"flags"))
-            {
-              newoption->optiontype = OPTION_FLAGS;
-            }
-            else // string
-            {
-              newoption->optiontype = OPTION_STRING;
-            }
-
-            switch (newoption->optiontype)
-            {
-              case OPTION_STRING :
-              case OPTION_INTEGER :
-                if (!TokenAvailable())
-                {
-                  optioncomplete = true;
-                               break;
-               }
-                GetToken(false); // :
-                strcpy(token_debug,token);
-                if ((token[0] == ':') && (strlen(token) > 1))
-                {
-                  newoption->optioninfo = strdup(token+1);
-                }
-                else
-                {
-                  GetToken(false);
-                  newoption->optioninfo = strdup(token);
-                }
-                if (TokenAvailable()) // default value ?
-                {
-                  GetToken(false);
-                  if (!strcmp(token,":"))
-                  {
-                    if (GetToken(false))
-                    {
-                      newoption->optiondefault = strdup(token);
-                      optioncomplete = true;
-                    }
-                  }
-                }
-                else
-                {
-                  optioncomplete = true;
-                }
-                break;
-
-              case OPTION_CHOICES :
-                GetTokenExtra(false,":",true); // : or :"something like this" (bah!)
-                strcpy(token_debug,token);
-                if ((token[0] == ':') && (strlen(token) > 1))
-                {
-                  if (token[1] == '\"')
-                  {
-                    strcpy(temp,token+2);
-                    while (1)
-                    {
-                      if (!GetToken(false))
-                        break;
-                      strcat(temp," ");
-                      strcat(temp,token);
-                      len = strlen(temp);
-                      if (temp[len-1] == '\"')
-                      {
-                        temp[len-1] = 0;
-                        break;
-                      }
-                    }
-                  }
-                  newoption->optioninfo = strdup(temp);
-                }
-                else
-                {
-                  GetToken(false);
-                  newoption->optioninfo = strdup(token);
-                }
-                GetToken(false); // : or =
-                strcpy(token_debug,token);
-                if (!strcmp(token,":"))
-                {
-                  GetToken(false);
-                  newoption->optiondefault = strdup(token);
-                }
-                else
-                {
-                  UnGetToken();
-                }
-                // And Follow on...
-              case OPTION_FLAGS :
-                GetToken(false); // : or =
-                strcpy(token_debug,token);
-                if (strcmp(token,"=")) // missing ?
-                  break;
-
-                GetToken(true); // [
-                strcpy(token_debug,token);
-                if (strcmp(token,"[")) // missing ?
-                  break;
-
-                choice_t *newchoice;
-                while (1)
-                {
-                  GetTokenExtra(true,":",true); // "]" or "number", or "number:"
-                  strcpy(token_debug,token);
-                  if (!strcmp(token,"]")) // no more ?
-                  {
-                    optioncomplete = true;
-                    break;
-                  }
-                  strcpy(temp,token);
-                  len = strlen(temp);
-                  if (temp[len-1] == ':')
-                  {
-                    temp[len-1] = 0;
-                  }
-                  else
-                  {
-                    GetToken(false); // :
-                    if (strcmp(token,":")) // missing ?
-                      break;
-                  }
-                  if (!TokenAvailable())
-                    break;
-                  GetToken(false); // the name
-
-                  newchoice = (choice_t *) malloc ( sizeof( choice_s ));
-                  memset( newchoice, 0, sizeof( choice_s ));
-
-                  newchoice->value = atoi(temp);
-                  newchoice->name = strdup(token);
-
-                  newoption->choices = g_slist_append(newoption->choices, newchoice);
-
-                  // ignore any remaining tokens on the line
-                  while (TokenAvailable()) GetToken(false);
-
-                  // and it we found a "]" on the end of the line, put it back in the queue.
-                  if (!strcmp(token,"]")) UnGetToken();
-                }
-                               break;
-
-            }
+ */
+                                                               GetTokenExtra( false,")",false ); // number
+                                                               newclass->boundingbox[1][2] = atof( token );
+                                                               newclass->gotsize = true;
+                                                               GetTokenExtra( false,")",true ); // )
+                                                       }
+                                               }
+                                       }
+                                       else if ( !strcmp( token,"color" ) ) {
+                                               GetTokenExtra( false,"(",true ); // (
+                                               if ( !strcmp( token,"(" ) ) {
+                                                       // get the color values (0-255) and normalize them if required.
+                                                       GetToken( false );
+                                                       newclass->color[0] = atof( token );
+                                                       if ( newclass->color[0] > 1 ) {
+                                                               newclass->color[0] /= 255;
+                                                       }
+                                                       GetToken( false );
+                                                       newclass->color[1] = atof( token );
+                                                       if ( newclass->color[1] > 1 ) {
+                                                               newclass->color[1] /= 255;
+                                                       }
+                                                       GetToken( false );
+                                                       strcpy( temp,token );
+                                                       len = strlen( temp );
+                                                       if ( temp[len - 1] == ')' ) {
+                                                               temp[len - 1] = 0;
+                                                       }
+                                                       newclass->color[2] = atof( temp );
+                                                       if ( newclass->color[2] > 1 ) {
+                                                               newclass->color[2] /= 255;
+                                                       }
+                                                       newclass->gotcolor = true;
+                                               }
+                                       }
+                                       else if ( !strcmp( token,"iconsprite" ) ) {
+                                               GetTokenExtra( false,"(",true ); // (
+                                               if ( !strcmp( token,"(" ) ) {
+                                                       GetTokenExtra( false,")",false ); // filename)
+                                                       // the model plugins will handle sprites too.
+                                                       // newclass->sprite = strdup(token);
+                                                       newclass->model = strdup( token );
+                                                       GetTokenExtra( false,")",true ); // )
+                                               }
+                                       }
+                                       else if ( !strcmp( token,"model" ) ) {
+                                               GetTokenExtra( false,"(",true ); // (
+                                               if ( !strcmp( token,"(" ) ) {
+                                                       GetTokenExtra( false,")",false ); // filename)
+                                                       newclass->model = strdup( token );
+                                                       GetTokenExtra( false,")",true ); // )
+                                               }
+                                       }
+                                       else
+                                       {
+                                               // Unsupported
+                                               GetToken( false ); // skip it.
+                                       }
+
+                               }
+                       }
 
-            // add option to the newclass
+                       GetToken( false ); // =
+                       strcpy( token_debug,token );
+                       if ( !strcmp( token,"=" ) ) {
+                               GetToken( false );
+                               newclass->classname = strdup( token );
+                       }
 
-            if (optioncomplete)
-            {
-              if (newoption)
-              {
-                // add it to the list.
-                newclass->l_optionlist = g_slist_append(newclass->l_optionlist, newoption);
-              }
-            }
-            else
-            {
-              Sys_Printf ("%WARNING: Parse error occured in '%s - %s'\n",classnames[newclass->classtype],newclass->classname);
-              Free_Option(newoption);
-            }
+                       // Get the description
+                       if ( newclass->classtype != CLASS_BASECLASS ) {
+                               GetToken( false );
+                               if ( !strcmp( token,":" ) ) {
+                                       GetToken( false );
+                                       newclass->description = strdup( token );
+                               }
+                               else{ UnGetToken(); // no description
+                               }
+                       }
 
-          }
-        }
-        else
-        {
-          UnGetToken(); // shouldn't get here.
-        }
-      }
+                       // now build the option list.
+                       GetToken( true ); // [ or []
+
+                       if ( strcmp( token,"[]" ) ) { // got some options ?
+                               if ( !strcmp( token,"[" ) ) {
+                                       // yup
+                                       bool optioncomplete = false;
+                                       option_t *newoption;
+
+                                       while ( 1 )
+                                       {
+                                               GetToken( true );
+                                               if ( !strcmp( token,"]" ) ) {
+                                                       break; // no more options
+
+                                               }
+                                               // parse the data and build the option_t
+
+                                               strcpy( temp,token );
+                                               len = strlen( temp );
+                                               char *ptr = strchr( temp,'(' );
+
+                                               if ( !ptr ) {
+                                                       break;
+                                               }
+
+                                               newoption = (option_t *) malloc( sizeof( option_s ) );
+                                               memset( newoption, 0, sizeof( option_s ) );
+
+                                               *ptr++ = 0;
+                                               newoption->epairname = strdup( temp );
+
+                                               len = strlen( ptr );
+                                               if ( ptr[len - 1] != ')' ) {
+                                                       break;
+                                               }
+
+                                               ptr[len - 1] = 0;
+                                               strlower( ptr );
+                                               if ( !strcmp( ptr,"integer" ) ) {
+                                                       newoption->optiontype = OPTION_INTEGER;
+                                               }
+                                               else if ( !strcmp( ptr,"choices" ) ) {
+                                                       newoption->optiontype = OPTION_CHOICES;
+                                               }
+                                               else if ( !strcmp( ptr,"flags" ) ) {
+                                                       newoption->optiontype = OPTION_FLAGS;
+                                               }
+                                               else // string
+                                               {
+                                                       newoption->optiontype = OPTION_STRING;
+                                               }
+
+                                               switch ( newoption->optiontype )
+                                               {
+                                               case OPTION_STRING:
+                                               case OPTION_INTEGER:
+                                                       if ( !TokenAvailable() ) {
+                                                               optioncomplete = true;
+                                                               break;
+                                                       }
+                                                       GetToken( false ); // :
+                                                       strcpy( token_debug,token );
+                                                       if ( ( token[0] == ':' ) && ( strlen( token ) > 1 ) ) {
+                                                               newoption->optioninfo = strdup( token + 1 );
+                                                       }
+                                                       else
+                                                       {
+                                                               GetToken( false );
+                                                               newoption->optioninfo = strdup( token );
+                                                       }
+                                                       if ( TokenAvailable() ) { // default value ?
+                                                               GetToken( false );
+                                                               if ( !strcmp( token,":" ) ) {
+                                                                       if ( GetToken( false ) ) {
+                                                                               newoption->optiondefault = strdup( token );
+                                                                               optioncomplete = true;
+                                                                       }
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               optioncomplete = true;
+                                                       }
+                                                       break;
+
+                                               case OPTION_CHOICES:
+                                                       GetTokenExtra( false,":",true ); // : or :"something like this" (bah!)
+                                                       strcpy( token_debug,token );
+                                                       if ( ( token[0] == ':' ) && ( strlen( token ) > 1 ) ) {
+                                                               if ( token[1] == '\"' ) {
+                                                                       strcpy( temp,token + 2 );
+                                                                       while ( 1 )
+                                                                       {
+                                                                               if ( !GetToken( false ) ) {
+                                                                                       break;
+                                                                               }
+                                                                               strcat( temp," " );
+                                                                               strcat( temp,token );
+                                                                               len = strlen( temp );
+                                                                               if ( temp[len - 1] == '\"' ) {
+                                                                                       temp[len - 1] = 0;
+                                                                                       break;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               newoption->optioninfo = strdup( temp );
+                                                       }
+                                                       else
+                                                       {
+                                                               GetToken( false );
+                                                               newoption->optioninfo = strdup( token );
+                                                       }
+                                                       GetToken( false ); // : or =
+                                                       strcpy( token_debug,token );
+                                                       if ( !strcmp( token,":" ) ) {
+                                                               GetToken( false );
+                                                               newoption->optiondefault = strdup( token );
+                                                       }
+                                                       else
+                                                       {
+                                                               UnGetToken();
+                                                       }
+                                               // And Follow on...
+                                               case OPTION_FLAGS:
+                                                       GetToken( false ); // : or =
+                                                       strcpy( token_debug,token );
+                                                       if ( strcmp( token,"=" ) ) { // missing ?
+                                                               break;
+                                                       }
+
+                                                       GetToken( true ); // [
+                                                       strcpy( token_debug,token );
+                                                       if ( strcmp( token,"[" ) ) { // missing ?
+                                                               break;
+                                                       }
+
+                                                       choice_t *newchoice;
+                                                       while ( 1 )
+                                                       {
+                                                               GetTokenExtra( true,":",true ); // "]" or "number", or "number:"
+                                                               strcpy( token_debug,token );
+                                                               if ( !strcmp( token,"]" ) ) { // no more ?
+                                                                       optioncomplete = true;
+                                                                       break;
+                                                               }
+                                                               strcpy( temp,token );
+                                                               len = strlen( temp );
+                                                               if ( temp[len - 1] == ':' ) {
+                                                                       temp[len - 1] = 0;
+                                                               }
+                                                               else
+                                                               {
+                                                                       GetToken( false ); // :
+                                                                       if ( strcmp( token,":" ) ) { // missing ?
+                                                                               break;
+                                                                       }
+                                                               }
+                                                               if ( !TokenAvailable() ) {
+                                                                       break;
+                                                               }
+                                                               GetToken( false ); // the name
+
+                                                               newchoice = (choice_t *) malloc( sizeof( choice_s ) );
+                                                               memset( newchoice, 0, sizeof( choice_s ) );
+
+                                                               newchoice->value = atoi( temp );
+                                                               newchoice->name = strdup( token );
+
+                                                               newoption->choices = g_slist_append( newoption->choices, newchoice );
+
+                                                               // ignore any remaining tokens on the line
+                                                               while ( TokenAvailable() ) GetToken( false );
+
+                                                               // and it we found a "]" on the end of the line, put it back in the queue.
+                                                               if ( !strcmp( token,"]" ) ) {
+                                                                       UnGetToken();
+                                                               }
+                                                       }
+                                                       break;
+
+                                               }
+
+                                               // add option to the newclass
+
+                                               if ( optioncomplete ) {
+                                                       if ( newoption ) {
+                                                               // add it to the list.
+                                                               newclass->l_optionlist = g_slist_append( newclass->l_optionlist, newoption );
+                                                       }
+                                               }
+                                               else
+                                               {
+                                                       Sys_Printf( "%WARNING: Parse error occured in '%s - %s'\n",classnames[newclass->classtype],newclass->classname );
+                                                       Free_Option( newoption );
+                                               }
+
+                                       }
+                               }
+                               else
+                               {
+                                       UnGetToken(); // shouldn't get here.
+                               }
+                       }
 
-      // add it to our list.
-      l_classes = g_slist_append (l_classes, newclass);
+                       // add it to our list.
+                       l_classes = g_slist_append( l_classes, newclass );
 
-    }
-  }
+               }
+       }
 
-  // finished with the file now.
-  g_free(data);
+       // finished with the file now.
+       g_free( data );
 
-  Sys_Printf ("FGD scan complete, building entities...\n");
+       Sys_Printf( "FGD scan complete, building entities...\n" );
 
-  // Once we get here we should have a few (!) lists in memory that we
-  // can extract all the information required to build a the eclass_t structures.
+       // Once we get here we should have a few (!) lists in memory that we
+       // can extract all the information required to build a the eclass_t structures.
 
-  Create_EClasses(l_classes);
+       Create_EClasses( l_classes );
 
-  // Free everything
+       // Free everything
 
-  GSList *p = l_classes;
-  while (p)
-  {
-    class_t *tmpclass = (class_t *)p->data;
+       GSList *p = l_classes;
+       while ( p )
+       {
+               class_t *tmpclass = (class_t *)p->data;
 
 #ifdef FGD_VERBOSE
-    // DEBUG: dump the info...
-    Sys_Printf ("%s: %s (", classnames[tmpclass->classtype],tmpclass->classname);
-    for (GSList *tmp = tmpclass->l_baselist; tmp != NULL; tmp = tmp->next)
-    {
-      if (tmp != tmpclass->l_baselist)
-      {
-        Sys_Printf (", ");
-      }
-      Sys_Printf ("%s", (char *)tmp->data);
-    }
-    if (tmpclass->gotsize)
-    {
-      sprintf(temp,"(%.0f %.0f %.0f) - (%.0f %.0f %.0f)",tmpclass->boundingbox[0][0],
-        tmpclass->boundingbox[0][1],
-        tmpclass->boundingbox[0][2],
-        tmpclass->boundingbox[1][0],
-        tmpclass->boundingbox[1][1],
-        tmpclass->boundingbox[1][2]);
-    } else strcpy(temp,"No Size");
-    Sys_Printf (") '%s' Size: %s",tmpclass->description ? tmpclass->description : "No description",temp);
-    if (tmpclass->gotcolor)
-    {
-      sprintf(temp,"(%d %d %d)",tmpclass->color[0],
-        tmpclass->color[1],
-        tmpclass->color[2]);
-    } else strcpy(temp,"No Color");
-    Sys_Printf (" Color: %s Options:\n",temp);
-    if (!tmpclass->l_optionlist)
-    {
-      Sys_Printf ("  No Options\n");
-    }
-    else
-    {
-      option_t *tmpoption;
-      int count;
-      GSList *olst;
-      for (olst = tmpclass->l_optionlist, count = 1; olst != NULL; olst = olst->next, count ++)
-      {
-        tmpoption = (option_t *)olst->data;
-        Sys_Printf ("  %d, Type: %s, EPair: %s\n", count,optionnames[tmpoption->optiontype], tmpoption->epairname );
-
-        choice_t *tmpchoice;
-        GSList *clst;
-        int ccount;
-        for (clst = tmpoption->choices, ccount = 1; clst != NULL; clst = clst->next, ccount ++)
-        {
-          tmpchoice = (choice_t *)clst->data;
-          Sys_Printf ("    %d, Value: %d, Name: %s\n", ccount, tmpchoice->value, tmpchoice->name);
-        }
-      }
-    }
+               // DEBUG: dump the info...
+               Sys_Printf( "%s: %s (", classnames[tmpclass->classtype],tmpclass->classname );
+               for ( GSList *tmp = tmpclass->l_baselist; tmp != NULL; tmp = tmp->next )
+               {
+                       if ( tmp != tmpclass->l_baselist ) {
+                               Sys_Printf( ", " );
+                       }
+                       Sys_Printf( "%s", (char *)tmp->data );
+               }
+               if ( tmpclass->gotsize ) {
+                       sprintf( temp,"(%.0f %.0f %.0f) - (%.0f %.0f %.0f)",tmpclass->boundingbox[0][0],
+                                        tmpclass->boundingbox[0][1],
+                                        tmpclass->boundingbox[0][2],
+                                        tmpclass->boundingbox[1][0],
+                                        tmpclass->boundingbox[1][1],
+                                        tmpclass->boundingbox[1][2] );
+               }
+               else{ strcpy( temp,"No Size" ); }
+               Sys_Printf( ") '%s' Size: %s",tmpclass->description ? tmpclass->description : "No description",temp );
+               if ( tmpclass->gotcolor ) {
+                       sprintf( temp,"(%d %d %d)",tmpclass->color[0],
+                                        tmpclass->color[1],
+                                        tmpclass->color[2] );
+               }
+               else{ strcpy( temp,"No Color" ); }
+               Sys_Printf( " Color: %s Options:\n",temp );
+               if ( !tmpclass->l_optionlist ) {
+                       Sys_Printf( "  No Options\n" );
+               }
+               else
+               {
+                       option_t *tmpoption;
+                       int count;
+                       GSList *olst;
+                       for ( olst = tmpclass->l_optionlist, count = 1; olst != NULL; olst = olst->next, count++ )
+                       {
+                               tmpoption = (option_t *)olst->data;
+                               Sys_Printf( "  %d, Type: %s, EPair: %s\n", count,optionnames[tmpoption->optiontype], tmpoption->epairname );
+
+                               choice_t *tmpchoice;
+                               GSList *clst;
+                               int ccount;
+                               for ( clst = tmpoption->choices, ccount = 1; clst != NULL; clst = clst->next, ccount++ )
+                               {
+                                       tmpchoice = (choice_t *)clst->data;
+                                       Sys_Printf( "    %d, Value: %d, Name: %s\n", ccount, tmpchoice->value, tmpchoice->name );
+                               }
+                       }
+               }
 
 #endif
 
-    // free the baselist.
-    ClearGSList(tmpclass->l_baselist);
-    Free_Class (tmpclass);
-    p = g_slist_remove (p, p->data);
-               }
-               
+               // free the baselist.
+               ClearGSList( tmpclass->l_baselist );
+               Free_Class( tmpclass );
+               p = g_slist_remove( p, p->data );
+       }
+
 }