NOW I do it right: #woxblox#
[divverent/netradiant.git] / libs / eclasslib.h
1 /*
2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined (INCLUDED_ECLASSLIB_H)
23 #define INCLUDED_ECLASSLIB_H
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <list>
28 #include <map>
29 #include <vector>
30
31 #include "ieclass.h"
32 #include "irender.h"
33
34 #include "math/vector.h"
35 #include "string/string.h"
36
37 typedef Vector3 Colour3;
38
39 class ListAttributeType
40 {
41   typedef std::pair<CopiedString, CopiedString> ListItem;
42   typedef std::vector<ListItem> ListItems;
43   ListItems m_items;
44 public:
45
46   typedef ListItems::const_iterator const_iterator;
47   const_iterator begin() const
48   {
49     return m_items.begin();
50   }
51   const_iterator end() const
52   {
53     return m_items.end();
54   }
55
56   const ListItem& operator[](std::size_t i) const
57   {
58     return m_items[i];
59   }
60   const_iterator findValue(const char* value) const
61   {
62     for(ListItems::const_iterator i = m_items.begin(); i != m_items.end(); ++i)
63     {
64       if(string_equal(value, (*i).second.c_str()))
65       {
66         return i;
67       }
68     }
69     return m_items.end();
70   }
71
72   void push_back(const char* name, const char* value)
73   {
74     m_items.push_back(ListItems::value_type(name, value));
75   }
76 };
77
78 class EntityClassAttribute
79 {
80 public:
81   CopiedString m_type;
82   CopiedString m_name;
83   CopiedString m_value;
84   CopiedString m_description;
85   EntityClassAttribute()
86   {
87   }
88   EntityClassAttribute(const char* type, const char* name, const char* value = "", const char* description = "") : m_type(type), m_name(name), m_value(value), m_description(description)
89   {
90   }
91 };
92
93 typedef std::pair<CopiedString, EntityClassAttribute> EntityClassAttributePair;
94 typedef std::list<EntityClassAttributePair> EntityClassAttributes;
95 typedef std::list<CopiedString> StringList;
96
97 inline const char* EntityClassAttributePair_getName(const EntityClassAttributePair& attributePair)
98 {
99   if(!string_empty(attributePair.second.m_name.c_str()))
100   {
101     return attributePair.second.m_name.c_str();
102   }
103   return attributePair.first.c_str();
104 }
105
106 inline const char* EntityClassAttributePair_getDescription(const EntityClassAttributePair& attributePair)
107 {
108   if(!string_empty(attributePair.second.m_description.c_str()))
109   {
110     return attributePair.second.m_description.c_str();
111   }
112   return EntityClassAttributePair_getName(attributePair);
113 }
114
115 class EntityClass
116 {
117 public:
118         CopiedString m_name;
119   StringList m_parent;
120         bool    fixedsize;
121         bool    unknown;                // wasn't found in source
122         Vector3 mins;
123   Vector3 maxs;
124
125         Colour3 color;
126   Shader* m_state_fill;
127   Shader* m_state_wire;
128   Shader* m_state_blend;
129
130         CopiedString m_comments;
131         char    flagnames[MAX_FLAGS][32];
132
133   CopiedString m_modelpath;
134   CopiedString m_skin;
135
136   void (*free)(EntityClass*);
137
138   EntityClassAttributes m_attributes;
139
140   bool inheritanceResolved;
141   bool sizeSpecified;
142   bool colorSpecified;
143
144   const char* name() const
145   {
146     return m_name.c_str();
147   }
148   const char* comments() const
149   {
150     return m_comments.c_str();
151   }
152   const char* modelpath() const
153   {
154     return m_modelpath.c_str();
155   }
156   const char* skin() const
157   {
158     return m_skin.c_str();
159   }
160 };
161
162 inline const char* EntityClass_valueForKey(const EntityClass& entityClass, const char* key)
163 {
164   for(EntityClassAttributes::const_iterator i = entityClass.m_attributes.begin(); i != entityClass.m_attributes.end(); ++i)
165   {
166     if(string_equal(key, (*i).first.c_str()))
167     {
168       return (*i).second.m_value.c_str();
169     }
170   }
171   return "";
172 }
173
174 inline EntityClassAttributePair& EntityClass_insertAttribute(EntityClass& entityClass, const char* key, const EntityClassAttribute& attribute = EntityClassAttribute())
175 {
176   entityClass.m_attributes.push_back(EntityClassAttributePair(key, attribute));
177   return entityClass.m_attributes.back();
178 }
179
180
181 inline void buffer_write_colour_fill(char buffer[128], const Colour3& colour)
182 {
183   sprintf(buffer, "(%g %g %g)", colour[0], colour[1], colour[2]);
184 }
185
186 inline void buffer_write_colour_wire(char buffer[128], const Colour3& colour)
187 {
188   sprintf(buffer, "<%g %g %g>", colour[0], colour[1], colour[2]);
189 }
190
191 inline void buffer_write_colour_blend(char buffer[128], const Colour3& colour)
192 {
193   sprintf(buffer, "[%g %g %g]", colour[0], colour[1], colour[2]);
194 }
195
196 inline Shader* colour_capture_state_fill(const Colour3& colour)
197 {
198   char buffer[128];
199   buffer_write_colour_fill(buffer, colour);
200   return GlobalShaderCache().capture(buffer);
201 }
202
203 inline void colour_release_state_fill(const Colour3& colour)
204 {
205   char buffer[128];
206   buffer_write_colour_fill(buffer, colour);
207   GlobalShaderCache().release(buffer);
208 }
209
210 inline Shader* colour_capture_state_wire(const Colour3& colour)
211 {
212   char buffer[128];
213   buffer_write_colour_wire(buffer, colour);
214   return GlobalShaderCache().capture(buffer);
215 }
216
217 inline void colour_release_state_wire(const Colour3& colour)
218 {
219   char buffer[128];
220   buffer_write_colour_wire(buffer, colour);
221   GlobalShaderCache().release(buffer);
222 }
223
224 inline Shader* colour_capture_state_blend(const Colour3& colour)
225 {
226   char buffer[128];
227   buffer_write_colour_blend(buffer, colour);
228   return GlobalShaderCache().capture(buffer);
229 }
230
231 inline void colour_release_state_blend(const Colour3& colour)
232 {
233   char buffer[128];
234   buffer_write_colour_blend(buffer, colour);
235   GlobalShaderCache().release(buffer);
236 }
237
238 inline void eclass_capture_state(EntityClass* eclass)
239 {
240   eclass->m_state_fill = colour_capture_state_fill(eclass->color);
241   eclass->m_state_wire = colour_capture_state_wire(eclass->color);
242   eclass->m_state_blend = colour_capture_state_blend(eclass->color);
243 }
244
245 inline void eclass_release_state(EntityClass* eclass)
246 {
247   colour_release_state_fill(eclass->color);
248   colour_release_state_wire(eclass->color);
249   colour_release_state_blend(eclass->color);
250 }
251
252 // eclass constructor
253 inline EntityClass* Eclass_Alloc()
254 {
255   EntityClass* e = new EntityClass;
256
257   e->fixedsize = false;
258   e->unknown = false;
259   memset(e->flagnames, 0, MAX_FLAGS*32);
260
261   e->maxs = Vector3(-1,-1,-1);
262   e->mins = Vector3(1, 1, 1);
263
264   e->free = 0;
265
266   e->inheritanceResolved = true;
267   e->sizeSpecified = false;
268   e->colorSpecified = false;
269
270   return e;
271 }
272
273 // eclass destructor
274 inline void Eclass_Free(EntityClass* e)
275 {
276   eclass_release_state(e);
277
278   delete e;
279 }
280
281 inline bool classname_equal(const char* classname, const char* other)
282 {
283   return string_equal(classname, other);
284 }
285
286 inline EntityClass* EClass_Create(const char* name, const Vector3& colour, const char* comments)
287 {
288   EntityClass *e = Eclass_Alloc();
289   e->free = &Eclass_Free;
290
291   e->m_name = name;
292
293         e->color = colour;
294   eclass_capture_state(e);
295
296   if (comments)
297     e->m_comments = comments;
298
299   return e;
300 }
301
302 inline EntityClass* EClass_Create_FixedSize(const char* name, const Vector3& colour, const Vector3& mins, const Vector3& maxs, const char* comments)
303 {
304   EntityClass *e = Eclass_Alloc();
305   e->free = &Eclass_Free;
306
307   e->m_name = name;
308
309         e->color = colour;
310   eclass_capture_state(e);
311
312   e->fixedsize = true;
313
314   e->mins = mins;
315   e->maxs = maxs;
316
317   if (comments)
318     e->m_comments = comments;
319
320   return e;
321 }
322
323 const Vector3 smallbox[2] = {
324   Vector3(-8,-8,-8),
325   Vector3( 8, 8, 8),
326 };
327
328 inline EntityClass *EntityClass_Create_Default(const char *name, bool has_brushes)
329 {
330         // create a new class for it
331         if (has_brushes)
332         {
333     return EClass_Create(name, Vector3(0.0f, 0.5f, 0.0f), "Not found in source.");
334         }
335         else
336         {
337     return EClass_Create_FixedSize(name, Vector3(0.0f, 0.5f, 0.0f), smallbox[0], smallbox[1], "Not found in source.");
338         }
339 }
340
341 #endif