Fix MSYS2 issues
[xonotic/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         return m_items.begin();
49 }
50 const_iterator end() const {
51         return m_items.end();
52 }
53
54 const ListItem& operator[]( std::size_t i ) const {
55         return m_items[i];
56 }
57 const_iterator findValue( const char* value ) const {
58         for ( ListItems::const_iterator i = m_items.begin(); i != m_items.end(); ++i )
59         {
60                 if ( string_equal( value, ( *i ).second.c_str() ) ) {
61                         return i;
62                 }
63         }
64         return m_items.end();
65 }
66
67 void push_back( const char* name, const char* value ){
68         m_items.push_back( ListItems::value_type( name, value ) );
69 }
70 };
71
72 class EntityClassAttribute
73 {
74 public:
75 CopiedString m_type;
76 CopiedString m_name;
77 CopiedString m_value;
78 CopiedString m_description;
79 EntityClassAttribute(){
80 }
81 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 ){
82 }
83 };
84
85 typedef std::pair<CopiedString, EntityClassAttribute> EntityClassAttributePair;
86 typedef std::list<EntityClassAttributePair> EntityClassAttributes;
87 typedef std::list<CopiedString> StringList;
88
89 inline const char* EntityClassAttributePair_getName( const EntityClassAttributePair& attributePair ){
90         if ( !string_empty( attributePair.second.m_name.c_str() ) ) {
91                 return attributePair.second.m_name.c_str();
92         }
93         return attributePair.first.c_str();
94 }
95
96 inline const char* EntityClassAttributePair_getDescription( const EntityClassAttributePair& attributePair ){
97         if ( !string_empty( attributePair.second.m_description.c_str() ) ) {
98                 return attributePair.second.m_description.c_str();
99         }
100         return EntityClassAttributePair_getName( attributePair );
101 }
102
103 class EntityClass
104 {
105 public:
106 CopiedString m_name;
107 StringList m_parent;
108 bool fixedsize;
109 bool unknown;               // wasn't found in source
110 Vector3 mins;
111 Vector3 maxs;
112
113 Colour3 color;
114 Shader* m_state_fill;
115 Shader* m_state_wire;
116 Shader* m_state_blend;
117
118 CopiedString m_comments;
119 char flagnames[MAX_FLAGS][32];
120
121 CopiedString m_modelpath;
122 CopiedString m_skin;
123
124 void ( *free )( EntityClass* );
125
126 EntityClassAttributes m_attributes;
127
128 bool inheritanceResolved;
129 bool sizeSpecified;
130 bool colorSpecified;
131
132 const char* name() const {
133         return m_name.c_str();
134 }
135 const char* comments() const {
136         return m_comments.c_str();
137 }
138 const char* modelpath() const {
139         return m_modelpath.c_str();
140 }
141 const char* skin() const {
142         return m_skin.c_str();
143 }
144 };
145
146 inline const char* EntityClass_valueForKey( const EntityClass& entityClass, const char* key ){
147         for ( EntityClassAttributes::const_iterator i = entityClass.m_attributes.begin(); i != entityClass.m_attributes.end(); ++i )
148         {
149                 if ( string_equal( key, ( *i ).first.c_str() ) ) {
150                         return ( *i ).second.m_value.c_str();
151                 }
152         }
153         return "";
154 }
155
156 inline EntityClassAttributePair& EntityClass_insertAttribute( EntityClass& entityClass, const char* key, const EntityClassAttribute& attribute = EntityClassAttribute() ){
157         entityClass.m_attributes.push_back( EntityClassAttributePair( key, attribute ) );
158         return entityClass.m_attributes.back();
159 }
160
161
162 inline void buffer_write_colour_fill( char buffer[128], const Colour3& colour ){
163         sprintf( buffer, "(%g %g %g)", colour[0], colour[1], colour[2] );
164 }
165
166 inline void buffer_write_colour_wire( char buffer[128], const Colour3& colour ){
167         sprintf( buffer, "<%g %g %g>", colour[0], colour[1], colour[2] );
168 }
169
170 inline void buffer_write_colour_blend( char buffer[128], const Colour3& colour ){
171         sprintf( buffer, "[%g %g %g]", colour[0], colour[1], colour[2] );
172 }
173
174 inline Shader* colour_capture_state_fill( const Colour3& colour ){
175         char buffer[128];
176         buffer_write_colour_fill( buffer, colour );
177         return GlobalShaderCache().capture( buffer );
178 }
179
180 inline void colour_release_state_fill( const Colour3& colour ){
181         char buffer[128];
182         buffer_write_colour_fill( buffer, colour );
183         GlobalShaderCache().release( buffer );
184 }
185
186 inline Shader* colour_capture_state_wire( const Colour3& colour ){
187         char buffer[128];
188         buffer_write_colour_wire( buffer, colour );
189         return GlobalShaderCache().capture( buffer );
190 }
191
192 inline void colour_release_state_wire( const Colour3& colour ){
193         char buffer[128];
194         buffer_write_colour_wire( buffer, colour );
195         GlobalShaderCache().release( buffer );
196 }
197
198 inline Shader* colour_capture_state_blend( const Colour3& colour ){
199         char buffer[128];
200         buffer_write_colour_blend( buffer, colour );
201         return GlobalShaderCache().capture( buffer );
202 }
203
204 inline void colour_release_state_blend( const Colour3& colour ){
205         char buffer[128];
206         buffer_write_colour_blend( buffer, colour );
207         GlobalShaderCache().release( buffer );
208 }
209
210 inline void eclass_capture_state( EntityClass* eclass ){
211         eclass->m_state_fill = colour_capture_state_fill( eclass->color );
212         eclass->m_state_wire = colour_capture_state_wire( eclass->color );
213         eclass->m_state_blend = colour_capture_state_blend( eclass->color );
214 }
215
216 inline void eclass_release_state( EntityClass* eclass ){
217         colour_release_state_fill( eclass->color );
218         colour_release_state_wire( eclass->color );
219         colour_release_state_blend( eclass->color );
220 }
221
222 // eclass constructor
223 inline EntityClass* Eclass_Alloc(){
224         EntityClass* e = new EntityClass;
225
226         e->fixedsize = false;
227         e->unknown = false;
228         memset( e->flagnames, 0, MAX_FLAGS * 32 );
229
230         e->maxs = Vector3( -1,-1,-1 );
231         e->mins = Vector3( 1, 1, 1 );
232
233         e->free = 0;
234
235         e->inheritanceResolved = true;
236         e->sizeSpecified = false;
237         e->colorSpecified = false;
238
239         return e;
240 }
241
242 // eclass destructor
243 inline void Eclass_Free( EntityClass* e ){
244         eclass_release_state( e );
245
246         delete e;
247 }
248
249 inline bool classname_equal( const char* classname, const char* other ){
250         return string_equal( classname, other );
251 }
252
253 inline EntityClass* EClass_Create( const char* name, const Vector3& colour, const char* comments ){
254         EntityClass *e = Eclass_Alloc();
255         e->free = &Eclass_Free;
256
257         e->m_name = name;
258
259         e->color = colour;
260         eclass_capture_state( e );
261
262         if ( comments ) {
263                 e->m_comments = comments;
264         }
265
266         return e;
267 }
268
269 inline EntityClass* EClass_Create_FixedSize( const char* name, const Vector3& colour, const Vector3& mins, const Vector3& maxs, const char* comments ){
270         EntityClass *e = Eclass_Alloc();
271         e->free = &Eclass_Free;
272
273         e->m_name = name;
274
275         e->color = colour;
276         eclass_capture_state( e );
277
278         e->fixedsize = true;
279
280         e->mins = mins;
281         e->maxs = maxs;
282
283         if ( comments ) {
284                 e->m_comments = comments;
285         }
286
287         return e;
288 }
289
290 const Vector3 smallbox[2] = {
291         Vector3( -8,-8,-8 ),
292         Vector3( 8, 8, 8 ),
293 };
294
295 inline EntityClass *EntityClass_Create_Default( const char *name, bool has_brushes ){
296         // create a new class for it
297         if ( has_brushes ) {
298                 return EClass_Create( name, Vector3( 0.0f, 0.5f, 0.0f ), "Not found in source." );
299         }
300         else
301         {
302                 return EClass_Create_FixedSize( name, Vector3( 0.0f, 0.5f, 0.0f ), smallbox[0], smallbox[1], "Not found in source." );
303         }
304 }
305
306 #endif