1 /***********************************************************
2 * Mirror Magic -- McDuffin's Revenge *
3 *----------------------------------------------------------*
4 * (c) 1994-2001 Artsoft Entertainment *
5 * Holger Schemel *
6 * Detmolder Strasse 189 *
7 * 33604 Bielefeld *
8 * Germany *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
11 * tools.c *
12 ***********************************************************/
13
14 #include <stdarg.h>
15
16 #ifdef __FreeBSD__
17 #include <sys/joystick.h>
18 #endif
19
20 #include "libgame/libgame.h"
21
22 #include "tools.h"
23 #include "game.h"
24 #include "events.h"
25 #include "cartoons.h"
26
27 #ifdef MSDOS
28 extern boolean wait_for_vsync;
29 #endif
30
31 /* tool button identifiers */
32 #define TOOL_CTRL_ID_YES 0
33 #define TOOL_CTRL_ID_NO 1
34 #define TOOL_CTRL_ID_CONFIRM 2
35
36 #define NUM_TOOL_BUTTONS 3
37
38 /* forward declaration for internal use */
39 static int getGraphicAnimationPhase(int, int, int);
40 static void UnmapToolButtons();
41 static void HandleToolButtons(struct GadgetInfo *);
42
43 static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
44 static int request_gadget_id = -1;
45
SetDrawtoField(int mode)46 void SetDrawtoField(int mode)
47 {
48 /* DRAW_DIRECT, DRAW_BACKBUFFER */
49
50 FX = SX;
51 FY = SY;
52 BX1 = 0;
53 BY1 = 0;
54 BX2 = SCR_FIELDX - 1;
55 BY2 = SCR_FIELDY - 1;
56 redraw_x1 = 0;
57 redraw_y1 = 0;
58
59 drawto_field = backbuffer;
60 }
61
BackToFront()62 void BackToFront()
63 {
64 int x,y;
65 DrawBuffer *buffer = drawto_field;
66
67 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
68 redraw_mask |= REDRAW_FIELD;
69
70 if (redraw_mask & REDRAW_FIELD)
71 redraw_mask &= ~REDRAW_TILES;
72
73 if (!redraw_mask)
74 return;
75
76 if (global.fps_slowdown && game_status == PLAYING)
77 {
78 static boolean last_frame_skipped = FALSE;
79 boolean skip_even_when_not_scrolling = TRUE;
80 boolean just_scrolling = (ScreenMovDir != 0);
81 boolean verbose = FALSE;
82
83 if (global.fps_slowdown_factor > 1 &&
84 (FrameCounter % global.fps_slowdown_factor) &&
85 (just_scrolling || skip_even_when_not_scrolling))
86 {
87 redraw_mask &= ~REDRAW_MAIN;
88
89 last_frame_skipped = TRUE;
90
91 if (verbose)
92 printf("FRAME SKIPPED\n");
93 }
94 else
95 {
96 if (last_frame_skipped)
97 redraw_mask |= REDRAW_FIELD;
98
99 last_frame_skipped = FALSE;
100
101 if (verbose)
102 printf("frame not skipped\n");
103 }
104 }
105
106 /* synchronize X11 graphics at this point; if we would synchronize the
107 display immediately after the buffer switching (after the XFlush),
108 this could mean that we have to wait for the graphics to complete,
109 although we could go on doing calculations for the next frame */
110
111 SyncDisplay();
112
113 if (redraw_mask & REDRAW_ALL)
114 {
115 BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
116 redraw_mask = 0;
117 }
118
119 if (redraw_mask & REDRAW_FIELD)
120 {
121 BlitBitmap(backbuffer, window,
122 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
123
124 redraw_mask &= ~REDRAW_MAIN;
125 }
126
127 if (redraw_mask & REDRAW_DOORS)
128 {
129 if (redraw_mask & REDRAW_DOOR_1)
130 BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
131 redraw_mask &= ~REDRAW_DOORS;
132 }
133
134 if (redraw_mask & REDRAW_MICROLEVEL)
135 {
136 BlitBitmap(backbuffer, window,
137 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
138 MICROLEV_XPOS, MICROLEV_YPOS);
139
140 redraw_mask &= ~REDRAW_MICROLEVEL;
141 }
142
143 if (redraw_mask & REDRAW_MICROLABEL)
144 {
145 BlitBitmap(backbuffer, window,
146 MICROLABEL_XPOS, MICROLABEL_YPOS,
147 MICROLABEL_XSIZE, MICROLABEL_YSIZE,
148 MICROLABEL_XPOS, MICROLABEL_YPOS);
149
150 redraw_mask &= ~REDRAW_MICROLABEL;
151 }
152
153 if (redraw_mask & REDRAW_TILES)
154 {
155 for(x=0; x<SCR_FIELDX; x++)
156 for(y=0; y<SCR_FIELDY; y++)
157 if (redraw[redraw_x1 + x][redraw_y1 + y])
158 BlitBitmap(buffer, window,
159 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
160 SX + x * TILEX, SY + y * TILEY);
161 }
162
163 if (redraw_mask & REDRAW_FPS) /* display frames per second */
164 {
165 char text[100];
166 char info1[100];
167
168 sprintf(info1, " (only every %d. frame)", global.fps_slowdown_factor);
169 if (!global.fps_slowdown)
170 info1[0] = '\0';
171
172 sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
173 DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
174 }
175
176 FlushDisplay();
177
178 for(x=0; x<MAX_BUF_XSIZE; x++)
179 for(y=0; y<MAX_BUF_YSIZE; y++)
180 redraw[x][y] = 0;
181 redraw_tiles = 0;
182 redraw_mask = 0;
183 }
184
FadeToFront()185 void FadeToFront()
186 {
187 #if 0
188 long fading_delay = 300;
189
190 if (setup.fading && (redraw_mask & REDRAW_FIELD))
191 {
192 #endif
193
194 #if 0
195 int x,y;
196
197 ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
198 FlushDisplay();
199
200 for(i=0;i<2*FULL_SYSIZE;i++)
201 {
202 for(y=0;y<FULL_SYSIZE;y++)
203 {
204 BlitBitmap(backbuffer, window,
205 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
206 }
207 FlushDisplay();
208 Delay(10);
209 }
210 #endif
211
212 #if 0
213 for(i=1;i<FULL_SYSIZE;i+=2)
214 BlitBitmap(backbuffer, window,
215 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
216 FlushDisplay();
217 Delay(fading_delay);
218 #endif
219
220 #if 0
221 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
222 BlitBitmapMasked(backbuffer, window,
223 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
224 REAL_SX,REAL_SY);
225 FlushDisplay();
226 Delay(fading_delay);
227
228 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
229 BlitBitmapMasked(backbuffer, window,
230 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
231 REAL_SX,REAL_SY);
232 FlushDisplay();
233 Delay(fading_delay);
234
235 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
236 BlitBitmapMasked(backbuffer, window,
237 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
238 REAL_SX,REAL_SY);
239 FlushDisplay();
240 Delay(fading_delay);
241
242 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
243 BlitBitmapMasked(backbuffer, window,
244 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
245 REAL_SX,REAL_SY);
246 FlushDisplay();
247 Delay(fading_delay);
248
249 redraw_mask &= ~REDRAW_MAIN;
250 }
251 #endif
252
253 BackToFront();
254 }
255
ClearWindow()256 void ClearWindow()
257 {
258 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
259
260 SetDrawtoField(DRAW_BACKBUFFER);
261
262 redraw_mask |= REDRAW_FIELD;
263 }
264
MarkTileDirty(int x,int y)265 void MarkTileDirty(int x, int y)
266 {
267 int xx = redraw_x1 + x;
268 int yy = redraw_y1 + y;
269
270 if (!redraw[xx][yy])
271 redraw_tiles++;
272
273 redraw[xx][yy] = TRUE;
274 redraw_mask |= REDRAW_TILES;
275 }
276
getGraphicAnimationPhase(int frames,int delay,int mode)277 static int getGraphicAnimationPhase(int frames, int delay, int mode)
278 {
279 int phase;
280
281 if (mode == ANIM_OSCILLATE)
282 {
283 int max_anim_frames = 2 * frames - 2;
284 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
285 phase = (phase < frames ? phase : max_anim_frames - phase);
286 }
287 else
288 phase = (FrameCounter % (delay * frames)) / delay;
289
290 if (mode == ANIM_REVERSE)
291 phase = -phase;
292
293 return(phase);
294 }
295
DrawGraphicAnimationExt(int x,int y,int graphic,int frames,int delay,int mode,int mask_mode)296 void DrawGraphicAnimationExt(int x, int y, int graphic,
297 int frames, int delay, int mode, int mask_mode)
298 {
299 int phase = getGraphicAnimationPhase(frames, delay, mode);
300
301 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
302 {
303 if (mask_mode == USE_MASKING)
304 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
305 else
306 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
307 }
308 }
309
DrawGraphicAnimation(int x,int y,int graphic,int frames,int delay,int mode)310 void DrawGraphicAnimation(int x, int y, int graphic,
311 int frames, int delay, int mode)
312 {
313 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
314 }
315
DrawGraphicAnimationThruMask(int x,int y,int graphic,int frames,int delay,int mode)316 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
317 int frames, int delay, int mode)
318 {
319 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
320 }
321
getGraphicSource(int graphic,int * bitmap_nr,int * x,int * y)322 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
323 {
324 if (graphic >= GFX_START_MIRRORSCREEN && graphic <= GFX_END_MIRRORSCREEN)
325 {
326 graphic -= GFX_START_MIRRORSCREEN;
327 *bitmap_nr = PIX_BACK;
328 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
329 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
330 }
331 else if (graphic >= GFX_START_MIRRORFONT && graphic <= GFX_END_MIRRORFONT)
332 {
333 graphic -= GFX_START_MIRRORFONT;
334 *bitmap_nr = PIX_BIGFONT;
335 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
336 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
337 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
338 }
339 else if (graphic >= GFX_START_MIRRORDF && graphic <= GFX_END_MIRRORDF)
340 {
341 graphic -= GFX_START_MIRRORDF;
342 *bitmap_nr = PIX_DF;
343 *x = (graphic % DF_PER_LINE) * TILEX;
344 *y = (graphic / DF_PER_LINE) * TILEY;
345 }
346 else
347 {
348 *bitmap_nr = PIX_BIGFONT;
349 *x = 0;
350 *y = 0;
351 }
352 }
353
DrawGraphic(int x,int y,int graphic)354 void DrawGraphic(int x, int y, int graphic)
355 {
356 #if DEBUG
357 if (!IN_SCR_FIELD(x,y))
358 {
359 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
360 printf("DrawGraphic(): This should never happen!\n");
361
362 #if 1
363 {
364 int i=0;
365 i=i/i;
366 }
367 #endif
368
369 return;
370 }
371 #endif
372
373 DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
374 MarkTileDirty(x, y);
375 }
376
DrawGraphicExt(DrawBuffer * d,int x,int y,int graphic)377 void DrawGraphicExt(DrawBuffer *d, int x, int y, int graphic)
378 {
379 int bitmap_nr;
380 int src_x, src_y;
381
382 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
383 BlitBitmap(pix[bitmap_nr], d, src_x, src_y, TILEX, TILEY, x, y);
384 }
385
DrawGraphicThruMask(int x,int y,int graphic)386 void DrawGraphicThruMask(int x, int y, int graphic)
387 {
388 #if DEBUG
389 if (!IN_SCR_FIELD(x,y))
390 {
391 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
392 printf("DrawGraphicThruMask(): This should never happen!\n");
393 return;
394 }
395 #endif
396
397 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
398 MarkTileDirty(x,y);
399 }
400
DrawGraphicThruMaskExt(DrawBuffer * d,int dest_x,int dest_y,int graphic)401 void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic)
402 {
403 int tile = graphic;
404 int bitmap_nr;
405 int src_x, src_y;
406 Bitmap *src_bitmap;
407 GC drawing_gc;
408
409 if (graphic == GFX_EMPTY)
410 return;
411
412 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
413 src_bitmap = pix[bitmap_nr];
414 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
415
416 if (tile_clipmask[tile] != None)
417 {
418 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
419 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
420 BlitBitmapMasked(src_bitmap, d,
421 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
422 }
423 else
424 {
425 #if DEBUG
426 #ifndef TARGET_SDL
427 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
428 #endif
429 #endif
430
431 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
432 BlitBitmapMasked(src_bitmap, d,
433 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
434 }
435 }
436
DrawMiniGraphic(int x,int y,int graphic)437 void DrawMiniGraphic(int x, int y, int graphic)
438 {
439 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
440 MarkTileDirty(x/2, y/2);
441 }
442
getMiniGraphicSource(int graphic,Bitmap ** bitmap,int * x,int * y)443 void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
444 {
445 if (graphic >= GFX_START_MIRRORSCREEN && graphic <= GFX_END_MIRRORSCREEN)
446 {
447 graphic -= GFX_START_MIRRORSCREEN;
448 *bitmap = pix[PIX_BACK];
449 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
450 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
451 }
452 else if (graphic >= GFX_START_PSEUDO && graphic <= GFX_END_PSEUDO)
453 {
454 if (graphic == GFX_DF_WALL_STEEL || graphic == GFX_DF_WALL_WOOD)
455 {
456 int graphic2 = GFX_DF_WALL_SEVERAL - GFX_START_MIRRORDF;
457 *bitmap = pix[PIX_DF];
458 *x = (graphic2 % DF_PER_LINE) * TILEX;
459 *y = (graphic2 / DF_PER_LINE) * TILEY;
460
461 if (graphic == GFX_DF_WALL_WOOD)
462 *x += MINI_TILEX;
463 }
464 else
465 {
466 int graphic2 = GFX_WALL_SEVERAL - GFX_START_MIRRORSCREEN;
467 *bitmap = pix[PIX_BACK];
468 *x = GFX_STARTX + (graphic2 % GFX_PER_LINE) * TILEX;
469 *y = GFX_STARTY + (graphic2 / GFX_PER_LINE) * TILEY;
470
471 if (graphic == GFX_WALL_WOOD || graphic == GFX_WALL_AMOEBA)
472 *x += MINI_TILEX;
473 if (graphic == GFX_WALL_ICE || graphic == GFX_WALL_AMOEBA)
474 *y += MINI_TILEY;
475 }
476 }
477 else if (graphic >= GFX_START_MIRRORFONT && graphic <= GFX_END_MIRRORFONT)
478 {
479 graphic -= GFX_START_MIRRORFONT;
480 *bitmap = pix[PIX_SMALLFONT];
481 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
482 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
483 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
484 }
485 else if (graphic >= GFX_START_MIRRORDF && graphic <= GFX_END_MIRRORDF)
486 {
487 graphic -= GFX_START_MIRRORDF;
488 *bitmap = pix[PIX_DF];
489 *x = MINI_DF_STARTX + (graphic % MINI_DF_PER_LINE) * MINI_TILEX;
490 *y = MINI_DF_STARTY + (graphic / MINI_DF_PER_LINE) * MINI_TILEY;
491 }
492 else
493 {
494 *bitmap = pix[PIX_BIGFONT];
495 *x = 0;
496 *y = 0;
497 }
498 }
499
getMicroGraphicSource(int graphic,Bitmap ** bitmap,int * x,int * y)500 void getMicroGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
501 {
502 if (graphic >= GFX_START_MIRRORSCREEN && graphic <= GFX_END_MIRRORSCREEN)
503 {
504 graphic -= GFX_START_MIRRORSCREEN;
505 *bitmap = pix[PIX_BACK];
506 *x = MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX;
507 *y = MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY;
508 }
509 else if (graphic >= GFX_START_PSEUDO && graphic <= GFX_END_PSEUDO)
510 {
511 if (graphic == GFX_DF_WALL_STEEL || graphic == GFX_DF_WALL_WOOD)
512 {
513 int graphic2 = GFX_DF_WALL_SEVERAL - GFX_START_MIRRORDF;
514 *bitmap = pix[PIX_DF];
515 *x = MICRO_DF_STARTX + (graphic2 % MICRO_DF_PER_LINE) * MICRO_TILEX;
516 *y = MICRO_DF_STARTY + (graphic2 / MICRO_DF_PER_LINE) * MICRO_TILEY;
517
518 if (graphic == GFX_DF_WALL_WOOD)
519 *x += MICRO_WALLX;
520 }
521 else
522 {
523 int graphic2 = GFX_WALL_SEVERAL - GFX_START_MIRRORSCREEN;
524 *bitmap = pix[PIX_BACK];
525 *x = MICRO_GFX_STARTX + (graphic2 % MICRO_GFX_PER_LINE) * MICRO_TILEX;
526 *y = MICRO_GFX_STARTY + (graphic2 / MICRO_GFX_PER_LINE) * MICRO_TILEY;
527
528 if (graphic == GFX_WALL_WOOD || graphic == GFX_WALL_AMOEBA)
529 *x += MICRO_WALLX;
530 if (graphic == GFX_WALL_ICE || graphic == GFX_WALL_AMOEBA)
531 *y += MICRO_WALLY;
532 }
533 }
534 else if (graphic >= GFX_START_MIRRORFONT && graphic <= GFX_END_MIRRORFONT)
535 {
536 graphic -= GFX_START_MIRRORFONT;
537 *bitmap = pix[PIX_DF];
538 *x = MICRO_FONT_STARTX + (graphic % MICRO_FONT_PER_LINE) * MICRO_TILEX;
539 *y = MICRO_FONT_STARTY + (graphic / MICRO_FONT_PER_LINE) * MICRO_TILEY;
540 }
541 else if (graphic >= GFX_START_MIRRORDF && graphic <= GFX_END_MIRRORDF)
542 {
543 graphic -= GFX_START_MIRRORDF;
544 *bitmap = pix[PIX_DF];
545 *x = MICRO_DF_STARTX + (graphic % MICRO_DF_PER_LINE) * MICRO_TILEX;
546 *y = MICRO_DF_STARTY + (graphic / MICRO_DF_PER_LINE) * MICRO_TILEY;
547 }
548 else
549 {
550 *bitmap = pix[PIX_BIGFONT];
551 *x = 0;
552 *y = 0;
553 }
554 }
555
DrawMiniGraphicExt(DrawBuffer * d,int x,int y,int graphic)556 void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
557 {
558 Bitmap *bitmap;
559 int src_x, src_y;
560
561 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
562 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
563 }
564
DrawGraphicShifted(int x,int y,int dx,int dy,int graphic,int cut_mode,int mask_mode)565 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
566 int cut_mode, int mask_mode)
567 {
568 int width = TILEX, height = TILEY;
569 int cx = 0, cy = 0;
570 int src_x, src_y, dest_x, dest_y;
571 int tile = graphic;
572 int bitmap_nr;
573 Bitmap *src_bitmap;
574 GC drawing_gc;
575
576 if (graphic < 0)
577 {
578 DrawGraphic(x, y, graphic);
579 return;
580 }
581
582 if (dx || dy) /* Verschiebung der Grafik? */
583 {
584 if (x < BX1) /* Element kommt von links ins Bild */
585 {
586 x = BX1;
587 width = dx;
588 cx = TILEX - dx;
589 dx = 0;
590 }
591 else if (x > BX2) /* Element kommt von rechts ins Bild */
592 {
593 x = BX2;
594 width = -dx;
595 dx = TILEX + dx;
596 }
597 else if (x==BX1 && dx < 0) /* Element verl��t links das Bild */
598 {
599 width += dx;
600 cx = -dx;
601 dx = 0;
602 }
603 else if (x==BX2 && dx > 0) /* Element verl��t rechts das Bild */
604 width -= dx;
605 else if (dx) /* allg. Bewegung in x-Richtung */
606 MarkTileDirty(x + SIGN(dx), y);
607
608 if (y < BY1) /* Element kommt von oben ins Bild */
609 {
610 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
611 return;
612
613 y = BY1;
614 height = dy;
615 cy = TILEY - dy;
616 dy = 0;
617 }
618 else if (y > BY2) /* Element kommt von unten ins Bild */
619 {
620 y = BY2;
621 height = -dy;
622 dy = TILEY + dy;
623 }
624 else if (y==BY1 && dy < 0) /* Element verl��t oben das Bild */
625 {
626 height += dy;
627 cy = -dy;
628 dy = 0;
629 }
630 else if (dy > 0 && cut_mode == CUT_ABOVE)
631 {
632 if (y == BY2) /* Element unterhalb des Bildes */
633 return;
634
635 height = dy;
636 cy = TILEY - dy;
637 dy = TILEY;
638 MarkTileDirty(x, y + 1);
639 } /* Element verl��t unten das Bild */
640 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
641 height -= dy;
642 else if (dy) /* allg. Bewegung in y-Richtung */
643 MarkTileDirty(x, y + SIGN(dy));
644 }
645
646 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
647 src_bitmap = pix[bitmap_nr];
648 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
649
650 src_x += cx;
651 src_y += cy;
652
653 dest_x = FX + x * TILEX + dx;
654 dest_y = FY + y * TILEY + dy;
655
656 #if DEBUG
657 if (!IN_SCR_FIELD(x,y))
658 {
659 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
660 printf("DrawGraphicShifted(): This should never happen!\n");
661 return;
662 }
663 #endif
664
665 if (mask_mode == USE_MASKING)
666 {
667 if (tile_clipmask[tile] != None)
668 {
669 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
670 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
671 BlitBitmapMasked(src_bitmap, drawto_field,
672 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
673 }
674 else
675 {
676 #if DEBUG
677 #ifndef TARGET_SDL
678 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
679 #endif
680 #endif
681
682 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
683 BlitBitmapMasked(src_bitmap, drawto_field,
684 src_x, src_y, width, height, dest_x, dest_y);
685 }
686 }
687 else
688 BlitBitmap(pix[bitmap_nr], drawto_field,
689 src_x, src_y, width, height, dest_x, dest_y);
690
691 MarkTileDirty(x,y);
692 }
693
DrawGraphicShiftedThruMask(int x,int y,int dx,int dy,int graphic,int cut_mode)694 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
695 int cut_mode)
696 {
697 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
698 }
699
DrawScreenElementExt(int x,int y,int dx,int dy,int element,int cut_mode,int mask_mode)700 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
701 int cut_mode, int mask_mode)
702 {
703 int ux = LEVELX(x), uy = LEVELY(y);
704 int graphic = el2gfx(element);
705 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
706 int phase2 = phase8 / 4;
707 int dir = MovDir[ux][uy];
708
709 if (element == EL_PACMAN)
710 {
711 graphic += 4 * !phase2;
712
713 if (dir == MV_UP)
714 graphic += 1;
715 else if (dir == MV_LEFT)
716 graphic += 2;
717 else if (dir == MV_DOWN)
718 graphic += 3;
719 }
720
721 if (dx || dy)
722 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
723 else if (mask_mode == USE_MASKING)
724 DrawGraphicThruMask(x, y, graphic);
725 else
726 DrawGraphic(x, y, graphic);
727 }
728
DrawLevelElementExt(int x,int y,int dx,int dy,int element,int cut_mode,int mask_mode)729 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
730 int cut_mode, int mask_mode)
731 {
732 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
733 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
734 cut_mode, mask_mode);
735 }
736
DrawScreenElementShifted(int x,int y,int dx,int dy,int element,int cut_mode)737 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
738 int cut_mode)
739 {
740 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
741 }
742
DrawLevelElementShifted(int x,int y,int dx,int dy,int element,int cut_mode)743 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
744 int cut_mode)
745 {
746 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
747 }
748
DrawScreenElementThruMask(int x,int y,int element)749 void DrawScreenElementThruMask(int x, int y, int element)
750 {
751 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
752 }
753
DrawLevelElementThruMask(int x,int y,int element)754 void DrawLevelElementThruMask(int x, int y, int element)
755 {
756 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
757 }
758
DrawLevelFieldThruMask(int x,int y)759 void DrawLevelFieldThruMask(int x, int y)
760 {
761 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
762 }
763
DrawScreenElement(int x,int y,int element)764 void DrawScreenElement(int x, int y, int element)
765 {
766 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
767 }
768
DrawLevelElement(int x,int y,int element)769 void DrawLevelElement(int x, int y, int element)
770 {
771 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
772 DrawScreenElement(SCREENX(x), SCREENY(y), element);
773 }
774
DrawScreenField(int x,int y)775 void DrawScreenField(int x, int y)
776 {
777 int element = Feld[x][y];
778
779 if (!IN_LEV_FIELD(x, y))
780 return;
781
782 if (IS_MOVING(x, y))
783 {
784 int horiz_move = (MovDir[x][y] == MV_LEFT || MovDir[x][y] == MV_RIGHT);
785
786 DrawScreenElement(x, y, EL_EMPTY);
787
788 if (horiz_move)
789 DrawScreenElementShifted(x, y, MovPos[x][y], 0, element, NO_CUTTING);
790 else
791 DrawScreenElementShifted(x, y, 0, MovPos[x][y], element, NO_CUTTING);
792 }
793 else if (IS_BLOCKED(x, y))
794 {
795 int oldx, oldy;
796 int sx, sy;
797 int horiz_move;
798
799 Blocked2Moving(x, y, &oldx, &oldy);
800 sx = SCREENX(oldx);
801 sy = SCREENY(oldy);
802 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
803 MovDir[oldx][oldy] == MV_RIGHT);
804
805 DrawScreenElement(x, y, EL_EMPTY);
806 element = Feld[oldx][oldy];
807
808 if (horiz_move)
809 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
810 else
811 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,NO_CUTTING);
812 }
813 else if (IS_DRAWABLE(element))
814 DrawScreenElement(x, y, element);
815 else
816 DrawScreenElement(x, y, EL_EMPTY);
817 }
818
DrawLevelField(int x,int y)819 void DrawLevelField(int x, int y)
820 {
821 DrawScreenField(x, y);
822 }
823
DrawMiniElement(int x,int y,int element)824 void DrawMiniElement(int x, int y, int element)
825 {
826 int graphic;
827
828 if (!element)
829 {
830 DrawMiniGraphic(x, y, GFX_EMPTY);
831 return;
832 }
833
834 graphic = el2gfx(element);
835 DrawMiniGraphic(x, y, graphic);
836 }
837
DrawMiniElementOrWall(int sx,int sy,int scroll_x,int scroll_y)838 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
839 {
840 int x = sx + scroll_x, y = sy + scroll_y;
841
842 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
843 DrawMiniElement(sx, sy, EL_EMPTY);
844 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
845 DrawMiniElement(sx, sy, Feld[x][y]);
846 }
847
848
849 #if 0
850 void DrawMicroElement(int xpos, int ypos, int element)
851 {
852 int graphic;
853
854 if (element == EL_LEERRAUM)
855 return;
856
857 graphic = el2gfx(element);
858
859 BlitBitmap(pix[PIX_BACK], drawto,
860 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
861 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
862 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
863 }
864
865 void DrawLevel()
866 {
867 int x,y;
868
869 ClearWindow();
870
871 for(x=BX1; x<=BX2; x++)
872 for(y=BY1; y<=BY2; y++)
873 DrawScreenField(x, y);
874
875 redraw_mask |= REDRAW_FIELD;
876 }
877 #endif
878
DrawField(int x,int y)879 void DrawField(int x, int y)
880 {
881 int element = Feld[x][y];
882
883 DrawElement(x, y, element);
884 }
885
DrawLevel()886 void DrawLevel()
887 {
888 int x,y;
889
890 ClearWindow();
891
892 for (x=0; x<lev_fieldx; x++)
893 for (y=0; y<lev_fieldy; y++)
894 DrawField(x, y);
895
896 redraw_mask |= REDRAW_FIELD;
897 }
898
DrawWallsExt(int x,int y,int element,int draw_mask)899 void DrawWallsExt(int x, int y, int element, int draw_mask)
900 {
901 Bitmap *bitmap;
902 int graphic = el2gfx(WALL_BASE(element));
903 int gx, gy;
904 int i;
905
906 getMiniGraphicSource(graphic, &bitmap, &gx, &gy);
907
908 if (game_status != LEVELED || !editor.draw_walls_masked)
909 DrawGraphic(x, y, GFX_EMPTY);
910
911 /*
912 if (IS_WALL_WOOD(element) || IS_WALL_AMOEBA(element) ||
913 IS_DF_WALL_WOOD(element))
914 gx += MINI_TILEX;
915 if (IS_WALL_ICE(element) || IS_WALL_AMOEBA(element))
916 gy += MINI_TILEY;
917 */
918
919 for(i=0; i<4; i++)
920 {
921 int dest_x = SX + x * TILEX + MINI_TILEX * (i % 2);
922 int dest_y = SY + y * TILEY + MINI_TILEY * (i / 2);
923
924 if (!((1 << i) & draw_mask))
925 continue;
926
927 if (element & (1 << i))
928 BlitBitmap(bitmap, drawto, gx, gy, MINI_TILEX, MINI_TILEY,
929 dest_x, dest_y);
930 else if (!editor.draw_walls_masked)
931 ClearRectangle(drawto, dest_x, dest_y, MINI_TILEX, MINI_TILEY);
932 }
933
934 MarkTileDirty(x, y);
935 }
936
DrawWalls(int x,int y,int element)937 void DrawWalls(int x, int y, int element)
938 {
939 DrawWallsExt(x, y, element, HIT_MASK_ALL);
940 }
941
DrawWallsAnimation(int x,int y,int element,int phase,int bit_mask)942 void DrawWallsAnimation(int x, int y, int element, int phase, int bit_mask)
943 {
944 int graphic = GFX_WALL_SEVERAL;
945 int graphic_anim = graphic + (phase + 1) / 2;
946 int dx = (IS_WALL_AMOEBA(element) ? MINI_TILEX : 0);
947 int dy = MINI_TILEY;
948 int dx_anim = dx;
949 int dy_anim = ((phase + 1) % 2) * MINI_TILEY;
950 int i;
951
952 if (phase == 0)
953 {
954 DrawWalls(x, y, element);
955 return;
956 }
957
958 for(i=0; i<4; i++)
959 {
960 if (element & (1 << i))
961 {
962 int dest_x = SX + x * TILEX + MINI_TILEX * (i % 2);
963 int dest_y = SY + y * TILEY + MINI_TILEY * (i / 2);
964 int gx, gy;
965
966 if (bit_mask & (1 << i))
967 {
968 gx = SX + ((graphic_anim) % GFX_PER_LINE) * TILEX + dx_anim;
969 gy = SY + ((graphic_anim) / GFX_PER_LINE) * TILEY + dy_anim;
970 }
971 else
972 {
973 gx = SX + (graphic % GFX_PER_LINE) * TILEX + dx;
974 gy = SY + (graphic / GFX_PER_LINE) * TILEY + dy;
975 }
976
977 BlitBitmap(pix[PIX_BACK], drawto, gx, gy, MINI_TILEX, MINI_TILEY,
978 dest_x, dest_y);
979 }
980 }
981
982 MarkTileDirty(x, y);
983 }
984
DrawElement(int x,int y,int element)985 void DrawElement(int x, int y, int element)
986 {
987 if (element == EL_EMPTY)
988 DrawGraphic(x, y, GFX_EMPTY);
989 else if (IS_WALL(element))
990 DrawWalls(x, y, element);
991 #if 0
992 else if (IS_WALL_CHANGING(element) && IS_WALL_CHANGING(Feld[x][y]))
993 {
994 int wall_element = Feld[x][y] - EL_WALL_CHANGING + Store[x][y];
995
996 DrawWalls(x, y, wall_element);
997 }
998 #endif
999 else if (element == EL_PACMAN)
1000 DrawLevelField(x, y);
1001 else
1002 DrawGraphic(x, y, el2gfx(element));
1003 }
1004
DrawMicroWalls(int x,int y,int element)1005 void DrawMicroWalls(int x, int y, int element)
1006 {
1007 Bitmap *bitmap;
1008 int graphic = el2gfx(WALL_BASE(element));
1009 int gx, gy;
1010 int i;
1011
1012 getMicroGraphicSource(graphic, &bitmap, &gx, &gy);
1013
1014 for (i=0; i<4; i++)
1015 {
1016 int xpos = MICROLEV_XPOS + x * MICRO_TILEX + MICRO_WALLX * (i % 2);
1017 int ypos = MICROLEV_YPOS + y * MICRO_TILEY + MICRO_WALLY * (i / 2);
1018
1019 if (element & (1 << i))
1020 BlitBitmap(bitmap, drawto, gx, gy, MICRO_WALLX, MICRO_WALLY, xpos, ypos);
1021 else
1022 ClearRectangle(drawto, xpos, ypos, MICRO_WALLX, MICRO_WALLY);
1023 }
1024 }
1025
DrawMicroElement(int x,int y,int element)1026 void DrawMicroElement(int x, int y, int element)
1027 {
1028 Bitmap *bitmap;
1029 int graphic = el2gfx(element);
1030 int gx, gy;
1031
1032 if (element == EL_EMPTY)
1033 return;
1034
1035 if (IS_WALL(element))
1036 {
1037 DrawMicroWalls(x, y, element);
1038 return;
1039 }
1040
1041 getMicroGraphicSource(graphic, &bitmap, &gx, &gy);
1042
1043 BlitBitmap(bitmap, drawto, gx, gy, MICRO_TILEX, MICRO_TILEY,
1044 MICROLEV_XPOS + x * MICRO_TILEX, MICROLEV_YPOS + y * MICRO_TILEY);
1045 }
1046
DrawMicroLevelExt(int xpos,int ypos)1047 void DrawMicroLevelExt(int xpos, int ypos)
1048 {
1049 int x,y;
1050
1051 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1052
1053 for (x=0; x<STD_LEV_FIELDX; x++)
1054 for (y=0; y<STD_LEV_FIELDY; y++)
1055 DrawMicroElement(x, y, Ur[x][y]);
1056
1057 redraw_mask |= REDRAW_MICROLEVEL;
1058 }
1059
DrawMiniLevel(int size_x,int size_y,int scroll_x,int scroll_y)1060 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1061 {
1062 int x,y;
1063
1064 for(x=0; x<size_x; x++)
1065 for(y=0; y<size_y; y++)
1066 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1067
1068 redraw_mask |= REDRAW_FIELD;
1069 }
1070
1071 #define MICROLABEL_EMPTY 0
1072 #define MICROLABEL_LEVEL_NAME 1
1073 #define MICROLABEL_CREATED_BY 2
1074 #define MICROLABEL_LEVEL_AUTHOR 3
1075 #define MICROLABEL_IMPORTED_FROM 4
1076 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1077
1078 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1079
DrawMicroLevelLabelExt(int mode)1080 static void DrawMicroLevelLabelExt(int mode)
1081 {
1082 char label_text[MAX_MICROLABEL_SIZE + 1];
1083
1084 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1085
1086 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1087 mode == MICROLABEL_CREATED_BY ? "created by" :
1088 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1089 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1090 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1091 leveldir_current->imported_from : ""),
1092 MAX_MICROLABEL_SIZE);
1093 label_text[MAX_MICROLABEL_SIZE] = '\0';
1094
1095 if (strlen(label_text) > 0)
1096 {
1097 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1098 int lypos = MICROLABEL_YPOS;
1099
1100 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1101 }
1102
1103 redraw_mask |= REDRAW_MICROLABEL;
1104 }
1105
DrawMicroLevel(int xpos,int ypos,boolean restart)1106 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1107 {
1108 static unsigned long scroll_delay = 0;
1109 static unsigned long label_delay = 0;
1110 static int label_state, label_counter;
1111
1112 if (restart)
1113 {
1114 label_state = 1;
1115 label_counter = 0;
1116
1117 DrawMicroLevelExt(xpos, ypos);
1118 DrawMicroLevelLabelExt(label_state);
1119
1120 /* initialize delay counters */
1121 DelayReached(&scroll_delay, 0);
1122 DelayReached(&label_delay, 0);
1123
1124 return;
1125 }
1126
1127 /* redraw micro level label, if needed */
1128 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1129 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1130 strcmp(level.author, leveldir_current->name) != 0 &&
1131 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1132 {
1133 int max_label_counter = 23;
1134
1135 if (leveldir_current->imported_from != NULL)
1136 max_label_counter += 14;
1137
1138 label_counter = (label_counter + 1) % max_label_counter;
1139 label_state = (label_counter >= 0 && label_counter <= 7 ?
1140 MICROLABEL_LEVEL_NAME :
1141 label_counter >= 9 && label_counter <= 12 ?
1142 MICROLABEL_CREATED_BY :
1143 label_counter >= 14 && label_counter <= 21 ?
1144 MICROLABEL_LEVEL_AUTHOR :
1145 label_counter >= 23 && label_counter <= 26 ?
1146 MICROLABEL_IMPORTED_FROM :
1147 label_counter >= 28 && label_counter <= 35 ?
1148 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1149 DrawMicroLevelLabelExt(label_state);
1150 }
1151 }
1152
REQ_in_range(int x,int y)1153 int REQ_in_range(int x, int y)
1154 {
1155 if (y > DY+249 && y < DY+278)
1156 {
1157 if (x > DX+1 && x < DX+48)
1158 return 1;
1159 else if (x > DX+51 && x < DX+98)
1160 return 2;
1161 }
1162 return 0;
1163 }
1164
Request(char * text,unsigned int req_state)1165 boolean Request(char *text, unsigned int req_state)
1166 {
1167 int mx, my, ty, result = -1;
1168 unsigned int old_door_state;
1169
1170 old_door_state = GetDoorState();
1171
1172 UnmapAllGadgets();
1173
1174 CloseDoor(DOOR_CLOSE_1);
1175
1176 /* save old door content */
1177 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1178 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1179 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1180
1181 /* clear door drawing field */
1182 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1183
1184 /* write text for request */
1185 for(ty=0; ty<13; ty++)
1186 {
1187 int tx, tl, tc;
1188 char txt[256];
1189
1190 if (!*text)
1191 break;
1192
1193 for(tl=0,tx=0; tx<7; tl++,tx++)
1194 {
1195 tc = *(text + tx);
1196 if (!tc || tc == 32)
1197 break;
1198 }
1199 if (!tl)
1200 {
1201 text++;
1202 ty--;
1203 continue;
1204 }
1205 sprintf(txt, text);
1206 txt[tl] = 0;
1207 DrawTextExt(drawto,
1208 DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1209 txt, FS_SMALL, FC_YELLOW);
1210 text += tl + (tc == 32 ? 1 : 0);
1211 }
1212
1213 if (req_state & REQ_ASK)
1214 {
1215 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1216 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1217 }
1218 else if (req_state & REQ_CONFIRM)
1219 {
1220 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1221 }
1222
1223 /* copy request gadgets to door backbuffer */
1224 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1225 DX, DY, DXSIZE, DYSIZE,
1226 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1227
1228 OpenDoor(DOOR_OPEN_1);
1229
1230 #if 0
1231 ClearEventQueue();
1232 #endif
1233
1234 if (!(req_state & REQUEST_WAIT_FOR))
1235 return(FALSE);
1236
1237 if (game_status != MAINMENU)
1238 InitAnimation();
1239
1240 button_status = MB_RELEASED;
1241
1242 request_gadget_id = -1;
1243
1244 while(result < 0)
1245 {
1246 if (PendingEvent())
1247 {
1248 Event event;
1249
1250 NextEvent(&event);
1251
1252 switch(event.type)
1253 {
1254 case EVENT_BUTTONPRESS:
1255 case EVENT_BUTTONRELEASE:
1256 case EVENT_MOTIONNOTIFY:
1257 {
1258 if (event.type == EVENT_MOTIONNOTIFY)
1259 {
1260 if (!PointerInWindow(window))
1261 continue; /* window and pointer are on different screens */
1262
1263 if (!button_status)
1264 continue;
1265
1266 motion_status = TRUE;
1267 mx = ((MotionEvent *) &event)->x;
1268 my = ((MotionEvent *) &event)->y;
1269 }
1270 else
1271 {
1272 motion_status = FALSE;
1273 mx = ((ButtonEvent *) &event)->x;
1274 my = ((ButtonEvent *) &event)->y;
1275 if (event.type == EVENT_BUTTONPRESS)
1276 button_status = ((ButtonEvent *) &event)->button;
1277 else
1278 button_status = MB_RELEASED;
1279 }
1280
1281 /* this sets 'request_gadget_id' */
1282 HandleGadgets(mx, my, button_status);
1283
1284 switch(request_gadget_id)
1285 {
1286 case TOOL_CTRL_ID_YES:
1287 result = TRUE;
1288 break;
1289 case TOOL_CTRL_ID_NO:
1290 result = FALSE;
1291 break;
1292 case TOOL_CTRL_ID_CONFIRM:
1293 result = TRUE | FALSE;
1294 break;
1295
1296 default:
1297 break;
1298 }
1299
1300 break;
1301 }
1302
1303 case EVENT_KEYPRESS:
1304 switch(GetEventKey((KeyEvent *)&event, TRUE))
1305 {
1306 case KSYM_Return:
1307 result = 1;
1308 break;
1309
1310 case KSYM_Escape:
1311 result = 0;
1312 break;
1313
1314 default:
1315 break;
1316 }
1317 break;
1318
1319 case EVENT_KEYRELEASE:
1320 key_joystick_mapping = 0;
1321 break;
1322
1323 default:
1324 HandleOtherEvents(&event);
1325 break;
1326 }
1327 }
1328
1329 DoAnimation();
1330
1331 /* don't eat all CPU time */
1332 Delay(10);
1333 }
1334
1335 if (game_status != MAINMENU)
1336 StopAnimation();
1337
1338 UnmapToolButtons();
1339
1340 if (!(req_state & REQ_STAY_OPEN))
1341 {
1342 CloseDoor(DOOR_CLOSE_1);
1343
1344 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1345 {
1346 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1347 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1348 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1349 OpenDoor(DOOR_OPEN_1);
1350 }
1351 }
1352
1353 RemapAllGadgets();
1354
1355 return(result);
1356 }
1357
OpenDoor(unsigned int door_state)1358 unsigned int OpenDoor(unsigned int door_state)
1359 {
1360 unsigned int new_door_state;
1361
1362 if (door_state & DOOR_COPY_BACK)
1363 {
1364 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1365 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
1366 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1367 door_state &= ~DOOR_COPY_BACK;
1368 }
1369
1370 new_door_state = MoveDoor(door_state);
1371
1372 return(new_door_state);
1373 }
1374
CloseDoor(unsigned int door_state)1375 unsigned int CloseDoor(unsigned int door_state)
1376 {
1377 unsigned int new_door_state;
1378
1379 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
1380 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1381
1382 new_door_state = MoveDoor(door_state);
1383
1384 return(new_door_state);
1385 }
1386
GetDoorState()1387 unsigned int GetDoorState()
1388 {
1389 return(MoveDoor(DOOR_GET_STATE));
1390 }
1391
MoveDoor(unsigned int door_state)1392 unsigned int MoveDoor(unsigned int door_state)
1393 {
1394 static int door1 = DOOR_OPEN_1;
1395 static int door2 = DOOR_CLOSE_2;
1396 static unsigned long door_delay = 0;
1397 int x, start, stepsize = 2;
1398 unsigned long door_delay_value = stepsize * 5;
1399
1400 /* there is no second door */
1401 door_state &= ~DOOR_ACTION_2;
1402
1403 if (door_state == DOOR_GET_STATE)
1404 return(door1 | door2);
1405
1406 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1407 door_state &= ~DOOR_OPEN_1;
1408 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1409 door_state &= ~DOOR_CLOSE_1;
1410 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1411 door_state &= ~DOOR_OPEN_2;
1412 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1413 door_state &= ~DOOR_CLOSE_2;
1414
1415 if (setup.quick_doors)
1416 {
1417 stepsize = 20;
1418 door_delay_value = 0;
1419 StopSound(SND_OEFFNEN);
1420 }
1421
1422 if (door_state & DOOR_ACTION)
1423 {
1424 if (door_state & DOOR_ACTION_1)
1425 {
1426 if (door_state & DOOR_OPEN_1)
1427 {
1428 BlitBitmap(pix[PIX_DOOR], pix[PIX_DOOR], 104,136, 8,8, 146,136);
1429 BlitBitmap(pix[PIX_DOOR], window, 104,136, 8,8, DX + 46,DY + 136);
1430 redraw_mask &= ~REDRAW_DOOR_1;
1431
1432 if (!setup.quick_doors)
1433 {
1434 #if 0
1435 int i;
1436
1437 for (i=0; i<30; i++)
1438 {
1439 ColorCycling();
1440 if (game_status == MAINMENU)
1441 DoAnimation();
1442 Delay(10);
1443 }
1444 #else
1445 Delay(100);
1446 #endif
1447 }
1448
1449 }
1450 else
1451 BlitBitmap(pix[PIX_DOOR], pix[PIX_DOOR], 88,136, 8,8, 146,136);
1452
1453 if (!(door_state & DOOR_NO_DELAY))
1454 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
1455 }
1456
1457 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1458
1459 for(x=start; x<=DXSIZE; x+=stepsize)
1460 {
1461 Bitmap *bitmap = pix[PIX_DOOR];
1462 GC gc = bitmap->stored_clip_gc;
1463
1464 WaitUntilDelayReached(&door_delay, door_delay_value);
1465
1466 if (door_state & DOOR_ACTION_1)
1467 {
1468 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1469
1470 if (x < DXSIZE || door_state & DOOR_OPEN_1)
1471 {
1472 BlitBitmap(pix[PIX_DB_DOOR], drawto,
1473 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
1474 DXSIZE,DYSIZE - i/2, DX, DY);
1475
1476 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE, i/2);
1477 }
1478 else
1479 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1480
1481 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY);
1482 BlitBitmapMasked(bitmap, drawto,
1483 DXSIZE - i, DOOR_GFX_PAGEY1, i, 30,
1484 DX, DY);
1485 BlitBitmapMasked(bitmap, drawto,
1486 DXSIZE - i, DOOR_GFX_PAGEY1 + DYSIZE - 30, i, 30,
1487 DX, DY + DYSIZE - 30);
1488 SetClipOrigin(bitmap, gc, DX - i, DY);
1489 BlitBitmapMasked(bitmap, drawto,
1490 DXSIZE, DOOR_GFX_PAGEY1, i, 30,
1491 DX + DXSIZE - i, DY);
1492 BlitBitmapMasked(bitmap, drawto,
1493 DXSIZE, DOOR_GFX_PAGEY1 + DYSIZE - 30, i, 30,
1494 DX + DXSIZE - i, DY + DYSIZE - 30);
1495
1496 if (i > 14)
1497 {
1498 SetClipOrigin(bitmap, gc, DX - i, DY);
1499 BlitBitmapMasked(bitmap, drawto,
1500 DXSIZE + 14, DOOR_GFX_PAGEY1 + 30,
1501 i - 14, DYSIZE - 60,
1502 DX + DXSIZE + 14 - i, DY + 30);
1503 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY);
1504 BlitBitmapMasked(bitmap, drawto,
1505 DXSIZE - i, DOOR_GFX_PAGEY1 + 30,
1506 i - 14, DYSIZE - 60,
1507 DX, DY + 30);
1508 }
1509
1510 redraw_mask |= REDRAW_DOOR_1;
1511 }
1512
1513 BackToFront();
1514
1515 if (game_status == MAINMENU)
1516 DoAnimation();
1517 }
1518 }
1519
1520 if (setup.quick_doors)
1521 StopSound(SND_OEFFNEN);
1522
1523 if (door_state & DOOR_ACTION_1)
1524 door1 = door_state & DOOR_ACTION_1;
1525 if (door_state & DOOR_ACTION_2)
1526 door2 = door_state & DOOR_ACTION_2;
1527
1528 return (door1 | door2);
1529 }
1530
1531
1532 #if 0
1533 void DrawSpecialEditorDoor()
1534 {
1535 /* draw bigger toolbox window */
1536 BlitBitmap(pix[PIX_DOOR], drawto,
1537 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
1538
1539 redraw_mask |= REDRAW_ALL;
1540 }
1541
1542 void UndrawSpecialEditorDoor()
1543 {
1544 /* draw normal tape recorder window */
1545 BlitBitmap(pix[PIX_BACK], drawto,
1546 562, 344, 108, 56, EX - 4, EY - 12);
1547
1548 redraw_mask |= REDRAW_ALL;
1549 }
1550 #endif
1551
ReadPixel(DrawBuffer * bitmap,int x,int y)1552 Pixel ReadPixel(DrawBuffer *bitmap, int x, int y)
1553 {
1554 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
1555 return GetPixel(bitmap, x, y);
1556 #else
1557 /* GetPixel() does also work for X11, but we use some optimization here */
1558 unsigned long pixel_value;
1559
1560 if (bitmap == pix[PIX_BACK])
1561 {
1562 /* when reading pixel values from images, it is much faster to use
1563 client side images (XImage) than server side images (Pixmap) */
1564 static XImage *client_image = NULL;
1565
1566 if (client_image == NULL) /* init image cache, if not existing */
1567 client_image = XGetImage(display, bitmap->drawable,
1568 0,0, WIN_XSIZE,WIN_YSIZE, AllPlanes, ZPixmap);
1569
1570 pixel_value = XGetPixel(client_image, x, y);
1571 }
1572 else
1573 {
1574 XImage *pixel_image;
1575
1576 pixel_image = XGetImage(display, bitmap->drawable, x, y, 1, 1,
1577 AllPlanes, ZPixmap);
1578 pixel_value = XGetPixel(pixel_image, 0, 0);
1579
1580 XDestroyImage(pixel_image);
1581 }
1582
1583 return pixel_value;
1584 #endif
1585 }
1586
SetRGB(unsigned long pixel,unsigned short red,unsigned short green,unsigned short blue)1587 void SetRGB(unsigned long pixel,
1588 unsigned short red, unsigned short green, unsigned short blue)
1589 {
1590 return;
1591
1592 #if 0
1593 XColor color;
1594
1595 if (color_status==STATIC_COLORS)
1596 return;
1597
1598 color.pixel = pixel;
1599 color.red = red;
1600 color.green = green;
1601 color.blue = blue;
1602 color.flags = DoRed | DoGreen | DoBlue;
1603 XStoreColor(display, cmap, &color);
1604 XFlush(display);
1605 #endif
1606 }
1607
1608 /* ---------- new tool button stuff ---------------------------------------- */
1609
1610 /* graphic position values for tool buttons */
1611 #define TOOL_BUTTON_YES_XPOS 2
1612 #define TOOL_BUTTON_YES_YPOS 250
1613 #define TOOL_BUTTON_YES_GFX_YPOS 0
1614 #define TOOL_BUTTON_YES_XSIZE 46
1615 #define TOOL_BUTTON_YES_YSIZE 28
1616 #define TOOL_BUTTON_NO_XPOS 52
1617 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
1618 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
1619 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
1620 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
1621 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
1622 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
1623 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
1624 #define TOOL_BUTTON_CONFIRM_XSIZE 96
1625 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
1626
1627 static struct
1628 {
1629 int xpos, ypos;
1630 int x, y;
1631 int width, height;
1632 int gadget_id;
1633 char *infotext;
1634 } toolbutton_info[NUM_TOOL_BUTTONS] =
1635 {
1636 {
1637 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
1638 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
1639 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
1640 TOOL_CTRL_ID_YES,
1641 "yes"
1642 },
1643 {
1644 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
1645 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
1646 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
1647 TOOL_CTRL_ID_NO,
1648 "no"
1649 },
1650 {
1651 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
1652 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
1653 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
1654 TOOL_CTRL_ID_CONFIRM,
1655 "confirm"
1656 }
1657 };
1658
DoNotDisplayInfoText(void * ptr)1659 static void DoNotDisplayInfoText(void *ptr)
1660 {
1661 return;
1662 }
1663
CreateToolButtons()1664 void CreateToolButtons()
1665 {
1666 int i;
1667
1668 for (i=0; i<NUM_TOOL_BUTTONS; i++)
1669 {
1670 Bitmap *gd_bitmap = pix[PIX_DOOR];
1671 Bitmap *deco_bitmap = None;
1672 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
1673 struct GadgetInfo *gi;
1674 unsigned long event_mask;
1675 int gd_xoffset, gd_yoffset;
1676 int gd_x1, gd_x2, gd_y;
1677 int id = i;
1678
1679 event_mask = GD_EVENT_RELEASED;
1680
1681 gd_xoffset = toolbutton_info[i].xpos;
1682 gd_yoffset = toolbutton_info[i].ypos;
1683 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
1684 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
1685 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
1686
1687 gi = CreateGadget(GDI_CUSTOM_ID, id,
1688 GDI_INFO_TEXT, toolbutton_info[i].infotext,
1689 GDI_X, DX + toolbutton_info[i].x,
1690 GDI_Y, DY + toolbutton_info[i].y,
1691 GDI_WIDTH, toolbutton_info[i].width,
1692 GDI_HEIGHT, toolbutton_info[i].height,
1693 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
1694 GDI_STATE, GD_BUTTON_UNPRESSED,
1695 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
1696 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
1697 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
1698 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
1699 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
1700 GDI_DECORATION_SHIFTING, 1, 1,
1701 GDI_EVENT_MASK, event_mask,
1702 GDI_CALLBACK_ACTION, HandleToolButtons,
1703 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
1704 GDI_END);
1705
1706 if (gi == NULL)
1707 Error(ERR_EXIT, "cannot create gadget");
1708
1709 tool_gadget[id] = gi;
1710 }
1711 }
1712
UnmapToolButtons()1713 static void UnmapToolButtons()
1714 {
1715 int i;
1716
1717 for (i=0; i<NUM_TOOL_BUTTONS; i++)
1718 UnmapGadget(tool_gadget[i]);
1719 }
1720
HandleToolButtons(struct GadgetInfo * gi)1721 static void HandleToolButtons(struct GadgetInfo *gi)
1722 {
1723 request_gadget_id = gi->custom_id;
1724 }
1725
1726 /* ------------------------------------------------------------------------- */
1727
get_base_element(int element)1728 int get_base_element(int element)
1729 {
1730 if (IS_MIRROR(element))
1731 return EL_MIRROR_START;
1732 else if (IS_MIRROR_FIXED(element))
1733 return EL_MIRROR_FIXED_START;
1734 else if (IS_POLAR(element))
1735 return EL_POLAR_START;
1736 else if (IS_POLAR_CROSS(element))
1737 return EL_POLAR_CROSS_START;
1738 else if (IS_BEAMER(element))
1739 return EL_BEAMER_RED_START + BEAMER_NR(element) * 16;
1740 else if (IS_FIBRE_OPTIC(element))
1741 return EL_FIBRE_OPTIC_START + FIBRE_OPTIC_NR(element) * 2;
1742 else if (IS_MCDUFFIN(element))
1743 return EL_MCDUFFIN_START;
1744 else if (IS_LASER(element))
1745 return EL_LASER_START;
1746 else if (IS_RECEIVER(element))
1747 return EL_RECEIVER_START;
1748 else if (IS_DF_MIRROR(element))
1749 return EL_DF_MIRROR_START;
1750 else if (IS_DF_MIRROR_AUTO(element))
1751 return EL_DF_MIRROR_AUTO_START;
1752 else if (IS_PACMAN(element))
1753 return EL_PACMAN_START;
1754 else if (IS_GRID_STEEL(element))
1755 return EL_GRID_STEEL_START;
1756 else if (IS_GRID_WOOD(element))
1757 return EL_GRID_WOOD_START;
1758 else if (IS_GRID_STEEL_FIXED(element))
1759 return EL_GRID_STEEL_FIXED_START;
1760 else if (IS_GRID_WOOD_FIXED(element))
1761 return EL_GRID_WOOD_FIXED_START;
1762 else if (IS_GRID_STEEL_AUTO(element))
1763 return EL_GRID_STEEL_AUTO_START;
1764 else if (IS_GRID_WOOD_AUTO(element))
1765 return EL_GRID_WOOD_AUTO_START;
1766 else if (IS_WALL_STEEL(element))
1767 return EL_WALL_STEEL_START;
1768 else if (IS_WALL_WOOD(element))
1769 return EL_WALL_WOOD_START;
1770 else if (IS_WALL_ICE(element))
1771 return EL_WALL_ICE_START;
1772 else if (IS_WALL_AMOEBA(element))
1773 return EL_WALL_AMOEBA_START;
1774 else if (IS_DF_WALL_STEEL(element))
1775 return EL_DF_WALL_STEEL_START;
1776 else if (IS_DF_WALL_WOOD(element))
1777 return EL_DF_WALL_WOOD_START;
1778 else if (IS_CHAR(element))
1779 return EL_CHAR_START;
1780 else
1781 return element;
1782 }
1783
get_element_phase(int element)1784 int get_element_phase(int element)
1785 {
1786 return element - get_base_element(element);
1787 }
1788
get_num_elements(int element)1789 int get_num_elements(int element)
1790 {
1791 if (IS_MIRROR(element) ||
1792 IS_POLAR(element) ||
1793 IS_BEAMER(element) ||
1794 IS_DF_MIRROR(element) ||
1795 IS_DF_MIRROR_AUTO(element))
1796 return 16;
1797 else if (IS_GRID_STEEL_FIXED(element) ||
1798 IS_GRID_WOOD_FIXED(element) ||
1799 IS_GRID_STEEL_AUTO(element) ||
1800 IS_GRID_WOOD_AUTO(element))
1801 return 8;
1802 else if (IS_MIRROR_FIXED(element) ||
1803 IS_POLAR_CROSS(element) ||
1804 IS_MCDUFFIN(element) ||
1805 IS_LASER(element) ||
1806 IS_RECEIVER(element) ||
1807 IS_PACMAN(element) ||
1808 IS_GRID_STEEL(element) ||
1809 IS_GRID_WOOD(element))
1810 return 4;
1811 else
1812 return 1;
1813 }
1814
get_rotated_element(int element,int step)1815 int get_rotated_element(int element, int step)
1816 {
1817 int base_element = get_base_element(element);
1818 int num_elements = get_num_elements(element);
1819 int element_phase = element - base_element;
1820
1821 return base_element + (element_phase + step + num_elements) % num_elements;
1822 }
1823
el2gfx(int element)1824 int el2gfx(int element)
1825 {
1826 switch(element)
1827 {
1828 case EL_EMPTY: return -1;
1829 case EL_GRID_STEEL_00: return GFX_GRID_STEEL_00;
1830 case EL_GRID_STEEL_01: return GFX_GRID_STEEL_01;
1831 case EL_GRID_STEEL_02: return GFX_GRID_STEEL_02;
1832 case EL_GRID_STEEL_03: return GFX_GRID_STEEL_03;
1833 case EL_MCDUFFIN_RIGHT: return GFX_MCDUFFIN_RIGHT;
1834 case EL_MCDUFFIN_UP: return GFX_MCDUFFIN_UP;
1835 case EL_MCDUFFIN_LEFT: return GFX_MCDUFFIN_LEFT;
1836 case EL_MCDUFFIN_DOWN: return GFX_MCDUFFIN_DOWN;
1837 case EL_EXIT_CLOSED: return GFX_EXIT_CLOSED;
1838 case EL_EXIT_OPENING_1: return GFX_EXIT_OPENING_1;
1839 case EL_EXIT_OPENING_2: return GFX_EXIT_OPENING_2;
1840 case EL_EXIT_OPEN: return GFX_EXIT_OPEN;
1841 case EL_KETTLE: return GFX_KETTLE;
1842 case EL_BOMB: return GFX_BOMB;
1843 case EL_PRISM: return GFX_PRISM;
1844 case EL_BLOCK_WOOD: return GFX_BLOCK_WOOD;
1845 case EL_BALL_GRAY: return GFX_BALL_GRAY;
1846 case EL_FUSE_ON: return GFX_FUSE_ON;
1847 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
1848 case EL_PACMAN_UP: return GFX_PACMAN_UP;
1849 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
1850 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
1851 case EL_POLAR_CROSS_00: return GFX_POLAR_CROSS_00;
1852 case EL_POLAR_CROSS_01: return GFX_POLAR_CROSS_01;
1853 case EL_POLAR_CROSS_02: return GFX_POLAR_CROSS_02;
1854 case EL_POLAR_CROSS_03: return GFX_POLAR_CROSS_03;
1855 case EL_MIRROR_FIXED_00: return GFX_MIRROR_FIXED_00;
1856 case EL_MIRROR_FIXED_01: return GFX_MIRROR_FIXED_01;
1857 case EL_MIRROR_FIXED_02: return GFX_MIRROR_FIXED_02;
1858 case EL_MIRROR_FIXED_03: return GFX_MIRROR_FIXED_03;
1859 case EL_GATE_STONE: return GFX_GATE_STONE;
1860 case EL_KEY: return GFX_KEY;
1861 case EL_LIGHTBULB_ON: return GFX_LIGHTBULB_ON;
1862 case EL_LIGHTBULB_OFF: return GFX_LIGHTBULB_OFF;
1863 case EL_LIGHTBALL: return GFX_BALL_RED + RND(3);;
1864 case EL_BLOCK_STONE: return GFX_BLOCK_STONE;
1865 case EL_GATE_WOOD: return GFX_GATE_WOOD;
1866 case EL_FUEL_FULL: return GFX_FUEL_FULL;
1867 case EL_GRID_WOOD_00: return GFX_GRID_WOOD_00;
1868 case EL_GRID_WOOD_01: return GFX_GRID_WOOD_01;
1869 case EL_GRID_WOOD_02: return GFX_GRID_WOOD_02;
1870 case EL_GRID_WOOD_03: return GFX_GRID_WOOD_03;
1871 case EL_FUEL_EMPTY: return GFX_FUEL_EMPTY;
1872 case EL_FUSE_OFF: return GFX_FUSE_OFF;
1873 case EL_PACMAN: return GFX_PACMAN;
1874 case EL_REFRACTOR: return GFX_REFRACTOR;
1875 case EL_CELL: return GFX_CELL;
1876 case EL_MINE: return GFX_MINE;
1877
1878 /* pseudo-graphics; will be mapped to other graphics */
1879 case EL_WALL_STEEL: return GFX_WALL_STEEL;
1880 case EL_WALL_WOOD: return GFX_WALL_WOOD;
1881 case EL_WALL_ICE: return GFX_WALL_ICE;
1882 case EL_WALL_AMOEBA: return GFX_WALL_AMOEBA;
1883 case EL_DF_WALL_STEEL: return GFX_DF_WALL_STEEL;
1884 case EL_DF_WALL_WOOD: return GFX_DF_WALL_WOOD;
1885
1886 default:
1887 {
1888 boolean ed = (game_status == LEVELED);
1889 int base_element = get_base_element(element);
1890 int element_phase = element - base_element;
1891 int base_graphic;
1892
1893 if (IS_BEAMER(element))
1894 element_phase = element - EL_BEAMER_RED_START;
1895 else if (IS_FIBRE_OPTIC(element))
1896 element_phase = element - EL_FIBRE_OPTIC_START;
1897
1898 if (IS_MIRROR(element))
1899 base_graphic = GFX_MIRROR_START;
1900 else if (IS_BEAMER_OLD(element))
1901 base_graphic = GFX_BEAMER_START;
1902 else if (IS_POLAR(element))
1903 base_graphic = GFX_POLAR_START;
1904 else if (IS_CHAR(element))
1905 base_graphic = GFX_CHAR_START;
1906 else if (IS_GRID_WOOD_FIXED(element))
1907 base_graphic = GFX_GRID_WOOD_FIXED_00;
1908 else if (IS_GRID_STEEL_FIXED(element))
1909 base_graphic = GFX_GRID_STEEL_FIXED_00;
1910 else if (IS_DF_MIRROR(element))
1911 base_graphic = GFX_DF_MIRROR_00;
1912 else if (IS_LASER(element))
1913 base_graphic = GFX_LASER_RIGHT;
1914 else if (IS_RECEIVER(element))
1915 base_graphic = GFX_RECEIVER_RIGHT;
1916 else if (IS_DF_MIRROR(element))
1917 base_graphic = GFX_DF_MIRROR_00;
1918 else if (IS_FIBRE_OPTIC(element))
1919 base_graphic = (ed ? GFX_FIBRE_OPTIC_ED_00 : GFX_FIBRE_OPTIC_00);
1920 else if (IS_GRID_WOOD_AUTO(element))
1921 base_graphic = (ed ? GFX_GRID_WOOD_AUTO_00 : GFX_GRID_WOOD_FIXED_00);
1922 else if (IS_GRID_STEEL_AUTO(element))
1923 base_graphic = (ed ? GFX_GRID_STEEL_AUTO_00 : GFX_GRID_STEEL_FIXED_00);
1924 else if (IS_DF_MIRROR_AUTO(element))
1925 base_graphic = (ed ? GFX_DF_MIRROR_AUTO_00 : GFX_DF_MIRROR_00);
1926 else if (IS_BEAMER(element))
1927 base_graphic = GFX_BEAMER_RED_START;
1928 else
1929 return GFX_EMPTY;
1930
1931 return base_graphic + element_phase;
1932 }
1933 }
1934 }
1935