1 /* 2000-08-13T14:36:17Z
3 * graphics manipulation crap
11 unsigned int frame; /* current screen frame */
12 unsigned int screen_x; /* current scroll position */
13 unsigned int screen_y;
15 /* tiles currently on screen */
16 static unsigned int screentiles[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
17 static unsigned int crumbled_state[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
20 /* copy the entire screen to the window at the scroll position
22 * perhaps use mit-shm to speed this up
27 unsigned int x = screen_x % (MAX_BUF_XSIZE * TILEX);
28 unsigned int y = screen_y % (MAX_BUF_YSIZE * TILEY);
30 if (x < 2 * TILEX && y < 2 * TILEY)
32 BlitBitmap(screenBitmap, window, x, y,
33 SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
35 else if (x < 2 * TILEX && y >= 2 * TILEY)
37 BlitBitmap(screenBitmap, window, x, y,
38 SCR_FIELDX * TILEX, MAX_BUF_YSIZE * TILEY - y,
40 BlitBitmap(screenBitmap, window, x, 0,
41 SCR_FIELDX * TILEX, y - 2 * TILEY,
42 SX, SY + MAX_BUF_YSIZE * TILEY - y);
44 else if (x >= 2 * TILEX && y < 2 * TILEY)
46 BlitBitmap(screenBitmap, window, x, y,
47 MAX_BUF_XSIZE * TILEX - x, SCR_FIELDY * TILEY,
49 BlitBitmap(screenBitmap, window, 0, y,
50 x - 2 * TILEX, SCR_FIELDY * TILEY,
51 SX + MAX_BUF_XSIZE * TILEX - x, SY);
55 BlitBitmap(screenBitmap, window, x, y,
56 MAX_BUF_XSIZE * TILEX - x, MAX_BUF_YSIZE * TILEY - y,
58 BlitBitmap(screenBitmap, window, 0, y,
59 x - 2 * TILEX, MAX_BUF_YSIZE * TILEY - y,
60 SX + MAX_BUF_XSIZE * TILEX - x, SY);
61 BlitBitmap(screenBitmap, window, x, 0,
62 MAX_BUF_XSIZE * TILEX - x, y - 2 * TILEY,
63 SX, SY + MAX_BUF_YSIZE * TILEY - y);
64 BlitBitmap(screenBitmap, window, 0, 0,
65 x - 2 * TILEX, y - 2 * TILEY,
66 SX + MAX_BUF_XSIZE * TILEX - x, SY + MAX_BUF_YSIZE * TILEY - y);
71 /* draw differences between game tiles and screen tiles
73 * implicitly handles scrolling and restoring background under the sprites
75 * perhaps use mit-shm to speed this up
78 static void animscreen(void)
81 unsigned int left = screen_x / TILEX;
82 unsigned int top = screen_y / TILEY;
91 for (y = top; y < top + MAX_BUF_YSIZE; y++)
93 for (x = left; x < left + MAX_BUF_XSIZE; x++)
95 int dx = x % MAX_BUF_XSIZE;
96 int dy = y % MAX_BUF_YSIZE;
97 int tile = Draw[y][x];
98 struct GraphicInfo_EM *g = &graphic_info_em_object[tile][frame];
100 unsigned int crm = 0;
105 /* re-calculate crumbled state of this tile */
106 if (g->has_crumbled_graphics)
108 for (i = 0; i < 4; i++)
110 int xx = x + xy[i][0];
111 int yy = y + xy[i][1];
114 if (xx < 0 || xx >= EM_MAX_CAVE_WIDTH ||
115 yy < 0 || yy >= EM_MAX_CAVE_HEIGHT)
118 tile_next = Draw[yy][xx];
120 if (!graphic_info_em_object[tile_next][frame].has_crumbled_graphics)
125 /* re-calculate crumbled state of this tile */
126 if (tile == Xgrass ||
128 tile == Xfake_grass ||
129 tile == Xfake_grassB)
131 for (i = 0; i < 4; i++)
133 int xx = x + xy[i][0];
134 int yy = y + xy[i][1];
137 if (xx < 0 || xx >= EM_MAX_CAVE_WIDTH ||
138 yy < 0 || yy >= EM_MAX_CAVE_HEIGHT)
141 tile2 = Draw[yy][xx];
143 if (tile2 == Xgrass ||
145 tile2 == Xfake_grass ||
146 tile2 == Xfake_grassB ||
147 tile2 == Ygrass_nB ||
148 tile2 == Ygrass_eB ||
149 tile2 == Ygrass_sB ||
150 tile2 == Ygrass_wB ||
162 /* create unique graphic identifier to decide if tile must be redrawn */
163 obj = g->unique_identifier;
165 if (screentiles[dy][dx] != obj || crumbled_state[dy][dx] != crm)
167 int dst_x = dx * TILEX;
168 int dst_y = dy * TILEY;
170 if (g->width != TILEX || g->height != TILEY)
171 ClearRectangle(screenBitmap, dst_x, dst_y, TILEX, TILEY);
173 if (g->width > 0 && g->height > 0)
174 BlitBitmap(g->bitmap, screenBitmap,
175 g->src_x + g->src_offset_x, g->src_y + g->src_offset_y,
177 dst_x + g->dst_offset_x, dst_y + g->dst_offset_y);
180 /* add crumbling graphic, if needed */
183 for (i = 0; i < 4; i++)
187 int width, height, cx, cy;
189 if (i == 1 || i == 2)
191 width = g->crumbled_border_size;
193 cx = (i == 2 ? TILEX - g->crumbled_border_size : 0);
199 height = g->crumbled_border_size;
201 cy = (i == 3 ? TILEY - g->crumbled_border_size : 0);
204 if (width > 0 && height > 0)
205 BlitBitmap(g->crumbled_bitmap, screenBitmap,
206 g->crumbled_src_x + cx, g->crumbled_src_y + cy,
207 width, height, dst_x + cx, dst_y + cy);
212 /* add crumbling graphic, if needed */
215 int crumbled_border_size;
217 tile = (tile == Xgrass ? Ygrass_crumbled :
218 tile == Xdirt ? Ydirt_crumbled :
219 tile == Xfake_grass ? Yfake_grass_crumbled :
220 tile == Xfake_grassB ? Yfake_grassB_crumbled : 0);
221 g = &graphic_info_em_object[tile][frame];
222 crumbled_border_size = g->border_size;
224 for (i = 0; i < 4; i++)
228 int width, height, cx, cy;
230 if (i == 1 || i == 2)
232 width = crumbled_border_size;
234 cx = (i == 2 ? TILEX - crumbled_border_size : 0);
240 height = crumbled_border_size;
242 cy = (i == 3 ? TILEY - crumbled_border_size : 0);
245 if (width > 0 && height > 0)
246 BlitBitmap(g->bitmap, screenBitmap,
247 g->src_x + cx, g->src_y + cy, width, height,
248 dst_x + cx, dst_y + cy);
254 screentiles[dy][dx] = obj;
255 crumbled_state[dy][dx] = crm;
258 obj = map_obj[frame][tile];
260 if (screentiles[dy][dx] != obj)
262 BlitBitmap(objBitmap, screenBitmap,
263 (obj / 512) * TILEX, (obj % 512) * TILEY / 16,
264 TILEX, TILEY, dx * TILEX, dy * TILEY);
266 screentiles[dy][dx] = obj;
274 /* blit players to the screen
276 * handles transparency and movement
279 static void blitplayer(struct PLAYER *ply)
282 int old_x, old_y, new_x, new_y;
283 int src_x, src_y, dst_x, dst_y;
284 unsigned int x1, y1, x2, y2;
288 unsigned short obj, spr;
294 /* some casts to "int" are needed because of negative calculation values */
295 dx = (int)ply->x - (int)ply->oldx;
296 dy = (int)ply->y - (int)ply->oldy;
297 old_x = (int)ply->oldx + (7 - (int)frame) * dx / 8;
298 old_y = (int)ply->oldy + (7 - (int)frame) * dy / 8;
299 new_x = old_x + SIGN(dx);
300 new_y = old_y + SIGN(dy);
302 /* x1/y1 are left/top and x2/y2 are right/down part of the player movement */
303 x1 = (frame * ply->oldx + (8 - frame) * ply->x) * TILEX / 8;
304 y1 = (frame * ply->oldy + (8 - frame) * ply->y) * TILEY / 8;
308 if ((unsigned int)(x2 - screen_x) < ((MAX_BUF_XSIZE - 1) * TILEX - 1) &&
309 (unsigned int)(y2 - screen_y) < ((MAX_BUF_YSIZE - 1) * TILEY - 1))
311 struct GraphicInfo_EM *g;
314 spr = map_spr[ply->num][frame][ply->anim];
315 x1 %= MAX_BUF_XSIZE * TILEX;
316 y1 %= MAX_BUF_YSIZE * TILEY;
317 x2 %= MAX_BUF_XSIZE * TILEX;
318 y2 %= MAX_BUF_YSIZE * TILEY;
323 g = &graphic_info_em_player[ply->num][ply->anim][frame];
325 /* draw the player to current location */
326 BlitBitmap(g->bitmap, screenBitmap,
327 g->src_x, g->src_y, TILEX, TILEY,
330 /* draw the player to opposite wrap-around column */
331 BlitBitmap(g->bitmap, screenBitmap,
332 g->src_x, g->src_y, TILEX, TILEY,
333 x1 - MAX_BUF_XSIZE * TILEX, y1);
335 /* draw the player to opposite wrap-around row */
336 BlitBitmap(g->bitmap, screenBitmap,
337 g->src_x, g->src_y, TILEX, TILEY,
338 x1, y1 - MAX_BUF_YSIZE * TILEY);
340 /* draw the player to current location */
341 BlitBitmap(sprBitmap, screenBitmap,
342 (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY,
345 /* draw the player to opposite wrap-around column */
346 BlitBitmap(sprBitmap, screenBitmap,
347 (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY,
348 x1 - MAX_BUF_XSIZE * TILEX, y1);
350 /* draw the player to opposite wrap-around row */
351 BlitBitmap(sprBitmap, screenBitmap,
352 (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY,
353 x1, y1 - MAX_BUF_YSIZE * TILEY);
356 /* draw the field the player is moving from (masked over the player) */
358 obj = screentiles[y1 / TILEY][x1 / TILEX];
359 src_x = (obj / 512) * TILEX;
360 src_y = (obj % 512) * TILEY / 16;
361 dst_x = (x1 / TILEX) * TILEX;
362 dst_y = (y1 / TILEY) * TILEY;
366 tile = Draw[old_y][old_x];
367 g = &graphic_info_em_object[tile][frame];
369 if (g->width > 0 && g->height > 0)
371 src_x = g->src_x + g->src_offset_x;
372 src_y = g->src_y + g->src_offset_y;
373 dst_x = old_x % MAX_BUF_XSIZE * TILEX + g->dst_offset_x;
374 dst_y = old_y % MAX_BUF_YSIZE * TILEY + g->dst_offset_y;
376 SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
377 dst_x - src_x, dst_y - src_y);
378 BlitBitmapMasked(g->bitmap, screenBitmap,
379 src_x, src_y, g->width, g->height, dst_x, dst_y);
382 SetClipOrigin(objBitmap, objBitmap->stored_clip_gc,
383 dst_x - src_x, dst_y - src_y);
384 BlitBitmapMasked(objBitmap, screenBitmap,
385 src_x, src_y, TILEX, TILEY, dst_x, dst_y);
388 /* draw the field the player is moving to (masked over the player) */
390 obj = screentiles[y2 / TILEY][x2 / TILEX];
391 src_x = (obj / 512) * TILEX;
392 src_y = (obj % 512) * TILEY / 16;
393 dst_x = (x2 / TILEX) * TILEX;
394 dst_y = (y2 / TILEY) * TILEY;
398 tile = Draw[new_y][new_x];
399 g = &graphic_info_em_object[tile][frame];
401 if (g->width > 0 && g->height > 0)
403 src_x = g->src_x + g->src_offset_x;
404 src_y = g->src_y + g->src_offset_y;
405 dst_x = new_x % MAX_BUF_XSIZE * TILEX + g->dst_offset_x;
406 dst_y = new_y % MAX_BUF_YSIZE * TILEY + g->dst_offset_y;
408 SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
409 dst_x - src_x, dst_y - src_y);
410 BlitBitmapMasked(g->bitmap, screenBitmap,
411 src_x, src_y, g->width, g->height, dst_x, dst_y);
414 SetClipOrigin(objBitmap, objBitmap->stored_clip_gc,
415 dst_x - src_x, dst_y - src_y);
416 BlitBitmapMasked(objBitmap, screenBitmap,
417 src_x, src_y, TILEX, TILEY, dst_x, dst_y);
424 obj = screentiles[y1 / TILEY][x1 / TILEX];
425 XCopyArea(display, objmaskBitmap, spriteBitmap, spriteGC,
426 (obj / 512) * TILEX, (obj % 512) * TILEY / 16, TILEX, TILEY,
427 -(x1 % TILEX), -(y1 % TILEY));
429 obj = screentiles[y2 / TILEY][x2 / TILEX];
430 XCopyArea(display, objmaskBitmap, spriteBitmap, spriteGC,
431 (obj / 512) * TILEX, (obj % 512) * TILEY / 16, TILEX, TILEY,
432 (MAX_BUF_XSIZE * TILEX - x1) % TILEX,
433 (MAX_BUF_YSIZE * TILEY - y1) % TILEY);
435 else if (sprmaskBitmap)
437 XCopyArea(display, sprmaskBitmap, spriteBitmap, spriteGC,
438 (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY, 0, 0);
442 XFillRectangle(display, spriteBitmap, spriteGC, 0, 0, TILEX, TILEY);
445 SetClipMask(sprBitmap, sprBitmap->stored_clip_gc, spriteBitmap);
447 SetClipOrigin(sprBitmap, sprBitmap->stored_clip_gc, x, y);
448 BlitBitmapMasked(sprBitmap, screenBitmap,
449 (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY,
452 SetClipOrigin(sprBitmap, sprBitmap->stored_clip_gc,
453 x - MAX_BUF_XSIZE * TILEX, y);
454 BlitBitmapMasked(sprBitmap, screenBitmap,
455 (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY,
456 x1 - MAX_BUF_XSIZE * TILEX, y1);
458 SetClipOrigin(sprBitmap, sprBitmap->stored_clip_gc,
459 x1, y1 - MAX_BUF_YSIZE * TILEY);
460 BlitBitmapMasked(sprBitmap, screenBitmap,
461 (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY,
462 x1, y1 - MAX_BUF_YSIZE * TILEY);
464 SetClipMask(sprBitmap, sprBitmap->stored_clip_gc, None);
467 /* mark screen tiles as dirty */
468 screentiles[y1 / TILEY][x1 / TILEX] = -1;
469 screentiles[y2 / TILEY][x2 / TILEX] = -1;
473 void game_initscreen(void)
481 for (y = 0; y < MAX_BUF_YSIZE; y++)
483 for (x = 0; x < MAX_BUF_XSIZE; x++)
485 screentiles[y][x] = -1;
486 crumbled_state[y][x] = 0;
490 DrawGameDoorValues_EM(lev.required, ply1.dynamite, lev.score,
491 DISPLAY_TIME(lev.time + 4));
494 void game_animscreen(void)
498 x = (frame * ply1.oldx + (8 - frame) * ply1.x) * TILEX / 8
499 + ((SCR_FIELDX - 1) * TILEX) / 2;
500 y = (frame * ply1.oldy + (8 - frame) * ply1.y) * TILEY / 8
501 + ((SCR_FIELDY - 1) * TILEY) / 2;
503 if (x > lev.width * TILEX)
504 x = lev.width * TILEX;
505 if (y > lev.height * TILEY)
506 y = lev.height * TILEY;
508 if (x < SCR_FIELDX * TILEX)
509 x = SCR_FIELDX * TILEY;
510 if (y < SCR_FIELDY * TILEY)
511 y = SCR_FIELDY * TILEY;
513 screen_x = x - (SCR_FIELDX - 1) * TILEX;
514 screen_y = y - (SCR_FIELDY - 1) * TILEY;