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