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"
30 #if defined(PLATFORM_MSDOS)
31 extern boolean wait_for_vsync;
34 /* tool button identifiers */
35 #define TOOL_CTRL_ID_YES 0
36 #define TOOL_CTRL_ID_NO 1
37 #define TOOL_CTRL_ID_CONFIRM 2
38 #define TOOL_CTRL_ID_PLAYER_1 3
39 #define TOOL_CTRL_ID_PLAYER_2 4
40 #define TOOL_CTRL_ID_PLAYER_3 5
41 #define TOOL_CTRL_ID_PLAYER_4 6
43 #define NUM_TOOL_BUTTONS 7
45 /* forward declaration for internal use */
46 static int getGraphicAnimationPhase(int, int, int);
47 static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
49 static void UnmapToolButtons();
50 static void HandleToolButtons(struct GadgetInfo *);
52 static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
53 static int request_gadget_id = -1;
55 void SetDrawtoField(int mode)
57 if (mode == DRAW_BUFFERED && setup.soft_scrolling)
68 drawto_field = fieldbuffer;
70 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
81 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
88 DrawBuffer buffer = (drawto_field == window ? backbuffer : drawto_field);
90 if (setup.direct_draw && game_status == PLAYING)
91 redraw_mask &= ~REDRAW_MAIN;
93 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
94 redraw_mask |= REDRAW_FIELD;
96 if (redraw_mask & REDRAW_FIELD)
97 redraw_mask &= ~REDRAW_TILES;
102 if (global.fps_slowdown && game_status == PLAYING)
104 static boolean last_frame_skipped = FALSE;
105 boolean skip_even_when_not_scrolling = TRUE;
106 boolean just_scrolling = (ScreenMovDir != 0);
107 boolean verbose = FALSE;
109 if (global.fps_slowdown_factor > 1 &&
110 (FrameCounter % global.fps_slowdown_factor) &&
111 (just_scrolling || skip_even_when_not_scrolling))
113 redraw_mask &= ~REDRAW_MAIN;
115 last_frame_skipped = TRUE;
118 printf("FRAME SKIPPED\n");
122 if (last_frame_skipped)
123 redraw_mask |= REDRAW_FIELD;
125 last_frame_skipped = FALSE;
128 printf("frame not skipped\n");
132 /* synchronize X11 graphics at this point; if we would synchronize the
133 display immediately after the buffer switching (after the XFlush),
134 this could mean that we have to wait for the graphics to complete,
135 although we could go on doing calculations for the next frame */
139 if (redraw_mask & REDRAW_ALL)
141 BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
145 if (redraw_mask & REDRAW_FIELD)
147 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
149 BlitBitmap(backbuffer, window,
150 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
154 int fx = FX, fy = FY;
156 if (setup.soft_scrolling)
158 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
159 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
162 if (setup.soft_scrolling ||
163 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
164 ABS(ScreenMovPos) == ScrollStepSize ||
165 redraw_tiles > REDRAWTILES_THRESHOLD)
167 BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
171 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
173 (setup.soft_scrolling ?
174 "setup.soft_scrolling" :
175 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
176 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
177 ABS(ScreenGfxPos) == ScrollStepSize ?
178 "ABS(ScreenGfxPos) == ScrollStepSize" :
179 "redraw_tiles > REDRAWTILES_THRESHOLD"));
185 redraw_mask &= ~REDRAW_MAIN;
188 if (redraw_mask & REDRAW_DOORS)
190 if (redraw_mask & REDRAW_DOOR_1)
191 BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
192 if (redraw_mask & REDRAW_DOOR_2)
194 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
195 BlitBitmap(backbuffer, window, VX,VY, VXSIZE,VYSIZE, VX,VY);
198 if (redraw_mask & REDRAW_VIDEO_1)
199 BlitBitmap(backbuffer, window,
200 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
201 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
202 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
203 if (redraw_mask & REDRAW_VIDEO_2)
204 BlitBitmap(backbuffer, window,
205 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
206 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
207 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
208 if (redraw_mask & REDRAW_VIDEO_3)
209 BlitBitmap(backbuffer, window,
210 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
211 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
212 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
215 if (redraw_mask & REDRAW_DOOR_3)
216 BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
217 redraw_mask &= ~REDRAW_DOORS;
220 if (redraw_mask & REDRAW_MICROLEVEL)
222 BlitBitmap(backbuffer, window,
223 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
224 MICROLEV_XPOS, MICROLEV_YPOS);
225 BlitBitmap(backbuffer, window,
226 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
227 SX, MICROLABEL_YPOS);
228 redraw_mask &= ~REDRAW_MICROLEVEL;
231 if (redraw_mask & REDRAW_TILES)
233 for(x=0; x<SCR_FIELDX; x++)
234 for(y=0; y<SCR_FIELDY; y++)
235 if (redraw[redraw_x1 + x][redraw_y1 + y])
236 BlitBitmap(buffer, window,
237 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
238 SX + x * TILEX, SY + y * TILEY);
241 if (redraw_mask & REDRAW_FPS) /* display frames per second */
246 sprintf(info1, " (only every %d. frame)", global.fps_slowdown_factor);
247 if (!global.fps_slowdown)
250 sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
251 DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
256 for(x=0; x<MAX_BUF_XSIZE; x++)
257 for(y=0; y<MAX_BUF_YSIZE; y++)
266 long fading_delay = 300;
268 if (setup.fading && (redraw_mask & REDRAW_FIELD))
275 ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
278 for(i=0;i<2*FULL_SYSIZE;i++)
280 for(y=0;y<FULL_SYSIZE;y++)
282 BlitBitmap(backbuffer, window,
283 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
291 for(i=1;i<FULL_SYSIZE;i+=2)
292 BlitBitmap(backbuffer, window,
293 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
299 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
300 BlitBitmapMasked(backbuffer, window,
301 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
306 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
307 BlitBitmapMasked(backbuffer, window,
308 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
313 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
314 BlitBitmapMasked(backbuffer, window,
315 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
320 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
321 BlitBitmapMasked(backbuffer, window,
322 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
327 redraw_mask &= ~REDRAW_MAIN;
336 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
338 if (setup.soft_scrolling && game_status == PLAYING)
340 ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
341 SetDrawtoField(DRAW_BUFFERED);
344 SetDrawtoField(DRAW_BACKBUFFER);
346 if (setup.direct_draw && game_status == PLAYING)
348 ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
349 SetDrawtoField(DRAW_DIRECT);
352 redraw_mask |= REDRAW_FIELD;
357 int getFontWidth(int font_size, int font_type)
359 return (font_size == FS_BIG ? FONT1_XSIZE :
360 font_size == FS_MEDIUM ? FONT6_XSIZE :
361 font_type == FC_SPECIAL1 ? FONT3_XSIZE :
362 font_type == FC_SPECIAL2 ? FONT4_XSIZE :
363 font_type == FC_SPECIAL3 ? FONT5_XSIZE :
367 int getFontHeight(int font_size, int font_type)
369 return (font_size == FS_BIG ? FONT1_YSIZE :
370 font_size == FS_MEDIUM ? FONT6_YSIZE :
371 font_type == FC_SPECIAL1 ? FONT3_YSIZE :
372 font_type == FC_SPECIAL2 ? FONT4_YSIZE :
373 font_type == FC_SPECIAL3 ? FONT5_YSIZE :
377 void DrawInitText(char *text, int ypos, int color)
379 if (window && pix[PIX_SMALLFONT])
381 ClearRectangle(window, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
382 DrawTextExt(window, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
383 ypos, text, FS_SMALL, color);
388 void DrawTextFCentered(int y, int font_type, char *format, ...)
390 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
391 int font_width = getFontWidth(FS_SMALL, font_type);
394 va_start(ap, format);
395 vsprintf(buffer, format, ap);
398 DrawText(SX + (SXSIZE - strlen(buffer) * font_width) / 2, SY + y,
399 buffer, FS_SMALL, font_type);
402 void DrawTextF(int x, int y, int font_type, char *format, ...)
404 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
407 va_start(ap, format);
408 vsprintf(buffer, format, ap);
411 DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
414 void DrawText(int x, int y, char *text, int font_size, int font_type)
416 DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
419 redraw_mask |= REDRAW_FIELD;
421 redraw_mask |= REDRAW_DOOR_1;
424 void DrawTextExt(DrawBuffer d, GC gc, int x, int y,
425 char *text, int font_size, int font_type)
427 int font_width, font_height, font_start;
429 boolean print_inverse = FALSE;
431 if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
432 font_size = FS_SMALL;
433 if (font_type < FC_RED || font_type > FC_SPECIAL3)
436 font_width = getFontWidth(font_size, font_type);
437 font_height = getFontHeight(font_size, font_type);
439 font_bitmap = (font_size == FS_BIG ? PIX_BIGFONT :
440 font_size == FS_MEDIUM ? PIX_MEDIUMFONT :
442 font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
443 font_size == FS_MEDIUM ? FONT6_YSIZE :
445 FONT_LINES_PER_FONT);
447 if (font_type == FC_SPECIAL3)
448 font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
454 if (c == '~' && font_size == FS_SMALL)
456 print_inverse = TRUE;
460 if (c >= 'a' && c <= 'z')
462 else if (c == 'ä' || c == 'Ä')
464 else if (c == 'ö' || c == 'Ö')
466 else if (c == 'ü' || c == 'Ü')
469 if (c >= 32 && c <= 95)
471 int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
472 int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
473 int dest_x = x, dest_y = y;
477 BlitBitmap(pix[font_bitmap], d,
478 FONT_CHARS_PER_LINE * font_width,
479 3 * font_height + font_start,
480 font_width, font_height, x, y);
482 SetClipOrigin(clip_gc[font_bitmap], dest_x - src_x, dest_y - src_y);
483 BlitBitmapMasked(pix_masked[font_bitmap], d,
484 0, 0, font_width, font_height, dest_x, dest_y);
487 BlitBitmap(pix[font_bitmap], d,
488 src_x, src_y, font_width, font_height, dest_x, dest_y);
497 void MarkTileDirty(int x, int y)
499 int xx = redraw_x1 + x;
500 int yy = redraw_y1 + y;
505 redraw[xx][yy] = TRUE;
506 redraw_mask |= REDRAW_TILES;
509 void SetBorderElement()
513 BorderElement = EL_LEERRAUM;
515 for(y=0; y<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
517 for(x=0; x<lev_fieldx; x++)
519 if (!IS_MASSIVE(Feld[x][y]))
520 BorderElement = EL_BETON;
522 if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
528 void DrawAllPlayers()
532 for(i=0; i<MAX_PLAYERS; i++)
533 if (stored_player[i].active)
534 DrawPlayer(&stored_player[i]);
537 void DrawPlayerField(int x, int y)
539 if (!IS_PLAYER(x, y))
542 DrawPlayer(PLAYERINFO(x, y));
545 void DrawPlayer(struct PlayerInfo *player)
547 int jx = player->jx, jy = player->jy;
548 int last_jx = player->last_jx, last_jy = player->last_jy;
549 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
550 int sx = SCREENX(jx), sy = SCREENY(jy);
551 int sxx = 0, syy = 0;
552 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
554 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
556 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
560 if (!IN_LEV_FIELD(jx,jy))
562 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
563 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
564 printf("DrawPlayerField(): This should never happen!\n");
569 if (element == EL_EXPLODING)
572 /* draw things in the field the player is leaving, if needed */
574 if (player_is_moving)
576 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
578 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
579 DrawLevelFieldThruMask(last_jx, last_jy);
581 else if (last_element == EL_DYNAMITE_ACTIVE)
582 DrawDynamite(last_jx, last_jy);
584 DrawLevelField(last_jx, last_jy);
586 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
590 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
591 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
593 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
596 DrawLevelField(next_jx, next_jy);
600 if (!IN_SCR_FIELD(sx, sy))
603 if (setup.direct_draw)
604 SetDrawtoField(DRAW_BUFFERED);
606 /* draw things behind the player, if needed */
609 DrawLevelElement(jx, jy, Store[jx][jy]);
610 else if (!IS_ACTIVE_BOMB(element))
611 DrawLevelField(jx, jy);
613 /* draw player himself */
615 if (game.emulation == EMU_SUPAPLEX)
617 static int last_dir = MV_LEFT;
618 int action = (player->programmed_action ? player->programmed_action :
620 boolean action_moving =
622 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
623 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
625 graphic = GFX_SP_MURPHY;
629 if (player->MovDir == MV_LEFT)
630 graphic = GFX_MURPHY_PUSH_LEFT;
631 else if (player->MovDir == MV_RIGHT)
632 graphic = GFX_MURPHY_PUSH_RIGHT;
633 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
634 graphic = GFX_MURPHY_PUSH_LEFT;
635 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
636 graphic = GFX_MURPHY_PUSH_RIGHT;
638 else if (player->snapped)
640 if (player->MovDir == MV_LEFT)
641 graphic = GFX_MURPHY_SNAP_LEFT;
642 else if (player->MovDir == MV_RIGHT)
643 graphic = GFX_MURPHY_SNAP_RIGHT;
644 else if (player->MovDir == MV_UP)
645 graphic = GFX_MURPHY_SNAP_UP;
646 else if (player->MovDir == MV_DOWN)
647 graphic = GFX_MURPHY_SNAP_DOWN;
649 else if (action_moving)
651 if (player->MovDir == MV_LEFT)
652 graphic = GFX_MURPHY_GO_LEFT;
653 else if (player->MovDir == MV_RIGHT)
654 graphic = GFX_MURPHY_GO_RIGHT;
655 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
656 graphic = GFX_MURPHY_GO_LEFT;
657 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
658 graphic = GFX_MURPHY_GO_RIGHT;
660 graphic = GFX_MURPHY_GO_LEFT;
662 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
665 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
666 last_dir = player->MovDir;
670 if (player->MovDir == MV_LEFT)
672 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
673 else if (player->MovDir == MV_RIGHT)
675 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
676 else if (player->MovDir == MV_UP)
677 graphic = GFX_SPIELER1_UP;
678 else /* MV_DOWN || MV_NO_MOVING */
679 graphic = GFX_SPIELER1_DOWN;
681 graphic += player->index_nr * 3 * HEROES_PER_LINE;
682 graphic += player->Frame;
687 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
688 sxx = player->GfxPos;
690 syy = player->GfxPos;
693 if (!setup.soft_scrolling && ScreenMovPos)
696 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
698 if (SHIELD_ON(player))
700 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
701 GFX2_SHIELD_PASSIVE);
703 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
704 3, 8, ANIM_OSCILLATE);
707 if (player->Pushing && player->GfxPos)
709 int px = SCREENX(next_jx), py = SCREENY(next_jy);
711 if (element == EL_SOKOBAN_FELD_LEER ||
712 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
713 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
717 int element = Feld[next_jx][next_jy];
718 int graphic = el2gfx(element);
720 if ((element == EL_FELSBROCKEN ||
721 element == EL_SP_ZONK ||
722 element == EL_BD_ROCK) && sxx)
724 int phase = (player->GfxPos / (TILEX / 4));
726 if (player->MovDir == MV_LEFT)
729 graphic += (phase + 4) % 4;
732 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
736 /* draw things in front of player (active dynamite or dynabombs) */
738 if (IS_ACTIVE_BOMB(element))
740 graphic = el2gfx(element);
742 if (element == EL_DYNAMITE_ACTIVE)
744 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
749 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
753 if (game.emulation == EMU_SUPAPLEX)
754 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
756 DrawGraphicThruMask(sx, sy, graphic + phase);
759 if (player_is_moving && last_element == EL_EXPLODING)
761 int phase = Frame[last_jx][last_jy];
765 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
766 GFX_EXPLOSION + ((phase - 1) / delay - 1));
769 /* draw elements that stay over the player */
770 /* handle the field the player is leaving ... */
771 if (player_is_moving && IS_OVER_PLAYER(last_element))
772 DrawLevelField(last_jx, last_jy);
773 /* ... and the field the player is entering */
774 if (IS_OVER_PLAYER(element))
775 DrawLevelField(jx, jy);
777 if (setup.direct_draw)
779 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
780 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
781 int x_size = TILEX * (1 + ABS(jx - last_jx));
782 int y_size = TILEY * (1 + ABS(jy - last_jy));
784 BlitBitmap(drawto_field, window,
785 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
786 SetDrawtoField(DRAW_DIRECT);
789 MarkTileDirty(sx,sy);
792 static int getGraphicAnimationPhase(int frames, int delay, int mode)
796 if (mode == ANIM_OSCILLATE)
798 int max_anim_frames = 2 * frames - 2;
799 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
800 phase = (phase < frames ? phase : max_anim_frames - phase);
803 phase = (FrameCounter % (delay * frames)) / delay;
805 if (mode == ANIM_REVERSE)
811 void DrawGraphicAnimationExt(int x, int y, int graphic,
812 int frames, int delay, int mode, int mask_mode)
814 int phase = getGraphicAnimationPhase(frames, delay, mode);
816 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
818 if (mask_mode == USE_MASKING)
819 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
821 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
825 void DrawGraphicAnimation(int x, int y, int graphic,
826 int frames, int delay, int mode)
828 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
831 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
832 int frames, int delay, int mode)
834 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
837 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
840 int frames, int delay,
843 int phase = getGraphicAnimationPhase(frames, delay, mode);
845 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
848 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
850 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
852 graphic -= GFX_START_ROCKSSCREEN;
853 *bitmap_nr = PIX_BACK;
854 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
855 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
857 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
859 graphic -= GFX_START_ROCKSHEROES;
860 *bitmap_nr = PIX_HEROES;
861 *x = (graphic % HEROES_PER_LINE) * TILEX;
862 *y = (graphic / HEROES_PER_LINE) * TILEY;
864 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
866 graphic -= GFX_START_ROCKSSP;
868 *x = (graphic % SP_PER_LINE) * TILEX;
869 *y = (graphic / SP_PER_LINE) * TILEY;
871 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
873 graphic -= GFX_START_ROCKSDC;
875 *x = (graphic % DC_PER_LINE) * TILEX;
876 *y = (graphic / DC_PER_LINE) * TILEY;
878 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
880 graphic -= GFX_START_ROCKSMORE;
881 *bitmap_nr = PIX_MORE;
882 *x = (graphic % MORE_PER_LINE) * TILEX;
883 *y = (graphic / MORE_PER_LINE) * TILEY;
885 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
887 graphic -= GFX_START_ROCKSFONT;
888 *bitmap_nr = PIX_BIGFONT;
889 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
890 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
891 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
901 void DrawGraphic(int x, int y, int graphic)
904 if (!IN_SCR_FIELD(x,y))
906 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
907 printf("DrawGraphic(): This should never happen!\n");
912 DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
916 void DrawGraphicExt(DrawBuffer bitmap, int x, int y, int graphic)
921 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
922 BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
925 void DrawGraphicThruMask(int x, int y, int graphic)
928 if (!IN_SCR_FIELD(x,y))
930 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
931 printf("DrawGraphicThruMask(): This should never happen!\n");
936 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
940 void DrawGraphicThruMaskExt(DrawBuffer d, int dest_x, int dest_y, int graphic)
948 if (graphic == GFX_LEERRAUM)
951 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
952 src_bitmap = pix[bitmap_nr];
953 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
955 if (tile_clipmask[tile] != None)
957 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
958 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
959 BlitBitmapMasked(src_bitmap, d,
960 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
966 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
970 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
971 BlitBitmapMasked(src_bitmap, d,
972 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
976 void DrawMiniGraphic(int x, int y, int graphic)
978 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
979 MarkTileDirty(x/2, y/2);
982 void getMiniGraphicSource(int graphic, Bitmap *bitmap, int *x, int *y)
984 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
986 graphic -= GFX_START_ROCKSSCREEN;
987 *bitmap = pix[PIX_BACK];
988 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
989 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
991 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
993 graphic -= GFX_START_ROCKSSP;
994 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
995 *bitmap = pix[PIX_SP];
996 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
997 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
999 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1001 graphic -= GFX_START_ROCKSDC;
1002 *bitmap = pix[PIX_DC];
1003 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
1004 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
1006 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1008 graphic -= GFX_START_ROCKSMORE;
1009 *bitmap = pix[PIX_MORE];
1010 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
1011 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
1013 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
1015 graphic -= GFX_START_ROCKSFONT;
1016 *bitmap = pix[PIX_SMALLFONT];
1017 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
1018 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
1019 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
1023 *bitmap = pix[PIX_SP];
1024 *x = MINI_SP_STARTX;
1025 *y = MINI_SP_STARTY;
1029 void DrawMiniGraphicExt(DrawBuffer d, int x, int y, int graphic)
1034 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
1035 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
1038 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
1039 int cut_mode, int mask_mode)
1041 int width = TILEX, height = TILEY;
1043 int src_x, src_y, dest_x, dest_y;
1051 DrawGraphic(x, y, graphic);
1055 if (dx || dy) /* Verschiebung der Grafik? */
1057 if (x < BX1) /* Element kommt von links ins Bild */
1064 else if (x > BX2) /* Element kommt von rechts ins Bild */
1070 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1076 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1078 else if (dx) /* allg. Bewegung in x-Richtung */
1079 MarkTileDirty(x + SIGN(dx), y);
1081 if (y < BY1) /* Element kommt von oben ins Bild */
1083 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1091 else if (y > BY2) /* Element kommt von unten ins Bild */
1097 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1103 else if (dy > 0 && cut_mode == CUT_ABOVE)
1105 if (y == BY2) /* Element unterhalb des Bildes */
1111 MarkTileDirty(x, y + 1);
1112 } /* Element verläßt unten das Bild */
1113 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1115 else if (dy) /* allg. Bewegung in y-Richtung */
1116 MarkTileDirty(x, y + SIGN(dy));
1119 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
1120 src_bitmap = pix[bitmap_nr];
1121 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
1126 dest_x = FX + x * TILEX + dx;
1127 dest_y = FY + y * TILEY + dy;
1130 if (!IN_SCR_FIELD(x,y))
1132 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1133 printf("DrawGraphicShifted(): This should never happen!\n");
1138 if (mask_mode == USE_MASKING)
1140 if (tile_clipmask[tile] != None)
1142 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1143 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1144 BlitBitmapMasked(src_bitmap, drawto_field,
1145 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1151 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1155 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1156 BlitBitmapMasked(src_bitmap, drawto_field,
1157 src_x, src_y, width, height, dest_x, dest_y);
1161 BlitBitmap(pix[bitmap_nr], drawto_field,
1162 src_x, src_y, width, height, dest_x, dest_y);
1167 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1170 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1173 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1174 int cut_mode, int mask_mode)
1176 int ux = LEVELX(x), uy = LEVELY(y);
1177 int graphic = el2gfx(element);
1178 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1179 int phase4 = phase8 / 2;
1180 int phase2 = phase8 / 4;
1181 int dir = MovDir[ux][uy];
1183 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1185 graphic += 4 * !phase2;
1189 else if (dir == MV_LEFT)
1191 else if (dir == MV_DOWN)
1194 else if (element == EL_SP_SNIKSNAK)
1197 graphic = GFX_SP_SNIKSNAK_LEFT;
1198 else if (dir == MV_RIGHT)
1199 graphic = GFX_SP_SNIKSNAK_RIGHT;
1200 else if (dir == MV_UP)
1201 graphic = GFX_SP_SNIKSNAK_UP;
1203 graphic = GFX_SP_SNIKSNAK_DOWN;
1205 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1207 else if (element == EL_SP_ELECTRON)
1209 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1211 else if (element == EL_MOLE || element == EL_PINGUIN ||
1212 element == EL_SCHWEIN || element == EL_DRACHE)
1215 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1216 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1217 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1218 else if (dir == MV_RIGHT)
1219 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1220 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1221 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1222 else if (dir == MV_UP)
1223 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1224 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1225 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1227 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1228 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1229 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1233 else if (element == EL_SONDE)
1235 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1237 else if (element == EL_SALZSAEURE)
1239 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1241 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1245 else if (element == EL_BALLOON)
1249 else if ((element == EL_FELSBROCKEN ||
1250 element == EL_SP_ZONK ||
1251 element == EL_BD_ROCK ||
1252 IS_GEM(element)) && !cut_mode)
1254 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1256 if (element == EL_FELSBROCKEN ||
1257 element == EL_SP_ZONK ||
1258 element == EL_BD_ROCK)
1261 graphic += (4 - phase4) % 4;
1262 else if (dir == MV_RIGHT)
1265 graphic += phase2 * 2;
1267 else if (element != EL_SP_INFOTRON)
1271 else if (element == EL_MAGIC_WALL_EMPTY ||
1272 element == EL_MAGIC_WALL_BD_EMPTY ||
1273 element == EL_MAGIC_WALL_FULL ||
1274 element == EL_MAGIC_WALL_BD_FULL)
1276 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1278 else if (IS_AMOEBOID(element))
1280 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1281 graphic += (x + 2 * y + 4) % 4;
1283 else if (element == EL_MAUER_LEBT)
1285 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1287 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1288 links_massiv = TRUE;
1289 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1290 rechts_massiv = TRUE;
1292 if (links_massiv && rechts_massiv)
1293 graphic = GFX_MAUERWERK;
1294 else if (links_massiv)
1295 graphic = GFX_MAUER_R;
1296 else if (rechts_massiv)
1297 graphic = GFX_MAUER_L;
1299 else if ((element == EL_INVISIBLE_STEEL ||
1300 element == EL_UNSICHTBAR ||
1301 element == EL_SAND_INVISIBLE) && game.light_time_left)
1303 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1304 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1305 GFX_SAND_INVISIBLE_ON);
1309 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1310 else if (mask_mode == USE_MASKING)
1311 DrawGraphicThruMask(x, y, graphic);
1313 DrawGraphic(x, y, graphic);
1316 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1317 int cut_mode, int mask_mode)
1319 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1320 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1321 cut_mode, mask_mode);
1324 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1327 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1330 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1333 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1336 void DrawScreenElementThruMask(int x, int y, int element)
1338 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1341 void DrawLevelElementThruMask(int x, int y, int element)
1343 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1346 void DrawLevelFieldThruMask(int x, int y)
1348 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1351 void ErdreichAnbroeckeln(int x, int y)
1353 int i, width, height, cx,cy;
1354 int ux = LEVELX(x), uy = LEVELY(y);
1355 int element, graphic;
1357 static int xy[4][2] =
1365 if (!IN_LEV_FIELD(ux, uy))
1368 element = Feld[ux][uy];
1370 if (element == EL_ERDREICH ||
1371 element == EL_LANDMINE ||
1372 element == EL_TRAP_INACTIVE ||
1373 element == EL_TRAP_ACTIVE)
1375 if (!IN_SCR_FIELD(x, y))
1378 graphic = GFX_ERDENRAND;
1384 uxx = ux + xy[i][0];
1385 uyy = uy + xy[i][1];
1386 if (!IN_LEV_FIELD(uxx, uyy))
1389 element = Feld[uxx][uyy];
1391 if (element == EL_ERDREICH ||
1392 element == EL_LANDMINE ||
1393 element == EL_TRAP_INACTIVE ||
1394 element == EL_TRAP_ACTIVE)
1397 if (i == 1 || i == 2)
1401 cx = (i == 2 ? TILEX - snip : 0);
1409 cy = (i == 3 ? TILEY - snip : 0);
1412 BlitBitmap(pix[PIX_BACK], drawto_field,
1413 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1414 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1415 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1418 MarkTileDirty(x, y);
1422 graphic = GFX_ERDENRAND;
1426 int xx, yy, uxx, uyy;
1430 uxx = ux + xy[i][0];
1431 uyy = uy + xy[i][1];
1433 if (!IN_LEV_FIELD(uxx, uyy) ||
1434 (Feld[uxx][uyy] != EL_ERDREICH &&
1435 Feld[uxx][uyy] != EL_LANDMINE &&
1436 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1437 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1438 !IN_SCR_FIELD(xx, yy))
1441 if (i == 1 || i == 2)
1445 cx = (i == 1 ? TILEX - snip : 0);
1453 cy = (i==0 ? TILEY-snip : 0);
1456 BlitBitmap(pix[PIX_BACK], drawto_field,
1457 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1458 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1459 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1461 MarkTileDirty(xx, yy);
1466 void DrawScreenElement(int x, int y, int element)
1468 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1469 ErdreichAnbroeckeln(x, y);
1472 void DrawLevelElement(int x, int y, int element)
1474 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1475 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1478 void DrawScreenField(int x, int y)
1480 int ux = LEVELX(x), uy = LEVELY(y);
1483 if (!IN_LEV_FIELD(ux, uy))
1485 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1486 element = EL_LEERRAUM;
1488 element = BorderElement;
1490 DrawScreenElement(x, y, element);
1494 element = Feld[ux][uy];
1496 if (IS_MOVING(ux, uy))
1498 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1499 boolean cut_mode = NO_CUTTING;
1501 if (Store[ux][uy] == EL_MORAST_LEER ||
1502 Store[ux][uy] == EL_MAGIC_WALL_EMPTY ||
1503 Store[ux][uy] == EL_MAGIC_WALL_BD_EMPTY ||
1504 Store[ux][uy] == EL_AMOEBE_NASS)
1505 cut_mode = CUT_ABOVE;
1506 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1507 Store[ux][uy] == EL_MAGIC_WALL_FULL ||
1508 Store[ux][uy] == EL_MAGIC_WALL_BD_FULL)
1509 cut_mode = CUT_BELOW;
1511 if (cut_mode == CUT_ABOVE)
1512 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1514 DrawScreenElement(x, y, EL_LEERRAUM);
1517 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1519 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1521 if (Store[ux][uy] == EL_SALZSAEURE)
1522 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1524 else if (IS_BLOCKED(ux, uy))
1529 boolean cut_mode = NO_CUTTING;
1531 Blocked2Moving(ux, uy, &oldx, &oldy);
1534 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1535 MovDir[oldx][oldy] == MV_RIGHT);
1537 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1538 Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
1539 Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
1540 Store[oldx][oldy] == EL_AMOEBE_NASS)
1541 cut_mode = CUT_ABOVE;
1543 DrawScreenElement(x, y, EL_LEERRAUM);
1544 element = Feld[oldx][oldy];
1547 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1549 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1551 else if (IS_DRAWABLE(element))
1552 DrawScreenElement(x, y, element);
1554 DrawScreenElement(x, y, EL_LEERRAUM);
1557 void DrawLevelField(int x, int y)
1559 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1560 DrawScreenField(SCREENX(x), SCREENY(y));
1561 else if (IS_MOVING(x, y))
1565 Moving2Blocked(x, y, &newx, &newy);
1566 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1567 DrawScreenField(SCREENX(newx), SCREENY(newy));
1569 else if (IS_BLOCKED(x, y))
1573 Blocked2Moving(x, y, &oldx, &oldy);
1574 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1575 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1579 void DrawMiniElement(int x, int y, int element)
1585 DrawMiniGraphic(x, y, -1);
1589 graphic = el2gfx(element);
1590 DrawMiniGraphic(x, y, graphic);
1593 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1595 int x = sx + scroll_x, y = sy + scroll_y;
1597 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1598 DrawMiniElement(sx, sy, EL_LEERRAUM);
1599 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1600 DrawMiniElement(sx, sy, Feld[x][y]);
1603 int steel_type, steel_position;
1606 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1607 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1608 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1609 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1610 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1611 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1614 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1615 steel_position = (x == -1 && y == -1 ? 0 :
1616 x == lev_fieldx && y == -1 ? 1 :
1617 x == -1 && y == lev_fieldy ? 2 :
1618 x == lev_fieldx && y == lev_fieldy ? 3 :
1619 x == -1 || x == lev_fieldx ? 4 :
1620 y == -1 || y == lev_fieldy ? 5 : -1);
1622 if (steel_position != -1)
1623 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1627 void DrawMicroElement(int xpos, int ypos, int element)
1631 if (element == EL_LEERRAUM)
1634 graphic = el2gfx(element);
1636 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1638 graphic -= GFX_START_ROCKSSP;
1639 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1640 BlitBitmap(pix[PIX_SP], drawto,
1641 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1642 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1643 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1645 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1647 graphic -= GFX_START_ROCKSDC;
1648 BlitBitmap(pix[PIX_DC], drawto,
1649 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1650 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1651 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1653 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1655 graphic -= GFX_START_ROCKSMORE;
1656 BlitBitmap(pix[PIX_MORE], drawto,
1657 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1658 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1659 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1662 BlitBitmap(pix[PIX_BACK], drawto,
1663 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1664 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1665 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1674 for(x=BX1; x<=BX2; x++)
1675 for(y=BY1; y<=BY2; y++)
1676 DrawScreenField(x, y);
1678 redraw_mask |= REDRAW_FIELD;
1681 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1685 for(x=0; x<size_x; x++)
1686 for(y=0; y<size_y; y++)
1687 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1689 redraw_mask |= REDRAW_FIELD;
1692 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1696 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1698 if (lev_fieldx < STD_LEV_FIELDX)
1699 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1700 if (lev_fieldy < STD_LEV_FIELDY)
1701 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1703 xpos += MICRO_TILEX;
1704 ypos += MICRO_TILEY;
1706 for(x=-1; x<=STD_LEV_FIELDX; x++)
1708 for(y=-1; y<=STD_LEV_FIELDY; y++)
1710 int lx = from_x + x, ly = from_y + y;
1712 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1713 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1715 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1716 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1721 redraw_mask |= REDRAW_MICROLEVEL;
1724 #define MICROLABEL_EMPTY 0
1725 #define MICROLABEL_LEVEL_NAME 1
1726 #define MICROLABEL_CREATED_BY 2
1727 #define MICROLABEL_LEVEL_AUTHOR 3
1728 #define MICROLABEL_IMPORTED_FROM 4
1729 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1731 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1733 static void DrawMicroLevelLabelExt(int mode)
1735 char label_text[MAX_MICROLABEL_SIZE + 1];
1737 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1739 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1740 mode == MICROLABEL_CREATED_BY ? "created by" :
1741 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1742 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1743 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1744 leveldir_current->imported_from : ""),
1745 MAX_MICROLABEL_SIZE);
1746 label_text[MAX_MICROLABEL_SIZE] = '\0';
1748 if (strlen(label_text) > 0)
1750 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1751 int lypos = MICROLABEL_YPOS;
1753 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1756 redraw_mask |= REDRAW_MICROLEVEL;
1759 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1761 static unsigned long scroll_delay = 0;
1762 static unsigned long label_delay = 0;
1763 static int from_x, from_y, scroll_direction;
1764 static int label_state, label_counter;
1768 from_x = from_y = 0;
1769 scroll_direction = MV_RIGHT;
1773 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1774 DrawMicroLevelLabelExt(label_state);
1776 /* initialize delay counters */
1777 DelayReached(&scroll_delay, 0);
1778 DelayReached(&label_delay, 0);
1783 /* scroll micro level, if needed */
1784 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1785 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1787 switch (scroll_direction)
1793 scroll_direction = MV_UP;
1797 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1800 scroll_direction = MV_DOWN;
1807 scroll_direction = MV_RIGHT;
1811 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1814 scroll_direction = MV_LEFT;
1821 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1824 /* redraw micro level label, if needed */
1825 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1826 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1827 strcmp(level.author, leveldir_current->name) != 0 &&
1828 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1830 int max_label_counter = 23;
1832 if (leveldir_current->imported_from != NULL)
1833 max_label_counter += 14;
1835 label_counter = (label_counter + 1) % max_label_counter;
1836 label_state = (label_counter >= 0 && label_counter <= 7 ?
1837 MICROLABEL_LEVEL_NAME :
1838 label_counter >= 9 && label_counter <= 12 ?
1839 MICROLABEL_CREATED_BY :
1840 label_counter >= 14 && label_counter <= 21 ?
1841 MICROLABEL_LEVEL_AUTHOR :
1842 label_counter >= 23 && label_counter <= 26 ?
1843 MICROLABEL_IMPORTED_FROM :
1844 label_counter >= 28 && label_counter <= 35 ?
1845 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1846 DrawMicroLevelLabelExt(label_state);
1850 int REQ_in_range(int x, int y)
1852 if (y > DY+249 && y < DY+278)
1854 if (x > DX+1 && x < DX+48)
1856 else if (x > DX+51 && x < DX+98)
1862 boolean Request(char *text, unsigned int req_state)
1864 int mx, my, ty, result = -1;
1865 unsigned int old_door_state;
1867 #if defined(PLATFORM_UNIX)
1868 /* pause network game while waiting for request to answer */
1869 if (options.network &&
1870 game_status == PLAYING &&
1871 req_state & REQUEST_WAIT_FOR)
1872 SendToServer_PausePlaying();
1875 old_door_state = GetDoorState();
1879 CloseDoor(DOOR_CLOSE_1);
1881 /* save old door content */
1882 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1883 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1884 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1886 /* clear door drawing field */
1887 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1889 /* write text for request */
1890 for(ty=0; ty<13; ty++)
1898 for(tl=0,tx=0; tx<7; tl++,tx++)
1901 if (!tc || tc == 32)
1912 DrawTextExt(drawto, DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1913 txt, FS_SMALL, FC_YELLOW);
1914 text += tl + (tc == 32 ? 1 : 0);
1917 if (req_state & REQ_ASK)
1919 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1920 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1922 else if (req_state & REQ_CONFIRM)
1924 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1926 else if (req_state & REQ_PLAYER)
1928 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1929 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1930 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1931 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1934 /* copy request gadgets to door backbuffer */
1935 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1936 DX, DY, DXSIZE, DYSIZE,
1937 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1939 OpenDoor(DOOR_OPEN_1);
1945 if (!(req_state & REQUEST_WAIT_FOR))
1948 if (game_status != MAINMENU)
1951 button_status = MB_RELEASED;
1953 request_gadget_id = -1;
1965 case EVENT_BUTTONPRESS:
1966 case EVENT_BUTTONRELEASE:
1967 case EVENT_MOTIONNOTIFY:
1969 if (event.type == EVENT_MOTIONNOTIFY)
1971 if (!PointerInWindow(window))
1972 continue; /* window and pointer are on different screens */
1977 motion_status = TRUE;
1978 mx = ((MotionEvent *) &event)->x;
1979 my = ((MotionEvent *) &event)->y;
1983 motion_status = FALSE;
1984 mx = ((ButtonEvent *) &event)->x;
1985 my = ((ButtonEvent *) &event)->y;
1986 if (event.type == EVENT_BUTTONPRESS)
1987 button_status = ((ButtonEvent *) &event)->button;
1989 button_status = MB_RELEASED;
1992 /* this sets 'request_gadget_id' */
1993 HandleGadgets(mx, my, button_status);
1995 switch(request_gadget_id)
1997 case TOOL_CTRL_ID_YES:
2000 case TOOL_CTRL_ID_NO:
2003 case TOOL_CTRL_ID_CONFIRM:
2004 result = TRUE | FALSE;
2007 case TOOL_CTRL_ID_PLAYER_1:
2010 case TOOL_CTRL_ID_PLAYER_2:
2013 case TOOL_CTRL_ID_PLAYER_3:
2016 case TOOL_CTRL_ID_PLAYER_4:
2027 case EVENT_KEYPRESS:
2028 switch(GetEventKey((KeyEvent *)&event, TRUE))
2041 if (req_state & REQ_PLAYER)
2045 case EVENT_KEYRELEASE:
2046 key_joystick_mapping = 0;
2050 HandleOtherEvents(&event);
2054 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
2056 int joy = AnyJoystick();
2058 if (joy & JOY_BUTTON_1)
2060 else if (joy & JOY_BUTTON_2)
2066 /* don't eat all CPU time */
2070 if (game_status != MAINMENU)
2075 if (!(req_state & REQ_STAY_OPEN))
2077 CloseDoor(DOOR_CLOSE_1);
2079 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2081 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2082 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2083 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2084 OpenDoor(DOOR_OPEN_1);
2090 #if defined(PLATFORM_UNIX)
2091 /* continue network game after request */
2092 if (options.network &&
2093 game_status == PLAYING &&
2094 req_state & REQUEST_WAIT_FOR)
2095 SendToServer_ContinuePlaying();
2101 unsigned int OpenDoor(unsigned int door_state)
2103 unsigned int new_door_state;
2105 if (door_state & DOOR_COPY_BACK)
2107 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2108 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2109 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2110 door_state &= ~DOOR_COPY_BACK;
2113 new_door_state = MoveDoor(door_state);
2115 return(new_door_state);
2118 unsigned int CloseDoor(unsigned int door_state)
2120 unsigned int new_door_state;
2122 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2123 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2124 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2125 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2127 new_door_state = MoveDoor(door_state);
2129 return(new_door_state);
2132 unsigned int GetDoorState()
2134 return(MoveDoor(DOOR_GET_STATE));
2137 unsigned int MoveDoor(unsigned int door_state)
2139 static int door1 = DOOR_OPEN_1;
2140 static int door2 = DOOR_CLOSE_2;
2141 static unsigned long door_delay = 0;
2142 int x, start, stepsize = 2;
2143 unsigned long door_delay_value = stepsize * 5;
2145 if (door_state == DOOR_GET_STATE)
2146 return(door1 | door2);
2148 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2149 door_state &= ~DOOR_OPEN_1;
2150 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2151 door_state &= ~DOOR_CLOSE_1;
2152 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2153 door_state &= ~DOOR_OPEN_2;
2154 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2155 door_state &= ~DOOR_CLOSE_2;
2157 if (setup.quick_doors)
2160 door_delay_value = 0;
2161 StopSound(SND_OEFFNEN);
2164 if (door_state & DOOR_ACTION)
2166 if (!(door_state & DOOR_NO_DELAY))
2167 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2169 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2171 for(x=start; x<=DXSIZE; x+=stepsize)
2173 Bitmap bitmap = pix[PIX_DOOR];
2174 GC gc = bitmap->stored_clip_gc;
2176 WaitUntilDelayReached(&door_delay, door_delay_value);
2178 if (door_state & DOOR_ACTION_1)
2180 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2181 int j = (DXSIZE - i) / 3;
2183 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2184 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2185 DXSIZE,DYSIZE - i/2, DX, DY);
2187 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2189 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2190 BlitBitmapMasked(bitmap, drawto,
2191 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2192 DX + DXSIZE - i, DY + j);
2193 BlitBitmapMasked(bitmap, drawto,
2194 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2195 DX + DXSIZE - i, DY + 140 + j);
2196 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2197 BlitBitmapMasked(bitmap, drawto,
2198 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2200 BlitBitmapMasked(bitmap, drawto,
2201 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2204 BlitBitmapMasked(bitmap, drawto,
2205 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2207 BlitBitmapMasked(bitmap, drawto,
2208 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2210 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2211 BlitBitmapMasked(bitmap, drawto,
2212 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2213 DX + DXSIZE - i, DY + 77 + j);
2214 BlitBitmapMasked(bitmap, drawto,
2215 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2216 DX + DXSIZE - i, DY + 203 + j);
2218 redraw_mask |= REDRAW_DOOR_1;
2221 if (door_state & DOOR_ACTION_2)
2223 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2224 int j = (VXSIZE - i) / 3;
2226 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2227 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2228 VXSIZE, VYSIZE - i/2, VX, VY);
2230 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2232 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2233 BlitBitmapMasked(bitmap, drawto,
2234 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2235 VX + VXSIZE-i, VY+j);
2236 SetClipOrigin(bitmap, gc,
2237 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2238 BlitBitmapMasked(bitmap, drawto,
2239 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2242 BlitBitmapMasked(bitmap, drawto,
2243 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2244 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2245 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2246 BlitBitmapMasked(bitmap, drawto,
2247 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2249 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2251 redraw_mask |= REDRAW_DOOR_2;
2256 if (game_status == MAINMENU)
2261 if (setup.quick_doors)
2262 StopSound(SND_OEFFNEN);
2264 if (door_state & DOOR_ACTION_1)
2265 door1 = door_state & DOOR_ACTION_1;
2266 if (door_state & DOOR_ACTION_2)
2267 door2 = door_state & DOOR_ACTION_2;
2269 return (door1 | door2);
2272 void DrawSpecialEditorDoor()
2274 /* draw bigger toolbox window */
2275 BlitBitmap(pix[PIX_DOOR], drawto,
2276 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2278 redraw_mask |= REDRAW_ALL;
2281 void UndrawSpecialEditorDoor()
2283 /* draw normal tape recorder window */
2284 BlitBitmap(pix[PIX_BACK], drawto,
2285 562, 344, 108, 56, EX - 4, EY - 12);
2287 redraw_mask |= REDRAW_ALL;
2291 int ReadPixel(DrawBuffer bitmap, int x, int y)
2293 XImage *pixel_image;
2294 unsigned long pixel_value;
2296 pixel_image = XGetImage(display, bitmap->drawable,
2297 x, y, 1, 1, AllPlanes, ZPixmap);
2298 pixel_value = XGetPixel(pixel_image, 0, 0);
2300 XDestroyImage(pixel_image);
2306 /* ---------- new tool button stuff ---------------------------------------- */
2308 /* graphic position values for tool buttons */
2309 #define TOOL_BUTTON_YES_XPOS 2
2310 #define TOOL_BUTTON_YES_YPOS 250
2311 #define TOOL_BUTTON_YES_GFX_YPOS 0
2312 #define TOOL_BUTTON_YES_XSIZE 46
2313 #define TOOL_BUTTON_YES_YSIZE 28
2314 #define TOOL_BUTTON_NO_XPOS 52
2315 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2316 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2317 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2318 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2319 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2320 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2321 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2322 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2323 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2324 #define TOOL_BUTTON_PLAYER_XSIZE 30
2325 #define TOOL_BUTTON_PLAYER_YSIZE 30
2326 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2327 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2328 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2329 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2330 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2331 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2332 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2333 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2334 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2335 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2336 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2337 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2338 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2339 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2340 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2341 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2342 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2343 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2344 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2345 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2354 } toolbutton_info[NUM_TOOL_BUTTONS] =
2357 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2358 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2359 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2364 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2365 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2366 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2371 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2372 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2373 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2374 TOOL_CTRL_ID_CONFIRM,
2378 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2379 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2380 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2381 TOOL_CTRL_ID_PLAYER_1,
2385 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2386 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2387 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2388 TOOL_CTRL_ID_PLAYER_2,
2392 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2393 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2394 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2395 TOOL_CTRL_ID_PLAYER_3,
2399 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2400 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2401 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2402 TOOL_CTRL_ID_PLAYER_4,
2408 static void DoNotDisplayInfoText(void *ptr)
2414 void CreateToolButtons()
2418 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2420 Bitmap gd_bitmap = pix[PIX_DOOR];
2421 Bitmap deco_bitmap = None;
2422 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2423 struct GadgetInfo *gi;
2424 unsigned long event_mask;
2425 int gd_xoffset, gd_yoffset;
2426 int gd_x1, gd_x2, gd_y;
2429 event_mask = GD_EVENT_RELEASED;
2431 gd_xoffset = toolbutton_info[i].xpos;
2432 gd_yoffset = toolbutton_info[i].ypos;
2433 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2434 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2435 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2437 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2439 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2440 &deco_bitmap, &deco_x, &deco_y);
2441 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2442 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2445 gi = CreateGadget(GDI_CUSTOM_ID, id,
2446 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2447 GDI_X, DX + toolbutton_info[i].x,
2448 GDI_Y, DY + toolbutton_info[i].y,
2449 GDI_WIDTH, toolbutton_info[i].width,
2450 GDI_HEIGHT, toolbutton_info[i].height,
2451 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2452 GDI_STATE, GD_BUTTON_UNPRESSED,
2453 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2454 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2455 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2456 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2457 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2458 GDI_DECORATION_SHIFTING, 1, 1,
2459 GDI_EVENT_MASK, event_mask,
2462 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2465 GDI_CALLBACK_ACTION, HandleToolButtons,
2469 Error(ERR_EXIT, "cannot create gadget");
2471 tool_gadget[id] = gi;
2475 static void UnmapToolButtons()
2479 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2480 UnmapGadget(tool_gadget[i]);
2483 static void HandleToolButtons(struct GadgetInfo *gi)
2485 request_gadget_id = gi->custom_id;
2488 int el2gfx(int element)
2492 case EL_LEERRAUM: return -1;
2493 case EL_ERDREICH: return GFX_ERDREICH;
2494 case EL_MAUERWERK: return GFX_MAUERWERK;
2495 case EL_FELSBODEN: return GFX_FELSBODEN;
2496 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2497 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2498 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2499 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2500 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2501 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2502 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2503 case EL_SPIELER1: return GFX_SPIELER1;
2504 case EL_SPIELER2: return GFX_SPIELER2;
2505 case EL_SPIELER3: return GFX_SPIELER3;
2506 case EL_SPIELER4: return GFX_SPIELER4;
2507 case EL_KAEFER: return GFX_KAEFER;
2508 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2509 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2510 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2511 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2512 case EL_FLIEGER: return GFX_FLIEGER;
2513 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2514 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2515 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2516 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2517 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2518 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2519 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2520 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2521 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2522 case EL_FIREFLY: return GFX_FIREFLY;
2523 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2524 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2525 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2526 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2527 case EL_MAMPFER: return GFX_MAMPFER;
2528 case EL_ROBOT: return GFX_ROBOT;
2529 case EL_BETON: return GFX_BETON;
2530 case EL_DIAMANT: return GFX_DIAMANT;
2531 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2532 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2533 case EL_TROPFEN: return GFX_TROPFEN;
2534 case EL_BOMBE: return GFX_BOMBE;
2535 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2536 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2537 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2538 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2539 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2540 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2541 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2542 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2543 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2544 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2545 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2546 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2547 case EL_LIFE: return GFX_LIFE;
2548 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2549 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2550 case EL_BADEWANNE: return GFX_BADEWANNE;
2551 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2552 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2553 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2554 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2555 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2556 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2557 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2558 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2559 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2560 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2561 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2562 case EL_PFORTE1: return GFX_PFORTE1;
2563 case EL_PFORTE2: return GFX_PFORTE2;
2564 case EL_PFORTE3: return GFX_PFORTE3;
2565 case EL_PFORTE4: return GFX_PFORTE4;
2566 case EL_PFORTE1X: return GFX_PFORTE1X;
2567 case EL_PFORTE2X: return GFX_PFORTE2X;
2568 case EL_PFORTE3X: return GFX_PFORTE3X;
2569 case EL_PFORTE4X: return GFX_PFORTE4X;
2570 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2571 case EL_PACMAN: return GFX_PACMAN;
2572 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2573 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2574 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2575 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2576 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2577 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2578 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2579 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2580 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2581 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2582 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2583 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2584 case EL_MAUER_X: return GFX_MAUER_X;
2585 case EL_MAUER_Y: return GFX_MAUER_Y;
2586 case EL_MAUER_XY: return GFX_MAUER_XY;
2587 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2588 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2589 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2590 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2591 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2592 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2593 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2594 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2595 case EL_MAMPFER2: return GFX_MAMPFER2;
2596 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2597 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2598 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2599 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2600 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2601 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2602 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2603 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2604 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2605 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2606 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2607 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2608 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2609 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2610 case EL_MOLE: return GFX_MOLE;
2611 case EL_PINGUIN: return GFX_PINGUIN;
2612 case EL_SCHWEIN: return GFX_SCHWEIN;
2613 case EL_DRACHE: return GFX_DRACHE;
2614 case EL_SONDE: return GFX_SONDE;
2615 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2616 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2617 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2618 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2619 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2620 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2621 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2622 case EL_SP_ZONK: return GFX_SP_ZONK;
2623 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2624 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2625 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2626 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2627 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2628 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2629 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2630 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2631 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2632 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2633 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2634 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2635 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2636 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2637 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2638 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2639 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2640 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2641 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2642 case EL_PEARL: return GFX_PEARL;
2643 case EL_CRYSTAL: return GFX_CRYSTAL;
2644 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2645 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2646 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2647 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2648 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2649 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2650 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2651 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2652 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2653 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2654 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2655 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2656 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2657 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2658 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2659 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2660 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2661 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2662 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2663 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2664 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2665 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2666 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2667 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2668 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2669 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2670 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2671 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2672 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2673 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2674 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2675 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2676 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2677 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2678 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2679 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2680 case EL_LANDMINE: return GFX_LANDMINE;
2681 case EL_ENVELOPE: return GFX_ENVELOPE;
2682 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2683 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2684 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2685 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2686 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2687 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2688 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2689 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2690 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2691 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2692 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2693 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2694 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2695 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2696 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2697 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2698 case EL_MOLE_UP: return GFX_MOLE_UP;
2699 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2700 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2701 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2702 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2703 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2704 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2705 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2706 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2707 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2708 case EL_BALLOON: return GFX_BALLOON;
2709 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2710 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2711 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2712 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2713 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2714 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2715 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2716 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2717 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2718 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2719 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2720 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2721 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2722 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2723 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2724 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2725 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2726 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2727 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2728 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2729 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2730 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2731 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2732 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2733 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2734 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2735 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2736 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2737 case EL_SPRING: return GFX_SPRING;
2738 case EL_SPRING_MOVING: return GFX_SPRING;
2739 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2740 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2741 case EL_BD_WALL: return GFX_BD_WALL;
2742 case EL_BD_ROCK: return GFX_BD_ROCK;
2743 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2744 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2748 if (IS_CHAR(element))
2749 return GFX_CHAR_START + (element - EL_CHAR_START);
2750 else if (element >= EL_SP_START && element <= EL_SP_END)
2752 int nr_element = element - EL_SP_START;
2753 int gfx_per_line = 8;
2755 (nr_element / gfx_per_line) * SP_PER_LINE +
2756 (nr_element % gfx_per_line);
2758 return GFX_START_ROCKSSP + nr_graphic;