1 /*
2  * file level.c - Setting up level given in database
3  *
4  * $Id: level.c,v 1.14 2006/03/28 11:41:19 fzago Exp $
5  *
6  * Program XBLAST
7  * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published
11  * by the Free Software Foundation; either version 2; or (at your option)
12  * any later version
13  *
14  * This program is distributed in the hope that it will be entertaining,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17  * Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.
21  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 
24 #include "xblast.h"
25 
26 static DBRoot *warnings = NULL;
27 
28 /*
29  * initialize level problem database
30  */
31 static void
InitLevelWarnings(void)32 InitLevelWarnings (void)
33 {
34 	if (warnings != NULL) {
35 		DB_DeleteAll (warnings);
36 	}
37 	else {
38 		warnings = DB_Create (DT_Level, GUI_StringToAtom ("levelwarn!"));
39 		assert (warnings != NULL);
40 	}
41 
42 }								/* InitLevelWarnings */
43 
44 /*
45  * get number of warnings found in last parse
46  */
47 unsigned
GetWarningCount(void)48 GetWarningCount (void)
49 {
50 	unsigned cnt = DB_NumAllEntries (warnings);
51 	Dbg_Out ("warnings = %u\n", cnt);
52 	return cnt;
53 }								/* GetWarningCount */
54 
55 /*
56  * parse a new level
57  */
58 XBBool
ParseLevel(const DBRoot * level)59 ParseLevel (const DBRoot * level)
60 {
61 	DBSection *sec, *sec1, *sec2;
62 #ifdef DEBUG
63 	Dbg_StartClock ();
64 #endif
65 	Dbg_Level ("start parsing\n");
66 	/* sanity check */
67 	assert (level != NULL);
68 	InitLevelWarnings ();
69 	/* TODO: disallow random positions in some levels */
70 
71 	/* create info section in warnings, then parse */
72 	Dbg_Level ("parsing section [%s]\n", GUI_AtomToString (atomInfo));
73 	sec = DB_CreateSection (warnings, atomInfo);
74 	if (NULL == sec) {
75 		Dbg_Level ("failed to create warning section\n");
76 		return XBFalse;
77 	}
78 	if (!ParseLevelInfo (DB_GetSection (level, atomInfo), sec)) {
79 		Dbg_Level ("section invalid!\n");
80 		return XBFalse;
81 	}
82 	/* create player section in warning, then parse */
83 	sec = DB_CreateSection (warnings, atomPlayer);
84 	if (NULL == sec) {
85 		Dbg_Level ("failed to create warning section\n");
86 		return XBFalse;
87 	}
88 	Dbg_Level ("parsing section [%s]\n", GUI_AtomToString (atomPlayer));
89 	if (!ParseLevelPlayers (DB_GetSection (level, atomPlayer), GetGameModeInfo (), sec)) {
90 		Dbg_Level ("section invalid!\n");
91 		return XBFalse;
92 	}
93 
94 	/* setup shrink pattern */
95 	sec = DB_CreateSection (warnings, atomShrink);
96 	if (NULL == sec) {
97 		Dbg_Level ("failed to create warning section\n");
98 		return XBFalse;
99 	}
100 	Dbg_Level ("parsing section [%s]\n", GUI_AtomToString (atomShrink));
101 	if (!ParseLevelShrink (DB_GetSection (level, atomShrink), sec)) {
102 		Dbg_Level ("section invalid!\n");
103 		return XBFalse;
104 	}
105 
106 	/* setup scrambling blocks */
107 	sec1 = DB_CreateSection (warnings, atomScrambleDraw);
108 	if (NULL == sec1) {
109 		Dbg_Level ("failed to create warning section\n");
110 		return XBFalse;
111 	}
112 	sec2 = DB_CreateSection (warnings, atomScrambleDel);
113 	if (NULL == sec2) {
114 		Dbg_Level ("failed to create warning section\n");
115 		return XBFalse;
116 	}
117 	Dbg_Level ("parsing sections [%s] and [%s]\n",
118 			   GUI_AtomToString (atomScrambleDraw), GUI_AtomToString (atomScrambleDel));
119 	if (!ParseLevelScramble (DB_GetSection (level, atomScrambleDraw),
120 							 DB_GetSection (level, atomScrambleDel), sec1, sec2)) {
121 		Dbg_Level ("sections invalid!\n");
122 		return XBFalse;
123 	}
124 
125 	/* setup function pointers */
126 	sec = DB_CreateSection (warnings, atomFunc);
127 	if (NULL == sec) {
128 		Dbg_Level ("failed to create warning section\n");
129 		return XBFalse;
130 	}
131 	Dbg_Level ("parsing section [%s]\n", GUI_AtomToString (atomFunc));
132 	if (!ParseLevelFunc (DB_GetSection (level, atomFunc), sec)) {
133 		Dbg_Level ("section invalid!\n");
134 		return XBFalse;
135 	}
136 
137 	/* setup bombs */
138 	sec = DB_CreateSection (warnings, atomBombs);
139 	if (NULL == sec) {
140 		Dbg_Level ("failed to create warning section\n");
141 		return XBFalse;
142 	}
143 	Dbg_Level ("parsing section [%s]\n", GUI_AtomToString (atomBombs));
144 	if (!ParseLevelBombs (DB_GetSection (level, atomBombs), sec)) {
145 		Dbg_Level ("section invalid!\n");
146 		return XBFalse;
147 	}
148 
149 	/* setup graphics */
150 	sec = DB_CreateSection (warnings, atomGraphics);
151 	if (NULL == sec) {
152 		Dbg_Level ("failed to create warning section\n");
153 		return XBFalse;
154 	}
155 	if (!ParseLevelGraphics (DB_GetSection (level, atomGraphics), sec)) {
156 		Dbg_Level ("section invalid!\n");
157 		return XBFalse;
158 	}
159 
160 	/* setup map layout */
161 	sec = DB_CreateSection (warnings, atomMap);
162 	if (NULL == sec) {
163 		Dbg_Level ("failed to create warning section\n");
164 		return XBFalse;
165 	}
166 	if (!ParseLevelMap (DB_GetSection (level, atomMap), sec)) {
167 		Dbg_Level ("section invalid!\n");
168 		return XBFalse;
169 	}
170 
171 	Dbg_Level ("parsed in %lu msec\n", Dbg_FinishClock ());
172 	/* show all warnings */
173 	if (GetWarningCount ()) {
174 		DB_Dump (warnings);
175 	}
176 	return XBTrue;
177 }								/* ParseLevel */
178 
179 /*
180  * Configure new level
181  */
182 XBBool
ConfigLevel(const DBRoot * level)183 ConfigLevel (const DBRoot * level)
184 {
185 	/* sanity check */
186 	assert (level != NULL);
187 	/* parse first */
188 	if (!ParseLevel (level)) {
189 		return XBFalse;
190 	}
191 #ifdef DEBUG
192 	Dbg_StartClock ();
193 #endif
194 	Dbg_Level ("start configuring\n");
195 	ConfigLevelPlayers (DB_GetSection (level, atomPlayer), XBTrue, GetGameModeInfo ());
196 	ConfigLevelShrink (DB_GetSection (level, atomShrink));
197 	ConfigLevelFunc (DB_GetSection (level, atomFunc));
198 	ConfigLevelBombs (DB_GetSection (level, atomBombs));
199 	ConfigLevelGraphics (DB_GetSection (level, atomGraphics));
200 	ConfigLevelMap (DB_GetSection (level, atomMap));
201 	Dbg_Level ("configured in %lu msec\n", Dbg_FinishClock ());
202 	return XBTrue;
203 }								/* ConfigLevel */
204 
205 /*
206  * clean up after level
207  */
208 void
FinishLevel(void)209 FinishLevel (void)
210 {
211 	/* shrinking */
212 	FinishLevelShrink ();
213 	/* graphics */
214 	FinishLevelGraphics ();
215 	/* explosions */
216 	DeleteAllExplosions ();
217 }								/* FinishLevel */
218 
219 /*
220  * get string of level
221  */
222 static const char *
GetLevelString(const DBRoot * level,XBAtom atom)223 GetLevelString (const DBRoot * level, XBAtom atom)
224 {
225 	const char *s;
226 	const DBSection *section;
227 
228 	assert (level != NULL);
229 	section = DB_GetSection (level, atomInfo);
230 	if (NULL == section) {
231 		return NULL;
232 	}
233 	if (!DB_GetEntryString (section, atom, &s)) {
234 		return NULL;
235 	}
236 	return s;
237 }								/* GetLevelString */
238 
239 /*
240  * get name of level
241  */
242 const char *
GetLevelName(const DBRoot * level)243 GetLevelName (const DBRoot * level)
244 {
245 	return GetLevelString (level, atomName);
246 }								/* GetLevelName */
247 
248 /*
249  * get author of level
250  */
251 const char *
GetLevelAuthor(const DBRoot * level)252 GetLevelAuthor (const DBRoot * level)
253 {
254 	return GetLevelString (level, atomAuthor);
255 }								/* GetLevelAuthor */
256 
257 /*
258  * get hint for level
259  */
260 const char *
GetLevelHint(const DBRoot * level)261 GetLevelHint (const DBRoot * level)
262 {
263 	return GetLevelString (level, atomHint);
264 }								/* GetLevelHint */
265 
266 /*
267  * end of file level.c
268  */
269