1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
16 #if defined(PLATFORM_FREEBSD)
17 #include <machine/joystick.h>
20 #include "libgame/libgame.h"
29 #if defined(PLATFORM_MSDOS)
30 extern boolean wait_for_vsync;
33 /* tool button identifiers */
34 #define TOOL_CTRL_ID_YES 0
35 #define TOOL_CTRL_ID_NO 1
36 #define TOOL_CTRL_ID_CONFIRM 2
37 #define TOOL_CTRL_ID_PLAYER_1 3
38 #define TOOL_CTRL_ID_PLAYER_2 4
39 #define TOOL_CTRL_ID_PLAYER_3 5
40 #define TOOL_CTRL_ID_PLAYER_4 6
42 #define NUM_TOOL_BUTTONS 7
44 /* forward declaration for internal use */
45 static int getGraphicAnimationPhase(int, int, int);
46 static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
48 static void UnmapToolButtons();
49 static void HandleToolButtons(struct GadgetInfo *);
51 static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
52 static int request_gadget_id = -1;
54 void SetDrawtoField(int mode)
56 if (mode == DRAW_BUFFERED && setup.soft_scrolling)
67 drawto_field = fieldbuffer;
69 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
80 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
87 DrawBuffer buffer = (drawto_field == window ? backbuffer : drawto_field);
89 if (setup.direct_draw && game_status == PLAYING)
90 redraw_mask &= ~REDRAW_MAIN;
92 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
93 redraw_mask |= REDRAW_FIELD;
95 if (redraw_mask & REDRAW_FIELD)
96 redraw_mask &= ~REDRAW_TILES;
101 if (global.fps_slowdown && game_status == PLAYING)
103 static boolean last_frame_skipped = FALSE;
104 boolean skip_even_when_not_scrolling = TRUE;
105 boolean just_scrolling = (ScreenMovDir != 0);
106 boolean verbose = FALSE;
108 if (global.fps_slowdown_factor > 1 &&
109 (FrameCounter % global.fps_slowdown_factor) &&
110 (just_scrolling || skip_even_when_not_scrolling))
112 redraw_mask &= ~REDRAW_MAIN;
114 last_frame_skipped = TRUE;
117 printf("FRAME SKIPPED\n");
121 if (last_frame_skipped)
122 redraw_mask |= REDRAW_FIELD;
124 last_frame_skipped = FALSE;
127 printf("frame not skipped\n");
131 /* synchronize X11 graphics at this point; if we would synchronize the
132 display immediately after the buffer switching (after the XFlush),
133 this could mean that we have to wait for the graphics to complete,
134 although we could go on doing calculations for the next frame */
138 if (redraw_mask & REDRAW_ALL)
140 BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
144 if (redraw_mask & REDRAW_FIELD)
146 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
148 BlitBitmap(backbuffer, window,
149 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
153 int fx = FX, fy = FY;
155 if (setup.soft_scrolling)
157 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
158 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
161 if (setup.soft_scrolling ||
162 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
163 ABS(ScreenMovPos) == ScrollStepSize ||
164 redraw_tiles > REDRAWTILES_THRESHOLD)
166 BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
170 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
172 (setup.soft_scrolling ?
173 "setup.soft_scrolling" :
174 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
175 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
176 ABS(ScreenGfxPos) == ScrollStepSize ?
177 "ABS(ScreenGfxPos) == ScrollStepSize" :
178 "redraw_tiles > REDRAWTILES_THRESHOLD"));
184 redraw_mask &= ~REDRAW_MAIN;
187 if (redraw_mask & REDRAW_DOORS)
189 if (redraw_mask & REDRAW_DOOR_1)
190 BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
191 if (redraw_mask & REDRAW_DOOR_2)
193 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
194 BlitBitmap(backbuffer, window, VX,VY, VXSIZE,VYSIZE, VX,VY);
197 if (redraw_mask & REDRAW_VIDEO_1)
198 BlitBitmap(backbuffer, window,
199 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
200 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
201 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
202 if (redraw_mask & REDRAW_VIDEO_2)
203 BlitBitmap(backbuffer, window,
204 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
205 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
206 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
207 if (redraw_mask & REDRAW_VIDEO_3)
208 BlitBitmap(backbuffer, window,
209 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
210 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
211 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
214 if (redraw_mask & REDRAW_DOOR_3)
215 BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
216 redraw_mask &= ~REDRAW_DOORS;
219 if (redraw_mask & REDRAW_MICROLEVEL)
221 BlitBitmap(backbuffer, window,
222 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
223 MICROLEV_XPOS, MICROLEV_YPOS);
224 BlitBitmap(backbuffer, window,
225 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
226 SX, MICROLABEL_YPOS);
227 redraw_mask &= ~REDRAW_MICROLEVEL;
230 if (redraw_mask & REDRAW_TILES)
232 for(x=0; x<SCR_FIELDX; x++)
233 for(y=0; y<SCR_FIELDY; y++)
234 if (redraw[redraw_x1 + x][redraw_y1 + y])
235 BlitBitmap(buffer, window,
236 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
237 SX + x * TILEX, SY + y * TILEY);
240 if (redraw_mask & REDRAW_FPS) /* display frames per second */
245 sprintf(info1, " (only every %d. frame)", global.fps_slowdown_factor);
246 if (!global.fps_slowdown)
249 sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
250 DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
255 for(x=0; x<MAX_BUF_XSIZE; x++)
256 for(y=0; y<MAX_BUF_YSIZE; y++)
265 long fading_delay = 300;
267 if (setup.fading && (redraw_mask & REDRAW_FIELD))
274 ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
277 for(i=0;i<2*FULL_SYSIZE;i++)
279 for(y=0;y<FULL_SYSIZE;y++)
281 BlitBitmap(backbuffer, window,
282 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
290 for(i=1;i<FULL_SYSIZE;i+=2)
291 BlitBitmap(backbuffer, window,
292 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
298 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
299 BlitBitmapMasked(backbuffer, window,
300 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
305 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
306 BlitBitmapMasked(backbuffer, window,
307 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
312 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
313 BlitBitmapMasked(backbuffer, window,
314 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
319 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
320 BlitBitmapMasked(backbuffer, window,
321 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
326 redraw_mask &= ~REDRAW_MAIN;
335 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
337 if (setup.soft_scrolling && game_status == PLAYING)
339 ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
340 SetDrawtoField(DRAW_BUFFERED);
343 SetDrawtoField(DRAW_BACKBUFFER);
345 if (setup.direct_draw && game_status == PLAYING)
347 ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
348 SetDrawtoField(DRAW_DIRECT);
351 redraw_mask |= REDRAW_FIELD;
356 int getFontWidth(int font_size, int font_type)
358 return (font_size == FS_BIG ? FONT1_XSIZE :
359 font_size == FS_MEDIUM ? FONT6_XSIZE :
360 font_type == FC_SPECIAL1 ? FONT3_XSIZE :
361 font_type == FC_SPECIAL2 ? FONT4_XSIZE :
362 font_type == FC_SPECIAL3 ? FONT5_XSIZE :
366 int getFontHeight(int font_size, int font_type)
368 return (font_size == FS_BIG ? FONT1_YSIZE :
369 font_size == FS_MEDIUM ? FONT6_YSIZE :
370 font_type == FC_SPECIAL1 ? FONT3_YSIZE :
371 font_type == FC_SPECIAL2 ? FONT4_YSIZE :
372 font_type == FC_SPECIAL3 ? FONT5_YSIZE :
376 void DrawInitText(char *text, int ypos, int color)
378 if (window && pix[PIX_SMALLFONT])
380 ClearRectangle(window, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
381 DrawTextExt(window, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
382 ypos, text, FS_SMALL, color);
387 void DrawTextFCentered(int y, int font_type, char *format, ...)
389 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
390 int font_width = getFontWidth(FS_SMALL, font_type);
393 va_start(ap, format);
394 vsprintf(buffer, format, ap);
397 DrawText(SX + (SXSIZE - strlen(buffer) * font_width) / 2, SY + y,
398 buffer, FS_SMALL, font_type);
401 void DrawTextF(int x, int y, int font_type, char *format, ...)
403 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
406 va_start(ap, format);
407 vsprintf(buffer, format, ap);
410 DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
413 void DrawText(int x, int y, char *text, int font_size, int font_type)
415 DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
418 redraw_mask |= REDRAW_FIELD;
420 redraw_mask |= REDRAW_DOOR_1;
423 void DrawTextExt(DrawBuffer d, GC gc, int x, int y,
424 char *text, int font_size, int font_type)
426 int font_width, font_height, font_start;
428 boolean print_inverse = FALSE;
430 if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
431 font_size = FS_SMALL;
432 if (font_type < FC_RED || font_type > FC_SPECIAL3)
435 font_width = getFontWidth(font_size, font_type);
436 font_height = getFontHeight(font_size, font_type);
438 font_bitmap = (font_size == FS_BIG ? PIX_BIGFONT :
439 font_size == FS_MEDIUM ? PIX_MEDIUMFONT :
441 font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
442 font_size == FS_MEDIUM ? FONT6_YSIZE :
444 FONT_LINES_PER_FONT);
446 if (font_type == FC_SPECIAL3)
447 font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
453 if (c == '~' && font_size == FS_SMALL)
455 print_inverse = TRUE;
459 if (c >= 'a' && c <= 'z')
461 else if (c == 'ä' || c == 'Ä')
463 else if (c == 'ö' || c == 'Ö')
465 else if (c == 'ü' || c == 'Ü')
468 if (c >= 32 && c <= 95)
470 int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
471 int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
472 int dest_x = x, dest_y = y;
476 BlitBitmap(pix[font_bitmap], d,
477 FONT_CHARS_PER_LINE * font_width,
478 3 * font_height + font_start,
479 font_width, font_height, x, y);
481 SetClipOrigin(clip_gc[font_bitmap], dest_x - src_x, dest_y - src_y);
482 BlitBitmapMasked(pix_masked[font_bitmap], d,
483 0, 0, font_width, font_height, dest_x, dest_y);
486 BlitBitmap(pix[font_bitmap], d,
487 src_x, src_y, font_width, font_height, dest_x, dest_y);
496 void DrawAllPlayers()
500 for(i=0; i<MAX_PLAYERS; i++)
501 if (stored_player[i].active)
502 DrawPlayer(&stored_player[i]);
505 void DrawPlayerField(int x, int y)
507 if (!IS_PLAYER(x, y))
510 DrawPlayer(PLAYERINFO(x, y));
513 void DrawPlayer(struct PlayerInfo *player)
515 int jx = player->jx, jy = player->jy;
516 int last_jx = player->last_jx, last_jy = player->last_jy;
517 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
518 int sx = SCREENX(jx), sy = SCREENY(jy);
519 int sxx = 0, syy = 0;
520 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
522 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
524 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
528 if (!IN_LEV_FIELD(jx,jy))
530 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
531 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
532 printf("DrawPlayerField(): This should never happen!\n");
537 if (element == EL_EXPLODING)
540 /* draw things in the field the player is leaving, if needed */
542 if (player_is_moving)
544 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
546 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
547 DrawLevelFieldThruMask(last_jx, last_jy);
549 else if (last_element == EL_DYNAMITE_ACTIVE)
550 DrawDynamite(last_jx, last_jy);
552 DrawLevelField(last_jx, last_jy);
554 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
558 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
559 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
561 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
564 DrawLevelField(next_jx, next_jy);
568 if (!IN_SCR_FIELD(sx, sy))
571 if (setup.direct_draw)
572 SetDrawtoField(DRAW_BUFFERED);
574 /* draw things behind the player, if needed */
577 DrawLevelElement(jx, jy, Store[jx][jy]);
578 else if (!IS_ACTIVE_BOMB(element))
579 DrawLevelField(jx, jy);
581 /* draw player himself */
583 if (game.emulation == EMU_SUPAPLEX)
585 static int last_dir = MV_LEFT;
586 int action = (player->programmed_action ? player->programmed_action :
588 boolean action_moving =
590 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
591 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
593 graphic = GFX_SP_MURPHY;
597 if (player->MovDir == MV_LEFT)
598 graphic = GFX_MURPHY_PUSH_LEFT;
599 else if (player->MovDir == MV_RIGHT)
600 graphic = GFX_MURPHY_PUSH_RIGHT;
601 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
602 graphic = GFX_MURPHY_PUSH_LEFT;
603 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
604 graphic = GFX_MURPHY_PUSH_RIGHT;
606 else if (player->snapped)
608 if (player->MovDir == MV_LEFT)
609 graphic = GFX_MURPHY_SNAP_LEFT;
610 else if (player->MovDir == MV_RIGHT)
611 graphic = GFX_MURPHY_SNAP_RIGHT;
612 else if (player->MovDir == MV_UP)
613 graphic = GFX_MURPHY_SNAP_UP;
614 else if (player->MovDir == MV_DOWN)
615 graphic = GFX_MURPHY_SNAP_DOWN;
617 else if (action_moving)
619 if (player->MovDir == MV_LEFT)
620 graphic = GFX_MURPHY_GO_LEFT;
621 else if (player->MovDir == MV_RIGHT)
622 graphic = GFX_MURPHY_GO_RIGHT;
623 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
624 graphic = GFX_MURPHY_GO_LEFT;
625 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
626 graphic = GFX_MURPHY_GO_RIGHT;
628 graphic = GFX_MURPHY_GO_LEFT;
630 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
633 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
634 last_dir = player->MovDir;
638 if (player->MovDir == MV_LEFT)
640 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
641 else if (player->MovDir == MV_RIGHT)
643 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
644 else if (player->MovDir == MV_UP)
645 graphic = GFX_SPIELER1_UP;
646 else /* MV_DOWN || MV_NO_MOVING */
647 graphic = GFX_SPIELER1_DOWN;
649 graphic += player->index_nr * 3 * HEROES_PER_LINE;
650 graphic += player->Frame;
655 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
656 sxx = player->GfxPos;
658 syy = player->GfxPos;
661 if (!setup.soft_scrolling && ScreenMovPos)
664 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
666 if (SHIELD_ON(player))
668 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
669 GFX2_SHIELD_PASSIVE);
671 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
672 3, 8, ANIM_OSCILLATE);
675 if (player->Pushing && player->GfxPos)
677 int px = SCREENX(next_jx), py = SCREENY(next_jy);
679 if (element == EL_SOKOBAN_FELD_LEER ||
680 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
681 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
685 int element = Feld[next_jx][next_jy];
686 int graphic = el2gfx(element);
688 if ((element == EL_FELSBROCKEN ||
689 element == EL_SP_ZONK ||
690 element == EL_BD_ROCK) && sxx)
692 int phase = (player->GfxPos / (TILEX / 4));
694 if (player->MovDir == MV_LEFT)
697 graphic += (phase + 4) % 4;
700 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
704 /* draw things in front of player (active dynamite or dynabombs) */
706 if (IS_ACTIVE_BOMB(element))
708 graphic = el2gfx(element);
710 if (element == EL_DYNAMITE_ACTIVE)
712 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
717 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
721 if (game.emulation == EMU_SUPAPLEX)
722 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
724 DrawGraphicThruMask(sx, sy, graphic + phase);
727 if (player_is_moving && last_element == EL_EXPLODING)
729 int phase = Frame[last_jx][last_jy];
733 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
734 GFX_EXPLOSION + ((phase - 1) / delay - 1));
737 /* draw elements that stay over the player */
738 /* handle the field the player is leaving ... */
739 if (player_is_moving && IS_OVER_PLAYER(last_element))
740 DrawLevelField(last_jx, last_jy);
741 /* ... and the field the player is entering */
742 if (IS_OVER_PLAYER(element))
743 DrawLevelField(jx, jy);
745 if (setup.direct_draw)
747 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
748 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
749 int x_size = TILEX * (1 + ABS(jx - last_jx));
750 int y_size = TILEY * (1 + ABS(jy - last_jy));
752 BlitBitmap(drawto_field, window,
753 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
754 SetDrawtoField(DRAW_DIRECT);
757 MarkTileDirty(sx,sy);
760 static int getGraphicAnimationPhase(int frames, int delay, int mode)
764 if (mode == ANIM_OSCILLATE)
766 int max_anim_frames = 2 * frames - 2;
767 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
768 phase = (phase < frames ? phase : max_anim_frames - phase);
771 phase = (FrameCounter % (delay * frames)) / delay;
773 if (mode == ANIM_REVERSE)
779 void DrawGraphicAnimationExt(int x, int y, int graphic,
780 int frames, int delay, int mode, int mask_mode)
782 int phase = getGraphicAnimationPhase(frames, delay, mode);
784 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
786 if (mask_mode == USE_MASKING)
787 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
789 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
793 void DrawGraphicAnimation(int x, int y, int graphic,
794 int frames, int delay, int mode)
796 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
799 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
800 int frames, int delay, int mode)
802 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
805 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
808 int frames, int delay,
811 int phase = getGraphicAnimationPhase(frames, delay, mode);
813 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
816 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
818 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
820 graphic -= GFX_START_ROCKSSCREEN;
821 *bitmap_nr = PIX_BACK;
822 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
823 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
825 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
827 graphic -= GFX_START_ROCKSHEROES;
828 *bitmap_nr = PIX_HEROES;
829 *x = (graphic % HEROES_PER_LINE) * TILEX;
830 *y = (graphic / HEROES_PER_LINE) * TILEY;
832 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
834 graphic -= GFX_START_ROCKSSP;
836 *x = (graphic % SP_PER_LINE) * TILEX;
837 *y = (graphic / SP_PER_LINE) * TILEY;
839 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
841 graphic -= GFX_START_ROCKSDC;
843 *x = (graphic % DC_PER_LINE) * TILEX;
844 *y = (graphic / DC_PER_LINE) * TILEY;
846 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
848 graphic -= GFX_START_ROCKSMORE;
849 *bitmap_nr = PIX_MORE;
850 *x = (graphic % MORE_PER_LINE) * TILEX;
851 *y = (graphic / MORE_PER_LINE) * TILEY;
853 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
855 graphic -= GFX_START_ROCKSFONT;
856 *bitmap_nr = PIX_BIGFONT;
857 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
858 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
859 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
869 void DrawGraphic(int x, int y, int graphic)
872 if (!IN_SCR_FIELD(x,y))
874 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
875 printf("DrawGraphic(): This should never happen!\n");
880 DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
884 void DrawGraphicExt(DrawBuffer bitmap, int x, int y, int graphic)
889 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
890 BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
893 void DrawGraphicThruMask(int x, int y, int graphic)
896 if (!IN_SCR_FIELD(x,y))
898 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
899 printf("DrawGraphicThruMask(): This should never happen!\n");
904 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
908 void DrawGraphicThruMaskExt(DrawBuffer d, int dest_x, int dest_y, int graphic)
916 if (graphic == GFX_LEERRAUM)
919 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
920 src_bitmap = pix[bitmap_nr];
921 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
923 if (tile_clipmask[tile] != None)
925 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
926 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
927 BlitBitmapMasked(src_bitmap, d,
928 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
934 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
938 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
939 BlitBitmapMasked(src_bitmap, d,
940 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
944 void DrawMiniGraphic(int x, int y, int graphic)
946 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
947 MarkTileDirty(x/2, y/2);
950 void getMiniGraphicSource(int graphic, Bitmap *bitmap, int *x, int *y)
952 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
954 graphic -= GFX_START_ROCKSSCREEN;
955 *bitmap = pix[PIX_BACK];
956 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
957 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
959 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
961 graphic -= GFX_START_ROCKSSP;
962 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
963 *bitmap = pix[PIX_SP];
964 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
965 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
967 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
969 graphic -= GFX_START_ROCKSDC;
970 *bitmap = pix[PIX_DC];
971 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
972 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
974 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
976 graphic -= GFX_START_ROCKSMORE;
977 *bitmap = pix[PIX_MORE];
978 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
979 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
981 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
983 graphic -= GFX_START_ROCKSFONT;
984 *bitmap = pix[PIX_SMALLFONT];
985 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
986 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
987 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
991 *bitmap = pix[PIX_SP];
997 void DrawMiniGraphicExt(DrawBuffer d, int x, int y, int graphic)
1002 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
1003 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
1006 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
1007 int cut_mode, int mask_mode)
1009 int width = TILEX, height = TILEY;
1011 int src_x, src_y, dest_x, dest_y;
1019 DrawGraphic(x, y, graphic);
1023 if (dx || dy) /* Verschiebung der Grafik? */
1025 if (x < BX1) /* Element kommt von links ins Bild */
1032 else if (x > BX2) /* Element kommt von rechts ins Bild */
1038 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1044 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1046 else if (dx) /* allg. Bewegung in x-Richtung */
1047 MarkTileDirty(x + SIGN(dx), y);
1049 if (y < BY1) /* Element kommt von oben ins Bild */
1051 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1059 else if (y > BY2) /* Element kommt von unten ins Bild */
1065 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1071 else if (dy > 0 && cut_mode == CUT_ABOVE)
1073 if (y == BY2) /* Element unterhalb des Bildes */
1079 MarkTileDirty(x, y + 1);
1080 } /* Element verläßt unten das Bild */
1081 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1083 else if (dy) /* allg. Bewegung in y-Richtung */
1084 MarkTileDirty(x, y + SIGN(dy));
1087 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
1088 src_bitmap = pix[bitmap_nr];
1089 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
1094 dest_x = FX + x * TILEX + dx;
1095 dest_y = FY + y * TILEY + dy;
1098 if (!IN_SCR_FIELD(x,y))
1100 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1101 printf("DrawGraphicShifted(): This should never happen!\n");
1106 if (mask_mode == USE_MASKING)
1108 if (tile_clipmask[tile] != None)
1110 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1111 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1112 BlitBitmapMasked(src_bitmap, drawto_field,
1113 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1119 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1123 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1124 BlitBitmapMasked(src_bitmap, drawto_field,
1125 src_x, src_y, width, height, dest_x, dest_y);
1129 BlitBitmap(pix[bitmap_nr], drawto_field,
1130 src_x, src_y, width, height, dest_x, dest_y);
1135 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1138 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1141 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1142 int cut_mode, int mask_mode)
1144 int ux = LEVELX(x), uy = LEVELY(y);
1145 int graphic = el2gfx(element);
1146 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1147 int phase4 = phase8 / 2;
1148 int phase2 = phase8 / 4;
1149 int dir = MovDir[ux][uy];
1151 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1153 graphic += 4 * !phase2;
1157 else if (dir == MV_LEFT)
1159 else if (dir == MV_DOWN)
1162 else if (element == EL_SP_SNIKSNAK)
1165 graphic = GFX_SP_SNIKSNAK_LEFT;
1166 else if (dir == MV_RIGHT)
1167 graphic = GFX_SP_SNIKSNAK_RIGHT;
1168 else if (dir == MV_UP)
1169 graphic = GFX_SP_SNIKSNAK_UP;
1171 graphic = GFX_SP_SNIKSNAK_DOWN;
1173 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1175 else if (element == EL_SP_ELECTRON)
1177 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1179 else if (element == EL_MOLE || element == EL_PINGUIN ||
1180 element == EL_SCHWEIN || element == EL_DRACHE)
1183 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1184 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1185 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1186 else if (dir == MV_RIGHT)
1187 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1188 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1189 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1190 else if (dir == MV_UP)
1191 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1192 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1193 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1195 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1196 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1197 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1201 else if (element == EL_SONDE)
1203 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1205 else if (element == EL_SALZSAEURE)
1207 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1209 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1213 else if (element == EL_BALLOON)
1217 else if ((element == EL_FELSBROCKEN ||
1218 element == EL_SP_ZONK ||
1219 element == EL_BD_ROCK ||
1220 IS_GEM(element)) && !cut_mode)
1222 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1224 if (element == EL_FELSBROCKEN ||
1225 element == EL_SP_ZONK ||
1226 element == EL_BD_ROCK)
1229 graphic += (4 - phase4) % 4;
1230 else if (dir == MV_RIGHT)
1233 graphic += phase2 * 2;
1235 else if (element != EL_SP_INFOTRON)
1239 else if (element == EL_MAGIC_WALL_EMPTY ||
1240 element == EL_MAGIC_WALL_BD_EMPTY ||
1241 element == EL_MAGIC_WALL_FULL ||
1242 element == EL_MAGIC_WALL_BD_FULL)
1244 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1246 else if (IS_AMOEBOID(element))
1248 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1249 graphic += (x + 2 * y + 4) % 4;
1251 else if (element == EL_MAUER_LEBT)
1253 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1255 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1256 links_massiv = TRUE;
1257 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1258 rechts_massiv = TRUE;
1260 if (links_massiv && rechts_massiv)
1261 graphic = GFX_MAUERWERK;
1262 else if (links_massiv)
1263 graphic = GFX_MAUER_R;
1264 else if (rechts_massiv)
1265 graphic = GFX_MAUER_L;
1267 else if ((element == EL_INVISIBLE_STEEL ||
1268 element == EL_UNSICHTBAR ||
1269 element == EL_SAND_INVISIBLE) && game.light_time_left)
1271 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1272 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1273 GFX_SAND_INVISIBLE_ON);
1277 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1278 else if (mask_mode == USE_MASKING)
1279 DrawGraphicThruMask(x, y, graphic);
1281 DrawGraphic(x, y, graphic);
1284 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1285 int cut_mode, int mask_mode)
1287 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1288 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1289 cut_mode, mask_mode);
1292 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1295 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1298 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1301 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1304 void DrawScreenElementThruMask(int x, int y, int element)
1306 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1309 void DrawLevelElementThruMask(int x, int y, int element)
1311 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1314 void DrawLevelFieldThruMask(int x, int y)
1316 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1319 void ErdreichAnbroeckeln(int x, int y)
1321 int i, width, height, cx,cy;
1322 int ux = LEVELX(x), uy = LEVELY(y);
1323 int element, graphic;
1325 static int xy[4][2] =
1333 if (!IN_LEV_FIELD(ux, uy))
1336 element = Feld[ux][uy];
1338 if (element == EL_ERDREICH ||
1339 element == EL_LANDMINE ||
1340 element == EL_TRAP_INACTIVE ||
1341 element == EL_TRAP_ACTIVE)
1343 if (!IN_SCR_FIELD(x, y))
1346 graphic = GFX_ERDENRAND;
1352 uxx = ux + xy[i][0];
1353 uyy = uy + xy[i][1];
1354 if (!IN_LEV_FIELD(uxx, uyy))
1357 element = Feld[uxx][uyy];
1359 if (element == EL_ERDREICH ||
1360 element == EL_LANDMINE ||
1361 element == EL_TRAP_INACTIVE ||
1362 element == EL_TRAP_ACTIVE)
1365 if (i == 1 || i == 2)
1369 cx = (i == 2 ? TILEX - snip : 0);
1377 cy = (i == 3 ? TILEY - snip : 0);
1380 BlitBitmap(pix[PIX_BACK], drawto_field,
1381 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1382 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1383 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1386 MarkTileDirty(x, y);
1390 graphic = GFX_ERDENRAND;
1394 int xx, yy, uxx, uyy;
1398 uxx = ux + xy[i][0];
1399 uyy = uy + xy[i][1];
1401 if (!IN_LEV_FIELD(uxx, uyy) ||
1402 (Feld[uxx][uyy] != EL_ERDREICH &&
1403 Feld[uxx][uyy] != EL_LANDMINE &&
1404 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1405 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1406 !IN_SCR_FIELD(xx, yy))
1409 if (i == 1 || i == 2)
1413 cx = (i == 1 ? TILEX - snip : 0);
1421 cy = (i==0 ? TILEY-snip : 0);
1424 BlitBitmap(pix[PIX_BACK], drawto_field,
1425 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1426 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1427 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1429 MarkTileDirty(xx, yy);
1434 void DrawScreenElement(int x, int y, int element)
1436 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1437 ErdreichAnbroeckeln(x, y);
1440 void DrawLevelElement(int x, int y, int element)
1442 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1443 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1446 void DrawScreenField(int x, int y)
1448 int ux = LEVELX(x), uy = LEVELY(y);
1451 if (!IN_LEV_FIELD(ux, uy))
1453 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1454 element = EL_LEERRAUM;
1456 element = BorderElement;
1458 DrawScreenElement(x, y, element);
1462 element = Feld[ux][uy];
1464 if (IS_MOVING(ux, uy))
1466 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1467 boolean cut_mode = NO_CUTTING;
1469 if (Store[ux][uy] == EL_MORAST_LEER ||
1470 Store[ux][uy] == EL_MAGIC_WALL_EMPTY ||
1471 Store[ux][uy] == EL_MAGIC_WALL_BD_EMPTY ||
1472 Store[ux][uy] == EL_AMOEBE_NASS)
1473 cut_mode = CUT_ABOVE;
1474 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1475 Store[ux][uy] == EL_MAGIC_WALL_FULL ||
1476 Store[ux][uy] == EL_MAGIC_WALL_BD_FULL)
1477 cut_mode = CUT_BELOW;
1479 if (cut_mode == CUT_ABOVE)
1480 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1482 DrawScreenElement(x, y, EL_LEERRAUM);
1485 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1487 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1489 if (Store[ux][uy] == EL_SALZSAEURE)
1490 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1492 else if (IS_BLOCKED(ux, uy))
1497 boolean cut_mode = NO_CUTTING;
1499 Blocked2Moving(ux, uy, &oldx, &oldy);
1502 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1503 MovDir[oldx][oldy] == MV_RIGHT);
1505 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1506 Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
1507 Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
1508 Store[oldx][oldy] == EL_AMOEBE_NASS)
1509 cut_mode = CUT_ABOVE;
1511 DrawScreenElement(x, y, EL_LEERRAUM);
1512 element = Feld[oldx][oldy];
1515 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1517 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1519 else if (IS_DRAWABLE(element))
1520 DrawScreenElement(x, y, element);
1522 DrawScreenElement(x, y, EL_LEERRAUM);
1525 void DrawLevelField(int x, int y)
1527 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1528 DrawScreenField(SCREENX(x), SCREENY(y));
1529 else if (IS_MOVING(x, y))
1533 Moving2Blocked(x, y, &newx, &newy);
1534 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1535 DrawScreenField(SCREENX(newx), SCREENY(newy));
1537 else if (IS_BLOCKED(x, y))
1541 Blocked2Moving(x, y, &oldx, &oldy);
1542 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1543 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1547 void DrawMiniElement(int x, int y, int element)
1553 DrawMiniGraphic(x, y, -1);
1557 graphic = el2gfx(element);
1558 DrawMiniGraphic(x, y, graphic);
1561 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1563 int x = sx + scroll_x, y = sy + scroll_y;
1565 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1566 DrawMiniElement(sx, sy, EL_LEERRAUM);
1567 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1568 DrawMiniElement(sx, sy, Feld[x][y]);
1571 int steel_type, steel_position;
1574 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1575 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1576 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1577 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1578 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1579 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1582 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1583 steel_position = (x == -1 && y == -1 ? 0 :
1584 x == lev_fieldx && y == -1 ? 1 :
1585 x == -1 && y == lev_fieldy ? 2 :
1586 x == lev_fieldx && y == lev_fieldy ? 3 :
1587 x == -1 || x == lev_fieldx ? 4 :
1588 y == -1 || y == lev_fieldy ? 5 : -1);
1590 if (steel_position != -1)
1591 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1595 void DrawMicroElement(int xpos, int ypos, int element)
1599 if (element == EL_LEERRAUM)
1602 graphic = el2gfx(element);
1604 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1606 graphic -= GFX_START_ROCKSSP;
1607 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1608 BlitBitmap(pix[PIX_SP], drawto,
1609 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1610 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1611 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1613 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1615 graphic -= GFX_START_ROCKSDC;
1616 BlitBitmap(pix[PIX_DC], drawto,
1617 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1618 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1619 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1621 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1623 graphic -= GFX_START_ROCKSMORE;
1624 BlitBitmap(pix[PIX_MORE], drawto,
1625 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1626 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1627 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1630 BlitBitmap(pix[PIX_BACK], drawto,
1631 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1632 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1633 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1642 for(x=BX1; x<=BX2; x++)
1643 for(y=BY1; y<=BY2; y++)
1644 DrawScreenField(x, y);
1646 redraw_mask |= REDRAW_FIELD;
1649 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1653 for(x=0; x<size_x; x++)
1654 for(y=0; y<size_y; y++)
1655 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1657 redraw_mask |= REDRAW_FIELD;
1660 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1664 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1666 if (lev_fieldx < STD_LEV_FIELDX)
1667 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1668 if (lev_fieldy < STD_LEV_FIELDY)
1669 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1671 xpos += MICRO_TILEX;
1672 ypos += MICRO_TILEY;
1674 for(x=-1; x<=STD_LEV_FIELDX; x++)
1676 for(y=-1; y<=STD_LEV_FIELDY; y++)
1678 int lx = from_x + x, ly = from_y + y;
1680 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1681 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1683 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1684 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1689 redraw_mask |= REDRAW_MICROLEVEL;
1692 #define MICROLABEL_EMPTY 0
1693 #define MICROLABEL_LEVEL_NAME 1
1694 #define MICROLABEL_CREATED_BY 2
1695 #define MICROLABEL_LEVEL_AUTHOR 3
1696 #define MICROLABEL_IMPORTED_FROM 4
1697 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1699 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1701 static void DrawMicroLevelLabelExt(int mode)
1703 char label_text[MAX_MICROLABEL_SIZE + 1];
1705 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1707 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1708 mode == MICROLABEL_CREATED_BY ? "created by" :
1709 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1710 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1711 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1712 leveldir_current->imported_from : ""),
1713 MAX_MICROLABEL_SIZE);
1714 label_text[MAX_MICROLABEL_SIZE] = '\0';
1716 if (strlen(label_text) > 0)
1718 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1719 int lypos = MICROLABEL_YPOS;
1721 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1724 redraw_mask |= REDRAW_MICROLEVEL;
1727 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1729 static unsigned long scroll_delay = 0;
1730 static unsigned long label_delay = 0;
1731 static int from_x, from_y, scroll_direction;
1732 static int label_state, label_counter;
1736 from_x = from_y = 0;
1737 scroll_direction = MV_RIGHT;
1741 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1742 DrawMicroLevelLabelExt(label_state);
1744 /* initialize delay counters */
1745 DelayReached(&scroll_delay, 0);
1746 DelayReached(&label_delay, 0);
1751 /* scroll micro level, if needed */
1752 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1753 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1755 switch (scroll_direction)
1761 scroll_direction = MV_UP;
1765 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1768 scroll_direction = MV_DOWN;
1775 scroll_direction = MV_RIGHT;
1779 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1782 scroll_direction = MV_LEFT;
1789 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1792 /* redraw micro level label, if needed */
1793 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1794 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1795 strcmp(level.author, leveldir_current->name) != 0 &&
1796 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1798 int max_label_counter = 23;
1800 if (leveldir_current->imported_from != NULL)
1801 max_label_counter += 14;
1803 label_counter = (label_counter + 1) % max_label_counter;
1804 label_state = (label_counter >= 0 && label_counter <= 7 ?
1805 MICROLABEL_LEVEL_NAME :
1806 label_counter >= 9 && label_counter <= 12 ?
1807 MICROLABEL_CREATED_BY :
1808 label_counter >= 14 && label_counter <= 21 ?
1809 MICROLABEL_LEVEL_AUTHOR :
1810 label_counter >= 23 && label_counter <= 26 ?
1811 MICROLABEL_IMPORTED_FROM :
1812 label_counter >= 28 && label_counter <= 35 ?
1813 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1814 DrawMicroLevelLabelExt(label_state);
1818 int REQ_in_range(int x, int y)
1820 if (y > DY+249 && y < DY+278)
1822 if (x > DX+1 && x < DX+48)
1824 else if (x > DX+51 && x < DX+98)
1830 boolean Request(char *text, unsigned int req_state)
1832 int mx, my, ty, result = -1;
1833 unsigned int old_door_state;
1835 #if defined(PLATFORM_UNIX)
1836 /* pause network game while waiting for request to answer */
1837 if (options.network &&
1838 game_status == PLAYING &&
1839 req_state & REQUEST_WAIT_FOR)
1840 SendToServer_PausePlaying();
1843 old_door_state = GetDoorState();
1847 CloseDoor(DOOR_CLOSE_1);
1849 /* save old door content */
1850 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1851 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1852 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1854 /* clear door drawing field */
1855 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1857 /* write text for request */
1858 for(ty=0; ty<13; ty++)
1866 for(tl=0,tx=0; tx<7; tl++,tx++)
1869 if (!tc || tc == 32)
1880 DrawTextExt(drawto, DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1881 txt, FS_SMALL, FC_YELLOW);
1882 text += tl + (tc == 32 ? 1 : 0);
1885 if (req_state & REQ_ASK)
1887 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1888 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1890 else if (req_state & REQ_CONFIRM)
1892 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1894 else if (req_state & REQ_PLAYER)
1896 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1897 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1898 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1899 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1902 /* copy request gadgets to door backbuffer */
1903 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1904 DX, DY, DXSIZE, DYSIZE,
1905 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1907 OpenDoor(DOOR_OPEN_1);
1913 if (!(req_state & REQUEST_WAIT_FOR))
1916 if (game_status != MAINMENU)
1919 button_status = MB_RELEASED;
1921 request_gadget_id = -1;
1933 case EVENT_BUTTONPRESS:
1934 case EVENT_BUTTONRELEASE:
1935 case EVENT_MOTIONNOTIFY:
1937 if (event.type == EVENT_MOTIONNOTIFY)
1939 if (!PointerInWindow(window))
1940 continue; /* window and pointer are on different screens */
1945 motion_status = TRUE;
1946 mx = ((MotionEvent *) &event)->x;
1947 my = ((MotionEvent *) &event)->y;
1951 motion_status = FALSE;
1952 mx = ((ButtonEvent *) &event)->x;
1953 my = ((ButtonEvent *) &event)->y;
1954 if (event.type == EVENT_BUTTONPRESS)
1955 button_status = ((ButtonEvent *) &event)->button;
1957 button_status = MB_RELEASED;
1960 /* this sets 'request_gadget_id' */
1961 HandleGadgets(mx, my, button_status);
1963 switch(request_gadget_id)
1965 case TOOL_CTRL_ID_YES:
1968 case TOOL_CTRL_ID_NO:
1971 case TOOL_CTRL_ID_CONFIRM:
1972 result = TRUE | FALSE;
1975 case TOOL_CTRL_ID_PLAYER_1:
1978 case TOOL_CTRL_ID_PLAYER_2:
1981 case TOOL_CTRL_ID_PLAYER_3:
1984 case TOOL_CTRL_ID_PLAYER_4:
1995 case EVENT_KEYPRESS:
1996 switch(GetEventKey((KeyEvent *)&event, TRUE))
2009 if (req_state & REQ_PLAYER)
2013 case EVENT_KEYRELEASE:
2014 key_joystick_mapping = 0;
2018 HandleOtherEvents(&event);
2022 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
2024 int joy = AnyJoystick();
2026 if (joy & JOY_BUTTON_1)
2028 else if (joy & JOY_BUTTON_2)
2034 /* don't eat all CPU time */
2038 if (game_status != MAINMENU)
2043 if (!(req_state & REQ_STAY_OPEN))
2045 CloseDoor(DOOR_CLOSE_1);
2047 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2049 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2050 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2051 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2052 OpenDoor(DOOR_OPEN_1);
2058 #if defined(PLATFORM_UNIX)
2059 /* continue network game after request */
2060 if (options.network &&
2061 game_status == PLAYING &&
2062 req_state & REQUEST_WAIT_FOR)
2063 SendToServer_ContinuePlaying();
2069 unsigned int OpenDoor(unsigned int door_state)
2071 unsigned int new_door_state;
2073 if (door_state & DOOR_COPY_BACK)
2075 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2076 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2077 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2078 door_state &= ~DOOR_COPY_BACK;
2081 new_door_state = MoveDoor(door_state);
2083 return(new_door_state);
2086 unsigned int CloseDoor(unsigned int door_state)
2088 unsigned int new_door_state;
2090 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2091 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2092 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2093 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2095 new_door_state = MoveDoor(door_state);
2097 return(new_door_state);
2100 unsigned int GetDoorState()
2102 return(MoveDoor(DOOR_GET_STATE));
2105 unsigned int MoveDoor(unsigned int door_state)
2107 static int door1 = DOOR_OPEN_1;
2108 static int door2 = DOOR_CLOSE_2;
2109 static unsigned long door_delay = 0;
2110 int x, start, stepsize = 2;
2111 unsigned long door_delay_value = stepsize * 5;
2113 if (door_state == DOOR_GET_STATE)
2114 return(door1 | door2);
2116 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2117 door_state &= ~DOOR_OPEN_1;
2118 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2119 door_state &= ~DOOR_CLOSE_1;
2120 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2121 door_state &= ~DOOR_OPEN_2;
2122 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2123 door_state &= ~DOOR_CLOSE_2;
2125 if (setup.quick_doors)
2128 door_delay_value = 0;
2129 StopSound(SND_OEFFNEN);
2132 if (door_state & DOOR_ACTION)
2134 if (!(door_state & DOOR_NO_DELAY))
2135 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2137 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2139 for(x=start; x<=DXSIZE; x+=stepsize)
2141 Bitmap bitmap = pix[PIX_DOOR];
2142 GC gc = bitmap->stored_clip_gc;
2144 WaitUntilDelayReached(&door_delay, door_delay_value);
2146 if (door_state & DOOR_ACTION_1)
2148 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2149 int j = (DXSIZE - i) / 3;
2151 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2152 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2153 DXSIZE,DYSIZE - i/2, DX, DY);
2155 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2157 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2158 BlitBitmapMasked(bitmap, drawto,
2159 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2160 DX + DXSIZE - i, DY + j);
2161 BlitBitmapMasked(bitmap, drawto,
2162 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2163 DX + DXSIZE - i, DY + 140 + j);
2164 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2165 BlitBitmapMasked(bitmap, drawto,
2166 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2168 BlitBitmapMasked(bitmap, drawto,
2169 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2172 BlitBitmapMasked(bitmap, drawto,
2173 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2175 BlitBitmapMasked(bitmap, drawto,
2176 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2178 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2179 BlitBitmapMasked(bitmap, drawto,
2180 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2181 DX + DXSIZE - i, DY + 77 + j);
2182 BlitBitmapMasked(bitmap, drawto,
2183 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2184 DX + DXSIZE - i, DY + 203 + j);
2186 redraw_mask |= REDRAW_DOOR_1;
2189 if (door_state & DOOR_ACTION_2)
2191 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2192 int j = (VXSIZE - i) / 3;
2194 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2195 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2196 VXSIZE, VYSIZE - i/2, VX, VY);
2198 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2200 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2201 BlitBitmapMasked(bitmap, drawto,
2202 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2203 VX + VXSIZE-i, VY+j);
2204 SetClipOrigin(bitmap, gc,
2205 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2206 BlitBitmapMasked(bitmap, drawto,
2207 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2210 BlitBitmapMasked(bitmap, drawto,
2211 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2212 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2213 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2214 BlitBitmapMasked(bitmap, drawto,
2215 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2217 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2219 redraw_mask |= REDRAW_DOOR_2;
2224 if (game_status == MAINMENU)
2229 if (setup.quick_doors)
2230 StopSound(SND_OEFFNEN);
2232 if (door_state & DOOR_ACTION_1)
2233 door1 = door_state & DOOR_ACTION_1;
2234 if (door_state & DOOR_ACTION_2)
2235 door2 = door_state & DOOR_ACTION_2;
2237 return (door1 | door2);
2240 void DrawSpecialEditorDoor()
2242 /* draw bigger toolbox window */
2243 BlitBitmap(pix[PIX_DOOR], drawto,
2244 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2246 redraw_mask |= REDRAW_ALL;
2249 void UndrawSpecialEditorDoor()
2251 /* draw normal tape recorder window */
2252 BlitBitmap(pix[PIX_BACK], drawto,
2253 562, 344, 108, 56, EX - 4, EY - 12);
2255 redraw_mask |= REDRAW_ALL;
2259 int ReadPixel(DrawBuffer bitmap, int x, int y)
2261 XImage *pixel_image;
2262 unsigned long pixel_value;
2264 pixel_image = XGetImage(display, bitmap->drawable,
2265 x, y, 1, 1, AllPlanes, ZPixmap);
2266 pixel_value = XGetPixel(pixel_image, 0, 0);
2268 XDestroyImage(pixel_image);
2274 /* ---------- new tool button stuff ---------------------------------------- */
2276 /* graphic position values for tool buttons */
2277 #define TOOL_BUTTON_YES_XPOS 2
2278 #define TOOL_BUTTON_YES_YPOS 250
2279 #define TOOL_BUTTON_YES_GFX_YPOS 0
2280 #define TOOL_BUTTON_YES_XSIZE 46
2281 #define TOOL_BUTTON_YES_YSIZE 28
2282 #define TOOL_BUTTON_NO_XPOS 52
2283 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2284 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2285 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2286 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2287 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2288 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2289 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2290 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2291 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2292 #define TOOL_BUTTON_PLAYER_XSIZE 30
2293 #define TOOL_BUTTON_PLAYER_YSIZE 30
2294 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2295 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2296 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2297 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2298 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2299 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2300 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2301 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2302 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2303 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2304 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2305 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2306 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2307 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2308 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2309 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2310 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2311 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2312 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2313 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2322 } toolbutton_info[NUM_TOOL_BUTTONS] =
2325 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2326 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2327 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2332 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2333 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2334 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2339 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2340 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2341 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2342 TOOL_CTRL_ID_CONFIRM,
2346 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2347 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2348 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2349 TOOL_CTRL_ID_PLAYER_1,
2353 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2354 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2355 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2356 TOOL_CTRL_ID_PLAYER_2,
2360 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2361 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2362 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2363 TOOL_CTRL_ID_PLAYER_3,
2367 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2368 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2369 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2370 TOOL_CTRL_ID_PLAYER_4,
2376 static void DoNotDisplayInfoText(void *ptr)
2382 void CreateToolButtons()
2386 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2388 Bitmap gd_bitmap = pix[PIX_DOOR];
2389 Bitmap deco_bitmap = None;
2390 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2391 struct GadgetInfo *gi;
2392 unsigned long event_mask;
2393 int gd_xoffset, gd_yoffset;
2394 int gd_x1, gd_x2, gd_y;
2397 event_mask = GD_EVENT_RELEASED;
2399 gd_xoffset = toolbutton_info[i].xpos;
2400 gd_yoffset = toolbutton_info[i].ypos;
2401 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2402 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2403 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2405 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2407 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2408 &deco_bitmap, &deco_x, &deco_y);
2409 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2410 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2413 gi = CreateGadget(GDI_CUSTOM_ID, id,
2414 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2415 GDI_X, DX + toolbutton_info[i].x,
2416 GDI_Y, DY + toolbutton_info[i].y,
2417 GDI_WIDTH, toolbutton_info[i].width,
2418 GDI_HEIGHT, toolbutton_info[i].height,
2419 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2420 GDI_STATE, GD_BUTTON_UNPRESSED,
2421 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2422 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2423 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2424 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2425 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2426 GDI_DECORATION_SHIFTING, 1, 1,
2427 GDI_EVENT_MASK, event_mask,
2430 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2433 GDI_CALLBACK_ACTION, HandleToolButtons,
2437 Error(ERR_EXIT, "cannot create gadget");
2439 tool_gadget[id] = gi;
2443 static void UnmapToolButtons()
2447 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2448 UnmapGadget(tool_gadget[i]);
2451 static void HandleToolButtons(struct GadgetInfo *gi)
2453 request_gadget_id = gi->custom_id;
2456 int el2gfx(int element)
2460 case EL_LEERRAUM: return -1;
2461 case EL_ERDREICH: return GFX_ERDREICH;
2462 case EL_MAUERWERK: return GFX_MAUERWERK;
2463 case EL_FELSBODEN: return GFX_FELSBODEN;
2464 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2465 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2466 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2467 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2468 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2469 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2470 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2471 case EL_SPIELER1: return GFX_SPIELER1;
2472 case EL_SPIELER2: return GFX_SPIELER2;
2473 case EL_SPIELER3: return GFX_SPIELER3;
2474 case EL_SPIELER4: return GFX_SPIELER4;
2475 case EL_KAEFER: return GFX_KAEFER;
2476 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2477 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2478 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2479 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2480 case EL_FLIEGER: return GFX_FLIEGER;
2481 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2482 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2483 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2484 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2485 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2486 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2487 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2488 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2489 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2490 case EL_FIREFLY: return GFX_FIREFLY;
2491 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2492 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2493 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2494 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2495 case EL_MAMPFER: return GFX_MAMPFER;
2496 case EL_ROBOT: return GFX_ROBOT;
2497 case EL_BETON: return GFX_BETON;
2498 case EL_DIAMANT: return GFX_DIAMANT;
2499 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2500 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2501 case EL_TROPFEN: return GFX_TROPFEN;
2502 case EL_BOMBE: return GFX_BOMBE;
2503 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2504 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2505 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2506 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2507 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2508 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2509 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2510 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2511 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2512 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2513 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2514 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2515 case EL_LIFE: return GFX_LIFE;
2516 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2517 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2518 case EL_BADEWANNE: return GFX_BADEWANNE;
2519 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2520 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2521 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2522 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2523 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2524 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2525 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2526 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2527 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2528 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2529 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2530 case EL_PFORTE1: return GFX_PFORTE1;
2531 case EL_PFORTE2: return GFX_PFORTE2;
2532 case EL_PFORTE3: return GFX_PFORTE3;
2533 case EL_PFORTE4: return GFX_PFORTE4;
2534 case EL_PFORTE1X: return GFX_PFORTE1X;
2535 case EL_PFORTE2X: return GFX_PFORTE2X;
2536 case EL_PFORTE3X: return GFX_PFORTE3X;
2537 case EL_PFORTE4X: return GFX_PFORTE4X;
2538 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2539 case EL_PACMAN: return GFX_PACMAN;
2540 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2541 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2542 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2543 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2544 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2545 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2546 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2547 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2548 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2549 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2550 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2551 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2552 case EL_MAUER_X: return GFX_MAUER_X;
2553 case EL_MAUER_Y: return GFX_MAUER_Y;
2554 case EL_MAUER_XY: return GFX_MAUER_XY;
2555 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2556 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2557 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2558 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2559 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2560 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2561 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2562 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2563 case EL_MAMPFER2: return GFX_MAMPFER2;
2564 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2565 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2566 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2567 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2568 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2569 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2570 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2571 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2572 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2573 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2574 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2575 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2576 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2577 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2578 case EL_MOLE: return GFX_MOLE;
2579 case EL_PINGUIN: return GFX_PINGUIN;
2580 case EL_SCHWEIN: return GFX_SCHWEIN;
2581 case EL_DRACHE: return GFX_DRACHE;
2582 case EL_SONDE: return GFX_SONDE;
2583 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2584 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2585 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2586 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2587 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2588 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2589 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2590 case EL_SP_ZONK: return GFX_SP_ZONK;
2591 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2592 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2593 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2594 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2595 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2596 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2597 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2598 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2599 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2600 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2601 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2602 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2603 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2604 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2605 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2606 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2607 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2608 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2609 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2610 case EL_PEARL: return GFX_PEARL;
2611 case EL_CRYSTAL: return GFX_CRYSTAL;
2612 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2613 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2614 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2615 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2616 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2617 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2618 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2619 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2620 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2621 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2622 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2623 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2624 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2625 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2626 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2627 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2628 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2629 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2630 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2631 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2632 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2633 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2634 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2635 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2636 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2637 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2638 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2639 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2640 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2641 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2642 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2643 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2644 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2645 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2646 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2647 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2648 case EL_LANDMINE: return GFX_LANDMINE;
2649 case EL_ENVELOPE: return GFX_ENVELOPE;
2650 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2651 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2652 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2653 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2654 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2655 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2656 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2657 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2658 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2659 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2660 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2661 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2662 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2663 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2664 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2665 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2666 case EL_MOLE_UP: return GFX_MOLE_UP;
2667 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2668 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2669 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2670 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2671 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2672 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2673 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2674 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2675 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2676 case EL_BALLOON: return GFX_BALLOON;
2677 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2678 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2679 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2680 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2681 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2682 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2683 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2684 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2685 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2686 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2687 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2688 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2689 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2690 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2691 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2692 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2693 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2694 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2695 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2696 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2697 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2698 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2699 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2700 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2701 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2702 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2703 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2704 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2705 case EL_SPRING: return GFX_SPRING;
2706 case EL_SPRING_MOVING: return GFX_SPRING;
2707 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2708 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2709 case EL_BD_WALL: return GFX_BD_WALL;
2710 case EL_BD_ROCK: return GFX_BD_ROCK;
2711 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2712 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2716 if (IS_CHAR(element))
2717 return GFX_CHAR_START + (element - EL_CHAR_START);
2718 else if (element >= EL_SP_START && element <= EL_SP_END)
2720 int nr_element = element - EL_SP_START;
2721 int gfx_per_line = 8;
2723 (nr_element / gfx_per_line) * SP_PER_LINE +
2724 (nr_element % gfx_per_line);
2726 return GFX_START_ROCKSSP + nr_graphic;