more eol-style
[xonotic/netradiant.git] / plugins / entity / entity.cpp
index 9da72ce473171b94b14f408ac904628d384eeb99..28faf4257b975714c7a7dc4aaa616c6bb3850c9d 100644 (file)
-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
-*/\r
-\r
-#include "plugin.h"\r
-#include "entity.h"\r
-#include "entity_entitymodel.h"\r
-#include "light.h"\r
-\r
-int g_entityId = 1;\r
-\r
-\r
-\r
-// internal\r
-\r
-static void Entity_FreeEpairs(entity_t *e);\r
-\r
-static void SetKeyValue (epair_t *&e, const char *key, const char *value);\r
-static void  DeleteKey (epair_t *&e, const char *key);\r
-static const char *ValueForKey ( epair_t *&e, const char *key);\r
-\r
-static void Entity_OnKeyValueChanged(entity_t *e, const char* key, const char* value);\r
-\r
-// constructor\r
-entity_t *Entity_Alloc()\r
-{\r
-  entity_t *e;\r
-       e = (entity_t*)malloc (sizeof(*e));\r
-       e->entityId = g_entityId++;\r
-  VectorSet(e->origin, 0, 0, 0);\r
-  VectorSet(e->color, 1, 1, 1);\r
-  e->redoId = 0;\r
-  e->undoId = 0;\r
-  e->next = e->prev = NULL;\r
-       e->brushes.onext = e->brushes.oprev = &e->brushes;\r
-  e->epairs = NULL;\r
-  e->eclass = NULL;\r
-  e->model.pRender = NULL;\r
-  e->model.pSelect = NULL;\r
-  e->model.pEdit = NULL;\r
-  return e;\r
-}\r
-\r
-// destructor\r
-void Entity_Free (entity_t *e)\r
-{\r
-       while (e->brushes.onext != &e->brushes)\r
-               Brush_Free( e->brushes.onext, true );\r
-\r
-       if (e->next)\r
-       {\r
-               e->next->prev = e->prev;\r
-               e->prev->next = e->next;\r
-       }\r
-\r
-       Entity_FreeEpairs(e);\r
-\r
-  if (e->model.pRender)\r
-  {\r
-    e->model.pRender->DecRef();\r
-    e->model.pRender = NULL;\r
-  }\r
-  if (e->model.pSelect)\r
-  {\r
-    e->model.pSelect->DecRef();\r
-    e->model.pSelect = NULL;\r
-  }\r
-  if (e->model.pEdit)\r
-  {\r
-    e->model.pEdit->DecRef();\r
-    e->model.pEdit = NULL;\r
-  }\r
-\r
-       free (e);\r
-}\r
-\r
-// construct from entity\r
-entity_t       *Entity_Clone (entity_t *e)\r
-{\r
-       entity_t        *n;\r
-       epair_t         *ep;\r
-\r
-       n = Entity_Alloc();\r
-       n->eclass = e->eclass;\r
-\r
-       for (ep = e->epairs ; ep ; ep=ep->next)\r
-    SetKeyValue(n, ep->key, ep->value);\r
-\r
-       // copy some misc stuff as well\r
-       VectorCopy( e->origin, n->origin );\r
-//     VectorCopy( e->vRotation, n->vRotation );\r
-//     VectorCopy( e->vScale, n->vScale );\r
-\r
-//  n->bDirty = true;\r
-\r
-       return n;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-const char *ValueForKey ( epair_t *&e, const char *key)\r
-{\r
-  epair_t *ep;\r
-  for (ep=e ; ep ; ep=ep->next)\r
-  {\r
-               if (!strcmp (ep->key, key) )\r
-    {\r
-      return ep->value;\r
-    }\r
-  }\r
-  return "";\r
-}\r
-\r
-const char *ValueForKey (entity_t *ent, const char *key)\r
-{\r
-  return ValueForKey(ent->epairs, key);\r
-}\r
-\r
-void   SetKeyValue (epair_t *&e, const char *key, const char *value)\r
-{\r
-       epair_t *ep;\r
-  for (ep=e ; ep ; ep=ep->next)\r
-  {\r
-               if (!strcmp (ep->key, key) )\r
-               {\r
-                       free (ep->value);\r
-                       ep->value = (char*)malloc(strlen(value)+1);\r
-                       strcpy (ep->value, value);\r
-                       return;\r
-               }\r
-  }\r
-       ep = (epair_t*)malloc (sizeof(*ep));\r
-       ep->next = e;\r
-       e = ep;\r
-       ep->key = (char*)malloc(strlen(key)+1);\r
-       strcpy (ep->key, key);\r
-       ep->value = (char*)malloc(strlen(value)+1);\r
-       strcpy (ep->value, value);\r
-\r
-}\r
-\r
-void SetKeyValue (entity_t *ent, const char *key, const char *value)\r
-{\r
-       if (ent == NULL)\r
-  {\r
-    Sys_FPrintf(SYS_ERR, "ERROR: SetKeyValue: NULL entity \n");\r
-               return;\r
-  }\r
-\r
-       if (!key || !key[0])\r
-  {\r
-    Sys_FPrintf(SYS_ERR, "ERROR: SetKeyValue: NULL or zero-length key\n");\r
-               return;\r
-  }\r
-\r
-  SetKeyValue(ent->epairs, key, value);\r
-  /*!\r
-  \todo TODO broadcast this through a clean messaging API ;-)\r
-  */\r
-  Entity_OnKeyValueChanged(ent, key, value);\r
-}\r
-\r
-void   DeleteKey (epair_t *&e, const char *key)\r
-{\r
-       epair_t **ep, *next;\r
-       \r
-       ep = &e;\r
-       while (*ep)\r
-       {\r
-               next = *ep;\r
-               if ( !strcmp (next->key, key) )\r
-               {\r
-                       *ep = next->next;\r
-                       free(next->key);\r
-                       free(next->value);\r
-                       free(next);\r
-                       return;\r
-               }\r
-               ep = &next->next;\r
-       }\r
-}\r
-\r
-void   DeleteKey (entity_t *ent, const char *key)\r
-{\r
-  DeleteKey(ent->epairs, key);\r
-  Entity_OnKeyValueChanged(ent, key, "");\r
-}\r
-\r
-float  FloatForKey (entity_t *ent, const char *key)\r
-{\r
-       const char      *k;\r
-       \r
-       k = ValueForKey (ent, key);\r
-       return (float) atof(k);\r
-}\r
-\r
-int IntForKey (entity_t *ent, const char *key)\r
-{\r
-       const char      *k;\r
-       \r
-       k = ValueForKey (ent, key);\r
-       return atoi(k);\r
-}\r
-\r
-void   GetVectorForKey (entity_t *ent, const char *key, vec3_t vec)\r
-{\r
-       const char      *k;\r
-       \r
-       k = ValueForKey (ent, key);\r
-       sscanf (k, "%f %f %f", &vec[0], &vec[1], &vec[2]);\r
-}\r
-\r
-/*\r
-===============\r
-Entity_FreeEpairs\r
-\r
-Frees the entity epairs.\r
-===============\r
-*/\r
-void Entity_FreeEpairs(entity_t *e)\r
-{\r
-       epair_t *ep, *next;\r
-\r
-       for (ep = e->epairs; ep; ep = next)\r
-       {\r
-               next = ep->next;\r
-               free (ep->key);\r
-               free (ep->value);\r
-               free (ep);\r
-       }\r
-       e->epairs = NULL;\r
-}\r
-\r
-void Entity_AddToList(entity_t *e, entity_t *elist)\r
-{\r
-       if (e->next || e->prev)\r
-               Error ("Entity_AddToList: already linked");\r
-       //e->next = elist->next;\r
-       //elist->next->prev = e;\r
-       //elist->next = e;\r
-       //e->prev = elist;\r
-       e->next = elist;\r
-       e->prev = elist->prev;\r
-       elist->prev->next = e;\r
-       elist->prev = e;\r
-}\r
-\r
-void Entity_RemoveFromList (entity_t *e)\r
-{\r
-       if (!e->next || !e->prev)\r
-               Error ("Entity_RemoveFromList: not linked");\r
-       e->next->prev = e->prev;\r
-       e->prev->next = e->next;\r
-       e->next = e->prev = NULL;\r
-}\r
-\r
-void Entity_LinkBrush (entity_t *e, brush_t *b)\r
-{\r
-       if (b->oprev || b->onext)\r
-               Error ("Entity_LinkBrush: Already linked");\r
-       b->owner = e;\r
-\r
-//     b->onext = e->brushes.onext;\r
-//     b->oprev = &e->brushes;\r
-//     e->brushes.onext->oprev = b;\r
-//     e->brushes.onext = b;\r
-  /*\r
-  SPoG - changed to add brushes to end of list instead of start - so this can be used by map loader.\r
-  This could concievably cause a problem if someone is traversing e->brushes while calling this function.\r
-  So don't.\r
-  */\r
-  b->onext = &e->brushes;\r
-       b->oprev = e->brushes.oprev;\r
-       e->brushes.oprev->onext = b;\r
-       e->brushes.oprev = b;\r
-}\r
-\r
-void Entity_UnlinkBrush (brush_t *b)\r
-{\r
-       if (!b->onext || !b->oprev)\r
-               Error ("Entity_UnlinkBrush: Not currently linked");\r
-       b->onext->oprev = b->oprev;\r
-       b->oprev->onext = b->onext;\r
-       b->onext = b->oprev = NULL;\r
-       b->owner = NULL;\r
-}\r
-\r
-// for undo\r
-int Entity_MemorySize(entity_t *e)\r
-{\r
-       epair_t *ep;\r
-       int size = 0;\r
-\r
-       for (ep = e->epairs; ep; ep = ep->next)\r
-       {\r
-    size += strlen(ep->key);\r
-    size += strlen(ep->value);\r
-    size += sizeof(epair_t);\r
-       }\r
-  size += sizeof(entity_t);\r
-       return size;\r
-}\r
-\r
-epair_t* Entity_AllocateEpair(const char *key, const char *value)\r
-{\r
-  epair_t *ep = (epair_t*)malloc (sizeof(*ep));\r
-  ep->key = (char*)malloc(strlen(key)+1);\r
-  strcpy (ep->key, key);\r
-  ep->value = (char*)malloc(strlen(value)+1);\r
-  strcpy (ep->value, value);\r
-  ep->next = NULL;\r
-  return ep;\r
-}\r
-\r
-epair_t** Entity_GetKeyValList(entity_t *e)\r
-{\r
-  return &e->epairs;\r
-}\r
-\r
-void Entity_SetKeyValList(entity_t *e, epair_t* ep)\r
-{\r
-  if( e->epairs )\r
-    Sys_Printf( "Warning : pe->epairs != NULL in Entity_SetKeyValList, will not set\n" );\r
-  else {\r
-    e->epairs = ep;\r
-\r
-    for (epair_t *pe_ep = e->epairs; pe_ep; pe_ep = pe_ep->next)\r
-      Entity_OnKeyValueChanged(e, pe_ep->key, pe_ep->value);\r
-  }\r
-}\r
-\r
-\r
-/*!\r
-\todo FIXME TTimo\r
-this is meant to raise messages instead of calling the IEdit directly\r
-*/\r
-static void Entity_OnKeyValueChanged(entity_t *e, const char *key, const char* value)\r
-{\r
-  if(strcmp(key,"classname") == 0)\r
-  {\r
-    e->eclass = Eclass_ForName(value, false);\r
-    Entity_UpdateClass(e, value);\r
-    if(strcmp(value,"light") == 0)\r
-      for(epair_t* ep = e->epairs; ep != NULL; ep=ep->next)\r
-        Light_OnKeyValueChanged(e, ep->key, ep->value);\r
-    if(e->model.pEdit)\r
-      for(epair_t* ep = e->epairs; ep != NULL; ep=ep->next)\r
-        e->model.pEdit->OnKeyValueChanged(e, ep->key, ep->value);\r
-  }\r
-  else if(Entity_IsLight(e))\r
-    Light_OnKeyValueChanged(e, key, value);\r
-  else if(e->model.pEdit)\r
-    e->model.pEdit->OnKeyValueChanged(e, key, value);\r
-\r
-  // update brush mins/maxs for legacy culling system\r
-  if(e->model.pRender && e->brushes.onext != &e->brushes)\r
-    Brush_Build( e->brushes.onext, true, true, false, true );\r
-}\r
+/*
+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.
+
+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.
+
+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
+*/
+
+#include "plugin.h"
+#include "entity.h"
+#include "entity_entitymodel.h"
+#include "light.h"
+
+int g_entityId = 1;
+
+
+
+// internal
+
+static void Entity_FreeEpairs(entity_t *e);
+
+static void SetKeyValue (epair_t *&e, const char *key, const char *value);
+static void  DeleteKey (epair_t *&e, const char *key);
+static const char *ValueForKey ( epair_t *&e, const char *key);
+
+static void Entity_OnKeyValueChanged(entity_t *e, const char* key, const char* value);
+
+// constructor
+entity_t *Entity_Alloc()
+{
+  entity_t *e;
+       e = (entity_t*)malloc (sizeof(*e));
+       e->entityId = g_entityId++;
+  VectorSet(e->origin, 0, 0, 0);
+  VectorSet(e->color, 1, 1, 1);
+  e->redoId = 0;
+  e->undoId = 0;
+  e->next = e->prev = NULL;
+       e->brushes.onext = e->brushes.oprev = &e->brushes;
+  e->epairs = NULL;
+  e->eclass = NULL;
+  e->model.pRender = NULL;
+  e->model.pSelect = NULL;
+  e->model.pEdit = NULL;
+  return e;
+}
+
+// destructor
+void Entity_Free (entity_t *e)
+{
+       while (e->brushes.onext != &e->brushes)
+               Brush_Free( e->brushes.onext, true );
+
+       if (e->next)
+       {
+               e->next->prev = e->prev;
+               e->prev->next = e->next;
+       }
+
+       Entity_FreeEpairs(e);
+
+  if (e->model.pRender)
+  {
+    e->model.pRender->DecRef();
+    e->model.pRender = NULL;
+  }
+  if (e->model.pSelect)
+  {
+    e->model.pSelect->DecRef();
+    e->model.pSelect = NULL;
+  }
+  if (e->model.pEdit)
+  {
+    e->model.pEdit->DecRef();
+    e->model.pEdit = NULL;
+  }
+
+       free (e);
+}
+
+// construct from entity
+entity_t       *Entity_Clone (entity_t *e)
+{
+       entity_t        *n;
+       epair_t         *ep;
+
+       n = Entity_Alloc();
+       n->eclass = e->eclass;
+
+       for (ep = e->epairs ; ep ; ep=ep->next)
+    SetKeyValue(n, ep->key, ep->value);
+
+       // copy some misc stuff as well
+       VectorCopy( e->origin, n->origin );
+//     VectorCopy( e->vRotation, n->vRotation );
+//     VectorCopy( e->vScale, n->vScale );
+
+//  n->bDirty = true;
+
+       return n;
+}
+
+
+
+
+
+const char *ValueForKey ( epair_t *&e, const char *key)
+{
+  epair_t *ep;
+  for (ep=e ; ep ; ep=ep->next)
+  {
+               if (!strcmp (ep->key, key) )
+    {
+      return ep->value;
+    }
+  }
+  return "";
+}
+
+const char *ValueForKey (entity_t *ent, const char *key)
+{
+  return ValueForKey(ent->epairs, key);
+}
+
+void   SetKeyValue (epair_t *&e, const char *key, const char *value)
+{
+       epair_t *ep;
+  for (ep=e ; ep ; ep=ep->next)
+  {
+               if (!strcmp (ep->key, key) )
+               {
+                       free (ep->value);
+                       ep->value = (char*)malloc(strlen(value)+1);
+                       strcpy (ep->value, value);
+                       return;
+               }
+  }
+       ep = (epair_t*)malloc (sizeof(*ep));
+       ep->next = e;
+       e = ep;
+       ep->key = (char*)malloc(strlen(key)+1);
+       strcpy (ep->key, key);
+       ep->value = (char*)malloc(strlen(value)+1);
+       strcpy (ep->value, value);
+
+}
+
+void SetKeyValue (entity_t *ent, const char *key, const char *value)
+{
+       if (ent == NULL)
+  {
+    Sys_FPrintf(SYS_ERR, "ERROR: SetKeyValue: NULL entity \n");
+               return;
+  }
+
+       if (!key || !key[0])
+  {
+    Sys_FPrintf(SYS_ERR, "ERROR: SetKeyValue: NULL or zero-length key\n");
+               return;
+  }
+
+  SetKeyValue(ent->epairs, key, value);
+  /*!
+  \todo TODO broadcast this through a clean messaging API ;-)
+  */
+  Entity_OnKeyValueChanged(ent, key, value);
+}
+
+void   DeleteKey (epair_t *&e, const char *key)
+{
+       epair_t **ep, *next;
+       
+       ep = &e;
+       while (*ep)
+       {
+               next = *ep;
+               if ( !strcmp (next->key, key) )
+               {
+                       *ep = next->next;
+                       free(next->key);
+                       free(next->value);
+                       free(next);
+                       return;
+               }
+               ep = &next->next;
+       }
+}
+
+void   DeleteKey (entity_t *ent, const char *key)
+{
+  DeleteKey(ent->epairs, key);
+  Entity_OnKeyValueChanged(ent, key, "");
+}
+
+float  FloatForKey (entity_t *ent, const char *key)
+{
+       const char      *k;
+       
+       k = ValueForKey (ent, key);
+       return (float) atof(k);
+}
+
+int IntForKey (entity_t *ent, const char *key)
+{
+       const char      *k;
+       
+       k = ValueForKey (ent, key);
+       return atoi(k);
+}
+
+void   GetVectorForKey (entity_t *ent, const char *key, vec3_t vec)
+{
+       const char      *k;
+       
+       k = ValueForKey (ent, key);
+       sscanf (k, "%f %f %f", &vec[0], &vec[1], &vec[2]);
+}
+
+/*
+===============
+Entity_FreeEpairs
+
+Frees the entity epairs.
+===============
+*/
+void Entity_FreeEpairs(entity_t *e)
+{
+       epair_t *ep, *next;
+
+       for (ep = e->epairs; ep; ep = next)
+       {
+               next = ep->next;
+               free (ep->key);
+               free (ep->value);
+               free (ep);
+       }
+       e->epairs = NULL;
+}
+
+void Entity_AddToList(entity_t *e, entity_t *elist)
+{
+       if (e->next || e->prev)
+               Error ("Entity_AddToList: already linked");
+       //e->next = elist->next;
+       //elist->next->prev = e;
+       //elist->next = e;
+       //e->prev = elist;
+       e->next = elist;
+       e->prev = elist->prev;
+       elist->prev->next = e;
+       elist->prev = e;
+}
+
+void Entity_RemoveFromList (entity_t *e)
+{
+       if (!e->next || !e->prev)
+               Error ("Entity_RemoveFromList: not linked");
+       e->next->prev = e->prev;
+       e->prev->next = e->next;
+       e->next = e->prev = NULL;
+}
+
+void Entity_LinkBrush (entity_t *e, brush_t *b)
+{
+       if (b->oprev || b->onext)
+               Error ("Entity_LinkBrush: Already linked");
+       b->owner = e;
+
+//     b->onext = e->brushes.onext;
+//     b->oprev = &e->brushes;
+//     e->brushes.onext->oprev = b;
+//     e->brushes.onext = b;
+  /*
+  SPoG - changed to add brushes to end of list instead of start - so this can be used by map loader.
+  This could concievably cause a problem if someone is traversing e->brushes while calling this function.
+  So don't.
+  */
+  b->onext = &e->brushes;
+       b->oprev = e->brushes.oprev;
+       e->brushes.oprev->onext = b;
+       e->brushes.oprev = b;
+}
+
+void Entity_UnlinkBrush (brush_t *b)
+{
+       if (!b->onext || !b->oprev)
+               Error ("Entity_UnlinkBrush: Not currently linked");
+       b->onext->oprev = b->oprev;
+       b->oprev->onext = b->onext;
+       b->onext = b->oprev = NULL;
+       b->owner = NULL;
+}
+
+// for undo
+int Entity_MemorySize(entity_t *e)
+{
+       epair_t *ep;
+       int size = 0;
+
+       for (ep = e->epairs; ep; ep = ep->next)
+       {
+    size += strlen(ep->key);
+    size += strlen(ep->value);
+    size += sizeof(epair_t);
+       }
+  size += sizeof(entity_t);
+       return size;
+}
+
+epair_t* Entity_AllocateEpair(const char *key, const char *value)
+{
+  epair_t *ep = (epair_t*)malloc (sizeof(*ep));
+  ep->key = (char*)malloc(strlen(key)+1);
+  strcpy (ep->key, key);
+  ep->value = (char*)malloc(strlen(value)+1);
+  strcpy (ep->value, value);
+  ep->next = NULL;
+  return ep;
+}
+
+epair_t** Entity_GetKeyValList(entity_t *e)
+{
+  return &e->epairs;
+}
+
+void Entity_SetKeyValList(entity_t *e, epair_t* ep)
+{
+  if( e->epairs )
+    Sys_Printf( "Warning : pe->epairs != NULL in Entity_SetKeyValList, will not set\n" );
+  else {
+    e->epairs = ep;
+
+    for (epair_t *pe_ep = e->epairs; pe_ep; pe_ep = pe_ep->next)
+      Entity_OnKeyValueChanged(e, pe_ep->key, pe_ep->value);
+  }
+}
+
+
+/*!
+\todo FIXME TTimo
+this is meant to raise messages instead of calling the IEdit directly
+*/
+static void Entity_OnKeyValueChanged(entity_t *e, const char *key, const char* value)
+{
+  if(strcmp(key,"classname") == 0)
+  {
+    e->eclass = Eclass_ForName(value, false);
+    Entity_UpdateClass(e, value);
+    if(strcmp(value,"light") == 0)
+      for(epair_t* ep = e->epairs; ep != NULL; ep=ep->next)
+        Light_OnKeyValueChanged(e, ep->key, ep->value);
+    if(e->model.pEdit)
+      for(epair_t* ep = e->epairs; ep != NULL; ep=ep->next)
+        e->model.pEdit->OnKeyValueChanged(e, ep->key, ep->value);
+  }
+  else if(Entity_IsLight(e))
+    Light_OnKeyValueChanged(e, key, value);
+  else if(e->model.pEdit)
+    e->model.pEdit->OnKeyValueChanged(e, key, value);
+
+  // update brush mins/maxs for legacy culling system
+  if(e->model.pRender && e->brushes.onext != &e->brushes)
+    Brush_Build( e->brushes.onext, true, true, false, true );
+}