1 //----------------------------------------------------------------------------
2 // EDGE Data Definition File Code (Colourmaps)
3 //----------------------------------------------------------------------------
4 //
5 // Copyright (c) 1999-2008 The EDGE Team.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // This program 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 //----------------------------------------------------------------------------
18 //
19 // Colourmap handling.
20 //
21
22 #include "local.h"
23
24 #include "colormap.h"
25
26 static colourmap_c *dynamic_colmap;
27
28 colourmap_container_c colourmaps;
29
30 void DDF_ColmapGetSpecial(const char *info, void *storage);
31
32 #define DDF_CMD_BASE dummy_colmap
33 static colourmap_c dummy_colmap;
34
35 static const commandlist_t colmap_commands[] =
36 {
37 DDF_FIELD("LUMP", lump_name, DDF_MainGetLumpName),
38 DDF_FIELD("START", start, DDF_MainGetNumeric),
39 DDF_FIELD("LENGTH", length, DDF_MainGetNumeric),
40 DDF_FIELD("SPECIAL", special, DDF_ColmapGetSpecial),
41 DDF_FIELD("GL_COLOUR", gl_colour, DDF_MainGetRGB),
42
43 DDF_CMD_END
44 };
45
46
47 //
48 // DDF PARSE ROUTINES
49 //
50
ColmapStartEntry(const char * name,bool extend)51 static void ColmapStartEntry(const char *name, bool extend)
52 {
53 if (!name || name[0] == 0)
54 {
55 DDF_WarnError("New colormap entry is missing a name!");
56 name = "COLORMAP_WITH_NO_NAME";
57 }
58
59 dynamic_colmap = colourmaps.Lookup(name);
60
61 if (extend)
62 {
63 if (! dynamic_colmap)
64 DDF_Error("Unknown colormap to extend: %s\n", name);
65 return;
66 }
67
68 // replaces the existing entry
69 if (dynamic_colmap)
70 {
71 dynamic_colmap->Default();
72
73 if (strnicmp(name, "TEXT", 4) == 0)
74 dynamic_colmap->special = COLSP_Whiten;
75
76 return;
77 }
78
79 // not found, create a new one
80 dynamic_colmap = new colourmap_c;
81
82 dynamic_colmap->name.Set(name);
83
84 // make sure fonts get whitened properly (as the default)
85 if (strnicmp(name, "TEXT", 4) == 0)
86 dynamic_colmap->special = COLSP_Whiten;
87
88 colourmaps.Insert(dynamic_colmap);
89 }
90
91
ColmapParseField(const char * field,const char * contents,int index,bool is_last)92 static void ColmapParseField(const char *field, const char *contents,
93 int index, bool is_last)
94 {
95 #if (DEBUG_DDF)
96 I_Debugf("COLMAP_PARSE: %s = %s;\n", field, contents);
97 #endif
98
99 // -AJA- backwards compatibility cruft...
100 if (DDF_CompareName(field, "PRIORITY") == 0)
101 return;
102
103 if (DDF_MainParseField(colmap_commands, field, contents, (byte *)dynamic_colmap))
104 return; // OK
105
106 DDF_WarnError("Unknown colmap.ddf command: %s\n", field);
107 }
108
109
ColmapFinishEntry(void)110 static void ColmapFinishEntry(void)
111 {
112 if (dynamic_colmap->start < 0)
113 {
114 DDF_WarnError("Bad START value for colmap: %d\n", dynamic_colmap->start);
115 dynamic_colmap->start = 0;
116 }
117
118 // don't need a length when using GL_COLOUR
119 if (! dynamic_colmap->lump_name.empty() && dynamic_colmap->length <= 0)
120 {
121 DDF_WarnError("Bad LENGTH value for colmap: %d\n", dynamic_colmap->length);
122 dynamic_colmap->length = 1;
123 }
124
125 if (dynamic_colmap->lump_name.empty() && dynamic_colmap->gl_colour == RGB_NO_VALUE)
126 DDF_Error("Colourmap entry missing LUMP or GL_COLOUR.\n");
127 }
128
129
ColmapClearAll(void)130 static void ColmapClearAll(void)
131 {
132 I_Warning("Ignoring #CLEARALL in colormap.ddf\n");
133 }
134
135
DDF_ReadColourMaps(void * data,int size)136 bool DDF_ReadColourMaps(void *data, int size)
137 {
138 readinfo_t colm_r;
139
140 colm_r.memfile = (char*)data;
141 colm_r.memsize = size;
142 colm_r.tag = "COLOURMAPS";
143 colm_r.entries_per_dot = 2;
144
145 if (colm_r.memfile)
146 {
147 colm_r.message = NULL;
148 colm_r.filename = NULL;
149 colm_r.lumpname = "DDFCOLM";
150 }
151 else
152 {
153 colm_r.message = "DDF_InitColourMaps";
154 colm_r.filename = "colmap.ddf";
155 colm_r.lumpname = NULL;
156 }
157
158 colm_r.start_entry = ColmapStartEntry;
159 colm_r.parse_field = ColmapParseField;
160 colm_r.finish_entry = ColmapFinishEntry;
161 colm_r.clear_all = ColmapClearAll;
162
163 return DDF_MainReadFile(&colm_r);
164 }
165
166
DDF_ColmapInit(void)167 void DDF_ColmapInit(void)
168 {
169 colourmaps.Clear();
170 }
171
172
DDF_ColmapCleanUp(void)173 void DDF_ColmapCleanUp(void)
174 {
175 colourmaps.Trim();
176 }
177
178
179 specflags_t colmap_specials[] =
180 {
181 {"FLASH", COLSP_NoFlash, true},
182 {"WHITEN", COLSP_Whiten, false},
183
184 // -AJA- backwards compatibility cruft...
185 {"SKY", 0, 0},
186
187 {NULL, 0, 0}
188 };
189
190
191 //
192 // DDF_ColmapGetSpecial
193 //
194 // Gets the colourmap specials.
195 //
DDF_ColmapGetSpecial(const char * info,void * storage)196 void DDF_ColmapGetSpecial(const char *info, void *storage)
197 {
198 colourspecial_e *spec = (colourspecial_e *)storage;
199
200 int flag_value;
201
202 switch (DDF_MainCheckSpecialFlag(info, colmap_specials, &flag_value,
203 true, false))
204 {
205 case CHKF_Positive:
206 *spec = (colourspecial_e)(*spec | flag_value);
207 break;
208
209 case CHKF_Negative:
210 *spec = (colourspecial_e)(*spec & ~flag_value);
211 break;
212
213 case CHKF_User:
214 case CHKF_Unknown:
215 DDF_WarnError("DDF_ColmapGetSpecial: Unknown Special: %s", info);
216 break;
217 }
218 }
219
220
221 //
222 // This is used to make entries for lumps between C_START and C_END
223 // markers in a (BOOM) WAD file.
224 //
DDF_ColourmapAddRaw(const char * lump_name,int size)225 void DDF_ColourmapAddRaw(const char *lump_name, int size)
226 {
227 if (size < 256)
228 {
229 I_Warning("WAD Colourmap '%s' too small (%d < %d)\n", lump_name, size, 256);
230 return;
231 }
232
233 colourmap_c *def = colourmaps.Lookup(lump_name);
234
235 // not found, create a new one
236 if (! def)
237 {
238 def = new colourmap_c;
239
240 colourmaps.Insert(def);
241 }
242
243 def->Default();
244
245 def->name = lump_name;
246
247 def->lump_name.Set(lump_name);
248
249 def->start = 0;
250 def->length = MIN(32, size / 256);
251
252 I_Debugf("- Added RAW colourmap '%s' start=%d length=%d\n",
253 lump_name, def->start, def->length);
254 }
255
256
257 // --> Colourmap Class
258
259 //
260 // colourmap_c Constructor
261 //
colourmap_c()262 colourmap_c::colourmap_c() : name()
263 {
264 Default();
265 }
266
267 //
268 // colourmap_c Deconstructor
269 //
~colourmap_c()270 colourmap_c::~colourmap_c()
271 {
272 }
273
274 //
275 // colourmap_c::CopyDetail()
276 //
CopyDetail(colourmap_c & src)277 void colourmap_c::CopyDetail(colourmap_c &src)
278 {
279 lump_name = src.lump_name;
280
281 start = src.start;
282 length = src.length;
283 special = src.special;
284
285 gl_colour = src.gl_colour;
286 font_colour = src.font_colour;
287
288 // FIXME!!! Cache struct to class
289 cache.data = src.cache.data;
290 analysis = NULL;
291 }
292
293 //
294 // colourmap_c::Default()
295 //
Default()296 void colourmap_c::Default()
297 {
298 lump_name.clear();
299
300 start = 0;
301 length = 0;
302 special = COLSP_None;
303
304 gl_colour = RGB_NO_VALUE;
305 font_colour = RGB_NO_VALUE;
306
307 // FIXME!!! Cache struct to class
308 cache.data = NULL;
309 analysis = NULL;
310 }
311
312
313 // --> colourmap_container_c class
314
315 //
316 // colourmap_container_c::colourmap_container_c()
317 //
colourmap_container_c()318 colourmap_container_c::colourmap_container_c() : epi::array_c(sizeof(atkdef_c*))
319 {
320 }
321
322 //
323 // ~colourmap_container_c::colourmap_container_c()
324 //
~colourmap_container_c()325 colourmap_container_c::~colourmap_container_c()
326 {
327 Clear(); // <-- Destroy self before exiting
328 }
329
330 //
331 // colourmap_container_c::CleanupObject
332 //
CleanupObject(void * obj)333 void colourmap_container_c::CleanupObject(void *obj)
334 {
335 colourmap_c *c = *(colourmap_c**)obj;
336
337 if (c)
338 delete c;
339
340 return;
341 }
342
343 //
344 // colourmap_c* colourmap_container_c::Lookup()
345 //
Lookup(const char * refname)346 colourmap_c* colourmap_container_c::Lookup(const char *refname)
347 {
348 epi::array_iterator_c it;
349 colourmap_c *c;
350
351 if (!refname || !refname[0])
352 return NULL;
353
354 for (it = GetIterator(0); it.IsValid(); it++)
355 {
356 c = ITERATOR_TO_TYPE(it, colourmap_c*);
357 if (DDF_CompareName(c->name.c_str(), refname) == 0)
358 return c;
359 }
360
361 return NULL;
362 }
363
364 //--- editor settings ---
365 // vi:ts=4:sw=4:noexpandtab
366