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;
104 if (1 && game_status == PLAYING)
106 static boolean last_frame_skipped = 0;
107 int fps_slowdown_factor = 2;
108 boolean skip_even_when_not_scrolling = 1;
109 boolean just_scrolling = (ScreenMovDir != 0);
113 printf("ScreenMovDir = %d\n", ScreenMovDir);
117 printf("ScreenGfxPos = %d\n", ScreenGfxPos);
120 if (fps_slowdown_factor > 1 &&
121 (FrameCounter % fps_slowdown_factor) &&
122 (just_scrolling || skip_even_when_not_scrolling))
124 redraw_mask &= ~REDRAW_MAIN;
127 printf("FRAME SKIPPED\n");
129 last_frame_skipped = 1;
133 if (last_frame_skipped)
134 redraw_mask |= REDRAW_FIELD;
136 last_frame_skipped = 0;
139 printf("frame not skipped\n");
145 /* synchronize X11 graphics at this point; if we would synchronize the
146 display immediately after the buffer switching (after the XFlush),
147 this could mean that we have to wait for the graphics to complete,
148 although we could go on doing calculations for the next frame */
152 if (redraw_mask & REDRAW_ALL)
154 BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
158 if (redraw_mask & REDRAW_FIELD)
160 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
162 BlitBitmap(backbuffer, window,
163 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
167 int fx = FX, fy = FY;
169 if (setup.soft_scrolling)
171 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
172 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
175 if (setup.soft_scrolling ||
176 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
177 ABS(ScreenMovPos) == ScrollStepSize ||
178 redraw_tiles > REDRAWTILES_THRESHOLD)
180 BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
184 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
186 (setup.soft_scrolling ?
187 "setup.soft_scrolling" :
188 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
189 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
190 ABS(ScreenGfxPos) == ScrollStepSize ?
191 "ABS(ScreenGfxPos) == ScrollStepSize" :
192 "redraw_tiles > REDRAWTILES_THRESHOLD"));
198 redraw_mask &= ~REDRAW_MAIN;
201 if (redraw_mask & REDRAW_DOORS)
203 if (redraw_mask & REDRAW_DOOR_1)
204 BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
205 if (redraw_mask & REDRAW_DOOR_2)
207 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
208 BlitBitmap(backbuffer, window, VX,VY, VXSIZE,VYSIZE, VX,VY);
211 if (redraw_mask & REDRAW_VIDEO_1)
212 BlitBitmap(backbuffer, window,
213 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
214 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
215 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
216 if (redraw_mask & REDRAW_VIDEO_2)
217 BlitBitmap(backbuffer, window,
218 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
219 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
220 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
221 if (redraw_mask & REDRAW_VIDEO_3)
222 BlitBitmap(backbuffer, window,
223 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
224 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
225 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
228 if (redraw_mask & REDRAW_DOOR_3)
229 BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
230 redraw_mask &= ~REDRAW_DOORS;
233 if (redraw_mask & REDRAW_MICROLEVEL)
235 BlitBitmap(backbuffer, window,
236 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
237 MICROLEV_XPOS, MICROLEV_YPOS);
238 BlitBitmap(backbuffer, window,
239 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
240 SX, MICROLABEL_YPOS);
241 redraw_mask &= ~REDRAW_MICROLEVEL;
244 if (redraw_mask & REDRAW_TILES)
246 for(x=0; x<SCR_FIELDX; x++)
247 for(y=0; y<SCR_FIELDY; y++)
248 if (redraw[redraw_x1 + x][redraw_y1 + y])
249 BlitBitmap(buffer, window,
250 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
251 SX + x * TILEX, SY + y * TILEY);
254 if (redraw_mask & REDRAW_FPS) /* display frames per second */
258 sprintf(text, "%.1f fps", global.frames_per_second);
259 DrawTextExt(window, gc, SX, SY, text, FS_SMALL, FC_YELLOW);
264 for(x=0; x<MAX_BUF_XSIZE; x++)
265 for(y=0; y<MAX_BUF_YSIZE; y++)
274 long fading_delay = 300;
276 if (setup.fading && (redraw_mask & REDRAW_FIELD))
283 ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
286 for(i=0;i<2*FULL_SYSIZE;i++)
288 for(y=0;y<FULL_SYSIZE;y++)
290 BlitBitmap(backbuffer, window,
291 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
299 for(i=1;i<FULL_SYSIZE;i+=2)
300 BlitBitmap(backbuffer, window,
301 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
307 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
308 BlitBitmapMasked(backbuffer, window,
309 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
314 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
315 BlitBitmapMasked(backbuffer, window,
316 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
321 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
322 BlitBitmapMasked(backbuffer, window,
323 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
328 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
329 BlitBitmapMasked(backbuffer, window,
330 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
335 redraw_mask &= ~REDRAW_MAIN;
344 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
346 if (setup.soft_scrolling && game_status == PLAYING)
348 ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
349 SetDrawtoField(DRAW_BUFFERED);
352 SetDrawtoField(DRAW_BACKBUFFER);
354 if (setup.direct_draw && game_status == PLAYING)
356 ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
357 SetDrawtoField(DRAW_DIRECT);
360 redraw_mask |= REDRAW_FIELD;
363 int getFontWidth(int font_size, int font_type)
365 return (font_size == FS_BIG ? FONT1_XSIZE :
366 font_size == FS_MEDIUM ? FONT6_XSIZE :
367 font_type == FC_SPECIAL1 ? FONT3_XSIZE :
368 font_type == FC_SPECIAL2 ? FONT4_XSIZE :
369 font_type == FC_SPECIAL3 ? FONT5_XSIZE :
373 int getFontHeight(int font_size, int font_type)
375 return (font_size == FS_BIG ? FONT1_YSIZE :
376 font_size == FS_MEDIUM ? FONT6_YSIZE :
377 font_type == FC_SPECIAL1 ? FONT3_YSIZE :
378 font_type == FC_SPECIAL2 ? FONT4_YSIZE :
379 font_type == FC_SPECIAL3 ? FONT5_YSIZE :
383 void DrawInitText(char *text, int ypos, int color)
385 if (window && pix[PIX_SMALLFONT])
387 ClearRectangle(window, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
388 DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
389 ypos, text, FS_SMALL, color);
394 void DrawTextFCentered(int y, int font_type, char *format, ...)
396 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
397 int font_width = getFontWidth(FS_SMALL, font_type);
400 va_start(ap, format);
401 vsprintf(buffer, format, ap);
404 DrawText(SX + (SXSIZE - strlen(buffer) * font_width) / 2, SY + y,
405 buffer, FS_SMALL, font_type);
408 void DrawTextF(int x, int y, int font_type, char *format, ...)
410 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
413 va_start(ap, format);
414 vsprintf(buffer, format, ap);
417 DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
420 void DrawText(int x, int y, char *text, int font_size, int font_type)
422 DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
425 redraw_mask |= REDRAW_FIELD;
427 redraw_mask |= REDRAW_DOOR_1;
430 void DrawTextExt(DrawBuffer d, GC gc, int x, int y,
431 char *text, int font_size, int font_type)
433 int font_width, font_height, font_start;
435 boolean print_inverse = FALSE;
437 if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
438 font_size = FS_SMALL;
439 if (font_type < FC_RED || font_type > FC_SPECIAL3)
442 font_width = getFontWidth(font_size, font_type);
443 font_height = getFontHeight(font_size, font_type);
445 font_bitmap = (font_size == FS_BIG ? PIX_BIGFONT :
446 font_size == FS_MEDIUM ? PIX_MEDIUMFONT :
448 font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
449 font_size == FS_MEDIUM ? FONT6_YSIZE :
451 FONT_LINES_PER_FONT);
453 if (font_type == FC_SPECIAL3)
454 font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
460 if (c == '~' && font_size == FS_SMALL)
462 print_inverse = TRUE;
466 if (c >= 'a' && c <= 'z')
468 else if (c == 'ä' || c == 'Ä')
470 else if (c == 'ö' || c == 'Ö')
472 else if (c == 'ü' || c == 'Ü')
475 if (c >= 32 && c <= 95)
477 int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
478 int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
479 int dest_x = x, dest_y = y;
483 BlitBitmap(pix[font_bitmap], d,
484 FONT_CHARS_PER_LINE * font_width,
485 3 * font_height + font_start,
486 font_width, font_height, x, y);
488 SetClipOrigin(clip_gc[font_bitmap], dest_x - src_x, dest_y - src_y);
489 BlitBitmapMasked(pix_masked[font_bitmap], d,
490 0, 0, font_width, font_height, dest_x, dest_y);
493 BlitBitmap(pix[font_bitmap], d,
494 src_x, src_y, font_width, font_height, dest_x, dest_y);
501 void DrawAllPlayers()
505 for(i=0; i<MAX_PLAYERS; i++)
506 if (stored_player[i].active)
507 DrawPlayer(&stored_player[i]);
510 void DrawPlayerField(int x, int y)
512 if (!IS_PLAYER(x, y))
515 DrawPlayer(PLAYERINFO(x, y));
518 void DrawPlayer(struct PlayerInfo *player)
520 int jx = player->jx, jy = player->jy;
521 int last_jx = player->last_jx, last_jy = player->last_jy;
522 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
523 int sx = SCREENX(jx), sy = SCREENY(jy);
524 int sxx = 0, syy = 0;
525 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
527 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
529 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
533 if (!IN_LEV_FIELD(jx,jy))
535 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
536 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
537 printf("DrawPlayerField(): This should never happen!\n");
542 if (element == EL_EXPLODING)
545 /* draw things in the field the player is leaving, if needed */
547 if (player_is_moving)
549 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
551 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
552 DrawLevelFieldThruMask(last_jx, last_jy);
554 else if (last_element == EL_DYNAMITE_ACTIVE)
555 DrawDynamite(last_jx, last_jy);
557 DrawLevelField(last_jx, last_jy);
559 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
563 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
564 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
566 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
569 DrawLevelField(next_jx, next_jy);
573 if (!IN_SCR_FIELD(sx, sy))
576 if (setup.direct_draw)
577 SetDrawtoField(DRAW_BUFFERED);
579 /* draw things behind the player, if needed */
582 DrawLevelElement(jx, jy, Store[jx][jy]);
583 else if (!IS_ACTIVE_BOMB(element))
584 DrawLevelField(jx, jy);
586 /* draw player himself */
588 if (game.emulation == EMU_SUPAPLEX)
590 static int last_dir = MV_LEFT;
591 int action = (player->programmed_action ? player->programmed_action :
593 boolean action_moving =
595 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
596 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
598 graphic = GFX_SP_MURPHY;
602 if (player->MovDir == MV_LEFT)
603 graphic = GFX_MURPHY_PUSH_LEFT;
604 else if (player->MovDir == MV_RIGHT)
605 graphic = GFX_MURPHY_PUSH_RIGHT;
606 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
607 graphic = GFX_MURPHY_PUSH_LEFT;
608 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
609 graphic = GFX_MURPHY_PUSH_RIGHT;
611 else if (player->snapped)
613 if (player->MovDir == MV_LEFT)
614 graphic = GFX_MURPHY_SNAP_LEFT;
615 else if (player->MovDir == MV_RIGHT)
616 graphic = GFX_MURPHY_SNAP_RIGHT;
617 else if (player->MovDir == MV_UP)
618 graphic = GFX_MURPHY_SNAP_UP;
619 else if (player->MovDir == MV_DOWN)
620 graphic = GFX_MURPHY_SNAP_DOWN;
622 else if (action_moving)
624 if (player->MovDir == MV_LEFT)
625 graphic = GFX_MURPHY_GO_LEFT;
626 else if (player->MovDir == MV_RIGHT)
627 graphic = GFX_MURPHY_GO_RIGHT;
628 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
629 graphic = GFX_MURPHY_GO_LEFT;
630 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
631 graphic = GFX_MURPHY_GO_RIGHT;
633 graphic = GFX_MURPHY_GO_LEFT;
635 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
638 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
639 last_dir = player->MovDir;
643 if (player->MovDir == MV_LEFT)
645 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
646 else if (player->MovDir == MV_RIGHT)
648 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
649 else if (player->MovDir == MV_UP)
650 graphic = GFX_SPIELER1_UP;
651 else /* MV_DOWN || MV_NO_MOVING */
652 graphic = GFX_SPIELER1_DOWN;
654 graphic += player->index_nr * 3 * HEROES_PER_LINE;
655 graphic += player->Frame;
660 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
661 sxx = player->GfxPos;
663 syy = player->GfxPos;
666 if (!setup.soft_scrolling && ScreenMovPos)
669 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
671 if (SHIELD_ON(player))
673 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
674 GFX2_SHIELD_PASSIVE);
676 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
677 3, 8, ANIM_OSCILLATE);
680 if (player->Pushing && player->GfxPos)
682 int px = SCREENX(next_jx), py = SCREENY(next_jy);
684 if (element == EL_SOKOBAN_FELD_LEER ||
685 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
686 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
690 int element = Feld[next_jx][next_jy];
691 int graphic = el2gfx(element);
693 if ((element == EL_FELSBROCKEN ||
694 element == EL_SP_ZONK ||
695 element == EL_BD_ROCK) && sxx)
697 int phase = (player->GfxPos / (TILEX / 4));
699 if (player->MovDir == MV_LEFT)
702 graphic += (phase + 4) % 4;
705 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
709 /* draw things in front of player (active dynamite or dynabombs) */
711 if (IS_ACTIVE_BOMB(element))
713 graphic = el2gfx(element);
715 if (element == EL_DYNAMITE_ACTIVE)
717 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
722 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
726 if (game.emulation == EMU_SUPAPLEX)
727 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
729 DrawGraphicThruMask(sx, sy, graphic + phase);
732 if (player_is_moving && last_element == EL_EXPLODING)
734 int phase = Frame[last_jx][last_jy];
738 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
739 GFX_EXPLOSION + ((phase - 1) / delay - 1));
742 /* draw elements that stay over the player */
743 /* handle the field the player is leaving ... */
744 if (player_is_moving && IS_OVER_PLAYER(last_element))
745 DrawLevelField(last_jx, last_jy);
746 /* ... and the field the player is entering */
747 if (IS_OVER_PLAYER(element))
748 DrawLevelField(jx, jy);
750 if (setup.direct_draw)
752 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
753 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
754 int x_size = TILEX * (1 + ABS(jx - last_jx));
755 int y_size = TILEY * (1 + ABS(jy - last_jy));
757 BlitBitmap(drawto_field, window,
758 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
759 SetDrawtoField(DRAW_DIRECT);
762 MarkTileDirty(sx,sy);
765 static int getGraphicAnimationPhase(int frames, int delay, int mode)
769 if (mode == ANIM_OSCILLATE)
771 int max_anim_frames = 2 * frames - 2;
772 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
773 phase = (phase < frames ? phase : max_anim_frames - phase);
776 phase = (FrameCounter % (delay * frames)) / delay;
778 if (mode == ANIM_REVERSE)
784 void DrawGraphicAnimationExt(int x, int y, int graphic,
785 int frames, int delay, int mode, int mask_mode)
787 int phase = getGraphicAnimationPhase(frames, delay, mode);
789 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
791 if (mask_mode == USE_MASKING)
792 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
794 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
798 void DrawGraphicAnimation(int x, int y, int graphic,
799 int frames, int delay, int mode)
801 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
804 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
805 int frames, int delay, int mode)
807 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
810 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
813 int frames, int delay,
816 int phase = getGraphicAnimationPhase(frames, delay, mode);
818 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
821 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
823 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
825 graphic -= GFX_START_ROCKSSCREEN;
826 *bitmap_nr = PIX_BACK;
827 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
828 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
830 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
832 graphic -= GFX_START_ROCKSHEROES;
833 *bitmap_nr = PIX_HEROES;
834 *x = (graphic % HEROES_PER_LINE) * TILEX;
835 *y = (graphic / HEROES_PER_LINE) * TILEY;
837 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
839 graphic -= GFX_START_ROCKSSP;
841 *x = (graphic % SP_PER_LINE) * TILEX;
842 *y = (graphic / SP_PER_LINE) * TILEY;
844 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
846 graphic -= GFX_START_ROCKSDC;
848 *x = (graphic % DC_PER_LINE) * TILEX;
849 *y = (graphic / DC_PER_LINE) * TILEY;
851 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
853 graphic -= GFX_START_ROCKSMORE;
854 *bitmap_nr = PIX_MORE;
855 *x = (graphic % MORE_PER_LINE) * TILEX;
856 *y = (graphic / MORE_PER_LINE) * TILEY;
858 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
860 graphic -= GFX_START_ROCKSFONT;
861 *bitmap_nr = PIX_BIGFONT;
862 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
863 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
864 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
874 void DrawGraphic(int x, int y, int graphic)
877 if (!IN_SCR_FIELD(x,y))
879 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
880 printf("DrawGraphic(): This should never happen!\n");
885 DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
889 void DrawGraphicExt(DrawBuffer d, GC gc, int x, int y, int graphic)
894 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
895 BlitBitmap(pix[bitmap_nr], d, src_x, src_y, TILEX, TILEY, x, y);
898 void DrawGraphicThruMask(int x, int y, int graphic)
901 if (!IN_SCR_FIELD(x,y))
903 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
904 printf("DrawGraphicThruMask(): This should never happen!\n");
909 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
913 void DrawGraphicThruMaskExt(DrawBuffer d, int dest_x, int dest_y, int graphic)
921 if (graphic == GFX_LEERRAUM)
924 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
925 src_bitmap = pix_masked[bitmap_nr];
926 drawing_gc = clip_gc[bitmap_nr];
928 if (tile_clipmask[tile] != None)
930 SetClipMask(tile_clip_gc, tile_clipmask[tile]);
931 SetClipOrigin(tile_clip_gc, dest_x, dest_y);
932 BlitBitmapMasked(src_bitmap, d,
933 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
938 #ifndef USE_SDL_LIBRARY
939 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
943 SetClipOrigin(drawing_gc, dest_x-src_x, dest_y-src_y);
944 BlitBitmapMasked(src_bitmap, d,
945 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
949 void DrawMiniGraphic(int x, int y, int graphic)
951 DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
952 MarkTileDirty(x/2, y/2);
955 void getMiniGraphicSource(int graphic, Bitmap *bitmap, int *x, int *y)
957 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
959 graphic -= GFX_START_ROCKSSCREEN;
960 *bitmap = pix[PIX_BACK];
961 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
962 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
964 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
966 graphic -= GFX_START_ROCKSSP;
967 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
968 *bitmap = pix[PIX_SP];
969 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
970 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
972 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
974 graphic -= GFX_START_ROCKSDC;
975 *bitmap = pix[PIX_DC];
976 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
977 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
979 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
981 graphic -= GFX_START_ROCKSMORE;
982 *bitmap = pix[PIX_MORE];
983 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
984 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
986 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
988 graphic -= GFX_START_ROCKSFONT;
989 *bitmap = pix[PIX_SMALLFONT];
990 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
991 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
992 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
996 *bitmap = pix[PIX_SP];
1002 void DrawMiniGraphicExt(DrawBuffer d, GC gc, int x, int y, int graphic)
1007 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
1008 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
1011 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
1012 int cut_mode, int mask_mode)
1014 int width = TILEX, height = TILEY;
1016 int src_x, src_y, dest_x, dest_y;
1023 DrawGraphic(x, y, graphic);
1027 if (dx || dy) /* Verschiebung der Grafik? */
1029 if (x < BX1) /* Element kommt von links ins Bild */
1036 else if (x > BX2) /* Element kommt von rechts ins Bild */
1042 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1048 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1050 else if (dx) /* allg. Bewegung in x-Richtung */
1051 MarkTileDirty(x + SIGN(dx), y);
1053 if (y < BY1) /* Element kommt von oben ins Bild */
1055 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1063 else if (y > BY2) /* Element kommt von unten ins Bild */
1069 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1075 else if (dy > 0 && cut_mode == CUT_ABOVE)
1077 if (y == BY2) /* Element unterhalb des Bildes */
1083 MarkTileDirty(x, y + 1);
1084 } /* Element verläßt unten das Bild */
1085 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1087 else if (dy) /* allg. Bewegung in y-Richtung */
1088 MarkTileDirty(x, y + SIGN(dy));
1091 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
1092 drawing_gc = clip_gc[bitmap_nr];
1097 dest_x = FX + x * TILEX + dx;
1098 dest_y = FY + y * TILEY + dy;
1101 if (!IN_SCR_FIELD(x,y))
1103 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1104 printf("DrawGraphicShifted(): This should never happen!\n");
1109 if (mask_mode == USE_MASKING)
1111 if (tile_clipmask[tile] != None)
1113 SetClipMask(tile_clip_gc, tile_clipmask[tile]);
1114 SetClipOrigin(tile_clip_gc, dest_x, dest_y);
1115 BlitBitmapMasked(pix_masked[bitmap_nr], drawto_field,
1116 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1121 #ifndef USE_SDL_LIBRARY
1122 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1126 SetClipOrigin(drawing_gc, dest_x - src_x, dest_y - src_y);
1127 BlitBitmapMasked(pix_masked[bitmap_nr], drawto_field,
1128 src_x, src_y, width, height, dest_x, dest_y);
1132 BlitBitmap(pix[bitmap_nr], drawto_field,
1133 src_x, src_y, width, height, dest_x, dest_y);
1138 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1141 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1144 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1145 int cut_mode, int mask_mode)
1147 int ux = LEVELX(x), uy = LEVELY(y);
1148 int graphic = el2gfx(element);
1149 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1150 int phase4 = phase8 / 2;
1151 int phase2 = phase8 / 4;
1152 int dir = MovDir[ux][uy];
1154 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1156 graphic += 4 * !phase2;
1160 else if (dir == MV_LEFT)
1162 else if (dir == MV_DOWN)
1165 else if (element == EL_SP_SNIKSNAK)
1168 graphic = GFX_SP_SNIKSNAK_LEFT;
1169 else if (dir == MV_RIGHT)
1170 graphic = GFX_SP_SNIKSNAK_RIGHT;
1171 else if (dir == MV_UP)
1172 graphic = GFX_SP_SNIKSNAK_UP;
1174 graphic = GFX_SP_SNIKSNAK_DOWN;
1176 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1178 else if (element == EL_SP_ELECTRON)
1180 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1182 else if (element == EL_MOLE || element == EL_PINGUIN ||
1183 element == EL_SCHWEIN || element == EL_DRACHE)
1186 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1187 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1188 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1189 else if (dir == MV_RIGHT)
1190 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1191 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1192 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1193 else if (dir == MV_UP)
1194 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1195 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1196 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1198 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1199 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1200 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1204 else if (element == EL_SONDE)
1206 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1208 else if (element == EL_SALZSAEURE)
1210 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1212 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1216 else if (element == EL_BALLOON)
1220 else if ((element == EL_FELSBROCKEN ||
1221 element == EL_SP_ZONK ||
1222 element == EL_BD_ROCK ||
1223 IS_GEM(element)) && !cut_mode)
1225 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1227 if (element == EL_FELSBROCKEN ||
1228 element == EL_SP_ZONK ||
1229 element == EL_BD_ROCK)
1232 graphic += (4 - phase4) % 4;
1233 else if (dir == MV_RIGHT)
1236 graphic += phase2 * 2;
1238 else if (element != EL_SP_INFOTRON)
1242 else if (element == EL_MAGIC_WALL_EMPTY ||
1243 element == EL_MAGIC_WALL_BD_EMPTY ||
1244 element == EL_MAGIC_WALL_FULL ||
1245 element == EL_MAGIC_WALL_BD_FULL)
1247 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1249 else if (IS_AMOEBOID(element))
1251 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1252 graphic += (x + 2 * y + 4) % 4;
1254 else if (element == EL_MAUER_LEBT)
1256 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1258 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1259 links_massiv = TRUE;
1260 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1261 rechts_massiv = TRUE;
1263 if (links_massiv && rechts_massiv)
1264 graphic = GFX_MAUERWERK;
1265 else if (links_massiv)
1266 graphic = GFX_MAUER_R;
1267 else if (rechts_massiv)
1268 graphic = GFX_MAUER_L;
1270 else if ((element == EL_INVISIBLE_STEEL ||
1271 element == EL_UNSICHTBAR ||
1272 element == EL_SAND_INVISIBLE) && game.light_time_left)
1274 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1275 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1276 GFX_SAND_INVISIBLE_ON);
1280 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1281 else if (mask_mode == USE_MASKING)
1282 DrawGraphicThruMask(x, y, graphic);
1284 DrawGraphic(x, y, graphic);
1287 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1288 int cut_mode, int mask_mode)
1290 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1291 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1292 cut_mode, mask_mode);
1295 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1298 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1301 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1304 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1307 void DrawScreenElementThruMask(int x, int y, int element)
1309 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1312 void DrawLevelElementThruMask(int x, int y, int element)
1314 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1317 void DrawLevelFieldThruMask(int x, int y)
1319 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1322 void ErdreichAnbroeckeln(int x, int y)
1324 int i, width, height, cx,cy;
1325 int ux = LEVELX(x), uy = LEVELY(y);
1326 int element, graphic;
1328 static int xy[4][2] =
1336 if (!IN_LEV_FIELD(ux, uy))
1339 element = Feld[ux][uy];
1341 if (element == EL_ERDREICH ||
1342 element == EL_LANDMINE ||
1343 element == EL_TRAP_INACTIVE ||
1344 element == EL_TRAP_ACTIVE)
1346 if (!IN_SCR_FIELD(x, y))
1349 graphic = GFX_ERDENRAND;
1355 uxx = ux + xy[i][0];
1356 uyy = uy + xy[i][1];
1357 if (!IN_LEV_FIELD(uxx, uyy))
1360 element = Feld[uxx][uyy];
1362 if (element == EL_ERDREICH ||
1363 element == EL_LANDMINE ||
1364 element == EL_TRAP_INACTIVE ||
1365 element == EL_TRAP_ACTIVE)
1368 if (i == 1 || i == 2)
1372 cx = (i == 2 ? TILEX - snip : 0);
1380 cy = (i == 3 ? TILEY - snip : 0);
1383 BlitBitmap(pix[PIX_BACK], drawto_field,
1384 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1385 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1386 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1389 MarkTileDirty(x, y);
1393 graphic = GFX_ERDENRAND;
1397 int xx, yy, uxx, uyy;
1401 uxx = ux + xy[i][0];
1402 uyy = uy + xy[i][1];
1404 if (!IN_LEV_FIELD(uxx, uyy) ||
1405 (Feld[uxx][uyy] != EL_ERDREICH &&
1406 Feld[uxx][uyy] != EL_LANDMINE &&
1407 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1408 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1409 !IN_SCR_FIELD(xx, yy))
1412 if (i == 1 || i == 2)
1416 cx = (i == 1 ? TILEX - snip : 0);
1424 cy = (i==0 ? TILEY-snip : 0);
1427 BlitBitmap(pix[PIX_BACK], drawto_field,
1428 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1429 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1430 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1432 MarkTileDirty(xx, yy);
1437 void DrawScreenElement(int x, int y, int element)
1439 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1440 ErdreichAnbroeckeln(x, y);
1443 void DrawLevelElement(int x, int y, int element)
1445 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1446 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1449 void DrawScreenField(int x, int y)
1451 int ux = LEVELX(x), uy = LEVELY(y);
1454 if (!IN_LEV_FIELD(ux, uy))
1456 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1457 element = EL_LEERRAUM;
1459 element = BorderElement;
1461 DrawScreenElement(x, y, element);
1465 element = Feld[ux][uy];
1467 if (IS_MOVING(ux, uy))
1469 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1470 boolean cut_mode = NO_CUTTING;
1472 if (Store[ux][uy] == EL_MORAST_LEER ||
1473 Store[ux][uy] == EL_MAGIC_WALL_EMPTY ||
1474 Store[ux][uy] == EL_MAGIC_WALL_BD_EMPTY ||
1475 Store[ux][uy] == EL_AMOEBE_NASS)
1476 cut_mode = CUT_ABOVE;
1477 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1478 Store[ux][uy] == EL_MAGIC_WALL_FULL ||
1479 Store[ux][uy] == EL_MAGIC_WALL_BD_FULL)
1480 cut_mode = CUT_BELOW;
1482 if (cut_mode == CUT_ABOVE)
1483 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1485 DrawScreenElement(x, y, EL_LEERRAUM);
1488 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1490 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1492 if (Store[ux][uy] == EL_SALZSAEURE)
1493 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1495 else if (IS_BLOCKED(ux, uy))
1500 boolean cut_mode = NO_CUTTING;
1502 Blocked2Moving(ux, uy, &oldx, &oldy);
1505 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1506 MovDir[oldx][oldy] == MV_RIGHT);
1508 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1509 Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
1510 Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
1511 Store[oldx][oldy] == EL_AMOEBE_NASS)
1512 cut_mode = CUT_ABOVE;
1514 DrawScreenElement(x, y, EL_LEERRAUM);
1515 element = Feld[oldx][oldy];
1518 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1520 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1522 else if (IS_DRAWABLE(element))
1523 DrawScreenElement(x, y, element);
1525 DrawScreenElement(x, y, EL_LEERRAUM);
1528 void DrawLevelField(int x, int y)
1530 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1531 DrawScreenField(SCREENX(x), SCREENY(y));
1532 else if (IS_MOVING(x, y))
1536 Moving2Blocked(x, y, &newx, &newy);
1537 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1538 DrawScreenField(SCREENX(newx), SCREENY(newy));
1540 else if (IS_BLOCKED(x, y))
1544 Blocked2Moving(x, y, &oldx, &oldy);
1545 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1546 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1550 void DrawMiniElement(int x, int y, int element)
1556 DrawMiniGraphic(x, y, -1);
1560 graphic = el2gfx(element);
1561 DrawMiniGraphic(x, y, graphic);
1564 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1566 int x = sx + scroll_x, y = sy + scroll_y;
1568 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1569 DrawMiniElement(sx, sy, EL_LEERRAUM);
1570 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1571 DrawMiniElement(sx, sy, Feld[x][y]);
1574 int steel_type, steel_position;
1577 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1578 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1579 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1580 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1581 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1582 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1585 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1586 steel_position = (x == -1 && y == -1 ? 0 :
1587 x == lev_fieldx && y == -1 ? 1 :
1588 x == -1 && y == lev_fieldy ? 2 :
1589 x == lev_fieldx && y == lev_fieldy ? 3 :
1590 x == -1 || x == lev_fieldx ? 4 :
1591 y == -1 || y == lev_fieldy ? 5 : -1);
1593 if (steel_position != -1)
1594 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1598 void DrawMicroElement(int xpos, int ypos, int element)
1602 if (element == EL_LEERRAUM)
1605 graphic = el2gfx(element);
1607 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1609 graphic -= GFX_START_ROCKSSP;
1610 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1611 BlitBitmap(pix[PIX_SP], drawto,
1612 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1613 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1614 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1616 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1618 graphic -= GFX_START_ROCKSDC;
1619 BlitBitmap(pix[PIX_DC], drawto,
1620 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1621 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1622 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1624 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1626 graphic -= GFX_START_ROCKSMORE;
1627 BlitBitmap(pix[PIX_MORE], drawto,
1628 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1629 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1630 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1633 BlitBitmap(pix[PIX_BACK], drawto,
1634 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1635 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1636 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1645 for(x=BX1; x<=BX2; x++)
1646 for(y=BY1; y<=BY2; y++)
1647 DrawScreenField(x, y);
1649 redraw_mask |= REDRAW_FIELD;
1652 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1656 for(x=0; x<size_x; x++)
1657 for(y=0; y<size_y; y++)
1658 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1660 redraw_mask |= REDRAW_FIELD;
1663 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1667 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1669 if (lev_fieldx < STD_LEV_FIELDX)
1670 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1671 if (lev_fieldy < STD_LEV_FIELDY)
1672 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1674 xpos += MICRO_TILEX;
1675 ypos += MICRO_TILEY;
1677 for(x=-1; x<=STD_LEV_FIELDX; x++)
1679 for(y=-1; y<=STD_LEV_FIELDY; y++)
1681 int lx = from_x + x, ly = from_y + y;
1683 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1684 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1686 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1687 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1692 redraw_mask |= REDRAW_MICROLEVEL;
1695 #define MICROLABEL_EMPTY 0
1696 #define MICROLABEL_LEVEL_NAME 1
1697 #define MICROLABEL_CREATED_BY 2
1698 #define MICROLABEL_LEVEL_AUTHOR 3
1699 #define MICROLABEL_IMPORTED_FROM 4
1700 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1702 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1704 static void DrawMicroLevelLabelExt(int mode)
1706 char label_text[MAX_MICROLABEL_SIZE + 1];
1708 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1710 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1711 mode == MICROLABEL_CREATED_BY ? "created by" :
1712 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1713 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1714 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1715 leveldir_current->imported_from : ""),
1716 MAX_MICROLABEL_SIZE);
1717 label_text[MAX_MICROLABEL_SIZE] = '\0';
1719 if (strlen(label_text) > 0)
1721 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1722 int lypos = MICROLABEL_YPOS;
1724 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1727 redraw_mask |= REDRAW_MICROLEVEL;
1730 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1732 static unsigned long scroll_delay = 0;
1733 static unsigned long label_delay = 0;
1734 static int from_x, from_y, scroll_direction;
1735 static int label_state, label_counter;
1739 from_x = from_y = 0;
1740 scroll_direction = MV_RIGHT;
1744 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1745 DrawMicroLevelLabelExt(label_state);
1747 /* initialize delay counters */
1748 DelayReached(&scroll_delay, 0);
1749 DelayReached(&label_delay, 0);
1754 /* scroll micro level, if needed */
1755 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1756 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1758 switch (scroll_direction)
1764 scroll_direction = MV_UP;
1768 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1771 scroll_direction = MV_DOWN;
1778 scroll_direction = MV_RIGHT;
1782 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1785 scroll_direction = MV_LEFT;
1792 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1795 /* redraw micro level label, if needed */
1796 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1797 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1798 strcmp(level.author, leveldir_current->name) != 0 &&
1799 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1801 int max_label_counter = 23;
1803 if (leveldir_current->imported_from != NULL)
1804 max_label_counter += 14;
1806 label_counter = (label_counter + 1) % max_label_counter;
1807 label_state = (label_counter >= 0 && label_counter <= 7 ?
1808 MICROLABEL_LEVEL_NAME :
1809 label_counter >= 9 && label_counter <= 12 ?
1810 MICROLABEL_CREATED_BY :
1811 label_counter >= 14 && label_counter <= 21 ?
1812 MICROLABEL_LEVEL_AUTHOR :
1813 label_counter >= 23 && label_counter <= 26 ?
1814 MICROLABEL_IMPORTED_FROM :
1815 label_counter >= 28 && label_counter <= 35 ?
1816 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1817 DrawMicroLevelLabelExt(label_state);
1821 int REQ_in_range(int x, int y)
1823 if (y > DY+249 && y < DY+278)
1825 if (x > DX+1 && x < DX+48)
1827 else if (x > DX+51 && x < DX+98)
1833 boolean Request(char *text, unsigned int req_state)
1835 int mx, my, ty, result = -1;
1836 unsigned int old_door_state;
1838 #if !defined(MSDOS) && !defined(WIN32)
1839 /* pause network game while waiting for request to answer */
1840 if (options.network &&
1841 game_status == PLAYING &&
1842 req_state & REQUEST_WAIT_FOR)
1843 SendToServer_PausePlaying();
1846 old_door_state = GetDoorState();
1850 CloseDoor(DOOR_CLOSE_1);
1852 /* save old door content */
1853 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1854 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1855 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1857 /* clear door drawing field */
1858 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1860 /* write text for request */
1861 for(ty=0; ty<13; ty++)
1869 for(tl=0,tx=0; tx<7; tl++,tx++)
1872 if (!tc || tc == 32)
1883 DrawTextExt(drawto, gc,
1884 DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1885 txt, FS_SMALL, FC_YELLOW);
1886 text += tl + (tc == 32 ? 1 : 0);
1889 if (req_state & REQ_ASK)
1891 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1892 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1894 else if (req_state & REQ_CONFIRM)
1896 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1898 else if (req_state & REQ_PLAYER)
1900 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1901 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1902 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1903 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1906 /* copy request gadgets to door backbuffer */
1907 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1908 DX, DY, DXSIZE, DYSIZE,
1909 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1911 OpenDoor(DOOR_OPEN_1);
1917 if (!(req_state & REQUEST_WAIT_FOR))
1920 if (game_status != MAINMENU)
1923 button_status = MB_RELEASED;
1925 request_gadget_id = -1;
1937 case EVENT_BUTTONPRESS:
1938 case EVENT_BUTTONRELEASE:
1939 case EVENT_MOTIONNOTIFY:
1941 if (event.type == EVENT_MOTIONNOTIFY)
1943 if (!PointerInWindow(window))
1944 continue; /* window and pointer are on different screens */
1949 motion_status = TRUE;
1950 mx = ((MotionEvent *) &event)->x;
1951 my = ((MotionEvent *) &event)->y;
1955 motion_status = FALSE;
1956 mx = ((ButtonEvent *) &event)->x;
1957 my = ((ButtonEvent *) &event)->y;
1958 if (event.type == EVENT_BUTTONPRESS)
1959 button_status = ((ButtonEvent *) &event)->button;
1961 button_status = MB_RELEASED;
1964 /* this sets 'request_gadget_id' */
1965 HandleGadgets(mx, my, button_status);
1967 switch(request_gadget_id)
1969 case TOOL_CTRL_ID_YES:
1972 case TOOL_CTRL_ID_NO:
1975 case TOOL_CTRL_ID_CONFIRM:
1976 result = TRUE | FALSE;
1979 case TOOL_CTRL_ID_PLAYER_1:
1982 case TOOL_CTRL_ID_PLAYER_2:
1985 case TOOL_CTRL_ID_PLAYER_3:
1988 case TOOL_CTRL_ID_PLAYER_4:
1999 case EVENT_KEYPRESS:
2000 switch(GetEventKey((KeyEvent *)&event, TRUE))
2013 if (req_state & REQ_PLAYER)
2017 case EVENT_KEYRELEASE:
2018 key_joystick_mapping = 0;
2022 HandleOtherEvents(&event);
2026 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
2028 int joy = AnyJoystick();
2030 if (joy & JOY_BUTTON_1)
2032 else if (joy & JOY_BUTTON_2)
2038 /* don't eat all CPU time */
2042 if (game_status != MAINMENU)
2047 if (!(req_state & REQ_STAY_OPEN))
2049 CloseDoor(DOOR_CLOSE_1);
2051 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2053 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2054 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2055 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2056 OpenDoor(DOOR_OPEN_1);
2062 #if !defined(MSDOS) && !defined(WIN32)
2063 /* continue network game after request */
2064 if (options.network &&
2065 game_status == PLAYING &&
2066 req_state & REQUEST_WAIT_FOR)
2067 SendToServer_ContinuePlaying();
2073 unsigned int OpenDoor(unsigned int door_state)
2075 unsigned int new_door_state;
2077 if (door_state & DOOR_COPY_BACK)
2079 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2080 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2081 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2082 door_state &= ~DOOR_COPY_BACK;
2085 new_door_state = MoveDoor(door_state);
2087 return(new_door_state);
2090 unsigned int CloseDoor(unsigned int door_state)
2092 unsigned int new_door_state;
2094 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2095 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2096 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2097 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2099 new_door_state = MoveDoor(door_state);
2101 return(new_door_state);
2104 unsigned int GetDoorState()
2106 return(MoveDoor(DOOR_GET_STATE));
2109 unsigned int MoveDoor(unsigned int door_state)
2111 static int door1 = DOOR_OPEN_1;
2112 static int door2 = DOOR_CLOSE_2;
2113 static unsigned long door_delay = 0;
2114 int x, start, stepsize = 2;
2115 unsigned long door_delay_value = stepsize * 5;
2117 if (door_state == DOOR_GET_STATE)
2118 return(door1 | door2);
2120 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2121 door_state &= ~DOOR_OPEN_1;
2122 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2123 door_state &= ~DOOR_CLOSE_1;
2124 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2125 door_state &= ~DOOR_OPEN_2;
2126 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2127 door_state &= ~DOOR_CLOSE_2;
2129 if (setup.quick_doors)
2132 door_delay_value = 0;
2133 StopSound(SND_OEFFNEN);
2136 if (door_state & DOOR_ACTION)
2138 if (!(door_state & DOOR_NO_DELAY))
2139 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2141 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2143 for(x=start; x<=DXSIZE; x+=stepsize)
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(clip_gc[PIX_DOOR], DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2159 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2160 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2161 DX + DXSIZE - i, DY + j);
2162 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2163 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2164 DX + DXSIZE - i, DY + 140 + j);
2165 SetClipOrigin(clip_gc[PIX_DOOR],
2166 DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2167 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2168 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2170 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2171 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2174 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2175 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2177 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2178 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2180 SetClipOrigin(clip_gc[PIX_DOOR], DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2181 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2182 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2183 DX + DXSIZE - i, DY + 77 + j);
2184 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2185 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2186 DX + DXSIZE - i, DY + 203 + j);
2188 redraw_mask |= REDRAW_DOOR_1;
2191 if (door_state & DOOR_ACTION_2)
2193 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2194 int j = (VXSIZE - i) / 3;
2196 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2197 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2198 VXSIZE, VYSIZE - i/2, VX, VY);
2200 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2202 SetClipOrigin(clip_gc[PIX_DOOR], VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2203 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2204 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2205 VX + VXSIZE-i, VY+j);
2206 SetClipOrigin(clip_gc[PIX_DOOR],
2207 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2208 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2209 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2212 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2213 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2214 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2215 SetClipOrigin(clip_gc[PIX_DOOR], VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2216 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2217 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2219 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2221 redraw_mask |= REDRAW_DOOR_2;
2226 if (game_status == MAINMENU)
2231 if (setup.quick_doors)
2232 StopSound(SND_OEFFNEN);
2234 if (door_state & DOOR_ACTION_1)
2235 door1 = door_state & DOOR_ACTION_1;
2236 if (door_state & DOOR_ACTION_2)
2237 door2 = door_state & DOOR_ACTION_2;
2239 return (door1 | door2);
2242 void DrawSpecialEditorDoor()
2244 /* draw bigger toolbox window */
2245 BlitBitmap(pix[PIX_DOOR], drawto,
2246 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2248 redraw_mask |= REDRAW_ALL;
2251 void UndrawSpecialEditorDoor()
2253 /* draw normal tape recorder window */
2254 BlitBitmap(pix[PIX_BACK], drawto,
2255 562, 344, 108, 56, EX - 4, EY - 12);
2257 redraw_mask |= REDRAW_ALL;
2260 #ifndef USE_SDL_LIBRARY
2261 int ReadPixel(DrawBuffer d, int x, int y)
2263 XImage *pixel_image;
2264 unsigned long pixel_value;
2266 pixel_image = XGetImage(display, d, 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,
2376 static void DoNotDisplayInfoText(void *ptr)
2381 void CreateToolButtons()
2385 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2387 Bitmap gd_bitmap = pix[PIX_DOOR];
2388 Bitmap deco_bitmap = None;
2389 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2390 struct GadgetInfo *gi;
2391 unsigned long event_mask;
2392 int gd_xoffset, gd_yoffset;
2393 int gd_x1, gd_x2, gd_y;
2396 event_mask = GD_EVENT_RELEASED;
2398 gd_xoffset = toolbutton_info[i].xpos;
2399 gd_yoffset = toolbutton_info[i].ypos;
2400 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2401 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2402 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2404 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2406 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2407 &deco_bitmap, &deco_x, &deco_y);
2408 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2409 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2412 gi = CreateGadget(GDI_CUSTOM_ID, id,
2413 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2414 GDI_X, DX + toolbutton_info[i].x,
2415 GDI_Y, DY + toolbutton_info[i].y,
2416 GDI_WIDTH, toolbutton_info[i].width,
2417 GDI_HEIGHT, toolbutton_info[i].height,
2418 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2419 GDI_STATE, GD_BUTTON_UNPRESSED,
2420 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2421 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2422 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2423 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2424 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2425 GDI_DECORATION_SHIFTING, 1, 1,
2426 GDI_EVENT_MASK, event_mask,
2427 GDI_CALLBACK_ACTION, HandleToolButtons,
2428 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2432 Error(ERR_EXIT, "cannot create gadget");
2434 tool_gadget[id] = gi;
2438 static void UnmapToolButtons()
2442 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2443 UnmapGadget(tool_gadget[i]);
2446 static void HandleToolButtons(struct GadgetInfo *gi)
2448 request_gadget_id = gi->custom_id;
2451 int el2gfx(int element)
2455 case EL_LEERRAUM: return -1;
2456 case EL_ERDREICH: return GFX_ERDREICH;
2457 case EL_MAUERWERK: return GFX_MAUERWERK;
2458 case EL_FELSBODEN: return GFX_FELSBODEN;
2459 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2460 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2461 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2462 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2463 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2464 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2465 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2466 case EL_SPIELER1: return GFX_SPIELER1;
2467 case EL_SPIELER2: return GFX_SPIELER2;
2468 case EL_SPIELER3: return GFX_SPIELER3;
2469 case EL_SPIELER4: return GFX_SPIELER4;
2470 case EL_KAEFER: return GFX_KAEFER;
2471 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2472 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2473 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2474 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2475 case EL_FLIEGER: return GFX_FLIEGER;
2476 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2477 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2478 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2479 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2480 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2481 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2482 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2483 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2484 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2485 case EL_FIREFLY: return GFX_FIREFLY;
2486 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2487 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2488 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2489 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2490 case EL_MAMPFER: return GFX_MAMPFER;
2491 case EL_ROBOT: return GFX_ROBOT;
2492 case EL_BETON: return GFX_BETON;
2493 case EL_DIAMANT: return GFX_DIAMANT;
2494 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2495 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2496 case EL_TROPFEN: return GFX_TROPFEN;
2497 case EL_BOMBE: return GFX_BOMBE;
2498 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2499 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2500 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2501 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2502 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2503 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2504 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2505 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2506 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2507 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2508 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2509 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2510 case EL_LIFE: return GFX_LIFE;
2511 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2512 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2513 case EL_BADEWANNE: return GFX_BADEWANNE;
2514 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2515 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2516 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2517 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2518 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2519 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2520 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2521 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2522 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2523 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2524 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2525 case EL_PFORTE1: return GFX_PFORTE1;
2526 case EL_PFORTE2: return GFX_PFORTE2;
2527 case EL_PFORTE3: return GFX_PFORTE3;
2528 case EL_PFORTE4: return GFX_PFORTE4;
2529 case EL_PFORTE1X: return GFX_PFORTE1X;
2530 case EL_PFORTE2X: return GFX_PFORTE2X;
2531 case EL_PFORTE3X: return GFX_PFORTE3X;
2532 case EL_PFORTE4X: return GFX_PFORTE4X;
2533 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2534 case EL_PACMAN: return GFX_PACMAN;
2535 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2536 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2537 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2538 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2539 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2540 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2541 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2542 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2543 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2544 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2545 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2546 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2547 case EL_MAUER_X: return GFX_MAUER_X;
2548 case EL_MAUER_Y: return GFX_MAUER_Y;
2549 case EL_MAUER_XY: return GFX_MAUER_XY;
2550 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2551 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2552 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2553 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2554 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2555 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2556 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2557 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2558 case EL_MAMPFER2: return GFX_MAMPFER2;
2559 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2560 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2561 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2562 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2563 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2564 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2565 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2566 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2567 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2568 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2569 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2570 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2571 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2572 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2573 case EL_MOLE: return GFX_MOLE;
2574 case EL_PINGUIN: return GFX_PINGUIN;
2575 case EL_SCHWEIN: return GFX_SCHWEIN;
2576 case EL_DRACHE: return GFX_DRACHE;
2577 case EL_SONDE: return GFX_SONDE;
2578 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2579 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2580 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2581 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2582 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2583 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2584 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2585 case EL_SP_ZONK: return GFX_SP_ZONK;
2586 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2587 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2588 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2589 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2590 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2591 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2592 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2593 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2594 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2595 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2596 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2597 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2598 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2599 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2600 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2601 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2602 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2603 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2604 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2605 case EL_PEARL: return GFX_PEARL;
2606 case EL_CRYSTAL: return GFX_CRYSTAL;
2607 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2608 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2609 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2610 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2611 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2612 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2613 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2614 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2615 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2616 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2617 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2618 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2619 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2620 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2621 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2622 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2623 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2624 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2625 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2626 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2627 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2628 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2629 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2630 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2631 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2632 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2633 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2634 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2635 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2636 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2637 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2638 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2639 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2640 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2641 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2642 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2643 case EL_LANDMINE: return GFX_LANDMINE;
2644 case EL_ENVELOPE: return GFX_ENVELOPE;
2645 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2646 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2647 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2648 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2649 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2650 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2651 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2652 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2653 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2654 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2655 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2656 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2657 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2658 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2659 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2660 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2661 case EL_MOLE_UP: return GFX_MOLE_UP;
2662 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2663 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2664 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2665 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2666 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2667 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2668 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2669 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2670 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2671 case EL_BALLOON: return GFX_BALLOON;
2672 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2673 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2674 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2675 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2676 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2677 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2678 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2679 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2680 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2681 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2682 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2683 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2684 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2685 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2686 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2687 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2688 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2689 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2690 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2691 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2692 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2693 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2694 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2695 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2696 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2697 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2698 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2699 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2700 case EL_SPRING: return GFX_SPRING;
2701 case EL_SPRING_MOVING: return GFX_SPRING;
2702 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2703 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2704 case EL_BD_WALL: return GFX_BD_WALL;
2705 case EL_BD_ROCK: return GFX_BD_ROCK;
2706 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2707 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2711 if (IS_CHAR(element))
2712 return GFX_CHAR_START + (element - EL_CHAR_START);
2713 else if (element >= EL_SP_START && element <= EL_SP_END)
2715 int nr_element = element - EL_SP_START;
2716 int gfx_per_line = 8;
2718 (nr_element / gfx_per_line) * SP_PER_LINE +
2719 (nr_element % gfx_per_line);
2721 return GFX_START_ROCKSSP + nr_graphic;