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, gc, 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, gc, (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, gc, FX + x*TILEX, FY + y*TILEY, graphic);
884 void DrawGraphicExt(DrawBuffer d, GC gc, int x, int y, int graphic)
889 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
890 BlitBitmap(pix[bitmap_nr], d, 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_masked[bitmap_nr];
921 drawing_gc = clip_gc[bitmap_nr];
923 if (tile_clipmask[tile] != None)
925 SetClipMask(tile_clip_gc, tile_clipmask[tile]);
926 SetClipOrigin(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(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,gc, 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, GC gc, 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;
1018 DrawGraphic(x, y, graphic);
1022 if (dx || dy) /* Verschiebung der Grafik? */
1024 if (x < BX1) /* Element kommt von links ins Bild */
1031 else if (x > BX2) /* Element kommt von rechts ins Bild */
1037 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1043 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1045 else if (dx) /* allg. Bewegung in x-Richtung */
1046 MarkTileDirty(x + SIGN(dx), y);
1048 if (y < BY1) /* Element kommt von oben ins Bild */
1050 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1058 else if (y > BY2) /* Element kommt von unten ins Bild */
1064 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1070 else if (dy > 0 && cut_mode == CUT_ABOVE)
1072 if (y == BY2) /* Element unterhalb des Bildes */
1078 MarkTileDirty(x, y + 1);
1079 } /* Element verläßt unten das Bild */
1080 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1082 else if (dy) /* allg. Bewegung in y-Richtung */
1083 MarkTileDirty(x, y + SIGN(dy));
1086 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
1087 drawing_gc = clip_gc[bitmap_nr];
1092 dest_x = FX + x * TILEX + dx;
1093 dest_y = FY + y * TILEY + dy;
1096 if (!IN_SCR_FIELD(x,y))
1098 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1099 printf("DrawGraphicShifted(): This should never happen!\n");
1104 if (mask_mode == USE_MASKING)
1106 if (tile_clipmask[tile] != None)
1108 SetClipMask(tile_clip_gc, tile_clipmask[tile]);
1109 SetClipOrigin(tile_clip_gc, dest_x, dest_y);
1110 BlitBitmapMasked(pix_masked[bitmap_nr], drawto_field,
1111 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1117 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1121 SetClipOrigin(drawing_gc, dest_x - src_x, dest_y - src_y);
1122 BlitBitmapMasked(pix_masked[bitmap_nr], drawto_field,
1123 src_x, src_y, width, height, dest_x, dest_y);
1127 BlitBitmap(pix[bitmap_nr], drawto_field,
1128 src_x, src_y, width, height, dest_x, dest_y);
1133 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1136 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1139 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1140 int cut_mode, int mask_mode)
1142 int ux = LEVELX(x), uy = LEVELY(y);
1143 int graphic = el2gfx(element);
1144 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1145 int phase4 = phase8 / 2;
1146 int phase2 = phase8 / 4;
1147 int dir = MovDir[ux][uy];
1149 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1151 graphic += 4 * !phase2;
1155 else if (dir == MV_LEFT)
1157 else if (dir == MV_DOWN)
1160 else if (element == EL_SP_SNIKSNAK)
1163 graphic = GFX_SP_SNIKSNAK_LEFT;
1164 else if (dir == MV_RIGHT)
1165 graphic = GFX_SP_SNIKSNAK_RIGHT;
1166 else if (dir == MV_UP)
1167 graphic = GFX_SP_SNIKSNAK_UP;
1169 graphic = GFX_SP_SNIKSNAK_DOWN;
1171 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1173 else if (element == EL_SP_ELECTRON)
1175 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1177 else if (element == EL_MOLE || element == EL_PINGUIN ||
1178 element == EL_SCHWEIN || element == EL_DRACHE)
1181 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1182 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1183 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1184 else if (dir == MV_RIGHT)
1185 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1186 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1187 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1188 else if (dir == MV_UP)
1189 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1190 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1191 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1193 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1194 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1195 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1199 else if (element == EL_SONDE)
1201 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1203 else if (element == EL_SALZSAEURE)
1205 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1207 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1211 else if (element == EL_BALLOON)
1215 else if ((element == EL_FELSBROCKEN ||
1216 element == EL_SP_ZONK ||
1217 element == EL_BD_ROCK ||
1218 IS_GEM(element)) && !cut_mode)
1220 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1222 if (element == EL_FELSBROCKEN ||
1223 element == EL_SP_ZONK ||
1224 element == EL_BD_ROCK)
1227 graphic += (4 - phase4) % 4;
1228 else if (dir == MV_RIGHT)
1231 graphic += phase2 * 2;
1233 else if (element != EL_SP_INFOTRON)
1237 else if (element == EL_MAGIC_WALL_EMPTY ||
1238 element == EL_MAGIC_WALL_BD_EMPTY ||
1239 element == EL_MAGIC_WALL_FULL ||
1240 element == EL_MAGIC_WALL_BD_FULL)
1242 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1244 else if (IS_AMOEBOID(element))
1246 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1247 graphic += (x + 2 * y + 4) % 4;
1249 else if (element == EL_MAUER_LEBT)
1251 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1253 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1254 links_massiv = TRUE;
1255 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1256 rechts_massiv = TRUE;
1258 if (links_massiv && rechts_massiv)
1259 graphic = GFX_MAUERWERK;
1260 else if (links_massiv)
1261 graphic = GFX_MAUER_R;
1262 else if (rechts_massiv)
1263 graphic = GFX_MAUER_L;
1265 else if ((element == EL_INVISIBLE_STEEL ||
1266 element == EL_UNSICHTBAR ||
1267 element == EL_SAND_INVISIBLE) && game.light_time_left)
1269 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1270 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1271 GFX_SAND_INVISIBLE_ON);
1275 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1276 else if (mask_mode == USE_MASKING)
1277 DrawGraphicThruMask(x, y, graphic);
1279 DrawGraphic(x, y, graphic);
1282 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1283 int cut_mode, int mask_mode)
1285 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1286 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1287 cut_mode, mask_mode);
1290 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1293 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1296 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1299 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1302 void DrawScreenElementThruMask(int x, int y, int element)
1304 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1307 void DrawLevelElementThruMask(int x, int y, int element)
1309 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1312 void DrawLevelFieldThruMask(int x, int y)
1314 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1317 void ErdreichAnbroeckeln(int x, int y)
1319 int i, width, height, cx,cy;
1320 int ux = LEVELX(x), uy = LEVELY(y);
1321 int element, graphic;
1323 static int xy[4][2] =
1331 if (!IN_LEV_FIELD(ux, uy))
1334 element = Feld[ux][uy];
1336 if (element == EL_ERDREICH ||
1337 element == EL_LANDMINE ||
1338 element == EL_TRAP_INACTIVE ||
1339 element == EL_TRAP_ACTIVE)
1341 if (!IN_SCR_FIELD(x, y))
1344 graphic = GFX_ERDENRAND;
1350 uxx = ux + xy[i][0];
1351 uyy = uy + xy[i][1];
1352 if (!IN_LEV_FIELD(uxx, uyy))
1355 element = Feld[uxx][uyy];
1357 if (element == EL_ERDREICH ||
1358 element == EL_LANDMINE ||
1359 element == EL_TRAP_INACTIVE ||
1360 element == EL_TRAP_ACTIVE)
1363 if (i == 1 || i == 2)
1367 cx = (i == 2 ? TILEX - snip : 0);
1375 cy = (i == 3 ? TILEY - snip : 0);
1378 BlitBitmap(pix[PIX_BACK], drawto_field,
1379 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1380 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1381 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1384 MarkTileDirty(x, y);
1388 graphic = GFX_ERDENRAND;
1392 int xx, yy, uxx, uyy;
1396 uxx = ux + xy[i][0];
1397 uyy = uy + xy[i][1];
1399 if (!IN_LEV_FIELD(uxx, uyy) ||
1400 (Feld[uxx][uyy] != EL_ERDREICH &&
1401 Feld[uxx][uyy] != EL_LANDMINE &&
1402 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1403 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1404 !IN_SCR_FIELD(xx, yy))
1407 if (i == 1 || i == 2)
1411 cx = (i == 1 ? TILEX - snip : 0);
1419 cy = (i==0 ? TILEY-snip : 0);
1422 BlitBitmap(pix[PIX_BACK], drawto_field,
1423 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1424 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1425 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1427 MarkTileDirty(xx, yy);
1432 void DrawScreenElement(int x, int y, int element)
1434 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1435 ErdreichAnbroeckeln(x, y);
1438 void DrawLevelElement(int x, int y, int element)
1440 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1441 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1444 void DrawScreenField(int x, int y)
1446 int ux = LEVELX(x), uy = LEVELY(y);
1449 if (!IN_LEV_FIELD(ux, uy))
1451 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1452 element = EL_LEERRAUM;
1454 element = BorderElement;
1456 DrawScreenElement(x, y, element);
1460 element = Feld[ux][uy];
1462 if (IS_MOVING(ux, uy))
1464 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1465 boolean cut_mode = NO_CUTTING;
1467 if (Store[ux][uy] == EL_MORAST_LEER ||
1468 Store[ux][uy] == EL_MAGIC_WALL_EMPTY ||
1469 Store[ux][uy] == EL_MAGIC_WALL_BD_EMPTY ||
1470 Store[ux][uy] == EL_AMOEBE_NASS)
1471 cut_mode = CUT_ABOVE;
1472 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1473 Store[ux][uy] == EL_MAGIC_WALL_FULL ||
1474 Store[ux][uy] == EL_MAGIC_WALL_BD_FULL)
1475 cut_mode = CUT_BELOW;
1477 if (cut_mode == CUT_ABOVE)
1478 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1480 DrawScreenElement(x, y, EL_LEERRAUM);
1483 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1485 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1487 if (Store[ux][uy] == EL_SALZSAEURE)
1488 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1490 else if (IS_BLOCKED(ux, uy))
1495 boolean cut_mode = NO_CUTTING;
1497 Blocked2Moving(ux, uy, &oldx, &oldy);
1500 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1501 MovDir[oldx][oldy] == MV_RIGHT);
1503 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1504 Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
1505 Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
1506 Store[oldx][oldy] == EL_AMOEBE_NASS)
1507 cut_mode = CUT_ABOVE;
1509 DrawScreenElement(x, y, EL_LEERRAUM);
1510 element = Feld[oldx][oldy];
1513 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1515 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1517 else if (IS_DRAWABLE(element))
1518 DrawScreenElement(x, y, element);
1520 DrawScreenElement(x, y, EL_LEERRAUM);
1523 void DrawLevelField(int x, int y)
1525 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1526 DrawScreenField(SCREENX(x), SCREENY(y));
1527 else if (IS_MOVING(x, y))
1531 Moving2Blocked(x, y, &newx, &newy);
1532 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1533 DrawScreenField(SCREENX(newx), SCREENY(newy));
1535 else if (IS_BLOCKED(x, y))
1539 Blocked2Moving(x, y, &oldx, &oldy);
1540 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1541 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1545 void DrawMiniElement(int x, int y, int element)
1551 DrawMiniGraphic(x, y, -1);
1555 graphic = el2gfx(element);
1556 DrawMiniGraphic(x, y, graphic);
1559 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1561 int x = sx + scroll_x, y = sy + scroll_y;
1563 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1564 DrawMiniElement(sx, sy, EL_LEERRAUM);
1565 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1566 DrawMiniElement(sx, sy, Feld[x][y]);
1569 int steel_type, steel_position;
1572 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1573 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1574 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1575 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1576 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1577 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1580 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1581 steel_position = (x == -1 && y == -1 ? 0 :
1582 x == lev_fieldx && y == -1 ? 1 :
1583 x == -1 && y == lev_fieldy ? 2 :
1584 x == lev_fieldx && y == lev_fieldy ? 3 :
1585 x == -1 || x == lev_fieldx ? 4 :
1586 y == -1 || y == lev_fieldy ? 5 : -1);
1588 if (steel_position != -1)
1589 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1593 void DrawMicroElement(int xpos, int ypos, int element)
1597 if (element == EL_LEERRAUM)
1600 graphic = el2gfx(element);
1602 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1604 graphic -= GFX_START_ROCKSSP;
1605 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1606 BlitBitmap(pix[PIX_SP], drawto,
1607 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1608 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1609 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1611 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1613 graphic -= GFX_START_ROCKSDC;
1614 BlitBitmap(pix[PIX_DC], drawto,
1615 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1616 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1617 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1619 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1621 graphic -= GFX_START_ROCKSMORE;
1622 BlitBitmap(pix[PIX_MORE], drawto,
1623 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1624 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1625 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1628 BlitBitmap(pix[PIX_BACK], drawto,
1629 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1630 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1631 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1640 for(x=BX1; x<=BX2; x++)
1641 for(y=BY1; y<=BY2; y++)
1642 DrawScreenField(x, y);
1644 redraw_mask |= REDRAW_FIELD;
1647 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1651 for(x=0; x<size_x; x++)
1652 for(y=0; y<size_y; y++)
1653 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1655 redraw_mask |= REDRAW_FIELD;
1658 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1662 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1664 if (lev_fieldx < STD_LEV_FIELDX)
1665 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1666 if (lev_fieldy < STD_LEV_FIELDY)
1667 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1669 xpos += MICRO_TILEX;
1670 ypos += MICRO_TILEY;
1672 for(x=-1; x<=STD_LEV_FIELDX; x++)
1674 for(y=-1; y<=STD_LEV_FIELDY; y++)
1676 int lx = from_x + x, ly = from_y + y;
1678 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1679 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1681 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1682 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1687 redraw_mask |= REDRAW_MICROLEVEL;
1690 #define MICROLABEL_EMPTY 0
1691 #define MICROLABEL_LEVEL_NAME 1
1692 #define MICROLABEL_CREATED_BY 2
1693 #define MICROLABEL_LEVEL_AUTHOR 3
1694 #define MICROLABEL_IMPORTED_FROM 4
1695 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1697 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1699 static void DrawMicroLevelLabelExt(int mode)
1701 char label_text[MAX_MICROLABEL_SIZE + 1];
1703 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1705 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1706 mode == MICROLABEL_CREATED_BY ? "created by" :
1707 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1708 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1709 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1710 leveldir_current->imported_from : ""),
1711 MAX_MICROLABEL_SIZE);
1712 label_text[MAX_MICROLABEL_SIZE] = '\0';
1714 if (strlen(label_text) > 0)
1716 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1717 int lypos = MICROLABEL_YPOS;
1719 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1722 redraw_mask |= REDRAW_MICROLEVEL;
1725 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1727 static unsigned long scroll_delay = 0;
1728 static unsigned long label_delay = 0;
1729 static int from_x, from_y, scroll_direction;
1730 static int label_state, label_counter;
1734 from_x = from_y = 0;
1735 scroll_direction = MV_RIGHT;
1739 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1740 DrawMicroLevelLabelExt(label_state);
1742 /* initialize delay counters */
1743 DelayReached(&scroll_delay, 0);
1744 DelayReached(&label_delay, 0);
1749 /* scroll micro level, if needed */
1750 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1751 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1753 switch (scroll_direction)
1759 scroll_direction = MV_UP;
1763 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1766 scroll_direction = MV_DOWN;
1773 scroll_direction = MV_RIGHT;
1777 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1780 scroll_direction = MV_LEFT;
1787 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1790 /* redraw micro level label, if needed */
1791 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1792 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1793 strcmp(level.author, leveldir_current->name) != 0 &&
1794 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1796 int max_label_counter = 23;
1798 if (leveldir_current->imported_from != NULL)
1799 max_label_counter += 14;
1801 label_counter = (label_counter + 1) % max_label_counter;
1802 label_state = (label_counter >= 0 && label_counter <= 7 ?
1803 MICROLABEL_LEVEL_NAME :
1804 label_counter >= 9 && label_counter <= 12 ?
1805 MICROLABEL_CREATED_BY :
1806 label_counter >= 14 && label_counter <= 21 ?
1807 MICROLABEL_LEVEL_AUTHOR :
1808 label_counter >= 23 && label_counter <= 26 ?
1809 MICROLABEL_IMPORTED_FROM :
1810 label_counter >= 28 && label_counter <= 35 ?
1811 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1812 DrawMicroLevelLabelExt(label_state);
1816 int REQ_in_range(int x, int y)
1818 if (y > DY+249 && y < DY+278)
1820 if (x > DX+1 && x < DX+48)
1822 else if (x > DX+51 && x < DX+98)
1828 boolean Request(char *text, unsigned int req_state)
1830 int mx, my, ty, result = -1;
1831 unsigned int old_door_state;
1833 #if defined(PLATFORM_UNIX)
1834 /* pause network game while waiting for request to answer */
1835 if (options.network &&
1836 game_status == PLAYING &&
1837 req_state & REQUEST_WAIT_FOR)
1838 SendToServer_PausePlaying();
1841 old_door_state = GetDoorState();
1845 CloseDoor(DOOR_CLOSE_1);
1847 /* save old door content */
1848 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1849 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1850 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1852 /* clear door drawing field */
1853 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1855 /* write text for request */
1856 for(ty=0; ty<13; ty++)
1864 for(tl=0,tx=0; tx<7; tl++,tx++)
1867 if (!tc || tc == 32)
1878 DrawTextExt(drawto, gc,
1879 DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1880 txt, FS_SMALL, FC_YELLOW);
1881 text += tl + (tc == 32 ? 1 : 0);
1884 if (req_state & REQ_ASK)
1886 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1887 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1889 else if (req_state & REQ_CONFIRM)
1891 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1893 else if (req_state & REQ_PLAYER)
1895 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1896 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1897 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1898 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1901 /* copy request gadgets to door backbuffer */
1902 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1903 DX, DY, DXSIZE, DYSIZE,
1904 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1906 OpenDoor(DOOR_OPEN_1);
1912 if (!(req_state & REQUEST_WAIT_FOR))
1915 if (game_status != MAINMENU)
1918 button_status = MB_RELEASED;
1920 request_gadget_id = -1;
1932 case EVENT_BUTTONPRESS:
1933 case EVENT_BUTTONRELEASE:
1934 case EVENT_MOTIONNOTIFY:
1936 if (event.type == EVENT_MOTIONNOTIFY)
1938 if (!PointerInWindow(window))
1939 continue; /* window and pointer are on different screens */
1944 motion_status = TRUE;
1945 mx = ((MotionEvent *) &event)->x;
1946 my = ((MotionEvent *) &event)->y;
1950 motion_status = FALSE;
1951 mx = ((ButtonEvent *) &event)->x;
1952 my = ((ButtonEvent *) &event)->y;
1953 if (event.type == EVENT_BUTTONPRESS)
1954 button_status = ((ButtonEvent *) &event)->button;
1956 button_status = MB_RELEASED;
1959 /* this sets 'request_gadget_id' */
1960 HandleGadgets(mx, my, button_status);
1962 switch(request_gadget_id)
1964 case TOOL_CTRL_ID_YES:
1967 case TOOL_CTRL_ID_NO:
1970 case TOOL_CTRL_ID_CONFIRM:
1971 result = TRUE | FALSE;
1974 case TOOL_CTRL_ID_PLAYER_1:
1977 case TOOL_CTRL_ID_PLAYER_2:
1980 case TOOL_CTRL_ID_PLAYER_3:
1983 case TOOL_CTRL_ID_PLAYER_4:
1994 case EVENT_KEYPRESS:
1995 switch(GetEventKey((KeyEvent *)&event, TRUE))
2008 if (req_state & REQ_PLAYER)
2012 case EVENT_KEYRELEASE:
2013 key_joystick_mapping = 0;
2017 HandleOtherEvents(&event);
2021 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
2023 int joy = AnyJoystick();
2025 if (joy & JOY_BUTTON_1)
2027 else if (joy & JOY_BUTTON_2)
2033 /* don't eat all CPU time */
2037 if (game_status != MAINMENU)
2042 if (!(req_state & REQ_STAY_OPEN))
2044 CloseDoor(DOOR_CLOSE_1);
2046 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2048 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2049 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2050 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2051 OpenDoor(DOOR_OPEN_1);
2057 #if defined(PLATFORM_UNIX)
2058 /* continue network game after request */
2059 if (options.network &&
2060 game_status == PLAYING &&
2061 req_state & REQUEST_WAIT_FOR)
2062 SendToServer_ContinuePlaying();
2068 unsigned int OpenDoor(unsigned int door_state)
2070 unsigned int new_door_state;
2072 if (door_state & DOOR_COPY_BACK)
2074 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2075 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2076 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2077 door_state &= ~DOOR_COPY_BACK;
2080 new_door_state = MoveDoor(door_state);
2082 return(new_door_state);
2085 unsigned int CloseDoor(unsigned int door_state)
2087 unsigned int new_door_state;
2089 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2090 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2091 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2092 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2094 new_door_state = MoveDoor(door_state);
2096 return(new_door_state);
2099 unsigned int GetDoorState()
2101 return(MoveDoor(DOOR_GET_STATE));
2104 unsigned int MoveDoor(unsigned int door_state)
2106 static int door1 = DOOR_OPEN_1;
2107 static int door2 = DOOR_CLOSE_2;
2108 static unsigned long door_delay = 0;
2109 int x, start, stepsize = 2;
2110 unsigned long door_delay_value = stepsize * 5;
2112 if (door_state == DOOR_GET_STATE)
2113 return(door1 | door2);
2115 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2116 door_state &= ~DOOR_OPEN_1;
2117 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2118 door_state &= ~DOOR_CLOSE_1;
2119 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2120 door_state &= ~DOOR_OPEN_2;
2121 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2122 door_state &= ~DOOR_CLOSE_2;
2124 if (setup.quick_doors)
2127 door_delay_value = 0;
2128 StopSound(SND_OEFFNEN);
2131 if (door_state & DOOR_ACTION)
2133 if (!(door_state & DOOR_NO_DELAY))
2134 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2136 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2138 for(x=start; x<=DXSIZE; x+=stepsize)
2140 WaitUntilDelayReached(&door_delay, door_delay_value);
2142 if (door_state & DOOR_ACTION_1)
2144 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2145 int j = (DXSIZE - i) / 3;
2147 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2148 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2149 DXSIZE,DYSIZE - i/2, DX, DY);
2151 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2153 SetClipOrigin(clip_gc[PIX_DOOR], DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2154 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2155 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2156 DX + DXSIZE - i, DY + j);
2157 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2158 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2159 DX + DXSIZE - i, DY + 140 + j);
2160 SetClipOrigin(clip_gc[PIX_DOOR],
2161 DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2162 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2163 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2165 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2166 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2169 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2170 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2172 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2173 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2175 SetClipOrigin(clip_gc[PIX_DOOR], DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2176 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2177 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2178 DX + DXSIZE - i, DY + 77 + j);
2179 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2180 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2181 DX + DXSIZE - i, DY + 203 + j);
2183 redraw_mask |= REDRAW_DOOR_1;
2186 if (door_state & DOOR_ACTION_2)
2188 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2189 int j = (VXSIZE - i) / 3;
2191 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2192 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2193 VXSIZE, VYSIZE - i/2, VX, VY);
2195 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2197 SetClipOrigin(clip_gc[PIX_DOOR], VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2198 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2199 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2200 VX + VXSIZE-i, VY+j);
2201 SetClipOrigin(clip_gc[PIX_DOOR],
2202 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2203 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2204 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2207 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2208 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2209 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2210 SetClipOrigin(clip_gc[PIX_DOOR], VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2211 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2212 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2214 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2216 redraw_mask |= REDRAW_DOOR_2;
2221 if (game_status == MAINMENU)
2226 if (setup.quick_doors)
2227 StopSound(SND_OEFFNEN);
2229 if (door_state & DOOR_ACTION_1)
2230 door1 = door_state & DOOR_ACTION_1;
2231 if (door_state & DOOR_ACTION_2)
2232 door2 = door_state & DOOR_ACTION_2;
2234 return (door1 | door2);
2237 void DrawSpecialEditorDoor()
2239 /* draw bigger toolbox window */
2240 BlitBitmap(pix[PIX_DOOR], drawto,
2241 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2243 redraw_mask |= REDRAW_ALL;
2246 void UndrawSpecialEditorDoor()
2248 /* draw normal tape recorder window */
2249 BlitBitmap(pix[PIX_BACK], drawto,
2250 562, 344, 108, 56, EX - 4, EY - 12);
2252 redraw_mask |= REDRAW_ALL;
2256 int ReadPixel(DrawBuffer d, int x, int y)
2258 XImage *pixel_image;
2259 unsigned long pixel_value;
2261 pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
2262 pixel_value = XGetPixel(pixel_image, 0, 0);
2264 XDestroyImage(pixel_image);
2270 /* ---------- new tool button stuff ---------------------------------------- */
2272 /* graphic position values for tool buttons */
2273 #define TOOL_BUTTON_YES_XPOS 2
2274 #define TOOL_BUTTON_YES_YPOS 250
2275 #define TOOL_BUTTON_YES_GFX_YPOS 0
2276 #define TOOL_BUTTON_YES_XSIZE 46
2277 #define TOOL_BUTTON_YES_YSIZE 28
2278 #define TOOL_BUTTON_NO_XPOS 52
2279 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2280 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2281 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2282 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2283 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2284 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2285 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2286 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2287 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2288 #define TOOL_BUTTON_PLAYER_XSIZE 30
2289 #define TOOL_BUTTON_PLAYER_YSIZE 30
2290 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2291 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2292 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2293 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2294 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2295 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2296 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2297 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2298 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2299 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2300 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2301 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2302 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2303 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2304 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2305 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2306 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2307 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2308 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2309 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2318 } toolbutton_info[NUM_TOOL_BUTTONS] =
2321 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2322 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2323 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2328 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2329 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2330 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2335 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2336 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2337 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2338 TOOL_CTRL_ID_CONFIRM,
2342 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2343 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2344 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2345 TOOL_CTRL_ID_PLAYER_1,
2349 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2350 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2351 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2352 TOOL_CTRL_ID_PLAYER_2,
2356 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2357 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2358 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2359 TOOL_CTRL_ID_PLAYER_3,
2363 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2364 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2365 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2366 TOOL_CTRL_ID_PLAYER_4,
2372 static void DoNotDisplayInfoText(void *ptr)
2378 void CreateToolButtons()
2382 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2384 Bitmap gd_bitmap = pix[PIX_DOOR];
2385 Bitmap deco_bitmap = None;
2386 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2387 struct GadgetInfo *gi;
2388 unsigned long event_mask;
2389 int gd_xoffset, gd_yoffset;
2390 int gd_x1, gd_x2, gd_y;
2393 event_mask = GD_EVENT_RELEASED;
2395 gd_xoffset = toolbutton_info[i].xpos;
2396 gd_yoffset = toolbutton_info[i].ypos;
2397 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2398 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2399 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2401 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2403 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2404 &deco_bitmap, &deco_x, &deco_y);
2405 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2406 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2409 gi = CreateGadget(GDI_CUSTOM_ID, id,
2410 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2411 GDI_X, DX + toolbutton_info[i].x,
2412 GDI_Y, DY + toolbutton_info[i].y,
2413 GDI_WIDTH, toolbutton_info[i].width,
2414 GDI_HEIGHT, toolbutton_info[i].height,
2415 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2416 GDI_STATE, GD_BUTTON_UNPRESSED,
2417 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2418 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2419 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2420 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2421 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2422 GDI_DECORATION_SHIFTING, 1, 1,
2423 GDI_EVENT_MASK, event_mask,
2426 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2429 GDI_CALLBACK_ACTION, HandleToolButtons,
2433 Error(ERR_EXIT, "cannot create gadget");
2435 tool_gadget[id] = gi;
2439 static void UnmapToolButtons()
2443 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2444 UnmapGadget(tool_gadget[i]);
2447 static void HandleToolButtons(struct GadgetInfo *gi)
2449 request_gadget_id = gi->custom_id;
2452 int el2gfx(int element)
2456 case EL_LEERRAUM: return -1;
2457 case EL_ERDREICH: return GFX_ERDREICH;
2458 case EL_MAUERWERK: return GFX_MAUERWERK;
2459 case EL_FELSBODEN: return GFX_FELSBODEN;
2460 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2461 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2462 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2463 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2464 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2465 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2466 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2467 case EL_SPIELER1: return GFX_SPIELER1;
2468 case EL_SPIELER2: return GFX_SPIELER2;
2469 case EL_SPIELER3: return GFX_SPIELER3;
2470 case EL_SPIELER4: return GFX_SPIELER4;
2471 case EL_KAEFER: return GFX_KAEFER;
2472 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2473 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2474 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2475 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2476 case EL_FLIEGER: return GFX_FLIEGER;
2477 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2478 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2479 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2480 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2481 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2482 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2483 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2484 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2485 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2486 case EL_FIREFLY: return GFX_FIREFLY;
2487 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2488 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2489 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2490 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2491 case EL_MAMPFER: return GFX_MAMPFER;
2492 case EL_ROBOT: return GFX_ROBOT;
2493 case EL_BETON: return GFX_BETON;
2494 case EL_DIAMANT: return GFX_DIAMANT;
2495 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2496 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2497 case EL_TROPFEN: return GFX_TROPFEN;
2498 case EL_BOMBE: return GFX_BOMBE;
2499 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2500 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2501 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2502 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2503 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2504 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2505 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2506 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2507 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2508 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2509 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2510 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2511 case EL_LIFE: return GFX_LIFE;
2512 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2513 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2514 case EL_BADEWANNE: return GFX_BADEWANNE;
2515 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2516 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2517 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2518 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2519 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2520 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2521 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2522 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2523 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2524 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2525 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2526 case EL_PFORTE1: return GFX_PFORTE1;
2527 case EL_PFORTE2: return GFX_PFORTE2;
2528 case EL_PFORTE3: return GFX_PFORTE3;
2529 case EL_PFORTE4: return GFX_PFORTE4;
2530 case EL_PFORTE1X: return GFX_PFORTE1X;
2531 case EL_PFORTE2X: return GFX_PFORTE2X;
2532 case EL_PFORTE3X: return GFX_PFORTE3X;
2533 case EL_PFORTE4X: return GFX_PFORTE4X;
2534 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2535 case EL_PACMAN: return GFX_PACMAN;
2536 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2537 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2538 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2539 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2540 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2541 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2542 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2543 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2544 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2545 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2546 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2547 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2548 case EL_MAUER_X: return GFX_MAUER_X;
2549 case EL_MAUER_Y: return GFX_MAUER_Y;
2550 case EL_MAUER_XY: return GFX_MAUER_XY;
2551 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2552 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2553 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2554 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2555 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2556 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2557 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2558 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2559 case EL_MAMPFER2: return GFX_MAMPFER2;
2560 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2561 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2562 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2563 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2564 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2565 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2566 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2567 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2568 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2569 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2570 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2571 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2572 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2573 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2574 case EL_MOLE: return GFX_MOLE;
2575 case EL_PINGUIN: return GFX_PINGUIN;
2576 case EL_SCHWEIN: return GFX_SCHWEIN;
2577 case EL_DRACHE: return GFX_DRACHE;
2578 case EL_SONDE: return GFX_SONDE;
2579 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2580 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2581 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2582 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2583 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2584 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2585 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2586 case EL_SP_ZONK: return GFX_SP_ZONK;
2587 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2588 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2589 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2590 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2591 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2592 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2593 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2594 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2595 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2596 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2597 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2598 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2599 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2600 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2601 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2602 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2603 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2604 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2605 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2606 case EL_PEARL: return GFX_PEARL;
2607 case EL_CRYSTAL: return GFX_CRYSTAL;
2608 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2609 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2610 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2611 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2612 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2613 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2614 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2615 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2616 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2617 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2618 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2619 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2620 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2621 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2622 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2623 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2624 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2625 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2626 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2627 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2628 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2629 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2630 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2631 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2632 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2633 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2634 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2635 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2636 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2637 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2638 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2639 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2640 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2641 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2642 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2643 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2644 case EL_LANDMINE: return GFX_LANDMINE;
2645 case EL_ENVELOPE: return GFX_ENVELOPE;
2646 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2647 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2648 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2649 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2650 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2651 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2652 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2653 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2654 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2655 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2656 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2657 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2658 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2659 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2660 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2661 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2662 case EL_MOLE_UP: return GFX_MOLE_UP;
2663 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2664 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2665 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2666 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2667 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2668 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2669 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2670 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2671 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2672 case EL_BALLOON: return GFX_BALLOON;
2673 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2674 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2675 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2676 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2677 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2678 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2679 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2680 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2681 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2682 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2683 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2684 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2685 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2686 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2687 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2688 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2689 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2690 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2691 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2692 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2693 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2694 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2695 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2696 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2697 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2698 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2699 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2700 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2701 case EL_SPRING: return GFX_SPRING;
2702 case EL_SPRING_MOVING: return GFX_SPRING;
2703 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2704 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2705 case EL_BD_WALL: return GFX_BD_WALL;
2706 case EL_BD_ROCK: return GFX_BD_ROCK;
2707 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2708 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2712 if (IS_CHAR(element))
2713 return GFX_CHAR_START + (element - EL_CHAR_START);
2714 else if (element >= EL_SP_START && element <= EL_SP_END)
2716 int nr_element = element - EL_SP_START;
2717 int gfx_per_line = 8;
2719 (nr_element / gfx_per_line) * SP_PER_LINE +
2720 (nr_element % gfx_per_line);
2722 return GFX_START_ROCKSSP + nr_graphic;