1 /*
2  * file image.c - maige filenames and sizes
3  *
4  * $Id: image.c,v 1.10 2006/02/09 21:21:24 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 /*
27  * local types
28  */
29 typedef struct _shape_list ShapeList;
30 struct _shape_list
31 {
32 	char *name;
33 	XBBool valid;
34 	ShapeList *next;
35 };
36 
37 /*
38  * global variables
39  */
40 
41 /* search paths */
42 #ifdef WMS
43 #define GAME_DATADIR "."
44 #endif
45 
46 const char *imgPathBlock = GAME_DATADIR "/image/block";
47 const char *imgPathExpl = GAME_DATADIR "/image/explosion";
48 const char *imgPathMisc = GAME_DATADIR "/image/misc";
49 const char *imgPathScore = GAME_DATADIR "/image/score";
50 const char *imgPathSprite = GAME_DATADIR "/image/sprite";
51 
52 /* background pixmaps */
53 const char *imgFileTitle = "title";
54 const char *imgFileTextBg = "text_bg";
55 const char *imgFileTextFg = "text_fg";
56 /* score board leds */
57 const char *imgFileScoreLed[] = {
58 	"led_off",
59 	"led_on",
60 };
61 
62 /* score board tiles */
63 const char *imgFileScoreTile[] = {
64 	"tile_void",
65 	"text_left",
66 	"text_middle",
67 	"text_right",
68 };
69 
70 /* score player stats */
71 const char *imgFileScorePlayer[] = {
72 	"player_dead",
73 	"player_sick",
74 	"player",
75 	"player_abort",
76 	"player_sick_abort",
77 
78 };
79 
80 /* bomb images */
81 const char *imgFileBomb[MAX_BOMBS][MAX_BOMB_ANIME] = {
82 	{
83 	 "bomb_0", "bomb_1", "bomb_2", "bomb_3", "bomb_4", "bomb_5", "bomb_6", "bomb_7",
84 	 "bomb_8", "bomb_9", "bomb_10", "bomb_11", "bomb_12", "bomb_13", "bomb_14", "bomb_15",
85 	 "bomb_x",
86 	 },
87 	{
88 	 "mini_0", "mini_1", "mini_2", "mini_3", "mini_4", "mini_5", "mini_6", "mini_7",
89 	 "mini_8", "mini_9", "mini_10", "mini_11", "mini_12", "mini_13", "mini_14", "mini_15",
90 	 "mini_x",
91 	 },
92 };
93 
94 /* explosions image */
95 const char *imgFileExpl[MAX_EXPLOSION] = {
96 	"expl00",
97 	"expl01",
98 	"expl02",
99 	"expl03",
100 	"expl04",
101 	"expl05",
102 	"expl06",
103 	"expl07",
104 	"expl08",
105 	"expl09",
106 	"expl0a",
107 	"expl0b",
108 	"expl0c",
109 	"expl0d",
110 	"expl0e",
111 	"expl0f",
112 };
113 
114 /*
115  * offset and size data for sprites
116  */
117 const BMRectangle imgRectSprite[MAX_ANIME] = {
118 	/* down */
119 	{0, 3 * BASE_Y, 8 * BASE_X, 13 * BASE_Y},
120 	{0, 3 * BASE_Y, 8 * BASE_X, 13 * BASE_Y},
121 	{0, 3 * BASE_Y, 8 * BASE_X, 13 * BASE_Y},
122 	{0, 3 * BASE_Y, 8 * BASE_X, 13 * BASE_Y},
123 	{0, 3 * BASE_Y, 8 * BASE_X, 13 * BASE_Y},
124 	/* up */
125 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
126 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
127 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
128 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
129 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
130 	/* right */
131 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
132 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
133 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
134 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
135 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
136 	/* left */
137 	{0, 4 * BASE_Y, 8 * BASE_X, 12 * BASE_Y},
138 	{0, 4 * BASE_Y, 8 * BASE_X, 12 * BASE_Y},
139 	{0, 4 * BASE_Y, 8 * BASE_X, 12 * BASE_Y},
140 	{0, 4 * BASE_Y, 8 * BASE_X, 12 * BASE_Y},
141 	{0, 4 * BASE_Y, 8 * BASE_X, 12 * BASE_Y},
142 	/* damaged */
143 	{0, (4 - 1) * BASE_Y, 8 * BASE_X, 12 * BASE_Y},
144 	{1 * BASE_X, 6 * BASE_Y, 8 * BASE_X, 10 * BASE_Y},
145 	{0, (7 + 1) * BASE_Y, 8 * BASE_X, 8 * BASE_Y},
146 	{-1 * BASE_X, 6 * BASE_Y, 8 * BASE_X, 10 * BASE_Y},
147 	/* looser */
148 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
149 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
150 	{0, 4 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
151 	/* winner */
152 	{0, 2 * BASE_Y, 8 * BASE_X, 13 * BASE_Y},
153 	{0, 2 * BASE_Y, 8 * BASE_X, 13 * BASE_Y},
154 	{0, 3 * BASE_Y, 8 * BASE_X, 12 * BASE_Y},
155 	/* big winner */
156 	{-4 * BASE_X, (-8 + 5) * BASE_Y, 16 * BASE_X, 25 * BASE_Y},
157 	/* skeleton */
158 	{0, 5 * BASE_Y, 8 * BASE_X, 10 * BASE_Y},
159 	{0, 5 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
160 	{0, 5 * BASE_Y, 8 * BASE_X, 9 * BASE_Y},
161 	{0, 5 * BASE_Y, 8 * BASE_X, 11 * BASE_Y},
162 	/* morphed eyes */
163 	{0, 7 * BASE_Y, 8 * BASE_X, 8 * BASE_Y},
164 	{0, 5 * BASE_Y, 8 * BASE_X, 10 * BASE_Y},	/* zombie */
165 };
166 
167 /* epm file formats */
168 static const char *imgFileSpriteEpm[MAX_ANIME_EPM] = {
169 	/* looking down */
170 	"%s_D_S", "%s_D_0", "%s_D_1", "%s_D_2", "%s_D_3",
171 	/* looking up */
172 	"%s_U_S", "%s_U_0", "%s_U_1", "%s_U_2", "%s_U_3",
173 	/* looking right */
174 	"%s_R_S", "%s_R_0", "%s_R_1", "%s_R_2", "%s_R_3",
175 	/* looking left */
176 	"%s_L_S", "%s_L_0", "%s_L_1", "%s_L_2", "%s_L_3",
177 	/* damaged player */
178 	"%s_DD", "%s_DL", "%s_DU", "%s_DR",
179 	/* loosing player */
180 	"%s_L", "%s_L1", "%s_L2",
181 	/* winning player */
182 	"%s_W", "%s_W2", "%s_W3",
183 	/* big winning player */
184 	"%s_B",
185 };
186 
187 const char *imgFileSpritePpm[MAX_ANIME_PPM] = {
188 	/* skeleton */
189 	"skel_D", "skel_L", "skel_U", "skel_R",
190 	/* morphed player (eyes only) */
191 	"morph", "zombie",
192 };
193 
194 /* icon sprites */
195 const char *imgFileIcon[MAX_ICON_SPRITES] = {
196 	/* 6 color sprites */
197 	"icon_color", "icon_color", "icon_color", "icon_color", "icon_color", "icon_color",
198 	/* other icons */
199 	"icon_led_on", "icon_led_off", "icon_abort", "icon_default",
200 	/* team icons */
201 	"icon_led_off", "icon_led_on", "icon_led_on", "icon_led_on",
202 };
203 const BMRectangle imgRectIcon[MAX_ICON_SPRITES] = {
204 	/* 6 color sprite */
205 	{BASE_X, BASE_Y, 6 * BASE_X, 6 * BASE_Y,},
206 	{BASE_X, BASE_Y, 6 * BASE_X, 6 * BASE_Y,},
207 	{BASE_X, BASE_Y, 6 * BASE_X, 6 * BASE_Y,},
208 	{BASE_X, BASE_Y, 6 * BASE_X, 6 * BASE_Y,},
209 	{BASE_X, BASE_Y, 6 * BASE_X, 6 * BASE_Y,},
210 	{BASE_X, BASE_Y, 6 * BASE_X, 6 * BASE_Y,},
211 	/* other icons */
212 	{5 * BASE_X / 2, 3 * BASE_Y, 3 * BASE_X, 3 * BASE_Y,},
213 	{5 * BASE_X / 2, 3 * BASE_Y, 3 * BASE_X, 3 * BASE_Y,},
214 	{BASE_X, 2 * BASE_Y, 6 * BASE_X, 5 * BASE_Y,},
215 	{BASE_X, 2 * BASE_Y, 6 * BASE_X, 5 * BASE_Y,},
216 };
217 
218 /*
219  * local variables
220  */
221 
222 /* shapes */
223 static int numShapes = 0;
224 static XBAtom *shapeTable = NULL;
225 
226 /*
227  * create list with possible shapes
228  */
229 static ShapeList *
CreateShapeList(const XBDir * epmList)230 CreateShapeList (const XBDir * epmList)
231 {
232 	const char *s;
233 	int len;
234 	const XBDir *ptr;
235 	ShapeList *item;
236 	ShapeList *list = NULL;
237 
238 	for (ptr = epmList; ptr != NULL; ptr = ptr->next) {
239 		s = strstr (ptr->name, "_B");
240 		if (NULL != s) {
241 			len = s - ptr->name;
242 			/* found big player sprite */
243 			item = calloc (1, sizeof (ShapeList));
244 			assert (item != NULL);
245 			item->valid = XBTrue;
246 			item->name = calloc (len + 1, sizeof (char));
247 			strncpy (item->name, ptr->name, len);
248 			/* add to list */
249 			item->next = list;
250 			list = item;
251 		}
252 	}
253 	return list;
254 }								/* CreateShapeList */
255 
256 /*
257  * check for invalid items in shape list
258  */
259 static void
CheckShapeList(ShapeList * list,const XBDir * epmList)260 CheckShapeList (ShapeList * list, const XBDir * epmList)
261 {
262 	int i;
263 	const XBDir *ptr;
264 	ShapeList *item;
265 	char fileName[80];
266 	XBBool valid;
267 
268 	for (item = list; item != NULL; item = item->next) {
269 		for (i = 0; i < MAX_ANIME_EPM; i++) {
270 			sprintf (fileName, imgFileSpriteEpm[i], item->name);
271 			valid = XBFalse;
272 			for (ptr = epmList; ptr != NULL; ptr = ptr->next) {
273 				if (0 == strcmp (fileName, ptr->name)) {
274 					valid = XBTrue;
275 					break;
276 				}
277 			}
278 			if (!valid) {
279 				item->valid = XBFalse;
280 				break;
281 			}
282 		}
283 	}
284 }								/* CheckShapeList */
285 
286 /*
287  *
288  */
289 static XBAtom *
CreateShapeArray(const ShapeList * list,int * pNum)290 CreateShapeArray (const ShapeList * list, int *pNum)
291 {
292 	int i;
293 	XBAtom *table;
294 	const ShapeList *item;
295 
296 	assert (pNum != NULL);
297 
298 	*pNum = 0;
299 	for (item = list; item != NULL; item = item->next) {
300 		if (item->valid) {
301 			*pNum = *pNum + 1;
302 		}
303 	}
304 	if (0 == *pNum) {
305 		return NULL;
306 	}
307 	table = calloc (*pNum, sizeof (XBAtom));
308 	assert (table != NULL);
309 	i = 0;
310 #ifdef DEBUG
311 	fprintf (stderr, "found shape:");
312 #endif
313 	for (item = list; item != NULL; item = item->next) {
314 		if (item->valid) {
315 #ifdef DEBUG
316 			fputc (' ', stderr);
317 			fputs (item->name, stderr);
318 #endif
319 			table[i] = GUI_StringToAtom (item->name);
320 		}
321 		i++;
322 	}
323 #ifdef DEBUG
324 	fputc ('\n', stderr);
325 #endif
326 	return table;
327 }								/* CreateShapeArray */
328 
329 /*
330  * Delete shape list
331  */
332 static void
DeleteShapeList(ShapeList * list)333 DeleteShapeList (ShapeList * list)
334 {
335 	ShapeList *item, *itemNext;
336 
337 	for (item = list; item != NULL; item = itemNext) {
338 		itemNext = item->next;
339 		free (item->name);
340 		free (item);
341 	}
342 }								/* DeleteShapeList */
343 
344 /*
345  * inititalize valid player shapes
346  */
347 static XBAtom *
InitShapes(int * pNum)348 InitShapes (int *pNum)
349 {
350 	XBDir *epmList;
351 	XBDir *pbmList;
352 	ShapeList *list = NULL;
353 	XBAtom *table;
354 #ifdef DEBUG
355 	Dbg_StartClock ();
356 #endif
357 
358 	epmList = CreateFileList (GAME_DATADIR "/image/sprite", "epm", XBFalse);
359 	pbmList = CreateFileList (GAME_DATADIR "/image/sprite", "pbm", XBFalse);
360 	/* find possible shapes */
361 	list = CreateShapeList (epmList);
362 	/* check them */
363 	CheckShapeList (list, epmList);
364 	CheckShapeList (list, pbmList);
365 	/* create array and delete list */
366 	table = CreateShapeArray (list, pNum);
367 	/* delete list */
368 	DeleteShapeList (list);
369 	/* delete file list */
370 	DeleteFileList (epmList);
371 	DeleteFileList (pbmList);
372 #ifdef DEBUG
373 	fprintf (stderr, "load shapes: %lu msec\n", Dbg_FinishClock ());
374 #endif
375 	return table;
376 }								/* InitShapes */
377 
378 /*
379  * convert shape name to existing shape
380  */
381 static const char *
ShapeToName(XBAtom shape)382 ShapeToName (XBAtom shape)
383 {
384 	int i;
385 
386 	if (NULL == shapeTable) {
387 		shapeTable = InitShapes (&numShapes);
388 	}
389 	assert (shapeTable != NULL);
390 	for (i = 0; i < numShapes; i++) {
391 		if (shape == shapeTable[i]) {
392 			return GUI_AtomToString (shape);
393 		}
394 	}
395 	return "normal";
396 }								/* NameToShape */
397 
398 /*
399  * create name for sprite
400  */
401 const char *
ImgFileSpriteEpm(XBAtom shape,int anime)402 ImgFileSpriteEpm (XBAtom shape, int anime)
403 {
404 	static char tmp[80];
405 
406 	assert (shape != ATOM_INVALID);
407 	assert (anime >= 0);
408 	assert (anime < MAX_ANIME_EPM);
409 	sprintf (tmp, imgFileSpriteEpm[anime], ShapeToName (shape));
410 	return tmp;
411 }								/* ImgFileSpriteEpm */
412 
413 /*
414  * list all shapes
415  */
416 const XBAtom *
GetShapeList(int * pNum)417 GetShapeList (int *pNum)
418 {
419 	if (NULL == shapeTable) {
420 		shapeTable = InitShapes (&numShapes);
421 	}
422 	assert (shapeTable != NULL);
423 	*pNum = numShapes;
424 	return shapeTable;
425 }								/* GetShapeList */
426 
427 /*
428  * delete shape list
429  */
430 void
ClearShapeList(void)431 ClearShapeList (void)
432 {
433 	if (NULL != shapeTable) {
434 		free (shapeTable);
435 		shapeTable = NULL;
436 		numShapes = 0;
437 	}
438 }								/* ClearShapeList */
439 
440 /*
441  * end of file x11c_data.c
442  */
443