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 ***********************************************************/
17 #include <machine/joystick.h>
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, gc, 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;
355 int getFontWidth(int font_size, int font_type)
357 return (font_size == FS_BIG ? FONT1_XSIZE :
358 font_size == FS_MEDIUM ? FONT6_XSIZE :
359 font_type == FC_SPECIAL1 ? FONT3_XSIZE :
360 font_type == FC_SPECIAL2 ? FONT4_XSIZE :
361 font_type == FC_SPECIAL3 ? FONT5_XSIZE :
365 int getFontHeight(int font_size, int font_type)
367 return (font_size == FS_BIG ? FONT1_YSIZE :
368 font_size == FS_MEDIUM ? FONT6_YSIZE :
369 font_type == FC_SPECIAL1 ? FONT3_YSIZE :
370 font_type == FC_SPECIAL2 ? FONT4_YSIZE :
371 font_type == FC_SPECIAL3 ? FONT5_YSIZE :
375 void DrawInitText(char *text, int ypos, int color)
377 if (window && pix[PIX_SMALLFONT])
379 ClearRectangle(window, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
380 DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
381 ypos, text, FS_SMALL, color);
386 void DrawTextFCentered(int y, int font_type, char *format, ...)
388 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
389 int font_width = getFontWidth(FS_SMALL, font_type);
392 va_start(ap, format);
393 vsprintf(buffer, format, ap);
396 DrawText(SX + (SXSIZE - strlen(buffer) * font_width) / 2, SY + y,
397 buffer, FS_SMALL, font_type);
400 void DrawTextF(int x, int y, int font_type, char *format, ...)
402 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
405 va_start(ap, format);
406 vsprintf(buffer, format, ap);
409 DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
412 void DrawText(int x, int y, char *text, int font_size, int font_type)
414 DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
417 redraw_mask |= REDRAW_FIELD;
419 redraw_mask |= REDRAW_DOOR_1;
422 void DrawTextExt(DrawBuffer d, GC gc, int x, int y,
423 char *text, int font_size, int font_type)
425 int font_width, font_height, font_start;
427 boolean print_inverse = FALSE;
429 if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
430 font_size = FS_SMALL;
431 if (font_type < FC_RED || font_type > FC_SPECIAL3)
434 font_width = getFontWidth(font_size, font_type);
435 font_height = getFontHeight(font_size, font_type);
437 font_bitmap = (font_size == FS_BIG ? PIX_BIGFONT :
438 font_size == FS_MEDIUM ? PIX_MEDIUMFONT :
440 font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
441 font_size == FS_MEDIUM ? FONT6_YSIZE :
443 FONT_LINES_PER_FONT);
445 if (font_type == FC_SPECIAL3)
446 font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
452 if (c == '~' && font_size == FS_SMALL)
454 print_inverse = TRUE;
458 if (c >= 'a' && c <= 'z')
460 else if (c == 'ä' || c == 'Ä')
462 else if (c == 'ö' || c == 'Ö')
464 else if (c == 'ü' || c == 'Ü')
467 if (c >= 32 && c <= 95)
469 int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
470 int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
471 int dest_x = x, dest_y = y;
475 BlitBitmap(pix[font_bitmap], d,
476 FONT_CHARS_PER_LINE * font_width,
477 3 * font_height + font_start,
478 font_width, font_height, x, y);
480 SetClipOrigin(clip_gc[font_bitmap], dest_x - src_x, dest_y - src_y);
481 BlitBitmapMasked(pix_masked[font_bitmap], d,
482 0, 0, font_width, font_height, dest_x, dest_y);
485 BlitBitmap(pix[font_bitmap], d,
486 src_x, src_y, font_width, font_height, dest_x, dest_y);
493 void DrawAllPlayers()
497 for(i=0; i<MAX_PLAYERS; i++)
498 if (stored_player[i].active)
499 DrawPlayer(&stored_player[i]);
502 void DrawPlayerField(int x, int y)
504 if (!IS_PLAYER(x, y))
507 DrawPlayer(PLAYERINFO(x, y));
510 void DrawPlayer(struct PlayerInfo *player)
512 int jx = player->jx, jy = player->jy;
513 int last_jx = player->last_jx, last_jy = player->last_jy;
514 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
515 int sx = SCREENX(jx), sy = SCREENY(jy);
516 int sxx = 0, syy = 0;
517 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
519 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
521 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
525 if (!IN_LEV_FIELD(jx,jy))
527 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
528 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
529 printf("DrawPlayerField(): This should never happen!\n");
534 if (element == EL_EXPLODING)
537 /* draw things in the field the player is leaving, if needed */
539 if (player_is_moving)
541 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
543 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
544 DrawLevelFieldThruMask(last_jx, last_jy);
546 else if (last_element == EL_DYNAMITE_ACTIVE)
547 DrawDynamite(last_jx, last_jy);
549 DrawLevelField(last_jx, last_jy);
551 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
555 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
556 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
558 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
561 DrawLevelField(next_jx, next_jy);
565 if (!IN_SCR_FIELD(sx, sy))
568 if (setup.direct_draw)
569 SetDrawtoField(DRAW_BUFFERED);
571 /* draw things behind the player, if needed */
574 DrawLevelElement(jx, jy, Store[jx][jy]);
575 else if (!IS_ACTIVE_BOMB(element))
576 DrawLevelField(jx, jy);
578 /* draw player himself */
580 if (game.emulation == EMU_SUPAPLEX)
582 static int last_dir = MV_LEFT;
583 int action = (player->programmed_action ? player->programmed_action :
585 boolean action_moving =
587 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
588 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
590 graphic = GFX_SP_MURPHY;
594 if (player->MovDir == MV_LEFT)
595 graphic = GFX_MURPHY_PUSH_LEFT;
596 else if (player->MovDir == MV_RIGHT)
597 graphic = GFX_MURPHY_PUSH_RIGHT;
598 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
599 graphic = GFX_MURPHY_PUSH_LEFT;
600 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
601 graphic = GFX_MURPHY_PUSH_RIGHT;
603 else if (player->snapped)
605 if (player->MovDir == MV_LEFT)
606 graphic = GFX_MURPHY_SNAP_LEFT;
607 else if (player->MovDir == MV_RIGHT)
608 graphic = GFX_MURPHY_SNAP_RIGHT;
609 else if (player->MovDir == MV_UP)
610 graphic = GFX_MURPHY_SNAP_UP;
611 else if (player->MovDir == MV_DOWN)
612 graphic = GFX_MURPHY_SNAP_DOWN;
614 else if (action_moving)
616 if (player->MovDir == MV_LEFT)
617 graphic = GFX_MURPHY_GO_LEFT;
618 else if (player->MovDir == MV_RIGHT)
619 graphic = GFX_MURPHY_GO_RIGHT;
620 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
621 graphic = GFX_MURPHY_GO_LEFT;
622 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
623 graphic = GFX_MURPHY_GO_RIGHT;
625 graphic = GFX_MURPHY_GO_LEFT;
627 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
630 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
631 last_dir = player->MovDir;
635 if (player->MovDir == MV_LEFT)
637 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
638 else if (player->MovDir == MV_RIGHT)
640 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
641 else if (player->MovDir == MV_UP)
642 graphic = GFX_SPIELER1_UP;
643 else /* MV_DOWN || MV_NO_MOVING */
644 graphic = GFX_SPIELER1_DOWN;
646 graphic += player->index_nr * 3 * HEROES_PER_LINE;
647 graphic += player->Frame;
652 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
653 sxx = player->GfxPos;
655 syy = player->GfxPos;
658 if (!setup.soft_scrolling && ScreenMovPos)
661 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
663 if (SHIELD_ON(player))
665 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
666 GFX2_SHIELD_PASSIVE);
668 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
669 3, 8, ANIM_OSCILLATE);
672 if (player->Pushing && player->GfxPos)
674 int px = SCREENX(next_jx), py = SCREENY(next_jy);
676 if (element == EL_SOKOBAN_FELD_LEER ||
677 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
678 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
682 int element = Feld[next_jx][next_jy];
683 int graphic = el2gfx(element);
685 if ((element == EL_FELSBROCKEN ||
686 element == EL_SP_ZONK ||
687 element == EL_BD_ROCK) && sxx)
689 int phase = (player->GfxPos / (TILEX / 4));
691 if (player->MovDir == MV_LEFT)
694 graphic += (phase + 4) % 4;
697 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
701 /* draw things in front of player (active dynamite or dynabombs) */
703 if (IS_ACTIVE_BOMB(element))
705 graphic = el2gfx(element);
707 if (element == EL_DYNAMITE_ACTIVE)
709 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
714 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
718 if (game.emulation == EMU_SUPAPLEX)
719 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
721 DrawGraphicThruMask(sx, sy, graphic + phase);
724 if (player_is_moving && last_element == EL_EXPLODING)
726 int phase = Frame[last_jx][last_jy];
730 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
731 GFX_EXPLOSION + ((phase - 1) / delay - 1));
734 /* draw elements that stay over the player */
735 /* handle the field the player is leaving ... */
736 if (player_is_moving && IS_OVER_PLAYER(last_element))
737 DrawLevelField(last_jx, last_jy);
738 /* ... and the field the player is entering */
739 if (IS_OVER_PLAYER(element))
740 DrawLevelField(jx, jy);
742 if (setup.direct_draw)
744 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
745 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
746 int x_size = TILEX * (1 + ABS(jx - last_jx));
747 int y_size = TILEY * (1 + ABS(jy - last_jy));
749 BlitBitmap(drawto_field, window,
750 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
751 SetDrawtoField(DRAW_DIRECT);
754 MarkTileDirty(sx,sy);
757 static int getGraphicAnimationPhase(int frames, int delay, int mode)
761 if (mode == ANIM_OSCILLATE)
763 int max_anim_frames = 2 * frames - 2;
764 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
765 phase = (phase < frames ? phase : max_anim_frames - phase);
768 phase = (FrameCounter % (delay * frames)) / delay;
770 if (mode == ANIM_REVERSE)
776 void DrawGraphicAnimationExt(int x, int y, int graphic,
777 int frames, int delay, int mode, int mask_mode)
779 int phase = getGraphicAnimationPhase(frames, delay, mode);
781 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
783 if (mask_mode == USE_MASKING)
784 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
786 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
790 void DrawGraphicAnimation(int x, int y, int graphic,
791 int frames, int delay, int mode)
793 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
796 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
797 int frames, int delay, int mode)
799 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
802 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
805 int frames, int delay,
808 int phase = getGraphicAnimationPhase(frames, delay, mode);
810 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
813 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
815 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
817 graphic -= GFX_START_ROCKSSCREEN;
818 *bitmap_nr = PIX_BACK;
819 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
820 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
822 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
824 graphic -= GFX_START_ROCKSHEROES;
825 *bitmap_nr = PIX_HEROES;
826 *x = (graphic % HEROES_PER_LINE) * TILEX;
827 *y = (graphic / HEROES_PER_LINE) * TILEY;
829 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
831 graphic -= GFX_START_ROCKSSP;
833 *x = (graphic % SP_PER_LINE) * TILEX;
834 *y = (graphic / SP_PER_LINE) * TILEY;
836 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
838 graphic -= GFX_START_ROCKSDC;
840 *x = (graphic % DC_PER_LINE) * TILEX;
841 *y = (graphic / DC_PER_LINE) * TILEY;
843 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
845 graphic -= GFX_START_ROCKSMORE;
846 *bitmap_nr = PIX_MORE;
847 *x = (graphic % MORE_PER_LINE) * TILEX;
848 *y = (graphic / MORE_PER_LINE) * TILEY;
850 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
852 graphic -= GFX_START_ROCKSFONT;
853 *bitmap_nr = PIX_BIGFONT;
854 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
855 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
856 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
866 void DrawGraphic(int x, int y, int graphic)
869 if (!IN_SCR_FIELD(x,y))
871 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
872 printf("DrawGraphic(): This should never happen!\n");
877 DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
881 void DrawGraphicExt(DrawBuffer d, GC gc, int x, int y, int graphic)
886 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
887 BlitBitmap(pix[bitmap_nr], d, src_x, src_y, TILEX, TILEY, x, y);
890 void DrawGraphicThruMask(int x, int y, int graphic)
893 if (!IN_SCR_FIELD(x,y))
895 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
896 printf("DrawGraphicThruMask(): This should never happen!\n");
901 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
905 void DrawGraphicThruMaskExt(DrawBuffer d, int dest_x, int dest_y, int graphic)
913 if (graphic == GFX_LEERRAUM)
916 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
917 src_bitmap = pix_masked[bitmap_nr];
918 drawing_gc = clip_gc[bitmap_nr];
920 if (tile_clipmask[tile] != None)
922 SetClipMask(tile_clip_gc, tile_clipmask[tile]);
923 SetClipOrigin(tile_clip_gc, dest_x, dest_y);
924 BlitBitmapMasked(src_bitmap, d,
925 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
931 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
935 SetClipOrigin(drawing_gc, dest_x-src_x, dest_y-src_y);
936 BlitBitmapMasked(src_bitmap, d,
937 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
941 void DrawMiniGraphic(int x, int y, int graphic)
943 DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
944 MarkTileDirty(x/2, y/2);
947 void getMiniGraphicSource(int graphic, Bitmap *bitmap, int *x, int *y)
949 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
951 graphic -= GFX_START_ROCKSSCREEN;
952 *bitmap = pix[PIX_BACK];
953 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
954 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
956 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
958 graphic -= GFX_START_ROCKSSP;
959 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
960 *bitmap = pix[PIX_SP];
961 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
962 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
964 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
966 graphic -= GFX_START_ROCKSDC;
967 *bitmap = pix[PIX_DC];
968 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
969 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
971 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
973 graphic -= GFX_START_ROCKSMORE;
974 *bitmap = pix[PIX_MORE];
975 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
976 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
978 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
980 graphic -= GFX_START_ROCKSFONT;
981 *bitmap = pix[PIX_SMALLFONT];
982 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
983 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
984 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
988 *bitmap = pix[PIX_SP];
994 void DrawMiniGraphicExt(DrawBuffer d, GC gc, int x, int y, int graphic)
999 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
1000 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
1003 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
1004 int cut_mode, int mask_mode)
1006 int width = TILEX, height = TILEY;
1008 int src_x, src_y, dest_x, dest_y;
1015 DrawGraphic(x, y, graphic);
1019 if (dx || dy) /* Verschiebung der Grafik? */
1021 if (x < BX1) /* Element kommt von links ins Bild */
1028 else if (x > BX2) /* Element kommt von rechts ins Bild */
1034 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1040 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1042 else if (dx) /* allg. Bewegung in x-Richtung */
1043 MarkTileDirty(x + SIGN(dx), y);
1045 if (y < BY1) /* Element kommt von oben ins Bild */
1047 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1055 else if (y > BY2) /* Element kommt von unten ins Bild */
1061 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1067 else if (dy > 0 && cut_mode == CUT_ABOVE)
1069 if (y == BY2) /* Element unterhalb des Bildes */
1075 MarkTileDirty(x, y + 1);
1076 } /* Element verläßt unten das Bild */
1077 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1079 else if (dy) /* allg. Bewegung in y-Richtung */
1080 MarkTileDirty(x, y + SIGN(dy));
1083 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
1084 drawing_gc = clip_gc[bitmap_nr];
1089 dest_x = FX + x * TILEX + dx;
1090 dest_y = FY + y * TILEY + dy;
1093 if (!IN_SCR_FIELD(x,y))
1095 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1096 printf("DrawGraphicShifted(): This should never happen!\n");
1101 if (mask_mode == USE_MASKING)
1103 if (tile_clipmask[tile] != None)
1105 SetClipMask(tile_clip_gc, tile_clipmask[tile]);
1106 SetClipOrigin(tile_clip_gc, dest_x, dest_y);
1107 BlitBitmapMasked(pix_masked[bitmap_nr], drawto_field,
1108 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1114 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1118 SetClipOrigin(drawing_gc, dest_x - src_x, dest_y - src_y);
1119 BlitBitmapMasked(pix_masked[bitmap_nr], drawto_field,
1120 src_x, src_y, width, height, dest_x, dest_y);
1124 BlitBitmap(pix[bitmap_nr], drawto_field,
1125 src_x, src_y, width, height, dest_x, dest_y);
1130 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1133 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1136 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1137 int cut_mode, int mask_mode)
1139 int ux = LEVELX(x), uy = LEVELY(y);
1140 int graphic = el2gfx(element);
1141 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1142 int phase4 = phase8 / 2;
1143 int phase2 = phase8 / 4;
1144 int dir = MovDir[ux][uy];
1146 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1148 graphic += 4 * !phase2;
1152 else if (dir == MV_LEFT)
1154 else if (dir == MV_DOWN)
1157 else if (element == EL_SP_SNIKSNAK)
1160 graphic = GFX_SP_SNIKSNAK_LEFT;
1161 else if (dir == MV_RIGHT)
1162 graphic = GFX_SP_SNIKSNAK_RIGHT;
1163 else if (dir == MV_UP)
1164 graphic = GFX_SP_SNIKSNAK_UP;
1166 graphic = GFX_SP_SNIKSNAK_DOWN;
1168 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1170 else if (element == EL_SP_ELECTRON)
1172 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1174 else if (element == EL_MOLE || element == EL_PINGUIN ||
1175 element == EL_SCHWEIN || element == EL_DRACHE)
1178 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1179 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1180 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1181 else if (dir == MV_RIGHT)
1182 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1183 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1184 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1185 else if (dir == MV_UP)
1186 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1187 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1188 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1190 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1191 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1192 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1196 else if (element == EL_SONDE)
1198 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1200 else if (element == EL_SALZSAEURE)
1202 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1204 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1208 else if (element == EL_BALLOON)
1212 else if ((element == EL_FELSBROCKEN ||
1213 element == EL_SP_ZONK ||
1214 element == EL_BD_ROCK ||
1215 IS_GEM(element)) && !cut_mode)
1217 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1219 if (element == EL_FELSBROCKEN ||
1220 element == EL_SP_ZONK ||
1221 element == EL_BD_ROCK)
1224 graphic += (4 - phase4) % 4;
1225 else if (dir == MV_RIGHT)
1228 graphic += phase2 * 2;
1230 else if (element != EL_SP_INFOTRON)
1234 else if (element == EL_MAGIC_WALL_EMPTY ||
1235 element == EL_MAGIC_WALL_BD_EMPTY ||
1236 element == EL_MAGIC_WALL_FULL ||
1237 element == EL_MAGIC_WALL_BD_FULL)
1239 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1241 else if (IS_AMOEBOID(element))
1243 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1244 graphic += (x + 2 * y + 4) % 4;
1246 else if (element == EL_MAUER_LEBT)
1248 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1250 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1251 links_massiv = TRUE;
1252 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1253 rechts_massiv = TRUE;
1255 if (links_massiv && rechts_massiv)
1256 graphic = GFX_MAUERWERK;
1257 else if (links_massiv)
1258 graphic = GFX_MAUER_R;
1259 else if (rechts_massiv)
1260 graphic = GFX_MAUER_L;
1262 else if ((element == EL_INVISIBLE_STEEL ||
1263 element == EL_UNSICHTBAR ||
1264 element == EL_SAND_INVISIBLE) && game.light_time_left)
1266 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1267 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1268 GFX_SAND_INVISIBLE_ON);
1272 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1273 else if (mask_mode == USE_MASKING)
1274 DrawGraphicThruMask(x, y, graphic);
1276 DrawGraphic(x, y, graphic);
1279 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1280 int cut_mode, int mask_mode)
1282 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1283 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1284 cut_mode, mask_mode);
1287 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1290 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1293 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1296 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1299 void DrawScreenElementThruMask(int x, int y, int element)
1301 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1304 void DrawLevelElementThruMask(int x, int y, int element)
1306 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1309 void DrawLevelFieldThruMask(int x, int y)
1311 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1314 void ErdreichAnbroeckeln(int x, int y)
1316 int i, width, height, cx,cy;
1317 int ux = LEVELX(x), uy = LEVELY(y);
1318 int element, graphic;
1320 static int xy[4][2] =
1328 if (!IN_LEV_FIELD(ux, uy))
1331 element = Feld[ux][uy];
1333 if (element == EL_ERDREICH ||
1334 element == EL_LANDMINE ||
1335 element == EL_TRAP_INACTIVE ||
1336 element == EL_TRAP_ACTIVE)
1338 if (!IN_SCR_FIELD(x, y))
1341 graphic = GFX_ERDENRAND;
1347 uxx = ux + xy[i][0];
1348 uyy = uy + xy[i][1];
1349 if (!IN_LEV_FIELD(uxx, uyy))
1352 element = Feld[uxx][uyy];
1354 if (element == EL_ERDREICH ||
1355 element == EL_LANDMINE ||
1356 element == EL_TRAP_INACTIVE ||
1357 element == EL_TRAP_ACTIVE)
1360 if (i == 1 || i == 2)
1364 cx = (i == 2 ? TILEX - snip : 0);
1372 cy = (i == 3 ? TILEY - snip : 0);
1375 BlitBitmap(pix[PIX_BACK], drawto_field,
1376 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1377 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1378 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1381 MarkTileDirty(x, y);
1385 graphic = GFX_ERDENRAND;
1389 int xx, yy, uxx, uyy;
1393 uxx = ux + xy[i][0];
1394 uyy = uy + xy[i][1];
1396 if (!IN_LEV_FIELD(uxx, uyy) ||
1397 (Feld[uxx][uyy] != EL_ERDREICH &&
1398 Feld[uxx][uyy] != EL_LANDMINE &&
1399 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1400 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1401 !IN_SCR_FIELD(xx, yy))
1404 if (i == 1 || i == 2)
1408 cx = (i == 1 ? TILEX - snip : 0);
1416 cy = (i==0 ? TILEY-snip : 0);
1419 BlitBitmap(pix[PIX_BACK], drawto_field,
1420 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1421 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1422 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1424 MarkTileDirty(xx, yy);
1429 void DrawScreenElement(int x, int y, int element)
1431 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1432 ErdreichAnbroeckeln(x, y);
1435 void DrawLevelElement(int x, int y, int element)
1437 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1438 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1441 void DrawScreenField(int x, int y)
1443 int ux = LEVELX(x), uy = LEVELY(y);
1446 if (!IN_LEV_FIELD(ux, uy))
1448 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1449 element = EL_LEERRAUM;
1451 element = BorderElement;
1453 DrawScreenElement(x, y, element);
1457 element = Feld[ux][uy];
1459 if (IS_MOVING(ux, uy))
1461 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1462 boolean cut_mode = NO_CUTTING;
1464 if (Store[ux][uy] == EL_MORAST_LEER ||
1465 Store[ux][uy] == EL_MAGIC_WALL_EMPTY ||
1466 Store[ux][uy] == EL_MAGIC_WALL_BD_EMPTY ||
1467 Store[ux][uy] == EL_AMOEBE_NASS)
1468 cut_mode = CUT_ABOVE;
1469 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1470 Store[ux][uy] == EL_MAGIC_WALL_FULL ||
1471 Store[ux][uy] == EL_MAGIC_WALL_BD_FULL)
1472 cut_mode = CUT_BELOW;
1474 if (cut_mode == CUT_ABOVE)
1475 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1477 DrawScreenElement(x, y, EL_LEERRAUM);
1480 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1482 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1484 if (Store[ux][uy] == EL_SALZSAEURE)
1485 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1487 else if (IS_BLOCKED(ux, uy))
1492 boolean cut_mode = NO_CUTTING;
1494 Blocked2Moving(ux, uy, &oldx, &oldy);
1497 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1498 MovDir[oldx][oldy] == MV_RIGHT);
1500 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1501 Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
1502 Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
1503 Store[oldx][oldy] == EL_AMOEBE_NASS)
1504 cut_mode = CUT_ABOVE;
1506 DrawScreenElement(x, y, EL_LEERRAUM);
1507 element = Feld[oldx][oldy];
1510 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1512 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1514 else if (IS_DRAWABLE(element))
1515 DrawScreenElement(x, y, element);
1517 DrawScreenElement(x, y, EL_LEERRAUM);
1520 void DrawLevelField(int x, int y)
1522 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1523 DrawScreenField(SCREENX(x), SCREENY(y));
1524 else if (IS_MOVING(x, y))
1528 Moving2Blocked(x, y, &newx, &newy);
1529 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1530 DrawScreenField(SCREENX(newx), SCREENY(newy));
1532 else if (IS_BLOCKED(x, y))
1536 Blocked2Moving(x, y, &oldx, &oldy);
1537 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1538 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1542 void DrawMiniElement(int x, int y, int element)
1548 DrawMiniGraphic(x, y, -1);
1552 graphic = el2gfx(element);
1553 DrawMiniGraphic(x, y, graphic);
1556 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1558 int x = sx + scroll_x, y = sy + scroll_y;
1560 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1561 DrawMiniElement(sx, sy, EL_LEERRAUM);
1562 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1563 DrawMiniElement(sx, sy, Feld[x][y]);
1566 int steel_type, steel_position;
1569 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1570 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1571 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1572 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1573 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1574 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1577 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1578 steel_position = (x == -1 && y == -1 ? 0 :
1579 x == lev_fieldx && y == -1 ? 1 :
1580 x == -1 && y == lev_fieldy ? 2 :
1581 x == lev_fieldx && y == lev_fieldy ? 3 :
1582 x == -1 || x == lev_fieldx ? 4 :
1583 y == -1 || y == lev_fieldy ? 5 : -1);
1585 if (steel_position != -1)
1586 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1590 void DrawMicroElement(int xpos, int ypos, int element)
1594 if (element == EL_LEERRAUM)
1597 graphic = el2gfx(element);
1599 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1601 graphic -= GFX_START_ROCKSSP;
1602 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1603 BlitBitmap(pix[PIX_SP], drawto,
1604 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1605 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1606 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1608 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1610 graphic -= GFX_START_ROCKSDC;
1611 BlitBitmap(pix[PIX_DC], drawto,
1612 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1613 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1614 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1616 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1618 graphic -= GFX_START_ROCKSMORE;
1619 BlitBitmap(pix[PIX_MORE], drawto,
1620 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1621 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1622 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1625 BlitBitmap(pix[PIX_BACK], drawto,
1626 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1627 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1628 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1637 for(x=BX1; x<=BX2; x++)
1638 for(y=BY1; y<=BY2; y++)
1639 DrawScreenField(x, y);
1641 redraw_mask |= REDRAW_FIELD;
1644 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1648 for(x=0; x<size_x; x++)
1649 for(y=0; y<size_y; y++)
1650 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1652 redraw_mask |= REDRAW_FIELD;
1655 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1659 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1661 if (lev_fieldx < STD_LEV_FIELDX)
1662 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1663 if (lev_fieldy < STD_LEV_FIELDY)
1664 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1666 xpos += MICRO_TILEX;
1667 ypos += MICRO_TILEY;
1669 for(x=-1; x<=STD_LEV_FIELDX; x++)
1671 for(y=-1; y<=STD_LEV_FIELDY; y++)
1673 int lx = from_x + x, ly = from_y + y;
1675 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1676 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1678 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1679 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1684 redraw_mask |= REDRAW_MICROLEVEL;
1687 #define MICROLABEL_EMPTY 0
1688 #define MICROLABEL_LEVEL_NAME 1
1689 #define MICROLABEL_CREATED_BY 2
1690 #define MICROLABEL_LEVEL_AUTHOR 3
1691 #define MICROLABEL_IMPORTED_FROM 4
1692 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1694 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1696 static void DrawMicroLevelLabelExt(int mode)
1698 char label_text[MAX_MICROLABEL_SIZE + 1];
1700 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1702 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1703 mode == MICROLABEL_CREATED_BY ? "created by" :
1704 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1705 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1706 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1707 leveldir_current->imported_from : ""),
1708 MAX_MICROLABEL_SIZE);
1709 label_text[MAX_MICROLABEL_SIZE] = '\0';
1711 if (strlen(label_text) > 0)
1713 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1714 int lypos = MICROLABEL_YPOS;
1716 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1719 redraw_mask |= REDRAW_MICROLEVEL;
1722 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1724 static unsigned long scroll_delay = 0;
1725 static unsigned long label_delay = 0;
1726 static int from_x, from_y, scroll_direction;
1727 static int label_state, label_counter;
1731 from_x = from_y = 0;
1732 scroll_direction = MV_RIGHT;
1736 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1737 DrawMicroLevelLabelExt(label_state);
1739 /* initialize delay counters */
1740 DelayReached(&scroll_delay, 0);
1741 DelayReached(&label_delay, 0);
1746 /* scroll micro level, if needed */
1747 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1748 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1750 switch (scroll_direction)
1756 scroll_direction = MV_UP;
1760 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1763 scroll_direction = MV_DOWN;
1770 scroll_direction = MV_RIGHT;
1774 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1777 scroll_direction = MV_LEFT;
1784 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1787 /* redraw micro level label, if needed */
1788 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1789 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1790 strcmp(level.author, leveldir_current->name) != 0 &&
1791 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1793 int max_label_counter = 23;
1795 if (leveldir_current->imported_from != NULL)
1796 max_label_counter += 14;
1798 label_counter = (label_counter + 1) % max_label_counter;
1799 label_state = (label_counter >= 0 && label_counter <= 7 ?
1800 MICROLABEL_LEVEL_NAME :
1801 label_counter >= 9 && label_counter <= 12 ?
1802 MICROLABEL_CREATED_BY :
1803 label_counter >= 14 && label_counter <= 21 ?
1804 MICROLABEL_LEVEL_AUTHOR :
1805 label_counter >= 23 && label_counter <= 26 ?
1806 MICROLABEL_IMPORTED_FROM :
1807 label_counter >= 28 && label_counter <= 35 ?
1808 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1809 DrawMicroLevelLabelExt(label_state);
1813 int REQ_in_range(int x, int y)
1815 if (y > DY+249 && y < DY+278)
1817 if (x > DX+1 && x < DX+48)
1819 else if (x > DX+51 && x < DX+98)
1825 boolean Request(char *text, unsigned int req_state)
1827 int mx, my, ty, result = -1;
1828 unsigned int old_door_state;
1830 #if !defined(MSDOS) && !defined(WIN32)
1831 /* pause network game while waiting for request to answer */
1832 if (options.network &&
1833 game_status == PLAYING &&
1834 req_state & REQUEST_WAIT_FOR)
1835 SendToServer_PausePlaying();
1838 old_door_state = GetDoorState();
1842 CloseDoor(DOOR_CLOSE_1);
1844 /* save old door content */
1845 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1846 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1847 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1849 /* clear door drawing field */
1850 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1852 /* write text for request */
1853 for(ty=0; ty<13; ty++)
1861 for(tl=0,tx=0; tx<7; tl++,tx++)
1864 if (!tc || tc == 32)
1875 DrawTextExt(drawto, gc,
1876 DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1877 txt, FS_SMALL, FC_YELLOW);
1878 text += tl + (tc == 32 ? 1 : 0);
1881 if (req_state & REQ_ASK)
1883 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1884 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1886 else if (req_state & REQ_CONFIRM)
1888 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1890 else if (req_state & REQ_PLAYER)
1892 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1893 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1894 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1895 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1898 /* copy request gadgets to door backbuffer */
1899 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1900 DX, DY, DXSIZE, DYSIZE,
1901 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1903 OpenDoor(DOOR_OPEN_1);
1909 if (!(req_state & REQUEST_WAIT_FOR))
1912 if (game_status != MAINMENU)
1915 button_status = MB_RELEASED;
1917 request_gadget_id = -1;
1929 case EVENT_BUTTONPRESS:
1930 case EVENT_BUTTONRELEASE:
1931 case EVENT_MOTIONNOTIFY:
1933 if (event.type == EVENT_MOTIONNOTIFY)
1935 if (!PointerInWindow(window))
1936 continue; /* window and pointer are on different screens */
1941 motion_status = TRUE;
1942 mx = ((MotionEvent *) &event)->x;
1943 my = ((MotionEvent *) &event)->y;
1947 motion_status = FALSE;
1948 mx = ((ButtonEvent *) &event)->x;
1949 my = ((ButtonEvent *) &event)->y;
1950 if (event.type == EVENT_BUTTONPRESS)
1951 button_status = ((ButtonEvent *) &event)->button;
1953 button_status = MB_RELEASED;
1956 /* this sets 'request_gadget_id' */
1957 HandleGadgets(mx, my, button_status);
1959 switch(request_gadget_id)
1961 case TOOL_CTRL_ID_YES:
1964 case TOOL_CTRL_ID_NO:
1967 case TOOL_CTRL_ID_CONFIRM:
1968 result = TRUE | FALSE;
1971 case TOOL_CTRL_ID_PLAYER_1:
1974 case TOOL_CTRL_ID_PLAYER_2:
1977 case TOOL_CTRL_ID_PLAYER_3:
1980 case TOOL_CTRL_ID_PLAYER_4:
1991 case EVENT_KEYPRESS:
1992 switch(GetEventKey((KeyEvent *)&event, TRUE))
2005 if (req_state & REQ_PLAYER)
2009 case EVENT_KEYRELEASE:
2010 key_joystick_mapping = 0;
2014 HandleOtherEvents(&event);
2018 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
2020 int joy = AnyJoystick();
2022 if (joy & JOY_BUTTON_1)
2024 else if (joy & JOY_BUTTON_2)
2030 /* don't eat all CPU time */
2034 if (game_status != MAINMENU)
2039 if (!(req_state & REQ_STAY_OPEN))
2041 CloseDoor(DOOR_CLOSE_1);
2043 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2045 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2046 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2047 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2048 OpenDoor(DOOR_OPEN_1);
2054 #if !defined(MSDOS) && !defined(WIN32)
2055 /* continue network game after request */
2056 if (options.network &&
2057 game_status == PLAYING &&
2058 req_state & REQUEST_WAIT_FOR)
2059 SendToServer_ContinuePlaying();
2065 unsigned int OpenDoor(unsigned int door_state)
2067 unsigned int new_door_state;
2069 if (door_state & DOOR_COPY_BACK)
2071 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2072 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2073 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2074 door_state &= ~DOOR_COPY_BACK;
2077 new_door_state = MoveDoor(door_state);
2079 return(new_door_state);
2082 unsigned int CloseDoor(unsigned int door_state)
2084 unsigned int new_door_state;
2086 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2087 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2088 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2089 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2091 new_door_state = MoveDoor(door_state);
2093 return(new_door_state);
2096 unsigned int GetDoorState()
2098 return(MoveDoor(DOOR_GET_STATE));
2101 unsigned int MoveDoor(unsigned int door_state)
2103 static int door1 = DOOR_OPEN_1;
2104 static int door2 = DOOR_CLOSE_2;
2105 static unsigned long door_delay = 0;
2106 int x, start, stepsize = 2;
2107 unsigned long door_delay_value = stepsize * 5;
2109 if (door_state == DOOR_GET_STATE)
2110 return(door1 | door2);
2112 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2113 door_state &= ~DOOR_OPEN_1;
2114 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2115 door_state &= ~DOOR_CLOSE_1;
2116 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2117 door_state &= ~DOOR_OPEN_2;
2118 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2119 door_state &= ~DOOR_CLOSE_2;
2121 if (setup.quick_doors)
2124 door_delay_value = 0;
2125 StopSound(SND_OEFFNEN);
2128 if (door_state & DOOR_ACTION)
2130 if (!(door_state & DOOR_NO_DELAY))
2131 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2133 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2135 for(x=start; x<=DXSIZE; x+=stepsize)
2137 WaitUntilDelayReached(&door_delay, door_delay_value);
2139 if (door_state & DOOR_ACTION_1)
2141 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2142 int j = (DXSIZE - i) / 3;
2144 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2145 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2146 DXSIZE,DYSIZE - i/2, DX, DY);
2148 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2150 SetClipOrigin(clip_gc[PIX_DOOR], DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2151 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2152 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2153 DX + DXSIZE - i, DY + j);
2154 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2155 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2156 DX + DXSIZE - i, DY + 140 + j);
2157 SetClipOrigin(clip_gc[PIX_DOOR],
2158 DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2159 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2160 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2162 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2163 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2166 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2167 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2169 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2170 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2172 SetClipOrigin(clip_gc[PIX_DOOR], DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2173 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2174 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2175 DX + DXSIZE - i, DY + 77 + j);
2176 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2177 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2178 DX + DXSIZE - i, DY + 203 + j);
2180 redraw_mask |= REDRAW_DOOR_1;
2183 if (door_state & DOOR_ACTION_2)
2185 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2186 int j = (VXSIZE - i) / 3;
2188 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2189 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2190 VXSIZE, VYSIZE - i/2, VX, VY);
2192 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2194 SetClipOrigin(clip_gc[PIX_DOOR], VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2195 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2196 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2197 VX + VXSIZE-i, VY+j);
2198 SetClipOrigin(clip_gc[PIX_DOOR],
2199 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2200 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2201 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2204 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2205 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2206 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2207 SetClipOrigin(clip_gc[PIX_DOOR], VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2208 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2209 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2211 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2213 redraw_mask |= REDRAW_DOOR_2;
2218 if (game_status == MAINMENU)
2223 if (setup.quick_doors)
2224 StopSound(SND_OEFFNEN);
2226 if (door_state & DOOR_ACTION_1)
2227 door1 = door_state & DOOR_ACTION_1;
2228 if (door_state & DOOR_ACTION_2)
2229 door2 = door_state & DOOR_ACTION_2;
2231 return (door1 | door2);
2234 void DrawSpecialEditorDoor()
2236 /* draw bigger toolbox window */
2237 BlitBitmap(pix[PIX_DOOR], drawto,
2238 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2240 redraw_mask |= REDRAW_ALL;
2243 void UndrawSpecialEditorDoor()
2245 /* draw normal tape recorder window */
2246 BlitBitmap(pix[PIX_BACK], drawto,
2247 562, 344, 108, 56, EX - 4, EY - 12);
2249 redraw_mask |= REDRAW_ALL;
2253 int ReadPixel(DrawBuffer d, int x, int y)
2255 XImage *pixel_image;
2256 unsigned long pixel_value;
2258 pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
2259 pixel_value = XGetPixel(pixel_image, 0, 0);
2261 XDestroyImage(pixel_image);
2267 /* ---------- new tool button stuff ---------------------------------------- */
2269 /* graphic position values for tool buttons */
2270 #define TOOL_BUTTON_YES_XPOS 2
2271 #define TOOL_BUTTON_YES_YPOS 250
2272 #define TOOL_BUTTON_YES_GFX_YPOS 0
2273 #define TOOL_BUTTON_YES_XSIZE 46
2274 #define TOOL_BUTTON_YES_YSIZE 28
2275 #define TOOL_BUTTON_NO_XPOS 52
2276 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2277 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2278 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2279 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2280 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2281 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2282 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2283 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2284 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2285 #define TOOL_BUTTON_PLAYER_XSIZE 30
2286 #define TOOL_BUTTON_PLAYER_YSIZE 30
2287 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2288 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2289 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2290 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2291 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2292 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2293 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2294 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2295 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2296 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2297 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2298 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2299 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2300 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2301 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2302 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2303 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2304 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2305 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2306 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2315 } toolbutton_info[NUM_TOOL_BUTTONS] =
2318 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2319 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2320 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2325 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2326 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2327 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2332 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2333 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2334 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2335 TOOL_CTRL_ID_CONFIRM,
2339 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2340 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2341 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2342 TOOL_CTRL_ID_PLAYER_1,
2346 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2347 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2348 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2349 TOOL_CTRL_ID_PLAYER_2,
2353 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2354 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2355 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2356 TOOL_CTRL_ID_PLAYER_3,
2360 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2361 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2362 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2363 TOOL_CTRL_ID_PLAYER_4,
2368 static void DoNotDisplayInfoText(void *ptr)
2373 void CreateToolButtons()
2377 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2379 Bitmap gd_bitmap = pix[PIX_DOOR];
2380 Bitmap deco_bitmap = None;
2381 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2382 struct GadgetInfo *gi;
2383 unsigned long event_mask;
2384 int gd_xoffset, gd_yoffset;
2385 int gd_x1, gd_x2, gd_y;
2388 event_mask = GD_EVENT_RELEASED;
2390 gd_xoffset = toolbutton_info[i].xpos;
2391 gd_yoffset = toolbutton_info[i].ypos;
2392 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2393 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2394 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2396 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2398 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2399 &deco_bitmap, &deco_x, &deco_y);
2400 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2401 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2404 gi = CreateGadget(GDI_CUSTOM_ID, id,
2405 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2406 GDI_X, DX + toolbutton_info[i].x,
2407 GDI_Y, DY + toolbutton_info[i].y,
2408 GDI_WIDTH, toolbutton_info[i].width,
2409 GDI_HEIGHT, toolbutton_info[i].height,
2410 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2411 GDI_STATE, GD_BUTTON_UNPRESSED,
2412 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2413 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2414 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2415 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2416 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2417 GDI_DECORATION_SHIFTING, 1, 1,
2418 GDI_EVENT_MASK, event_mask,
2419 GDI_CALLBACK_ACTION, HandleToolButtons,
2420 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2424 Error(ERR_EXIT, "cannot create gadget");
2426 tool_gadget[id] = gi;
2430 static void UnmapToolButtons()
2434 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2435 UnmapGadget(tool_gadget[i]);
2438 static void HandleToolButtons(struct GadgetInfo *gi)
2440 request_gadget_id = gi->custom_id;
2443 int el2gfx(int element)
2447 case EL_LEERRAUM: return -1;
2448 case EL_ERDREICH: return GFX_ERDREICH;
2449 case EL_MAUERWERK: return GFX_MAUERWERK;
2450 case EL_FELSBODEN: return GFX_FELSBODEN;
2451 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2452 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2453 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2454 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2455 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2456 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2457 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2458 case EL_SPIELER1: return GFX_SPIELER1;
2459 case EL_SPIELER2: return GFX_SPIELER2;
2460 case EL_SPIELER3: return GFX_SPIELER3;
2461 case EL_SPIELER4: return GFX_SPIELER4;
2462 case EL_KAEFER: return GFX_KAEFER;
2463 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2464 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2465 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2466 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2467 case EL_FLIEGER: return GFX_FLIEGER;
2468 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2469 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2470 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2471 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2472 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2473 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2474 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2475 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2476 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2477 case EL_FIREFLY: return GFX_FIREFLY;
2478 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2479 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2480 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2481 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2482 case EL_MAMPFER: return GFX_MAMPFER;
2483 case EL_ROBOT: return GFX_ROBOT;
2484 case EL_BETON: return GFX_BETON;
2485 case EL_DIAMANT: return GFX_DIAMANT;
2486 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2487 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2488 case EL_TROPFEN: return GFX_TROPFEN;
2489 case EL_BOMBE: return GFX_BOMBE;
2490 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2491 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2492 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2493 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2494 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2495 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2496 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2497 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2498 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2499 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2500 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2501 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2502 case EL_LIFE: return GFX_LIFE;
2503 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2504 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2505 case EL_BADEWANNE: return GFX_BADEWANNE;
2506 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2507 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2508 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2509 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2510 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2511 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2512 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2513 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2514 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2515 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2516 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2517 case EL_PFORTE1: return GFX_PFORTE1;
2518 case EL_PFORTE2: return GFX_PFORTE2;
2519 case EL_PFORTE3: return GFX_PFORTE3;
2520 case EL_PFORTE4: return GFX_PFORTE4;
2521 case EL_PFORTE1X: return GFX_PFORTE1X;
2522 case EL_PFORTE2X: return GFX_PFORTE2X;
2523 case EL_PFORTE3X: return GFX_PFORTE3X;
2524 case EL_PFORTE4X: return GFX_PFORTE4X;
2525 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2526 case EL_PACMAN: return GFX_PACMAN;
2527 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2528 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2529 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2530 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2531 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2532 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2533 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2534 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2535 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2536 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2537 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2538 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2539 case EL_MAUER_X: return GFX_MAUER_X;
2540 case EL_MAUER_Y: return GFX_MAUER_Y;
2541 case EL_MAUER_XY: return GFX_MAUER_XY;
2542 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2543 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2544 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2545 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2546 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2547 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2548 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2549 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2550 case EL_MAMPFER2: return GFX_MAMPFER2;
2551 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2552 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2553 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2554 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2555 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2556 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2557 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2558 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2559 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2560 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2561 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2562 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2563 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2564 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2565 case EL_MOLE: return GFX_MOLE;
2566 case EL_PINGUIN: return GFX_PINGUIN;
2567 case EL_SCHWEIN: return GFX_SCHWEIN;
2568 case EL_DRACHE: return GFX_DRACHE;
2569 case EL_SONDE: return GFX_SONDE;
2570 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2571 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2572 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2573 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2574 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2575 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2576 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2577 case EL_SP_ZONK: return GFX_SP_ZONK;
2578 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2579 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2580 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2581 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2582 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2583 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2584 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2585 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2586 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2587 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2588 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2589 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2590 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2591 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2592 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2593 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2594 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2595 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2596 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2597 case EL_PEARL: return GFX_PEARL;
2598 case EL_CRYSTAL: return GFX_CRYSTAL;
2599 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2600 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2601 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2602 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2603 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2604 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2605 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2606 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2607 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2608 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2609 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2610 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2611 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2612 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2613 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2614 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2615 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2616 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2617 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2618 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2619 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2620 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2621 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2622 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2623 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2624 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2625 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2626 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2627 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2628 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2629 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2630 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2631 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2632 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2633 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2634 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2635 case EL_LANDMINE: return GFX_LANDMINE;
2636 case EL_ENVELOPE: return GFX_ENVELOPE;
2637 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2638 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2639 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2640 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2641 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2642 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2643 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2644 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2645 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2646 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2647 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2648 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2649 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2650 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2651 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2652 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2653 case EL_MOLE_UP: return GFX_MOLE_UP;
2654 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2655 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2656 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2657 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2658 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2659 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2660 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2661 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2662 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2663 case EL_BALLOON: return GFX_BALLOON;
2664 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2665 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2666 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2667 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2668 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2669 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2670 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2671 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2672 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2673 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2674 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2675 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2676 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2677 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2678 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2679 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2680 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2681 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2682 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2683 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2684 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2685 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2686 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2687 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2688 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2689 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2690 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2691 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2692 case EL_SPRING: return GFX_SPRING;
2693 case EL_SPRING_MOVING: return GFX_SPRING;
2694 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2695 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2696 case EL_BD_WALL: return GFX_BD_WALL;
2697 case EL_BD_ROCK: return GFX_BD_ROCK;
2698 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2699 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2703 if (IS_CHAR(element))
2704 return GFX_CHAR_START + (element - EL_CHAR_START);
2705 else if (element >= EL_SP_START && element <= EL_SP_END)
2707 int nr_element = element - EL_SP_START;
2708 int gfx_per_line = 8;
2710 (nr_element / gfx_per_line) * SP_PER_LINE +
2711 (nr_element % gfx_per_line);
2713 return GFX_START_ROCKSSP + nr_graphic;