1 //----------------------------------------------------------------------------
2 //  EDGE Data Definition File Codes (Switch textures)
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 // Switch Texture Setup and Parser Code
20 //
21 
22 #include "local.h"
23 
24 #include "switch.h"
25 
26 static switchdef_c *dynamic_switchdef;
27 
28 switchdef_container_c switchdefs;
29 
30 #define DDF_CMD_BASE  dummy_switchdef
31 static switchdef_c dummy_switchdef;
32 
33 static const commandlist_t switch_commands[] =
34 {
35 	DDF_FIELD("ON_TEXTURE",   on_name, DDF_MainGetLumpName),
36 	DDF_FIELD("OFF_TEXTURE", off_name, DDF_MainGetLumpName),
37 	DDF_FIELD("ON_SOUND",   on_sfx, DDF_MainLookupSound),
38 	DDF_FIELD("OFF_SOUND", off_sfx, DDF_MainLookupSound),
39 	DDF_FIELD("TIME", time, DDF_MainGetTime),
40 
41 	// -AJA- backwards compatibility cruft...
42 	DDF_FIELD("SOUND", on_sfx, DDF_MainLookupSound),
43 
44 	DDF_CMD_END
45 };
46 
47 
48 //
49 //  DDF PARSE ROUTINES
50 //
51 
SwitchStartEntry(const char * name,bool extend)52 static void SwitchStartEntry(const char *name, bool extend)
53 {
54 	if (!name || !name[0])
55 	{
56 		DDF_WarnError("New switch entry is missing a name!");
57 		name = "SWITCH_WITH_NO_NAME";
58 	}
59 
60 	dynamic_switchdef = switchdefs.Find(name);
61 
62 	if (extend)
63 	{
64 		if (! dynamic_switchdef)
65 			DDF_Error("Unknown switch to extend: %s\n", name);
66 		return;
67 	}
68 
69 	// replaces an existing entry
70 	if (dynamic_switchdef)
71 	{
72 		dynamic_switchdef->Default();
73 		return;
74 	}
75 
76 	// not found, create a new one
77 	dynamic_switchdef = new switchdef_c;
78 
79 	dynamic_switchdef->name = name;
80 
81 	switchdefs.Insert(dynamic_switchdef);
82 }
83 
84 
SwitchParseField(const char * field,const char * contents,int index,bool is_last)85 static void SwitchParseField(const char *field, const char *contents,
86 		int index, bool is_last)
87 {
88 #if (DEBUG_DDF)
89 	I_Debugf("SWITCH_PARSE: %s = %s;\n", field, contents);
90 #endif
91 
92 	if (DDF_MainParseField(switch_commands, field, contents, (byte *)dynamic_switchdef))
93 		return;
94 
95 	DDF_WarnError("Unknown switch.ddf command: %s\n", field);
96 }
97 
98 
SwitchFinishEntry(void)99 static void SwitchFinishEntry(void)
100 {
101 	if (!dynamic_switchdef->on_name[0])
102 		DDF_Error("Missing first name for switch.\n");
103 
104 	if (!dynamic_switchdef->off_name[0])
105 		DDF_Error("Missing last name for switch.\n");
106 
107 	if (dynamic_switchdef->time <= 0)
108 		DDF_Error("Bad time value for switch: %d\n", dynamic_switchdef->time);
109 }
110 
111 
SwitchClearAll(void)112 static void SwitchClearAll(void)
113 {
114 	// 100% safe to delete all switchdefs
115 	switchdefs.Clear();
116 }
117 
118 
DDF_ReadSwitch(void * data,int size)119 bool DDF_ReadSwitch(void *data, int size)
120 {
121 #if (DEBUG_DDF)
122 	epi::array_iterator_c it;
123 	switchdef_c *sw;
124 #endif
125 
126 	readinfo_t switches;
127 
128 	switches.memfile = (char*)data;
129 	switches.memsize = size;
130 	switches.tag = "SWITCHES";
131 	switches.entries_per_dot = 2;
132 
133 	if (switches.memfile)
134 	{
135 		switches.message = NULL;
136 		switches.filename = NULL;
137 		switches.lumpname = "DDFSWTH";
138 	}
139 	else
140 	{
141 		switches.message = "DDF_InitSwitches";
142 		switches.filename = "switch.ddf";
143 		switches.lumpname = NULL;
144 	}
145 
146 	switches.start_entry  = SwitchStartEntry;
147 	switches.parse_field  = SwitchParseField;
148 	switches.finish_entry = SwitchFinishEntry;
149 	switches.clear_all    = SwitchClearAll;
150 
151 	if (! DDF_MainReadFile(&switches))
152 		return false;
153 
154 #if (DEBUG_DDF)
155 	I_Debugf("DDF_ReadSW: Switch List:\n");
156 
157 	for (it = switchdefs.GetBaseIterator(); it.IsValid(); it++)
158 	{
159 		sw = ITERATOR_TO_TYPE(it, switchdef_c*);
160 
161 		I_Debugf("  Num: %d  ON: '%s'  OFF: '%s'\n",
162 						i, sw->on_name, sw->off_name);
163 	}
164 #endif
165 
166 	return true;
167 }
168 
169 //
170 // DDF_SwitchInit
171 //
DDF_SwitchInit(void)172 void DDF_SwitchInit(void)
173 {
174 	switchdefs.Clear();
175 }
176 
177 //
178 // DDF_SwitchCleanUp
179 //
DDF_SwitchCleanUp(void)180 void DDF_SwitchCleanUp(void)
181 {
182 	switchdefs.Trim();
183 }
184 
DDF_ParseSWITCHES(const byte * data,int size)185 void DDF_ParseSWITCHES(const byte *data, int size)
186 {
187 	for (; size >= 20; data += 20, size -= 20)
188 	{
189 		if (data[18] == 0)  // end marker
190 			break;
191 
192 		char  on_name[10];
193 		char off_name[10];
194 
195 		// make sure names are NUL-terminated
196 		memcpy( on_name, data+9, 9);  on_name[8] = 0;
197 		memcpy(off_name, data+0, 9); off_name[8] = 0;
198 
199 		I_Debugf("- SWITCHES LUMP: off '%s' : on '%s'\n", off_name, on_name);
200 
201 		// ignore zero-length names
202 		if (!off_name[0] || !on_name[0])
203 			continue;
204 
205 		switchdef_c *def = new switchdef_c;
206 
207 		def->name = "BOOM_SWITCH";
208 
209 		def->Default();
210 
211 		def->on_name.Set( on_name);
212 		def->off_name.Set(off_name);
213 
214 		switchdefs.Insert(def);
215 	}
216 }
217 
218 
219 // ---> switchdef_c class
220 
221 //
222 // switchdef_c Constructor
223 //
switchdef_c()224 switchdef_c::switchdef_c() : name()
225 {
226 	Default();
227 }
228 
229 
230 //
231 // switchdef_c::CopyDetail()
232 //
233 // Copies all the detail with the exception of ddf info
234 //
CopyDetail(switchdef_c & src)235 void switchdef_c::CopyDetail(switchdef_c &src)
236 {
237 	 on_name = src.on_name;
238 	off_name = src.off_name;
239 
240 	 on_sfx = src.on_sfx;
241 	off_sfx = src.off_sfx;
242 
243 	time = src.time;
244 }
245 
246 //
247 // switchdef_c::Default()
248 //
Default()249 void switchdef_c::Default()
250 {
251 	 on_name.clear();
252 	off_name.clear();
253 
254 	 on_sfx = sfx_None;
255 	off_sfx = sfx_None;
256 
257 	time = BUTTONTIME;
258 }
259 
260 
261 // --> switchdef_container_c Class
262 
263 //
264 // switchdef_container_c::CleanupObject()
265 //
CleanupObject(void * obj)266 void switchdef_container_c::CleanupObject(void *obj)
267 {
268 	switchdef_c *sw = *(switchdef_c**)obj;
269 
270 	if (sw)
271 		delete sw;
272 
273 	return;
274 }
275 
276 //
277 // switchdef_c* switchdef_container_c::Find()
278 //
Find(const char * name)279 switchdef_c* switchdef_container_c::Find(const char *name)
280 {
281 	epi::array_iterator_c it;
282 	switchdef_c *sw;
283 
284 	for (it = GetBaseIterator(); it.IsValid(); it++)
285 	{
286 		sw = ITERATOR_TO_TYPE(it, switchdef_c*);
287 		if (DDF_CompareName(sw->name.c_str(), name) == 0)
288 			return sw;
289 	}
290 
291 	return NULL;
292 }
293 
294 //--- editor settings ---
295 // vi:ts=4:sw=4:noexpandtab
296