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