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 DrawAllPlayers()
501 for(i=0; i<MAX_PLAYERS; i++)
502 if (stored_player[i].active)
503 DrawPlayer(&stored_player[i]);
506 void DrawPlayerField(int x, int y)
508 if (!IS_PLAYER(x, y))
511 DrawPlayer(PLAYERINFO(x, y));
514 void DrawPlayer(struct PlayerInfo *player)
516 int jx = player->jx, jy = player->jy;
517 int last_jx = player->last_jx, last_jy = player->last_jy;
518 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
519 int sx = SCREENX(jx), sy = SCREENY(jy);
520 int sxx = 0, syy = 0;
521 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
523 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
525 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
529 if (!IN_LEV_FIELD(jx,jy))
531 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
532 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
533 printf("DrawPlayerField(): This should never happen!\n");
538 if (element == EL_EXPLODING)
541 /* draw things in the field the player is leaving, if needed */
543 if (player_is_moving)
545 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
547 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
548 DrawLevelFieldThruMask(last_jx, last_jy);
550 else if (last_element == EL_DYNAMITE_ACTIVE)
551 DrawDynamite(last_jx, last_jy);
553 DrawLevelField(last_jx, last_jy);
555 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
559 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
560 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
562 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
565 DrawLevelField(next_jx, next_jy);
569 if (!IN_SCR_FIELD(sx, sy))
572 if (setup.direct_draw)
573 SetDrawtoField(DRAW_BUFFERED);
575 /* draw things behind the player, if needed */
578 DrawLevelElement(jx, jy, Store[jx][jy]);
579 else if (!IS_ACTIVE_BOMB(element))
580 DrawLevelField(jx, jy);
582 /* draw player himself */
584 if (game.emulation == EMU_SUPAPLEX)
586 static int last_dir = MV_LEFT;
587 int action = (player->programmed_action ? player->programmed_action :
589 boolean action_moving =
591 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
592 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
594 graphic = GFX_SP_MURPHY;
598 if (player->MovDir == MV_LEFT)
599 graphic = GFX_MURPHY_PUSH_LEFT;
600 else if (player->MovDir == MV_RIGHT)
601 graphic = GFX_MURPHY_PUSH_RIGHT;
602 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
603 graphic = GFX_MURPHY_PUSH_LEFT;
604 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
605 graphic = GFX_MURPHY_PUSH_RIGHT;
607 else if (player->snapped)
609 if (player->MovDir == MV_LEFT)
610 graphic = GFX_MURPHY_SNAP_LEFT;
611 else if (player->MovDir == MV_RIGHT)
612 graphic = GFX_MURPHY_SNAP_RIGHT;
613 else if (player->MovDir == MV_UP)
614 graphic = GFX_MURPHY_SNAP_UP;
615 else if (player->MovDir == MV_DOWN)
616 graphic = GFX_MURPHY_SNAP_DOWN;
618 else if (action_moving)
620 if (player->MovDir == MV_LEFT)
621 graphic = GFX_MURPHY_GO_LEFT;
622 else if (player->MovDir == MV_RIGHT)
623 graphic = GFX_MURPHY_GO_RIGHT;
624 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
625 graphic = GFX_MURPHY_GO_LEFT;
626 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
627 graphic = GFX_MURPHY_GO_RIGHT;
629 graphic = GFX_MURPHY_GO_LEFT;
631 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
634 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
635 last_dir = player->MovDir;
639 if (player->MovDir == MV_LEFT)
641 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
642 else if (player->MovDir == MV_RIGHT)
644 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
645 else if (player->MovDir == MV_UP)
646 graphic = GFX_SPIELER1_UP;
647 else /* MV_DOWN || MV_NO_MOVING */
648 graphic = GFX_SPIELER1_DOWN;
650 graphic += player->index_nr * 3 * HEROES_PER_LINE;
651 graphic += player->Frame;
656 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
657 sxx = player->GfxPos;
659 syy = player->GfxPos;
662 if (!setup.soft_scrolling && ScreenMovPos)
665 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
667 if (SHIELD_ON(player))
669 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
670 GFX2_SHIELD_PASSIVE);
672 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
673 3, 8, ANIM_OSCILLATE);
676 if (player->Pushing && player->GfxPos)
678 int px = SCREENX(next_jx), py = SCREENY(next_jy);
680 if (element == EL_SOKOBAN_FELD_LEER ||
681 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
682 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
686 int element = Feld[next_jx][next_jy];
687 int graphic = el2gfx(element);
689 if ((element == EL_FELSBROCKEN ||
690 element == EL_SP_ZONK ||
691 element == EL_BD_ROCK) && sxx)
693 int phase = (player->GfxPos / (TILEX / 4));
695 if (player->MovDir == MV_LEFT)
698 graphic += (phase + 4) % 4;
701 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
705 /* draw things in front of player (active dynamite or dynabombs) */
707 if (IS_ACTIVE_BOMB(element))
709 graphic = el2gfx(element);
711 if (element == EL_DYNAMITE_ACTIVE)
713 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
718 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
722 if (game.emulation == EMU_SUPAPLEX)
723 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
725 DrawGraphicThruMask(sx, sy, graphic + phase);
728 if (player_is_moving && last_element == EL_EXPLODING)
730 int phase = Frame[last_jx][last_jy];
734 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
735 GFX_EXPLOSION + ((phase - 1) / delay - 1));
738 /* draw elements that stay over the player */
739 /* handle the field the player is leaving ... */
740 if (player_is_moving && IS_OVER_PLAYER(last_element))
741 DrawLevelField(last_jx, last_jy);
742 /* ... and the field the player is entering */
743 if (IS_OVER_PLAYER(element))
744 DrawLevelField(jx, jy);
746 if (setup.direct_draw)
748 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
749 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
750 int x_size = TILEX * (1 + ABS(jx - last_jx));
751 int y_size = TILEY * (1 + ABS(jy - last_jy));
753 BlitBitmap(drawto_field, window,
754 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
755 SetDrawtoField(DRAW_DIRECT);
758 MarkTileDirty(sx,sy);
761 static int getGraphicAnimationPhase(int frames, int delay, int mode)
765 if (mode == ANIM_OSCILLATE)
767 int max_anim_frames = 2 * frames - 2;
768 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
769 phase = (phase < frames ? phase : max_anim_frames - phase);
772 phase = (FrameCounter % (delay * frames)) / delay;
774 if (mode == ANIM_REVERSE)
780 void DrawGraphicAnimationExt(int x, int y, int graphic,
781 int frames, int delay, int mode, int mask_mode)
783 int phase = getGraphicAnimationPhase(frames, delay, mode);
785 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
787 if (mask_mode == USE_MASKING)
788 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
790 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
794 void DrawGraphicAnimation(int x, int y, int graphic,
795 int frames, int delay, int mode)
797 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
800 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
801 int frames, int delay, int mode)
803 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
806 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
809 int frames, int delay,
812 int phase = getGraphicAnimationPhase(frames, delay, mode);
814 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
817 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
819 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
821 graphic -= GFX_START_ROCKSSCREEN;
822 *bitmap_nr = PIX_BACK;
823 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
824 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
826 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
828 graphic -= GFX_START_ROCKSHEROES;
829 *bitmap_nr = PIX_HEROES;
830 *x = (graphic % HEROES_PER_LINE) * TILEX;
831 *y = (graphic / HEROES_PER_LINE) * TILEY;
833 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
835 graphic -= GFX_START_ROCKSSP;
837 *x = (graphic % SP_PER_LINE) * TILEX;
838 *y = (graphic / SP_PER_LINE) * TILEY;
840 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
842 graphic -= GFX_START_ROCKSDC;
844 *x = (graphic % DC_PER_LINE) * TILEX;
845 *y = (graphic / DC_PER_LINE) * TILEY;
847 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
849 graphic -= GFX_START_ROCKSMORE;
850 *bitmap_nr = PIX_MORE;
851 *x = (graphic % MORE_PER_LINE) * TILEX;
852 *y = (graphic / MORE_PER_LINE) * TILEY;
854 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
856 graphic -= GFX_START_ROCKSFONT;
857 *bitmap_nr = PIX_BIGFONT;
858 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
859 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
860 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
870 void DrawGraphic(int x, int y, int graphic)
873 if (!IN_SCR_FIELD(x,y))
875 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
876 printf("DrawGraphic(): This should never happen!\n");
881 DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
885 void DrawGraphicExt(DrawBuffer bitmap, int x, int y, int graphic)
890 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
891 BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
894 void DrawGraphicThruMask(int x, int y, int graphic)
897 if (!IN_SCR_FIELD(x,y))
899 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
900 printf("DrawGraphicThruMask(): This should never happen!\n");
905 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
909 void DrawGraphicThruMaskExt(DrawBuffer d, int dest_x, int dest_y, int graphic)
917 if (graphic == GFX_LEERRAUM)
920 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
921 src_bitmap = pix[bitmap_nr];
922 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
924 if (tile_clipmask[tile] != None)
926 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
927 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
928 BlitBitmapMasked(src_bitmap, d,
929 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
935 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
939 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
940 BlitBitmapMasked(src_bitmap, d,
941 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
945 void DrawMiniGraphic(int x, int y, int graphic)
947 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
948 MarkTileDirty(x/2, y/2);
951 void getMiniGraphicSource(int graphic, Bitmap *bitmap, int *x, int *y)
953 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
955 graphic -= GFX_START_ROCKSSCREEN;
956 *bitmap = pix[PIX_BACK];
957 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
958 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
960 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
962 graphic -= GFX_START_ROCKSSP;
963 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
964 *bitmap = pix[PIX_SP];
965 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
966 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
968 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
970 graphic -= GFX_START_ROCKSDC;
971 *bitmap = pix[PIX_DC];
972 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
973 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
975 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
977 graphic -= GFX_START_ROCKSMORE;
978 *bitmap = pix[PIX_MORE];
979 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
980 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
982 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
984 graphic -= GFX_START_ROCKSFONT;
985 *bitmap = pix[PIX_SMALLFONT];
986 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
987 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
988 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
992 *bitmap = pix[PIX_SP];
998 void DrawMiniGraphicExt(DrawBuffer d, int x, int y, int graphic)
1003 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
1004 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
1007 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
1008 int cut_mode, int mask_mode)
1010 int width = TILEX, height = TILEY;
1012 int src_x, src_y, dest_x, dest_y;
1020 DrawGraphic(x, y, graphic);
1024 if (dx || dy) /* Verschiebung der Grafik? */
1026 if (x < BX1) /* Element kommt von links ins Bild */
1033 else if (x > BX2) /* Element kommt von rechts ins Bild */
1039 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1045 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1047 else if (dx) /* allg. Bewegung in x-Richtung */
1048 MarkTileDirty(x + SIGN(dx), y);
1050 if (y < BY1) /* Element kommt von oben ins Bild */
1052 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1060 else if (y > BY2) /* Element kommt von unten ins Bild */
1066 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1072 else if (dy > 0 && cut_mode == CUT_ABOVE)
1074 if (y == BY2) /* Element unterhalb des Bildes */
1080 MarkTileDirty(x, y + 1);
1081 } /* Element verläßt unten das Bild */
1082 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1084 else if (dy) /* allg. Bewegung in y-Richtung */
1085 MarkTileDirty(x, y + SIGN(dy));
1088 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
1089 src_bitmap = pix[bitmap_nr];
1090 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
1095 dest_x = FX + x * TILEX + dx;
1096 dest_y = FY + y * TILEY + dy;
1099 if (!IN_SCR_FIELD(x,y))
1101 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1102 printf("DrawGraphicShifted(): This should never happen!\n");
1107 if (mask_mode == USE_MASKING)
1109 if (tile_clipmask[tile] != None)
1111 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1112 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1113 BlitBitmapMasked(src_bitmap, drawto_field,
1114 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1120 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1124 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1125 BlitBitmapMasked(src_bitmap, drawto_field,
1126 src_x, src_y, width, height, dest_x, dest_y);
1130 BlitBitmap(pix[bitmap_nr], drawto_field,
1131 src_x, src_y, width, height, dest_x, dest_y);
1136 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1139 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1142 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1143 int cut_mode, int mask_mode)
1145 int ux = LEVELX(x), uy = LEVELY(y);
1146 int graphic = el2gfx(element);
1147 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1148 int phase4 = phase8 / 2;
1149 int phase2 = phase8 / 4;
1150 int dir = MovDir[ux][uy];
1152 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1154 graphic += 4 * !phase2;
1158 else if (dir == MV_LEFT)
1160 else if (dir == MV_DOWN)
1163 else if (element == EL_SP_SNIKSNAK)
1166 graphic = GFX_SP_SNIKSNAK_LEFT;
1167 else if (dir == MV_RIGHT)
1168 graphic = GFX_SP_SNIKSNAK_RIGHT;
1169 else if (dir == MV_UP)
1170 graphic = GFX_SP_SNIKSNAK_UP;
1172 graphic = GFX_SP_SNIKSNAK_DOWN;
1174 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1176 else if (element == EL_SP_ELECTRON)
1178 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1180 else if (element == EL_MOLE || element == EL_PINGUIN ||
1181 element == EL_SCHWEIN || element == EL_DRACHE)
1184 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1185 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1186 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1187 else if (dir == MV_RIGHT)
1188 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1189 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1190 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1191 else if (dir == MV_UP)
1192 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1193 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1194 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1196 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1197 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1198 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1202 else if (element == EL_SONDE)
1204 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1206 else if (element == EL_SALZSAEURE)
1208 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1210 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1214 else if (element == EL_BALLOON)
1218 else if ((element == EL_FELSBROCKEN ||
1219 element == EL_SP_ZONK ||
1220 element == EL_BD_ROCK ||
1221 IS_GEM(element)) && !cut_mode)
1223 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1225 if (element == EL_FELSBROCKEN ||
1226 element == EL_SP_ZONK ||
1227 element == EL_BD_ROCK)
1230 graphic += (4 - phase4) % 4;
1231 else if (dir == MV_RIGHT)
1234 graphic += phase2 * 2;
1236 else if (element != EL_SP_INFOTRON)
1240 else if (element == EL_MAGIC_WALL_EMPTY ||
1241 element == EL_MAGIC_WALL_BD_EMPTY ||
1242 element == EL_MAGIC_WALL_FULL ||
1243 element == EL_MAGIC_WALL_BD_FULL)
1245 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1247 else if (IS_AMOEBOID(element))
1249 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1250 graphic += (x + 2 * y + 4) % 4;
1252 else if (element == EL_MAUER_LEBT)
1254 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1256 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1257 links_massiv = TRUE;
1258 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1259 rechts_massiv = TRUE;
1261 if (links_massiv && rechts_massiv)
1262 graphic = GFX_MAUERWERK;
1263 else if (links_massiv)
1264 graphic = GFX_MAUER_R;
1265 else if (rechts_massiv)
1266 graphic = GFX_MAUER_L;
1268 else if ((element == EL_INVISIBLE_STEEL ||
1269 element == EL_UNSICHTBAR ||
1270 element == EL_SAND_INVISIBLE) && game.light_time_left)
1272 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1273 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1274 GFX_SAND_INVISIBLE_ON);
1278 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1279 else if (mask_mode == USE_MASKING)
1280 DrawGraphicThruMask(x, y, graphic);
1282 DrawGraphic(x, y, graphic);
1285 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1286 int cut_mode, int mask_mode)
1288 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1289 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1290 cut_mode, mask_mode);
1293 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1296 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1299 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1302 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1305 void DrawScreenElementThruMask(int x, int y, int element)
1307 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1310 void DrawLevelElementThruMask(int x, int y, int element)
1312 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1315 void DrawLevelFieldThruMask(int x, int y)
1317 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1320 void ErdreichAnbroeckeln(int x, int y)
1322 int i, width, height, cx,cy;
1323 int ux = LEVELX(x), uy = LEVELY(y);
1324 int element, graphic;
1326 static int xy[4][2] =
1334 if (!IN_LEV_FIELD(ux, uy))
1337 element = Feld[ux][uy];
1339 if (element == EL_ERDREICH ||
1340 element == EL_LANDMINE ||
1341 element == EL_TRAP_INACTIVE ||
1342 element == EL_TRAP_ACTIVE)
1344 if (!IN_SCR_FIELD(x, y))
1347 graphic = GFX_ERDENRAND;
1353 uxx = ux + xy[i][0];
1354 uyy = uy + xy[i][1];
1355 if (!IN_LEV_FIELD(uxx, uyy))
1358 element = Feld[uxx][uyy];
1360 if (element == EL_ERDREICH ||
1361 element == EL_LANDMINE ||
1362 element == EL_TRAP_INACTIVE ||
1363 element == EL_TRAP_ACTIVE)
1366 if (i == 1 || i == 2)
1370 cx = (i == 2 ? TILEX - snip : 0);
1378 cy = (i == 3 ? TILEY - snip : 0);
1381 BlitBitmap(pix[PIX_BACK], drawto_field,
1382 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1383 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1384 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1387 MarkTileDirty(x, y);
1391 graphic = GFX_ERDENRAND;
1395 int xx, yy, uxx, uyy;
1399 uxx = ux + xy[i][0];
1400 uyy = uy + xy[i][1];
1402 if (!IN_LEV_FIELD(uxx, uyy) ||
1403 (Feld[uxx][uyy] != EL_ERDREICH &&
1404 Feld[uxx][uyy] != EL_LANDMINE &&
1405 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1406 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1407 !IN_SCR_FIELD(xx, yy))
1410 if (i == 1 || i == 2)
1414 cx = (i == 1 ? TILEX - snip : 0);
1422 cy = (i==0 ? TILEY-snip : 0);
1425 BlitBitmap(pix[PIX_BACK], drawto_field,
1426 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1427 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1428 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1430 MarkTileDirty(xx, yy);
1435 void DrawScreenElement(int x, int y, int element)
1437 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1438 ErdreichAnbroeckeln(x, y);
1441 void DrawLevelElement(int x, int y, int element)
1443 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1444 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1447 void DrawScreenField(int x, int y)
1449 int ux = LEVELX(x), uy = LEVELY(y);
1452 if (!IN_LEV_FIELD(ux, uy))
1454 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1455 element = EL_LEERRAUM;
1457 element = BorderElement;
1459 DrawScreenElement(x, y, element);
1463 element = Feld[ux][uy];
1465 if (IS_MOVING(ux, uy))
1467 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1468 boolean cut_mode = NO_CUTTING;
1470 if (Store[ux][uy] == EL_MORAST_LEER ||
1471 Store[ux][uy] == EL_MAGIC_WALL_EMPTY ||
1472 Store[ux][uy] == EL_MAGIC_WALL_BD_EMPTY ||
1473 Store[ux][uy] == EL_AMOEBE_NASS)
1474 cut_mode = CUT_ABOVE;
1475 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1476 Store[ux][uy] == EL_MAGIC_WALL_FULL ||
1477 Store[ux][uy] == EL_MAGIC_WALL_BD_FULL)
1478 cut_mode = CUT_BELOW;
1480 if (cut_mode == CUT_ABOVE)
1481 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1483 DrawScreenElement(x, y, EL_LEERRAUM);
1486 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1488 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1490 if (Store[ux][uy] == EL_SALZSAEURE)
1491 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1493 else if (IS_BLOCKED(ux, uy))
1498 boolean cut_mode = NO_CUTTING;
1500 Blocked2Moving(ux, uy, &oldx, &oldy);
1503 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1504 MovDir[oldx][oldy] == MV_RIGHT);
1506 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1507 Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
1508 Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
1509 Store[oldx][oldy] == EL_AMOEBE_NASS)
1510 cut_mode = CUT_ABOVE;
1512 DrawScreenElement(x, y, EL_LEERRAUM);
1513 element = Feld[oldx][oldy];
1516 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1518 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1520 else if (IS_DRAWABLE(element))
1521 DrawScreenElement(x, y, element);
1523 DrawScreenElement(x, y, EL_LEERRAUM);
1526 void DrawLevelField(int x, int y)
1528 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1529 DrawScreenField(SCREENX(x), SCREENY(y));
1530 else if (IS_MOVING(x, y))
1534 Moving2Blocked(x, y, &newx, &newy);
1535 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1536 DrawScreenField(SCREENX(newx), SCREENY(newy));
1538 else if (IS_BLOCKED(x, y))
1542 Blocked2Moving(x, y, &oldx, &oldy);
1543 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1544 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1548 void DrawMiniElement(int x, int y, int element)
1554 DrawMiniGraphic(x, y, -1);
1558 graphic = el2gfx(element);
1559 DrawMiniGraphic(x, y, graphic);
1562 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1564 int x = sx + scroll_x, y = sy + scroll_y;
1566 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1567 DrawMiniElement(sx, sy, EL_LEERRAUM);
1568 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1569 DrawMiniElement(sx, sy, Feld[x][y]);
1572 int steel_type, steel_position;
1575 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1576 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1577 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1578 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1579 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1580 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1583 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1584 steel_position = (x == -1 && y == -1 ? 0 :
1585 x == lev_fieldx && y == -1 ? 1 :
1586 x == -1 && y == lev_fieldy ? 2 :
1587 x == lev_fieldx && y == lev_fieldy ? 3 :
1588 x == -1 || x == lev_fieldx ? 4 :
1589 y == -1 || y == lev_fieldy ? 5 : -1);
1591 if (steel_position != -1)
1592 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1596 void DrawMicroElement(int xpos, int ypos, int element)
1600 if (element == EL_LEERRAUM)
1603 graphic = el2gfx(element);
1605 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1607 graphic -= GFX_START_ROCKSSP;
1608 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1609 BlitBitmap(pix[PIX_SP], drawto,
1610 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1611 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1612 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1614 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1616 graphic -= GFX_START_ROCKSDC;
1617 BlitBitmap(pix[PIX_DC], drawto,
1618 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1619 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1620 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1622 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1624 graphic -= GFX_START_ROCKSMORE;
1625 BlitBitmap(pix[PIX_MORE], drawto,
1626 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1627 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1628 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1631 BlitBitmap(pix[PIX_BACK], drawto,
1632 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1633 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1634 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1643 for(x=BX1; x<=BX2; x++)
1644 for(y=BY1; y<=BY2; y++)
1645 DrawScreenField(x, y);
1647 redraw_mask |= REDRAW_FIELD;
1650 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1654 for(x=0; x<size_x; x++)
1655 for(y=0; y<size_y; y++)
1656 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1658 redraw_mask |= REDRAW_FIELD;
1661 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1665 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1667 if (lev_fieldx < STD_LEV_FIELDX)
1668 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1669 if (lev_fieldy < STD_LEV_FIELDY)
1670 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1672 xpos += MICRO_TILEX;
1673 ypos += MICRO_TILEY;
1675 for(x=-1; x<=STD_LEV_FIELDX; x++)
1677 for(y=-1; y<=STD_LEV_FIELDY; y++)
1679 int lx = from_x + x, ly = from_y + y;
1681 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1682 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1684 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1685 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1690 redraw_mask |= REDRAW_MICROLEVEL;
1693 #define MICROLABEL_EMPTY 0
1694 #define MICROLABEL_LEVEL_NAME 1
1695 #define MICROLABEL_CREATED_BY 2
1696 #define MICROLABEL_LEVEL_AUTHOR 3
1697 #define MICROLABEL_IMPORTED_FROM 4
1698 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1700 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1702 static void DrawMicroLevelLabelExt(int mode)
1704 char label_text[MAX_MICROLABEL_SIZE + 1];
1706 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1708 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1709 mode == MICROLABEL_CREATED_BY ? "created by" :
1710 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1711 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1712 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1713 leveldir_current->imported_from : ""),
1714 MAX_MICROLABEL_SIZE);
1715 label_text[MAX_MICROLABEL_SIZE] = '\0';
1717 if (strlen(label_text) > 0)
1719 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1720 int lypos = MICROLABEL_YPOS;
1722 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1725 redraw_mask |= REDRAW_MICROLEVEL;
1728 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1730 static unsigned long scroll_delay = 0;
1731 static unsigned long label_delay = 0;
1732 static int from_x, from_y, scroll_direction;
1733 static int label_state, label_counter;
1737 from_x = from_y = 0;
1738 scroll_direction = MV_RIGHT;
1742 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1743 DrawMicroLevelLabelExt(label_state);
1745 /* initialize delay counters */
1746 DelayReached(&scroll_delay, 0);
1747 DelayReached(&label_delay, 0);
1752 /* scroll micro level, if needed */
1753 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1754 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1756 switch (scroll_direction)
1762 scroll_direction = MV_UP;
1766 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1769 scroll_direction = MV_DOWN;
1776 scroll_direction = MV_RIGHT;
1780 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1783 scroll_direction = MV_LEFT;
1790 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1793 /* redraw micro level label, if needed */
1794 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1795 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1796 strcmp(level.author, leveldir_current->name) != 0 &&
1797 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1799 int max_label_counter = 23;
1801 if (leveldir_current->imported_from != NULL)
1802 max_label_counter += 14;
1804 label_counter = (label_counter + 1) % max_label_counter;
1805 label_state = (label_counter >= 0 && label_counter <= 7 ?
1806 MICROLABEL_LEVEL_NAME :
1807 label_counter >= 9 && label_counter <= 12 ?
1808 MICROLABEL_CREATED_BY :
1809 label_counter >= 14 && label_counter <= 21 ?
1810 MICROLABEL_LEVEL_AUTHOR :
1811 label_counter >= 23 && label_counter <= 26 ?
1812 MICROLABEL_IMPORTED_FROM :
1813 label_counter >= 28 && label_counter <= 35 ?
1814 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1815 DrawMicroLevelLabelExt(label_state);
1819 int REQ_in_range(int x, int y)
1821 if (y > DY+249 && y < DY+278)
1823 if (x > DX+1 && x < DX+48)
1825 else if (x > DX+51 && x < DX+98)
1831 boolean Request(char *text, unsigned int req_state)
1833 int mx, my, ty, result = -1;
1834 unsigned int old_door_state;
1836 #if defined(PLATFORM_UNIX)
1837 /* pause network game while waiting for request to answer */
1838 if (options.network &&
1839 game_status == PLAYING &&
1840 req_state & REQUEST_WAIT_FOR)
1841 SendToServer_PausePlaying();
1844 old_door_state = GetDoorState();
1848 CloseDoor(DOOR_CLOSE_1);
1850 /* save old door content */
1851 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1852 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1853 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1855 /* clear door drawing field */
1856 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1858 /* write text for request */
1859 for(ty=0; ty<13; ty++)
1867 for(tl=0,tx=0; tx<7; tl++,tx++)
1870 if (!tc || tc == 32)
1881 DrawTextExt(drawto, DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1882 txt, FS_SMALL, FC_YELLOW);
1883 text += tl + (tc == 32 ? 1 : 0);
1886 if (req_state & REQ_ASK)
1888 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1889 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1891 else if (req_state & REQ_CONFIRM)
1893 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1895 else if (req_state & REQ_PLAYER)
1897 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1898 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1899 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1900 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1903 /* copy request gadgets to door backbuffer */
1904 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1905 DX, DY, DXSIZE, DYSIZE,
1906 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1908 OpenDoor(DOOR_OPEN_1);
1914 if (!(req_state & REQUEST_WAIT_FOR))
1917 if (game_status != MAINMENU)
1920 button_status = MB_RELEASED;
1922 request_gadget_id = -1;
1934 case EVENT_BUTTONPRESS:
1935 case EVENT_BUTTONRELEASE:
1936 case EVENT_MOTIONNOTIFY:
1938 if (event.type == EVENT_MOTIONNOTIFY)
1940 if (!PointerInWindow(window))
1941 continue; /* window and pointer are on different screens */
1946 motion_status = TRUE;
1947 mx = ((MotionEvent *) &event)->x;
1948 my = ((MotionEvent *) &event)->y;
1952 motion_status = FALSE;
1953 mx = ((ButtonEvent *) &event)->x;
1954 my = ((ButtonEvent *) &event)->y;
1955 if (event.type == EVENT_BUTTONPRESS)
1956 button_status = ((ButtonEvent *) &event)->button;
1958 button_status = MB_RELEASED;
1961 /* this sets 'request_gadget_id' */
1962 HandleGadgets(mx, my, button_status);
1964 switch(request_gadget_id)
1966 case TOOL_CTRL_ID_YES:
1969 case TOOL_CTRL_ID_NO:
1972 case TOOL_CTRL_ID_CONFIRM:
1973 result = TRUE | FALSE;
1976 case TOOL_CTRL_ID_PLAYER_1:
1979 case TOOL_CTRL_ID_PLAYER_2:
1982 case TOOL_CTRL_ID_PLAYER_3:
1985 case TOOL_CTRL_ID_PLAYER_4:
1996 case EVENT_KEYPRESS:
1997 switch(GetEventKey((KeyEvent *)&event, TRUE))
2010 if (req_state & REQ_PLAYER)
2014 case EVENT_KEYRELEASE:
2015 key_joystick_mapping = 0;
2019 HandleOtherEvents(&event);
2023 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
2025 int joy = AnyJoystick();
2027 if (joy & JOY_BUTTON_1)
2029 else if (joy & JOY_BUTTON_2)
2035 /* don't eat all CPU time */
2039 if (game_status != MAINMENU)
2044 if (!(req_state & REQ_STAY_OPEN))
2046 CloseDoor(DOOR_CLOSE_1);
2048 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2050 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2051 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2052 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2053 OpenDoor(DOOR_OPEN_1);
2059 #if defined(PLATFORM_UNIX)
2060 /* continue network game after request */
2061 if (options.network &&
2062 game_status == PLAYING &&
2063 req_state & REQUEST_WAIT_FOR)
2064 SendToServer_ContinuePlaying();
2070 unsigned int OpenDoor(unsigned int door_state)
2072 unsigned int new_door_state;
2074 if (door_state & DOOR_COPY_BACK)
2076 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2077 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2078 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2079 door_state &= ~DOOR_COPY_BACK;
2082 new_door_state = MoveDoor(door_state);
2084 return(new_door_state);
2087 unsigned int CloseDoor(unsigned int door_state)
2089 unsigned int new_door_state;
2091 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2092 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2093 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2094 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2096 new_door_state = MoveDoor(door_state);
2098 return(new_door_state);
2101 unsigned int GetDoorState()
2103 return(MoveDoor(DOOR_GET_STATE));
2106 unsigned int MoveDoor(unsigned int door_state)
2108 static int door1 = DOOR_OPEN_1;
2109 static int door2 = DOOR_CLOSE_2;
2110 static unsigned long door_delay = 0;
2111 int x, start, stepsize = 2;
2112 unsigned long door_delay_value = stepsize * 5;
2114 if (door_state == DOOR_GET_STATE)
2115 return(door1 | door2);
2117 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2118 door_state &= ~DOOR_OPEN_1;
2119 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2120 door_state &= ~DOOR_CLOSE_1;
2121 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2122 door_state &= ~DOOR_OPEN_2;
2123 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2124 door_state &= ~DOOR_CLOSE_2;
2126 if (setup.quick_doors)
2129 door_delay_value = 0;
2130 StopSound(SND_OEFFNEN);
2133 if (door_state & DOOR_ACTION)
2135 if (!(door_state & DOOR_NO_DELAY))
2136 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2138 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2140 for(x=start; x<=DXSIZE; x+=stepsize)
2142 Bitmap bitmap = pix[PIX_DOOR];
2143 GC gc = bitmap->stored_clip_gc;
2145 WaitUntilDelayReached(&door_delay, door_delay_value);
2147 if (door_state & DOOR_ACTION_1)
2149 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2150 int j = (DXSIZE - i) / 3;
2152 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2153 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2154 DXSIZE,DYSIZE - i/2, DX, DY);
2156 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2158 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2159 BlitBitmapMasked(bitmap, drawto,
2160 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2161 DX + DXSIZE - i, DY + j);
2162 BlitBitmapMasked(bitmap, drawto,
2163 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2164 DX + DXSIZE - i, DY + 140 + j);
2165 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2166 BlitBitmapMasked(bitmap, drawto,
2167 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2169 BlitBitmapMasked(bitmap, drawto,
2170 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2173 BlitBitmapMasked(bitmap, drawto,
2174 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2176 BlitBitmapMasked(bitmap, drawto,
2177 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2179 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2180 BlitBitmapMasked(bitmap, drawto,
2181 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2182 DX + DXSIZE - i, DY + 77 + j);
2183 BlitBitmapMasked(bitmap, drawto,
2184 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2185 DX + DXSIZE - i, DY + 203 + j);
2187 redraw_mask |= REDRAW_DOOR_1;
2190 if (door_state & DOOR_ACTION_2)
2192 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2193 int j = (VXSIZE - i) / 3;
2195 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2196 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2197 VXSIZE, VYSIZE - i/2, VX, VY);
2199 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2201 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2202 BlitBitmapMasked(bitmap, drawto,
2203 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2204 VX + VXSIZE-i, VY+j);
2205 SetClipOrigin(bitmap, gc,
2206 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2207 BlitBitmapMasked(bitmap, drawto,
2208 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2211 BlitBitmapMasked(bitmap, drawto,
2212 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2213 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2214 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2215 BlitBitmapMasked(bitmap, drawto,
2216 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2218 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2220 redraw_mask |= REDRAW_DOOR_2;
2225 if (game_status == MAINMENU)
2230 if (setup.quick_doors)
2231 StopSound(SND_OEFFNEN);
2233 if (door_state & DOOR_ACTION_1)
2234 door1 = door_state & DOOR_ACTION_1;
2235 if (door_state & DOOR_ACTION_2)
2236 door2 = door_state & DOOR_ACTION_2;
2238 return (door1 | door2);
2241 void DrawSpecialEditorDoor()
2243 /* draw bigger toolbox window */
2244 BlitBitmap(pix[PIX_DOOR], drawto,
2245 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2247 redraw_mask |= REDRAW_ALL;
2250 void UndrawSpecialEditorDoor()
2252 /* draw normal tape recorder window */
2253 BlitBitmap(pix[PIX_BACK], drawto,
2254 562, 344, 108, 56, EX - 4, EY - 12);
2256 redraw_mask |= REDRAW_ALL;
2260 int ReadPixel(DrawBuffer bitmap, int x, int y)
2262 XImage *pixel_image;
2263 unsigned long pixel_value;
2265 pixel_image = XGetImage(display, bitmap->drawable,
2266 x, y, 1, 1, AllPlanes, ZPixmap);
2267 pixel_value = XGetPixel(pixel_image, 0, 0);
2269 XDestroyImage(pixel_image);
2275 /* ---------- new tool button stuff ---------------------------------------- */
2277 /* graphic position values for tool buttons */
2278 #define TOOL_BUTTON_YES_XPOS 2
2279 #define TOOL_BUTTON_YES_YPOS 250
2280 #define TOOL_BUTTON_YES_GFX_YPOS 0
2281 #define TOOL_BUTTON_YES_XSIZE 46
2282 #define TOOL_BUTTON_YES_YSIZE 28
2283 #define TOOL_BUTTON_NO_XPOS 52
2284 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2285 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2286 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2287 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2288 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2289 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2290 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2291 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2292 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2293 #define TOOL_BUTTON_PLAYER_XSIZE 30
2294 #define TOOL_BUTTON_PLAYER_YSIZE 30
2295 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2296 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2297 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2298 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2299 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2300 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2301 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2302 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2303 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2304 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2305 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2306 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2307 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2308 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2309 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2310 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2311 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2312 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2313 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2314 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2323 } toolbutton_info[NUM_TOOL_BUTTONS] =
2326 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2327 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2328 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2333 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2334 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2335 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2340 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2341 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2342 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2343 TOOL_CTRL_ID_CONFIRM,
2347 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2348 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2349 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2350 TOOL_CTRL_ID_PLAYER_1,
2354 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2355 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2356 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2357 TOOL_CTRL_ID_PLAYER_2,
2361 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2362 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2363 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2364 TOOL_CTRL_ID_PLAYER_3,
2368 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2369 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2370 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2371 TOOL_CTRL_ID_PLAYER_4,
2377 static void DoNotDisplayInfoText(void *ptr)
2383 void CreateToolButtons()
2387 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2389 Bitmap gd_bitmap = pix[PIX_DOOR];
2390 Bitmap deco_bitmap = None;
2391 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2392 struct GadgetInfo *gi;
2393 unsigned long event_mask;
2394 int gd_xoffset, gd_yoffset;
2395 int gd_x1, gd_x2, gd_y;
2398 event_mask = GD_EVENT_RELEASED;
2400 gd_xoffset = toolbutton_info[i].xpos;
2401 gd_yoffset = toolbutton_info[i].ypos;
2402 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2403 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2404 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2406 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2408 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2409 &deco_bitmap, &deco_x, &deco_y);
2410 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2411 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2414 gi = CreateGadget(GDI_CUSTOM_ID, id,
2415 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2416 GDI_X, DX + toolbutton_info[i].x,
2417 GDI_Y, DY + toolbutton_info[i].y,
2418 GDI_WIDTH, toolbutton_info[i].width,
2419 GDI_HEIGHT, toolbutton_info[i].height,
2420 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2421 GDI_STATE, GD_BUTTON_UNPRESSED,
2422 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2423 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2424 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2425 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2426 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2427 GDI_DECORATION_SHIFTING, 1, 1,
2428 GDI_EVENT_MASK, event_mask,
2431 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2434 GDI_CALLBACK_ACTION, HandleToolButtons,
2438 Error(ERR_EXIT, "cannot create gadget");
2440 tool_gadget[id] = gi;
2444 static void UnmapToolButtons()
2448 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2449 UnmapGadget(tool_gadget[i]);
2452 static void HandleToolButtons(struct GadgetInfo *gi)
2454 request_gadget_id = gi->custom_id;
2457 int el2gfx(int element)
2461 case EL_LEERRAUM: return -1;
2462 case EL_ERDREICH: return GFX_ERDREICH;
2463 case EL_MAUERWERK: return GFX_MAUERWERK;
2464 case EL_FELSBODEN: return GFX_FELSBODEN;
2465 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2466 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2467 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2468 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2469 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2470 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2471 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2472 case EL_SPIELER1: return GFX_SPIELER1;
2473 case EL_SPIELER2: return GFX_SPIELER2;
2474 case EL_SPIELER3: return GFX_SPIELER3;
2475 case EL_SPIELER4: return GFX_SPIELER4;
2476 case EL_KAEFER: return GFX_KAEFER;
2477 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2478 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2479 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2480 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2481 case EL_FLIEGER: return GFX_FLIEGER;
2482 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2483 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2484 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2485 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2486 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2487 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2488 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2489 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2490 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2491 case EL_FIREFLY: return GFX_FIREFLY;
2492 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2493 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2494 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2495 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2496 case EL_MAMPFER: return GFX_MAMPFER;
2497 case EL_ROBOT: return GFX_ROBOT;
2498 case EL_BETON: return GFX_BETON;
2499 case EL_DIAMANT: return GFX_DIAMANT;
2500 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2501 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2502 case EL_TROPFEN: return GFX_TROPFEN;
2503 case EL_BOMBE: return GFX_BOMBE;
2504 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2505 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2506 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2507 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2508 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2509 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2510 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2511 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2512 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2513 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2514 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2515 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2516 case EL_LIFE: return GFX_LIFE;
2517 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2518 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2519 case EL_BADEWANNE: return GFX_BADEWANNE;
2520 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2521 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2522 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2523 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2524 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2525 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2526 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2527 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2528 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2529 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2530 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2531 case EL_PFORTE1: return GFX_PFORTE1;
2532 case EL_PFORTE2: return GFX_PFORTE2;
2533 case EL_PFORTE3: return GFX_PFORTE3;
2534 case EL_PFORTE4: return GFX_PFORTE4;
2535 case EL_PFORTE1X: return GFX_PFORTE1X;
2536 case EL_PFORTE2X: return GFX_PFORTE2X;
2537 case EL_PFORTE3X: return GFX_PFORTE3X;
2538 case EL_PFORTE4X: return GFX_PFORTE4X;
2539 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2540 case EL_PACMAN: return GFX_PACMAN;
2541 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2542 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2543 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2544 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2545 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2546 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2547 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2548 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2549 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2550 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2551 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2552 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2553 case EL_MAUER_X: return GFX_MAUER_X;
2554 case EL_MAUER_Y: return GFX_MAUER_Y;
2555 case EL_MAUER_XY: return GFX_MAUER_XY;
2556 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2557 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2558 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2559 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2560 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2561 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2562 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2563 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2564 case EL_MAMPFER2: return GFX_MAMPFER2;
2565 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2566 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2567 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2568 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2569 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2570 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2571 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2572 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2573 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2574 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2575 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2576 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2577 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2578 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2579 case EL_MOLE: return GFX_MOLE;
2580 case EL_PINGUIN: return GFX_PINGUIN;
2581 case EL_SCHWEIN: return GFX_SCHWEIN;
2582 case EL_DRACHE: return GFX_DRACHE;
2583 case EL_SONDE: return GFX_SONDE;
2584 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2585 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2586 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2587 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2588 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2589 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2590 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2591 case EL_SP_ZONK: return GFX_SP_ZONK;
2592 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2593 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2594 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2595 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2596 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2597 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2598 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2599 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2600 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2601 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2602 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2603 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2604 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2605 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2606 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2607 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2608 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2609 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2610 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2611 case EL_PEARL: return GFX_PEARL;
2612 case EL_CRYSTAL: return GFX_CRYSTAL;
2613 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2614 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2615 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2616 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2617 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2618 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2619 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2620 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2621 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2622 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2623 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2624 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2625 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2626 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2627 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2628 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2629 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2630 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2631 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2632 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2633 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2634 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2635 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2636 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2637 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2638 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2639 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2640 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2641 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2642 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2643 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2644 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2645 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2646 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2647 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2648 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2649 case EL_LANDMINE: return GFX_LANDMINE;
2650 case EL_ENVELOPE: return GFX_ENVELOPE;
2651 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2652 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2653 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2654 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2655 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2656 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2657 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2658 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2659 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2660 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2661 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2662 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2663 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2664 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2665 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2666 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2667 case EL_MOLE_UP: return GFX_MOLE_UP;
2668 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2669 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2670 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2671 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2672 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2673 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2674 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2675 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2676 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2677 case EL_BALLOON: return GFX_BALLOON;
2678 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2679 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2680 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2681 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2682 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2683 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2684 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2685 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2686 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2687 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2688 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2689 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2690 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2691 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2692 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2693 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2694 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2695 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2696 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2697 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2698 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2699 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2700 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2701 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2702 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2703 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2704 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2705 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2706 case EL_SPRING: return GFX_SPRING;
2707 case EL_SPRING_MOVING: return GFX_SPRING;
2708 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2709 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2710 case EL_BD_WALL: return GFX_BD_WALL;
2711 case EL_BD_ROCK: return GFX_BD_ROCK;
2712 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2713 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2717 if (IS_CHAR(element))
2718 return GFX_CHAR_START + (element - EL_CHAR_START);
2719 else if (element >= EL_SP_START && element <= EL_SP_END)
2721 int nr_element = element - EL_SP_START;
2722 int gfx_per_line = 8;
2724 (nr_element / gfx_per_line) * SP_PER_LINE +
2725 (nr_element % gfx_per_line);
2727 return GFX_START_ROCKSSP + nr_graphic;