rnd-20130916-1-src
[rocksndiamonds.git] / src / game_em / graphics.c
1 /* 2000-08-13T14:36:17Z
2  *
3  * graphics manipulation crap
4  */
5
6 #include "main_em.h"
7
8 #define MIN_SCREEN_XPOS         1
9 #define MIN_SCREEN_YPOS         1
10 #define MAX_SCREEN_XPOS         MAX(1, lev.width  - (SCR_FIELDX - 1))
11 #define MAX_SCREEN_YPOS         MAX(1, lev.height - (SCR_FIELDY - 1))
12
13 #define MIN_SCREEN_X            (MIN_SCREEN_XPOS * TILEX)
14 #define MIN_SCREEN_Y            (MIN_SCREEN_YPOS * TILEY)
15 #define MAX_SCREEN_X            (MAX_SCREEN_XPOS * TILEX)
16 #define MAX_SCREEN_Y            (MAX_SCREEN_YPOS * TILEY)
17
18 #define VALID_SCREEN_X(x)       ((x) < MIN_SCREEN_X ? MIN_SCREEN_X :    \
19                                  (x) > MAX_SCREEN_X ? MAX_SCREEN_X : (x))
20 #define VALID_SCREEN_Y(y)       ((y) < MIN_SCREEN_Y ? MIN_SCREEN_Y :    \
21                                  (y) > MAX_SCREEN_Y ? MAX_SCREEN_Y : (y))
22
23 #define PLAYER_SCREEN_X(p)      (((    frame) * ply[p].oldx +           \
24                                   (8 - frame) * ply[p].x) * TILEX / 8   \
25                                  - ((SCR_FIELDX - 1) * TILEX) / 2)
26 #define PLAYER_SCREEN_Y(p)      (((    frame) * ply[p].oldy +           \
27                                   (8 - frame) * ply[p].y) * TILEY / 8   \
28                                  - ((SCR_FIELDY - 1) * TILEY) / 2)
29
30 #define USE_EXTENDED_GRAPHICS_ENGINE            1
31
32
33 #if 0
34 int TILEX = ORIG_TILEX * ZOOM_FACTOR;
35 int TILEY = ORIG_TILEY * ZOOM_FACTOR;
36 #endif
37
38 int frame;                              /* current screen frame */
39 int screen_x, screen_y;                 /* current scroll position */
40
41 /* tiles currently on screen */
42 #if 1
43 static int screentiles[MAX_PLAYFIELD_HEIGHT + 2][MAX_PLAYFIELD_WIDTH + 2];
44 static int crumbled_state[MAX_PLAYFIELD_HEIGHT + 2][MAX_PLAYFIELD_WIDTH + 2];
45
46 static boolean redraw[MAX_PLAYFIELD_WIDTH + 2][MAX_PLAYFIELD_HEIGHT + 2];
47 #else
48 static int screentiles[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
49 static int crumbled_state[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
50
51 static boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
52 #endif
53
54 #if 0
55 #if 1
56 int centered_player_nr;
57 #else
58 static int centered_player_nr;
59 #endif
60 #endif
61
62 /* copy the entire screen to the window at the scroll position */
63
64 void BlitScreenToBitmap_EM(Bitmap *target_bitmap)
65 {
66   int x = screen_x % (MAX_BUF_XSIZE * TILEX);
67   int y = screen_y % (MAX_BUF_YSIZE * TILEY);
68   int sx, sy, sxsize, sysize;
69   int xsize = SXSIZE;
70   int ysize = SYSIZE;
71   int full_xsize = lev.width  * TILEX;
72   int full_ysize = lev.height * TILEY;
73
74   sxsize = (full_xsize < xsize ? full_xsize : xsize);
75   sysize = (full_ysize < ysize ? full_ysize : ysize);
76   sx = SX + (full_xsize < xsize ? (xsize - full_xsize) / 2 : 0);
77   sy = SY + (full_ysize < ysize ? (ysize - full_ysize) / 2 : 0);
78
79 #if 0
80   printf("::: %d, %d\n", screenBitmap->width, screenBitmap->height);
81   BlitBitmap(screenBitmap, target_bitmap, 0, 0, 544, 544, SX, SY);
82   return;
83 #endif
84
85 #if 1
86   if (x < 2 * TILEX && y < 2 * TILEY)
87   {
88     BlitBitmap(screenBitmap, target_bitmap, x, y,
89                sxsize, sysize, sx, sy);
90   }
91   else if (x < 2 * TILEX && y >= 2 * TILEY)
92   {
93     BlitBitmap(screenBitmap, target_bitmap, x, y,
94                sxsize, MAX_BUF_YSIZE * TILEY - y,
95                sx, sy);
96     BlitBitmap(screenBitmap, target_bitmap, x, 0,
97                sxsize, y - 2 * TILEY,
98                sx, sy + MAX_BUF_YSIZE * TILEY - y);
99   }
100   else if (x >= 2 * TILEX && y < 2 * TILEY)
101   {
102     BlitBitmap(screenBitmap, target_bitmap, x, y,
103                MAX_BUF_XSIZE * TILEX - x, sysize,
104                sx, sy);
105     BlitBitmap(screenBitmap, target_bitmap, 0, y,
106                x - 2 * TILEX, sysize,
107                sx + MAX_BUF_XSIZE * TILEX - x, sy);
108   }
109   else
110   {
111     BlitBitmap(screenBitmap, target_bitmap, x, y,
112                MAX_BUF_XSIZE * TILEX - x, MAX_BUF_YSIZE * TILEY - y,
113                sx, sy);
114     BlitBitmap(screenBitmap, target_bitmap, 0, y,
115                x - 2 * TILEX, MAX_BUF_YSIZE * TILEY - y,
116                sx + MAX_BUF_XSIZE * TILEX - x, sy);
117     BlitBitmap(screenBitmap, target_bitmap, x, 0,
118                MAX_BUF_XSIZE * TILEX - x, y - 2 * TILEY,
119                sx, sy + MAX_BUF_YSIZE * TILEY - y);
120     BlitBitmap(screenBitmap, target_bitmap, 0, 0,
121                x - 2 * TILEX, y - 2 * TILEY,
122                sx + MAX_BUF_XSIZE * TILEX - x, sy + MAX_BUF_YSIZE * TILEY - y);
123   }
124 #else
125   if (x < 2 * TILEX && y < 2 * TILEY)
126   {
127     BlitBitmap(screenBitmap, target_bitmap, x, y,
128                SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
129   }
130   else if (x < 2 * TILEX && y >= 2 * TILEY)
131   {
132     BlitBitmap(screenBitmap, target_bitmap, x, y,
133                SCR_FIELDX * TILEX, MAX_BUF_YSIZE * TILEY - y,
134                SX, SY);
135     BlitBitmap(screenBitmap, target_bitmap, x, 0,
136                SCR_FIELDX * TILEX, y - 2 * TILEY,
137                SX, SY + MAX_BUF_YSIZE * TILEY - y);
138   }
139   else if (x >= 2 * TILEX && y < 2 * TILEY)
140   {
141     BlitBitmap(screenBitmap, target_bitmap, x, y,
142                MAX_BUF_XSIZE * TILEX - x, SCR_FIELDY * TILEY,
143                SX, SY);
144     BlitBitmap(screenBitmap, target_bitmap, 0, y,
145                x - 2 * TILEX, SCR_FIELDY * TILEY,
146                SX + MAX_BUF_XSIZE * TILEX - x, SY);
147   }
148   else
149   {
150     BlitBitmap(screenBitmap, target_bitmap, x, y,
151                MAX_BUF_XSIZE * TILEX - x, MAX_BUF_YSIZE * TILEY - y,
152                SX, SY);
153     BlitBitmap(screenBitmap, target_bitmap, 0, y,
154                x - 2 * TILEX, MAX_BUF_YSIZE * TILEY - y,
155                SX + MAX_BUF_XSIZE * TILEX - x, SY);
156     BlitBitmap(screenBitmap, target_bitmap, x, 0,
157                MAX_BUF_XSIZE * TILEX - x, y - 2 * TILEY,
158                SX, SY + MAX_BUF_YSIZE * TILEY - y);
159     BlitBitmap(screenBitmap, target_bitmap, 0, 0,
160                x - 2 * TILEX, y - 2 * TILEY,
161                SX + MAX_BUF_XSIZE * TILEX - x, SY + MAX_BUF_YSIZE * TILEY - y);
162   }
163 #endif
164 }
165
166 void BackToFront_EM(void)
167 {
168   static int screen_x_last = -1, screen_y_last = -1;
169   static boolean scrolling_last = FALSE;
170   int left = screen_x / TILEX;
171   int top  = screen_y / TILEY;
172 #if 1
173   boolean scrolling = (screen_x != screen_x_last || screen_y != screen_y_last);
174 #else
175   boolean scrolling = (screen_x % TILEX != 0 || screen_y % TILEY != 0);
176 #endif
177   int x, y;
178
179 #if 0
180   printf("::: %d, %d\n", screen_x, screen_y);
181 #endif
182
183   SyncDisplay();
184
185   if (redraw_tiles > REDRAWTILES_THRESHOLD || scrolling || scrolling_last)
186   {
187     /* blit all (up to four) parts of the scroll buffer to the backbuffer */
188     BlitScreenToBitmap_EM(backbuffer);
189
190     /* blit the completely updated backbuffer to the window (in one blit) */
191     BlitBitmap(backbuffer, window, SX, SY, SXSIZE, SYSIZE, SX, SY);
192   }
193   else
194   {
195 #if 1
196 #if 1
197     boolean half_shifted_x = (screen_x % TILEX != 0);
198     boolean half_shifted_y = (screen_y % TILEY != 0);
199 #else
200     boolean half_shifted_x = (EVEN(SCR_FIELDX) && screen_x % TILEX != 0);
201     boolean half_shifted_y = (EVEN(SCR_FIELDY) && screen_y % TILEY != 0);
202 #endif
203
204     int sx, sy;
205 #if 0
206     int sxsize, sysize;
207 #endif
208     int xsize = SXSIZE;
209     int ysize = SYSIZE;
210     int full_xsize = lev.width  * TILEX;
211     int full_ysize = lev.height * TILEY;
212
213 #if 0
214     sxsize = (full_xsize < xsize ? full_xsize : xsize);
215     sysize = (full_ysize < ysize ? full_ysize : ysize);
216 #endif
217     sx = SX + (full_xsize < xsize ? (xsize - full_xsize) / 2 : 0);
218     sy = SY + (full_ysize < ysize ? (ysize - full_ysize) / 2 : 0);
219
220 #if 0
221 #if 1
222     printf("::: %d, %d\n", EVEN(SCR_FIELDX), screen_x);
223 #else
224     half_shifted_x = TRUE;
225     half_shifted_y = FALSE;
226 #endif
227 #endif
228
229     int x1 = 0, x2 = SCR_FIELDX - (half_shifted_x ? 0 : 1);
230     int y1 = 0, y2 = SCR_FIELDY - (half_shifted_y ? 0 : 1);
231     int scroll_xoffset = (half_shifted_x ? TILEX / 2 : 0);
232     int scroll_yoffset = (half_shifted_y ? TILEY / 2 : 0);
233
234     InitGfxClipRegion(TRUE, SX, SY, SXSIZE, SYSIZE);
235
236     for (x = x1; x <= x2; x++)
237     {
238       for (y = y1; y <= y2; y++)
239       {
240         int xx = (left + x) % MAX_BUF_XSIZE;
241         int yy = (top  + y) % MAX_BUF_YSIZE;
242
243         if (redraw[xx][yy])
244           BlitBitmap(screenBitmap, window,
245                      xx * TILEX, yy * TILEY, TILEX, TILEY,
246                      sx + x * TILEX - scroll_xoffset,
247                      sy + y * TILEY - scroll_yoffset);
248       }
249     }
250
251     InitGfxClipRegion(FALSE, -1, -1, -1, -1);
252
253 #else
254
255     for (x = 0; x < SCR_FIELDX; x++)
256     {
257       for (y = 0; y < SCR_FIELDY; y++)
258       {
259         int xx = (left + x) % MAX_BUF_XSIZE;
260         int yy = (top  + y) % MAX_BUF_YSIZE;
261
262         if (redraw[xx][yy])
263           BlitBitmap(screenBitmap, window,
264                      xx * TILEX, yy * TILEY, TILEX, TILEY,
265                      SX + x * TILEX, SY + y * TILEY);
266       }
267     }
268 #endif
269   }
270
271   FlushDisplay();
272
273   for (x = 0; x < MAX_BUF_XSIZE; x++)
274     for (y = 0; y < MAX_BUF_YSIZE; y++)
275       redraw[x][y] = FALSE;
276   redraw_tiles = 0;
277
278   screen_x_last = screen_x;
279   screen_y_last = screen_y;
280   scrolling_last = scrolling;
281 }
282
283 void blitscreen(void)
284 {
285   BackToFront_EM();
286 }
287
288 static struct GraphicInfo_EM *getObjectGraphic(int x, int y)
289 {
290   int tile = Draw[y][x];
291   struct GraphicInfo_EM *g = &graphic_info_em_object[tile][frame];
292
293   if (!game.use_native_emc_graphics_engine)
294     getGraphicSourceObjectExt_EM(g, tile, 7 - frame, x - 2, y - 2);
295
296   return g;
297 }
298
299 static struct GraphicInfo_EM *getPlayerGraphic(int player_nr, int anim)
300 {
301   struct GraphicInfo_EM *g = &graphic_info_em_player[player_nr][anim][frame];
302
303   if (!game.use_native_emc_graphics_engine)
304     getGraphicSourcePlayerExt_EM(g, player_nr, anim, 7 - frame);
305
306   return g;
307 }
308
309 static void DrawLevelField_EM(int x, int y, int sx, int sy,
310                               boolean draw_masked)
311 {
312   struct GraphicInfo_EM *g = getObjectGraphic(x, y);
313 #if NEW_TILESIZE
314   int src_x = g->src_x + g->src_offset_x * TILESIZE_VAR / TILESIZE;
315   int src_y = g->src_y + g->src_offset_y * TILESIZE_VAR / TILESIZE;
316   int dst_x = sx * TILEX + g->dst_offset_x * TILESIZE_VAR / TILESIZE;
317   int dst_y = sy * TILEY + g->dst_offset_y * TILESIZE_VAR / TILESIZE;
318   int width = g->width * TILESIZE_VAR / TILESIZE;
319   int height = g->height * TILESIZE_VAR / TILESIZE;
320 #else
321   int src_x = g->src_x + g->src_offset_x;
322   int src_y = g->src_y + g->src_offset_y;
323   int dst_x = sx * TILEX + g->dst_offset_x;
324   int dst_y = sy * TILEY + g->dst_offset_y;
325   int width = g->width;
326   int height = g->height;
327 #endif
328   int left = screen_x / TILEX;
329   int top  = screen_y / TILEY;
330
331   /* do not draw fields that are outside the visible screen area */
332   if (x < left || x >= left + MAX_BUF_XSIZE ||
333       y < top  || y >= top  + MAX_BUF_YSIZE)
334     return;
335
336   if (draw_masked)
337   {
338     if (width > 0 && height > 0)
339     {
340       SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
341                     dst_x - src_x, dst_y - src_y);
342       BlitBitmapMasked(g->bitmap, screenBitmap,
343                        src_x, src_y, width, height, dst_x, dst_y);
344     }
345   }
346   else
347   {
348     if ((width != TILEX || height != TILEY) && !g->preserve_background)
349       ClearRectangle(screenBitmap, sx * TILEX, sy * TILEY, TILEX, TILEY);
350
351     if (width > 0 && height > 0)
352       BlitBitmap(g->bitmap, screenBitmap,
353                  src_x, src_y, width, height, dst_x, dst_y);
354   }
355 }
356
357 static void DrawLevelFieldCrumbled_EM(int x, int y, int sx, int sy,
358                                       int crm, boolean draw_masked)
359 {
360 #if 1
361   struct GraphicInfo_EM *g;
362 #else
363   struct GraphicInfo_EM *g = getObjectGraphic(x, y);
364 #endif
365   int crumbled_border_size;
366   int left = screen_x / TILEX;
367   int top  = screen_y / TILEY;
368   int i;
369
370   /* do not draw fields that are outside the visible screen area */
371   if (x < left || x >= left + MAX_BUF_XSIZE ||
372       y < top  || y >= top  + MAX_BUF_YSIZE)
373     return;
374
375   if (crm == 0)         /* no crumbled edges for this tile */
376     return;
377
378 #if 1
379   g = getObjectGraphic(x, y);
380 #endif
381
382   crumbled_border_size = g->crumbled_border_size;
383
384 #if NEW_TILESIZE
385   crumbled_border_size = crumbled_border_size * TILESIZE_VAR / TILESIZE;
386 #endif
387
388 #if 0
389   if (x == 3 && y == 3 && frame == 0)
390     printf("::: %d, %d\n",
391            graphic_info_em_object[207][0].crumbled_src_x,
392            graphic_info_em_object[207][0].crumbled_src_y);
393 #endif
394
395   for (i = 0; i < 4; i++)
396   {
397     if (crm & (1 << i))
398     {
399       int width, height, cx, cy;
400
401       if (i == 1 || i == 2)
402       {
403         width = crumbled_border_size;
404         height = TILEY;
405         cx = (i == 2 ? TILEX - crumbled_border_size : 0);
406         cy = 0;
407       }
408       else
409       {
410         width = TILEX;
411         height = crumbled_border_size;
412         cx = 0;
413         cy = (i == 3 ? TILEY - crumbled_border_size : 0);
414       }
415
416       if (width > 0 && height > 0)
417       {
418         int src_x = g->crumbled_src_x + cx;
419         int src_y = g->crumbled_src_y + cy;
420         int dst_x = sx * TILEX + cx;
421         int dst_y = sy * TILEY + cy;
422
423         if (draw_masked)
424         {
425           SetClipOrigin(g->crumbled_bitmap, g->crumbled_bitmap->stored_clip_gc,
426                         dst_x - src_x, dst_y - src_y);
427           BlitBitmapMasked(g->crumbled_bitmap, screenBitmap,
428                            src_x, src_y, width, height, dst_x, dst_y);
429         }
430         else
431           BlitBitmap(g->crumbled_bitmap, screenBitmap,
432                      src_x, src_y, width, height, dst_x, dst_y);
433       }
434     }
435   }
436 }
437
438 static void DrawLevelPlayer_EM(int x1, int y1, int player_nr, int anim,
439                                boolean draw_masked)
440 {
441   struct GraphicInfo_EM *g = getPlayerGraphic(player_nr, anim);
442   int src_x = g->src_x, src_y = g->src_y;
443   int dst_x, dst_y;
444
445   /* do not draw fields that are outside the visible screen area */
446   if (x1 < screen_x - TILEX || x1 >= screen_x + MAX_BUF_XSIZE * TILEX ||
447       y1 < screen_y - TILEY || y1 >= screen_y + MAX_BUF_YSIZE * TILEY)
448     return;
449
450   x1 %= MAX_BUF_XSIZE * TILEX;
451   y1 %= MAX_BUF_YSIZE * TILEY;
452
453   if (draw_masked)
454   {
455     /* draw the player to current location */
456     dst_x = x1;
457     dst_y = y1;
458     SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
459                   dst_x - src_x, dst_y - src_y);
460     BlitBitmapMasked(g->bitmap, screenBitmap,
461                      src_x, src_y, TILEX, TILEY, dst_x, dst_y);
462
463     /* draw the player to opposite wrap-around column */
464     dst_x = x1 - MAX_BUF_XSIZE * TILEX;
465     dst_y = y1;
466     SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
467                   dst_x - src_x, dst_y - src_y);
468     BlitBitmapMasked(g->bitmap, screenBitmap,
469                      g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
470
471     /* draw the player to opposite wrap-around row */
472     dst_x = x1;
473     dst_y = y1 - MAX_BUF_YSIZE * TILEY;
474     SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
475                   dst_x - src_x, dst_y - src_y);
476     BlitBitmapMasked(g->bitmap, screenBitmap,
477                      g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
478   }
479   else
480   {
481     /* draw the player to current location */
482     dst_x = x1;
483     dst_y = y1;
484     BlitBitmap(g->bitmap, screenBitmap,
485                g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
486
487     /* draw the player to opposite wrap-around column */
488     dst_x = x1 - MAX_BUF_XSIZE * TILEX;
489     dst_y = y1;
490     BlitBitmap(g->bitmap, screenBitmap,
491                g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
492
493     /* draw the player to opposite wrap-around row */
494     dst_x = x1;
495     dst_y = y1 - MAX_BUF_YSIZE * TILEY;
496     BlitBitmap(g->bitmap, screenBitmap,
497                g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
498   }
499 }
500
501 /* draw differences between game tiles and screen tiles
502  *
503  * implicitly handles scrolling and restoring background under the sprites
504  */
505
506 static void animscreen(void)
507 {
508   int x, y, i;
509   int left = screen_x / TILEX;
510   int top  = screen_y / TILEY;
511   static int xy[4][2] =
512   {
513     { 0, -1 },
514     { -1, 0 },
515     { +1, 0 },
516     { 0, +1 }
517   };
518
519   if (!game.use_native_emc_graphics_engine)
520     for (y = 2; y < EM_MAX_CAVE_HEIGHT - 2; y++)
521       for (x = 2; x < EM_MAX_CAVE_WIDTH - 2; x++)
522         SetGfxAnimation_EM(&graphic_info_em_object[Draw[y][x]][frame],
523                            Draw[y][x], 7 - frame, x - 2, y - 2);
524
525   for (y = top; y < top + MAX_BUF_YSIZE; y++)
526   {
527     for (x = left; x < left + MAX_BUF_XSIZE; x++)
528     {
529       int sx = x % MAX_BUF_XSIZE;
530       int sy = y % MAX_BUF_YSIZE;    
531       int tile = Draw[y][x];
532       struct GraphicInfo_EM *g = &graphic_info_em_object[tile][frame];
533       int obj = g->unique_identifier;
534       int crm = 0;
535       boolean redraw_screen_tile = FALSE;
536
537       /* re-calculate crumbled state of this tile */
538       if (g->has_crumbled_graphics)
539       {
540         for (i = 0; i < 4; i++)
541         {
542           int xx = x + xy[i][0];
543           int yy = y + xy[i][1];
544           int tile_next;
545
546           if (xx < 0 || xx >= EM_MAX_CAVE_WIDTH ||
547               yy < 0 || yy >= EM_MAX_CAVE_HEIGHT)
548             continue;
549
550           tile_next = Draw[yy][xx];
551
552           if (!graphic_info_em_object[tile_next][frame].has_crumbled_graphics)
553             crm |= (1 << i);
554         }
555       }
556
557       redraw_screen_tile = (screentiles[sy][sx]    != obj ||
558                             crumbled_state[sy][sx] != crm);
559
560 #if 0
561       /* !!! TEST ONLY -- CHANGE THIS !!! */
562       if (!game.use_native_emc_graphics_engine)
563         redraw_screen_tile = TRUE;
564 #endif
565
566       /* only redraw screen tiles if they (or their crumbled state) changed */
567       if (redraw_screen_tile)
568       {
569         DrawLevelField_EM(x, y, sx, sy, FALSE);
570         DrawLevelFieldCrumbled_EM(x, y, sx, sy, crm, FALSE);
571
572         screentiles[sy][sx] = obj;
573         crumbled_state[sy][sx] = crm;
574
575         redraw[sx][sy] = TRUE;
576         redraw_tiles++;
577       }
578     }
579   }
580 }
581
582
583 /* blit players to the screen
584  *
585  * handles transparency and movement
586  */
587
588 static void blitplayer(struct PLAYER *ply)
589 {
590   int x1, y1, x2, y2;
591
592   if (!ply->alive)
593     return;
594
595   /* x1/y1 are left/top and x2/y2 are right/down part of the player movement */
596   x1 = (frame * ply->oldx + (8 - frame) * ply->x) * TILEX / 8;
597   y1 = (frame * ply->oldy + (8 - frame) * ply->y) * TILEY / 8;
598   x2 = x1 + TILEX - 1;
599   y2 = y1 + TILEY - 1;
600
601 #if 0
602   printf("::: %d, %d\n", x1, y1);
603 #endif
604
605   if ((int)(x2 - screen_x) < ((MAX_BUF_XSIZE - 1) * TILEX - 1) &&
606       (int)(y2 - screen_y) < ((MAX_BUF_YSIZE - 1) * TILEY - 1))
607   {
608     /* some casts to "int" are needed because of negative calculation values */
609     int dx = (int)ply->x - (int)ply->oldx;
610     int dy = (int)ply->y - (int)ply->oldy;
611     int old_x = (int)ply->oldx + (7 - (int)frame) * dx / 8;
612     int old_y = (int)ply->oldy + (7 - (int)frame) * dy / 8;
613     int new_x = old_x + SIGN(dx);
614     int new_y = old_y + SIGN(dy);
615     int old_sx = old_x % MAX_BUF_XSIZE;
616     int old_sy = old_y % MAX_BUF_XSIZE;
617     int new_sx = new_x % MAX_BUF_XSIZE;
618     int new_sy = new_y % MAX_BUF_XSIZE;
619 #if 0
620     int old_crm = crumbled_state[old_sy][old_sx];
621 #endif
622     int new_crm = crumbled_state[new_sy][new_sx];
623
624     /* only diggable elements can be crumbled in the classic EM engine */
625     boolean player_is_digging = (new_crm != 0);
626
627 #if 0
628     x1 %= MAX_BUF_XSIZE * TILEX;
629     y1 %= MAX_BUF_YSIZE * TILEY;
630     x2 %= MAX_BUF_XSIZE * TILEX;
631     y2 %= MAX_BUF_YSIZE * TILEY;
632 #endif
633
634     if (player_is_digging)
635     {
636 #if 0
637       /* draw the field the player is moving from (under the player) */
638       DrawLevelField_EM(old_x, old_y, old_sx, old_sy, FALSE);
639       DrawLevelFieldCrumbled_EM(old_x, old_y, old_sx, old_sy, old_crm, FALSE);
640 #endif
641
642       /* draw the field the player is moving to (under the player) */
643       DrawLevelField_EM(new_x, new_y, new_sx, new_sy, FALSE);
644       DrawLevelFieldCrumbled_EM(new_x, new_y, new_sx, new_sy, new_crm, FALSE);
645
646       /* draw the player (masked) over the element he is just digging away */
647       DrawLevelPlayer_EM(x1, y1, ply->num, ply->anim, TRUE);
648
649 #if 1
650       /* draw the field the player is moving from (masked over the player) */
651       DrawLevelField_EM(old_x, old_y, old_sx, old_sy, TRUE);
652 #endif
653     }
654     else
655     {
656       /* draw the player under the element which is on the same field */
657       DrawLevelPlayer_EM(x1, y1, ply->num, ply->anim, FALSE);
658
659       /* draw the field the player is moving from (masked over the player) */
660       DrawLevelField_EM(old_x, old_y, old_sx, old_sy, TRUE);
661
662       /* draw the field the player is moving to (masked over the player) */
663       DrawLevelField_EM(new_x, new_y, new_sx, new_sy, TRUE);
664     }
665
666     /* redraw screen tiles in the next frame (player may have left the tiles) */
667     screentiles[old_sy][old_sx] = -1;
668     screentiles[new_sy][new_sx] = -1;
669
670     /* mark screen tiles as dirty (force screen refresh with changed content) */
671     redraw[old_sx][old_sy] = TRUE;
672     redraw[new_sx][new_sy] = TRUE;
673     redraw_tiles += 2;
674   }
675 }
676
677 void game_initscreen(void)
678 {
679   int x,y;
680   int dynamite_state = ply[0].dynamite;         /* !!! ONLY PLAYER 1 !!! */
681   int all_keys_state = ply[0].keys | ply[1].keys | ply[2].keys | ply[3].keys;
682   int player_nr;
683
684   frame = 6;
685
686 #if 0
687   game.centered_player_nr = getCenteredPlayerNr_EM();
688 #endif
689
690   player_nr = (game.centered_player_nr != -1 ? game.centered_player_nr : 0);
691
692   screen_x = VALID_SCREEN_X(PLAYER_SCREEN_X(player_nr));
693   screen_y = VALID_SCREEN_Y(PLAYER_SCREEN_Y(player_nr));
694
695   for (y = 0; y < MAX_BUF_YSIZE; y++)
696   {
697     for (x = 0; x < MAX_BUF_XSIZE; x++)
698     {
699       screentiles[y][x] = -1;
700       crumbled_state[y][x] = 0;
701     }
702   }
703
704   DrawAllGameValues(lev.required, dynamite_state, lev.score,
705                     lev.time, all_keys_state);
706 }
707
708 #if 0
709 void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation)
710 {
711   boolean ffwd_delay = (tape.playing && tape.fast_forward);
712   boolean no_delay = (tape.warp_forward);
713   int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
714   int wait_delay_value = (no_delay ? 0 : frame_delay_value);
715   int jx = player->jx;
716   int jy = player->jy;
717
718   if (quick_relocation)
719   {
720     int offset = game.scroll_delay_value;
721
722     if (!IN_VIS_FIELD(SCREENX(jx), SCREENY(jy)))
723     {
724       scroll_x = (player->jx < SBX_Left  + MIDPOSX ? SBX_Left :
725                   player->jx > SBX_Right + MIDPOSX ? SBX_Right :
726                   player->jx - MIDPOSX);
727
728       scroll_y = (player->jy < SBY_Upper + MIDPOSY ? SBY_Upper :
729                   player->jy > SBY_Lower + MIDPOSY ? SBY_Lower :
730                   player->jy - MIDPOSY);
731     }
732     else
733     {
734       if ((player->MovDir == MV_LEFT  && scroll_x > jx - MIDPOSX + offset) ||
735           (player->MovDir == MV_RIGHT && scroll_x < jx - MIDPOSX - offset))
736         scroll_x = jx - MIDPOSX + (scroll_x < jx-MIDPOSX ? -offset : +offset);
737
738       if ((player->MovDir == MV_UP  && scroll_y > jy - MIDPOSY + offset) ||
739           (player->MovDir == MV_DOWN && scroll_y < jy - MIDPOSY - offset))
740         scroll_y = jy - MIDPOSY + (scroll_y < jy-MIDPOSY ? -offset : +offset);
741
742       /* don't scroll over playfield boundaries */
743       if (scroll_x < SBX_Left || scroll_x > SBX_Right)
744         scroll_x = (scroll_x < SBX_Left ? SBX_Left : SBX_Right);
745
746       /* don't scroll over playfield boundaries */
747       if (scroll_y < SBY_Upper || scroll_y > SBY_Lower)
748         scroll_y = (scroll_y < SBY_Upper ? SBY_Upper : SBY_Lower);
749     }
750
751     RedrawPlayfield(TRUE, 0,0,0,0);
752   }
753   else
754   {
755     int scroll_xx = -999, scroll_yy = -999;
756
757     ScrollScreen(NULL, SCROLL_GO_ON);   /* scroll last frame to full tile */
758
759     while (scroll_xx != scroll_x || scroll_yy != scroll_y)
760     {
761       int dx = 0, dy = 0;
762       int fx = FX, fy = FY;
763
764       scroll_xx = (player->jx < SBX_Left  + MIDPOSX ? SBX_Left :
765                    player->jx > SBX_Right + MIDPOSX ? SBX_Right :
766                    player->jx - MIDPOSX);
767
768       scroll_yy = (player->jy < SBY_Upper + MIDPOSY ? SBY_Upper :
769                    player->jy > SBY_Lower + MIDPOSY ? SBY_Lower :
770                    player->jy - MIDPOSY);
771
772       dx = (scroll_xx < scroll_x ? +1 : scroll_xx > scroll_x ? -1 : 0);
773       dy = (scroll_yy < scroll_y ? +1 : scroll_yy > scroll_y ? -1 : 0);
774
775       if (dx == 0 && dy == 0)           /* no scrolling needed at all */
776         break;
777
778       scroll_x -= dx;
779       scroll_y -= dy;
780
781       fx += dx * TILEX / 2;
782       fy += dy * TILEY / 2;
783
784       ScrollLevel(dx, dy);
785       DrawAllPlayers();
786
787       /* scroll in two steps of half tile size to make things smoother */
788       BlitBitmap(drawto_field, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
789       FlushDisplay();
790       Delay(wait_delay_value);
791
792       /* scroll second step to align at full tile size */
793       BackToFront();
794       Delay(wait_delay_value);
795     }
796
797     DrawPlayer(player);
798     BackToFront();
799     Delay(wait_delay_value);
800   }
801 }
802 #endif
803
804 static int getMaxCenterDistancePlayerNr(int center_x, int center_y)
805 {
806   int max_dx = 0, max_dy = 0;
807   int player_nr = game_em.last_moving_player;
808   int i;
809
810   for (i = 0; i < MAX_PLAYERS; i++)
811   {
812     if (ply[i].alive)
813     {
814       int sx = PLAYER_SCREEN_X(i);
815       int sy = PLAYER_SCREEN_Y(i);
816
817       if (game_em.last_player_direction[i] != MV_NONE &&
818           (ABS(sx - center_x) > max_dx ||
819            ABS(sy - center_y) > max_dy))
820       {
821         max_dx = MAX(max_dx, ABS(sx - center_x));
822         max_dy = MAX(max_dy, ABS(sy - center_y));
823
824         player_nr = i;
825       }
826     }
827   }
828
829   return player_nr;
830 }
831
832 static void setMinimalPlayerBoundaries(int *sx1, int *sy1, int *sx2, int *sy2)
833 {
834   boolean num_checked_players = 0;
835   int i;
836
837   for (i = 0; i < MAX_PLAYERS; i++)
838   {
839     if (ply[i].alive)
840     {
841       int sx = PLAYER_SCREEN_X(i);
842       int sy = PLAYER_SCREEN_Y(i);
843
844       if (num_checked_players == 0)
845       {
846         *sx1 = *sx2 = sx;
847         *sy1 = *sy2 = sy;
848       }
849       else
850       {
851         *sx1 = MIN(*sx1, sx);
852         *sy1 = MIN(*sy1, sy);
853         *sx2 = MAX(*sx2, sx);
854         *sy2 = MAX(*sy2, sy);
855       }
856
857       num_checked_players++;
858     }
859   }
860 }
861
862 boolean checkIfAllPlayersFitToScreen()
863 {
864   int sx1 = 0, sy1 = 0, sx2 = 0, sy2 = 0;
865
866   setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2);
867
868   return (sx2 - sx1 <= SCR_FIELDX * TILEX &&
869           sy2 - sy1 <= SCR_FIELDY * TILEY);
870 }
871
872 static void setScreenCenteredToAllPlayers(int *sx, int *sy)
873 {
874   int sx1 = screen_x, sy1 = screen_y, sx2 = screen_x, sy2 = screen_y;
875
876   setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2);
877
878   *sx = (sx1 + sx2) / 2;
879   *sy = (sy1 + sy2) / 2;
880 }
881
882 static void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy,
883                                               int center_x, int center_y)
884 {
885   int sx1 = center_x, sy1 = center_y, sx2 = center_x, sy2 = center_y;
886
887   setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2);
888
889   *max_dx = MAX(ABS(sx1 - center_x), ABS(sx2 - center_x));
890   *max_dy = MAX(ABS(sy1 - center_y), ABS(sy2 - center_y));
891 }
892
893 static boolean checkIfAllPlayersAreVisible(int center_x, int center_y)
894 {
895   int max_dx, max_dy;
896
897   setMaxCenterDistanceForAllPlayers(&max_dx, &max_dy, center_x, center_y);
898
899   return (max_dx <= SCR_FIELDX * TILEX / 2 &&
900           max_dy <= SCR_FIELDY * TILEY / 2);
901 }
902
903 void RedrawPlayfield_EM(boolean force_redraw)
904 {
905 #if 0
906   boolean all_players_visible = checkIfAllPlayersAreVisible();
907 #endif
908   boolean draw_new_player_location = FALSE;
909   boolean quick_relocation = setup.quick_switch;
910 #if 0
911   boolean scrolling = (screen_x % TILEX != 0 || screen_y % TILEY != 0);
912 #endif
913 #if 0
914   boolean game.set_centered_player = getSetCenteredPlayer_EM();
915   int game.centered_player_nr_next = getCenteredPlayerNr_EM();
916 #endif
917 #if 1
918   int max_center_distance_player_nr =
919     getMaxCenterDistancePlayerNr(screen_x, screen_y);
920 #else
921   int player_nr = game_em.last_moving_player;
922 #endif
923   int stepsize = TILEX / 8;
924   int offset = game.scroll_delay_value * TILEX;
925   int offset_x = offset;
926   int offset_y = offset;
927   int screen_x_old = screen_x;
928   int screen_y_old = screen_y;
929   int x, y, sx, sy;
930   int i;
931
932   if (game.set_centered_player)
933   {
934     boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen();
935
936     /* switching to "all players" only possible if all players fit to screen */
937     if (game.centered_player_nr_next == -1 && !all_players_fit_to_screen)
938     {
939       game.centered_player_nr_next = game.centered_player_nr;
940       game.set_centered_player = FALSE;
941     }
942
943     /* do not switch focus to non-existing (or non-active) player */
944     if (game.centered_player_nr_next >= 0 &&
945         !ply[game.centered_player_nr_next].alive)
946     {
947       game.centered_player_nr_next = game.centered_player_nr;
948       game.set_centered_player = FALSE;
949     }
950   }
951
952 #if 1
953   /* also allow focus switching when screen is scrolled to half tile */
954 #else
955   if (!scrolling)       /* screen currently aligned at tile position */
956 #endif
957   {
958 #if 1
959     if (game.set_centered_player)
960 #else
961     if (game.centered_player_nr != game.centered_player_nr_next)
962 #endif
963     {
964       game.centered_player_nr = game.centered_player_nr_next;
965
966       draw_new_player_location = TRUE;
967       force_redraw = TRUE;
968
969       game.set_centered_player = FALSE;
970     }
971   }
972
973   if (game.centered_player_nr == -1)
974   {
975 #if 1
976     if (draw_new_player_location || offset == 0)
977 #else
978     if (draw_new_player_location)
979 #endif
980     {
981       setScreenCenteredToAllPlayers(&sx, &sy);
982     }
983     else
984     {
985 #if 1
986       sx = PLAYER_SCREEN_X(max_center_distance_player_nr);
987       sy = PLAYER_SCREEN_Y(max_center_distance_player_nr);
988 #else
989       sx = PLAYER_SCREEN_X(game_em.last_moving_player);
990       sy = PLAYER_SCREEN_Y(game_em.last_moving_player);
991 #endif
992     }
993   }
994   else
995   {
996     sx = PLAYER_SCREEN_X(game.centered_player_nr);
997     sy = PLAYER_SCREEN_Y(game.centered_player_nr);
998   }
999
1000   if (draw_new_player_location && quick_relocation)
1001   {
1002     screen_x = VALID_SCREEN_X(sx);
1003     screen_y = VALID_SCREEN_Y(sy);
1004     screen_x_old = screen_x;
1005     screen_y_old = screen_y;
1006
1007 #if 0
1008     offset_x = 0;
1009     offset_y = 0;
1010 #endif
1011   }
1012
1013   if (draw_new_player_location && !quick_relocation)
1014   {
1015 #if 1
1016     unsigned int game_frame_delay_value = getGameFrameDelay_EM(20);
1017 #else
1018     unsigned int game_frame_delay_value = getGameFrameDelay_EM(25);
1019 #endif
1020     int wait_delay_value = game_frame_delay_value;
1021     int screen_xx = VALID_SCREEN_X(sx);
1022     int screen_yy = VALID_SCREEN_Y(sy);
1023
1024     while (screen_x != screen_xx || screen_y != screen_yy)
1025     {
1026       int dx = (screen_xx < screen_x ? +1 : screen_xx > screen_x ? -1 : 0);
1027       int dy = (screen_yy < screen_y ? +1 : screen_yy > screen_y ? -1 : 0);
1028       int dxx = 0, dyy = 0;
1029
1030       if (dx == 0 && dy == 0)           /* no scrolling needed at all */
1031         break;
1032
1033 #if 1
1034
1035       if (ABS(screen_xx - screen_x) >= TILEX)
1036       {
1037         screen_x -= dx * TILEX;
1038         dxx = dx * TILEX / 2;
1039       }
1040       else
1041       {
1042         screen_x = screen_xx;
1043         dxx = 0;
1044       }
1045
1046       if (ABS(screen_yy - screen_y) >= TILEY)
1047       {
1048         screen_y -= dy * TILEY;
1049         dyy = dy * TILEY / 2;
1050       }
1051       else
1052       {
1053         screen_y = screen_yy;
1054         dyy = 0;
1055       }
1056
1057 #else
1058
1059 #if 1
1060       if (ABS(screen_xx - screen_x) >= TILEX ||
1061           ABS(screen_yy - screen_y) >= TILEY)
1062       {
1063         screen_x -= dx * TILEX;
1064         screen_y -= dy * TILEY;
1065
1066         dxx = dx * TILEX / 2;
1067         dyy = dy * TILEY / 2;
1068       }
1069       else
1070       {
1071         screen_x = screen_xx;
1072         screen_y = screen_yy;
1073
1074         dxx = 0;
1075         dyy = 0;
1076       }
1077 #else
1078       screen_x -= dx * TILEX;
1079       screen_y -= dy * TILEY;
1080
1081       dxx += dx * TILEX / 2;
1082       dyy += dy * TILEY / 2;
1083 #endif
1084
1085 #endif
1086
1087       /* scroll in two steps of half tile size to make things smoother */
1088       screen_x += dxx;
1089       screen_y += dyy;
1090
1091       animscreen();
1092
1093       for (i = 0; i < MAX_PLAYERS; i++)
1094         blitplayer(&ply[i]);
1095
1096       blitscreen();
1097
1098       Delay(wait_delay_value);
1099
1100       /* scroll second step to align at full tile size */
1101       screen_x -= dxx;
1102       screen_y -= dyy;
1103
1104 #if 0
1105       SyncDisplay();
1106 #endif
1107
1108       animscreen();
1109
1110       for (i = 0; i < MAX_PLAYERS; i++)
1111         blitplayer(&ply[i]);
1112
1113       blitscreen();
1114
1115       Delay(wait_delay_value);
1116     }
1117
1118     screen_x_old = screen_x;
1119     screen_y_old = screen_y;
1120   }
1121
1122   if (force_redraw)
1123   {
1124     for (y = 0; y < MAX_BUF_YSIZE; y++)
1125     {
1126       for (x = 0; x < MAX_BUF_XSIZE; x++)
1127       {
1128         screentiles[y][x] = -1;
1129         crumbled_state[y][x] = 0;
1130       }
1131     }
1132   }
1133
1134   /* calculate new screen scrolling position, with regard to scroll delay */
1135   screen_x = VALID_SCREEN_X(sx + offset_x < screen_x ? sx + offset_x :
1136                             sx - offset_x > screen_x ? sx - offset_x :
1137                             screen_x);
1138   screen_y = VALID_SCREEN_Y(sy + offset_y < screen_y ? sy + offset_y :
1139                             sy - offset_y > screen_y ? sy - offset_y :
1140                             screen_y);
1141
1142 #if 0
1143   printf("::: (%d, %d) => (%d, %d) [(%d, %d), (%d, %d)] [%d, %d] [%d / %d]\n",
1144          screen_x_old, screen_y_old,
1145          screen_x, screen_y,
1146          ply[max_center_distance_player_nr].oldx,
1147          ply[max_center_distance_player_nr].x,
1148          ply[max_center_distance_player_nr].oldy,
1149          ply[max_center_distance_player_nr].y,
1150          sx, sy,
1151          ABS(screen_x - screen_x_old),
1152          ABS(screen_y - screen_y_old));
1153 #endif
1154
1155 #if 1
1156
1157 #if 1
1158   /* prevent scrolling further than double player step size when scrolling */
1159   if (ABS(screen_x - screen_x_old) > 2 * stepsize)
1160   {
1161     int dx = SIGN(screen_x - screen_x_old);
1162
1163     screen_x = screen_x_old + dx * 2 * stepsize;
1164   }
1165   if (ABS(screen_y - screen_y_old) > 2 * stepsize)
1166   {
1167     int dy = SIGN(screen_y - screen_y_old);
1168
1169     screen_y = screen_y_old + dy * 2 * stepsize;
1170   }
1171 #else
1172   /* prevent scrolling further than double player step size when scrolling */
1173   if (ABS(screen_x - screen_x_old) > 2 * stepsize ||
1174       ABS(screen_y - screen_y_old) > 2 * stepsize)
1175   {
1176     int dx = SIGN(screen_x - screen_x_old);
1177     int dy = SIGN(screen_y - screen_y_old);
1178
1179     screen_x = screen_x_old + dx * 2 * stepsize;
1180     screen_y = screen_y_old + dy * 2 * stepsize;
1181   }
1182 #endif
1183
1184 #else
1185   /* prevent scrolling further than player step size when scrolling */
1186   if (ABS(screen_x - screen_x_old) > stepsize ||
1187       ABS(screen_y - screen_y_old) > stepsize)
1188   {
1189     int dx = SIGN(screen_x - screen_x_old);
1190     int dy = SIGN(screen_y - screen_y_old);
1191
1192     screen_x = screen_x_old + dx * stepsize;
1193     screen_y = screen_y_old + dy * stepsize;
1194   }
1195 #endif
1196
1197   /* prevent scrolling away from the other players when focus on all players */
1198   if (game.centered_player_nr == -1)
1199   {
1200 #if 1
1201     /* check if all players are still visible with new scrolling position */
1202     if (checkIfAllPlayersAreVisible(screen_x_old, screen_y_old) &&
1203         !checkIfAllPlayersAreVisible(screen_x, screen_y))
1204     {
1205       /* reset horizontal scroll position to last value, if needed */
1206       if (!checkIfAllPlayersAreVisible(screen_x, screen_y_old))
1207         screen_x = screen_x_old;
1208
1209       /* reset vertical scroll position to last value, if needed */
1210       if (!checkIfAllPlayersAreVisible(screen_x_old, screen_y))
1211         screen_y = screen_y_old;
1212     }
1213 #else
1214     boolean all_players_visible = checkIfAllPlayersAreVisible();
1215
1216     if (!all_players_visible)
1217     {
1218       printf("::: not all players visible\n");
1219
1220       screen_x = screen_x_old;
1221       screen_y = screen_y_old;
1222     }
1223 #endif
1224   }
1225
1226   /* prevent scrolling (for screen correcting) if no player is moving */
1227   if (!game_em.any_player_moving)
1228   {
1229     screen_x = screen_x_old;
1230     screen_y = screen_y_old;
1231   }
1232   else
1233   {
1234     /* prevent scrolling against the players move direction */
1235 #if 0
1236     int player_nr = game_em.last_moving_player;
1237 #endif
1238     int player_nr = (game.centered_player_nr == -1 ?
1239                      max_center_distance_player_nr : game.centered_player_nr);
1240     int player_move_dir = game_em.last_player_direction[player_nr];
1241     int dx = SIGN(screen_x - screen_x_old);
1242     int dy = SIGN(screen_y - screen_y_old);
1243
1244     if ((dx < 0 && player_move_dir != MV_LEFT) ||
1245         (dx > 0 && player_move_dir != MV_RIGHT))
1246       screen_x = screen_x_old;
1247
1248     if ((dy < 0 && player_move_dir != MV_UP) ||
1249         (dy > 0 && player_move_dir != MV_DOWN))
1250       screen_y = screen_y_old;
1251   }
1252
1253   animscreen();
1254
1255   for (i = 0; i < MAX_PLAYERS; i++)
1256     blitplayer(&ply[i]);
1257
1258 #if 0
1259 #if 0
1260   SyncDisplay();
1261 #endif
1262
1263   blitscreen();
1264 #endif
1265 }
1266
1267 void game_animscreen(void)
1268 {
1269   RedrawPlayfield_EM(FALSE);
1270 }
1271
1272 void DrawGameDoorValues_EM()
1273 {
1274 #if 1
1275   int dynamite_state;
1276   int key_state;
1277 #else
1278   int dynamite_state = ply[0].dynamite;         /* !!! ONLY PLAYER 1 !!! */
1279   int key_state = ply[0].keys | ply[1].keys | ply[2].keys | ply[3].keys;
1280 #endif
1281
1282 #if 1
1283   if (game.centered_player_nr == -1)
1284   {
1285 #if 1
1286     int i;
1287
1288     dynamite_state = 0;
1289     key_state = 0;
1290
1291     for (i = 0; i < MAX_PLAYERS; i++)
1292     {
1293       dynamite_state += ply[i].dynamite;
1294       key_state |= ply[i].keys;
1295     }
1296
1297 #else
1298
1299     dynamite_state = ply[0].dynamite;           /* !!! ONLY PLAYER 1 !!! */
1300     key_state = ply[0].keys | ply[1].keys | ply[2].keys | ply[3].keys;
1301 #endif
1302   }
1303   else
1304   {
1305     int player_nr = game.centered_player_nr;
1306
1307     dynamite_state = ply[player_nr].dynamite;
1308     key_state = ply[player_nr].keys;
1309   }
1310 #endif
1311
1312 #if 1
1313   DrawAllGameValues(lev.required, dynamite_state, lev.score,
1314                     lev.time, key_state);
1315 #else
1316   DrawAllGameValues(lev.required, ply1.dynamite, lev.score,
1317                     DISPLAY_TIME(lev.time), ply1.keys | ply2.keys);
1318 #endif
1319 }