1 /*
2  * file w32_tile.c - loading and drawing maptiles
3  *
4  * $Id: w32_tile.c,v 1.8 2006/02/19 13:33:01 lodott 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 #include "xblast.h"
24 #include "w32_tile.h"
25 #include "gui.h"
26 
27 #include "w32_image.h"
28 #include "w32_sprite.h"
29 #include "w32_pixmap.h"
30 
31 #include "geom.h"
32 #include "image.h"
33 
34 /*
35  * local variables
36  */
37 
38 #define MAX_LEDS 5				// 2+3 XBCC
39 
40 static HDC hdcDst = NULL;
41 static HDC hdcSrc = NULL;
42 
43 static HBITMAP pixBlock[MAX_TILE];
44 static HBITMAP pixLeds[MAX_LEDS];
45 static HBITMAP pixScore[MAX_SCORE_TILES];
46 static HBITMAP pixExplBlock[MAX_EXPLOSION];
47 
48 static RECT voidList[MAZE_W * (MAZE_H + 2)];
49 static RECT blockList[MAX_TILE][MAZE_W * (MAZE_H + 2)];
50 static RECT explList[MAX_EXPLOSION][MAZE_W * (MAZE_H + 2)];
51 
52 static RECT *voidLast = voidList;
53 static RECT *blockLast[MAX_TILE];
54 static RECT *explLast[MAX_EXPLOSION];
55 /*
56  *
57  */
58 XBBool
InitTiles(void)59 InitTiles (void)
60 {
61 	HDC hdc;
62 	int i;
63 
64 	/* create device contextes for drawing block to pixmap */
65 	hdc = GetDC (window);
66 	if (NULL == hdc) {
67 		return XBFalse;
68 	}
69 	hdcDst = CreateCompatibleDC (hdc);
70 	if (NULL == hdcDst) {
71 		return XBFalse;
72 	}
73 	hdcSrc = CreateCompatibleDC (hdc);
74 	if (NULL == hdcSrc) {
75 		return XBFalse;
76 	}
77 	/* init led tiles  */
78 	for (i = 0; i < 2; i++) {
79 		pixLeds[i] =
80 			ReadCchPixmap (imgPathScore, imgFileScoreLed[i], COLOR_BLACK, COLOR_LIGHT_GOLDENROD,
81 						   COLOR_SPRING_GREEN);
82 	}
83 	// XBCC
84 	pixLeds[2] = ReadCchPixmap (imgPathScore, imgFileScoreLed[1], COLOR_BLACK, COLOR_LIGHT_GOLDENROD, COLOR_RED);	// SHRINK Led
85 	pixLeds[3] = ReadCchPixmap (imgPathScore, imgFileScoreLed[1], COLOR_BLACK, COLOR_LIGHT_GOLDENROD, COLOR_ORANGE);	// SCRAMBLE DRAW Led
86 	pixLeds[4] = ReadCchPixmap (imgPathScore, imgFileScoreLed[1], COLOR_BLACK, COLOR_LIGHT_GOLDENROD, COLOR_BLUE);	// SCRAMBLE DEL Led
87 	// -XBCC
88 	/* init other score tiles */
89 	for (i = 0; i < SBDead; i++) {
90 		pixScore[i] =
91 			ReadCchPixmap (imgPathScore, imgFileScoreTile[i], COLOR_BLACK, COLOR_LIGHT_GOLDENROD,
92 						   COLOR_SADDLE_BROWN);
93 	}
94 	/* init drawing lists */
95 	for (i = 0; i < MAX_TILE; i++) {
96 		blockLast[i] = blockList[i];
97 	}
98 	for (i = 0; i < MAX_EXPLOSION; i++) {
99 		explLast[i] = explList[i];
100 	}
101 	/* just clear this ones */
102 	memset (pixBlock, 0, sizeof (pixBlock));
103 	memset (pixExplBlock, 0, sizeof (pixExplBlock));
104 	return XBTrue;
105 }								/* InitTiles */
106 
107 /*
108  *
109  */
110 void
FinishTiles(void)111 FinishTiles (void)
112 {
113 	int i;
114 
115 	/* delete block tiles if loaded */
116 	for (i = 0; i < MAX_TILE; i++) {
117 		if (NULL != pixBlock[i]) {
118 			DeleteObject (pixBlock[i]);
119 		}
120 	}
121 	/* score tiles */
122 	for (i = 0; i < 2; i++) {
123 		if (NULL != pixLeds[i]) {
124 			DeleteObject (pixLeds[i]);
125 		}
126 	}
127 	for (i = 0; i < MAX_SCORE_TILES; i++) {
128 		if (NULL != pixScore[i]) {
129 			DeleteObject (pixScore[i]);
130 		}
131 	}
132 	/* explosion blocks */
133 	for (i = 0; i < MAX_EXPLOSION; i++) {
134 		if (NULL != pixExplBlock[i]) {
135 			DeleteObject (pixExplBlock[i]);
136 		}
137 	}
138 	/* remove devicerc contexts */
139 	if (NULL != hdcDst) {
140 		DeleteObject (hdcDst);
141 	}
142 	if (NULL != hdcSrc) {
143 		DeleteObject (hdcSrc);
144 	}
145 }								/* FinishTiles */
146 
147 /*
148  *
149  */
150 void
GUI_DrawBlock(int x,int y,int block)151 GUI_DrawBlock (int x, int y, int block)
152 {
153 	assert (x >= 0);
154 	assert (x < MAZE_W);
155 	assert (y >= 0);
156 #ifdef SMPF
157 	assert (y < MAZE_H + 4);
158 #else
159 	assert (y < MAZE_H + 3);
160 #endif
161 	assert (block >= -1);
162 	assert (block < MAX_TILE);
163 
164 	if (block >= 0) {
165 		blockLast[block]->left = x * BLOCK_WIDTH;
166 		blockLast[block]->top = y * BLOCK_HEIGHT;
167 		blockLast[block]->right = (x + 1) * BLOCK_WIDTH;
168 		blockLast[block]->bottom = (y + 1) * BLOCK_HEIGHT;
169 
170 		blockLast[block]++;
171 	}
172 	else {
173 		voidLast->left = x * BLOCK_WIDTH;
174 		voidLast->top = y * BLOCK_HEIGHT;
175 		voidLast->right = (x + 1) * BLOCK_WIDTH;
176 		voidLast->bottom = (y + 1) * BLOCK_HEIGHT;
177 
178 		voidLast++;
179 	}
180 }								/* GUI_DrawBlock */
181 
182 /*
183  *
184  */
185 void
GUI_DrawExplosion(int x,int y,int block)186 GUI_DrawExplosion (int x, int y, int block)
187 {
188 	assert (block >= 0);
189 	assert (block < MAX_EXPLOSION);
190 
191 	explLast[block]->left = x * BLOCK_WIDTH;
192 	explLast[block]->top = y * BLOCK_HEIGHT;
193 	explLast[block]->right = (x + 1) * BLOCK_WIDTH;
194 	explLast[block]->bottom = (y + 1) * BLOCK_HEIGHT;
195 
196 	explLast[block]++;
197 }								/* GUI_DrawExplosion */
198 
199 /*
200  *
201  */
202 void
GUI_LoadBlockRgb(int id,const char * name)203 GUI_LoadBlockRgb (int id, const char *name)
204 {
205 	assert (id >= 0);
206 	assert (id < MAX_TILE);
207 	assert (NULL == pixBlock[id]);
208 
209 	if (NULL != pixBlock[id]) {
210 		DeleteObject (pixBlock[id]);
211 	}
212 	pixBlock[id] = ReadRgbPixmap (imgPathBlock, name);
213 
214 	if (pixBlock[id] == NULL) {
215 		fprintf (stderr, " Faile to load rgb Block %s.ppm \n", name);
216 		pixBlock[id] = ReadRgbPixmap (imgPathBlock, "unknown-file");
217 	}
218 }								/* GUI_LoadBlockPpm */
219 
220 /*
221  *
222  */
223 void
GUI_LoadBlockCch(int id,const char * name,XBColor fg,XBColor bg,XBColor add)224 GUI_LoadBlockCch (int id, const char *name, XBColor fg, XBColor bg, XBColor add)
225 {
226 	assert (id >= 0);
227 	assert (id < MAX_TILE);
228 	assert (NULL == pixBlock[id]);
229 
230 	if (NULL != pixBlock[id]) {
231 		DeleteObject (pixBlock[id]);
232 	}
233 	pixBlock[id] = ReadCchPixmap (imgPathBlock, name, fg, bg, add);
234 	if (pixBlock[id] == NULL) {
235 		fprintf (stderr, " Faile to load rgb Block %s.ppm \n", name);
236 		pixBlock[id] = ReadRgbPixmap (imgPathBlock, "unknown-file");
237 	}
238 }								/* GUI_LoadBlock */
239 
240 /*
241  *
242  */
243 static void
MultiBlt(HDC hdcDst,HDC hdcSrc,RECT * rect,int n_rect,DWORD rop)244 MultiBlt (HDC hdcDst, HDC hdcSrc, RECT * rect, int n_rect, DWORD rop)
245 {
246 	int i;
247 
248 	for (i = 0; i < n_rect; i++) {
249 		BitBlt (hdcDst, rect[i].left, rect[i].top, rect[i].right - rect[i].left,
250 				rect[i].bottom - rect[i].top, hdcSrc, 0, 0, rop);
251 	}
252 }								/* MultiBlt */
253 
254 /*
255  *
256  */
257 void
GUI_FlushBlocks(void)258 GUI_FlushBlocks (void)
259 {
260 	int i;
261 	HGDIOBJ oldSrc;
262 	HGDIOBJ oldDst;
263 
264 	oldDst = SelectObject (hdcDst, pix);
265 	/* normal blocks */
266 	for (i = 0; i < MAX_TILE; i++) {
267 		if (pixBlock[i] != NULL && blockLast[i] != blockList[i]) {
268 			oldSrc = SelectObject (hdcSrc, pixBlock[i]);
269 			MultiBlt (hdcDst, hdcSrc, blockList[i], blockLast[i] - blockList[i], SRCCOPY);
270 			SelectObject (hdcSrc, oldSrc);
271 		}
272 		blockLast[i] = blockList[i];
273 	}
274 	/* void blocks */
275 	ClearRectangles (hdcDst, hdcSrc, voidList, voidLast - voidList);
276 	voidLast = voidList;
277 	/* explosion blocks */
278 	for (i = 0; i < MAX_EXPLOSION; i++) {
279 		if (pixExplBlock[i] != NULL) {
280 			if (explLast[i] != explList[i]) {
281 				oldSrc = SelectObject (hdcSrc, pixExplBlock[i]);
282 				MultiBlt (hdcDst, hdcSrc, explList[i], explLast[i] - explList[i], SRCCOPY);
283 				SelectObject (hdcSrc, oldSrc);
284 				explLast[i] = explList[i];
285 			}
286 		}
287 	}
288 	/* that's all */
289 	(void)SelectObject (hdcDst, oldDst);
290 }								/* GUI_FlushBlocks */
291 
292 void
GUI_FreeBlock(int block)293 GUI_FreeBlock (int block)
294 {
295 	assert (block >= 0);
296 	assert (block < MAX_TILE);
297 	/* delete bitmap */
298 	if (NULL != pixBlock[block]) {
299 		DeleteObject (pixBlock[block]);
300 		pixBlock[block] = NULL;
301 	}
302 }								/* GUI_FreeBlock */
303 
304 /*
305  *
306  */
307 void
GUI_InitExplosionBlocks(void)308 GUI_InitExplosionBlocks (void)
309 {
310 	HGDIOBJ oldSrc;
311 	HGDIOBJ oldDst;
312 	int i;
313 
314 	for (i = 0; i < MAX_EXPLOSION; i++) {
315 		oldSrc = SelectObject (hdcSrc, pixBlock[0]);
316 		pixExplBlock[i] = CreateCompatibleBitmap (hdcSrc, BLOCK_WIDTH, BLOCK_HEIGHT);
317 		assert (pixExplBlock[i] != NULL);
318 		oldDst = SelectObject (hdcDst, pixExplBlock[i]);
319 		/* draw floor tile into it */
320 		BitBlt (hdcDst, 0, 0, BLOCK_WIDTH, BLOCK_HEIGHT, hdcSrc, 0, 0, SRCCOPY);
321 		SelectObject (hdcSrc, oldSrc);
322 		SelectObject (hdcDst, oldDst);
323 		/* now copy explosion into it */
324 		CopyExplosion (pixExplBlock[i], i);
325 	}
326 }								/* GUI_InitExplosionBlocks */
327 
328 /*
329  *
330  */
331 void
GUI_FreeExplosionBlocks(void)332 GUI_FreeExplosionBlocks (void)
333 {
334 	int i;
335 
336 	for (i = 0; i < MAX_EXPLOSION; i++) {
337 		if (NULL != pixExplBlock[i]) {
338 			DeleteObject (pixExplBlock[i]);
339 			pixExplBlock[i] = NULL;
340 		}
341 	}
342 }								/* GUI_FreeExplosionBlocks */
343 
344 /*
345  *
346  */
347 void
GUI_LoadPlayerScoreTiles(int player,const CFGPlayerGraphics * config)348 GUI_LoadPlayerScoreTiles (int player, const CFGPlayerGraphics * config)
349 {
350 	XBColor scoreColors[NUM_PLAYER_COLORS];
351 
352 	assert (player < MAX_PLAYER);
353 	assert (config != NULL);
354 	/* copy colors */
355 	scoreColors[0] = config->helmet;
356 	scoreColors[1] = config->face;
357 	scoreColors[2] = config->handsFeet;
358 	scoreColors[3] = config->armsLegs;
359 	scoreColors[4] = COLOR_LIGHT_GOLDENROD;
360 	scoreColors[5] = COLOR_SADDLE_BROWN;
361 	scoreColors[6] = COLOR_WHITE;
362 	/* load pixmap */
363 	pixScore[SBDead + player] =
364 		ReadEpmPixmap (imgPathScore, imgFileScorePlayer[0], NUM_PLAYER_COLORS, scoreColors);
365 	pixScore[SBSick + player] =
366 		ReadEpmPixmap (imgPathScore, imgFileScorePlayer[1], NUM_PLAYER_COLORS, scoreColors);
367 	pixScore[SBPlayer + player] =
368 		ReadEpmPixmap (imgPathScore, imgFileScorePlayer[2], NUM_PLAYER_COLORS, scoreColors);
369 	pixScore[SBAbort + player] =
370 		ReadEpmPixmap (imgPathScore, imgFileScorePlayer[3], NUM_PLAYER_COLORS, scoreColors);
371 	pixScore[SBSickAbort + player] =
372 		ReadEpmPixmap (imgPathScore, imgFileScorePlayer[4], NUM_PLAYER_COLORS, scoreColors);
373 
374 }								/* GUI_LoadPlayerScoreTile */
375 
376 /*
377  *
378  */
379 void
380 //#ifdef SMPF
GUI_DrawScoreBlock(int x,int y,int block)381 GUI_DrawScoreBlock (int x, int y, int block)	// SMPF
382 	 /*#else
383 	    GUI_DrawScoreBlock (int x, int block)
384 	    #endif */
385 {
386 	HGDIOBJ oldSrc;
387 	HGDIOBJ oldDst;
388 
389 	assert (block < MAX_SCORE_TILES);
390 	assert (pixScore[block] != NULL);
391 
392 	oldSrc = SelectObject (hdcSrc, pixScore[block]);
393 	oldDst = SelectObject (hdcDst, pix);
394 	//#ifdef SMPF
395 	BitBlt (hdcDst, x * STAT_WIDTH, MAZE_H * BLOCK_HEIGHT + y * STAT_HEIGHT, STAT_WIDTH, STAT_HEIGHT, hdcSrc, 0, 0, SRCCOPY);	// SMPF
396 	/*#else
397 	   BitBlt (hdcDst, x*STAT_WIDTH, MAZE_H*BLOCK_HEIGHT, STAT_WIDTH, STAT_HEIGHT, hdcSrc, 0, 0, SRCCOPY);
398 	   #endif */
399 	SelectObject (hdcDst, oldDst);
400 	SelectObject (hdcSrc, oldSrc);
401 }								/* GUI_DrawScoreBlock */
402 
403 /*
404  *
405  */
406 void
GUI_DrawTimeLed(int x,int block)407 GUI_DrawTimeLed (int x, int block)
408 {
409 	HGDIOBJ oldSrc;
410 	HGDIOBJ oldDst;
411 
412 	assert (block < MAX_LEDS);
413 	assert (pixLeds[block] != NULL);
414 
415 	oldSrc = SelectObject (hdcSrc, pixLeds[block]);
416 	oldDst = SelectObject (hdcDst, pix);
417 #ifdef SMPF
418 	BitBlt (hdcDst, x * LED_WIDTH, MAZE_H * BLOCK_HEIGHT + STAT_HEIGHT * 2, LED_WIDTH, LED_HEIGHT,
419 			hdcSrc, 0, 0, SRCCOPY);
420 #else
421 	BitBlt (hdcDst, x * LED_WIDTH, MAZE_H * BLOCK_HEIGHT + STAT_HEIGHT, LED_WIDTH, LED_HEIGHT,
422 			hdcSrc, 0, 0, SRCCOPY);
423 #endif
424 	SelectObject (hdcDst, oldDst);
425 	SelectObject (hdcSrc, oldSrc);
426 }								/* GUI_DrawTimeLed  */
427 
428 /*
429  * end of file w32_tile.c
430  */
431